@wrongstack/acp 1.1.2 → 1.1.4

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.
@@ -139,6 +139,8 @@ export interface ACPChildProcess extends EventEmitter {
139
139
  export declare class ClientTransport implements ACPClientTransport {
140
140
  private child;
141
141
  private buffer;
142
+ private stderrTail;
143
+ private stopRequested;
142
144
  private readonly handlers;
143
145
  private readonly claimHandlers;
144
146
  private readonly closeHandlers;
@@ -4,7 +4,11 @@ export interface PendingRequest {
4
4
  reject: (e: Error) => void;
5
5
  timeoutMs: number;
6
6
  timeoutHandle: ReturnType<typeof setTimeout>;
7
+ /** Set on a request timed by inactivity: restarts its clock. */
8
+ rearm?: (() => void) | undefined;
7
9
  }
10
+ /** The agent was heard from: restart the clock of every inactivity-timed request. */
11
+ export declare function touchIdleRequests(pending: Map<string | number, PendingRequest>): void;
8
12
  export type State = 'init' | 'ready' | 'authenticated' | 'sessioning' | 'prompting' | 'done' | 'closed';
9
13
  /**
10
14
  * Fail and forget every in-flight request. Without a `reason` the session was
@@ -29,4 +29,23 @@ export declare function executeSetProvider(ctx: ACPSessionOpContext, providerId:
29
29
  export declare function executeDisableProvider(ctx: ACPSessionOpContext): Promise<void>;
30
30
  export declare function executeMcpMessage(ctx: ACPSessionOpContext, connectionId: string, message: Record<string, unknown>): Promise<unknown>;
31
31
  export declare function executeCreateSession(ctx: ACPSessionOpContext): Promise<SessionId>;
32
+ /**
33
+ * Create the session now rather than at the first prompt. `resumed` is true
34
+ * when it continues `opts.resumeSessionId` (the agent remembers it), false for
35
+ * a new session.
36
+ */
37
+ export declare function executeOpenSession(ctx: ACPSessionOpContext, create: () => Promise<SessionId>): Promise<{
38
+ sessionId: SessionId;
39
+ resumed: boolean;
40
+ }>;
41
+ /** What a steer did: joined the running turn, found none, or cannot steer. */
42
+ export type AcpSteerOutcome = 'injected' | 'promptRequired' | 'startedNewTurn' | 'unsupported';
43
+ /**
44
+ * Inject `text` into the turn the agent is running, through the
45
+ * `_session/steering` extension (Claude's ACP adapter advertises it as
46
+ * `InitializeResponse._meta.steering.supported`). With no turn running the
47
+ * agent hands the text back (`promptRequired`) instead of starting a turn
48
+ * nobody awaits.
49
+ */
50
+ export declare function executeSteer(ctx: ACPSessionOpContext, supported: boolean, text: string): Promise<AcpSteerOutcome>;
32
51
  //# sourceMappingURL=acp-session-ops.d.ts.map
@@ -15,8 +15,8 @@ export interface AcpSessionPromptHost {
15
15
  resetScratch(): void;
16
16
  progressHandler: ACPProgressHandler | null;
17
17
  allocId(): number;
18
- sendRequest(id: number, method: string, params: unknown, timeoutMs?: number): Promise<unknown>;
19
- timeoutMs: number;
18
+ sendRequest(id: number, method: string, params: unknown, timeoutMs?: number, idle?: boolean): Promise<unknown>;
19
+ promptIdleTimeoutMs: number;
20
20
  scratch: ACPSessionScratch;
21
21
  }
22
22
  export declare function prompt(host: AcpSessionPromptHost, blocks: ContentBlock[], signal: AbortSignal, onProgress?: ACPProgressHandler): Promise<ACPSessionRunResult>;
@@ -8,7 +8,15 @@ export interface ACPSessionOptions {
8
8
  cwd?: string | undefined;
9
9
  role?: string | undefined;
10
10
  projectRoot: string;
11
+ /** Cap for each request to the agent other than a prompt turn. Default 5 minutes. */
11
12
  timeoutMs?: number | undefined;
13
+ /**
14
+ * How long a prompt turn may go without hearing from the agent (an update,
15
+ * a permission request, a file or terminal call) before it counts as
16
+ * stalled and is cancelled. Default 10 minutes. A turn that keeps reporting
17
+ * runs until it ends: a coding agent's turn routinely outlasts any fixed cap.
18
+ */
19
+ promptIdleTimeoutMs?: number | undefined;
12
20
  permissionPolicy?: PermissionPolicy | undefined;
13
21
  trustBoundary?: TrustBoundary | undefined;
14
22
  trustActor?: TrustActor | undefined;
@@ -19,6 +27,30 @@ export interface ACPSessionOptions {
19
27
  terminalOutputByteLimit?: number | undefined;
20
28
  terminalMaxCount?: number | undefined;
21
29
  mcpServers?: McpServer[] | undefined;
30
+ /**
31
+ * Opaque `_meta` sent with `session/new`. ACP reserves `_meta` for
32
+ * agent-specific extensions; e.g. the Claude adapter reads
33
+ * `systemPrompt: { append }` from it. Agents that know no key ignore it.
34
+ */
35
+ sessionMeta?: Record<string, unknown> | undefined;
36
+ /**
37
+ * Session mode to switch to right after `session/new`, when the agent
38
+ * offers it (e.g. Claude's `default`, so it asks before edits and
39
+ * commands instead of following the user's own Claude permission mode).
40
+ */
41
+ initialModeId?: string | undefined;
42
+ /**
43
+ * Refuse the session when the agent does not offer `initialModeId`: the
44
+ * host depends on that mode (an agent left in its own mode may never ask).
45
+ */
46
+ requireInitialMode?: boolean | undefined;
47
+ /**
48
+ * An earlier session of this agent to continue instead of starting one
49
+ * (`session/resume`, with this session's MCP servers, `_meta` and mode).
50
+ * Used when the agent advertises resume; when it does not, or no longer has
51
+ * the session, a new session starts. `openSession()` says which happened.
52
+ */
53
+ resumeSessionId?: string | undefined;
22
54
  }
23
55
  export interface ACPCapturedDiff {
24
56
  path: string;
@@ -32,6 +64,12 @@ export interface ACPCapturedToolCall {
32
64
  status: ToolCallStatus;
33
65
  rawOutput?: Record<string, unknown> | undefined;
34
66
  rawInput?: Record<string, unknown> | undefined;
67
+ /**
68
+ * What the call returned, as text: its `content` text blocks, else a
69
+ * string or text-block `rawOutput`. Claude's adapter sends the result in
70
+ * those shapes, which `rawOutput` (an object only) never held.
71
+ */
72
+ output?: string | undefined;
35
73
  }
36
74
  export interface ACPSessionRunResult {
37
75
  text: string;
@@ -42,11 +80,23 @@ export interface ACPSessionRunResult {
42
80
  size: number;
43
81
  cost?: UsageCost | undefined;
44
82
  } | undefined;
83
+ /**
84
+ * Token counts for the turn, from the `session/prompt` response
85
+ * (`PromptResponse.usage`). `usage.cost`, by contrast, is the session's
86
+ * running total.
87
+ */
88
+ tokens?: ACPTokenUsage | undefined;
45
89
  plan?: PlanEntry[] | undefined;
46
90
  toolCalls: ACPCapturedToolCall[];
47
91
  diffs: ACPCapturedDiff[];
48
92
  thoughts: string;
49
93
  }
94
+ export interface ACPTokenUsage {
95
+ input: number;
96
+ output: number;
97
+ cacheRead: number;
98
+ cacheWrite: number;
99
+ }
50
100
  export type ACPProgressHandler = (event: ACPProgressEvent) => void;
51
101
  export type ACPProgressEvent = {
52
102
  type: 'message';
@@ -73,9 +123,25 @@ export type ACPProgressEvent = {
73
123
  size: number;
74
124
  cost?: UsageCost | undefined;
75
125
  };
126
+ }
127
+ /**
128
+ * The agent's account rate-limit reading, as it sent it (Claude's adapter:
129
+ * `usage_update._meta["_claude/rateLimit"]` — status, resetsAt, windows).
130
+ */
131
+ | {
132
+ type: 'rate_limit';
133
+ info: Record<string, unknown>;
134
+ }
135
+ /** Emitted by the subagent runner once a turn ends: what the turn consumed. */
136
+ | {
137
+ type: 'turn_usage';
138
+ tokens?: ACPTokenUsage | undefined;
139
+ costUsd: number;
76
140
  } | {
77
141
  type: 'raw';
78
142
  update: AnySessionUpdate;
79
143
  };
80
- export type ACPSessionErrorKind = 'spawn_failed' | 'init_failed' | 'protocol_error' | 'session_create_failed' | 'prompt_failed' | 'auth_failed' | 'logout_failed' | 'aborted' | 'closed' | 'agent_died' | 'unsupported_capability';
144
+ export type ACPSessionErrorKind = 'spawn_failed' | 'init_failed' | 'protocol_error' | 'session_create_failed' | 'prompt_failed' | 'auth_failed' | 'logout_failed' | 'aborted' | 'closed' | 'agent_died'
145
+ /** A prompt turn heard nothing from the agent for `promptIdleTimeoutMs`. */
146
+ | 'stalled' | 'unsupported_capability';
81
147
  //# sourceMappingURL=acp-session-types.d.ts.map
@@ -12,6 +12,15 @@ export interface ACPSessionScratch {
12
12
  };
13
13
  toolCalls: Map<string, ACPCapturedToolCall>;
14
14
  diffs: ACPCapturedDiff[];
15
+ /**
16
+ * Set when a tool call ran after the last message text: the next text
17
+ * chunk starts a new assistant message, not a continuation.
18
+ */
19
+ messageBreak?: boolean;
20
+ /** Diffs already captured, keyed by tool call; agents resend them on update. */
21
+ seenDiffs?: Set<string>;
22
+ /** Tool calls already reported as started (see captureToolCall). */
23
+ announced?: Set<string>;
15
24
  }
16
25
  export declare function createSessionScratch(): ACPSessionScratch;
17
26
  export declare function handleAcpSessionUpdate(msg: ACPMessage, scratch: ACPSessionScratch, emitProgress: (event: ACPProgressEvent) => void): void;
@@ -10,6 +10,7 @@
10
10
  */
11
11
  import { type ACPClientTransport } from '../agent/stdio-transport.js';
12
12
  import { type AgentCapabilities, type AuthMethod, type ContentBlock, type McpServer, type SessionId, type SessionInfo } from '../types/acp-v1.js';
13
+ import { type AcpSteerOutcome } from './acp-session-ops.js';
13
14
  import type { ACPProgressHandler, ACPSessionOptions, ACPSessionRunResult } from './acp-session-types.js';
14
15
  import { type WebSocketClientTransportOptions } from './websocket-transport.js';
15
16
  export { audioContent, imageContent, textContent } from './acp-session-content.js';
@@ -21,6 +22,7 @@ export declare class ACPSession {
21
22
  private readonly terminalServer;
22
23
  private readonly permissionPolicy;
23
24
  private readonly timeoutMs;
25
+ private readonly promptIdleTimeoutMs;
24
26
  private readonly opts;
25
27
  private transportOff;
26
28
  private readonly callbackAbort;
@@ -35,6 +37,8 @@ export declare class ACPSession {
35
37
  private agentCapabilities;
36
38
  private agentInfo;
37
39
  private authMethods;
40
+ /** The agent accepts `_session/steering` (see executeSteer). */
41
+ private steeringSupported;
38
42
  /** Protocol version negotiated with the agent during initialize. */
39
43
  private negotiatedVersion;
40
44
  private constructor();
@@ -85,6 +89,11 @@ export declare class ACPSession {
85
89
  */
86
90
  logout(): Promise<void>;
87
91
  private opContext;
92
+ /** Start (or, with `resumeSessionId`, resume) the agent session now, not at the first prompt. */
93
+ openSession(): Promise<{
94
+ sessionId: SessionId;
95
+ resumed: boolean;
96
+ }>;
88
97
  loadSession(sessionId: SessionId, mcpServers?: McpServer[], cwd?: string): Promise<void>;
89
98
  resumeSession(sessionId: SessionId, mcpServers?: McpServer[], cwd?: string): Promise<void>;
90
99
  listSessions(cursor?: string, cwd?: string): Promise<{
@@ -102,6 +111,10 @@ export declare class ACPSession {
102
111
  mcpMessage(connectionId: string, message: Record<string, unknown>): Promise<unknown>;
103
112
  setProvider(providerId: string, config?: Record<string, unknown>): Promise<void>;
104
113
  disableProvider(): Promise<void>;
114
+ /** Whether {@link steer} can reach the agent. */
115
+ canSteer(): boolean;
116
+ /** Inject a message into the agent's running turn. */
117
+ steer(text: string): Promise<AcpSteerOutcome>;
105
118
  prompt(blocks: ContentBlock[], signal: AbortSignal, onProgress?: ACPProgressHandler): Promise<ACPSessionRunResult>;
106
119
  /**
107
120
  * Best-effort cancel for a session the server confirmed after we already
@@ -114,7 +127,14 @@ export declare class ACPSession {
114
127
  */
115
128
  private cancelLateSession;
116
129
  private closeSession;
117
- close(): Promise<void>;
130
+ /**
131
+ * Close the session and stop the agent. `graceMs` bounds how long the
132
+ * agent may take to answer `session/close` before it is stopped anyway —
133
+ * shutdown passes a short one so a slow answer cannot outlive the process.
134
+ */
135
+ close(opts?: {
136
+ graceMs?: number;
137
+ }): Promise<void>;
118
138
  private allocId;
119
139
  private sendRequest;
120
140
  /**