prismalens 0.3.0 → 0.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/bin/prismalens.js +39 -50
- package/dist/chunk-2Z7QZSIS.js +20 -0
- package/dist/chunk-5BT3XQOG.js +2990 -0
- package/dist/chunk-6N4PHBII.js +30 -0
- package/dist/chunk-CTKCK7QT.js +387 -0
- package/dist/chunk-CVSS5JPC.js +130 -0
- package/dist/chunk-HPE5CTO4.js +22 -0
- package/dist/chunk-PTBCAI34.js +34 -0
- package/dist/chunk-PVQVFRIV.js +452 -0
- package/dist/chunk-QDK5PAI3.js +155 -0
- package/dist/chunk-SSEIMBQ2.js +204 -0
- package/dist/chunk-TGP6QTFO.js +156 -0
- package/dist/chunk-V6M6ISKI.js +161 -0
- package/dist/chunk-XH6DIKTA.js +83 -0
- package/dist/src/cli/auth.js +112 -101
- package/dist/src/cli/doctor.js +184 -187
- package/dist/src/cli/flags.js +6 -32
- package/dist/src/cli/grouping.js +16 -227
- package/dist/src/cli/init.js +54 -48
- package/dist/src/cli/investigate.js +23 -465
- package/dist/src/cli/listen.js +550 -286
- package/dist/src/cli/report.js +70 -67
- package/dist/src/cli/serve.js +260 -30
- package/dist/src/cli/status.js +87 -86
- package/package.json +16 -7
- package/dist/bin/prismalens.d.ts +0 -3
- package/dist/bin/prismalens.d.ts.map +0 -1
- package/dist/bin/prismalens.js.map +0 -1
- package/dist/src/cli/auth.d.ts +0 -3
- package/dist/src/cli/auth.d.ts.map +0 -1
- package/dist/src/cli/auth.js.map +0 -1
- package/dist/src/cli/doctor.d.ts +0 -18
- package/dist/src/cli/doctor.d.ts.map +0 -1
- package/dist/src/cli/doctor.js.map +0 -1
- package/dist/src/cli/flags.d.ts +0 -2
- package/dist/src/cli/flags.d.ts.map +0 -1
- package/dist/src/cli/flags.js.map +0 -1
- package/dist/src/cli/grouping.d.ts +0 -18
- package/dist/src/cli/grouping.d.ts.map +0 -1
- package/dist/src/cli/grouping.js.map +0 -1
- package/dist/src/cli/init.d.ts +0 -3
- package/dist/src/cli/init.d.ts.map +0 -1
- package/dist/src/cli/init.js.map +0 -1
- package/dist/src/cli/investigate.d.ts +0 -115
- package/dist/src/cli/investigate.d.ts.map +0 -1
- package/dist/src/cli/investigate.js.map +0 -1
- package/dist/src/cli/listen.d.ts +0 -56
- package/dist/src/cli/listen.d.ts.map +0 -1
- package/dist/src/cli/listen.js.map +0 -1
- package/dist/src/cli/report.d.ts +0 -24
- package/dist/src/cli/report.d.ts.map +0 -1
- package/dist/src/cli/report.js.map +0 -1
- package/dist/src/cli/serve.d.ts +0 -3
- package/dist/src/cli/serve.d.ts.map +0 -1
- package/dist/src/cli/serve.js.map +0 -1
- package/dist/src/cli/status.d.ts +0 -19
- package/dist/src/cli/status.d.ts.map +0 -1
- package/dist/src/cli/status.js.map +0 -1
- package/dist/src/config/loader.d.ts +0 -22
- package/dist/src/config/loader.d.ts.map +0 -1
- package/dist/src/config/loader.js +0 -195
- package/dist/src/config/loader.js.map +0 -1
- package/dist/src/config/schema.d.ts +0 -465
- package/dist/src/config/schema.d.ts.map +0 -1
- package/dist/src/config/schema.js +0 -219
- package/dist/src/config/schema.js.map +0 -1
- package/dist/src/core/caps.d.ts +0 -36
- package/dist/src/core/caps.d.ts.map +0 -1
- package/dist/src/core/caps.js +0 -36
- package/dist/src/core/caps.js.map +0 -1
- package/dist/src/core/db.d.ts +0 -3
- package/dist/src/core/db.d.ts.map +0 -1
- package/dist/src/core/db.js +0 -105
- package/dist/src/core/db.js.map +0 -1
- package/dist/src/core/detect-repo.d.ts +0 -4
- package/dist/src/core/detect-repo.d.ts.map +0 -1
- package/dist/src/core/detect-repo.js +0 -28
- package/dist/src/core/detect-repo.js.map +0 -1
- package/dist/src/core/file-session-store.d.ts +0 -10
- package/dist/src/core/file-session-store.d.ts.map +0 -1
- package/dist/src/core/file-session-store.js +0 -34
- package/dist/src/core/file-session-store.js.map +0 -1
- package/dist/src/core/parse-stdin.d.ts +0 -2
- package/dist/src/core/parse-stdin.d.ts.map +0 -1
- package/dist/src/core/parse-stdin.js +0 -21
- package/dist/src/core/parse-stdin.js.map +0 -1
- package/dist/src/core/run-investigation.d.ts +0 -54
- package/dist/src/core/run-investigation.d.ts.map +0 -1
- package/dist/src/core/run-investigation.js +0 -202
- package/dist/src/core/run-investigation.js.map +0 -1
- package/dist/src/core/session.d.ts +0 -63
- package/dist/src/core/session.d.ts.map +0 -1
- package/dist/src/core/session.js +0 -45
- package/dist/src/core/session.js.map +0 -1
- package/dist/src/core/slack-notify.d.ts +0 -9
- package/dist/src/core/slack-notify.d.ts.map +0 -1
- package/dist/src/core/slack-notify.js +0 -57
- package/dist/src/core/slack-notify.js.map +0 -1
- package/dist/src/core/sqlite-session-store.d.ts +0 -39
- package/dist/src/core/sqlite-session-store.d.ts.map +0 -1
- package/dist/src/core/sqlite-session-store.js +0 -239
- package/dist/src/core/sqlite-session-store.js.map +0 -1
- package/dist/src/http/server.d.ts +0 -31
- package/dist/src/http/server.d.ts.map +0 -1
- package/dist/src/http/server.js +0 -164
- package/dist/src/http/server.js.map +0 -1
- package/dist/src/jsonrpc/server.d.ts +0 -44
- package/dist/src/jsonrpc/server.d.ts.map +0 -1
- package/dist/src/jsonrpc/server.js +0 -267
- package/dist/src/jsonrpc/server.js.map +0 -1
- package/dist/src/jsonrpc/types.d.ts +0 -12
- package/dist/src/jsonrpc/types.d.ts.map +0 -1
- package/dist/src/jsonrpc/types.js +0 -4
- package/dist/src/jsonrpc/types.js.map +0 -1
- package/dist/src/version.d.ts +0 -8
- package/dist/src/version.d.ts.map +0 -1
- package/dist/src/version.js +0 -27
- package/dist/src/version.js.map +0 -1
package/dist/src/cli/report.js
CHANGED
|
@@ -1,73 +1,76 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
createSessionManager
|
|
3
|
+
} from "../../chunk-CTKCK7QT.js";
|
|
4
|
+
import {
|
|
5
|
+
assertKnownFlags
|
|
6
|
+
} from "../../chunk-PTBCAI34.js";
|
|
7
|
+
import "../../chunk-6N4PHBII.js";
|
|
8
|
+
import "../../chunk-2Z7QZSIS.js";
|
|
9
|
+
|
|
10
|
+
// src/cli/report.ts
|
|
3
11
|
import { defineCommand } from "citty";
|
|
4
12
|
import consola from "consola";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
var report_default = defineCommand({
|
|
14
|
+
meta: {
|
|
15
|
+
name: "report",
|
|
16
|
+
description: "Print a stored report for a given run ID\n\nExamples:\n $ pl report 1234abcd\n $ pl report 1234abcd --json\n $ pl report 1234abcd --events"
|
|
17
|
+
},
|
|
18
|
+
args: {
|
|
19
|
+
id: {
|
|
20
|
+
type: "positional",
|
|
21
|
+
description: "The run ID",
|
|
22
|
+
required: true
|
|
11
23
|
},
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
required: true,
|
|
17
|
-
},
|
|
18
|
-
events: {
|
|
19
|
-
type: "boolean",
|
|
20
|
-
description: "Include timeline events",
|
|
21
|
-
required: false,
|
|
22
|
-
},
|
|
23
|
-
"workspace-dir": {
|
|
24
|
-
type: "string",
|
|
25
|
-
description: "Workspace directory (default: ~/.prismalens; overridden by PRISMALENS_WORKSPACE_DIR)",
|
|
26
|
-
required: false,
|
|
27
|
-
},
|
|
28
|
-
json: {
|
|
29
|
-
type: "boolean",
|
|
30
|
-
description: "Print machine-readable JSON",
|
|
31
|
-
required: false,
|
|
32
|
-
},
|
|
24
|
+
events: {
|
|
25
|
+
type: "boolean",
|
|
26
|
+
description: "Include timeline events",
|
|
27
|
+
required: false
|
|
33
28
|
},
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
sessions = createSessionManager(args["workspace-dir"]);
|
|
39
|
-
const json = Boolean(args.json);
|
|
40
|
-
const report = await sessions.readReport(args.id);
|
|
41
|
-
if (!report) {
|
|
42
|
-
consola.error(`No report for run ${args.id}`);
|
|
43
|
-
// exitCode (not process.exit) so the finally block still closes the
|
|
44
|
-
// session manager before the process tears down.
|
|
45
|
-
process.exitCode = 1;
|
|
46
|
-
return;
|
|
47
|
-
}
|
|
48
|
-
if (json) {
|
|
49
|
-
const out = args.events
|
|
50
|
-
? { report, events: await sessions.readEvents(args.id) }
|
|
51
|
-
: report;
|
|
52
|
-
process.stdout.write(`${JSON.stringify(out, null, 2)}\n`);
|
|
53
|
-
return;
|
|
54
|
-
}
|
|
55
|
-
consola.log(JSON.stringify(report, null, 2));
|
|
56
|
-
if (args.events) {
|
|
57
|
-
const events = await sessions.readEvents(args.id);
|
|
58
|
-
consola.log("\n--- Timeline Events ---");
|
|
59
|
-
for (const ev of events) {
|
|
60
|
-
consola.log(JSON.stringify(ev));
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
catch (err) {
|
|
65
|
-
consola.error("Failed to read report:", err);
|
|
66
|
-
process.exitCode = 1;
|
|
67
|
-
}
|
|
68
|
-
finally {
|
|
69
|
-
sessions?.close?.();
|
|
70
|
-
}
|
|
29
|
+
"workspace-dir": {
|
|
30
|
+
type: "string",
|
|
31
|
+
description: "Workspace directory (default: ~/.prismalens; overridden by PRISMALENS_WORKSPACE_DIR)",
|
|
32
|
+
required: false
|
|
71
33
|
},
|
|
34
|
+
json: {
|
|
35
|
+
type: "boolean",
|
|
36
|
+
description: "Print machine-readable JSON",
|
|
37
|
+
required: false
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
async run({ args, cmd }) {
|
|
41
|
+
let sessions;
|
|
42
|
+
try {
|
|
43
|
+
assertKnownFlags(args, cmd);
|
|
44
|
+
sessions = createSessionManager(args["workspace-dir"]);
|
|
45
|
+
const json = Boolean(args.json);
|
|
46
|
+
const report = await sessions.readReport(args.id);
|
|
47
|
+
if (!report) {
|
|
48
|
+
consola.error(`No report for run ${args.id}`);
|
|
49
|
+
process.exitCode = 1;
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
if (json) {
|
|
53
|
+
const out = args.events ? { report, events: await sessions.readEvents(args.id) } : report;
|
|
54
|
+
process.stdout.write(`${JSON.stringify(out, null, 2)}
|
|
55
|
+
`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
consola.log(JSON.stringify(report, null, 2));
|
|
59
|
+
if (args.events) {
|
|
60
|
+
const events = await sessions.readEvents(args.id);
|
|
61
|
+
consola.log("\n--- Timeline Events ---");
|
|
62
|
+
for (const ev of events) {
|
|
63
|
+
consola.log(JSON.stringify(ev));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
} catch (err) {
|
|
67
|
+
consola.error("Failed to read report:", err);
|
|
68
|
+
process.exitCode = 1;
|
|
69
|
+
} finally {
|
|
70
|
+
sessions?.close?.();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
72
73
|
});
|
|
73
|
-
|
|
74
|
+
export {
|
|
75
|
+
report_default as default
|
|
76
|
+
};
|
package/dist/src/cli/serve.js
CHANGED
|
@@ -1,35 +1,265 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import {
|
|
2
|
+
cliVersion
|
|
3
|
+
} from "../../chunk-HPE5CTO4.js";
|
|
4
|
+
import {
|
|
5
|
+
createFileSessionStore,
|
|
6
|
+
resolveRepoSlug,
|
|
7
|
+
resolveRunSandbox
|
|
8
|
+
} from "../../chunk-PVQVFRIV.js";
|
|
9
|
+
import {
|
|
10
|
+
loadConfig
|
|
11
|
+
} from "../../chunk-V6M6ISKI.js";
|
|
12
|
+
import {
|
|
13
|
+
createSessionManager
|
|
14
|
+
} from "../../chunk-CTKCK7QT.js";
|
|
15
|
+
import {
|
|
16
|
+
resolveInvestigation
|
|
17
|
+
} from "../../chunk-QDK5PAI3.js";
|
|
18
|
+
import "../../chunk-CVSS5JPC.js";
|
|
19
|
+
import "../../chunk-TGP6QTFO.js";
|
|
20
|
+
import {
|
|
21
|
+
assertKnownFlags
|
|
22
|
+
} from "../../chunk-PTBCAI34.js";
|
|
23
|
+
import {
|
|
24
|
+
SANDBOX_MODES,
|
|
25
|
+
conductRun
|
|
26
|
+
} from "../../chunk-5BT3XQOG.js";
|
|
27
|
+
import "../../chunk-6N4PHBII.js";
|
|
28
|
+
import "../../chunk-XH6DIKTA.js";
|
|
29
|
+
import "../../chunk-2Z7QZSIS.js";
|
|
30
|
+
|
|
31
|
+
// src/cli/serve.ts
|
|
12
32
|
import { defineCommand } from "citty";
|
|
13
33
|
import { consola } from "consola";
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
34
|
+
|
|
35
|
+
// src/jsonrpc/server.ts
|
|
36
|
+
import { randomUUID } from "node:crypto";
|
|
37
|
+
import { resolve } from "node:path";
|
|
38
|
+
import { createInterface } from "node:readline";
|
|
39
|
+
import {
|
|
40
|
+
JSONRPCErrorException,
|
|
41
|
+
JSONRPCServer
|
|
42
|
+
} from "json-rpc-2.0";
|
|
43
|
+
var PROTOCOL_VERSION = 1;
|
|
44
|
+
var PARSE_ERROR = -32700;
|
|
45
|
+
var INVALID_PARAMS = -32602;
|
|
46
|
+
var INTERNAL_ERROR = -32603;
|
|
47
|
+
var NO_EVIDENCE = -32e3;
|
|
48
|
+
function isRecord(x) {
|
|
49
|
+
return x !== null && typeof x === "object" && !Array.isArray(x);
|
|
50
|
+
}
|
|
51
|
+
function str(x) {
|
|
52
|
+
return typeof x === "string" ? x : void 0;
|
|
53
|
+
}
|
|
54
|
+
function parseInvestigateParams(raw) {
|
|
55
|
+
const p = isRecord(raw) ? raw : {};
|
|
56
|
+
const out = {};
|
|
57
|
+
if (isRecord(p.alert)) out.alert = p.alert;
|
|
58
|
+
const query = str(p.query);
|
|
59
|
+
if (query) out.query = query;
|
|
60
|
+
const repo = str(p.repo);
|
|
61
|
+
if (repo) out.repo = repo;
|
|
62
|
+
const harness = str(p.harness);
|
|
63
|
+
if (harness) out.harness = harness;
|
|
64
|
+
const model = str(p.model);
|
|
65
|
+
if (model) out.model = model;
|
|
66
|
+
const config = str(p.config);
|
|
67
|
+
if (config) out.config = config;
|
|
68
|
+
const service = str(p.service);
|
|
69
|
+
if (service) out.service = service;
|
|
70
|
+
const mode = str(p.mode);
|
|
71
|
+
if (mode) out.mode = mode;
|
|
72
|
+
if (typeof p.dangerouslySkipPermissions === "boolean") {
|
|
73
|
+
out.dangerouslySkipPermissions = p.dangerouslySkipPermissions;
|
|
74
|
+
}
|
|
75
|
+
if (p.sandbox !== void 0) {
|
|
76
|
+
const sandbox = str(p.sandbox);
|
|
77
|
+
if (!sandbox || !SANDBOX_MODES.includes(sandbox)) {
|
|
78
|
+
throw new JSONRPCErrorException(
|
|
79
|
+
`Invalid sandbox mode ${JSON.stringify(p.sandbox)}. Expected one of: ${SANDBOX_MODES.join(", ")}.`,
|
|
80
|
+
INVALID_PARAMS
|
|
81
|
+
);
|
|
82
|
+
}
|
|
83
|
+
out.sandbox = sandbox;
|
|
84
|
+
}
|
|
85
|
+
if (p.maxTurns !== void 0) {
|
|
86
|
+
if (typeof p.maxTurns !== "number" || !Number.isInteger(p.maxTurns) || p.maxTurns <= 0) {
|
|
87
|
+
throw new JSONRPCErrorException(
|
|
88
|
+
`Invalid maxTurns ${JSON.stringify(p.maxTurns)}. Expected a positive integer.`,
|
|
89
|
+
INVALID_PARAMS
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
out.maxTurns = p.maxTurns;
|
|
93
|
+
}
|
|
94
|
+
return out;
|
|
95
|
+
}
|
|
96
|
+
async function runJsonRpcServer(options) {
|
|
97
|
+
const input = options.input ?? process.stdin;
|
|
98
|
+
const output = options.output ?? process.stdout;
|
|
99
|
+
const write = (message) => {
|
|
100
|
+
output.write(`${JSON.stringify(message)}
|
|
101
|
+
`);
|
|
102
|
+
};
|
|
103
|
+
const notify = (method, params) => {
|
|
104
|
+
write({ jsonrpc: "2.0", method, params });
|
|
105
|
+
};
|
|
106
|
+
const handleInitialize = () => ({
|
|
107
|
+
protocolVersion: PROTOCOL_VERSION,
|
|
108
|
+
serverInfo: { name: "prismalens", version: options.version }
|
|
109
|
+
});
|
|
110
|
+
const handleInvestigate = async (rawParams) => {
|
|
111
|
+
const params = parseInvestigateParams(rawParams);
|
|
112
|
+
const cwd = params.repo ? resolve(params.repo) : process.cwd();
|
|
113
|
+
const config = await loadConfig({
|
|
114
|
+
...params.config ? { configPath: params.config } : {},
|
|
115
|
+
cwd,
|
|
116
|
+
cliOverrides: { ...params.model ? { model: params.model } : {} }
|
|
117
|
+
});
|
|
118
|
+
const permissionMode = params.dangerouslySkipPermissions ? "dangerous" : params.mode;
|
|
119
|
+
const harnessName = params.harness ?? config.agent.default;
|
|
120
|
+
const sandboxMode = params.sandbox ?? config.agent.sandbox;
|
|
121
|
+
let selection;
|
|
122
|
+
try {
|
|
123
|
+
selection = (await resolveRunSandbox(harnessName, sandboxMode, config)).selection;
|
|
124
|
+
} catch (err) {
|
|
125
|
+
throw new JSONRPCErrorException(
|
|
126
|
+
err instanceof Error ? err.message : String(err),
|
|
127
|
+
INVALID_PARAMS
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
try {
|
|
131
|
+
let resolved;
|
|
132
|
+
try {
|
|
133
|
+
resolved = resolveInvestigation(
|
|
134
|
+
{
|
|
135
|
+
...params.alert ? { alert: params.alert } : {},
|
|
136
|
+
...params.query ? { query: params.query } : {},
|
|
137
|
+
...params.repo ? { repo: params.repo } : {},
|
|
138
|
+
...params.harness ? { harness: params.harness } : {},
|
|
139
|
+
...params.service ? { service: params.service } : {},
|
|
140
|
+
...permissionMode ? { permissionMode } : {},
|
|
141
|
+
...selection ? {
|
|
142
|
+
sandbox: selection.sandbox,
|
|
143
|
+
requestedSandbox: selection.requested
|
|
144
|
+
} : {},
|
|
145
|
+
...params.maxTurns ? { maxTurns: params.maxTurns } : {}
|
|
146
|
+
},
|
|
147
|
+
config
|
|
148
|
+
);
|
|
149
|
+
} catch (err) {
|
|
150
|
+
throw new JSONRPCErrorException(
|
|
151
|
+
err instanceof Error ? err.message : String(err),
|
|
152
|
+
INVALID_PARAMS
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
const { context, harness, synth, harnessName: harnessName2, fidelity, maxBranches } = resolved;
|
|
156
|
+
const primaryAlert = context.alerts[0];
|
|
157
|
+
const runId = randomUUID();
|
|
158
|
+
const repoSlug = await resolveRepoSlug(config.repo, cwd);
|
|
159
|
+
const sessions = createSessionManager(config.workspace.dir);
|
|
160
|
+
const fileSession = createFileSessionStore(sessions, {
|
|
161
|
+
runId,
|
|
162
|
+
alertname: primaryAlert.alertname,
|
|
163
|
+
agent: harnessName2,
|
|
164
|
+
...repoSlug ? { repo: repoSlug } : {}
|
|
165
|
+
});
|
|
166
|
+
const outcome = await conductRun(
|
|
167
|
+
{
|
|
168
|
+
context,
|
|
169
|
+
harness,
|
|
170
|
+
synth,
|
|
171
|
+
fidelity,
|
|
172
|
+
runId,
|
|
173
|
+
...maxBranches !== void 0 ? { maxBranches } : {}
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
sink: (event) => {
|
|
177
|
+
notify("investigate/event", { runId, event });
|
|
178
|
+
},
|
|
179
|
+
store: fileSession.store
|
|
28
180
|
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
181
|
+
);
|
|
182
|
+
if (!outcome.report) {
|
|
183
|
+
throw new JSONRPCErrorException(
|
|
184
|
+
outcome.error ?? "investigation produced no evidence",
|
|
185
|
+
outcome.failureKind === "no-evidence" ? NO_EVIDENCE : INTERNAL_ERROR,
|
|
186
|
+
{ runId }
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
return { runId: outcome.runId, report: outcome.report };
|
|
190
|
+
} finally {
|
|
191
|
+
if (selection) await selection.sandbox.destroy();
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
const server = new JSONRPCServer();
|
|
195
|
+
server.addMethod("initialize", () => handleInitialize());
|
|
196
|
+
server.addMethod(
|
|
197
|
+
"investigate",
|
|
198
|
+
(params) => handleInvestigate(params)
|
|
199
|
+
);
|
|
200
|
+
server.mapErrorToJSONRPCErrorResponse = (id, error) => {
|
|
201
|
+
if (error instanceof JSONRPCErrorException) {
|
|
202
|
+
return {
|
|
203
|
+
jsonrpc: "2.0",
|
|
204
|
+
id,
|
|
205
|
+
error: {
|
|
206
|
+
code: error.code,
|
|
207
|
+
message: error.message,
|
|
208
|
+
...error.data !== void 0 ? { data: error.data } : {}
|
|
32
209
|
}
|
|
33
|
-
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
jsonrpc: "2.0",
|
|
214
|
+
id,
|
|
215
|
+
error: {
|
|
216
|
+
code: INTERNAL_ERROR,
|
|
217
|
+
message: error instanceof Error ? error.message : String(error)
|
|
218
|
+
}
|
|
219
|
+
};
|
|
220
|
+
};
|
|
221
|
+
const handleLine = (line) => {
|
|
222
|
+
const trimmed = line.trim();
|
|
223
|
+
if (!trimmed) return;
|
|
224
|
+
let parsed;
|
|
225
|
+
try {
|
|
226
|
+
parsed = JSON.parse(trimmed);
|
|
227
|
+
} catch {
|
|
228
|
+
write({
|
|
229
|
+
jsonrpc: "2.0",
|
|
230
|
+
id: null,
|
|
231
|
+
error: { code: PARSE_ERROR, message: "Parse error: invalid JSON" }
|
|
232
|
+
});
|
|
233
|
+
return;
|
|
234
|
+
}
|
|
235
|
+
void server.receive(parsed).then((response) => {
|
|
236
|
+
if (response) write(response);
|
|
237
|
+
});
|
|
238
|
+
};
|
|
239
|
+
const rl = createInterface({ input, crlfDelay: Number.POSITIVE_INFINITY });
|
|
240
|
+
rl.on("line", handleLine);
|
|
241
|
+
await new Promise((resolveClose) => {
|
|
242
|
+
rl.on("close", () => resolveClose());
|
|
243
|
+
});
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// src/cli/serve.ts
|
|
247
|
+
var SERVER_VERSION = cliVersion();
|
|
248
|
+
var serve_default = defineCommand({
|
|
249
|
+
meta: {
|
|
250
|
+
name: "serve",
|
|
251
|
+
description: "Run the JSON-RPC 2.0 server over stdio (the LIVE channel for the desktop app / API).\n\nExamples:\n $ pl serve"
|
|
252
|
+
},
|
|
253
|
+
async run({ args, cmd }) {
|
|
254
|
+
try {
|
|
255
|
+
assertKnownFlags(args, cmd);
|
|
256
|
+
await runJsonRpcServer({ version: SERVER_VERSION });
|
|
257
|
+
} catch (err) {
|
|
258
|
+
consola.error(err instanceof Error ? err.message : String(err));
|
|
259
|
+
process.exit(1);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
34
262
|
});
|
|
35
|
-
|
|
263
|
+
export {
|
|
264
|
+
serve_default as default
|
|
265
|
+
};
|
package/dist/src/cli/status.js
CHANGED
|
@@ -1,93 +1,94 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
import {
|
|
2
|
+
createSessionManager
|
|
3
|
+
} from "../../chunk-CTKCK7QT.js";
|
|
4
|
+
import {
|
|
5
|
+
assertKnownFlags
|
|
6
|
+
} from "../../chunk-PTBCAI34.js";
|
|
7
|
+
import "../../chunk-6N4PHBII.js";
|
|
8
|
+
import "../../chunk-2Z7QZSIS.js";
|
|
9
|
+
|
|
10
|
+
// src/cli/status.ts
|
|
3
11
|
import { defineCommand } from "citty";
|
|
4
12
|
import consola from "consola";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
13
|
+
var status_default = defineCommand({
|
|
14
|
+
meta: {
|
|
15
|
+
name: "status",
|
|
16
|
+
description: "List incident groups and runs with their state (running, done, errored, suppressed)\n\nExamples:\n $ pl status\n $ pl status --status running,errored\n $ pl status --json"
|
|
17
|
+
},
|
|
18
|
+
args: {
|
|
19
|
+
status: {
|
|
20
|
+
type: "string",
|
|
21
|
+
description: "Filter by status (running, done, errored, suppressed)",
|
|
22
|
+
required: false
|
|
11
23
|
},
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
required: false,
|
|
17
|
-
},
|
|
18
|
-
"workspace-dir": {
|
|
19
|
-
type: "string",
|
|
20
|
-
description: "Workspace directory (default: ~/.prismalens; overridden by PRISMALENS_WORKSPACE_DIR)",
|
|
21
|
-
required: false,
|
|
22
|
-
},
|
|
23
|
-
json: {
|
|
24
|
-
type: "boolean",
|
|
25
|
-
description: "Print machine-readable JSON",
|
|
26
|
-
required: false,
|
|
27
|
-
},
|
|
24
|
+
"workspace-dir": {
|
|
25
|
+
type: "string",
|
|
26
|
+
description: "Workspace directory (default: ~/.prismalens; overridden by PRISMALENS_WORKSPACE_DIR)",
|
|
27
|
+
required: false
|
|
28
28
|
},
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
const json = Boolean(args.json);
|
|
57
|
-
const runs = await sessions.list(filter);
|
|
58
|
-
if (json) {
|
|
59
|
-
process.stdout.write(`${JSON.stringify(runs, null, 2)}\n`);
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
if (runs.length === 0) {
|
|
63
|
-
consola.info("No runs found.");
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
for (const run of runs) {
|
|
67
|
-
const info = [
|
|
68
|
-
`run_id: ${run.runId}`,
|
|
69
|
-
`status: ${run.status}`,
|
|
70
|
-
`created_at: ${run.createdAt}`,
|
|
71
|
-
];
|
|
72
|
-
if (run.alertname)
|
|
73
|
-
info.push(`alertname: ${run.alertname}`);
|
|
74
|
-
if (run.agent)
|
|
75
|
-
info.push(`agent: ${run.agent}`);
|
|
76
|
-
if (run.repo)
|
|
77
|
-
info.push(`repo: ${run.repo}`);
|
|
78
|
-
if (run.status === "suppressed" && run.suppressionReason) {
|
|
79
|
-
info.push(`suppressed_by: ${run.suppressionReason}`);
|
|
80
|
-
}
|
|
81
|
-
consola.log(info.join(" | "));
|
|
82
|
-
}
|
|
29
|
+
json: {
|
|
30
|
+
type: "boolean",
|
|
31
|
+
description: "Print machine-readable JSON",
|
|
32
|
+
required: false
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
async run({ args, cmd }) {
|
|
36
|
+
let sessions;
|
|
37
|
+
try {
|
|
38
|
+
assertKnownFlags(args, cmd);
|
|
39
|
+
sessions = createSessionManager(args["workspace-dir"]);
|
|
40
|
+
const valid = [
|
|
41
|
+
"running",
|
|
42
|
+
"done",
|
|
43
|
+
"errored",
|
|
44
|
+
"suppressed"
|
|
45
|
+
];
|
|
46
|
+
let filter;
|
|
47
|
+
if (args.status) {
|
|
48
|
+
const parts = args.status.split(",").map((s) => s.trim()).filter((s) => s.length > 0);
|
|
49
|
+
const bad = parts.filter((s) => !valid.includes(s));
|
|
50
|
+
if (bad.length > 0) {
|
|
51
|
+
consola.error(
|
|
52
|
+
`Invalid status: ${bad.join(", ")}. Valid: ${valid.join(", ")}`
|
|
53
|
+
);
|
|
54
|
+
process.exitCode = 1;
|
|
55
|
+
return;
|
|
83
56
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
57
|
+
filter = { status: parts };
|
|
58
|
+
}
|
|
59
|
+
const json = Boolean(args.json);
|
|
60
|
+
const runs = await sessions.list(filter);
|
|
61
|
+
if (json) {
|
|
62
|
+
process.stdout.write(`${JSON.stringify(runs, null, 2)}
|
|
63
|
+
`);
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
if (runs.length === 0) {
|
|
67
|
+
consola.info("No runs found.");
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
for (const run of runs) {
|
|
71
|
+
const info = [
|
|
72
|
+
`run_id: ${run.runId}`,
|
|
73
|
+
`status: ${run.status}`,
|
|
74
|
+
`created_at: ${run.createdAt}`
|
|
75
|
+
];
|
|
76
|
+
if (run.alertname) info.push(`alertname: ${run.alertname}`);
|
|
77
|
+
if (run.agent) info.push(`agent: ${run.agent}`);
|
|
78
|
+
if (run.repo) info.push(`repo: ${run.repo}`);
|
|
79
|
+
if (run.status === "suppressed" && run.suppressionReason) {
|
|
80
|
+
info.push(`suppressed_by: ${run.suppressionReason}`);
|
|
87
81
|
}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
82
|
+
consola.log(info.join(" | "));
|
|
83
|
+
}
|
|
84
|
+
} catch (err) {
|
|
85
|
+
consola.error("Failed to read status:", err);
|
|
86
|
+
process.exitCode = 1;
|
|
87
|
+
} finally {
|
|
88
|
+
sessions?.close?.();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
92
91
|
});
|
|
93
|
-
|
|
92
|
+
export {
|
|
93
|
+
status_default as default
|
|
94
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prismalens",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "AI root-cause investigation from your terminal — point it at a repo, pipe it an alert, get an evidence-linked report",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -36,25 +36,34 @@
|
|
|
36
36
|
"access": "public"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
+
"@ai-sdk/anthropic": "^4.0.7",
|
|
40
|
+
"@ai-sdk/google": "^4.0.8",
|
|
41
|
+
"@ai-sdk/groq": "^4.0.5",
|
|
42
|
+
"@ai-sdk/openai": "^4.0.7",
|
|
43
|
+
"@ai-sdk/openai-compatible": "^3.0.5",
|
|
44
|
+
"@anthropic-ai/claude-agent-sdk": "^0.3.199",
|
|
45
|
+
"@orpc/contract": "^1.14.6",
|
|
46
|
+
"ai": "^7.0.14",
|
|
39
47
|
"citty": "^0.2.2",
|
|
40
48
|
"consola": "^3.4.2",
|
|
41
49
|
"env-paths": "^4.0.0",
|
|
42
50
|
"json-rpc-2.0": "^1.7.1",
|
|
43
51
|
"yaml": "^2.9.0",
|
|
44
|
-
"zod": "^3.25.76"
|
|
45
|
-
"@prismalens/contracts": "0.1.1",
|
|
46
|
-
"@prismalens/engine": "0.2.1",
|
|
47
|
-
"@prismalens/config": "0.3.0"
|
|
52
|
+
"zod": "^3.25.76"
|
|
48
53
|
},
|
|
49
54
|
"devDependencies": {
|
|
50
55
|
"@types/node": "^24.13.2",
|
|
51
56
|
"@vitest/coverage-v8": "^4.1.9",
|
|
57
|
+
"tsup": "^8.5.1",
|
|
52
58
|
"tsx": "^4.22.5",
|
|
53
59
|
"typescript": "^5.9.3",
|
|
54
|
-
"vitest": "^4.1.9"
|
|
60
|
+
"vitest": "^4.1.9",
|
|
61
|
+
"@prismalens/config": "0.3.0",
|
|
62
|
+
"@prismalens/contracts": "0.1.1",
|
|
63
|
+
"@prismalens/engine": "0.2.1"
|
|
55
64
|
},
|
|
56
65
|
"scripts": {
|
|
57
|
-
"build": "
|
|
66
|
+
"build": "tsup",
|
|
58
67
|
"typecheck": "tsc --noEmit",
|
|
59
68
|
"dev": "tsx bin/prismalens.ts",
|
|
60
69
|
"test": "vitest run --coverage"
|
package/dist/bin/prismalens.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"prismalens.d.ts","sourceRoot":"","sources":["../../bin/prismalens.ts"],"names":[],"mappings":""}
|