@untangle-code/cli 0.0.0-stage → 0.1.0

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 (571) hide show
  1. package/LICENSE +661 -0
  2. package/NOTICE +90 -0
  3. package/README.md +424 -2
  4. package/THIRD_PARTY_LICENSES.md +152 -0
  5. package/dist/cli/args.d.ts +48 -0
  6. package/dist/cli/args.d.ts.map +1 -0
  7. package/dist/cli/args.js +167 -0
  8. package/dist/cli/args.js.map +1 -0
  9. package/dist/cli/command.d.ts +69 -0
  10. package/dist/cli/command.d.ts.map +1 -0
  11. package/dist/cli/command.js +82 -0
  12. package/dist/cli/command.js.map +1 -0
  13. package/dist/cli/deadline.d.ts +33 -0
  14. package/dist/cli/deadline.d.ts.map +1 -0
  15. package/dist/cli/deadline.js +49 -0
  16. package/dist/cli/deadline.js.map +1 -0
  17. package/dist/cli/embedder-deadline.d.ts +72 -0
  18. package/dist/cli/embedder-deadline.d.ts.map +1 -0
  19. package/dist/cli/embedder-deadline.js +117 -0
  20. package/dist/cli/embedder-deadline.js.map +1 -0
  21. package/dist/cli/exit.d.ts +71 -0
  22. package/dist/cli/exit.d.ts.map +1 -0
  23. package/dist/cli/exit.js +81 -0
  24. package/dist/cli/exit.js.map +1 -0
  25. package/dist/cli/graphs.d.ts +65 -0
  26. package/dist/cli/graphs.d.ts.map +1 -0
  27. package/dist/cli/graphs.js +108 -0
  28. package/dist/cli/graphs.js.map +1 -0
  29. package/dist/cli/index-freshness.d.ts +13 -0
  30. package/dist/cli/index-freshness.d.ts.map +1 -0
  31. package/dist/cli/index-freshness.js +226 -0
  32. package/dist/cli/index-freshness.js.map +1 -0
  33. package/dist/cli/index-refresh.d.ts +10 -0
  34. package/dist/cli/index-refresh.d.ts.map +1 -0
  35. package/dist/cli/index-refresh.js +76 -0
  36. package/dist/cli/index-refresh.js.map +1 -0
  37. package/dist/cli/index-state.d.ts +184 -0
  38. package/dist/cli/index-state.d.ts.map +1 -0
  39. package/dist/cli/index-state.js +852 -0
  40. package/dist/cli/index-state.js.map +1 -0
  41. package/dist/cli/io.d.ts +29 -0
  42. package/dist/cli/io.d.ts.map +1 -0
  43. package/dist/cli/io.js +42 -0
  44. package/dist/cli/io.js.map +1 -0
  45. package/dist/cli/language-support.d.ts +77 -0
  46. package/dist/cli/language-support.d.ts.map +1 -0
  47. package/dist/cli/language-support.js +152 -0
  48. package/dist/cli/language-support.js.map +1 -0
  49. package/dist/cli/renewing-lease.d.ts +26 -0
  50. package/dist/cli/renewing-lease.d.ts.map +1 -0
  51. package/dist/cli/renewing-lease.js +102 -0
  52. package/dist/cli/renewing-lease.js.map +1 -0
  53. package/dist/cli/search-graph-enrichment.d.ts +16 -0
  54. package/dist/cli/search-graph-enrichment.d.ts.map +1 -0
  55. package/dist/cli/search-graph-enrichment.js +428 -0
  56. package/dist/cli/search-graph-enrichment.js.map +1 -0
  57. package/dist/cli/system.d.ts +34 -0
  58. package/dist/cli/system.d.ts.map +1 -0
  59. package/dist/cli/system.js +89 -0
  60. package/dist/cli/system.js.map +1 -0
  61. package/dist/cli/vector-store-policy.d.ts +116 -0
  62. package/dist/cli/vector-store-policy.d.ts.map +1 -0
  63. package/dist/cli/vector-store-policy.js +160 -0
  64. package/dist/cli/vector-store-policy.js.map +1 -0
  65. package/dist/cli/version.d.ts +3 -0
  66. package/dist/cli/version.d.ts.map +1 -0
  67. package/dist/cli/version.js +3 -0
  68. package/dist/cli/version.js.map +1 -0
  69. package/dist/cli/workspace.d.ts +105 -0
  70. package/dist/cli/workspace.d.ts.map +1 -0
  71. package/dist/cli/workspace.js +215 -0
  72. package/dist/cli/workspace.js.map +1 -0
  73. package/dist/commands/complexity.d.ts +72 -0
  74. package/dist/commands/complexity.d.ts.map +1 -0
  75. package/dist/commands/complexity.js +580 -0
  76. package/dist/commands/complexity.js.map +1 -0
  77. package/dist/commands/doctor.d.ts +66 -0
  78. package/dist/commands/doctor.d.ts.map +1 -0
  79. package/dist/commands/doctor.js +764 -0
  80. package/dist/commands/doctor.js.map +1 -0
  81. package/dist/commands/doctor.languages.d.ts +37 -0
  82. package/dist/commands/doctor.languages.d.ts.map +1 -0
  83. package/dist/commands/doctor.languages.js +143 -0
  84. package/dist/commands/doctor.languages.js.map +1 -0
  85. package/dist/commands/doctor.storage.d.ts +17 -0
  86. package/dist/commands/doctor.storage.d.ts.map +1 -0
  87. package/dist/commands/doctor.storage.js +91 -0
  88. package/dist/commands/doctor.storage.js.map +1 -0
  89. package/dist/commands/extensions/add.d.ts +10 -0
  90. package/dist/commands/extensions/add.d.ts.map +1 -0
  91. package/dist/commands/extensions/add.js +213 -0
  92. package/dist/commands/extensions/add.js.map +1 -0
  93. package/dist/commands/extensions/configure.d.ts +5 -0
  94. package/dist/commands/extensions/configure.d.ts.map +1 -0
  95. package/dist/commands/extensions/configure.js +58 -0
  96. package/dist/commands/extensions/configure.js.map +1 -0
  97. package/dist/commands/extensions/container.d.ts +15 -0
  98. package/dist/commands/extensions/container.d.ts.map +1 -0
  99. package/dist/commands/extensions/container.js +135 -0
  100. package/dist/commands/extensions/container.js.map +1 -0
  101. package/dist/commands/extensions/context.d.ts +37 -0
  102. package/dist/commands/extensions/context.d.ts.map +1 -0
  103. package/dist/commands/extensions/context.js +72 -0
  104. package/dist/commands/extensions/context.js.map +1 -0
  105. package/dist/commands/extensions/enable.d.ts +6 -0
  106. package/dist/commands/extensions/enable.d.ts.map +1 -0
  107. package/dist/commands/extensions/enable.js +180 -0
  108. package/dist/commands/extensions/enable.js.map +1 -0
  109. package/dist/commands/extensions/environment.d.ts +74 -0
  110. package/dist/commands/extensions/environment.d.ts.map +1 -0
  111. package/dist/commands/extensions/environment.js +168 -0
  112. package/dist/commands/extensions/environment.js.map +1 -0
  113. package/dist/commands/extensions/feature-scan.d.ts +48 -0
  114. package/dist/commands/extensions/feature-scan.d.ts.map +1 -0
  115. package/dist/commands/extensions/feature-scan.js +156 -0
  116. package/dist/commands/extensions/feature-scan.js.map +1 -0
  117. package/dist/commands/extensions/invoke.d.ts +60 -0
  118. package/dist/commands/extensions/invoke.d.ts.map +1 -0
  119. package/dist/commands/extensions/invoke.js +275 -0
  120. package/dist/commands/extensions/invoke.js.map +1 -0
  121. package/dist/commands/extensions/list.d.ts +5 -0
  122. package/dist/commands/extensions/list.d.ts.map +1 -0
  123. package/dist/commands/extensions/list.js +125 -0
  124. package/dist/commands/extensions/list.js.map +1 -0
  125. package/dist/commands/extensions/logs.d.ts +5 -0
  126. package/dist/commands/extensions/logs.d.ts.map +1 -0
  127. package/dist/commands/extensions/logs.js +74 -0
  128. package/dist/commands/extensions/logs.js.map +1 -0
  129. package/dist/commands/extensions/provision.d.ts +36 -0
  130. package/dist/commands/extensions/provision.d.ts.map +1 -0
  131. package/dist/commands/extensions/provision.js +137 -0
  132. package/dist/commands/extensions/provision.js.map +1 -0
  133. package/dist/commands/extensions/remove.d.ts +5 -0
  134. package/dist/commands/extensions/remove.d.ts.map +1 -0
  135. package/dist/commands/extensions/remove.js +77 -0
  136. package/dist/commands/extensions/remove.js.map +1 -0
  137. package/dist/commands/extensions/render.d.ts +16 -0
  138. package/dist/commands/extensions/render.d.ts.map +1 -0
  139. package/dist/commands/extensions/render.js +25 -0
  140. package/dist/commands/extensions/render.js.map +1 -0
  141. package/dist/commands/extensions/run.d.ts +30 -0
  142. package/dist/commands/extensions/run.d.ts.map +1 -0
  143. package/dist/commands/extensions/run.js +292 -0
  144. package/dist/commands/extensions/run.js.map +1 -0
  145. package/dist/commands/extensions/secret-store.d.ts +15 -0
  146. package/dist/commands/extensions/secret-store.d.ts.map +1 -0
  147. package/dist/commands/extensions/secret-store.js +164 -0
  148. package/dist/commands/extensions/secret-store.js.map +1 -0
  149. package/dist/commands/extensions/setup.d.ts +17 -0
  150. package/dist/commands/extensions/setup.d.ts.map +1 -0
  151. package/dist/commands/extensions/setup.js +94 -0
  152. package/dist/commands/extensions/setup.js.map +1 -0
  153. package/dist/commands/extensions/source.d.ts +47 -0
  154. package/dist/commands/extensions/source.d.ts.map +1 -0
  155. package/dist/commands/extensions/source.js +142 -0
  156. package/dist/commands/extensions/source.js.map +1 -0
  157. package/dist/commands/extensions/state.d.ts +62 -0
  158. package/dist/commands/extensions/state.d.ts.map +1 -0
  159. package/dist/commands/extensions/state.js +177 -0
  160. package/dist/commands/extensions/state.js.map +1 -0
  161. package/dist/commands/extensions/status.d.ts +9 -0
  162. package/dist/commands/extensions/status.d.ts.map +1 -0
  163. package/dist/commands/extensions/status.js +239 -0
  164. package/dist/commands/extensions/status.js.map +1 -0
  165. package/dist/commands/extensions.d.ts +3 -0
  166. package/dist/commands/extensions.d.ts.map +1 -0
  167. package/dist/commands/extensions.js +223 -0
  168. package/dist/commands/extensions.js.map +1 -0
  169. package/dist/commands/flow/index.d.ts +3 -0
  170. package/dist/commands/flow/index.d.ts.map +1 -0
  171. package/dist/commands/flow/index.js +295 -0
  172. package/dist/commands/flow/index.js.map +1 -0
  173. package/dist/commands/flow/limits.d.ts +12 -0
  174. package/dist/commands/flow/limits.d.ts.map +1 -0
  175. package/dist/commands/flow/limits.js +13 -0
  176. package/dist/commands/flow/limits.js.map +1 -0
  177. package/dist/commands/flow/output.d.ts +8 -0
  178. package/dist/commands/flow/output.d.ts.map +1 -0
  179. package/dist/commands/flow/output.js +11 -0
  180. package/dist/commands/flow/output.js.map +1 -0
  181. package/dist/commands/flow/render.d.ts +51 -0
  182. package/dist/commands/flow/render.d.ts.map +1 -0
  183. package/dist/commands/flow/render.js +220 -0
  184. package/dist/commands/flow/render.js.map +1 -0
  185. package/dist/commands/flow/select.d.ts +31 -0
  186. package/dist/commands/flow/select.d.ts.map +1 -0
  187. package/dist/commands/flow/select.js +62 -0
  188. package/dist/commands/flow/select.js.map +1 -0
  189. package/dist/commands/graph/boundaries-input.d.ts +26 -0
  190. package/dist/commands/graph/boundaries-input.d.ts.map +1 -0
  191. package/dist/commands/graph/boundaries-input.js +54 -0
  192. package/dist/commands/graph/boundaries-input.js.map +1 -0
  193. package/dist/commands/graph/boundaries.d.ts +4 -0
  194. package/dist/commands/graph/boundaries.d.ts.map +1 -0
  195. package/dist/commands/graph/boundaries.js +141 -0
  196. package/dist/commands/graph/boundaries.js.map +1 -0
  197. package/dist/commands/graph/bounds.d.ts +16 -0
  198. package/dist/commands/graph/bounds.d.ts.map +1 -0
  199. package/dist/commands/graph/bounds.js +22 -0
  200. package/dist/commands/graph/bounds.js.map +1 -0
  201. package/dist/commands/graph/category-clusters.d.ts +20 -0
  202. package/dist/commands/graph/category-clusters.d.ts.map +1 -0
  203. package/dist/commands/graph/category-clusters.js +158 -0
  204. package/dist/commands/graph/category-clusters.js.map +1 -0
  205. package/dist/commands/graph/feature-3d.d.ts +22 -0
  206. package/dist/commands/graph/feature-3d.d.ts.map +1 -0
  207. package/dist/commands/graph/feature-3d.js +114 -0
  208. package/dist/commands/graph/feature-3d.js.map +1 -0
  209. package/dist/commands/graph/feature-clusters.d.ts +17 -0
  210. package/dist/commands/graph/feature-clusters.d.ts.map +1 -0
  211. package/dist/commands/graph/feature-clusters.js +94 -0
  212. package/dist/commands/graph/feature-clusters.js.map +1 -0
  213. package/dist/commands/graph/feature-html.d.ts +26 -0
  214. package/dist/commands/graph/feature-html.d.ts.map +1 -0
  215. package/dist/commands/graph/feature-html.js +314 -0
  216. package/dist/commands/graph/feature-html.js.map +1 -0
  217. package/dist/commands/graph/feature-map.d.ts +31 -0
  218. package/dist/commands/graph/feature-map.d.ts.map +1 -0
  219. package/dist/commands/graph/feature-map.js +217 -0
  220. package/dist/commands/graph/feature-map.js.map +1 -0
  221. package/dist/commands/graph/feature-model.d.ts +55 -0
  222. package/dist/commands/graph/feature-model.d.ts.map +1 -0
  223. package/dist/commands/graph/feature-model.js +167 -0
  224. package/dist/commands/graph/feature-model.js.map +1 -0
  225. package/dist/commands/graph/feature-untangle-motion.d.ts +33 -0
  226. package/dist/commands/graph/feature-untangle-motion.d.ts.map +1 -0
  227. package/dist/commands/graph/feature-untangle-motion.js +155 -0
  228. package/dist/commands/graph/feature-untangle-motion.js.map +1 -0
  229. package/dist/commands/graph/index.d.ts +3 -0
  230. package/dist/commands/graph/index.d.ts.map +1 -0
  231. package/dist/commands/graph/index.js +414 -0
  232. package/dist/commands/graph/index.js.map +1 -0
  233. package/dist/commands/graph/render.d.ts +63 -0
  234. package/dist/commands/graph/render.d.ts.map +1 -0
  235. package/dist/commands/graph/render.js +352 -0
  236. package/dist/commands/graph/render.js.map +1 -0
  237. package/dist/commands/graph/select.d.ts +34 -0
  238. package/dist/commands/graph/select.d.ts.map +1 -0
  239. package/dist/commands/graph/select.js +55 -0
  240. package/dist/commands/graph/select.js.map +1 -0
  241. package/dist/commands/index/index.d.ts +6 -0
  242. package/dist/commands/index/index.d.ts.map +1 -0
  243. package/dist/commands/index/index.js +461 -0
  244. package/dist/commands/index/index.js.map +1 -0
  245. package/dist/commands/index/render.d.ts +53 -0
  246. package/dist/commands/index/render.d.ts.map +1 -0
  247. package/dist/commands/index/render.js +205 -0
  248. package/dist/commands/index/render.js.map +1 -0
  249. package/dist/commands/index/target.d.ts +34 -0
  250. package/dist/commands/index/target.d.ts.map +1 -0
  251. package/dist/commands/index/target.js +97 -0
  252. package/dist/commands/index/target.js.map +1 -0
  253. package/dist/commands/index-watch.d.ts +30 -0
  254. package/dist/commands/index-watch.d.ts.map +1 -0
  255. package/dist/commands/index-watch.js +138 -0
  256. package/dist/commands/index-watch.js.map +1 -0
  257. package/dist/commands/init/command.d.ts +25 -0
  258. package/dist/commands/init/command.d.ts.map +1 -0
  259. package/dist/commands/init/command.js +198 -0
  260. package/dist/commands/init/command.js.map +1 -0
  261. package/dist/commands/init/config-draft.d.ts +48 -0
  262. package/dist/commands/init/config-draft.d.ts.map +1 -0
  263. package/dist/commands/init/config-draft.js +201 -0
  264. package/dist/commands/init/config-draft.js.map +1 -0
  265. package/dist/commands/init/diff.d.ts +33 -0
  266. package/dist/commands/init/diff.d.ts.map +1 -0
  267. package/dist/commands/init/diff.js +109 -0
  268. package/dist/commands/init/diff.js.map +1 -0
  269. package/dist/commands/init/http-probe.d.ts +26 -0
  270. package/dist/commands/init/http-probe.d.ts.map +1 -0
  271. package/dist/commands/init/http-probe.js +144 -0
  272. package/dist/commands/init/http-probe.js.map +1 -0
  273. package/dist/commands/init/ignore-rules.d.ts +70 -0
  274. package/dist/commands/init/ignore-rules.d.ts.map +1 -0
  275. package/dist/commands/init/ignore-rules.js +146 -0
  276. package/dist/commands/init/ignore-rules.js.map +1 -0
  277. package/dist/commands/init/index.d.ts +33 -0
  278. package/dist/commands/init/index.d.ts.map +1 -0
  279. package/dist/commands/init/index.js +32 -0
  280. package/dist/commands/init/index.js.map +1 -0
  281. package/dist/commands/init/integrations-apply.d.ts +50 -0
  282. package/dist/commands/init/integrations-apply.d.ts.map +1 -0
  283. package/dist/commands/init/integrations-apply.js +452 -0
  284. package/dist/commands/init/integrations-apply.js.map +1 -0
  285. package/dist/commands/init/integrations-plan.d.ts +68 -0
  286. package/dist/commands/init/integrations-plan.d.ts.map +1 -0
  287. package/dist/commands/init/integrations-plan.js +515 -0
  288. package/dist/commands/init/integrations-plan.js.map +1 -0
  289. package/dist/commands/init/integrations.d.ts +5 -0
  290. package/dist/commands/init/integrations.d.ts.map +1 -0
  291. package/dist/commands/init/integrations.js +4 -0
  292. package/dist/commands/init/integrations.js.map +1 -0
  293. package/dist/commands/init/languages.d.ts +55 -0
  294. package/dist/commands/init/languages.d.ts.map +1 -0
  295. package/dist/commands/init/languages.js +245 -0
  296. package/dist/commands/init/languages.js.map +1 -0
  297. package/dist/commands/init/product-context.d.ts +63 -0
  298. package/dist/commands/init/product-context.d.ts.map +1 -0
  299. package/dist/commands/init/product-context.js +390 -0
  300. package/dist/commands/init/product-context.js.map +1 -0
  301. package/dist/commands/init/render.d.ts +38 -0
  302. package/dist/commands/init/render.d.ts.map +1 -0
  303. package/dist/commands/init/render.js +501 -0
  304. package/dist/commands/init/render.js.map +1 -0
  305. package/dist/commands/init/report.d.ts +24 -0
  306. package/dist/commands/init/report.d.ts.map +1 -0
  307. package/dist/commands/init/report.js +163 -0
  308. package/dist/commands/init/report.js.map +1 -0
  309. package/dist/commands/init/run.d.ts +71 -0
  310. package/dist/commands/init/run.d.ts.map +1 -0
  311. package/dist/commands/init/run.js +253 -0
  312. package/dist/commands/init/run.js.map +1 -0
  313. package/dist/commands/init/services.d.ts +82 -0
  314. package/dist/commands/init/services.d.ts.map +1 -0
  315. package/dist/commands/init/services.js +209 -0
  316. package/dist/commands/init/services.js.map +1 -0
  317. package/dist/commands/init/storage.d.ts +8 -0
  318. package/dist/commands/init/storage.d.ts.map +1 -0
  319. package/dist/commands/init/storage.js +102 -0
  320. package/dist/commands/init/storage.js.map +1 -0
  321. package/dist/commands/init/toml.d.ts +65 -0
  322. package/dist/commands/init/toml.d.ts.map +1 -0
  323. package/dist/commands/init/toml.js +159 -0
  324. package/dist/commands/init/toml.js.map +1 -0
  325. package/dist/commands/init/topology.d.ts +54 -0
  326. package/dist/commands/init/topology.d.ts.map +1 -0
  327. package/dist/commands/init/topology.js +146 -0
  328. package/dist/commands/init/topology.js.map +1 -0
  329. package/dist/commands/init/types.d.ts +334 -0
  330. package/dist/commands/init/types.d.ts.map +1 -0
  331. package/dist/commands/init/types.js +31 -0
  332. package/dist/commands/init/types.js.map +1 -0
  333. package/dist/commands/init/wizard-terminal.d.ts +36 -0
  334. package/dist/commands/init/wizard-terminal.d.ts.map +1 -0
  335. package/dist/commands/init/wizard-terminal.js +163 -0
  336. package/dist/commands/init/wizard-terminal.js.map +1 -0
  337. package/dist/commands/init/wizard.d.ts +25 -0
  338. package/dist/commands/init/wizard.d.ts.map +1 -0
  339. package/dist/commands/init/wizard.js +358 -0
  340. package/dist/commands/init/wizard.js.map +1 -0
  341. package/dist/commands/mcp.d.ts +4 -0
  342. package/dist/commands/mcp.d.ts.map +1 -0
  343. package/dist/commands/mcp.js +111 -0
  344. package/dist/commands/mcp.js.map +1 -0
  345. package/dist/commands/product-test-runner.d.ts +4 -0
  346. package/dist/commands/product-test-runner.d.ts.map +1 -0
  347. package/dist/commands/product-test-runner.js +85 -0
  348. package/dist/commands/product-test-runner.js.map +1 -0
  349. package/dist/commands/product.d.ts +16 -0
  350. package/dist/commands/product.d.ts.map +1 -0
  351. package/dist/commands/product.js +262 -0
  352. package/dist/commands/product.js.map +1 -0
  353. package/dist/commands/query.d.ts +114 -0
  354. package/dist/commands/query.d.ts.map +1 -0
  355. package/dist/commands/query.js +783 -0
  356. package/dist/commands/query.js.map +1 -0
  357. package/dist/commands/scan.d.ts +10 -0
  358. package/dist/commands/scan.d.ts.map +1 -0
  359. package/dist/commands/scan.js +302 -0
  360. package/dist/commands/scan.js.map +1 -0
  361. package/dist/commands/sdd.d.ts +24 -0
  362. package/dist/commands/sdd.d.ts.map +1 -0
  363. package/dist/commands/sdd.js +195 -0
  364. package/dist/commands/sdd.js.map +1 -0
  365. package/dist/commands/unavailable.d.ts +40 -0
  366. package/dist/commands/unavailable.d.ts.map +1 -0
  367. package/dist/commands/unavailable.js +73 -0
  368. package/dist/commands/unavailable.js.map +1 -0
  369. package/dist/commands/watch/analyze.d.ts +69 -0
  370. package/dist/commands/watch/analyze.d.ts.map +1 -0
  371. package/dist/commands/watch/analyze.js +402 -0
  372. package/dist/commands/watch/analyze.js.map +1 -0
  373. package/dist/commands/watch/cli.d.ts +8 -0
  374. package/dist/commands/watch/cli.d.ts.map +1 -0
  375. package/dist/commands/watch/cli.js +97 -0
  376. package/dist/commands/watch/cli.js.map +1 -0
  377. package/dist/commands/watch/delta.d.ts +46 -0
  378. package/dist/commands/watch/delta.d.ts.map +1 -0
  379. package/dist/commands/watch/delta.js +170 -0
  380. package/dist/commands/watch/delta.js.map +1 -0
  381. package/dist/commands/watch/events.d.ts +214 -0
  382. package/dist/commands/watch/events.d.ts.map +1 -0
  383. package/dist/commands/watch/events.js +13 -0
  384. package/dist/commands/watch/events.js.map +1 -0
  385. package/dist/commands/watch/index.d.ts +19 -0
  386. package/dist/commands/watch/index.d.ts.map +1 -0
  387. package/dist/commands/watch/index.js +15 -0
  388. package/dist/commands/watch/index.js.map +1 -0
  389. package/dist/commands/watch/options.d.ts +43 -0
  390. package/dist/commands/watch/options.d.ts.map +1 -0
  391. package/dist/commands/watch/options.js +193 -0
  392. package/dist/commands/watch/options.js.map +1 -0
  393. package/dist/commands/watch/render.d.ts +26 -0
  394. package/dist/commands/watch/render.d.ts.map +1 -0
  395. package/dist/commands/watch/render.js +175 -0
  396. package/dist/commands/watch/render.js.map +1 -0
  397. package/dist/commands/watch/run.d.ts +14 -0
  398. package/dist/commands/watch/run.d.ts.map +1 -0
  399. package/dist/commands/watch/run.js +460 -0
  400. package/dist/commands/watch/run.js.map +1 -0
  401. package/dist/commands/watch/runtime.d.ts +67 -0
  402. package/dist/commands/watch/runtime.d.ts.map +1 -0
  403. package/dist/commands/watch/runtime.js +149 -0
  404. package/dist/commands/watch/runtime.js.map +1 -0
  405. package/dist/commands/watch-command.d.ts +3 -0
  406. package/dist/commands/watch-command.d.ts.map +1 -0
  407. package/dist/commands/watch-command.js +273 -0
  408. package/dist/commands/watch-command.js.map +1 -0
  409. package/dist/entry-point.d.ts +11 -0
  410. package/dist/entry-point.d.ts.map +1 -0
  411. package/dist/entry-point.js +65 -0
  412. package/dist/entry-point.js.map +1 -0
  413. package/dist/index.d.ts +38 -0
  414. package/dist/index.d.ts.map +1 -0
  415. package/dist/index.js +245 -0
  416. package/dist/index.js.map +1 -0
  417. package/dist/mcp/boundaries-schema.d.ts +262 -0
  418. package/dist/mcp/boundaries-schema.d.ts.map +1 -0
  419. package/dist/mcp/boundaries-schema.js +183 -0
  420. package/dist/mcp/boundaries-schema.js.map +1 -0
  421. package/dist/mcp/default-runtime.d.ts +16 -0
  422. package/dist/mcp/default-runtime.d.ts.map +1 -0
  423. package/dist/mcp/default-runtime.js +718 -0
  424. package/dist/mcp/default-runtime.js.map +1 -0
  425. package/dist/mcp/envelope.d.ts +13 -0
  426. package/dist/mcp/envelope.d.ts.map +1 -0
  427. package/dist/mcp/envelope.js +29 -0
  428. package/dist/mcp/envelope.js.map +1 -0
  429. package/dist/mcp/index.d.ts +8 -0
  430. package/dist/mcp/index.d.ts.map +1 -0
  431. package/dist/mcp/index.js +8 -0
  432. package/dist/mcp/index.js.map +1 -0
  433. package/dist/mcp/output-schemas.d.ts +5928 -0
  434. package/dist/mcp/output-schemas.d.ts.map +1 -0
  435. package/dist/mcp/output-schemas.js +2814 -0
  436. package/dist/mcp/output-schemas.js.map +1 -0
  437. package/dist/mcp/path-sandbox.d.ts +35 -0
  438. package/dist/mcp/path-sandbox.d.ts.map +1 -0
  439. package/dist/mcp/path-sandbox.js +128 -0
  440. package/dist/mcp/path-sandbox.js.map +1 -0
  441. package/dist/mcp/server.d.ts +155 -0
  442. package/dist/mcp/server.d.ts.map +1 -0
  443. package/dist/mcp/server.js +257 -0
  444. package/dist/mcp/server.js.map +1 -0
  445. package/dist/mcp/stdio.d.ts +20 -0
  446. package/dist/mcp/stdio.d.ts.map +1 -0
  447. package/dist/mcp/stdio.js +71 -0
  448. package/dist/mcp/stdio.js.map +1 -0
  449. package/dist/mcp/tools.d.ts +355 -0
  450. package/dist/mcp/tools.d.ts.map +1 -0
  451. package/dist/mcp/tools.js +319 -0
  452. package/dist/mcp/tools.js.map +1 -0
  453. package/dist/mcp/types.d.ts +15 -0
  454. package/dist/mcp/types.d.ts.map +1 -0
  455. package/dist/mcp/types.js +45 -0
  456. package/dist/mcp/types.js.map +1 -0
  457. package/package.json +99 -3
  458. package/src/cli/args.ts +231 -0
  459. package/src/cli/command.ts +146 -0
  460. package/src/cli/deadline.ts +56 -0
  461. package/src/cli/embedder-deadline.ts +187 -0
  462. package/src/cli/exit.ts +94 -0
  463. package/src/cli/graphs.ts +191 -0
  464. package/src/cli/index-freshness.ts +303 -0
  465. package/src/cli/index-refresh.ts +125 -0
  466. package/src/cli/index-state.ts +1217 -0
  467. package/src/cli/io.ts +56 -0
  468. package/src/cli/language-support.ts +203 -0
  469. package/src/cli/renewing-lease.ts +121 -0
  470. package/src/cli/search-graph-enrichment.ts +639 -0
  471. package/src/cli/system.ts +94 -0
  472. package/src/cli/vector-store-policy.ts +213 -0
  473. package/src/cli/version.ts +2 -0
  474. package/src/cli/workspace.ts +324 -0
  475. package/src/commands/complexity.ts +776 -0
  476. package/src/commands/doctor.languages.ts +187 -0
  477. package/src/commands/doctor.storage.ts +124 -0
  478. package/src/commands/doctor.ts +946 -0
  479. package/src/commands/extensions/add.ts +312 -0
  480. package/src/commands/extensions/configure.ts +82 -0
  481. package/src/commands/extensions/container.ts +209 -0
  482. package/src/commands/extensions/context.ts +109 -0
  483. package/src/commands/extensions/enable.ts +237 -0
  484. package/src/commands/extensions/environment.ts +218 -0
  485. package/src/commands/extensions/feature-scan.ts +232 -0
  486. package/src/commands/extensions/invoke.ts +368 -0
  487. package/src/commands/extensions/list.ts +158 -0
  488. package/src/commands/extensions/logs.ts +104 -0
  489. package/src/commands/extensions/provision.ts +206 -0
  490. package/src/commands/extensions/remove.ts +110 -0
  491. package/src/commands/extensions/render.ts +32 -0
  492. package/src/commands/extensions/run.ts +386 -0
  493. package/src/commands/extensions/secret-store.ts +223 -0
  494. package/src/commands/extensions/setup.ts +140 -0
  495. package/src/commands/extensions/source.ts +189 -0
  496. package/src/commands/extensions/state.ts +252 -0
  497. package/src/commands/extensions/status.ts +320 -0
  498. package/src/commands/extensions.ts +280 -0
  499. package/src/commands/flow/index.ts +402 -0
  500. package/src/commands/flow/limits.ts +14 -0
  501. package/src/commands/flow/output.ts +16 -0
  502. package/src/commands/flow/render.ts +318 -0
  503. package/src/commands/flow/select.ts +101 -0
  504. package/src/commands/graph/boundaries-input.ts +63 -0
  505. package/src/commands/graph/boundaries.ts +182 -0
  506. package/src/commands/graph/bounds.ts +25 -0
  507. package/src/commands/graph/category-clusters.ts +194 -0
  508. package/src/commands/graph/feature-3d.ts +141 -0
  509. package/src/commands/graph/feature-clusters.ts +125 -0
  510. package/src/commands/graph/feature-html.ts +336 -0
  511. package/src/commands/graph/feature-map.ts +270 -0
  512. package/src/commands/graph/feature-model.ts +234 -0
  513. package/src/commands/graph/feature-untangle-motion.ts +192 -0
  514. package/src/commands/graph/index.ts +562 -0
  515. package/src/commands/graph/render.ts +503 -0
  516. package/src/commands/graph/select.ts +77 -0
  517. package/src/commands/index/index.ts +595 -0
  518. package/src/commands/index/render.ts +325 -0
  519. package/src/commands/index/target.ts +136 -0
  520. package/src/commands/index-watch.ts +206 -0
  521. package/src/commands/init/command.ts +238 -0
  522. package/src/commands/init/config-draft.ts +235 -0
  523. package/src/commands/init/diff.ts +117 -0
  524. package/src/commands/init/http-probe.ts +150 -0
  525. package/src/commands/init/ignore-rules.ts +170 -0
  526. package/src/commands/init/index.ts +63 -0
  527. package/src/commands/init/integrations-apply.ts +618 -0
  528. package/src/commands/init/integrations-plan.ts +634 -0
  529. package/src/commands/init/integrations.ts +8 -0
  530. package/src/commands/init/languages.ts +320 -0
  531. package/src/commands/init/product-context.ts +576 -0
  532. package/src/commands/init/render.ts +598 -0
  533. package/src/commands/init/report.ts +204 -0
  534. package/src/commands/init/run.ts +349 -0
  535. package/src/commands/init/services.ts +271 -0
  536. package/src/commands/init/storage.ts +136 -0
  537. package/src/commands/init/toml.ts +174 -0
  538. package/src/commands/init/topology.ts +192 -0
  539. package/src/commands/init/types.ts +366 -0
  540. package/src/commands/init/wizard-terminal.ts +206 -0
  541. package/src/commands/init/wizard.ts +450 -0
  542. package/src/commands/mcp.ts +123 -0
  543. package/src/commands/product-test-runner.ts +80 -0
  544. package/src/commands/product.ts +331 -0
  545. package/src/commands/query.ts +1032 -0
  546. package/src/commands/scan.ts +360 -0
  547. package/src/commands/sdd.ts +243 -0
  548. package/src/commands/unavailable.ts +92 -0
  549. package/src/commands/watch/README.md +160 -0
  550. package/src/commands/watch/analyze.ts +600 -0
  551. package/src/commands/watch/cli.ts +108 -0
  552. package/src/commands/watch/delta.ts +186 -0
  553. package/src/commands/watch/events.ts +235 -0
  554. package/src/commands/watch/index.ts +53 -0
  555. package/src/commands/watch/options.ts +234 -0
  556. package/src/commands/watch/render.ts +240 -0
  557. package/src/commands/watch/run.ts +553 -0
  558. package/src/commands/watch/runtime.ts +167 -0
  559. package/src/commands/watch-command.ts +294 -0
  560. package/src/entry-point.ts +67 -0
  561. package/src/index.ts +291 -0
  562. package/src/mcp/boundaries-schema.ts +193 -0
  563. package/src/mcp/default-runtime.ts +1034 -0
  564. package/src/mcp/envelope.ts +57 -0
  565. package/src/mcp/index.ts +28 -0
  566. package/src/mcp/output-schemas.ts +3071 -0
  567. package/src/mcp/path-sandbox.ts +156 -0
  568. package/src/mcp/server.ts +358 -0
  569. package/src/mcp/stdio.ts +92 -0
  570. package/src/mcp/tools.ts +563 -0
  571. package/src/mcp/types.ts +66 -0
