@try-works/dsh-model-as-tool 0.1.2 → 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/lang-detect.d.ts +16 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/lang-detect.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/lang-detect.js +85 -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/stt-transcribe.d.ts +20 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/stt-transcribe.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/contracts/stt-transcribe.js +112 -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 +82 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/dsh.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/dsh.js +274 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/index.d.ts +26 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/index.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/index.js +48 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/meta.d.ts +104 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/meta.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/meta.js +55 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/registry.d.ts +107 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/registry.d.ts.map +1 -0
- package/node_modules/@try-works/tool-mode-contracts/lib/registry.js +246 -0
- package/node_modules/@try-works/tool-mode-contracts/package.json +34 -0
- 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 +50 -17
- 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,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Make the runtime SDK resolvable from inside an installed extension (EXT-02, EXT-19).
|
|
3
|
+
*
|
|
4
|
+
* THE GAP THIS CLOSES. Installing a package puts it at
|
|
5
|
+
* `<store>/extensions/<id>/<version>/`, which has no `node_modules`. An extension that
|
|
6
|
+
* declares `@try-works/tool-mode-extension-sdk` — which is what the extension protocol
|
|
7
|
+
* requires it to depend on — therefore cannot import it, and its entry fails with
|
|
8
|
+
* `ERR_MODULE_NOT_FOUND`. The package is discoverable and activatable and cannot RUN.
|
|
9
|
+
*
|
|
10
|
+
* This is the same class of problem the host hit when its own dependency was unpublished:
|
|
11
|
+
* a package is only loadable where its dependencies resolve. The store has no install step,
|
|
12
|
+
* so the link has to be made deliberately.
|
|
13
|
+
*
|
|
14
|
+
* WHY A DIRECTORY LINK RATHER THAN A COPY. The SDK is HOST-PROVIDED and versioned with the
|
|
15
|
+
* host, so copying it into every install would ship N copies that drift independently — and
|
|
16
|
+
* an extension running against a stale copy of the runtime is worse than one that refuses
|
|
17
|
+
* to start. The link keeps a single implementation.
|
|
18
|
+
*
|
|
19
|
+
* A JUNCTION ON WINDOWS: `symlinkSync` with a `'dir'` type needs elevation, while a
|
|
20
|
+
* junction does not, and junctions are the realistic Windows case in this repository's
|
|
21
|
+
* other escape tests for the same reason.
|
|
22
|
+
*
|
|
23
|
+
* @module @try-works/tool-mode-extension-sdk/install/runtime-link
|
|
24
|
+
*/
|
|
25
|
+
import { existsSync, mkdirSync, readFileSync, rmSync, symlinkSync } from 'node:fs';
|
|
26
|
+
import { createRequire } from 'node:module';
|
|
27
|
+
import { dirname, join } from 'node:path';
|
|
28
|
+
/** The one runtime dependency an extension is allowed to have (EXT-02). */
|
|
29
|
+
export const RUNTIME_SDK_NAME = '@try-works/tool-mode-extension-sdk';
|
|
30
|
+
/**
|
|
31
|
+
* Locate this package's own root.
|
|
32
|
+
*
|
|
33
|
+
* Resolved from the SDK itself rather than from the caller, so the link points at the
|
|
34
|
+
* runtime the INSTALLER is running from — the one that will actually execute the extension.
|
|
35
|
+
* @returns the absolute package root, or undefined when it cannot be found.
|
|
36
|
+
*/
|
|
37
|
+
export function runtimeSdkRoot() {
|
|
38
|
+
try {
|
|
39
|
+
const require = createRequire(import.meta.url);
|
|
40
|
+
// `package.json` rather than the entry, because the ROOT is what must be linked and the
|
|
41
|
+
// entry may be remapped by an exports condition.
|
|
42
|
+
return dirname(require.resolve(`${RUNTIME_SDK_NAME}/package.json`));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Make the runtime SDK resolvable from an installed extension.
|
|
50
|
+
*
|
|
51
|
+
* @param installPath - the installed package directory.
|
|
52
|
+
* @param sdkRoot - where the runtime lives; resolved automatically when omitted.
|
|
53
|
+
* @returns what happened, which is reported rather than assumed.
|
|
54
|
+
*/
|
|
55
|
+
export function linkRuntimeSdk(installPath, sdkRoot = runtimeSdkRoot()) {
|
|
56
|
+
if (sdkRoot === undefined) {
|
|
57
|
+
/**
|
|
58
|
+
* NOT FATAL. An extension that imports nothing (a declarative or tool-only package)
|
|
59
|
+
* runs fine without the link, so refusing the whole install would break working
|
|
60
|
+
* packages to fix a problem they do not have.
|
|
61
|
+
*/
|
|
62
|
+
return { linked: false, reason: 'sdk-not-locatable' };
|
|
63
|
+
}
|
|
64
|
+
const scopeDirectory = join(installPath, 'node_modules', '@try-works');
|
|
65
|
+
const linkPath = join(scopeDirectory, 'tool-mode-extension-sdk');
|
|
66
|
+
/**
|
|
67
|
+
* A PRE-EXISTING ENTRY IS NOT ASSUMED TO BE OURS.
|
|
68
|
+
*
|
|
69
|
+
* This was a real, reproduced escape. The first version returned `already-present` if
|
|
70
|
+
* ANYTHING existed at the link path — and an archive may legitimately SHIP that
|
|
71
|
+
* directory, because nothing about it is a traversal or an illegal name. The installer
|
|
72
|
+
* then never made the host link, and Node resolved the extension's bare
|
|
73
|
+
* `import '@try-works/tool-mode-extension-sdk'` to the PACKAGE-SUPPLIED module. The
|
|
74
|
+
* package was executing against its own copy of the runtime, and the operator was told
|
|
75
|
+
* the link was "already-present", which reads as success.
|
|
76
|
+
*
|
|
77
|
+
* The check is now on the CONTENT, not the existence: the entry must be the same package
|
|
78
|
+
* at the same version as the runtime the installer is running from. Anything else is
|
|
79
|
+
* refused, and refusal is the right answer rather than replacement — silently deleting
|
|
80
|
+
* files an archive shipped would make the installed bytes differ from the verified
|
|
81
|
+
* digest the operator approved.
|
|
82
|
+
*/
|
|
83
|
+
if (existsSync(linkPath)) {
|
|
84
|
+
const shipped = readPackageIdentity(linkPath);
|
|
85
|
+
const ours = readPackageIdentity(sdkRoot);
|
|
86
|
+
if (shipped === undefined || ours === undefined || shipped.name !== ours.name || shipped.version !== ours.version) {
|
|
87
|
+
return {
|
|
88
|
+
linked: false,
|
|
89
|
+
reason: 'sdk-shadowed',
|
|
90
|
+
path: linkPath,
|
|
91
|
+
detail: `the package ships its own ${RUNTIME_SDK_NAME}`
|
|
92
|
+
+ `${shipped === undefined ? ' (unreadable)' : `@${shipped.version}`}, `
|
|
93
|
+
+ `but the host provides ${ours === undefined ? 'an unreadable runtime' : `@${ours.version}`}. `
|
|
94
|
+
+ 'An extension must run against the host runtime, so this install is refused.',
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
return { linked: false, reason: 'already-present', path: linkPath, detail: `the host runtime @${ours.version} is already linked` };
|
|
98
|
+
}
|
|
99
|
+
try {
|
|
100
|
+
mkdirSync(scopeDirectory, { recursive: true });
|
|
101
|
+
/**
|
|
102
|
+
* A junction, which on Windows does not require elevation. `type` is ignored on POSIX,
|
|
103
|
+
* where this becomes a plain directory symlink.
|
|
104
|
+
*/
|
|
105
|
+
symlinkSync(sdkRoot, linkPath, 'junction');
|
|
106
|
+
return { linked: true, path: linkPath };
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
// Clean up a half-made link so a retry is not blocked by a broken entry.
|
|
110
|
+
rmSync(linkPath, { recursive: true, force: true });
|
|
111
|
+
return {
|
|
112
|
+
linked: false,
|
|
113
|
+
reason: 'link-failed',
|
|
114
|
+
path: linkPath,
|
|
115
|
+
detail: error instanceof Error ? error.message : String(error),
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
/** Read a package's name and version, or undefined when it cannot be read. */
|
|
120
|
+
function readPackageIdentity(packageRoot) {
|
|
121
|
+
try {
|
|
122
|
+
const manifest = JSON.parse(readFileSync(join(packageRoot, 'package.json'), 'utf8'));
|
|
123
|
+
if (typeof manifest.name !== 'string' || typeof manifest.version !== 'string')
|
|
124
|
+
return undefined;
|
|
125
|
+
return { name: manifest.name, version: manifest.version };
|
|
126
|
+
}
|
|
127
|
+
catch {
|
|
128
|
+
// An unreadable or absent manifest is NOT an identity match. A planted directory with
|
|
129
|
+
// a broken manifest must not be treated as the host runtime.
|
|
130
|
+
return undefined;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* Remove a runtime link, for an uninstall (EXT-24).
|
|
135
|
+
*
|
|
136
|
+
* Removed separately from the package directory so a caller that removes the link but keeps
|
|
137
|
+
* the package — or the reverse — does not end up with an extension whose imports resolve
|
|
138
|
+
* against a runtime it was not installed for.
|
|
139
|
+
* @param installPath - the installed package directory.
|
|
140
|
+
* @returns whether a link was removed.
|
|
141
|
+
*/
|
|
142
|
+
export function unlinkRuntimeSdk(installPath) {
|
|
143
|
+
const linkPath = join(installPath, 'node_modules', '@try-works', 'tool-mode-extension-sdk');
|
|
144
|
+
if (!existsSync(linkPath))
|
|
145
|
+
return false;
|
|
146
|
+
rmSync(linkPath, { recursive: true, force: true });
|
|
147
|
+
return true;
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=runtime-link.js.map
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local source-directory developer mode (EXT-06's optional fourth source).
|
|
3
|
+
*
|
|
4
|
+
* A source DIRECTORY is treated as a package source with the SAME discipline
|
|
5
|
+
* as archives: the operator configuration must explicitly allow it, the path's
|
|
6
|
+
* ancestor chain is reparse-point-checked, the tree is COPIED (a source
|
|
7
|
+
* checkout is mutable and must not become a live installation), reparse points
|
|
8
|
+
* INSIDE the tree are refused, the manifest is validated exactly like a packed
|
|
9
|
+
* package, install-time lifecycle scripts are refused (never run), and the
|
|
10
|
+
* installation lands INACTIVE with its source recorded. It is developer mode,
|
|
11
|
+
* not a production release path (EXT-06: "Optional developer mode only").
|
|
12
|
+
*
|
|
13
|
+
* @module @try-works/tool-mode-extension-sdk/install/source-directory
|
|
14
|
+
*/
|
|
15
|
+
import { type InstallPreview, type InstallProvenance, type StagedInstallResult } from './staged.ts';
|
|
16
|
+
import { type InstallDependencyGraph } from './dependencies.ts';
|
|
17
|
+
/**
|
|
18
|
+
* Install a local source directory in developer mode (EXT-06).
|
|
19
|
+
*
|
|
20
|
+
* @param options - the directory, the store, the operator allow-gate, and the
|
|
21
|
+
* same preview/dependency/provenance options the archive path takes.
|
|
22
|
+
* @returns the installed (INACTIVE) extension.
|
|
23
|
+
* @throws ManagementError for every rejection path.
|
|
24
|
+
*/
|
|
25
|
+
export declare function stagedInstallFromDirectory(options: {
|
|
26
|
+
readonly sourceDir: string;
|
|
27
|
+
readonly storeDir: string;
|
|
28
|
+
/** The operator config gate: source directories install ONLY when explicitly allowed. */
|
|
29
|
+
readonly allowSourceDirectories: boolean;
|
|
30
|
+
readonly preview?: (preview: InstallPreview) => void | Promise<void>;
|
|
31
|
+
readonly dependencies?: InstallDependencyGraph;
|
|
32
|
+
readonly provenance?: InstallProvenance;
|
|
33
|
+
readonly record?: boolean;
|
|
34
|
+
}): Promise<StagedInstallResult>;
|
|
35
|
+
//# sourceMappingURL=source-directory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"source-directory.d.ts","sourceRoot":"","sources":["../../src/install/source-directory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAOH,OAAO,EAAkB,KAAK,cAAc,EAAE,KAAK,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACnH,OAAO,EAAgD,KAAK,sBAAsB,EAAE,MAAM,mBAAmB,CAAA;AA6D7G;;;;;;;GAOG;AACH,wBAAsB,0BAA0B,CAAC,OAAO,EAAE;IACxD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,yFAAyF;IACzF,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAA;IACxC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpE,QAAQ,CAAC,YAAY,CAAC,EAAE,sBAAsB,CAAA;IAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,iBAAiB,CAAA;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAC1B,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA2H/B"}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Local source-directory developer mode (EXT-06's optional fourth source).
|
|
3
|
+
*
|
|
4
|
+
* A source DIRECTORY is treated as a package source with the SAME discipline
|
|
5
|
+
* as archives: the operator configuration must explicitly allow it, the path's
|
|
6
|
+
* ancestor chain is reparse-point-checked, the tree is COPIED (a source
|
|
7
|
+
* checkout is mutable and must not become a live installation), reparse points
|
|
8
|
+
* INSIDE the tree are refused, the manifest is validated exactly like a packed
|
|
9
|
+
* package, install-time lifecycle scripts are refused (never run), and the
|
|
10
|
+
* installation lands INACTIVE with its source recorded. It is developer mode,
|
|
11
|
+
* not a production release path (EXT-06: "Optional developer mode only").
|
|
12
|
+
*
|
|
13
|
+
* @module @try-works/tool-mode-extension-sdk/install/source-directory
|
|
14
|
+
*/
|
|
15
|
+
import { copyFileSync, existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from 'node:fs';
|
|
16
|
+
import { join, parse, resolve, sep } from 'node:path';
|
|
17
|
+
import { ManagementError } from "./../errors.js";
|
|
18
|
+
import { discoverExtension } from "./../discovery.js";
|
|
19
|
+
import { digestInstalledContent, ExtensionStore } from "./store.js";
|
|
20
|
+
import { installPathFor } from "./staged.js";
|
|
21
|
+
import { installDependencyGraph, refuseInstallScripts } from "./dependencies.js";
|
|
22
|
+
import { linkRuntimeSdk, RUNTIME_SDK_NAME } from "./runtime-link.js";
|
|
23
|
+
/** The dev-mode bounds for one directory copy. */
|
|
24
|
+
const MAX_DIRECTORY_FILES = 10_000;
|
|
25
|
+
const MAX_DIRECTORY_BYTES = 512 * 1024 * 1024;
|
|
26
|
+
/** Refuse a reparse point anywhere on the source directory's ancestor chain. */
|
|
27
|
+
function ancestorRefusal(target) {
|
|
28
|
+
const absolute = resolve(target);
|
|
29
|
+
const root = parse(absolute).root;
|
|
30
|
+
const components = absolute.slice(root.length).split(sep).filter(Boolean);
|
|
31
|
+
let cursor = root;
|
|
32
|
+
for (const component of components) {
|
|
33
|
+
cursor = join(cursor, component);
|
|
34
|
+
try {
|
|
35
|
+
if (lstatSync(cursor).isSymbolicLink()) {
|
|
36
|
+
return `the source directory passes through a symbolic link or junction at ${cursor}; developer-mode installs refuse reparse points`;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
/** Copy one directory tree, refusing reparse points and bounding the copy. */
|
|
46
|
+
function copyTree(source, destination, budget) {
|
|
47
|
+
mkdirSync(destination, { recursive: true });
|
|
48
|
+
for (const entry of readdirSync(source, { withFileTypes: true })) {
|
|
49
|
+
const from = join(source, entry.name);
|
|
50
|
+
const to = join(destination, entry.name);
|
|
51
|
+
if (entry.isSymbolicLink() || entry.isFile() === false && entry.isDirectory() === false) {
|
|
52
|
+
// Windows junctions appear as symlinks via dirent in modern Node;
|
|
53
|
+
// anything that is neither a plain file nor a directory is refused.
|
|
54
|
+
throw new ManagementError('INVALID_EXTENSION', 'install', `${from} is a reparse point; a source checkout must not smuggle links into the installation`, 'Remove the link or copy the referenced content explicitly; the installer never follows it.');
|
|
55
|
+
}
|
|
56
|
+
if (entry.isDirectory()) {
|
|
57
|
+
copyTree(from, to, budget);
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const stat = lstatSync(from);
|
|
61
|
+
budget.files += 1;
|
|
62
|
+
budget.bytes += stat.size;
|
|
63
|
+
if (budget.files > MAX_DIRECTORY_FILES || budget.bytes > MAX_DIRECTORY_BYTES) {
|
|
64
|
+
throw new ManagementError('INVALID_EXTENSION', 'install', `the source directory exceeds the developer-mode bounds (${MAX_DIRECTORY_FILES} files / ${MAX_DIRECTORY_BYTES} bytes)`, 'Reduce the checkout or pack it into an archive.');
|
|
65
|
+
}
|
|
66
|
+
copyFileSync(from, to);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Install a local source directory in developer mode (EXT-06).
|
|
71
|
+
*
|
|
72
|
+
* @param options - the directory, the store, the operator allow-gate, and the
|
|
73
|
+
* same preview/dependency/provenance options the archive path takes.
|
|
74
|
+
* @returns the installed (INACTIVE) extension.
|
|
75
|
+
* @throws ManagementError for every rejection path.
|
|
76
|
+
*/
|
|
77
|
+
export async function stagedInstallFromDirectory(options) {
|
|
78
|
+
if (!options.allowSourceDirectories) {
|
|
79
|
+
throw new ManagementError('INVALID_EXTENSION', 'install', 'source-directory installs are not allowed by the operator configuration', 'Enable the developer-mode source-directory source deliberately, or pack the directory into an archive.');
|
|
80
|
+
}
|
|
81
|
+
const source = resolve(options.sourceDir);
|
|
82
|
+
if (!existsSync(source)) {
|
|
83
|
+
throw new ManagementError('INVALID_EXTENSION', 'install', `the source directory ${source} does not exist`, 'Point at an existing checkout.');
|
|
84
|
+
}
|
|
85
|
+
const chainRefusal = ancestorRefusal(source);
|
|
86
|
+
if (chainRefusal !== undefined) {
|
|
87
|
+
throw new ManagementError('INVALID_EXTENSION', 'install', chainRefusal, 'Use a path free of junctions and symlinks.');
|
|
88
|
+
}
|
|
89
|
+
const storeDir = resolve(options.storeDir);
|
|
90
|
+
const staging = join(storeDir, '.staging');
|
|
91
|
+
const attempt = join(staging, `source-${process.pid}-${Date.now().toString(36)}`);
|
|
92
|
+
mkdirSync(attempt, { recursive: true });
|
|
93
|
+
try {
|
|
94
|
+
copyTree(source, attempt, { files: 0, bytes: 0 });
|
|
95
|
+
const discovery = discoverExtension(attempt);
|
|
96
|
+
// Install-time lifecycle scripts are refused, never run (EXT-10).
|
|
97
|
+
refuseInstallScripts(attempt, discovery.packageName, discovery.packageVersion);
|
|
98
|
+
let lockedDependencies = [];
|
|
99
|
+
let declared = 0;
|
|
100
|
+
try {
|
|
101
|
+
declared = Object.keys(JSON.parse(readFileSync(join(attempt, 'package.json'), 'utf8')).dependencies ?? {}).length;
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
// Discovery already read package.json.
|
|
105
|
+
}
|
|
106
|
+
if (declared > 0) {
|
|
107
|
+
if (options.dependencies === undefined) {
|
|
108
|
+
throw new ManagementError('DEPENDENCY_UNSATISFIED', 'install', `${discovery.packageName} declares ${declared} runtime dependenc${declared === 1 ? 'y' : 'ies'} but no dependency-graph installer was provided`, 'Provide the operator-configured registry resolver, or bundle the dependencies.');
|
|
109
|
+
}
|
|
110
|
+
lockedDependencies = await installDependencyGraph(attempt, options.dependencies);
|
|
111
|
+
}
|
|
112
|
+
if (options.preview !== undefined) {
|
|
113
|
+
const manifest = discovery.manifest;
|
|
114
|
+
await options.preview({
|
|
115
|
+
extensionId: discovery.packageName,
|
|
116
|
+
version: discovery.packageVersion,
|
|
117
|
+
permissions: manifest.permissions,
|
|
118
|
+
models: manifest.models.map(model => ({
|
|
119
|
+
id: model.id,
|
|
120
|
+
assetSet: model.assetSet,
|
|
121
|
+
platforms: model.platforms.map(platform => `${platform.os}-${platform.arch}${platform.accelerator === undefined ? '' : `-${platform.accelerator}`}`),
|
|
122
|
+
})),
|
|
123
|
+
licenses: (manifest.licenses ?? []).map(layer => `${layer.layer}: ${layer.name}`),
|
|
124
|
+
downloadImplications: 'developer-mode directory source: nothing is downloaded; the checkout was copied and verified',
|
|
125
|
+
requiresApproval: false,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
const destination = installPathFor(storeDir, discovery.packageName, discovery.packageVersion);
|
|
129
|
+
if (existsSync(destination)) {
|
|
130
|
+
throw new ManagementError('UPGRADE_FAILED', 'install', `${discovery.packageName}@${discovery.packageVersion} is already installed`, 'Install a different version, or uninstall the existing one first.');
|
|
131
|
+
}
|
|
132
|
+
mkdirSync(join(destination, '..'), { recursive: true });
|
|
133
|
+
renameSync(attempt, destination);
|
|
134
|
+
const runtimeLinkDiagnostic = linkRuntimeSdk(destination);
|
|
135
|
+
if (runtimeLinkDiagnostic.reason === 'sdk-shadowed') {
|
|
136
|
+
rmSync(destination, { recursive: true, force: true });
|
|
137
|
+
throw new ManagementError('INVALID_EXTENSION', 'install', runtimeLinkDiagnostic.detail ?? 'the package ships its own copy of the host runtime SDK', 'Remove node_modules/' + RUNTIME_SDK_NAME + ' from the checkout.');
|
|
138
|
+
}
|
|
139
|
+
const contentDigest = digestInstalledContent(destination);
|
|
140
|
+
writeFileSync(join(destination, '.tool-mode-install.json'), `${JSON.stringify({
|
|
141
|
+
extensionId: discovery.packageName,
|
|
142
|
+
version: discovery.packageVersion,
|
|
143
|
+
archiveDigest: contentDigest, // a directory has no archive; the content digest is the identity
|
|
144
|
+
...runtimeLinkDiagnostic === undefined ? {} : { runtimeLink: runtimeLinkDiagnostic },
|
|
145
|
+
source: { kind: 'local-directory', requested: source },
|
|
146
|
+
...lockedDependencies.length === 0 ? {} : { dependencies: lockedDependencies },
|
|
147
|
+
...options.provenance === undefined ? {} : { provenance: options.provenance },
|
|
148
|
+
installedAt: new Date().toISOString(),
|
|
149
|
+
}, null, 2)}\n`);
|
|
150
|
+
if (options.record !== false) {
|
|
151
|
+
const store = new ExtensionStore(storeDir);
|
|
152
|
+
store.recordInstall({
|
|
153
|
+
extensionId: discovery.packageName,
|
|
154
|
+
version: discovery.packageVersion,
|
|
155
|
+
installPath: destination,
|
|
156
|
+
archiveDigest: contentDigest,
|
|
157
|
+
...runtimeLinkDiagnostic === undefined ? {} : { runtimeLink: runtimeLinkDiagnostic },
|
|
158
|
+
contentDigest,
|
|
159
|
+
source: { kind: 'local-directory', requested: source },
|
|
160
|
+
...lockedDependencies.length === 0 ? {} : { dependencies: lockedDependencies },
|
|
161
|
+
...options.provenance === undefined ? {} : { provenance: options.provenance },
|
|
162
|
+
installedAt: new Date().toISOString(),
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
return {
|
|
166
|
+
extensionId: discovery.packageName,
|
|
167
|
+
version: discovery.packageVersion,
|
|
168
|
+
installPath: destination,
|
|
169
|
+
activation: 'inactive',
|
|
170
|
+
discovery,
|
|
171
|
+
archiveDigest: contentDigest,
|
|
172
|
+
...runtimeLinkDiagnostic === undefined ? {} : { runtimeLink: runtimeLinkDiagnostic },
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
finally {
|
|
176
|
+
rmSync(attempt, { recursive: true, force: true });
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
//# sourceMappingURL=source-directory.js.map
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Staged installation (EXT-07, EXT-08).
|
|
3
|
+
*
|
|
4
|
+
* The ordering is the security property. A package is fetched into quarantine,
|
|
5
|
+
* verified, inspected as DATA, validated, and only then promoted into the store —
|
|
6
|
+
* and promotion is not activation. Nothing in this module imports extension code,
|
|
7
|
+
* runs inference, warms a model, or publishes a tool (EXT-07).
|
|
8
|
+
*
|
|
9
|
+
* The fetch and extract steps are INJECTED rather than implemented here, for two
|
|
10
|
+
* reasons: the SDK must stay free of a network stack and an archive library, and
|
|
11
|
+
* a test must be able to drive every rejection path without a real download or a
|
|
12
|
+
* real filesystem. The host supplies the real implementations.
|
|
13
|
+
*
|
|
14
|
+
* @module @try-works/tool-mode-extension-sdk/install/staged
|
|
15
|
+
*/
|
|
16
|
+
import { type ExtensionDiscovery } from './../discovery.ts';
|
|
17
|
+
import { type InstallDependencyGraph } from './dependencies.ts';
|
|
18
|
+
import { type ArchiveEntry, type ArchiveLimits } from './archive.ts';
|
|
19
|
+
/** How an archive was obtained. */
|
|
20
|
+
export interface InstallSource {
|
|
21
|
+
/** Where the archive came from, for the receipt. */
|
|
22
|
+
readonly kind: 'registry' | 'url' | 'local';
|
|
23
|
+
/** The requested source, recorded verbatim for the audit trail. */
|
|
24
|
+
readonly requested: string;
|
|
25
|
+
}
|
|
26
|
+
/** What a host must supply to install: bytes in, files out. */
|
|
27
|
+
export interface ArchiveSource {
|
|
28
|
+
/**
|
|
29
|
+
* Fetch the archive, bounded.
|
|
30
|
+
*
|
|
31
|
+
* The implementation MUST enforce the byte and time limits it is given: the
|
|
32
|
+
* installer cannot bound a stream it never sees.
|
|
33
|
+
* @param source - what to fetch.
|
|
34
|
+
* @param limits - the byte and time bounds.
|
|
35
|
+
* @returns the archive bytes.
|
|
36
|
+
*/
|
|
37
|
+
fetch(source: InstallSource, limits: {
|
|
38
|
+
readonly maxBytes: number;
|
|
39
|
+
readonly timeoutMs: number;
|
|
40
|
+
}): Promise<Uint8Array>;
|
|
41
|
+
/**
|
|
42
|
+
* List an archive's entries WITHOUT extracting them.
|
|
43
|
+
* @param bytes - the archive bytes.
|
|
44
|
+
* @returns the entry list.
|
|
45
|
+
*/
|
|
46
|
+
list(bytes: Uint8Array): ArchiveEntry[];
|
|
47
|
+
/**
|
|
48
|
+
* Extract a validated archive into a directory.
|
|
49
|
+
*
|
|
50
|
+
* Only called after {@link validateArchiveEntries} has accepted the entry list,
|
|
51
|
+
* so an implementation may assume every path is package-relative and link-free.
|
|
52
|
+
* @param bytes - the archive bytes.
|
|
53
|
+
* @param destination - the directory to extract into.
|
|
54
|
+
* @param root - the package root prefix to strip, from `findPackageRoot`.
|
|
55
|
+
*/
|
|
56
|
+
extract(bytes: Uint8Array, destination: string, root: string): void;
|
|
57
|
+
}
|
|
58
|
+
/** Bounds for one installation attempt. */
|
|
59
|
+
export interface InstallLimits {
|
|
60
|
+
/** Maximum archive bytes to fetch. */
|
|
61
|
+
readonly maxArchiveBytes: number;
|
|
62
|
+
/** Fetch timeout in milliseconds. */
|
|
63
|
+
readonly fetchTimeoutMs: number;
|
|
64
|
+
/** Entry-list bounds. */
|
|
65
|
+
readonly archive: ArchiveLimits;
|
|
66
|
+
}
|
|
67
|
+
/** Conservative install limits. */
|
|
68
|
+
export declare const DEFAULT_INSTALL_LIMITS: InstallLimits;
|
|
69
|
+
/** The result of a successful stage-then-promote installation. */
|
|
70
|
+
export interface StagedInstallResult {
|
|
71
|
+
/** Extension identity from the validated manifest. */
|
|
72
|
+
readonly extensionId: string;
|
|
73
|
+
/** Package version from the validated manifest. */
|
|
74
|
+
readonly version: string;
|
|
75
|
+
/** Absolute path of the immutable installation directory. */
|
|
76
|
+
readonly installPath: string;
|
|
77
|
+
/**
|
|
78
|
+
* Always `'inactive'`. Installation is not activation (EXT-07); the field is
|
|
79
|
+
* returned explicitly so a caller cannot mistake a successful install for a
|
|
80
|
+
* usable tool.
|
|
81
|
+
*/
|
|
82
|
+
readonly activation: 'inactive';
|
|
83
|
+
/** What was discovered, without any of it having been executed. */
|
|
84
|
+
readonly discovery: ExtensionDiscovery;
|
|
85
|
+
/** The verified archive digest, for the receipt (EXT-12). */
|
|
86
|
+
readonly archiveDigest: string;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* The EXT-08 operator approval PREVIEW, produced before materialization.
|
|
90
|
+
*
|
|
91
|
+
* The caller inspects the permissions/licences/models/download implications
|
|
92
|
+
* and may refuse (throw) to abort the install while nothing is promoted.
|
|
93
|
+
*/
|
|
94
|
+
export interface InstallPreview {
|
|
95
|
+
readonly extensionId: string;
|
|
96
|
+
readonly version: string;
|
|
97
|
+
readonly permissions: ExtensionDiscovery['manifest']['permissions'];
|
|
98
|
+
/** Declared model asset sets with their platform descriptors. */
|
|
99
|
+
readonly models: readonly {
|
|
100
|
+
readonly id: string;
|
|
101
|
+
readonly assetSet: string;
|
|
102
|
+
readonly platforms: readonly string[];
|
|
103
|
+
}[];
|
|
104
|
+
/** The declared licence layers, as `layer: name` strings. */
|
|
105
|
+
readonly licenses: readonly string[];
|
|
106
|
+
/** What the install implies for downloads and preparation consent. */
|
|
107
|
+
readonly downloadImplications: string;
|
|
108
|
+
/** Whether this install warrants an explicit operator approval. */
|
|
109
|
+
readonly requiresApproval: boolean;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Provenance fields recorded AS DATA, NEVER AS TRUST (EXT-12): where the
|
|
113
|
+
* registry reported integrity/provenance flags, they travel with the install
|
|
114
|
+
* record for audit; verification is always against the operator-supplied
|
|
115
|
+
* digest, never against these fields alone.
|
|
116
|
+
*/
|
|
117
|
+
export interface InstallProvenance {
|
|
118
|
+
/** The registry-recorded integrity string, verbatim. */
|
|
119
|
+
readonly registryIntegrity?: string;
|
|
120
|
+
/** Whether the registry reported a build-provenance attestation. */
|
|
121
|
+
readonly provenance?: boolean;
|
|
122
|
+
/** Reported attestation references, verbatim. */
|
|
123
|
+
readonly attestations?: readonly string[];
|
|
124
|
+
/** Reported signature references, verbatim. */
|
|
125
|
+
readonly signatures?: readonly string[];
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Install an extension into an operator-owned store, staged (EXT-08).
|
|
129
|
+
*
|
|
130
|
+
* Steps, in order: fetch into quarantine → verify integrity → list entries →
|
|
131
|
+
* validate the entry list → extract → discover → validate compatibility →
|
|
132
|
+
* promote atomically → record the installation. A failure at any step removes the
|
|
133
|
+
* quarantine, so a partial install never becomes visible.
|
|
134
|
+
*
|
|
135
|
+
* The store is RECORDED rather than merely written to: an installation that is not
|
|
136
|
+
* in the lock document cannot be activated later, because nothing would know what
|
|
137
|
+
* bytes were approved.
|
|
138
|
+
*
|
|
139
|
+
* @param options - the source, the store, the injected archive source, and limits.
|
|
140
|
+
* @returns the installed (but inactive) extension.
|
|
141
|
+
* @throws ManagementError for every rejection path.
|
|
142
|
+
*/
|
|
143
|
+
export declare function stagedInstall(options: {
|
|
144
|
+
readonly source: InstallSource;
|
|
145
|
+
/** Absolute path of the operator-owned extension store. */
|
|
146
|
+
readonly storeDir: string;
|
|
147
|
+
/** The declared SHA-512 of the archive (EXT-12). */
|
|
148
|
+
readonly expectedSha512: string;
|
|
149
|
+
readonly archive: ArchiveSource;
|
|
150
|
+
readonly limits?: InstallLimits;
|
|
151
|
+
/** When false, the lock document is not updated. Defaults to true. */
|
|
152
|
+
readonly record?: boolean;
|
|
153
|
+
/**
|
|
154
|
+
* The injected dependency graph installer (EXT-09). When the package
|
|
155
|
+
* declares runtime dependencies and this is omitted, the install REFUSES
|
|
156
|
+
* with DEPENDENCY_UNSATISFIED rather than materializing an unresolvable
|
|
157
|
+
* extension.
|
|
158
|
+
*/
|
|
159
|
+
readonly dependencies?: InstallDependencyGraph;
|
|
160
|
+
/** The EXT-08 operator approval preview, called before materialization. */
|
|
161
|
+
readonly preview?: (preview: InstallPreview) => void | Promise<void>;
|
|
162
|
+
/** Provenance fields recorded as data, never as trust (EXT-12). */
|
|
163
|
+
readonly provenance?: InstallProvenance;
|
|
164
|
+
}): Promise<StagedInstallResult>;
|
|
165
|
+
/**
|
|
166
|
+
* The immutable installation directory for one extension version (EXT-33).
|
|
167
|
+
*
|
|
168
|
+
* The identity is VALIDATED rather than merely escaped. Escaping would turn
|
|
169
|
+
* `../../etc` into a harmless-looking directory name and silently install
|
|
170
|
+
* something under a package name that no registry would accept; refusing says
|
|
171
|
+
* what is actually wrong.
|
|
172
|
+
* @param storeDir - the operator's store root.
|
|
173
|
+
* @param extensionId - the validated extension identity.
|
|
174
|
+
* @param version - the validated version.
|
|
175
|
+
* @returns the absolute installation path.
|
|
176
|
+
* @throws ManagementError when the identity or version is not a legal one.
|
|
177
|
+
*/
|
|
178
|
+
export declare function installPathFor(storeDir: string, extensionId: string, version: string): string;
|
|
179
|
+
//# sourceMappingURL=staged.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"staged.d.ts","sourceRoot":"","sources":["../../src/install/staged.ts"],"names":[],"mappings":"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"}
|