opensip-cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +8 -0
  3. package/README.md +51 -0
  4. package/dist/api.d.ts +17 -0
  5. package/dist/api.d.ts.map +1 -0
  6. package/dist/api.js +16 -0
  7. package/dist/api.js.map +1 -0
  8. package/dist/bootstrap/admit-tool-package.d.ts +117 -0
  9. package/dist/bootstrap/admit-tool-package.d.ts.map +1 -0
  10. package/dist/bootstrap/admit-tool-package.js +170 -0
  11. package/dist/bootstrap/admit-tool-package.js.map +1 -0
  12. package/dist/bootstrap/baseline-seams.d.ts +30 -0
  13. package/dist/bootstrap/baseline-seams.d.ts.map +1 -0
  14. package/dist/bootstrap/baseline-seams.js +156 -0
  15. package/dist/bootstrap/baseline-seams.js.map +1 -0
  16. package/dist/bootstrap/bootstrap-error.d.ts +41 -0
  17. package/dist/bootstrap/bootstrap-error.d.ts.map +1 -0
  18. package/dist/bootstrap/bootstrap-error.js +33 -0
  19. package/dist/bootstrap/bootstrap-error.js.map +1 -0
  20. package/dist/bootstrap/build-command-registration-input.d.ts +34 -0
  21. package/dist/bootstrap/build-command-registration-input.d.ts.map +1 -0
  22. package/dist/bootstrap/build-command-registration-input.js +73 -0
  23. package/dist/bootstrap/build-command-registration-input.js.map +1 -0
  24. package/dist/bootstrap/build-per-run-scope.d.ts +62 -0
  25. package/dist/bootstrap/build-per-run-scope.d.ts.map +1 -0
  26. package/dist/bootstrap/build-per-run-scope.js +152 -0
  27. package/dist/bootstrap/build-per-run-scope.js.map +1 -0
  28. package/dist/bootstrap/build-targets.d.ts +42 -0
  29. package/dist/bootstrap/build-targets.d.ts.map +1 -0
  30. package/dist/bootstrap/build-targets.js +117 -0
  31. package/dist/bootstrap/build-targets.js.map +1 -0
  32. package/dist/bootstrap/cli-defaults.d.ts +35 -0
  33. package/dist/bootstrap/cli-defaults.d.ts.map +1 -0
  34. package/dist/bootstrap/cli-defaults.js +65 -0
  35. package/dist/bootstrap/cli-defaults.js.map +1 -0
  36. package/dist/bootstrap/config-and-capabilities.d.ts +74 -0
  37. package/dist/bootstrap/config-and-capabilities.d.ts.map +1 -0
  38. package/dist/bootstrap/config-and-capabilities.js +224 -0
  39. package/dist/bootstrap/config-and-capabilities.js.map +1 -0
  40. package/dist/bootstrap/deliver-envelope.d.ts +80 -0
  41. package/dist/bootstrap/deliver-envelope.d.ts.map +1 -0
  42. package/dist/bootstrap/deliver-envelope.js +195 -0
  43. package/dist/bootstrap/deliver-envelope.js.map +1 -0
  44. package/dist/bootstrap/egress-plane.d.ts +22 -0
  45. package/dist/bootstrap/egress-plane.d.ts.map +1 -0
  46. package/dist/bootstrap/egress-plane.js +37 -0
  47. package/dist/bootstrap/egress-plane.js.map +1 -0
  48. package/dist/bootstrap/host-planes.d.ts +28 -0
  49. package/dist/bootstrap/host-planes.d.ts.map +1 -0
  50. package/dist/bootstrap/host-planes.js +152 -0
  51. package/dist/bootstrap/host-planes.js.map +1 -0
  52. package/dist/bootstrap/index.d.ts +76 -0
  53. package/dist/bootstrap/index.d.ts.map +1 -0
  54. package/dist/bootstrap/index.js +109 -0
  55. package/dist/bootstrap/index.js.map +1 -0
  56. package/dist/bootstrap/live-plane.d.ts +51 -0
  57. package/dist/bootstrap/live-plane.d.ts.map +1 -0
  58. package/dist/bootstrap/live-plane.js +72 -0
  59. package/dist/bootstrap/live-plane.js.map +1 -0
  60. package/dist/bootstrap/load-tool-capabilities.d.ts +42 -0
  61. package/dist/bootstrap/load-tool-capabilities.d.ts.map +1 -0
  62. package/dist/bootstrap/load-tool-capabilities.js +76 -0
  63. package/dist/bootstrap/load-tool-capabilities.js.map +1 -0
  64. package/dist/bootstrap/output-plane.d.ts +37 -0
  65. package/dist/bootstrap/output-plane.d.ts.map +1 -0
  66. package/dist/bootstrap/output-plane.js +114 -0
  67. package/dist/bootstrap/output-plane.js.map +1 -0
  68. package/dist/bootstrap/owning-tool-init.d.ts +32 -0
  69. package/dist/bootstrap/owning-tool-init.d.ts.map +1 -0
  70. package/dist/bootstrap/owning-tool-init.js +69 -0
  71. package/dist/bootstrap/owning-tool-init.js.map +1 -0
  72. package/dist/bootstrap/pre-action-guards.d.ts +44 -0
  73. package/dist/bootstrap/pre-action-guards.d.ts.map +1 -0
  74. package/dist/bootstrap/pre-action-guards.js +136 -0
  75. package/dist/bootstrap/pre-action-guards.js.map +1 -0
  76. package/dist/bootstrap/pre-action-hook.d.ts +68 -0
  77. package/dist/bootstrap/pre-action-hook.d.ts.map +1 -0
  78. package/dist/bootstrap/pre-action-hook.js +289 -0
  79. package/dist/bootstrap/pre-action-hook.js.map +1 -0
  80. package/dist/bootstrap/pre-action-messages.d.ts +32 -0
  81. package/dist/bootstrap/pre-action-messages.d.ts.map +1 -0
  82. package/dist/bootstrap/pre-action-messages.js +49 -0
  83. package/dist/bootstrap/pre-action-messages.js.map +1 -0
  84. package/dist/bootstrap/process-idempotency.d.ts +17 -0
  85. package/dist/bootstrap/process-idempotency.d.ts.map +1 -0
  86. package/dist/bootstrap/process-idempotency.js +20 -0
  87. package/dist/bootstrap/process-idempotency.js.map +1 -0
  88. package/dist/bootstrap/register-language-adapters.d.ts +23 -0
  89. package/dist/bootstrap/register-language-adapters.d.ts.map +1 -0
  90. package/dist/bootstrap/register-language-adapters.js +35 -0
  91. package/dist/bootstrap/register-language-adapters.js.map +1 -0
  92. package/dist/bootstrap/register-tools.d.ts +228 -0
  93. package/dist/bootstrap/register-tools.d.ts.map +1 -0
  94. package/dist/bootstrap/register-tools.js +696 -0
  95. package/dist/bootstrap/register-tools.js.map +1 -0
  96. package/dist/bootstrap/render.d.ts +27 -0
  97. package/dist/bootstrap/render.d.ts.map +1 -0
  98. package/dist/bootstrap/render.js +53 -0
  99. package/dist/bootstrap/render.js.map +1 -0
  100. package/dist/bootstrap/report.d.ts +34 -0
  101. package/dist/bootstrap/report.d.ts.map +1 -0
  102. package/dist/bootstrap/report.js +47 -0
  103. package/dist/bootstrap/report.js.map +1 -0
  104. package/dist/bootstrap/run-plane.d.ts +105 -0
  105. package/dist/bootstrap/run-plane.d.ts.map +1 -0
  106. package/dist/bootstrap/run-plane.js +190 -0
  107. package/dist/bootstrap/run-plane.js.map +1 -0
  108. package/dist/bootstrap/scope-access.d.ts +68 -0
  109. package/dist/bootstrap/scope-access.d.ts.map +1 -0
  110. package/dist/bootstrap/scope-access.js +115 -0
  111. package/dist/bootstrap/scope-access.js.map +1 -0
  112. package/dist/bootstrap/state-seams.d.ts +14 -0
  113. package/dist/bootstrap/state-seams.d.ts.map +1 -0
  114. package/dist/bootstrap/state-seams.js +26 -0
  115. package/dist/bootstrap/state-seams.js.map +1 -0
  116. package/dist/bootstrap/tool-lifecycle.d.ts +102 -0
  117. package/dist/bootstrap/tool-lifecycle.d.ts.map +1 -0
  118. package/dist/bootstrap/tool-lifecycle.js +103 -0
  119. package/dist/bootstrap/tool-lifecycle.js.map +1 -0
  120. package/dist/bootstrap/tool-trust.d.ts +49 -0
  121. package/dist/bootstrap/tool-trust.d.ts.map +1 -0
  122. package/dist/bootstrap/tool-trust.js +65 -0
  123. package/dist/bootstrap/tool-trust.js.map +1 -0
  124. package/dist/bootstrap/validate-tool.d.ts +22 -0
  125. package/dist/bootstrap/validate-tool.d.ts.map +1 -0
  126. package/dist/bootstrap/validate-tool.js +38 -0
  127. package/dist/bootstrap/validate-tool.js.map +1 -0
  128. package/dist/cli-context.d.ts +38 -0
  129. package/dist/cli-context.d.ts.map +1 -0
  130. package/dist/cli-context.js +134 -0
  131. package/dist/cli-context.js.map +1 -0
  132. package/dist/commands/agent-catalog.d.ts +45 -0
  133. package/dist/commands/agent-catalog.d.ts.map +1 -0
  134. package/dist/commands/agent-catalog.js +115 -0
  135. package/dist/commands/agent-catalog.js.map +1 -0
  136. package/dist/commands/assemble-outcome.d.ts +69 -0
  137. package/dist/commands/assemble-outcome.d.ts.map +1 -0
  138. package/dist/commands/assemble-outcome.js +121 -0
  139. package/dist/commands/assemble-outcome.js.map +1 -0
  140. package/dist/commands/clear.d.ts +32 -0
  141. package/dist/commands/clear.d.ts.map +1 -0
  142. package/dist/commands/clear.js +73 -0
  143. package/dist/commands/clear.js.map +1 -0
  144. package/dist/commands/completion.d.ts +90 -0
  145. package/dist/commands/completion.d.ts.map +1 -0
  146. package/dist/commands/completion.js +233 -0
  147. package/dist/commands/completion.js.map +1 -0
  148. package/dist/commands/configure.d.ts +32 -0
  149. package/dist/commands/configure.d.ts.map +1 -0
  150. package/dist/commands/configure.js +94 -0
  151. package/dist/commands/configure.js.map +1 -0
  152. package/dist/commands/history.d.ts +18 -0
  153. package/dist/commands/history.d.ts.map +1 -0
  154. package/dist/commands/history.js +48 -0
  155. package/dist/commands/history.js.map +1 -0
  156. package/dist/commands/host-command-specs.d.ts +49 -0
  157. package/dist/commands/host-command-specs.d.ts.map +1 -0
  158. package/dist/commands/host-command-specs.js +331 -0
  159. package/dist/commands/host-command-specs.js.map +1 -0
  160. package/dist/commands/host-subcommand-groups.d.ts +69 -0
  161. package/dist/commands/host-subcommand-groups.d.ts.map +1 -0
  162. package/dist/commands/host-subcommand-groups.js +374 -0
  163. package/dist/commands/host-subcommand-groups.js.map +1 -0
  164. package/dist/commands/index.d.ts +36 -0
  165. package/dist/commands/index.d.ts.map +1 -0
  166. package/dist/commands/index.js +36 -0
  167. package/dist/commands/index.js.map +1 -0
  168. package/dist/commands/init/config-templates.d.ts +16 -0
  169. package/dist/commands/init/config-templates.d.ts.map +1 -0
  170. package/dist/commands/init/config-templates.js +108 -0
  171. package/dist/commands/init/config-templates.js.map +1 -0
  172. package/dist/commands/init/file-classifier.d.ts +40 -0
  173. package/dist/commands/init/file-classifier.d.ts.map +1 -0
  174. package/dist/commands/init/file-classifier.js +155 -0
  175. package/dist/commands/init/file-classifier.js.map +1 -0
  176. package/dist/commands/init/language-detection.d.ts +44 -0
  177. package/dist/commands/init/language-detection.d.ts.map +1 -0
  178. package/dist/commands/init/language-detection.js +124 -0
  179. package/dist/commands/init/language-detection.js.map +1 -0
  180. package/dist/commands/init/scaffold-writer.d.ts +26 -0
  181. package/dist/commands/init/scaffold-writer.d.ts.map +1 -0
  182. package/dist/commands/init/scaffold-writer.js +102 -0
  183. package/dist/commands/init/scaffold-writer.js.map +1 -0
  184. package/dist/commands/init/state-machine.d.ts +32 -0
  185. package/dist/commands/init/state-machine.d.ts.map +1 -0
  186. package/dist/commands/init/state-machine.js +105 -0
  187. package/dist/commands/init/state-machine.js.map +1 -0
  188. package/dist/commands/init.d.ts +95 -0
  189. package/dist/commands/init.d.ts.map +1 -0
  190. package/dist/commands/init.js +209 -0
  191. package/dist/commands/init.js.map +1 -0
  192. package/dist/commands/mount-command-spec.d.ts +106 -0
  193. package/dist/commands/mount-command-spec.d.ts.map +1 -0
  194. package/dist/commands/mount-command-spec.js +313 -0
  195. package/dist/commands/mount-command-spec.js.map +1 -0
  196. package/dist/commands/mount-result-command.d.ts +71 -0
  197. package/dist/commands/mount-result-command.d.ts.map +1 -0
  198. package/dist/commands/mount-result-command.js +76 -0
  199. package/dist/commands/mount-result-command.js.map +1 -0
  200. package/dist/commands/plugin/config-edit.d.ts +20 -0
  201. package/dist/commands/plugin/config-edit.d.ts.map +1 -0
  202. package/dist/commands/plugin/config-edit.js +102 -0
  203. package/dist/commands/plugin/config-edit.js.map +1 -0
  204. package/dist/commands/plugin/domain-resolution.d.ts +38 -0
  205. package/dist/commands/plugin/domain-resolution.d.ts.map +1 -0
  206. package/dist/commands/plugin/domain-resolution.js +98 -0
  207. package/dist/commands/plugin/domain-resolution.js.map +1 -0
  208. package/dist/commands/plugin/host-dir.d.ts +42 -0
  209. package/dist/commands/plugin/host-dir.d.ts.map +1 -0
  210. package/dist/commands/plugin/host-dir.js +168 -0
  211. package/dist/commands/plugin/host-dir.js.map +1 -0
  212. package/dist/commands/plugin-host-ops.d.ts +41 -0
  213. package/dist/commands/plugin-host-ops.d.ts.map +1 -0
  214. package/dist/commands/plugin-host-ops.js +114 -0
  215. package/dist/commands/plugin-host-ops.js.map +1 -0
  216. package/dist/commands/plugin.d.ts +81 -0
  217. package/dist/commands/plugin.d.ts.map +1 -0
  218. package/dist/commands/plugin.js +287 -0
  219. package/dist/commands/plugin.js.map +1 -0
  220. package/dist/commands/render-outcome.d.ts +52 -0
  221. package/dist/commands/render-outcome.d.ts.map +1 -0
  222. package/dist/commands/render-outcome.js +55 -0
  223. package/dist/commands/render-outcome.js.map +1 -0
  224. package/dist/commands/session-show.d.ts +27 -0
  225. package/dist/commands/session-show.d.ts.map +1 -0
  226. package/dist/commands/session-show.js +166 -0
  227. package/dist/commands/session-show.js.map +1 -0
  228. package/dist/commands/shared.d.ts +107 -0
  229. package/dist/commands/shared.d.ts.map +1 -0
  230. package/dist/commands/shared.js +13 -0
  231. package/dist/commands/shared.js.map +1 -0
  232. package/dist/commands/tools/data-purge.d.ts +20 -0
  233. package/dist/commands/tools/data-purge.d.ts.map +1 -0
  234. package/dist/commands/tools/data-purge.js +59 -0
  235. package/dist/commands/tools/data-purge.js.map +1 -0
  236. package/dist/commands/tools/index.d.ts +16 -0
  237. package/dist/commands/tools/index.d.ts.map +1 -0
  238. package/dist/commands/tools/index.js +213 -0
  239. package/dist/commands/tools/index.js.map +1 -0
  240. package/dist/commands/tools/install.d.ts +24 -0
  241. package/dist/commands/tools/install.d.ts.map +1 -0
  242. package/dist/commands/tools/install.js +83 -0
  243. package/dist/commands/tools/install.js.map +1 -0
  244. package/dist/commands/tools/list.d.ts +41 -0
  245. package/dist/commands/tools/list.d.ts.map +1 -0
  246. package/dist/commands/tools/list.js +103 -0
  247. package/dist/commands/tools/list.js.map +1 -0
  248. package/dist/commands/tools/runtime-probe-entry.d.ts +14 -0
  249. package/dist/commands/tools/runtime-probe-entry.d.ts.map +1 -0
  250. package/dist/commands/tools/runtime-probe-entry.js +36 -0
  251. package/dist/commands/tools/runtime-probe-entry.js.map +1 -0
  252. package/dist/commands/tools/runtime-probe.d.ts +29 -0
  253. package/dist/commands/tools/runtime-probe.d.ts.map +1 -0
  254. package/dist/commands/tools/runtime-probe.js +66 -0
  255. package/dist/commands/tools/runtime-probe.js.map +1 -0
  256. package/dist/commands/tools/storage-contract-checks.d.ts +37 -0
  257. package/dist/commands/tools/storage-contract-checks.d.ts.map +1 -0
  258. package/dist/commands/tools/storage-contract-checks.js +91 -0
  259. package/dist/commands/tools/storage-contract-checks.js.map +1 -0
  260. package/dist/commands/tools/uninstall.d.ts +29 -0
  261. package/dist/commands/tools/uninstall.d.ts.map +1 -0
  262. package/dist/commands/tools/uninstall.js +77 -0
  263. package/dist/commands/tools/uninstall.js.map +1 -0
  264. package/dist/commands/tools/validate.d.ts +44 -0
  265. package/dist/commands/tools/validate.d.ts.map +1 -0
  266. package/dist/commands/tools/validate.js +202 -0
  267. package/dist/commands/tools/validate.js.map +1 -0
  268. package/dist/commands/uninstall/targets.d.ts +53 -0
  269. package/dist/commands/uninstall/targets.d.ts.map +1 -0
  270. package/dist/commands/uninstall/targets.js +205 -0
  271. package/dist/commands/uninstall/targets.js.map +1 -0
  272. package/dist/commands/uninstall.d.ts +88 -0
  273. package/dist/commands/uninstall.d.ts.map +1 -0
  274. package/dist/commands/uninstall.js +184 -0
  275. package/dist/commands/uninstall.js.map +1 -0
  276. package/dist/env/host-env-specs.d.ts +52 -0
  277. package/dist/env/host-env-specs.d.ts.map +1 -0
  278. package/dist/env/host-env-specs.js +129 -0
  279. package/dist/env/host-env-specs.js.map +1 -0
  280. package/dist/error-handler.d.ts +64 -0
  281. package/dist/error-handler.d.ts.map +1 -0
  282. package/dist/error-handler.js +180 -0
  283. package/dist/error-handler.js.map +1 -0
  284. package/dist/index.d.ts +21 -0
  285. package/dist/index.d.ts.map +1 -0
  286. package/dist/index.js +154 -0
  287. package/dist/index.js.map +1 -0
  288. package/dist/open-report.d.ts +40 -0
  289. package/dist/open-report.d.ts.map +1 -0
  290. package/dist/open-report.js +54 -0
  291. package/dist/open-report.js.map +1 -0
  292. package/dist/report-compose.d.ts +35 -0
  293. package/dist/report-compose.d.ts.map +1 -0
  294. package/dist/report-compose.js +103 -0
  295. package/dist/report-compose.js.map +1 -0
  296. package/dist/session-replay-registry.d.ts +20 -0
  297. package/dist/session-replay-registry.d.ts.map +1 -0
  298. package/dist/session-replay-registry.js +38 -0
  299. package/dist/session-replay-registry.js.map +1 -0
  300. package/dist/telemetry/profiling.d.ts +42 -0
  301. package/dist/telemetry/profiling.d.ts.map +1 -0
  302. package/dist/telemetry/profiling.js +160 -0
  303. package/dist/telemetry/profiling.js.map +1 -0
  304. package/dist/telemetry/sdk-init.d.ts +87 -0
  305. package/dist/telemetry/sdk-init.d.ts.map +1 -0
  306. package/dist/telemetry/sdk-init.js +235 -0
  307. package/dist/telemetry/sdk-init.js.map +1 -0
  308. package/dist/ui/App.d.ts +32 -0
  309. package/dist/ui/App.d.ts.map +1 -0
  310. package/dist/ui/App.js +35 -0
  311. package/dist/ui/App.js.map +1 -0
  312. package/dist/ui/render.d.ts +15 -0
  313. package/dist/ui/render.d.ts.map +1 -0
  314. package/dist/ui/render.js +21 -0
  315. package/dist/ui/render.js.map +1 -0
  316. package/dist/ui/result-to-view.d.ts +40 -0
  317. package/dist/ui/result-to-view.d.ts.map +1 -0
  318. package/dist/ui/result-to-view.js +389 -0
  319. package/dist/ui/result-to-view.js.map +1 -0
  320. package/dist/ui/views/init-view.d.ts +9 -0
  321. package/dist/ui/views/init-view.d.ts.map +1 -0
  322. package/dist/ui/views/init-view.js +119 -0
  323. package/dist/ui/views/init-view.js.map +1 -0
  324. package/dist/ui/views/misc-views.d.ts +18 -0
  325. package/dist/ui/views/misc-views.d.ts.map +1 -0
  326. package/dist/ui/views/misc-views.js +244 -0
  327. package/dist/ui/views/misc-views.js.map +1 -0
  328. package/dist/ui/views/plugin-view.d.ts +8 -0
  329. package/dist/ui/views/plugin-view.d.ts.map +1 -0
  330. package/dist/ui/views/plugin-view.js +135 -0
  331. package/dist/ui/views/plugin-view.js.map +1 -0
  332. package/dist/ui/views/tools-views.d.ts +12 -0
  333. package/dist/ui/views/tools-views.d.ts.map +1 -0
  334. package/dist/ui/views/tools-views.js +152 -0
  335. package/dist/ui/views/tools-views.js.map +1 -0
  336. package/dist/update-notifier.d.ts +108 -0
  337. package/dist/update-notifier.d.ts.map +1 -0
  338. package/dist/update-notifier.js +188 -0
  339. package/dist/update-notifier.js.map +1 -0
  340. package/dist/update-state.d.ts +40 -0
  341. package/dist/update-state.d.ts.map +1 -0
  342. package/dist/update-state.js +81 -0
  343. package/dist/update-state.js.map +1 -0
  344. package/dist/welcome.d.ts +53 -0
  345. package/dist/welcome.d.ts.map +1 -0
  346. package/dist/welcome.js +89 -0
  347. package/dist/welcome.js.map +1 -0
  348. package/package.json +100 -0
