@ai-devkit/agent-manager 0.1.0

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 (57) hide show
  1. package/.eslintrc.json +31 -0
  2. package/dist/AgentManager.d.ts +104 -0
  3. package/dist/AgentManager.d.ts.map +1 -0
  4. package/dist/AgentManager.js +185 -0
  5. package/dist/AgentManager.js.map +1 -0
  6. package/dist/adapters/AgentAdapter.d.ts +76 -0
  7. package/dist/adapters/AgentAdapter.d.ts.map +1 -0
  8. package/dist/adapters/AgentAdapter.js +20 -0
  9. package/dist/adapters/AgentAdapter.js.map +1 -0
  10. package/dist/adapters/ClaudeCodeAdapter.d.ts +58 -0
  11. package/dist/adapters/ClaudeCodeAdapter.d.ts.map +1 -0
  12. package/dist/adapters/ClaudeCodeAdapter.js +274 -0
  13. package/dist/adapters/ClaudeCodeAdapter.js.map +1 -0
  14. package/dist/adapters/index.d.ts +4 -0
  15. package/dist/adapters/index.d.ts.map +1 -0
  16. package/dist/adapters/index.js +8 -0
  17. package/dist/adapters/index.js.map +1 -0
  18. package/dist/index.d.ts +10 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +23 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/terminal/TerminalFocusManager.d.ts +22 -0
  23. package/dist/terminal/TerminalFocusManager.d.ts.map +1 -0
  24. package/dist/terminal/TerminalFocusManager.js +196 -0
  25. package/dist/terminal/TerminalFocusManager.js.map +1 -0
  26. package/dist/terminal/index.d.ts +3 -0
  27. package/dist/terminal/index.d.ts.map +1 -0
  28. package/dist/terminal/index.js +6 -0
  29. package/dist/terminal/index.js.map +1 -0
  30. package/dist/utils/file.d.ts +52 -0
  31. package/dist/utils/file.d.ts.map +1 -0
  32. package/dist/utils/file.js +135 -0
  33. package/dist/utils/file.js.map +1 -0
  34. package/dist/utils/index.d.ts +4 -0
  35. package/dist/utils/index.d.ts.map +1 -0
  36. package/dist/utils/index.js +15 -0
  37. package/dist/utils/index.js.map +1 -0
  38. package/dist/utils/process.d.ts +61 -0
  39. package/dist/utils/process.d.ts.map +1 -0
  40. package/dist/utils/process.js +166 -0
  41. package/dist/utils/process.js.map +1 -0
  42. package/jest.config.js +21 -0
  43. package/package.json +42 -0
  44. package/project.json +29 -0
  45. package/src/AgentManager.ts +198 -0
  46. package/src/__tests__/AgentManager.test.ts +308 -0
  47. package/src/__tests__/adapters/ClaudeCodeAdapter.test.ts +286 -0
  48. package/src/adapters/AgentAdapter.ts +94 -0
  49. package/src/adapters/ClaudeCodeAdapter.ts +344 -0
  50. package/src/adapters/index.ts +3 -0
  51. package/src/index.ts +12 -0
  52. package/src/terminal/TerminalFocusManager.ts +206 -0
  53. package/src/terminal/index.ts +2 -0
  54. package/src/utils/file.ts +100 -0
  55. package/src/utils/index.ts +3 -0
  56. package/src/utils/process.ts +184 -0
  57. package/tsconfig.json +17 -0
