@shield-agent/kya 0.1.29 → 0.1.31

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.
Files changed (54) hide show
  1. package/.mcp.json +1 -1
  2. package/LIMITATIONS.md +6 -2
  3. package/README.md +29 -22
  4. package/assets/activity-receipt.png +0 -0
  5. package/claude/claude_desktop_config.example.json +1 -1
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +81 -3
  8. package/dist/cli.js.map +1 -1
  9. package/dist/commands/receipt.d.ts +38 -0
  10. package/dist/commands/receipt.d.ts.map +1 -0
  11. package/dist/commands/receipt.js +92 -0
  12. package/dist/commands/receipt.js.map +1 -0
  13. package/dist/commands/start.d.ts +15 -0
  14. package/dist/commands/start.d.ts.map +1 -0
  15. package/dist/commands/start.js +113 -0
  16. package/dist/commands/start.js.map +1 -0
  17. package/dist/commands/wrap.d.ts +4 -2
  18. package/dist/commands/wrap.d.ts.map +1 -1
  19. package/dist/commands/wrap.js +41 -5
  20. package/dist/commands/wrap.js.map +1 -1
  21. package/dist/config.d.ts +5 -0
  22. package/dist/config.d.ts.map +1 -1
  23. package/dist/config.js +5 -0
  24. package/dist/config.js.map +1 -1
  25. package/dist/dash/render.d.ts.map +1 -1
  26. package/dist/dash/render.js +4 -0
  27. package/dist/dash/render.js.map +1 -1
  28. package/dist/receipt/auto-open.d.ts +17 -0
  29. package/dist/receipt/auto-open.d.ts.map +1 -0
  30. package/dist/receipt/auto-open.js +68 -0
  31. package/dist/receipt/auto-open.js.map +1 -0
  32. package/dist/receipt/live-server.d.ts +17 -0
  33. package/dist/receipt/live-server.d.ts.map +1 -0
  34. package/dist/receipt/live-server.js +197 -0
  35. package/dist/receipt/live-server.js.map +1 -0
  36. package/dist/receipt/render-receipt.d.ts +29 -0
  37. package/dist/receipt/render-receipt.d.ts.map +1 -0
  38. package/dist/receipt/render-receipt.js +439 -0
  39. package/dist/receipt/render-receipt.js.map +1 -0
  40. package/dist/trail-summary.d.ts +13 -0
  41. package/dist/trail-summary.d.ts.map +1 -0
  42. package/dist/trail-summary.js +254 -0
  43. package/dist/trail-summary.js.map +1 -0
  44. package/dist/trail.d.ts +28 -0
  45. package/dist/trail.d.ts.map +1 -0
  46. package/dist/trail.js +92 -0
  47. package/dist/trail.js.map +1 -0
  48. package/gemini/settings.example.json +1 -1
  49. package/grok/README.md +1 -1
  50. package/manifest.json +1 -1
  51. package/mcp.json +1 -1
  52. package/openai/codex.config.example.toml +1 -1
  53. package/package.json +1 -1
  54. package/server.json +2 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-receipt.d.ts","sourceRoot":"","sources":["../../src/receipt/render-receipt.ts"],"names":[],"mappings":"AAIA,OAAO,EAA2C,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAEvF,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE;QACf,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QACzB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;KAC/B,CAAC;IACF,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS;QAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACpF,gEAAgE;IAChE,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB;AAyED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,MAAM,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,GAAG,QAAQ,GAAG,aAAa,GAAG,YAAY,CAAC,CAAC,GACtF,YAAY,CAWd;AAED,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,OAAO,CAAC,IAAI,CAAC,YAAY,EAAE,OAAO,GAAG,QAAQ,GAAG,aAAa,GAAG,YAAY,CAAC,CAAC,GACtF,YAAY,CAWd;AAED,uEAAuE;AACvE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE;IACtC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC;CACzB,GAAG,YAAY,CAOf;AA6CD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CA4Q7D;AAED,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAoBjE"}
