dsh-pstack 0.2.0 → 0.3.0-beta.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.
- package/README.md +123 -123
- package/README.zh.md +120 -120
- package/cordis.patch.yml +4 -0
- package/dist/client.mjs +184 -43
- package/dist/client.mjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{paths-BT77khwm.mjs → paths-yji9SNak.mjs} +0 -1
- package/dist/pstack/docs/harness/dsh.md +36 -37
- package/dist/remote.d.mts +1 -1
- package/dist/remote.mjs +2 -1
- package/dist/role-catalog.d.mts +35 -0
- package/dist/role-catalog.mjs +122 -0
- package/dist/{role-config-NNn5r1JX.mjs → role-config-a4JpVdc-.mjs} +107 -143
- package/dist/role-manifest-79cnFfDM.mjs +112 -0
- package/dist/role-manifest-8OERX9-s.d.mts +90 -0
- package/dist/{role-wire-DZwTn2wF.d.mts → role-wire-CAJsVA6e.d.mts} +2 -3
- package/dist/roles.d.mts +1 -1
- package/dist/roles.mjs +4 -34
- package/dist/script.mjs +1 -1
- package/dist/subagent.d.mts +25 -3
- package/dist/subagent.mjs +67 -37
- package/package.json +22 -20
- package/dist/role-manifest-C3fUzjLI.d.mts +0 -19
package/dist/subagent.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as POTETO_MODE_SKILL_PATH } from "./paths-
|
|
2
|
-
import { a as
|
|
1
|
+
import { a as POTETO_MODE_SKILL_PATH } from "./paths-yji9SNak.mjs";
|
|
2
|
+
import { a as selectRoleRoutes, i as resolveDshHome, n as readRoleConfiguration, r as requireRole, t as modelsFilePath } from "./role-config-a4JpVdc-.mjs";
|
|
3
3
|
import { isAbsolute, join, relative, resolve } from "node:path";
|
|
4
4
|
import { existsSync, statSync } from "node:fs";
|
|
5
5
|
// src/internal/effort.ts
|
|
@@ -149,6 +149,13 @@ const AGENT_KINDS = [
|
|
|
149
149
|
"general"
|
|
150
150
|
];
|
|
151
151
|
const DEFAULT_CONFIG = { provider: DEFAULT_SUBAGENT_PROVIDER };
|
|
152
|
+
/**
|
|
153
|
+
* Depth a child runs at when a call omits `maxDepth` or passes an unusable value.
|
|
154
|
+
*
|
|
155
|
+
* A child is always at least depth 1 (it is one level below its parent), so this is the
|
|
156
|
+
* smallest value that can start a child while forbidding it from delegating further.
|
|
157
|
+
*/
|
|
158
|
+
const DEFAULT_CHILD_MAX_DEPTH = 1;
|
|
152
159
|
/** Raised for a configuration or argument problem, before any child starts. */
|
|
153
160
|
var DelegationError = class extends Error {
|
|
154
161
|
constructor(message) {
|
|
@@ -214,22 +221,36 @@ function composeChildPrompt(input) {
|
|
|
214
221
|
sections.push(`Task:\n\n${input.task}`);
|
|
215
222
|
return sections.join("\n\n---\n\n");
|
|
216
223
|
}
|
|
224
|
+
const DELEGATION_ARGUMENT_KEYS = [
|
|
225
|
+
"description",
|
|
226
|
+
"prompt",
|
|
227
|
+
"agent",
|
|
228
|
+
"role",
|
|
229
|
+
"roleIndex",
|
|
230
|
+
"reasoningEffort",
|
|
231
|
+
"cwd",
|
|
232
|
+
"maxDepth"
|
|
233
|
+
];
|
|
234
|
+
/**
|
|
235
|
+
* Keys a call must pass. `maxDepth` is accepted but not required: a missing or unusable
|
|
236
|
+
* value resolves to `DEFAULT_CHILD_MAX_DEPTH` instead of forcing the caller to guess an
|
|
237
|
+
* integer, which is where the reflexive `0` came from.
|
|
238
|
+
*/
|
|
239
|
+
const REQUIRED_DELEGATION_ARGUMENT_KEYS = [
|
|
240
|
+
"description",
|
|
241
|
+
"prompt",
|
|
242
|
+
"agent",
|
|
243
|
+
"role",
|
|
244
|
+
"roleIndex",
|
|
245
|
+
"reasoningEffort",
|
|
246
|
+
"cwd"
|
|
247
|
+
];
|
|
217
248
|
/** Validate every required model-facing argument. Null declines an optional setting. */
|
|
218
249
|
function parseDelegationArgs(raw) {
|
|
219
250
|
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) throw new DelegationError("arguments must be an object");
|
|
220
251
|
const record = raw;
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
"prompt",
|
|
224
|
-
"agent",
|
|
225
|
-
"role",
|
|
226
|
-
"roleIndex",
|
|
227
|
-
"reasoningEffort",
|
|
228
|
-
"cwd",
|
|
229
|
-
"maxDepth"
|
|
230
|
-
];
|
|
231
|
-
for (const key of known) if (!Object.hasOwn(record, key)) throw new DelegationError(`missing required argument "${key}"; every argument must be passed explicitly`);
|
|
232
|
-
for (const key of Object.keys(record)) if (!known.includes(key)) throw new DelegationError(`unknown argument "${key}"; accepted arguments are ${known.join(", ")}`);
|
|
252
|
+
for (const key of REQUIRED_DELEGATION_ARGUMENT_KEYS) if (!Object.hasOwn(record, key)) throw new DelegationError(`missing required argument "${key}"; every argument except maxDepth must be passed explicitly`);
|
|
253
|
+
for (const key of Object.keys(record)) if (!DELEGATION_ARGUMENT_KEYS.includes(key)) throw new DelegationError(`unknown argument "${key}"; accepted arguments are ${DELEGATION_ARGUMENT_KEYS.join(", ")}`);
|
|
233
254
|
const description = record["description"];
|
|
234
255
|
if (!isNonEmptyString(description)) throw new DelegationError("description must be a non-empty string: it becomes the child label");
|
|
235
256
|
const prompt = record["prompt"];
|
|
@@ -240,8 +261,9 @@ function parseDelegationArgs(raw) {
|
|
|
240
261
|
if (role !== null && !isNonEmptyString(role)) throw new DelegationError("role must be a non-empty string or null");
|
|
241
262
|
const cwd = record["cwd"];
|
|
242
263
|
if (cwd !== null && !isNonEmptyString(cwd)) throw new DelegationError("cwd must be a non-empty string or null");
|
|
243
|
-
const
|
|
244
|
-
|
|
264
|
+
const rawMaxDepth = record["maxDepth"];
|
|
265
|
+
const maxDepth = rawMaxDepth === void 0 ? null : rawMaxDepth;
|
|
266
|
+
if (maxDepth !== null && !isNonNegativeSafeInteger(maxDepth)) throw new DelegationError("maxDepth must be a non-negative safe integer, or null/omitted");
|
|
245
267
|
const roleIndex = record["roleIndex"];
|
|
246
268
|
if (roleIndex !== null && !isNonNegativeSafeInteger(roleIndex)) throw new DelegationError("roleIndex must be a non-negative safe integer or null");
|
|
247
269
|
if (roleIndex !== null && role === null) throw new DelegationError("roleIndex requires a non-null role");
|
|
@@ -267,15 +289,30 @@ function routeLabel(route, effortOverride) {
|
|
|
267
289
|
}
|
|
268
290
|
/** Take the smallest of the requested depth, this row's cap, and the Host setting. */
|
|
269
291
|
function resolveDelegationDepth(configured, requested, hostLimit) {
|
|
270
|
-
if (requested !== void 0 && !isNonNegativeSafeInteger(requested)) throw new DelegationError("maxDepth must be a non-negative safe integer");
|
|
271
|
-
if (configured !== void 0 && requested !== void 0 && requested > configured) throw new DelegationError(`maxDepth ${requested} exceeds this row's configured cap of ${configured}. Lower the request or raise \`pstack-subagent\` config.maxDepth.`);
|
|
292
|
+
if (requested !== void 0 && requested !== null && !isNonNegativeSafeInteger(requested)) throw new DelegationError("maxDepth must be a non-negative safe integer or null");
|
|
293
|
+
if (configured !== void 0 && requested !== void 0 && requested !== null && requested > configured) throw new DelegationError(`maxDepth ${requested} exceeds this row's configured cap of ${configured}. Lower the request or raise \`pstack-subagent\` config.maxDepth.`);
|
|
272
294
|
const candidates = [
|
|
273
295
|
configured,
|
|
274
296
|
requested,
|
|
275
297
|
hostLimit
|
|
276
|
-
].filter((value) => value !== void 0);
|
|
298
|
+
].filter((value) => value !== void 0 && value !== null);
|
|
277
299
|
return candidates.length === 0 ? void 0 : Math.min(...candidates);
|
|
278
300
|
}
|
|
301
|
+
/**
|
|
302
|
+
* Turn the per-call `maxDepth` request into an effective depth request.
|
|
303
|
+
*
|
|
304
|
+
* A child is always at least depth 1, so `0` can never start one: it is reported and
|
|
305
|
+
* replaced with `DEFAULT_CHILD_MAX_DEPTH` rather than failing the whole call. Omitting
|
|
306
|
+
* `maxDepth` (null) also uses the default, so a caller never has to guess an integer.
|
|
307
|
+
*/
|
|
308
|
+
function requestedChildDepth(requested, diagnostics) {
|
|
309
|
+
if (requested === null) return 1;
|
|
310
|
+
if (requested === 0) {
|
|
311
|
+
diagnostics.push(`maxDepth 0 cannot start a child (the child itself is depth 1), so this call used 1. Omit maxDepth for that default, or pass 1 or more.`);
|
|
312
|
+
return 1;
|
|
313
|
+
}
|
|
314
|
+
return requested;
|
|
315
|
+
}
|
|
279
316
|
/** Resolve the role file, routes, prompt, and depth into one plan. Pure of service calls. */
|
|
280
317
|
function planDelegation(args, runtime, config = DEFAULT_CONFIG) {
|
|
281
318
|
const rolePath = modelsFilePath(runtime.dshHome);
|
|
@@ -305,7 +342,7 @@ function planDelegation(args, runtime, config = DEFAULT_CONFIG) {
|
|
|
305
342
|
task: args.prompt
|
|
306
343
|
});
|
|
307
344
|
const agentPreset = agentPresetFor(args.agent);
|
|
308
|
-
const depth = resolveDelegationDepth(config.maxDepth, args.maxDepth, void 0);
|
|
345
|
+
const depth = resolveDelegationDepth(config.maxDepth, requestedChildDepth(args.maxDepth, diagnostics), void 0);
|
|
309
346
|
const total = routes.length;
|
|
310
347
|
const children = routes.map((route, index) => {
|
|
311
348
|
const agentOptions = agentOptionsFor(route, args.reasoningEffort ?? void 0);
|
|
@@ -495,9 +532,11 @@ async function delegate(parent, args, runtime, config = DEFAULT_CONFIG, signal =
|
|
|
495
532
|
const TOOL_DESCRIPTION = [
|
|
496
533
|
"Delegate self-contained work to one or more fresh child agents.",
|
|
497
534
|
"",
|
|
498
|
-
"Every argument is required. Pass null for role, roleIndex, reasoningEffort,
|
|
499
|
-
"setting is not used. Choose agent explicitly. maxDepth is
|
|
500
|
-
"
|
|
535
|
+
"Every argument is required except maxDepth. Pass null for role, roleIndex, reasoningEffort,",
|
|
536
|
+
"or cwd when that setting is not used. Choose agent explicitly. maxDepth is optional: omit it",
|
|
537
|
+
"(or pass null) for the safe default of 1, where the child exists but cannot start its own",
|
|
538
|
+
"children; pass 2 or more, within this row's configured cap, to let it delegate further. A 0 is",
|
|
539
|
+
"treated as 1, because a child is already depth 1 and 0 can never start one.",
|
|
501
540
|
"",
|
|
502
541
|
"Returns the id of every child it started plus the route each one resolved. The children run",
|
|
503
542
|
"in the background: their results arrive later as completion notices in this conversation.",
|
|
@@ -546,28 +585,19 @@ function buildParameters() {
|
|
|
546
585
|
description: "Required initial working directory, inside this session's directory or a separate Git worktree. Relative paths resolve against this session's directory. Null inherits the session directory."
|
|
547
586
|
},
|
|
548
587
|
maxDepth: {
|
|
549
|
-
type: "integer",
|
|
550
|
-
description: "
|
|
588
|
+
type: ["integer", "null"],
|
|
589
|
+
description: "Optional delegation-depth cap for the child. Omit or pass null for the safe default of 1 (the child exists but cannot start its own children). Pass 2 or more, within this row's configured cap, to let it delegate further. 0 is treated as 1: a child is already depth 1, so 0 can never start one."
|
|
551
590
|
},
|
|
552
591
|
roleIndex: {
|
|
553
592
|
type: ["integer", "null"],
|
|
554
|
-
description: "Required entry index for a list-valued role that is not an automatic panel, 0 or greater. Requires a non-null role. Null selects the first entry."
|
|
593
|
+
description: "Required entry index for a list-valued role that is not an automatic panel, 0 or greater. Requires a non-null role. Null selects the first entry. Call `pstack_roles` to see which roles accept an index."
|
|
555
594
|
},
|
|
556
595
|
reasoningEffort: {
|
|
557
596
|
type: ["string", "null"],
|
|
558
597
|
description: "Required reasoning-effort override for every child this call starts. Use one token the target model advertises, or null to keep the role line's starting effort. An unknown token fails the whole call before any child starts."
|
|
559
598
|
}
|
|
560
599
|
},
|
|
561
|
-
required: [
|
|
562
|
-
"description",
|
|
563
|
-
"prompt",
|
|
564
|
-
"agent",
|
|
565
|
-
"role",
|
|
566
|
-
"roleIndex",
|
|
567
|
-
"reasoningEffort",
|
|
568
|
-
"cwd",
|
|
569
|
-
"maxDepth"
|
|
570
|
-
]
|
|
600
|
+
required: [...REQUIRED_DELEGATION_ARGUMENT_KEYS]
|
|
571
601
|
};
|
|
572
602
|
}
|
|
573
603
|
const OUTPUT_SCHEMA = {
|
|
@@ -694,4 +724,4 @@ function describeError(error) {
|
|
|
694
724
|
}
|
|
695
725
|
return String(error);
|
|
696
726
|
}
|
|
697
|
-
export { AGENT_KINDS, AGENT_PRESETS, DEFAULT_SUBAGENT_PROVIDER, DelegationError, PartialDelegationError, TOOL_NAME, agentPresetFor, apply, assertProviderCapabilities, composeChildPrompt, createPstackSubagentTool, delegate, hostRuntime, inject, name, normalizeConfig, parseDelegationArgs, planDelegation, renderDelegationResult, resolveChildCwd, resolveDelegationDepth, routeLabel, startPlannedChildren };
|
|
727
|
+
export { AGENT_KINDS, AGENT_PRESETS, DEFAULT_CHILD_MAX_DEPTH, DEFAULT_SUBAGENT_PROVIDER, DELEGATION_ARGUMENT_KEYS, DelegationError, PartialDelegationError, REQUIRED_DELEGATION_ARGUMENT_KEYS, TOOL_NAME, agentPresetFor, apply, assertProviderCapabilities, composeChildPrompt, createPstackSubagentTool, delegate, hostRuntime, inject, name, normalizeConfig, parseDelegationArgs, planDelegation, renderDelegationResult, requestedChildDepth, resolveChildCwd, resolveDelegationDepth, routeLabel, startPlannedChildren };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-pstack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0-beta.1",
|
|
4
4
|
"description": "pstack for DeepSeek Harness: rigorous agent workflows ported from cursor/plugins.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"agent-skills",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
".": "./dist/index.mjs",
|
|
39
39
|
"./models": "./dist/models.mjs",
|
|
40
40
|
"./remote": "./dist/remote.mjs",
|
|
41
|
+
"./role-catalog": "./dist/role-catalog.mjs",
|
|
41
42
|
"./roles": "./dist/roles.mjs",
|
|
42
43
|
"./script": "./dist/script.mjs",
|
|
43
44
|
"./skill": "./dist/skill.mjs",
|
|
@@ -47,25 +48,26 @@
|
|
|
47
48
|
"./locale/*.json": "./locale/*.json"
|
|
48
49
|
},
|
|
49
50
|
"dependencies": {
|
|
50
|
-
"@deepseek-ai/dsh-agent": "0.2.2-alpha.2",
|
|
51
|
-
"@deepseek-ai/dsh-jobs": "0.2.2-alpha.2",
|
|
52
|
-
"@deepseek-ai/dsh-llm": "0.2.2-alpha.2",
|
|
53
|
-
"@deepseek-ai/dsh-session": "0.2.2-alpha.2",
|
|
54
|
-
"@deepseek-ai/dsh-skill": "0.2.2-alpha.2",
|
|
55
|
-
"@deepseek-ai/dsh-subagent": "0.2.2-alpha.2",
|
|
56
|
-
"@deepseek-ai/dsh-system-prompt": "0.2.2-alpha.2",
|
|
57
|
-
"@deepseek-ai/dsh-tools": "0.2.2-alpha.2",
|
|
58
|
-
"@deepseek-ai/dsh-typert-protocol": "0.2.2-alpha.2",
|
|
59
|
-
"@deepseek-ai/dsh-working-directory": "0.2.2-alpha.2",
|
|
60
51
|
"commander": "14.0.0"
|
|
61
52
|
},
|
|
62
53
|
"devDependencies": {
|
|
63
|
-
"@deepseek-ai/
|
|
64
|
-
"@deepseek-ai/dsh-
|
|
65
|
-
"@deepseek-ai/dsh-
|
|
66
|
-
"@deepseek-ai/dsh-client-
|
|
67
|
-
"@deepseek-ai/dsh-client-ui-
|
|
68
|
-
"@deepseek-ai/dsh-
|
|
54
|
+
"@deepseek-ai/cordis": "~4.0.6-alpha.2",
|
|
55
|
+
"@deepseek-ai/dsh-agent": "0.2.2-alpha.3",
|
|
56
|
+
"@deepseek-ai/dsh-api-gateway": "0.2.2-alpha.3",
|
|
57
|
+
"@deepseek-ai/dsh-client-locale": "0.2.2-alpha.3",
|
|
58
|
+
"@deepseek-ai/dsh-client-ui-plugin-manager": "0.2.2-alpha.3",
|
|
59
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.2.2-alpha.3",
|
|
60
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.2.2-alpha.3",
|
|
61
|
+
"@deepseek-ai/dsh-jobs": "0.2.2-alpha.3",
|
|
62
|
+
"@deepseek-ai/dsh-llm": "0.2.2-alpha.3",
|
|
63
|
+
"@deepseek-ai/dsh-session": "0.2.2-alpha.3",
|
|
64
|
+
"@deepseek-ai/dsh-skill": "0.2.2-alpha.3",
|
|
65
|
+
"@deepseek-ai/dsh-subagent": "0.2.2-alpha.3",
|
|
66
|
+
"@deepseek-ai/dsh-system-prompt": "0.2.2-alpha.3",
|
|
67
|
+
"@deepseek-ai/dsh-tools": "0.2.2-alpha.3",
|
|
68
|
+
"@deepseek-ai/dsh-typert-protocol": "0.2.2-alpha.3",
|
|
69
|
+
"@deepseek-ai/dsh-typert-registry": "0.2.2-alpha.3",
|
|
70
|
+
"@deepseek-ai/dsh-working-directory": "0.2.2-alpha.3",
|
|
69
71
|
"@types/node": "^24.1.0",
|
|
70
72
|
"@types/react": "~18.3.1",
|
|
71
73
|
"@types/react-dom": "~18.3.0",
|
|
@@ -79,7 +81,7 @@
|
|
|
79
81
|
"vite-plus": "1.4.0"
|
|
80
82
|
},
|
|
81
83
|
"peerDependencies": {
|
|
82
|
-
"@deepseek-ai/cordis": "~4.0.6-alpha.
|
|
84
|
+
"@deepseek-ai/cordis": "~4.0.6-alpha.2"
|
|
83
85
|
},
|
|
84
86
|
"icon": "./assets/logo.png",
|
|
85
87
|
"devEngines": {
|
|
@@ -95,7 +97,7 @@
|
|
|
95
97
|
}
|
|
96
98
|
},
|
|
97
99
|
"engines": {
|
|
98
|
-
"dsh": ">=0.2.
|
|
100
|
+
"dsh": ">=0.2.2-alpha.3",
|
|
99
101
|
"node": ">=24.21.1"
|
|
100
102
|
},
|
|
101
103
|
"dsh": {
|
|
@@ -130,7 +132,7 @@
|
|
|
130
132
|
}
|
|
131
133
|
],
|
|
132
134
|
"scripts": {
|
|
133
|
-
"prerelease": "vp run -r check && vp run -r test",
|
|
135
|
+
"prerelease": "vp run build && vp run -r check && vp run typecheck && vp run -r test",
|
|
134
136
|
"release": "bumpp"
|
|
135
137
|
}
|
|
136
138
|
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The one pstack role manifest.
|
|
3
|
-
*
|
|
4
|
-
* Keys are matched exactly after normalization, and commas belong to some keys
|
|
5
|
-
* (`feature, refactoring`, `reflect judgment, divergent, synthesizer`), so nothing here
|
|
6
|
-
* may split a key on a comma. A second literal role list anywhere is a bug.
|
|
7
|
-
*
|
|
8
|
-
* This module has no Node imports: the bundle imports it directly.
|
|
9
|
-
*/
|
|
10
|
-
/** Whether a role holds one route or a comma-separated list of routes. */
|
|
11
|
-
type RoleValueShape = "single" | "list";
|
|
12
|
-
interface RoleSpec {
|
|
13
|
-
/** Exact key as written in the role file. Commas belong to the key. */
|
|
14
|
-
readonly key: string;
|
|
15
|
-
readonly shape: RoleValueShape;
|
|
16
|
-
/** A list role that starts one child per entry automatically. */
|
|
17
|
-
readonly autoPanel: boolean;
|
|
18
|
-
}
|
|
19
|
-
export { RoleValueShape as n, RoleSpec as t };
|