@shield-agent/kya 0.33.5 → 0.34.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/.cursor-plugin/plugin.json +1 -1
- package/.mcp.json +1 -1
- package/README.md +22 -5
- package/amp/settings.example.json +1 -1
- package/assets/screenshot-features.json +17 -0
- package/claude/claude_desktop_config.example.json +1 -1
- package/cline/cline_mcp_settings.example.json +1 -1
- package/copilot/mcp-config.example.json +1 -1
- package/dist/alerts/config.d.ts +22 -0
- package/dist/alerts/config.d.ts.map +1 -0
- package/dist/alerts/config.js +59 -0
- package/dist/alerts/config.js.map +1 -0
- package/dist/alerts/constants.d.ts +5 -0
- package/dist/alerts/constants.d.ts.map +1 -0
- package/dist/alerts/constants.js +5 -0
- package/dist/alerts/constants.js.map +1 -0
- package/dist/alerts/desktop.d.ts +19 -0
- package/dist/alerts/desktop.d.ts.map +1 -0
- package/dist/alerts/desktop.js +57 -0
- package/dist/alerts/desktop.js.map +1 -0
- package/dist/alerts/incident-alert.d.ts +42 -0
- package/dist/alerts/incident-alert.d.ts.map +1 -0
- package/dist/alerts/incident-alert.js +84 -0
- package/dist/alerts/incident-alert.js.map +1 -0
- package/dist/alerts/scan.d.ts +37 -0
- package/dist/alerts/scan.d.ts.map +1 -0
- package/dist/alerts/scan.js +188 -0
- package/dist/alerts/scan.js.map +1 -0
- package/dist/alerts/state.d.ts +55 -0
- package/dist/alerts/state.d.ts.map +1 -0
- package/dist/alerts/state.js +178 -0
- package/dist/alerts/state.js.map +1 -0
- package/dist/alerts/triage-input.d.ts +36 -0
- package/dist/alerts/triage-input.d.ts.map +1 -0
- package/dist/alerts/triage-input.js +159 -0
- package/dist/alerts/triage-input.js.map +1 -0
- package/dist/alerts/triage-model.d.ts +42 -0
- package/dist/alerts/triage-model.d.ts.map +1 -0
- package/dist/alerts/triage-model.js +126 -0
- package/dist/alerts/triage-model.js.map +1 -0
- package/dist/alerts/triage-prompt.d.ts +23 -0
- package/dist/alerts/triage-prompt.d.ts.map +1 -0
- package/dist/alerts/triage-prompt.js +53 -0
- package/dist/alerts/triage-prompt.js.map +1 -0
- package/dist/alerts/triage-schema.json +52 -0
- package/dist/alerts/triage-setup.d.ts +73 -0
- package/dist/alerts/triage-setup.d.ts.map +1 -0
- package/dist/alerts/triage-setup.js +280 -0
- package/dist/alerts/triage-setup.js.map +1 -0
- package/dist/alerts/triage-status.d.ts +26 -0
- package/dist/alerts/triage-status.d.ts.map +1 -0
- package/dist/alerts/triage-status.js +61 -0
- package/dist/alerts/triage-status.js.map +1 -0
- package/dist/alerts/triage-tokenizer.d.ts +29 -0
- package/dist/alerts/triage-tokenizer.d.ts.map +1 -0
- package/dist/alerts/triage-tokenizer.js +82 -0
- package/dist/alerts/triage-tokenizer.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/alerts.d.ts +16 -0
- package/dist/commands/alerts.d.ts.map +1 -0
- package/dist/commands/alerts.js +112 -0
- package/dist/commands/alerts.js.map +1 -0
- package/dist/commands/notify-flush.d.ts.map +1 -1
- package/dist/commands/notify-flush.js +3 -0
- package/dist/commands/notify-flush.js.map +1 -1
- package/dist/commands/receipt-serve.d.ts +1 -1
- package/dist/commands/receipt-serve.d.ts.map +1 -1
- package/dist/commands/receipt-serve.js +3 -2
- package/dist/commands/receipt-serve.js.map +1 -1
- package/dist/investigate/detectors.d.ts +6 -0
- package/dist/investigate/detectors.d.ts.map +1 -1
- package/dist/investigate/detectors.js +10 -0
- package/dist/investigate/detectors.js.map +1 -1
- package/dist/notify/dispatch.d.ts +1 -1
- package/dist/notify/dispatch.d.ts.map +1 -1
- package/dist/notify/dispatch.js +4 -1
- package/dist/notify/dispatch.js.map +1 -1
- package/dist/notify/incident-templates.d.ts +23 -0
- package/dist/notify/incident-templates.d.ts.map +1 -0
- package/dist/notify/incident-templates.js +128 -0
- package/dist/notify/incident-templates.js.map +1 -0
- package/dist/notify/index.d.ts +12 -0
- package/dist/notify/index.d.ts.map +1 -1
- package/dist/notify/index.js +50 -3
- package/dist/notify/index.js.map +1 -1
- package/dist/notify/templates.d.ts +6 -0
- package/dist/notify/templates.d.ts.map +1 -1
- package/dist/notify/templates.js +12 -2
- package/dist/notify/templates.js.map +1 -1
- package/dist/receipt/live-server.d.ts +4 -0
- package/dist/receipt/live-server.d.ts.map +1 -1
- package/dist/receipt/live-server.js +48 -0
- package/dist/receipt/live-server.js.map +1 -1
- package/dist/receipt/render-receipt.d.ts +3 -0
- package/dist/receipt/render-receipt.d.ts.map +1 -1
- package/dist/receipt/render-receipt.js +28 -1
- package/dist/receipt/render-receipt.js.map +1 -1
- package/dist/trail.d.ts +6 -0
- package/dist/trail.d.ts.map +1 -1
- package/dist/trail.js +11 -0
- package/dist/trail.js.map +1 -1
- package/droid/README.md +1 -1
- package/droid/mcp.example.json +1 -1
- package/gemini/settings.example.json +1 -1
- package/grok/README.md +2 -2
- package/kilo/kilo.example.json +1 -1
- package/kimi/mcp.example.json +1 -1
- package/kiro/mcp.example.json +1 -1
- package/manifest.json +1 -1
- package/mastracode/mcp.example.json +1 -1
- package/mcp.json +1 -1
- package/openai/codex.config.example.toml +1 -1
- package/opencode/opencode.example.json +1 -1
- package/package.json +1 -1
- package/qwen/settings.example.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One-time offer of security alerts with local triage, made by `kya start` (same pattern as
|
|
3
|
+
* receipt/semantic-setup.ts). Alerts tell you when KYA detects a security incident (destructive change,
|
|
4
|
+
* secret access, exfiltration, repeated denies). The optional local model adds a category, an urgency and a
|
|
5
|
+
* suggested action to each alert. It runs offline after one download. Advisory: it never blocks anything.
|
|
6
|
+
*
|
|
7
|
+
* Asks once, in a terminal. Yes: installs the runtime and the model, turns alerts on in the USER-level config,
|
|
8
|
+
* sends one test alert. No: remembered (alerts-choice.json), never asked again. Without a terminal: one hint line.
|
|
9
|
+
* `KYA_ALERTS=on` installs without asking (scripts, images). `KYA_ALERTS=off` never asks.
|
|
10
|
+
* Never fails `kya start`: any problem prints the manual command and moves on. Without the model, alerts still
|
|
11
|
+
* work with the detector severity.
|
|
12
|
+
*/
|
|
13
|
+
import { execFile } from "node:child_process";
|
|
14
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
15
|
+
import { createWriteStream, mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
16
|
+
import { dirname, join } from "node:path";
|
|
17
|
+
import { createInterface } from "node:readline";
|
|
18
|
+
import { Readable, Transform } from "node:stream";
|
|
19
|
+
import { pipeline } from "node:stream/promises";
|
|
20
|
+
import { kyaHome, globalConfigDir, readFileConfig } from "../config.js";
|
|
21
|
+
import { notifyIncident, resolveIncidentWebhooks } from "../notify/index.js";
|
|
22
|
+
import { resolveAlertsConfig, writeAlertsEnabled } from "./config.js";
|
|
23
|
+
import { desktopNotify } from "./desktop.js";
|
|
24
|
+
import { buildTestIncidentAlert } from "./incident-alert.js";
|
|
25
|
+
import { TRIAGE_MODEL_HOST, TRIAGE_MODEL_MAX_BYTES, TRIAGE_MODEL_MB, TRIAGE_MODEL_SHA256, TRIAGE_MODEL_URL, TRIAGE_RUNTIME_PACKAGE, triageInstallCommand, triageInstalled, triageModelInstallPath, triageModelPresent, triageRuntimeDir, triageRuntimeInstalled, } from "./triage-status.js";
|
|
26
|
+
const CHOICE_FILE = "alerts-choice.json";
|
|
27
|
+
const INSTALL_TIMEOUT_MS = 5 * 60_000;
|
|
28
|
+
/** Time to the response headers (connect and first byte). */
|
|
29
|
+
const DOWNLOAD_CONNECT_TIMEOUT_MS = 10_000;
|
|
30
|
+
/** Longest silence while the body streams. */
|
|
31
|
+
const DOWNLOAD_READ_TIMEOUT_MS = 60_000;
|
|
32
|
+
/** A model file smaller than this is not a model (error page, empty body). */
|
|
33
|
+
const MIN_MODEL_BYTES = 1_000_000;
|
|
34
|
+
const NOTICE = [
|
|
35
|
+
"Security alerts (optional).",
|
|
36
|
+
"KYA tells you when it detects a security incident: a destructive change, secret access, data exfiltration or repeated denies.",
|
|
37
|
+
`A small local model adds a category, an urgency and a next step to each alert. It runs fully offline after one download: about ${TRIAGE_MODEL_MB} MB for the model and about 100 MB for a local runtime. Nothing leaves this machine.`,
|
|
38
|
+
"Alerts are advisory: local KYA never blocks because of them.",
|
|
39
|
+
];
|
|
40
|
+
function choicePath(env) {
|
|
41
|
+
return join(globalConfigDir(env), CHOICE_FILE);
|
|
42
|
+
}
|
|
43
|
+
function declinedBefore(env) {
|
|
44
|
+
try {
|
|
45
|
+
return JSON.parse(readFileSync(choicePath(env), "utf8")).answer === "no";
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
function recordChoice(env, answer) {
|
|
52
|
+
try {
|
|
53
|
+
mkdirSync(globalConfigDir(env), { recursive: true });
|
|
54
|
+
writeFileSync(choicePath(env), `${JSON.stringify({ answer, askedAt: new Date().toISOString() })}\n`, { mode: 0o600 });
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
/* a lost answer only means we may ask again */
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/** Other platforms' native binaries are dead weight (about 200 MB). Removes them from our own runtime dir. */
|
|
61
|
+
function pruneOtherPlatforms(env) {
|
|
62
|
+
try {
|
|
63
|
+
const bin = join(triageRuntimeDir(env), "node_modules", "onnxruntime-node", "bin");
|
|
64
|
+
for (const napi of readdirSync(bin)) {
|
|
65
|
+
for (const plat of readdirSync(join(bin, napi))) {
|
|
66
|
+
if (plat !== process.platform)
|
|
67
|
+
rmSync(join(bin, napi, plat), { recursive: true, force: true });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
/* pruning is only a size saving */
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/** `npm install --prefix <dir> onnxruntime-node@1.30.0`. Fixed arguments, no user text. */
|
|
76
|
+
export function installTriageRuntime(env) {
|
|
77
|
+
const dir = triageRuntimeDir(env);
|
|
78
|
+
try {
|
|
79
|
+
mkdirSync(dir, { recursive: true });
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
return Promise.resolve({ ok: false, detail: err instanceof Error ? err.message : String(err) });
|
|
83
|
+
}
|
|
84
|
+
const win = process.platform === "win32";
|
|
85
|
+
return new Promise((resolve) => {
|
|
86
|
+
execFile(win ? "npm.cmd" : "npm",
|
|
87
|
+
// --ignore-scripts: the only install script of onnxruntime-node downloads CUDA binaries on Linux x64 (hundreds of MB). The CPU binary is bundled.
|
|
88
|
+
["install", "--prefix", win ? `"${dir}"` : dir, "--no-audit", "--no-fund", "--ignore-scripts", TRIAGE_RUNTIME_PACKAGE], { env: { ...env, ONNXRUNTIME_NODE_INSTALL: "skip" }, timeout: INSTALL_TIMEOUT_MS, windowsHide: true, shell: win }, (err, _stdout, stderr) => {
|
|
89
|
+
if (err)
|
|
90
|
+
return resolve({ ok: false, detail: (String(stderr).trim().split("\n").pop() || err.message).slice(0, 200) });
|
|
91
|
+
pruneOtherPlatforms(env);
|
|
92
|
+
resolve({ ok: triageRuntimeInstalled(env) });
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/** https, exactly the model host, default port, no credentials. No exception for any other host or scheme. */
|
|
97
|
+
export function modelUrlRefusal(url) {
|
|
98
|
+
let u;
|
|
99
|
+
try {
|
|
100
|
+
u = new URL(url);
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return "model URL is not valid";
|
|
104
|
+
}
|
|
105
|
+
if (u.protocol !== "https:")
|
|
106
|
+
return "model URL must use https";
|
|
107
|
+
if (u.hostname !== TRIAGE_MODEL_HOST || u.port !== "" || u.username !== "" || u.password !== "")
|
|
108
|
+
return `model URL must be on ${TRIAGE_MODEL_HOST}`;
|
|
109
|
+
return undefined;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Download the pinned model once. The URL is a constant: no environment variable or option changes it
|
|
113
|
+
* (`KYA_TRIAGE_MODEL_URL` is ignored).
|
|
114
|
+
*/
|
|
115
|
+
export function downloadTriageModel(env) {
|
|
116
|
+
return downloadModelFrom(env, { url: TRIAGE_MODEL_URL });
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The download, for any source (tests). Rules: https only, one host, redirects are never followed (a 3xx is a failure), the
|
|
120
|
+
* response must declare a Content-Length of at most 200 MB, the stream is cut off past the cap, the bytes are
|
|
121
|
+
* hashed while they are written to a temp file next to the target, and only a file with the pinned sha256 is
|
|
122
|
+
* renamed into place (atomic). The temp file is removed on any failure. Timeouts: 10 s to the headers, 60 s of
|
|
123
|
+
* silence while streaming.
|
|
124
|
+
*/
|
|
125
|
+
export async function downloadModelFrom(env, deps) {
|
|
126
|
+
const target = triageModelInstallPath(env);
|
|
127
|
+
const tmp = `${target}.${randomBytes(8).toString("hex")}.part`;
|
|
128
|
+
const abort = new AbortController();
|
|
129
|
+
const cap = deps.maxBytes ?? TRIAGE_MODEL_MAX_BYTES;
|
|
130
|
+
let timer;
|
|
131
|
+
const arm = (ms, what) => {
|
|
132
|
+
if (timer)
|
|
133
|
+
clearTimeout(timer);
|
|
134
|
+
timer = setTimeout(() => abort.abort(new Error(what)), ms);
|
|
135
|
+
};
|
|
136
|
+
try {
|
|
137
|
+
const url = deps.url;
|
|
138
|
+
const refusal = (deps.refusal ?? modelUrlRefusal)(url);
|
|
139
|
+
if (refusal)
|
|
140
|
+
return { ok: false, detail: refusal };
|
|
141
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
142
|
+
arm(deps.connectTimeoutMs ?? DOWNLOAD_CONNECT_TIMEOUT_MS, "download timed out (no answer in 10 s)");
|
|
143
|
+
const res = await (deps.fetch ?? fetch)(url, { redirect: "manual", signal: abort.signal });
|
|
144
|
+
if (res.status >= 300 && res.status < 400)
|
|
145
|
+
return { ok: false, detail: `download refused: redirect (HTTP ${res.status}) is not followed` };
|
|
146
|
+
if (!res.ok || !res.body)
|
|
147
|
+
return { ok: false, detail: `download failed (HTTP ${res.status})` };
|
|
148
|
+
const declared = res.headers.get("content-length");
|
|
149
|
+
if (declared === null || !/^\d{1,12}$/.test(declared))
|
|
150
|
+
return { ok: false, detail: "download refused: no Content-Length" };
|
|
151
|
+
if (Number(declared) > cap)
|
|
152
|
+
return { ok: false, detail: "download refused: file is larger than 200 MB" };
|
|
153
|
+
const hash = createHash("sha256");
|
|
154
|
+
let bytes = 0;
|
|
155
|
+
// pipeline closes both ends and passes any stream error on, so a broken write cannot crash the process.
|
|
156
|
+
await pipeline(Readable.fromWeb(res.body), new Transform({
|
|
157
|
+
transform(chunk, _enc, cb) {
|
|
158
|
+
bytes += chunk.length;
|
|
159
|
+
if (bytes > cap)
|
|
160
|
+
return cb(new Error("download aborted: more than 200 MB"));
|
|
161
|
+
arm(deps.readTimeoutMs ?? DOWNLOAD_READ_TIMEOUT_MS, "download timed out (no data for 60 s)");
|
|
162
|
+
hash.update(chunk);
|
|
163
|
+
cb(null, chunk);
|
|
164
|
+
},
|
|
165
|
+
}), createWriteStream(tmp, { mode: 0o600 }), { signal: abort.signal });
|
|
166
|
+
const want = (deps.sha256 ?? TRIAGE_MODEL_SHA256).toLowerCase();
|
|
167
|
+
if (hash.digest("hex") !== want) {
|
|
168
|
+
rmSync(tmp, { force: true });
|
|
169
|
+
return { ok: false, detail: "sha256 does not match the pinned value: file refused" };
|
|
170
|
+
}
|
|
171
|
+
if (bytes < MIN_MODEL_BYTES) {
|
|
172
|
+
rmSync(tmp, { force: true });
|
|
173
|
+
return { ok: false, detail: "model file is too small: refused" };
|
|
174
|
+
}
|
|
175
|
+
renameSync(tmp, target);
|
|
176
|
+
return { ok: true };
|
|
177
|
+
}
|
|
178
|
+
catch (err) {
|
|
179
|
+
const reason = abort.signal.aborted && abort.signal.reason instanceof Error ? abort.signal.reason : err;
|
|
180
|
+
return { ok: false, detail: (reason instanceof Error ? reason.message : String(reason)).slice(0, 200) };
|
|
181
|
+
}
|
|
182
|
+
finally {
|
|
183
|
+
if (timer)
|
|
184
|
+
clearTimeout(timer);
|
|
185
|
+
rmSync(tmp, { force: true });
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
/** Desktop notification plus every configured incident webhook, marked as a test. */
|
|
189
|
+
export async function sendTestAlert(env) {
|
|
190
|
+
const alert = buildTestIncidentAlert();
|
|
191
|
+
const desktop = resolveAlertsConfig(env).desktop ? await desktopNotify(alert, env) : false;
|
|
192
|
+
const targets = resolveIncidentWebhooks(readFileConfig(kyaHome(env)));
|
|
193
|
+
const webhooks = targets.length > 0 ? await notifyIncident(alert, targets, env) : 0;
|
|
194
|
+
return { desktop, webhooks };
|
|
195
|
+
}
|
|
196
|
+
function defaultAsk(question) {
|
|
197
|
+
return new Promise((resolve) => {
|
|
198
|
+
// Prompt on stderr so stdout stays clean for anything piping the command's output.
|
|
199
|
+
const rl = createInterface({ input: process.stdin, output: process.stderr });
|
|
200
|
+
rl.question(`${question} `, (answer) => {
|
|
201
|
+
rl.close();
|
|
202
|
+
resolve(answer);
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
async function runInstall(io, env) {
|
|
207
|
+
io.error("Turning on security alerts. The local model download can take a few minutes...");
|
|
208
|
+
const wasOn = readFileConfig(kyaHome(env)).alerts?.enabled === true;
|
|
209
|
+
let modelOk = true;
|
|
210
|
+
let installedNow = false;
|
|
211
|
+
if (!triageRuntimeInstalled(env)) {
|
|
212
|
+
const r = await (io.installRuntime ?? installTriageRuntime)(env);
|
|
213
|
+
if (!r.ok) {
|
|
214
|
+
modelOk = false;
|
|
215
|
+
io.error(`Could not install the local runtime${r.detail ? ` (${r.detail})` : ""}.`);
|
|
216
|
+
}
|
|
217
|
+
else
|
|
218
|
+
installedNow = true;
|
|
219
|
+
}
|
|
220
|
+
if (modelOk && !triageModelPresent(env)) {
|
|
221
|
+
const r = await (io.downloadModel ?? downloadTriageModel)(env);
|
|
222
|
+
if (!r.ok) {
|
|
223
|
+
modelOk = false;
|
|
224
|
+
io.error(`Could not get the local model${r.detail ? ` (${r.detail})` : ""}.`);
|
|
225
|
+
}
|
|
226
|
+
else
|
|
227
|
+
installedNow = true;
|
|
228
|
+
}
|
|
229
|
+
try {
|
|
230
|
+
writeAlertsEnabled(env, true);
|
|
231
|
+
}
|
|
232
|
+
catch (err) {
|
|
233
|
+
io.error(`Could not write the alerts setting (${err instanceof Error ? err.message : String(err)}). Try later: ${triageInstallCommand()}`);
|
|
234
|
+
return "partial";
|
|
235
|
+
}
|
|
236
|
+
if (modelOk)
|
|
237
|
+
io.error("Security alerts are on, with local triage.");
|
|
238
|
+
else
|
|
239
|
+
io.error(`Security alerts are on with the detector severity only. Add the local model later: ${triageInstallCommand()}`);
|
|
240
|
+
// KYA_ALERTS=on runs this on every start while the model is missing: send the test alert only when this run changed something.
|
|
241
|
+
if (wasOn && !installedNow)
|
|
242
|
+
return modelOk ? "installed" : "partial";
|
|
243
|
+
try {
|
|
244
|
+
const t = await (io.testAlert ?? sendTestAlert)(env);
|
|
245
|
+
const where = [t.desktop ? "a desktop notification" : "", t.webhooks > 0 ? `${t.webhooks} webhook(s)` : ""].filter(Boolean);
|
|
246
|
+
io.error(where.length > 0 ? `Sent a test alert: ${where.join(" and ")}.` : "No desktop notifier found and no webhook set: alerts show in the report only.");
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
/* a failed test alert does not change anything else */
|
|
250
|
+
}
|
|
251
|
+
return modelOk ? "installed" : "partial";
|
|
252
|
+
}
|
|
253
|
+
export async function maybeOfferTriageAlerts(io, env) {
|
|
254
|
+
const mode = env.KYA_ALERTS?.trim().toLowerCase();
|
|
255
|
+
if (mode === "off" || mode === "0" || mode === "false")
|
|
256
|
+
return "skipped";
|
|
257
|
+
if (triageInstalled(env))
|
|
258
|
+
return "already";
|
|
259
|
+
if (mode === "on" || mode === "1" || mode === "true")
|
|
260
|
+
return runInstall(io, env);
|
|
261
|
+
// An explicit user-level choice (`kya alerts on|off`) is a decision: do not ask.
|
|
262
|
+
if (resolveAlertsConfig(env).source === "config" || declinedBefore(env))
|
|
263
|
+
return "skipped";
|
|
264
|
+
const interactive = io.isTty ?? Boolean(process.stdin.isTTY && process.stderr.isTTY);
|
|
265
|
+
if (!interactive) {
|
|
266
|
+
io.error(`Security alerts are off. Turn them on: ${triageInstallCommand()}`);
|
|
267
|
+
return "hinted";
|
|
268
|
+
}
|
|
269
|
+
for (const line of NOTICE)
|
|
270
|
+
io.error(line);
|
|
271
|
+
const answer = await (io.ask ?? defaultAsk)("Turn on security alerts? [Y/n]");
|
|
272
|
+
const no = /^n(o)?$/i.test(answer.trim());
|
|
273
|
+
recordChoice(env, no ? "no" : "yes");
|
|
274
|
+
if (no) {
|
|
275
|
+
io.error(`No problem. Turn it on later: ${triageInstallCommand()}`);
|
|
276
|
+
return "declined";
|
|
277
|
+
}
|
|
278
|
+
return runInstall(io, env);
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=triage-setup.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triage-setup.js","sourceRoot":"","sources":["../../src/alerts/triage-setup.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** Pinned exact version, published 2026-09-14. No network at hook time: it is installed once, by the offer. */
|
|
2
|
+
export declare const TRIAGE_RUNTIME_PACKAGE = "onnxruntime-node@1.30.0";
|
|
3
|
+
export declare const TRIAGE_RUNTIME_NAME = "onnxruntime-node";
|
|
4
|
+
export declare const TRIAGE_MODEL_ID = "kya-triage-v1";
|
|
5
|
+
/** The only host the model is downloaded from: a public Cloudflare R2 bucket (`kya-models`) behind a custom domain. */
|
|
6
|
+
export declare const TRIAGE_MODEL_HOST = "models.shield-agent.com";
|
|
7
|
+
/** Immutable object path (a new model is a new path). Upload steps: docs/operations/kya-triage-model-release.md. */
|
|
8
|
+
export declare const TRIAGE_MODEL_URL = "https://models.shield-agent.com/triage-model-v1/kya-triage-v1.bin";
|
|
9
|
+
/** A model file larger than this is refused (the real file is about 145 MiB). */
|
|
10
|
+
export declare const TRIAGE_MODEL_MAX_BYTES: number;
|
|
11
|
+
/** sha256 of the packed model file (of the uploaded object). A download with another hash is refused. */
|
|
12
|
+
export declare const TRIAGE_MODEL_SHA256 = "9df79939edaef4bdadbb9972bf357a9f7c396b6a837489f438974a54e00be786";
|
|
13
|
+
export declare const TRIAGE_MODEL_MB = 150;
|
|
14
|
+
export declare function triageRuntimeDir(env?: NodeJS.ProcessEnv): string;
|
|
15
|
+
/** Where the offer writes the model. */
|
|
16
|
+
export declare function triageModelInstallPath(env?: NodeJS.ProcessEnv): string;
|
|
17
|
+
/** The model file to load. `KYA_TRIAGE_MODEL_PATH` points at a locally built file (tests, development). */
|
|
18
|
+
export declare function triageModelFile(env?: NodeJS.ProcessEnv): string;
|
|
19
|
+
/** The one command that installs the runtime and the model (printed when an install fails). */
|
|
20
|
+
export declare function triageInstallCommand(): string;
|
|
21
|
+
/** True when the runtime package files exist under the opt-in prefix. Nothing is loaded. */
|
|
22
|
+
export declare function triageRuntimeInstalled(env?: NodeJS.ProcessEnv): boolean;
|
|
23
|
+
export declare function triageModelPresent(env?: NodeJS.ProcessEnv): boolean;
|
|
24
|
+
/** Runtime and model are both there: the alert scan then adds triage to each new incident alert. */
|
|
25
|
+
export declare function triageInstalled(env?: NodeJS.ProcessEnv): boolean;
|
|
26
|
+
//# sourceMappingURL=triage-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triage-status.d.ts","sourceRoot":"","sources":["../../src/alerts/triage-status.ts"],"names":[],"mappings":"AAUA,+GAA+G;AAC/G,eAAO,MAAM,sBAAsB,4BAA4B,CAAC;AAChE,eAAO,MAAM,mBAAmB,qBAAqB,CAAC;AACtD,eAAO,MAAM,eAAe,kBAAkB,CAAC;AAC/C,uHAAuH;AACvH,eAAO,MAAM,iBAAiB,4BAA4B,CAAC;AAC3D,oHAAoH;AACpH,eAAO,MAAM,gBAAgB,sEAAmE,CAAC;AACjG,iFAAiF;AACjF,eAAO,MAAM,sBAAsB,QAAoB,CAAC;AACxD,yGAAyG;AACzG,eAAO,MAAM,mBAAmB,qEAAqE,CAAC;AACtG,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC,wBAAgB,gBAAgB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAE7E;AAED,wCAAwC;AACxC,wBAAgB,sBAAsB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAEnF;AAED,2GAA2G;AAC3G,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CAG5E;AAED,+FAA+F;AAC/F,wBAAgB,oBAAoB,IAAI,MAAM,CAE7C;AAED,4FAA4F;AAC5F,wBAAgB,sBAAsB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAOpF;AAED,wBAAgB,kBAAkB,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAMhF;AAED,oGAAoG;AACpG,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,OAAO,CAE7E"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether the opt-in local triage model is installed. Light on purpose: the alert scan and `kya start`
|
|
3
|
+
* import it, so it loads no code from the runtime and no model. See triage-model.ts for the loader.
|
|
4
|
+
* Runtime: onnxruntime-node under <kya home>/.kya/triage (same pattern as the plain-language search runtime).
|
|
5
|
+
* Model: one file, downloaded once from models.shield-agent.com (R2), sha256 pinned below.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, realpathSync, statSync } from "node:fs";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { globalConfigDir } from "../config.js";
|
|
10
|
+
/** Pinned exact version, published 2026-09-14. No network at hook time: it is installed once, by the offer. */
|
|
11
|
+
export const TRIAGE_RUNTIME_PACKAGE = "onnxruntime-node@1.30.0";
|
|
12
|
+
export const TRIAGE_RUNTIME_NAME = "onnxruntime-node";
|
|
13
|
+
export const TRIAGE_MODEL_ID = "kya-triage-v1";
|
|
14
|
+
/** The only host the model is downloaded from: a public Cloudflare R2 bucket (`kya-models`) behind a custom domain. */
|
|
15
|
+
export const TRIAGE_MODEL_HOST = "models.shield-agent.com";
|
|
16
|
+
/** Immutable object path (a new model is a new path). Upload steps: docs/operations/kya-triage-model-release.md. */
|
|
17
|
+
export const TRIAGE_MODEL_URL = `https://${TRIAGE_MODEL_HOST}/triage-model-v1/kya-triage-v1.bin`;
|
|
18
|
+
/** A model file larger than this is refused (the real file is about 145 MiB). */
|
|
19
|
+
export const TRIAGE_MODEL_MAX_BYTES = 200 * 1024 * 1024;
|
|
20
|
+
/** sha256 of the packed model file (of the uploaded object). A download with another hash is refused. */
|
|
21
|
+
export const TRIAGE_MODEL_SHA256 = "9df79939edaef4bdadbb9972bf357a9f7c396b6a837489f438974a54e00be786";
|
|
22
|
+
export const TRIAGE_MODEL_MB = 150;
|
|
23
|
+
export function triageRuntimeDir(env = process.env) {
|
|
24
|
+
return join(globalConfigDir(env), "triage");
|
|
25
|
+
}
|
|
26
|
+
/** Where the offer writes the model. */
|
|
27
|
+
export function triageModelInstallPath(env = process.env) {
|
|
28
|
+
return join(triageRuntimeDir(env), "model", `${TRIAGE_MODEL_ID}.bin`);
|
|
29
|
+
}
|
|
30
|
+
/** The model file to load. `KYA_TRIAGE_MODEL_PATH` points at a locally built file (tests, development). */
|
|
31
|
+
export function triageModelFile(env = process.env) {
|
|
32
|
+
const override = env.KYA_TRIAGE_MODEL_PATH?.trim();
|
|
33
|
+
return override ? override : triageModelInstallPath(env);
|
|
34
|
+
}
|
|
35
|
+
/** The one command that installs the runtime and the model (printed when an install fails). */
|
|
36
|
+
export function triageInstallCommand() {
|
|
37
|
+
return "KYA_ALERTS=on kya start";
|
|
38
|
+
}
|
|
39
|
+
/** True when the runtime package files exist under the opt-in prefix. Nothing is loaded. */
|
|
40
|
+
export function triageRuntimeInstalled(env = process.env) {
|
|
41
|
+
try {
|
|
42
|
+
const root = realpathSync(triageRuntimeDir(env));
|
|
43
|
+
return existsSync(join(root, "node_modules", TRIAGE_RUNTIME_NAME, "package.json"));
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
export function triageModelPresent(env = process.env) {
|
|
50
|
+
try {
|
|
51
|
+
return statSync(triageModelFile(env)).size > 0;
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
/** Runtime and model are both there: the alert scan then adds triage to each new incident alert. */
|
|
58
|
+
export function triageInstalled(env = process.env) {
|
|
59
|
+
return triageRuntimeInstalled(env) && triageModelPresent(env);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=triage-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triage-status.js","sourceRoot":"","sources":["../../src/alerts/triage-status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,+GAA+G;AAC/G,MAAM,CAAC,MAAM,sBAAsB,GAAG,yBAAyB,CAAC;AAChE,MAAM,CAAC,MAAM,mBAAmB,GAAG,kBAAkB,CAAC;AACtD,MAAM,CAAC,MAAM,eAAe,GAAG,eAAe,CAAC;AAC/C,uHAAuH;AACvH,MAAM,CAAC,MAAM,iBAAiB,GAAG,yBAAyB,CAAC;AAC3D,oHAAoH;AACpH,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,iBAAiB,oCAAoC,CAAC;AACjG,iFAAiF;AACjF,MAAM,CAAC,MAAM,sBAAsB,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAC;AACxD,yGAAyG;AACzG,MAAM,CAAC,MAAM,mBAAmB,GAAG,kEAAkE,CAAC;AACtG,MAAM,CAAC,MAAM,eAAe,GAAG,GAAG,CAAC;AAEnC,MAAM,UAAU,gBAAgB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACnE,OAAO,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC9C,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,sBAAsB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACzE,OAAO,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,OAAO,EAAE,GAAG,eAAe,MAAM,CAAC,CAAC;AACxE,CAAC;AAED,2GAA2G;AAC3G,MAAM,UAAU,eAAe,CAAC,MAAyB,OAAO,CAAC,GAAG;IAClE,MAAM,QAAQ,GAAG,GAAG,CAAC,qBAAqB,EAAE,IAAI,EAAE,CAAC;IACnD,OAAO,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;AAC3D,CAAC;AAED,+FAA+F;AAC/F,MAAM,UAAU,oBAAoB;IAClC,OAAO,yBAAyB,CAAC;AACnC,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,sBAAsB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACzE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,YAAY,CAAC,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;QACjD,OAAO,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,cAAc,EAAE,mBAAmB,EAAE,cAAc,CAAC,CAAC,CAAC;IACrF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,MAAyB,OAAO,CAAC,GAAG;IACrE,IAAI,CAAC;QACH,OAAO,QAAQ,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED,oGAAoG;AACpG,MAAM,UAAU,eAAe,CAAC,MAAyB,OAAO,CAAC,GAAG;IAClE,OAAO,sBAAsB,CAAC,GAAG,CAAC,IAAI,kBAAkB,CAAC,GAAG,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Byte-level BPE tokenizer for ModernBERT (GPT-2 style): NFC, split on added tokens, GPT-2 pre-tokenizer
|
|
3
|
+
* regex, byte-to-unicode, BPE merges by rank, then [CLS] ... [SEP]. The vocabulary and merges ship in the
|
|
4
|
+
* model file, so no npm package is needed. Parity with the Hugging Face
|
|
5
|
+
* tokenizer is pinned by test/fixtures/alerts/triage-model-golden.json (token ids of fixed cases).
|
|
6
|
+
*/
|
|
7
|
+
export interface TokenizerMeta {
|
|
8
|
+
readonly vocab: Readonly<Record<string, number>>;
|
|
9
|
+
readonly merges: readonly string[];
|
|
10
|
+
/** [content, id] of every added token (special tokens and runs of spaces). */
|
|
11
|
+
readonly added: ReadonlyArray<readonly [string, number]>;
|
|
12
|
+
readonly cls: number;
|
|
13
|
+
readonly sep: number;
|
|
14
|
+
}
|
|
15
|
+
/** Byte value to its printable character (the GPT-2 map). Exported for tests. */
|
|
16
|
+
export declare const BYTE_TO_UNICODE: string[];
|
|
17
|
+
export declare class BpeTokenizer {
|
|
18
|
+
private readonly meta;
|
|
19
|
+
private readonly ranks;
|
|
20
|
+
private readonly cache;
|
|
21
|
+
private readonly addedRe;
|
|
22
|
+
private readonly addedIds;
|
|
23
|
+
constructor(meta: TokenizerMeta);
|
|
24
|
+
private bpe;
|
|
25
|
+
private plain;
|
|
26
|
+
/** Token ids with [CLS] and [SEP], cut so that the whole sequence has at most `maxLen` ids. */
|
|
27
|
+
encode(text: string, maxLen: number): number[];
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=triage-tokenizer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triage-tokenizer.d.ts","sourceRoot":"","sources":["../../src/alerts/triage-tokenizer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjD,QAAQ,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,8EAA8E;IAC9E,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACzD,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAeD,iFAAiF;AACjF,eAAO,MAAM,eAAe,UAAY,CAAC;AAIzC,qBAAa,YAAY;IAMX,OAAO,CAAC,QAAQ,CAAC,IAAI;IALjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA6B;IACnD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAA+B;IACrD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqB;IAC7C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAA6B;gBAEzB,IAAI,EAAE,aAAa;IAOhD,OAAO,CAAC,GAAG;IAsBX,OAAO,CAAC,KAAK;IASb,+FAA+F;IAC/F,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;CAc/C"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
const PRETOKEN = /'(?:s|t|re|ve|m|ll|d)| ?\p{L}+| ?\p{N}+| ?[^\s\p{L}\p{N}]+|\s+(?!\S)|\s+/gu;
|
|
2
|
+
/** GPT-2 byte to printable unicode map. */
|
|
3
|
+
function byteMap() {
|
|
4
|
+
const keep = [];
|
|
5
|
+
for (let b = 33; b <= 126; b++)
|
|
6
|
+
keep.push(b);
|
|
7
|
+
for (let b = 161; b <= 172; b++)
|
|
8
|
+
keep.push(b);
|
|
9
|
+
for (let b = 174; b <= 255; b++)
|
|
10
|
+
keep.push(b);
|
|
11
|
+
const map = new Array(256);
|
|
12
|
+
let extra = 0;
|
|
13
|
+
for (let b = 0; b < 256; b++)
|
|
14
|
+
map[b] = String.fromCodePoint(keep.includes(b) ? b : 256 + extra++);
|
|
15
|
+
return map;
|
|
16
|
+
}
|
|
17
|
+
/** Byte value to its printable character (the GPT-2 map). Exported for tests. */
|
|
18
|
+
export const BYTE_TO_UNICODE = byteMap();
|
|
19
|
+
const BYTES = BYTE_TO_UNICODE;
|
|
20
|
+
const escapeRe = (s) => s.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
21
|
+
export class BpeTokenizer {
|
|
22
|
+
meta;
|
|
23
|
+
ranks = new Map();
|
|
24
|
+
cache = new Map();
|
|
25
|
+
addedRe;
|
|
26
|
+
addedIds = new Map();
|
|
27
|
+
constructor(meta) {
|
|
28
|
+
this.meta = meta;
|
|
29
|
+
meta.merges.forEach((m, i) => this.ranks.set(m, i));
|
|
30
|
+
for (const [content, id] of meta.added)
|
|
31
|
+
this.addedIds.set(content, id);
|
|
32
|
+
const parts = [...this.addedIds.keys()].sort((a, b) => b.length - a.length).map(escapeRe);
|
|
33
|
+
this.addedRe = parts.length > 0 ? new RegExp(parts.join("|"), "g") : undefined;
|
|
34
|
+
}
|
|
35
|
+
bpe(word) {
|
|
36
|
+
const hit = this.cache.get(word);
|
|
37
|
+
if (hit)
|
|
38
|
+
return hit;
|
|
39
|
+
let parts = Array.from(word);
|
|
40
|
+
while (parts.length > 1) {
|
|
41
|
+
let best = -1;
|
|
42
|
+
let bestRank = Infinity;
|
|
43
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
44
|
+
const r = this.ranks.get(`${parts[i]} ${parts[i + 1]}`);
|
|
45
|
+
if (r !== undefined && r < bestRank) {
|
|
46
|
+
bestRank = r;
|
|
47
|
+
best = i;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (best < 0)
|
|
51
|
+
break;
|
|
52
|
+
parts = [...parts.slice(0, best), parts[best] + parts[best + 1], ...parts.slice(best + 2)];
|
|
53
|
+
}
|
|
54
|
+
const ids = parts.map((p) => this.meta.vocab[p]).filter((v) => v !== undefined);
|
|
55
|
+
this.cache.set(word, ids);
|
|
56
|
+
return ids;
|
|
57
|
+
}
|
|
58
|
+
plain(chunk) {
|
|
59
|
+
const ids = [];
|
|
60
|
+
for (const m of chunk.matchAll(PRETOKEN)) {
|
|
61
|
+
const mapped = Array.from(Buffer.from(m[0], "utf8"), (b) => BYTES[b]).join("");
|
|
62
|
+
ids.push(...this.bpe(mapped));
|
|
63
|
+
}
|
|
64
|
+
return ids;
|
|
65
|
+
}
|
|
66
|
+
/** Token ids with [CLS] and [SEP], cut so that the whole sequence has at most `maxLen` ids. */
|
|
67
|
+
encode(text, maxLen) {
|
|
68
|
+
const norm = text.normalize("NFC");
|
|
69
|
+
const ids = [];
|
|
70
|
+
let last = 0;
|
|
71
|
+
if (this.addedRe) {
|
|
72
|
+
for (const m of norm.matchAll(this.addedRe)) {
|
|
73
|
+
ids.push(...this.plain(norm.slice(last, m.index)));
|
|
74
|
+
ids.push(this.addedIds.get(m[0]));
|
|
75
|
+
last = m.index + m[0].length;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
ids.push(...this.plain(norm.slice(last)));
|
|
79
|
+
return [this.meta.cls, ...ids.slice(0, Math.max(0, maxLen - 2)), this.meta.sep];
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=triage-tokenizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"triage-tokenizer.js","sourceRoot":"","sources":["../../src/alerts/triage-tokenizer.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;;;GAOG;AAoLH,MAAM,WAAW,KAAK;IACpB,QAAQ,CAAC,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,QAAQ,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,QAAQ,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,4EAA4E;IAC5E,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IACzB,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;IAC1D,qGAAqG;IACrG,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;CACtD;AAcD,sFAAsF;AACtF,wBAAgB,iBAAiB,IAAI,OAAO,CAE3C;AAED,+FAA+F;AAC/F,wBAAsB,MAAM,CAC1B,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,EAAE,GAAE,KAAiB,EACrB,GAAG,GAAE,MAAM,CAAC,UAAwB,EACpC,GAAG,GAAE,MAAsB,GAC1B,OAAO,CAAC,MAAM,CAAC,CAm8BjB"}
|
package/dist/cli.js
CHANGED
|
@@ -113,6 +113,8 @@ Commands:
|
|
|
113
113
|
<file>, or --from agt [--file <path>] for the AGT audit log)
|
|
114
114
|
investigate Deterministic trail analysis: detectors, grouped incidents,
|
|
115
115
|
markdown fix briefs for coding agents (--json)
|
|
116
|
+
alerts Security alerts for detected incidents, optional local triage model, off by default, advisory
|
|
117
|
+
(status [--json] | test | on | off) - see docs/alerts.md
|
|
116
118
|
discover Scan this endpoint for AI agents, IDEs, runtimes, and MCP servers
|
|
117
119
|
(--json, --diff <snapshot>, --push)
|
|
118
120
|
|
|
@@ -239,6 +241,9 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
239
241
|
if (!config.json) {
|
|
240
242
|
const { maybeOfferSemanticSearch } = await import("./receipt/semantic-setup.js");
|
|
241
243
|
await maybeOfferSemanticSearch(io, env).catch(() => undefined);
|
|
244
|
+
// Security alerts with optional local triage: asked once, after the search offer, same rules. Never fails start.
|
|
245
|
+
const { maybeOfferTriageAlerts } = await import("./alerts/triage-setup.js");
|
|
246
|
+
await maybeOfferTriageAlerts(io, env).catch(() => undefined);
|
|
242
247
|
}
|
|
243
248
|
const result = await runStart(config, { force, open: !noOpen, gate: !noGate });
|
|
244
249
|
if (config.json) {
|
|
@@ -1077,6 +1082,15 @@ export async function runCli(argv, io = defaultIo, env = process.env, cwd = proc
|
|
|
1077
1082
|
const { discoverOptionsFromArgs, runDiscover } = await import("./commands/discover.js");
|
|
1078
1083
|
return await runDiscover(discoverOptionsFromArgs(parsed), io, cwd, env);
|
|
1079
1084
|
}
|
|
1085
|
+
case "alerts": {
|
|
1086
|
+
const { runAlerts } = await import("./commands/alerts.js");
|
|
1087
|
+
return await runAlerts({
|
|
1088
|
+
io: { log: (line) => io.log(line), error: (line) => io.error(line) },
|
|
1089
|
+
env,
|
|
1090
|
+
sub: parsed.positionals[0],
|
|
1091
|
+
flags: parsed.flags,
|
|
1092
|
+
});
|
|
1093
|
+
}
|
|
1080
1094
|
case "notify-flush": {
|
|
1081
1095
|
const { runNotifyFlush } = await import("./commands/notify-flush.js");
|
|
1082
1096
|
// Internal: spawned detached by hook/wrap (src/notify/dispatch.ts).
|