@try-works/dsh-model-as-tool 0.4.0 → 0.4.2
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/client/client.model-tools.js +4 -0
- package/client/index.js +17 -0
- package/lib/extension-dependencies.d.ts +15 -2
- package/lib/extension-dependencies.d.ts.map +1 -1
- package/lib/extension-dependencies.js +54 -18
- package/lib/extensions-api.d.ts +3 -1
- package/lib/extensions-api.d.ts.map +1 -1
- package/lib/extensions-service.d.ts +10 -0
- package/lib/extensions-service.d.ts.map +1 -1
- package/lib/extensions-service.js +273 -7
- package/lib/index.d.ts +5 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +7 -0
- package/package.json +1 -1
- package/remote/spec.mjs +1 -0
package/client/index.js
CHANGED
|
@@ -1526,6 +1526,23 @@ window.__ModuleLoader__.load({
|
|
|
1526
1526
|
await dualWriteDisabledExtensions(id, 'disable')
|
|
1527
1527
|
}
|
|
1528
1528
|
setExtRemote({ kind: 'ready', namespace, ...(await describeExtensions(namespace)) })
|
|
1529
|
+
// A store write and the following describe can land in either order
|
|
1530
|
+
// under load. One bounded re-read after a successful action settles
|
|
1531
|
+
// the row's controls (the Enable switch appears on an install) without
|
|
1532
|
+
// asking the operator to reopen the page. mounted() gates a stale
|
|
1533
|
+
// update after the dialog closes.
|
|
1534
|
+
setTimeout(() => {
|
|
1535
|
+
void (async () => {
|
|
1536
|
+
try {
|
|
1537
|
+
const settled = modelToolsRemote(ctx, mounted())
|
|
1538
|
+
if (settled !== null) {
|
|
1539
|
+
setExtRemote({ kind: 'ready', namespace: settled, ...(await describeExtensions(settled)) })
|
|
1540
|
+
}
|
|
1541
|
+
} catch (settleError) {
|
|
1542
|
+
// The snapshot already rendered is the last known host truth.
|
|
1543
|
+
}
|
|
1544
|
+
})()
|
|
1545
|
+
}, 500)
|
|
1529
1546
|
} catch (error) {
|
|
1530
1547
|
setExtRowError({ id, text: remoteErrorText(error) })
|
|
1531
1548
|
// The action may have changed host state before failing. Read it back,
|
|
@@ -252,8 +252,17 @@ export interface RegistrySessionOptions {
|
|
|
252
252
|
readonly archiveFactory: (fetcher: (source: InstallSource) => Promise<Uint8Array>) => ArchiveSource;
|
|
253
253
|
/** Hard cap on one downloaded package tarball; defaults to the SDK archive bound. */
|
|
254
254
|
readonly maxTarballBytes?: number;
|
|
255
|
-
/**
|
|
256
|
-
readonly
|
|
255
|
+
/** Packument/metadata request timeout (wall clock); default 30 s. */
|
|
256
|
+
readonly metadataTimeoutMs?: number;
|
|
257
|
+
/**
|
|
258
|
+
* Tarball IDLE timeout: abort only after this long with NO bytes arriving.
|
|
259
|
+
*
|
|
260
|
+
* A large dependency (onnxruntime-node is hundreds of MB) must not be aborted
|
|
261
|
+
* by the short metadata budget; the sha512 is verified after the transfer, so
|
|
262
|
+
* the byte cap is the real bound and a slow-but-moving stream is fine.
|
|
263
|
+
* Default 10 minutes.
|
|
264
|
+
*/
|
|
265
|
+
readonly tarballTimeoutMs?: number;
|
|
257
266
|
/** Injected fetch, for tests. Defaults to the global fetch. */
|
|
258
267
|
readonly fetchImpl?: typeof fetch;
|
|
259
268
|
}
|
|
@@ -279,6 +288,10 @@ export interface RegistrySession {
|
|
|
279
288
|
*/
|
|
280
289
|
download(source: InstallSource, signal?: AbortSignal): Promise<Uint8Array>;
|
|
281
290
|
}
|
|
291
|
+
/** The default packument timeout: metadata is small and must answer promptly. */
|
|
292
|
+
export declare const DEFAULT_REGISTRY_METADATA_TIMEOUT_MS = 30000;
|
|
293
|
+
/** The default tarball IDLE timeout: a large dependency may transfer for minutes. */
|
|
294
|
+
export declare const DEFAULT_REGISTRY_TARBALL_TIMEOUT_MS: number;
|
|
282
295
|
/**
|
|
283
296
|
* Whether one published version satisfies a semver range.
|
|
284
297
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extension-dependencies.d.ts","sourceRoot":"","sources":["../src/extension-dependencies.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"extension-dependencies.d.ts","sourceRoot":"","sources":["../src/extension-dependencies.ts"],"names":[],"mappings":"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"}
|
|
@@ -401,30 +401,48 @@ function encodePackageName(name) {
|
|
|
401
401
|
// npm encodes scoped names' slash as %2f and leaves the leading @ readable.
|
|
402
402
|
return name.startsWith('@') ? name.replace('/', '%2f') : encodeURIComponent(name);
|
|
403
403
|
}
|
|
404
|
-
/**
|
|
405
|
-
|
|
404
|
+
/** The default packument timeout: metadata is small and must answer promptly. */
|
|
405
|
+
export const DEFAULT_REGISTRY_METADATA_TIMEOUT_MS = 30_000;
|
|
406
|
+
/** The default tarball IDLE timeout: a large dependency may transfer for minutes. */
|
|
407
|
+
export const DEFAULT_REGISTRY_TARBALL_TIMEOUT_MS = 10 * 60_000;
|
|
408
|
+
/** Read a response body with a hard byte cap and an optional IDLE timeout. */
|
|
409
|
+
async function readBoundedBody(response, maxBytes, options) {
|
|
410
|
+
const tooLarge = (declared) => new RegistryError('registry-tarball-too-large', options?.tooLargeMessage?.(declared) ?? `the response is over the ${maxBytes}-byte cap`);
|
|
406
411
|
const declared = Number(response.headers.get('content-length') ?? Number.NaN);
|
|
407
412
|
if (Number.isFinite(declared) && declared > maxBytes) {
|
|
408
413
|
await response.body?.cancel();
|
|
409
|
-
throw
|
|
414
|
+
throw tooLarge(declared);
|
|
410
415
|
}
|
|
411
416
|
if (response.body === null) {
|
|
412
417
|
const buffer = new Uint8Array(await response.arrayBuffer());
|
|
413
418
|
if (buffer.byteLength > maxBytes)
|
|
414
|
-
throw
|
|
419
|
+
throw tooLarge(buffer.byteLength);
|
|
415
420
|
return buffer;
|
|
416
421
|
}
|
|
417
422
|
const reader = response.body.getReader();
|
|
418
423
|
const chunks = [];
|
|
419
424
|
let total = 0;
|
|
420
425
|
for (;;) {
|
|
421
|
-
const
|
|
426
|
+
const idleTimeoutMs = options?.idleTimeoutMs;
|
|
427
|
+
const idleMessage = options?.idleMessage;
|
|
428
|
+
const { done, value } = idleTimeoutMs === undefined
|
|
429
|
+
? await reader.read()
|
|
430
|
+
: await new Promise((resolve, reject) => {
|
|
431
|
+
const timer = setTimeout(() => {
|
|
432
|
+
// Abort the transfer, then name WHY in the caller's vocabulary.
|
|
433
|
+
void reader.cancel(new Error('registry tarball idle timeout')).catch(() => { });
|
|
434
|
+
reject(new RegistryError('registry-tarball-fetch-failed', idleMessage?.() ?? `no bytes arrived for ${idleTimeoutMs} ms (idle timeout)`));
|
|
435
|
+
}, idleTimeoutMs);
|
|
436
|
+
reader.read().then(result => { clearTimeout(timer); resolve(result); }, error => { clearTimeout(timer); reject(error); });
|
|
437
|
+
});
|
|
422
438
|
if (done)
|
|
423
439
|
break;
|
|
440
|
+
if (value === undefined)
|
|
441
|
+
continue;
|
|
424
442
|
total += value.byteLength;
|
|
425
443
|
if (total > maxBytes) {
|
|
426
444
|
await reader.cancel();
|
|
427
|
-
throw
|
|
445
|
+
throw tooLarge(total);
|
|
428
446
|
}
|
|
429
447
|
chunks.push(value);
|
|
430
448
|
}
|
|
@@ -737,13 +755,14 @@ function selectPublishedVersion(name, spec, packument) {
|
|
|
737
755
|
export function createRegistrySession(options) {
|
|
738
756
|
const registryUrl = normalizeRegistryUrl(options.registryUrl);
|
|
739
757
|
const maxTarballBytes = options.maxTarballBytes ?? MAX_DEPENDENCY_ARCHIVE_BYTES;
|
|
740
|
-
const
|
|
758
|
+
const metadataTimeoutMs = options.metadataTimeoutMs ?? DEFAULT_REGISTRY_METADATA_TIMEOUT_MS;
|
|
759
|
+
const tarballTimeoutMs = options.tarballTimeoutMs ?? DEFAULT_REGISTRY_TARBALL_TIMEOUT_MS;
|
|
741
760
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
742
761
|
/** tarball URL per `name@version` key, registered by resolve(). */
|
|
743
762
|
const tarballs = new Map();
|
|
744
|
-
const
|
|
745
|
-
? AbortSignal.timeout(
|
|
746
|
-
: AbortSignal.any([signal, AbortSignal.timeout(
|
|
763
|
+
const timedMetadata = (signal) => signal === undefined
|
|
764
|
+
? AbortSignal.timeout(metadataTimeoutMs)
|
|
765
|
+
: AbortSignal.any([signal, AbortSignal.timeout(metadataTimeoutMs)]);
|
|
747
766
|
const requireRegistry = () => {
|
|
748
767
|
if (registryUrl === '') {
|
|
749
768
|
throw new RegistryError('registry-not-configured', 'no npm registry is configured (config.extensionRegistry)');
|
|
@@ -761,11 +780,11 @@ export function createRegistrySession(options) {
|
|
|
761
780
|
try {
|
|
762
781
|
response = await fetchImpl(url, {
|
|
763
782
|
headers: { accept: 'application/vnd.npm.install-v1+json, application/json' },
|
|
764
|
-
signal:
|
|
783
|
+
signal: timedMetadata(signal),
|
|
765
784
|
});
|
|
766
785
|
}
|
|
767
786
|
catch (error) {
|
|
768
|
-
throw new RegistryError('registry-unavailable', `the npm registry ${base} could not be reached: ${messageOf(error)}`, { cause: error, transport: true });
|
|
787
|
+
throw new RegistryError('registry-unavailable', `the npm registry ${base} could not be reached for ${name} within ${metadataTimeoutMs} ms (metadata timeout): ${messageOf(error)}`, { cause: error, transport: true });
|
|
769
788
|
}
|
|
770
789
|
if (!response.ok) {
|
|
771
790
|
await response.body?.cancel();
|
|
@@ -777,7 +796,9 @@ export function createRegistrySession(options) {
|
|
|
777
796
|
}
|
|
778
797
|
throw new RegistryError('registry-invalid-metadata', `the npm registry ${base} refused ${name} with HTTP ${response.status}`);
|
|
779
798
|
}
|
|
780
|
-
const metadata = await readBoundedBody(response, MAX_REGISTRY_METADATA_BYTES
|
|
799
|
+
const metadata = await readBoundedBody(response, MAX_REGISTRY_METADATA_BYTES, {
|
|
800
|
+
tooLargeMessage: declared => `the registry metadata for ${name} is over the ${MAX_REGISTRY_METADATA_BYTES}-byte cap${declared === undefined ? '' : ` (declared ${declared})`}`,
|
|
801
|
+
});
|
|
781
802
|
let parsed;
|
|
782
803
|
try {
|
|
783
804
|
parsed = JSON.parse(new TextDecoder().decode(metadata));
|
|
@@ -806,24 +827,39 @@ export function createRegistrySession(options) {
|
|
|
806
827
|
// resolve-then-fetch, so this is a programming error, not a package refusal.
|
|
807
828
|
throw new RegistryError('registry-invalid-metadata', `the registry tarball ${source.requested} was not resolved by this session`);
|
|
808
829
|
}
|
|
830
|
+
let host = 'unknown host';
|
|
831
|
+
try {
|
|
832
|
+
host = new URL(url).host;
|
|
833
|
+
}
|
|
834
|
+
catch {
|
|
835
|
+
// A tarball URL is validated as http(s) at resolve time; keep a safe label.
|
|
836
|
+
}
|
|
837
|
+
const label = `${source.requested} from ${host}`;
|
|
809
838
|
let response;
|
|
810
839
|
try {
|
|
811
|
-
|
|
840
|
+
// NO wall-clock deadline here: the bytes are digest-verified, so a large
|
|
841
|
+
// dependency may transfer for minutes. Only the caller's signal and the
|
|
842
|
+
// IDLE timeout below can abort it.
|
|
843
|
+
response = await fetchImpl(url, signal === undefined ? {} : { signal });
|
|
812
844
|
}
|
|
813
845
|
catch (error) {
|
|
814
|
-
throw new RegistryError('registry-tarball-fetch-failed', `the tarball for ${
|
|
846
|
+
throw new RegistryError('registry-tarball-fetch-failed', `the tarball for ${label} could not be downloaded (timeout or transport, not the size cap; the cap is ${maxTarballBytes} bytes): ${messageOf(error)}`, { cause: error });
|
|
815
847
|
}
|
|
816
848
|
if (!response.ok) {
|
|
817
849
|
await response.body?.cancel();
|
|
818
|
-
throw new RegistryError('registry-tarball-fetch-failed', `the tarball for ${
|
|
850
|
+
throw new RegistryError('registry-tarball-fetch-failed', `the tarball for ${label} answered HTTP ${response.status} (not the size cap)`);
|
|
819
851
|
}
|
|
820
852
|
try {
|
|
821
|
-
return await readBoundedBody(response, maxTarballBytes
|
|
853
|
+
return await readBoundedBody(response, maxTarballBytes, {
|
|
854
|
+
idleTimeoutMs: tarballTimeoutMs,
|
|
855
|
+
tooLargeMessage: declared => `the tarball for ${label} is over the ${maxTarballBytes}-byte cap${declared === undefined ? '' : ` (${declared} bytes)`}`,
|
|
856
|
+
idleMessage: () => `the tarball for ${label} timed out: no bytes arrived for ${tarballTimeoutMs} ms (timeout, not the ${maxTarballBytes}-byte cap)`,
|
|
857
|
+
});
|
|
822
858
|
}
|
|
823
859
|
catch (error) {
|
|
824
860
|
if (error instanceof RegistryError)
|
|
825
861
|
throw error;
|
|
826
|
-
throw new RegistryError('registry-tarball-fetch-failed', `the tarball for ${
|
|
862
|
+
throw new RegistryError('registry-tarball-fetch-failed', `the tarball for ${label} could not be read (timeout or transport, not the size cap): ${messageOf(error)}`, { cause: error });
|
|
827
863
|
}
|
|
828
864
|
},
|
|
829
865
|
};
|
package/lib/extensions-api.d.ts
CHANGED
|
@@ -15,7 +15,9 @@
|
|
|
15
15
|
*/
|
|
16
16
|
/** One extension, as the UI needs it. */
|
|
17
17
|
/** What kind of prerequisite an extension (or a model it serves) has. */
|
|
18
|
-
export type ExtensionRequirementKind = 'store' | 'source' | 'dependencies'
|
|
18
|
+
export type ExtensionRequirementKind = 'store' | 'source' | 'dependencies'
|
|
19
|
+
/** Optional tool-runtime packages (optionalDependencies) the extension's tools load. */
|
|
20
|
+
| 'runtime' | 'assets' | 'executable' | 'harness-model' | 'platform' | 'integrity' | 'activation';
|
|
19
21
|
/** The action that clears an unmet requirement, when the deployment supports it. */
|
|
20
22
|
export type ExtensionRequirementAction = 'install' | 'prepare' | 'enable' | 'config' | 'none';
|
|
21
23
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extensions-api.d.ts","sourceRoot":"","sources":["../src/extensions-api.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,yCAAyC;AACzC,yEAAyE;AACzE,MAAM,MAAM,wBAAwB,GAChC,OAAO,GACP,QAAQ,GACR,cAAc,
|
|
1
|
+
{"version":3,"file":"extensions-api.d.ts","sourceRoot":"","sources":["../src/extensions-api.ts"],"names":[],"mappings":"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"}
|
|
@@ -112,6 +112,8 @@ export type ExtensionsServiceErrorCode =
|
|
|
112
112
|
| 'extension-preparation-failed'
|
|
113
113
|
/** A prerequisite the deployment cannot satisfy blocks activation before any lifecycle call. */
|
|
114
114
|
| 'extension-requirement-unmet'
|
|
115
|
+
/** The extension's optional tool runtime is not installed, so its tools cannot load. */
|
|
116
|
+
| 'extension-runtime-unavailable'
|
|
115
117
|
/** Registry mode was selected but no registry URL is configured. */
|
|
116
118
|
| 'extension-registry-unconfigured'
|
|
117
119
|
/** The registry has no such package, version, or dist-tag (HTTP 404 / no matching version). */
|
|
@@ -190,6 +192,14 @@ export interface ExtensionsServiceOptions {
|
|
|
190
192
|
readonly registryUrl?: string;
|
|
191
193
|
/** Hard cap on one registry package tarball; defaults to the SDK archive bound (256 MiB). */
|
|
192
194
|
readonly registryTarballMaxBytes?: number;
|
|
195
|
+
/**
|
|
196
|
+
* IDLE timeout for one registry tarball download, in ms; defaults to 10 minutes.
|
|
197
|
+
*
|
|
198
|
+
* Separate from the short metadata timeout: onnxruntime-node is hundreds of MB,
|
|
199
|
+
* and a moving transfer must not be aborted by the packument budget. Aborts only
|
|
200
|
+
* when NO bytes arrive for this long; the byte cap remains the real bound.
|
|
201
|
+
*/
|
|
202
|
+
readonly registryTarballTimeoutMs?: number;
|
|
193
203
|
/** INTERNAL TEST SEAM: the directory installer, defaulting to the SDK's staged path. */
|
|
194
204
|
readonly installDirectory?: DirectoryInstaller;
|
|
195
205
|
/** INTERNAL TEST SEAM: the content digest, defaulting to the SDK's installed-content digest. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extensions-service.d.ts","sourceRoot":"","sources":["../src/extensions-service.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;
|
|
1
|
+
{"version":3,"file":"extensions-service.d.ts","sourceRoot":"","sources":["../src/extensions-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -48,10 +48,11 @@
|
|
|
48
48
|
*
|
|
49
49
|
* @module @try-works/dsh-model-as-tool/extensions-service
|
|
50
50
|
*/
|
|
51
|
-
import { accessSync, constants, existsSync, readFileSync, readdirSync, statSync } from 'node:fs';
|
|
51
|
+
import { accessSync, constants, cpSync, existsSync, mkdtempSync, readFileSync, readdirSync, renameSync, rmSync, statSync, writeFileSync } from 'node:fs';
|
|
52
|
+
import { tmpdir } from 'node:os';
|
|
52
53
|
import { dirname, join, resolve } from 'node:path';
|
|
53
|
-
import { createTarGzipArchiveSource, digestInstalledContent, discoverExtension, ExtensionStore, ManagementError, stagedInstall, stagedInstallFromDirectory, } from '@try-works/tool-mode-extension-sdk';
|
|
54
|
-
import { createFirstPartyDependencyGraph, createRegistryDependencyGraph, createRegistrySession, DEFAULT_REGISTRY_URL, MAX_DEPENDENCY_ARCHIVE_BYTES, RegistryError, resolveFirstPartyDependency, } from "./extension-dependencies.js";
|
|
54
|
+
import { createTarGzipArchiveSource, digestInstalledContent, discoverExtension, ExtensionStore, installDependencyGraph, ManagementError, stagedInstall, stagedInstallFromDirectory, } from '@try-works/tool-mode-extension-sdk';
|
|
55
|
+
import { createFirstPartyDependencyGraph, createRegistryDependencyGraph, createRegistrySession, DEFAULT_REGISTRY_URL, MAX_DEPENDENCY_ARCHIVE_BYTES, RegistryError, resolveFirstPartyDependency, satisfiesRegistryRange, } from "./extension-dependencies.js";
|
|
55
56
|
import { createHttpSource } from "./http-acquisition.js";
|
|
56
57
|
/**
|
|
57
58
|
* The readiness values that permit activation (the SDK's callable set).
|
|
@@ -77,6 +78,7 @@ const REQUIREMENT_PRIORITY = [
|
|
|
77
78
|
'integrity',
|
|
78
79
|
'platform',
|
|
79
80
|
'dependencies',
|
|
81
|
+
'runtime',
|
|
80
82
|
'harness-model',
|
|
81
83
|
'executable',
|
|
82
84
|
'assets',
|
|
@@ -105,7 +107,8 @@ function blocksRow(installed, requirement) {
|
|
|
105
107
|
|| requirement.kind === 'source'
|
|
106
108
|
|| requirement.kind === 'dependencies'
|
|
107
109
|
|| requirement.kind === 'platform'
|
|
108
|
-
|| requirement.kind === 'harness-model'
|
|
110
|
+
|| requirement.kind === 'harness-model'
|
|
111
|
+
|| requirement.kind === 'runtime';
|
|
109
112
|
}
|
|
110
113
|
/** Build one requirement value. */
|
|
111
114
|
function requirement(kind, satisfied, reason, action = 'none') {
|
|
@@ -178,10 +181,11 @@ const EMPTY_FACTS = {
|
|
|
178
181
|
executionKind: undefined,
|
|
179
182
|
platforms: [],
|
|
180
183
|
dependencies: [],
|
|
184
|
+
optionalDependencies: [],
|
|
181
185
|
problem: null,
|
|
182
186
|
};
|
|
183
|
-
/** Read
|
|
184
|
-
function readDeclaredDependencies(packageDir) {
|
|
187
|
+
/** Read one package.json dependency field as name→range pairs; empty when unreadable. */
|
|
188
|
+
function readDeclaredDependencies(packageDir, field = 'dependencies') {
|
|
185
189
|
if (packageDir === null)
|
|
186
190
|
return [];
|
|
187
191
|
try {
|
|
@@ -191,7 +195,7 @@ function readDeclaredDependencies(packageDir) {
|
|
|
191
195
|
// SAFETY: the value came from JSON.parse and the object guard above; only
|
|
192
196
|
// string-valued dependency specs are kept, so an unexpected shape yields an
|
|
193
197
|
// empty declaration rather than a trusted one.
|
|
194
|
-
const dependencies = parsed
|
|
198
|
+
const dependencies = parsed[field];
|
|
195
199
|
if (typeof dependencies !== 'object' || dependencies === null || Array.isArray(dependencies))
|
|
196
200
|
return [];
|
|
197
201
|
const declared = [];
|
|
@@ -214,6 +218,7 @@ function readDeclaredDependencies(packageDir) {
|
|
|
214
218
|
*/
|
|
215
219
|
function readExtensionFacts(packageDir) {
|
|
216
220
|
const dependencies = readDeclaredDependencies(packageDir);
|
|
221
|
+
const optionalDependencies = readDeclaredDependencies(packageDir, 'optionalDependencies');
|
|
217
222
|
try {
|
|
218
223
|
const discovery = discoverExtension(packageDir);
|
|
219
224
|
const manifest = discovery.manifest;
|
|
@@ -226,6 +231,7 @@ function readExtensionFacts(packageDir) {
|
|
|
226
231
|
executionKind: manifest.execution.kind,
|
|
227
232
|
platforms: manifest.models.flatMap(model => model.platforms),
|
|
228
233
|
dependencies,
|
|
234
|
+
optionalDependencies,
|
|
229
235
|
problem: null,
|
|
230
236
|
};
|
|
231
237
|
}
|
|
@@ -236,6 +242,7 @@ function readExtensionFacts(packageDir) {
|
|
|
236
242
|
packageVersion: null,
|
|
237
243
|
packageDir,
|
|
238
244
|
dependencies,
|
|
245
|
+
optionalDependencies,
|
|
239
246
|
problem: `the package at ${packageDir} is not a usable extension: ${messageOf(error)}`,
|
|
240
247
|
};
|
|
241
248
|
}
|
|
@@ -252,6 +259,96 @@ function platformLabel(platform) {
|
|
|
252
259
|
function hostPlatformMatches(platforms) {
|
|
253
260
|
return platforms.some(platform => platform.os === process.platform && platform.arch === process.arch);
|
|
254
261
|
}
|
|
262
|
+
/** The sidecar filename inside the extension store (host-owned, never inside a package). */
|
|
263
|
+
const RUNTIME_DEPENDENCY_FILE = 'runtime-dependencies.json';
|
|
264
|
+
/** Read the store's runtime-dependency sidecar; a missing/corrupt document is empty. */
|
|
265
|
+
function readRuntimeDependencyDocument(storeDir) {
|
|
266
|
+
try {
|
|
267
|
+
const parsed = JSON.parse(readFileSync(join(storeDir, RUNTIME_DEPENDENCY_FILE), 'utf8'));
|
|
268
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
269
|
+
return { updatedAt: '', extensions: {} };
|
|
270
|
+
const extensions = parsed.extensions;
|
|
271
|
+
if (typeof extensions !== 'object' || extensions === null || Array.isArray(extensions)) {
|
|
272
|
+
return { updatedAt: '', extensions: {} };
|
|
273
|
+
}
|
|
274
|
+
// SAFETY: the container was checked to be a non-array object; each entry is
|
|
275
|
+
// read defensively by the requirement model, and a malformed entry is ignored.
|
|
276
|
+
return { updatedAt: '', extensions: extensions };
|
|
277
|
+
}
|
|
278
|
+
catch {
|
|
279
|
+
return { updatedAt: '', extensions: {} };
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
/** Merge one extension's runtime attempts into the store sidecar (atomic replace). */
|
|
283
|
+
function writeRuntimeDependencyDocument(storeDir, extensionId, version, optional) {
|
|
284
|
+
try {
|
|
285
|
+
const current = readRuntimeDependencyDocument(storeDir);
|
|
286
|
+
const document = {
|
|
287
|
+
updatedAt: new Date().toISOString(),
|
|
288
|
+
extensions: {
|
|
289
|
+
...current.extensions,
|
|
290
|
+
[extensionId]: { version, optional },
|
|
291
|
+
},
|
|
292
|
+
};
|
|
293
|
+
const target = join(storeDir, RUNTIME_DEPENDENCY_FILE);
|
|
294
|
+
const temporary = `${target}.${process.pid}.${Date.now().toString(36)}.tmp`;
|
|
295
|
+
writeFileSync(temporary, `${JSON.stringify(document, null, 2)}\n`, 'utf8');
|
|
296
|
+
rmSync(target, { force: true });
|
|
297
|
+
cpSync(temporary, target);
|
|
298
|
+
rmSync(temporary, { force: true });
|
|
299
|
+
}
|
|
300
|
+
catch {
|
|
301
|
+
// Diagnostics only: failing to record an optional-runtime attempt must never
|
|
302
|
+
// turn a successful install into a failure. The requirement probes the tree.
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
/** Read one installed dependency's package.json version, or undefined. */
|
|
306
|
+
function readInstalledDependencyVersion(installPath, name) {
|
|
307
|
+
try {
|
|
308
|
+
const parsed = JSON.parse(readFileSync(join(installPath, 'node_modules', ...name.split('/'), 'package.json'), 'utf8'));
|
|
309
|
+
if (typeof parsed !== 'object' || parsed === null)
|
|
310
|
+
return undefined;
|
|
311
|
+
const version = parsed.version;
|
|
312
|
+
return typeof version === 'string' ? version : undefined;
|
|
313
|
+
}
|
|
314
|
+
catch {
|
|
315
|
+
return undefined;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/**
|
|
319
|
+
* Atomically REPLACE one installed record in the store lock.
|
|
320
|
+
*
|
|
321
|
+
* The SDK's `recordInstall` deliberately refuses an already-recorded identity
|
|
322
|
+
* (upgrade protection), and it exposes no update call. The host legitimately
|
|
323
|
+
* changes an installed copy AFTER activation-free materialization (optional tool
|
|
324
|
+
* runtimes): the recorded content digest must match the bytes the operator now
|
|
325
|
+
* has, and the lock is the host-owned document that carries it. The replacement is
|
|
326
|
+
* a same-file atomic rename, so a crash leaves either the old or the new record.
|
|
327
|
+
* @param storeDir - the configured store.
|
|
328
|
+
* @param updated - the record to store, keyed by identity and version.
|
|
329
|
+
* @returns whether the record was found and replaced.
|
|
330
|
+
*/
|
|
331
|
+
function replaceInstalledRecord(storeDir, updated) {
|
|
332
|
+
try {
|
|
333
|
+
const store = new ExtensionStore(storeDir);
|
|
334
|
+
const lock = store.readLock();
|
|
335
|
+
if (lock.corrupt)
|
|
336
|
+
return false;
|
|
337
|
+
const index = lock.value.extensions.findIndex(candidate => candidate.extensionId === updated.extensionId && candidate.version === updated.version);
|
|
338
|
+
if (index === -1)
|
|
339
|
+
return false;
|
|
340
|
+
const extensions = [...lock.value.extensions];
|
|
341
|
+
extensions[index] = updated;
|
|
342
|
+
const target = store.lockPath;
|
|
343
|
+
const temporary = `${target}.${process.pid}.${Date.now().toString(36)}.tmp`;
|
|
344
|
+
writeFileSync(temporary, `${JSON.stringify({ lockVersion: 1, extensions }, null, 2)}\n`, 'utf8');
|
|
345
|
+
renameSync(temporary, target);
|
|
346
|
+
return true;
|
|
347
|
+
}
|
|
348
|
+
catch {
|
|
349
|
+
return false;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
255
352
|
/**
|
|
256
353
|
* Every declared deployment whose recorded readiness does not permit activation.
|
|
257
354
|
*
|
|
@@ -707,6 +804,9 @@ export class ExtensionsService {
|
|
|
707
804
|
else {
|
|
708
805
|
requirements.push(requirement('integrity', false, input.integrityReason ?? `the installed content's integrity is ${input.integrity}`, 'install'));
|
|
709
806
|
}
|
|
807
|
+
// RUNTIME: optional tool-runtime packages must be materialized, or the
|
|
808
|
+
// extension's tools load and fail at call time — which is not activation.
|
|
809
|
+
requirements.push(this.#runtimeRequirement(input));
|
|
710
810
|
// HARNESS MODEL: only declarative packages are served by the host broker.
|
|
711
811
|
if (input.facts.executionKind === 'declarative') {
|
|
712
812
|
requirements.push(this.#harnessModelRequirement());
|
|
@@ -795,6 +895,45 @@ export class ExtensionsService {
|
|
|
795
895
|
? requirement('dependencies', true, `all ${count} declared runtime dependenc${count === 1 ? 'y resolves' : 'ies resolve'} in the host's installed tree`)
|
|
796
896
|
: requirement('dependencies', false, `the host's tree is missing ${missing.length} declared runtime dependenc${missing.length === 1 ? 'y' : 'ies'}: ${missing.join(', ')}; install the dependency for the host first`, 'none');
|
|
797
897
|
}
|
|
898
|
+
/**
|
|
899
|
+
* The OPTIONAL tool-runtime requirement.
|
|
900
|
+
*
|
|
901
|
+
* Module extensions declare the packages their tools `require()` at call time as
|
|
902
|
+
* optionalDependencies (e.g. tongue's `@desert-ant-labs/tongue`). If one is absent
|
|
903
|
+
* the extension still activates and its tools fail at call time, so this
|
|
904
|
+
* requirement BLOCKS activation instead: a tool that cannot load is not served.
|
|
905
|
+
* The sidecar records why a materialization attempt failed (the lock cannot).
|
|
906
|
+
*/
|
|
907
|
+
#runtimeRequirement(input) {
|
|
908
|
+
const declared = input.facts.optionalDependencies;
|
|
909
|
+
if (declared.length === 0) {
|
|
910
|
+
return requirement('runtime', true, 'the package declares no optional tool runtime');
|
|
911
|
+
}
|
|
912
|
+
if (!input.installed || input.record === undefined) {
|
|
913
|
+
return requirement('runtime', true, 'not installed yet; optional tool runtimes are materialized and verified at install time');
|
|
914
|
+
}
|
|
915
|
+
const recorded = readRuntimeDependencyDocument(input.storeDir).extensions[input.id];
|
|
916
|
+
const unresolved = [];
|
|
917
|
+
const resolved = [];
|
|
918
|
+
for (const dependency of declared) {
|
|
919
|
+
const installedVersion = readInstalledDependencyVersion(input.record.installPath, dependency.name);
|
|
920
|
+
if (installedVersion === undefined) {
|
|
921
|
+
const attempt = recorded?.optional.find(entry => entry.name === dependency.name && !entry.satisfied);
|
|
922
|
+
unresolved.push(`${dependency.name} ${dependency.range} is not installed inside the extension`
|
|
923
|
+
+ (attempt?.error === undefined ? '' : `: ${attempt.error}`));
|
|
924
|
+
}
|
|
925
|
+
else if (!satisfiesRegistryRange(installedVersion, dependency.range)) {
|
|
926
|
+
unresolved.push(`${dependency.name} is installed at ${installedVersion}, which does not satisfy ${dependency.range}`);
|
|
927
|
+
}
|
|
928
|
+
else {
|
|
929
|
+
resolved.push(`${dependency.name}@${installedVersion}`);
|
|
930
|
+
}
|
|
931
|
+
}
|
|
932
|
+
if (unresolved.length === 0) {
|
|
933
|
+
return requirement('runtime', true, `the optional tool runtime${resolved.length === 1 ? ' is' : 's are'} materialized (${resolved.join(', ')})`);
|
|
934
|
+
}
|
|
935
|
+
return requirement('runtime', false, `the extension's tools cannot load: ${unresolved.join('; ')}`, 'install');
|
|
936
|
+
}
|
|
798
937
|
/** The harness-model requirement for a declarative package. */
|
|
799
938
|
#harnessModelRequirement() {
|
|
800
939
|
const status = this.#options.harnessProviderStatus?.();
|
|
@@ -1119,6 +1258,9 @@ export class ExtensionsService {
|
|
|
1119
1258
|
registryUrl,
|
|
1120
1259
|
archiveFactory: createTarGzipArchiveSource,
|
|
1121
1260
|
maxTarballBytes: this.#options.registryTarballMaxBytes ?? MAX_DEPENDENCY_ARCHIVE_BYTES,
|
|
1261
|
+
...this.#options.registryTarballTimeoutMs === undefined
|
|
1262
|
+
? {}
|
|
1263
|
+
: { tarballTimeoutMs: this.#options.registryTarballTimeoutMs },
|
|
1122
1264
|
});
|
|
1123
1265
|
let resolved;
|
|
1124
1266
|
try {
|
|
@@ -1164,6 +1306,10 @@ export class ExtensionsService {
|
|
|
1164
1306
|
if (installed.archiveDigest.trim().length === 0) {
|
|
1165
1307
|
throw new ExtensionsServiceError('extension-digest-unavailable', `${installed.extensionId}@${installed.version} was installed without a content digest, so it cannot be verified before activation`);
|
|
1166
1308
|
}
|
|
1309
|
+
// Optional tool runtimes are materialized AFTER the package install and are
|
|
1310
|
+
// NOT allowed to fail it: tongue/voz tools `require()` an optional package at
|
|
1311
|
+
// call time, and the requirement model blocks activation if it is absent.
|
|
1312
|
+
await this.#materializeOptionalRuntimes(storeDir, installed, session, signal);
|
|
1167
1313
|
return {
|
|
1168
1314
|
id: installed.extensionId,
|
|
1169
1315
|
version: installed.version,
|
|
@@ -1172,6 +1318,122 @@ export class ExtensionsService {
|
|
|
1172
1318
|
resolvedVersion: resolved.version,
|
|
1173
1319
|
};
|
|
1174
1320
|
}
|
|
1321
|
+
/**
|
|
1322
|
+
* The dependency graph for optional tool runtimes.
|
|
1323
|
+
*
|
|
1324
|
+
* The registry arm is the default. When the operator's preinstalled gate is ON,
|
|
1325
|
+
* a host-tree package that satisfies the range is preferred: tongue's runtime
|
|
1326
|
+
* (@desert-ant-labs/tongue) declares a `prepare` script, which the registry arm
|
|
1327
|
+
* must refuse under EXT-10, while content that ARRIVED from an operator-completed
|
|
1328
|
+
* install is exactly what the gate exists for. The SDK records provenance
|
|
1329
|
+
* `preinstalled`, so the lock states the installer ran no lifecycle script.
|
|
1330
|
+
* @param session - the registry session.
|
|
1331
|
+
* @returns the graph.
|
|
1332
|
+
*/
|
|
1333
|
+
#optionalRuntimeGraph(session) {
|
|
1334
|
+
const registryGraph = createRegistryDependencyGraph(session);
|
|
1335
|
+
const preinstalledRoot = this.#options.preinstalledDependenciesRoot ?? '';
|
|
1336
|
+
const allowPreinstalled = this.#options.allowPreinstalledDependencies === true && preinstalledRoot !== '';
|
|
1337
|
+
if (!allowPreinstalled)
|
|
1338
|
+
return registryGraph;
|
|
1339
|
+
return {
|
|
1340
|
+
resolver: {
|
|
1341
|
+
async resolve(name, range) {
|
|
1342
|
+
try {
|
|
1343
|
+
const found = resolveFirstPartyDependency({ sourcePackageDir: preinstalledRoot }, name, range);
|
|
1344
|
+
return { name: found.name, version: found.version, dir: found.directory, provenance: 'preinstalled' };
|
|
1345
|
+
}
|
|
1346
|
+
catch {
|
|
1347
|
+
return registryGraph.resolver.resolve(name, range);
|
|
1348
|
+
}
|
|
1349
|
+
},
|
|
1350
|
+
},
|
|
1351
|
+
archive: registryGraph.archive,
|
|
1352
|
+
allowPreinstalled: true,
|
|
1353
|
+
preinstalledRoot,
|
|
1354
|
+
};
|
|
1355
|
+
}
|
|
1356
|
+
/**
|
|
1357
|
+
* Materialize the extension's optionalDependencies without failing the install.
|
|
1358
|
+
*
|
|
1359
|
+
* Each declaration is resolved and materialized through the SAME SDK dependency
|
|
1360
|
+
* graph discipline as regular dependencies (bounded fetch, sha512 verification,
|
|
1361
|
+
* EXT-10 script refusal) into a scratch package, then merged into the
|
|
1362
|
+
* extension's own node_modules. A failure is RECORDED (store sidecar) and the
|
|
1363
|
+
* requirement model blocks activation instead; the package install stands.
|
|
1364
|
+
*
|
|
1365
|
+
* The store record's content digest is recomputed after a successful merge,
|
|
1366
|
+
* because the installed bytes legitimately changed; the archive digest (the
|
|
1367
|
+
* tarball identity) is untouched.
|
|
1368
|
+
* @param storeDir - the configured store.
|
|
1369
|
+
* @param installed - the just-installed package.
|
|
1370
|
+
* @param session - the registry session used for the install.
|
|
1371
|
+
* @param signal - cancellation.
|
|
1372
|
+
*/
|
|
1373
|
+
async #materializeOptionalRuntimes(storeDir, installed, session, signal) {
|
|
1374
|
+
const optional = readDeclaredDependencies(installed.installPath, 'optionalDependencies');
|
|
1375
|
+
if (optional.length === 0)
|
|
1376
|
+
return;
|
|
1377
|
+
const attempts = [];
|
|
1378
|
+
const locked = [];
|
|
1379
|
+
for (const dependency of optional) {
|
|
1380
|
+
signal?.throwIfAborted();
|
|
1381
|
+
const scratch = mkdtempSync(join(tmpdir(), 'dsh-optional-runtime-'));
|
|
1382
|
+
try {
|
|
1383
|
+
writeFileSync(join(scratch, 'package.json'), `${JSON.stringify({ name: 'dsh-optional-runtime-host', version: '0.0.0', dependencies: { [dependency.name]: dependency.range } }, null, 2)}\n`, 'utf8');
|
|
1384
|
+
const materialized = await installDependencyGraph(scratch, this.#optionalRuntimeGraph(session));
|
|
1385
|
+
const sourceNodeModules = join(scratch, 'node_modules');
|
|
1386
|
+
const targetNodeModules = join(installed.installPath, 'node_modules');
|
|
1387
|
+
if (existsSync(sourceNodeModules)) {
|
|
1388
|
+
for (const name of readdirSync(sourceNodeModules)) {
|
|
1389
|
+
const from = join(sourceNodeModules, name);
|
|
1390
|
+
const to = join(targetNodeModules, name);
|
|
1391
|
+
if (existsSync(to)) {
|
|
1392
|
+
const kept = readInstalledDependencyVersion(installed.installPath, name);
|
|
1393
|
+
const wanted = materialized.find(entry => entry.name === name);
|
|
1394
|
+
if (kept !== undefined && wanted !== undefined && kept !== wanted.version) {
|
|
1395
|
+
throw new Error(`${name} is already installed at ${kept}, but the optional runtime needs ${wanted.version}`);
|
|
1396
|
+
}
|
|
1397
|
+
continue;
|
|
1398
|
+
}
|
|
1399
|
+
cpSync(from, to, { recursive: true });
|
|
1400
|
+
}
|
|
1401
|
+
locked.push(...materialized);
|
|
1402
|
+
}
|
|
1403
|
+
const own = materialized.find(entry => entry.name === dependency.name);
|
|
1404
|
+
attempts.push({
|
|
1405
|
+
name: dependency.name,
|
|
1406
|
+
range: dependency.range,
|
|
1407
|
+
satisfied: true,
|
|
1408
|
+
...own === undefined ? {} : { version: own.version },
|
|
1409
|
+
});
|
|
1410
|
+
}
|
|
1411
|
+
catch (error) {
|
|
1412
|
+
if (signal?.aborted === true)
|
|
1413
|
+
throw error;
|
|
1414
|
+
attempts.push({ name: dependency.name, range: dependency.range, satisfied: false, error: messageOf(error) });
|
|
1415
|
+
}
|
|
1416
|
+
finally {
|
|
1417
|
+
rmSync(scratch, { recursive: true, force: true });
|
|
1418
|
+
}
|
|
1419
|
+
}
|
|
1420
|
+
writeRuntimeDependencyDocument(storeDir, installed.extensionId, installed.version, attempts);
|
|
1421
|
+
if (locked.length === 0)
|
|
1422
|
+
return;
|
|
1423
|
+
const store = new ExtensionStore(storeDir);
|
|
1424
|
+
const record = store.listInstalled().value.find(candidate => candidate.extensionId === installed.extensionId && candidate.version === installed.version);
|
|
1425
|
+
if (record === undefined)
|
|
1426
|
+
return;
|
|
1427
|
+
const existing = new Set((record.dependencies ?? []).map(entry => entry.name));
|
|
1428
|
+
const additions = locked.filter(entry => !existing.has(entry.name));
|
|
1429
|
+
if (additions.length === 0)
|
|
1430
|
+
return;
|
|
1431
|
+
replaceInstalledRecord(storeDir, {
|
|
1432
|
+
...record,
|
|
1433
|
+
contentDigest: digestInstalledContent(installed.installPath),
|
|
1434
|
+
dependencies: [...(record.dependencies ?? []), ...additions],
|
|
1435
|
+
});
|
|
1436
|
+
}
|
|
1175
1437
|
/**
|
|
1176
1438
|
* Install one extension from a local source directory (EXT-06 developer mode).
|
|
1177
1439
|
*
|
|
@@ -1319,6 +1581,10 @@ export class ExtensionsService {
|
|
|
1319
1581
|
// that classification while refusing before the lifecycle call.
|
|
1320
1582
|
throw new ExtensionsServiceError('extension-activation-failed', `[INTEGRITY_MISMATCH] ${unmet.reason}`);
|
|
1321
1583
|
}
|
|
1584
|
+
if (unmet.kind === 'runtime') {
|
|
1585
|
+
// Activation that cannot serve the extension's tools is not activation.
|
|
1586
|
+
throw new ExtensionsServiceError('extension-runtime-unavailable', unmet.reason);
|
|
1587
|
+
}
|
|
1322
1588
|
throw new ExtensionsServiceError('extension-requirement-unmet', unmet.reason);
|
|
1323
1589
|
}
|
|
1324
1590
|
const ownedHere = current?.observedActivation === 'active'
|
package/lib/index.d.ts
CHANGED
|
@@ -153,6 +153,11 @@ export interface Config {
|
|
|
153
153
|
extensionRegistry?: string;
|
|
154
154
|
/** Hard cap on one registry package tarball download. Default 256 MiB. */
|
|
155
155
|
extensionTarballMaxBytes?: number;
|
|
156
|
+
/**
|
|
157
|
+
* IDLE timeout for one registry tarball download, in ms. Default 10 minutes.
|
|
158
|
+
* Applies only when NO bytes arrive; a slow large download is not aborted.
|
|
159
|
+
*/
|
|
160
|
+
extensionTarballTimeoutMs?: number;
|
|
156
161
|
/**
|
|
157
162
|
* Operator gate: allow dependency content that arrived already materialized.
|
|
158
163
|
*
|
package/lib/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/lib/index.js
CHANGED
|
@@ -103,6 +103,12 @@ export const Config = z.object({
|
|
|
103
103
|
extensionRegistry: z.string().default('https://registry.npmjs.org/'),
|
|
104
104
|
/** Hard cap on one registry tarball download, in bytes. Default 256 MiB. */
|
|
105
105
|
extensionTarballMaxBytes: z.number().min(1).default(256 * 1024 * 1024),
|
|
106
|
+
/**
|
|
107
|
+
* IDLE timeout for one registry tarball download, in ms. Default 10 minutes.
|
|
108
|
+
* Aborts only when NO bytes arrive for this long; a large dependency streaming
|
|
109
|
+
* slowly is not aborted by the short package-metadata timeout.
|
|
110
|
+
*/
|
|
111
|
+
extensionTarballTimeoutMs: z.number().min(1000).default(10 * 60_000),
|
|
106
112
|
allowPreinstalledDependencies: z.boolean().default(false),
|
|
107
113
|
preinstalledDependenciesRoot: z.string().default(''),
|
|
108
114
|
/**
|
|
@@ -373,6 +379,7 @@ export async function apply(ctx, config = {}) {
|
|
|
373
379
|
installSource: config.extensionInstallSource ?? 'auto',
|
|
374
380
|
registryUrl: config.extensionRegistry ?? 'https://registry.npmjs.org/',
|
|
375
381
|
registryTarballMaxBytes: config.extensionTarballMaxBytes ?? 256 * 1024 * 1024,
|
|
382
|
+
registryTarballTimeoutMs: config.extensionTarballTimeoutMs ?? 10 * 60_000,
|
|
376
383
|
/**
|
|
377
384
|
* The operator gate for already-materialized dependencies. OFF by default:
|
|
378
385
|
* a dependency whose package.json declares install-time scripts still
|
package/package.json
CHANGED