@soleri/forge 9.14.4 → 9.16.7

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 (119) hide show
  1. package/dist/agent-schema.d.ts +2 -2
  2. package/dist/compose-claude-md.js +5 -2
  3. package/dist/compose-claude-md.js.map +1 -1
  4. package/dist/index.js +0 -0
  5. package/dist/lib.d.ts +1 -0
  6. package/dist/lib.js +1 -0
  7. package/dist/lib.js.map +1 -1
  8. package/dist/scaffold-filetree.js +27 -0
  9. package/dist/scaffold-filetree.js.map +1 -1
  10. package/dist/scaffolder.js +10 -0
  11. package/dist/scaffolder.js.map +1 -1
  12. package/dist/skills/soleri-agent-dev/SKILL.md +1 -0
  13. package/dist/skills/soleri-agent-guide/SKILL.md +1 -0
  14. package/dist/skills/soleri-agent-issues/SKILL.md +1 -0
  15. package/dist/skills/soleri-agent-mode/SKILL.md +173 -0
  16. package/dist/skills/soleri-agent-persona/SKILL.md +1 -0
  17. package/dist/skills/soleri-brain-debrief/SKILL.md +1 -0
  18. package/dist/skills/soleri-brainstorming/SKILL.md +1 -0
  19. package/dist/skills/soleri-build-skill/SKILL.md +2 -0
  20. package/dist/skills/soleri-code-patrol/SKILL.md +1 -0
  21. package/dist/skills/soleri-context-resume/SKILL.md +1 -0
  22. package/dist/skills/soleri-curator/SKILL.md +66 -0
  23. package/dist/skills/soleri-deep-review/SKILL.md +1 -0
  24. package/dist/skills/soleri-deliver-and-ship/SKILL.md +1 -0
  25. package/dist/skills/soleri-discovery-phase/SKILL.md +1 -0
  26. package/dist/skills/soleri-dream/SKILL.md +31 -1
  27. package/dist/skills/soleri-env-setup/SKILL.md +1 -0
  28. package/dist/skills/soleri-executing-plans/SKILL.md +1 -0
  29. package/dist/skills/soleri-finishing-a-development-branch/SKILL.md +1 -0
  30. package/dist/skills/soleri-fix-and-learn/SKILL.md +1 -0
  31. package/dist/skills/soleri-health-check/SKILL.md +1 -0
  32. package/dist/skills/soleri-intake/SKILL.md +100 -0
  33. package/dist/skills/soleri-knowledge-harvest/SKILL.md +1 -0
  34. package/dist/skills/soleri-loop/SKILL.md +69 -0
  35. package/dist/skills/soleri-mcp-doctor/SKILL.md +1 -0
  36. package/dist/skills/soleri-onboard-me/SKILL.md +1 -0
  37. package/dist/skills/soleri-orchestrate/SKILL.md +70 -0
  38. package/dist/skills/soleri-parallel-execute/SKILL.md +1 -0
  39. package/dist/skills/soleri-research-scout/SKILL.md +1 -0
  40. package/dist/skills/soleri-retrospective/SKILL.md +1 -0
  41. package/dist/skills/soleri-second-opinion/SKILL.md +1 -0
  42. package/dist/skills/soleri-subagent-driven-development/SKILL.md +1 -0
  43. package/dist/skills/soleri-systematic-debugging/SKILL.md +1 -0
  44. package/dist/skills/soleri-test-driven-development/SKILL.md +1 -0
  45. package/dist/skills/soleri-using-git-worktrees/SKILL.md +1 -0
  46. package/dist/skills/soleri-vault-capture/SKILL.md +6 -5
  47. package/dist/skills/soleri-vault-curate/SKILL.md +1 -0
  48. package/dist/skills/soleri-vault-navigator/SKILL.md +1 -0
  49. package/dist/skills/soleri-vault-smells/SKILL.md +1 -0
  50. package/dist/skills/soleri-verification-before-completion/SKILL.md +1 -0
  51. package/dist/skills/soleri-writing-plans/SKILL.md +6 -3
  52. package/dist/skills/soleri-yolo-mode/SKILL.md +1 -0
  53. package/dist/templates/claude-md-template.js +2 -29
  54. package/dist/templates/claude-md-template.js.map +1 -1
  55. package/dist/templates/package-json.js +2 -0
  56. package/dist/templates/package-json.js.map +1 -1
  57. package/dist/templates/setup-script.js +6 -63
  58. package/dist/templates/setup-script.js.map +1 -1
  59. package/dist/templates/shared-rules.js +11 -4
  60. package/dist/templates/shared-rules.js.map +1 -1
  61. package/dist/templates/skills.d.ts +13 -0
  62. package/dist/templates/skills.js +55 -3
  63. package/dist/templates/skills.js.map +1 -1
  64. package/dist/types.d.ts +2 -2
  65. package/package.json +1 -1
  66. package/src/__tests__/knowledge-installer.test.ts +1 -1
  67. package/src/__tests__/scaffold-filetree.test.ts +1 -1
  68. package/src/__tests__/scaffolder.test.ts +143 -111
  69. package/src/compose-claude-md.ts +5 -1
  70. package/src/lib.ts +1 -0
  71. package/src/scaffold-filetree.ts +33 -0
  72. package/src/scaffolder.ts +10 -0
  73. package/src/skills/soleri-agent-dev/SKILL.md +1 -0
  74. package/src/skills/soleri-agent-guide/SKILL.md +1 -0
  75. package/src/skills/soleri-agent-issues/SKILL.md +1 -0
  76. package/src/skills/soleri-agent-mode/SKILL.md +173 -0
  77. package/src/skills/soleri-agent-persona/SKILL.md +1 -0
  78. package/src/skills/soleri-brain-debrief/SKILL.md +1 -0
  79. package/src/skills/soleri-brainstorming/SKILL.md +1 -0
  80. package/src/skills/soleri-build-skill/SKILL.md +2 -0
  81. package/src/skills/soleri-code-patrol/SKILL.md +1 -0
  82. package/src/skills/soleri-context-resume/SKILL.md +1 -0
  83. package/src/skills/soleri-curator/SKILL.md +66 -0
  84. package/src/skills/soleri-deep-review/SKILL.md +1 -0
  85. package/src/skills/soleri-deliver-and-ship/SKILL.md +1 -0
  86. package/src/skills/soleri-discovery-phase/SKILL.md +1 -0
  87. package/src/skills/soleri-dream/SKILL.md +31 -1
  88. package/src/skills/soleri-env-setup/SKILL.md +1 -0
  89. package/src/skills/soleri-executing-plans/SKILL.md +1 -0
  90. package/src/skills/soleri-finishing-a-development-branch/SKILL.md +1 -0
  91. package/src/skills/soleri-fix-and-learn/SKILL.md +1 -0
  92. package/src/skills/soleri-health-check/SKILL.md +1 -0
  93. package/src/skills/soleri-intake/SKILL.md +100 -0
  94. package/src/skills/soleri-knowledge-harvest/SKILL.md +1 -0
  95. package/src/skills/soleri-loop/SKILL.md +69 -0
  96. package/src/skills/soleri-mcp-doctor/SKILL.md +1 -0
  97. package/src/skills/soleri-onboard-me/SKILL.md +1 -0
  98. package/src/skills/soleri-orchestrate/SKILL.md +70 -0
  99. package/src/skills/soleri-parallel-execute/SKILL.md +1 -0
  100. package/src/skills/soleri-research-scout/SKILL.md +1 -0
  101. package/src/skills/soleri-retrospective/SKILL.md +1 -0
  102. package/src/skills/soleri-second-opinion/SKILL.md +1 -0
  103. package/src/skills/soleri-subagent-driven-development/SKILL.md +1 -0
  104. package/src/skills/soleri-systematic-debugging/SKILL.md +1 -0
  105. package/src/skills/soleri-test-driven-development/SKILL.md +1 -0
  106. package/src/skills/soleri-using-git-worktrees/SKILL.md +1 -0
  107. package/src/skills/soleri-vault-capture/SKILL.md +6 -5
  108. package/src/skills/soleri-vault-curate/SKILL.md +1 -0
  109. package/src/skills/soleri-vault-navigator/SKILL.md +1 -0
  110. package/src/skills/soleri-vault-smells/SKILL.md +1 -0
  111. package/src/skills/soleri-verification-before-completion/SKILL.md +1 -0
  112. package/src/skills/soleri-writing-plans/SKILL.md +6 -3
  113. package/src/skills/soleri-yolo-mode/SKILL.md +1 -0
  114. package/src/templates/claude-md-template.ts +2 -50
  115. package/src/templates/package-json.ts +2 -0
  116. package/src/templates/setup-script.ts +6 -63
  117. package/src/templates/shared-rules.ts +11 -4
  118. package/src/templates/skills.ts +63 -3
  119. package/vitest.config.ts +2 -1
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: soleri-orchestrate
3
+ tier: default
4
+ description: >
5
+ Use when the user gives a work task: "implement X", "build Y", "fix Z",
6
+ "add feature", or any request that requires planning and execution.
7
+ Runs the full orchestration loop: plan → execute → complete with vault
8
+ context and brain recommendations built in.
9
+ ---
10
+
11
+ # Orchestrate — Full Work Loop
12
+
13
+ Run the full work loop with vault intelligence: plan the task, execute it step by step, and close with knowledge capture. Use this for any non-trivial task where missing context or skipping steps would cost time.
14
+
15
+ ## When to Use
16
+
17
+ - User gives a concrete work task ("implement auth", "refactor the parser", "fix the flaky test")
18
+ - Task spans multiple files or has cross-cutting concerns
19
+ - You want vault patterns and brain recommendations surfaced automatically
20
+
21
+ ## Orchestration
22
+
23
+ ### Step 1: Plan
24
+
25
+ ```
26
+ YOUR_AGENT_orchestrate op:orchestrate_plan
27
+ params: {
28
+ prompt: "<user task description>",
29
+ context: { domain: "<inferred domain>" }
30
+ }
31
+ ```
32
+
33
+ Present the plan to the user. If grade < A-, ask for approval before proceeding.
34
+
35
+ ### Step 2: Execute
36
+
37
+ Once approved, begin execution. For each task in the plan:
38
+
39
+ ```
40
+ YOUR_AGENT_orchestrate op:orchestrate_execute
41
+ params: {
42
+ planId: "<planId from step 1>",
43
+ taskId: "<current task id>",
44
+ output: "<what you did>"
45
+ }
46
+ ```
47
+
48
+ Log progress after each task: show completed count / total and current task title.
49
+
50
+ ### Step 3: Complete
51
+
52
+ After all tasks are done:
53
+
54
+ ```
55
+ YOUR_AGENT_orchestrate op:orchestrate_complete
56
+ params: {
57
+ planId: "<planId>",
58
+ summary: "<one-line outcome>",
59
+ operatorSignals: {
60
+ qualityNotes: "<any quality observations>",
61
+ unexpectedComplexity: <true|false>
62
+ }
63
+ }
64
+ ```
65
+
66
+ Report the completion summary and any knowledge captured.
67
+
68
+ ## Exit Criteria
69
+
70
+ All plan tasks executed, `orchestrate_complete` called with outcome, knowledge persisted to vault.
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: soleri-parallel-execute
3
+ tier: default
3
4
  description: >
