@gilbertgt/dsh-plan-orchestrator 1.0.1 → 1.0.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.
Files changed (2) hide show
  1. package/lib/index.js +43 -30
  2. package/package.json +1 -1
package/lib/index.js CHANGED
@@ -2276,14 +2276,18 @@ function buildTaskPacket(plan, task, dependencyHandoff = []) {
2276
2276
  }
2277
2277
  //#endregion
2278
2278
  //#region src/contract/role-result.ts
2279
+ /**
2280
+ * Model-facing structured-output schema. DeepSeek Harness intentionally accepts
2281
+ * only a constrained raw JSON Schema vocabulary for subagent outputSchema.
2282
+ * Size/count limits therefore stay in validateRoleResult(), where they are
2283
+ * enforced after structured output is returned instead of being expressed with
2284
+ * unsupported maxLength/maxItems keywords here.
2285
+ */
2279
2286
  const ROLE_RESULT_SCHEMA = {
2280
2287
  type: "object",
2281
2288
  additionalProperties: false,
2282
2289
  properties: {
2283
- taskId: {
2284
- type: "string",
2285
- maxLength: 200
2286
- },
2290
+ taskId: { type: "string" },
2287
2291
  status: {
2288
2292
  type: "string",
2289
2293
  enum: [
@@ -2294,11 +2298,7 @@ const ROLE_RESULT_SCHEMA = {
2294
2298
  },
2295
2299
  changed: {
2296
2300
  type: "array",
2297
- items: {
2298
- type: "string",
2299
- maxLength: 512
2300
- },
2301
- maxItems: 200
2301
+ items: { type: "string" }
2302
2302
  },
2303
2303
  validation: {
2304
2304
  type: "array",
@@ -2306,10 +2306,7 @@ const ROLE_RESULT_SCHEMA = {
2306
2306
  type: "object",
2307
2307
  additionalProperties: false,
2308
2308
  properties: {
2309
- id: {
2310
- type: "string",
2311
- maxLength: 200
2312
- },
2309
+ id: { type: "string" },
2313
2310
  status: {
2314
2311
  type: "string",
2315
2312
  enum: [
@@ -2318,30 +2315,18 @@ const ROLE_RESULT_SCHEMA = {
2318
2315
  "INCONCLUSIVE"
2319
2316
  ]
2320
2317
  },
2321
- detail: {
2322
- type: "string",
2323
- maxLength: 2e3
2324
- }
2318
+ detail: { type: "string" }
2325
2319
  },
2326
2320
  required: ["id", "status"]
2327
- },
2328
- maxItems: 30
2321
+ }
2329
2322
  },
2330
2323
  remaining: {
2331
2324
  type: "array",
2332
- items: {
2333
- type: "string",
2334
- maxLength: 1e3
2335
- },
2336
- maxItems: 30
2325
+ items: { type: "string" }
2337
2326
  },
2338
2327
  contextExpansion: {
2339
2328
  type: "array",
2340
- items: {
2341
- type: "string",
2342
- maxLength: 1e3
2343
- },
2344
- maxItems: 30
2329
+ items: { type: "string" }
2345
2330
  }
2346
2331
  },
2347
2332
  required: [
@@ -2613,6 +2598,34 @@ const OWNERSHIP_SAFE_MUTATION_TOOLS = [
2613
2598
  "apply_patch",
2614
2599
  "patch"
2615
2600
  ];
2601
+ function errorMessage(error) {
2602
+ return error instanceof Error ? error.message : String(error);
2603
+ }
2604
+ /**
2605
+ * Resolve the conservative ownership-safe policy against the host's actual
2606
+ * global tool catalog. DSH rejects unknown names in tools.restrict(), so aliases
2607
+ * that are not registered in the active profile must never reach toolFilter.
2608
+ */
2609
+ function resolveOwnershipSafeToolAllow(ctx) {
2610
+ const schemas = ctx?.tools?.schemas;
2611
+ if (typeof schemas !== "function") throw new Error("tools.schemas unavailable for ownership-safe tool filtering");
2612
+ let catalog;
2613
+ try {
2614
+ catalog = schemas.call(ctx.tools);
2615
+ } catch (error) {
2616
+ throw new Error(`tools.schemas failed for ownership-safe tool filtering: ${errorMessage(error)}`);
2617
+ }
2618
+ if (!Array.isArray(catalog)) throw new Error("tools.schemas returned an invalid catalog for ownership-safe tool filtering");
2619
+ const registered = /* @__PURE__ */ new Set();
2620
+ for (const schema of catalog) {
2621
+ if (!schema || typeof schema !== "object" || Array.isArray(schema)) continue;
2622
+ const name = schema.name;
2623
+ if (typeof name === "string" && name.length > 0) registered.add(name);
2624
+ }
2625
+ const allow = OWNERSHIP_SAFE_MUTATION_TOOLS.filter((name) => registered.has(name));
2626
+ if (allow.length === 0) throw new Error("no ownership-safe global tools are registered in the active DSH profile");
2627
+ return [...allow];
2628
+ }
2616
2629
  var NativeSpawnBackend = class {
2617
2630
  ctx;
2618
2631
  constructor(ctx) {
@@ -2625,7 +2638,7 @@ var NativeSpawnBackend = class {
2625
2638
  try {
2626
2639
  const cwd = req.parent?.session?.header?.cwd;
2627
2640
  const signal = req.ownership ? withRoleTimeout(cwd, req.signal) : req.signal;
2628
- const toolFilter = req.ownership ? { allow: OWNERSHIP_SAFE_MUTATION_TOOLS } : req.toolFilter;
2641
+ const toolFilter = req.ownership ? { allow: resolveOwnershipSafeToolAllow(this.ctx) } : req.toolFilter;
2629
2642
  run = await this.ctx.subagents.start("spawn", {
2630
2643
  label: `${req.role}:${req.taskId}`,
2631
2644
  prompt: [{
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gilbertgt/dsh-plan-orchestrator",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "description": "Product-grade orchestration layer for DeepSeek Harness native Plan Mode",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",