@coralai/sps-cli 0.26.0 → 0.26.2

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 (135) hide show
  1. package/README-CN.md +4 -5
  2. package/README.md +38 -54
  3. package/dist/commands/acpCommand.d.ts.map +1 -1
  4. package/dist/commands/acpCommand.js +2 -19
  5. package/dist/commands/acpCommand.js.map +1 -1
  6. package/dist/commands/doctor.d.ts.map +1 -1
  7. package/dist/commands/doctor.js +3 -13
  8. package/dist/commands/doctor.js.map +1 -1
  9. package/dist/commands/tick.d.ts +0 -1
  10. package/dist/commands/tick.d.ts.map +1 -1
  11. package/dist/commands/tick.js +0 -18
  12. package/dist/commands/tick.js.map +1 -1
  13. package/dist/commands/workerDashboard.d.ts.map +1 -1
  14. package/dist/commands/workerDashboard.js +18 -89
  15. package/dist/commands/workerDashboard.js.map +1 -1
  16. package/dist/core/config.d.ts +2 -4
  17. package/dist/core/config.d.ts.map +1 -1
  18. package/dist/core/config.js +2 -4
  19. package/dist/core/config.js.map +1 -1
  20. package/dist/core/config.test.js +3 -5
  21. package/dist/core/config.test.js.map +1 -1
  22. package/dist/core/sessionLiveness.d.ts +0 -1
  23. package/dist/core/sessionLiveness.d.ts.map +1 -1
  24. package/dist/core/sessionLiveness.js +6 -16
  25. package/dist/core/sessionLiveness.js.map +1 -1
  26. package/dist/core/state.d.ts +4 -5
  27. package/dist/core/state.d.ts.map +1 -1
  28. package/dist/core/state.js +0 -1
  29. package/dist/core/state.js.map +1 -1
  30. package/dist/core/state.test.js +0 -1
  31. package/dist/core/state.test.js.map +1 -1
  32. package/dist/engines/CloseoutEngine.js.map +1 -1
  33. package/dist/engines/ExecutionEngine.d.ts +1 -1
  34. package/dist/engines/ExecutionEngine.js +3 -3
  35. package/dist/engines/ExecutionEngine.js.map +1 -1
  36. package/dist/engines/MonitorEngine.d.ts.map +1 -1
  37. package/dist/engines/MonitorEngine.js +5 -8
  38. package/dist/engines/MonitorEngine.js.map +1 -1
  39. package/dist/main.js +3 -3
  40. package/dist/main.js.map +1 -1
  41. package/dist/manager/integration-queue.d.ts +1 -1
  42. package/dist/manager/integration-queue.d.ts.map +1 -1
  43. package/dist/manager/runtime-coordinator.js +1 -1
  44. package/dist/manager/runtime-coordinator.js.map +1 -1
  45. package/dist/manager/worker-manager-impl.d.ts +1 -1
  46. package/dist/manager/worker-manager-impl.d.ts.map +1 -1
  47. package/dist/manager/worker-manager-impl.js +8 -8
  48. package/dist/manager/worker-manager-impl.js.map +1 -1
  49. package/dist/manager/worker-manager.d.ts +4 -4
  50. package/dist/manager/worker-manager.d.ts.map +1 -1
  51. package/dist/providers/adapters/AcpSdkAdapter.js +1 -1
  52. package/dist/providers/registry.d.ts.map +1 -1
  53. package/dist/providers/registry.js +0 -5
  54. package/dist/providers/registry.js.map +1 -1
  55. package/package.json +1 -1
  56. package/dist/core/acpState.d.ts +0 -4
  57. package/dist/core/acpState.d.ts.map +0 -1
  58. package/dist/core/acpState.js +0 -38
  59. package/dist/core/acpState.js.map +0 -1
  60. package/dist/core/ptyControl.d.ts +0 -27
  61. package/dist/core/ptyControl.d.ts.map +0 -1
  62. package/dist/core/ptyControl.js +0 -53
  63. package/dist/core/ptyControl.js.map +0 -1
  64. package/dist/interfaces/WorkerProvider.d.ts +0 -92
  65. package/dist/interfaces/WorkerProvider.d.ts.map +0 -1
  66. package/dist/interfaces/WorkerProvider.js +0 -2
  67. package/dist/interfaces/WorkerProvider.js.map +0 -1
  68. package/dist/manager/merge-mutex.d.ts +0 -20
  69. package/dist/manager/merge-mutex.d.ts.map +0 -1
  70. package/dist/manager/merge-mutex.js +0 -38
  71. package/dist/manager/merge-mutex.js.map +0 -1
  72. package/dist/manager/post-actions.d.ts +0 -81
  73. package/dist/manager/post-actions.d.ts.map +0 -1
  74. package/dist/manager/post-actions.js +0 -449
  75. package/dist/manager/post-actions.js.map +0 -1
  76. package/dist/manager/pty-session-manager.d.ts +0 -75
  77. package/dist/manager/pty-session-manager.d.ts.map +0 -1
  78. package/dist/manager/pty-session-manager.js +0 -343
  79. package/dist/manager/pty-session-manager.js.map +0 -1
  80. package/dist/manager/pty-session.d.ts +0 -77
  81. package/dist/manager/pty-session.d.ts.map +0 -1
  82. package/dist/manager/pty-session.js +0 -230
  83. package/dist/manager/pty-session.js.map +0 -1
  84. package/dist/manager/recovery.d.ts +0 -56
  85. package/dist/manager/recovery.d.ts.map +0 -1
  86. package/dist/manager/recovery.js +0 -510
  87. package/dist/manager/recovery.js.map +0 -1
  88. package/dist/providers/ClaudePrintProvider.d.ts +0 -54
  89. package/dist/providers/ClaudePrintProvider.d.ts.map +0 -1
  90. package/dist/providers/ClaudePrintProvider.js +0 -300
  91. package/dist/providers/ClaudePrintProvider.js.map +0 -1
  92. package/dist/providers/ClaudeTmuxProvider.d.ts +0 -94
  93. package/dist/providers/ClaudeTmuxProvider.d.ts.map +0 -1
  94. package/dist/providers/ClaudeTmuxProvider.js +0 -330
  95. package/dist/providers/ClaudeTmuxProvider.js.map +0 -1
  96. package/dist/providers/ClaudeWorkerProvider.d.ts +0 -6
  97. package/dist/providers/ClaudeWorkerProvider.d.ts.map +0 -1
  98. package/dist/providers/ClaudeWorkerProvider.js +0 -6
  99. package/dist/providers/ClaudeWorkerProvider.js.map +0 -1
  100. package/dist/providers/CodexExecProvider.d.ts +0 -36
  101. package/dist/providers/CodexExecProvider.d.ts.map +0 -1
  102. package/dist/providers/CodexExecProvider.js +0 -262
  103. package/dist/providers/CodexExecProvider.js.map +0 -1
  104. package/dist/providers/CodexTmuxProvider.d.ts +0 -71
  105. package/dist/providers/CodexTmuxProvider.d.ts.map +0 -1
  106. package/dist/providers/CodexTmuxProvider.js +0 -350
  107. package/dist/providers/CodexTmuxProvider.js.map +0 -1
  108. package/dist/providers/CodexWorkerProvider.d.ts +0 -6
  109. package/dist/providers/CodexWorkerProvider.d.ts.map +0 -1
  110. package/dist/providers/CodexWorkerProvider.js +0 -6
  111. package/dist/providers/CodexWorkerProvider.js.map +0 -1
  112. package/dist/providers/PTYAgentRuntime.d.ts +0 -54
  113. package/dist/providers/PTYAgentRuntime.d.ts.map +0 -1
  114. package/dist/providers/PTYAgentRuntime.js +0 -434
  115. package/dist/providers/PTYAgentRuntime.js.map +0 -1
  116. package/dist/providers/acpTmux.d.ts +0 -6
  117. package/dist/providers/acpTmux.d.ts.map +0 -1
  118. package/dist/providers/acpTmux.js +0 -51
  119. package/dist/providers/acpTmux.js.map +0 -1
  120. package/dist/providers/adapters/ClaudeACPAdapter.d.ts +0 -11
  121. package/dist/providers/adapters/ClaudeACPAdapter.d.ts.map +0 -1
  122. package/dist/providers/adapters/ClaudeACPAdapter.js +0 -150
  123. package/dist/providers/adapters/ClaudeACPAdapter.js.map +0 -1
  124. package/dist/providers/adapters/CodexACPAdapter.d.ts +0 -11
  125. package/dist/providers/adapters/CodexACPAdapter.d.ts.map +0 -1
  126. package/dist/providers/adapters/CodexACPAdapter.js +0 -158
  127. package/dist/providers/adapters/CodexACPAdapter.js.map +0 -1
  128. package/dist/providers/parsers/claude-parser.d.ts +0 -17
  129. package/dist/providers/parsers/claude-parser.d.ts.map +0 -1
  130. package/dist/providers/parsers/claude-parser.js +0 -112
  131. package/dist/providers/parsers/claude-parser.js.map +0 -1
  132. package/dist/providers/parsers/codex-parser.d.ts +0 -12
  133. package/dist/providers/parsers/codex-parser.d.ts.map +0 -1
  134. package/dist/providers/parsers/codex-parser.js +0 -91
  135. package/dist/providers/parsers/codex-parser.js.map +0 -1
