@automaton-labs/aib 0.0.7 → 0.0.8

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 (477) hide show
  1. package/README.md +36 -257
  2. package/config/agent-dx-policy.default.json +31 -0
  3. package/config/control-plane-client.default.json +3 -0
  4. package/dist/agent-dx/agent-dx.js +805 -0
  5. package/dist/agent-dx/presentation.js +32 -0
  6. package/dist/alias-advisor/analyze.js +982 -0
  7. package/dist/alias-advisor/exact-text-cost.js +74 -0
  8. package/dist/alias-advisor/lexical.js +240 -0
  9. package/dist/alias-advisor/model.js +2 -0
  10. package/dist/alias-advisor/path-identity.js +49 -0
  11. package/dist/alias-advisor/ranking.js +171 -0
  12. package/dist/alias-advisor/token-estimator.js +85 -0
  13. package/dist/bin/aib.js +5 -1
  14. package/dist/bin/cli.js +811 -4
  15. package/dist/commands/add-missing-imports-preview-cache.js +99 -2
  16. package/dist/commands/add-missing-imports.js +241 -2
  17. package/dist/commands/apply-module-plan.js +1319 -3
  18. package/dist/commands/background-command.js +378 -2
  19. package/dist/commands/captured-input.js +74 -1
  20. package/dist/commands/config-command.js +314 -2
  21. package/dist/commands/config-output.js +357 -10
  22. package/dist/commands/control-plane-command.js +183 -1
  23. package/dist/commands/declaration-command.js +1209 -7
  24. package/dist/commands/declaration-execution-cache.js +79 -1
  25. package/dist/commands/declaration-format.js +221 -1
  26. package/dist/commands/declaration-preview-cache.js +114 -2
  27. package/dist/commands/diagnostics-command.js +70 -3
  28. package/dist/commands/doctor.js +137 -3
  29. package/dist/commands/execution-command.js +117 -1
  30. package/dist/commands/exports-star-collapse-command.js +178 -0
  31. package/dist/commands/exports-star-command.js +252 -0
  32. package/dist/commands/exports-star-preview-cache.js +84 -0
  33. package/dist/commands/feedback-command.js +176 -3
  34. package/dist/commands/file-move-to-dir-execution-cache.js +92 -1
  35. package/dist/commands/file-move-to-dir-preview-cache.js +125 -2
  36. package/dist/commands/file-move-to-dir-worker.js +54 -0
  37. package/dist/commands/file-move-to-dir.js +1073 -5
  38. package/dist/commands/file-mutation-runtime.js +102 -1
  39. package/dist/commands/file-mutation-worker-apply.js +180 -0
  40. package/dist/commands/file-refactor-batch-execution-cache.js +90 -1
  41. package/dist/commands/file-refactor-batch-preview-cache.js +125 -2
  42. package/dist/commands/file-refactor-batch-worker.js +54 -0
  43. package/dist/commands/file-refactor-batch.js +1154 -5
  44. package/dist/commands/file-rename-execution-cache.js +92 -1
  45. package/dist/commands/file-rename-preview-cache.js +125 -2
  46. package/dist/commands/file-rename-worker.js +54 -0
  47. package/dist/commands/file-rename.js +1053 -5
  48. package/dist/commands/file-text-edit-executor.js +205 -0
  49. package/dist/commands/find-importers.js +52 -1
  50. package/dist/commands/find-unused-imports.js +55 -1
  51. package/dist/commands/generate-docs-command.js +244 -6
  52. package/dist/commands/help-command.js +460 -7
  53. package/dist/commands/import-specifier-policy.js +391 -0
  54. package/dist/commands/imports-command.js +68 -1
  55. package/dist/commands/imports-rebase.js +1138 -0
  56. package/dist/commands/init-skill-usage.js +92 -3
  57. package/dist/commands/init-workspace.js +30 -1
  58. package/dist/commands/inspect-alias-candidates.js +413 -0
  59. package/dist/commands/inspect-cycles.js +811 -5
  60. package/dist/commands/inspect-direct-usages.js +98 -0
  61. package/dist/commands/inspect-duplicates-format.js +229 -0
  62. package/dist/commands/inspect-format-primitives.js +127 -0
  63. package/dist/commands/inspect-format.js +1590 -18
  64. package/dist/commands/inspect-graph.js +1553 -9
  65. package/dist/commands/inspect-imports.js +339 -2
  66. package/dist/commands/inspect-mixed-format.js +524 -0
  67. package/dist/commands/inspect-module-plan-format.js +216 -0
  68. package/dist/commands/inspect-module-plan-serialization.js +402 -0
  69. package/dist/commands/inspect-reference-path-format.js +157 -0
  70. package/dist/commands/inspect-request-values.js +599 -0
  71. package/dist/commands/inspect-selector-kind.js +21 -0
  72. package/dist/commands/inspect-selector.js +50 -0
  73. package/dist/commands/inspect-symbol-format.js +90 -0
  74. package/dist/commands/inspect-topology.js +435 -0
  75. package/dist/commands/inspect-tree.js +827 -5
  76. package/dist/commands/inspect-usages-detail.js +793 -0
  77. package/dist/commands/inspect-usages-evidence.js +31 -0
  78. package/dist/commands/inspect-usages-format.js +367 -0
  79. package/dist/commands/inspect.js +1450 -16
  80. package/dist/commands/internal-command.js +64 -0
  81. package/dist/commands/json-file-input.js +60 -1
  82. package/dist/commands/module-plan-cache.js +156 -2
  83. package/dist/commands/module-plan-standalone.js +208 -0
  84. package/dist/commands/module-plan-timeout.js +77 -1
  85. package/dist/commands/move-preview-cache.js +101 -2
  86. package/dist/commands/mutate-aggregate-output.js +996 -0
  87. package/dist/commands/mutate-child-execution.js +374 -0
  88. package/dist/commands/mutate-command.js +1394 -0
  89. package/dist/commands/mutate-declaration-output.js +313 -0
  90. package/dist/commands/mutate-domain-adapters.js +638 -0
  91. package/dist/commands/mutate-execution-cache.js +114 -0
  92. package/dist/commands/mutate-execution-status.js +598 -0
  93. package/dist/commands/mutate-failure-output.js +531 -0
  94. package/dist/commands/mutate-file-view.js +151 -0
  95. package/dist/commands/mutate-object-output.js +91 -0
  96. package/dist/commands/mutate-output-values.js +97 -0
  97. package/dist/commands/mutate-preview-cache.js +86 -0
  98. package/dist/commands/mutate-response-replay.js +153 -0
  99. package/dist/commands/mutate-result-projection.js +818 -0
  100. package/dist/commands/mutation-eta.js +28 -0
  101. package/dist/commands/mutation-execution-cache.js +140 -3
  102. package/dist/commands/mutation-recovery-journal.js +195 -0
  103. package/dist/commands/normalize-imports.js +1120 -4
  104. package/dist/commands/object-pack-command.js +546 -0
  105. package/dist/commands/object-pack-preview-cache.js +88 -0
  106. package/dist/commands/observability-command.js +47 -3
  107. package/dist/commands/ota-command.js +403 -2
  108. package/dist/commands/print-config.js +10 -1
  109. package/dist/commands/quick-read.js +1113 -11
  110. package/dist/commands/refactor-batch-builder.js +265 -1
  111. package/dist/commands/refactor-batch-execution-cache.js +85 -1
  112. package/dist/commands/refactor-batch-preview-cache.js +96 -2
  113. package/dist/commands/refactor-batch.js +461 -4
  114. package/dist/commands/rename-entities.js +794 -4
  115. package/dist/commands/rename-execution-cache.js +49 -1
  116. package/dist/commands/rename-input.js +22 -1
  117. package/dist/commands/rename-polling-policy.js +68 -0
  118. package/dist/commands/rename-preview-cache.js +96 -2
  119. package/dist/commands/result-view.js +993 -7
  120. package/dist/commands/reveal-command.js +445 -5
  121. package/dist/commands/selector-suggestions.js +93 -0
  122. package/dist/commands/session-workspace.js +1836 -31
  123. package/dist/commands/shared.js +2 -1
  124. package/dist/commands/skills-command.js +315 -0
  125. package/dist/commands/sync-command.js +59 -2
  126. package/dist/commands/worker-command.js +173 -1
  127. package/dist/commands/workspace-cache.js +55 -1
  128. package/dist/config/defaults.js +26 -1
  129. package/dist/config/env-vars.js +77 -1
  130. package/dist/config/glob-match.js +44 -1
  131. package/dist/config/import-rules.js +165 -1
  132. package/dist/config/local-config.js +293 -3
  133. package/dist/config/mutation-comments.js +51 -1
  134. package/dist/config/path-aliases.js +165 -1
  135. package/dist/config/path-display.js +84 -1
  136. package/dist/config/product-storage.js +37 -1
  137. package/dist/config/request-env.js +21 -0
  138. package/dist/config/request-routing-context.js +23 -0
  139. package/dist/config/resolve-command-alias.js +74 -1
  140. package/dist/config/resolve.js +24 -1
  141. package/dist/config/tsconfig-discovery.js +113 -1
  142. package/dist/config/typescript-preferences.js +131 -0
  143. package/dist/config/workspace-root.js +310 -3
  144. package/dist/config/workspace-state.js +254 -1
  145. package/dist/content/content-bundle.js +88 -1
  146. package/dist/diagnostics/module-plan-timeline.js +75 -2
  147. package/dist/diagnostics/readiness-text.js +45 -8
  148. package/dist/dsl/aib-dsl.js +838 -1
  149. package/dist/dsl/declaration-dsl.js +264 -1
  150. package/dist/dsl/file-move-to-dir-dsl.js +123 -1
  151. package/dist/dsl/file-refactor-batch-dsl.js +203 -1
  152. package/dist/dsl/file-rename-dsl.js +135 -1
  153. package/dist/dsl/mutate-dsl.js +746 -0
  154. package/dist/help/bootstrap.bash.md +176 -341
  155. package/dist/help/bootstrap.md +175 -340
  156. package/dist/help/bootstrap.pwsh.md +176 -341
  157. package/dist/help/docs/basics.md +1 -1
  158. package/dist/help/docs/config-setup.import-normalize.md +65 -65
  159. package/dist/help/docs/config-setup.import-rules.md +6 -5
  160. package/dist/help/docs/first-setup.md +6 -5
  161. package/dist/help/docs/help-protocol.md +4 -3
  162. package/dist/help/docs/import.base.md +38 -0
  163. package/dist/help/docs/import.rebase.md +85 -0
  164. package/dist/help/docs/inspect.aliasCandidates.md +39 -0
  165. package/dist/help/docs/inspect.code.md +1 -7
  166. package/dist/help/docs/inspect.file.md +10 -19
  167. package/dist/help/docs/inspect.graph.md +3 -17
  168. package/dist/help/{dsl/docs/inspect.md → docs/inspect.shared.md} +13 -12
  169. package/dist/help/docs/modulePlan.md +24 -28
  170. package/dist/help/docs/move.md +19 -22
  171. package/dist/help/{dsl/topics/file.move.md → docs/moveToDir.md} +36 -34
  172. package/dist/help/docs/mutate.mixed.md +34 -0
  173. package/dist/help/docs/mutation.shared.md +55 -0
  174. package/dist/help/docs/patterns.md +3 -12
  175. package/dist/help/docs/qr.md +12 -6
  176. package/dist/help/docs/quick-map.md +36 -24
  177. package/dist/help/docs/recipe.file-layout.md +10 -10
  178. package/dist/help/docs/recipe.import-boundary.md +92 -0
  179. package/dist/help/docs/recipe.safe-artifact-probing.md +68 -0
  180. package/dist/help/docs/recipe.unfamiliar-area.md +64 -0
  181. package/dist/help/docs/recipes.md +20 -0
  182. package/dist/help/docs/rename.md +19 -27
  183. package/dist/help/docs/renameFile.md +36 -0
  184. package/dist/help/docs/rules.md +26 -0
  185. package/dist/help/dsl/bootstrap.bash.md +176 -341
  186. package/dist/help/dsl/bootstrap.md +175 -340
  187. package/dist/help/dsl/bootstrap.pwsh.md +176 -341
  188. package/dist/help/dsl/docs/basics.md +1 -1
  189. package/dist/help/dsl/docs/config-setup.import-normalize.md +65 -65
  190. package/dist/help/dsl/docs/config-setup.import-rules.md +6 -5
  191. package/dist/help/dsl/docs/first-setup.md +6 -5
  192. package/dist/help/dsl/docs/help-protocol.md +4 -3
  193. package/dist/help/dsl/docs/import.base.md +38 -0
  194. package/dist/help/dsl/docs/import.rebase.md +85 -0
  195. package/dist/help/dsl/docs/inspect.aliasCandidates.md +39 -0
  196. package/dist/help/dsl/docs/inspect.code.md +1 -7
  197. package/dist/help/dsl/docs/inspect.file.md +10 -19
  198. package/dist/help/dsl/docs/inspect.graph.md +3 -17
  199. package/dist/help/{docs/inspect.md → dsl/docs/inspect.shared.md} +13 -12
  200. package/dist/help/dsl/docs/modulePlan.md +24 -28
  201. package/dist/help/dsl/docs/move.md +19 -22
  202. package/dist/help/{topics/file.move.md → dsl/docs/moveToDir.md} +36 -34
  203. package/dist/help/dsl/docs/mutate.mixed.md +34 -0
  204. package/dist/help/dsl/docs/mutation.shared.md +55 -0
  205. package/dist/help/dsl/docs/patterns.md +3 -12
  206. package/dist/help/dsl/docs/qr.md +12 -6
  207. package/dist/help/dsl/docs/quick-map.md +36 -24
  208. package/dist/help/dsl/docs/recipe.file-layout.md +10 -10
  209. package/dist/help/dsl/docs/recipe.import-boundary.md +92 -0
  210. package/dist/help/dsl/docs/recipe.safe-artifact-probing.md +68 -0
  211. package/dist/help/dsl/docs/recipe.unfamiliar-area.md +64 -0
  212. package/dist/help/dsl/docs/recipes.md +20 -0
  213. package/dist/help/dsl/docs/rename.md +19 -27
  214. package/dist/help/dsl/docs/renameFile.md +36 -0
  215. package/dist/help/dsl/docs/rules.md +26 -0
  216. package/dist/help/dsl/full.md +175 -340
  217. package/dist/help/dsl/help-index.md +48 -43
  218. package/dist/help/dsl/snippets/agents.md +2 -2
  219. package/dist/help/dsl/tokens/qr.inline.examples.md +1 -1
  220. package/dist/help/dsl/topics/basics.md +1 -1
  221. package/dist/help/dsl/topics/config-setup.import-normalize.md +65 -65
  222. package/dist/help/dsl/topics/config-setup.import-rules.md +6 -5
  223. package/dist/help/dsl/topics/first-setup.md +6 -5
  224. package/dist/help/dsl/topics/help-protocol.md +4 -3
  225. package/dist/help/dsl/topics/import.base.md +36 -0
  226. package/dist/help/dsl/topics/import.rebase.md +83 -0
  227. package/dist/help/dsl/topics/inspect.aliasCandidates.md +37 -0
  228. package/dist/help/dsl/topics/inspect.code.md +1 -7
  229. package/dist/help/dsl/topics/inspect.file.md +10 -19
  230. package/dist/help/dsl/topics/inspect.graph.md +3 -17
  231. package/dist/help/dsl/topics/{inspect.md → inspect.shared.md} +13 -12
  232. package/dist/help/dsl/topics/modulePlan.md +21 -26
  233. package/dist/help/dsl/topics/move.md +17 -18
  234. package/dist/help/{docs/file.move.md → dsl/topics/moveToDir.md} +33 -35
  235. package/dist/help/dsl/topics/mutate.mixed.md +32 -0
  236. package/dist/help/dsl/topics/mutation.shared.md +53 -0
  237. package/dist/help/dsl/topics/patterns.md +3 -12
  238. package/dist/help/dsl/topics/qr.md +12 -6
  239. package/dist/help/dsl/topics/quick-map.md +36 -24
  240. package/dist/help/dsl/topics/recipe.file-layout.md +10 -10
  241. package/dist/help/dsl/topics/recipe.import-boundary.md +90 -0
  242. package/dist/help/dsl/topics/recipe.safe-artifact-probing.md +66 -0
  243. package/dist/help/dsl/topics/recipe.unfamiliar-area.md +62 -0
  244. package/dist/help/dsl/topics/recipes.md +18 -0
  245. package/dist/help/dsl/topics/rename.md +15 -15
  246. package/dist/help/dsl/topics/renameFile.md +34 -0
  247. package/dist/help/dsl/topics/rules.md +24 -0
  248. package/dist/help/full.md +175 -340
  249. package/dist/help/help-index.md +48 -43
  250. package/dist/help/help-meta.json +98 -48
  251. package/dist/help/index.md +52 -20
  252. package/dist/help/snippets/agents.md +2 -2
  253. package/dist/help/tokens/qr.inline.examples.md +1 -1
  254. package/dist/help/topics/basics.md +1 -1
  255. package/dist/help/topics/config-setup.import-normalize.md +65 -65
  256. package/dist/help/topics/config-setup.import-rules.md +6 -5
  257. package/dist/help/topics/first-setup.md +6 -5
  258. package/dist/help/topics/help-protocol.md +4 -3
  259. package/dist/help/topics/import.base.md +36 -0
  260. package/dist/help/topics/import.rebase.md +83 -0
  261. package/dist/help/topics/inspect.aliasCandidates.md +37 -0
  262. package/dist/help/topics/inspect.code.md +1 -7
  263. package/dist/help/topics/inspect.file.md +10 -19
  264. package/dist/help/topics/inspect.graph.md +3 -17
  265. package/dist/help/topics/{inspect.md → inspect.shared.md} +13 -12
  266. package/dist/help/topics/modulePlan.md +21 -26
  267. package/dist/help/topics/move.md +17 -18
  268. package/dist/help/{dsl/docs/file.move.md → topics/moveToDir.md} +33 -35
  269. package/dist/help/topics/mutate.mixed.md +32 -0
  270. package/dist/help/topics/mutation.shared.md +53 -0
  271. package/dist/help/topics/patterns.md +3 -12
  272. package/dist/help/topics/qr.md +12 -6
  273. package/dist/help/topics/quick-map.md +36 -24
  274. package/dist/help/topics/recipe.file-layout.md +10 -10
  275. package/dist/help/topics/recipe.import-boundary.md +90 -0
  276. package/dist/help/topics/recipe.safe-artifact-probing.md +66 -0
  277. package/dist/help/topics/recipe.unfamiliar-area.md +62 -0
  278. package/dist/help/topics/recipes.md +18 -0
  279. package/dist/help/topics/rename.md +15 -15
  280. package/dist/help/topics/renameFile.md +34 -0
  281. package/dist/help/topics/rules.md +24 -0
  282. package/dist/host/capabilities.js +56 -1
  283. package/dist/imports/standalone-import-analysis.js +602 -0
  284. package/dist/imports/standalone-import-model.js +2 -0
  285. package/dist/imports/standalone-import-process.js +66 -0
  286. package/dist/imports/standalone-import-worker.js +27 -0
  287. package/dist/imports/standalone-ts-project.js +147 -0
  288. package/dist/inspect/inspect-duplicates-service.js +526 -0
  289. package/dist/inspect/inspect-reverse-module-closure.js +338 -0
  290. package/dist/inspect/inspect-source-ranges.js +82 -0
  291. package/dist/inspect/inspect-source-shape.js +649 -0
  292. package/dist/inspect/standalone-inspect-analysis.js +319 -0
  293. package/dist/inspect/standalone-inspect-model.js +9 -0
  294. package/dist/inspect/standalone-inspect-process.js +55 -0
  295. package/dist/inspect/standalone-inspect-usages.js +274 -0
  296. package/dist/inspect/standalone-inspect-worker.js +13 -0
  297. package/dist/metrics/central-metrics.js +101 -2
  298. package/dist/mutation/concrete-edit-plan.js +157 -0
  299. package/dist/mutation/exports-star-collapse-preview.js +361 -0
  300. package/dist/mutation/exports-star-expand-apply.js +373 -0
  301. package/dist/mutation/exports-star-expand-preview.js +807 -0
  302. package/dist/mutation/file-impact-scan.js +182 -0
  303. package/dist/mutation/file-mutation-discovery.js +674 -0
  304. package/dist/mutation/file-mutation-eta.js +99 -0
  305. package/dist/mutation/file-mutation-standalone-apply.js +584 -0
  306. package/dist/mutation/file-mutation-standalone-planner.js +500 -0
  307. package/dist/mutation/file-mutation-tsserver-session.js +473 -0
  308. package/dist/mutation/mutation-estimate.js +45 -0
  309. package/dist/mutation/mutation-plan.js +467 -0
  310. package/dist/mutation/object-mutation-foundation.js +2 -0
  311. package/dist/mutation/object-mutation-partition.js +148 -0
  312. package/dist/mutation/object-pack-semantic-apply.js +507 -0
  313. package/dist/mutation/object-pack-semantic-preview.js +984 -0
  314. package/dist/mutation/object-unpack-semantic-preview.js +993 -0
  315. package/dist/mutation/package-manifest-impact.js +176 -0
  316. package/dist/mutation/rename-owner-worker-child.js +37 -0
  317. package/dist/mutation/rename-owner-worker.js +122 -0
  318. package/dist/mutation/runtime-cycle-query.js +66 -0
  319. package/dist/mutation/semantic-execution-progress.js +63 -0
  320. package/dist/mutation/semantic-export-index.js +474 -0
  321. package/dist/mutation/semantic-impact-scan.js +434 -0
  322. package/dist/mutation/semantic-model.js +2 -0
  323. package/dist/mutation/semantic-move-best-effort-planner.js +209 -0
  324. package/dist/mutation/semantic-move-config-worker-child.js +61 -0
  325. package/dist/mutation/semantic-move-config-worker.js +449 -0
  326. package/dist/mutation/semantic-move-declarations.js +94 -0
  327. package/dist/mutation/semantic-move-metrics.js +119 -0
  328. package/dist/mutation/semantic-move-model.js +2 -0
  329. package/dist/mutation/semantic-move-owner-authority.js +122 -0
  330. package/dist/mutation/semantic-move-owner-candidates.js +300 -0
  331. package/dist/mutation/semantic-move-owner-divergence-harness.js +474 -0
  332. package/dist/mutation/semantic-move-owner-divergence-runner.js +162 -0
  333. package/dist/mutation/semantic-move-plan-hash.js +56 -0
  334. package/dist/mutation/semantic-move-policy.js +360 -0
  335. package/dist/mutation/semantic-move-process.js +218 -0
  336. package/dist/mutation/semantic-move-provider-diagnostics.js +27 -0
  337. package/dist/mutation/semantic-move-standalone-engine.js +919 -0
  338. package/dist/mutation/semantic-move-standalone-planner.js +1553 -0
  339. package/dist/mutation/semantic-move-transaction.js +639 -0
  340. package/dist/mutation/semantic-mutation-engine.js +478 -0
  341. package/dist/mutation/semantic-mutation-runtime.js +521 -0
  342. package/dist/mutation/semantic-planner-retry.js +26 -0
  343. package/dist/mutation/semantic-program-roots.js +69 -0
  344. package/dist/mutation/semantic-rename-commonjs.js +229 -0
  345. package/dist/mutation/semantic-rename-config-worker-child.js +46 -0
  346. package/dist/mutation/semantic-rename-config-worker.js +498 -0
  347. package/dist/mutation/semantic-rename-locations.js +192 -0
  348. package/dist/mutation/semantic-rename-model.js +2 -0
  349. package/dist/mutation/semantic-rename-process.js +210 -0
  350. package/dist/mutation/semantic-rename-standalone-engine.js +302 -0
  351. package/dist/mutation/semantic-rename-standalone-planner.js +567 -0
  352. package/dist/mutation/semantic-rename-transaction.js +333 -0
  353. package/dist/mutation/semantic-unused-import-cleanup.js +248 -0
  354. package/dist/mutation/semantic-worker-retry.js +40 -0
  355. package/dist/mutation/semantic-workspace.js +804 -0
  356. package/dist/mutation/targeted-import-canonicalizer.js +359 -0
  357. package/dist/observability/config.js +206 -1
  358. package/dist/observability/context.js +59 -1
  359. package/dist/observability/failure-snapshot.js +124 -2
  360. package/dist/observability/recent.js +63 -2
  361. package/dist/payloads/read-stdin-json.js +212 -1
  362. package/dist/rg-wrapper/core.js +714 -6
  363. package/dist/rg-wrapper/options.js +125 -1
  364. package/dist/rtk-wrapper/core.js +144 -2
  365. package/dist/rtk-wrapper/git-safety.js +203 -0
  366. package/dist/rtk-wrapper/output-adapter.js +106 -0
  367. package/dist/runtime/buffered-process.js +114 -0
  368. package/dist/runtime/bundled-node.js +97 -1
  369. package/dist/runtime/command-lifecycle.js +2 -0
  370. package/dist/runtime/input-source.js +238 -1
  371. package/dist/runtime/node-cli-identity.js +37 -0
  372. package/dist/runtime/run-command.js +191 -1
  373. package/dist/selectors/parse-entities.js +84 -1
  374. package/dist/semantic/semantic-context-pool.js +830 -0
  375. package/dist/semantic/semantic-context-provider.js +416 -0
  376. package/dist/semantic/semantic-resident-admission.js +38 -0
  377. package/dist/semantic/semantic-worker-child.js +40 -0
  378. package/dist/semantic/semantic-worker-manager.js +460 -0
  379. package/dist/semantic/semantic-worker-protocol.js +2 -0
  380. package/dist/semantic/semantic-worker-runtime.js +38 -0
  381. package/dist/semantic/workspace-semantic-context-pools.js +136 -0
  382. package/dist/session/client.js +359 -1
  383. package/dist/session/daemon-state.js +185 -2
  384. package/dist/session/external-tool-coordinator.js +88 -0
  385. package/dist/session/external-tool-request.js +52 -0
  386. package/dist/session/lane-owner.js +116 -0
  387. package/dist/session/paths.js +71 -1
  388. package/dist/session/runtime-lifecycle.js +225 -0
  389. package/dist/session/runtime-shutdown.js +95 -0
  390. package/dist/session/server.js +1194 -7
  391. package/dist/session/session-health.js +27 -0
  392. package/dist/shared/agent-text.js +29 -1
  393. package/dist/shared/errors.js +496 -30
  394. package/dist/shared/event-loop.js +6 -1
  395. package/dist/shared/hints.js +37 -1
  396. package/dist/shared/metrics.js +43 -1
  397. package/dist/shared/presentation.js +69 -4
  398. package/dist/shared/stdin-examples.js +77 -1
  399. package/dist/shared/stdout.js +6 -2
  400. package/dist/shared/types.js +23 -1
  401. package/dist/tool-runtime/runtime-tools.js +120 -1
  402. package/dist/topology/availability.js +663 -0
  403. package/dist/topology/cache.js +130 -0
  404. package/dist/topology/candidates.js +372 -0
  405. package/dist/topology/core.js +903 -0
  406. package/dist/topology/dependency-snapshot.js +189 -0
  407. package/dist/topology/model.js +2 -0
  408. package/dist/topology/scope.js +100 -0
  409. package/dist/topology/ts-oracle-batch.js +529 -0
  410. package/dist/topology/ts-oracle-host.js +69 -0
  411. package/dist/topology/ts-oracle-model.js +2 -0
  412. package/dist/topology/ts-oracle.js +224 -0
  413. package/dist/topology/tsconfig-loader.js +105 -0
  414. package/dist/topology/workspace-project-index.js +542 -0
  415. package/dist/tracing/config.js +192 -2
  416. package/dist/tracing/failure-summary.js +100 -0
  417. package/dist/tracing/trace.js +318 -5
  418. package/dist/tsc-wrapper/core.js +697 -0
  419. package/dist/workers/control-plane/aib-control-plane-worker.cjs +32 -32
  420. package/dist/workers/control-plane/client-config.default.json +3 -3
  421. package/dist/workers/lexical-worker-child.js +27 -0
  422. package/dist/workers/lexical-worker-manager.js +394 -0
  423. package/dist/workers/lexical-worker-protocol.js +2 -0
  424. package/dist/workers/lexical-worker-runtime.js +25 -0
  425. package/dist/workers/owned-one-shot-process.js +115 -0
  426. package/dist/workers/product-storage.js +23 -1
  427. package/dist/workers/registry.js +241 -1
  428. package/package.json +8 -13
  429. package/scripts/postinstall.cjs +29 -29
  430. package/scripts/provision-runtime.cjs +411 -459
  431. package/dist/client/http-client.js +0 -1
  432. package/dist/client/transport-options.js +0 -1
  433. package/dist/client/websocket-client.js +0 -1
  434. package/dist/commands/entity-resolution.js +0 -1
  435. package/dist/commands/file-command.js +0 -1
  436. package/dist/commands/host-command.js +0 -1
  437. package/dist/commands/inspect-symbol-query.js +0 -1
  438. package/dist/commands/list-instances.js +0 -1
  439. package/dist/commands/module-plan-command.js +0 -1
  440. package/dist/commands/move-command.js +0 -1
  441. package/dist/commands/move-to-file.js +0 -2
  442. package/dist/commands/ping.js +0 -1
  443. package/dist/commands/refactor-command.js +0 -1
  444. package/dist/commands/rename-command.js +0 -1
  445. package/dist/commands/runtime-command.js +0 -4
  446. package/dist/commands/runtime-info.js +0 -1
  447. package/dist/commands/validate-module-plan.js +0 -2
  448. package/dist/compatibility/policy.js +0 -1
  449. package/dist/config/auto-start-ide.js +0 -1
  450. package/dist/discovery/registry.js +0 -1
  451. package/dist/discovery/select-instance.js +0 -1
  452. package/dist/help/docs/file.rename.md +0 -35
  453. package/dist/help/docs/mutation.md +0 -60
  454. package/dist/help/docs/refactor.batch.md +0 -44
  455. package/dist/help/dsl/docs/file.rename.md +0 -35
  456. package/dist/help/dsl/docs/mutation.md +0 -60
  457. package/dist/help/dsl/docs/refactor.batch.md +0 -44
  458. package/dist/help/dsl/topics/file.rename.md +0 -33
  459. package/dist/help/dsl/topics/mutation.md +0 -58
  460. package/dist/help/dsl/topics/refactor.batch.md +0 -33
  461. package/dist/help/topics/file.rename.md +0 -33
  462. package/dist/help/topics/mutation.md +0 -58
  463. package/dist/help/topics/refactor.batch.md +0 -33
  464. package/dist/ide-launch/common.cjs +0 -162
  465. package/dist/managed-host/extension-vsix-resolver.js +0 -1
  466. package/dist/managed-host/manage-serve-web-host.cjs +0 -141
  467. package/dist/managed-host/serve-web-autostart.js +0 -1
  468. package/dist/managed-host/serve-web-host.cjs +0 -2115
  469. package/dist/runtime/managed-runtime-provisioning.js +0 -1
  470. package/dist/shared/diagnostic-catalog.js +0 -1
  471. package/dist/shared/diagnostics.js +0 -1
  472. package/dist/shared/operations.js +0 -1
  473. package/dist/shared/protocol.js +0 -1
  474. package/dist/shared/routes.js +0 -1
  475. package/extension/vscode-refactor-bridge-extension.vsix +0 -0
  476. package/runtimes/launcher/linux-x64/aib +0 -0
  477. package/runtimes/launcher/win-x64/aib.exe +0 -0