4
5
  Use when the user says "run in parallel", "fan out", "concurrent execution",
5
6
  "batch execute", or "dispatch subagents". Executes independent plan tasks
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: soleri-research-scout
3
+ tier: default
3
4
  description: >
4
5
  Use when the user says "scout", "research scout", "find new info",
5
6
  "what's new", or "scan the web". Discovers new information that challenges
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: soleri-retrospective
3
+ tier: default
3
4
  description: >
4
5
  Use when the user says "sprint retro", "weekly summary", "what went well",
5
6
  "end of sprint", or "monthly report". Time-bound reflection on recent work
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: soleri-second-opinion
3
+ tier: default
3
4
  description: >
4
5
  Use when the user says "second opinion", "technical decision",
5
6
  "comparing approaches", or "which approach". Provides informed recommendations
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: soleri-subagent-driven-development
3
+ tier: default
3
4
  description: >
4
5
  Use when the user says "use subagents", "parallel agents",
5
6
  "subagent driven", or "isolated execution". Decomposes work into isolated
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: soleri-systematic-debugging
3
+ tier: default
3
4
  description: >
4
5
  Use as the FIRST response when something is broken — "bug", "failing test",
5
6
  "not working", "debug this", "error", "crash", or "weird issue". Diagnoses
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: soleri-test-driven-development
3
+ tier: default
3
4
  description: >
