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.
Files changed (91) hide show
  1. package/INSTALL.md +154 -0
  2. package/README.md +228 -0
  3. package/dist/audit/logger.d.ts +25 -0
  4. package/dist/audit/logger.d.ts.map +1 -0
  5. package/dist/audit/logger.js +56 -0
  6. package/dist/audit/logger.js.map +1 -0
  7. package/dist/browser/actions.d.ts +111 -0
  8. package/dist/browser/actions.d.ts.map +1 -0
  9. package/dist/browser/actions.js +291 -0
  10. package/dist/browser/actions.js.map +1 -0
  11. package/dist/browser/manager.d.ts +51 -0
  12. package/dist/browser/manager.d.ts.map +1 -0
  13. package/dist/browser/manager.js +233 -0
  14. package/dist/browser/manager.js.map +1 -0
  15. package/dist/cli/client.d.ts +13 -0
  16. package/dist/cli/client.d.ts.map +1 -0
  17. package/dist/cli/client.js +109 -0
  18. package/dist/cli/client.js.map +1 -0
  19. package/dist/cli/commands/actions.d.ts +3 -0
  20. package/dist/cli/commands/actions.d.ts.map +1 -0
  21. package/dist/cli/commands/actions.js +349 -0
  22. package/dist/cli/commands/actions.js.map +1 -0
  23. package/dist/cli/commands/pages.d.ts +3 -0
  24. package/dist/cli/commands/pages.d.ts.map +1 -0
  25. package/dist/cli/commands/pages.js +107 -0
  26. package/dist/cli/commands/pages.js.map +1 -0
  27. package/dist/cli/commands/route.d.ts +3 -0
  28. package/dist/cli/commands/route.d.ts.map +1 -0
  29. package/dist/cli/commands/route.js +72 -0
  30. package/dist/cli/commands/route.js.map +1 -0
  31. package/dist/cli/commands/session.d.ts +3 -0
  32. package/dist/cli/commands/session.d.ts.map +1 -0
  33. package/dist/cli/commands/session.js +57 -0
  34. package/dist/cli/commands/session.js.map +1 -0
  35. package/dist/cli/commands/start.d.ts +8 -0
  36. package/dist/cli/commands/start.d.ts.map +1 -0
  37. package/dist/cli/commands/start.js +66 -0
  38. package/dist/cli/commands/start.js.map +1 -0
  39. package/dist/cli/commands/status.d.ts +6 -0
  40. package/dist/cli/commands/status.d.ts.map +1 -0
  41. package/dist/cli/commands/status.js +25 -0
  42. package/dist/cli/commands/status.js.map +1 -0
  43. package/dist/cli/commands/stop.d.ts +6 -0
  44. package/dist/cli/commands/stop.d.ts.map +1 -0
  45. package/dist/cli/commands/stop.js +53 -0
  46. package/dist/cli/commands/stop.js.map +1 -0
  47. package/dist/cli/commands/trace.d.ts +3 -0
  48. package/dist/cli/commands/trace.d.ts.map +1 -0
  49. package/dist/cli/commands/trace.js +43 -0
  50. package/dist/cli/commands/trace.js.map +1 -0
  51. package/dist/cli/index.d.ts +3 -0
  52. package/dist/cli/index.d.ts.map +1 -0
  53. package/dist/cli/index.js +44 -0
  54. package/dist/cli/index.js.map +1 -0
  55. package/dist/daemon/config.d.ts +25 -0
  56. package/dist/daemon/config.d.ts.map +1 -0
  57. package/dist/daemon/config.js +35 -0
  58. package/dist/daemon/config.js.map +1 -0
  59. package/dist/daemon/index.d.ts +7 -0
  60. package/dist/daemon/index.d.ts.map +1 -0
  61. package/dist/daemon/index.js +84 -0
  62. package/dist/daemon/index.js.map +1 -0
  63. package/dist/daemon/routes/actions.d.ts +5 -0
  64. package/dist/daemon/routes/actions.d.ts.map +1 -0
  65. package/dist/daemon/routes/actions.js +425 -0
  66. package/dist/daemon/routes/actions.js.map +1 -0
  67. package/dist/daemon/routes/sessions.d.ts +5 -0
  68. package/dist/daemon/routes/sessions.d.ts.map +1 -0
  69. package/dist/daemon/routes/sessions.js +507 -0
  70. package/dist/daemon/routes/sessions.js.map +1 -0
  71. package/dist/daemon/server.d.ts +6 -0
  72. package/dist/daemon/server.d.ts.map +1 -0
  73. package/dist/daemon/server.js +66 -0
  74. package/dist/daemon/server.js.map +1 -0
  75. package/dist/daemon/session.d.ts +52 -0
  76. package/dist/daemon/session.d.ts.map +1 -0
  77. package/dist/daemon/session.js +191 -0
  78. package/dist/daemon/session.js.map +1 -0
  79. package/dist/daemon/types.d.ts +17 -0
  80. package/dist/daemon/types.d.ts.map +1 -0
  81. package/dist/daemon/types.js +3 -0
  82. package/dist/daemon/types.js.map +1 -0
  83. package/dist/policy/engine.d.ts +43 -0
  84. package/dist/policy/engine.d.ts.map +1 -0
  85. package/dist/policy/engine.js +234 -0
  86. package/dist/policy/engine.js.map +1 -0
  87. package/dist/policy/types.d.ts +40 -0
  88. package/dist/policy/types.d.ts.map +1 -0
  89. package/dist/policy/types.js +53 -0
  90. package/dist/policy/types.js.map +1 -0
  91. 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":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function sessionCommands(program: Command): void;
3
+ //# sourceMappingURL=session.d.ts.map
@@ -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,8 @@
1
+ interface StartOptions {
2
+ port: string;
3
+ dataDir: string;
4
+ logLevel: string;
5
+ }
6
+ export declare function startDaemon(opts: StartOptions): Promise<void>;
7
+ export {};
8
+ //# sourceMappingURL=start.d.ts.map
@@ -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,6 @@
1
+ interface StatusOptions {
2
+ port: string;
3
+ }
4
+ export declare function showStatus(opts: StatusOptions): Promise<void>;
5
+ export {};
6
+ //# sourceMappingURL=status.d.ts.map
@@ -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,6 @@
1
+ interface StopOptions {
2
+ dataDir: string;
3
+ }
4
+ export declare function stopDaemon(opts: StopOptions): Promise<void>;
5
+ export {};
6
+ //# sourceMappingURL=stop.d.ts.map
@@ -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,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function traceCommands(program: Command): void;
3
+ //# sourceMappingURL=trace.d.ts.map
@@ -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,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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,7 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * agentmb daemon entrypoint
4
+ * Launched by: agentmb start OR node dist/daemon/index.js
5
+ */
6
+ export {};
7
+ //# sourceMappingURL=index.d.ts.map
@@ -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