@@ -0,0 +1,38 @@
1
+ /**
2
+ * plugin/domain-resolution — pure validation + routing logic for the
3
+ * `plugin add/remove/sync` commands.
4
+ *
5
+ * Extracted from `commands/plugin.ts` to keep that file focused on the
6
+ * command bodies. Everything here decides WHICH host dir / domain a spec
7
+ * targets — it reads package markers but performs no install. The
8
+ * plugin-supporting domains are NOT hardcoded: they come from the
9
+ * registered tools' `pluginLayout` descriptors (threaded in as
10
+ * `PluginLayout[]`), so the kernel stays tool-agnostic and the tools
11
+ * remain the single source of truth (ADR-0009 corollary 1).
12
+ */
13
+ import { type PluginLayout } from '@opensip-cli/core';
14
+ /**
15
+ * Pseudo-domain for full Tool plugins (whole subcommands). Distinct from
16
+ * the fit/sim plugin DOMAINS (which are project-committed + listed in
17
+ * `plugins.<domain>` config): a Tool plugin auto-discovers by its
18
+ * `opensipTools.kind: "tool"` marker, needs NO config entry, and installs
19
+ * user-global by default (`~/.opensip-cli/plugins/tool`) so the
20
+ * subcommand is available in every project — or project-local
21
+ * (`.runtime/plugins/tool`) with `--project`.
22
+ */
23
+ export declare const TOOL_DOMAIN = "tool";
24
+ /** The set of plugin-supporting domain names from the contributed layouts. */
25
+ export declare function domainNames(layouts: readonly PluginLayout[]): string[];
26
+ /**
27
+ * Resolve the target domain, rejecting arbitrary strings from --domain.
28
+ * A bare cast would let a caller pass '../../etc' and drive path
29
+ * construction outside opensip-cli/.runtime/.
30
+ */
31
+ export declare function resolveDomain(override: string | undefined, packageName: string, domains: readonly string[]): string | undefined;
32
+ /**
33
+ * Decide whether `plugin add/remove <spec>` targets a Tool plugin:
34
+ * explicit `--domain tool`, or (when no `--domain` is given) a detected
35
+ * `kind: "tool"` marker. An explicit fit/sim `--domain` is honoured as-is.
36
+ */
37
+ export declare function isToolTarget(domainOverride: string | undefined, spec: string, cwd: string): boolean;
38
+ //# sourceMappingURL=domain-resolution.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-resolution.d.ts","sourceRoot":"","sources":["../../../src/commands/plugin/domain-resolution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,EAAoB,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAIxE;;;;;;;;GAQG;AACH,eAAO,MAAM,WAAW,SAAS,CAAC;AAElC,8EAA8E;AAC9E,wBAAgB,WAAW,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,MAAM,EAAE,CAEtE;AAaD;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,GAAG,SAAS,EAC5B,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,SAAS,MAAM,EAAE,GACzB,MAAM,GAAG,SAAS,CAGpB;AAqCD;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,GACV,OAAO,CAIT"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * plugin/domain-resolution — pure validation + routing logic for the
3
+ * `plugin add/remove/sync` commands.
4
+ *
5
+ * Extracted from `commands/plugin.ts` to keep that file focused on the
6
+ * command bodies. Everything here decides WHICH host dir / domain a spec
7
+ * targets — it reads package markers but performs no install. The
8
+ * plugin-supporting domains are NOT hardcoded: they come from the
9
+ * registered tools' `pluginLayout` descriptors (threaded in as
10
+ * `PluginLayout[]`), so the kernel stays tool-agnostic and the tools
11
+ * remain the single source of truth (ADR-0009 corollary 1).
12
+ */
13
+ import { execFileSync } from 'node:child_process';
14
+ import { isAbsolute, join } from 'node:path';
15
+ import { readDeclaredKind } from '@opensip-cli/core';
16
+ import { extractNameFromSpec } from './host-dir.js';
17
+ /**
18
+ * Pseudo-domain for full Tool plugins (whole subcommands). Distinct from
19
+ * the fit/sim plugin DOMAINS (which are project-committed + listed in
20
+ * `plugins.<domain>` config): a Tool plugin auto-discovers by its
21
+ * `opensipTools.kind: "tool"` marker, needs NO config entry, and installs
22
+ * user-global by default (`~/.opensip-cli/plugins/tool`) so the
23
+ * subcommand is available in every project — or project-local
24
+ * (`.runtime/plugins/tool`) with `--project`.
25
+ */
26
+ export const TOOL_DOMAIN = 'tool';
27
+ /** The set of plugin-supporting domain names from the contributed layouts. */
28
+ export function domainNames(layouts) {
29
+ return layouts.map((l) => l.domain);
30
+ }
31
+ /**
32
+ * Infer a target domain from a package name when --domain is omitted: the
33
+ * first declared domain whose name appears as a word in the package name,
34
+ * else the first declared domain. Domain names come from trusted
35
+ * first-party layouts, so building a RegExp from them is safe.
36
+ */
37
+ function inferDomain(packageName, domains) {
38
+ const match = domains.find((d) => new RegExp(String.raw `\b${d}\b`).test(packageName));
39
+ return match ?? domains[0];
40
+ }
41
+ /**
42
+ * Resolve the target domain, rejecting arbitrary strings from --domain.
43
+ * A bare cast would let a caller pass '../../etc' and drive path
44
+ * construction outside opensip-cli/.runtime/.
45
+ */
46
+ export function resolveDomain(override, packageName, domains) {
47
+ if (override === undefined)
48
+ return inferDomain(packageName, domains);
49
+ return domains.includes(override) ? override : undefined;
50
+ }
51
+ /**
52
+ * Detect a package's `opensipTools.kind` BEFORE installing, so `plugin add`
53
+ * can route a Tool plugin to its host dir rather than a fit/sim domain.
54
+ *
55
+ * - Local-path specs (`.`/`/`/`file:`): read the target's package.json
56
+ * directly — free and offline.
57
+ * - Registry specs: `npm view <name> opensipTools.kind` (one network
58
+ * call; `plugin add` is already online for the install).
59
+ *
60
+ * Returns undefined when undetectable (offline, private registry, no
61
+ * marker) — the caller then falls back to fit/sim domain inference. The raw
62
+ * declared kind is returned as a string (the only thing the caller checks is
63
+ * `=== 'tool'`); domain markers are no longer a compiled-in host union.
64
+ */
65
+ function detectPluginKind(spec, cwd) {
66
+ if (spec.startsWith('/') || spec.startsWith('.') || spec.startsWith('file:')) {
67
+ const raw = spec.startsWith('file:') ? spec.slice('file:'.length) : spec;
68
+ return readDeclaredKind(isAbsolute(raw) ? raw : join(cwd, raw));
69
+ }
70
+ try {
71
+ const name = extractNameFromSpec(spec) ?? spec;
72
+ const out = execFileSync('npm', ['view', name, 'opensipTools.kind'], {
73
+ cwd,
74
+ encoding: 'utf8',
75
+ stdio: ['ignore', 'pipe', 'ignore'],
76
+ })
77
+ .toString()
78
+ .trim();
79
+ return out === '' ? undefined : out;
80
+ }
81
+ catch {
82
+ // @fitness-ignore-next-line error-handling-quality -- `npm view` failure (offline, private registry, or no such package) means the kind is undetectable; returning undefined routes the caller to fit/sim domain inference — the documented fallback, not a swallowed error.
83
+ return undefined;
84
+ }
85
+ }
86
+ /**
87
+ * Decide whether `plugin add/remove <spec>` targets a Tool plugin:
88
+ * explicit `--domain tool`, or (when no `--domain` is given) a detected
89
+ * `kind: "tool"` marker. An explicit fit/sim `--domain` is honoured as-is.
90
+ */
91
+ export function isToolTarget(domainOverride, spec, cwd) {
92
+ if (domainOverride === TOOL_DOMAIN)
93
+ return true;
94
+ if (domainOverride !== undefined)
95
+ return false;
96
+ return detectPluginKind(spec, cwd) === 'tool';
97
+ }
98
+ //# sourceMappingURL=domain-resolution.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-resolution.js","sourceRoot":"","sources":["../../../src/commands/plugin/domain-resolution.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAE7C,OAAO,EAAE,gBAAgB,EAAqB,MAAM,mBAAmB,CAAC;AAExE,OAAO,EAAE,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAEpD;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,MAAM,CAAC;AAElC,8EAA8E;AAC9E,MAAM,UAAU,WAAW,CAAC,OAAgC;IAC1D,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AACtC,CAAC;AAED;;;;;GAKG;AACH,SAAS,WAAW,CAAC,WAAmB,EAAE,OAA0B;IAClE,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,GAAG,CAAA,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;IACtF,OAAO,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC;AAC7B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,QAA4B,EAC5B,WAAmB,EACnB,OAA0B;IAE1B,IAAI,QAAQ,KAAK,SAAS;QAAE,OAAO,WAAW,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IACrE,OAAO,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3D,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAS,gBAAgB,CAAC,IAAY,EAAE,GAAW;IACjD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC7E,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACzE,OAAO,gBAAgB,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;QAC/C,MAAM,GAAG,GAAG,YAAY,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,IAAI,EAAE,mBAAmB,CAAC,EAAE;YACnE,GAAG;YACH,QAAQ,EAAE,MAAM;YAChB,KAAK,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC;SACpC,CAAC;aACC,QAAQ,EAAE;aACV,IAAI,EAAE,CAAC;QACV,OAAO,GAAG,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC;IACtC,CAAC;IAAC,MAAM,CAAC;QACP,6QAA6Q;QAC7Q,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAC1B,cAAkC,EAClC,IAAY,EACZ,GAAW;IAEX,IAAI,cAAc,KAAK,WAAW;QAAE,OAAO,IAAI,CAAC;IAChD,IAAI,cAAc,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC/C,OAAO,gBAAgB,CAAC,IAAI,EAAE,GAAG,CAAC,KAAK,MAAM,CAAC;AAChD,CAAC"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @fileoverview Plugin host directory + installed-package introspection.
3
+ *
4
+ * Each plugin domain owns a `node_modules` tree under
5
+ * `<project>/opensip-cli/.runtime/plugins/<domain>/`. This module
6
+ * creates the host package.json, peeks at installed packages to
7
+ * resolve real package names (for local-path specs that don't carry a
8
+ * name), and walks peerDependencies for auto-install.
9
+ *
10
+ * Extracted from `commands/plugin.ts` so the install/uninstall flows
11
+ * there stay focused on Commander + npm orchestration.
12
+ */
13
+ /** Filename of the host package.json that pins plugin installs. */
14
+ export declare const HOST_PACKAGE_JSON = "package.json";
15
+ /**
16
+ * Guard against argv-injection through npm. execFileSync doesn't spawn
17
+ * a shell, so shell metacharacters are safe, but any arg starting with
18
+ * '-' would be consumed by npm as a flag (e.g. '-g', '--prefix=/etc').
19
+ */
20
+ export declare function isSafeNpmSpec(spec: string): boolean;
21
+ /** Create the host package.json (if absent) for a plugin host dir + return the dir. */
22
+ /** Create (if absent) a plugin host dir + its host package.json; returns `dir`. */
23
+ export declare function ensureHostDir(dir: string, domain: string): string;
24
+ /** Project-local plugin host dir: `<project>/opensip-cli/.runtime/plugins/<domain>`. */
25
+ export declare function ensurePluginHostDir(domain: string, cwd: string): string;
26
+ /**
27
+ * User-global plugin host dir: `~/.opensip-cli/plugins/<domain>`. Used by
28
+ * the `tool` domain so a `plugin add <tool>` makes the subcommand available
29
+ * across every project (the cross-project analogue of `npm i -g`).
30
+ */
31
+ export declare function ensureUserPluginHostDir(domain: string): string;
32
+ /**
33
+ * After installing a plugin, look at its peerDependencies and install
34
+ * any missing ones into the same plugin directory. Best-effort: missing
35
+ * peers produce no error here, the loader will surface a clear error if
36
+ * the plugin can't resolve its imports.
37
+ */
38
+ export declare function installMissingPeers(dir: string, requestedSpec: string, depsBefore: Set<string>): void;
39
+ export declare function findInstalledName(dir: string, requestedSpec: string, depsBefore: Set<string>): string | undefined;
40
+ export declare function readHostDependencies(dir: string): Set<string>;
41
+ export declare function extractNameFromSpec(spec: string): string | undefined;
42
+ //# sourceMappingURL=host-dir.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-dir.d.ts","sourceRoot":"","sources":["../../../src/commands/plugin/host-dir.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAQH,mEAAmE;AACnE,eAAO,MAAM,iBAAiB,iBAAiB,CAAC;AAEhD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAInD;AAED,uFAAuF;AACvF,mFAAmF;AACnF,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAoBjE;AAED,wFAAwF;AACxF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAEvE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GACtB,IAAI,CAsBN;AAED,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,aAAa,EAAE,MAAM,EACrB,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GACtB,MAAM,GAAG,SAAS,CAEpB;AA2BD,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAG7D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAapE"}
@@ -0,0 +1,168 @@
1
+ // @fitness-ignore-file error-handling-quality -- package.json walks / npm-install probes where unreadable/malformed entries mean "not installable" / "not a candidate" — same as absent; npm errors already stream to stderr via inherited stdio.
2
+ // @fitness-ignore-file unbounded-memory -- reads package.json files; bounded by standard npm package metadata shape.
3
+ /**
4
+ * @fileoverview Plugin host directory + installed-package introspection.
5
+ *
6
+ * Each plugin domain owns a `node_modules` tree under
7
+ * `<project>/opensip-cli/.runtime/plugins/<domain>/`. This module
8
+ * creates the host package.json, peeks at installed packages to
9
+ * resolve real package names (for local-path specs that don't carry a
10
+ * name), and walks peerDependencies for auto-install.
11
+ *
12
+ * Extracted from `commands/plugin.ts` so the install/uninstall flows
13
+ * there stay focused on Commander + npm orchestration.
14
+ */
15
+ import { execFileSync } from 'node:child_process';
16
+ import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
17
+ import { join } from 'node:path';
18
+ import { resolveProjectPaths, resolveUserPaths } from '@opensip-cli/core';
19
+ /** Filename of the host package.json that pins plugin installs. */
20
+ export const HOST_PACKAGE_JSON = 'package.json';
21
+ /**
22
+ * Guard against argv-injection through npm. execFileSync doesn't spawn
23
+ * a shell, so shell metacharacters are safe, but any arg starting with
24
+ * '-' would be consumed by npm as a flag (e.g. '-g', '--prefix=/etc').
25
+ */
26
+ export function isSafeNpmSpec(spec) {
27
+ if (spec.length === 0)
28
+ return false;
29
+ if (spec.startsWith('-'))
30
+ return false;
31
+ return true;
32
+ }
33
+ /** Create the host package.json (if absent) for a plugin host dir + return the dir. */
34
+ /** Create (if absent) a plugin host dir + its host package.json; returns `dir`. */
35
+ export function ensureHostDir(dir, domain) {
36
+ mkdirSync(dir, { recursive: true });
37
+ const pkgJsonPath = join(dir, HOST_PACKAGE_JSON);
38
+ if (!existsSync(pkgJsonPath)) {
39
+ writeFileSync(pkgJsonPath, JSON.stringify({
40
+ name: `opensip-cli-${domain}-plugins`,
41
+ version: '0.0.0',
42
+ private: true,
43
+ type: 'module',
44
+ dependencies: {},
45
+ }, null, 2));
46
+ }
47
+ return dir;
48
+ }
49
+ /** Project-local plugin host dir: `<project>/opensip-cli/.runtime/plugins/<domain>`. */
50
+ export function ensurePluginHostDir(domain, cwd) {
51
+ return ensureHostDir(resolveProjectPaths(cwd).pluginsDir(domain), domain);
52
+ }
53
+ /**
54
+ * User-global plugin host dir: `~/.opensip-cli/plugins/<domain>`. Used by
55
+ * the `tool` domain so a `plugin add <tool>` makes the subcommand available
56
+ * across every project (the cross-project analogue of `npm i -g`).
57
+ */
58
+ export function ensureUserPluginHostDir(domain) {
59
+ return ensureHostDir(resolveUserPaths().pluginsDir(domain), domain);
60
+ }
61
+ /**
62
+ * After installing a plugin, look at its peerDependencies and install
63
+ * any missing ones into the same plugin directory. Best-effort: missing
64
+ * peers produce no error here, the loader will surface a clear error if
65
+ * the plugin can't resolve its imports.
66
+ */
67
+ export function installMissingPeers(dir, requestedSpec, depsBefore) {
68
+ const installed = findInstalledPackage(dir, requestedSpec, depsBefore);
69
+ if (!installed)
70
+ return;
71
+ const peerDeps = installed.peerDependencies ?? {};
72
+ const installedAtRoot = new Set(safeReaddirScopedAndFlat(join(dir, 'node_modules')));
73
+ const missing = Object.entries(peerDeps).filter(([name]) => !installedAtRoot.has(name));
74
+ if (missing.length === 0)
75
+ return;
76
+ for (const [name, range] of missing) {
77
+ if (!isSafeNpmSpec(name))
78
+ continue;
79
+ if (typeof range !== 'string' || !isSafeNpmSpec(range))
80
+ continue;
81
+ try {
82
+ execFileSync('npm', ['install', '--ignore-scripts', '--no-save', `${name}@${range}`], {
83
+ cwd: dir,
84
+ stdio: ['ignore', process.stderr, process.stderr],
85
+ });
86
+ }
87
+ catch {
88
+ // Loader will surface unresolved imports; swallow here.
89
+ }
90
+ }
91
+ }
92
+ export function findInstalledName(dir, requestedSpec, depsBefore) {
93
+ return findInstalledPackage(dir, requestedSpec, depsBefore)?.name;
94
+ }
95
+ function findInstalledPackage(dir, requestedSpec, depsBefore) {
96
+ const nodeModulesDir = join(dir, 'node_modules');
97
+ if (!existsSync(nodeModulesDir))
98
+ return undefined;
99
+ const namedSpec = extractNameFromSpec(requestedSpec);
100
+ if (namedSpec) {
101
+ const pkg = readPackageJson(join(nodeModulesDir, namedSpec, HOST_PACKAGE_JSON));
102
+ if (pkg)
103
+ return pkg;
104
+ }
105
+ // Local-path installs: the new dep key is whichever entry is in the
106
+ // host package.json now that wasn't there before.
107
+ const depsAfter = readHostDependencies(dir);
108
+ for (const name of depsAfter) {
109
+ if (depsBefore.has(name))
110
+ continue;
111
+ const pkg = readPackageJson(join(nodeModulesDir, name, HOST_PACKAGE_JSON));
112
+ if (pkg?.name === name)
113
+ return pkg;
114
+ }
115
+ return undefined;
116
+ }
117
+ export function readHostDependencies(dir) {
118
+ const hostPkg = readPackageJson(join(dir, HOST_PACKAGE_JSON));
119
+ return new Set(Object.keys(hostPkg?.dependencies ?? {}));
120
+ }
121
+ export function extractNameFromSpec(spec) {
122
+ if (spec.startsWith('/') || spec.startsWith('.') || spec.startsWith('file:'))
123
+ return undefined;
124
+ if (spec.startsWith('@')) {
125
+ const withoutScope = spec.slice(1);
126
+ const slashIdx = withoutScope.indexOf('/');
127
+ if (slashIdx === -1)
128
+ return undefined;
129
+ const rest = withoutScope.slice(slashIdx + 1);
130
+ const atIdx = rest.indexOf('@');
131
+ const name = atIdx === -1 ? rest : rest.slice(0, atIdx);
132
+ return `@${withoutScope.slice(0, slashIdx)}/${name}`;
133
+ }
134
+ const atIdx = spec.indexOf('@');
135
+ return atIdx === -1 ? spec : spec.slice(0, atIdx);
136
+ }
137
+ function readPackageJson(path) {
138
+ if (!existsSync(path))
139
+ return undefined;
140
+ try {
141
+ return JSON.parse(readFileSync(path, 'utf8'));
142
+ }
143
+ catch {
144
+ return undefined;
145
+ }
146
+ }
147
+ function safeReaddirScopedAndFlat(nodeModulesDir) {
148
+ if (!existsSync(nodeModulesDir))
149
+ return [];
150
+ const out = [];
151
+ for (const entry of readdirSync(nodeModulesDir)) {
152
+ if (entry.startsWith('@')) {
153
+ const scopeDir = join(nodeModulesDir, entry);
154
+ try {
155
+ for (const scoped of readdirSync(scopeDir))
156
+ out.push(`${entry}/${scoped}`);
157
+ }
158
+ catch {
159
+ /* unreadable scope */
160
+ }
161
+ }
162
+ else if (!entry.startsWith('.')) {
163
+ out.push(entry);
164
+ }
165
+ }
166
+ return out;
167
+ }
168
+ //# sourceMappingURL=host-dir.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-dir.js","sourceRoot":"","sources":["../../../src/commands/plugin/host-dir.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * plugin-host-ops — host-mutation helpers for the `plugin` command.
3
+ *
4
+ * The npm install/uninstall primitives and the Tool-plugin add/remove
5
+ * wrappers that mutate a plugin host dir. Extracted from `plugin.ts` so the
6
+ * command bodies (`pluginList`/`pluginAdd`/`pluginRemove`/`pluginSync`) stay
7
+ * focused on argument validation and config wiring; this module owns the
8
+ * side-effecting npm + host-dir mutation.
9
+ */
10
+ import type { PluginResult } from '@opensip-cli/contracts';
11
+ export { editPluginList } from './plugin/config-edit.js';
12
+ /** Outcome of an npm install into a host dir: the resolved installed name, or an error message. */
13
+ export type InstallOutcome = {
14
+ readonly ok: true;
15
+ readonly installedName: string;
16
+ } | {
17
+ readonly ok: false;
18
+ readonly error: string;
19
+ };
20
+ /**
21
+ * `npm install --ignore-scripts <spec>` into a plugin host dir, then
22
+ * resolve the real installed name and auto-install peers. Shared by the
23
+ * fit/sim domain path and the Tool-plugin path.
24
+ *
25
+ * --ignore-scripts: plugins run via dynamic import() at tool time; they
26
+ * don't legitimately need install-time code execution. Blocks supply-chain
27
+ * attacks via postinstall hooks. npm's stdout is routed to stderr so JSON
28
+ * renderers (which own process stdout) are not contaminated.
29
+ */
30
+ export declare function npmInstallIntoHost(dir: string, packageName: string): InstallOutcome;
31
+ /**
32
+ * Install a Tool plugin into its host dir (user-global by default,
33
+ * project-local with `--project`). No `plugins.<domain>` config entry —
34
+ * Tool plugins auto-discover by their `kind: "tool"` marker.
35
+ */
36
+ export declare function addToolPlugin(packageName: string, cwd: string, project: boolean): PluginResult;
37
+ /** npm-uninstall a package from a host dir. Pure of config concerns. */
38
+ export declare function npmUninstallFromHost(dir: string, packageName: string): boolean;
39
+ /** Remove a Tool plugin from its host dir (user-global by default, --project otherwise). */
40
+ export declare function removeToolPlugin(packageName: string, cwd: string, project: boolean): PluginResult;
41
+ //# sourceMappingURL=plugin-host-ops.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-host-ops.d.ts","sourceRoot":"","sources":["../../src/commands/plugin-host-ops.ts"],"names":[],"mappings":"AACA;;;;;;;;GAQG;AAkBH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAI3D,OAAO,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAUzD,mGAAmG;AACnG,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAAE,GACrD;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnD;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,cAAc,CAwBnF;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,YAAY,CAS9F;AAED,wEAAwE;AACxE,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAU9E;AAED,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,YAAY,CAsBjG"}
@@ -0,0 +1,114 @@
1
+ // @fitness-ignore-file error-handling-quality -- npm install failures already stream to stderr via inherited stdio (downstream loader surfaces unresolved imports), and the package.json / node_modules walks are probes where unreadable/malformed entries mean "not installable" or "not a candidate" — same as absent.
2
+ /**
3
+ * plugin-host-ops — host-mutation helpers for the `plugin` command.
4
+ *
5
+ * The npm install/uninstall primitives and the Tool-plugin add/remove
6
+ * wrappers that mutate a plugin host dir. Extracted from `plugin.ts` so the
7
+ * command bodies (`pluginList`/`pluginAdd`/`pluginRemove`/`pluginSync`) stay
8
+ * focused on argument validation and config wiring; this module owns the
9
+ * side-effecting npm + host-dir mutation.
10
+ */
11
+ import { execFileSync } from 'node:child_process';
12
+ import { existsSync } from 'node:fs';
13
+ import { join } from 'node:path';
14
+ import { resolveProjectPaths, resolveUserPaths } from '@opensip-cli/core';
15
+ import { TOOL_DOMAIN } from './plugin/domain-resolution.js';
16
+ import { ensurePluginHostDir, ensureUserPluginHostDir, findInstalledName, HOST_PACKAGE_JSON, installMissingPeers, readHostDependencies, } from './plugin/host-dir.js';
17
+ // Re-exported so the test hook (`__test.editPluginList`) and any host-ops
18
+ // consumer have a single import home for the host-mutation surface.
19
+ export { editPluginList } from './plugin/config-edit.js';
20
+ /**
21
+ * CommandResult discriminator literals. `as const` keeps the literal type
22
+ * (so the PluginResult union still narrows) while satisfying
23
+ * sonarjs/no-duplicate-string — no scattered eslint-disable needed.
24
+ */
25
+ const PLUGIN_ADD = 'plugin-add';
26
+ const PLUGIN_REMOVE = 'plugin-remove';
27
+ /**
28
+ * `npm install --ignore-scripts <spec>` into a plugin host dir, then
29
+ * resolve the real installed name and auto-install peers. Shared by the
30
+ * fit/sim domain path and the Tool-plugin path.
31
+ *
32
+ * --ignore-scripts: plugins run via dynamic import() at tool time; they
33
+ * don't legitimately need install-time code execution. Blocks supply-chain
34
+ * attacks via postinstall hooks. npm's stdout is routed to stderr so JSON
35
+ * renderers (which own process stdout) are not contaminated.
36
+ */
37
+ export function npmInstallIntoHost(dir, packageName) {
38
+ const depsBefore = readHostDependencies(dir);
39
+ try {
40
+ execFileSync('npm', ['install', '--ignore-scripts', packageName], {
41
+ cwd: dir,
42
+ stdio: ['ignore', process.stderr, process.stderr],
43
+ });
44
+ const resolvedName = findInstalledName(dir, packageName, depsBefore);
45
+ const isLocalPathSpec = packageName.startsWith('/') || packageName.startsWith('.') || packageName.startsWith('file:');
46
+ if (!resolvedName && isLocalPathSpec) {
47
+ return {
48
+ ok: false,
49
+ error: `Installed '${packageName}' but could not resolve the installed package name from package.json. The install was not recorded; remove and retry.`,
50
+ };
51
+ }
52
+ installMissingPeers(dir, packageName, depsBefore);
53
+ return { ok: true, installedName: resolvedName ?? packageName };
54
+ }
55
+ catch (error) {
56
+ return {
57
+ ok: false,
58
+ error: `Failed to add ${packageName}: ${error instanceof Error ? error.message : String(error)}`,
59
+ };
60
+ }
61
+ }
62
+ /**
63
+ * Install a Tool plugin into its host dir (user-global by default,
64
+ * project-local with `--project`). No `plugins.<domain>` config entry —
65
+ * Tool plugins auto-discover by their `kind: "tool"` marker.
66
+ */
67
+ export function addToolPlugin(packageName, cwd, project) {
68
+ const dir = project
69
+ ? ensurePluginHostDir(TOOL_DOMAIN, cwd)
70
+ : ensureUserPluginHostDir(TOOL_DOMAIN);
71
+ const outcome = npmInstallIntoHost(dir, packageName);
72
+ if (!outcome.ok) {
73
+ return { type: PLUGIN_ADD, packageName, success: false, error: outcome.error };
74
+ }
75
+ return { type: PLUGIN_ADD, packageName: outcome.installedName, success: true };
76
+ }
77
+ /** npm-uninstall a package from a host dir. Pure of config concerns. */
78
+ export function npmUninstallFromHost(dir, packageName) {
79
+ try {
80
+ execFileSync('npm', ['uninstall', packageName], {
81
+ cwd: dir,
82
+ stdio: ['ignore', process.stderr, process.stderr],
83
+ });
84
+ return true;
85
+ }
86
+ catch {
87
+ return false;
88
+ }
89
+ }
90
+ /** Remove a Tool plugin from its host dir (user-global by default, --project otherwise). */
91
+ export function removeToolPlugin(packageName, cwd, project) {
92
+ const dir = project
93
+ ? resolveProjectPaths(cwd).pluginsDir(TOOL_DOMAIN)
94
+ : resolveUserPaths().pluginsDir(TOOL_DOMAIN);
95
+ if (!existsSync(join(dir, HOST_PACKAGE_JSON))) {
96
+ return {
97
+ type: PLUGIN_REMOVE,
98
+ packageName,
99
+ success: false,
100
+ error: `No tool plugins installed in ${dir}`,
101
+ };
102
+ }
103
+ if (!npmUninstallFromHost(dir, packageName)) {
104
+ return {
105
+ type: PLUGIN_REMOVE,
106
+ packageName,
107
+ success: false,
108
+ error: `Failed to remove ${packageName}`,
109
+ };
110
+ }
111
+ // No config entry to clean up — tool plugins auto-discover by marker.
112
+ return { type: PLUGIN_REMOVE, packageName, success: true };
113
+ }
114
+ //# sourceMappingURL=plugin-host-ops.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin-host-ops.js","sourceRoot":"","sources":["../../src/commands/plugin-host-ops.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * plugin command — manage project-local npm-installed plugins.
3
+ *
4
+ * Layout (no user-global plugin dir):
5
+ *
6
+ * <project>/opensip-cli/.runtime/plugins/<domain>/
7
+ * ├── package.json — host package; "dependencies" is the
8
+ * │ plugin install state for this domain
9
+ * └── node_modules/ — npm-installed plugin packages
10
+ *
11
+ * <project>/opensip-cli.config.yml
12
+ * plugins:
13
+ * fit:
14
+ * - "@org/fitness-checks" — declares which installed packages
15
+ * discovery should LOAD. Required;
16
+ * discovery does not auto-load every
17
+ * installed package (silent loads
18
+ * would surprise users).
19
+ *
20
+ * `plugin add <pkg>` is the one-step install: writes the package to
21
+ * .runtime/plugins/<domain>/node_modules AND adds it to plugins.<domain>
22
+ * in the project config. After: `opensip fit` loads it on next run.
23
+ *
24
+ * `plugin remove <pkg>` is the inverse: removes from node_modules AND
25
+ * deletes from plugins.<domain>.
26
+ *
27
+ * `plugin list` walks .runtime/plugins/<domain>/node_modules + the
28
+ * config to show what's installed and what's currently loaded.
29
+ *
30
+ * `plugin sync` is the post-clone bootstrap: reads plugins.<domain> from
31
+ * the config and `npm install`s everything declared. Used by CI and
32
+ * by users who clone a repo with custom plugins.
33
+ *
34
+ * Module layout
35
+ * -------------
36
+ * - This file owns the `plugin {list,add,remove,sync}` command bodies.
37
+ * - `plugin/config-edit.ts` — YAML round-trip edits to plugins.<domain>.
38
+ * - `plugin/domain-resolution.ts` — TOOL_DOMAIN + the pure validation
39
+ * logic that routes a spec to a domain / Tool host dir (no install).
40
+ * - `plugin/host-dir.ts` — host package.json creation + installed-
41
+ * package introspection (incl. peer-dependency auto-install).
42
+ */
43
+ import { type PluginLayout, type ToolProvenance } from '@opensip-cli/core';
44
+ import { editPluginList } from './plugin-host-ops.js';
45
+ import type { PluginResult } from '@opensip-cli/contracts';
46
+ /** Options shared by `plugin add`/`remove` for Tool-plugin scope selection. */
47
+ export interface PluginScopeOpts {
48
+ /** Install/remove a Tool plugin in the project-local host dir instead of user-global. */
49
+ readonly project?: boolean;
50
+ }
51
+ /**
52
+ * Test-only export for the YAML-driven config edit so unit tests can
53
+ * exercise the round-trip behaviour without spawning npm. Intentionally
54
+ * not part of the public CLI API surface.
55
+ */
56
+ export declare const __test: {
57
+ editPluginList: typeof editPluginList;
58
+ };
59
+ export declare function pluginList(cwd?: string, layouts?: readonly PluginLayout[], toolProvenance?: readonly ToolProvenance[]): Promise<PluginResult>;
60
+ /**
61
+ * Install a plugin AND add it to the project config in one step.
62
+ *
63
+ * Without the config update, the package wouldn't get loaded — making
64
+ * "install" alone always incomplete. Single-step is the only sensible
65
+ * default.
66
+ */
67
+ export declare function pluginAdd(packageName: string | undefined, cwd?: string, domainOverride?: string, layouts?: readonly PluginLayout[], scope?: PluginScopeOpts): Promise<PluginResult>;
68
+ export declare function pluginRemove(packageName: string | undefined, cwd?: string, domainOverride?: string, layouts?: readonly PluginLayout[], scope?: PluginScopeOpts): Promise<PluginResult>;
69
+ /**
70
+ * Install every plugin declared in `plugins.<domain>` for a given
71
+ * domain (or all domains when none specified). Idempotent — re-running
72
+ * after `git pull` updates the install state.
73
+ *
74
+ * The post-clone story: a developer clones a repo with declared
75
+ * plugins, runs `opensip plugin sync`, and the
76
+ * .runtime/plugins/<domain>/node_modules trees are populated. Without
77
+ * this, the first `opensip fit` would warn about every declared
78
+ * plugin being uninstalled.
79
+ */
80
+ export declare function pluginSync(cwd?: string, domainOverride?: string, layouts?: readonly PluginLayout[]): Promise<PluginResult>;
81
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/commands/plugin.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AAMH,OAAO,EAKL,KAAK,YAAY,EACjB,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AAU3B,OAAO,EAEL,cAAc,EAIf,MAAM,sBAAsB,CAAC;AAE9B,OAAO,KAAK,EAAc,YAAY,EAAa,MAAM,wBAAwB,CAAC;AAUlF,+EAA+E;AAC/E,MAAM,WAAW,eAAe;IAC9B,yFAAyF;IACzF,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM;;CAAqB,CAAC;AAMzC,wBAAsB,UAAU,CAC9B,GAAG,GAAE,MAAsB,EAC3B,OAAO,GAAE,SAAS,YAAY,EAAO,EAGrC,cAAc,GAAE,SAAS,cAAc,EAAO,GAC7C,OAAO,CAAC,YAAY,CAAC,CA2CvB;AAUD;;;;;;GAMG;AAEH,wBAAsB,SAAS,CAC7B,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,GAAG,GAAE,MAAsB,EAC3B,cAAc,CAAC,EAAE,MAAM,EACvB,OAAO,GAAE,SAAS,YAAY,EAAO,EACrC,KAAK,GAAE,eAAoB,GAC1B,OAAO,CAAC,YAAY,CAAC,CA6CvB;AAOD,wBAAsB,YAAY,CAChC,WAAW,EAAE,MAAM,GAAG,SAAS,EAC/B,GAAG,GAAE,MAAsB,EAC3B,cAAc,CAAC,EAAE,MAAM,EACvB,OAAO,GAAE,SAAS,YAAY,EAAO,EACrC,KAAK,GAAE,eAAoB,GAC1B,OAAO,CAAC,YAAY,CAAC,CA0DvB;AAMD;;;;;;;;;;GAUG;AAKH,wBAAsB,UAAU,CAC9B,GAAG,GAAE,MAAsB,EAC3B,cAAc,CAAC,EAAE,MAAM,EACvB,OAAO,GAAE,SAAS,YAAY,EAAO,GACpC,OAAO,CAAC,YAAY,CAAC,CA4CvB"}