4
5
  Use when the user says "TDD", "write tests first", "red green refactor",
5
6
  or "test driven". Write failing tests before implementation code for any
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: soleri-using-git-worktrees
3
+ tier: default
3
4
  description: >
4
5
  Use when the user says "worktree", "parallel branch", "safe branch",
5
6
  or "isolated branch". Provides the protocol for creating, working in,
@@ -1,11 +1,12 @@
1
1
  ---
2
2
  name: soleri-vault-capture
3
+ tier: default
3
4
  description: >
4
- Use when the user says "save this", "capture this", "remember this pattern",
5
- "add to vault", "vault capture", or when persisting learnings from a work
6
- session. Validated capture with tier scoping, duplicate detection, and
7
- abstraction review. For bulk extraction from documents, code, or PRs, use
8
- knowledge-harvest instead.
5
+ Use when the user says "save this to vault", "capture this", "remember this pattern",
6
+ "add to vault", "vault capture", or when persisting learnings from a work session.
7
+ Priority over memory_capture for durable knowledge (patterns, decisions, anti-patterns).
8
+ For quick session notes say "save this as a memory" to use memory_capture instead.
9
+ For bulk extraction from documents, code, or PRs, use knowledge-harvest.
9
10
  ---
10
11
 
11
12
  # Vault Capture — Validated Knowledge Persistence
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: soleri-vault-curate
3
+ tier: default
3
4
  description: >
