zcode-acp-server 0.48.0 → 0.49.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/README.md +1 -1
- package/dist/backend/adapter.d.ts +129 -0
- package/dist/backend/adapter.d.ts.map +1 -0
- package/dist/backend/adapter.js +71 -0
- package/dist/backend/adapter.js.map +1 -0
- package/dist/backend/client.d.ts +14 -103
- package/dist/backend/client.d.ts.map +1 -1
- package/dist/backend/client.js +63 -413
- package/dist/backend/client.js.map +1 -1
- package/dist/backend/index.d.ts +3 -1
- package/dist/backend/index.d.ts.map +1 -1
- package/dist/backend/index.js +2 -0
- package/dist/backend/index.js.map +1 -1
- package/dist/backend/jsonrpc-child.d.ts +128 -0
- package/dist/backend/jsonrpc-child.d.ts.map +1 -0
- package/dist/backend/jsonrpc-child.js +397 -0
- package/dist/backend/jsonrpc-child.js.map +1 -0
- package/dist/code-fingerprint.json +2 -2
- package/dist/config/options.d.ts.map +1 -1
- package/dist/config/options.js +14 -4
- package/dist/config/options.js.map +1 -1
- package/dist/handlers/session.d.ts.map +1 -1
- package/dist/handlers/session.js +9 -4
- package/dist/handlers/session.js.map +1 -1
- package/dist/handlers/slash.d.ts.map +1 -1
- package/dist/handlers/slash.js +8 -4
- package/dist/handlers/slash.js.map +1 -1
- package/dist/remote/settings-endpoint.d.ts.map +1 -1
- package/dist/remote/settings-endpoint.js +64 -1
- package/dist/remote/settings-endpoint.js.map +1 -1
- package/dist/server.d.ts +8 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +7 -0
- package/dist/server.js.map +1 -1
- package/dist/settings/workflow.d.ts +25 -0
- package/dist/settings/workflow.d.ts.map +1 -1
- package/dist/settings/workflow.js +61 -2
- package/dist/settings/workflow.js.map +1 -1
- package/docs/ARCHITECTURE.md +8 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -285,7 +285,7 @@ Thanks to everyone who has contributed (updated automatically from the
|
|
|
285
285
|
<a href="https://github.com/william0wang/zcode-acp/graphs/contributors">
|
|
286
286
|
<!-- release-please re-stamps &v= on every release: the new URL busts the
|
|
287
287
|
contrib.rocks and GitHub camo image caches. -->
|
|
288
|
-
<img src="https://contrib.rocks/image?repo=william0wang/zcode-acp&v=0.
|
|
288
|
+
<img src="https://contrib.rocks/image?repo=william0wang/zcode-acp&v=0.49.0" alt="Contributors" /> <!-- x-release-please-version -->
|
|
289
289
|
</a>
|
|
290
290
|
|
|
291
291
|
## Related Projects
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BackendAdapter — the seam between the bridge and its agent-harness backend
|
|
3
|
+
* (ADR-0023, revised 2026-09-25).
|
|
4
|
+
*
|
|
5
|
+
* One bridge process owns exactly one backend subprocess, and the capability
|
|
6
|
+
* table below is the SINGLE enforcement point for value-add surfaces: handlers
|
|
7
|
+
* consult `backendCapabilities(kind)` instead of branching on the backend.
|
|
8
|
+
* The backend-kind selection flag lands with the dsh adapter (PR2); until
|
|
9
|
+
* then every bridge is zcode and the table is all-true, so gating through it
|
|
10
|
+
* is behavior-neutral by construction.
|
|
11
|
+
*/
|
|
12
|
+
import type { ZcodeInteractionPermissionParams, ZcodeInteractionUserInputParams, ZcodeResponse } from "./types.js";
|
|
13
|
+
/** A supported backend harness. `dsh` = DeepSeek Harness (`dsh --profile acp`). */
|
|
14
|
+
export type BackendKind = "zcode" | "dsh";
|
|
15
|
+
/** Parse a user-supplied backend name; undefined when unrecognized. */
|
|
16
|
+
export declare function parseBackendKind(raw: string): BackendKind | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* Feature flags the bridge consults before registering value-add surfaces
|
|
19
|
+
* (slash commands, settings routes, auto-behaviors). Keyed off the backend
|
|
20
|
+
* KIND — not a live adapter — because registration happens at startup /
|
|
21
|
+
* initialize, before the lazy backend ever spawns. A false entry means the
|
|
22
|
+
* surface stays dark (no menu entry, no route) and an out-of-band invocation
|
|
23
|
+
* answers with a friendly downgrade message, never a raw backend error.
|
|
24
|
+
*/
|
|
25
|
+
export interface BackendCapabilities {
|
|
26
|
+
/** session/fork + /fork. */
|
|
27
|
+
fork: boolean;
|
|
28
|
+
/** session/compact + /compact. */
|
|
29
|
+
compact: boolean;
|
|
30
|
+
/** Threshold-based auto-compaction after end_turn. */
|
|
31
|
+
autoCompact: boolean;
|
|
32
|
+
/** Permission-mode config option + session/setMode + /mode. */
|
|
33
|
+
modes: boolean;
|
|
34
|
+
/** EnterPlanMode/ExitPlanMode plan flow (backend-tool driven). */
|
|
35
|
+
plans: boolean;
|
|
36
|
+
/** Form-based elicitation (AskUserQuestion / plan-review forms). */
|
|
37
|
+
elicitation: boolean;
|
|
38
|
+
/** Seatbelt sandbox wrapping (backend spawn argv). */
|
|
39
|
+
sandbox: boolean;
|
|
40
|
+
/** /mcp listing (reads the ZCode desktop config + plugins — zcode-only source). */
|
|
41
|
+
mcpListing: boolean;
|
|
42
|
+
/** Incremental streaming deltas. */
|
|
43
|
+
streaming: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Image attachments on prompts. False when the adapter drops them —
|
|
46
|
+
* advertising the capability anyway would silently eat user input.
|
|
47
|
+
*/
|
|
48
|
+
image: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* Stop needs a post-cancel drain (probe-until-idle + session/close
|
|
51
|
+
* escalation). True for zcode, whose session/stop was historically ignored;
|
|
52
|
+
* false for a backend whose cancel is a real cancel — draining it would
|
|
53
|
+
* only escalate against a live session.
|
|
54
|
+
*/
|
|
55
|
+
drain: boolean;
|
|
56
|
+
/**
|
|
57
|
+
* session/resume on an already-active session succeeds as a no-op. False
|
|
58
|
+
* means adoption paths must skip the resume RPC when the target session is
|
|
59
|
+
* already live in this backend process (the backend rejects duplicates).
|
|
60
|
+
*/
|
|
61
|
+
resumeIdempotent: boolean;
|
|
62
|
+
/** Settings API management surface (ADR-0025 route families). */
|
|
63
|
+
settings: boolean;
|
|
64
|
+
/** /workflow + /workflows slash commands (dynamic workflow, ADR-0029). */
|
|
65
|
+
workflowCommands: boolean;
|
|
66
|
+
/** Settings API dynamic-workflow route family + run poller (ADR-0029). */
|
|
67
|
+
workflowRoutes: boolean;
|
|
68
|
+
/** POST /settings/backend/restart (backend respawn orchestration). */
|
|
69
|
+
backendRestart: boolean;
|
|
70
|
+
/** Martty boot-resume banner handshake (DSH_TUI_AUTOPROMPT arming). */
|
|
71
|
+
bootResumeHandshake: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* GLM Coding Plan quota surfaces (dock refresher + pseudo-option). The
|
|
74
|
+
* /quota command and account/usage_stats get their own per-backend wiring
|
|
75
|
+
* with the dsh port (dsh pins quota to Opencode Go per ADR-0023).
|
|
76
|
+
*/
|
|
77
|
+
quota: boolean;
|
|
78
|
+
}
|
|
79
|
+
/** Capability table for a backend kind (pure — no adapter instance needed). */
|
|
80
|
+
export declare function backendCapabilities(kind: BackendKind): BackendCapabilities;
|
|
81
|
+
/** A server→client request that we must reply to. */
|
|
82
|
+
export interface ServerRequest {
|
|
83
|
+
id: number | string;
|
|
84
|
+
method: string;
|
|
85
|
+
params: ZcodeInteractionPermissionParams | ZcodeInteractionUserInputParams | Record<string, unknown>;
|
|
86
|
+
}
|
|
87
|
+
/** Listener for backend event pushes on a given session. */
|
|
88
|
+
export interface EventListener {
|
|
89
|
+
handleEvent(event: import("./types.js").ZcodeEvent): void;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* The backend seam. Concrete implementations spawn their harness over stdio
|
|
93
|
+
* and demultiplex its JSON-RPC stream; the bridge core only ever sees this.
|
|
94
|
+
* Backend creation follows the async spawn contract of ADR-0023 (revised):
|
|
95
|
+
* the SERVER packs creation policy (workflow-gate verdict, env layers,
|
|
96
|
+
* arrival responders, per-generation registry resets) and the ADAPTER owns
|
|
97
|
+
* process/wire mechanics.
|
|
98
|
+
*/
|
|
99
|
+
export interface BackendAdapter {
|
|
100
|
+
/** Feature flags for this backend's kind (see {@link backendCapabilities}). */
|
|
101
|
+
readonly capabilities: BackendCapabilities;
|
|
102
|
+
/** True once the backend's read loop is gone — further requests fail fast. */
|
|
103
|
+
get isDead(): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Synchronous request/response. Returns `{error}` on dead backend, broken
|
|
106
|
+
* pipe, or timeout — never throws.
|
|
107
|
+
*/
|
|
108
|
+
request(id: number, method: string, params?: Record<string, unknown>, timeoutMs?: number): Promise<ZcodeResponse>;
|
|
109
|
+
/** Send a message with an id but WITHOUT registering a pending response. */
|
|
110
|
+
send(method: string, params?: Record<string, unknown>): void;
|
|
111
|
+
/** Fire-and-forget notification (no id, no response). */
|
|
112
|
+
notify(method: string, params?: Record<string, unknown>): void;
|
|
113
|
+
/** Reply to a backend server→client request with a result. */
|
|
114
|
+
sendReply(id: number | string, result: unknown): void;
|
|
115
|
+
/** Reply to a backend server→client request with an error. */
|
|
116
|
+
sendError(id: number | string, code: number, message: string): void;
|
|
117
|
+
/** Non-blocking drain of pending server→client requests. */
|
|
118
|
+
pollServerRequests(): ServerRequest[];
|
|
119
|
+
/**
|
|
120
|
+
* Re-queue server→client requests that belong to a different session
|
|
121
|
+
* (prepended to preserve arrival order).
|
|
122
|
+
*/
|
|
123
|
+
requeueServerRequests(reqs: ServerRequest[]): void;
|
|
124
|
+
registerEventListener(sessionId: string, listener: EventListener): void;
|
|
125
|
+
unregisterEventListener(sessionId: string, listener: EventListener): void;
|
|
126
|
+
/** Kill the whole backend process group and wait for it to die. */
|
|
127
|
+
close(): Promise<void>;
|
|
128
|
+
}
|
|
129
|
+
//# sourceMappingURL=adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/backend/adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BackendAdapter — the seam between the bridge and its agent-harness backend
|
|
3
|
+
* (ADR-0023, revised 2026-09-25).
|
|
4
|
+
*
|
|
5
|
+
* One bridge process owns exactly one backend subprocess, and the capability
|
|
6
|
+
* table below is the SINGLE enforcement point for value-add surfaces: handlers
|
|
7
|
+
* consult `backendCapabilities(kind)` instead of branching on the backend.
|
|
8
|
+
* The backend-kind selection flag lands with the dsh adapter (PR2); until
|
|
9
|
+
* then every bridge is zcode and the table is all-true, so gating through it
|
|
10
|
+
* is behavior-neutral by construction.
|
|
11
|
+
*/
|
|
12
|
+
/** Parse a user-supplied backend name; undefined when unrecognized. */
|
|
13
|
+
export function parseBackendKind(raw) {
|
|
14
|
+
const v = raw.trim().toLowerCase();
|
|
15
|
+
if (v === "zcode" || v === "dsh")
|
|
16
|
+
return v;
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
/** zcode: every value-add surface available. */
|
|
20
|
+
const ZCODE_CAPABILITIES = Object.freeze({
|
|
21
|
+
fork: true,
|
|
22
|
+
compact: true,
|
|
23
|
+
autoCompact: true,
|
|
24
|
+
modes: true,
|
|
25
|
+
plans: true,
|
|
26
|
+
elicitation: true,
|
|
27
|
+
sandbox: true,
|
|
28
|
+
mcpListing: true,
|
|
29
|
+
streaming: true,
|
|
30
|
+
image: true,
|
|
31
|
+
drain: true,
|
|
32
|
+
resumeIdempotent: true,
|
|
33
|
+
settings: true,
|
|
34
|
+
workflowCommands: true,
|
|
35
|
+
workflowRoutes: true,
|
|
36
|
+
backendRestart: true,
|
|
37
|
+
bootResumeHandshake: true,
|
|
38
|
+
quota: true,
|
|
39
|
+
});
|
|
40
|
+
/**
|
|
41
|
+
* dsh starting point for the port (PR2): verified against
|
|
42
|
+
* @deepseek-ai/dsh 0.1.7-rc.2 (`.zcode/scratch/research-dsh-017-facts.md`) —
|
|
43
|
+
* no fork on the ACP wire, no compact/modes/plans/elicitation, committed-
|
|
44
|
+
* chunk updates only, no image attachments, session/cancel is a real cancel,
|
|
45
|
+
* session/resume rejects an already-active session.
|
|
46
|
+
*/
|
|
47
|
+
const DSH_CAPABILITIES = Object.freeze({
|
|
48
|
+
fork: false,
|
|
49
|
+
compact: false,
|
|
50
|
+
autoCompact: false,
|
|
51
|
+
modes: false,
|
|
52
|
+
plans: false,
|
|
53
|
+
elicitation: false,
|
|
54
|
+
sandbox: false,
|
|
55
|
+
mcpListing: false,
|
|
56
|
+
streaming: false,
|
|
57
|
+
image: false,
|
|
58
|
+
drain: false,
|
|
59
|
+
resumeIdempotent: false,
|
|
60
|
+
settings: false,
|
|
61
|
+
workflowCommands: false,
|
|
62
|
+
workflowRoutes: false,
|
|
63
|
+
backendRestart: false,
|
|
64
|
+
bootResumeHandshake: false,
|
|
65
|
+
quota: false,
|
|
66
|
+
});
|
|
67
|
+
/** Capability table for a backend kind (pure — no adapter instance needed). */
|
|
68
|
+
export function backendCapabilities(kind) {
|
|
69
|
+
return kind === "dsh" ? DSH_CAPABILITIES : ZCODE_CAPABILITIES;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/backend/adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAWH,uEAAuE;AACvE,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,MAAM,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACnC,IAAI,CAAC,KAAK,OAAO,IAAI,CAAC,KAAK,KAAK;QAAE,OAAO,CAAC,CAAC;IAC3C,OAAO,SAAS,CAAC;AACnB,CAAC;AAiED,gDAAgD;AAChD,MAAM,kBAAkB,GAAwB,MAAM,CAAC,MAAM,CAAC;IAC5D,IAAI,EAAE,IAAI;IACV,OAAO,EAAE,IAAI;IACb,WAAW,EAAE,IAAI;IACjB,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,WAAW,EAAE,IAAI;IACjB,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,IAAI;IAChB,SAAS,EAAE,IAAI;IACf,KAAK,EAAE,IAAI;IACX,KAAK,EAAE,IAAI;IACX,gBAAgB,EAAE,IAAI;IACtB,QAAQ,EAAE,IAAI;IACd,gBAAgB,EAAE,IAAI;IACtB,cAAc,EAAE,IAAI;IACpB,cAAc,EAAE,IAAI;IACpB,mBAAmB,EAAE,IAAI;IACzB,KAAK,EAAE,IAAI;CACZ,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,gBAAgB,GAAwB,MAAM,CAAC,MAAM,CAAC;IAC1D,IAAI,EAAE,KAAK;IACX,OAAO,EAAE,KAAK;IACd,WAAW,EAAE,KAAK;IAClB,KAAK,EAAE,KAAK;IACZ,KAAK,EAAE,KAAK;IACZ,WAAW,EAAE,KAAK;IAClB,OAAO,EAAE,KAAK;IACd,UAAU,EAAE,KAAK;IACjB,SAAS,EAAE,KAAK;IAChB,KAAK,EAAE,KAAK;IACZ,KAAK,EAAE,KAAK;IACZ,gBAAgB,EAAE,KAAK;IACvB,QAAQ,EAAE,KAAK;IACf,gBAAgB,EAAE,KAAK;IACvB,cAAc,EAAE,KAAK;IACrB,cAAc,EAAE,KAAK;IACrB,mBAAmB,EAAE,KAAK;IAC1B,KAAK,EAAE,KAAK;CACb,CAAC,CAAC;AAEH,+EAA+E;AAC/E,MAAM,UAAU,mBAAmB,CAAC,IAAiB;IACnD,OAAO,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,kBAAkB,CAAC;AAChE,CAAC"}
|
package/dist/backend/client.d.ts
CHANGED
|
@@ -1,42 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* ZCode subprocess client:
|
|
2
|
+
* ZCode subprocess client: the zcode dialect over the shared JSON-RPC transport.
|
|
3
3
|
*
|
|
4
4
|
* The ZCode app-server is launched as a subprocess (`zcode app-server --stdio`)
|
|
5
|
-
* speaking line-delimited JSON over stdio.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* - server→client requests (id + method, id not pending) → server-request queue
|
|
9
|
-
* - notifications (no id):
|
|
10
|
-
* - `session/event` → routed to the registered session listener
|
|
11
|
-
* - anything else → general notification queue
|
|
5
|
+
* speaking line-delimited JSON over stdio. It deliberately omits the `jsonrpc`
|
|
6
|
+
* field (its strict validator rejects it — see AGENTS.md), and pushes events
|
|
7
|
+
* via the `session/event` notification plus `state.updated` settings patches.
|
|
12
8
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
9
|
+
* The generic transport (read-loop multiplexer, pending-request map, watchdog,
|
|
10
|
+
* process-group lifecycle) lives in {@link JsonRpcChild}; this class only
|
|
11
|
+
* supplies the zcode dialect.
|
|
16
12
|
*/
|
|
17
|
-
import { type
|
|
18
|
-
import
|
|
19
|
-
|
|
20
|
-
export
|
|
21
|
-
|
|
22
|
-
method: string;
|
|
23
|
-
params: ZcodeInteractionPermissionParams | ZcodeInteractionUserInputParams | Record<string, unknown>;
|
|
24
|
-
}
|
|
25
|
-
/** Listener for `session/event` pushes on a given session. */
|
|
26
|
-
export interface EventListener {
|
|
27
|
-
handleEvent(event: ZcodeEvent): void;
|
|
28
|
-
}
|
|
29
|
-
export declare class ZcodeBackend {
|
|
30
|
-
readonly proc: ChildProcess;
|
|
31
|
-
private readonly pending;
|
|
32
|
-
private readonly serverRequests;
|
|
33
|
-
private readonly listeners;
|
|
34
|
-
private readerDead;
|
|
35
|
-
/** Monotonic id for fire-and-forget sends (send()). Uses a high range to
|
|
36
|
-
* avoid collisions with the server's request ids (low range). */
|
|
37
|
-
private sendIdCounter;
|
|
38
|
-
/** Watchdog process that kills the zcode group if this bridge dies (SIGKILL). */
|
|
39
|
-
private watchdog;
|
|
13
|
+
import { type BackendCapabilities, type ServerRequest } from "./adapter.js";
|
|
14
|
+
import { JsonRpcChild } from "./jsonrpc-child.js";
|
|
15
|
+
export type { EventListener, ServerRequest } from "./adapter.js";
|
|
16
|
+
export declare class ZcodeBackend extends JsonRpcChild {
|
|
17
|
+
readonly capabilities: BackendCapabilities;
|
|
40
18
|
/**
|
|
41
19
|
* Arrival-time responder for `interaction/requestProviderRuntimeHeaders`.
|
|
42
20
|
* The backend asks before EVERY model request on a zhipu-account provider,
|
|
@@ -60,74 +38,7 @@ export declare class ZcodeBackend {
|
|
|
60
38
|
*/
|
|
61
39
|
onCompactOutcome?: (sessionId: string, reason: string) => void;
|
|
62
40
|
constructor(argv: string[], env: NodeJS.ProcessEnv);
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
* bridge process disappears.
|
|
66
|
-
*
|
|
67
|
-
* The detached/kill(-pid) cleanup in `close()` only runs when the bridge
|
|
68
|
-
* exits cleanly enough for the signal handlers to fire (SIGTERM/SIGINT/etc).
|
|
69
|
-
* If the bridge is SIGKILLed (Zed force-kill on reconnect, crash, OOM), the
|
|
70
|
-
* handler never runs and the zcode subprocess group is orphaned. The
|
|
71
|
-
* watchdog closes that gap: it polls the bridge pid every 2s and, once the
|
|
72
|
-
* bridge is gone, sends SIGKILL to the zcode process group, then exits.
|
|
73
|
-
*
|
|
74
|
-
* The watchdog is its own process-group leader (detached) and `unref`'d, so
|
|
75
|
-
* it never holds the event loop open and is not part of the zcode group it
|
|
76
|
-
* kills. It self-terminates as soon as the zcode process exits, so a normal
|
|
77
|
-
* shutdown leaves no lingering watchdog.
|
|
78
|
-
*/
|
|
79
|
-
private startWatchdog;
|
|
80
|
-
private startReader;
|
|
81
|
-
private route;
|
|
82
|
-
/** Deliver a ZcodeEvent to every listener registered for its session. */
|
|
83
|
-
private dispatchEvent;
|
|
84
|
-
private resolvePending;
|
|
85
|
-
private markReaderDead;
|
|
86
|
-
registerEventListener(zcodeSid: string, listener: EventListener): void;
|
|
87
|
-
unregisterEventListener(zcodeSid: string, listener: EventListener): void;
|
|
88
|
-
/** Non-blocking drain of pending server→client requests. */
|
|
89
|
-
pollServerRequests(): ServerRequest[];
|
|
90
|
-
/**
|
|
91
|
-
* Re-queue server→client requests that belong to a different session (prepended
|
|
92
|
-
* to preserve arrival order). Used by `handleServerRequests` to put back
|
|
93
|
-
* requests it popped but doesn't own.
|
|
94
|
-
*/
|
|
95
|
-
requeueServerRequests(reqs: ServerRequest[]): void;
|
|
96
|
-
/** Reply to a zcode server→client request with a result (id + result). */
|
|
97
|
-
sendReply(id: number | string, result: unknown): void;
|
|
98
|
-
/** Reply to a zcode server→client request with an error. */
|
|
99
|
-
sendError(id: number | string, code: number, message: string): void;
|
|
100
|
-
/** Fire-and-forget notification to ZCode (no id, no response). */
|
|
101
|
-
notify(method: string, params?: Record<string, unknown>): void;
|
|
102
|
-
/**
|
|
103
|
-
* Send a message with an id but WITHOUT registering a pending response
|
|
104
|
-
* (fire-and-forget). Mirrors Python's `_backend.send({"id": ..., ...})` for
|
|
105
|
-
* `session/stop`: some backends route by id presence, so carrying an id is
|
|
106
|
-
* more robust than a bare notify. If the backend replies, the reader's
|
|
107
|
-
* `resolvePending` finds no pending entry and safely discards it.
|
|
108
|
-
*/
|
|
109
|
-
send(method: string, params?: Record<string, unknown>): void;
|
|
110
|
-
/**
|
|
111
|
-
* Synchronous request/response: register a pending promise, send, await.
|
|
112
|
-
* Other notifications arriving during the wait are routed async by the
|
|
113
|
-
* reader loop (they don't get swallowed).
|
|
114
|
-
*
|
|
115
|
-
* Returns `{error}` on dead backend, broken pipe, or timeout — never throws.
|
|
116
|
-
*/
|
|
117
|
-
request(id: number, method: string, params?: Record<string, unknown>, timeoutMs?: number): Promise<ZcodeResponse>;
|
|
118
|
-
/**
|
|
119
|
-
* Kill the whole zcode process group and wait for it to die.
|
|
120
|
-
*
|
|
121
|
-
* SIGTERM → wait up to 3s → SIGKILL if still alive. Mirrors the Python
|
|
122
|
-
* `os.killpg` + `proc.wait(3)` + SIGKILL escalation. Note `proc.killed` is
|
|
123
|
-
* NOT set by `process.kill(-pid)` (group signal), so we track liveness via
|
|
124
|
-
* `exitCode === null` instead. Async so the caller can `await` a full reap
|
|
125
|
-
* before the parent exits (an unref'd timer could be skipped on fast exit,
|
|
126
|
-
* leaving orphans).
|
|
127
|
-
*/
|
|
128
|
-
close(): Promise<void>;
|
|
129
|
-
/** Terminate the watchdog process if it is still running. */
|
|
130
|
-
private killWatchdog;
|
|
131
|
-
get isDead(): boolean;
|
|
41
|
+
protected handleNotification(method: string, params: Record<string, unknown>): void;
|
|
42
|
+
protected handleServerRequest(req: ServerRequest): boolean;
|
|
132
43
|
}
|
|
133
44
|
//# sourceMappingURL=client.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/backend/client.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/backend/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAuB,KAAK,mBAAmB,EAAE,KAAK,aAAa,EAAE,MAAM,cAAc,CAAC;AACjG,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAMlD,YAAY,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAEjE,qBAAa,YAAa,SAAQ,YAAY;IAC5C,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAAgC;IAE1E;;;;;;;;;OASG;IACH,+BAA+B,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC;IAC3F;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;gBAEnD,IAAI,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU;IAWlD,SAAS,CAAC,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IAiCnF,SAAS,CAAC,mBAAmB,CAAC,GAAG,EAAE,aAAa,GAAG,OAAO;CA4B3D"}
|