@try-works/dsh-model-as-tool 0.1.3 → 0.4.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 (260) hide show
  1. package/bin/dsh-tool-mode-credentials.mjs +20 -0
  2. package/bin/dsh-tool-mode.mjs +202 -0
  3. package/catalog/desert-ant-models.json +693 -693
  4. package/client/client.model-tools.js +614 -0
  5. package/client/index.js +1717 -0
  6. package/lib/adapters/index.d.ts.map +1 -1
  7. package/lib/adapters/index.js +4 -4
  8. package/lib/bindings.d.ts.map +1 -1
  9. package/lib/bindings.js +26 -25
  10. package/lib/capability.d.ts.map +1 -1
  11. package/lib/capability.js +17 -0
  12. package/lib/capture-path.d.ts +97 -0
  13. package/lib/capture-path.d.ts.map +1 -0
  14. package/lib/capture-path.js +152 -0
  15. package/lib/diagnostics.d.ts +166 -0
  16. package/lib/diagnostics.d.ts.map +1 -0
  17. package/lib/diagnostics.js +135 -0
  18. package/lib/extension-dependencies.d.ts +325 -0
  19. package/lib/extension-dependencies.d.ts.map +1 -0
  20. package/lib/extension-dependencies.js +858 -0
  21. package/lib/extension-dispatch.d.ts +117 -0
  22. package/lib/extension-dispatch.d.ts.map +1 -0
  23. package/lib/extension-dispatch.js +124 -0
  24. package/lib/extension-registrar.d.ts +100 -0
  25. package/lib/extension-registrar.d.ts.map +1 -0
  26. package/lib/extension-registrar.js +134 -0
  27. package/lib/extensions-api.d.ts +221 -0
  28. package/lib/extensions-api.d.ts.map +1 -0
  29. package/lib/extensions-api.js +17 -0
  30. package/lib/extensions-remote.d.ts +54 -0
  31. package/lib/extensions-remote.d.ts.map +1 -0
  32. package/lib/extensions-remote.js +66 -0
  33. package/lib/extensions-service.d.ts +367 -0
  34. package/lib/extensions-service.d.ts.map +1 -0
  35. package/lib/extensions-service.js +1527 -0
  36. package/lib/harness-llm.d.ts +138 -0
  37. package/lib/harness-llm.d.ts.map +1 -0
  38. package/lib/harness-llm.js +218 -0
  39. package/lib/harness-serving.d.ts +95 -0
  40. package/lib/harness-serving.d.ts.map +1 -0
  41. package/lib/harness-serving.js +157 -0
  42. package/lib/headless.d.ts +97 -0
  43. package/lib/headless.d.ts.map +1 -0
  44. package/lib/headless.js +349 -0
  45. package/lib/http-acquisition.d.ts +27 -0
  46. package/lib/http-acquisition.d.ts.map +1 -0
  47. package/lib/http-acquisition.js +136 -0
  48. package/lib/index.d.ts +271 -7
  49. package/lib/index.d.ts.map +1 -1
  50. package/lib/index.js +2644 -70
  51. package/lib/invocation-accounting.d.ts +169 -0
  52. package/lib/invocation-accounting.d.ts.map +1 -0
  53. package/lib/invocation-accounting.js +148 -0
  54. package/lib/legacy-migration.d.ts +95 -0
  55. package/lib/legacy-migration.d.ts.map +1 -0
  56. package/lib/legacy-migration.js +429 -0
  57. package/lib/managed-workers.d.ts +151 -0
  58. package/lib/managed-workers.d.ts.map +1 -0
  59. package/lib/managed-workers.js +249 -0
  60. package/lib/mcp/client-grant.d.ts +74 -0
  61. package/lib/mcp/client-grant.d.ts.map +1 -0
  62. package/lib/mcp/client-grant.js +60 -0
  63. package/lib/mcp/credential-cli.d.ts +38 -0
  64. package/lib/mcp/credential-cli.d.ts.map +1 -0
  65. package/lib/mcp/credential-cli.js +148 -0
  66. package/lib/mcp/credential-store.d.ts +143 -0
  67. package/lib/mcp/credential-store.d.ts.map +1 -0
  68. package/lib/mcp/credential-store.js +454 -0
  69. package/lib/mcp/host-binding.d.ts +25 -0
  70. package/lib/mcp/host-binding.d.ts.map +1 -1
  71. package/lib/mcp/host-binding.js +107 -14
  72. package/lib/mcp/http.d.ts +68 -18
  73. package/lib/mcp/http.d.ts.map +1 -1
  74. package/lib/mcp/http.js +390 -62
  75. package/lib/mcp/oauth.d.ts +149 -0
  76. package/lib/mcp/oauth.d.ts.map +1 -0
  77. package/lib/mcp/oauth.js +396 -0
  78. package/lib/mcp/protocol.d.ts +46 -7
  79. package/lib/mcp/protocol.d.ts.map +1 -1
  80. package/lib/mcp/protocol.js +63 -16
  81. package/lib/mcp/rate-limit.d.ts +68 -0
  82. package/lib/mcp/rate-limit.d.ts.map +1 -0
  83. package/lib/mcp/rate-limit.js +114 -0
  84. package/lib/mcp/sdk-v2.d.ts +17 -0
  85. package/lib/mcp/sdk-v2.d.ts.map +1 -0
  86. package/lib/mcp/sdk-v2.js +181 -0
  87. package/lib/mcp/server.d.ts +11 -1
  88. package/lib/mcp/server.d.ts.map +1 -1
  89. package/lib/mcp/server.js +80 -13
  90. package/lib/mcp/stdio.d.ts.map +1 -1
  91. package/lib/mcp/stdio.js +9 -1
  92. package/lib/mcp/subscriptions.d.ts +43 -1
  93. package/lib/mcp/subscriptions.d.ts.map +1 -1
  94. package/lib/mcp/subscriptions.js +90 -9
  95. package/lib/model-qualification.d.ts +192 -0
  96. package/lib/model-qualification.d.ts.map +1 -0
  97. package/lib/model-qualification.js +178 -0
  98. package/lib/planning.d.ts +246 -0
  99. package/lib/planning.d.ts.map +1 -0
  100. package/lib/planning.js +457 -0
  101. package/lib/prepared-assets.d.ts +178 -0
  102. package/lib/prepared-assets.d.ts.map +1 -0
  103. package/lib/prepared-assets.js +286 -0
  104. package/lib/provider-bridge.d.ts +37 -0
  105. package/lib/provider-bridge.d.ts.map +1 -1
  106. package/lib/provider-bridge.js +189 -12
  107. package/lib/ptc-authority.d.ts +140 -0
  108. package/lib/ptc-authority.d.ts.map +1 -0
  109. package/lib/ptc-authority.js +216 -0
  110. package/lib/ptc-runtime.d.ts +156 -0
  111. package/lib/ptc-runtime.d.ts.map +1 -0
  112. package/lib/ptc-runtime.js +191 -0
  113. package/lib/publication.d.ts +2 -1
  114. package/lib/publication.d.ts.map +1 -1
  115. package/lib/publication.js +13 -5
  116. package/lib/receipt.d.ts.map +1 -1
  117. package/lib/receipt.js +8 -0
  118. package/lib/title-proposal.d.ts +194 -0
  119. package/lib/title-proposal.d.ts.map +1 -0
  120. package/lib/title-proposal.js +244 -0
  121. package/lib/tool-mode-run.d.ts +235 -0
  122. package/lib/tool-mode-run.d.ts.map +1 -0
  123. package/lib/tool-mode-run.js +283 -0
  124. package/lib/types.d.ts +3 -1
  125. package/lib/types.d.ts.map +1 -1
  126. package/lib/update-surface.d.ts +79 -0
  127. package/lib/update-surface.d.ts.map +1 -0
  128. package/lib/update-surface.js +224 -0
  129. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/standard.d.ts +38 -0
  130. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/standard.d.ts.map +1 -0
  131. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/standard.js +445 -0
  132. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-embed.d.ts +14 -0
  133. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-embed.d.ts.map +1 -0
  134. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-embed.js +63 -0
  135. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-rerank.d.ts +14 -0
  136. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-rerank.d.ts.map +1 -0
  137. package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-rerank.js +76 -0
  138. package/node_modules/@try-works/tool-mode-contracts/lib/dsh.d.ts.map +1 -1
  139. package/node_modules/@try-works/tool-mode-contracts/lib/dsh.js +69 -55
  140. package/node_modules/@try-works/tool-mode-contracts/lib/index.d.ts +4 -1
  141. package/node_modules/@try-works/tool-mode-contracts/lib/index.d.ts.map +1 -1
  142. package/node_modules/@try-works/tool-mode-contracts/lib/index.js +26 -2
  143. package/node_modules/@try-works/tool-mode-contracts/lib/registry.d.ts +28 -2
  144. package/node_modules/@try-works/tool-mode-contracts/lib/registry.d.ts.map +1 -1
  145. package/node_modules/@try-works/tool-mode-contracts/lib/registry.js +93 -10
  146. package/node_modules/@try-works/tool-mode-contracts/package.json +0 -1
  147. package/node_modules/@try-works/tool-mode-extension-sdk/bin/dsh-tool-mode.mjs +20 -0
  148. package/node_modules/@try-works/tool-mode-extension-sdk/lib/cli.d.ts +80 -0
  149. package/node_modules/@try-works/tool-mode-extension-sdk/lib/cli.d.ts.map +1 -0
  150. package/node_modules/@try-works/tool-mode-extension-sdk/lib/cli.js +533 -0
  151. package/node_modules/@try-works/tool-mode-extension-sdk/lib/declarative-recipes.d.ts +83 -0
  152. package/node_modules/@try-works/tool-mode-extension-sdk/lib/declarative-recipes.d.ts.map +1 -0
  153. package/node_modules/@try-works/tool-mode-extension-sdk/lib/declarative-recipes.js +125 -0
  154. package/node_modules/@try-works/tool-mode-extension-sdk/lib/discovery.d.ts +70 -0
  155. package/node_modules/@try-works/tool-mode-extension-sdk/lib/discovery.d.ts.map +1 -0
  156. package/node_modules/@try-works/tool-mode-extension-sdk/lib/discovery.js +201 -0
  157. package/node_modules/@try-works/tool-mode-extension-sdk/lib/errors.d.ts +57 -0
  158. package/node_modules/@try-works/tool-mode-extension-sdk/lib/errors.d.ts.map +1 -0
  159. package/node_modules/@try-works/tool-mode-extension-sdk/lib/errors.js +83 -0
  160. package/node_modules/@try-works/tool-mode-extension-sdk/lib/index.d.ts +32 -0
  161. package/node_modules/@try-works/tool-mode-extension-sdk/lib/index.d.ts.map +1 -0
  162. package/node_modules/@try-works/tool-mode-extension-sdk/lib/index.js +32 -0
  163. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/archive.d.ts +86 -0
  164. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/archive.d.ts.map +1 -0
  165. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/archive.js +191 -0
  166. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/dependencies.d.ts +126 -0
  167. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/dependencies.d.ts.map +1 -0
  168. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/dependencies.js +297 -0
  169. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/lifecycle.d.ts +216 -0
  170. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/lifecycle.d.ts.map +1 -0
  171. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/lifecycle.js +800 -0
  172. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/migration.d.ts +210 -0
  173. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/migration.d.ts.map +1 -0
  174. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/migration.js +368 -0
  175. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/runtime-link.d.ts +63 -0
  176. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/runtime-link.d.ts.map +1 -0
  177. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/runtime-link.js +149 -0
  178. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/source-directory.d.ts +35 -0
  179. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/source-directory.d.ts.map +1 -0
  180. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/source-directory.js +179 -0
  181. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/staged.d.ts +179 -0
  182. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/staged.d.ts.map +1 -0
  183. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/staged.js +235 -0
  184. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/store.d.ts +367 -0
  185. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/store.d.ts.map +1 -0
  186. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/store.js +807 -0
  187. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/tar-gzip-source.d.ts +44 -0
  188. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/tar-gzip-source.d.ts.map +1 -0
  189. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/tar-gzip-source.js +243 -0
  190. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/update-flow.d.ts +185 -0
  191. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/update-flow.d.ts.map +1 -0
  192. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/update-flow.js +504 -0
  193. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/zip-source.d.ts +17 -0
  194. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/zip-source.d.ts.map +1 -0
  195. package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/zip-source.js +80 -0
  196. package/node_modules/@try-works/tool-mode-extension-sdk/lib/load.d.ts +52 -0
  197. package/node_modules/@try-works/tool-mode-extension-sdk/lib/load.d.ts.map +1 -0
  198. package/node_modules/@try-works/tool-mode-extension-sdk/lib/load.js +102 -0
  199. package/node_modules/@try-works/tool-mode-extension-sdk/lib/manifest.d.ts +171 -0
  200. package/node_modules/@try-works/tool-mode-extension-sdk/lib/manifest.d.ts.map +1 -0
  201. package/node_modules/@try-works/tool-mode-extension-sdk/lib/manifest.js +271 -0
  202. package/node_modules/@try-works/tool-mode-extension-sdk/lib/runtime.d.ts +242 -0
  203. package/node_modules/@try-works/tool-mode-extension-sdk/lib/runtime.d.ts.map +1 -0
  204. package/node_modules/@try-works/tool-mode-extension-sdk/lib/runtime.js +58 -0
  205. package/node_modules/@try-works/tool-mode-extension-sdk/lib/state.d.ts +118 -0
  206. package/node_modules/@try-works/tool-mode-extension-sdk/lib/state.d.ts.map +1 -0
  207. package/node_modules/@try-works/tool-mode-extension-sdk/lib/state.js +113 -0
  208. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker/worker-child.d.ts +2 -0
  209. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker/worker-child.d.ts.map +1 -0
  210. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker/worker-child.js +351 -0
  211. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker.d.ts +150 -0
  212. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker.d.ts.map +1 -0
  213. package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker.js +670 -0
  214. package/node_modules/@try-works/tool-mode-extension-sdk/package.json +53 -0
  215. package/node_modules/@try-works/tool-mode-extension-sdk/schema/extension-manifest-1.1.0.schema.json +253 -0
  216. package/node_modules/@try-works/tool-mode-recipes/bin/tool-mode-recipe.mjs +15 -0
  217. package/node_modules/@try-works/tool-mode-recipes/lib/broker.d.ts +427 -0
  218. package/node_modules/@try-works/tool-mode-recipes/lib/broker.d.ts.map +1 -0
  219. package/node_modules/@try-works/tool-mode-recipes/lib/broker.js +592 -0
  220. package/node_modules/@try-works/tool-mode-recipes/lib/cli.d.ts +60 -0
  221. package/node_modules/@try-works/tool-mode-recipes/lib/cli.d.ts.map +1 -0
  222. package/node_modules/@try-works/tool-mode-recipes/lib/cli.js +936 -0
  223. package/node_modules/@try-works/tool-mode-recipes/lib/dsh-adapter.d.ts +237 -0
  224. package/node_modules/@try-works/tool-mode-recipes/lib/dsh-adapter.d.ts.map +1 -0
  225. package/node_modules/@try-works/tool-mode-recipes/lib/dsh-adapter.js +200 -0
  226. package/node_modules/@try-works/tool-mode-recipes/lib/fixture-provider.d.ts +85 -0
  227. package/node_modules/@try-works/tool-mode-recipes/lib/fixture-provider.d.ts.map +1 -0
  228. package/node_modules/@try-works/tool-mode-recipes/lib/fixture-provider.js +176 -0
  229. package/node_modules/@try-works/tool-mode-recipes/lib/images.d.ts +105 -0
  230. package/node_modules/@try-works/tool-mode-recipes/lib/images.d.ts.map +1 -0
  231. package/node_modules/@try-works/tool-mode-recipes/lib/images.js +129 -0
  232. package/node_modules/@try-works/tool-mode-recipes/lib/index.d.ts +25 -0
  233. package/node_modules/@try-works/tool-mode-recipes/lib/index.d.ts.map +1 -0
  234. package/node_modules/@try-works/tool-mode-recipes/lib/index.js +25 -0
  235. package/node_modules/@try-works/tool-mode-recipes/lib/recipe-format.d.ts +325 -0
  236. package/node_modules/@try-works/tool-mode-recipes/lib/recipe-format.d.ts.map +1 -0
  237. package/node_modules/@try-works/tool-mode-recipes/lib/recipe-format.js +1310 -0
  238. package/node_modules/@try-works/tool-mode-recipes/lib/templates.d.ts +51 -0
  239. package/node_modules/@try-works/tool-mode-recipes/lib/templates.d.ts.map +1 -0
  240. package/node_modules/@try-works/tool-mode-recipes/lib/templates.js +310 -0
  241. package/node_modules/@try-works/tool-mode-recipes/lib/titles.d.ts +227 -0
  242. package/node_modules/@try-works/tool-mode-recipes/lib/titles.d.ts.map +1 -0
  243. package/node_modules/@try-works/tool-mode-recipes/lib/titles.js +407 -0
  244. package/node_modules/@try-works/tool-mode-recipes/package.json +56 -0
  245. package/node_modules/@try-works/tool-mode-recipes/recipes/describe-image.json +38 -0
  246. package/node_modules/@try-works/tool-mode-recipes/recipes/text-title.json +45 -0
  247. package/node_modules/@try-works/tool-mode-recipes/schema/harness-model-recipe.schema.json +273 -0
  248. package/package.json +43 -15
  249. package/remote/spec.mjs +462 -0
  250. package/remote/typert.host.mjs +14 -0
  251. package/remote/typert.remote-client.mjs +16 -0
  252. package/lib/adapters/tongue.d.ts +0 -31
  253. package/lib/adapters/tongue.d.ts.map +0 -1
  254. package/lib/adapters/tongue.js +0 -93
  255. package/lib/adapters/voz.d.ts +0 -28
  256. package/lib/adapters/voz.d.ts.map +0 -1
  257. package/lib/adapters/voz.js +0 -102
  258. /package/{lib → node_modules/@try-works/tool-mode-extension-sdk/lib}/licensing.d.ts +0 -0
  259. /package/{lib → node_modules/@try-works/tool-mode-extension-sdk/lib}/licensing.d.ts.map +0 -0
  260. /package/{lib → node_modules/@try-works/tool-mode-extension-sdk/lib}/licensing.js +0 -0