4
5
  Use when the user says "clean vault", "deduplicate vault", "groom knowledge",
5
6
  "merge patterns", or "vault maintenance". Maintains vault quality through
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: soleri-vault-navigator
3
+ tier: default
3
4
  description: >
4
5
  Use when the user says "search the vault", "find patterns for",
5
6
  "have we seen this before", "vault search", or "best practice for".
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: soleri-vault-smells
3
+ tier: default
3
4
  description: >
4
5
  Use when the user says "vault quality", "vault analysis", "knowledge quality",
5
6
  "knowledge debt", "stale patterns", or "find contradictions". Deep knowledge
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: soleri-verification-before-completion
3
+ tier: default
3
4
  description: >
4
5
  Use when the user says "verify this works", "check output", "quality gate",
5
6
  or "run tests before done". Internal quality gate before claiming any task
@@ -1,9 +1,12 @@
1
1
  ---
2
2
  name: soleri-writing-plans
3
+ tier: default
3
4
  description: >
4
- Use when the user says "create a plan", "break this down", or
5
- "plan the implementation". Creates structured implementation plans when
6
- requirements are already known. For exploration, use brainstorming.
5
+ Use when the user says "create a plan", "write up a plan", "break this down",
6
+ or "plan the implementation". Produces a human-readable markdown plan file.
7
+ Takes priority over orchestrate_plan MCP op for explicit plan-writing requests.
8
+ For exploration or ideation, use brainstorming. For automated task orchestration,
9
+ the engine uses orchestrate_plan directly without this skill.
7
10
  ---
8
11
 
9
12
  # Writing Plans
@@ -1,5 +1,6 @@
1
1
  ---
2
2
  name: soleri-yolo-mode
3
+ tier: default
3
4
  description: >
4
5
  Use when the user says "yolo", "autonomous", "skip approvals",
5
6
  "full auto", or "hands off". Activates autonomous execution mode
@@ -70,60 +70,12 @@ export function generateClaudeMdTemplate(config: AgentConfig): string {
70
70
  '',
71
71
  ];
72
72
 
73
- // ─── Compact Facade Table ───────────────────────────────
73
+ // ─── Skill pointer (replaces inline facade table) ───────
74
74
  mdLines.push(
75
- '## Essential Tools',
76
- `<!-- ${toolPrefix}:tools -->`,
75
+ `> Command reference: use the ${bt}${toolPrefix}-agent-mode${bt} skill or run ${bt}${toolPrefix}_admin op:admin_tool_list${bt}`,
77
76
  '',
78
- '| Facade | Key Ops |',
79
- '|--------|---------|',
80
- `| ${bt}${toolPrefix}_core${bt} | ${bt}health${bt}, ${bt}search${bt}, ${bt}identity${bt}, ${bt}session_start${bt}, ${bt}activate${bt} |`,
81
77
  );
82
78
 
