@martin0309205/prism 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +87 -0
- package/assets/systemd/prism@.service +21 -0
- package/dist/artifacts.d.ts +9 -0
- package/dist/artifacts.js +77 -0
- package/dist/artifacts.js.map +1 -0
- package/dist/cli/commands/daemon.d.ts +2 -0
- package/dist/cli/commands/daemon.js +90 -0
- package/dist/cli/commands/daemon.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.js +69 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/generate.d.ts +2 -0
- package/dist/cli/commands/generate.js +89 -0
- package/dist/cli/commands/generate.js.map +1 -0
- package/dist/cli/commands/onboard.d.ts +2 -0
- package/dist/cli/commands/onboard.js +131 -0
- package/dist/cli/commands/onboard.js.map +1 -0
- package/dist/cli/commands/serve.d.ts +2 -0
- package/dist/cli/commands/serve.js +51 -0
- package/dist/cli/commands/serve.js.map +1 -0
- package/dist/cli/commands/update.d.ts +2 -0
- package/dist/cli/commands/update.js +38 -0
- package/dist/cli/commands/update.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +29 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config.d.ts +34 -0
- package/dist/config.js +88 -0
- package/dist/config.js.map +1 -0
- package/dist/daemon.d.ts +16 -0
- package/dist/daemon.js +72 -0
- package/dist/daemon.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/instances.d.ts +2 -0
- package/dist/instances.js +16 -0
- package/dist/instances.js.map +1 -0
- package/dist/logger.d.ts +9 -0
- package/dist/logger.js +23 -0
- package/dist/logger.js.map +1 -0
- package/dist/runner.d.ts +19 -0
- package/dist/runner.js +89 -0
- package/dist/runner.js.map +1 -0
- package/dist/surfaces/http.d.ts +12 -0
- package/dist/surfaces/http.js +96 -0
- package/dist/surfaces/http.js.map +1 -0
- package/dist/surfaces/slack.d.ts +9 -0
- package/dist/surfaces/slack.js +123 -0
- package/dist/surfaces/slack.js.map +1 -0
- package/package.json +51 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { loadConfig, loadEnvFile } from '../../config.js';
|
|
2
|
+
import { createLogger } from '../../logger.js';
|
|
3
|
+
import { startHttpServer } from '../../surfaces/http.js';
|
|
4
|
+
import { startSlackServer } from '../../surfaces/slack.js';
|
|
5
|
+
export function serveCmd(program) {
|
|
6
|
+
program
|
|
7
|
+
.command('serve')
|
|
8
|
+
.description('Start the configured surfaces (HTTP + Slack) for an instance.')
|
|
9
|
+
.option('-i, --instance <name>', 'prism instance to run', 'default')
|
|
10
|
+
.option('--http-only', 'start only the HTTP surface')
|
|
11
|
+
.option('--slack-only', 'start only the Slack surface')
|
|
12
|
+
.option('--public-base-url <url>', 'public base URL for artifact links (HTTP)', '')
|
|
13
|
+
.action(async (opts) => {
|
|
14
|
+
const config = loadConfig(opts.instance);
|
|
15
|
+
const env = loadEnvFile(opts.instance);
|
|
16
|
+
const logger = createLogger(config.logging.level);
|
|
17
|
+
// expose loaded env vars to claude subprocess via process.env
|
|
18
|
+
for (const [k, v] of Object.entries(env)) {
|
|
19
|
+
if (process.env[k] == null)
|
|
20
|
+
process.env[k] = v;
|
|
21
|
+
}
|
|
22
|
+
const runSlack = config.surfaces.slack.enabled && !opts.httpOnly;
|
|
23
|
+
const runHttp = config.surfaces.http.enabled && !opts.slackOnly;
|
|
24
|
+
const shutdownHandlers = [];
|
|
25
|
+
if (runHttp) {
|
|
26
|
+
const app = await startHttpServer({
|
|
27
|
+
config,
|
|
28
|
+
env,
|
|
29
|
+
logger,
|
|
30
|
+
public_base_url: opts.publicBaseUrl || undefined,
|
|
31
|
+
});
|
|
32
|
+
shutdownHandlers.push(async () => { await app.close(); });
|
|
33
|
+
}
|
|
34
|
+
if (runSlack) {
|
|
35
|
+
const app = await startSlackServer({ config, env, logger });
|
|
36
|
+
shutdownHandlers.push(async () => { await app.stop(); });
|
|
37
|
+
}
|
|
38
|
+
if (!runHttp && !runSlack) {
|
|
39
|
+
logger.warn('serve.nothing_enabled');
|
|
40
|
+
process.exit(0);
|
|
41
|
+
}
|
|
42
|
+
const shutdown = async (sig) => {
|
|
43
|
+
logger.info('serve.shutdown', { sig });
|
|
44
|
+
await Promise.allSettled(shutdownHandlers.map((h) => h()));
|
|
45
|
+
process.exit(0);
|
|
46
|
+
};
|
|
47
|
+
process.on('SIGINT', () => void shutdown('SIGINT'));
|
|
48
|
+
process.on('SIGTERM', () => void shutdown('SIGTERM'));
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../../src/cli/commands/serve.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { listInstances } from '../../instances.js';
|
|
3
|
+
export function updateCmd(program) {
|
|
4
|
+
program
|
|
5
|
+
.command('update')
|
|
6
|
+
.description('Pull the latest prism version from npm and restart all installed services.')
|
|
7
|
+
.option('--no-restart', 'skip restarting systemd services')
|
|
8
|
+
.option('--version <ver>', 'specific version to install', 'latest')
|
|
9
|
+
.action((opts) => {
|
|
10
|
+
const target = `prism@${opts.version}`;
|
|
11
|
+
process.stderr.write(`[prism] installing ${target}...\n`);
|
|
12
|
+
const install = spawnSync('npm', ['install', '-g', target], { stdio: 'inherit' });
|
|
13
|
+
if (install.status !== 0) {
|
|
14
|
+
process.stderr.write(`[prism] npm install failed\n`);
|
|
15
|
+
process.exit(install.status ?? 1);
|
|
16
|
+
}
|
|
17
|
+
if (!opts.restart)
|
|
18
|
+
return;
|
|
19
|
+
if (process.platform !== 'linux') {
|
|
20
|
+
process.stderr.write(`[prism] skipping service restart (not Linux)\n`);
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const instances = listInstances();
|
|
24
|
+
if (instances.length === 0) {
|
|
25
|
+
process.stderr.write(`[prism] no instances configured, nothing to restart\n`);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
for (const inst of instances) {
|
|
29
|
+
const unit = `prism@${inst}.service`;
|
|
30
|
+
process.stderr.write(`[prism] restarting ${unit}...\n`);
|
|
31
|
+
const r = spawnSync('systemctl', ['--user', 'restart', unit], { stdio: 'inherit' });
|
|
32
|
+
if (r.status !== 0) {
|
|
33
|
+
process.stderr.write(`[prism] failed to restart ${unit} (continuing)\n`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=update.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/cli/commands/update.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,UAAU,SAAS,CAAC,OAAgB;IACxC,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,4EAA4E,CAAC;SACzF,MAAM,CAAC,cAAc,EAAE,kCAAkC,CAAC;SAC1D,MAAM,CAAC,iBAAiB,EAAE,6BAA6B,EAAE,QAAQ,CAAC;SAClE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,SAAS,IAAI,CAAC,OAAO,EAAE,CAAC;QACvC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,MAAM,OAAO,CAAC,CAAC;QAC1D,MAAM,OAAO,GAAG,SAAS,CAAC,KAAK,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;QAClF,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;YACrD,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC;QACpC,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAE1B,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACjC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;YACvE,OAAO;QACT,CAAC;QAED,MAAM,SAAS,GAAG,aAAa,EAAE,CAAC;QAClC,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;YAC9E,OAAO;QACT,CAAC;QAED,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,SAAS,IAAI,UAAU,CAAC;YACrC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sBAAsB,IAAI,OAAO,CAAC,CAAC;YACxD,MAAM,CAAC,GAAG,SAAS,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YACpF,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,6BAA6B,IAAI,iBAAiB,CAAC,CAAC;YAC3E,CAAC;QACH,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Command } from 'commander';
|
|
3
|
+
import { readFileSync } from 'node:fs';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { dirname, resolve } from 'node:path';
|
|
6
|
+
import { generateCmd } from './commands/generate.js';
|
|
7
|
+
import { onboardCmd } from './commands/onboard.js';
|
|
8
|
+
import { doctorCmd } from './commands/doctor.js';
|
|
9
|
+
import { serveCmd } from './commands/serve.js';
|
|
10
|
+
import { updateCmd } from './commands/update.js';
|
|
11
|
+
import { daemonCmd } from './commands/daemon.js';
|
|
12
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const pkg = JSON.parse(readFileSync(resolve(here, '..', '..', 'package.json'), 'utf8'));
|
|
14
|
+
const program = new Command();
|
|
15
|
+
program
|
|
16
|
+
.name('prism')
|
|
17
|
+
.description('Thin connector around Claude Code: Slack/HTTP/CLI surfaces that ship the files Claude creates.')
|
|
18
|
+
.version(pkg.version);
|
|
19
|
+
generateCmd(program);
|
|
20
|
+
serveCmd(program);
|
|
21
|
+
onboardCmd(program);
|
|
22
|
+
doctorCmd(program);
|
|
23
|
+
daemonCmd(program);
|
|
24
|
+
updateCmd(program);
|
|
25
|
+
program.parseAsync(process.argv).catch((err) => {
|
|
26
|
+
console.error(err instanceof Error ? err.message : String(err));
|
|
27
|
+
process.exit(1);
|
|
28
|
+
});
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AAEjD,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AACrD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAwB,CAAC;AAE/G,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,OAAO,CAAC;KACb,WAAW,CAAC,gGAAgG,CAAC;KAC7G,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAExB,WAAW,CAAC,OAAO,CAAC,CAAC;AACrB,QAAQ,CAAC,OAAO,CAAC,CAAC;AAClB,UAAU,CAAC,OAAO,CAAC,CAAC;AACpB,SAAS,CAAC,OAAO,CAAC,CAAC;AACnB,SAAS,CAAC,OAAO,CAAC,CAAC;AACnB,SAAS,CAAC,OAAO,CAAC,CAAC;AAEnB,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC7C,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface PrismConfig {
|
|
2
|
+
instance: string;
|
|
3
|
+
surfaces: {
|
|
4
|
+
slack: {
|
|
5
|
+
enabled: boolean;
|
|
6
|
+
allowlist_channels?: string[];
|
|
7
|
+
};
|
|
8
|
+
http: {
|
|
9
|
+
enabled: boolean;
|
|
10
|
+
bind: string;
|
|
11
|
+
port: number;
|
|
12
|
+
};
|
|
13
|
+
cli: {
|
|
14
|
+
enabled: boolean;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
claude: {
|
|
18
|
+
bin: string;
|
|
19
|
+
timeout_ms: number;
|
|
20
|
+
workdir_root: string;
|
|
21
|
+
};
|
|
22
|
+
artifacts: {
|
|
23
|
+
retention_days: number;
|
|
24
|
+
dir?: string;
|
|
25
|
+
};
|
|
26
|
+
logging: {
|
|
27
|
+
level: 'debug' | 'info' | 'warn' | 'error';
|
|
28
|
+
decision_log: boolean;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export declare function defaultConfig(instance?: string): PrismConfig;
|
|
32
|
+
export declare function instanceRoot(instance?: string): string;
|
|
33
|
+
export declare function loadConfig(instance?: string): PrismConfig;
|
|
34
|
+
export declare function loadEnvFile(instance?: string): Record<string, string>;
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { parse as parseYaml } from 'yaml';
|
|
5
|
+
export function defaultConfig(instance = 'default') {
|
|
6
|
+
return {
|
|
7
|
+
instance,
|
|
8
|
+
surfaces: {
|
|
9
|
+
slack: { enabled: false, allowlist_channels: [] },
|
|
10
|
+
http: { enabled: true, bind: '127.0.0.1', port: 18790 },
|
|
11
|
+
cli: { enabled: true },
|
|
12
|
+
},
|
|
13
|
+
claude: {
|
|
14
|
+
bin: 'claude',
|
|
15
|
+
timeout_ms: 600_000,
|
|
16
|
+
workdir_root: '/tmp',
|
|
17
|
+
},
|
|
18
|
+
artifacts: {
|
|
19
|
+
retention_days: 7,
|
|
20
|
+
},
|
|
21
|
+
logging: {
|
|
22
|
+
level: 'info',
|
|
23
|
+
decision_log: true,
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export function instanceRoot(instance = 'default') {
|
|
28
|
+
return join(homedir(), '.prism', 'instances', instance);
|
|
29
|
+
}
|
|
30
|
+
export function loadConfig(instance = 'default') {
|
|
31
|
+
const root = instanceRoot(instance);
|
|
32
|
+
const configPath = join(root, 'config.yaml');
|
|
33
|
+
const base = defaultConfig(instance);
|
|
34
|
+
if (!existsSync(configPath))
|
|
35
|
+
return base;
|
|
36
|
+
const raw = readFileSync(configPath, 'utf8');
|
|
37
|
+
const parsed = parseYaml(raw);
|
|
38
|
+
if (!parsed)
|
|
39
|
+
return base;
|
|
40
|
+
return mergeDeep(base, parsed);
|
|
41
|
+
}
|
|
42
|
+
export function loadEnvFile(instance = 'default') {
|
|
43
|
+
const path = join(instanceRoot(instance), '.env');
|
|
44
|
+
if (!existsSync(path))
|
|
45
|
+
return {};
|
|
46
|
+
const out = {};
|
|
47
|
+
for (const line of readFileSync(path, 'utf8').split(/\r?\n/)) {
|
|
48
|
+
const trimmed = line.trim();
|
|
49
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
50
|
+
continue;
|
|
51
|
+
const eq = trimmed.indexOf('=');
|
|
52
|
+
if (eq < 0)
|
|
53
|
+
continue;
|
|
54
|
+
const key = trimmed.slice(0, eq).trim();
|
|
55
|
+
let val = trimmed.slice(eq + 1).trim();
|
|
56
|
+
if ((val.startsWith('"') && val.endsWith('"')) ||
|
|
57
|
+
(val.startsWith("'") && val.endsWith("'"))) {
|
|
58
|
+
val = val.slice(1, -1);
|
|
59
|
+
}
|
|
60
|
+
out[key] = val;
|
|
61
|
+
}
|
|
62
|
+
return out;
|
|
63
|
+
}
|
|
64
|
+
function mergeDeep(base, override) {
|
|
65
|
+
if (override == null)
|
|
66
|
+
return base;
|
|
67
|
+
if (typeof base !== 'object' || typeof override !== 'object') {
|
|
68
|
+
return override ?? base;
|
|
69
|
+
}
|
|
70
|
+
const out = { ...base };
|
|
71
|
+
for (const [key, value] of Object.entries(override)) {
|
|
72
|
+
if (value == null)
|
|
73
|
+
continue;
|
|
74
|
+
const baseVal = base[key];
|
|
75
|
+
if (typeof baseVal === 'object' &&
|
|
76
|
+
baseVal !== null &&
|
|
77
|
+
!Array.isArray(baseVal) &&
|
|
78
|
+
typeof value === 'object' &&
|
|
79
|
+
!Array.isArray(value)) {
|
|
80
|
+
out[key] = mergeDeep(baseVal, value);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
out[key] = value;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return out;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/daemon.d.ts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare function userSystemdDir(): string;
|
|
2
|
+
export declare function unitName(instance: string): string;
|
|
3
|
+
export declare function unitPath(): string;
|
|
4
|
+
export declare function renderUnit(prismBin: string): string;
|
|
5
|
+
export declare function installUnit(prismBin: string): string;
|
|
6
|
+
export declare function uninstallUnit(): void;
|
|
7
|
+
export declare function ensureInstancePaths(instance: string): void;
|
|
8
|
+
export declare function systemctl(args: string[], opts?: {
|
|
9
|
+
check?: boolean;
|
|
10
|
+
}): {
|
|
11
|
+
status: number;
|
|
12
|
+
stdout: string;
|
|
13
|
+
stderr: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function detectPrismBin(): string;
|
|
16
|
+
export declare function claudeAvailable(bin?: string): boolean;
|
package/dist/daemon.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { execFileSync, spawnSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, unlinkSync } from 'node:fs';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { dirname, join, resolve } from 'node:path';
|
|
5
|
+
import { fileURLToPath } from 'node:url';
|
|
6
|
+
import { instanceRoot } from './config.js';
|
|
7
|
+
import { instancesRoot } from './instances.js';
|
|
8
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
// dist/daemon.js -> ../assets/systemd/prism@.service relative to package root
|
|
10
|
+
const TEMPLATE_PATH = resolve(here, '..', 'assets', 'systemd', 'prism@.service');
|
|
11
|
+
export function userSystemdDir() {
|
|
12
|
+
return join(homedir(), '.config', 'systemd', 'user');
|
|
13
|
+
}
|
|
14
|
+
export function unitName(instance) {
|
|
15
|
+
return `prism@${instance}.service`;
|
|
16
|
+
}
|
|
17
|
+
export function unitPath() {
|
|
18
|
+
return join(userSystemdDir(), 'prism@.service');
|
|
19
|
+
}
|
|
20
|
+
export function renderUnit(prismBin) {
|
|
21
|
+
const tmpl = readFileSync(TEMPLATE_PATH, 'utf8');
|
|
22
|
+
return tmpl
|
|
23
|
+
.replaceAll('__PRISM_BIN__', prismBin)
|
|
24
|
+
.replaceAll('__HOME__', homedir())
|
|
25
|
+
.replaceAll('__INSTANCE_DIR__', instancesRoot());
|
|
26
|
+
}
|
|
27
|
+
export function installUnit(prismBin) {
|
|
28
|
+
const dir = userSystemdDir();
|
|
29
|
+
mkdirSync(dir, { recursive: true });
|
|
30
|
+
const path = unitPath();
|
|
31
|
+
writeFileSync(path, renderUnit(prismBin), 'utf8');
|
|
32
|
+
systemctl(['daemon-reload']);
|
|
33
|
+
return path;
|
|
34
|
+
}
|
|
35
|
+
export function uninstallUnit() {
|
|
36
|
+
const path = unitPath();
|
|
37
|
+
if (existsSync(path))
|
|
38
|
+
unlinkSync(path);
|
|
39
|
+
systemctl(['daemon-reload']);
|
|
40
|
+
}
|
|
41
|
+
export function ensureInstancePaths(instance) {
|
|
42
|
+
const root = instanceRoot(instance);
|
|
43
|
+
if (!existsSync(root)) {
|
|
44
|
+
throw new Error(`instance ${instance} not found at ${root} — run 'prism onboard' first`);
|
|
45
|
+
}
|
|
46
|
+
mkdirSync(join(root, 'logs'), { recursive: true });
|
|
47
|
+
mkdirSync(join(root, 'artifacts'), { recursive: true });
|
|
48
|
+
}
|
|
49
|
+
export function systemctl(args, opts = {}) {
|
|
50
|
+
const r = spawnSync('systemctl', ['--user', ...args], { encoding: 'utf8' });
|
|
51
|
+
if (opts.check && r.status !== 0) {
|
|
52
|
+
throw new Error(`systemctl --user ${args.join(' ')} failed: ${r.stderr || r.stdout}`);
|
|
53
|
+
}
|
|
54
|
+
return { status: r.status ?? -1, stdout: r.stdout ?? '', stderr: r.stderr ?? '' };
|
|
55
|
+
}
|
|
56
|
+
export function detectPrismBin() {
|
|
57
|
+
const which = spawnSync(process.platform === 'win32' ? 'where' : 'which', ['prism'], { encoding: 'utf8' });
|
|
58
|
+
if (which.status === 0 && which.stdout.trim()) {
|
|
59
|
+
return which.stdout.trim().split(/\r?\n/)[0];
|
|
60
|
+
}
|
|
61
|
+
return 'prism';
|
|
62
|
+
}
|
|
63
|
+
export function claudeAvailable(bin = 'claude') {
|
|
64
|
+
try {
|
|
65
|
+
execFileSync(bin, ['--version'], { stdio: 'ignore' });
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../src/daemon.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
2
|
+
import { homedir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
export function instancesRoot() {
|
|
5
|
+
return join(homedir(), '.prism', 'instances');
|
|
6
|
+
}
|
|
7
|
+
export function listInstances() {
|
|
8
|
+
const root = instancesRoot();
|
|
9
|
+
if (!existsSync(root))
|
|
10
|
+
return [];
|
|
11
|
+
return readdirSync(root, { withFileTypes: true })
|
|
12
|
+
.filter((d) => d.isDirectory())
|
|
13
|
+
.map((d) => d.name)
|
|
14
|
+
.sort();
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=instances.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instances.js","sourceRoot":"","sources":["../src/instances.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,MAAM,UAAU,aAAa;IAC3B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,IAAI,GAAG,aAAa,EAAE,CAAC;IAC7B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,OAAO,WAAW,CAAC,IAAI,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC;SAC9C,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SAC9B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAClB,IAAI,EAAE,CAAC;AACZ,CAAC"}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
type Level = 'debug' | 'info' | 'warn' | 'error';
|
|
2
|
+
export interface Logger {
|
|
3
|
+
debug: (msg: string, extra?: Record<string, unknown>) => void;
|
|
4
|
+
info: (msg: string, extra?: Record<string, unknown>) => void;
|
|
5
|
+
warn: (msg: string, extra?: Record<string, unknown>) => void;
|
|
6
|
+
error: (msg: string, extra?: Record<string, unknown>) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function createLogger(level?: Level): Logger;
|
|
9
|
+
export {};
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
const LEVELS = { debug: 10, info: 20, warn: 30, error: 40 };
|
|
2
|
+
export function createLogger(level = 'info') {
|
|
3
|
+
const threshold = LEVELS[level] ?? LEVELS.info;
|
|
4
|
+
function emit(at, msg, extra) {
|
|
5
|
+
if (LEVELS[at] < threshold)
|
|
6
|
+
return;
|
|
7
|
+
const line = {
|
|
8
|
+
ts: new Date().toISOString(),
|
|
9
|
+
level: at,
|
|
10
|
+
msg,
|
|
11
|
+
...(extra ?? {}),
|
|
12
|
+
};
|
|
13
|
+
const stream = at === 'error' || at === 'warn' ? process.stderr : process.stdout;
|
|
14
|
+
stream.write(JSON.stringify(line) + '\n');
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
debug: (msg, extra) => emit('debug', msg, extra),
|
|
18
|
+
info: (msg, extra) => emit('info', msg, extra),
|
|
19
|
+
warn: (msg, extra) => emit('warn', msg, extra),
|
|
20
|
+
error: (msg, extra) => emit('error', msg, extra),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,GAA0B,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;AASnF,MAAM,UAAU,YAAY,CAAC,QAAe,MAAM;IAChD,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC;IAC/C,SAAS,IAAI,CAAC,EAAS,EAAE,GAAW,EAAE,KAA+B;QACnE,IAAI,MAAM,CAAC,EAAE,CAAC,GAAG,SAAS;YAAE,OAAO;QACnC,MAAM,IAAI,GAAG;YACX,EAAE,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YAC5B,KAAK,EAAE,EAAE;YACT,GAAG;YACH,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;SACjB,CAAC;QACF,MAAM,MAAM,GAAG,EAAE,KAAK,OAAO,IAAI,EAAE,KAAK,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;QACjF,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC;IAC5C,CAAC;IACD,OAAO;QACL,KAAK,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC;QAChD,IAAI,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC;QAC9C,IAAI,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,CAAC;QAC9C,KAAK,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC;KACjD,CAAC;AACJ,CAAC"}
|
package/dist/runner.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
export interface RunOptions {
|
|
2
|
+
brief: string;
|
|
3
|
+
workdir?: string;
|
|
4
|
+
timeout_ms?: number;
|
|
5
|
+
claude_bin?: string;
|
|
6
|
+
env?: NodeJS.ProcessEnv;
|
|
7
|
+
on_stdout?: (chunk: string) => void;
|
|
8
|
+
on_stderr?: (chunk: string) => void;
|
|
9
|
+
}
|
|
10
|
+
export interface RunResult {
|
|
11
|
+
text: string;
|
|
12
|
+
files: string[];
|
|
13
|
+
stderr: string;
|
|
14
|
+
exit_code: number;
|
|
15
|
+
workdir: string;
|
|
16
|
+
duration_ms: number;
|
|
17
|
+
timed_out: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare function generate(opts: RunOptions): Promise<RunResult>;
|
package/dist/runner.js
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
import { mkdtempSync, readdirSync, statSync, existsSync } from 'node:fs';
|
|
3
|
+
import { tmpdir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
const DEFAULT_TIMEOUT_MS = 10 * 60 * 1000;
|
|
6
|
+
export async function generate(opts) {
|
|
7
|
+
const workdir = opts.workdir ?? mkdtempSync(join(tmpdir(), 'prism-'));
|
|
8
|
+
const before = snapshotMtimes(workdir);
|
|
9
|
+
const claude_bin = opts.claude_bin ?? process.env.CLAUDE_BIN ?? 'claude';
|
|
10
|
+
const timeout_ms = opts.timeout_ms ?? DEFAULT_TIMEOUT_MS;
|
|
11
|
+
const start = Date.now();
|
|
12
|
+
return new Promise((resolve, reject) => {
|
|
13
|
+
const child = spawn(claude_bin, ['-p', opts.brief, '--dangerously-skip-permissions'], {
|
|
14
|
+
cwd: workdir,
|
|
15
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
16
|
+
env: { ...process.env, ...opts.env },
|
|
17
|
+
});
|
|
18
|
+
let stdout = '';
|
|
19
|
+
let stderr = '';
|
|
20
|
+
let timed_out = false;
|
|
21
|
+
child.stdout.on('data', (chunk) => {
|
|
22
|
+
const text = chunk.toString('utf8');
|
|
23
|
+
stdout += text;
|
|
24
|
+
opts.on_stdout?.(text);
|
|
25
|
+
});
|
|
26
|
+
child.stderr.on('data', (chunk) => {
|
|
27
|
+
const text = chunk.toString('utf8');
|
|
28
|
+
stderr += text;
|
|
29
|
+
opts.on_stderr?.(text);
|
|
30
|
+
});
|
|
31
|
+
const timer = setTimeout(() => {
|
|
32
|
+
timed_out = true;
|
|
33
|
+
child.kill('SIGTERM');
|
|
34
|
+
setTimeout(() => {
|
|
35
|
+
if (!child.killed)
|
|
36
|
+
child.kill('SIGKILL');
|
|
37
|
+
}, 5_000);
|
|
38
|
+
}, timeout_ms);
|
|
39
|
+
child.on('error', (err) => {
|
|
40
|
+
clearTimeout(timer);
|
|
41
|
+
reject(err);
|
|
42
|
+
});
|
|
43
|
+
child.on('exit', (code) => {
|
|
44
|
+
clearTimeout(timer);
|
|
45
|
+
const after = snapshotMtimes(workdir);
|
|
46
|
+
const files = [];
|
|
47
|
+
for (const [path, mtime] of after) {
|
|
48
|
+
const prev = before.get(path);
|
|
49
|
+
if (prev == null || mtime > prev)
|
|
50
|
+
files.push(path);
|
|
51
|
+
}
|
|
52
|
+
files.sort();
|
|
53
|
+
resolve({
|
|
54
|
+
text: stdout.trim(),
|
|
55
|
+
files,
|
|
56
|
+
stderr,
|
|
57
|
+
exit_code: code ?? -1,
|
|
58
|
+
workdir,
|
|
59
|
+
duration_ms: Date.now() - start,
|
|
60
|
+
timed_out,
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
function snapshotMtimes(dir) {
|
|
66
|
+
const map = new Map();
|
|
67
|
+
if (!existsSync(dir))
|
|
68
|
+
return map;
|
|
69
|
+
let entries;
|
|
70
|
+
try {
|
|
71
|
+
entries = readdirSync(dir, { recursive: true });
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
return map;
|
|
75
|
+
}
|
|
76
|
+
for (const name of entries) {
|
|
77
|
+
const full = join(dir, name);
|
|
78
|
+
try {
|
|
79
|
+
const st = statSync(full);
|
|
80
|
+
if (st.isFile())
|
|
81
|
+
map.set(full, st.mtimeMs);
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// unreadable entry — skip
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return map;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type FastifyInstance } from 'fastify';
|
|
2
|
+
import type { PrismConfig } from '../config.js';
|
|
3
|
+
import type { Logger } from '../logger.js';
|
|
4
|
+
export interface HttpServerOptions {
|
|
5
|
+
config: PrismConfig;
|
|
6
|
+
env: Record<string, string>;
|
|
7
|
+
logger: Logger;
|
|
8
|
+
api_key?: string;
|
|
9
|
+
public_base_url?: string;
|
|
10
|
+
}
|
|
11
|
+
export declare function createHttpServer(opts: HttpServerOptions): Promise<FastifyInstance>;
|
|
12
|
+
export declare function startHttpServer(opts: HttpServerOptions): Promise<FastifyInstance>;
|