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,69 @@
1
+ /**
2
+ * owning-tool-init — resolve the tool that owns the invoked subcommand and run
3
+ * its lazy, once-per-process `Tool.initialize()`.
4
+ *
5
+ * Extracted from `pre-action-hook.ts` so that hook stays the high-level
6
+ * per-invocation SEQUENCER; the owning-tool resolution + fail-fast init
7
+ * semantics live here as a cohesive unit (see also `tool-lifecycle.ts`).
8
+ */
9
+ import { logger } from '@opensip-cli/core';
10
+ import { BootstrapError } from './bootstrap-error.js';
11
+ import { initializedToolIds } from './process-idempotency.js';
12
+ const MODULE_TAG = 'cli:bootstrap';
13
+ /**
14
+ * Find the registered tool that owns the invoked subcommand, matching the
15
+ * descriptor's canonical name or any alias. Returns undefined for
16
+ * CLI-only commands (init/sessions/configure/plugin/...) — they belong to
17
+ * no tool, so no `initialize()` runs for them.
18
+ */
19
+ export function resolveOwningTool(tools, cmdName) {
20
+ return tools
21
+ .list()
22
+ .find((tool) => tool.commands.some((c) => c.name === cmdName || (c.aliases?.includes(cmdName) ?? false)));
23
+ }
24
+ /**
25
+ * Lazy, memoized Tool.initialize() (P1a). Resolve the tool owning the
26
+ * invoked subcommand and run its initialize() exactly once per process,
27
+ * after the scope is entered and immediately before the action body. Tools
28
+ * not invoked this run pay nothing; `--help`/welcome run no initialize().
29
+ *
30
+ * Fail-fast: a throwing initialize() fails the run closed rather than letting a
31
+ * half-initialised tool run its command and silently appear to work. The
32
+ * id is recorded only on success, so a transient failure can retry in a
33
+ * long-lived host.
34
+ *
35
+ * @throws {BootstrapError} (exit 1) when the owning tool's initialize() throws —
36
+ * the top-level boundary renders it (human stderr / structured `--json`).
37
+ */
38
+ export async function maybeInitializeOwningTool(tools, cmdName, runId) {
39
+ const owningTool = resolveOwningTool(tools, cmdName);
40
+ if (!owningTool?.initialize)
41
+ return;
42
+ const toolHumanId = owningTool.metadata.name ?? owningTool.metadata.id;
43
+ if (initializedToolIds.has(toolHumanId))
44
+ return;
45
+ try {
46
+ await owningTool.initialize();
47
+ initializedToolIds.add(toolHumanId);
48
+ }
49
+ catch (error) {
50
+ const msg = error instanceof Error ? error.message : String(error);
51
+ logger.error({
52
+ evt: 'cli.tool.initialize_failed',
53
+ module: MODULE_TAG,
54
+ runId,
55
+ toolId: owningTool.metadata.id, // stable UUID for structured
56
+ toolName: toolHumanId,
57
+ error: msg,
58
+ });
59
+ // §4.7: a tool-init failure becomes a typed BootstrapError (exit 1) the
60
+ // top-level boundary renders, instead of an inline stderr write + exit.
61
+ throw new BootstrapError({
62
+ message: `Tool '${toolHumanId}' failed to initialize: ${msg}`,
63
+ humanMessage: `✗ Tool '${toolHumanId}' failed to initialize: ${msg}`,
64
+ suggestion: undefined,
65
+ exitCode: 1,
66
+ });
67
+ }
68
+ }
69
+ //# sourceMappingURL=owning-tool-init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"owning-tool-init.js","sourceRoot":"","sources":["../../src/bootstrap/owning-tool-init.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,EAAgC,MAAM,mBAAmB,CAAC;AAEzE,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE9D,MAAM,UAAU,GAAG,eAAe,CAAC;AAEnC;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAmB,EAAE,OAAe;IACpE,OAAO,KAAK;SACT,IAAI,EAAE;SACN,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CACb,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,KAAK,CAAC,CAAC,CACzF,CAAC;AACN,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,yBAAyB,CAC7C,KAAmB,EACnB,OAAe,EACf,KAAa;IAEb,MAAM,UAAU,GAAG,iBAAiB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACrD,IAAI,CAAC,UAAU,EAAE,UAAU;QAAE,OAAO;IACpC,MAAM,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAC,IAAI,IAAI,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;IACvE,IAAI,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC;QAAE,OAAO;IAChD,IAAI,CAAC;QACH,MAAM,UAAU,CAAC,UAAU,EAAE,CAAC;QAC9B,kBAAkB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACtC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnE,MAAM,CAAC,KAAK,CAAC;YACX,GAAG,EAAE,4BAA4B;YACjC,MAAM,EAAE,UAAU;YAClB,KAAK;YACL,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE,EAAE,6BAA6B;YAC7D,QAAQ,EAAE,WAAW;YACrB,KAAK,EAAE,GAAG;SACX,CAAC,CAAC;QACH,wEAAwE;QACxE,wEAAwE;QACxE,MAAM,IAAI,cAAc,CAAC;YACvB,OAAO,EAAE,SAAS,WAAW,2BAA2B,GAAG,EAAE;YAC7D,YAAY,EAAE,WAAW,WAAW,2BAA2B,GAAG,EAAE;YACpE,UAAU,EAAE,SAAS;YACrB,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
@@ -0,0 +1,44 @@
1
+ /**
2
+ * pre-action-guards — the pure bailout / warning guards the bootstrap
3
+ * `preAction` hook runs inside its decision window, BEFORE any side effect
4
+ * fires (see `pre-action-hook.ts` for the load-bearing ordering).
5
+ *
6
+ * Extracted from `pre-action-hook.ts` as a cohesive unit: each guard is a
7
+ * `(project, …) => void` that either exits the process with an actionable
8
+ * message (schema-too-old, no-project) or warns to stderr (phantom runtimes),
9
+ * and nothing else. Housing them here keeps the hook module focused on the
10
+ * orchestration sequence and the per-tool `initialize()` lifecycle.
11
+ */
12
+ import { type ProjectContext } from '@opensip-cli/core';
13
+ /**
14
+ * Schema-version bailout. THROWS a {@link BootstrapError} (exit 2) with the
15
+ * "upgrade your CLI" message when the project config declares a schema newer than
16
+ * this CLI knows. Direction-correct: `migrate` would go the other way (old → new);
17
+ * when the CLI itself is behind, the user must upgrade it. The top-level boundary
18
+ * renders it (human stderr / structured `--json`); this guard no longer writes or
19
+ * exits (§4.7).
20
+ *
21
+ * @throws {BootstrapError} (exit 2) when the project config's schema is newer than
22
+ * this CLI supports — the boundary renders the "upgrade your CLI" message.
23
+ */
24
+ export declare function checkSchemaVersionAndBailout(project: ProjectContext, runId: string): void;
25
+ /**
26
+ * No-project-found bailout. THROWS a {@link BootstrapError} (exit 2) for
27
+ * project-scoped commands when discovery resolved scope === 'none'. The top-level
28
+ * boundary renders it: human mode writes the unchanged multi-line explainer to
29
+ * stderr; `--json` emits a structured `bootstrap.error` outcome (§4.7). The guard
30
+ * no longer branches on json or writes a stream itself.
31
+ *
32
+ * @throws {BootstrapError} (exit 2) when a project-scoped command runs with no
33
+ * discoverable opensip-cli project (scope === 'none').
34
+ */
35
+ export declare function checkNoProjectAndBailout(project: ProjectContext, cwd: string, cmdName: string, runId: string, extraAgnostic?: ReadonlySet<string>): void;
36
+ /**
37
+ * Phantom-runtime warning. Detects orphaned opensip-cli/.runtime/
38
+ * subtrees between cwd and the discovered project root — fossils from
39
+ * pre-discovery runs that scaffolded under subdirs. Warns to stderr
40
+ * with a safe `rm -rf` hint; never auto-deletes. Suppressed for JSON
41
+ * output (would corrupt the stream's stderr peer in some tools).
42
+ */
43
+ export declare function warnAboutPhantomRuntimes(project: ProjectContext, jsonOutput: boolean): void;
44
+ //# sourceMappingURL=pre-action-guards.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pre-action-guards.d.ts","sourceRoot":"","sources":["../../src/bootstrap/pre-action-guards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAKL,KAAK,cAAc,EACpB,MAAM,mBAAmB,CAAC;AA+B3B;;;;;;;;;;GAUG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAmCzF;AAED;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,cAAc,EACvB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,aAAa,GAAE,WAAW,CAAC,MAAM,CAAa,GAC7C,IAAI,CAgBN;AAED;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,cAAc,EAAE,UAAU,EAAE,OAAO,GAAG,IAAI,CAa3F"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * pre-action-guards — the pure bailout / warning guards the bootstrap
3
+ * `preAction` hook runs inside its decision window, BEFORE any side effect
4
+ * fires (see `pre-action-hook.ts` for the load-bearing ordering).
5
+ *
6
+ * Extracted from `pre-action-hook.ts` as a cohesive unit: each guard is a
7
+ * `(project, …) => void` that either exits the process with an actionable
8
+ * message (schema-too-old, no-project) or warns to stderr (phantom runtimes),
9
+ * and nothing else. Housing them here keeps the hook module focused on the
10
+ * orchestration sequence and the per-tool `initialize()` lifecycle.
11
+ */
12
+ import { checkSchemaCompat, detectPhantomRuntimes, logger, readConfigSchemaVersion, } from '@opensip-cli/core';
13
+ import { BootstrapError } from './bootstrap-error.js';
14
+ import { formatCliTooOldMessage, formatNoProjectFoundMessage } from './pre-action-messages.js';
15
+ const MODULE_TAG = 'cli:bootstrap';
16
+ /**
17
+ * Commands that operate WITHOUT requiring a project context. These don't
18
+ * read project files or the datastore; running them from a directory
19
+ * with no opensip-cli project is legitimate.
20
+ *
21
+ * Everything else is project-scoped: when `project.scope === 'none'`,
22
+ * the hook emits the "No OpenSIP CLI project found" error and exits 2.
23
+ *
24
+ * Note: `uninstall --user` is project-agnostic, but `uninstall --project`
25
+ * requires one. The check is per-command name here; uninstall's own
26
+ * mode-specific guarding lives in its action body.
27
+ *
28
+ * The base list covers pure host commands. Tool CommandSpecs that declare
29
+ * `scope: 'none'` are added dynamically at runtime (see pre-action-hook)
30
+ * so the declared `CommandSpec.scope` actually controls behavior (previously
31
+ * this list was the only source of truth, making the field dead for tools).
32
+ */
33
+ const PROJECT_AGNOSTIC_COMMANDS = new Set([
34
+ 'init',
35
+ 'configure',
36
+ 'completion',
37
+ 'uninstall',
38
+ ]);
39
+ /**
40
+ * Schema-version bailout. THROWS a {@link BootstrapError} (exit 2) with the
41
+ * "upgrade your CLI" message when the project config declares a schema newer than
42
+ * this CLI knows. Direction-correct: `migrate` would go the other way (old → new);
43
+ * when the CLI itself is behind, the user must upgrade it. The top-level boundary
44
+ * renders it (human stderr / structured `--json`); this guard no longer writes or
45
+ * exits (§4.7).
46
+ *
47
+ * @throws {BootstrapError} (exit 2) when the project config's schema is newer than
48
+ * this CLI supports — the boundary renders the "upgrade your CLI" message.
49
+ */
50
+ export function checkSchemaVersionAndBailout(project, runId) {
51
+ if (project.scope !== 'project' || project.configPath === undefined)
52
+ return;
53
+ const configVersion = readConfigSchemaVersion(project.configPath);
54
+ const compat = checkSchemaCompat(configVersion);
55
+ if (compat.kind === 'cli-too-old') {
56
+ const msg = formatCliTooOldMessage({
57
+ root: project.projectRoot,
58
+ configVersion: compat.configVersion,
59
+ cliVersion: compat.cliVersion,
60
+ });
61
+ logger.warn({
62
+ evt: 'cli.config.schema.cli-too-old',
63
+ module: MODULE_TAG,
64
+ runId,
65
+ root: project.projectRoot,
66
+ configVersion: compat.configVersion,
67
+ cliVersion: compat.cliVersion,
68
+ });
69
+ throw new BootstrapError({
70
+ message: `This project's opensip-cli.config.yml uses a newer schema (v${compat.configVersion}) than this CLI supports (v${compat.cliVersion}).`,
71
+ humanMessage: msg,
72
+ suggestion: 'Update your CLI: curl -fsSL https://opensip.ai/cli/install.sh | bash',
73
+ exitCode: 2,
74
+ });
75
+ }
76
+ if (compat.kind === 'older') {
77
+ logger.info({
78
+ evt: 'cli.config.schema.older',
79
+ module: MODULE_TAG,
80
+ runId,
81
+ root: project.projectRoot,
82
+ configVersion: compat.configVersion,
83
+ cliVersion: compat.cliVersion,
84
+ });
85
+ }
86
+ }
87
+ /**
88
+ * No-project-found bailout. THROWS a {@link BootstrapError} (exit 2) for
89
+ * project-scoped commands when discovery resolved scope === 'none'. The top-level
90
+ * boundary renders it: human mode writes the unchanged multi-line explainer to
91
+ * stderr; `--json` emits a structured `bootstrap.error` outcome (§4.7). The guard
92
+ * no longer branches on json or writes a stream itself.
93
+ *
94
+ * @throws {BootstrapError} (exit 2) when a project-scoped command runs with no
95
+ * discoverable opensip-cli project (scope === 'none').
96
+ */
97
+ export function checkNoProjectAndBailout(project, cwd, cmdName, runId, extraAgnostic = new Set()) {
98
+ const effective = new Set([...PROJECT_AGNOSTIC_COMMANDS, ...extraAgnostic]);
99
+ if (project.scope !== 'none' || effective.has(cmdName))
100
+ return;
101
+ logger.warn({
102
+ evt: 'cli.project.not-found',
103
+ module: MODULE_TAG,
104
+ runId,
105
+ cwd,
106
+ command: cmdName,
107
+ });
108
+ throw new BootstrapError({
109
+ message: `No opensip-cli.config.yml found. Searched from ${cwd} upward.`,
110
+ humanMessage: formatNoProjectFoundMessage(cwd),
111
+ suggestion: 'Run opensip init to get started.',
112
+ exitCode: 2,
113
+ });
114
+ }
115
+ /**
116
+ * Phantom-runtime warning. Detects orphaned opensip-cli/.runtime/
117
+ * subtrees between cwd and the discovered project root — fossils from
118
+ * pre-discovery runs that scaffolded under subdirs. Warns to stderr
119
+ * with a safe `rm -rf` hint; never auto-deletes. Suppressed for JSON
120
+ * output (would corrupt the stream's stderr peer in some tools).
121
+ */
122
+ export function warnAboutPhantomRuntimes(project, jsonOutput) {
123
+ if (jsonOutput)
124
+ return;
125
+ if (project.scope !== 'project' || project.walkedUp === 0)
126
+ return;
127
+ const phantoms = detectPhantomRuntimes(project.cwd, project.projectRoot);
128
+ for (const phantom of phantoms) {
129
+ process.stderr.write(`ℹ Detected an orphaned opensip-cli/ at:\n` +
130
+ ` ${phantom}\n` +
131
+ ` Left over from running opensip from this subdirectory\n` +
132
+ ` before project-root discovery was added. Safe to delete with:\n` +
133
+ ` rm -rf ${phantom}\n\n`);
134
+ }
135
+ }
136
+ //# sourceMappingURL=pre-action-guards.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pre-action-guards.js","sourceRoot":"","sources":["../../src/bootstrap/pre-action-guards.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,MAAM,EACN,uBAAuB,GAExB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAE/F,MAAM,UAAU,GAAG,eAAe,CAAC;AAEnC;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,yBAAyB,GAAwB,IAAI,GAAG,CAAC;IAC7D,MAAM;IACN,WAAW;IACX,YAAY;IACZ,WAAW;CACZ,CAAC,CAAC;AAEH;;;;;;;;;;GAUG;AACH,MAAM,UAAU,4BAA4B,CAAC,OAAuB,EAAE,KAAa;IACjF,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,UAAU,KAAK,SAAS;QAAE,OAAO;IAC5E,MAAM,aAAa,GAAG,uBAAuB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAClE,MAAM,MAAM,GAAG,iBAAiB,CAAC,aAAa,CAAC,CAAC;IAChD,IAAI,MAAM,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;QAClC,MAAM,GAAG,GAAG,sBAAsB,CAAC;YACjC,IAAI,EAAE,OAAO,CAAC,WAAW;YACzB,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,UAAU,EAAE,MAAM,CAAC,UAAU;SAC9B,CAAC,CAAC;QACH,MAAM,CAAC,IAAI,CAAC;YACV,GAAG,EAAE,+BAA+B;YACpC,MAAM,EAAE,UAAU;YAClB,KAAK;YACL,IAAI,EAAE,OAAO,CAAC,WAAW;YACzB,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,UAAU,EAAE,MAAM,CAAC,UAAU;SAC9B,CAAC,CAAC;QACH,MAAM,IAAI,cAAc,CAAC;YACvB,OAAO,EAAE,+DAA+D,MAAM,CAAC,aAAa,8BAA8B,MAAM,CAAC,UAAU,IAAI;YAC/I,YAAY,EAAE,GAAG;YACjB,UAAU,EAAE,sEAAsE;YAClF,QAAQ,EAAE,CAAC;SACZ,CAAC,CAAC;IACL,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC5B,MAAM,CAAC,IAAI,CAAC;YACV,GAAG,EAAE,yBAAyB;YAC9B,MAAM,EAAE,UAAU;YAClB,KAAK;YACL,IAAI,EAAE,OAAO,CAAC,WAAW;YACzB,aAAa,EAAE,MAAM,CAAC,aAAa;YACnC,UAAU,EAAE,MAAM,CAAC,UAAU;SAC9B,CAAC,CAAC;IACL,CAAC;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CACtC,OAAuB,EACvB,GAAW,EACX,OAAe,EACf,KAAa,EACb,gBAAqC,IAAI,GAAG,EAAE;IAE9C,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,yBAAyB,EAAE,GAAG,aAAa,CAAC,CAAC,CAAC;IAC5E,IAAI,OAAO,CAAC,KAAK,KAAK,MAAM,IAAI,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC;QAAE,OAAO;IAC/D,MAAM,CAAC,IAAI,CAAC;QACV,GAAG,EAAE,uBAAuB;QAC5B,MAAM,EAAE,UAAU;QAClB,KAAK;QACL,GAAG;QACH,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IACH,MAAM,IAAI,cAAc,CAAC;QACvB,OAAO,EAAE,kDAAkD,GAAG,UAAU;QACxE,YAAY,EAAE,2BAA2B,CAAC,GAAG,CAAC;QAC9C,UAAU,EAAE,kCAAkC;QAC9C,QAAQ,EAAE,CAAC;KACZ,CAAC,CAAC;AACL,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,wBAAwB,CAAC,OAAuB,EAAE,UAAmB;IACnF,IAAI,UAAU;QAAE,OAAO;IACvB,IAAI,OAAO,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,QAAQ,KAAK,CAAC;QAAE,OAAO;IAClE,MAAM,QAAQ,GAAG,qBAAqB,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IACzE,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;QAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,2CAA2C;YACzC,OAAO,OAAO,IAAI;YAClB,2DAA2D;YAC3D,mEAAmE;YACnE,cAAc,OAAO,MAAM,CAC9B,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,68 @@
1
+ /**
2
+ * pre-action-hook — Commander `preAction` body.
3
+ *
4
+ * Runs before every subcommand's action. Centralises run-id generation,
5
+ * config-merge, project-context resolution, schema-version bailout, and
6
+ * (only when the run will proceed) log file initialisation. Datastore is
7
+ * NOT opened here — that's a lazy getter on ToolCliContext (Task 1.3).
8
+ *
9
+ * Ordering is load-bearing: side effects only fire AFTER all bailout
10
+ * decisions. Sequence:
11
+ *
12
+ * 1. generate runId
13
+ * 2. read opts; resolve project context (pure; may throw on strict --config)
14
+ * 3. expose context on opts.projectContext (collision-free name)
15
+ * 4. bailout window — schema check (Phase 6.3), phantom warn (Phase 7)
16
+ * 5. side-effect setup — configureLogger({ logDir }) + setProjectContextForRun
17
+ * gated on project.scope === 'project' && existsSync(projectRoot)
18
+ * 6. Project: header (Phase 2.2)
19
+ * 7. cli.start log line
20
+ * 8. lazy Tool.initialize() — run the owning tool's optional one-time
21
+ * init exactly once per process, after the scope is entered and just
22
+ * before the action body (P1a). CLI-only commands have no owner and
23
+ * skip it; a failing init is fatal.
24
+ *
25
+ * Strict --config: when `--config <path>` doesn't resolve, the
26
+ * underlying ValidationError surfaces with exit 2 — no silent walk-up.
27
+ */
28
+ import { type LanguageRegistry, type ToolPluginManifest, type ToolProvenance, type ToolRegistry } from '@opensip-cli/core';
29
+ import type { Command } from 'commander';
30
+ export { resolveOwningTool } from './owning-tool-init.js';
31
+ /**
32
+ * The `scope.configDocument` slot value (ADR-0023 one-reader): the validated
33
+ * document rides the scope so tools project their shapes from it instead of
34
+ * re-reading the file — but ONLY when a real config file was read. A
35
+ * config-less run stays document-less so tools that hard-error on a missing
36
+ * config (fitness) stay loud instead of silently validating `{}`.
37
+ */
38
+ /**
39
+ * The per-invocation bootstrap result the hook needs to BUILD the scope —
40
+ * the populated registries plus the admitted-tool manifests/provenance. These
41
+ * are created in `main()` BEFORE the scope can be constructed (the registries
42
+ * are inputs to `RunScope`; you can't read them off a scope that doesn't exist
43
+ * yet), so the composition root captures them in this closure and hands them to
44
+ * `installPreActionHook`. After the hook calls `enterScope`, every per-run read
45
+ * (project, datastore, manifests, provenance, …) goes through `currentScope()`
46
+ * — there is NO module-global handoff bag (the former `currentRuntimeContext`).
47
+ */
48
+ export interface PreActionRuntime {
49
+ readonly languages: LanguageRegistry;
50
+ readonly tools: ToolRegistry;
51
+ readonly manifests: readonly ToolPluginManifest[];
52
+ readonly provenance: readonly ToolProvenance[];
53
+ }
54
+ /**
55
+ * Mount the bootstrap `preAction` hook on the supplied program.
56
+ *
57
+ * @param program The root Commander program.
58
+ * @param version The CLI version (from `readPackageVersion` at the entry
59
+ * point). Threaded in rather than re-read here so the `mini` banner shows
60
+ * the SAME version `--version` reports — and so the kernel-adjacent hook
61
+ * doesn't resolve cli-ui's or its own package version by mistake.
62
+ * @param runtime The bootstrap result (registries + admitted manifests/
63
+ * provenance). Captured in the hook closure instead of read from a module
64
+ * global — the composition root installs the hook AFTER `bootstrapCli`
65
+ * populates the registries (see {@link PreActionRuntime}).
66
+ */
67
+ export declare function installPreActionHook(program: Command, version: string, runtime: PreActionRuntime): void;
68
+ //# sourceMappingURL=pre-action-hook.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pre-action-hook.d.ts","sourceRoot":"","sources":["../../src/bootstrap/pre-action-hook.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAIH,OAAO,EASL,KAAK,gBAAgB,EAErB,KAAK,kBAAkB,EACvB,KAAK,cAAc,EACnB,KAAK,YAAY,EAClB,MAAM,mBAAmB,CAAC;AAiB3B,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWzC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D;;;;;;GAMG;AAEH;;;;;;;;;GASG;AACH,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAC;IACrC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,QAAQ,CAAC,SAAS,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAClD,QAAQ,CAAC,UAAU,EAAE,SAAS,cAAc,EAAE,CAAC;CAChD;AAED;;;;;;;;;;;;GAYG;AAUH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,gBAAgB,GACxB,IAAI,CAqPN"}
@@ -0,0 +1,289 @@
1
+ // @fitness-ignore-file detached-promises -- the preAction hook is a composition root: its body invokes synchronous bootstrap helpers (mergeConfigDefaults, configureLogger, the checkSchemaVersion/checkNoProject/warnAboutPhantom bailout guards, enterScope) that the name-based heuristic mistakes for promise-returning calls. The one genuine async call (maybeInitializeOwningTool) is awaited. Matches the same suppression on index.ts and bootstrap/index.ts.
2
+ /**
3
+ * pre-action-hook — Commander `preAction` body.
4
+ *
5
+ * Runs before every subcommand's action. Centralises run-id generation,
6
+ * config-merge, project-context resolution, schema-version bailout, and
7
+ * (only when the run will proceed) log file initialisation. Datastore is
8
+ * NOT opened here — that's a lazy getter on ToolCliContext (Task 1.3).
9
+ *
10
+ * Ordering is load-bearing: side effects only fire AFTER all bailout
11
+ * decisions. Sequence:
12
+ *
13
+ * 1. generate runId
14
+ * 2. read opts; resolve project context (pure; may throw on strict --config)
15
+ * 3. expose context on opts.projectContext (collision-free name)
16
+ * 4. bailout window — schema check (Phase 6.3), phantom warn (Phase 7)
17
+ * 5. side-effect setup — configureLogger({ logDir }) + setProjectContextForRun
18
+ * gated on project.scope === 'project' && existsSync(projectRoot)
19
+ * 6. Project: header (Phase 2.2)
20
+ * 7. cli.start log line
21
+ * 8. lazy Tool.initialize() — run the owning tool's optional one-time
22
+ * init exactly once per process, after the scope is entered and just
23
+ * before the action body (P1a). CLI-only commands have no owner and
24
+ * skip it; a failing init is fatal.
25
+ *
26
+ * Strict --config: when `--config <path>` doesn't resolve, the
27
+ * underlying ValidationError surfaces with exit 2 — no silent walk-up.
28
+ */
29
+ import { existsSync } from 'node:fs';
30
+ import { configureLogger, currentScope, enterScope, generatePrefixedId, logger, resolveProjectContext, resolveProjectPaths, SystemError, } from '@opensip-cli/core';
31
+ import { getMeter } from '@opensip-cli/core';
32
+ import { startProfiling } from '../telemetry/profiling.js';
33
+ import { checkForUpdate, formatUpdateNag } from '../update-notifier.js';
34
+ import { BootstrapError } from './bootstrap-error.js';
35
+ import { buildPerRunScope } from './build-per-run-scope.js';
36
+ import { loadCliDefaults, mergeConfigDefaults } from './cli-defaults.js';
37
+ import { loadOwningToolCapabilities } from './load-tool-capabilities.js';
38
+ import { maybeInitializeOwningTool, resolveOwningTool } from './owning-tool-init.js';
39
+ import { checkNoProjectAndBailout, checkSchemaVersionAndBailout, warnAboutPhantomRuntimes, } from './pre-action-guards.js';
40
+ /** npm package whose version the update check compares against. */
41
+ const CLI_PACKAGE_NAME = 'opensip-cli';
42
+ const MODULE_TAG = 'cli:bootstrap';
43
+ // Owning-tool resolution + lazy `Tool.initialize()` live in `owning-tool-init.ts`
44
+ // (also imported below for local use). `resolveOwningTool` is re-exported so
45
+ // existing importers (e.g. the lifecycle test) keep their stable
46
+ // `pre-action-hook.js` entry point.
47
+ export { resolveOwningTool } from './owning-tool-init.js';
48
+ /**
49
+ * Mount the bootstrap `preAction` hook on the supplied program.
50
+ *
51
+ * @param program The root Commander program.
52
+ * @param version The CLI version (from `readPackageVersion` at the entry
53
+ * point). Threaded in rather than re-read here so the `mini` banner shows
54
+ * the SAME version `--version` reports — and so the kernel-adjacent hook
55
+ * doesn't resolve cli-ui's or its own package version by mistake.
56
+ * @param runtime The bootstrap result (registries + admitted manifests/
57
+ * provenance). Captured in the hook closure instead of read from a module
58
+ * global — the composition root installs the hook AFTER `bootstrapCli`
59
+ * populates the registries (see {@link PreActionRuntime}).
60
+ */
61
+ // The body (including the preAction hook arrow it registers) sequences the full
62
+ // per-invocation bootstrap: runId, defaults merge, project resolve + bailouts,
63
+ // scope construction/enter, metrics, profiling start, lazy tool init, capability
64
+ // drive. It has many explicit early-exit paths by design (the documented contract
65
+ // for "only side effects after all bailouts"). Cognitive complexity exceeds 15
66
+ // because it is the single source of truth for ordering; splitting would obscure
67
+ // the load-bearing sequence and duplicate the guard/enter wiring. Acceptable for
68
+ // this composition root (see similar disables on other bootstrap entry points).
69
+ /* eslint-disable sonarjs/cognitive-complexity -- single source of truth for scope construction/enter ordering; splitting would obscure the load-bearing sequence (rationale above) */
70
+ export function installPreActionHook(program, version, runtime) {
71
+ program.hook('preAction', async (_thisCommand, actionCommand) => {
72
+ const runId = generatePrefixedId('run');
73
+ const opts = actionCommand.opts();
74
+ const cwd = opts.cwd ?? process.cwd();
75
+ const cwdExplicit = actionCommand.getOptionValueSource('cwd') === 'cli';
76
+ // Keep the loaded defaults around: `mergeConfigDefaults` only copies the
77
+ // flag-shaped fields onto opts, but `ui.banner` has no flag — we read it
78
+ // straight off the config object below to build the UiContext.
79
+ const cliDefaults = loadCliDefaults(cwd, opts.config);
80
+ mergeConfigDefaults(opts, cliDefaults);
81
+ // Single bootstrap-time configuration of the process-wide logger
82
+ // singleton. Replaces the four prior free mutators (`setSilent`,
83
+ // `setDebugMode`, `setRunId`, `initLogFile`). `logDir` is wired in
84
+ // below once the project context is resolved — at that point the
85
+ // logsDir is known and we apply a second `configureLogger` to fill
86
+ // it in. The two-call sequence is intentional: silencing stderr
87
+ // before the project-resolve step is what makes Ink renders clean
88
+ // even when the project is missing.
89
+ configureLogger({
90
+ silent: true,
91
+ debugMode: Boolean(opts.debug),
92
+ runId,
93
+ });
94
+ // 2. Resolve the project context — pure, no side effects.
95
+ // Strict --config: throws ValidationError when explicit path misses.
96
+ let project;
97
+ try {
98
+ project = resolveProjectContext({
99
+ cwd,
100
+ cwdExplicit,
101
+ explicitConfigPath: opts.config,
102
+ });
103
+ }
104
+ catch (error) {
105
+ // §4.7: a config-resolve failure (e.g. strict --config miss) becomes a typed
106
+ // BootstrapError the top-level boundary renders — human stderr / structured
107
+ // --json — instead of an inline stderr write + process.exit.
108
+ const msg = error instanceof Error ? error.message : String(error);
109
+ throw new BootstrapError({
110
+ message: msg,
111
+ humanMessage: `✗ ${msg}`,
112
+ suggestion: 'Check opensip-cli.config.yml (or your --config path).',
113
+ exitCode: 2,
114
+ });
115
+ }
116
+ // 3. Stash the context on opts under the COLLISION-FREE name.
117
+ // `opts.project` is reserved for Commander's --project [path] flag
118
+ // in uninstall.ts; we never use that name here.
119
+ opts.projectContext = project;
120
+ // Stash the resolved "was --cwd typed on the CLI?" signal alongside it,
121
+ // so the `init` command-spec handler (launch Phase 6) reads ONE
122
+ // source instead of recomputing `getOptionValueSource('cwd')` on its own
123
+ // Commander command. `actionCommand` IS the init command here, so this is
124
+ // byte-identical to the former register-init computation.
125
+ opts.cwdExplicit = cwdExplicit;
126
+ // 4. Bailout window — each may THROW a BootstrapError (rendered by the
127
+ // top-level boundary) before any side effects. Phantom warn is non-fatal;
128
+ // warns then continues.
129
+ checkSchemaVersionAndBailout(project, runId);
130
+ // Build the effective set of project-agnostic command names from the base list
131
+ // PLUS any tool CommandSpecs that declare scope: 'none'. This makes the
132
+ // declared `CommandSpec.scope` drive enforcement (previously the hardcoded
133
+ // name list made the field dead for tools and third-party commands).
134
+ const extraAgnostic = new Set();
135
+ for (const tool of runtime.tools.list()) {
136
+ for (const c of tool.commands || []) {
137
+ if (c.scope === 'none') {
138
+ extraAgnostic.add(c.name);
139
+ (c.aliases ?? []).forEach((a) => extraAgnostic.add(a));
140
+ }
141
+ }
142
+ }
143
+ checkNoProjectAndBailout(project, cwd, actionCommand.name(), runId, extraAgnostic);
144
+ warnAboutPhantomRuntimes(project, opts.json === true);
145
+ // 5. Side-effect setup, gated on a real project being present.
146
+ if (project.scope === 'project' && existsSync(project.projectRoot)) {
147
+ const projectPaths = resolveProjectPaths(project.projectRoot);
148
+ // Second configureLogger call — fills in the project-scoped logDir
149
+ // now that the project context is resolved. Leaves silent/debugMode/runId
150
+ // untouched (configureLogger only writes fields present in the bag).
151
+ configureLogger({ logDir: projectPaths.logsDir });
152
+ }
153
+ // Build the per-run RunScope and enter it via AsyncLocalStorage so
154
+ // library functions deep in the call tree (currentScope() readers)
155
+ // see the bound logger/registries/project + a lazy datastore thunk.
156
+ // enterWith propagates forward through the same async chain, so the
157
+ // action body invoked after this hook sees the same scope without
158
+ // needing a callback wrapper — which Commander does not expose.
159
+ // (Phase 5 deferred Task 5.2 / T1 Item D close-out.)
160
+ // Resolve presentation + update state once, before the scope is built.
161
+ // bannerSize: explicit `cli.ui.banner`, else the product default `mini`.
162
+ // update: the cached newer-version string (best-effort; undefined when
163
+ // up-to-date / opted-out / non-TTY). The `mini` banner shows it inline;
164
+ // other sizes — and the banner-less `--json` path — fall back to the
165
+ // stderr nag so the signal is never silently lost.
166
+ const bannerSize = cliDefaults.ui?.banner ?? 'mini';
167
+ const update = checkForUpdate({ name: CLI_PACKAGE_NAME, version });
168
+ if (update && (bannerSize !== 'mini' || opts.json === true)) {
169
+ process.stderr.write(formatUpdateNag(version, update));
170
+ }
171
+ // ADR-0008: select the cloud signal sink for this run. Sync + cheap —
172
+ // keyless / `cloud.sync:false` / `--no-cloud` / non-https → no-op with no
173
+ // IO; the entitlement check is deferred to first emit so non-signal
174
+ // commands pay nothing. `opts.cloud === false` comes from `--no-cloud`.
175
+ //
176
+ // `cloud` layers the user-level opt-out (~/.opensip-cli/config.yml#cloud)
177
+ // over the project's `cli.cloud:` block (audit P0-2): a user `sync: false`
178
+ // disables sync for every project on this machine.
179
+ const { languages, tools, manifests, provenance } = runtime;
180
+ // Extracted to thin the composition root (GA architectural blocker #2).
181
+ // All scope construction + wiring now lives in a dedicated small builder
182
+ // with explicit inputs. The hook remains the high-level sequencer. The
183
+ // registries + admitted-tool manifests/provenance come from the closure
184
+ // the composition root captured (no module-global handoff bag); the
185
+ // builder stamps manifests/provenance onto the scope for host commands.
186
+ const scope = buildPerRunScope({
187
+ project,
188
+ runId,
189
+ cwd,
190
+ cliDefaults,
191
+ registries: { languages, tools },
192
+ manifests,
193
+ provenance,
194
+ apiKey: opts.apiKey,
195
+ // @fitness-ignore-next-line null-safety -- Commander's optsWithGlobals() always returns an OptionValues object (never null/undefined); the heuristic misreads the method-call-then-property access. `.cloud` is an absent-or-boolean flag, compared with `=== false`.
196
+ noCloud: actionCommand.optsWithGlobals().cloud === false,
197
+ logger,
198
+ ui: { version, update },
199
+ });
200
+ enterScope(scope);
201
+ // Phase 3 hygiene: scope entry via ALS (enterScope) is now the single source of truth
202
+ // for per-run state. No holder mirror or mark dance. All subsequent readers (including
203
+ // host command bodies) must see a valid currentScope().
204
+ if (!currentScope()) {
205
+ throw new SystemError('Scope was not entered before command dispatch', {
206
+ code: 'SYSTEM.SCOPE.NOT_ENTERED',
207
+ });
208
+ }
209
+ // Lifecycle diagnostics (§5.10): record key construction facts on the per-run bus.
210
+ // These (plus the per-domain events emitted from loadCapabilityDomain and the
211
+ // wiring events from buildPerRunScope) ride on every CommandOutcome so --json
212
+ // consumers see the full uniform lifecycle (tools loaded, subscopes contributed,
213
+ // capability domains wired + driven, config validated, etc.). This directly
214
+ // improves observability of the blast-radius bootstrap paths (architecture review).
215
+ scope.diagnostics.event('load', 'debug', `${tools.list().length} tool(s) loaded`);
216
+ scope.diagnostics.counter('tools.loaded', tools.list().length);
217
+ // Phase 2 metrics (low cardinality)
218
+ getMeter('opensip-cli').createCounter('opensip_cli.commands.started').add(1, {
219
+ command: actionCommand.name(),
220
+ });
221
+ scope.diagnostics.event('validate', 'debug', `project config resolved (scope: ${project.scope})`);
222
+ // The `ℹ Project:` location line is rendered once, under the banner,
223
+ // by cli-ui's ProjectHeader — mounted by the App shell (static
224
+ // commands, via render.ts reading currentScope().project) and by each
225
+ // live view (fit/graph). No imperative pre-action print.
226
+ // Structured start log.
227
+ logger.info({
228
+ evt: 'cli.run.start',
229
+ module: MODULE_TAG,
230
+ runId,
231
+ command: actionCommand.name(),
232
+ cwd,
233
+ projectRoot: project.projectRoot,
234
+ scope: project.scope,
235
+ });
236
+ if (project.walkedUp > 0) {
237
+ logger.info({
238
+ evt: 'cli.project.discovered',
239
+ module: MODULE_TAG,
240
+ runId,
241
+ cwd,
242
+ projectRoot: project.projectRoot,
243
+ walkedUp: project.walkedUp,
244
+ });
245
+ }
246
+ // Optional profiling (Phase 3, severable). Start after scope (runId available).
247
+ // Respects the dual-gate (OPENSIP_PROFILING + OTEL) or OTEL-only fallback.
248
+ startProfiling(scope, actionCommand.name());
249
+ // 8. Lazy, memoized Tool.initialize() — runs the owning tool's
250
+ // optional one-time init here, AFTER enterScope (so eager setup that
251
+ // registers packs / reads currentScope() sees the bound scope) and
252
+ // immediately before Commander invokes the action body. See the
253
+ // helper for the once-per-process + fail-fast semantics.
254
+ await maybeInitializeOwningTool(tools, actionCommand.name(), runId);
255
+ // 9. §5.3/§4.5: drive the generic capability loader for the invoked tool's
256
+ // declared domains (e.g. graph-adapter). Lazy per command — only the
257
+ // owning tool's domains load, routed through the host's capability
258
+ // registry to each owner's registrar. Replaces the host-coupled,
259
+ // eager register-graph-adapters.ts.
260
+ const driven = await loadOwningToolCapabilities({
261
+ owningTool: resolveOwningTool(tools, actionCommand.name()),
262
+ projectDir: project.projectRoot,
263
+ configPath: project.scope === 'project' ? project.configPath : undefined,
264
+ });
265
+ if (driven > 0) {
266
+ scope.diagnostics.event('load', 'debug', `drove ${String(driven)} owning-tool capability domain(s) (see per-domain 'capability ... loaded' events for contribution counts + errors)`);
267
+ scope.diagnostics.counter('capabilities.driven', driven);
268
+ }
269
+ });
270
+ // Resilience: best-effort release of per-run resources (parseCache, recipe config slot,
271
+ // contributed sub-scopes, diagnostics bus) after the action body completes for every
272
+ // command. Complements the narrow dispose() impl and the current lack of finally in
273
+ // many paths. postAction fires for normal completion; error paths are covered by
274
+ // handleParseError + handleFatalBootstrapError (which may also dispose in future passes).
275
+ // Idempotent: dispose is cheap and safe to call more than once.
276
+ program.hook('postAction', () => {
277
+ try {
278
+ const s = currentScope();
279
+ if (s && typeof s.dispose === 'function') {
280
+ s.dispose();
281
+ }
282
+ }
283
+ catch {
284
+ // @swallow-ok dispose errors on shutdown; the run has already produced its outcome.
285
+ }
286
+ });
287
+ }
288
+ /* eslint-enable sonarjs/cognitive-complexity */
289
+ //# sourceMappingURL=pre-action-hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pre-action-hook.js","sourceRoot":"","sources":["../../src/bootstrap/pre-action-hook.ts"],"names":[],"mappings":"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"}