@shendeguize/dsh-agent-sidecar 0.1.0
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 +21 -0
- package/README.md +167 -0
- package/cordis.patch.yml +10 -0
- package/lib/client.js +8062 -0
- package/lib/client.js.map +1 -0
- package/lib/index.d.ts +396 -0
- package/lib/index.js +4166 -0
- package/package.json +101 -0
- package/src/analysis.ts +782 -0
- package/src/bridge.ts +841 -0
- package/src/client/analysis/AnalysisPanel.tsx +191 -0
- package/src/client/analysis/analysis.module.css +183 -0
- package/src/client/analysis-glue.ts +331 -0
- package/src/client/api.ts +380 -0
- package/src/client/board/Board.tsx +214 -0
- package/src/client/board/board.module.css +302 -0
- package/src/client/board/logic.ts +556 -0
- package/src/client/board/project-view-logic.ts +361 -0
- package/src/client/board/project-view.module.css +307 -0
- package/src/client/board/project-view.tsx +189 -0
- package/src/client/board/strings.ts +112 -0
- package/src/client/commands.ts +484 -0
- package/src/client/controller.ts +360 -0
- package/src/client/css-modules.d.ts +11 -0
- package/src/client/detail/SessionDetail.tsx +270 -0
- package/src/client/detail/detail.module.css +433 -0
- package/src/client/detail/logic.ts +779 -0
- package/src/client/detail/strings.ts +98 -0
- package/src/client/detail/transport.ts +175 -0
- package/src/client/detail-glue.ts +397 -0
- package/src/client/detail-view.module.css +79 -0
- package/src/client/detail-view.tsx +233 -0
- package/src/client/dsh-tools/LineageTree.tsx +210 -0
- package/src/client/dsh-tools/SearchPanel.tsx +169 -0
- package/src/client/dsh-tools/dsh-tools.module.css +374 -0
- package/src/client/dsh-tools/logic.ts +596 -0
- package/src/client/dsh-tools/strings.ts +90 -0
- package/src/client/index.ts +315 -0
- package/src/client/inject/InjectPanel.tsx +482 -0
- package/src/client/inject/inject.module.css +446 -0
- package/src/client/inject/logic.ts +516 -0
- package/src/client/inject/overlay.module.css +22 -0
- package/src/client/inject-glue.ts +171 -0
- package/src/client/locales/command.ts +48 -0
- package/src/client/locales/en.ts +385 -0
- package/src/client/locales/index.ts +123 -0
- package/src/client/locales/zh.ts +402 -0
- package/src/client/m3-transport.ts +151 -0
- package/src/client/mount.tsx +307 -0
- package/src/client/project-glue.ts +134 -0
- package/src/client/search-glue.ts +143 -0
- package/src/client/settings-card.module.css +359 -0
- package/src/client/settings-card.tsx +565 -0
- package/src/client/settings-glue.ts +130 -0
- package/src/client/sidebar-tab.tsx +494 -0
- package/src/client/sse.ts +366 -0
- package/src/client/widget.tsx +80 -0
- package/src/config.ts +193 -0
- package/src/dsh-inject.ts +240 -0
- package/src/fusion.ts +988 -0
- package/src/guard.ts +274 -0
- package/src/index.ts +950 -0
- package/src/inject-gateway.ts +574 -0
- package/src/routes.ts +1133 -0
- package/src/send-cli.ts +340 -0
- package/src/session-store.ts +184 -0
- package/src/skills-provider.ts +293 -0
- package/src/supervisor.ts +463 -0
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,396 @@
|
|
|
1
|
+
import z from "@deepseek-ai/schemastery";
|
|
2
|
+
import { IncomingMessage, ServerResponse } from "node:http";
|
|
3
|
+
import { Readable, Writable } from "node:stream";
|
|
4
|
+
import { Context } from "@deepseek-ai/cordis";
|
|
5
|
+
|
|
6
|
+
//#region src/analysis.d.ts
|
|
7
|
+
/**
|
|
8
|
+
* AI bypass-analysis engine — design §5 pillar 3 / §4.e.3 (M3, T5.6).
|
|
9
|
+
* Creates a DEDICATED dsh analysis session per request via `ctx.agents.create`,
|
|
10
|
+
* feeds it a bounded summary of the observed session/project, supports
|
|
11
|
+
* incremental follow-up questions, and can be cancelled from the UI at any
|
|
12
|
+
* time. Pure engine: routing/index wiring is the integration layer's job, and
|
|
13
|
+
* the analysis INPUT (summary text assembled from fusion timelines/overviews)
|
|
14
|
+
* arrives as a structured parameter — this module never touches fusion.
|
|
15
|
+
*
|
|
16
|
+
* API facts verified against the installed SDK
|
|
17
|
+
* (`@deepseek-ai/dsh-agent@0.1.1-rc.2` d.ts, authoritative over the design
|
|
18
|
+
* sketch):
|
|
19
|
+
*
|
|
20
|
+
* - `ctx.agents.create(options): Promise<AgentHandle>` (lib/types/index.d.ts:288)
|
|
21
|
+
* with `CreateAgentOptions` requiring a CALLER-SUPPLIED `sessionId`
|
|
22
|
+
* (index.d.ts:65-118) — the engine mints one per analysis — plus an optional
|
|
23
|
+
* creation-only `signal` (index.d.ts:98). `AgentHandle = { agent; dispose():
|
|
24
|
+
* Promise<void> }` (index.d.ts:155-158); `dispose()` stops the loop and
|
|
25
|
+
* removes the session, which is exactly the UI "stop" semantics.
|
|
26
|
+
* - There is NO system-prompt field on `CreateAgentOptions` (`agentOptions` is
|
|
27
|
+
* only provider/model/maxTokens, runtime-types.d.ts:21-28; `setup` composes
|
|
28
|
+
* cordis scopes and would break pure DI), so the read-only-analyst guidance
|
|
29
|
+
* rides the FIRST user message instead.
|
|
30
|
+
* - `Agent.followup(message: UserMessage): void` is a SYNCHRONOUS inbox splice
|
|
31
|
+
* (runtime-types.d.ts:115) — same finding as T4.4. There is no per-message
|
|
32
|
+
* response promise; the result must be read back from the session.
|
|
33
|
+
* - "Getting the analysis result": `Agent.whenIdle(): Promise<void>` resolves
|
|
34
|
+
* after whole-agent quiescence (runtime-types.d.ts:87), and a waking
|
|
35
|
+
* followup flips status to running synchronously (runtime-types.d.ts:161-172),
|
|
36
|
+
* so `followup → whenIdle → read log` observes the completed turn. The text
|
|
37
|
+
* is read from `agent.session.deriveMessages()` (dsh-session
|
|
38
|
+
* index.d.ts:259, the cached surface projection); token accounting rides
|
|
39
|
+
* `assistant/message` events as `data.usage?: TokenUsage`
|
|
40
|
+
* (dsh-session types.d.ts:279-285, dsh-llm types.d.ts:123-129) — that feeds
|
|
41
|
+
* `tokensHint`.
|
|
42
|
+
* - `Agent.cancel(cause: AgentCancelCause): void` aborts the active turn
|
|
43
|
+
* (runtime-types.d.ts:80); `{ kind: 'user' }` is the honest cause for a
|
|
44
|
+
* user-facing stop/timeout (dsh-session types.d.ts:118-127).
|
|
45
|
+
*
|
|
46
|
+
* Bounds (§7-B token-cost touchpoint, design risk 12): gated by live
|
|
47
|
+
* `analysis.enabled` (default false), input truncated to `maxInputChars`,
|
|
48
|
+
* first response and every follow-up bounded by `analysisTimeoutMs` (timeout
|
|
49
|
+
* cancels the in-flight turn), and at most `maxActiveSessions` concurrent
|
|
50
|
+
* analysis sessions. No periodic/automatic analysis exists here by design.
|
|
51
|
+
*
|
|
52
|
+
* Error vocabulary (contractual):
|
|
53
|
+
* `analysis_disabled | create_failed | timeout | too_many_active | cancelled`.
|
|
54
|
+
* `create_failed` covers the whole establishment phase of `request()`
|
|
55
|
+
* (create + priming followup + first-turn wait); `cancelled` covers follow-ups
|
|
56
|
+
* against a session that is unknown, already stopped, or died mid-turn.
|
|
57
|
+
*
|
|
58
|
+
* Honesty: results are AI-generated inference; every {@link AnalysisResult}
|
|
59
|
+
* carries {@link ANALYSIS_DISCLAIMER} for the UI to display.
|
|
60
|
+
*
|
|
61
|
+
* Log lines NEVER carry the analyzed content: no `summaryText`, no follow-up
|
|
62
|
+
* question, no model reply — only kind/title/analysisSessionId/outcome/token
|
|
63
|
+
* hints and sizes (S8).
|
|
64
|
+
*
|
|
65
|
+
* Pure DI: no cordis/dsh imports; `ctx.agents.create` is injected through the
|
|
66
|
+
* minimal structural face {@link AnalysisAgentFace} (method-syntax members
|
|
67
|
+
* keep parameter checks bivariant, so the SDK's branded `SessionId` / wider
|
|
68
|
+
* `UserMessage` / union `AgentCancelCause` signatures remain assignable).
|
|
69
|
+
*
|
|
70
|
+
* @module
|
|
71
|
+
*/
|
|
72
|
+
/** Widened user-message face (same shape family as dsh-inject's, F11). */
|
|
73
|
+
interface AnalysisUserMessageFace {
|
|
74
|
+
readonly id: string;
|
|
75
|
+
readonly role: 'user';
|
|
76
|
+
readonly content: ReadonlyArray<{
|
|
77
|
+
readonly type: string;
|
|
78
|
+
readonly text?: string;
|
|
79
|
+
}>;
|
|
80
|
+
readonly source: {
|
|
81
|
+
readonly kind: string;
|
|
82
|
+
readonly plugin?: string;
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
/** Widened derived-message face over dsh-llm `Message` (message.d.ts:120-129). */
|
|
86
|
+
interface AnalysisDerivedMessageFace {
|
|
87
|
+
readonly role: string;
|
|
88
|
+
readonly content: ReadonlyArray<{
|
|
89
|
+
readonly type: string;
|
|
90
|
+
readonly text?: string;
|
|
91
|
+
}>;
|
|
92
|
+
}
|
|
93
|
+
/** Widened session-event envelope face (dsh-session types.d.ts:425-443). */
|
|
94
|
+
interface AnalysisSessionEventFace {
|
|
95
|
+
readonly type: string;
|
|
96
|
+
/** `assistant/message` events carry `{ usage?: TokenUsage }` here. */
|
|
97
|
+
readonly data?: unknown;
|
|
98
|
+
}
|
|
99
|
+
/** Read face over the live session log (dsh-session index.d.ts:106-267). */
|
|
100
|
+
interface AnalysisSessionLogFace {
|
|
101
|
+
/** Cached surface projection of the derived LLM history (index.d.ts:259). */
|
|
102
|
+
deriveMessages(): ReadonlyArray<AnalysisDerivedMessageFace>;
|
|
103
|
+
/** Immutable append-only event snapshot (index.d.ts:174). */
|
|
104
|
+
readonly events: ReadonlyArray<AnalysisSessionEventFace>;
|
|
105
|
+
}
|
|
106
|
+
/** Cancellation cause face; `{kind:'user'}` ∈ `AgentCancelCause` (dsh-session types.d.ts:118-127). */
|
|
107
|
+
interface AnalysisCancelCauseFace {
|
|
108
|
+
readonly kind: 'user';
|
|
109
|
+
}
|
|
110
|
+
/** Live-agent face: prompt in, quiescence + log read back (runtime-types.d.ts:60-133). */
|
|
111
|
+
interface AnalysisAgentDriverFace {
|
|
112
|
+
readonly session: AnalysisSessionLogFace;
|
|
113
|
+
followup(message: AnalysisUserMessageFace): void;
|
|
114
|
+
cancel(cause: AnalysisCancelCauseFace): void;
|
|
115
|
+
whenIdle(): Promise<void>;
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* The dedicated analysis session handle — `AgentHandle` face
|
|
119
|
+
* (index.d.ts:155-158): send messages via `agent.followup`, read responses via
|
|
120
|
+
* `agent.whenIdle` + `agent.session`, stop via `dispose()`.
|
|
121
|
+
*/
|
|
122
|
+
interface AnalysisSession {
|
|
123
|
+
readonly agent: AnalysisAgentDriverFace;
|
|
124
|
+
dispose(): Promise<void>;
|
|
125
|
+
}
|
|
126
|
+
/** Per-agent options face over SDK `AgentOptions` (runtime-types.d.ts:21-28). */
|
|
127
|
+
interface AnalysisAgentOptionsFace {
|
|
128
|
+
/** Provider route (must have a registered adapter at call time). */
|
|
129
|
+
readonly provider?: string;
|
|
130
|
+
/** Model id interpreted by the selected provider adapter. */
|
|
131
|
+
readonly model?: string;
|
|
132
|
+
/** Maximum output tokens for each conversation-model request. */
|
|
133
|
+
readonly maxTokens?: number;
|
|
134
|
+
}
|
|
135
|
+
/** `CreateAgentOptions` face (index.d.ts:65-118): engine-minted id + creation abort. */
|
|
136
|
+
interface AnalysisCreateOptions {
|
|
137
|
+
readonly sessionId: string;
|
|
138
|
+
readonly signal?: AbortSignal;
|
|
139
|
+
/**
|
|
140
|
+
* Provider/model routing for the analysis agent (`CreateAgentOptions.
|
|
141
|
+
* agentOptions`). The engine never sets this — the integration layer's
|
|
142
|
+
* create adapter resolves and attaches it (A-1: an agent created without
|
|
143
|
+
* provider/model fails prompt assembly on the `{{model}}` variable and
|
|
144
|
+
* `buildRequest`, completing with an empty summary and zero tokens).
|
|
145
|
+
*/
|
|
146
|
+
readonly agentOptions?: AnalysisAgentOptionsFace;
|
|
147
|
+
/**
|
|
148
|
+
* Session creation metadata (`CreateAgentOptions.meta` subset). Also
|
|
149
|
+
* attached by the create adapter, never the engine: the deployment
|
|
150
|
+
* persona's `{{cwd}}` prompt variable reads `session.header.cwd`, which
|
|
151
|
+
* only `meta.cwd` populates (same reason dsh-headless passes
|
|
152
|
+
* `meta: { cwd: process.cwd() }` on its own create call).
|
|
153
|
+
*/
|
|
154
|
+
readonly meta?: {
|
|
155
|
+
readonly cwd?: string;
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
/** Minimal `ctx.agents` face: the one factory entry point this engine uses. */
|
|
159
|
+
interface AnalysisAgentFace {
|
|
160
|
+
/** `AgentRegistry.create` (index.d.ts:288). */
|
|
161
|
+
create(options: AnalysisCreateOptions): Promise<AnalysisSession>;
|
|
162
|
+
}
|
|
163
|
+
//#endregion
|
|
164
|
+
//#region src/supervisor.d.ts
|
|
165
|
+
type SupervisorPolicy = 'adopt-or-host' | 'adopt-only' | 'off';
|
|
166
|
+
//#endregion
|
|
167
|
+
//#region src/config.d.ts
|
|
168
|
+
/** Daemon lifecycle governance (design §4.a). */
|
|
169
|
+
interface DaemonConfig {
|
|
170
|
+
/** adopt-or-host: probe→adopt→else spawn; adopt-only: never spawn; off: no lifecycle management (read-only reconcile still runs). */
|
|
171
|
+
policy: SupervisorPolicy;
|
|
172
|
+
/** Consecutive hosting failures before the supervisor trips FAILED. */
|
|
173
|
+
backoffLimit: number;
|
|
174
|
+
}
|
|
175
|
+
/** How to reach/launch the sidecar itself. */
|
|
176
|
+
interface SidecarInvocationConfig {
|
|
177
|
+
/** argv prefix of the sidecar executable (PATH name, absolute path, or e.g. python3+zipapp as multiple entries). */
|
|
178
|
+
command: string[];
|
|
179
|
+
/** Empty = default `~/.agent_sidecar` (honoring AGENT_SIDECAR_RUNTIME_DIR); non-empty redirects via env for spawned daemons. */
|
|
180
|
+
runtimeDir: string;
|
|
181
|
+
}
|
|
182
|
+
/** Reconciler snapshot cadences (design §4.b / ADR-2). */
|
|
183
|
+
interface StreamConfig {
|
|
184
|
+
/** `status` snapshot cadence while any session is working (ms). */
|
|
185
|
+
reconcileActiveMs: number;
|
|
186
|
+
/** `status` snapshot cadence otherwise (ms). */
|
|
187
|
+
reconcileIdleMs: number;
|
|
188
|
+
}
|
|
189
|
+
/** Write-path master switch and defaults (M2 consumes defaultMode). */
|
|
190
|
+
interface InjectConfig {
|
|
191
|
+
/** Master gate: false hides all inject affordances and 403s write actions server-side. */
|
|
192
|
+
enabled: boolean;
|
|
193
|
+
/** Default injection mode offered by the inject panel. */
|
|
194
|
+
defaultMode: 'queue' | 'steer';
|
|
195
|
+
}
|
|
196
|
+
/** AI bypass-analysis switch and model routing (M3). */
|
|
197
|
+
interface AnalysisConfig {
|
|
198
|
+
enabled: boolean;
|
|
199
|
+
/**
|
|
200
|
+
* Explicit provider route for the dedicated analysis agents. Empty (the
|
|
201
|
+
* default) reuses the host's default model selection (`agentDefaultModel`
|
|
202
|
+
* service, the same source dsh's own entry points read). Takes effect
|
|
203
|
+
* only together with a non-empty `model`.
|
|
204
|
+
*/
|
|
205
|
+
provider: string;
|
|
206
|
+
/** Explicit model id for the analysis agents; see {@link provider}. */
|
|
207
|
+
model: string;
|
|
208
|
+
}
|
|
209
|
+
/** Board rendering knobs (client half). */
|
|
210
|
+
interface UiConfig {
|
|
211
|
+
/** Session recency window shown on the board (hours). */
|
|
212
|
+
timeWindowHours: number;
|
|
213
|
+
/** Whether dead sessions are listed. */
|
|
214
|
+
showDead: boolean;
|
|
215
|
+
}
|
|
216
|
+
/** Skill provider switch (design §6/§7 path two; wired in M4/T6.2). */
|
|
217
|
+
interface SkillConfig {
|
|
218
|
+
/** Register the embedded agent-sidecar skill on ctx.skills (read at apply; restart semantics). */
|
|
219
|
+
provide: boolean;
|
|
220
|
+
}
|
|
221
|
+
/** Validated composition config (all defaults filled by the schema). */
|
|
222
|
+
interface Config {
|
|
223
|
+
daemon: DaemonConfig;
|
|
224
|
+
sidecar: SidecarInvocationConfig;
|
|
225
|
+
stream: StreamConfig;
|
|
226
|
+
inject: InjectConfig;
|
|
227
|
+
analysis: AnalysisConfig;
|
|
228
|
+
ui: UiConfig;
|
|
229
|
+
skill: SkillConfig;
|
|
230
|
+
}
|
|
231
|
+
declare const Config: z<Config>;
|
|
232
|
+
//#endregion
|
|
233
|
+
//#region src/dsh-inject.d.ts
|
|
234
|
+
/**
|
|
235
|
+
* Widened message parameter face: the SDK's `UserMessage` is assignable to
|
|
236
|
+
* this shape, which keeps `Agent`'s method signatures structurally
|
|
237
|
+
* compatible with {@link DshAgentFace} without importing SDK types.
|
|
238
|
+
*/
|
|
239
|
+
interface DshUserMessageFace {
|
|
240
|
+
readonly id: string;
|
|
241
|
+
readonly role: 'user';
|
|
242
|
+
readonly content: ReadonlyArray<{
|
|
243
|
+
readonly type: string;
|
|
244
|
+
}>;
|
|
245
|
+
readonly source: {
|
|
246
|
+
readonly kind: string;
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
/** Live-agent face: the two injection entry points (runtime-types.d.ts:115/:123). */
|
|
250
|
+
interface DshAgentFace {
|
|
251
|
+
followup(message: DshUserMessageFace): void;
|
|
252
|
+
steer(message: DshUserMessageFace): void;
|
|
253
|
+
}
|
|
254
|
+
/** `AgentHandle` face (index.d.ts:155-158). `dispose` is deliberately absent:
|
|
255
|
+
* the executor never tears down an agent it resumed — disposal would unload
|
|
256
|
+
* the session and cancel the just-queued work. */
|
|
257
|
+
interface DshAgentHandleFace {
|
|
258
|
+
readonly agent: DshAgentFace;
|
|
259
|
+
}
|
|
260
|
+
/** Minimal `ctx.agents` (`AgentRegistry`) face: locate + resume. */
|
|
261
|
+
interface AgentsServiceFace {
|
|
262
|
+
/** Live lookup (index.d.ts:349); undefined = session not loaded. */
|
|
263
|
+
get(sessionId: string): DshAgentFace | undefined;
|
|
264
|
+
/** Load a persisted session and start an agent on it (index.d.ts:296). */
|
|
265
|
+
resume(options: {
|
|
266
|
+
readonly resumeSessionId: string;
|
|
267
|
+
}): Promise<DshAgentHandleFace>;
|
|
268
|
+
}
|
|
269
|
+
//#endregion
|
|
270
|
+
//#region src/index.d.ts
|
|
271
|
+
declare const name = "agent-sidecar";
|
|
272
|
+
/** Required services; see the module doc for why `agents` is lazy instead. */
|
|
273
|
+
declare const inject: string[];
|
|
274
|
+
/** `ctx.webServer` face (route registration only). */
|
|
275
|
+
interface WebServerService {
|
|
276
|
+
register(route: {
|
|
277
|
+
kind: 'exact' | 'prefix';
|
|
278
|
+
path: string;
|
|
279
|
+
handler: (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;
|
|
280
|
+
}): () => void;
|
|
281
|
+
}
|
|
282
|
+
/** Bounded in-memory collection for one child output stream. */
|
|
283
|
+
interface SubprocessCollectSpec {
|
|
284
|
+
maxBytes: number;
|
|
285
|
+
spill?: {
|
|
286
|
+
maxBytes: number;
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
/** Fully-specified spawn request (`ctx.subprocess` applies no defaults). */
|
|
290
|
+
interface SubprocessSpawnSpec {
|
|
291
|
+
argv: readonly string[];
|
|
292
|
+
cwd: string;
|
|
293
|
+
stdio: {
|
|
294
|
+
stdin: 'ignore' | 'pipe' | {
|
|
295
|
+
readonly data: string;
|
|
296
|
+
};
|
|
297
|
+
stdout: 'pipe' | 'inherit' | SubprocessCollectSpec;
|
|
298
|
+
stderr: 'pipe' | 'inherit' | SubprocessCollectSpec;
|
|
299
|
+
};
|
|
300
|
+
graceMs: number;
|
|
301
|
+
signal?: AbortSignal;
|
|
302
|
+
env?: NodeJS.ProcessEnv;
|
|
303
|
+
}
|
|
304
|
+
/** Exit facts of one closed process (Node `close`-event vocabulary). */
|
|
305
|
+
interface SubprocessOutcome {
|
|
306
|
+
exitCode: number | null;
|
|
307
|
+
signal: NodeJS.Signals | null;
|
|
308
|
+
}
|
|
309
|
+
/** Offset-based, non-consuming reader over one collect-mode stream. */
|
|
310
|
+
interface SubprocessOutputReader {
|
|
311
|
+
readFrom(fromByte: number): {
|
|
312
|
+
text: string;
|
|
313
|
+
nextOffset: number;
|
|
314
|
+
lossy: boolean;
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
/** Live child-process handle rooted in its own process tree. */
|
|
318
|
+
interface SubprocessHandle {
|
|
319
|
+
readonly pid: number;
|
|
320
|
+
/** Present iff spawned with `stdin: 'pipe'` (dsh-subprocess types.d.ts:158). */
|
|
321
|
+
readonly stdin: Writable | undefined;
|
|
322
|
+
readonly stdout: Readable | undefined;
|
|
323
|
+
readonly stderr: Readable | undefined;
|
|
324
|
+
readonly collected: {
|
|
325
|
+
readonly stdout?: SubprocessOutputReader;
|
|
326
|
+
readonly stderr?: SubprocessOutputReader;
|
|
327
|
+
};
|
|
328
|
+
readonly done: Promise<SubprocessOutcome>;
|
|
329
|
+
terminate(): void;
|
|
330
|
+
waitForExit(signal?: AbortSignal): Promise<boolean>;
|
|
331
|
+
}
|
|
332
|
+
/** `ctx.subprocess` face (managed pipe-process primitive only). */
|
|
333
|
+
interface SubprocessService {
|
|
334
|
+
spawn(spec: SubprocessSpawnSpec): SubprocessHandle;
|
|
335
|
+
}
|
|
336
|
+
/** Owner scope returned by `ctx.settings.register` (read/observe subset). */
|
|
337
|
+
interface SettingsScopeFace<T> {
|
|
338
|
+
get(): T;
|
|
339
|
+
watch(callback: (next: T, prev: T) => void): () => void;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* `ctx.settings` face (namespace registration only). Source:
|
|
343
|
+
* dsh-settings SettingsProvider.register — `register(ns, schema, {base,
|
|
344
|
+
* applies})` → owner scope; the namespace brand is compile-time only, so a
|
|
345
|
+
* plain string is structurally sound. Registration rides the CALLER's
|
|
346
|
+
* fiber (service proxy binds this.ctx), so disposal is automatic.
|
|
347
|
+
*/
|
|
348
|
+
interface SettingsServiceFace {
|
|
349
|
+
register<T>(ns: string, schema: unknown, options?: {
|
|
350
|
+
base?: Partial<T>;
|
|
351
|
+
applies?: 'live' | 'restart';
|
|
352
|
+
}): SettingsScopeFace<T>;
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* The lazily-bound `ctx.agents` registry surface: M2 injection consumes
|
|
356
|
+
* `get`/`resume` (dsh-inject's {@link AgentsServiceFace}), M3 analysis
|
|
357
|
+
* consumes `create` (analysis.ts's {@link AnalysisAgentFace}). One lazy
|
|
358
|
+
* binding serves both paths — and gates both degradations.
|
|
359
|
+
*/
|
|
360
|
+
type AgentsRegistryFace = AgentsServiceFace & Pick<AnalysisAgentFace, 'create'>;
|
|
361
|
+
/**
|
|
362
|
+
* `ctx.agentDefaultModel` face (dsh-agent-default-model index.d.ts:40-56):
|
|
363
|
+
* the host's default model selection — the SAME source dsh's own entry
|
|
364
|
+
* points read when creating agents (dsh-headless `run()` passes
|
|
365
|
+
* `agentOptions: {provider, model}` from `currentSelection()`;
|
|
366
|
+
* dsh-host-apiproxy exposes it as `defaultModelSelection`). Resolved per
|
|
367
|
+
* call via reflect `get` (never a hard inject): the service is core in
|
|
368
|
+
* dsh-base compositions but the plugin must degrade honestly without it.
|
|
369
|
+
*/
|
|
370
|
+
interface AgentDefaultModelFace {
|
|
371
|
+
currentSelection(): {
|
|
372
|
+
provider: string;
|
|
373
|
+
model: string;
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
/** The plugin context with the two hard-injected services visible. */
|
|
377
|
+
type HostContext = Context & {
|
|
378
|
+
webServer: WebServerService;
|
|
379
|
+
subprocess: SubprocessService;
|
|
380
|
+
};
|
|
381
|
+
/**
|
|
382
|
+
* Assemble the M1 host half.
|
|
383
|
+
*
|
|
384
|
+
* Teardown is order-sensitive, so the whole assembly lives in ONE
|
|
385
|
+
* `ctx.effect` disposer (design §4.a: "顺序敏感拆除放同一 disposer"):
|
|
386
|
+
* supervisor first (terminates a self-hosted daemon, never an adopted one),
|
|
387
|
+
* then the reconciler (closes the subscribe stream and timers), then
|
|
388
|
+
* `routes.dispose()` (ends SSE clients, unsubscribes), and the webServer
|
|
389
|
+
* route disposer last.
|
|
390
|
+
*
|
|
391
|
+
* @param ctx - plugin context handed by the cordis loader.
|
|
392
|
+
* @param config - schema-validated composition config (defaults filled).
|
|
393
|
+
*/
|
|
394
|
+
declare function apply(ctx: HostContext, config: Config): void;
|
|
395
|
+
//#endregion
|
|
396
|
+
export { AgentDefaultModelFace, AgentsRegistryFace, Config, HostContext, SettingsScopeFace, SettingsServiceFace, SubprocessCollectSpec, SubprocessHandle, SubprocessOutcome, SubprocessOutputReader, SubprocessService, SubprocessSpawnSpec, WebServerService, apply, inject, name };
|