@try-works/dsh-model-as-tool 0.1.3 → 0.3.6
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.
- package/bin/dsh-tool-mode-credentials.mjs +20 -0
- package/bin/dsh-tool-mode.mjs +202 -0
- package/catalog/desert-ant-models.json +693 -693
- package/client/client.model-tools.js +592 -0
- package/client/index.js +1679 -0
- package/lib/adapters/index.d.ts.map +1 -1
- package/lib/adapters/index.js +4 -4
- package/lib/bindings.d.ts.map +1 -1
- package/lib/bindings.js +26 -25
- package/lib/capability.d.ts.map +1 -1
- package/lib/capability.js +17 -0
- package/lib/capture-path.d.ts +97 -0
- package/lib/capture-path.d.ts.map +1 -0
- package/lib/capture-path.js +152 -0
- package/lib/diagnostics.d.ts +166 -0
- package/lib/diagnostics.d.ts.map +1 -0
- package/lib/diagnostics.js +135 -0
- package/lib/extension-dependencies.d.ts +197 -0
- package/lib/extension-dependencies.d.ts.map +1 -0
- package/lib/extension-dependencies.js +369 -0
- package/lib/extension-dispatch.d.ts +117 -0
- package/lib/extension-dispatch.d.ts.map +1 -0
- package/lib/extension-dispatch.js +124 -0
- package/lib/extension-registrar.d.ts +100 -0
- package/lib/extension-registrar.d.ts.map +1 -0
- package/lib/extension-registrar.js +134 -0
- package/lib/extensions-api.d.ts +217 -0
- package/lib/extensions-api.d.ts.map +1 -0
- package/lib/extensions-api.js +17 -0
- package/lib/extensions-remote.d.ts +54 -0
- package/lib/extensions-remote.d.ts.map +1 -0
- package/lib/extensions-remote.js +66 -0
- package/lib/extensions-service.d.ts +334 -0
- package/lib/extensions-service.d.ts.map +1 -0
- package/lib/extensions-service.js +1351 -0
- package/lib/harness-llm.d.ts +138 -0
- package/lib/harness-llm.d.ts.map +1 -0
- package/lib/harness-llm.js +218 -0
- package/lib/harness-serving.d.ts +95 -0
- package/lib/harness-serving.d.ts.map +1 -0
- package/lib/harness-serving.js +157 -0
- package/lib/headless.d.ts +97 -0
- package/lib/headless.d.ts.map +1 -0
- package/lib/headless.js +349 -0
- package/lib/http-acquisition.d.ts +27 -0
- package/lib/http-acquisition.d.ts.map +1 -0
- package/lib/http-acquisition.js +136 -0
- package/lib/index.d.ts +250 -7
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2625 -70
- package/lib/invocation-accounting.d.ts +169 -0
- package/lib/invocation-accounting.d.ts.map +1 -0
- package/lib/invocation-accounting.js +148 -0
- package/lib/legacy-migration.d.ts +95 -0
- package/lib/legacy-migration.d.ts.map +1 -0
- package/lib/legacy-migration.js +429 -0
- package/lib/managed-workers.d.ts +151 -0
- package/lib/managed-workers.d.ts.map +1 -0
- package/lib/managed-workers.js +249 -0
- package/lib/mcp/client-grant.d.ts +74 -0
- package/lib/mcp/client-grant.d.ts.map +1 -0
- package/lib/mcp/client-grant.js +60 -0
- package/lib/mcp/credential-cli.d.ts +38 -0
- package/lib/mcp/credential-cli.d.ts.map +1 -0
- package/lib/mcp/credential-cli.js +148 -0
- package/lib/mcp/credential-store.d.ts +143 -0
- package/lib/mcp/credential-store.d.ts.map +1 -0
- package/lib/mcp/credential-store.js +454 -0
- package/lib/mcp/host-binding.d.ts +25 -0
- package/lib/mcp/host-binding.d.ts.map +1 -1
- package/lib/mcp/host-binding.js +107 -14
- package/lib/mcp/http.d.ts +68 -18
- package/lib/mcp/http.d.ts.map +1 -1
- package/lib/mcp/http.js +390 -62
- package/lib/mcp/oauth.d.ts +149 -0
- package/lib/mcp/oauth.d.ts.map +1 -0
- package/lib/mcp/oauth.js +396 -0
- package/lib/mcp/protocol.d.ts +46 -7
- package/lib/mcp/protocol.d.ts.map +1 -1
- package/lib/mcp/protocol.js +63 -16
- package/lib/mcp/rate-limit.d.ts +68 -0
- package/lib/mcp/rate-limit.d.ts.map +1 -0
- package/lib/mcp/rate-limit.js +114 -0
- package/lib/mcp/sdk-v2.d.ts +17 -0
- package/lib/mcp/sdk-v2.d.ts.map +1 -0
- package/lib/mcp/sdk-v2.js +181 -0
- package/lib/mcp/server.d.ts +11 -1
- package/lib/mcp/server.d.ts.map +1 -1
- package/lib/mcp/server.js +80 -13
- package/lib/mcp/stdio.d.ts.map +1 -1
- package/lib/mcp/stdio.js +9 -1
- package/lib/mcp/subscriptions.d.ts +43 -1
- package/lib/mcp/subscriptions.d.ts.map +1 -1
- package/lib/mcp/subscriptions.js +90 -9
- package/lib/model-qualification.d.ts +192 -0
- package/lib/model-qualification.d.ts.map +1 -0
- package/lib/model-qualification.js +178 -0
- package/lib/planning.d.ts +246 -0
- package/lib/planning.d.ts.map +1 -0
- package/lib/planning.js +457 -0
- package/lib/prepared-assets.d.ts +178 -0
- package/lib/prepared-assets.d.ts.map +1 -0
- package/lib/prepared-assets.js +286 -0
- package/lib/provider-bridge.d.ts +37 -0
- package/lib/provider-bridge.d.ts.map +1 -1
- package/lib/provider-bridge.js +189 -12
- package/lib/ptc-authority.d.ts +140 -0
- package/lib/ptc-authority.d.ts.map +1 -0
- package/lib/ptc-authority.js +216 -0
- package/lib/ptc-runtime.d.ts +156 -0
- package/lib/ptc-runtime.d.ts.map +1 -0
- package/lib/ptc-runtime.js +191 -0
- package/lib/publication.d.ts +2 -1
- package/lib/publication.d.ts.map +1 -1
- package/lib/publication.js +13 -5
- package/lib/receipt.d.ts.map +1 -1
- package/lib/receipt.js +8 -0
- package/lib/title-proposal.d.ts +194 -0
- package/lib/title-proposal.d.ts.map +1 -0
- package/lib/title-proposal.js +244 -0
- package/lib/tool-mode-run.d.ts +235 -0
- package/lib/tool-mode-run.d.ts.map +1 -0
- package/lib/tool-mode-run.js +283 -0
- package/lib/types.d.ts +3 -1
- package/lib/types.d.ts.map +1 -1
- package/lib/update-surface.d.ts +79 -0
- package/lib/update-surface.d.ts.map +1 -0
- package/lib/update-surface.js +224 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/standard.d.ts +38 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/standard.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/standard.js +445 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-embed.d.ts +14 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-embed.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-embed.js +63 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-rerank.d.ts +14 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-rerank.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/text-rerank.js +76 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/dsh.d.ts.map +1 -1
- package/node_modules/@try-works/tool-mode-contracts/lib/dsh.js +69 -55
- package/node_modules/@try-works/tool-mode-contracts/lib/index.d.ts +4 -1
- package/node_modules/@try-works/tool-mode-contracts/lib/index.d.ts.map +1 -1
- package/node_modules/@try-works/tool-mode-contracts/lib/index.js +26 -2
- package/node_modules/@try-works/tool-mode-contracts/lib/registry.d.ts +28 -2
- package/node_modules/@try-works/tool-mode-contracts/lib/registry.d.ts.map +1 -1
- package/node_modules/@try-works/tool-mode-contracts/lib/registry.js +93 -10
- package/node_modules/@try-works/tool-mode-contracts/package.json +0 -1
- package/node_modules/@try-works/tool-mode-extension-sdk/bin/dsh-tool-mode.mjs +20 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/cli.d.ts +80 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/cli.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/cli.js +533 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/declarative-recipes.d.ts +83 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/declarative-recipes.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/declarative-recipes.js +125 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/discovery.d.ts +70 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/discovery.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/discovery.js +201 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/errors.d.ts +57 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/errors.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/errors.js +83 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/index.d.ts +31 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/index.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/index.js +31 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/archive.d.ts +86 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/archive.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/archive.js +185 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/dependencies.d.ts +126 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/dependencies.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/dependencies.js +297 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/lifecycle.d.ts +216 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/lifecycle.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/lifecycle.js +800 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/migration.d.ts +210 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/migration.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/migration.js +368 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/runtime-link.d.ts +63 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/runtime-link.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/runtime-link.js +149 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/source-directory.d.ts +35 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/source-directory.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/source-directory.js +179 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/staged.d.ts +179 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/staged.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/staged.js +235 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/store.d.ts +367 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/store.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/store.js +807 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/update-flow.d.ts +185 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/update-flow.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/update-flow.js +504 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/zip-source.d.ts +17 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/zip-source.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/install/zip-source.js +80 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/load.d.ts +52 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/load.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/load.js +102 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/manifest.d.ts +171 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/manifest.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/manifest.js +271 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/runtime.d.ts +242 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/runtime.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/runtime.js +58 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/state.d.ts +118 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/state.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/state.js +113 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker/worker-child.d.ts +2 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker/worker-child.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker/worker-child.js +351 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker.d.ts +150 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/lib/worker.js +670 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/package.json +53 -0
- package/node_modules/@try-works/tool-mode-extension-sdk/schema/extension-manifest-1.1.0.schema.json +253 -0
- package/node_modules/@try-works/tool-mode-recipes/bin/tool-mode-recipe.mjs +15 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/broker.d.ts +427 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/broker.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/broker.js +592 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/cli.d.ts +60 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/cli.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/cli.js +936 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/dsh-adapter.d.ts +237 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/dsh-adapter.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/dsh-adapter.js +200 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/fixture-provider.d.ts +85 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/fixture-provider.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/fixture-provider.js +176 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/images.d.ts +105 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/images.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/images.js +129 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/index.d.ts +25 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/index.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/index.js +25 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/recipe-format.d.ts +325 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/recipe-format.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/recipe-format.js +1310 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/templates.d.ts +51 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/templates.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/templates.js +310 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/titles.d.ts +227 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/titles.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-recipes/lib/titles.js +407 -0
- package/node_modules/@try-works/tool-mode-recipes/package.json +56 -0
- package/node_modules/@try-works/tool-mode-recipes/recipes/describe-image.json +38 -0
- package/node_modules/@try-works/tool-mode-recipes/recipes/text-title.json +45 -0
- package/node_modules/@try-works/tool-mode-recipes/schema/harness-model-recipe.schema.json +273 -0
- package/package.json +43 -15
- package/remote/spec.mjs +439 -0
- package/remote/typert.host.mjs +14 -0
- package/remote/typert.remote-client.mjs +16 -0
- package/lib/adapters/tongue.d.ts +0 -31
- package/lib/adapters/tongue.d.ts.map +0 -1
- package/lib/adapters/tongue.js +0 -93
- package/lib/adapters/voz.d.ts +0 -28
- package/lib/adapters/voz.d.ts.map +0 -1
- package/lib/adapters/voz.js +0 -102
- /package/{lib → node_modules/@try-works/tool-mode-extension-sdk/lib}/licensing.d.ts +0 -0
- /package/{lib → node_modules/@try-works/tool-mode-extension-sdk/lib}/licensing.d.ts.map +0 -0
- /package/{lib → node_modules/@try-works/tool-mode-extension-sdk/lib}/licensing.js +0 -0
|
@@ -0,0 +1,297 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Installer-owned dependency graphs (EXT-09).
|
|
3
|
+
*
|
|
4
|
+
* An extension's runtime dependencies are resolved through the operator's
|
|
5
|
+
* registry EXACTLY ONCE (ranges lock to exact versions), fetched, verified
|
|
6
|
+
* against their registry-recorded SHA-512, and materialized into the
|
|
7
|
+
* extension's OWN immutable installation directory — never the host's
|
|
8
|
+
* node_modules, never the user's workspace. Lifecycle scripts are refused,
|
|
9
|
+
* never silently skipped or run: a dependency whose package declares
|
|
10
|
+
* `prepare`/`preinstall`/`install`/`postinstall` refuses the install with a
|
|
11
|
+
* named error. The resolved graph (name, exact version, integrity, requested
|
|
12
|
+
* spec) is recorded in the install record (EXT-12).
|
|
13
|
+
*
|
|
14
|
+
* The registry half is INJECTED, like the archive source: the SDK owns the
|
|
15
|
+
* graph discipline, the host supplies the configured registry and the tarball
|
|
16
|
+
* transport. An extension's runtime can only import what this installer
|
|
17
|
+
* materialized — undeclared resolution attempts fail at module load, because
|
|
18
|
+
* the runtime SDK link is the only bridge into the host tree.
|
|
19
|
+
*
|
|
20
|
+
* @module @try-works/tool-mode-extension-sdk/install/dependencies
|
|
21
|
+
*/
|
|
22
|
+
import { copyFileSync, existsSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, statSync } from 'node:fs';
|
|
23
|
+
import { createHash } from 'node:crypto';
|
|
24
|
+
import { isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
25
|
+
import { ManagementError } from "./../errors.js";
|
|
26
|
+
import { verifyIntegrity } from "./archive.js";
|
|
27
|
+
/** The defaults for one preinstalled-content copy. */
|
|
28
|
+
const DEFAULT_PREINSTALLED_BYTES = 512 * 1024 * 1024;
|
|
29
|
+
const DEFAULT_PREINSTALLED_FILES = 10_000;
|
|
30
|
+
/** The install-time lifecycle scripts whose presence is a refusal, never a skip. */
|
|
31
|
+
const REFUSED_SCRIPTS = ['prepare', 'preinstall', 'install', 'postinstall'];
|
|
32
|
+
/** Read a package.json's runtime dependencies as name→spec pairs. */
|
|
33
|
+
function declaredDependencies(packageDir) {
|
|
34
|
+
let parsed;
|
|
35
|
+
try {
|
|
36
|
+
parsed = JSON.parse(readFileSync(join(packageDir, 'package.json'), 'utf8'));
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
throw new ManagementError('INVALID_EXTENSION', 'install', `the package.json could not be read: ${error instanceof Error ? error.message : String(error)}`, 'The archive must ship a parseable package.json.');
|
|
40
|
+
}
|
|
41
|
+
if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {
|
|
42
|
+
throw new ManagementError('INVALID_EXTENSION', 'install', 'the package.json is not an object', 'Ship a valid package.json.');
|
|
43
|
+
}
|
|
44
|
+
const dependencies = parsed['dependencies'];
|
|
45
|
+
if (dependencies === undefined)
|
|
46
|
+
return {};
|
|
47
|
+
if (typeof dependencies !== 'object' || dependencies === null || Array.isArray(dependencies)) {
|
|
48
|
+
throw new ManagementError('INVALID_EXTENSION', 'install', 'the package.json dependencies field is not a name→version object', 'Declare runtime dependencies as a plain object of exact versions or ranges.');
|
|
49
|
+
}
|
|
50
|
+
const result = {};
|
|
51
|
+
for (const [name, spec] of Object.entries(dependencies)) {
|
|
52
|
+
if (typeof spec !== 'string' || spec.length === 0) {
|
|
53
|
+
throw new ManagementError('INVALID_EXTENSION', 'install', `the dependency ${JSON.stringify(name)} declares a non-string spec`, 'Declare a version string for every runtime dependency.');
|
|
54
|
+
}
|
|
55
|
+
result[name] = spec;
|
|
56
|
+
}
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
/** Refuse a dependency whose package declares install-time lifecycle scripts. */
|
|
60
|
+
export function refuseInstallScripts(packageDir, name, version) {
|
|
61
|
+
let parsed;
|
|
62
|
+
try {
|
|
63
|
+
parsed = JSON.parse(readFileSync(join(packageDir, 'package.json'), 'utf8'));
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
throw new ManagementError('INVALID_EXTENSION', 'install', `the dependency ${name}@${version} ships an unparseable package.json: ${error instanceof Error ? error.message : String(error)}`, 'The dependency tarball must ship a parseable package.json.');
|
|
67
|
+
}
|
|
68
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
69
|
+
return;
|
|
70
|
+
const scripts = parsed['scripts'];
|
|
71
|
+
if (typeof scripts !== 'object' || scripts === null)
|
|
72
|
+
return;
|
|
73
|
+
for (const key of REFUSED_SCRIPTS) {
|
|
74
|
+
if (key in scripts) {
|
|
75
|
+
throw new ManagementError('DEPENDENCY_UNSATISFIED', 'install', `${name}@${version} declares a "${key}" lifecycle script; the installer never runs or silently skips install-time scripts (EXT-10)`, 'Publish a version of the dependency that needs no install-time script (prebuilt artifacts only), or pin a different version.');
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/** The content digest of one materialized tree (the digestInstalledContent algorithm). */
|
|
80
|
+
function digestContentOf(directory) {
|
|
81
|
+
const hash = createHash('sha256');
|
|
82
|
+
const files = [];
|
|
83
|
+
const walk = (current) => {
|
|
84
|
+
for (const entry of readdirSync(current, { withFileTypes: true }).sort((a, b) => a.name.localeCompare(b.name))) {
|
|
85
|
+
const absolute = join(current, entry.name);
|
|
86
|
+
if (entry.isDirectory())
|
|
87
|
+
walk(absolute);
|
|
88
|
+
else if (entry.isFile())
|
|
89
|
+
files.push(absolute);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
walk(directory);
|
|
93
|
+
for (const file of files.sort()) {
|
|
94
|
+
const name = relative(directory, file).split(sep).join('/');
|
|
95
|
+
if (name === '.tool-mode-install.json')
|
|
96
|
+
continue;
|
|
97
|
+
const bytes = readFileSync(file);
|
|
98
|
+
hash.update(name);
|
|
99
|
+
hash.update('\0');
|
|
100
|
+
hash.update(String(bytes.byteLength));
|
|
101
|
+
hash.update('\0');
|
|
102
|
+
hash.update(createHash('sha256').update(bytes).digest());
|
|
103
|
+
hash.update('\0');
|
|
104
|
+
}
|
|
105
|
+
return hash.digest('hex');
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Copy one preinstalled directory tree into the extension's own install dir.
|
|
109
|
+
*
|
|
110
|
+
* A COPY, never a link: the operator's host tree stays untouched and the
|
|
111
|
+
* extension owns its bytes. Reparse points inside the tree are refused (the
|
|
112
|
+
* same junction defense the archive path gets), and the copy is bounded.
|
|
113
|
+
*/
|
|
114
|
+
function copyPreinstalledTree(source, destination, limits) {
|
|
115
|
+
mkdirSync(destination, { recursive: true });
|
|
116
|
+
let files = 0;
|
|
117
|
+
let bytes = 0;
|
|
118
|
+
const walk = (from, to) => {
|
|
119
|
+
for (const entry of readdirSync(from, { withFileTypes: true })) {
|
|
120
|
+
const fromPath = join(from, entry.name);
|
|
121
|
+
const toPath = join(to, entry.name);
|
|
122
|
+
if (entry.isSymbolicLink() || (entry.isFile() === false && entry.isDirectory() === false)) {
|
|
123
|
+
throw new ManagementError('DEPENDENCY_UNSATISFIED', 'install', `${fromPath} is a reparse point; preinstalled content must not smuggle links into the installation`, 'Point at a real directory tree, or resolve the dependency from registry bytes.');
|
|
124
|
+
}
|
|
125
|
+
if (entry.isDirectory()) {
|
|
126
|
+
// The parent directory for this subtree must EXIST before any nested
|
|
127
|
+
// file is copied into it: copyFileSync does not create parents, and on
|
|
128
|
+
// Windows a missing parent raises ENOENT on the destination side
|
|
129
|
+
// (task-88: the live MiniLM install failed copying dist/… before this).
|
|
130
|
+
mkdirSync(toPath, { recursive: true });
|
|
131
|
+
walk(fromPath, toPath);
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
files += 1;
|
|
135
|
+
bytes += statSync(fromPath).size;
|
|
136
|
+
if (files > limits.files || bytes > limits.bytes) {
|
|
137
|
+
throw new ManagementError('DEPENDENCY_UNSATISFIED', 'install', `the preinstalled content exceeds the copy bounds (${limits.files} files / ${limits.bytes} bytes)`, 'Raise the operator bounds deliberately, or resolve the dependency from registry bytes.');
|
|
138
|
+
}
|
|
139
|
+
copyFileSync(fromPath, toPath);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
walk(source, destination);
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Resolve, fetch, verify and materialize one extension's dependency graph.
|
|
146
|
+
*
|
|
147
|
+
* Bounded BFS: ranges resolve exactly once, registry tarballs verify against
|
|
148
|
+
* their registry integrity, scripts are refused on the registry arm, and the
|
|
149
|
+
* graph is flattened into the extension's own `node_modules` (a private root —
|
|
150
|
+
* no hoisting into any other tree). Version conflicts within one graph are
|
|
151
|
+
* REFUSED rather than silently duplicated; the count and depth caps refuse
|
|
152
|
+
* runaway graphs by name.
|
|
153
|
+
*
|
|
154
|
+
* The PREINSTALLED arm is operator-gated: only when `allowPreinstalled` is set
|
|
155
|
+
* does a resolver-supplied directory get copied (bounded, path-escape-checked
|
|
156
|
+
* against `preinstalledRoot`, reparse-point-refused) into the extension's own
|
|
157
|
+
* tree, with the record's provenance stating that the installer ran no
|
|
158
|
+
* lifecycle script on it.
|
|
159
|
+
*
|
|
160
|
+
* @param packageDir - the extracted extension package directory.
|
|
161
|
+
* @param graph - the injected resolver/archive plus the bounds and the gate.
|
|
162
|
+
* @returns the locked dependency records, in materialization order.
|
|
163
|
+
*/
|
|
164
|
+
export async function installDependencyGraph(packageDir, graph) {
|
|
165
|
+
const maxDepth = graph.maxDepth ?? 3;
|
|
166
|
+
const maxPackages = graph.maxPackages ?? 64;
|
|
167
|
+
const declared = declaredDependencies(packageDir);
|
|
168
|
+
if (Object.keys(declared).length === 0)
|
|
169
|
+
return [];
|
|
170
|
+
const nodeModules = join(packageDir, 'node_modules');
|
|
171
|
+
const locked = [];
|
|
172
|
+
const visited = new Set();
|
|
173
|
+
const hoisted = new Map(); // name -> exact version already materialized
|
|
174
|
+
const queue = Object.entries(declared)
|
|
175
|
+
.map(([name, range]) => ({ name, range, depth: 0 }));
|
|
176
|
+
while (queue.length > 0) {
|
|
177
|
+
const entry = queue.shift();
|
|
178
|
+
if (visited.has(`${entry.name}@${entry.range}`))
|
|
179
|
+
continue;
|
|
180
|
+
visited.add(`${entry.name}@${entry.range}`);
|
|
181
|
+
if (entry.depth > maxDepth) {
|
|
182
|
+
throw new ManagementError('DEPENDENCY_UNSATISFIED', 'install', `the dependency graph exceeds the ${maxDepth}-level depth bound at ${entry.name}`, 'Flatten the dependency tree or raise the operator bound deliberately.');
|
|
183
|
+
}
|
|
184
|
+
if (locked.length >= maxPackages && !hoisted.has(entry.name)) {
|
|
185
|
+
throw new ManagementError('DEPENDENCY_UNSATISFIED', 'install', `the dependency graph exceeds the ${maxPackages}-package bound`, 'Reduce the graph or raise the operator bound deliberately.');
|
|
186
|
+
}
|
|
187
|
+
const resolvedEntry = await graph.resolver.resolve(entry.name, entry.range);
|
|
188
|
+
const existing = hoisted.get(resolvedEntry.name);
|
|
189
|
+
if (existing !== undefined && existing !== resolvedEntry.version) {
|
|
190
|
+
throw new ManagementError('DEPENDENCY_UNSATISFIED', 'install', `the dependency graph needs both ${resolvedEntry.name}@${existing} and ${resolvedEntry.name}@${resolvedEntry.version}; `
|
|
191
|
+
+ 'conflicting versions inside one extension are refused rather than silently duplicated', 'Pin the two requesters to one version, or publish a compatible version.');
|
|
192
|
+
}
|
|
193
|
+
if (existing !== undefined) {
|
|
194
|
+
// Already materialized at the same exact version: nothing more to fetch.
|
|
195
|
+
const transitive = declaredDependencies(join(nodeModules, resolvedEntry.name));
|
|
196
|
+
for (const [childName, childRange] of Object.entries(transitive)) {
|
|
197
|
+
if (!visited.has(`${childName}@${childRange}`))
|
|
198
|
+
queue.push({ name: childName, range: childRange, depth: entry.depth + 1 });
|
|
199
|
+
}
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
if (resolvedEntry.provenance === 'preinstalled') {
|
|
203
|
+
// The preinstalled arm: operator-gated, boundary-checked, copied (never
|
|
204
|
+
// linked), digested from the copied bytes, and recorded truthfully.
|
|
205
|
+
if (graph.allowPreinstalled !== true) {
|
|
206
|
+
throw new ManagementError('DEPENDENCY_UNSATISFIED', 'install', `${resolvedEntry.name}@${resolvedEntry.version} resolved to preinstalled content, but the preinstalled source is not enabled by the operator (allowPreinstalled)`, 'Enable the preinstalled source deliberately for this install, or resolve the dependency from registry bytes.');
|
|
207
|
+
}
|
|
208
|
+
if (graph.preinstalledRoot === undefined) {
|
|
209
|
+
throw new ManagementError('DEPENDENCY_UNSATISFIED', 'install', 'preinstalled content requires an operator-configured preinstalledRoot so the source boundary can be enforced', 'Set preinstalledRoot to the directory that holds the host-tree packages.');
|
|
210
|
+
}
|
|
211
|
+
const root = resolve(graph.preinstalledRoot);
|
|
212
|
+
const dir = resolve(resolvedEntry.dir);
|
|
213
|
+
const rel = relative(root, dir);
|
|
214
|
+
if (rel === '' || rel.startsWith('..') || isAbsolute(rel) || !existsSync(dir)) {
|
|
215
|
+
throw new ManagementError('DEPENDENCY_UNSATISFIED', 'install', `the preinstalled directory ${dir} is outside the operator-configured root ${root} (path-escape refused)`, 'Only preinstalled directories inside preinstalledRoot may be copied.');
|
|
216
|
+
}
|
|
217
|
+
// Honesty check: the content must BE the package the resolver claims.
|
|
218
|
+
let dirPackage;
|
|
219
|
+
try {
|
|
220
|
+
const parsed = JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8'));
|
|
221
|
+
dirPackage = parsed;
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
throw new ManagementError('DEPENDENCY_UNSATISFIED', 'install', `the preinstalled content at ${dir} ships an unreadable package.json: ${error instanceof Error ? error.message : String(error)}`, 'Preinstalled content must ship a parseable package.json.');
|
|
225
|
+
}
|
|
226
|
+
if (dirPackage.name !== resolvedEntry.name || dirPackage.version !== resolvedEntry.version) {
|
|
227
|
+
throw new ManagementError('DEPENDENCY_UNSATISFIED', 'install', `the preinstalled content at ${dir} is ${String(dirPackage.name)}@${String(dirPackage.version)}, not the resolved ${resolvedEntry.name}@${resolvedEntry.version}`, 'Point at the directory that actually holds the resolved package.');
|
|
228
|
+
}
|
|
229
|
+
const attempt = join(nodeModules, `.dep-${process.pid}-${Date.now().toString(36)}`);
|
|
230
|
+
mkdirSync(attempt, { recursive: true });
|
|
231
|
+
try {
|
|
232
|
+
// The scripts field is left UNTOUCHED and NO lifecycle script is run:
|
|
233
|
+
// the content arrived already materialized by a completed host install,
|
|
234
|
+
// and provenance:'preinstalled' records exactly that.
|
|
235
|
+
copyPreinstalledTree(dir, attempt, {
|
|
236
|
+
files: graph.maxPreinstalledFiles ?? DEFAULT_PREINSTALLED_FILES,
|
|
237
|
+
bytes: graph.maxPreinstalledBytes ?? DEFAULT_PREINSTALLED_BYTES,
|
|
238
|
+
});
|
|
239
|
+
const digest = digestContentOf(attempt);
|
|
240
|
+
const destination = join(nodeModules, resolvedEntry.name);
|
|
241
|
+
mkdirSync(join(destination, '..'), { recursive: true });
|
|
242
|
+
renameSync(attempt, destination);
|
|
243
|
+
hoisted.set(resolvedEntry.name, resolvedEntry.version);
|
|
244
|
+
locked.push({
|
|
245
|
+
name: resolvedEntry.name,
|
|
246
|
+
version: resolvedEntry.version,
|
|
247
|
+
integrity: digest,
|
|
248
|
+
resolvedFrom: entry.range,
|
|
249
|
+
provenance: 'preinstalled',
|
|
250
|
+
preinstalledFrom: resolvedEntry.dir,
|
|
251
|
+
});
|
|
252
|
+
const transitive = declaredDependencies(destination);
|
|
253
|
+
for (const [childName, childRange] of Object.entries(transitive)) {
|
|
254
|
+
if (!visited.has(`${childName}@${childRange}`))
|
|
255
|
+
queue.push({ name: childName, range: childRange, depth: entry.depth + 1 });
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
finally {
|
|
259
|
+
rmSync(attempt, { recursive: true, force: true });
|
|
260
|
+
}
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
const bytes = await graph.archive.fetch(resolvedEntry.tarball, {
|
|
264
|
+
maxBytes: 256 * 1024 * 1024,
|
|
265
|
+
timeoutMs: 120_000,
|
|
266
|
+
});
|
|
267
|
+
const digest = verifyIntegrity(bytes, resolvedEntry.integrity);
|
|
268
|
+
const attempt = join(nodeModules, `.dep-${process.pid}-${Date.now().toString(36)}`);
|
|
269
|
+
mkdirSync(attempt, { recursive: true });
|
|
270
|
+
try {
|
|
271
|
+
// The archive source strips the package root itself (the same contract
|
|
272
|
+
// stagedInstall relies on), so the extracted content IS the package.
|
|
273
|
+
graph.archive.extract(bytes, attempt, '');
|
|
274
|
+
refuseInstallScripts(attempt, resolvedEntry.name, resolvedEntry.version);
|
|
275
|
+
const destination = join(nodeModules, resolvedEntry.name);
|
|
276
|
+
mkdirSync(join(destination, '..'), { recursive: true });
|
|
277
|
+
renameSync(attempt, destination);
|
|
278
|
+
hoisted.set(resolvedEntry.name, resolvedEntry.version);
|
|
279
|
+
locked.push({
|
|
280
|
+
name: resolvedEntry.name,
|
|
281
|
+
version: resolvedEntry.version,
|
|
282
|
+
integrity: digest,
|
|
283
|
+
resolvedFrom: entry.range,
|
|
284
|
+
});
|
|
285
|
+
const transitive = declaredDependencies(destination);
|
|
286
|
+
for (const [childName, childRange] of Object.entries(transitive)) {
|
|
287
|
+
if (!visited.has(`${childName}@${childRange}`))
|
|
288
|
+
queue.push({ name: childName, range: childRange, depth: entry.depth + 1 });
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
finally {
|
|
292
|
+
rmSync(attempt, { recursive: true, force: true });
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return locked;
|
|
296
|
+
}
|
|
297
|
+
//# sourceMappingURL=dependencies.js.map
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Activation and deactivation (EXT-04, EXT-26, EXT-27, EXT-28).
|
|
3
|
+
*
|
|
4
|
+
* The two orderings this module exists to enforce:
|
|
5
|
+
*
|
|
6
|
+
* - **Activate commits last.** Contributions are published to a candidate set,
|
|
7
|
+
* and the catalog generation advances only once EVERY required contribution has
|
|
8
|
+
* been accepted. A half-activated package is worse than an inactive one,
|
|
9
|
+
* because tools would appear that nothing can serve.
|
|
10
|
+
* - **Deactivate persists intent first.** The inactive preference is made durable
|
|
11
|
+
* BEFORE anything is withdrawn. If withdrawal then fails or the process dies,
|
|
12
|
+
* the durable answer is still "inactive", so a restart cannot resurrect a
|
|
13
|
+
* package the operator switched off.
|
|
14
|
+
*
|
|
15
|
+
* Rollback is deliberately NARROW: a failed activation withdraws only the handles
|
|
16
|
+
* it published itself. Touching another extension's contributions would turn one
|
|
17
|
+
* bad package into an outage of every package.
|
|
18
|
+
*
|
|
19
|
+
* @module @try-works/tool-mode-extension-sdk/install/lifecycle
|
|
20
|
+
*/
|
|
21
|
+
import { ExtensionStore } from './store.ts';
|
|
22
|
+
import { summarize, type ExtensionState, type ModelReadiness } from './../state.ts';
|
|
23
|
+
/** One contribution a registrar can publish. */
|
|
24
|
+
export interface Contribution {
|
|
25
|
+
/** The extension that owns it. */
|
|
26
|
+
readonly extensionId: string;
|
|
27
|
+
/** What kind of contribution it is. */
|
|
28
|
+
readonly kind: 'tool' | 'skill' | 'implementation';
|
|
29
|
+
/** The caller-facing name for a tool or skill; the local id otherwise. */
|
|
30
|
+
readonly name: string;
|
|
31
|
+
/** The contract this contribution implements, for tools and implementations. */
|
|
32
|
+
readonly contractId?: string;
|
|
33
|
+
}
|
|
34
|
+
/** What can publish and withdraw contributions. Injected, so the SDK stays host-free. */
|
|
35
|
+
export interface ContributionRegistrar {
|
|
36
|
+
/**
|
|
37
|
+
* Publish one contribution.
|
|
38
|
+
* @param contribution - what to publish.
|
|
39
|
+
* @returns an opaque handle used to withdraw it.
|
|
40
|
+
*/
|
|
41
|
+
publish(contribution: Contribution): Promise<string> | string;
|
|
42
|
+
/**
|
|
43
|
+
* Withdraw a published contribution.
|
|
44
|
+
* @param handle - the handle returned by {@link ContributionRegistrar.publish}.
|
|
45
|
+
*/
|
|
46
|
+
withdraw(handle: string): Promise<void> | void;
|
|
47
|
+
}
|
|
48
|
+
/** A diagnostic about an activation that succeeded with caveats. */
|
|
49
|
+
export interface ActivationDiagnostic {
|
|
50
|
+
/** Stable code, e.g. `needs-preparation`. */
|
|
51
|
+
readonly code: 'needs-preparation' | 'not-registerable';
|
|
52
|
+
/** Human-readable detail. */
|
|
53
|
+
readonly message: string;
|
|
54
|
+
/** The contribution or deployment the diagnostic concerns. */
|
|
55
|
+
readonly subject?: string;
|
|
56
|
+
}
|
|
57
|
+
/** The outcome of an activation. */
|
|
58
|
+
export interface ActivationResult {
|
|
59
|
+
readonly extensionId: string;
|
|
60
|
+
readonly version: string;
|
|
61
|
+
/** The state as observed after the attempt. */
|
|
62
|
+
readonly state: ExtensionState;
|
|
63
|
+
/** Caveats that do not block activation (EXT-26). */
|
|
64
|
+
readonly diagnostics: readonly ActivationDiagnostic[];
|
|
65
|
+
/** The catalog generation after the attempt; unchanged when it failed. */
|
|
66
|
+
readonly generation: number;
|
|
67
|
+
}
|
|
68
|
+
/** The outcome of a deactivation. */
|
|
69
|
+
export interface DeactivationResult {
|
|
70
|
+
readonly extensionId: string;
|
|
71
|
+
readonly state: ExtensionState;
|
|
72
|
+
/**
|
|
73
|
+
* True only when every contribution was withdrawn AND every owned resource
|
|
74
|
+
* reported stopped. EXT-27 forbids reporting a package as fully stopped while
|
|
75
|
+
* an uncontrolled worker continues.
|
|
76
|
+
*/
|
|
77
|
+
readonly fullyStopped: boolean;
|
|
78
|
+
/** Why it is not fully stopped, when it is not. */
|
|
79
|
+
readonly cleanupFailure?: string;
|
|
80
|
+
/**
|
|
81
|
+
* The onWithdrawal hook's own failure, when it threw or rejected. The hook is
|
|
82
|
+
* a TEARDOWN observer: its error is surfaced here, never thrown — the
|
|
83
|
+
* deactivation's state write has already committed and must not be lost to a
|
|
84
|
+
* disposal callback that failed.
|
|
85
|
+
*/
|
|
86
|
+
readonly hookFailure?: string;
|
|
87
|
+
readonly generation: number;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* A teardown observer, invoked exactly once per withdrawn extension.
|
|
91
|
+
*
|
|
92
|
+
* `onWithdrawal` runs AFTER the lifecycle has finished withdrawing the
|
|
93
|
+
* extension's contribution handles and BEFORE the deactivation's final state
|
|
94
|
+
* write settles. A host uses it to dispose out-of-process resources (managed
|
|
95
|
+
* workers, native handles) at the one moment where the durable answer is
|
|
96
|
+
* already "inactive" and the registry surface is gone.
|
|
97
|
+
*/
|
|
98
|
+
export type OnWithdrawal = (extensionId: string) => void | Promise<void>;
|
|
99
|
+
/** Default grace period for a contribution to finish stopping, in milliseconds. */
|
|
100
|
+
export declare const DEFAULT_STOP_GRACE_MS = 5000;
|
|
101
|
+
/**
|
|
102
|
+
* Whether an extension's readiness should block activation.
|
|
103
|
+
*
|
|
104
|
+
* EXT-26 is explicit that a valid package with merely UNPREPARED model assets may
|
|
105
|
+
* be active with `needs-preparation` diagnostics: the tools exist and can be
|
|
106
|
+
* described, and preparation happens on first use. A FAILED model is different —
|
|
107
|
+
* it will not become ready by waiting.
|
|
108
|
+
* @param readiness - per-deployment readiness.
|
|
109
|
+
* @returns diagnostics, and whether activation may proceed.
|
|
110
|
+
*/
|
|
111
|
+
export declare function assessReadiness(readiness: Readonly<Record<string, ModelReadiness>>): {
|
|
112
|
+
readonly proceed: boolean;
|
|
113
|
+
readonly diagnostics: readonly ActivationDiagnostic[];
|
|
114
|
+
};
|
|
115
|
+
/** The extension lifecycle for one profile. */
|
|
116
|
+
export declare class ExtensionLifecycle {
|
|
117
|
+
#private;
|
|
118
|
+
constructor(options: {
|
|
119
|
+
readonly store: ExtensionStore;
|
|
120
|
+
readonly profile: string;
|
|
121
|
+
readonly registrar: ContributionRegistrar;
|
|
122
|
+
/** Starting catalog generation; defaults to 1. */
|
|
123
|
+
readonly generation?: number;
|
|
124
|
+
/**
|
|
125
|
+
* A teardown observer for host-managed out-of-process resources, invoked
|
|
126
|
+
* once per withdrawn extension AFTER handle teardown and BEFORE the final
|
|
127
|
+
* deactivation state write settles (see {@link OnWithdrawal}).
|
|
128
|
+
*/
|
|
129
|
+
readonly onWithdrawal?: OnWithdrawal;
|
|
130
|
+
});
|
|
131
|
+
/** The current catalog generation. */
|
|
132
|
+
get generation(): number;
|
|
133
|
+
/** Read the persisted states for this profile. */
|
|
134
|
+
states(): readonly ExtensionState[];
|
|
135
|
+
/** Read one extension's persisted state. */
|
|
136
|
+
stateOf(extensionId: string): ExtensionState | undefined;
|
|
137
|
+
/**
|
|
138
|
+
* Activate an installed extension (EXT-26).
|
|
139
|
+
*
|
|
140
|
+
* Verifies the installed bytes and locks, checks readiness, publishes every
|
|
141
|
+
* required contribution, and advances the generation only if all of that
|
|
142
|
+
* succeeded. On any failure the contributions THIS call published are withdrawn
|
|
143
|
+
* and the generation is left where it was.
|
|
144
|
+
* @param extensionId - the extension to activate.
|
|
145
|
+
* @param version - the installed version to activate.
|
|
146
|
+
* @returns the activation outcome.
|
|
147
|
+
* @throws ManagementError when the extension is not installed, its content changed, or a contribution cannot be registered.
|
|
148
|
+
*/
|
|
149
|
+
activate(extensionId: string, version: string): Promise<ActivationResult>;
|
|
150
|
+
/**
|
|
151
|
+
* Deactivate an extension (EXT-27).
|
|
152
|
+
*
|
|
153
|
+
* The inactive intent is made durable FIRST, so a failure or crash during
|
|
154
|
+
* withdrawal cannot resurrect the package on the next start.
|
|
155
|
+
* @param extensionId - the extension to deactivate.
|
|
156
|
+
* @returns the deactivation outcome, which reports honestly when it is not fully stopped.
|
|
157
|
+
*/
|
|
158
|
+
deactivate(extensionId: string): Promise<DeactivationResult>;
|
|
159
|
+
/**
|
|
160
|
+
* Enable or disable ONE tool inside an active extension (EXT-04).
|
|
161
|
+
*
|
|
162
|
+
* Independent of activation: the package stays active while a single tool is
|
|
163
|
+
* hidden from callers.
|
|
164
|
+
*
|
|
165
|
+
* ASYNC because the toggle also reconciles the PUBLISHED surface: a disabled
|
|
166
|
+
* tool is withdrawn from the registrar rather than merely remembered as off,
|
|
167
|
+
* and a re-enabled one is published again. When this instance does not own the
|
|
168
|
+
* surface — a CLI with no host attached — only the durable choice is recorded,
|
|
169
|
+
* because it cannot manage a registry another process owns.
|
|
170
|
+
* @param extensionId - the owning extension.
|
|
171
|
+
* @param toolName - the tool to toggle.
|
|
172
|
+
* @param enabled - the new visibility.
|
|
173
|
+
* @throws ManagementError when the extension or tool is unknown.
|
|
174
|
+
* @returns the state after the change.
|
|
175
|
+
*/
|
|
176
|
+
setToolEnabled(extensionId: string, toolName: string, enabled: boolean): Promise<ExtensionState>;
|
|
177
|
+
/**
|
|
178
|
+
* Whether a tool may be invoked right now.
|
|
179
|
+
* @param extensionId - the owning extension.
|
|
180
|
+
* @param toolName - the tool being invoked.
|
|
181
|
+
*/
|
|
182
|
+
admits(extensionId: string, toolName: string): boolean;
|
|
183
|
+
/**
|
|
184
|
+
* Uninstall an installed extension (EXT-04, EXT-28).
|
|
185
|
+
* @param extensionId - the extension to remove.
|
|
186
|
+
* @param options - `deactivate` must be set to remove an active package.
|
|
187
|
+
* @throws ManagementError `EXTENSION_IN_USE`, `BUILTIN_PROTECTED`, or `EXTENSION_INACTIVE`.
|
|
188
|
+
*/
|
|
189
|
+
uninstall(extensionId: string, options?: {
|
|
190
|
+
readonly deactivate?: boolean;
|
|
191
|
+
}): Promise<void>;
|
|
192
|
+
/**
|
|
193
|
+
* Record host-inspected readiness for an extension's declared deployments.
|
|
194
|
+
*
|
|
195
|
+
* This is the production writer `#readinessOf` reads: without it, every declared
|
|
196
|
+
* model stays `needs-preparation` forever and a model-backed package can never
|
|
197
|
+
* publish a callable tool. Inspection is the host's read-only EXT-18 surface, so
|
|
198
|
+
* recording it here is how "prepared" becomes a durable fact rather than a guess.
|
|
199
|
+
*
|
|
200
|
+
* Only values for deployments the CURRENT manifest declares are kept, matching the
|
|
201
|
+
* projection `#readinessOf` already applies, and `failed` is recorded so a failed
|
|
202
|
+
* deployment refuses activation instead of staying silent.
|
|
203
|
+
*
|
|
204
|
+
* ASYNC because a readiness CHANGE also moves the surface: a deployment that just
|
|
205
|
+
* became `failed` must have its tool withdrawn, and one that just became callable
|
|
206
|
+
* must be published. Recording without reconciling would leave the published
|
|
207
|
+
* snapshot stale, which is exactly the divergence admission exists to prevent.
|
|
208
|
+
* @param extensionId - the extension whose deployments were inspected.
|
|
209
|
+
* @param inspected - readiness keyed by deployment id.
|
|
210
|
+
* @returns the state after recording.
|
|
211
|
+
* @throws ManagementError when the extension is not installed.
|
|
212
|
+
*/
|
|
213
|
+
recordReadiness(extensionId: string, inspected: Readonly<Record<string, ModelReadiness>>): Promise<ExtensionState>;
|
|
214
|
+
}
|
|
215
|
+
export { summarize };
|
|
216
|
+
//# sourceMappingURL=lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.d.ts","sourceRoot":"","sources":["../../src/install/lifecycle.ts"],"names":[],"mappings":"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"}
|