@taskcast/cli 1.2.0 → 1.3.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 (75) hide show
  1. package/dist/client.d.ts +15 -0
  2. package/dist/client.d.ts.map +1 -0
  3. package/dist/client.js +47 -0
  4. package/dist/client.js.map +1 -0
  5. package/dist/commands/doctor.d.ts +23 -0
  6. package/dist/commands/doctor.d.ts.map +1 -0
  7. package/dist/commands/doctor.js +95 -0
  8. package/dist/commands/doctor.js.map +1 -0
  9. package/dist/commands/logs.d.ts +11 -0
  10. package/dist/commands/logs.d.ts.map +1 -0
  11. package/dist/commands/logs.js +171 -0
  12. package/dist/commands/logs.js.map +1 -0
  13. package/dist/commands/migrate.d.ts +3 -0
  14. package/dist/commands/migrate.d.ts.map +1 -0
  15. package/dist/commands/migrate.js +84 -0
  16. package/dist/commands/migrate.js.map +1 -0
  17. package/dist/commands/node.d.ts +5 -0
  18. package/dist/commands/node.d.ts.map +1 -0
  19. package/dist/commands/node.js +57 -0
  20. package/dist/commands/node.js.map +1 -0
  21. package/dist/commands/ping.d.ts +9 -0
  22. package/dist/commands/ping.d.ts.map +1 -0
  23. package/dist/commands/ping.js +43 -0
  24. package/dist/commands/ping.js.map +1 -0
  25. package/dist/commands/playground.d.ts +3 -0
  26. package/dist/commands/playground.d.ts.map +1 -0
  27. package/dist/commands/playground.js +37 -0
  28. package/dist/commands/playground.js.map +1 -0
  29. package/dist/commands/service.d.ts +8 -0
  30. package/dist/commands/service.d.ts.map +1 -0
  31. package/dist/commands/service.js +237 -0
  32. package/dist/commands/service.js.map +1 -0
  33. package/dist/commands/start.d.ts +3 -0
  34. package/dist/commands/start.d.ts.map +1 -0
  35. package/dist/commands/start.js +145 -0
  36. package/dist/commands/start.js.map +1 -0
  37. package/dist/commands/tasks.d.ts +11 -0
  38. package/dist/commands/tasks.d.ts.map +1 -0
  39. package/dist/commands/tasks.js +129 -0
  40. package/dist/commands/tasks.js.map +1 -0
  41. package/dist/commands/ui.d.ts +3 -0
  42. package/dist/commands/ui.d.ts.map +1 -0
  43. package/dist/commands/ui.js +103 -0
  44. package/dist/commands/ui.js.map +1 -0
  45. package/dist/index.js +41 -413
  46. package/dist/index.js.map +1 -1
  47. package/dist/node-config.d.ts +22 -0
  48. package/dist/node-config.d.ts.map +1 -0
  49. package/dist/node-config.js +71 -0
  50. package/dist/node-config.js.map +1 -0
  51. package/dist/service/interface.d.ts +26 -0
  52. package/dist/service/interface.d.ts.map +1 -0
  53. package/dist/service/interface.js +3 -0
  54. package/dist/service/interface.js.map +1 -0
  55. package/dist/service/launchd.d.ts +11 -0
  56. package/dist/service/launchd.d.ts.map +1 -0
  57. package/dist/service/launchd.js +97 -0
  58. package/dist/service/launchd.js.map +1 -0
  59. package/dist/service/paths.d.ts +12 -0
  60. package/dist/service/paths.d.ts.map +1 -0
  61. package/dist/service/paths.js +35 -0
  62. package/dist/service/paths.js.map +1 -0
  63. package/dist/service/resolve.d.ts +3 -0
  64. package/dist/service/resolve.d.ts.map +1 -0
  65. package/dist/service/resolve.js +10 -0
  66. package/dist/service/resolve.js.map +1 -0
  67. package/dist/service/systemd.d.ts +11 -0
  68. package/dist/service/systemd.d.ts.map +1 -0
  69. package/dist/service/systemd.js +86 -0
  70. package/dist/service/systemd.js.map +1 -0
  71. package/dist/utils.d.ts +5 -0
  72. package/dist/utils.d.ts.map +1 -0
  73. package/dist/utils.js +65 -0
  74. package/dist/utils.js.map +1 -0
  75. package/package.json +9 -8
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ping.js","sourceRoot":"","sources":["../../src/commands/ping.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAA;AAQrD,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW,EAAE,UAAwB,KAAK;IACzE,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IACxB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,GAAG,GAAG,SAAS,CAAC,CAAA;QAC1C,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAA;QACpC,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,GAAG,CAAC,MAAM,EAAE,EAAE,CAAA;QAC9D,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAA;IACrD,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,yCAAyC,CAAC;SACtD,MAAM,CAAC,eAAe,EAAE,oBAAoB,CAAC;SAC7C,MAAM,CAAC,KAAK,EAAE,IAAuB,EAAE,EAAE;QACxC,MAAM,GAAG,GAAG,IAAI,iBAAiB,EAAE,CAAA;QACnC,IAAI,IAAI,CAAA;QACR,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YACd,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACzB,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,IAAI,aAAa,CAAC,CAAA;gBAC9C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,GAAG,CAAC,UAAU,EAAE,CAAA;QACzB,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;QACzC,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;YACd,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,GAAG,KAAK,MAAM,CAAC,SAAS,KAAK,CAAC,CAAA;QACrE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,KAAK,CAAC,uBAAuB,IAAI,CAAC,GAAG,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,CAAA;YACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerPlaygroundCommand(program: Command): void;
3
+ //# sourceMappingURL=playground.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playground.d.ts","sourceRoot":"","sources":["../../src/commands/playground.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKnC,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA+BhE"}
@@ -0,0 +1,37 @@
1
+ import { existsSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import { createRequire } from 'module';
4
+ export function registerPlaygroundCommand(program) {
5
+ program
6
+ .command('playground')
7
+ .description('Serve only the playground UI (no engine)')
8
+ .option('-p, --port <port>', 'port to listen on', '5173')
9
+ .action(async (options) => {
10
+ const port = Number(options.port);
11
+ try {
12
+ const require = createRequire(import.meta.url);
13
+ const pkgPath = require.resolve('@taskcast/playground/package.json');
14
+ const distDir = join(dirname(pkgPath), 'dist');
15
+ if (!existsSync(distDir)) {
16
+ console.error('[taskcast] Playground dist not found. Run `pnpm --filter @taskcast/playground build` first.');
17
+ process.exit(1);
18
+ }
19
+ const { OpenAPIHono } = await import('@hono/zod-openapi');
20
+ const app = new OpenAPIHono();
21
+ const { serveStatic } = await import('@hono/node-server/serve-static');
22
+ app.use('/_playground/*', serveStatic({ root: distDir, rewriteRequestPath: (p) => p.replace(/^\/_playground/, '') }));
23
+ app.get('/_playground/*', serveStatic({ root: distDir, rewriteRequestPath: () => '/index.html' }));
24
+ app.get('/', (c) => c.redirect('/_playground/'));
25
+ const { serve } = await import('@hono/node-server');
26
+ serve({ fetch: app.fetch, port }, () => {
27
+ console.log(`[taskcast] Playground UI at http://localhost:${port}/_playground/`);
28
+ console.log('[taskcast] Use "External" mode in the UI to connect to a remote server.');
29
+ });
30
+ }
31
+ catch {
32
+ console.error('[taskcast] @taskcast/playground not available.');
33
+ process.exit(1);
34
+ }
35
+ });
36
+ }
37
+ //# sourceMappingURL=playground.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playground.js","sourceRoot":"","sources":["../../src/commands/playground.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAA;AAC/B,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACpC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AAEtC,MAAM,UAAU,yBAAyB,CAAC,OAAgB;IACxD,OAAO;SACJ,OAAO,CAAC,YAAY,CAAC;SACrB,WAAW,CAAC,0CAA0C,CAAC;SACvD,MAAM,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,CAAC;SACxD,MAAM,CAAC,KAAK,EAAE,OAAyB,EAAE,EAAE;QAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QACjC,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;YAC9C,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,mCAAmC,CAAC,CAAA;YACpE,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAA;YAC9C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBACzB,OAAO,CAAC,KAAK,CAAC,6FAA6F,CAAC,CAAA;gBAC5G,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACjB,CAAC;YACD,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAA;YACzD,MAAM,GAAG,GAAG,IAAI,WAAW,EAAE,CAAA;YAC7B,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,gCAAgC,CAAC,CAAA;YACtE,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,kBAAkB,EAAE,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,gBAAgB,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;YAC7H,GAAG,CAAC,GAAG,CAAC,gBAAgB,EAAE,WAAW,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,kBAAkB,EAAE,GAAG,EAAE,CAAC,aAAa,EAAE,CAAC,CAAC,CAAA;YAClG,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAA0C,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAA;YACzF,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,mBAAmB,CAAC,CAAA;YACnD,KAAK,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE;gBACrC,OAAO,CAAC,GAAG,CAAC,gDAAgD,IAAI,eAAe,CAAC,CAAA;gBAChF,OAAO,CAAC,GAAG,CAAC,yEAAyE,CAAC,CAAA;YACxF,CAAC,CAAC,CAAA;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAA;YAC/D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;IACH,CAAC,CAAC,CAAA;AACN,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { Command } from 'commander';
2
+ export declare function runServiceStart(_healthTimeoutMs?: number): Promise<void>;
3
+ export declare function runServiceStop(): Promise<void>;
4
+ export declare function runServiceStatus(): Promise<void>;
5
+ export declare function runServiceRestart(_healthTimeoutMs?: number): Promise<void>;
6
+ export declare function registerServiceCommand(program: Command): void;
7
+ export declare function pollHealth(port: number, timeoutMs?: number): Promise<boolean>;
8
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/commands/service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAkDnC,wBAAsB,eAAe,CAAC,gBAAgB,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAqB5E;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CASpD;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,IAAI,CAAC,CA6BtD;AAGD,wBAAsB,iBAAiB,CAAC,gBAAgB,SAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB9E;AAED,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmF7D;AAqBD,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,SAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAcjF"}
@@ -0,0 +1,237 @@
1
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs';
2
+ import { dirname } from 'path';
3
+ import { createServiceManager } from '../service/resolve.js';
4
+ import { getServicePaths } from '../service/paths.js';
5
+ function resolveNodePath() {
6
+ return process.execPath;
7
+ }
8
+ // Note: resolveEntryPoint uses import.meta.url which cannot be mocked in Vitest ESM tests.
9
+ // The entryPoint value is verified structurally (mockInstall called) but not by exact path.
10
+ /* v8 ignore next 3 */
11
+ function resolveEntryPoint() {
12
+ return new URL('../index.js', import.meta.url).pathname;
13
+ }
14
+ function ensureConfigFile(paths, configOpt) {
15
+ if (configOpt)
16
+ return configOpt;
17
+ // Check if any config already exists
18
+ if (existsSync(paths.defaultConfigPath)) {
19
+ return paths.defaultConfigPath;
20
+ }
21
+ // Create default config with SQLite
22
+ const dir = dirname(paths.defaultConfigPath);
23
+ mkdirSync(dir, { recursive: true });
24
+ const dbPath = paths.defaultDbPath;
25
+ const content = `# Taskcast service configuration
26
+ port: 3721
27
+
28
+ adapters:
29
+ shortTermStore:
30
+ provider: sqlite
31
+ path: ${dbPath}
32
+ longTermStore:
33
+ provider: sqlite
34
+ path: ${dbPath}
35
+ `;
36
+ writeFileSync(paths.defaultConfigPath, content);
37
+ console.log(`[taskcast] Created default config at ${paths.defaultConfigPath}`);
38
+ return paths.defaultConfigPath;
39
+ }
40
+ // Exported action functions — used directly by alias commands in index.ts
41
+ // _healthTimeoutMs is injectable for testing (default 5000ms)
42
+ export async function runServiceStart(_healthTimeoutMs = 5000) {
43
+ const mgr = createServiceManager();
44
+ const st = await mgr.status();
45
+ if (st.state === 'running') {
46
+ console.log('[taskcast] Service is already running.');
47
+ return;
48
+ }
49
+ await mgr.start();
50
+ const paths = getServicePaths();
51
+ const port = await getPortFromConfig();
52
+ const started = await pollHealth(port, _healthTimeoutMs);
53
+ if (started) {
54
+ console.log(`[taskcast] Service started on http://localhost:${port}`);
55
+ }
56
+ else {
57
+ console.error('[taskcast] Service may have failed to start. Check logs:');
58
+ if (paths.stdoutLog) {
59
+ console.error(` ${paths.stdoutLog}`);
60
+ }
61
+ else {
62
+ console.error(' journalctl --user -u taskcast');
63
+ }
64
+ }
65
+ }
66
+ export async function runServiceStop() {
67
+ const mgr = createServiceManager();
68
+ const st = await mgr.status();
69
+ if (st.state !== 'running') {
70
+ console.log('[taskcast] Service is not running.');
71
+ return;
72
+ }
73
+ await mgr.stop();
74
+ console.log('[taskcast] Service stopped.');
75
+ }
76
+ export async function runServiceStatus() {
77
+ const mgr = createServiceManager();
78
+ const st = await mgr.status();
79
+ if (st.state === 'not-installed') {
80
+ console.log('Service: not installed');
81
+ return;
82
+ }
83
+ if (st.state === 'stopped') {
84
+ console.log('Service: stopped');
85
+ return;
86
+ }
87
+ console.log(`Service: running (pid ${st.pid})`);
88
+ try {
89
+ const port = await getPortFromConfig();
90
+ const res = await fetch(`http://localhost:${port}/health/detail`);
91
+ if (res.ok) {
92
+ const body = await res.json();
93
+ if (body.uptime != null) {
94
+ const h = Math.floor(body.uptime / 3600);
95
+ const m = Math.floor((body.uptime % 3600) / 60);
96
+ console.log(`Uptime: ${h}h ${m}m`);
97
+ }
98
+ if (body.adapters?.shortTermStore) {
99
+ console.log(`Storage: ${body.adapters.shortTermStore.provider}`);
100
+ }
101
+ }
102
+ }
103
+ catch {
104
+ // Health endpoint not reachable — just show basic status
105
+ }
106
+ }
107
+ // _healthTimeoutMs is injectable for testing (default 5000ms)
108
+ export async function runServiceRestart(_healthTimeoutMs = 5000) {
109
+ const mgr = createServiceManager();
110
+ await mgr.restart();
111
+ const paths = getServicePaths();
112
+ const port = await getPortFromConfig();
113
+ const started = await pollHealth(port, _healthTimeoutMs);
114
+ if (started) {
115
+ console.log(`[taskcast] Service restarted on http://localhost:${port}`);
116
+ }
117
+ else {
118
+ console.error('[taskcast] Service may have failed to restart. Check logs:');
119
+ if (paths.stdoutLog) {
120
+ console.error(` ${paths.stdoutLog}`);
121
+ }
122
+ else {
123
+ console.error(' journalctl --user -u taskcast');
124
+ }
125
+ }
126
+ }
127
+ export function registerServiceCommand(program) {
128
+ const service = program
129
+ .command('service')
130
+ .description('Manage Taskcast as a system service');
131
+ service
132
+ .command('install')
133
+ .description('Register Taskcast as a system service with auto-start on boot')
134
+ .option('-c, --config <path>', 'config file path')
135
+ .option('-p, --port <port>', 'port to listen on', '3721')
136
+ .option('-s, --storage <type>', 'storage backend: memory | redis | sqlite')
137
+ .option('--db-path <path>', 'SQLite database file path')
138
+ .action(async (opts) => {
139
+ const port = Number(opts.port);
140
+ if (!Number.isFinite(port) || port < 1 || port > 65535 || port !== Math.floor(port)) {
141
+ console.error(`[taskcast] Invalid port: ${opts.port}`);
142
+ process.exit(1);
143
+ }
144
+ const mgr = createServiceManager();
145
+ const paths = getServicePaths();
146
+ const configPath = ensureConfigFile(paths, opts.config);
147
+ // When using auto-generated config (SQLite default) and user didn't
148
+ // explicitly set --storage, ensure the service starts with sqlite.
149
+ const autoSqlite = !opts.config && !opts.storage;
150
+ const storage = opts.storage ?? (autoSqlite ? 'sqlite' : undefined);
151
+ const dbPath = opts.dbPath ?? (autoSqlite ? paths.defaultDbPath : undefined);
152
+ const installOpts = {
153
+ port,
154
+ config: configPath,
155
+ nodePath: resolveNodePath(),
156
+ entryPoint: resolveEntryPoint(),
157
+ ...(storage !== undefined ? { storage } : {}),
158
+ ...(dbPath !== undefined ? { dbPath } : {}),
159
+ };
160
+ await mgr.install(installOpts);
161
+ // Write state file with the installed port so start/restart poll the right port
162
+ const statePath = paths.serviceStatePath;
163
+ mkdirSync(dirname(statePath), { recursive: true });
164
+ writeFileSync(statePath, JSON.stringify({ port }));
165
+ console.log('[taskcast] Service installed successfully.');
166
+ console.log('[taskcast] Run `taskcast service start` to start the service.');
167
+ });
168
+ service
169
+ .command('uninstall')
170
+ .description('Remove Taskcast system service registration')
171
+ .action(async () => {
172
+ const mgr = createServiceManager();
173
+ await mgr.uninstall();
174
+ console.log('[taskcast] Service uninstalled successfully.');
175
+ });
176
+ service
177
+ .command('start')
178
+ .description('Start Taskcast via system service manager')
179
+ .action(() => runServiceStart());
180
+ service
181
+ .command('stop')
182
+ .description('Stop Taskcast system service')
183
+ .action(() => runServiceStop());
184
+ service
185
+ .command('restart')
186
+ .description('Restart Taskcast system service')
187
+ .action(() => runServiceRestart());
188
+ service
189
+ .command('reload')
190
+ .description('Restart Taskcast system service (alias for restart)')
191
+ .action(() => runServiceRestart());
192
+ service
193
+ .command('status')
194
+ .description('Show Taskcast service status')
195
+ .action(runServiceStatus);
196
+ }
197
+ async function getPortFromConfig() {
198
+ try {
199
+ const paths = getServicePaths();
200
+ // Try state file first (written by install, has the exact installed port)
201
+ try {
202
+ const state = JSON.parse(readFileSync(paths.serviceStatePath, 'utf8'));
203
+ if (typeof state.port === 'number')
204
+ return state.port;
205
+ }
206
+ catch {
207
+ // State file not present — fall through to config file
208
+ }
209
+ const text = readFileSync(paths.defaultConfigPath, 'utf8');
210
+ const match = text.match(/^port:\s*(\d+)/m);
211
+ if (match)
212
+ return Number(match[1]);
213
+ }
214
+ catch {
215
+ // Config not readable — use default
216
+ }
217
+ return 3721;
218
+ }
219
+ export async function pollHealth(port, timeoutMs = 5000) {
220
+ const start = Date.now();
221
+ while (Date.now() - start < timeoutMs) {
222
+ try {
223
+ const res = await fetch(`http://localhost:${port}/health`);
224
+ if (res.ok)
225
+ return true;
226
+ }
227
+ catch {
228
+ // Not ready yet
229
+ }
230
+ const remaining = timeoutMs - (Date.now() - start);
231
+ if (remaining <= 0)
232
+ break;
233
+ await new Promise(r => setTimeout(r, Math.min(500, remaining)));
234
+ }
235
+ return false;
236
+ }
237
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/commands/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function registerStartCommand(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,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAqBnC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA4I3D"}
@@ -0,0 +1,145 @@
1
+ import { Redis } from 'ioredis';
2
+ import postgres from 'postgres';
3
+ import { existsSync } from 'fs';
4
+ import { join, dirname } from 'path';
5
+ import { createRequire } from 'module';
6
+ import { TaskEngine, WorkerManager, loadConfigFile, resolveAdminToken, MemoryBroadcastProvider, MemoryShortTermStore, } from '@taskcast/core';
7
+ import { createTaskcastApp } from '@taskcast/server';
8
+ import { createRedisAdapters } from '@taskcast/redis';
9
+ import { PostgresLongTermStore } from '@taskcast/postgres';
10
+ import { createSqliteAdapters } from '@taskcast/sqlite';
11
+ import { promptCreateGlobalConfig, createDefaultGlobalConfig } from '../utils.js';
12
+ export function registerStartCommand(program) {
13
+ program
14
+ .command('start', { isDefault: true })
15
+ .description('Start the taskcast server in foreground (default)')
16
+ .option('-c, --config <path>', 'config file path')
17
+ .option('-p, --port <port>', 'port to listen on', '3721')
18
+ .option('-s, --storage <type>', 'storage backend: memory | redis | sqlite', 'memory')
19
+ .option('--db-path <path>', 'SQLite database file path (default: ./taskcast.db)')
20
+ .option('--playground', 'serve the interactive playground UI at /_playground/')
21
+ .option('-v, --verbose', 'enable verbose logging')
22
+ .action(async (options) => {
23
+ let { config: fileConfig, source, path: configPath } = await loadConfigFile(options.config);
24
+ if (source === 'none') {
25
+ const shouldCreate = await promptCreateGlobalConfig();
26
+ if (shouldCreate) {
27
+ const createdPath = createDefaultGlobalConfig();
28
+ if (createdPath) {
29
+ const created = await loadConfigFile(createdPath);
30
+ fileConfig = created.config;
31
+ source = created.source;
32
+ configPath = created.path;
33
+ }
34
+ }
35
+ }
36
+ const port = Number(options.port ?? fileConfig.port ?? 3721);
37
+ const redisUrl = process.env['TASKCAST_REDIS_URL'] ?? fileConfig.adapters?.broadcast?.url;
38
+ const postgresUrl = process.env['TASKCAST_POSTGRES_URL'] ?? fileConfig.adapters?.longTermStore?.url;
39
+ let shortTermStore;
40
+ let broadcast;
41
+ let longTermStore;
42
+ const storage = options.storage ?? process.env['TASKCAST_STORAGE'] ?? (redisUrl ? 'redis' : 'memory');
43
+ let shortTermLabel;
44
+ let longTermLabel;
45
+ if (storage === 'sqlite') {
46
+ const dbPath = options.dbPath ?? './taskcast.db';
47
+ const sqliteOpts = options.dbPath ? { path: options.dbPath } : {};
48
+ const adapters = createSqliteAdapters(sqliteOpts);
49
+ broadcast = new MemoryBroadcastProvider();
50
+ shortTermStore = adapters.shortTermStore;
51
+ longTermStore = adapters.longTermStore;
52
+ shortTermLabel = `sqlite @ ${dbPath}`;
53
+ longTermLabel = `sqlite @ ${dbPath}`;
54
+ }
55
+ else if (storage === 'redis' || redisUrl) {
56
+ const pubClient = new Redis(redisUrl);
57
+ const subClient = new Redis(redisUrl);
58
+ const storeClient = new Redis(redisUrl);
59
+ const adapters = createRedisAdapters(pubClient, subClient, storeClient);
60
+ broadcast = adapters.broadcast;
61
+ shortTermStore = adapters.shortTermStore;
62
+ shortTermLabel = `redis @ ${redisUrl}`;
63
+ longTermLabel = '(none)';
64
+ }
65
+ else {
66
+ broadcast = new MemoryBroadcastProvider();
67
+ shortTermStore = new MemoryShortTermStore();
68
+ shortTermLabel = 'memory';
69
+ longTermLabel = '(none)';
70
+ }
71
+ if (storage !== 'sqlite' && postgresUrl) {
72
+ const sql = postgres(postgresUrl);
73
+ longTermStore = new PostgresLongTermStore(sql);
74
+ longTermLabel = `postgres @ ${postgresUrl}`;
75
+ }
76
+ // Print startup configuration summary
77
+ console.log(`[taskcast] Config: ${configPath ?? '(none)'}`);
78
+ console.log(`[taskcast] Short-term store: ${shortTermLabel}`);
79
+ console.log(`[taskcast] Long-term store: ${longTermLabel}`);
80
+ const engineOpts = { shortTermStore, broadcast };
81
+ if (longTermStore !== undefined)
82
+ engineOpts.longTermStore = longTermStore;
83
+ const engine = new TaskEngine(engineOpts);
84
+ const authMode = (process.env['TASKCAST_AUTH_MODE'] ?? fileConfig.auth?.mode ?? 'none');
85
+ // Worker assignment system
86
+ const workersEnabled = fileConfig.workers?.enabled ?? false;
87
+ let workerManager;
88
+ if (workersEnabled) {
89
+ console.log('[taskcast] Worker assignment system enabled');
90
+ const wmOpts = {
91
+ engine,
92
+ shortTermStore,
93
+ broadcast,
94
+ };
95
+ if (longTermStore !== undefined)
96
+ wmOpts.longTermStore = longTermStore;
97
+ if (fileConfig.workers?.defaults)
98
+ wmOpts.defaults = fileConfig.workers.defaults;
99
+ workerManager = new WorkerManager(wmOpts);
100
+ }
101
+ // Resolve admin token (auto-generate + print if adminApi is enabled)
102
+ resolveAdminToken(fileConfig);
103
+ const serverOpts = {
104
+ engine,
105
+ shortTermStore,
106
+ auth: { mode: authMode },
107
+ config: fileConfig,
108
+ verbose: options.verbose ?? false,
109
+ };
110
+ if (workerManager !== undefined)
111
+ serverOpts.workerManager = workerManager;
112
+ const { app, stop } = createTaskcastApp(serverOpts);
113
+ // Serve playground static files if --playground and dist exists
114
+ if (options.playground) {
115
+ try {
116
+ const require = createRequire(import.meta.url);
117
+ const pkgPath = require.resolve('@taskcast/playground/package.json');
118
+ const distDir = join(dirname(pkgPath), 'dist');
119
+ if (existsSync(distDir)) {
120
+ const { serveStatic } = await import('@hono/node-server/serve-static');
121
+ app.use('/_playground/*', serveStatic({ root: distDir, rewriteRequestPath: (p) => p.replace(/^\/_playground/, '') }));
122
+ // SPA fallback: serve index.html for non-asset paths
123
+ app.get('/_playground/*', serveStatic({ root: distDir, rewriteRequestPath: () => '/index.html' }));
124
+ }
125
+ else {
126
+ console.warn('[taskcast] Playground dist not found. Run `pnpm --filter @taskcast/playground build` first.');
127
+ }
128
+ }
129
+ catch {
130
+ console.warn('[taskcast] @taskcast/playground not available, skipping playground UI.');
131
+ }
132
+ }
133
+ const { serve } = await import('@hono/node-server');
134
+ const server = serve({ fetch: app.fetch, port }, () => {
135
+ console.log(`[taskcast] Server started on http://localhost:${port}`);
136
+ if (options.playground) {
137
+ console.log(`[taskcast] Playground UI at http://localhost:${port}/_playground/`);
138
+ }
139
+ });
140
+ // Clean up scheduler/heartbeat on shutdown
141
+ process.on('SIGTERM', () => { stop(); server.close?.(); });
142
+ process.on('SIGINT', () => { stop(); server.close?.(); });
143
+ });
144
+ }
145
+ //# 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,11 @@
1
+ import { Command } from 'commander';
2
+ export interface TaskListItem {
3
+ id: string;
4
+ type?: string;
5
+ status: string;
6
+ createdAt: number;
7
+ }
8
+ export declare function formatTaskList(tasks: TaskListItem[]): string;
9
+ export declare function formatTaskInspect(task: any, events: any[]): string;
10
+ export declare function registerTasksCommand(program: Command): void;
11
+ //# sourceMappingURL=tasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/commands/tasks.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKnC,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;CAClB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,YAAY,EAAE,GAAG,MAAM,CAa5D;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,CAyBlE;AAmBD,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwE3D"}
@@ -0,0 +1,129 @@
1
+ import { NodeConfigManager } from '../node-config.js';
2
+ import { createClientFromNodeAsync } from '../client.js';
3
+ export function formatTaskList(tasks) {
4
+ if (tasks.length === 0)
5
+ return 'No tasks found.';
6
+ const header = `${'ID'.padEnd(28)}${'TYPE'.padEnd(13)}${'STATUS'.padEnd(11)}CREATED`;
7
+ const rows = tasks.map((t) => {
8
+ const id = (t.id ?? '').padEnd(28);
9
+ const type = (t.type ?? '').padEnd(13);
10
+ const status = (t.status ?? '').padEnd(11);
11
+ const created = formatTimestamp(t.createdAt);
12
+ return `${id}${type}${status}${created}`;
13
+ });
14
+ return [header, ...rows].join('\n');
15
+ }
16
+ export function formatTaskInspect(task, events) {
17
+ const lines = [];
18
+ lines.push(`Task: ${task.id}`);
19
+ lines.push(` Type: ${task.type ?? ''}`);
20
+ lines.push(` Status: ${task.status}`);
21
+ lines.push(` Params: ${task.params != null ? JSON.stringify(task.params) : ''}`);
22
+ lines.push(` Created: ${formatTimestamp(task.createdAt)}`);
23
+ if (events.length > 0) {
24
+ const last5 = events.slice(-5);
25
+ lines.push('');
26
+ lines.push(`Recent Events (last ${last5.length}):`);
27
+ for (let i = 0; i < last5.length; i++) {
28
+ const e = last5[i];
29
+ const series = e.seriesId ? `series:${e.seriesId}` : '';
30
+ const ts = formatTimestamp(e.timestamp);
31
+ lines.push(` #${i} ${(e.type ?? '').padEnd(13)}${(e.level ?? '').padEnd(7)}${series.padEnd(17)}${ts}`);
32
+ }
33
+ }
34
+ else {
35
+ lines.push('');
36
+ lines.push('No events.');
37
+ }
38
+ return lines.join('\n');
39
+ }
40
+ function formatTimestamp(ts) {
41
+ if (!ts)
42
+ return '';
43
+ const d = new Date(ts);
44
+ const pad = (n) => String(n).padStart(2, '0');
45
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
46
+ }
47
+ /**
48
+ * Call _request on the server-sdk client.
49
+ * The SDK doesn't expose a listTasks method, so we use the internal _request
50
+ * to leverage the already-configured auth token and fetch function.
51
+ */
52
+ async function clientRequest(client, method, path) {
53
+ // Access the private _request method via bracket notation
54
+ return client._request(method, path);
55
+ }
56
+ export function registerTasksCommand(program) {
57
+ const tasks = program
58
+ .command('tasks')
59
+ .description('Manage tasks on a Taskcast server');
60
+ tasks
61
+ .command('list')
62
+ .description('List tasks')
63
+ .option('--status <status>', 'Filter by status (e.g. running)')
64
+ .option('--type <type>', 'Filter by task type (e.g. llm.*)')
65
+ .option('--limit <limit>', 'Maximum number of tasks to show', '20')
66
+ .option('--node <name>', 'Named node to query')
67
+ .action(async (opts) => {
68
+ const mgr = new NodeConfigManager();
69
+ let node;
70
+ if (opts.node) {
71
+ node = mgr.get(opts.node);
72
+ if (!node) {
73
+ console.error(`Node "${opts.node}" not found`);
74
+ process.exit(1);
75
+ }
76
+ }
77
+ else {
78
+ node = mgr.getCurrent();
79
+ }
80
+ try {
81
+ const client = await createClientFromNodeAsync(node);
82
+ const params = new URLSearchParams();
83
+ if (opts.status)
84
+ params.set('status', opts.status);
85
+ if (opts.type)
86
+ params.set('type', opts.type);
87
+ const qs = params.toString();
88
+ const path = `/tasks${qs ? `?${qs}` : ''}`;
89
+ const body = await clientRequest(client, 'GET', path);
90
+ const limit = parseInt(opts.limit ?? '20', 10);
91
+ const tasks = body.tasks.slice(0, limit);
92
+ console.log(formatTaskList(tasks));
93
+ }
94
+ catch (err) {
95
+ console.error(`Error: ${err.message}`);
96
+ process.exit(1);
97
+ }
98
+ });
99
+ tasks
100
+ .command('inspect')
101
+ .description('Inspect a task and its recent events')
102
+ .argument('<taskId>', 'Task ID to inspect')
103
+ .option('--node <name>', 'Named node to query')
104
+ .action(async (taskId, opts) => {
105
+ const mgr = new NodeConfigManager();
106
+ let node;
107
+ if (opts.node) {
108
+ node = mgr.get(opts.node);
109
+ if (!node) {
110
+ console.error(`Node "${opts.node}" not found`);
111
+ process.exit(1);
112
+ }
113
+ }
114
+ else {
115
+ node = mgr.getCurrent();
116
+ }
117
+ try {
118
+ const client = await createClientFromNodeAsync(node);
119
+ const task = await client.getTask(taskId);
120
+ const events = await client.getHistory(taskId);
121
+ console.log(formatTaskInspect(task, events));
122
+ }
123
+ catch (err) {
124
+ console.error(`Error: ${err.message}`);
125
+ process.exit(1);
126
+ }
127
+ });
128
+ }
129
+ //# sourceMappingURL=tasks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tasks.js","sourceRoot":"","sources":["../../src/commands/tasks.ts"],"names":[],"mappings":"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"}