@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,156 @@
1
+ import { lstatSync, readlinkSync, realpathSync, type Stats } from "node:fs";
2
+ import path from "node:path";
3
+
4
+ export class PathOutsideWorkspaceError extends Error {
5
+ readonly requestedPath: string;
6
+ readonly workspaceRoots: readonly string[];
7
+
8
+ constructor(requestedPath: string, workspaceRoots: readonly string[]) {
9
+ super(`Path "${requestedPath}" resolves outside every allowed workspace root.`);
10
+ this.name = "PathOutsideWorkspaceError";
11
+ this.requestedPath = requestedPath;
12
+ this.workspaceRoots = workspaceRoots;
13
+ }
14
+ }
15
+
16
+ /** A path could not be canonicalized safely (cycle, invalid bytes, I/O). */
17
+ export class InvalidWorkspacePathError extends Error {
18
+ readonly requestedPath: string;
19
+
20
+ constructor(requestedPath: string, cause: unknown) {
21
+ super(
22
+ `Path "${requestedPath}" cannot be canonicalized safely: ${cause instanceof Error ? cause.message : String(cause)}`,
23
+ { cause },
24
+ );
25
+ this.name = "InvalidWorkspacePathError";
26
+ this.requestedPath = requestedPath;
27
+ }
28
+ }
29
+
30
+ /**
31
+ * Canonicalizes an existing path, or the nearest existing ancestor plus the
32
+ * unresolved suffix. The latter closes the common `out/new-file` case while
33
+ * still resolving every symlink that already exists on the route.
34
+ */
35
+ export function canonicalPotentialPath(input: string): string {
36
+ try {
37
+ return canonicalPotentialPathFrom(input, new Set<string>());
38
+ } catch (error) {
39
+ if (error instanceof InvalidWorkspacePathError) throw error;
40
+ throw new InvalidWorkspacePathError(input, error);
41
+ }
42
+ }
43
+
44
+ function canonicalPotentialPathFrom(input: string, visitedLinks: Set<string>): string {
45
+ let cursor = path.resolve(input);
46
+ const suffix: string[] = [];
47
+ for (;;) {
48
+ const stat = lstatOrNull(cursor);
49
+ if (stat !== null) {
50
+ if (stat.isSymbolicLink()) {
51
+ if (visitedLinks.has(cursor)) {
52
+ throw new InvalidWorkspacePathError(
53
+ input,
54
+ new Error(`Symbolic-link cycle encountered at "${cursor}".`),
55
+ );
56
+ }
57
+ visitedLinks.add(cursor);
58
+ const target = path.resolve(path.dirname(cursor), readlinkSync(cursor));
59
+ return canonicalPotentialPathFrom(path.resolve(target, ...suffix), visitedLinks);
60
+ }
61
+ return path.resolve(realpathSync(cursor), ...suffix);
62
+ }
63
+ const parent = path.dirname(cursor);
64
+ if (parent === cursor) break;
65
+ suffix.unshift(path.basename(cursor));
66
+ cursor = parent;
67
+ }
68
+ return path.resolve(cursor, ...suffix);
69
+ }
70
+
71
+ function lstatOrNull(candidate: string): Stats | null {
72
+ try {
73
+ return lstatSync(candidate);
74
+ } catch (error) {
75
+ if (
76
+ typeof error === "object" &&
77
+ error !== null &&
78
+ "code" in error &&
79
+ (error.code === "ENOENT" || error.code === "ENOTDIR")
80
+ ) {
81
+ return null;
82
+ }
83
+ throw error;
84
+ }
85
+ }
86
+
87
+ function isWithin(root: string, candidate: string): boolean {
88
+ const relative = path.relative(root, candidate);
89
+ return (
90
+ relative === "" ||
91
+ (!relative.startsWith(`..${path.sep}`) && relative !== ".." && !path.isAbsolute(relative))
92
+ );
93
+ }
94
+
95
+ export function assertPathInsideWorkspace(
96
+ requestedPath: string,
97
+ options: { cwd: string; workspaceRoots: readonly string[] },
98
+ ): string {
99
+ let candidate: string;
100
+ try {
101
+ candidate = canonicalPotentialPath(path.resolve(options.cwd, requestedPath));
102
+ } catch (error) {
103
+ if (error instanceof InvalidWorkspacePathError) {
104
+ throw new InvalidWorkspacePathError(requestedPath, error.cause ?? error);
105
+ }
106
+ throw error;
107
+ }
108
+ const roots = options.workspaceRoots.map(canonicalPotentialPath);
109
+ if (!roots.some((root) => isWithin(root, candidate))) {
110
+ throw new PathOutsideWorkspaceError(requestedPath, roots);
111
+ }
112
+ return candidate;
113
+ }
114
+
115
+ export function assertToolPathsInsideWorkspace(
116
+ input: Readonly<Record<string, unknown>>,
117
+ pathFields: readonly string[],
118
+ options: { cwd: string; workspaceRoots: readonly string[] },
119
+ ): void {
120
+ canonicalizeToolPathsInsideWorkspace(input, pathFields, options);
121
+ }
122
+
123
+ /**
124
+ * Prueft alle deklarierten Pfade und ersetzt sie fuer den nachfolgenden
125
+ * Runtime-Aufruf durch ihre kanonischen absoluten Ziele. So kann ein bereits
126
+ * aufgeloester Symlink nach der Pruefung nicht allein dadurch wieder wirksam
127
+ * werden, dass die Runtime denselben rohen Linkpfad erneut interpretiert.
128
+ */
129
+ export function canonicalizeToolPathsInsideWorkspace(
130
+ input: Readonly<Record<string, unknown>>,
131
+ pathFields: readonly string[],
132
+ options: { cwd: string; workspaceRoots: readonly string[] },
133
+ ): Record<string, unknown> {
134
+ const canonicalInput: Record<string, unknown> = { ...input };
135
+ const rootValue = input["root"];
136
+ const toolCwd =
137
+ typeof rootValue === "string" ? assertPathInsideWorkspace(rootValue, options) : options.cwd;
138
+ if (typeof rootValue === "string") canonicalInput["root"] = toolCwd;
139
+
140
+ for (const field of pathFields) {
141
+ if (field === "root") continue;
142
+ const value = input[field];
143
+ if (typeof value === "string") {
144
+ canonicalInput[field] = assertPathInsideWorkspace(value, { ...options, cwd: toolCwd });
145
+ continue;
146
+ }
147
+ if (Array.isArray(value)) {
148
+ canonicalInput[field] = value.map((entry) =>
149
+ typeof entry === "string"
150
+ ? assertPathInsideWorkspace(entry, { ...options, cwd: toolCwd })
151
+ : entry,
152
+ );
153
+ }
154
+ }
155
+ return canonicalInput;
156
+ }
@@ -0,0 +1,358 @@
1
+ import { McpServer, type CallToolResult } from "@modelcontextprotocol/server";
2
+ import * as z from "zod/v4";
3
+
4
+ import { CLI_VERSION } from "../cli/version.js";
5
+
6
+ import { DefaultUntangleMcpRuntime } from "./default-runtime.js";
7
+ import { mcpFailure } from "./envelope.js";
8
+ import {
9
+ canonicalPotentialPath,
10
+ canonicalizeToolPathsInsideWorkspace,
11
+ InvalidWorkspacePathError,
12
+ PathOutsideWorkspaceError,
13
+ } from "./path-sandbox.js";
14
+ import { UNTANGLE_MCP_TOOLS, type McpToolDefinition } from "./tools.js";
15
+ import {
16
+ UNTANGLE_MCP_TOOL_NAMES,
17
+ type UntangleMcpRuntime,
18
+ type UntangleMcpToolName,
19
+ } from "./types.js";
20
+
21
+ const warningSchema = z
22
+ .object({
23
+ code: z.string(),
24
+ message: z.string(),
25
+ details: z.record(z.string(), z.json()).optional(),
26
+ })
27
+ .strict();
28
+
29
+ const toolErrorSchema = z
30
+ .object({
31
+ code: z.string(),
32
+ message: z.string(),
33
+ retryable: z.boolean(),
34
+ details: z.record(z.string(), z.json()).optional(),
35
+ })
36
+ .strict();
37
+
38
+ const indexStateSchema = z
39
+ .object({
40
+ generationId: z.string(),
41
+ status: z.string(),
42
+ stale: z.boolean(),
43
+ })
44
+ .strict();
45
+
46
+ const toolNameSchema = z.enum(UNTANGLE_MCP_TOOL_NAMES);
47
+ const successDataSchemas = new Map(
48
+ UNTANGLE_MCP_TOOLS.map((definition) => [definition.name, definition.successDataSchema] as const),
49
+ );
50
+
51
+ const knownSuccessEnvelopeSchema = z
52
+ .object({
53
+ schemaVersion: z.literal(1),
54
+ ok: z.literal(true),
55
+ operation: toolNameSchema,
56
+ workspaceId: z.string().optional(),
57
+ data: z.unknown(),
58
+ warnings: z.array(warningSchema),
59
+ indexState: indexStateSchema.optional(),
60
+ })
61
+ .strict()
62
+ .superRefine((envelope, context) => {
63
+ const schema = successDataSchemas.get(envelope.operation);
64
+ const parsed = schema?.safeParse(envelope.data);
65
+ if (parsed?.success === true) return;
66
+ context.addIssue({
67
+ code: "custom",
68
+ path: ["data"],
69
+ message: `Data does not match the success contract for ${envelope.operation}.`,
70
+ });
71
+ });
72
+
73
+ /** The wire contract from spec.md section 21.2. */
74
+ export const toolResponseEnvelopeSchema = z.discriminatedUnion("ok", [
75
+ knownSuccessEnvelopeSchema,
76
+ z
77
+ .object({
78
+ schemaVersion: z.literal(1),
79
+ ok: z.literal(false),
80
+ operation: toolNameSchema,
81
+ workspaceId: z.string().optional(),
82
+ warnings: z.array(warningSchema),
83
+ error: toolErrorSchema,
84
+ indexState: indexStateSchema.optional(),
85
+ })
86
+ .strict(),
87
+ ]);
88
+
89
+ export interface CreateUntangleMcpServerOptions {
90
+ readonly cwd?: string;
91
+ readonly env?: Readonly<Record<string, string | undefined>>;
92
+ readonly runtime?: UntangleMcpRuntime;
93
+ /** Canonical containment roots. An omitted/empty list is restricted to cwd. */
94
+ readonly workspaceRoots?: readonly string[];
95
+ }
96
+
97
+ /**
98
+ * Creates one transport-neutral server instance. The public CLI package owns
99
+ * this runtime so programmatic and binary consumers cannot drift apart.
100
+ */
101
+ export function createUntangleMcpServer(options: CreateUntangleMcpServerOptions = {}): McpServer {
102
+ const cwd = options.cwd ?? process.cwd();
103
+ const env = options.env ?? process.env;
104
+ const runtime = options.runtime ?? new DefaultUntangleMcpRuntime();
105
+ const configuredRoots = options.workspaceRoots ?? [];
106
+ const workspaceRoots = uniqueCanonicalRoots(
107
+ configuredRoots.length === 0 ? [cwd] : configuredRoots,
108
+ );
109
+ const server = new McpServer(
110
+ { name: "untangle", version: CLI_VERSION },
111
+ { capabilities: { tools: {} } },
112
+ );
113
+
114
+ for (const definition of UNTANGLE_MCP_TOOLS) {
115
+ const outputSchema = outputEnvelopeSchema(definition);
116
+ server.registerTool(
117
+ definition.name,
118
+ {
119
+ description: definition.description,
120
+ // The SDK normally turns validation failures into a text-only tool
121
+ // error before our handler runs. Advertise the exact schema, but let
122
+ // this boundary validate manually so EVERY tool result still carries
123
+ // the normative §21.2 envelope.
124
+ inputSchema: advertiseSchemaWithoutPrevalidation(definition.inputSchema),
125
+ outputSchema,
126
+ },
127
+ async (input, requestContext): Promise<CallToolResult> => {
128
+ return executeMcpToolInvocation(definition, input, {
129
+ cwd,
130
+ env,
131
+ runtime,
132
+ workspaceRoots,
133
+ signal: requestContext.mcpReq.signal,
134
+ });
135
+ },
136
+ );
137
+ }
138
+
139
+ return server;
140
+ }
141
+
142
+ interface ExecuteMcpToolInvocationOptions {
143
+ readonly cwd: string;
144
+ readonly env: Readonly<Record<string, string | undefined>>;
145
+ readonly runtime: UntangleMcpRuntime;
146
+ readonly workspaceRoots: readonly string[];
147
+ readonly signal: AbortSignal;
148
+ }
149
+
150
+ /**
151
+ * One testable invocation boundary. Keeping cancellation here means an
152
+ * already-aborted request never reaches a storage adapter or mutating use case.
153
+ */
154
+ export async function executeMcpToolInvocation(
155
+ definition: McpToolDefinition,
156
+ input: unknown,
157
+ options: ExecuteMcpToolInvocationOptions,
158
+ ): Promise<CallToolResult> {
159
+ let envelope;
160
+ try {
161
+ if (options.signal.aborted) {
162
+ envelope = mcpFailure(
163
+ definition.name,
164
+ "CANCELLED",
165
+ "The MCP operation was cancelled.",
166
+ false,
167
+ );
168
+ return toCallToolResult(definition, envelope);
169
+ }
170
+ const parsed = definition.inputSchema.safeParse(input);
171
+ if (!parsed.success) {
172
+ envelope = mcpFailure(
173
+ definition.name,
174
+ "INVALID_ARGUMENT",
175
+ `Invalid arguments for MCP tool "${definition.name}".`,
176
+ false,
177
+ { details: { issues: publicZodIssues(parsed.error) } },
178
+ );
179
+ return toCallToolResult(definition, envelope);
180
+ }
181
+ const canonicalInput = canonicalizeToolPathsInsideWorkspace(
182
+ parsed.data,
183
+ definition.pathFields,
184
+ {
185
+ cwd: options.cwd,
186
+ workspaceRoots: options.workspaceRoots,
187
+ },
188
+ );
189
+ if (options.signal.aborted) {
190
+ envelope = mcpFailure(
191
+ definition.name,
192
+ "CANCELLED",
193
+ "The MCP operation was cancelled.",
194
+ false,
195
+ );
196
+ return toCallToolResult(definition, envelope);
197
+ }
198
+ envelope = await options.runtime.invoke(definition.name, canonicalInput, {
199
+ cwd: options.cwd,
200
+ env: options.env,
201
+ signal: options.signal,
202
+ });
203
+ if (options.signal.aborted) {
204
+ envelope = mcpFailure(
205
+ definition.name,
206
+ "CANCELLED",
207
+ "The MCP operation was cancelled.",
208
+ false,
209
+ );
210
+ }
211
+ } catch (error) {
212
+ envelope = options.signal.aborted
213
+ ? mcpFailure(definition.name, "CANCELLED", "The MCP operation was cancelled.", false)
214
+ : serverFailure(definition.name, error);
215
+ }
216
+ return toCallToolResult(definition, envelope);
217
+ }
218
+
219
+ /**
220
+ * Keeps the advertised JSON Schema byte-for-byte equivalent to the Zod
221
+ * schema while deferring validation to our envelope-producing handler.
222
+ */
223
+ function advertiseSchemaWithoutPrevalidation(
224
+ schema: z.ZodType<Record<string, unknown>>,
225
+ ): z.ZodType<Record<string, unknown>> {
226
+ const standard = schema["~standard"];
227
+ return {
228
+ "~standard": {
229
+ ...standard,
230
+ validate: (value: unknown) => ({ value }),
231
+ },
232
+ } as unknown as z.ZodType<Record<string, unknown>>;
233
+ }
234
+
235
+ function outputEnvelopeSchema(definition: McpToolDefinition) {
236
+ return z.discriminatedUnion("ok", [
237
+ z
238
+ .object({
239
+ schemaVersion: z.literal(1),
240
+ ok: z.literal(true),
241
+ operation: z.literal(definition.name),
242
+ workspaceId: z.string().optional(),
243
+ data: definition.successDataSchema,
244
+ warnings: z.array(warningSchema),
245
+ indexState: indexStateSchema.optional(),
246
+ })
247
+ .strict(),
248
+ z
249
+ .object({
250
+ schemaVersion: z.literal(1),
251
+ ok: z.literal(false),
252
+ operation: z.literal(definition.name),
253
+ workspaceId: z.string().optional(),
254
+ warnings: z.array(warningSchema),
255
+ error: toolErrorSchema,
256
+ indexState: indexStateSchema.optional(),
257
+ })
258
+ .strict(),
259
+ ]);
260
+ }
261
+
262
+ function publicZodIssues(error: z.ZodError): Array<{
263
+ code: string;
264
+ path: string;
265
+ message: string;
266
+ }> {
267
+ return error.issues.slice(0, 32).map((issue) => ({
268
+ code: issue.code,
269
+ path: issue.path.map(String).join("."),
270
+ message: issue.message,
271
+ }));
272
+ }
273
+
274
+ function toCallToolResult(definition: McpToolDefinition, value: unknown): CallToolResult {
275
+ const operation = definition.name;
276
+ let envelope;
277
+ try {
278
+ const parsed = toolResponseEnvelopeSchema.safeParse(value);
279
+ if (!parsed.success || parsed.data.operation !== operation) {
280
+ envelope = invalidRuntimeEnvelope(
281
+ operation,
282
+ parsed.success ? "operation mismatch" : "schema mismatch",
283
+ );
284
+ } else if (parsed.data.ok) {
285
+ const data = definition.successDataSchema.safeParse(parsed.data.data);
286
+ envelope = data.success
287
+ ? { ...parsed.data, data: data.data }
288
+ : invalidRuntimeEnvelope(operation, "success data schema mismatch");
289
+ } else {
290
+ envelope = parsed.data;
291
+ }
292
+ const structuredContent = jsonObject(envelope);
293
+ return {
294
+ content: [{ type: "text", text: JSON.stringify(structuredContent) }],
295
+ structuredContent,
296
+ isError: !envelope.ok,
297
+ };
298
+ } catch {
299
+ envelope = invalidRuntimeEnvelope(operation, "response was not JSON serializable");
300
+ const structuredContent = jsonObject(envelope);
301
+ return {
302
+ content: [{ type: "text", text: JSON.stringify(structuredContent) }],
303
+ structuredContent,
304
+ isError: true,
305
+ };
306
+ }
307
+ }
308
+
309
+ function invalidRuntimeEnvelope(
310
+ operation: UntangleMcpToolName,
311
+ reason: string,
312
+ ): ReturnType<typeof mcpFailure> {
313
+ return mcpFailure(
314
+ operation,
315
+ "INVALID_INTERNAL_OUTPUT",
316
+ `The MCP runtime returned an invalid response envelope (${reason}).`,
317
+ false,
318
+ );
319
+ }
320
+
321
+ function serverFailure(operation: UntangleMcpToolName, error: unknown) {
322
+ if (error instanceof PathOutsideWorkspaceError) {
323
+ return mcpFailure(operation, "PATH_OUTSIDE_WORKSPACE", error.message, false, {
324
+ details: { requestedPath: error.requestedPath },
325
+ });
326
+ }
327
+ if (error instanceof InvalidWorkspacePathError) {
328
+ return mcpFailure(operation, "INVALID_ARGUMENT", error.message, false, {
329
+ details: { requestedPath: error.requestedPath },
330
+ });
331
+ }
332
+ if (error instanceof Error && error.name === "AbortError") {
333
+ return mcpFailure(operation, "CANCELLED", "The MCP operation was cancelled.", false);
334
+ }
335
+ return mcpFailure(
336
+ operation,
337
+ "INTERNAL_ERROR",
338
+ error instanceof Error ? error.message : String(error),
339
+ false,
340
+ );
341
+ }
342
+
343
+ function uniqueCanonicalRoots(roots: readonly string[]): string[] {
344
+ return [...new Set(roots.map(canonicalPotentialPath))];
345
+ }
346
+
347
+ /** Makes the JSON boundary explicit and rejects accidental non-JSON values. */
348
+ function jsonObject(value: unknown): Record<string, unknown> {
349
+ const serialized = JSON.stringify(value);
350
+ if (serialized === undefined) {
351
+ throw new TypeError("The MCP response is not JSON serializable.");
352
+ }
353
+ const parsed: unknown = JSON.parse(serialized);
354
+ if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
355
+ throw new TypeError("The MCP response envelope must be a JSON object.");
356
+ }
357
+ return parsed as Record<string, unknown>;
358
+ }
@@ -0,0 +1,92 @@
1
+ import {
2
+ serveStdio,
3
+ StdioServerTransport,
4
+ type StdioServerHandle,
5
+ } from "@modelcontextprotocol/server/stdio";
6
+
7
+ import { createUntangleMcpServer, type CreateUntangleMcpServerOptions } from "./server.js";
8
+
9
+ export interface ServeUntangleMcpStdioOptions extends CreateUntangleMcpServerOptions {
10
+ readonly onerror?: (error: Error) => void;
11
+ /** Injection seam for lifecycle tests and non-process stdio bindings. */
12
+ readonly transport?: StdioServerTransport;
13
+ }
14
+
15
+ export type UntangleStdioCloseOutcome =
16
+ { readonly reason: "closed" } | { readonly reason: "error"; readonly error: Error };
17
+
18
+ export interface UntangleStdioServerHandle extends StdioServerHandle {
19
+ /** Settles when the owned wire transport actually closes. */
20
+ readonly closed: Promise<UntangleStdioCloseOutcome>;
21
+ }
22
+
23
+ /** Starts the dual-era MCP stdio binding. stdout remains JSON-RPC only. */
24
+ export function serveUntangleMcpStdio(
25
+ options: ServeUntangleMcpStdioOptions = {},
26
+ ): UntangleStdioServerHandle {
27
+ const transport = options.transport ?? new StdioServerTransport();
28
+ let pendingTransportError: Error | undefined;
29
+ let closingFromHandle = false;
30
+ let settleClosed!: (outcome: UntangleStdioCloseOutcome) => void;
31
+ let didSettle = false;
32
+ const closed = new Promise<UntangleStdioCloseOutcome>((resolve) => {
33
+ settleClosed = (outcome) => {
34
+ if (didSettle) return;
35
+ didSettle = true;
36
+ resolve(outcome);
37
+ };
38
+ });
39
+
40
+ // The upstream handle exposes close(), but not the wire's close event. A
41
+ // fatal buffer/stdout failure calls transport.close() while stdin may stay
42
+ // open; intercepting that actual close gives the CLI a lifecycle signal.
43
+ // Recoverable protocol errors only call onerror and therefore do not end
44
+ // this promise.
45
+ const closeTransport = transport.close.bind(transport);
46
+ const startTransport = transport.start.bind(transport);
47
+ transport.start = async (): Promise<void> => {
48
+ try {
49
+ await startTransport();
50
+ } catch (error) {
51
+ settleClosed({
52
+ reason: "error",
53
+ error: error instanceof Error ? error : new Error(String(error)),
54
+ });
55
+ throw error;
56
+ }
57
+ };
58
+ transport.close = async (): Promise<void> => {
59
+ const fatalError = closingFromHandle ? undefined : pendingTransportError;
60
+ try {
61
+ await closeTransport();
62
+ } finally {
63
+ settleClosed(
64
+ fatalError === undefined ? { reason: "closed" } : { reason: "error", error: fatalError },
65
+ );
66
+ }
67
+ };
68
+
69
+ const handle = serveStdio(() => createUntangleMcpServer(options), {
70
+ legacy: "serve",
71
+ transport,
72
+ onerror: (error) => {
73
+ pendingTransportError = error;
74
+ queueMicrotask(() => {
75
+ if (pendingTransportError === error) pendingTransportError = undefined;
76
+ });
77
+ options.onerror?.(error);
78
+ },
79
+ });
80
+
81
+ return {
82
+ closed,
83
+ async close(): Promise<void> {
84
+ closingFromHandle = true;
85
+ try {
86
+ await handle.close();
87
+ } finally {
88
+ settleClosed({ reason: "closed" });
89
+ }
90
+ },
91
+ };
92
+ }