@vpxa/aikit 0.1.378 → 0.1.380
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/package.json +1 -1
- package/packages/claude-desktop/dist/manifest.json +1 -1
- package/packages/cli/dist/index.js +3 -3
- package/packages/cli/dist/{init-gDbVIWiP.js → init-BTsNYC02.js} +1 -1
- package/packages/cli/dist/{templates-BPC4t5yz.js → templates-CRs_gkfS.js} +13 -12
- package/packages/core/dist/index.d.ts +30 -10
- package/packages/core/dist/index.js +1 -1
- package/packages/server/dist/bin.js +1 -1
- package/packages/server/dist/config-Bz8Uyzuq.js +2 -0
- package/packages/server/dist/config-DZskEKrY.js +1 -0
- package/packages/server/dist/dashboard-static-NghHzTNh.js +1 -0
- package/packages/server/dist/dashboard-static-gAOiHHqI.js +2 -0
- package/packages/server/dist/index.js +1 -1
- package/packages/server/dist/register-tools-Dgu64Px5.js +3034 -0
- package/packages/server/dist/register-tools-jgdif5r4.js +3035 -0
- package/packages/server/dist/server-BmVdf84Q.js +26 -0
- package/packages/server/dist/server-C43D7SrT.js +27 -0
- package/packages/server/dist/server-http-BCpGwi0k.js +1 -0
- package/packages/server/dist/server-http-YQ9jxThI.js +2 -0
- package/packages/server/dist/server-stdio-3hhuJU8B.js +2 -0
- package/packages/server/dist/server-stdio-CuLAgQjc.js +1 -0
- package/packages/server/dist/settings-static-DcTUiqr7.js +1 -0
- package/packages/server/dist/settings-static-PjpMR9Q7.js +2 -0
- package/packages/server/dist/startup-maintenance-B4xWqEjc.js +20 -0
- package/packages/server/dist/startup-maintenance-BnTozHs1.js +21 -0
- package/packages/tools/dist/index.d.ts +135 -203
- package/packages/tools/dist/index.js +129 -120
- package/scaffold/dist/adapters/_shared.mjs +12 -11
- package/scaffold/dist/adapters/claude-code.mjs +7 -7
- package/scaffold/dist/adapters/copilot.mjs +12 -12
- package/scaffold/dist/adapters/hermes.mjs +1 -1
- package/scaffold/dist/definitions/bodies.mjs +1 -1
- package/scaffold/dist/definitions/protocols.mjs +1 -1
- package/scaffold/dist/definitions/skills/present.mjs +8 -5
- package/scaffold/dist/definitions/tools.mjs +1 -1
- package/scaffold/general/hooks/scripts/__tests__/bash-guard.test.mjs +214 -0
- package/scaffold/general/hooks/scripts/__tests__/read-size-guard.test.mjs +183 -0
- package/scaffold/general/hooks/scripts/bash-guard.mjs +6 -0
- package/packages/server/dist/config-B4klhHVp.js +0 -2
- package/packages/server/dist/config-D3rRPB9X.js +0 -1
- package/packages/server/dist/dashboard-static-Dw7Nsq4f.js +0 -1
- package/packages/server/dist/dashboard-static-dPnij4uF.js +0 -2
- package/packages/server/dist/evolution-BX_zTSdj.js +0 -2
- package/packages/server/dist/evolution-DWaEE6XW.js +0 -3
- package/packages/server/dist/prelude-C4z3H1li.js +0 -1
- package/packages/server/dist/prelude-WsqQzR-u.js +0 -2
- package/packages/server/dist/promotion-DRnRfteq.js +0 -3
- package/packages/server/dist/promotion-DzVLWVtx.js +0 -2
- package/packages/server/dist/repair-json-B6Q_HRoP.js +0 -3
- package/packages/server/dist/repair-json-D4mft_HA.js +0 -4
- package/packages/server/dist/resolve-sibling-BmZ7AxaA.js +0 -1
- package/packages/server/dist/resolve-sibling-DrGKPpb0.js +0 -2
- package/packages/server/dist/rolldown-runtime-yuFVEuWy.js +0 -2
- package/packages/server/dist/sampling-Bpwc-4Jr.js +0 -2
- package/packages/server/dist/sampling-CfLD3fM_.js +0 -1
- package/packages/server/dist/server-D2a5Rjgk.js +0 -3084
- package/packages/server/dist/server-http-B841uX1k.js +0 -2
- package/packages/server/dist/server-http-tZxvg5ke.js +0 -1
- package/packages/server/dist/server-jZ_r6xLb.js +0 -3083
- package/packages/server/dist/server-stdio-B22xZT0d.js +0 -2
- package/packages/server/dist/server-stdio-DpGfc6DI.js +0 -1
- package/packages/server/dist/settings-static-BpQgaMRs.js +0 -1
- package/packages/server/dist/settings-static-MepJZjer.js +0 -2
- package/packages/server/dist/startup-maintenance-BPrX5-1U.js +0 -2
- package/packages/server/dist/startup-maintenance-CT6Z3734.js +0 -1
- package/packages/server/dist/supersession-CWEne3av.js +0 -2
- package/packages/server/dist/supersession-DO_ZROFl.js +0 -3
- package/packages/server/dist/version-check-C7xqQr9o.js +0 -1
- package/packages/server/dist/version-check-CH5SIhnq.js +0 -2
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import{renderLayeredKnowledgeOperatingPolicyV1 as e}from"../definitions/protocols.mjs";function t(e){return e&&e[0].toLowerCase()+e.slice(1)}function n(
|
|
2
|
-
`)}
|
|
3
|
-
`)}function i({name:e,title:
|
|
1
|
+
import{renderLayeredKnowledgeOperatingPolicyV1 as e}from"../definitions/protocols.mjs";function t(e){return e&&e[0].toLowerCase()+e.slice(1)}function n(){return[`## Workspace Skill`,``,`This project has an auto-generated workspace skill at`,"`<aikit-workspace>/skills/<workspace-name>/SKILL.md`.",``,`The skill tracks **conventions**, **known issues**, and **workflow tips**`,`specific to this codebase. Load it at session start by either:`,``,"1. Calling `status()` and checking the `workspace_skill` metadata field"," for the skill file path, then reading it with `read_file`.",`2. Reading the skill file directly if you know the workspace path.`,``,`The skill is auto-generated from the AI Kit knowledge store and updates`,`automatically when new facts are promoted. To contribute learnings, use`,"the `knowledge` tool — entries appear in the skill on next regeneration.",``,`**Deep-dive references** (per-topic, loaded on demand):`,"- `<skill-dir>/references/architecture.md` — deep architecture","- `<skill-dir>/references/known-issues.md` — recurring problems","- `<skill-dir>/references/workflow-tips.md` — optimization patterns","- `<skill-dir>/references/flow-<slug>.md` — active flow briefing",``].join(`
|
|
2
|
+
`)}function r(e){return!e||e.length===0?``:`## Skills\n\n| Skill | When to load |\n|-------|--------------|\n${e.map(([e,t])=>`| ${e} | ${t} |`).join(`
|
|
3
|
+
`)}`}function i({name:e,title:i,description:a,skills:o,bodyAddendum:s}){let c=r(o),l=n(),u=[`# ${e} - ${i||e}`,``,`> ${a}`,``,`You are the **${e}**, ${t(a)}.`];return s&&u.push(``,s.trim()),c&&u.push(``,c),u.push(``,l),u.push(``),u.join(`
|
|
4
|
+
`)}function a({name:e,title:n,description:i,body:a,skills:o,additionalSections:s}){let c=[`### ${e} — ${n||e}`,``,`> ${i}`,``,`You are the **${e}**, ${t(i)}.`],l=[a,...s||[],r(o)].filter(Boolean).join(`
|
|
4
5
|
|
|
5
6
|
`).trim();return l&&c.push(``,l),c.push(``,`---`,``),c.join(`
|
|
6
|
-
`)}function
|
|
7
|
+
`)}function o({title:e,content:t}){return`# ${e}\n\n${t}`}function s(e){return Object.entries(e).map(([e,t])=>[`### ${t.title||t.description||e}`,``,t.content.trim(),``,`---`,``].join(`
|
|
7
8
|
`)).join(`
|
|
8
|
-
`).trimEnd()}const
|
|
9
|
-
`):``}function
|
|
10
|
-
`)}const
|
|
11
|
-
`).trimEnd()}function
|
|
9
|
+
`).trimEnd()}const c={sessionStart:`SessionStart`,beforeCodeChange:`PreToolUse`,beforeCommit:`PreCommit`,sessionEnd:`SessionEnd`},l=[`sessionStart`,`beforeCodeChange`,`beforeCommit`,`sessionEnd`];function u(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(`
|
|
10
|
+
`):``}function d(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: ${m.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(`
|
|
11
|
+
`)}const f={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:`}},p={sessionStart:`Session Start`,beforeCodeChange:`Before Code Change`,beforeCommit:`Before Commit`,sessionEnd:`Session End`},m=[`pinned`,`default`,`omit`];function h(e,t,n){if(!e)return``;let r=l.map(r=>{let i=e[r];if(!i)return``;let a=c[r],o=t&&a&&t[a]||`none`,s=f[r]||{},l=n?.[r];return d(i,p[r],o,s,l)}),i=u(t);return[...r,i].filter(Boolean).join(`
|
|
12
|
+
`).trimEnd()}function g(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 _(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(` ${g(t,s)||`—`} |`),c.push(` ${a.category||`—`} |`),r.push(c.join(``))}else{let e=[`| **${i}** | ${a.description} |`];n&&e.push(` ${g(t,i)||`—`} |`),e.push(` ${a.category||`—`} |`),r.push(e.join(``))}return n?`| Agent | Purpose | Model | Category |\n|-------|---------|-------|----------|\n${r.join(`
|
|
12
13
|
`)}`:`| Agent | Purpose | Category |\n|-------|---------|----------|\n${r.join(`
|
|
13
|
-
`)}`}function
|
|
14
|
-
`)}`}function
|
|
15
|
-
`)}function
|
|
14
|
+
`)}`}function v(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(`
|
|
15
|
+
`)}`}function y({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 b({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(`
|
|
16
|
+
`)}function x({flowTool:e=`flow`}={}){return b({flowTool:e,isLifecycleOwner:!1})}const S=`You MUST follow the Orchestrator Protocol: decompose every task into subtasks, delegate via Task()/sub-agents, and synthesize results. You are an orchestrator, not an implementer. Never write code directly unless the change is trivially small (≤5 lines, one file) or you are fixing a sub-agent's output. When in doubt, delegate.`;function C(e){return[`# ${S}`,``,...e]}export{S as ORCHESTRATOR_DIRECTIVE,i as buildAgentPrompt,_ as buildAgentTable,v as buildCompactAgentTable,u as buildEventBusNote,b as buildFlowSection,h as buildHooksSection,a as buildInlineAgentSection,y as buildMcpConfigJson,o as buildPromptFile,s as buildPromptSections,r as buildSkillsSection,x as buildSubagentFlowSection,n as buildWorkspaceSkillSection,C as injectOrchestratorDirective,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{SERVER_NAME 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 _,
|
|
2
|
-
`)}function
|
|
3
|
-
`)}function
|
|
4
|
-
`)}function
|
|
5
|
-
`)}function
|
|
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{SERVER_NAME 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 _,buildWorkspaceSkillSection as v,injectOrchestratorDirective as y,lowerFirst as b}from"./_shared.mjs";const 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__${r.toLowerCase().replace(/[^a-z0-9]/g,``)}__${e}`);return[...new Set([...t,...n])].sort((e,t)=>e.localeCompare(t))}function E(e,t){let n=[];return n.push(`# ${r} ${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,i(`claude-code`))){return[`# ${r} — Claude Code Agents`,``,c,``,s,``,`## MCP Server`,``,`Server name: \`${r}\``,"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,a[`claude-code`]),``].join(`
|
|
4
|
+
`)}function M(){return y([`# ${r} — 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,``,v(),``]).join(`
|
|
5
|
+
`)}function N(e,t,n,i,a){let o=T(t.toolRole),s=O(t),c=_(t.skills),l=e===`Orchestrator`?[x]:[S],u=[n,...s,t.bodyAddendum,c,...l].filter(Boolean).join(`
|
|
6
6
|
|
|
7
|
-
`).trim(),d=t.identity?`You are the **${e}**${t.identity}`:`You are the **${e}**, ${
|
|
8
|
-
`)}function
|
|
7
|
+
`).trim(),d=t.identity?`You are the **${e}**${t.identity}`:`You are the **${e}**, ${b(t.description)}.`,f=a?.[e],p=o.length>0?`tools: [${o.join(`, `)}]`:null,m=t.skills?.length>0?`skills: [${t.skills.map(([e])=>e).join(`, `)}]`:null,h=[`---`,`name: ${C(e)}`,`description: ${w(t.description)}`,...f?[`model: ${w(f)}`]:[],...p?[p]:[],`mcpServers:`,` - ${r}`,...m?[m]:[],`---`,``,`# ${e} - ${t.title||e}`,``,d];return u&&h.push(``,u),h.push(``),h.join(`
|
|
8
|
+
`)}function P(){let t=[],n=i(`claude-code`),r=p(e,n),a=m(e);t.push({path:`CLAUDE.md`,content:M()}),t.push({path:`AGENTS.md`,content:j(r)});for(let[e,n]of Object.entries(o))t.push({path:`.claude/commands/aikit-${e}.md`,content:E(e,n)});for(let[i,o]of Object.entries(e)){let e=D(i,a);if(o.variants){for(let[a,s]of Object.entries(o.variants)){let c=`${i}-${a}`;t.push({path:`.claude/agents/${c}.md`,content:N(c,{...o,description:s.description||o.description,identity:s.identity,bodyAddendum:s.bodyAddendum},e,r,n)})}continue}t.push({path:`.claude/agents/${i}.md`,content:N(i,o,e,r,n)})}return t}export{x as CLAUDE_FLOWS_SECTION,P as generateClaudeCode};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{AGENTS as e}from"../definitions/agents.mjs";import{AGENT_BODIES as t}from"../definitions/bodies.mjs";import{VARIANT_GROUPS as n,getPrimaryAgentModel as r}from"../definitions/models.mjs";import{PROMPTS as i}from"../definitions/prompts.mjs";import{AIKIT_INSTALL_HINT_SECTION as a,PLATFORM_OUTPUT_RULES_SECTION as o,PROTOCOLS as s,TEMPLATES as c}from"../definitions/protocols.mjs";import{IDE_CAPABILITIES as l}from"../definitions/tools.mjs";import{buildCompactAgentTable as u,buildFlowSection as d,buildSubagentFlowSection as f,injectOrchestratorDirective as
|
|
2
|
-
`)}`}function
|
|
1
|
+
import{AGENTS as e}from"../definitions/agents.mjs";import{AGENT_BODIES as t}from"../definitions/bodies.mjs";import{VARIANT_GROUPS as n,getPrimaryAgentModel as r}from"../definitions/models.mjs";import{PROMPTS as i}from"../definitions/prompts.mjs";import{AIKIT_INSTALL_HINT_SECTION as a,PLATFORM_OUTPUT_RULES_SECTION as o,PROTOCOLS as s,TEMPLATES as c}from"../definitions/protocols.mjs";import{IDE_CAPABILITIES as l}from"../definitions/tools.mjs";import{buildCompactAgentTable as u,buildFlowSection as d,buildSubagentFlowSection as f,buildWorkspaceSkillSection as p,injectOrchestratorDirective as m}from"./_shared.mjs";import{generateForbiddenTable as h}from"../definitions/policies.mjs";import{generateHooks as g,getHookScriptFiles as _}from"./hooks.mjs";const v={terminal:`execute/runInTerminal`,problems:`read/problems`,readFile:`read/readFile`,lastCommand:`read/terminalLastCommand`,subagent:`agent/runSubagent`,createFile:`edit/createFile`,editFiles:`edit/editFiles`,rename:`edit/rename`,createDirectory:`edit/createDirectory`,search:`search/changes, search/codebase, search/usages`,web:`web/fetch, web/githubRepo`,todo:`todo`,memory:`vscode/memory`,newWorkspace:`vscode/newWorkspace`,reviewPlan:`vscode/reviewPlan`,askQuestions:`vscode/askQuestions`,resolveMemoryFileUri:`vscode/resolveMemoryFileUri`,runCommand:`vscode/runCommand`,switchAgent:`vscode/switchAgent`,killTerminal:`execute/killTerminal`,createTask:`execute/createAndRunTask`,terminalSel:`read/terminalSelection`,fileSearch:`search/fileSearch`,listDir:`search/listDirectory`,textSearch:`search/textSearch`,searchSubagent:`search/searchSubagent`};function y(e){return`[${[...(l[e]||[]).map(e=>v[e]).filter(Boolean),`aikit/*`].join(`, `)}]`}function b(e){return r(`copilot`,e,`Auto (copilot)`)}const x=d({flowTool:`flow`,isLifecycleOwner:!0}),S=f({flowTool:`flow`});function C(){let t=[];for(let[i,a]of Object.entries(e))if(a.variants)for(let e of n[i]||[]){let n=`${i}-${e}`,o=r(`copilot`,n,`Unknown`),s=(a.variants[e]||{}).description||a.description;t.push(`| **${n}** | ${s} | ${o} | ${a.category} |`)}else{let e=r(`copilot`,i,`Unknown`);t.push(`| **${i}** | ${a.description} | ${e} | ${a.category} |`)}return`| Agent | Purpose | Model | Category |\n|-------|---------|-------|----------|\n${t.join(`
|
|
2
|
+
`)}`}function w(e,t,r){let i=`${e}-${t}`,a=r.variants[t]||{},o=b(i),c=a.description||r.description,l=a.identity||(t===n[e]?.[0]?`, the primary ${e} agent.`:`, a variant of ${e}. Same responsibilities, different model perspective.`),u=r.sharedBase&&s[r.sharedBase]?`\n\n${s[r.sharedBase]}`:``,d=r.extraBody?`\n\n${r.extraBody}`:``,f=a.bodyAddendum?`\n\n${a.bodyAddendum}`:``,p=(r.sharedProtocols||[]).map(e=>s[e]?`\n\n${s[e]}`:``).join(``),m=r.skills?.length?`\n\n## Skills (load on demand)\n\n| Skill | When to load |\n|-------|--------------|\n${r.skills.map(([e,t])=>`| ${e} | ${t} |`).join(`
|
|
3
3
|
`)}`:``,h=r.title||e;return`---
|
|
4
4
|
description: '${c}'
|
|
5
|
-
${r.argumentHint?`argument-hint: "${r.argumentHint}"\n`:``}tools: ${
|
|
5
|
+
${r.argumentHint?`argument-hint: "${r.argumentHint}"\n`:``}tools: ${y(r.toolRole)}
|
|
6
6
|
model: ${o}
|
|
7
7
|
---
|
|
8
8
|
|
|
@@ -11,11 +11,11 @@ model: ${o}
|
|
|
11
11
|
You are **${i}**${l}${d}
|
|
12
12
|
${u}${p}${f}${m}
|
|
13
13
|
|
|
14
|
-
${
|
|
15
|
-
`}function
|
|
14
|
+
${S}
|
|
15
|
+
`}function T(n,r){let i=b(n),a=typeof t[n]==`function`?t[n](u(e)):t[n]||``,o=r.sharedBase&&s[r.sharedBase]?`\n\n${s[r.sharedBase]}`:``,c=(r.sharedProtocols||[]).map(e=>s[e]?`\n\n${s[e]}`:``).join(``),l=r.title||n,d=r.skills?.length?`\n## Skills (load on demand)\n\n| Skill | When to load |\n|-------|--------------|\n${r.skills.map(([e,t])=>`| ${e} | ${t} |`).join(`
|
|
16
16
|
`)}\n`:``;return`---
|
|
17
17
|
description: '${r.description}'
|
|
18
|
-
${r.argumentHint?`argument-hint: "${r.argumentHint}"\n`:``}tools: ${
|
|
18
|
+
${r.argumentHint?`argument-hint: "${r.argumentHint}"\n`:``}tools: ${y(r.toolRole)}
|
|
19
19
|
model: ${i}
|
|
20
20
|
---
|
|
21
21
|
|
|
@@ -25,20 +25,20 @@ You are the **${n}**, ${r.description.toLowerCase().replace(/^./,e=>e.toLowerCas
|
|
|
25
25
|
|
|
26
26
|
${a}${o}${c}${d}
|
|
27
27
|
|
|
28
|
-
${n===`Orchestrator`?
|
|
29
|
-
`}function
|
|
28
|
+
${n===`Orchestrator`?x:S}
|
|
29
|
+
`}function E(e,t){return`---
|
|
30
30
|
description: "${t.description}"
|
|
31
31
|
agent: "${t.agent}"
|
|
32
32
|
---
|
|
33
33
|
|
|
34
34
|
${t.content}
|
|
35
|
-
`}function
|
|
35
|
+
`}function D(){return`# Agents
|
|
36
36
|
|
|
37
37
|
This directory contains AI agent definitions generated by \`@vpxa/aikit init\`.
|
|
38
38
|
|
|
39
39
|
## Agent Roster
|
|
40
40
|
|
|
41
|
-
${
|
|
41
|
+
${C()}
|
|
42
42
|
|
|
43
43
|
## Multi-Model Pattern
|
|
44
44
|
|
|
@@ -64,5 +64,5 @@ To regenerate after changing models or agent definitions:
|
|
|
64
64
|
cd knowledge-base
|
|
65
65
|
node scaffold/generate.mjs
|
|
66
66
|
\`\`\`
|
|
67
|
-
`}function
|
|
68
|
-
`)}function
|
|
67
|
+
`}function O(){return m([`# AI Kit — Copilot Instructions`,``,"This file is generated from `scaffold/definitions/`. Do not edit directly.",``,o,``,`## Tool Routing Rules`,``,`These rules are enforced by AI Kit compliance checking. Violations are flagged in reports and reduce your compliance score.`,``,h(),``,a,``,p(),``]).join(`
|
|
68
|
+
`)}function k(){let t=[];if(_().length===0)throw Error(`Executable hooks are not configured.`);t.push({path:`copilot-instructions.md`,content:O()});for(let[r,i]of Object.entries(e))if(i.variants)for(let e of n[r]||[])t.push({path:`agents/${r}-${e}.agent.md`,content:w(r,e,i)});else t.push({path:`agents/${r}.agent.md`,content:T(r,i)});for(let[e,n]of Object.entries(c))t.push({path:`agents/templates/${e}.md`,content:`${n}\n`});t.push({path:`agents/README.md`,content:D()});for(let[e,n]of Object.entries(i))t.push({path:`prompts/aikit-${e}.prompt.md`,content:E(e,n)});let r=g(`copilot`,`~/.copilot/hooks/scripts`);return t.push(...r.map(e=>({path:`hooks/${e.path}`,content:e.content}))),t}export{k as generateCopilot};
|
|
@@ -1,4 +1,4 @@
|
|
|
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{VARIANT_GROUPS as r,getPrimaryAgentModel 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{PROTOCOLS as s,TEMPLATES as c}from"../definitions/protocols.mjs";import{IDE_CAPABILITIES as l}from"../definitions/tools.mjs";import{buildAgentTable as u,buildCompactAgentTable as d,buildFlowSection as f,buildHooksSection as p,buildPromptSections as m,buildSkillsSection as h,injectOrchestratorDirective as g,lowerFirst as _}from"./_shared.mjs";import{generateHooks as v,getHookScriptFiles as y}from"./hooks.mjs";const b=f({flowTool:`flow`,isLifecycleOwner:!0}),x=f({flowTool:`flow`,isLifecycleOwner:!1});function S(e,n){let r=t[e];return typeof r==`function`?r(n):r||``}function C(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}const w={terminal:`terminal`,problems:`mcp_aikit_check`,readFile:`read_file`,lastCommand:`terminal`,subagent:`delegate_task`,createFile:`write_file`,editFiles:`patch`,rename:`write_file`,createDirectory:`terminal(mkdir)`,search:`search_files, mcp_aikit_search, mcp_aikit_find`,web:`web_search, web_extract, mcp_aikit_web_search, mcp_aikit_web_fetch`,todo:`todo`,memory:`memory`,newWorkspace:`terminal(cd)`,reviewPlan:`clarify`,askQuestions:`clarify`,resolveMemoryFileUri:`read_file`,runCommand:`terminal`,switchAgent:`delegate_task`,killTerminal:`process(kill)`,createTask:`todo`,terminalSel:`terminal`,fileSearch:`search_files`,listDir:`search_files(target=files)`,textSearch:`search_files(target=content)`,searchSubagent:`delegate_task`,browser:`mcp_aikit_browser, browser_navigate`};function T(e){let t=(l[e]||[]).map(e=>{let t=w[e];return t?t.split(`,`).map(e=>e.trim()):null}).filter(Boolean).flat();return`[${[...new Set(t),`aikit/*`].join(`, `)}]`}function E(e){return i(`hermes`,e,`Auto (hermes)`)}function D(e){let t=[[/`runSubagent`/g,"`delegate_task`"],[/`runSubagent\(/g,"`delegate_task("],[/\brunSubagent\b/g,`delegate_task`],[/`editFiles`/g,"`patch`"],[/`createFile`/g,"`write_file`"],[/`edit\/createFile`/g,"`write_file`"],[/`edit\/editFiles`/g,"`patch`"],[/`run_in_terminal`/g,"`terminal`"],[/`execute\/runInTerminal`/g,"`terminal`"],[/`execute\/killTerminal`/g,"`process(kill)`"],[/`grep_search`/g,"`search_files`"],[/`search\/codebase`/g,"`mcp_aikit_search`"],[/`search\/changes`/g,"`search_files`"],[/`search\/usages`/g,"`mcp_aikit_symbol` / `mcp_aikit_trace`"],[/`search\/textSearch`/g,"`search_files`"],[/`search\/searchSubagent`/g,"`delegate_task`"],[/`web\/fetch`/g,"`web_extract` / `mcp_aikit_web_fetch`"],[/`web\/githubRepo`/g,"`terminal(git ...)`"],[/`web\/webSearch`/g,"`web_search` / `mcp_aikit_web_search`"],[/`vscode\/memory`/g,"`memory`"],[/`vscode\/runCommand`/g,"`terminal`"],[/`vscode\/switchAgent`/g,"`delegate_task`"],[/`vscode\/newWorkspace`/g,"`terminal(cd)`"],[/`vscode\/reviewPlan`/g,"`clarify`"],[/`vscode\/askQuestions`/g,"`clarify`"],[/`vscode\/resolveMemoryFileUri`/g,"`read_file`"],[/`read\/readFile`/g,"`read_file`"],[/`read\/terminalLastCommand`/g,"`terminal`"],[/`read\/terminalSelection`/g,"`terminal`"],[/`read\/problems`/g,"`mcp_aikit_check`"],[/`agent\/runSubagent`/g,"`delegate_task`"],[/`execute\/createAndRunTask`/g,"`todo` / `delegate_task`"],[/`read_file` \(for understanding\)/g,"`read_file` (Hermes)"],[/(copilot)/g,`(hermes)`],[/runSubagent\(\{agentName:/g,`delegate_task({goal:`],[/runSubagent\(\{/g,`delegate_task({`]],n=e;for(let[e,r]of t)n=n.replace(e,r);return n}function O(){let t=u(e),r=d(e),i=m(o),s=[];for(let[t,n]of Object.entries(e)){let e=S(t,r);if(n.variants){for(let[r,i]of Object.entries(n.variants)){let a=`${t}-${r}`;s.push(k(a,{...n,description:i.description||n.description,identity:i.identity,bodyAddendum:i.bodyAddendum},e))}continue}s.push(k(t,n,e))}return g([`# 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
|
|
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{VARIANT_GROUPS as r,getPrimaryAgentModel 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{PROTOCOLS as s,TEMPLATES as c}from"../definitions/protocols.mjs";import{IDE_CAPABILITIES as l}from"../definitions/tools.mjs";import{buildAgentTable as u,buildCompactAgentTable as d,buildFlowSection as f,buildHooksSection as p,buildPromptSections as m,buildSkillsSection as h,injectOrchestratorDirective as g,lowerFirst as _}from"./_shared.mjs";import{generateHooks as v,getHookScriptFiles as y}from"./hooks.mjs";const b=f({flowTool:`flow`,isLifecycleOwner:!0}),x=f({flowTool:`flow`,isLifecycleOwner:!1});function S(e,n){let r=t[e];return typeof r==`function`?r(n):r||``}function C(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}const w={terminal:`terminal`,problems:`mcp_aikit_check`,readFile:`read_file`,lastCommand:`terminal`,subagent:`delegate_task`,createFile:`write_file`,editFiles:`patch`,rename:`write_file`,createDirectory:`terminal(mkdir)`,search:`search_files, mcp_aikit_search, mcp_aikit_find`,web:`web_search, web_extract, mcp_aikit_web_search, mcp_aikit_web_fetch`,todo:`todo`,memory:`memory`,newWorkspace:`terminal(cd)`,reviewPlan:`clarify`,askQuestions:`clarify`,resolveMemoryFileUri:`read_file`,runCommand:`terminal`,switchAgent:`delegate_task`,killTerminal:`process(kill)`,createTask:`todo`,terminalSel:`terminal`,fileSearch:`search_files`,listDir:`search_files(target=files)`,textSearch:`search_files(target=content)`,searchSubagent:`delegate_task`,browser:`mcp_aikit_browser, browser_navigate`};function T(e){let t=(l[e]||[]).map(e=>{let t=w[e];return t?t.split(`,`).map(e=>e.trim()):null}).filter(Boolean).flat();return`[${[...new Set(t),`aikit/*`].join(`, `)}]`}function E(e){return i(`hermes`,e,`Auto (hermes)`)}function D(e){let t=[[/`runSubagent`/g,"`delegate_task`"],[/`runSubagent\(/g,"`delegate_task("],[/\brunSubagent\b/g,`delegate_task`],[/`editFiles`/g,"`patch`"],[/`createFile`/g,"`write_file`"],[/`edit\/createFile`/g,"`write_file`"],[/`edit\/editFiles`/g,"`patch`"],[/`run_in_terminal`/g,"`terminal`"],[/`execute\/runInTerminal`/g,"`terminal`"],[/`execute\/killTerminal`/g,"`process(kill)`"],[/`grep_search`/g,"`search_files`"],[/`search\/codebase`/g,"`mcp_aikit_search`"],[/`search\/changes`/g,"`search_files`"],[/`search\/usages`/g,"`mcp_aikit_symbol` / `mcp_aikit_trace`"],[/`search\/textSearch`/g,"`search_files`"],[/`search\/searchSubagent`/g,"`delegate_task`"],[/`web\/fetch`/g,"`web_extract` / `mcp_aikit_web_fetch`"],[/`web\/githubRepo`/g,"`terminal(git ...)`"],[/`web\/webSearch`/g,"`web_search` / `mcp_aikit_web_search`"],[/`vscode\/memory`/g,"`memory`"],[/`vscode\/runCommand`/g,"`terminal`"],[/`vscode\/switchAgent`/g,"`delegate_task`"],[/`vscode\/newWorkspace`/g,"`terminal(cd)`"],[/`vscode\/reviewPlan`/g,"`clarify`"],[/`vscode\/askQuestions`/g,"`clarify`"],[/`vscode\/resolveMemoryFileUri`/g,"`read_file`"],[/`read\/readFile`/g,"`read_file`"],[/`read\/terminalLastCommand`/g,"`terminal`"],[/`read\/terminalSelection`/g,"`terminal`"],[/`read\/problems`/g,"`mcp_aikit_check`"],[/`agent\/runSubagent`/g,"`delegate_task`"],[/`execute\/createAndRunTask`/g,"`todo` / `delegate_task`"],[/`read_file` \(for understanding\)/g,"`read_file` (Hermes)"],[/(copilot)/g,`(hermes)`],[/runSubagent\(\{agentName:/g,`delegate_task({goal:`],[/runSubagent\(\{/g,`delegate_task({`]],n=e;for(let[e,r]of t)n=n.replace(e,r);return n}function O(){let t=u(e),r=d(e),i=m(o),s=[];for(let[t,n]of Object.entries(e)){let e=S(t,r);if(n.variants){for(let[r,i]of Object.entries(n.variants)){let a=`${t}-${r}`;s.push(k(a,{...n,description:i.description||n.description,identity:i.identity,bodyAddendum:i.bodyAddendum},e))}continue}s.push(k(t,n,e))}return g([`# 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 52 tools are available`,"as `mcp_aikit_*` tool calls in every conversation.",``,`## MCP Server`,``,"Server name: `AI Kit`","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.`,``,`## Workspace Skill`,``,`This project has an auto-generated workspace skill that tracks conventions, known issues,`,`and workflow tips for this specific codebase. Load it at session start:`,``,` skill_view('<workspace-name>')`,``,`The skill is named after your workspace (the project directory name).`,`It's auto-generated from the knowledge store and updates automatically.`,"If you discover something new about this workspace, store it via `knowledge` tool",`— it will appear in the skill on the next regeneration.`,``,"Use `skill_view(name, file_path)` for deep-dives into specific topics:","- `skill_view(name, 'references/architecture.md')` — deep architecture","- `skill_view(name, 'references/known-issues.md')` — recurring problems","- `skill_view(name, 'references/workflow-tips.md')` — optimization patterns","- `skill_view(name, 'references/flow-<slug>.md')` — active flow briefing",``,`## Available Tools (37)`,``,`AI Kit provides tools across the following categories:`,``,`| Category | Tools |`,`|----------|-------|`,"| **Search & Discovery** | `search`, `find`, `symbol`, `trace`, `scope_map`, `file_summary` |","| **Code Analysis** | `analyze`, `audit`, `graph`, `check` |","| **Context Compression** | `file_summary`, `digest` |","| **Memory & Knowledge** | `knowledge`, `remember`, `read`, `update`, `forget`, `list` |","| **FORGE Quality Gates** | `forge_ground`, `evidence_map` |","| **Development Workflows** | `flow`, `onboard`, `reindex`, `status`, `config` |","| **Testing & Build** | `test_run`, `parse_output`, `check`, `eval` |","| **Code Manipulation** | `rename`, `codemod`, `diff_parse`, `replay` |","| **Git** | `git` |","| **Session** | `session` |","| **Web & HTTP** | `web_search`, `web_fetch` |","| **Present & Visualize** | `present` |","| **Sandbox & Process** | `process`, `queue`, `restore`, `delegate` |","| **Utilities** | `measure`, `env` |","| **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`,``,s.join(`
|
|
2
2
|
`),``,`## Prompts`,``,i,``,b,``,`## Session Protocol`,``,p(n,a.hermes),``]).join(`
|
|
3
3
|
`)}function k(e,t,n){let r=C(t),i=h(t.skills),a=e===`Orchestrator`?b:x,o=[n,...r,t.bodyAddendum,i,a].filter(Boolean).join(`
|
|
4
4
|
|
|
@@ -39,7 +39,7 @@ When dispatching subagents, include this line: "Communication style: terse like
|
|
|
39
39
|
1a. For flow dispatch: status({ includePrelude: true }) → if onboard missing or workspace stale, onboard({ path: ".", update: true }) before any subagent dispatch.
|
|
40
40
|
2. Apply layered knowledge protocol (see below).<!-- layered-header -->
|
|
41
41
|
3. search({ query: "SESSION CHECKPOINT", origin: "curated" }) before planning.
|
|
42
|
-
5. Load skills by trigger: aikit always; multi-agents-development before delegation; present before non-tiny output (
|
|
42
|
+
5. Load skills by trigger: aikit always; multi-agents-development before delegation; present before non-tiny output (preferBrowser=true by default; set preferBrowser:false for inline rendering — auto-falls back to browser if client doesn't support inline); brainstorming for design decisions.
|
|
43
43
|
|
|
44
44
|
## Tiered Lifecycle
|
|
45
45
|
Floor: forge_classify -> one specialist -> check({}) + test_run({}) -> present result.
|
|
@@ -19,7 +19,7 @@ ${e===`<PROFILE>`?`**Profile:** Check your role → implementer | documenter | r
|
|
|
19
19
|
|
|
20
20
|
---`}function r(){return"\n## Evidence Citation Protocol (tier-aware)\n\nNo FORGE `task_id` → skip `evidence_map`; use `file:line` citations only.\nDo not create your own `task_id` or run the gate.\n\n| Tier | Your responsibility |\n|------|---------------------|\n| Floor | Findings with `file.ts#Lxx` citations. No `evidence_map`. |\n| Standard | Add 2-4 CRITICAL/HIGH findings with receipts. |\n| Critical | Add all CRITICAL/HIGH findings; tag contract/security claims with `safety_gate`. |\n\n**Every response MUST include:**\n- `**FORGE Task ID:** <task_id>` (passed in by Orchestrator, or state \"not provided\")\n- `**Tier applied:** Floor | Standard | Critical`\n- `**Findings:** <list>` with `file:line` receipts\n- Verdict: `APPROVED` | `CHANGES_REQUESTED` | `BLOCKED`\n\nDo NOT create a new `evidence_map`, run `evidence_map({action:'gate'})`, or add non-critical noise."}function i(...e){return e.filter(Boolean).join(`
|
|
21
21
|
|
|
22
|
-
`)}function a({title:e=`Knowledge Recall`,intro:t,commands:n,followUp:r}={}){let a=[``,`### Retrieval-First Knowledge Access`,``,`**Always follow progressive discovery: L0 → exact-topic search/refs → broad scans.**`,``,"1. **Start with L0** — `status({ includePrelude: true })` or `aikit://
|
|
22
|
+
`)}function a({title:e=`Knowledge Recall`,intro:t,commands:n,followUp:r}={}){let a=[``,`### Retrieval-First Knowledge Access`,``,`**Always follow progressive discovery: L0 → exact-topic search/refs → broad scans.**`,``,"1. **Start with L0** — `status({ includePrelude: true })` or `aikit://skill/SKILL.md` resource",'2. **Search exact topic** — `search({ query: "<specific-topic>" })` — results include `ctxc_` refs','3. **Reuse refs** — `compact({ ref: "ctxc_<hash>" })` restores context without re-running search',"4. **Use `enrich: true`** on search/find/symbol for graph context without extra round-trip",`5. **Broad scan last resort** — only use find/glob/raw reads when L0 + exact search + refs fail`,``,`> **Note:** L1 (flow working-context withdrawal) is handled by your Orchestrator before dispatch —`,'> do not re-withdraw `knowledge({ scope: "flow" })` yourself. L2 (curated) is covered by step 2 above.',``].join(`
|
|
23
23
|
`);return i(`## Pre-Task: ${e} (MANDATORY)`,t,["```",...(Array.isArray(n)?n:[n]).filter(Boolean),"```"].join(`
|
|
24
24
|
`),r,a)}function o(){return i(`## Post-Task: Capture Lesson`,`**HARD RULE:** Before DONE, capture 1-2 lessons unless change is pure config/formatting.`,'Quick capture:\n```\nknowledge({ action: "lesson", subAction: "create", context: "<what situation you faced>", insight: "<what principle the solution demonstrates>", evidence: "<file:line or commit that proves it>", confidence: 65 })\n```',"If recalled lesson was confirmed/invalid, use `confirm` or `contradict`.")}const s=1,c=Object.freeze({version:1,l0MemoriesDir:`memories`,sessionStart:{requiredCards:[`workspace-core`],maxAdditionalCards:1,activeFlowPreference:`workflow-card`,totalTokenBudget:2100},retrievalOrder:[`l0`,`l1`,`l2-on-demand`,`l3-evidence-only`],noFlowFallback:`l0-plus-l2-with-turn-local-context`,degradedFallback:`prelude-manifest-canonical-markdown`,lifecycleAuthority:`opaque-owner-capability`,autoKnowledgeMode:`observer-only`,l0Budgets:Object.freeze({"workspace-core":{min:800,max:1200},architecture:{min:600,max:900},"testing-release":{min:600,max:900},"known-issues":{min:400,max:700},"workflow:*":{min:500,max:900}})});function l(e={}){let{audience:t=`agent`}=e,n=c,r=`## Layered Knowledge Protocol (v${n.version})
|
|
25
25
|
|
|
@@ -18,9 +18,11 @@ Use present for complex user-facing output: reports, dashboards, evidence maps,
|
|
|
18
18
|
## Authoring Model
|
|
19
19
|
|
|
20
20
|
Choose one:
|
|
21
|
-
- blocks
|
|
22
|
-
- template + data
|
|
23
|
-
- raw JSON
|
|
21
|
+
- **blocks** — direct markdown/heading/table/chart/cards/metrics/checklist/timeline/status-board/stat-group/alert (use only supported block types from block catalog reference). **Safer default for browser transport.**
|
|
22
|
+
- **template + data** — only for viewer templates (c4@1, c4-static@1, process-flow@1, process-flow-static@1, tour@1, task-plan-static@1, code-review@1) or named presets (summary, plan, understanding, bug-analyze, task-done, review, explore, decision). Pass as \`present({ template: '<id>', data: {...} })\`.
|
|
23
|
+
- **raw JSON** — complex surfaces where hand-authored object is clearer. When using \`raw\`, omit \`schemaVersion\` and \`title\` at the top level — the \`raw\` JSON must be a self-contained ChannelSurface (include \`schemaVersion\`, \`title\`, and \`blocks\` inside the raw string).
|
|
24
|
+
|
|
25
|
+
**⚠️ MCP App templates (report, dashboard, document, error, diff-view, status-board) are display-only — they do NOT accept user \`data\`. Do NOT pass \`{ template: 'report@1', data: {...} }\`. The browser will open empty. Use \`blocks\` instead for rich browser content.**
|
|
24
26
|
|
|
25
27
|
Only use block types listed in the block catalog — unknown types fallback to markdown but lose styling.
|
|
26
28
|
|
|
@@ -28,7 +30,7 @@ Only use block types listed in the block catalog — unknown types fallback to m
|
|
|
28
30
|
|
|
29
31
|
| Need | Shape |
|
|
30
32
|
|---|---|---|
|
|
31
|
-
| Summary/report |
|
|
33
|
+
| Summary/report | heading + markdown/table blocks (NOT report template — that's MCP App display-only) |
|
|
32
34
|
| Plan/progress | task-plan/checklist/status-board |
|
|
33
35
|
| Metrics/trends | metrics + chart |
|
|
34
36
|
| Compare options | table + kv + recommendation |
|
|
@@ -409,8 +411,9 @@ All renderers accept \`meta: { palette: 'warm' | 'technical', title: string, sub
|
|
|
409
411
|
|
|
410
412
|
## 14 MCP App Templates
|
|
411
413
|
|
|
414
|
+
**⚠️ These are NOT viewer templates. Do NOT use \`present({ template: 'report@1', data: {...} })\` — the browser will open empty. MCP App templates are display-only and render inline in the MCP App host. For browser-rich output, use \`blocks\` instead.**
|
|
415
|
+
|
|
412
416
|
| Template | Purpose | Returns |
|
|
413
|
-
|----------|---------|---------|
|
|
414
417
|
| list-sort | Reorder ranked list | Reordered items |
|
|
415
418
|
| data-table | Inspect structured rows | Selection/filter |
|
|
416
419
|
| picker | Choose items from categories | Selected IDs |
|
|
@@ -1 +1 @@
|
|
|
1
|
-
const e=`analyze.audit.
|
|
1
|
+
const e=`analyze.audit.browser.check.codemod.config.delegate.digest.env.eval.evidence_map.file_summary.find.flow.forge_ground.git.graph.knowledge.measure.onboard.parse_output.present.process.produce_knowledge.queue.reindex.rename.replay.restore.scope_map.search.session.status.symbol.test_run.trace.web_fetch.web_search`.split(`.`),t={orchestrator:[`memory`,`runCommand`,`switchAgent`,`newWorkspace`,`reviewPlan`,`killTerminal`,`createTask`,`terminal`,`terminalSel`,`lastCommand`,`problems`,`readFile`,`editFiles`,`subagent`,`search`,`web`,`todo`,`searchSubagent`,`textSearch`,`browser`,`askQuestions`,`resolveMemoryFileUri`],researcher:[`terminal`,`problems`,`readFile`,`lastCommand`,`subagent`,`search`,`web`,`browser`],reviewer:[`terminal`,`problems`,`readFile`,`lastCommand`,`subagent`,`search`,`web`,`browser`],codeAgent:[`createTask`,`terminal`,`problems`,`readFile`,`lastCommand`,`subagent`,`createFile`,`editFiles`,`rename`,`createDirectory`,`search`,`todo`,`browser`],debugger:[`terminal`,`problems`,`readFile`,`terminalSel`,`lastCommand`,`subagent`,`createFile`,`editFiles`,`search`,`browser`],refactor:[`terminal`,`problems`,`readFile`,`lastCommand`,`subagent`,`createFile`,`editFiles`,`rename`,`createDirectory`,`search`,`browser`],explorer:[`problems`,`readFile`,`search`,`fileSearch`,`listDir`,`textSearch`,`browser`],planner:[`terminal`,`problems`,`readFile`,`reviewPlan`,`memory`,`askQuestions`,`resolveMemoryFileUri`,`lastCommand`,`subagent`,`createFile`,`editFiles`,`rename`,`createDirectory`,`search`,`web`,`todo`,`searchSubagent`,`browser`],security:[`terminal`,`problems`,`readFile`,`subagent`,`search`,`web`,`browser`],documenter:[`terminal`,`problems`,`readFile`,`lastCommand`,`subagent`,`createFile`,`editFiles`,`rename`,`createDirectory`,`search`,`web`,`browser`]},n={terminal:[`Bash`],problems:[`Read`],readFile:[`Read`],lastCommand:[`Bash`],subagent:[],createFile:[`Write`],editFiles:[`Edit`],rename:[`Write`],createDirectory:[`Write`],search:[`Read`],web:[`WebFetch`,`WebSearch`],todo:[`TodoRead`,`TodoWrite`],memory:[],runCommand:[`Bash`],switchAgent:[],newWorkspace:[`Bash`],reviewPlan:[],killTerminal:[`Bash`],createTask:[`Task`],terminalSel:[`Bash`],fileSearch:[`Read`],listDir:[`Read`],textSearch:[`Read`],searchSubagent:[],browser:[],askQuestions:[],resolveMemoryFileUri:[]};export{e as AIKIT_TOOLS,n as CLAUDE_CODE_TOOL_MAP,t as IDE_CAPABILITIES};
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Contract tests for bash-guard.mjs (PreToolUse guard).
|
|
4
|
+
*
|
|
5
|
+
* Tests the REDIRECT_PATTERNS logic in isolation — replicates the exact
|
|
6
|
+
* patterns from the guard and validates deny/allow decisions.
|
|
7
|
+
*
|
|
8
|
+
* The handler function is not exported from bash-guard.mjs (it's passed
|
|
9
|
+
* to createHook and never re-exported), so we contract-test the patterns
|
|
10
|
+
* and extraction logic directly. Any pattern change in the guard MUST
|
|
11
|
+
* be mirrored here — if tests fail, update both.
|
|
12
|
+
*
|
|
13
|
+
* @category test
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import assert from 'node:assert/strict';
|
|
17
|
+
import { describe, it } from 'node:test';
|
|
18
|
+
|
|
19
|
+
// ─── Exact replicas of bash-guard.mjs patterns ─────────────────────────────
|
|
20
|
+
|
|
21
|
+
const BASH_TOOLS = new Set(['Bash', 'bash', 'execute_command', 'terminal']);
|
|
22
|
+
|
|
23
|
+
const REDIRECT_PATTERNS = [
|
|
24
|
+
{ re: /^\s*grep(\s|$)/m },
|
|
25
|
+
{ re: /^\s*find(\s|$)/m },
|
|
26
|
+
{ re: /^\s*cat(\s|$)/m },
|
|
27
|
+
{ re: /^\s*ls(\s|$)/m },
|
|
28
|
+
{ re: /^\s*rg(\s|$)/m },
|
|
29
|
+
{ re: /^\s*dir(\s|$)/m },
|
|
30
|
+
// Chained commands — catches `cd /tmp; grep`, `cmd && find`, `ls | rg` bypasses
|
|
31
|
+
{ re: /[;&|]{1,2}\s*(grep|find|cat|ls|rg|dir)\s/m },
|
|
32
|
+
];
|
|
33
|
+
|
|
34
|
+
// ─── Replica of the handler's command extraction ──────────────────────────
|
|
35
|
+
|
|
36
|
+
function extractCommand(toolInput) {
|
|
37
|
+
return String(
|
|
38
|
+
toolInput?.command ?? toolInput?.cmd ?? toolInput?.input ?? toolInput?.script ?? '',
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// ─── Replica of the handler's core decision logic ─────────────────────────
|
|
43
|
+
|
|
44
|
+
function isDenied(toolName, toolInput) {
|
|
45
|
+
if (!BASH_TOOLS.has(toolName)) return false;
|
|
46
|
+
const command = extractCommand(toolInput);
|
|
47
|
+
if (!command.trim()) return false;
|
|
48
|
+
return REDIRECT_PATTERNS.some(({ re }) => re.test(command));
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// ─── Tests ─────────────────────────────────────────────────────────────────
|
|
52
|
+
|
|
53
|
+
describe('bash-guard — deny bad commands', () => {
|
|
54
|
+
// ── Start-of-line patterns ────────────────────────────────────────────
|
|
55
|
+
|
|
56
|
+
it('denies start-of-line grep', () => {
|
|
57
|
+
assert.ok(isDenied('Bash', { command: 'grep -r foo .' }));
|
|
58
|
+
assert.ok(isDenied('Bash', { command: 'grep foo bar' }));
|
|
59
|
+
assert.ok(isDenied('bash', { command: 'grep --include="*.ts" "pattern"' }));
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('denies start-of-line find', () => {
|
|
63
|
+
assert.ok(isDenied('Bash', { command: 'find . -name "*.ts"' }));
|
|
64
|
+
assert.ok(isDenied('execute_command', { command: 'find /var/log -mtime -1' }));
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it('denies start-of-line cat', () => {
|
|
68
|
+
assert.ok(isDenied('Bash', { command: 'cat file.ts' }));
|
|
69
|
+
assert.ok(isDenied('Bash', { command: 'cat src/index.ts' }));
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('denies start-of-line ls', () => {
|
|
73
|
+
assert.ok(isDenied('Bash', { command: 'ls -la' }));
|
|
74
|
+
assert.ok(isDenied('Bash', { command: 'ls .' }));
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
it('denies start-of-line rg', () => {
|
|
78
|
+
assert.ok(isDenied('Bash', { command: 'rg pattern' }));
|
|
79
|
+
assert.ok(isDenied('terminal', { command: 'rg "import.*from"' }));
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('denies start-of-line dir (Windows)', () => {
|
|
83
|
+
assert.ok(isDenied('Bash', { command: 'dir /b' }));
|
|
84
|
+
assert.ok(isDenied('Bash', { command: 'dir *.ts /s' }));
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('denies bare command (no args) for all patterns', () => {
|
|
88
|
+
assert.ok(isDenied('Bash', { command: 'grep' }));
|
|
89
|
+
assert.ok(isDenied('Bash', { command: 'find' }));
|
|
90
|
+
assert.ok(isDenied('Bash', { command: 'cat' }));
|
|
91
|
+
assert.ok(isDenied('Bash', { command: 'ls' }));
|
|
92
|
+
assert.ok(isDenied('Bash', { command: 'rg' }));
|
|
93
|
+
assert.ok(isDenied('Bash', { command: 'dir' }));
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
it('denies leading whitespace variants', () => {
|
|
97
|
+
assert.ok(isDenied('Bash', { command: ' grep foo' }));
|
|
98
|
+
assert.ok(isDenied('Bash', { command: '\tfind .' }));
|
|
99
|
+
});
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
describe('bash-guard — deny chained/piped bypass attempts', () => {
|
|
103
|
+
it('denies ;-chained grep', () => {
|
|
104
|
+
assert.ok(isDenied('Bash', { command: 'cd /tmp; grep foo' }));
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('denies ;-chained find', () => {
|
|
108
|
+
assert.ok(isDenied('Bash', { command: 'cd /tmp; find . -name "*.ts"' }));
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
it('denies &&-chained command', () => {
|
|
112
|
+
assert.ok(isDenied('Bash', { command: 'cd /tmp && grep foo' }));
|
|
113
|
+
assert.ok(isDenied('Bash', { command: 'npm build && cat result.txt' }));
|
|
114
|
+
});
|
|
115
|
+
|
|
116
|
+
it('denies ||-chained command', () => {
|
|
117
|
+
assert.ok(isDenied('Bash', { command: 'false || grep foo' }));
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
it('denies piped grep after another command', () => {
|
|
121
|
+
// Note: The chained pattern [;&|]{1,2} catches | grep mid-pipe too.
|
|
122
|
+
// This deliberately blocks all pipe-to-grep patterns.
|
|
123
|
+
assert.ok(isDenied('Bash', { command: 'npm test | grep fail' }));
|
|
124
|
+
assert.ok(isDenied('Bash', { command: 'git log | grep fix' }));
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
it('denies piped ls (ls also matched by start-of-line)', () => {
|
|
128
|
+
assert.ok(isDenied('Bash', { command: 'ls | grep foo' }));
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
it('denies chained cat', () => {
|
|
132
|
+
assert.ok(isDenied('Bash', { command: 'cd /tmp && cat config.json' }));
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
it('denies chained rg', () => {
|
|
136
|
+
assert.ok(isDenied('Bash', { command: 'ps aux; rg python' }));
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
it('denies chained dir', () => {
|
|
140
|
+
assert.ok(isDenied('Bash', { command: 'cd /tmp && dir /b' }));
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
describe('bash-guard — allow legitimate commands', () => {
|
|
145
|
+
it('allows git commands', () => {
|
|
146
|
+
assert.ok(!isDenied('Bash', { command: 'git log --oneline' }));
|
|
147
|
+
assert.ok(!isDenied('Bash', { command: 'git diff HEAD~1' }));
|
|
148
|
+
assert.ok(!isDenied('Bash', { command: 'git status' }));
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
it('allows npm commands', () => {
|
|
152
|
+
assert.ok(!isDenied('Bash', { command: 'npm install' }));
|
|
153
|
+
assert.ok(!isDenied('Bash', { command: 'npm run build' }));
|
|
154
|
+
assert.ok(!isDenied('Bash', { command: 'npx vitest run' }));
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
it('allows node commands', () => {
|
|
158
|
+
assert.ok(!isDenied('Bash', { command: 'node script.mjs' }));
|
|
159
|
+
assert.ok(!isDenied('Bash', { command: 'node --eval "console.log(1)"' }));
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
it('allows build commands (tsc, biome)', () => {
|
|
163
|
+
assert.ok(!isDenied('Bash', { command: 'tsc --noEmit' }));
|
|
164
|
+
assert.ok(!isDenied('Bash', { command: 'npx biome check .' }));
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it('allows process, network, utility commands', () => {
|
|
168
|
+
assert.ok(!isDenied('Bash', { command: 'ps aux' }));
|
|
169
|
+
assert.ok(!isDenied('Bash', { command: 'ping localhost' }));
|
|
170
|
+
assert.ok(!isDenied('Bash', { command: 'curl https://example.com' }));
|
|
171
|
+
assert.ok(!isDenied('Bash', { command: 'docker ps' }));
|
|
172
|
+
assert.ok(!isDenied('Bash', { command: 'mkdir -p dist' }));
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
it('allows commands with edge-case names that include substrings', () => {
|
|
176
|
+
// "catfish" starts with "cat" but the pattern requires \s or $
|
|
177
|
+
assert.ok(!isDenied('Bash', { command: 'catfish build' }));
|
|
178
|
+
// "grepify" same protection
|
|
179
|
+
assert.ok(!isDenied('Bash', { command: 'grepify --input file' }));
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
describe('bash-guard — non-Bash tool passthrough', () => {
|
|
184
|
+
it('allows any command from non-Bash tools', () => {
|
|
185
|
+
assert.ok(!isDenied('Read', { command: 'grep foo' }));
|
|
186
|
+
assert.ok(!isDenied('Glob', { command: 'find .' }));
|
|
187
|
+
assert.ok(!isDenied('Edit', { command: 'ls -la' }));
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
describe('bash-guard — edge cases', () => {
|
|
192
|
+
it('allows empty/whitespace commands', () => {
|
|
193
|
+
assert.ok(!isDenied('Bash', { command: '' }));
|
|
194
|
+
assert.ok(!isDenied('Bash', { command: ' ' }));
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
it('extracts command from alternative input fields', () => {
|
|
198
|
+
// toolInput.cmd
|
|
199
|
+
assert.ok(isDenied('Bash', { cmd: 'grep foo' }));
|
|
200
|
+
// toolInput.input
|
|
201
|
+
assert.ok(isDenied('Bash', { input: 'cat file.ts' }));
|
|
202
|
+
// toolInput.script
|
|
203
|
+
assert.ok(isDenied('Bash', { script: 'ls -la' }));
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it('handles missing toolInput gracefully', () => {
|
|
207
|
+
assert.ok(!isDenied('Bash', undefined));
|
|
208
|
+
assert.ok(!isDenied('Bash', {}));
|
|
209
|
+
});
|
|
210
|
+
|
|
211
|
+
it('allows commands that include grep as a substring argument', () => {
|
|
212
|
+
assert.ok(!isDenied('Bash', { command: 'npm install grep-from-npm' }));
|
|
213
|
+
});
|
|
214
|
+
});
|