@agentuity/opencode 0.1.40 → 0.1.42

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 (165) hide show
  1. package/README.md +324 -19
  2. package/dist/agents/architect.d.ts +4 -0
  3. package/dist/agents/architect.d.ts.map +1 -0
  4. package/dist/agents/architect.js +259 -0
  5. package/dist/agents/architect.js.map +1 -0
  6. package/dist/agents/builder.d.ts +1 -1
  7. package/dist/agents/builder.d.ts.map +1 -1
  8. package/dist/agents/builder.js +44 -1
  9. package/dist/agents/builder.js.map +1 -1
  10. package/dist/agents/index.d.ts.map +1 -1
  11. package/dist/agents/index.js +6 -0
  12. package/dist/agents/index.js.map +1 -1
  13. package/dist/agents/lead.d.ts +1 -1
  14. package/dist/agents/lead.d.ts.map +1 -1
  15. package/dist/agents/lead.js +185 -22
  16. package/dist/agents/lead.js.map +1 -1
  17. package/dist/agents/planner.d.ts +4 -0
  18. package/dist/agents/planner.d.ts.map +1 -0
  19. package/dist/agents/planner.js +158 -0
  20. package/dist/agents/planner.js.map +1 -0
  21. package/dist/agents/runner.d.ts +4 -0
  22. package/dist/agents/runner.d.ts.map +1 -0
  23. package/dist/agents/runner.js +364 -0
  24. package/dist/agents/runner.js.map +1 -0
  25. package/dist/agents/types.d.ts +5 -1
  26. package/dist/agents/types.d.ts.map +1 -1
  27. package/dist/background/concurrency.d.ts +36 -0
  28. package/dist/background/concurrency.d.ts.map +1 -0
  29. package/dist/background/concurrency.js +92 -0
  30. package/dist/background/concurrency.js.map +1 -0
  31. package/dist/background/index.d.ts +5 -0
  32. package/dist/background/index.d.ts.map +1 -0
  33. package/dist/background/index.js +4 -0
  34. package/dist/background/index.js.map +1 -0
  35. package/dist/background/manager.d.ts +54 -0
  36. package/dist/background/manager.d.ts.map +1 -0
  37. package/dist/background/manager.js +409 -0
  38. package/dist/background/manager.js.map +1 -0
  39. package/dist/background/types.d.ts +47 -0
  40. package/dist/background/types.d.ts.map +1 -0
  41. package/dist/background/types.js +2 -0
  42. package/dist/background/types.js.map +1 -0
  43. package/dist/config/index.d.ts +2 -0
  44. package/dist/config/index.d.ts.map +1 -1
  45. package/dist/config/index.js +2 -0
  46. package/dist/config/index.js.map +1 -1
  47. package/dist/config/loader.d.ts +24 -0
  48. package/dist/config/loader.d.ts.map +1 -1
  49. package/dist/config/loader.js +102 -23
  50. package/dist/config/loader.js.map +1 -1
  51. package/dist/config/presets.d.ts +16 -0
  52. package/dist/config/presets.d.ts.map +1 -0
  53. package/dist/config/presets.js +20 -0
  54. package/dist/config/presets.js.map +1 -0
  55. package/dist/config/validation.d.ts +26 -0
  56. package/dist/config/validation.d.ts.map +1 -0
  57. package/dist/config/validation.js +48 -0
  58. package/dist/config/validation.js.map +1 -0
  59. package/dist/index.d.ts +1 -1
  60. package/dist/index.d.ts.map +1 -1
  61. package/dist/index.js.map +1 -1
  62. package/dist/plugin/hooks/cadence.d.ts.map +1 -1
  63. package/dist/plugin/hooks/cadence.js +3 -1
  64. package/dist/plugin/hooks/cadence.js.map +1 -1
  65. package/dist/plugin/hooks/keyword.d.ts.map +1 -1
  66. package/dist/plugin/hooks/keyword.js +3 -0
  67. package/dist/plugin/hooks/keyword.js.map +1 -1
  68. package/dist/plugin/plugin.d.ts.map +1 -1
  69. package/dist/plugin/plugin.js +335 -36
  70. package/dist/plugin/plugin.js.map +1 -1
  71. package/dist/skills/frontmatter.d.ts +7 -0
  72. package/dist/skills/frontmatter.d.ts.map +1 -0
  73. package/dist/skills/frontmatter.js +17 -0
  74. package/dist/skills/frontmatter.js.map +1 -0
  75. package/dist/skills/index.d.ts +4 -0
  76. package/dist/skills/index.d.ts.map +1 -0
  77. package/dist/skills/index.js +4 -0
  78. package/dist/skills/index.js.map +1 -0
  79. package/dist/skills/loader.d.ts +20 -0
  80. package/dist/skills/loader.d.ts.map +1 -0
  81. package/dist/skills/loader.js +152 -0
  82. package/dist/skills/loader.js.map +1 -0
  83. package/dist/skills/types.d.ts +41 -0
  84. package/dist/skills/types.d.ts.map +1 -0
  85. package/dist/skills/types.js +2 -0
  86. package/dist/skills/types.js.map +1 -0
  87. package/dist/tmux/decision-engine.d.ts +24 -0
  88. package/dist/tmux/decision-engine.d.ts.map +1 -0
  89. package/dist/tmux/decision-engine.js +193 -0
  90. package/dist/tmux/decision-engine.js.map +1 -0
  91. package/dist/tmux/executor.d.ts +84 -0
  92. package/dist/tmux/executor.d.ts.map +1 -0
  93. package/dist/tmux/executor.js +546 -0
  94. package/dist/tmux/executor.js.map +1 -0
  95. package/dist/tmux/index.d.ts +7 -0
  96. package/dist/tmux/index.d.ts.map +1 -0
  97. package/dist/tmux/index.js +7 -0
  98. package/dist/tmux/index.js.map +1 -0
  99. package/dist/tmux/manager.d.ts +116 -0
  100. package/dist/tmux/manager.d.ts.map +1 -0
  101. package/dist/tmux/manager.js +488 -0
  102. package/dist/tmux/manager.js.map +1 -0
  103. package/dist/tmux/state-query.d.ts +7 -0
  104. package/dist/tmux/state-query.d.ts.map +1 -0
  105. package/dist/tmux/state-query.js +70 -0
  106. package/dist/tmux/state-query.js.map +1 -0
  107. package/dist/tmux/types.d.ts +97 -0
  108. package/dist/tmux/types.d.ts.map +1 -0
  109. package/dist/tmux/types.js +8 -0
  110. package/dist/tmux/types.js.map +1 -0
  111. package/dist/tmux/utils.d.ts +32 -0
  112. package/dist/tmux/utils.d.ts.map +1 -0
  113. package/dist/tmux/utils.js +80 -0
  114. package/dist/tmux/utils.js.map +1 -0
  115. package/dist/tools/background.d.ts +61 -0
  116. package/dist/tools/background.d.ts.map +1 -0
  117. package/dist/tools/background.js +78 -0
  118. package/dist/tools/background.js.map +1 -0
  119. package/dist/tools/delegate.d.ts +6 -0
  120. package/dist/tools/delegate.d.ts.map +1 -1
  121. package/dist/tools/delegate.js +8 -2
  122. package/dist/tools/delegate.js.map +1 -1
  123. package/dist/tools/index.d.ts +1 -0
  124. package/dist/tools/index.d.ts.map +1 -1
  125. package/dist/tools/index.js +1 -0
  126. package/dist/tools/index.js.map +1 -1
  127. package/dist/types.d.ts +118 -18
  128. package/dist/types.d.ts.map +1 -1
  129. package/dist/types.js +49 -7
  130. package/dist/types.js.map +1 -1
  131. package/package.json +4 -3
  132. package/src/agents/architect.ts +262 -0
  133. package/src/agents/builder.ts +44 -1
  134. package/src/agents/index.ts +6 -0
  135. package/src/agents/lead.ts +185 -22
  136. package/src/agents/planner.ts +161 -0
  137. package/src/agents/runner.ts +367 -0
  138. package/src/agents/types.ts +5 -1
  139. package/src/background/concurrency.ts +116 -0
  140. package/src/background/index.ts +4 -0
  141. package/src/background/manager.ts +478 -0
  142. package/src/background/types.ts +52 -0
  143. package/src/config/index.ts +2 -0
  144. package/src/config/loader.ts +128 -31
  145. package/src/config/presets.ts +21 -0
  146. package/src/config/validation.ts +70 -0
  147. package/src/index.ts +1 -0
  148. package/src/plugin/hooks/cadence.ts +2 -1
  149. package/src/plugin/hooks/keyword.ts +3 -0
  150. package/src/plugin/plugin.ts +374 -42
  151. package/src/skills/frontmatter.ts +25 -0
  152. package/src/skills/index.ts +3 -0
  153. package/src/skills/loader.ts +185 -0
  154. package/src/skills/types.ts +43 -0
  155. package/src/tmux/decision-engine.ts +246 -0
  156. package/src/tmux/executor.ts +618 -0
  157. package/src/tmux/index.ts +14 -0
  158. package/src/tmux/manager.ts +577 -0
  159. package/src/tmux/state-query.ts +77 -0
  160. package/src/tmux/types.ts +107 -0
  161. package/src/tmux/utils.ts +85 -0
  162. package/src/tools/background.ts +145 -0
  163. package/src/tools/delegate.ts +8 -2
  164. package/src/tools/index.ts +9 -0
  165. package/src/types.ts +88 -15
