@vpxa/aikit 0.1.343 → 0.1.345

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/package.json +1 -1
  2. package/packages/blocks-core/dist/index.mjs +16 -16
  3. package/packages/cli/dist/index.js +19 -19
  4. package/packages/cli/dist/{init-DgYgDXBw.js → init-XINdWZ5p.js} +1 -1
  5. package/packages/cli/dist/{templates-DEHhml1n.js → templates-Cjsh5cLs.js} +48 -16
  6. package/packages/core/dist/index.d.ts +269 -2
  7. package/packages/core/dist/index.js +1 -1
  8. package/packages/flows/dist/index.d.ts +141 -4
  9. package/packages/flows/dist/index.js +6 -6
  10. package/packages/server/dist/bin.js +1 -1
  11. package/packages/server/dist/config-BsS-77rp.js +2 -0
  12. package/packages/server/dist/config-Ds28Hvip.js +1 -0
  13. package/packages/server/dist/index.js +1 -1
  14. package/packages/server/dist/prelude-DYBTvrwz.js +2 -0
  15. package/packages/server/dist/prelude-V2gaMyeg.js +1 -0
  16. package/packages/server/dist/promotion-DRnRfteq.js +3 -0
  17. package/packages/server/dist/promotion-DzVLWVtx.js +2 -0
  18. package/packages/server/dist/sampling-0YAQqixD.js +1 -0
  19. package/packages/server/dist/sampling-BQmYJ4pz.js +2 -0
  20. package/packages/server/dist/{server-WTo9MN4i.js → server--QWu4dF1.js} +196 -198
  21. package/packages/server/dist/{server-QHpy3Vo9.js → server-Cv8aM3Xx.js} +195 -199
  22. package/packages/server/dist/{server-http-fvgPEVn5.js → server-http-BF6fnIQ0.js} +1 -1
  23. package/packages/server/dist/{server-http-Cxq-Bg3K.js → server-http-DoIPqaqk.js} +1 -1
  24. package/packages/server/dist/{server-stdio-vC20j-3j.js → server-stdio-CFH9BET5.js} +1 -1
  25. package/packages/server/dist/{server-stdio-DiT0r0Q3.js → server-stdio-CXF39-d2.js} +1 -1
  26. package/packages/server/dist/{startup-maintenance-L9NUOBVy.js → startup-maintenance-CBJWiJ7p.js} +1 -1
  27. package/packages/server/dist/{startup-maintenance-DYmXBVTV.js → startup-maintenance-DX1yTfBa.js} +1 -1
  28. package/packages/server/dist/version-check-BjFqR01r.js +1 -0
  29. package/packages/server/dist/version-check-_2wmedTl.js +2 -0
  30. package/packages/tools/dist/index.d.ts +140 -1
  31. package/packages/tools/dist/index.js +87 -82
  32. package/scaffold/dist/adapters/_shared.mjs +9 -9
  33. package/scaffold/dist/definitions/agents.mjs +2 -2
  34. package/scaffold/dist/definitions/bodies.mjs +22 -14
  35. package/scaffold/dist/definitions/flows.mjs +28 -12
  36. package/scaffold/dist/definitions/protocols.mjs +38 -8
  37. package/scaffold/dist/definitions/skills/aikit.mjs +80 -17
  38. package/scaffold/dist/definitions/skills/docs.mjs +9 -0
  39. package/scaffold/dist/definitions/skills/lesson-learned.mjs +9 -0
  40. package/scaffold/dist/definitions/skills/multi-agents-development.mjs +10 -5
  41. package/scaffold/dist/definitions/skills/present.mjs +14 -0
  42. package/packages/server/dist/config-B-wvmMyo.js +0 -1
  43. package/packages/server/dist/config-Bx85fwRX.js +0 -2
  44. package/packages/server/dist/prelude-CYbX3SD5.js +0 -1
  45. package/packages/server/dist/prelude-SM1mxlBF.js +0 -2
  46. package/packages/server/dist/promotion-RbjKfC88.js +0 -3
  47. package/packages/server/dist/promotion-l1L8Vf7U.js +0 -2
  48. package/packages/server/dist/version-check-2-tfmCnt.js +0 -2
  49. package/packages/server/dist/version-check-BKtLrLhw.js +0 -1
@@ -18,9 +18,10 @@ Use AI Kit as compression, memory, validation, and coordination layer. Each call
18
18
 
19
19
  Start:
20
20
  1. status({ includePrelude: true }); onboard if missing.
