Skip to content

Commit 2bef04b

Browse files
feat: support claude code login with credentails
1 parent 605a661 commit 2bef04b

4 files changed

Lines changed: 56 additions & 7 deletions

File tree

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,4 +177,5 @@ storybook-static/
177177
coverage/
178178
.DS_Store
179179
*.pem
180-
tasks_backup.json
180+
tasks_backup.json
181+
.credentials.json

async-code-web/components/code-agent-settings.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import { Label } from "@/components/ui/label";
1010
import { Alert, AlertDescription } from "@/components/ui/alert";
1111
import { AlertCircle, Save } from "lucide-react";
1212
import { toast } from "sonner";
13-
import { updateUserProfile } from "@/lib/supabase-service";
13+
import { SupabaseService } from "@/lib/supabase-service";
1414
import { useUserProfile } from "@/hooks/useUserProfile";
1515

1616
interface CodeAgentConfig {
@@ -87,7 +87,7 @@ export function CodeAgentSettings() {
8787
...preferences,
8888
};
8989

90-
await updateUserProfile({ preferences: mergedPrefs });
90+
await SupabaseService.updateUserProfile({ preferences: mergedPrefs });
9191
await refreshProfile();
9292
toast.success("Code agent settings saved successfully");
9393
} catch (error) {

async-code-web/hooks/useUserProfile.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"use client";
22

33
import { useState, useEffect, useCallback } from "react";
4-
import { getUserProfile } from "@/lib/supabase-service";
4+
import { SupabaseService } from "@/lib/supabase-service";
55
import { User } from "@/types";
66

77
export function useUserProfile() {
@@ -12,7 +12,7 @@ export function useUserProfile() {
1212
const fetchProfile = useCallback(async () => {
1313
try {
1414
setIsLoading(true);
15-
const data = await getUserProfile();
15+
const data = await SupabaseService.getUserProfile();
1616
setProfile(data);
1717
setError(null);
1818
} catch (err) {

server/utils/code_task_v2.py

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,33 @@ def _run_ai_code_task_v2_internal(task_id: int, user_id: str, github_token: str)
203203
logger.info(f"🕐 Adding additional {additional_delay:.1f}s delay due to lock conflict")
204204
time.sleep(additional_delay)
205205

206+
# Load Claude credentials from user preferences in Supabase
207+
credentials_content = ""
208+
escaped_credentials = ""
209+
if model_cli == 'claude':
210+
logger.info(f"🔍 Looking for Claude credentials in user preferences for task {task_id}")
211+
212+
# Check if user has Claude credentials in their preferences
213+
claude_preferences = user_preferences.get('claudeCode', {})
214+
if claude_preferences and 'credentials' in claude_preferences:
215+
try:
216+
credentials_json = claude_preferences['credentials']
217+
if credentials_json:
218+
# Convert JSON object to string for writing to container
219+
credentials_content = json.dumps(credentials_json)
220+
logger.info(f"📋 Successfully loaded Claude credentials from user preferences and stringified ({len(credentials_content)} characters) for task {task_id}")
221+
# Escape credentials content for shell
222+
escaped_credentials = credentials_content.replace("'", "'\"'\"'").replace('\n', '\\n')
223+
logger.info(f"📋 Credentials content escaped for shell injection")
224+
else:
225+
logger.warning(f"⚠️ Claude credentials field exists but is empty in user preferences for task {task_id}")
226+
except Exception as e:
227+
logger.error(f"❌ Failed to process Claude credentials from user preferences: {e}")
228+
credentials_content = ""
229+
escaped_credentials = ""
230+
else:
231+
logger.info(f"ℹ️ No Claude credentials found in user preferences for task {task_id} - skipping credentials setup")
232+
206233
# Create the command to run in container (v2 function)
207234
container_command = f'''
208235
set -e
@@ -221,8 +248,29 @@ def _run_ai_code_task_v2_internal(task_id: int, user_id: str, github_token: str)
221248
222249
echo "Starting {model_cli.upper()} Code with prompt..."
223250
224-
# Create a temporary file with the prompt
225-
echo "{escaped_prompt}" > /tmp/prompt.txt
251+
# Create a temporary file with the prompt using heredoc for proper handling
252+
cat << 'PROMPT_EOF' > /tmp/prompt.txt
253+
{prompt}
254+
PROMPT_EOF
255+
256+
# Setup Claude credentials for Claude tasks
257+
if [ "{model_cli}" = "claude" ]; then
258+
echo "Setting up Claude credentials..."
259+
260+
# Create ~/.claude directory if it doesn't exist
261+
mkdir -p ~/.claude
262+
263+
# Write credentials content directly to file
264+
if [ ! -z '{escaped_credentials}' ]; then
265+
echo "📋 Writing credentials to ~/.claude/.credentials.json"
266+
cat << 'CREDENTIALS_EOF' > ~/.claude/.credentials.json
267+
{credentials_content}
268+
CREDENTIALS_EOF
269+
echo "✅ Claude credentials configured"
270+
else
271+
echo "⚠️ No credentials content available"
272+
fi
273+
fi
226274
227275
# Check which CLI tool to use based on model selection
228276
if [ "{model_cli}" = "codex" ]; then

0 commit comments

Comments
 (0)