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 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 4 (auto-format, block-destructive, PostCompact, plus one contextual).
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 4 (auto-format, block-destructive, PostCompact, plus one contextual).
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