@coralai/sps-cli 0.10.2 → 0.11.1

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 (62) hide show
  1. package/README.md +63 -23
  2. package/dist/commands/workerDashboard.d.ts.map +1 -1
  3. package/dist/commands/workerDashboard.js +39 -11
  4. package/dist/commands/workerDashboard.js.map +1 -1
  5. package/dist/core/config.d.ts +1 -0
  6. package/dist/core/config.d.ts.map +1 -1
  7. package/dist/core/config.js +1 -0
  8. package/dist/core/config.js.map +1 -1
  9. package/dist/core/state.d.ts +10 -0
  10. package/dist/core/state.d.ts.map +1 -1
  11. package/dist/core/state.js +5 -0
  12. package/dist/core/state.js.map +1 -1
  13. package/dist/engines/CloseoutEngine.d.ts.map +1 -1
  14. package/dist/engines/CloseoutEngine.js +79 -28
  15. package/dist/engines/CloseoutEngine.js.map +1 -1
  16. package/dist/engines/ExecutionEngine.d.ts +5 -0
  17. package/dist/engines/ExecutionEngine.d.ts.map +1 -1
  18. package/dist/engines/ExecutionEngine.js +80 -16
  19. package/dist/engines/ExecutionEngine.js.map +1 -1
  20. package/dist/engines/MonitorEngine.d.ts.map +1 -1
  21. package/dist/engines/MonitorEngine.js +6 -1
  22. package/dist/engines/MonitorEngine.js.map +1 -1
  23. package/dist/interfaces/WorkerProvider.d.ts +68 -15
  24. package/dist/interfaces/WorkerProvider.d.ts.map +1 -1
  25. package/dist/models/types.d.ts +3 -1
  26. package/dist/models/types.d.ts.map +1 -1
  27. package/dist/providers/ClaudePrintProvider.d.ts +54 -0
  28. package/dist/providers/ClaudePrintProvider.d.ts.map +1 -0
  29. package/dist/providers/ClaudePrintProvider.js +279 -0
  30. package/dist/providers/ClaudePrintProvider.js.map +1 -0
  31. package/dist/providers/ClaudeTmuxProvider.d.ts +94 -0
  32. package/dist/providers/ClaudeTmuxProvider.d.ts.map +1 -0
  33. package/dist/providers/ClaudeTmuxProvider.js +331 -0
  34. package/dist/providers/ClaudeTmuxProvider.js.map +1 -0
  35. package/dist/providers/ClaudeWorkerProvider.d.ts +5 -93
  36. package/dist/providers/ClaudeWorkerProvider.d.ts.map +1 -1
  37. package/dist/providers/ClaudeWorkerProvider.js +3 -303
  38. package/dist/providers/ClaudeWorkerProvider.js.map +1 -1
  39. package/dist/providers/CodexExecProvider.d.ts +36 -0
  40. package/dist/providers/CodexExecProvider.d.ts.map +1 -0
  41. package/dist/providers/CodexExecProvider.js +238 -0
  42. package/dist/providers/CodexExecProvider.js.map +1 -0
  43. package/dist/providers/CodexTmuxProvider.d.ts +71 -0
  44. package/dist/providers/CodexTmuxProvider.d.ts.map +1 -0
  45. package/dist/providers/CodexTmuxProvider.js +351 -0
  46. package/dist/providers/CodexTmuxProvider.js.map +1 -0
  47. package/dist/providers/CodexWorkerProvider.d.ts +5 -70
  48. package/dist/providers/CodexWorkerProvider.d.ts.map +1 -1
  49. package/dist/providers/CodexWorkerProvider.js +3 -328
  50. package/dist/providers/CodexWorkerProvider.js.map +1 -1
  51. package/dist/providers/outputParser.d.ts +50 -0
  52. package/dist/providers/outputParser.d.ts.map +1 -0
  53. package/dist/providers/outputParser.js +219 -0
  54. package/dist/providers/outputParser.js.map +1 -0
  55. package/dist/providers/registry.d.ts.map +1 -1
  56. package/dist/providers/registry.js +18 -6
  57. package/dist/providers/registry.js.map +1 -1
  58. package/dist/providers/streamRenderer.d.ts +13 -0
  59. package/dist/providers/streamRenderer.d.ts.map +1 -0
  60. package/dist/providers/streamRenderer.js +106 -0
  61. package/dist/providers/streamRenderer.js.map +1 -0
  62. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"WorkerProvider.d.ts","sourceRoot":"","sources":["../../src/interfaces/WorkerProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACzD,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACjE,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7D,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxE,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpG,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IACxF,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IACjD,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3D,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAElF;;;;;;;;;OASG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAClD"}