83
- // Domain facades — one row per domain
84
- for (const d of config.domains) {
85
- const toolName = `${toolPrefix}_${d.replace(/-/g, '_')}`;
86
- mdLines.push(
87
- `| ${bt}${toolName}${bt} | ${bt}get_patterns${bt}, ${bt}search${bt}, ${bt}capture${bt} |`,
88
- );
89
- }
90
-
91
- // Domain pack facades (if any)
92
- if (config.domainPacks?.length) {
93
- mdLines.push('', '**Domain Pack Facades:**', '');
94
- for (const ref of config.domainPacks) {
95
- mdLines.push(
96
- `| ${bt}${ref.name}${bt} (pack: ${bt}${ref.package}${bt}) | *custom ops — see ${bt}admin_tool_list${bt}* |`,
97
- );
98
- }
99
- }
100
-
101
- // Engine facades — use actual tool names (standalone facades, NOT _core sub-groups)
102
- mdLines.push(
103
- // Vault — knowledge lifecycle, capture, search, management
104
- `| ${bt}${toolPrefix}_vault${bt} | ${bt}search_intelligent${bt}, ${bt}capture_knowledge${bt}, ${bt}capture_quick${bt}, ${bt}search_feedback${bt} |`,
105
- `| ${bt}${toolPrefix}_vault${bt} (keeper) | ${bt}knowledge_audit${bt}, ${bt}knowledge_health${bt}, ${bt}knowledge_merge${bt}, ${bt}knowledge_reorganize${bt} |`,
106
- `| ${bt}${toolPrefix}_vault${bt} (mgmt) | ${bt}vault_get${bt}, ${bt}vault_update${bt}, ${bt}vault_remove${bt}, ${bt}vault_tags${bt}, ${bt}vault_domains${bt}, ${bt}vault_recent${bt} |`,
107
- // Curator — quality, dedup, contradictions, grooming
108
- `| ${bt}${toolPrefix}_curator${bt} | ${bt}curator_status${bt}, ${bt}curator_detect_duplicates${bt}, ${bt}curator_contradictions${bt}, ${bt}curator_groom_all${bt}, ${bt}curator_consolidate${bt}, ${bt}curator_health_audit${bt} |`,
109
- `| ${bt}${toolPrefix}_curator${bt} (advanced) | ${bt}curator_enrich${bt}, ${bt}curator_hybrid_contradictions${bt}, ${bt}curator_entry_history${bt}, ${bt}curator_queue_stats${bt} |`,
110
- // Planning, orchestration, brain
111
- `| ${bt}${toolPrefix}_plan${bt} | ${bt}create_plan${bt}, ${bt}approve_plan${bt}, ${bt}plan_split${bt}, ${bt}plan_reconcile${bt}, ${bt}plan_complete_lifecycle${bt} |`,
112
- `| ${bt}${toolPrefix}_orchestrate${bt} | ${bt}orchestrate_plan${bt}, ${bt}orchestrate_execute${bt}, ${bt}orchestrate_complete${bt} |`,
113
- `| ${bt}${toolPrefix}_brain${bt} | ${bt}brain_stats${bt}, ${bt}brain_feedback${bt}, ${bt}rebuild_vocabulary${bt}, ${bt}brain_strengths${bt}, ${bt}brain_recommend${bt} |`,
114
- // Memory, control, loop
115
- `| ${bt}${toolPrefix}_memory${bt} | ${bt}memory_search${bt}, ${bt}memory_capture${bt}, ${bt}session_capture${bt} |`,
116
- `| ${bt}${toolPrefix}_control${bt} | ${bt}route_intent${bt}, ${bt}morph${bt}, ${bt}get_behavior_rules${bt}, ${bt}governance_dashboard${bt}, ${bt}governance_policy${bt} |`,
117
- `| ${bt}${toolPrefix}_loop${bt} | ${bt}loop_start${bt}, ${bt}loop_iterate${bt}, ${bt}loop_status${bt}, ${bt}loop_cancel${bt} |`,
118
- // Intelligence — context, agency
119
- `| ${bt}${toolPrefix}_context${bt} | ${bt}context_extract_entities${bt}, ${bt}context_retrieve_knowledge${bt}, ${bt}context_analyze${bt} |`,
120
- `| ${bt}${toolPrefix}_agency${bt} | ${bt}agency_enable${bt}, ${bt}agency_status${bt}, ${bt}agency_surface_patterns${bt}, ${bt}agency_warnings${bt}, ${bt}agency_clarify${bt} |`,
121
- // Admin
122
- `| ${bt}${toolPrefix}_admin${bt} | ${bt}admin_health${bt}, ${bt}admin_tool_list${bt}, ${bt}admin_diagnostic${bt} |`,
123
- );
124
-
125
- mdLines.push('', `> Full list: ${bt}${toolPrefix}_admin op:admin_tool_list${bt}`, '');
126
-
127
79
  // ─── Hook Packs (conditional) ──────────────────────────
