@automaton-labs/aib 0.0.6 → 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 (586) 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 -2
  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 -0
  19. package/dist/commands/captured-input.js +74 -2
  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 -0
  23. package/dist/commands/declaration-command.js +1209 -0
  24. package/dist/commands/declaration-execution-cache.js +79 -0
  25. package/dist/commands/declaration-format.js +221 -0
  26. package/dist/commands/declaration-preview-cache.js +114 -0
  27. package/dist/commands/diagnostics-command.js +70 -3
  28. package/dist/commands/doctor.js +137 -2
  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 -0
  35. package/dist/commands/file-move-to-dir-preview-cache.js +125 -0
  36. package/dist/commands/file-move-to-dir-worker.js +54 -0
  37. package/dist/commands/file-move-to-dir.js +1073 -0
  38. package/dist/commands/file-mutation-runtime.js +102 -0
  39. package/dist/commands/file-mutation-worker-apply.js +180 -0
  40. package/dist/commands/file-refactor-batch-execution-cache.js +90 -0
  41. package/dist/commands/file-refactor-batch-preview-cache.js +125 -0
  42. package/dist/commands/file-refactor-batch-worker.js +54 -0
  43. package/dist/commands/file-refactor-batch.js +1154 -0
  44. package/dist/commands/file-rename-execution-cache.js +92 -0
  45. package/dist/commands/file-rename-preview-cache.js +125 -0
  46. package/dist/commands/file-rename-worker.js +54 -0
  47. package/dist/commands/file-rename.js +1053 -0
  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 -0
  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 -6
  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 -0
  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 -0
  150. package/dist/dsl/file-move-to-dir-dsl.js +123 -0
  151. package/dist/dsl/file-refactor-batch-dsl.js +203 -0
  152. package/dist/dsl/file-rename-dsl.js +135 -0
  153. package/dist/dsl/mutate-dsl.js +746 -0
  154. package/dist/help/bootstrap.bash.md +742 -0
  155. package/dist/help/bootstrap.md +236 -437
  156. package/dist/help/bootstrap.pwsh.md +742 -0
  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/dsl.md +4 -3
  161. package/dist/help/docs/first-setup.md +6 -5
  162. package/dist/help/docs/help-protocol.md +4 -3
  163. package/dist/help/docs/import.base.md +38 -0
  164. package/dist/help/docs/import.rebase.md +85 -0
  165. package/dist/help/docs/inspect.aliasCandidates.md +39 -0
  166. package/dist/help/docs/inspect.code.md +5 -11
  167. package/dist/help/docs/inspect.deps.md +7 -7
  168. package/dist/help/docs/inspect.file.md +10 -18
  169. package/dist/help/docs/inspect.graph.md +6 -20
  170. package/dist/help/docs/{inspect.md → inspect.shared.md} +18 -17
  171. package/dist/help/docs/modulePlan.md +24 -28
  172. package/dist/help/docs/move.md +19 -22
  173. package/dist/help/docs/moveToDir.md +46 -0
  174. package/dist/help/docs/mutate.mixed.md +34 -0
  175. package/dist/help/docs/mutation.shared.md +55 -0
  176. package/dist/help/docs/patterns.md +3 -16
  177. package/dist/help/docs/qr.md +13 -22
  178. package/dist/help/docs/quick-map.md +36 -23
  179. package/dist/help/docs/recipe.file-layout.md +15 -0
  180. package/dist/help/docs/recipe.import-boundary.md +92 -0
  181. package/dist/help/docs/recipe.safe-artifact-probing.md +68 -0
  182. package/dist/help/docs/recipe.unfamiliar-area.md +64 -0
  183. package/dist/help/docs/recipes.md +20 -0
  184. package/dist/help/docs/rename.md +19 -27
  185. package/dist/help/docs/renameFile.md +36 -0
  186. package/dist/help/docs/rg.md +22 -0
  187. package/dist/help/docs/rules.md +26 -0
  188. package/dist/help/docs/selectors.md +3 -2
  189. package/dist/help/docs/session.md +1 -1
  190. package/dist/help/dsl/bootstrap.bash.md +742 -0
  191. package/dist/help/dsl/bootstrap.md +236 -437
  192. package/dist/help/dsl/bootstrap.pwsh.md +742 -0
  193. package/dist/help/dsl/docs/basics.md +1 -1
  194. package/dist/help/dsl/docs/config-setup.import-normalize.md +65 -65
  195. package/dist/help/dsl/docs/config-setup.import-rules.md +6 -5
  196. package/dist/help/dsl/docs/dsl.md +4 -3
  197. package/dist/help/dsl/docs/first-setup.md +6 -5
  198. package/dist/help/dsl/docs/help-protocol.md +4 -3
  199. package/dist/help/dsl/docs/import.base.md +38 -0
  200. package/dist/help/dsl/docs/import.rebase.md +85 -0
  201. package/dist/help/dsl/docs/inspect.aliasCandidates.md +39 -0
  202. package/dist/help/dsl/docs/inspect.code.md +5 -11
  203. package/dist/help/dsl/docs/inspect.deps.md +7 -7
  204. package/dist/help/dsl/docs/inspect.file.md +10 -18
  205. package/dist/help/dsl/docs/inspect.graph.md +6 -20
  206. package/dist/help/dsl/docs/{inspect.md → inspect.shared.md} +18 -17
  207. package/dist/help/dsl/docs/modulePlan.md +24 -28
  208. package/dist/help/dsl/docs/move.md +19 -22
  209. package/dist/help/dsl/docs/moveToDir.md +46 -0
  210. package/dist/help/dsl/docs/mutate.mixed.md +34 -0
  211. package/dist/help/dsl/docs/mutation.shared.md +55 -0
  212. package/dist/help/dsl/docs/patterns.md +3 -16
  213. package/dist/help/dsl/docs/qr.md +13 -22
  214. package/dist/help/dsl/docs/quick-map.md +36 -23
  215. package/dist/help/dsl/docs/recipe.file-layout.md +15 -0
  216. package/dist/help/dsl/docs/recipe.import-boundary.md +92 -0
  217. package/dist/help/dsl/docs/recipe.safe-artifact-probing.md +68 -0
  218. package/dist/help/dsl/docs/recipe.unfamiliar-area.md +64 -0
  219. package/dist/help/dsl/docs/recipes.md +20 -0
  220. package/dist/help/dsl/docs/rename.md +19 -27
  221. package/dist/help/dsl/docs/renameFile.md +36 -0
  222. package/dist/help/dsl/docs/rg.md +22 -0
  223. package/dist/help/dsl/docs/rules.md +26 -0
  224. package/dist/help/dsl/docs/selectors.md +3 -2
  225. package/dist/help/dsl/docs/session.md +1 -1
  226. package/dist/help/dsl/full.md +236 -437
  227. package/dist/help/dsl/help-index.md +49 -0
  228. package/dist/help/dsl/snippets/agents.md +2 -2
  229. package/dist/help/dsl/tokens/qr.inline.examples.md +2 -0
  230. package/dist/help/dsl/tokens/stdin.examples.bash.md +8 -0
  231. package/dist/help/dsl/tokens/stdin.examples.pwsh.md +8 -0
  232. package/dist/help/dsl/tokens/stdin.examples.with-qr.bash.md +12 -0
  233. package/dist/help/dsl/tokens/stdin.examples.with-qr.pwsh.md +12 -0
  234. package/dist/help/dsl/topics/basics.md +1 -1
  235. package/dist/help/dsl/topics/config-setup.import-normalize.md +65 -65
  236. package/dist/help/dsl/topics/config-setup.import-rules.md +6 -5
  237. package/dist/help/dsl/topics/dsl.md +4 -3
  238. package/dist/help/dsl/topics/first-setup.md +6 -5
  239. package/dist/help/dsl/topics/help-protocol.md +4 -3
  240. package/dist/help/dsl/topics/import.base.md +36 -0
  241. package/dist/help/dsl/topics/import.rebase.md +83 -0
  242. package/dist/help/dsl/topics/inspect.aliasCandidates.md +37 -0
  243. package/dist/help/dsl/topics/inspect.code.md +5 -11
  244. package/dist/help/dsl/topics/inspect.deps.md +7 -7
  245. package/dist/help/dsl/topics/inspect.file.md +10 -18
  246. package/dist/help/dsl/topics/inspect.graph.md +6 -20
  247. package/dist/help/dsl/topics/{inspect.md → inspect.shared.md} +18 -17
  248. package/dist/help/dsl/topics/modulePlan.md +21 -26
  249. package/dist/help/dsl/topics/move.md +17 -18
  250. package/dist/help/dsl/topics/moveToDir.md +44 -0
  251. package/dist/help/dsl/topics/mutate.mixed.md +32 -0
  252. package/dist/help/dsl/topics/mutation.shared.md +53 -0
  253. package/dist/help/dsl/topics/patterns.md +3 -16
  254. package/dist/help/dsl/topics/qr.md +13 -22
  255. package/dist/help/dsl/topics/quick-map.md +36 -23
  256. package/dist/help/dsl/topics/recipe.file-layout.md +13 -0
  257. package/dist/help/dsl/topics/recipe.import-boundary.md +90 -0
  258. package/dist/help/dsl/topics/recipe.safe-artifact-probing.md +66 -0
  259. package/dist/help/dsl/topics/recipe.unfamiliar-area.md +62 -0
  260. package/dist/help/dsl/topics/recipes.md +18 -0
  261. package/dist/help/dsl/topics/rename.md +15 -15
  262. package/dist/help/dsl/topics/renameFile.md +34 -0
  263. package/dist/help/dsl/topics/rg.md +20 -0
  264. package/dist/help/dsl/topics/rules.md +24 -0
  265. package/dist/help/dsl/topics/selectors.md +3 -2
  266. package/dist/help/dsl/topics/session.md +1 -1
  267. package/dist/help/full.md +236 -437
  268. package/dist/help/help-index.md +49 -0
  269. package/dist/help/help-meta.json +114 -48
  270. package/dist/help/index.md +76 -87
  271. package/dist/help/snippets/agents.md +2 -2
  272. package/dist/help/tokens/qr.inline.examples.md +2 -0
  273. package/dist/help/tokens/stdin.examples.bash.md +8 -0
  274. package/dist/help/tokens/stdin.examples.pwsh.md +8 -0
  275. package/dist/help/tokens/stdin.examples.with-qr.bash.md +12 -0
  276. package/dist/help/tokens/stdin.examples.with-qr.pwsh.md +12 -0
  277. package/dist/help/topics/basics.md +1 -1
  278. package/dist/help/topics/config-setup.import-normalize.md +65 -65
  279. package/dist/help/topics/config-setup.import-rules.md +6 -5
  280. package/dist/help/topics/dsl.md +4 -3
  281. package/dist/help/topics/first-setup.md +6 -5
  282. package/dist/help/topics/help-protocol.md +4 -3
  283. package/dist/help/topics/import.base.md +36 -0
  284. package/dist/help/topics/import.rebase.md +83 -0
  285. package/dist/help/topics/inspect.aliasCandidates.md +37 -0
  286. package/dist/help/topics/inspect.code.md +5 -11
  287. package/dist/help/topics/inspect.deps.md +7 -7
  288. package/dist/help/topics/inspect.file.md +10 -18
  289. package/dist/help/topics/inspect.graph.md +6 -20
  290. package/dist/help/topics/{inspect.md → inspect.shared.md} +18 -17
  291. package/dist/help/topics/modulePlan.md +21 -26
  292. package/dist/help/topics/move.md +17 -18
  293. package/dist/help/topics/moveToDir.md +44 -0
  294. package/dist/help/topics/mutate.mixed.md +32 -0
  295. package/dist/help/topics/mutation.shared.md +53 -0
  296. package/dist/help/topics/patterns.md +3 -16
  297. package/dist/help/topics/qr.md +13 -22
  298. package/dist/help/topics/quick-map.md +36 -23
  299. package/dist/help/topics/recipe.file-layout.md +13 -0
  300. package/dist/help/topics/recipe.import-boundary.md +90 -0
  301. package/dist/help/topics/recipe.safe-artifact-probing.md +66 -0
  302. package/dist/help/topics/recipe.unfamiliar-area.md +62 -0
  303. package/dist/help/topics/recipes.md +18 -0
  304. package/dist/help/topics/rename.md +15 -15
  305. package/dist/help/topics/renameFile.md +34 -0
  306. package/dist/help/topics/rg.md +20 -0
  307. package/dist/help/topics/rules.md +24 -0
  308. package/dist/help/topics/selectors.md +3 -2
  309. package/dist/help/topics/session.md +1 -1
  310. package/dist/host/capabilities.js +56 -0
  311. package/dist/imports/standalone-import-analysis.js +602 -0
  312. package/dist/imports/standalone-import-model.js +2 -0
  313. package/dist/imports/standalone-import-process.js +66 -0
  314. package/dist/imports/standalone-import-worker.js +27 -0
  315. package/dist/imports/standalone-ts-project.js +147 -0
  316. package/dist/inspect/inspect-duplicates-service.js +526 -0
  317. package/dist/inspect/inspect-reverse-module-closure.js +338 -0
  318. package/dist/inspect/inspect-source-ranges.js +82 -0
  319. package/dist/inspect/inspect-source-shape.js +649 -0
  320. package/dist/inspect/standalone-inspect-analysis.js +319 -0
  321. package/dist/inspect/standalone-inspect-model.js +9 -0
  322. package/dist/inspect/standalone-inspect-process.js +55 -0
  323. package/dist/inspect/standalone-inspect-usages.js +274 -0
  324. package/dist/inspect/standalone-inspect-worker.js +13 -0
  325. package/dist/metrics/central-metrics.js +101 -2
  326. package/dist/mutation/concrete-edit-plan.js +157 -0
  327. package/dist/mutation/exports-star-collapse-preview.js +361 -0
  328. package/dist/mutation/exports-star-expand-apply.js +373 -0
  329. package/dist/mutation/exports-star-expand-preview.js +807 -0
  330. package/dist/mutation/file-impact-scan.js +182 -0
  331. package/dist/mutation/file-mutation-discovery.js +674 -0
  332. package/dist/mutation/file-mutation-eta.js +99 -0
  333. package/dist/mutation/file-mutation-standalone-apply.js +584 -0
  334. package/dist/mutation/file-mutation-standalone-planner.js +500 -0
  335. package/dist/mutation/file-mutation-tsserver-session.js +473 -0
  336. package/dist/mutation/mutation-estimate.js +45 -0
  337. package/dist/mutation/mutation-plan.js +467 -0
  338. package/dist/mutation/object-mutation-foundation.js +2 -0
  339. package/dist/mutation/object-mutation-partition.js +148 -0
  340. package/dist/mutation/object-pack-semantic-apply.js +507 -0
  341. package/dist/mutation/object-pack-semantic-preview.js +984 -0
  342. package/dist/mutation/object-unpack-semantic-preview.js +993 -0
  343. package/dist/mutation/package-manifest-impact.js +176 -0
  344. package/dist/mutation/rename-owner-worker-child.js +37 -0
  345. package/dist/mutation/rename-owner-worker.js +122 -0
  346. package/dist/mutation/runtime-cycle-query.js +66 -0
  347. package/dist/mutation/semantic-execution-progress.js +63 -0
  348. package/dist/mutation/semantic-export-index.js +474 -0
  349. package/dist/mutation/semantic-impact-scan.js +434 -0
  350. package/dist/mutation/semantic-model.js +2 -0
  351. package/dist/mutation/semantic-move-best-effort-planner.js +209 -0
  352. package/dist/mutation/semantic-move-config-worker-child.js +61 -0
  353. package/dist/mutation/semantic-move-config-worker.js +449 -0
  354. package/dist/mutation/semantic-move-declarations.js +94 -0
  355. package/dist/mutation/semantic-move-metrics.js +119 -0
  356. package/dist/mutation/semantic-move-model.js +2 -0
  357. package/dist/mutation/semantic-move-owner-authority.js +122 -0
  358. package/dist/mutation/semantic-move-owner-candidates.js +300 -0
  359. package/dist/mutation/semantic-move-owner-divergence-harness.js +474 -0
  360. package/dist/mutation/semantic-move-owner-divergence-runner.js +162 -0
  361. package/dist/mutation/semantic-move-plan-hash.js +56 -0
  362. package/dist/mutation/semantic-move-policy.js +360 -0
  363. package/dist/mutation/semantic-move-process.js +218 -0
  364. package/dist/mutation/semantic-move-provider-diagnostics.js +27 -0
  365. package/dist/mutation/semantic-move-standalone-engine.js +919 -0
  366. package/dist/mutation/semantic-move-standalone-planner.js +1553 -0
  367. package/dist/mutation/semantic-move-transaction.js +639 -0
  368. package/dist/mutation/semantic-mutation-engine.js +478 -0
  369. package/dist/mutation/semantic-mutation-runtime.js +521 -0
  370. package/dist/mutation/semantic-planner-retry.js +26 -0
  371. package/dist/mutation/semantic-program-roots.js +69 -0
  372. package/dist/mutation/semantic-rename-commonjs.js +229 -0
  373. package/dist/mutation/semantic-rename-config-worker-child.js +46 -0
  374. package/dist/mutation/semantic-rename-config-worker.js +498 -0
  375. package/dist/mutation/semantic-rename-locations.js +192 -0
  376. package/dist/mutation/semantic-rename-model.js +2 -0
  377. package/dist/mutation/semantic-rename-process.js +210 -0
  378. package/dist/mutation/semantic-rename-standalone-engine.js +302 -0
  379. package/dist/mutation/semantic-rename-standalone-planner.js +567 -0
  380. package/dist/mutation/semantic-rename-transaction.js +333 -0
  381. package/dist/mutation/semantic-unused-import-cleanup.js +248 -0
  382. package/dist/mutation/semantic-worker-retry.js +40 -0
  383. package/dist/mutation/semantic-workspace.js +804 -0
  384. package/dist/mutation/targeted-import-canonicalizer.js +359 -0
  385. package/dist/observability/config.js +206 -1
  386. package/dist/observability/context.js +59 -1
  387. package/dist/observability/failure-snapshot.js +124 -2
  388. package/dist/observability/recent.js +63 -2
  389. package/dist/payloads/read-stdin-json.js +212 -1
  390. package/dist/rg-wrapper/core.js +714 -0
  391. package/dist/rg-wrapper/options.js +125 -0
  392. package/dist/rtk-wrapper/core.js +144 -0
  393. package/dist/rtk-wrapper/git-safety.js +203 -0
  394. package/dist/rtk-wrapper/output-adapter.js +106 -0
  395. package/dist/runtime/buffered-process.js +114 -0
  396. package/dist/runtime/bundled-node.js +97 -1
  397. package/dist/runtime/command-lifecycle.js +2 -0
  398. package/dist/runtime/input-source.js +238 -1
  399. package/dist/runtime/node-cli-identity.js +37 -0
  400. package/dist/runtime/run-command.js +191 -1
  401. package/dist/selectors/parse-entities.js +84 -1
  402. package/dist/semantic/semantic-context-pool.js +830 -0
  403. package/dist/semantic/semantic-context-provider.js +416 -0
  404. package/dist/semantic/semantic-resident-admission.js +38 -0
  405. package/dist/semantic/semantic-worker-child.js +40 -0
  406. package/dist/semantic/semantic-worker-manager.js +460 -0
  407. package/dist/semantic/semantic-worker-protocol.js +2 -0
  408. package/dist/semantic/semantic-worker-runtime.js +38 -0
  409. package/dist/semantic/workspace-semantic-context-pools.js +136 -0
  410. package/dist/session/client.js +359 -1
  411. package/dist/session/daemon-state.js +185 -0
  412. package/dist/session/external-tool-coordinator.js +88 -0
  413. package/dist/session/external-tool-request.js +52 -0
  414. package/dist/session/lane-owner.js +116 -0
  415. package/dist/session/paths.js +71 -1
  416. package/dist/session/runtime-lifecycle.js +225 -0
  417. package/dist/session/runtime-shutdown.js +95 -0
  418. package/dist/session/server.js +1194 -8
  419. package/dist/session/session-health.js +27 -0
  420. package/dist/shared/agent-text.js +29 -1
  421. package/dist/shared/errors.js +496 -30
  422. package/dist/shared/event-loop.js +6 -1
  423. package/dist/shared/hints.js +37 -1
  424. package/dist/shared/metrics.js +43 -1
  425. package/dist/shared/presentation.js +69 -4
  426. package/dist/shared/stdin-examples.js +77 -3
  427. package/dist/shared/stdout.js +6 -2
  428. package/dist/shared/types.js +23 -1
  429. package/dist/tool-runtime/runtime-tools.js +120 -0
  430. package/dist/topology/availability.js +663 -0
  431. package/dist/topology/cache.js +130 -0
  432. package/dist/topology/candidates.js +372 -0
  433. package/dist/topology/core.js +903 -0
  434. package/dist/topology/dependency-snapshot.js +189 -0
  435. package/dist/topology/model.js +2 -0
  436. package/dist/topology/scope.js +100 -0
  437. package/dist/topology/ts-oracle-batch.js +529 -0
  438. package/dist/topology/ts-oracle-host.js +69 -0
  439. package/dist/topology/ts-oracle-model.js +2 -0
  440. package/dist/topology/ts-oracle.js +224 -0
  441. package/dist/topology/tsconfig-loader.js +105 -0
  442. package/dist/topology/workspace-project-index.js +542 -0
  443. package/dist/tracing/config.js +192 -2
  444. package/dist/tracing/failure-summary.js +100 -0
  445. package/dist/tracing/trace.js +318 -5
  446. package/dist/tsc-wrapper/core.js +697 -0
  447. package/dist/workers/control-plane/aib-control-plane-worker.cjs +80 -0
  448. package/dist/workers/control-plane/client-config.default.json +3 -0
  449. package/dist/workers/lexical-worker-child.js +27 -0
  450. package/dist/workers/lexical-worker-manager.js +394 -0
  451. package/dist/workers/lexical-worker-protocol.js +2 -0
  452. package/dist/workers/lexical-worker-runtime.js +25 -0
  453. package/dist/workers/owned-one-shot-process.js +115 -0
  454. package/dist/workers/product-storage.js +23 -0
  455. package/dist/workers/registry.js +241 -0
  456. package/package.json +8 -11
  457. package/runtimes/tools/rg/darwin-arm64/rg +0 -0
  458. package/runtimes/tools/rg/darwin-x64/rg +0 -0
  459. package/runtimes/tools/rg/linux-arm64/rg +0 -0
  460. package/runtimes/tools/rg/linux-x64/rg +0 -0
  461. package/runtimes/tools/rg/manifest.json +36 -0
  462. package/runtimes/tools/rg/win32-x64/rg.exe +0 -0
  463. package/runtimes/tools/rtk/darwin-arm64/rtk +0 -0
  464. package/runtimes/tools/rtk/darwin-x64/rtk +0 -0
  465. package/runtimes/tools/rtk/linux-arm64/rtk +0 -0
  466. package/runtimes/tools/rtk/linux-x64/rtk +0 -0
  467. package/runtimes/tools/rtk/manifest.json +36 -0
  468. package/runtimes/tools/rtk/win32-x64/rtk.exe +0 -0
  469. package/scripts/postinstall.cjs +29 -29
  470. package/scripts/provision-runtime.cjs +411 -459
  471. package/dist/client/http-client.js +0 -1
  472. package/dist/client/transport-options.js +0 -1
  473. package/dist/client/websocket-client.js +0 -1
  474. package/dist/commands/entity-resolution.js +0 -1
  475. package/dist/commands/inspect-symbol-query.js +0 -1
  476. package/dist/commands/list-instances.js +0 -1
  477. package/dist/commands/module-plan-command.js +0 -1
  478. package/dist/commands/move-command.js +0 -1
  479. package/dist/commands/move-to-file.js +0 -2
  480. package/dist/commands/ping.js +0 -1
  481. package/dist/commands/refactor-command.js +0 -1
  482. package/dist/commands/rename-command.js +0 -1
  483. package/dist/commands/runtime-command.js +0 -4
  484. package/dist/commands/runtime-info.js +0 -1
  485. package/dist/commands/validate-module-plan.js +0 -2
  486. package/dist/compatibility/policy.js +0 -1
  487. package/dist/config/auto-start-ide.js +0 -1
  488. package/dist/discovery/registry.js +0 -1
  489. package/dist/discovery/select-instance.js +0 -1
  490. package/dist/help/docs/mutation.md +0 -50
  491. package/dist/help/docs/refactor.batch.md +0 -44
  492. package/dist/help/dsl/docs/mutation.md +0 -50
  493. package/dist/help/dsl/docs/refactor.batch.md +0 -44
  494. package/dist/help/dsl/topics/mutation.md +0 -48
  495. package/dist/help/dsl/topics/refactor.batch.md +0 -33
  496. package/dist/help/json/bootstrap.md +0 -1085
  497. package/dist/help/json/docs/basics.md +0 -15
  498. package/dist/help/json/docs/config-setup.aliases.md +0 -56
  499. package/dist/help/json/docs/config-setup.excludes.md +0 -45
  500. package/dist/help/json/docs/config-setup.import-normalize.md +0 -86
  501. package/dist/help/json/docs/config-setup.import-rules.md +0 -96
  502. package/dist/help/json/docs/config-setup.tsconfigs.md +0 -33
  503. package/dist/help/json/docs/dsl.md +0 -25
  504. package/dist/help/json/docs/first-setup.md +0 -292
  505. package/dist/help/json/docs/help-format.md +0 -9
  506. package/dist/help/json/docs/help-protocol.md +0 -26
  507. package/dist/help/json/docs/imports.normalize.md +0 -47
  508. package/dist/help/json/docs/inspect.code.md +0 -41
  509. package/dist/help/json/docs/inspect.cycles.md +0 -38
  510. package/dist/help/json/docs/inspect.deps.md +0 -46
  511. package/dist/help/json/docs/inspect.duplicates.md +0 -65
  512. package/dist/help/json/docs/inspect.exports.md +0 -40
  513. package/dist/help/json/docs/inspect.file.md +0 -38
  514. package/dist/help/json/docs/inspect.graph.md +0 -139
  515. package/dist/help/json/docs/inspect.imports.md +0 -15
  516. package/dist/help/json/docs/inspect.md +0 -88
  517. package/dist/help/json/docs/inspect.members.md +0 -32
  518. package/dist/help/json/docs/inspect.tree.md +0 -32
  519. package/dist/help/json/docs/inspect.usages.md +0 -61
  520. package/dist/help/json/docs/modulePlan.md +0 -73
  521. package/dist/help/json/docs/move.md +0 -56
  522. package/dist/help/json/docs/mutation.md +0 -65
  523. package/dist/help/json/docs/patterns.md +0 -76
  524. package/dist/help/json/docs/prefs.md +0 -40
  525. package/dist/help/json/docs/qr.md +0 -37
  526. package/dist/help/json/docs/quick-map.md +0 -30
  527. package/dist/help/json/docs/refactor.batch.md +0 -72
  528. package/dist/help/json/docs/rename.md +0 -47
  529. package/dist/help/json/docs/reveal.md +0 -30
  530. package/dist/help/json/docs/selectors.md +0 -23
  531. package/dist/help/json/docs/session.md +0 -77
  532. package/dist/help/json/docs/view.md +0 -30
  533. package/dist/help/json/full.md +0 -1085
  534. package/dist/help/json/snippets/agents.md +0 -14
  535. package/dist/help/json/topics/basics.md +0 -13
  536. package/dist/help/json/topics/config-setup.aliases.md +0 -54
  537. package/dist/help/json/topics/config-setup.excludes.md +0 -43
  538. package/dist/help/json/topics/config-setup.import-normalize.md +0 -84
  539. package/dist/help/json/topics/config-setup.import-rules.md +0 -94
  540. package/dist/help/json/topics/config-setup.tsconfigs.md +0 -31
  541. package/dist/help/json/topics/dsl.md +0 -23
  542. package/dist/help/json/topics/first-setup.md +0 -290
  543. package/dist/help/json/topics/help-format.md +0 -7
  544. package/dist/help/json/topics/help-protocol.md +0 -24
  545. package/dist/help/json/topics/imports.normalize.md +0 -45
  546. package/dist/help/json/topics/inspect.code.md +0 -39
  547. package/dist/help/json/topics/inspect.cycles.md +0 -36
  548. package/dist/help/json/topics/inspect.deps.md +0 -44
  549. package/dist/help/json/topics/inspect.duplicates.md +0 -37
  550. package/dist/help/json/topics/inspect.exports.md +0 -38
  551. package/dist/help/json/topics/inspect.file.md +0 -36
  552. package/dist/help/json/topics/inspect.graph.md +0 -137
  553. package/dist/help/json/topics/inspect.imports.md +0 -13
  554. package/dist/help/json/topics/inspect.md +0 -86
  555. package/dist/help/json/topics/inspect.members.md +0 -30
  556. package/dist/help/json/topics/inspect.tree.md +0 -22
  557. package/dist/help/json/topics/inspect.usages.md +0 -59
  558. package/dist/help/json/topics/modulePlan.md +0 -60
  559. package/dist/help/json/topics/move.md +0 -46
  560. package/dist/help/json/topics/mutation.md +0 -63
  561. package/dist/help/json/topics/patterns.md +0 -74
  562. package/dist/help/json/topics/prefs.md +0 -38
  563. package/dist/help/json/topics/qr.md +0 -35
  564. package/dist/help/json/topics/quick-map.md +0 -28
  565. package/dist/help/json/topics/refactor.batch.md +0 -61
  566. package/dist/help/json/topics/rename.md +0 -42
  567. package/dist/help/json/topics/reveal.md +0 -28
  568. package/dist/help/json/topics/selectors.md +0 -21
  569. package/dist/help/json/topics/session.md +0 -59
  570. package/dist/help/json/topics/view.md +0 -28
  571. package/dist/help/topics/mutation.md +0 -48
  572. package/dist/help/topics/refactor.batch.md +0 -33
  573. package/dist/ide-launch/common.cjs +0 -162
  574. package/dist/managed-host/extension-vsix-resolver.js +0 -1
  575. package/dist/managed-host/manage-serve-web-host.cjs +0 -141
  576. package/dist/managed-host/serve-web-autostart.js +0 -1
  577. package/dist/managed-host/serve-web-host.cjs +0 -1904
  578. package/dist/runtime/managed-runtime-provisioning.js +0 -1
  579. package/dist/shared/diagnostic-catalog.js +0 -1
  580. package/dist/shared/diagnostics.js +0 -1
  581. package/dist/shared/operations.js +0 -1
  582. package/dist/shared/protocol.js +0 -1
  583. package/dist/shared/routes.js +0 -1
  584. package/extension/vscode-refactor-bridge-extension.vsix +0 -0
  585. package/runtimes/launcher/linux-x64/aib +0 -0
  586. package/runtimes/launcher/win-x64/aib.exe +0 -0
