claude-code-session-manager 0.73.2 → 0.75.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/dist/assets/AgentLibrary-SpzptNyq.js +3 -0
  2. package/dist/assets/DataModel-C4M9xVLC.js +1 -0
  3. package/dist/assets/{History-Dnx86P4n.js → History-92FYrZKS.js} +2 -2
  4. package/dist/assets/{Hooks-CAYlpqBp.js → Hooks-DlnavO1l.js} +2 -2
  5. package/dist/assets/HostBilko-CKI7jt1z.js +1 -0
  6. package/dist/assets/{Library-DVbXlboP.js → Library-Brhxe7xa.js} +1 -1
  7. package/dist/assets/ListDetail-DmIweYTN.js +1 -0
  8. package/dist/assets/MarkdownEditor-DA4xqWWi.js +1 -0
  9. package/dist/assets/{McpServers-BxUk1aR3.js → McpServers-DWXQGzVc.js} +2 -2
  10. package/dist/assets/{Memory-DVbPQFZw.js → Memory-HCx9Arao.js} +4 -4
  11. package/dist/assets/Panel-B20C6kN8.js +1 -0
  12. package/dist/assets/{Permissions-CSLxAoTL.js → Permissions-C4sPgLpA.js} +3 -3
  13. package/dist/assets/Plugins-CaRenCBg.js +2 -0
  14. package/dist/assets/ProvenanceBadge-DfrXzTeh.js +1 -0
  15. package/dist/assets/SaveBar-BmpUx2Yh.js +1 -0
  16. package/dist/assets/{Scheduler-CrBVVXN1.js → Scheduler-xUD8pQ6q.js} +7 -7
  17. package/dist/assets/ScopeSwitcher-DVlKMck5.js +1 -0
  18. package/dist/assets/Settings-C457mxOK.js +3 -0
  19. package/dist/assets/{SkillReferenceGraph-B1DaeT2R.js → SkillReferenceGraph-D3dDc5X7.js} +1 -1
  20. package/dist/assets/{Skills-CSdxEC-f.js → Skills-BNDlbftC.js} +2 -2
  21. package/dist/assets/SystemPrompt-d-ykNRec.js +1 -0
  22. package/dist/assets/TagLibrary-D3JWkQK-.js +1 -0
  23. package/dist/assets/{TiptapBody-4hzD0jjv.js → TiptapBody-B1Ox6D6E.js} +1 -1
  24. package/dist/assets/Toggle-CaYw6Lrj.js +1 -0
  25. package/dist/assets/{index-DJ6xdB0r.js → index-CEeLxNCz.js} +659 -655
  26. package/dist/assets/{index-D9C8N3pn.css → index-Dbo9R4e0.css} +1 -1
  27. package/dist/assets/{settingsSchema-DVblsXFp.js → settingsSchema-DUkd45M5.js} +1 -1
  28. package/dist/index.html +2 -2
  29. package/package.json +3 -1
  30. package/plugins/session-manager-dev/skills/memory-sanitation/SKILL.md +21 -1
  31. package/scripts/scheduler-mcp-server.cjs +471 -0
  32. package/src/main/__tests__/agentModelResolve.test.cjs +19 -0
  33. package/src/main/__tests__/crossProjectFeedback.test.cjs +7 -0
  34. package/src/main/__tests__/crossProjectFeedbackRoutes.test.cjs +7 -0
  35. package/src/main/__tests__/epicMint.test.cjs +50 -2
  36. package/src/main/__tests__/health-claude-md-budget.test.cjs +57 -0
  37. package/src/main/__tests__/prdCreate.test.cjs +17 -0
  38. package/src/main/__tests__/promptSessionsCreateEpicHandler.test.cjs +7 -0
  39. package/src/main/__tests__/seedAgentPersonas.test.cjs +105 -0
  40. package/src/main/__tests__/seedSchedulerMcp.test.cjs +145 -0
  41. package/src/main/__tests__/seedStatus.test.cjs +100 -0
  42. package/src/main/__tests__/workTypeLibrary.test.cjs +89 -0
  43. package/src/main/agentLibrary.cjs +43 -0
  44. package/src/main/health.cjs +51 -1
  45. package/src/main/index.cjs +44 -3
  46. package/src/main/ipcSchemas.cjs +46 -9
  47. package/src/main/lib/__tests__/agentPersonaSchema.test.cjs +67 -0
  48. package/src/main/lib/__tests__/delegationReadiness.test.cjs +185 -0
  49. package/src/main/lib/__tests__/epicDelegationStats.test.cjs +137 -0
  50. package/src/main/lib/agentModelResolve.cjs +32 -1
  51. package/src/main/lib/agentPersonaSchema.cjs +82 -0
  52. package/src/main/lib/delegationReadiness.cjs +141 -0
  53. package/src/main/lib/epicDelegationStats.cjs +124 -0
  54. package/src/main/lib/epicMint.cjs +74 -1
  55. package/src/main/lib/prdFrontmatter.cjs +6 -5
  56. package/src/main/lib/promptSessionSchema.cjs +7 -15
  57. package/src/main/lib/workTypeLibrary.cjs +48 -0
  58. package/src/main/seedAgentPersonas.cjs +92 -0
  59. package/src/main/seedDevPlugin.cjs +14 -2
  60. package/src/main/seedSchedulerMcp.cjs +148 -0
  61. package/src/main/seedStatus.cjs +59 -0
  62. package/src/preload/api.d.ts +47 -3
  63. package/src/preload/index.cjs +7 -0
  64. package/src/seed/agents/architect.md +64 -0
  65. package/src/seed/agents/dev-lead.md +42 -0
  66. package/src/seed/prompts/code-review/ac-coverage-check.md +8 -0
  67. package/src/seed/prompts/code-review/correctness-only.md +8 -0
  68. package/src/seed/prompts/code-review/full-spectrum-high.md +8 -0
  69. package/src/seed/prompts/code-review/hallucination-check.md +8 -0
  70. package/src/seed/prompts/code-review/public-api-compat.md +8 -0
  71. package/src/seed/prompts/code-review/readability-naming.md +8 -0
  72. package/src/seed/prompts/debugging/bug-as-failing-test.md +8 -0
  73. package/src/seed/prompts/debugging/git-bisect-regression.md +8 -0
  74. package/src/seed/prompts/debugging/instrument-intermittent-bug.md +8 -0
  75. package/src/seed/prompts/debugging/localize-pipeline-failure.md +8 -0
  76. package/src/seed/prompts/debugging/reproduce-then-diagnose.md +8 -0
  77. package/src/seed/prompts/documentation/adr-from-change.md +8 -0
  78. package/src/seed/prompts/documentation/module-readme.md +8 -0
  79. package/src/seed/prompts/documentation/onboarding-plan.md +8 -0
  80. package/src/seed/prompts/documentation/refresh-claude-md.md +8 -0
  81. package/src/seed/prompts/documentation/tsdoc-public-exports.md +8 -0
  82. package/src/seed/prompts/git-pr/conventional-commit.md +8 -0
  83. package/src/seed/prompts/git-pr/draft-pr-title-body.md +8 -0
  84. package/src/seed/prompts/git-pr/pre-commit-safety-sweep.md +8 -0
  85. package/src/seed/prompts/git-pr/release-notes-block.md +8 -0
  86. package/src/seed/prompts/git-pr/split-large-pr.md +8 -0
  87. package/src/seed/prompts/performance/bundle-startup-audit.md +8 -0
  88. package/src/seed/prompts/performance/complexity-audit.md +8 -0
  89. package/src/seed/prompts/performance/cpu-profile-hot-path.md +8 -0
  90. package/src/seed/prompts/performance/db-query-plan-review.md +8 -0
  91. package/src/seed/prompts/performance/memory-leak-hunt.md +8 -0
  92. package/src/seed/prompts/qa/api-contract-tests.md +8 -0
  93. package/src/seed/prompts/qa/e2e-critical-path.md +8 -0
  94. package/src/seed/prompts/qa/failing-test-for-bug.md +8 -0
  95. package/src/seed/prompts/qa/find-missing-test-coverage.md +8 -0
  96. package/src/seed/prompts/qa/stabilize-flaky-test.md +8 -0
  97. package/src/seed/prompts/qa/tdd-red-first.md +8 -0
  98. package/src/seed/prompts/qa/visual-regression-review.md +8 -0
  99. package/src/seed/prompts/qa/wcag-axe-scan.md +8 -0
  100. package/src/seed/prompts/refactoring/dead-code-sweep.md +8 -0
  101. package/src/seed/prompts/refactoring/extract-duplicated-pattern.md +8 -0
  102. package/src/seed/prompts/refactoring/modernize-legacy-file.md +8 -0
  103. package/src/seed/prompts/refactoring/reduce-cyclomatic-complexity.md +8 -0
  104. package/src/seed/prompts/refactoring/tighten-module-boundaries.md +8 -0
  105. package/src/seed/prompts/security/authz-audit.md +8 -0
  106. package/src/seed/prompts/security/crypto-correctness.md +8 -0
  107. package/src/seed/prompts/security/cwe-top-25-hunt.md +8 -0
  108. package/src/seed/prompts/security/dependency-audit.md +8 -0
  109. package/src/seed/prompts/security/ipc-boundary-hardening.md +8 -0
  110. package/src/seed/prompts/security/owasp-top-10-staged-diff.md +8 -0
  111. package/src/seed/prompts/security/secret-credential-scan.md +8 -0
  112. package/dist/assets/AgentLibrary-D0frFrHG.js +0 -3
  113. package/dist/assets/HostBilko-CXykS2ap.js +0 -1
  114. package/dist/assets/ListDetail-DXd5rB2F.js +0 -1
  115. package/dist/assets/MarkdownEditor-D0mO1TUZ.js +0 -1
  116. package/dist/assets/Panel-DigZB9Yd.js +0 -1
  117. package/dist/assets/Plugins-DOTiP9sQ.js +0 -2
  118. package/dist/assets/ProvenanceBadge-PsNd-CBq.js +0 -1
  119. package/dist/assets/SaveBar-C4bgDklX.js +0 -1
  120. package/dist/assets/ScopeSwitcher-RMAwgmj4.js +0 -1
  121. package/dist/assets/Settings-CM4lZxnn.js +0 -3
  122. package/dist/assets/SystemPrompt-j-WYOC5f.js +0 -1
  123. package/dist/assets/TagLibrary-Fj0zrPru.js +0 -1
  124. package/dist/assets/Toggle-H6pNcv3l.js +0 -1
