Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ const projectChats = db.select().from(chats).where(eq(chats.projectId, id)).all(
- **React Query**: Server state via tRPC (auto-caching, refetch)

### Claude Integration
- Dynamic import of `@anthropic-ai/claude-code` SDK
- Dynamic import of `@anthropic-ai/claude-agent-sdk` SDK
- Two modes: "plan" (read-only) and "agent" (full permissions)
- Session resume via `sessionId` stored in SubChat
- Message streaming via tRPC subscription (`claude.onMessage`)
Expand Down
7 changes: 7 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
bun install
bun run claude:download # Download Claude binary (required!)
bun run codex:download # Download Codex binary (required!)
bun run build
bun run package:mac
bun run package:win
bun run package:linux
6 changes: 3 additions & 3 deletions openspec/project.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
| Components | Radix UI, Lucide icons, Motion, Sonner |
| State | Jotai, Zustand, React Query |
| Backend | tRPC, Drizzle ORM, better-sqlite3 |
| AI | @anthropic-ai/claude-code |
| AI | @anthropic-ai/claude-agent-sdk |
| Package Manager | bun |

## Project Conventions
Expand All @@ -30,7 +30,7 @@
- Zustand: Sub-chat tabs and pinned state (persisted to localStorage)
- React Query: Server state via tRPC (auto-caching, refetch)
- **Database**: Drizzle ORM with SQLite, auto-migration on app startup
- **Claude Integration**: Dynamic import of `@anthropic-ai/claude-code` SDK with two modes: "plan" (read-only) and "agent" (full permissions)
- **Claude Integration**: Dynamic import of `@anthropic-ai/claude-agent-sdk` SDK with two modes: "plan" (read-only) and "agent" (full permissions)

### Testing Strategy
[Testing approach not yet established - to be defined]
Expand All @@ -53,6 +53,6 @@
- Dev vs Production use separate userData paths and protocols

## External Dependencies
- **Claude Code SDK**: `@anthropic-ai/claude-code` for AI interactions
- **Claude Code SDK**: `@anthropic-ai/claude-agent-sdk` for AI interactions
- **21st.dev CDN**: Auto-update manifests and releases at `cdn.21st.dev`
- **OAuth Provider**: Authentication flow
31 changes: 14 additions & 17 deletions src/main/lib/trpc/routers/claude.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1772,7 +1772,7 @@ ${prompt}
includePartialMessages: true,
// Load skills from project and user directories (skip for Ollama - not supported)
...(!isUsingOllama && {
settingSources: ["project" as const, "user" as const],
settingSources: ["project" as const, "local" as const, "user" as const],
}),
canUseTool: async (
toolName: string,
Expand Down Expand Up @@ -1979,23 +1979,20 @@ ${prompt}
pathToClaudeCodeExecutable: claudeBinaryPath,
// Session handling: For Ollama, use resume with session ID to maintain history
// For Claude API, use resume with rollback/fork support
...(resumeSessionId && {
resume: resumeSessionId,
// Fork support - resume at specific point and create new session
...(shouldForkResume && forkResumeAtUuid && !isUsingOllama
? {
resumeSessionAt: forkResumeAtUuid,
forkSession: true,
}
: // Rollback support - resume at specific message UUID (from DB)
resumeAtUuid && !isUsingOllama
? { resumeSessionAt: resumeAtUuid }
: { continue: true }),
}),
// For first message in chat (no session ID yet), use continue mode
...(!resumeSessionId && { continue: true }),
// resume is mutually exclusive with continue (SDK contract)
...(resumeSessionId
? {
resume: resumeSessionId,
// Fork support - resume at specific point and create new session
...(shouldForkResume && forkResumeAtUuid && !isUsingOllama
? { resumeSessionAt: forkResumeAtUuid, forkSession: true }
: // Rollback support - resume at specific message UUID (from DB)
resumeAtUuid && !isUsingOllama
? { resumeSessionAt: resumeAtUuid }
: {}),
}
: { continue: true }),
...(resolvedModel && { model: resolvedModel }),
// fallbackModel: "claude-opus-4-5-20251101",
...(input.effort && { effort: input.effort }),
},
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -760,7 +760,7 @@ export function AgentsModelsTab() {
onChange={(e) => setModel(e.target.value)}
onBlur={handleBlurSave}
className="w-full"
placeholder="claude-3-7-sonnet-20250219"
placeholder="claude-sonnet-4-6"
/>
</div>
</div>
Expand Down
11 changes: 2 additions & 9 deletions src/renderer/features/agents/lib/ipc-chat-transport.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,9 @@ const ERROR_TOAST_CONFIG: Record<
"Your previous chat session expired. Send your message again to start fresh.",
},
EXECUTABLE_NOT_FOUND: {
title: "Claude CLI not found",
title: "Claude binary missing",
description:
"Install Claude Code CLI: npm install -g @anthropic-ai/claude-code",
action: {
label: "Copy command",
onClick: () =>
navigator.clipboard.writeText(
"npm install -g @anthropic-ai/claude-code",
),
},
"The bundled Claude binary could not be found. Reinstalling 1Code should restore it.",
},
NETWORK_ERROR: {
title: "Network error",
Expand Down