@@ -0,0 +1,533 @@
1
+ /**
2
+ * The operator command family (EXT-31).
3
+ *
4
+ * EXT-31 is explicit that these are REQUIRED NEW FUNCTIONALITY, not existing npm
5
+ * or DSH commands, and that offline edits must hold exclusive store ownership. So
6
+ * every mutating command takes the store lock, and the CLI refuses rather than
7
+ * racing a running host.
8
+ *
9
+ * The entry point takes argv and an output sink instead of reading `process`
10
+ * directly. A CLI that can only be exercised by spawning a child process is a CLI
11
+ * whose failure paths are tested by hand or not at all, and the failure paths here
12
+ * are the security-relevant ones.
13
+ *
14
+ * The management surface is deliberately NOT the inference surface: EXT-31 forbids
15
+ * exposing the management channel on the MCP tool surface by default, and nothing
16
+ * in this module registers a tool.
17
+ *
18
+ * @module @try-works/tool-mode-extension-sdk/cli
19
+ */
20
+ import { ManagementError } from "./errors.js";
21
+ import { ExtensionStore } from "./install/store.js";
22
+ import { ExtensionLifecycle } from "./install/lifecycle.js";
23
+ import { commitUpdate, rollback } from "./install/update-flow.js";
24
+ import { summarize } from "./state.js";
25
+ /** The default lazy resolver: the recipes CLI beside this SDK, or nothing. */
26
+ async function defaultRecipeCliResolver() {
27
+ try {
28
+ const module = await import('@try-works/tool-mode-recipes/cli');
29
+ return { runRecipeCli: module.runRecipeCli };
30
+ }
31
+ catch {
32
+ return undefined;
33
+ }
34
+ }
35
+ /**
36
+ * The `recipes` namespace: lazy OPTIONAL forwarding to the recipes authoring
37
+ * CLI (RCP-08). The SDK ships no recipe semantics of its own — the same
38
+ * implementation runs here as under the recipes package's own bin.
39
+ * @param argv - the recipe arguments after the `recipes` token.
40
+ * @param io - output sinks.
41
+ * @param dependencies - the injected runner or resolver.
42
+ * @returns the process exit code.
43
+ */
44
+ async function forwardRecipes(argv, io, dependencies) {
45
+ const runner = dependencies.recipeCliRunner
46
+ ?? await (dependencies.resolveRecipeCli ?? defaultRecipeCliResolver)();
47
+ if (runner === undefined) {
48
+ io.err('the recipes authoring CLI is not available beside this SDK: @try-works/tool-mode-recipes is not installed. '
49
+ + 'Install it, or run its own bin `tool-mode-recipe` directly. This refusal is deliberate: the SDK never '
50
+ + 'pretends to author a recipe it cannot validate.');
51
+ return 1;
52
+ }
53
+ // A raw throw from the forwarded runner becomes a refusal here: the SDK
54
+ // namespace never re-throws into the caller's stack.
55
+ try {
56
+ return await runner.runRecipeCli(argv, io);
57
+ }
58
+ catch (error) {
59
+ io.err(`the recipes CLI failed: ${error instanceof Error ? error.message : String(error)}`);
60
+ return 1;
61
+ }
62
+ }
63
+ /** The usage text. */
64
+ const USAGE = `dsh-tool-mode — manage Tool Mode extensions
65
+
66
+ extensions list list installed extensions
67
+ extensions inspect <id> show one extension's state
68
+ extensions install <spec> [--integrity sha512-…] install without activating
69
+ extensions activate <id> [--profile p] activate in a profile
70
+ extensions prepare <id> --model <model> prepare a model deployment
71
+ extensions deactivate <id> [--profile p] deactivate in a profile
72
+ extensions uninstall <id> [--deactivate] [--purge-assets]
73
+ extensions update <id> --to <version> commit a staged, approved update
74
+ (offline: pointerOnly; the host
75
+ reconciles admissions)
76
+ extensions rollback <id> [--to <version>] restore the recorded previous
77
+ pointer (pointer-only restore)
78
+ extensions purge-assets <id> refused here: purging belongs to
79
+ the running host's coordinator
80
+ tools enable <tool> [--profile p] enable one tool
81
+ tools disable <tool> [--profile p] disable one tool
82
+ recipes <…> author recipes: forwards to the
83
+ recipes CLI (create / edit-draft /
84
+ test / validate / describe / pack)
85
+
86
+ Global: --store <dir> --profile <name> --json (one JSON document: {command, exit, output, errors})
87
+
88
+ Mutating commands take exclusive ownership of the store. They refuse rather than
89
+ race a running host, and the management surface is never published on the
90
+ inference tool surface.`;
91
+ /**
92
+ * Parse argv into options.
93
+ *
94
+ * Anything unrecognised is REFUSED rather than ignored: a mistyped flag that is
95
+ * silently dropped turns `--deactivate` into a command the operator did not ask
96
+ * for, which on `uninstall` is the difference between previewing and removing.
97
+ * @param argv - arguments after the executable name.
98
+ * @returns the parsed options.
99
+ * @throws ManagementError when a flag is unknown or a value is missing.
100
+ */
101
+ export function parseArgs(argv) {
102
+ const positional = [];
103
+ const flags = {};
104
+ const known = new Set([
105
+ 'store', 'profile', 'integrity', 'model', 'deactivate', 'purge-assets', 'json', 'help', 'to',
106
+ ]);
107
+ for (let index = 0; index < argv.length; index += 1) {
108
+ const token = argv[index];
109
+ if (!token.startsWith('--')) {
110
+ positional.push(token);
111
+ continue;
112
+ }
113
+ const name = token.slice(2);
114
+ if (!known.has(name)) {
115
+ throw new ManagementError('INVALID_EXTENSION', 'install', `unknown option ${JSON.stringify(token)}`, 'Run `dsh-tool-mode --help` to see the supported options.');
116
+ }
117
+ // The boolean flags take no value; the rest require one.
118
+ if (name === 'deactivate' || name === 'purge-assets' || name === 'json' || name === 'help') {
119
+ flags[name] = true;
120
+ continue;
121
+ }
122
+ const value = argv[index + 1];
123
+ if (value === undefined || value.startsWith('--')) {
124
+ throw new ManagementError('INVALID_EXTENSION', 'install', `option ${JSON.stringify(token)} needs a value`, `Pass it as ${token} <value>.`);
125
+ }
126
+ flags[name] = value;
127
+ index += 1;
128
+ }
129
+ return {
130
+ store: typeof flags.store === 'string' ? flags.store : '.tool-mode-store',
131
+ profile: typeof flags.profile === 'string' ? flags.profile : 'default',
132
+ positional,
133
+ flags,
134
+ };
135
+ }
136
+ /**
137
+ * Run one command.
138
+ *
139
+ * @param argv - arguments after the executable name.
140
+ * @param io - output sinks.
141
+ * @param dependencies - the registrar and installer to act with.
142
+ * @returns the process exit code.
143
+ */
144
+ export async function runToolModeCli(argv, io, dependencies = {}) {
145
+ // The recipes namespace is forwarded RAW (no SDK-side parsing): the recipes
146
+ // CLI owns its own argv contract, and this file must not duplicate it. The
147
+ // --json wrapper applies to the forwarded namespace too.
148
+ if (argv[0] === 'recipes') {
149
+ const jsonIndex = argv.indexOf('--json');
150
+ if (jsonIndex === -1) {
151
+ return await forwardRecipes(argv.slice(1), io, dependencies);
152
+ }
153
+ const output = [];
154
+ const errors = [];
155
+ const forwarded = [...argv.slice(1, jsonIndex), ...argv.slice(jsonIndex + 1)];
156
+ const code = await forwardRecipes(forwarded, { out: line => output.push(line), err: line => errors.push(line) }, dependencies);
157
+ io.out(JSON.stringify({ command: `recipes ${forwarded.join(' ')}`, exit: code, output, errors }));
158
+ return code;
159
+ }
160
+ let options;
161
+ try {
162
+ options = parseArgs(argv);
163
+ }
164
+ catch (error) {
165
+ io.err(error instanceof Error ? error.message : String(error));
166
+ return 2;
167
+ }
168
+ if (options.flags.help === true || options.positional.length === 0) {
169
+ io.out(USAGE);
170
+ return options.positional.length === 0 && options.flags.help !== true ? 2 : 0;
171
+ }
172
+ const [group, action] = options.positional;
173
+ const store = new ExtensionStore(options.store);
174
+ const lifecycle = new ExtensionLifecycle({
175
+ store,
176
+ profile: options.profile,
177
+ registrar: dependencies.registrar ?? refusingRegistrar,
178
+ });
179
+ // --json: the whole command's output is captured and emitted as ONE JSON
180
+ // document with the exit code as the normalized status (0 success, 1 named
181
+ // management refusal, 2 usage/IO) — never hanging an unattended caller.
182
+ if (options.flags.json === true) {
183
+ const output = [];
184
+ const errors = [];
185
+ const code = await dispatchCli(`${group} ${action}`, options, store, lifecycle, { out: line => output.push(line), err: line => errors.push(line) }, dependencies);
186
+ io.out(JSON.stringify({ command: `${group} ${action}`, exit: code, output, errors }));
187
+ return code;
188
+ }
189
+ try {
190
+ return await dispatchCli(`${group} ${action}`, options, store, lifecycle, io, dependencies);
191
+ }
192
+ catch (error) {
193
+ if (error instanceof ManagementError) {
194
+ io.err(`${error.code}: ${error.message}`);
195
+ // Recovery advice is the point of the vocabulary: a code alone tells an
196
+ // operator what failed but not what to do about it.
197
+ io.err(` ${error.recovery}`);
198
+ return 1;
199
+ }
200
+ io.err(error instanceof Error ? error.message : String(error));
201
+ return 1;
202
+ }
203
+ }
204
+ /** The command dispatch, shared by the prose and the --json paths. */
205
+ async function dispatchCli(command, options, store, lifecycle, io, dependencies) {
206
+ try {
207
+ switch (command) {
208
+ case 'extensions list':
209
+ return listExtensions(store, lifecycle, io);
210
+ case 'extensions inspect':
211
+ return inspectExtension(store, lifecycle, options, io);
212
+ case 'extensions install':
213
+ return await installExtension(store, options, io, dependencies);
214
+ case 'extensions activate':
215
+ return await activateExtension(store, lifecycle, options, io);
216
+ case 'extensions prepare':
217
+ return prepareModel(lifecycle, options, io);
218
+ case 'extensions deactivate':
219
+ return await deactivateExtension(lifecycle, options, io);
220
+ case 'extensions uninstall':
221
+ return await uninstallExtension(lifecycle, store, options, io);
222
+ case 'extensions update':
223
+ return await updateExtension(store, options, io);
224
+ case 'extensions rollback':
225
+ return await rollbackExtension(store, options, io);
226
+ case 'extensions purge-assets':
227
+ return purgeAssets(options, io);
228
+ case 'tools enable':
229
+ return await setTool(store, lifecycle, options, io, true);
230
+ case 'tools disable':
231
+ return await setTool(store, lifecycle, options, io, false);
232
+ default:
233
+ io.err(`unknown command ${JSON.stringify(command)}`);
234
+ io.err(USAGE);
235
+ return 2;
236
+ }
237
+ }
238
+ catch (error) {
239
+ if (error instanceof ManagementError) {
240
+ io.err(`${error.code}: ${error.message}`);
241
+ io.err(` ${error.recovery}`);
242
+ return 1;
243
+ }
244
+ io.err(error instanceof Error ? error.message : String(error));
245
+ return 1;
246
+ }
247
+ }
248
+ /** A registrar that refuses, so activation without a host reports honestly. */
249
+ const refusingRegistrar = {
250
+ publish(contribution) {
251
+ throw new ManagementError('EXTENSION_INACTIVE', 'activate', `this CLI cannot publish ${contribution.name}: no running host is attached`, 'Activate through the running host, or use the host integration; the CLI does not fake publication.');
252
+ },
253
+ withdraw() { },
254
+ };
255
+ /**
256
+ * `extensions update <id> --to <v>` (EXT-31).
257
+ *
258
+ * The OFFLINE CLI path: the version must already be staged and approved
259
+ * (stageUpdate/recordApproval); the commit runs pointerOnly — the durable
260
+ * pointer moves and the running host reconciles admissions on its next
261
+ * lifecycle pass (the CLI never fakes a publication, EXT-31's management
262
+ * channel is the host's).
263
+ */
264
+ async function updateExtension(store, options, io) {
265
+ const id = options.positional[2];
266
+ const version = options.flags.to;
267
+ if (id === undefined) {
268
+ io.err('extensions update needs an extension id');
269
+ return 2;
270
+ }
271
+ if (typeof version !== 'string') {
272
+ io.err('extensions update needs --to <version> (the staged, approved version)');
273
+ return 2;
274
+ }
275
+ const result = await commitUpdate({
276
+ storeDir: store.rootDir,
277
+ profile: options.profile,
278
+ extensionId: id,
279
+ stagedVersion: version,
280
+ pointerOnly: true,
281
+ });
282
+ io.out(`updated ${id}: active ${result.activeVersion}${result.previousVersion === undefined ? '' : ` (was ${result.previousVersion})`}`);
283
+ return 0;
284
+ }
285
+ /** `extensions rollback <id> [--to <v>]` (EXT-31): pointer restore only. */
286
+ async function rollbackExtension(store, options, io) {
287
+ const id = options.positional[2];
288
+ if (id === undefined) {
289
+ io.err('extensions rollback needs an extension id');
290
+ return 2;
291
+ }
292
+ const requested = options.flags.to;
293
+ const pointers = store.readProfilePointers(options.profile);
294
+ if (pointers.corrupt) {
295
+ io.err(`the profile pointers could not be read: ${pointers.diagnostic ?? 'unknown reason'}`);
296
+ return 1;
297
+ }
298
+ const previous = pointers.value.previousVersions[id];
299
+ if (requested !== undefined && requested !== previous) {
300
+ io.err(`rollback --to ${String(requested)} does not match the recorded previous version ${previous ?? '(none)'}; `
301
+ + 'rollback restores the recorded previous pointer, never an arbitrary version');
302
+ return 1;
303
+ }
304
+ const result = await rollback({ storeDir: store.rootDir, profile: options.profile, extensionId: id });
305
+ io.out(`rolled back ${id}: active ${result.activeVersion}${result.hookFailure === undefined ? '' : ` (hook failure reported: ${result.hookFailure})`}`);
306
+ return 0;
307
+ }
308
+ /**
309
+ * `extensions purge-assets <id>` (EXT-31).
310
+ *
311
+ * Honest refusal: asset purging is the deployment coordinator's job in the
312
+ * running host — the offline CLI owns no asset registry and never invents one.
313
+ */
314
+ function purgeAssets(options, io) {
315
+ const id = options.positional[2];
316
+ if (id === undefined) {
317
+ io.err('extensions purge-assets needs an extension id');
318
+ return 2;
319
+ }
320
+ io.err(`asset purging for ${id} requires the running host's deployment coordinator; this offline CLI owns no asset registry and refuses rather than faking a purge`);
321
+ return 1;
322
+ }
323
+ /** `extensions list` */
324
+ function listExtensions(store, lifecycle, io) {
325
+ const lock = store.listInstalled();
326
+ if (lock.corrupt) {
327
+ // Fails closed with diagnostics rather than reporting an empty store, so an
328
+ // operator can tell "nothing installed" from "state unreadable".
329
+ io.err(`the store state could not be read: ${lock.diagnostic ?? 'unknown reason'}`);
330
+ return 1;
331
+ }
332
+ if (lock.value.length === 0) {
333
+ io.out('no extensions installed');
334
+ return 0;
335
+ }
336
+ for (const record of lock.value) {
337
+ const state = lifecycle.stateOf(record.extensionId);
338
+ const summary = state === undefined ? 'not-configured' : summarize(state);
339
+ io.out(`${record.extensionId}@${record.version}\t${summary}\t${record.installPath}`);
340
+ }
341
+ return 0;
342
+ }
343
+ /** `extensions inspect <id>` */
344
+ function inspectExtension(store, lifecycle, options, io) {
345
+ const id = options.positional[2];
346
+ if (id === undefined) {
347
+ io.err('extensions inspect needs an extension id');
348
+ return 2;
349
+ }
350
+ const record = store.listInstalled().value.find(candidate => candidate.extensionId === id);
351
+ if (record === undefined) {
352
+ io.err(`${id} is not installed`);
353
+ return 1;
354
+ }
355
+ const integrity = store.verifyUnchanged(record);
356
+ const state = lifecycle.stateOf(id);
357
+ if (options.flags.json === true) {
358
+ io.out(JSON.stringify({ record, state, unchanged: integrity.unchanged }, null, 2));
359
+ return 0;
360
+ }
361
+ io.out(`id ${record.extensionId}`);
362
+ io.out(`version ${record.version}`);
363
+ io.out(`installed ${record.installedAt}`);
364
+ io.out(`source ${record.source.kind}: ${record.source.requested}`);
365
+ io.out(`archive ${record.archiveDigest}`);
366
+ io.out(`content ${integrity.unchanged ? 'unchanged' : `CHANGED — ${integrity.diagnostic ?? ''}`}`);
367
+ io.out(`activation ${state === undefined ? 'not-configured' : summarize(state)}`);
368
+ if (state !== undefined) {
369
+ io.out(`desired ${state.desiredActivation}`);
370
+ io.out(`observed ${state.observedActivation}`);
371
+ io.out(`export ${state.export}`);
372
+ for (const tool of state.tools) {
373
+ io.out(`tool ${tool.toolName} ${tool.enabled ? 'enabled' : 'disabled'}`);
374
+ }
375
+ }
376
+ return 0;
377
+ }
378
+ /** `extensions install <spec>` */
379
+ async function installExtension(store, options, io, dependencies) {
380
+ const spec = options.positional[2];
381
+ if (spec === undefined) {
382
+ io.err('extensions install needs a source');
383
+ return 2;
384
+ }
385
+ const integrity = typeof options.flags.integrity === 'string' ? options.flags.integrity : undefined;
386
+ if (integrity === undefined) {
387
+ // EXT-12: integrity is not trust, but installing WITHOUT a declared digest
388
+ // means nothing can be verified later. Requiring it is the safer default.
389
+ io.err('extensions install requires --integrity sha512-<verified-base64>');
390
+ io.err(' Ask the publisher for the digest; installing unverified bytes cannot be undone later.');
391
+ return 2;
392
+ }
393
+ if (dependencies.install === undefined) {
394
+ io.err('this CLI has no installer attached; install through the host or a configured source');
395
+ return 1;
396
+ }
397
+ const release = store.acquireExclusive();
398
+ try {
399
+ const id = await dependencies.install(spec, integrity, options.store);
400
+ io.out(`installed ${id} (inactive — installation is not activation)`);
401
+ return 0;
402
+ }
403
+ finally {
404
+ release();
405
+ }
406
+ }
407
+ /** `extensions activate <id>` */
408
+ async function activateExtension(store, lifecycle, options, io) {
409
+ const id = options.positional[2];
410
+ if (id === undefined) {
411
+ io.err('extensions activate needs an extension id');
412
+ return 2;
413
+ }
414
+ // Activation names an exact installed VERSION, because the same extension may be
415
+ // installed twice and "activate the newest" is a guess about operator intent.
416
+ const installed = store.listInstalled().value.filter(record => record.extensionId === id);
417
+ if (installed.length === 0) {
418
+ io.err(`${id} is not installed`);
419
+ return 1;
420
+ }
421
+ if (installed.length > 1) {
422
+ const versions = installed.map(record => record.version).join(', ');
423
+ io.err(`${id} is installed at ${installed.length} versions (${versions})`);
424
+ io.err(' Uninstall the versions you do not want; activation will not pick one for you.');
425
+ return 1;
426
+ }
427
+ const result = await lifecycle.activate(id, installed[0].version);
428
+ io.out(`activated ${id}@${result.version} in profile ${options.profile} (generation ${result.generation})`);
429
+ for (const diagnostic of result.diagnostics) {
430
+ io.out(` ${diagnostic.code}: ${diagnostic.message}`);
431
+ }
432
+ return 0;
433
+ }
434
+ /** `extensions prepare <id> --model <model>` */
435
+ function prepareModel(lifecycle, options, io) {
436
+ const id = options.positional[2];
437
+ const model = typeof options.flags.model === 'string' ? options.flags.model : undefined;
438
+ if (id === undefined || model === undefined) {
439
+ io.err('extensions prepare needs an extension id and --model <model>');
440
+ return 2;
441
+ }
442
+ const state = lifecycle.stateOf(id);
443
+ if (state === undefined) {
444
+ io.err(`${id} is not configured in profile ${options.profile}`);
445
+ return 1;
446
+ }
447
+ // Preparation is the host's job and the host is not running, so this records the
448
+ // deployment the operator asked for rather than claiming to have fetched it.
449
+ io.out(`preparation requested for ${id} model ${model}`);
450
+ io.out(' preparation runs in the host; this command records the request only.');
451
+ return 0;
452
+ }
453
+ /** `extensions deactivate <id>` */
454
+ async function deactivateExtension(lifecycle, options, io) {
455
+ const id = options.positional[2];
456
+ if (id === undefined) {
457
+ io.err('extensions deactivate needs an extension id');
458
+ return 2;
459
+ }
460
+ const result = await lifecycle.deactivate(id);
461
+ if (result.fullyStopped) {
462
+ io.out(`deactivated ${id} in profile ${options.profile}`);
463
+ return 0;
464
+ }
465
+ // EXT-27: never report a full stop while an owned worker continues.
466
+ io.err(`deactivated ${id}, but cleanup did not complete: ${result.cleanupFailure ?? 'unknown reason'}`);
467
+ io.err(' The extension is quarantined; retry once its worker has stopped.');
468
+ return 1;
469
+ }
470
+ /** `extensions uninstall <id>` */
471
+ async function uninstallExtension(lifecycle, store, options, io) {
472
+ const id = options.positional[2];
473
+ if (id === undefined) {
474
+ io.err('extensions uninstall needs an extension id');
475
+ return 2;
476
+ }
477
+ const state = lifecycle.stateOf(id);
478
+ const active = state?.observedActivation === 'active' || state?.desiredActivation === 'active';
479
+ if (active && options.flags.deactivate !== true) {
480
+ // The impact preview EXT-28 requires, shown BEFORE refusing so the operator
481
+ // knows exactly what re-running would affect.
482
+ io.err(`${id} is active in profile ${options.profile}`);
483
+ io.err('Impact preview:');
484
+ for (const tool of state?.tools ?? [])
485
+ io.err(` tool ${tool.toolName} (${tool.enabled ? 'enabled' : 'disabled'})`);
486
+ io.err(` profile ${options.profile}`);
487
+ io.err('Re-run with --deactivate to deactivate it first.');
488
+ return 1;
489
+ }
490
+ await store.exclusive(async () => {
491
+ await lifecycle.uninstall(id, { deactivate: options.flags.deactivate === true });
492
+ io.out(`uninstalled ${id}`);
493
+ if (options.flags['purge-assets'] === true) {
494
+ // Assets are removed by a separate, restart-retryable step (EXT-29), so this
495
+ // reports the request rather than implying the bytes are already gone.
496
+ io.out(' asset purge requested; on Windows deletion may complete after restart');
497
+ }
498
+ io.out(' a disabled tombstone is retained so the package cannot silently return');
499
+ });
500
+ return 0;
501
+ }
502
+ /** `tools enable|disable <tool>` */
503
+ async function setTool(store, lifecycle, options, io, enabled) {
504
+ const toolName = options.positional[2];
505
+ if (toolName === undefined) {
506
+ io.err(`tools ${enabled ? 'enable' : 'disable'} needs a tool name`);
507
+ return 2;
508
+ }
509
+ // The tool name identifies the extension that contributes it, so the operator
510
+ // does not have to remember which package owns which tool.
511
+ const owner = lifecycle.states().find(state => state.tools.some(tool => tool.toolName === toolName));
512
+ if (owner === undefined) {
513
+ io.err(`no extension in profile ${options.profile} contributes a tool named ${toolName}`);
514
+ return 1;
515
+ }
516
+ // A toggle RECONCILES the published surface now, so like every other offline
517
+ // mutation it must hold exclusive store ownership: racing a running host's own
518
+ // registry mutations with none would leave the two processes disagreeing. The
519
+ // reentrant exclusive() is used rather than the raw lock so the lifecycle's own
520
+ // acquisition nests at depth 2 instead of overwriting this command's record.
521
+ try {
522
+ await store.exclusive(async () => {
523
+ await lifecycle.setToolEnabled(owner.extensionId, toolName, enabled);
524
+ });
525
+ }
526
+ catch (error) {
527
+ io.err(error instanceof Error ? error.message : String(error));
528
+ return 1;
529
+ }
530
+ io.out(`${enabled ? 'enabled' : 'disabled'} ${toolName} in profile ${options.profile}`);
531
+ return 0;
532
+ }
533
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Resolving a DECLARATIVE implementation's recipe (EXT-13, RCP-01, slice 3).
3
+ *
4
+ * THE CONVENTION THIS ESTABLISHES, and why it has to exist. The pinned manifest schema's
5
+ * `implementations` items permit only `id`, `contractId`, `contractVersion`, `modelId` and
6
+ * `recipeVersion`, with `additionalProperties: false` — so **a manifest cannot name its
7
+ * recipe files**. There is no path field to read.
8
+ *
9
+ * What a manifest declares is a recipe VERSION. The ARTEFACT is therefore located by a
10
+ * convention, and until now no convention existed because nothing had ever consumed a
11
+ * declarative manifest: every package in this repository was `kind: "module"` and reached its
12
+ * behaviour through a module entry.
13
+ *
14
+ * The convention, stated once so it is not re-invented at each call site:
15
+ *
16
+ * <package>/recipes/<implementation-id>.json
17
+ *
18
+ * Chosen because the implementation id is already unique within the package, already matches
19
+ * `^[a-z][a-z0-9-]*$` by schema, and therefore needs no escaping or normalisation to become a
20
+ * file name. The alternative — keying on the contract id — would need path-mapping for the
21
+ * `tool-mode/` namespace and would collide when one contract has several implementations,
22
+ * which is exactly what `implementations` is an ARRAY to allow.
23
+ *
24
+ * @module @try-works/tool-mode-extension-sdk/declarative-recipes
25
+ */
26
+ /** The directory the convention looks in. */
27
+ export declare const RECIPE_DIRECTORY = "recipes";
28
+ /** A resolved recipe, or the reason it could not be resolved. */
29
+ export type RecipeResolution = {
30
+ readonly ok: true;
31
+ readonly recipe: unknown;
32
+ readonly path: string;
33
+ } | {
34
+ readonly ok: false;
35
+ readonly reason: 'missing' | 'unreadable' | 'invalid-json';
36
+ readonly path: string;
37
+ readonly detail: string;
38
+ };
39
+ /**
40
+ * Resolve one implementation's recipe by the convention.
41
+ *
42
+ * @param packageDir - the installed package root.
43
+ * @param implementationId - the manifest implementation id, which names the file.
44
+ * @returns the parsed recipe, or an honest failure.
45
+ */
46
+ export declare function resolveDeclarativeRecipe(packageDir: string, implementationId: string): RecipeResolution;
47
+ /**
48
+ * Resolve every implementation a declarative manifest declares.
49
+ *
50
+ * All-or-nothing on purpose: a package that could satisfy HALF its declarations would be
51
+ * activated in a state its manifest does not describe, and a caller would have no way to
52
+ * learn which half. Refusing names what is missing instead.
53
+ *
54
+ * @param packageDir - the installed package root.
55
+ * @param implementations - the manifest's declaration list.
56
+ * @returns every resolved recipe, or the first failure.
57
+ */
58
+ export declare function resolveDeclarativeImplementations(packageDir: string, implementations: readonly {
59
+ readonly id: string;
60
+ readonly contractId: string;
61
+ readonly recipeVersion: string;
62
+ }[]): {
63
+ readonly ok: true;
64
+ readonly resolved: readonly {
65
+ readonly id: string;
66
+ readonly contractId: string;
67
+ readonly recipeVersion: string;
68
+ readonly recipe: unknown;
69
+ readonly path: string;
70
+ }[];
71
+ } | {
72
+ readonly ok: false;
73
+ readonly id: string;
74
+ readonly detail: string;
75
+ };
76
+ /**
77
+ * Whether an installed package is declarative, and what it declares.
78
+ *
79
+ * @param packageDir - the installed package root.
80
+ * @returns the declared recipe names when the package is declarative, else undefined.
81
+ */
82
+ export declare function declaredRecipeNames(packageDir: string): readonly string[] | undefined;
83
+ //# sourceMappingURL=declarative-recipes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"declarative-recipes.d.ts","sourceRoot":"","sources":["../src/declarative-recipes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAKH,6CAA6C;AAC7C,eAAO,MAAM,gBAAgB,YAAY,CAAA;AAEzC,iEAAiE;AACjE,MAAM,MAAM,gBAAgB,GACxB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,YAAY,GAAG,cAAc,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtI;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,UAAU,EAAE,MAAM,EAAE,gBAAgB,EAAE,MAAM,GAAG,gBAAgB,CA6CvG;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,MAAM,EAClB,eAAe,EAAE,SAAS;IAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;CAAE,EAAE,GAC/G;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,QAAQ,EAAE,SAAS;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,GACzL;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAcvE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,SAAS,CAQrF"}