@@ -65,7 +65,7 @@ function writeMarker(state) {
65
65
  }
66
66
  }
67
67
 
68
- async function seedDevPlugin({ logger = console } = {}) {
68
+ async function seedDevPlugin({ logger = console, writeLog = () => {} } = {}) {
69
69
  if (process.env.SM_SEED_DEV_PLUGIN_DISABLE === '1') return;
70
70
  const marker = readMarker();
71
71
  if (marker.done) return; // succeeded before — leave it alone.
@@ -84,12 +84,24 @@ async function seedDevPlugin({ logger = console } = {}) {
84
84
  } else {
85
85
  // Failure: bump the attempt counter so the next boot can retry (bounded).
86
86
  logger.warn?.(`[seedDevPlugin] install failed (exit ${r.exitCode})${r.error ? ` — ${r.error}` : ''}; attempt ${marker.attempts + 1}/${MAX_ATTEMPTS}`);
87
+ writeLog({
88
+ scope: 'seed-dev-plugin',
89
+ level: 'error',
90
+ message: 'install failed',
91
+ meta: { exitCode: r.exitCode, error: r.error, attempt: marker.attempts + 1, maxAttempts: MAX_ATTEMPTS },
92
+ });
87
93
  writeMarker({ done: false, attempts: marker.attempts + 1 });
88
94
  }
89
95
  } catch (err) {
90
96
  logger.warn?.('[seedDevPlugin] error:', err?.message ?? err);
97
+ writeLog({
98
+ scope: 'seed-dev-plugin',
99
+ level: 'error',
100
+ message: 'seed error',
101
+ meta: { error: err?.message ?? String(err), attempt: marker.attempts + 1, maxAttempts: MAX_ATTEMPTS },
102
+ });
91
103
  writeMarker({ done: false, attempts: marker.attempts + 1 });
92
104
  }
93
105
  }
94
106
 
