@ai-devkit/agent-manager 0.15.0 → 0.16.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/dist/AgentManager.d.ts +4 -0
- package/dist/AgentManager.d.ts.map +1 -1
- package/dist/AgentManager.js +35 -0
- package/dist/AgentManager.js.map +1 -1
- package/dist/adapters/CodexAdapter.d.ts +4 -1
- package/dist/adapters/CodexAdapter.d.ts.map +1 -1
- package/dist/adapters/CodexAdapter.js +35 -6
- package/dist/adapters/CodexAdapter.js.map +1 -1
- package/dist/adapters/GeminiCliAdapter.d.ts +4 -1
- package/dist/adapters/GeminiCliAdapter.d.ts.map +1 -1
- package/dist/adapters/GeminiCliAdapter.js +35 -6
- package/dist/adapters/GeminiCliAdapter.js.map +1 -1
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/terminal/TmuxManager.d.ts +28 -0
- package/dist/terminal/TmuxManager.d.ts.map +1 -0
- package/dist/terminal/TmuxManager.js +112 -0
- package/dist/terminal/TmuxManager.js.map +1 -0
- package/dist/utils/AgentRegistry.d.ts +35 -0
- package/dist/utils/AgentRegistry.d.ts.map +1 -0
- package/dist/utils/AgentRegistry.js +114 -0
- package/dist/utils/AgentRegistry.js.map +1 -0
- package/dist/utils/ClaudeSessionParser.d.ts.map +1 -1
- package/dist/utils/ClaudeSessionParser.js +21 -11
- package/dist/utils/ClaudeSessionParser.js.map +1 -1
- package/dist/utils/agents.d.ts +15 -0
- package/dist/utils/agents.d.ts.map +1 -0
- package/dist/utils/agents.js +30 -0
- package/dist/utils/agents.js.map +1 -0
- package/package.json +1 -1
- package/src/AgentManager.ts +40 -0
- package/src/__tests__/AgentManager.test.ts +135 -0
- package/src/__tests__/adapters/ClaudeCodeAdapter.test.ts +1 -2
- package/src/__tests__/adapters/CodexAdapter.test.ts +105 -0
- package/src/__tests__/adapters/GeminiCliAdapter.test.ts +111 -0
- package/src/__tests__/terminal/TmuxManager.test.ts +175 -0
- package/src/__tests__/utils/AgentRegistry.test.ts +223 -0
- package/src/__tests__/utils/ClaudeSessionParser.test.ts +71 -0
- package/src/adapters/CodexAdapter.ts +45 -6
- package/src/adapters/GeminiCliAdapter.ts +45 -6
- package/src/index.ts +6 -0
- package/src/terminal/TmuxManager.ts +118 -0
- package/src/utils/AgentRegistry.ts +139 -0
- package/src/utils/ClaudeSessionParser.ts +21 -10
- package/src/utils/agents.ts +41 -0
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { execFile } from 'child_process';
|
|
2
|
+
import { promisify } from 'util';
|
|
3
|
+
const execFileAsync = promisify(execFile);
|
|
4
|
+
export class TmuxManager {
|
|
5
|
+
async isAvailable() {
|
|
6
|
+
try {
|
|
7
|
+
await execFileAsync('tmux', ['-V']);
|
|
8
|
+
return true;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
async sessionExists(name) {
|
|
15
|
+
try {
|
|
16
|
+
await execFileAsync('tmux', ['has-session', '-t', name]);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async createSession(name, cwd) {
|
|
24
|
+
await execFileAsync('tmux', ['new-session', '-d', '-s', name, '-c', cwd]);
|
|
25
|
+
}
|
|
26
|
+
async sendKeys(session, keys) {
|
|
27
|
+
await execFileAsync('tmux', ['send-keys', '-t', session, keys, 'Enter']);
|
|
28
|
+
}
|
|
29
|
+
async killSession(name) {
|
|
30
|
+
try {
|
|
31
|
+
await execFileAsync('tmux', ['kill-session', '-t', name]);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
// Already gone — ignore
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Find the actual agent process PID inside a tmux pane.
|
|
39
|
+
*
|
|
40
|
+
* Strategy: BFS the process tree, return the deepest descendant whose
|
|
41
|
+
* `ps` command line is accepted by `matches`. The caller supplies the
|
|
42
|
+
* matcher so this method has no agent-type knowledge.
|
|
43
|
+
*
|
|
44
|
+
* This handles two real-world process shapes:
|
|
45
|
+
* - Wrapper case: shell → claude-wrapper (matches) → claude (matches, deeper)
|
|
46
|
+
* → returns the deeper one
|
|
47
|
+
* - Subprocess case: shell → claude (matches) → MCP server child (doesn't match)
|
|
48
|
+
* → returns claude, not the subprocess
|
|
49
|
+
*
|
|
50
|
+
* Returns null when no descendant matches yet (agent still starting); the
|
|
51
|
+
* caller's poll loop retries.
|
|
52
|
+
*/
|
|
53
|
+
async findAgentPid(session, matches) {
|
|
54
|
+
const panePid = await this.getPanePid(session);
|
|
55
|
+
if (panePid === null)
|
|
56
|
+
return null;
|
|
57
|
+
const visited = new Set();
|
|
58
|
+
const queue = [panePid];
|
|
59
|
+
let deepestMatch = null;
|
|
60
|
+
while (queue.length > 0) {
|
|
61
|
+
const pid = queue.shift();
|
|
62
|
+
if (visited.has(pid))
|
|
63
|
+
continue;
|
|
64
|
+
visited.add(pid);
|
|
65
|
+
if (pid !== panePid) {
|
|
66
|
+
const command = await this.getProcessCommand(pid);
|
|
67
|
+
if (command && matches(command)) {
|
|
68
|
+
deepestMatch = pid;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const children = await this.pgrepChildren(pid);
|
|
72
|
+
queue.push(...children);
|
|
73
|
+
}
|
|
74
|
+
return deepestMatch;
|
|
75
|
+
}
|
|
76
|
+
async getPanePid(session) {
|
|
77
|
+
try {
|
|
78
|
+
const { stdout } = await execFileAsync('tmux', [
|
|
79
|
+
'list-panes', '-t', session, '-F', '#{pane_pid}',
|
|
80
|
+
]);
|
|
81
|
+
const panePid = parseInt(stdout.trim().split('\n')[0], 10);
|
|
82
|
+
return isNaN(panePid) ? null : panePid;
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
async pgrepChildren(pid) {
|
|
89
|
+
try {
|
|
90
|
+
const { stdout } = await execFileAsync('pgrep', ['-P', String(pid)]);
|
|
91
|
+
return stdout
|
|
92
|
+
.trim()
|
|
93
|
+
.split('\n')
|
|
94
|
+
.map((s) => parseInt(s, 10))
|
|
95
|
+
.filter((n) => !isNaN(n));
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
async getProcessCommand(pid) {
|
|
102
|
+
try {
|
|
103
|
+
const { stdout } = await execFileAsync('ps', ['-p', String(pid), '-o', 'command=']);
|
|
104
|
+
const trimmed = stdout.trim();
|
|
105
|
+
return trimmed || null;
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
//# sourceMappingURL=TmuxManager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TmuxManager.js","sourceRoot":"","sources":["../../src/terminal/TmuxManager.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { AgentType } from '../adapters/AgentAdapter.js';
|
|
2
|
+
export declare class RenameNotFoundError extends Error {
|
|
3
|
+
agentName: string;
|
|
4
|
+
constructor(agentName: string);
|
|
5
|
+
}
|
|
6
|
+
export declare class RenameConflictError extends Error {
|
|
7
|
+
agentName: string;
|
|
8
|
+
constructor(agentName: string);
|
|
9
|
+
}
|
|
10
|
+
export interface RegistryEntry {
|
|
11
|
+
name: string;
|
|
12
|
+
type: AgentType;
|
|
13
|
+
pid: number;
|
|
14
|
+
tmuxSession: string;
|
|
15
|
+
cwd: string;
|
|
16
|
+
startedAt: string;
|
|
17
|
+
sessionId: string;
|
|
18
|
+
sessionFilePath: string;
|
|
19
|
+
}
|
|
20
|
+
export declare class AgentRegistry {
|
|
21
|
+
private filePath;
|
|
22
|
+
constructor(filePath?: string);
|
|
23
|
+
static default(): AgentRegistry;
|
|
24
|
+
private readFile;
|
|
25
|
+
private writeFile;
|
|
26
|
+
private mergeEntry;
|
|
27
|
+
isAlive(entry: RegistryEntry): boolean;
|
|
28
|
+
prune(): void;
|
|
29
|
+
register(entry: RegistryEntry): void;
|
|
30
|
+
registerBatch(entries: RegistryEntry[]): void;
|
|
31
|
+
rename(currentName: string, newName: string): void;
|
|
32
|
+
lookup(name: string): RegistryEntry | null;
|
|
33
|
+
list(): RegistryEntry[];
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=AgentRegistry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentRegistry.d.ts","sourceRoot":"","sources":["../../src/utils/AgentRegistry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,qBAAa,mBAAoB,SAAQ,KAAK;IACvB,SAAS,EAAE,MAAM;gBAAjB,SAAS,EAAE,MAAM;CAIvC;AAED,qBAAa,mBAAoB,SAAQ,KAAK;IACvB,SAAS,EAAE,MAAM;gBAAjB,SAAS,EAAE,MAAM;CAIvC;AAED,MAAM,WAAW,aAAa;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,SAAS,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,eAAe,EAAE,MAAM,CAAC;CAC3B;AAUD,qBAAa,aAAa;IACtB,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,GAAE,MAA8B;IAIpD,MAAM,CAAC,OAAO,IAAI,aAAa;IAO/B,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,UAAU;IAQlB,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO;IAStC,KAAK,IAAI,IAAI;IAQb,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAIpC,aAAa,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,IAAI;IAc7C,MAAM,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI;IAiBlD,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAK1C,IAAI,IAAI,aAAa,EAAE;CAG1B"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import os from 'os';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
export class RenameNotFoundError extends Error {
|
|
5
|
+
agentName;
|
|
6
|
+
constructor(agentName) {
|
|
7
|
+
super(`Agent "${agentName}" not found in registry.`);
|
|
8
|
+
this.agentName = agentName;
|
|
9
|
+
this.name = 'RenameNotFoundError';
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
export class RenameConflictError extends Error {
|
|
13
|
+
agentName;
|
|
14
|
+
constructor(agentName) {
|
|
15
|
+
super(`Agent "${agentName}" is already in use.`);
|
|
16
|
+
this.agentName = agentName;
|
|
17
|
+
this.name = 'RenameConflictError';
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const DEFAULT_REGISTRY_PATH = path.join(os.homedir(), '.ai-devkit', 'agents.json');
|
|
21
|
+
let defaultInstance = null;
|
|
22
|
+
export class AgentRegistry {
|
|
23
|
+
filePath;
|
|
24
|
+
constructor(filePath = DEFAULT_REGISTRY_PATH) {
|
|
25
|
+
this.filePath = filePath;
|
|
26
|
+
}
|
|
27
|
+
static default() {
|
|
28
|
+
if (!defaultInstance) {
|
|
29
|
+
defaultInstance = new AgentRegistry();
|
|
30
|
+
}
|
|
31
|
+
return defaultInstance;
|
|
32
|
+
}
|
|
33
|
+
readFile() {
|
|
34
|
+
try {
|
|
35
|
+
const raw = fs.readFileSync(this.filePath, 'utf8');
|
|
36
|
+
const parsed = JSON.parse(raw);
|
|
37
|
+
return { entries: Array.isArray(parsed.entries) ? parsed.entries : [] };
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return { entries: [] };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
writeFile(data) {
|
|
44
|
+
const dir = path.dirname(this.filePath);
|
|
45
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
46
|
+
const tmp = `${this.filePath}.tmp`;
|
|
47
|
+
fs.writeFileSync(tmp, JSON.stringify(data, null, 2), 'utf8');
|
|
48
|
+
fs.renameSync(tmp, this.filePath);
|
|
49
|
+
}
|
|
50
|
+
mergeEntry(incoming, existing) {
|
|
51
|
+
if (!existing)
|
|
52
|
+
return incoming;
|
|
53
|
+
return {
|
|
54
|
+
...incoming,
|
|
55
|
+
tmuxSession: incoming.tmuxSession || existing.tmuxSession,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
isAlive(entry) {
|
|
59
|
+
try {
|
|
60
|
+
process.kill(entry.pid, 0);
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
prune() {
|
|
68
|
+
const data = this.readFile();
|
|
69
|
+
const live = data.entries.filter((e) => this.isAlive(e));
|
|
70
|
+
if (live.length !== data.entries.length) {
|
|
71
|
+
this.writeFile({ entries: live });
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
register(entry) {
|
|
75
|
+
this.registerBatch([entry]);
|
|
76
|
+
}
|
|
77
|
+
registerBatch(entries) {
|
|
78
|
+
if (entries.length === 0)
|
|
79
|
+
return;
|
|
80
|
+
const data = this.readFile();
|
|
81
|
+
for (const incoming of entries) {
|
|
82
|
+
const idx = data.entries.findIndex((e) => e.name === incoming.name);
|
|
83
|
+
if (idx >= 0) {
|
|
84
|
+
data.entries[idx] = this.mergeEntry(incoming, data.entries[idx]);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
data.entries.push(incoming);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
this.writeFile(data);
|
|
91
|
+
}
|
|
92
|
+
rename(currentName, newName) {
|
|
93
|
+
const data = this.readFile();
|
|
94
|
+
const idx = data.entries.findIndex((e) => e.name === currentName);
|
|
95
|
+
if (idx < 0) {
|
|
96
|
+
throw new RenameNotFoundError(currentName);
|
|
97
|
+
}
|
|
98
|
+
const liveEntries = data.entries.filter((e) => this.isAlive(e));
|
|
99
|
+
const conflict = liveEntries.find((e) => e.name === newName);
|
|
100
|
+
if (conflict) {
|
|
101
|
+
throw new RenameConflictError(newName);
|
|
102
|
+
}
|
|
103
|
+
const pruned = liveEntries.map((e) => e.name === currentName ? { ...e, name: newName } : e);
|
|
104
|
+
this.writeFile({ entries: pruned });
|
|
105
|
+
}
|
|
106
|
+
lookup(name) {
|
|
107
|
+
const data = this.readFile();
|
|
108
|
+
return data.entries.find((e) => e.name === name) ?? null;
|
|
109
|
+
}
|
|
110
|
+
list() {
|
|
111
|
+
return this.readFile().entries;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=AgentRegistry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AgentRegistry.js","sourceRoot":"","sources":["../../src/utils/AgentRegistry.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClaudeSessionParser.d.ts","sourceRoot":"","sources":["../../src/utils/ClaudeSessionParser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE1D;;;GAGG;AACH,MAAM,WAAW,YAAY;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE;QACN,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;KACrC,CAAC;CACL;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,IAAI,CAAC;IACnB,UAAU,EAAE,IAAI,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;
|
|
1
|
+
{"version":3,"file":"ClaudeSessionParser.d.ts","sourceRoot":"","sources":["../../src/utils/ClaudeSessionParser.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AACvE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE1D;;;GAGG;AACH,MAAM,WAAW,YAAY;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IACzB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE;QACN,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY,EAAE,CAAC;KACrC,CAAC;CACL;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,IAAI,CAAC;IACnB,UAAU,EAAE,IAAI,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,OAAO,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,sEAAsE;IACtE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAoBD;;;;;;GAMG;AACH,qBAAa,mBAAmB;IAC5B;;;;;;;;OAQG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAmFxE;;;;;;;;;OASG;IACH,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,WAAW;IA6BpD;;;;;OAKG;IACH,eAAe,CAAC,eAAe,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,mBAAmB,EAAE;IA6ChG;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAiBzB;;;;;;;;;OASG;IACH,OAAO,CAAC,sBAAsB;IAwC9B;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAW3B;;OAEG;IACH,OAAO,CAAC,0BAA0B;CAmCrC"}
|
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { AgentStatus } from '../adapters/AgentAdapter.js';
|
|
4
|
-
/**
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Top-level JSONL entry types that represent conversation/agent state.
|
|
6
|
+
*
|
|
7
|
+
* Only these types update `lastEntryType` for status determination. All
|
|
8
|
+
* other types Claude Code emits (`attachment`, `permission-mode`,
|
|
9
|
+
* `ai-title`, `queued_command`, `tools_changed`, `model_changed`,
|
|
10
|
+
* `hook_progress`, …) are UI-state events that must not overwrite the
|
|
11
|
+
* last conversation turn — otherwise polling between writes lands on a
|
|
12
|
+
* UI-state entry and `determineStatus` falls through to UNKNOWN.
|
|
13
|
+
*/
|
|
14
|
+
const CONVERSATION_ENTRY_TYPES = new Set([
|
|
15
|
+
'user',
|
|
16
|
+
'assistant',
|
|
17
|
+
'system',
|
|
18
|
+
'progress',
|
|
19
|
+
'thinking',
|
|
20
|
+
]);
|
|
6
21
|
/**
|
|
7
22
|
* Parses Claude Code session JSONL files into structured data.
|
|
8
23
|
*
|
|
@@ -52,7 +67,7 @@ export class ClaudeSessionParser {
|
|
|
52
67
|
if (typeof entry.cwd === 'string' && entry.cwd.trim().length > 0) {
|
|
53
68
|
lastCwd = entry.cwd;
|
|
54
69
|
}
|
|
55
|
-
if (entry.type &&
|
|
70
|
+
if (entry.type && CONVERSATION_ENTRY_TYPES.has(entry.type)) {
|
|
56
71
|
lastEntryType = entry.type;
|
|
57
72
|
if (entry.type === 'user') {
|
|
58
73
|
const msgContent = entry.message?.content;
|
|
@@ -147,19 +162,14 @@ export class ClaudeSessionParser {
|
|
|
147
162
|
catch {
|
|
148
163
|
continue;
|
|
149
164
|
}
|
|
150
|
-
const entryType = entry.type;
|
|
151
|
-
if (!entryType || METADATA_ENTRY_TYPES.has(entryType))
|
|
152
|
-
continue;
|
|
153
|
-
if (entryType === 'progress' || entryType === 'thinking')
|
|
154
|
-
continue;
|
|
155
165
|
let role;
|
|
156
|
-
if (
|
|
166
|
+
if (entry.type === 'user') {
|
|
157
167
|
role = 'user';
|
|
158
168
|
}
|
|
159
|
-
else if (
|
|
169
|
+
else if (entry.type === 'assistant') {
|
|
160
170
|
role = 'assistant';
|
|
161
171
|
}
|
|
162
|
-
else if (
|
|
172
|
+
else if (entry.type === 'system') {
|
|
163
173
|
role = 'system';
|
|
164
174
|
}
|
|
165
175
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClaudeSessionParser.js","sourceRoot":"","sources":["../../src/utils/ClaudeSessionParser.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAE7B,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAkD1D
|
|
1
|
+
{"version":3,"file":"ClaudeSessionParser.js","sourceRoot":"","sources":["../../src/utils/ClaudeSessionParser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { AgentType } from '../adapters/AgentAdapter.js';
|
|
2
|
+
export type StartableAgentType = Exclude<AgentType, 'other'>;
|
|
3
|
+
export interface AgentConfig {
|
|
4
|
+
/** Shell command to launch the agent (sent to tmux via `send-keys`). */
|
|
5
|
+
command: string;
|
|
6
|
+
/** Returns true if the given `ps` command line belongs to this agent. */
|
|
7
|
+
matches: (psCommand: string) => boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Per-agent configuration: launch command plus a matcher that recognizes the
|
|
11
|
+
* agent's process in `ps` output. Each matcher knows that agent's distribution
|
|
12
|
+
* quirks (e.g. gemini ships as a Node script so its real binary is in argv[1..]).
|
|
13
|
+
*/
|
|
14
|
+
export declare const AGENTS: Record<StartableAgentType, AgentConfig>;
|
|
15
|
+
//# sourceMappingURL=agents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/utils/agents.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,MAAM,MAAM,kBAAkB,GAAG,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;AAE7D,MAAM,WAAW,WAAW;IACxB,wEAAwE;IACxE,OAAO,EAAE,MAAM,CAAC;IAChB,yEAAyE;IACzE,OAAO,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC;CAC3C;AAED;;;;GAIG;AACH,eAAO,MAAM,MAAM,EAAE,MAAM,CAAC,kBAAkB,EAAE,WAAW,CAK1D,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
/**
|
|
3
|
+
* Per-agent configuration: launch command plus a matcher that recognizes the
|
|
4
|
+
* agent's process in `ps` output. Each matcher knows that agent's distribution
|
|
5
|
+
* quirks (e.g. gemini ships as a Node script so its real binary is in argv[1..]).
|
|
6
|
+
*/
|
|
7
|
+
export const AGENTS = {
|
|
8
|
+
claude: { command: 'claude', matches: matchArgv0('claude') },
|
|
9
|
+
codex: { command: 'codex', matches: matchArgv0('codex') },
|
|
10
|
+
opencode: { command: 'opencode', matches: matchArgv0('opencode') },
|
|
11
|
+
gemini_cli: { command: 'gemini', matches: matchAnyToken('gemini') },
|
|
12
|
+
};
|
|
13
|
+
function matchArgv0(name) {
|
|
14
|
+
const lower = name.toLowerCase();
|
|
15
|
+
return (psCommand) => {
|
|
16
|
+
const token = psCommand.trim().split(/\s+/)[0];
|
|
17
|
+
return token ? path.basename(token).toLowerCase() === lower : false;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
function matchAnyToken(name) {
|
|
21
|
+
const lower = name.toLowerCase();
|
|
22
|
+
return (psCommand) => {
|
|
23
|
+
for (const token of psCommand.trim().split(/\s+/)) {
|
|
24
|
+
if (path.basename(token).toLowerCase() === lower)
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return false;
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=agents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/utils/agents.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAYxB;;;;GAIG;AACH,MAAM,CAAC,MAAM,MAAM,GAA4C;IAC3D,MAAM,EAAM,EAAE,OAAO,EAAE,QAAQ,EAAI,OAAO,EAAE,UAAU,CAAC,QAAQ,CAAC,EAAE;IAClE,KAAK,EAAO,EAAE,OAAO,EAAE,OAAO,EAAK,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE;IACjE,QAAQ,EAAI,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC,UAAU,CAAC,EAAE;IACpE,UAAU,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAI,OAAO,EAAE,aAAa,CAAC,QAAQ,CAAC,EAAE;CACxE,CAAC;AAEF,SAAS,UAAU,CAAC,IAAY;IAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,OAAO,CAAC,SAAS,EAAE,EAAE;QACjB,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/C,OAAO,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;IACxE,CAAC,CAAC;AACN,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;IACjC,OAAO,CAAC,SAAS,EAAE,EAAE;QACjB,KAAK,MAAM,KAAK,IAAI,SAAS,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAChD,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,WAAW,EAAE,KAAK,KAAK;gBAAE,OAAO,IAAI,CAAC;QAClE,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC,CAAC;AACN,CAAC"}
|
package/package.json
CHANGED
package/src/AgentManager.ts
CHANGED
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
ListSessionsOptions,
|
|
13
13
|
} from './adapters/AgentAdapter.js';
|
|
14
14
|
import { sortAgents, type AgentSortKey } from './utils/sortAgents.js';
|
|
15
|
+
import { AgentRegistry, type RegistryEntry } from './utils/AgentRegistry.js';
|
|
15
16
|
|
|
16
17
|
export interface ListAgentsOptions {
|
|
17
18
|
/**
|
|
@@ -38,6 +39,11 @@ export interface ListAgentsOptions {
|
|
|
38
39
|
*/
|
|
39
40
|
export class AgentManager {
|
|
40
41
|
private adapters: Map<string, AgentAdapter> = new Map();
|
|
42
|
+
private registry: AgentRegistry;
|
|
43
|
+
|
|
44
|
+
constructor(registry: AgentRegistry = AgentRegistry.default()) {
|
|
45
|
+
this.registry = registry;
|
|
46
|
+
}
|
|
41
47
|
|
|
42
48
|
/**
|
|
43
49
|
* Register an adapter for a specific agent type
|
|
@@ -150,10 +156,37 @@ export class AgentManager {
|
|
|
150
156
|
});
|
|
151
157
|
}
|
|
152
158
|
|
|
159
|
+
const preExistingByPid = new Map(this.registry.list().map((e) => [e.pid, e]));
|
|
160
|
+
const entries = allAgents.map((agent) =>
|
|
161
|
+
this.toRegistryEntry(agent, preExistingByPid.get(agent.pid)),
|
|
162
|
+
);
|
|
163
|
+
if (entries.length > 0) this.registry.registerBatch(entries);
|
|
164
|
+
this.registry.prune();
|
|
165
|
+
|
|
166
|
+
for (const agent of allAgents) {
|
|
167
|
+
const entry = preExistingByPid.get(agent.pid);
|
|
168
|
+
if (entry) {
|
|
169
|
+
agent.name = entry.name;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
|
|
153
173
|
const sortKey: AgentSortKey = options?.sortBy ?? 'status';
|
|
154
174
|
return sortAgents(allAgents, sortKey);
|
|
155
175
|
}
|
|
156
176
|
|
|
177
|
+
private toRegistryEntry(agent: AgentInfo, existing?: RegistryEntry): RegistryEntry {
|
|
178
|
+
return {
|
|
179
|
+
name: existing?.name ?? agent.name,
|
|
180
|
+
type: agent.type,
|
|
181
|
+
pid: agent.pid,
|
|
182
|
+
tmuxSession: existing?.tmuxSession ?? '',
|
|
183
|
+
cwd: agent.projectPath,
|
|
184
|
+
startedAt: existing?.startedAt ?? new Date().toISOString(),
|
|
185
|
+
sessionId: agent.sessionId,
|
|
186
|
+
sessionFilePath: agent.sessionFilePath ?? '',
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
157
190
|
/**
|
|
158
191
|
* List historical sessions across every registered adapter.
|
|
159
192
|
*
|
|
@@ -228,6 +261,13 @@ export class AgentManager {
|
|
|
228
261
|
resolveAgent(input: string, agents: AgentInfo[]): AgentInfo | AgentInfo[] | null {
|
|
229
262
|
if (!input || agents.length === 0) return null;
|
|
230
263
|
|
|
264
|
+
// Registry-first: if name is in registry and its PID is in the agent list, return it
|
|
265
|
+
const registryEntry = this.registry.lookup(input);
|
|
266
|
+
if (registryEntry) {
|
|
267
|
+
const registryAgent = agents.find((a) => a.pid === registryEntry.pid);
|
|
268
|
+
if (registryAgent) return registryAgent;
|
|
269
|
+
}
|
|
270
|
+
|
|
231
271
|
const lowerInput = input.toLowerCase();
|
|
232
272
|
|
|
233
273
|
// 1. Exact match (case-insensitive)
|