dsh-vision-router 2.3.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/README.md +18 -3
  2. package/README.zh.md +16 -3
  3. package/docs/architecture/3.0-architecture-plan.md +252 -0
  4. package/docs/architecture/3.0-r0-contract-ledger.md +137 -0
  5. package/docs/architecture/3.0-r1-source-artifact-boundary.md +98 -0
  6. package/docs/architecture/3.0-r10-final-correctness-closure.md +207 -0
  7. package/docs/architecture/3.0-r11-adversarial-review.md +447 -0
  8. package/docs/architecture/3.0-r5-browser-go-no-go.md +165 -0
  9. package/docs/architecture/3.0-r5-browser-typescript-gate.md +105 -0
  10. package/docs/architecture/3.0-r6-compat-retirement.md +203 -0
  11. package/docs/architecture/3.0-r7-public-api.md +151 -0
  12. package/docs/architecture/3.0-r8-ci-release.md +248 -0
  13. package/docs/architecture/3.0-r9-final-audit.md +370 -0
  14. package/docs/architecture/dsh-support-window.md +13 -3
  15. package/docs/releases/v3.0.0.md +85 -0
  16. package/docs/releases/v3.0.1.md +77 -0
  17. package/entry.js +1 -1
  18. package/index.js +110 -71
  19. package/lib/agent-request-route-authority.js +1 -20
  20. package/lib/core-apply-lifecycle.js +37 -43
  21. package/lib/core-cache.js +87 -0
  22. package/lib/core-primitives.js +11 -144
  23. package/lib/core-vision-surface-domain.js +63 -0
  24. package/lib/core-vision-surface.js +11 -77
  25. package/lib/delegated-call-config.js +15 -24
  26. package/lib/doctor-cli.js +0 -0
  27. package/lib/doctor-runtime.js +4 -1
  28. package/lib/dsh-contract-compat.js +26 -230
  29. package/lib/dsh-host-capabilities.js +3 -9
  30. package/lib/dsh-settings-017-compat.js +17 -10
  31. package/lib/file-logger.js +8 -3
  32. package/lib/grounding-coordinate-runtime.js +1 -2
  33. package/lib/http-body-limit.js +97 -79
  34. package/lib/image-offload-compat.js +30 -21
  35. package/lib/image-resource-governor.js +210 -228
  36. package/lib/legacy-global-proxy-boundary.js +46 -3
  37. package/lib/live-model-client-prelude.js +12 -4
  38. package/lib/live-model-discovery.js +134 -43
  39. package/lib/local-vision-stabilizer.js +33 -18
  40. package/lib/maintenance-routes.js +1 -3
  41. package/lib/native-image-coexistence.js +15 -3
  42. package/lib/ollama-cold-start.js +87 -23
  43. package/lib/pi-ai-bridge-wire-compat.js +3 -2
  44. package/lib/proxy-dispatcher-pool.js +151 -92
  45. package/lib/proxy-routing.js +75 -51
  46. package/lib/proxy-url-compat.js +3 -10
  47. package/lib/public-config.js +23 -44
  48. package/lib/public-entry.d.ts +148 -0
  49. package/lib/public-entry.js +17 -4
  50. package/lib/replay-delegation.js +12 -7
  51. package/lib/replay-envelope-v2-compat.js +12 -7
  52. package/lib/runtime-composition.js +30 -10
  53. package/lib/screenshot-source-boundary.js +2 -2
  54. package/lib/session-affinity-runtime.js +113 -97
  55. package/lib/session-affinity.js +89 -76
  56. package/lib/session-event-history-compat.js +30 -0
  57. package/lib/session-query-readers.js +263 -0
  58. package/lib/session-surface-compat.js +30 -31
  59. package/lib/session-surface-policy-domain.js +85 -0
  60. package/lib/session-surface-policy.js +2 -111
  61. package/lib/session-turn-resolver.js +2 -6
  62. package/lib/session-vision-attachment-index.js +143 -0
  63. package/lib/session-vision-delegation-boundary.js +34 -0
  64. package/lib/session-vision-delegation.js +22 -0
  65. package/lib/session-vision-index.js +25 -107
  66. package/lib/session-vision-mode-authority.js +229 -192
  67. package/lib/session-vision-mode-boundary.js +65 -22
  68. package/lib/session-vision-policy-domain.js +304 -0
  69. package/lib/session-vision-policy.js +104 -0
  70. package/lib/session-vision-state.js +368 -378
  71. package/lib/settings-client-017-compat.js +16 -10
  72. package/lib/structured-flow-hardening.js +22 -4
  73. package/lib/tesseract-exec-compat.js +9 -1
  74. package/lib/turn-budget-context.js +47 -41
  75. package/lib/update-check.js +11 -2
  76. package/lib/vision-attachment-handle-runtime.js +176 -156
  77. package/lib/vision-backend-runtime-policy.js +16 -0
  78. package/lib/vision-background-benchmark.js +55 -6
  79. package/lib/vision-background-failure-policy.js +41 -41
  80. package/lib/vision-background-stop-store-core.js +217 -0
  81. package/lib/vision-background-stop-store.js +8 -179
  82. package/lib/vision-capability-benchmark.js +11 -61
  83. package/lib/vision-capability-evidence.js +35 -0
  84. package/lib/vision-capability-fingerprint.js +72 -0
  85. package/lib/vision-capability-identity.js +116 -61
  86. package/lib/vision-capability-router.js +13 -33
  87. package/lib/vision-chunk-assembler.js +95 -0
  88. package/lib/vision-diagnostics-routes.js +42 -4
  89. package/lib/vision-execution-order-apply.js +45 -55
  90. package/lib/vision-execution-order.js +19 -19
  91. package/lib/vision-execution-policy.js +12 -7
  92. package/lib/vision-model-registry.js +30 -17
  93. package/lib/vision-model-visibility-boundary-main.js +15 -16
  94. package/lib/vision-provider-transport.js +137 -147
  95. package/lib/vision-routing-authority.js +47 -48
  96. package/lib/vision-routing-product.js +26 -29
  97. package/lib/vision-routing-settings-prelude.js +8 -3
  98. package/lib/vision-runtime-performance-store.js +166 -0
  99. package/lib/vision-runtime-performance.js +13 -142
  100. package/lib/vision-tool-runtime-boundary.js +99 -30
  101. package/lib/web/dsh-settings-017-root-transport.js +27 -12
  102. package/lib/web/remote-settings-client.js +4 -7
  103. package/lib/web-capability-boundary.js +17 -7
  104. package/lib/wrapper-directory.js +14 -23
  105. package/package.json +37 -11
