kairn-cli 2.9.0 → 2.10.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/cli.js +128 -9
- package/dist/cli.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3590,7 +3590,8 @@ var init_targeting = __esm({
|
|
|
3590
3590
|
"refactor": ["architecture", "conventions"],
|
|
3591
3591
|
"test-writing": ["verification", "commands"],
|
|
3592
3592
|
"config-change": ["settings", "mcp"],
|
|
3593
|
-
"documentation": ["general"]
|
|
3593
|
+
"documentation": ["general"],
|
|
3594
|
+
"persistence-completion": ["commands", "verification"]
|
|
3594
3595
|
};
|
|
3595
3596
|
}
|
|
3596
3597
|
});
|
|
@@ -4909,7 +4910,7 @@ You must output a JSON object matching the SkeletonSpec schema.
|
|
|
4909
4910
|
- MCP servers: maximum 6. Prefer fewer.
|
|
4910
4911
|
- Skills: maximum 3. Only include directly relevant ones.
|
|
4911
4912
|
- Agents: maximum 5. Orchestration pipeline (/develop) agents.
|
|
4912
|
-
- Hooks: maximum
|
|
4913
|
+
- Hooks: maximum 5 (auto-format, block-destructive, PostCompact, memory-persistence, plus one contextual).
|
|
4913
4914
|
|
|
4914
4915
|
If the workflow doesn't clearly need a tool, DO NOT include it.
|
|
4915
4916
|
Each MCP server costs 500-2000 tokens of context window.
|
|
@@ -5189,6 +5190,12 @@ For projects with multi-session workflows, include SessionStart/End hooks that p
|
|
|
5189
5190
|
|
|
5190
5191
|
This ensures accumulated project knowledge survives session boundaries.
|
|
5191
5192
|
|
|
5193
|
+
## Persistence Routing Hook
|
|
5194
|
+
|
|
5195
|
+
For code projects with autonomy level 3+, include a \`UserPromptSubmit\` hook that routes complex tasks through \`/project:persist\`.
|
|
5196
|
+
Generate \`.claude/hooks/persist-router.mjs\` (the routing logic) and add a \`UserPromptSubmit\` hook entry in settings.json that invokes it.
|
|
5197
|
+
Also add \`"persistence_routing": "auto"\` (level 3-4) or \`"persistence_routing": "manual"\` (level 1-2) to settings.json.
|
|
5198
|
+
|
|
5192
5199
|
## For Code Projects, Additionally Include
|
|
5193
5200
|
|
|
5194
5201
|
- \`/project:plan\` command (plan before coding)
|
|
@@ -5226,6 +5233,13 @@ This ensures accumulated project knowledge survives session boundaries.
|
|
|
5226
5233
|
- \`/project:prove\` command (runs tests, shows git diff vs main, rates confidence HIGH/MEDIUM/LOW with evidence)
|
|
5227
5234
|
- \`/project:grill\` command (adversarial code review \u2014 challenges each change with "why this approach?", "what if X input?", rates BLOCKER/SHOULD-FIX/NITPICK, blocks until BLOCKERs resolved)
|
|
5228
5235
|
- \`/project:reset\` command (reads DECISIONS.md and LEARNINGS.md, proposes clean restart, stashes current work, implements elegant solution)
|
|
5236
|
+
- \`/project:persist\` command (persistent execution loop \u2014 reads acceptance criteria from docs/SPRINT.md, works criterion-by-criterion with structured progress tracking in .claude/progress.json, auto-retries on verification failure up to 3 times per criterion, delegates to @grill for review gate before completion, resumes from progress.json if session was interrupted). The command protocol:
|
|
5237
|
+
1. Load or initialize .claude/progress.json from docs/SPRINT.md numbered acceptance criteria
|
|
5238
|
+
2. For each incomplete criterion: implement, run verification (build/test/typecheck/lint), mark PASSED or retry (max 3 attempts per criterion, mark BLOCKED after 3 failures)
|
|
5239
|
+
3. After all criteria attempted: if any BLOCKED report which and why; if all PASSED proceed to review gate
|
|
5240
|
+
4. Review gate: delegate to @grill for adversarial review; fix blockers if found (max 1 fix cycle)
|
|
5241
|
+
5. Persist state: write final progress.json; include progress summary in memory.json for session resume
|
|
5242
|
+
Resume protocol: when progress.json exists, skip PASSED criteria, resume from first non-PASSED criterion, carry forward failure notes from prior attempts.
|
|
5229
5243
|
|
|
5230
5244
|
## For Research Projects, Additionally Include
|
|
5231
5245
|
|
|
@@ -5270,7 +5284,7 @@ Return ONLY valid JSON matching this structure:
|
|
|
5270
5284
|
\`\`\`json
|
|
5271
5285
|
{
|
|
5272
5286
|
"claude_md": "Full CLAUDE.md content (under 150 lines)",
|
|
5273
|
-
"commands": { "help": "...", "develop": "...", "status": "...", "fix": "...", "sprint": "...", "spec": "...", "prove": "...", "grill": "...", "reset": "..." },
|
|
5287
|
+
"commands": { "help": "...", "develop": "...", "status": "...", "fix": "...", "sprint": "...", "spec": "...", "prove": "...", "grill": "...", "reset": "...", "persist": "..." },
|
|
5274
5288
|
"rules": { "continuity": "...", "security": "..." },
|
|
5275
5289
|
"agents": { "architect": "...", "planner": "...", "implementer": "...", "fixer": "...", "doc-updater": "...", "qa-orchestrator": "...", "linter": "...", "e2e-tester": "..." },
|
|
5276
5290
|
"skills": { "skill-name/SKILL": "..." },
|
|
@@ -5429,7 +5443,7 @@ Do not add generic filler. Every line must be specific to the user's workflow.
|
|
|
5429
5443
|
- Skills: maximum 3. Only include directly relevant ones.
|
|
5430
5444
|
- Agents: maximum 5. Orchestration pipeline (/develop) agents.
|
|
5431
5445
|
- Commands: no limit (loaded on demand, zero context cost).
|
|
5432
|
-
- Hooks: maximum
|
|
5446
|
+
- Hooks: maximum 5 (auto-format, block-destructive, PostCompact, memory-persistence, plus one contextual).
|
|
5433
5447
|
|
|
5434
5448
|
If the workflow doesn't clearly need a tool, DO NOT include it.
|
|
5435
5449
|
Each MCP server costs 500-2000 tokens of context window.
|
|
@@ -5458,7 +5472,8 @@ Return ONLY valid JSON matching this structure:
|
|
|
5458
5472
|
},
|
|
5459
5473
|
"commands": {
|
|
5460
5474
|
"help": "markdown content for /project:help",
|
|
5461
|
-
"develop": "markdown content for /project:develop"
|
|
5475
|
+
"develop": "markdown content for /project:develop",
|
|
5476
|
+
"persist": "markdown content for /project:persist"
|
|
5462
5477
|
},
|
|
5463
5478
|
"rules": {
|
|
5464
5479
|
"continuity": "markdown content for continuity rule",
|
|
@@ -6535,6 +6550,9 @@ function applyAutonomyLevel(spec) {
|
|
|
6535
6550
|
const agents = spec.harness.agents ?? {};
|
|
6536
6551
|
const docs = spec.harness.docs ?? {};
|
|
6537
6552
|
const settings = spec.harness.settings ?? {};
|
|
6553
|
+
if (!("persistence_routing" in settings)) {
|
|
6554
|
+
settings.persistence_routing = level >= 3 ? "auto" : "manual";
|
|
6555
|
+
}
|
|
6538
6556
|
if (level >= 1) {
|
|
6539
6557
|
if (!("tour" in commands)) {
|
|
6540
6558
|
commands.tour = TOUR_COMMAND;
|
|
@@ -6606,6 +6624,85 @@ var ENV_LOADER_HOOK = {
|
|
|
6606
6624
|
command: 'if [ -f .env ] && [ -n "$CLAUDE_ENV_FILE" ]; then grep -v "^#" .env | grep -v "^$" | grep "=" >> "$CLAUDE_ENV_FILE"; fi'
|
|
6607
6625
|
}]
|
|
6608
6626
|
};
|
|
6627
|
+
var PERSIST_ROUTER_TEMPLATE = `import { readFileSync } from 'fs';
|
|
6628
|
+
|
|
6629
|
+
const input = JSON.parse(readFileSync('/dev/stdin', 'utf8'));
|
|
6630
|
+
const prompt = (input.prompt ?? '').trim();
|
|
6631
|
+
|
|
6632
|
+
// Pass-through patterns (fast exit)
|
|
6633
|
+
const PASSTHROUGH = /^(what|how|why|where|when|can you|does|is |show me|find |search |list |\\/project:)/i;
|
|
6634
|
+
const SINGLE_FILE = /^(edit|fix the typo|update the comment|change the|rename) .{3,60}$/i;
|
|
6635
|
+
|
|
6636
|
+
if (PASSTHROUGH.test(prompt) || SINGLE_FILE.test(prompt) || prompt.length < 20) {
|
|
6637
|
+
process.stdout.write(JSON.stringify({ continue: true }));
|
|
6638
|
+
process.exit(0);
|
|
6639
|
+
}
|
|
6640
|
+
|
|
6641
|
+
// Check config for routing mode
|
|
6642
|
+
let routingMode = 'auto';
|
|
6643
|
+
try {
|
|
6644
|
+
const settings = JSON.parse(readFileSync('.claude/settings.json', 'utf8'));
|
|
6645
|
+
routingMode = settings.persistence_routing ?? 'auto';
|
|
6646
|
+
} catch { /* default to auto */ }
|
|
6647
|
+
|
|
6648
|
+
if (routingMode === 'off') {
|
|
6649
|
+
process.stdout.write(JSON.stringify({ continue: true }));
|
|
6650
|
+
process.exit(0);
|
|
6651
|
+
}
|
|
6652
|
+
|
|
6653
|
+
// Complexity signals
|
|
6654
|
+
const signals = [];
|
|
6655
|
+
|
|
6656
|
+
if (/\\b(then|after that|and also|next|finally|step \\d|first .* then)\\b/i.test(prompt)) {
|
|
6657
|
+
signals.push('multi-step');
|
|
6658
|
+
}
|
|
6659
|
+
if (/\\b(add|implement|build|create|integrate|set up)\\b.*\\b(feature|auth|api|endpoint|page|component|module|service|database|migration)\\b/i.test(prompt)) {
|
|
6660
|
+
signals.push('feature-scope');
|
|
6661
|
+
}
|
|
6662
|
+
if (/\\b(migrate|convert|replace|upgrade|refactor|rewrite|restructure)\\b/i.test(prompt)) {
|
|
6663
|
+
signals.push('refactor-scope');
|
|
6664
|
+
}
|
|
6665
|
+
if (/\\b(when .* happens|steps to reproduce|broken|crash|regression|fails when)\\b/i.test(prompt)) {
|
|
6666
|
+
signals.push('bug-with-repro');
|
|
6667
|
+
}
|
|
6668
|
+
if (/\\b(persist|keep working|don't stop|until done|until .* pass)\\b/i.test(prompt)) {
|
|
6669
|
+
signals.push('explicit');
|
|
6670
|
+
}
|
|
6671
|
+
if (prompt.split(/\\s+/).length > 50) {
|
|
6672
|
+
signals.push('long-prompt');
|
|
6673
|
+
}
|
|
6674
|
+
|
|
6675
|
+
const shouldRoute = routingMode === 'manual'
|
|
6676
|
+
? signals.includes('explicit')
|
|
6677
|
+
: signals.length >= 2 || signals.includes('explicit');
|
|
6678
|
+
|
|
6679
|
+
if (shouldRoute) {
|
|
6680
|
+
process.stdout.write(JSON.stringify({
|
|
6681
|
+
continue: true,
|
|
6682
|
+
hookSpecificOutput: {
|
|
6683
|
+
hookEventName: 'UserPromptSubmit',
|
|
6684
|
+
additionalContext: [
|
|
6685
|
+
'PERSISTENCE ROUTING: This task has complexity signals (' + signals.join(', ') + ').',
|
|
6686
|
+
'Execute this using the /project:persist workflow:',
|
|
6687
|
+
'1. Ensure acceptance criteria exist in docs/SPRINT.md (create from this prompt if needed)',
|
|
6688
|
+
'2. Initialize .claude/progress.json',
|
|
6689
|
+
'3. Work criterion-by-criterion until all pass',
|
|
6690
|
+
'4. Run review gate before marking complete',
|
|
6691
|
+
].join('\\n'),
|
|
6692
|
+
},
|
|
6693
|
+
}));
|
|
6694
|
+
} else {
|
|
6695
|
+
process.stdout.write(JSON.stringify({ continue: true }));
|
|
6696
|
+
}
|
|
6697
|
+
`;
|
|
6698
|
+
var PERSIST_ROUTER_HOOK = {
|
|
6699
|
+
matcher: "",
|
|
6700
|
+
hooks: [{
|
|
6701
|
+
type: "command",
|
|
6702
|
+
command: 'node "$CLAUDE_PROJECT_DIR/.claude/hooks/persist-router.mjs"',
|
|
6703
|
+
timeout: 5
|
|
6704
|
+
}]
|
|
6705
|
+
};
|
|
6609
6706
|
function resolveSettings(spec, options) {
|
|
6610
6707
|
const settings = spec.harness.settings;
|
|
6611
6708
|
const base = settings && Object.keys(settings).length > 0 ? { ...settings } : {};
|
|
@@ -6619,6 +6716,13 @@ function resolveSettings(spec, options) {
|
|
|
6619
6716
|
hooks.SessionStart = sessionStart;
|
|
6620
6717
|
base.hooks = hooks;
|
|
6621
6718
|
}
|
|
6719
|
+
if (isCodeProject(spec) && (spec.autonomy_level ?? 1) >= 3) {
|
|
6720
|
+
const hooks = base.hooks ?? {};
|
|
6721
|
+
const userPromptSubmit = hooks.UserPromptSubmit ?? [];
|
|
6722
|
+
userPromptSubmit.push(PERSIST_ROUTER_HOOK);
|
|
6723
|
+
hooks.UserPromptSubmit = userPromptSubmit;
|
|
6724
|
+
base.hooks = hooks;
|
|
6725
|
+
}
|
|
6622
6726
|
const hasIntentHooks = spec.harness.hooks && Object.keys(spec.harness.hooks).length > 0;
|
|
6623
6727
|
if (hasIntentHooks) {
|
|
6624
6728
|
const hooks = base.hooks ?? {};
|
|
@@ -6710,6 +6814,9 @@ function buildFileMap(spec, options) {
|
|
|
6710
6814
|
files.set(".claude/hooks/intent-log.jsonl", "");
|
|
6711
6815
|
}
|
|
6712
6816
|
}
|
|
6817
|
+
if (isCodeProject(spec) && (spec.autonomy_level ?? 1) >= 3) {
|
|
6818
|
+
files.set(".claude/hooks/persist-router.mjs", PERSIST_ROUTER_TEMPLATE);
|
|
6819
|
+
}
|
|
6713
6820
|
return files;
|
|
6714
6821
|
}
|
|
6715
6822
|
async function writeEnvironment(spec, targetDir, options) {
|
|
@@ -6780,6 +6887,11 @@ async function writeEnvironment(spec, targetDir, options) {
|
|
|
6780
6887
|
written.push(".claude/hooks/intent-log.jsonl");
|
|
6781
6888
|
}
|
|
6782
6889
|
}
|
|
6890
|
+
if (isCodeProject(spec) && (spec.autonomy_level ?? 1) >= 3) {
|
|
6891
|
+
const p = path5.join(claudeDir, "hooks", "persist-router.mjs");
|
|
6892
|
+
await writeFile(p, PERSIST_ROUTER_TEMPLATE);
|
|
6893
|
+
written.push(".claude/hooks/persist-router.mjs");
|
|
6894
|
+
}
|
|
6783
6895
|
return written;
|
|
6784
6896
|
}
|
|
6785
6897
|
function summarizeSpec(spec, registry) {
|
|
@@ -8478,14 +8590,20 @@ var EVAL_TEMPLATES = {
|
|
|
8478
8590
|
name: "Intent Routing",
|
|
8479
8591
|
description: "Test that natural language prompts route to the correct workflow command via intent hooks",
|
|
8480
8592
|
bestFor: ["feature-development", "full-stack", "api-building"]
|
|
8593
|
+
},
|
|
8594
|
+
"persistence-completion": {
|
|
8595
|
+
id: "persistence-completion",
|
|
8596
|
+
name: "Persistence Completion",
|
|
8597
|
+
description: "Can the agent complete a multi-criterion task using the persistence loop?",
|
|
8598
|
+
bestFor: ["feature-development", "full-stack", "api-building", "maintenance"]
|
|
8481
8599
|
}
|
|
8482
8600
|
};
|
|
8483
8601
|
function selectTemplatesForWorkflow(workflowType) {
|
|
8484
8602
|
const mapping = {
|
|
8485
|
-
"feature-development": ["add-feature", "test-writing", "convention-adherence", "workflow-compliance", "intent-routing"],
|
|
8486
|
-
"api-building": ["add-feature", "fix-bug", "test-writing", "convention-adherence"],
|
|
8487
|
-
"full-stack": ["add-feature", "fix-bug", "test-writing", "convention-adherence"],
|
|
8488
|
-
"maintenance": ["fix-bug", "refactor", "test-writing", "rule-compliance"],
|
|
8603
|
+
"feature-development": ["add-feature", "test-writing", "convention-adherence", "workflow-compliance", "intent-routing", "persistence-completion"],
|
|
8604
|
+
"api-building": ["add-feature", "fix-bug", "test-writing", "convention-adherence", "persistence-completion"],
|
|
8605
|
+
"full-stack": ["add-feature", "fix-bug", "test-writing", "convention-adherence", "persistence-completion"],
|
|
8606
|
+
"maintenance": ["fix-bug", "refactor", "test-writing", "rule-compliance", "persistence-completion"],
|
|
8489
8607
|
"debugging": ["fix-bug", "test-writing", "rule-compliance"],
|
|
8490
8608
|
"qa": ["fix-bug", "test-writing", "add-feature", "workflow-compliance"],
|
|
8491
8609
|
"architecture": ["refactor", "test-writing", "config-change", "convention-adherence"],
|
|
@@ -8506,6 +8624,7 @@ IMPORTANT: For harness-aware templates (convention-adherence, workflow-complianc
|
|
|
8506
8624
|
- convention-adherence: Task must require following specific conventions from CLAUDE.md (naming, file structure, patterns). Judge by whether output matches the conventions.
|
|
8507
8625
|
- workflow-compliance: Task must require using project slash commands or workflow steps defined in .claude/commands/. Judge by whether the agent followed the defined workflow.
|
|
8508
8626
|
- rule-compliance: Task must create a scenario where .claude/rules/ content is relevant. Judge by whether the agent respected all rules.
|
|
8627
|
+
- persistence-completion: Task MUST have 3+ acceptance criteria that require sequential implementation. The task description should be a realistic feature request \u2014 the agent must parse it into criteria. Judge by: (a) all criteria met (progress.json status: complete), (b) structured tracking used (progress.json exists with 3+ criteria), (c) tests pass, (d) review gate executed (progress.json review field present).
|
|
8509
8628
|
|
|
8510
8629
|
These harness-aware tasks are critical \u2014 they test whether the .claude/ environment actually improves agent behavior.
|
|
8511
8630
|
|