@soleri/forge 9.7.2 → 9.8.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/agent-schema.d.ts +177 -6
- package/dist/agent-schema.js +58 -0
- package/dist/agent-schema.js.map +1 -1
- package/dist/compose-claude-md.js +56 -3
- package/dist/compose-claude-md.js.map +1 -1
- package/dist/domain-manager.d.ts +1 -0
- package/dist/domain-manager.js +57 -1
- package/dist/domain-manager.js.map +1 -1
- package/dist/knowledge-installer.d.ts +2 -0
- package/dist/knowledge-installer.js +107 -1
- package/dist/knowledge-installer.js.map +1 -1
- package/dist/lib.d.ts +1 -1
- package/dist/lib.js +1 -1
- package/dist/lib.js.map +1 -1
- package/dist/scaffold-filetree.d.ts +12 -0
- package/dist/scaffold-filetree.js +332 -2
- package/dist/scaffold-filetree.js.map +1 -1
- package/dist/scaffolder.js +12 -0
- package/dist/scaffolder.js.map +1 -1
- package/dist/templates/setup-script.js +71 -0
- package/dist/templates/setup-script.js.map +1 -1
- package/dist/templates/shared-rules.js +52 -6
- package/dist/templates/shared-rules.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/domain-manager.test.ts +140 -0
- package/src/__tests__/scaffold-filetree.test.ts +282 -1
- package/src/__tests__/shared-rules.test.ts +48 -0
- package/src/agent-schema.ts +66 -0
- package/src/compose-claude-md.ts +63 -3
- package/src/domain-manager.ts +74 -1
- package/src/knowledge-installer.ts +124 -1
- package/src/lib.ts +6 -1
- package/src/scaffold-filetree.ts +380 -2
- package/src/scaffolder.ts +17 -0
- package/src/templates/setup-script.ts +71 -0
- package/src/templates/shared-rules.ts +53 -6
|
@@ -322,6 +322,77 @@ else
|
|
|
322
322
|
echo "Note: Add $AGENT_DIR/scripts to PATH, or symlink $AGENT_DIR/scripts/$AGENT_NAME to /usr/local/bin/$AGENT_NAME"
|
|
323
323
|
fi
|
|
324
324
|
fi
|
|
325
|
+
|
|
326
|
+
# Configure OpenCode enforcement plugin (hooks)
|
|
327
|
+
OPENCODE_PLUGINS_DIR="$AGENT_DIR/.opencode/plugins"
|
|
328
|
+
ENFORCEMENT_PLUGIN="$OPENCODE_PLUGINS_DIR/soleri-enforcement.ts"
|
|
329
|
+
|
|
330
|
+
echo ""
|
|
331
|
+
echo "Configuring OpenCode enforcement plugin..."
|
|
332
|
+
mkdir -p "$OPENCODE_PLUGINS_DIR"
|
|
333
|
+
|
|
334
|
+
if [ -f "$ENFORCEMENT_PLUGIN" ]; then
|
|
335
|
+
echo "[ok] Enforcement plugin already exists — skipping"
|
|
336
|
+
else
|
|
337
|
+
cat > "$ENFORCEMENT_PLUGIN" << PLUGIN
|
|
338
|
+
/**
|
|
339
|
+
* Soleri enforcement plugin for OpenCode.
|
|
340
|
+
* Auto-generated by setup script — do not edit manually.
|
|
341
|
+
*
|
|
342
|
+
* Hooks:
|
|
343
|
+
* - tool.execute.before: block destructive commands (anti-deletion)
|
|
344
|
+
* - session.compacted: capture session summary before context compaction
|
|
345
|
+
* - session.created: clean stale git worktrees on session start
|
|
346
|
+
*/
|
|
347
|
+
|
|
348
|
+
const DESTRUCTIVE_PATTERNS = [
|
|
349
|
+
/\\brm\\s+(-[rRf]+\\s+|--force\\s+|--recursive\\s+)/,
|
|
350
|
+
/\\brmdir\\b/,
|
|
351
|
+
/\\bgit\\s+push\\s+--force\\b/,
|
|
352
|
+
/\\bgit\\s+push\\s+-f\\b/,
|
|
353
|
+
/\\bgit\\s+reset\\s+--hard\\b/,
|
|
354
|
+
/\\bgit\\s+clean\\s+-[a-zA-Z]*f/,
|
|
355
|
+
];
|
|
356
|
+
|
|
357
|
+
export default {
|
|
358
|
+
hooks: {
|
|
359
|
+
'tool.execute.before': (ctx) => {
|
|
360
|
+
// Anti-deletion: intercept destructive commands
|
|
361
|
+
const input = JSON.stringify(ctx.input ?? '');
|
|
362
|
+
for (const pattern of DESTRUCTIVE_PATTERNS) {
|
|
363
|
+
if (pattern.test(input)) {
|
|
364
|
+
throw new Error(
|
|
365
|
+
'[soleri-anti-deletion] BLOCKED: Destructive command detected. ' +
|
|
366
|
+
'Use explicit confirmation or a safer alternative.'
|
|
367
|
+
);
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
},
|
|
371
|
+
'session.compacted': (ctx) => {
|
|
372
|
+
// Session capture: call op:session_capture before context compaction
|
|
373
|
+
console.info(
|
|
374
|
+
'[soleri-session-capture] Before context is compacted, capture a session summary ' +
|
|
375
|
+
'by calling ${config.id}_core op:session_capture with a brief summary of what was ' +
|
|
376
|
+
'accomplished, the topics covered, files modified, and tools used.'
|
|
377
|
+
);
|
|
378
|
+
},
|
|
379
|
+
'session.created': (ctx) => {
|
|
380
|
+
// Worktree cleanup: clean stale git worktrees on session start
|
|
381
|
+
try {
|
|
382
|
+
const { execSync } = require('child_process');
|
|
383
|
+
execSync('sh $AGENT_DIR/scripts/clean-worktrees.sh', {
|
|
384
|
+
timeout: 10000,
|
|
385
|
+
stdio: 'pipe',
|
|
386
|
+
});
|
|
387
|
+
} catch (err) {
|
|
388
|
+
console.warn('[soleri-worktree-cleanup] Failed to clean worktrees:', err.message);
|
|
389
|
+
}
|
|
390
|
+
},
|
|
391
|
+
},
|
|
392
|
+
};
|
|
393
|
+
PLUGIN
|
|
394
|
+
echo "[ok] Created enforcement plugin at $ENFORCEMENT_PLUGIN"
|
|
395
|
+
fi
|
|
325
396
|
`
|
|
326
397
|
: '';
|
|
327
398
|
|
|
@@ -341,13 +341,29 @@ const ENGINE_RULES_LINES: string[] = [
|
|
|
341
341
|
'',
|
|
342
342
|
'### The Non-Negotiable Rule',
|
|
343
343
|
'',
|
|
344
|
-
'`op:orchestrate_complete` runs for EVERY task — simple or complex.
|
|
344
|
+
'`op:orchestrate_complete` runs for EVERY task — simple or complex. But it is **user-gated**: never auto-complete without confirmation.',
|
|
345
|
+
'',
|
|
346
|
+
'This captures:',
|
|
345
347
|
'- Knowledge to vault (patterns learned, decisions made)',
|
|
346
348
|
'- Session summary (what was done, files changed)',
|
|
347
349
|
"- Brain feedback (what worked, what didn't)",
|
|
348
350
|
'',
|
|
349
351
|
'Without completion, the knowledge trail is lost. The code is in git, but the WHY disappears.',
|
|
350
352
|
'',
|
|
353
|
+
'### Reconciliation Triggers',
|
|
354
|
+
'',
|
|
355
|
+
'`op:orchestrate_complete` is triggered by one of three conditions — all require user confirmation before running.',
|
|
356
|
+
'',
|
|
357
|
+
'| Trigger | Condition | Agent Action |',
|
|
358
|
+
'|---------|-----------|--------------|',
|
|
359
|
+
'| **Explicit** | User says "done", "ship it", "looks good", "wrap up" | Call `op:orchestrate_complete` immediately |',
|
|
360
|
+
'| **Plan-complete** | All plan tasks reach terminal state (completed/skipped/failed) | Ask: "All tasks are complete. Want me to wrap up and capture what we learned, or is there more to fix?" |',
|
|
361
|
+
'| **Idle** | Plan in `executing` state with no recent task work | Ask: "We\'ve been idle on this plan. Ready to wrap up, or still working?" |',
|
|
362
|
+
'',
|
|
363
|
+
'**NEVER auto-complete without asking the user.** The agent detects readiness but the user decides when to finalize.',
|
|
364
|
+
'',
|
|
365
|
+
'Use `op:orchestrate_status` to check plan readiness — it includes a `readiness` field with `allTasksTerminal`, `terminalCount`, `totalCount`, and `idleSince` for the active plan.',
|
|
366
|
+
'',
|
|
351
367
|
'### Exceptions (skip assessment, execute directly)',
|
|
352
368
|
'',
|
|
353
369
|
'- Read-only operations (search, status, health check)',
|
|
@@ -588,6 +604,7 @@ const ENGINE_RULES_LINES: string[] = [
|
|
|
588
604
|
'```',
|
|
589
605
|
'',
|
|
590
606
|
'The scaffolded agent is ready immediately — no build step, no npm install for the agent itself.',
|
|
607
|
+
'Git is initialized by default (`git init` + initial commit). Use `--no-git` to skip. After scaffolding, the CLI offers to set up a remote via `gh repo create` (if gh CLI is available) or a manual remote URL. The `--yes` flag enables git init but skips the remote prompt.',
|
|
591
608
|
'',
|
|
592
609
|
'### Updating Soleri',
|
|
593
610
|
'',
|
|
@@ -631,11 +648,14 @@ const ENGINE_RULES_LINES: string[] = [
|
|
|
631
648
|
'The composition pipeline assembles CLAUDE.md from:',
|
|
632
649
|
'',
|
|
633
650
|
'1. **Agent identity** — from `agent.yaml`',
|
|
634
|
-
'2. **
|
|
635
|
-
'3. **
|
|
636
|
-
'4. **
|
|
637
|
-
'5. **
|
|
638
|
-
'6. **
|
|
651
|
+
'2. **Custom instructions** — from `instructions/user.md` (priority placement, before engine rules)',
|
|
652
|
+
'3. **Engine rules** — from `@soleri/forge` shared rules (this section)',
|
|
653
|
+
'4. **User instructions** — from `instructions/*.md` (alphabetically sorted, excluding `user.md` and `_engine.md`)',
|
|
654
|
+
'5. **Tools table** — from engine registration',
|
|
655
|
+
'6. **Workflow index** — from `workflows/`',
|
|
656
|
+
'7. **Skills index** — from `skills/`',
|
|
657
|
+
'',
|
|
658
|
+
'`instructions/user.md` is the recommended place for your most important agent-specific rules — it appears early in CLAUDE.md for maximum influence on model behavior. Other `instructions/*.md` files are included after engine rules.',
|
|
639
659
|
'',
|
|
640
660
|
'When the engine updates (`@soleri/core` or `@soleri/forge`), running `soleri agent refresh` regenerates CLAUDE.md with the latest shared rules. Your own `instructions/*.md` files are where agent-specific behavior lives — those survive regeneration.',
|
|
641
661
|
'',
|
|
@@ -687,6 +707,10 @@ const ENGINE_RULES_LINES: string[] = [
|
|
|
687
707
|
'',
|
|
688
708
|
'### Hooks & Skills',
|
|
689
709
|
'',
|
|
710
|
+
'Your agent ships with **essential skills** by default (agent-guide, agent-persona, vault-navigator, vault-capture, systematic-debugging, writing-plans, context-resume). Install more with `soleri skills install <name>`. List available skills with `soleri skills list`.',
|
|
711
|
+
'',
|
|
712
|
+
'To scaffold all skills instead, set `skillsFilter: all` in `agent.yaml`.',
|
|
713
|
+
'',
|
|
690
714
|
'| Command | What it does |',
|
|
691
715
|
'|---------|-------------|',
|
|
692
716
|
'| `soleri hooks list-packs` | Show available hook packs and their status |',
|
|
@@ -701,6 +725,7 @@ const ENGINE_RULES_LINES: string[] = [
|
|
|
701
725
|
'|---------|-------------|',
|
|
702
726
|
'| `soleri install` | Register agent as MCP server (`--target opencode\\|claude\\|codex\\|all`) |',
|
|
703
727
|
'| `soleri uninstall` | Remove agent MCP server entry |',
|
|
728
|
+
'| `soleri create --no-git` | Scaffold agent without git initialization |',
|
|
704
729
|
'| `soleri governance --show` | Show vault governance policy |',
|
|
705
730
|
'| `soleri governance --preset <name>` | Set policy preset (strict\\|moderate\\|permissive) |',
|
|
706
731
|
'| `soleri upgrade` | Upgrade @soleri/cli (`--check` to preview) |',
|
|
@@ -749,6 +774,28 @@ const ENGINE_RULES_LINES: string[] = [
|
|
|
749
774
|
'- Any file inside `@soleri/core` or `@soleri/forge`',
|
|
750
775
|
'',
|
|
751
776
|
|
|
777
|
+
// ─── Workspace Routing ─────────────────────────────────────
|
|
778
|
+
'## Workspace Routing',
|
|
779
|
+
'<!-- soleri:workspace-routing -->',
|
|
780
|
+
'',
|
|
781
|
+
'Agents can define **workspaces** — scoped context areas with their own CONTEXT.md files — and a **routing table** that maps task patterns to workspaces.',
|
|
782
|
+
'',
|
|
783
|
+
'### How It Works',
|
|
784
|
+
'',
|
|
785
|
+
'1. When a task matches a routing pattern, navigate to that workspace.',
|
|
786
|
+
"2. Load the workspace's CONTEXT.md for task-specific instructions and context.",
|
|
787
|
+
'3. Activate only the skills listed in the routing entry.',
|
|
788
|
+
'4. If no pattern matches, use the default root context (agent-level CLAUDE.md).',
|
|
789
|
+
'',
|
|
790
|
+
'### Routing Rules',
|
|
791
|
+
'',
|
|
792
|
+
'- Patterns are matched by semantic similarity, not exact string match.',
|
|
793
|
+
'- The routing table is defined in `agent.yaml` under the `routing:` key.',
|
|
794
|
+
'- Workspaces are directories under `workspaces/{id}/` with a CONTEXT.md file.',
|
|
795
|
+
'- When entering a workspace, its CONTEXT.md supplements (not replaces) the root context.',
|
|
796
|
+
'- Skills listed in the routing entry are prioritized but do not prevent other skills from activating.',
|
|
797
|
+
'',
|
|
798
|
+
|
|
752
799
|
// ─── Verification Protocol ─────────────────────────────────
|
|
753
800
|
'## Verification Protocol',
|
|
754
801
|
'<!-- soleri:verification-protocol -->',
|