@@ -1,343 +0,0 @@
1
- /**
2
- * PTYSessionManager — manages multiple PTY sessions across projects and slots.
3
- *
4
- * Each worker slot gets one persistent PTYSession. Sessions are reused across
5
- * task cards within the same slot.
6
- *
7
- * Replaces LocalACPClient + acpTmux.ts for the PTY transport.
8
- */
9
- import { resolve } from 'node:path';
10
- import { mkdirSync } from 'node:fs';
11
- import { PTYSession } from './pty-session.js';
12
- import { ClaudeOutputParser } from '../providers/parsers/claude-parser.js';
13
- import { CodexOutputParser } from '../providers/parsers/codex-parser.js';
14
- function sleep(ms) {
15
- return new Promise(resolve => setTimeout(resolve, ms));
16
- }
17
- function previewPrompt(prompt) {
18
- const oneLine = prompt.replace(/\s+/g, ' ').trim();
19
- return oneLine.length > 120 ? `${oneLine.slice(0, 117)}...` : oneLine;
20
- }
21
- // ─── Manager ────────────────────────────────────────────────────
22
- export class PTYSessionManager {
23
- sessions = new Map();
24
- static makeKey(project, slot) {
25
- return `${project}:${slot}`;
26
- }
27
- // ─── Session Lifecycle ──────────────────────────────────────
28
- /**
29
- * Ensure a ready PTY session exists for the given slot.
30
- * Reuses existing live session or creates a new one.
31
- */
32
- async ensureSession(opts) {
33
- const key = PTYSessionManager.makeKey(opts.project, opts.slot);
34
- // Reuse existing live session
35
- const existing = this.sessions.get(key);
36
- if (existing?.isAlive()) {
37
- // If session was left in a worktree from a previous card, we can't change cwd
38
- // of a running PTY. But the run prompt will include explicit cwd instructions.
39
- return existing;
40
- }
41
- // Clean up dead session
42
- if (existing) {
43
- this.sessions.delete(key);
44
- }
45
- // Create output log directory
46
- mkdirSync(opts.logsDir, { recursive: true });
47
- const outputPath = resolve(opts.logsDir, `${opts.slot}-pty-${Date.now()}.log`);
48
- // Create parser for the tool
49
- const parser = opts.tool === 'claude'
50
- ? new ClaudeOutputParser()
51
- : new CodexOutputParser();
52
- // Spawn PTY
53
- const session = new PTYSession(opts.tool, opts.cwd, outputPath, parser);
54
- // Auto-handle trust prompts
55
- if (opts.autoTrust !== false) {
56
- session.on('waiting-input', (event) => {
57
- const prompt = event.prompt.toLowerCase();
58
- const codexUpdateNotice = event.type === 'confirmation' && (prompt.includes('update notice') ||
59
- prompt.includes('press enter to continue'));
60
- if (codexUpdateNotice) {
61
- this.log(`[${key}] Auto-skipping Codex update notice`);
62
- session.write('\x1b[B\r');
63
- return;
64
- }
65
- if (event.type === 'trust') {
66
- this.log(`[${key}] Auto-confirming trust prompt`);
67
- session.confirm();
68
- }
69
- });
70
- }
71
- // Clean up on exit
72
- session.on('exit', (code) => {
73
- this.log(`[${key}] PTY exited (code=${code})`);
74
- this.sessions.delete(key);
75
- });
76
- this.sessions.set(key, session);
77
- // Wait for ready
78
- const timeout = opts.readyTimeoutMs ?? 60_000;
79
- try {
80
- await this.waitForState(session, 'ready', timeout);
81
- this.log(`[${key}] Session ready (pid=${session.pid})`);
82
- }
83
- catch (err) {
84
- const state = session.getState();
85
- // If stuck in confirmation/input during boot, still return session
86
- if (state === 'waiting_input' || state === 'needs_confirmation') {
87
- this.log(`[${key}] Session waiting for input (pid=${session.pid})`);
88
- }
89
- else {
90
- this.log(`[${key}] Session failed to reach ready state: ${state}`);
91
- session.kill();
92
- this.sessions.delete(key);
93
- throw err;
94
- }
95
- }
96
- return session;
97
- }
98
- // ─── Run Management ─────────────────────────────────────────
99
- /**
100
- * Start a new run (send prompt) on an existing session.
101
- */
102
- async startRun(project, slot, prompt) {
103
- const session = this.requireSession(project, slot);
104
- if (session.getState() !== 'ready') {
105
- throw new Error(`Session not ready (state=${session.getState()})`);
106
- }
107
- const runId = String(Date.now());
108
- session.beginRun(runId, prompt, previewPrompt(prompt));
109
- session.sendPrompt(prompt);
110
- await this.ensurePromptSubmitted(project, slot, session);
111
- this.log(`[${project}:${slot}] Run started: ${runId}`);
112
- return { runId };
113
- }
114
- /**
115
- * Resume a run on the same session (for conflict resolution, retries, etc.)
116
- */
117
- async resumeRun(project, slot, instruction) {
118
- const session = this.requireSession(project, slot);
119
- if (session.getState() !== 'ready') {
120
- throw new Error(`Session not ready for resume (state=${session.getState()})`);
121
- }
122
- const runId = String(Date.now());
123
- session.beginRun(runId, instruction, previewPrompt(instruction));
124
- session.sendPrompt(instruction);
125
- await this.ensurePromptSubmitted(project, slot, session);
126
- this.log(`[${project}:${slot}] Resume run started: ${runId}`);
127
- return { runId };
128
- }
129
- /**
130
- * Wait for the current run to complete (prompt reappears).
131
- */
132
- async waitForRunComplete(project, slot, timeoutMs = 3_600_000) {
133
- const session = this.requireSession(project, slot);
134
- const runId = session.getRunId();
135
- return new Promise((resolve) => {
136
- const timer = setTimeout(() => {
137
- resolve({ status: 'timeout', runId });
138
- }, timeoutMs);
139
- const onCompleted = (completedRunId) => {
140
- clearTimeout(timer);
141
- cleanup();
142
- resolve({ status: 'completed', runId: completedRunId });
143
- };
144
- const onFailed = (failedRunId) => {
145
- clearTimeout(timer);
146
- cleanup();
147
- resolve({ status: 'failed', runId: failedRunId });
148
- };
149
- const onExit = () => {
150
- clearTimeout(timer);
151
- cleanup();
152
- resolve({ status: 'failed', runId });
153
- };
154
- const cleanup = () => {
155
- session.off('run-completed', onCompleted);
156
- session.off('run-failed', onFailed);
157
- session.off('exit', onExit);
158
- };
159
- session.on('run-completed', onCompleted);
160
- session.on('run-failed', onFailed);
161
- session.on('exit', onExit);
162
- });
163
- }
164
- // ─── Human Interaction ──────────────────────────────────────
165
- /**
166
- * Send a response to a waiting-input prompt.
167
- */
168
- respond(project, slot, response) {
169
- const session = this.requireSession(project, slot);
170
- this.writeResponse(session, response);
171
- this.log(`[${project}:${slot}] Sent response: ${response}`);
172
- }
173
- async maintainSession(project, slot) {
174
- const session = this.getSession(project, slot);
175
- if (!session)
176
- return null;
177
- await this.repairPromptSubmission(project, slot, session);
178
- return this.inspect(project, slot);
179
- }
180
- // ─── Inspection ─────────────────────────────────────────────
181
- getSession(project, slot) {
182
- return this.sessions.get(PTYSessionManager.makeKey(project, slot)) || null;
183
- }
184
- inspect(project, slot) {
185
- const session = this.getSession(project, slot);
186
- if (!session)
187
- return null;
188
- return {
189
- sessionId: session.sessionId,
190
- state: session.getState(),
191
- pid: session.pid,
192
- tool: session.tool,
193
- cwd: session.cwd,
194
- runId: session.getRunId(),
195
- buffer: session.getBuffer(30),
196
- alive: session.isAlive(),
197
- lastOutputAt: session.getLastOutputAt() ? new Date(session.getLastOutputAt()).toISOString() : null,
198
- submitAttempts: session.getSubmitAttempts(),
199
- stalledReason: session.getStalledReason(),
200
- promptPreview: session.getPromptPreview(),
201
- executionEvidence: this.hasExecutionEvidence(session),
202
- };
203
- }
204
- listSessions() {
205
- const result = [];
206
- for (const session of this.sessions.values()) {
207
- result.push({
208
- sessionId: session.sessionId,
209
- state: session.getState(),
210
- pid: session.pid,
211
- tool: session.tool,
212
- cwd: session.cwd,
213
- runId: session.getRunId(),
214
- buffer: session.getBuffer(5),
215
- alive: session.isAlive(),
216
- lastOutputAt: session.getLastOutputAt() ? new Date(session.getLastOutputAt()).toISOString() : null,
217
- submitAttempts: session.getSubmitAttempts(),
218
- stalledReason: session.getStalledReason(),
219
- promptPreview: session.getPromptPreview(),
220
- executionEvidence: this.hasExecutionEvidence(session),
221
- });
222
- }
223
- return result;
224
- }
225
- // ─── Cleanup ────────────────────────────────────────────────
226
- killSession(project, slot) {
227
- const key = PTYSessionManager.makeKey(project, slot);
228
- const session = this.sessions.get(key);
229
- if (session) {
230
- session.kill();
231
- this.sessions.delete(key);
232
- }
233
- }
234
- killAll() {
235
- for (const session of this.sessions.values()) {
236
- session.kill();
237
- }
238
- this.sessions.clear();
239
- }
240
- get size() {
241
- return this.sessions.size;
242
- }
243
- // ─── Internal ─────────────────────────────────────────────
244
- requireSession(project, slot) {
245
- const session = this.getSession(project, slot);
246
- if (!session || !session.isAlive()) {
247
- throw new Error(`No live session for ${project}:${slot}`);
248
- }
249
- return session;
250
- }
251
- waitForState(session, target, timeoutMs) {
252
- if (session.getState() === target)
253
- return Promise.resolve();
254
- return new Promise((resolve, reject) => {
255
- const timer = setTimeout(() => reject(new Error(`Timeout (${timeoutMs}ms) waiting for ${target}, current: ${session.getState()}`)), timeoutMs);
256
- const handler = (state) => {
257
- if (state === target) {
258
- clearTimeout(timer);
259
- session.off('state-change', handler);
260
- resolve();
261
- }
262
- };
263
- session.on('state-change', handler);
264
- session.on('exit', () => {
265
- clearTimeout(timer);
266
- session.off('state-change', handler);
267
- reject(new Error('Session exited before reaching target state'));
268
- });
269
- });
270
- }
271
- log(msg) {
272
- process.stderr.write(`[pty-manager] ${msg}\n`);
273
- }
274
- writeResponse(session, response) {
275
- const num = parseInt(response, 10);
276
- if (!Number.isNaN(num) && num >= 1) {
277
- const downs = '\x1b[B'.repeat(num - 1);
278
- session.write(`${downs}\r`);
279
- return;
280
- }
281
- session.write(`${response}\r`);
282
- }
283
- async ensurePromptSubmitted(project, slot, session) {
284
- const key = `${project}:${slot}`;
285
- for (let attempt = 1; attempt <= 3; attempt++) {
286
- session.markSubmitAttempt();
287
- session.confirm();
288
- await sleep(900);
289
- if (this.isRunAccepted(session)) {
290
- return;
291
- }
292
- this.log(`[${key}] Prompt still not executing after submit attempt ${attempt}`);
293
- }
294
- session.setStalledReason('Prompt did not start executing after submit attempts');
295
- }
296
- async repairPromptSubmission(project, slot, session) {
297
- if (!session.isAlive() || !session.getRunId())
298
- return;
299
- if (session.getState() !== 'ready')
300
- return;
301
- const attempts = session.getSubmitAttempts();
302
- if (attempts === 0)
303
- return;
304
- if (this.isRunAccepted(session))
305
- return;
306
- const lastSubmitAt = session.getLastSubmitAt();
307
- if (lastSubmitAt && Date.now() - lastSubmitAt < 5_000)
308
- return;
309
- if (attempts >= 6)
310
- return;
311
- const key = `${project}:${slot}`;
312
- const promptText = session.getPromptText();
313
- if (attempts >= 3 && promptText) {
314
- this.log(`[${key}] Re-sending prompt after stalled submit (attempt ${attempts + 1})`);
315
- session.sendPrompt('\x15');
316
- await sleep(100);
317
- session.sendPrompt(promptText);
318
- }
319
- else {
320
- this.log(`[${key}] Re-submitting Enter after stalled submit (attempt ${attempts + 1})`);
321
- }
322
- session.markSubmitAttempt();
323
- session.confirm();
324
- await sleep(900);
325
- if (this.isRunAccepted(session)) {
326
- session.setStalledReason(null);
327
- return;
328
- }
329
- session.setStalledReason(`Prompt still not executing after ${session.getSubmitAttempts()} submit attempts`);
330
- }
331
- isRunAccepted(session) {
332
- const state = session.getState();
333
- if (state === 'busy' || state === 'waiting_input' || state === 'needs_confirmation') {
334
- return true;
335
- }
336
- return this.hasExecutionEvidence(session);
337
- }
338
- hasExecutionEvidence(session) {
339
- const text = session.getBuffer(120);
340
- return /Working\(|\bRan\b|I['’]ll do|I['’]m going to|Reading|Searching|Applied|Updated|The repository is|^•\s+/im.test(text);
341
- }
342
- }
343
- //# sourceMappingURL=pty-session-manager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pty-session-manager.js","sourceRoot":"","sources":["../../src/manager/pty-session-manager.ts"],"names":[],"mappings":"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"}
@@ -1,77 +0,0 @@
1
- import { EventEmitter } from 'node:events';
2
- export type SessionState = 'booting' | 'ready' | 'busy' | 'waiting_input' | 'needs_confirmation' | 'offline';
3
- export interface WaitingInputEvent {
4
- type: 'input' | 'trust' | 'permission' | 'confirmation' | 'unknown';
5
- prompt: string;
6
- options?: string[];
7
- dangerous?: boolean;
8
- timestamp: string;
9
- }
10
- export interface PTYSessionEvents {
11
- 'state-change': (state: SessionState, prev: SessionState) => void;
12
- 'waiting-input': (event: WaitingInputEvent) => void;
13
- 'run-completed': (runId: string) => void;
14
- 'run-failed': (runId: string, error: string) => void;
15
- 'output': (chunk: string) => void;
16
- 'exit': (code: number) => void;
17
- }
18
- /**
19
- * OutputParser — tool-specific stream parser. Fed every chunk from PTY stdout.
20
- * Responsible for detecting state transitions by analyzing the output stream.
21
- */
22
- export interface OutputParser {
23
- feed(chunk: string, session: PTYSession): void;
24
- reset(): void;
25
- }
26
- export declare class PTYSession extends EventEmitter {
27
- private readonly parser;
28
- private terminal;
29
- private state;
30
- private buffer;
31
- private outputStream;
32
- private currentRunId;
33
- private _alive;
34
- private lastOutputAt;
35
- private submitAttempts;
36
- private lastSubmitAt;
37
- private stalledReason;
38
- private promptPreview;
39
- private promptText;
40
- readonly pid: number;
41
- readonly sessionId: string;
42
- readonly tool: 'claude' | 'codex';
43
- readonly cwd: string;
44
- constructor(tool: 'claude' | 'codex', cwd: string, outputPath: string | null, parser: OutputParser);
45
- /** Write raw bytes to PTY stdin */
46
- write(data: string): void;
47
- /** Send prompt text without implicitly submitting it. */
48
- sendPrompt(prompt: string): void;
49
- /** Send Enter key (confirm) */
50
- confirm(): void;
51
- /** Send Escape key (cancel/reject) */
52
- reject(): void;
53
- /** Send Ctrl+C */
54
- interrupt(): void;
55
- getState(): SessionState;
56
- setState(state: SessionState): void;
57
- getRunId(): string | null;
58
- setRunId(runId: string | null): void;
59
- beginRun(runId: string, promptText: string, promptPreview: string): void;
60
- isAlive(): boolean;
61
- getLastOutputAt(): number | null;
62
- getPromptPreview(): string | null;
63
- getPromptText(): string | null;
64
- getSubmitAttempts(): number;
65
- getLastSubmitAt(): number | null;
66
- markSubmitAttempt(): void;
67
- getStalledReason(): string | null;
68
- setStalledReason(reason: string | null): void;
69
- /** Get recent buffer content (optionally limited to last N lines) */
70
- getBuffer(lines?: number): string;
71
- /** Get raw buffer including ANSI sequences */
72
- getRawBuffer(): string;
73
- resize(cols: number, rows: number): void;
74
- kill(): void;
75
- private trimBuffer;
76
- }
77
- //# sourceMappingURL=pty-session.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pty-session.d.ts","sourceRoot":"","sources":["../../src/manager/pty-session.ts"],"names":[],"mappings":"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"}
@@ -1,230 +0,0 @@
1
- /**
2
- * PTYSession — wraps a single persistent Worker process (Claude/Codex) in a
3
- * pseudoterminal. Provides real-time streaming output, direct stdin injection,
4
- * and event-driven state detection.
5
- *
6
- * Replaces tmux send-keys/capture-pane with direct PTY read/write.
7
- */
8
- import * as pty from 'node-pty';
9
- import { EventEmitter } from 'node:events';
10
- import { chmodSync, createWriteStream, existsSync, statSync } from 'node:fs';
11
- import { dirname, join } from 'node:path';
12
- import { createRequire } from 'node:module';
13
- // ─── Constants ──────────────────────────────────────────────────
14
- const MAX_BUFFER_LINES = 500;
15
- const STRIP_ANSI_RE = /\x1b\[[0-9;]*[a-zA-Z]|\x1b\][^\x07]*\x07|\x1b[()][AB012]|\x1b\[[\?]?[0-9;]*[hlm]/g;
16
- function stripAnsi(text) {
17
- return text.replace(STRIP_ANSI_RE, '');
18
- }
19
- const require = createRequire(import.meta.url);
20
- let spawnHelpersVerified = false;
21
- function ensureSpawnHelpersExecutable() {
22
- if (spawnHelpersVerified || process.platform !== 'darwin')
23
- return;
24
- const packageJsonPath = require.resolve('node-pty/package.json');
25
- const prebuildsDir = join(dirname(packageJsonPath), 'prebuilds');
26
- const candidates = Array.from(new Set([
27
- join(prebuildsDir, `darwin-${process.arch}`, 'spawn-helper'),
28
- join(prebuildsDir, 'darwin-arm64', 'spawn-helper'),
29
- join(prebuildsDir, 'darwin-x64', 'spawn-helper'),
30
- ]));
31
- for (const helperPath of candidates) {
32
- if (!existsSync(helperPath))
33
- continue;
34
- const mode = statSync(helperPath).mode & 0o777;
35
- if ((mode & 0o111) === 0o111)
36
- continue;
37
- chmodSync(helperPath, mode | 0o111);
38
- process.stderr.write(`[pty-session] Restored execute permission on ${helperPath}\n`);
39
- }
40
- spawnHelpersVerified = true;
41
- }
42
- function wrapSpawnError(tool, error) {
43
- const base = error instanceof Error ? error : new Error(String(error));
44
- if (process.platform !== 'darwin' || !base.message.includes('posix_spawnp failed')) {
45
- return base;
46
- }
47
- return new Error(`Failed to launch ${tool} PTY session: ${base.message}. ` +
48
- 'On macOS this usually means node-pty spawn-helper is missing executable permissions.', { cause: base });
49
- }
50
- // ─── PTYSession ─────────────────────────────────────────────────
51
- export class PTYSession extends EventEmitter {
52
- parser;
53
- terminal;
54
- state = 'booting';
55
- buffer = '';
56
- outputStream = null;
57
- currentRunId = null;
58
- _alive = true;
59
- lastOutputAt = null;
60
- submitAttempts = 0;
61
- lastSubmitAt = null;
62
- stalledReason = null;
63
- promptPreview = null;
64
- promptText = null;
65
- pid;
66
- sessionId;
67
- tool;
68
- cwd;
69
- constructor(tool, cwd, outputPath, parser) {
70
- super();
71
- this.parser = parser;
72
- this.tool = tool;
73
- this.cwd = cwd;
74
- const cmd = tool === 'claude' ? 'claude' : 'codex';
75
- const args = tool === 'claude'
76
- ? ['--dangerously-skip-permissions']
77
- : ['--full-auto'];
78
- ensureSpawnHelpersExecutable();
79
- try {
80
- this.terminal = pty.spawn(cmd, args, {
81
- name: 'xterm-256color',
82
- cols: 200,
83
- rows: 50,
84
- cwd,
85
- env: { ...process.env },
86
- });
87
- }
88
- catch (error) {
89
- throw wrapSpawnError(tool, error);
90
- }
91
- this.pid = this.terminal.pid;
92
- this.sessionId = `pty-${tool}-${this.pid}-${Date.now()}`;
93
- if (outputPath) {
94
- this.outputStream = createWriteStream(outputPath, { flags: 'a' });
95
- }
96
- // ── Real-time stream processing ──
97
- this.terminal.onData((chunk) => {
98
- this.lastOutputAt = Date.now();
99
- this.buffer += chunk;
100
- this.trimBuffer();
101
- if (this.outputStream)
102
- this.outputStream.write(chunk);
103
- this.emit('output', chunk);
104
- // Feed clean text to parser
105
- const clean = stripAnsi(chunk);
106
- this.parser.feed(clean, this);
107
- });
108
- this.terminal.onExit(({ exitCode }) => {
109
- this._alive = false;
110
- this.setState('offline');
111
- if (this.outputStream)
112
- this.outputStream.end();
113
- this.emit('exit', exitCode);
114
- });
115
- }
116
- // ─── Write ────────────────────────────────────────────────────
117
- /** Write raw bytes to PTY stdin */
118
- write(data) {
119
- if (!this._alive)
120
- return;
121
- this.terminal.write(data);
122
- }
123
- /** Send prompt text without implicitly submitting it. */
124
- sendPrompt(prompt) {
125
- this.write(prompt);
126
- }
127
- /** Send Enter key (confirm) */
128
- confirm() {
129
- this.write('\r');
130
- }
131
- /** Send Escape key (cancel/reject) */
132
- reject() {
133
- this.write('\x1b');
134
- }
135
- /** Send Ctrl+C */
136
- interrupt() {
137
- this.write('\x03');
138
- }
139
- // ─── State ────────────────────────────────────────────────────
140
- getState() {
141
- return this.state;
142
- }
143
- setState(state) {
144
- const prev = this.state;
145
- if (prev === state)
146
- return;
147
- this.state = state;
148
- if (state === 'busy' || state === 'waiting_input' || state === 'needs_confirmation') {
149
- this.stalledReason = null;
150
- }
151
- this.emit('state-change', state, prev);
152
- }
153
- getRunId() {
154
- return this.currentRunId;
155
- }
156
- setRunId(runId) {
157
- this.currentRunId = runId;
158
- }
159
- beginRun(runId, promptText, promptPreview) {
160
- this.currentRunId = runId;
161
- this.promptText = promptText;
162
- this.promptPreview = promptPreview;
163
- this.submitAttempts = 0;
164
- this.lastSubmitAt = null;
165
- this.stalledReason = null;
166
- }
167
- isAlive() {
168
- return this._alive;
169
- }
170
- getLastOutputAt() {
171
- return this.lastOutputAt;
172
- }
173
- getPromptPreview() {
174
- return this.promptPreview;
175
- }
176
- getPromptText() {
177
- return this.promptText;
178
- }
179
- getSubmitAttempts() {
180
- return this.submitAttempts;
181
- }
182
- getLastSubmitAt() {
183
- return this.lastSubmitAt;
184
- }
185
- markSubmitAttempt() {
186
- this.submitAttempts += 1;
187
- this.lastSubmitAt = Date.now();
188
- }
189
- getStalledReason() {
190
- return this.stalledReason;
191
- }
192
- setStalledReason(reason) {
193
- this.stalledReason = reason;
194
- }
195
- // ─── Buffer ───────────────────────────────────────────────────
196
- /** Get recent buffer content (optionally limited to last N lines) */
197
- getBuffer(lines) {
198
- const clean = stripAnsi(this.buffer);
199
- if (!lines)
200
- return clean;
201
- const all = clean.split('\n');
202
- return all.slice(-lines).join('\n');
203
- }
204
- /** Get raw buffer including ANSI sequences */
205
- getRawBuffer() {
206
- return this.buffer;
207
- }
208
- // ─── Lifecycle ────────────────────────────────────────────────
209
- resize(cols, rows) {
210
- if (this._alive)
211
- this.terminal.resize(cols, rows);
212
- }
213
- kill() {
214
- this._alive = false;
215
- try {
216
- this.terminal.kill();
217
- }
218
- catch { /* already dead */ }
219
- if (this.outputStream)
220
- this.outputStream.end();
221
- }
222
- // ─── Internal ─────────────────────────────────────────────────
223
- trimBuffer() {
224
- const lines = this.buffer.split('\n');
225
- if (lines.length > MAX_BUFFER_LINES) {
226
- this.buffer = lines.slice(-MAX_BUFFER_LINES).join('\n');
227
- }
228
- }
229
- }
230
- //# sourceMappingURL=pty-session.js.map