21
- 2. search({ query: "SESSION CHECKPOINT", origin: "curated" }).
22
- 3. flow({ action: 'status' }) when active flow may exist.
23
- 4. scope_map({ task }) for non-trivial work.
21
+ 2. **L0 session start**: \`status({ includePrelude: true })\` auto-injects workspace-core. If a flow is active, workflow card loaded via flow context. ≤ 2,100 tokens.
22
+ 3. search({ query: "SESSION CHECKPOINT", origin: "curated" }).
23
+ 4. flow({ action: 'status' }) when active flow may exist — use L1 snapshot before broad retrieval.
24
+ 5. scope_map({ task }) for non-trivial work.
24
25
 
25
26
  During:
26
27
  - Prefer search/file_summary/compact/digest/symbol/trace/graph over raw reads.
@@ -34,20 +35,26 @@ End:
34
35
  - session_digest({ persist: true }).
35
36
  - knowledge remember session checkpoint with done/decisions/next/blockers.
36
37
 
37
- ## Retrieval Ladder
38
-
39
- | Need | Tool |
40
- |---|---|
41
- | Prior decisions/conventions | search / knowledge |
42
- | File structure | file_summary |
43
- | Exact relevant section | compact |
44
- | Many files | digest |
45
- | Symbol defs/refs | symbol |
46
- | Call/data flow | trace |
47
- | Module/import relationships | graph |
48
- | Impact | blast_radius |
49
- | Type/lint/test | check / test_run |
50
- | Tool choice unknown | list_tools -> search_tools -> describe_tool |
38
+ ## Retrieval Ladder — Layered (L0-L3)
39
+
40
+ | Layer | Need | Tool |
41
+ |-------|------|------|
42
+ | **L0** | Session briefing (auto) | \`status({ includePrelude: true })\` — workspace-core pre-injected, no manual load needed |
43
+ | **L0** | Architecture overview | \`architecture\` briefing card |
44
+ | **L0** | Known issues | \`known-issues\` briefing card |
45
+ | **L0** | Flow-specific context | \`workflow:<flow>\` briefing card |
46
+ | **L1** | Active flow state | \`knowledge({ action: 'withdraw', scope: 'flow', profile: '<role>' })\` |
47
+ | **L2** | Prior decisions/conventions | \`search\` / \`knowledge\` |
48
+ | **L2** | File structure | \`file_summary\` |
49
+ | **L2** | Exact relevant section | \`compact\` |
50
+ | **L2** | Many files | \`digest\` |
51
+ | **L2** | Symbol defs/refs | \`symbol\` |
52
+ | **L2** | Call/data flow | \`trace\` |
53
+ | **L2** | Module/import relationships | \`graph\` |
54
+ | **L2** | Impact | \`blast_radius\` |
55
+ | **L2** | Type/lint/test | \`check\` / \`test_run\` |
56
+ | **L3** | Evidence, provenance, conflict review | \`search\` with \`knowledge({ action: 'lesson' })\` — focused only |
57
+ | **General** | Tool choice unknown | \`list_tools\` → \`search_tools\` → \`describe_tool\` |
51
58
 
52
59
  Raw read_file only for exact edit lines after compressed tools identify target.
53
60
 
@@ -76,10 +83,17 @@ Review decayed/stale entries periodically with knowledge({ action: 'flagged' }).
76
83
 
77
84
  Flows guide multi-step work. Read active step before acting. FORGE handles tiering/evidence/gates; load references only when main skill is too thin.
78
85
 
86
+ ### Layered Knowledge Protocol
87
+ - **L0** → Generated briefing cards: always load \`workspace-core\` at session start; add \`workflow:<flow>\` if flow active, or one task card if no flow. Use \`stratum_card\` / \`compact\` for content. Token-bounded.
88
+ - **L1** → Flow working context. Withdraw before dispatch; reuse before broad retrieval.
89
+ - **L2** → Canonical curated knowledge. Retrieve on demand; never preload broadly.
90
+ - **L3** → Evidence/auto-knowledge. Inspect only for provenance, conflict, or promotion assessment.
91
+
79
92
  Reference docs:
80
93
  - references/coordination.md - queue, lanes, stash, checkpoints, signaling.
81
94
  - references/forge-protocol.md - tiering, evidence, gates.
82
95
  - references/search-patterns.md - search, trace, graph, compression recipes.
96
+ - references/layered-knowledge-protocol.md - L0-L3 operating policy and hot path.
83
97
 
84
98
  ## Self-Dogfooding
85
99
 
@@ -179,4 +193,53 @@ file_summary → compact → digest → read_file only for edit lines
179
193
  ## Rule of Thumb
180
194
 
181
195
  If you are about to read raw code, ask whether the answer is really about structure, relevance, flow, or relationships. AI Kit has a smaller tool for each of those.
196
+ `},{file:`references/layered-knowledge-protocol.md`,content:`# Layered Knowledge Protocol
197
+
198
+ AI Kit delivers knowledge through four layers:
199
+
200
+ ## L0 — Generated Briefing Cards
201
+
202
+ Fast, compact task setup loaded at session start.
203
+
204
+ - **Auto-injected**: \`workspace-core\` (800-1200 tokens) — included in \`status({ includePrelude: true })\` output
205
+ - **If flow active**: Load \`workflow:<flow>\` (500-900 tokens) via flow start refs (replaces task card)
206
+ - **If no flow**: Optionally load one task card via \`stratum_card\` / \`compact\`
207
+ - **Budget**: ≤ 2,100 tokens total
208
+ - **Storage**: Generated workspace cache (path from server config)
209
+ - **Card families**: \`workspace-core\`, \`architecture\`, \`testing-release\`, \`known-issues\`, \`workflow:<flow>\`
210
+ - Session-start budget: workspace-core (800-1200 tokens) + 1 additional card ≤ 2,100 tokens total
211
+ - Generated cache, not canonical — rebuildable from L2 canonical sources
212
+
213
+ ## L1 — Flow Working Context
214
+
215
+ Active run state and role-filtered dispatch context.
216
+
217
+ - Withdraw via \`knowledge({ action: 'withdraw', scope: 'flow', profile: '<role>', budget: 6000 })\`
218
+ - Use withdrawn refs before calling \`compact\`, \`file_summary\`, \`stratum_card\`, \`scope_map\`, \`blast_radius\`, or \`search\`
219
+ - Each step has a declared \`contextProfile\` (implementer, reviewer, researcher, documenter, debugger)
220
+
221
+ ## L2 — Canonical Curated Knowledge
222
+
223
+ Durable workspace archive managed by CuratedKnowledgeManager.
224
+
225
+ - Retrieve on demand via \`search()\` or \`knowledge({ action: 'read' })\`
226
+ - Never preload broadly at session start when L1 refs are already supplied
227
+ - Markdown is the canonical form; vector/FTS indexes are derived
228
+
229
+ ## L3 — Evidence Archive
230
+
231
+ High-volume observations, proofs, failures, and runtime traces.
232
+
233
+ - Never auto-injected into session or step context
234
+ - Inspect only for provenance verification, conflict review, or promotion assessment
235
+ - Auto-knowledge extractors write to L3; they cannot navigate flow state or promote
236
+
237
+ ## Retrieval Order
238
+
239
+ 1. L0 (loaded cards at session start)
240
+ 2. L1 (flow withdrawal when active)
241
+ 3. L2 (on-demand canonical knowledge)
242
+ 4. L3 (focused evidence retrieval only)
243
+
244
+ No active flow → keep L1 absent; use L0 + on-demand L2; turn-local context only.
182
245
  `}];export{e as default};
@@ -2260,6 +2260,15 @@ Use for docs/ creation, refresh, migration, tours, architecture docs, PRDs, and
2260
2260
 
2261
2261
  If one page mixes modes, split it.
2262
2262
 
2263
+ ## Layered Knowledge Integration
2264
+
2265
+ Doc changes produce L2 canonical candidates through the flow epilogue.
2266
+
2267
+ - **L2 candidate mapping**: Durable documentation changes (new ADRs, architecture docs, reference updates) are L2 promotion candidates after verified final consolidation.
2268
+ - **Evidence chain**: Every doc claim should trace to an L2 curated source or L3 evidence receipt.
2269
+ - **No direct promotion**: Docs role is candidate author, not promotion authority. Consolidation adjudication decides promote/hold/supersede.
2270
+ - **Card invalidation**: Topic changes that affect L0 briefing cards schedule regeneration via the briefing-card-compiler.
2271
+
2263
2272
  ## Scenario Detection
2264
2273
 
2265
2274
  | Condition | Mode |
@@ -180,6 +180,15 @@ Search before storing. Confirm/contradict existing lessons when new evidence sup
180
180
 
181
181
  Load anti-patterns.md for low-quality lesson smells. Load se-principles.md for naming/generalization help. Load references/extraction-workflow.md for the detailed 5-phase extraction workflow with git commands and categorization rubric.
182
182
 
