ashral 0.2.1 → 0.2.3

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.
Files changed (34) hide show
  1. package/dist/adapters/baseAdapter.d.ts +6 -0
  2. package/dist/adapters/baseAdapter.d.ts.map +1 -1
  3. package/dist/adapters/baseAdapter.js +8 -0
  4. package/dist/adapters/baseAdapter.js.map +1 -1
  5. package/dist/adapters/claudeAdapter.d.ts +1 -0
  6. package/dist/adapters/claudeAdapter.d.ts.map +1 -1
  7. package/dist/adapters/claudeAdapter.js +12 -0
  8. package/dist/adapters/claudeAdapter.js.map +1 -1
  9. package/dist/adapters/codexAdapter.d.ts +1 -0
  10. package/dist/adapters/codexAdapter.d.ts.map +1 -1
  11. package/dist/adapters/codexAdapter.js +10 -0
  12. package/dist/adapters/codexAdapter.js.map +1 -1
  13. package/dist/api/backendClient.d.ts +29 -1
  14. package/dist/api/backendClient.d.ts.map +1 -1
  15. package/dist/api/backendClient.js +98 -2
  16. package/dist/api/backendClient.js.map +1 -1
  17. package/dist/cli.js +62 -30
  18. package/dist/cli.js.map +1 -1
  19. package/dist/proxy/anthropicProxy.d.ts +6 -0
  20. package/dist/proxy/anthropicProxy.d.ts.map +1 -0
  21. package/dist/proxy/anthropicProxy.js +319 -0
  22. package/dist/proxy/anthropicProxy.js.map +1 -0
  23. package/dist/runner/runSession.d.ts.map +1 -1
  24. package/dist/runner/runSession.js +159 -24
  25. package/dist/runner/runSession.js.map +1 -1
  26. package/dist/runner/sessionState.d.ts +1 -1
  27. package/dist/runner/sessionState.d.ts.map +1 -1
  28. package/dist/runner/sessionState.js +2 -1
  29. package/dist/runner/sessionState.js.map +1 -1
  30. package/dist/types/events.d.ts +2 -0
  31. package/dist/types/events.d.ts.map +1 -1
  32. package/dist/types/session.d.ts +1 -1
  33. package/dist/types/session.d.ts.map +1 -1
  34. package/package.json +1 -1
