@ai-devkit/agent-manager 0.13.0 → 0.15.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.
- package/.eslintrc.json +1 -1
- package/README.md +32 -0
- package/dist/AgentManager.d.ts +10 -12
- package/dist/AgentManager.d.ts.map +1 -1
- package/dist/AgentManager.js +6 -34
- package/dist/AgentManager.js.map +1 -1
- package/dist/adapters/AgentAdapter.js +2 -5
- package/dist/adapters/AgentAdapter.js.map +1 -1
- package/dist/adapters/ClaudeCodeAdapter.d.ts +1 -1
- package/dist/adapters/ClaudeCodeAdapter.d.ts.map +1 -1
- package/dist/adapters/ClaudeCodeAdapter.js +29 -63
- package/dist/adapters/ClaudeCodeAdapter.js.map +1 -1
- package/dist/adapters/CodexAdapter.d.ts +1 -1
- package/dist/adapters/CodexAdapter.d.ts.map +1 -1
- package/dist/adapters/CodexAdapter.js +32 -68
- package/dist/adapters/CodexAdapter.js.map +1 -1
- package/dist/adapters/GeminiCliAdapter.d.ts +1 -1
- package/dist/adapters/GeminiCliAdapter.d.ts.map +1 -1
- package/dist/adapters/GeminiCliAdapter.js +29 -65
- package/dist/adapters/GeminiCliAdapter.js.map +1 -1
- package/dist/adapters/OpenCodeAdapter.d.ts +1 -1
- package/dist/adapters/OpenCodeAdapter.d.ts.map +1 -1
- package/dist/adapters/OpenCodeAdapter.js +20 -59
- package/dist/adapters/OpenCodeAdapter.js.map +1 -1
- package/dist/adapters/index.d.ts +6 -6
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +5 -13
- package/dist/adapters/index.js.map +1 -1
- package/dist/index.d.ts +13 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +9 -22
- package/dist/index.js.map +1 -1
- package/dist/terminal/TerminalFocusManager.js +13 -17
- package/dist/terminal/TerminalFocusManager.js.map +1 -1
- package/dist/terminal/TtyWriter.d.ts +1 -1
- package/dist/terminal/TtyWriter.d.ts.map +1 -1
- package/dist/terminal/TtyWriter.js +11 -15
- package/dist/terminal/TtyWriter.js.map +1 -1
- package/dist/terminal/index.d.ts +4 -4
- package/dist/terminal/index.d.ts.map +1 -1
- package/dist/terminal/index.js +3 -9
- package/dist/terminal/index.js.map +1 -1
- package/dist/utils/ClaudeSessionParser.d.ts +2 -2
- package/dist/utils/ClaudeSessionParser.d.ts.map +1 -1
- package/dist/utils/ClaudeSessionParser.js +11 -48
- package/dist/utils/ClaudeSessionParser.js.map +1 -1
- package/dist/utils/applescript.js +1 -4
- package/dist/utils/applescript.js.map +1 -1
- package/dist/utils/index.d.ts +6 -6
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +4 -15
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/matching.d.ts +2 -2
- package/dist/utils/matching.d.ts.map +1 -1
- package/dist/utils/matching.js +3 -40
- package/dist/utils/matching.js.map +1 -1
- package/dist/utils/process.d.ts +1 -1
- package/dist/utils/process.d.ts.map +1 -1
- package/dist/utils/process.js +12 -52
- package/dist/utils/process.js.map +1 -1
- package/dist/utils/session.js +8 -49
- package/dist/utils/session.js.map +1 -1
- package/dist/utils/sortAgents.d.ts +4 -0
- package/dist/utils/sortAgents.d.ts.map +1 -0
- package/dist/utils/sortAgents.js +48 -0
- package/dist/utils/sortAgents.js.map +1 -0
- package/package.json +9 -8
- package/src/AgentManager.ts +13 -28
- package/src/__tests__/AgentManager.test.ts +5 -5
- package/src/__tests__/adapters/ClaudeCodeAdapter.test.ts +44 -42
- package/src/__tests__/adapters/CodexAdapter.test.ts +32 -30
- package/src/__tests__/adapters/GeminiCliAdapter.test.ts +19 -18
- package/src/__tests__/adapters/OpenCodeAdapter.test.ts +23 -21
- package/src/__tests__/terminal/TtyWriter.test.ts +10 -9
- package/src/__tests__/utils/ClaudeSessionParser.test.ts +2 -2
- package/src/__tests__/utils/matching.test.ts +4 -4
- package/src/__tests__/utils/process.test.ts +6 -5
- package/src/__tests__/utils/session.test.ts +8 -7
- package/src/adapters/ClaudeCodeAdapter.ts +8 -8
- package/src/adapters/CodexAdapter.ts +6 -6
- package/src/adapters/GeminiCliAdapter.ts +6 -6
- package/src/adapters/OpenCodeAdapter.ts +4 -4
- package/src/adapters/index.ts +6 -6
- package/src/index.ts +13 -11
- package/src/terminal/TerminalFocusManager.ts +2 -2
- package/src/terminal/TtyWriter.ts +3 -3
- package/src/terminal/index.ts +4 -4
- package/src/utils/ClaudeSessionParser.ts +2 -2
- package/src/utils/index.ts +6 -6
- package/src/utils/matching.ts +2 -2
- package/src/utils/process.ts +1 -1
- package/src/utils/sortAgents.ts +52 -0
- package/tsconfig.json +2 -2
- package/vitest.config.ts +20 -0
- package/jest.config.js +0 -21
|
@@ -2,28 +2,30 @@
|
|
|
2
2
|
* Tests for OpenCodeAdapter
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
import type { MockedFunction } from 'vitest';
|
|
5
6
|
import * as fs from 'fs';
|
|
6
7
|
import * as path from 'path';
|
|
7
|
-
|
|
8
|
-
import { OpenCodeAdapter } from '../../adapters/OpenCodeAdapter';
|
|
9
|
-
import type { ProcessInfo } from '../../adapters/AgentAdapter';
|
|
10
|
-
import { AgentStatus } from '../../adapters/AgentAdapter';
|
|
11
|
-
import { listAgentProcesses, enrichProcesses } from '../../utils/process';
|
|
12
|
-
import { generateAgentName } from '../../utils/matching';
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
8
|
+
|
|
9
|
+
import { OpenCodeAdapter } from '../../adapters/OpenCodeAdapter.js';
|
|
10
|
+
import type { ProcessInfo } from '../../adapters/AgentAdapter.js';
|
|
11
|
+
import { AgentStatus } from '../../adapters/AgentAdapter.js';
|
|
12
|
+
import { listAgentProcesses, enrichProcesses } from '../../utils/process.js';
|
|
13
|
+
import { generateAgentName } from '../../utils/matching.js';
|
|
14
|
+
import * as os from 'os';
|
|
15
|
+
|
|
16
|
+
vi.mock('../../utils/process.js', () => ({
|
|
17
|
+
listAgentProcesses: vi.fn(),
|
|
18
|
+
enrichProcesses: vi.fn(),
|
|
17
19
|
}));
|
|
18
20
|
|
|
19
|
-
|
|
20
|
-
generateAgentName:
|
|
21
|
-
matchProcessesToSessions:
|
|
21
|
+
vi.mock('../../utils/matching.js', () => ({
|
|
22
|
+
generateAgentName: vi.fn(),
|
|
23
|
+
matchProcessesToSessions: vi.fn(),
|
|
22
24
|
}));
|
|
23
25
|
|
|
24
|
-
const mockedListAgentProcesses = listAgentProcesses as
|
|
25
|
-
const mockedEnrichProcesses = enrichProcesses as
|
|
26
|
-
const mockedGenerateAgentName = generateAgentName as
|
|
26
|
+
const mockedListAgentProcesses = listAgentProcesses as MockedFunction<typeof listAgentProcesses>;
|
|
27
|
+
const mockedEnrichProcesses = enrichProcesses as MockedFunction<typeof enrichProcesses>;
|
|
28
|
+
const mockedGenerateAgentName = generateAgentName as MockedFunction<typeof generateAgentName>;
|
|
27
29
|
|
|
28
30
|
function makeDb(queries: {
|
|
29
31
|
session?: Array<{ id: string; directory: string; time_created: number }>;
|
|
@@ -85,11 +87,11 @@ function makeDb(queries: {
|
|
|
85
87
|
return { all: () => [], get: () => undefined };
|
|
86
88
|
};
|
|
87
89
|
|
|
88
|
-
return { prepare: prepareImpl, close:
|
|
90
|
+
return { prepare: prepareImpl, close: vi.fn() };
|
|
89
91
|
}
|
|
90
92
|
|
|
91
93
|
function makeDbConstructor(db: ReturnType<typeof makeDb>) {
|
|
92
|
-
return
|
|
94
|
+
return vi.fn().mockReturnValue(db);
|
|
93
95
|
}
|
|
94
96
|
|
|
95
97
|
describe('OpenCodeAdapter', () => {
|
|
@@ -110,7 +112,7 @@ describe('OpenCodeAdapter', () => {
|
|
|
110
112
|
return `${folder}-${pid}`;
|
|
111
113
|
});
|
|
112
114
|
|
|
113
|
-
tmpDir = fs.mkdtempSync(path.join(
|
|
115
|
+
tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'opencode-test-'));
|
|
114
116
|
dbPath = path.join(tmpDir, 'opencode.db');
|
|
115
117
|
(adapter as any).dbPath = dbPath;
|
|
116
118
|
(adapter as any).db = null;
|
|
@@ -118,7 +120,7 @@ describe('OpenCodeAdapter', () => {
|
|
|
118
120
|
|
|
119
121
|
afterEach(() => {
|
|
120
122
|
fs.rmSync(tmpDir, { recursive: true, force: true });
|
|
121
|
-
|
|
123
|
+
vi.restoreAllMocks();
|
|
122
124
|
});
|
|
123
125
|
|
|
124
126
|
describe('type', () => {
|
|
@@ -193,7 +195,7 @@ describe('OpenCodeAdapter', () => {
|
|
|
193
195
|
|
|
194
196
|
fs.writeFileSync(dbPath, ''); // file exists but empty → sqlite throws
|
|
195
197
|
const db = makeDb({ session: [] }); // no matching session
|
|
196
|
-
|
|
198
|
+
vi.doMock('better-sqlite3', () => makeDbConstructor(db));
|
|
197
199
|
(adapter as any).db = db;
|
|
198
200
|
|
|
199
201
|
const agents = await adapter.detectAgents();
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import
|
|
1
|
+
import type { Mock } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { TtyWriter } from '../../terminal/TtyWriter.js';
|
|
4
|
+
import { TerminalType } from '../../terminal/TerminalFocusManager.js';
|
|
5
|
+
import type { TerminalLocation } from '../../terminal/TerminalFocusManager.js';
|
|
5
6
|
import { execFile } from 'child_process';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
const actual =
|
|
8
|
+
vi.mock('child_process', async () => {
|
|
9
|
+
const actual = await vi.importActual<typeof import('child_process')>('child_process');
|
|
9
10
|
return {
|
|
10
11
|
...actual,
|
|
11
|
-
execFile:
|
|
12
|
+
execFile: vi.fn(),
|
|
12
13
|
};
|
|
13
14
|
});
|
|
14
15
|
|
|
15
|
-
const mockedExecFile = execFile as unknown as
|
|
16
|
+
const mockedExecFile = execFile as unknown as Mock;
|
|
16
17
|
|
|
17
18
|
function mockExecFileSuccess(stdout = '') {
|
|
18
19
|
mockedExecFile.mockImplementation((...args: unknown[]) => {
|
|
@@ -30,7 +31,7 @@ function mockExecFileError(message: string) {
|
|
|
30
31
|
|
|
31
32
|
describe('TtyWriter', () => {
|
|
32
33
|
beforeEach(() => {
|
|
33
|
-
|
|
34
|
+
vi.clearAllMocks();
|
|
34
35
|
});
|
|
35
36
|
|
|
36
37
|
describe('tmux', () => {
|
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
* harness-injected XML tags from conversation content.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
|
|
7
7
|
import * as fs from 'fs';
|
|
8
8
|
import * as os from 'os';
|
|
9
9
|
import * as path from 'path';
|
|
10
|
-
import { ClaudeSessionParser } from '../../utils/ClaudeSessionParser';
|
|
10
|
+
import { ClaudeSessionParser } from '../../utils/ClaudeSessionParser.js';
|
|
11
11
|
|
|
12
12
|
interface JsonlEntry {
|
|
13
13
|
type: 'user' | 'assistant' | 'system';
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
* Tests for utils/matching.ts
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
import { matchProcessesToSessions, generateAgentName } from '../../utils/matching';
|
|
7
|
-
import type { ProcessInfo } from '../../adapters/AgentAdapter';
|
|
8
|
-
import type { SessionFile } from '../../utils/session';
|
|
5
|
+
|
|
6
|
+
import { matchProcessesToSessions, generateAgentName } from '../../utils/matching.js';
|
|
7
|
+
import type { ProcessInfo } from '../../adapters/AgentAdapter.js';
|
|
8
|
+
import type { SessionFile } from '../../utils/session.js';
|
|
9
9
|
|
|
10
10
|
function makeProcess(overrides: Partial<ProcessInfo> & { pid: number }): ProcessInfo {
|
|
11
11
|
return {
|
|
@@ -2,20 +2,21 @@
|
|
|
2
2
|
* Tests for new functions in utils/process.ts
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import type { MockedFunction } from 'vitest';
|
|
6
|
+
|
|
6
7
|
import { execFileSync } from 'child_process';
|
|
7
8
|
import {
|
|
8
9
|
listAgentProcesses,
|
|
9
10
|
batchGetProcessCwds,
|
|
10
11
|
batchGetProcessStartTimes,
|
|
11
12
|
enrichProcesses,
|
|
12
|
-
} from '../../utils/process';
|
|
13
|
+
} from '../../utils/process.js';
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
execFileSync:
|
|
15
|
+
vi.mock('child_process', () => ({
|
|
16
|
+
execFileSync: vi.fn(),
|
|
16
17
|
}));
|
|
17
18
|
|
|
18
|
-
const mockedExecFileSync = execFileSync as
|
|
19
|
+
const mockedExecFileSync = execFileSync as MockedFunction<typeof execFileSync>;
|
|
19
20
|
|
|
20
21
|
describe('listAgentProcesses', () => {
|
|
21
22
|
beforeEach(() => {
|
|
@@ -2,17 +2,18 @@
|
|
|
2
2
|
* Tests for utils/session.ts
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import type { MockedFunction } from 'vitest';
|
|
6
|
+
|
|
6
7
|
import * as fs from 'fs';
|
|
7
|
-
import { batchGetSessionFileBirthtimes } from '../../utils/session';
|
|
8
|
+
import { batchGetSessionFileBirthtimes } from '../../utils/session.js';
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
readdirSync:
|
|
11
|
-
statSync:
|
|
10
|
+
vi.mock('fs', () => ({
|
|
11
|
+
readdirSync: vi.fn(),
|
|
12
|
+
statSync: vi.fn(),
|
|
12
13
|
}));
|
|
13
14
|
|
|
14
|
-
const mockedReaddirSync = fs.readdirSync as
|
|
15
|
-
const mockedStatSync = fs.statSync as
|
|
15
|
+
const mockedReaddirSync = fs.readdirSync as MockedFunction<typeof fs.readdirSync>;
|
|
16
|
+
const mockedStatSync = fs.statSync as MockedFunction<typeof fs.statSync>;
|
|
16
17
|
|
|
17
18
|
describe('batchGetSessionFileBirthtimes', () => {
|
|
18
19
|
beforeEach(() => {
|
|
@@ -7,14 +7,14 @@ import type {
|
|
|
7
7
|
ConversationMessage,
|
|
8
8
|
SessionSummary,
|
|
9
9
|
ListSessionsOptions,
|
|
10
|
-
} from './AgentAdapter';
|
|
11
|
-
import { AgentStatus } from './AgentAdapter';
|
|
12
|
-
import { listAgentProcesses, enrichProcesses } from '../utils/process';
|
|
13
|
-
import { batchGetSessionFileBirthtimes, isDirectory, listJsonl, safeReaddir, safeStat } from '../utils/session';
|
|
14
|
-
import type { SessionFile } from '../utils/session';
|
|
15
|
-
import { matchProcessesToSessions, generateAgentName } from '../utils/matching';
|
|
16
|
-
import { ClaudeSessionParser } from '../utils/ClaudeSessionParser';
|
|
17
|
-
import type { ClaudeSession } from '../utils/ClaudeSessionParser';
|
|
10
|
+
} from './AgentAdapter.js';
|
|
11
|
+
import { AgentStatus } from './AgentAdapter.js';
|
|
12
|
+
import { listAgentProcesses, enrichProcesses } from '../utils/process.js';
|
|
13
|
+
import { batchGetSessionFileBirthtimes, isDirectory, listJsonl, safeReaddir, safeStat } from '../utils/session.js';
|
|
14
|
+
import type { SessionFile } from '../utils/session.js';
|
|
15
|
+
import { matchProcessesToSessions, generateAgentName } from '../utils/matching.js';
|
|
16
|
+
import { ClaudeSessionParser } from '../utils/ClaudeSessionParser.js';
|
|
17
|
+
import type { ClaudeSession } from '../utils/ClaudeSessionParser.js';
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
20
|
* Entry in ~/.claude/sessions/<pid>.json written by Claude Code.
|
|
@@ -19,12 +19,12 @@ import type {
|
|
|
19
19
|
ConversationMessage,
|
|
20
20
|
SessionSummary,
|
|
21
21
|
ListSessionsOptions,
|
|
22
|
-
} from './AgentAdapter';
|
|
23
|
-
import { AgentStatus } from './AgentAdapter';
|
|
24
|
-
import { listAgentProcesses, enrichProcesses } from '../utils/process';
|
|
25
|
-
import { batchGetSessionFileBirthtimes, isDirectory, safeReadFile, safeReaddir, safeStat } from '../utils/session';
|
|
26
|
-
import type { SessionFile } from '../utils/session';
|
|
27
|
-
import { matchProcessesToSessions, generateAgentName } from '../utils/matching';
|
|
22
|
+
} from './AgentAdapter.js';
|
|
23
|
+
import { AgentStatus } from './AgentAdapter.js';
|
|
24
|
+
import { listAgentProcesses, enrichProcesses } from '../utils/process.js';
|
|
25
|
+
import { batchGetSessionFileBirthtimes, isDirectory, safeReadFile, safeReaddir, safeStat } from '../utils/session.js';
|
|
26
|
+
import type { SessionFile } from '../utils/session.js';
|
|
27
|
+
import { matchProcessesToSessions, generateAgentName } from '../utils/matching.js';
|
|
28
28
|
|
|
29
29
|
interface CodexEventEntry {
|
|
30
30
|
timestamp?: string;
|
|
@@ -20,12 +20,12 @@ import type {
|
|
|
20
20
|
ConversationMessage,
|
|
21
21
|
SessionSummary,
|
|
22
22
|
ListSessionsOptions,
|
|
23
|
-
} from './AgentAdapter';
|
|
24
|
-
import { AgentStatus } from './AgentAdapter';
|
|
25
|
-
import { listAgentProcesses, enrichProcesses } from '../utils/process';
|
|
26
|
-
import { isDirectory, safeReadFile, safeReaddir, safeStat } from '../utils/session';
|
|
27
|
-
import type { SessionFile } from '../utils/session';
|
|
28
|
-
import { matchProcessesToSessions, generateAgentName } from '../utils/matching';
|
|
23
|
+
} from './AgentAdapter.js';
|
|
24
|
+
import { AgentStatus } from './AgentAdapter.js';
|
|
25
|
+
import { listAgentProcesses, enrichProcesses } from '../utils/process.js';
|
|
26
|
+
import { isDirectory, safeReadFile, safeReaddir, safeStat } from '../utils/session.js';
|
|
27
|
+
import type { SessionFile } from '../utils/session.js';
|
|
28
|
+
import { matchProcessesToSessions, generateAgentName } from '../utils/matching.js';
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* A single Gemini CLI message content part. Mirrors the `{text?: string}`
|
|
@@ -21,10 +21,10 @@ import type {
|
|
|
21
21
|
ConversationMessage,
|
|
22
22
|
SessionSummary,
|
|
23
23
|
ListSessionsOptions,
|
|
24
|
-
} from './AgentAdapter';
|
|
25
|
-
import { AgentStatus } from './AgentAdapter';
|
|
26
|
-
import { listAgentProcesses, enrichProcesses } from '../utils/process';
|
|
27
|
-
import { generateAgentName } from '../utils/matching';
|
|
24
|
+
} from './AgentAdapter.js';
|
|
25
|
+
import { AgentStatus } from './AgentAdapter.js';
|
|
26
|
+
import { listAgentProcesses, enrichProcesses } from '../utils/process.js';
|
|
27
|
+
import { generateAgentName } from '../utils/matching.js';
|
|
28
28
|
|
|
29
29
|
const SESSION_REF_SEP = '::';
|
|
30
30
|
|
package/src/adapters/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { ClaudeCodeAdapter } from './ClaudeCodeAdapter';
|
|
2
|
-
export { CodexAdapter } from './CodexAdapter';
|
|
3
|
-
export { GeminiCliAdapter } from './GeminiCliAdapter';
|
|
4
|
-
export { OpenCodeAdapter } from './OpenCodeAdapter';
|
|
5
|
-
export { AgentStatus } from './AgentAdapter';
|
|
6
|
-
export type { AgentAdapter, AgentType, AgentInfo, ProcessInfo } from './AgentAdapter';
|
|
1
|
+
export { ClaudeCodeAdapter } from './ClaudeCodeAdapter.js';
|
|
2
|
+
export { CodexAdapter } from './CodexAdapter.js';
|
|
3
|
+
export { GeminiCliAdapter } from './GeminiCliAdapter.js';
|
|
4
|
+
export { OpenCodeAdapter } from './OpenCodeAdapter.js';
|
|
5
|
+
export { AgentStatus } from './AgentAdapter.js';
|
|
6
|
+
export type { AgentAdapter, AgentType, AgentInfo, ProcessInfo } from './AgentAdapter.js';
|
package/src/index.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
export { AgentManager } from './AgentManager';
|
|
1
|
+
export { AgentManager } from './AgentManager.js';
|
|
2
2
|
|
|
3
|
-
export { ClaudeCodeAdapter } from './adapters/ClaudeCodeAdapter';
|
|
4
|
-
export { CodexAdapter } from './adapters/CodexAdapter';
|
|
5
|
-
export { GeminiCliAdapter } from './adapters/GeminiCliAdapter';
|
|
6
|
-
export { OpenCodeAdapter } from './adapters/OpenCodeAdapter';
|
|
7
|
-
export { AgentStatus } from './adapters/AgentAdapter';
|
|
3
|
+
export { ClaudeCodeAdapter } from './adapters/ClaudeCodeAdapter.js';
|
|
4
|
+
export { CodexAdapter } from './adapters/CodexAdapter.js';
|
|
5
|
+
export { GeminiCliAdapter } from './adapters/GeminiCliAdapter.js';
|
|
6
|
+
export { OpenCodeAdapter } from './adapters/OpenCodeAdapter.js';
|
|
7
|
+
export { AgentStatus } from './adapters/AgentAdapter.js';
|
|
8
8
|
export type {
|
|
9
9
|
AgentAdapter,
|
|
10
10
|
AgentType,
|
|
@@ -13,10 +13,12 @@ export type {
|
|
|
13
13
|
ConversationMessage,
|
|
14
14
|
SessionSummary,
|
|
15
15
|
ListSessionsOptions,
|
|
16
|
-
} from './adapters/AgentAdapter';
|
|
16
|
+
} from './adapters/AgentAdapter.js';
|
|
17
17
|
|
|
18
|
-
export { TerminalFocusManager, TerminalType } from './terminal/TerminalFocusManager';
|
|
19
|
-
export type { TerminalLocation } from './terminal/TerminalFocusManager';
|
|
20
|
-
export { TtyWriter } from './terminal/TtyWriter';
|
|
18
|
+
export { TerminalFocusManager, TerminalType } from './terminal/TerminalFocusManager.js';
|
|
19
|
+
export type { TerminalLocation } from './terminal/TerminalFocusManager.js';
|
|
20
|
+
export { TtyWriter } from './terminal/TtyWriter.js';
|
|
21
21
|
|
|
22
|
-
export { getProcessTty } from './utils/process';
|
|
22
|
+
export { getProcessTty } from './utils/process.js';
|
|
23
|
+
export type { AgentSortKey } from './utils/sortAgents.js';
|
|
24
|
+
export type { ListAgentsOptions } from './AgentManager.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { execFile } from 'child_process';
|
|
2
2
|
import { promisify } from 'util';
|
|
3
|
-
import { getProcessTty } from '../utils/process';
|
|
4
|
-
import { escapeAppleScript } from '../utils/applescript';
|
|
3
|
+
import { getProcessTty } from '../utils/process.js';
|
|
4
|
+
import { escapeAppleScript } from '../utils/applescript.js';
|
|
5
5
|
|
|
6
6
|
const execFileAsync = promisify(execFile);
|
|
7
7
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { execFile } from 'child_process';
|
|
2
2
|
import { promisify } from 'util';
|
|
3
|
-
import type { TerminalLocation } from './TerminalFocusManager';
|
|
4
|
-
import { TerminalType } from './TerminalFocusManager';
|
|
5
|
-
import { escapeAppleScript } from '../utils/applescript';
|
|
3
|
+
import type { TerminalLocation } from './TerminalFocusManager.js';
|
|
4
|
+
import { TerminalType } from './TerminalFocusManager.js';
|
|
5
|
+
import { escapeAppleScript } from '../utils/applescript.js';
|
|
6
6
|
|
|
7
7
|
const execFileAsync = promisify(execFile);
|
|
8
8
|
|
package/src/terminal/index.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { TerminalFocusManager } from './TerminalFocusManager';
|
|
2
|
-
export { TerminalType } from './TerminalFocusManager';
|
|
3
|
-
export type { TerminalLocation } from './TerminalFocusManager';
|
|
4
|
-
export { TtyWriter } from './TtyWriter';
|
|
1
|
+
export { TerminalFocusManager } from './TerminalFocusManager.js';
|
|
2
|
+
export { TerminalType } from './TerminalFocusManager.js';
|
|
3
|
+
export type { TerminalLocation } from './TerminalFocusManager.js';
|
|
4
|
+
export { TtyWriter } from './TtyWriter.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
-
import type { ConversationMessage } from '../adapters/AgentAdapter';
|
|
4
|
-
import { AgentStatus } from '../adapters/AgentAdapter';
|
|
3
|
+
import type { ConversationMessage } from '../adapters/AgentAdapter.js';
|
|
4
|
+
import { AgentStatus } from '../adapters/AgentAdapter.js';
|
|
5
5
|
|
|
6
6
|
/**
|
|
7
7
|
* Content block within a Claude Code JSONL message entry.
|
package/src/utils/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses } from './process';
|
|
2
|
-
export { getProcessTty } from './process';
|
|
3
|
-
export { batchGetSessionFileBirthtimes } from './session';
|
|
4
|
-
export type { SessionFile } from './session';
|
|
5
|
-
export { matchProcessesToSessions, generateAgentName } from './matching';
|
|
6
|
-
export type { MatchResult } from './matching';
|
|
1
|
+
export { listAgentProcesses, batchGetProcessCwds, batchGetProcessStartTimes, enrichProcesses } from './process.js';
|
|
2
|
+
export { getProcessTty } from './process.js';
|
|
3
|
+
export { batchGetSessionFileBirthtimes } from './session.js';
|
|
4
|
+
export type { SessionFile } from './session.js';
|
|
5
|
+
export { matchProcessesToSessions, generateAgentName } from './matching.js';
|
|
6
|
+
export type { MatchResult } from './matching.js';
|
package/src/utils/matching.ts
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
8
|
import * as path from 'path';
|
|
9
|
-
import type { ProcessInfo } from '../adapters/AgentAdapter';
|
|
10
|
-
import type { SessionFile } from './session';
|
|
9
|
+
import type { ProcessInfo } from '../adapters/AgentAdapter.js';
|
|
10
|
+
import type { SessionFile } from './session.js';
|
|
11
11
|
|
|
12
12
|
/** Maximum allowed delta between process start time and session file birth time. */
|
|
13
13
|
const TOLERANCE_MS = 3 * 60 * 1000; // 3 minutes
|
package/src/utils/process.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
import * as path from 'path';
|
|
9
9
|
import { execFileSync } from 'child_process';
|
|
10
|
-
import type { ProcessInfo } from '../adapters/AgentAdapter';
|
|
10
|
+
import type { ProcessInfo } from '../adapters/AgentAdapter.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* List running processes matching an agent executable name.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { AgentStatus, type AgentInfo } from '../adapters/AgentAdapter.js';
|
|
2
|
+
|
|
3
|
+
export type AgentSortKey = 'name' | 'status' | 'pid' | 'lastActive';
|
|
4
|
+
|
|
5
|
+
const STATUS_PRIORITY: Record<AgentStatus, number> = {
|
|
6
|
+
[AgentStatus.WAITING]: 0,
|
|
7
|
+
[AgentStatus.RUNNING]: 1,
|
|
8
|
+
[AgentStatus.IDLE]: 2,
|
|
9
|
+
[AgentStatus.UNKNOWN]: 3,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
function compareByName(a: AgentInfo, b: AgentInfo): number {
|
|
13
|
+
return a.name.localeCompare(b.name);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function compareByStatus(a: AgentInfo, b: AgentInfo): number {
|
|
17
|
+
const pa = STATUS_PRIORITY[a.status] ?? 999;
|
|
18
|
+
const pb = STATUS_PRIORITY[b.status] ?? 999;
|
|
19
|
+
if (pa !== pb) return pa - pb;
|
|
20
|
+
return compareByName(a, b);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function compareByPid(a: AgentInfo, b: AgentInfo): number {
|
|
24
|
+
if (a.pid !== b.pid) return a.pid - b.pid;
|
|
25
|
+
return compareByName(a, b);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function compareByLastActive(a: AgentInfo, b: AgentInfo): number {
|
|
29
|
+
const ta = a.lastActive instanceof Date ? a.lastActive.getTime() : new Date(a.lastActive).getTime();
|
|
30
|
+
const tb = b.lastActive instanceof Date ? b.lastActive.getTime() : new Date(b.lastActive).getTime();
|
|
31
|
+
if (tb !== ta) return tb - ta; // most recent first
|
|
32
|
+
return compareByName(a, b);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function sortAgents(agents: AgentInfo[], by: AgentSortKey): AgentInfo[] {
|
|
36
|
+
const copy = agents.slice();
|
|
37
|
+
switch (by) {
|
|
38
|
+
case 'name':
|
|
39
|
+
copy.sort(compareByName);
|
|
40
|
+
break;
|
|
41
|
+
case 'status':
|
|
42
|
+
copy.sort(compareByStatus);
|
|
43
|
+
break;
|
|
44
|
+
case 'pid':
|
|
45
|
+
copy.sort(compareByPid);
|
|
46
|
+
break;
|
|
47
|
+
case 'lastActive':
|
|
48
|
+
copy.sort(compareByLastActive);
|
|
49
|
+
break;
|
|
50
|
+
}
|
|
51
|
+
return copy;
|
|
52
|
+
}
|
package/tsconfig.json
CHANGED
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config';
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
globals: true,
|
|
6
|
+
environment: 'node',
|
|
7
|
+
include: ['src/**/__tests__/**/*.test.ts'],
|
|
8
|
+
coverage: {
|
|
9
|
+
provider: 'v8',
|
|
10
|
+
include: ['src/**/*.ts'],
|
|
11
|
+
exclude: ['src/index.ts', 'src/**/*.d.ts'],
|
|
12
|
+
thresholds: {
|
|
13
|
+
branches: 70,
|
|
14
|
+
functions: 70,
|
|
15
|
+
lines: 70,
|
|
16
|
+
statements: 70,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
});
|
package/jest.config.js
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
preset: 'ts-jest',
|
|
3
|
-
testEnvironment: 'node',
|
|
4
|
-
roots: ['<rootDir>/src'],
|
|
5
|
-
testMatch: ['**/__tests__/**/*.test.ts', '**/?(*.)+(spec|test).ts'],
|
|
6
|
-
collectCoverageFrom: [
|
|
7
|
-
'src/**/*.{ts,js}',
|
|
8
|
-
'!src/**/*.d.ts',
|
|
9
|
-
'!src/index.ts'
|
|
10
|
-
],
|
|
11
|
-
coverageDirectory: 'coverage',
|
|
12
|
-
coverageReporters: ['text', 'lcov', 'html'],
|
|
13
|
-
coverageThreshold: {
|
|
14
|
-
global: {
|
|
15
|
-
branches: 80,
|
|
16
|
-
functions: 80,
|
|
17
|
-
lines: 80,
|
|
18
|
-
statements: 80
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
};
|