1
+ {"version":3,"file":"WorkerProvider.d.ts","sourceRoot":"","sources":["../../src/interfaces/WorkerProvider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,iFAAiF;AACjF,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,GAAG,EAAE,MAAM,CAAC;IACZ,qEAAqE;IACrE,UAAU,EAAE,MAAM,CAAC;IACnB,6DAA6D;IAC7D,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,qEAAqE;IACrE,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEzD;;;;;;;;;;OAUG;IACH,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAErF;;;;OAIG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAChC,KAAK,EAAE,OAAO,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC,CAAC;IAEH;;;;OAIG;IACH,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAExF;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAEpG;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEjD;;;;;;;;OAQG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,eAAe,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAEpG;;;;;;;OAOG;IACH,eAAe,CACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;IAEhC;;;;OAIG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAExC;;;;OAIG;IACH,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAErC,iDAAiD;IACjD,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;CAClD"}
@@ -11,7 +11,9 @@ export interface Card {
11
11
  export type CardState = 'Planning' | 'Backlog' | 'Todo' | 'Inprogress' | 'QA' | 'Done';
12
12
  export type AuxiliaryState = 'BLOCKED' | 'NEEDS-FIX' | 'WAITING-CONFIRMATION' | 'CONFLICT' | 'STALE-RUNTIME';
13
13
  /** Worker detection result */
14
- export type WorkerStatus = 'ALIVE' | 'COMPLETED' | 'NEEDS_INPUT' | 'AUTO_CONFIRM' | 'BLOCKED' | 'DEAD' | 'DEAD_EXCEEDED';
14
+ export type WorkerStatus = 'ALIVE' | 'COMPLETED' | 'NEEDS_INPUT' | 'AUTO_CONFIRM' | 'BLOCKED' | 'DEAD' | 'DEAD_EXCEEDED'
15
+ /** Process exited (code 0) but no artifacts found (no commits/MR). Worker gave up or hit token limit. */
16
+ | 'EXITED_INCOMPLETE';
15
17
  /** MR status from repo backend */
16
18
  export interface MrStatus {
17
19
  exists: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/models/types.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,SAAS,CAAC;IACjB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAED,MAAM,MAAM,SAAS,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,YAAY,GAAG,IAAI,GAAG,MAAM,CAAC;AAEvF,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,WAAW,GAAG,sBAAsB,GAAG,UAAU,GAAG,eAAe,CAAC;AAE7G,8BAA8B;AAC9B,MAAM,MAAM,YAAY,GACpB,OAAO,GACP,WAAW,GACX,aAAa,GACb,cAAc,GACd,SAAS,GACT,MAAM,GACN,eAAe,CAAC;AAEpB,kCAAkC;AAClC,MAAM,WAAW,QAAQ;IACvB,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,WAAW,CAAC;IACpD,QAAQ,EAAE,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;IAC/E,WAAW,EAAE,eAAe,GAAG,kBAAkB,GAAG,UAAU,GAAG,SAAS,CAAC;IAC3E,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CACpB;AAED,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;IACxC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,MAAM,CAAC;IAC/B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,6BAA6B;AAC7B,MAAM,WAAW,UAAW,SAAQ,aAAa;IAC/C,KAAK,EAAE,UAAU,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,IAAI,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CAAC;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB;AAED,4CAA4C;AAC5C,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,CAAC;IAC1C,cAAc,EAAE,OAAO,CAAC;IACxB,oBAAoB,EAAE,OAAO,CAAC;IAC9B,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,0BAA0B;AAC1B,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;IAC1C,OAAO,EAAE,MAAM,CAAC;CACjB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/models/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import type { ProjectConfig } from '../core/config.js';
2
+ import type { WorkerProvider, LaunchResult } from '../interfaces/WorkerProvider.js';
3
+ import type { WorkerStatus } from '../models/types.js';
4
+ export declare class ClaudePrintProvider implements WorkerProvider {
5
+ private readonly config;
6
+ constructor(config: ProjectConfig);
7
+ prepareEnv(worktree: string, _seq: string): Promise<void>;
8
+ /**
9
+ * Spawn `claude -p` with the prompt piped via stdin.
10
+ * Returns immediately — the process runs in background.
11
+ */
12
+ launch(session: string, worktree: string, promptFile: string): Promise<LaunchResult>;
13
+ inspect(session: string): Promise<{
14
+ alive: boolean;
15
+ paneText: string;
16
+ pid?: number;
17
+ exitCode?: number;
18
+ }>;
19
+ detectCompleted(session: string, logDir: string, branch: string): Promise<WorkerStatus>;
20
+ /**
21
+ * Print mode with --dangerously-skip-permissions never waits for input.
22
+ */
23
+ detectWaiting(_session: string): Promise<{
24
+ waiting: boolean;
25
+ destructive: boolean;
26
+ prompt: string;
27
+ }>;
28
+ detectBlocked(_session: string): Promise<boolean>;
29
+ /**
30
+ * Send a fix prompt by spawning a NEW claude -p with --resume.
31
+ * Returns a new LaunchResult with the new process info.
32
+ */
33
+ sendFix(session: string, fixPrompt: string, resumeSessionId?: string): Promise<LaunchResult>;
34
+ resolveConflict(session: string, worktree: string, branch: string, resumeSessionId?: string): Promise<LaunchResult>;
35
+ /**
36
+ * No-op in print mode — process already exited.
37
+ */
38
+ release(_session: string): Promise<void>;
39
+ stop(session: string): Promise<void>;
40
+ collectSummary(session: string): Promise<string>;
41
+ private spawnClaude;
42
+ /**
43
+ * Try to extract session ID from output file after process starts.
44
+ * Called asynchronously — updates the tracking entry.
45
+ */
46
+ extractSessionIdAsync(session: string): Promise<string | null>;
47
+ /**
48
+ * Look up worker slot info from state.json by tmuxSession name.
49
+ * Used as fallback when activeProcesses map is empty (SPS restarted).
50
+ */
51
+ private findSlotBySession;
52
+ private log;
53
+ }
54
+ //# sourceMappingURL=ClaudePrintProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClaudePrintProvider.d.ts","sourceRoot":"","sources":["../../src/providers/ClaudePrintProvider.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA0BvD,qBAAa,mBAAoB,YAAW,cAAc;IACxD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;gBAE3B,MAAM,EAAE,aAAa;IAI3B,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa/D;;;OAGG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAcpF,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QACtC,KAAK,EAAE,OAAO,CAAC;QACf,QAAQ,EAAE,MAAM,CAAC;QACjB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;IA8BI,eAAe,CACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,YAAY,CAAC;IAkExB;;OAEG;IACG,aAAa,CACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAIhE,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAIvD;;;OAGG;IACG,OAAO,CACX,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,YAAY,CAAC;IAalB,eAAe,CACnB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,eAAe,CAAC,EAAE,MAAM,GACvB,OAAO,CAAC,YAAY,CAAC;IAmBxB;;OAEG;IACG,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAKxC,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAWpC,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAQtD,OAAO,CAAC,WAAW;IAkEnB;;;OAGG;IACG,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAQpE;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAgCzB,OAAO,CAAC,GAAG;CAGZ"}
@@ -0,0 +1,279 @@
1
+ /**
2
+ * ClaudePrintProvider — one-shot print-mode worker using `claude -p`.
3
+ *
4
+ * Eliminates all tmux interaction. Process lifecycle = task lifecycle.
5
+ * Uses --resume <sessionId> for context continuity across tasks.
6
+ */
7
+ import { spawn, execFileSync } from 'node:child_process';
8
+ import { existsSync, readFileSync, createWriteStream } from 'node:fs';
9
+ import { resolve } from 'node:path';
10
+ import { tailFile, parseClaudeSessionId, isProcessAlive, killProcessGroup, extractLastAssistantText, branchCommitsAhead, branchPushed, } from './outputParser.js';
11
+ import { readState } from '../core/state.js';
12
+ /** Completion indicators in the final assistant message. */
13
+ const COMPLETION_KEYWORDS = /\b(done|完成|全部完成|MR created|merge request|已提交|已推送)\b|🎉/i;
14
+ /**
15
+ * Track spawned child processes by session name.
16
+ * Needed because inspect()/detectCompleted() receive session name, not PID.
17
+ */
18
+ const activeProcesses = new Map();
19
+ export class ClaudePrintProvider {
20
+ config;
21
+ constructor(config) {
22
+ this.config = config;
23
+ }
24
+ async prepareEnv(worktree, _seq) {
25
+ if (!existsSync(worktree)) {
26
+ throw new Error(`Worktree directory does not exist: ${worktree}`);
27
+ }
28
+ try {
29
+ execFileSync('git', ['-C', worktree, 'rev-parse', '--is-inside-work-tree'], {
30
+ encoding: 'utf-8', timeout: 5_000, stdio: ['ignore', 'pipe', 'pipe'],
31
+ });
32
+ }
33
+ catch {
34
+ throw new Error(`Directory is not a git worktree: ${worktree}`);
35
+ }
36
+ }
37
+ /**
38
+ * Spawn `claude -p` with the prompt piped via stdin.
39
+ * Returns immediately — the process runs in background.
40
+ */
41
+ async launch(session, worktree, promptFile) {
42
+ if (!existsSync(promptFile)) {
43
+ throw new Error(`Prompt file does not exist: ${promptFile}`);
44
+ }
45
+ const prompt = readFileSync(promptFile, 'utf-8').trim();
46
+ const outputFile = resolve(this.config.raw.LOGS_DIR || `/tmp/sps-${this.config.PROJECT_NAME}`, `${session}-${Date.now()}.jsonl`);
47
+ return this.spawnClaude(session, worktree, prompt, outputFile);
48
+ }
49
+ async inspect(session) {
50
+ // Try in-memory tracking first
51
+ const proc = activeProcesses.get(session);
52
+ if (proc) {
53
+ const pid = proc.child.pid ?? 0;
54
+ const alive = pid > 0 && isProcessAlive(pid);
55
+ return {
56
+ alive,
57
+ paneText: tailFile(proc.outputFile, 50),
58
+ pid,
59
+ exitCode: proc.exitCode ?? undefined,
60
+ };
61
+ }
62
+ // Fallback: recover from state.json (SPS process may have restarted)
63
+ const slotInfo = this.findSlotBySession(session);
64
+ if (slotInfo?.pid) {
65
+ const alive = isProcessAlive(slotInfo.pid);
66
+ const paneText = slotInfo.outputFile ? tailFile(slotInfo.outputFile, 50) : '';
67
+ return {
68
+ alive,
69
+ paneText,
70
+ pid: slotInfo.pid,
71
+ exitCode: alive ? undefined : (slotInfo.exitCode ?? undefined),
72
+ };
73
+ }
74
+ return { alive: false, paneText: '', pid: undefined, exitCode: undefined };
75
+ }
76
+ async detectCompleted(session, logDir, branch) {
77
+ // Priority 1: marker file
78
+ const markerPath = `${logDir}/task_completed`;
79
+ if (existsSync(markerPath)) {
80
+ return 'COMPLETED';
81
+ }
82
+ // Resolve process info — in-memory or state.json fallback
83
+ const proc = activeProcesses.get(session);
84
+ const slotInfo = !proc ? this.findSlotBySession(session) : null;
85
+ const pid = proc?.child.pid ?? slotInfo?.pid ?? 0;
86
+ const outputFile = proc?.outputFile ?? slotInfo?.outputFile ?? null;
87
+ const exitCode = proc?.exitCode ?? slotInfo?.exitCode ?? null;
88
+ if (!pid && !proc) {
89
+ // No process tracked at all — treat as dead
90
+ return 'DEAD';
91
+ }
92
+ // Priority 2: process still running
93
+ if (pid > 0 && isProcessAlive(pid)) {
94
+ return 'ALIVE';
95
+ }
96
+ // ── Process has exited — verify with artifacts ──
97
+ // The key question: did the worker actually complete the task?
98
+ // Exit code 0 alone is NOT enough — worker may have:
99
+ // - Hit token/budget limit and exited gracefully
100
+ // - Said "I can't do this" and exited
101
+ // - Completed coding but not pushed / not created MR
102
+ // Check git artifacts: branch pushed with commits ahead of base
103
+ const worktree = slotInfo?.worktree ?? null;
104
+ const baseBranch = this.config.GITLAB_MERGE_BRANCH;
105
+ if (worktree && branch) {
106
+ const pushed = branchPushed(worktree, branch);
107
+ const commitsAhead = pushed
108
+ ? branchCommitsAhead(worktree, branch, baseBranch)
109
+ : 0;
110
+ if (pushed && commitsAhead > 0) {
111
+ // Branch has been pushed with new commits — worker did real work.
112
+ // ExecutionEngine will additionally check MR existence before moving to QA.
113
+ return 'COMPLETED';
114
+ }
115
+ }
116
+ // Check output text for completion keywords as secondary signal
117
+ if (outputFile) {
118
+ const lastText = extractLastAssistantText(outputFile);
119
+ if (COMPLETION_KEYWORDS.test(lastText)) {
120
+ return 'COMPLETED';
121
+ }
122
+ }
123
+ // Process exited but no artifacts found
124
+ if (exitCode === 0) {
125
+ // Graceful exit but nothing to show for it
126
+ return 'EXITED_INCOMPLETE';
127
+ }
128
+ // Non-zero exit — worker crashed
129
+ return 'DEAD';
130
+ }
131
+ /**
132
+ * Print mode with --dangerously-skip-permissions never waits for input.
133
+ */
134
+ async detectWaiting(_session) {
135
+ return { waiting: false, destructive: false, prompt: '' };
136
+ }
137
+ async detectBlocked(_session) {
138
+ return false;
139
+ }
140
+ /**
141
+ * Send a fix prompt by spawning a NEW claude -p with --resume.
142
+ * Returns a new LaunchResult with the new process info.
143
+ */
144
+ async sendFix(session, fixPrompt, resumeSessionId) {
145
+ // Find worktree from state.json
146
+ const slotInfo = this.findSlotBySession(session);
147
+ const worktree = slotInfo?.worktree || '.';
148
+ const outputFile = resolve(this.config.raw.LOGS_DIR || `/tmp/sps-${this.config.PROJECT_NAME}`, `${session}-fix-${Date.now()}.jsonl`);
149
+ return this.spawnClaude(session, worktree, fixPrompt, outputFile, resumeSessionId);
150
+ }
151
+ async resolveConflict(session, worktree, branch, resumeSessionId) {
152
+ const instruction = [
153
+ `There is a merge conflict on branch ${branch}.`,
154
+ `Working directory: ${worktree}`,
155
+ 'Please resolve the conflict:',
156
+ `1. Run: git fetch origin && git rebase origin/${this.config.GITLAB_MERGE_BRANCH}`,
157
+ '2. Resolve any conflicts in the affected files',
158
+ '3. Run: git add . && git rebase --continue',
159
+ '4. Run: git push --force-with-lease',
160
+ ].join('\n');
161
+ const outputFile = resolve(this.config.raw.LOGS_DIR || `/tmp/sps-${this.config.PROJECT_NAME}`, `${session}-conflict-${Date.now()}.jsonl`);
162
+ return this.spawnClaude(session, worktree, instruction, outputFile, resumeSessionId);
163
+ }
164
+ /**
165
+ * No-op in print mode — process already exited.
166
+ */
167
+ async release(_session) {
168
+ // Clean up tracking entry
169
+ activeProcesses.delete(_session);
170
+ }
171
+ async stop(session) {
172
+ const proc = activeProcesses.get(session);
173
+ if (!proc)
174
+ return;
175
+ const pid = proc.child.pid;
176
+ if (pid && isProcessAlive(pid)) {
177
+ await killProcessGroup(pid);
178
+ }
179
+ activeProcesses.delete(session);
180
+ }
181
+ async collectSummary(session) {
182
+ const proc = activeProcesses.get(session);
183
+ if (!proc)
184
+ return '';
185
+ return tailFile(proc.outputFile, 100);
186
+ }
187
+ // ─── Internal ────────────────────────────────────────────────────
188
+ spawnClaude(session, worktree, prompt, outputFile, resumeSessionId) {
189
+ const args = [
190
+ '-p', // print mode: reads prompt from stdin when no prompt arg given
191
+ '--output-format', 'stream-json',
192
+ '--dangerously-skip-permissions',
193
+ ];
194
+ if (resumeSessionId) {
195
+ args.push('--resume', resumeSessionId);
196
+ }
197
+ // Ensure output directory exists
198
+ const { mkdirSync } = require('node:fs');
199
+ const { dirname } = require('node:path');
200
+ try {
201
+ mkdirSync(dirname(outputFile), { recursive: true });
202
+ }
203
+ catch { /* exists */ }
204
+ const outStream = createWriteStream(outputFile, { flags: 'a' });
205
+ const child = spawn('claude', args, {
206
+ cwd: worktree,
207
+ stdio: ['pipe', 'pipe', 'pipe'],
208
+ detached: true, // own process group for killProcessGroup()
209
+ env: { ...process.env },
210
+ });
211
+ // Pipe stdout (stream-json) to output file
212
+ child.stdout?.pipe(outStream);
213
+ // Also capture stderr to output file
214
+ child.stderr?.on('data', (chunk) => {
215
+ outStream.write(chunk);
216
+ });
217
+ // Write prompt to stdin and close
218
+ child.stdin?.write(prompt);
219
+ child.stdin?.end();
220
+ // Track process
221
+ const entry = { child, outputFile, exitCode: null };
222
+ activeProcesses.set(session, entry);
223
+ child.on('exit', (code) => {
224
+ entry.exitCode = code ?? 1;
225
+ outStream.end();
226
+ });
227
+ // Don't let this child block the parent from exiting
228
+ child.unref();
229
+ // Parse session ID from output once available (async)
230
+ const sessionId = resumeSessionId || undefined;
231
+ this.log(`Spawned claude -p for ${session} (pid=${child.pid}), output=${outputFile}`);
232
+ return {
233
+ pid: child.pid ?? 0,
234
+ outputFile,
235
+ sessionId,
236
+ };
237
+ }
238
+ /**
239
+ * Try to extract session ID from output file after process starts.
240
+ * Called asynchronously — updates the tracking entry.
241
+ */
242
+ async extractSessionIdAsync(session) {
243
+ // Wait a bit for output to be written
244
+ await new Promise((r) => setTimeout(r, 3_000));
245
+ const proc = activeProcesses.get(session);
246
+ if (!proc)
247
+ return null;
248
+ return parseClaudeSessionId(proc.outputFile);
249
+ }
250
+ /**
251
+ * Look up worker slot info from state.json by tmuxSession name.
252
+ * Used as fallback when activeProcesses map is empty (SPS restarted).
253
+ */
254
+ findSlotBySession(session) {
255
+ try {
256
+ const stateFile = resolve(process.env.HOME || '~', '.projects', this.config.PROJECT_NAME, 'runtime', 'state.json');
257
+ if (!existsSync(stateFile))
258
+ return null;
259
+ const state = readState(stateFile, this.config.MAX_CONCURRENT_WORKERS);
260
+ for (const slot of Object.values(state.workers)) {
261
+ if (slot.tmuxSession === session && slot.mode === 'print') {
262
+ return {
263
+ pid: slot.pid ?? null,
264
+ outputFile: slot.outputFile ?? null,
265
+ exitCode: slot.exitCode ?? null,
266
+ sessionId: slot.sessionId ?? null,
267
+ worktree: slot.worktree ?? null,
268
+ };
269
+ }
270
+ }
271
+ }
272
+ catch { /* state read error */ }
273
+ return null;
274
+ }
275
+ log(msg) {
276
+ process.stderr.write(`[claude-print] ${msg}\n`);
277
+ }
278
+ }
279
+ //# sourceMappingURL=ClaudePrintProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClaudePrintProvider.js","sourceRoot":"","sources":["../../src/providers/ClaudePrintProvider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,94 @@
1
+ import type { ProjectConfig } from '../core/config.js';
2
+ import type { WorkerProvider, LaunchResult } from '../interfaces/WorkerProvider.js';
3
+ import type { WorkerStatus } from '../models/types.js';
4
+ export declare class ClaudeTmuxProvider implements WorkerProvider {
5
+ private readonly config;
6
+ constructor(config: ProjectConfig);
7
+ /**
8
+ * Ensure worktree directory exists and is clean.
9
+ * This is largely a no-op when the worktree is already prepared.
10
+ */
11
+ prepareEnv(worktree: string, _seq: string): Promise<void>;
12
+ /**
13
+ * Launch a Claude Code worker inside a tmux session.
14
+ *
15
+ * Session reuse strategy (WORKER_SESSION_REUSE=true):
16
+ * 1. Session exists + Claude running → reuse: /clear + cd worktree (keep context hot)
17
+ * 2. Session exists + Claude not running → reuse session: cd + start claude
18
+ * 3. No session → create new session + start claude
19
+ */
20
+ launch(session: string, worktree: string, promptFile: string): Promise<LaunchResult>;
21
+ private log;
22
+ /**
23
+ * Poll tmux pane text until Claude's ready prompt appears.
24
+ * Default timeout: 30 seconds, poll interval: 2 seconds.
25
+ */
26
+ waitReady(session: string, timeoutMs?: number): Promise<boolean>;
27
+ /**
28
+ * Send a task prompt file to the Claude session.
29
+ */
30
+ sendTask(session: string, promptFile: string): Promise<void>;
31
+ /**
32
+ * Inspect a tmux session: check if alive and capture pane text.
33
+ */
34
+ inspect(session: string): Promise<{
35
+ alive: boolean;
36
+ paneText: string;
37
+ }>;
38
+ /**
39
+ * Multi-layer completion detection chain.
40
+ *
41
+ * Priority order:
42
+ * 1. task_completed marker file in logDir
43
+ * 2. Waiting for confirmation prompts (delegates to detectWaiting)
44
+ * 3. Completion keywords in pane text
45
+ * 4. MR exists on GitLab (skipped — returns ALIVE)
46
+ * 5. tmux session alive → ALIVE
47
+ * 6. Session dead + restart limit exceeded → DEAD_EXCEEDED
48
+ */
49
+ detectCompleted(session: string, logDir: string, _branch: string): Promise<WorkerStatus>;
50
+ /**
51
+ * Detect whether the worker is waiting for user confirmation.
52
+ * Returns whether the prompt is destructive (delete/remove/drop etc.).
53
+ */
54
+ detectWaiting(session: string): Promise<{
55
+ waiting: boolean;
56
+ destructive: boolean;
57
+ prompt: string;
58
+ }>;
59
+ /**
60
+ * Check pane text for blocked indicators (errors, stuck states).
61
+ */
62
+ detectBlocked(session: string): Promise<boolean>;
63
+ /**
64
+ * Send a fix prompt to the Claude session (e.g. after CI failure).
65
+ */
66
+ sendFix(session: string, fixPrompt: string, _resumeSessionId?: string): Promise<void>;
67
+ /**
68
+ * Send conflict resolution instructions to the Claude session.
69
+ */
70
+ resolveConflict(session: string, worktree: string, branch: string, _resumeSessionId?: string): Promise<void>;
71
+ /**
72
+ * Release a worker session after task completion.
73
+ *
74
+ * WORKER_SESSION_REUSE=true: do nothing — keep Claude running so the
75
+ * next task can hot-reuse the session via /clear + cd (preserves
76
+ * session state, env vars, loaded MCP servers, etc.).
77
+ *
78
+ * WORKER_SESSION_REUSE=false: exit Claude but keep tmux session alive
79
+ * (next launch will restart Claude in the existing session).
80
+ */
81
+ release(session: string): Promise<void>;
82
+ /**
83
+ * Force-stop a worker session (error recovery, cleanup).
84
+ * Always exits Claude and kills the tmux session.
85
+ */
86
+ stop(session: string): Promise<void>;
87
+ /**
88
+ * Capture the last 100 lines of pane text as a summary.
89
+ */
90
+ collectSummary(session: string): Promise<string>;
91
+ /** Helper: sleep for the given milliseconds. */
92
+ private sleep;
93
+ }
94
+ //# sourceMappingURL=ClaudeTmuxProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClaudeTmuxProvider.d.ts","sourceRoot":"","sources":["../../src/providers/ClaudeTmuxProvider.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,iCAAiC,CAAC;AACpF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AA6DvD,qBAAa,kBAAmB,YAAW,cAAc;IACvD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAgB;gBAE3B,MAAM,EAAE,aAAa;IAIjC;;;OAGG;IACG,UAAU,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAgB/D;;;;;;;OAOG;IACG,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAqC1F,OAAO,CAAC,GAAG,CAAwE;IAEnF;;;OAGG;IACG,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,SAAS,GAAG,OAAO,CAAC,OAAO,CAAC;IA4BtE;;OAEG;IACG,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAoClE;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAM7E;;;;;;;;;;OAUG;IACG,eAAe,CACnB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,YAAY,CAAC;IAoCxB;;;OAGG;IACG,aAAa,CACjB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,WAAW,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAiBtE;;OAEG;IACG,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAKtD;;OAEG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM3F;;OAEG;IACG,eAAe,CACnB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,gBAAgB,CAAC,EAAE,MAAM,GACxB,OAAO,CAAC,IAAI,CAAC;IAchB;;;;;;;;;OASG;IACG,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAa7C;;;OAGG;IACG,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW1C;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAItD,gDAAgD;IAChD,OAAO,CAAC,KAAK;CAGd"}