@vpxa/aikit 0.1.347 → 0.1.349

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 (53) hide show
  1. package/package.json +2 -1
  2. package/packages/cli/dist/index.js +19 -19
  3. package/packages/cli/dist/{init-BZHwK5rv.js → init-D5TsG2R6.js} +1 -1
  4. package/packages/cli/dist/{templates-DxyYPlMl.js → templates-CztsaGb2.js} +25 -25
  5. package/packages/core/dist/index.d.ts +17 -1
  6. package/packages/core/dist/index.js +1 -1
  7. package/packages/server/dist/bin.js +6 -6
  8. package/packages/server/dist/config-4M54ZAT8.js +2 -0
  9. package/packages/server/dist/config-BXd38nVn.js +1 -0
  10. package/packages/server/dist/index.js +2 -2
  11. package/packages/server/dist/prelude-DpX0QnqF.js +2 -0
  12. package/packages/server/dist/prelude-pJPHXvnQ.js +1 -0
  13. package/packages/server/dist/proxy.js +7 -7
  14. package/packages/server/dist/routes-9KnBpwfe.js +6 -0
  15. package/packages/server/dist/routes-B8hTXXR8.js +5 -0
  16. package/packages/server/dist/sampling-9GcILoHr.js +2 -0
  17. package/packages/server/dist/sampling-DuXB6-rK.js +1 -0
  18. package/packages/server/dist/{server-Bme4eBy1.js → server-BYZo2XjK.js} +158 -163
  19. package/packages/server/dist/{server-B9PIl5SY.js → server-BtRv0mbH.js} +158 -163
  20. package/packages/server/dist/{server-http-rK25FoUm.js → server-http-CatdRS-N.js} +1 -1
  21. package/packages/server/dist/{server-http-C7PO0D_V.js → server-http-L_WQ9v_b.js} +1 -1
  22. package/packages/server/dist/{server-stdio-BVxXXgvL.js → server-stdio-CZuGZR4e.js} +1 -1
  23. package/packages/server/dist/{server-stdio-OQL2grn7.js → server-stdio-avLmmdEi.js} +1 -1
  24. package/packages/server/dist/version-check-B6bui-YI.js +1 -0
  25. package/packages/server/dist/version-check-CZ5hY6R2.js +2 -0
  26. package/packages/server/dist/workspace-bootstrap-B57Oz40_.js +1 -0
  27. package/packages/tools/dist/index.d.ts +64 -27
  28. package/packages/tools/dist/index.js +95 -97
  29. package/scaffold/dist/adapters/hermes-agent.mjs +1 -1
  30. package/scaffold/dist/adapters/hermes.mjs +1 -1
  31. package/scaffold/dist/definitions/agents.mjs +1 -1
  32. package/scaffold/dist/definitions/bodies.mjs +39 -35
  33. package/scaffold/dist/definitions/flows.mjs +7 -7
  34. package/scaffold/dist/definitions/prompts.mjs +7 -7
  35. package/scaffold/dist/definitions/protocols.mjs +9 -9
  36. package/scaffold/dist/definitions/skills/aikit.mjs +22 -21
  37. package/scaffold/dist/definitions/skills/c4-architecture.mjs +1 -1
  38. package/scaffold/dist/definitions/skills/docs.mjs +5 -5
  39. package/scaffold/dist/definitions/skills/multi-agents-development.mjs +9 -9
  40. package/scaffold/dist/definitions/tools.mjs +1 -1
  41. package/scaffold/general/hooks/scripts/subagent-context.mjs +1 -1
  42. package/packages/server/dist/config-BsS-77rp.js +0 -2
  43. package/packages/server/dist/config-Ds28Hvip.js +0 -1
  44. package/packages/server/dist/prelude-B58MO48q.js +0 -1
  45. package/packages/server/dist/prelude-HRPwDugi.js +0 -2
  46. package/packages/server/dist/routes-C7bDyCOW.js +0 -5
  47. package/packages/server/dist/routes-CfG5gdSR.js +0 -6
  48. package/packages/server/dist/sampling-DvrIzeWt.js +0 -1
  49. package/packages/server/dist/sampling-lH0Mam1_.js +0 -2
  50. package/packages/server/dist/version-check-BjFqR01r.js +0 -1
  51. package/packages/server/dist/version-check-_2wmedTl.js +0 -2
  52. package/packages/server/dist/workspace-bootstrap-BJloolzr.js +0 -1
  53. package/scaffold/INSTRUCTIONS.md +0 -273
@@ -17,14 +17,15 @@ Use AI Kit as compression, memory, validation, and coordination layer. Each call
17
17
  ## Session Loop
18
18
 
19
19
  Start:
