@ai-devkit/agent-manager 0.14.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/.eslintrc.json +1 -1
- package/dist/AgentManager.d.ts +14 -12
- package/dist/AgentManager.d.ts.map +1 -1
- package/dist/AgentManager.js +40 -33
- 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 +5 -2
- package/dist/adapters/CodexAdapter.d.ts.map +1 -1
- package/dist/adapters/CodexAdapter.js +66 -73
- package/dist/adapters/CodexAdapter.js.map +1 -1
- package/dist/adapters/GeminiCliAdapter.d.ts +5 -2
- package/dist/adapters/GeminiCliAdapter.d.ts.map +1 -1
- package/dist/adapters/GeminiCliAdapter.js +63 -70
- 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 +18 -11
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12 -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/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/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/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 +2 -2
- package/dist/utils/ClaudeSessionParser.d.ts.map +1 -1
- package/dist/utils/ClaudeSessionParser.js +32 -59
- 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/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 +53 -28
- package/src/__tests__/AgentManager.test.ts +140 -5
- package/src/__tests__/adapters/ClaudeCodeAdapter.test.ts +45 -44
- package/src/__tests__/adapters/CodexAdapter.test.ts +137 -30
- package/src/__tests__/adapters/GeminiCliAdapter.test.ts +130 -18
- package/src/__tests__/adapters/OpenCodeAdapter.test.ts +23 -21
- package/src/__tests__/terminal/TmuxManager.test.ts +175 -0
- package/src/__tests__/terminal/TtyWriter.test.ts +10 -9
- package/src/__tests__/utils/AgentRegistry.test.ts +223 -0
- package/src/__tests__/utils/ClaudeSessionParser.test.ts +73 -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 +51 -12
- package/src/adapters/GeminiCliAdapter.ts +51 -12
- package/src/adapters/OpenCodeAdapter.ts +4 -4
- package/src/adapters/index.ts +6 -6
- package/src/index.ts +19 -11
- package/src/terminal/TerminalFocusManager.ts +2 -2
- package/src/terminal/TmuxManager.ts +118 -0
- package/src/terminal/TtyWriter.ts +3 -3
- package/src/terminal/index.ts +4 -4
- package/src/utils/AgentRegistry.ts +139 -0
- package/src/utils/ClaudeSessionParser.ts +23 -12
- package/src/utils/agents.ts +41 -0
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matching.d.ts","sourceRoot":"","sources":["../../src/utils/matching.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"matching.d.ts","sourceRoot":"","sources":["../../src/utils/matching.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAKhD;;GAEG;AACH,MAAM,WAAW,WAAW;IACxB,0BAA0B;IAC1B,OAAO,EAAE,WAAW,CAAC;IAErB,+BAA+B;IAC/B,OAAO,EAAE,WAAW,CAAC;IAErB,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACpC,SAAS,EAAE,WAAW,EAAE,EACxB,QAAQ,EAAE,WAAW,EAAE,GACxB,WAAW,EAAE,CAsCf;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAOlE"}
|
package/dist/utils/matching.js
CHANGED
|
@@ -1,47 +1,10 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Session Matching Utilities
|
|
4
3
|
*
|
|
5
4
|
* Shared 1:1 greedy matching algorithm that pairs running processes with session files
|
|
6
5
|
* based on CWD and birth-time proximity to process start time.
|
|
7
6
|
*/
|
|
8
|
-
|
|
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.matchProcessesToSessions = matchProcessesToSessions;
|
|
43
|
-
exports.generateAgentName = generateAgentName;
|
|
44
|
-
const path = __importStar(require("path"));
|
|
7
|
+
import * as path from 'path';
|
|
45
8
|
/** Maximum allowed delta between process start time and session file birth time. */
|
|
46
9
|
const TOLERANCE_MS = 3 * 60 * 1000; // 3 minutes
|
|
47
10
|
/**
|
|
@@ -56,7 +19,7 @@ const TOLERANCE_MS = 3 * 60 * 1000; // 3 minutes
|
|
|
56
19
|
*
|
|
57
20
|
* Adapters must set session.resolvedCwd before calling this function.
|
|
58
21
|
*/
|
|
59
|
-
function matchProcessesToSessions(processes, sessions) {
|
|
22
|
+
export function matchProcessesToSessions(processes, sessions) {
|
|
60
23
|
// Build all candidate pairs
|
|
61
24
|
const candidates = [];
|
|
62
25
|
for (const proc of processes) {
|
|
@@ -96,7 +59,7 @@ function matchProcessesToSessions(processes, sessions) {
|
|
|
96
59
|
*
|
|
97
60
|
* Format: "folder-name-pid" (lowercase kebab-case)
|
|
98
61
|
*/
|
|
99
|
-
function generateAgentName(cwd, pid) {
|
|
62
|
+
export function generateAgentName(cwd, pid) {
|
|
100
63
|
const folderName = path.basename(cwd) || 'unknown';
|
|
101
64
|
const kebab = folderName
|
|
102
65
|
.toLowerCase()
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matching.js","sourceRoot":"","sources":["../../src/utils/matching.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"matching.js","sourceRoot":"","sources":["../../src/utils/matching.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAI7B,oFAAoF;AACpF,MAAM,YAAY,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,YAAY;AAgBhD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,wBAAwB,CACpC,SAAwB,EACxB,QAAuB;IAEvB,4BAA4B;IAC5B,MAAM,UAAU,GAA2E,EAAE,CAAC;IAE9F,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC3B,IAAI,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,GAAG;YAAE,SAAS;QAE3C,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC;QAEhD,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,CAAC,OAAO,CAAC,WAAW;gBAAE,SAAS;YACnC,IAAI,IAAI,CAAC,GAAG,KAAK,OAAO,CAAC,WAAW;gBAAE,SAAS;YAE/C,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,cAAc,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;YAC/D,IAAI,OAAO,GAAG,YAAY;gBAAE,SAAS;YAErC,UAAU,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;QACzD,CAAC;IACL,CAAC;IAED,+BAA+B;IAC/B,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IAEjD,wBAAwB;IACxB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;IACtC,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;IAC5C,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACjC,IAAI,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC;YAAE,SAAS;QACrD,IAAI,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC;YAAE,SAAS;QAEjE,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACvC,iBAAiB,CAAC,GAAG,CAAC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,GAAW;IACtD,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,SAAS,CAAC;IACnD,MAAM,KAAK,GAAG,UAAU;SACnB,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IAC7B,OAAO,GAAG,KAAK,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;AAC1C,CAAC"}
|
package/dist/utils/process.d.ts
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Shared shell command wrappers for detecting and inspecting running processes.
|
|
5
5
|
* All execFileSync calls for process data live here — adapters must not call execFileSync directly.
|
|
6
6
|
*/
|
|
7
|
-
import type { ProcessInfo } from '../adapters/AgentAdapter';
|
|
7
|
+
import type { ProcessInfo } from '../adapters/AgentAdapter.js';
|
|
8
8
|
/**
|
|
9
9
|
* List running processes matching an agent executable name.
|
|
10
10
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/utils/process.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../../src/utils/process.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAE/D;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,WAAW,EAAE,CA6CrE;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAuCvE;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAkC3E;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE,CAavE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAYjD"}
|
package/dist/utils/process.js
CHANGED
|
@@ -1,51 +1,11 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Process Detection Utilities
|
|
4
3
|
*
|
|
5
4
|
* Shared shell command wrappers for detecting and inspecting running processes.
|
|
6
5
|
* All execFileSync calls for process data live here — adapters must not call execFileSync directly.
|
|
7
6
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
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.listAgentProcesses = listAgentProcesses;
|
|
43
|
-
exports.batchGetProcessCwds = batchGetProcessCwds;
|
|
44
|
-
exports.batchGetProcessStartTimes = batchGetProcessStartTimes;
|
|
45
|
-
exports.enrichProcesses = enrichProcesses;
|
|
46
|
-
exports.getProcessTty = getProcessTty;
|
|
47
|
-
const path = __importStar(require("path"));
|
|
48
|
-
const child_process_1 = require("child_process");
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import { execFileSync } from 'child_process';
|
|
49
9
|
/**
|
|
50
10
|
* List running processes matching an agent executable name.
|
|
51
11
|
*
|
|
@@ -55,13 +15,13 @@ const child_process_1 = require("child_process");
|
|
|
55
15
|
* Returned ProcessInfo has pid, command, tty populated.
|
|
56
16
|
* cwd and startTime are NOT populated — call enrichProcesses() to fill them.
|
|
57
17
|
*/
|
|
58
|
-
function listAgentProcesses(namePattern) {
|
|
18
|
+
export function listAgentProcesses(namePattern) {
|
|
59
19
|
// Validate pattern contains only safe characters (alphanumeric, dash, underscore)
|
|
60
20
|
if (!namePattern || !/^[a-zA-Z0-9_-]+$/.test(namePattern)) {
|
|
61
21
|
return [];
|
|
62
22
|
}
|
|
63
23
|
try {
|
|
64
|
-
const output =
|
|
24
|
+
const output = execFileSync('ps', ['aux'], { encoding: 'utf-8' });
|
|
65
25
|
const lowerPattern = namePattern.toLowerCase();
|
|
66
26
|
const processes = [];
|
|
67
27
|
for (const line of output.trim().split('\n')) {
|
|
@@ -101,12 +61,12 @@ function listAgentProcesses(namePattern) {
|
|
|
101
61
|
* Single `lsof -a -d cwd -Fn -p PID1,PID2,...` call.
|
|
102
62
|
* Returns partial results — if lsof fails for one PID, others still return.
|
|
103
63
|
*/
|
|
104
|
-
function batchGetProcessCwds(pids) {
|
|
64
|
+
export function batchGetProcessCwds(pids) {
|
|
105
65
|
const result = new Map();
|
|
106
66
|
if (pids.length === 0)
|
|
107
67
|
return result;
|
|
108
68
|
try {
|
|
109
|
-
const output =
|
|
69
|
+
const output = execFileSync('lsof', ['-a', '-d', 'cwd', '-Fn', '-p', pids.join(',')], { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] });
|
|
110
70
|
// lsof output format: p{PID}\nn{path}\np{PID}\nn{path}...
|
|
111
71
|
let currentPid = null;
|
|
112
72
|
for (const line of output.trim().split('\n')) {
|
|
@@ -123,7 +83,7 @@ function batchGetProcessCwds(pids) {
|
|
|
123
83
|
// Try per-PID fallback with pwdx (Linux)
|
|
124
84
|
for (const pid of pids) {
|
|
125
85
|
try {
|
|
126
|
-
const output =
|
|
86
|
+
const output = execFileSync('pwdx', [String(pid)], { encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] });
|
|
127
87
|
const match = output.match(/^\d+:\s*(.+)$/);
|
|
128
88
|
if (match) {
|
|
129
89
|
result.set(pid, match[1].trim());
|
|
@@ -143,12 +103,12 @@ function batchGetProcessCwds(pids) {
|
|
|
143
103
|
* Uses lstart format which gives full timestamp (e.g., "Thu Feb 5 16:00:57 2026").
|
|
144
104
|
* Returns partial results.
|
|
145
105
|
*/
|
|
146
|
-
function batchGetProcessStartTimes(pids) {
|
|
106
|
+
export function batchGetProcessStartTimes(pids) {
|
|
147
107
|
const result = new Map();
|
|
148
108
|
if (pids.length === 0)
|
|
149
109
|
return result;
|
|
150
110
|
try {
|
|
151
|
-
const output =
|
|
111
|
+
const output = execFileSync('ps', ['-o', 'pid=,lstart=', '-p', pids.join(',')], { encoding: 'utf-8' });
|
|
152
112
|
for (const rawLine of output.split('\n')) {
|
|
153
113
|
const line = rawLine.trim();
|
|
154
114
|
if (!line)
|
|
@@ -180,7 +140,7 @@ function batchGetProcessStartTimes(pids) {
|
|
|
180
140
|
* then populates each ProcessInfo in-place. Returns partial results —
|
|
181
141
|
* if a PID fails, that process keeps empty cwd / undefined startTime.
|
|
182
142
|
*/
|
|
183
|
-
function enrichProcesses(processes) {
|
|
143
|
+
export function enrichProcesses(processes) {
|
|
184
144
|
if (processes.length === 0)
|
|
185
145
|
return processes;
|
|
186
146
|
const pids = processes.map(p => p.pid);
|
|
@@ -195,9 +155,9 @@ function enrichProcesses(processes) {
|
|
|
195
155
|
/**
|
|
196
156
|
* Get the TTY device for a specific process
|
|
197
157
|
*/
|
|
198
|
-
function getProcessTty(pid) {
|
|
158
|
+
export function getProcessTty(pid) {
|
|
199
159
|
try {
|
|
200
|
-
const output =
|
|
160
|
+
const output = execFileSync('ps', ['-p', String(pid), '-o', 'tty='], { encoding: 'utf-8' });
|
|
201
161
|
const tty = output.trim();
|
|
202
162
|
return tty.startsWith('/dev/') ? tty.slice(5) : tty;
|
|
203
163
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/utils/process.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"process.js","sourceRoot":"","sources":["../../src/utils/process.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/session.js
CHANGED
|
@@ -1,64 +1,23 @@
|
|
|
1
|
-
"use strict";
|
|
2
1
|
/**
|
|
3
2
|
* Session File Utilities
|
|
4
3
|
*
|
|
5
4
|
* Utilities for discovering session files and their birth times.
|
|
6
5
|
* Uses Node.js fs APIs to get birth timestamps without reading file contents.
|
|
7
6
|
*/
|
|
8
|
-
|
|
9
|
-
|
|
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.isDirectory = isDirectory;
|
|
43
|
-
exports.safeStat = safeStat;
|
|
44
|
-
exports.safeReadFile = safeReadFile;
|
|
45
|
-
exports.safeReaddir = safeReaddir;
|
|
46
|
-
exports.listJsonl = listJsonl;
|
|
47
|
-
exports.batchGetSessionFileBirthtimes = batchGetSessionFileBirthtimes;
|
|
48
|
-
const fs = __importStar(require("fs"));
|
|
49
|
-
const path = __importStar(require("path"));
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
50
9
|
/**
|
|
51
10
|
* Check whether a path exists and is a directory.
|
|
52
11
|
* Returns false on any error (missing path, permission denied, broken symlink, etc.).
|
|
53
12
|
*/
|
|
54
|
-
function isDirectory(p) {
|
|
13
|
+
export function isDirectory(p) {
|
|
55
14
|
return safeStat(p)?.isDirectory() ?? false;
|
|
56
15
|
}
|
|
57
16
|
/**
|
|
58
17
|
* `fs.statSync` that swallows errors and returns `undefined` on failure.
|
|
59
18
|
* Callers can pull whichever fields they need (mtime, birthtime, ...).
|
|
60
19
|
*/
|
|
61
|
-
function safeStat(filePath) {
|
|
20
|
+
export function safeStat(filePath) {
|
|
62
21
|
try {
|
|
63
22
|
return fs.statSync(filePath);
|
|
64
23
|
}
|
|
@@ -71,7 +30,7 @@ function safeStat(filePath) {
|
|
|
71
30
|
* on failure. Use when an unreadable file should be skipped rather than
|
|
72
31
|
* raised.
|
|
73
32
|
*/
|
|
74
|
-
function safeReadFile(filePath) {
|
|
33
|
+
export function safeReadFile(filePath) {
|
|
75
34
|
try {
|
|
76
35
|
return fs.readFileSync(filePath, 'utf-8');
|
|
77
36
|
}
|
|
@@ -84,7 +43,7 @@ function safeReadFile(filePath) {
|
|
|
84
43
|
* Useful when walking optional/transient directories where missing or
|
|
85
44
|
* unreadable entries should be skipped silently.
|
|
86
45
|
*/
|
|
87
|
-
function safeReaddir(dir) {
|
|
46
|
+
export function safeReaddir(dir) {
|
|
88
47
|
try {
|
|
89
48
|
return fs.readdirSync(dir);
|
|
90
49
|
}
|
|
@@ -96,7 +55,7 @@ function safeReaddir(dir) {
|
|
|
96
55
|
* List entries in a directory that end with `.jsonl`. Returns `[]` on
|
|
97
56
|
* read errors. The result preserves directory order (no sorting).
|
|
98
57
|
*/
|
|
99
|
-
function listJsonl(dir) {
|
|
58
|
+
export function listJsonl(dir) {
|
|
100
59
|
return safeReaddir(dir).filter((name) => name.endsWith('.jsonl'));
|
|
101
60
|
}
|
|
102
61
|
/**
|
|
@@ -107,7 +66,7 @@ function listJsonl(dir) {
|
|
|
107
66
|
* Returns empty array if no directories have .jsonl files or reads fail.
|
|
108
67
|
* resolvedCwd is left empty — the adapter must set it.
|
|
109
68
|
*/
|
|
110
|
-
function batchGetSessionFileBirthtimes(dirs) {
|
|
69
|
+
export function batchGetSessionFileBirthtimes(dirs) {
|
|
111
70
|
if (dirs.length === 0)
|
|
112
71
|
return [];
|
|
113
72
|
const results = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/utils/session.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/utils/session.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAsB7B;;;GAGG;AACH,MAAM,UAAU,WAAW,CAAC,CAAS;IACjC,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,KAAK,CAAC;AAC/C,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,QAAgB;IACrC,IAAI,CAAC;QACD,OAAO,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACjC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,SAAS,CAAC;IACrB,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB;IACzC,IAAI,CAAC;QACD,OAAO,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC9C,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,SAAS,CAAC;IACrB,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,GAAW;IACnC,IAAI,CAAC;QACD,OAAO,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,EAAE,CAAC;IACd,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW;IACjC,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AACtE,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,6BAA6B,CAAC,IAAc;IACxD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEjC,MAAM,OAAO,GAAkB,EAAE,CAAC;IAElC,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACrB,IAAI,OAAiB,CAAC;QACtB,IAAI,CAAC;YACD,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,CAAC;QAAC,MAAM,CAAC;YACL,SAAS;QACb,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC1B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAExC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YAEvC,IAAI,WAAmB,CAAC;YACxB,IAAI,CAAC;gBACD,WAAW,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC;YACpD,CAAC;YAAC,MAAM,CAAC;gBACL,SAAS;YACb,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,WAAW,IAAI,CAAC;gBAAE,SAAS;YAEhE,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;YAEhD,OAAO,CAAC,IAAI,CAAC;gBACT,SAAS;gBACT,QAAQ;gBACR,UAAU,EAAE,GAAG;gBACf,WAAW;gBACX,WAAW,EAAE,EAAE;aAClB,CAAC,CAAC;QACP,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sortAgents.d.ts","sourceRoot":"","sources":["../../src/utils/sortAgents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE1E,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,YAAY,CAAC;AAgCpE,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,EAAE,EAAE,YAAY,GAAG,SAAS,EAAE,CAiB7E"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { AgentStatus } from '../adapters/AgentAdapter.js';
|
|
2
|
+
const STATUS_PRIORITY = {
|
|
3
|
+
[AgentStatus.WAITING]: 0,
|
|
4
|
+
[AgentStatus.RUNNING]: 1,
|
|
5
|
+
[AgentStatus.IDLE]: 2,
|
|
6
|
+
[AgentStatus.UNKNOWN]: 3,
|
|
7
|
+
};
|
|
8
|
+
function compareByName(a, b) {
|
|
9
|
+
return a.name.localeCompare(b.name);
|
|
10
|
+
}
|
|
11
|
+
function compareByStatus(a, b) {
|
|
12
|
+
const pa = STATUS_PRIORITY[a.status] ?? 999;
|
|
13
|
+
const pb = STATUS_PRIORITY[b.status] ?? 999;
|
|
14
|
+
if (pa !== pb)
|
|
15
|
+
return pa - pb;
|
|
16
|
+
return compareByName(a, b);
|
|
17
|
+
}
|
|
18
|
+
function compareByPid(a, b) {
|
|
19
|
+
if (a.pid !== b.pid)
|
|
20
|
+
return a.pid - b.pid;
|
|
21
|
+
return compareByName(a, b);
|
|
22
|
+
}
|
|
23
|
+
function compareByLastActive(a, b) {
|
|
24
|
+
const ta = a.lastActive instanceof Date ? a.lastActive.getTime() : new Date(a.lastActive).getTime();
|
|
25
|
+
const tb = b.lastActive instanceof Date ? b.lastActive.getTime() : new Date(b.lastActive).getTime();
|
|
26
|
+
if (tb !== ta)
|
|
27
|
+
return tb - ta; // most recent first
|
|
28
|
+
return compareByName(a, b);
|
|
29
|
+
}
|
|
30
|
+
export function sortAgents(agents, by) {
|
|
31
|
+
const copy = agents.slice();
|
|
32
|
+
switch (by) {
|
|
33
|
+
case 'name':
|
|
34
|
+
copy.sort(compareByName);
|
|
35
|
+
break;
|
|
36
|
+
case 'status':
|
|
37
|
+
copy.sort(compareByStatus);
|
|
38
|
+
break;
|
|
39
|
+
case 'pid':
|
|
40
|
+
copy.sort(compareByPid);
|
|
41
|
+
break;
|
|
42
|
+
case 'lastActive':
|
|
43
|
+
copy.sort(compareByLastActive);
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
return copy;
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=sortAgents.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sortAgents.js","sourceRoot":"","sources":["../../src/utils/sortAgents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,6BAA6B,CAAC;AAI1E,MAAM,eAAe,GAAgC;IACjD,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;IACxB,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;IACxB,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;IACrB,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,CAAC;CAC3B,CAAC;AAEF,SAAS,aAAa,CAAC,CAAY,EAAE,CAAY;IAC7C,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;AACxC,CAAC;AAED,SAAS,eAAe,CAAC,CAAY,EAAE,CAAY;IAC/C,MAAM,EAAE,GAAG,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;IAC5C,MAAM,EAAE,GAAG,eAAe,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;IAC5C,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,EAAE,GAAG,EAAE,CAAC;IAC9B,OAAO,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,YAAY,CAAC,CAAY,EAAE,CAAY;IAC5C,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG;QAAE,OAAO,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC;IAC1C,OAAO,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,mBAAmB,CAAC,CAAY,EAAE,CAAY;IACnD,MAAM,EAAE,GAAG,CAAC,CAAC,UAAU,YAAY,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC;IACpG,MAAM,EAAE,GAAG,CAAC,CAAC,UAAU,YAAY,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC;IACpG,IAAI,EAAE,KAAK,EAAE;QAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,oBAAoB;IACnD,OAAO,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAmB,EAAE,EAAgB;IAC5D,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC;IAC5B,QAAQ,EAAE,EAAE,CAAC;QACT,KAAK,MAAM;YACP,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;YACzB,MAAM;QACV,KAAK,QAAQ;YACT,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;YAC3B,MAAM;QACV,KAAK,KAAK;YACN,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YACxB,MAAM;QACV,KAAK,YAAY;YACb,IAAI,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;YAC/B,MAAM;IACd,CAAC;IACD,OAAO,IAAI,CAAC;AAChB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-devkit/agent-manager",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0",
|
|
4
|
+
"type": "module",
|
|
4
5
|
"description": "Standalone agent detection and management utilities for AI DevKit",
|
|
5
6
|
"main": "dist/index.js",
|
|
6
7
|
"types": "dist/index.d.ts",
|
|
7
8
|
"exports": {
|
|
8
9
|
".": {
|
|
9
10
|
"types": "./dist/index.d.ts",
|
|
10
|
-
"
|
|
11
|
+
"import": "./dist/index.js"
|
|
11
12
|
}
|
|
12
13
|
},
|
|
13
14
|
"scripts": {
|
|
14
15
|
"build": "tsc",
|
|
15
|
-
"test": "
|
|
16
|
-
"test:
|
|
16
|
+
"test": "vitest run",
|
|
17
|
+
"test:watch": "vitest",
|
|
18
|
+
"test:coverage": "vitest run --coverage",
|
|
17
19
|
"lint": "eslint src --ext .ts",
|
|
18
20
|
"typecheck": "tsc --noEmit",
|
|
19
21
|
"clean": "rm -rf dist"
|
|
@@ -31,14 +33,13 @@
|
|
|
31
33
|
},
|
|
32
34
|
"devDependencies": {
|
|
33
35
|
"@types/better-sqlite3": "^7.6.11",
|
|
34
|
-
"@types/jest": "^30.0.0",
|
|
35
36
|
"@types/node": "^20.11.5",
|
|
36
37
|
"@typescript-eslint/eslint-plugin": "^6.19.1",
|
|
37
38
|
"@typescript-eslint/parser": "^6.19.1",
|
|
39
|
+
"@vitest/coverage-v8": "^2.1.0",
|
|
38
40
|
"eslint": "^8.56.0",
|
|
39
|
-
"
|
|
40
|
-
"
|
|
41
|
-
"typescript": "^5.3.3"
|
|
41
|
+
"typescript": "^5.5.0",
|
|
42
|
+
"vitest": "^2.1.0"
|
|
42
43
|
},
|
|
43
44
|
"engines": {
|
|
44
45
|
"node": ">=20.20.0"
|
package/src/AgentManager.ts
CHANGED
|
@@ -10,8 +10,17 @@ import type {
|
|
|
10
10
|
AgentInfo,
|
|
11
11
|
SessionSummary,
|
|
12
12
|
ListSessionsOptions,
|
|
13
|
-
} from './adapters/AgentAdapter';
|
|
14
|
-
import {
|
|
13
|
+
} from './adapters/AgentAdapter.js';
|
|
14
|
+
import { sortAgents, type AgentSortKey } from './utils/sortAgents.js';
|
|
15
|
+
import { AgentRegistry, type RegistryEntry } from './utils/AgentRegistry.js';
|
|
16
|
+
|
|
17
|
+
export interface ListAgentsOptions {
|
|
18
|
+
/**
|
|
19
|
+
* Sort key for the returned list. Defaults to `status`, which orders
|
|
20
|
+
* waiting → running → idle → unknown, then by name for stability.
|
|
21
|
+
*/
|
|
22
|
+
sortBy?: AgentSortKey;
|
|
23
|
+
}
|
|
15
24
|
|
|
16
25
|
/**
|
|
17
26
|
* Agent Manager Class
|
|
@@ -30,6 +39,11 @@ import { AgentStatus } from './adapters/AgentAdapter';
|
|
|
30
39
|
*/
|
|
31
40
|
export class AgentManager {
|
|
32
41
|
private adapters: Map<string, AgentAdapter> = new Map();
|
|
42
|
+
private registry: AgentRegistry;
|
|
43
|
+
|
|
44
|
+
constructor(registry: AgentRegistry = AgentRegistry.default()) {
|
|
45
|
+
this.registry = registry;
|
|
46
|
+
}
|
|
33
47
|
|
|
34
48
|
/**
|
|
35
49
|
* Register an adapter for a specific agent type
|
|
@@ -108,7 +122,7 @@ export class AgentManager {
|
|
|
108
122
|
* });
|
|
109
123
|
* ```
|
|
110
124
|
*/
|
|
111
|
-
async listAgents(): Promise<AgentInfo[]> {
|
|
125
|
+
async listAgents(options?: ListAgentsOptions): Promise<AgentInfo[]> {
|
|
112
126
|
const allAgents: AgentInfo[] = [];
|
|
113
127
|
const errors: Array<{ type: string; error: Error }> = [];
|
|
114
128
|
|
|
@@ -142,8 +156,35 @@ export class AgentManager {
|
|
|
142
156
|
});
|
|
143
157
|
}
|
|
144
158
|
|
|
145
|
-
|
|
146
|
-
|
|
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
|
+
|
|
173
|
+
const sortKey: AgentSortKey = options?.sortBy ?? 'status';
|
|
174
|
+
return sortAgents(allAgents, sortKey);
|
|
175
|
+
}
|
|
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
|
+
};
|
|
147
188
|
}
|
|
148
189
|
|
|
149
190
|
/**
|
|
@@ -193,29 +234,6 @@ export class AgentManager {
|
|
|
193
234
|
return merged;
|
|
194
235
|
}
|
|
195
236
|
|
|
196
|
-
/**
|
|
197
|
-
* Sort agents by status priority
|
|
198
|
-
*
|
|
199
|
-
* Priority order: waiting > running > idle > unknown
|
|
200
|
-
* This ensures agents that need attention appear first.
|
|
201
|
-
*
|
|
202
|
-
* @param agents Array of agents to sort
|
|
203
|
-
* @returns Sorted array of agents
|
|
204
|
-
*/
|
|
205
|
-
private sortAgentsByStatus(agents: AgentInfo[]): AgentInfo[] {
|
|
206
|
-
const statusPriority: Record<AgentStatus, number> = {
|
|
207
|
-
[AgentStatus.WAITING]: 0,
|
|
208
|
-
[AgentStatus.RUNNING]: 1,
|
|
209
|
-
[AgentStatus.IDLE]: 2,
|
|
210
|
-
[AgentStatus.UNKNOWN]: 3,
|
|
211
|
-
};
|
|
212
|
-
|
|
213
|
-
return agents.sort((a, b) => {
|
|
214
|
-
const priorityA = statusPriority[a.status] ?? 999;
|
|
215
|
-
const priorityB = statusPriority[b.status] ?? 999;
|
|
216
|
-
return priorityA - priorityB;
|
|
217
|
-
});
|
|
218
|
-
}
|
|
219
237
|
|
|
220
238
|
/**
|
|
221
239
|
* Get count of registered adapters
|
|
@@ -243,6 +261,13 @@ export class AgentManager {
|
|
|
243
261
|
resolveAgent(input: string, agents: AgentInfo[]): AgentInfo | AgentInfo[] | null {
|
|
244
262
|
if (!input || agents.length === 0) return null;
|
|
245
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
|
+
|
|
246
271
|
const lowerInput = input.toLowerCase();
|
|
247
272
|
|
|
248
273
|
// 1. Exact match (case-insensitive)
|