@wrongstack/acp 0.273.1 → 0.275.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 +376 -0
- package/dist/acp-subagent-runner-BAlo23L-.d.ts +644 -0
- package/dist/acp-v1-BxskPsdo.d.ts +520 -0
- package/dist/agent.d.ts +34 -61
- package/dist/agent.js +796 -32
- package/dist/agent.js.map +1 -1
- package/dist/client.d.ts +3 -2
- package/dist/client.js +779 -112
- package/dist/client.js.map +1 -1
- package/dist/index-DEEYyEpu.d.ts +54 -0
- package/dist/index.d.ts +186 -227
- package/dist/index.js +1881 -286
- package/dist/index.js.map +1 -1
- package/dist/sdk.d.ts +12 -0
- package/dist/sdk.js +3350 -0
- package/dist/sdk.js.map +1 -0
- package/dist/server-agent-turn-C3U0lhA-.d.ts +163 -0
- package/dist/terminal-server-P9KpMZTT.d.ts +99 -0
- package/dist/{tools-registry-BCf8evEG.d.ts → tools-registry-D2xdbzN7.d.ts} +1 -1
- package/dist/wrongstack-acp-agent-nzrqmJnc.d.ts +341 -0
- package/dist/wrongstack-acp-agent.d.ts +2 -2
- package/dist/wrongstack-acp-agent.js +426 -26
- package/dist/wrongstack-acp-agent.js.map +1 -1
- package/package.json +7 -2
- package/dist/index-BvPqJHhm.d.ts +0 -119
- package/dist/stdio-transport-CsFr8JzC.d.ts +0 -205
- package/dist/wrongstack-acp-agent-Dv-A0bEm.d.ts +0 -310
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
import { d as SessionState, g as RunTurnApi, R as RunTurn, b as RunTurnResult } from './wrongstack-acp-agent-nzrqmJnc.js';
|
|
2
|
+
import { Agent } from '@wrongstack/core';
|
|
3
|
+
|
|
4
|
+
/** A persisted conversation turn (user/agent message chunk) for replay. */
|
|
5
|
+
interface PersistedHistoryUpdate {
|
|
6
|
+
sessionUpdate: string;
|
|
7
|
+
content: unknown;
|
|
8
|
+
}
|
|
9
|
+
/** A persisted session: metadata + replayable conversation history. */
|
|
10
|
+
interface PersistedSession extends Partial<SessionState> {
|
|
11
|
+
history?: PersistedHistoryUpdate[] | undefined;
|
|
12
|
+
}
|
|
13
|
+
interface SessionStoreOptions {
|
|
14
|
+
/** Directory to store session files. Defaults to a temp dir. */
|
|
15
|
+
dir?: string | undefined;
|
|
16
|
+
}
|
|
17
|
+
declare class ACPSessionStore {
|
|
18
|
+
private readonly dir;
|
|
19
|
+
/**
|
|
20
|
+
* Memoized result of the first successful `init()`. Saved sessions
|
|
21
|
+
* are the hot path — calling `mkdir(..., {recursive:true})` on every
|
|
22
|
+
* turn adds an avoidable syscall to the per-prompt persistence flow.
|
|
23
|
+
* Cleared automatically if the directory disappears between calls.
|
|
24
|
+
*/
|
|
25
|
+
private initialized;
|
|
26
|
+
constructor(opts?: SessionStoreOptions);
|
|
27
|
+
/** Ensure the store directory exists. Memoized — only mkdirs once. */
|
|
28
|
+
init(): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Persist a session state (and optionally its conversation history) to
|
|
31
|
+
* disk. Returns the session id. `history` enables cross-restart
|
|
32
|
+
* `session/load` replay.
|
|
33
|
+
*/
|
|
34
|
+
save(state: SessionState, history?: PersistedHistoryUpdate[]): Promise<string>;
|
|
35
|
+
/** Load a persisted session (metadata + history) from disk, or null. */
|
|
36
|
+
load(sessionId: string): Promise<PersistedSession | null>;
|
|
37
|
+
/** List all persisted sessions. */
|
|
38
|
+
list(): Promise<Array<{
|
|
39
|
+
id: string;
|
|
40
|
+
updatedAt: string;
|
|
41
|
+
}>>;
|
|
42
|
+
/** Sidecar path that stores `{id, updatedAt}` for every saved session. */
|
|
43
|
+
private indexPath;
|
|
44
|
+
/** Read the sidecar index. Returns `null` when missing or unreadable. */
|
|
45
|
+
private readIndex;
|
|
46
|
+
/** Atomically replace the sidecar index with the supplied entries. */
|
|
47
|
+
private writeIndex;
|
|
48
|
+
/** Update one entry in the index, adding it if missing. Best-effort. */
|
|
49
|
+
private updateIndex;
|
|
50
|
+
/** Delete a session file. */
|
|
51
|
+
delete(sessionId: string): Promise<void>;
|
|
52
|
+
/** Get the store directory path. */
|
|
53
|
+
getDirectory(): string;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* ACPServerAgentTurn — `RunTurn` adapter for the v1 server side.
|
|
58
|
+
*
|
|
59
|
+
* Wires the ACP v1 server (`ACPProtocolHandler`) to a core `Agent`.
|
|
60
|
+
* Each session gets its own `Agent` instance (per spec: sessions are
|
|
61
|
+
* isolated; sharing agents across sessions would defeat isolation).
|
|
62
|
+
* The agent is created lazily on the first `session/prompt` and
|
|
63
|
+
* torn down when the server is closed or the session is removed.
|
|
64
|
+
*
|
|
65
|
+
* The adapter:
|
|
66
|
+
* - converts the ACP `ContentBlock[]` prompt into a single string
|
|
67
|
+
* (concatenating text blocks; non-text blocks are recorded as a
|
|
68
|
+
* note in the prompt — future work can route images / audio to
|
|
69
|
+
* the appropriate provider)
|
|
70
|
+
* - calls `agent.run(prompt, {signal})` to drive the core loop
|
|
71
|
+
* - captures the agent's text result and emits it as one or more
|
|
72
|
+
* `agent_message_chunk` notifications
|
|
73
|
+
* - maps the agent's stop semantics to a v1 `StopReason`
|
|
74
|
+
*
|
|
75
|
+
* Streaming: the core `Agent` API is not currently token-streamed
|
|
76
|
+
* through this surface (its `run()` returns a final `RunResult`).
|
|
77
|
+
* v1 clients expect text deltas, but most implementations batch
|
|
78
|
+
* them — a single chunk per turn is acceptable. A future
|
|
79
|
+
* enhancement can use the Agent's `Renderer` interface to capture
|
|
80
|
+
* deltas as they're written, then forward them as multiple chunks.
|
|
81
|
+
*
|
|
82
|
+
* Scope: the adapter is deliberately minimal. It does NOT:
|
|
83
|
+
* - model the full conversation history across turns (the v1 spec
|
|
84
|
+
* leaves this to the agent; on the next prompt we re-feed the
|
|
85
|
+
* latest user message and the agent handles its own history)
|
|
86
|
+
* - use the agent's tool registry, permission policy, or
|
|
87
|
+
* extensions (this adapter is the lowest-fidelity integration;
|
|
88
|
+
* a future PR can wire a richer session-aware agent)
|
|
89
|
+
* - stream deltas token-by-token (see "Streaming" above)
|
|
90
|
+
*
|
|
91
|
+
* Cancellation: the parent `AbortSignal` propagates through
|
|
92
|
+
* `agent.run({signal})` and the underlying provider call observes
|
|
93
|
+
* it. On abort, the adapter maps the resulting `AbortError` to
|
|
94
|
+
* `{stopReason: 'cancelled'}`.
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
interface ACPServerAgentTurnOptions {
|
|
98
|
+
/**
|
|
99
|
+
* Factory that creates a fresh `Agent` for a given session.
|
|
100
|
+
* Called once per session on the first `session/prompt` turn.
|
|
101
|
+
* The factory must isolate each agent — sharing one agent
|
|
102
|
+
* across sessions would defeat v1's session-isolation model.
|
|
103
|
+
*
|
|
104
|
+
* `api` (when provided) is the client-callback surface: ask the client
|
|
105
|
+
* for permission, and use the client's filesystem/terminal when it
|
|
106
|
+
* advertises those capabilities. A factory that wires it builds a
|
|
107
|
+
* client-backed permission policy and ACP-backed fs/terminal tools
|
|
108
|
+
* instead of silently auto-approving against the local disk.
|
|
109
|
+
*/
|
|
110
|
+
agentFor: (sessionId: string, cwd: string, api?: RunTurnApi) => Promise<Agent> | Agent;
|
|
111
|
+
/**
|
|
112
|
+
* Hard wall-clock cap for one turn. The agent's own provider
|
|
113
|
+
* timeout is layered under this; this cap is a safety belt.
|
|
114
|
+
* Default 5 minutes.
|
|
115
|
+
*/
|
|
116
|
+
timeoutMs?: number | undefined;
|
|
117
|
+
}
|
|
118
|
+
/** A recorded conversation turn, replayable on `session/load`. */
|
|
119
|
+
interface SessionReplayUpdate {
|
|
120
|
+
sessionUpdate: 'user_message_chunk' | 'agent_message_chunk';
|
|
121
|
+
content: {
|
|
122
|
+
type: 'text';
|
|
123
|
+
text: string;
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* A `RunTurn` that also exposes the recorded per-session history so the
|
|
128
|
+
* server can replay it on `session/load`.
|
|
129
|
+
*/
|
|
130
|
+
interface ACPServerAgentTurn {
|
|
131
|
+
(input: Parameters<RunTurn>[0], emit: Parameters<RunTurn>[1], api?: Parameters<RunTurn>[2]): Promise<RunTurnResult>;
|
|
132
|
+
/** Recorded user/agent text turns for a session, in order. */
|
|
133
|
+
replay(sessionId: string): SessionReplayUpdate[];
|
|
134
|
+
/**
|
|
135
|
+
* Seed a session's history (from a durable store on cold `session/load`)
|
|
136
|
+
* so `replay()` returns it AND the next-created `Agent` for the session is
|
|
137
|
+
* primed with the prior conversation as model context — not just the
|
|
138
|
+
* client UI. Call before the first post-load `session/prompt`.
|
|
139
|
+
*/
|
|
140
|
+
seed(sessionId: string, history: ReadonlyArray<{
|
|
141
|
+
sessionUpdate: string;
|
|
142
|
+
content: unknown;
|
|
143
|
+
}>): void;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Build a `RunTurn` that owns per-session `Agent` instances and
|
|
147
|
+
* delegates each turn to the appropriate agent. The returned
|
|
148
|
+
* function is reusable across sessions — the agents are kept in a
|
|
149
|
+
* Map keyed by `sessionId`. It also records each turn's user/agent
|
|
150
|
+
* text so the server can replay history on `session/load` (see
|
|
151
|
+
* `.replay(sessionId)`).
|
|
152
|
+
*/
|
|
153
|
+
declare function makeACPServerAgentTurn(opts: ACPServerAgentTurnOptions): ACPServerAgentTurn;
|
|
154
|
+
/**
|
|
155
|
+
* Tear down the agents and timers held by a turn factory. The
|
|
156
|
+
* server's `close()` should call this so child connections don't
|
|
157
|
+
* outlive the server.
|
|
158
|
+
*/
|
|
159
|
+
declare function disposeACPServerAgentTurn(opts: {
|
|
160
|
+
agents: Map<string, Agent>;
|
|
161
|
+
}): Promise<void>;
|
|
162
|
+
|
|
163
|
+
export { type ACPServerAgentTurnOptions as A, type PersistedSession as P, type SessionStoreOptions as S, ACPSessionStore as a, disposeACPServerAgentTurn as d, makeACPServerAgentTurn as m };
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
interface FileServerOptions {
|
|
2
|
+
/** Absolute path; only files under this root are accessible. */
|
|
3
|
+
projectRoot: string;
|
|
4
|
+
/** Per-call timeout, default 30s. */
|
|
5
|
+
timeoutMs?: number;
|
|
6
|
+
}
|
|
7
|
+
interface ReadFileParams {
|
|
8
|
+
sessionId: string;
|
|
9
|
+
path: string;
|
|
10
|
+
}
|
|
11
|
+
interface WriteFileParams {
|
|
12
|
+
sessionId: string;
|
|
13
|
+
path: string;
|
|
14
|
+
content: string;
|
|
15
|
+
}
|
|
16
|
+
type FsErrorCode = 'ENOENT' | 'EACCES' | 'OUTSIDE_ROOT' | 'TIMEOUT' | 'INVALID_PATH';
|
|
17
|
+
/**
|
|
18
|
+
* Thrown for protocol-level rejections (path outside root, etc.).
|
|
19
|
+
* The session converts these into JSON-RPC error responses.
|
|
20
|
+
*/
|
|
21
|
+
declare class FsError extends Error {
|
|
22
|
+
readonly code: FsErrorCode;
|
|
23
|
+
readonly path: string;
|
|
24
|
+
constructor(code: FsErrorCode, path: string, message: string);
|
|
25
|
+
}
|
|
26
|
+
declare class FileServer {
|
|
27
|
+
private readonly root;
|
|
28
|
+
private readonly timeoutMs;
|
|
29
|
+
constructor(opts: FileServerOptions);
|
|
30
|
+
/** Read a text file. Returns the content as a string. */
|
|
31
|
+
readTextFile(params: ReadFileParams): Promise<{
|
|
32
|
+
content: string;
|
|
33
|
+
}>;
|
|
34
|
+
/** Write a text file. Atomic via write-then-rename. */
|
|
35
|
+
writeTextFile(params: WriteFileParams): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Resolve a path; throw `FsError('OUTSIDE_ROOT')` if the result is
|
|
38
|
+
* not under the project root. Symlinks are not followed here — we
|
|
39
|
+
* operate on the textual path. A future hardening pass can
|
|
40
|
+
* `fs.realpath` each access to catch symlink escapes.
|
|
41
|
+
*/
|
|
42
|
+
private resolveInside;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
interface TerminalServerOptions {
|
|
46
|
+
projectRoot: string;
|
|
47
|
+
/** Hard cap on per-command wall-clock. Default 5 minutes. */
|
|
48
|
+
commandTimeoutMs?: number;
|
|
49
|
+
/** Bytes of output to retain per terminal. Default 1 MiB. */
|
|
50
|
+
outputByteLimit?: number;
|
|
51
|
+
/** Optional abort signal that kills ALL active terminals. */
|
|
52
|
+
signal?: AbortSignal;
|
|
53
|
+
}
|
|
54
|
+
declare class TerminalServer {
|
|
55
|
+
private readonly terminals;
|
|
56
|
+
private readonly projectRoot;
|
|
57
|
+
private readonly commandTimeoutMs;
|
|
58
|
+
private readonly outputByteLimit;
|
|
59
|
+
private nextId;
|
|
60
|
+
constructor(opts: TerminalServerOptions);
|
|
61
|
+
/** Spawn a new terminal. Returns the agent-facing id. */
|
|
62
|
+
create(params: {
|
|
63
|
+
sessionId: string;
|
|
64
|
+
command: string;
|
|
65
|
+
args?: string[];
|
|
66
|
+
env?: {
|
|
67
|
+
name: string;
|
|
68
|
+
value: string;
|
|
69
|
+
}[];
|
|
70
|
+
cwd?: string;
|
|
71
|
+
outputByteLimit?: number;
|
|
72
|
+
}): {
|
|
73
|
+
terminalId: string;
|
|
74
|
+
};
|
|
75
|
+
/** Return captured output and (if available) the exit status. */
|
|
76
|
+
output(terminalId: string): {
|
|
77
|
+
output: string;
|
|
78
|
+
truncated: boolean;
|
|
79
|
+
exitStatus?: {
|
|
80
|
+
exitCode: number | null;
|
|
81
|
+
signal: string | null;
|
|
82
|
+
};
|
|
83
|
+
};
|
|
84
|
+
/** Block until the process exits. Resolves with the exit status. */
|
|
85
|
+
waitForExit(terminalId: string): Promise<{
|
|
86
|
+
exitCode: number | null;
|
|
87
|
+
signal: string | null;
|
|
88
|
+
}>;
|
|
89
|
+
/** Kill the process but keep the terminal record (agent can still read output). */
|
|
90
|
+
kill(terminalId: string): void;
|
|
91
|
+
/** Kill the process if alive and remove the record. */
|
|
92
|
+
release(terminalId: string): void;
|
|
93
|
+
/** Kill all active terminals. Used on session close. */
|
|
94
|
+
releaseAll(): void;
|
|
95
|
+
private resolveCwd;
|
|
96
|
+
private buildEnv;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export { FileServer as F, type ReadFileParams as R, TerminalServer as T, type WriteFileParams as W, type FileServerOptions as a, FsError as b, type FsErrorCode as c, type TerminalServerOptions as d };
|
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
import { a as AgentServerTransport, C as ContentBlock, T as ToolKind, P as PermissionOption, R as RequestPermissionOutcome, e as StopReason, f as PlanEntry, U as UsageCost } from './acp-v1-BxskPsdo.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* ACP v1 server-side protocol handler.
|
|
5
|
+
*
|
|
6
|
+
* Receives JSON-RPC requests from an external ACP client (Zed, JetBrains
|
|
7
|
+
* Junie, VS Code ACP extension, etc.) over stdio and answers them per the
|
|
8
|
+
* v1 spec. See https://agentclientprotocol.com/protocol/v1/overview.
|
|
9
|
+
*
|
|
10
|
+
* Supported methods
|
|
11
|
+
* ─────────────────
|
|
12
|
+
* - initialize — handshake
|
|
13
|
+
* - authenticate — optional, no-op when auth isn't required
|
|
14
|
+
* - session/new — create a session
|
|
15
|
+
* - session/load — restore a session by id
|
|
16
|
+
* - session/prompt — run one turn, stream session/update
|
|
17
|
+
* notifications, return stopReason
|
|
18
|
+
* - session/cancel — notification (no response); cancels the
|
|
19
|
+
* in-flight turn on the target session
|
|
20
|
+
* - session/set_mode — change the active mode for a session
|
|
21
|
+
* - session/set_config_option — change a config option value
|
|
22
|
+
* - session/list — list known sessions
|
|
23
|
+
*
|
|
24
|
+
* Method execution
|
|
25
|
+
* ────────────────
|
|
26
|
+
* The handler is transport-agnostic; it sends responses via the
|
|
27
|
+
* `AgentServerTransport` injected at construction. The actual
|
|
28
|
+
* agent-loop work for a `session/prompt` turn is delegated to the
|
|
29
|
+
* caller-provided `runTurn` callback, which receives the prompt
|
|
30
|
+
* blocks and the per-turn AbortSignal and resolves with the final
|
|
31
|
+
* stopReason. Updates are streamed via the `emit` callback passed
|
|
32
|
+
* to `runTurn`; the handler wraps each as a `session/update`
|
|
33
|
+
* notification.
|
|
34
|
+
*
|
|
35
|
+
* This separation keeps the handler unit-testable: tests can supply
|
|
36
|
+
* a fake `runTurn` that yields a canned sequence of updates, and
|
|
37
|
+
* assert on the JSON-RPC traffic the handler produces. A real
|
|
38
|
+
* production caller wires `runTurn` to a core `Agent` instance.
|
|
39
|
+
*
|
|
40
|
+
* Concurrency
|
|
41
|
+
* ───────────
|
|
42
|
+
* Each session is single-threaded (one active turn at a time). The
|
|
43
|
+
* handler keeps a per-session AbortController so a `session/cancel`
|
|
44
|
+
* notification can stop the running turn mid-stream without tearing
|
|
45
|
+
* down the session. Multiple sessions can be active concurrently.
|
|
46
|
+
*/
|
|
47
|
+
|
|
48
|
+
declare const WRONGSTACK_VERSION = "0.274.1";
|
|
49
|
+
interface RunTurnInput {
|
|
50
|
+
sessionId: string;
|
|
51
|
+
/** Content blocks the client sent. */
|
|
52
|
+
prompt: readonly ContentBlock[];
|
|
53
|
+
/** Cancelled when the client sends `session/cancel` for this session. */
|
|
54
|
+
signal: AbortSignal;
|
|
55
|
+
}
|
|
56
|
+
interface RunTurnResult {
|
|
57
|
+
stopReason: StopReason;
|
|
58
|
+
/** Optional summary text the agent produced. */
|
|
59
|
+
text?: string;
|
|
60
|
+
plan?: PlanEntry[];
|
|
61
|
+
usage?: {
|
|
62
|
+
used: number;
|
|
63
|
+
size: number;
|
|
64
|
+
cost?: UsageCost | undefined;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* A tool-call permission request the agent surfaces to the client.
|
|
69
|
+
*/
|
|
70
|
+
interface RunTurnPermissionRequest {
|
|
71
|
+
toolCall: {
|
|
72
|
+
toolCallId: string;
|
|
73
|
+
title: string;
|
|
74
|
+
kind?: ToolKind | undefined;
|
|
75
|
+
};
|
|
76
|
+
options: PermissionOption[];
|
|
77
|
+
}
|
|
78
|
+
/** Client filesystem/terminal capabilities advertised at initialize. */
|
|
79
|
+
interface ClientCapabilities {
|
|
80
|
+
fs?: {
|
|
81
|
+
readTextFile?: boolean | undefined;
|
|
82
|
+
writeTextFile?: boolean | undefined;
|
|
83
|
+
} | undefined;
|
|
84
|
+
terminal?: boolean | undefined;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Client-callback API handed to `runTurn`. Lets the agent's tools call back
|
|
88
|
+
* into the connected ACP client — ask for permission, and (when the client
|
|
89
|
+
* advertises the capability) use the client's filesystem and terminal so the
|
|
90
|
+
* editor's view (including unsaved buffers) is the source of truth.
|
|
91
|
+
*/
|
|
92
|
+
interface RunTurnApi {
|
|
93
|
+
/**
|
|
94
|
+
* Ask the connected ACP client to approve/reject a tool call via the
|
|
95
|
+
* `session/request_permission` method. Resolves with the client's
|
|
96
|
+
* outcome. Rejects if no client channel is available or the request
|
|
97
|
+
* times out — the caller decides the fallback.
|
|
98
|
+
*/
|
|
99
|
+
requestPermission(req: RunTurnPermissionRequest): Promise<RequestPermissionOutcome>;
|
|
100
|
+
/** Capabilities the client advertised at initialize — gate tool wiring on these. */
|
|
101
|
+
clientCapabilities: ClientCapabilities;
|
|
102
|
+
/** Read a text file from the client's filesystem (`fs/read_text_file`). */
|
|
103
|
+
readTextFile(params: {
|
|
104
|
+
path: string;
|
|
105
|
+
line?: number;
|
|
106
|
+
limit?: number;
|
|
107
|
+
}): Promise<string>;
|
|
108
|
+
/** Write a text file in the client's filesystem (`fs/write_text_file`). */
|
|
109
|
+
writeTextFile(params: {
|
|
110
|
+
path: string;
|
|
111
|
+
content: string;
|
|
112
|
+
}): Promise<void>;
|
|
113
|
+
/**
|
|
114
|
+
* Run a command in the client's terminal (`terminal/create` →
|
|
115
|
+
* `wait_for_exit` → `output` → `release`) and resolve with the combined
|
|
116
|
+
* output and exit code.
|
|
117
|
+
*/
|
|
118
|
+
runTerminal(params: {
|
|
119
|
+
command: string;
|
|
120
|
+
args?: string[] | undefined;
|
|
121
|
+
cwd?: string | undefined;
|
|
122
|
+
}): Promise<{
|
|
123
|
+
output: string;
|
|
124
|
+
exitCode: number | null;
|
|
125
|
+
}>;
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* The agent's per-turn work. Streams `SessionUpdate` notifications to
|
|
129
|
+
* `emit` and resolves with the final stopReason. Errors thrown from
|
|
130
|
+
* this iterable are converted to a `prompt_failed` JSON-RPC error.
|
|
131
|
+
*
|
|
132
|
+
* `api` is an optional client-callback surface (permission requests).
|
|
133
|
+
* Older runTurn implementations that ignore it keep working unchanged.
|
|
134
|
+
*/
|
|
135
|
+
type RunTurn = (input: RunTurnInput, emit: (update: unknown) => void, api?: RunTurnApi) => Promise<RunTurnResult>;
|
|
136
|
+
interface SessionState {
|
|
137
|
+
id: string;
|
|
138
|
+
cwd: string;
|
|
139
|
+
/** Per-turn abort signal — aborted when the session is cancelled or closed. */
|
|
140
|
+
abort: AbortController;
|
|
141
|
+
/** Active mode, advertised to the client in current_mode_update. */
|
|
142
|
+
modeId: string;
|
|
143
|
+
/** Created at, for session/list ordering. */
|
|
144
|
+
createdAt: string;
|
|
145
|
+
/** Last activity timestamp, for session/info_update. */
|
|
146
|
+
updatedAt: string;
|
|
147
|
+
/** Optional human title. */
|
|
148
|
+
title?: string;
|
|
149
|
+
}
|
|
150
|
+
/** MCP-style session mode advertised in current_mode_update. */
|
|
151
|
+
interface SessionMode {
|
|
152
|
+
id: string;
|
|
153
|
+
name: string;
|
|
154
|
+
description?: string | undefined;
|
|
155
|
+
}
|
|
156
|
+
interface SessionConfigOption {
|
|
157
|
+
id: string;
|
|
158
|
+
name: string;
|
|
159
|
+
type: 'select' | string;
|
|
160
|
+
currentValue: string;
|
|
161
|
+
options: {
|
|
162
|
+
value: string;
|
|
163
|
+
name: string;
|
|
164
|
+
description?: string | undefined;
|
|
165
|
+
}[];
|
|
166
|
+
}
|
|
167
|
+
interface ProtocolHandlerOptions {
|
|
168
|
+
transport: AgentServerTransport;
|
|
169
|
+
/** Where the server is running; used for new sessions' default cwd. */
|
|
170
|
+
defaultCwd: string;
|
|
171
|
+
/** Agent's per-turn implementation. */
|
|
172
|
+
runTurn: RunTurn;
|
|
173
|
+
/**
|
|
174
|
+
* Optional callbacks for the lifecycle events the server should
|
|
175
|
+
* surface to the client. All default to no-ops.
|
|
176
|
+
*/
|
|
177
|
+
onSessionNew?: ((state: SessionState) => void) | undefined;
|
|
178
|
+
/** Static list of available modes (advertised to clients). */
|
|
179
|
+
modes?: readonly SessionMode[] | undefined;
|
|
180
|
+
/** Static list of config options. */
|
|
181
|
+
configOptions?: readonly SessionConfigOption[] | undefined;
|
|
182
|
+
/** Agent name advertised in initialize. */
|
|
183
|
+
agentName?: string | undefined;
|
|
184
|
+
/**
|
|
185
|
+
* Optional source of replayable conversation history for `session/load`.
|
|
186
|
+
* Returns the `session/update` payloads (user/agent message chunks) to
|
|
187
|
+
* stream back to the client before the load response. Wired from
|
|
188
|
+
* `makeACPServerAgentTurn(...).replay`.
|
|
189
|
+
*/
|
|
190
|
+
replayFor?: ((sessionId: string) => Array<{
|
|
191
|
+
sessionUpdate: string;
|
|
192
|
+
content: unknown;
|
|
193
|
+
}>) | undefined;
|
|
194
|
+
/**
|
|
195
|
+
* Optional hook to prime the turn engine's session history on cold
|
|
196
|
+
* `session/load` (server restart). Wired from `makeACPServerAgentTurn(...).seed`
|
|
197
|
+
* — it re-feeds the persisted conversation into the next-created Agent so
|
|
198
|
+
* the model resumes, not just the client UI.
|
|
199
|
+
*/
|
|
200
|
+
seedFor?: ((sessionId: string, history: Array<{
|
|
201
|
+
sessionUpdate: string;
|
|
202
|
+
content: unknown;
|
|
203
|
+
}>) => void) | undefined;
|
|
204
|
+
/**
|
|
205
|
+
* Optional durable session store. When set, sessions + their recorded
|
|
206
|
+
* history are persisted on create/prompt and restored on `session/load`,
|
|
207
|
+
* so a reconnecting client can resume after a server restart.
|
|
208
|
+
* (Structural type — `ACPSessionStore` satisfies it without a value import.)
|
|
209
|
+
*/
|
|
210
|
+
store?: SessionPersistence | undefined;
|
|
211
|
+
}
|
|
212
|
+
/** Minimal durable-store contract the handler uses (ACPSessionStore satisfies it). */
|
|
213
|
+
interface SessionPersistence {
|
|
214
|
+
save(state: SessionState, history?: Array<{
|
|
215
|
+
sessionUpdate: string;
|
|
216
|
+
content: unknown;
|
|
217
|
+
}>): Promise<unknown>;
|
|
218
|
+
load(sessionId: string): Promise<(Partial<SessionState> & {
|
|
219
|
+
history?: Array<{
|
|
220
|
+
sessionUpdate: string;
|
|
221
|
+
content: unknown;
|
|
222
|
+
}> | undefined;
|
|
223
|
+
}) | null>;
|
|
224
|
+
}
|
|
225
|
+
declare class ACPProtocolHandler {
|
|
226
|
+
private readonly transport;
|
|
227
|
+
private readonly defaultCwd;
|
|
228
|
+
private readonly runTurn;
|
|
229
|
+
private readonly onSessionNew;
|
|
230
|
+
private readonly modes;
|
|
231
|
+
private readonly configOptions;
|
|
232
|
+
private readonly agentName;
|
|
233
|
+
private readonly replayFor;
|
|
234
|
+
private readonly seedFor;
|
|
235
|
+
private readonly store;
|
|
236
|
+
private initialized;
|
|
237
|
+
private clientCapabilities;
|
|
238
|
+
private readonly sessions;
|
|
239
|
+
private nextId;
|
|
240
|
+
private readonly pendingOut;
|
|
241
|
+
private nextOutId;
|
|
242
|
+
constructor(opts: ProtocolHandlerOptions);
|
|
243
|
+
/**
|
|
244
|
+
* Send a request to the client and await its response. Used for
|
|
245
|
+
* server-initiated calls like `session/request_permission`. Rejects on
|
|
246
|
+
* timeout or transport error so the caller can pick a safe fallback.
|
|
247
|
+
*/
|
|
248
|
+
private request;
|
|
249
|
+
private maybeResolvePending;
|
|
250
|
+
/**
|
|
251
|
+
* Process one inbound message. Returns true if this was a terminal
|
|
252
|
+
* message (rare; reserved for future use by the server's own
|
|
253
|
+
* shutdown signal).
|
|
254
|
+
*/
|
|
255
|
+
handleMessage(msg: unknown): Promise<boolean>;
|
|
256
|
+
/** Abort all active turns and drop session state. */
|
|
257
|
+
close(): void;
|
|
258
|
+
private handleRequest;
|
|
259
|
+
private handleInitialize;
|
|
260
|
+
private handleAuthenticate;
|
|
261
|
+
private handleLogout;
|
|
262
|
+
private handleSessionNew;
|
|
263
|
+
private handleSessionLoad;
|
|
264
|
+
private handleSessionResume;
|
|
265
|
+
private handleSessionClose;
|
|
266
|
+
private handleSessionDelete;
|
|
267
|
+
private handleSessionFork;
|
|
268
|
+
private handleProvidersList;
|
|
269
|
+
private handleProvidersSet;
|
|
270
|
+
private handleProvidersDisable;
|
|
271
|
+
private handleMcpMessage;
|
|
272
|
+
private handleSessionPrompt;
|
|
273
|
+
private handleSetMode;
|
|
274
|
+
private handleSetConfigOption;
|
|
275
|
+
private handleSessionList;
|
|
276
|
+
private handleNotification;
|
|
277
|
+
private sendNotification;
|
|
278
|
+
/** Best-effort durable persistence of a session + its recorded history. */
|
|
279
|
+
private persist;
|
|
280
|
+
private sendError;
|
|
281
|
+
private allocId;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
interface WrongStackACPServerOptions {
|
|
285
|
+
runTurn?: RunTurn | undefined;
|
|
286
|
+
defaultCwd?: string | undefined;
|
|
287
|
+
agentName?: string | undefined;
|
|
288
|
+
/**
|
|
289
|
+
* Transport mode. 'stdio' (default) communicates over stdin/stdout.
|
|
290
|
+
* When a number is provided, the server listens as an HTTP server on
|
|
291
|
+
* that port, accepting Streamable HTTP (JSON-RPC over HTTP POST).
|
|
292
|
+
*/
|
|
293
|
+
transport?: 'stdio' | number | undefined;
|
|
294
|
+
/** Host for HTTP transport. Defaults to '127.0.0.1'. */
|
|
295
|
+
host?: string | undefined;
|
|
296
|
+
/** Emit the pre-v1 startup marker on stdio. Defaults to false. */
|
|
297
|
+
legacyStartupMarker?: boolean | undefined;
|
|
298
|
+
/**
|
|
299
|
+
* Conversation-history source for `session/load` replay. Pass
|
|
300
|
+
* `makeACPServerAgentTurn(...).replay` here so a reconnecting client
|
|
301
|
+
* gets prior turns streamed back.
|
|
302
|
+
*/
|
|
303
|
+
replayFor?: ((sessionId: string) => Array<{
|
|
304
|
+
sessionUpdate: string;
|
|
305
|
+
content: unknown;
|
|
306
|
+
}>) | undefined;
|
|
307
|
+
/**
|
|
308
|
+
* Cold-load seed hook. Pass `makeACPServerAgentTurn(...).seed` so a
|
|
309
|
+
* restored session's Agent resumes the model context, not just the UI.
|
|
310
|
+
*/
|
|
311
|
+
seedFor?: ((sessionId: string, history: Array<{
|
|
312
|
+
sessionUpdate: string;
|
|
313
|
+
content: unknown;
|
|
314
|
+
}>) => void) | undefined;
|
|
315
|
+
/**
|
|
316
|
+
* Durable session store. When set, sessions + history are persisted and
|
|
317
|
+
* restored across restarts for `session/load`. Pass an `ACPSessionStore`.
|
|
318
|
+
*/
|
|
319
|
+
store?: SessionPersistence | undefined;
|
|
320
|
+
}
|
|
321
|
+
declare class WrongStackACPServer {
|
|
322
|
+
private readonly transport;
|
|
323
|
+
private readonly handler;
|
|
324
|
+
private readonly options;
|
|
325
|
+
/** HTTP server when transport mode is HTTP. */
|
|
326
|
+
private httpServer;
|
|
327
|
+
private running;
|
|
328
|
+
constructor(opts?: WrongStackACPServerOptions);
|
|
329
|
+
/**
|
|
330
|
+
* Start the server. Mode depends on `options.transport`:
|
|
331
|
+
* - 'stdio' (default): reads JSON-RPC from stdin, writes to stdout.
|
|
332
|
+
* - number: listens as HTTP on the given port.
|
|
333
|
+
*/
|
|
334
|
+
start(): Promise<void>;
|
|
335
|
+
private startStdio;
|
|
336
|
+
private startHttp;
|
|
337
|
+
/** Stop the server. */
|
|
338
|
+
stop(): void;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
export { ACPProtocolHandler as A, type ClientCapabilities as C, type ProtocolHandlerOptions as P, type RunTurn as R, type SessionConfigOption as S, WRONGSTACK_VERSION as W, type RunTurnInput as a, type RunTurnResult as b, type SessionMode as c, type SessionState as d, WrongStackACPServer as e, type WrongStackACPServerOptions as f, type RunTurnApi as g, type RunTurnPermissionRequest as h, type SessionPersistence as i };
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export {
|
|
2
|
-
import './
|
|
1
|
+
export { e as WrongStackACPServer, f as WrongStackACPServerOptions } from './wrongstack-acp-agent-nzrqmJnc.js';
|
|
2
|
+
import './acp-v1-BxskPsdo.js';
|
|
3
3
|
import 'node:events';
|