@@ -17,6 +17,9 @@ const toolRuntime = new AsyncLocalStorage()
17
17
  const wrappedContexts = new WeakMap()
18
18
  const runtimeStates = new WeakMap()
19
19
  const wrappedFileSystems = new WeakMap()
20
+ // Settings proxies are cached per underlying service/scope and per runtime
21
+ // state. Re-creating them on every `ctx.settings` read would re-run scope
22
+ // activation and register a second lifecycle effect for the same generation.
20
23
  const wrappedSettings = new WeakMap()
21
24
  const wrappedScopes = new WeakMap()
22
25
  const wrappedLlms = new WeakMap()
@@ -104,7 +107,7 @@ function createRuntimeState(initialConfig = {}) {
104
107
  const cache = new LiveDescribeCache()
105
108
  const endpoints = new HttpEndpointRevisionTracker()
106
109
  const transparentReasoning = new Map()
107
- let config = {
110
+ const fallbackConfig = {
108
111
  cache: true,
109
112
  cacheMaxEntries: 200,
110
113
  cacheTtlSeconds: 3600,
@@ -115,8 +118,13 @@ function createRuntimeState(initialConfig = {}) {
115
118
  ? initialConfig
116
119
  : {}),
117
120
  }
121
+ let config = fallbackConfig
118
122
  let signature = stableRuntimeConfigSignature(config)
119
123
  let revision = 0
124
+ let activeSettingsGeneration
125
+ // scope -> { runtimeState, token, ownsLifecycle }: the generation registry
126
+ // that makes repeated activation idempotent per runtime.
127
+ const wiredScopes = new WeakMap()
120
128
 
121
129
  const noteConfig = (value) => {
122
130
  if (!value || typeof value !== 'object' || Array.isArray(value)) return config
@@ -135,6 +143,59 @@ function createRuntimeState(initialConfig = {}) {
135
143
  return config
136
144
  }
137
145
 
146
+ const activateSettingsScope = (scope, ownerCtx, runtimeState) => {
147
+ if (!scope || (typeof scope !== 'object' && typeof scope !== 'function')) return undefined
148
+ // Registering the same scope twice (repeated `ctx.settings` reads, a
149
+ // generation that re-registers its namespace) must not stack lifecycle
150
+ // owners or mint a competing generation: reuse the existing one.
151
+ const known = wiredScopes.get(scope)
152
+ if (known && known.runtimeState === runtimeState) {
153
+ if (activeSettingsGeneration?.token !== known.token) {
154
+ activeSettingsGeneration = { token: known.token, scope, ownsLifecycle: known.ownsLifecycle }
155
+ }
156
+ return known.token
157
+ }
158
+ const token = {}
159
+ // Lifecycle ownership is an optimisation, not a precondition: a context
160
+ // without `effect()` (harness contexts, non-Cordis embeddings) still needs
161
+ // live settings to reach the runtime, but the generation must then be the
162
+ // most recently registered scope so a stale scope cannot outrank it.
163
+ let ownsLifecycle = false
164
+ try {
165
+ if (typeof ownerCtx?.effect === 'function') {
166
+ ownerCtx.effect(
167
+ () => () => {
168
+ if (activeSettingsGeneration?.token !== token) return
169
+ activeSettingsGeneration = undefined
170
+ noteConfig(fallbackConfig)
171
+ },
172
+ 'vision-router: tool runtime settings lifecycle',
173
+ )
174
+ ownsLifecycle = true
175
+ }
176
+ } catch {
177
+ ownsLifecycle = false
178
+ }
179
+ wiredScopes.set(scope, { runtimeState, token, ownsLifecycle })
180
+ activeSettingsGeneration = { token, scope, ownsLifecycle }
181
+ try {
182
+ if (typeof scope.get === 'function') noteConfig(scope.get())
183
+ } catch {
184
+ // Boot config remains authoritative until the scope becomes readable.
185
+ }
186
+ return token
187
+ }
188
+
189
+ const noteSettingsConfig = (token, value) => {
190
+ // Only the active generation may write config. An unowned generation is
191
+ // still "the active one" while it is the latest registration, so a
192
+ // lifecycle-less context keeps its watch path exactly as before the token
193
+ // existed, while a retired generation can no longer resurrect stale config.
194
+ if (token === undefined || activeSettingsGeneration?.token !== token) return false
195
+ noteConfig(value)
196
+ return true
197
+ }
198
+
138
199
  const rememberTransparentReasoning = (key, value) => {
139
200
  if (transparentReasoning.size >= MAX_TRANSPARENT_REASONING_MEMORY && !transparentReasoning.has(key)) {
140
201
  const oldest = transparentReasoning.keys().next().value
@@ -156,6 +217,8 @@ function createRuntimeState(initialConfig = {}) {
156
217
  cache,
157
218
  endpoints,
158
219
  noteConfig,
220
+ activateSettingsScope,
221
+ noteSettingsConfig,
159
222
  config: () => config,
160
223
  revision: () => revision,
161
224
  rememberTransparentReasoning,
@@ -242,9 +305,12 @@ function wrapFileSystem(fs) {
242
305
  return wrapped
243
306
  }
244
307
 
245
- function projectLiveSettings(value, runtimeState) {
308
+ function projectLiveSettings(value, runtimeState, settingsToken) {
246
309
  if (!value || typeof value !== 'object' || Array.isArray(value)) return value
247
- runtimeState.noteConfig(value)
310
+ if (settingsToken !== undefined && runtimeState.noteSettingsConfig(settingsToken, value) !== true) {
311
+ return value
312
+ }
313
+ if (settingsToken === undefined) runtimeState.noteConfig(value)
248
314
  const toolState = toolRuntime.getStore()
249
315
  const httpProviders = runtimeState.endpoints.project(value.httpProviders)
250
316
  const suppressCoreCache = toolState?.disableCoreCache === true && value.cache !== false
@@ -256,21 +322,16 @@ function projectLiveSettings(value, runtimeState) {
256
322
  }
257
323
  }
258
324
 
259
- function wrapSettingsScope(scope, runtimeState) {
325
+ function wrapSettingsScope(scope, runtimeState, settingsToken) {
260
326
  if (!scope || (typeof scope !== 'object' && typeof scope !== 'function')) return scope
261
- let byRuntime = wrappedScopes.get(scope)
262
- if (!byRuntime) {
263
- byRuntime = new WeakMap()
264
- wrappedScopes.set(scope, byRuntime)
265
- }
266
- const cached = byRuntime.get(runtimeState)
267
- if (cached) return cached
327
+ const cached = wrappedScopes.get(scope)
328
+ if (cached && cached.runtimeState === runtimeState && cached.token === settingsToken) return cached.wrapped
268
329
  const wrapped = new Proxy(scope, {
269
330
  get(target, property) {
270
331
  if (property === 'get') {
271
332
  const get = Reflect.get(target, property, target)
272
333
  if (typeof get !== 'function') return get
273
- return (...args) => projectLiveSettings(get.apply(target, args), runtimeState)
334
+ return (...args) => projectLiveSettings(get.apply(target, args), runtimeState, settingsToken)
274
335
  }
275
336
  if (property === 'watch') {
276
337
  const watch = Reflect.get(target, property, target)
@@ -278,7 +339,7 @@ function wrapSettingsScope(scope, runtimeState) {
278
339
  return (callback, ...rest) => watch.call(target, (...args) => {
279
340
  try {
280
341
  const get = Reflect.get(target, 'get', target)
281
- if (typeof get === 'function') runtimeState.noteConfig(get.call(target))
342
+ if (typeof get === 'function') runtimeState.noteSettingsConfig(settingsToken, get.call(target))
282
343
  } catch {
283
344
  // Diagnostics refresh is best effort.
284
345
  }
@@ -289,19 +350,14 @@ function wrapSettingsScope(scope, runtimeState) {
289
350
  return typeof value === 'function' ? value.bind(target) : value
290
351
  },
291
352
  })
292
- byRuntime.set(runtimeState, wrapped)
353
+ wrappedScopes.set(scope, { runtimeState, token: settingsToken, wrapped })
293
354
  return wrapped
294
355
  }
295
356
 
296
- function wrapSettingsService(settings, runtimeState) {
357
+ function wrapSettingsService(settings, runtimeState, ownerCtx) {
297
358
  if (!settings || (typeof settings !== 'object' && typeof settings !== 'function')) return settings
298
- let byRuntime = wrappedSettings.get(settings)
299
- if (!byRuntime) {
300
- byRuntime = new WeakMap()
301
- wrappedSettings.set(settings, byRuntime)
302
- }
303
- const cached = byRuntime.get(runtimeState)
304
- if (cached) return cached
359
+ const cached = wrappedSettings.get(settings)
360
+ if (cached && cached.runtimeState === runtimeState) return cached.wrapped
305
361
  const wrapped = new Proxy(settings, {
306
362
  get(target, property) {
307
363
  if (property === 'register') {
@@ -310,25 +366,22 @@ function wrapSettingsService(settings, runtimeState) {
310
366
  return (namespace, ...args) => {
311
367
  const scope = register.call(target, namespace, ...args)
312
368
  if (namespace !== 'vision-router') return scope
313
- try {
314
- if (typeof scope?.get === 'function') runtimeState.noteConfig(scope.get())
315
- } catch {
316
- // Core can still run from boot config if settings are late.
317
- }
318
- return wrapSettingsScope(scope, runtimeState)
369
+ const settingsToken = runtimeState.activateSettingsScope(scope, ownerCtx, runtimeState)
370
+ if (settingsToken === undefined) return scope
371
+ return wrapSettingsScope(scope, runtimeState, settingsToken)
319
372
  }
320
373
  }
321
374
  const value = Reflect.get(target, property, target)
322
375
  return typeof value === 'function' ? value.bind(target) : value
323
376
  },
324
377
  })
325
- byRuntime.set(runtimeState, wrapped)
378
+ wrappedSettings.set(settings, { runtimeState, wrapped })
326
379
  return wrapped
327
380
  }
328
381
 
329
382
  function wrapSettingsContext(ctx, runtimeState) {
330
383
  if (!ctx || (typeof ctx !== 'object' && typeof ctx !== 'function') || !ctx.settings) return ctx
331
- const settings = wrapSettingsService(ctx.settings, runtimeState)
384
+ const settings = wrapSettingsService(ctx.settings, runtimeState, ctx)
332
385
  return new Proxy(ctx, {
333
386
  get(target, property) {
334
387
  if (property === 'settings') return settings
@@ -716,6 +769,22 @@ export function installVisionToolRuntimeBoundary(ctx, initialConfig = {}) {
716
769
  })
717
770
  wrappedContexts.set(ctx, wrapped)
718
771
  runtimeStates.set(wrapped, runtimeState)
772
+ let lifecycleOwned = false
773
+ try {
774
+ if (typeof ctx.effect === 'function') {
775
+ ctx.effect(
776
+ () => () => {
777
+ if (wrappedContexts.get(ctx) === wrapped) wrappedContexts.delete(ctx)
778
+ },
779
+ 'vision-router: vision tool runtime context lifecycle',
780
+ )
781
+ lifecycleOwned = true
782
+ }
783
+ } catch {
784
+ // Keep the current returned view usable as a one-shot boundary.
785
+ }
786
+ // runtimeState captures this generation's config/cache/endpoint revision.
787
+ if (!lifecycleOwned && wrappedContexts.get(ctx) === wrapped) wrappedContexts.delete(ctx)
719
788
  return wrapped
720
789
  }
721
790
 
@@ -55,12 +55,10 @@ function stateFor(root) {
55
55
  }
56
56
 
57
57
  function serviceOf(ctx, name) {
58
+ if (!ctx || (typeof ctx !== 'object' && typeof ctx !== 'function')) return undefined
59
+ if (typeof ctx.get !== 'function') return undefined
58
60
  try {
59
- const value = typeof ctx?.get === 'function' ? ctx.get(name) : undefined
60
- if (value !== undefined && value !== null) return value
61
- } catch {}
62
- try {
63
- const value = ctx?.[name]
61
+ const value = ctx.get(name)
64
62
  return value === undefined || value === null ? undefined : value
65
63
  } catch {
66
64
  return undefined
@@ -283,17 +281,34 @@ export function installDsh017RootLocalSettingsTransport(ctx) {
283
281
  }
284
282
  state.current = generation
285
283
  trace('generation-mount', { generation: generation.id })
286
- ensureRootRoute(root, state)
287
284
 
288
- if (typeof settingsCtx?.effect === 'function') {
285
+ let generationDisposed = false
286
+ const disposeGeneration = () => {
287
+ if (generationDisposed) return
288
+ generationDisposed = true
289
+ generation.active = false
290
+ if (state.current === generation) state.current = undefined
291
+ trace('generation-dispose', { generation: generation.id })
292
+ }
293
+
294
+ try {
295
+ if (typeof settingsCtx?.effect !== 'function') {
296
+ throw new Error('Vision Router requires lifecycle ownership for the DSH 0.1.7 settings generation')
297
+ }
289
298
  settingsCtx.effect(
290
- () => () => {
291
- generation.active = false
292
- if (state.current === generation) state.current = undefined
293
- trace('generation-dispose', { generation: generation.id })
294
- },
299
+ () => disposeGeneration,
295
300
  'vision-router: DSH 0.1.7 settings generation',
296
301
  )
302
+ } catch (error) {
303
+ disposeGeneration()
304
+ throw error
305
+ }
306
+
307
+ try {
308
+ ensureRootRoute(root, state)
309
+ } catch (error) {
310
+ disposeGeneration()
311
+ throw error
297
312
  }
298
313
  })
299
314
  }
@@ -20,14 +20,11 @@ export const SETTINGS_CONFIG_FORMS_CLIENT_PRELUDE = String.raw`(function(){
20
20
  var connectionCache = typeof WeakMap === 'function' ? new WeakMap() : undefined;
21
21
 
22
22
  function safeGet(ctx, name) {
23
- if (!ctx) return undefined;
23
+ if (!ctx || typeof ctx.get !== 'function') return undefined;
24
24
  try {
25
- if (typeof ctx.get === 'function') {
26
- var value = ctx.get(name);
27
- if (value !== undefined && value !== null) return value;
28
- }
29
- } catch (_) {}
30
- try { return ctx[name]; } catch (_) { return undefined; }
25
+ var value = ctx.get(name);
26
+ return value === undefined || value === null ? undefined : value;
27
+ } catch (_) { return undefined; }
31
28
  }
32
29
 
33
30
  function isLoopbackLocation(locationLike) {
@@ -352,13 +352,23 @@ export function installLocalMutationRouteBoundary(ctx) {
352
352
  }
353
353
  return inject.call(target, dependencies, (childCtx) => {
354
354
  const getConnection = () => {
355
- try {
356
- if (typeof childCtx?.get === 'function') return childCtx.get('connection')
357
- } catch {}
358
- try {
359
- if (typeof target?.get === 'function') return target.get('connection')
360
- } catch {}
361
- return childCtx?.connection ?? target?.connection
355
+ if (typeof childCtx?.get === 'function') {
356
+ try {
357
+ const connection = childCtx.get('connection')
358
+ if (connection !== undefined && connection !== null) return connection
359
+ } catch {}
360
+ }
361
+ if (typeof target?.get === 'function') {
362
+ try {
363
+ const connection = target.get('connection')
364
+ return connection === undefined || connection === null ? undefined : connection
365
+ } catch {
366
+ return undefined
367
+ }
368
+ }
369
+ // Non-Cordis harness compatibility only. Supported DSH Hosts have
370
+ // Context#get from the 0.1.5 floor onward.
371
+ try { return childCtx?.connection ?? target?.connection } catch { return undefined }
362
372
  }
363
373
  // Preserve the ORIGINAL child context identity for rc.6 ownership,
364
374
  // but never leave our registrar wrapper visible to other plugins.
@@ -165,39 +165,30 @@ export function installWrapperDirectoryAlias(ctx, baseConfig = {}, logger = ctx
165
165
  }
166
166
  }
167
167
 
168
- sync()
169
- // DSH's registerConfigurableProviders ties its internal cleanup to the
170
- // shared LLM service context, not to this plugin's fiber: without an
171
- // explicit plugin-scoped disposer the directory entry survives a plugin
172
- // reload, and the reloaded instance then mistakes the stale row for an
173
- // external owner and never takes the route back. Dispose through this
174
- // plugin's own lifecycle so reloads re-publish cleanly.
168
+ // DSH registerConfigurableProviders() has been caller-fiber-owned since the
169
+ // supported 0.1.5 floor. This effect owns only DVR's local generation state;
170
+ // do not double-own or double-dispose the Host registration handle.
175
171
  if (typeof ctx.effect === 'function') {
176
172
  try {
177
173
  ctx.effect(
178
174
  () => () => {
179
175
  disposed = true
180
- if (handle) {
181
- const current = handle
182
- handle = undefined
183
- ownedProvider = undefined
184
- heldKey = undefined
185
- try {
186
- current()
187
- } catch (error) {
188
- warn(
189
- 'vision-router: failed to dispose Models-directory alias:',
190
- error && error.message ? error.message : String(error),
191
- )
192
- }
193
- }
176
+ handle = undefined
177
+ ownedProvider = undefined
178
+ heldKey = undefined
194
179
  },
195
- 'vision-router: models-directory alias lifecycle',
180
+ 'vision-router: models-directory alias local state',
196
181
  )
197
182
  } catch {
198
- /* lifecycle wiring must not break alias sync */
183
+ disposed = true
184
+ return sync
199
185
  }
200
186
  }
187
+
188
+ // Establish the generation owner before publishing a directory alias or
189
+ // subscribing to events that could later republish it.
190
+ sync()
191
+ if (disposed) return sync
201
192
  if (typeof ctx.on === 'function') {
202
193
  ctx.on('llm/adapters-updated', sync)
203
194
  ctx.on('settings/updated', (ns) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-vision-router",
3
- "version": "2.3.0",
3
+ "version": "3.0.1",
4
4
  "description": "Eyes for text-only DeepSeek Harness agents: built-in free vision chain + pixel-level tools. Remote vision providers, including the default free fallback, receive image content unless strict local-only use is configured.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -14,7 +14,10 @@
14
14
  "dsh-vision-router": "./lib/doctor-cli-p0.js"
15
15
  },
16
16
  "exports": {
17
- ".": "./lib/public-entry.js",
17
+ ".": {
18
+ "types": "./lib/public-entry.d.ts",
19
+ "default": "./lib/public-entry.js"
20
+ },
18
21
  "./client": "./lib/client.js",
19
22
  "./package.json": "./package.json",
20
23
  "./cordis.patch.yml": "./cordis.patch.yml"
@@ -51,12 +54,14 @@
51
54
  "@deepseek-ai/schemastery": ">=3.18.0",
52
55
  "potrace": "^2.1.8",
53
56
  "puppeteer-core": "^25.6.0",
54
- "undici": "^7.29.0"
57
+ "undici": "^7.29.0",
58
+ "zod": "^4.4.3"
55
59
  },
56
60
  "peerDependencies": {
57
61
  "@deepseek-ai/dsh-anonymous-user-id": ">=0.1.5-rc.1 <0.2.0-0 || >=0.2.0-rc.2 <0.3.0-0",
58
62
  "@deepseek-ai/dsh-llm-deepseek": ">=0.1.5-rc.1 <0.2.0-0 || >=0.2.0-rc.2 <0.3.0-0",
59
- "sharp": ">=0.35.3 <1"
63
+ "sharp": ">=0.35.3 <1",
64
+ "@deepseek-ai/dsh-storage-domain": ">=0.1.5-rc.1 <0.2.0-0 || >=0.2.0-rc.2 <0.3.0-0"
60
65
  },
61
66
  "peerDependenciesMeta": {
62
67
  "@deepseek-ai/dsh-anonymous-user-id": {
@@ -67,19 +72,27 @@
67
72
  },
68
73
  "sharp": {
69
74
  "optional": true
75
+ },
76
+ "@deepseek-ai/dsh-storage-domain": {
77
+ "optional": true
70
78
  }
71
79
  },
72
80
  "devDependencies": {
73
81
  "@deepseek-ai/dsh-anonymous-user-id": "0.2.0-rc.2",
74
82
  "@deepseek-ai/dsh-llm-deepseek": "0.2.0-rc.2",
75
83
  "fast-check": "4.10.0",
76
- "sharp": "^0.35.4"
84
+ "sharp": "^0.35.4",
85
+ "typescript": "6.0.3",
86
+ "@deepseek-ai/dsh-attachment": "0.2.0-rc.2",
87
+ "@deepseek-ai/dsh-llm": "0.2.0-rc.2",
88
+ "@types/node": "22.20.0",
89
+ "@deepseek-ai/dsh-storage-domain": "0.2.0-rc.2"
77
90
  },
78
91
  "scripts": {
79
- "test": "node --test tests/index-modularization.test.js tests/adapter-prepare-call-compat.test.js tests/core.test.js tests/issue-374-delegated-call-config.test.js tests/grounding-coordinate-frame.test.js tests/grounding-coordinate-runtime.test.js tests/capability-advisory.test.js tests/vision-execution-policy.test.js tests/vision-backend-diagnostics.test.js tests/live-model-discovery.test.js tests/cache-atomic-write-concurrency.test.js tests/live-model-credential-resolution.test.js tests/vision-model-registry.test.js tests/live-model-client-stability.test.js tests/providers-persistence.test.js tests/provider-directory-fallback.test.js tests/model-catalog-policy.test.js tests/settings-ia-client-prelude.test.js tests/settings-ia-fj.test.js tests/settings-ia-acceptance-regression.test.js tests/settings-migration.test.js tests/settings-section-order.test.js tests/attachment-admission-policy.test.js tests/vision-resilience.test.js tests/degraded-local-evidence.test.js tests/vision-resilience-lifecycle.test.js tests/vision-breaker-readonly.test.js tests/alpha1-browser-lifecycle-integration.test.js tests/issue-367-remote-session-inject.test.js tests/vision-mode-toggle-injection.test.js tests/client.test.js tests/issue-307-regression.test.js tests/issue-284-vision-mode-toggle.test.js tests/issue-284-vision-mode-hardening.test.js tests/issue-284-attachment-id-hint.test.js tests/issue-284-model-visibility.test.js tests/issue-284-vision-selection-effort.test.js tests/client-presentation-boundary.test.js tests/clipboard-image-paste-compat.test.js tests/remote-settings-bridge.test.js tests/remote-settings-v2-contract.test.js tests/remote-settings-risk-confirmation.test.js tests/local-remote-settings-permission.test.js tests/artifact-path-security.test.js tests/http-compat.test.js tests/catalog-corrections.test.js tests/release-registry-identity.test.js tests/update-check.test.js tests/update-check-signal-lifecycle.test.js tests/self-update.test.js tests/doctor.test.js tests/doctor-cli.test.js tests/legacy-session-repair.test.js tests/profile-pnpm-diagnostics.test.js tests/doctor-v2.test.js tests/doctor-cli-v2.test.js tests/doctor-runtime.test.js tests/dsh-host-capabilities.test.js tests/doctor-host-capabilities.test.js tests/session-repair-v2.test.js tests/bundle-defaults.test.js tests/file-logger.test.js tests/official-deepseek-catalog.test.js tests/replay-delegation.test.js tests/twin-image-capability-fallback.test.js tests/twin-image-custom-wrapper.test.js tests/adversarial-hardening.test.js tests/vision-adversarial-hardening-v2.test.js tests/vision-capability-benchmark-visual-proof.test.js tests/wrapper-directory.test.js tests/logging-ui.test.js tests/manifest-dependencies.test.js tests/architecture-2.3-gate.test.js tests/esm-cycle-audit.test.js tests/structured-bootstrap.test.js tests/structured-bootstrap-gate.test.js tests/vision-model-guidance-contract.test.js tests/local-ollama.test.js tests/local-only-vision.test.js tests/ollama-cold-start.test.js tests/ollama-cold-start-loaded.test.js tests/zero-regression-gate.test.js tests/runtime-e2e.test.js tests/local-vision-stabilizer.test.js tests/local-connection-probe.test.js tests/vision-diagnostics-routes.test.js tests/repetition-guard.test.js tests/guide-scroll-gate.test.js tests/settings-scroll-jank-regression.test.js tests/free-cloud-first.test.js tests/dsh-host-compat.test.js tests/native-image-coexistence.test.js tests/issue-276-session-image-ownership.test.js tests/issue-276-entry-policy-bridge.test.js tests/issue-276-policy-hardening.test.js tests/issue-289-native-nonintervention.test.js tests/issue-512-tool-restriction.test.js tests/issue-606-session-source-ownership.test.js tests/pi-ai-bridge-wire-compat.test.js tests/fetch-wrapper-lifecycle.test.js tests/fetch-wrapper-composition.test.js tests/mixed-router.test.js tests/depth-tier.test.js tests/depth-quota-behavior.test.js tests/structured-flow-hardening.test.js tests/structured-flow-adversarial.test.js tests/vision-budget-activation.test.js tests/runtime-boundary-fixes.test.js tests/security-resource-boundaries.test.js tests/security-property-fuzz.test.js tests/security-adversarial-fuzz-contract.test.js tests/runtime-i18n.test.js tests/long-ocr-empty-retry.test.js tests/tesseract-adaptive-ocr.test.js tests/tesseract-node24-boot.test.js tests/session-vision-state.test.js tests/session-vision-state-integration.test.js tests/session-vision-event-feed.test.js tests/image-resource-governor.test.js tests/resource-retention-lifecycle.test.js tests/pixel-diff-stream.test.js tests/large-image-resource-integration.test.js tests/structured-guard-idempotency.test.js tests/vision-routing-product.test.js tests/vision-runtime-performance.test.js tests/vision-routing-settings-prelude.test.js tests/v2-settings-ia-integration.test.js tests/vision-capability-router.test.js tests/vision-capability-reference.test.js tests/vision-capability-benchmark.test.js tests/vision-capability-grounding-proof-contract.test.js tests/vision-capability-probe.test.js tests/vision-capability-axis-freshness.test.js tests/vision-capability-shadow-health.test.js tests/vision-capability-benchmark-service.test.js tests/vision-capability-preflight-hardening.test.js tests/vision-capability-benchmark-contract.test.js tests/vision-capability-benchmark-client.test.js tests/vision-capability-benchmark-client-productization.test.js tests/vision-capability-adapter-route.test.js tests/vision-background-benchmark.test.js tests/vision-background-lifecycle.test.js tests/vision-background-benchmark-productization.test.js tests/vision-capability-benchmark-budget.test.js tests/vision-image-input-verdict.test.js tests/vision-capability-failure-classification.test.js tests/vision-capability-gate-client.test.js tests/v2-product-review-fixes.test.js tests/qa-top5-reliability.test.js tests/qa-screenshot-runtime.test.js tests/qa-runtime-identity.test.js tests/qa-turn-budget-cancellation.test.js tests/qa-cancellation-publication.test.js tests/qa-reliability-tail.test.js tests/qa-endpoint-route-alias.test.js tests/settings-native-card-semantics.test.js tests/settings-native-card-lazy-data.test.js tests/settings-invalid-staged-dirty.test.js tests/vision-toggle-root-hardening.test.js && node --test tests/vision-backend-runtime-policy.test.js",
92
+ "test": "node --test tests/index-modularization.test.js tests/adapter-prepare-call-compat.test.js tests/core.test.js tests/issue-374-delegated-call-config.test.js tests/grounding-coordinate-frame.test.js tests/grounding-coordinate-runtime.test.js tests/capability-advisory.test.js tests/vision-execution-policy.test.js tests/vision-backend-diagnostics.test.js tests/live-model-discovery.test.js tests/cache-atomic-write-concurrency.test.js tests/live-model-credential-resolution.test.js tests/vision-model-registry.test.js tests/live-model-client-stability.test.js tests/providers-persistence.test.js tests/provider-directory-fallback.test.js tests/model-catalog-policy.test.js tests/settings-ia-client-prelude.test.js tests/settings-ia-fj.test.js tests/settings-ia-acceptance-regression.test.js tests/settings-migration.test.js tests/settings-section-order.test.js tests/attachment-admission-policy.test.js tests/vision-resilience.test.js tests/degraded-local-evidence.test.js tests/vision-resilience-lifecycle.test.js tests/vision-breaker-readonly.test.js tests/alpha1-browser-lifecycle-integration.test.js tests/issue-367-remote-session-inject.test.js tests/vision-mode-toggle-injection.test.js tests/client.test.js tests/issue-307-regression.test.js tests/issue-284-vision-mode-toggle.test.js tests/issue-284-vision-mode-hardening.test.js tests/issue-284-attachment-id-hint.test.js tests/issue-284-model-visibility.test.js tests/issue-284-vision-selection-effort.test.js tests/client-presentation-boundary.test.js tests/clipboard-image-paste-compat.test.js tests/remote-settings-bridge.test.js tests/remote-settings-v2-contract.test.js tests/remote-settings-risk-confirmation.test.js tests/local-remote-settings-permission.test.js tests/artifact-path-security.test.js tests/http-compat.test.js tests/catalog-corrections.test.js tests/release-registry-identity.test.js tests/update-check.test.js tests/update-check-signal-lifecycle.test.js tests/self-update.test.js tests/doctor.test.js tests/doctor-cli.test.js tests/legacy-session-repair.test.js tests/profile-pnpm-diagnostics.test.js tests/doctor-v2.test.js tests/doctor-cli-v2.test.js tests/doctor-runtime.test.js tests/dsh-host-capabilities.test.js tests/doctor-host-capabilities.test.js tests/session-repair-v2.test.js tests/activation-shim-contract.test.js tests/bundle-defaults.test.js tests/file-logger.test.js tests/official-deepseek-catalog.test.js tests/replay-delegation.test.js tests/twin-image-capability-fallback.test.js tests/twin-image-custom-wrapper.test.js tests/adversarial-hardening.test.js tests/vision-adversarial-hardening-v2.test.js tests/vision-capability-benchmark-visual-proof.test.js tests/wrapper-directory.test.js tests/logging-ui.test.js tests/manifest-dependencies.test.js tests/architecture-2.3-gate.test.js tests/host-settings-seam.test.js tests/drift-canary-settings-seam.test.js tests/esm-cycle-audit.test.js tests/structured-bootstrap.test.js tests/structured-bootstrap-gate.test.js tests/vision-model-guidance-contract.test.js tests/local-ollama.test.js tests/local-only-vision.test.js tests/ollama-cold-start.test.js tests/ollama-cold-start-loaded.test.js tests/zero-regression-gate.test.js tests/runtime-e2e.test.js tests/local-vision-stabilizer.test.js tests/local-connection-probe.test.js tests/vision-diagnostics-routes.test.js tests/repetition-guard.test.js tests/guide-scroll-gate.test.js tests/settings-scroll-jank-regression.test.js tests/free-cloud-first.test.js tests/dsh-host-compat.test.js tests/native-image-coexistence.test.js tests/issue-276-session-image-ownership.test.js tests/issue-276-entry-policy-bridge.test.js tests/issue-276-policy-hardening.test.js tests/issue-289-native-nonintervention.test.js tests/issue-512-tool-restriction.test.js tests/issue-606-session-source-ownership.test.js tests/pi-ai-bridge-wire-compat.test.js tests/fetch-wrapper-lifecycle.test.js tests/fetch-wrapper-composition.test.js tests/provider-probe-proxy-scope.test.js tests/lifecycle-invariants.test.js tests/vision-tool-settings-generation.test.js tests/release-package-content-identity.test.js tests/release-state-machine.test.js tests/mixed-router.test.js tests/depth-tier.test.js tests/depth-quota-behavior.test.js tests/structured-flow-hardening.test.js tests/structured-flow-adversarial.test.js tests/vision-budget-activation.test.js tests/runtime-boundary-fixes.test.js tests/security-resource-boundaries.test.js tests/security-property-fuzz.test.js tests/security-adversarial-fuzz-contract.test.js tests/runtime-i18n.test.js tests/long-ocr-empty-retry.test.js tests/tesseract-adaptive-ocr.test.js tests/tesseract-node24-boot.test.js tests/session-vision-state.test.js tests/session-vision-state-integration.test.js tests/session-vision-event-feed.test.js tests/session-vision-policy.test.js tests/session-vision-policy-domain.test.js tests/session-vision-delegation.test.js tests/session-vision-delegation-boundary.test.js tests/subagent-vision-inheritance-characterization.test.js tests/subagent-vision-runtime-integration.test.js tests/subagent-vision-cold-resume.test.js tests/image-resource-governor.test.js tests/resource-retention-lifecycle.test.js tests/pixel-diff-stream.test.js tests/large-image-resource-integration.test.js tests/structured-guard-idempotency.test.js tests/vision-routing-product.test.js tests/vision-runtime-performance.test.js tests/vision-routing-settings-prelude.test.js tests/v2-settings-ia-integration.test.js tests/vision-capability-router.test.js tests/vision-capability-reference.test.js tests/vision-capability-benchmark.test.js tests/vision-capability-grounding-proof-contract.test.js tests/vision-capability-probe.test.js tests/vision-capability-axis-freshness.test.js tests/vision-capability-shadow-health.test.js tests/vision-capability-benchmark-service.test.js tests/vision-capability-preflight-hardening.test.js tests/vision-capability-benchmark-contract.test.js tests/vision-capability-benchmark-client.test.js tests/vision-capability-benchmark-client-productization.test.js tests/vision-capability-adapter-route.test.js tests/vision-background-benchmark.test.js tests/vision-background-lifecycle.test.js tests/vision-background-benchmark-productization.test.js tests/vision-capability-benchmark-budget.test.js tests/vision-image-input-verdict.test.js tests/vision-capability-failure-classification.test.js tests/vision-capability-gate-client.test.js tests/v2-product-review-fixes.test.js tests/qa-top5-reliability.test.js tests/qa-screenshot-runtime.test.js tests/qa-runtime-identity.test.js tests/qa-turn-budget-cancellation.test.js tests/qa-cancellation-publication.test.js tests/qa-reliability-tail.test.js tests/qa-endpoint-route-alias.test.js tests/settings-native-card-semantics.test.js tests/settings-native-card-lazy-data.test.js tests/settings-invalid-staged-dirty.test.js tests/vision-toggle-root-hardening.test.js && pnpm test:regression-closure && node --test tests/vision-backend-runtime-policy.test.js",
80
93
  "test:core": "node --test tests/core.test.js tests/degraded-local-evidence.test.js tests/runtime-e2e.test.js tests/structured-bootstrap.test.js tests/structured-flow-hardening.test.js tests/structured-flow-adversarial.test.js tests/vision-execution-policy.test.js tests/vision-backend-runtime-policy.test.js",
81
94
  "test:routing": "node --test tests/issue-374-delegated-call-config.test.js tests/twin-image-capability-fallback.test.js tests/twin-image-custom-wrapper.test.js tests/vision-routing-product.test.js tests/vision-capability-router.test.js tests/vision-capability-probe.test.js tests/vision-capability-shadow-health.test.js tests/vision-runtime-performance.test.js tests/vision-background-benchmark.test.js tests/vision-image-input-verdict.test.js",
82
- "test:session": "node --test tests/session-vision-state.test.js tests/session-vision-state-integration.test.js tests/replay-delegation.test.js tests/legacy-session-repair.test.js tests/session-repair-v2.test.js tests/issue-276-session-image-ownership.test.js",
95
+ "test:session": "node --test tests/session-vision-state.test.js tests/session-vision-state-integration.test.js tests/session-vision-policy.test.js tests/session-vision-delegation.test.js tests/session-vision-delegation-boundary.test.js tests/subagent-vision-inheritance-characterization.test.js tests/subagent-vision-runtime-integration.test.js tests/subagent-vision-cold-resume.test.js tests/session-vision-policy-domain.test.js tests/replay-delegation.test.js tests/legacy-session-repair.test.js tests/session-repair-v2.test.js tests/issue-276-session-image-ownership.test.js",
83
96
  "test:resources": "node --test tests/artifact-path-security.test.js tests/image-resource-governor.test.js tests/resource-retention-lifecycle.test.js tests/pixel-diff-stream.test.js tests/large-image-resource-integration.test.js tests/qa-turn-budget-cancellation.test.js tests/qa-cancellation-publication.test.js",
84
97
  "test:compat": "node --test tests/adapter-prepare-call-compat.test.js tests/attachment-admission-policy.test.js tests/dsh-host-compat.test.js tests/http-compat.test.js tests/pi-ai-bridge-wire-compat.test.js tests/fetch-wrapper-lifecycle.test.js tests/fetch-wrapper-composition.test.js tests/native-image-coexistence.test.js tests/tesseract-node24-boot.test.js tests/dsh-host-capabilities.test.js",
85
98
  "test:web": "node --test tests/alpha1-browser-lifecycle-integration.test.js tests/issue-367-remote-session-inject.test.js tests/vision-mode-toggle-injection.test.js tests/client.test.js tests/client-presentation-boundary.test.js tests/clipboard-image-paste-compat.test.js tests/settings-ia-client-prelude.test.js tests/settings-ia-acceptance-regression.test.js tests/remote-settings-bridge.test.js tests/remote-settings-v2-contract.test.js tests/local-remote-settings-permission.test.js tests/v2-settings-ia-integration.test.js tests/logging-ui.test.js",
@@ -93,8 +106,21 @@
93
106
  "quality:round2:template": "node quality/vision-round2/make-run-template.mjs",
94
107
  "quality:round2:run": "node quality/vision-round2/run-host-api.mjs",
95
108
  "quality:round2:report": "node quality/vision-round2/report-results.mjs",
96
- "client:sync": "node scripts/sync-client-embedded-modules.mjs",
97
- "client:check": "node scripts/sync-client-embedded-modules.mjs --check"
109
+ "client:sync": "node scripts/sync-client-embedded-modules.mjs && pnpm build",
110
+ "client:check": "node scripts/sync-client-embedded-modules.mjs --check && pnpm build:check",
111
+ "build": "node scripts/build-source-artifacts.mjs",
112
+ "build:check": "node scripts/build-source-artifacts.mjs --check",
113
+ "pretest": "pnpm build",
114
+ "build:reproducible": "node scripts/verify-build-reproducibility.mjs",
115
+ "typecheck:host": "tsc -p tsconfig.host.json",
116
+ "typecheck:client": "tsc -p tsconfig.client.json",
117
+ "typecheck:declaration": "tsc -p tsconfig.declaration.json",
118
+ "typecheck": "pnpm typecheck:host && pnpm typecheck:client && pnpm typecheck:declaration",
119
+ "prepare": "pnpm build",
120
+ "prepack": "pnpm build",
121
+ "lint": "node scripts/lint-source-ownership.mjs && node scripts/lint-lifecycle-invariants.mjs",
122
+ "source:artifact:check": "node scripts/verify-source-artifact-map.mjs",
123
+ "test:regression-closure": "node --test tests/auto-wrap-model-removal.test.js tests/guard-stop-surface-shadow.test.js tests/release-package-content-identity.test.js tests/settings-card-race-safety.test.js tests/settings-guide-replay-safety.test.js tests/settings-ia-targeted-adversarial.test.js tests/v2-release-acceptance-regressions.test.js tests/vision-turn-budget-client-prelude.test.js tests/wrapper-scope-client-prelude.test.js"
98
124
  },
99
125
  "dsh": {
100
126
  "client": {
@@ -102,7 +128,6 @@
102
128
  "inject": [
103
129
  "@deepseek-ai/dsh-client-ui-settings",
104
130
  "@deepseek-ai/dsh-client-ui-primitives",
105
- "@deepseek-ai/dsh-client-runtime",
106
131
  "@deepseek-ai/dsh-client-connection",
107
132
  "@deepseek-ai/dsh-api-remotes"
108
133
  ]
@@ -110,5 +135,6 @@
110
135
  "bundle": {
111
136
  "patch": "./cordis.patch.yml"
112
137
  }
113
- }
138
+ },
139
+ "types": "lib/public-entry.d.ts"
114
140
  }