agentmb 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.
- package/INSTALL.md +154 -0
- package/README.md +228 -0
- package/dist/audit/logger.d.ts +25 -0
- package/dist/audit/logger.d.ts.map +1 -0
- package/dist/audit/logger.js +56 -0
- package/dist/audit/logger.js.map +1 -0
- package/dist/browser/actions.d.ts +111 -0
- package/dist/browser/actions.d.ts.map +1 -0
- package/dist/browser/actions.js +291 -0
- package/dist/browser/actions.js.map +1 -0
- package/dist/browser/manager.d.ts +51 -0
- package/dist/browser/manager.d.ts.map +1 -0
- package/dist/browser/manager.js +233 -0
- package/dist/browser/manager.js.map +1 -0
- package/dist/cli/client.d.ts +13 -0
- package/dist/cli/client.d.ts.map +1 -0
- package/dist/cli/client.js +109 -0
- package/dist/cli/client.js.map +1 -0
- package/dist/cli/commands/actions.d.ts +3 -0
- package/dist/cli/commands/actions.d.ts.map +1 -0
- package/dist/cli/commands/actions.js +349 -0
- package/dist/cli/commands/actions.js.map +1 -0
- package/dist/cli/commands/pages.d.ts +3 -0
- package/dist/cli/commands/pages.d.ts.map +1 -0
- package/dist/cli/commands/pages.js +107 -0
- package/dist/cli/commands/pages.js.map +1 -0
- package/dist/cli/commands/route.d.ts +3 -0
- package/dist/cli/commands/route.d.ts.map +1 -0
- package/dist/cli/commands/route.js +72 -0
- package/dist/cli/commands/route.js.map +1 -0
- package/dist/cli/commands/session.d.ts +3 -0
- package/dist/cli/commands/session.d.ts.map +1 -0
- package/dist/cli/commands/session.js +57 -0
- package/dist/cli/commands/session.js.map +1 -0
- package/dist/cli/commands/start.d.ts +8 -0
- package/dist/cli/commands/start.d.ts.map +1 -0
- package/dist/cli/commands/start.js +66 -0
- package/dist/cli/commands/start.js.map +1 -0
- package/dist/cli/commands/status.d.ts +6 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +25 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/cli/commands/stop.d.ts +6 -0
- package/dist/cli/commands/stop.d.ts.map +1 -0
- package/dist/cli/commands/stop.js +53 -0
- package/dist/cli/commands/stop.js.map +1 -0
- package/dist/cli/commands/trace.d.ts +3 -0
- package/dist/cli/commands/trace.d.ts.map +1 -0
- package/dist/cli/commands/trace.js +43 -0
- package/dist/cli/commands/trace.js.map +1 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +44 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/daemon/config.d.ts +25 -0
- package/dist/daemon/config.d.ts.map +1 -0
- package/dist/daemon/config.js +35 -0
- package/dist/daemon/config.js.map +1 -0
- package/dist/daemon/index.d.ts +7 -0
- package/dist/daemon/index.d.ts.map +1 -0
- package/dist/daemon/index.js +84 -0
- package/dist/daemon/index.js.map +1 -0
- package/dist/daemon/routes/actions.d.ts +5 -0
- package/dist/daemon/routes/actions.d.ts.map +1 -0
- package/dist/daemon/routes/actions.js +425 -0
- package/dist/daemon/routes/actions.js.map +1 -0
- package/dist/daemon/routes/sessions.d.ts +5 -0
- package/dist/daemon/routes/sessions.d.ts.map +1 -0
- package/dist/daemon/routes/sessions.js +507 -0
- package/dist/daemon/routes/sessions.js.map +1 -0
- package/dist/daemon/server.d.ts +6 -0
- package/dist/daemon/server.d.ts.map +1 -0
- package/dist/daemon/server.js +66 -0
- package/dist/daemon/server.js.map +1 -0
- package/dist/daemon/session.d.ts +52 -0
- package/dist/daemon/session.d.ts.map +1 -0
- package/dist/daemon/session.js +191 -0
- package/dist/daemon/session.js.map +1 -0
- package/dist/daemon/types.d.ts +17 -0
- package/dist/daemon/types.d.ts.map +1 -0
- package/dist/daemon/types.js +3 -0
- package/dist/daemon/types.js.map +1 -0
- package/dist/policy/engine.d.ts +43 -0
- package/dist/policy/engine.d.ts.map +1 -0
- package/dist/policy/engine.js +234 -0
- package/dist/policy/engine.js.map +1 -0
- package/dist/policy/types.d.ts +40 -0
- package/dist/policy/types.d.ts.map +1 -0
- package/dist/policy/types.js +53 -0
- package/dist/policy/types.js.map +1 -0
- package/package.json +61 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.routeCommands = routeCommands;
|
|
4
|
+
const client_1 = require("../client");
|
|
5
|
+
function routeCommands(program) {
|
|
6
|
+
const route = program.command('route').description('Manage network route mocks for a session');
|
|
7
|
+
route
|
|
8
|
+
.command('list <session-id>')
|
|
9
|
+
.description('List active route mocks')
|
|
10
|
+
.action(async (sessionId) => {
|
|
11
|
+
const res = await (0, client_1.apiGet)(`/api/v1/sessions/${sessionId}/routes`);
|
|
12
|
+
if (res.error) {
|
|
13
|
+
console.error('Error:', res.error);
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
const routes = res.routes ?? [];
|
|
17
|
+
if (routes.length === 0) {
|
|
18
|
+
console.log('No active route mocks.');
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
for (const r of routes) {
|
|
22
|
+
const mock = r.mock ?? {};
|
|
23
|
+
console.log(` ${r.pattern} → HTTP ${mock.status ?? 200} ${mock.content_type ?? ''}`);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
route
|
|
27
|
+
.command('add <session-id> <pattern>')
|
|
28
|
+
.description('Register a route mock (intercept requests matching pattern)')
|
|
29
|
+
.option('--status <code>', 'HTTP status code', '200')
|
|
30
|
+
.option('--body <text>', 'Response body text')
|
|
31
|
+
.option('--content-type <type>', 'Response content-type', 'text/plain')
|
|
32
|
+
.option('--headers <json>', 'Extra response headers as JSON object (e.g. \'{"X-Mock":"1"}\')')
|
|
33
|
+
.action(async (sessionId, pattern, opts) => {
|
|
34
|
+
const mock = {
|
|
35
|
+
status: parseInt(opts.status),
|
|
36
|
+
content_type: opts.contentType,
|
|
37
|
+
};
|
|
38
|
+
if (opts.body !== undefined)
|
|
39
|
+
mock.body = opts.body;
|
|
40
|
+
if (opts.headers) {
|
|
41
|
+
try {
|
|
42
|
+
mock.headers = JSON.parse(opts.headers);
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
console.error('Error: --headers must be valid JSON');
|
|
46
|
+
process.exit(1);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
const res = await (0, client_1.apiPost)(`/api/v1/sessions/${sessionId}/route`, { pattern, mock });
|
|
50
|
+
if (res.error) {
|
|
51
|
+
console.error('Error:', res.error);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
console.log(`✓ Route mock registered: ${res.pattern}`);
|
|
55
|
+
});
|
|
56
|
+
route
|
|
57
|
+
.command('rm <session-id> <pattern>')
|
|
58
|
+
.description('Remove a route mock by pattern')
|
|
59
|
+
.action(async (sessionId, pattern) => {
|
|
60
|
+
const res = await (0, client_1.apiDeleteWithBody)(`/api/v1/sessions/${sessionId}/route`, { pattern });
|
|
61
|
+
if (res.statusCode === 400) {
|
|
62
|
+
console.error('Error:', res.data?.error ?? 'Bad request');
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
if (res.statusCode === 404) {
|
|
66
|
+
console.error('Error: Session not found.');
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
console.log(`✓ Route mock removed: ${pattern}`);
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=route.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"route.js","sourceRoot":"","sources":["../../../src/cli/commands/route.ts"],"names":[],"mappings":";;AAGA,sCAgDC;AAlDD,sCAA8D;AAE9D,SAAgB,aAAa,CAAC,OAAgB;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,0CAA0C,CAAC,CAAA;IAE9F,KAAK;SACF,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,yBAAyB,CAAC;SACtC,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,EAAE;QAC1B,MAAM,GAAG,GAAG,MAAM,IAAA,eAAM,EAAC,oBAAoB,SAAS,SAAS,CAAC,CAAA;QAChE,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAAC,CAAC;QACtE,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,EAAE,CAAA;QAC/B,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;YAAC,OAAM;QAAC,CAAC;QAC1E,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,IAAI,EAAE,CAAA;YACzB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,OAAO,aAAa,IAAI,CAAC,MAAM,IAAI,GAAG,KAAK,IAAI,CAAC,YAAY,IAAI,EAAE,EAAE,CAAC,CAAA;QAC1F,CAAC;IACH,CAAC,CAAC,CAAA;IAEJ,KAAK;SACF,OAAO,CAAC,4BAA4B,CAAC;SACrC,WAAW,CAAC,6DAA6D,CAAC;SAC1E,MAAM,CAAC,iBAAiB,EAAE,kBAAkB,EAAE,KAAK,CAAC;SACpD,MAAM,CAAC,eAAe,EAAE,oBAAoB,CAAC;SAC7C,MAAM,CAAC,uBAAuB,EAAE,uBAAuB,EAAE,YAAY,CAAC;SACtE,MAAM,CAAC,kBAAkB,EAAE,iEAAiE,CAAC;SAC7F,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;QACzC,MAAM,IAAI,GAA4B;YACpC,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC;YAC7B,YAAY,EAAE,IAAI,CAAC,WAAW;SAC/B,CAAA;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS;YAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,CAAA;QAClD,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,IAAI,CAAC;gBAAC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;YAAC,CAAC;YAC/C,MAAM,CAAC;gBAAC,OAAO,CAAC,KAAK,CAAC,qCAAqC,CAAC,CAAC;gBAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAAC,CAAC;QACjF,CAAC;QACD,MAAM,GAAG,GAAG,MAAM,IAAA,gBAAO,EAAC,oBAAoB,SAAS,QAAQ,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAA;QACnF,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,4BAA4B,GAAG,CAAC,OAAO,EAAE,CAAC,CAAA;IACxD,CAAC,CAAC,CAAA;IAEJ,KAAK;SACF,OAAO,CAAC,2BAA2B,CAAC;SACpC,WAAW,CAAC,gCAAgC,CAAC;SAC7C,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,EAAE;QACnC,MAAM,GAAG,GAAG,MAAM,IAAA,0BAAiB,EAAC,oBAAoB,SAAS,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC,CAAA;QACvF,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;YAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,EAAE,KAAK,IAAI,aAAa,CAAC,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAAC,CAAC;QAC1G,IAAI,GAAG,CAAC,UAAU,KAAK,GAAG,EAAE,CAAC;YAAC,OAAO,CAAC,KAAK,CAAC,2BAA2B,CAAC,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAAC,CAAC;QAC3F,OAAO,CAAC,GAAG,CAAC,yBAAyB,OAAO,EAAE,CAAC,CAAA;IACjD,CAAC,CAAC,CAAA;AACN,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGnC,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkDtD"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sessionCommands = sessionCommands;
|
|
4
|
+
const client_1 = require("../client");
|
|
5
|
+
function sessionCommands(program) {
|
|
6
|
+
const sess = program.command('session').description('Manage browser sessions');
|
|
7
|
+
sess
|
|
8
|
+
.command('new')
|
|
9
|
+
.description('Create a new browser session')
|
|
10
|
+
.option('--profile <name>', 'Profile name', 'default')
|
|
11
|
+
.option('--headed', 'Launch in headed (visible) mode')
|
|
12
|
+
.option('--accept-downloads', 'Allow the browser to save downloaded files (default: off)')
|
|
13
|
+
.action(async (opts) => {
|
|
14
|
+
const res = await (0, client_1.apiPost)('/api/v1/sessions', {
|
|
15
|
+
profile: opts.profile,
|
|
16
|
+
headless: !opts.headed,
|
|
17
|
+
accept_downloads: opts.acceptDownloads ?? false,
|
|
18
|
+
});
|
|
19
|
+
if (res.error) {
|
|
20
|
+
console.error('Error:', res.error);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
console.log(`Created session: ${res.session_id}`);
|
|
24
|
+
console.log(` Profile: ${res.profile}`);
|
|
25
|
+
console.log(` Headless: ${res.headless}`);
|
|
26
|
+
if (res.accept_downloads)
|
|
27
|
+
console.log(` Downloads: enabled`);
|
|
28
|
+
});
|
|
29
|
+
sess
|
|
30
|
+
.command('list')
|
|
31
|
+
.description('List active sessions')
|
|
32
|
+
.action(async () => {
|
|
33
|
+
const sessions = await (0, client_1.apiGet)('/api/v1/sessions');
|
|
34
|
+
if (!Array.isArray(sessions) || sessions.length === 0) {
|
|
35
|
+
console.log('No active sessions.');
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
for (const s of sessions) {
|
|
39
|
+
// API v2 returns session_id/created_at; guard against old field names
|
|
40
|
+
const id = s.session_id ?? s.id;
|
|
41
|
+
const created = s.created_at ?? s.createdAt;
|
|
42
|
+
console.log(` ${id} profile=${s.profile} headless=${s.headless} state=${s.state ?? 'live'} created=${created}`);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
sess
|
|
46
|
+
.command('rm <session-id>')
|
|
47
|
+
.description('Close and remove a session')
|
|
48
|
+
.action(async (sessionId) => {
|
|
49
|
+
const result = await (0, client_1.apiDelete)(`/api/v1/sessions/${sessionId}`);
|
|
50
|
+
if (result.statusCode === 404) {
|
|
51
|
+
console.error(`Session ${sessionId} not found.`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
console.log(`Session ${sessionId} closed.`);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=session.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../../src/cli/commands/session.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"AAIA,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;CACjB;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAmCnE"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.startDaemon = startDaemon;
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const http_1 = __importDefault(require("http"));
|
|
10
|
+
async function startDaemon(opts) {
|
|
11
|
+
const port = parseInt(opts.port);
|
|
12
|
+
const env = {
|
|
13
|
+
...process.env,
|
|
14
|
+
AGENTMB_PORT: String(port),
|
|
15
|
+
AGENTMB_DATA_DIR: opts.dataDir,
|
|
16
|
+
AGENTMB_LOG_LEVEL: opts.logLevel,
|
|
17
|
+
};
|
|
18
|
+
// Check if already running
|
|
19
|
+
const running = await isRunning(port);
|
|
20
|
+
if (running) {
|
|
21
|
+
console.log(`agentmb daemon already running on port ${port}`);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const daemonEntry = path_1.default.join(__dirname, '../../daemon/index.js');
|
|
25
|
+
const child = (0, child_process_1.spawn)(process.execPath, [daemonEntry], {
|
|
26
|
+
env,
|
|
27
|
+
detached: true,
|
|
28
|
+
stdio: 'inherit',
|
|
29
|
+
});
|
|
30
|
+
child.unref();
|
|
31
|
+
console.log(`agentmb daemon starting on port ${port} (PID ${child.pid})…`);
|
|
32
|
+
// Wait up to 5s for daemon to become ready
|
|
33
|
+
const ready = await waitReady(port, 5000);
|
|
34
|
+
if (ready) {
|
|
35
|
+
console.log(`✓ agentmb daemon ready — http://127.0.0.1:${port}`);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
console.error('✗ Daemon did not become ready within 5 seconds. Check logs.');
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function isRunning(port) {
|
|
43
|
+
return new Promise((resolve) => {
|
|
44
|
+
const req = http_1.default.get(`http://127.0.0.1:${port}/health`, (res) => {
|
|
45
|
+
resolve(res.statusCode === 200);
|
|
46
|
+
});
|
|
47
|
+
req.on('error', () => resolve(false));
|
|
48
|
+
req.setTimeout(500, () => { req.destroy(); resolve(false); });
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
function waitReady(port, timeoutMs) {
|
|
52
|
+
return new Promise((resolve) => {
|
|
53
|
+
const deadline = Date.now() + timeoutMs;
|
|
54
|
+
const check = () => {
|
|
55
|
+
isRunning(port).then((ok) => {
|
|
56
|
+
if (ok)
|
|
57
|
+
return resolve(true);
|
|
58
|
+
if (Date.now() >= deadline)
|
|
59
|
+
return resolve(false);
|
|
60
|
+
setTimeout(check, 300);
|
|
61
|
+
});
|
|
62
|
+
};
|
|
63
|
+
setTimeout(check, 500); // give daemon a moment to bind
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../../src/cli/commands/start.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAEA,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBnE"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.showStatus = showStatus;
|
|
4
|
+
const client_1 = require("../client");
|
|
5
|
+
async function showStatus(opts) {
|
|
6
|
+
// CLI flag takes precedence; write back to env so apiGet() connects to the right port
|
|
7
|
+
const port = opts.port ? parseInt(opts.port) : (0, client_1.cliPort)();
|
|
8
|
+
if (opts.port)
|
|
9
|
+
process.env.AGENTMB_PORT = opts.port;
|
|
10
|
+
const data = await (0, client_1.apiGet)(`/api/v1/status`).catch(() => null);
|
|
11
|
+
if (!data || data.error) {
|
|
12
|
+
console.log(`agentmb daemon is NOT running on port ${port}`);
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
console.log(`agentmb daemon RUNNING`);
|
|
16
|
+
console.log(` PID: ${data.pid}`);
|
|
17
|
+
console.log(` Uptime: ${data.uptime_s}s`);
|
|
18
|
+
console.log(` Sessions: ${data.sessions?.length ?? 0}`);
|
|
19
|
+
if (data.sessions?.length) {
|
|
20
|
+
for (const s of data.sessions) {
|
|
21
|
+
console.log(` [${s.id}] profile=${s.profile} headless=${s.headless}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.js","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":";;AAMA,gCAkBC;AAxBD,sCAA2C;AAMpC,KAAK,UAAU,UAAU,CAAC,IAAmB;IAClD,sFAAsF;IACtF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAA,gBAAO,GAAE,CAAA;IACxD,IAAI,IAAI,CAAC,IAAI;QAAE,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,IAAI,CAAC,IAAI,CAAA;IACnD,MAAM,IAAI,GAAG,MAAM,IAAA,eAAM,EAAC,gBAAgB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;IAC7D,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,yCAAyC,IAAI,EAAE,CAAC,CAAA;QAC5D,OAAM;IACR,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAA;IACrC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;IACtC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,QAAQ,GAAG,CAAC,CAAA;IAC5C,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,CAAC,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAE,CAAC,CAAA;IACxD,IAAI,IAAI,CAAC,QAAQ,EAAE,MAAM,EAAE,CAAC;QAC1B,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,aAAa,CAAC,CAAC,OAAO,aAAa,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA;QAC1E,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/stop.ts"],"names":[],"mappings":"AAGA,UAAU,WAAW;IACnB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAyCjE"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.stopDaemon = stopDaemon;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
async function stopDaemon(opts) {
|
|
10
|
+
const pidPath = path_1.default.join(opts.dataDir, 'daemon.pid');
|
|
11
|
+
if (!fs_1.default.existsSync(pidPath)) {
|
|
12
|
+
console.log('No daemon PID file found — daemon is not running.');
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const pid = parseInt(fs_1.default.readFileSync(pidPath, 'utf8').trim());
|
|
16
|
+
if (isNaN(pid)) {
|
|
17
|
+
console.error('Invalid PID file. Removing.');
|
|
18
|
+
fs_1.default.unlinkSync(pidPath);
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
try {
|
|
22
|
+
process.kill(pid, 'SIGTERM');
|
|
23
|
+
console.log(`✓ Sent SIGTERM to daemon (PID ${pid})`);
|
|
24
|
+
// Wait for PID file to disappear (daemon removes it on clean exit)
|
|
25
|
+
let waited = 0;
|
|
26
|
+
while (fs_1.default.existsSync(pidPath) && waited < 5000) {
|
|
27
|
+
await new Promise((r) => setTimeout(r, 200));
|
|
28
|
+
waited += 200;
|
|
29
|
+
}
|
|
30
|
+
if (fs_1.default.existsSync(pidPath)) {
|
|
31
|
+
console.warn('Daemon did not exit cleanly within 5s. Sending SIGKILL…');
|
|
32
|
+
try {
|
|
33
|
+
process.kill(pid, 'SIGKILL');
|
|
34
|
+
}
|
|
35
|
+
catch { }
|
|
36
|
+
fs_1.default.unlinkSync(pidPath);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
console.log('✓ Daemon stopped.');
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
if (err.code === 'ESRCH') {
|
|
44
|
+
console.log('Daemon process not found (already stopped). Cleaning up PID file.');
|
|
45
|
+
fs_1.default.unlinkSync(pidPath);
|
|
46
|
+
}
|
|
47
|
+
else {
|
|
48
|
+
console.error('Error stopping daemon:', err.message);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=stop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stop.js","sourceRoot":"","sources":["../../../src/cli/commands/stop.ts"],"names":[],"mappings":";;;;;AAOA,gCAyCC;AAhDD,4CAAmB;AACnB,gDAAuB;AAMhB,KAAK,UAAU,UAAU,CAAC,IAAiB;IAChD,MAAM,OAAO,GAAG,cAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;IAErD,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAA;QAChE,OAAM;IACR,CAAC;IAED,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;IAC7D,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAA;QAC5C,YAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QACtB,OAAM;IACR,CAAC;IAED,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;QAC5B,OAAO,CAAC,GAAG,CAAC,iCAAiC,GAAG,GAAG,CAAC,CAAA;QAEpD,mEAAmE;QACnE,IAAI,MAAM,GAAG,CAAC,CAAA;QACd,OAAO,YAAE,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,MAAM,GAAG,IAAI,EAAE,CAAC;YAC/C,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAA;YAC5C,MAAM,IAAI,GAAG,CAAA;QACf,CAAC;QACD,IAAI,YAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,yDAAyD,CAAC,CAAA;YACvE,IAAI,CAAC;gBAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;YAAC,CAAC;YAAC,MAAM,CAAC,CAAA,CAAC;YAC7C,YAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QACxB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC,CAAA;QAClC,CAAC;IACH,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,mEAAmE,CAAC,CAAA;YAChF,YAAE,CAAC,UAAU,CAAC,OAAO,CAAC,CAAA;QACxB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,wBAAwB,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;YACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/trace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAInC,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA6BpD"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.traceCommands = traceCommands;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const client_1 = require("../client");
|
|
9
|
+
function traceCommands(program) {
|
|
10
|
+
const trace = program.command('trace').description('Playwright trace recording for a session');
|
|
11
|
+
trace
|
|
12
|
+
.command('start <session-id>')
|
|
13
|
+
.description('Start trace recording (screenshots + DOM snapshots)')
|
|
14
|
+
.option('--no-screenshots', 'Disable screenshot recording')
|
|
15
|
+
.option('--no-snapshots', 'Disable DOM snapshot recording')
|
|
16
|
+
.action(async (sessionId, opts) => {
|
|
17
|
+
const res = await (0, client_1.apiPost)(`/api/v1/sessions/${sessionId}/trace/start`, {
|
|
18
|
+
screenshots: opts.screenshots !== false,
|
|
19
|
+
snapshots: opts.snapshots !== false,
|
|
20
|
+
});
|
|
21
|
+
if (res.error) {
|
|
22
|
+
console.error('Error:', res.error);
|
|
23
|
+
process.exit(1);
|
|
24
|
+
}
|
|
25
|
+
console.log(`✓ Trace recording started for session ${sessionId}`);
|
|
26
|
+
});
|
|
27
|
+
trace
|
|
28
|
+
.command('stop <session-id>')
|
|
29
|
+
.description('Stop trace recording and save the ZIP to a file')
|
|
30
|
+
.option('-o, --out <file>', 'Output file path', './trace.zip')
|
|
31
|
+
.action(async (sessionId, opts) => {
|
|
32
|
+
const res = await (0, client_1.apiPost)(`/api/v1/sessions/${sessionId}/trace/stop`, {});
|
|
33
|
+
if (res.error) {
|
|
34
|
+
console.error('Error:', res.error);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
const buf = Buffer.from(res.data, 'base64');
|
|
38
|
+
fs_1.default.writeFileSync(opts.out, buf);
|
|
39
|
+
console.log(`✓ Trace saved to ${opts.out} (${(buf.length / 1024).toFixed(1)}KB)`);
|
|
40
|
+
console.log(` Open with: npx playwright show-trace ${opts.out}`);
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=trace.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../../../src/cli/commands/trace.ts"],"names":[],"mappings":";;;;;AAIA,sCA6BC;AAhCD,4CAAmB;AACnB,sCAAmC;AAEnC,SAAgB,aAAa,CAAC,OAAgB;IAC5C,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,WAAW,CAAC,0CAA0C,CAAC,CAAA;IAE9F,KAAK;SACF,OAAO,CAAC,oBAAoB,CAAC;SAC7B,WAAW,CAAC,qDAAqD,CAAC;SAClE,MAAM,CAAC,kBAAkB,EAAE,8BAA8B,CAAC;SAC1D,MAAM,CAAC,gBAAgB,EAAE,gCAAgC,CAAC;SAC1D,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;QAChC,MAAM,GAAG,GAAG,MAAM,IAAA,gBAAO,EAAC,oBAAoB,SAAS,cAAc,EAAE;YACrE,WAAW,EAAE,IAAI,CAAC,WAAW,KAAK,KAAK;YACvC,SAAS,EAAE,IAAI,CAAC,SAAS,KAAK,KAAK;SACpC,CAAC,CAAA;QACF,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAAC,CAAC;QACtE,OAAO,CAAC,GAAG,CAAC,yCAAyC,SAAS,EAAE,CAAC,CAAA;IACnE,CAAC,CAAC,CAAA;IAEJ,KAAK;SACF,OAAO,CAAC,mBAAmB,CAAC;SAC5B,WAAW,CAAC,iDAAiD,CAAC;SAC9D,MAAM,CAAC,kBAAkB,EAAE,kBAAkB,EAAE,aAAa,CAAC;SAC7D,MAAM,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;QAChC,MAAM,GAAG,GAAG,MAAM,IAAA,gBAAO,EAAC,oBAAoB,SAAS,aAAa,EAAE,EAAE,CAAC,CAAA;QACzE,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;YAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;YAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QAAC,CAAC;QACtE,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAA;QAC3C,YAAE,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;QAC/B,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;QACjF,OAAO,CAAC,GAAG,CAAC,0CAA0C,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;IACnE,CAAC,CAAC,CAAA;AACN,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const start_1 = require("./commands/start");
|
|
6
|
+
const stop_1 = require("./commands/stop");
|
|
7
|
+
const status_1 = require("./commands/status");
|
|
8
|
+
const session_1 = require("./commands/session");
|
|
9
|
+
const actions_1 = require("./commands/actions");
|
|
10
|
+
const pages_1 = require("./commands/pages");
|
|
11
|
+
const route_1 = require("./commands/route");
|
|
12
|
+
const trace_1 = require("./commands/trace");
|
|
13
|
+
const program = new commander_1.Command();
|
|
14
|
+
program
|
|
15
|
+
.name('agentmb')
|
|
16
|
+
.description('agentmb — local Chromium runtime for AI agents')
|
|
17
|
+
.version('0.1.0');
|
|
18
|
+
program
|
|
19
|
+
.command('start')
|
|
20
|
+
.description('Start the agentmb daemon')
|
|
21
|
+
.option('-p, --port <port>', 'Port to listen on', '19315')
|
|
22
|
+
.option('-d, --data-dir <dir>', 'Data directory', `${process.env.HOME}/.agentmb`)
|
|
23
|
+
.option('-l, --log-level <level>', 'Log level (trace|debug|info|warn|error)', 'info')
|
|
24
|
+
.action(start_1.startDaemon);
|
|
25
|
+
program
|
|
26
|
+
.command('stop')
|
|
27
|
+
.description('Stop the running agentmb daemon')
|
|
28
|
+
.option('-d, --data-dir <dir>', 'Data directory', `${process.env.HOME}/.agentmb`)
|
|
29
|
+
.action(stop_1.stopDaemon);
|
|
30
|
+
program
|
|
31
|
+
.command('status')
|
|
32
|
+
.description('Show daemon status')
|
|
33
|
+
.option('-p, --port <port>', 'Port', '19315')
|
|
34
|
+
.action(status_1.showStatus);
|
|
35
|
+
(0, session_1.sessionCommands)(program);
|
|
36
|
+
(0, actions_1.actionCommands)(program);
|
|
37
|
+
(0, pages_1.pagesCommands)(program);
|
|
38
|
+
(0, route_1.routeCommands)(program);
|
|
39
|
+
(0, trace_1.traceCommands)(program);
|
|
40
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
41
|
+
console.error('Error:', err.message);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
});
|
|
44
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;AACA,yCAAmC;AACnC,4CAA8C;AAC9C,0CAA4C;AAC5C,8CAA8C;AAC9C,gDAAoD;AACpD,gDAAmD;AACnD,4CAAgD;AAChD,4CAAgD;AAChD,4CAAgD;AAEhD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAA;AAE7B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,gDAAgD,CAAC;KAC7D,OAAO,CAAC,OAAO,CAAC,CAAA;AAEnB,OAAO;KACJ,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,0BAA0B,CAAC;KACvC,MAAM,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,OAAO,CAAC;KACzD,MAAM,CAAC,sBAAsB,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC;KAChF,MAAM,CAAC,yBAAyB,EAAE,yCAAyC,EAAE,MAAM,CAAC;KACpF,MAAM,CAAC,mBAAW,CAAC,CAAA;AAEtB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,iCAAiC,CAAC;KAC9C,MAAM,CAAC,sBAAsB,EAAE,gBAAgB,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC;KAChF,MAAM,CAAC,iBAAU,CAAC,CAAA;AAErB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,oBAAoB,CAAC;KACjC,MAAM,CAAC,mBAAmB,EAAE,MAAM,EAAE,OAAO,CAAC;KAC5C,MAAM,CAAC,mBAAU,CAAC,CAAA;AAErB,IAAA,yBAAe,EAAC,OAAO,CAAC,CAAA;AACxB,IAAA,wBAAc,EAAC,OAAO,CAAC,CAAA;AACvB,IAAA,qBAAa,EAAC,OAAO,CAAC,CAAA;AACtB,IAAA,qBAAa,EAAC,OAAO,CAAC,CAAA;AACtB,IAAA,qBAAa,EAAC,OAAO,CAAC,CAAA;AAEtB,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC7C,OAAO,CAAC,KAAK,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,CAAA;IACpC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export interface DaemonConfig {
|
|
2
|
+
port: number;
|
|
3
|
+
host: string;
|
|
4
|
+
dataDir: string;
|
|
5
|
+
logLevel: string;
|
|
6
|
+
apiToken?: string;
|
|
7
|
+
/**
|
|
8
|
+
* Optional AES-256-GCM encryption key for sessions.json.
|
|
9
|
+
* Must be exactly 32 bytes encoded as base64 (44 chars) or hex (64 chars).
|
|
10
|
+
* Set via AGENTMB_ENCRYPTION_KEY env var.
|
|
11
|
+
* If not set, sessions.json is stored as plain JSON (backward compatible).
|
|
12
|
+
*/
|
|
13
|
+
encryptionKey?: string;
|
|
14
|
+
/**
|
|
15
|
+
* Safety execution policy profile applied globally (r06-c02).
|
|
16
|
+
* Set via AGENTMB_POLICY_PROFILE env var.
|
|
17
|
+
* Values: 'safe' (default) | 'permissive' | 'disabled'
|
|
18
|
+
*/
|
|
19
|
+
policyProfile?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function resolveConfig(overrides?: Partial<DaemonConfig>): DaemonConfig;
|
|
22
|
+
export declare function profilesDir(config: DaemonConfig): string;
|
|
23
|
+
export declare function logsDir(config: DaemonConfig): string;
|
|
24
|
+
export declare function pidFile(config: DaemonConfig): string;
|
|
25
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/daemon/config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,wBAAgB,aAAa,CAAC,SAAS,GAAE,OAAO,CAAC,YAAY,CAAM,GAAG,YAAY,CAejF;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAExD;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAEpD;AAED,wBAAgB,OAAO,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAEpD"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.resolveConfig = resolveConfig;
|
|
7
|
+
exports.profilesDir = profilesDir;
|
|
8
|
+
exports.logsDir = logsDir;
|
|
9
|
+
exports.pidFile = pidFile;
|
|
10
|
+
const os_1 = __importDefault(require("os"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
function resolveConfig(overrides = {}) {
|
|
13
|
+
const dataDir = overrides.dataDir ??
|
|
14
|
+
process.env.AGENTMB_DATA_DIR ??
|
|
15
|
+
path_1.default.join(os_1.default.homedir(), '.agentmb');
|
|
16
|
+
return {
|
|
17
|
+
port: overrides.port ?? Number(process.env.AGENTMB_PORT ?? 19315),
|
|
18
|
+
host: overrides.host ?? process.env.AGENTMB_HOST ?? '127.0.0.1',
|
|
19
|
+
dataDir,
|
|
20
|
+
logLevel: overrides.logLevel ?? process.env.AGENTMB_LOG_LEVEL ?? 'info',
|
|
21
|
+
apiToken: overrides.apiToken ?? process.env.AGENTMB_API_TOKEN,
|
|
22
|
+
encryptionKey: overrides.encryptionKey ?? process.env.AGENTMB_ENCRYPTION_KEY,
|
|
23
|
+
policyProfile: overrides.policyProfile ?? process.env.AGENTMB_POLICY_PROFILE ?? 'safe',
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function profilesDir(config) {
|
|
27
|
+
return path_1.default.join(config.dataDir, 'profiles');
|
|
28
|
+
}
|
|
29
|
+
function logsDir(config) {
|
|
30
|
+
return path_1.default.join(config.dataDir, 'logs');
|
|
31
|
+
}
|
|
32
|
+
function pidFile(config) {
|
|
33
|
+
return path_1.default.join(config.dataDir, 'daemon.pid');
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/daemon/config.ts"],"names":[],"mappings":";;;;;AAwBA,sCAeC;AAED,kCAEC;AAED,0BAEC;AAED,0BAEC;AAnDD,4CAAmB;AACnB,gDAAuB;AAuBvB,SAAgB,aAAa,CAAC,YAAmC,EAAE;IACjE,MAAM,OAAO,GACX,SAAS,CAAC,OAAO;QACjB,OAAO,CAAC,GAAG,CAAC,gBAAgB;QAC5B,cAAI,CAAC,IAAI,CAAC,YAAE,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAA;IAErC,OAAO;QACL,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,KAAK,CAAC;QACjE,IAAI,EAAE,SAAS,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,WAAW;QAC/D,OAAO;QACP,QAAQ,EAAE,SAAS,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,MAAM;QACvE,QAAQ,EAAE,SAAS,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB;QAC7D,aAAa,EAAE,SAAS,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB;QAC5E,aAAa,EAAE,SAAS,CAAC,aAAa,IAAI,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,MAAM;KACvF,CAAA;AACH,CAAC;AAED,SAAgB,WAAW,CAAC,MAAoB;IAC9C,OAAO,cAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;AAC9C,CAAC;AAED,SAAgB,OAAO,CAAC,MAAoB;IAC1C,OAAO,cAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;AAC1C,CAAC;AAED,SAAgB,OAAO,CAAC,MAAoB;IAC1C,OAAO,cAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;AAChD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/daemon/index.ts"],"names":[],"mappings":";AACA;;;GAGG"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
/**
|
|
4
|
+
* agentmb daemon entrypoint
|
|
5
|
+
* Launched by: agentmb start OR node dist/daemon/index.js
|
|
6
|
+
*/
|
|
7
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
8
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
9
|
+
};
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
11
|
+
// Node 20 LTS minimum — checked before any imports that may fail on old runtimes
|
|
12
|
+
const [nodeMajor] = process.versions.node.split('.').map(Number);
|
|
13
|
+
if (nodeMajor < 20) {
|
|
14
|
+
process.stderr.write(`[agentmb] ERROR: Node.js ${process.versions.node} is not supported.\n` +
|
|
15
|
+
` Requires Node 20 LTS or higher. Install via: nvm install 20\n`);
|
|
16
|
+
process.exit(1);
|
|
17
|
+
}
|
|
18
|
+
const fs_1 = __importDefault(require("fs"));
|
|
19
|
+
const server_1 = require("./server");
|
|
20
|
+
const session_1 = require("./session");
|
|
21
|
+
const manager_1 = require("../browser/manager");
|
|
22
|
+
const logger_1 = require("../audit/logger");
|
|
23
|
+
const config_1 = require("./config");
|
|
24
|
+
const engine_1 = require("../policy/engine");
|
|
25
|
+
async function main() {
|
|
26
|
+
const config = (0, config_1.resolveConfig)();
|
|
27
|
+
// Ensure data directories exist
|
|
28
|
+
fs_1.default.mkdirSync((0, config_1.profilesDir)(config), { recursive: true });
|
|
29
|
+
fs_1.default.mkdirSync((0, config_1.logsDir)(config), { recursive: true });
|
|
30
|
+
// PID file — prevent double-start
|
|
31
|
+
const pid = (0, config_1.pidFile)(config);
|
|
32
|
+
if (fs_1.default.existsSync(pid)) {
|
|
33
|
+
const existingPid = fs_1.default.readFileSync(pid, 'utf8').trim();
|
|
34
|
+
try {
|
|
35
|
+
process.kill(Number(existingPid), 0); // check if process alive
|
|
36
|
+
console.error(`agentmb daemon already running (PID ${existingPid}). Use 'agentmb stop' first.`);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// stale pid file — remove and continue
|
|
41
|
+
fs_1.default.unlinkSync(pid);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
fs_1.default.writeFileSync(pid, String(process.pid));
|
|
45
|
+
const registry = new session_1.SessionRegistry(config.dataDir, config.encryptionKey);
|
|
46
|
+
const manager = new manager_1.BrowserManager(registry, config);
|
|
47
|
+
const auditLogger = new logger_1.AuditLogger((0, config_1.logsDir)(config));
|
|
48
|
+
// Restore persisted session metadata (zombie state — profiles on disk, browsers not auto-relaunched)
|
|
49
|
+
registry.loadPersistedSessions();
|
|
50
|
+
const zombieCount = registry.list().length;
|
|
51
|
+
if (zombieCount > 0) {
|
|
52
|
+
console.log(`[agentmb] Loaded ${zombieCount} session(s) from state file (zombie state — run 'agentmb session new' to relaunch browser)`);
|
|
53
|
+
}
|
|
54
|
+
const policyProfile = (config.policyProfile ?? 'safe');
|
|
55
|
+
const policyEngine = new engine_1.PolicyEngine(policyProfile);
|
|
56
|
+
const server = (0, server_1.buildServer)(config, registry);
|
|
57
|
+
// T11: Attach dependencies — typed via src/daemon/types.ts augmentation
|
|
58
|
+
server.browserManager = manager;
|
|
59
|
+
server.auditLogger = auditLogger;
|
|
60
|
+
server.policyEngine = policyEngine;
|
|
61
|
+
console.log(`[agentmb] Policy profile: ${policyProfile}`);
|
|
62
|
+
// Graceful shutdown
|
|
63
|
+
const shutdown = async (signal) => {
|
|
64
|
+
server.log.info(`Received ${signal}, shutting down…`);
|
|
65
|
+
// Persist zombie session state BEFORE closing browsers so metadata survives restart
|
|
66
|
+
await registry.shutdownAll();
|
|
67
|
+
await server.close();
|
|
68
|
+
fs_1.default.unlinkSync(pid);
|
|
69
|
+
process.exit(0);
|
|
70
|
+
};
|
|
71
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
72
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
73
|
+
try {
|
|
74
|
+
await server.listen({ port: config.port, host: config.host });
|
|
75
|
+
server.log.info(`agentmb daemon listening on http://${config.host}:${config.port}`);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
server.log.error(err);
|
|
79
|
+
fs_1.default.unlinkSync(pid);
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
main();
|
|
84
|
+
//# sourceMappingURL=index.js.map
|