@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
package/README.md
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Prism
|
|
2
|
+
|
|
3
|
+
> **Mnemos remembers. Prism delivers.**
|
|
4
|
+
|
|
5
|
+
Prism is a thin connector around [Claude Code](https://claude.com/claude-code). It listens for a request (Slack mention, HTTP call, or CLI invocation), spawns `claude -p "<prompt>"` in a working directory that has the right skills available, lets Claude do its job (query the brain, look up brand tokens, generate the artifact), then ships the output files back to the caller.
|
|
6
|
+
|
|
7
|
+
That's the whole product. No custom LLM client. No custom skill format. No custom brain client.
|
|
8
|
+
|
|
9
|
+
## Architecture
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
surfaces runner
|
|
13
|
+
┌────────────┐ ┌──────────────────────┐
|
|
14
|
+
│ Slack bot │────┐ │ │
|
|
15
|
+
├────────────┤ │ │ spawn 'claude -p' │
|
|
16
|
+
│ POST /api/ │────┼───▶│ in temp workdir │
|
|
17
|
+
│ generate │ │ │ │
|
|
18
|
+
├────────────┤ │ │ capture new files │
|
|
19
|
+
│ CLI │────┘ │ in cwd after exit │
|
|
20
|
+
└────────────┘ └──────────────────────┘
|
|
21
|
+
│
|
|
22
|
+
▼
|
|
23
|
+
Claude Code (the LLM)
|
|
24
|
+
│
|
|
25
|
+
~/.claude/skills/:
|
|
26
|
+
├─ ask-mnemos-astry
|
|
27
|
+
├─ astry-design-system
|
|
28
|
+
├─ astry-pdf
|
|
29
|
+
└─ ...
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Install
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npm install -g prism
|
|
36
|
+
prism onboard
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
`prism onboard` walks through:
|
|
40
|
+
|
|
41
|
+
- Picking an instance name
|
|
42
|
+
- Slack Socket Mode tokens (optional)
|
|
43
|
+
- HTTP API key (optional)
|
|
44
|
+
- Brain endpoint + key (read by `ask-mnemos-astry` skill)
|
|
45
|
+
- Verifying `claude` is on `PATH` and authenticated
|
|
46
|
+
|
|
47
|
+
## Usage
|
|
48
|
+
|
|
49
|
+
### CLI
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
prism generate "fais un PDF récap du meeting Endemol" --out ./
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### HTTP
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
curl -X POST http://localhost:18790/api/generate \
|
|
59
|
+
-H "Authorization: Bearer prism_live_..." \
|
|
60
|
+
-H "Content-Type: application/json" \
|
|
61
|
+
-d '{"brief": "fais un récap du meeting Endemol kickoff du 6 mai"}'
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Slack
|
|
65
|
+
|
|
66
|
+
Mention `@prism` in any channel the bot has access to:
|
|
67
|
+
|
|
68
|
+
```
|
|
69
|
+
@prism fais-moi un PDF du meeting Endemol de ce matin
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Required skills (operator install)
|
|
73
|
+
|
|
74
|
+
Prism does not ship skills. The operator installs them under the user that runs Prism:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
ls ~/.claude/skills/
|
|
78
|
+
# ask-mnemos-astry/
|
|
79
|
+
# astry-design-system/
|
|
80
|
+
# astry-pdf/
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
`prism doctor` reports which expected skills are missing.
|
|
84
|
+
|
|
85
|
+
## License
|
|
86
|
+
|
|
87
|
+
UNLICENSED — internal Astry tooling.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
[Unit]
|
|
2
|
+
Description=Prism agent (instance %i)
|
|
3
|
+
After=network-online.target
|
|
4
|
+
Wants=network-online.target
|
|
5
|
+
|
|
6
|
+
[Service]
|
|
7
|
+
Type=simple
|
|
8
|
+
ExecStart=__PRISM_BIN__ serve -i %i
|
|
9
|
+
Restart=on-failure
|
|
10
|
+
RestartSec=5s
|
|
11
|
+
KillSignal=SIGTERM
|
|
12
|
+
TimeoutStopSec=30s
|
|
13
|
+
Environment=NODE_ENV=production
|
|
14
|
+
Environment=PRISM_INSTANCE=%i
|
|
15
|
+
# claude requires a writable HOME and access to ~/.claude
|
|
16
|
+
Environment=HOME=__HOME__
|
|
17
|
+
StandardOutput=append:__INSTANCE_DIR__/%i/logs/prism.log
|
|
18
|
+
StandardError=append:__INSTANCE_DIR__/%i/logs/prism.err.log
|
|
19
|
+
|
|
20
|
+
[Install]
|
|
21
|
+
WantedBy=default.target
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface ArtifactRecord {
|
|
2
|
+
filename: string;
|
|
3
|
+
path: string;
|
|
4
|
+
size_bytes: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function artifactsRoot(instance: string, override?: string): string;
|
|
7
|
+
export declare function persistArtifacts(instance: string, jobId: string, files: string[], override?: string): ArtifactRecord[];
|
|
8
|
+
export declare function pruneArtifacts(instance: string, retentionDays: number, override?: string): number;
|
|
9
|
+
export declare function mimeTypeFor(filename: string): string;
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, readdirSync, rmSync, statSync } from 'node:fs';
|
|
2
|
+
import { join, basename } from 'node:path';
|
|
3
|
+
import { instanceRoot } from './config.js';
|
|
4
|
+
export function artifactsRoot(instance, override) {
|
|
5
|
+
return override ?? join(instanceRoot(instance), 'artifacts');
|
|
6
|
+
}
|
|
7
|
+
export function persistArtifacts(instance, jobId, files, override) {
|
|
8
|
+
const root = artifactsRoot(instance, override);
|
|
9
|
+
const dir = join(root, jobId);
|
|
10
|
+
mkdirSync(dir, { recursive: true });
|
|
11
|
+
const out = [];
|
|
12
|
+
for (const src of files) {
|
|
13
|
+
if (!existsSync(src))
|
|
14
|
+
continue;
|
|
15
|
+
const name = uniqueName(dir, basename(src));
|
|
16
|
+
const dst = join(dir, name);
|
|
17
|
+
copyFileSync(src, dst);
|
|
18
|
+
out.push({ filename: name, path: dst, size_bytes: statSync(dst).size });
|
|
19
|
+
}
|
|
20
|
+
return out;
|
|
21
|
+
}
|
|
22
|
+
export function pruneArtifacts(instance, retentionDays, override) {
|
|
23
|
+
const root = artifactsRoot(instance, override);
|
|
24
|
+
if (!existsSync(root))
|
|
25
|
+
return 0;
|
|
26
|
+
const cutoff = Date.now() - retentionDays * 24 * 60 * 60 * 1000;
|
|
27
|
+
let removed = 0;
|
|
28
|
+
for (const name of readdirSync(root)) {
|
|
29
|
+
const full = join(root, name);
|
|
30
|
+
try {
|
|
31
|
+
const st = statSync(full);
|
|
32
|
+
if (st.mtimeMs < cutoff) {
|
|
33
|
+
rmSync(full, { recursive: true, force: true });
|
|
34
|
+
removed += 1;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
catch {
|
|
38
|
+
// ignore
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
return removed;
|
|
42
|
+
}
|
|
43
|
+
function uniqueName(dir, name) {
|
|
44
|
+
if (!existsSync(join(dir, name)))
|
|
45
|
+
return name;
|
|
46
|
+
const dot = name.lastIndexOf('.');
|
|
47
|
+
const stem = dot > 0 ? name.slice(0, dot) : name;
|
|
48
|
+
const ext = dot > 0 ? name.slice(dot) : '';
|
|
49
|
+
let i = 1;
|
|
50
|
+
while (existsSync(join(dir, `${stem}-${i}${ext}`)))
|
|
51
|
+
i += 1;
|
|
52
|
+
return `${stem}-${i}${ext}`;
|
|
53
|
+
}
|
|
54
|
+
export function mimeTypeFor(filename) {
|
|
55
|
+
const ext = filename.toLowerCase().split('.').pop() ?? '';
|
|
56
|
+
const map = {
|
|
57
|
+
pdf: 'application/pdf',
|
|
58
|
+
png: 'image/png',
|
|
59
|
+
jpg: 'image/jpeg',
|
|
60
|
+
jpeg: 'image/jpeg',
|
|
61
|
+
gif: 'image/gif',
|
|
62
|
+
svg: 'image/svg+xml',
|
|
63
|
+
webp: 'image/webp',
|
|
64
|
+
txt: 'text/plain',
|
|
65
|
+
md: 'text/markdown',
|
|
66
|
+
html: 'text/html',
|
|
67
|
+
htm: 'text/html',
|
|
68
|
+
json: 'application/json',
|
|
69
|
+
csv: 'text/csv',
|
|
70
|
+
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
|
71
|
+
xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
|
|
72
|
+
pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
|
73
|
+
zip: 'application/zip',
|
|
74
|
+
};
|
|
75
|
+
return map[ext] ?? 'application/octet-stream';
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=artifacts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"artifacts.js","sourceRoot":"","sources":["../src/artifacts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { detectPrismBin, ensureInstancePaths, installUnit, systemctl, uninstallUnit, unitName, unitPath } from '../../daemon.js';
|
|
3
|
+
import { listInstances } from '../../instances.js';
|
|
4
|
+
export function daemonCmd(program) {
|
|
5
|
+
const daemon = program
|
|
6
|
+
.command('daemon')
|
|
7
|
+
.description('Manage the systemd user service for prism instances (Linux only).');
|
|
8
|
+
daemon
|
|
9
|
+
.command('install')
|
|
10
|
+
.description('Render prism@.service into ~/.config/systemd/user and enable+start the instance.')
|
|
11
|
+
.option('-i, --instance <name>', 'instance to enable+start', 'default')
|
|
12
|
+
.option('--prism-bin <path>', 'override the prism binary path')
|
|
13
|
+
.option('--no-start', 'install the unit without starting it')
|
|
14
|
+
.action((opts) => {
|
|
15
|
+
assertLinux();
|
|
16
|
+
ensureInstancePaths(opts.instance);
|
|
17
|
+
const bin = opts.prismBin ?? detectPrismBin();
|
|
18
|
+
const path = installUnit(bin);
|
|
19
|
+
console.error(`✓ unit installed: ${path}`);
|
|
20
|
+
const unit = unitName(opts.instance);
|
|
21
|
+
systemctl(['enable', unit], { check: true });
|
|
22
|
+
console.error(`✓ enabled ${unit}`);
|
|
23
|
+
if (opts.start !== false) {
|
|
24
|
+
systemctl(['restart', unit], { check: true });
|
|
25
|
+
console.error(`✓ started ${unit}`);
|
|
26
|
+
}
|
|
27
|
+
});
|
|
28
|
+
daemon
|
|
29
|
+
.command('start')
|
|
30
|
+
.argument('[instance]', 'instance name', 'default')
|
|
31
|
+
.description('Start (or restart) the prism systemd unit for an instance.')
|
|
32
|
+
.action((instance) => {
|
|
33
|
+
assertLinux();
|
|
34
|
+
systemctl(['restart', unitName(instance)], { check: true });
|
|
35
|
+
console.error(`✓ ${unitName(instance)} restarted`);
|
|
36
|
+
});
|
|
37
|
+
daemon
|
|
38
|
+
.command('stop')
|
|
39
|
+
.argument('[instance]', 'instance name', 'default')
|
|
40
|
+
.description('Stop the prism systemd unit for an instance.')
|
|
41
|
+
.action((instance) => {
|
|
42
|
+
assertLinux();
|
|
43
|
+
systemctl(['stop', unitName(instance)], { check: true });
|
|
44
|
+
console.error(`✓ ${unitName(instance)} stopped`);
|
|
45
|
+
});
|
|
46
|
+
daemon
|
|
47
|
+
.command('status')
|
|
48
|
+
.argument('[instance]', 'instance name (omit for all)')
|
|
49
|
+
.description('Show systemd status for one or all prism instances.')
|
|
50
|
+
.action((instance) => {
|
|
51
|
+
assertLinux();
|
|
52
|
+
const list = instance ? [instance] : listInstances();
|
|
53
|
+
if (list.length === 0) {
|
|
54
|
+
console.error('no instances found');
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
for (const inst of list) {
|
|
58
|
+
const r = systemctl(['status', unitName(inst), '--no-pager']);
|
|
59
|
+
process.stdout.write(`\n=== ${unitName(inst)} ===\n${r.stdout}${r.stderr}`);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
daemon
|
|
63
|
+
.command('logs')
|
|
64
|
+
.argument('[instance]', 'instance name', 'default')
|
|
65
|
+
.option('-f, --follow', 'follow logs')
|
|
66
|
+
.option('-n, --lines <n>', 'number of recent lines', '200')
|
|
67
|
+
.description('Tail journalctl for the prism systemd unit.')
|
|
68
|
+
.action((instance, opts) => {
|
|
69
|
+
assertLinux();
|
|
70
|
+
const args = ['--user', '--user-unit', unitName(instance), '-n', String(opts.lines)];
|
|
71
|
+
if (opts.follow)
|
|
72
|
+
args.push('-f');
|
|
73
|
+
spawnSync('journalctl', args, { stdio: 'inherit' });
|
|
74
|
+
});
|
|
75
|
+
daemon
|
|
76
|
+
.command('uninstall')
|
|
77
|
+
.description('Remove the systemd unit. Existing instance configs/artifacts are kept on disk.')
|
|
78
|
+
.action(() => {
|
|
79
|
+
assertLinux();
|
|
80
|
+
uninstallUnit();
|
|
81
|
+
console.error(`✓ removed ${unitPath()}`);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
function assertLinux() {
|
|
85
|
+
if (process.platform !== 'linux') {
|
|
86
|
+
console.error('error: prism daemon commands require Linux + systemd');
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=daemon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../../src/cli/commands/daemon.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { execFileSync, spawnSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, readdirSync } from 'node:fs';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import { join } from 'node:path';
|
|
5
|
+
import { loadConfig, instanceRoot } from '../../config.js';
|
|
6
|
+
const EXPECTED_SKILLS = ['ask-mnemos-astry', 'astry-design-system', 'astry-pdf'];
|
|
7
|
+
export function doctorCmd(program) {
|
|
8
|
+
program
|
|
9
|
+
.command('doctor')
|
|
10
|
+
.description('Verify claude is installed/authenticated and expected skills are present.')
|
|
11
|
+
.option('-i, --instance <name>', 'prism instance to inspect', 'default')
|
|
12
|
+
.action((opts) => {
|
|
13
|
+
const config = loadConfig(opts.instance);
|
|
14
|
+
let ok = true;
|
|
15
|
+
const root = instanceRoot(opts.instance);
|
|
16
|
+
if (!existsSync(root)) {
|
|
17
|
+
printWarn(`instance directory missing: ${root} (run 'prism onboard' first)`);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
printOk(`instance dir: ${root}`);
|
|
21
|
+
}
|
|
22
|
+
const claudeBin = config.claude.bin;
|
|
23
|
+
const which = spawnSync(process.platform === 'win32' ? 'where' : 'which', [claudeBin], {
|
|
24
|
+
encoding: 'utf8',
|
|
25
|
+
});
|
|
26
|
+
if (which.status !== 0 || !which.stdout.trim()) {
|
|
27
|
+
printErr(`'${claudeBin}' not found on PATH`);
|
|
28
|
+
ok = false;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
printOk(`claude binary: ${which.stdout.trim().split(/\r?\n/)[0]}`);
|
|
32
|
+
try {
|
|
33
|
+
const version = execFileSync(claudeBin, ['--version'], { encoding: 'utf8' }).trim();
|
|
34
|
+
printOk(`claude version: ${version}`);
|
|
35
|
+
}
|
|
36
|
+
catch (err) {
|
|
37
|
+
printWarn(`could not run 'claude --version': ${err.message}`);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const skillsDir = join(homedir(), '.claude', 'skills');
|
|
41
|
+
if (!existsSync(skillsDir)) {
|
|
42
|
+
printErr(`~/.claude/skills missing — claude not authenticated under this user?`);
|
|
43
|
+
ok = false;
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
const installed = new Set(readdirSync(skillsDir, { withFileTypes: true }).filter((d) => d.isDirectory()).map((d) => d.name));
|
|
47
|
+
for (const name of EXPECTED_SKILLS) {
|
|
48
|
+
if (installed.has(name)) {
|
|
49
|
+
printOk(`skill: ${name}`);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
printWarn(`skill missing: ${name} — install at ${join(skillsDir, name)}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
printOk(`config loaded: instance=${config.instance}, http=${config.surfaces.http.enabled}, slack=${config.surfaces.slack.enabled}`);
|
|
57
|
+
if (!ok) {
|
|
58
|
+
process.stderr.write('\nprism doctor: issues detected.\n');
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
process.stderr.write('\nprism doctor: all checks passed.\n');
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
function printOk(msg) { process.stderr.write(`[ok] ${msg}\n`); }
|
|
67
|
+
function printWarn(msg) { process.stderr.write(`[warn] ${msg}\n`); }
|
|
68
|
+
function printErr(msg) { process.stderr.write(`[err] ${msg}\n`); }
|
|
69
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../../src/cli/commands/doctor.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC7D,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;AACjC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE3D,MAAM,eAAe,GAAG,CAAC,kBAAkB,EAAE,qBAAqB,EAAE,WAAW,CAAC,CAAC;AAEjF,MAAM,UAAU,SAAS,CAAC,OAAgB;IACxC,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,2EAA2E,CAAC;SACxF,MAAM,CAAC,uBAAuB,EAAE,2BAA2B,EAAE,SAAS,CAAC;SACvE,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QACf,MAAM,MAAM,GAAG,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,EAAE,GAAG,IAAI,CAAC;QAEd,MAAM,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,SAAS,CAAC,+BAA+B,IAAI,8BAA8B,CAAC,CAAC;QAC/E,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC;QACpC,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,SAAS,CAAC,EAAE;YACrF,QAAQ,EAAE,MAAM;SACjB,CAAC,CAAC;QACH,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YAC/C,QAAQ,CAAC,IAAI,SAAS,qBAAqB,CAAC,CAAC;YAC7C,EAAE,GAAG,KAAK,CAAC;QACb,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,kBAAkB,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YACnE,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,YAAY,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;gBACpF,OAAO,CAAC,mBAAmB,OAAO,EAAE,CAAC,CAAC;YACxC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,SAAS,CAAC,qCAAsC,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YAC3E,CAAC;QACH,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;QACvD,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,QAAQ,CAAC,sEAAsE,CAAC,CAAC;YACjF,EAAE,GAAG,KAAK,CAAC;QACb,CAAC;aAAM,CAAC;YACN,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,SAAS,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YAC7H,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;gBACnC,IAAI,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;oBACxB,OAAO,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC;gBAC5B,CAAC;qBAAM,CAAC;oBACN,SAAS,CAAC,kBAAkB,IAAI,iBAAiB,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC5E,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,CAAC,2BAA2B,MAAM,CAAC,QAAQ,UAAU,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,WAAW,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAEpI,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;YAC3D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,OAAO,CAAC,GAAW,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAC1E,SAAS,SAAS,CAAC,GAAW,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;AAC5E,SAAS,QAAQ,CAAC,GAAW,IAAI,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { copyFileSync, existsSync, mkdirSync, statSync } from 'node:fs';
|
|
2
|
+
import { basename, resolve, join } from 'node:path';
|
|
3
|
+
import { generate } from '../../runner.js';
|
|
4
|
+
import { loadConfig, loadEnvFile } from '../../config.js';
|
|
5
|
+
export function generateCmd(program) {
|
|
6
|
+
program
|
|
7
|
+
.command('generate')
|
|
8
|
+
.description('Run claude -p with the given brief and ship back the files it creates.')
|
|
9
|
+
.argument('<brief...>', 'natural-language brief for claude')
|
|
10
|
+
.option('-o, --out <dir>', 'directory to copy generated files into', process.cwd())
|
|
11
|
+
.option('-i, --instance <name>', 'prism instance to use', 'default')
|
|
12
|
+
.option('--workdir <dir>', 'override the temp workdir (default: fresh tmpdir)')
|
|
13
|
+
.option('--timeout <ms>', 'timeout in ms', (v) => parseInt(v, 10))
|
|
14
|
+
.option('--claude-bin <path>', 'override the claude binary')
|
|
15
|
+
.option('--quiet', 'do not stream stdout to terminal')
|
|
16
|
+
.option('--json', 'emit a JSON summary on stdout instead of human output')
|
|
17
|
+
.action(async (briefParts, opts) => {
|
|
18
|
+
const brief = briefParts.join(' ').trim();
|
|
19
|
+
if (!brief) {
|
|
20
|
+
console.error('error: empty brief');
|
|
21
|
+
process.exit(2);
|
|
22
|
+
}
|
|
23
|
+
const config = loadConfig(opts.instance);
|
|
24
|
+
const env = loadEnvFile(opts.instance);
|
|
25
|
+
const outDir = resolve(opts.out);
|
|
26
|
+
mkdirSync(outDir, { recursive: true });
|
|
27
|
+
const result = await generate({
|
|
28
|
+
brief,
|
|
29
|
+
workdir: opts.workdir,
|
|
30
|
+
timeout_ms: opts.timeout ?? config.claude.timeout_ms,
|
|
31
|
+
claude_bin: opts.claudeBin ?? config.claude.bin,
|
|
32
|
+
env,
|
|
33
|
+
on_stdout: opts.quiet || opts.json ? undefined : (chunk) => process.stdout.write(chunk),
|
|
34
|
+
on_stderr: opts.quiet || opts.json ? undefined : (chunk) => process.stderr.write(chunk),
|
|
35
|
+
});
|
|
36
|
+
const copied = [];
|
|
37
|
+
for (const src of result.files) {
|
|
38
|
+
if (!existsSync(src))
|
|
39
|
+
continue;
|
|
40
|
+
const dst = uniqueDest(outDir, basename(src));
|
|
41
|
+
copyFileSync(src, dst);
|
|
42
|
+
copied.push({ src, dst, size: statSync(dst).size });
|
|
43
|
+
}
|
|
44
|
+
if (opts.json) {
|
|
45
|
+
process.stdout.write(JSON.stringify({
|
|
46
|
+
text: result.text,
|
|
47
|
+
files: copied.map((c) => ({ path: c.dst, size_bytes: c.size })),
|
|
48
|
+
exit_code: result.exit_code,
|
|
49
|
+
duration_ms: result.duration_ms,
|
|
50
|
+
timed_out: result.timed_out,
|
|
51
|
+
workdir: result.workdir,
|
|
52
|
+
}, null, 2) + '\n');
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
if (copied.length === 0) {
|
|
56
|
+
process.stderr.write('\n[prism] no new files created in workdir.\n');
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
process.stderr.write(`\n[prism] ${copied.length} file(s) written to ${outDir}:\n`);
|
|
60
|
+
for (const c of copied) {
|
|
61
|
+
process.stderr.write(` ${c.dst} (${formatSize(c.size)})\n`);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
process.exit(result.exit_code === 0 ? 0 : result.exit_code);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
function uniqueDest(dir, name) {
|
|
69
|
+
let candidate = join(dir, name);
|
|
70
|
+
if (!existsSync(candidate))
|
|
71
|
+
return candidate;
|
|
72
|
+
const dot = name.lastIndexOf('.');
|
|
73
|
+
const stem = dot > 0 ? name.slice(0, dot) : name;
|
|
74
|
+
const ext = dot > 0 ? name.slice(dot) : '';
|
|
75
|
+
let i = 1;
|
|
76
|
+
while (existsSync(candidate)) {
|
|
77
|
+
candidate = join(dir, `${stem}-${i}${ext}`);
|
|
78
|
+
i += 1;
|
|
79
|
+
}
|
|
80
|
+
return candidate;
|
|
81
|
+
}
|
|
82
|
+
function formatSize(bytes) {
|
|
83
|
+
if (bytes < 1024)
|
|
84
|
+
return `${bytes} B`;
|
|
85
|
+
if (bytes < 1024 * 1024)
|
|
86
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
87
|
+
return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import prompts from 'prompts';
|
|
2
|
+
import { existsSync, mkdirSync, writeFileSync, chmodSync } from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { stringify as stringifyYaml } from 'yaml';
|
|
5
|
+
import { defaultConfig, instanceRoot } from '../../config.js';
|
|
6
|
+
export function onboardCmd(program) {
|
|
7
|
+
program
|
|
8
|
+
.command('onboard')
|
|
9
|
+
.description('Interactive wizard to create a new prism instance.')
|
|
10
|
+
.option('-i, --instance <name>', 'instance name (default: prompted)')
|
|
11
|
+
.option('--force', 'overwrite existing instance config')
|
|
12
|
+
.action(async (opts) => {
|
|
13
|
+
const answers = await prompts([
|
|
14
|
+
{
|
|
15
|
+
type: opts.instance ? null : 'text',
|
|
16
|
+
name: 'instance',
|
|
17
|
+
message: 'Instance name',
|
|
18
|
+
initial: 'default',
|
|
19
|
+
validate: (v) => /^[a-z0-9_-]+$/.test(v) ? true : 'lowercase letters, digits, _ or - only',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
type: 'toggle',
|
|
23
|
+
name: 'slack_enabled',
|
|
24
|
+
message: 'Enable the Slack surface?',
|
|
25
|
+
initial: true,
|
|
26
|
+
active: 'yes',
|
|
27
|
+
inactive: 'no',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
type: (_, values) => (values.slack_enabled ? 'password' : null),
|
|
31
|
+
name: 'slack_bot_token',
|
|
32
|
+
message: 'SLACK_BOT_TOKEN (xoxb-...)',
|
|
33
|
+
validate: (v) => v.startsWith('xoxb-') ? true : 'expected xoxb- token',
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
type: (_, values) => (values.slack_enabled ? 'password' : null),
|
|
37
|
+
name: 'slack_app_token',
|
|
38
|
+
message: 'SLACK_APP_TOKEN (xapp-... for Socket Mode)',
|
|
39
|
+
validate: (v) => v.startsWith('xapp-') ? true : 'expected xapp- token',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
type: (_, values) => (values.slack_enabled ? 'text' : null),
|
|
43
|
+
name: 'slack_channels',
|
|
44
|
+
message: 'Allowlist channel IDs (comma-separated, blank = all)',
|
|
45
|
+
initial: '',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
type: 'toggle',
|
|
49
|
+
name: 'http_enabled',
|
|
50
|
+
message: 'Enable the HTTP API?',
|
|
51
|
+
initial: true,
|
|
52
|
+
active: 'yes',
|
|
53
|
+
inactive: 'no',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
type: (_, values) => (values.http_enabled ? 'number' : null),
|
|
57
|
+
name: 'http_port',
|
|
58
|
+
message: 'HTTP port',
|
|
59
|
+
initial: 18790,
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
type: (_, values) => (values.http_enabled ? 'password' : null),
|
|
63
|
+
name: 'http_api_key',
|
|
64
|
+
message: 'HTTP API key (will be required for /api/generate)',
|
|
65
|
+
validate: (v) => v.length >= 16 ? true : 'use at least 16 characters',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
type: 'text',
|
|
69
|
+
name: 'mnemos_brain_url',
|
|
70
|
+
message: 'Mnemos brain URL (read by ask-mnemos-astry skill, blank = skip)',
|
|
71
|
+
initial: 'https://brain.astry.agency',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
type: (_, values) => (values.mnemos_brain_url ? 'password' : null),
|
|
75
|
+
name: 'mnemos_api_key',
|
|
76
|
+
message: 'Mnemos API key (brn_live_...)',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
type: 'text',
|
|
80
|
+
name: 'claude_bin',
|
|
81
|
+
message: "Path to claude binary (or just 'claude' if on PATH)",
|
|
82
|
+
initial: 'claude',
|
|
83
|
+
},
|
|
84
|
+
], { onCancel: () => { process.exit(130); } });
|
|
85
|
+
const instance = opts.instance ?? answers.instance;
|
|
86
|
+
const root = instanceRoot(instance);
|
|
87
|
+
if (existsSync(root) && !opts.force) {
|
|
88
|
+
console.error(`error: ${root} already exists. Use --force to overwrite.`);
|
|
89
|
+
process.exit(1);
|
|
90
|
+
}
|
|
91
|
+
mkdirSync(root, { recursive: true });
|
|
92
|
+
mkdirSync(join(root, 'artifacts'), { recursive: true });
|
|
93
|
+
mkdirSync(join(root, 'logs'), { recursive: true });
|
|
94
|
+
const config = defaultConfig(instance);
|
|
95
|
+
config.surfaces.slack.enabled = !!answers.slack_enabled;
|
|
96
|
+
config.surfaces.slack.allowlist_channels = answers.slack_channels
|
|
97
|
+
? String(answers.slack_channels).split(',').map((s) => s.trim()).filter(Boolean)
|
|
98
|
+
: [];
|
|
99
|
+
config.surfaces.http.enabled = !!answers.http_enabled;
|
|
100
|
+
if (answers.http_port)
|
|
101
|
+
config.surfaces.http.port = Number(answers.http_port);
|
|
102
|
+
config.claude.bin = String(answers.claude_bin);
|
|
103
|
+
const configPath = join(root, 'config.yaml');
|
|
104
|
+
writeFileSync(configPath, stringifyYaml(config), 'utf8');
|
|
105
|
+
const envLines = ['# Prism instance secrets', '# DO NOT commit this file'];
|
|
106
|
+
if (answers.slack_bot_token)
|
|
107
|
+
envLines.push(`SLACK_BOT_TOKEN=${answers.slack_bot_token}`);
|
|
108
|
+
if (answers.slack_app_token)
|
|
109
|
+
envLines.push(`SLACK_APP_TOKEN=${answers.slack_app_token}`);
|
|
110
|
+
if (answers.http_api_key)
|
|
111
|
+
envLines.push(`PRISM_HTTP_API_KEY=${answers.http_api_key}`);
|
|
112
|
+
if (answers.mnemos_brain_url)
|
|
113
|
+
envLines.push(`MNEMOS_BRAIN_URL=${answers.mnemos_brain_url}`);
|
|
114
|
+
if (answers.mnemos_api_key)
|
|
115
|
+
envLines.push(`MNEMOS_API_KEY=${answers.mnemos_api_key}`);
|
|
116
|
+
const envPath = join(root, '.env');
|
|
117
|
+
writeFileSync(envPath, envLines.join('\n') + '\n', { mode: 0o600 });
|
|
118
|
+
try {
|
|
119
|
+
chmodSync(envPath, 0o600);
|
|
120
|
+
}
|
|
121
|
+
catch { /* windows */ }
|
|
122
|
+
console.log(`\n✓ instance "${instance}" written to ${root}`);
|
|
123
|
+
console.log(` config: ${configPath}`);
|
|
124
|
+
console.log(` env: ${envPath}`);
|
|
125
|
+
console.log(`\nNext steps:`);
|
|
126
|
+
console.log(` prism doctor -i ${instance} # verify claude + skills`);
|
|
127
|
+
console.log(` prism serve -i ${instance} # run surfaces in foreground`);
|
|
128
|
+
console.log(` prism daemon install -i ${instance} # install systemd service (Linux)`);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=onboard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboard.js","sourceRoot":"","sources":["../../../src/cli/commands/onboard.ts"],"names":[],"mappings":"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"}
|