dsh-codex-subscription 2.1.2 → 2.1.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.
package/lib/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { createRequire } from "node:module";
1
2
  import { createHash, randomBytes, randomUUID } from "node:crypto";
2
3
  import { closeOpenAICodexWebSocketSessions, resetOpenAICodexWebSocketDebugStats } from "@earendil-works/pi-ai/api/openai-codex-responses";
3
4
  import { execFile, spawn } from "node:child_process";
@@ -9,6 +10,9 @@ import { HttpsProxyAgent } from "https-proxy-agent";
9
10
  import WebSocket from "ws";
10
11
  import { clientRequestSchema } from "@deepseek-ai/dsh-client-connection";
11
12
  import { lstat, mkdir, open, readFile, rename, rm, stat } from "node:fs/promises";
13
+ import { constants, readFileSync } from "node:fs";
14
+ import { dirname, join, resolve } from "node:path";
15
+ import { pathToFileURL } from "node:url";
12
16
  import { defineTool } from "@deepseek-ai/dsh-tools";
13
17
  import * as dshCredentials from "@deepseek-ai/dsh-credentials";
14
18
  import { dshHomePath, resolveDshHome } from "@deepseek-ai/dsh-home-paths";
@@ -18,8 +22,6 @@ import z from "@deepseek-ai/schemastery";
18
22
  import { openaiCodexProvider as createOpenAICodexProvider } from "@earendil-works/pi-ai/providers/openai-codex";
19
23
  import { createModels } from "@earendil-works/pi-ai";
20
24
  import { WebError } from "@deepseek-ai/dsh-web";
21
- import { constants } from "node:fs";
22
- import { dirname, join, resolve } from "node:path";
23
25
  //#region src/image-models.js
24
26
  const DEFAULT_IMAGE_MODEL = "gpt-image-2";