183
+ ## Layered Knowledge Integration
184
+
185
+ Lessons are a knowledge **kind** and a promotion **signal**, not a confidence-only gate.
186
+
187
+ - **L1/L3 evidence**: Emit evidence-backed candidate learnings into flow context (L1) and evidence archive (L3). Use \`knowledge({ action: 'remember', scope: 'flow', ... })\` for step-level candidate learnings.
188
+ - **No direct promotion**: Candidate learnings require verified final consolidation before promotion adjudication. Confidence alone never promotes.
189
+ - **Recurrence threshold**: Single observation → L3 evidence. Same pattern ≥3 diffs → promotion candidate.
190
+ - **Impact signal**: High-impact one-time fix with strong evidence can promote without recurrence (e.g., security vulnerability, data loss prevention).
191
+
183
192
  ## Output
184
193
 
185
194
  Report created/updated/skipped lessons, confidence, evidence, and reason if skipped.
@@ -467,23 +467,28 @@ Every subagent prompt includes:
467
467
  2. Goal + acceptance criteria.
468
468
  3. Files/boundary + do-not-touch list.
469
469
  4. Compressed context: relevant snippets, conventions, decisions, active flow paths.
470
- 5. Constraints: skills to load, libraries/patterns, no present, no flow advance.
471
- 6. FORGE: tier, task_id, evidence claims to add.
472
- 7. Validation: expected check, test_run, or reason skipped.
473
- 8. Return contract: DONE | DONE_WITH_CONCERNS | NEEDS_CONTEXT | BLOCKED, <=200 words unless blocked.
470
+ 5. **L0/L1 refs**: Include \`selectedCardRefs\`, \`retrievedRefs\`, and L1 \`FlowContextSnapshotV1\` fields relevant to the role.
471
+ 6. **Hard rule — no broad card reload**: Subagent must reuse supplied refs first. Must NOT independently reload \`workspace-core\`, architecture, testing-release, or known-issues cards when the dispatch already carries applicable refs.
472
+ 7. Constraints: skills to load, libraries/patterns, no present, no flow advance.
473
+ 8. FORGE: tier, task_id, evidence claims to add.
474
+ 9. Validation: expected check, test_run, or reason skipped.
475
+ 10. Return contract: DONE | DONE_WITH_CONCERNS | NEEDS_CONTEXT | BLOCKED, <=200 words unless blocked.
474
476
 
475
477
  Use references/implementer-prompt.md for implementation dispatches and references/parallel-dispatch-example.md for batch shape.
476
478
 
477
- ## Context Broker
479
+ ## Context Broker (Layered Knowledge)
478
480
 
479
481
  Before dispatch:
480
482
  - knowledge({ action: 'withdraw', scope: 'flow', profile: '<role>', budget: 6000 })
483
+ - Include \`selectedCardRefs\` (L0 card refs) and \`retrievedRefs\` (from L1) in the dispatch envelope.
481
484
  - Add only missing snippets with compact/digest.
482
485
  - Paste context into dispatch; do not tell subagent to rediscover basics.
486
+ - **Hard rule**: Subagent must reuse supplied L0/L1 refs before broad retrieval. Block if it reloads \`workspace-core\` or architecture cards independently.
483
487
 
484
488
  After subagent work:
485
489
  - Store durable findings with knowledge({ action: 'remember', scope: 'flow', ... }).
486
490
  - Summarize status/files/decisions/blockers into stash or session digest.
491
+ - Flag candidate learnings for L1 update; do not promote directly.
487
492
  - Flush flow context only when work completes.
488
493
 
489
494
  Profiles: implementer, documenter, reviewer, researcher, debugger.
@@ -43,6 +43,20 @@ Always include schemaVersion: 1 and title. Use concise description when helpful.
43
43
  - Free-form text input should use text-submit or elicitation when available.
44
44
  - Keep action ids stable, labels short, variants meaningful.
45
45
 
46
+ ## Transport
47
+
48
+ | Parameter | Effect |
49
+ |-----------|--------|
50
+ | \`actions\` or \`response.required\` | Auto-activates browser transport (external window) |
51
+ | \`preferBrowser: true\` | Forces browser transport even for mcp-app-only templates (e.g. task-plan-static@1) |
52
+ | \`preferBrowser: false\` | Forces inline rendering when supported |
53
+ | Not set | Auto-detects: CLI clients → browser, MCP App hosts → inline |
54
+
55
+ - Use \`preferBrowser: true\` when user explicitly requests "open in browser", "external window", or "browser transport"
56
+ - Templates \`c4@1\`, \`tour@1\`, \`process-flow@1\` are browser-only (interactive) — always open in browser
57
+ - Templates \`c4-static@1\`, \`task-plan-static@1\`, \`process-flow-static@1\` are mcp-app-only — inline by default, use \`preferBrowser\` to force browser
58
+ - Block-only surfaces (no template) respond to \`preferBrowser\` as expected
59
+
46
60
  ## Quality Bar
47
61
 
48
62
  - One clear title, no giant unstructured markdown dumps.
@@ -1 +0,0 @@
1
- import{o as e,t}from"./supersession-CWEne3av.js";import{fileURLToPath as n}from"node:url";import{AIKIT_RUNTIME_PATHS as r,EMBEDDING_DEFAULTS as i,computePartitionKey as a,createLogger as o,getPartitionDir as s,migrateLegacyWorkspaceLayout as c,serializeError as l}from"../../core/dist/index.js";import{existsSync as u,mkdirSync as d,readFileSync as f,writeFileSync as p}from"node:fs";import{dirname as m,isAbsolute as h,relative as g,resolve as _}from"node:path";const v={workingToEpisodicAccesses:2,episodicToSemanticReferences:3,semanticToProceduralVerifications:5},y={working:1,episodic:2,semantic:4,procedural:12};function b(e,t=v){switch(e.tier){case`working`:if(e.accessCount>=t.workingToEpisodicAccesses)return`episodic`;break;case`episodic`:if(e.accessCount>=t.workingToEpisodicAccesses+t.episodicToSemanticReferences)return`semantic`;break;case`semantic`:if(e.accessCount>=t.workingToEpisodicAccesses+t.episodicToSemanticReferences+t.semanticToProceduralVerifications)return`procedural`;break;case`procedural`:break;default:break}}function x(e,t,n){e.memoryMetaUpdateTier(t,n)}const S={stabilityHours:168,accessMultiplier:1.5,flagThreshold:.1,maxStabilityHours:8760};function C(e){return{...S,...e}}function w(e,t){if(!e)return t;let n=Date.parse(e);return Number.isNaN(n)?t:n}function T(e){return e&&e in y?e:`working`}function E(e,t,n,r=S,i){let a=typeof r==`string`?T(r):`working`,o=C(typeof r==`string`?i:r),s=w(e,w(n,Date.now())),c=Math.max(0,Date.now()-s)/(1e3*60*60),l=Math.min(o.stabilityHours*y[a]*o.accessMultiplier**Math.max(0,t),o.maxStabilityHours);return Math.exp(-c/l)}function D(e,t,n){let r=e.memoryMetaGet(t);if(!r)return;let i=E(r.lastAccessedAt,r.accessCount,r.createdAt,r.tier,n);return r.retentionScore!==i&&e.memoryMetaUpdateScore(t,i),e.memoryMetaGet(t)??{...r,retentionScore:i}}function O(e,t,n){e.memoryMetaGet(t)||e.memoryMetaCreate(t),e.memoryMetaTouch(t);let r=e.memoryMetaGet(t);if(!r)return 1;let i=E(r.lastAccessedAt,r.accessCount,r.createdAt,r.tier,n);return e.memoryMetaUpdateScore(t,i),i}function k(e,t){let n=C(t);return e.memoryMetaList().map(t=>D(e,t.entryId,n)??t).filter(e=>e.retentionScore<n.flagThreshold).sort((e,t)=>e.retentionScore-t.retentionScore)}const A=m(n(import.meta.url)),j=o(`server`),M=[`auto`,`manual`,`smart`],N={model:i.model,dimensions:i.dimensions,childProcess:!0,idleTimeoutMs:3e5};function P(e){return typeof e==`string`&&M.includes(e)}function F(e,t,n){let r=_(e),i=g(_(t),r);if(i.startsWith(`..`)||h(i))throw Error(`Config ${n} path escapes allowed root: ${e} is not under ${t}`);return r}function I(e,t){let n=_(e),r=g(_(t),n);return!(r.startsWith(`..`)||h(r))}function L(e){return s(a(e))}function R(e,t,n,r,i){let a=r?_(t,r):t;if(!n)return F(a,t,i);let o=_(e,n);return I(o,t)?r&&_(o)===_(t)?F(a,t,i):F(o,t,i):F(a,t,i)}function z(e){let t=[e.store?.path,e.curated?.path,e.onboardDir,e.stateDir];for(let e of t)e&&d(e,{recursive:!0})}function B(e,t){c(t);let n=L(t);e.store={...e.store,path:R(t,n,e.store?.path,r.data,`store`)},e.curated={...e.curated,path:R(t,n,e.curated?.path,r.curated,`curated`)},e.onboardDir=R(t,n,e.onboardDir,r.onboard,`onboard`),e.stateDir=R(t,n,e.stateDir,r.state,`state`)}function V(e){let t=process.env.AIKIT_INDEX_MODE;if(P(t))return t;if(e.indexMode)return e.indexMode;let n=process.env.AIKIT_AUTO_INDEX;return n===void 0?e.autoIndex===void 0?`smart`:e.autoIndex?`auto`:`manual`:n===`true`?`auto`:`manual`}function H(){let n=process.env.AIKIT_CONFIG_PATH??(u(_(process.cwd(),`aikit.config.json`))?_(process.cwd(),`aikit.config.json`):_(A,`..`,`..`,`..`,`aikit.config.json`));try{if(!u(n))return j.info(`No config file found, using defaults`,{configPath:n}),W();let r=f(n,`utf-8`),i=JSON.parse(r),a={...N,...i.embedding};if(i.embedding=a,i.memory={retention:{...S,...i.memory?.retention},lessons:{...e,...i.memory?.lessons},consolidation:{...v,...i.memory?.consolidation},supersession:{...t,...i.memory?.supersession}},i.logging?.errorDetails!==void 0&&typeof i.logging.errorDetails!=`boolean`)throw Error(`Config logging.errorDetails must be a boolean`);if(i.logging={errorDetails:i.logging?.errorDetails===!0},!i.sources||!Array.isArray(i.sources)||i.sources.length===0)throw Error(`Config must have at least one source`);if(!i.store?.path)throw Error(`Config must specify store.path`);if(i.autoIndex!==void 0&&typeof i.autoIndex!=`boolean`)throw Error(`Config autoIndex must be a boolean`);if(i.indexMode!==void 0&&!P(i.indexMode))throw Error(`Config indexMode must be one of: ${M.join(`, `)}`);if(typeof a.model!=`string`||a.model.trim()===``)throw Error(`Config embedding.model must be a non-empty string`);if(a.nativeDim!==void 0&&(!Number.isInteger(a.nativeDim)||a.nativeDim<=0))throw Error(`Config embedding.nativeDim must be a positive integer`);if(a.dimensions!==void 0&&(!Number.isInteger(a.dimensions)||a.dimensions<=0))throw Error(`Config embedding.dimensions must be a positive integer`);if(a.dimensions!==void 0&&a.nativeDim!==void 0&&a.dimensions>a.nativeDim)throw Error(`Config embedding.dimensions must not exceed embedding.nativeDim`);if(a.queryPrefix!==void 0&&typeof a.queryPrefix!=`string`)throw Error(`Config embedding.queryPrefix must be a string`);let o=m(n);return i.sources=i.sources.map(e=>({...e,path:F(_(o,e.path),o,`source`)})),G(i,n),B(i,o),i.indexMode=V(i),i}catch(e){let t=`Failed to load config from ${n}. ${e instanceof Error?e.message:String(e)}`;console.error(`\n ⚠ CONFIG ERROR — ${t}\n Check that the file exists, is valid JSON, and all required fields are present.\n`),j.error(`Failed to load config`,{configPath:n,...l(e)}),j.warn(`Falling back to default configuration`,{configPath:n});let r=W();return r.configError=t,r}}const U=[`.git/**`,`**/node_modules/**`,`*.lock`,`pnpm-lock.yaml`,`package-lock.json`,`**/dist/**`,`**/build/**`,`**/out/**`,`**/.output/**`,`**/cdk.out/**`,`**/.next/**`,`**/.nuxt/**`,`**/.vercel/**`,`**/.serverless/**`,`**/.turbo/**`,`**/.cache/**`,`**/.parcel-cache/**`,`**/coverage/**`,`**/.terraform/**`,`**/__pycache__/**`,`**/.venv/**`,`**/.docusaurus/**`,`**/.temp/**`,`**/tmp/**`];function W(){let n=process.env.AIKIT_WORKSPACE_ROOT??process.cwd(),i=L(n),a={sources:[{path:n,excludePatterns:[...U]}],serverName:`aikit`,indexing:{chunkSize:800,chunkOverlap:150,minChunkSize:100},embedding:{...N},store:{backend:`sqlite-vec`,path:_(i,r.data)},curated:{path:_(i,r.curated)},memory:{retention:{...S},lessons:{...e},consolidation:{...v},supersession:{...t}},logging:{errorDetails:!1},onboardDir:_(i,r.onboard),stateDir:_(i,r.state)};return a.indexMode=V(a),a}function G(e,t){let n=e.configVersion??0;if(n>=1)return e;if(n<1)for(let t of e.sources){t.excludePatterns=t.excludePatterns??[];let e=new Set(t.excludePatterns);for(let n of U)e.has(n)||t.excludePatterns.push(n)}e.configVersion=1;try{p(t,`${JSON.stringify(e,null,2)}\n`,`utf-8`),j.info(`Config auto-upgraded`,{from:n,to:1,configPath:t})}catch(e){j.warn(`Failed to write upgraded config`,{configPath:t,...l(e)})}return e}function K(e,t){if(!u(t))throw Error(`Workspace root does not exist: ${t}`);c(t),j.debug(`Reconfiguring for workspace root`,{workspaceRoot:t});try{process.chdir(t),j.debug(`Changed process cwd to workspace root`,{cwd:process.cwd()})}catch(e){j.warn(`Failed to chdir to workspace root`,{workspaceRoot:t,...l(e)})}e.sources=[{path:t,excludePatterns:e.sources[0]?.excludePatterns??[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],B(e,t),z(e)}export{U as DEFAULT_EXCLUDE_PATTERNS,b as a,v as i,H as loadConfig,D as n,x as o,O as r,K as reconfigureForWorkspace,V as resolveIndexMode,k as t};
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import{o as e,t}from"./supersession-DO_ZROFl.js";import{fileURLToPath as n}from"node:url";import{AIKIT_RUNTIME_PATHS as r,EMBEDDING_DEFAULTS as i,computePartitionKey as a,createLogger as o,getPartitionDir as s,migrateLegacyWorkspaceLayout as c,serializeError as l}from"../../core/dist/index.js";import{existsSync as u,mkdirSync as d,readFileSync as f,writeFileSync as p}from"node:fs";import{dirname as m,isAbsolute as h,relative as g,resolve as _}from"node:path";const v={workingToEpisodicAccesses:2,episodicToSemanticReferences:3,semanticToProceduralVerifications:5},y={working:1,episodic:2,semantic:4,procedural:12};function b(e,t=v){switch(e.tier){case`working`:if(e.accessCount>=t.workingToEpisodicAccesses)return`episodic`;break;case`episodic`:if(e.accessCount>=t.workingToEpisodicAccesses+t.episodicToSemanticReferences)return`semantic`;break;case`semantic`:if(e.accessCount>=t.workingToEpisodicAccesses+t.episodicToSemanticReferences+t.semanticToProceduralVerifications)return`procedural`;break;case`procedural`:break;default:break}}function x(e,t,n){e.memoryMetaUpdateTier(t,n)}const S={stabilityHours:168,accessMultiplier:1.5,flagThreshold:.1,maxStabilityHours:8760};function C(e){return{...S,...e}}function w(e,t){if(!e)return t;let n=Date.parse(e);return Number.isNaN(n)?t:n}function T(e){return e&&e in y?e:`working`}function E(e,t,n,r=S,i){let a=typeof r==`string`?T(r):`working`,o=C(typeof r==`string`?i:r),s=w(e,w(n,Date.now())),c=Math.max(0,Date.now()-s)/(1e3*60*60),l=Math.min(o.stabilityHours*y[a]*o.accessMultiplier**Math.max(0,t),o.maxStabilityHours);return Math.exp(-c/l)}function D(e,t,n){let r=e.memoryMetaGet(t);if(!r)return;let i=E(r.lastAccessedAt,r.accessCount,r.createdAt,r.tier,n);return r.retentionScore!==i&&e.memoryMetaUpdateScore(t,i),e.memoryMetaGet(t)??{...r,retentionScore:i}}function O(e,t,n){e.memoryMetaGet(t)||e.memoryMetaCreate(t),e.memoryMetaTouch(t);let r=e.memoryMetaGet(t);if(!r)return 1;let i=E(r.lastAccessedAt,r.accessCount,r.createdAt,r.tier,n);return e.memoryMetaUpdateScore(t,i),i}function k(e,t){let n=C(t);return e.memoryMetaList().map(t=>D(e,t.entryId,n)??t).filter(e=>e.retentionScore<n.flagThreshold).sort((e,t)=>e.retentionScore-t.retentionScore)}const A=m(n(import.meta.url)),j=o(`server`),M=[`auto`,`manual`,`smart`],N={model:i.model,dimensions:i.dimensions,childProcess:!0,idleTimeoutMs:3e5};function P(e){return typeof e==`string`&&M.includes(e)}function F(e,t,n){let r=_(e),i=g(_(t),r);if(i.startsWith(`..`)||h(i))throw Error(`Config ${n} path escapes allowed root: ${e} is not under ${t}`);return r}function I(e,t){let n=_(e),r=g(_(t),n);return!(r.startsWith(`..`)||h(r))}function L(e){return s(a(e))}function R(e,t,n,r,i){let a=r?_(t,r):t;if(!n)return F(a,t,i);let o=_(e,n);return I(o,t)?r&&_(o)===_(t)?F(a,t,i):F(o,t,i):F(a,t,i)}function z(e){let t=[e.store?.path,e.curated?.path,e.onboardDir,e.stateDir];for(let e of t)e&&d(e,{recursive:!0})}function B(e,t){c(t);let n=L(t);e.store={...e.store,path:R(t,n,e.store?.path,r.data,`store`)},e.curated={...e.curated,path:R(t,n,e.curated?.path,r.curated,`curated`)},e.onboardDir=R(t,n,e.onboardDir,r.onboard,`onboard`),e.stateDir=R(t,n,e.stateDir,r.state,`state`)}function V(e){let t=process.env.AIKIT_INDEX_MODE;if(P(t))return t;if(e.indexMode)return e.indexMode;let n=process.env.AIKIT_AUTO_INDEX;return n===void 0?e.autoIndex===void 0?`smart`:e.autoIndex?`auto`:`manual`:n===`true`?`auto`:`manual`}function H(){let n=process.env.AIKIT_CONFIG_PATH??(u(_(process.cwd(),`aikit.config.json`))?_(process.cwd(),`aikit.config.json`):_(A,`..`,`..`,`..`,`aikit.config.json`));try{if(!u(n))return j.info(`No config file found, using defaults`,{configPath:n}),W();let r=f(n,`utf-8`),i=JSON.parse(r),a={...N,...i.embedding};if(i.embedding=a,i.memory={retention:{...S,...i.memory?.retention},lessons:{...e,...i.memory?.lessons},consolidation:{...v,...i.memory?.consolidation},supersession:{...t,...i.memory?.supersession}},i.logging?.errorDetails!==void 0&&typeof i.logging.errorDetails!=`boolean`)throw Error(`Config logging.errorDetails must be a boolean`);if(i.logging={errorDetails:i.logging?.errorDetails===!0},!i.sources||!Array.isArray(i.sources)||i.sources.length===0)throw Error(`Config must have at least one source`);if(!i.store?.path)throw Error(`Config must specify store.path`);if(i.autoIndex!==void 0&&typeof i.autoIndex!=`boolean`)throw Error(`Config autoIndex must be a boolean`);if(i.indexMode!==void 0&&!P(i.indexMode))throw Error(`Config indexMode must be one of: ${M.join(`, `)}`);if(typeof a.model!=`string`||a.model.trim()===``)throw Error(`Config embedding.model must be a non-empty string`);if(a.nativeDim!==void 0&&(!Number.isInteger(a.nativeDim)||a.nativeDim<=0))throw Error(`Config embedding.nativeDim must be a positive integer`);if(a.dimensions!==void 0&&(!Number.isInteger(a.dimensions)||a.dimensions<=0))throw Error(`Config embedding.dimensions must be a positive integer`);if(a.dimensions!==void 0&&a.nativeDim!==void 0&&a.dimensions>a.nativeDim)throw Error(`Config embedding.dimensions must not exceed embedding.nativeDim`);if(a.queryPrefix!==void 0&&typeof a.queryPrefix!=`string`)throw Error(`Config embedding.queryPrefix must be a string`);let o=m(n);return i.sources=i.sources.map(e=>({...e,path:F(_(o,e.path),o,`source`)})),G(i,n),B(i,o),i.indexMode=V(i),i}catch(e){let t=`Failed to load config from ${n}. ${e instanceof Error?e.message:String(e)}`;console.error(`\n ⚠ CONFIG ERROR — ${t}\n Check that the file exists, is valid JSON, and all required fields are present.\n`),j.error(`Failed to load config`,{configPath:n,...l(e)}),j.warn(`Falling back to default configuration`,{configPath:n});let r=W();return r.configError=t,r}}const U=[`.git/**`,`**/node_modules/**`,`*.lock`,`pnpm-lock.yaml`,`package-lock.json`,`**/dist/**`,`**/build/**`,`**/out/**`,`**/.output/**`,`**/cdk.out/**`,`**/.next/**`,`**/.nuxt/**`,`**/.vercel/**`,`**/.serverless/**`,`**/.turbo/**`,`**/.cache/**`,`**/.parcel-cache/**`,`**/coverage/**`,`**/.terraform/**`,`**/__pycache__/**`,`**/.venv/**`,`**/.docusaurus/**`,`**/.temp/**`,`**/tmp/**`];function W(){let n=process.env.AIKIT_WORKSPACE_ROOT??process.cwd(),i=L(n),a={sources:[{path:n,excludePatterns:[...U]}],serverName:`aikit`,indexing:{chunkSize:800,chunkOverlap:150,minChunkSize:100},embedding:{...N},store:{backend:`sqlite-vec`,path:_(i,r.data)},curated:{path:_(i,r.curated)},memory:{retention:{...S},lessons:{...e},consolidation:{...v},supersession:{...t}},logging:{errorDetails:!1},onboardDir:_(i,r.onboard),stateDir:_(i,r.state)};return a.indexMode=V(a),a}function G(e,t){let n=e.configVersion??0;if(n>=1)return e;if(n<1)for(let t of e.sources){t.excludePatterns=t.excludePatterns??[];let e=new Set(t.excludePatterns);for(let n of U)e.has(n)||t.excludePatterns.push(n)}e.configVersion=1;try{p(t,`${JSON.stringify(e,null,2)}\n`,`utf-8`),j.info(`Config auto-upgraded`,{from:n,to:1,configPath:t})}catch(e){j.warn(`Failed to write upgraded config`,{configPath:t,...l(e)})}return e}function K(e,t){if(!u(t))throw Error(`Workspace root does not exist: ${t}`);c(t),j.debug(`Reconfiguring for workspace root`,{workspaceRoot:t});try{process.chdir(t),j.debug(`Changed process cwd to workspace root`,{cwd:process.cwd()})}catch(e){j.warn(`Failed to chdir to workspace root`,{workspaceRoot:t,...l(e)})}e.sources=[{path:t,excludePatterns:e.sources[0]?.excludePatterns??[`node_modules/**`,`dist/**`,`.git/**`,`coverage/**`,`*.lock`,`pnpm-lock.yaml`]}],B(e,t),z(e)}export{U as DEFAULT_EXCLUDE_PATTERNS,b as a,v as i,H as loadConfig,D as n,x as o,O as r,K as reconfigureForWorkspace,V as resolveIndexMode,k as t};
@@ -1 +0,0 @@
1
- import{n as e,t}from"./server-WTo9MN4i.js";export{t as buildPreludeInjection,e as generatePrelude};
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import{n as e,t}from"./server-QHpy3Vo9.js";export{t as buildPreludeInjection,e as generatePrelude};
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- import{t as e}from"./rolldown-runtime-yuFVEuWy.js";import{t}from"./bin.js";import{f as n,r,u as i}from"./supersession-DO_ZROFl.js";import{getGlobalDataDir as a,isUserInstalled as o,listWorkspaces as s}from"../../core/dist/index.js";import{existsSync as c,mkdirSync as l}from"node:fs";import{join as u}from"node:path";var d=e({DEFAULT_PROMOTE_CONFIG:()=>f,collectWorkspaceLessons:()=>w,demoteLesson:()=>D,getGlobalCuratedDir:()=>C,promoteLessons:()=>E,scanForDuplicates:()=>T});const f={minWorkspaces:2,minAvgConfidence:80,similarityThreshold:.7,dryRun:!0};function p(e){return{minWorkspaces:Math.max(2,Math.trunc(e?.minWorkspaces??f.minWorkspaces)),minAvgConfidence:Math.min(100,Math.max(0,Math.trunc(e?.minAvgConfidence??f.minAvgConfidence))),similarityThreshold:Math.min(1,Math.max(0,e?.similarityThreshold??f.similarityThreshold)),dryRun:e?.dryRun??f.dryRun}}function m(e,t){let n=e.map(()=>[]);for(let i=0;i<e.length;i+=1)for(let a=i+1;a<e.length;a+=1)r(e[i].insight,e[a].insight)>=t&&(n[i].push(a),n[a].push(i));return n}function h(e){let t=new Set,n=[];for(let r=0;r<e.length;r+=1){if(t.has(r))continue;let i=[r],a=[];for(t.add(r);i.length>0;){let n=i.pop();if(n!==void 0){a.push(n);for(let r of e[n])t.has(r)||(t.add(r),i.push(r))}}n.push(a)}return n}function g(e){return new t(e,null,null)}function _(e){return(e??``).replace(/\s+/g,` `).trim()}function v(e){let t=_(e);return t.length<=80?t:`${t.slice(0,77).replace(/\s+\S*$/,``)}...`}function y(e){return i({title:v(e.insight),context:`Observed across ${e.foundIn.length} workspaces: ${e.foundIn.join(`, `)}`,insight:e.insight,evidence:[`Promoted from workspaces: ${e.foundIn.join(`, `)}`,`Average confidence: ${e.avgConfidence}/100`,`Reason: ${e.reason}`].join(`
3
- `),confidence:e.avgConfidence,tags:[`lesson`,`promoted`,`global`]})}async function b(e,t){let r=await e.list({category:`lessons`,limit:1e3,orderBy:`updated`,order:`desc`});return(await Promise.all(r.map(async r=>{let i=await e.read(r.path),a=n(i.content),o=_(a.insight);return o?{workspace:t,path:r.path,title:a.title??i.title??r.title,insight:o,confidence:a.confidence??0}:null}))).filter(e=>e!==null)}async function x(e){return(await b(e,`global`)).map(e=>e.insight)}function S(e,t,n){return t.some(t=>r(t,e)>=n)}function C(){let e=u(a(),`global-knowledge`,`.ai`,`curated`);return c(e)||l(e,{recursive:!0}),e}async function w(e){let t=new Map;if(!o())return t;for(let e of s()){let n=u(e.workspacePath,`.ai`,`curated`);if(!c(n))continue;let r=await b(g(n),e.partition);r.length>0&&t.set(e.partition,r)}return t}function T(e,t=f){let n=p(t),r=[...e.values()].flat();if(r.length===0)return[];let i=h(m(r,n.similarityThreshold)),a=[];for(let e of i){let t=e.map(e=>r[e]),i=[...new Set(t.map(e=>e.workspace))].sort();if(i.length<n.minWorkspaces)continue;let o=Math.round(t.reduce((e,t)=>e+t.confidence,0)/t.length),s=[...t].sort((e,t)=>t.confidence-e.confidence||e.title.localeCompare(t.title)||e.path.localeCompare(t.path))[0];a.push({insight:s.insight,foundIn:i,avgConfidence:o,action:o>=n.minAvgConfidence?`promote`:`skip`,reason:o>=n.minAvgConfidence?`Shared across ${i.length} workspaces`:`Below confidence threshold`})}return a.sort((e,t)=>Number(t.action===`promote`)-Number(e.action===`promote`)||t.foundIn.length-e.foundIn.length||t.avgConfidence-e.avgConfidence||e.insight.localeCompare(t.insight))}async function E(e,t,n=f){let r=p(n),i=[],a=await x(t);for(let n of e){if(n.action!==`promote`||S(n.insight,a,r.similarityThreshold)||r.dryRun)continue;let e=await t.remember(v(n.insight),y(n),`lessons`,[`lesson`,`promoted`,`global`]);i.push(e.path),a.push(n.insight)}return{candidates:e,promoted:i}}async function D(e,t){try{return await e.forget(t,`Demoted from global knowledge partition`),{removed:!0,path:t}}catch(e){if(e instanceof Error&&/not found/i.test(e.message))return{removed:!1,path:t};throw e}}export{E as a,C as i,w as n,d as o,D as r,T as s,f as t};
@@ -1,2 +0,0 @@
1
- import{t as e}from"./rolldown-runtime-DT7IzrpZ.js";import{t}from"./curated-manager-CBKTmAjM.js";import{f as n,r,u as i}from"./supersession-CWEne3av.js";import{getGlobalDataDir as a,isUserInstalled as o,listWorkspaces as s}from"../../core/dist/index.js";import{existsSync as c,mkdirSync as l}from"node:fs";import{join as u}from"node:path";var d=e({DEFAULT_PROMOTE_CONFIG:()=>f,collectWorkspaceLessons:()=>w,demoteLesson:()=>D,getGlobalCuratedDir:()=>C,promoteLessons:()=>E,scanForDuplicates:()=>T});const f={minWorkspaces:2,minAvgConfidence:80,similarityThreshold:.7,dryRun:!0};function p(e){return{minWorkspaces:Math.max(2,Math.trunc(e?.minWorkspaces??f.minWorkspaces)),minAvgConfidence:Math.min(100,Math.max(0,Math.trunc(e?.minAvgConfidence??f.minAvgConfidence))),similarityThreshold:Math.min(1,Math.max(0,e?.similarityThreshold??f.similarityThreshold)),dryRun:e?.dryRun??f.dryRun}}function m(e,t){let n=e.map(()=>[]);for(let i=0;i<e.length;i+=1)for(let a=i+1;a<e.length;a+=1)r(e[i].insight,e[a].insight)>=t&&(n[i].push(a),n[a].push(i));return n}function h(e){let t=new Set,n=[];for(let r=0;r<e.length;r+=1){if(t.has(r))continue;let i=[r],a=[];for(t.add(r);i.length>0;){let n=i.pop();if(n!==void 0){a.push(n);for(let r of e[n])t.has(r)||(t.add(r),i.push(r))}}n.push(a)}return n}function g(e){return new t(e,null,null)}function _(e){return(e??``).replace(/\s+/g,` `).trim()}function v(e){let t=_(e);return t.length<=80?t:`${t.slice(0,77).replace(/\s+\S*$/,``)}...`}function y(e){return i({title:v(e.insight),context:`Observed across ${e.foundIn.length} workspaces: ${e.foundIn.join(`, `)}`,insight:e.insight,evidence:[`Promoted from workspaces: ${e.foundIn.join(`, `)}`,`Average confidence: ${e.avgConfidence}/100`,`Reason: ${e.reason}`].join(`
2
- `),confidence:e.avgConfidence,tags:[`lesson`,`promoted`,`global`]})}async function b(e,t){let r=await e.list({category:`lessons`,limit:1e3,orderBy:`updated`,order:`desc`});return(await Promise.all(r.map(async r=>{let i=await e.read(r.path),a=n(i.content),o=_(a.insight);return o?{workspace:t,path:r.path,title:a.title??i.title??r.title,insight:o,confidence:a.confidence??0}:null}))).filter(e=>e!==null)}async function x(e){return(await b(e,`global`)).map(e=>e.insight)}function S(e,t,n){return t.some(t=>r(t,e)>=n)}function C(){let e=u(a(),`global-knowledge`,`.ai`,`curated`);return c(e)||l(e,{recursive:!0}),e}async function w(e){let t=new Map;if(!o())return t;for(let e of s()){let n=u(e.workspacePath,`.ai`,`curated`);if(!c(n))continue;let r=await b(g(n),e.partition);r.length>0&&t.set(e.partition,r)}return t}function T(e,t=f){let n=p(t),r=[...e.values()].flat();if(r.length===0)return[];let i=h(m(r,n.similarityThreshold)),a=[];for(let e of i){let t=e.map(e=>r[e]),i=[...new Set(t.map(e=>e.workspace))].sort();if(i.length<n.minWorkspaces)continue;let o=Math.round(t.reduce((e,t)=>e+t.confidence,0)/t.length),s=[...t].sort((e,t)=>t.confidence-e.confidence||e.title.localeCompare(t.title)||e.path.localeCompare(t.path))[0];a.push({insight:s.insight,foundIn:i,avgConfidence:o,action:o>=n.minAvgConfidence?`promote`:`skip`,reason:o>=n.minAvgConfidence?`Shared across ${i.length} workspaces`:`Below confidence threshold`})}return a.sort((e,t)=>Number(t.action===`promote`)-Number(e.action===`promote`)||t.foundIn.length-e.foundIn.length||t.avgConfidence-e.avgConfidence||e.insight.localeCompare(t.insight))}async function E(e,t,n=f){let r=p(n),i=[],a=await x(t);for(let n of e){if(n.action!==`promote`||S(n.insight,a,r.similarityThreshold)||r.dryRun)continue;let e=await t.remember(v(n.insight),y(n),`lessons`,[`lesson`,`promoted`,`global`]);i.push(e.path),a.push(n.insight)}return{candidates:e,promoted:i}}async function D(e,t){try{return await e.forget(t,`Demoted from global knowledge partition`),{removed:!0,path:t}}catch(e){if(e instanceof Error&&/not found/i.test(e.message))return{removed:!1,path:t};throw e}}export{E as a,C as i,w as n,d as o,D as r,T as s,f as t};
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import{fileURLToPath as e}from"node:url";import{INSTALL_ARGS as t,createLogger as n}from"../../core/dist/index.js";import{existsSync as r,mkdirSync as i,readFileSync as a,readdirSync as o,renameSync as s,rmSync as c,writeFileSync as l}from"node:fs";import{dirname as u,join as d,resolve as f}from"node:path";import{homedir as p}from"node:os";import{execFile as m,execSync as h,spawn as g}from"node:child_process";const _=`@vpxa/aikit`,v=`https://registry.npmjs.org/${_}/latest`,y=n(`server`);function b(){let t=u(e(import.meta.url));return[f(t,`..`,`..`,`..`,`bin`,`aikit.mjs`),f(t,`..`,`bin`,`aikit.mjs`),...process.argv[1]?[f(u(process.argv[1]),`aikit.mjs`)]:[]].find(e=>r(e))??null}const x=d(p(),`.aikit`),S=d(x,`current-version.json`),C=d(x,`versions`),w=/^\d+\.\d+\.\d+(-[\w.+]+)?(\+[\w.]+)?$/;function T(e){if(!w.test(e))throw Error(`Invalid semver version: ${JSON.stringify(e)}`)}function E(){let t=f(u(e(import.meta.url)),`..`,`..`,`..`,`package.json`);try{return JSON.parse(a(t,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}function D(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){let t=(n[e]??0)-(r[e]??0);if(t!==0)return t>0?1:-1}return 0}function O(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){if((n[e]??0)>(r[e]??0))return!0;if((n[e]??0)<(r[e]??0))return!1}return!1}async function k(e){T(e);let n=`v${e}`,a=d(C,`${n}-staging`),o=d(C,n);try{r(a)&&c(a,{recursive:!0,force:!0}),i(a,{recursive:!0}),h(`tar -xzf "${h(`npm pack ${_}@${e} 2>${process.platform===`win32`?`NUL`:`/dev/null`}`,{cwd:a,encoding:`utf-8`,timeout:6e4,windowsHide:!0}).trim()}"`,{cwd:a,encoding:`utf-8`,stdio:`pipe`,timeout:3e4,windowsHide:!0});let n=d(a,`package`);h(`npm ${t.join(` `)}`,{cwd:n,encoding:`utf-8`,stdio:`pipe`,timeout:12e4,windowsHide:!0});let u=d(n,`packages`,`server`,`dist`,`bin.js`);if(!r(u))throw Error(`Server entry not found at ${u}`);if(!r(d(n,`node_modules`)))throw Error(`node_modules not found — npm install may have failed`);r(o)&&c(o,{recursive:!0,force:!0}),s(n,o);let f=`${S}.tmp`;l(f,JSON.stringify({version:e,installedAt:new Date().toISOString()},null,2)),s(f,S)}finally{r(a)&&c(a,{recursive:!0,force:!0})}}function A(e){y.debug(`Updated to v${e}. Restarting server...`),setTimeout(()=>{process.exit(0)},300).unref()}function j(){try{if(!r(C))return;let e=E();if(!e)return;let t=o(C,{withFileTypes:!0}).filter(e=>e.isDirectory()&&/^v\d+\.\d+\.\d+$/.test(e.name)).map(e=>e.name).sort().reverse(),n=new Set([`v${e}`]),i=t.filter(t=>t!==`v${e}`).slice(0,1);for(let e of i)n.add(e);for(let e of t)n.has(e)||(c(d(C,e),{recursive:!0,force:!0}),y.debug(`Cleaned old version: ${e}`))}catch{}}async function M(){try{let e=a(S,`utf-8`),{version:t}=JSON.parse(e),n=await fetch(v,{signal:AbortSignal.timeout(1e4)});if(!n.ok)return;let i=(await n.json()).version;if(!i||i===t||!O(i,t))return;if(r(d(C,`v${i}`))){let e=`${S}.tmp`;l(e,JSON.stringify({version:i,installedAt:new Date().toISOString()},null,2)),s(e,S),y.debug(`Re-activated existing version v${i} — no download needed`),A(i);return}y.debug(`New version available: ${i}. Installing...`),await k(i),A(i)}catch(e){y.error(`Background update check failed: ${e instanceof Error?e.message:String(e)}`)}}let N=null;function P(){return N||(N=F().finally(()=>{N=null}),N)}async function F(){if(r(S)){await M();return}let e=E();try{let t=await fetch(v,{signal:AbortSignal.timeout(1e4)});if(!t.ok)return;let n=(await t.json()).version;if(!n)return;if(D(e,n)<0){y.debug(`Newer version available — installing`,{currentVersion:e,latestVersion:n});try{await k(n),A(n)}catch(e){y.warn(`Auto-install failed`,{error:e instanceof Error?e.message:String(e),latestVersion:n})}}}catch{}}function I(){try{let e=f(p(),`.copilot`,`.aikit-scaffold.json`);return r(e)?JSON.parse(a(e,`utf-8`)).version??null:null}catch{return null}}function L(){try{let e=f(process.cwd(),`.github`,`.aikit-scaffold.json`);return r(e)?JSON.parse(a(e,`utf-8`)).version??null:null}catch{return null}}let R=`idle`,z=null,B=null,V=!1;function H(){return{state:R,error:z}}function U(){R=`idle`,z=null}function W(){try{let e=E();if(P(),!V){V=!0;try{let e=b();e&&g(process.execPath,[e,`migrate-launcher`],{stdio:`ignore`,timeout:15e3,windowsHide:!0}).unref()}catch{}}let t=I(),n=L();if(!(t!=null&&t!==e)&&!(n!=null&&n!==e)||(B!==e&&(U(),B=e),R!==`idle`))return;R=`pending`,z=null,y.debug(`Scaffold version mismatch — auto-upgrading`,{serverVersion:e,userScaffoldVersion:t,workspaceScaffoldVersion:n});let r=b();if(!r){R=`failed`,z=`aikit CLI binary not found`,y.warn(`Cannot auto-upgrade: aikit CLI binary not found`);return}m(process.execPath,[r,`upgrade`],{timeout:3e4,windowsHide:!0},(t,n,i)=>{t?(R=`failed`,z=t.message,y.warn(`Auto-upgrade failed`,{error:t.message,stderr:i?.slice(0,500),binPath:r,platform:process.platform})):(R=`success`,z=null,y.debug(`Auto-upgrade completed to version ${e}`))}).unref()}catch(e){R=`failed`,z=e instanceof Error?e.message:String(e),y.warn(`Auto-upgrade check failed`,{error:z})}}export{W as autoUpgradeScaffold,P as checkForUpdates,j as cleanupOldVersions,E as getCurrentVersion,H as getUpgradeState};
@@ -1 +0,0 @@
1
- import{fileURLToPath as e}from"node:url";import{INSTALL_ARGS as t,createLogger as n}from"../../core/dist/index.js";import{existsSync as r,mkdirSync as i,readFileSync as a,readdirSync as o,renameSync as s,rmSync as c,writeFileSync as l}from"node:fs";import{dirname as u,join as d,resolve as f}from"node:path";import{execFile as p,execSync as m,spawn as h}from"node:child_process";import{homedir as g}from"node:os";const _=`@vpxa/aikit`,v=`https://registry.npmjs.org/${_}/latest`,y=n(`server`);function b(){let t=u(e(import.meta.url));return[f(t,`..`,`..`,`..`,`bin`,`aikit.mjs`),f(t,`..`,`bin`,`aikit.mjs`),...process.argv[1]?[f(u(process.argv[1]),`aikit.mjs`)]:[]].find(e=>r(e))??null}const x=d(g(),`.aikit`),S=d(x,`current-version.json`),C=d(x,`versions`),w=/^\d+\.\d+\.\d+(-[\w.+]+)?(\+[\w.]+)?$/;function T(e){if(!w.test(e))throw Error(`Invalid semver version: ${JSON.stringify(e)}`)}function E(){let t=f(u(e(import.meta.url)),`..`,`..`,`..`,`package.json`);try{return JSON.parse(a(t,`utf-8`)).version??`0.0.0`}catch{return`0.0.0`}}function D(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){let t=(n[e]??0)-(r[e]??0);if(t!==0)return t>0?1:-1}return 0}function O(e,t){let n=e.split(`.`).map(Number),r=t.split(`.`).map(Number);for(let e=0;e<3;e++){if((n[e]??0)>(r[e]??0))return!0;if((n[e]??0)<(r[e]??0))return!1}return!1}async function k(e){T(e);let n=`v${e}`,a=d(C,`${n}-staging`),o=d(C,n);try{r(a)&&c(a,{recursive:!0,force:!0}),i(a,{recursive:!0}),m(`tar -xzf "${m(`npm pack ${_}@${e} 2>${process.platform===`win32`?`NUL`:`/dev/null`}`,{cwd:a,encoding:`utf-8`,timeout:6e4,windowsHide:!0}).trim()}"`,{cwd:a,encoding:`utf-8`,stdio:`pipe`,timeout:3e4,windowsHide:!0});let n=d(a,`package`);m(`npm ${t.join(` `)}`,{cwd:n,encoding:`utf-8`,stdio:`pipe`,timeout:12e4,windowsHide:!0});let u=d(n,`packages`,`server`,`dist`,`bin.js`);if(!r(u))throw Error(`Server entry not found at ${u}`);if(!r(d(n,`node_modules`)))throw Error(`node_modules not found — npm install may have failed`);r(o)&&c(o,{recursive:!0,force:!0}),s(n,o);let f=`${S}.tmp`;l(f,JSON.stringify({version:e,installedAt:new Date().toISOString()},null,2)),s(f,S)}finally{r(a)&&c(a,{recursive:!0,force:!0})}}function A(e){y.debug(`Updated to v${e}. Restarting server...`),setTimeout(()=>{process.exit(0)},300).unref()}function j(){try{if(!r(C))return;let e=E();if(!e)return;let t=o(C,{withFileTypes:!0}).filter(e=>e.isDirectory()&&/^v\d+\.\d+\.\d+$/.test(e.name)).map(e=>e.name).sort().reverse(),n=new Set([`v${e}`]),i=t.filter(t=>t!==`v${e}`).slice(0,1);for(let e of i)n.add(e);for(let e of t)n.has(e)||(c(d(C,e),{recursive:!0,force:!0}),y.debug(`Cleaned old version: ${e}`))}catch{}}async function M(){try{let e=a(S,`utf-8`),{version:t}=JSON.parse(e),n=await fetch(v,{signal:AbortSignal.timeout(1e4)});if(!n.ok)return;let i=(await n.json()).version;if(!i||i===t||!O(i,t))return;if(r(d(C,`v${i}`))){let e=`${S}.tmp`;l(e,JSON.stringify({version:i,installedAt:new Date().toISOString()},null,2)),s(e,S),y.debug(`Re-activated existing version v${i} — no download needed`),A(i);return}y.debug(`New version available: ${i}. Installing...`),await k(i),A(i)}catch(e){y.error(`Background update check failed: ${e instanceof Error?e.message:String(e)}`)}}let N=null;function P(){return N||(N=F().finally(()=>{N=null}),N)}async function F(){if(r(S)){await M();return}let e=E();try{let t=await fetch(v,{signal:AbortSignal.timeout(1e4)});if(!t.ok)return;let n=(await t.json()).version;if(!n)return;if(D(e,n)<0){y.debug(`Newer version available — installing`,{currentVersion:e,latestVersion:n});try{await k(n),A(n)}catch(e){y.warn(`Auto-install failed`,{error:e instanceof Error?e.message:String(e),latestVersion:n})}}}catch{}}function I(){try{let e=f(g(),`.copilot`,`.aikit-scaffold.json`);return r(e)?JSON.parse(a(e,`utf-8`)).version??null:null}catch{return null}}function L(){try{let e=f(process.cwd(),`.github`,`.aikit-scaffold.json`);return r(e)?JSON.parse(a(e,`utf-8`)).version??null:null}catch{return null}}let R=`idle`,z=null,B=null,V=!1;function H(){return{state:R,error:z}}function U(){R=`idle`,z=null}function W(){try{let e=E();if(P(),!V){V=!0;try{let e=b();e&&h(process.execPath,[e,`migrate-launcher`],{stdio:`ignore`,timeout:15e3,windowsHide:!0}).unref()}catch{}}let t=I(),n=L();if(!(t!=null&&t!==e)&&!(n!=null&&n!==e)||(B!==e&&(U(),B=e),R!==`idle`))return;R=`pending`,z=null,y.debug(`Scaffold version mismatch — auto-upgrading`,{serverVersion:e,userScaffoldVersion:t,workspaceScaffoldVersion:n});let r=b();if(!r){R=`failed`,z=`aikit CLI binary not found`,y.warn(`Cannot auto-upgrade: aikit CLI binary not found`);return}p(process.execPath,[r,`upgrade`],{timeout:3e4,windowsHide:!0},(t,n,i)=>{t?(R=`failed`,z=t.message,y.warn(`Auto-upgrade failed`,{error:t.message,stderr:i?.slice(0,500),binPath:r,platform:process.platform})):(R=`success`,z=null,y.debug(`Auto-upgrade completed to version ${e}`))}).unref()}catch(e){R=`failed`,z=e instanceof Error?e.message:String(e),y.warn(`Auto-upgrade check failed`,{error:z})}}export{W as autoUpgradeScaffold,P as checkForUpdates,j as cleanupOldVersions,E as getCurrentVersion,H as getUpgradeState};