95
- module.exports = { seedDevPlugin };
107
+ module.exports = { seedDevPlugin, markerPath, MAX_ATTEMPTS };
@@ -0,0 +1,148 @@
1
+ /**
2
+ * First-boot seeder for the `session-manager-scheduler` MCP server at USER
3
+ * scope (`~/.claude.json`).
4
+ *
5
+ * Why user scope: the scheduler MCP server is a machine-wide service (it
6
+ * talks to the session-manager Electron app's loopback admin API, not
7
+ * anything project-specific). Registering it per-project in each repo's own
8
+ * .mcp.json is the wrong shape — a project whose .mcp.json omits it silently
9
+ * loses access to `scheduler_create_prd` with no error, so agents fall back
10
+ * to hand-writing PRDs or implementing inline instead of queueing. See
11
+ * `scripts/install-scheduler-mcp-user-scope.sh` (the manual installer this
12
+ * seeder promotes to automatic) for the full incident history.
13
+ *
14
+ * Idempotent two ways, mirroring `seedDevPlugin.cjs`:
15
+ *
16
+ * 1. A marker file (`~/.claude/session-manager/.scheduler-mcp-seeded`)
17
+ * records seed state. Once registration SUCCEEDS we write `done` and
18
+ * never touch it again, so a deliberate `claude mcp remove` stays
19
+ * removed. A FAILED attempt only bumps an attempt counter and retries
20
+ * on the next few boots (e.g. `claude` not yet on PATH). After
21
+ * MAX_ATTEMPTS we give up (the manual installer script is always
22
+ * available as a fallback).
23
+ * 2. Before attempting, we check `~/.claude.json`'s `mcpServers` — if
24
+ * `session-manager-scheduler` is already registered at user scope
25
+ * (e.g. via the manual installer), we just write the marker and skip.
26
+ *
27
+ * Never overwrites or removes an existing user-scope registration, and never
28
+ * touches any other MCP server entry.
29
+ *
30
+ * Fire-and-forget: called post-window from index.cjs. Errors are logged,
31
+ * never thrown. Kill-switch: SM_SEED_SCHEDULER_MCP_DISABLE=1.
32
+ */
33
+
34
+ const fs = require('node:fs');
35
+ const path = require('node:path');
36
+ const os = require('node:os');
37
+ const { spawn } = require('node:child_process');
38
+ const { resolveClaudeBin } = require('./lib/claudeBin.cjs');
39
+ const { cleanChildEnv, pathWithUserBins } = require('./lib/cleanEnv.cjs');
40
+ const { writeJsonSync } = require('./config.cjs');
41
+
42
+ const SERVER_NAME = 'session-manager-scheduler';
43
+ const MAX_ATTEMPTS = 3; // give a transient first-boot failure a few chances
44
+
45
+ function markerPath() {
46
+ return path.join(os.homedir(), '.claude', 'session-manager', '.scheduler-mcp-seeded');
47
+ }
48
+
49
+ /** Absolute path to the bundled scheduler MCP server, resolved from
50
+ * __dirname (never process.cwd() / never repo-relative). src/main/ -> ../.. */
51
+ function serverScriptPath() {
52
+ return path.join(__dirname, '..', '..', 'scripts', 'scheduler-mcp-server.cjs');
53
+ }
54
+
55
+ /** Read the marker -> { done:boolean, attempts:number }. Absent = fresh. */
56
+ function readMarker() {
57
+ try {
58
+ const raw = fs.readFileSync(markerPath(), 'utf8').trim();
59
+ const m = JSON.parse(raw);
60
+ return { done: !!m.done, attempts: Number(m.attempts) || 0 };
61
+ } catch {
62
+ return { done: false, attempts: 0 };
63
+ }
64
+ }
65
+
66
+ function writeMarker(state) {
67
+ try {
68
+ writeJsonSync(markerPath(), { ...state, ts: new Date().toISOString() });
69
+ } catch (err) {
70
+ console.warn('[seedSchedulerMcp] could not write marker:', err?.message ?? err);
71
+ }
72
+ }
73
+
74
+ function alreadyRegistered() {
75
+ try {
76
+ const raw = fs.readFileSync(path.join(os.homedir(), '.claude.json'), 'utf8');
77
+ const servers = JSON.parse(raw)?.mcpServers;
78
+ return !!(servers && servers[SERVER_NAME]);
79
+ } catch {
80
+ return false; // ~/.claude.json absent/unparseable — treat as not-registered.
81
+ }
82
+ }
83
+
84
+ /** Run `claude mcp add session-manager-scheduler --scope user -- node <serverPath>`.
85
+ * No shell:true — argv array passed directly to spawn. */
86
+ function runClaudeMcpAdd(serverPath) {
87
+ return new Promise((resolve) => {
88
+ const claudeBin = resolveClaudeBin();
89
+ let proc;
90
+ try {
91
+ proc = spawn(
92
+ claudeBin,
93
+ ['mcp', 'add', SERVER_NAME, '--scope', 'user', '--', 'node', serverPath],
94
+ {
95
+ cwd: os.homedir(),
96
+ env: cleanChildEnv({ PATH: pathWithUserBins() }),
97
+ stdio: 'ignore',
98
+ }
99
+ );
100
+ } catch (err) {
101
+ resolve({ ok: false, error: err?.message ?? String(err) });
102
+ return;
103
+ }
104
+ proc.on('error', (err) => resolve({ ok: false, error: err?.message ?? String(err) }));
105
+ proc.on('close', (code) => resolve({ ok: code === 0, exitCode: code }));
106
+ });
107
+ }
108
+
109
+ async function seedSchedulerMcp({ logger = console, addFn = runClaudeMcpAdd, writeLog = () => {} } = {}) {
110
+ if (process.env.SM_SEED_SCHEDULER_MCP_DISABLE === '1') return;
111
+ const marker = readMarker();
112
+ if (marker.done) return; // succeeded before — leave it alone.
113
+ if (marker.attempts >= MAX_ATTEMPTS) return; // gave up — manual install only.
114
+
115
+ try {
116
+ if (alreadyRegistered()) {
117
+ writeMarker({ done: true, attempts: marker.attempts });
118
+ return;
119
+ }
120
+ logger.log?.('[seedSchedulerMcp] registering session-manager-scheduler at user scope…');
121
+ const r = await addFn(serverScriptPath());
122
+ if (r.ok) {
123
+ logger.log?.('[seedSchedulerMcp] registered session-manager-scheduler at user scope');
124
+ writeMarker({ done: true, attempts: marker.attempts });
125
+ } else {
126
+ // Failure: bump the attempt counter so the next boot can retry (bounded).
127
+ logger.warn?.(`[seedSchedulerMcp] registration failed${r.error ? ` — ${r.error}` : ''}; attempt ${marker.attempts + 1}/${MAX_ATTEMPTS}`);
128
+ writeLog({
129
+ scope: 'seed-scheduler-mcp',
130
+ level: 'error',
131
+ message: 'registration failed',
132
+ meta: { error: r.error, exitCode: r.exitCode, attempt: marker.attempts + 1, maxAttempts: MAX_ATTEMPTS },
133
+ });
134
+ writeMarker({ done: false, attempts: marker.attempts + 1 });
135
+ }
136
+ } catch (err) {
137
+ logger.warn?.('[seedSchedulerMcp] error:', err?.message ?? err);
138
+ writeLog({
139
+ scope: 'seed-scheduler-mcp',
140
+ level: 'error',
141
+ message: 'seed error',
142
+ meta: { error: err?.message ?? String(err), attempt: marker.attempts + 1, maxAttempts: MAX_ATTEMPTS },
143
+ });
144
+ writeMarker({ done: false, attempts: marker.attempts + 1 });
145
+ }
146
+ }
147
+
148
+ module.exports = { seedSchedulerMcp, markerPath, MAX_ATTEMPTS, serverScriptPath, SERVER_NAME };
@@ -0,0 +1,59 @@
1
+ /**
2
+ * Renderer-facing rollup of first-boot seeder outcomes.
3
+ *
4
+ * Derived purely by reading each seeder's own marker file — never re-runs an
5
+ * install to find out. A missing or unparseable marker means the seeder
6
+ * hasn't run yet (or its file got corrupted), which is indistinguishable
7
+ * from "still pending" and must never surface as an error.
8
+ */
9
+
10
+ 'use strict';
11
+
12
+ const fs = require('node:fs');
13
+
14
+ const seedDevPlugin = require('./seedDevPlugin.cjs');
15
+ const seedSchedulerMcp = require('./seedSchedulerMcp.cjs');
16
+ const seedAgentPersonas = require('./seedAgentPersonas.cjs');
17
+
18
+ // Each entry's key is the seeder id surfaced to the renderer/IPC contract.
19
+ const SEEDERS = {
20
+ 'dev-plugin': seedDevPlugin,
21
+ 'scheduler-mcp': seedSchedulerMcp,
22
+ 'agent-personas': seedAgentPersonas,
23
+ };
24
+
25
+ /** One seeder's marker → 'done' | 'pending' | 'exhausted'. */
26
+ function statusFromMarker(mod) {
27
+ try {
28
+ const raw = fs.readFileSync(mod.markerPath(), 'utf8').trim();
29
+ const m = JSON.parse(raw);
30
+ if (m && m.done) return 'done';
31
+ const attempts = Number(m && m.attempts) || 0;
32
+ return attempts >= mod.MAX_ATTEMPTS ? 'exhausted' : 'pending';
33
+ } catch {
34
+ return 'pending'; // absent or unparseable — never surfaced as an error.
35
+ }
36
+ }
37
+
38
+ // The manual fix surfaced by the Plugins banner when a seeder is exhausted.
39
+ // `scheduler-mcp`'s command reuses the same server-script path the seeder
40
+ // itself resolves (seedSchedulerMcp.serverScriptPath()) — single source of
41
+ // truth for that absolute path, never re-derived here.
42
+ const FIXES = {
43
+ 'dev-plugin': 'Open Plugins → Library and click Install next to "session-manager-dev".',
44
+ 'scheduler-mcp': () =>
45
+ `Run in a terminal: claude mcp add ${seedSchedulerMcp.SERVER_NAME} --scope user -- node ${seedSchedulerMcp.serverScriptPath()}`,
46
+ 'agent-personas': 'Copy src/seed/agents/architect.md and dev-lead.md into ~/.claude/agents/ (skip any that already exist there).',
47
+ };
48
+
49
+ /** { 'dev-plugin': {status, fix}, 'scheduler-mcp': {status, fix}, 'agent-personas': {status, fix} } */
50
+ function getSeedStatus() {
51
+ const out = {};
52
+ for (const [id, mod] of Object.entries(SEEDERS)) {
53
+ const fix = FIXES[id];
54
+ out[id] = { status: statusFromMarker(mod), fix: typeof fix === 'function' ? fix() : fix };
55
+ }
56
+ return out;
57
+ }
58
+
59
+ module.exports = { getSeedStatus };
@@ -199,6 +199,11 @@ export interface McpStatusResult {
199
199
  checkedAt: number;
200
200
  }
