@sena-ai/cli 0.0.15

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 (49) hide show
  1. package/dist/__tests__/config-loader.test.d.ts +2 -0
  2. package/dist/__tests__/config-loader.test.d.ts.map +1 -0
  3. package/dist/__tests__/config-loader.test.js +57 -0
  4. package/dist/__tests__/config-loader.test.js.map +1 -0
  5. package/dist/__tests__/pid.test.d.ts +2 -0
  6. package/dist/__tests__/pid.test.d.ts.map +1 -0
  7. package/dist/__tests__/pid.test.js +23 -0
  8. package/dist/__tests__/pid.test.js.map +1 -0
  9. package/dist/cli.d.ts +3 -0
  10. package/dist/cli.d.ts.map +1 -0
  11. package/dist/cli.js +27 -0
  12. package/dist/cli.js.map +1 -0
  13. package/dist/commands/logs.d.ts +3 -0
  14. package/dist/commands/logs.d.ts.map +1 -0
  15. package/dist/commands/logs.js +34 -0
  16. package/dist/commands/logs.js.map +1 -0
  17. package/dist/commands/restart.d.ts +3 -0
  18. package/dist/commands/restart.d.ts.map +1 -0
  19. package/dist/commands/restart.js +92 -0
  20. package/dist/commands/restart.js.map +1 -0
  21. package/dist/commands/start.d.ts +3 -0
  22. package/dist/commands/start.d.ts.map +1 -0
  23. package/dist/commands/start.js +91 -0
  24. package/dist/commands/start.js.map +1 -0
  25. package/dist/commands/status.d.ts +3 -0
  26. package/dist/commands/status.d.ts.map +1 -0
  27. package/dist/commands/status.js +58 -0
  28. package/dist/commands/status.js.map +1 -0
  29. package/dist/commands/stop.d.ts +3 -0
  30. package/dist/commands/stop.d.ts.map +1 -0
  31. package/dist/commands/stop.js +45 -0
  32. package/dist/commands/stop.js.map +1 -0
  33. package/dist/config-loader.d.ts +7 -0
  34. package/dist/config-loader.d.ts.map +1 -0
  35. package/dist/config-loader.js +41 -0
  36. package/dist/config-loader.js.map +1 -0
  37. package/dist/index.d.ts +3 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +2 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/pid.d.ts +5 -0
  42. package/dist/pid.d.ts.map +1 -0
  43. package/dist/pid.js +34 -0
  44. package/dist/pid.js.map +1 -0
  45. package/dist/worker-entry.d.ts +2 -0
  46. package/dist/worker-entry.d.ts.map +1 -0
  47. package/dist/worker-entry.js +22 -0
  48. package/dist/worker-entry.js.map +1 -0
  49. package/package.json +31 -0
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=config-loader.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/config-loader.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,57 @@
1
+ import { mkdtempSync, mkdirSync, realpathSync, writeFileSync } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { afterEach, describe, expect, it } from 'vitest';
5
+ import { loadConfig } from '../config-loader.js';
6
+ const createdDirs = [];
7
+ function createTempAgentDir() {
8
+ const dir = mkdtempSync(join(tmpdir(), 'sena-cli-'));
9
+ createdDirs.push(dir);
10
+ return dir;
11
+ }
12
+ describe('loadConfig', () => {
13
+ afterEach(() => {
14
+ delete process.env.SENA_PORT;
15
+ });
16
+ it('loads sena.config.ts and .env from the current working directory', async () => {
17
+ const dir = createTempAgentDir();
18
+ mkdirSync(join(dir, '.sena'));
19
+ writeFileSync(join(dir, '.env'), 'SENA_PORT=4567\n', 'utf-8');
20
+ writeFileSync(join(dir, 'sena.config.ts'), [
21
+ 'export default {',
22
+ " name: 'test-agent',",
23
+ ' orchestrator: { port: 1234 },',
24
+ '}',
25
+ ].join('\n'), 'utf-8');
26
+ const previousCwd = process.cwd();
27
+ process.chdir(dir);
28
+ try {
29
+ const result = await loadConfig();
30
+ expect(result.config.name).toBe('test-agent');
31
+ expect(result.port).toBe(1234);
32
+ expect(realpathSync(result.configPath)).toBe(realpathSync(join(dir, 'sena.config.ts')));
33
+ }
34
+ finally {
35
+ process.chdir(previousCwd);
36
+ }
37
+ });
38
+ it('falls back to SENA_PORT when config port is missing', async () => {
39
+ const dir = createTempAgentDir();
40
+ writeFileSync(join(dir, '.env'), 'SENA_PORT=4567\n', 'utf-8');
41
+ writeFileSync(join(dir, 'sena.config.ts'), [
42
+ 'export default {',
43
+ " name: 'port-from-env',",
44
+ '}',
45
+ ].join('\n'), 'utf-8');
46
+ const previousCwd = process.cwd();
47
+ process.chdir(dir);
48
+ try {
49
+ const result = await loadConfig();
50
+ expect(result.port).toBe(4567);
51
+ }
52
+ finally {
53
+ process.chdir(previousCwd);
54
+ }
55
+ });
56
+ });
57
+ //# sourceMappingURL=config-loader.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.test.js","sourceRoot":"","sources":["../../src/__tests__/config-loader.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=pid.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pid.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/pid.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,23 @@
1
+ import { mkdtempSync } from 'node:fs';
2
+ import { tmpdir } from 'node:os';
3
+ import { join } from 'node:path';
4
+ import { describe, expect, it } from 'vitest';
5
+ import { isProcessAlive, readPid, removePid, writePid } from '../pid.js';
6
+ describe('pid helpers', () => {
7
+ it('writes, reads, and removes the pid file in the current directory', () => {
8
+ const dir = mkdtempSync(join(tmpdir(), 'sena-pid-'));
9
+ const previousCwd = process.cwd();
10
+ process.chdir(dir);
11
+ try {
12
+ writePid(process.pid);
13
+ expect(readPid()).toBe(process.pid);
14
+ expect(isProcessAlive(process.pid)).toBe(true);
15
+ removePid();
16
+ expect(readPid()).toBeNull();
17
+ }
18
+ finally {
19
+ process.chdir(previousCwd);
20
+ }
21
+ });
22
+ });
23
+ //# sourceMappingURL=pid.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pid.test.js","sourceRoot":"","sources":["../../src/__tests__/pid.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACrC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAA;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAA;AAE7C,OAAO,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAA;AAExE,QAAQ,CAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,EAAE,CAAC,kEAAkE,EAAE,GAAG,EAAE;QAC1E,MAAM,GAAG,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,WAAW,CAAC,CAAC,CAAA;QACpD,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;QACjC,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAA;QAElB,IAAI,CAAC;YACH,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YACrB,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YACnC,MAAM,CAAC,cAAc,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YAE9C,SAAS,EAAE,CAAA;YACX,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE,CAAA;QAC9B,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,KAAK,CAAC,WAAW,CAAC,CAAA;QAC5B,CAAC;IACH,CAAC,CAAC,CAAA;AACJ,CAAC,CAAC,CAAA"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,27 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from 'commander';
3
+ import { readFileSync } from 'node:fs';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { dirname, resolve } from 'node:path';
6
+ import { registerStart } from './commands/start.js';
7
+ import { registerStop } from './commands/stop.js';
8
+ import { registerRestart } from './commands/restart.js';
9
+ import { registerStatus } from './commands/status.js';
10
+ import { registerLogs } from './commands/logs.js';
11
+ const __filename = fileURLToPath(import.meta.url);
12
+ const __dirname = dirname(__filename);
13
+ // Read version from package.json
14
+ const pkg = JSON.parse(readFileSync(resolve(__dirname, '..', 'package.json'), 'utf-8'));
15
+ const program = new Command();
16
+ program
17
+ .name('sena')
18
+ .description('Sena AI agent lifecycle manager')
19
+ .version(pkg.version)
20
+ .option('-c, --config <path>', 'path to sena.config.ts');
21
+ registerStart(program);
22
+ registerStop(program);
23
+ registerRestart(program);
24
+ registerStatus(program);
25
+ registerLogs(program);
26
+ program.parse();
27
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AACxC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAE5C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjD,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AACjD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAA;AAErC,iCAAiC;AACjC,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAwB,CAAA;AAE9G,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B,OAAO;KACJ,IAAI,CAAC,MAAM,CAAC;KACZ,WAAW,CAAC,iCAAiC,CAAC;KAC9C,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC;KACpB,MAAM,CAAC,qBAAqB,EAAE,wBAAwB,CAAC,CAAA;AAE1D,aAAa,CAAC,OAAO,CAAC,CAAA;AACtB,YAAY,CAAC,OAAO,CAAC,CAAA;AACrB,eAAe,CAAC,OAAO,CAAC,CAAA;AACxB,cAAc,CAAC,OAAO,CAAC,CAAA;AACvB,YAAY,CAAC,OAAO,CAAC,CAAA;AAErB,OAAO,CAAC,KAAK,EAAE,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerLogs(program: Command): void;
3
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKxC,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkCnD"}
@@ -0,0 +1,34 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { resolve } from 'node:path';
3
+ import { existsSync } from 'node:fs';
4
+ export function registerLogs(program) {
5
+ program
6
+ .command('logs')
7
+ .description('Show Sena agent logs')
8
+ .option('-f, --follow', 'follow log output (default: true)', true)
9
+ .option('--no-follow', 'do not follow log output')
10
+ .option('-n, --lines <n>', 'number of lines to show', '50')
11
+ .action((opts) => {
12
+ const logPath = resolve(process.cwd(), 'sena.log');
13
+ if (!existsSync(logPath)) {
14
+ console.log('No log file found (sena.log)');
15
+ return;
16
+ }
17
+ const args = ['-n', opts.lines];
18
+ if (opts.follow) {
19
+ args.push('-f');
20
+ }
21
+ args.push(logPath);
22
+ const tail = spawn('tail', args, {
23
+ stdio: ['ignore', 'inherit', 'inherit'],
24
+ });
25
+ process.on('SIGINT', () => {
26
+ tail.kill();
27
+ process.exit(0);
28
+ });
29
+ tail.on('exit', (code) => {
30
+ process.exit(code ?? 0);
31
+ });
32
+ });
33
+ }
34
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logs.js","sourceRoot":"","sources":["../../src/commands/logs.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAA;AAC1C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEpC,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,sBAAsB,CAAC;SACnC,MAAM,CAAC,cAAc,EAAE,mCAAmC,EAAE,IAAI,CAAC;SACjE,MAAM,CAAC,aAAa,EAAE,0BAA0B,CAAC;SACjD,MAAM,CAAC,iBAAiB,EAAE,yBAAyB,EAAE,IAAI,CAAC;SAC1D,MAAM,CAAC,CAAC,IAAwC,EAAE,EAAE;QACnD,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAA;QAElD,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAA;YAC3C,OAAM;QACR,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAA;QAC/B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;QACjB,CAAC;QACD,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;QAElB,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE;YAC/B,KAAK,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAC;SACxC,CAAC,CAAA;QAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;YACxB,IAAI,CAAC,IAAI,EAAE,CAAA;YACX,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC,CAAC,CAAA;QAEF,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;YACvB,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,CAAA;QACzB,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACN,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerRestart(program: Command): void;
3
+ //# sourceMappingURL=restart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restart.d.ts","sourceRoot":"","sources":["../../src/commands/restart.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAatD"}
@@ -0,0 +1,92 @@
1
+ import { readPid, isProcessAlive } from '../pid.js';
2
+ export function registerRestart(program) {
3
+ program
4
+ .command('restart')
5
+ .description('Restart the Sena agent')
6
+ .option('--full', 'full restart (stop + start in daemon mode)')
7
+ .option('-c, --config <path>', 'path to sena.config.ts')
8
+ .action(async (opts) => {
9
+ if (opts.full) {
10
+ await fullRestart(program, opts.config);
11
+ }
12
+ else {
13
+ await workerRestart();
14
+ }
15
+ });
16
+ }
17
+ async function workerRestart() {
18
+ const pid = readPid();
19
+ if (pid === null) {
20
+ console.error('No running sena process found');
21
+ process.exit(1);
22
+ }
23
+ if (!isProcessAlive(pid)) {
24
+ console.error(`Process (PID: ${pid}) is not running`);
25
+ process.exit(1);
26
+ }
27
+ process.kill(pid, 'SIGUSR2');
28
+ console.log('Worker restart triggered');
29
+ }
30
+ async function fullRestart(program, configPath) {
31
+ // Execute stop logic
32
+ const pid = readPid();
33
+ if (pid !== null && isProcessAlive(pid)) {
34
+ // Reuse stop logic inline
35
+ process.kill(pid, 'SIGTERM');
36
+ console.log(`Sent SIGTERM to process ${pid}, waiting for shutdown...`);
37
+ const maxWait = 10_000;
38
+ const interval = 100;
39
+ let waited = 0;
40
+ while (waited < maxWait) {
41
+ await new Promise((r) => setTimeout(r, interval));
42
+ waited += interval;
43
+ if (!isProcessAlive(pid))
44
+ break;
45
+ }
46
+ if (isProcessAlive(pid)) {
47
+ try {
48
+ process.kill(pid, 'SIGKILL');
49
+ }
50
+ catch {
51
+ // ignore
52
+ }
53
+ }
54
+ const { removePid } = await import('../pid.js');
55
+ removePid();
56
+ console.log('Previous instance stopped');
57
+ }
58
+ // Start in daemon mode
59
+ const { loadConfig } = await import('../config-loader.js');
60
+ const globalConfig = program.opts().config;
61
+ const resolvedConfigPath = configPath ?? globalConfig;
62
+ // Simulate daemon start by importing and calling
63
+ const { spawn } = await import('node:child_process');
64
+ const { openSync } = await import('node:fs');
65
+ const { resolve, dirname } = await import('node:path');
66
+ const { fileURLToPath } = await import('node:url');
67
+ const { writePid } = await import('../pid.js');
68
+ const __filename = fileURLToPath(import.meta.url);
69
+ const __dirname = dirname(__filename);
70
+ const { port, configPath: absConfigPath } = await loadConfig(resolvedConfigPath);
71
+ const cliPath = resolve(__dirname, '..', 'cli.js');
72
+ const logPath = resolve(process.cwd(), 'sena.log');
73
+ const logFd = openSync(logPath, 'a');
74
+ const args = ['start'];
75
+ if (absConfigPath) {
76
+ args.push('-c', absConfigPath);
77
+ }
78
+ const child = spawn(process.execPath, [cliPath, ...args], {
79
+ detached: true,
80
+ stdio: ['ignore', logFd, logFd],
81
+ env: { ...process.env, SENA_CONFIG_PATH: absConfigPath },
82
+ });
83
+ child.unref();
84
+ if (child.pid) {
85
+ console.log(`Full restart completed (new PID: ${child.pid}, port: ${port})`);
86
+ }
87
+ else {
88
+ console.error('Failed to start new process');
89
+ process.exit(1);
90
+ }
91
+ }
92
+ //# sourceMappingURL=restart.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"restart.js","sourceRoot":"","sources":["../../src/commands/restart.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerStart(program: Command): void;
3
+ //# sourceMappingURL=start.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.d.ts","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAWxC,wBAAgB,aAAa,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAuBpD"}
@@ -0,0 +1,91 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { openSync } from 'node:fs';
3
+ import { fileURLToPath } from 'node:url';
4
+ import { resolve, dirname } from 'node:path';
5
+ import { loadConfig } from '../config-loader.js';
6
+ import { writePid, removePid, readPid, isProcessAlive } from '../pid.js';
7
+ const __filename = fileURLToPath(import.meta.url);
8
+ const __dirname = dirname(__filename);
9
+ export function registerStart(program) {
10
+ program
11
+ .command('start')
12
+ .description('Start the Sena agent')
13
+ .option('-d, --daemon', 'run in background (daemon mode)')
14
+ .option('-c, --config <path>', 'path to sena.config.ts')
15
+ .action(async (opts) => {
16
+ ensureNoRunningProcess();
17
+ const configPath = opts.config ?? program.opts().config;
18
+ const { port, configPath: resolvedConfigPath, config } = await loadConfig(configPath);
19
+ // Set SENA_CONFIG_PATH so forked workers can find the config
20
+ process.env.SENA_CONFIG_PATH = resolvedConfigPath;
21
+ const agentName = config.name ?? 'default';
22
+ if (opts.daemon) {
23
+ await startDaemon(resolvedConfigPath, port, agentName);
24
+ }
25
+ else {
26
+ await startForeground(resolvedConfigPath, port, agentName);
27
+ }
28
+ });
29
+ }
30
+ function ensureNoRunningProcess() {
31
+ const pid = readPid();
32
+ if (pid === null) {
33
+ return;
34
+ }
35
+ if (!isProcessAlive(pid)) {
36
+ removePid();
37
+ return;
38
+ }
39
+ console.error(`Sena agent is already running (PID: ${pid})`);
40
+ process.exit(1);
41
+ }
42
+ async function startDaemon(configPath, port, agentName) {
43
+ const cliPath = resolve(__dirname, '..', 'cli.js');
44
+ const logPath = resolve(process.cwd(), 'sena.log');
45
+ const logFd = openSync(logPath, 'a');
46
+ // Build args: start (without -d), preserving config path if provided
47
+ const args = ['start'];
48
+ if (process.env.SENA_CONFIG_PATH) {
49
+ args.push('-c', process.env.SENA_CONFIG_PATH);
50
+ }
51
+ const child = spawn(process.execPath, [cliPath, ...args], {
52
+ detached: true,
53
+ stdio: ['ignore', logFd, logFd],
54
+ env: { ...process.env, SENA_CONFIG_PATH: configPath },
55
+ });
56
+ child.unref();
57
+ if (child.pid) {
58
+ console.log(`Sena agent '${agentName}' started in background (PID: ${child.pid}, port: ${port})`);
59
+ }
60
+ else {
61
+ console.error('Failed to start daemon process');
62
+ process.exit(1);
63
+ }
64
+ }
65
+ async function startForeground(configPath, port, agentName) {
66
+ const { createOrchestrator } = await import('@sena-ai/core');
67
+ // Worker entry path (relative to dist/)
68
+ const workerEntryPath = resolve(__dirname, '..', 'worker-entry.js');
69
+ const orchestrator = createOrchestrator({
70
+ port,
71
+ workerScript: workerEntryPath,
72
+ });
73
+ await orchestrator.start();
74
+ writePid(process.pid);
75
+ console.log(`Sena agent '${agentName}' started on port ${port}`);
76
+ // SIGUSR2 → graceful worker restart
77
+ process.on('SIGUSR2', () => {
78
+ console.log('Received SIGUSR2, restarting workers...');
79
+ void orchestrator.restart();
80
+ });
81
+ // SIGINT/SIGTERM → graceful shutdown
82
+ const shutdown = async () => {
83
+ console.log('Shutting down...');
84
+ await orchestrator.stop();
85
+ removePid();
86
+ process.exit(0);
87
+ };
88
+ process.on('SIGINT', () => void shutdown());
89
+ process.on('SIGTERM', () => void shutdown());
90
+ }
91
+ //# sourceMappingURL=start.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerStatus(program: Command): void;
3
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKxC,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkCrD"}
@@ -0,0 +1,58 @@
1
+ import { request } from 'node:http';
2
+ import { readPid, isProcessAlive, removePid } from '../pid.js';
3
+ import { loadConfig } from '../config-loader.js';
4
+ export function registerStatus(program) {
5
+ program
6
+ .command('status')
7
+ .description('Show the status of the Sena agent')
8
+ .option('-c, --config <path>', 'path to sena.config.ts')
9
+ .action(async (opts) => {
10
+ const pid = readPid();
11
+ if (pid === null || !isProcessAlive(pid)) {
12
+ if (pid !== null) {
13
+ removePid();
14
+ }
15
+ console.log('No running sena agent found');
16
+ return;
17
+ }
18
+ // Try to determine port from config / .env
19
+ let port;
20
+ try {
21
+ const configPath = opts.config ?? program.opts().config;
22
+ const result = await loadConfig(configPath);
23
+ port = result.port;
24
+ }
25
+ catch {
26
+ port = parseInt(process.env.SENA_PORT || '3100', 10);
27
+ }
28
+ // Health check
29
+ const healthy = await checkHealth(port);
30
+ if (healthy) {
31
+ console.log(`Sena agent running (PID: ${pid}, port: ${port})`);
32
+ }
33
+ else {
34
+ console.log(`Sena agent process alive (PID: ${pid}) but not responding on port ${port}`);
35
+ }
36
+ });
37
+ }
38
+ function checkHealth(port) {
39
+ return new Promise((resolve) => {
40
+ const req = request({
41
+ hostname: '127.0.0.1',
42
+ port,
43
+ path: '/health',
44
+ method: 'GET',
45
+ timeout: 3000,
46
+ }, (res) => {
47
+ resolve(res.statusCode === 200);
48
+ res.resume();
49
+ });
50
+ req.on('error', () => resolve(false));
51
+ req.on('timeout', () => {
52
+ req.destroy();
53
+ resolve(false);
54
+ });
55
+ req.end();
56
+ });
57
+ }
58
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAA;AAEhD,MAAM,UAAU,cAAc,CAAC,OAAgB;IAC7C,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,mCAAmC,CAAC;SAChD,MAAM,CAAC,qBAAqB,EAAE,wBAAwB,CAAC;SACvD,MAAM,CAAC,KAAK,EAAE,IAAyB,EAAE,EAAE;QAC1C,MAAM,GAAG,GAAG,OAAO,EAAE,CAAA;QAErB,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YACzC,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;gBACjB,SAAS,EAAE,CAAA;YACb,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAA;YAC1C,OAAM;QACR,CAAC;QAED,2CAA2C;QAC3C,IAAI,IAAY,CAAA;QAChB,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC,MAA4B,CAAA;YAC7E,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,UAAU,CAAC,CAAA;YAC3C,IAAI,GAAG,MAAM,CAAC,IAAI,CAAA;QACpB,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,EAAE,EAAE,CAAC,CAAA;QACtD,CAAC;QAED,eAAe;QACf,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,CAAA;QACvC,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,GAAG,CAAC,4BAA4B,GAAG,WAAW,IAAI,GAAG,CAAC,CAAA;QAChE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,kCAAkC,GAAG,gCAAgC,IAAI,EAAE,CAAC,CAAA;QAC1F,CAAC;IACH,CAAC,CAAC,CAAA;AACN,CAAC;AAED,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,GAAG,GAAG,OAAO,CACjB;YACE,QAAQ,EAAE,WAAW;YACrB,IAAI;YACJ,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,KAAK;YACb,OAAO,EAAE,IAAI;SACd,EACD,CAAC,GAAG,EAAE,EAAE;YACN,OAAO,CAAC,GAAG,CAAC,UAAU,KAAK,GAAG,CAAC,CAAA;YAC/B,GAAG,CAAC,MAAM,EAAE,CAAA;QACd,CAAC,CACF,CAAA;QAED,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;QACrC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;YACrB,GAAG,CAAC,OAAO,EAAE,CAAA;YACb,OAAO,CAAC,KAAK,CAAC,CAAA;QAChB,CAAC,CAAC,CAAA;QAEF,GAAG,CAAC,GAAG,EAAE,CAAA;IACX,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerStop(program: Command): void;
3
+ //# sourceMappingURL=stop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAgDnD"}
@@ -0,0 +1,45 @@
1
+ import { readPid, removePid, isProcessAlive } from '../pid.js';
2
+ export function registerStop(program) {
3
+ program
4
+ .command('stop')
5
+ .description('Stop the running Sena agent')
6
+ .action(async () => {
7
+ const pid = readPid();
8
+ if (pid === null) {
9
+ console.log('No running sena process found');
10
+ return;
11
+ }
12
+ if (!isProcessAlive(pid)) {
13
+ removePid();
14
+ console.log(`Process (PID: ${pid}) not running, cleaned up stale PID file`);
15
+ return;
16
+ }
17
+ // Send SIGTERM for graceful shutdown
18
+ process.kill(pid, 'SIGTERM');
19
+ console.log(`Sent SIGTERM to process ${pid}, waiting for shutdown...`);
20
+ // Wait up to 10 seconds
21
+ const maxWait = 10_000;
22
+ const interval = 100;
23
+ let waited = 0;
24
+ while (waited < maxWait) {
25
+ await new Promise((r) => setTimeout(r, interval));
26
+ waited += interval;
27
+ if (!isProcessAlive(pid)) {
28
+ removePid();
29
+ console.log('Sena agent stopped');
30
+ return;
31
+ }
32
+ }
33
+ // Force kill if still alive
34
+ console.log('Process did not stop gracefully, sending SIGKILL...');
35
+ try {
36
+ process.kill(pid, 'SIGKILL');
37
+ }
38
+ catch {
39
+ // Process may have exited between check and kill
40
+ }
41
+ removePid();
42
+ console.log('Sena agent stopped (forced)');
43
+ });
44
+ }
45
+ //# sourceMappingURL=stop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.js","sourceRoot":"","sources":["../../src/commands/stop.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,WAAW,CAAA;AAE9D,MAAM,UAAU,YAAY,CAAC,OAAgB;IAC3C,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,6BAA6B,CAAC;SAC1C,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,GAAG,GAAG,OAAO,EAAE,CAAA;QAErB,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;YACjB,OAAO,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAA;YAC5C,OAAM;QACR,CAAC;QAED,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,SAAS,EAAE,CAAA;YACX,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,0CAA0C,CAAC,CAAA;YAC3E,OAAM;QACR,CAAC;QAED,qCAAqC;QACrC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;QAC5B,OAAO,CAAC,GAAG,CAAC,2BAA2B,GAAG,2BAA2B,CAAC,CAAA;QAEtE,wBAAwB;QACxB,MAAM,OAAO,GAAG,MAAM,CAAA;QACtB,MAAM,QAAQ,GAAG,GAAG,CAAA;QACpB,IAAI,MAAM,GAAG,CAAC,CAAA;QAEd,OAAO,MAAM,GAAG,OAAO,EAAE,CAAC;YACxB,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAA;YACjD,MAAM,IAAI,QAAQ,CAAA;YAClB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzB,SAAS,EAAE,CAAA;gBACX,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAA;gBACjC,OAAM;YACR,CAAC;QACH,CAAC;QAED,4BAA4B;QAC5B,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAA;QAClE,IAAI,CAAC;YACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,CAAC,CAAA;QAC9B,CAAC;QAAC,MAAM,CAAC;YACP,iDAAiD;QACnD,CAAC;QAED,SAAS,EAAE,CAAA;QACX,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAA;IAC5C,CAAC,CAAC,CAAA;AACN,CAAC"}
@@ -0,0 +1,7 @@
1
+ export type LoadConfigResult = {
2
+ config: Record<string, unknown>;
3
+ port: number;
4
+ configPath: string;
5
+ };
6
+ export declare function loadConfig(configPath?: string): Promise<LoadConfigResult>;
7
+ //# sourceMappingURL=config-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.d.ts","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,gBAAgB,GAAG;IAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC/B,IAAI,EAAE,MAAM,CAAA;IACZ,UAAU,EAAE,MAAM,CAAA;CACnB,CAAA;AAyBD,wBAAsB,UAAU,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAoB/E"}
@@ -0,0 +1,41 @@
1
+ import { resolve } from 'node:path';
2
+ import dotenv from 'dotenv';
3
+ function unwrapConfigModule(mod) {
4
+ const first = (mod.default ?? mod);
5
+ return (first.default ?? first);
6
+ }
7
+ /**
8
+ * Dynamically import a TypeScript file using tsx's tsImport API.
9
+ * Falls back to plain dynamic import for non-TS files or if tsx is unavailable.
10
+ */
11
+ async function importTs(filePath) {
12
+ if (filePath.endsWith('.ts') || filePath.endsWith('.tsx')) {
13
+ try {
14
+ const { tsImport } = await import('tsx/esm/api');
15
+ const mod = await tsImport(filePath, import.meta.url);
16
+ return unwrapConfigModule(mod);
17
+ }
18
+ catch {
19
+ // Fall back to plain import (works if tsx is active via --import flag)
20
+ }
21
+ }
22
+ const mod = await import(filePath);
23
+ return unwrapConfigModule(mod);
24
+ }
25
+ export async function loadConfig(configPath) {
26
+ const cwd = process.cwd();
27
+ // 1. Load .env
28
+ dotenv.config({ path: resolve(cwd, '.env'), override: true });
29
+ // 2. Resolve config path
30
+ const resolvedConfigPath = configPath
31
+ ? resolve(cwd, configPath)
32
+ : resolve(cwd, 'sena.config.ts');
33
+ // 3. Dynamic import of user config (using tsx tsImport for .ts files)
34
+ const config = await importTs(resolvedConfigPath);
35
+ // 4. Resolve port
36
+ const orchestrator = config.orchestrator;
37
+ const port = orchestrator?.port
38
+ ?? parseInt(process.env.SENA_PORT || '3100', 10);
39
+ return { config, port, configPath: resolvedConfigPath };
40
+ }
41
+ //# sourceMappingURL=config-loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-loader.js","sourceRoot":"","sources":["../src/config-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,MAAM,MAAM,QAAQ,CAAA;AAQ3B,SAAS,kBAAkB,CAAC,GAA4B;IACtD,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,GAAG,CAA4B,CAAA;IAC7D,OAAO,CAAC,KAAK,CAAC,OAAO,IAAI,KAAK,CAA4B,CAAA;AAC5D,CAAC;AAED;;;GAGG;AACH,KAAK,UAAU,QAAQ,CAAC,QAAgB;IACtC,IAAI,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QAC1D,IAAI,CAAC;YACH,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAA;YAChD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAA4B,CAAA;YAChF,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAA;QAChC,CAAC;QAAC,MAAM,CAAC;YACP,uEAAuE;QACzE,CAAC;IACH,CAAC;IACD,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,QAAQ,CAA4B,CAAA;IAC7D,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAA;AAChC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,UAAmB;IAClD,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAA;IAEzB,eAAe;IACf,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAA;IAE7D,yBAAyB;IACzB,MAAM,kBAAkB,GAAG,UAAU;QACnC,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC;QAC1B,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,gBAAgB,CAAC,CAAA;IAElC,sEAAsE;IACtE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,kBAAkB,CAAC,CAAA;IAEjD,kBAAkB;IAClB,MAAM,YAAY,GAAG,MAAM,CAAC,YAA6C,CAAA;IACzE,MAAM,IAAI,GAAG,YAAY,EAAE,IAAI;WAC1B,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,MAAM,EAAE,EAAE,CAAC,CAAA;IAElD,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,EAAE,kBAAkB,EAAE,CAAA;AACzD,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { loadConfig } from './config-loader.js';
2
+ export type { LoadConfigResult } from './config-loader.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { loadConfig } from './config-loader.js';
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA"}
package/dist/pid.d.ts ADDED
@@ -0,0 +1,5 @@
1
+ export declare function writePid(pid: number): void;
2
+ export declare function readPid(): number | null;
3
+ export declare function removePid(): void;
4
+ export declare function isProcessAlive(pid: number): boolean;
5
+ //# sourceMappingURL=pid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pid.d.ts","sourceRoot":"","sources":["../src/pid.ts"],"names":[],"mappings":"AAKA,wBAAgB,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAE1C;AAED,wBAAgB,OAAO,IAAI,MAAM,GAAG,IAAI,CAQvC;AAED,wBAAgB,SAAS,IAAI,IAAI,CAMhC;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAOnD"}
package/dist/pid.js ADDED
@@ -0,0 +1,34 @@
1
+ import { resolve } from 'node:path';
2
+ import { writeFileSync, readFileSync, unlinkSync } from 'node:fs';
3
+ const PID_FILE = () => resolve(process.cwd(), '.sena.pid');
4
+ export function writePid(pid) {
5
+ writeFileSync(PID_FILE(), String(pid), 'utf-8');
6
+ }
7
+ export function readPid() {
8
+ try {
9
+ const content = readFileSync(PID_FILE(), 'utf-8').trim();
10
+ const pid = parseInt(content, 10);
11
+ return Number.isNaN(pid) ? null : pid;
12
+ }
13
+ catch {
14
+ return null;
15
+ }
16
+ }
17
+ export function removePid() {
18
+ try {
19
+ unlinkSync(PID_FILE());
20
+ }
21
+ catch {
22
+ // Ignore if file doesn't exist
23
+ }
24
+ }
25
+ export function isProcessAlive(pid) {
26
+ try {
27
+ process.kill(pid, 0);
28
+ return true;
29
+ }
30
+ catch {
31
+ return false;
32
+ }
33
+ }
34
+ //# sourceMappingURL=pid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pid.js","sourceRoot":"","sources":["../src/pid.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEjE,MAAM,QAAQ,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,WAAW,CAAC,CAAA;AAE1D,MAAM,UAAU,QAAQ,CAAC,GAAW;IAClC,aAAa,CAAC,QAAQ,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAA;AACjD,CAAC;AAED,MAAM,UAAU,OAAO;IACrB,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAA;QACxD,MAAM,GAAG,GAAG,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAA;QACjC,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAA;IACvC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAA;IACb,CAAC;AACH,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,IAAI,CAAC;QACH,UAAU,CAAC,QAAQ,EAAE,CAAC,CAAA;IACxB,CAAC;IAAC,MAAM,CAAC;QACP,+BAA+B;IACjC,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,IAAI,CAAC;QACH,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;QACpB,OAAO,IAAI,CAAA;IACb,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC"}
@@ -0,0 +1,2 @@
1
+ import 'dotenv/config';
2
+ //# sourceMappingURL=worker-entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-entry.d.ts","sourceRoot":"","sources":["../src/worker-entry.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA"}
@@ -0,0 +1,22 @@
1
+ import 'dotenv/config';
2
+ import { createWorker } from '@sena-ai/core';
3
+ const configPath = process.env.SENA_CONFIG_PATH;
4
+ if (!configPath) {
5
+ console.error('SENA_CONFIG_PATH environment variable is required');
6
+ process.exit(1);
7
+ }
8
+ // Use tsx tsImport for .ts config files (plain import won't work from compiled .js)
9
+ let config;
10
+ if (configPath.endsWith('.ts') || configPath.endsWith('.tsx')) {
11
+ const { tsImport } = await import('tsx/esm/api');
12
+ const mod = await tsImport(configPath, import.meta.url);
13
+ config = mod.default;
14
+ }
15
+ else {
16
+ const mod = await import(configPath);
17
+ config = mod.default;
18
+ }
19
+ const port = parseInt(process.env.SENA_WORKER_PORT || '0', 10);
20
+ const worker = createWorker({ config, port });
21
+ worker.start();
22
+ //# sourceMappingURL=worker-entry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"worker-entry.js","sourceRoot":"","sources":["../src/worker-entry.ts"],"names":[],"mappings":"AAAA,OAAO,eAAe,CAAA;AACtB,OAAO,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AAE5C,MAAM,UAAU,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAA;AAC/C,IAAI,CAAC,UAAU,EAAE,CAAC;IAChB,OAAO,CAAC,KAAK,CAAC,mDAAmD,CAAC,CAAA;IAClE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC;AAED,oFAAoF;AACpF,IAAI,MAAoD,CAAA;AACxD,IAAI,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;IAC9D,MAAM,EAAE,QAAQ,EAAE,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAA;IAChD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAA+B,CAAA;IACrF,MAAM,GAAG,GAAG,CAAC,OAAO,CAAA;AACtB,CAAC;KAAM,CAAC;IACN,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAA+B,CAAA;IAClE,MAAM,GAAG,GAAG,CAAC,OAAO,CAAA;AACtB,CAAC;AAED,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,GAAG,EAAE,EAAE,CAAC,CAAA;AAE9D,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;AAC7C,MAAM,CAAC,KAAK,EAAE,CAAA"}
package/package.json ADDED
@@ -0,0 +1,31 @@
1
+ {
2
+ "name": "@sena-ai/cli",
3
+ "version": "0.0.15",
4
+ "type": "module",
5
+ "bin": {
6
+ "sena": "./dist/cli.js"
7
+ },
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js",
12
+ "default": "./dist/index.js"
13
+ }
14
+ },
15
+ "files": [
16
+ "dist"
17
+ ],
18
+ "scripts": {
19
+ "build": "tsc -b"
20
+ },
21
+ "dependencies": {
22
+ "tsx": "^4.21.0",
23
+ "commander": "^13",
24
+ "dotenv": "^16.6",
25
+ "@sena-ai/core": "workspace:*"
26
+ },
27
+ "devDependencies": {
28
+ "@types/node": "^25.5.0",
29
+ "typescript": "^5.8.0"
30
+ }
31
+ }