@@ -1,9 +1,1553 @@
1
- "use strict";var xe=exports&&exports.__createBinding||(Object.create?(function(e,t,n,r){r===void 0&&(r=n);var s=Object.getOwnPropertyDescriptor(t,n);(!s||("get"in s?!t.__esModule:s.writable||s.configurable))&&(s={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,s)}):(function(e,t,n,r){r===void 0&&(r=n),e[r]=t[n]})),Se=exports&&exports.__setModuleDefault||(Object.create?(function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}):function(e,t){e.default=t}),k=exports&&exports.__importStar||(function(){var e=function(t){return e=Object.getOwnPropertyNames||function(n){var r=[];for(var s in n)Object.prototype.hasOwnProperty.call(n,s)&&(r[r.length]=s);return r},e(t)};return function(t){if(t&&t.__esModule)return t;var n={};if(t!=null)for(var r=e(t),s=0;s<r.length;s++)r[s]!=="default"&&xe(n,t,r[s]);return Se(n,t),n}})();Object.defineProperty(exports,"__esModule",{value:!0}),exports.isInspectGraphRequest=Ae,exports.runInspectGraph=Ee,exports.formatGraphAgentText=H,exports.buildInspectGraphModel=Me;const x=k(require("node:fs")),d=k(require("node:path")),ve=require("../config/glob-match"),_e=require("../config/local-config"),J=require("../shared/agent-text"),y=require("../shared/errors"),A=require("./session-workspace"),we=require("./json-file-input"),j=[".ts",".tsx",".mts",".cts"],D=[".ts",".tsx",".mts",".cts",".js",".jsx",".mjs",".cjs"],Pe=new Set(["node_modules",".git","dist","out","build",".tmp"]),Z=12,S=8,X="tsconfig.json";function Ae(e,t){return e[0]==="graph"}function Ee(e,t,n){const r=(0,_e.resolveLocalCliConfig)(e),s=Oe(e,t,n);if(s){const i=Ce(s).map((l,a)=>{if(!N(l))throw new y.CliError("INVALID_GRAPH_REQUEST",`inspect graph request at index ${a} must be an object.`);return Q(e,Ne(e,l,r.config.inspect.graph.exclude))});return i.length===1?i[0]:$e(i)}return Q(e,Le(e,t,r.config.inspect.graph.exclude))}function Q(e,t){const n=t.fromFile?dt(e,t.fromFile):ee(e,t),r=t.toFile?gt(e,t.toFile,n):null,s=t.save?(0,A.saveSessionOutputJson)(e,"graph",t.save,n):null,o=Qe(e,n,{focus:t.focus,depth:t.depth,writtenTo:r,symbols:t.symbols,symbolUsage:t.symbolUsage,sections:t.sections,...t.view!==void 0?{view:t.view}:{}});return s&&(o.saved=s.saved,o.next=`Focus with: aib inspect graph --from-file ${s.saved} --focus <file>`),(0,J.attachAgentText)(o,H(o))}function $e(e){const t=e.map(r=>typeof r.saved=="string"?r.saved:"").filter(r=>r!==""),n={operation:"inspect.graphBatch",summary:`${e.length} graph requests${t.length>0?`, ${t.length} saved`:""}`,results:e.map(Ie)};return t.length>0?(n.saved=t,n.next="Focus a saved graph with: aib inspect graph --from-file <saved> --focus <file>"):n.next="Focus files with --focus, or inspect exports/code on relevant files.",(0,J.attachAgentText)(n,H(n))}function Ie(e){const t=Object.entries(e).filter(([n])=>n!=="operation"&&n!=="last"&&n!=="next"&&!(n==="graphFile"&&typeof e.saved=="string"));return Object.fromEntries(t)}function H(e){const t=typeof e.operation=="string"?e.operation:"";if(t!=="inspect.graph"&&t!=="inspect.graphBatch")return null;const n=[t];typeof e.summary=="string"&&n.push(e.summary);const r=Array.isArray(e.results)?e.results:null;return r&&(O(n,"view",e.view),O(n,"excluded",e.excluded),Y(n,e.paths)),r?r.forEach((s,o)=>{N(s)&&(n.push(`[${o+1}] ${typeof s.summary=="string"?s.summary:"graph result"}`),K(n,s))}):K(n,e),r||_(n,"saved",e.saved),O(n,"next",e.next),n.join(`
2
- `)}function K(e,t){O(e,"view",t.view),O(e,"excluded",t.excluded),Y(e,t.paths),_(e,"hubs",t.hubs),_(e,"scopeEntrypoints",t.scopeEntrypoints),_(e,"scopeLeaves",t.scopeLeaves),_(e,"edges",t.edges),Fe(e,t.focus),O(e,"saved",t.saved)}function Fe(e,t){if(!(!Array.isArray(t)||t.length===0)){e.push("focus:");for(const n of t){if(!N(n))continue;const r=typeof n.file=="string"?n.file:"unknown";e.push(`${r}:`),_(e,"imports",n.imports),_(e,"symbols",n.symbols),Ge(e,n.usage),_(e,"importsOther",n.importsOther),_(e,"importedBy",n.importedBy),_(e,"external",n.external),_(e,"omittedLocalImports",n.omittedLocalImports),O(e,"error",n.error)}}}function Ge(e,t){if(N(t))for(const n of["value","type","unknown"])_(e,`usage.${n}`,t[n])}function Y(e,t){if(!(!N(t)||Object.keys(t).length===0)){e.push("paths:");for(const[n,r]of Object.entries(t))typeof r=="string"&&e.push(`${n} = ${r}`)}}function O(e,t,n){typeof n=="string"&&n!==""&&e.push(`${t}: ${n}`)}function _(e,t,n){const r=Array.isArray(n)?n.filter(s=>typeof s=="string"&&s!==""):[];if(r.length!==0){e.push(`${t}:`);for(const s of r)e.push(s)}}function Oe(e,t,n){if(n!==void 0){if(!N(n))throw new y.CliError("INVALID_GRAPH_STDIN","inspect graph --stdin expects a JSON object payload.");return n}const r=St(t,"--from-json");return r?(0,we.readJsonObjectFile)(e,r,"INVALID_GRAPH_JSON_FILE"):null}function Ce(e){return Array.isArray(e.requests)?e.requests:[e]}function Le(e,t,n){const r=[],s=[],o=[],i=[];let l,a,f,h,c,g=(0,A.readSessionBooleanPref)(e,"inspect.graph.symbols",!1),v=(0,A.readSessionBooleanPref)(e,"inspect.graph.symbolUsage",!1);for(let u=1;u<t.length;u+=1){const m=t[u];if(m){if(m==="--focus"){const p=t[u+1];if(!p)throw new y.CliError("MISSING_FLAG_VALUE","Expected a value after --focus.");s.push(I(e,$(e,p))),u+=1;continue}if(m==="--depth"){const p=t[u+1],b=p===void 0?Number.NaN:Number.parseInt(p,10);if(!Number.isInteger(b)||b<0||b>2)throw new y.CliError("INVALID_GRAPH_DEPTH","inspect graph --depth expects 0, 1, or 2.");l=b,u+=1;continue}if(m==="--view"){const p=t[u+1];if(!p)throw new y.CliError("MISSING_FLAG_VALUE","Expected a value after --view.");a=ge(p),u+=1;continue}if(m==="--to-file"){const p=t[u+1];if(!p)throw new y.CliError("MISSING_FLAG_VALUE","Expected a value after --to-file.");f=p,u+=1;continue}if(m==="--from-file"){const p=t[u+1];if(!p)throw new y.CliError("MISSING_FLAG_VALUE","Expected a value after --from-file.");h=p,u+=1;continue}if(m==="--save"){const p=t[u+1];if(!p)throw new y.CliError("MISSING_FLAG_VALUE","Expected a value after --save.");c=p,u+=1;continue}if(m==="--exclude"){const p=t[u+1];if(!p)throw new y.CliError("MISSING_FLAG_VALUE","Expected a value after --exclude.");o.push(p),u+=1;continue}if(m==="--exclude-from"){const p=t[u+1];if(!p)throw new y.CliError("MISSING_FLAG_VALUE","Expected a value after --exclude-from.");i.push(p),u+=1;continue}if(m==="--symbols"){g=!0;continue}if(m==="--symbol-usage"){g=!0,v=!0;continue}if(m.startsWith("--"))throw new y.CliError("UNKNOWN_INSPECT_GRAPH_FLAG",`Unknown inspect graph flag: ${m}`);r.push(I(e,$(e,m)))}}if(h&&r.length>0)throw new y.CliError("GRAPH_INPUT_SOURCE_CONFLICT","Use either inspect graph <scopes...> or --from-file, not both.");if(f&&c)throw new y.CliError("GRAPH_OUTPUT_TARGET_CONFLICT","Use either inspect graph --to-file or --save, not both.");if(!h&&r.length===0)throw new y.CliError("GRAPH_SCOPE_REQUIRED","inspect graph expects at least one file or directory scope.");const E=l??ye(a??R(e,r,h)),P=l!==void 0?be(l):a??R(e,r,h);return{scopes:r,focus:s,depth:E,symbols:g||v,symbolUsage:v,sections:de(e),excludePatterns:U([...n,...i.flatMap(u=>ne(e,u)),...o]),...c!==void 0?{save:c}:{},...f!==void 0?{toFile:f}:{},...h!==void 0?{fromFile:h}:{},...P!==void 0?{view:P}:{}}}function Ne(e,t,n){const r=G(t.scopes)??G(t.scope)??G(t.files)??G(t.file)??[],s=G(t.focus)??[],o=G(t.exclude)??G(t.excludePatterns)??[],i=G(t.excludeFrom)??[],l=M(t.fromFile)??M(t.from),a=M(t.toFile)??M(t.outputFile),f=M(t.save),h=xt(t.depth),c=t.view!==void 0?ge(t.view):void 0,v=w(t.symbolUsage)??(0,A.readSessionBooleanPref)(e,"inspect.graph.symbolUsage",!1),E=v||(w(t.symbols)??(0,A.readSessionBooleanPref)(e,"inspect.graph.symbols",!1));if(l&&r.length>0)throw new y.CliError("GRAPH_INPUT_SOURCE_CONFLICT","Use either inspect graph scopes or fromFile/from, not both.");if(a&&f)throw new y.CliError("GRAPH_OUTPUT_TARGET_CONFLICT","Use either toFile or save, not both.");if(!l&&r.length===0)throw new y.CliError("GRAPH_SCOPE_REQUIRED","inspect graph JSON expects scope/scopes or fromFile/from.");const P=r.map(p=>I(e,$(e,p))),u=h??ye(c??R(e,P,l??void 0)),m=h!==void 0?be(h):c??R(e,P,l??void 0);return{scopes:P,focus:s.map(p=>I(e,$(e,p))),depth:u,symbols:E,symbolUsage:v,sections:bt(e,t),excludePatterns:U([...n,...i.flatMap(p=>ne(e,p)),...o]),...f?{save:f}:{},...a?{toFile:a}:{},...l?{fromFile:l}:{},...m!==void 0?{view:m}:{}}}function ee(e,t){const n=He(e),r=Te(e,t.excludePatterns),s=Be(e,t.scopes,r),o=new Set(s);let i=s;for(let u=0;u<t.depth;u+=1){const m=new Set;for(const p of i)for(const b of re(e,p,n).imports)!r.isExcluded(b)&&!o.has(b)&&(o.add(b),m.add(b));i=Array.from(m).sort()}const l=Array.from(o).sort(),a=new Set(l.map(u=>I(e,u))),f=new Map,h=new Map,c=new Map;for(const u of l){const m=re(e,u,n),p=I(e,u);h.set(p,m.external);const b=[];for(const C of m.imports){if(r.isExcluded(C))continue;const B=I(e,C);if(!a.has(B)){b.push(B);continue}f.set(`${p}
3
- ${B}
4
- ${m.specifiers.get(C)??""}`,{from:p,to:B,specifier:m.specifiers.get(C)??"",resolution:m.resolutions.get(C)??"relative",symbols:m.symbols.get(C)??[]})}b.length>0&&c.set(p,U(b))}const g=Array.from(f.values()).sort(wt),v=new Map;for(const u of l){const m=I(e,u),p={file:m,imports:[],importedBy:[],external:h.get(m)??[]},b=c.get(m);b&&b.length>0&&(p.omittedLocalImports=b),v.set(m,p)}for(const u of g)v.get(u.from)?.imports.push(u.to),v.get(u.to)?.importedBy.push(u.from);const E=U(Array.from(h.values()).flat()),P=r.excluded.size>0?{count:r.excluded.size,patterns:t.excludePatterns}:void 0;return{operation:"inspect.graph",version:1,root:d.resolve(e),scopes:t.scopes,generatedAt:new Date().toISOString(),files:Array.from(v.values()).sort((u,m)=>u.file.localeCompare(m.file)),edges:g,externalPackages:E,timeoutHint:Ue(v.size,g.length,t.view),...P?{excluded:P}:{}}}function Me(e,t){return ee(e,{scopes:t.scopes,focus:[],depth:t.depth,symbols:!0,symbolUsage:t.symbolUsage??!0,sections:{hubs:!1,entrypoints:!1,leaves:!1,edges:!0},excludePatterns:t.excludePatterns??[]})}function Ue(e,t,n){const r=n==="expanded"?2:n==="neighbors"?1.5:1;return{recommendedTimeoutMs:Math.min(6e5,Math.max(6e4,Math.round((3e4+e*250+t*100)*r))),fileCount:e,edgeCount:t,view:n??"local"}}function Be(e,t,n){const r=new Set;for(const s of t){const o=$(e,s);if(!x.existsSync(o))throw new y.CliError("GRAPH_SCOPE_NOT_FOUND",`Graph scope does not exist: ${s}`);const i=x.statSync(o);if(i.isDirectory()){for(const l of te(o))n.isExcluded(l)||r.add(l);continue}i.isFile()&&W(o)&&!n.isExcluded(o)&&r.add(o)}return Array.from(r).sort()}function Te(e,t){const n=U(t.map(s=>F(s.trim())).filter(Boolean)),r=new Set;return{patterns:n,excluded:r,isExcluded(s){if(n.length===0)return!1;const o=I(e,s),i=(0,ve.matchesAnyGlob)(o,n);return i&&r.add(o),i}}}function te(e){const t=[];for(const n of x.readdirSync(e,{withFileTypes:!0})){if(n.isDirectory()){Pe.has(n.name)||t.push(...te(d.join(e,n.name)));continue}const r=d.join(e,n.name);n.isFile()&&W(r)&&t.push(r)}return t}function ne(e,t){const n=$(e,t);try{return x.readFileSync(n,"utf8").split(/\r?\n/).map(r=>r.trim()).filter(r=>r.length>0&&!r.startsWith("#"))}catch{throw new y.CliError("GRAPH_EXCLUDE_FILE_NOT_FOUND",`Could not read inspect graph --exclude-from file: ${t}`)}}function re(e,t,n){const r=x.readFileSync(t,"utf8"),s=new Set,o=new Set,i=new Map,l=new Map,a=new Map;for(const f of Re(r)){const{specifier:h}=f;if(h.startsWith(".")){const g=De(t,h);g&&(s.add(g),i.set(g,h),l.set(g,"relative"),a.set(g,oe(a.get(g),f.symbols)));continue}const c=n.resolve(t,h);if(c){s.add(c),i.set(c,h),l.set(c,"tsconfig-paths"),a.set(c,oe(a.get(c),f.symbols));continue}o.add(vt(h))}return{imports:Array.from(s).sort(),external:Array.from(o).sort(),specifiers:i,resolutions:l,symbols:a}}function Re(e){const t=[],n=new Set,r=le(e),s=/\bimport\s+(type\s+)?(?:([$A-Z_a-z][$\w]*)\s*,\s*)?(\*\s+as\s+[$A-Z_a-z][$\w]*|\{[\s\S]*?\})\s+from\s+["']([^"']+)["']/g;for(const a of r.matchAll(s)){const f=a[2]?.trim(),h=a[3]?.trim()??"",c=a[4]?.trim();T(t,n,c,je(f,h,!!a[1]))}const o=/\bimport\s+(type\s+)?([$A-Z_a-z][$\w]*)\s+from\s+["']([^"']+)["']/g;for(const a of r.matchAll(o)){const f=a[2]?.trim(),h=a[3]?.trim();T(t,n,h,f?[L(`default:${f}`,a[1]?"type":"value")]:[])}const i=/\bexport\s+(type\s+)?(\{[\s\S]*?\}|\*)\s+from\s+["']([^"']+)["']/g;for(const a of r.matchAll(i)){const f=a[2]?.trim()??"",h=a[3]?.trim();T(t,n,h,f==="*"?[L("*",a[1]?"type":"value")]:se(f,!!a[1]))}const l=[/\bimport\s+["']([^"']+)["']/g,/\bimport\s*\(\s*["']([^"']+)["']\s*\)/g,/\brequire\s*\(\s*["']([^"']+)["']\s*\)/g];for(const a of l)for(const f of r.matchAll(a))T(t,n,f[1]?.trim(),[]);return t}function T(e,t,n,r){if(!n)return;const s=ie(r.filter(i=>i.name.trim()!=="")),o=`${n}
5
- ${s.map(i=>`${i.usage}:${i.name}`).join(`
6
- `)}`;t.has(o)||(t.add(o),e.push({specifier:n,symbols:s}))}function je(e,t,n){const r=n?"type":"value",s=[];e&&s.push(L(`default:${e}`,r));const o=t.match(/^\*\s+as\s+([$A-Z_a-z][$\w]*)$/);return o?.[1]?(s.push(L(`*:${o[1]}`,r)),s):[...s,...se(t,n)]}function se(e,t){const n=e.trim();return!n.startsWith("{")||!n.endsWith("}")?[]:n.slice(1,-1).split(",").map(r=>{const s=r.trim(),o=s.startsWith("type ");return{raw:o?s.replace(/^type\s+/,""):s,usage:t||o?"type":"value"}}).filter(r=>r.raw!=="").map(r=>{const s=r.raw.match(/^([$A-Z_a-z][$\w]*)\s+as\s+([$A-Z_a-z][$\w]*)$/),o=s?.[1]&&s[2]?`${s[1]} as ${s[2]}`:r.raw;return L(o,r.usage)})}function L(e,t){return{name:e,usage:t}}function oe(e,t){return ie([...e??[],...t])}function ie(e){const t=new Map;for(const n of e)t.set(`${n.usage}:${n.name}`,n);return Array.from(t.values()).sort((n,r)=>n.usage.localeCompare(r.usage)||n.name.localeCompare(r.name))}function De(e,t){const n=d.resolve(d.dirname(e),t);return ce(n)}function ce(e){const t=new Set;t.add(e);const n=d.extname(e);if(n){if([".js",".jsx",".mjs",".cjs"].includes(n)){const r=e.slice(0,-n.length);for(const s of j)t.add(`${r}${s}`)}if(!D.includes(n))for(const r of j)t.add(`${e}${r}`)}else for(const r of D)t.add(`${e}${r}`);for(const r of D)t.add(d.join(e,`index${r}`));for(const r of t)if(x.existsSync(r)&&x.statSync(r).isFile()&&W(r))return r;return null}function He(e){const t=new Map;return{resolve(n,r){const s=qe(d.dirname(n),e);if(!s)return null;const o=Ve(s,t);if(!o||o.mappings.length===0)return null;for(const i of o.mappings){const l=Xe(r,i);if(l!==null)for(const a of i.targets){const f=a.includes("*")?a.replace(/\*/g,l):a,h=d.resolve(o.baseUrl,f),c=ce(h);if(c)return c}}return null}}}function qe(e,t){let n=d.resolve(e);const r=d.parse(d.resolve(t)).root;for(;;){const s=d.join(n,X);if(x.existsSync(s)&&x.statSync(s).isFile())return s;const o=d.dirname(n);if(o===n||n===r)return null;n=o}}function Ve(e,t){const n=d.resolve(e);if(t.has(n))return t.get(n)??null;t.set(n,null);const r=ae(n);if(!r)return null;const s=d.dirname(n),o=r.baseUrl?d.resolve(s,r.baseUrl):s,i=Object.entries(r.paths??{}).flatMap(([a,f])=>Ze(a,f)).sort((a,f)=>f.specificity-a.specificity||a.pattern.localeCompare(f.pattern)),l={configPath:n,baseUrl:o,mappings:i};return t.set(n,l),l}function ae(e){try{const t=ke(x.readFileSync(e,"utf8")),n=ze(e,t.extends),r=q(t.compilerOptions)?t.compilerOptions:{},s=Je(r.paths),o=typeof r.baseUrl=="string"?d.resolve(d.dirname(e),r.baseUrl):void 0;return{...n??{},...o!==void 0?{baseUrl:o}:{},...s?{paths:s}:{}}}catch{return null}}function ze(e,t){if(typeof t!="string"||t.trim()==="")return null;const n=d.dirname(e),r=We(n,t.trim());for(const s of r)if(x.existsSync(s)&&x.statSync(s).isFile())return ae(s);return null}function We(e,t){const n=t.startsWith(".")||d.isAbsolute(t)?d.resolve(e,t):d.resolve(e,"node_modules",t),r=[n];return d.extname(n)||r.push(`${n}.json`,d.join(n,X)),r}function ke(e){const n=le(e).replace(/,\s*([}\]])/g,"$1"),r=JSON.parse(n);return q(r)?r:{}}function q(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function le(e){let t="",n=!1,r=!1;for(let s=0;s<e.length;s+=1){const o=e[s],i=e[s+1];if(n){t+=o,r?r=!1:o==="\\"?r=!0:o==='"'&&(n=!1);continue}if(o==='"'){n=!0,t+=o;continue}if(o==="/"&&i==="/"){for(;s<e.length&&e[s]!==`
7
- `;)s+=1;t+=`
8
- `;continue}if(o==="/"&&i==="*"){for(s+=2;s<e.length&&!(e[s]==="*"&&e[s+1]==="/");)s+=1;s+=1;continue}t+=o}return t}function Je(e){if(!q(e))return null;const t={};for(const[n,r]of Object.entries(e)){if(!Array.isArray(r))continue;const s=r.filter(o=>typeof o=="string"&&o.trim()!=="");s.length>0&&(t[n]=s)}return Object.keys(t).length>0?t:null}function Ze(e,t){if(typeof e!="string"||e.trim()==="")return[];const n=e.indexOf("*"),r=n>=0?e.slice(0,n):e,s=n>=0?e.slice(n+1):"";return[{pattern:e,prefix:r,suffix:s,targets:t,specificity:r.length+s.length}]}function Xe(e,t){return t.pattern.includes("*")?!e.startsWith(t.prefix)||!e.endsWith(t.suffix)?null:e.slice(t.prefix.length,e.length-t.suffix.length):e===t.pattern?"":null}function Qe(e,t,n){const r=et(Ye(t,n)),s=fe(e,t,n,r),o=ot(s,r),i=o.length===r.aliases.length?r:pe(o),l=i===r?s:fe(e,t,n,i);return st(l,i)}function fe(e,t,n,r){const s={operation:"inspect.graph",summary:`${t.files.length} files, ${t.edges.length} local edges, ${t.externalPackages.length} external packages`};if(t.timeoutHint&&(s.timeoutHint=t.timeoutHint),n.view&&(s.view=n.view),t.excluded&&t.excluded.count>0&&(s.excluded=`${t.excluded.count} files by graph.exclude`),n.writtenTo&&(s.graphFile=n.writtenTo),n.focus.length>0)return s.focus=n.focus.slice(0,10).map(c=>Ke(t,F(c),r,n.symbols,n.symbolUsage)),s.next=ue(n,t),s;const o=t.files.map(c=>({file:c.file,total:c.imports.length+c.importedBy.length,imports:c.imports.length,importedBy:c.importedBy.length})).filter(c=>c.total>0).sort((c,g)=>g.total-c.total||c.file.localeCompare(g.file)).slice(0,S).map(c=>`${r.compactPath(c.file)} imports ${c.imports}, importedBy ${c.importedBy}`);n.sections.hubs&&o.length>0&&(s.hubs=o);const i=t.files.filter(c=>c.importedBy.length===0&&c.imports.length>0).sort((c,g)=>g.imports.length-c.imports.length||c.file.localeCompare(g.file)).map(c=>c.file),l=r.compactList(i,S);n.sections.entrypoints&&l.length>0&&(s.scopeEntrypoints=l);const a=t.files.filter(c=>c.imports.length===0&&c.importedBy.length>0).sort((c,g)=>g.importedBy.length-c.importedBy.length||c.file.localeCompare(g.file)).map(c=>c.file),f=r.compactList(a,S);n.sections.leaves&&f.length>0&&(s.scopeLeaves=f);const h=ft(t.edges,r,Z,n.symbols);return n.sections.edges&&h.length>0&&(s.edges=h),s.next=n.writtenTo?`Focus saved graph: aib inspect graph --from-file ${_t(e,n.writtenTo)} --focus <file>`:ue(n,t),s}function Ke(e,t,n,r,s){const o=e.files.find(l=>F(l.file)===t);if(!o)return{file:t,ok:!1,code:"GRAPH_FOCUS_NOT_FOUND",error:"Focus file is not present in this graph."};const i={file:n.compactPath(o.file)};if(o.imports.length>0)if(r){const l=e.edges.filter(a=>a.from===o.file);if(s){const a=pt(l,n,S);Object.keys(a).length>0&&(i.usage=a);const f=ht(o.imports,l,n);f.length>0&&(i.importsOther=f)}else i.symbols=ut(l,n,S)}else i.imports=n.compactList(o.imports,S);return o.importedBy.length>0&&(i.importedBy=n.compactList(o.importedBy,S)),o.external.length>0&&(i.external=Pt(o.external,S)),o.omittedLocalImports&&o.omittedLocalImports.length>0&&(i.omittedLocalImports=n.compactList(o.omittedLocalImports,S)),i}function ue(e,t){return e.depth===0&&t.files.some(n=>(n.omittedLocalImports??[]).length>0)?"Use --depth 1 to include direct local imports outside the initial scope.":"Use --depth 2 for a wider local neighborhood, or inspect exports/code on focused files."}function Ye(e,t){const n=new Set;if(t.focus.length>0){for(const r of t.focus.slice(0,10)){const s=F(r),o=e.files.find(i=>F(i.file)===s);if(o){n.add(o.file);for(const i of o.imports.slice(0,S))n.add(i);for(const i of o.importedBy.slice(0,S))n.add(i);for(const i of(o.omittedLocalImports??[]).slice(0,S))n.add(i);if(t.symbols)for(const i of e.edges.filter(l=>l.from===o.file).slice(0,S))n.add(i.to)}}return Array.from(n)}if(t.sections.hubs){const r=e.files.map(s=>({file:s.file,total:s.imports.length+s.importedBy.length,imports:s.imports.length,importedBy:s.importedBy.length})).filter(s=>s.total>0).sort((s,o)=>o.total-s.total||s.file.localeCompare(o.file)).slice(0,S);for(const s of r)n.add(s.file)}if(t.sections.entrypoints)for(const r of e.files.filter(s=>s.importedBy.length===0&&s.imports.length>0).sort((s,o)=>o.imports.length-s.imports.length||s.file.localeCompare(o.file)).map(s=>s.file).slice(0,S))n.add(r);if(t.sections.leaves)for(const r of e.files.filter(s=>s.imports.length===0&&s.importedBy.length>0).sort((s,o)=>o.importedBy.length-s.importedBy.length||s.file.localeCompare(o.file)).map(s=>s.file).slice(0,S))n.add(r);if(t.sections.edges)for(const r of e.edges.slice(0,Z))n.add(r.from),n.add(r.to);return Array.from(n)}function et(e){return pe(tt(e))}function pe(e){return{aliases:e,compactPath(t){return he(t,e)},compactList(t,n){return at(t,n,e)}}}function tt(e){const t=new Map;for(const s of e)for(const o of rt(s))t.set(o,(t.get(o)??0)+1);const n=new Set,r=Array.from(t.entries()).map(([s,o])=>{const i=`<${d.basename(s)}>`;return{prefix:s,count:o,token:i,score:Math.max(0,s.length-i.length)*o}}).filter(s=>s.count>=2&&(s.score>=16||s.count>=3)&&s.prefix!=="src/main").sort((s,o)=>o.score-s.score||o.count-s.count||o.prefix.length-s.prefix.length||s.prefix.localeCompare(o.prefix)).filter(s=>n.has(s.token)?!1:(n.add(s.token),!0));return nt(r).slice(0,6).sort((s,o)=>o.prefix.length-s.prefix.length).map(s=>({token:s.token,prefix:s.prefix}))}function nt(e){return e.filter(t=>!e.find(r=>r.prefix!==t.prefix&&t.prefix.startsWith(`${r.prefix}/`)&&r.count>=t.count&&r.score>=12&&t.score<40))}function rt(e){const t=F(e).split("/"),n=[];for(let r=2;r<t.length;r+=1){const s=t.slice(0,r).join("/");s.length>=8&&n.push(s)}return n}function st(e,t){const n=ct(t,e);return n?{operation:e.operation??"inspect.graph",summary:e.summary??"",paths:n,...Object.fromEntries(Object.entries(e).filter(([r])=>r!=="operation"&&r!=="summary"))}:e}function ot(e,t){const n=JSON.stringify(e);return t.aliases.filter(r=>it(n,r.token)>=2)}function it(e,t){let n=0,r=0;for(;;){const s=e.indexOf(t,r);if(s<0)return n;n+=1,r=s+t.length}}function ct(e,t){if(e.aliases.length===0)return null;const n=JSON.stringify(t),r={};for(const s of e.aliases)n.includes(s.token)&&(r[s.token]=s.prefix);return Object.keys(r).length>0?r:null}function he(e,t){const n=F(e),r=t.find(s=>n===s.prefix||n.startsWith(`${s.prefix}/`));return r?n===r.prefix?r.token:`${r.token}/${n.slice(r.prefix.length+1)}`:n}function at(e,t,n){const r=e.slice(0,t).map(i=>he(i,n)),s=lt(r),o=e.length-Math.min(e.length,t);return o>0?[...s,`+ ${o} more`]:s}function lt(e){const t=new Map,n=[];for(const r of e){const s=r.startsWith("<")?r.indexOf(">"):-1;if(s<=0){n.push(r);continue}const o=r.indexOf("/",s);if(o<0){n.push(r);continue}const i=r.slice(0,o),l=r.slice(o+1),a=t.get(i)??[];a.push(l),t.set(i,a)}return[...Array.from(t.entries()).map(([r,s])=>s.length===1?`${r}/${s[0]}`:`${r}/: ${s.join(", ")}`),...n].sort()}function ft(e,t,n,r){const s=e.slice(0,n),o=new Map,i=[];for(const f of s){const h=t.compactPath(f.from),c=t.compactPath(f.to),g=r?V(f.symbols):"",v=c.startsWith("<")?c.indexOf(">"):-1,E=v>0?c.indexOf("/",v):-1;if(E<0){i.push(`${h} -> ${c}${g}`);continue}const P=c.slice(0,E),u=`${c.slice(E+1)}${g}`,m=`${h} -> ${P}`,p=o.get(m)??[];p.push(u),o.set(m,p)}const l=[...Array.from(o.entries()).map(([f,h])=>h.length===1?`${f}/${h[0]}`:`${f}/: ${h.join(", ")}`),...i].sort(),a=e.length-Math.min(e.length,n);return a>0?[...l,`+ ${a} more`]:l}function ut(e,t,n){const r=e.slice(0,n).map(o=>`${t.compactPath(o.to)}${V(o.symbols)}`),s=e.length-Math.min(e.length,n);return s>0?[...r,`+ ${s} more files`]:r}function pt(e,t,n){const r=e.slice(0,n),s=r.flatMap(a=>me(a,t,"type")),o=r.flatMap(a=>me(a,t,"value")),i=e.length-Math.min(e.length,n),l={};return o.length>0&&(l.value=o),s.length>0&&(l.type=s),i>0&&(l.moreFiles=`+ ${i} more files`),l}function ht(e,t,n){const r=new Set(t.filter(o=>z(o.symbols).length>0).map(o=>o.to)),s=e.filter(o=>!r.has(o));return n.compactList(s,S)}function me(e,t,n){const r=z(e.symbols).filter(s=>s.usage===n);return r.length===0?[]:[`${t.compactPath(e.to)}${V(r)}`]}function V(e){const t=z(e);return t.length===0?"":`: ${mt(t,4).join(", ")}`}function mt(e,t){const n=e.slice(0,t).map(s=>s.name),r=e.length-Math.min(e.length,t);return r>0?[...n,`+ ${r} more symbols`]:n}function z(e){return(e??[]).map(t=>typeof t=="string"?L(t,"value"):t).filter(t=>t.name.trim()!=="")}function dt(e,t){const n=$(e,(0,A.resolveSessionFileArgument)(e,t)),r=JSON.parse(x.readFileSync(n,"utf8"));if(!yt(r))throw new y.CliError("INVALID_GRAPH_FILE","inspect graph --from-file expects a graph JSON file created by inspect graph --to-file.");return r}function gt(e,t,n){const r=$(e,t);return x.mkdirSync(d.dirname(r),{recursive:!0}),x.writeFileSync(r,`${JSON.stringify(n,null,2)}
9
- `),r}function yt(e){return!!e&&typeof e=="object"&&!Array.isArray(e)&&e.operation==="inspect.graph"&&Array.isArray(e.files)&&Array.isArray(e.edges)}function M(e){return typeof e=="string"&&e.trim()!==""?e.trim():null}function G(e){return typeof e=="string"&&e.trim()!==""?[e.trim()]:Array.isArray(e)?e.filter(t=>typeof t=="string"&&t.trim()!=="").map(t=>t.trim()):null}function w(e){return typeof e=="boolean"?e:null}function de(e){return{hubs:(0,A.readSessionBooleanPref)(e,"inspect.graph.hubs",!0),entrypoints:(0,A.readSessionBooleanPref)(e,"inspect.graph.entrypoints",!0),leaves:(0,A.readSessionBooleanPref)(e,"inspect.graph.leaves",!0),edges:(0,A.readSessionBooleanPref)(e,"inspect.graph.edges",!0)}}function bt(e,t){const n=de(e);return{hubs:w(t.hubs)??w(t.showHubs)??n.hubs,entrypoints:w(t.entrypoints)??w(t.scopeEntrypoints)??w(t.showEntrypoints)??n.entrypoints,leaves:w(t.leaves)??w(t.scopeLeaves)??w(t.showLeaves)??n.leaves,edges:w(t.edges)??w(t.showEdges)??n.edges}}function xt(e){if(e===void 0)return;const t=typeof e=="number"?e:typeof e=="string"?Number.parseInt(e,10):Number.NaN;if(!Number.isInteger(t)||t<0||t>2)throw new y.CliError("INVALID_GRAPH_DEPTH","inspect graph depth expects 0, 1, or 2.");return t}function ge(e){if(e==="local"||e==="neighbors"||e==="expanded")return e;throw new y.CliError("INVALID_GRAPH_VIEW","inspect graph view expects local, neighbors, or expanded.")}function ye(e){return e==="local"?0:e==="expanded"?2:1}function be(e){return e===0?"local":e===2?"expanded":"neighbors"}function R(e,t,n){if(n)return;if(t.length!==1)return"neighbors";const r=$(e,t[0]);return x.existsSync(r)&&x.statSync(r).isDirectory()?"local":"neighbors"}function St(e,t){const n=e.indexOf(t);return n>=0?e[n+1]:void 0}function N(e){return!!e&&typeof e=="object"&&!Array.isArray(e)}function W(e){return j.includes(d.extname(e))&&!e.endsWith(".d.ts")}function vt(e){if(e.startsWith("node:"))return e;if(e.startsWith("@")){const t=e.split("/");return t.length>=2?`${t[0]}/${t[1]}`:e}return e.split("/")[0]??e}function $(e,t){return d.resolve(e,t)}function I(e,t){return F(d.relative(e,d.resolve(t)))}function F(e){return e.replace(/\\/g,"/").replace(/^\.\//,"")}function _t(e,t){const n=d.relative(e,t);return n&&!n.startsWith("..")?F(n):t}function U(e){return Array.from(new Set(e)).sort()}function wt(e,t){return e.from.localeCompare(t.from)||e.to.localeCompare(t.to)||e.specifier.localeCompare(t.specifier)}function Pt(e,t){return At(e.slice(0,t),e.length)}function At(e,t){const n=t-e.length;return n>0?[...e,`+ ${n} more`]:e}function Et(e){return e.filter(t=>t.importedBy.length===0&&t.imports.length>0).length}function $t(e){return e.filter(t=>t.imports.length===0&&t.importedBy.length>0).length}
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.isInspectGraphRequest = isInspectGraphRequest;
37
+ exports.runInspectGraph = runInspectGraph;
38
+ exports.formatGraphAgentText = formatGraphAgentText;
39
+ exports.buildInspectGraphModel = buildInspectGraphModel;
40
+ const fs = __importStar(require("node:fs"));
41
+ const path = __importStar(require("node:path"));
42
+ const glob_match_1 = require("../config/glob-match");
43
+ const local_config_1 = require("../config/local-config");
44
+ const agent_text_1 = require("../shared/agent-text");
45
+ const errors_1 = require("../shared/errors");
46
+ const session_workspace_1 = require("./session-workspace");
47
+ const json_file_input_1 = require("./json-file-input");
48
+ const GRAPH_SOURCE_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts"];
49
+ const GRAPH_IMPORT_EXTENSIONS = [".ts", ".tsx", ".mts", ".cts", ".js", ".jsx", ".mjs", ".cjs"];
50
+ const GRAPH_EXCLUDED_DIRS = new Set(["node_modules", ".git", "dist", "out", "build", ".tmp"]);
51
+ const DEFAULT_EDGE_LIMIT = 12;
52
+ const DEFAULT_LIST_LIMIT = 8;
53
+ const TSCONFIG_FILE_NAME = "tsconfig.json";
54
+ function isInspectGraphRequest(restArgs, stdinPayload) {
55
+ return restArgs[0] === "graph";
56
+ }
57
+ function runInspectGraph(cwd, restArgs, stdinPayload) {
58
+ const localConfig = (0, local_config_1.resolveLocalCliConfig)(cwd);
59
+ const payload = readGraphInputPayload(cwd, restArgs, stdinPayload);
60
+ if (payload) {
61
+ const requests = expandGraphPayloadRequests(payload);
62
+ const results = requests.map((request, index) => {
63
+ if (!isObject(request)) {
64
+ throw new errors_1.CliError("INVALID_GRAPH_REQUEST", `inspect graph request at index ${index} must be an object.`);
65
+ }
66
+ return runGraphRequest(cwd, parseGraphOptionsFromPayload(cwd, request, localConfig.config.inspect.graph.exclude));
67
+ });
68
+ return results.length === 1
69
+ ? results[0]
70
+ : formatGraphBatchResponse(results);
71
+ }
72
+ return runGraphRequest(cwd, parseGraphOptions(cwd, restArgs, localConfig.config.inspect.graph.exclude));
73
+ }
74
+ function runGraphRequest(cwd, options) {
75
+ const model = options.fromFile ? readGraphModel(cwd, options.fromFile) : buildGraphModel(cwd, options);
76
+ const writtenTo = options.toFile ? writeGraphModel(cwd, options.toFile, model) : null;
77
+ const saved = options.save ? (0, session_workspace_1.saveSessionOutputJson)(cwd, "graph", options.save, model) : null;
78
+ const response = formatGraphResponse(cwd, model, {
79
+ focus: options.focus,
80
+ depth: options.depth,
81
+ writtenTo,
82
+ symbols: options.symbols,
83
+ symbolUsage: options.symbolUsage,
84
+ sections: options.sections,
85
+ ...(options.view !== undefined ? { view: options.view } : {})
86
+ });
87
+ if (saved) {
88
+ response.saved = saved.saved;
89
+ response.next = `Focus with: aib inspect graph --from-file ${saved.saved} --focus <file>`;
90
+ }
91
+ return (0, agent_text_1.attachAgentText)(response, formatGraphAgentText(response));
92
+ }
93
+ function formatGraphBatchResponse(results) {
94
+ const saved = results
95
+ .map((result) => typeof result.saved === "string" ? result.saved : "")
96
+ .filter((value) => value !== "");
97
+ const response = {
98
+ operation: "inspect.graphBatch",
99
+ summary: `${results.length} graph requests${saved.length > 0 ? `, ${saved.length} saved` : ""}`,
100
+ results: results.map(formatGraphBatchResult)
101
+ };
102
+ if (saved.length > 0) {
103
+ response.saved = saved;
104
+ response.next = "Focus a saved graph with: aib inspect graph --from-file <saved> --focus <file>";
105
+ }
106
+ else {
107
+ response.next = "Focus files with --focus, or inspect exports/code on relevant files.";
108
+ }
109
+ return (0, agent_text_1.attachAgentText)(response, formatGraphAgentText(response));
110
+ }
111
+ function formatGraphBatchResult(result) {
112
+ const entries = Object.entries(result).filter(([key]) => key !== "operation" &&
113
+ key !== "last" &&
114
+ key !== "next" &&
115
+ !(key === "graphFile" && typeof result.saved === "string"));
116
+ return Object.fromEntries(entries);
117
+ }
118
+ function formatGraphAgentText(response) {
119
+ const operation = typeof response.operation === "string" ? response.operation : "";
120
+ if (operation !== "inspect.graph" && operation !== "inspect.graphBatch") {
121
+ return null;
122
+ }
123
+ const lines = [operation];
124
+ if (typeof response.summary === "string") {
125
+ lines.push(response.summary);
126
+ }
127
+ const batchResults = Array.isArray(response.results) ? response.results : null;
128
+ if (batchResults) {
129
+ appendGraphScalar(lines, "view", response.view);
130
+ appendGraphScalar(lines, "excluded", response.excluded);
131
+ appendGraphPaths(lines, response.paths);
132
+ }
133
+ if (batchResults) {
134
+ batchResults.forEach((item, index) => {
135
+ if (!isObject(item)) {
136
+ return;
137
+ }
138
+ lines.push(`[${index + 1}] ${typeof item.summary === "string" ? item.summary : "graph result"}`);
139
+ appendGraphResponseBody(lines, item);
140
+ });
141
+ }
142
+ else {
143
+ appendGraphResponseBody(lines, response);
144
+ }
145
+ if (!batchResults) {
146
+ appendGraphList(lines, "saved", response.saved);
147
+ }
148
+ appendGraphScalar(lines, "next", response.next);
149
+ return lines.join("\n");
150
+ }
151
+ function appendGraphResponseBody(lines, response) {
152
+ appendGraphScalar(lines, "view", response.view);
153
+ appendGraphScalar(lines, "excluded", response.excluded);
154
+ appendGraphPaths(lines, response.paths);
155
+ appendGraphList(lines, "hubs", response.hubs);
156
+ appendGraphList(lines, "scopeEntrypoints", response.scopeEntrypoints);
157
+ appendGraphList(lines, "scopeLeaves", response.scopeLeaves);
158
+ appendGraphList(lines, "edges", response.edges);
159
+ appendGraphFocus(lines, response.focus);
160
+ appendGraphScalar(lines, "saved", response.saved);
161
+ }
162
+ function appendGraphFocus(lines, focusValue) {
163
+ if (!Array.isArray(focusValue) || focusValue.length === 0) {
164
+ return;
165
+ }
166
+ lines.push("focus:");
167
+ for (const rawFocus of focusValue) {
168
+ if (!isObject(rawFocus)) {
169
+ continue;
170
+ }
171
+ const file = typeof rawFocus.file === "string" ? rawFocus.file : "unknown";
172
+ lines.push(`${file}:`);
173
+ appendGraphList(lines, "imports", rawFocus.imports);
174
+ appendGraphList(lines, "symbols", rawFocus.symbols);
175
+ appendGraphUsage(lines, rawFocus.usage);
176
+ appendGraphList(lines, "importsOther", rawFocus.importsOther);
177
+ appendGraphList(lines, "importedBy", rawFocus.importedBy);
178
+ appendGraphList(lines, "external", rawFocus.external);
179
+ appendGraphList(lines, "omittedLocalImports", rawFocus.omittedLocalImports);
180
+ appendGraphScalar(lines, "error", rawFocus.error);
181
+ }
182
+ }
183
+ function appendGraphUsage(lines, usageValue) {
184
+ if (!isObject(usageValue)) {
185
+ return;
186
+ }
187
+ for (const key of ["value", "type", "unknown"]) {
188
+ appendGraphList(lines, `usage.${key}`, usageValue[key]);
189
+ }
190
+ }
191
+ function appendGraphPaths(lines, pathsValue) {
192
+ if (!isObject(pathsValue) || Object.keys(pathsValue).length === 0) {
193
+ return;
194
+ }
195
+ lines.push("paths:");
196
+ for (const [token, prefix] of Object.entries(pathsValue)) {
197
+ if (typeof prefix === "string") {
198
+ lines.push(`${token} = ${prefix}`);
199
+ }
200
+ }
201
+ }
202
+ function appendGraphScalar(lines, label, value) {
203
+ if (typeof value === "string" && value !== "") {
204
+ lines.push(`${label}: ${value}`);
205
+ }
206
+ }
207
+ function appendGraphList(lines, label, value) {
208
+ const items = Array.isArray(value) ? value.filter((item) => typeof item === "string" && item !== "") : [];
209
+ if (items.length === 0) {
210
+ return;
211
+ }
212
+ lines.push(`${label}:`);
213
+ for (const item of items) {
214
+ lines.push(item);
215
+ }
216
+ }
217
+ function readGraphInputPayload(cwd, restArgs, stdinPayload) {
218
+ if (stdinPayload !== undefined) {
219
+ if (!isObject(stdinPayload)) {
220
+ throw new errors_1.CliError("INVALID_GRAPH_STDIN", "inspect graph --stdin expects a JSON object payload.");
221
+ }
222
+ return stdinPayload;
223
+ }
224
+ const fromJson = readFlagValue(restArgs, "--from-json");
225
+ return fromJson ? (0, json_file_input_1.readJsonObjectFile)(cwd, fromJson, "INVALID_GRAPH_JSON_FILE") : null;
226
+ }
227
+ function expandGraphPayloadRequests(payload) {
228
+ return Array.isArray(payload.requests) ? payload.requests : [payload];
229
+ }
230
+ function parseGraphOptions(cwd, restArgs, configExcludePatterns) {
231
+ const scopes = [];
232
+ const focus = [];
233
+ const cliExcludePatterns = [];
234
+ const excludeFromFiles = [];
235
+ let depth;
236
+ let view;
237
+ let toFile;
238
+ let fromFile;
239
+ let save;
240
+ let symbols = (0, session_workspace_1.readSessionBooleanPref)(cwd, "inspect.graph.symbols", false);
241
+ let symbolUsage = (0, session_workspace_1.readSessionBooleanPref)(cwd, "inspect.graph.symbolUsage", false);
242
+ for (let index = 1; index < restArgs.length; index += 1) {
243
+ const arg = restArgs[index];
244
+ if (!arg) {
245
+ continue;
246
+ }
247
+ if (arg === "--focus") {
248
+ const value = restArgs[index + 1];
249
+ if (!value) {
250
+ throw new errors_1.CliError("MISSING_FLAG_VALUE", "Expected a value after --focus.");
251
+ }
252
+ focus.push(toGraphPath(cwd, resolveMaybeRelative(cwd, value)));
253
+ index += 1;
254
+ continue;
255
+ }
256
+ if (arg === "--depth") {
257
+ const value = restArgs[index + 1];
258
+ const parsed = value === undefined ? Number.NaN : Number.parseInt(value, 10);
259
+ if (!Number.isInteger(parsed) || parsed < 0 || parsed > 2) {
260
+ throw new errors_1.CliError("INVALID_GRAPH_DEPTH", "inspect graph --depth expects 0, 1, or 2.");
261
+ }
262
+ depth = parsed;
263
+ index += 1;
264
+ continue;
265
+ }
266
+ if (arg === "--view") {
267
+ const value = restArgs[index + 1];
268
+ if (!value) {
269
+ throw new errors_1.CliError("MISSING_FLAG_VALUE", "Expected a value after --view.");
270
+ }
271
+ view = readGraphView(value);
272
+ index += 1;
273
+ continue;
274
+ }
275
+ if (arg === "--to-file") {
276
+ const value = restArgs[index + 1];
277
+ if (!value) {
278
+ throw new errors_1.CliError("MISSING_FLAG_VALUE", "Expected a value after --to-file.");
279
+ }
280
+ toFile = value;
281
+ index += 1;
282
+ continue;
283
+ }
284
+ if (arg === "--from-file") {
285
+ const value = restArgs[index + 1];
286
+ if (!value) {
287
+ throw new errors_1.CliError("MISSING_FLAG_VALUE", "Expected a value after --from-file.");
288
+ }
289
+ fromFile = value;
290
+ index += 1;
291
+ continue;
292
+ }
293
+ if (arg === "--save") {
294
+ const value = restArgs[index + 1];
295
+ if (!value) {
296
+ throw new errors_1.CliError("MISSING_FLAG_VALUE", "Expected a value after --save.");
297
+ }
298
+ save = value;
299
+ index += 1;
300
+ continue;
301
+ }
302
+ if (arg === "--exclude") {
303
+ const value = restArgs[index + 1];
304
+ if (!value) {
305
+ throw new errors_1.CliError("MISSING_FLAG_VALUE", "Expected a value after --exclude.");
306
+ }
307
+ cliExcludePatterns.push(value);
308
+ index += 1;
309
+ continue;
310
+ }
311
+ if (arg === "--exclude-from") {
312
+ const value = restArgs[index + 1];
313
+ if (!value) {
314
+ throw new errors_1.CliError("MISSING_FLAG_VALUE", "Expected a value after --exclude-from.");
315
+ }
316
+ excludeFromFiles.push(value);
317
+ index += 1;
318
+ continue;
319
+ }
320
+ if (arg === "--symbols") {
321
+ symbols = true;
322
+ continue;
323
+ }
324
+ if (arg === "--symbol-usage") {
325
+ symbols = true;
326
+ symbolUsage = true;
327
+ continue;
328
+ }
329
+ if (arg.startsWith("--")) {
330
+ throw new errors_1.CliError("UNKNOWN_INSPECT_GRAPH_FLAG", `Unknown inspect graph flag: ${arg}`);
331
+ }
332
+ scopes.push(toGraphPath(cwd, resolveMaybeRelative(cwd, arg)));
333
+ }
334
+ if (fromFile && scopes.length > 0) {
335
+ throw new errors_1.CliError("GRAPH_INPUT_SOURCE_CONFLICT", "Use either inspect graph <scopes...> or --from-file, not both.");
336
+ }
337
+ if (toFile && save) {
338
+ throw new errors_1.CliError("GRAPH_OUTPUT_TARGET_CONFLICT", "Use either inspect graph --to-file or --save, not both.");
339
+ }
340
+ if (!fromFile && scopes.length === 0) {
341
+ throw new errors_1.CliError("GRAPH_SCOPE_REQUIRED", "inspect graph expects at least one file or directory scope.");
342
+ }
343
+ const effectiveDepth = depth ?? graphViewDepth(view ?? defaultGraphView(cwd, scopes, fromFile));
344
+ const effectiveView = depth !== undefined ? graphViewFromDepth(depth) : view ?? defaultGraphView(cwd, scopes, fromFile);
345
+ return {
346
+ scopes,
347
+ focus,
348
+ depth: effectiveDepth,
349
+ symbols: symbols || symbolUsage,
350
+ symbolUsage,
351
+ sections: readGraphSectionsFromPrefs(cwd),
352
+ excludePatterns: uniqueSorted([
353
+ ...configExcludePatterns,
354
+ ...excludeFromFiles.flatMap((file) => readExcludePatternsFile(cwd, file)),
355
+ ...cliExcludePatterns
356
+ ]),
357
+ ...(save !== undefined ? { save } : {}),
358
+ ...(toFile !== undefined ? { toFile } : {}),
359
+ ...(fromFile !== undefined ? { fromFile } : {}),
360
+ ...(effectiveView !== undefined ? { view: effectiveView } : {})
361
+ };
362
+ }
363
+ function parseGraphOptionsFromPayload(cwd, payload, configExcludePatterns) {
364
+ const rawScopes = readStringArray(payload.scopes) ?? readStringArray(payload.scope) ?? readStringArray(payload.files) ?? readStringArray(payload.file) ?? [];
365
+ const rawFocus = readStringArray(payload.focus) ?? [];
366
+ const rawExclude = readStringArray(payload.exclude) ?? readStringArray(payload.excludePatterns) ?? [];
367
+ const rawExcludeFrom = readStringArray(payload.excludeFrom) ?? [];
368
+ const fromFile = readString(payload.fromFile) ?? readString(payload.from);
369
+ const toFile = readString(payload.toFile) ?? readString(payload.outputFile);
370
+ const save = readString(payload.save);
371
+ const requestedDepth = readOptionalGraphDepth(payload.depth);
372
+ const requestedView = payload.view !== undefined ? readGraphView(payload.view) : undefined;
373
+ const requestedSymbolUsage = readBoolean(payload.symbolUsage);
374
+ const effectiveSymbolUsage = requestedSymbolUsage ?? (0, session_workspace_1.readSessionBooleanPref)(cwd, "inspect.graph.symbolUsage", false);
375
+ const effectiveSymbols = effectiveSymbolUsage ||
376
+ (readBoolean(payload.symbols) ?? (0, session_workspace_1.readSessionBooleanPref)(cwd, "inspect.graph.symbols", false));
377
+ if (fromFile && rawScopes.length > 0) {
378
+ throw new errors_1.CliError("GRAPH_INPUT_SOURCE_CONFLICT", "Use either inspect graph scopes or fromFile/from, not both.");
379
+ }
380
+ if (toFile && save) {
381
+ throw new errors_1.CliError("GRAPH_OUTPUT_TARGET_CONFLICT", "Use either toFile or save, not both.");
382
+ }
383
+ if (!fromFile && rawScopes.length === 0) {
384
+ throw new errors_1.CliError("GRAPH_SCOPE_REQUIRED", "inspect graph JSON expects scope/scopes or fromFile/from.");
385
+ }
386
+ const scopes = rawScopes.map((scope) => toGraphPath(cwd, resolveMaybeRelative(cwd, scope)));
387
+ const effectiveDepth = requestedDepth ?? graphViewDepth(requestedView ?? defaultGraphView(cwd, scopes, fromFile ?? undefined));
388
+ const effectiveView = requestedDepth !== undefined ? graphViewFromDepth(requestedDepth) : requestedView ?? defaultGraphView(cwd, scopes, fromFile ?? undefined);
389
+ return {
390
+ scopes,
391
+ focus: rawFocus.map((focus) => toGraphPath(cwd, resolveMaybeRelative(cwd, focus))),
392
+ depth: effectiveDepth,
393
+ symbols: effectiveSymbols,
394
+ symbolUsage: effectiveSymbolUsage,
395
+ sections: readGraphSectionsFromPayload(cwd, payload),
396
+ excludePatterns: uniqueSorted([
397
+ ...configExcludePatterns,
398
+ ...rawExcludeFrom.flatMap((file) => readExcludePatternsFile(cwd, file)),
399
+ ...rawExclude
400
+ ]),
401
+ ...(save ? { save } : {}),
402
+ ...(toFile ? { toFile } : {}),
403
+ ...(fromFile ? { fromFile } : {}),
404
+ ...(effectiveView !== undefined ? { view: effectiveView } : {})
405
+ };
406
+ }
407
+ function buildGraphModel(cwd, options) {
408
+ const tsconfigResolver = createTsConfigResolver(cwd);
409
+ const excludeFilter = createGraphExcludeFilter(cwd, options.excludePatterns);
410
+ const files = collectScopedFiles(cwd, options.scopes, excludeFilter);
411
+ const visited = new Set(files);
412
+ let frontier = files;
413
+ for (let level = 0; level < options.depth; level += 1) {
414
+ const next = new Set();
415
+ for (const file of frontier) {
416
+ for (const resolved of readLocalImports(cwd, file, tsconfigResolver).imports) {
417
+ if (!excludeFilter.isExcluded(resolved) && !visited.has(resolved)) {
418
+ visited.add(resolved);
419
+ next.add(resolved);
420
+ }
421
+ }
422
+ }
423
+ frontier = Array.from(next).sort();
424
+ }
425
+ const allFiles = Array.from(visited).sort();
426
+ const graphPathSet = new Set(allFiles.map((file) => toGraphPath(cwd, file)));
427
+ const edgeMap = new Map();
428
+ const externalByFile = new Map();
429
+ const omittedLocalImportsByFile = new Map();
430
+ for (const file of allFiles) {
431
+ const parsed = readLocalImports(cwd, file, tsconfigResolver);
432
+ const from = toGraphPath(cwd, file);
433
+ externalByFile.set(from, parsed.external);
434
+ const omittedLocalImports = [];
435
+ for (const target of parsed.imports) {
436
+ if (excludeFilter.isExcluded(target)) {
437
+ continue;
438
+ }
439
+ const to = toGraphPath(cwd, target);
440
+ if (!graphPathSet.has(to)) {
441
+ omittedLocalImports.push(to);
442
+ continue;
443
+ }
444
+ edgeMap.set(`${from}\n${to}\n${parsed.specifiers.get(target) ?? ""}`, {
445
+ from,
446
+ to,
447
+ specifier: parsed.specifiers.get(target) ?? "",
448
+ resolution: parsed.resolutions.get(target) ?? "relative",
449
+ symbols: parsed.symbols.get(target) ?? []
450
+ });
451
+ }
452
+ if (omittedLocalImports.length > 0) {
453
+ omittedLocalImportsByFile.set(from, uniqueSorted(omittedLocalImports));
454
+ }
455
+ }
456
+ const edges = Array.from(edgeMap.values()).sort(compareEdges);
457
+ const fileMap = new Map();
458
+ for (const file of allFiles) {
459
+ const graphPath = toGraphPath(cwd, file);
460
+ const filePayload = {
461
+ file: graphPath,
462
+ imports: [],
463
+ importedBy: [],
464
+ external: externalByFile.get(graphPath) ?? []
465
+ };
466
+ const omittedLocalImports = omittedLocalImportsByFile.get(graphPath);
467
+ if (omittedLocalImports && omittedLocalImports.length > 0) {
468
+ filePayload.omittedLocalImports = omittedLocalImports;
469
+ }
470
+ fileMap.set(graphPath, filePayload);
471
+ }
472
+ for (const edge of edges) {
473
+ fileMap.get(edge.from)?.imports.push(edge.to);
474
+ fileMap.get(edge.to)?.importedBy.push(edge.from);
475
+ }
476
+ const externalPackages = uniqueSorted(Array.from(externalByFile.values()).flat());
477
+ const excluded = excludeFilter.excluded.size > 0
478
+ ? {
479
+ count: excludeFilter.excluded.size,
480
+ patterns: options.excludePatterns
481
+ }
482
+ : undefined;
483
+ return {
484
+ operation: "inspect.graph",
485
+ version: 1,
486
+ root: path.resolve(cwd),
487
+ scopes: options.scopes,
488
+ generatedAt: new Date().toISOString(),
489
+ files: Array.from(fileMap.values()).sort((left, right) => left.file.localeCompare(right.file)),
490
+ edges,
491
+ externalPackages,
492
+ timeoutHint: buildGraphTimeoutHint(fileMap.size, edges.length, options.view),
493
+ ...(excluded ? { excluded } : {})
494
+ };
495
+ }
496
+ function buildInspectGraphModel(cwd, options) {
497
+ return buildGraphModel(cwd, {
498
+ scopes: options.scopes,
499
+ focus: [],
500
+ depth: options.depth,
501
+ symbols: true,
502
+ symbolUsage: options.symbolUsage ?? true,
503
+ sections: {
504
+ hubs: false,
505
+ entrypoints: false,
506
+ leaves: false,
507
+ edges: true
508
+ },
509
+ excludePatterns: options.excludePatterns ?? []
510
+ });
511
+ }
512
+ function buildGraphTimeoutHint(fileCount, edgeCount, view) {
513
+ const viewMultiplier = view === "expanded" ? 2 : view === "neighbors" ? 1.5 : 1;
514
+ const recommendedTimeoutMs = Math.min(600_000, Math.max(60_000, Math.round((30_000 + fileCount * 250 + edgeCount * 100) * viewMultiplier)));
515
+ return {
516
+ recommendedTimeoutMs,
517
+ fileCount,
518
+ edgeCount,
519
+ view: view ?? "local"
520
+ };
521
+ }
522
+ function collectScopedFiles(cwd, scopes, excludeFilter) {
523
+ const files = new Set();
524
+ for (const scope of scopes) {
525
+ const absolute = resolveMaybeRelative(cwd, scope);
526
+ if (!fs.existsSync(absolute)) {
527
+ throw new errors_1.CliError("GRAPH_SCOPE_NOT_FOUND", `Graph scope does not exist: ${scope}`);
528
+ }
529
+ const stat = fs.statSync(absolute);
530
+ if (stat.isDirectory()) {
531
+ for (const file of walkSourceFiles(absolute)) {
532
+ if (!excludeFilter.isExcluded(file)) {
533
+ files.add(file);
534
+ }
535
+ }
536
+ continue;
537
+ }
538
+ if (stat.isFile() && isGraphSourceFile(absolute) && !excludeFilter.isExcluded(absolute)) {
539
+ files.add(absolute);
540
+ }
541
+ }
542
+ return Array.from(files).sort();
543
+ }
544
+ function createGraphExcludeFilter(cwd, patterns) {
545
+ const normalizedPatterns = uniqueSorted(patterns.map((pattern) => normalizeGraphPath(pattern.trim())).filter(Boolean));
546
+ const excluded = new Set();
547
+ return {
548
+ patterns: normalizedPatterns,
549
+ excluded,
550
+ isExcluded(file) {
551
+ if (normalizedPatterns.length === 0) {
552
+ return false;
553
+ }
554
+ const graphPath = toGraphPath(cwd, file);
555
+ const matches = (0, glob_match_1.matchesAnyGlob)(graphPath, normalizedPatterns);
556
+ if (matches) {
557
+ excluded.add(graphPath);
558
+ }
559
+ return matches;
560
+ }
561
+ };
562
+ }
563
+ function walkSourceFiles(dir) {
564
+ const files = [];
565
+ for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
566
+ if (entry.isDirectory()) {
567
+ if (!GRAPH_EXCLUDED_DIRS.has(entry.name)) {
568
+ files.push(...walkSourceFiles(path.join(dir, entry.name)));
569
+ }
570
+ continue;
571
+ }
572
+ const filePath = path.join(dir, entry.name);
573
+ if (entry.isFile() && isGraphSourceFile(filePath)) {
574
+ files.push(filePath);
575
+ }
576
+ }
577
+ return files;
578
+ }
579
+ function readExcludePatternsFile(cwd, rawFile) {
580
+ const filePath = resolveMaybeRelative(cwd, rawFile);
581
+ try {
582
+ return fs.readFileSync(filePath, "utf8")
583
+ .split(/\r?\n/)
584
+ .map((line) => line.trim())
585
+ .filter((line) => line.length > 0 && !line.startsWith("#"));
586
+ }
587
+ catch {
588
+ throw new errors_1.CliError("GRAPH_EXCLUDE_FILE_NOT_FOUND", `Could not read inspect graph --exclude-from file: ${rawFile}`);
589
+ }
590
+ }
591
+ function readLocalImports(cwd, file, tsconfigResolver) {
592
+ const text = fs.readFileSync(file, "utf8");
593
+ const imports = new Set();
594
+ const external = new Set();
595
+ const specifiers = new Map();
596
+ const resolutions = new Map();
597
+ const symbols = new Map();
598
+ for (const reference of collectModuleReferences(text)) {
599
+ const { specifier } = reference;
600
+ if (specifier.startsWith(".")) {
601
+ const resolved = resolveLocalImport(file, specifier);
602
+ if (resolved) {
603
+ imports.add(resolved);
604
+ specifiers.set(resolved, specifier);
605
+ resolutions.set(resolved, "relative");
606
+ symbols.set(resolved, mergeSymbols(symbols.get(resolved), reference.symbols));
607
+ }
608
+ continue;
609
+ }
610
+ const resolved = tsconfigResolver.resolve(file, specifier);
611
+ if (resolved) {
612
+ imports.add(resolved);
613
+ specifiers.set(resolved, specifier);
614
+ resolutions.set(resolved, "tsconfig-paths");
615
+ symbols.set(resolved, mergeSymbols(symbols.get(resolved), reference.symbols));
616
+ continue;
617
+ }
618
+ external.add(toExternalPackageName(specifier));
619
+ }
620
+ return {
621
+ imports: Array.from(imports).sort(),
622
+ external: Array.from(external).sort(),
623
+ specifiers,
624
+ resolutions,
625
+ symbols
626
+ };
627
+ }
628
+ function collectModuleReferences(text) {
629
+ const references = [];
630
+ const seen = new Set();
631
+ const importText = stripCommentsOutsideStrings(text);
632
+ const structuredImportPattern = /\bimport\s+(type\s+)?(?:([$A-Z_a-z][$\w]*)\s*,\s*)?(\*\s+as\s+[$A-Z_a-z][$\w]*|\{[\s\S]*?\})\s+from\s+["']([^"']+)["']/g;
633
+ for (const match of importText.matchAll(structuredImportPattern)) {
634
+ const defaultName = match[2]?.trim();
635
+ const namedClause = match[3]?.trim() ?? "";
636
+ const specifier = match[4]?.trim();
637
+ addModuleReference(references, seen, specifier, parseImportSymbols(defaultName, namedClause, Boolean(match[1])));
638
+ }
639
+ const defaultImportPattern = /\bimport\s+(type\s+)?([$A-Z_a-z][$\w]*)\s+from\s+["']([^"']+)["']/g;
640
+ for (const match of importText.matchAll(defaultImportPattern)) {
641
+ const defaultName = match[2]?.trim();
642
+ const specifier = match[3]?.trim();
643
+ addModuleReference(references, seen, specifier, defaultName ? [createImportSymbol(`default:${defaultName}`, Boolean(match[1]) ? "type" : "value")] : []);
644
+ }
645
+ const exportFromPattern = /\bexport\s+(type\s+)?(\{[\s\S]*?\}|\*)\s+from\s+["']([^"']+)["']/g;
646
+ for (const match of importText.matchAll(exportFromPattern)) {
647
+ const exportClause = match[2]?.trim() ?? "";
648
+ const specifier = match[3]?.trim();
649
+ addModuleReference(references, seen, specifier, exportClause === "*" ? [createImportSymbol("*", Boolean(match[1]) ? "type" : "value")] : parseNamedBindings(exportClause, Boolean(match[1])));
650
+ }
651
+ const specifierOnlyPatterns = [
652
+ /\bimport\s+["']([^"']+)["']/g,
653
+ /\bimport\s*\(\s*["']([^"']+)["']\s*\)/g,
654
+ /\brequire\s*\(\s*["']([^"']+)["']\s*\)/g
655
+ ];
656
+ for (const pattern of specifierOnlyPatterns) {
657
+ for (const match of importText.matchAll(pattern)) {
658
+ addModuleReference(references, seen, match[1]?.trim(), []);
659
+ }
660
+ }
661
+ return references;
662
+ }
663
+ function addModuleReference(references, seen, specifier, symbols) {
664
+ if (!specifier) {
665
+ return;
666
+ }
667
+ const normalizedSymbols = uniqueSortedImportSymbols(symbols.filter((symbol) => symbol.name.trim() !== ""));
668
+ const key = `${specifier}\n${normalizedSymbols.map((symbol) => `${symbol.usage}:${symbol.name}`).join("\n")}`;
669
+ if (seen.has(key)) {
670
+ return;
671
+ }
672
+ seen.add(key);
673
+ references.push({
674
+ specifier,
675
+ symbols: normalizedSymbols
676
+ });
677
+ }
678
+ function parseImportSymbols(defaultName, namedClause, typeOnly) {
679
+ const usage = typeOnly ? "type" : "value";
680
+ const symbols = [];
681
+ if (defaultName) {
682
+ symbols.push(createImportSymbol(`default:${defaultName}`, usage));
683
+ }
684
+ const namespaceMatch = namedClause.match(/^\*\s+as\s+([$A-Z_a-z][$\w]*)$/);
685
+ if (namespaceMatch?.[1]) {
686
+ symbols.push(createImportSymbol(`*:${namespaceMatch[1]}`, usage));
687
+ return symbols;
688
+ }
689
+ return [...symbols, ...parseNamedBindings(namedClause, typeOnly)];
690
+ }
691
+ function parseNamedBindings(rawClause, typeOnly) {
692
+ const trimmed = rawClause.trim();
693
+ if (!trimmed.startsWith("{") || !trimmed.endsWith("}")) {
694
+ return [];
695
+ }
696
+ return trimmed
697
+ .slice(1, -1)
698
+ .split(",")
699
+ .map((item) => {
700
+ const trimmedItem = item.trim();
701
+ const inlineType = trimmedItem.startsWith("type ");
702
+ return {
703
+ raw: inlineType ? trimmedItem.replace(/^type\s+/, "") : trimmedItem,
704
+ usage: typeOnly || inlineType ? "type" : "value"
705
+ };
706
+ })
707
+ .filter((item) => item.raw !== "")
708
+ .map((item) => {
709
+ const aliasMatch = item.raw.match(/^([$A-Z_a-z][$\w]*)\s+as\s+([$A-Z_a-z][$\w]*)$/);
710
+ const name = aliasMatch?.[1] && aliasMatch[2] ? `${aliasMatch[1]} as ${aliasMatch[2]}` : item.raw;
711
+ return createImportSymbol(name, item.usage);
712
+ });
713
+ }
714
+ function createImportSymbol(name, usage) {
715
+ return { name, usage };
716
+ }
717
+ function mergeSymbols(existing, next) {
718
+ return uniqueSortedImportSymbols([...(existing ?? []), ...next]);
719
+ }
720
+ function uniqueSortedImportSymbols(items) {
721
+ const unique = new Map();
722
+ for (const item of items) {
723
+ unique.set(`${item.usage}:${item.name}`, item);
724
+ }
725
+ return Array.from(unique.values()).sort((left, right) => left.usage.localeCompare(right.usage) || left.name.localeCompare(right.name));
726
+ }
727
+ function resolveLocalImport(fromFile, specifier) {
728
+ const base = path.resolve(path.dirname(fromFile), specifier);
729
+ return resolveImportBase(base);
730
+ }
731
+ function resolveImportBase(base) {
732
+ const candidates = new Set();
733
+ candidates.add(base);
734
+ const ext = path.extname(base);
735
+ if (ext) {
736
+ if ([".js", ".jsx", ".mjs", ".cjs"].includes(ext)) {
737
+ const withoutExt = base.slice(0, -ext.length);
738
+ for (const sourceExt of GRAPH_SOURCE_EXTENSIONS) {
739
+ candidates.add(`${withoutExt}${sourceExt}`);
740
+ }
741
+ }
742
+ if (!GRAPH_IMPORT_EXTENSIONS.includes(ext)) {
743
+ for (const candidateExt of GRAPH_SOURCE_EXTENSIONS) {
744
+ candidates.add(`${base}${candidateExt}`);
745
+ }
746
+ }
747
+ }
748
+ else {
749
+ for (const candidateExt of GRAPH_IMPORT_EXTENSIONS) {
750
+ candidates.add(`${base}${candidateExt}`);
751
+ }
752
+ }
753
+ for (const candidateExt of GRAPH_IMPORT_EXTENSIONS) {
754
+ candidates.add(path.join(base, `index${candidateExt}`));
755
+ }
756
+ for (const candidate of candidates) {
757
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isFile() && isGraphSourceFile(candidate)) {
758
+ return candidate;
759
+ }
760
+ }
761
+ return null;
762
+ }
763
+ function createTsConfigResolver(cwd) {
764
+ const configCache = new Map();
765
+ return {
766
+ resolve(fromFile, specifier) {
767
+ const configPath = findNearestTsConfig(path.dirname(fromFile), cwd);
768
+ if (!configPath) {
769
+ return null;
770
+ }
771
+ const config = readTsConfigInfo(configPath, configCache);
772
+ if (!config || config.mappings.length === 0) {
773
+ return null;
774
+ }
775
+ for (const mapping of config.mappings) {
776
+ const wildcard = matchPathPattern(specifier, mapping);
777
+ if (wildcard === null) {
778
+ continue;
779
+ }
780
+ for (const target of mapping.targets) {
781
+ const substituted = target.includes("*") ? target.replace(/\*/g, wildcard) : target;
782
+ const base = path.resolve(config.baseUrl, substituted);
783
+ const resolved = resolveImportBase(base);
784
+ if (resolved) {
785
+ return resolved;
786
+ }
787
+ }
788
+ }
789
+ return null;
790
+ }
791
+ };
792
+ }
793
+ function findNearestTsConfig(startDir, stopDir) {
794
+ let current = path.resolve(startDir);
795
+ const stop = path.parse(path.resolve(stopDir)).root;
796
+ while (true) {
797
+ const candidate = path.join(current, TSCONFIG_FILE_NAME);
798
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
799
+ return candidate;
800
+ }
801
+ const parent = path.dirname(current);
802
+ if (parent === current || current === stop) {
803
+ return null;
804
+ }
805
+ current = parent;
806
+ }
807
+ }
808
+ function readTsConfigInfo(configPath, cache) {
809
+ const normalizedConfigPath = path.resolve(configPath);
810
+ if (cache.has(normalizedConfigPath)) {
811
+ return cache.get(normalizedConfigPath) ?? null;
812
+ }
813
+ cache.set(normalizedConfigPath, null);
814
+ const parsed = readParsedTsConfig(normalizedConfigPath);
815
+ if (!parsed) {
816
+ return null;
817
+ }
818
+ const configDir = path.dirname(normalizedConfigPath);
819
+ const baseUrl = parsed.baseUrl ? path.resolve(configDir, parsed.baseUrl) : configDir;
820
+ const mappings = Object.entries(parsed.paths ?? {})
821
+ .flatMap(([pattern, targets]) => createPathMapping(pattern, targets))
822
+ .sort((left, right) => right.specificity - left.specificity || left.pattern.localeCompare(right.pattern));
823
+ const info = {
824
+ configPath: normalizedConfigPath,
825
+ baseUrl,
826
+ mappings
827
+ };
828
+ cache.set(normalizedConfigPath, info);
829
+ return info;
830
+ }
831
+ function readParsedTsConfig(configPath) {
832
+ try {
833
+ const raw = parseJsoncObject(fs.readFileSync(configPath, "utf8"));
834
+ const parent = readExtendsTsConfig(configPath, raw.extends);
835
+ const compilerOptions = isRecord(raw.compilerOptions) ? raw.compilerOptions : {};
836
+ const paths = readPaths(compilerOptions.paths);
837
+ const baseUrl = typeof compilerOptions.baseUrl === "string"
838
+ ? path.resolve(path.dirname(configPath), compilerOptions.baseUrl)
839
+ : undefined;
840
+ return {
841
+ ...(parent ?? {}),
842
+ ...(baseUrl !== undefined ? { baseUrl } : {}),
843
+ ...(paths ? { paths } : {})
844
+ };
845
+ }
846
+ catch {
847
+ return null;
848
+ }
849
+ }
850
+ function readExtendsTsConfig(configPath, rawExtends) {
851
+ if (typeof rawExtends !== "string" || rawExtends.trim() === "") {
852
+ return null;
853
+ }
854
+ const configDir = path.dirname(configPath);
855
+ const candidates = tsConfigExtendsCandidates(configDir, rawExtends.trim());
856
+ for (const candidate of candidates) {
857
+ if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) {
858
+ return readParsedTsConfig(candidate);
859
+ }
860
+ }
861
+ return null;
862
+ }
863
+ function tsConfigExtendsCandidates(configDir, rawExtends) {
864
+ const base = rawExtends.startsWith(".") || path.isAbsolute(rawExtends)
865
+ ? path.resolve(configDir, rawExtends)
866
+ : path.resolve(configDir, "node_modules", rawExtends);
867
+ const candidates = [base];
868
+ if (!path.extname(base)) {
869
+ candidates.push(`${base}.json`, path.join(base, TSCONFIG_FILE_NAME));
870
+ }
871
+ return candidates;
872
+ }
873
+ function parseJsoncObject(text) {
874
+ const withoutComments = stripCommentsOutsideStrings(text);
875
+ const withoutTrailingCommas = withoutComments.replace(/,\s*([}\]])/g, "$1");
876
+ const parsed = JSON.parse(withoutTrailingCommas);
877
+ return isRecord(parsed) ? parsed : {};
878
+ }
879
+ function isRecord(value) {
880
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
881
+ }
882
+ function stripCommentsOutsideStrings(text) {
883
+ let result = "";
884
+ let inString = false;
885
+ let escaped = false;
886
+ for (let index = 0; index < text.length; index += 1) {
887
+ const current = text[index];
888
+ const next = text[index + 1];
889
+ if (inString) {
890
+ result += current;
891
+ if (escaped) {
892
+ escaped = false;
893
+ }
894
+ else if (current === "\\") {
895
+ escaped = true;
896
+ }
897
+ else if (current === "\"") {
898
+ inString = false;
899
+ }
900
+ continue;
901
+ }
902
+ if (current === "\"") {
903
+ inString = true;
904
+ result += current;
905
+ continue;
906
+ }
907
+ if (current === "/" && next === "/") {
908
+ while (index < text.length && text[index] !== "\n") {
909
+ index += 1;
910
+ }
911
+ result += "\n";
912
+ continue;
913
+ }
914
+ if (current === "/" && next === "*") {
915
+ index += 2;
916
+ while (index < text.length && !(text[index] === "*" && text[index + 1] === "/")) {
917
+ index += 1;
918
+ }
919
+ index += 1;
920
+ continue;
921
+ }
922
+ result += current;
923
+ }
924
+ return result;
925
+ }
926
+ function readPaths(value) {
927
+ if (!isRecord(value)) {
928
+ return null;
929
+ }
930
+ const paths = {};
931
+ for (const [key, rawTargets] of Object.entries(value)) {
932
+ if (!Array.isArray(rawTargets)) {
933
+ continue;
934
+ }
935
+ const targets = rawTargets.filter((target) => typeof target === "string" && target.trim() !== "");
936
+ if (targets.length > 0) {
937
+ paths[key] = targets;
938
+ }
939
+ }
940
+ return Object.keys(paths).length > 0 ? paths : null;
941
+ }
942
+ function createPathMapping(pattern, targets) {
943
+ if (typeof pattern !== "string" || pattern.trim() === "") {
944
+ return [];
945
+ }
946
+ const starIndex = pattern.indexOf("*");
947
+ const prefix = starIndex >= 0 ? pattern.slice(0, starIndex) : pattern;
948
+ const suffix = starIndex >= 0 ? pattern.slice(starIndex + 1) : "";
949
+ return [{
950
+ pattern,
951
+ prefix,
952
+ suffix,
953
+ targets,
954
+ specificity: prefix.length + suffix.length
955
+ }];
956
+ }
957
+ function matchPathPattern(specifier, mapping) {
958
+ if (!mapping.pattern.includes("*")) {
959
+ return specifier === mapping.pattern ? "" : null;
960
+ }
961
+ if (!specifier.startsWith(mapping.prefix) || !specifier.endsWith(mapping.suffix)) {
962
+ return null;
963
+ }
964
+ return specifier.slice(mapping.prefix.length, specifier.length - mapping.suffix.length);
965
+ }
966
+ function formatGraphResponse(cwd, model, options) {
967
+ const initialFormatter = createGraphPathFormatter(collectVisibleGraphPaths(model, options));
968
+ const initialResponse = formatGraphResponsePayload(cwd, model, options, initialFormatter);
969
+ const usefulAliases = usefulAliasesForResponse(initialResponse, initialFormatter);
970
+ const formatter = usefulAliases.length === initialFormatter.aliases.length
971
+ ? initialFormatter
972
+ : createGraphPathFormatterFromAliases(usefulAliases);
973
+ const response = formatter === initialFormatter
974
+ ? initialResponse
975
+ : formatGraphResponsePayload(cwd, model, options, formatter);
976
+ return withUsedPathAliases(response, formatter);
977
+ }
978
+ function formatGraphResponsePayload(cwd, model, options, formatter) {
979
+ const response = {
980
+ operation: "inspect.graph",
981
+ summary: `${model.files.length} files, ${model.edges.length} local edges, ${model.externalPackages.length} external packages`
982
+ };
983
+ if (model.timeoutHint) {
984
+ response.timeoutHint = model.timeoutHint;
985
+ }
986
+ if (options.view) {
987
+ response.view = options.view;
988
+ }
989
+ if (model.excluded && model.excluded.count > 0) {
990
+ response.excluded = `${model.excluded.count} files by graph.exclude`;
991
+ }
992
+ if (options.writtenTo) {
993
+ response.graphFile = options.writtenTo;
994
+ }
995
+ if (options.focus.length > 0) {
996
+ response.focus = options.focus.slice(0, 10).map((focus) => formatFocus(model, normalizeGraphPath(focus), formatter, options.symbols, options.symbolUsage));
997
+ response.next = nextHint(options, model);
998
+ return response;
999
+ }
1000
+ const hubs = model.files
1001
+ .map((file) => ({
1002
+ file: file.file,
1003
+ total: file.imports.length + file.importedBy.length,
1004
+ imports: file.imports.length,
1005
+ importedBy: file.importedBy.length
1006
+ }))
1007
+ .filter((item) => item.total > 0)
1008
+ .sort((left, right) => right.total - left.total || left.file.localeCompare(right.file))
1009
+ .slice(0, DEFAULT_LIST_LIMIT)
1010
+ .map((item) => `${formatter.compactPath(item.file)} imports ${item.imports}, importedBy ${item.importedBy}`);
1011
+ if (options.sections.hubs && hubs.length > 0) {
1012
+ response.hubs = hubs;
1013
+ }
1014
+ const entrypoints = model.files
1015
+ .filter((file) => file.importedBy.length === 0 && file.imports.length > 0)
1016
+ .sort((left, right) => right.imports.length - left.imports.length || left.file.localeCompare(right.file))
1017
+ .map((file) => file.file);
1018
+ const visibleEntrypoints = formatter.compactList(entrypoints, DEFAULT_LIST_LIMIT);
1019
+ if (options.sections.entrypoints && visibleEntrypoints.length > 0) {
1020
+ response.scopeEntrypoints = visibleEntrypoints;
1021
+ }
1022
+ const leaves = model.files
1023
+ .filter((file) => file.imports.length === 0 && file.importedBy.length > 0)
1024
+ .sort((left, right) => right.importedBy.length - left.importedBy.length || left.file.localeCompare(right.file))
1025
+ .map((file) => file.file);
1026
+ const visibleLeaves = formatter.compactList(leaves, DEFAULT_LIST_LIMIT);
1027
+ if (options.sections.leaves && visibleLeaves.length > 0) {
1028
+ response.scopeLeaves = visibleLeaves;
1029
+ }
1030
+ const edges = formatEdgeSample(model.edges, formatter, DEFAULT_EDGE_LIMIT, options.symbols);
1031
+ if (options.sections.edges && edges.length > 0) {
1032
+ response.edges = edges;
1033
+ }
1034
+ response.next = options.writtenTo
1035
+ ? `Focus saved graph: aib inspect graph --from-file ${toCliDisplayPath(cwd, options.writtenTo)} --focus <file>`
1036
+ : nextHint(options, model);
1037
+ return response;
1038
+ }
1039
+ function formatFocus(model, focus, formatter, includeSymbols, symbolUsage) {
1040
+ const file = model.files.find((item) => normalizeGraphPath(item.file) === focus);
1041
+ if (!file) {
1042
+ return {
1043
+ file: focus,
1044
+ ok: false,
1045
+ code: "GRAPH_FOCUS_NOT_FOUND",
1046
+ error: "Focus file is not present in this graph."
1047
+ };
1048
+ }
1049
+ const payload = {
1050
+ file: formatter.compactPath(file.file)
1051
+ };
1052
+ if (file.imports.length > 0) {
1053
+ if (includeSymbols) {
1054
+ const outgoingEdges = model.edges.filter((edge) => edge.from === file.file);
1055
+ if (symbolUsage) {
1056
+ const usage = formatSymbolImportUsage(outgoingEdges, formatter, DEFAULT_LIST_LIMIT);
1057
+ if (Object.keys(usage).length > 0) {
1058
+ payload.usage = usage;
1059
+ }
1060
+ const importsOther = importsWithoutVisibleSymbols(file.imports, outgoingEdges, formatter);
1061
+ if (importsOther.length > 0) {
1062
+ payload.importsOther = importsOther;
1063
+ }
1064
+ }
1065
+ else {
1066
+ payload.symbols = formatSymbolImportList(outgoingEdges, formatter, DEFAULT_LIST_LIMIT);
1067
+ }
1068
+ }
1069
+ else {
1070
+ payload.imports = formatter.compactList(file.imports, DEFAULT_LIST_LIMIT);
1071
+ }
1072
+ }
1073
+ if (file.importedBy.length > 0) {
1074
+ payload.importedBy = formatter.compactList(file.importedBy, DEFAULT_LIST_LIMIT);
1075
+ }
1076
+ if (file.external.length > 0) {
1077
+ payload.external = summarizeList(file.external, DEFAULT_LIST_LIMIT);
1078
+ }
1079
+ if (file.omittedLocalImports && file.omittedLocalImports.length > 0) {
1080
+ payload.omittedLocalImports = formatter.compactList(file.omittedLocalImports, DEFAULT_LIST_LIMIT);
1081
+ }
1082
+ return payload;
1083
+ }
1084
+ function nextHint(options, model) {
1085
+ if (options.depth === 0 && model.files.some((file) => (file.omittedLocalImports ?? []).length > 0)) {
1086
+ return "Use --depth 1 to include direct local imports outside the initial scope.";
1087
+ }
1088
+ return "Use --depth 2 for a wider local neighborhood, or inspect exports/code on focused files.";
1089
+ }
1090
+ function collectVisibleGraphPaths(model, options) {
1091
+ const paths = new Set();
1092
+ if (options.focus.length > 0) {
1093
+ for (const rawFocus of options.focus.slice(0, 10)) {
1094
+ const focus = normalizeGraphPath(rawFocus);
1095
+ const file = model.files.find((item) => normalizeGraphPath(item.file) === focus);
1096
+ if (!file) {
1097
+ continue;
1098
+ }
1099
+ paths.add(file.file);
1100
+ for (const item of file.imports.slice(0, DEFAULT_LIST_LIMIT)) {
1101
+ paths.add(item);
1102
+ }
1103
+ for (const item of file.importedBy.slice(0, DEFAULT_LIST_LIMIT)) {
1104
+ paths.add(item);
1105
+ }
1106
+ for (const item of (file.omittedLocalImports ?? []).slice(0, DEFAULT_LIST_LIMIT)) {
1107
+ paths.add(item);
1108
+ }
1109
+ if (options.symbols) {
1110
+ for (const edge of model.edges.filter((item) => item.from === file.file).slice(0, DEFAULT_LIST_LIMIT)) {
1111
+ paths.add(edge.to);
1112
+ }
1113
+ }
1114
+ }
1115
+ return Array.from(paths);
1116
+ }
1117
+ if (options.sections.hubs) {
1118
+ const hubs = model.files
1119
+ .map((file) => ({
1120
+ file: file.file,
1121
+ total: file.imports.length + file.importedBy.length,
1122
+ imports: file.imports.length,
1123
+ importedBy: file.importedBy.length
1124
+ }))
1125
+ .filter((item) => item.total > 0)
1126
+ .sort((left, right) => right.total - left.total || left.file.localeCompare(right.file))
1127
+ .slice(0, DEFAULT_LIST_LIMIT);
1128
+ for (const item of hubs) {
1129
+ paths.add(item.file);
1130
+ }
1131
+ }
1132
+ if (options.sections.entrypoints) {
1133
+ for (const item of model.files
1134
+ .filter((file) => file.importedBy.length === 0 && file.imports.length > 0)
1135
+ .sort((left, right) => right.imports.length - left.imports.length || left.file.localeCompare(right.file))
1136
+ .map((file) => file.file)
1137
+ .slice(0, DEFAULT_LIST_LIMIT)) {
1138
+ paths.add(item);
1139
+ }
1140
+ }
1141
+ if (options.sections.leaves) {
1142
+ for (const item of model.files
1143
+ .filter((file) => file.imports.length === 0 && file.importedBy.length > 0)
1144
+ .sort((left, right) => right.importedBy.length - left.importedBy.length || left.file.localeCompare(right.file))
1145
+ .map((file) => file.file)
1146
+ .slice(0, DEFAULT_LIST_LIMIT)) {
1147
+ paths.add(item);
1148
+ }
1149
+ }
1150
+ if (options.sections.edges) {
1151
+ for (const edge of model.edges.slice(0, DEFAULT_EDGE_LIMIT)) {
1152
+ paths.add(edge.from);
1153
+ paths.add(edge.to);
1154
+ }
1155
+ }
1156
+ return Array.from(paths);
1157
+ }
1158
+ function createGraphPathFormatter(pathValues) {
1159
+ return createGraphPathFormatterFromAliases(buildGraphPathAliases(pathValues));
1160
+ }
1161
+ function createGraphPathFormatterFromAliases(aliases) {
1162
+ return {
1163
+ aliases,
1164
+ compactPath(pathValue) {
1165
+ return compactGraphPath(pathValue, aliases);
1166
+ },
1167
+ compactList(paths, limit) {
1168
+ return compactPathList(paths, limit, aliases);
1169
+ }
1170
+ };
1171
+ }
1172
+ function buildGraphPathAliases(pathValues) {
1173
+ const counts = new Map();
1174
+ for (const pathValue of pathValues) {
1175
+ for (const prefix of candidatePathPrefixes(pathValue)) {
1176
+ counts.set(prefix, (counts.get(prefix) ?? 0) + 1);
1177
+ }
1178
+ }
1179
+ const usedTokens = new Set();
1180
+ const candidates = Array.from(counts.entries())
1181
+ .map(([prefix, count]) => {
1182
+ const token = `<${path.basename(prefix)}>`;
1183
+ return {
1184
+ prefix,
1185
+ count,
1186
+ token,
1187
+ score: Math.max(0, prefix.length - token.length) * count
1188
+ };
1189
+ })
1190
+ .filter((item) => item.count >= 2 && (item.score >= 16 || item.count >= 3) && item.prefix !== "src/main")
1191
+ .sort((left, right) => right.score - left.score || right.count - left.count || right.prefix.length - left.prefix.length || left.prefix.localeCompare(right.prefix))
1192
+ .filter((item) => {
1193
+ if (usedTokens.has(item.token)) {
1194
+ return false;
1195
+ }
1196
+ usedTokens.add(item.token);
1197
+ return true;
1198
+ });
1199
+ return pruneNestedAliases(candidates)
1200
+ .slice(0, 6)
1201
+ .sort((left, right) => right.prefix.length - left.prefix.length)
1202
+ .map((item) => ({
1203
+ token: item.token,
1204
+ prefix: item.prefix
1205
+ }));
1206
+ }
1207
+ function pruneNestedAliases(aliases) {
1208
+ return aliases.filter((alias) => {
1209
+ const broader = aliases.find((candidate) => candidate.prefix !== alias.prefix &&
1210
+ alias.prefix.startsWith(`${candidate.prefix}/`) &&
1211
+ candidate.count >= alias.count &&
1212
+ candidate.score >= 12 &&
1213
+ alias.score < 40);
1214
+ return !broader;
1215
+ });
1216
+ }
1217
+ function candidatePathPrefixes(pathValue) {
1218
+ const parts = normalizeGraphPath(pathValue).split("/");
1219
+ const prefixes = [];
1220
+ for (let index = 2; index < parts.length; index += 1) {
1221
+ const prefix = parts.slice(0, index).join("/");
1222
+ if (prefix.length >= 8) {
1223
+ prefixes.push(prefix);
1224
+ }
1225
+ }
1226
+ return prefixes;
1227
+ }
1228
+ function withUsedPathAliases(response, formatter) {
1229
+ const pathAliases = pathAliasesPayload(formatter, response);
1230
+ if (!pathAliases) {
1231
+ return response;
1232
+ }
1233
+ return {
1234
+ operation: response.operation ?? "inspect.graph",
1235
+ summary: response.summary ?? "",
1236
+ paths: pathAliases,
1237
+ ...Object.fromEntries(Object.entries(response).filter(([key]) => key !== "operation" && key !== "summary"))
1238
+ };
1239
+ }
1240
+ function usefulAliasesForResponse(response, formatter) {
1241
+ const serializedResponse = JSON.stringify(response);
1242
+ return formatter.aliases.filter((alias) => countOccurrences(serializedResponse, alias.token) >= 2);
1243
+ }
1244
+ function countOccurrences(text, pattern) {
1245
+ let count = 0;
1246
+ let offset = 0;
1247
+ while (true) {
1248
+ const index = text.indexOf(pattern, offset);
1249
+ if (index < 0) {
1250
+ return count;
1251
+ }
1252
+ count += 1;
1253
+ offset = index + pattern.length;
1254
+ }
1255
+ }
1256
+ function pathAliasesPayload(formatter, response) {
1257
+ if (formatter.aliases.length === 0) {
1258
+ return null;
1259
+ }
1260
+ const serializedResponse = JSON.stringify(response);
1261
+ const payload = {};
1262
+ for (const alias of formatter.aliases) {
1263
+ if (serializedResponse.includes(alias.token)) {
1264
+ payload[alias.token] = alias.prefix;
1265
+ }
1266
+ }
1267
+ return Object.keys(payload).length > 0 ? payload : null;
1268
+ }
1269
+ function compactGraphPath(pathValue, aliases) {
1270
+ const normalized = normalizeGraphPath(pathValue);
1271
+ const alias = aliases.find((candidate) => normalized === candidate.prefix || normalized.startsWith(`${candidate.prefix}/`));
1272
+ if (!alias) {
1273
+ return normalized;
1274
+ }
1275
+ if (normalized === alias.prefix) {
1276
+ return alias.token;
1277
+ }
1278
+ return `${alias.token}/${normalized.slice(alias.prefix.length + 1)}`;
1279
+ }
1280
+ function compactPathList(paths, limit, aliases) {
1281
+ const visible = paths.slice(0, limit).map((item) => compactGraphPath(item, aliases));
1282
+ const grouped = groupCompactPaths(visible);
1283
+ const hidden = paths.length - Math.min(paths.length, limit);
1284
+ return hidden > 0 ? [...grouped, `+ ${hidden} more`] : grouped;
1285
+ }
1286
+ function groupCompactPaths(paths) {
1287
+ const groups = new Map();
1288
+ const singles = [];
1289
+ for (const pathValue of paths) {
1290
+ const markerEnd = pathValue.startsWith("<") ? pathValue.indexOf(">") : -1;
1291
+ if (markerEnd <= 0) {
1292
+ singles.push(pathValue);
1293
+ continue;
1294
+ }
1295
+ const slashIndex = pathValue.indexOf("/", markerEnd);
1296
+ if (slashIndex < 0) {
1297
+ singles.push(pathValue);
1298
+ continue;
1299
+ }
1300
+ const prefix = pathValue.slice(0, slashIndex);
1301
+ const rest = pathValue.slice(slashIndex + 1);
1302
+ const existing = groups.get(prefix) ?? [];
1303
+ existing.push(rest);
1304
+ groups.set(prefix, existing);
1305
+ }
1306
+ return [
1307
+ ...Array.from(groups.entries()).map(([prefix, items]) => items.length === 1 ? `${prefix}/${items[0]}` : `${prefix}/: ${items.join(", ")}`),
1308
+ ...singles
1309
+ ].sort();
1310
+ }
1311
+ function formatEdgeSample(edges, formatter, limit, includeSymbols) {
1312
+ const visible = edges.slice(0, limit);
1313
+ const groups = new Map();
1314
+ const singles = [];
1315
+ for (const edge of visible) {
1316
+ const from = formatter.compactPath(edge.from);
1317
+ const to = formatter.compactPath(edge.to);
1318
+ const symbolsSuffix = includeSymbols ? formatSymbolsSuffix(edge.symbols) : "";
1319
+ const markerEnd = to.startsWith("<") ? to.indexOf(">") : -1;
1320
+ const slashIndex = markerEnd > 0 ? to.indexOf("/", markerEnd) : -1;
1321
+ if (slashIndex < 0) {
1322
+ singles.push(`${from} -> ${to}${symbolsSuffix}`);
1323
+ continue;
1324
+ }
1325
+ const targetPrefix = to.slice(0, slashIndex);
1326
+ const targetRest = `${to.slice(slashIndex + 1)}${symbolsSuffix}`;
1327
+ const key = `${from} -> ${targetPrefix}`;
1328
+ const existing = groups.get(key) ?? [];
1329
+ existing.push(targetRest);
1330
+ groups.set(key, existing);
1331
+ }
1332
+ const grouped = [
1333
+ ...Array.from(groups.entries()).map(([prefix, items]) => items.length === 1 ? `${prefix}/${items[0]}` : `${prefix}/: ${items.join(", ")}`),
1334
+ ...singles
1335
+ ].sort();
1336
+ const hidden = edges.length - Math.min(edges.length, limit);
1337
+ return hidden > 0 ? [...grouped, `+ ${hidden} more`] : grouped;
1338
+ }
1339
+ function formatSymbolImportList(edges, formatter, limit) {
1340
+ const visible = edges.slice(0, limit).map((edge) => `${formatter.compactPath(edge.to)}${formatSymbolsSuffix(edge.symbols)}`);
1341
+ const hidden = edges.length - Math.min(edges.length, limit);
1342
+ return hidden > 0 ? [...visible, `+ ${hidden} more files`] : visible;
1343
+ }
1344
+ function formatSymbolImportUsage(edges, formatter, limit) {
1345
+ const visible = edges.slice(0, limit);
1346
+ const typeSymbols = visible.flatMap((edge) => formatSymbolUsageEntries(edge, formatter, "type"));
1347
+ const valueSymbols = visible.flatMap((edge) => formatSymbolUsageEntries(edge, formatter, "value"));
1348
+ const hidden = edges.length - Math.min(edges.length, limit);
1349
+ const payload = {};
1350
+ if (valueSymbols.length > 0) {
1351
+ payload.value = valueSymbols;
1352
+ }
1353
+ if (typeSymbols.length > 0) {
1354
+ payload.type = typeSymbols;
1355
+ }
1356
+ if (hidden > 0) {
1357
+ payload.moreFiles = `+ ${hidden} more files`;
1358
+ }
1359
+ return payload;
1360
+ }
1361
+ function importsWithoutVisibleSymbols(imports, edges, formatter) {
1362
+ const withVisibleSymbols = new Set(edges
1363
+ .filter((edge) => normalizeImportSymbols(edge.symbols).length > 0)
1364
+ .map((edge) => edge.to));
1365
+ const missing = imports.filter((file) => !withVisibleSymbols.has(file));
1366
+ return formatter.compactList(missing, DEFAULT_LIST_LIMIT);
1367
+ }
1368
+ function formatSymbolUsageEntries(edge, formatter, usage) {
1369
+ const symbols = normalizeImportSymbols(edge.symbols).filter((symbol) => symbol.usage === usage);
1370
+ if (symbols.length === 0) {
1371
+ return [];
1372
+ }
1373
+ return [`${formatter.compactPath(edge.to)}${formatSymbolsSuffix(symbols)}`];
1374
+ }
1375
+ function formatSymbolsSuffix(symbols) {
1376
+ const normalizedSymbols = normalizeImportSymbols(symbols);
1377
+ if (normalizedSymbols.length === 0) {
1378
+ return "";
1379
+ }
1380
+ return `: ${summarizeSymbols(normalizedSymbols, 4).join(", ")}`;
1381
+ }
1382
+ function summarizeSymbols(symbols, limit) {
1383
+ const visible = symbols.slice(0, limit).map((symbol) => symbol.name);
1384
+ const hidden = symbols.length - Math.min(symbols.length, limit);
1385
+ return hidden > 0 ? [...visible, `+ ${hidden} more symbols`] : visible;
1386
+ }
1387
+ function normalizeImportSymbols(symbols) {
1388
+ return (symbols ?? [])
1389
+ .map((symbol) => typeof symbol === "string" ? createImportSymbol(symbol, "value") : symbol)
1390
+ .filter((symbol) => symbol.name.trim() !== "");
1391
+ }
1392
+ function readGraphModel(cwd, rawFile) {
1393
+ const filePath = resolveMaybeRelative(cwd, (0, session_workspace_1.resolveSessionFileArgument)(cwd, rawFile));
1394
+ const raw = JSON.parse(fs.readFileSync(filePath, "utf8"));
1395
+ if (!isGraphModel(raw)) {
1396
+ throw new errors_1.CliError("INVALID_GRAPH_FILE", "inspect graph --from-file expects a graph JSON file created by inspect graph --to-file.");
1397
+ }
1398
+ return raw;
1399
+ }
1400
+ function writeGraphModel(cwd, rawFile, model) {
1401
+ const filePath = resolveMaybeRelative(cwd, rawFile);
1402
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
1403
+ fs.writeFileSync(filePath, `${JSON.stringify(model, null, 2)}\n`);
1404
+ return filePath;
1405
+ }
1406
+ function isGraphModel(value) {
1407
+ return Boolean(value) &&
1408
+ typeof value === "object" &&
1409
+ !Array.isArray(value) &&
1410
+ value.operation === "inspect.graph" &&
1411
+ Array.isArray(value.files) &&
1412
+ Array.isArray(value.edges);
1413
+ }
1414
+ function readString(value) {
1415
+ return typeof value === "string" && value.trim() !== "" ? value.trim() : null;
1416
+ }
1417
+ function readStringArray(value) {
1418
+ if (typeof value === "string" && value.trim() !== "") {
1419
+ return [value.trim()];
1420
+ }
1421
+ if (!Array.isArray(value)) {
1422
+ return null;
1423
+ }
1424
+ return value
1425
+ .filter((item) => typeof item === "string" && item.trim() !== "")
1426
+ .map((item) => item.trim());
1427
+ }
1428
+ function readBoolean(value) {
1429
+ return typeof value === "boolean" ? value : null;
1430
+ }
1431
+ function readGraphSectionsFromPrefs(cwd) {
1432
+ return {
1433
+ hubs: (0, session_workspace_1.readSessionBooleanPref)(cwd, "inspect.graph.hubs", true),
1434
+ entrypoints: (0, session_workspace_1.readSessionBooleanPref)(cwd, "inspect.graph.entrypoints", true),
1435
+ leaves: (0, session_workspace_1.readSessionBooleanPref)(cwd, "inspect.graph.leaves", true),
1436
+ edges: (0, session_workspace_1.readSessionBooleanPref)(cwd, "inspect.graph.edges", true)
1437
+ };
1438
+ }
1439
+ function readGraphSectionsFromPayload(cwd, payload) {
1440
+ const defaults = readGraphSectionsFromPrefs(cwd);
1441
+ return {
1442
+ hubs: readBoolean(payload.hubs) ?? readBoolean(payload.showHubs) ?? defaults.hubs,
1443
+ entrypoints: readBoolean(payload.entrypoints) ??
1444
+ readBoolean(payload.scopeEntrypoints) ??
1445
+ readBoolean(payload.showEntrypoints) ??
1446
+ defaults.entrypoints,
1447
+ leaves: readBoolean(payload.leaves) ??
1448
+ readBoolean(payload.scopeLeaves) ??
1449
+ readBoolean(payload.showLeaves) ??
1450
+ defaults.leaves,
1451
+ edges: readBoolean(payload.edges) ?? readBoolean(payload.showEdges) ?? defaults.edges
1452
+ };
1453
+ }
1454
+ function readOptionalGraphDepth(value) {
1455
+ if (value === undefined) {
1456
+ return undefined;
1457
+ }
1458
+ const parsed = typeof value === "number" ? value : typeof value === "string" ? Number.parseInt(value, 10) : Number.NaN;
1459
+ if (!Number.isInteger(parsed) || parsed < 0 || parsed > 2) {
1460
+ throw new errors_1.CliError("INVALID_GRAPH_DEPTH", "inspect graph depth expects 0, 1, or 2.");
1461
+ }
1462
+ return parsed;
1463
+ }
1464
+ function readGraphView(value) {
1465
+ if (value === "local" || value === "neighbors" || value === "expanded") {
1466
+ return value;
1467
+ }
1468
+ throw new errors_1.CliError("INVALID_GRAPH_VIEW", "inspect graph view expects local, neighbors, or expanded.");
1469
+ }
1470
+ function graphViewDepth(view) {
1471
+ if (view === "local") {
1472
+ return 0;
1473
+ }
1474
+ if (view === "expanded") {
1475
+ return 2;
1476
+ }
1477
+ return 1;
1478
+ }
1479
+ function graphViewFromDepth(depth) {
1480
+ if (depth === 0) {
1481
+ return "local";
1482
+ }
1483
+ if (depth === 2) {
1484
+ return "expanded";
1485
+ }
1486
+ return "neighbors";
1487
+ }
1488
+ function defaultGraphView(cwd, scopes, fromFile) {
1489
+ if (fromFile) {
1490
+ return undefined;
1491
+ }
1492
+ if (scopes.length !== 1) {
1493
+ return "neighbors";
1494
+ }
1495
+ const absolute = resolveMaybeRelative(cwd, scopes[0]);
1496
+ if (fs.existsSync(absolute) && fs.statSync(absolute).isDirectory()) {
1497
+ return "local";
1498
+ }
1499
+ return "neighbors";
1500
+ }
1501
+ function readFlagValue(args, flag) {
1502
+ const index = args.indexOf(flag);
1503
+ return index >= 0 ? args[index + 1] : undefined;
1504
+ }
1505
+ function isObject(value) {
1506
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1507
+ }
1508
+ function isGraphSourceFile(filePath) {
1509
+ return GRAPH_SOURCE_EXTENSIONS.includes(path.extname(filePath)) &&
1510
+ !filePath.endsWith(".d.ts");
1511
+ }
1512
+ function toExternalPackageName(specifier) {
1513
+ if (specifier.startsWith("node:")) {
1514
+ return specifier;
1515
+ }
1516
+ if (specifier.startsWith("@")) {
1517
+ const parts = specifier.split("/");
1518
+ return parts.length >= 2 ? `${parts[0]}/${parts[1]}` : specifier;
1519
+ }
1520
+ return specifier.split("/")[0] ?? specifier;
1521
+ }
1522
+ function resolveMaybeRelative(cwd, rawPath) {
1523
+ return path.resolve(cwd, rawPath);
1524
+ }
1525
+ function toGraphPath(cwd, filePath) {
1526
+ return normalizeGraphPath(path.relative(cwd, path.resolve(filePath)));
1527
+ }
1528
+ function normalizeGraphPath(filePath) {
1529
+ return filePath.replace(/\\/g, "/").replace(/^\.\//, "");
1530
+ }
1531
+ function toCliDisplayPath(cwd, filePath) {
1532
+ const relative = path.relative(cwd, filePath);
1533
+ return relative && !relative.startsWith("..") ? normalizeGraphPath(relative) : filePath;
1534
+ }
1535
+ function uniqueSorted(items) {
1536
+ return Array.from(new Set(items)).sort();
1537
+ }
1538
+ function compareEdges(left, right) {
1539
+ return left.from.localeCompare(right.from) || left.to.localeCompare(right.to) || left.specifier.localeCompare(right.specifier);
1540
+ }
1541
+ function summarizeList(items, limit) {
1542
+ return withHiddenCount(items.slice(0, limit), items.length);
1543
+ }
1544
+ function withHiddenCount(visible, total) {
1545
+ const hidden = total - visible.length;
1546
+ return hidden > 0 ? [...visible, `+ ${hidden} more`] : visible;
1547
+ }
1548
+ function countEntrypoints(files) {
1549
+ return files.filter((file) => file.importedBy.length === 0 && file.imports.length > 0).length;
1550
+ }
1551
+ function countLeaves(files) {
1552
+ return files.filter((file) => file.imports.length === 0 && file.importedBy.length > 0).length;
1553
+ }