@vpxa/aikit 0.1.359 → 0.1.360

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 (37) hide show
  1. package/package.json +1 -1
  2. package/packages/analyzers/dist/index.d.ts +1 -1
  3. package/packages/cli/dist/index.js +3 -3
  4. package/packages/cli/dist/{init-Cvys5TD4.js → init-C_WzeMTD.js} +1 -1
  5. package/packages/cli/dist/{templates-d2UQHjpi.js → templates-DUUaYk_d.js} +1 -1
  6. package/packages/core/dist/index.d.ts +43 -2
  7. package/packages/core/dist/index.js +1 -1
  8. package/packages/present/dist/annotation-layer.js +10 -10
  9. package/packages/server/dist/bin.js +1 -1
  10. package/packages/server/dist/index.js +1 -1
  11. package/packages/server/dist/observations-CfglxBMB.js +6 -0
  12. package/packages/server/dist/observations-CrQU_HVm.js +5 -0
  13. package/packages/server/dist/prelude-CNOjd5qt.js +2 -0
  14. package/packages/server/dist/prelude-Dki25eYn.js +1 -0
  15. package/packages/server/dist/sampling-B8NwOv_z.js +1 -0
  16. package/packages/server/dist/sampling-DOOgTH1B.js +2 -0
  17. package/packages/server/dist/{server-CICqmfQ_.js → server-C2n9kQMF.js} +179 -185
  18. package/packages/server/dist/{server-BZVPmRGV.js → server-CizTllz1.js} +180 -184
  19. package/packages/server/dist/{server-http-CPU9_eVT.js → server-http-BaMUtb5Y.js} +1 -1
  20. package/packages/server/dist/{server-http-D3DK1H19.js → server-http-Dd2uCMBi.js} +1 -1
  21. package/packages/server/dist/{server-stdio-BRKxFWyO.js → server-stdio-B5rk-PAI.js} +1 -1
  22. package/packages/server/dist/{server-stdio-l8I0RW4l.js → server-stdio-CtR4QNT3.js} +1 -1
  23. package/packages/tools/dist/index.js +69 -69
  24. package/scaffold/AUTOMATION-BOUNDARY-ANALYSIS.md +78 -0
  25. package/scaffold/dist/adapters/_shared.mjs +7 -6
  26. package/scaffold/dist/adapters/claude-code.mjs +7 -7
  27. package/scaffold/dist/adapters/claude-desktop.mjs +7 -0
  28. package/scaffold/dist/adapters/gemini.mjs +6 -6
  29. package/scaffold/dist/adapters/hermes.mjs +5 -5
  30. package/scaffold/dist/adapters/hooks.mjs +1 -1
  31. package/scaffold/dist/adapters/opencode.mjs +7 -7
  32. package/scaffold/dist/definitions/exec-hooks.mjs +1 -1
  33. package/scaffold/dist/definitions/platform-capabilities.mjs +1 -0
  34. package/packages/server/dist/prelude-CfXBHLpw.js +0 -1
  35. package/packages/server/dist/prelude-D33q42vQ.js +0 -2
  36. package/packages/server/dist/sampling-Cs9MoNYX.js +0 -2
  37. package/packages/server/dist/sampling-DFogBKrL.js +0 -1
@@ -0,0 +1,78 @@
1
+ # Automation Boundary Analysis (Reconciled)
2
+
3
+ > **Status:** Corrected per architectural review (2026-06-28).
4
+ > **Previous version:** Classified 7 actions as AUTOMATABLE with 80% token savings claims.
5
+ > **Corrections:**
6
+ > - `status({includePrelude: true})` is LLM-JUDGMENT, not automatable
7
+ > - `search({query: "SESSION CHECKPOINT"})` is LLM-JUDGMENT — fixed query silently misses
8
+ > - `check({})` / `test_run({})` are MIXED/SCOPED only — full-project runs too slow
9
+ > - Token savings claims removed — not proven
10
+ >
11
+ > See `docs/architecture/eventbus-hooks-developer-guide.md` for the full implementation guide.
12
+
13
+ ---
14
+
15
+ ## Corrected Classification
16
+
17
+ | Action | Correct Category | Reason |
18
+ |--------|-----------------|--------|
19
+ | `status({})` at session start | **Automatable signal** | Safe only when bounded (no includePrelude) and not used as dynamic instruction replacement |
20
+ | `status({includePrelude: true})` | **LLM judgment** | Produces LLM-facing context; may be stale if hidden behind a hook |
21
+ | `knowledge({action: "list"})` at session start | **Automatable signal with budget** | Safe only with strict result cap and no full-list injection |
22
+ | `search({query: "SESSION CHECKPOINT"})` | **LLM judgment** | Fixed query can silently miss relevant checkpoints |
23
+ | `search({query: "<task>"})` before code change | **LLM judgment** | Query requires task understanding |
24
+ | `scope_map({task})` before code change | **LLM judgment** | Task description requires LLM synthesis |
25
+ | `check({})` / `test_run({})` before commit | **Mixed, scoped only** | Full-project runs too slow; must pass `files` from `git diff` or user intent |
26
+ | `blast_radius({changed_files})` before commit | **Mixed** | Call can be automated; output interpretation is LLM judgment |
27
+ | Handoff/checkpoint content creation | **LLM judgment** | Requires summarizing decisions and next steps |
28
+ | Writing a prepared handoff file | **Automatable** | File IO is deterministic after content exists |
29
+ | Skill loading at session start | **LLM judgment with signal** | Hook can recommend; LLM must choose and follow skill protocol |
30
+ | Context pressure check at session end | **Automatable signal** | Numeric comparison is deterministic |
31
+
32
+ ---
33
+
34
+ ## Per-Automation Specification
35
+
36
+ Each automated action must have:
37
+
38
+ | Field | Required |
39
+ |-------|----------|
40
+ | Input source | ✔ — What triggers the automation |
41
+ | Output budget | ✔ — Max tokens/characters produced |
42
+ | Timeout | ✔ — Max execution time |
43
+ | Failure mode | ✔ — Log, warn, or degrade (never silently fail) |
44
+ | User-visible trace | ✔ — Agent sees automation output |
45
+
46
+ ---
47
+
48
+ ## Per-LLM-Judgment Specification
49
+
50
+ Each LLM-judgment action must have:
51
+
52
+ | Field | Required |
53
+ |-------|----------|
54
+ | Why it cannot be automated | ✔ — Clear boundary reason |
55
+ | What instructions must remain | ✔ — Exact instruction text |
56
+ | How EventBus can assist (not replace) | ✔ — Signal, not decision |
57
+
58
+ ---
59
+
60
+ ## What NOT to Automate
61
+
62
+ These actions are explicitly rejected for automation:
63
+
64
+ - Search query composition (requires task understanding)
65
+ - Scope map task description (requires intent synthesis)
66
+ - Handoff/checkpoint content creation (requires LLM synthesis)
67
+ - Broad `check({})` / `test_run({})` without scope (too slow, may not match task)
68
+ - Any action where the automation would hide its own failures from the LLM
69
+
70
+ ---
71
+
72
+ ## Guiding Principles
73
+
74
+ 1. **Automate bounds, not decisions** — signals and file IO are safe; composition and synthesis are not
75
+ 2. **Every automation must be bounded** — max cost, max output, failure behavior, user-visible trace
76
+ 3. **No hidden behavior** — the LLM must know automation ran and see its output
77
+ 4. **LLM remains responsible for** — query composition, scope description, checkpoint/handoff synthesis, blast-radius interpretation, and validation choice when scope is unclear
78
+ 5. **Token savings require proof** — do not claim reduced instruction text until the removed instruction is proven safe to omit on that platform
@@ -5,10 +5,11 @@ import{renderLayeredKnowledgeOperatingPolicyV1 as e}from"../definitions/protocol
5
5
  `).trim();return l&&c.push(``,l),c.push(``,`---`,``),c.join(`
6
6
  `)}function a({title:e,content:t}){return`# ${e}\n\n${t}`}function o(e){return Object.entries(e).map(([e,t])=>[`### ${t.title||t.description||e}`,``,t.content.trim(),``,`---`,``].join(`
7
7
  `)).join(`
