@try-works/dsh-model-as-tool 0.4.1 → 0.4.3

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.
@@ -230,6 +230,10 @@ window.__ModuleLoader__.load({
230
230
  "kind": "literal",
231
231
  "value": "dependencies"
232
232
  },
233
+ {
234
+ "kind": "literal",
235
+ "value": "runtime"
236
+ },
233
237
  {
234
238
  "kind": "literal",
235
239
  "value": "assets"
@@ -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
- /** Request timeout; default 30 s. */
256
- readonly timeoutMs?: number;
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
- /** Read a response body with a hard byte cap enforced BEFORE allocation grows unbounded. */
405
- async function readBoundedBody(response, maxBytes) {
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 new RegistryError('registry-tarball-too-large', `the response declares ${declared} bytes, over the ${maxBytes}-byte cap`);
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 new RegistryError('registry-tarball-too-large', `the response is ${buffer.byteLength} bytes, over the ${maxBytes}-byte cap`);
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 { done, value } = await reader.read();
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 new RegistryError('registry-tarball-too-large', `the response is over the ${maxBytes}-byte cap`);
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 timeoutMs = options.timeoutMs ?? 30_000;
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 timed = (signal) => signal === undefined
745
- ? AbortSignal.timeout(timeoutMs)
746
- : AbortSignal.any([signal, AbortSignal.timeout(timeoutMs)]);
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: timed(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
- response = await fetchImpl(url, { signal: timed(signal) });
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 ${source.requested} could not be downloaded: ${messageOf(error)}`, { cause: error });
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 ${source.requested} answered HTTP ${response.status}`);
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 ${source.requested} could not be read: ${messageOf(error)}`, { cause: error });
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
  };
@@ -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' | 'assets' | 'executable' | 'harness-model' | 'platform' | 'integrity' | 'activation';
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":"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"}
1
+ {"version":3,"file":"extensions-api.d.ts","sourceRoot":"","sources":["../src/extensions-api.ts"],"names":[],"mappings":"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"}
@@ -52,6 +52,14 @@ import { stagedInstallFromDirectory, type ExtensionLifecycle, type InstallDepend
52
52
  import type { ExtensionInstallResult, ExtensionPrepareResult, ExtensionToggleResult, ExtensionsDescribeResult, ModelToolsRemote } from './extensions-api.ts';
53
53
  import type { AcquisitionSource } from './asset-acquisition.ts';
54
54
  import type { PrepareAssetsSurface } from './prepared-assets.ts';
55
+ /**
56
+ * The default dependency-graph depth bound for registry installs (task-116).
57
+ *
58
+ * The SDK default (3) is too shallow for real trees; onnxruntime-node reaches
59
+ * `define-data-property` at depth 4. Preinstalled packages are leaves, so this
60
+ * only bounds registry-resolved graphs.
61
+ */
62
+ export declare const DEFAULT_REGISTRY_DEPENDENCY_DEPTH = 12;
55
63
  /** What the host can report about the shared harness model provider (declarative extensions). */
56
64
  export interface HarnessProviderStatus {
57
65
  /** Whether a provider is composed and able to serve declarative extensions. */
@@ -112,6 +120,8 @@ export type ExtensionsServiceErrorCode =
112
120
  | 'extension-preparation-failed'
113
121
  /** A prerequisite the deployment cannot satisfy blocks activation before any lifecycle call. */
114
122
  | 'extension-requirement-unmet'
123
+ /** The extension's optional tool runtime is not installed, so its tools cannot load. */
124
+ | 'extension-runtime-unavailable'
115
125
  /** Registry mode was selected but no registry URL is configured. */
116
126
  | 'extension-registry-unconfigured'
117
127
  /** The registry has no such package, version, or dist-tag (HTTP 404 / no matching version). */
@@ -190,6 +200,20 @@ export interface ExtensionsServiceOptions {
190
200
  readonly registryUrl?: string;
191
201
  /** Hard cap on one registry package tarball; defaults to the SDK archive bound (256 MiB). */
192
202
  readonly registryTarballMaxBytes?: number;
203
+ /**
204
+ * IDLE timeout for one registry tarball download, in ms; defaults to 10 minutes.
205
+ *
206
+ * Separate from the short metadata timeout: onnxruntime-node is hundreds of MB,
207
+ * and a moving transfer must not be aborted by the packument budget. Aborts only
208
+ * when NO bytes arrive for this long; the byte cap remains the real bound.
209
+ */
210
+ readonly registryTarballTimeoutMs?: number;
211
+ /**
212
+ * Dependency-graph depth bound for registry installs; defaults to
213
+ * {@link DEFAULT_REGISTRY_DEPENDENCY_DEPTH} (12). Configurable because real
214
+ * dependency trees vary; a refusal names the level and the package.
215
+ */
216
+ readonly registryDependencyDepth?: number;
193
217
  /** INTERNAL TEST SEAM: the directory installer, defaulting to the SDK's staged path. */
194
218
  readonly installDirectory?: DirectoryInstaller;
195
219
  /** 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":"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"}
1
+ {"version":3,"file":"extensions-service.d.ts","sourceRoot":"","sources":["../src/extensions-service.ts"],"names":[],"mappings":"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"}
@@ -48,11 +48,20 @@
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";
57
+ /**
58
+ * The default dependency-graph depth bound for registry installs (task-116).
59
+ *
60
+ * The SDK default (3) is too shallow for real trees; onnxruntime-node reaches
61
+ * `define-data-property` at depth 4. Preinstalled packages are leaves, so this
62
+ * only bounds registry-resolved graphs.
63
+ */
64
+ export const DEFAULT_REGISTRY_DEPENDENCY_DEPTH = 12;
56
65
  /**
57
66
  * The readiness values that permit activation (the SDK's callable set).
58
67
  *
@@ -77,6 +86,7 @@ const REQUIREMENT_PRIORITY = [
77
86
  'integrity',
78
87
  'platform',
79
88
  'dependencies',
89
+ 'runtime',
80
90
  'harness-model',
81
91
  'executable',
82
92
  'assets',
@@ -105,7 +115,8 @@ function blocksRow(installed, requirement) {
105
115
  || requirement.kind === 'source'
106
116
  || requirement.kind === 'dependencies'
107
117
  || requirement.kind === 'platform'
108
- || requirement.kind === 'harness-model';
118
+ || requirement.kind === 'harness-model'
119
+ || requirement.kind === 'runtime';
109
120
  }
110
121
  /** Build one requirement value. */
111
122
  function requirement(kind, satisfied, reason, action = 'none') {
@@ -178,10 +189,11 @@ const EMPTY_FACTS = {
178
189
  executionKind: undefined,
179
190
  platforms: [],
180
191
  dependencies: [],
192
+ optionalDependencies: [],
181
193
  problem: null,
182
194
  };
183
- /** Read a package.json's `dependencies` as name→range pairs; empty when unreadable. */
184
- function readDeclaredDependencies(packageDir) {
195
+ /** Read one package.json dependency field as name→range pairs; empty when unreadable. */
196
+ function readDeclaredDependencies(packageDir, field = 'dependencies') {
185
197
  if (packageDir === null)
186
198
  return [];
187
199
  try {
@@ -191,7 +203,7 @@ function readDeclaredDependencies(packageDir) {
191
203
  // SAFETY: the value came from JSON.parse and the object guard above; only
192
204
  // string-valued dependency specs are kept, so an unexpected shape yields an
193
205
  // empty declaration rather than a trusted one.
194
- const dependencies = parsed.dependencies;
206
+ const dependencies = parsed[field];
195
207
  if (typeof dependencies !== 'object' || dependencies === null || Array.isArray(dependencies))
196
208
  return [];
197
209
  const declared = [];
@@ -214,6 +226,7 @@ function readDeclaredDependencies(packageDir) {
214
226
  */
215
227
  function readExtensionFacts(packageDir) {
216
228
  const dependencies = readDeclaredDependencies(packageDir);
229
+ const optionalDependencies = readDeclaredDependencies(packageDir, 'optionalDependencies');
217
230
  try {
218
231
  const discovery = discoverExtension(packageDir);
219
232
  const manifest = discovery.manifest;
@@ -226,6 +239,7 @@ function readExtensionFacts(packageDir) {
226
239
  executionKind: manifest.execution.kind,
227
240
  platforms: manifest.models.flatMap(model => model.platforms),
228
241
  dependencies,
242
+ optionalDependencies,
229
243
  problem: null,
230
244
  };
231
245
  }
@@ -236,6 +250,7 @@ function readExtensionFacts(packageDir) {
236
250
  packageVersion: null,
237
251
  packageDir,
238
252
  dependencies,
253
+ optionalDependencies,
239
254
  problem: `the package at ${packageDir} is not a usable extension: ${messageOf(error)}`,
240
255
  };
241
256
  }
@@ -252,6 +267,146 @@ function platformLabel(platform) {
252
267
  function hostPlatformMatches(platforms) {
253
268
  return platforms.some(platform => platform.os === process.platform && platform.arch === process.arch);
254
269
  }
270
+ /** The sidecar filename inside the extension store (host-owned, never inside a package). */
271
+ const RUNTIME_DEPENDENCY_FILE = 'runtime-dependencies.json';
272
+ /** Read the store's runtime-dependency sidecar; a missing/corrupt document is empty. */
273
+ function readRuntimeDependencyDocument(storeDir) {
274
+ try {
275
+ const parsed = JSON.parse(readFileSync(join(storeDir, RUNTIME_DEPENDENCY_FILE), 'utf8'));
276
+ if (typeof parsed !== 'object' || parsed === null)
277
+ return { updatedAt: '', extensions: {} };
278
+ const extensions = parsed.extensions;
279
+ if (typeof extensions !== 'object' || extensions === null || Array.isArray(extensions)) {
280
+ return { updatedAt: '', extensions: {} };
281
+ }
282
+ // SAFETY: the container was checked to be a non-array object; each entry is
283
+ // read defensively by the requirement model, and a malformed entry is ignored.
284
+ return { updatedAt: '', extensions: extensions };
285
+ }
286
+ catch {
287
+ return { updatedAt: '', extensions: {} };
288
+ }
289
+ }
290
+ /** Merge one extension's runtime attempts into the store sidecar (atomic replace). */
291
+ function writeRuntimeDependencyDocument(storeDir, extensionId, version, optional) {
292
+ try {
293
+ const current = readRuntimeDependencyDocument(storeDir);
294
+ const document = {
295
+ updatedAt: new Date().toISOString(),
296
+ extensions: {
297
+ ...current.extensions,
298
+ [extensionId]: { version, optional },
299
+ },
300
+ };
301
+ const target = join(storeDir, RUNTIME_DEPENDENCY_FILE);
302
+ const temporary = `${target}.${process.pid}.${Date.now().toString(36)}.tmp`;
303
+ writeFileSync(temporary, `${JSON.stringify(document, null, 2)}\n`, 'utf8');
304
+ rmSync(target, { force: true });
305
+ cpSync(temporary, target);
306
+ rmSync(temporary, { force: true });
307
+ }
308
+ catch {
309
+ // Diagnostics only: failing to record an optional-runtime attempt must never
310
+ // turn a successful install into a failure. The requirement probes the tree.
311
+ }
312
+ }
313
+ /** Read one installed dependency's package.json version, or undefined. */
314
+ function readInstalledDependencyVersion(installPath, name) {
315
+ try {
316
+ const parsed = JSON.parse(readFileSync(join(installPath, 'node_modules', ...name.split('/'), 'package.json'), 'utf8'));
317
+ if (typeof parsed !== 'object' || parsed === null)
318
+ return undefined;
319
+ const version = parsed.version;
320
+ return typeof version === 'string' ? version : undefined;
321
+ }
322
+ catch {
323
+ return undefined;
324
+ }
325
+ }
326
+ /**
327
+ * Atomically REPLACE one installed record in the store lock.
328
+ *
329
+ * The SDK's `recordInstall` deliberately refuses an already-recorded identity
330
+ * (upgrade protection), and it exposes no update call. The host legitimately
331
+ * changes an installed copy AFTER activation-free materialization (optional tool
332
+ * runtimes): the recorded content digest must match the bytes the operator now
333
+ * has, and the lock is the host-owned document that carries it. The replacement is
334
+ * a same-file atomic rename, so a crash leaves either the old or the new record.
335
+ * @param storeDir - the configured store.
336
+ * @param updated - the record to store, keyed by identity and version.
337
+ * @returns whether the record was found and replaced.
338
+ */
339
+ function replaceInstalledRecord(storeDir, updated) {
340
+ try {
341
+ const store = new ExtensionStore(storeDir);
342
+ const lock = store.readLock();
343
+ if (lock.corrupt)
344
+ return false;
345
+ const index = lock.value.extensions.findIndex(candidate => candidate.extensionId === updated.extensionId && candidate.version === updated.version);
346
+ if (index === -1)
347
+ return false;
348
+ const extensions = [...lock.value.extensions];
349
+ extensions[index] = updated;
350
+ const target = store.lockPath;
351
+ const temporary = `${target}.${process.pid}.${Date.now().toString(36)}.tmp`;
352
+ writeFileSync(temporary, `${JSON.stringify({ lockVersion: 1, extensions }, null, 2)}\n`, 'utf8');
353
+ renameSync(temporary, target);
354
+ return true;
355
+ }
356
+ catch {
357
+ return false;
358
+ }
359
+ }
360
+ /**
361
+ * Directories to search for OPERATOR-PREINSTALLED packages, deepest-nested first.
362
+ *
363
+ * A preinstalled package is a LEAF: its transitive dependencies already sit in its
364
+ * OWN `node_modules` (npm nests them when versions conflict), so root-level lookup
365
+ * alone misses e.g. `@huggingface/transformers/node_modules/onnxruntime-web`. This
366
+ * enumerates the preinstalled root, each top-level package directory, and (bounded)
367
+ * their nested package directories; the resolver tries each in order.
368
+ * @param root - the operator-configured preinstalled root (its `node_modules` is searched).
369
+ * @param depth - how many nested package levels to enumerate (bounded).
370
+ * @returns candidate package roots, root first.
371
+ */
372
+ function preinstalledSearchRoots(root, depth = 3) {
373
+ const candidates = [root];
374
+ const visit = (nodeModules, remaining) => {
375
+ if (remaining <= 0)
376
+ return;
377
+ let entries;
378
+ try {
379
+ entries = readdirSync(nodeModules);
380
+ }
381
+ catch {
382
+ return;
383
+ }
384
+ for (const entry of entries) {
385
+ if (entry.startsWith('.'))
386
+ continue;
387
+ const entryPath = join(nodeModules, entry);
388
+ if (entry.startsWith('@')) {
389
+ let scoped;
390
+ try {
391
+ scoped = readdirSync(entryPath);
392
+ }
393
+ catch {
394
+ continue;
395
+ }
396
+ for (const name of scoped) {
397
+ const packageDir = join(entryPath, name);
398
+ candidates.push(packageDir);
399
+ visit(join(packageDir, 'node_modules'), remaining - 1);
400
+ }
401
+ continue;
402
+ }
403
+ candidates.push(entryPath);
404
+ visit(join(entryPath, 'node_modules'), remaining - 1);
405
+ }
406
+ };
407
+ visit(join(root, 'node_modules'), depth);
408
+ return candidates;
409
+ }
255
410
  /**
256
411
  * Every declared deployment whose recorded readiness does not permit activation.
257
412
  *
@@ -707,6 +862,9 @@ export class ExtensionsService {
707
862
  else {
708
863
  requirements.push(requirement('integrity', false, input.integrityReason ?? `the installed content's integrity is ${input.integrity}`, 'install'));
709
864
  }
865
+ // RUNTIME: optional tool-runtime packages must be materialized, or the
866
+ // extension's tools load and fail at call time — which is not activation.
867
+ requirements.push(this.#runtimeRequirement(input));
710
868
  // HARNESS MODEL: only declarative packages are served by the host broker.
711
869
  if (input.facts.executionKind === 'declarative') {
712
870
  requirements.push(this.#harnessModelRequirement());
@@ -795,6 +953,45 @@ export class ExtensionsService {
795
953
  ? requirement('dependencies', true, `all ${count} declared runtime dependenc${count === 1 ? 'y resolves' : 'ies resolve'} in the host's installed tree`)
796
954
  : 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
955
  }
956
+ /**
957
+ * The OPTIONAL tool-runtime requirement.
958
+ *
959
+ * Module extensions declare the packages their tools `require()` at call time as
960
+ * optionalDependencies (e.g. tongue's `@desert-ant-labs/tongue`). If one is absent
961
+ * the extension still activates and its tools fail at call time, so this
962
+ * requirement BLOCKS activation instead: a tool that cannot load is not served.
963
+ * The sidecar records why a materialization attempt failed (the lock cannot).
964
+ */
965
+ #runtimeRequirement(input) {
966
+ const declared = input.facts.optionalDependencies;
967
+ if (declared.length === 0) {
968
+ return requirement('runtime', true, 'the package declares no optional tool runtime');
969
+ }
970
+ if (!input.installed || input.record === undefined) {
971
+ return requirement('runtime', true, 'not installed yet; optional tool runtimes are materialized and verified at install time');
972
+ }
973
+ const recorded = readRuntimeDependencyDocument(input.storeDir).extensions[input.id];
974
+ const unresolved = [];
975
+ const resolved = [];
976
+ for (const dependency of declared) {
977
+ const installedVersion = readInstalledDependencyVersion(input.record.installPath, dependency.name);
978
+ if (installedVersion === undefined) {
979
+ const attempt = recorded?.optional.find(entry => entry.name === dependency.name && !entry.satisfied);
980
+ unresolved.push(`${dependency.name} ${dependency.range} is not installed inside the extension`
981
+ + (attempt?.error === undefined ? '' : `: ${attempt.error}`));
982
+ }
983
+ else if (!satisfiesRegistryRange(installedVersion, dependency.range)) {
984
+ unresolved.push(`${dependency.name} is installed at ${installedVersion}, which does not satisfy ${dependency.range}`);
985
+ }
986
+ else {
987
+ resolved.push(`${dependency.name}@${installedVersion}`);
988
+ }
989
+ }
990
+ if (unresolved.length === 0) {
991
+ return requirement('runtime', true, `the optional tool runtime${resolved.length === 1 ? ' is' : 's are'} materialized (${resolved.join(', ')})`);
992
+ }
993
+ return requirement('runtime', false, `the extension's tools cannot load: ${unresolved.join('; ')}`, 'install');
994
+ }
798
995
  /** The harness-model requirement for a declarative package. */
799
996
  #harnessModelRequirement() {
800
997
  const status = this.#options.harnessProviderStatus?.();
@@ -1119,6 +1316,9 @@ export class ExtensionsService {
1119
1316
  registryUrl,
1120
1317
  archiveFactory: createTarGzipArchiveSource,
1121
1318
  maxTarballBytes: this.#options.registryTarballMaxBytes ?? MAX_DEPENDENCY_ARCHIVE_BYTES,
1319
+ ...this.#options.registryTarballTimeoutMs === undefined
1320
+ ? {}
1321
+ : { tarballTimeoutMs: this.#options.registryTarballTimeoutMs },
1122
1322
  });
1123
1323
  let resolved;
1124
1324
  try {
@@ -1141,7 +1341,7 @@ export class ExtensionsService {
1141
1341
  // Registry metadata recorded AS DATA, never as trust: the bytes are
1142
1342
  // verified against the same sha512 before anything is extracted.
1143
1343
  provenance: { registryIntegrity: resolved.integrity },
1144
- dependencies: createRegistryDependencyGraph(session),
1344
+ dependencies: this.#installGraph(session),
1145
1345
  });
1146
1346
  }
1147
1347
  catch (error) {
@@ -1164,6 +1364,10 @@ export class ExtensionsService {
1164
1364
  if (installed.archiveDigest.trim().length === 0) {
1165
1365
  throw new ExtensionsServiceError('extension-digest-unavailable', `${installed.extensionId}@${installed.version} was installed without a content digest, so it cannot be verified before activation`);
1166
1366
  }
1367
+ // Optional tool runtimes are materialized AFTER the package install and are
1368
+ // NOT allowed to fail it: tongue/voz tools `require()` an optional package at
1369
+ // call time, and the requirement model blocks activation if it is absent.
1370
+ await this.#materializeOptionalRuntimes(storeDir, installed, session, signal);
1167
1371
  return {
1168
1372
  id: installed.extensionId,
1169
1373
  version: installed.version,
@@ -1172,6 +1376,136 @@ export class ExtensionsService {
1172
1376
  resolvedVersion: resolved.version,
1173
1377
  };
1174
1378
  }
1379
+ /**
1380
+ * The dependency graph used on the REGISTRY install path (regular AND optional).
1381
+ *
1382
+ * PRECEDENCE: when the operator's preinstalled gate is ON and the host's own
1383
+ * tree holds a package satisfying the range, that operator-completed content is
1384
+ * preferred. The SDK copies it with provenance `preinstalled` and records that
1385
+ * no lifecycle script was run. Anything NOT preinstalled falls to the registry
1386
+ * arm, where EXT-10 still refuses script-declaring packages.
1387
+ *
1388
+ * DEPTH: preinstalled packages are LEAVES for graph purposes — their transitive
1389
+ * tree travels with them — but real registry trees (onnxruntime-node) exceed the
1390
+ * SDK's default 3-level bound, so the host raises the default to
1391
+ * {@link DEFAULT_REGISTRY_DEPENDENCY_DEPTH} and makes it configurable.
1392
+ * @param session - the registry session.
1393
+ * @returns the graph.
1394
+ */
1395
+ #installGraph(session) {
1396
+ const depth = this.#options.registryDependencyDepth ?? DEFAULT_REGISTRY_DEPENDENCY_DEPTH;
1397
+ const registryGraph = { ...createRegistryDependencyGraph(session), maxDepth: depth };
1398
+ const preinstalledRoot = this.#options.preinstalledDependenciesRoot ?? '';
1399
+ const allowPreinstalled = this.#options.allowPreinstalledDependencies === true && preinstalledRoot !== '';
1400
+ if (!allowPreinstalled)
1401
+ return registryGraph;
1402
+ const preinstalledRoots = preinstalledSearchRoots(preinstalledRoot);
1403
+ return {
1404
+ resolver: {
1405
+ async resolve(name, range) {
1406
+ // Prefer operator-completed content, root first and then nested package
1407
+ // trees: a preinstalled package's transitive deps live in ITS OWN
1408
+ // node_modules, so root-level lookup alone would fall through to the
1409
+ // registry and refuse a script-declaring leaf under EXT-10.
1410
+ for (const candidateRoot of preinstalledRoots) {
1411
+ try {
1412
+ const found = resolveFirstPartyDependency({ sourcePackageDir: candidateRoot }, name, range);
1413
+ return { name: found.name, version: found.version, dir: found.directory, provenance: 'preinstalled' };
1414
+ }
1415
+ catch {
1416
+ continue;
1417
+ }
1418
+ }
1419
+ return registryGraph.resolver.resolve(name, range);
1420
+ },
1421
+ },
1422
+ archive: registryGraph.archive,
1423
+ allowPreinstalled: true,
1424
+ preinstalledRoot,
1425
+ maxDepth: depth,
1426
+ };
1427
+ }
1428
+ /**
1429
+ * Materialize the extension's optionalDependencies without failing the install.
1430
+ *
1431
+ * Each declaration is resolved and materialized through the SAME SDK dependency
1432
+ * graph discipline as regular dependencies (bounded fetch, sha512 verification,
1433
+ * EXT-10 script refusal) into a scratch package, then merged into the
1434
+ * extension's own node_modules. A failure is RECORDED (store sidecar) and the
1435
+ * requirement model blocks activation instead; the package install stands.
1436
+ *
1437
+ * The store record's content digest is recomputed after a successful merge,
1438
+ * because the installed bytes legitimately changed; the archive digest (the
1439
+ * tarball identity) is untouched.
1440
+ * @param storeDir - the configured store.
1441
+ * @param installed - the just-installed package.
1442
+ * @param session - the registry session used for the install.
1443
+ * @param signal - cancellation.
1444
+ */
1445
+ async #materializeOptionalRuntimes(storeDir, installed, session, signal) {
1446
+ const optional = readDeclaredDependencies(installed.installPath, 'optionalDependencies');
1447
+ if (optional.length === 0)
1448
+ return;
1449
+ const attempts = [];
1450
+ const locked = [];
1451
+ for (const dependency of optional) {
1452
+ signal?.throwIfAborted();
1453
+ const scratch = mkdtempSync(join(tmpdir(), 'dsh-optional-runtime-'));
1454
+ try {
1455
+ 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');
1456
+ const materialized = await installDependencyGraph(scratch, this.#installGraph(session));
1457
+ const sourceNodeModules = join(scratch, 'node_modules');
1458
+ const targetNodeModules = join(installed.installPath, 'node_modules');
1459
+ if (existsSync(sourceNodeModules)) {
1460
+ for (const name of readdirSync(sourceNodeModules)) {
1461
+ const from = join(sourceNodeModules, name);
1462
+ const to = join(targetNodeModules, name);
1463
+ if (existsSync(to)) {
1464
+ const kept = readInstalledDependencyVersion(installed.installPath, name);
1465
+ const wanted = materialized.find(entry => entry.name === name);
1466
+ if (kept !== undefined && wanted !== undefined && kept !== wanted.version) {
1467
+ throw new Error(`${name} is already installed at ${kept}, but the optional runtime needs ${wanted.version}`);
1468
+ }
1469
+ continue;
1470
+ }
1471
+ cpSync(from, to, { recursive: true });
1472
+ }
1473
+ locked.push(...materialized);
1474
+ }
1475
+ const own = materialized.find(entry => entry.name === dependency.name);
1476
+ attempts.push({
1477
+ name: dependency.name,
1478
+ range: dependency.range,
1479
+ satisfied: true,
1480
+ ...own === undefined ? {} : { version: own.version },
1481
+ });
1482
+ }
1483
+ catch (error) {
1484
+ if (signal?.aborted === true)
1485
+ throw error;
1486
+ attempts.push({ name: dependency.name, range: dependency.range, satisfied: false, error: messageOf(error) });
1487
+ }
1488
+ finally {
1489
+ rmSync(scratch, { recursive: true, force: true });
1490
+ }
1491
+ }
1492
+ writeRuntimeDependencyDocument(storeDir, installed.extensionId, installed.version, attempts);
1493
+ if (locked.length === 0)
1494
+ return;
1495
+ const store = new ExtensionStore(storeDir);
1496
+ const record = store.listInstalled().value.find(candidate => candidate.extensionId === installed.extensionId && candidate.version === installed.version);
1497
+ if (record === undefined)
1498
+ return;
1499
+ const existing = new Set((record.dependencies ?? []).map(entry => entry.name));
1500
+ const additions = locked.filter(entry => !existing.has(entry.name));
1501
+ if (additions.length === 0)
1502
+ return;
1503
+ replaceInstalledRecord(storeDir, {
1504
+ ...record,
1505
+ contentDigest: digestInstalledContent(installed.installPath),
1506
+ dependencies: [...(record.dependencies ?? []), ...additions],
1507
+ });
1508
+ }
1175
1509
  /**
1176
1510
  * Install one extension from a local source directory (EXT-06 developer mode).
1177
1511
  *
@@ -1319,6 +1653,10 @@ export class ExtensionsService {
1319
1653
  // that classification while refusing before the lifecycle call.
1320
1654
  throw new ExtensionsServiceError('extension-activation-failed', `[INTEGRITY_MISMATCH] ${unmet.reason}`);
1321
1655
  }
1656
+ if (unmet.kind === 'runtime') {
1657
+ // Activation that cannot serve the extension's tools is not activation.
1658
+ throw new ExtensionsServiceError('extension-runtime-unavailable', unmet.reason);
1659
+ }
1322
1660
  throw new ExtensionsServiceError('extension-requirement-unmet', unmet.reason);
1323
1661
  }
1324
1662
  const ownedHere = current?.observedActivation === 'active'
package/lib/index.d.ts CHANGED
@@ -153,6 +153,19 @@ 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;
161
+ /**
162
+ * Dependency-graph depth bound for registry installs. Default 12.
163
+ *
164
+ * Preinstalled dependencies are leaves (their own tree travels with them);
165
+ * registry-resolved graphs are bounded by this, and a refusal names the level
166
+ * and the package.
167
+ */
168
+ extensionDependencyDepth?: number;
156
169
  /**
157
170
  * Operator gate: allow dependency content that arrived already materialized.
158
171
  *
@@ -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,14 @@ 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),
112
+ /** Depth bound for registry dependency graphs. Default 12 (SDK default is 3). */
113
+ extensionDependencyDepth: z.number().min(1).max(64).default(12),
106
114
  allowPreinstalledDependencies: z.boolean().default(false),
107
115
  preinstalledDependenciesRoot: z.string().default(''),
108
116
  /**
@@ -337,6 +345,44 @@ export async function apply(ctx, config = {}) {
337
345
  * install loop; the extension-store block assigns it.
338
346
  */
339
347
  let extensionLifecycle;
348
+ /**
349
+ * TASK-117: the catalogue-vs-extension tool-name reconciliation.
350
+ *
351
+ * OWNERSHIP RULE: an INSTALLED extension that declares a tool with a given
352
+ * name OWNS that name — its activation registers the tool, so the catalogue
353
+ * must SKIP its own registration for a contract-backed entry with the same
354
+ * tool name (the live EXTENSION_FAULT was the catalogue winning the race at
355
+ * boot). The skip is recorded; when the owning extension deactivates, the
356
+ * catalogue registration is RESTORED. Deterministic in both orders: the
357
+ * probe reads the durable store, not an in-flight registry.
358
+ */
359
+ const extensionStore = config.extensionStore !== undefined && config.extensionStore.length > 0
360
+ ? new ExtensionStore(config.extensionStore)
361
+ : undefined;
362
+ const catalogueDeferred = new Set();
363
+ const extensionOwnsToolName = (toolName) => {
364
+ if (extensionStore === undefined)
365
+ return false;
366
+ try {
367
+ // Only an ACTIVE extension owns a name at runtime: a disabled (or
368
+ // failed) installation must not keep the catalogue from serving it.
369
+ const active = new Set(extensionStore.readProfileState('default').value
370
+ .filter(entry => entry.desiredActivation === 'active' && entry.observedActivation === 'active')
371
+ .map(entry => entry.extensionId));
372
+ for (const record of extensionStore.listInstalled().value) {
373
+ if (!active.has(record.extensionId))
374
+ continue;
375
+ const discovery = discoverExtension(record.installPath);
376
+ if (discovery.manifest.tools.some(tool => tool.name === toolName))
377
+ return true;
378
+ }
379
+ }
380
+ catch {
381
+ // A broken package cannot own a tool name; the catalogue keeps it.
382
+ return false;
383
+ }
384
+ return false;
385
+ };
340
386
  /**
341
387
  * The extensions the contribution registrar currently admits.
342
388
  *
@@ -373,6 +419,8 @@ export async function apply(ctx, config = {}) {
373
419
  installSource: config.extensionInstallSource ?? 'auto',
374
420
  registryUrl: config.extensionRegistry ?? 'https://registry.npmjs.org/',
375
421
  registryTarballMaxBytes: config.extensionTarballMaxBytes ?? 256 * 1024 * 1024,
422
+ registryTarballTimeoutMs: config.extensionTarballTimeoutMs ?? 10 * 60_000,
423
+ registryDependencyDepth: config.extensionDependencyDepth ?? 12,
376
424
  /**
377
425
  * The operator gate for already-materialized dependencies. OFF by default:
378
426
  * a dependency whose package.json declares install-time scripts still
@@ -411,11 +459,28 @@ export async function apply(ctx, config = {}) {
411
459
  onActivationChange: (extensionId, active) => {
412
460
  if (active) {
413
461
  activatedExtensions.add(extensionId);
462
+ // TASK-117: the extension now owns its tool names — withdraw the
463
+ // catalogue registrations for those names BEFORE the lifecycle
464
+ // publishes (the hook runs before activate), so the activation cannot
465
+ // collide with a catalogue tool. The names are deferred, not lost.
466
+ for (const item of resolved.filter(candidate => candidate.entry.contract !== null)) {
467
+ if (!extensionOwnsToolName(item.entry.tool.name))
468
+ continue;
469
+ if (!installed.has(item.entry.id))
470
+ continue;
471
+ uninstall(item.entry.id);
472
+ catalogueDeferred.add(item.entry.id);
473
+ ctx.logger.info(`model-tools: ${item.entry.name}'s tool ${item.entry.tool.name} is taken over by ${extensionId}; `
474
+ + 'the catalogue registration is withdrawn and deferred');
475
+ }
414
476
  return;
415
477
  }
416
478
  if (extensionLifecycle?.stateOf(extensionId)?.observedActivation !== 'active') {
417
479
  activatedExtensions.delete(extensionId);
418
480
  }
481
+ // TASK-117: the extension released its tool names — restore every
482
+ // deferred catalogue registration the release freed.
483
+ void restoreDeferredCatalogue();
419
484
  },
420
485
  /**
421
486
  * The harness-model provider status seam (task-93): the thunk evaluates the
@@ -1110,6 +1175,18 @@ export async function apply(ctx, config = {}) {
1110
1175
  toolName = existing.toolName;
1111
1176
  dispose = () => { };
1112
1177
  }
1178
+ else if (extensionOwnsToolName(entry.tool.name)) {
1179
+ /**
1180
+ * TASK-117: an installed extension OWNS this tool name — its
1181
+ * activation registers it, so the catalogue registration is SKIPPED
1182
+ * rather than racing it (the live EXTENSION_FAULT). The deferral is
1183
+ * recorded; the extension's deactivation restores the catalogue tool.
1184
+ */
1185
+ catalogueDeferred.add(entry.id);
1186
+ ctx.logger.info(`model-tools: ${entry.name}'s tool ${entry.tool.name} is owned by an installed extension; `
1187
+ + 'the catalogue registration is deferred until the extension releases the name');
1188
+ return false;
1189
+ }
1113
1190
  else {
1114
1191
  const registered = registerContractTool(ctx, binding, host);
1115
1192
  registeredContracts.set(entry.contract, registered);
@@ -1211,6 +1288,33 @@ export async function apply(ctx, config = {}) {
1211
1288
  const configuredIds = resolved
1212
1289
  .filter(item => (wanted === undefined || wanted.has(item.entry.id)) && !excluded.has(item.entry.id))
1213
1290
  .map(item => item.entry.id);
1291
+ /**
1292
+ * TASK-117: the deferred catalogue registrations, restored when the owning
1293
+ * extension releases a tool name (deactivation). Runs after `install` and
1294
+ * `resolved` exist; the onActivationChange hook fires it asynchronously.
1295
+ */
1296
+ const restoreDeferredCatalogue = async () => {
1297
+ for (const modelId of [...catalogueDeferred]) {
1298
+ const item = resolved.find(candidate => candidate.entry.id === modelId);
1299
+ if (item === undefined) {
1300
+ catalogueDeferred.delete(modelId);
1301
+ continue;
1302
+ }
1303
+ if (extensionOwnsToolName(item.entry.tool.name))
1304
+ continue;
1305
+ catalogueDeferred.delete(modelId);
1306
+ ctx.logger.info(`model-tools: ${item.entry.name}'s tool ${item.entry.tool.name} is released; restoring the catalogue registration`);
1307
+ try {
1308
+ await install(item);
1309
+ }
1310
+ catch (error) {
1311
+ // A failed restore is reported, never swallowed silently: the operator
1312
+ // must see why the catalogue tool did not come back.
1313
+ ctx.logger.warn(`model-tools: could not restore the catalogue registration for ${item.entry.name}: `
1314
+ + `${error instanceof Error ? error.message : String(error)}`);
1315
+ }
1316
+ }
1317
+ };
1214
1318
  for (const item of resolved) {
1215
1319
  const { install: selection, disabled } = resolveSelection(configuredIds, persisted);
1216
1320
  if (!selection.has(item.entry.id)) {
@@ -2353,7 +2457,9 @@ export async function apply(ctx, config = {}) {
2353
2457
  */
2354
2458
  const extensionStoreDir = config.extensionStore ?? '';
2355
2459
  if (extensionStoreDir.length > 0) {
2356
- const store = new ExtensionStore(extensionStoreDir);
2460
+ // TASK-117: the store is the HOISTED instance (constructed at the apply
2461
+ // top so the catalogue-install loop can probe extension tool ownership).
2462
+ const store = extensionStore;
2357
2463
  /**
2358
2464
  * How dispatch reaches an ACTIVATED extension.
2359
2465
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@try-works/dsh-model-as-tool",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "Install Desert Ant Labs on-device models as DSH tools and skills, with per-platform capability gating",
5
5
  "keywords": [
6
6
  "dsh",
package/remote/spec.mjs CHANGED
@@ -49,6 +49,7 @@ const REQUIREMENT_KIND = {
49
49
  'store',
50
50
  'source',
51
51
  'dependencies',
52
+ 'runtime',
52
53
  'assets',
53
54
  'executable',
54
55
  'harness-model',