@@ -0,0 +1,439 @@
1
+ /**
2
+ * Activity feed HTML/MD for local trail events.
3
+ */
4
+ import { assertNoSecrets, clip } from "../dash/render.js";
5
+ import { productLabel, readTrail, readTrailSince } from "../trail.js";
6
+ function esc(s) {
7
+ return s
8
+ .replace(/&/g, "&")
9
+ .replace(/</g, "&lt;")
10
+ .replace(/>/g, "&gt;")
11
+ .replace(/"/g, "&quot;");
12
+ }
13
+ function countVerdicts(events) {
14
+ let allow = 0;
15
+ let deny = 0;
16
+ let require = 0;
17
+ let never = 0;
18
+ for (const e of events) {
19
+ const v = e.verdict.toUpperCase();
20
+ if (e.neverEvent || e.reasonCode === "NEVER_EVENT")
21
+ never++;
22
+ if (v === "ALLOW")
23
+ allow++;
24
+ else if (v === "DENY")
25
+ deny++;
26
+ else if (v === "REQUIRE_APPROVE")
27
+ require++;
28
+ }
29
+ return { allow, deny, require, never };
30
+ }
31
+ function relativeTime(ts, nowMs) {
32
+ const t = Date.parse(ts);
33
+ if (Number.isNaN(t))
34
+ return ts;
35
+ const sec = Math.round((nowMs - t) / 1000);
36
+ if (sec < 45)
37
+ return "just now";
38
+ if (sec < 3600)
39
+ return `${Math.max(1, Math.round(sec / 60))}m ago`;
40
+ if (sec < 86400)
41
+ return `${Math.round(sec / 3600)}h ago`;
42
+ if (sec < 86400 * 2)
43
+ return "yesterday";
44
+ return `${Math.round(sec / 86400)}d ago`;
45
+ }
46
+ function localDayKey(ts) {
47
+ const d = new Date(ts);
48
+ if (Number.isNaN(d.getTime()))
49
+ return "unknown";
50
+ const y = d.getFullYear();
51
+ const m = String(d.getMonth() + 1).padStart(2, "0");
52
+ const day = String(d.getDate()).padStart(2, "0");
53
+ return `${y}-${m}-${day}`;
54
+ }
55
+ function dayLabel(key, nowMs) {
56
+ const today = localDayKey(nowMs);
57
+ const y = localDayKey(nowMs - 86400000);
58
+ if (key === today)
59
+ return "Today";
60
+ if (key === y)
61
+ return "Yesterday";
62
+ return key;
63
+ }
64
+ function clock(ts) {
65
+ const d = new Date(ts);
66
+ if (Number.isNaN(d.getTime()))
67
+ return "";
68
+ return d.toLocaleTimeString(undefined, { hour: "2-digit", minute: "2-digit", hour12: false });
69
+ }
70
+ function tone(verdict) {
71
+ const v = verdict.toUpperCase();
72
+ if (v === "ALLOW")
73
+ return "ok";
74
+ if (v === "DENY")
75
+ return "bad";
76
+ if (v === "REQUIRE_APPROVE")
77
+ return "warn";
78
+ return "mute";
79
+ }
80
+ function verdictWord(verdict) {
81
+ const v = verdict.toUpperCase();
82
+ if (v === "REQUIRE_APPROVE")
83
+ return "HOLD";
84
+ return v;
85
+ }
86
+ export function buildReceiptModel(sessionId, events, extras) {
87
+ const filtered = events.filter((e) => e.sessionId === sessionId);
88
+ return {
89
+ title: "Agent activity",
90
+ rangeLabel: `session ${sessionId}`,
91
+ generatedAt: new Date().toISOString(),
92
+ events: filtered,
93
+ spend: extras?.spend,
94
+ mcpSeen: extras?.mcpSeen,
95
+ live: extras?.live,
96
+ };
97
+ }
98
+ export function buildWindowReceiptModel(events, days, extras) {
99
+ const n = days > 0 ? days : 3;
100
+ return {
101
+ title: "Agent activity",
102
+ rangeLabel: `last ${n} day${n === 1 ? "" : "s"}`,
103
+ generatedAt: new Date().toISOString(),
104
+ events,
105
+ spend: extras?.spend,
106
+ mcpSeen: extras?.mcpSeen,
107
+ live: extras?.live,
108
+ };
109
+ }
110
+ /** Shared loader for static artifacts and the live loopback server. */
111
+ export function loadReceiptModel(input) {
112
+ const days = input.days > 0 ? Math.floor(input.days) : 3;
113
+ if (input.sessionId) {
114
+ return buildReceiptModel(input.sessionId, readTrail(input.cwd), { live: input.live });
115
+ }
116
+ const since = new Date(Date.now() - days * 24 * 60 * 60 * 1000);
117
+ return buildWindowReceiptModel(readTrailSince(input.cwd, since), days, { live: input.live });
118
+ }
119
+ function renderFeed(events, nowMs, live) {
120
+ if (events.length === 0) {
121
+ const hint = live
122
+ ? "No events yet. Wrap a tool call and this page will refresh."
123
+ : "No events yet. Run a wrap, then regenerate this receipt.";
124
+ return `<p class="empty">${hint}</p>`;
125
+ }
126
+ const sorted = [...events].sort((a, b) => b.ts.localeCompare(a.ts));
127
+ const parts = [];
128
+ let lastDay = "";
129
+ for (const e of sorted) {
130
+ const key = localDayKey(e.ts);
131
+ if (key !== lastDay) {
132
+ lastDay = key;
133
+ parts.push(`<div class="day" role="presentation">${esc(dayLabel(key, nowMs))}</div>`);
134
+ }
135
+ const t = tone(e.verdict);
136
+ const never = e.neverEvent || e.reasonCode === "NEVER_EVENT";
137
+ const summary = e.summary?.trim()
138
+ ? `<div class="summary">${esc(e.summary.trim())}</div>`
139
+ : "";
140
+ parts.push(`<article class="ev ${t}${never ? " never" : ""}">
141
+ <div class="rail" aria-hidden="true"><span class="tick"></span></div>
142
+ <div class="main">
143
+ <div class="top">
144
+ <span class="verdict">${esc(verdictWord(e.verdict))}</span>
145
+ <code class="tool">${esc(e.toolId)}</code>
146
+ <time class="when" datetime="${esc(e.ts)}" title="${esc(e.ts)}">${esc(clock(e.ts))} <span class="rel">${esc(relativeTime(e.ts, nowMs))}</span></time>
147
+ </div>
148
+ ${summary}
149
+ <div class="meta">
150
+ <span class="product">${esc(productLabel(e.product))}</span>
151
+ <span class="dot">-</span>
152
+ <span class="reason">${esc(e.reasonCode)}</span>
153
+ </div>
154
+ </div>
155
+ </article>`);
156
+ }
157
+ return parts.join("\n");
158
+ }
159
+ export function renderReceiptHtml(model) {
160
+ const nowMs = Date.now();
161
+ const events = [...model.events].map((e) => ({
162
+ ...e,
163
+ toolId: clip(e.toolId, 160),
164
+ reasonCode: clip(e.reasonCode, 80),
165
+ summary: e.summary ? clip(e.summary, 120) : undefined,
166
+ }));
167
+ const c = countVerdicts(events);
168
+ const blocked = events.filter((e) => e.neverEvent || e.reasonCode === "NEVER_EVENT");
169
+ const tools = model.mcpSeen && model.mcpSeen.length > 0
170
+ ? model.mcpSeen.map((m) => m.toolId)
171
+ : [...new Set(events.map((e) => e.toolId))];
172
+ const blockedBanner = blocked.length === 0
173
+ ? ""
174
+ : `<aside class="alert" aria-label="Blocked never-events">
175
+ <strong>${blocked.length} blocked</strong>
176
+ <span>${blocked.map((e) => `<code>${esc(e.toolId)}</code>`).join(" ")}</span>
177
+ </aside>`;
178
+ const toolsHtml = tools.length === 0
179
+ ? ""
180
+ : `<footer class="tools">
181
+ <span class="label">Tools</span>
182
+ ${tools.map((t) => `<code>${esc(t)}</code>`).join("")}
183
+ </footer>`;
184
+ const liveScript = model.live
185
+ ? `<script>
186
+ (function(){
187
+ var pill = document.querySelector('.live');
188
+ var es = new EventSource('/events');
189
+ es.onmessage = function(){ location.reload(); };
190
+ es.onerror = function(){
191
+ if (pill) { pill.textContent = 'Offline'; pill.classList.add('off'); }
192
+ };
193
+ })();
194
+ </script>`
195
+ : "";
196
+ const livePill = model.live ? `<span class="live" title="Watching trail.jsonl">Live</span>` : "";
197
+ const html = `<!DOCTYPE html>
198
+ <html lang="en">
199
+ <head>
200
+ <meta charset="utf-8"/>
201
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
202
+ <title>${esc(model.title)} - ${esc(model.rangeLabel)}</title>
203
+ <style>
204
+ :root {
205
+ color-scheme: dark;
206
+ --bg: #0a0c10;
207
+ --fg: #eef2f7;
208
+ --mute: #8b95a8;
209
+ --line: #1c2330;
210
+ --card: #10141c;
211
+ --ok: #3ecf8e;
212
+ --bad: #ff5d5d;
213
+ --warn: #f0b429;
214
+ --rail: #2a3344;
215
+ --day: #6b7280;
216
+ }
217
+ @media (prefers-color-scheme: light) {
218
+ :root {
219
+ color-scheme: light;
220
+ --bg: #f3f5f8;
221
+ --fg: #0f172a;
222
+ --mute: #64748b;
223
+ --line: #e2e8f0;
224
+ --card: #ffffff;
225
+ --ok: #059669;
226
+ --bad: #dc2626;
227
+ --warn: #d97706;
228
+ --rail: #cbd5e1;
229
+ --day: #64748b;
230
+ }
231
+ }
232
+ * { box-sizing: border-box; }
233
+ body {
234
+ margin: 0;
235
+ font-family: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif;
236
+ background: var(--bg);
237
+ color: var(--fg);
238
+ line-height: 1.4;
239
+ }
240
+ main { max-width: 42rem; margin: 0 auto; padding: 1.35rem 1rem 3rem; }
241
+ header.bar {
242
+ position: sticky; top: 0; z-index: 3;
243
+ background: color-mix(in srgb, var(--bg) 88%, transparent);
244
+ backdrop-filter: blur(10px);
245
+ padding: 0.85rem 0 0.75rem;
246
+ border-bottom: 1px solid var(--line);
247
+ margin-bottom: 1rem;
248
+ }
249
+ .title-row {
250
+ display: flex; align-items: baseline; justify-content: space-between;
251
+ gap: 0.75rem; flex-wrap: wrap;
252
+ }
253
+ h1 {
254
+ margin: 0; font-size: 1.2rem; font-weight: 600;
255
+ letter-spacing: -0.025em;
256
+ }
257
+ .range { color: var(--mute); font-size: 0.85rem; display: inline-flex; align-items: center; gap: 0.5rem; }
258
+ .live {
259
+ display: inline-flex; align-items: center; gap: 0.35rem;
260
+ font-size: 0.7rem; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase;
261
+ color: var(--ok); border: 1px solid color-mix(in srgb, var(--ok) 40%, transparent);
262
+ border-radius: 999px; padding: 0.12rem 0.5rem;
263
+ }
264
+ .live::before {
265
+ content: ""; width: 0.4rem; height: 0.4rem; border-radius: 50%;
266
+ background: var(--ok);
267
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--ok) 22%, transparent);
268
+ animation: pulse 1.6s ease-in-out infinite;
269
+ }
270
+ .live.off { color: var(--mute); border-color: var(--line); }
271
+ .live.off::before { background: var(--mute); box-shadow: none; animation: none; }
272
+ @keyframes pulse {
273
+ 0%, 100% { opacity: 1; }
274
+ 50% { opacity: 0.45; }
275
+ }
276
+ @media (prefers-reduced-motion: reduce) {
277
+ .live::before { animation: none; }
278
+ }
279
+ .stats {
280
+ display: flex; flex-wrap: wrap; gap: 0.4rem; margin-top: 0.7rem;
281
+ }
282
+ .stat {
283
+ font-size: 0.75rem; font-variant-numeric: tabular-nums;
284
+ color: var(--mute); background: var(--card);
285
+ border: 1px solid var(--line); border-radius: 999px;
286
+ padding: 0.2rem 0.6rem;
287
+ }
288
+ .stat b { color: var(--fg); font-weight: 650; margin-left: 0.25rem; }
289
+ .stat.bad b { color: var(--bad); }
290
+ .stat.warn b { color: var(--warn); }
291
+ .stat.ok b { color: var(--ok); }
292
+ .alert {
293
+ display: flex; flex-wrap: wrap; gap: 0.45rem 0.75rem; align-items: baseline;
294
+ background: color-mix(in srgb, var(--bad) 12%, var(--card));
295
+ border: 1px solid color-mix(in srgb, var(--bad) 35%, var(--line));
296
+ border-radius: 10px; padding: 0.65rem 0.85rem; margin-bottom: 1rem;
297
+ font-size: 0.85rem;
298
+ }
299
+ .alert strong { color: var(--bad); font-size: 0.78rem; text-transform: uppercase; letter-spacing: 0.04em; }
300
+ .alert code {
301
+ font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
302
+ font-size: 0.78rem;
303
+ }
304
+ .feed {
305
+ background: var(--card);
306
+ border: 1px solid var(--line);
307
+ border-radius: 12px;
308
+ overflow: hidden;
309
+ }
310
+ .day {
311
+ padding: 0.55rem 0.9rem 0.35rem;
312
+ font-size: 0.68rem; font-weight: 700; letter-spacing: 0.08em;
313
+ text-transform: uppercase; color: var(--day);
314
+ background: color-mix(in srgb, var(--bg) 55%, var(--card));
315
+ border-bottom: 1px solid var(--line);
316
+ position: sticky; top: 4.2rem; z-index: 1;
317
+ }
318
+ .ev {
319
+ display: grid; grid-template-columns: 1.1rem 1fr; gap: 0;
320
+ border-bottom: 1px solid var(--line);
321
+ }
322
+ .ev:last-child { border-bottom: none; }
323
+ .rail {
324
+ position: relative;
325
+ display: flex; justify-content: center;
326
+ padding-top: 1.05rem;
327
+ }
328
+ .rail::before {
329
+ content: ""; position: absolute; top: 0; bottom: 0; left: 50%;
330
+ width: 1px; background: var(--rail); transform: translateX(-50%);
331
+ }
332
+ .tick {
333
+ width: 0.55rem; height: 0.55rem; border-radius: 50%;
334
+ background: var(--mute); position: relative; z-index: 1;
335
+ box-shadow: 0 0 0 3px var(--card);
336
+ }
337
+ .ev.ok .tick { background: var(--ok); }
338
+ .ev.bad .tick { background: var(--bad); }
339
+ .ev.warn .tick { background: var(--warn); }
340
+ .ev.never { background: color-mix(in srgb, var(--bad) 7%, transparent); }
341
+ .main { padding: 0.7rem 0.85rem 0.7rem 0.35rem; min-width: 0; }
342
+ .top {
343
+ display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.35rem 0.55rem;
344
+ }
345
+ @media (max-width: 480px) {
346
+ .when { flex-basis: 100%; margin-left: 0; margin-top: 0.1rem; }
347
+ }
348
+ .verdict {
349
+ font-size: 0.68rem; font-weight: 750; letter-spacing: 0.05em;
350
+ min-width: 2.6rem;
351
+ }
352
+ .ev.ok .verdict { color: var(--ok); }
353
+ .ev.bad .verdict { color: var(--bad); }
354
+ .ev.warn .verdict { color: var(--warn); }
355
+ .tool {
356
+ font-family: "IBM Plex Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
357
+ font-size: 0.84rem; word-break: break-word; flex: 1 1 auto;
358
+ }
359
+ .when {
360
+ margin-left: auto; color: var(--mute); font-size: 0.72rem;
361
+ font-variant-numeric: tabular-nums; white-space: nowrap;
362
+ }
363
+ .when .rel { opacity: 0.85; margin-left: 0.35rem; }
364
+ .summary {
365
+ margin-top: 0.2rem;
366
+ font-size: 0.84rem;
367
+ color: var(--fg);
368
+ word-break: break-word;
369
+ }
370
+ .meta {
371
+ margin-top: 0.18rem; color: var(--mute); font-size: 0.76rem;
372
+ display: flex; flex-wrap: wrap; gap: 0.25rem; align-items: baseline;
373
+ }
374
+ .dot { opacity: 0.55; }
375
+ .empty { margin: 0; padding: 1.25rem 1rem; color: var(--mute); font-size: 0.9rem; }
376
+ .tools {
377
+ margin-top: 1.1rem; display: flex; flex-wrap: wrap; gap: 0.35rem; align-items: center;
378
+ }
379
+ .tools .label {
380
+ font-size: 0.68rem; font-weight: 700; letter-spacing: 0.06em;
381
+ text-transform: uppercase; color: var(--mute); margin-right: 0.25rem;
382
+ }
383
+ .tools code {
384
+ font-family: "IBM Plex Mono", ui-monospace, Menlo, monospace;
385
+ font-size: 0.72rem; color: var(--mute);
386
+ background: var(--card); border: 1px solid var(--line);
387
+ border-radius: 6px; padding: 0.18rem 0.4rem;
388
+ }
389
+ </style>
390
+ </head>
391
+ <body>
392
+ <main>
393
+ <header class="bar">
394
+ <div class="title-row">
395
+ <h1>${esc(model.title)}</h1>
396
+ <div class="range">${esc(model.rangeLabel)}${livePill}</div>
397
+ </div>
398
+ <div class="stats" aria-label="Counts">
399
+ <span class="stat ok">Allow<b>${c.allow}</b></span>
400
+ <span class="stat bad">Deny<b>${c.deny}</b></span>
401
+ <span class="stat warn">Hold<b>${c.require}</b></span>
402
+ <span class="stat">Never<b>${c.never}</b></span>
403
+ </div>
404
+ </header>
405
+ ${blockedBanner}
406
+ <section class="feed" id="feed" aria-label="Activity feed">
407
+ ${renderFeed(events, nowMs, model.live)}
408
+ </section>
409
+ ${toolsHtml}
410
+ </main>
411
+ ${liveScript}
412
+ </body>
413
+ </html>`;
414
+ // Defense-in-depth: block known secret shapes before serving HTML.
415
+ assertNoSecrets(html);
416
+ return html;
417
+ }
418
+ export function renderReceiptMarkdown(model) {
419
+ const c = countVerdicts(model.events);
420
+ const lines = [
421
+ `# ${model.title}`,
422
+ "",
423
+ model.rangeLabel,
424
+ "",
425
+ `Allow ${c.allow} | Deny ${c.deny} | Hold ${c.require} | Never ${c.never}`,
426
+ "",
427
+ "## Feed",
428
+ ...[...model.events]
429
+ .sort((a, b) => b.ts.localeCompare(a.ts))
430
+ .map((e) => {
431
+ const sum = e.summary?.trim() ? ` - ${e.summary.trim()}` : "";
432
+ return `- **${verdictWord(e.verdict)}** \`${e.toolId}\`${sum} - ${productLabel(e.product)} - ${e.reasonCode}`;
433
+ }),
434
+ ];
435
+ const md = `${lines.join("\n")}\n`;
436
+ assertNoSecrets(md);
437
+ return md;
438
+ }
439
+ //# sourceMappingURL=render-receipt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-receipt.js","sourceRoot":"","sources":["../../src/receipt/render-receipt.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /** Strip query/fragment from URLs before they enter the summary. */
2
+ export declare function scrubUrl(value: string): string;
3
+ /**
4
+ * Shell lines: keep bin + arg count only — never the full command
5
+ * (env assignments, -p passwords, Basic auth headers).
6
+ */
7
+ export declare function summarizeShellCommand(cmd: string): string;
8
+ /**
9
+ * Derive a one-line change summary for the activity feed.
10
+ * Returns undefined when there is nothing safe/useful to show.
11
+ */
12
+ export declare function deriveTrailSummary(toolId: string, args?: unknown): string | undefined;
13
+ //# sourceMappingURL=trail-summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trail-summary.d.ts","sourceRoot":"","sources":["../src/trail-summary.ts"],"names":[],"mappings":"AA8GA,oEAAoE;AACpE,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAe9C;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAkBzD;AAoDD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CA8DrF"}