@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.
- package/dist/client.d.ts +15 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +47 -0
- package/dist/client.js.map +1 -0
- package/dist/commands/doctor.d.ts +23 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +95 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/logs.d.ts +11 -0
- package/dist/commands/logs.d.ts.map +1 -0
- package/dist/commands/logs.js +171 -0
- package/dist/commands/logs.js.map +1 -0
- package/dist/commands/migrate.d.ts +3 -0
- package/dist/commands/migrate.d.ts.map +1 -0
- package/dist/commands/migrate.js +84 -0
- package/dist/commands/migrate.js.map +1 -0
- package/dist/commands/node.d.ts +5 -0
- package/dist/commands/node.d.ts.map +1 -0
- package/dist/commands/node.js +57 -0
- package/dist/commands/node.js.map +1 -0
- package/dist/commands/ping.d.ts +9 -0
- package/dist/commands/ping.d.ts.map +1 -0
- package/dist/commands/ping.js +43 -0
- package/dist/commands/ping.js.map +1 -0
- package/dist/commands/playground.d.ts +3 -0
- package/dist/commands/playground.d.ts.map +1 -0
- package/dist/commands/playground.js +37 -0
- package/dist/commands/playground.js.map +1 -0
- 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 +3 -0
- package/dist/commands/start.d.ts.map +1 -0
- package/dist/commands/start.js +145 -0
- package/dist/commands/start.js.map +1 -0
- package/dist/commands/tasks.d.ts +11 -0
- package/dist/commands/tasks.d.ts.map +1 -0
- package/dist/commands/tasks.js +129 -0
- package/dist/commands/tasks.js.map +1 -0
- package/dist/commands/ui.d.ts +3 -0
- package/dist/commands/ui.d.ts.map +1 -0
- package/dist/commands/ui.js +103 -0
- package/dist/commands/ui.js.map +1 -0
- package/dist/index.js +41 -413
- package/dist/index.js.map +1 -1
- package/dist/node-config.d.ts +22 -0
- package/dist/node-config.d.ts.map +1 -0
- package/dist/node-config.js +71 -0
- package/dist/node-config.js.map +1 -0
- 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/dist/utils.d.ts +5 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +65 -0
- package/dist/utils.js.map +1 -0
- package/package.json +9 -8
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { homedir } from 'os';
|
|
4
|
+
const DEFAULT_URL = 'http://localhost:3721';
|
|
5
|
+
export class NodeConfigManager {
|
|
6
|
+
configPath;
|
|
7
|
+
constructor(configDir) {
|
|
8
|
+
const dir = configDir ?? join(homedir(), '.taskcast');
|
|
9
|
+
this.configPath = join(dir, 'nodes.json');
|
|
10
|
+
}
|
|
11
|
+
getCurrent() {
|
|
12
|
+
const data = this.load();
|
|
13
|
+
if (data.current) {
|
|
14
|
+
const node = data.nodes[data.current];
|
|
15
|
+
if (node)
|
|
16
|
+
return node;
|
|
17
|
+
}
|
|
18
|
+
return { url: DEFAULT_URL };
|
|
19
|
+
}
|
|
20
|
+
get(name) {
|
|
21
|
+
const data = this.load();
|
|
22
|
+
return data.nodes[name];
|
|
23
|
+
}
|
|
24
|
+
add(name, entry) {
|
|
25
|
+
const data = this.load();
|
|
26
|
+
data.nodes[name] = entry;
|
|
27
|
+
this.save(data);
|
|
28
|
+
}
|
|
29
|
+
remove(name) {
|
|
30
|
+
const data = this.load();
|
|
31
|
+
if (!(name in data.nodes)) {
|
|
32
|
+
throw new Error(`Node "${name}" not found`);
|
|
33
|
+
}
|
|
34
|
+
delete data.nodes[name];
|
|
35
|
+
if (data.current === name) {
|
|
36
|
+
data.current = null;
|
|
37
|
+
}
|
|
38
|
+
this.save(data);
|
|
39
|
+
}
|
|
40
|
+
use(name) {
|
|
41
|
+
const data = this.load();
|
|
42
|
+
if (!(name in data.nodes)) {
|
|
43
|
+
throw new Error(`Node "${name}" not found`);
|
|
44
|
+
}
|
|
45
|
+
data.current = name;
|
|
46
|
+
this.save(data);
|
|
47
|
+
}
|
|
48
|
+
list() {
|
|
49
|
+
const data = this.load();
|
|
50
|
+
return Object.entries(data.nodes).map(([name, entry]) => ({
|
|
51
|
+
...entry,
|
|
52
|
+
name,
|
|
53
|
+
current: data.current === name,
|
|
54
|
+
}));
|
|
55
|
+
}
|
|
56
|
+
load() {
|
|
57
|
+
try {
|
|
58
|
+
const raw = readFileSync(this.configPath, 'utf-8');
|
|
59
|
+
return JSON.parse(raw);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return { current: null, nodes: {} };
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
save(data) {
|
|
66
|
+
const dir = this.configPath.replace(/[/\\][^/\\]*$/, '');
|
|
67
|
+
mkdirSync(dir, { recursive: true });
|
|
68
|
+
writeFileSync(this.configPath, JSON.stringify(data, null, 2), 'utf-8');
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=node-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"node-config.js","sourceRoot":"","sources":["../src/node-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -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/dist/utils.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare const DEFAULT_CONFIG_YAML = "# Taskcast configuration\n# Docs: https://github.com/weightwave/taskcast\n\nport: 3721\n\n# auth:\n# mode: none # none | jwt\n\n# adapters:\n# broadcast:\n# provider: memory # memory | redis\n# # url: redis://localhost:6379\n# shortTermStore:\n# provider: memory # memory | redis\n# # url: redis://localhost:6379\n# longTermStore:\n# provider: postgres\n# # url: postgresql://localhost:5432/taskcast\n";
|
|
2
|
+
export declare function promptCreateGlobalConfig(): Promise<boolean>;
|
|
3
|
+
export declare function promptConfirm(message: string): Promise<boolean>;
|
|
4
|
+
export declare function createDefaultGlobalConfig(): string | null;
|
|
5
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,mBAAmB,ybAkB/B,CAAA;AAED,wBAAsB,wBAAwB,IAAI,OAAO,CAAC,OAAO,CAAC,CAiBjE;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAYrE;AAED,wBAAgB,yBAAyB,IAAI,MAAM,GAAG,IAAI,CAYzD"}
|
package/dist/utils.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { createInterface } from 'readline';
|
|
2
|
+
import { mkdirSync, writeFileSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import { homedir } from 'os';
|
|
5
|
+
export const DEFAULT_CONFIG_YAML = `# Taskcast configuration
|
|
6
|
+
# Docs: https://github.com/weightwave/taskcast
|
|
7
|
+
|
|
8
|
+
port: 3721
|
|
9
|
+
|
|
10
|
+
# auth:
|
|
11
|
+
# mode: none # none | jwt
|
|
12
|
+
|
|
13
|
+
# adapters:
|
|
14
|
+
# broadcast:
|
|
15
|
+
# provider: memory # memory | redis
|
|
16
|
+
# # url: redis://localhost:6379
|
|
17
|
+
# shortTermStore:
|
|
18
|
+
# provider: memory # memory | redis
|
|
19
|
+
# # url: redis://localhost:6379
|
|
20
|
+
# longTermStore:
|
|
21
|
+
# provider: postgres
|
|
22
|
+
# # url: postgresql://localhost:5432/taskcast
|
|
23
|
+
`;
|
|
24
|
+
export async function promptCreateGlobalConfig() {
|
|
25
|
+
if (!process.stdin.isTTY)
|
|
26
|
+
return false;
|
|
27
|
+
const globalConfigPath = join(homedir(), '.taskcast', 'taskcast.config.yaml');
|
|
28
|
+
return new Promise((resolve) => {
|
|
29
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
30
|
+
rl.on('close', () => resolve(false));
|
|
31
|
+
rl.question(`[taskcast] No config file found.\n? Create a default config at ${globalConfigPath}? (Y/n) `, (answer) => {
|
|
32
|
+
const trimmed = answer.trim().toLowerCase();
|
|
33
|
+
resolve(trimmed === '' || trimmed === 'y' || trimmed === 'yes');
|
|
34
|
+
rl.close();
|
|
35
|
+
});
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
export async function promptConfirm(message) {
|
|
39
|
+
if (!process.stdin.isTTY)
|
|
40
|
+
return false;
|
|
41
|
+
return new Promise((resolve) => {
|
|
42
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
43
|
+
rl.on('close', () => resolve(false));
|
|
44
|
+
rl.question(message, (answer) => {
|
|
45
|
+
const trimmed = answer.trim().toLowerCase();
|
|
46
|
+
resolve(trimmed === '' || trimmed === 'y' || trimmed === 'yes');
|
|
47
|
+
rl.close();
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
export function createDefaultGlobalConfig() {
|
|
52
|
+
const globalDir = join(homedir(), '.taskcast');
|
|
53
|
+
const globalConfigPath = join(globalDir, 'taskcast.config.yaml');
|
|
54
|
+
try {
|
|
55
|
+
mkdirSync(globalDir, { recursive: true });
|
|
56
|
+
writeFileSync(globalConfigPath, DEFAULT_CONFIG_YAML);
|
|
57
|
+
console.log(`[taskcast] Created default config at ${globalConfigPath}`);
|
|
58
|
+
return globalConfigPath;
|
|
59
|
+
}
|
|
60
|
+
catch (err) {
|
|
61
|
+
console.warn(`[taskcast] Could not create config at ${globalConfigPath}: ${err.message}`);
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.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.3.0",
|
|
4
4
|
"description": "Standalone Taskcast server CLI — run with npx taskcast.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -37,13 +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/playground": "0.3.
|
|
42
|
-
"@taskcast/
|
|
43
|
-
"@taskcast/
|
|
44
|
-
"@taskcast/sqlite": "1.
|
|
45
|
-
"@taskcast/
|
|
46
|
-
"@taskcast/
|
|
40
|
+
"@taskcast/core": "1.3.0",
|
|
41
|
+
"@taskcast/playground": "0.3.5",
|
|
42
|
+
"@taskcast/postgres": "1.3.0",
|
|
43
|
+
"@taskcast/redis": "1.3.0",
|
|
44
|
+
"@taskcast/sqlite": "1.3.0",
|
|
45
|
+
"@taskcast/server": "1.3.0",
|
|
46
|
+
"@taskcast/server-sdk": "1.3.0",
|
|
47
|
+
"@taskcast/dashboard-web": "0.3.5"
|
|
47
48
|
},
|
|
48
49
|
"devDependencies": {
|
|
49
50
|
"typescript": "^5.7.0",
|