@@ -0,0 +1,319 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.startAnthropicProxy = startAnthropicProxy;
37
+ const http = __importStar(require("http"));
38
+ const https = __importStar(require("https"));
39
+ const backendClient_1 = require("../api/backendClient");
40
+ const ANTHROPIC_HOST = 'api.anthropic.com';
41
+ const CHUNK_MAX_CHARS = 14000;
42
+ /**
43
+ * Parses Anthropic SSE chunks and returns text, stop reason, and token usage.
44
+ */
45
+ function parseSSE(sseChunk) {
46
+ let text = '';
47
+ let stopReason = null;
48
+ let inputTokens = 0;
49
+ let outputTokens = 0;
50
+ for (const line of sseChunk.split('\n')) {
51
+ if (!line.startsWith('data: '))
52
+ continue;
53
+ const raw = line.slice(6).trim();
54
+ if (!raw || raw === '[DONE]')
55
+ continue;
56
+ try {
57
+ const event = JSON.parse(raw);
58
+ if (event.type === 'content_block_delta' &&
59
+ typeof event.delta === 'object' && event.delta !== null &&
60
+ event.delta.type === 'text_delta') {
61
+ text += event.delta.text;
62
+ }
63
+ if (event.type === 'message_start') {
64
+ const usage = (event.message?.usage ?? {});
65
+ inputTokens += usage.input_tokens ?? 0;
66
+ outputTokens += usage.output_tokens ?? 0;
67
+ }
68
+ if (event.type === 'message_delta' &&
69
+ typeof event.delta === 'object' && event.delta !== null) {
70
+ stopReason = event.delta.stop_reason ?? null;
71
+ const usage = (event.usage ?? {});
72
+ outputTokens += usage.output_tokens ?? 0;
73
+ }
74
+ }
75
+ catch { /* malformed JSON — skip */ }
76
+ }
77
+ return { text, stopReason, inputTokens, outputTokens };
78
+ }
79
+ // Pricing in USD per million tokens (input / output).
80
+ // Covers current Claude 4 and Claude 3.x model families.
81
+ const MODEL_PRICING = {
82
+ // Claude 4
83
+ 'claude-opus-4': { input: 15, output: 75 },
84
+ 'claude-sonnet-4': { input: 3, output: 15 },
85
+ 'claude-haiku-4': { input: 0.25, output: 1.25 },
86
+ // Claude 3.7 / 3.5 / 3
87
+ 'claude-3-7-sonnet': { input: 3, output: 15 },
88
+ 'claude-3-5-sonnet': { input: 3, output: 15 },
89
+ 'claude-3-5-haiku': { input: 0.8, output: 4 },
90
+ 'claude-3-opus': { input: 15, output: 75 },
91
+ 'claude-3-sonnet': { input: 3, output: 15 },
92
+ 'claude-3-haiku': { input: 0.25, output: 1.25 },
93
+ };
94
+ function modelPricing(model) {
95
+ for (const [prefix, price] of Object.entries(MODEL_PRICING)) {
96
+ if (model.startsWith(prefix))
97
+ return price;
98
+ }
99
+ return { input: 3, output: 15 }; // safe default (Sonnet tier)
100
+ }
101
+ function extractModel(body) {
102
+ try {
103
+ const json = JSON.parse(body.toString('utf8'));
104
+ return typeof json.model === 'string' ? json.model : '';
105
+ }
106
+ catch {
107
+ return '';
108
+ }
109
+ }
110
+ /**
111
+ * Extracts unique file paths touched by tool_use calls in assistant messages.
112
+ * The request body contains the full conversation history so we can scan it here.
113
+ */
114
+ function extractToolFilePaths(body) {
115
+ try {
116
+ const json = JSON.parse(body.toString('utf8'));
117
+ const messages = json.messages;
118
+ if (!Array.isArray(messages))
119
+ return [];
120
+ const paths = [];
121
+ for (const msg of messages) {
122
+ if (msg.role !== 'assistant' || !Array.isArray(msg.content))
123
+ continue;
124
+ for (const block of msg.content) {
125
+ if (block.type !== 'tool_use')
126
+ continue;
127
+ const input = block.input;
128
+ const path = (input?.file_path ?? input?.path);
129
+ if (path && typeof path === 'string')
130
+ paths.push(path);
131
+ }
132
+ }
133
+ return paths;
134
+ }
135
+ catch {
136
+ return [];
137
+ }
138
+ }
139
+ /**
140
+ * Claude Code instructs Claude to append JSON metadata and <system-reminder> blocks
141
+ * after its visible response. Strip everything from the first such block onward.
142
+ */
143
+ function stripInternalMetadata(text) {
144
+ const trimmed = text.trim();
145
+ if (!trimmed)
146
+ return '';
147
+ // If the entire response is valid JSON, it's pure metadata — discard it
148
+ try {
149
+ JSON.parse(trimmed);
150
+ return '';
151
+ }
152
+ catch { /* not pure JSON, continue */ }
153
+ // Truncate at a JSON blob that starts on its own line — Claude Code appends
154
+ // metadata like {"type":"usage",...} on a new line after the visible text.
155
+ // Only match \n{" so inline JSON within the response is not cut off.
156
+ const jsonIdx = trimmed.search(/\n\{"/);
157
+ if (jsonIdx !== -1) {
158
+ const before = trimmed.slice(0, jsonIdx).trim();
159
+ if (before)
160
+ return before;
161
+ return '';
162
+ }
163
+ // Truncate at the first <tag (system-reminder etc.)
164
+ const tagIdx = trimmed.search(/<\w/);
165
+ if (tagIdx !== -1) {
166
+ return trimmed.slice(0, tagIdx).trim();
167
+ }
168
+ return trimmed;
169
+ }
170
+ async function save(sessionId, text, stream) {
171
+ const trimmed = stream === 'stdout' ? stripInternalMetadata(text) : text.trim();
172
+ if (!trimmed)
173
+ return;
174
+ for (let i = 0; i < trimmed.length; i += CHUNK_MAX_CHARS) {
175
+ await (0, backendClient_1.appendSessionOutput)(sessionId, trimmed.slice(i, i + CHUNK_MAX_CHARS), stream).catch(() => { });
176
+ }
177
+ }
178
+ /**
179
+ * Extracts the last user-typed message from the request body.
180
+ * Skips tool results and injected system content (<system-reminder> etc.).
181
+ */
182
+ function extractUserMessage(body) {
183
+ try {
184
+ const json = JSON.parse(body.toString('utf8'));
185
+ const messages = json.messages;
186
+ if (!Array.isArray(messages))
187
+ return null;
188
+ // Warmup/init requests have no system prompt and a single message — skip them
189
+ if (!json.system && messages.length === 1)
190
+ return null;
191
+ for (let i = messages.length - 1; i >= 0; i--) {
192
+ const msg = messages[i];
193
+ if (msg.role !== 'user')
194
+ continue;
195
+ if (typeof msg.content === 'string') {
196
+ const text = msg.content.trim();
197
+ if (!text)
198
+ continue;
199
+ // Skip plain-string JSON blobs Claude Code injects as metadata
200
+ try {
201
+ JSON.parse(text);
202
+ continue;
203
+ }
204
+ catch { /* not JSON — it's real user text */ }
205
+ return text;
206
+ }
207
+ if (Array.isArray(msg.content)) {
208
+ const blocks = msg.content
209
+ .filter((b) => b.type === 'text' && typeof b.text === 'string')
210
+ .map((b) => b.text.trim())
211
+ // Drop injected blocks: system tags, JSON blobs, quota notices, skill content,
212
+ // and Claude Code system instructions (compact-return prompt etc.).
213
+ // Real user messages are conversational and short; anything > 4000 chars is
214
+ // injected system/skill content (skill guides are tens of thousands of chars).
215
+ .filter((t) => t.length > 0 &&
216
+ t.length < 4000 &&
217
+ !t.startsWith('<') &&
218
+ !t.startsWith('[') &&
219
+ !t.startsWith('{') &&
220
+ !t.startsWith('Base directory for this skill:') &&
221
+ !t.startsWith('### Skill:') &&
222
+ !t.startsWith('The user stepped away') &&
223
+ !t.includes('Prior knowledge:'));
224
+ // The actual user text is always the last block
225
+ const last = blocks[blocks.length - 1];
226
+ if (last)
227
+ return last;
228
+ // No valid blocks — keep looking backwards
229
+ }
230
+ }
231
+ }
232
+ catch { /* not JSON — skip */ }
233
+ return null;
234
+ }
235
+ function startAnthropicProxy(sessionId) {
236
+ let lastSavedUserMsg = '';
237
+ const sessionFilePaths = new Set(); // unique file paths across the session
238
+ return new Promise((resolve, reject) => {
239
+ const server = http.createServer((req, res) => {
240
+ const bodyChunks = [];
241
+ req.on('data', (chunk) => bodyChunks.push(chunk));
242
+ req.on('end', () => {
243
+ const body = Buffer.concat(bodyChunks);
244
+ const userMsg = extractUserMessage(body);
245
+ if (userMsg && userMsg !== lastSavedUserMsg) {
246
+ lastSavedUserMsg = userMsg;
247
+ void save(sessionId, userMsg, 'stderr');
248
+ }
249
+ // Count new unique file paths seen in this request's history
250
+ const newPaths = extractToolFilePaths(body).filter(p => !sessionFilePaths.has(p));
251
+ for (const p of newPaths)
252
+ sessionFilePaths.add(p);
253
+ const pricing = modelPricing(extractModel(body));
254
+ const headers = {
255
+ ...req.headers,
256
+ host: ANTHROPIC_HOST,
257
+ };
258
+ // Remove Accept-Encoding so response arrives as plain-text SSE, not gzip
259
+ delete headers['accept-encoding'];
260
+ const proxyReq = https.request({ hostname: ANTHROPIC_HOST, port: 443, path: req.url, method: req.method, headers }, (proxyRes) => {
261
+ res.writeHead(proxyRes.statusCode ?? 502, proxyRes.headers);
262
+ let accumulated = '';
263
+ let accStopReason = null;
264
+ let accInputTokens = 0;
265
+ let accOutputTokens = 0;
266
+ let remainder = '';
267
+ proxyRes.on('data', (chunk) => {
268
+ res.write(chunk);
269
+ const raw = remainder + chunk.toString('utf8');
270
+ const lines = raw.split('\n');
271
+ remainder = lines.pop() ?? '';
272
+ const { text, stopReason, inputTokens, outputTokens } = parseSSE(lines.join('\n'));
273
+ accumulated += text;
274
+ accInputTokens += inputTokens;
275
+ accOutputTokens += outputTokens;
276
+ if (stopReason)
277
+ accStopReason = stopReason;
278
+ });
279
+ proxyRes.on('end', () => {
280
+ if (remainder) {
281
+ const { text, stopReason, inputTokens, outputTokens } = parseSSE(remainder);
282
+ accumulated += text;
283
+ accInputTokens += inputTokens;
284
+ accOutputTokens += outputTokens;
285
+ if (stopReason)
286
+ accStopReason = stopReason;
287
+ }
288
+ res.end();
289
+ if (accStopReason === 'end_turn') {
290
+ void save(sessionId, accumulated, 'stdout');
291
+ const cost = (accInputTokens * pricing.input + accOutputTokens * pricing.output) / 1000000;
292
+ void (0, backendClient_1.updateSessionStats)(sessionId, {
293
+ calls: 1,
294
+ tokens: accInputTokens + accOutputTokens,
295
+ cost,
296
+ ...(newPaths.length > 0 && { files: newPaths.length }),
297
+ });
298
+ }
299
+ });
300
+ proxyRes.on('error', () => res.end());
301
+ });
302
+ proxyReq.on('error', () => { res.writeHead(502); res.end(); });
303
+ proxyReq.write(body);
304
+ proxyReq.end();
305
+ });
306
+ req.on('error', () => res.end());
307
+ });
308
+ server.listen(0, '127.0.0.1', () => {
309
+ const addr = server.address();
310
+ if (!addr || typeof addr === 'string') {
311
+ reject(new Error('Failed to bind proxy port'));
312
+ return;
313
+ }
314
+ resolve({ port: addr.port, stop: () => new Promise((done) => server.close(() => done())) });
315
+ });
316
+ server.on('error', reject);
317
+ });
318
+ }
319
+ //# sourceMappingURL=anthropicProxy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropicProxy.js","sourceRoot":"","sources":["../../src/proxy/anthropicProxy.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"runSession.d.ts","sourceRoot":"","sources":["../../src/runner/runSession.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAuCnD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CACvC;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmG1E"}
1
+ {"version":3,"file":"runSession.d.ts","sourceRoot":"","sources":["../../src/runner/runSession.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAmEnD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wEAAwE;IACxE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2EAA2E;IAC3E,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,OAAO,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CACvC;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CAwN1E"}
@@ -36,24 +36,32 @@ Object.defineProperty(exports, "__esModule", { value: true });
36
36
  exports.runSession = runSession;
37
37
  const pty = __importStar(require("node-pty"));
38
38
  const sessionState_1 = require("./sessionState");
39
+ const anthropicProxy_1 = require("../proxy/anthropicProxy");
40
+ const backendClient_1 = require("../api/backendClient");
39
41
  const ANSI_RE = /\x1B\[[0-9;]*[A-Za-z]|\x1B[@-_][0-?]*[ -/]*[@-~]/g;
40
- const BUFFER_SIZE = 40;
41
42
  /**
42
43
  * Rolling buffer of the last N clean lines of PTY output.
43
- * The question text often arrives in an earlier chunk than the one that
44
- * triggers the status change, so we look back across recent output.
44
+ * Used only for status detection and push notification body extraction.
45
45
  */
46
46
  function makeOutputBuffer() {
47
47
  const lines = [];
48
+ const MAX = 80;
48
49
  function push(raw) {
49
50
  const cleaned = raw
50
- .replace(ANSI_RE, '')
51
+ // ink uses cursor-forward (\x1b[nC) for spaces — restore them before stripping
52
+ .replace(/\x1B\[(\d*)C/g, (_, n) => ' '.repeat(Math.max(1, parseInt(n || '1', 10))))
53
+ // Cursor-position and cursor-down codes imply a new line — convert before stripping
54
+ .replace(/\x1B\[(?:\d+;)*\d*[Hf]/g, '\n') // \x1b[row;colH / \x1b[H → newline
55
+ .replace(/\x1B\[\d*[BE]/g, '\n') // cursor down / next line → newline
56
+ .replace(/\x1B\[\d*G/g, '\n') // cursor to column (start of line) → newline
57
+ .replace(ANSI_RE, '') // strip remaining escape sequences
58
+ .replace(/\r/g, '\n') // bare \r → newline
51
59
  .split('\n')
52
60
  .map((l) => l.trim())
53
61
  .filter((l) => l.length > 1);
54
62
  lines.push(...cleaned);
55
- if (lines.length > BUFFER_SIZE)
56
- lines.splice(0, lines.length - BUFFER_SIZE);
63
+ if (lines.length > MAX)
64
+ lines.splice(0, lines.length - MAX);
57
65
  }
58
66
  function extractBody() {
59
67
  const candidates = lines
@@ -61,12 +69,31 @@ function makeOutputBuffer() {
61
69
  .filter((l) => !/^\d+\.\s/.test(l))
62
70
  .filter((l) => !/^[╭╰╮╯│─❯>\s□↓↑←→]+$/.test(l))
63
71
  .filter((l) => !/→\s*\w+_\w+/.test(l));
64
- // Prefer the last line ending with "?" — most likely the actual question
65
72
  const question = [...candidates].reverse().find((l) => l.endsWith('?'));
66
73
  const body = question ?? candidates[candidates.length - 1];
67
74
  return body ? body.slice(0, 200) : undefined;
68
75
  }
69
- return { push, extractBody };
76
+ /** Extract numbered option lines from the buffer, e.g. ["1. Write code", "2. Review code"] */
77
+ function extractOptions() {
78
+ const seen = new Set();
79
+ const result = [];
80
+ for (const line of lines) {
81
+ // Match optional ❯ or > cursor prefix, then "N. Label text"
82
+ const match = /^[❯>]?\s*(\d+\.\s+\S.*)$/.exec(line);
83
+ if (!match)
84
+ continue;
85
+ const option = match[1].trim();
86
+ if (!seen.has(option)) {
87
+ seen.add(option);
88
+ result.push(option);
89
+ }
90
+ }
91
+ return result.slice(0, 10);
92
+ }
93
+ function clear() {
94
+ lines.length = 0;
95
+ }
96
+ return { push, extractBody, extractOptions, clear };
70
97
  }
71
98
  /**
72
99
  * Spawns the agent inside a PTY, bridges all I/O, and drives the session
@@ -78,8 +105,19 @@ async function runSession(options) {
78
105
  const { columns = 80, rows = 24 } = process.stdout;
79
106
  const state = new sessionState_1.SessionState(adapter.agentName, name, cwd, onEvent, sessionId);
80
107
  const config = adapter.getCommand(passthroughArgs);
81
- // Merge adapter env overrides on top of the current environment
82
- const env = { ...process.env, ...(config.env ?? {}) };
108
+ // If the caller passed --resume <id>, we already know the agent session ID
109
+ const resumeIdx = passthroughArgs.indexOf('--resume');
110
+ const preKnownAgentSessionId = resumeIdx >= 0 ? passthroughArgs[resumeIdx + 1] : null;
111
+ if (preKnownAgentSessionId) {
112
+ void (0, backendClient_1.saveAgentSessionId)(state.id, preKnownAgentSessionId).catch(() => { });
113
+ }
114
+ // Start the transparent Anthropic proxy — Claude Code's API traffic flows
115
+ // through it so we can capture clean assistant text without touching the PTY.
116
+ const proxy = await (0, anthropicProxy_1.startAnthropicProxy)(state.id).catch(() => null);
117
+ const baseEnv = { ...process.env, ...(config.env ?? {}) };
118
+ const env = proxy
119
+ ? { ...baseEnv, ANTHROPIC_BASE_URL: `http://127.0.0.1:${proxy.port}` }
120
+ : baseEnv;
83
121
  const term = pty.spawn(config.command, config.args, {
84
122
  name: 'xterm-color',
85
123
  cols: columns,
@@ -89,9 +127,79 @@ async function runSession(options) {
89
127
  });
90
128
  state.transition('running');
91
129
  const buffer = makeOutputBuffer();
130
+ // ── Agent session ID detection ───────────────────────────────────────────────
131
+ // Accumulates early PTY output (up to 5000 stripped chars) and scans for the
132
+ // agent's internal session ID so we can persist it for later resumption.
133
+ let agentSessionIdSaved = !!preKnownAgentSessionId;
134
+ let startupBuf = '';
135
+ const STARTUP_SCAN_LIMIT = 5000;
136
+ // ── Spurious-running suppression ─────────────────────────────────────────────
137
+ // After entering waiting_for_input/approval_required, ink often emits cursor-
138
+ // movement output that the adapter mis-detects as 'running'. Suppress those
139
+ // PTY-sourced 'running' transitions for a short window so the backend retains
140
+ // pendingAction long enough for Flutter to poll it.
141
+ let suppressRunningUntil = 0;
142
+ // ── Remote response polling ──────────────────────────────────────────────────
143
+ // When the agent is waiting for input and the user responds via the mobile app,
144
+ // we poll the backend and write the response directly into the PTY.
145
+ let responsePoller = null;
146
+ function startResponsePolling() {
147
+ if (responsePoller)
148
+ return;
149
+ responsePoller = setInterval(async () => {
150
+ if (state.status !== 'waiting_for_input' && state.status !== 'approval_required') {
151
+ stopResponsePolling();
152
+ return;
153
+ }
154
+ try {
155
+ const response = await (0, backendClient_1.getSessionResponse)(state.id);
156
+ if (response) {
157
+ stopResponsePolling();
158
+ suppressRunningUntil = 0; // Legitimate transition — lift suppression
159
+ buffer.clear(); // Clear stale options so they don't bleed into the next question
160
+ await writeToPty(response);
161
+ state.transition('running');
162
+ }
163
+ }
164
+ catch {
165
+ // ignore — polling is best-effort
166
+ }
167
+ }, 2000);
168
+ }
169
+ function stopResponsePolling() {
170
+ if (responsePoller) {
171
+ clearInterval(responsePoller);
172
+ responsePoller = null;
173
+ }
174
+ }
175
+ async function writeToPty(response) {
176
+ const lower = response.toLowerCase().trim();
177
+ const approvalMap = {
178
+ approve: 'y',
179
+ allow: 'y',
180
+ yes: 'y',
181
+ deny: 'n',
182
+ no: 'n',
183
+ };
184
+ if (approvalMap[lower]) {
185
+ term.write(approvalMap[lower] + '\r');
186
+ return;
187
+ }
188
+ // Numbered option — navigate with arrow keys, one per tick, so ink-select-input
189
+ // processes each keypress before the next arrives.
190
+ const num = parseInt(response.trim(), 10);
191
+ if (!isNaN(num) && num >= 1) {
192
+ for (let i = 1; i < num; i++) {
193
+ term.write('\x1B[B');
194
+ await new Promise(resolve => setTimeout(resolve, 80));
195
+ }
196
+ term.write('\r');
197
+ return;
198
+ }
199
+ term.write(response + '\r');
200
+ }
92
201
  // ── Output: mirror PTY → stdout, inspect for state changes ─────────────────
93
202
  term.onData((data) => {
94
- // Write raw (ANSI-preserved) data so the terminal renders correctly
95
203
  process.stdout.write(data);
96
204
  onEvent({
97
205
  type: 'output',
@@ -100,22 +208,54 @@ async function runSession(options) {
100
208
  data,
101
209
  });
102
210
  buffer.push(data);
211
+ if (!agentSessionIdSaved && startupBuf.length < STARTUP_SCAN_LIMIT) {
212
+ startupBuf += data.replace(ANSI_RE, '');
213
+ const detected = adapter.extractAgentSessionId(startupBuf);
214
+ if (detected) {
215
+ agentSessionIdSaved = true;
216
+ void (0, backendClient_1.saveAgentSessionId)(state.id, detected).catch(() => { });
217
+ }
218
+ }
103
219
  const next = adapter.detectStatus(data, state.status);
104
220
  if (next !== null) {
105
- state.transition(next, buffer.extractBody());
221
+ // Suppress PTY-sourced 'running' detections right after waiting_for_input
222
+ // to prevent the backend from clearing pendingAction before Flutter polls it.
223
+ if (next === 'running' && Date.now() < suppressRunningUntil) {
224
+ return;
225
+ }
226
+ const body = buffer.extractBody();
227
+ state.transition(next, body);
228
+ if (next === 'waiting_for_input' || next === 'approval_required') {
229
+ suppressRunningUntil = Date.now() + 5000; // Hold off spurious running for 5s
230
+ // Delay extraction so the full prompt has time to finish rendering into the buffer
231
+ setTimeout(() => {
232
+ const options = buffer.extractOptions();
233
+ const question = buffer.extractBody();
234
+ void (0, backendClient_1.updateSessionStatus)(state.id, 'waiting_for_input', {
235
+ question,
236
+ // Fall back to approve/deny for approval prompts with no detectable numbered options
237
+ options: options.length > 0 ? options : (next === 'approval_required' ? ['approve', 'deny'] : []),
238
+ }).catch(() => { });
239
+ startResponsePolling();
240
+ }, 500);
241
+ }
242
+ else {
243
+ suppressRunningUntil = 0;
244
+ stopResponsePolling();
245
+ }
106
246
  }
107
247
  });
108
248
  // ── Input: forward stdin → PTY ──────────────────────────────────────────────
109
- // Raw mode disables line buffering and lets control characters (Ctrl+C etc.)
110
- // pass through as data to the PTY rather than being handled by Node.
111
249
  const isTTY = process.stdin.isTTY ?? false;
112
250
  if (isTTY)
113
251
  process.stdin.setRawMode(true);
114
252
  process.stdin.resume();
115
253
  const onStdinData = (chunk) => {
116
254
  term.write(chunk.toString('binary'));
117
- // User responded — reset to running so the next question fires a notification
118
255
  if (state.status === 'waiting_for_input' || state.status === 'approval_required') {
256
+ stopResponsePolling();
257
+ suppressRunningUntil = 0; // Legitimate transition — lift suppression
258
+ buffer.clear();
119
259
  state.transition('running');
120
260
  }
121
261
  };
@@ -126,19 +266,19 @@ async function runSession(options) {
126
266
  term.resize(cols, r);
127
267
  };
128
268
  process.stdout.on('resize', onResize);
129
- // ── Cleanup helper ───────────────────────────────────────────────────────────
130
269
  function teardown() {
270
+ stopResponsePolling();
131
271
  process.stdin.removeListener('data', onStdinData);
132
272
  process.stdout.removeListener('resize', onResize);
133
273
  if (isTTY)
134
274
  process.stdin.setRawMode(false);
135
275
  process.stdin.pause();
136
276
  }
137
- return new Promise((resolve, reject) => {
138
- term.onExit(({ exitCode, signal }) => {
277
+ return new Promise((resolve) => {
278
+ term.onExit(async ({ exitCode, signal }) => {
139
279
  teardown();
280
+ await proxy?.stop();
140
281
  if (signal && exitCode !== 0) {
141
- // Process was killed by a signal — surface as an error event
142
282
  onEvent({
143
283
  type: 'error',
144
284
  sessionId: state.id,
@@ -150,11 +290,6 @@ async function runSession(options) {
150
290
  state.complete(exitCode);
151
291
  resolve();
152
292
  });
153
- // Catch spawn errors (e.g. command not found)
154
- process.nextTick(() => {
155
- // node-pty doesn't emit an 'error' event; spawn failures surface as
156
- // immediate exits with code 127 or throw synchronously — handled above.
157
- });
158
293
  });
159
294
  }
160
295
  //# sourceMappingURL=runSession.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"runSession.js","sourceRoot":"","sources":["../../src/runner/runSession.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"runSession.js","sourceRoot":"","sources":["../../src/runner/runSession.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ export declare class SessionState {
7
7
  get id(): string;
8
8
  get status(): SessionStatus;
9
9
  /** Transition to a new status and emit a status_changed event. No-ops on same status. */
10
- transition(to: SessionStatus, text?: string): void;
10
+ transition(to: SessionStatus, text?: string, options?: string[]): void;
11
11
  /** Mark the session as done. Sets endedAt and transitions to completed. */
12
12
  complete(exitCode: number): void;
13
13
  snapshot(): Readonly<Session>;