128
80
  appendHookPacks(mdLines, config);
129
81
 
@@ -9,6 +9,7 @@ export function generatePackageJson(config: AgentConfig): string {
9
9
  main: 'dist/index.js',
10
10
  bin: { [`${config.id}-mcp`]: 'dist/index.js' },
11
11
  scripts: {
12
+ postinstall: 'soleri hooks sync || true',
12
13
  dev: 'tsx src/index.ts',
13
14
  build: 'tsc && node scripts/copy-assets.js',
14
15
  start: 'node dist/index.js',
@@ -39,6 +40,7 @@ export function generatePackageJson(config: AgentConfig): string {
39
40
  '@anthropic-ai/sdk': '^0.39.0',
40
41
  },
41
42
  devDependencies: {
43
+ '@soleri/cli': '^9.0.0',
42
44
  '@types/node': '^22.13.4',
43
45
  '@vitest/coverage-v8': '^3.0.5',
44
46
  tsx: '^4.19.2',
@@ -35,72 +35,15 @@ echo "Registering ${config.name} with Claude Code..."
35
35
  claude mcp add --scope user "$AGENT_NAME" -- node "$AGENT_DIR/dist/index.js"
36
36
  echo "[ok] Registered ${config.name} as MCP server (Claude Code)"
37
37
 
38
- # Configure PreCompact hook for session capture
39
- SETTINGS_FILE="$HOME/.claude/settings.json"
38
+ # Sync lifecycle hooks into ~/.claude/settings.json
40
39
  echo ""
41
- echo "Configuring Claude session capture hook..."
42
-
43
- if [ ! -d "$HOME/.claude" ]; then
44
- mkdir -p "$HOME/.claude"
45
- fi
46
-
47
- if [ ! -f "$SETTINGS_FILE" ]; then
48
- cat > "$SETTINGS_FILE" << SETTINGS
49
- {
50
- "hooks": {
51
- "PreCompact": [
52
- {
53
- "type": "prompt",
54
- "prompt": "Before context is compacted, capture a session summary by calling ${config.id}_core op:session_capture with a brief summary of what was accomplished, the topics covered, files modified, and tools used."
55
- }
56
- ],
57
- "SessionStart": [
58
- {
59
- "type": "command",
60
- "command": "sh $AGENT_DIR/scripts/clean-worktrees.sh",
61
- "timeout": 10
62
- }
63
- ]
64
- }
65
- }
66
- SETTINGS
67
- echo "[ok] Created $SETTINGS_FILE with PreCompact + SessionStart hooks"
40
+ echo "Syncing lifecycle hooks..."
41
+ if command -v soleri &>/dev/null; then
42
+ soleri hooks sync
68
43
  else
69
- if grep -q "PreCompact" "$SETTINGS_FILE" 2>/dev/null; then
70
- echo "[ok] PreCompact hook already configured — skipping"
71
- else
72
- node -e "
73
- const fs = require('fs');
74
- const settings = JSON.parse(fs.readFileSync('$SETTINGS_FILE', 'utf-8'));
75
- if (!settings.hooks) settings.hooks = {};
76
- if (!settings.hooks.PreCompact) settings.hooks.PreCompact = [];
77
- settings.hooks.PreCompact.push({
78
- type: 'prompt',
79
- prompt: 'Before context is compacted, capture a session summary by calling ${config.id}_core op:session_capture with a brief summary of what was accomplished, the topics covered, files modified, and tools used.'
80
- });
81
- fs.writeFileSync('$SETTINGS_FILE', JSON.stringify(settings, null, 2) + '\\n');
82
- "
83
- echo "[ok] Added PreCompact hook to $SETTINGS_FILE"
84
- fi
85
- # Add SessionStart worktree cleanup hook
86
- if grep -q "clean-worktrees" "$SETTINGS_FILE" 2>/dev/null; then
87
- echo "[ok] SessionStart worktree cleanup hook already configured"
88
- else
89
- node -e "
90
- const fs = require('fs');
91
- const settings = JSON.parse(fs.readFileSync('$SETTINGS_FILE', 'utf-8'));
92
- if (!settings.hooks) settings.hooks = {};
93
- if (!settings.hooks.SessionStart) settings.hooks.SessionStart = [];
94
- settings.hooks.SessionStart.push({
95
- type: 'command',
96
- command: 'sh $AGENT_DIR/scripts/clean-worktrees.sh',
97
- timeout: 10
98
- });
99
- fs.writeFileSync('$SETTINGS_FILE', JSON.stringify(settings, null, 2) + '\\n');
100
- "
101
- echo "[ok] Added SessionStart worktree cleanup hook"
102
- fi
44
+ npx --yes soleri hooks sync
103
45
  fi
46
+ echo "[ok] Lifecycle hooks synced"
104
47
 
105
48
  # Install skills to ~/.claude/skills/
106
49
  SKILLS_DIR="$AGENT_DIR/skills"
@@ -186,12 +186,20 @@ const ENGINE_RULES_LINES: string[] = [
186
186
  '',
187
187
  'The vault is a **Zettelkasten** — a connected knowledge graph. Every knowledge operation follows Zettelkasten principles: atomic entries, typed links, dense connections.',
188
188
  '',
189
- '- **SHOULD**: Consult the vault BEFORE every decisionsearch + traverse the link graph.',
190
- '- Lookup order: 1) VAULT search → 2) VAULT traverse (follow links 2 hops) → 3) MEMORY → 4) CODEBASE → 5) WEB/TRAINING.',
189
+ '**SHOULD follow this lookup order for every question, problem, or task regardless of whether agent MCP is active:**',
190
+ '',
191
+ '1. **Vault** — `op:search_intelligent` + traverse links 2 hops (when agent MCP is active)',
192
+ '2. **Web** — `WebSearch` tool (always — never skip if vault returns no answer)',
193
+ '3. **Memory** — `op:memory_search` (when agent MCP is active)',
194
+ '4. **Codebase** — read relevant files',
195
+ '5. **Training data** — last resort; flag as potentially outdated',
196
+ '',
197
+ '- Web search is **not optional**. If vault is unavailable or returns no relevant results, search the web before answering from training data alone.',
198
+ '- If the vault has a pattern, follow it. If it has an anti-pattern, avoid it.',
191
199
  "- **Search + Traverse**: Don't just search — traverse from the best result to discover connected knowledge and anti-patterns.",
192
200
  '- Check `contradicts` links to know what to avoid. Check `sequences` links for ordering dependencies.',
193
201
  '- Persist lessons: capture + link. An unlinked entry is incomplete.',
194
- '- Exceptions: runtime errors with stack traces → codebase first; user explicitly asks to search web.',
202
+ '- Exception: runtime errors with stack traces → codebase first.',
195
203
  '',
196
204
  '### Vault Search Strategy',
197
205
  '',
@@ -651,7 +659,6 @@ const ENGINE_RULES_LINES: string[] = [
651
659
  '',
652
660
  '### Character Persistence',
653
661
  '',
654
- '- **SHOULD**: Prefix every response with `{AgentName} >` when activated (e.g., `Ernesto >`, `Salvador >`). This signals to the user that the agent persona is active.',
655
662
  "- All communication flows through your persona's voice — tone, vocabulary, opinions",
656
663
  '- Stay in character until explicitly deactivated',
657
664
  '- Context compaction does not change who you are — these rules persist in CLAUDE.md',
@@ -6,8 +6,8 @@ import type { AgentConfig } from '../types.js';
6
6
  const __dirname = dirname(fileURLToPath(import.meta.url));
7
7
  const SKILLS_DIR = join(__dirname, '..', 'skills');
8
8
 
9
- /** Placeholder token in skill templates that gets replaced with agent-specific tool name. */
10
- const AGENT_PLACEHOLDER = 'YOUR_AGENT_core';
9
+ /** Placeholder token in skill templates that gets replaced with agent-specific tool prefix. */
10
+ const AGENT_PLACEHOLDER = 'YOUR_AGENT_';
11
11
 
12
12
  // ---------------------------------------------------------------------------
13
13
  // Frontmatter step extraction
@@ -77,6 +77,63 @@ export function extractStepsFromFrontmatter(content: string): SkillStepDef[] | n
77
77
  return steps.length > 0 ? steps : null;
78
78
  }
79
79
 
80
+ // ---------------------------------------------------------------------------
81
+ // Announce / Complete injection
82
+ // ---------------------------------------------------------------------------
83
+
84
+ /**
85
+ * Extract the `name:` field from YAML frontmatter.
86
+ * Returns the raw string value, or null if not found.
87
+ */
88
+ export function extractNameFromFrontmatter(content: string): string | null {
89
+ const fmMatch = content.match(/^---\n([\s\S]*?)\n---/);
90
+ if (!fmMatch) return null;
91
+ const nameMatch = fmMatch[1].match(/^name:\s*(.+)/m);
92
+ return nameMatch ? nameMatch[1].trim().replace(/^["']|["']$/g, '') : null;
93
+ }
94
+
95
+ /**
96
+ * Inject announce and completion feedback instructions into a skill's content.
97
+ *
98
+ * Announce goes immediately after the frontmatter block.
99
+ * Complete goes at the very end of the file.
100
+ * Both are inside HTML comments so they don't clutter the rendered output.
101
+ */
102
+ export function injectSkillFeedback(content: string, skillName: string): string {
103
+ // Count ### headings as "steps"
104
+ const stepMatches = content.match(/^### .+/gm) ?? [];
105
+ const stepCount = stepMatches.length;
106
+ const firstStep = stepMatches[0]?.replace(/^### \d+\.\s*/, '').trim() ?? 'Step 1';
107
+
108
+ const displayName = skillName
109
+ .replace(/^soleri-/, '')
110
+ .replace(/-/g, ' ')
111
+ .replace(/\b\w/g, (c) => c.toUpperCase());
112
+
113
+ const announceBlock = [
114
+ '',
115
+ '## Announce',
116
+ '',
117
+ `When this skill is invoked, immediately say:`,
118
+ `> "Using **${displayName}** skill${stepCount > 0 ? ` (${stepCount} steps)` : ''}. Starting with: ${firstStep}"`,
119
+ '',
120
+ ].join('\n');
121
+
122
+ const completeBlock = [
123
+ '',
124
+ '## Completion',
125
+ '',
126
+ 'After all steps are done, close with a one-line summary:',
127
+ `> "${displayName} complete: {brief outcome — e.g. '3 captured, 1 skipped'}"`,
128
+ '',
129
+ ].join('\n');
130
+
131
+ // Insert announce block right after the closing --- of frontmatter
132
+ const afterFm = content.replace(/^(---\n[\s\S]*?\n---\n)/, `$1${announceBlock}`);
133
+
134
+ return afterFm + completeBlock;
135
+ }
136
+
80
137
  // ---------------------------------------------------------------------------
81
138
  // Skill generation
82
139
  // ---------------------------------------------------------------------------
@@ -136,9 +193,12 @@ export function generateSkills(config: AgentConfig): Array<[string, string]> {
136
193
  let content = readFileSync(contentPath, 'utf-8');
137
194
 
138
195
  if (content.includes(AGENT_PLACEHOLDER)) {
139
- content = content.replace(/YOUR_AGENT_core/g, `${config.id}_core`);
196
+ content = content.replace(/YOUR_AGENT_/g, `${config.id}_`);
140
197
  }
141
198
 
199
+ // Inject announce / complete feedback blocks
200
+ content = injectSkillFeedback(content, skillName);
201
+
142
202
  // Extract structured steps from frontmatter and append as metadata block
143
203
  const steps = extractStepsFromFrontmatter(content);
144
204
  if (steps) {
package/vitest.config.ts CHANGED
@@ -3,7 +3,8 @@ import { defineConfig } from 'vitest/config';
3
3
  export default defineConfig({
4
4
  test: {
5
5
  environment: 'node',
6
- pool: 'threads',
6
+ pool: 'forks',
7
+ poolOptions: { forks: { singleFork: true } },
7
8
  testTimeout: 30_000,
8
9
  exclude: ['**/node_modules/**', '**/.claude/worktrees/**'],
9
10
  coverage: {