@shield-agent/kya 0.19.0 → 0.21.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/.mcp.json +1 -1
- package/README.md +21 -5
- package/amp/settings.example.json +1 -1
- 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/cli.d.ts.map +1 -1
- package/dist/cli.js +23 -1
- package/dist/cli.js.map +1 -1
- package/dist/commands/receipt.d.ts +13 -0
- package/dist/commands/receipt.d.ts.map +1 -1
- package/dist/commands/receipt.js +20 -0
- package/dist/commands/receipt.js.map +1 -1
- package/dist/receipt/embeddings.d.ts +34 -0
- package/dist/receipt/embeddings.d.ts.map +1 -0
- package/dist/receipt/embeddings.js +140 -0
- package/dist/receipt/embeddings.js.map +1 -0
- package/dist/receipt/live-server.d.ts +3 -0
- package/dist/receipt/live-server.d.ts.map +1 -1
- package/dist/receipt/live-server.js +24 -3
- package/dist/receipt/live-server.js.map +1 -1
- package/dist/receipt/receipt-css.d.ts.map +1 -1
- package/dist/receipt/receipt-css.js +29 -0
- package/dist/receipt/receipt-css.js.map +1 -1
- package/dist/receipt/render-receipt.d.ts +4 -1
- package/dist/receipt/render-receipt.d.ts.map +1 -1
- package/dist/receipt/render-receipt.js +199 -67
- package/dist/receipt/render-receipt.js.map +1 -1
- package/dist/receipt/search.d.ts +79 -0
- package/dist/receipt/search.d.ts.map +1 -0
- package/dist/receipt/search.js +475 -0
- package/dist/receipt/search.js.map +1 -0
- package/dist/receipt/share.d.ts +65 -0
- package/dist/receipt/share.d.ts.map +1 -0
- package/dist/receipt/share.js +109 -0
- package/dist/receipt/share.js.map +1 -0
- package/dist/star-cta.d.ts +14 -0
- package/dist/star-cta.d.ts.map +1 -0
- package/dist/star-cta.js +51 -0
- package/dist/star-cta.js.map +1 -0
- package/droid/README.md +1 -1
- package/droid/mcp.example.json +1 -1
- package/gemini/settings.example.json +1 -1
- package/grok/README.md +1 -1
- 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 +14 -3
- package/qwen/settings.example.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Natural-language search over the activity feed.
|
|
3
|
+
*
|
|
4
|
+
* Pure-lexical BM25 with optional MiniLM semantic hybrid. The search module
|
|
5
|
+
* has no runtime dependency on native ML libraries: fastembed is imported
|
|
6
|
+
* lazily and only in the live server path.
|
|
7
|
+
*/
|
|
8
|
+
import { createHash } from "node:crypto";
|
|
9
|
+
import { clip } from "../dash/render.js";
|
|
10
|
+
import { mcpServerLabel, parseMcpToolId } from "../mcp-servers.js";
|
|
11
|
+
import { productLabel } from "../trail.js";
|
|
12
|
+
const STOPWORDS = new Set([
|
|
13
|
+
"a",
|
|
14
|
+
"an",
|
|
15
|
+
"the",
|
|
16
|
+
"and",
|
|
17
|
+
"or",
|
|
18
|
+
"but",
|
|
19
|
+
"is",
|
|
20
|
+
"are",
|
|
21
|
+
"was",
|
|
22
|
+
"were",
|
|
23
|
+
"be",
|
|
24
|
+
"been",
|
|
25
|
+
"being",
|
|
26
|
+
"to",
|
|
27
|
+
"of",
|
|
28
|
+
"in",
|
|
29
|
+
"on",
|
|
30
|
+
"at",
|
|
31
|
+
"by",
|
|
32
|
+
"for",
|
|
33
|
+
"with",
|
|
34
|
+
"as",
|
|
35
|
+
"this",
|
|
36
|
+
"that",
|
|
37
|
+
"these",
|
|
38
|
+
"those",
|
|
39
|
+
"it",
|
|
40
|
+
"its",
|
|
41
|
+
"from",
|
|
42
|
+
"up",
|
|
43
|
+
"about",
|
|
44
|
+
"into",
|
|
45
|
+
"through",
|
|
46
|
+
"during",
|
|
47
|
+
"before",
|
|
48
|
+
"after",
|
|
49
|
+
"above",
|
|
50
|
+
"below",
|
|
51
|
+
"between",
|
|
52
|
+
"among",
|
|
53
|
+
"within",
|
|
54
|
+
"without",
|
|
55
|
+
"against",
|
|
56
|
+
"over",
|
|
57
|
+
"under",
|
|
58
|
+
"again",
|
|
59
|
+
"further",
|
|
60
|
+
"then",
|
|
61
|
+
"once",
|
|
62
|
+
"here",
|
|
63
|
+
"there",
|
|
64
|
+
"when",
|
|
65
|
+
"where",
|
|
66
|
+
"why",
|
|
67
|
+
"how",
|
|
68
|
+
"all",
|
|
69
|
+
"any",
|
|
70
|
+
"both",
|
|
71
|
+
"each",
|
|
72
|
+
"few",
|
|
73
|
+
"more",
|
|
74
|
+
"most",
|
|
75
|
+
"other",
|
|
76
|
+
"some",
|
|
77
|
+
"such",
|
|
78
|
+
"only",
|
|
79
|
+
"own",
|
|
80
|
+
"same",
|
|
81
|
+
"so",
|
|
82
|
+
"than",
|
|
83
|
+
"too",
|
|
84
|
+
"very",
|
|
85
|
+
"can",
|
|
86
|
+
"will",
|
|
87
|
+
"just",
|
|
88
|
+
"should",
|
|
89
|
+
"now",
|
|
90
|
+
"did",
|
|
91
|
+
"does",
|
|
92
|
+
"do",
|
|
93
|
+
"has",
|
|
94
|
+
"have",
|
|
95
|
+
"had",
|
|
96
|
+
"having",
|
|
97
|
+
"get",
|
|
98
|
+
"got",
|
|
99
|
+
"gets",
|
|
100
|
+
"make",
|
|
101
|
+
"made",
|
|
102
|
+
"makes",
|
|
103
|
+
"use",
|
|
104
|
+
"used",
|
|
105
|
+
"uses",
|
|
106
|
+
"using",
|
|
107
|
+
]);
|
|
108
|
+
/** Light stemmer: trailing "ing", "ed", and simple plural "s". */
|
|
109
|
+
function stem(token) {
|
|
110
|
+
if (token.length <= 3)
|
|
111
|
+
return token;
|
|
112
|
+
let s = token;
|
|
113
|
+
if (s.endsWith("ing")) {
|
|
114
|
+
const stem = s.slice(0, -3);
|
|
115
|
+
if (/[aeiou]/.test(stem))
|
|
116
|
+
s = stem;
|
|
117
|
+
}
|
|
118
|
+
else if (s.endsWith("ed")) {
|
|
119
|
+
const stem = s.slice(0, -2);
|
|
120
|
+
if (/[aeiou]/.test(stem))
|
|
121
|
+
s = stem;
|
|
122
|
+
}
|
|
123
|
+
else if (s.endsWith("s") && !s.endsWith("ss")) {
|
|
124
|
+
s = s.slice(0, -1);
|
|
125
|
+
}
|
|
126
|
+
if (s.length > 3 && /([bcdfghjklmnpqrstvwxz])\1$/.test(s)) {
|
|
127
|
+
s = s.slice(0, -1);
|
|
128
|
+
}
|
|
129
|
+
return s.length >= 2 ? s : token;
|
|
130
|
+
}
|
|
131
|
+
/** Split camelCase, PascalCase, snake_case, kebab-case, and dot.case. */
|
|
132
|
+
function splitIdentifiers(token) {
|
|
133
|
+
const parts = [];
|
|
134
|
+
let current = "";
|
|
135
|
+
for (const char of token) {
|
|
136
|
+
if (char === "_" || char === "-" || char === ".") {
|
|
137
|
+
if (current)
|
|
138
|
+
parts.push(current);
|
|
139
|
+
current = "";
|
|
140
|
+
}
|
|
141
|
+
else if (/[A-Z]/.test(char)) {
|
|
142
|
+
if (current && /[a-z]/.test(current[current.length - 1])) {
|
|
143
|
+
parts.push(current);
|
|
144
|
+
current = char.toLowerCase();
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
current += char.toLowerCase();
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
current += char;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
if (current)
|
|
155
|
+
parts.push(current);
|
|
156
|
+
return parts;
|
|
157
|
+
}
|
|
158
|
+
/** Tokenize a query or document for BM25 matching. */
|
|
159
|
+
export function tokenize(text) {
|
|
160
|
+
const out = [];
|
|
161
|
+
for (const raw of text.split(/[^a-zA-Z0-9]+/)) {
|
|
162
|
+
if (!raw)
|
|
163
|
+
continue;
|
|
164
|
+
for (const part of splitIdentifiers(raw)) {
|
|
165
|
+
if (!part)
|
|
166
|
+
continue;
|
|
167
|
+
const s = stem(part.toLowerCase());
|
|
168
|
+
if (STOPWORDS.has(s))
|
|
169
|
+
continue;
|
|
170
|
+
out.push(s);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return out;
|
|
174
|
+
}
|
|
175
|
+
/** Concatenate the searchable fields of a trail event. */
|
|
176
|
+
export function eventDocumentText(e) {
|
|
177
|
+
const parsed = parseMcpToolId(e.toolId);
|
|
178
|
+
const serverLabel = parsed ? mcpServerLabel(parsed.server) : "";
|
|
179
|
+
const parts = [
|
|
180
|
+
e.toolId,
|
|
181
|
+
e.reasonCode,
|
|
182
|
+
e.summary ?? "",
|
|
183
|
+
e.project ?? "",
|
|
184
|
+
productLabel(e.product),
|
|
185
|
+
e.mode,
|
|
186
|
+
serverLabel,
|
|
187
|
+
e.targetPath ?? "",
|
|
188
|
+
];
|
|
189
|
+
return parts.filter((p) => p).join(" ");
|
|
190
|
+
}
|
|
191
|
+
/** Stable SHA1 of the searchable document text; used to version embeddings. */
|
|
192
|
+
export function eventTextSha1(e) {
|
|
193
|
+
return createHash("sha1").update(eventDocumentText(e)).digest("hex");
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Standard BM25 over field-weighted documents.
|
|
197
|
+
*
|
|
198
|
+
* k1 controls term saturation; b controls document-length normalization.
|
|
199
|
+
*/
|
|
200
|
+
export class Bm25Index {
|
|
201
|
+
k1;
|
|
202
|
+
b;
|
|
203
|
+
docs = new Map();
|
|
204
|
+
df = new Map();
|
|
205
|
+
totalDocLength = 0;
|
|
206
|
+
constructor(k1 = 1.5, b = 0.75) {
|
|
207
|
+
this.k1 = k1;
|
|
208
|
+
this.b = b;
|
|
209
|
+
}
|
|
210
|
+
add(id, doc) {
|
|
211
|
+
this.docs.set(id, doc);
|
|
212
|
+
this.totalDocLength += doc.tokens.length;
|
|
213
|
+
const seen = new Set();
|
|
214
|
+
for (const t of doc.tokens) {
|
|
215
|
+
if (seen.has(t))
|
|
216
|
+
continue;
|
|
217
|
+
seen.add(t);
|
|
218
|
+
this.df.set(t, (this.df.get(t) ?? 0) + 1);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
avgDocLength() {
|
|
222
|
+
return this.docs.size ? this.totalDocLength / this.docs.size : 0;
|
|
223
|
+
}
|
|
224
|
+
search(query) {
|
|
225
|
+
const qTokens = [...new Set(tokenize(query))];
|
|
226
|
+
if (qTokens.length === 0 || this.docs.size === 0)
|
|
227
|
+
return [];
|
|
228
|
+
const avg = this.avgDocLength();
|
|
229
|
+
const results = [];
|
|
230
|
+
for (const doc of this.docs.values()) {
|
|
231
|
+
// Field-weighted length normalization: sum(field tokens * weight).
|
|
232
|
+
let weightedLength = 0;
|
|
233
|
+
for (const f of doc.fields) {
|
|
234
|
+
weightedLength += tokenize(f.text).length * f.weight;
|
|
235
|
+
}
|
|
236
|
+
let score = 0;
|
|
237
|
+
for (const t of qTokens) {
|
|
238
|
+
const df = this.df.get(t) ?? 0;
|
|
239
|
+
if (df === 0)
|
|
240
|
+
continue;
|
|
241
|
+
// IDF with a floor so common terms still contribute a little.
|
|
242
|
+
const idf = Math.log(1 + (this.docs.size - df + 0.5) / (df + 0.5));
|
|
243
|
+
const tf = doc.tokens.filter((x) => x === t).length;
|
|
244
|
+
if (tf === 0)
|
|
245
|
+
continue;
|
|
246
|
+
const denom = tf + this.k1 * (1 - this.b + (this.b * weightedLength) / Math.max(avg, 1));
|
|
247
|
+
score += idf * ((tf * (this.k1 + 1)) / denom);
|
|
248
|
+
}
|
|
249
|
+
if (score > 0)
|
|
250
|
+
results.push({ id: doc.id, score });
|
|
251
|
+
}
|
|
252
|
+
return results.sort((a, b) => b.score - a.score);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
const SERVER_ALIASES = {
|
|
256
|
+
github: ["GitHub"],
|
|
257
|
+
gitlab: ["GitLab"],
|
|
258
|
+
postgres: ["PostgreSQL"],
|
|
259
|
+
postgresql: ["PostgreSQL"],
|
|
260
|
+
slack: ["Slack"],
|
|
261
|
+
notion: ["Notion"],
|
|
262
|
+
jira: ["Jira"],
|
|
263
|
+
confluence: ["Confluence"],
|
|
264
|
+
linear: ["Linear"],
|
|
265
|
+
playwright: ["Playwright"],
|
|
266
|
+
browser: ["Playwright"],
|
|
267
|
+
puppeteer: ["Puppeteer"],
|
|
268
|
+
stripe: ["Stripe"],
|
|
269
|
+
vercel: ["Vercel"],
|
|
270
|
+
aws: ["AWS"],
|
|
271
|
+
gcp: ["GCP"],
|
|
272
|
+
google: ["GCP"],
|
|
273
|
+
azure: ["Azure"],
|
|
274
|
+
};
|
|
275
|
+
const PRODUCT_ALIASES = {
|
|
276
|
+
cursor: ["cursor"],
|
|
277
|
+
claude: ["claude"],
|
|
278
|
+
codex: ["codex"],
|
|
279
|
+
grok: ["grok"],
|
|
280
|
+
kimi: ["kimi"],
|
|
281
|
+
};
|
|
282
|
+
/** Map natural-language terms to known facet values for soft boosting. */
|
|
283
|
+
export function extractFacetHints(query) {
|
|
284
|
+
const q = ` ${query.toLowerCase()} `;
|
|
285
|
+
const hints = {
|
|
286
|
+
verdict: [],
|
|
287
|
+
server: [],
|
|
288
|
+
product: [],
|
|
289
|
+
mode: [],
|
|
290
|
+
};
|
|
291
|
+
if (/\b(deny|denied|blocked|rejected|forbidden)\b/.test(q))
|
|
292
|
+
hints.verdict.push("DENY");
|
|
293
|
+
if (/\b(approve|review|hold)\b/.test(q))
|
|
294
|
+
hints.verdict.push("REQUIRE_APPROVE");
|
|
295
|
+
if (/\ballow(ed)?\b/.test(q))
|
|
296
|
+
hints.verdict.push("ALLOW");
|
|
297
|
+
if (/\bnever\b/.test(q))
|
|
298
|
+
hints.verdict.push("NEVER_EVENT");
|
|
299
|
+
for (const [alias, labels] of Object.entries(SERVER_ALIASES)) {
|
|
300
|
+
if (q.includes(` ${alias} `))
|
|
301
|
+
hints.server.push(...labels);
|
|
302
|
+
}
|
|
303
|
+
for (const [alias, ids] of Object.entries(PRODUCT_ALIASES)) {
|
|
304
|
+
if (q.includes(` ${alias} `))
|
|
305
|
+
hints.product.push(...ids);
|
|
306
|
+
}
|
|
307
|
+
if (/\b(observe|observed)\b/.test(q))
|
|
308
|
+
hints.mode.push("observe");
|
|
309
|
+
if (/\bhold\b/.test(q))
|
|
310
|
+
hints.mode.push("hold");
|
|
311
|
+
if (/\boffline\b/.test(q))
|
|
312
|
+
hints.mode.push("offline");
|
|
313
|
+
const out = {};
|
|
314
|
+
if (hints.verdict.length)
|
|
315
|
+
out.verdict = hints.verdict;
|
|
316
|
+
if (hints.server.length)
|
|
317
|
+
out.server = hints.server;
|
|
318
|
+
if (hints.product.length)
|
|
319
|
+
out.product = hints.product;
|
|
320
|
+
if (hints.mode.length)
|
|
321
|
+
out.mode = hints.mode;
|
|
322
|
+
return out;
|
|
323
|
+
}
|
|
324
|
+
/** Cosine similarity of two equal-length vectors. */
|
|
325
|
+
export function cosine(a, b) {
|
|
326
|
+
if (a.length !== b.length || a.length === 0)
|
|
327
|
+
return 0;
|
|
328
|
+
let dot = 0;
|
|
329
|
+
let na = 0;
|
|
330
|
+
let nb = 0;
|
|
331
|
+
for (let i = 0; i < a.length; i++) {
|
|
332
|
+
dot += a[i] * b[i];
|
|
333
|
+
na += a[i] * a[i];
|
|
334
|
+
nb += b[i] * b[i];
|
|
335
|
+
}
|
|
336
|
+
const denom = Math.sqrt(na) * Math.sqrt(nb);
|
|
337
|
+
return denom === 0 ? 0 : dot / denom;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Reciprocal Rank Fusion of two ranked lists. Each list is expected in
|
|
341
|
+
* descending order by score; ranks are 1-based.
|
|
342
|
+
*/
|
|
343
|
+
export function rrfMerge(bm25Ranks, semanticRanks, k = 60) {
|
|
344
|
+
const map = new Map();
|
|
345
|
+
for (let i = 0; i < bm25Ranks.length; i++) {
|
|
346
|
+
const r = bm25Ranks[i];
|
|
347
|
+
map.set(r.id, (map.get(r.id) ?? 0) + 1 / (k + i + 1));
|
|
348
|
+
}
|
|
349
|
+
for (let i = 0; i < semanticRanks.length; i++) {
|
|
350
|
+
const r = semanticRanks[i];
|
|
351
|
+
map.set(r.id, (map.get(r.id) ?? 0) + 1 / (k + i + 1));
|
|
352
|
+
}
|
|
353
|
+
return [...map.entries()]
|
|
354
|
+
.map(([id, score]) => ({ id, score }))
|
|
355
|
+
.sort((a, b) => b.score - a.score);
|
|
356
|
+
}
|
|
357
|
+
/** Build a BM25 index from trail events with weighted fields. */
|
|
358
|
+
export function buildEventIndex(events) {
|
|
359
|
+
const index = new Bm25Index();
|
|
360
|
+
for (const e of events) {
|
|
361
|
+
const parsed = parseMcpToolId(e.toolId);
|
|
362
|
+
const serverLabel = parsed ? mcpServerLabel(parsed.server) : "";
|
|
363
|
+
const fields = [
|
|
364
|
+
{ text: e.toolId, weight: 2 },
|
|
365
|
+
{ text: e.reasonCode, weight: 1 },
|
|
366
|
+
{ text: e.summary ?? "", weight: 2 },
|
|
367
|
+
{ text: e.project ?? "", weight: 1 },
|
|
368
|
+
{ text: productLabel(e.product), weight: 1 },
|
|
369
|
+
{ text: e.mode, weight: 1 },
|
|
370
|
+
{ text: serverLabel, weight: 1 },
|
|
371
|
+
{ text: e.targetPath ?? "", weight: 1 },
|
|
372
|
+
].filter((f) => f.text);
|
|
373
|
+
const tokens = [];
|
|
374
|
+
for (const f of fields) {
|
|
375
|
+
for (let i = 0; i < f.weight; i++) {
|
|
376
|
+
tokens.push(...tokenize(f.text));
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
index.add(eventKey(e), { id: eventKey(e), tokens, fields });
|
|
380
|
+
}
|
|
381
|
+
return index;
|
|
382
|
+
}
|
|
383
|
+
export function eventKey(e) {
|
|
384
|
+
return `${e.ts}::${e.sessionId}::${e.toolId}`;
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Rank events by query relevance. Chip filters are applied first; BM25 ranks
|
|
388
|
+
* the survivors; optional semantic embeddings are merged with RRF.
|
|
389
|
+
*/
|
|
390
|
+
export function rankEvents(events, options) {
|
|
391
|
+
const { query, filters, embeddings, queryEmbedding, facetBoost = 0.05 } = options;
|
|
392
|
+
const q = query.trim();
|
|
393
|
+
const hints = extractFacetHints(q);
|
|
394
|
+
const filtered = applyChipFilters(events, filters ?? {});
|
|
395
|
+
const index = buildEventIndex(filtered);
|
|
396
|
+
const bm25 = index.search(q);
|
|
397
|
+
const byId = new Map(filtered.map((e) => [eventKey(e), e]));
|
|
398
|
+
let merged = bm25;
|
|
399
|
+
if (embeddings && embeddings.size > 0 && q.length > 0 && queryEmbedding) {
|
|
400
|
+
const semantic = [];
|
|
401
|
+
for (const e of filtered) {
|
|
402
|
+
const vec = embeddings.get(eventKey(e));
|
|
403
|
+
if (!vec)
|
|
404
|
+
continue;
|
|
405
|
+
const sim = cosine(queryEmbedding, vec);
|
|
406
|
+
if (sim > 0)
|
|
407
|
+
semantic.push({ id: eventKey(e), score: sim });
|
|
408
|
+
}
|
|
409
|
+
merged = rrfMerge(bm25, semantic.sort((a, b) => b.score - a.score));
|
|
410
|
+
}
|
|
411
|
+
const ranked = [];
|
|
412
|
+
for (const s of merged) {
|
|
413
|
+
const event = byId.get(s.id);
|
|
414
|
+
if (event)
|
|
415
|
+
ranked.push({ event, score: s.score });
|
|
416
|
+
}
|
|
417
|
+
return applyFacetBoost(ranked, byId, hints, facetBoost);
|
|
418
|
+
}
|
|
419
|
+
function applyFacetBoost(ranked, byId, hints, boost) {
|
|
420
|
+
if (!hints.verdict && !hints.server && !hints.product && !hints.mode)
|
|
421
|
+
return ranked;
|
|
422
|
+
return ranked.map((r) => {
|
|
423
|
+
const e = byId.get(eventKey(r.event));
|
|
424
|
+
if (!e)
|
|
425
|
+
return r;
|
|
426
|
+
let b = 0;
|
|
427
|
+
if (hints.verdict?.includes(e.verdict.toUpperCase()))
|
|
428
|
+
b += boost;
|
|
429
|
+
const parsed = parseMcpToolId(e.toolId);
|
|
430
|
+
if (parsed && hints.server?.includes(mcpServerLabel(parsed.server)))
|
|
431
|
+
b += boost;
|
|
432
|
+
if (hints.product?.includes(e.product ?? "other"))
|
|
433
|
+
b += boost;
|
|
434
|
+
if (hints.mode?.includes(e.mode))
|
|
435
|
+
b += boost;
|
|
436
|
+
return b > 0 ? { event: r.event, score: r.score + b } : r;
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
export function applyChipFilters(events, filters) {
|
|
440
|
+
const groups = Object.entries(filters)
|
|
441
|
+
.map(([group, vals]) => [group, vals.filter((v) => v !== "")])
|
|
442
|
+
.filter(([, vals]) => vals.length > 0);
|
|
443
|
+
if (groups.length === 0)
|
|
444
|
+
return [...events];
|
|
445
|
+
return events.filter((e) => groups.every(([group, vals]) => vals.some((v) => eventMatchesFilter(e, group, v))));
|
|
446
|
+
}
|
|
447
|
+
export function eventMatchesFilter(e, group, value) {
|
|
448
|
+
switch (group) {
|
|
449
|
+
case "verdict":
|
|
450
|
+
return e.verdict.toUpperCase() === value;
|
|
451
|
+
case "never":
|
|
452
|
+
return (e.neverEvent || e.reasonCode === "NEVER_EVENT") && value === "1";
|
|
453
|
+
case "mode":
|
|
454
|
+
return e.mode === value;
|
|
455
|
+
case "plane":
|
|
456
|
+
return (e.host?.trim() || "unknown") === value;
|
|
457
|
+
case "product":
|
|
458
|
+
return (e.product ?? "other") === value;
|
|
459
|
+
case "project":
|
|
460
|
+
if (value === "")
|
|
461
|
+
return false;
|
|
462
|
+
return (e.project?.trim() ?? "") === value;
|
|
463
|
+
case "tool":
|
|
464
|
+
return clip(e.toolId, 60) === value;
|
|
465
|
+
case "session":
|
|
466
|
+
return (e.sessionId || "unknown") === value;
|
|
467
|
+
case "server": {
|
|
468
|
+
const parsed = parseMcpToolId(e.toolId);
|
|
469
|
+
return parsed != null && mcpServerLabel(parsed.server) === value;
|
|
470
|
+
}
|
|
471
|
+
default:
|
|
472
|
+
return false;
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/receipt/search.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { type ReceiptModel } from "./render-receipt.js";
|
|
2
|
+
export declare const SHARE_DEFAULT_BASE_URL = "https://shield-agent.com";
|
|
3
|
+
export declare const SHARE_PATH = "/api/v1/share/reports";
|
|
4
|
+
export declare const SHARE_TIMEOUT_MS = 15000;
|
|
5
|
+
export interface ShareStats {
|
|
6
|
+
readonly total: number;
|
|
7
|
+
readonly allow: number;
|
|
8
|
+
readonly review: number;
|
|
9
|
+
readonly deny: number;
|
|
10
|
+
readonly never: number;
|
|
11
|
+
/** Distinct sessions in the window — a count, never ids. */
|
|
12
|
+
readonly sessions: number;
|
|
13
|
+
}
|
|
14
|
+
export interface ShareCertify {
|
|
15
|
+
readonly status: "pass" | "gap";
|
|
16
|
+
readonly pass: number;
|
|
17
|
+
readonly gap: number;
|
|
18
|
+
readonly insufficient: number;
|
|
19
|
+
readonly attested: number;
|
|
20
|
+
readonly topGaps: readonly {
|
|
21
|
+
readonly id: string;
|
|
22
|
+
readonly severity: string;
|
|
23
|
+
readonly title: string;
|
|
24
|
+
}[];
|
|
25
|
+
}
|
|
26
|
+
export interface SharePayload {
|
|
27
|
+
readonly version: 1;
|
|
28
|
+
readonly title: string;
|
|
29
|
+
readonly rangeLabel: string;
|
|
30
|
+
readonly generatedAt: string;
|
|
31
|
+
readonly cliVersion: string;
|
|
32
|
+
readonly stats: ShareStats;
|
|
33
|
+
readonly products: readonly {
|
|
34
|
+
readonly label: string;
|
|
35
|
+
readonly count: number;
|
|
36
|
+
}[];
|
|
37
|
+
readonly reasonCodes: readonly {
|
|
38
|
+
readonly code: string;
|
|
39
|
+
readonly count: number;
|
|
40
|
+
}[];
|
|
41
|
+
readonly certify: ShareCertify | null;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Roll the model into the share payload. Only fields that are already public
|
|
45
|
+
* labels or aggregates leave the machine: verdict counts, product/reason
|
|
46
|
+
* labels, and certify requirement ids (catalog identifiers). Events, session
|
|
47
|
+
* ids, tool args, paths, and identity never enter the payload.
|
|
48
|
+
*/
|
|
49
|
+
export declare function buildSharePayload(model: ReceiptModel): SharePayload;
|
|
50
|
+
/** Resolve the endpoint base: --share-url flag > KYA_SHARE_URL > default. */
|
|
51
|
+
export declare function shareBaseUrl(override: string | undefined, env: NodeJS.ProcessEnv): string;
|
|
52
|
+
export type ShareResult = {
|
|
53
|
+
readonly ok: true;
|
|
54
|
+
readonly url: string;
|
|
55
|
+
} | {
|
|
56
|
+
readonly ok: false;
|
|
57
|
+
readonly error: string;
|
|
58
|
+
};
|
|
59
|
+
/** POST the payload; 15s timeout. Never throws — failures come back as {ok:false}. */
|
|
60
|
+
export declare function shareReceiptPayload(payload: SharePayload, opts: {
|
|
61
|
+
readonly baseUrl: string;
|
|
62
|
+
readonly fetchImpl?: typeof fetch;
|
|
63
|
+
readonly timeoutMs?: number;
|
|
64
|
+
}): Promise<ShareResult>;
|
|
65
|
+
//# sourceMappingURL=share.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"share.d.ts","sourceRoot":"","sources":["../../src/receipt/share.ts"],"names":[],"mappings":"AAUA,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEzE,eAAO,MAAM,sBAAsB,6BAA6B,CAAC;AACjE,eAAO,MAAM,UAAU,0BAA0B,CAAC;AAClD,eAAO,MAAM,gBAAgB,QAAS,CAAC;AAEvC,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,OAAO,EAAE,SAAS;QAAE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACzG;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,SAAS;QAAE,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACjF,QAAQ,CAAC,WAAW,EAAE,SAAS;QAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACnF,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;CACvC;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,YAAY,CA2CnE;AAED,6EAA6E;AAC7E,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAGzF;AAED,MAAM,MAAM,WAAW,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEvH,sFAAsF;AACtF,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,YAAY,EACrB,IAAI,EAAE;IAAE,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IAAC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GACjG,OAAO,CAAC,WAAW,CAAC,CA+BtB"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `kya receipt --share` — publish a redacted summary of the current report
|
|
3
|
+
* window to the hosted platform and get back a public URL.
|
|
4
|
+
*
|
|
5
|
+
* The payload is built FROM THE RECEIPT MODEL, never from the raw trail:
|
|
6
|
+
* aggregate counts and public labels only. No absolute paths, no session ids,
|
|
7
|
+
* no tool arguments, no identity (baseUrl/IP) — anything that could identify
|
|
8
|
+
* a machine, project, or person stays local. Dependency-free: global fetch.
|
|
9
|
+
*/
|
|
10
|
+
import { CLI_VERSION } from "../version.js";
|
|
11
|
+
import { aggregateEvents } from "./render-receipt.js";
|
|
12
|
+
export const SHARE_DEFAULT_BASE_URL = "https://shield-agent.com";
|
|
13
|
+
export const SHARE_PATH = "/api/v1/share/reports";
|
|
14
|
+
export const SHARE_TIMEOUT_MS = 15_000;
|
|
15
|
+
/**
|
|
16
|
+
* Roll the model into the share payload. Only fields that are already public
|
|
17
|
+
* labels or aggregates leave the machine: verdict counts, product/reason
|
|
18
|
+
* labels, and certify requirement ids (catalog identifiers). Events, session
|
|
19
|
+
* ids, tool args, paths, and identity never enter the payload.
|
|
20
|
+
*/
|
|
21
|
+
export function buildSharePayload(model) {
|
|
22
|
+
const events = model.events;
|
|
23
|
+
let allow = 0;
|
|
24
|
+
let review = 0;
|
|
25
|
+
let deny = 0;
|
|
26
|
+
let never = 0;
|
|
27
|
+
const sessions = new Set();
|
|
28
|
+
for (const e of events) {
|
|
29
|
+
const v = e.verdict.toUpperCase();
|
|
30
|
+
if (e.neverEvent || e.reasonCode === "NEVER_EVENT")
|
|
31
|
+
never++;
|
|
32
|
+
if (v === "ALLOW")
|
|
33
|
+
allow++;
|
|
34
|
+
else if (v === "DENY")
|
|
35
|
+
deny++;
|
|
36
|
+
else if (v === "REQUIRE_APPROVE")
|
|
37
|
+
review++;
|
|
38
|
+
sessions.add(e.sessionId?.trim() || "unknown");
|
|
39
|
+
}
|
|
40
|
+
const agg = aggregateEvents(events);
|
|
41
|
+
return {
|
|
42
|
+
version: 1,
|
|
43
|
+
title: model.title,
|
|
44
|
+
rangeLabel: model.rangeLabel,
|
|
45
|
+
generatedAt: model.generatedAt,
|
|
46
|
+
cliVersion: CLI_VERSION,
|
|
47
|
+
stats: {
|
|
48
|
+
total: events.length,
|
|
49
|
+
allow,
|
|
50
|
+
review,
|
|
51
|
+
deny,
|
|
52
|
+
never,
|
|
53
|
+
sessions: sessions.size,
|
|
54
|
+
},
|
|
55
|
+
products: agg.products.slice(0, 6).map(({ label, count }) => ({ label, count })),
|
|
56
|
+
reasonCodes: agg.reasons.slice(0, 8).map(({ label, count }) => ({ code: label, count })),
|
|
57
|
+
certify: model.certify
|
|
58
|
+
? {
|
|
59
|
+
status: model.certify.result,
|
|
60
|
+
pass: model.certify.pass,
|
|
61
|
+
gap: model.certify.gap,
|
|
62
|
+
insufficient: model.certify.insufficientEvidence,
|
|
63
|
+
attested: model.certify.attested,
|
|
64
|
+
topGaps: model.certify.topGaps.slice(0, 5).map(({ id, severity, title }) => ({ id, severity, title })),
|
|
65
|
+
}
|
|
66
|
+
: null,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
/** Resolve the endpoint base: --share-url flag > KYA_SHARE_URL > default. */
|
|
70
|
+
export function shareBaseUrl(override, env) {
|
|
71
|
+
const raw = override?.trim() || env.KYA_SHARE_URL?.trim() || SHARE_DEFAULT_BASE_URL;
|
|
72
|
+
return raw.replace(/\/+$/, "");
|
|
73
|
+
}
|
|
74
|
+
/** POST the payload; 15s timeout. Never throws — failures come back as {ok:false}. */
|
|
75
|
+
export async function shareReceiptPayload(payload, opts) {
|
|
76
|
+
const fetchImpl = opts.fetchImpl ?? globalThis.fetch;
|
|
77
|
+
const controller = new AbortController();
|
|
78
|
+
const timer = setTimeout(() => controller.abort(), opts.timeoutMs ?? SHARE_TIMEOUT_MS);
|
|
79
|
+
try {
|
|
80
|
+
let res;
|
|
81
|
+
try {
|
|
82
|
+
res = await fetchImpl(`${opts.baseUrl}${SHARE_PATH}`, {
|
|
83
|
+
method: "POST",
|
|
84
|
+
headers: { "Content-Type": "application/json" },
|
|
85
|
+
body: JSON.stringify(payload),
|
|
86
|
+
signal: controller.signal,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
catch (err) {
|
|
90
|
+
const timedOut = err instanceof Error && err.name === "AbortError";
|
|
91
|
+
return {
|
|
92
|
+
ok: false,
|
|
93
|
+
error: timedOut ? "share failed: request timed out" : `share failed: ${err instanceof Error ? err.message : String(err)}`,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
if (res.status !== 200 && res.status !== 201) {
|
|
97
|
+
return { ok: false, error: `share failed: HTTP ${res.status}` };
|
|
98
|
+
}
|
|
99
|
+
const data = (await res.json().catch(() => null));
|
|
100
|
+
if (!data || typeof data.url !== "string" || !data.url) {
|
|
101
|
+
return { ok: false, error: "share failed: response did not include a url" };
|
|
102
|
+
}
|
|
103
|
+
return { ok: true, url: data.url };
|
|
104
|
+
}
|
|
105
|
+
finally {
|
|
106
|
+
clearTimeout(timer);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
//# sourceMappingURL=share.js.map
|