@taskcast/cli 1.2.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/service.d.ts +8 -0
- package/dist/commands/service.d.ts.map +1 -0
- package/dist/commands/service.js +237 -0
- package/dist/commands/service.js.map +1 -0
- package/dist/commands/start.d.ts.map +1 -1
- package/dist/commands/start.js +17 -3
- package/dist/commands/start.js.map +1 -1
- package/dist/index.js +25 -8
- package/dist/index.js.map +1 -1
- package/dist/service/interface.d.ts +26 -0
- package/dist/service/interface.d.ts.map +1 -0
- package/dist/service/interface.js +3 -0
- package/dist/service/interface.js.map +1 -0
- package/dist/service/launchd.d.ts +11 -0
- package/dist/service/launchd.d.ts.map +1 -0
- package/dist/service/launchd.js +97 -0
- package/dist/service/launchd.js.map +1 -0
- package/dist/service/paths.d.ts +12 -0
- package/dist/service/paths.d.ts.map +1 -0
- package/dist/service/paths.js +35 -0
- package/dist/service/paths.js.map +1 -0
- package/dist/service/resolve.d.ts +3 -0
- package/dist/service/resolve.d.ts.map +1 -0
- package/dist/service/resolve.js +10 -0
- package/dist/service/resolve.js.map +1 -0
- package/dist/service/systemd.d.ts +11 -0
- package/dist/service/systemd.d.ts.map +1 -0
- package/dist/service/systemd.js +86 -0
- package/dist/service/systemd.js.map +1 -0
- package/package.json +9 -9
|
@@ -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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"}
|
|
@@ -1 +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,
|
|
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"}
|
package/dist/commands/start.js
CHANGED
|
@@ -20,7 +20,7 @@ export function registerStartCommand(program) {
|
|
|
20
20
|
.option('--playground', 'serve the interactive playground UI at /_playground/')
|
|
21
21
|
.option('-v, --verbose', 'enable verbose logging')
|
|
22
22
|
.action(async (options) => {
|
|
23
|
-
let { config: fileConfig, source } = await loadConfigFile(options.config);
|
|
23
|
+
let { config: fileConfig, source, path: configPath } = await loadConfigFile(options.config);
|
|
24
24
|
if (source === 'none') {
|
|
25
25
|
const shouldCreate = await promptCreateGlobalConfig();
|
|
26
26
|
if (shouldCreate) {
|
|
@@ -28,6 +28,8 @@ export function registerStartCommand(program) {
|
|
|
28
28
|
if (createdPath) {
|
|
29
29
|
const created = await loadConfigFile(createdPath);
|
|
30
30
|
fileConfig = created.config;
|
|
31
|
+
source = created.source;
|
|
32
|
+
configPath = created.path;
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
35
|
}
|
|
@@ -38,13 +40,17 @@ export function registerStartCommand(program) {
|
|
|
38
40
|
let broadcast;
|
|
39
41
|
let longTermStore;
|
|
40
42
|
const storage = options.storage ?? process.env['TASKCAST_STORAGE'] ?? (redisUrl ? 'redis' : 'memory');
|
|
43
|
+
let shortTermLabel;
|
|
44
|
+
let longTermLabel;
|
|
41
45
|
if (storage === 'sqlite') {
|
|
46
|
+
const dbPath = options.dbPath ?? './taskcast.db';
|
|
42
47
|
const sqliteOpts = options.dbPath ? { path: options.dbPath } : {};
|
|
43
48
|
const adapters = createSqliteAdapters(sqliteOpts);
|
|
44
49
|
broadcast = new MemoryBroadcastProvider();
|
|
45
50
|
shortTermStore = adapters.shortTermStore;
|
|
46
51
|
longTermStore = adapters.longTermStore;
|
|
47
|
-
|
|
52
|
+
shortTermLabel = `sqlite @ ${dbPath}`;
|
|
53
|
+
longTermLabel = `sqlite @ ${dbPath}`;
|
|
48
54
|
}
|
|
49
55
|
else if (storage === 'redis' || redisUrl) {
|
|
50
56
|
const pubClient = new Redis(redisUrl);
|
|
@@ -53,16 +59,24 @@ export function registerStartCommand(program) {
|
|
|
53
59
|
const adapters = createRedisAdapters(pubClient, subClient, storeClient);
|
|
54
60
|
broadcast = adapters.broadcast;
|
|
55
61
|
shortTermStore = adapters.shortTermStore;
|
|
62
|
+
shortTermLabel = `redis @ ${redisUrl}`;
|
|
63
|
+
longTermLabel = '(none)';
|
|
56
64
|
}
|
|
57
65
|
else {
|
|
58
|
-
console.warn('[taskcast] No TASKCAST_REDIS_URL configured — using in-memory adapters');
|
|
59
66
|
broadcast = new MemoryBroadcastProvider();
|
|
60
67
|
shortTermStore = new MemoryShortTermStore();
|
|
68
|
+
shortTermLabel = 'memory';
|
|
69
|
+
longTermLabel = '(none)';
|
|
61
70
|
}
|
|
62
71
|
if (storage !== 'sqlite' && postgresUrl) {
|
|
63
72
|
const sql = postgres(postgresUrl);
|
|
64
73
|
longTermStore = new PostgresLongTermStore(sql);
|
|
74
|
+
longTermLabel = `postgres @ ${postgresUrl}`;
|
|
65
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}`);
|
|
66
80
|
const engineOpts = { shortTermStore, broadcast };
|
|
67
81
|
if (longTermStore !== undefined)
|
|
68
82
|
engineOpts.longTermStore = longTermStore;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,QAAQ,MAAM,UAAU,CAAA;AAC/B,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;AACtC,OAAO,EACL,UAAU,EACV,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,uBAAuB,EACvB,oBAAoB,GACrB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AACrD,OAAO,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAA;AAC1D,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAA;AACvD,OAAO,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAA;AAEjF,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,OAAO;SACJ,OAAO,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;SACrC,WAAW,CAAC,mDAAmD,CAAC;SAChE,MAAM,CAAC,qBAAqB,EAAE,kBAAkB,CAAC;SACjD,MAAM,CAAC,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,CAAC;SACxD,MAAM,CAAC,sBAAsB,EAAE,0CAA0C,EAAE,QAAQ,CAAC;SACpF,MAAM,CAAC,kBAAkB,EAAE,oDAAoD,CAAC;SAChF,MAAM,CAAC,cAAc,EAAE,sDAAsD,CAAC;SAC9E,MAAM,CAAC,eAAe,EAAE,wBAAwB,CAAC;SACjD,MAAM,CAAC,KAAK,EAAE,OAAsH,EAAE,EAAE;QACvI,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,MAAM,cAAc,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"start.js","sourceRoot":"","sources":["../../src/commands/start.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'module';
|
|
2
3
|
import { Command } from 'commander';
|
|
3
4
|
import { registerStartCommand } from './commands/start.js';
|
|
4
5
|
import { registerMigrateCommand } from './commands/migrate.js';
|
|
@@ -9,11 +10,14 @@ import { registerPingCommand } from './commands/ping.js';
|
|
|
9
10
|
import { registerDoctorCommand } from './commands/doctor.js';
|
|
10
11
|
import { registerLogsCommand, registerTailCommand } from './commands/logs.js';
|
|
11
12
|
import { registerTasksCommand } from './commands/tasks.js';
|
|
13
|
+
import { registerServiceCommand } from './commands/service.js';
|
|
14
|
+
const _require = createRequire(import.meta.url);
|
|
15
|
+
const { version } = _require('../package.json');
|
|
12
16
|
const program = new Command();
|
|
13
17
|
program
|
|
14
18
|
.name('taskcast')
|
|
15
19
|
.description('Taskcast — unified task tracking and streaming service')
|
|
16
|
-
.version(
|
|
20
|
+
.version(version);
|
|
17
21
|
registerStartCommand(program);
|
|
18
22
|
registerMigrateCommand(program);
|
|
19
23
|
registerPlaygroundCommand(program);
|
|
@@ -24,12 +28,25 @@ registerDoctorCommand(program);
|
|
|
24
28
|
registerLogsCommand(program);
|
|
25
29
|
registerTailCommand(program);
|
|
26
30
|
registerTasksCommand(program);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
.action(() => {
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
registerServiceCommand(program);
|
|
32
|
+
// Backward-compat aliases for old daemon/stop/status placeholder commands
|
|
33
|
+
program.command('daemon').description('Alias for `taskcast service start`')
|
|
34
|
+
/* v8 ignore next 4 */
|
|
35
|
+
.action(async () => {
|
|
36
|
+
const { runServiceStart } = await import('./commands/service.js');
|
|
37
|
+
await runServiceStart();
|
|
38
|
+
});
|
|
39
|
+
program.command('stop').description('Alias for `taskcast service stop`')
|
|
40
|
+
/* v8 ignore next 4 */
|
|
41
|
+
.action(async () => {
|
|
42
|
+
const { runServiceStop } = await import('./commands/service.js');
|
|
43
|
+
await runServiceStop();
|
|
44
|
+
});
|
|
45
|
+
program.command('status').description('Alias for `taskcast service status`')
|
|
46
|
+
/* v8 ignore next 4 */
|
|
47
|
+
.action(async () => {
|
|
48
|
+
const { runServiceStatus } = await import('./commands/service.js');
|
|
49
|
+
await runServiceStatus();
|
|
50
|
+
});
|
|
34
51
|
program.parse();
|
|
35
52
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAA;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AACtC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAA;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAA;AAC5D,OAAO,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAA;AAC7E,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAA;AAE9D,MAAM,QAAQ,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;AAC/C,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,CAAC,iBAAiB,CAAwB,CAAA;AAEtE,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAA;AAE7B,OAAO;KACJ,IAAI,CAAC,UAAU,CAAC;KAChB,WAAW,CAAC,wDAAwD,CAAC;KACrE,OAAO,CAAC,OAAO,CAAC,CAAA;AAEnB,oBAAoB,CAAC,OAAO,CAAC,CAAA;AAC7B,sBAAsB,CAAC,OAAO,CAAC,CAAA;AAC/B,yBAAyB,CAAC,OAAO,CAAC,CAAA;AAClC,iBAAiB,CAAC,OAAO,CAAC,CAAA;AAC1B,mBAAmB,CAAC,OAAO,CAAC,CAAA;AAC5B,mBAAmB,CAAC,OAAO,CAAC,CAAA;AAC5B,qBAAqB,CAAC,OAAO,CAAC,CAAA;AAC9B,mBAAmB,CAAC,OAAO,CAAC,CAAA;AAC5B,mBAAmB,CAAC,OAAO,CAAC,CAAA;AAC5B,oBAAoB,CAAC,OAAO,CAAC,CAAA;AAC7B,sBAAsB,CAAC,OAAO,CAAC,CAAA;AAE/B,0EAA0E;AAC1E,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,oCAAoC,CAAC;IACzE,sBAAsB;KACrB,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAA;IACjE,MAAM,eAAe,EAAE,CAAA;AACzB,CAAC,CAAC,CAAA;AACJ,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,CAAC,mCAAmC,CAAC;IACtE,sBAAsB;KACrB,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAA;IAChE,MAAM,cAAc,EAAE,CAAA;AACxB,CAAC,CAAC,CAAA;AACJ,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,CAAC,qCAAqC,CAAC;IAC1E,sBAAsB;KACrB,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAA;IAClE,MAAM,gBAAgB,EAAE,CAAA;AAC1B,CAAC,CAAC,CAAA;AAEJ,OAAO,CAAC,KAAK,EAAE,CAAA"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface ServiceInstallOptions {
|
|
2
|
+
port: number;
|
|
3
|
+
config?: string;
|
|
4
|
+
storage?: string;
|
|
5
|
+
dbPath?: string;
|
|
6
|
+
nodePath: string;
|
|
7
|
+
entryPoint: string;
|
|
8
|
+
}
|
|
9
|
+
export type ServiceStatus = {
|
|
10
|
+
state: 'running';
|
|
11
|
+
pid: number;
|
|
12
|
+
port?: number;
|
|
13
|
+
} | {
|
|
14
|
+
state: 'stopped';
|
|
15
|
+
} | {
|
|
16
|
+
state: 'not-installed';
|
|
17
|
+
};
|
|
18
|
+
export interface ServiceManager {
|
|
19
|
+
install(opts: ServiceInstallOptions): Promise<void>;
|
|
20
|
+
uninstall(): Promise<void>;
|
|
21
|
+
start(): Promise<void>;
|
|
22
|
+
stop(): Promise<void>;
|
|
23
|
+
restart(): Promise<void>;
|
|
24
|
+
status(): Promise<ServiceStatus>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=interface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interface.d.ts","sourceRoot":"","sources":["../../src/service/interface.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,MAAM,aAAa,GACrB;IAAE,KAAK,EAAE,SAAS,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAChD;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,GACpB;IAAE,KAAK,EAAE,eAAe,CAAA;CAAE,CAAA;AAE9B,MAAM,WAAW,cAAc;IAC7B,OAAO,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACnD,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACxB,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC,CAAA;CACjC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interface.js","sourceRoot":"","sources":["../../src/service/interface.ts"],"names":[],"mappings":"AAAA,wCAAwC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ServiceManager, ServiceInstallOptions, ServiceStatus } from './interface.js';
|
|
2
|
+
export declare class LaunchdServiceManager implements ServiceManager {
|
|
3
|
+
private paths;
|
|
4
|
+
install(opts: ServiceInstallOptions): Promise<void>;
|
|
5
|
+
uninstall(): Promise<void>;
|
|
6
|
+
start(): Promise<void>;
|
|
7
|
+
stop(): Promise<void>;
|
|
8
|
+
restart(): Promise<void>;
|
|
9
|
+
status(): Promise<ServiceStatus>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=launchd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launchd.d.ts","sourceRoot":"","sources":["../../src/service/launchd.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AAwC1F,qBAAa,qBAAsB,YAAW,cAAc;IAC1D,OAAO,CAAC,KAAK,CAAoB;IAE3B,OAAO,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAcnD,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAY1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAStB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAKrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAKxB,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;CAgBvC"}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
// packages/cli/src/service/launchd.ts
|
|
2
|
+
import { existsSync, writeFileSync, mkdirSync, unlinkSync } from 'fs';
|
|
3
|
+
import { execFileSync } from 'child_process';
|
|
4
|
+
import { dirname } from 'path';
|
|
5
|
+
import { getServicePaths, LAUNCHD_LABEL } from './paths.js';
|
|
6
|
+
function getUid() {
|
|
7
|
+
return process.getuid?.() ?? 501;
|
|
8
|
+
}
|
|
9
|
+
function generatePlist(opts, paths) {
|
|
10
|
+
const args = [opts.entryPoint, 'start', '--port', String(opts.port)];
|
|
11
|
+
if (opts.config)
|
|
12
|
+
args.push('--config', opts.config);
|
|
13
|
+
if (opts.storage)
|
|
14
|
+
args.push('--storage', opts.storage);
|
|
15
|
+
if (opts.dbPath)
|
|
16
|
+
args.push('--db-path', opts.dbPath);
|
|
17
|
+
const programArgs = [opts.nodePath, ...args]
|
|
18
|
+
.map(a => ` <string>${a}</string>`)
|
|
19
|
+
.join('\n');
|
|
20
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
21
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
22
|
+
<plist version="1.0">
|
|
23
|
+
<dict>
|
|
24
|
+
<key>Label</key>
|
|
25
|
+
<string>${LAUNCHD_LABEL}</string>
|
|
26
|
+
<key>ProgramArguments</key>
|
|
27
|
+
<array>
|
|
28
|
+
${programArgs}
|
|
29
|
+
</array>
|
|
30
|
+
<key>RunAtLoad</key>
|
|
31
|
+
<true/>
|
|
32
|
+
<key>KeepAlive</key>
|
|
33
|
+
<false/>
|
|
34
|
+
<key>StandardOutPath</key>
|
|
35
|
+
<string>${paths.stdoutLog}</string>
|
|
36
|
+
<key>StandardErrorPath</key>
|
|
37
|
+
<string>${paths.stderrLog}</string>
|
|
38
|
+
</dict>
|
|
39
|
+
</plist>
|
|
40
|
+
`;
|
|
41
|
+
}
|
|
42
|
+
export class LaunchdServiceManager {
|
|
43
|
+
paths = getServicePaths();
|
|
44
|
+
async install(opts) {
|
|
45
|
+
if (existsSync(this.paths.plistOrUnitPath)) {
|
|
46
|
+
throw new Error(`Taskcast service is already installed. Run \`taskcast service uninstall\` first.`);
|
|
47
|
+
}
|
|
48
|
+
// Ensure log directory exists
|
|
49
|
+
mkdirSync(this.paths.logDir, { recursive: true });
|
|
50
|
+
// Ensure plist parent directory exists
|
|
51
|
+
mkdirSync(dirname(this.paths.plistOrUnitPath), { recursive: true });
|
|
52
|
+
const plist = generatePlist(opts, this.paths);
|
|
53
|
+
writeFileSync(this.paths.plistOrUnitPath, plist);
|
|
54
|
+
}
|
|
55
|
+
async uninstall() {
|
|
56
|
+
if (!existsSync(this.paths.plistOrUnitPath))
|
|
57
|
+
return;
|
|
58
|
+
// Stop if running
|
|
59
|
+
const st = await this.status();
|
|
60
|
+
if (st.state === 'running') {
|
|
61
|
+
await this.stop();
|
|
62
|
+
}
|
|
63
|
+
unlinkSync(this.paths.plistOrUnitPath);
|
|
64
|
+
}
|
|
65
|
+
async start() {
|
|
66
|
+
if (!existsSync(this.paths.plistOrUnitPath)) {
|
|
67
|
+
throw new Error(`Taskcast service is not installed. Run \`taskcast service install\` first.`);
|
|
68
|
+
}
|
|
69
|
+
const uid = getUid();
|
|
70
|
+
execFileSync('launchctl', ['bootstrap', `gui/${uid}`, this.paths.plistOrUnitPath], { stdio: 'pipe' });
|
|
71
|
+
}
|
|
72
|
+
async stop() {
|
|
73
|
+
const uid = getUid();
|
|
74
|
+
execFileSync('launchctl', ['bootout', `gui/${uid}/${LAUNCHD_LABEL}`], { stdio: 'pipe' });
|
|
75
|
+
}
|
|
76
|
+
async restart() {
|
|
77
|
+
await this.stop();
|
|
78
|
+
await this.start();
|
|
79
|
+
}
|
|
80
|
+
async status() {
|
|
81
|
+
if (!existsSync(this.paths.plistOrUnitPath)) {
|
|
82
|
+
return { state: 'not-installed' };
|
|
83
|
+
}
|
|
84
|
+
try {
|
|
85
|
+
const output = execFileSync('launchctl', ['list', LAUNCHD_LABEL], { stdio: 'pipe' }).toString();
|
|
86
|
+
const pidMatch = output.match(/"PID"\s*=\s*(\d+)/);
|
|
87
|
+
if (pidMatch) {
|
|
88
|
+
return { state: 'running', pid: Number(pidMatch[1]) };
|
|
89
|
+
}
|
|
90
|
+
return { state: 'stopped' };
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return { state: 'stopped' };
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=launchd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"launchd.js","sourceRoot":"","sources":["../../src/service/launchd.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface ServicePaths {
|
|
2
|
+
plistOrUnitPath: string;
|
|
3
|
+
logDir: string;
|
|
4
|
+
stdoutLog: string;
|
|
5
|
+
stderrLog: string;
|
|
6
|
+
defaultConfigPath: string;
|
|
7
|
+
defaultDbPath: string;
|
|
8
|
+
serviceStatePath: string;
|
|
9
|
+
}
|
|
10
|
+
export declare const LAUNCHD_LABEL = "com.taskcast.daemon";
|
|
11
|
+
export declare function getServicePaths(): ServicePaths;
|
|
12
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/service/paths.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,YAAY;IAC3B,eAAe,EAAE,MAAM,CAAA;IACvB,MAAM,EAAE,MAAM,CAAA;IACd,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,iBAAiB,EAAE,MAAM,CAAA;IACzB,aAAa,EAAE,MAAM,CAAA;IACrB,gBAAgB,EAAE,MAAM,CAAA;CACzB;AAED,eAAO,MAAM,aAAa,wBAAwB,CAAA;AAElD,wBAAgB,eAAe,IAAI,YAAY,CAkC9C"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { homedir } from 'os';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
export const LAUNCHD_LABEL = 'com.taskcast.daemon';
|
|
4
|
+
export function getServicePaths() {
|
|
5
|
+
const home = homedir();
|
|
6
|
+
const platform = process.platform;
|
|
7
|
+
const defaultConfigPath = join(home, '.taskcast', 'taskcast.config.yaml');
|
|
8
|
+
const defaultDbPath = join(home, '.taskcast', 'taskcast.db');
|
|
9
|
+
const serviceStatePath = join(home, '.taskcast', 'service.state.json');
|
|
10
|
+
if (platform === 'darwin') {
|
|
11
|
+
const logDir = join(home, 'Library/Application Support/taskcast');
|
|
12
|
+
return {
|
|
13
|
+
plistOrUnitPath: join(home, 'Library/LaunchAgents', `${LAUNCHD_LABEL}.plist`),
|
|
14
|
+
logDir,
|
|
15
|
+
stdoutLog: join(logDir, 'taskcast.log'),
|
|
16
|
+
stderrLog: join(logDir, 'taskcast.err.log'),
|
|
17
|
+
defaultConfigPath,
|
|
18
|
+
defaultDbPath,
|
|
19
|
+
serviceStatePath,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
if (platform === 'linux') {
|
|
23
|
+
return {
|
|
24
|
+
plistOrUnitPath: join(home, '.config/systemd/user/taskcast.service'),
|
|
25
|
+
logDir: '', // systemd uses journalctl
|
|
26
|
+
stdoutLog: '', // journalctl --user -u taskcast
|
|
27
|
+
stderrLog: '', // journalctl --user -u taskcast
|
|
28
|
+
defaultConfigPath,
|
|
29
|
+
defaultDbPath,
|
|
30
|
+
serviceStatePath,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
throw new Error(`Unsupported platform: ${platform}`);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/service/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAA;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAY3B,MAAM,CAAC,MAAM,aAAa,GAAG,qBAAqB,CAAA;AAElD,MAAM,UAAU,eAAe;IAC7B,MAAM,IAAI,GAAG,OAAO,EAAE,CAAA;IACtB,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;IAEjC,MAAM,iBAAiB,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,sBAAsB,CAAC,CAAA;IACzE,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,aAAa,CAAC,CAAA;IAC5D,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,EAAE,WAAW,EAAE,oBAAoB,CAAC,CAAA;IAEtE,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,EAAE,sCAAsC,CAAC,CAAA;QACjE,OAAO;YACL,eAAe,EAAE,IAAI,CAAC,IAAI,EAAE,sBAAsB,EAAE,GAAG,aAAa,QAAQ,CAAC;YAC7E,MAAM;YACN,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC;YACvC,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,kBAAkB,CAAC;YAC3C,iBAAiB;YACjB,aAAa;YACb,gBAAgB;SACjB,CAAA;IACH,CAAC;IAED,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;QACzB,OAAO;YACL,eAAe,EAAE,IAAI,CAAC,IAAI,EAAE,uCAAuC,CAAC;YACpE,MAAM,EAAE,EAAE,EAAE,0BAA0B;YACtC,SAAS,EAAE,EAAE,EAAE,gCAAgC;YAC/C,SAAS,EAAE,EAAE,EAAE,gCAAgC;YAC/C,iBAAiB;YACjB,aAAa;YACb,gBAAgB;SACjB,CAAA;IACH,CAAC;IAED,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAA;AACtD,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/service/resolve.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAA;AAIpD,wBAAgB,oBAAoB,IAAI,cAAc,CAIrD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { LaunchdServiceManager } from './launchd.js';
|
|
2
|
+
import { SystemdServiceManager } from './systemd.js';
|
|
3
|
+
export function createServiceManager() {
|
|
4
|
+
if (process.platform === 'darwin')
|
|
5
|
+
return new LaunchdServiceManager();
|
|
6
|
+
if (process.platform === 'linux')
|
|
7
|
+
return new SystemdServiceManager();
|
|
8
|
+
throw new Error(`Unsupported platform: ${process.platform}`);
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=resolve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/service/resolve.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AACpD,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAA;AAEpD,MAAM,UAAU,oBAAoB;IAClC,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAAE,OAAO,IAAI,qBAAqB,EAAE,CAAA;IACrE,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,IAAI,qBAAqB,EAAE,CAAA;IACpE,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAA;AAC9D,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ServiceManager, ServiceInstallOptions, ServiceStatus } from './interface.js';
|
|
2
|
+
export declare class SystemdServiceManager implements ServiceManager {
|
|
3
|
+
private paths;
|
|
4
|
+
install(opts: ServiceInstallOptions): Promise<void>;
|
|
5
|
+
uninstall(): Promise<void>;
|
|
6
|
+
start(): Promise<void>;
|
|
7
|
+
stop(): Promise<void>;
|
|
8
|
+
restart(): Promise<void>;
|
|
9
|
+
status(): Promise<ServiceStatus>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=systemd.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemd.d.ts","sourceRoot":"","sources":["../../src/service/systemd.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAA;AA6B1F,qBAAa,qBAAsB,YAAW,cAAc;IAC1D,OAAO,CAAC,KAAK,CAAoB;IAE3B,OAAO,CAAC,IAAI,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC;IAcnD,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAa1B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAQtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAIxB,MAAM,IAAI,OAAO,CAAC,aAAa,CAAC;CAyBvC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
// packages/cli/src/service/systemd.ts
|
|
2
|
+
import { existsSync, writeFileSync, mkdirSync, unlinkSync } from 'fs';
|
|
3
|
+
import { execFileSync } from 'child_process';
|
|
4
|
+
import { dirname } from 'path';
|
|
5
|
+
import { getServicePaths } from './paths.js';
|
|
6
|
+
const SYSTEMD_UNIT = 'taskcast';
|
|
7
|
+
function generateUnitFile(opts) {
|
|
8
|
+
const args = [opts.entryPoint, 'start', '--port', String(opts.port)];
|
|
9
|
+
if (opts.config)
|
|
10
|
+
args.push('--config', opts.config);
|
|
11
|
+
if (opts.storage)
|
|
12
|
+
args.push('--storage', opts.storage);
|
|
13
|
+
if (opts.dbPath)
|
|
14
|
+
args.push('--db-path', opts.dbPath);
|
|
15
|
+
// Quote any argument containing spaces so systemd parses them correctly
|
|
16
|
+
const quote = (s) => (s.includes(' ') ? `"${s}"` : s);
|
|
17
|
+
const execStart = [opts.nodePath, ...args].map(quote).join(' ');
|
|
18
|
+
return `[Unit]
|
|
19
|
+
Description=Taskcast — unified task tracking and streaming service
|
|
20
|
+
After=network.target
|
|
21
|
+
|
|
22
|
+
[Service]
|
|
23
|
+
Type=simple
|
|
24
|
+
ExecStart=${execStart}
|
|
25
|
+
Restart=no
|
|
26
|
+
|
|
27
|
+
[Install]
|
|
28
|
+
WantedBy=default.target
|
|
29
|
+
`;
|
|
30
|
+
}
|
|
31
|
+
export class SystemdServiceManager {
|
|
32
|
+
paths = getServicePaths();
|
|
33
|
+
async install(opts) {
|
|
34
|
+
if (existsSync(this.paths.plistOrUnitPath)) {
|
|
35
|
+
throw new Error(`Taskcast service is already installed. Run \`taskcast service uninstall\` first.`);
|
|
36
|
+
}
|
|
37
|
+
mkdirSync(dirname(this.paths.plistOrUnitPath), { recursive: true });
|
|
38
|
+
const unit = generateUnitFile(opts);
|
|
39
|
+
writeFileSync(this.paths.plistOrUnitPath, unit);
|
|
40
|
+
execFileSync('systemctl', ['--user', 'daemon-reload'], { stdio: 'pipe' });
|
|
41
|
+
execFileSync('systemctl', ['--user', 'enable', SYSTEMD_UNIT], { stdio: 'pipe' });
|
|
42
|
+
}
|
|
43
|
+
async uninstall() {
|
|
44
|
+
if (!existsSync(this.paths.plistOrUnitPath))
|
|
45
|
+
return;
|
|
46
|
+
const st = await this.status();
|
|
47
|
+
if (st.state === 'running') {
|
|
48
|
+
await this.stop();
|
|
49
|
+
}
|
|
50
|
+
execFileSync('systemctl', ['--user', 'disable', SYSTEMD_UNIT], { stdio: 'pipe' });
|
|
51
|
+
execFileSync('systemctl', ['--user', 'daemon-reload'], { stdio: 'pipe' });
|
|
52
|
+
unlinkSync(this.paths.plistOrUnitPath);
|
|
53
|
+
}
|
|
54
|
+
async start() {
|
|
55
|
+
if (!existsSync(this.paths.plistOrUnitPath)) {
|
|
56
|
+
throw new Error(`Taskcast service is not installed. Run \`taskcast service install\` first.`);
|
|
57
|
+
}
|
|
58
|
+
execFileSync('systemctl', ['--user', 'start', SYSTEMD_UNIT], { stdio: 'pipe' });
|
|
59
|
+
}
|
|
60
|
+
async stop() {
|
|
61
|
+
execFileSync('systemctl', ['--user', 'stop', SYSTEMD_UNIT], { stdio: 'pipe' });
|
|
62
|
+
}
|
|
63
|
+
async restart() {
|
|
64
|
+
execFileSync('systemctl', ['--user', 'restart', SYSTEMD_UNIT], { stdio: 'pipe' });
|
|
65
|
+
}
|
|
66
|
+
async status() {
|
|
67
|
+
if (!existsSync(this.paths.plistOrUnitPath)) {
|
|
68
|
+
return { state: 'not-installed' };
|
|
69
|
+
}
|
|
70
|
+
try {
|
|
71
|
+
const output = execFileSync('systemctl', ['--user', 'show', SYSTEMD_UNIT, '--property=ActiveState,MainPID'], { stdio: 'pipe' }).toString();
|
|
72
|
+
const activeMatch = output.match(/ActiveState=(\w+)/);
|
|
73
|
+
const pidMatch = output.match(/MainPID=(\d+)/);
|
|
74
|
+
if (activeMatch?.[1] === 'active' && pidMatch) {
|
|
75
|
+
const pid = Number(pidMatch[1]);
|
|
76
|
+
if (pid > 0)
|
|
77
|
+
return { state: 'running', pid };
|
|
78
|
+
}
|
|
79
|
+
return { state: 'stopped' };
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return { state: 'stopped' };
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=systemd.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemd.js","sourceRoot":"","sources":["../../src/service/systemd.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@taskcast/cli",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"description": "Standalone Taskcast server CLI — run with npx taskcast.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -37,14 +37,14 @@
|
|
|
37
37
|
"commander": "^12.1.0",
|
|
38
38
|
"ioredis": "^5.4.0",
|
|
39
39
|
"postgres": "^3.4.5",
|
|
40
|
-
"@taskcast/core": "1.
|
|
41
|
-
"@taskcast/dashboard-web": "0.3.
|
|
42
|
-
"@taskcast/
|
|
43
|
-
"@taskcast/redis": "1.
|
|
44
|
-
"@taskcast/
|
|
45
|
-
"@taskcast/server-sdk": "1.
|
|
46
|
-
"@taskcast/
|
|
47
|
-
"@taskcast/
|
|
40
|
+
"@taskcast/core": "1.4.0",
|
|
41
|
+
"@taskcast/dashboard-web": "0.3.6",
|
|
42
|
+
"@taskcast/playground": "0.3.6",
|
|
43
|
+
"@taskcast/redis": "1.4.0",
|
|
44
|
+
"@taskcast/postgres": "1.4.0",
|
|
45
|
+
"@taskcast/server-sdk": "1.4.0",
|
|
46
|
+
"@taskcast/server": "1.4.0",
|
|
47
|
+
"@taskcast/sqlite": "1.4.0"
|
|
48
48
|
},
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"typescript": "^5.7.0",
|