@@ -0,0 +1,274 @@
1
+ "use strict";
2
+ /**
3
+ * Claude Code Adapter
4
+ *
5
+ * Detects running Claude Code agents by reading session files
6
+ * from ~/.claude/ directory and correlating with running processes.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.ClaudeCodeAdapter = void 0;
43
+ const fs = __importStar(require("fs"));
44
+ const path = __importStar(require("path"));
45
+ const AgentAdapter_1 = require("./AgentAdapter");
46
+ const process_1 = require("../utils/process");
47
+ const file_1 = require("../utils/file");
48
+ /**
49
+ * Claude Code Adapter
50
+ *
51
+ * Detects Claude Code agents by:
52
+ * 1. Finding running claude processes
53
+ * 2. Reading session files from ~/.claude/projects/
54
+ * 3. Matching sessions to processes via CWD
55
+ * 4. Extracting status from session JSONL
56
+ * 5. Extracting summary from history.jsonl
57
+ */
58
+ class ClaudeCodeAdapter {
59
+ constructor() {
60
+ this.type = 'claude';
61
+ const homeDir = process.env.HOME || process.env.USERPROFILE || '';
62
+ this.claudeDir = path.join(homeDir, '.claude');
63
+ this.projectsDir = path.join(this.claudeDir, 'projects');
64
+ this.historyPath = path.join(this.claudeDir, 'history.jsonl');
65
+ }
66
+ /**
67
+ * Check if this adapter can handle a given process
68
+ */
69
+ canHandle(processInfo) {
70
+ return processInfo.command.toLowerCase().includes('claude');
71
+ }
72
+ /**
73
+ * Detect running Claude Code agents
74
+ */
75
+ async detectAgents() {
76
+ // 1. Find running claude processes
77
+ const claudeProcesses = (0, process_1.listProcesses)({ namePattern: 'claude' });
78
+ if (claudeProcesses.length === 0) {
79
+ return [];
80
+ }
81
+ // 2. Read all sessions
82
+ const sessions = this.readSessions();
83
+ // 3. Read history for summaries
84
+ const history = this.readHistory();
85
+ // 4. Group processes by CWD
86
+ const processesByCwd = new Map();
87
+ for (const p of claudeProcesses) {
88
+ const list = processesByCwd.get(p.cwd) || [];
89
+ list.push(p);
90
+ processesByCwd.set(p.cwd, list);
91
+ }
92
+ // 5. Match sessions to processes
93
+ const agents = [];
94
+ for (const [cwd, processes] of processesByCwd) {
95
+ // Find sessions for this project path
96
+ const projectSessions = sessions.filter(s => s.projectPath === cwd);
97
+ if (projectSessions.length === 0) {
98
+ continue;
99
+ }
100
+ // Sort sessions by last active time (newest first)
101
+ projectSessions.sort((a, b) => {
102
+ const timeA = a.lastActive?.getTime() || 0;
103
+ const timeB = b.lastActive?.getTime() || 0;
104
+ return timeB - timeA;
105
+ });
106
+ // Map processes to the most recent sessions
107
+ // If there are 2 processes, we take the 2 most recent sessions
108
+ const activeSessions = projectSessions.slice(0, processes.length);
109
+ for (let i = 0; i < activeSessions.length; i++) {
110
+ const session = activeSessions[i];
111
+ const process = processes[i]; // Assign process to session (arbitrary 1-to-1 mapping)
112
+ const historyEntry = [...history].reverse().find(h => h.sessionId === session.sessionId);
113
+ const summary = historyEntry?.display || 'Session started';
114
+ const status = this.determineStatus(session);
115
+ const agentName = this.generateAgentName(session, agents); // Pass currently built agents for collision checks
116
+ agents.push({
117
+ name: agentName,
118
+ type: this.type,
119
+ status,
120
+ summary,
121
+ pid: process.pid,
122
+ projectPath: session.projectPath,
123
+ sessionId: session.sessionId,
124
+ slug: session.slug,
125
+ lastActive: session.lastActive || new Date(),
126
+ });
127
+ }
128
+ }
129
+ return agents;
130
+ }
131
+ /**
132
+ * Read all Claude Code sessions
133
+ */
134
+ readSessions() {
135
+ if (!fs.existsSync(this.projectsDir)) {
136
+ return [];
137
+ }
138
+ const sessions = [];
139
+ const projectDirs = fs.readdirSync(this.projectsDir);
140
+ for (const dirName of projectDirs) {
141
+ if (dirName.startsWith('.')) {
142
+ continue;
143
+ }
144
+ const projectDir = path.join(this.projectsDir, dirName);
145
+ if (!fs.statSync(projectDir).isDirectory()) {
146
+ continue;
147
+ }
148
+ // Read sessions-index.json to get original project path
149
+ const indexPath = path.join(projectDir, 'sessions-index.json');
150
+ if (!fs.existsSync(indexPath)) {
151
+ continue;
152
+ }
153
+ const sessionsIndex = (0, file_1.readJson)(indexPath);
154
+ if (!sessionsIndex) {
155
+ console.error(`Failed to parse ${indexPath}`);
156
+ continue;
157
+ }
158
+ const sessionFiles = fs.readdirSync(projectDir).filter(f => f.endsWith('.jsonl'));
159
+ for (const sessionFile of sessionFiles) {
160
+ const sessionId = sessionFile.replace('.jsonl', '');
161
+ const sessionLogPath = path.join(projectDir, sessionFile);
162
+ try {
163
+ const sessionData = this.readSessionLog(sessionLogPath);
164
+ sessions.push({
165
+ sessionId,
166
+ projectPath: sessionsIndex.originalPath,
167
+ slug: sessionData.slug,
168
+ sessionLogPath,
169
+ lastEntry: sessionData.lastEntry,
170
+ lastActive: sessionData.lastActive,
171
+ });
172
+ }
173
+ catch (error) {
174
+ console.error(`Failed to read session ${sessionId}:`, error);
175
+ continue;
176
+ }
177
+ }
178
+ }
179
+ return sessions;
180
+ }
181
+ /**
182
+ * Read a session JSONL file
183
+ * Only reads last 100 lines for performance with large files
184
+ */
185
+ readSessionLog(logPath) {
186
+ const lines = (0, file_1.readLastLines)(logPath, 100);
187
+ let slug;
188
+ let lastEntry;
189
+ let lastActive;
190
+ for (const line of lines) {
191
+ try {
192
+ const entry = JSON.parse(line);
193
+ if (entry.slug && !slug) {
194
+ slug = entry.slug;
195
+ }
196
+ lastEntry = entry;
197
+ if (entry.timestamp) {
198
+ lastActive = new Date(entry.timestamp);
199
+ }
200
+ }
201
+ catch (error) {
202
+ continue;
203
+ }
204
+ }
205
+ return { slug, lastEntry, lastActive };
206
+ }
207
+ /**
208
+ * Read history.jsonl for user prompts
209
+ * Only reads last 100 lines for performance
210
+ */
211
+ readHistory() {
212
+ return (0, file_1.readJsonLines)(this.historyPath, 100);
213
+ }
214
+ /**
215
+ * Determine agent status from session entry
216
+ */
217
+ determineStatus(session) {
218
+ if (!session.lastEntry) {
219
+ return AgentAdapter_1.AgentStatus.UNKNOWN;
220
+ }
221
+ const entryType = session.lastEntry.type;
222
+ const lastActive = session.lastActive || new Date(0);
223
+ const ageMinutes = (Date.now() - lastActive.getTime()) / 1000 / 60;
224
+ if (ageMinutes > ClaudeCodeAdapter.IDLE_THRESHOLD_MINUTES) {
225
+ return AgentAdapter_1.AgentStatus.IDLE;
226
+ }
227
+ if (entryType === 'user') {
228
+ // Check if user interrupted manually - this puts agent back in waiting state
229
+ const content = session.lastEntry.message?.content;
230
+ if (Array.isArray(content)) {
231
+ const isInterrupted = content.some(c => (c.type === 'text' && c.text?.includes('[Request interrupted')) ||
232
+ (c.type === 'tool_result' && c.content?.includes('[Request interrupted')));
233
+ if (isInterrupted)
234
+ return AgentAdapter_1.AgentStatus.WAITING;
235
+ }
236
+ return AgentAdapter_1.AgentStatus.RUNNING;
237
+ }
238
+ if (entryType === 'progress' || entryType === 'thinking') {
239
+ return AgentAdapter_1.AgentStatus.RUNNING;
240
+ }
241
+ else if (entryType === 'assistant') {
242
+ return AgentAdapter_1.AgentStatus.WAITING;
243
+ }
244
+ else if (entryType === 'system') {
245
+ return AgentAdapter_1.AgentStatus.IDLE;
246
+ }
247
+ return AgentAdapter_1.AgentStatus.UNKNOWN;
248
+ }
249
+ /**
250
+ * Generate unique agent name
251
+ * Uses project basename, appends slug if multiple sessions for same project
252
+ */
253
+ generateAgentName(session, existingAgents) {
254
+ const projectName = path.basename(session.projectPath);
255
+ const sameProjectAgents = existingAgents.filter(a => a.projectPath === session.projectPath);
256
+ if (sameProjectAgents.length === 0) {
257
+ return projectName;
258
+ }
259
+ // Multiple sessions for same project, append slug
260
+ if (session.slug) {
261
+ // Use first word of slug for brevity (with safety check for format)
262
+ const slugPart = session.slug.includes('-')
263
+ ? session.slug.split('-')[0]
264
+ : session.slug.slice(0, 8);
265
+ return `${projectName} (${slugPart})`;
266
+ }
267
+ // No slug available, use session ID prefix
268
+ return `${projectName} (${session.sessionId.slice(0, 8)})`;
269
+ }
270
+ }
271
+ exports.ClaudeCodeAdapter = ClaudeCodeAdapter;
272
+ /** Threshold in minutes before considering a session idle */
273
+ ClaudeCodeAdapter.IDLE_THRESHOLD_MINUTES = 5;
274
+ //# sourceMappingURL=ClaudeCodeAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClaudeCodeAdapter.js","sourceRoot":"","sources":["../../src/adapters/ClaudeCodeAdapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ export { ClaudeCodeAdapter } from './ClaudeCodeAdapter';
2
+ export { AgentStatus } from './AgentAdapter';
3
+ export type { AgentAdapter, AgentType, AgentInfo, ProcessInfo } from './AgentAdapter';
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AgentStatus = exports.ClaudeCodeAdapter = void 0;
4
+ var ClaudeCodeAdapter_1 = require("./ClaudeCodeAdapter");
5
+ Object.defineProperty(exports, "ClaudeCodeAdapter", { enumerable: true, get: function () { return ClaudeCodeAdapter_1.ClaudeCodeAdapter; } });
6
+ var AgentAdapter_1 = require("./AgentAdapter");
7
+ Object.defineProperty(exports, "AgentStatus", { enumerable: true, get: function () { return AgentAdapter_1.AgentStatus; } });
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/adapters/index.ts"],"names":[],"mappings":";;;AAAA,yDAAwD;AAA/C,sHAAA,iBAAiB,OAAA;AAC1B,+CAA6C;AAApC,2GAAA,WAAW,OAAA"}
@@ -0,0 +1,10 @@
1
+ export { AgentManager } from './AgentManager';
2
+ export { ClaudeCodeAdapter } from './adapters/ClaudeCodeAdapter';
3
+ export { AgentStatus } from './adapters/AgentAdapter';
4
+ export type { AgentAdapter, AgentType, AgentInfo, ProcessInfo } from './adapters/AgentAdapter';
5
+ export { TerminalFocusManager } from './terminal/TerminalFocusManager';
6
+ export type { TerminalLocation } from './terminal/TerminalFocusManager';
7
+ export { listProcesses, getProcessCwd, getProcessTty, isProcessRunning, getProcessInfo } from './utils/process';
8
+ export type { ListProcessesOptions } from './utils/process';
9
+ export { readLastLines, readJsonLines, fileExists, readJson } from './utils/file';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAE/F,OAAO,EAAE,oBAAoB,EAAE,MAAM,iCAAiC,CAAC;AACvE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AAExE,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAChH,YAAY,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.readJson = exports.fileExists = exports.readJsonLines = exports.readLastLines = exports.getProcessInfo = exports.isProcessRunning = exports.getProcessTty = exports.getProcessCwd = exports.listProcesses = exports.TerminalFocusManager = exports.AgentStatus = exports.ClaudeCodeAdapter = exports.AgentManager = void 0;
4
+ var AgentManager_1 = require("./AgentManager");
5
+ Object.defineProperty(exports, "AgentManager", { enumerable: true, get: function () { return AgentManager_1.AgentManager; } });
6
+ var ClaudeCodeAdapter_1 = require("./adapters/ClaudeCodeAdapter");
7
+ Object.defineProperty(exports, "ClaudeCodeAdapter", { enumerable: true, get: function () { return ClaudeCodeAdapter_1.ClaudeCodeAdapter; } });
8
+ var AgentAdapter_1 = require("./adapters/AgentAdapter");
9
+ Object.defineProperty(exports, "AgentStatus", { enumerable: true, get: function () { return AgentAdapter_1.AgentStatus; } });
10
+ var TerminalFocusManager_1 = require("./terminal/TerminalFocusManager");
11
+ Object.defineProperty(exports, "TerminalFocusManager", { enumerable: true, get: function () { return TerminalFocusManager_1.TerminalFocusManager; } });
12
+ var process_1 = require("./utils/process");
13
+ Object.defineProperty(exports, "listProcesses", { enumerable: true, get: function () { return process_1.listProcesses; } });
14
+ Object.defineProperty(exports, "getProcessCwd", { enumerable: true, get: function () { return process_1.getProcessCwd; } });
15
+ Object.defineProperty(exports, "getProcessTty", { enumerable: true, get: function () { return process_1.getProcessTty; } });
16
+ Object.defineProperty(exports, "isProcessRunning", { enumerable: true, get: function () { return process_1.isProcessRunning; } });
17
+ Object.defineProperty(exports, "getProcessInfo", { enumerable: true, get: function () { return process_1.getProcessInfo; } });
18
+ var file_1 = require("./utils/file");
19
+ Object.defineProperty(exports, "readLastLines", { enumerable: true, get: function () { return file_1.readLastLines; } });
20
+ Object.defineProperty(exports, "readJsonLines", { enumerable: true, get: function () { return file_1.readJsonLines; } });
21
+ Object.defineProperty(exports, "fileExists", { enumerable: true, get: function () { return file_1.fileExists; } });
22
+ Object.defineProperty(exports, "readJson", { enumerable: true, get: function () { return file_1.readJson; } });
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;AAAA,+CAA8C;AAArC,4GAAA,YAAY,OAAA;AAErB,kEAAiE;AAAxD,sHAAA,iBAAiB,OAAA;AAC1B,wDAAsD;AAA7C,2GAAA,WAAW,OAAA;AAGpB,wEAAuE;AAA9D,4HAAA,oBAAoB,OAAA;AAG7B,2CAAgH;AAAvG,wGAAA,aAAa,OAAA;AAAE,wGAAA,aAAa,OAAA;AAAE,wGAAA,aAAa,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAAE,yGAAA,cAAc,OAAA;AAEtF,qCAAkF;AAAzE,qGAAA,aAAa,OAAA;AAAE,qGAAA,aAAa,OAAA;AAAE,kGAAA,UAAU,OAAA;AAAE,gGAAA,QAAQ,OAAA"}
@@ -0,0 +1,22 @@
1
+ export interface TerminalLocation {
2
+ type: 'tmux' | 'iterm2' | 'terminal-app' | 'unknown';
3
+ identifier: string;
4
+ tty: string;
5
+ }
6
+ export declare class TerminalFocusManager {
7
+ /**
8
+ * Find the terminal location (emulator info) for a given process ID
9
+ */
10
+ findTerminal(pid: number): Promise<TerminalLocation | null>;
11
+ /**
12
+ * Focus the terminal identified by the location
13
+ */
14
+ focusTerminal(location: TerminalLocation): Promise<boolean>;
15
+ private findTmuxPane;
16
+ private findITerm2Session;
17
+ private findTerminalAppWindow;
18
+ private focusTmuxPane;
19
+ private focusITerm2Session;
20
+ private focusTerminalAppWindow;
21
+ }
22
+ //# sourceMappingURL=TerminalFocusManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TerminalFocusManager.d.ts","sourceRoot":"","sources":["../../src/terminal/TerminalFocusManager.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,cAAc,GAAG,SAAS,CAAC;IACrD,UAAU,EAAE,MAAM,CAAC;IACnB,GAAG,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,oBAAoB;IAC7B;;OAEG;IACG,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC;IA8BjE;;OAEG;IACG,aAAa,CAAC,QAAQ,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;YAiBnD,YAAY;YAyBZ,iBAAiB;YAkCjB,qBAAqB;YAgCrB,aAAa;YASb,kBAAkB;YAoBlB,sBAAsB;CAkBvC"}
@@ -0,0 +1,196 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TerminalFocusManager = void 0;
4
+ const child_process_1 = require("child_process");
5
+ const util_1 = require("util");
6
+ const process_1 = require("../utils/process");
7
+ const execAsync = (0, util_1.promisify)(child_process_1.exec);
8
+ const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
9
+ class TerminalFocusManager {
10
+ /**
11
+ * Find the terminal location (emulator info) for a given process ID
12
+ */
13
+ async findTerminal(pid) {
14
+ const ttyShort = (0, process_1.getProcessTty)(pid);
15
+ // If no TTY or invalid, we can't find the terminal
16
+ if (!ttyShort || ttyShort === '?') {
17
+ return null;
18
+ }
19
+ const fullTty = `/dev/${ttyShort}`;
20
+ // 1. Check tmux (most specific if running inside it)
21
+ const tmuxLocation = await this.findTmuxPane(fullTty);
22
+ if (tmuxLocation)
23
+ return tmuxLocation;
24
+ // 2. Check iTerm2
25
+ const itermLocation = await this.findITerm2Session(fullTty);
26
+ if (itermLocation)
27
+ return itermLocation;
28
+ // 3. Check Terminal.app
29
+ const terminalAppLocation = await this.findTerminalAppWindow(fullTty);
30
+ if (terminalAppLocation)
31
+ return terminalAppLocation;
32
+ // 4. Fallback: we know the TTY but not the emulator wrapper
33
+ return {
34
+ type: 'unknown',
35
+ identifier: '',
36
+ tty: fullTty
37
+ };
38
+ }
39
+ /**
40
+ * Focus the terminal identified by the location
41
+ */
42
+ async focusTerminal(location) {
43
+ try {
44
+ switch (location.type) {
45
+ case 'tmux':
46
+ return await this.focusTmuxPane(location.identifier);
47
+ case 'iterm2':
48
+ return await this.focusITerm2Session(location.tty);
49
+ case 'terminal-app':
50
+ return await this.focusTerminalAppWindow(location.tty);
51
+ default:
52
+ return false;
53
+ }
54
+ }
55
+ catch (error) {
56
+ return false;
57
+ }
58
+ }
59
+ async findTmuxPane(tty) {
60
+ try {
61
+ // List all panes with their TTYs and identifiers
62
+ // Format: /dev/ttys001|my-session:1.1
63
+ // using | as separator to handle spaces in session names
64
+ const { stdout } = await execAsync("tmux list-panes -a -F '#{pane_tty}|#{session_name}:#{window_index}.#{pane_index}'");
65
+ const lines = stdout.trim().split('\n');
66
+ for (const line of lines) {
67
+ if (!line.trim())
68
+ continue;
69
+ const [paneTty, identifier] = line.split('|');
70
+ if (paneTty === tty && identifier) {
71
+ return {
72
+ type: 'tmux',
73
+ identifier,
74
+ tty
75
+ };
76
+ }
77
+ }
78
+ }
79
+ catch (error) {
80
+ // tmux might not be installed or running
81
+ }
82
+ return null;
83
+ }
84
+ async findITerm2Session(tty) {
85
+ try {
86
+ // Check if iTerm2 is running first to avoid launching it
87
+ const { stdout: isRunning } = await execAsync('pgrep -x iTerm2 || echo "no"');
88
+ if (isRunning.trim() === "no")
89
+ return null;
90
+ const script = `
91
+ tell application "iTerm"
92
+ repeat with w in windows
93
+ repeat with t in tabs of w
94
+ repeat with s in sessions of t
95
+ if tty of s is "${tty}" then
96
+ return "found"
97
+ end if
98
+ end repeat
99
+ end repeat
100
+ end repeat
101
+ end tell
102
+ `;
103
+ const { stdout } = await execAsync(`osascript -e '${script}'`);
104
+ if (stdout.trim() === "found") {
105
+ return {
106
+ type: 'iterm2',
107
+ identifier: tty,
108
+ tty
109
+ };
110
+ }
111
+ }
112
+ catch (error) {
113
+ // iTerm2 not found or script failed
114
+ }
115
+ return null;
116
+ }
117
+ async findTerminalAppWindow(tty) {
118
+ try {
119
+ // Check if Terminal is running
120
+ const { stdout: isRunning } = await execAsync('pgrep -x Terminal || echo "no"');
121
+ if (isRunning.trim() === "no")
122
+ return null;
123
+ const script = `
124
+ tell application "Terminal"
125
+ repeat with w in windows
126
+ repeat with t in tabs of w
127
+ if tty of t is "${tty}" then
128
+ return "found"
129
+ end if
130
+ end repeat
131
+ end repeat
132
+ end tell
133
+ `;
134
+ const { stdout } = await execAsync(`osascript -e '${script}'`);
135
+ if (stdout.trim() === "found") {
136
+ return {
137
+ type: 'terminal-app',
138
+ identifier: tty,
139
+ tty
140
+ };
141
+ }
142
+ }
143
+ catch (error) {
144
+ // Terminal not found or script failed
145
+ }
146
+ return null;
147
+ }
148
+ async focusTmuxPane(identifier) {
149
+ try {
150
+ await execFileAsync('tmux', ['switch-client', '-t', identifier]);
151
+ return true;
152
+ }
153
+ catch (error) {
154
+ return false;
155
+ }
156
+ }
157
+ async focusITerm2Session(tty) {
158
+ const script = `
159
+ tell application "iTerm"
160
+ activate
161
+ repeat with w in windows
162
+ repeat with t in tabs of w
163
+ repeat with s in sessions of t
164
+ if tty of s is "${tty}" then
165
+ select s
166
+ return "true"
167
+ end if
168
+ end repeat
169
+ end repeat
170
+ end repeat
171
+ end tell
172
+ `;
173
+ const { stdout } = await execAsync(`osascript -e '${script}'`);
174
+ return stdout.trim() === "true";
175
+ }
176
+ async focusTerminalAppWindow(tty) {
177
+ const script = `
178
+ tell application "Terminal"
179
+ activate
180
+ repeat with w in windows
181
+ repeat with t in tabs of w
182
+ if tty of t is "${tty}" then
183
+ set index of w to 1
184
+ set selected tab of w to t
185
+ return "true"
186
+ end if
187
+ end repeat
188
+ end repeat
189
+ end tell
190
+ `;
191
+ const { stdout } = await execAsync(`osascript -e '${script}'`);
192
+ return stdout.trim() === "true";
193
+ }
194
+ }
195
+ exports.TerminalFocusManager = TerminalFocusManager;
196
+ //# sourceMappingURL=TerminalFocusManager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TerminalFocusManager.js","sourceRoot":"","sources":["../../src/terminal/TerminalFocusManager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { TerminalFocusManager } from './TerminalFocusManager';
2
+ export type { TerminalLocation } from './TerminalFocusManager';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/terminal/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,YAAY,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TerminalFocusManager = void 0;
4
+ var TerminalFocusManager_1 = require("./TerminalFocusManager");
5
+ Object.defineProperty(exports, "TerminalFocusManager", { enumerable: true, get: function () { return TerminalFocusManager_1.TerminalFocusManager; } });
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/terminal/index.ts"],"names":[],"mappings":";;;AAAA,+DAA8D;AAArD,4HAAA,oBAAoB,OAAA"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * File Utilities
3
+ *
4
+ * Helper functions for reading files efficiently
5
+ */
6
+ /**
7
+ * Read last N lines from a file efficiently
8
+ *
9
+ * @param filePath Path to the file
10
+ * @param lineCount Number of lines to read from the end (default: 100)
11
+ * @returns Array of lines
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * const lastLines = readLastLines('/path/to/log.txt', 50);
16
+ * ```
17
+ */
18
+ export declare function readLastLines(filePath: string, lineCount?: number): string[];
19
+ /**
20
+ * Read a JSONL (JSON Lines) file and parse each line
21
+ *
22
+ * @param filePath Path to the JSONL file
23
+ * @param maxLines Maximum number of lines to read from end (default: 1000)
24
+ * @returns Array of parsed objects
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const entries = readJsonLines<MyType>('/path/to/data.jsonl');
29
+ * const recent = readJsonLines<MyType>('/path/to/data.jsonl', 100);
30
+ * ```
31
+ */
32
+ export declare function readJsonLines<T = unknown>(filePath: string, maxLines?: number): T[];
33
+ /**
34
+ * Check if a file exists
35
+ *
36
+ * @param filePath Path to check
37
+ * @returns True if file exists
38
+ */
39
+ export declare function fileExists(filePath: string): boolean;
40
+ /**
41
+ * Read a JSON file safely
42
+ *
43
+ * @param filePath Path to JSON file
44
+ * @returns Parsed JSON object or null if error
45
+ *
46
+ * @example
47
+ * ```typescript
48
+ * const config = readJson<ConfigType>('/path/to/config.json');
49
+ * ```
50
+ */
51
+ export declare function readJson<T = unknown>(filePath: string): T | null;
52
+ //# sourceMappingURL=file.d.ts.map