dsh-pstack 0.0.0-stage → 0.2.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/LICENSE +22 -0
- package/README.md +133 -2
- package/assets/agents/comment-sicko.md +32 -0
- package/assets/agents/poteto-agent.md +8 -0
- package/assets/docs/guide/01-setup.md +64 -0
- package/assets/docs/guide/02-poteto-mode.md +139 -0
- package/assets/docs/guide/03-understand.md +79 -0
- package/assets/docs/guide/04-design.md +133 -0
- package/assets/docs/guide/05-build-and-clean.md +83 -0
- package/assets/docs/guide/06-verify-and-ship.md +152 -0
- package/assets/docs/guide/07-overnight.md +120 -0
- package/assets/docs/guide/08-principles.md +72 -0
- package/assets/docs/guide/09-make-it-yours.md +96 -0
- package/assets/docs/guide/10-recipes-and-pitfalls.md +180 -0
- package/assets/docs/guide/README.md +38 -0
- package/assets/docs/guide/images/design.jpg +0 -0
- package/assets/docs/guide/images/overnight.jpg +0 -0
- package/assets/docs/guide/images/recipes.jpg +0 -0
- package/assets/docs/guide/images/router.jpg +0 -0
- package/assets/docs/guide/images/understanding.jpg +0 -0
- package/assets/docs/guide/images/verification.jpg +0 -0
- package/assets/docs/harness/dsh.md +60 -0
- package/assets/docs/pstack-models.example.md +54 -0
- package/assets/skills/architect/SKILL.md +81 -0
- package/assets/skills/architect/references/design-red-flags.md +57 -0
- package/assets/skills/architect/references/rationale-template.md +35 -0
- package/assets/skills/architect/references/runner-prompt.md +20 -0
- package/assets/skills/arena/SKILL.md +50 -0
- package/assets/skills/automate-me/SKILL.md +106 -0
- package/assets/skills/benchmark-checklist/SKILL.md +39 -0
- package/assets/skills/blast-radius/SKILL.md +52 -0
- package/assets/skills/bro/SKILL.md +7 -0
- package/assets/skills/correct/SKILL.md +32 -0
- package/assets/skills/create-formal-verification-skill/SKILL.md +43 -0
- package/assets/skills/create-verification-skill/SKILL.md +46 -0
- package/assets/skills/create-verification-skill/references/feature-map-example/README.md +47 -0
- package/assets/skills/create-verification-skill/references/feature-map-example/create-note.md +39 -0
- package/assets/skills/create-verification-skill/references/feature-map-example/search.md +45 -0
- package/assets/skills/figure-it-out/SKILL.md +54 -0
- package/assets/skills/how/SKILL.md +38 -0
- package/assets/skills/how/references/explainer-prompt.md +55 -0
- package/assets/skills/how/references/explorer-prompt.md +35 -0
- package/assets/skills/in-your-own-words/SKILL.md +7 -0
- package/assets/skills/interrogate/SKILL.md +71 -0
- package/assets/skills/interrogate/references/code-quality-review.md +47 -0
- package/assets/skills/interrogate/references/lead-judgment.md +39 -0
- package/assets/skills/interrogate/references/reviewer-prompt.md +62 -0
- package/assets/skills/interrogate/references/rubric.md +77 -0
- package/assets/skills/ketchup/SKILL.md +45 -0
- package/assets/skills/maintain-formal-verification-skill/SKILL.md +60 -0
- package/assets/skills/maintain-verification-skill/SKILL.md +41 -0
- package/assets/skills/no-comments/SKILL.md +26 -0
- package/assets/skills/poteto-help/SKILL.md +162 -0
- package/assets/skills/poteto-help/references/prompting.md +51 -0
- package/assets/skills/poteto-help/references/recipes.md +51 -0
- package/assets/skills/poteto-mode/SKILL.md +151 -0
- package/assets/skills/poteto-mode/playbooks/authoring-a-skill.md +12 -0
- package/assets/skills/poteto-mode/playbooks/autonomous-run.md +15 -0
- package/assets/skills/poteto-mode/playbooks/autopilot-full.md +25 -0
- package/assets/skills/poteto-mode/playbooks/autopilot-stack.md +12 -0
- package/assets/skills/poteto-mode/playbooks/babysit.md +23 -0
- package/assets/skills/poteto-mode/playbooks/bug-fix.md +15 -0
- package/assets/skills/poteto-mode/playbooks/eval.md +25 -0
- package/assets/skills/poteto-mode/playbooks/feature.md +21 -0
- package/assets/skills/poteto-mode/playbooks/hillclimb.md +21 -0
- package/assets/skills/poteto-mode/playbooks/investigation.md +14 -0
- package/assets/skills/poteto-mode/playbooks/multi-phase-plan.md +155 -0
- package/assets/skills/poteto-mode/playbooks/opening-a-pr.md +34 -0
- package/assets/skills/poteto-mode/playbooks/orchestrate.md +112 -0
- package/assets/skills/poteto-mode/playbooks/pause-safely.md +10 -0
- package/assets/skills/poteto-mode/playbooks/perf-issue.md +25 -0
- package/assets/skills/poteto-mode/playbooks/prototype.md +14 -0
- package/assets/skills/poteto-mode/playbooks/refactoring.md +16 -0
- package/assets/skills/poteto-mode/playbooks/runtime-forensics.md +11 -0
- package/assets/skills/poteto-mode/playbooks/session-pickup.md +11 -0
- package/assets/skills/poteto-mode/playbooks/shipping.md +12 -0
- package/assets/skills/poteto-mode/playbooks/trace-forensics.md +14 -0
- package/assets/skills/poteto-mode/playbooks/visual-parity.md +11 -0
- package/assets/skills/poteto-mode/playbooks/worktree-cleanup.md +20 -0
- package/assets/skills/poteto-mode/references/bugbot-triage.md +142 -0
- package/assets/skills/poteto-mode/scripts/check-plan.mjs +220 -0
- package/assets/skills/poteto-mode/scripts/check-plan.test.mjs +343 -0
- package/assets/skills/poteto-mode/scripts/orch/orch.mjs +4282 -0
- package/assets/skills/poteto-mode/scripts/orch/orch.test.mjs +2042 -0
- package/assets/skills/poteto-mode/scripts/watch-pr/cli.test.mjs +5101 -0
- package/assets/skills/poteto-mode/scripts/watch-pr/github.test.mjs +1177 -0
- package/assets/skills/poteto-mode/scripts/watch-pr/policy.test.mjs +1441 -0
- package/assets/skills/poteto-mode/scripts/watch-pr/watch-pr.mjs +4601 -0
- package/assets/skills/poteto-mode/scripts/worktree-audit.mjs +675 -0
- package/assets/skills/principle-attack-the-premise/SKILL.md +21 -0
- package/assets/skills/principle-boundary-discipline/SKILL.md +34 -0
- package/assets/skills/principle-build-the-lever/SKILL.md +23 -0
- package/assets/skills/principle-encode-lessons-in-structure/SKILL.md +11 -0
- package/assets/skills/principle-exhaust-the-design-space/SKILL.md +9 -0
- package/assets/skills/principle-experience-first/SKILL.md +19 -0
- package/assets/skills/principle-explain-the-number/SKILL.md +17 -0
- package/assets/skills/principle-fix-root-causes/SKILL.md +21 -0
- package/assets/skills/principle-foundational-thinking/SKILL.md +21 -0
- package/assets/skills/principle-guard-the-context-window/SKILL.md +12 -0
- package/assets/skills/principle-laziness-protocol/SKILL.md +10 -0
- package/assets/skills/principle-make-operations-idempotent/SKILL.md +22 -0
- package/assets/skills/principle-migrate-callers-then-delete-legacy-apis/SKILL.md +14 -0
- package/assets/skills/principle-minimize-reader-load/SKILL.md +18 -0
- package/assets/skills/principle-model-the-domain/SKILL.md +24 -0
- package/assets/skills/principle-never-block-on-the-human/SKILL.md +15 -0
- package/assets/skills/principle-outcome-oriented-execution/SKILL.md +21 -0
- package/assets/skills/principle-prove-it-works/SKILL.md +24 -0
- package/assets/skills/principle-redesign-from-first-principles/SKILL.md +16 -0
- package/assets/skills/principle-separate-before-serializing-shared-state/SKILL.md +16 -0
- package/assets/skills/principle-sequence-verifiable-units/SKILL.md +17 -0
- package/assets/skills/principle-subtract-before-you-add/SKILL.md +18 -0
- package/assets/skills/principle-test-behavior-not-implementation/SKILL.md +20 -0
- package/assets/skills/principle-type-system-discipline/SKILL.md +13 -0
- package/assets/skills/recall/SKILL.md +37 -0
- package/assets/skills/reflect/SKILL.md +69 -0
- package/assets/skills/reflect/references/divergent-reviewer.md +38 -0
- package/assets/skills/reflect/references/judgment-reviewer.md +37 -0
- package/assets/skills/reflect/references/synthesizer.md +56 -0
- package/assets/skills/reflect/references/tooling-reviewer.md +48 -0
- package/assets/skills/setup-pstack/SKILL.md +67 -0
- package/assets/skills/sharpen/SKILL.md +16 -0
- package/assets/skills/show-me-your-work/SKILL.md +84 -0
- package/assets/skills/show-me-your-work/references/decision-log-template.tsv +1 -0
- package/assets/skills/show-me-your-work/scripts/log.mjs +108 -0
- package/assets/skills/swarm/SKILL.md +43 -0
- package/assets/skills/tdd/SKILL.md +42 -0
- package/assets/skills/teach/SKILL.md +23 -0
- package/assets/skills/technical-writing/SKILL.md +108 -0
- package/assets/skills/typescript-best-practices/SKILL.md +34 -0
- package/assets/skills/typescript-best-practices/references/patterns.md +328 -0
- package/assets/skills/unslop/SKILL.md +62 -0
- package/assets/skills/why/SKILL.md +100 -0
- package/assets/skills/why/references/epistemics.md +71 -0
- package/assets/skills/why/references/investigator-prompt.md +84 -0
- package/assets/skills/why/references/source-playbook.md +17 -0
- package/assets/skills/why/references/sources/code-archaeology.md +51 -0
- package/assets/skills/why/references/sources/databricks.md +70 -0
- package/assets/skills/why/references/sources/datadog.md +97 -0
- package/assets/skills/why/references/sources/incident-postmortem.md +5 -0
- package/assets/skills/why/references/sources/linear.md +48 -0
- package/assets/skills/why/references/sources/notion.md +55 -0
- package/assets/skills/why/references/sources/sentry.md +66 -0
- package/assets/skills/why/references/sources/slack.md +17 -0
- package/assets/skills/why/references/synthesizer-prompt.md +129 -0
- package/cordis.patch.yml +39 -0
- package/dist/frontmatter-BQX3ekwP.mjs +229 -0
- package/dist/frontmatter-BQX3ekwP.mjs.map +1 -0
- package/dist/history.d.mts +429 -0
- package/dist/history.mjs +1129 -0
- package/dist/history.mjs.map +1 -0
- package/dist/host-contract-o47JH_r8.d.mts +527 -0
- package/dist/index.d.mts +278 -0
- package/dist/index.mjs +272 -0
- package/dist/index.mjs.map +1 -0
- package/dist/paths-D_JlVmBk.mjs +42 -0
- package/dist/paths-D_JlVmBk.mjs.map +1 -0
- package/dist/script.d.mts +193 -0
- package/dist/script.mjs +782 -0
- package/dist/script.mjs.map +1 -0
- package/dist/subagent.d.mts +336 -0
- package/dist/subagent.mjs +1402 -0
- package/dist/subagent.mjs.map +1 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +106 -3
- package/static/icon.png +0 -0
|
@@ -0,0 +1,527 @@
|
|
|
1
|
+
//#region src/host-contract.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Structural copies of the `@deepseek-ai/*` 0.2.1-rc.3 declarations this plugin
|
|
4
|
+
* binds to.
|
|
5
|
+
*
|
|
6
|
+
* Runtime modules import nothing from the host packages. A profile install of a
|
|
7
|
+
* workspace directory is a link into this checkout, and the profile's
|
|
8
|
+
* `pnpm-workspace.yaml` sets `autoInstallPeers: false`, so a runtime import of a
|
|
9
|
+
* host package resolves nothing. Restating the contract here keeps that promise
|
|
10
|
+
* and keeps `pnpm typecheck` independent of a machine-local DSH install.
|
|
11
|
+
*
|
|
12
|
+
* This is the only file that restates a host contract for delegation. When DSH
|
|
13
|
+
* changes, re-inspect and update here, then run the delegation tests and the real
|
|
14
|
+
* profile acceptance. Do not grow a second copy in another module.
|
|
15
|
+
*
|
|
16
|
+
* Contract sources (Host Inspect, 0.2.1-rc.3):
|
|
17
|
+
* - `Service.listService({ service: "subagents" })`
|
|
18
|
+
* - `Service.listService({ service: "llm" })`
|
|
19
|
+
* - `Service.listService({ service: "tools" })`
|
|
20
|
+
* - `Service.listService({ service: "agents" })` — `Agent`, `AgentsHost`,
|
|
21
|
+
* `AgentScope`, and the `agent/request` waterfall below
|
|
22
|
+
* - `Service.listService({ service: "sessionQuery" })`
|
|
23
|
+
*
|
|
24
|
+
* `Agent` is deliberately not minimal. Its `options`, `session.requestHeader()`,
|
|
25
|
+
* and `ctx` are the three seams a child-scoped reasoning-effort control needs, and
|
|
26
|
+
* an `Agent` that stops at `{ id }` cannot express the capability at all. The cost
|
|
27
|
+
* of the wider copy is that every test now has to build a fuller fake; the cost of
|
|
28
|
+
* the narrower one was a documented capability with nowhere to live.
|
|
29
|
+
*
|
|
30
|
+
* Deliberate simplifications, none observable at runtime:
|
|
31
|
+
* - Branded ids (`SessionId`, `MessageId`, `ReasoningEffortId`,
|
|
32
|
+
* `SessionSeq`, `SessionPersistenceRevision`) are plain `string`/`number`;
|
|
33
|
+
* the brand is erased and only carried for documentation.
|
|
34
|
+
* - `ContentBlock` names the text variant this plugin emits and leaves the other
|
|
35
|
+
* variants opaque, because the prompt this tool builds is text only.
|
|
36
|
+
* - `SessionEvent.data` stays `unknown`. Restricted history forwards raw event
|
|
37
|
+
* payloads unchanged, so naming every event variant here would be a second,
|
|
38
|
+
* drifting copy of the log format with no reader.
|
|
39
|
+
*/
|
|
40
|
+
/**
|
|
41
|
+
* The request header in force after the log's last header event.
|
|
42
|
+
*
|
|
43
|
+
* Only `config` is named, because only `config` is read. `config` is the call
|
|
44
|
+
* configuration the machine would use, i.e. the live route after a model switch,
|
|
45
|
+
* where `Agent.options` describes the creation-time route instead.
|
|
46
|
+
*/
|
|
47
|
+
interface RequestEpochHeader {
|
|
48
|
+
readonly config: LlmCallConfig;
|
|
49
|
+
}
|
|
50
|
+
/** The slice of `Agent.session` used to resolve a live route. */
|
|
51
|
+
interface AgentSession {
|
|
52
|
+
/** The header in force after the log's last header event; undefined before the first request. */
|
|
53
|
+
requestHeader(): RequestEpochHeader | undefined;
|
|
54
|
+
}
|
|
55
|
+
/** One `agent/request` waterfall listener. */
|
|
56
|
+
type AgentRequestListener = (payload: {
|
|
57
|
+
readonly agent: Agent;
|
|
58
|
+
readonly turn: number;
|
|
59
|
+
readonly step: number;
|
|
60
|
+
}, next: () => Promise<LlmCallConfig>) => Promise<LlmCallConfig>;
|
|
61
|
+
/**
|
|
62
|
+
* The slice of an agent-scoped context a child-scoped contribution needs.
|
|
63
|
+
*
|
|
64
|
+
* Everything registered here is agent-local: it unwinds on disposal and rejects
|
|
65
|
+
* registration afterward. That is what makes one child's reasoning-effort control
|
|
66
|
+
* invisible to its siblings, and why two concurrent delegations cannot affect each
|
|
67
|
+
* other.
|
|
68
|
+
*/
|
|
69
|
+
interface AgentScope {
|
|
70
|
+
/**
|
|
71
|
+
* Contribute to the agent-scoped `agent/request` waterfall.
|
|
72
|
+
*
|
|
73
|
+
* Dispatch is scope-filtered, so a listener registered on this child's own
|
|
74
|
+
* context receives only that child's requests. `next()` yields the configuration
|
|
75
|
+
* the machine would use (agent options on the first request, the logged header
|
|
76
|
+
* afterwards); returning a replacement switches it. A request already in flight
|
|
77
|
+
* is never rewritten.
|
|
78
|
+
*
|
|
79
|
+
* @returns the disposer, which unwinds with the scope.
|
|
80
|
+
*/
|
|
81
|
+
on(event: "agent/request", listener: AgentRequestListener): () => void;
|
|
82
|
+
/** The tool registry, scoped to this agent. */
|
|
83
|
+
readonly tools: ToolsHost;
|
|
84
|
+
}
|
|
85
|
+
/** The live Agent the tool executes under. */
|
|
86
|
+
interface Agent {
|
|
87
|
+
readonly id: string;
|
|
88
|
+
/** The provider route and model this agent's requests use at creation time. */
|
|
89
|
+
readonly options: AgentOptions;
|
|
90
|
+
/** The live session this agent drives. */
|
|
91
|
+
readonly session: AgentSession;
|
|
92
|
+
/** Agent-scoped context; contributions are agent-local and unwind on disposal. */
|
|
93
|
+
readonly ctx: AgentScope;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* The slice of `ctx.agents` this tool uses to reach a child it has just started.
|
|
97
|
+
*
|
|
98
|
+
* `startActivation` returns the child id and not the child handle, and this tool
|
|
99
|
+
* needs the handle to contribute to the child's own scope.
|
|
100
|
+
*/
|
|
101
|
+
interface AgentsHost {
|
|
102
|
+
/** The live agent with this shared agent/session id, or undefined when none is live. */
|
|
103
|
+
get(id: string): Agent | undefined;
|
|
104
|
+
}
|
|
105
|
+
/** Adapter-owned child model controls. Omitted fields inherit the parent route. */
|
|
106
|
+
interface AgentOptions {
|
|
107
|
+
provider?: string;
|
|
108
|
+
model?: string;
|
|
109
|
+
reasoningEffort?: string;
|
|
110
|
+
maxTokens?: number;
|
|
111
|
+
}
|
|
112
|
+
/** One provider/model route plus optional request controls. */
|
|
113
|
+
interface LlmCallConfig {
|
|
114
|
+
provider: string;
|
|
115
|
+
model: string;
|
|
116
|
+
reasoningEffort?: string;
|
|
117
|
+
temperature?: number;
|
|
118
|
+
maxTokens?: number;
|
|
119
|
+
stop?: string[];
|
|
120
|
+
}
|
|
121
|
+
interface LlmProviderInfo {
|
|
122
|
+
readonly id: string;
|
|
123
|
+
readonly name: string;
|
|
124
|
+
}
|
|
125
|
+
interface LlmReasoningEffortInfo {
|
|
126
|
+
readonly id: string;
|
|
127
|
+
readonly name: string;
|
|
128
|
+
readonly description?: string;
|
|
129
|
+
}
|
|
130
|
+
interface LlmModelReasoningInfo {
|
|
131
|
+
readonly efforts: readonly LlmReasoningEffortInfo[];
|
|
132
|
+
readonly defaultEffort?: string;
|
|
133
|
+
}
|
|
134
|
+
interface LlmModelContext {
|
|
135
|
+
readonly contextWindow: number;
|
|
136
|
+
}
|
|
137
|
+
/** Detached metadata for one exact route, as the owning adapter reports it. */
|
|
138
|
+
interface LlmResolvedModelInfo {
|
|
139
|
+
readonly provider: string;
|
|
140
|
+
readonly id: string;
|
|
141
|
+
readonly name: string;
|
|
142
|
+
readonly description?: string;
|
|
143
|
+
readonly context?: LlmModelContext;
|
|
144
|
+
readonly reasoning?: LlmModelReasoningInfo;
|
|
145
|
+
}
|
|
146
|
+
/** The slice of `ctx.llm` used to validate a child route before starting it. */
|
|
147
|
+
interface LlmHost {
|
|
148
|
+
listProviders(): readonly LlmProviderInfo[];
|
|
149
|
+
resolveModelInfo(provider: string, model: string, signal?: AbortSignal): Promise<LlmResolvedModelInfo>;
|
|
150
|
+
/**
|
|
151
|
+
* Validate a call config against the exact model capability and materialize
|
|
152
|
+
* adapter defaults. An unsupported explicit effort rejects before any provider
|
|
153
|
+
* I/O; nothing is clamped or aliased.
|
|
154
|
+
*/
|
|
155
|
+
resolveCallConfig(config: LlmCallConfig, signal?: AbortSignal): Promise<LlmCallConfig>;
|
|
156
|
+
}
|
|
157
|
+
/** A text content block, the only prompt variant this tool sends. */
|
|
158
|
+
interface TextBlock {
|
|
159
|
+
readonly type: "text";
|
|
160
|
+
readonly text: string;
|
|
161
|
+
}
|
|
162
|
+
/** Prompt content; the non-text variants stay opaque here. */
|
|
163
|
+
type ContentBlock = TextBlock | {
|
|
164
|
+
readonly type: string;
|
|
165
|
+
readonly [field: string]: unknown;
|
|
166
|
+
};
|
|
167
|
+
/** What one registered backend can enforce, checked before a child starts. */
|
|
168
|
+
interface SubagentCapabilities {
|
|
169
|
+
readonly agentOptions: boolean;
|
|
170
|
+
readonly agentPreset: boolean;
|
|
171
|
+
readonly outputSchema: boolean;
|
|
172
|
+
readonly depthLimit: boolean;
|
|
173
|
+
}
|
|
174
|
+
/** The registered backend behind a provider name. */
|
|
175
|
+
interface SubagentProvider {
|
|
176
|
+
readonly name: string;
|
|
177
|
+
readonly capabilities: SubagentCapabilities;
|
|
178
|
+
readonly inheritsParentContext: boolean;
|
|
179
|
+
readonly agentRouteDefaults?: Readonly<{
|
|
180
|
+
provider: string;
|
|
181
|
+
model: string;
|
|
182
|
+
}>;
|
|
183
|
+
}
|
|
184
|
+
/** One child start request, after the activation wrapper supplies label and signal. */
|
|
185
|
+
interface SubagentStartRequest {
|
|
186
|
+
readonly cwd?: string;
|
|
187
|
+
readonly agentPreset?: string;
|
|
188
|
+
readonly label?: string;
|
|
189
|
+
readonly prompt: ContentBlock[];
|
|
190
|
+
readonly parent: Agent;
|
|
191
|
+
readonly signal: AbortSignal;
|
|
192
|
+
readonly agentOptions?: AgentOptions;
|
|
193
|
+
readonly outputSchema?: unknown;
|
|
194
|
+
readonly maxDepth?: number;
|
|
195
|
+
}
|
|
196
|
+
interface SubagentActivationSpec {
|
|
197
|
+
readonly provider: string;
|
|
198
|
+
readonly label: string;
|
|
199
|
+
readonly childId?: string;
|
|
200
|
+
readonly request: Omit<SubagentStartRequest, "label" | "signal">;
|
|
201
|
+
readonly signal: AbortSignal;
|
|
202
|
+
readonly delivery: "parent" | "caller";
|
|
203
|
+
}
|
|
204
|
+
interface SubagentActivation {
|
|
205
|
+
readonly childId: string;
|
|
206
|
+
readonly messageId?: string;
|
|
207
|
+
}
|
|
208
|
+
/** The slice of `ctx.subagents` this tool drives. */
|
|
209
|
+
interface SubagentsHost {
|
|
210
|
+
/** Registered provider names in insertion order. */
|
|
211
|
+
list(): string[];
|
|
212
|
+
getProvider(name: string): SubagentProvider | undefined;
|
|
213
|
+
/**
|
|
214
|
+
* Resolve this tool's depth policy. A numeric `configured` is returned as-is and
|
|
215
|
+
* an omitted one reads the Host setting, so the caller owns taking the minimum
|
|
216
|
+
* against its own cap.
|
|
217
|
+
*/
|
|
218
|
+
resolveMaxDepth(configured?: number | "provider-managed"): number | undefined;
|
|
219
|
+
startActivation(spec: SubagentActivationSpec): Promise<SubagentActivation>;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* One durable direct-child catalog row.
|
|
223
|
+
*
|
|
224
|
+
* `mode` is the authorization discriminator: only `continuable` children are
|
|
225
|
+
* reviewable. `one-shot` children cannot be resumed, `external` children live in
|
|
226
|
+
* another backend, and `unknown` modes carry no review guarantee.
|
|
227
|
+
*/
|
|
228
|
+
type SubagentCatalogEntry = {
|
|
229
|
+
readonly id: string;
|
|
230
|
+
readonly createdAt: number;
|
|
231
|
+
} & ({
|
|
232
|
+
readonly mode: "one-shot";
|
|
233
|
+
readonly label?: string;
|
|
234
|
+
} | {
|
|
235
|
+
readonly mode: "external";
|
|
236
|
+
readonly label?: string;
|
|
237
|
+
} | {
|
|
238
|
+
readonly mode: "continuable";
|
|
239
|
+
readonly label: string;
|
|
240
|
+
} | {
|
|
241
|
+
readonly mode: "unknown";
|
|
242
|
+
readonly label?: string;
|
|
243
|
+
});
|
|
244
|
+
/**
|
|
245
|
+
* The slice of `ctx.subagents` restricted history reads for authorization.
|
|
246
|
+
*
|
|
247
|
+
* `listChildren` takes a parent session id, not a caller identity, so its result
|
|
248
|
+
* is a naming source and never an authorization boundary on its own. Restricted
|
|
249
|
+
* history pairs it with the observed `header.parentSession`.
|
|
250
|
+
*/
|
|
251
|
+
interface SubagentCatalogHost {
|
|
252
|
+
listChildren(parentSessionId: string, signal?: AbortSignal): Promise<readonly SubagentCatalogEntry[]>;
|
|
253
|
+
}
|
|
254
|
+
/** The last committed log position, or `-1` when the log is empty. */
|
|
255
|
+
type SessionSeqCursor = number;
|
|
256
|
+
/**
|
|
257
|
+
* One raw log event.
|
|
258
|
+
*
|
|
259
|
+
* Only the envelope is named. `data` is forwarded unchanged so an auditor reads
|
|
260
|
+
* the log rather than a projection: this is the reason the tool never returns
|
|
261
|
+
* `deriveMessages()` output in its place.
|
|
262
|
+
*/
|
|
263
|
+
interface SessionEvent {
|
|
264
|
+
readonly type: string;
|
|
265
|
+
readonly seq: number;
|
|
266
|
+
readonly time: number;
|
|
267
|
+
readonly data: unknown;
|
|
268
|
+
readonly ignorable?: true;
|
|
269
|
+
readonly surfaceOp?: "append" | {
|
|
270
|
+
readonly op: "replace";
|
|
271
|
+
readonly startSeq: number;
|
|
272
|
+
readonly endSeq: number;
|
|
273
|
+
};
|
|
274
|
+
readonly sourceEventSeqs?: readonly number[];
|
|
275
|
+
}
|
|
276
|
+
/** Immutable per-session identity plus its durable delegation position. */
|
|
277
|
+
interface SessionHeader {
|
|
278
|
+
readonly version: number;
|
|
279
|
+
readonly id: string;
|
|
280
|
+
readonly createdAt: number;
|
|
281
|
+
readonly cwd?: string;
|
|
282
|
+
readonly parentSession?: string;
|
|
283
|
+
readonly isSeeded: boolean;
|
|
284
|
+
readonly origin?: "subagent";
|
|
285
|
+
readonly delegationDepth?: number;
|
|
286
|
+
readonly agentPreset?: string;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* One caller-owned observation lease.
|
|
290
|
+
*
|
|
291
|
+
* A `live` lease fixes the log position when it is built, so `events` never
|
|
292
|
+
* grows after construction. A `prepared` lease is a detached copy read from
|
|
293
|
+
* persistence; rc.3 appends synthetic interrupted-turn closers to it and marks
|
|
294
|
+
* neither them nor the persisted boundary. `revision` is present only for
|
|
295
|
+
* `prepared`. Both shapes must be released with `[Symbol.dispose]()`.
|
|
296
|
+
*/
|
|
297
|
+
interface SessionObservation {
|
|
298
|
+
readonly source: "live" | "prepared";
|
|
299
|
+
readonly header: SessionHeader;
|
|
300
|
+
readonly inheritedEventCount: number;
|
|
301
|
+
readonly events: readonly SessionEvent[];
|
|
302
|
+
/** Last seq this snapshot covers; `-1` when the log was empty. */
|
|
303
|
+
readonly cursor: SessionSeqCursor;
|
|
304
|
+
/** Persistence revision of a prepared snapshot. Live snapshots omit it. */
|
|
305
|
+
readonly revision?: string;
|
|
306
|
+
retain(): SessionObservation;
|
|
307
|
+
[Symbol.dispose](): void;
|
|
308
|
+
}
|
|
309
|
+
interface SessionObservationOptions {
|
|
310
|
+
readonly signal?: AbortSignal;
|
|
311
|
+
readonly projectionMode?: "all" | "none";
|
|
312
|
+
}
|
|
313
|
+
interface SessionRecord {
|
|
314
|
+
readonly header: SessionHeader;
|
|
315
|
+
readonly live: boolean;
|
|
316
|
+
readonly persisted: boolean;
|
|
317
|
+
readonly formatStatus?: "current" | "migration-required";
|
|
318
|
+
}
|
|
319
|
+
/** Provider-independent session metadata predicate, ANDed with its siblings. */
|
|
320
|
+
type SessionResultFilter = {
|
|
321
|
+
readonly kind: "id";
|
|
322
|
+
readonly values: readonly string[];
|
|
323
|
+
} | {
|
|
324
|
+
readonly kind: "cwd";
|
|
325
|
+
readonly values: readonly (string | null)[];
|
|
326
|
+
} | {
|
|
327
|
+
readonly kind: "created-at";
|
|
328
|
+
readonly from?: number;
|
|
329
|
+
readonly to?: number;
|
|
330
|
+
} | {
|
|
331
|
+
readonly kind: "parent";
|
|
332
|
+
readonly values: readonly (string | null)[];
|
|
333
|
+
} | {
|
|
334
|
+
readonly kind: "availability";
|
|
335
|
+
readonly values: readonly ("live" | "persisted")[];
|
|
336
|
+
};
|
|
337
|
+
/**
|
|
338
|
+
* The slice of `ctx.sessionQuery` restricted history reads.
|
|
339
|
+
*
|
|
340
|
+
* `observeSession` is the only raw-event reader used: `listEvents` returns a
|
|
341
|
+
* summary and `readSession` re-reads a detached copy, so neither can page one
|
|
342
|
+
* fixed snapshot. `filterSessions` answers the caller's workspace without
|
|
343
|
+
* materializing its log.
|
|
344
|
+
*/
|
|
345
|
+
interface SessionQueryHost {
|
|
346
|
+
observeSession(sessionId: string, options?: SessionObservationOptions): Promise<SessionObservation>;
|
|
347
|
+
filterSessions(filters: readonly SessionResultFilter[], signal?: AbortSignal): Promise<readonly SessionRecord[]>;
|
|
348
|
+
}
|
|
349
|
+
type JsonSchemaType = "object" | "array" | "string" | "number" | "integer" | "boolean" | "null";
|
|
350
|
+
/**
|
|
351
|
+
* The JSON Schema subset the Host actually enforces.
|
|
352
|
+
*
|
|
353
|
+
* Exactly `type`/`oneOf`/`properties`/`required`/`additionalProperties`/`items`/
|
|
354
|
+
* `enum`/`const` plus the annotation keys. Nothing else is accepted by
|
|
355
|
+
* `assertSupportedJsonSchema`, and the subset is deliberately narrow here too:
|
|
356
|
+
* `minimum` used to be listed, three tools declared numeric bounds with it, and the
|
|
357
|
+
* Host rejected the whole schema — so `jsonSchemaToTs` and `jsonSchemaToPy` fell back
|
|
358
|
+
* to `"unknown"` and the declared bounds were never enforced. Omitting it from this
|
|
359
|
+
* type makes the same mistake a compile error. Bounds live in each tool's own
|
|
360
|
+
* argument validation and in its `description`.
|
|
361
|
+
*/
|
|
362
|
+
interface JsonSchemaNode {
|
|
363
|
+
type?: JsonSchemaType;
|
|
364
|
+
oneOf?: JsonSchemaNode[];
|
|
365
|
+
properties?: Record<string, JsonSchemaNode>;
|
|
366
|
+
required?: string[];
|
|
367
|
+
additionalProperties?: boolean;
|
|
368
|
+
items?: JsonSchemaNode;
|
|
369
|
+
enum?: readonly (string | number | boolean | null)[];
|
|
370
|
+
const?: string | number | boolean | null;
|
|
371
|
+
description?: string;
|
|
372
|
+
title?: string;
|
|
373
|
+
default?: unknown;
|
|
374
|
+
}
|
|
375
|
+
/** How one tool's result is projected for the model. */
|
|
376
|
+
interface ToolOutputDefinition {
|
|
377
|
+
readonly schema: JsonSchemaNode;
|
|
378
|
+
render(args: unknown, value: unknown): ContentBlock[];
|
|
379
|
+
}
|
|
380
|
+
/** The typed same-process call input the registry supplies to `execute`. */
|
|
381
|
+
interface ToolExecutionInput {
|
|
382
|
+
readonly name: string;
|
|
383
|
+
/** Corpus id of this exact call, as written to the `tool/call` event. */
|
|
384
|
+
readonly callId: string;
|
|
385
|
+
readonly arguments: unknown;
|
|
386
|
+
readonly agent?: Agent;
|
|
387
|
+
readonly signal: AbortSignal;
|
|
388
|
+
}
|
|
389
|
+
/** `exec` inside a tool body. */
|
|
390
|
+
interface ToolRunContext extends ToolExecutionInput {
|
|
391
|
+
deferContext(context: unknown): void;
|
|
392
|
+
concludeTurn(): void;
|
|
393
|
+
}
|
|
394
|
+
interface ToolDefinition {
|
|
395
|
+
name: string;
|
|
396
|
+
description: string;
|
|
397
|
+
parameters: Record<string, unknown>;
|
|
398
|
+
readonly output: ToolOutputDefinition;
|
|
399
|
+
execute(args: unknown, exec: ToolRunContext): Promise<unknown>;
|
|
400
|
+
isConcurrencySafe?(args: unknown): boolean;
|
|
401
|
+
/**
|
|
402
|
+
* Cooperative tool-call timeout budget in milliseconds; omitted means no deadline.
|
|
403
|
+
*
|
|
404
|
+
* Enforced by `@deepseek-ai/dsh-tool-call-timeout-policy`, which wraps
|
|
405
|
+
* `tools/execute`: it replaces `exec.signal` with a deadline-combined signal for the
|
|
406
|
+
* duration of the call, and converts the outcome to a timeout when its own timer won.
|
|
407
|
+
*
|
|
408
|
+
* The budget covers **only the tool call**, not work the call starts. The wrapper
|
|
409
|
+
* disposes its timer as soon as `execute` settles, so a background job started by the
|
|
410
|
+
* call keeps running past the budget — the deadline cannot be used to bound a long
|
|
411
|
+
* task, and it does not break one either.
|
|
412
|
+
*
|
|
413
|
+
* Never sent to the model: `schemas()` whitelists name/description/parameters only.
|
|
414
|
+
*
|
|
415
|
+
* Declaring it asserts that the tool forwards `exec.signal` into an implementation
|
|
416
|
+
* that can reach quiescence when that signal aborts. `pstack_script` does: the
|
|
417
|
+
* foreground run hands the signal to `spawn`, so an abort kills the child.
|
|
418
|
+
*
|
|
419
|
+
* Source: `dsh-tools/lib/types/index.d.ts` (`ToolDefinition.timeoutMs`) in the
|
|
420
|
+
* installed 0.2.1-rc.3 tree; the npm copy of that file is byte-identical.
|
|
421
|
+
*/
|
|
422
|
+
timeoutMs?: number;
|
|
423
|
+
}
|
|
424
|
+
/** The slice of `ctx.tools` this tool needs. */
|
|
425
|
+
interface ToolsHost {
|
|
426
|
+
register(definition: ToolDefinition): () => void;
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* The slice of `ctx.workingDirectory` a script run needs.
|
|
430
|
+
*
|
|
431
|
+
* `ensure` is the same seam `dsh-tool-bash` uses before it spawns anything
|
|
432
|
+
* (`dsh-tool-bash/lib/index.js:663`): it returns the Session's current directory,
|
|
433
|
+
* creating or restoring it as the Host requires. Reading `process.cwd()` instead
|
|
434
|
+
* would run the script in the Host process's directory — wrong for every Session
|
|
435
|
+
* whose workspace is a checkout or a worktree.
|
|
436
|
+
*/
|
|
437
|
+
interface WorkingDirectoryHost {
|
|
438
|
+
/** The Session's current directory, validated/created as the Host requires. */
|
|
439
|
+
ensure(agent: Agent, signal?: AbortSignal): Promise<string>;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* A registry-issued job id, branded by the Host.
|
|
443
|
+
*
|
|
444
|
+
* Kept as a plain `string` here, like the other branded ids in this file: the brand
|
|
445
|
+
* is erased and only documents that the value is opaque and must not be parsed.
|
|
446
|
+
*/
|
|
447
|
+
type JobId = string;
|
|
448
|
+
/**
|
|
449
|
+
* A session id, branded by the Host.
|
|
450
|
+
*
|
|
451
|
+
* Plain `string` for the same reason. A job's `owner` is a session id, so the jobs
|
|
452
|
+
* slice below reuses the name rather than introducing a second spelling.
|
|
453
|
+
*/
|
|
454
|
+
type SessionId = string;
|
|
455
|
+
/** The tool call a job was started for. */
|
|
456
|
+
interface JobToolCall {
|
|
457
|
+
readonly callId: string;
|
|
458
|
+
readonly rootCallId: string;
|
|
459
|
+
}
|
|
460
|
+
/** One job's lifecycle state. */
|
|
461
|
+
type JobStatus = "running" | "stopping" | "completed" | "killed" | "failed";
|
|
462
|
+
/** One output channel a producer may append to. */
|
|
463
|
+
type JobChannel = "stdout" | "stderr" | "log";
|
|
464
|
+
/** A live handle on a started job. */
|
|
465
|
+
interface JobHandle {
|
|
466
|
+
readonly id: JobId;
|
|
467
|
+
append(text: string, options?: {
|
|
468
|
+
readonly channel?: JobChannel;
|
|
469
|
+
}): void;
|
|
470
|
+
updateProgress(line: string): void;
|
|
471
|
+
}
|
|
472
|
+
/** What a producer returns so the registry can cancel it and await its outcome. */
|
|
473
|
+
interface JobHooks {
|
|
474
|
+
cancel(reason?: string): void;
|
|
475
|
+
readonly done: Promise<JobOutcome>;
|
|
476
|
+
}
|
|
477
|
+
/** How a job ended, as its producer reports it. */
|
|
478
|
+
interface JobOutcome {
|
|
479
|
+
readonly status: "completed" | "killed" | "failed";
|
|
480
|
+
readonly detail?: string;
|
|
481
|
+
readonly result?: string;
|
|
482
|
+
}
|
|
483
|
+
/** The spec handed to `jobs.start`. */
|
|
484
|
+
interface JobSpec {
|
|
485
|
+
readonly kind: "bash";
|
|
486
|
+
readonly label: string;
|
|
487
|
+
readonly owner?: SessionId;
|
|
488
|
+
readonly toolCall?: JobToolCall;
|
|
489
|
+
readonly outputLimitBytes?: number;
|
|
490
|
+
readonly run: (job: JobHandle) => JobHooks;
|
|
491
|
+
}
|
|
492
|
+
/** A fresh projection of one job. */
|
|
493
|
+
interface JobView {
|
|
494
|
+
readonly id: JobId;
|
|
495
|
+
readonly kind: string;
|
|
496
|
+
readonly label: string;
|
|
497
|
+
readonly owner?: SessionId;
|
|
498
|
+
readonly status: JobStatus;
|
|
499
|
+
readonly progress?: string;
|
|
500
|
+
readonly detail?: string;
|
|
501
|
+
readonly startedAt: number;
|
|
502
|
+
readonly finishedAt?: number;
|
|
503
|
+
readonly output: {
|
|
504
|
+
readonly total: number;
|
|
505
|
+
readonly earliest: number;
|
|
506
|
+
readonly spillPaths?: readonly string[];
|
|
507
|
+
};
|
|
508
|
+
}
|
|
509
|
+
/**
|
|
510
|
+
* The slice of `ctx.jobs` a background script run needs.
|
|
511
|
+
*
|
|
512
|
+
* `jobs` is optional in the composition: a profile without a job controller still
|
|
513
|
+
* gets `pstack_script`, and a `background: true` call is then refused with a reason
|
|
514
|
+
* instead of hanging. That is why the access the row uses is `ctx.get("jobs")` —
|
|
515
|
+
* rc.3's optional-service form — and not `ctx.jobs`.
|
|
516
|
+
*
|
|
517
|
+
* Only `start` and `get` are named. `pstack_script` starts one job and reports its
|
|
518
|
+
* id; reading output, waiting, and killing stay with the Host's own job tools, which
|
|
519
|
+
* already own the model cursor and authorization checks.
|
|
520
|
+
*/
|
|
521
|
+
interface JobsHost {
|
|
522
|
+
start(spec: JobSpec): JobId;
|
|
523
|
+
get(id: JobId, caller?: SessionId): JobView;
|
|
524
|
+
}
|
|
525
|
+
//#endregion
|
|
526
|
+
export { ToolRunContext as _, JobsHost as a, SessionEvent as c, SessionQueryHost as d, SubagentCapabilities as f, ToolDefinition as g, SubagentsHost as h, JobId as i, SessionHeader as l, SubagentCatalogHost as m, AgentOptions as n, JsonSchemaNode as o, SubagentCatalogEntry as p, AgentsHost as r, LlmHost as s, Agent as t, SessionId as u, ToolsHost as v, WorkingDirectoryHost as y };
|
|
527
|
+
//# sourceMappingURL=host-contract-o47JH_r8.d.mts.map
|