@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,320 @@
1
+ /**
2
+ * `untangle extensions status [<id>]`
3
+ *
4
+ * The read-only view of the two promises B29 makes: every extension runs
5
+ * behind a license gate, and every container image is pinned to a complete
6
+ * digest. Both were already enforced — the gate before any process start, the
7
+ * pin as a validation rule and as `EXTENSION_IMAGE_MISMATCH` at run time —
8
+ * but only ever at the moment of a run. A guarantee nobody can inspect is
9
+ * hard to trust and easy to break unnoticed, so this command shows the pin
10
+ * the runtime would enforce, the gate that stands in front of it, the
11
+ * endpoint that would be contacted, and what the last run did.
12
+ *
13
+ * What it does NOT do is start anything the gate has not cleared. `detect`
14
+ * looks harmless but is not: a version query starts the foreign program, an
15
+ * endpoint probe talks to the foreign service. The runtime therefore refuses
16
+ * both while the gate is open (X5), and this command inherits that refusal
17
+ * rather than re-implementing it. Containers are never started or pulled here
18
+ * under any circumstances (X1); without a container runtime probe the running
19
+ * digest is reported as unknown, with the reason, instead of being quietly
20
+ * omitted (E4).
21
+ *
22
+ * Secrets never appear. Their VALUES are passed to the runtime only so it can
23
+ * redact them from probe output; what the report shows is which required
24
+ * secret is missing, by name and environment variable.
25
+ */
26
+ import {
27
+ buildHttpAuthHeaders,
28
+ createFetchHttpRunner,
29
+ createNodeProcessRunner,
30
+ defaultProcessLimits,
31
+ detectExtension,
32
+ type ExtensionHealthV1,
33
+ type LicenseGateDecisionV1,
34
+ type LoadedExtensionV1,
35
+ } from "@untangle-code/extension-runtime";
36
+
37
+ import { type ParsedArgs } from "../../cli/args.js";
38
+ import { EXIT, OperationalError } from "../../cli/exit.js";
39
+ import { line, type Io } from "../../cli/io.js";
40
+
41
+ import { createContainerCli } from "./container.js";
42
+ import { explainMissing, findExtension, gateFor, loadExtensionContext } from "./context.js";
43
+ import type { ExtensionEnvironmentV1 } from "./environment.js";
44
+ import { emitJson, renderTable } from "./render.js";
45
+ import { resolveSecretEnvironment } from "./secret-store.js";
46
+ import type { LastRunRecordV1 } from "./state.js";
47
+
48
+ export interface StatusDeps {
49
+ /** Injected in tests so no unit test opens a socket. */
50
+ fetchImpl?: typeof fetch;
51
+ }
52
+
53
+ /** The manifest pin (X6) — `null` when the extension is not container-invoked. */
54
+ interface ImagePinV1 {
55
+ image: string;
56
+ digest: string;
57
+ }
58
+
59
+ interface StatusRowV1 {
60
+ id: string;
61
+ displayName: string;
62
+ category: string;
63
+ invocation: string[];
64
+ enabled: boolean;
65
+ license: {
66
+ spdxId: string;
67
+ usageRestriction: string;
68
+ gate: LicenseGateDecisionV1;
69
+ };
70
+ pin: ImagePinV1 | null;
71
+ health: ExtensionHealthV1;
72
+ /** Required secrets that are not set here — reported, not fatal. */
73
+ missingSecrets: string[];
74
+ manifestPath: string;
75
+ origin: string;
76
+ lastRun?: LastRunRecordV1;
77
+ }
78
+
79
+ export async function runStatus(
80
+ environment: ExtensionEnvironmentV1,
81
+ args: ParsedArgs,
82
+ io: Io,
83
+ format: "text" | "json",
84
+ deps: StatusDeps = {},
85
+ ): Promise<number> {
86
+ const context = await loadExtensionContext(environment);
87
+ const wanted = args.positionals[1];
88
+
89
+ let extensions: LoadedExtensionV1[];
90
+ if (wanted === undefined) {
91
+ extensions = [...context.discovery.extensions];
92
+ } else {
93
+ const found = findExtension(context, wanted);
94
+ if (found === null) {
95
+ throw new OperationalError(
96
+ explainMissing(context, wanted),
97
+ "Install it first: untangle extensions add --from=<path-or-url>",
98
+ );
99
+ }
100
+ extensions = [found];
101
+ }
102
+
103
+ const clock = environment.clock;
104
+ const processRunner = createNodeProcessRunner(clock);
105
+ // Nur INSPIZIEREN, nie starten: `status` ist eine Leseoperation (X1). Der
106
+ // laufende Digest ist damit erstmals wirklich beobachtet statt behauptet —
107
+ // bis Welle 12 gab es keine Sonde, und der Abgleich gegen den Pin blieb
108
+ // Vertragsevidenz.
109
+ const containerCli = createContainerCli({
110
+ processRunner,
111
+ limits: { ...defaultProcessLimits(), timeoutMs: 20_000 },
112
+ ...(environment.env["UNTANGLE_CONTAINER_CLI"] === undefined
113
+ ? {}
114
+ : { command: environment.env["UNTANGLE_CONTAINER_CLI"] }),
115
+ });
116
+ const runtimeDeps = {
117
+ clock,
118
+ random: environment.random,
119
+ processRunner,
120
+ httpRunner: createFetchHttpRunner(
121
+ (deps.fetchImpl ?? fetch) as Parameters<typeof createFetchHttpRunner>[0],
122
+ clock,
123
+ ),
124
+ containerProbe: async (
125
+ extension: LoadedExtensionV1,
126
+ probeOptions: { signal?: AbortSignal } = {},
127
+ ) => {
128
+ const runtime = await containerCli.available(probeOptions);
129
+ if (!runtime.available) {
130
+ return { available: false, detail: runtime.detail };
131
+ }
132
+ const state = await containerCli.inspect(extension.manifest, probeOptions);
133
+ return {
134
+ available: state.running && state.ownedByUntangle,
135
+ ...(state.imageDigest === undefined ? {} : { imageDigest: state.imageDigest }),
136
+ detail: state.detail,
137
+ };
138
+ },
139
+ };
140
+
141
+ const rows: StatusRowV1[] = [];
142
+ for (const extension of extensions) {
143
+ const manifest = extension.manifest;
144
+ const gate = gateFor(context, extension);
145
+
146
+ let effectiveEnv: Readonly<Record<string, string | undefined>> = environment.env;
147
+ try {
148
+ effectiveEnv = await resolveSecretEnvironment(environment, manifest);
149
+ } catch (error) {
150
+ context.warnings.push(
151
+ `${manifest.id}: ${error instanceof Error ? error.message : "Cannot read credential configuration"}`,
152
+ );
153
+ }
154
+ const secretValues: string[] = [];
155
+ const missingSecrets: string[] = [];
156
+ const secretEnv: Record<string, string> = {};
157
+ for (const secret of manifest.secrets) {
158
+ if (secret.setupOnly) continue;
159
+ const value = effectiveEnv[secret.envVar];
160
+ if (value === undefined || value === "") {
161
+ if (secret.required) {
162
+ missingSecrets.push(`${secret.name} (${secret.envVar})`);
163
+ }
164
+ continue;
165
+ }
166
+ secretEnv[secret.envVar] = value;
167
+ secretValues.push(value);
168
+ }
169
+
170
+ const httpHeaders = buildHttpAuthHeaders(manifest, effectiveEnv);
171
+ const health = await detectExtension(runtimeDeps, {
172
+ extension,
173
+ licenseGate: gate.tool.status,
174
+ ...(Object.keys(httpHeaders).length === 0 ? {} : { httpHeaders }),
175
+ env: {
176
+ PATH: environment.env["PATH"] ?? "",
177
+ ...(environment.env["HOME"] === undefined ? {} : { HOME: environment.env["HOME"] }),
178
+ ...secretEnv,
179
+ },
180
+ secretValues,
181
+ ...(manifest.http?.defaultUrl === undefined ? {} : { httpUrl: manifest.http.defaultUrl }),
182
+ });
183
+
184
+ // Der Digest gehoert zur EXTENSION, nicht zum Analyseweg. Ein Dienst wird
185
+ // als Container bereitgestellt und ueber HTTP befragt; `detect` betritt den
186
+ // Container-Zweig dann nie, und der Pin bliebe ungeprueft — obwohl genau
187
+ // dieser Container laeuft. Deshalb wird hier unabhaengig vom Aufrufmodus
188
+ // nachgesehen, sobald das Manifest einen Container beschreibt.
189
+ if (manifest.container !== undefined) {
190
+ const state = await containerCli.inspect(manifest);
191
+ if (state.ownedByUntangle && state.imageDigest !== undefined) {
192
+ health.imageDigest = state.imageDigest;
193
+ health.digestMatchesManifest = state.imageDigest === manifest.container.digest;
194
+ } else if (state.exists && !state.ownedByUntangle) {
195
+ health.unavailableReasons.push({ invocation: "container", detail: state.detail });
196
+ }
197
+ }
198
+
199
+ const lastRun = context.state.lastRuns[manifest.id];
200
+ rows.push({
201
+ id: manifest.id,
202
+ displayName: manifest.displayName,
203
+ category: manifest.category,
204
+ invocation: [...manifest.invocation],
205
+ enabled: context.state.enabled.includes(manifest.id),
206
+ license: {
207
+ spdxId: manifest.license.spdxId,
208
+ usageRestriction: manifest.license.usageRestriction,
209
+ gate,
210
+ },
211
+ pin:
212
+ manifest.container === undefined
213
+ ? null
214
+ : { image: manifest.container.image, digest: manifest.container.digest },
215
+ health,
216
+ missingSecrets,
217
+ manifestPath: extension.manifestPath,
218
+ origin: extension.origin,
219
+ ...(lastRun === undefined ? {} : { lastRun }),
220
+ });
221
+ }
222
+
223
+ if (format === "json") {
224
+ emitJson(io, {
225
+ command: "extensions status",
226
+ rootsScanned: context.discovery.rootsScanned,
227
+ projectRootsExcluded: environment.projectRoots,
228
+ extensions: rows,
229
+ rejected: context.discovery.rejected,
230
+ ignored: context.discovery.ignored,
231
+ warnings: context.warnings,
232
+ });
233
+ return EXIT.ok;
234
+ }
235
+
236
+ renderText(io, rows, context.discovery.rootsScanned, context.warnings);
237
+ return EXIT.ok;
238
+ }
239
+
240
+ function renderText(
241
+ io: Io,
242
+ rows: readonly StatusRowV1[],
243
+ rootsScanned: readonly { root: string; exists: boolean }[],
244
+ warnings: readonly string[],
245
+ ): void {
246
+ if (rows.length === 0) {
247
+ line(io, "no extensions installed.");
248
+ }
249
+ for (const row of rows) {
250
+ line(io, `${row.id} (${row.displayName})`);
251
+ for (const rendered of renderTable(
252
+ ["FIELD", "VALUE"],
253
+ [
254
+ ["enabled", row.enabled ? "yes" : "no"],
255
+ ["invocation", row.invocation.join(", ")],
256
+ ["available", row.health.available ? "yes" : "no"],
257
+ ["effective mode", row.health.effectiveInvocation ?? "—"],
258
+ ["tool version", row.health.toolVersion ?? "—"],
259
+ ["endpoint", row.health.endpoint ?? "—"],
260
+ ["binary", row.health.binaryPath ?? "—"],
261
+ ["license", `${row.license.spdxId} (${row.license.usageRestriction})`],
262
+ ["license gate", `${row.health.licenseGate} — ${row.license.gate.tool.reason}`],
263
+ ["pinned image", row.pin === null ? "— (not container-invoked)" : row.pin.image],
264
+ ["pinned digest", row.pin === null ? "—" : row.pin.digest],
265
+ ["running digest", describeRunningDigest(row)],
266
+ ["last run", describeLastRun(row.lastRun)],
267
+ [
268
+ "missing secrets",
269
+ row.missingSecrets.length === 0 ? "none" : row.missingSecrets.join(", "),
270
+ ],
271
+ ],
272
+ )) {
273
+ line(io, ` ${rendered}`);
274
+ }
275
+ for (const entry of row.license.gate.rulesets) {
276
+ line(io, ` ruleset ${entry.ruleset}: ${entry.status} — ${entry.reason}`);
277
+ }
278
+ for (const reason of row.health.unavailableReasons) {
279
+ line(io, ` unavailable via ${reason.invocation}: ${reason.detail}`);
280
+ }
281
+ for (const command of row.license.gate.acknowledgeCommands) {
282
+ line(io, ` to acknowledge: ${command}`);
283
+ }
284
+ line(io, ` manifest: ${row.manifestPath} (${row.origin})`);
285
+ line(io, "");
286
+ }
287
+
288
+ line(io, "roots searched (project directories are never searched):");
289
+ for (const root of rootsScanned) {
290
+ line(io, ` ${root.root}${root.exists ? "" : " (does not exist)"}`);
291
+ }
292
+ for (const warning of warnings) {
293
+ line(io, `warning: ${warning}`);
294
+ }
295
+ }
296
+
297
+ /**
298
+ * A digest that could not be read is said to be unreadable, with the reason.
299
+ * "—" alone would look like "no container", which is a different statement.
300
+ */
301
+ function describeRunningDigest(row: StatusRowV1): string {
302
+ if (row.pin === null) {
303
+ return "—";
304
+ }
305
+ if (row.health.imageDigest === undefined) {
306
+ return "unknown (nothing was started or pulled to find out)";
307
+ }
308
+ return `${row.health.imageDigest} (${row.health.digestMatchesManifest === true ? "matches the pin" : "DIFFERS from the pin"})`;
309
+ }
310
+
311
+ function describeLastRun(lastRun: LastRunRecordV1 | undefined): string {
312
+ if (lastRun === undefined) {
313
+ return "never run";
314
+ }
315
+ return (
316
+ `${lastRun.startedAt} ${lastRun.exitStatus}` +
317
+ `${lastRun.errorCode === undefined ? "" : ` (${lastRun.errorCode})`}` +
318
+ `, ${String(lastRun.findingsTotal)} findings`
319
+ );
320
+ }
@@ -0,0 +1,280 @@
1
+ /**
2
+ * `untangle extensions` — the analyzer-extension surface (WP-127).
3
+ *
4
+ * ## What this command group is, and what it deliberately is not
5
+ *
6
+ * Untangle ships the extension RUNTIME, the manifest schema and a small set
7
+ * of output-format parsers. It ships NO tool definitions. There is no list of
8
+ * known analyzers in this file, no branch that recognizes a vendor, no
9
+ * bundled manifest — Untangle understands output FORMATS (`sarif`,
10
+ * `junit-xml`, `generic-findings`, `generic-metrics`), and every
11
+ * tool-specific detail arrives as user data inside a manifest
12
+ * (extensions.md §17 "X9"; E2: no third-party product name in this source
13
+ * tree).
14
+ *
15
+ * That is not tidiness. It is what makes "optional" mean optional: if tool
16
+ * definitions shipped with the product, they would be part of the product
17
+ * even while switched off, and the license boundary that keeps AGPL code and
18
+ * source-available analyzers apart would run through this repository instead
19
+ * of around it.
20
+ *
21
+ * ## The security boundary you will notice first
22
+ *
23
+ * A manifest in the PROJECT directory is never loaded automatically. Only the
24
+ * user profile is searched (`~/.untangle/extensions/<id>/manifest.toml` and
25
+ * the OS data directory). A manifest is a description of how to start a
26
+ * program; if the working directory were a search path, `git clone` of a
27
+ * stranger's repository would be enough to place a program invocation in
28
+ * front of the runtime. `add --from <path inside a project>` therefore
29
+ * refuses unless the user types `--allow-project-local` in that very command.
30
+ */
31
+ import type { FlagSpecs, ParsedArgs } from "../cli/args.js";
32
+ import { enumFlag } from "../cli/args.js";
33
+ import type { Command, CommandContext } from "../cli/command.js";
34
+ import { EXIT, UsageError } from "../cli/exit.js";
35
+
36
+ import { runAdd } from "./extensions/add.js";
37
+ import { runConfigure } from "./extensions/configure.js";
38
+ import { runDisable, runEnable } from "./extensions/enable.js";
39
+ import { createExtensionEnvironment } from "./extensions/environment.js";
40
+ import { runList } from "./extensions/list.js";
41
+ import { runLogs } from "./extensions/logs.js";
42
+ import { runRemove } from "./extensions/remove.js";
43
+ import { runRun } from "./extensions/run.js";
44
+ import { runStatus } from "./extensions/status.js";
45
+
46
+ const FLAGS: FlagSpecs = {
47
+ from: {
48
+ kind: "string",
49
+ placeholder: "URL|PATH",
50
+ describe: "add: manifest source. configure: private JSON file containing secret values.",
51
+ },
52
+ digest: {
53
+ kind: "string",
54
+ placeholder: "sha256:HEX",
55
+ describe: "add: expected manifest sha256. Required for a URL.",
56
+ },
57
+ "allow-project-local": {
58
+ kind: "boolean",
59
+ describe: "add: explicitly allow a path inside the project directory.",
60
+ },
61
+ force: {
62
+ kind: "boolean",
63
+ describe: "add: replace an installed extension with the same ID.",
64
+ },
65
+ "acknowledge-license": {
66
+ kind: "boolean",
67
+ describe: "add/enable: acknowledge the tool-license gate, not the ruleset gate.",
68
+ },
69
+ "acknowledge-ruleset": {
70
+ kind: "list",
71
+ placeholder: "ID",
72
+ describe: "add/enable: acknowledge exactly one ruleset. Repeatable.",
73
+ },
74
+ "revoke-license": {
75
+ kind: "boolean",
76
+ describe: "disable/remove: revoke the stored license acknowledgment.",
77
+ },
78
+ category: {
79
+ kind: "string",
80
+ placeholder: "C,...",
81
+ describe: "list: show only extensions in these categories.",
82
+ },
83
+ "enabled-only": {
84
+ kind: "boolean",
85
+ describe: "list: show only enabled extensions.",
86
+ },
87
+ yes: {
88
+ kind: "boolean",
89
+ describe: "run/setup: allow container provisioning and missing-credential setup (X1).",
90
+ },
91
+ tail: {
92
+ kind: "number",
93
+ placeholder: "N",
94
+ describe: "logs: number of trailing lines.",
95
+ defaultLabel: "200",
96
+ },
97
+ "remove-container": {
98
+ kind: "boolean",
99
+ describe: "disable: stop and remove only the owned container, verified by its labels.",
100
+ },
101
+ "remove-volumes": {
102
+ kind: "boolean",
103
+ describe: "disable: also remove named volumes. Destructive.",
104
+ },
105
+ workspace: {
106
+ kind: "string",
107
+ placeholder: "PATH",
108
+ describe: "run: root of the analyzed workspace.",
109
+ defaultLabel: "current directory",
110
+ },
111
+ target: {
112
+ kind: "string",
113
+ placeholder: "PATH",
114
+ describe: "run: analysis target inside the workspace.",
115
+ defaultLabel: "the workspace",
116
+ },
117
+ ruleset: {
118
+ kind: "string",
119
+ placeholder: "NAME",
120
+ describe: "run: effective ruleset; otherwise the manifest's defaultRuleset applies.",
121
+ },
122
+ url: {
123
+ kind: "string",
124
+ placeholder: "URL",
125
+ describe: "run: endpoint for invocation kind `http`.",
126
+ },
127
+ timeout: {
128
+ kind: "number",
129
+ placeholder: "MS",
130
+ describe: "run: execution time budget in milliseconds.",
131
+ defaultLabel: "900000",
132
+ },
133
+ "max-output-bytes": {
134
+ kind: "number",
135
+ placeholder: "N",
136
+ describe: "run: maximum collected tool-output bytes.",
137
+ },
138
+ format: {
139
+ kind: "string",
140
+ placeholder: "text|json",
141
+ describe: "Output format.",
142
+ defaultLabel: "text",
143
+ },
144
+ };
145
+
146
+ /**
147
+ * Which flags each subcommand accepts.
148
+ *
149
+ * The parser validates flags against the union above; this table catches the
150
+ * rest. Without it, `untangle extensions list --from=x` would be silently
151
+ * accepted and silently ignored — precisely the kind of quiet skip E4
152
+ * forbids, one layer above the pipeline.
153
+ */
154
+ const ALLOWED_FLAGS: Readonly<Record<string, readonly string[]>> = {
155
+ add: [
156
+ "from",
157
+ "digest",
158
+ "allow-project-local",
159
+ "force",
160
+ "acknowledge-license",
161
+ "acknowledge-ruleset",
162
+ "format",
163
+ ],
164
+ list: ["category", "enabled-only", "format"],
165
+ status: ["format"],
166
+ configure: ["from", "format"],
167
+ setup: ["workspace", "url", "timeout", "max-output-bytes", "yes", "format"],
168
+ logs: ["tail", "format"],
169
+ enable: ["acknowledge-license", "acknowledge-ruleset", "format"],
170
+ disable: ["revoke-license", "remove-container", "remove-volumes", "format"],
171
+ remove: ["revoke-license", "format"],
172
+ run: ["workspace", "target", "ruleset", "url", "timeout", "max-output-bytes", "yes", "format"],
173
+ };
174
+
175
+ const SUBCOMMANDS = Object.keys(ALLOWED_FLAGS);
176
+
177
+ export const extensionsCommand: Command = {
178
+ spec: {
179
+ name: "extensions",
180
+ implementedBy: "commands/extensions.js",
181
+ summary: "Manage and run analyzer extensions",
182
+ usage:
183
+ "untangle extensions <add|list|status|configure|setup|enable|disable|remove|run|logs> [options]",
184
+ details: [
185
+ "Untangle supplies the extension runtime, manifest schema and format parsers, without bundled tool definitions. A manifest is an external artifact you explicitly load (extensions.md §17, X9). The runtime understands formats (sarif, junit-xml, generic-findings, generic-metrics), not individual tools.",
186
+ "Trust boundary: manifests in the project directory are never loaded automatically. Discovery searches only the user profile (~/.untangle/extensions/<id>/manifest.toml and the OS data directory). A manifest specifies how to launch a program; trusting a cloned project's manifest automatically would allow unrequested execution. `add --from` therefore rejects project-local paths unless --allow-project-local is explicit.",
187
+ "Likewise, `add --from <https-URL>` requires --digest: changing content behind a stable URL could silently change findings. X6 forbids mutable container tags for the same reason.",
188
+ "Installing a manifest starts nothing. `enable` records activation without launching processes or containers (X1). Restrictively licensed tools require explicit personal acknowledgment (X5).",
189
+ "`status` previews the effective pinned image digest, running digest and comparison, license and ruleset gates, endpoint and last run. It neither starts containers nor pulls images (X1); an open gate also prevents version probes (X5).",
190
+ "setup --yes provisions the service, configures missing credentials through the manifest's declared setup process and verifies them with an analysis run. configure creates private secret configuration or imports values with --from. Environment variables take precedence; status creates no tokens.",
191
+ "External tool findings are `ExternalFindingV1`: evidence, never Untangle metrics. They never contribute to complexity values or Risk Score (X3), and never change the exit code.",
192
+ ],
193
+ flags: FLAGS,
194
+ examples: [
195
+ "untangle extensions add --from=./my-analyzer/manifest.toml",
196
+ "untangle extensions add --from=https://example.invalid/manifest.toml --digest=sha256:<64 hex>",
197
+ "untangle extensions list --format=json",
198
+ "untangle extensions status my-analyzer",
199
+ "untangle extensions configure my-analyzer",
200
+ "untangle extensions setup my-analyzer --yes",
201
+ "untangle extensions enable my-analyzer --acknowledge-license",
202
+ "untangle extensions run my-analyzer --target=src --format=json",
203
+ "untangle extensions remove my-analyzer --revoke-license",
204
+ ],
205
+ exitCodes: [
206
+ [EXIT.ok, "The command completed. Findings do not change this code (X3)."],
207
+ [EXIT.operational, "Invalid manifest, missing extension or failed run."],
208
+ [EXIT.usage, "Usage error: unknown subcommand, missing or unsupported option."],
209
+ [
210
+ EXIT.environment,
211
+ "License/ruleset gate is open, or a required secret is missing. Nothing was started.",
212
+ ],
213
+ ],
214
+ },
215
+
216
+ async run(ctx: CommandContext, args: ParsedArgs): Promise<number> {
217
+ const subcommand = args.positionals[0];
218
+ if (subcommand === undefined) {
219
+ throw new UsageError(
220
+ "`untangle extensions` needs a subcommand.",
221
+ `Choose one of: ${SUBCOMMANDS.join(", ")} — see untangle extensions --help.`,
222
+ );
223
+ }
224
+ const allowed = ALLOWED_FLAGS[subcommand];
225
+ if (allowed === undefined) {
226
+ throw new UsageError(
227
+ `Unknown subcommand "extensions ${subcommand}".`,
228
+ `Choose one of: ${SUBCOMMANDS.join(", ")}.`,
229
+ );
230
+ }
231
+ rejectForeignFlags(subcommand, args, allowed);
232
+
233
+ const format = enumFlag(args, "format", ["text", "json"] as const, "text");
234
+ const environment = await createExtensionEnvironment({ cwd: ctx.cwd, env: ctx.env });
235
+
236
+ switch (subcommand) {
237
+ case "add":
238
+ return await runAdd(environment, args, ctx.io, format);
239
+ case "list":
240
+ return await runList(environment, args, ctx.io, format);
241
+ case "status":
242
+ return await runStatus(environment, args, ctx.io, format);
243
+ case "logs":
244
+ return await runLogs(environment, args, ctx.io, format);
245
+ case "enable":
246
+ return await runEnable(environment, args, ctx.io, format);
247
+ case "disable":
248
+ return await runDisable(environment, args, ctx.io, format);
249
+ case "remove":
250
+ return await runRemove(environment, args, ctx.io, format);
251
+ case "configure":
252
+ return await runConfigure(environment, args, ctx.io, format);
253
+ case "setup":
254
+ case "run":
255
+ return await runRun(environment, args, ctx.io, format, { signal: ctx.signal });
256
+ default:
257
+ throw new UsageError(
258
+ `Unknown subcommand "extensions ${subcommand}".`,
259
+ `Choose one of: ${SUBCOMMANDS.join(", ")}.`,
260
+ );
261
+ }
262
+ },
263
+ };
264
+
265
+ function rejectForeignFlags(
266
+ subcommand: string,
267
+ args: ParsedArgs,
268
+ allowed: readonly string[],
269
+ ): void {
270
+ const foreign = Object.keys(args.flags)
271
+ .filter((name) => !allowed.includes(name))
272
+ .sort();
273
+ if (foreign.length === 0) {
274
+ return;
275
+ }
276
+ throw new UsageError(
277
+ `"extensions ${subcommand}" does not accept ${foreign.map((name) => `--${name}`).join(", ")}.`,
278
+ `Accepted here: ${allowed.map((name) => `--${name}`).join(", ")}.`,
279
+ );
280
+ }