@untangle-code/cli 0.0.0-stage → 0.1.1

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 +451 -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,360 @@
1
+ /** One report with separate own metrics, external evidence and explained gaps. */
2
+ import { analyzeProductAlignment } from "@untangle-code/core";
3
+ import { METRICS_VERSION, compareCodepoints, formatExternalNumber } from "@untangle-code/domain";
4
+ import { createLineOffsetResolver, defaultProcessLimits } from "@untangle-code/extension-runtime";
5
+
6
+ import { boolFlag, enumFlag, stringFlag, type FlagSpecs, type ParsedArgs } from "../cli/args.js";
7
+ import type { Command, CommandContext } from "../cli/command.js";
8
+ import { EXIT, UsageError } from "../cli/exit.js";
9
+ import { line, note, type Io } from "../cli/io.js";
10
+
11
+ import { analyze, type AnalysisResult } from "./complexity.js";
12
+ import { explainMissing, loadExtensionContext } from "./extensions/context.js";
13
+ import {
14
+ canonicalize,
15
+ createExtensionEnvironment,
16
+ resolveUserPath,
17
+ } from "./extensions/environment.js";
18
+ import {
19
+ finishScanFeature,
20
+ renderScanFeature,
21
+ type ScanFeatureContext,
22
+ type ScanProductAnalyzer,
23
+ } from "./extensions/feature-scan.js";
24
+ import { invokeExtension, type ExtensionRanV1 } from "./extensions/invoke.js";
25
+ import { emitJson, renderTable } from "./extensions/render.js";
26
+ import { workspaceFileResolver, lazyWorkspaceContents } from "./extensions/run.js";
27
+ import { saveCliState, summarizeRun } from "./extensions/state.js";
28
+
29
+ const FLAGS: FlagSpecs = {
30
+ root: {
31
+ kind: "string",
32
+ placeholder: "PATH",
33
+ describe: "Measurement root directory.",
34
+ defaultLabel: "current directory",
35
+ },
36
+ yes: {
37
+ kind: "boolean",
38
+ describe:
39
+ "Allow container provisioning and missing-credential setup for enabled extensions; costs are shown on stderr first.",
40
+ },
41
+ format: {
42
+ kind: "string",
43
+ placeholder: "text|json",
44
+ describe: "Output format.",
45
+ defaultLabel: "text",
46
+ },
47
+ feature: {
48
+ kind: "string",
49
+ placeholder: "ID",
50
+ describe:
51
+ "Declared feature: own full-file analysis, responsibility and separately scoped external evidence.",
52
+ },
53
+ manifest: {
54
+ kind: "string",
55
+ placeholder: "PATH",
56
+ describe: "Feature manifest inside --root; requires --feature.",
57
+ },
58
+ "test-evidence": {
59
+ kind: "string",
60
+ placeholder: "PATH",
61
+ describe:
62
+ "Supplied source-bound test evidence inside --root; requires --feature. Does not execute tests.",
63
+ },
64
+ };
65
+
66
+ interface NotMeasured {
67
+ extensionId: string;
68
+ reason: string;
69
+ detail: string;
70
+ nextStep?: string;
71
+ }
72
+
73
+ interface ScanData {
74
+ root: string;
75
+ own: AnalysisResult;
76
+ outcomes: ExtensionRanV1[];
77
+ notMeasured: NotMeasured[];
78
+ warnings: string[];
79
+ featureAlignment?: ScanFeatureContext;
80
+ }
81
+
82
+ export const scanCommand: Command = {
83
+ spec: {
84
+ name: "scan",
85
+ implementedBy: "commands/scan.js",
86
+ summary: "Own metrics and enabled extensions in one report",
87
+ usage:
88
+ "untangle scan [--root=PATH] [--feature=ID] [--manifest=PATH] [--test-evidence=PATH] [--yes] [--format=text|json]",
89
+ details: [
90
+ "Measure local complexity without an index and run all enabled extensions through Untangle. License gates, digest pins and provenance still apply.",
91
+ "Three separate sections: own metrics, external evidence and unmeasured extensions with reasons. comparableTo supports test cross-checks, never differences, ratios or a combined report score (X3, X8).",
92
+ "Without --yes, no container is provisioned. With --yes, consent applies to the whole scan; resources and image are shown on stderr before each provisioning action. License gates remain independent.",
93
+ "Individual extension failures do not stop the report. Exit code 0 means the report was created, not that every extension succeeded. JSON includes run status, provenance and skip reasons.",
94
+ "--feature links declared intent, ownership, complete code/test measurements and external file evidence. Repository analyzer values stay repository context; remote source freshness is not inferred. Local sources are checked before and after. No feature flag preserves the existing report.",
95
+ ],
96
+ flags: FLAGS,
97
+ examples: [
98
+ "untangle scan",
99
+ "untangle scan --format=json",
100
+ "untangle scan --feature=search.local --format=json",
101
+ "untangle scan --yes",
102
+ ],
103
+ exitCodes: [
104
+ [EXIT.ok, "Report created, including explained extension failures."],
105
+ [EXIT.operational, "The own-code analysis could not run."],
106
+ [EXIT.usage, "Invalid arguments."],
107
+ [EXIT.cancelled, "Cancelled."],
108
+ ],
109
+ },
110
+ run: runScan,
111
+ };
112
+
113
+ /** Injectable HTTP boundary; analysis, discovery and execution remain real in tests. */
114
+ export async function runScan(
115
+ ctx: CommandContext,
116
+ args: ParsedArgs,
117
+ deps: { fetchImpl?: typeof fetch; analyzeProduct?: ScanProductAnalyzer } = {},
118
+ ): Promise<number> {
119
+ const format = enumFlag(args, "format", ["text", "json"] as const, "text");
120
+ if (args.positionals.length > 0) {
121
+ throw new UsageError("scan does not accept positional arguments.", "Use --root=PATH.");
122
+ }
123
+ const featureId = stringFlag(args, "feature");
124
+ const manifestPath = stringFlag(args, "manifest");
125
+ const testEvidencePath = stringFlag(args, "test-evidence");
126
+ for (const [name, value] of [
127
+ ["feature", featureId],
128
+ ["manifest", manifestPath],
129
+ ["test-evidence", testEvidencePath],
130
+ ] as const) {
131
+ if (value !== undefined && value.trim().length === 0)
132
+ throw new UsageError(`--${name} requires a non-empty value.`);
133
+ }
134
+ if (featureId === undefined && (manifestPath !== undefined || testEvidencePath !== undefined))
135
+ throw new UsageError("--manifest and --test-evidence require --feature.");
136
+ ctx.signal.throwIfAborted();
137
+ const requestedRoot = resolveUserPath(ctx.cwd, stringFlag(args, "root") ?? ".");
138
+ // The analyzed project, including --root outside cwd, is the discovery boundary.
139
+ const environment = await createExtensionEnvironment({ cwd: requestedRoot, env: ctx.env });
140
+ const root = await canonicalize(environment.fs, requestedRoot);
141
+ const productAnalyzer = deps.analyzeProduct ?? analyzeProductAlignment;
142
+ const featureOptions =
143
+ featureId === undefined
144
+ ? undefined
145
+ : {
146
+ root,
147
+ featureId,
148
+ signal: ctx.signal,
149
+ ...(manifestPath === undefined
150
+ ? {}
151
+ : { manifestPath: resolveUserPath(root, manifestPath) }),
152
+ ...(testEvidencePath === undefined
153
+ ? {}
154
+ : { testEvidencePath: resolveUserPath(root, testEvidencePath) }),
155
+ };
156
+ const productBefore =
157
+ featureOptions === undefined ? undefined : await productAnalyzer(featureOptions);
158
+ const own = await analyze(root, ctx.signal);
159
+ const context = await loadExtensionContext(environment);
160
+ const notMeasured: NotMeasured[] = [];
161
+ const outcomes: ExtensionRanV1[] = [];
162
+ const warnings = [...context.warnings];
163
+
164
+ for (const rejected of context.discovery.rejected) {
165
+ notMeasured.push({
166
+ extensionId: rejected.directoryName ?? rejected.manifestPath,
167
+ reason: "manifest_rejected",
168
+ detail: `${rejected.manifestPath}: ${rejected.issues.map((issue) => `${issue.field}: ${issue.message}`).join("; ")}`,
169
+ nextStep: "untangle extensions list",
170
+ });
171
+ }
172
+ for (const ignored of context.discovery.ignored) {
173
+ notMeasured.push({
174
+ extensionId: ignored.manifestPath,
175
+ reason: "manifest_ignored",
176
+ detail: `${ignored.reason}: ${ignored.detail}`,
177
+ nextStep: "untangle extensions list",
178
+ });
179
+ }
180
+ const installed = new Set(context.discovery.extensions.map((entry) => entry.manifest.id));
181
+ for (const id of context.state.enabled) {
182
+ if (!installed.has(id) && !notMeasured.some((entry) => entry.extensionId === id)) {
183
+ notMeasured.push({
184
+ extensionId: id,
185
+ reason: "extension_missing",
186
+ detail: explainMissing(context, id),
187
+ nextStep: "untangle extensions list",
188
+ });
189
+ }
190
+ }
191
+
192
+ const resolveFile = workspaceFileResolver(root);
193
+ const resolvePosition = createLineOffsetResolver(lazyWorkspaceContents(root));
194
+ const extensions = [...context.discovery.extensions].sort((a, b) =>
195
+ compareCodepoints(a.manifest.id, b.manifest.id),
196
+ );
197
+ for (const extension of extensions) {
198
+ ctx.signal.throwIfAborted();
199
+ const outcome = await invokeExtension({
200
+ environment,
201
+ context,
202
+ extension,
203
+ workspacePath: root,
204
+ target: root,
205
+ limits: defaultProcessLimits(),
206
+ provisionConsent: boolFlag(args, "yes"),
207
+ requireEnabled: true,
208
+ ...(deps.fetchImpl === undefined ? {} : { fetchImpl: deps.fetchImpl }),
209
+ onProvisionPlanned: (detail) => {
210
+ note(ctx.io, `Provisioning: ${detail}`);
211
+ },
212
+ onProvisionStep: (step) => {
213
+ note(ctx.io, ` ${step}`);
214
+ },
215
+ signal: ctx.signal,
216
+ resolveFile,
217
+ resolvePosition,
218
+ });
219
+ if (outcome.status === "not_run") {
220
+ notMeasured.push(outcome);
221
+ continue;
222
+ }
223
+ outcomes.push(outcome);
224
+ if (outcome.result.run.exitStatus !== "completed") {
225
+ notMeasured.push({
226
+ extensionId: outcome.extensionId,
227
+ reason: "run_failed",
228
+ detail: [
229
+ outcome.result.run.exitStatus,
230
+ outcome.result.run.errorCode,
231
+ outcome.result.error?.message,
232
+ ]
233
+ .filter(Boolean)
234
+ .join(": "),
235
+ nextStep: `untangle extensions run ${outcome.extensionId}${extension.manifest.container === undefined ? "" : " --yes"}`,
236
+ });
237
+ }
238
+ }
239
+ ctx.signal.throwIfAborted();
240
+ if (outcomes.length > 0) {
241
+ try {
242
+ await saveCliState(environment.fs, environment.userDataDir, {
243
+ ...context.state,
244
+ lastRuns: {
245
+ ...context.state.lastRuns,
246
+ ...Object.fromEntries(
247
+ outcomes.map((outcome) => [outcome.extensionId, summarizeRun(outcome.result.run)]),
248
+ ),
249
+ },
250
+ });
251
+ } catch {
252
+ warnings.push(
253
+ "The report was created, but the last extension run could not be saved in the user profile.",
254
+ );
255
+ }
256
+ }
257
+ notMeasured.sort(
258
+ (a, b) =>
259
+ compareCodepoints(a.extensionId, b.extensionId) || compareCodepoints(a.reason, b.reason),
260
+ );
261
+ ctx.signal.throwIfAborted();
262
+ const featureAlignment =
263
+ featureOptions === undefined || productBefore === undefined
264
+ ? undefined
265
+ : await finishScanFeature(featureOptions, productBefore, outcomes, productAnalyzer);
266
+ ctx.signal.throwIfAborted();
267
+ render(ctx.io, format, {
268
+ root,
269
+ own,
270
+ outcomes,
271
+ notMeasured,
272
+ warnings,
273
+ ...(featureAlignment === undefined ? {} : { featureAlignment }),
274
+ });
275
+ return EXIT.ok;
276
+ }
277
+
278
+ function render(io: Io, format: "text" | "json", data: ScanData): void {
279
+ if (format === "json") {
280
+ emitJson(io, {
281
+ command: "scan",
282
+ root: data.root,
283
+ ownMetrics: {
284
+ metricsVersion: METRICS_VERSION,
285
+ filesDiscovered: data.own.filesDiscovered,
286
+ filesAnalyzed: data.own.filesAnalyzed,
287
+ totals: data.own.totals,
288
+ totalsReading: data.own.totalsReading,
289
+ proseAnalyzed: data.own.proseAnalyzed,
290
+ prose: data.own.prose,
291
+ skipped: data.own.skipped,
292
+ },
293
+ externalSignals: data.outcomes.map((outcome) => ({
294
+ extensionId: outcome.extensionId,
295
+ evidenceOnly: true,
296
+ health: outcome.health,
297
+ run: outcome.result.run,
298
+ measurements: outcome.result.measurements,
299
+ findings: outcome.result.findings,
300
+ skipped: outcome.result.skipped,
301
+ error: outcome.result.error?.message,
302
+ })),
303
+ notMeasured: data.notMeasured,
304
+ warnings: data.warnings,
305
+ ...(data.featureAlignment === undefined ? {} : { featureAlignment: data.featureAlignment }),
306
+ });
307
+ return;
308
+ }
309
+ line(io, `# Own metrics (${METRICS_VERSION}) — ${data.root}`);
310
+ for (const row of renderTable(
311
+ ["KENNZAHL", "VALUE"],
312
+ [
313
+ ["files analyzed", String(data.own.filesAnalyzed)],
314
+ ["Ausfuehrungseinheiten", String(data.own.totals.executionUnits)],
315
+ ["including outermost units", String(data.own.totals.executionUnitRoots)],
316
+ ["Cognitive total", String(data.own.totals.cognitive)],
317
+ ["Cyclomatic total", String(data.own.totals.cyclomatic)],
318
+ ["Prose analyzed separately", String(data.own.proseAnalyzed)],
319
+ ["skipped with a reason", String(data.own.skipped.length)],
320
+ ],
321
+ ))
322
+ line(io, ` ${row}`);
323
+ line(io, " Totals: execution_unit (nested functions are not counted twice).");
324
+ for (const skip of data.own.skipped)
325
+ note(io, `skip ${skip.path ?? ""}: ${skip.reason} — ${skip.detail}`);
326
+
327
+ line(io, "\n# External signals — evidence, never Untangle metrics (X3)");
328
+ if (data.outcomes.length === 0) line(io, " no extension was executed.");
329
+ for (const { extensionId, result } of data.outcomes) {
330
+ line(io, ` ${extensionId} (${result.run.toolVersion}): ${result.run.exitStatus}`);
331
+ line(
332
+ io,
333
+ ` Lauf ${result.run.runId}; ${result.run.findingsTotal} findings; ${result.run.formatParserVersion}`,
334
+ );
335
+ for (const measurement of result.measurements) {
336
+ const signal = measurement.signal;
337
+ line(
338
+ io,
339
+ ` ${measurement.key}: ${formatExternalNumber(measurement.value)} — ${signal === undefined ? "without a declared meaning" : `${signal.kind}/${signal.scope}`}`,
340
+ );
341
+ }
342
+ for (const finding of result.findings)
343
+ line(
344
+ io,
345
+ ` ${finding.severity.normalized} ${finding.filePath}:${finding.sourceRange.startLine ?? 0} ${finding.ruleId}: ${finding.message}`,
346
+ );
347
+ for (const skip of result.skipped) note(io, `${extensionId}: ${skip.reason} — ${skip.detail}`);
348
+ for (const warning of result.run.warnings) note(io, `${extensionId}: ${warning}`);
349
+ for (const error of result.run.errors)
350
+ note(io, `${extensionId}: ${error.code} — ${error.message}`);
351
+ }
352
+ line(io, "\n# Not measured, with reasons (E4)");
353
+ if (data.notMeasured.length === 0) line(io, " no omitted or failed extensions.");
354
+ for (const entry of data.notMeasured) {
355
+ line(io, ` ${entry.extensionId}: ${entry.reason}\n ${entry.detail}`);
356
+ if (entry.nextStep !== undefined) line(io, ` -> ${entry.nextStep}`);
357
+ }
358
+ for (const warning of data.warnings) note(io, `warning: ${warning}`);
359
+ if (data.featureAlignment !== undefined) renderScanFeature(io, data.featureAlignment);
360
+ }
@@ -0,0 +1,243 @@
1
+ import { constants } from "node:fs";
2
+ import { lstat, mkdir, open, realpath, unlink } from "node:fs/promises";
3
+ import path from "node:path";
4
+
5
+ import {
6
+ discoverSddArtifacts,
7
+ type SddConnectionReportV1,
8
+ type SddFrameworkV1,
9
+ } from "@untangle-code/core";
10
+ import { canonicalJson, sha256Hex } from "@untangle-code/domain";
11
+
12
+ import { boolFlag, enumFlag, stringFlag, type FlagSpecs, type ParsedArgs } from "../cli/args.js";
13
+ import type { CommandContext } from "../cli/command.js";
14
+ import { OperationalError, UsageError } from "../cli/exit.js";
15
+ import { line, note } from "../cli/io.js";
16
+
17
+ export const SDD_CONNECT_FLAGS: FlagSpecs = {
18
+ "dry-run": {
19
+ kind: "boolean",
20
+ describe: "Inspect the SDD connector draft without writing its local report or manifest.",
21
+ },
22
+ };
23
+
24
+ export interface SddConnectionArtifactV1 {
25
+ schemaVersion: 1;
26
+ kind: "sdd_connection_artifact";
27
+ report: SddConnectionReportV1;
28
+ reportPath: string | null;
29
+ manifestPath: string | null;
30
+ sha256: { report: string; manifest: string } | null;
31
+ }
32
+
33
+ /** Exclusive, versioned project metadata; the upstream workspace is never modified. */
34
+ export async function writeSddConnection(
35
+ report: SddConnectionReportV1,
36
+ options: { signal?: AbortSignal } = {},
37
+ ): Promise<SddConnectionArtifactV1> {
38
+ const { signal } = options;
39
+ signal?.throwIfAborted();
40
+ if (report.status === "stale")
41
+ throw new OperationalError("SDD sources changed during inspection; run the connector again.");
42
+ if (report.features.length === 0)
43
+ return {
44
+ schemaVersion: 1,
45
+ kind: "sdd_connection_artifact",
46
+ report,
47
+ reportPath: null,
48
+ manifestPath: null,
49
+ sha256: null,
50
+ };
51
+ const root = await realpath(report.root);
52
+ if (root !== report.root)
53
+ throw new OperationalError("The selected SDD project root changed physical identity.");
54
+ const current = await discoverSddArtifacts({
55
+ root,
56
+ framework: report.requestedFramework,
57
+ ...(signal ? { signal } : {}),
58
+ });
59
+ if (
60
+ current.status === "stale" ||
61
+ current.sourceDigest !== report.sourceDigest ||
62
+ canonicalJson(current) !== canonicalJson(report)
63
+ )
64
+ throw new OperationalError(
65
+ "SDD source evidence changed after the preview; inspect a fresh connector plan before writing.",
66
+ );
67
+ const reportText = JSON.stringify(report, null, 2) + "\n";
68
+ const manifestText = JSON.stringify(report.draft, null, 2) + "\n";
69
+ const sha256 = { report: sha256Hex(reportText), manifest: sha256Hex(manifestText) };
70
+ const artifactKey = sha256Hex(
71
+ canonicalJson({ report: sha256.report, manifest: sha256.manifest }),
72
+ );
73
+ let directory = root;
74
+ for (const component of [
75
+ ".untangle",
76
+ "sdd",
77
+ `${report.requestedFramework}-${artifactKey.slice(0, 24)}`,
78
+ ]) {
79
+ signal?.throwIfAborted();
80
+ directory = path.join(directory, component);
81
+ try {
82
+ await mkdir(directory, { mode: 0o700 });
83
+ } catch (error) {
84
+ if ((error as NodeJS.ErrnoException).code !== "EEXIST") throw error;
85
+ }
86
+ const info = await lstat(directory);
87
+ if (!info.isDirectory() || info.isSymbolicLink() || (await realpath(directory)) !== directory)
88
+ throw new OperationalError(
89
+ "SDD metadata directories must be physical in-project directories, without symlinks.",
90
+ );
91
+ }
92
+ const created: { file: string; ino: number; dev: number; expected: Buffer; complete: boolean }[] =
93
+ [];
94
+ try {
95
+ for (const [name, text] of [
96
+ ["report.json", reportText],
97
+ ["untangle.features.json", manifestText],
98
+ ] as const) {
99
+ signal?.throwIfAborted();
100
+ const file = path.join(directory, name);
101
+ let handle;
102
+ try {
103
+ handle = await open(
104
+ file,
105
+ constants.O_WRONLY | constants.O_CREAT | constants.O_EXCL | constants.O_NOFOLLOW,
106
+ 0o600,
107
+ );
108
+ } catch (error) {
109
+ if ((error as NodeJS.ErrnoException).code !== "EEXIST") throw error;
110
+ const existing = await open(file, constants.O_RDONLY | constants.O_NOFOLLOW);
111
+ try {
112
+ const info = await existing.stat();
113
+ if (
114
+ !info.isFile() ||
115
+ info.size !== Buffer.byteLength(text) ||
116
+ (await realpath(file)) !== file ||
117
+ (await existing.readFile()).toString("utf8") !== text
118
+ )
119
+ throw new OperationalError("Existing SDD artifacts differ; no file was overwritten.");
120
+ } finally {
121
+ await existing.close();
122
+ }
123
+ continue;
124
+ }
125
+ try {
126
+ const info = await handle.stat();
127
+ const own = {
128
+ file,
129
+ ino: info.ino,
130
+ dev: info.dev,
131
+ expected: Buffer.from(text),
132
+ complete: false,
133
+ };
134
+ created.push(own);
135
+ await handle.writeFile(text, { signal });
136
+ own.complete = true;
137
+ signal?.throwIfAborted();
138
+ } finally {
139
+ await handle.close();
140
+ }
141
+ }
142
+ } catch (error) {
143
+ for (const own of created) {
144
+ const info = await lstat(own.file).catch(() => null);
145
+ if (!info?.isFile() || info.ino !== own.ino || info.dev !== own.dev) continue;
146
+ const handle = await open(own.file, constants.O_RDONLY | constants.O_NOFOLLOW).catch(
147
+ () => null,
148
+ );
149
+ if (!handle) continue;
150
+ try {
151
+ const opened = await handle.stat();
152
+ if (opened.ino !== own.ino || opened.dev !== own.dev || opened.size > own.expected.length)
153
+ continue;
154
+ const bytes = await handle.readFile();
155
+ // A failed write may leave only a prefix. Preserve replacements and unexpected edits.
156
+ const matches = own.complete
157
+ ? bytes.equals(own.expected)
158
+ : bytes.equals(own.expected.subarray(0, bytes.length));
159
+ const current = await lstat(own.file).catch(() => null);
160
+ const unchanged =
161
+ current?.ino === opened.ino &&
162
+ current.dev === opened.dev &&
163
+ current.size === opened.size &&
164
+ current.mtimeMs === opened.mtimeMs;
165
+ if (matches && unchanged) await unlink(own.file);
166
+ } finally {
167
+ await handle.close();
168
+ }
169
+ }
170
+ throw error;
171
+ }
172
+ return {
173
+ schemaVersion: 1,
174
+ kind: "sdd_connection_artifact",
175
+ report,
176
+ reportPath: path.join(directory, "report.json"),
177
+ manifestPath: path.join(directory, "untangle.features.json"),
178
+ sha256,
179
+ };
180
+ }
181
+
182
+ export async function runSddConnection(
183
+ ctx: CommandContext,
184
+ args: ParsedArgs,
185
+ deps: { discover?: typeof discoverSddArtifacts; write?: typeof writeSddConnection } = {},
186
+ ): Promise<number> {
187
+ const positionals =
188
+ args.positionals[0] === "connect" ? args.positionals.slice(1) : args.positionals;
189
+ if (
190
+ positionals.length > 1 ||
191
+ !["auto", "spec-kit", "openspec"].includes(positionals[0] ?? "auto")
192
+ )
193
+ throw new UsageError(
194
+ "Use `untangle product connect [auto|spec-kit|openspec] [--root=PATH] [--dry-run] [--format=json]`.",
195
+ );
196
+ for (const [name, value] of Object.entries(args.flags))
197
+ if (!["root", "dry-run", "format", "help"].includes(name) && value !== undefined)
198
+ throw new UsageError(`--${name} is not supported by product connect.`);
199
+ const framework = (positionals[0] ?? "auto") as SddFrameworkV1 | "auto";
200
+ const format = enumFlag(args, "format", ["text", "json"] as const, "text");
201
+ const report = await (deps.discover ?? discoverSddArtifacts)({
202
+ root: path.resolve(ctx.cwd, stringFlag(args, "root") ?? "."),
203
+ framework,
204
+ signal: ctx.signal,
205
+ });
206
+ ctx.signal.throwIfAborted();
207
+ const result: SddConnectionArtifactV1 = boolFlag(args, "dry-run")
208
+ ? {
209
+ schemaVersion: 1,
210
+ kind: "sdd_connection_artifact",
211
+ report,
212
+ reportPath: null,
213
+ manifestPath: null,
214
+ sha256: null,
215
+ }
216
+ : await (deps.write ?? writeSddConnection)(report, { signal: ctx.signal });
217
+ if (format === "json") line(ctx.io, JSON.stringify(result, null, 2));
218
+ else {
219
+ line(
220
+ ctx.io,
221
+ `SDD connection: ${report.status}; ${String(report.features.length)} proposed features from ${report.frameworks.join(", ") || "no detected framework"}.`,
222
+ );
223
+ if (result.manifestPath) {
224
+ line(ctx.io, `Review manifest: ${result.manifestPath}`);
225
+ line(ctx.io, `Evidence report: ${result.reportPath!}`);
226
+ line(
227
+ ctx.io,
228
+ `Next argv (data, not a shell command): ${JSON.stringify(["untangle", "product", `--root=${report.root}`, `--manifest=${result.manifestPath}`])}`,
229
+ );
230
+ line(
231
+ ctx.io,
232
+ `Map argv (data, not a shell command): ${JSON.stringify(["untangle", "graph", "features", `--root=${report.root}`, `--feature-map=${result.manifestPath}`])}`,
233
+ );
234
+ }
235
+ for (const issue of report.issues)
236
+ note(ctx.io, `${issue.code}: ${issue.path}: ${issue.message}`);
237
+ note(
238
+ ctx.io,
239
+ "Imported declarations require review. No framework commands or tests ran; no implementation or ownership was confirmed.",
240
+ );
241
+ }
242
+ return report.status === "stale" ? 1 : 0;
243
+ }
@@ -0,0 +1,92 @@
1
+ /**
2
+ * DER BAUPLAN fuer Befehle, deren Faehigkeit es NOCH NICHT GIBT.
3
+ *
4
+ * STAND: DIESE DATEI FUEHRT DERZEIT KEINEN BEFEHL MEHR. `watch` ist mit
5
+ * WP-128 hier ausgezogen, `graph` und `flow` mit WP-229 — beide lesen den
6
+ * Graphen jetzt wirklich zurueck (`commands/graph/`, `commands/flow/`).
7
+ * Geblieben ist {@link createUnavailableCommand}: der Bauplan fuer den
8
+ * naechsten Befehl, der angelegt, aber noch nicht gebaut ist. Er wird
9
+ * absichtlich NICHT geloescht — die Alternative zu einem ehrlichen
10
+ * Platzhalter ist erfahrungsgemaess kein fertiger Befehl, sondern ein
11
+ * stiller.
12
+ *
13
+ * Sie stehen in der Oberflaeche, weil ihre Abwesenheit sonst unsichtbar waere
14
+ * — ein Nutzer wuesste nicht, ob `untangle index` fehlt, falsch geschrieben
15
+ * ist oder heimlich nichts tut. BUILD_PLAN E4 verlangt genau das Gegenteil:
16
+ * jedes Ueberspringen bekommt einen Grund.
17
+ *
18
+ * Deshalb tut jeder dieser Befehle drei Dinge und nichts sonst:
19
+ * 1. er sagt, WAS fehlt — pruefbar, mit Paket- und Typnamen;
20
+ * 2. er sagt, was HEUTE schon geht, wenn es etwas gibt;
21
+ * 3. er nennt GENAU EINEN naechsten Schritt.
22
+ * Und er endet mit Exit-Code 3, nie mit 0 und nie mit 1.
23
+ */
24
+
25
+ import type { FlagSpecs } from "../cli/args.js";
26
+ import type { Command, CommandContext, CommandSpec } from "../cli/command.js";
27
+ import { wrap } from "../cli/command.js";
28
+ import { EXIT, UnavailableError } from "../cli/exit.js";
29
+ import { note } from "../cli/io.js";
30
+
31
+ const COMMON_FLAGS: FlagSpecs = {
32
+ root: {
33
+ kind: "string",
34
+ placeholder: "PATH",
35
+ describe: "Project directory; configuration is discovered from here.",
36
+ defaultLabel: "current directory",
37
+ },
38
+ };
39
+
40
+ interface UnavailableDefinition {
41
+ readonly name: string;
42
+ readonly summary: string;
43
+ readonly usage: string;
44
+ /** Was fehlt — die pruefbare Aussage, nicht „nicht implementiert". */
45
+ readonly missing: readonly string[];
46
+ /** Was heute schon geht; leer, wenn es nichts gibt. */
47
+ readonly worksToday?: readonly string[];
48
+ /** GENAU EIN naechster Schritt. */
49
+ readonly nextStep: string;
50
+ readonly extraFlags?: FlagSpecs;
51
+ }
52
+
53
+ export function createUnavailableCommand(definition: UnavailableDefinition): Command {
54
+ const spec: CommandSpec = {
55
+ name: definition.name,
56
+ // Alle drei Platzhalter kommen aus DIESEM Modul. Das ist die Kehrseite
57
+ // von `implementedBy`: ein Befehl, der hierher zeigt, gibt zu, dass
58
+ // seine Faehigkeit noch fehlt (`notYetBuilt`) — und ein Befehl, der
59
+ // NICHT hierher zeigt, behauptet das Gegenteil und wird daran gemessen.
60
+ implementedBy: "commands/unavailable.js",
61
+ summary: `${definition.summary}; not available yet`,
62
+ usage: definition.usage,
63
+ details: [
64
+ `This command is registered, but its capability is not implemented. It performs no action and exits with code ${String(EXIT.unavailable)}; it neither reports success nor invents an operational error.`,
65
+ ...definition.missing,
66
+ ...(definition.worksToday ?? []),
67
+ ],
68
+ flags: { ...COMMON_FLAGS, ...(definition.extraFlags ?? {}) },
69
+ exitCodes: [[EXIT.unavailable, "This capability is not implemented."]],
70
+ notYetBuilt: true,
71
+ };
72
+
73
+ return {
74
+ spec,
75
+ run(ctx: CommandContext): Promise<number> {
76
+ note(ctx.io, `untangle ${definition.name}: not available yet.`);
77
+ note(ctx.io, "");
78
+ for (const paragraph of definition.missing) {
79
+ for (const wrapped of wrap(paragraph, 76)) note(ctx.io, ` ${wrapped}`);
80
+ note(ctx.io, "");
81
+ }
82
+ for (const paragraph of definition.worksToday ?? []) {
83
+ for (const wrapped of wrap(paragraph, 76)) note(ctx.io, ` ${wrapped}`);
84
+ note(ctx.io, "");
85
+ }
86
+ throw new UnavailableError(
87
+ `The capability behind "untangle ${definition.name}" is not implemented.`,
88
+ definition.nextStep,
89
+ );
90
+ },
91
+ };
92
+ }