@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.
- package/dist/agent-schema.d.ts +2 -2
- package/dist/compose-claude-md.js +5 -2
- package/dist/compose-claude-md.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/lib.d.ts +1 -0
- package/dist/lib.js +1 -0
- package/dist/lib.js.map +1 -1
- package/dist/scaffold-filetree.js +27 -0
- package/dist/scaffold-filetree.js.map +1 -1
- package/dist/scaffolder.js +10 -0
- package/dist/scaffolder.js.map +1 -1
- package/dist/skills/soleri-agent-dev/SKILL.md +1 -0
- package/dist/skills/soleri-agent-guide/SKILL.md +1 -0
- package/dist/skills/soleri-agent-issues/SKILL.md +1 -0
- package/dist/skills/soleri-agent-mode/SKILL.md +173 -0
- package/dist/skills/soleri-agent-persona/SKILL.md +1 -0
- package/dist/skills/soleri-brain-debrief/SKILL.md +1 -0
- package/dist/skills/soleri-brainstorming/SKILL.md +1 -0
- package/dist/skills/soleri-build-skill/SKILL.md +2 -0
- package/dist/skills/soleri-code-patrol/SKILL.md +1 -0
- package/dist/skills/soleri-context-resume/SKILL.md +1 -0
- package/dist/skills/soleri-curator/SKILL.md +66 -0
- package/dist/skills/soleri-deep-review/SKILL.md +1 -0
- package/dist/skills/soleri-deliver-and-ship/SKILL.md +1 -0
- package/dist/skills/soleri-discovery-phase/SKILL.md +1 -0
- package/dist/skills/soleri-dream/SKILL.md +31 -1
- package/dist/skills/soleri-env-setup/SKILL.md +1 -0
- package/dist/skills/soleri-executing-plans/SKILL.md +1 -0
- package/dist/skills/soleri-finishing-a-development-branch/SKILL.md +1 -0
- package/dist/skills/soleri-fix-and-learn/SKILL.md +1 -0
- package/dist/skills/soleri-health-check/SKILL.md +1 -0
- package/dist/skills/soleri-intake/SKILL.md +100 -0
- package/dist/skills/soleri-knowledge-harvest/SKILL.md +1 -0
- package/dist/skills/soleri-loop/SKILL.md +69 -0
- package/dist/skills/soleri-mcp-doctor/SKILL.md +1 -0
- package/dist/skills/soleri-onboard-me/SKILL.md +1 -0
- package/dist/skills/soleri-orchestrate/SKILL.md +70 -0
- package/dist/skills/soleri-parallel-execute/SKILL.md +1 -0
- package/dist/skills/soleri-research-scout/SKILL.md +1 -0
- package/dist/skills/soleri-retrospective/SKILL.md +1 -0
- package/dist/skills/soleri-second-opinion/SKILL.md +1 -0
- package/dist/skills/soleri-subagent-driven-development/SKILL.md +1 -0
- package/dist/skills/soleri-systematic-debugging/SKILL.md +1 -0
- package/dist/skills/soleri-test-driven-development/SKILL.md +1 -0
- package/dist/skills/soleri-using-git-worktrees/SKILL.md +1 -0
- package/dist/skills/soleri-vault-capture/SKILL.md +6 -5
- package/dist/skills/soleri-vault-curate/SKILL.md +1 -0
- package/dist/skills/soleri-vault-navigator/SKILL.md +1 -0
- package/dist/skills/soleri-vault-smells/SKILL.md +1 -0
- package/dist/skills/soleri-verification-before-completion/SKILL.md +1 -0
- package/dist/skills/soleri-writing-plans/SKILL.md +6 -3
- package/dist/skills/soleri-yolo-mode/SKILL.md +1 -0
- package/dist/templates/claude-md-template.js +2 -29
- package/dist/templates/claude-md-template.js.map +1 -1
- package/dist/templates/package-json.js +2 -0
- package/dist/templates/package-json.js.map +1 -1
- package/dist/templates/setup-script.js +6 -63
- package/dist/templates/setup-script.js.map +1 -1
- package/dist/templates/shared-rules.js +11 -4
- package/dist/templates/shared-rules.js.map +1 -1
- package/dist/templates/skills.d.ts +13 -0
- package/dist/templates/skills.js +55 -3
- package/dist/templates/skills.js.map +1 -1
- package/dist/types.d.ts +2 -2
- package/package.json +1 -1
- package/src/__tests__/knowledge-installer.test.ts +1 -1
- package/src/__tests__/scaffold-filetree.test.ts +1 -1
- package/src/__tests__/scaffolder.test.ts +143 -111
- package/src/compose-claude-md.ts +5 -1
- package/src/lib.ts +1 -0
- package/src/scaffold-filetree.ts +33 -0
- package/src/scaffolder.ts +10 -0
- package/src/skills/soleri-agent-dev/SKILL.md +1 -0
- package/src/skills/soleri-agent-guide/SKILL.md +1 -0
- package/src/skills/soleri-agent-issues/SKILL.md +1 -0
- package/src/skills/soleri-agent-mode/SKILL.md +173 -0
- package/src/skills/soleri-agent-persona/SKILL.md +1 -0
- package/src/skills/soleri-brain-debrief/SKILL.md +1 -0
- package/src/skills/soleri-brainstorming/SKILL.md +1 -0
- package/src/skills/soleri-build-skill/SKILL.md +2 -0
- package/src/skills/soleri-code-patrol/SKILL.md +1 -0
- package/src/skills/soleri-context-resume/SKILL.md +1 -0
- package/src/skills/soleri-curator/SKILL.md +66 -0
- package/src/skills/soleri-deep-review/SKILL.md +1 -0
- package/src/skills/soleri-deliver-and-ship/SKILL.md +1 -0
- package/src/skills/soleri-discovery-phase/SKILL.md +1 -0
- package/src/skills/soleri-dream/SKILL.md +31 -1
- package/src/skills/soleri-env-setup/SKILL.md +1 -0
- package/src/skills/soleri-executing-plans/SKILL.md +1 -0
- package/src/skills/soleri-finishing-a-development-branch/SKILL.md +1 -0
- package/src/skills/soleri-fix-and-learn/SKILL.md +1 -0
- package/src/skills/soleri-health-check/SKILL.md +1 -0
- package/src/skills/soleri-intake/SKILL.md +100 -0
- package/src/skills/soleri-knowledge-harvest/SKILL.md +1 -0
- package/src/skills/soleri-loop/SKILL.md +69 -0
- package/src/skills/soleri-mcp-doctor/SKILL.md +1 -0
- package/src/skills/soleri-onboard-me/SKILL.md +1 -0
- package/src/skills/soleri-orchestrate/SKILL.md +70 -0
- package/src/skills/soleri-parallel-execute/SKILL.md +1 -0
- package/src/skills/soleri-research-scout/SKILL.md +1 -0
- package/src/skills/soleri-retrospective/SKILL.md +1 -0
- package/src/skills/soleri-second-opinion/SKILL.md +1 -0
- package/src/skills/soleri-subagent-driven-development/SKILL.md +1 -0
- package/src/skills/soleri-systematic-debugging/SKILL.md +1 -0
- package/src/skills/soleri-test-driven-development/SKILL.md +1 -0
- package/src/skills/soleri-using-git-worktrees/SKILL.md +1 -0
- package/src/skills/soleri-vault-capture/SKILL.md +6 -5
- package/src/skills/soleri-vault-curate/SKILL.md +1 -0
- package/src/skills/soleri-vault-navigator/SKILL.md +1 -0
- package/src/skills/soleri-vault-smells/SKILL.md +1 -0
- package/src/skills/soleri-verification-before-completion/SKILL.md +1 -0
- package/src/skills/soleri-writing-plans/SKILL.md +6 -3
- package/src/skills/soleri-yolo-mode/SKILL.md +1 -0
- package/src/templates/claude-md-template.ts +2 -50
- package/src/templates/package-json.ts +2 -0
- package/src/templates/setup-script.ts +6 -63
- package/src/templates/shared-rules.ts +11 -4
- package/src/templates/skills.ts +63 -3
- 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,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
|
-
|
|
7
|
-
|
|
8
|
-
knowledge-harvest
|
|
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,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",
|
|
5
|
-
"plan the implementation".
|
|
6
|
-
|
|
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
|
|
@@ -70,60 +70,12 @@ export function generateClaudeMdTemplate(config: AgentConfig): string {
|
|
|
70
70
|
'',
|
|
71
71
|
];
|
|
72
72
|
|
|
73
|
-
// ───
|
|
73
|
+
// ─── Skill pointer (replaces inline facade table) ───────
|
|
74
74
|
mdLines.push(
|
|
75
|
-
|
|
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
|
-
#
|
|
39
|
-
SETTINGS_FILE="$HOME/.claude/settings.json"
|
|
38
|
+
# Sync lifecycle hooks into ~/.claude/settings.json
|
|
40
39
|
echo ""
|
|
41
|
-
echo "
|
|
42
|
-
|
|
43
|
-
|
|
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
|
-
|
|
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
|
-
'
|
|
190
|
-
'
|
|
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
|
-
'-
|
|
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',
|
package/src/templates/skills.ts
CHANGED
|
@@ -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
|
|
10
|
-
const AGENT_PLACEHOLDER = '
|
|
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(/
|
|
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: '
|
|
6
|
+
pool: 'forks',
|
|
7
|
+
poolOptions: { forks: { singleFork: true } },
|
|
7
8
|
testTimeout: 30_000,
|
|
8
9
|
exclude: ['**/node_modules/**', '**/.claude/worktrees/**'],
|
|
9
10
|
coverage: {
|