@cybedefend/vibedefend 1.6.0 → 1.8.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.
Files changed (79) hide show
  1. package/README.md +24 -13
  2. package/dist/clients/antigravity.js +327 -0
  3. package/dist/clients/antigravity.js.map +1 -0
  4. package/dist/clients/registry.js +2 -0
  5. package/dist/clients/registry.js.map +1 -1
  6. package/dist/commands/mcp/proxy.js +67 -11
  7. package/dist/commands/mcp/proxy.js.map +1 -1
  8. package/dist/hook-runner.js +902 -227
  9. package/dist/hooks/install.js +1 -1
  10. package/dist/hooks/install.js.map +1 -1
  11. package/dist/hooks/runtime/antigravity-session.js +400 -0
  12. package/dist/hooks/runtime/antigravity-session.js.map +1 -0
  13. package/dist/hooks/runtime/emit.js +206 -0
  14. package/dist/hooks/runtime/emit.js.map +1 -1
  15. package/dist/hooks/runtime/exit-deadlock-guard.js +46 -0
  16. package/dist/hooks/runtime/exit-deadlock-guard.js.map +1 -0
  17. package/dist/hooks/runtime/fetch-rules.js +39 -3
  18. package/dist/hooks/runtime/fetch-rules.js.map +1 -1
  19. package/dist/hooks/runtime/pre-invocation.js +45 -0
  20. package/dist/hooks/runtime/pre-invocation.js.map +1 -0
  21. package/dist/hooks/runtime/runner-args.js +12 -0
  22. package/dist/hooks/runtime/runner-args.js.map +1 -0
  23. package/dist/hooks/runtime/session-activation.js +10 -4
  24. package/dist/hooks/runtime/session-activation.js.map +1 -1
  25. package/dist/hooks/runtime/session-review.js +42 -0
  26. package/dist/hooks/runtime/session-review.js.map +1 -1
  27. package/dist/hooks/runtime/session-start.js +21 -1
  28. package/dist/hooks/runtime/session-start.js.map +1 -1
  29. package/dist/hooks/runtime/sniff.js +325 -70
  30. package/dist/hooks/runtime/sniff.js.map +1 -1
  31. package/dist/hooks/runtime/work-dir.js +3 -0
  32. package/dist/hooks/runtime/work-dir.js.map +1 -1
  33. package/dist/hooks/shim.js +102 -5
  34. package/dist/hooks/shim.js.map +1 -1
  35. package/dist/json-file.js +6 -3
  36. package/dist/json-file.js.map +1 -1
  37. package/dist/mcp/proxy/audit.js.map +1 -1
  38. package/dist/mcp/proxy/inject.js +20 -5
  39. package/dist/mcp/proxy/inject.js.map +1 -1
  40. package/dist/mcp/proxy/intercept.js +26 -0
  41. package/dist/mcp/proxy/intercept.js.map +1 -1
  42. package/dist/mcp/proxy/paths.js +4 -0
  43. package/dist/mcp/proxy/paths.js.map +1 -1
  44. package/dist/mcp/proxy/proxy.js +12 -2
  45. package/dist/mcp/proxy/proxy.js.map +1 -1
  46. package/dist/mcp/proxy/serverCheckTimer.js +75 -0
  47. package/dist/mcp/proxy/serverCheckTimer.js.map +1 -0
  48. package/dist/mcp/proxy/sessionLifecycle.js +29 -0
  49. package/dist/mcp/proxy/sessionLifecycle.js.map +1 -0
  50. package/dist/mcp/proxy/verifyInterceptor.js +186 -27
  51. package/dist/mcp/proxy/verifyInterceptor.js.map +1 -1
  52. package/dist/mcp/report/buffer.js +351 -0
  53. package/dist/mcp/report/buffer.js.map +1 -0
  54. package/dist/mcp/report/coalesce.js +165 -0
  55. package/dist/mcp/report/coalesce.js.map +1 -0
  56. package/dist/mcp/report/constants.js +51 -0
  57. package/dist/mcp/report/constants.js.map +1 -0
  58. package/dist/mcp/report/project.js +83 -0
  59. package/dist/mcp/report/project.js.map +1 -0
  60. package/dist/mcp/report/reporter.js +443 -0
  61. package/dist/mcp/report/reporter.js.map +1 -0
  62. package/dist/mcp/report/types.js +3 -0
  63. package/dist/mcp/report/types.js.map +1 -0
  64. package/dist/mcp/report/validate.js +179 -0
  65. package/dist/mcp/report/validate.js.map +1 -0
  66. package/dist/mcp/verify/api.js +39 -0
  67. package/dist/mcp/verify/api.js.map +1 -1
  68. package/dist/mcp/verify/cache.js +18 -0
  69. package/dist/mcp/verify/cache.js.map +1 -1
  70. package/dist/mcp/verify/identity.js +120 -7
  71. package/dist/mcp/verify/identity.js.map +1 -1
  72. package/dist/mcp/verify/policy.js +2 -0
  73. package/dist/mcp/verify/policy.js.map +1 -1
  74. package/dist/mcp/verify/verifier.js +189 -32
  75. package/dist/mcp/verify/verifier.js.map +1 -1
  76. package/dist/shim.js +53 -3
  77. package/dist/utils.js +9 -0
  78. package/dist/utils.js.map +1 -1
  79. package/package.json +4 -3