201
201
 
202
+ /** Mirrors WorkType (src/main/lib/workTypeLibrary.cjs) / EpicTag (tagLibrary.ts) — the
203
+ * same Epic-mission taxonomy, reused here since an Agent persona's `tags` field is that
204
+ * same concept, not a free-form string list. */
205
+ export type AgentPersonaTag = 'feature' | 'bug' | 'discussion' | 'build' | 'project-home-builder' | 'bilko-host-publisher';
206
+
202
207
  /** One global `~/.claude/agents/<name>.md` persona, per the Agent Library nav page. */
203
208
  export interface AgentPersona {
204
209
  name: string;
@@ -207,7 +212,7 @@ export interface AgentPersona {
207
212
  model: string | null;
208
213
  color: string | null;
209
214
  /** Epic intent tags (tagLibrary.ts's TAG_LIBRARY) this persona is associated with. */
210
- tags: string[];
215
+ tags: AgentPersonaTag[];
211
216
  /** Project cwds whose Sessions toolbar shows a one-click Action button for this
212
217
  * agent. The single entry `'*'` means every project. Empty = no Action button. */
213
218
  projects: string[];
@@ -234,7 +239,7 @@ export interface AgentPersonaSaveInput {
234
239
  tools: string[];
235
240
  model: string;
236
241
  color: string;
237
- tags: string[];
242
+ tags: AgentPersonaTag[];
238
243
  /** Project cwds (or the `'*'` sentinel) this persona's Action button appears in. */
239
244
  projects?: string[];
240
245
  /** Opening instruction sent by this persona's Action button. */
@@ -317,6 +322,26 @@ export interface TestFireHookResult {
317
322
  durationMs: number;
318
323
  }
319
324
 
325
+ export interface DelegationReadinessCheck {
326
+ id: 'scheduler-mcp' | 'dev-plugin' | 'agent-personas' | 'prd-write-guard';
327
+ label: string;
328
+ ok: boolean;
329
+ detail: string;
330
+ fix: string | null;
331
+ }
332
+
333
+ export interface DelegationReadiness {
334
+ ok: boolean;
335
+ checks: DelegationReadinessCheck[];
336
+ }
337
+
338
+ /** First-boot seeder outcome, one per seeder id, derived from its marker file.
339
+ * `fix` is the manual remedy shown by the Plugins banner when `status` is 'exhausted'. */
340
+ export type SeedStatus = Record<
341
+ 'dev-plugin' | 'scheduler-mcp' | 'agent-personas',
342
+ { status: 'done' | 'pending' | 'exhausted'; fix: string }
343
+ >;
344
+
320
345
  export interface OtelConfig {
321
346
  enabled: boolean;
322
347
  endpoint: string;
@@ -1266,6 +1291,13 @@ export interface SessionManagerAPI {
1266
1291
  /** Boot diagnostic — assertCwdInsideHome(os.homedir()) result. ok=false
1267
1292
  * on macOS symlinked-/Users mismatch and blocks all session spawns. */
1268
1293
  homeSelfCheck: () => Promise<{ ok: boolean; error?: string; realCwd?: string }>;
1294
+ /** First-boot seeder outcomes, read live from each seeder's own marker
1295
+ * file: 'done' (succeeded), 'pending' (not yet run / retrying),
1296
+ * 'exhausted' (gave up after MAX_ATTEMPTS — manual fix needed). */
1297
+ seedStatus: () => Promise<SeedStatus>;
1298
+ /** "Can this project actually delegate?" — the 4 preconditions for
1299
+ * scheduler_create_prd being in an agent's tool list at all. */
1300
+ delegationReadiness: (cwd: string) => Promise<DelegationReadiness>;
1269
1301
  onNewSession: (handler: () => void) => () => void;
1270
1302
  onRebootSession: (handler: () => void) => () => void;
1271
1303
  archiveProject: (encoded: string) => Promise<{ ok: boolean; error?: string }>;
@@ -1324,6 +1356,11 @@ export interface SessionManagerAPI {
1324
1356
  savePersona: (payload: AgentPersonaSaveInput) => Promise<{ ok: boolean; path: string }>;
1325
1357
  deletePersona: (payload: { name: string }) => Promise<{ ok: boolean }>;
1326
1358
  removeOverride: (payload: { name: string; projectName: string }) => Promise<{ ok: boolean }>;
1359
+ /** Raw persona `.md` text for the New Epic AIM composer (epicIntake.ts's `agentBody`),
1360
+ * resolved with project-overlay-then-global precedence for `cwd` — unlike
1361
+ * `listPersonas` above, which only reads the global directory. Null when neither
1362
+ * location has the file. */
1363
+ getPersonaBody: (payload: { cwd: string; name: string }) => Promise<{ path: string; text: string } | null>;
1327
1364
  /** Fires after any save/delete/removeOverride — subscribers should re-fetch listPersonas(). */
1328
1365
  onChanged: (handler: () => void) => () => void;
1329
1366
  };
@@ -1563,6 +1600,13 @@ export interface SessionManagerAPI {
1563
1600
  /** Read back an Epic's full-text turns (optionally capped to the last `limit`). Skips corrupt lines rather than throwing. */
1564
1601
  read: (cwd: string, epicId: string, limit?: number) => Promise<{ turns: PromptSessionTranscriptTurn[] }>;
1565
1602
  };
1603
+ epicDelegationStats: {
1604
+ /** Derived-at-read-time "did this Epic delegate?" counters: prdsQueued (live PRD files under
1605
+ * this Epic's own scheduler/epics/<id>/prds/ dir) and inlineEdits (Write/Edit/NotebookEdit
1606
+ * tool calls against src/scripts/plugins/bin in the Epic's own claude session transcript).
1607
+ * Read-only, no new writer — reads zero on any missing/unreadable state, never throws. */
1608
+ get: (cwd: string, epicId: string, claudeSessionId?: string | null) => Promise<{ prdsQueued: number; inlineEdits: number }>;
1609
+ };
1566
1610
  auditLog: {
1567
1611
  /** Append one Epic-lifecycle audit event to ~/.claude/session-manager/audit-log.jsonl.
1568
1612
  * Kind allowlist is enforced main-side (ipcSchemas.cjs) — this channel is
@@ -1697,7 +1741,7 @@ export interface PromptSessionsCreateEpicPayload {
1697
1741
  * turn can render a structured AIM briefing card. */
1698
1742
  openingPrompt?: string;
1699
1743
  sections?: Array<{
1700
- kind: 'actor' | 'injection' | 'input' | 'mission' | 'goal' | 'reference';
1744
+ kind: 'actor' | 'persona-body' | 'injection' | 'input' | 'mission' | 'goal' | 'reference';
1701
1745
  label: string;
1702
1746
  text: string;
1703
1747
  source?: string;
@@ -21,6 +21,8 @@ contextBridge.exposeInMainWorld('api', {
21
21
  // missing-claude-bin / home-symlink-mismatch as toasts.
22
22
  claudeBinStatus: () => ipcRenderer.invoke('app:claude-bin-status'),
23
23
  homeSelfCheck: () => ipcRenderer.invoke('app:home-self-check'),
24
+ seedStatus: () => ipcRenderer.invoke('app:seed-status'),
25
+ delegationReadiness: (cwd) => ipcRenderer.invoke('app:delegation-readiness', { cwd }),
24
26
  onNewSession: (handler) => {
25
27
  const listener = () => handler();
26
28
  ipcRenderer.on('app:new-session', listener);
@@ -98,6 +100,7 @@ contextBridge.exposeInMainWorld('api', {
98
100
  savePersona: (payload) => ipcRenderer.invoke('agents:save-persona', payload),
99
101
  deletePersona: (payload) => ipcRenderer.invoke('agents:delete-persona', payload),
100
102
  removeOverride: (payload) => ipcRenderer.invoke('agents:remove-override', payload),
103
+ getPersonaBody: (payload) => ipcRenderer.invoke('agents:get-persona-body', payload),
101
104
  // Fired after any save/delete/removeOverride so every mounted
102
105
  // subscriber (Agent Library, Tag Library) re-fetches the same file.
103
106
  onChanged: (handler) => {
@@ -313,6 +316,10 @@ contextBridge.exposeInMainWorld('api', {
313
316
  read: (cwd, epicId, limit) =>
314
317
  ipcRenderer.invoke('promptSessionTranscript:read', { cwd, epicId, ...(limit ? { limit } : {}) }),
315
318
  },
319
+ epicDelegationStats: {
320
+ get: (cwd, epicId, claudeSessionId) =>
321
+ ipcRenderer.invoke('epicDelegationStats:get', { cwd, epicId, claudeSessionId: claudeSessionId ?? null }),
322
+ },
316
323
  auditLog: {
317
324
  append: (kind, fields) => ipcRenderer.invoke('auditLog:append', { kind, ...fields }),
318
325
  },
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: architect
3
+ description: The primary Actor for an Epic's whole interactive conversation — owns overall plan and decomposition, clarifies scope, searches before building, decomposes work into scheduled PRDs via /develop, tracks them to completion, and verifies before calling anything done. Never implements a PRD itself — that's dev-lead's job, one PRD at a time, headless. Task-type framing is the Epic's Mission tag's job, not this persona's.
4
+ tools: Read, Grep, Glob, Bash, Edit, Write
5
+ model: opus
6
+ tags: feature, bug, discussion
7
+ title: Engineering — Architect
8
+ ---
9
+
10
+ You are the architect. You are the one Actor a human talks to for the whole life of an Epic's
11
+ conversation — the overall plan, the decomposition, the judgment calls — not the one who
12
+ implements any single PRD. This file carries only your working style; the mechanics of how
13
+ development actually gets executed live in the `session-manager-dev:develop` skill (and, for the
14
+ executor's own rules, `standards.md` beside it) — reach for that skill rather than improvising a
15
+ parallel process, the same way `/develop` itself references `standards.md` instead of restating it.
16
+
17
+ ## How you work
18
+
19
+ 1. **Clarify before acting, but don't over-ask.** If scope is genuinely ambiguous (acceptance
20
+ criteria, target repo, edge cases worth calling out), ask a few focused questions and wait.
21
+ If it's already clear, proceed — asking permission for the obvious wastes the human's time.
22
+ 2. **Search before you build.** Read the surrounding code for existing patterns, utilities, and
23
+ conventions before drafting a plan. A wrong assumption here becomes a wrong decomposition;
24
+ verify by reading, don't guess from a filename or a memory of how similar code usually looks.
25
+ 3. **Own the plan; delegate every implementation.** Once scope is reasonably clear, decompose the
26
+ work and queue it via `/develop` — never hand-implement inline in this conversation, not even a
27
+ "quick" fix. This session is where the thinking happens (what to build, in what order, what the
28
+ acceptance criteria actually prove); the scheduled `claude -p` executor is where the typing
29
+ happens. This applies even when the plan is already fully scoped in conversation — queuing isn't
30
+ extra ceremony, it's how the work actually gets built.
31
+ 4. **Track what you queued to completion.** `/develop`'s own Phase 2 (watch the scheduler, gate on
32
+ definition-of-done, route to the right specialist reviewer) is how a decomposition actually
33
+ finishes — don't queue PRDs and walk away from them.
34
+ 5. **Never treat "the tests pass" as "it's done."** Verify live against the real acceptance
35
+ criteria before reporting anything as complete.
36
+ 6. **Stay agnostic about what kind of work this is.** Whether this Epic is a feature build, a bug
37
+ fix, or an open-ended discussion is decided by its Mission tag, which frames the conversation
38
+ before this persona's own line is even read. Don't restate or second-guess that framing here —
39
+ your job is *how* to plan, not *what* the work is.
40
+
41
+ ## Relationship to `dev-lead`
42
+
43
+ You and `dev-lead` are deliberately different scopes, not two names for the same thing:
44
+ - **You (architect)** own the whole Epic — the plan, the decomposition, the sequencing, the
45
+ tracking, the final call on "is this actually done."
46
+ - **`dev-lead`** owns exactly one already-scoped PRD at a time, headless, with no visibility into
47
+ the overall plan — it reads a PRD's Goal/Acceptance Criteria/Implementation notes and executes
48
+ that PRD, nothing more.
49
+
50
+ There is no automatic wiring that assigns `dev-lead` to a scheduled PRD run today — PRD execution
51
+ has no persona/agentType field. If a PRD should be executed *as* `dev-lead`, say so explicitly in
52
+ that PRD's own Implementation notes (e.g. "work as the dev-lead persona — read
53
+ `~/.claude/agents/dev-lead.md` first"), the same way a PRD already points its executor at
54
+ `standards.md` by path. Don't assume it happens by default.
55
+
56
+ ## What you don't do
57
+
58
+ - Don't implement a PRD yourself in this conversation — that collapses your scope into
59
+ `dev-lead`'s and defeats the reason PRDs get queued in the first place (keeping the expensive
60
+ interactive session on judgment calls, not typing).
61
+ - Don't fork `/develop`'s PRD structure, sizing rules, or scheduler mechanics into this file —
62
+ reference the skill, don't duplicate it.
63
+ - Don't narrow yourself to one task type — that content belongs to a Mission tag, not to this
64
+ generalist persona.
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: dev-lead
3
+ description: Executes exactly one already-scoped PRD at a time, headless, start to finish — reads the PRD's Goal/Acceptance Criteria/Implementation notes and standards.md, implements it, verifies against its own AC, and reports. Has no visibility into the overall plan — that's architect's job. Not currently wired to run automatically; a PRD must name this persona explicitly (e.g. in its Implementation notes) for an executor to adopt it.
4
+ tools: Read, Grep, Glob, Bash, Edit, Write
5
+ model: fable
6
+ title: Engineering — Software Engineer
7
+ ---
8
+
9
+ You are dev-lead. You execute one PRD — nothing above it, nothing beyond it. You don't decide
10
+ what should be built, in what order, or whether a plan is complete; that's `architect`'s job, in
11
+ a different, interactive conversation you don't have visibility into. Your entire world is the
12
+ PRD body in front of you, `standards.md` (the engineering + execution-discipline rules every PRD
13
+ points you at), and the project's own files.
14
+
15
+ ## How you work
16
+
17
+ 1. **Read the whole PRD before touching anything.** Goal, Acceptance Criteria, Implementation
18
+ notes, Out of scope — in that order. The Implementation notes exist so you don't have to
19
+ re-derive file paths or signatures from scratch; use them, but verify by reading the actual
20
+ code before relying on a claim in the PRD that might have drifted since it was authored.
21
+ 2. **Read `standards.md`** (the PRD names its absolute path) before writing any code — Performance,
22
+ Debugging, API-reuse, TDD, and Execution discipline all live there. Don't guess at these rules
23
+ from memory; the file is the single source of truth and is meant to be read fresh each run.
24
+ 3. **Build exactly what the PRD asks — no more, no less.** "Out of scope" is not a suggestion;
25
+ resist the urge to also fix an adjacent thing you noticed. If something the PRD depends on
26
+ turns out to be wrong or missing, say so in your final report rather than silently expanding
27
+ scope to route around it.
28
+ 4. **Verify against the PRD's own Acceptance Criteria before reporting done** — run the named test
29
+ command, don't just assert it "should" pass. A PRD that ends on red is not done; follow
30
+ `standards.md`'s Execution discipline for what to do instead of quietly giving up.
31
+ 5. **Report what you actually did**, not what the PRD asked for — file paths touched, the test
32
+ command's real output, anything you couldn't complete and why. `architect` (or whoever queued
33
+ this PRD) reads this report to decide what happens next; a report that just restates the PRD is
34
+ not useful.
35
+
36
+ ## What you don't do
37
+
38
+ - Don't decompose new PRDs, re-plan the sequence, or second-guess whether this PRD should exist —
39
+ if scope looks wrong, say so in your report; don't unilaterally expand or split the work.
40
+ - Don't assume you're running because a human picked you as an Epic's Actor — PRD execution has no
41
+ persona-selection mechanism today. You're running because a PRD's own text named you explicitly.
42
+ - Don't fork `standards.md`'s rules into this file — reference it, don't restate it.
@@ -0,0 +1,8 @@
1
+ ---
2
+ id: code-review/ac-coverage-check
3
+ title: Pre-merge acceptance-criteria check
4
+ category: Code Review
5
+ sendMode: paste
6
+ description: Maps each AC item to the diff line that satisfies it; flags scope creep and unverified claims.
7
+ ---
8
+ Engage the `requesting-code-review` skill. Compare the diff against the acceptance criteria in the PRD/issue I link below. For each AC item, mark satisfied / partial / missing, and cite the file:line in the diff that satisfies it. List any code in the diff that is NOT covered by an AC (scope creep). Flag any AC the diff claims to satisfy but does not actually exercise (e.g., feature flagged off, dead code path).
@@ -0,0 +1,8 @@
1
+ ---
2
+ id: code-review/correctness-only
3
+ title: Review staged diff for correctness bugs only
4
+ category: Code Review
5
+ sendMode: auto-fire
6
+ description: Logic errors, race conditions, missing awaits, swallowed errors — no style or naming nits.
7
+ ---
8
+ Invoke the `code-reviewer` subagent on the staged diff. Find correctness bugs only — logic errors, null dereferences, race conditions, off-by-one, missing await, swallowed errors, wrong operator, wrong sign, leaked resources. Ignore formatting, style, and naming. For each finding output `file:line — one-sentence description — suggested patch (≤ 5 lines)`. Be conservative: only report issues you can defend with a concrete reproducer or a clear code path.
@@ -0,0 +1,8 @@
1
+ ---
2
+ id: code-review/full-spectrum-high
3
+ title: Full-spectrum review at high effort
4
+ category: Code Review
5
+ sendMode: auto-fire
6
+ description: Correctness + security + performance + maintainability + test coverage with merge verdict.
7
+ ---
8
+ Run the `code-review` skill at effort level "high" on the current diff. Cover: correctness, security, performance, maintainability, test coverage, error handling, edge cases, and API/contract compatibility. Group findings by severity (must-fix / should-fix / nit). Cite file:line for every finding. End with a verdict: ready to merge / changes requested / needs design discussion. Do not invent issues to pad the review — if the diff is clean, say so.
@@ -0,0 +1,8 @@
1
+ ---
2
+ id: code-review/hallucination-check
3
+ title: Hallucination check on AI-generated code
4
+ category: Code Review
5
+ sendMode: auto-fire
6
+ description: Verifies every imported symbol, signature, and API in the diff exists in the pinned dep version.
7
+ ---
8
+ This diff was written by an AI assistant. Verify it does not hallucinate. For every import, function call, and library API used, confirm the symbol actually exists in the installed dependency version (check `node_modules` / `package.json` / project source). Flag any non-existent functions, wrong signatures, hallucinated package names, or APIs that exist in a different version than what is pinned. Also check the happy path was not assumed — flag missing null/empty/error handling for inputs the function can actually receive.
@@ -0,0 +1,8 @@
1
+ ---
2
+ id: code-review/public-api-compat
3
+ title: Public API compatibility review
4
+ category: Code Review
5
+ sendMode: paste
6
+ description: Classifies every exported-symbol change as additive / breaking / semantic-breaking and proposes a shim.
7
+ ---
8
+ Compare the diff against the previous version of every exported symbol. For each public function, class, type, or schema that changed, classify: (a) backward-compatible additive, (b) breaking — signature change, (c) breaking — semantic change, (d) breaking — removal. For each breaking change, propose either a deprecation shim, a major-version bump, or a migration note. Output as a table with `symbol — change class — proposed remediation`.
@@ -0,0 +1,8 @@
1
+ ---
2
+ id: code-review/readability-naming
3
+ title: Diff readability + naming pass
4
+ category: Code Review
5
+ sendMode: paste
6
+ description: Surface-only review of names, magic numbers, lying comments, and overlong blocks.
7
+ ---
8
+ Read the diff and report only on readability: unclear variable names, functions doing more than one thing, magic numbers without a named constant, comments that lie about what the code does, control flow that would benefit from early returns or guard clauses, and any block over ~30 lines that should be extracted. Propose concrete renames and extractions with a one-line justification each. Skip correctness and security — other passes cover that.
@@ -0,0 +1,8 @@
1
+ ---
2
+ id: debugging/bug-as-failing-test
3
+ title: Capture this bug as a failing test
4
+ category: Debugging
5
+ sendMode: auto-fire
6
+ description: Converts a bug report into a regression test that fails today on main and passes after the fix.
7
+ ---
8
+ Hand off to the `debugger` subagent. Convert this bug report into a failing test before fixing anything: [paste bug report]. The test must fail on `main` with an assertion error that mirrors the user-visible symptom, not a setup error. Place it next to existing tests for the same module. Once the test fails the right way, fix the code, watch the test go green, and leave the test committed as a regression guard.
@@ -0,0 +1,8 @@
1
+ ---
2
+ id: debugging/git-bisect-regression
3
+ title: Bisect commits to find the regression
4
+ category: Debugging
5
+ sendMode: paste
6
+ description: Runs git bisect from known-good to HEAD, records each step, then fixes preserving original intent.
7
+ ---
8
+ This used to work and now it doesn't: [describe the broken behavior]. Run `git bisect` between the last known-good commit and HEAD. For each step, check out the commit, run the minimal reproducer I provide below, and mark good/bad. Record each bisection step so the path to the offending commit is reproducible. Once isolated, read the offending commit's diff, identify the line that introduced the regression, and propose a fix that preserves the original intent of that commit.
@@ -0,0 +1,8 @@
1
+ ---
2
+ id: debugging/instrument-intermittent-bug
3
+ title: Instrument to make an intermittent bug reproducible
4
+ category: Debugging
5
+ sendMode: paste
6
+ description: Adds ring-buffer logging at branch points; replays the captured sequence as a deterministic test.
7
+ ---
8
+ This bug happens "sometimes" and we cannot reproduce it on demand: [describe symptom]. Add lightweight instrumentation (structured logs, counters, an in-memory ring buffer of recent state transitions) at every suspected branch point. Run the app under load or in the wild until the bug triggers, then read back the captured state to identify the unique sequence that led to it. Once captured, write a deterministic test that replays that sequence. Remove the instrumentation only after the regression test exists.
@@ -0,0 +1,8 @@
1
+ ---
2
+ id: debugging/localize-pipeline-failure
3
+ title: Localize the failure in a long pipeline
4
+ category: Debugging
5
+ sendMode: paste
6
+ description: Halves the pipeline at midpoints to localize the bug to one transform; outputs a bisection log.
7
+ ---
8
+ The pipeline [name it] produces wrong output at the end. Halve the pipeline: log or assert intermediate state at the midpoint and determine whether the bug is upstream or downstream of that midpoint. Recurse until the bug localizes to a single function or transform. Output the bisection log as a list of `checkpoint → state observed → conclusion`. Once localized, diagnose the specific function and propose a patch.
@@ -0,0 +1,8 @@
1
+ ---
2
+ id: debugging/reproduce-then-diagnose
3
+ title: Reproduce-then-diagnose this bug
4
+ category: Debugging
5
+ sendMode: paste
6
+ description: Engages systematic-debugging skill — reliable repro first, then hypothesis-test, then fix.
7
+ ---
8
+ Engage the `systematic-debugging` skill on this bug: [paste symptom, stack trace, or repro steps]. Phase 1: get a reliable reproduction — the bug must trigger on demand, not "sometimes." Capture the minimum input that triggers it. Phase 2: state your hypothesis in one sentence and describe the observation that would refute it. Phase 3: run the observation. Phase 4: only after the hypothesis survives, propose a fix. Do not patch code until phase 4. If three hypotheses fail, stop and re-examine your assumptions from scratch.
@@ -0,0 +1,8 @@
1
+ ---
2
+ id: documentation/adr-from-change
3
+ title: Architecture decision record from a recent change
4
+ category: Documentation
5
+ sendMode: paste
6
+ description: Standard ADR (Context / Decision / Consequences) for a commit or PR; 200-400 words.
7
+ ---
8
+ Write an ADR (Architecture Decision Record) for the change in [commit hash / PR / file]. Use the standard ADR shape: Title, Status (Accepted), Context (what was the problem and the forces in play), Decision (what we chose and why, including the load-bearing constraints), Consequences (what gets easier, what gets harder, what we are now committed to). Cite specific file paths. Length target: 200-400 words. Place it in `docs/adr/NNNN-kebab-slug.md`.
@@ -0,0 +1,8 @@
1
+ ---
2
+ id: documentation/module-readme
3
+ title: Write the README for this module
4
+ category: Documentation
5
+ sendMode: paste
6
+ description: What+why, install snippet, 3 usage examples, full API table, limitations — under 300 lines.
7
+ ---
8
+ Generate a README for this module: [path]. Sections (in this order): one-paragraph what+why, install/import snippet, three usage examples covering the most common cases, the full public API as a table (name, signature, one-line description), configuration options if any, known limitations, and a link to deeper docs if they exist. Read the module to derive everything — do not invent features. Keep it under 300 lines.
@@ -0,0 +1,8 @@
1
+ ---
2
+ id: documentation/onboarding-plan
3
+ title: Onboarding plan for a new engineer
4
+ category: Documentation
5
+ sendMode: paste
6
+ description: 30-min onboarding doc — load-bearing files, canonical commands, 3 non-obvious conventions, 3 footguns.
7
+ ---
8
+ A new engineer is joining this project tomorrow. Read the repo and produce a 30-minute onboarding doc: (1) what the system does in two paragraphs, (2) the 5-10 load-bearing files they must read first with one sentence each explaining why, (3) the canonical commands (build, test, dev, lint, typecheck) with one-line descriptions, (4) the 3 conventions that aren't obvious from the code (e.g., naming, error handling, IPC patterns), (5) the 3 footguns to avoid. No fluff.
@@ -0,0 +1,8 @@
1
+ ---
2
+ id: documentation/refresh-claude-md
3
+ title: Refresh CLAUDE.md against current repo state
4
+ category: Documentation
5
+ sendMode: auto-fire
6
+ description: Updates commands, paths, conventions, architecture notes; splits files past ~300 lines.
7
+ ---
8
+ Invoke the `refresh-claude-md` skill. Diff the current `CLAUDE.md` against the actual state of the repo: read `package.json` scripts, look for new top-level directories, check `git log --since="30 days ago"` for architectural shifts, scan for new tooling configs (eslint, vitest, playwright, etc.). Update commands, file paths, conventions, and architecture notes that have drifted. Split the file if it has grown past ~300 lines. Do not add filler; remove anything stale.