20
- 1. status({ includePrelude: true }); onboard if missing.
21
- 2. **L0 session start**: Fetch \`aikit://l0/workspace-core\` resource (full card) or \`status({ includePrelude: true })\` (compact summary). 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.
20
+ 1. status({ includePrelude: true }).
21
+ 2. If prelude.workspaceCore is null run \`onboard({ path, mode: 'generate' })\`, then \`status({ includePrelude: true })\` again.
22
+ 3. **L0 session start**: Fetch \`aikit://l0/workspace-core\` resource (full card) or \`status({ includePrelude: true })\` (compact summary). If a flow is active, workflow card loaded via flow context. ≤ 2,100 tokens.
23
+ 4. search({ query: "SESSION CHECKPOINT", origin: "curated" }).
24
+ 5. flow({ action: 'status' }) when active flow may exist — use L1 snapshot before broad retrieval.
25
+ 6. scope_map({ task }) for non-trivial work.
25
26
 
26
27
  During:
27
- - Prefer search/file_summary/compact/digest/symbol/trace/graph over raw reads.
28
+ - Prefer search/file_summary/digest/symbol/trace/graph over raw reads.
28
29
  - Use stash for temporary findings; knowledge for durable decisions.
29
30
  - Run blast_radius before shared/public edits.
30
31
  - Validate with check + relevant test_run.
@@ -39,14 +40,14 @@ End:
39
40
 
40
41
  | Layer | Need | Tool |
41
42
  |-------|------|------|
42
- | **L0** | Session briefing (auto) | Resource \`aikit://l0/workspace-core\` (full card) or \`status({ includePrelude: true })\` (compact summary) |
43
+ | **L0** | Session briefing (after onboard) | Resource \`aikit://l0/workspace-core\` (full card) or \`status({ includePrelude: true })\` (compact summary). Run \`onboard\` first if card missing. |
43
44
  | **L0** | Architecture overview | \`architecture\` briefing card |
44
45
  | **L0** | Known issues | \`known-issues\` briefing card |
45
46
  | **L0** | Flow-specific context | \`workflow:<flow>\` briefing card |
46
47
  | **L1** | Active flow state | \`knowledge({ action: 'withdraw', scope: 'flow', profile: '<role>' })\` |
47
48
  | **L2** | Prior decisions/conventions | \`search\` / \`knowledge\` |
48
- | **L2** | File structure | \`file_summary\` |
49
- | **L2** | Exact relevant section | \`compact\` |
49
+ | **L2** | File structure | \`file_summary({ files, tier: 'T1' })\` |
50
+ | **L2** | Exact relevant section | \`file_summary({ files, tier: 'T2' })\` |
50
51
  | **L2** | Many files | \`digest\` |
51
52
  | **L2** | Symbol defs/refs | \`symbol\` |
52
53
  | **L2** | Call/data flow | \`trace\` |
@@ -60,13 +61,13 @@ Raw read_file only for exact edit lines after compressed tools identify target.
60
61
 
61
62
  ## Context Reuse
62
63
 
63
- Before rereading path/topic, search exact path/topic first. If response gives ctxc_..., reuse with compact({ ref }) or compact({ ref, query }). Use enrich: true on tools that support it after first pass.
64
+ Before rereading path/topic, search exact path/topic first. If response gives ctxc_..., reuse with file_summary({ ref }) or file_summary({ ref, query }). Use enrich: true on tools that support it after first pass.
64
65
 
65
66
  ## Patterns
66
67
 
67
- - New area: search -> scope_map -> file_summary/compact -> graph/trace -> stash.
68
- - Bug: search -> symbol -> trace -> compact -> test/check -> remember.
69
- - Refactor shared code: blast_radius -> checkpoint -> compact -> rename/codemod -> check -> test_run.
68
+ - New area: search -> scope_map -> file_summary -> graph/trace -> stash.
69
+ - Bug: search -> symbol -> trace -> file_summary -> test/check -> remember.
70
+ - Refactor shared code: blast_radius -> checkpoint -> file_summary -> rename/codemod -> check -> test_run.
70
71
  - Web/API: web_search/web_fetch/http; browser only when JS/auth interaction needed. Browser snapshots now use ~200-400 tokens, making them practical for quick page state checks.
71
72
 
72
73
  ## Memory Discipline
@@ -84,7 +85,7 @@ Review decayed/stale entries periodically with knowledge({ action: 'flagged' }).
84
85
  Flows guide multi-step work. Read active step before acting. FORGE handles tiering/evidence/gates; load references only when main skill is too thin.
85
86
 
86
87
  ### Layered Knowledge Protocol
87
- - **L0** → Generated briefing cards: always load \`workspace-core\` at session start via \`aikit://l0/workspace-core\` resource (full card, live-updated). Add \`workflow:<flow>\` if flow active, or one task card if no flow. Use \`stratum_card\` / \`compact\` for content. Token-bounded.
88
+ - **L0** → Generated briefing cards: load \`workspace-core\` at session start via \`aikit://l0/workspace-core\` resource (full card, live-updated) or \`status({ includePrelude: true })\` (compact summary). Requires \`onboard()\` first — if card null, run \`onboard\` before session start. Add \`workflow:<flow>\` if flow active, or one task card if no flow. Use \`file_summary({ tier: 'T1' })\` for structure, or \`file_summary({ tier: 'T2', query })\` for content. Token-bounded.
88
89
  - **L1** → Flow working context. Withdraw before dispatch; reuse before broad retrieval.
89
90
  - **L2** → Canonical curated knowledge. Retrieve on demand; never preload broadly.
90
91
  - **L3** → Evidence/auto-knowledge. Inspect only for provenance, conflict, or promotion assessment.
@@ -171,7 +172,7 @@ Need real usage examples? → find({ mode: 'examples' })
171
172
  Need call/data flow? → trace
172
173
  Need import/module graph? → graph
173
174
  Need file reading plan? → scope_map
174
- Need one file section? → compact
175
+ Need one file section? → file_summary({ tier: "T2", query })
175
176
  Need many files compressed? → digest
176
177
  ~~~
177
178
 
@@ -181,13 +182,13 @@ Need many files compressed? → digest
181
182
  - Use \`symbol\` when the question is definition, imports, or refs.
182
183
  - Use \`trace\` when you care about execution path.
183
184
  - Use \`graph\` when you care about who depends on what.
184
- - Use \`compact\` after you already know the file and the question.
185
- - Use \`file_summary\` before \`compact\` if you still need structure.
185
+ - Use \`file_summary\` after you already know the file and the question.
186
+ - Use \`file_summary({ tier: 'T1' })\` for structure, or \`file_summary({ tier: 'T2', query })\` for specific content.
186
187
 
187
188
  ## Compression Ladder
188
189
 
189
190
  ~~~text
190
- file_summary compact digest read_file only for edit lines
191
+ file_summary (T1=structure, T2=content) or digest (multi-file synthesis). Read_file ONLY for edit lines
191
192
  ~~~
192
193
 
193
194
  ## Rule of Thumb
@@ -201,9 +202,9 @@ AI Kit delivers knowledge through four layers:
201
202
 
202
203
  Fast, compact task setup loaded at session start.
203
204
 
204
- - **Auto-injected**: \`workspace-core\` (800-1200 tokens) — included in \`status({ includePrelude: true })\` output
205
+ - **Auto-injected**: \`workspace-core\` (800-1200 tokens) — available via \`status({ includePrelude: true })\` after \`onboard()\` generates the card. If null → run \`onboard({ path, mode: 'generate' })\` then retry status.
205
206
  - **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
+ - **If no flow**: Optionally load one task card via \`file_summary\`
207
208
  - **Budget**: ≤ 2,100 tokens total
208
209
  - **Storage**: Generated workspace cache (path from server config)
209
210
  - **Card families**: \`workspace-core\`, \`architecture\`, \`testing-release\`, \`known-issues\`, \`workflow:<flow>\`
@@ -215,7 +216,7 @@ Fast, compact task setup loaded at session start.
215
216
  Active run state and role-filtered dispatch context.
216
217
 
217
218
  - 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
+ - Use withdrawn refs before calling \`file_summary\`, \`scope_map\`, \`blast_radius\`, or \`search\`
219
220
  - Each step has a declared \`contextProfile\` (implementer, reviewer, researcher, documenter, debugger)
220
221
 
221
222
  ## L2 — Canonical Curated Knowledge
@@ -139,7 +139,7 @@ Default: Context + Container. Add Component only for a complex container and a c
139
139
 
140
140
  1. **Study examples first**: Load references/ example files to understand visual patterns, label density, and layout conventions before generating.
141
141
  2. Identify audience and decision the diagram supports.
142
- 3. Gather evidence with AI Kit: analyze/graph/search/compact.
142
+ 3. Gather evidence with AI Kit: analyze/graph/search/file_summary.
143
143
  4. Pick level(s); avoid mixing levels in one diagram.
144
144
  5. **Generate structured diagram JSON** conforming to the centralized diagram schema (see ~/.aikit/resources/renderers/schemas/). Render via CLI:
145
145
 
@@ -811,7 +811,7 @@ Each prose step in a markdown tour should name the focus, explain what the reade
811
811
  ### Tour Generation Workflow
812
812
 
813
813
  1. Run the algorithm above to produce an ordered step list
814
- 2. For each step, use \`compact({ items: [{path, query: "purpose and public API"}] })\` to extract key info
814
+ 2. For each step, use \`file_summary({ files, tier: 'T1', query: "purpose and public API" })\` to extract key info
815
815
  3. Write the tour as \`docs/tours/{topic}.md\`
816
816
  4. Generate \`docs/tours/index.md\` linking all tours with descriptions
817
817
 
@@ -954,7 +954,7 @@ After generating tour JSON, validate EVERY step's line numbers against the actua
954
954
  **Validation snippet:**
955
955
  \`\`\`
956
956
  For each step:
957
- compact({ items: [{path: step.file, query: step.title}] }) → find actual location
957
+ file_summary({ files: [step.file], tier: 'T1', query: step.title }) → find actual location
958
958
  read_file(step.file, step.line, step.line + 10) → verify code matches description
959
959
  If mismatch → search({ query: step.explanation }) → find correct file:line
960
960
  \`\`\`
@@ -1555,7 +1555,7 @@ analyze({ items: [{aspect: "symbols"}] }) # All exported symbols
1555
1555
  analyze({ items: [{aspect: "entry_points"}] }) # Entry points
1556
1556
  graph({ action: "find_nodes" }) # Module graph
1557
1557
  # For each module:
1558
- file_summary({ items: [{path}] }) # Structure without reading full file
1558
+ file_summary({ files, tier: 'T1' }) # Structure without reading full file
1559
1559
  # Output: structured JSON with all deterministic facts
1560
1560
  \`\`\`
1561
1561
 
@@ -1684,7 +1684,7 @@ graph({ action: "find_nodes" })
1684
1684
  \`\`\`
1685
1685
  # For each detected domain/bounded context:
1686
1686
  1. Identify files belonging to domain (from layer/cluster analysis)
1687
- 2. compact() key files for context
1687
+ 2. file_summary({ files, tier: 'T2', query: "<domain-specific>", max_content_chars: 1200 })
1688
1688
  3. Apply Domain Documentation Prompt
1689
1689
  4. Output: docs/architecture/domains/{domain}.md
1690
1690
  \`\`\`
@@ -2169,7 +2169,7 @@ For each major component:
2169
2169
  - Internal structure
2170
2170
  - Key abstractions
2171
2171
  - Interaction patterns
2172
- - **Tools**: \`analyze({ items: [{aspect: "symbols", path: "component/"}] })\` + \`compact({ items: [{path, query: "exports"}] })\`
2172
+ - **Tools**: \`analyze({ items: [{aspect: "symbols", path: "component/"}] })\` + \`file_summary({ files, tier: 'T1', query: "exports" })\`
2173
2173
  - **Output**: \`docs/architecture/components/{name}.md\`
2174
2174
 
2175
2175
  #### 5. Layers & Dependencies
@@ -16,7 +16,7 @@ You are performing an architecture review. Focus on structural decisions, not co
16
16
  [List of files with module/boundary information]
17
17
 
18
18
  ## Architectural Context
19
- [Paste relevant architecture docs, module graph, dependency structure from compact/digest]
19
+ [Paste relevant architecture docs, module graph, dependency structure from file_summary/digest]
20
20
 
21
21
  ---
22
22
 
@@ -197,7 +197,7 @@ You are implementing a focused task. All context you need is provided below. Do
197
197
  - [ ] [Specific, testable criterion 3]
198
198
 
199
199
  ## 3. Architectural Context
200
- [Relevant code snippets, patterns, conventions from compact/digest — paste actual code, don't reference files]
200
+ [Relevant code snippets, patterns, conventions from file_summary/digest — paste actual code, don't reference files]
201
201
 
202
202
  Example existing pattern:
203
203
  \\\`\\\`\\\`typescript
@@ -323,9 +323,9 @@ Create backend API for notification preferences CRUD.
323
323
  - Migration creates notification_preferences table
324
324
 
325
325
  ## 3. Architectural Context
326
- [Paste existing service pattern from compact()]
327
- [Paste existing route pattern from compact()]
328
- [Paste existing migration pattern from compact()]
326
+ [Paste existing service pattern from file_summary()]
327
+ [Paste existing route pattern from file_summary()]
328
+ [Paste existing migration pattern from file_summary()]
329
329
  [Paste the shared type contract above]
330
330
 
331
331
  ## 4. Constraints
@@ -359,8 +359,8 @@ Create notification preferences settings page.
359
359
  - Loading skeleton on initial fetch
360
360
 
361
361
  ## 3. Architectural Context
362
- [Paste existing settings page pattern from compact()]
363
- [Paste existing toggle component from compact()]
362
+ [Paste existing settings page pattern from file_summary()]
363
+ [Paste existing toggle component from file_summary()]
364
364
  [Paste the shared type contract + API contract above]
365
365
 
366
366
  ## 4. Constraints
@@ -418,7 +418,7 @@ Purpose: decompose work, dispatch focused agents, integrate evidence, recover cl
418
418
  - Main agent owns plan, flow, user comms, gates, and final synthesis.
419
419
  - Subagents own one scoped research/review/implementation task.
420
420
  - Fresh prompt only. Assume no inherited session state.
421
- - Context flows through AI Kit: withdraw -> compact/digest -> dispatch -> deposit.
421
+ - Context flows through AI Kit: withdraw -> file_summary/digest -> dispatch -> deposit.
422
422
  - Token goal: send decisions, constraints, snippets, paths; skip raw history.
423
423
 
424
424
  ## Role Routing
@@ -481,7 +481,7 @@ Use references/implementer-prompt.md for implementation dispatches and reference
481
481
  Before dispatch:
482
482
  - knowledge({ action: 'withdraw', scope: 'flow', profile: '<role>', budget: 6000 })
483
483
  - Include \`selectedCardRefs\` (L0 card refs) and \`retrievedRefs\` (from L1) in the dispatch envelope.
484
- - Add only missing snippets with compact/digest.
484
+ - Add only missing snippets with file_summary/digest.
485
485
  - Paste context into dispatch; do not tell subagent to rediscover basics.
486
486
  - **Hard rule**: Subagent must reuse supplied L0/L1 refs before broad retrieval. Block if it reloads \`workspace-core\` or architecture cards independently.
487
487
 
@@ -1 +1 @@
1
- const e=`analyze.audit.blast_radius.changelog.check.checkpoint.codemod.compact.config.data_transform.dead_symbols.delegate.describe_tool.diff_parse.digest.encode.env.eval.evidence_map.file_summary.find.flow.forge_classify.forge_ground.git_context.graph.guide.health.http.knowledge.lane.list_tools.lookup.measure.onboard.parse_output.present.process.produce_knowledge.queue.regex_test.reindex.rename.replay.restore.schema_validate.scope_map.search.search_tools.session_digest.signal.stash.status.stratum_card.symbol.test_run.time.trace.watch.web_fetch.web_search.workset`.split(`.`),t={orchestrator:[`memory`,`runCommand`,`switchAgent`,`newWorkspace`,`reviewPlan`,`killTerminal`,`createTask`,`terminal`,`terminalSel`,`lastCommand`,`problems`,`readFile`,`subagent`,`search`,`web`,`todo`,`searchSubagent`,`textSearch`,`browser`,`askQuestions`,`resolveMemoryFileUri`],researcher:[`terminal`,`problems`,`readFile`,`lastCommand`,`subagent`,`search`,`web`,`browser`],reviewer:[`terminal`,`problems`,`readFile`,`lastCommand`,`subagent`,`search`,`web`,`browser`],codeAgent:[`createTask`,`terminal`,`problems`,`readFile`,`lastCommand`,`subagent`,`createFile`,`editFiles`,`rename`,`createDirectory`,`search`,`todo`,`browser`],debugger:[`terminal`,`problems`,`readFile`,`terminalSel`,`lastCommand`,`subagent`,`createFile`,`editFiles`,`search`,`browser`],refactor:[`terminal`,`problems`,`readFile`,`lastCommand`,`subagent`,`createFile`,`editFiles`,`rename`,`createDirectory`,`search`,`browser`],explorer:[`problems`,`readFile`,`search`,`fileSearch`,`listDir`,`textSearch`,`browser`],planner:[`terminal`,`problems`,`readFile`,`reviewPlan`,`memory`,`askQuestions`,`resolveMemoryFileUri`,`lastCommand`,`subagent`,`createFile`,`editFiles`,`rename`,`createDirectory`,`search`,`web`,`todo`,`searchSubagent`,`browser`],security:[`terminal`,`problems`,`readFile`,`subagent`,`search`,`web`,`browser`],documenter:[`terminal`,`problems`,`readFile`,`lastCommand`,`subagent`,`createFile`,`editFiles`,`rename`,`createDirectory`,`search`,`web`,`browser`]},n={terminal:[`Bash`],problems:[`Read`],readFile:[`Read`],lastCommand:[`Bash`],subagent:[],createFile:[`Write`],editFiles:[`Edit`],rename:[`Write`],createDirectory:[`Write`],search:[`Read`],web:[`WebFetch`,`WebSearch`],todo:[`TodoRead`,`TodoWrite`],memory:[],runCommand:[`Bash`],switchAgent:[],newWorkspace:[`Bash`],reviewPlan:[],killTerminal:[`Bash`],createTask:[`Bash`],terminalSel:[`Bash`],fileSearch:[`Read`],listDir:[`Read`],textSearch:[`Read`],searchSubagent:[],browser:[],askQuestions:[],resolveMemoryFileUri:[]};export{e as AIKIT_TOOLS,n as CLAUDE_CODE_TOOL_MAP,t as IDE_CAPABILITIES};
1
+ const e=`analyze.audit.blast_radius.changelog.check.checkpoint.codemod.config.data_transform.dead_symbols.delegate.describe_tool.diff_parse.digest.encode.env.eval.evidence_map.file_summary.find.flow.forge_classify.forge_ground.git_context.graph.guide.health.http.knowledge.lane.list_tools.lookup.measure.onboard.parse_output.present.process.produce_knowledge.queue.regex_test.reindex.rename.replay.restore.schema_validate.scope_map.search.search_tools.session_digest.signal.stash.status.symbol.test_run.time.trace.watch.web_fetch.web_search.workset`.split(`.`),t={orchestrator:[`memory`,`runCommand`,`switchAgent`,`newWorkspace`,`reviewPlan`,`killTerminal`,`createTask`,`terminal`,`terminalSel`,`lastCommand`,`problems`,`readFile`,`subagent`,`search`,`web`,`todo`,`searchSubagent`,`textSearch`,`browser`,`askQuestions`,`resolveMemoryFileUri`],researcher:[`terminal`,`problems`,`readFile`,`lastCommand`,`subagent`,`search`,`web`,`browser`],reviewer:[`terminal`,`problems`,`readFile`,`lastCommand`,`subagent`,`search`,`web`,`browser`],codeAgent:[`createTask`,`terminal`,`problems`,`readFile`,`lastCommand`,`subagent`,`createFile`,`editFiles`,`rename`,`createDirectory`,`search`,`todo`,`browser`],debugger:[`terminal`,`problems`,`readFile`,`terminalSel`,`lastCommand`,`subagent`,`createFile`,`editFiles`,`search`,`browser`],refactor:[`terminal`,`problems`,`readFile`,`lastCommand`,`subagent`,`createFile`,`editFiles`,`rename`,`createDirectory`,`search`,`browser`],explorer:[`problems`,`readFile`,`search`,`fileSearch`,`listDir`,`textSearch`,`browser`],planner:[`terminal`,`problems`,`readFile`,`reviewPlan`,`memory`,`askQuestions`,`resolveMemoryFileUri`,`lastCommand`,`subagent`,`createFile`,`editFiles`,`rename`,`createDirectory`,`search`,`web`,`todo`,`searchSubagent`,`browser`],security:[`terminal`,`problems`,`readFile`,`subagent`,`search`,`web`,`browser`],documenter:[`terminal`,`problems`,`readFile`,`lastCommand`,`subagent`,`createFile`,`editFiles`,`rename`,`createDirectory`,`search`,`web`,`browser`]},n={terminal:[`Bash`],problems:[`Read`],readFile:[`Read`],lastCommand:[`Bash`],subagent:[],createFile:[`Write`],editFiles:[`Edit`],rename:[`Write`],createDirectory:[`Write`],search:[`Read`],web:[`WebFetch`,`WebSearch`],todo:[`TodoRead`,`TodoWrite`],memory:[],runCommand:[`Bash`],switchAgent:[],newWorkspace:[`Bash`],reviewPlan:[],killTerminal:[`Bash`],createTask:[`Bash`],terminalSel:[`Bash`],fileSearch:[`Read`],listDir:[`Read`],textSearch:[`Read`],searchSubagent:[],browser:[],askQuestions:[],resolveMemoryFileUri:[]};export{e as AIKIT_TOOLS,n as CLAUDE_CODE_TOOL_MAP,t as IDE_CAPABILITIES};
@@ -51,7 +51,7 @@ export const subagentContext = async (context) => {
51
51
  `Project: ${name}${description ? ` — ${description}` : ''}`,
52
52
  `Stack: ${stack}`,
53
53
  `Conventions: ${truncate(conventionText || 'Reuse existing scaffold patterns.', 120)}`,
54
- 'Use aikit search/file_summary/compact — NOT raw read_file for understanding code.',
54
+ 'Use aikit search/file_summary — NOT raw read_file for understanding code.',
55
55
  ].join('\n');
56
56
  return { additionalContext: contextText };
57
57
  };
@@ -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,e.l0CardDir];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`),e.l0CardDir=R(t,n,e.l0CardDir,r.l0Cards,`l0CardDir`)}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.layeredKnowledge===void 0&&(i.layeredKnowledge=process.env.AIKIT_LAYERED_KNOWLEDGE===`true`),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{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,e.l0CardDir];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`),e.l0CardDir=R(t,n,e.l0CardDir,r.l0Cards,`l0CardDir`)}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.layeredKnowledge===void 0&&(i.layeredKnowledge=process.env.AIKIT_LAYERED_KNOWLEDGE===`true`),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-Bme4eBy1.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-B9PIl5SY.js";export{t as buildPreludeInjection,e as generatePrelude};
@@ -1,5 +0,0 @@
1
- import{getGlobalDataDir as e,isUserInstalled as t}from"../../core/dist/index.js";import{existsSync as n,mkdirSync as r,readFileSync as i,renameSync as a,writeFileSync as o}from"node:fs";import{dirname as s,resolve as c}from"node:path";import{z as l}from"zod";import{Router as u}from"express";const d=[{key:`serverName`,type:`string`,default:`aikit`,description:`MCP server name advertised to clients.`,group:`general`,requiresRestart:!0},{key:`toolPrefix`,type:`string`,default:``,description:`Prefix prepended to every MCP tool name (e.g. "aikit_").`,group:`general`,requiresRestart:!0},{key:`toolProfile`,type:`string`,default:`full`,description:`Active tool profile.`,group:`general`,enum:[`full`,`safe`,`research`,`minimal`,`discovery`],requiresRestart:!0},{key:`autoIndex`,type:`boolean`,default:!1,description:`Deprecated. Prefer indexMode. true → auto, false → manual.`,group:`indexing`},{key:`indexMode`,type:`string`,default:`smart`,description:`Indexing strategy. auto = full on startup, manual = on demand, smart = on-demand + idle.`,group:`indexing`,enum:[`auto`,`manual`,`smart`]},{key:`sources`,type:`array`,description:`Source roots to index. Each entry has { path, excludePatterns }.`,group:`indexing`,requiresRestart:!0},{key:`indexing.chunkSize`,type:`number`,default:1500,description:`Maximum chunk size in characters.`,group:`indexing`},{key:`indexing.chunkOverlap`,type:`number`,default:200,description:`Overlap between adjacent chunks.`,group:`indexing`},{key:`indexing.minChunkSize`,type:`number`,default:100,description:`Minimum chunk size before merging into the next chunk.`,group:`indexing`},{key:`indexing.concurrency`,type:`number`,description:`Max files processed concurrently. Defaults to half of CPU cores.`,group:`indexing`},{key:`embedding.model`,type:`string`,default:`mixedbread-ai/mxbai-embed-large-v1`,description:`Embedding model identifier.`,group:`embedding`,requiresRestart:!0},{key:`embedding.dimensions`,type:`number`,default:1024,description:`Embedding vector dimensions. Must match the model.`,group:`embedding`,requiresRestart:!0},{key:`store.backend`,type:`string`,default:`sqlite-vec`,description:`Vector store backend (sqlite-vec | lancedb).`,group:`store`,requiresRestart:!0},{key:`store.path`,type:`string`,description:`Filesystem path for the vector store.`,group:`store`,requiresRestart:!0},{key:`curated.path`,type:`string`,description:`Path to curated knowledge directory.`,group:`store`,requiresRestart:!0},{key:`onboardDir`,type:`string`,description:`Directory for onboard / produce_knowledge output.`,group:`store`,requiresRestart:!0},{key:`stateDir`,type:`string`,description:`Directory for session state (stash, checkpoints, etc.).`,group:`store`,requiresRestart:!0},{key:`er.enabled`,type:`boolean`,default:!1,description:`Enable enterprise RAG bridge integration.`,group:`enterprise-bridge`,requiresRestart:!0},{key:`er.baseUrl`,type:`string`,description:`Base URL of the ER API.`,group:`enterprise-bridge`,requiresRestart:!0},{key:`er.timeoutMs`,type:`number`,default:5e3,description:`ER request timeout in milliseconds.`,group:`enterprise-bridge`},{key:`er.fallbackThreshold`,type:`number`,default:.45,description:`Vector similarity threshold below which ER fallback triggers.`,group:`enterprise-bridge`}],f=[{key:`AIKIT_TRANSPORT`,type:`string`,default:`stdio`,description:`MCP transport mode.`,group:`transport`,enum:[`stdio`,`http`],defaultScope:`workspace`},{key:`AIKIT_PORT`,type:`string`,default:`3210`,description:`HTTP port when transport = http.`,group:`transport`,defaultScope:`workspace`},{key:`AIKIT_CORS_ORIGIN`,type:`string`,description:`CORS Access-Control-Allow-Origin header for HTTP mode.`,group:`transport`,defaultScope:`workspace`},{key:`AIKIT_CONFIG_PATH`,type:`string`,description:`Override path to aikit.config.json.`,group:`paths`,defaultScope:`workspace`},{key:`AIKIT_WORKSPACE_ROOT`,type:`string`,description:`Override workspace root used when no config file is present.`,group:`paths`,defaultScope:`workspace`},{key:`AIKIT_GLOBAL_DATA_DIR`,type:`string`,description:`Override global data directory (default: ~/.aikit).`,group:`paths`,defaultScope:`global`},{key:`AIKIT_INDEX_MODE`,type:`string`,description:`Override config indexMode.`,group:`indexing`,enum:[`auto`,`manual`,`smart`],defaultScope:`workspace`},{key:`AIKIT_AUTO_INDEX`,type:`string`,description:`Legacy boolean override. Prefer AIKIT_INDEX_MODE.`,group:`indexing`,enum:[`true`,`false`],defaultScope:`workspace`},{key:`AIKIT_TOOLSET`,type:`string`,description:`Override active tool profile.`,group:`general`,defaultScope:`workspace`},{key:`AIKIT_BROWSER_DEFAULT_MODE`,type:`string`,default:`ui`,description:`Default browser launch mode for browser_* tools.`,group:`browser`,enum:[`ui`,`headless`,`panel`],defaultScope:`workspace`},{key:`AIKIT_BROWSER_PATH`,type:`string`,description:`Optional Playwright browser download path override.`,group:`browser`,defaultScope:`workspace`},{key:`AIKIT_BROWSER_IDLE_MINUTES`,type:`string`,default:`10`,description:`Idle shutdown timeout in minutes for the shared browser runtime.`,group:`browser`,defaultScope:`workspace`},{key:`AIKIT_BROWSER_EVAL_TIMEOUT_MS`,type:`string`,default:`5000`,description:`Default browser_eval timeout in milliseconds.`,group:`browser`,defaultScope:`workspace`},{key:`AIKIT_SEARCH_DEADLINE_MS`,type:`string`,default:`10000`,description:`Multi-provider web search deadline (milliseconds).`,group:`search-providers`,defaultScope:`global`},{key:`SEARXNG_URL`,type:`string`,description:`Optional SearXNG instance URL for the web_search tool.`,group:`search-providers`,defaultScope:`global`},{key:`GOOGLE_API_KEY`,type:`secret`,description:`Google Custom Search API key.`,group:`search-providers`,defaultScope:`global`},{key:`GOOGLE_CSE_ID`,type:`string`,description:`Google Custom Search Engine ID.`,group:`search-providers`,defaultScope:`global`},{key:`BRAVE_API_KEY`,type:`secret`,description:`Brave Search API key.`,group:`search-providers`,defaultScope:`global`},{key:`BING_API_KEY`,type:`secret`,description:`Bing Web Search API key.`,group:`search-providers`,defaultScope:`global`}];function p(e){return f.find(t=>t.key===e)}function m(e){let t=p(e);return t?t.type===`secret`:/(_KEY|_TOKEN|_SECRET|_PASSWORD|_PASS|_PWD)$/i.test(e)}const h=/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=(.*)$/;function g(e){let t=e.replace(/^\s+/,``);if(t.startsWith(`"`)){let e=1,n=``;for(;e<t.length;){let r=t[e];if(r===`\\`&&e+1<t.length){let r=t[e+1];r===`n`?n+=`
2
- `:r===`r`?n+=`\r`:r===`t`?n+=` `:n+=r,e+=2;continue}if(r===`"`){let r=t.slice(e+1),i=r.indexOf(`#`),a=i===-1?``:r.slice(i);return{value:n,quoted:!0,inlineComment:a}}n+=r,e+=1}return{value:t.slice(1),quoted:!0,inlineComment:``}}let n=t.match(/(\s+#.*)$/);return n&&n.index!==void 0?{value:t.slice(0,n.index).trimEnd(),quoted:!1,inlineComment:n[1].trimStart()}:{value:t.trimEnd(),quoted:!1,inlineComment:``}}function _(e){let t;t=e.quoted||/[\s#"']/.test(e.value)||e.value.includes(`
3
- `)||e.value.length===0?`"${e.value.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`).replace(/\n/g,`\\n`).replace(/\r/g,`\\r`).replace(/\t/g,`\\t`)}"`:e.value;let n=e.inlineComment?` ${e.inlineComment}`:``;return`${e.key}=${t}${n}`}function v(e){let t=[],n=e.split(/\r?\n/),r=e.endsWith(`
4
- `)?n.slice(0,-1):n;for(let e of r){let n=e.match(h);if(!n){t.push({kind:`raw`,text:e});continue}let r=n[1],{value:i,quoted:a,inlineComment:o}=g(n[2]);t.push({kind:`assign`,key:r,value:i,quoted:a,inlineComment:o})}return{lines:t}}function y(e){return`${e.lines.map(e=>e.kind===`assign`?_(e):e.text).join(`
5
- `)}\n`}function b(e){let t={};for(let n of e.lines)n.kind===`assign`&&(t[n.key]=n.value);return t}function x(e,t,n){let r=e.lines.map(e=>e.kind===`assign`&&e.key===t?{...e,value:n}:e);return e.lines.some(e=>e.kind===`assign`&&e.key===t)||r.push({kind:`assign`,key:t,value:n,quoted:!1,inlineComment:``}),{lines:r}}function S(e,t){return{lines:e.lines.filter(e=>!(e.kind===`assign`&&e.key===t))}}function C(e){return c(e,`.env`)}function w(){return c(e(),`global.env`)}function T(e,t){return e===`workspace`?C(t):w()}function E(e){return n(e)?v(i(e,`utf-8`)):{lines:[]}}function D(e,t){let i=s(e);n(i)||r(i,{recursive:!0});let c=`${e}.${process.pid}.${Date.now()}.tmp`;o(c,y(t),{encoding:`utf-8`,mode:384}),a(c,e)}function O(e,t,r={}){let i=T(e,t),a=n(i),o=b(E(i)),s={};for(let[e,t]of Object.entries(o))s[e]=r.reveal||!m(e)?t:k(t);return{scope:e,path:i,exists:a,vars:s}}function k(e){return e.length===0?``:e.length<=4?`•`.repeat(e.length):`${e.slice(0,2)}${`•`.repeat(Math.min(e.length-4,12))}${e.slice(-2)}`}function A(){return process.env.AIKIT_WORKSPACE_ROOT??process.cwd()}function j(){return t()?`user`:`workspace`}function M(){let t=e();return n(t)||r(t,{recursive:!0}),t}var N=class extends Error{details;constructor(e,t){super(e),this.name=`ConfigValidationError`,this.details=t}};function P(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function F(e=A()){let t=process.env.AIKIT_CONFIG_PATH;return t?c(t):c(e,`aikit.config.json`)}function I(e){if(!n(e))return null;let t=i(e,`utf-8`),r=JSON.parse(t);if(!P(r))throw new N(`config-not-object`,[`Config file must contain a JSON object at the root.`]);return r}function L(e,t){let i=s(e);n(i)||r(i,{recursive:!0});let c=`${JSON.stringify(t,null,2)}\n`,l=`${e}.${process.pid}.${Date.now()}.tmp`;o(l,c,{encoding:`utf-8`}),a(l,e)}function R(e){return e.length===0?[]:e.split(`.`)}function z(e,t,n){let r=R(t);if(r.length===0)throw new N(`invalid-path`,[`Patch path must not be empty.`]);let i={...e},a=i;for(let e=0;e<r.length-1;e+=1){let t=r[e],n=r[e+1],i=/^\d+$/.test(n);if(Array.isArray(a)){let n=Number(t);if(!Number.isInteger(n))throw new N(`invalid-path`,[`Path segment "${t}" must be an integer index for array at depth ${e}.`]);let r=a[n];if(i){let e=Array.isArray(r)?[...r]:[];a[n]=e,a=e}else{let e=P(r)?{...r}:{};a[n]=e,a=e}continue}let o=a[t];if(i){let e=Array.isArray(o)?[...o]:[];a[t]=e,a=e}else{let e=P(o)?{...o}:{};a[t]=e,a=e}}let o=r[r.length-1];if(Array.isArray(a)){let e=Number(o);if(!Number.isInteger(e))throw new N(`invalid-path`,[`Path segment "${o}" must be an integer index for array.`]);a[e]=n}else a[o]=n;return i}function B(e,t){let n=R(t);if(n.length===0)throw new N(`invalid-path`,[`Patch path must not be empty.`]);let r={...e},i=r;for(let e=0;e<n.length-1;e+=1){let t=n[e];if(Array.isArray(i)){let e=Number(t);if(!Number.isInteger(e))return r;let n=i[e];if(!P(n)&&!Array.isArray(n))return r;let a=Array.isArray(n)?[...n]:{...n};i[e]=a,i=a;continue}let a=i[t];if(!P(a)&&!Array.isArray(a))return r;let o=Array.isArray(a)?[...a]:{...a};i[t]=o,i=o}let a=n[n.length-1];if(Array.isArray(i)){let e=Number(a);Number.isInteger(e)&&i.splice(e,1)}else delete i[a];return r}function V(e,t){let n=e;for(let e of t)n=e.op===`set`?z(n,e.path,e.value):B(n,e.path);return n}function H(e){let t=[];if(`autoIndex`in e&&e.autoIndex!==void 0&&typeof e.autoIndex!=`boolean`&&t.push(`autoIndex must be a boolean.`),`serverName`in e&&e.serverName!==void 0&&typeof e.serverName!=`string`&&t.push(`serverName must be a string.`),`toolPrefix`in e&&e.toolPrefix!==void 0&&typeof e.toolPrefix!=`string`&&t.push(`toolPrefix must be a string.`),`indexMode`in e&&e.indexMode!==void 0&&![`auto`,`manual`,`smart`].includes(e.indexMode)&&t.push(`indexMode must be one of: auto, manual, smart.`),(!Array.isArray(e.sources)||e.sources.length===0)&&t.push(`sources must be a non-empty array.`),`indexing`in e&&e.indexing!==void 0)if(!P(e.indexing))t.push(`indexing must be an object.`);else for(let n of[`chunkSize`,`chunkOverlap`,`minChunkSize`,`concurrency`]){let r=e.indexing[n];r!==void 0&&(typeof r!=`number`||!Number.isFinite(r)||r<=0)&&t.push(`indexing.${n} must be a positive number.`)}return`store`in e&&e.store!==void 0&&(P(e.store)?(typeof e.store.backend!=`string`&&t.push(`store.backend must be a string.`),typeof e.store.path!=`string`&&t.push(`store.path must be a string.`)):t.push(`store must be an object.`)),t}const U=l.object({ops:l.array(l.object({op:l.enum([`set`,`unset`]),path:l.string().min(1),value:l.unknown().optional()})).min(1)}),W=l.string().min(1).regex(/^[A-Za-z_][A-Za-z0-9_]*$/,`Invalid env key`),G=l.object({value:l.string(),scope:l.enum([`workspace`,`global`])}),K=l.enum([`workspace`,`global`]);function q(e,t,n,r){e.status(t).json({error:n,details:r})}function J(e){let t=u(),r=e.workspaceRoot??A;return t.get(`/status`,(t,i)=>{let a=r(),o=F(a);i.json({mode:j(),cwd:process.cwd(),workspaceRoot:a,configPath:o,configExists:n(o),globalDataDir:M(),envPaths:{workspace:C(a),global:w()},mcp:e.mcpInfo?.()??{transport:`http`,pid:process.pid,startedAt:new Date(0).toISOString()}})}),t.get(`/schema`,(e,t)=>{t.json({config:d,env:f})}),t.get(`/config`,(e,t)=>{let n=F(r());try{let e=I(n);t.json({path:n,exists:e!==null,content:e??{}})}catch(e){if(e instanceof N){q(t,400,e.message,e.details);return}q(t,500,`config-read-failed`,e instanceof Error?e.message:String(e))}}),t.patch(`/config`,(t,n)=>{let i=U.safeParse(t.body);if(!i.success){q(n,400,`invalid-body`,i.error.issues);return}let a=F(r()),o;try{o=I(a)??{}}catch(e){if(e instanceof N){q(n,400,e.message,e.details);return}q(n,500,`config-read-failed`,e instanceof Error?e.message:String(e));return}let s;try{s=V(o,i.data.ops)}catch(e){if(e instanceof N){q(n,400,e.message,e.details);return}q(n,400,`patch-failed`,e instanceof Error?e.message:String(e));return}let c=H(s);if(c.length>0){q(n,400,`invalid-config`,c);return}try{L(a,s)}catch(e){q(n,500,`config-write-failed`,e instanceof Error?e.message:String(e));return}e.log.info(`Settings: config updated`,{path:a,ops:i.data.ops.length}),n.json({path:a,content:s,restartRecommended:!0})}),t.get(`/env`,(t,n)=>{let i=t.query.reveal===`true`||t.query.reveal===`1`;i&&e.log.warn(`Settings: env values revealed`,{ip:t.ip??`unknown`});let a=r();n.json({workspace:O(`workspace`,a,{reveal:i}),global:O(`global`,a,{reveal:i}),processOverrides:Object.keys(process.env).filter(e=>e.startsWith(`AIKIT_`)||/^(SEARXNG_URL|GOOGLE_|BRAVE_|BING_)/.test(e)).sort()})}),t.put(`/env/:key`,(t,n)=>{let i=W.safeParse(t.params.key);if(!i.success){q(n,400,`invalid-key`,i.error.issues);return}let a=G.safeParse(t.body);if(!a.success){q(n,400,`invalid-body`,a.error.issues);return}let o=a.data.scope,s=T(o,r());try{D(s,x(E(s),i.data,a.data.value)),e.log.info(`Settings: env set`,{key:i.data,scope:o,path:s}),n.json({ok:!0,scope:o,path:s,restartRecommended:!0})}catch(e){q(n,500,`env-write-failed`,e instanceof Error?e.message:String(e))}}),t.delete(`/env/:key`,(t,n)=>{let i=W.safeParse(t.params.key);if(!i.success){q(n,400,`invalid-key`,i.error.issues);return}let a=K.safeParse(t.query.scope);if(!a.success){q(n,400,`invalid-scope`,a.error.issues);return}let o=a.data,s=T(o,r());try{D(s,S(E(s),i.data)),e.log.info(`Settings: env unset`,{key:i.data,scope:o,path:s}),n.json({ok:!0,scope:o,path:s,restartRecommended:!0})}catch(e){q(n,500,`env-write-failed`,e instanceof Error?e.message:String(e))}}),t}export{J as createSettingsRouter};
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env node
2
- import{getGlobalDataDir as e,isUserInstalled as t}from"../../core/dist/index.js";import{existsSync as n,mkdirSync as r,readFileSync as i,renameSync as a,writeFileSync as o}from"node:fs";import{dirname as s,resolve as c}from"node:path";import{z as l}from"zod";import{Router as u}from"express";const d=[{key:`serverName`,type:`string`,default:`aikit`,description:`MCP server name advertised to clients.`,group:`general`,requiresRestart:!0},{key:`toolPrefix`,type:`string`,default:``,description:`Prefix prepended to every MCP tool name (e.g. "aikit_").`,group:`general`,requiresRestart:!0},{key:`toolProfile`,type:`string`,default:`full`,description:`Active tool profile.`,group:`general`,enum:[`full`,`safe`,`research`,`minimal`,`discovery`],requiresRestart:!0},{key:`autoIndex`,type:`boolean`,default:!1,description:`Deprecated. Prefer indexMode. true → auto, false → manual.`,group:`indexing`},{key:`indexMode`,type:`string`,default:`smart`,description:`Indexing strategy. auto = full on startup, manual = on demand, smart = on-demand + idle.`,group:`indexing`,enum:[`auto`,`manual`,`smart`]},{key:`sources`,type:`array`,description:`Source roots to index. Each entry has { path, excludePatterns }.`,group:`indexing`,requiresRestart:!0},{key:`indexing.chunkSize`,type:`number`,default:1500,description:`Maximum chunk size in characters.`,group:`indexing`},{key:`indexing.chunkOverlap`,type:`number`,default:200,description:`Overlap between adjacent chunks.`,group:`indexing`},{key:`indexing.minChunkSize`,type:`number`,default:100,description:`Minimum chunk size before merging into the next chunk.`,group:`indexing`},{key:`indexing.concurrency`,type:`number`,description:`Max files processed concurrently. Defaults to half of CPU cores.`,group:`indexing`},{key:`embedding.model`,type:`string`,default:`mixedbread-ai/mxbai-embed-large-v1`,description:`Embedding model identifier.`,group:`embedding`,requiresRestart:!0},{key:`embedding.dimensions`,type:`number`,default:1024,description:`Embedding vector dimensions. Must match the model.`,group:`embedding`,requiresRestart:!0},{key:`store.backend`,type:`string`,default:`sqlite-vec`,description:`Vector store backend (sqlite-vec | lancedb).`,group:`store`,requiresRestart:!0},{key:`store.path`,type:`string`,description:`Filesystem path for the vector store.`,group:`store`,requiresRestart:!0},{key:`curated.path`,type:`string`,description:`Path to curated knowledge directory.`,group:`store`,requiresRestart:!0},{key:`onboardDir`,type:`string`,description:`Directory for onboard / produce_knowledge output.`,group:`store`,requiresRestart:!0},{key:`stateDir`,type:`string`,description:`Directory for session state (stash, checkpoints, etc.).`,group:`store`,requiresRestart:!0},{key:`er.enabled`,type:`boolean`,default:!1,description:`Enable enterprise RAG bridge integration.`,group:`enterprise-bridge`,requiresRestart:!0},{key:`er.baseUrl`,type:`string`,description:`Base URL of the ER API.`,group:`enterprise-bridge`,requiresRestart:!0},{key:`er.timeoutMs`,type:`number`,default:5e3,description:`ER request timeout in milliseconds.`,group:`enterprise-bridge`},{key:`er.fallbackThreshold`,type:`number`,default:.45,description:`Vector similarity threshold below which ER fallback triggers.`,group:`enterprise-bridge`}],f=[{key:`AIKIT_TRANSPORT`,type:`string`,default:`stdio`,description:`MCP transport mode.`,group:`transport`,enum:[`stdio`,`http`],defaultScope:`workspace`},{key:`AIKIT_PORT`,type:`string`,default:`3210`,description:`HTTP port when transport = http.`,group:`transport`,defaultScope:`workspace`},{key:`AIKIT_CORS_ORIGIN`,type:`string`,description:`CORS Access-Control-Allow-Origin header for HTTP mode.`,group:`transport`,defaultScope:`workspace`},{key:`AIKIT_CONFIG_PATH`,type:`string`,description:`Override path to aikit.config.json.`,group:`paths`,defaultScope:`workspace`},{key:`AIKIT_WORKSPACE_ROOT`,type:`string`,description:`Override workspace root used when no config file is present.`,group:`paths`,defaultScope:`workspace`},{key:`AIKIT_GLOBAL_DATA_DIR`,type:`string`,description:`Override global data directory (default: ~/.aikit).`,group:`paths`,defaultScope:`global`},{key:`AIKIT_INDEX_MODE`,type:`string`,description:`Override config indexMode.`,group:`indexing`,enum:[`auto`,`manual`,`smart`],defaultScope:`workspace`},{key:`AIKIT_AUTO_INDEX`,type:`string`,description:`Legacy boolean override. Prefer AIKIT_INDEX_MODE.`,group:`indexing`,enum:[`true`,`false`],defaultScope:`workspace`},{key:`AIKIT_TOOLSET`,type:`string`,description:`Override active tool profile.`,group:`general`,defaultScope:`workspace`},{key:`AIKIT_BROWSER_DEFAULT_MODE`,type:`string`,default:`ui`,description:`Default browser launch mode for browser_* tools.`,group:`browser`,enum:[`ui`,`headless`,`panel`],defaultScope:`workspace`},{key:`AIKIT_BROWSER_PATH`,type:`string`,description:`Optional Playwright browser download path override.`,group:`browser`,defaultScope:`workspace`},{key:`AIKIT_BROWSER_IDLE_MINUTES`,type:`string`,default:`10`,description:`Idle shutdown timeout in minutes for the shared browser runtime.`,group:`browser`,defaultScope:`workspace`},{key:`AIKIT_BROWSER_EVAL_TIMEOUT_MS`,type:`string`,default:`5000`,description:`Default browser_eval timeout in milliseconds.`,group:`browser`,defaultScope:`workspace`},{key:`AIKIT_SEARCH_DEADLINE_MS`,type:`string`,default:`10000`,description:`Multi-provider web search deadline (milliseconds).`,group:`search-providers`,defaultScope:`global`},{key:`SEARXNG_URL`,type:`string`,description:`Optional SearXNG instance URL for the web_search tool.`,group:`search-providers`,defaultScope:`global`},{key:`GOOGLE_API_KEY`,type:`secret`,description:`Google Custom Search API key.`,group:`search-providers`,defaultScope:`global`},{key:`GOOGLE_CSE_ID`,type:`string`,description:`Google Custom Search Engine ID.`,group:`search-providers`,defaultScope:`global`},{key:`BRAVE_API_KEY`,type:`secret`,description:`Brave Search API key.`,group:`search-providers`,defaultScope:`global`},{key:`BING_API_KEY`,type:`secret`,description:`Bing Web Search API key.`,group:`search-providers`,defaultScope:`global`}];function p(e){return f.find(t=>t.key===e)}function m(e){let t=p(e);return t?t.type===`secret`:/(_KEY|_TOKEN|_SECRET|_PASSWORD|_PASS|_PWD)$/i.test(e)}const h=/^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=(.*)$/;function g(e){let t=e.replace(/^\s+/,``);if(t.startsWith(`"`)){let e=1,n=``;for(;e<t.length;){let r=t[e];if(r===`\\`&&e+1<t.length){let r=t[e+1];r===`n`?n+=`
3
- `:r===`r`?n+=`\r`:r===`t`?n+=` `:n+=r,e+=2;continue}if(r===`"`){let r=t.slice(e+1),i=r.indexOf(`#`),a=i===-1?``:r.slice(i);return{value:n,quoted:!0,inlineComment:a}}n+=r,e+=1}return{value:t.slice(1),quoted:!0,inlineComment:``}}let n=t.match(/(\s+#.*)$/);return n&&n.index!==void 0?{value:t.slice(0,n.index).trimEnd(),quoted:!1,inlineComment:n[1].trimStart()}:{value:t.trimEnd(),quoted:!1,inlineComment:``}}function _(e){let t;t=e.quoted||/[\s#"']/.test(e.value)||e.value.includes(`
4
- `)||e.value.length===0?`"${e.value.replace(/\\/g,`\\\\`).replace(/"/g,`\\"`).replace(/\n/g,`\\n`).replace(/\r/g,`\\r`).replace(/\t/g,`\\t`)}"`:e.value;let n=e.inlineComment?` ${e.inlineComment}`:``;return`${e.key}=${t}${n}`}function v(e){let t=[],n=e.split(/\r?\n/),r=e.endsWith(`
5
- `)?n.slice(0,-1):n;for(let e of r){let n=e.match(h);if(!n){t.push({kind:`raw`,text:e});continue}let r=n[1],{value:i,quoted:a,inlineComment:o}=g(n[2]);t.push({kind:`assign`,key:r,value:i,quoted:a,inlineComment:o})}return{lines:t}}function y(e){return`${e.lines.map(e=>e.kind===`assign`?_(e):e.text).join(`
6
- `)}\n`}function b(e){let t={};for(let n of e.lines)n.kind===`assign`&&(t[n.key]=n.value);return t}function x(e,t,n){let r=e.lines.map(e=>e.kind===`assign`&&e.key===t?{...e,value:n}:e);return e.lines.some(e=>e.kind===`assign`&&e.key===t)||r.push({kind:`assign`,key:t,value:n,quoted:!1,inlineComment:``}),{lines:r}}function S(e,t){return{lines:e.lines.filter(e=>!(e.kind===`assign`&&e.key===t))}}function C(e){return c(e,`.env`)}function w(){return c(e(),`global.env`)}function T(e,t){return e===`workspace`?C(t):w()}function E(e){return n(e)?v(i(e,`utf-8`)):{lines:[]}}function D(e,t){let i=s(e);n(i)||r(i,{recursive:!0});let c=`${e}.${process.pid}.${Date.now()}.tmp`;o(c,y(t),{encoding:`utf-8`,mode:384}),a(c,e)}function O(e,t,r={}){let i=T(e,t),a=n(i),o=b(E(i)),s={};for(let[e,t]of Object.entries(o))s[e]=r.reveal||!m(e)?t:k(t);return{scope:e,path:i,exists:a,vars:s}}function k(e){return e.length===0?``:e.length<=4?`•`.repeat(e.length):`${e.slice(0,2)}${`•`.repeat(Math.min(e.length-4,12))}${e.slice(-2)}`}function A(){return process.env.AIKIT_WORKSPACE_ROOT??process.cwd()}function j(){return t()?`user`:`workspace`}function M(){let t=e();return n(t)||r(t,{recursive:!0}),t}var N=class extends Error{details;constructor(e,t){super(e),this.name=`ConfigValidationError`,this.details=t}};function P(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function F(e=A()){let t=process.env.AIKIT_CONFIG_PATH;return t?c(t):c(e,`aikit.config.json`)}function I(e){if(!n(e))return null;let t=i(e,`utf-8`),r=JSON.parse(t);if(!P(r))throw new N(`config-not-object`,[`Config file must contain a JSON object at the root.`]);return r}function L(e,t){let i=s(e);n(i)||r(i,{recursive:!0});let c=`${JSON.stringify(t,null,2)}\n`,l=`${e}.${process.pid}.${Date.now()}.tmp`;o(l,c,{encoding:`utf-8`}),a(l,e)}function R(e){return e.length===0?[]:e.split(`.`)}function z(e,t,n){let r=R(t);if(r.length===0)throw new N(`invalid-path`,[`Patch path must not be empty.`]);let i={...e},a=i;for(let e=0;e<r.length-1;e+=1){let t=r[e],n=r[e+1],i=/^\d+$/.test(n);if(Array.isArray(a)){let n=Number(t);if(!Number.isInteger(n))throw new N(`invalid-path`,[`Path segment "${t}" must be an integer index for array at depth ${e}.`]);let r=a[n];if(i){let e=Array.isArray(r)?[...r]:[];a[n]=e,a=e}else{let e=P(r)?{...r}:{};a[n]=e,a=e}continue}let o=a[t];if(i){let e=Array.isArray(o)?[...o]:[];a[t]=e,a=e}else{let e=P(o)?{...o}:{};a[t]=e,a=e}}let o=r[r.length-1];if(Array.isArray(a)){let e=Number(o);if(!Number.isInteger(e))throw new N(`invalid-path`,[`Path segment "${o}" must be an integer index for array.`]);a[e]=n}else a[o]=n;return i}function B(e,t){let n=R(t);if(n.length===0)throw new N(`invalid-path`,[`Patch path must not be empty.`]);let r={...e},i=r;for(let e=0;e<n.length-1;e+=1){let t=n[e];if(Array.isArray(i)){let e=Number(t);if(!Number.isInteger(e))return r;let n=i[e];if(!P(n)&&!Array.isArray(n))return r;let a=Array.isArray(n)?[...n]:{...n};i[e]=a,i=a;continue}let a=i[t];if(!P(a)&&!Array.isArray(a))return r;let o=Array.isArray(a)?[...a]:{...a};i[t]=o,i=o}let a=n[n.length-1];if(Array.isArray(i)){let e=Number(a);Number.isInteger(e)&&i.splice(e,1)}else delete i[a];return r}function V(e,t){let n=e;for(let e of t)n=e.op===`set`?z(n,e.path,e.value):B(n,e.path);return n}function H(e){let t=[];if(`autoIndex`in e&&e.autoIndex!==void 0&&typeof e.autoIndex!=`boolean`&&t.push(`autoIndex must be a boolean.`),`serverName`in e&&e.serverName!==void 0&&typeof e.serverName!=`string`&&t.push(`serverName must be a string.`),`toolPrefix`in e&&e.toolPrefix!==void 0&&typeof e.toolPrefix!=`string`&&t.push(`toolPrefix must be a string.`),`indexMode`in e&&e.indexMode!==void 0&&![`auto`,`manual`,`smart`].includes(e.indexMode)&&t.push(`indexMode must be one of: auto, manual, smart.`),(!Array.isArray(e.sources)||e.sources.length===0)&&t.push(`sources must be a non-empty array.`),`indexing`in e&&e.indexing!==void 0)if(!P(e.indexing))t.push(`indexing must be an object.`);else for(let n of[`chunkSize`,`chunkOverlap`,`minChunkSize`,`concurrency`]){let r=e.indexing[n];r!==void 0&&(typeof r!=`number`||!Number.isFinite(r)||r<=0)&&t.push(`indexing.${n} must be a positive number.`)}return`store`in e&&e.store!==void 0&&(P(e.store)?(typeof e.store.backend!=`string`&&t.push(`store.backend must be a string.`),typeof e.store.path!=`string`&&t.push(`store.path must be a string.`)):t.push(`store must be an object.`)),t}const U=l.object({ops:l.array(l.object({op:l.enum([`set`,`unset`]),path:l.string().min(1),value:l.unknown().optional()})).min(1)}),W=l.string().min(1).regex(/^[A-Za-z_][A-Za-z0-9_]*$/,`Invalid env key`),G=l.object({value:l.string(),scope:l.enum([`workspace`,`global`])}),K=l.enum([`workspace`,`global`]);function q(e,t,n,r){e.status(t).json({error:n,details:r})}function J(e){let t=u(),r=e.workspaceRoot??A;return t.get(`/status`,(t,i)=>{let a=r(),o=F(a);i.json({mode:j(),cwd:process.cwd(),workspaceRoot:a,configPath:o,configExists:n(o),globalDataDir:M(),envPaths:{workspace:C(a),global:w()},mcp:e.mcpInfo?.()??{transport:`http`,pid:process.pid,startedAt:new Date(0).toISOString()}})}),t.get(`/schema`,(e,t)=>{t.json({config:d,env:f})}),t.get(`/config`,(e,t)=>{let n=F(r());try{let e=I(n);t.json({path:n,exists:e!==null,content:e??{}})}catch(e){if(e instanceof N){q(t,400,e.message,e.details);return}q(t,500,`config-read-failed`,e instanceof Error?e.message:String(e))}}),t.patch(`/config`,(t,n)=>{let i=U.safeParse(t.body);if(!i.success){q(n,400,`invalid-body`,i.error.issues);return}let a=F(r()),o;try{o=I(a)??{}}catch(e){if(e instanceof N){q(n,400,e.message,e.details);return}q(n,500,`config-read-failed`,e instanceof Error?e.message:String(e));return}let s;try{s=V(o,i.data.ops)}catch(e){if(e instanceof N){q(n,400,e.message,e.details);return}q(n,400,`patch-failed`,e instanceof Error?e.message:String(e));return}let c=H(s);if(c.length>0){q(n,400,`invalid-config`,c);return}try{L(a,s)}catch(e){q(n,500,`config-write-failed`,e instanceof Error?e.message:String(e));return}e.log.info(`Settings: config updated`,{path:a,ops:i.data.ops.length}),n.json({path:a,content:s,restartRecommended:!0})}),t.get(`/env`,(t,n)=>{let i=t.query.reveal===`true`||t.query.reveal===`1`;i&&e.log.warn(`Settings: env values revealed`,{ip:t.ip??`unknown`});let a=r();n.json({workspace:O(`workspace`,a,{reveal:i}),global:O(`global`,a,{reveal:i}),processOverrides:Object.keys(process.env).filter(e=>e.startsWith(`AIKIT_`)||/^(SEARXNG_URL|GOOGLE_|BRAVE_|BING_)/.test(e)).sort()})}),t.put(`/env/:key`,(t,n)=>{let i=W.safeParse(t.params.key);if(!i.success){q(n,400,`invalid-key`,i.error.issues);return}let a=G.safeParse(t.body);if(!a.success){q(n,400,`invalid-body`,a.error.issues);return}let o=a.data.scope,s=T(o,r());try{D(s,x(E(s),i.data,a.data.value)),e.log.info(`Settings: env set`,{key:i.data,scope:o,path:s}),n.json({ok:!0,scope:o,path:s,restartRecommended:!0})}catch(e){q(n,500,`env-write-failed`,e instanceof Error?e.message:String(e))}}),t.delete(`/env/:key`,(t,n)=>{let i=W.safeParse(t.params.key);if(!i.success){q(n,400,`invalid-key`,i.error.issues);return}let a=K.safeParse(t.query.scope);if(!a.success){q(n,400,`invalid-scope`,a.error.issues);return}let o=a.data,s=T(o,r());try{D(s,S(E(s),i.data)),e.log.info(`Settings: env unset`,{key:i.data,scope:o,path:s}),n.json({ok:!0,scope:o,path:s,restartRecommended:!0})}catch(e){q(n,500,`env-write-failed`,e instanceof Error?e.message:String(e))}}),t}export{J as createSettingsRouter};
@@ -1 +0,0 @@
1
- import{r as e}from"./server-Bme4eBy1.js";export{e as createSamplingClient};
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import{r as e}from"./server-B9PIl5SY.js";export{e as createSamplingClient};
@@ -1 +0,0 @@
1
- import{fileURLToPath as e}from"node:url";import{INSTALL_ARGS as t,cleanupOldVersions as n,createLogger as r}from"../../core/dist/index.js";import{existsSync as i,mkdirSync as a,readFileSync 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=r(`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=>i(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(o(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}`,r=d(C,`${n}-staging`),o=d(C,n);try{i(r)&&c(r,{recursive:!0,force:!0}),a(r,{recursive:!0}),m(`tar -xzf "${m(`npm pack ${_}@${e} 2>${process.platform===`win32`?`NUL`:`/dev/null`}`,{cwd:r,encoding:`utf-8`,timeout:6e4,windowsHide:!0}).trim()}"`,{cwd:r,encoding:`utf-8`,stdio:`pipe`,timeout:3e4,windowsHide:!0});let n=d(r,`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(!i(u))throw Error(`Server entry not found at ${u}`);if(!i(d(n,`node_modules`)))throw Error(`node_modules not found — npm install may have failed`);i(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),j(e)}finally{i(r)&&c(r,{recursive:!0,force:!0})}}function A(e){y.debug(`Updated to v${e}. Restarting server...`),setTimeout(()=>{process.exit(0)},300).unref()}function j(e){n(C,e??E())}async function M(){try{let e=o(S,`utf-8`),{version:t}=JSON.parse(e),n=await fetch(v,{signal:AbortSignal.timeout(1e4)});if(!n.ok)return;let r=(await n.json()).version;if(!r||r===t||!O(r,t))return;if(i(d(C,`v${r}`))){let e=`${S}.tmp`;l(e,JSON.stringify({version:r,installedAt:new Date().toISOString()},null,2)),s(e,S),y.debug(`Re-activated existing version v${r} — no download needed`),A(r);return}y.debug(`New version available: ${r}. Installing...`),await k(r),A(r)}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(i(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 i(e)?JSON.parse(o(e,`utf-8`)).version??null:null}catch{return null}}function L(){try{let e=f(process.cwd(),`.github`,`.aikit-scaffold.json`);return i(e)?JSON.parse(o(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};
@@ -1,2 +0,0 @@
1
- #!/usr/bin/env node
2
- import{fileURLToPath as e}from"node:url";import{INSTALL_ARGS as t,cleanupOldVersions as n,createLogger as r}from"../../core/dist/index.js";import{existsSync as i,mkdirSync as a,readFileSync 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=r(`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=>i(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(o(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}`,r=d(C,`${n}-staging`),o=d(C,n);try{i(r)&&c(r,{recursive:!0,force:!0}),a(r,{recursive:!0}),h(`tar -xzf "${h(`npm pack ${_}@${e} 2>${process.platform===`win32`?`NUL`:`/dev/null`}`,{cwd:r,encoding:`utf-8`,timeout:6e4,windowsHide:!0}).trim()}"`,{cwd:r,encoding:`utf-8`,stdio:`pipe`,timeout:3e4,windowsHide:!0});let n=d(r,`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(!i(u))throw Error(`Server entry not found at ${u}`);if(!i(d(n,`node_modules`)))throw Error(`node_modules not found — npm install may have failed`);i(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),j(e)}finally{i(r)&&c(r,{recursive:!0,force:!0})}}function A(e){y.debug(`Updated to v${e}. Restarting server...`),setTimeout(()=>{process.exit(0)},300).unref()}function j(e){n(C,e??E())}async function M(){try{let e=o(S,`utf-8`),{version:t}=JSON.parse(e),n=await fetch(v,{signal:AbortSignal.timeout(1e4)});if(!n.ok)return;let r=(await n.json()).version;if(!r||r===t||!O(r,t))return;if(i(d(C,`v${r}`))){let e=`${S}.tmp`;l(e,JSON.stringify({version:r,installedAt:new Date().toISOString()},null,2)),s(e,S),y.debug(`Re-activated existing version v${r} — no download needed`),A(r);return}y.debug(`New version available: ${r}. Installing...`),await k(r),A(r)}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(i(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 i(e)?JSON.parse(o(e,`utf-8`)).version??null:null}catch{return null}}function L(){try{let e=f(process.cwd(),`.github`,`.aikit-scaffold.json`);return i(e)?JSON.parse(o(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{serializeError as t}from"../../core/dist/index.js";import{resolve as n}from"node:path";function r(t){return t.startsWith(`file://`)?e(t):t}function i(e){let t=n(e);return process.platform===`win32`?t.toLowerCase():t}function a(e){let t=new Map;for(let n of e){let e=r(n.uri);t.set(i(e),e)}return[...t.values()].sort((e,t)=>i(e).localeCompare(i(t)))}function o({config:e,roots:t}){let n=a(t);if(n.length===0)return null;let r=e.sources?.[0]?.path;if(r){let e=i(r),t=n.find(t=>i(t)===e);if(t)return t}return n[0]}function s({config:e,log:t,reconfigureForWorkspace:n,roots:r}){let s=a(r);if(s.length===0)return!1;let c=o({config:e,roots:s.map(e=>({uri:e}))});if(!c)return!1;let l=e.sources?.[0]?.path;return t.debug(`MCP roots resolved`,{rootPath:c,rootCount:s.length,selectedBy:l&&i(l)===i(c)?`configured-source`:`stable-sorted-root`}),n(e,c),e.allRoots=s,!0}async function c({config:e,indexMode:n,log:r,rootsChangedNotificationSchema:i,reconfigureForWorkspace:a,runInitialIndex:o,server:c,startInit:l,timeoutMs:u=5e3,getCwd:d=()=>process.env.AIKIT_WORKSPACE_ROOT??process.cwd(),version:f=`0.0.0`}){let p=!1,m=!1,h,g=c.server,_=e=>{let n=t(e),r=`${String(e)} ${String(n.message??``)}`.toLowerCase();return r.includes(`method not found`)||r.includes(`not supported`)||r.includes(`unsupported`)||r.includes(`unknown method`)||r.includes(`roots/list`)||r.includes(`timed out`)},v=()=>{p||(p=!0,l())},y=()=>{m||n!==`auto`||(m=!0,(async()=>{try{await o()}catch(e){r.error(`Initial index failed`,{version:f,...t(e)})}})())},b=t=>t.length===0||(h&&=(clearTimeout(h),void 0),!s({config:e,log:r,reconfigureForWorkspace:a,roots:t}))?!1:(v(),y(),!0);try{if(b((await g.listRoots()).roots))return;r.debug(`No MCP roots yet; waiting for roots/list_changed notification`)}catch(n){if(_(n)){let i=e.sources?.[0]?.path;i?(r.debug(`MCP roots/list not supported; using configured source path`,{version:f,configuredRoot:i,cwd:d(),...t(n)}),v(),y()):(r.warn(`MCP roots/list not supported by client; using cwd fallback`,{version:f,cwd:d(),...t(n)}),s({config:e,log:r,reconfigureForWorkspace:a,roots:[{uri:d()}]})&&(v(),y()));return}r.warn(`MCP roots/list failed; waiting for roots/list_changed notification`,{version:f,cwd:d(),...t(n)})}g.setNotificationHandler(i,async()=>{try{b((await g.listRoots()).roots)}catch(e){r.warn(`roots/list retry failed after notification`,{version:f,...t(e)})}}),h=setTimeout(()=>{let t=e.sources?.[0]?.path;if(t)r.debug(`Timed out waiting for roots/list_changed; using configured source path`,{configuredRoot:t}),v(),y();else{let t=d();r.debug(`Timed out waiting for roots/list_changed; falling back to cwd workspace`,{cwd:t}),s({config:e,log:r,reconfigureForWorkspace:a,roots:[{uri:t}]})&&(v(),y())}},u)}export{c as n,o as r,s as t};