@@ -0,0 +1,83 @@
1
+ /**
2
+ * The project a proxy reports for, resolved once per process.
3
+ *
4
+ * Off the hot path: the caller (the reporter) awaits it in the background and
5
+ * never before forwarding a call. It never throws.
6
+ *
7
+ * Only Claude Code has its project read from the proxy's working directory
8
+ * (`.cybedefend/config.json`, then the git origin through
9
+ * `GET /user/projects/resolve`): that the working directory is the agent's
10
+ * launch folder is verified for Claude Code alone. Any other agent, or one
11
+ * that did not say who it is, gets a project only from an explicit
12
+ * `CYBEDEFEND_PROJECT_ID`; otherwise its reports carry none. Where it is not
13
+ * reliable, the project is omitted rather than guessed (spec §2.3).
14
+ */
15
+ import { execFile } from 'node:child_process';
16
+ import { resolveProjectIdWithApi } from '../../hooks/runtime/resolve.js';
17
+ import { findRepoRoot } from '../../hooks/runtime/work-dir.js';
18
+ import { verifyTokenResolver } from '../verify/token.js';
19
+ const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
20
+ const ORIGIN_TIMEOUT_MS = 3000;
21
+ /** The agents whose working directory says which project they work on (normalised names). */
22
+ const PROJECT_FROM_WORKING_DIRECTORY = new Set(['claude-code']);
23
+ /**
24
+ * A client name as the gateway stores it (`toClientName`): lowercase, every run
25
+ * of other characters a single `-`, no `-` at either end, 64 characters at most.
26
+ */
27
+ export function normaliseClientName(name) {
28
+ if (typeof name !== 'string')
29
+ return '';
30
+ return name
31
+ .toLowerCase()
32
+ .replace(/[^a-z0-9._-]+/g, '-')
33
+ .replace(/-{2,}/g, '-')
34
+ .replace(/^-+|-+$/g, '')
35
+ .slice(0, 64)
36
+ .replace(/-+$/, '');
37
+ }
38
+ /**
39
+ * Asynchronous on purpose: the sync `spawnSync` of `src/git.ts` would block the
40
+ * forwarding loop for up to its timeout.
41
+ */
42
+ function readGitOrigin(cwd) {
43
+ return new Promise((resolve) => {
44
+ try {
45
+ execFile('git', ['remote', 'get-url', 'origin'], { cwd, timeout: ORIGIN_TIMEOUT_MS }, (err, stdout) => {
46
+ const out = err ? '' : String(stdout).trim();
47
+ resolve(out === '' ? null : out);
48
+ });
49
+ }
50
+ catch {
51
+ resolve(null);
52
+ }
53
+ });
54
+ }
55
+ export async function resolveReportProjectId(deps) {
56
+ try {
57
+ const explicit = deps.env.CYBEDEFEND_PROJECT_ID?.trim();
58
+ if (explicit && UUID_RE.test(explicit))
59
+ return explicit;
60
+ if (!PROJECT_FROM_WORKING_DIRECTORY.has(normaliseClientName(deps.clientName)))
61
+ return null;
62
+ const cwd = deps.cwd ?? process.cwd();
63
+ const root = findRepoRoot(cwd) ?? cwd;
64
+ let origin = null;
65
+ try {
66
+ origin = await (deps.readOrigin ?? readGitOrigin)(root);
67
+ }
68
+ catch {
69
+ origin = null;
70
+ }
71
+ const resolve = deps.resolveProject ?? resolveProjectIdWithApi;
72
+ const resolution = await resolve(root, {
73
+ resolveTokenFn: verifyTokenResolver({ env: deps.env }),
74
+ getOrigin: () => origin,
75
+ });
76
+ const id = resolution?.projectId;
77
+ return typeof id === 'string' && UUID_RE.test(id) ? id : null;
78
+ }
79
+ catch {
80
+ return null;
81
+ }
82
+ }
83
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","sourceRoot":"","sources":["../../../src/mcp/report/project.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,443 @@
1
+ // ─── The call reporter: what the proxy decided, batched off the hot path ─────
2
+ //
3
+ // `event()` is called from the forwarding loop: it is synchronous, bounded and
4
+ // never throws. Everything else runs on timers that never keep the process
5
+ // alive. The first send goes FIRST_SEND_DELAY_MS after something happened,
6
+ // then at most one send per MIN_SEND_INTERVAL_MS. A send appends its reports
7
+ // to the on-disk buffer first and posts from there, so a backend that is down
8
+ // or refusing loses nothing and the buffer's holds decide when it is asked
9
+ // again: what a flush leaves (refused, timed out, held, or skipped because
10
+ // another proxy held the flush lock) re-arms the one send timer for when it is
11
+ // due, never sooner than MIN_SEND_INTERVAL_MS after the last send.
12
+ //
13
+ // A report carries the server's identity (D2), the inventory snapshot (D8)
14
+ // and the coalesced events (D5), copied field by field: an input object is
15
+ // never spread into a body, because the gateway strips unknown keys rather
16
+ // than refusing them, and what it strips has already left the machine.
17
+ import { readClientInfo } from '../proxy/intercept.js';
18
+ import { EventCoalescer } from './coalesce.js';
19
+ import { FIRST_SEND_DELAY_MS, INVENTORY_REFRESH_MS, MIN_SEND_INTERVAL_MS, REPORT_MAX_EVENTS, REPORT_MAX_TOOL_COUNT, } from './constants.js';
20
+ import { reportProblems } from './validate.js';
21
+ const UUID = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
22
+ /** A send that failed before its flush said anything: tried again like a lost lock. */
23
+ const FLUSH_UNKNOWN = { ran: false, retryAt: null };
24
+ export class McpReporter {
25
+ opts;
26
+ now;
27
+ firstDelayMs;
28
+ minIntervalMs;
29
+ refreshMs;
30
+ setTimeoutFn;
31
+ clearTimeoutFn;
32
+ coalescer;
33
+ /** Cleaned like a `clientInfo` name. */
34
+ fallbackClientName;
35
+ client;
36
+ /**
37
+ * Who the agent is is known: a clientInfo arrived, or `initialize` was answered
38
+ * (`start`). Until then the project is not resolved: a send carries none.
39
+ */
40
+ clientSettled = false;
41
+ listDecided = false;
42
+ lastSnapshotJson;
43
+ lastInventoryAt = 0;
44
+ lastSendAt;
45
+ /** Learnt from the last backend context: the backend and organisation `stop()` appends under. */
46
+ destination;
47
+ projectPromise;
48
+ projectIdKnown;
49
+ /** The one send timer, and when it fires: an earlier need moves it, a later one leaves it. */
50
+ sendTimer;
51
+ sendTimerAt;
52
+ refreshTimer;
53
+ running = false;
54
+ scheduleAfterRun = false;
55
+ stopped = false;
56
+ constructor(opts) {
57
+ this.opts = opts;
58
+ this.now = opts.now ?? Date.now;
59
+ this.firstDelayMs = opts.firstDelayMs ?? FIRST_SEND_DELAY_MS;
60
+ this.minIntervalMs = opts.minIntervalMs ?? MIN_SEND_INTERVAL_MS;
61
+ this.refreshMs = opts.refreshMs ?? INVENTORY_REFRESH_MS;
62
+ this.setTimeoutFn = opts.setTimeoutFn ?? setTimeout;
63
+ this.clearTimeoutFn = opts.clearTimeoutFn ?? clearTimeout;
64
+ this.coalescer = new EventCoalescer({ now: this.now });
65
+ this.fallbackClientName =
66
+ opts.fallbackClientName === undefined
67
+ ? undefined
68
+ : readClientInfo({ clientInfo: { name: opts.fallbackClientName } })?.name;
69
+ }
70
+ // ── The hot path ─────────────────────────────────────────────────────────
71
+ event(input) {
72
+ try {
73
+ if (this.stopped)
74
+ return;
75
+ this.coalescer.add(input);
76
+ this.schedule();
77
+ }
78
+ catch {
79
+ // A report is never worth a call.
80
+ }
81
+ }
82
+ noteClient(client) {
83
+ if (client === undefined)
84
+ return;
85
+ try {
86
+ const cleaned = readClientInfo({ clientInfo: client });
87
+ if (cleaned) {
88
+ this.client = cleaned;
89
+ this.clientSettled = true;
90
+ }
91
+ }
92
+ catch {
93
+ // Ignored: the fallback name is used.
94
+ }
95
+ }
96
+ noteListDecided() {
97
+ this.listDecided = true;
98
+ this.scheduleIfInventoryDue();
99
+ }
100
+ noteServerChanged() {
101
+ this.scheduleIfInventoryDue();
102
+ }
103
+ // ── Lifecycle ────────────────────────────────────────────────────────────
104
+ /**
105
+ * After `initialize` was answered, with the clientInfo it carried (none:
106
+ * `undefined`): who the agent is is settled. Flushes what earlier processes
107
+ * left, learns the organization, arms the hourly refresh.
108
+ */
109
+ start(client) {
110
+ if (this.stopped)
111
+ return;
112
+ this.noteClient(client);
113
+ this.clientSettled = true;
114
+ this.armRefresh();
115
+ void this.flushOnly();
116
+ }
117
+ /** Synchronous: what is pending goes to the buffer, for the next process to send. No network. */
118
+ stop() {
119
+ if (this.stopped)
120
+ return;
121
+ this.stopped = true;
122
+ if (this.sendTimer !== undefined)
123
+ this.clearTimeoutFn(this.sendTimer);
124
+ if (this.refreshTimer !== undefined)
125
+ this.clearTimeoutFn(this.refreshTimer);
126
+ this.sendTimer = undefined;
127
+ this.sendTimerAt = undefined;
128
+ this.refreshTimer = undefined;
129
+ try {
130
+ if (this.destination !== undefined && this.coalescer.hasPending()) {
131
+ this.drainToBuffer(this.destination, false);
132
+ }
133
+ }
134
+ catch {
135
+ // Best-effort: the session is ending.
136
+ }
137
+ }
138
+ /** One send: the pending reports to the buffer, then the buffer to the backend. Never rejects. */
139
+ async sendNow() {
140
+ this.retryLater(await this.sendOnce());
141
+ }
142
+ /** `ctx: null` when there was no backend context to send with. Never rejects. */
143
+ async sendOnce() {
144
+ let ctx = null;
145
+ try {
146
+ ctx = await this.context();
147
+ if (!ctx)
148
+ return { ctx: null }; // No organization, no send: everything stays in memory, bounded.
149
+ // Resolved once, and only once the agent is known: before that the send
150
+ // carries no project, and the resolution waits for the agent's name.
151
+ if (this.projectIdKnown === undefined && this.clientSettled) {
152
+ this.projectIdKnown = await this.project();
153
+ }
154
+ this.drainToBuffer(ctx, true);
155
+ return { ctx, flushed: await this.flush(ctx) };
156
+ }
157
+ catch (error) {
158
+ this.opts.logger.warn('report: a send failed, the reports wait in the buffer', {
159
+ error: error instanceof Error ? error.name : 'unknown',
160
+ });
161
+ return { ctx, flushed: FLUSH_UNKNOWN };
162
+ }
163
+ }
164
+ // ── Cadence ──────────────────────────────────────────────────────────────
165
+ schedule() {
166
+ if (this.stopped)
167
+ return;
168
+ if (this.running) {
169
+ this.scheduleAfterRun = true;
170
+ return;
171
+ }
172
+ const nowMs = this.now();
173
+ const sinceLast = this.lastSendAt === undefined ? 0 : this.lastSendAt + this.minIntervalMs - nowMs;
174
+ this.armAt(nowMs + Math.max(this.firstDelayMs, sinceLast));
175
+ }
176
+ /** One timer: an earlier time moves it, a later one leaves it where it is. */
177
+ armAt(at) {
178
+ if (this.stopped)
179
+ return;
180
+ if (this.sendTimer !== undefined && this.sendTimerAt !== undefined && this.sendTimerAt <= at)
181
+ return;
182
+ if (this.sendTimer !== undefined)
183
+ this.clearTimeoutFn(this.sendTimer);
184
+ this.sendTimerAt = at;
185
+ this.sendTimer = this.unref(this.setTimeoutFn(() => void this.tick(), Math.max(0, at - this.now())));
186
+ }
187
+ /**
188
+ * After a flush, the one timer for what it left of this backend's records:
189
+ * when its earliest hold ends (a refusal, a timeout, a 401 backoff), at once
190
+ * when something is due already (appended meanwhile), and after the minimum
191
+ * interval when the flush did not run (another proxy held the lock) — never
192
+ * sooner than the minimum interval after the last send.
193
+ */
194
+ retryLater(outcome) {
195
+ try {
196
+ if (this.stopped || !outcome.ctx || !outcome.flushed)
197
+ return;
198
+ const { ctx, flushed } = outcome;
199
+ const nowMs = this.now();
200
+ let at;
201
+ if (!flushed.ran)
202
+ at = nowMs + this.minIntervalMs;
203
+ else if (flushed.retryAt !== null)
204
+ at = flushed.retryAt;
205
+ else
206
+ at = this.opts.buffer.hasDue(ctx.apiBase, ctx.token) ? nowMs : null;
207
+ if (at === null)
208
+ return;
209
+ const floor = this.lastSendAt === undefined ? at : this.lastSendAt + this.minIntervalMs;
210
+ this.armAt(Math.max(at, floor));
211
+ }
212
+ catch {
213
+ // Ignored: the next event or the hourly refresh sends again.
214
+ }
215
+ }
216
+ scheduleIfInventoryDue() {
217
+ try {
218
+ if (this.inventoryDue(this.safeSnapshot()))
219
+ this.schedule();
220
+ }
221
+ catch {
222
+ // Ignored: the hourly refresh catches up.
223
+ }
224
+ }
225
+ async tick() {
226
+ this.sendTimer = undefined;
227
+ this.sendTimerAt = undefined;
228
+ if (this.stopped)
229
+ return;
230
+ if (this.running) {
231
+ // A send is still on its way: this one follows it, at the usual cadence.
232
+ this.scheduleAfterRun = true;
233
+ return;
234
+ }
235
+ this.running = true;
236
+ this.scheduleAfterRun = false;
237
+ let outcome = { ctx: null };
238
+ try {
239
+ outcome = await this.sendOnce();
240
+ // No context this time (offline, organization not resolved yet): what
241
+ // is waiting is tried again at the next allowed send, not left for a
242
+ // trigger that may never come.
243
+ if (!outcome.ctx && (this.coalescer.hasPending() || this.inventoryDue(this.safeSnapshot()))) {
244
+ this.scheduleAfterRun = true;
245
+ }
246
+ }
247
+ finally {
248
+ // When the send ENDED: a hold the flush set runs from its own clock, so
249
+ // the next send is never armed a few milliseconds before it is due.
250
+ this.lastSendAt = this.now();
251
+ this.running = false;
252
+ if (this.scheduleAfterRun)
253
+ this.schedule();
254
+ this.retryLater(outcome);
255
+ }
256
+ }
257
+ armRefresh() {
258
+ if (this.stopped)
259
+ return;
260
+ if (this.refreshTimer !== undefined)
261
+ this.clearTimeoutFn(this.refreshTimer);
262
+ this.refreshTimer = this.unref(this.setTimeoutFn(() => {
263
+ this.refreshTimer = undefined;
264
+ this.armRefresh();
265
+ this.schedule();
266
+ }, this.refreshMs));
267
+ }
268
+ inventoryDue(snapshot) {
269
+ if (!this.listDecided || snapshot === null)
270
+ return false;
271
+ if (this.lastSnapshotJson === undefined)
272
+ return true;
273
+ if (JSON.stringify(snapshot) !== this.lastSnapshotJson)
274
+ return true;
275
+ return this.now() - this.lastInventoryAt >= this.refreshMs;
276
+ }
277
+ // ── Building and sending ─────────────────────────────────────────────────
278
+ /**
279
+ * Turns the pending events (and the inventory when it is due) into reports,
280
+ * appended to the buffer under the backend and organisation they are for.
281
+ * Synchronous, no network.
282
+ */
283
+ drainToBuffer(destination, withInventory) {
284
+ const snapshot = this.safeSnapshot();
285
+ if (snapshot === null)
286
+ return; // Nothing to say about the server yet: the events wait.
287
+ const nowMs = this.now();
288
+ const base = this.body(snapshot, new Date(nowMs).toISOString(), []);
289
+ const baseProblems = reportProblems(base);
290
+ const pending = this.coalescer.pending(Number.MAX_SAFE_INTEGER);
291
+ if (baseProblems.length > 0) {
292
+ // Field names only: never a value.
293
+ this.opts.logger.warn('report: the server part of a report is invalid, nothing is sent', {
294
+ problems: baseProblems,
295
+ });
296
+ this.coalescer.markSent(pending);
297
+ return;
298
+ }
299
+ const events = [];
300
+ for (const raw of pending) {
301
+ const event = copyEvent(raw);
302
+ if (reportProblems({ ...base, events: [event] }).length > 0) {
303
+ this.opts.logger.warn('report: an event the contract refuses is dropped', {
304
+ kind: String(raw.kind),
305
+ reason: String(raw.reason),
306
+ });
307
+ this.coalescer.markSent([raw]);
308
+ continue;
309
+ }
310
+ events.push(event);
311
+ }
312
+ const chunks = [];
313
+ for (let i = 0; i < events.length; i += REPORT_MAX_EVENTS) {
314
+ chunks.push(events.slice(i, i + REPORT_MAX_EVENTS));
315
+ }
316
+ if (chunks.length === 0 && withInventory && this.inventoryDue(snapshot))
317
+ chunks.push([]);
318
+ if (chunks.length === 0)
319
+ return;
320
+ for (const chunk of chunks) {
321
+ this.opts.buffer.append(destination.apiBase, destination.organizationId, { ...base, events: chunk });
322
+ this.coalescer.markSent(chunk);
323
+ }
324
+ this.lastSnapshotJson = JSON.stringify(snapshot);
325
+ this.lastInventoryAt = nowMs;
326
+ this.armRefresh();
327
+ }
328
+ body(snapshot, seenAt, events) {
329
+ const id = this.opts.identity;
330
+ const server = {
331
+ serverKey: id.serverKey,
332
+ kind: id.kind,
333
+ ...(id.host !== undefined ? { host: id.host } : {}),
334
+ ...(id.package !== undefined
335
+ ? {
336
+ package: {
337
+ ecosystem: id.package.ecosystem,
338
+ name: id.package.name,
339
+ ...(id.package.version !== undefined ? { version: id.package.version } : {}),
340
+ },
341
+ }
342
+ : {}),
343
+ ...(id.label !== undefined ? { label: id.label } : {}),
344
+ verdict: snapshot.verdict,
345
+ action: snapshot.action,
346
+ blockedBy: snapshot.blockedBy ?? null,
347
+ advisoryIds: [...(snapshot.advisoryIds ?? [])],
348
+ // The gateway refuses a count past its bound with a 400 that would cost the
349
+ // whole report: a server this large is told as the largest it accepts.
350
+ toolCount: Math.min(snapshot.toolCount, REPORT_MAX_TOOL_COUNT),
351
+ flaggedToolCount: Math.min(snapshot.flaggedToolCount, REPORT_MAX_TOOL_COUNT),
352
+ ...(snapshot.flaggedTools !== undefined
353
+ ? { flaggedTools: snapshot.flaggedTools.map((t) => ({ name: t.name, digest: t.digest })) }
354
+ : {}),
355
+ seenAt,
356
+ };
357
+ const name = this.client?.name ?? this.fallbackClientName ?? 'unknown';
358
+ const version = this.client?.name !== undefined ? this.client.version : undefined;
359
+ const projectId = this.projectIdKnown;
360
+ return {
361
+ vibedefendVersion: this.opts.vibedefendVersion,
362
+ client: version !== undefined ? { name, version } : { name },
363
+ ...(typeof projectId === 'string' && UUID.test(projectId) ? { projectId } : {}),
364
+ server,
365
+ events,
366
+ };
367
+ }
368
+ /** Posts the records made for this context's backend, and those only. */
369
+ flush(ctx) {
370
+ return this.opts.buffer.flush(ctx.apiBase, ctx.token, (organizationId, body) => this.opts.post({
371
+ apiBase: ctx.apiBase,
372
+ token: ctx.token,
373
+ mcpName: ctx.mcpName,
374
+ organizationId,
375
+ }, body));
376
+ }
377
+ /** `start()`'s flush: no new report, only what is waiting. */
378
+ async flushOnly() {
379
+ try {
380
+ const ctx = await this.context();
381
+ if (!ctx)
382
+ return;
383
+ // No project lookup here: it is a request of its own, made only once
384
+ // there is a report to file under it.
385
+ this.retryLater({ ctx, flushed: await this.flush(ctx) });
386
+ }
387
+ catch {
388
+ // Best-effort: the next send flushes again.
389
+ }
390
+ }
391
+ async context() {
392
+ let ctx;
393
+ try {
394
+ ctx = await this.opts.backendContext();
395
+ }
396
+ catch {
397
+ return null;
398
+ }
399
+ if (!ctx || !ctx.organizationId)
400
+ return null;
401
+ this.destination = { apiBase: ctx.apiBase, organizationId: ctx.organizationId };
402
+ return ctx;
403
+ }
404
+ /** Resolved once per process, for the agent's declared name; never rejects. */
405
+ project() {
406
+ this.projectPromise ??= Promise.resolve()
407
+ .then(() => this.opts.projectId(this.client?.name))
408
+ .catch(() => null);
409
+ return this.projectPromise;
410
+ }
411
+ safeSnapshot() {
412
+ try {
413
+ return this.opts.snapshot();
414
+ }
415
+ catch {
416
+ return null;
417
+ }
418
+ }
419
+ unref(handle) {
420
+ const unref = handle?.unref;
421
+ if (typeof unref === 'function')
422
+ unref.call(handle);
423
+ return handle;
424
+ }
425
+ }
426
+ /** An event as it leaves the machine, field by field. */
427
+ function copyEvent(e) {
428
+ return {
429
+ eventId: e.eventId,
430
+ kind: e.kind,
431
+ reason: e.reason,
432
+ tool: e.tool,
433
+ ...(e.toolDigest !== undefined ? { toolDigest: e.toolDigest } : {}),
434
+ ...(e.verdict !== undefined ? { verdict: e.verdict } : {}),
435
+ ...(e.category !== undefined ? { category: e.category } : {}),
436
+ ...(e.severity !== undefined ? { severity: e.severity } : {}),
437
+ ...(e.rules !== undefined ? { rules: [...e.rules] } : {}),
438
+ count: e.count,
439
+ firstAt: e.firstAt,
440
+ lastAt: e.lastAt,
441
+ };
442
+ }
443
+ //# sourceMappingURL=reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reporter.js","sourceRoot":"","sources":["../../../src/mcp/report/reporter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ // ─── The body of a call report (contract C4) ─────────────────────────────────
2
+ export {};
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/mcp/report/types.ts"],"names":[],"mappings":"AAAA,gFAAgF"}