prismalens 0.0.2 → 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 +12 -2
- package/dist/bin/prismalens.js +13 -0
- package/dist/bin/prismalens.js.map +1 -1
- package/dist/src/cli/doctor.d.ts +15 -1
- package/dist/src/cli/doctor.d.ts.map +1 -1
- package/dist/src/cli/doctor.js +107 -56
- package/dist/src/cli/doctor.js.map +1 -1
- package/dist/src/cli/flags.d.ts +2 -0
- package/dist/src/cli/flags.d.ts.map +1 -0
- package/dist/src/cli/flags.js +25 -0
- package/dist/src/cli/flags.js.map +1 -0
- package/dist/src/cli/grouping.d.ts +18 -0
- package/dist/src/cli/grouping.d.ts.map +1 -0
- package/dist/src/cli/grouping.js +169 -0
- package/dist/src/cli/grouping.js.map +1 -0
- package/dist/src/cli/init.d.ts.map +1 -1
- package/dist/src/cli/init.js +26 -11
- package/dist/src/cli/init.js.map +1 -1
- package/dist/src/cli/investigate.d.ts +12 -0
- package/dist/src/cli/investigate.d.ts.map +1 -1
- package/dist/src/cli/investigate.js +142 -140
- package/dist/src/cli/investigate.js.map +1 -1
- package/dist/src/cli/listen.d.ts +50 -0
- package/dist/src/cli/listen.d.ts.map +1 -0
- package/dist/src/cli/listen.js +249 -0
- package/dist/src/cli/listen.js.map +1 -0
- package/dist/src/cli/report.d.ts +19 -0
- package/dist/src/cli/report.d.ts.map +1 -0
- package/dist/src/cli/report.js +60 -0
- package/dist/src/cli/report.js.map +1 -0
- package/dist/src/cli/serve.d.ts.map +1 -1
- package/dist/src/cli/serve.js +11 -2
- package/dist/src/cli/serve.js.map +1 -1
- package/dist/src/cli/status.d.ts +14 -0
- package/dist/src/cli/status.d.ts.map +1 -0
- package/dist/src/cli/status.js +83 -0
- package/dist/src/cli/status.js.map +1 -0
- package/dist/src/config/loader.d.ts.map +1 -1
- package/dist/src/config/loader.js +28 -2
- package/dist/src/config/loader.js.map +1 -1
- package/dist/src/config/schema.d.ts +121 -0
- package/dist/src/config/schema.d.ts.map +1 -1
- package/dist/src/config/schema.js +47 -1
- package/dist/src/config/schema.js.map +1 -1
- package/dist/src/core/caps.d.ts +36 -0
- package/dist/src/core/caps.d.ts.map +1 -0
- package/dist/src/core/caps.js +36 -0
- package/dist/src/core/caps.js.map +1 -0
- package/dist/src/core/db.d.ts +3 -0
- package/dist/src/core/db.d.ts.map +1 -0
- package/dist/src/core/db.js +71 -0
- package/dist/src/core/db.js.map +1 -0
- package/dist/src/core/file-session-store.js +2 -2
- package/dist/src/core/file-session-store.js.map +1 -1
- package/dist/src/core/run-investigation.d.ts +10 -0
- package/dist/src/core/run-investigation.d.ts.map +1 -1
- package/dist/src/core/run-investigation.js +85 -30
- package/dist/src/core/run-investigation.js.map +1 -1
- package/dist/src/core/session.d.ts +22 -1
- package/dist/src/core/session.d.ts.map +1 -1
- package/dist/src/core/session.js +6 -129
- package/dist/src/core/session.js.map +1 -1
- package/dist/src/core/slack-notify.d.ts +9 -0
- package/dist/src/core/slack-notify.d.ts.map +1 -0
- package/dist/src/core/slack-notify.js +57 -0
- package/dist/src/core/slack-notify.js.map +1 -0
- package/dist/src/core/sqlite-session-store.d.ts +39 -0
- package/dist/src/core/sqlite-session-store.d.ts.map +1 -0
- package/dist/src/core/sqlite-session-store.js +239 -0
- package/dist/src/core/sqlite-session-store.js.map +1 -0
- package/dist/src/http/server.d.ts +26 -0
- package/dist/src/http/server.d.ts.map +1 -0
- package/dist/src/http/server.js +151 -0
- package/dist/src/http/server.js.map +1 -0
- package/package.json +6 -5
|
@@ -84,6 +84,7 @@ export declare const AgentConfigSchema: z.ZodObject<{
|
|
|
84
84
|
* default (3). A single-alert run always uses one branch regardless.
|
|
85
85
|
*/
|
|
86
86
|
max_branches: z.ZodOptional<z.ZodNumber>;
|
|
87
|
+
max_turns: z.ZodOptional<z.ZodNumber>;
|
|
87
88
|
}, "strip", z.ZodTypeAny, {
|
|
88
89
|
default: "deepagents" | "claude-code" | "codex";
|
|
89
90
|
permissions: {
|
|
@@ -97,6 +98,7 @@ export declare const AgentConfigSchema: z.ZodObject<{
|
|
|
97
98
|
};
|
|
98
99
|
model?: string | undefined;
|
|
99
100
|
max_branches?: number | undefined;
|
|
101
|
+
max_turns?: number | undefined;
|
|
100
102
|
}, {
|
|
101
103
|
default?: "deepagents" | "claude-code" | "codex" | undefined;
|
|
102
104
|
model?: string | undefined;
|
|
@@ -104,6 +106,7 @@ export declare const AgentConfigSchema: z.ZodObject<{
|
|
|
104
106
|
sandbox?: "auto" | "process" | "srt" | "e2b" | undefined;
|
|
105
107
|
limits?: Record<string, unknown> | undefined;
|
|
106
108
|
max_branches?: number | undefined;
|
|
109
|
+
max_turns?: number | undefined;
|
|
107
110
|
}>;
|
|
108
111
|
export declare const WorkspaceConfigSchema: z.ZodObject<{
|
|
109
112
|
base_dir: z.ZodDefault<z.ZodString>;
|
|
@@ -112,6 +115,73 @@ export declare const WorkspaceConfigSchema: z.ZodObject<{
|
|
|
112
115
|
}, {
|
|
113
116
|
base_dir?: string | undefined;
|
|
114
117
|
}>;
|
|
118
|
+
/**
|
|
119
|
+
* Run-budget guardrails for `pl listen` (issue #62): non-dollar caps only.
|
|
120
|
+
* `max_concurrent`/`max_per_hour` gate dispatch; `max_turns` is threaded into the
|
|
121
|
+
* default harness as a per-run runaway guard (no default ⇒ the harness's own default).
|
|
122
|
+
*/
|
|
123
|
+
export declare const ListenCapsConfigSchema: z.ZodObject<{
|
|
124
|
+
/** Max investigations running at once. Default 2. */
|
|
125
|
+
max_concurrent: z.ZodDefault<z.ZodNumber>;
|
|
126
|
+
/** Max investigations started per trailing hour. Default 10. */
|
|
127
|
+
max_per_hour: z.ZodDefault<z.ZodNumber>;
|
|
128
|
+
/** Per-run turn ceiling for the default harness. Unset ⇒ the harness default. */
|
|
129
|
+
max_turns: z.ZodOptional<z.ZodNumber>;
|
|
130
|
+
}, "strip", z.ZodTypeAny, {
|
|
131
|
+
max_concurrent: number;
|
|
132
|
+
max_per_hour: number;
|
|
133
|
+
max_turns?: number | undefined;
|
|
134
|
+
}, {
|
|
135
|
+
max_turns?: number | undefined;
|
|
136
|
+
max_concurrent?: number | undefined;
|
|
137
|
+
max_per_hour?: number | undefined;
|
|
138
|
+
}>;
|
|
139
|
+
/**
|
|
140
|
+
* `pl listen` webhook intake (issue #58, Phase 1 R1). `token` is REQUIRED to
|
|
141
|
+
* start listening but optional here so every other command parses a config
|
|
142
|
+
* without it; set it via env interpolation (`token: "${PRISMALENS_LISTEN_TOKEN}"`)
|
|
143
|
+
* rather than a literal. The grouping_window_ms configures the debounce window.
|
|
144
|
+
*/
|
|
145
|
+
export declare const ListenConfigSchema: z.ZodObject<{
|
|
146
|
+
/** Local intake port (4181: clear of 9090/9093/3000/8080 defaults). 0 = ephemeral. */
|
|
147
|
+
port: z.ZodDefault<z.ZodNumber>;
|
|
148
|
+
/** Shared bearer token Alertmanager presents; unset ⇒ `pl listen` refuses to start. */
|
|
149
|
+
token: z.ZodOptional<z.ZodString>;
|
|
150
|
+
/** Max alerts waiting or running at once; default 8. */
|
|
151
|
+
max_pending: z.ZodDefault<z.ZodNumber>;
|
|
152
|
+
/** Grouping window in milliseconds to debounce alerts into one investigation. */
|
|
153
|
+
grouping_window_ms: z.ZodDefault<z.ZodNumber>;
|
|
154
|
+
/**
|
|
155
|
+
* Slack incoming-webhook URL for report delivery (issue #61). Optional — unset ⇒
|
|
156
|
+
* delivery disabled. Set via env interpolation (slack_webhook_url:
|
|
157
|
+
* "${PRISMALENS_SLACK_WEBHOOK_URL}") so the secret stays in env (ADR-0006).
|
|
158
|
+
*/
|
|
159
|
+
slack_webhook_url: z.ZodOptional<z.ZodString>;
|
|
160
|
+
/** Run-budget guardrails (issue #62). Always present with defaults after parse. */
|
|
161
|
+
caps: z.ZodEffects<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>, {
|
|
162
|
+
max_concurrent: number;
|
|
163
|
+
max_per_hour: number;
|
|
164
|
+
max_turns?: number | undefined;
|
|
165
|
+
}, Record<string, unknown> | undefined>;
|
|
166
|
+
}, "strip", z.ZodTypeAny, {
|
|
167
|
+
port: number;
|
|
168
|
+
max_pending: number;
|
|
169
|
+
grouping_window_ms: number;
|
|
170
|
+
caps: {
|
|
171
|
+
max_concurrent: number;
|
|
172
|
+
max_per_hour: number;
|
|
173
|
+
max_turns?: number | undefined;
|
|
174
|
+
};
|
|
175
|
+
token?: string | undefined;
|
|
176
|
+
slack_webhook_url?: string | undefined;
|
|
177
|
+
}, {
|
|
178
|
+
port?: number | undefined;
|
|
179
|
+
token?: string | undefined;
|
|
180
|
+
max_pending?: number | undefined;
|
|
181
|
+
grouping_window_ms?: number | undefined;
|
|
182
|
+
slack_webhook_url?: string | undefined;
|
|
183
|
+
caps?: Record<string, unknown> | undefined;
|
|
184
|
+
}>;
|
|
115
185
|
/**
|
|
116
186
|
* Read-only telemetry + app endpoints the harness may query. Mirrors the engine's
|
|
117
187
|
* TelemetryEndpoints (camelCase) so a loaded config can be handed straight to
|
|
@@ -176,6 +246,19 @@ export declare const RepoConfigSchema: z.ZodObject<{
|
|
|
176
246
|
local_path?: string | null | undefined;
|
|
177
247
|
alert_sources?: Record<string, Record<string, string>> | undefined;
|
|
178
248
|
}>;
|
|
249
|
+
export declare const SynthConfigSchema: z.ZodObject<{
|
|
250
|
+
provider: z.ZodOptional<z.ZodEnum<["custom" | "anthropic" | "openai" | "google" | "ollama" | "groq", ...("custom" | "anthropic" | "openai" | "google" | "ollama" | "groq")[]]>>;
|
|
251
|
+
model: z.ZodOptional<z.ZodString>;
|
|
252
|
+
base_url: z.ZodOptional<z.ZodString>;
|
|
253
|
+
}, "strip", z.ZodTypeAny, {
|
|
254
|
+
model?: string | undefined;
|
|
255
|
+
provider?: "custom" | "anthropic" | "openai" | "google" | "ollama" | "groq" | undefined;
|
|
256
|
+
base_url?: string | undefined;
|
|
257
|
+
}, {
|
|
258
|
+
model?: string | undefined;
|
|
259
|
+
provider?: "custom" | "anthropic" | "openai" | "google" | "ollama" | "groq" | undefined;
|
|
260
|
+
base_url?: string | undefined;
|
|
261
|
+
}>;
|
|
179
262
|
export declare const PlConfigSchema: z.ZodObject<{
|
|
180
263
|
$schema: z.ZodOptional<z.ZodString>;
|
|
181
264
|
/** Convenience single-repo default (owner/name); `repos` is the multi-repo map. */
|
|
@@ -243,10 +326,28 @@ export declare const PlConfigSchema: z.ZodObject<{
|
|
|
243
326
|
};
|
|
244
327
|
model?: string | undefined;
|
|
245
328
|
max_branches?: number | undefined;
|
|
329
|
+
max_turns?: number | undefined;
|
|
330
|
+
}, Record<string, unknown> | undefined>;
|
|
331
|
+
synth: z.ZodEffects<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>, {
|
|
332
|
+
model?: string | undefined;
|
|
333
|
+
provider?: "custom" | "anthropic" | "openai" | "google" | "ollama" | "groq" | undefined;
|
|
334
|
+
base_url?: string | undefined;
|
|
246
335
|
}, Record<string, unknown> | undefined>;
|
|
247
336
|
workspace: z.ZodEffects<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>, {
|
|
248
337
|
base_dir: string;
|
|
249
338
|
}, Record<string, unknown> | undefined>;
|
|
339
|
+
listen: z.ZodEffects<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>, {
|
|
340
|
+
port: number;
|
|
341
|
+
max_pending: number;
|
|
342
|
+
grouping_window_ms: number;
|
|
343
|
+
caps: {
|
|
344
|
+
max_concurrent: number;
|
|
345
|
+
max_per_hour: number;
|
|
346
|
+
max_turns?: number | undefined;
|
|
347
|
+
};
|
|
348
|
+
token?: string | undefined;
|
|
349
|
+
slack_webhook_url?: string | undefined;
|
|
350
|
+
}, Record<string, unknown> | undefined>;
|
|
250
351
|
telemetry: z.ZodEffects<z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>, {
|
|
251
352
|
prometheusUrl?: string | undefined;
|
|
252
353
|
alertmanagerUrl?: string | undefined;
|
|
@@ -266,6 +367,18 @@ export declare const PlConfigSchema: z.ZodObject<{
|
|
|
266
367
|
native?: Record<string, unknown> | undefined;
|
|
267
368
|
}> | undefined>;
|
|
268
369
|
}, "strip", z.ZodTypeAny, {
|
|
370
|
+
listen: {
|
|
371
|
+
port: number;
|
|
372
|
+
max_pending: number;
|
|
373
|
+
grouping_window_ms: number;
|
|
374
|
+
caps: {
|
|
375
|
+
max_concurrent: number;
|
|
376
|
+
max_per_hour: number;
|
|
377
|
+
max_turns?: number | undefined;
|
|
378
|
+
};
|
|
379
|
+
token?: string | undefined;
|
|
380
|
+
slack_webhook_url?: string | undefined;
|
|
381
|
+
};
|
|
269
382
|
alert_sources: Record<string, Record<string, string>>;
|
|
270
383
|
repos: Record<string, {
|
|
271
384
|
repo: string;
|
|
@@ -294,6 +407,12 @@ export declare const PlConfigSchema: z.ZodObject<{
|
|
|
294
407
|
};
|
|
295
408
|
model?: string | undefined;
|
|
296
409
|
max_branches?: number | undefined;
|
|
410
|
+
max_turns?: number | undefined;
|
|
411
|
+
};
|
|
412
|
+
synth: {
|
|
413
|
+
model?: string | undefined;
|
|
414
|
+
provider?: "custom" | "anthropic" | "openai" | "google" | "ollama" | "groq" | undefined;
|
|
415
|
+
base_url?: string | undefined;
|
|
297
416
|
};
|
|
298
417
|
workspace: {
|
|
299
418
|
base_dir: string;
|
|
@@ -309,6 +428,7 @@ export declare const PlConfigSchema: z.ZodObject<{
|
|
|
309
428
|
repo?: string | undefined;
|
|
310
429
|
$schema?: string | undefined;
|
|
311
430
|
}, {
|
|
431
|
+
listen?: Record<string, unknown> | undefined;
|
|
312
432
|
repo?: string | undefined;
|
|
313
433
|
alert_sources?: Record<string, Record<string, string>> | undefined;
|
|
314
434
|
$schema?: string | undefined;
|
|
@@ -324,6 +444,7 @@ export declare const PlConfigSchema: z.ZodObject<{
|
|
|
324
444
|
}> | undefined;
|
|
325
445
|
logs?: Record<string, unknown> | undefined;
|
|
326
446
|
agent?: Record<string, unknown> | undefined;
|
|
447
|
+
synth?: Record<string, unknown> | undefined;
|
|
327
448
|
workspace?: Record<string, unknown> | undefined;
|
|
328
449
|
telemetry?: Record<string, unknown> | undefined;
|
|
329
450
|
harnesses?: Record<string, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/config/schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/config/schema.ts"],"names":[],"mappings":"AAuBA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH,eAAO,MAAM,sBAAsB;;;;;;EAEjC,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,yBAAyB;;;;;;EAEpC,CAAC;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,uBAAuB;IACnC,qEAAqE;;IAErE,gEAAgE;;IAEhE,+EAA+E;;;;;;;;;;EAE9E,CAAC;AAEH,8DAA8D;AAC9D,eAAO,MAAM,iBAAiB;;IAE7B;;;;;OAKG;;IAEH,4DAA4D;;;;IAE5D;;;;;;OAMG;;IAEH;;;OAGG;;;;;;IAEH;;;;OAIG;;;;;;;;;;;;;;;;;;;;;;;;;EAGF,CAAC;AAEH,eAAO,MAAM,qBAAqB;;;;;;EAEhC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,sBAAsB;IAClC,qDAAqD;;IAErD,gEAAgE;;IAEhE,iFAAiF;;;;;;;;;;EAEhF,CAAC;AAEH;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB;IAC9B,sFAAsF;;IAEtF,uFAAuF;;IAEvF,wDAAwD;;IAExD,iFAAiF;;IAEjF;;;;OAIG;;IAEH,mFAAmF;;;;;;;;;;;;;;;;;;;;;;;;EAElF,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;EAIhC,CAAC;AAEH;;;;GAIG;AACH,eAAO,MAAM,mBAAmB;;IAE/B,yDAAyD;;IAEzD,2DAA2D;;;;;;;;;;EAE1D,CAAC;AAEH,gFAAgF;AAChF,eAAO,MAAM,qBAAqB;;;;;;;;;EAGhC,CAAC;AAEH,mFAAmF;AACnF,eAAO,MAAM,uBAAuB,iEAGnC,CAAC;AAEF,eAAO,MAAM,gBAAgB;;;;;;;;;;;;EAI3B,CAAC;AAcH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;EAI5B,CAAC;AAEH,eAAO,MAAM,cAAc;;IAE1B,mFAAmF;;;;;;;;;;;;;;;;;;;;;;;IAMnF,iFAAiF;;;QAlDjF,yDAAyD;;QAEzD,2DAA2D;;;;;;;;;;;;;;;;;;;IAqD3D,wDAAwD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAUxD,sEAAsE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAKrE,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAC3D,2EAA2E;AAC3E,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,OAAO,cAAc,CAAC,CAAC"}
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* the role machinery is gone.
|
|
19
19
|
*/
|
|
20
20
|
import { HARNESS_IDS, PERMISSION_MODES } from "@prismalens/config/harness";
|
|
21
|
+
import { llmProviderIdSchema } from "@prismalens/config/llm";
|
|
21
22
|
import { SANDBOX_MODES } from "@prismalens/engine";
|
|
22
23
|
import { z } from "zod";
|
|
23
24
|
/**
|
|
@@ -54,7 +55,7 @@ export const AgentLimitsConfigSchema = z.object({
|
|
|
54
55
|
});
|
|
55
56
|
/** Tier-2 harness backend the supervisor rents (ADR-0008). */
|
|
56
57
|
export const AgentConfigSchema = z.object({
|
|
57
|
-
default: z.enum(HARNESS_IDS).default("
|
|
58
|
+
default: z.enum(HARNESS_IDS).default("claude-code"),
|
|
58
59
|
/**
|
|
59
60
|
* BARE model id (e.g. "gpt-oss:120b") — the chosen harness applies its own
|
|
60
61
|
* provider prefix (ADR-0017: deepagents prepends "openai:"; Claude Code takes it
|
|
@@ -83,10 +84,48 @@ export const AgentConfigSchema = z.object({
|
|
|
83
84
|
* default (3). A single-alert run always uses one branch regardless.
|
|
84
85
|
*/
|
|
85
86
|
max_branches: z.number().int().positive().optional(),
|
|
87
|
+
max_turns: z.number().int().positive().optional(),
|
|
86
88
|
});
|
|
87
89
|
export const WorkspaceConfigSchema = z.object({
|
|
88
90
|
base_dir: z.string().default("~/.prismalens"),
|
|
89
91
|
});
|
|
92
|
+
/**
|
|
93
|
+
* Run-budget guardrails for `pl listen` (issue #62): non-dollar caps only.
|
|
94
|
+
* `max_concurrent`/`max_per_hour` gate dispatch; `max_turns` is threaded into the
|
|
95
|
+
* default harness as a per-run runaway guard (no default ⇒ the harness's own default).
|
|
96
|
+
*/
|
|
97
|
+
export const ListenCapsConfigSchema = z.object({
|
|
98
|
+
/** Max investigations running at once. Default 2. */
|
|
99
|
+
max_concurrent: z.number().int().positive().default(2),
|
|
100
|
+
/** Max investigations started per trailing hour. Default 10. */
|
|
101
|
+
max_per_hour: z.number().int().positive().default(10),
|
|
102
|
+
/** Per-run turn ceiling for the default harness. Unset ⇒ the harness default. */
|
|
103
|
+
max_turns: z.number().int().positive().optional(),
|
|
104
|
+
});
|
|
105
|
+
/**
|
|
106
|
+
* `pl listen` webhook intake (issue #58, Phase 1 R1). `token` is REQUIRED to
|
|
107
|
+
* start listening but optional here so every other command parses a config
|
|
108
|
+
* without it; set it via env interpolation (`token: "${PRISMALENS_LISTEN_TOKEN}"`)
|
|
109
|
+
* rather than a literal. The grouping_window_ms configures the debounce window.
|
|
110
|
+
*/
|
|
111
|
+
export const ListenConfigSchema = z.object({
|
|
112
|
+
/** Local intake port (4181: clear of 9090/9093/3000/8080 defaults). 0 = ephemeral. */
|
|
113
|
+
port: z.number().int().min(0).max(65535).default(4181),
|
|
114
|
+
/** Shared bearer token Alertmanager presents; unset ⇒ `pl listen` refuses to start. */
|
|
115
|
+
token: z.string().optional(),
|
|
116
|
+
/** Max alerts waiting or running at once; default 8. */
|
|
117
|
+
max_pending: z.number().int().positive().default(8),
|
|
118
|
+
/** Grouping window in milliseconds to debounce alerts into one investigation. */
|
|
119
|
+
grouping_window_ms: z.number().int().min(1000).max(120000).default(60000),
|
|
120
|
+
/**
|
|
121
|
+
* Slack incoming-webhook URL for report delivery (issue #61). Optional — unset ⇒
|
|
122
|
+
* delivery disabled. Set via env interpolation (slack_webhook_url:
|
|
123
|
+
* "${PRISMALENS_SLACK_WEBHOOK_URL}") so the secret stays in env (ADR-0006).
|
|
124
|
+
*/
|
|
125
|
+
slack_webhook_url: z.string().url().optional(),
|
|
126
|
+
/** Run-budget guardrails (issue #62). Always present with defaults after parse. */
|
|
127
|
+
caps: optionalWithDefaults(ListenCapsConfigSchema),
|
|
128
|
+
});
|
|
90
129
|
/**
|
|
91
130
|
* Read-only telemetry + app endpoints the harness may query. Mirrors the engine's
|
|
92
131
|
* TelemetryEndpoints (camelCase) so a loaded config can be handed straight to
|
|
@@ -132,6 +171,11 @@ function optionalWithDefaults(schema) {
|
|
|
132
171
|
.optional(z.record(z.string(), z.unknown()))
|
|
133
172
|
.transform((val) => schema.parse(val ?? {}));
|
|
134
173
|
}
|
|
174
|
+
export const SynthConfigSchema = z.object({
|
|
175
|
+
provider: llmProviderIdSchema.optional(),
|
|
176
|
+
model: z.string().optional(),
|
|
177
|
+
base_url: z.string().url().optional(),
|
|
178
|
+
});
|
|
135
179
|
export const PlConfigSchema = z.object({
|
|
136
180
|
$schema: z.string().optional(),
|
|
137
181
|
/** Convenience single-repo default (owner/name); `repos` is the multi-repo map. */
|
|
@@ -148,7 +192,9 @@ export const PlConfigSchema = z.object({
|
|
|
148
192
|
/** Read-only log-query system the harness may query. */
|
|
149
193
|
logs: optionalWithDefaults(LogSourceConfigSchema),
|
|
150
194
|
agent: optionalWithDefaults(AgentConfigSchema),
|
|
195
|
+
synth: optionalWithDefaults(SynthConfigSchema),
|
|
151
196
|
workspace: optionalWithDefaults(WorkspaceConfigSchema),
|
|
197
|
+
listen: optionalWithDefaults(ListenConfigSchema),
|
|
152
198
|
telemetry: optionalWithDefaults(TelemetryConfigSchema),
|
|
153
199
|
alert_sources: AlertSourceConfigSchema.optional().transform((val) => val ?? {}),
|
|
154
200
|
/** Per-harness native passthrough (ADR-0017), keyed by harness id. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/config/schema.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,6BAA6B;AAE7B;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;GAIG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC9C,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC;CACnD,CAAC,CAAC;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;CACpD,CAAC,CAAC;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/C,qEAAqE;IACrE,aAAa,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACrD,gEAAgE;IAChE,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;IACjD,+EAA+E;IAC/E,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE;CAC3C,CAAC,CAAC;AAEH,8DAA8D;AAC9D,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACzC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/config/schema.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The dispatch-time run-budget gate for `pl listen` (issue #62). Concurrency +
|
|
3
|
+
* per-hour ONLY gate dispatch here; `max_turns` is threaded to the engine harness
|
|
4
|
+
* (not a dispatch decision) and is deliberately absent from {@link DispatchCaps}.
|
|
5
|
+
* Pure and clock-injected: state lives in the closure, the clock is a caller arg, so
|
|
6
|
+
* the per-hour window is deterministically testable with a fake clock.
|
|
7
|
+
*/
|
|
8
|
+
export interface DispatchCaps {
|
|
9
|
+
/** Max investigations running at once. Unset ⇒ concurrency unbounded. */
|
|
10
|
+
maxConcurrent?: number;
|
|
11
|
+
/** Max investigations STARTED in the trailing hour. Unset ⇒ rate unbounded. */
|
|
12
|
+
maxPerHour?: number;
|
|
13
|
+
}
|
|
14
|
+
export type CapReason = "concurrency" | "per_hour";
|
|
15
|
+
export type CapDecision = {
|
|
16
|
+
allow: true;
|
|
17
|
+
} | {
|
|
18
|
+
allow: false;
|
|
19
|
+
reason: CapReason;
|
|
20
|
+
};
|
|
21
|
+
export interface CapsGate {
|
|
22
|
+
/**
|
|
23
|
+
* Evaluate the caps and, on allow, ATOMICALLY record the start (active++ and push
|
|
24
|
+
* `nowMs` into the hourly window). The caller MUST invoke this with NO `await`
|
|
25
|
+
* between reading the caps and this call — the single-threaded event loop then
|
|
26
|
+
* makes check-and-commit atomic, so two window timers cannot both pass a
|
|
27
|
+
* concurrency=1 gate (the dispatch race the scout flagged).
|
|
28
|
+
*/
|
|
29
|
+
tryDispatch(caps: DispatchCaps, nowMs: number): CapDecision;
|
|
30
|
+
/** Release one active slot when a dispatched run finishes. Call exactly once per `allow`. */
|
|
31
|
+
release(): void;
|
|
32
|
+
/** Live active count (inspection/tests). */
|
|
33
|
+
readonly activeCount: number;
|
|
34
|
+
}
|
|
35
|
+
export declare function createCapsGate(): CapsGate;
|
|
36
|
+
//# sourceMappingURL=caps.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caps.d.ts","sourceRoot":"","sources":["../../../src/core/caps.ts"],"names":[],"mappings":"AAGA;;;;;;GAMG;AACH,MAAM,WAAW,YAAY;IAC5B,yEAAyE;IACzE,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG,UAAU,CAAC;AACnD,MAAM,MAAM,WAAW,GAAG;IAAE,KAAK,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,SAAS,CAAA;CAAE,CAAC;AAEhF,MAAM,WAAW,QAAQ;IACxB;;;;;;OAMG;IACH,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,GAAG,WAAW,CAAC;IAC5D,6FAA6F;IAC7F,OAAO,IAAI,IAAI,CAAC;IAChB,4CAA4C;IAC5C,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;CAC7B;AAID,wBAAgB,cAAc,IAAI,QAAQ,CA+BzC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright 2026 Sumit Patel
|
|
3
|
+
const HOUR_MS = 3_600_000;
|
|
4
|
+
export function createCapsGate() {
|
|
5
|
+
let active = 0;
|
|
6
|
+
// Rolling window of dispatched-run START times (ms). Per-hour is a rate on
|
|
7
|
+
// STARTS, so entries are pruned by age, never by release.
|
|
8
|
+
const startsMs = [];
|
|
9
|
+
return {
|
|
10
|
+
get activeCount() {
|
|
11
|
+
return active;
|
|
12
|
+
},
|
|
13
|
+
tryDispatch(caps, nowMs) {
|
|
14
|
+
// Concurrency FIRST (cheapest, trips most often), then per-hour. The FIRST
|
|
15
|
+
// cap that trips is the recorded reason.
|
|
16
|
+
if (caps.maxConcurrent !== undefined && active >= caps.maxConcurrent) {
|
|
17
|
+
return { allow: false, reason: "concurrency" };
|
|
18
|
+
}
|
|
19
|
+
const cutoff = nowMs - HOUR_MS;
|
|
20
|
+
while (startsMs.length > 0 && startsMs[0] <= cutoff) {
|
|
21
|
+
startsMs.shift();
|
|
22
|
+
}
|
|
23
|
+
if (caps.maxPerHour !== undefined && startsMs.length >= caps.maxPerHour) {
|
|
24
|
+
return { allow: false, reason: "per_hour" };
|
|
25
|
+
}
|
|
26
|
+
active++;
|
|
27
|
+
startsMs.push(nowMs);
|
|
28
|
+
return { allow: true };
|
|
29
|
+
},
|
|
30
|
+
release() {
|
|
31
|
+
if (active > 0)
|
|
32
|
+
active--;
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=caps.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caps.js","sourceRoot":"","sources":["../../../src/core/caps.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,6BAA6B;AAkC7B,MAAM,OAAO,GAAG,SAAS,CAAC;AAE1B,MAAM,UAAU,cAAc;IAC7B,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,2EAA2E;IAC3E,0DAA0D;IAC1D,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,OAAO;QACN,IAAI,WAAW;YACd,OAAO,MAAM,CAAC;QACf,CAAC;QACD,WAAW,CAAC,IAAI,EAAE,KAAK;YACtB,2EAA2E;YAC3E,yCAAyC;YACzC,IAAI,IAAI,CAAC,aAAa,KAAK,SAAS,IAAI,MAAM,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACtE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;YAChD,CAAC;YACD,MAAM,MAAM,GAAG,KAAK,GAAG,OAAO,CAAC;YAC/B,OAAO,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAK,QAAQ,CAAC,CAAC,CAAY,IAAI,MAAM,EAAE,CAAC;gBACjE,QAAQ,CAAC,KAAK,EAAE,CAAC;YAClB,CAAC;YACD,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACzE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,CAAC;YAC7C,CAAC;YACD,MAAM,EAAE,CAAC;YACT,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACrB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;QACxB,CAAC;QACD,OAAO;YACN,IAAI,MAAM,GAAG,CAAC;gBAAE,MAAM,EAAE,CAAC;QAC1B,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../../src/core/db.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,IAAI,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAYpE,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CA0D9D"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
// Copyright 2026 Sumit Patel
|
|
3
|
+
import { mkdirSync } from "node:fs";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
let DatabaseSync;
|
|
6
|
+
try {
|
|
7
|
+
const mod = await import("node:sqlite");
|
|
8
|
+
DatabaseSync = mod.DatabaseSync;
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
console.error("PrismaLens requires Node >= 22.13.");
|
|
12
|
+
process.exit(1);
|
|
13
|
+
}
|
|
14
|
+
export function openDatabase(baseDir) {
|
|
15
|
+
mkdirSync(baseDir, { recursive: true });
|
|
16
|
+
const db = new DatabaseSync(join(baseDir, "prismalens.db"));
|
|
17
|
+
db.exec(`
|
|
18
|
+
PRAGMA journal_mode = WAL;
|
|
19
|
+
PRAGMA busy_timeout = 5000;
|
|
20
|
+
PRAGMA foreign_keys = ON;
|
|
21
|
+
|
|
22
|
+
CREATE TABLE IF NOT EXISTS groups (
|
|
23
|
+
id TEXT PRIMARY KEY,
|
|
24
|
+
group_key TEXT,
|
|
25
|
+
formed_by TEXT NOT NULL DEFAULT 'window',
|
|
26
|
+
created_at TEXT NOT NULL
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
CREATE TABLE IF NOT EXISTS runs (
|
|
30
|
+
run_id TEXT PRIMARY KEY,
|
|
31
|
+
group_id TEXT REFERENCES groups(id),
|
|
32
|
+
status TEXT NOT NULL CHECK (status IN ('running','done','errored','suppressed')),
|
|
33
|
+
alertname TEXT,
|
|
34
|
+
agent TEXT,
|
|
35
|
+
repo TEXT,
|
|
36
|
+
workspace_path TEXT NOT NULL,
|
|
37
|
+
error TEXT,
|
|
38
|
+
suppression_reason TEXT,
|
|
39
|
+
created_at TEXT NOT NULL,
|
|
40
|
+
updated_at TEXT NOT NULL,
|
|
41
|
+
completed_at TEXT
|
|
42
|
+
);
|
|
43
|
+
CREATE INDEX IF NOT EXISTS idx_runs_created_at ON runs(created_at DESC);
|
|
44
|
+
CREATE INDEX IF NOT EXISTS idx_runs_status ON runs(status);
|
|
45
|
+
|
|
46
|
+
CREATE TABLE IF NOT EXISTS events (
|
|
47
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
48
|
+
run_id TEXT NOT NULL REFERENCES runs(run_id),
|
|
49
|
+
payload TEXT NOT NULL
|
|
50
|
+
);
|
|
51
|
+
CREATE INDEX IF NOT EXISTS idx_events_run ON events(run_id, id);
|
|
52
|
+
|
|
53
|
+
CREATE TABLE IF NOT EXISTS reports (
|
|
54
|
+
run_id TEXT PRIMARY KEY REFERENCES runs(run_id),
|
|
55
|
+
payload TEXT NOT NULL
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
-- One row per alert attached to a group, in insertion order (rowid).
|
|
59
|
+
-- late = 0 for the alerts that formed the window, 1 for alerts that
|
|
60
|
+
-- attached while the group's run was already in flight.
|
|
61
|
+
CREATE TABLE IF NOT EXISTS group_alerts (
|
|
62
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
63
|
+
group_id TEXT NOT NULL REFERENCES groups(id),
|
|
64
|
+
late INTEGER NOT NULL,
|
|
65
|
+
payload TEXT NOT NULL
|
|
66
|
+
);
|
|
67
|
+
CREATE INDEX IF NOT EXISTS idx_group_alerts ON group_alerts(group_id, id);
|
|
68
|
+
`);
|
|
69
|
+
return db;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"db.js","sourceRoot":"","sources":["../../../src/core/db.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,6BAA6B;AAE7B,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAGjC,IAAI,YAAqC,CAAC;AAE1C,IAAI,CAAC;IACJ,MAAM,GAAG,GAAG,MAAM,MAAM,CAAC,aAAa,CAAC,CAAC;IACxC,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC;AACjC,CAAC;AAAC,MAAM,CAAC;IACR,OAAO,CAAC,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACjB,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,OAAe;IAC3C,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACxC,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,IAAI,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC,CAAC;IAE5D,EAAE,CAAC,IAAI,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmDP,CAAC,CAAC;IAEH,OAAO,EAAE,CAAC;AACX,CAAC"}
|
|
@@ -17,8 +17,8 @@ export function createFileSessionStore(sessions, meta) {
|
|
|
17
17
|
completedAt: new Date().toISOString(),
|
|
18
18
|
});
|
|
19
19
|
},
|
|
20
|
-
async fail() {
|
|
21
|
-
await sessions.update(meta.runId, { status: "errored" });
|
|
20
|
+
async fail(error) {
|
|
21
|
+
await sessions.update(meta.runId, { status: "errored", error });
|
|
22
22
|
},
|
|
23
23
|
};
|
|
24
24
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-session-store.js","sourceRoot":"","sources":["../../../src/core/file-session-store.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,6BAA6B;AA4B7B,oFAAoF;AACpF,MAAM,UAAU,sBAAsB,CACrC,QAAwB,EACxB,IAAwB;IAExB,IAAI,OAAkC,CAAC;IAEvC,MAAM,KAAK,GAAuB;QACjC,KAAK,CAAC,MAAM;YACX,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,KAAqB;YACjC,MAAM,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC/C,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,MAA2B;YACvC,MAAM,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC/C,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE;gBACjC,MAAM,EAAE,MAAM;gBACd,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACrC,CAAC,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,IAAI;
|
|
1
|
+
{"version":3,"file":"file-session-store.js","sourceRoot":"","sources":["../../../src/core/file-session-store.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,6BAA6B;AA4B7B,oFAAoF;AACpF,MAAM,UAAU,sBAAsB,CACrC,QAAwB,EACxB,IAAwB;IAExB,IAAI,OAAkC,CAAC;IAEvC,MAAM,KAAK,GAAuB;QACjC,KAAK,CAAC,MAAM;YACX,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QACvC,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,KAAqB;YACjC,MAAM,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAC/C,CAAC;QACD,KAAK,CAAC,MAAM,CAAC,MAA2B;YACvC,MAAM,QAAQ,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;YAC/C,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE;gBACjC,MAAM,EAAE,MAAM;gBACd,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;aACrC,CAAC,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,KAAa;YACvB,MAAM,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC,CAAC;QACjE,CAAC;KACD,CAAC;IAEF,OAAO;QACN,KAAK;QACL,aAAa;YACZ,IAAI,CAAC,OAAO,EAAE,CAAC;gBACd,MAAM,IAAI,KAAK,CACd,uDAAuD,CACvD,CAAC;YACH,CAAC;YACD,OAAO,OAAO,CAAC,aAAa,CAAC;QAC9B,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -4,6 +4,8 @@ export type { ResolvedInvestigation };
|
|
|
4
4
|
export interface ResolveInvestigationArgs {
|
|
5
5
|
/** Raw alert payload (piped JSON / RPC param) coerced into a FiringAlert. */
|
|
6
6
|
alert?: Record<string, unknown>;
|
|
7
|
+
/** Multiple raw alerts (storm grouping). When present, supersedes `alert`. */
|
|
8
|
+
alerts?: Record<string, unknown>[];
|
|
7
9
|
/** Free-text fallback → a synthesized alert when no alert payload is supplied. */
|
|
8
10
|
query?: string;
|
|
9
11
|
/** Repository the harness investigates (its cwd). Defaults to `process.cwd()`. */
|
|
@@ -31,6 +33,8 @@ export interface ResolveInvestigationArgs {
|
|
|
31
33
|
* console warning.
|
|
32
34
|
*/
|
|
33
35
|
requestedSandbox?: string;
|
|
36
|
+
/** Per-run turn ceiling for the default harness (issue #62). Forwarded to the engine. */
|
|
37
|
+
maxTurns?: number;
|
|
34
38
|
}
|
|
35
39
|
/**
|
|
36
40
|
* Resolve a seed alert + merged `pl.config.yaml` into the inputs
|
|
@@ -38,5 +42,11 @@ export interface ResolveInvestigationArgs {
|
|
|
38
42
|
* the BYO-key secrets from env, and delegates the actual build to the engine
|
|
39
43
|
* resolver. Throws (via the engine) on a hard input error.
|
|
40
44
|
*/
|
|
45
|
+
export declare function isSynthConfigured(config: PlConfig): boolean;
|
|
41
46
|
export declare function resolveInvestigation(args: ResolveInvestigationArgs, config: PlConfig): ResolvedInvestigation;
|
|
47
|
+
/**
|
|
48
|
+
* The alert's service identity label — `service`, else `namespace`, else `job`.
|
|
49
|
+
* Exported for the `listen` path's per-payload repo resolution (issue #58 AC5).
|
|
50
|
+
*/
|
|
51
|
+
export declare function pickServiceLabel(alert: Record<string, unknown> | undefined): string | undefined;
|
|
42
52
|
//# sourceMappingURL=run-investigation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run-investigation.d.ts","sourceRoot":"","sources":["../../../src/core/run-investigation.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"run-investigation.d.ts","sourceRoot":"","sources":["../../../src/core/run-investigation.ts"],"names":[],"mappings":"AAyBA,OAAO,EAIN,KAAK,qBAAqB,EAC1B,KAAK,OAAO,EAEZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AAEpD,YAAY,EAAE,qBAAqB,EAAE,CAAC;AAEtC,MAAM,WAAW,wBAAwB;IACxC,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,8EAA8E;IAC9E,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IACnC,kFAAkF;IAClF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kFAAkF;IAClF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yFAAyF;IACzF,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,QAAQ,GAAG,OAAO,CAa3D;AAED,wBAAgB,oBAAoB,CACnC,IAAI,EAAE,wBAAwB,EAC9B,MAAM,EAAE,QAAQ,GACd,qBAAqB,CAwIvB;AAwCD;;;GAGG;AACH,wBAAgB,gBAAgB,CAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GACxC,MAAM,GAAG,SAAS,CAIpB"}
|