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.
- package/dist/assets/AgentLibrary-SpzptNyq.js +3 -0
- package/dist/assets/DataModel-C4M9xVLC.js +1 -0
- package/dist/assets/{History-Dnx86P4n.js → History-92FYrZKS.js} +2 -2
- package/dist/assets/{Hooks-CAYlpqBp.js → Hooks-DlnavO1l.js} +2 -2
- package/dist/assets/HostBilko-CKI7jt1z.js +1 -0
- package/dist/assets/{Library-DVbXlboP.js → Library-Brhxe7xa.js} +1 -1
- package/dist/assets/ListDetail-DmIweYTN.js +1 -0
- package/dist/assets/MarkdownEditor-DA4xqWWi.js +1 -0
- package/dist/assets/{McpServers-BxUk1aR3.js → McpServers-DWXQGzVc.js} +2 -2
- package/dist/assets/{Memory-DVbPQFZw.js → Memory-HCx9Arao.js} +4 -4
- package/dist/assets/Panel-B20C6kN8.js +1 -0
- package/dist/assets/{Permissions-CSLxAoTL.js → Permissions-C4sPgLpA.js} +3 -3
- package/dist/assets/Plugins-CaRenCBg.js +2 -0
- package/dist/assets/ProvenanceBadge-DfrXzTeh.js +1 -0
- package/dist/assets/SaveBar-BmpUx2Yh.js +1 -0
- package/dist/assets/{Scheduler-CrBVVXN1.js → Scheduler-xUD8pQ6q.js} +7 -7
- package/dist/assets/ScopeSwitcher-DVlKMck5.js +1 -0
- package/dist/assets/Settings-C457mxOK.js +3 -0
- package/dist/assets/{SkillReferenceGraph-B1DaeT2R.js → SkillReferenceGraph-D3dDc5X7.js} +1 -1
- package/dist/assets/{Skills-CSdxEC-f.js → Skills-BNDlbftC.js} +2 -2
- package/dist/assets/SystemPrompt-d-ykNRec.js +1 -0
- package/dist/assets/TagLibrary-D3JWkQK-.js +1 -0
- package/dist/assets/{TiptapBody-4hzD0jjv.js → TiptapBody-B1Ox6D6E.js} +1 -1
- package/dist/assets/Toggle-CaYw6Lrj.js +1 -0
- package/dist/assets/{index-DJ6xdB0r.js → index-CEeLxNCz.js} +659 -655
- package/dist/assets/{index-D9C8N3pn.css → index-Dbo9R4e0.css} +1 -1
- package/dist/assets/{settingsSchema-DVblsXFp.js → settingsSchema-DUkd45M5.js} +1 -1
- package/dist/index.html +2 -2
- package/package.json +3 -1
- package/plugins/session-manager-dev/skills/memory-sanitation/SKILL.md +21 -1
- package/scripts/scheduler-mcp-server.cjs +471 -0
- package/src/main/__tests__/agentModelResolve.test.cjs +19 -0
- package/src/main/__tests__/crossProjectFeedback.test.cjs +7 -0
- package/src/main/__tests__/crossProjectFeedbackRoutes.test.cjs +7 -0
- package/src/main/__tests__/epicMint.test.cjs +50 -2
- package/src/main/__tests__/health-claude-md-budget.test.cjs +57 -0
- package/src/main/__tests__/prdCreate.test.cjs +17 -0
- package/src/main/__tests__/promptSessionsCreateEpicHandler.test.cjs +7 -0
- package/src/main/__tests__/seedAgentPersonas.test.cjs +105 -0
- package/src/main/__tests__/seedSchedulerMcp.test.cjs +145 -0
- package/src/main/__tests__/seedStatus.test.cjs +100 -0
- package/src/main/__tests__/workTypeLibrary.test.cjs +89 -0
- package/src/main/agentLibrary.cjs +43 -0
- package/src/main/health.cjs +51 -1
- package/src/main/index.cjs +44 -3
- package/src/main/ipcSchemas.cjs +46 -9
- package/src/main/lib/__tests__/agentPersonaSchema.test.cjs +67 -0
- package/src/main/lib/__tests__/delegationReadiness.test.cjs +185 -0
- package/src/main/lib/__tests__/epicDelegationStats.test.cjs +137 -0
- package/src/main/lib/agentModelResolve.cjs +32 -1
- package/src/main/lib/agentPersonaSchema.cjs +82 -0
- package/src/main/lib/delegationReadiness.cjs +141 -0
- package/src/main/lib/epicDelegationStats.cjs +124 -0
- package/src/main/lib/epicMint.cjs +74 -1
- package/src/main/lib/prdFrontmatter.cjs +6 -5
- package/src/main/lib/promptSessionSchema.cjs +7 -15
- package/src/main/lib/workTypeLibrary.cjs +48 -0
- package/src/main/seedAgentPersonas.cjs +92 -0
- package/src/main/seedDevPlugin.cjs +14 -2
- package/src/main/seedSchedulerMcp.cjs +148 -0
- package/src/main/seedStatus.cjs +59 -0
- package/src/preload/api.d.ts +47 -3
- package/src/preload/index.cjs +7 -0
- package/src/seed/agents/architect.md +64 -0
- package/src/seed/agents/dev-lead.md +42 -0
- package/src/seed/prompts/code-review/ac-coverage-check.md +8 -0
- package/src/seed/prompts/code-review/correctness-only.md +8 -0
- package/src/seed/prompts/code-review/full-spectrum-high.md +8 -0
- package/src/seed/prompts/code-review/hallucination-check.md +8 -0
- package/src/seed/prompts/code-review/public-api-compat.md +8 -0
- package/src/seed/prompts/code-review/readability-naming.md +8 -0
- package/src/seed/prompts/debugging/bug-as-failing-test.md +8 -0
- package/src/seed/prompts/debugging/git-bisect-regression.md +8 -0
- package/src/seed/prompts/debugging/instrument-intermittent-bug.md +8 -0
- package/src/seed/prompts/debugging/localize-pipeline-failure.md +8 -0
- package/src/seed/prompts/debugging/reproduce-then-diagnose.md +8 -0
- package/src/seed/prompts/documentation/adr-from-change.md +8 -0
- package/src/seed/prompts/documentation/module-readme.md +8 -0
- package/src/seed/prompts/documentation/onboarding-plan.md +8 -0
- package/src/seed/prompts/documentation/refresh-claude-md.md +8 -0
- package/src/seed/prompts/documentation/tsdoc-public-exports.md +8 -0
- package/src/seed/prompts/git-pr/conventional-commit.md +8 -0
- package/src/seed/prompts/git-pr/draft-pr-title-body.md +8 -0
- package/src/seed/prompts/git-pr/pre-commit-safety-sweep.md +8 -0
- package/src/seed/prompts/git-pr/release-notes-block.md +8 -0
- package/src/seed/prompts/git-pr/split-large-pr.md +8 -0
- package/src/seed/prompts/performance/bundle-startup-audit.md +8 -0
- package/src/seed/prompts/performance/complexity-audit.md +8 -0
- package/src/seed/prompts/performance/cpu-profile-hot-path.md +8 -0
- package/src/seed/prompts/performance/db-query-plan-review.md +8 -0
- package/src/seed/prompts/performance/memory-leak-hunt.md +8 -0
- package/src/seed/prompts/qa/api-contract-tests.md +8 -0
- package/src/seed/prompts/qa/e2e-critical-path.md +8 -0
- package/src/seed/prompts/qa/failing-test-for-bug.md +8 -0
- package/src/seed/prompts/qa/find-missing-test-coverage.md +8 -0
- package/src/seed/prompts/qa/stabilize-flaky-test.md +8 -0
- package/src/seed/prompts/qa/tdd-red-first.md +8 -0
- package/src/seed/prompts/qa/visual-regression-review.md +8 -0
- package/src/seed/prompts/qa/wcag-axe-scan.md +8 -0
- package/src/seed/prompts/refactoring/dead-code-sweep.md +8 -0
- package/src/seed/prompts/refactoring/extract-duplicated-pattern.md +8 -0
- package/src/seed/prompts/refactoring/modernize-legacy-file.md +8 -0
- package/src/seed/prompts/refactoring/reduce-cyclomatic-complexity.md +8 -0
- package/src/seed/prompts/refactoring/tighten-module-boundaries.md +8 -0
- package/src/seed/prompts/security/authz-audit.md +8 -0
- package/src/seed/prompts/security/crypto-correctness.md +8 -0
- package/src/seed/prompts/security/cwe-top-25-hunt.md +8 -0
- package/src/seed/prompts/security/dependency-audit.md +8 -0
- package/src/seed/prompts/security/ipc-boundary-hardening.md +8 -0
- package/src/seed/prompts/security/owasp-top-10-staged-diff.md +8 -0
- package/src/seed/prompts/security/secret-credential-scan.md +8 -0
- package/dist/assets/AgentLibrary-D0frFrHG.js +0 -3
- package/dist/assets/HostBilko-CXykS2ap.js +0 -1
- package/dist/assets/ListDetail-DXd5rB2F.js +0 -1
- package/dist/assets/MarkdownEditor-D0mO1TUZ.js +0 -1
- package/dist/assets/Panel-DigZB9Yd.js +0 -1
- package/dist/assets/Plugins-DOTiP9sQ.js +0 -2
- package/dist/assets/ProvenanceBadge-PsNd-CBq.js +0 -1
- package/dist/assets/SaveBar-C4bgDklX.js +0 -1
- package/dist/assets/ScopeSwitcher-RMAwgmj4.js +0 -1
- package/dist/assets/Settings-CM4lZxnn.js +0 -3
- package/dist/assets/SystemPrompt-j-WYOC5f.js +0 -1
- package/dist/assets/TagLibrary-Fj0zrPru.js +0 -1
- 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 };
|
package/src/preload/api.d.ts
CHANGED
|
@@ -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:
|
|
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:
|
|
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;
|
package/src/preload/index.cjs
CHANGED
|
@@ -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.
|