diff options
| author | bndw <ben@bdw.to> | 2026-02-28 21:08:40 -0800 |
|---|---|---|
| committer | bndw <ben@bdw.to> | 2026-02-28 21:08:40 -0800 |
| commit | 04c63d4ef601876186e5d7fab980d76575c494ec (patch) | |
| tree | 2620784e148957ae2ee3af0327c2b128983577e7 /src/main/claude | |
| parent | 0da42e4fa414ab3268d4f71896455097239f8590 (diff) | |
feat: **1. `src/main/db/schema.ts`** — add `settings` table … (+10 more)
- ✅ **1. `src/main/db/schema.ts`** — add `settings` table to `initSchema`
- ✅ **2. `src/main/db/settings.ts`** — create file with `getSetting`, `getSettings`, `setSetting`, `deleteSetting`
- ✅ **3. `src/main/claude/phases.ts`** — add `customSystemPrompt?` param to `getPhaseConfig`; add `getDefaultSystemPromptTemplate` export
- ✅ **4. `src/main/claude/index.ts`** — import `getSetting`; load custom prompt in `sendMessage`; pass to `getPhaseConfig`
- ✅ **5. `src/main/ipc/handlers.ts`** — import `settingsDb` + `getDefaultSystemPromptTemplate`; register `settings:get`, `settings:set`, `settings:delete`, `settings:getDefaultPrompts`
- ✅ **6. `src/main/preload.ts`** — add `getSettings`, `setSetting`, `deleteSetting`, `getDefaultSystemPrompts` to interface + api object
- ✅ **7. `renderer/src/styles/globals.css`** — append all new CSS rules
- ✅ **8. `renderer/src/components/settings/SystemPromptsSettings.tsx`** — create file (new directory)
- ✅ **9. `renderer/src/components/SettingsPage.tsx`** — create file
- ✅ **10. `renderer/src/components/Header.tsx`** — add `onOpenSettings` prop + ⚙ button
- ✅ **11. `renderer/src/App.tsx`** — add `showSettings` state; import + render `<SettingsPage>`; pass `onOpenSettings` to Header
Diffstat (limited to 'src/main/claude')
| -rw-r--r-- | src/main/claude/index.ts | 7 | ||||
| -rw-r--r-- | src/main/claude/phases.ts | 22 |
2 files changed, 26 insertions, 3 deletions
diff --git a/src/main/claude/index.ts b/src/main/claude/index.ts index 8971844..30a0f57 100644 --- a/src/main/claude/index.ts +++ b/src/main/claude/index.ts | |||
| @@ -4,6 +4,7 @@ import { getPhaseConfig, getNextPhase, getArtifactFilename } from "./phases"; | |||
| 4 | import type { Phase, UserPermissionMode } from "./phases"; | 4 | import type { Phase, UserPermissionMode } from "./phases"; |
| 5 | import { getProject } from "../db/projects"; | 5 | import { getProject } from "../db/projects"; |
| 6 | import { updateSession } from "../db/sessions"; | 6 | import { updateSession } from "../db/sessions"; |
| 7 | import { getSetting } from "../db/settings"; | ||
| 7 | import { autoCommitTurn } from "../git"; | 8 | import { autoCommitTurn } from "../git"; |
| 8 | import fs from "node:fs"; | 9 | import fs from "node:fs"; |
| 9 | import path from "node:path"; | 10 | import path from "node:path"; |
| @@ -44,10 +45,14 @@ export async function sendMessage({ | |||
| 44 | const sessionDir = getSessionDir(project.path, session.id); | 45 | const sessionDir = getSessionDir(project.path, session.id); |
| 45 | ensureDir(sessionDir); | 46 | ensureDir(sessionDir); |
| 46 | 47 | ||
| 48 | // Load any custom system prompt for this phase (null → use default) | ||
| 49 | const customSystemPrompt = getSetting(`systemPrompt.${session.phase}`) ?? undefined; | ||
| 50 | |||
| 47 | const phaseConfig = getPhaseConfig( | 51 | const phaseConfig = getPhaseConfig( |
| 48 | session.phase as Phase, | 52 | session.phase as Phase, |
| 49 | sessionDir, | 53 | sessionDir, |
| 50 | session.permission_mode as UserPermissionMode | 54 | session.permission_mode as UserPermissionMode, |
| 55 | customSystemPrompt | ||
| 51 | ); | 56 | ); |
| 52 | 57 | ||
| 53 | const q = query({ | 58 | const q = query({ |
diff --git a/src/main/claude/phases.ts b/src/main/claude/phases.ts index 89e7c22..a1cbba1 100644 --- a/src/main/claude/phases.ts +++ b/src/main/claude/phases.ts | |||
| @@ -160,11 +160,20 @@ When complete, summarize what was done and any follow-up tasks.`, | |||
| 160 | export function getPhaseConfig( | 160 | export function getPhaseConfig( |
| 161 | phase: Phase, | 161 | phase: Phase, |
| 162 | artifactDir: string, | 162 | artifactDir: string, |
| 163 | userPermissionMode?: UserPermissionMode | 163 | userPermissionMode?: UserPermissionMode, |
| 164 | customSystemPrompt?: string | ||
| 164 | ): PhaseConfig { | 165 | ): PhaseConfig { |
| 165 | const template = phaseConfigTemplates[phase]; | 166 | const template = phaseConfigTemplates[phase]; |
| 167 | |||
| 168 | // If a custom prompt is provided, substitute the {{artifactDir}} placeholder. | ||
| 169 | // Otherwise use the default template function (existing behaviour). | ||
| 170 | const systemPrompt = | ||
| 171 | customSystemPrompt !== undefined | ||
| 172 | ? customSystemPrompt.replace(/\{\{artifactDir\}\}/g, artifactDir) | ||
| 173 | : template.systemPrompt(artifactDir); | ||
| 174 | |||
| 166 | const config: PhaseConfig = { | 175 | const config: PhaseConfig = { |
| 167 | systemPrompt: template.systemPrompt(artifactDir), | 176 | systemPrompt, |
| 168 | tools: template.tools, | 177 | tools: template.tools, |
| 169 | permissionMode: template.permissionMode, | 178 | permissionMode: template.permissionMode, |
| 170 | initialMessage: template.initialMessage, | 179 | initialMessage: template.initialMessage, |
| @@ -175,6 +184,15 @@ export function getPhaseConfig( | |||
| 175 | return config; | 184 | return config; |
| 176 | } | 185 | } |
| 177 | 186 | ||
| 187 | /** | ||
| 188 | * Returns the default system prompt for a phase with "{{artifactDir}}" as a | ||
| 189 | * literal placeholder — the same format used when storing a custom prompt in | ||
| 190 | * the settings DB. Used by the Settings UI to display the default text. | ||
| 191 | */ | ||
| 192 | export function getDefaultSystemPromptTemplate(phase: Phase): string { | ||
| 193 | return phaseConfigTemplates[phase].systemPrompt("{{artifactDir}}"); | ||
| 194 | } | ||
| 195 | |||
| 178 | export function getPhaseInitialMessage(phase: Phase): string { | 196 | export function getPhaseInitialMessage(phase: Phase): string { |
| 179 | return phaseConfigTemplates[phase].initialMessage; | 197 | return phaseConfigTemplates[phase].initialMessage; |
| 180 | } | 198 | } |