@@ -0,0 +1,576 @@
1
+ import { createHash } from "node:crypto";
2
+ import path from "node:path";
3
+
4
+ import type { FileSystemPort } from "@untangle-code/domain";
5
+ import {
6
+ compareCodepoints,
7
+ findMarkdownLinks,
8
+ linkFilePath,
9
+ outlineMarkdown,
10
+ } from "@untangle-code/domain";
11
+ import type { ScannedFileV1 } from "@untangle-code/scanner";
12
+
13
+ export type ProductContextRoleV1 = "vision" | "specification" | "product";
14
+ export type ProductContextSourceStatusV1 =
15
+ "readable" | "empty" | "unreadable" | "changed" | "not_in_scan" | "not_assessed";
16
+
17
+ export interface ProductContextSourceV1 {
18
+ role: ProductContextRoleV1;
19
+ /** Repository-relative path, including a visible escape for rejected explicit paths. */
20
+ path: string;
21
+ /** Hash of the exact bytes read; absent when no content was read. */
22
+ contentHash?: string;
23
+ /** Accepted scanner hash, retained separately when the subsequent read differs. */
24
+ scannedContentHash?: string;
25
+ status: ProductContextSourceStatusV1;
26
+ selected: boolean;
27
+ selection: "explicit" | "filename_candidate";
28
+ sections: { title: string; startLine: number; endLine: number }[];
29
+ }
30
+
31
+ export interface ProductContextReferenceV1 {
32
+ sourcePath: string;
33
+ sourceLine: number;
34
+ targetPath: string;
35
+ status: "present" | "missing" | "not_in_scan" | "outside_workspace";
36
+ /** Hash from the accepted scan, never a claim of semantic implementation. */
37
+ targetContentHash?: string;
38
+ }
39
+
40
+ export interface ProductContextAssessmentV1 {
41
+ schemaVersion: 1;
42
+ status: "needs_context" | "needs_selection" | "ready_for_review" | "incomplete";
43
+ sources: ProductContextSourceV1[];
44
+ missingRoles: ProductContextRoleV1[];
45
+ ambiguousRoles: ProductContextRoleV1[];
46
+ references: ProductContextReferenceV1[];
47
+ referencesTruncated: boolean;
48
+ alignment: { status: "unverified"; reason: "feature_and_ownership_not_confirmed" };
49
+ reviewDraft: { features: []; ownership: []; questions: string[] };
50
+ limitations: string[];
51
+ }
52
+
53
+ export interface AssessProductContextInputV1 {
54
+ fs: FileSystemPort;
55
+ root: string;
56
+ /** Files already accepted by the same bounded, ignore-aware scanner pass. */
57
+ files: readonly ScannedFileV1[];
58
+ inventoryTruncated: boolean;
59
+ visionPath?: string;
60
+ specPath?: string;
61
+ signal?: AbortSignal;
62
+ /** Number of distinct documents to read, from zero to the hard ceiling of 32. */
63
+ maxDocuments?: number;
64
+ }
65
+
66
+ const ROLES: readonly ProductContextRoleV1[] = ["vision", "specification", "product"];
67
+ const REQUIRED_ROLES: readonly ProductContextRoleV1[] = ["vision", "specification"];
68
+ const MAX_DOCUMENTS = 32;
69
+ const MAX_DOCUMENT_BYTES = 5 * 1024 * 1024;
70
+ const MAX_REFERENCES = 256;
71
+ const MAX_LINE_CHARACTERS = 16_384;
72
+ const MAX_LINK_OPENINGS = 4_096;
73
+ const MAX_HEADING_CANDIDATES = 2_048;
74
+
75
+ interface DocumentRead {
76
+ status: ProductContextSourceStatusV1;
77
+ contentHash?: string;
78
+ scannedContentHash?: string;
79
+ lines?: string[];
80
+ limitation?: string;
81
+ }
82
+
83
+ interface InspectionContext {
84
+ input: AssessProductContextInputV1;
85
+ root: string;
86
+ inventory: ReadonlyMap<string, ScannedFileV1>;
87
+ }
88
+
89
+ /** Discover and bind product documents; neither filenames nor links prove conformance. */
90
+ export async function assessProductContext(
91
+ input: AssessProductContextInputV1,
92
+ ): Promise<ProductContextAssessmentV1> {
93
+ input.signal?.throwIfAborted();
94
+ const maximum = documentLimit(input.maxDocuments);
95
+ const root = path.resolve(input.root);
96
+ const inventory = acceptedInventory(root, input.files);
97
+ const sources = discoverSources(input, root, inventory);
98
+ const ambiguousRoles = ambiguousSourceRoles(sources);
99
+ selectSources(sources, ambiguousRoles, input.inventoryTruncated);
100
+
101
+ const context: InspectionContext = { input, root, inventory };
102
+ const reads = await inspectDocuments(context, sources, maximum);
103
+ const { references, referencesTruncated, pathLimitations } = await inspectReferences(
104
+ context,
105
+ reads,
106
+ );
107
+ const missingRoles = missingSourceRoles(sources, input.inventoryTruncated);
108
+ const limitations = inspectionLimitations(
109
+ input,
110
+ reads,
111
+ references,
112
+ referencesTruncated,
113
+ pathLimitations,
114
+ );
115
+
116
+ input.signal?.throwIfAborted();
117
+ return {
118
+ schemaVersion: 1,
119
+ status: assessmentStatus(
120
+ sources,
121
+ missingRoles,
122
+ ambiguousRoles,
123
+ input.inventoryTruncated || referencesTruncated,
124
+ ),
125
+ sources,
126
+ missingRoles,
127
+ ambiguousRoles,
128
+ references,
129
+ referencesTruncated,
130
+ alignment: { status: "unverified", reason: "feature_and_ownership_not_confirmed" },
131
+ reviewDraft: { features: [], ownership: [], questions: reviewQuestions(sources, references) },
132
+ limitations,
133
+ };
134
+ }
135
+
136
+ function documentLimit(candidate: number | undefined): number {
137
+ const value = candidate ?? MAX_DOCUMENTS;
138
+ if (!Number.isInteger(value) || value < 0 || value > MAX_DOCUMENTS) {
139
+ throw new RangeError("maxDocuments must be an integer between 0 and 32");
140
+ }
141
+ return value;
142
+ }
143
+
144
+ function normalizedRelativePath(root: string, candidate: string): string {
145
+ return path
146
+ .relative(root, path.resolve(root, candidate.replaceAll("\\", "/")))
147
+ .split(path.sep)
148
+ .join("/");
149
+ }
150
+
151
+ function isWithinRoot(root: string, candidate: string): boolean {
152
+ const relative = path.relative(root, path.resolve(candidate));
153
+ return relative !== ".." && !relative.startsWith(`..${path.sep}`) && !path.isAbsolute(relative);
154
+ }
155
+
156
+ function acceptedInventory(
157
+ root: string,
158
+ files: readonly ScannedFileV1[],
159
+ ): Map<string, ScannedFileV1> {
160
+ const inventory = new Map<string, ScannedFileV1>();
161
+ for (const file of files) {
162
+ const relative = normalizedRelativePath(root, file.relativePath);
163
+ if (isWithinRoot(root, path.resolve(root, relative)) && isWithinRoot(root, file.absolutePath)) {
164
+ inventory.set(relative, file);
165
+ }
166
+ }
167
+ return inventory;
168
+ }
169
+
170
+ function filenameRole(filePath: string): ProductContextRoleV1 | undefined {
171
+ const name = path.posix.basename(filePath).toLowerCase();
172
+ if (!/\.(md|markdown|mdx)$/u.test(name)) return undefined;
173
+ const stem = name.replace(/\.(md|markdown|mdx)$/u, "");
174
+ if (/^(vision|product[-_]vision)(?:[-_.].+)?$/u.test(stem)) return "vision";
175
+ if (/^(spec|specification|requirements)(?:[-_.].+)?$/u.test(stem)) return "specification";
176
+ if (/^(prd|product)(?:[-_.].+)?$/u.test(stem)) return "product";
177
+ return undefined;
178
+ }
179
+
180
+ function sourceEntry(
181
+ role: ProductContextRoleV1,
182
+ filePath: string,
183
+ selection: ProductContextSourceV1["selection"],
184
+ ): ProductContextSourceV1 {
185
+ return { role, path: filePath, selection, status: "not_assessed", selected: false, sections: [] };
186
+ }
187
+
188
+ function discoverSources(
189
+ input: AssessProductContextInputV1,
190
+ root: string,
191
+ inventory: ReadonlyMap<string, ScannedFileV1>,
192
+ ): ProductContextSourceV1[] {
193
+ const entries = new Map<string, ProductContextSourceV1>();
194
+ for (const filePath of inventory.keys()) {
195
+ const role = filenameRole(filePath);
196
+ if (role !== undefined)
197
+ entries.set(`${role}\0${filePath}`, sourceEntry(role, filePath, "filename_candidate"));
198
+ }
199
+ for (const [role, explicit] of [
200
+ ["vision", input.visionPath],
201
+ ["specification", input.specPath],
202
+ ] as const) {
203
+ if (explicit === undefined) continue;
204
+ const filePath = normalizedRelativePath(root, explicit);
205
+ entries.set(`${role}\0${filePath}`, sourceEntry(role, filePath, "explicit"));
206
+ }
207
+ return [...entries.values()].sort(
208
+ (left, right) =>
209
+ ROLES.indexOf(left.role) - ROLES.indexOf(right.role) ||
210
+ compareCodepoints(left.path, right.path),
211
+ );
212
+ }
213
+
214
+ function ambiguousSourceRoles(sources: readonly ProductContextSourceV1[]): ProductContextRoleV1[] {
215
+ return ROLES.filter((role) => {
216
+ const candidates = sources.filter((source) => source.role === role);
217
+ if (candidates.some((source) => source.selection === "explicit")) return false;
218
+ return candidates.length > 1;
219
+ });
220
+ }
221
+
222
+ function selectSources(
223
+ sources: ProductContextSourceV1[],
224
+ ambiguousRoles: readonly ProductContextRoleV1[],
225
+ inventoryTruncated: boolean,
226
+ ): void {
227
+ for (const role of ROLES) {
228
+ const candidates = sources.filter((source) => source.role === role);
229
+ const explicit = candidates.find((source) => source.selection === "explicit");
230
+ if (explicit !== undefined) explicit.selected = true;
231
+ else if (!inventoryTruncated && !ambiguousRoles.includes(role) && candidates.length === 1) {
232
+ (candidates[0] as ProductContextSourceV1).selected = true;
233
+ }
234
+ }
235
+ }
236
+
237
+ async function inspectDocuments(
238
+ context: InspectionContext,
239
+ sources: ProductContextSourceV1[],
240
+ maximum: number,
241
+ ): Promise<Map<string, DocumentRead>> {
242
+ const reads = new Map<string, DocumentRead>();
243
+ const prioritized = [...sources].sort(
244
+ (left, right) =>
245
+ Number(right.selection === "explicit") - Number(left.selection === "explicit") ||
246
+ Number(right.selected) - Number(left.selected) ||
247
+ ROLES.indexOf(left.role) - ROLES.indexOf(right.role) ||
248
+ compareCodepoints(left.path, right.path),
249
+ );
250
+ let readCount = 0;
251
+ for (const source of prioritized) {
252
+ context.input.signal?.throwIfAborted();
253
+ let result = reads.get(source.path);
254
+ if (result === undefined) {
255
+ const file = context.inventory.get(source.path);
256
+ if (file === undefined)
257
+ result = {
258
+ status: "not_in_scan",
259
+ limitation: `Source "${source.path}" is absent from the accepted scan; it may be missing, ignored, or outside the workspace.`,
260
+ };
261
+ else if (readCount >= maximum)
262
+ result = {
263
+ status: "not_assessed",
264
+ limitation: `Source "${source.path}" was not read because the document limit of ${String(maximum)} was reached.`,
265
+ };
266
+ else {
267
+ readCount += 1;
268
+ result = await inspectDocument(context, file);
269
+ }
270
+ reads.set(source.path, result);
271
+ }
272
+ applyDocumentRead(source, result);
273
+ }
274
+ return reads;
275
+ }
276
+
277
+ async function inspectDocument(
278
+ context: InspectionContext,
279
+ file: ScannedFileV1,
280
+ ): Promise<DocumentRead> {
281
+ const { fs, signal } = context.input;
282
+ const options = signal === undefined ? {} : { signal };
283
+ let contentHash: string | undefined;
284
+ try {
285
+ const realPath = await fs.realPath(path.resolve(context.root, file.relativePath), options);
286
+ signal?.throwIfAborted();
287
+ if (!isWithinRoot(context.root, realPath)) {
288
+ return {
289
+ status: "not_in_scan",
290
+ limitation: `Source "${file.relativePath}" now resolves outside the workspace; no content was read.`,
291
+ };
292
+ }
293
+ const stat = await fs.stat(realPath, options);
294
+ signal?.throwIfAborted();
295
+ if (stat === null || stat.kind !== "file" || stat.sizeBytes > MAX_DOCUMENT_BYTES) {
296
+ return {
297
+ status: "unreadable",
298
+ limitation: `Source "${file.relativePath}" is not a readable file within the 5 MiB document ceiling.`,
299
+ };
300
+ }
301
+ const bytes = await fs.readFile(realPath, options);
302
+ signal?.throwIfAborted();
303
+ contentHash = createHash("sha256").update(bytes).digest("hex");
304
+ if (bytes.byteLength > MAX_DOCUMENT_BYTES) {
305
+ return {
306
+ status: "unreadable",
307
+ contentHash,
308
+ limitation: `Source "${file.relativePath}" exceeded the 5 MiB document ceiling during reading.`,
309
+ };
310
+ }
311
+ if (contentHash !== file.contentHash) {
312
+ return {
313
+ status: "changed",
314
+ contentHash,
315
+ scannedContentHash: file.contentHash,
316
+ limitation: `Source "${file.relativePath}" changed after discovery; its content was not interpreted.`,
317
+ };
318
+ }
319
+ if (file.encoding === "utf16le" || file.encoding === "utf16be") {
320
+ return {
321
+ status: "unreadable",
322
+ contentHash,
323
+ limitation: `Source "${file.relativePath}" has unsupported ${file.encoding} encoding; no headings were inferred.`,
324
+ };
325
+ }
326
+ const text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
327
+ const lines = text.split(/\r?\n/u);
328
+ const parseLimitation = markdownParseLimitation(lines);
329
+ if (parseLimitation !== undefined) {
330
+ return {
331
+ status: "not_assessed",
332
+ contentHash,
333
+ limitation: `Source "${file.relativePath}" was not interpreted: ${parseLimitation}.`,
334
+ };
335
+ }
336
+ return {
337
+ status: text.trim() === "" ? "empty" : "readable",
338
+ contentHash,
339
+ lines,
340
+ };
341
+ } catch (error) {
342
+ rethrowCancellation(error, signal);
343
+ return {
344
+ status: "unreadable",
345
+ ...(contentHash === undefined ? {} : { contentHash }),
346
+ limitation: `Source "${file.relativePath}" could not be read or decoded as UTF-8.`,
347
+ };
348
+ }
349
+ }
350
+
351
+ /** Conservative input bounds precede the shared outline and link parsers. */
352
+ function markdownParseLimitation(lines: readonly string[]): string | undefined {
353
+ let linkOpenings = 0;
354
+ let headingCandidates = 0;
355
+ for (const line of lines) {
356
+ if (line.length > MAX_LINE_CHARACTERS) {
357
+ return "the Markdown parse budget of 16,384 characters per line was exceeded";
358
+ }
359
+ if (line.trimStart().startsWith("#")) headingCandidates += 1;
360
+ if (headingCandidates > MAX_HEADING_CANDIDATES) {
361
+ return "the Markdown parse budget of 2,048 heading candidates was exceeded";
362
+ }
363
+ for (const character of line) {
364
+ if (character === "[") linkOpenings += 1;
365
+ if (linkOpenings > MAX_LINK_OPENINGS) {
366
+ return "the Markdown parse budget of 4,096 opening link brackets was exceeded";
367
+ }
368
+ }
369
+ }
370
+ return undefined;
371
+ }
372
+
373
+ function rethrowCancellation(error: unknown, signal: AbortSignal | undefined): void {
374
+ signal?.throwIfAborted();
375
+ if (
376
+ error instanceof Error &&
377
+ (error.name === "AbortError" || ("code" in error && error.code === "JOB_CANCELLED"))
378
+ )
379
+ throw error;
380
+ }
381
+
382
+ function applyDocumentRead(source: ProductContextSourceV1, result: DocumentRead): void {
383
+ source.status = result.status;
384
+ if (result.contentHash !== undefined) source.contentHash = result.contentHash;
385
+ if (result.scannedContentHash !== undefined)
386
+ source.scannedContentHash = result.scannedContentHash;
387
+ if (result.status !== "readable") source.selected = false;
388
+ if (result.status === "readable" && result.lines !== undefined) {
389
+ source.sections = outlineMarkdown(result.lines).map((section) => ({
390
+ title: section.breadcrumb,
391
+ startLine: section.startLine,
392
+ endLine: section.endLine,
393
+ }));
394
+ }
395
+ }
396
+
397
+ async function inspectReferences(
398
+ context: InspectionContext,
399
+ reads: ReadonlyMap<string, DocumentRead>,
400
+ ): Promise<{
401
+ references: ProductContextReferenceV1[];
402
+ referencesTruncated: boolean;
403
+ pathLimitations: string[];
404
+ }> {
405
+ const references: ProductContextReferenceV1[] = [];
406
+ const pathLimitations: string[] = [];
407
+ for (const [sourcePath, document] of reads) {
408
+ if (document.status !== "readable" || document.lines === undefined) continue;
409
+ for (const link of findMarkdownLinks(document.lines)) {
410
+ context.input.signal?.throwIfAborted();
411
+ if (link.kind !== "relative_file") continue;
412
+ if (references.length >= MAX_REFERENCES)
413
+ return {
414
+ references: sortedReferences(references),
415
+ referencesTruncated: true,
416
+ pathLimitations,
417
+ };
418
+ const target = referencePath(context.root, sourcePath, link.target);
419
+ const reference = { sourcePath, sourceLine: link.line, targetPath: target.path };
420
+ if (target.limitation !== undefined) {
421
+ references.push({ ...reference, status: "not_in_scan" });
422
+ pathLimitations.push(target.limitation);
423
+ } else references.push(await inspectReference(context, reference));
424
+ }
425
+ }
426
+ return { references: sortedReferences(references), referencesTruncated: false, pathLimitations };
427
+ }
428
+
429
+ function referencePath(
430
+ root: string,
431
+ sourcePath: string,
432
+ target: string,
433
+ ): { path: string; limitation?: string } {
434
+ const filePart = linkFilePath(target);
435
+ try {
436
+ const decoded = decodeURIComponent(filePart).replaceAll("\\", "/");
437
+ return {
438
+ path: normalizedRelativePath(
439
+ root,
440
+ path.resolve(root, path.posix.dirname(sourcePath), decoded),
441
+ ),
442
+ };
443
+ } catch {
444
+ return {
445
+ path: normalizedRelativePath(
446
+ root,
447
+ path.resolve(root, path.posix.dirname(sourcePath), filePart),
448
+ ),
449
+ limitation: `Reference from "${sourcePath}" to "${target}" has a malformed URI path; no target path was inspected.`,
450
+ };
451
+ }
452
+ }
453
+
454
+ function sortedReferences(references: ProductContextReferenceV1[]): ProductContextReferenceV1[] {
455
+ return references.sort(
456
+ (left, right) =>
457
+ compareCodepoints(left.sourcePath, right.sourcePath) ||
458
+ left.sourceLine - right.sourceLine ||
459
+ compareCodepoints(left.targetPath, right.targetPath),
460
+ );
461
+ }
462
+
463
+ async function inspectReference(
464
+ context: InspectionContext,
465
+ reference: Omit<ProductContextReferenceV1, "status" | "targetContentHash">,
466
+ ): Promise<ProductContextReferenceV1> {
467
+ const absolute = path.resolve(context.root, reference.targetPath);
468
+ if (!isWithinRoot(context.root, absolute)) return { ...reference, status: "outside_workspace" };
469
+ const accepted = context.inventory.get(reference.targetPath);
470
+ if (accepted !== undefined)
471
+ return { ...reference, status: "present", targetContentHash: accepted.contentHash };
472
+ const options = context.input.signal === undefined ? {} : { signal: context.input.signal };
473
+ try {
474
+ const stat = await context.input.fs.stat(absolute, options);
475
+ context.input.signal?.throwIfAborted();
476
+ if (stat === null) return { ...reference, status: "missing" };
477
+ const realPath = await context.input.fs.realPath(absolute, options);
478
+ context.input.signal?.throwIfAborted();
479
+ return {
480
+ ...reference,
481
+ status: isWithinRoot(context.root, realPath) ? "not_in_scan" : "outside_workspace",
482
+ };
483
+ } catch (error) {
484
+ rethrowCancellation(error, context.input.signal);
485
+ return { ...reference, status: "not_in_scan" };
486
+ }
487
+ }
488
+
489
+ function missingSourceRoles(
490
+ sources: readonly ProductContextSourceV1[],
491
+ inventoryTruncated: boolean,
492
+ ): ProductContextRoleV1[] {
493
+ if (inventoryTruncated) return [];
494
+ return REQUIRED_ROLES.filter((role) => !sources.some((source) => source.role === role));
495
+ }
496
+
497
+ function assessmentStatus(
498
+ sources: readonly ProductContextSourceV1[],
499
+ missingRoles: readonly ProductContextRoleV1[],
500
+ ambiguousRoles: readonly ProductContextRoleV1[],
501
+ inventoryTruncated: boolean,
502
+ ): ProductContextAssessmentV1["status"] {
503
+ if (
504
+ inventoryTruncated ||
505
+ sources.some((source) =>
506
+ ["unreadable", "changed", "not_in_scan", "not_assessed"].includes(source.status),
507
+ )
508
+ )
509
+ return "incomplete";
510
+ if (ambiguousRoles.some((role) => REQUIRED_ROLES.includes(role))) return "needs_selection";
511
+ if (
512
+ missingRoles.length > 0 ||
513
+ REQUIRED_ROLES.some(
514
+ (role) =>
515
+ !sources.some(
516
+ (source) => source.role === role && source.selected && source.status === "readable",
517
+ ),
518
+ )
519
+ )
520
+ return "needs_context";
521
+ return "ready_for_review";
522
+ }
523
+
524
+ function inspectionLimitations(
525
+ input: AssessProductContextInputV1,
526
+ reads: ReadonlyMap<string, DocumentRead>,
527
+ references: readonly ProductContextReferenceV1[],
528
+ referencesTruncated: boolean,
529
+ pathLimitations: readonly string[],
530
+ ): string[] {
531
+ const limitations = [
532
+ "Document roles inferred from filenames are candidates, not confirmed authority.",
533
+ "References confirm accepted-scan paths only; anchors, features, behavior, and ownership remain unverified.",
534
+ ...pathLimitations,
535
+ ];
536
+ if (input.inventoryTruncated)
537
+ limitations.push(
538
+ "The accepted file inventory was truncated; missing roles and unique filename selection cannot be established.",
539
+ );
540
+ if (referencesTruncated)
541
+ limitations.push(
542
+ "Local document references exceeded the limit of 256; further reference paths were not assessed.",
543
+ );
544
+ for (const document of reads.values())
545
+ if (document.limitation !== undefined) limitations.push(document.limitation);
546
+ for (const reference of references) {
547
+ if (reference.status !== "present")
548
+ limitations.push(
549
+ `Reference from "${reference.sourcePath}":${String(reference.sourceLine)} to "${reference.targetPath}" is ${reference.status}.`,
550
+ );
551
+ }
552
+ return [...new Set(limitations)].sort(compareCodepoints);
553
+ }
554
+
555
+ function reviewQuestions(
556
+ sources: readonly ProductContextSourceV1[],
557
+ references: readonly ProductContextReferenceV1[],
558
+ ): string[] {
559
+ const questions = [
560
+ "Which product features are intended, and which current code and tests demonstrate each one?",
561
+ "Who owns each feature and requirement, and which source takes precedence when documents disagree?",
562
+ ];
563
+ for (const role of REQUIRED_ROLES) {
564
+ if (
565
+ !sources.some(
566
+ (source) => source.role === role && source.selected && source.status === "readable",
567
+ )
568
+ )
569
+ questions.push(`Which readable document is the authoritative ${role} source?`);
570
+ }
571
+ if (references.some((reference) => reference.status !== "present"))
572
+ questions.push(
573
+ "Which unresolved document references should be corrected or explicitly excluded from the review?",
574
+ );
575
+ return questions;
576
+ }