@@ -0,0 +1,116 @@
1
+ import type { PluginInput } from '@opencode-ai/plugin';
2
+ import type { TmuxConfig } from './types';
3
+ export interface TmuxSessionManagerCallbacks {
4
+ onLog?: (message: string) => void;
5
+ }
6
+ /**
7
+ * Manages tmux panes for background agents.
8
+ *
9
+ * Architecture:
10
+ * 1. QUERY: Get actual tmux pane state (source of truth)
11
+ * 2. DECIDE: Pure function determines actions based on state
12
+ * 3. EXECUTE: Execute actions with verification
13
+ * 4. UPDATE: Update internal cache only after tmux confirms success
14
+ */
15
+ export declare class TmuxSessionManager {
16
+ private ctx;
17
+ private config;
18
+ private callbacks?;
19
+ private sessions;
20
+ private pendingSessions;
21
+ private pollInterval?;
22
+ private sourcePaneId;
23
+ constructor(ctx: PluginInput, config: TmuxConfig, callbacks?: TmuxSessionManagerCallbacks | undefined);
24
+ /**
25
+ * Check if tmux integration is enabled and available
26
+ */
27
+ isEnabled(): boolean;
28
+ /**
29
+ * Handle a new background session being created
30
+ * This is called by BackgroundManager when a background task starts
31
+ */
32
+ onSessionCreated(event: {
33
+ sessionId: string;
34
+ parentId: string;
35
+ title: string;
36
+ }): Promise<void>;
37
+ /**
38
+ * Get all tracked PIDs for logging
39
+ */
40
+ private getTrackedPids;
41
+ /**
42
+ * Handle a session being deleted
43
+ *
44
+ * Explicitly kills the pane when a background session completes.
45
+ * We can't rely on `opencode attach` exiting because it's an interactive
46
+ * terminal that keeps running even after the session goes idle.
47
+ */
48
+ onSessionDeleted(event: {
49
+ sessionId: string;
50
+ }): Promise<void>;
51
+ /**
52
+ * Clean up all panes on shutdown
53
+ *
54
+ * Kills the entire "Agents" window, which closes all agent panes at once.
55
+ * Falls back to pkill if PID-based cleanup fails.
56
+ */
57
+ cleanup(): Promise<void>;
58
+ /**
59
+ * Synchronous cleanup for shutdown (ensures completion before exit)
60
+ *
61
+ * Uses spawnSync to guarantee the tmux commands complete before the
62
+ * process exits, which is necessary for signal handlers.
63
+ */
64
+ cleanupSync(): void;
65
+ /**
66
+ * Start polling for session status
67
+ */
68
+ private startPolling;
69
+ /**
70
+ * Stop polling
71
+ */
72
+ private stopPolling;
73
+ /**
74
+ * Poll active sessions for status changes
75
+ */
76
+ private pollSessions;
77
+ /**
78
+ * Get session mappings for decision engine
79
+ */
80
+ private getSessionMappings;
81
+ private getServerUrl;
82
+ private applyActionResults;
83
+ /**
84
+ * Find and report orphaned processes (does NOT kill them by default).
85
+ * Call this manually if you need to identify orphaned processes after a crash.
86
+ *
87
+ * Note: This method only reports - it does not kill processes because we cannot
88
+ * reliably distinguish between processes we spawned vs user-initiated sessions.
89
+ * The shutdown cleanup (cleanup/cleanupSync) is safe because it only kills PIDs
90
+ * we explicitly tracked during this session.
91
+ */
92
+ reportOrphanedProcesses(): Promise<number[]>;
93
+ private findOrphanedAttachPids;
94
+ private extractSessionId;
95
+ /**
96
+ * Kill a process and all its children synchronously.
97
+ *
98
+ * This is necessary because we spawn `bash -c "opencode attach ...; tmux kill-pane"`
99
+ * and #{pane_pid} returns the bash PID, not the opencode attach PID.
100
+ */
101
+ private killProcessByPidSync;
102
+ private log;
103
+ /**
104
+ * Static method to clean up orphaned processes without needing an instance.
105
+ * This is useful for manual cleanup commands.
106
+ *
107
+ * @param serverUrl - Optional server URL to filter processes
108
+ * @param logger - Optional logging function
109
+ * @returns Object with cleanup results
110
+ */
111
+ static cleanupOrphans(serverUrl?: string, logger?: (msg: string) => void): Promise<{
112
+ killed: number;
113
+ windowClosed: boolean;
114
+ }>;
115
+ }
116
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/tmux/manager.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,KAAK,EAEX,UAAU,EAKV,MAAM,SAAS,CAAC;AA8BjB,MAAM,WAAW,2BAA2B;IAC3C,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC;AAED;;;;;;;;GAQG;AACH,qBAAa,kBAAkB;IAO7B,OAAO,CAAC,GAAG;IACX,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,SAAS,CAAC;IARnB,OAAO,CAAC,QAAQ,CAAqC;IACrD,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,YAAY,CAAC,CAAiC;IACtD,OAAO,CAAC,YAAY,CAAqB;gBAGhC,GAAG,EAAE,WAAW,EAChB,MAAM,EAAE,UAAU,EAClB,SAAS,CAAC,EAAE,2BAA2B,YAAA;IAKhD;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;;OAGG;IACG,gBAAgB,CAAC,KAAK,EAAE;QAC7B,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;QACjB,KAAK,EAAE,MAAM,CAAC;KACd,GAAG,OAAO,CAAC,IAAI,CAAC;IA8FjB;;OAEG;IACH,OAAO,CAAC,cAAc;IAMtB;;;;;;OAMG;IACG,gBAAgB,CAAC,KAAK,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAoCnE;;;;;OAKG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IA6B9B;;;;;OAKG;IACH,WAAW,IAAI,IAAI;IAgCnB;;OAEG;IACH,OAAO,CAAC,YAAY;IAOpB;;OAEG;IACH,OAAO,CAAC,WAAW;IAMnB;;OAEG;YACW,YAAY;IAgC1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,YAAY;IAWpB,OAAO,CAAC,kBAAkB;IAuC1B;;;;;;;;OAQG;IACG,uBAAuB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YAoBpC,sBAAsB;IA6BpC,OAAO,CAAC,gBAAgB;IAKxB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAmD5B,OAAO,CAAC,GAAG;IAIX;;;;;;;OAOG;WACU,cAAc,CAC1B,SAAS,CAAC,EAAE,MAAM,EAClB,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,GAC5B,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,OAAO,CAAA;KAAE,CAAC;CAqBrD"}
@@ -0,0 +1,488 @@
1
+ import { spawn, spawnSync } from 'bun';
2
+ import { POLL_INTERVAL_MS, SESSION_MISSING_GRACE_MS, SESSION_TIMEOUT_MS } from './types';
3
+ import { getCurrentPaneId, getTmuxPath, isInsideTmux } from './utils';
4
+ import { queryWindowState } from './state-query';
5
+ import { decideSpawnActions } from './decision-engine';
6
+ import { executeActions, closeAgentsWindow, closeAgentsWindowSync, closePaneById, killProcessByPid, killOrphanedAttachProcesses, killOrphanedAttachProcessesSync, } from './executor';
7
+ /**
8
+ * Check if the OpenCode server is running by hitting the health endpoint
9
+ */
10
+ async function isServerRunning(serverUrl) {
11
+ try {
12
+ const healthUrl = new URL('/health', serverUrl).toString();
13
+ const response = await fetch(healthUrl, {
14
+ signal: AbortSignal.timeout(2000),
15
+ });
16
+ return response.ok;
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }
22
+ /**
23
+ * Manages tmux panes for background agents.
24
+ *
25
+ * Architecture:
26
+ * 1. QUERY: Get actual tmux pane state (source of truth)
27
+ * 2. DECIDE: Pure function determines actions based on state
28
+ * 3. EXECUTE: Execute actions with verification
29
+ * 4. UPDATE: Update internal cache only after tmux confirms success
30
+ */
31
+ export class TmuxSessionManager {
32
+ ctx;
33
+ config;
34
+ callbacks;
35
+ sessions = new Map();
36
+ pendingSessions = new Set();
37
+ pollInterval;
38
+ sourcePaneId;
39
+ constructor(ctx, config, callbacks) {
40
+ this.ctx = ctx;
41
+ this.config = config;
42
+ this.callbacks = callbacks;
43
+ this.sourcePaneId = getCurrentPaneId();
44
+ }
45
+ /**
46
+ * Check if tmux integration is enabled and available
47
+ */
48
+ isEnabled() {
49
+ return this.config.enabled && isInsideTmux();
50
+ }
51
+ /**
52
+ * Handle a new background session being created
53
+ * This is called by BackgroundManager when a background task starts
54
+ */
55
+ async onSessionCreated(event) {
56
+ this.log(`onSessionCreated called for ${event.sessionId} (${event.title})`);
57
+ if (!this.isEnabled()) {
58
+ this.log(`Skipping - tmux not enabled (config: ${this.config.enabled}, insideTmux: ${isInsideTmux()})`);
59
+ return;
60
+ }
61
+ if (this.pendingSessions.has(event.sessionId) || this.sessions.has(event.sessionId)) {
62
+ this.log(`Skipping - session ${event.sessionId} already pending or tracked`);
63
+ return;
64
+ }
65
+ this.pendingSessions.add(event.sessionId);
66
+ try {
67
+ const tmuxPath = await getTmuxPath();
68
+ if (!tmuxPath) {
69
+ this.log('tmux binary not found.');
70
+ return;
71
+ }
72
+ if (!this.sourcePaneId) {
73
+ this.sourcePaneId = getCurrentPaneId();
74
+ }
75
+ if (!this.sourcePaneId) {
76
+ this.log('Unable to determine source pane id.');
77
+ return;
78
+ }
79
+ const state = await queryWindowState(this.sourcePaneId);
80
+ if (!state) {
81
+ this.log('Failed to query tmux window state.');
82
+ return;
83
+ }
84
+ const decision = decideSpawnActions(state, event.sessionId, event.title, {
85
+ mainPaneMinWidth: this.config.mainPaneMinWidth,
86
+ agentPaneMinWidth: this.config.agentPaneMinWidth,
87
+ maxPanes: this.config.maxPanes,
88
+ }, this.getSessionMappings());
89
+ if (!decision.canSpawn) {
90
+ if (decision.reason) {
91
+ this.log(`Cannot spawn pane: ${decision.reason}`);
92
+ }
93
+ return;
94
+ }
95
+ const serverUrl = this.getServerUrl();
96
+ if (!serverUrl) {
97
+ this.log('Unable to determine OpenCode server URL.');
98
+ return;
99
+ }
100
+ // Check if server is actually running before attempting to spawn
101
+ const serverRunning = await isServerRunning(serverUrl);
102
+ if (!serverRunning) {
103
+ this.log(`Server not running at ${serverUrl}. Start opencode with --port flag to enable tmux integration.`);
104
+ return;
105
+ }
106
+ const result = await executeActions(decision.actions, {
107
+ config: this.config,
108
+ serverUrl,
109
+ windowState: state,
110
+ });
111
+ if (!result.success) {
112
+ this.log('Failed to execute tmux actions.');
113
+ return;
114
+ }
115
+ this.applyActionResults(decision.actions, result.results);
116
+ this.log(`Successfully spawned pane for ${event.sessionId}. Tracking ${this.sessions.size} sessions. PIDs: ${this.getTrackedPids().join(', ') || 'none'}`);
117
+ if (this.sessions.size > 0) {
118
+ this.startPolling();
119
+ }
120
+ }
121
+ finally {
122
+ this.pendingSessions.delete(event.sessionId);
123
+ }
124
+ }
125
+ /**
126
+ * Get all tracked PIDs for logging
127
+ */
128
+ getTrackedPids() {
129
+ return Array.from(this.sessions.values())
130
+ .map((s) => s.pid)
131
+ .filter((pid) => pid !== undefined);
132
+ }
133
+ /**
134
+ * Handle a session being deleted
135
+ *
136
+ * Explicitly kills the pane when a background session completes.
137
+ * We can't rely on `opencode attach` exiting because it's an interactive
138
+ * terminal that keeps running even after the session goes idle.
139
+ */
140
+ async onSessionDeleted(event) {
141
+ this.log(`onSessionDeleted called for ${event.sessionId}`);
142
+ if (!this.isEnabled()) {
143
+ this.log(`Skipping delete - tmux not enabled`);
144
+ return;
145
+ }
146
+ // Find the session in our mappings
147
+ const session = this.sessions.get(event.sessionId);
148
+ if (!session) {
149
+ this.log(`Session ${event.sessionId} not found in tracked sessions`);
150
+ return;
151
+ }
152
+ this.log(`Closing pane ${session.paneId} (PID: ${session.pid}) for session ${event.sessionId}`);
153
+ // Kill the pane explicitly - opencode attach won't exit on its own
154
+ const result = await closePaneById(session.paneId, session.pid);
155
+ if (!result.success) {
156
+ this.log(`Failed to close pane ${session.paneId}: ${result.error}`);
157
+ }
158
+ else {
159
+ this.log(`Successfully closed pane ${session.paneId}`);
160
+ }
161
+ // Update internal state
162
+ this.sessions.delete(event.sessionId);
163
+ this.log(`Removed session from tracking. Now tracking ${this.sessions.size} sessions.`);
164
+ if (this.sessions.size === 0) {
165
+ this.stopPolling();
166
+ }
167
+ }
168
+ /**
169
+ * Clean up all panes on shutdown
170
+ *
171
+ * Kills the entire "Agents" window, which closes all agent panes at once.
172
+ * Falls back to pkill if PID-based cleanup fails.
173
+ */
174
+ async cleanup() {
175
+ this.log('Starting cleanup...');
176
+ this.stopPolling();
177
+ let pidCleanupFailed = false;
178
+ for (const session of this.sessions.values()) {
179
+ if (!session.pid)
180
+ continue;
181
+ this.log(`Killing process ${session.pid} for session ${session.sessionId}`);
182
+ const success = await killProcessByPid(session.pid);
183
+ if (!success) {
184
+ this.log(`Failed to kill process ${session.pid} for session ${session.sessionId}`);
185
+ pidCleanupFailed = true;
186
+ }
187
+ }
188
+ // Kill the entire agents window - this closes all panes at once
189
+ await closeAgentsWindow();
190
+ this.sessions.clear();
191
+ // Fallback: if PID-based cleanup failed, use pkill to catch any orphans
192
+ if (pidCleanupFailed) {
193
+ this.log('PID-based cleanup had failures, running fallback cleanup...');
194
+ const serverUrl = this.getServerUrl();
195
+ await killOrphanedAttachProcesses(serverUrl, (msg) => this.log(msg));
196
+ }
197
+ this.log('Cleanup complete');
198
+ }
199
+ /**
200
+ * Synchronous cleanup for shutdown (ensures completion before exit)
201
+ *
202
+ * Uses spawnSync to guarantee the tmux commands complete before the
203
+ * process exits, which is necessary for signal handlers.
204
+ */
205
+ cleanupSync() {
206
+ this.log('Starting sync cleanup...');
207
+ this.stopPolling();
208
+ let pidCleanupFailed = false;
209
+ for (const session of this.sessions.values()) {
210
+ if (!session.pid)
211
+ continue;
212
+ this.log(`Killing process ${session.pid} for session ${session.sessionId}`);
213
+ this.killProcessByPidSync(session.pid);
214
+ // Check if process is still alive after kill attempt
215
+ try {
216
+ process.kill(session.pid, 0);
217
+ pidCleanupFailed = true; // Process still exists
218
+ }
219
+ catch {
220
+ // Process is dead, good
221
+ }
222
+ }
223
+ // Kill the entire agents window synchronously
224
+ closeAgentsWindowSync();
225
+ this.sessions.clear();
226
+ // Fallback: if PID-based cleanup failed, use pkill to catch any orphans
227
+ if (pidCleanupFailed) {
228
+ this.log('PID-based cleanup had failures, running fallback cleanup...');
229
+ const serverUrl = this.getServerUrl();
230
+ killOrphanedAttachProcessesSync(serverUrl, (msg) => this.log(msg));
231
+ }
232
+ this.log('Sync cleanup complete');
233
+ }
234
+ /**
235
+ * Start polling for session status
236
+ */
237
+ startPolling() {
238
+ if (this.pollInterval)
239
+ return;
240
+ this.pollInterval = setInterval(() => {
241
+ void this.pollSessions();
242
+ }, POLL_INTERVAL_MS);
243
+ }
244
+ /**
245
+ * Stop polling
246
+ */
247
+ stopPolling() {
248
+ if (!this.pollInterval)
249
+ return;
250
+ clearInterval(this.pollInterval);
251
+ this.pollInterval = undefined;
252
+ }
253
+ /**
254
+ * Poll active sessions for status changes
255
+ */
256
+ async pollSessions() {
257
+ if (!this.isEnabled())
258
+ return;
259
+ if (!this.sourcePaneId)
260
+ return;
261
+ const state = await queryWindowState(this.sourcePaneId);
262
+ if (!state)
263
+ return;
264
+ const now = Date.now();
265
+ for (const session of this.sessions.values()) {
266
+ const pane = findPane(state, session.paneId);
267
+ if (pane) {
268
+ session.lastSeenAt = new Date();
269
+ continue;
270
+ }
271
+ const missingFor = now - session.lastSeenAt.getTime();
272
+ if (missingFor > SESSION_MISSING_GRACE_MS) {
273
+ this.sessions.delete(session.sessionId);
274
+ continue;
275
+ }
276
+ const age = now - session.createdAt.getTime();
277
+ if (age > SESSION_TIMEOUT_MS) {
278
+ this.sessions.delete(session.sessionId);
279
+ }
280
+ }
281
+ if (this.sessions.size === 0) {
282
+ this.stopPolling();
283
+ }
284
+ }
285
+ /**
286
+ * Get session mappings for decision engine
287
+ */
288
+ getSessionMappings() {
289
+ return Array.from(this.sessions.values()).map((session) => ({
290
+ sessionId: session.sessionId,
291
+ paneId: session.paneId,
292
+ createdAt: session.createdAt,
293
+ }));
294
+ }
295
+ getServerUrl() {
296
+ const ctx = this.ctx;
297
+ const serverUrl = ctx.serverUrl ?? ctx.baseUrl ?? ctx.client?.baseUrl;
298
+ if (!serverUrl)
299
+ return undefined;
300
+ return typeof serverUrl === 'string' ? serverUrl : serverUrl.toString();
301
+ }
302
+ applyActionResults(actions, results) {
303
+ const now = new Date();
304
+ for (const [index, action] of actions.entries()) {
305
+ const actionResult = results[index]?.result;
306
+ switch (action.type) {
307
+ case 'close':
308
+ this.sessions.delete(action.sessionId);
309
+ break;
310
+ case 'replace':
311
+ this.sessions.delete(action.oldSessionId);
312
+ this.sessions.set(action.newSessionId, {
313
+ sessionId: action.newSessionId,
314
+ paneId: action.paneId,
315
+ pid: actionResult?.pid,
316
+ description: action.description,
317
+ createdAt: now,
318
+ lastSeenAt: now,
319
+ });
320
+ break;
321
+ case 'spawn': {
322
+ const paneId = actionResult?.paneId;
323
+ if (!paneId)
324
+ break;
325
+ this.sessions.set(action.sessionId, {
326
+ sessionId: action.sessionId,
327
+ paneId,
328
+ pid: actionResult?.pid,
329
+ description: action.description,
330
+ createdAt: now,
331
+ lastSeenAt: now,
332
+ });
333
+ break;
334
+ }
335
+ }
336
+ }
337
+ }
338
+ /**
339
+ * Find and report orphaned processes (does NOT kill them by default).
340
+ * Call this manually if you need to identify orphaned processes after a crash.
341
+ *
342
+ * Note: This method only reports - it does not kill processes because we cannot
343
+ * reliably distinguish between processes we spawned vs user-initiated sessions.
344
+ * The shutdown cleanup (cleanup/cleanupSync) is safe because it only kills PIDs
345
+ * we explicitly tracked during this session.
346
+ */
347
+ async reportOrphanedProcesses() {
348
+ if (!this.isEnabled())
349
+ return [];
350
+ const serverUrl = this.getServerUrl();
351
+ if (!serverUrl)
352
+ return [];
353
+ const trackedSessionIds = new Set(this.sessions.keys());
354
+ const orphanedPids = await this.findOrphanedAttachPids(serverUrl, trackedSessionIds);
355
+ if (orphanedPids.length > 0) {
356
+ this.log(`Found ${orphanedPids.length} potentially orphaned processes: ${orphanedPids.join(', ')}`);
357
+ this.log('These may be user-initiated sessions. Run "pkill -f opencode\\ attach" to clean them up manually if needed.');
358
+ }
359
+ return orphanedPids;
360
+ }
361
+ async findOrphanedAttachPids(serverUrl, trackedSessionIds) {
362
+ try {
363
+ const proc = spawn(['ps', 'aux'], { stdout: 'pipe', stderr: 'pipe' });
364
+ await proc.exited;
365
+ const output = await new Response(proc.stdout).text();
366
+ const lines = output.split('\n');
367
+ const matches = [];
368
+ for (const line of lines) {
369
+ if (!line.includes('opencode attach'))
370
+ continue;
371
+ if (!line.includes(serverUrl))
372
+ continue;
373
+ const parts = line.trim().split(/\s+/);
374
+ const pid = Number(parts[1]);
375
+ if (!Number.isFinite(pid) || pid <= 0)
376
+ continue;
377
+ if (pid === process.pid)
378
+ continue;
379
+ const sessionId = this.extractSessionId(line);
380
+ if (sessionId && trackedSessionIds.has(sessionId))
381
+ continue;
382
+ matches.push(pid);
383
+ }
384
+ return matches;
385
+ }
386
+ catch {
387
+ return [];
388
+ }
389
+ }
390
+ extractSessionId(line) {
391
+ const match = line.match(/--session\s+(['"]?)([^'";\s]+)\1/);
392
+ return match?.[2];
393
+ }
394
+ /**
395
+ * Kill a process and all its children synchronously.
396
+ *
397
+ * This is necessary because we spawn `bash -c "opencode attach ...; tmux kill-pane"`
398
+ * and #{pane_pid} returns the bash PID, not the opencode attach PID.
399
+ */
400
+ killProcessByPidSync(pid) {
401
+ if (!Number.isFinite(pid) || pid <= 0)
402
+ return;
403
+ // First, kill all child processes
404
+ try {
405
+ spawnSync(['pkill', '-TERM', '-P', String(pid)]);
406
+ }
407
+ catch {
408
+ // Ignore errors - children may not exist
409
+ }
410
+ // Then kill the parent
411
+ try {
412
+ process.kill(pid, 'SIGTERM');
413
+ }
414
+ catch (error) {
415
+ const code = error.code;
416
+ if (code === 'ESRCH')
417
+ return;
418
+ return;
419
+ }
420
+ // Wait for processes to die
421
+ try {
422
+ const buffer = new SharedArrayBuffer(4);
423
+ const view = new Int32Array(buffer);
424
+ Atomics.wait(view, 0, 0, 1000);
425
+ }
426
+ catch {
427
+ // ignore sleep errors
428
+ }
429
+ // Check if parent is dead
430
+ try {
431
+ process.kill(pid, 0);
432
+ }
433
+ catch (error) {
434
+ const code = error.code;
435
+ if (code === 'ESRCH')
436
+ return; // Dead, good
437
+ }
438
+ // Force kill children
439
+ try {
440
+ spawnSync(['pkill', '-KILL', '-P', String(pid)]);
441
+ }
442
+ catch {
443
+ // Ignore errors
444
+ }
445
+ // Force kill parent
446
+ try {
447
+ process.kill(pid, 'SIGKILL');
448
+ }
449
+ catch {
450
+ // ignore errors
451
+ }
452
+ }
453
+ log(message) {
454
+ this.callbacks?.onLog?.(`[tmux] ${message}`);
455
+ }
456
+ /**
457
+ * Static method to clean up orphaned processes without needing an instance.
458
+ * This is useful for manual cleanup commands.
459
+ *
460
+ * @param serverUrl - Optional server URL to filter processes
461
+ * @param logger - Optional logging function
462
+ * @returns Object with cleanup results
463
+ */
464
+ static async cleanupOrphans(serverUrl, logger) {
465
+ const log = logger ?? (() => { });
466
+ log('Starting orphan cleanup...');
467
+ // First, try to close the agents window (recovers from persisted file)
468
+ let windowClosed = false;
469
+ try {
470
+ await closeAgentsWindow();
471
+ windowClosed = true;
472
+ log('Closed agents window');
473
+ }
474
+ catch {
475
+ log('No agents window to close');
476
+ }
477
+ // Then kill any orphaned processes
478
+ const killed = await killOrphanedAttachProcesses(serverUrl, log);
479
+ log(`Orphan cleanup complete: ${killed} processes killed, window closed: ${windowClosed}`);
480
+ return { killed, windowClosed };
481
+ }
482
+ }
483
+ function findPane(state, paneId) {
484
+ if (state.mainPane?.paneId === paneId)
485
+ return state.mainPane;
486
+ return state.agentPanes.find((pane) => pane.paneId === paneId);
487
+ }
488
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/tmux/manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import type { WindowState } from './types';
2
+ /**
3
+ * Query the current tmux window state
4
+ * Returns information about all panes in the current window
5
+ */
6
+ export declare function queryWindowState(sourcePaneId: string): Promise<WindowState | null>;
7
+ //# sourceMappingURL=state-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state-query.d.ts","sourceRoot":"","sources":["../../src/tmux/state-query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAgB,MAAM,SAAS,CAAC;AAGzD;;;GAGG;AACH,wBAAsB,gBAAgB,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC,CAqExF"}