@@ -1,31 +1,1836 @@
1
- "use strict";var De=exports&&exports.__createBinding||(Object.create?(function(e,t,n,s){s===void 0&&(s=n);var i=Object.getOwnPropertyDescriptor(t,n);(!i||("get"in i?!t.__esModule:i.writable||i.configurable))&&(i={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,s,i)}):(function(e,t,n,s){s===void 0&&(s=n),e[s]=t[n]})),$e=exports&&exports.__setModuleDefault||(Object.create?(function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}):function(e,t){e.default=t}),ie=exports&&exports.__importStar||(function(){var e=function(t){return e=Object.getOwnPropertyNames||function(n){var s=[];for(var i in n)Object.prototype.hasOwnProperty.call(n,i)&&(s[s.length]=i);return s},e(t)};return function(t){if(t&&t.__esModule)return t;var n={};if(t!=null)for(var s=e(t),i=0;i<s.length;i++)s[i]!=="default"&&De(n,t,s[i]);return $e(n,t),n}})();Object.defineProperty(exports,"__esModule",{value:!0}),exports.isSessionHandle=M,exports.runWithSessionOverride=Ue,exports.runSessionWorkspaceCommand=Fe,exports.resolveSessionFileArgument=B,exports.saveSessionOutputJson=qe,exports.saveSessionOutputText=et,exports.saveSessionResultJson=tt,exports.saveSessionResultViewJson=nt,exports.readSessionResultViewJson=st,exports.readSessionResultJson=it,exports.captureSessionInputJson=rt,exports.captureSessionInput=ae,exports.sessionWorkspaceExists=ot,exports.useSessionGuidance=ue,exports.readSessionBooleanPref=at,exports.readSessionNumberPref=ut,exports.readSessionStringPref=ct,exports.readEffectiveSessionPathAliases=lt,exports.readSessionPathAliasOverrides=ft,exports.tryResolveCurrentSessionId=Ut;const l=ie(require("node:fs")),c=ie(require("node:path")),xe=require("node:async_hooks"),E=require("../config/env-vars"),_=require("../config/workspace-root"),b=require("../config/path-aliases"),m=require("../shared/agent-text"),u=require("../shared/errors"),je=c.join(".tmp","aib"),U="sessionDir",Ce="session.json",we="active.json",Re="aib:",Le="s_",Pe="last",Te="_last.json",F=new xe.AsyncLocalStorage,ke=["graph","inspect","code","slice","members","exports","deps","usages","duplicates","execution","rename","move","refactor","modulePlan","imports"],We=["inspect","graph","rename","move","refactor","modulePlan","imports","generic"],O={"guidance.nextLimit":{type:"number",default:2,min:0,max:100,hidden:!0},"diagnostics.hintLimit":{type:"number",default:2,min:0,max:100,hidden:!0},"inspect.code.show":{type:"boolean",default:!0,hidden:!0},"inspect.code.maxNonEmptyLines":{type:"number",default:120,min:1,max:1e4},"inspect.code.meta":{type:"boolean",default:!0,hidden:!0},"inspect.members.maxItems":{type:"number",default:20,min:1,max:1e3},"inspect.members.all":{type:"boolean",default:!1,hidden:!0},"inspect.exports.ranges":{type:"boolean",default:!1,hidden:!0},"inspect.exports.resolveStar":{type:"boolean",default:!1,hidden:!0},"inspect.graph.hubs":{type:"boolean",default:!0},"inspect.graph.entrypoints":{type:"boolean",default:!0},"inspect.graph.leaves":{type:"boolean",default:!0},"inspect.graph.edges":{type:"boolean",default:!0},"inspect.graph.symbols":{type:"boolean",default:!1,hidden:!0},"inspect.graph.symbolUsage":{type:"boolean",default:!1},"inspect.usages.detail":{type:"string",default:"locations",values:["summary","locations","code"],hidden:!0},"inspect.usages.maxLocations":{type:"number",default:12,min:1,max:1e4},"inspect.usages.maxCodeBlocks":{type:"number",default:8,min:1,max:1e4},"inspect.usages.excludeTarget":{type:"boolean",default:!1,hidden:!0}};function M(e){return e.startsWith(Re)}function Ue(e,t){return e?F.run(e,t):t()}function Fe(e,t,n){const s=t[0]??"status",i=(0,_.resolveWorkspaceRoot)(e);if(!i){if(s==="status")return(0,m.attachAgentText)({initialized:!1,active:null,source:"none",available:[],next:"Run aib help first-setup"},["session not ready","","No aib.json was found.","","If you are a user:","ask your agent to set up AIB for this repo:","aib help first-setup","","If you are an agent:","run:","aib help first-setup","","Then follow the setup from the intended repository root."].join(`
2
- `));(0,_.resolveRequiredWorkspaceRoot)(e)}const r=i?.root??e;if(Rt(r),s==="init")return dt(r,t.slice(1));if(s==="status")return Dt(r);if(s==="list")return St(r);if(s==="use")return ht(r,t.slice(1));if(s==="where")return mt(r,t.slice(1));if(s==="read")return It(r,t.slice(1),n);if(s==="write")return Je(r,t.slice(1),n);if(s==="prefs")return Be(r,t.slice(1),n);if(s==="aliases")return Me(r,t.slice(1),n);if(s==="clear")return Ct(r);throw new u.CliError("UNKNOWN_SESSION_WORKSPACE_COMMAND",`Unknown session workspace command: ${s}`)}function Me(e,t,n){const s=t[0]??"get";if(s==="get"){const i=A(e),r=(0,b.readConfigPathAliases)(e),o=(0,b.normalizePathAliasMap)(i.pathAliases??{},"session path aliases"),a={aliases:(0,b.effectivePathAliases)(e,o),config:r,session:o};return(0,m.attachAgentText)(a,V(a))}if(s==="set"){const i=A(e),r=t.includes("--stdin")?Ve(n):ze(t.slice(1)),o=(0,b.normalizePathAliasMap)(i.pathAliases??{},"session path aliases"),a={};for(const[d,p]of Object.entries(r)){const S=(0,b.normalizePathAliasName)(d,"session path aliases");if(typeof p!="string"||p.trim()==="")throw new u.CliError("INVALID_PATH_ALIAS_TARGET",`session path alias ${d} must be a non-empty path string.`);o[S]=p.trim().replace(/\\/g,"/"),a[S]=o[S]}i.pathAliases=o,g(e,i);const f={updated:a,aliases:(0,b.effectivePathAliases)(e,o)};return(0,m.attachAgentText)(f,V(f))}if(s==="clear"){const i=A(e),r=t.slice(1).filter(d=>!d.startsWith("--")),o=(0,b.normalizePathAliasMap)(i.pathAliases??{},"session path aliases"),a=[];if(r.length===0)a.push(...Object.keys(o).sort()),delete i.pathAliases;else{for(const d of r){const p=(0,b.normalizePathAliasName)(d,"session path aliases");Object.prototype.hasOwnProperty.call(o,p)&&(a.push(p),delete o[p])}Object.keys(o).length>0?i.pathAliases=o:delete i.pathAliases}g(e,i);const f={cleared:a,aliases:(0,b.effectivePathAliases)(e,i.pathAliases??{})};return(0,m.attachAgentText)(f,V(f))}throw new u.CliError("UNKNOWN_SESSION_ALIASES_COMMAND",`Unknown session aliases command: ${s}`,{expected:"aib session aliases get | set | clear"})}function Ve(e){if(!y(e))throw new u.CliError("INVALID_SESSION_ALIASES_STDIN","session aliases set --stdin expects a JSON object.");const t=y(e.aliases)?e.aliases:e,n={};for(const[s,i]of Object.entries(t))typeof i=="string"&&(n[s]=i);return n}function ze(e){if(e.length===0||e.length%2!==0)throw new u.CliError("SESSION_ALIASES_SET_USAGE","Usage: aib session aliases set <name> <path> [<name> <path>...] or session aliases set --stdin");const t={};for(let n=0;n<e.length;n+=2)t[e[n]??""]=e[n+1]??"";return t}function V(e){if(y(e.updated))return re("aliases.updated",e.updated);if(Array.isArray(e.cleared)){const t=e.cleared.filter(n=>typeof n=="string");return t.length>0?["aliases.cleared",...t].join(`
3
- `):"aliases.cleared none"}if(y(e.aliases)){const t=re("aliases",e.aliases).split(`
4
- `);return t.length===1&&t.push("none"),t.join(`
5
- `)}return null}function re(e,t){const n=[e];for(const[s,i]of Object.entries(t).sort(([r],[o])=>r.localeCompare(o)))n.push(`@${s}/=${String(i)}`);return n.join(`
6
- `)}function Je(e,t,n){const s=t[0]??"",i=t[1]??"";if(!s||!i)throw new u.CliError("SESSION_WRITE_USAGE","Usage: aib session write <kind> <name> --stdin");if(n===void 0)throw new u.CliError("STDIN_REQUIRED","session write expects JSON on stdin and the --stdin flag.");const r=A(e),o=Z(r,s,i);x(o,n);const a=C(r,"inputs",s,i,o);Ne(r,s,n),g(e,r);const f={written:a.handle,file:h(e,o)},d=ue(e,"session.write.from",`Use with --from ${a.handle}`);return d&&(f.next=d),f}function Be(e,t,n){const s=t[0]??"get";if(s==="get"){const i=A(e),r=t.includes("--all"),o=t.slice(1).find(p=>!p.startsWith("--")),a=r?Ye(i):Ze(i.prefs??{}),f=Ke(a,o),d=r?{prefs:f}:{overrides:f,defaults:"omitted; use session prefs get --all"};return(0,m.attachAgentText)(d,z(d))}if(s==="set"){const i=A(e),r=t.includes("--stdin")?He(n):Ge(t.slice(1)),o=i.prefs??{},a={};for(const[d,p]of Object.entries(r)){const S=oe(d),N=Qe(S,p);o[S]=N,a[S]=N}i.prefs=o,g(e,i);const f={updated:a};return(0,m.attachAgentText)(f,z(f))}if(s==="clear"){const i=A(e),r=t.slice(1).filter(d=>!d.startsWith("--")),o=i.prefs??{},a=[];if(r.length===0)a.push(...Object.keys(o).sort()),delete i.prefs;else{for(const d of r){const p=oe(d);Object.prototype.hasOwnProperty.call(o,p)&&(a.push(p),delete o[p])}Object.keys(o).length>0?i.prefs=o:delete i.prefs}g(e,i);const f={cleared:a};return(0,m.attachAgentText)(f,z(f))}throw new u.CliError("UNKNOWN_SESSION_PREFS_COMMAND",`Unknown session prefs command: ${s}`,{expected:"aib session prefs get | set | clear"})}function Ke(e,t){if(!t)return e;const n={};for(const[s,i]of Object.entries(e))(s===t||s.startsWith(`${t}.`))&&(n[s]=i);return n}function z(e){if(y(e.updated))return J("prefs.updated",e.updated);if(Array.isArray(e.cleared)){const t=e.cleared.filter(n=>typeof n=="string");return t.length>0?["prefs.cleared",...t].join(`
7
- `):"prefs.cleared none"}if(y(e.overrides)){const t=J("prefs",e.overrides).split(`
8
- `);return t.length===1&&t.push("no overrides"),typeof e.defaults=="string"&&t.push(e.defaults),t.join(`
9
- `)}return y(e.prefs)?J("prefs",e.prefs):null}function J(e,t){const n=[e];for(const[s,i]of Object.entries(t).sort(([r],[o])=>r.localeCompare(o)))n.push(`${s}=${String(i)}`);return n.join(`
10
- `)}function He(e){if(!y(e))throw new u.CliError("INVALID_SESSION_PREFS_STDIN","session prefs set --stdin expects a JSON object.");const t=y(e.prefs)?e.prefs:e,n={};for(const[s,i]of Object.entries(t))n[s]=i;return n}function Ge(e){if(e.length===0||e.length%2!==0)throw new u.CliError("SESSION_PREFS_SET_USAGE","Usage: aib session prefs set <key> <value> [<key> <value>...] or session prefs set --stdin");const t={};for(let n=0;n<e.length;n+=2){const s=e[n]??"",i=e[n+1]??"";t[s]=i}return t}function oe(e){if(Object.prototype.hasOwnProperty.call(O,e))return e;throw new u.CliError("UNKNOWN_SESSION_PREF",`Unknown session preference: ${e}`,{available:Object.keys(O)})}function Qe(e,t){const n=O[e];if(n.type==="boolean"){if(typeof t=="boolean")return t;if(typeof t=="string"){const i=t.trim().toLowerCase();if(i==="true")return!0;if(i==="false")return!1}throw new u.CliError("INVALID_SESSION_PREF_VALUE",`${e} expects true or false.`)}if(n.type==="string"){if(typeof t!="string")throw new u.CliError("INVALID_SESSION_PREF_VALUE",`${e} expects one of: ${n.values.join(", ")}.`);const i=t.trim();if(!n.values.includes(i))throw new u.CliError("INVALID_SESSION_PREF_VALUE",`${e} expects one of: ${n.values.join(", ")}.`);return i}const s=typeof t=="number"?t:typeof t=="string"?Number(t):NaN;if(!Number.isInteger(s)||s<n.min||s>n.max)throw new u.CliError("INVALID_SESSION_PREF_VALUE",`${e} expects an integer from ${n.min} to ${n.max}.`);return s}function Ye(e){const t={};for(const n of Object.keys(O)){const s=O[n];"hidden"in s&&s.hidden||(s.type==="boolean"?t[n]=ce(e,n,s.default):s.type==="number"?t[n]=K(e,n,s.default):t[n]=le(e,n,s.default))}return t}function Ze(e){const t={};for(const[n,s]of Object.entries(e))Xe(n)||(t[n]=s);return t}function Xe(e){if(!Object.prototype.hasOwnProperty.call(O,e))return!1;const t=O[e];return"hidden"in t&&t.hidden===!0}function B(e,t){if(!M(t))return t;const n=A(e),s=Oe(t),i=s.scope==="input"?n.inputs:n.outputs,r=s.scope==="input"?s.kind:s.scope,o=i[r],a=s.name==="last"?o?.last:s.name,f=a?o?.items[a]:void 0;if(!f)throw new u.CliError("SESSION_HANDLE_NOT_FOUND",`Session handle not found: ${t}`,{handle:t,sessionDir:h(e,n.rootDir)});return f.file}function qe(e,t,n,s){const i=A(e),r=Ae(i,t,n,".json");l.mkdirSync(c.dirname(r),{recursive:!0}),l.writeFileSync(r,`${JSON.stringify(s,null,2)}
11
- `);const o=C(i,"outputs",t,n,r);return g(e,i),{saved:o.handle,last:`aib:${t}:last`,file:h(e,r)}}function et(e,t,n,s,i=".txt"){const r=A(e),o=Ae(r,t,n,i);l.mkdirSync(c.dirname(o),{recursive:!0}),l.writeFileSync(o,s);const a=C(r,"outputs",t,n,o);return g(e,r),{saved:a.handle,last:`aib:${t}:last`,file:h(e,o)}}function tt(e,t,n,s){const i=v(e);if(!i)return null;const r=I(t),o=I(n),a=c.join(i.rootDir,"outputs","result",r,`${o}.json`);return x(a,s),{saved:`aib:result:${r}:${o}`,file:h(e,a)}}function nt(e,t,n){const s=v(e);if(!s)return null;const i=I(t),r=c.join(s.rootDir,"outputs","result",`${i}.json`);return x(r,n),{saved:`aib:${i}`,file:h(e,r)}}function st(e,t){const n=A(e),s=I(t),i=c.join(n.rootDir,"outputs","result",`${s}.json`);if(!l.existsSync(i))throw new u.CliError("SESSION_RESULT_NOT_FOUND",`Result handle not found: aib:${s}`,{handle:`aib:${s}`,sessionDir:h(e,n.rootDir)});const r=JSON.parse(l.readFileSync(i,"utf8"));if(!r||typeof r!="object"||Array.isArray(r))throw new u.CliError("INVALID_SESSION_RESULT",`Result artifact is not a JSON object: aib:${s}`);return r}function it(e,t,n){const s=A(e),i=I(t),r=I(n),o=c.join(s.rootDir,"outputs","result",i,`${r}.json`);if(!l.existsSync(o))throw new u.CliError("SESSION_RESULT_NOT_FOUND",`Result handle not found: aib:result:${i}:${r}`,{handle:`aib:result:${i}:${r}`,sessionDir:h(e,s.rootDir)});const a=JSON.parse(l.readFileSync(o,"utf8"));if(!a||typeof a!="object"||Array.isArray(a))throw new u.CliError("INVALID_SESSION_RESULT",`Result artifact is not a JSON object: aib:result:${i}:${r}`);return a}function rt(e,t,n,s){return ae(e,t,n,s,{format:"json",text:JSON.stringify(s,null,2)})}function ae(e,t,n,s,i){const r=v(e);if(!r)return null;const o=i??{format:"json",text:JSON.stringify(s,null,2)},a=o.format==="dsl"?Z(r,t,n,".dsl"):Z(r,t,n,".json");o.format==="dsl"?(_e(a,o.text),x(Ft(r,t,n),s)):x(a,s);const f=C(r,"inputs",t,n,a);return Ne(r,t,s,o),g(e,r),{handle:f.handle,file:h(e,a)}}function ot(e){return l.existsSync(L(e))}function ue(e,t,n,s=-1){const i=v(e);if(!i)return n;const r=s>=0?s:K(i,"guidance.nextLimit",2),o=i.guidance??{},a=o[t]??{shown:0,limit:r};if(a.limit=r,a.shown>=a.limit){o[t]=a,i.guidance=o,g(e,i);return}return a.shown+=1,o[t]=a,i.guidance=o,g(e,i),n}function at(e,t,n){const s=v(e),i=O[t],r=typeof n=="boolean"?n:i.type==="boolean"?i.default:!1;return s?ce(s,t,r):r}function ut(e,t,n){const s=v(e),i=O[t],r=typeof n=="number"?n:i.type==="number"?i.default:0,o=(0,_.readWorkspaceNumberConfig)(e,t,r);return s?K(s,t,o):o}function ct(e,t,n){const s=v(e),i=O[t],r=typeof n=="string"?n:i.type==="string"?i.default:"";return s?le(s,t,r):r}function lt(e){try{const t=v(e);return(0,b.effectivePathAliases)(e,t?.pathAliases??{})}catch(t){if(t instanceof u.CliError&&t.code==="MULTIPLE_AIB_SESSIONS")return(0,b.effectivePathAliases)(e,{});throw t}}function ft(e){try{const t=v(e);return(0,b.normalizePathAliasMap)(t?.pathAliases??{},"session path aliases")}catch(t){if(t instanceof u.CliError&&t.code==="MULTIPLE_AIB_SESSIONS")return{};throw t}}function ce(e,t,n){const s=e.prefs?.[t];return typeof s=="boolean"?s:n}function K(e,t,n){const s=e.prefs?.[t];return typeof s=="number"&&Number.isFinite(s)?s:n}function le(e,t,n){const s=e.prefs?.[t];return typeof s=="string"?s:n}function dt(e,t){const n=w(t,"--dir"),s=Q(e,n,!0),i=w(t,"--name"),r=$(i??Y()??Jt()),o=c.join(s.rootDir,r),a=new Date().toISOString(),d=R(e,r)??{version:1,sessionId:r,cwd:c.resolve(e),rootDir:o,createdAt:a,updatedAt:a,outputs:{},inputs:{},guidance:{}};d.sessionId=r,d.rootDir=o,d.updatedAt=a,me(d),g(e,d),be(e,d,!0);const p=D(e),S=p?Object.keys(p.sessions).length:1,N={session:r,dir:h(e,d.rootDir),sessionDir:h(e,s.rootDir),sessionDirSource:s.source,sessionCount:S,bind:`${E.CLI_ENV.session}=${r}`,next:S===1?"Run AIB commands without -s for now. AIB will tell you if multiple sessions exist.":`Use aib -s ${r} <command> or set ${E.CLI_ENV.session}=${r}.`};return s.ignoredRequestedDir&&(N.note=`${U} from aib.json is in effect; --dir was ignored.`,N.requestedDir=s.ignoredRequestedDir),(0,m.attachAgentText)(N,pt(N))}function pt(e){const t=String(e.session??""),n=typeof e.sessionCount=="number"?e.sessionCount:1,s=[`session ready: ${t}`,""];return typeof e.note=="string"&&e.note&&(s.push("aib.json sessionDir is in effect; --dir was ignored."),s.push("")),n===1?(s.push("Only one AIB session exists in this repo."),s.push("You can run AIB commands without -s for now."),s.push("AIB will tell you if multiple sessions exist and you need to choose one.")):(s.push("Multiple AIB sessions exist in this repo."),s.push("Use this session explicitly:"),s.push(`aib -s ${t} <command>`),s.push(""),s.push("Or bind it in this shell:"),s.push(`${E.CLI_ENV.session}=${t}`)),s.join(`
12
- `)}function St(e){const t=D(e),n=k(e);return{active:n.sessionId??t?.activeSessionId??null,source:n.source,sessions:t?Object.values(t.sessions).sort((s,i)=>s.sessionId.localeCompare(i.sessionId)).map(s=>`${s.sessionId} -> ${h(e,s.rootDir)}`):[]}}function ht(e,t){const n=t[0]??"";if(!n)throw new u.CliError("SESSION_USE_ID_REQUIRED","Usage: aib session use <sessionId>");const s=$(n),i=D(e),r=i?.sessions[s];if(!r)throw new u.CliError("SESSION_NOT_FOUND",`Session not found: ${s}`,{available:i?Object.keys(i.sessions).sort():[]});return T(e,{...i??ge(e),activeSessionId:s}),{session:s,dir:h(e,r.rootDir),bind:`${E.CLI_ENV.session}=${s}`,next:`Use aib -s ${s} <command> or set ${E.CLI_ENV.session}=${s}.`}}function mt(e,t){const n=t[0]??"";if(!n)throw new u.CliError("SESSION_WHERE_HANDLE_REQUIRED","Usage: aib session where <handle>");const s=B(e,n),i={handle:n,file:h(e,s)};return(0,m.attachAgentText)(i,[n,i.file].join(`
13
- `))}function It(e,t,n){if(t.includes("--stdin")){if(!y(n))throw new u.CliError("INVALID_SESSION_READ_STDIN","session read --stdin expects a JSON object payload.");const r=yt(n);if(r.length===1){const a=H(e,r[0]);return(0,m.attachAgentText)(a,G(a))}const o={reads:r.map(a=>gt(e,a))};return(0,m.attachAgentText)(o,G(o))}const s=t[0]??"";if(!s)throw new u.CliError("SESSION_READ_HANDLE_REQUIRED","Usage: aib session read <handle> [--head <n> | --offset <n> --limit <n>]");const i=H(e,{handle:s,...vt(t.slice(1))});return(0,m.attachAgentText)(i,G(i))}function yt(e){if(Array.isArray(e.reads))return e.reads.map((t,n)=>{if(typeof t=="string"){if(!M(t))throw new u.CliError("INVALID_SESSION_READ_ROW",`session read row at index ${n} must be an aib: handle string or an object.`);return{handle:t}}if(!y(t))throw new u.CliError("INVALID_SESSION_READ_ROW",`session read row at index ${n} must be an aib: handle string or an object.`);return fe(t,n)});if(typeof e.handle=="string"||typeof e.read=="string")return[fe(e,0)];throw new u.CliError("INVALID_SESSION_READ_STDIN","Expected { reads: [{ handle }] } or { handle }.")}function fe(e,t){const n=X(e.handle)??X(e.read);if(!n)throw new u.CliError("SESSION_READ_HANDLE_REQUIRED",`session read row at index ${t} requires handle.`);return{handle:n,...e.rawInput===!0?{rawInput:!0}:{},...pe(e,t)}}function gt(e,t){try{return H(e,t)}catch(n){if(n instanceof u.CliError){const s=y(n.details)?n.details:{};return{read:t.handle,error:n.code,...typeof s.next=="string"?{next:s.next}:{}}}return{read:t.handle,error:"UNEXPECTED_ERROR"}}}function H(e,t){Ot(t);const n=Oe(t.handle),s=B(e,t.handle);if(n.scope==="input"&&!t.rawInput){const r=Nt(n.kind,t.handle);return{read:t.handle,file:h(e,s),next:r?`Edit file, then rerun: ${r}`:"Edit file, then rerun the command with --from <handle>."}}if(n.scope==="graph"||n.scope==="usages"){const r=n.scope==="graph"?`aib inspect graph --from-file ${t.handle} --focus <file>`:`aib inspect usages --from-file ${t.handle} --focus <name>`;throw new u.CliError("SESSION_ARTIFACT_NOT_READABLE",`${n.scope} artifacts are reusable indexes, not agent-readable context.`,{handle:t.handle,kind:n.scope,next:r})}if(n.scope==="duplicates"){const r=l.readFileSync(s,"utf8");return{read:t.handle,content:bt(e,t.handle,s,r,t)}}const i=l.readFileSync(s,"utf8");return{read:t.handle,content:At(s,i,t)}}function bt(e,t,n,s,i){const r=Et(e,t,n,s);return i.head!==void 0||i.offset!==void 0||i.limit!==void 0?Se(r,i):r}function Et(e,t,n,s){let i;try{i=JSON.parse(s)}catch{return de(t,n,s)}if(!y(i))return de(t,n,s);const r=[],o=Array.isArray(i.targetPaths)?i.targetPaths.filter(S=>typeof S=="string"&&S!==""):[],a=o.length===1?h(e,o[0]):o.length>1?`${o.length} scopes`:"";r.push(a?`duplicates ${a}`:"duplicates");const f=typeof i.summary=="string"?i.summary:`${j(i.itemCount)} ${te(j(i.itemCount),"name")}`;r.push(f);const d=Array.isArray(i.items)?i.items.filter(y):[];for(const S of d){const N=typeof S.name=="string"?S.name:"",ve=j(S.declarationCount),ne=j(S.variantCount),se=j(S.exactCopyCount);N&&r.push(`${N} x${ve}, ${ne} ${te(ne,"variant")}${se>0?`, exact x${se}`:""}`)}const p=j(i.hiddenItemCount);return p>0&&r.push(`+ ${p} ${te(p,"name")}`),r.push(`raw: aib session where ${t}`),r.join(`
14
- `)}function de(e,t,n){return[`saved artifact ${e}`,`${n.length} bytes`,`raw: ${t}`].join(`
15
- `)}function At(e,t,n){if(n.head!==void 0||n.offset!==void 0||n.limit!==void 0)return Se(t,n);if(c.extname(e).toLowerCase()!==".json")return t;try{return JSON.parse(t)}catch{return t}}function G(e){const t=Array.isArray(e.reads)?e.reads.filter(y):[e];if(t.length===0)return null;const n=[],s=t.length>1;for(const i of t){const r=typeof i.read=="string"?i.read:"",o=i.content,a=_t(o);if(a!==null){s&&r&&n.push(`// ${r}`),n.push(a.trimEnd());continue}if(typeof i.file=="string"){s&&r?n.push(`// ${r}`):r&&n.push(`input ${r}`),n.push(`file: ${i.file}`),typeof i.next=="string"&&n.push(`next: ${i.next}`);continue}const f=typeof i.error=="string"?i.error:"";if(f){s&&r&&n.push(`// ${r}`),n.push(`error: ${f}`),typeof i.next=="string"&&n.push(`next: ${i.next}`);continue}return null}return n.join(`
16
- `)}function _t(e){return typeof e=="string"?e:e===void 0?null:JSON.stringify(e,null,2)}function Nt(e,t){return e==="inspect"?`aib inspect --from ${t}`:e==="graph"?`aib inspect graph --from ${t}`:e==="rename"?`aib rename preview --from ${t}`:e==="move"?`aib move toFile preview --from ${t}`:e==="refactor"?`aib refactor batch preview --from ${t}`:e==="modulePlan"?`aib modulePlan preview --from ${t}`:e==="imports"?`aib imports normalize preview --from ${t}`:null}function Ot(e){if(e.head!==void 0&&(e.offset!==void 0||e.limit!==void 0))throw new u.CliError("SESSION_READ_RANGE_CONFLICT","Use either head or offset/limit, not both.")}function vt(e){const t={},n=w(e,"--head"),s=w(e,"--offset"),i=w(e,"--limit");return n!==void 0&&(t.head=n),s!==void 0&&(t.offset=s),i!==void 0&&(t.limit=i),{...e.includes("--raw-input")?{rawInput:!0}:{},...pe(t,0)}}function pe(e,t){const n=q(e.head,`session read row at index ${t} has invalid head.`),s=q(e.offset,`session read row at index ${t} has invalid offset.`),i=zt(e.limit,`session read row at index ${t} has invalid limit.`);return{...n!==void 0?{head:n}:{},...s!==void 0?{offset:s}:{},...i!==void 0?{limit:i}:{}}}function Se(e,t){if(t.head===void 0&&t.offset===void 0&&t.limit===void 0)return e;const n=e.split(/\r?\n/),s=t.head!==void 0?0:t.offset??0,i=t.head!==void 0?t.head:t.limit!==void 0?s+t.limit:void 0;return n.slice(s,i).join(`
17
- `)}function Dt(e){const t=D(e),n=k(e),s=t?Object.keys(t.sessions).sort():[];if(n.source==="ambiguous")return(0,m.attachAgentText)({ok:!1,code:"MULTIPLE_AIB_SESSIONS",error:"Multiple AIB sessions exist. Select one explicitly.",available:s,next:`Use aib -s <session> <command> or set ${E.CLI_ENV.session}=<session>.`},jt(s));const i=n.sessionId?R(e,n.sessionId):null;if(!i){const o={initialized:!1,active:n.sessionId??null,source:n.source,available:s,next:n.sessionId?`Run aib session init --name ${n.sessionId}`:"Run aib session init --name <name>"};return(0,m.attachAgentText)(o,$t(o))}g(e,i);const r={initialized:!0,session:i.sessionId??n.sessionId,active:i.sessionId??n.sessionId,source:n.source,available:s,sessionDir:h(e,i.rootDir),aliases:(0,b.effectivePathAliases)(e,i.pathAliases??{}),latest:Mt(i),dirs:Vt(e,i)};return(0,m.attachAgentText)(r,xt(r))}function $t(e){const t=typeof e.active=="string"&&e.active?e.active:null;return t?["session not ready","",`Session ${t} was not found.`,"Create it:",`aib session init --name ${t}`].join(`
18
- `):["session not ready","","No AIB sessions exist in this repo.","Create one:","aib session init --name <name>"].join(`
19
- `)}function xt(e){const t=String(e.session??""),n=e.aliases&&typeof e.aliases=="object"&&!Array.isArray(e.aliases)?e.aliases:{},s=[`session: ${t}`],i=Object.entries(n).filter(([,r])=>typeof r=="string"&&r.trim()!=="").sort(([r],[o])=>r.localeCompare(o)).map(([r,o])=>`@${r} -> ${String(o)}`);return i.length>0&&s.push("","aliases:",...i),e.source==="single"&&s.push("","Only one AIB session exists in this repo.","You can run AIB commands without -s."),s.join(`
20
- `)}function jt(e){return["multiple AIB sessions","","available:",...e,"","Choose one:","aib -s <session> <command>","","Or bind it in this shell:",`${E.CLI_ENV.session}=<session>`,"","If none of these sessions is yours, create a new one:","aib session init --name <name>"].join(`
21
- `)}function Ct(e){const t=k(e),n=D(e),s=n?Object.keys(n.sessions).sort():[];if(t.source==="ambiguous")return(0,m.attachAgentText)({ok:!1,code:"MULTIPLE_AIB_SESSIONS",error:"Multiple AIB sessions exist. Select one explicitly.",available:s,next:"Use aib -s <session> session clear."},wt(s));const i=t.sessionId?R(e,t.sessionId):null;if(!i)return(0,m.attachAgentText)({cleared:!1,reason:"session-not-initialized"},["No AIB sessions exist in this repo.","","Create one:","aib session init --name <name>"].join(`
22
- `));he(i,{touch:!0}),g(e,i);const r=i.sessionId??t.sessionId??"";return(0,m.attachAgentText)({cleared:!0,session:r,dir:h(e,i.rootDir)},[`session cleared: ${r}`,"","Inputs and outputs were pruned.","You can keep using this session."].join(`
23
- `))}function he(e,t){l.rmSync(c.join(e.rootDir,"inputs"),{recursive:!0,force:!0}),l.rmSync(c.join(e.rootDir,"outputs"),{recursive:!0,force:!0}),e.inputs={},e.outputs={},e.guidance={},t.touch&&(e.updatedAt=new Date().toISOString()),me(e)}function wt(e){return["multiple AIB sessions","","available:",...e,"","Clear one explicitly only if it is yours:","aib -s <session> session clear","","If none of these sessions is yours, create a new one:","aib session init --name <name>"].join(`
24
- `)}function Rt(e){const t=Lt(e),n=D(e);if(!n)return;const s=Date.now();let i=!1;for(const[r,o]of Object.entries(n.sessions)){const a=P(o.rootDir);if(!l.existsSync(a)){delete n.sessions[r],i=!0,n.activeSessionId===r&&delete n.activeSessionId;continue}const f=Date.parse(o.updatedAt);if(!Number.isFinite(f))continue;const d=s-f;if(t.autoDelete&&t.ttlDeleteMs>0&&d>t.ttlDeleteMs){l.rmSync(o.rootDir,{recursive:!0,force:!0}),delete n.sessions[r],i=!0,n.activeSessionId===r&&delete n.activeSessionId;continue}if(t.autoClean&&t.ttlCleanMs>0&&d>t.ttlCleanMs){const p=Ie(e,o.rootDir,r);p&&(he(p,{touch:!1}),Pt(p))}}if(i){if(!n.activeSessionId){const r=Object.keys(n.sessions).sort()[0];r&&(n.activeSessionId=r)}T(e,n)}}function Lt(e){const t=(0,_.readWorkspaceNumberConfig)(e,"session.ttlMinutes",60),n=(0,_.readWorkspaceNumberConfig)(e,"session.ttlDeleteMinutes",t),s=(0,_.readWorkspaceNumberConfig)(e,"session.ttlCleanMinutes",t);return{autoDelete:(0,_.readWorkspaceBooleanConfig)(e,"session.autoDelete",!0),ttlDeleteMs:n>0?n*6e4:0,autoClean:(0,_.readWorkspaceBooleanConfig)(e,"session.autoClean",!0),ttlCleanMs:s>0?s*6e4:0}}function me(e){for(const t of ke)l.mkdirSync(c.join(e.rootDir,"outputs",t),{recursive:!0});for(const t of We)l.mkdirSync(c.join(e.rootDir,"inputs",t),{recursive:!0})}function R(e,t){const s=D(e)?.sessions[t];return s?Ie(e,s.rootDir,t):null}function v(e){const t=Ee(e);return t.sessionId?R(e,t.sessionId):null}function Ie(e,t,n){try{const s=JSON.parse(l.readFileSync(P(t),"utf8"));if(!s||typeof s!="object"||Array.isArray(s))return null;const i=s;return i.version!==1||typeof i.rootDir!="string"?null:(i.sessionId=i.sessionId??n,i)}catch{return null}}function A(e){const t=v(e);if(!t)throw new u.CliError("SESSION_WORKSPACE_NOT_INITIALIZED","Session workspace is not initialized.",{session:Y()??null,next:"Run aib session init --name <name>",help:"aib help session"});return g(e,t),t}function g(e,t){t.updatedAt=new Date().toISOString(),l.mkdirSync(t.rootDir,{recursive:!0}),l.writeFileSync(P(t.rootDir),`${JSON.stringify(t,null,2)}
25
- `),be(e,t,!1)}function Pt(e){l.mkdirSync(e.rootDir,{recursive:!0}),l.writeFileSync(P(e.rootDir),`${JSON.stringify(e,null,2)}
26
- `)}function Q(e,t,n=!1){const s=(0,_.resolveWorkspaceRoot)(e),i=s?.root??e,r=s?X(s.config[U]):void 0;if(r)return{rootDir:ye(i,r),source:"aib.json",...t?{ignoredRequestedDir:t}:{}};const a=ye(i,t??je);return n&&s&&(0,_.updateWorkspaceConfig)(i,{[U]:Tt(i,a)}),{rootDir:a,source:t?"request":"default"}}function ye(e,t){const n=c.resolve(e,t);return c.basename(n).toLowerCase()==="aib"?n:c.join(n,"aib")}function Tt(e,t){const n=c.relative(e,t);return n&&!n.startsWith("..")&&!c.isAbsolute(n)?n.replace(/\\/g,"/"):t.replace(/\\/g,"/")}function L(e){return c.join(Q(e).rootDir,Ce)}function kt(e){return c.join(Q(e).rootDir,we)}function P(e){return c.join(e,"session.json")}function D(e){try{const t=JSON.parse(l.readFileSync(L(e),"utf8"));if(!t||typeof t!="object"||Array.isArray(t))return null;const n=t;return n.version!==1||!n.sessions||typeof n.sessions!="object"?null:{version:1,cwd:typeof n.cwd=="string"?n.cwd:c.resolve(e),...typeof n.activeSessionId=="string"?{activeSessionId:n.activeSessionId}:{},sessions:n.sessions}}catch{return null}}function T(e,t){t.cwd=c.resolve((0,_.resolveWorkspaceRoot)(e)?.root??e),l.mkdirSync(c.dirname(L(e)),{recursive:!0}),l.writeFileSync(L(e),`${JSON.stringify(t,null,2)}
27
- `),Wt(e,t.activeSessionId)}function ge(e){return{version:1,cwd:c.resolve(e),sessions:{}}}function Wt(e,t){const n=kt(e);if(l.mkdirSync(c.dirname(n),{recursive:!0}),!t){l.rmSync(n,{force:!0});return}l.writeFileSync(n,`${JSON.stringify({sessionId:t,updatedAt:new Date().toISOString()},null,2)}
28
- `)}function be(e,t,n){const s=t.sessionId??Y()??"";if(!s)return;const i=D(e)??ge(e);i.sessions[s]={sessionId:s,rootDir:t.rootDir,createdAt:i.sessions[s]?.createdAt??t.createdAt,updatedAt:t.updatedAt},(n||!i.activeSessionId)&&(i.activeSessionId=s),T(e,i)}function Bt(e,t){const n=D(e);if(!(!n||!t)){if(delete n.sessions[t],n.activeSessionId===t){const s=Object.keys(n.sessions).sort()[0];s?n.activeSessionId=s:delete n.activeSessionId}T(e,n)}}function Ee(e){const t=F.getStore();if(t)return{sessionId:$(t),source:"override"};const n=process.env[E.CLI_ENV.session];if(n&&n.trim())return{sessionId:$(n),source:"env"};const s=process.env[E.CLI_ENV.legacySession];if(s&&s.trim())return{sessionId:$(s),source:"legacy-env"};const i=D(e),r=i?Object.keys(i.sessions).sort():[];if(r.length===1)return{sessionId:r[0],source:"single"};if(r.length>1)throw new u.CliError("MULTIPLE_AIB_SESSIONS","Multiple AIB sessions exist. Select one explicitly.",{available:r,next:`Use aib -s <session> <command> or set ${E.CLI_ENV.session}=<session>.`});return{sessionId:null,source:"none"}}function k(e){try{return Ee(e)}catch(t){if(t instanceof u.CliError&&t.code==="MULTIPLE_AIB_SESSIONS")return{sessionId:null,source:"ambiguous"};throw t}}function Ut(e){const t=k(e);return{sessionId:t.sessionId,sessionSource:t.source}}function Y(){const e=F.getStore();if(e)return $(e);const t=process.env[E.CLI_ENV.session];if(t&&t.trim())return $(t);const n=process.env[E.CLI_ENV.legacySession];return n&&n.trim()?$(n):null}function Ae(e,t,n,s){return c.join(e.rootDir,"outputs",I(t),`${I(n)}${ee(s)}`)}function Z(e,t,n,s=".json"){return c.join(e.rootDir,"inputs",I(t),`${I(n)}${ee(s)}`)}function Ft(e,t,n){return c.join(e.rootDir,"inputs",I(t),`${I(n)}.compiled.json`)}function W(e,t,n=".json"){return c.join(e.rootDir,"inputs",I(t),n===".json"?Te:`_last${ee(n)}`)}function x(e,t){l.mkdirSync(c.dirname(e),{recursive:!0}),l.writeFileSync(e,`${JSON.stringify(t,null,2)}
29
- `)}function _e(e,t){l.mkdirSync(c.dirname(e),{recursive:!0}),l.writeFileSync(e,t.endsWith(`
30
- `)?t:`${t}
31
- `,"utf8")}function Ne(e,t,n,s){const i=I(t),r=s??{format:"json",text:JSON.stringify(n,null,2)},o=r.format==="dsl"?W(e,i,".dsl"):W(e,i,".json");r.format==="dsl"?(_e(o,r.text),x(c.join(e.rootDir,"inputs",i,"_last.compiled.json"),n),l.rmSync(W(e,i,".json"),{force:!0})):(x(o,n),l.rmSync(W(e,i,".dsl"),{force:!0}),l.rmSync(c.join(e.rootDir,"inputs",i,"_last.compiled.json"),{force:!0})),C(e,"inputs",i,Pe,o)}function C(e,t,n,s,i){const r=I(n),o=I(s),a=t==="inputs"?`aib:input:${r}:${o}`:`aib:${r}:${o}`,f=new Date().toISOString(),d=e[t],p=d[r]??{items:{}},S={handle:a,file:i,createdAt:p.items[o]?.createdAt??f,updatedAt:f};return p.items[o]=S,p.last=o,d[r]=p,S}function Oe(e){const t=e.split(":");if(t[0]!=="aib")throw new u.CliError("INVALID_SESSION_HANDLE",`Invalid session handle: ${e}`);if(t[1]==="input"&&t.length===4)return{scope:"input",kind:t[2]??"",name:t[3]??""};if(t.length===3)return{scope:t[1]??"",kind:t[1]??"",name:t[2]??""};throw new u.CliError("INVALID_SESSION_HANDLE",`Invalid session handle: ${e}`,{expected:"aib:<kind>:<name> or aib:input:<kind>:<name>"})}function Mt(e){const t={};for(const[n,s]of Object.entries(e.outputs))s.last&&(t[n]=`aib:${n}:${s.last}`);for(const[n,s]of Object.entries(e.inputs))s.last&&(t[`input:${n}`]=`aib:input:${n}:${s.last}`);return t}function Vt(e,t){return{outputs:h(e,c.join(t.rootDir,"outputs")),inputs:h(e,c.join(t.rootDir,"inputs"))}}function w(e,t){const n=e.indexOf(t);return n>=0?e[n+1]:void 0}function X(e){return typeof e=="string"&&e.trim()!==""?e.trim():void 0}function q(e,t){if(e===void 0)return;const n=typeof e=="number"?e:typeof e=="string"?Number(e):Number.NaN;if(!Number.isInteger(n)||n<0)throw new u.CliError("INVALID_SESSION_READ_RANGE",t);return n}function zt(e,t){if(e===void 0)return;const n=q(e,t);if(n!==void 0){if(n<=0)throw new u.CliError("INVALID_SESSION_READ_RANGE",t);return n}}function y(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function I(e){const t=e.trim().replace(/[^A-Za-z0-9._-]/g,"-").replace(/^-+|-+$/g,"");if(!t)throw new u.CliError("INVALID_SESSION_ARTIFACT_NAME",`Invalid session artifact name: ${e}`);return t}function $(e){const t=e.trim().replace(/[^A-Za-z0-9._-]/g,"-").replace(/^-+|-+$/g,"");if(!t)throw new u.CliError("INVALID_SESSION_ID",`Invalid session id: ${e}`);return t}function Jt(){return`${Le}${Math.random().toString(16).slice(2,8)}`}function ee(e){return(e.startsWith(".")?e:`.${e}`).replace(/[^A-Za-z0-9.]/g,"")||".txt"}function j(e){return typeof e=="number"&&Number.isFinite(e)?e:0}function te(e,t){return e===1?t:`${t}s`}function h(e,t){const n=c.relative(e,t);return n&&!n.startsWith("..")?n.replace(/\\/g,"/"):t}
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.isSessionHandle = isSessionHandle;
37
+ exports.runWithSessionOverride = runWithSessionOverride;
38
+ exports.runSessionWorkspaceCommand = runSessionWorkspaceCommand;
39
+ exports.resolveSessionFileArgument = resolveSessionFileArgument;
40
+ exports.saveSessionOutputJson = saveSessionOutputJson;
41
+ exports.saveSessionOutputText = saveSessionOutputText;
42
+ exports.saveSessionResultJson = saveSessionResultJson;
43
+ exports.saveSessionResultViewJson = saveSessionResultViewJson;
44
+ exports.readSessionResultViewJson = readSessionResultViewJson;
45
+ exports.readSessionResultJson = readSessionResultJson;
46
+ exports.captureSessionInputJson = captureSessionInputJson;
47
+ exports.captureSessionInput = captureSessionInput;
48
+ exports.sessionWorkspaceExists = sessionWorkspaceExists;
49
+ exports.useSessionGuidance = useSessionGuidance;
50
+ exports.readSessionBooleanPref = readSessionBooleanPref;
51
+ exports.readSessionNumberPref = readSessionNumberPref;
52
+ exports.readSessionStringPref = readSessionStringPref;
53
+ exports.readEffectiveSessionPathAliases = readEffectiveSessionPathAliases;
54
+ exports.readSessionPathAliasOverrides = readSessionPathAliasOverrides;
55
+ exports.tryResolveCurrentSessionId = tryResolveCurrentSessionId;
56
+ const fs = __importStar(require("node:fs"));
57
+ const path = __importStar(require("node:path"));
58
+ const node_async_hooks_1 = require("node:async_hooks");
59
+ const env_vars_1 = require("../config/env-vars");
60
+ const workspace_root_1 = require("../config/workspace-root");
61
+ const path_aliases_1 = require("../config/path-aliases");
62
+ const agent_text_1 = require("../shared/agent-text");
63
+ const errors_1 = require("../shared/errors");
64
+ const DEFAULT_SESSION_ROOT = path.join(".tmp", "aib");
65
+ const SESSION_DIR_CONFIG_KEY = "sessionDir";
66
+ const SESSION_REGISTRY_FILE_NAME = "session.json";
67
+ const ACTIVE_SESSION_FILE_NAME = "active.json";
68
+ const HANDLE_PREFIX = "aib:";
69
+ const SESSION_ID_PREFIX = "s_";
70
+ const DEFAULT_AUTO_SESSION_ID = "_default";
71
+ const LAST_INPUT_NAME = "last";
72
+ const LAST_INPUT_FILE_NAME = "_last.json";
73
+ const sessionOverrideStorage = new node_async_hooks_1.AsyncLocalStorage();
74
+ const OUTPUT_KINDS = [
75
+ "graph",
76
+ "inspect",
77
+ "code",
78
+ "slice",
79
+ "members",
80
+ "exports",
81
+ "deps",
82
+ "usages",
83
+ "duplicates",
84
+ "mutate",
85
+ "execution",
86
+ "imports"
87
+ ];
88
+ const INPUT_KINDS = [
89
+ "inspect",
90
+ "graph",
91
+ "mutate",
92
+ "imports",
93
+ "generic"
94
+ ];
95
+ const SESSION_PREF_DEFS = {
96
+ "guidance.nextLimit": { type: "number", default: 2, min: 0, max: 100, hidden: true },
97
+ "diagnostics.hintLimit": { type: "number", default: 2, min: 0, max: 100, hidden: true },
98
+ "inspect.code.show": { type: "boolean", default: true, hidden: true },
99
+ "inspect.code.maxNonEmptyLines": { type: "number", default: 120, min: 1, max: 10000 },
100
+ "inspect.code.meta": { type: "boolean", default: true, hidden: true },
101
+ "inspect.members.maxItems": { type: "number", default: 20, min: 1, max: 1000 },
102
+ "inspect.members.all": { type: "boolean", default: false, hidden: true },
103
+ "inspect.exports.ranges": { type: "boolean", default: false, hidden: true },
104
+ "inspect.exports.resolveStar": { type: "boolean", default: false, hidden: true },
105
+ "inspect.graph.hubs": { type: "boolean", default: true },
106
+ "inspect.graph.entrypoints": { type: "boolean", default: true },
107
+ "inspect.graph.leaves": { type: "boolean", default: true },
108
+ "inspect.graph.edges": { type: "boolean", default: true },
109
+ "inspect.graph.symbols": { type: "boolean", default: false, hidden: true },
110
+ "inspect.graph.symbolUsage": { type: "boolean", default: false },
111
+ "inspect.usages.detail": { type: "string", default: "locations", values: ["summary", "locations", "code"], hidden: true },
112
+ "inspect.usages.maxLocations": { type: "number", default: 12, min: 1, max: 10000 },
113
+ "inspect.usages.maxCodeBlocks": { type: "number", default: 8, min: 1, max: 10000 },
114
+ "inspect.usages.excludeTarget": { type: "boolean", default: false, hidden: true }
115
+ };
116
+ function isSessionHandle(value) {
117
+ return value.startsWith(HANDLE_PREFIX);
118
+ }
119
+ function runWithSessionOverride(sessionId, callback) {
120
+ if (!sessionId) {
121
+ return callback();
122
+ }
123
+ return sessionOverrideStorage.run(sessionId, callback);
124
+ }
125
+ function runSessionWorkspaceCommand(cwd, restArgs, stdinPayload) {
126
+ const command = restArgs[0] ?? "status";
127
+ const resolvedWorkspace = (0, workspace_root_1.resolveWorkspaceRoot)(cwd);
128
+ if (!resolvedWorkspace) {
129
+ if (command === "status") {
130
+ return (0, agent_text_1.attachAgentText)({
131
+ initialized: false,
132
+ active: null,
133
+ source: "none",
134
+ available: [],
135
+ next: "Run aib help first-setup"
136
+ }, [
137
+ "session not ready",
138
+ "",
139
+ "No aib.json was found.",
140
+ "",
141
+ "If you are a user:",
142
+ "ask your agent to set up AIB for this repo:",
143
+ "aib help first-setup",
144
+ "",
145
+ "If you are an agent:",
146
+ "run:",
147
+ "aib help first-setup",
148
+ "",
149
+ "Then follow the setup from the intended repository root."
150
+ ].join("\n"));
151
+ }
152
+ (0, workspace_root_1.resolveRequiredWorkspaceRoot)(cwd);
153
+ }
154
+ const workspaceRoot = resolvedWorkspace?.root ?? cwd;
155
+ cleanupExpiredSessions(workspaceRoot);
156
+ if (command === "init") {
157
+ return initSessionWorkspace(workspaceRoot, restArgs.slice(1));
158
+ }
159
+ if (command === "status") {
160
+ return sessionWorkspaceStatus(workspaceRoot);
161
+ }
162
+ if (command === "list") {
163
+ return sessionWorkspaceList(workspaceRoot);
164
+ }
165
+ if (command === "use") {
166
+ return sessionWorkspaceUse(workspaceRoot, restArgs.slice(1));
167
+ }
168
+ if (command === "where") {
169
+ return sessionWorkspaceWhere(workspaceRoot, restArgs.slice(1));
170
+ }
171
+ if (command === "read") {
172
+ return sessionWorkspaceRead(workspaceRoot, restArgs.slice(1), stdinPayload);
173
+ }
174
+ if (command === "write") {
175
+ return sessionWorkspaceWrite(workspaceRoot, restArgs.slice(1), stdinPayload);
176
+ }
177
+ if (command === "prefs") {
178
+ return sessionWorkspacePrefs(workspaceRoot, restArgs.slice(1), stdinPayload);
179
+ }
180
+ if (command === "aliases") {
181
+ return sessionWorkspaceAliases(workspaceRoot, restArgs.slice(1), stdinPayload);
182
+ }
183
+ if (command === "clear") {
184
+ return clearSessionWorkspace(workspaceRoot);
185
+ }
186
+ throw new errors_1.CliError("UNKNOWN_SESSION_WORKSPACE_COMMAND", `Unknown session workspace command: ${command}`);
187
+ }
188
+ function sessionWorkspaceAliases(cwd, args, stdinPayload) {
189
+ const command = args[0] ?? "get";
190
+ if (command === "get") {
191
+ const workspace = readRequiredWorkspace(cwd);
192
+ const config = (0, path_aliases_1.readConfigPathAliases)(cwd);
193
+ const session = (0, path_aliases_1.normalizePathAliasMap)(workspace.pathAliases ?? {}, "session path aliases");
194
+ const response = {
195
+ aliases: (0, path_aliases_1.effectivePathAliases)(cwd, session),
196
+ config,
197
+ session
198
+ };
199
+ return (0, agent_text_1.attachAgentText)(response, formatSessionAliasesAgentText(response));
200
+ }
201
+ if (command === "set") {
202
+ const workspace = readRequiredWorkspace(cwd);
203
+ const updates = args.includes("--stdin")
204
+ ? readAliasesStdinPayload(stdinPayload)
205
+ : readAliasesPairArgs(args.slice(1));
206
+ const aliases = (0, path_aliases_1.normalizePathAliasMap)(workspace.pathAliases ?? {}, "session path aliases");
207
+ const updated = {};
208
+ for (const [name, target] of Object.entries(updates)) {
209
+ const alias = (0, path_aliases_1.normalizePathAliasName)(name, "session path aliases");
210
+ if (typeof target !== "string" || target.trim() === "") {
211
+ throw new errors_1.CliError("INVALID_PATH_ALIAS_TARGET", `session path alias ${name} must be a non-empty path string.`);
212
+ }
213
+ aliases[alias] = target.trim().replace(/\\/g, "/");
214
+ updated[alias] = aliases[alias];
215
+ }
216
+ workspace.pathAliases = aliases;
217
+ writeWorkspace(cwd, workspace);
218
+ const response = {
219
+ updated,
220
+ aliases: (0, path_aliases_1.effectivePathAliases)(cwd, aliases)
221
+ };
222
+ return (0, agent_text_1.attachAgentText)(response, formatSessionAliasesAgentText(response));
223
+ }
224
+ if (command === "clear") {
225
+ const workspace = readRequiredWorkspace(cwd);
226
+ const keys = args.slice(1).filter((item) => !item.startsWith("--"));
227
+ const aliases = (0, path_aliases_1.normalizePathAliasMap)(workspace.pathAliases ?? {}, "session path aliases");
228
+ const cleared = [];
229
+ if (keys.length === 0) {
230
+ cleared.push(...Object.keys(aliases).sort());
231
+ delete workspace.pathAliases;
232
+ }
233
+ else {
234
+ for (const key of keys) {
235
+ const alias = (0, path_aliases_1.normalizePathAliasName)(key, "session path aliases");
236
+ if (Object.prototype.hasOwnProperty.call(aliases, alias)) {
237
+ cleared.push(alias);
238
+ delete aliases[alias];
239
+ }
240
+ }
241
+ if (Object.keys(aliases).length > 0) {
242
+ workspace.pathAliases = aliases;
243
+ }
244
+ else {
245
+ delete workspace.pathAliases;
246
+ }
247
+ }
248
+ writeWorkspace(cwd, workspace);
249
+ const response = {
250
+ cleared,
251
+ aliases: (0, path_aliases_1.effectivePathAliases)(cwd, workspace.pathAliases ?? {})
252
+ };
253
+ return (0, agent_text_1.attachAgentText)(response, formatSessionAliasesAgentText(response));
254
+ }
255
+ throw new errors_1.CliError("UNKNOWN_SESSION_ALIASES_COMMAND", `Unknown session aliases command: ${command}`, {
256
+ expected: "aib session aliases get | set | clear"
257
+ });
258
+ }
259
+ function readAliasesStdinPayload(stdinPayload) {
260
+ if (!isObject(stdinPayload)) {
261
+ throw new errors_1.CliError("INVALID_SESSION_ALIASES_STDIN", "session aliases set --stdin expects a JSON object.");
262
+ }
263
+ const rawAliases = isObject(stdinPayload.aliases) ? stdinPayload.aliases : stdinPayload;
264
+ const aliases = {};
265
+ for (const [key, value] of Object.entries(rawAliases)) {
266
+ if (typeof value === "string") {
267
+ aliases[key] = value;
268
+ }
269
+ }
270
+ return aliases;
271
+ }
272
+ function readAliasesPairArgs(args) {
273
+ if (args.length === 0 || args.length % 2 !== 0) {
274
+ throw new errors_1.CliError("SESSION_ALIASES_SET_USAGE", "Usage: aib session aliases set <name> <path> [<name> <path>...] or session aliases set --stdin");
275
+ }
276
+ const aliases = {};
277
+ for (let index = 0; index < args.length; index += 2) {
278
+ aliases[args[index] ?? ""] = args[index + 1] ?? "";
279
+ }
280
+ return aliases;
281
+ }
282
+ function formatSessionAliasesAgentText(response) {
283
+ if (isObject(response.updated)) {
284
+ return formatAliasesMap("aliases.updated", response.updated);
285
+ }
286
+ if (Array.isArray(response.cleared)) {
287
+ const cleared = response.cleared.filter((item) => typeof item === "string");
288
+ return cleared.length > 0 ? ["aliases.cleared", ...cleared].join("\n") : "aliases.cleared none";
289
+ }
290
+ if (isObject(response.aliases)) {
291
+ const lines = formatAliasesMap("aliases", response.aliases).split("\n");
292
+ if (lines.length === 1) {
293
+ lines.push("none");
294
+ }
295
+ return lines.join("\n");
296
+ }
297
+ return null;
298
+ }
299
+ function formatAliasesMap(title, aliases) {
300
+ const lines = [title];
301
+ for (const [key, value] of Object.entries(aliases).sort(([left], [right]) => left.localeCompare(right))) {
302
+ lines.push(`@${key}/=${String(value)}`);
303
+ }
304
+ return lines.join("\n");
305
+ }
306
+ function sessionWorkspaceWrite(cwd, args, stdinPayload) {
307
+ const kind = args[0] ?? "";
308
+ const name = args[1] ?? "";
309
+ if (!kind || !name) {
310
+ throw new errors_1.CliError("SESSION_WRITE_USAGE", "Usage: aib session write <kind> <name> --stdin");
311
+ }
312
+ if (stdinPayload === undefined) {
313
+ throw new errors_1.CliError("STDIN_REQUIRED", "session write expects JSON on stdin and the --stdin flag.");
314
+ }
315
+ const workspace = readRequiredWorkspace(cwd);
316
+ const file = sessionInputPath(workspace, kind, name);
317
+ writeJsonFile(file, stdinPayload);
318
+ const artifact = registerArtifact(workspace, "inputs", kind, name, file);
319
+ registerLastInputArtifact(workspace, kind, stdinPayload);
320
+ writeWorkspace(cwd, workspace);
321
+ const result = {
322
+ written: artifact.handle,
323
+ file: toDisplayPath(cwd, file)
324
+ };
325
+ const next = useSessionGuidance(cwd, "session.write.from", `Use with --from ${artifact.handle}`);
326
+ if (next) {
327
+ result.next = next;
328
+ }
329
+ return result;
330
+ }
331
+ function sessionWorkspacePrefs(cwd, args, stdinPayload) {
332
+ const command = args[0] ?? "get";
333
+ if (command === "get") {
334
+ const workspace = readRequiredWorkspace(cwd);
335
+ const full = args.includes("--all");
336
+ const prefix = args.slice(1).find((item) => !item.startsWith("--"));
337
+ const prefs = full ? effectivePrefs(workspace) : visiblePrefs(workspace.prefs ?? {});
338
+ const selected = selectPrefs(prefs, prefix);
339
+ const response = full
340
+ ? {
341
+ prefs: selected
342
+ }
343
+ : {
344
+ overrides: selected,
345
+ defaults: "omitted; use session prefs get --all"
346
+ };
347
+ return (0, agent_text_1.attachAgentText)(response, formatSessionPrefsAgentText(response));
348
+ }
349
+ if (command === "set") {
350
+ const workspace = readRequiredWorkspace(cwd);
351
+ const updates = args.includes("--stdin")
352
+ ? readPrefsStdinPayload(stdinPayload)
353
+ : readPrefsPairArgs(args.slice(1));
354
+ const prefs = workspace.prefs ?? {};
355
+ const updated = {};
356
+ for (const [key, value] of Object.entries(updates)) {
357
+ const normalizedKey = normalizeSessionPrefKey(key);
358
+ const parsed = parseSessionPrefValue(normalizedKey, value);
359
+ prefs[normalizedKey] = parsed;
360
+ updated[normalizedKey] = parsed;
361
+ }
362
+ workspace.prefs = prefs;
363
+ writeWorkspace(cwd, workspace);
364
+ const response = { updated };
365
+ return (0, agent_text_1.attachAgentText)(response, formatSessionPrefsAgentText(response));
366
+ }
367
+ if (command === "clear") {
368
+ const workspace = readRequiredWorkspace(cwd);
369
+ const keys = args.slice(1).filter((item) => !item.startsWith("--"));
370
+ const currentPrefs = workspace.prefs ?? {};
371
+ const cleared = [];
372
+ if (keys.length === 0) {
373
+ cleared.push(...Object.keys(currentPrefs).sort());
374
+ delete workspace.prefs;
375
+ }
376
+ else {
377
+ for (const key of keys) {
378
+ const normalizedKey = normalizeSessionPrefKey(key);
379
+ if (Object.prototype.hasOwnProperty.call(currentPrefs, normalizedKey)) {
380
+ cleared.push(normalizedKey);
381
+ delete currentPrefs[normalizedKey];
382
+ }
383
+ }
384
+ if (Object.keys(currentPrefs).length > 0) {
385
+ workspace.prefs = currentPrefs;
386
+ }
387
+ else {
388
+ delete workspace.prefs;
389
+ }
390
+ }
391
+ writeWorkspace(cwd, workspace);
392
+ const response = {
393
+ cleared
394
+ };
395
+ return (0, agent_text_1.attachAgentText)(response, formatSessionPrefsAgentText(response));
396
+ }
397
+ throw new errors_1.CliError("UNKNOWN_SESSION_PREFS_COMMAND", `Unknown session prefs command: ${command}`, {
398
+ expected: "aib session prefs get | set | clear"
399
+ });
400
+ }
401
+ function selectPrefs(prefs, prefix) {
402
+ if (!prefix) {
403
+ return prefs;
404
+ }
405
+ const selected = {};
406
+ for (const [key, value] of Object.entries(prefs)) {
407
+ if (key === prefix || key.startsWith(`${prefix}.`)) {
408
+ selected[key] = value;
409
+ }
410
+ }
411
+ return selected;
412
+ }
413
+ function formatSessionPrefsAgentText(response) {
414
+ if (isObject(response.updated)) {
415
+ return formatPrefsMap("prefs.updated", response.updated);
416
+ }
417
+ if (Array.isArray(response.cleared)) {
418
+ const cleared = response.cleared.filter((item) => typeof item === "string");
419
+ return cleared.length > 0 ? ["prefs.cleared", ...cleared].join("\n") : "prefs.cleared none";
420
+ }
421
+ if (isObject(response.overrides)) {
422
+ const lines = formatPrefsMap("prefs", response.overrides).split("\n");
423
+ if (lines.length === 1) {
424
+ lines.push("no overrides");
425
+ }
426
+ if (typeof response.defaults === "string") {
427
+ lines.push(response.defaults);
428
+ }
429
+ return lines.join("\n");
430
+ }
431
+ if (isObject(response.prefs)) {
432
+ return formatPrefsMap("prefs", response.prefs);
433
+ }
434
+ return null;
435
+ }
436
+ function formatPrefsMap(title, prefs) {
437
+ const lines = [title];
438
+ for (const [key, value] of Object.entries(prefs).sort(([left], [right]) => left.localeCompare(right))) {
439
+ lines.push(`${key}=${String(value)}`);
440
+ }
441
+ return lines.join("\n");
442
+ }
443
+ function readPrefsStdinPayload(stdinPayload) {
444
+ if (!isObject(stdinPayload)) {
445
+ throw new errors_1.CliError("INVALID_SESSION_PREFS_STDIN", "session prefs set --stdin expects a JSON object.");
446
+ }
447
+ const rawPrefs = isObject(stdinPayload.prefs) ? stdinPayload.prefs : stdinPayload;
448
+ const prefs = {};
449
+ for (const [key, value] of Object.entries(rawPrefs)) {
450
+ prefs[key] = value;
451
+ }
452
+ return prefs;
453
+ }
454
+ function readPrefsPairArgs(args) {
455
+ if (args.length === 0 || args.length % 2 !== 0) {
456
+ throw new errors_1.CliError("SESSION_PREFS_SET_USAGE", "Usage: aib session prefs set <key> <value> [<key> <value>...] or session prefs set --stdin");
457
+ }
458
+ const prefs = {};
459
+ for (let index = 0; index < args.length; index += 2) {
460
+ const key = args[index] ?? "";
461
+ const value = args[index + 1] ?? "";
462
+ prefs[key] = value;
463
+ }
464
+ return prefs;
465
+ }
466
+ function normalizeSessionPrefKey(key) {
467
+ if (Object.prototype.hasOwnProperty.call(SESSION_PREF_DEFS, key)) {
468
+ return key;
469
+ }
470
+ throw new errors_1.CliError("UNKNOWN_SESSION_PREF", `Unknown session preference: ${key}`, {
471
+ available: Object.keys(SESSION_PREF_DEFS)
472
+ });
473
+ }
474
+ function parseSessionPrefValue(key, value) {
475
+ const definition = SESSION_PREF_DEFS[key];
476
+ if (definition.type === "boolean") {
477
+ if (typeof value === "boolean") {
478
+ return value;
479
+ }
480
+ if (typeof value === "string") {
481
+ const normalized = value.trim().toLowerCase();
482
+ if (normalized === "true") {
483
+ return true;
484
+ }
485
+ if (normalized === "false") {
486
+ return false;
487
+ }
488
+ }
489
+ throw new errors_1.CliError("INVALID_SESSION_PREF_VALUE", `${key} expects true or false.`);
490
+ }
491
+ if (definition.type === "string") {
492
+ if (typeof value !== "string") {
493
+ throw new errors_1.CliError("INVALID_SESSION_PREF_VALUE", `${key} expects one of: ${definition.values.join(", ")}.`);
494
+ }
495
+ const normalized = value.trim();
496
+ if (!definition.values.includes(normalized)) {
497
+ throw new errors_1.CliError("INVALID_SESSION_PREF_VALUE", `${key} expects one of: ${definition.values.join(", ")}.`);
498
+ }
499
+ return normalized;
500
+ }
501
+ const parsed = typeof value === "number" ? value : typeof value === "string" ? Number(value) : NaN;
502
+ if (!Number.isInteger(parsed) || parsed < definition.min || parsed > definition.max) {
503
+ throw new errors_1.CliError("INVALID_SESSION_PREF_VALUE", `${key} expects an integer from ${definition.min} to ${definition.max}.`);
504
+ }
505
+ return parsed;
506
+ }
507
+ function effectivePrefs(workspace) {
508
+ const prefs = {};
509
+ for (const key of Object.keys(SESSION_PREF_DEFS)) {
510
+ const definition = SESSION_PREF_DEFS[key];
511
+ if ("hidden" in definition && definition.hidden) {
512
+ continue;
513
+ }
514
+ if (definition.type === "boolean") {
515
+ prefs[key] = readWorkspaceBooleanPref(workspace, key, definition.default);
516
+ }
517
+ else if (definition.type === "number") {
518
+ prefs[key] = readWorkspaceNumberPref(workspace, key, definition.default);
519
+ }
520
+ else {
521
+ prefs[key] = readWorkspaceStringPref(workspace, key, definition.default);
522
+ }
523
+ }
524
+ return prefs;
525
+ }
526
+ function visiblePrefs(prefs) {
527
+ const visible = {};
528
+ for (const [key, value] of Object.entries(prefs)) {
529
+ if (!isHiddenSessionPrefKey(key)) {
530
+ visible[key] = value;
531
+ }
532
+ }
533
+ return visible;
534
+ }
535
+ function isHiddenSessionPrefKey(key) {
536
+ if (!Object.prototype.hasOwnProperty.call(SESSION_PREF_DEFS, key)) {
537
+ return false;
538
+ }
539
+ const definition = SESSION_PREF_DEFS[key];
540
+ return "hidden" in definition && definition.hidden === true;
541
+ }
542
+ function resolveSessionFileArgument(cwd, value) {
543
+ if (!isSessionHandle(value)) {
544
+ return value;
545
+ }
546
+ const workspace = readRequiredWorkspace(cwd);
547
+ const parsed = parseSessionHandle(value);
548
+ const bucketGroup = parsed.scope === "input" ? workspace.inputs : workspace.outputs;
549
+ const kind = parsed.scope === "input" ? parsed.kind : parsed.scope;
550
+ const bucket = bucketGroup[kind];
551
+ const name = parsed.name === "last" ? bucket?.last : parsed.name;
552
+ const artifact = name ? bucket?.items[name] : undefined;
553
+ if (!artifact) {
554
+ throw new errors_1.CliError("SESSION_HANDLE_NOT_FOUND", `Session handle not found: ${value}`, {
555
+ handle: value,
556
+ sessionDir: toDisplayPath(cwd, workspace.rootDir)
557
+ });
558
+ }
559
+ return artifact.file;
560
+ }
561
+ function saveSessionOutputJson(cwd, kind, name, value) {
562
+ const workspace = readRequiredWorkspaceForSave(cwd);
563
+ const file = sessionOutputPath(workspace, kind, name, ".json");
564
+ fs.mkdirSync(path.dirname(file), { recursive: true });
565
+ fs.writeFileSync(file, `${JSON.stringify(value, null, 2)}\n`);
566
+ const artifact = registerArtifact(workspace, "outputs", kind, name, file);
567
+ writeWorkspace(cwd, workspace);
568
+ return {
569
+ saved: artifact.handle,
570
+ last: `aib:${kind}:last`,
571
+ file: toDisplayPath(cwd, file)
572
+ };
573
+ }
574
+ function saveSessionOutputText(cwd, kind, name, value, extension = ".txt") {
575
+ const workspace = readRequiredWorkspaceForSave(cwd);
576
+ const file = sessionOutputPath(workspace, kind, name, extension);
577
+ fs.mkdirSync(path.dirname(file), { recursive: true });
578
+ fs.writeFileSync(file, value);
579
+ const artifact = registerArtifact(workspace, "outputs", kind, name, file);
580
+ writeWorkspace(cwd, workspace);
581
+ return {
582
+ saved: artifact.handle,
583
+ last: `aib:${kind}:last`,
584
+ file: toDisplayPath(cwd, file)
585
+ };
586
+ }
587
+ function saveSessionResultJson(cwd, kind, id, value) {
588
+ const workspace = readWorkspaceForSave(cwd);
589
+ if (!workspace) {
590
+ return null;
591
+ }
592
+ const normalizedKind = sanitizePathSegment(kind);
593
+ const normalizedId = sanitizePathSegment(id);
594
+ const file = path.join(workspace.rootDir, "outputs", "result", normalizedKind, `${normalizedId}.json`);
595
+ writeJsonFile(file, value);
596
+ return {
597
+ saved: `aib:result:${normalizedKind}:${normalizedId}`,
598
+ file: toDisplayPath(cwd, file)
599
+ };
600
+ }
601
+ function saveSessionResultViewJson(cwd, id, value) {
602
+ const workspace = readWorkspaceForSave(cwd);
603
+ if (!workspace) {
604
+ return null;
605
+ }
606
+ const normalizedId = sanitizePathSegment(id);
607
+ const file = path.join(workspace.rootDir, "outputs", "result", `${normalizedId}.json`);
608
+ writeJsonFile(file, value);
609
+ return {
610
+ saved: `aib:${normalizedId}`,
611
+ file: toDisplayPath(cwd, file)
612
+ };
613
+ }
614
+ function readSessionResultViewJson(cwd, id) {
615
+ const workspace = readRequiredWorkspace(cwd);
616
+ const normalizedId = sanitizePathSegment(id);
617
+ const file = path.join(workspace.rootDir, "outputs", "result", `${normalizedId}.json`);
618
+ if (!fs.existsSync(file)) {
619
+ throw new errors_1.CliError("SESSION_RESULT_NOT_FOUND", `Result handle not found: aib:${normalizedId}`, {
620
+ handle: `aib:${normalizedId}`,
621
+ sessionDir: toDisplayPath(cwd, workspace.rootDir)
622
+ });
623
+ }
624
+ const parsed = JSON.parse(fs.readFileSync(file, "utf8"));
625
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
626
+ throw new errors_1.CliError("INVALID_SESSION_RESULT", `Result artifact is not a JSON object: aib:${normalizedId}`);
627
+ }
628
+ return parsed;
629
+ }
630
+ function readSessionResultJson(cwd, kind, id) {
631
+ const workspace = readRequiredWorkspace(cwd);
632
+ const normalizedKind = sanitizePathSegment(kind);
633
+ const normalizedId = sanitizePathSegment(id);
634
+ const file = path.join(workspace.rootDir, "outputs", "result", normalizedKind, `${normalizedId}.json`);
635
+ if (!fs.existsSync(file)) {
636
+ throw new errors_1.CliError("SESSION_RESULT_NOT_FOUND", `Result handle not found: aib:result:${normalizedKind}:${normalizedId}`, {
637
+ handle: `aib:result:${normalizedKind}:${normalizedId}`,
638
+ sessionDir: toDisplayPath(cwd, workspace.rootDir)
639
+ });
640
+ }
641
+ const parsed = JSON.parse(fs.readFileSync(file, "utf8"));
642
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
643
+ throw new errors_1.CliError("INVALID_SESSION_RESULT", `Result artifact is not a JSON object: aib:result:${normalizedKind}:${normalizedId}`);
644
+ }
645
+ return parsed;
646
+ }
647
+ function captureSessionInputJson(cwd, kind, name, value) {
648
+ return captureSessionInput(cwd, kind, name, value, { format: "json", text: JSON.stringify(value, null, 2) });
649
+ }
650
+ function captureSessionInput(cwd, kind, name, value, source) {
651
+ const workspace = readWorkspaceForSave(cwd);
652
+ if (!workspace) {
653
+ return null;
654
+ }
655
+ const inputSource = source ?? { format: "json", text: JSON.stringify(value, null, 2) };
656
+ const file = inputSource.format === "dsl"
657
+ ? sessionInputPath(workspace, kind, name, ".dsl")
658
+ : sessionInputPath(workspace, kind, name, ".json");
659
+ if (inputSource.format === "dsl") {
660
+ writeTextFile(file, inputSource.text);
661
+ writeJsonFile(sessionCompiledInputPath(workspace, kind, name), value);
662
+ }
663
+ else {
664
+ writeJsonFile(file, value);
665
+ }
666
+ const artifact = registerArtifact(workspace, "inputs", kind, name, file);
667
+ registerLastInputArtifact(workspace, kind, value, inputSource);
668
+ writeWorkspace(cwd, workspace);
669
+ return {
670
+ handle: artifact.handle,
671
+ file: toDisplayPath(cwd, file)
672
+ };
673
+ }
674
+ function sessionWorkspaceExists(cwd) {
675
+ return fs.existsSync(workspaceMarkerPath(cwd));
676
+ }
677
+ function useSessionGuidance(cwd, key, message, limit = -1) {
678
+ const workspace = readWorkspace(cwd);
679
+ if (!workspace) {
680
+ return message;
681
+ }
682
+ const configuredLimit = limit >= 0 ? limit : readWorkspaceNumberPref(workspace, "guidance.nextLimit", 2);
683
+ const guidance = workspace.guidance ?? {};
684
+ const state = guidance[key] ?? { shown: 0, limit: configuredLimit };
685
+ state.limit = configuredLimit;
686
+ if (state.shown >= state.limit) {
687
+ guidance[key] = state;
688
+ workspace.guidance = guidance;
689
+ writeWorkspace(cwd, workspace);
690
+ return undefined;
691
+ }
692
+ state.shown += 1;
693
+ guidance[key] = state;
694
+ workspace.guidance = guidance;
695
+ writeWorkspace(cwd, workspace);
696
+ return message;
697
+ }
698
+ function readSessionBooleanPref(cwd, key, fallback) {
699
+ const workspace = readWorkspace(cwd);
700
+ const definition = SESSION_PREF_DEFS[key];
701
+ const defaultValue = typeof fallback === "boolean" ? fallback : definition.type === "boolean" ? definition.default : false;
702
+ return workspace ? readWorkspaceBooleanPref(workspace, key, defaultValue) : defaultValue;
703
+ }
704
+ function readSessionNumberPref(cwd, key, fallback) {
705
+ const workspace = readWorkspace(cwd);
706
+ const definition = SESSION_PREF_DEFS[key];
707
+ const defaultValue = typeof fallback === "number" ? fallback : definition.type === "number" ? definition.default : 0;
708
+ const configValue = (0, workspace_root_1.readWorkspaceNumberConfig)(cwd, key, defaultValue);
709
+ return workspace ? readWorkspaceNumberPref(workspace, key, configValue) : configValue;
710
+ }
711
+ function readSessionStringPref(cwd, key, fallback) {
712
+ const workspace = readWorkspace(cwd);
713
+ const definition = SESSION_PREF_DEFS[key];
714
+ const defaultValue = typeof fallback === "string" ? fallback : definition.type === "string" ? definition.default : "";
715
+ return workspace ? readWorkspaceStringPref(workspace, key, defaultValue) : defaultValue;
716
+ }
717
+ function readEffectiveSessionPathAliases(cwd) {
718
+ try {
719
+ const workspace = readWorkspace(cwd);
720
+ return (0, path_aliases_1.effectivePathAliases)(cwd, workspace?.pathAliases ?? {});
721
+ }
722
+ catch (error) {
723
+ if (error instanceof errors_1.CliError && error.code === "MULTIPLE_AIB_SESSIONS") {
724
+ return (0, path_aliases_1.effectivePathAliases)(cwd, {});
725
+ }
726
+ throw error;
727
+ }
728
+ }
729
+ function readSessionPathAliasOverrides(cwd) {
730
+ try {
731
+ const workspace = readWorkspace(cwd);
732
+ return (0, path_aliases_1.normalizePathAliasMap)(workspace?.pathAliases ?? {}, "session path aliases");
733
+ }
734
+ catch (error) {
735
+ if (error instanceof errors_1.CliError && error.code === "MULTIPLE_AIB_SESSIONS") {
736
+ return {};
737
+ }
738
+ throw error;
739
+ }
740
+ }
741
+ function readWorkspaceBooleanPref(workspace, key, fallback) {
742
+ const value = workspace.prefs?.[key];
743
+ return typeof value === "boolean" ? value : fallback;
744
+ }
745
+ function readWorkspaceNumberPref(workspace, key, fallback) {
746
+ const value = workspace.prefs?.[key];
747
+ return typeof value === "number" && Number.isFinite(value) ? value : fallback;
748
+ }
749
+ function readWorkspaceStringPref(workspace, key, fallback) {
750
+ const value = workspace.prefs?.[key];
751
+ return typeof value === "string" ? value : fallback;
752
+ }
753
+ function initSessionWorkspace(cwd, args) {
754
+ const requestedDir = readFlagValue(args, "--dir");
755
+ const explicitName = readFlagValue(args, "--name");
756
+ const sessionId = sanitizeSessionId(explicitName ?? currentSessionId() ?? createSessionId());
757
+ if (explicitName && sessionId === DEFAULT_AUTO_SESSION_ID) {
758
+ throw new errors_1.CliError("SESSION_ID_RESERVED", `${DEFAULT_AUTO_SESSION_ID} is reserved for AIB's automatic default session.`, {
759
+ session: sessionId,
760
+ next: "Use aib session init --name <name>"
761
+ });
762
+ }
763
+ const sessionRoot = resolveSessionRoot(cwd, requestedDir, true);
764
+ const rootDir = path.join(sessionRoot.rootDir, sessionId);
765
+ const now = new Date().toISOString();
766
+ const existing = readWorkspaceById(cwd, sessionId);
767
+ const workspace = existing ?? {
768
+ version: 1,
769
+ sessionId,
770
+ cwd: path.resolve(cwd),
771
+ rootDir,
772
+ createdAt: now,
773
+ updatedAt: now,
774
+ outputs: {},
775
+ inputs: {},
776
+ guidance: {}
777
+ };
778
+ workspace.sessionId = sessionId;
779
+ workspace.rootDir = rootDir;
780
+ workspace.updatedAt = now;
781
+ ensureWorkspaceDirs(workspace);
782
+ writeWorkspace(cwd, workspace);
783
+ upsertRegistrySession(cwd, workspace, true);
784
+ const registry = readRegistry(cwd);
785
+ const sessionCount = registry ? Object.keys(registry.sessions).length : 1;
786
+ const result = {
787
+ session: sessionId,
788
+ dir: toDisplayPath(cwd, workspace.rootDir),
789
+ sessionDir: toDisplayPath(cwd, sessionRoot.rootDir),
790
+ sessionDirSource: sessionRoot.source,
791
+ sessionCount,
792
+ bind: `${env_vars_1.CLI_ENV.session}=${sessionId}`,
793
+ next: sessionCount === 1
794
+ ? "Run AIB commands without -s for now. AIB will tell you if multiple sessions exist."
795
+ : `Use aib -s ${sessionId} <command> or set ${env_vars_1.CLI_ENV.session}=${sessionId}.`
796
+ };
797
+ if (sessionRoot.ignoredRequestedDir) {
798
+ result.note = `${SESSION_DIR_CONFIG_KEY} from aib.json is in effect; --dir was ignored.`;
799
+ result.requestedDir = sessionRoot.ignoredRequestedDir;
800
+ }
801
+ return (0, agent_text_1.attachAgentText)(result, formatSessionInitAgentText(result));
802
+ }
803
+ function formatSessionInitAgentText(result) {
804
+ const sessionId = String(result.session ?? "");
805
+ const sessionCount = typeof result.sessionCount === "number" ? result.sessionCount : 1;
806
+ const lines = [`session ready: ${sessionId}`, ""];
807
+ if (typeof result.note === "string" && result.note) {
808
+ lines.push("aib.json sessionDir is in effect; --dir was ignored.");
809
+ lines.push("");
810
+ }
811
+ if (sessionCount === 1) {
812
+ lines.push("Only one AIB session exists in this repo.");
813
+ lines.push("You can run AIB commands without -s for now.");
814
+ lines.push("AIB will tell you if multiple sessions exist and you need to choose one.");
815
+ }
816
+ else {
817
+ lines.push("Multiple AIB sessions exist in this repo.");
818
+ lines.push("Use this session explicitly:");
819
+ lines.push(`aib -s ${sessionId} <command>`);
820
+ lines.push("");
821
+ lines.push("Or bind it in this shell:");
822
+ lines.push(`${env_vars_1.CLI_ENV.session}=${sessionId}`);
823
+ }
824
+ return lines.join("\n");
825
+ }
826
+ function sessionWorkspaceList(cwd) {
827
+ const registry = readRegistry(cwd);
828
+ const selected = resolveSelectedSessionForList(cwd);
829
+ return {
830
+ active: selected.sessionId ?? registry?.activeSessionId ?? null,
831
+ source: selected.source,
832
+ sessions: registry
833
+ ? Object.values(registry.sessions)
834
+ .sort((left, right) => left.sessionId.localeCompare(right.sessionId))
835
+ .map((session) => `${session.sessionId} -> ${toDisplayPath(cwd, session.rootDir)}`)
836
+ : []
837
+ };
838
+ }
839
+ function sessionWorkspaceUse(cwd, args) {
840
+ const rawSessionId = args[0] ?? "";
841
+ if (!rawSessionId) {
842
+ throw new errors_1.CliError("SESSION_USE_ID_REQUIRED", "Usage: aib session use <sessionId>");
843
+ }
844
+ const sessionId = sanitizeSessionId(rawSessionId);
845
+ const registry = readRegistry(cwd);
846
+ const entry = registry?.sessions[sessionId];
847
+ if (!entry) {
848
+ throw new errors_1.CliError("SESSION_NOT_FOUND", `Session not found: ${sessionId}`, {
849
+ available: registry ? Object.keys(registry.sessions).sort() : []
850
+ });
851
+ }
852
+ writeRegistry(cwd, {
853
+ ...(registry ?? createEmptyRegistry(cwd)),
854
+ activeSessionId: sessionId
855
+ });
856
+ return {
857
+ session: sessionId,
858
+ dir: toDisplayPath(cwd, entry.rootDir),
859
+ bind: `${env_vars_1.CLI_ENV.session}=${sessionId}`,
860
+ next: `Use aib -s ${sessionId} <command> or set ${env_vars_1.CLI_ENV.session}=${sessionId}.`
861
+ };
862
+ }
863
+ function sessionWorkspaceWhere(cwd, args) {
864
+ const handle = args[0] ?? "";
865
+ if (!handle) {
866
+ throw new errors_1.CliError("SESSION_WHERE_HANDLE_REQUIRED", "Usage: aib session where <handle>");
867
+ }
868
+ const file = resolveSessionFileArgument(cwd, handle);
869
+ const response = {
870
+ handle,
871
+ file: toDisplayPath(cwd, file)
872
+ };
873
+ return (0, agent_text_1.attachAgentText)(response, [
874
+ handle,
875
+ response.file
876
+ ].join("\n"));
877
+ }
878
+ function sessionWorkspaceRead(cwd, args, stdinPayload) {
879
+ if (args.includes("--stdin")) {
880
+ if (!isObject(stdinPayload)) {
881
+ throw new errors_1.CliError("INVALID_SESSION_READ_STDIN", "session read --stdin expects a JSON object payload.");
882
+ }
883
+ const readRequests = parseSessionReadBatchPayload(stdinPayload);
884
+ if (readRequests.length === 1) {
885
+ const result = readSessionArtifact(cwd, readRequests[0]);
886
+ return (0, agent_text_1.attachAgentText)(result, formatSessionReadAgentText(result));
887
+ }
888
+ const result = {
889
+ reads: readRequests.map((request) => readSessionArtifactRow(cwd, request))
890
+ };
891
+ return (0, agent_text_1.attachAgentText)(result, formatSessionReadAgentText(result));
892
+ }
893
+ const handle = args[0] ?? "";
894
+ if (!handle) {
895
+ throw new errors_1.CliError("SESSION_READ_HANDLE_REQUIRED", "Usage: aib session read <handle> [--head <n> | --offset <n> --limit <n>]");
896
+ }
897
+ const result = readSessionArtifact(cwd, {
898
+ handle,
899
+ ...readSessionReadOptions(args.slice(1))
900
+ });
901
+ return (0, agent_text_1.attachAgentText)(result, formatSessionReadAgentText(result));
902
+ }
903
+ function parseSessionReadBatchPayload(payload) {
904
+ if (Array.isArray(payload.reads)) {
905
+ return payload.reads.map((row, index) => {
906
+ if (typeof row === "string") {
907
+ if (!isSessionHandle(row)) {
908
+ throw new errors_1.CliError("INVALID_SESSION_READ_ROW", `session read row at index ${index} must be an aib: handle string or an object.`);
909
+ }
910
+ return { handle: row };
911
+ }
912
+ if (!isObject(row)) {
913
+ throw new errors_1.CliError("INVALID_SESSION_READ_ROW", `session read row at index ${index} must be an aib: handle string or an object.`);
914
+ }
915
+ return parseSessionReadRow(row, index);
916
+ });
917
+ }
918
+ if (typeof payload.handle === "string" || typeof payload.read === "string") {
919
+ return [parseSessionReadRow(payload, 0)];
920
+ }
921
+ throw new errors_1.CliError("INVALID_SESSION_READ_STDIN", "Expected { reads: [{ handle }] } or { handle }.");
922
+ }
923
+ function parseSessionReadRow(row, index) {
924
+ const handle = readString(row.handle) ?? readString(row.read);
925
+ if (!handle) {
926
+ throw new errors_1.CliError("SESSION_READ_HANDLE_REQUIRED", `session read row at index ${index} requires handle.`);
927
+ }
928
+ return {
929
+ handle,
930
+ ...(row.rawInput === true ? { rawInput: true } : {}),
931
+ ...readSessionReadObjectOptions(row, index)
932
+ };
933
+ }
934
+ function readSessionArtifactRow(cwd, request) {
935
+ try {
936
+ return readSessionArtifact(cwd, request);
937
+ }
938
+ catch (error) {
939
+ if (error instanceof errors_1.CliError) {
940
+ const details = isObject(error.details) ? error.details : {};
941
+ return {
942
+ read: request.handle,
943
+ error: error.code,
944
+ ...(typeof details.next === "string" ? { next: details.next } : {})
945
+ };
946
+ }
947
+ return {
948
+ read: request.handle,
949
+ error: "UNEXPECTED_ERROR"
950
+ };
951
+ }
952
+ }
953
+ function readSessionArtifact(cwd, request) {
954
+ validateSessionReadOptions(request);
955
+ const parsed = parseSessionHandle(request.handle);
956
+ const file = resolveSessionFileArgument(cwd, request.handle);
957
+ if (parsed.scope === "input" && !request.rawInput) {
958
+ const rerun = buildInputRerunCommand(parsed.kind, request.handle);
959
+ return {
960
+ read: request.handle,
961
+ file: toDisplayPath(cwd, file),
962
+ next: rerun
963
+ ? `Edit file, then rerun: ${rerun}`
964
+ : "Edit file, then rerun the command with --from <handle>."
965
+ };
966
+ }
967
+ if (parsed.scope === "graph" || parsed.scope === "usages") {
968
+ const next = parsed.scope === "graph"
969
+ ? `aib inspect graph --from-file ${request.handle} --focus <file>`
970
+ : `aib inspect usages --from-file ${request.handle} --focus <name>`;
971
+ throw new errors_1.CliError("SESSION_ARTIFACT_NOT_READABLE", `${parsed.scope} artifacts are reusable indexes, not agent-readable context.`, {
972
+ handle: request.handle,
973
+ kind: parsed.scope,
974
+ next
975
+ });
976
+ }
977
+ if (parsed.scope === "duplicates") {
978
+ const content = fs.readFileSync(file, "utf8");
979
+ return {
980
+ read: request.handle,
981
+ content: readSavedDuplicatesContent(cwd, request.handle, file, content, request)
982
+ };
983
+ }
984
+ const content = fs.readFileSync(file, "utf8");
985
+ return {
986
+ read: request.handle,
987
+ content: readSessionArtifactContent(file, content, request)
988
+ };
989
+ }
990
+ function readSavedDuplicatesContent(cwd, handle, file, content, request) {
991
+ const text = formatSavedDuplicatesContent(cwd, handle, file, content);
992
+ return request.head !== undefined || request.offset !== undefined || request.limit !== undefined
993
+ ? applyReadWindow(text, request)
994
+ : text;
995
+ }
996
+ function formatSavedDuplicatesContent(cwd, handle, file, content) {
997
+ let payload;
998
+ try {
999
+ payload = JSON.parse(content);
1000
+ }
1001
+ catch {
1002
+ return applySavedArtifactFallback(handle, file, content);
1003
+ }
1004
+ if (!isObject(payload)) {
1005
+ return applySavedArtifactFallback(handle, file, content);
1006
+ }
1007
+ const lines = [];
1008
+ const targets = Array.isArray(payload.targetPaths)
1009
+ ? payload.targetPaths.filter((item) => typeof item === "string" && item !== "")
1010
+ : [];
1011
+ const targetLabel = targets.length === 1
1012
+ ? toDisplayPath(cwd, targets[0])
1013
+ : targets.length > 1 ? `${targets.length} scopes` : "";
1014
+ lines.push(targetLabel ? `duplicates ${targetLabel}` : "duplicates");
1015
+ const summary = typeof payload.summary === "string"
1016
+ ? payload.summary
1017
+ : `${numberOrZero(payload.itemCount)} ${plural(numberOrZero(payload.itemCount), "name")}`;
1018
+ lines.push(summary);
1019
+ const items = Array.isArray(payload.items) ? payload.items.filter(isObject) : [];
1020
+ for (const item of items) {
1021
+ const name = typeof item.name === "string" ? item.name : "";
1022
+ const count = numberOrZero(item.declarationCount);
1023
+ const variants = numberOrZero(item.variantCount);
1024
+ const exactCopies = numberOrZero(item.exactCopyCount);
1025
+ if (name) {
1026
+ lines.push(`${name} x${count}, ${variants} ${plural(variants, "variant")}${exactCopies > 0 ? `, exact x${exactCopies}` : ""}`);
1027
+ }
1028
+ }
1029
+ const hidden = numberOrZero(payload.hiddenItemCount);
1030
+ if (hidden > 0) {
1031
+ lines.push(`+ ${hidden} ${plural(hidden, "name")}`);
1032
+ }
1033
+ lines.push(`raw: aib session where ${handle}`);
1034
+ return lines.join("\n");
1035
+ }
1036
+ function applySavedArtifactFallback(handle, file, content) {
1037
+ return [
1038
+ `saved artifact ${handle}`,
1039
+ `${content.length} bytes`,
1040
+ `raw: ${file}`
1041
+ ].join("\n");
1042
+ }
1043
+ function readSessionArtifactContent(file, content, request) {
1044
+ if (request.head !== undefined || request.offset !== undefined || request.limit !== undefined) {
1045
+ return applyReadWindow(content, request);
1046
+ }
1047
+ if (path.extname(file).toLowerCase() !== ".json") {
1048
+ return content;
1049
+ }
1050
+ try {
1051
+ return JSON.parse(content);
1052
+ }
1053
+ catch {
1054
+ return content;
1055
+ }
1056
+ }
1057
+ function formatSessionReadAgentText(response) {
1058
+ const rows = Array.isArray(response.reads) ? response.reads.filter(isObject) : [response];
1059
+ if (rows.length === 0) {
1060
+ return null;
1061
+ }
1062
+ const parts = [];
1063
+ const includeHeaders = rows.length > 1;
1064
+ for (const row of rows) {
1065
+ const handle = typeof row.read === "string" ? row.read : "";
1066
+ const content = row.content;
1067
+ const formattedContent = formatSessionReadContent(content);
1068
+ if (formattedContent !== null) {
1069
+ if (includeHeaders && handle) {
1070
+ parts.push(`// ${handle}`);
1071
+ }
1072
+ parts.push(formattedContent.trimEnd());
1073
+ continue;
1074
+ }
1075
+ if (typeof row.file === "string") {
1076
+ if (includeHeaders && handle) {
1077
+ parts.push(`// ${handle}`);
1078
+ }
1079
+ else if (handle) {
1080
+ parts.push(`input ${handle}`);
1081
+ }
1082
+ parts.push(`file: ${row.file}`);
1083
+ if (typeof row.next === "string") {
1084
+ parts.push(`next: ${row.next}`);
1085
+ }
1086
+ continue;
1087
+ }
1088
+ const error = typeof row.error === "string" ? row.error : "";
1089
+ if (error) {
1090
+ if (includeHeaders && handle) {
1091
+ parts.push(`// ${handle}`);
1092
+ }
1093
+ parts.push(`error: ${error}`);
1094
+ if (typeof row.next === "string") {
1095
+ parts.push(`next: ${row.next}`);
1096
+ }
1097
+ continue;
1098
+ }
1099
+ return null;
1100
+ }
1101
+ return parts.join("\n");
1102
+ }
1103
+ function formatSessionReadContent(content) {
1104
+ if (typeof content === "string") {
1105
+ return content;
1106
+ }
1107
+ if (content === undefined) {
1108
+ return null;
1109
+ }
1110
+ return JSON.stringify(content, null, 2);
1111
+ }
1112
+ function buildInputRerunCommand(kind, handle) {
1113
+ if (kind === "inspect") {
1114
+ return `aib inspect --from ${handle}`;
1115
+ }
1116
+ if (kind === "graph") {
1117
+ return `aib inspect graph --from ${handle}`;
1118
+ }
1119
+ if (kind === "rename") {
1120
+ return `aib mutate preview --from ${handle}`;
1121
+ }
1122
+ if (kind === "move") {
1123
+ return `aib mutate preview --from ${handle}`;
1124
+ }
1125
+ if (kind === "refactor") {
1126
+ return `aib mutate preview --from ${handle}`;
1127
+ }
1128
+ if (kind === "modulePlan") {
1129
+ return `aib mutate preview --from ${handle}`;
1130
+ }
1131
+ if (kind === "imports") {
1132
+ return `aib mutate preview --from ${handle}`;
1133
+ }
1134
+ return null;
1135
+ }
1136
+ function validateSessionReadOptions(options) {
1137
+ if (options.head !== undefined && (options.offset !== undefined || options.limit !== undefined)) {
1138
+ throw new errors_1.CliError("SESSION_READ_RANGE_CONFLICT", "Use either head or offset/limit, not both.");
1139
+ }
1140
+ }
1141
+ function readSessionReadOptions(args) {
1142
+ const row = {};
1143
+ const head = readFlagValue(args, "--head");
1144
+ const offset = readFlagValue(args, "--offset");
1145
+ const limit = readFlagValue(args, "--limit");
1146
+ if (head !== undefined) {
1147
+ row.head = head;
1148
+ }
1149
+ if (offset !== undefined) {
1150
+ row.offset = offset;
1151
+ }
1152
+ if (limit !== undefined) {
1153
+ row.limit = limit;
1154
+ }
1155
+ return {
1156
+ ...(args.includes("--raw-input") ? { rawInput: true } : {}),
1157
+ ...readSessionReadObjectOptions(row, 0)
1158
+ };
1159
+ }
1160
+ function readSessionReadObjectOptions(row, index) {
1161
+ const head = readOptionalNonNegativeInteger(row.head, `session read row at index ${index} has invalid head.`);
1162
+ const offset = readOptionalNonNegativeInteger(row.offset, `session read row at index ${index} has invalid offset.`);
1163
+ const limit = readOptionalPositiveInteger(row.limit, `session read row at index ${index} has invalid limit.`);
1164
+ return {
1165
+ ...(head !== undefined ? { head } : {}),
1166
+ ...(offset !== undefined ? { offset } : {}),
1167
+ ...(limit !== undefined ? { limit } : {})
1168
+ };
1169
+ }
1170
+ function applyReadWindow(content, options) {
1171
+ if (options.head === undefined && options.offset === undefined && options.limit === undefined) {
1172
+ return content;
1173
+ }
1174
+ const lines = content.split(/\r?\n/);
1175
+ const start = options.head !== undefined ? 0 : options.offset ?? 0;
1176
+ const end = options.head !== undefined ? options.head : options.limit !== undefined ? start + options.limit : undefined;
1177
+ return lines.slice(start, end).join("\n");
1178
+ }
1179
+ function sessionWorkspaceStatus(cwd) {
1180
+ const registry = readRegistry(cwd);
1181
+ const selected = resolveSelectedSessionForList(cwd);
1182
+ const available = registry ? Object.keys(registry.sessions).sort() : [];
1183
+ if (selected.source === "ambiguous") {
1184
+ return (0, agent_text_1.attachAgentText)({
1185
+ ok: false,
1186
+ code: "MULTIPLE_AIB_SESSIONS",
1187
+ error: "Multiple AIB sessions exist. Select one explicitly.",
1188
+ available,
1189
+ next: `Use aib -s <session> <command> or set ${env_vars_1.CLI_ENV.session}=<session>.`
1190
+ }, formatMultipleSessionsStatusText(available));
1191
+ }
1192
+ const workspace = selected.sessionId ? readWorkspaceById(cwd, selected.sessionId) : null;
1193
+ if (!workspace) {
1194
+ const response = {
1195
+ initialized: false,
1196
+ active: selected.sessionId ?? null,
1197
+ source: selected.source,
1198
+ available,
1199
+ next: selected.sessionId
1200
+ ? `Run aib session init --name ${selected.sessionId}`
1201
+ : "Run aib session init --name <name>"
1202
+ };
1203
+ return (0, agent_text_1.attachAgentText)(response, formatSessionNotReadyStatusText(response));
1204
+ }
1205
+ writeWorkspace(cwd, workspace);
1206
+ const response = {
1207
+ initialized: true,
1208
+ session: workspace.sessionId ?? selected.sessionId,
1209
+ active: workspace.sessionId ?? selected.sessionId,
1210
+ source: selected.source,
1211
+ available,
1212
+ sessionDir: toDisplayPath(cwd, workspace.rootDir),
1213
+ aliases: (0, path_aliases_1.effectivePathAliases)(cwd, workspace.pathAliases ?? {}),
1214
+ latest: latestHandles(workspace),
1215
+ dirs: sessionDirsPayload(cwd, workspace)
1216
+ };
1217
+ return (0, agent_text_1.attachAgentText)(response, formatSessionStatusText(response));
1218
+ }
1219
+ function formatSessionNotReadyStatusText(response) {
1220
+ const active = typeof response.active === "string" && response.active ? response.active : null;
1221
+ if (active) {
1222
+ return [
1223
+ "session not ready",
1224
+ "",
1225
+ `Session ${active} was not found.`,
1226
+ "Create it:",
1227
+ `aib session init --name ${active}`
1228
+ ].join("\n");
1229
+ }
1230
+ return [
1231
+ "session not ready",
1232
+ "",
1233
+ "No AIB sessions exist in this repo.",
1234
+ "Create one:",
1235
+ "aib session init --name <name>"
1236
+ ].join("\n");
1237
+ }
1238
+ function formatSessionStatusText(response) {
1239
+ const sessionId = String(response.session ?? "");
1240
+ const aliases = response.aliases && typeof response.aliases === "object" && !Array.isArray(response.aliases)
1241
+ ? response.aliases
1242
+ : {};
1243
+ const lines = [`session: ${sessionId}`];
1244
+ const aliasLines = Object.entries(aliases)
1245
+ .filter(([, target]) => typeof target === "string" && target.trim() !== "")
1246
+ .sort(([left], [right]) => left.localeCompare(right))
1247
+ .map(([name, target]) => `@${name} -> ${String(target)}`);
1248
+ if (aliasLines.length > 0) {
1249
+ lines.push("", "aliases:", ...aliasLines);
1250
+ }
1251
+ if (response.source === "single") {
1252
+ lines.push("", "Only one AIB session exists in this repo.", "You can run AIB commands without -s.");
1253
+ }
1254
+ return lines.join("\n");
1255
+ }
1256
+ function formatMultipleSessionsStatusText(available) {
1257
+ return [
1258
+ "multiple AIB sessions",
1259
+ "",
1260
+ "available:",
1261
+ ...available,
1262
+ "",
1263
+ "Choose one:",
1264
+ "aib -s <session> <command>",
1265
+ "",
1266
+ "Or bind it in this shell:",
1267
+ `${env_vars_1.CLI_ENV.session}=<session>`,
1268
+ "",
1269
+ "If none of these sessions is yours, create a new one:",
1270
+ "aib session init --name <name>"
1271
+ ].join("\n");
1272
+ }
1273
+ function clearSessionWorkspace(cwd) {
1274
+ const selected = resolveSelectedSessionForList(cwd);
1275
+ const registry = readRegistry(cwd);
1276
+ const available = registry ? Object.keys(registry.sessions).sort() : [];
1277
+ if (selected.source === "ambiguous") {
1278
+ return (0, agent_text_1.attachAgentText)({
1279
+ ok: false,
1280
+ code: "MULTIPLE_AIB_SESSIONS",
1281
+ error: "Multiple AIB sessions exist. Select one explicitly.",
1282
+ available,
1283
+ next: "Use aib -s <session> session clear."
1284
+ }, formatMultipleSessionsClearText(available));
1285
+ }
1286
+ const workspace = selected.sessionId ? readWorkspaceById(cwd, selected.sessionId) : null;
1287
+ if (!workspace) {
1288
+ return (0, agent_text_1.attachAgentText)({
1289
+ cleared: false,
1290
+ reason: "session-not-initialized"
1291
+ }, [
1292
+ "No AIB sessions exist in this repo.",
1293
+ "",
1294
+ "Create one:",
1295
+ "aib session init --name <name>"
1296
+ ].join("\n"));
1297
+ }
1298
+ pruneSessionWorkspaceData(workspace, { touch: true });
1299
+ writeWorkspace(cwd, workspace);
1300
+ const sessionId = workspace.sessionId ?? selected.sessionId ?? "";
1301
+ return (0, agent_text_1.attachAgentText)({
1302
+ cleared: true,
1303
+ session: sessionId,
1304
+ dir: toDisplayPath(cwd, workspace.rootDir)
1305
+ }, [
1306
+ `session cleared: ${sessionId}`,
1307
+ "",
1308
+ "Inputs and outputs were pruned.",
1309
+ "You can keep using this session."
1310
+ ].join("\n"));
1311
+ }
1312
+ function pruneSessionWorkspaceData(workspace, options) {
1313
+ fs.rmSync(path.join(workspace.rootDir, "inputs"), { recursive: true, force: true });
1314
+ fs.rmSync(path.join(workspace.rootDir, "outputs"), { recursive: true, force: true });
1315
+ workspace.inputs = {};
1316
+ workspace.outputs = {};
1317
+ workspace.guidance = {};
1318
+ if (options.touch) {
1319
+ workspace.updatedAt = new Date().toISOString();
1320
+ }
1321
+ ensureWorkspaceDirs(workspace);
1322
+ }
1323
+ function formatMultipleSessionsClearText(available) {
1324
+ return [
1325
+ "multiple AIB sessions",
1326
+ "",
1327
+ "available:",
1328
+ ...available,
1329
+ "",
1330
+ "Clear one explicitly only if it is yours:",
1331
+ "aib -s <session> session clear",
1332
+ "",
1333
+ "If none of these sessions is yours, create a new one:",
1334
+ "aib session init --name <name>"
1335
+ ].join("\n");
1336
+ }
1337
+ function cleanupExpiredSessions(cwd) {
1338
+ const policy = readSessionTtlPolicy(cwd);
1339
+ const registry = readRegistry(cwd);
1340
+ if (!registry) {
1341
+ return;
1342
+ }
1343
+ const now = Date.now();
1344
+ let changed = false;
1345
+ for (const [sessionId, entry] of Object.entries(registry.sessions)) {
1346
+ const sessionFile = workspaceFilePath(entry.rootDir);
1347
+ if (!fs.existsSync(sessionFile)) {
1348
+ delete registry.sessions[sessionId];
1349
+ changed = true;
1350
+ if (registry.activeSessionId === sessionId) {
1351
+ delete registry.activeSessionId;
1352
+ }
1353
+ continue;
1354
+ }
1355
+ const updatedAt = Date.parse(entry.updatedAt);
1356
+ if (!Number.isFinite(updatedAt)) {
1357
+ continue;
1358
+ }
1359
+ const inactiveMs = now - updatedAt;
1360
+ if (policy.autoDelete && policy.ttlDeleteMs > 0 && inactiveMs > policy.ttlDeleteMs) {
1361
+ fs.rmSync(entry.rootDir, { recursive: true, force: true });
1362
+ delete registry.sessions[sessionId];
1363
+ changed = true;
1364
+ if (registry.activeSessionId === sessionId) {
1365
+ delete registry.activeSessionId;
1366
+ }
1367
+ continue;
1368
+ }
1369
+ if (policy.autoClean && policy.ttlCleanMs > 0 && inactiveMs > policy.ttlCleanMs) {
1370
+ const workspace = readWorkspaceFile(cwd, entry.rootDir, sessionId);
1371
+ if (workspace) {
1372
+ pruneSessionWorkspaceData(workspace, { touch: false });
1373
+ writeWorkspacePreservingTimestamp(workspace);
1374
+ }
1375
+ }
1376
+ }
1377
+ if (!changed) {
1378
+ return;
1379
+ }
1380
+ if (!registry.activeSessionId) {
1381
+ const nextSessionId = Object.keys(registry.sessions).sort()[0];
1382
+ if (nextSessionId) {
1383
+ registry.activeSessionId = nextSessionId;
1384
+ }
1385
+ }
1386
+ writeRegistry(cwd, registry);
1387
+ }
1388
+ function readSessionTtlPolicy(cwd) {
1389
+ const legacyTtlMinutes = (0, workspace_root_1.readWorkspaceNumberConfig)(cwd, "session.ttlMinutes", 60);
1390
+ const ttlDeleteMinutes = (0, workspace_root_1.readWorkspaceNumberConfig)(cwd, "session.ttlDeleteMinutes", legacyTtlMinutes);
1391
+ const ttlCleanMinutes = (0, workspace_root_1.readWorkspaceNumberConfig)(cwd, "session.ttlCleanMinutes", legacyTtlMinutes);
1392
+ return {
1393
+ autoDelete: (0, workspace_root_1.readWorkspaceBooleanConfig)(cwd, "session.autoDelete", true),
1394
+ ttlDeleteMs: ttlDeleteMinutes > 0 ? ttlDeleteMinutes * 60_000 : 0,
1395
+ autoClean: (0, workspace_root_1.readWorkspaceBooleanConfig)(cwd, "session.autoClean", true),
1396
+ ttlCleanMs: ttlCleanMinutes > 0 ? ttlCleanMinutes * 60_000 : 0
1397
+ };
1398
+ }
1399
+ function ensureWorkspaceDirs(workspace) {
1400
+ for (const kind of OUTPUT_KINDS) {
1401
+ fs.mkdirSync(path.join(workspace.rootDir, "outputs", kind), { recursive: true });
1402
+ }
1403
+ for (const kind of INPUT_KINDS) {
1404
+ fs.mkdirSync(path.join(workspace.rootDir, "inputs", kind), { recursive: true });
1405
+ }
1406
+ }
1407
+ function readWorkspaceById(cwd, sessionId) {
1408
+ const registry = readRegistry(cwd);
1409
+ const entry = registry?.sessions[sessionId];
1410
+ if (!entry) {
1411
+ return null;
1412
+ }
1413
+ return readWorkspaceFile(cwd, entry.rootDir, sessionId);
1414
+ }
1415
+ function readWorkspace(cwd) {
1416
+ const selected = resolveSelectedSession(cwd);
1417
+ return selected.sessionId ? readWorkspaceById(cwd, selected.sessionId) : null;
1418
+ }
1419
+ function readWorkspaceForSave(cwd) {
1420
+ cleanupExpiredSessions(cwd);
1421
+ const workspace = readWorkspace(cwd);
1422
+ return workspace ?? createDefaultSessionWorkspace(cwd);
1423
+ }
1424
+ function createDefaultSessionWorkspace(cwd) {
1425
+ const workspaceRoot = (0, workspace_root_1.resolveWorkspaceRoot)(cwd);
1426
+ if (!workspaceRoot) {
1427
+ return null;
1428
+ }
1429
+ const sessionRoot = resolveSessionRoot(workspaceRoot.root, undefined, false);
1430
+ const rootDir = path.join(sessionRoot.rootDir, DEFAULT_AUTO_SESSION_ID);
1431
+ const now = new Date().toISOString();
1432
+ const existing = readWorkspaceFile(workspaceRoot.root, rootDir, DEFAULT_AUTO_SESSION_ID);
1433
+ const workspace = existing ?? {
1434
+ version: 1,
1435
+ sessionId: DEFAULT_AUTO_SESSION_ID,
1436
+ auto: true,
1437
+ cwd: path.resolve(workspaceRoot.root),
1438
+ rootDir,
1439
+ createdAt: now,
1440
+ updatedAt: now,
1441
+ outputs: {},
1442
+ inputs: {},
1443
+ guidance: {}
1444
+ };
1445
+ workspace.sessionId = DEFAULT_AUTO_SESSION_ID;
1446
+ workspace.auto = true;
1447
+ workspace.cwd = path.resolve(workspaceRoot.root);
1448
+ workspace.rootDir = rootDir;
1449
+ workspace.updatedAt = now;
1450
+ ensureWorkspaceDirs(workspace);
1451
+ writeWorkspace(workspaceRoot.root, workspace);
1452
+ return workspace;
1453
+ }
1454
+ function readWorkspaceFile(cwd, rootDir, sessionId) {
1455
+ try {
1456
+ const parsed = JSON.parse(fs.readFileSync(workspaceFilePath(rootDir), "utf8"));
1457
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
1458
+ return null;
1459
+ }
1460
+ const candidate = parsed;
1461
+ if (candidate.version !== 1 || typeof candidate.rootDir !== "string") {
1462
+ return null;
1463
+ }
1464
+ candidate.sessionId = candidate.sessionId ?? sessionId;
1465
+ return candidate;
1466
+ }
1467
+ catch {
1468
+ return null;
1469
+ }
1470
+ }
1471
+ function readRequiredWorkspace(cwd) {
1472
+ const workspace = readWorkspace(cwd);
1473
+ if (!workspace) {
1474
+ throw new errors_1.CliError("SESSION_WORKSPACE_NOT_INITIALIZED", "Session workspace is not initialized.", {
1475
+ session: currentSessionId() ?? null,
1476
+ next: "Run aib session init --name <name>",
1477
+ help: "aib help session"
1478
+ });
1479
+ }
1480
+ writeWorkspace(cwd, workspace);
1481
+ return workspace;
1482
+ }
1483
+ function readRequiredWorkspaceForSave(cwd) {
1484
+ const workspace = readWorkspaceForSave(cwd);
1485
+ if (!workspace) {
1486
+ throw new errors_1.CliError("SESSION_WORKSPACE_NOT_INITIALIZED", "Session workspace is not initialized.", {
1487
+ session: currentSessionId() ?? null,
1488
+ next: "Run aib session init --name <name>",
1489
+ help: "aib help session"
1490
+ });
1491
+ }
1492
+ return workspace;
1493
+ }
1494
+ function writeWorkspace(cwd, workspace) {
1495
+ workspace.updatedAt = new Date().toISOString();
1496
+ fs.mkdirSync(workspace.rootDir, { recursive: true });
1497
+ fs.writeFileSync(workspaceFilePath(workspace.rootDir), `${JSON.stringify(workspace, null, 2)}\n`);
1498
+ upsertRegistrySession(cwd, workspace, false);
1499
+ }
1500
+ function writeWorkspacePreservingTimestamp(workspace) {
1501
+ fs.mkdirSync(workspace.rootDir, { recursive: true });
1502
+ fs.writeFileSync(workspaceFilePath(workspace.rootDir), `${JSON.stringify(workspace, null, 2)}\n`);
1503
+ }
1504
+ function resolveSessionRoot(cwd, requestedDir, persistDefault = false) {
1505
+ const workspace = (0, workspace_root_1.resolveWorkspaceRoot)(cwd);
1506
+ const workspaceRoot = workspace?.root ?? cwd;
1507
+ const configuredDir = workspace ? readString(workspace.config[SESSION_DIR_CONFIG_KEY]) : undefined;
1508
+ if (configuredDir) {
1509
+ return {
1510
+ rootDir: normalizeSessionRootDir(workspaceRoot, configuredDir),
1511
+ source: "aib.json",
1512
+ ...(requestedDir ? { ignoredRequestedDir: requestedDir } : {})
1513
+ };
1514
+ }
1515
+ const rawDir = requestedDir ?? DEFAULT_SESSION_ROOT;
1516
+ const rootDir = normalizeSessionRootDir(workspaceRoot, rawDir);
1517
+ if (persistDefault && workspace) {
1518
+ (0, workspace_root_1.updateWorkspaceConfig)(workspaceRoot, {
1519
+ [SESSION_DIR_CONFIG_KEY]: toConfigRelativePath(workspaceRoot, rootDir)
1520
+ });
1521
+ }
1522
+ return {
1523
+ rootDir,
1524
+ source: requestedDir ? "request" : "default"
1525
+ };
1526
+ }
1527
+ function normalizeSessionRootDir(workspaceRoot, rawDir) {
1528
+ const resolved = path.resolve(workspaceRoot, rawDir);
1529
+ return path.basename(resolved).toLowerCase() === "aib" ? resolved : path.join(resolved, "aib");
1530
+ }
1531
+ function toConfigRelativePath(workspaceRoot, filePath) {
1532
+ const relative = path.relative(workspaceRoot, filePath);
1533
+ return relative && !relative.startsWith("..") && !path.isAbsolute(relative)
1534
+ ? relative.replace(/\\/g, "/")
1535
+ : filePath.replace(/\\/g, "/");
1536
+ }
1537
+ function workspaceMarkerPath(cwd) {
1538
+ return path.join(resolveSessionRoot(cwd).rootDir, SESSION_REGISTRY_FILE_NAME);
1539
+ }
1540
+ function activeSessionPath(cwd) {
1541
+ return path.join(resolveSessionRoot(cwd).rootDir, ACTIVE_SESSION_FILE_NAME);
1542
+ }
1543
+ function workspaceFilePath(rootDir) {
1544
+ return path.join(rootDir, "session.json");
1545
+ }
1546
+ function readRegistry(cwd) {
1547
+ try {
1548
+ const parsed = JSON.parse(fs.readFileSync(workspaceMarkerPath(cwd), "utf8"));
1549
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
1550
+ return null;
1551
+ }
1552
+ const candidate = parsed;
1553
+ if (candidate.version !== 1 || !candidate.sessions || typeof candidate.sessions !== "object") {
1554
+ return null;
1555
+ }
1556
+ return {
1557
+ version: 1,
1558
+ cwd: typeof candidate.cwd === "string" ? candidate.cwd : path.resolve(cwd),
1559
+ ...(typeof candidate.activeSessionId === "string" ? { activeSessionId: candidate.activeSessionId } : {}),
1560
+ sessions: candidate.sessions
1561
+ };
1562
+ }
1563
+ catch {
1564
+ return null;
1565
+ }
1566
+ }
1567
+ function writeRegistry(cwd, registry) {
1568
+ registry.cwd = path.resolve((0, workspace_root_1.resolveWorkspaceRoot)(cwd)?.root ?? cwd);
1569
+ fs.mkdirSync(path.dirname(workspaceMarkerPath(cwd)), { recursive: true });
1570
+ fs.writeFileSync(workspaceMarkerPath(cwd), `${JSON.stringify(registry, null, 2)}\n`);
1571
+ writeActiveSession(cwd, registry.activeSessionId);
1572
+ }
1573
+ function createEmptyRegistry(cwd) {
1574
+ return {
1575
+ version: 1,
1576
+ cwd: path.resolve(cwd),
1577
+ sessions: {}
1578
+ };
1579
+ }
1580
+ function writeActiveSession(cwd, sessionId) {
1581
+ const file = activeSessionPath(cwd);
1582
+ fs.mkdirSync(path.dirname(file), { recursive: true });
1583
+ if (!sessionId) {
1584
+ fs.rmSync(file, { force: true });
1585
+ return;
1586
+ }
1587
+ fs.writeFileSync(file, `${JSON.stringify({ sessionId, updatedAt: new Date().toISOString() }, null, 2)}\n`);
1588
+ }
1589
+ function upsertRegistrySession(cwd, workspace, makeActive) {
1590
+ const sessionId = workspace.sessionId ?? currentSessionId() ?? "";
1591
+ if (!sessionId) {
1592
+ return;
1593
+ }
1594
+ const registry = readRegistry(cwd) ?? createEmptyRegistry(cwd);
1595
+ registry.sessions[sessionId] = {
1596
+ sessionId,
1597
+ ...(workspace.auto ? { auto: true } : {}),
1598
+ rootDir: workspace.rootDir,
1599
+ createdAt: registry.sessions[sessionId]?.createdAt ?? workspace.createdAt,
1600
+ updatedAt: workspace.updatedAt
1601
+ };
1602
+ if (makeActive || !registry.activeSessionId) {
1603
+ registry.activeSessionId = sessionId;
1604
+ }
1605
+ writeRegistry(cwd, registry);
1606
+ }
1607
+ function removeRegistrySession(cwd, sessionId) {
1608
+ const registry = readRegistry(cwd);
1609
+ if (!registry || !sessionId) {
1610
+ return;
1611
+ }
1612
+ delete registry.sessions[sessionId];
1613
+ if (registry.activeSessionId === sessionId) {
1614
+ const nextSessionId = Object.keys(registry.sessions).sort()[0];
1615
+ if (nextSessionId) {
1616
+ registry.activeSessionId = nextSessionId;
1617
+ }
1618
+ else {
1619
+ delete registry.activeSessionId;
1620
+ }
1621
+ }
1622
+ writeRegistry(cwd, registry);
1623
+ }
1624
+ function resolveSelectedSession(cwd) {
1625
+ const override = sessionOverrideStorage.getStore();
1626
+ if (override) {
1627
+ return { sessionId: sanitizeSessionId(override), source: "override" };
1628
+ }
1629
+ const envSession = process.env[env_vars_1.CLI_ENV.session];
1630
+ if (envSession && envSession.trim()) {
1631
+ return { sessionId: sanitizeSessionId(envSession), source: "env" };
1632
+ }
1633
+ const legacyEnvSession = process.env[env_vars_1.CLI_ENV.legacySession];
1634
+ if (legacyEnvSession && legacyEnvSession.trim()) {
1635
+ return { sessionId: sanitizeSessionId(legacyEnvSession), source: "legacy-env" };
1636
+ }
1637
+ const registry = readRegistry(cwd);
1638
+ const sessions = registry ? Object.keys(registry.sessions).sort() : [];
1639
+ if (sessions.length === 1) {
1640
+ return { sessionId: sessions[0], source: "single" };
1641
+ }
1642
+ if (sessions.length > 1) {
1643
+ throw new errors_1.CliError("MULTIPLE_AIB_SESSIONS", "Multiple AIB sessions exist. Select one explicitly.", {
1644
+ available: sessions,
1645
+ next: `Use aib -s <session> <command> or set ${env_vars_1.CLI_ENV.session}=<session>.`
1646
+ });
1647
+ }
1648
+ return { sessionId: null, source: "none" };
1649
+ }
1650
+ function resolveSelectedSessionForList(cwd) {
1651
+ try {
1652
+ return resolveSelectedSession(cwd);
1653
+ }
1654
+ catch (error) {
1655
+ if (error instanceof errors_1.CliError && error.code === "MULTIPLE_AIB_SESSIONS") {
1656
+ return { sessionId: null, source: "ambiguous" };
1657
+ }
1658
+ throw error;
1659
+ }
1660
+ }
1661
+ function tryResolveCurrentSessionId(cwd) {
1662
+ const selected = resolveSelectedSessionForList(cwd);
1663
+ return {
1664
+ sessionId: selected.sessionId,
1665
+ sessionSource: selected.source
1666
+ };
1667
+ }
1668
+ function currentSessionId() {
1669
+ const override = sessionOverrideStorage.getStore();
1670
+ if (override) {
1671
+ return sanitizeSessionId(override);
1672
+ }
1673
+ const envSession = process.env[env_vars_1.CLI_ENV.session];
1674
+ if (envSession && envSession.trim()) {
1675
+ return sanitizeSessionId(envSession);
1676
+ }
1677
+ const legacyEnvSession = process.env[env_vars_1.CLI_ENV.legacySession];
1678
+ return legacyEnvSession && legacyEnvSession.trim() ? sanitizeSessionId(legacyEnvSession) : null;
1679
+ }
1680
+ function sessionOutputPath(workspace, kind, name, extension) {
1681
+ return path.join(workspace.rootDir, "outputs", sanitizePathSegment(kind), `${sanitizePathSegment(name)}${sanitizeExtension(extension)}`);
1682
+ }
1683
+ function sessionInputPath(workspace, kind, name, extension = ".json") {
1684
+ return path.join(workspace.rootDir, "inputs", sanitizePathSegment(kind), `${sanitizePathSegment(name)}${sanitizeExtension(extension)}`);
1685
+ }
1686
+ function sessionCompiledInputPath(workspace, kind, name) {
1687
+ return path.join(workspace.rootDir, "inputs", sanitizePathSegment(kind), `${sanitizePathSegment(name)}.compiled.json`);
1688
+ }
1689
+ function sessionLastInputPath(workspace, kind, extension = ".json") {
1690
+ return path.join(workspace.rootDir, "inputs", sanitizePathSegment(kind), extension === ".json" ? LAST_INPUT_FILE_NAME : `_last${sanitizeExtension(extension)}`);
1691
+ }
1692
+ function writeJsonFile(file, value) {
1693
+ fs.mkdirSync(path.dirname(file), { recursive: true });
1694
+ fs.writeFileSync(file, `${JSON.stringify(value, null, 2)}\n`);
1695
+ }
1696
+ function writeTextFile(file, value) {
1697
+ fs.mkdirSync(path.dirname(file), { recursive: true });
1698
+ fs.writeFileSync(file, value.endsWith("\n") ? value : `${value}\n`, "utf8");
1699
+ }
1700
+ function registerLastInputArtifact(workspace, kind, value, source) {
1701
+ const normalizedKind = sanitizePathSegment(kind);
1702
+ const inputSource = source ?? { format: "json", text: JSON.stringify(value, null, 2) };
1703
+ const file = inputSource.format === "dsl"
1704
+ ? sessionLastInputPath(workspace, normalizedKind, ".dsl")
1705
+ : sessionLastInputPath(workspace, normalizedKind, ".json");
1706
+ if (inputSource.format === "dsl") {
1707
+ writeTextFile(file, inputSource.text);
1708
+ writeJsonFile(path.join(workspace.rootDir, "inputs", normalizedKind, "_last.compiled.json"), value);
1709
+ fs.rmSync(sessionLastInputPath(workspace, normalizedKind, ".json"), { force: true });
1710
+ }
1711
+ else {
1712
+ writeJsonFile(file, value);
1713
+ fs.rmSync(sessionLastInputPath(workspace, normalizedKind, ".dsl"), { force: true });
1714
+ fs.rmSync(path.join(workspace.rootDir, "inputs", normalizedKind, "_last.compiled.json"), { force: true });
1715
+ }
1716
+ registerArtifact(workspace, "inputs", normalizedKind, LAST_INPUT_NAME, file);
1717
+ }
1718
+ function registerArtifact(workspace, group, kind, name, file) {
1719
+ const normalizedKind = sanitizePathSegment(kind);
1720
+ const normalizedName = sanitizePathSegment(name);
1721
+ const handle = group === "inputs"
1722
+ ? `aib:input:${normalizedKind}:${normalizedName}`
1723
+ : `aib:${normalizedKind}:${normalizedName}`;
1724
+ const now = new Date().toISOString();
1725
+ const buckets = workspace[group];
1726
+ const bucket = buckets[normalizedKind] ?? { items: {} };
1727
+ const artifact = {
1728
+ handle,
1729
+ file,
1730
+ createdAt: bucket.items[normalizedName]?.createdAt ?? now,
1731
+ updatedAt: now
1732
+ };
1733
+ bucket.items[normalizedName] = artifact;
1734
+ bucket.last = normalizedName;
1735
+ buckets[normalizedKind] = bucket;
1736
+ return artifact;
1737
+ }
1738
+ function parseSessionHandle(handle) {
1739
+ const parts = handle.split(":");
1740
+ if (parts[0] !== "aib") {
1741
+ throw new errors_1.CliError("INVALID_SESSION_HANDLE", `Invalid session handle: ${handle}`);
1742
+ }
1743
+ if (parts[1] === "input" && parts.length === 4) {
1744
+ return { scope: "input", kind: parts[2] ?? "", name: parts[3] ?? "" };
1745
+ }
1746
+ if (parts.length === 3) {
1747
+ return { scope: parts[1] ?? "", kind: parts[1] ?? "", name: parts[2] ?? "" };
1748
+ }
1749
+ throw new errors_1.CliError("INVALID_SESSION_HANDLE", `Invalid session handle: ${handle}`, {
1750
+ expected: "aib:<kind>:<name> or aib:input:<kind>:<name>"
1751
+ });
1752
+ }
1753
+ function latestHandles(workspace) {
1754
+ const latest = {};
1755
+ for (const [kind, bucket] of Object.entries(workspace.outputs)) {
1756
+ if (bucket.last) {
1757
+ latest[kind] = `aib:${kind}:${bucket.last}`;
1758
+ }
1759
+ }
1760
+ for (const [kind, bucket] of Object.entries(workspace.inputs)) {
1761
+ if (bucket.last) {
1762
+ latest[`input:${kind}`] = `aib:input:${kind}:${bucket.last}`;
1763
+ }
1764
+ }
1765
+ return latest;
1766
+ }
1767
+ function sessionDirsPayload(cwd, workspace) {
1768
+ return {
1769
+ outputs: toDisplayPath(cwd, path.join(workspace.rootDir, "outputs")),
1770
+ inputs: toDisplayPath(cwd, path.join(workspace.rootDir, "inputs"))
1771
+ };
1772
+ }
1773
+ function readFlagValue(args, flag) {
1774
+ const index = args.indexOf(flag);
1775
+ return index >= 0 ? args[index + 1] : undefined;
1776
+ }
1777
+ function readString(value) {
1778
+ return typeof value === "string" && value.trim() !== "" ? value.trim() : undefined;
1779
+ }
1780
+ function readOptionalNonNegativeInteger(value, message) {
1781
+ if (value === undefined) {
1782
+ return undefined;
1783
+ }
1784
+ const parsed = typeof value === "number" ? value : typeof value === "string" ? Number(value) : Number.NaN;
1785
+ if (!Number.isInteger(parsed) || parsed < 0) {
1786
+ throw new errors_1.CliError("INVALID_SESSION_READ_RANGE", message);
1787
+ }
1788
+ return parsed;
1789
+ }
1790
+ function readOptionalPositiveInteger(value, message) {
1791
+ if (value === undefined) {
1792
+ return undefined;
1793
+ }
1794
+ const parsed = readOptionalNonNegativeInteger(value, message);
1795
+ if (parsed === undefined) {
1796
+ return undefined;
1797
+ }
1798
+ if (parsed <= 0) {
1799
+ throw new errors_1.CliError("INVALID_SESSION_READ_RANGE", message);
1800
+ }
1801
+ return parsed;
1802
+ }
1803
+ function isObject(value) {
1804
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1805
+ }
1806
+ function sanitizePathSegment(value) {
1807
+ const sanitized = value.trim().replace(/[^A-Za-z0-9._-]/g, "-").replace(/^-+|-+$/g, "");
1808
+ if (!sanitized) {
1809
+ throw new errors_1.CliError("INVALID_SESSION_ARTIFACT_NAME", `Invalid session artifact name: ${value}`);
1810
+ }
1811
+ return sanitized;
1812
+ }
1813
+ function sanitizeSessionId(value) {
1814
+ const sanitized = value.trim().replace(/[^A-Za-z0-9._-]/g, "-").replace(/^-+|-+$/g, "");
1815
+ if (!sanitized) {
1816
+ throw new errors_1.CliError("INVALID_SESSION_ID", `Invalid session id: ${value}`);
1817
+ }
1818
+ return sanitized;
1819
+ }
1820
+ function createSessionId() {
1821
+ return `${SESSION_ID_PREFIX}${Math.random().toString(16).slice(2, 8)}`;
1822
+ }
1823
+ function sanitizeExtension(value) {
1824
+ const extension = value.startsWith(".") ? value : `.${value}`;
1825
+ return extension.replace(/[^A-Za-z0-9.]/g, "") || ".txt";
1826
+ }
1827
+ function numberOrZero(value) {
1828
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
1829
+ }
1830
+ function plural(count, singular) {
1831
+ return count === 1 ? singular : `${singular}s`;
1832
+ }
1833
+ function toDisplayPath(cwd, filePath) {
1834
+ const relative = path.relative(cwd, filePath);
1835
+ return relative && !relative.startsWith("..") ? relative.replace(/\\/g, "/") : filePath;
1836
+ }