@vpxa/aikit 0.1.273 → 0.1.275
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 +7 -1
- package/packages/cli/dist/index.js +14 -14
- package/packages/cli/dist/{init-DCs4TWh6.js → init-B3a2fygD.js} +1 -1
- package/packages/cli/dist/scaffold-BNPHP-QC.js +2 -0
- package/packages/cli/dist/{templates-C92mODRl.js → templates-CDa0UuoE.js} +19 -19
- package/packages/core/dist/index.d.ts +45 -17
- package/packages/core/dist/index.js +1 -1
- package/packages/flows/dist/index.d.ts +23 -2
- package/packages/flows/dist/index.js +1 -1
- package/packages/server/dist/bin.js +6 -6
- package/packages/server/dist/config-DZ-6Zy94.js +2 -0
- package/packages/server/dist/config-DxWyWSb9.js +1 -0
- package/packages/server/dist/curated-manager-C5uOPept.js +7 -0
- package/packages/server/dist/index.js +1 -1
- package/packages/server/dist/{promotion-BNEScZVD.js → promotion-D9anNXv8.js} +1 -1
- package/packages/server/dist/{routes-CR3fI-HJ.js → routes-1wkXLxXe.js} +1 -1
- package/packages/server/dist/{routes-Afg7J7xK.js → routes-KC-D2U8n.js} +1 -1
- package/packages/server/dist/{server-4h0Cclv3.js → server-CkCRBlz4.js} +93 -93
- package/packages/server/dist/{server-DIz2FGOX.js → server-DlE6A6sd.js} +93 -93
- package/packages/server/dist/{version-check-gazMo-D4.js → version-check-CgfflkJX.js} +1 -1
- package/packages/server/dist/{version-check-BgHzxxCW.js → version-check-ruLtfyDd.js} +1 -1
- package/packages/server/viewers/canvas.html +2 -1
- package/packages/server/viewers/task-plan-static.html +2 -1
- package/packages/tools/dist/index.d.ts +5 -5
- package/packages/tools/dist/index.js +72 -72
- package/scaffold/dist/adapters/copilot.mjs +19 -19
- package/scaffold/dist/definitions/hooks.mjs +1 -1
- package/scaffold/dist/definitions/skills/c4-architecture.mjs +1 -1
- package/scaffold/dist/definitions/skills/session-handoff.mjs +2 -732
- package/packages/cli/dist/scaffold-BnhmnBfn.js +0 -2
- package/packages/server/dist/config-CZuVxRpX.js +0 -1
- package/packages/server/dist/config-WpN5CWM7.js +0 -2
- package/packages/server/dist/curated-manager-CfwN96rp.js +0 -7
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import{createRequire as e}from"node:module";import{readFileSync as t}from"node:fs";import{dirname as n,resolve as r}from"node:path";import{fileURLToPath as i}from"node:url";import{
|
|
2
|
-
`))console.log(` ${e}`)}}function
|
|
1
|
+
import{createRequire as e}from"node:module";import{readFileSync as t}from"node:fs";import{dirname as n,resolve as r}from"node:path";import{fileURLToPath as i}from"node:url";import{resolveStateDir as a}from"../../core/dist/index.js";import{createSqliteAdapter as o,createStateStore as s}from"../../store/dist/index.js";import{mkdir as c}from"node:fs/promises";async function l(e=process.cwd()){let t=a(r(e));return await c(t,{recursive:!0}),s(await o(r(t,`state.db`)))}function u(){let t=e(import.meta.url);try{return t.resolve(`@vpxa/aikit/package.json`)}catch{return r(i(import.meta.url),`..`,`..`,`..`,`..`,`package.json`)}}function d(){return n(u())}function f(){try{return JSON.parse(t(u(),`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}function p(){let t=e(import.meta.url);try{return r(n(t.resolve(`@aikit/server`)),`bin.js`)}catch{return r(d(),`packages`,`server`,`dist`,`bin.js`)}}function m(e,t,n){let r=e.indexOf(t);if(r===-1||r+1>=e.length)return n;let i=Number.parseInt(e.splice(r,2)[1],10);return Number.isNaN(i)?n:i}function h(e,t,n){let r=e.indexOf(t);return r===-1||r+1>=e.length?n:e.splice(r,2)[1]}function g(e,t){let n=e.indexOf(t);return n===-1?!1:(e.splice(n,1),!0)}async function _(){if(process.stdin.isTTY)return``;let e=[];for await(let t of process.stdin)e.push(t);return Buffer.concat(e).toString(`utf-8`)}function v(e){return e.split(`,`).map(e=>e.trim()).filter(Boolean)}function y(e){return e.map(e=>{let t=e.heading?` ${e.heading}`:``;return`${e.start}-${e.end}${t}`}).join(`, `)}function b(e){switch(e.tool){case`tsc`:case`biome`:console.log(`${e.tool} errors: ${e.errors.length}`);for(let t of e.errors){let e=[t.line,t.column].filter(e=>e!==void 0).join(`:`),n=e?`${t.file}:${e}`:t.file,r=t.code?` ${t.code}`:``;console.log(`- ${n} [${t.severity}${r}] ${t.message}`)}return;case`vitest`:console.log(`Vitest summary`),console.log(` Passed: ${e.summary.passed}`),console.log(` Failed: ${e.summary.failed}`),console.log(` Skipped: ${e.summary.skipped}`),e.summary.duration!==void 0&&console.log(` Duration: ${e.summary.duration}ms`);for(let t of e.summary.tests)t.status===`fail`&&(console.log(`- ${t.name}${t.file?` (${t.file})`:``}`),t.error&&console.log(` ${t.error}`));return;case`git-status`:console.log(`Branch: ${e.status.branch??`unknown`}`),console.log(`Staged: ${e.status.staged.length}`);for(let t of e.status.staged)console.log(` ${t.status} ${t.file}`);console.log(`Unstaged: ${e.status.unstaged.length}`);for(let t of e.status.unstaged)console.log(` ${t.status} ${t.file}`);console.log(`Untracked: ${e.status.untracked.length}`);for(let t of e.status.untracked)console.log(` ?? ${t}`);return}}function x(e){console.log(`Overall: ${e.passed?`passed`:`failed`}`),S(`tsc`,e.tsc.passed,e.tsc.errors),S(`biome`,e.biome.passed,e.biome.errors)}function S(e,t,n){console.log(`${e}: ${t?`passed`:`${n.length} issue(s)`}`);for(let e of n){let t=[e.line,e.column].filter(e=>e!==void 0).join(`:`),n=t?`${e.file}:${t}`:e.file,r=e.code?` ${e.code}`:``;console.log(` - ${n} [${e.severity}${r}] ${e.message}`)}}function C(e){console.log(`Vitest: ${e.passed?`passed`:`failed`}`),console.log(` Duration: ${e.durationMs}ms`),console.log(` Passed: ${e.summary.passed}`),console.log(` Failed: ${e.summary.failed}`),console.log(` Skipped: ${e.summary.skipped}`),e.summary.suites!==void 0&&console.log(` Suites: ${e.summary.suites}`);let t=e.summary.tests.filter(e=>e.status===`fail`);if(t.length!==0){console.log(`Failed tests:`);for(let e of t)console.log(` - ${e.name}${e.file?` (${e.file})`:``}`),e.error&&console.log(` ${e.error}`)}}function w(e){console.log(`Branch: ${e.branch}`),console.log(`Staged: ${e.status.staged.length}`);for(let t of e.status.staged)console.log(` - ${t}`);console.log(`Modified: ${e.status.modified.length}`);for(let t of e.status.modified)console.log(` - ${t}`);console.log(`Untracked: ${e.status.untracked.length}`);for(let t of e.status.untracked)console.log(` - ${t}`);if(console.log(``),console.log(`Recent commits:`),e.recentCommits.length===0)console.log(` none`);else for(let t of e.recentCommits)console.log(` - ${t.hash} ${t.message}`),console.log(` ${t.author} @ ${t.date}`);e.diff&&(console.log(``),console.log(`Diff stat:`),console.log(e.diff))}function T(e){if(e.length===0){console.log(`No diff files found.`);return}for(let t of e){let e=t.oldPath?` (from ${t.oldPath})`:``;console.log(`${t.path}${e}`),console.log(` Status: ${t.status}`),console.log(` Changes: +${t.additions} -${t.deletions}`),console.log(` Hunks: ${t.hunks.length}`);for(let e of t.hunks){let t=e.header?` ${e.header}`:``;console.log(` @@ -${e.oldStart},${e.oldLines} +${e.newStart},${e.newLines} @@${t}`)}}}function E(e){if(console.log(`Start: ${e.start}`),console.log(`Direction: ${e.direction}`),console.log(`Depth reached: ${e.depth}`),console.log(`Nodes: ${e.nodes.length}`),e.nodes.length===0){console.log(`No trace nodes found.`);return}for(let t of e.nodes)console.log(` - [${t.relationship}] ${t.path}:${t.line} ${t.symbol}`)}function D(e){if(console.log(`Query: ${e.query}`),console.log(`Examples: ${e.examples.length} shown (${e.totalFound} total)`),e.examples.length===0){console.log(`No matching examples found.`);return}for(let t of e.examples){console.log(``),console.log(`${t.path}:${t.startLine}-${t.endLine}`),console.log(` Context: ${t.context}`),console.log(` Relevance: ${(t.relevance*100).toFixed(1)}%`);for(let e of t.content.split(`
|
|
2
|
+
`))console.log(` ${e}`)}}function O(e){console.log(e.id),console.log(` Command: ${e.command}${e.args.length>0?` ${e.args.join(` `)}`:``}`),console.log(` PID: ${e.pid??`unknown`}`),console.log(` Status: ${e.status}`),console.log(` Started: ${e.startedAt}`),e.exitCode!==void 0&&console.log(` Exit code: ${e.exitCode}`),console.log(` Logs: ${e.logs.length}`)}function k(e){if(console.log(`Exports scanned: ${e.totalExports}`),console.log(`Dead in source: ${e.totalDeadSource} (actionable)`),console.log(`Dead in docs: ${e.totalDeadDocs} (informational)`),e.totalDeadSource===0&&e.totalDeadDocs===0){console.log(`No dead symbols found.`);return}if(e.deadInSource.length>0){console.log(`
|
|
3
3
|
Dead in source (actionable):`);for(let t of e.deadInSource)console.log(` - ${t.path}:${t.line} ${t.kind} ${t.name}`)}if(e.deadInDocs.length>0){console.log(`
|
|
4
|
-
Dead in docs (informational):`);for(let t of e.deadInDocs)console.log(` - ${t.path}:${t.line} ${t.kind} ${t.name}`)}}function
|
|
5
|
-
`))console.log(` ${t}`)}function
|
|
4
|
+
Dead in docs (informational):`);for(let t of e.deadInDocs)console.log(` - ${t.path}:${t.line} ${t.kind} ${t.name}`)}}function A(e){console.log(e.path),console.log(` Language: ${e.language}`),console.log(` Lines: ${e.lines}`),console.log(` Estimated tokens: ~${e.estimatedTokens}`),console.log(``),P(`Imports`,e.imports),P(`Exports`,e.exports),P(`Functions`,e.functions.map(e=>`${e.name} @ line ${e.line}${e.exported?` [exported]`:``}`)),P(`Classes`,e.classes.map(e=>`${e.name} @ line ${e.line}${e.exported?` [exported]`:``}`)),P(`Interfaces`,e.interfaces.map(e=>`${e.name} @ line ${e.line}`)),P(`Types`,e.types.map(e=>`${e.name} @ line ${e.line}`))}function j(e){if(console.log(`Symbol: ${e.name}`),e.definedIn?console.log(`Defined in: ${e.definedIn.path}:${e.definedIn.line} (${e.definedIn.kind})`):console.log(`Defined in: not found`),console.log(``),console.log(`Imported by:`),e.importedBy.length===0)console.log(` none`);else for(let t of e.importedBy)console.log(` - ${t.path}:${t.line} ${t.importStatement}`);if(console.log(``),console.log(`Referenced in:`),e.referencedIn.length===0)console.log(` none`);else for(let t of e.referencedIn)console.log(` - ${t.path}:${t.line} ${t.context}`)}function M(e){console.log(e.name),console.log(` Files: ${e.files.length}`),console.log(` Updated: ${e.updated}`),e.description&&console.log(` Description: ${e.description}`);for(let t of e.files)console.log(` - ${t}`)}function N(e){let t=Array.isArray(e.data.files)?e.data.files.filter(e=>typeof e==`string`):[];if(console.log(e.id),console.log(` Label: ${e.label}`),console.log(` Created: ${e.createdAt}`),e.notes&&console.log(` Notes: ${e.notes}`),t.length>0){console.log(` Files: ${t.length}`);for(let e of t)console.log(` - ${e}`)}console.log(` Data:`);for(let t of JSON.stringify(e.data,null,2).split(`
|
|
5
|
+
`))console.log(` ${t}`)}function P(e,t){if(console.log(`${e}:`),t.length===0){console.log(` none`),console.log(``);return}for(let e of t)console.log(` - ${e}`);console.log(``)}function F(e){let t=e.trim();if(!t)return``;try{return JSON.parse(t)}catch{return e}}function I(e){let t=e.trim();if(!t)return{};let n=JSON.parse(t);if(!n||typeof n!=`object`||Array.isArray(n))throw Error(`Checkpoint data must be a JSON object.`);return n}function ee(e,t,n=60){let r=new Map;for(let t=0;t<e.length;t++){let i=e[t];r.set(i.record.id,{record:i.record,score:1/(n+t+1)})}for(let e=0;e<t.length;e++){let i=t[e],a=r.get(i.record.id);a?a.score+=1/(n+e+1):r.set(i.record.id,{record:i.record,score:1/(n+e+1)})}return[...r.values()].sort((e,t)=>t.score-e.score)}const L=[`const{execSync:x}=require('child_process')`,`const{existsSync:e,renameSync:m}=require('fs')`,`const{join:j}=require('path')`,`const c=j(process.env.LOCALAPPDATA||process.env.HOME||'','npm-cache')`,`const s={stdio:'inherit'}`,`try{x('npx -y @vpxa/aikit@latest serve',s)}catch{try{const d=j(c,'_npx');if(e(d))m(d,j(c,'_npx_'+Date.now()))}catch{};try{x('npm cache verify',{stdio:'ignore',timeout:30000})}catch{};try{x('npx -y @vpxa/aikit@latest serve',s)}catch(e){process.stderr.write('aikit: all recovery attempts failed. Run: npm cache clean --force && npx -y @vpxa/aikit@latest serve');process.exit(1)}}`].join(`;`),R=`aikit`,z={type:`stdio`,command:`node`,args:[`-e`,L]},B=[`aikit`,`brainstorming`,`multi-agents-development`,`session-handoff`,`requirements-clarity`,`lesson-learned`,`c4-architecture`,`adr-skill`,`present`,`frontend-design`,`react`,`typescript`,`docs`,`repo-access`],V=[`aikit-basic`,`aikit-advanced`,`_epilogue`],H={"chat.agentFilesLocations":{"~/.claude/agents":!1},"chat.useClaudeMdFile":!1,"github.copilot.chat.copilotMemory.enabled":!0,"chat.customAgentInSubagent.enabled":!0,"chat.useNestedAgentsMdFiles":!0,"chat.useAgentSkills":!0,"github.copilot.chat.switchAgent.enabled":!0,"workbench.browser.enableChatTools":!0,"chat.mcp.apps.enabled":!0,"chat.instructionsFilesLocations":{"~/.copilot/instructions":!0,".github/instructions":!0,".claude/rules":!1,"~/.claude/rules":!1}};function U(e){return`
|
|
6
6
|
## Flow Context Bootstrap
|
|
7
7
|
|
|
8
8
|
When dispatched as a subagent within an active flow:
|
|
@@ -21,17 +21,17 @@ When dispatched as a subagent within an active flow:
|
|
|
21
21
|
|
|
22
22
|
${e===`<PROFILE>`?`**Profile:** Check your role → implementer | documenter | reviewer | researcher | debugger`:`**Profile:** \`${e}\``}
|
|
23
23
|
|
|
24
|
-
---`}function
|
|
24
|
+
---`}function W(){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 G(...e){return e.filter(Boolean).join(`
|
|
25
25
|
|
|
26
|
-
`)}const G
|
|
27
|
-
`).replace(/\\r/g,`\r`).replace(/\\t/g,` `).replace(/\\\\/g,`\\`)}function
|
|
26
|
+
`)}const K=G(`## Output Rules (HARD RULE)`,`**Plain text is allowed only when ALL are true:**`,` - Response is 1-2 short sentences.`,` - No table, list, checklist, plan, report, verdict, review, summary, progress, evidence map, or batch result is being returned.`,` - No user approval, mandatory stop, or choice is needed.`,"Follow the **Presentation Priority** (1st Inline Visual - `present({ schemaVersion: 1, title, blocks })` → 2nd Interactive - `present({ schemaVersion: 1, title, blocks, actions })` → 3rd Plain Text). Only tiny status/questions that pass the gate above → plain text (Priority 3). Prefer `present` for all others, especially summaries, comparisons, reports, task plans, verdicts, and progress."),q=G(`## AI Kit Recovery`,"If AI Kit tools are unavailable or missing, run `npx -y @vpxa/aikit@latest init --user`, then reload the client so the `aikit` MCP server and user instructions become available.");`${U(`<PROFILE>`)}`,`${U(`researcher`)}`,`${U(`reviewer`)}${W()}`,`${U(`reviewer`)}${W()}`;const J=/{\s*name:\s*'((?:\\.|[^'])*)',\s*rationale:\s*'((?:\\.|[^'])*)',\s*bitterLessonSafe:\s*(?:true|false),\s*}/g;let Y=null;function X(e){return e.replace(/\\'/g,`'`).replace(/\\n/g,`
|
|
27
|
+
`).replace(/\\r/g,`\r`).replace(/\\t/g,` `).replace(/\\\\/g,`\\`)}function Z(){if(Y)return Y;let e=r(d(),`scaffold`,`definitions`,`exclusions.mjs`),n=t(e,`utf8`),i=Array.from(n.matchAll(J),([,e,t])=>({name:X(e),rationale:X(t)}));if(i.length===0)throw Error(`Failed to parse permanent exclusions from ${e}`);return Y=i,i}function Q(e){return e.replace(/\|/g,`\\|`).replace(/\r?\n+/g,` `).trim()}function $(){return`## Permanent Exclusions
|
|
28
28
|
|
|
29
29
|
These capabilities are intentionally NOT provided by aikit. Each decision follows the Bitter Lesson: leverage computation and configurable tools over hand-crafted features.
|
|
30
30
|
|
|
31
31
|
| Capability | Rationale |
|
|
32
32
|
|-----------|-----------|
|
|
33
|
-
${
|
|
34
|
-
`)}`}function
|
|
33
|
+
${Z().map(({name:e,rationale:t})=>`| ${Q(e)} | ${Q(t)} |`).join(`
|
|
34
|
+
`)}`}function te(e,t){return`# ${e} — Copilot Instructions
|
|
35
35
|
|
|
36
36
|
This project has an MCP server (\`${t}\`) providing 64 tools for search, analysis, memory, and validation.
|
|
37
37
|
**These tools REPLACE most native IDE tools.** You MUST use them.
|
|
@@ -86,7 +86,7 @@ Even then, use \`file_summary\` first to identify which lines to read.
|
|
|
86
86
|
4. **Validate** — \`check({})\` + \`test_run({})\` before presenting changes. \`blast_radius({ changed_files })\` for impact.
|
|
87
87
|
5. **Lifecycle** — Check \`status({})\` first. If onboard not run, run \`onboard({ path: "." })\`. After implementation, \`reindex({})\` + \`produce_knowledge({})\`. At session end, \`remember()\` checkpoint.
|
|
88
88
|
|
|
89
|
-
${
|
|
89
|
+
${$()}
|
|
90
90
|
|
|
91
91
|
## User Interaction Rules
|
|
92
92
|
|
|
@@ -95,8 +95,8 @@ When you need to explain something or ask for user input:
|
|
|
95
95
|
| Situation | Method | Details |
|
|
96
96
|
|-----------|--------|---------|
|
|
97
97
|
| Simple explanation + question | **Elicitation** | Text-only context is sufficient; ask via elicitation fields |
|
|
98
|
-
| Rich content + question | **\`present
|
|
99
|
-
| Complex visual + interaction | **\`present
|
|
98
|
+
| Rich content + question | **\`present\`** + **Elicitation** | Use \`present({ schemaVersion: 1, title, blocks })\` for visual explanation, then elicitation for user input |
|
|
99
|
+
| Complex visual + interaction | **\`present\`** | Use \`present({ schemaVersion: 1, title, blocks, actions })\` for interactive UI; confirmations and selections can use actions, other input uses elicitation |
|
|
100
100
|
|
|
101
101
|
**Rules:**
|
|
102
102
|
- Never dump long tables or complex visuals as plain text — use \`present\` to render them
|
|
@@ -104,7 +104,7 @@ When you need to explain something or ask for user input:
|
|
|
104
104
|
- Free-form text input always goes through elicitation, even when using \`present\` for the explanation
|
|
105
105
|
- Prefer the simplest method that adequately conveys the information
|
|
106
106
|
|
|
107
|
-
${
|
|
107
|
+
${K}
|
|
108
108
|
|
|
109
109
|
## Communication Style
|
|
110
110
|
|
|
@@ -150,9 +150,9 @@ Auto-knowledge also captures facts automatically from tool outputs (conventions
|
|
|
150
150
|
| Store | \`remember\` | \`knowledge({ action: "remember", title: "Auth uses JWT RS256", content: "...", category: "decisions" })\` |
|
|
151
151
|
| Search | \`search\` | \`search({ query: "authentication", origin: "curated" })\` |
|
|
152
152
|
| Browse | \`list\` | \`knowledge({ action: "list" })\` or \`knowledge({ action: "list", category: "decisions" })\` |
|
|
153
|
-
| Read | \`read\` | \`knowledge({ action: "read",
|
|
154
|
-
| Update | \`update\` | \`knowledge({ action: "update",
|
|
155
|
-
| Remove | \`forget\` | \`knowledge({ action: "forget",
|
|
153
|
+
| Read | \`read\` | \`knowledge({ action: "read", path: "<entry-path>" })\` |
|
|
154
|
+
| Update | \`update\` | \`knowledge({ action: "update", path: "<entry-path>", content: "Updated info", reason: "Refresh stored guidance" })\` |
|
|
155
|
+
| Remove | \`forget\` | \`knowledge({ action: "forget", path: "<entry-path>" })\` |
|
|
156
156
|
| Withdraw | \`withdraw\` | \`knowledge({ action: "withdraw", scope: "flow:<run-id>", profile: "implementer", budget: 4000 })\` |
|
|
157
157
|
| Flush | \`flush\` | \`knowledge({ action: "flush", scope: "flow:<run-id>" })\` |
|
|
158
158
|
|
|
@@ -178,8 +178,8 @@ knowledge({ action: "remember", title: "Session checkpoint: <topic>", content:
|
|
|
178
178
|
search({ query: "SESSION CHECKPOINT", origin: "curated" })
|
|
179
179
|
\`\`\`
|
|
180
180
|
|
|
181
|
-
${
|
|
182
|
-
`}function
|
|
181
|
+
${q}
|
|
182
|
+
`}function ne(e,t){return`# ${e} — Agent Instructions
|
|
183
183
|
|
|
184
184
|
## AI Kit MCP Server (\`${t}\`)
|
|
185
185
|
|
|
@@ -295,4 +295,4 @@ Both ReactFlow viewers include an **AI Kit** attribution badge (bottom-right). A
|
|
|
295
295
|
## Full Documentation
|
|
296
296
|
|
|
297
297
|
For complete tool documentation (62 tools), workflow chains, search strategies, session protocol, and persistent memory patterns, load the \`aikit\` skill at session start.
|
|
298
|
-
`}export{
|
|
298
|
+
`}export{_ as A,w as C,C as D,j as E,ee as M,v as N,E as O,A as S,b as T,x as _,R as a,T as b,l as c,h as d,y as f,I as g,F as h,z as i,p as j,M as k,g as l,f as m,te as n,B as o,d as p,V as r,H as s,ne as t,m as u,N as v,O as w,D as x,k as y};
|
|
@@ -96,23 +96,42 @@ declare class CircuitOpenError extends Error {
|
|
|
96
96
|
* Single source of truth — change here to update everywhere.
|
|
97
97
|
*/
|
|
98
98
|
declare const AIKIT_PATHS: {
|
|
99
|
-
/** AI
|
|
99
|
+
/** AI Kit runtime root directory */readonly root: ".aikit"; /** AI artifacts root directory */
|
|
100
|
+
readonly ai: ".ai"; /** Onboard / produce_knowledge output directory */
|
|
100
101
|
readonly aiContext: ".ai/context"; /** Curated knowledge directory */
|
|
101
102
|
readonly aiCurated: ".ai/curated"; /** Restore points for destructive operations (codemod, rename, forget) */
|
|
102
103
|
readonly restorePoints: ".ai/restore-points"; /** Vector store + graph data */
|
|
103
|
-
readonly data: ".aikit
|
|
104
|
-
readonly state: ".aikit
|
|
105
|
-
readonly logs: ".aikit
|
|
104
|
+
readonly data: ".aikit/data"; /** Session state (stash, lanes, checkpoints, worksets, queues, replay, evidence-maps, snippets) */
|
|
105
|
+
readonly state: ".aikit/state"; /** Persistent warn/error logs for dogfooding review */
|
|
106
|
+
readonly logs: ".aikit/logs"; /** Brainstorming sessions */
|
|
106
107
|
readonly brainstorm: ".brainstorm"; /** Session handoff documents */
|
|
107
108
|
readonly handoffs: ".handoffs";
|
|
108
109
|
};
|
|
109
110
|
/**
|
|
110
|
-
*
|
|
111
|
+
* Runtime directories stored inside ~/.aikit/workspaces/<partition>/.
|
|
112
|
+
* These are the default durable locations for non-flow runtime artifacts.
|
|
113
|
+
*/
|
|
114
|
+
declare const AIKIT_RUNTIME_PATHS: {
|
|
115
|
+
/** Vector store + graph data directory */readonly data: "data"; /** Curated knowledge directory */
|
|
116
|
+
readonly curated: "curated"; /** Onboard / produce_knowledge output directory */
|
|
117
|
+
readonly onboard: "onboard"; /** Session state directory */
|
|
118
|
+
readonly state: "state"; /** Restore points for destructive operations */
|
|
119
|
+
readonly restorePoints: "restore-points"; /** Brainstorming sessions */
|
|
120
|
+
readonly brainstorm: "brainstorm"; /** Session handoff documents */
|
|
121
|
+
readonly handoffs: "handoffs";
|
|
122
|
+
};
|
|
123
|
+
/**
|
|
124
|
+
* Global-mode directory paths (under ~/.aikit/).
|
|
111
125
|
* Used when AI Kit is installed at user level rather than per-workspace.
|
|
112
126
|
*/
|
|
113
127
|
declare const AIKIT_GLOBAL_PATHS: {
|
|
114
|
-
/** Root directory name for global data store */readonly root: ".aikit
|
|
115
|
-
readonly registry: "registry.json";
|
|
128
|
+
/** Root directory name for global data store */readonly root: ".aikit"; /** Registry file tracking all enrolled workspaces */
|
|
129
|
+
readonly registry: "registry.json"; /** Workspace partitions directory */
|
|
130
|
+
readonly workspaces: "workspaces"; /** Shared runtime logs directory */
|
|
131
|
+
readonly logs: "logs"; /** Shared state migration target for legacy home-level state */
|
|
132
|
+
readonly state: "state"; /** Legacy global data directory name */
|
|
133
|
+
readonly legacyDataRoot: ".aikit-data"; /** Legacy global state directory name */
|
|
134
|
+
readonly legacyStateRoot: ".aikit-state";
|
|
116
135
|
};
|
|
117
136
|
/** Default chunk sizes by content type */
|
|
118
137
|
declare const CHUNK_SIZES: {
|
|
@@ -144,7 +163,7 @@ declare const EMBEDDING_DEFAULTS: {
|
|
|
144
163
|
/** Default store config */
|
|
145
164
|
declare const STORE_DEFAULTS: {
|
|
146
165
|
readonly backend: "sqlite-vec";
|
|
147
|
-
readonly path: ".aikit
|
|
166
|
+
readonly path: ".aikit/data";
|
|
148
167
|
readonly tableName: "knowledge";
|
|
149
168
|
};
|
|
150
169
|
/** File size limits */
|
|
@@ -339,7 +358,7 @@ interface AikitConfig {
|
|
|
339
358
|
};
|
|
340
359
|
/** Resolved directory for onboard/produce_knowledge output. User-level mode redirects this outside the project. */
|
|
341
360
|
onboardDir?: string;
|
|
342
|
-
/** Resolved state directory path. User-level mode redirects this to the partition. Defaults to `.aikit
|
|
361
|
+
/** Resolved state directory path. User-level mode redirects this to the partition. Defaults to `.aikit/state` in workspace root. */
|
|
343
362
|
stateDir?: string;
|
|
344
363
|
/**
|
|
345
364
|
* All workspace roots provided by the MCP client (IDE).
|
|
@@ -448,7 +467,7 @@ declare function isPermanent(error: unknown): error is PermanentError;
|
|
|
448
467
|
//#region packages/core/src/global-registry.d.ts
|
|
449
468
|
/**
|
|
450
469
|
* Global registry for tracking workspaces enrolled in global MCP install mode.
|
|
451
|
-
* Registry lives at ~/.aikit
|
|
470
|
+
* Registry lives at ~/.aikit/registry.json alongside per-workspace partition directories.
|
|
452
471
|
*/
|
|
453
472
|
/** A single workspace entry in the global registry. */
|
|
454
473
|
interface RegistryEntry {
|
|
@@ -461,11 +480,21 @@ interface RegistryEntry {
|
|
|
461
480
|
/** ISO timestamp of last server start */
|
|
462
481
|
lastAccessedAt: string;
|
|
463
482
|
}
|
|
464
|
-
/** Schema for ~/.aikit
|
|
483
|
+
/** Schema for ~/.aikit/registry.json */
|
|
465
484
|
interface GlobalRegistry {
|
|
466
485
|
version: 1;
|
|
467
486
|
workspaces: Record<string, RegistryEntry>;
|
|
468
487
|
}
|
|
488
|
+
/**
|
|
489
|
+
* Get the partition directory for a workspace under ~/.aikit/workspaces/.
|
|
490
|
+
*/
|
|
491
|
+
declare function getWorkspacePartitionDir(cwd: string): string;
|
|
492
|
+
declare function migrateLegacyWorkspaceLayout(workspaceRoot: string): void;
|
|
493
|
+
/**
|
|
494
|
+
* Resolve the state directory for a workspace root.
|
|
495
|
+
* Always routes to ~/.aikit/workspaces/<partition>/state/.
|
|
496
|
+
*/
|
|
497
|
+
declare function resolveStateDir(cwd: string): string;
|
|
469
498
|
/**
|
|
470
499
|
* Get the global data directory root.
|
|
471
500
|
* Override with `AIKIT_GLOBAL_DATA_DIR` env var for testing.
|
|
@@ -503,15 +532,14 @@ declare function listWorkspaces(): RegistryEntry[];
|
|
|
503
532
|
*/
|
|
504
533
|
declare function getPartitionDir(partition: string): string;
|
|
505
534
|
/**
|
|
506
|
-
* Check whether user-level mode is installed (registry.json exists in ~/.aikit
|
|
535
|
+
* Check whether user-level mode is installed (registry.json exists in ~/.aikit/).
|
|
507
536
|
*/
|
|
508
537
|
declare function isUserInstalled(): boolean;
|
|
509
538
|
/**
|
|
510
|
-
* Resolve the
|
|
511
|
-
*
|
|
512
|
-
* - Workspace-level install: `<cwd>/.aikit-state/`
|
|
539
|
+
* Resolve the shared runtime log directory.
|
|
540
|
+
* Logs always live under the home-level ~/.aikit/logs directory.
|
|
513
541
|
*/
|
|
514
|
-
declare function
|
|
542
|
+
declare function resolveLogDir(): string;
|
|
515
543
|
//#endregion
|
|
516
544
|
//#region packages/core/src/health-bus.d.ts
|
|
517
545
|
type HealthStatus = 'healthy' | 'degraded' | 'unavailable';
|
|
@@ -632,4 +660,4 @@ interface RetryOptions {
|
|
|
632
660
|
*/
|
|
633
661
|
declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
634
662
|
//#endregion
|
|
635
|
-
export { AIKIT_GLOBAL_PATHS, AIKIT_PATHS, AikitConfig, AikitError, CATEGORY_PATTERN, CHUNK_SIZES, CONTENT_TYPES, ChunkMetadata, CircuitBreaker, CircuitBreakerOptions, CircuitOpenError, CircuitState, ConfigError, ContentType, DEFAULT_CATEGORIES, EMBEDDING_DEFAULTS, EmbeddingError, FILE_LIMITS, GlobalRegistry, HealthBus, HealthEvent, HealthStatus, INDEX_MODES, IndexError, IndexMode, IndexStats, KNOWLEDGE_ORIGINS, KnowledgeOrigin, KnowledgeRecord, LogLevel, LogListener, PermanentError, RawChunk, RegistryEntry, RetryOptions, SEARCH_DEFAULTS, SOURCE_TYPES, STORE_DEFAULTS, SearchResult, SourceType, StoreError, SubsystemHealth, SupersessionConfig, TOKEN_BUDGETS, TokenBudget, TransientError, addLogListener, computePartitionKey, contentTypeToSourceType, createLogger, detectContentType, getGlobalDataDir, getLogLevel, getPartitionDir, isPermanent, isTransient, isUserInstalled, listWorkspaces, loadRegistry, lookupWorkspace, registerWorkspace, resetLogDir, resolveStateDir, saveRegistry, serializeError, setDetailedErrorLoggingEnabled, setFileSinkEnabled, setLogLevel, sourceTypeContentTypes, withRetry };
|
|
663
|
+
export { AIKIT_GLOBAL_PATHS, AIKIT_PATHS, AIKIT_RUNTIME_PATHS, AikitConfig, AikitError, CATEGORY_PATTERN, CHUNK_SIZES, CONTENT_TYPES, ChunkMetadata, CircuitBreaker, CircuitBreakerOptions, CircuitOpenError, CircuitState, ConfigError, ContentType, DEFAULT_CATEGORIES, EMBEDDING_DEFAULTS, EmbeddingError, FILE_LIMITS, GlobalRegistry, HealthBus, HealthEvent, HealthStatus, INDEX_MODES, IndexError, IndexMode, IndexStats, KNOWLEDGE_ORIGINS, KnowledgeOrigin, KnowledgeRecord, LogLevel, LogListener, PermanentError, RawChunk, RegistryEntry, RetryOptions, SEARCH_DEFAULTS, SOURCE_TYPES, STORE_DEFAULTS, SearchResult, SourceType, StoreError, SubsystemHealth, SupersessionConfig, TOKEN_BUDGETS, TokenBudget, TransientError, addLogListener, computePartitionKey, contentTypeToSourceType, createLogger, detectContentType, getGlobalDataDir, getLogLevel, getPartitionDir, getWorkspacePartitionDir, isPermanent, isTransient, isUserInstalled, listWorkspaces, loadRegistry, lookupWorkspace, migrateLegacyWorkspaceLayout, registerWorkspace, resetLogDir, resolveLogDir, resolveStateDir, saveRegistry, serializeError, setDetailedErrorLoggingEnabled, setFileSinkEnabled, setLogLevel, sourceTypeContentTypes, withRetry };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{EventEmitter as e}from"node:events";import{basename as t,extname as n,join as r,resolve as i}from"node:path";import{createHash as a}from"node:crypto";import{appendFileSync as o,closeSync as s,constants as c,existsSync as l,mkdirSync as u,openSync as ee,readFileSync as te,readdirSync as d,renameSync as f,statSync as p,unlinkSync as m,writeFileSync as h}from"node:fs";import{homedir as ne}from"node:os";var g=class t extends e{static registry=new Map;state=`closed`;failures=0;halfOpenAttempts=0;openUntil=0;threshold;cooldownMs;halfOpenMaxAttempts;jitterMs;name;onStateChange;static getAll(){return t.registry}static get(e){return t.registry.get(e)}static clearRegistry(){t.registry.clear()}constructor(e={}){super(),this.threshold=Math.max(1,e.threshold??3),this.cooldownMs=Math.max(0,e.cooldownMs??6e4),this.halfOpenMaxAttempts=Math.max(1,e.halfOpenMaxAttempts??1),this.jitterMs=Math.max(0,e.jitterMs??0),this.name=e.name,this.onStateChange=e.onStateChange,this.name&&t.registry.set(this.name,this)}async execute(e){this.assertNotOpen();try{let t=await e();return this.recordSuccess(),t}catch(e){throw this.recordFailure(),e}}getState(){return this.refreshState(),this.state}getName(){return this.name}isOpen(){return this.getState()===`open`}reset(){this.failures=0,this.halfOpenAttempts=0,this.openUntil=0,this.transitionTo(`closed`,`manual reset`)}dispose(){this.name&&t.registry.get(this.name)===this&&t.registry.delete(this.name),this.removeAllListeners()}forceOpen(e){this.failures=this.threshold,this.halfOpenAttempts=0,this.transitionTo(`open`,e??`manual override`)}recordSuccess(){this.refreshState(),this.failures=0,this.halfOpenAttempts=0,this.state===`half-open`&&this.transitionTo(`closed`,`probe succeeded`)}recordFailure(){if(this.refreshState(),this.failures+=1,this.halfOpenAttempts=0,this.state===`half-open`){this.transitionTo(`open`,`probe failed`);return}this.state===`closed`&&this.failures>=this.threshold&&this.transitionTo(`open`,`failure threshold reached`)}remainingCooldownMs(){return this.refreshState(),this.state===`open`?Math.max(0,this.openUntil-Date.now()):0}assertNotOpen(){if(this.refreshState(),this.state===`open`)throw new _(this.remainingCooldownMs());if(this.state===`half-open`){if(this.halfOpenAttempts>=this.halfOpenMaxAttempts)throw this.transitionTo(`open`,`half-open probe limit reached`),new _(this.remainingCooldownMs());this.halfOpenAttempts+=1}}refreshState(){this.state===`open`&&Date.now()>=this.openUntil&&(this.halfOpenAttempts=0,this.transitionTo(`half-open`,`cooldown expired`))}transitionTo(e,t){let n=this.state;if(n===e){e===`open`&&(this.openUntil=this.computeOpenUntil());return}this.state=e,e===`open`?(this.openUntil=this.computeOpenUntil(),this.halfOpenAttempts=0):(this.openUntil=0,e===`closed`&&(this.halfOpenAttempts=0)),this.onStateChange?.(n,e),this.emit(e,{from:n,reason:t})}computeOpenUntil(){return Date.now()+this.cooldownMs+Math.floor(Math.random()*this.jitterMs)}},_=class extends Error{remainingMs;constructor(e){super(`Circuit breaker is open — ${Math.ceil(e/1e3)}s remaining`),this.remainingMs=e,this.name=`CircuitOpenError`}};const v={ai:`.ai`,aiContext:`.ai/context`,aiCurated:`.ai/curated`,restorePoints:`.ai/restore-points`,data:`.aikit-data`,state:`.aikit-state`,logs:`.aikit-state/logs`,brainstorm:`.brainstorm`,handoffs:`.handoffs`},y={root:`.aikit-data`,registry:`registry.json`},b={markdown:{max:1500,min:100},code:{max:2e3,min:50},config:{max:3e3,min:50},default:{max:1500,min:100,overlap:200}},x={model:`mixedbread-ai/mxbai-embed-large-v1`,nativeDim:1024,dimensions:512,queryPrefix:``},S={backend:`sqlite-vec`,path:v.data,tableName:`knowledge`},re={maxFileSizeBytes:1e6,maxCuratedFileSizeBytes:5e4},ie={maxResults:10,minScore:.25},ae=/^[a-z][a-z0-9-]*$/,oe=[`decisions`,`patterns`,`troubleshooting`,`conventions`,`architecture`],C={".ts":`code-typescript`,".tsx":`code-typescript`,".mts":`code-typescript`,".cts":`code-typescript`,".js":`code-javascript`,".jsx":`code-javascript`,".mjs":`code-javascript`,".cjs":`code-javascript`,".py":`code-python`,".json":`config-json`,".yaml":`config-yaml`,".yml":`config-yaml`,".toml":`config-toml`,".env":`config-env`,".md":`markdown`,".mdx":`markdown`},se=[/\.test\.[jt]sx?$/,/\.spec\.[jt]sx?$/,/(^|\/)__tests__\//,/(^|\/)test\//,/(^|\/)tests\//,/(^|\/)spec\//,/(^|\/)fixtures\//],ce=[/\.stack\.[jt]s$/,/(^|\/)stacks\//,/(^|\/)constructs\//,/cdk\.json$/];function le(e){let r=n(e).toLowerCase(),i=t(e).toLowerCase();return e.includes(`${v.aiContext}/`)?`produced-knowledge`:e.includes(`${v.aiCurated}/`)?`curated-knowledge`:se.some(t=>t.test(e))?`test-code`:ce.some(t=>t.test(e))?`cdk-stack`:r in C?C[r]:i.startsWith(`.env`)?`config-env`:[`.go`,`.rs`,`.java`,`.rb`,`.php`,`.sh`,`.ps1`,`.sql`,`.graphql`,`.proto`,`.css`,`.scss`,`.less`,`.html`,`.htm`,`.vue`,`.svelte`,`.astro`,`.hbs`,`.ejs`,`.svg`].includes(r)?`code-other`:`unknown`}const w={"code-typescript":`source`,"code-javascript":`source`,"code-python":`source`,"code-other":`source`,"cdk-stack":`source`,"test-code":`test`,markdown:`documentation`,documentation:`documentation`,"curated-knowledge":`documentation`,"produced-knowledge":`documentation`,"config-json":`config`,"config-yaml":`config`,"config-toml":`config`,"config-env":`config`,unknown:`source`};function ue(e){return w[e]??`source`}function de(e){return Object.entries(w).filter(([,t])=>t===e).map(([e])=>e)}var T=class extends Error{code;constructor(e,t,n){super(e,n===void 0?void 0:{cause:n}),this.code=t,this.name=`AikitError`}},fe=class extends T{constructor(e,t){super(e,`EMBEDDING_ERROR`,t),this.name=`EmbeddingError`}},pe=class extends T{constructor(e,t){super(e,`STORE_ERROR`,t),this.name=`StoreError`}},E=class extends T{constructor(e,t){super(e,`INDEX_ERROR`,t),this.name=`IndexError`}},D=class extends T{constructor(e,t){super(e,`CONFIG_ERROR`,t),this.name=`ConfigError`}},O=class extends T{retryAfterMs;constructor(e,t,n){super(e,`TRANSIENT_ERROR`,n),this.retryAfterMs=t,this.name=`TransientError`}},k=class extends T{constructor(e,t){super(e,`PERMANENT_ERROR`,t),this.name=`PermanentError`}};function A(e){return e instanceof O}function j(e){return e instanceof k}function M(){return process.env.AIKIT_GLOBAL_DATA_DIR??i(ne(),y.root)}function N(e){let n=i(e);return`${t(n).toLowerCase().replace(/[^a-z0-9-]/g,`-`)||`workspace`}-${a(`sha256`).update(n).digest(`hex`).slice(0,8)}`}function P(){let e=i(M(),y.registry);if(!l(e))return{version:1,workspaces:{}};let t=te(e,`utf-8`);try{return JSON.parse(t)}catch{return{version:1,workspaces:{}}}}function F(e,t=5e3){let n=`${e}.lock`,r=Date.now()+t,i=10;for(;Date.now()<r;)try{let e=ee(n,c.O_CREAT|c.O_EXCL|c.O_WRONLY);return h(e,`${process.pid}\n`),s(e),n}catch(e){if(e.code!==`EEXIST`)throw e;try{let{mtimeMs:e}=p(n);if(Date.now()-e>3e4){m(n);continue}}catch{}let t=new SharedArrayBuffer(4);Atomics.wait(new Int32Array(t),0,0,i),i=Math.min(i*2,200)}throw Error(`Failed to acquire registry lock after ${t}ms`)}function I(e){try{m(e)}catch{}}function L(e){let t=M();u(t,{recursive:!0});let n=i(t,y.registry),r=F(n);try{let t=`${n}.tmp`;h(t,JSON.stringify(e,null,2),`utf-8`),f(t,n)}finally{I(r)}}function R(e){let t=P(),n=N(e),r=new Date().toISOString();return t.workspaces[n]?t.workspaces[n].lastAccessedAt=r:t.workspaces[n]={partition:n,workspacePath:i(e),registeredAt:r,lastAccessedAt:r},u(V(n),{recursive:!0}),L(t),t.workspaces[n]}function z(e){let t=P(),n=N(e);return t.workspaces[n]}function B(){let e=P();return Object.values(e.workspaces)}function V(e){return i(M(),e)}function H(){return l(i(M(),y.registry))}function U(e){return H()?i(V(R(e).partition),`state`):i(e,v.state)}var me=class t extends e{static _instance=null;subsystems=new Map;constructor(){super()}static instance(){return t._instance||=new t,t._instance}static reset(){t._instance?.removeAllListeners(),t._instance=null}register(e){this.subsystems.has(e)||this.subsystems.set(e,{name:e,status:`healthy`,since:Date.now()})}reportDegraded(e,t){this.transition(e,`degraded`,t)}reportUnavailable(e,t){this.transition(e,`unavailable`,t)}reportRecovered(e){this.transition(e,`healthy`)}isDegraded(e){let t=this.subsystems.get(e);return t?.status===`degraded`||t?.status===`unavailable`}isHealthy(e){return this.subsystems.get(e)?.status===`healthy`}getAll(){return Array.from(this.subsystems.values(),e=>({...e}))}getSubsystem(e){let t=this.subsystems.get(e);return t?{...t}:void 0}transition(e,t,n){let r=this.subsystems.get(e);if(!r||r.status===t)return;let i={subsystem:e,status:t,previousStatus:r.status,reason:n,timestamp:Date.now()};r.status=t,r.since=i.timestamp,r.reason=n,this.emit(t,i),this.emit(`change`,i)}};const W={debug:0,info:1,warn:2,error:3},G=[];let K=process.env.AIKIT_LOG_LEVEL??`info`,q=!1,J=process.env.AIKIT_LOG_FILE_SINK===`true`||process.env.AIKIT_LOG_FILE_SINK!==`false`&&!process.env.VITEST&&process.env.NODE_ENV!==`test`;function he(){return J?process.env.VITEST||process.env.NODE_ENV===`test`?process.env.AIKIT_LOG_FILE_SINK===`true`:!0:!1}let Y;function X(){return Y||=r(U(process.cwd()),`logs`),Y}function ge(e){let t=e.toISOString().slice(0,10);return r(X(),`${t}.jsonl`)}let Z=0;function _e(){let e=Date.now();if(!(e-Z<36e5)){Z=e;try{let t=X(),n=new Date(e-30*864e5).toISOString().slice(0,10);for(let e of d(t))if(e.endsWith(`.jsonl`)&&e.slice(0,10)<n)try{m(r(t,e))}catch{}}catch{}}}function ve(e,t){try{u(X(),{recursive:!0}),o(ge(t),`${e}\n`),_e()}catch{}}function ye(e){K=e}function be(){return K}function xe(e){J=e}function Q(){Y=void 0}function Se(e){q=e}function Ce(e){if(e instanceof Error){let t={error:e.message};return q?(e.stack&&(t.stack=e.stack),e.cause!==void 0&&(t.cause=e.cause instanceof Error?e.cause.message:String(e.cause)),t):t}return{error:String(e)}}function we(e){return G.push(e),()=>{let t=G.indexOf(e);t>=0&&G.splice(t,1)}}function Te(e){function t(t,n,r){if(W[t]<W[K])return;let i=new Date,a={ts:i.toISOString(),level:t,component:e,msg:n,...r},o=JSON.stringify(a);(t===`warn`||t===`error`)&&console.error(o);for(let i of G)try{i({level:t,component:e,message:n,data:r})}catch{}he()&&(t===`warn`||t===`error`)&&ve(o,i)}return{debug:(e,n)=>t(`debug`,e,n),info:(e,n)=>t(`info`,e,n),warn:(e,n)=>t(`warn`,e,n),error:(e,n)=>t(`error`,e,n)}}const $={maxAttempts:3,baseDelayMs:500,maxDelayMs:3e4,jitterFraction:.25};async function Ee(e,t={}){let{maxAttempts:n=$.maxAttempts,baseDelayMs:r=$.baseDelayMs,maxDelayMs:i=$.maxDelayMs,jitterFraction:a=$.jitterFraction}=t,o=t.shouldRetry??(e=>e instanceof O),s;for(let c=1;c<=n;c++)try{return await e()}catch(e){if(s=e,c>=n||!o(e,c))throw e;let l;if(e instanceof O&&e.retryAfterMs!=null&&e.retryAfterMs>0)l=Math.min(e.retryAfterMs,i);else{let e=r*2**(c-1),t=Math.min(e,i),n=t*a*(Math.random()*2-1);l=Math.round(t+n)}t.onRetry?.(e,c,l),await De(l)}throw s}function De(e){return new Promise(t=>setTimeout(t,e))}const Oe=[`indexed`,`curated`,`produced`],ke=[`source`,`documentation`,`test`,`config`,`generated`],Ae=[`auto`,`manual`,`smart`],je=[`efficient`,`normal`,`full`],Me=[`documentation`,`code-typescript`,`code-javascript`,`code-python`,`code-other`,`config-json`,`config-yaml`,`config-toml`,`config-env`,`test-code`,`cdk-stack`,`markdown`,`curated-knowledge`,`produced-knowledge`,`unknown`];export{y as AIKIT_GLOBAL_PATHS,v as AIKIT_PATHS,T as AikitError,ae as CATEGORY_PATTERN,b as CHUNK_SIZES,Me as CONTENT_TYPES,g as CircuitBreaker,_ as CircuitOpenError,D as ConfigError,oe as DEFAULT_CATEGORIES,x as EMBEDDING_DEFAULTS,fe as EmbeddingError,re as FILE_LIMITS,me as HealthBus,Ae as INDEX_MODES,E as IndexError,Oe as KNOWLEDGE_ORIGINS,k as PermanentError,ie as SEARCH_DEFAULTS,ke as SOURCE_TYPES,S as STORE_DEFAULTS,pe as StoreError,je as TOKEN_BUDGETS,O as TransientError,we as addLogListener,N as computePartitionKey,ue as contentTypeToSourceType,Te as createLogger,le as detectContentType,M as getGlobalDataDir,be as getLogLevel,V as getPartitionDir,j as isPermanent,A as isTransient,H as isUserInstalled,B as listWorkspaces,P as loadRegistry,z as lookupWorkspace,R as registerWorkspace,Q as resetLogDir,U as resolveStateDir,L as saveRegistry,Ce as serializeError,Se as setDetailedErrorLoggingEnabled,xe as setFileSinkEnabled,ye as setLogLevel,de as sourceTypeContentTypes,Ee as withRetry};
|
|
1
|
+
import{EventEmitter as e}from"node:events";import{basename as t,extname as n,join as r,resolve as i}from"node:path";import{createHash as a}from"node:crypto";import{appendFileSync as o,closeSync as s,constants as c,copyFileSync as l,existsSync as u,lstatSync as ee,mkdirSync as d,openSync as te,readFileSync as ne,readdirSync as f,renameSync as p,rmSync as m,statSync as h,unlinkSync as g,writeFileSync as _}from"node:fs";import{homedir as v}from"node:os";var re=class t extends e{static registry=new Map;state=`closed`;failures=0;halfOpenAttempts=0;openUntil=0;threshold;cooldownMs;halfOpenMaxAttempts;jitterMs;name;onStateChange;static getAll(){return t.registry}static get(e){return t.registry.get(e)}static clearRegistry(){t.registry.clear()}constructor(e={}){super(),this.threshold=Math.max(1,e.threshold??3),this.cooldownMs=Math.max(0,e.cooldownMs??6e4),this.halfOpenMaxAttempts=Math.max(1,e.halfOpenMaxAttempts??1),this.jitterMs=Math.max(0,e.jitterMs??0),this.name=e.name,this.onStateChange=e.onStateChange,this.name&&t.registry.set(this.name,this)}async execute(e){this.assertNotOpen();try{let t=await e();return this.recordSuccess(),t}catch(e){throw this.recordFailure(),e}}getState(){return this.refreshState(),this.state}getName(){return this.name}isOpen(){return this.getState()===`open`}reset(){this.failures=0,this.halfOpenAttempts=0,this.openUntil=0,this.transitionTo(`closed`,`manual reset`)}dispose(){this.name&&t.registry.get(this.name)===this&&t.registry.delete(this.name),this.removeAllListeners()}forceOpen(e){this.failures=this.threshold,this.halfOpenAttempts=0,this.transitionTo(`open`,e??`manual override`)}recordSuccess(){this.refreshState(),this.failures=0,this.halfOpenAttempts=0,this.state===`half-open`&&this.transitionTo(`closed`,`probe succeeded`)}recordFailure(){if(this.refreshState(),this.failures+=1,this.halfOpenAttempts=0,this.state===`half-open`){this.transitionTo(`open`,`probe failed`);return}this.state===`closed`&&this.failures>=this.threshold&&this.transitionTo(`open`,`failure threshold reached`)}remainingCooldownMs(){return this.refreshState(),this.state===`open`?Math.max(0,this.openUntil-Date.now()):0}assertNotOpen(){if(this.refreshState(),this.state===`open`)throw new y(this.remainingCooldownMs());if(this.state===`half-open`){if(this.halfOpenAttempts>=this.halfOpenMaxAttempts)throw this.transitionTo(`open`,`half-open probe limit reached`),new y(this.remainingCooldownMs());this.halfOpenAttempts+=1}}refreshState(){this.state===`open`&&Date.now()>=this.openUntil&&(this.halfOpenAttempts=0,this.transitionTo(`half-open`,`cooldown expired`))}transitionTo(e,t){let n=this.state;if(n===e){e===`open`&&(this.openUntil=this.computeOpenUntil());return}this.state=e,e===`open`?(this.openUntil=this.computeOpenUntil(),this.halfOpenAttempts=0):(this.openUntil=0,e===`closed`&&(this.halfOpenAttempts=0)),this.onStateChange?.(n,e),this.emit(e,{from:n,reason:t})}computeOpenUntil(){return Date.now()+this.cooldownMs+Math.floor(Math.random()*this.jitterMs)}},y=class extends Error{remainingMs;constructor(e){super(`Circuit breaker is open — ${Math.ceil(e/1e3)}s remaining`),this.remainingMs=e,this.name=`CircuitOpenError`}};const b={root:`.aikit`,ai:`.ai`,aiContext:`.ai/context`,aiCurated:`.ai/curated`,restorePoints:`.ai/restore-points`,data:`.aikit/data`,state:`.aikit/state`,logs:`.aikit/logs`,brainstorm:`.brainstorm`,handoffs:`.handoffs`},x={data:`data`,curated:`curated`,onboard:`onboard`,state:`state`,restorePoints:`restore-points`,brainstorm:`brainstorm`,handoffs:`handoffs`},S={root:`.aikit`,registry:`registry.json`,workspaces:`workspaces`,logs:`logs`,state:`state`,legacyDataRoot:`.aikit-data`,legacyStateRoot:`.aikit-state`},ie={markdown:{max:1500,min:100},code:{max:2e3,min:50},config:{max:3e3,min:50},default:{max:1500,min:100,overlap:200}},ae={model:`mixedbread-ai/mxbai-embed-large-v1`,nativeDim:1024,dimensions:512,queryPrefix:``},C={backend:`sqlite-vec`,path:b.data,tableName:`knowledge`},oe={maxFileSizeBytes:1e6,maxCuratedFileSizeBytes:5e4},se={maxResults:10,minScore:.25},ce=/^[a-z][a-z0-9-]*$/,le=[`decisions`,`patterns`,`troubleshooting`,`conventions`,`architecture`],w={".ts":`code-typescript`,".tsx":`code-typescript`,".mts":`code-typescript`,".cts":`code-typescript`,".js":`code-javascript`,".jsx":`code-javascript`,".mjs":`code-javascript`,".cjs":`code-javascript`,".py":`code-python`,".json":`config-json`,".yaml":`config-yaml`,".yml":`config-yaml`,".toml":`config-toml`,".env":`config-env`,".md":`markdown`,".mdx":`markdown`},ue=[/\.test\.[jt]sx?$/,/\.spec\.[jt]sx?$/,/(^|\/)__tests__\//,/(^|\/)test\//,/(^|\/)tests\//,/(^|\/)spec\//,/(^|\/)fixtures\//],de=[/\.stack\.[jt]s$/,/(^|\/)stacks\//,/(^|\/)constructs\//,/cdk\.json$/];function fe(e){let r=n(e).toLowerCase(),i=t(e).toLowerCase();return e.includes(`${b.aiContext}/`)?`produced-knowledge`:e.includes(`${b.aiCurated}/`)?`curated-knowledge`:ue.some(t=>t.test(e))?`test-code`:de.some(t=>t.test(e))?`cdk-stack`:r in w?w[r]:i.startsWith(`.env`)?`config-env`:[`.go`,`.rs`,`.java`,`.rb`,`.php`,`.sh`,`.ps1`,`.sql`,`.graphql`,`.proto`,`.css`,`.scss`,`.less`,`.html`,`.htm`,`.vue`,`.svelte`,`.astro`,`.hbs`,`.ejs`,`.svg`].includes(r)?`code-other`:`unknown`}const T={"code-typescript":`source`,"code-javascript":`source`,"code-python":`source`,"code-other":`source`,"cdk-stack":`source`,"test-code":`test`,markdown:`documentation`,documentation:`documentation`,"curated-knowledge":`documentation`,"produced-knowledge":`documentation`,"config-json":`config`,"config-yaml":`config`,"config-toml":`config`,"config-env":`config`,unknown:`source`};function pe(e){return T[e]??`source`}function me(e){return Object.entries(T).filter(([,t])=>t===e).map(([e])=>e)}var E=class extends Error{code;constructor(e,t,n){super(e,n===void 0?void 0:{cause:n}),this.code=t,this.name=`AikitError`}},he=class extends E{constructor(e,t){super(e,`EMBEDDING_ERROR`,t),this.name=`EmbeddingError`}},ge=class extends E{constructor(e,t){super(e,`STORE_ERROR`,t),this.name=`StoreError`}},_e=class extends E{constructor(e,t){super(e,`INDEX_ERROR`,t),this.name=`IndexError`}},ve=class extends E{constructor(e,t){super(e,`CONFIG_ERROR`,t),this.name=`ConfigError`}},D=class extends E{retryAfterMs;constructor(e,t,n){super(e,`TRANSIENT_ERROR`,n),this.retryAfterMs=t,this.name=`TransientError`}},O=class extends E{constructor(e,t){super(e,`PERMANENT_ERROR`,t),this.name=`PermanentError`}};function ye(e){return e instanceof D}function be(e){return e instanceof O}let k=!1;function A(e){try{return!ee(e).isSymbolicLink()}catch{return!1}}function j(e,t){if(h(e).isDirectory()){d(t,{recursive:!0});for(let n of f(e))N(i(e,n),i(t,n));m(e,{recursive:!0,force:!0});return}d(i(t,`..`),{recursive:!0}),l(e,t),g(e)}function M(e,t){try{p(e,t)}catch(n){let r=n.code;if(r===`ENOENT`&&!u(e)&&u(t))return;if(r!==`EXDEV`)throw n;j(e,t)}}function N(e,t){if(!u(e)||e===t||!A(e))return;let n=h(e);if(!u(t)){d(i(t,`..`),{recursive:!0}),M(e,t);return}if(n.isDirectory()){d(t,{recursive:!0});for(let n of f(e))N(i(e,n),i(t,n));try{m(e,{recursive:!0,force:!0})}catch{}}}function P(e){if(u(e))try{f(e).length===0&&m(e,{recursive:!0,force:!0})}catch{}}function xe(e){let t=i(e,x.data);d(t,{recursive:!0});for(let n of f(e))n!==x.data&&(n===`lance`||/\.db(?:-(?:wal|shm|journal))?$/i.test(n))&&N(i(e,n),i(t,n))}function F(e){return H(R(e))}function Se(e){if(k)return;k=!0,d(e,{recursive:!0});let t=v(),n=i(t,S.legacyDataRoot),r=i(t,S.legacyStateRoot),a=i(e,S.workspaces),o=i(e,S.logs),s=i(e,S.state);if(u(n)&&n!==e){d(a,{recursive:!0});for(let t of f(n))N(i(n,t),t===S.registry||t===`global.env`||t===`flows`||t===`global-knowledge`?i(e,t):i(a,t));P(n)}if(u(r)&&r!==e){for(let e of f(r))N(i(r,e),e===`logs`?o:i(s,e));P(r)}}function I(e){let t=i(e),n=F(t),r=i(n,x.data),a=i(L(),S.logs),o=[{from:i(t,S.legacyDataRoot),to:r},{from:i(t,S.legacyStateRoot),to:i(n,x.state)},{from:i(t,b.data),to:r},{from:i(t,b.state),to:i(n,x.state)},{from:i(t,b.aiCurated),to:i(n,x.curated)},{from:i(t,b.aiContext),to:i(n,x.onboard)},{from:i(t,b.restorePoints),to:i(n,x.restorePoints)},{from:i(t,b.brainstorm),to:i(n,x.brainstorm)},{from:i(t,b.handoffs),to:i(n,x.handoffs)},{from:i(t,b.logs),to:a}];d(n,{recursive:!0}),d(a,{recursive:!0}),xe(n);for(let e of o)N(e.from,e.to);P(i(t,b.root)),P(i(t,b.ai)),P(i(t,b.brainstorm)),P(i(t,b.handoffs))}function Ce(e){return I(e),i(H(V(e).partition),x.state)}function L(){let e=process.env.AIKIT_GLOBAL_DATA_DIR,t=e??i(v(),S.root);return!e&&!process.env.VITEST&&process.env.NODE_ENV!==`test`&&Se(t),t}function R(e){let n=i(e);return`${t(n).toLowerCase().replace(/[^a-z0-9-]/g,`-`)||`workspace`}-${a(`sha256`).update(n).digest(`hex`).slice(0,8)}`}function z(){let e=i(L(),S.registry);if(!u(e))return{version:1,workspaces:{}};let t=ne(e,`utf-8`);try{return JSON.parse(t)}catch{return{version:1,workspaces:{}}}}function we(e,t=5e3){let n=`${e}.lock`,r=Date.now()+t,i=10;for(;Date.now()<r;)try{let e=te(n,c.O_CREAT|c.O_EXCL|c.O_WRONLY);return _(e,`${process.pid}\n`),s(e),n}catch(e){if(e.code!==`EEXIST`)throw e;try{let{mtimeMs:e}=h(n);if(Date.now()-e>3e4){g(n);continue}}catch{}let t=new SharedArrayBuffer(4);Atomics.wait(new Int32Array(t),0,0,i),i=Math.min(i*2,200)}throw Error(`Failed to acquire registry lock after ${t}ms`)}function Te(e){try{g(e)}catch{}}function B(e){let t=L();d(t,{recursive:!0});let n=i(t,S.registry),r=we(n);try{let t=`${n}.tmp`;_(t,JSON.stringify(e,null,2),`utf-8`),p(t,n)}finally{Te(r)}}function V(e){let t=z(),n=R(e),r=new Date().toISOString();return t.workspaces[n]?t.workspaces[n].lastAccessedAt=r:t.workspaces[n]={partition:n,workspacePath:i(e),registeredAt:r,lastAccessedAt:r},d(H(n),{recursive:!0}),B(t),t.workspaces[n]}function Ee(e){let t=z(),n=R(e);return t.workspaces[n]}function De(){let e=z();return Object.values(e.workspaces)}function H(e){return i(L(),S.workspaces,e)}function Oe(){return u(i(L(),S.registry))}function U(){return i(L(),S.logs)}var ke=class t extends e{static _instance=null;subsystems=new Map;constructor(){super()}static instance(){return t._instance||=new t,t._instance}static reset(){t._instance?.removeAllListeners(),t._instance=null}register(e){this.subsystems.has(e)||this.subsystems.set(e,{name:e,status:`healthy`,since:Date.now()})}reportDegraded(e,t){this.transition(e,`degraded`,t)}reportUnavailable(e,t){this.transition(e,`unavailable`,t)}reportRecovered(e){this.transition(e,`healthy`)}isDegraded(e){let t=this.subsystems.get(e);return t?.status===`degraded`||t?.status===`unavailable`}isHealthy(e){return this.subsystems.get(e)?.status===`healthy`}getAll(){return Array.from(this.subsystems.values(),e=>({...e}))}getSubsystem(e){let t=this.subsystems.get(e);return t?{...t}:void 0}transition(e,t,n){let r=this.subsystems.get(e);if(!r||r.status===t)return;let i={subsystem:e,status:t,previousStatus:r.status,reason:n,timestamp:Date.now()};r.status=t,r.since=i.timestamp,r.reason=n,this.emit(t,i),this.emit(`change`,i)}};const W={debug:0,info:1,warn:2,error:3},G=[];let K=process.env.AIKIT_LOG_LEVEL??`info`,q=!1,J=process.env.AIKIT_LOG_FILE_SINK===`true`||process.env.AIKIT_LOG_FILE_SINK!==`false`&&!process.env.VITEST&&process.env.NODE_ENV!==`test`;function Ae(){return J?process.env.VITEST||process.env.NODE_ENV===`test`?process.env.AIKIT_LOG_FILE_SINK===`true`:!0:!1}let Y;function X(){return Y||=U(),Y}function je(e){let t=e.toISOString().slice(0,10);return r(X(),`${t}.jsonl`)}let Z=0;function Me(){let e=Date.now();if(!(e-Z<36e5)){Z=e;try{let t=X(),n=new Date(e-30*864e5).toISOString().slice(0,10);for(let e of f(t))if(e.endsWith(`.jsonl`)&&e.slice(0,10)<n)try{g(r(t,e))}catch{}}catch{}}}function Ne(e,t){try{d(X(),{recursive:!0}),o(je(t),`${e}\n`),Me()}catch{}}function Pe(e){K=e}function Fe(){return K}function Q(e){J=e}function Ie(){Y=void 0}function Le(e){q=e}function Re(e){if(e instanceof Error){let t={error:e.message};return q?(e.stack&&(t.stack=e.stack),e.cause!==void 0&&(t.cause=e.cause instanceof Error?e.cause.message:String(e.cause)),t):t}return{error:String(e)}}function ze(e){return G.push(e),()=>{let t=G.indexOf(e);t>=0&&G.splice(t,1)}}function Be(e){function t(t,n,r){if(W[t]<W[K])return;let i=new Date,a={ts:i.toISOString(),level:t,component:e,msg:n,...r},o=JSON.stringify(a);(t===`warn`||t===`error`)&&console.error(o);for(let i of G)try{i({level:t,component:e,message:n,data:r})}catch{}Ae()&&(t===`warn`||t===`error`)&&Ne(o,i)}return{debug:(e,n)=>t(`debug`,e,n),info:(e,n)=>t(`info`,e,n),warn:(e,n)=>t(`warn`,e,n),error:(e,n)=>t(`error`,e,n)}}const $={maxAttempts:3,baseDelayMs:500,maxDelayMs:3e4,jitterFraction:.25};async function Ve(e,t={}){let{maxAttempts:n=$.maxAttempts,baseDelayMs:r=$.baseDelayMs,maxDelayMs:i=$.maxDelayMs,jitterFraction:a=$.jitterFraction}=t,o=t.shouldRetry??(e=>e instanceof D),s;for(let c=1;c<=n;c++)try{return await e()}catch(e){if(s=e,c>=n||!o(e,c))throw e;let l;if(e instanceof D&&e.retryAfterMs!=null&&e.retryAfterMs>0)l=Math.min(e.retryAfterMs,i);else{let e=r*2**(c-1),t=Math.min(e,i),n=t*a*(Math.random()*2-1);l=Math.round(t+n)}t.onRetry?.(e,c,l),await He(l)}throw s}function He(e){return new Promise(t=>setTimeout(t,e))}const Ue=[`indexed`,`curated`,`produced`],We=[`source`,`documentation`,`test`,`config`,`generated`],Ge=[`auto`,`manual`,`smart`],Ke=[`efficient`,`normal`,`full`],qe=[`documentation`,`code-typescript`,`code-javascript`,`code-python`,`code-other`,`config-json`,`config-yaml`,`config-toml`,`config-env`,`test-code`,`cdk-stack`,`markdown`,`curated-knowledge`,`produced-knowledge`,`unknown`];export{S as AIKIT_GLOBAL_PATHS,b as AIKIT_PATHS,x as AIKIT_RUNTIME_PATHS,E as AikitError,ce as CATEGORY_PATTERN,ie as CHUNK_SIZES,qe as CONTENT_TYPES,re as CircuitBreaker,y as CircuitOpenError,ve as ConfigError,le as DEFAULT_CATEGORIES,ae as EMBEDDING_DEFAULTS,he as EmbeddingError,oe as FILE_LIMITS,ke as HealthBus,Ge as INDEX_MODES,_e as IndexError,Ue as KNOWLEDGE_ORIGINS,O as PermanentError,se as SEARCH_DEFAULTS,We as SOURCE_TYPES,C as STORE_DEFAULTS,ge as StoreError,Ke as TOKEN_BUDGETS,D as TransientError,ze as addLogListener,R as computePartitionKey,pe as contentTypeToSourceType,Be as createLogger,fe as detectContentType,L as getGlobalDataDir,Fe as getLogLevel,H as getPartitionDir,F as getWorkspacePartitionDir,be as isPermanent,ye as isTransient,Oe as isUserInstalled,De as listWorkspaces,z as loadRegistry,Ee as lookupWorkspace,I as migrateLegacyWorkspaceLayout,V as registerWorkspace,Ie as resetLogDir,U as resolveLogDir,Ce as resolveStateDir,B as saveRegistry,Re as serializeError,Le as setDetailedErrorLoggingEnabled,Q as setFileSinkEnabled,Pe as setLogLevel,me as sourceTypeContentTypes,Ve as withRetry};
|
|
@@ -91,6 +91,17 @@ interface FlowRegistryEntry {
|
|
|
91
91
|
/** Git commit SHA of the installed version (git sources only) */
|
|
92
92
|
commitSha?: string;
|
|
93
93
|
}
|
|
94
|
+
/** Snapshot of a flow definition's registry origin captured at run start */
|
|
95
|
+
interface FlowDefinitionOrigin {
|
|
96
|
+
/** Original source (URL, path, or "builtin") */
|
|
97
|
+
source: string;
|
|
98
|
+
/** How the flow was installed */
|
|
99
|
+
sourceType: FlowSourceType;
|
|
100
|
+
/** Detected source format */
|
|
101
|
+
format: FlowFormat;
|
|
102
|
+
/** Git commit SHA of the installed version (git sources only) */
|
|
103
|
+
commitSha?: string;
|
|
104
|
+
}
|
|
94
105
|
/** The flow registry file structure */
|
|
95
106
|
interface FlowRegistry {
|
|
96
107
|
/** Schema version */
|
|
@@ -117,6 +128,8 @@ interface StepExecutionRecord {
|
|
|
117
128
|
interface FlowState {
|
|
118
129
|
/** Which flow is active (name from registry) */
|
|
119
130
|
flow: string;
|
|
131
|
+
/** Snapshot of the flow definition origin captured at start time */
|
|
132
|
+
flowOrigin?: FlowDefinitionOrigin;
|
|
120
133
|
/** Current status */
|
|
121
134
|
status: FlowStatus;
|
|
122
135
|
/** Current step ID (null if not started) */
|
|
@@ -160,6 +173,8 @@ interface FlowRunMeta {
|
|
|
160
173
|
flow: string;
|
|
161
174
|
/** Flow version at time of start */
|
|
162
175
|
flowVersion: string;
|
|
176
|
+
/** Snapshot of the flow definition origin captured at start time */
|
|
177
|
+
flowOrigin?: FlowDefinitionOrigin;
|
|
163
178
|
/** Human-readable topic */
|
|
164
179
|
topic: string;
|
|
165
180
|
/** Run status */
|
|
@@ -195,6 +210,8 @@ interface FlowRunSummary {
|
|
|
195
210
|
id: string;
|
|
196
211
|
/** Flow name */
|
|
197
212
|
flow: string;
|
|
213
|
+
/** Snapshot of the flow definition origin captured at start time */
|
|
214
|
+
flowOrigin?: FlowDefinitionOrigin;
|
|
198
215
|
/** Human-readable topic */
|
|
199
216
|
topic: string;
|
|
200
217
|
/** Run status */
|
|
@@ -448,6 +465,10 @@ declare class FlowStateMachine {
|
|
|
448
465
|
constructor(flowsDir: string, epilogueConfig?: EpilogueConfig);
|
|
449
466
|
/** Create a filesystem-safe slug from a human-readable topic */
|
|
450
467
|
private slugify;
|
|
468
|
+
/** Keep the meta.json path within a conservative Windows-safe budget */
|
|
469
|
+
private getMaxSlugLength;
|
|
470
|
+
/** Trim a slug to fit a length budget while keeping separators tidy */
|
|
471
|
+
private fitSlugToBudget;
|
|
451
472
|
/** Allocate a unique run slug for a topic */
|
|
452
473
|
private generateSlug;
|
|
453
474
|
/** Resolve the meta.json path for a run slug */
|
|
@@ -473,7 +494,7 @@ declare class FlowStateMachine {
|
|
|
473
494
|
/** Convert persisted run metadata into the public FlowState shape */
|
|
474
495
|
private metaToState;
|
|
475
496
|
/** Start a new flow */
|
|
476
|
-
start(flowName: string, manifest: FlowManifest, topic?: string): FlowResult<FlowState>;
|
|
497
|
+
start(flowName: string, manifest: FlowManifest, topic?: string, flowOrigin?: FlowDefinitionOrigin): FlowResult<FlowState>;
|
|
477
498
|
/** Advance the flow: next, skip, or redo current step */
|
|
478
499
|
step(action: StepAction, manifest: FlowManifest): FlowResult<FlowState>;
|
|
479
500
|
/** Get current flow status */
|
|
@@ -503,4 +524,4 @@ declare class SymlinkManager {
|
|
|
503
524
|
private getAgentStem;
|
|
504
525
|
}
|
|
505
526
|
//#endregion
|
|
506
|
-
export { type BuiltinFlow, ClaudePluginAdapter, type ContentTransformFn, CopilotAdapter, type EpilogueConfig, type EpiloguePosition, type EpilogueStepDef, type FlowFormat, type FlowFormatAdapter, type FlowHookConfig, FlowLoader, type FlowManifest, type FlowParseOptions, type FlowPhase, type FlowRegistry, type FlowRegistryEntry, FlowRegistryManager, type FlowResult, type FlowRunMeta, type FlowRunSummary, type FlowSourceType, type FlowState, FlowStateMachine, type FlowStatus, type FlowStep, FoundationIntegration, GitInstaller, NativeAdapter, OpenSpecAdapter, type StepAction, SymlinkManager, getBuiltinFlows };
|
|
527
|
+
export { type BuiltinFlow, ClaudePluginAdapter, type ContentTransformFn, CopilotAdapter, type EpilogueConfig, type EpiloguePosition, type EpilogueStepDef, type FlowDefinitionOrigin, type FlowFormat, type FlowFormatAdapter, type FlowHookConfig, FlowLoader, type FlowManifest, type FlowParseOptions, type FlowPhase, type FlowRegistry, type FlowRegistryEntry, FlowRegistryManager, type FlowResult, type FlowRunMeta, type FlowRunSummary, type FlowSourceType, type FlowState, FlowStateMachine, type FlowStatus, type FlowStep, FoundationIntegration, GitInstaller, NativeAdapter, OpenSpecAdapter, type StepAction, SymlinkManager, getBuiltinFlows };
|
|
@@ -12,4 +12,4 @@ ${M}`}var P=class{injectPreamble(e,t){let r=N(t);if(!n(e)){d(e,`${r}\n`,`utf-8`)
|
|
|
12
12
|
|
|
13
13
|
`),`utf-8`)}getTargetFiles(e){let t=[],r=m(e,`.github`,`copilot-instructions.md`);n(r)&&t.push(r);let i=m(e,`CLAUDE.md`);n(i)&&t.push(i);let a=m(e,`AGENTS.md`);return n(a)&&t.push(a),t}};function F(e){if(!e||typeof e!=`object`||!(`stderr`in e))return``;let t=e.stderr;return Buffer.isBuffer(t)?t.toString().trim():typeof t==`string`?t.trim():``}function I(e){try{return new URL(e).hostname}catch{}return e.match(/^[^@]+@([^:]+):/)?.[1]??`<host>`}function L(e,t,n){let r=[`Git operation failed for: ${e}`],i=I(e),a=t.includes(`ETIMEDOUT`)||t.includes(`SIGTERM`)||t.toLowerCase().includes(`timed out`),o=n.includes(`Authentication failed`)||n.includes(`could not read Username`)||n.includes(`terminal prompts disabled`)||n.includes(`401`)||n.includes(`403`)||n.includes(`Permission denied`),s=n.includes(`SSL certificate`)||n.includes(`unable to access`)&&n.includes(`SSL`),c=n.includes(`Could not resolve host`)||n.includes(`Name or service not known`),l=n.includes(`SAML`)||n.includes(`single sign-on`);return o||l?(r.push(``),r.push(`Cause: Authentication required or credentials not configured.`),r.push(``),r.push(`To fix this, ensure git can access this repository:`),r.push(``),r.push(` Option 1 - SSH key:`),r.push(` 1. Generate an SSH key: ssh-keygen -t ed25519`),r.push(` 2. Add the public key to your Git hosting account`),r.push(` 3. Use the SSH URL instead: git@<host>:<org>/<repo>.git`),r.push(``),r.push(` Option 2 - Personal Access Token (PAT):`),r.push(` 1. Create a PAT in your Git hosting Settings > Developer settings > Tokens`),r.push(` 2. For GitHub Enterprise with SAML SSO, authorize the token for your org`),r.push(` 3. Configure git credentials:`),r.push(` git config --global credential.helper store`),r.push(` git clone ${e} (enter PAT as password)`),r.push(``),r.push(` Option 3 - Git Credential Manager:`),r.push(` 1. Install: https://github.com/git-ecosystem/git-credential-manager`),r.push(` 2. Run: git clone ${e}`),r.push(` 3. Follow the browser-based auth prompt`),r.push(``),r.push(`After configuring credentials, retry: aikit flow add ${e}`)):a?(r.push(``),r.push(`Cause: Connection timed out - the server did not respond within 60 seconds.`),r.push(``),r.push(`Possible reasons:`),r.push(` - The repository requires VPN access. Ensure your VPN is connected`),r.push(` - The host is behind a firewall or corporate proxy`),r.push(` - The URL may be incorrect`),r.push(``),r.push(`Diagnostics:`),r.push(` 1. Verify the URL is correct: ${e}`),r.push(` 2. Test connectivity: git ls-remote ${e}`),r.push(` 3. If behind a proxy, configure git:`),r.push(` git config --global http.proxy http://proxy:port`),r.push(``),r.push(`If this is a corporate/internal host, you may need to:`),r.push(` - Connect to the corporate VPN`),r.push(` - Add the host to your SSH config or git config`),r.push(` - Ask your IT team to allowlist your machine`),r.push(``),r.push(`After resolving, retry: aikit flow add ${e}`)):s?(r.push(``),r.push(`Cause: SSL/TLS certificate verification failed.`),r.push(``),r.push(`This often happens with corporate proxies or self-signed certificates.`),r.push(``),r.push(`To fix:`),r.push(` 1. If your company uses a custom CA, add it:`),r.push(` git config --global http.sslCAInfo /path/to/ca-bundle.crt`),r.push(` 2. As a last resort (not recommended for production):`),r.push(` git config --global http.sslVerify false`),r.push(``),r.push(`After resolving, retry: aikit flow add ${e}`)):c?(r.push(``),r.push(`Cause: Cannot resolve hostname.`),r.push(``),r.push(`Check:`),r.push(` 1. Is the URL correct? ${e}`),r.push(` 2. Are you connected to the internet/VPN?`),r.push(` 3. Can you resolve the host? ping ${i}`),r.push(``),r.push(`After resolving, retry: aikit flow add ${e}`)):(r.push(``),r.push(`Error: ${t}`),n&&r.push(`Details: ${n}`),r.push(``),r.push(`Troubleshooting:`),r.push(` 1. Verify the URL is a valid git repository: git ls-remote ${e}`),r.push(` 2. Check your git credentials and network connectivity`),r.push(` 3. If the repo requires auth, configure credentials first (PAT or SSH key)`),r.push(``),r.push(`After resolving, retry: aikit flow add ${e}`)),r.join(`
|
|
14
14
|
`)}function R(){try{return v(`git`,[`credential-manager`,`--version`],{stdio:`pipe`,timeout:5e3}).status===0}catch{return!1}}function z(e,t){let n=`${e}\n${t}`.toLowerCase();return n.includes(`authentication failed`)||n.includes(`could not read username`)||n.includes(`saml sso`)||n.includes(`terminal prompts disabled`)||n.includes(`host key verification failed`)||n.includes(`permission denied`)||n.includes(`403`)||n.includes(`401`)}var B=class{flowsDir;constructor(e){this.flowsDir=e}clone(e,t){let r=this.repoNameFromUrl(e),i=m(this.flowsDir,r);if(n(i))if(!n(m(i,`.git`)))s(i,{recursive:!0,force:!0});else return{success:!1,error:`Flow "${r}" already installed at ${i}. Use update instead.`};try{if(this.ensureFlowsDir(),t){let n=process.platform===`win32`?`bat`:`sh`,r=m(y(),`git-askpass-${Date.now()}.${n}`);process.platform===`win32`?d(r,`@echo ${t}`,{mode:448}):d(r,`#!/bin/sh\necho "${t}"`,{mode:448});try{let t=v(`git`,[`clone`,`--depth`,`1`,e,i],{stdio:`pipe`,timeout:6e4,env:{...process.env,GIT_TERMINAL_PROMPT:`0`,GIT_ASKPASS:r}});if(t.status!==0){let e=t.stderr?.toString().trim()??``;throw Error(e||t.error?.message||`git clone failed`)}}finally{try{u(r)}catch{}}}else{let t=v(`git`,[`clone`,`--depth`,`1`,e,i],{stdio:`pipe`,timeout:6e4,env:{...process.env,GIT_TERMINAL_PROMPT:`0`,GIT_ASKPASS:``}});if(t.status!==0){let e=t.stderr?.toString().trim()??``;throw Error(e||t.error?.message||`git clone failed`)}}return{success:!0,data:i}}catch(r){n(i)&&s(i,{recursive:!0,force:!0});let a=F(r),o=r instanceof Error?r.message:String(r);if(!t&&z(o,a)&&R()){let t=I(e)||e;console.log(`\nAuthentication required for ${t}.\nGit Credential Manager detected - opening browser for login...\n(If a browser window does not open, check your terminal for a device code.)\n`);try{if(this.ensureFlowsDir(),v(`git`,[`clone`,`--depth`,`1`,e,i],{stdio:`inherit`,timeout:12e4,env:{...process.env,GIT_TERMINAL_PROMPT:`1`}}).status===0)return{success:!0,data:i};n(i)&&s(i,{recursive:!0,force:!0})}catch{n(i)&&s(i,{recursive:!0,force:!0})}}return{success:!1,error:L(e,o,a)}}}update(e){if(!n(e))return{success:!1,error:`Install path not found: ${e}`};try{return _(`git pull --ff-only`,{cwd:e,stdio:`pipe`,timeout:6e4,env:{...process.env,GIT_TERMINAL_PROMPT:`0`,GIT_ASKPASS:``}}),{success:!0}}catch(t){let n=e;try{n=_(`git remote get-url origin`,{cwd:e,stdio:`pipe`,timeout:1e4}).toString().trim()}catch{}let r=F(t),i=t instanceof Error?t.message:String(t);if(z(i,r)&&R()){let t=I(n)||n;console.log(`\nAuthentication required for ${t}.\nGit Credential Manager detected - opening browser for login...\n`);try{if(v(`git`,[`pull`,`--ff-only`],{cwd:e,stdio:`inherit`,timeout:12e4,env:{...process.env,GIT_TERMINAL_PROMPT:`1`}}).status===0)return{success:!0}}catch{}}return{success:!1,error:L(n,i,r)}}}copyLocal(e,r){let i=m(this.flowsDir,r);if(n(i))return{success:!1,error:`Flow "${r}" already installed at ${i}`};try{return this.ensureFlowsDir(),t(e,i,{recursive:!0}),{success:!0,data:i}}catch(e){return{success:!1,error:`Copy failed: ${e instanceof Error?e.message:String(e)}`}}}remove(e){if(!n(e))return{success:!0};try{return s(e,{recursive:!0,force:!0}),{success:!0}}catch(e){return{success:!1,error:`Remove failed: ${e instanceof Error?e.message:String(e)}`}}}runInstallDeps(e){for(let t of e)try{if(t.startsWith(`npm:`)){_(`npx skills add ${t.slice(4)} -g`,{stdio:`pipe`,timeout:12e4});continue}if(t.endsWith(`.git`)||t.includes(`github.com`)){_(`npx skills add ${t} -g`,{stdio:`pipe`,timeout:12e4});continue}return{success:!1,error:`Unknown install entry format: ${t}`}}catch(e){return{success:!1,error:`Install dependency failed for "${t}": ${e instanceof Error?e.message:String(e)}`}}return{success:!0}}getLocalCommit(e){try{return _(`git rev-parse HEAD`,{cwd:e,stdio:`pipe`,timeout:1e4,env:{...process.env,GIT_TERMINAL_PROMPT:`0`}}).toString().trim()||null}catch{return null}}getRemoteCommit(e){try{return _(`git ls-remote origin HEAD`,{cwd:e,stdio:`pipe`,timeout:3e4,env:{...process.env,GIT_TERMINAL_PROMPT:`0`}}).toString().trim().split(/\s+/)[0]||null}catch{return null}}hasUpdates(e){let t=this.getLocalCommit(e);if(!t)return{success:!1,error:`Could not determine local commit (not a git repo?)`};let n=this.getRemoteCommit(e);return n?{success:!0,data:{localCommit:t,remoteCommit:n,hasUpdates:t!==n}}:{success:!1,error:`Could not reach remote to check for updates`}}repoNameFromUrl(e){return f(e).replace(/\.git$/,``)}ensureFlowsDir(){n(this.flowsDir)||r(this.flowsDir,{recursive:!0})}};const V=[new E,new w,new T,new D];function H(e){let t=V.find(t=>t.format===e);if(!t)throw Error(`No adapter for format: ${e}`);return t}function U(e){for(let t of V)if(t.detect(e))return t;return null}var W=class{async load(e,t){if(!n(e))return{success:!1,error:`Source directory not found: ${e}`};let r=U(e);if(!r)return{success:!1,error:`No format adapter matches source: ${e}`};try{let n=await r.parse(e,t),i=this.validate(n);return i.success?{success:!0,data:{manifest:n,format:r.format}}:i}catch(e){return{success:!1,error:`Failed to parse flow: ${e instanceof Error?e.message:String(e)}`}}}async loadWithFormat(e,t,n){let r=H(t);try{let t=await r.parse(e,n),i=this.validate(t);return i.success?{success:!0,data:t}:i}catch(e){return{success:!1,error:`Failed to parse flow: ${e instanceof Error?e.message:String(e)}`}}}validate(e){let t=[];e.name?.trim()||t.push(`Missing flow name`),e.version?.trim()||t.push(`Missing flow version`),e.steps?.length||t.push(`Flow must have at least one step`);let n=new Set(e.steps.map(e=>e.id));for(let r of e.steps??[]){r.id?.trim()||t.push(`Step missing id`),r.instruction?.trim()||t.push(`Step "${r.id}" missing instruction path`);for(let e of r.requires??[])n.has(e)||t.push(`Step "${r.id}" requires unknown step "${e}"`)}return n.size!==(e.steps?.length??0)&&t.push(`Duplicate step IDs found`),t.length>0?{success:!1,error:`Validation failed:\n${t.join(`
|
|
15
|
-
`)}`}:{success:!0}}};function G(){return A().map(e=>({name:e.manifest.name,version:e.manifest.version,source:`builtin`,sourceType:`builtin`,installPath:e.scaffoldDir,format:`native`,registeredAt:`1970-01-01T00:00:00.000Z`,updatedAt:`1970-01-01T00:00:00.000Z`,manifest:e.manifest}))}var K=class{registryPath;constructor(e){this.registryPath=e}load(){if(!n(this.registryPath))return{version:1,flows:{}};try{let e=i(this.registryPath,`utf-8`);return JSON.parse(e)}catch{return{version:1,flows:{}}}}save(e){let t=p(this.registryPath);n(t)||r(t,{recursive:!0}),d(this.registryPath,JSON.stringify(e,null,2),`utf-8`)}register(e){let t=this.load();return t.flows[e.name]=e,this.save(t),{success:!0}}unregister(e){let t=this.load();return t.flows[e]?(delete t.flows[e],this.save(t),{success:!0}):{success:!1,error:`Flow "${e}" not found in registry`}}get(e){return this.load().flows[e]||(G().find(t=>t.name===e)??null)}list(){let e=this.load(),t=new Set(Object.keys(e.flows)),n=Object.values(e.flows);for(let e of G())t.has(e.name)||n.push(e);return n}has(e){return e in this.load().flows?!0:G().some(t=>t.name===e)}},q=class{flowsDir;epilogueConfig;constructor(e,t={before:[],after:[]}){this.flowsDir=e,this.epilogueConfig=t}slugify(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``)||`flow`}generateSlug(e){let t=this.slugify(e);if(!n(m(this.flowsDir,
|
|
15
|
+
`)}`}:{success:!0}}};function G(){return A().map(e=>({name:e.manifest.name,version:e.manifest.version,source:`builtin`,sourceType:`builtin`,installPath:e.scaffoldDir,format:`native`,registeredAt:`1970-01-01T00:00:00.000Z`,updatedAt:`1970-01-01T00:00:00.000Z`,manifest:e.manifest}))}var K=class{registryPath;constructor(e){this.registryPath=e}load(){if(!n(this.registryPath))return{version:1,flows:{}};try{let e=i(this.registryPath,`utf-8`);return JSON.parse(e)}catch{return{version:1,flows:{}}}}save(e){let t=p(this.registryPath);n(t)||r(t,{recursive:!0}),d(this.registryPath,JSON.stringify(e,null,2),`utf-8`)}register(e){let t=this.load();return t.flows[e.name]=e,this.save(t),{success:!0}}unregister(e){let t=this.load();return t.flows[e]?(delete t.flows[e],this.save(t),{success:!0}):{success:!1,error:`Flow "${e}" not found in registry`}}get(e){return this.load().flows[e]||(G().find(t=>t.name===e)??null)}list(){let e=this.load(),t=new Set(Object.keys(e.flows)),n=Object.values(e.flows);for(let e of G())t.has(e.name)||n.push(e);return n}has(e){return e in this.load().flows?!0:G().some(t=>t.name===e)}},q=class{flowsDir;epilogueConfig;constructor(e,t={before:[],after:[]}){this.flowsDir=e,this.epilogueConfig=t}slugify(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/-+/g,`-`).replace(/^-|-$/g,``)||`flow`}getMaxSlugLength(){let e=240-m(this.flowsDir,`meta.json`).length-1;return Math.max(1,Math.min(60,e))}fitSlugToBudget(e,t){return e.length<=t?e:e.slice(0,t).replace(/-+$/,``)||e.slice(0,t)}generateSlug(e){let t=this.slugify(e),r=this.getMaxSlugLength(),i=this.fitSlugToBudget(t,r);if(!n(m(this.flowsDir,i)))return i;for(let e=2;e<=100;e+=1){let i=`-${e}`;if(i.length>=r)continue;let a=`${this.fitSlugToBudget(t,r-i.length)}${i}`;if(!n(m(this.flowsDir,a)))return a}throw Error(`Unable to allocate a flow run slug for topic "${e}"`)}getMetaPath(e){return m(this.flowsDir,e,`meta.json`)}buildStepSequence(e){return[...this.epilogueConfig.before.map(e=>({id:e.id,phase:`before`})),...e.steps.map(e=>({id:e.id,phase:`flow`})),...this.epilogueConfig.after.map(e=>({id:e.id,phase:`after`}))]}readMeta(e){let t=this.getMetaPath(e);if(!n(t))return null;try{let e=i(t,`utf-8`);return JSON.parse(e)}catch{return null}}writeMeta(e,t){let i=m(this.flowsDir,e);n(i)||r(i,{recursive:!0});let a=this.getMetaPath(e),s=`${a}.tmp`;d(s,JSON.stringify(t,null,2),`utf-8`),o(s,a)}normalizeMeta(e){let t=e;return t.completedTokens??=[],t.executionLog??=[],t}hasCompletedExecution(e,t){return e.executionLog.some(n=>n.stepId===t&&e.completedTokens.includes(n.token))}markCrashedExecution(e){let t=e.currentToken;if(!(!t||e.completedTokens.includes(t)))for(let n=e.executionLog.length-1;n>=0;--n){let r=e.executionLog[n];if(r.token===t&&r.outcome===`in-progress`){r.outcome=`crashed`;break}}}finalizeCurrentStep(e,t,n){let r=e.currentToken;if(r){e.completedTokens.includes(r)||e.completedTokens.push(r);for(let i=e.executionLog.length-1;i>=0;--i){let a=e.executionLog[i];if(a.token===r){a.completedAt=n,a.outcome=t;break}}}e.currentToken=void 0}activateStep(e,t,n,r){let i=n;for(;i<t.length;){let n=t[i];if(e.currentStep=n.id,e.phase=n.phase,r?.force||!this.hasCompletedExecution(e,n.id)){this.markCrashedExecution(e);let t=Date.now(),r=new Date(t).toISOString(),i=`${n.id}-${t}`;e.currentToken=i,e.executionLog.push({stepId:n.id,token:i,startedAt:r,outcome:`in-progress`});return}n.phase===`flow`?e.completedSteps.includes(n.id)||e.completedSteps.push(n.id):e.completedEpilogueSteps.includes(n.id)||e.completedEpilogueSteps.push(n.id),i+=1}e.currentStep=null,e.currentToken=void 0,e.status=`completed`,e.phase=`after`}findActiveRun(){if(!n(this.flowsDir))return null;for(let e of a(this.flowsDir,{withFileTypes:!0})){if(!e.isDirectory())continue;let t=this.readMeta(e.name);if(t?.status===`active`)return{slug:e.name,meta:t}}return null}metaToState(e,t){let n=this.normalizeMeta(t),r=n.phase??`flow`;return{flow:n.flow,flowOrigin:n.flowOrigin,status:n.status,currentStep:n.currentStep,currentToken:n.currentToken,completedSteps:n.completedSteps,completedTokens:n.completedTokens,skippedSteps:n.skippedSteps,executionLog:n.executionLog,artifacts:n.artifacts,startedAt:n.startedAt,updatedAt:n.updatedAt,slug:e,runDir:m(this.flowsDir,e),topic:n.topic,phase:r,isEpilogue:r!==`flow`,roots:n.roots,primaryRoot:n.primaryRoot}}start(e,t,n,i){let a=this.findActiveRun();if(a)return{success:!1,error:`Flow "${a.meta.flow}" is already active. Reset it first.`};let o=this.buildStepSequence(t);if(!o.length)return{success:!1,error:`Flow has no steps`};try{let a=(n??t.description)||e,s=this.generateSlug(a),c=m(this.flowsDir,s),l=new Date().toISOString(),u=o[0],d={id:s,flow:e,flowVersion:t.version,flowOrigin:i,topic:a,status:`active`,currentStep:u.id,currentToken:void 0,completedSteps:[],completedTokens:[],skippedSteps:[],executionLog:[],artifactsDir:t.artifacts_dir,artifacts:{},startedAt:l,updatedAt:l,phase:u.phase,completedEpilogueSteps:[],skippedEpilogueSteps:[]};return this.activateStep(d,o,0),r(c,{recursive:!0}),r(m(c,t.artifacts_dir),{recursive:!0}),this.writeMeta(s,d),{success:!0,data:this.metaToState(s,d)}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}step(e,t){let r=this.findActiveRun();if(!r)return{success:!1,error:`No active flow`};if(r.meta.status!==`active`)return{success:!1,error:`Flow is ${r.meta.status}, not active`};if(!r.meta.currentStep)return{success:!1,error:`No current step`};let i=r.meta.currentStep,a=this.buildStepSequence(t),o=a.findIndex(e=>e.id===i);if(o===-1)return{success:!1,error:`Current step "${r.meta.currentStep}" not found in manifest`};let s=a[o],c=new Date().toISOString(),l=this.normalizeMeta(r.meta);switch(e){case`next`:if(s.phase===`flow`){let e=t.steps.find(e=>e.id===i);if(e&&e.produces.length>0){let a=m(m(this.flowsDir,r.slug),t.artifacts_dir),o=e.produces.filter(e=>!n(m(a,e)));if(o.length>0)return{success:!1,error:`Step "${i}" cannot advance — missing required artifacts in ${t.artifacts_dir}/: ${o.join(`, `)}. Create these files before advancing.`}}}s.phase===`flow`?l.completedSteps.includes(i)||l.completedSteps.push(i):l.completedEpilogueSteps.includes(i)||l.completedEpilogueSteps.push(i),this.finalizeCurrentStep(l,`completed`,c),this.activateStep(l,a,o+1);break;case`skip`:s.phase===`flow`?l.skippedSteps.includes(i)||l.skippedSteps.push(i):l.skippedEpilogueSteps.includes(i)||l.skippedEpilogueSteps.push(i),this.finalizeCurrentStep(l,`skipped`,c),this.activateStep(l,a,o+1);break;case`redo`:this.markCrashedExecution(l),s.phase===`flow`?(l.completedSteps=l.completedSteps.filter(e=>e!==i),l.skippedSteps=l.skippedSteps.filter(e=>e!==i)):(l.completedEpilogueSteps=l.completedEpilogueSteps.filter(e=>e!==i),l.skippedEpilogueSteps=l.skippedEpilogueSteps.filter(e=>e!==i)),l.currentToken=void 0,this.activateStep(l,a,o,{force:!0});break}return l.updatedAt=c,this.writeMeta(r.slug,l),{success:!0,data:this.metaToState(r.slug,l)}}getStatus(){let e=this.findActiveRun();return e?{success:!0,data:this.metaToState(e.slug,e.meta)}:{success:!1,error:`No active flow`}}reset(){let e=this.findActiveRun();return e?(e.meta.status=`abandoned`,e.meta.currentStep=null,e.meta.updatedAt=new Date().toISOString(),this.writeMeta(e.slug,e.meta),{success:!0}):{success:!0}}recordArtifact(e,t){let n=this.findActiveRun();return n?(n.meta.artifacts[e]=t,n.meta.updatedAt=new Date().toISOString(),this.writeMeta(n.slug,n.meta),{success:!0}):{success:!1,error:`No active flow`}}listRuns(e){if(!n(this.flowsDir))return[];let t=[];for(let n of a(this.flowsDir,{withFileTypes:!0})){if(!n.isDirectory())continue;let r=this.readMeta(n.name);r&&(e?.flow&&r.flow!==e.flow||e?.status&&r.status!==e.status||t.push({id:n.name,flow:r.flow,flowOrigin:r.flowOrigin,topic:r.topic,status:r.status,currentStep:r.currentStep,startedAt:r.startedAt,updatedAt:r.updatedAt}))}return t.sort((e,t)=>t.updatedAt.localeCompare(e.updatedAt))}},J=class{createSymlinks(t,i,a,o){let s=this.getTargets(t,i);for(let t of s){n(t.baseDir)||r(t.baseDir,{recursive:!0});for(let r of o.agents){let i=m(a,r);if(!n(i))continue;let o=this.getAgentStem(r),s=m(t.baseDir,`${o}${t.extension}`);n(s)&&u(s);let c=h(p(s),i);try{l(c,s,`file`)}catch{try{e(i,s)}catch(e){console.warn(`Failed to create symlink or copy fallback for ${i}: ${e instanceof Error?e.message:String(e)}`)}}}}}removeSymlinks(e,t){let r=this.getTargets(e,t);for(let e of r)if(n(e.baseDir))try{let t=a(e.baseDir,{withFileTypes:!0});for(let n of t)!n.isFile()&&!n.isSymbolicLink()||u(m(e.baseDir,n.name));a(e.baseDir).length===0&&c(e.baseDir)}catch{}}getTargets(e,t){return[{ide:`copilot`,baseDir:m(e,`.github`,`agents`,`flows`,t),extension:`.agent.md`},{ide:`claude-code`,baseDir:m(e,`.claude`,`agents`,`flows`,t),extension:`.md`}]}getAgentStem(e){return f(e).replace(/\.agent\.md$/,``).replace(/\.md$/,``)}};export{w as ClaudePluginAdapter,T as CopilotAdapter,W as FlowLoader,K as FlowRegistryManager,q as FlowStateMachine,P as FoundationIntegration,B as GitInstaller,E as NativeAdapter,D as OpenSpecAdapter,J as SymlinkManager,A as getBuiltinFlows};
|