8
- `).trimEnd()}function s(e){return[[`Session Start`,e.sessionStart],[`Before Code Change`,e.beforeCodeChange],[`Before Commit`,e.beforeCommit],[`Session End`,e.sessionEnd]].map(([e,t])=>{let n=(t?.actions||[]).map(e=>`- \`${e}\``);return[`### ${e}`,``,...n,``].join(`
9
- `)}).join(`
10
- `).trimEnd()}function c(e,t){if(!e)return null;let n=typeof e==`function`?e(t):e[t];return n?typeof n==`string`?n:n.primary||n.model||null:null}function l(e,t){let n=!!t,r=[];for(let[i,a]of Object.entries(e))if(a.variants)for(let[e,o]of Object.entries(a.variants)){let s=`${i}-${e}`,l=[`| **${s}** | ${o.description} |`];n&&l.push(` ${c(t,s)||`—`} |`),l.push(` ${a.category||`—`} |`),r.push(l.join(``))}else{let e=[`| **${i}** | ${a.description} |`];n&&e.push(` ${c(t,i)||`—`} |`),e.push(` ${a.category||`—`} |`),r.push(e.join(``))}return n?`| Agent | Purpose | Model | Category |\n|-------|---------|-------|----------|\n${r.join(`
8
+ `).trimEnd()}const s={sessionStart:`SessionStart`,beforeCodeChange:`PreToolUse`,beforeCommit:`PreCommit`,sessionEnd:`SessionEnd`},c=[`sessionStart`,`beforeCodeChange`,`beforeCommit`,`sessionEnd`];function l(e){return e?.overall===`none`?[``,`> **Note**: This platform does not support native hook execution (no SessionStart, PreToolUse,`,`> PostToolUse, or PreCommit events). All hook behaviors documented below are **manual** -- you`,`> must perform them yourself. If you need server-side guardrails (privacy guards, scope`,`> enforcement, auto-knowledge signals), consider running the MCP server's **EventBus**, which`,`> provides in-process lifecycle subscribers without requiring IDE-level hook support.`,"> Check `aikit://hooks/config` for available EventBus subscribers.",``].join(`
9
+ `):``}function u(e,t,n,r,i){if(!e||i===`omit`)return``;i!==void 0&&i!==`pinned`&&i!=="default"&&console.warn(`buildHookSubsection: unrecognized treatment "${i}" for "${t}". Valid: ${p.join(`, `)}. Falling back to level-based rendering.`);let a=(e.actions||[]).map(e=>`- \`${e}\``),o=[`### ${t}`];return n===`native`?o.push(``,`_`+(r.native||`Auto-handled by native hooks.`)+`_ The following run automatically:`,``,...a,``):n===`eventbus`?o.push(``,`_`+(r.eventbus||`Monitored by EventBus.`)+`_ Active subscribers run automatically.`,`For awareness, these are the current subscribers:`,``,...a,``,"Check `aikit://hooks/config` for the full subscriber list.",``):n===`middleware`?o.push(``,`_`+(r.middleware||`Automated by middleware.`)+`_ The platform middleware handles this:`,``,...a,``):o.push(``,`${r.none||`Manually run the following:`}`,``,...a,``),o.join(`
10
+ `)}const d={sessionStart:{native:`Auto-handled by hooks. Status/knowledge/search run on every session start.`,eventbus:`Handled by EventBus. Session-start subscribers fire on connection.`,middleware:`Automated by ToolPipeline middleware. Status/knowledge/search run on session init.`,none:`On every session start, manually run the following to resume context:`},beforeCodeChange:{native:`Auto-handled by hooks. Search+scope checks run before every code change.`,eventbus:`Monitored by EventBus. Tool-before subscribers may provide context.`,none:`Before modifying any code, manually run these checks:`},beforeCommit:{native:`Hook auto-runs. Check+test+blast-radius run before every commit.`,eventbus:`No native pre-commit hooks on this platform. Validate manually:`,middleware:`No middleware-based pre-commit support. Validate manually:`,none:`Before committing changes, manually run these validations:`},sessionEnd:{native:`Auto-handled by hooks. Session-end hook persists checkpoints automatically.`,eventbus:`Tracked by EventBus. Stop subscribers fire on shutdown.`,middleware:`Automated by middleware. Handoff runs on session end.`,none:`Before ending a session (or at high context pressure), manually create a handoff:`}},f={sessionStart:`Session Start`,beforeCodeChange:`Before Code Change`,beforeCommit:`Before Commit`,sessionEnd:`Session End`},p=[`pinned`,`default`,`omit`];function m(e,t,n){if(!e)return``;let r=c.map(r=>{let i=e[r];if(!i)return``;let a=s[r],o=t&&a&&t[a]||`none`,c=d[r]||{},l=n?.[r];return u(i,f[r],o,c,l)}),i=l(t);return[...r,i].filter(Boolean).join(`
11
+ `).trimEnd()}function h(e,t){if(!e)return null;let n=typeof e==`function`?e(t):e[t];return n?typeof n==`string`?n:n.primary||n.model||null:null}function g(e,t){let n=!!t,r=[];for(let[i,a]of Object.entries(e))if(a.variants)for(let[e,o]of Object.entries(a.variants)){let s=`${i}-${e}`,c=[`| **${s}** | ${o.description} |`];n&&c.push(` ${h(t,s)||`—`} |`),c.push(` ${a.category||`—`} |`),r.push(c.join(``))}else{let e=[`| **${i}** | ${a.description} |`];n&&e.push(` ${h(t,i)||`—`} |`),e.push(` ${a.category||`—`} |`),r.push(e.join(``))}return n?`| Agent | Purpose | Model | Category |\n|-------|---------|-------|----------|\n${r.join(`
11
12
  `)}`:`| Agent | Purpose | Category |\n|-------|---------|----------|\n${r.join(`
12
- `)}`}function u(e){let t=[];for(let[n,r]of Object.entries(e)){if(n===`Orchestrator`)continue;let e=r.compactRole||r.description;if(r.variants){let i=Object.keys(r.variants);t.push(`| **${n}-${i.join(`/`)}** | ${e} |`)}else t.push(`| **${n}** | ${e} |`)}return`| Agent | Role |\n|-------|------|\n${t.join(`
13
- `)}`}function d({serverName:e,mcpEntry:t,configKey:n,extraServerFields:r}){let i={...t};return r&&Object.assign(i,r),JSON.stringify({[n]:{[e]:i}},null,2)}function f({flowTool:t=`flow`,isLifecycleOwner:n=!0}={}){let r=[`## Flows`,``,`This project uses aikit's pluggable flow system. Check flow status with the \`${t}\` MCP tool.`,``];return n?r.push(e({audience:`agent`}),``,`Use \`${t}({ action: 'list' })\` to see available flows and \`${t}({ action: 'start', name, topic })\` to begin one.`,``,`If a flow is active, follow the current step's skill instructions. Advance with \`${t}({ action: 'step', advance: 'next' })\`.`):r.push(`This project uses aikit's pluggable flow system. Use \`${t}({ action: 'status' })\` to check if a flow is active.`,`If dispatched as part of a flow, your work contributes to the current step. Do NOT advance or manage the flow — the Orchestrator handles flow lifecycle.`),r.join(`
14
- `)}function p({flowTool:e=`flow`}={}){return f({flowTool:e,isLifecycleOwner:!1})}export{r as buildAgentPrompt,l as buildAgentTable,u as buildCompactAgentTable,f as buildFlowSection,s as buildHooksSection,i as buildInlineAgentSection,d as buildMcpConfigJson,a as buildPromptFile,o as buildPromptSections,n as buildSkillsSection,p as buildSubagentFlowSection,t as lowerFirst};
13
+ `)}`}function _(e){let t=[];for(let[n,r]of Object.entries(e)){if(n===`Orchestrator`)continue;let e=r.compactRole||r.description;if(r.variants){let i=Object.keys(r.variants);t.push(`| **${n}-${i.join(`/`)}** | ${e} |`)}else t.push(`| **${n}** | ${e} |`)}return`| Agent | Role |\n|-------|------|\n${t.join(`
14
+ `)}`}function v({serverName:e,mcpEntry:t,configKey:n,extraServerFields:r}){let i={...t};return r&&Object.assign(i,r),JSON.stringify({[n]:{[e]:i}},null,2)}function y({flowTool:t=`flow`,isLifecycleOwner:n=!0}={}){let r=[`## Flows`,``,`This project uses aikit's pluggable flow system. Check flow status with the \`${t}\` MCP tool.`,``];return n?r.push(e({audience:`agent`}),``,`Use \`${t}({ action: 'list' })\` to see available flows and \`${t}({ action: 'start', name, topic })\` to begin one.`,``,`If a flow is active, follow the current step's skill instructions. Advance with \`${t}({ action: 'step', advance: 'next' })\`.`):r.push(`This project uses aikit's pluggable flow system. Use \`${t}({ action: 'status' })\` to check if a flow is active.`,`If dispatched as part of a flow, your work contributes to the current step. Do NOT advance or manage the flow — the Orchestrator handles flow lifecycle.`),r.join(`
15
+ `)}function b({flowTool:e=`flow`}={}){return y({flowTool:e,isLifecycleOwner:!1})}export{r as buildAgentPrompt,g as buildAgentTable,_ as buildCompactAgentTable,l as buildEventBusNote,y as buildFlowSection,m as buildHooksSection,i as buildInlineAgentSection,v as buildMcpConfigJson,a as buildPromptFile,o as buildPromptSections,n as buildSkillsSection,b as buildSubagentFlowSection,t as lowerFirst};
@@ -1,8 +1,8 @@
1
- import{AGENTS as e}from"../definitions/agents.mjs";import{AGENT_BODIES as t}from"../definitions/bodies.mjs";import{HOOKS as n}from"../definitions/hooks.mjs";import{MCP_SERVER_ENTRY as r,SERVER_NAME as i}from"../definitions/mcp.mjs";import{getPlatformPrimaryModelMap as a}from"../definitions/models.mjs";import{PROMPTS as o}from"../definitions/prompts.mjs";import{AIKIT_INSTALL_HINT_SECTION as s,PLATFORM_OUTPUT_RULES_SECTION as c,PROTOCOLS as l}from"../definitions/protocols.mjs";import{AIKIT_TOOLS as u,CLAUDE_CODE_TOOL_MAP as d,IDE_CAPABILITIES as f}from"../definitions/tools.mjs";import{buildAgentTable as p,buildCompactAgentTable as m,buildFlowSection as h,buildHooksSection as g,buildMcpConfigJson as _,buildSkillsSection as v,lowerFirst as y}from"./_shared.mjs";const b=h({flowTool:`flow`,isLifecycleOwner:!0}),x=h({flowTool:`flow`,isLifecycleOwner:!0}),S=h({flowTool:`flow`,isLifecycleOwner:!1});function C(e){return e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).replace(/[^a-zA-Z0-9]+/g,`-`).replace(/^-+|-+$/g,``).toLowerCase()}function w(e){return`"${String(e).replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}"`}function T(e){let t=(f[e]||[]).flatMap(e=>d[e]||[]),n=u.map(e=>`mcp__aikit__${e}`);return[...new Set([...t,...n])].sort((e,t)=>e.localeCompare(t))}function E(e,t){let n=[];return n.push(`# aikit ${e}`),n.push(``),t.description&&(n.push(`> ${t.description}`),n.push(``)),n.push(t.content.trim()),n.push(``),n.join(`
2
- `)}function D(e,n){let r=t[e];return typeof r==`function`?r(n):r||``}function O(e){let t=[];e.extraBody&&t.push(e.extraBody),e.sharedBase&&l[e.sharedBase]&&t.push(l[e.sharedBase]);for(let n of e.sharedProtocols||[])l[n]&&t.push(l[n]);return t}function k(){let t=[];for(let[n,r]of Object.entries(e)){if(r.variants){for(let[e,i]of Object.entries(r.variants))t.push({name:`${n}-${e}`,description:i.description||r.description});continue}t.push({name:n,description:r.description})}return t}function A(e){return k().map(({name:t,description:n})=>`- \`${e}/${t}.md\` — ${n}`).join(`
3
- `)}function j(t=p(e,a(`claude-code`))){return[`# aikit — Claude Code Agents`,``,c,``,s,``,`## MCP Server`,``,"Server name: `aikit`","Configured in `.mcp.json` (project) and `~/.claude.json` (user-global — `claude mcp add --scope user` format).","Default agent: `Orchestrator` in `~/.claude/settings.json` — every conversation starts as Orchestrator automatically.",``,`## Agents`,``,t,``,`## Agent Files`,``,A(`.claude/agents`),``,`## Commands`,``,"Slash commands live under `.claude/commands/`.",``,`## Session Protocol`,``,g(n),``].join(`
4
- `)}function M(){return[`# aikit — Claude Code Instructions`,``,"Detailed workspace instructions live in `AGENTS.md`.","Full sub-agent instructions live in `.claude/agents/`.","Slash commands live in `.claude/commands/`.","MCP server config lives in `.mcp.json` (project) and `~/.claude.json` (user-global — written by `claude mcp add --scope user`).","Default agent set to `Orchestrator` in `~/.claude/settings.json` — every conversation starts as Orchestrator, no `/agent` command needed.",``,"Start with `AGENTS.md`, then open the specific sub-agent file you want to use.",``,c,``,s,``].join(`
5
- `)}function N(e,t,n,r,i){let a=T(t.toolRole),o=O(t),s=v(t.skills),c=e===`Orchestrator`?[b,x]:[S],l=[n,...o,t.bodyAddendum,s,...c].filter(Boolean).join(`
1
+ import{AGENTS as e}from"../definitions/agents.mjs";import{AGENT_BODIES as t}from"../definitions/bodies.mjs";import{HOOKS as n}from"../definitions/hooks.mjs";import{MCP_SERVER_ENTRY as r,SERVER_NAME as i}from"../definitions/mcp.mjs";import{getPlatformPrimaryModelMap as a}from"../definitions/models.mjs";import{PLATFORM_HOOK_CAPABILITIES as o}from"../definitions/platform-capabilities.mjs";import{PROMPTS as s}from"../definitions/prompts.mjs";import{AIKIT_INSTALL_HINT_SECTION as c,PLATFORM_OUTPUT_RULES_SECTION as l,PROTOCOLS as u}from"../definitions/protocols.mjs";import{AIKIT_TOOLS as d,CLAUDE_CODE_TOOL_MAP as f,IDE_CAPABILITIES as p}from"../definitions/tools.mjs";import{buildAgentTable as m,buildCompactAgentTable as h,buildFlowSection as g,buildHooksSection as _,buildMcpConfigJson as v,buildSkillsSection as y,lowerFirst as b}from"./_shared.mjs";const x=g({flowTool:`flow`,isLifecycleOwner:!0}),S=g({flowTool:`flow`,isLifecycleOwner:!0}),C=g({flowTool:`flow`,isLifecycleOwner:!1});function w(e){return e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).replace(/[^a-zA-Z0-9]+/g,`-`).replace(/^-+|-+$/g,``).toLowerCase()}function T(e){return`"${String(e).replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}"`}function E(e){let t=(p[e]||[]).flatMap(e=>f[e]||[]),n=d.map(e=>`mcp__aikit__${e}`);return[...new Set([...t,...n])].sort((e,t)=>e.localeCompare(t))}function D(e,t){let n=[];return n.push(`# aikit ${e}`),n.push(``),t.description&&(n.push(`> ${t.description}`),n.push(``)),n.push(t.content.trim()),n.push(``),n.join(`
2
+ `)}function O(e,n){let r=t[e];return typeof r==`function`?r(n):r||``}function k(e){let t=[];e.extraBody&&t.push(e.extraBody),e.sharedBase&&u[e.sharedBase]&&t.push(u[e.sharedBase]);for(let n of e.sharedProtocols||[])u[n]&&t.push(u[n]);return t}function A(){let t=[];for(let[n,r]of Object.entries(e)){if(r.variants){for(let[e,i]of Object.entries(r.variants))t.push({name:`${n}-${e}`,description:i.description||r.description});continue}t.push({name:n,description:r.description})}return t}function j(e){return A().map(({name:t,description:n})=>`- \`${e}/${t}.md\` — ${n}`).join(`
3
+ `)}function M(t=m(e,a(`claude-code`))){return[`# aikit — Claude Code Agents`,``,l,``,c,``,`## MCP Server`,``,"Server name: `aikit`","Configured in `.mcp.json` (project) and `~/.claude.json` (user-global — `claude mcp add --scope user` format).","Default agent: `Orchestrator` in `~/.claude/settings.json` — every conversation starts as Orchestrator automatically.",``,`## Agents`,``,t,``,`## Agent Files`,``,j(`.claude/agents`),``,`## Commands`,``,"Slash commands live under `.claude/commands/`.",``,`## Session Protocol`,``,_(n,o[`claude-code`]),``].join(`
4
+ `)}function N(){return[`# aikit — Claude Code Instructions`,``,"Detailed workspace instructions live in `AGENTS.md`.","Full sub-agent instructions live in `.claude/agents/`.","Slash commands live in `.claude/commands/`.","MCP server config lives in `.mcp.json` (project) and `~/.claude.json` (user-global — written by `claude mcp add --scope user`).","Default agent set to `Orchestrator` in `~/.claude/settings.json` — every conversation starts as Orchestrator, no `/agent` command needed.",``,"Start with `AGENTS.md`, then open the specific sub-agent file you want to use.",``,l,``,c,``].join(`
5
+ `)}function P(e,t,n,r,i){let a=E(t.toolRole),o=k(t),s=y(t.skills),c=e===`Orchestrator`?[x,S]:[C],l=[n,...o,t.bodyAddendum,s,...c].filter(Boolean).join(`
6
6
 
7
- `).trim(),u=t.identity?`You are the **${e}**${t.identity}`:`You are the **${e}**, ${y(t.description)}.`,d=i?.[e],f=a.length>0?`tools: [${a.join(`, `)}]`:null,p=t.skills?.length>0?`skills: [${t.skills.map(([e])=>e).join(`, `)}]`:null,m=[`---`,`name: ${C(e)}`,`description: ${w(t.description)}`,...d?[`model: ${w(d)}`]:[],...f?[f]:[],`mcpServers:`,` - aikit`,...p?[p]:[],`---`,``,`# ${e} - ${t.title||e}`,``,u];return l&&m.push(``,l),m.push(``),m.join(`
8
- `)}function P(){let t=[],n=a(`claude-code`),s=p(e,n),c=m(e);t.push({path:`.mcp.json`,content:`${_({serverName:i,mcpEntry:r,configKey:`mcpServers`})}\n`}),t.push({path:`CLAUDE.md`,content:M()}),t.push({path:`AGENTS.md`,content:j(s)});for(let[e,n]of Object.entries(o))t.push({path:`.claude/commands/aikit-${e}.md`,content:E(e,n)});for(let[r,i]of Object.entries(e)){let e=D(r,c);if(i.variants){for(let[a,o]of Object.entries(i.variants)){let c=`${r}-${a}`;t.push({path:`.claude/agents/${c}.md`,content:N(c,{...i,description:o.description||i.description,identity:o.identity,bodyAddendum:o.bodyAddendum},e,s,n)})}continue}t.push({path:`.claude/agents/${r}.md`,content:N(r,i,e,s,n)})}return t}export{b as CLAUDE_FLOWS_SECTION,x as CLAUDE_ORCHESTRATOR_FLOW_ROUTING_SECTION,P as generateClaudeCode};
7
+ `).trim(),u=t.identity?`You are the **${e}**${t.identity}`:`You are the **${e}**, ${b(t.description)}.`,d=i?.[e],f=a.length>0?`tools: [${a.join(`, `)}]`:null,p=t.skills?.length>0?`skills: [${t.skills.map(([e])=>e).join(`, `)}]`:null,m=[`---`,`name: ${w(e)}`,`description: ${T(t.description)}`,...d?[`model: ${T(d)}`]:[],...f?[f]:[],`mcpServers:`,` - aikit`,...p?[p]:[],`---`,``,`# ${e} - ${t.title||e}`,``,u];return l&&m.push(``,l),m.push(``),m.join(`
8
+ `)}function F(){let t=[],n=a(`claude-code`),o=m(e,n),c=h(e);t.push({path:`.mcp.json`,content:`${v({serverName:i,mcpEntry:r,configKey:`mcpServers`})}\n`}),t.push({path:`CLAUDE.md`,content:N()}),t.push({path:`AGENTS.md`,content:M(o)});for(let[e,n]of Object.entries(s))t.push({path:`.claude/commands/aikit-${e}.md`,content:D(e,n)});for(let[r,i]of Object.entries(e)){let e=O(r,c);if(i.variants){for(let[a,s]of Object.entries(i.variants)){let c=`${r}-${a}`;t.push({path:`.claude/agents/${c}.md`,content:P(c,{...i,description:s.description||i.description,identity:s.identity,bodyAddendum:s.bodyAddendum},e,o,n)})}continue}t.push({path:`.claude/agents/${r}.md`,content:P(r,i,e,o,n)})}return t}export{x as CLAUDE_FLOWS_SECTION,S as CLAUDE_ORCHESTRATOR_FLOW_ROUTING_SECTION,F as generateClaudeCode};
@@ -0,0 +1,7 @@
1
+ import{AGENTS as e}from"../definitions/agents.mjs";import{AGENT_BODIES as t}from"../definitions/bodies.mjs";import{HOOKS as n}from"../definitions/hooks.mjs";import{MCP_SERVER_ENTRY as r}from"../definitions/mcp.mjs";import{getPlatformPrimaryModelMap as i}from"../definitions/models.mjs";import{PLATFORM_HOOK_CAPABILITIES as a}from"../definitions/platform-capabilities.mjs";import{PROMPTS as o}from"../definitions/prompts.mjs";import{AIKIT_INSTALL_HINT_SECTION as s,PLATFORM_OUTPUT_RULES_SECTION as c,PROTOCOLS as l}from"../definitions/protocols.mjs";import{AIKIT_TOOLS as u,CLAUDE_CODE_TOOL_MAP as d,IDE_CAPABILITIES as f}from"../definitions/tools.mjs";import{buildAgentTable as p,buildCompactAgentTable as m,buildFlowSection as h,buildHooksSection as g,buildSkillsSection as _,lowerFirst as v}from"./_shared.mjs";const y=h({flowTool:`flow`,isLifecycleOwner:!0}),b=h({flowTool:`flow`,isLifecycleOwner:!1});function x(e){return e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).replace(/[^a-zA-Z0-9]+/g,`-`).replace(/^-+|-+$/g,``).toLowerCase()}function S(e){return`"${String(e).replace(/\\/g,`\\\\`).replace(/"/g,`\\"`)}"`}function C(e){let t=(f[e]||[]).flatMap(e=>d[e]||[]),n=u.map(e=>`mcp__aikit__${e}`);return[...new Set([...t,...n])].sort((e,t)=>e.localeCompare(t))}function w(e,t){let n=[];return n.push(`# aikit ${e}`),n.push(``),t.description&&(n.push(`> ${t.description}`),n.push(``)),n.push(t.content.trim()),n.push(``),n.join(`
2
+ `)}function T(e,n){let r=t[e];return typeof r==`function`?r(n):r||``}function E(e){let t=[];e.extraBody&&t.push(e.extraBody),e.sharedBase&&l[e.sharedBase]&&t.push(l[e.sharedBase]);for(let n of e.sharedProtocols||[])l[n]&&t.push(l[n]);return t}function D(){return[`# aikit — Claude Desktop Instructions`,``,"Detailed workspace instructions live in `AGENTS.md`.","MCP server config lives in `claude_desktop_config.json`.",``,c,``,s,``,g(n,a[`claude-desktop`]),``].join(`
3
+ `)}function O(e){return[`# aikit — Claude Desktop Agents`,``,c,``,s,``,`## MCP Server`,``,"Server name: `aikit`","Configured in `claude_desktop_config.json`.",``,`## Agents`,``,e,``,g(n,a[`claude-desktop`]),``].join(`
4
+ `)}function k(e,t,n,r,i){let a=C(t.toolRole),o=E(t),s=_(t.skills),c=e===`Orchestrator`?[y,b]:[b],l=[n,...o,t.bodyAddendum,s,...c].filter(Boolean).join(`
5
+
6
+ `).trim(),u=t.identity?`You are the **${e}**${t.identity}`:`You are the **${e}**, ${v(t.description)}.`,d=i?.[e],f=a.length>0?`tools: [${a.join(`, `)}]`:null;t.skills?.length>0&&`${t.skills.map(([e])=>e).join(`, `)}`;let p=[`---`,`name: ${x(e)}`,`description: ${S(t.description)}`,...d?[`model: ${S(d)}`]:[],...f?[f]:[],`---`,``,`# ${e} - ${t.title||e}`,``,u];return l&&p.push(``,l),p.push(``),p.join(`
7
+ `)}function A(){let t=[],n=i(`claude-desktop`),a=p(e,n),s=m(e);t.push({path:`claude_desktop_config.json`,content:`${JSON.stringify({mcpServers:{aikit:{command:r.command,args:r.args}}},null,2)}\n`}),t.push({path:`CLAUDE.md`,content:D()}),t.push({path:`AGENTS.md`,content:O(a)});for(let[e,n]of Object.entries(o))t.push({path:`.claude/commands/aikit-${e}.md`,content:w(e,n)});for(let[r,i]of Object.entries(e)){let e=T(r,s);if(i.variants){for(let[o,s]of Object.entries(i.variants)){let c=`${r}-${o}`;t.push({path:`.claude/agents/${c}.md`,content:k(c,{...i,description:s.description||i.description,identity:s.identity,bodyAddendum:s.bodyAddendum},e,a,n)})}continue}t.push({path:`.claude/agents/${r}.md`,content:k(r,i,e,a,n)})}return t}export{A as generateClaudeDesktop};
@@ -1,7 +1,7 @@
1
- import{AGENTS as e}from"../definitions/agents.mjs";import{AGENT_BODIES as t}from"../definitions/bodies.mjs";import{HOOKS as n}from"../definitions/hooks.mjs";import{MCP_SERVER_ENTRY as r,SERVER_NAME as i}from"../definitions/mcp.mjs";import{PROMPTS as a}from"../definitions/prompts.mjs";import{PROTOCOLS as o}from"../definitions/protocols.mjs";import{buildAgentTable as s,buildCompactAgentTable as c,buildFlowSection as l,buildHooksSection as u,buildMcpConfigJson as d,buildPromptSections as f,buildSkillsSection as p,lowerFirst as m}from"./_shared.mjs";const h=l({flowTool:`flow`,isLifecycleOwner:!0}),g=l({flowTool:`flow`,isLifecycleOwner:!1});function _(e,n){let r=t[e];return typeof r==`function`?r(n):r||``}function v(e){let t=[];e.extraBody&&t.push(e.extraBody),e.sharedBase&&o[e.sharedBase]&&t.push(o[e.sharedBase]);for(let n of e.sharedProtocols||[])o[n]&&t.push(o[n]);return t}function y(){let t=[];for(let[n,r]of Object.entries(e)){if(r.variants){for(let[e,i]of Object.entries(r.variants))t.push({name:`${n}-${e}`,description:i.description||r.description});continue}t.push({name:n,description:r.description})}return t}function b(e){return y().map(({name:t,description:n})=>`- \`${e}/${t}.md\` — ${n}`).join(`
2
- `)}function x(e,t,n){let r=v(t),i=p(t.skills),a=e===`Orchestrator`?h:g,o=[n,...r,t.bodyAddendum,i,a].filter(Boolean).join(`
1
+ import{AGENTS as e}from"../definitions/agents.mjs";import{AGENT_BODIES as t}from"../definitions/bodies.mjs";import{HOOKS as n}from"../definitions/hooks.mjs";import{MCP_SERVER_ENTRY as r,SERVER_NAME as i}from"../definitions/mcp.mjs";import{PLATFORM_HOOK_CAPABILITIES as a}from"../definitions/platform-capabilities.mjs";import{PROMPTS as o}from"../definitions/prompts.mjs";import{PROTOCOLS as s}from"../definitions/protocols.mjs";import{buildAgentTable as c,buildCompactAgentTable as l,buildFlowSection as u,buildHooksSection as d,buildMcpConfigJson as f,buildPromptSections as p,buildSkillsSection as m,lowerFirst as h}from"./_shared.mjs";const g=u({flowTool:`flow`,isLifecycleOwner:!0}),_=u({flowTool:`flow`,isLifecycleOwner:!1});function v(e,n){let r=t[e];return typeof r==`function`?r(n):r||``}function y(e){let t=[];e.extraBody&&t.push(e.extraBody),e.sharedBase&&s[e.sharedBase]&&t.push(s[e.sharedBase]);for(let n of e.sharedProtocols||[])s[n]&&t.push(s[n]);return t}function b(){let t=[];for(let[n,r]of Object.entries(e)){if(r.variants){for(let[e,i]of Object.entries(r.variants))t.push({name:`${n}-${e}`,description:i.description||r.description});continue}t.push({name:n,description:r.description})}return t}function x(e){return b().map(({name:t,description:n})=>`- \`${e}/${t}.md\` — ${n}`).join(`
2
+ `)}function S(e,t,n){let r=y(t),i=m(t.skills),a=e===`Orchestrator`?g:_,o=[n,...r,t.bodyAddendum,i,a].filter(Boolean).join(`
3
3
 
4
- `).trim();return[`# ${e} - ${t.title||e}`,``,`> ${t.description}`,``,t.identity?`You are the **${e}**${t.identity}`:`You are the **${e}**, ${m(t.description)}.`,...o?[``,o]:[],``].join(`
5
- `)}function S(){return[`# aikit — Gemini CLI Agents`,``,"This workspace keeps the root `GEMINI.md` intentionally small. Full agent instructions are split into per-agent files under `.gemini/agents/`.",``,`## MCP Server`,``,"Server name: `aikit`","Configure in `.gemini/settings.json` (already done if scaffold was deployed).",``,`## Agents`,``,s(e),``,`## Agent Files`,``,b(`.gemini/agents`),``,`## Prompts`,``,f(a),``,`## Session Protocol`,``,u(n),``].join(`
6
- `)}function C(){return[`# aikit — Gemini CLI Instructions`,``,"Detailed workspace instructions live in `AGENTS.md`.","Per-agent instructions are emitted under `.gemini/agents/`.","MCP server config lives in `.gemini/settings.json`.",``,"Start with `AGENTS.md`, then open the specific agent file you want to use.",``].join(`
7
- `)}function w(){let t=[{path:`.gemini/settings.json`,content:`${d({serverName:i,mcpEntry:r,configKey:`mcpServers`})}\n`},{path:`GEMINI.md`,content:C()},{path:`AGENTS.md`,content:S()}],n=c(e);for(let[r,i]of Object.entries(e)){let e=_(r,n);if(i.variants){for(let[n,a]of Object.entries(i.variants)){let o=`${r}-${n}`;t.push({path:`.gemini/agents/${o}.md`,content:x(o,{...i,description:a.description||i.description,identity:a.identity,bodyAddendum:a.bodyAddendum},e)})}continue}t.push({path:`.gemini/agents/${r}.md`,content:x(r,i,e)})}return t}export{w as generateGemini};
4
+ `).trim();return[`# ${e} - ${t.title||e}`,``,`> ${t.description}`,``,t.identity?`You are the **${e}**${t.identity}`:`You are the **${e}**, ${h(t.description)}.`,...o?[``,o]:[],``].join(`
5
+ `)}function C(){return[`# aikit — Gemini CLI Agents`,``,"This workspace keeps the root `GEMINI.md` intentionally small. Full agent instructions are split into per-agent files under `.gemini/agents/`.",``,`## MCP Server`,``,"Server name: `aikit`","Configure in `.gemini/settings.json` (already done if scaffold was deployed).",``,`## Agents`,``,c(e),``,`## Agent Files`,``,x(`.gemini/agents`),``,`## Prompts`,``,p(o),``,`## Session Protocol`,``,d(n,a.gemini),``].join(`
6
+ `)}function w(){return[`# aikit — Gemini CLI Instructions`,``,"Detailed workspace instructions live in `AGENTS.md`.","Per-agent instructions are emitted under `.gemini/agents/`.","MCP server config lives in `.gemini/settings.json`.",``,"Start with `AGENTS.md`, then open the specific agent file you want to use.",``].join(`
7
+ `)}function T(){let t=[{path:`.gemini/settings.json`,content:`${f({serverName:i,mcpEntry:r,configKey:`mcpServers`})}\n`},{path:`GEMINI.md`,content:w()},{path:`AGENTS.md`,content:C()}],n=l(e);for(let[r,i]of Object.entries(e)){let e=v(r,n);if(i.variants){for(let[n,a]of Object.entries(i.variants)){let o=`${r}-${n}`;t.push({path:`.gemini/agents/${o}.md`,content:S(o,{...i,description:a.description||i.description,identity:a.identity,bodyAddendum:a.bodyAddendum},e)})}continue}t.push({path:`.gemini/agents/${r}.md`,content:S(r,i,e)})}return t}export{T as generateGemini};
@@ -1,6 +1,6 @@
1
- import{AGENTS as e}from"../definitions/agents.mjs";import{AGENT_BODIES as t}from"../definitions/bodies.mjs";import{HOOKS as n}from"../definitions/hooks.mjs";import{PROMPTS as r}from"../definitions/prompts.mjs";import{PROTOCOLS as i}from"../definitions/protocols.mjs";import{buildAgentTable as a,buildCompactAgentTable as o,buildFlowSection as s,buildHooksSection as c,buildPromptSections as l,buildSkillsSection as u,lowerFirst as d}from"./_shared.mjs";const f=s({flowTool:`flow`,isLifecycleOwner:!0}),p=s({flowTool:`flow`,isLifecycleOwner:!1});function m(e,n){let r=t[e];return typeof r==`function`?r(n):r||``}function h(e){let t=[];e.extraBody&&t.push(e.extraBody),e.sharedBase&&i[e.sharedBase]&&t.push(i[e.sharedBase]);for(let n of e.sharedProtocols||[])i[n]&&t.push(i[n]);return t}function g(){let t=a(e),i=o(e),s=l(r),u=[];for(let[t,n]of Object.entries(e)){let e=m(t,i);if(n.variants){for(let[r,i]of Object.entries(n.variants)){let a=`${t}-${r}`;u.push(_(a,{...n,description:i.description||n.description,identity:i.identity,bodyAddendum:i.bodyAddendum},e))}continue}u.push(_(t,n,e))}return[`# AI Kit — Hermes Agent Instructions`,``,"This project uses **AI Kit** (`@vpxa/aikit`), a local-first MCP server that provides search,",`code analysis, persistent memory, context compression, and guided development flows.`,``,`The AI Kit MCP server is registered in your Hermes config and its 64 tools are available`,"as `mcp_aikit_*` tool calls in every conversation.",``,`## MCP Server`,``,"Server name: `aikit`","Configured via `hermes mcp add` (user-level). Tools are auto-discovered at session start.",``,`## Skills-First Rule`,``,`**Before starting ANY task, check available skills.** If a skill matches your task domain`,`— load it first. Skills contain domain-specific patterns, templates, and constraints.`,``,`## Available Tools (64)`,``,`AI Kit provides tools across the following categories:`,``,`| Category | Tools |`,`|----------|-------|`,"| **Search & Discovery** | `search`, `find`, `symbol`, `trace`, `lookup`, `scope_map`, `file_summary`, `dead_symbols` |","| **Code Analysis** | `analyze`, `blast_radius`, `audit`, `graph`, `health`, `check` |","| **Context Compression** | `file_summary`, `digest` |","| **Memory & Knowledge** | `knowledge`, `remember`, `read`, `update`, `forget`, `list`, `stash` |","| **FORGE Quality Gates** | `forge_classify`, `forge_ground`, `evidence_map`, `compliance_score` |","| **Development Workflows** | `flow`, `onboard`, `reindex`, `status`, `guide`, `config` |","| **Testing & Build** | `test_run`, `parse_output`, `check`, `eval` |","| **Code Manipulation** | `rename`, `codemod`, `data_transform`, `diff_parse`, `git_context`, `replay` |","| **Web & HTTP** | `web_search`, `web_fetch`, `http` |","| **Present & Visualize** | `present`, `signal`, `session_digest` |","| **Sandbox & Process** | `process`, `watch`, `workset`, `lane`, `queue`, `restore`, `delegate` |","| **Utilities** | `encode`, `regex_test`, `measure`, `changelog`, `schema_validate`, `env`, `time` |","| **Browser** | `browser` |",``,`## Important: Prefer AI Kit Tools Over Generic Shell Commands`,``,`When working in this project, use AI Kit MCP tools instead of generic alternatives:`,``,`| Instead of | Use AI Kit Tool | Why |`,`|-----------|----------------|-----|`,"| `grep` / `rg` | `mcp_aikit_search` or `mcp_aikit_find` | Hybrid search (vector + keyword + BM25) across all indexed content |","| `read_file` for understanding | `mcp_aikit_file_summary` | T1=structure, T2=structure+content — 10x fewer tokens than raw file reads |","| `cd` + `ls` | `mcp_aikit_analyze` | Structural analysis with tree views |","| Running tests in terminal | `mcp_aikit_test_run` | Structured test output — no shell needed |","| `tsc` / `biome` in terminal | `mcp_aikit_check` | Typecheck + lint combined |","| Web search | `mcp_aikit_web_search` | Fans out to multiple keyless providers |",``,`## Agents`,``,t,``,`## Agent Instructions`,``,u.join(`
2
- `),``,`## Prompts`,``,s,``,f,``,`## Session Protocol`,``,c(n),``].join(`
3
- `)}function _(e,t,n){let r=h(t),i=u(t.skills),a=e===`Orchestrator`?f:p,o=[n,...r,t.bodyAddendum,i,a].filter(Boolean).join(`
1
+ import{AGENTS as e}from"../definitions/agents.mjs";import{AGENT_BODIES as t}from"../definitions/bodies.mjs";import{HOOKS as n}from"../definitions/hooks.mjs";import{PLATFORM_HOOK_CAPABILITIES as r}from"../definitions/platform-capabilities.mjs";import{PROMPTS as i}from"../definitions/prompts.mjs";import{PROTOCOLS as a}from"../definitions/protocols.mjs";import{buildAgentTable as o,buildCompactAgentTable as s,buildFlowSection as c,buildHooksSection as l,buildPromptSections as u,buildSkillsSection as d,lowerFirst as f}from"./_shared.mjs";const p=c({flowTool:`flow`,isLifecycleOwner:!0}),m=c({flowTool:`flow`,isLifecycleOwner:!1});function h(e,n){let r=t[e];return typeof r==`function`?r(n):r||``}function g(e){let t=[];e.extraBody&&t.push(e.extraBody),e.sharedBase&&a[e.sharedBase]&&t.push(a[e.sharedBase]);for(let n of e.sharedProtocols||[])a[n]&&t.push(a[n]);return t}function _(){let t=o(e),a=s(e),c=u(i),d=[];for(let[t,n]of Object.entries(e)){let e=h(t,a);if(n.variants){for(let[r,i]of Object.entries(n.variants)){let a=`${t}-${r}`;d.push(v(a,{...n,description:i.description||n.description,identity:i.identity,bodyAddendum:i.bodyAddendum},e))}continue}d.push(v(t,n,e))}return[`# AI Kit — Hermes Agent Instructions`,``,"This project uses **AI Kit** (`@vpxa/aikit`), a local-first MCP server that provides search,",`code analysis, persistent memory, context compression, and guided development flows.`,``,`The AI Kit MCP server is registered in your Hermes config and its 64 tools are available`,"as `mcp_aikit_*` tool calls in every conversation.",``,`## MCP Server`,``,"Server name: `aikit`","Configured via `hermes mcp add` (user-level). Tools are auto-discovered at session start.",``,`## Skills-First Rule`,``,`**Before starting ANY task, check available skills.** If a skill matches your task domain`,`— load it first. Skills contain domain-specific patterns, templates, and constraints.`,``,`## Available Tools (64)`,``,`AI Kit provides tools across the following categories:`,``,`| Category | Tools |`,`|----------|-------|`,"| **Search & Discovery** | `search`, `find`, `symbol`, `trace`, `lookup`, `scope_map`, `file_summary`, `dead_symbols` |","| **Code Analysis** | `analyze`, `blast_radius`, `audit`, `graph`, `health`, `check` |","| **Context Compression** | `file_summary`, `digest` |","| **Memory & Knowledge** | `knowledge`, `remember`, `read`, `update`, `forget`, `list`, `stash` |","| **FORGE Quality Gates** | `forge_classify`, `forge_ground`, `evidence_map`, `compliance_score` |","| **Development Workflows** | `flow`, `onboard`, `reindex`, `status`, `guide`, `config` |","| **Testing & Build** | `test_run`, `parse_output`, `check`, `eval` |","| **Code Manipulation** | `rename`, `codemod`, `data_transform`, `diff_parse`, `git_context`, `replay` |","| **Web & HTTP** | `web_search`, `web_fetch`, `http` |","| **Present & Visualize** | `present`, `signal`, `session_digest` |","| **Sandbox & Process** | `process`, `watch`, `workset`, `lane`, `queue`, `restore`, `delegate` |","| **Utilities** | `encode`, `regex_test`, `measure`, `changelog`, `schema_validate`, `env`, `time` |","| **Browser** | `browser` |",``,`## Important: Prefer AI Kit Tools Over Generic Shell Commands`,``,`When working in this project, use AI Kit MCP tools instead of generic alternatives:`,``,`| Instead of | Use AI Kit Tool | Why |`,`|-----------|----------------|-----|`,"| `grep` / `rg` | `mcp_aikit_search` or `mcp_aikit_find` | Hybrid search (vector + keyword + BM25) across all indexed content |","| `read_file` for understanding | `mcp_aikit_file_summary` | T1=structure, T2=structure+content — 10x fewer tokens than raw file reads |","| `cd` + `ls` | `mcp_aikit_analyze` | Structural analysis with tree views |","| Running tests in terminal | `mcp_aikit_test_run` | Structured test output — no shell needed |","| `tsc` / `biome` in terminal | `mcp_aikit_check` | Typecheck + lint combined |","| Web search | `mcp_aikit_web_search` | Fans out to multiple keyless providers |",``,`## Agents`,``,t,``,`## Agent Instructions`,``,d.join(`
2
+ `),``,`## Prompts`,``,c,``,p,``,`## Session Protocol`,``,l(n,r.hermes),``].join(`
3
+ `)}function v(e,t,n){let r=g(t),i=d(t.skills),a=e===`Orchestrator`?p:m,o=[n,...r,t.bodyAddendum,i,a].filter(Boolean).join(`
4
4
 
5
- `).trim();return[`## ${e} - ${t.title||e}`,``,`> ${t.description}`,``,t.identity?`You are the **${e}**${t.identity}`:`You are the **${e}**, ${d(t.description)}.`,...o?[``,o]:[],``].join(`
6
- `)}function v(){return[{path:`AGENTS.md`,content:g()}]}export{v as generateHermes};
5
+ `).trim();return[`## ${e} - ${t.title||e}`,``,`> ${t.description}`,``,t.identity?`You are the **${e}**${t.identity}`:`You are the **${e}**, ${f(t.description)}.`,...o?[``,o]:[],``].join(`
6
+ `)}function y(){return[{path:`AGENTS.md`,content:_()}]}export{y as generateHermes};
@@ -1 +1 @@
1
- import{EXEC_HOOKS as e,HOOK_EVENTS as t,HOOK_TOOL_MATCHERS as n,SUPPORTED_PLATFORMS as r}from"../definitions/exec-hooks.mjs";const i={PreCompact:3e3,PostToolUse:3e3},a={copilot:`hooks.json`,copilotCli:`hooks.json`,hermes:`hooks.json`},o=r;function s(e){if(!o.includes(e))throw Error(`Unknown platform: "${e}". Supported: ${o.join(`, `)}. Add it to SUPPORTED_PLATFORMS in exec-hooks.mjs first, then add entries to HOOK_EVENTS and HOOK_TOOL_MATCHERS. Add FILE_NAMES in generateHooks if file-producing.`);for(let[n,r]of Object.entries(t))if(!(e in r))throw Error(`Platform "${e}" is missing from HOOK_EVENTS.${n}. Add a "${e}" key to HOOK_EVENTS.${n} in exec-hooks.mjs.`);for(let[t,r]of Object.entries(n))if(!(e in r))throw Error(`Platform "${e}" is missing from HOOK_TOOL_MATCHERS.${t}. Add a "${e}" key to HOOK_TOOL_MATCHERS.${t} in exec-hooks.mjs.`)}function c(e,t){return(e.matcher||[]).flatMap(e=>{let r=n[e];if(!r)throw Error(`Unknown hook matcher: ${e}`);return r[t]||[]})}function l(e,t,n,r){let a=`${n}/${e.script}`;if(r===`claude`){let t=c(e,r);return{matcher:t.length>0?t.join(`|`):``,hooks:[{type:`command`,command:`node ${JSON.stringify(a)}`}]}}return r===`copilot`?{event:t,steps:[{type:`command`,command:`node`,args:[a],timeout:i[e.event]||5e3}]}:{command:`node`,args:[a]}}function u(n,r){s(n);let i={};for(let a of Object.values(e)){let e=t[a.event]?.[n];if(!e){console.warn(`[aikit] Unsupported hook event ${a.event} for ${n} — skipping`);continue}i[e]||=[],i[e].push(l(a,e,r,n))}return{hooks:i}}function d(n,r){if(s(n),n===`claude`)return[];if(n===`copilot`){let i=Object.values(e).flatMap(e=>{let i=t[e.event]?.[n];return i?l(e,i,r,n):(console.warn(`[aikit] Unsupported hook event ${e.event} for ${n} — skipping`),[])});return[{path:a[n],content:JSON.stringify({hooks:i},null,2)}]}if(!(n in a))throw Error(`Platform "${n}" is missing from FILE_NAMES. Add "${n}: '<filename>'" to FILE_NAMES in adapters/hooks.mjs.`);let i={};for(let a of Object.values(e)){let e=t[a.event]?.[n];if(!e){console.warn(`[aikit] Unsupported hook event ${a.event} for ${n} — skipping`);continue}i[e]||=[],i[e].push(l(a,e,r,n))}return[{path:a[n],content:JSON.stringify({hooks:i},null,2)}]}function f(){return[`_runtime.mjs`,...Object.values(e).map(e=>e.script)]}export{u as buildHooksBlock,d as generateHooks,f as getHookScriptFiles};
1
+ import{EXEC_HOOKS as e,HOOK_EVENTS as t,HOOK_TOOL_MATCHERS as n,SUPPORTED_PLATFORMS as r}from"../definitions/exec-hooks.mjs";const i={PreCompact:3e3,PostToolUse:3e3},a={copilot:`hooks.json`,copilotCli:`hooks.json`,hermes:`hooks.json`},o=r;function s(e){if(!o.includes(e))throw Error(`Unknown platform: "${e}". Supported: ${o.join(`, `)}. Add it to SUPPORTED_PLATFORMS in exec-hooks.mjs first, then add entries to HOOK_EVENTS and HOOK_TOOL_MATCHERS. Add FILE_NAMES in generateHooks if file-producing.`);for(let[n,r]of Object.entries(t))if(!(e in r))throw Error(`Platform "${e}" is missing from HOOK_EVENTS.${n}. Add a "${e}" key to HOOK_EVENTS.${n} in exec-hooks.mjs.`);for(let[t,r]of Object.entries(n))if(!(e in r))throw Error(`Platform "${e}" is missing from HOOK_TOOL_MATCHERS.${t}. Add a "${e}" key to HOOK_TOOL_MATCHERS.${t} in exec-hooks.mjs.`)}function c(e,t){return(e.matcher||[]).flatMap(e=>{let r=n[e];if(!r)throw Error(`Unknown hook matcher: ${e}`);return r[t]||[]})}function l(e,t,n,r){let a=`${n}/${e.script}`;if(r===`claude`){let t=c(e,r);return{matcher:t.length>0?t.join(`|`):``,hooks:[{type:`command`,command:`node ${JSON.stringify(a)}`}]}}return r===`copilot`?{event:t,steps:[{type:`command`,command:`node`,args:[a],timeout:i[e.event]||5e3}]}:{command:`node`,args:[a]}}function u(n,r){s(n);let i={};for(let a of Object.values(e)){let e=t[a.event]?.[n];if(!e){console.warn(`[aikit] Unsupported hook event ${a.event} for ${n} — skipping`);continue}i[e]||=[],i[e].push(l(a,e,r,n))}return{hooks:i}}function d(n,r){if(s(n),n===`claude`)return[];if(n===`copilot`){let i=Object.values(e).flatMap(e=>{let i=t[e.event]?.[n];return i?l(e,i,r,n):(console.warn(`[aikit] Unsupported hook event ${e.event} for ${n} — skipping`),[])});return[{path:a[n],content:JSON.stringify({hooks:i},null,2)}]}if(!(n in a))throw Error(`Platform "${n}" is missing from FILE_NAMES. Add "${n}: '<filename>'" to FILE_NAMES in adapters/hooks.mjs.`);let i={};for(let a of Object.values(e)){let e=t[a.event]?.[n];if(!e){console.warn(`[aikit] Unsupported hook event ${a.event} for ${n} — skipping`);continue}i[e]||=[],i[e].push(l(a,e,r,n))}return[{path:a[n],content:JSON.stringify({hooks:i},null,2)}]}function f(){return[`_runtime.mjs`,...Object.values(e).map(e=>e.script)]}function p(){let t={PostToolUse:`tool:after`,SessionStart:`session:start`,Stop:`server:stop`},n={fileRead:[`read_file`,`readFile`,`Read`,`grep_search`,`semantic_search`],fileWrite:[`write_file`,`patch`,`editFiles`,`Edit`,`Write`,`MultiEdit`],fileSearch:[`search_files`,`grep_search`,`semantic_search`,`find`,`Bash`,`mcp_aikit_search`,`mcp_aikit_find`]};return Object.values(e).map(e=>{let r=t[e.event]||e.event.toLowerCase().replace(/([a-z])([A-Z])/g,`$1:$2`).replace(/^./,e=>e.toLowerCase()),i=(e.matcher||[]).flatMap(e=>n[e]||[]);return{id:`scaffold-${e.id}`,eventType:r,policy:`async`,name:e.id,toolFilter:i.length>0?i:void 0,description:e.description,llmBenefit:e.llmBenefit,category:e.category,failurePolicy:e.failurePolicy,executionModel:e.executionModel}})}export{u as buildHooksBlock,p as buildServerHookConfig,d as generateHooks,f as getHookScriptFiles};
@@ -1,8 +1,8 @@
1
- import{AGENTS as e}from"../definitions/agents.mjs";import{AGENT_BODIES as t}from"../definitions/bodies.mjs";import{HOOKS as n}from"../definitions/hooks.mjs";import{MCP_SERVER_ENTRY as r,SERVER_NAME as i}from"../definitions/mcp.mjs";import{PROMPTS as a}from"../definitions/prompts.mjs";import{PROTOCOLS as o}from"../definitions/protocols.mjs";import{buildAgentTable as s,buildCompactAgentTable as c,buildFlowSection as l,buildHooksSection as u,buildPromptSections as d,buildSkillsSection as f,lowerFirst as p}from"./_shared.mjs";const m=l({flowTool:`flow`,isLifecycleOwner:!0}),h=l({flowTool:`flow`,isLifecycleOwner:!1});function g(e,n){let r=t[e];return typeof r==`function`?r(n):r||``}function _(e){let t=[];e.extraBody&&t.push(e.extraBody),e.sharedBase&&o[e.sharedBase]&&t.push(o[e.sharedBase]);for(let n of e.sharedProtocols||[])o[n]&&t.push(o[n]);return t}function v(){let t=[];for(let[n,r]of Object.entries(e)){if(r.variants){for(let[e,i]of Object.entries(r.variants))t.push({name:`${n}-${e}`,description:i.description||r.description});continue}t.push({name:n,description:r.description})}return t}function y(e){return v().map(({name:t,description:n})=>`- \`${e}/${t}.md\` — ${n}`).join(`
2
- `)}const b={orchestrator:{edit:`allow`,bash:`allow`},planner:{edit:`allow`,bash:`allow`},codeAgent:{edit:`allow`,bash:`allow`},refactor:{edit:`allow`,bash:`allow`},debugger:{edit:`allow`,bash:`allow`},security:{edit:`allow`,bash:`allow`},documenter:{edit:`allow`,bash:`deny`},explorer:{edit:`deny`,bash:`deny`},researcher:{edit:`deny`,bash:`deny`},reviewer:{edit:`deny`,bash:`deny`}};function x(e){let t=e.category===`orchestration`&&e.title===`The Master Conductor`?`primary`:`subagent`,n=b[e.toolRole]||{edit:`deny`,bash:`deny`},r=[`---`,`description: ${e.description}`,`mode: ${t}`,`permission:`];for(let[e,t]of Object.entries(n))r.push(` ${e}: ${t}`);return r.push(`---`),r.join(`
3
- `)}function S(e,t,n){let r=_(t),i=f(t.skills),a=e===`Orchestrator`?m:h,o=[n,...r,t.bodyAddendum,i,a].filter(Boolean).join(`
1
+ import{AGENTS as e}from"../definitions/agents.mjs";import{AGENT_BODIES as t}from"../definitions/bodies.mjs";import{HOOKS as n}from"../definitions/hooks.mjs";import{MCP_SERVER_ENTRY as r,SERVER_NAME as i}from"../definitions/mcp.mjs";import{PLATFORM_HOOK_CAPABILITIES as a}from"../definitions/platform-capabilities.mjs";import{PROMPTS as o}from"../definitions/prompts.mjs";import{PROTOCOLS as s}from"../definitions/protocols.mjs";import{buildAgentTable as c,buildCompactAgentTable as l,buildFlowSection as u,buildHooksSection as d,buildPromptSections as f,buildSkillsSection as p,lowerFirst as m}from"./_shared.mjs";const h=u({flowTool:`flow`,isLifecycleOwner:!0}),g=u({flowTool:`flow`,isLifecycleOwner:!1});function _(e,n){let r=t[e];return typeof r==`function`?r(n):r||``}function v(e){let t=[];e.extraBody&&t.push(e.extraBody),e.sharedBase&&s[e.sharedBase]&&t.push(s[e.sharedBase]);for(let n of e.sharedProtocols||[])s[n]&&t.push(s[n]);return t}function y(){let t=[];for(let[n,r]of Object.entries(e)){if(r.variants){for(let[e,i]of Object.entries(r.variants))t.push({name:`${n}-${e}`,description:i.description||r.description});continue}t.push({name:n,description:r.description})}return t}function b(e){return y().map(({name:t,description:n})=>`- \`${e}/${t}.md\` — ${n}`).join(`
2
+ `)}const x={orchestrator:{edit:`allow`,bash:`allow`},planner:{edit:`allow`,bash:`allow`},codeAgent:{edit:`allow`,bash:`allow`},refactor:{edit:`allow`,bash:`allow`},debugger:{edit:`allow`,bash:`allow`},security:{edit:`allow`,bash:`allow`},documenter:{edit:`allow`,bash:`deny`},explorer:{edit:`deny`,bash:`deny`},researcher:{edit:`deny`,bash:`deny`},reviewer:{edit:`deny`,bash:`deny`}};function S(e){let t=e.category===`orchestration`&&e.title===`The Master Conductor`?`primary`:`subagent`,n=x[e.toolRole]||{edit:`deny`,bash:`deny`},r=[`---`,`description: ${e.description}`,`mode: ${t}`,`permission:`];for(let[e,t]of Object.entries(n))r.push(` ${e}: ${t}`);return r.push(`---`),r.join(`
3
+ `)}function C(e,t,n){let r=v(t),i=p(t.skills),a=e===`Orchestrator`?h:g,o=[n,...r,t.bodyAddendum,i,a].filter(Boolean).join(`
4
4
 
5
- `).trim(),s=[`# ${e} - ${t.title||e}`,``,`> ${t.description}`,``,t.identity?`You are the **${e}**${t.identity}`:`You are the **${e}**, ${p(t.description)}.`,...o?[``,o]:[],``].join(`
6
- `);return`${x(t)}\n\n${s}`}function C(){return[`# aikit — OpenCode Agents`,``,"This workspace keeps the root `OPENCODE.md` intentionally small. Full agent instructions are split into per-agent files under `.opencode/agents/`.",``,`## MCP Server`,``,"Server name: `aikit`","Configure in `.opencode/opencode.json` (already done if scaffold was deployed).",``,`## Agents`,``,s(e),``,`## Agent Files`,``,y(`.opencode/agents`),``,`## Prompts`,``,d(a),``,`## Session Protocol`,``,u(n),``].join(`
7
- `)}function w(){return[`# aikit — OpenCode Instructions`,``,"Detailed workspace instructions live in `OPENCODE.md`.","Per-agent instructions are emitted under `.opencode/agents/`.","MCP server config lives in `.opencode/opencode.json`.",``,"Start with `OPENCODE.md`, then open the specific agent file you want to use.",``].join(`
8
- `)}function T(e,t){let{type:n,...r}=t;return JSON.stringify({mcp:{[e]:{type:`local`,command:[r.command,...r.args]}}},null,2)}function E(){let t=[{path:`.opencode/opencode.json`,content:`${T(i,r)}\n`},{path:`OPENCODE.md`,content:w()},{path:`AGENTS.md`,content:C()}],n=c(e);for(let[r,i]of Object.entries(e)){let e=g(r,n);if(i.variants){for(let[n,a]of Object.entries(i.variants)){let o=`${r}-${n}`;t.push({path:`.opencode/agents/${o}.md`,content:S(o,{...i,description:a.description||i.description,identity:a.identity,bodyAddendum:a.bodyAddendum},e)})}continue}t.push({path:`.opencode/agents/${r}.md`,content:S(r,i,e)})}return t}export{E as generateOpencode};
5
+ `).trim(),s=[`# ${e} - ${t.title||e}`,``,`> ${t.description}`,``,t.identity?`You are the **${e}**${t.identity}`:`You are the **${e}**, ${m(t.description)}.`,...o?[``,o]:[],``].join(`
6
+ `);return`${S(t)}\n\n${s}`}function w(){return[`# aikit — OpenCode Agents`,``,"This workspace keeps the root `OPENCODE.md` intentionally small. Full agent instructions are split into per-agent files under `.opencode/agents/`.",``,`## MCP Server`,``,"Server name: `aikit`","Configure in `.opencode/opencode.json` (already done if scaffold was deployed).",``,`## Agents`,``,c(e),``,`## Agent Files`,``,b(`.opencode/agents`),``,`## Prompts`,``,f(o),``,`## Session Protocol`,``,d(n,a.opencode),``].join(`
7
+ `)}function T(){return[`# aikit — OpenCode Instructions`,``,"Detailed workspace instructions live in `OPENCODE.md`.","Per-agent instructions are emitted under `.opencode/agents/`.","MCP server config lives in `.opencode/opencode.json`.",``,"Start with `OPENCODE.md`, then open the specific agent file you want to use.",``].join(`
8
+ `)}function E(e,t){let{type:n,...r}=t;return JSON.stringify({mcp:{[e]:{type:`local`,command:[r.command,...r.args]}}},null,2)}function D(){let t=[{path:`.opencode/opencode.json`,content:`${E(i,r)}\n`},{path:`OPENCODE.md`,content:T()},{path:`AGENTS.md`,content:w()}],n=l(e);for(let[r,i]of Object.entries(e)){let e=_(r,n);if(i.variants){for(let[n,a]of Object.entries(i.variants)){let o=`${r}-${n}`;t.push({path:`.opencode/agents/${o}.md`,content:C(o,{...i,description:a.description||i.description,identity:a.identity,bodyAddendum:a.bodyAddendum},e)})}continue}t.push({path:`.opencode/agents/${r}.md`,content:C(r,i,e)})}return t}export{D as generateOpencode};
@@ -1 +1 @@
1
- const e=[`copilot`,`claude`,`copilotCli`,`hermes`],t={SessionStart:{copilot:`SessionStart`,claude:`SessionStart`,copilotCli:`sessionStart`,hermes:`SessionStart`},PreToolUse:{copilot:`PreToolUse`,claude:`PreToolUse`,copilotCli:`preToolUse`,hermes:`PreToolUse`},PostToolUse:{copilot:`PostToolUse`,claude:`PostToolUse`,copilotCli:`postToolUse`,hermes:`PostToolUse`},SubagentStart:{copilot:`SubagentStart`,claude:`SubagentStart`,copilotCli:`subagentStart`,hermes:`SubagentStart`},PreCompact:{copilot:`PreCompact`,claude:`PreCompact`,copilotCli:`preCompact`,hermes:`PreCompact`},Stop:{copilot:`Stop`,claude:`Stop`,copilotCli:`stop`,hermes:`Stop`}},n={fileRead:{copilot:[`read_file`,`readFile`],claude:[`Read`],copilotCli:[`read_file`],hermes:[`read_file`]},fileWrite:{copilot:[`editFiles`,`replace_string_in_file`,`create_file`],claude:[`Edit`,`Write`,`MultiEdit`],copilotCli:[`editFiles`,`replace_string_in_file`],hermes:[`write_file`,`patch`]},fileSearch:{copilot:[`grep_search`,`semantic_search`,`find`],claude:[`Bash`],copilotCli:[`grep_search`],hermes:[`search_files`]}},r={"privacy-guard":{id:`privacy-guard`,event:`PreToolUse`,category:`guard`,description:`Deny reads of secret-bearing files: .env, .pem, .key, .ssh/*, credentials, tokens, .netrc.`,script:`privacy-guard.mjs`,matcher:[`fileRead`],outputBudgetLines:0,scope:`user`},"scout-guard":{id:`scout-guard`,event:`PreToolUse`,category:`guard`,description:`Deny reads inside generated/dependency directories: node_modules/, dist/, .git/objects/, vendor/, build/.`,script:`scout-guard.mjs`,matcher:[`fileRead`,`fileSearch`],outputBudgetLines:0,scope:`user`},"freshness-signal":{id:`freshness-signal`,event:`SessionStart`,category:`signal`,description:`Check workspace state freshness at session start: onboard staleness, active flow, scaffold drift.`,script:`freshness-signal.mjs`,outputBudgetLines:5,scope:`user`},"scope-guard":{id:`scope-guard`,event:`PostToolUse`,category:`signal`,description:`After file writes, detect edit drift: files changed outside flow scope, too many files, scaffold source/dist mismatch.`,script:`scope-guard.mjs`,matcher:[`fileWrite`],outputBudgetLines:5,scope:`user`}};function i(r){let i=[{name:`HOOK_EVENTS`,entries:Object.values(t)},{name:`HOOK_TOOL_MATCHERS`,entries:Object.values(n)}];for(let t of e){for(let e of i)for(let n of e.entries)if(!(t in n))throw Error(`Registration drift: platform "${t}" is missing from ${e.name} (entry has keys: ${Object.keys(n).join(`, `)}). Add a "${t}" key to all entries in ${e.name} in exec-hooks.mjs.`);if(r){for(let[e,n]of Object.entries(r))if(!(t in n))throw Error(`Registration drift: platform "${t}" is missing from ${e} (has keys: ${Object.keys(n).join(`, `)}). Add "${t}: '...'" to ${e}.`)}}}export{r as EXEC_HOOKS,t as HOOK_EVENTS,n as HOOK_TOOL_MATCHERS,e as SUPPORTED_PLATFORMS,i as validateAllPlatformRegistries};
1
+ const e=[`copilot`,`claude`,`copilotCli`,`hermes`],t={SessionStart:{copilot:`SessionStart`,claude:`SessionStart`,copilotCli:`sessionStart`,hermes:`SessionStart`},PreToolUse:{copilot:`PreToolUse`,claude:`PreToolUse`,copilotCli:`preToolUse`,hermes:`PreToolUse`},PostToolUse:{copilot:`PostToolUse`,claude:`PostToolUse`,copilotCli:`postToolUse`,hermes:`PostToolUse`},SubagentStart:{copilot:`SubagentStart`,claude:`SubagentStart`,copilotCli:`subagentStart`,hermes:`SubagentStart`},PreCompact:{copilot:`PreCompact`,claude:`PreCompact`,copilotCli:`preCompact`,hermes:`PreCompact`},Stop:{copilot:`Stop`,claude:`Stop`,copilotCli:`stop`,hermes:`Stop`}},n={fileRead:{copilot:[`read_file`,`readFile`],claude:[`Read`],copilotCli:[`read_file`],hermes:[`read_file`]},fileWrite:{copilot:[`editFiles`,`replace_string_in_file`,`create_file`],claude:[`Edit`,`Write`,`MultiEdit`],copilotCli:[`editFiles`,`replace_string_in_file`],hermes:[`write_file`,`patch`]},fileSearch:{copilot:[`grep_search`,`semantic_search`,`find`],claude:[`Bash`],copilotCli:[`grep_search`],hermes:[`search_files`]}},r={"privacy-guard":{id:`privacy-guard`,event:`PreToolUse`,category:`guard`,description:`Deny reads of secret-bearing files: .env, .pem, .key, .ssh/*, credentials, tokens, .netrc.`,llmBenefit:`Prevents accidental leakage of API keys, tokens, and credentials into conversation context.`,script:`privacy-guard.mjs`,matcher:[`fileRead`],outputBudgetLines:0,executionModel:`child-process`,scope:`user`,failurePolicy:`deny-closed`,supportedPlatforms:[`copilot`,`claude`,`copilotCli`,`hermes`],unsupportedBehavior:`Reject via agent instruction — no native hook runtime available`,evidenceRequirements:`Hook script tested against known secret patterns`,rollbackBehavior:`Remove from settings.json hooks block and delete script file`},"scout-guard":{id:`scout-guard`,event:`PreToolUse`,category:`guard`,description:`Deny reads inside generated/dependency directories: node_modules/, dist/, .git/objects/, vendor/, build/.`,llmBenefit:`Keeps context clean by preventing reads of irrelevant generated or vendored files.`,script:`scout-guard.mjs`,matcher:[`fileRead`,`fileSearch`],outputBudgetLines:0,executionModel:`child-process`,scope:`user`,failurePolicy:`deny-closed`,supportedPlatforms:[`copilot`,`claude`,`copilotCli`,`hermes`],unsupportedBehavior:`Reject via agent instruction — no native hook runtime available`,evidenceRequirements:`Hook script tested against known generated directory patterns`,rollbackBehavior:`Remove from settings.json hooks block and delete script file`},"freshness-signal":{id:`freshness-signal`,event:`SessionStart`,category:`signal`,description:`Check workspace state freshness at session start: onboard staleness, active flow, scaffold drift.`,llmBenefit:`Avoids working with stale onboard data or drifting scaffold state.`,script:`freshness-signal.mjs`,outputBudgetLines:5,executionModel:`child-process`,scope:`user`,silentWhenHealthy:!0,failurePolicy:`allow-open`,matcher:[],supportedPlatforms:[`copilot`,`claude`,`copilotCli`,`hermes`],unsupportedBehavior:`Skip — no native hook runtime on this platform`,evidenceRequirements:`None (signal-only, no enforcement)`,rollbackBehavior:`Remove from settings.json hooks block`},"scope-guard":{id:`scope-guard`,event:`PostToolUse`,category:`signal`,description:`After file writes, detect edit drift: files changed outside flow scope, too many files, scaffold source/dist mismatch.`,llmBenefit:`Prevents accidental scope creep, over-editing, and scaffold drift during a session.`,script:`scope-guard.mjs`,matcher:[`fileWrite`],outputBudgetLines:5,executionModel:`child-process`,scope:`user`,silentWhenHealthy:!0,failurePolicy:`allow-open`,supportedPlatforms:[`copilot`,`claude`,`copilotCli`,`hermes`],unsupportedBehavior:`Skip — no native hook runtime on this platform`,evidenceRequirements:`None (signal-only, no enforcement)`,rollbackBehavior:`Remove from settings.json hooks block`}},i=[`id`,`event`,`category`,`script`,`description`],a=[`matcher`,`llmBenefit`,`executionModel`,`scope`,`failurePolicy`,`outputBudgetLines`,`supportedPlatforms`,`unsupportedBehavior`],o=[`evidenceRequirements`,`rollbackBehavior`],s=[`silentWhenHealthy`];function c(){let e=new Set(Object.keys(t)),n=[`child-process`,`eventbus-subscriber`],c=[`deny-closed`,`allow-open`];for(let[t,l]of Object.entries(r)){for(let e of i){if(!(e in l)||l[e]===void 0||l[e]===null)throw Error(`EXEC_HOOKS["${t}"] is missing or null Tier 1 field "${e}". Add it to the "${t}" entry in exec-hooks.mjs.`);if(typeof l[e]==`string`&&l[e].trim()===``)throw Error(`EXEC_HOOKS["${t}"] has empty string for Tier 1 field "${e}". Provide a non-empty value.`)}for(let e of a)(!(e in l)||l[e]===void 0||l[e]===null)&&console.warn(`EXEC_HOOKS["${t}"] is missing Tier 2 field "${e}". Add it when the field values are actionable.`);if(l.category===`guard`)for(let e of o)(!(e in l)||l[e]===void 0||l[e]===null)&&console.warn(`EXEC_HOOKS["${t}"] (guard) is missing guard field "${e}". Add it when guard lifecycle tooling exists.`);if(l.category===`signal`)for(let e of s)(!(e in l)||l[e]===void 0||l[e]===null)&&console.warn(`EXEC_HOOKS["${t}"] (signal) is missing signal field "${e}". Add it when signal lifecycle tooling exists.`);if(l.id!==t)throw Error(`EXEC_HOOKS["${t}"] has id="${l.id}" which doesn't match its object key. Set id to "${t}".`);if(!e.has(l.event))throw Error(`EXEC_HOOKS["${t}"] has unrecognized event "${l.event}". Valid: ${[...e].join(`, `)}.`);if(![`guard`,`signal`].includes(l.category))throw Error(`EXEC_HOOKS["${t}"] has invalid category "${l.category}". Must be "guard" or "signal".`);[`user`,`workspace`].includes(l.scope)||console.warn(`EXEC_HOOKS["${t}"] has invalid scope "${l.scope}". Must be "user" or "workspace".`),l.executionModel&&!n.includes(l.executionModel)&&console.warn(`EXEC_HOOKS["${t}"] has unrecognized executionModel "${l.executionModel}". Valid: ${n.join(`, `)}.`),l.failurePolicy&&!c.includes(l.failurePolicy)&&console.warn(`EXEC_HOOKS["${t}"] has unrecognized failurePolicy "${l.failurePolicy}". Valid: ${c.join(`, `)}.`)}}function l(r){let i=[{name:`HOOK_EVENTS`,entries:Object.values(t)},{name:`HOOK_TOOL_MATCHERS`,entries:Object.values(n)}];for(let t of e){for(let e of i)for(let n of e.entries)if(!(t in n))throw Error(`Registration drift: platform "${t}" is missing from ${e.name} (entry has keys: ${Object.keys(n).join(`, `)}). Add a "${t}" key to all entries in ${e.name} in exec-hooks.mjs.`);if(r){for(let[e,n]of Object.entries(r))if(!(t in n))throw Error(`Registration drift: platform "${t}" is missing from ${e} (has keys: ${Object.keys(n).join(`, `)}). Add "${t}: '...'" to ${e}.`)}}}function u(e){let t=[];if(!e||typeof e!=`object`)return t.push(`Generated hook must be a non-null object`),t;for(let n of[`id`,`event`,`category`,`description`])(!e[n]||typeof e[n]!=`string`)&&t.push(`Generated hook missing or invalid "${n}" (must be a non-empty string)`);e.category&&![`guard`,`signal`].includes(e.category)&&t.push(`Generated hook has invalid category "${e.category}". Must be "guard" or "signal".`);let n=[`candidate`,`evaluated`,`promoted`,`rejected`,`disabled`];return e.promotionState&&!n.includes(e.promotionState)&&t.push(`Generated hook has invalid promotionState "${e.promotionState}". Valid: ${n.join(`, `)}.`),e.confidence!==void 0&&(typeof e.confidence!=`number`||e.confidence<0||e.confidence>1)&&t.push(`Generated hook confidence must be a number between 0 and 1, got "${e.confidence}"`),e.originToolNames!==void 0&&!Array.isArray(e.originToolNames)&&t.push(`Generated hook originToolNames must be an array of strings`),e.promotionState===`promoted`&&!e.createdAt&&t.push(`Generated hook promoted but missing createdAt timestamp`),t}export{r as EXEC_HOOKS,t as HOOK_EVENTS,n as HOOK_TOOL_MATCHERS,e as SUPPORTED_PLATFORMS,l as validateAllPlatformRegistries,u as validateGeneratedHookDef,c as validateHookDefinitions};
@@ -0,0 +1 @@
1
+ const e=[`SessionStart`,`PreToolUse`,`PostToolUse`,`PreCommit`,`SessionEnd`],t=[`native`,`eventbus`,`middleware`,`none`],n=[`full`,`partial`,`eventbus`,`middleware`,`none`],r={"claude-code":{SessionStart:`native`,PreToolUse:`native`,PostToolUse:`native`,PreCommit:`native`,SessionEnd:`native`,overall:`full`,label:`Claude Code`},"claude-desktop":{SessionStart:`eventbus`,PreToolUse:`none`,PostToolUse:`eventbus`,PreCommit:`none`,SessionEnd:`eventbus`,overall:`eventbus`,label:`Claude Desktop`},cursor:{SessionStart:`none`,PreToolUse:`none`,PostToolUse:`none`,PreCommit:`none`,SessionEnd:`none`,overall:`none`,label:`Cursor`},windsurf:{SessionStart:`none`,PreToolUse:`none`,PostToolUse:`none`,PreCommit:`none`,SessionEnd:`none`,overall:`none`,label:`Windsurf`},copilot:{SessionStart:`none`,PreToolUse:`native`,PostToolUse:`native`,PreCommit:`none`,SessionEnd:`none`,overall:`partial`,label:`GitHub Copilot`},hermes:{SessionStart:`middleware`,PreToolUse:`middleware`,PostToolUse:`middleware`,PreCommit:`none`,SessionEnd:`middleware`,overall:`middleware`,label:`Hermes Agent (legacy)`},"hermes-agent":{SessionStart:`middleware`,PreToolUse:`middleware`,PostToolUse:`middleware`,PreCommit:`none`,SessionEnd:`middleware`,overall:`middleware`,label:`Hermes Agent`},codex:{SessionStart:`none`,PreToolUse:`none`,PostToolUse:`none`,PreCommit:`none`,SessionEnd:`none`,overall:`none`,label:`Codex CLI`},gemini:{SessionStart:`none`,PreToolUse:`none`,PostToolUse:`none`,PreCommit:`none`,SessionEnd:`none`,overall:`none`,label:`Gemini CLI`},opencode:{SessionStart:`none`,PreToolUse:`none`,PostToolUse:`none`,PreCommit:`none`,SessionEnd:`none`,overall:`none`,label:`OpenCode`},zed:{SessionStart:`none`,PreToolUse:`none`,PostToolUse:`none`,PreCommit:`none`,SessionEnd:`none`,overall:`none`,label:`Zed`},intellij:{SessionStart:`none`,PreToolUse:`none`,PostToolUse:`none`,PreCommit:`none`,SessionEnd:`none`,overall:`none`,label:`IntelliJ`}};function i(){let i=new Set(e),a=[`overall`,`label`];for(let[o,s]of Object.entries(r)){for(let e of i)if(!(e in s))throw Error(`Capability matrix: platform "${o}" is missing event "${e}". Add it to PLATFORM_HOOK_CAPABILITIES.${o}.`);for(let e of a)if(!(e in s))throw Error(`Capability matrix: platform "${o}" is missing "${e}". Add it to PLATFORM_HOOK_CAPABILITIES.${o}.`);if(typeof s.label!=`string`||s.label.length===0)throw Error(`Capability matrix: platform "${o}" has empty or missing "label". Set a non-empty label.`);if(!n.includes(s.overall))throw Error(`Capability matrix: platform "${o}" has invalid overall "${s.overall}". Valid: ${n.join(`, `)}.`);if(e.every(e=>s[e]===`none`)&&s.overall!==`none`)throw Error(`Capability matrix: platform "${o}" has all events 'none' but overall="${s.overall}". Set overall to 'none'.`);for(let e of i)if(!t.includes(s[e]))throw Error(`Capability matrix: platform "${o}" event "${e}" has invalid level "${s[e]}". Valid: ${t.join(`, `)}.`)}}function a(e){let t=Object.keys(r),n=new Set(e);for(let e of t)n.has(e)||console.warn(`Capability matrix: platform "${e}" has no corresponding adapter in generate.mjs ADAPTERS. Hook generation for this platform will be skipped.`)}export{e as HOOK_EVENTS,r as PLATFORM_HOOK_CAPABILITIES,i as validateCapabilityMatrix,a as validateMatrixAdapterAlignment};
@@ -1 +0,0 @@
1
- import{n as e,t}from"./server-BZVPmRGV.js";export{t as buildPreludeInjection,e as generatePrelude};
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import{n as e,t}from"./server-CICqmfQ_.js";export{t as buildPreludeInjection,e as generatePrelude};
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import{r as e}from"./server-CICqmfQ_.js";export{e as createSamplingClient};
@@ -1 +0,0 @@
1
- import{r as e}from"./server-BZVPmRGV.js";export{e as createSamplingClient};