25
27
  const IMAGE_MODELS = Object.freeze({
@@ -875,6 +877,10 @@ const RPC_ENDPOINTS = Object.freeze([
875
877
  "preferences/status",
876
878
  "preferences/models",
877
879
  "preferences/update",
880
+ "runtime/status",
881
+ "runtime/install",
882
+ "runtime/remove",
883
+ "runtime/cancel",
878
884
  "reset-credit/inspect",
879
885
  "reset-credit/prepare",
880
886
  "reset-credit/consume",
@@ -1048,6 +1054,45 @@ function authenticatedSubagentChild(child, { Transport, getTokens, thread, signa
1048
1054
  } });
1049
1055
  }
1050
1056
  //#endregion
1057
+ //#region src/subagent-runtime.js
1058
+ const SUBAGENT_RUNTIME_PACKAGE = "@deepseek-ai/dsh-subagent-codex";
1059
+ const SUBAGENT_RUNTIME_VERSION = "0.1.5-rc.2";
1060
+ const require = createRequire(import.meta.url);
1061
+ const execute = promisify(execFile);
1062
+ function inspectSubagentRuntime(resolve = require.resolve) {
1063
+ try {
1064
+ const manifestPath = resolve(`${SUBAGENT_RUNTIME_PACKAGE}/package.json`);
1065
+ if (JSON.parse(readFileSync(manifestPath, "utf8")).version !== "0.1.5-rc.2") return { installed: false };
1066
+ return { installed: true };
1067
+ } catch {
1068
+ return { installed: false };
1069
+ }
1070
+ }
1071
+ async function loadSubagentRuntime({ resolve: resolve$1 = require.resolve, run = execute, importModule = (url) => import(url) } = {}) {
1072
+ if (!inspectSubagentRuntime(resolve$1).installed) throw new Error("Codex subtask runtime is not prepared");
1073
+ const entry = resolve$1(SUBAGENT_RUNTIME_PACKAGE);
1074
+ const providerRequire = createRequire(entry);
1075
+ const codexManifestPath = providerRequire.resolve("@openai/codex/package.json");
1076
+ const codex = JSON.parse(readFileSync(codexManifestPath, "utf8"));
1077
+ if (codex.version !== "0.153.4" || typeof codex.bin?.codex !== "string") throw new Error("Codex subtask runtime version is unsupported");
1078
+ const wrapper = resolve(dirname(codexManifestPath), codex.bin.codex);
1079
+ try {
1080
+ const { stdout } = await run(process.execPath, [wrapper, "--version"], {
1081
+ timeout: 1e4,
1082
+ maxBuffer: 4096,
1083
+ windowsHide: true
1084
+ });
1085
+ if (stdout.trim() !== "codex-cli 0.153.4") throw new Error("Unexpected CLI version");
1086
+ } catch {
1087
+ throw new Error("Codex subtask runtime is incomplete; prepare it for this platform");
1088
+ }
1089
+ const [official, { JsonRpcLineTransport: Transport }] = await Promise.all([importModule(pathToFileURL(entry).href), importModule(pathToFileURL(providerRequire.resolve("@deepseek-ai/dsh-sdk-protocol")).href)]);
1090
+ return {
1091
+ official,
1092
+ Transport
1093
+ };
1094
+ }
1095
+ //#endregion
1051
1096
  //#region src/subagent-backend.js
1052
1097
  const SUBAGENT_PROVIDER = "codex-subscription-subagent";
1053
1098
  const MODES = /* @__PURE__ */ new Set([
@@ -1086,7 +1131,7 @@ function subagentThreadPolicy(parent, policy, requested = {}) {
1086
1131
  };
1087
1132
  }
1088
1133
  /** Reuse the official DSH process/turn provider; keep only subscription auth here. */
1089
- function createSubscriptionSubagent({ ctx, nativeHome, resolveAuth, store, refresh, loadRuntime }) {
1134
+ function createSubscriptionSubagent({ ctx, nativeHome, resolveAuth, store, refresh, loadRuntime, maintenance = () => false }) {
1090
1135
  let runtime;
1091
1136
  const load = () => runtime ??= loadRuntime().catch((error) => {
1092
1137
  runtime = void 0;
@@ -1107,6 +1152,7 @@ function createSubscriptionSubagent({ ctx, nativeHome, resolveAuth, store, refre
1107
1152
  inheritsParentContext: false,
1108
1153
  async start(request) {
1109
1154
  if (disposed) throw new Error("Codex subagent is unavailable");
1155
+ if (maintenance()) throw new Error("Codex subtask component is being changed; restart DSH after completion");
1110
1156
  const controller = new AbortController();
1111
1157
  active.add(controller);
1112
1158
  const signal = AbortSignal.any([request.signal, controller.signal]);
@@ -1178,7 +1224,11 @@ function createSubscriptionSubagent({ ctx, nativeHome, resolveAuth, store, refre
1178
1224
  }
1179
1225
  }
1180
1226
  },
1181
- prepare: load,
1227
+ activeCount: () => active.size,
1228
+ prepare: () => {
1229
+ if (maintenance()) return Promise.reject(/* @__PURE__ */ new Error("Restart DSH after changing the Codex subtask component"));
1230
+ return load();
1231
+ },
1182
1232
  dispose() {
1183
1233
  disposed = true;
1184
1234
  for (const controller of active) controller.abort();
@@ -1252,11 +1302,104 @@ function createSubagentBackendSwitcher({ entries, prepare, persist }) {
1252
1302
  }
1253
1303
  };
1254
1304
  }
1255
- async function loadSubagentRuntime() {
1256
- const [official, { JsonRpcLineTransport: Transport }] = await Promise.all([import("@deepseek-ai/dsh-subagent-codex"), import("@deepseek-ai/dsh-sdk-protocol")]);
1305
+ //#endregion
1306
+ //#region src/runtime-management.js
1307
+ function createRuntimeManagement({ manager, inspect, active, selectDsh }) {
1308
+ let operation;
1309
+ let state = {
1310
+ phase: "idle",
1311
+ restartRequired: false
1312
+ };
1313
+ const supported = (value) => [
1314
+ "listBundles",
1315
+ "installBundle",
1316
+ "removeBundle",
1317
+ "cancelInstall"
1318
+ ].every((key) => typeof value?.[key] === "function");
1319
+ const status = async () => {
1320
+ const host = manager();
1321
+ let bundle;
1322
+ let available = supported(host);
1323
+ try {
1324
+ if (available) bundle = (await host.listBundles()).find((value) => value.name === SUBAGENT_RUNTIME_PACKAGE);
1325
+ } catch {
1326
+ available = false;
1327
+ }
1328
+ return {
1329
+ ...state,
1330
+ available,
1331
+ installed: inspect().installed,
1332
+ removable: available && bundle?.installed === true && !bundle.readOnlyReason,
1333
+ active: active()
1334
+ };
1335
+ };
1336
+ const start = async (action) => {
1337
+ if (!["install", "remove"].includes(action)) throw Error("invalid-action");
1338
+ if (operation) throw Error("busy");
1339
+ if (state.restartRequired) throw Error("restart-required");
1340
+ if (active() > 0) throw Error("active-tasks");
1341
+ const host = manager();
1342
+ if (!supported(host)) throw Error("unavailable");
1343
+ const requestId = randomUUID();
1344
+ const current = {
1345
+ action,
1346
+ requestId,
1347
+ host
1348
+ };
1349
+ operation = current;
1350
+ state = {
1351
+ phase: action === "install" ? "installing" : "removing",
1352
+ restartRequired: false
1353
+ };
1354
+ current.done = (async () => {
1355
+ try {
1356
+ if (action === "remove") {
1357
+ const bundle = (await host.listBundles()).find((value) => value.name === SUBAGENT_RUNTIME_PACKAGE);
1358
+ if (!bundle?.installed || bundle.readOnlyReason) throw Error("not-removable");
1359
+ await selectDsh();
1360
+ }
1361
+ const result = action === "install" ? await host.installBundle(`${SUBAGENT_RUNTIME_PACKAGE}@${SUBAGENT_RUNTIME_VERSION}`, {
1362
+ enabled: false,
1363
+ requestId
1364
+ }) : await host.removeBundle(SUBAGENT_RUNTIME_PACKAGE);
1365
+ if (result.application === "cancelled") state = {
1366
+ phase: "cancelled",
1367
+ restartRequired: false
1368
+ };
1369
+ else if (["applied", "restart-required"].includes(result.application)) state = {
1370
+ phase: "done",
1371
+ restartRequired: true
1372
+ };
1373
+ else state = {
1374
+ phase: "failed",
1375
+ restartRequired: false,
1376
+ error: result.packageResult?.kind ?? result.error?.code ?? "operation-error"
1377
+ };
1378
+ } catch (error) {
1379
+ state = {
1380
+ phase: "failed",
1381
+ restartRequired: false,
1382
+ error: error.message === "not-removable" ? "not-removable" : "operation-error"
1383
+ };
1384
+ } finally {
1385
+ operation = void 0;
1386
+ }
1387
+ })();
1388
+ return status();
1389
+ };
1257
1390
  return {
1258
- official,
1259
- Transport
1391
+ status,
1392
+ start,
1393
+ blocked: () => operation !== void 0 || state.restartRequired,
1394
+ progress(value) {
1395
+ if (operation?.action === "install" && value.requestId === operation.requestId && value.phase === "applying") state.phase = "applying";
1396
+ },
1397
+ async cancel() {
1398
+ const current = operation;
1399
+ if (current?.action !== "install") return status();
1400
+ if ((await current.host.cancelInstall(current.requestId)).status === "cancelled") await current.done;
1401
+ return status();
1402
+ }
1260
1403
  };
1261
1404
  }
1262
1405
  //#endregion
@@ -2644,7 +2787,7 @@ function openaiCodexSubscriptionProvider({ resolveSpeedMode = () => void 0, reso
2644
2787
  Object.freeze(["0.82.1", "0.85.1"]);
2645
2788
  //#endregion
2646
2789
  //#region src/version.js
2647
- const PACKAGE_VERSION = "2.1.2";
2790
+ const PACKAGE_VERSION = "2.1.3";
2648
2791
  const USER_AGENT = `dsh-codex-subscription/${PACKAGE_VERSION}`;
2649
2792
  //#endregion
2650
2793
  //#region src/model-catalog.js
@@ -2689,7 +2832,8 @@ function unsupportedCapabilities(value) {
2689
2832
  function visibleModel(value) {
2690
2833
  if (!record$4(value)) return void 0;
2691
2834
  const id = nonEmpty$2(value.slug);
2692
- if (id === void 0 || value.visibility !== "list") return void 0;
2835
+ const reserve = id === "gpt-reserve" && ["list", "hide"].includes(value.visibility);
2836
+ if (id === void 0 || value.visibility !== "list" && !reserve) return void 0;
2693
2837
  const supported = Array.isArray(value.supported_reasoning_levels) ? value.supported_reasoning_levels : [];
2694
2838
  const input = Array.isArray(value.input_modalities) ? value.input_modalities.filter((item) => ["text", "image"].includes(item)) : ["text", "image"];
2695
2839
  const unsupported = unsupportedCapabilities({
@@ -2699,7 +2843,7 @@ function visibleModel(value) {
2699
2843
  return {
2700
2844
  ...Object.keys(unsupported).length ? { unsupported } : {},
2701
2845
  id,
2702
- name: nonEmpty$2(value.display_name) ?? id,
2846
+ name: reserve ? "GPT-Reserve (Experimental)" : nonEmpty$2(value.display_name) ?? id,
2703
2847
  description: nonEmpty$2(value.description),
2704
2848
  priority: Number.isFinite(value.priority) ? value.priority : 0,
2705
2849
  input: input.length > 0 ? input : ["text"],
@@ -2719,7 +2863,7 @@ function visibleModel(value) {
2719
2863
  function parseOfficialModelCatalog(value) {
2720
2864
  if (!record$4(value) || !Array.isArray(value.models)) throw new Error("Codex returned a malformed model catalog");
2721
2865
  const seen = /* @__PURE__ */ new Set();
2722
- return value.models.map(visibleModel).filter((model) => model !== void 0 && !seen.has(model.id) && seen.add(model.id)).sort((left, right) => right.priority - left.priority);
2866
+ return value.models.map(visibleModel).filter((model) => model !== void 0 && !seen.has(model.id) && seen.add(model.id)).sort((left, right) => Number(left.id === "gpt-reserve") - Number(right.id === "gpt-reserve") || right.priority - left.priority);
2723
2867
  }
2724
2868
  function mergeModel(baseModels, remote) {
2725
2869
  const base = baseModels.find((model) => model.id === remote.id) ?? baseModels.find((model) => model.id !== "gpt-5.3-codex-spark") ?? baseModels[0];
@@ -2838,7 +2982,7 @@ function createOfficialModelCatalog(options = {}) {
2838
2982
  };
2839
2983
  return Object.freeze({
2840
2984
  refresh,
2841
- getModels: (fallback) => models ?? fallback,
2985
+ getModels: (fallback) => models ?? fallback.filter((model) => model.id !== "gpt-5.3-codex-spark"),
2842
2986
  metadata: (modelId) => metadata.get(modelId),
2843
2987
  revision: () => revision,
2844
2988
  capabilityGaps: () => [...metadata.values()].filter((model) => model.unsupported && /^[a-z][a-z0-9._-]{0,79}$/u.test(model.id)).slice(0, 20).map((model) => ({
@@ -4693,8 +4837,31 @@ const publicError = (code, message) => ({
4693
4837
  details: { issues: [] }
4694
4838
  }
4695
4839
  });
4696
- function createSubscriptionRpcHandler({ authHandler, usageReader, resetCreditService, preferences, diagnosticsReader, modelCatalog, originalImages, resolveInheritedOriginal }) {
4840
+ function createSubscriptionRpcHandler({ authHandler, usageReader, resetCreditService, preferences, runtimeManagement, diagnosticsReader, modelCatalog, originalImages, resolveInheritedOriginal, closeConnections }) {
4697
4841
  return async (endpoint, payload, signal) => {
4842
+ if ([
4843
+ "runtime/status",
4844
+ "runtime/install",
4845
+ "runtime/remove",
4846
+ "runtime/cancel"
4847
+ ].includes(endpoint)) try {
4848
+ signal.throwIfAborted();
4849
+ if (!runtimeManagement) return publicError("unavailable", "Runtime management is unavailable");
4850
+ const action = endpoint.split("/")[1];
4851
+ return {
4852
+ ok: true,
4853
+ value: action === "status" ? await runtimeManagement.status() : action === "cancel" ? await runtimeManagement.cancel() : await runtimeManagement.start(action)
4854
+ };
4855
+ } catch (error) {
4856
+ if (signal.aborted) throw error;
4857
+ const code = [
4858
+ "busy",
4859
+ "active-tasks",
4860
+ "restart-required",
4861
+ "unavailable"
4862
+ ].includes(error.message) ? error.message : "operation-error";
4863
+ return publicError(code, code);
4864
+ }
4698
4865
  if (endpoint === "image/original/chunk") try {
4699
4866
  signal.throwIfAborted();
4700
4867
  if (typeof payload?.sessionId !== "string" || payload.sessionId.length === 0 || payload.sessionId.length > 512 || typeof payload?.assetId !== "string" || !ORIGINAL_IMAGE_ID_PATTERN.test(payload.assetId) || !Number.isSafeInteger(payload?.offset) || payload.offset < 0 || payload.offset % 4194304 !== 0) return publicError("invalid-input", "Invalid original image request");
@@ -4813,6 +4980,11 @@ function createSubscriptionRpcHandler({ authHandler, usageReader, resetCreditSer
4813
4980
  return publicError("internal", message);
4814
4981
  }
4815
4982
  const result = await authHandler(endpoint, payload, signal);
4983
+ if (result.ok === true && [
4984
+ "logout",
4985
+ "account/select",
4986
+ "account/remove"
4987
+ ].includes(endpoint)) closeConnections?.();
4816
4988
  if (endpoint === "account/remove" && result.ok === true && typeof payload?.id === "string") await usageReader.clearScope(payload.id);
4817
4989
  if (endpoint === "logout" && result.ok === true) {
4818
4990
  await usageReader.clear();
@@ -4910,6 +5082,16 @@ function apply(ctx) {
4910
5082
  const baseProvider = createOpenAICodexProvider();
4911
5083
  let resolveAuth = async () => void 0;
4912
5084
  let subagentBackend;
5085
+ const runtimeManagement = createRuntimeManagement({
5086
+ manager: () => ctx.get?.("pluginManager"),
5087
+ inspect: inspectSubagentRuntime,
5088
+ active: () => subagentBackend?.activeCount() ?? 0,
5089
+ selectDsh: async () => {
5090
+ if (subagentBackend) await subagentBackend.select("dsh");
5091
+ else await settings.update({ subagentBackend: "dsh" });
5092
+ }
5093
+ });
5094
+ ctx.effect(() => ctx.on?.("plugin-manager/install-state", (value) => runtimeManagement.progress(value)));
4913
5095
  const modelCatalog = createOfficialModelCatalog({
4914
5096
  getAuth: (options) => resolveAuth(options),
4915
5097
  readCredential: (options) => store.read(PROVIDER, options),
@@ -4948,6 +5130,7 @@ function apply(ctx) {
4948
5130
  connectionMode: settings.get().connectionMode ?? "sse",
4949
5131
  subagentBackend: settings.get().subagentBackend ?? "dsh",
4950
5132
  subagentBackendAvailable: subagentBackend !== void 0,
5133
+ subagentRuntimeInstalled: inspectSubagentRuntime().installed,
4951
5134
  ...readCapabilitySettings(settings.get()),
4952
5135
  [QUICK_QUOTA_MODE_FIELD]: normalizeQuickQuotaMode(settings.get()[QUICK_QUOTA_MODE_FIELD], settings.get()[LEGACY_QUICK_QUOTA_FIELD]),
4953
5136
  [SEARCH_PROVIDER_FIELD]: settings.get()[SEARCH_PROVIDER_FIELD],
@@ -5014,7 +5197,8 @@ function apply(ctx) {
5014
5197
  resolveAuth,
5015
5198
  store,
5016
5199
  refresh: (credential) => network.run("oauth", () => baseProvider.auth.oauth.refresh(credential)),
5017
- loadRuntime: loadSubagentRuntime
5200
+ loadRuntime: loadSubagentRuntime,
5201
+ maintenance: runtimeManagement.blocked
5018
5202
  });
5019
5203
  scoped.subagents.registerProvider(instance.provider);
5020
5204
  const switcher = createSubagentBackendSwitcher({
@@ -5035,7 +5219,10 @@ function apply(ctx) {
5035
5219
  throw error;
5036
5220
  }
5037
5221
  };
5038
- subagentBackend = { select };
5222
+ subagentBackend = {
5223
+ select,
5224
+ activeCount: instance.activeCount
5225
+ };
5039
5226
  const sync = (value) => {
5040
5227
  const mode = value.subagentBackend ?? "dsh";
5041
5228
  if (mode !== requested) select(mode).catch(() => scoped.logger.warn("Could not switch the subscription subagent backend"));
@@ -5180,6 +5367,7 @@ function apply(ctx) {
5180
5367
  usageReader,
5181
5368
  resetCreditService,
5182
5369
  preferences,
5370
+ runtimeManagement,
5183
5371
  diagnosticsReader: () => createSubscriptionDiagnostics({
5184
5372
  auth,
5185
5373
  preferences,
@@ -5188,6 +5376,7 @@ function apply(ctx) {
5188
5376
  modelCatalog
5189
5377
  }),
5190
5378
  modelCatalog,
5379
+ closeConnections: () => connection.dispose(),
5191
5380
  originalImages,
5192
5381
  resolveInheritedOriginal: (sessionId, assetId) => inheritedOriginalImageRef(ctx.get?.("sessions")?.get?.(sessionId), assetId)
5193
5382
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-codex-subscription",
3
- "version": "2.1.2",
3
+ "version": "2.1.3",
4
4
  "description": "Use ChatGPT and Codex subscriptions in DeepSeek Harness with OAuth, quota, safe resets, web search, images, and Fast mode",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -74,45 +74,46 @@
74
74
  },
75
75
  "peerDependencies": {
76
76
  "@deepseek-ai/cordis": "4.0.1 || 4.0.2",
77
- "@deepseek-ai/dsh-api-remotes": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
78
- "@deepseek-ai/dsh-client-connection": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
79
- "@deepseek-ai/dsh-client-locale": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
80
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
81
- "@deepseek-ai/dsh-client-ui-model-selection": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
82
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
83
- "@deepseek-ai/dsh-client-ui-settings": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
84
- "@deepseek-ai/dsh-client-ui-slots": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
85
- "@deepseek-ai/dsh-client-ui-tool": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
86
- "@deepseek-ai/dsh-credentials": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
87
- "@deepseek-ai/dsh-llm": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
88
- "@deepseek-ai/dsh-llm-pi-ai": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
89
- "@deepseek-ai/dsh-settings": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
90
- "@deepseek-ai/dsh-tools": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
91
- "@deepseek-ai/dsh-web": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.6-alpha.1",
77
+ "@deepseek-ai/dsh-api-remotes": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
78
+ "@deepseek-ai/dsh-client-connection": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
79
+ "@deepseek-ai/dsh-client-locale": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
80
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
81
+ "@deepseek-ai/dsh-client-ui-model-selection": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
82
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
83
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
84
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
85
+ "@deepseek-ai/dsh-client-ui-tool": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
86
+ "@deepseek-ai/dsh-credentials": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
87
+ "@deepseek-ai/dsh-llm": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
88
+ "@deepseek-ai/dsh-llm-pi-ai": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
89
+ "@deepseek-ai/dsh-settings": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
90
+ "@deepseek-ai/dsh-tools": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
91
+ "@deepseek-ai/dsh-web": "0.1.2-rc.1 || 0.1.5-alpha.1 || 0.1.5-alpha.2 || 0.1.5-rc.1 || 0.1.5-rc.2 || 0.1.6-alpha.1 || 0.1.6-alpha.2",
92
92
  "@deepseek-ai/schemastery": "3.18.1 || ^3.18.2",
93
93
  "@earendil-works/pi-ai": "0.82.1 || 0.85.1",
94
94
  "react": "^18.2.0",
95
- "react-dom": "^18.2.0"
95
+ "react-dom": "^18.2.0",
96
+ "@deepseek-ai/dsh-subagent-codex": "0.1.5-rc.2"
96
97
  },
97
98
  "devDependencies": {
98
99
  "@deepseek-ai/cordis": "4.0.2",
99
- "@deepseek-ai/dsh-api-remotes": "0.1.5-rc.1",
100
- "@deepseek-ai/dsh-client-connection": "0.1.5-rc.1",
101
- "@deepseek-ai/dsh-client-locale": "0.1.5-rc.1",
102
- "@deepseek-ai/dsh-client-ui-conversation": "0.1.5-rc.1",
103
- "@deepseek-ai/dsh-client-ui-model-selection": "0.1.5-rc.1",
104
- "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.1",
105
- "@deepseek-ai/dsh-client-ui-settings": "0.1.5-rc.1",
106
- "@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.1",
107
- "@deepseek-ai/dsh-client-ui-tool": "0.1.5-rc.1",
108
- "@deepseek-ai/dsh-credentials": "0.1.5-rc.1",
109
- "@deepseek-ai/dsh-invariants": "0.1.5-rc.1",
110
- "@deepseek-ai/dsh-llm": "0.1.5-rc.1",
111
- "@deepseek-ai/dsh-llm-pi-ai": "0.1.5-rc.1",
112
- "@deepseek-ai/dsh-session": "0.1.5-rc.1",
113
- "@deepseek-ai/dsh-settings": "0.1.5-rc.1",
114
- "@deepseek-ai/dsh-tools": "0.1.5-rc.1",
115
- "@deepseek-ai/dsh-web": "0.1.5-rc.1",
100
+ "@deepseek-ai/dsh-api-remotes": "0.1.5-rc.2",
101
+ "@deepseek-ai/dsh-client-connection": "0.1.5-rc.2",
102
+ "@deepseek-ai/dsh-client-locale": "0.1.5-rc.2",
103
+ "@deepseek-ai/dsh-client-ui-conversation": "0.1.5-rc.2",
104
+ "@deepseek-ai/dsh-client-ui-model-selection": "0.1.5-rc.2",
105
+ "@deepseek-ai/dsh-client-ui-primitives": "0.1.5-rc.2",
106
+ "@deepseek-ai/dsh-client-ui-settings": "0.1.5-rc.2",
107
+ "@deepseek-ai/dsh-client-ui-slots": "0.1.5-rc.2",
108
+ "@deepseek-ai/dsh-client-ui-tool": "0.1.5-rc.2",
109
+ "@deepseek-ai/dsh-credentials": "0.1.5-rc.2",
110
+ "@deepseek-ai/dsh-invariants": "0.1.5-rc.2",
111
+ "@deepseek-ai/dsh-llm": "0.1.5-rc.2",
112
+ "@deepseek-ai/dsh-llm-pi-ai": "0.1.5-rc.2",
113
+ "@deepseek-ai/dsh-session": "0.1.5-rc.2",
114
+ "@deepseek-ai/dsh-settings": "0.1.5-rc.2",
115
+ "@deepseek-ai/dsh-tools": "0.1.5-rc.2",
116
+ "@deepseek-ai/dsh-web": "0.1.5-rc.2",
116
117
  "@deepseek-ai/schemastery": "3.18.2",
117
118
  "@earendil-works/pi-ai": "0.82.1",
118
119
  "@heroicons/react": "2.2.0",
@@ -120,16 +121,18 @@
120
121
  "fake-indexeddb": "6.2.5",
121
122
  "react": "18.3.1",
122
123
  "react-dom": "18.3.1",
123
- "tsdown": "0.22.2"
124
+ "tsdown": "0.22.2",
125
+ "@deepseek-ai/dsh-subagent-codex": "0.1.5-rc.2"
124
126
  },
125
127
  "dependencies": {
126
128
  "@deepseek-ai/dsh-home-paths": "0.1.1-rc.2",
127
129
  "https-proxy-agent": "7.0.6",
128
130
  "ws": "8.21.3"
129
131
  },
130
- "optionalDependencies": {
131
- "@deepseek-ai/dsh-sdk-protocol": "0.1.5-rc.2",
132
- "@deepseek-ai/dsh-subagent-codex": "0.1.5-rc.2"
132
+ "peerDependenciesMeta": {
133
+ "@deepseek-ai/dsh-subagent-codex": {
134
+ "optional": true
135
+ }
133
136
  },
134
137
  "scripts": {
135
138
  "build": "tsdown --config tsdown.config.mjs",