agent-insights 0.0.13 → 0.0.16

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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- type AgentName = "claude-code" | "cursor" | "opencode" | "codex" | "unknown";
1
+ type AgentName = "claude-code" | "cursor" | "opencode" | "codex" | "pi" | "unknown";
2
2
  type AgentEventType = "session.start" | "session.end" | "user.prompt.submit" | "tool.start" | "tool.end" | "tool.failure" | "permission.request" | "permission.denied" | "subagent.start" | "subagent.end" | "agent.stop" | "notification" | "context.compact.start" | "context.compact.end" | "error";
3
3
  type AgentOutcome = "success" | "error" | "cancelled" | "unknown";
4
4
  type AgentEvent = {
@@ -82,7 +82,7 @@ type AgentInsightsConfig = {
82
82
  exporter: ExporterConfig;
83
83
  transcriptStore: TranscriptStoreConfig;
84
84
  sessionAnalysis: SessionAnalysisConfig;
85
- agents: Record<"claudeCode" | "cursor", AgentConfig>;
85
+ agents: Record<"claudeCode" | "cursor" | "codex" | "pi", AgentConfig>;
86
86
  privacy: {
87
87
  capturePrompts: false;
88
88
  captureMessages: false;
@@ -94,7 +94,7 @@ declare function defaultConfig(): AgentInsightsConfig;
94
94
  declare function loadConfig(): Promise<AgentInsightsConfig | undefined>;
95
95
  declare function saveConfig(cfg: AgentInsightsConfig): Promise<void>;
96
96
 
97
- type AgentId = "claude-code" | "cursor";
97
+ type AgentId = "claude-code" | "cursor" | "codex" | "pi";
98
98
  type HookPayload = {
99
99
  /** Native event name as emitted by the agent (e.g. `SessionStart`). */
100
100
  event: string;
package/dist/index.js CHANGED
@@ -257,12 +257,162 @@ function asString(v) {
257
257
  return typeof v === "string" && v.length > 0 ? v : void 0;
258
258
  }
259
259
 
260
- // src/adapters/cursor.ts
260
+ // src/adapters/codex.ts
261
261
  import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
262
262
  import { homedir as homedir2 } from "os";
263
263
  import { dirname as dirname2, join as join2 } from "path";
264
264
  var HOOK_COMMAND_NAME2 = "agent-insights";
265
265
  var HOOK_MAP2 = {
266
+ SessionStart: "session.start",
267
+ UserPromptSubmit: "user.prompt.submit",
268
+ PreToolUse: "tool.start",
269
+ PostToolUse: "tool.end",
270
+ PermissionRequest: "permission.request",
271
+ Stop: "session.end"
272
+ };
273
+ var CODEX_HOOK_EVENTS = Object.keys(HOOK_MAP2);
274
+ var codexAdapter = {
275
+ id: "codex",
276
+ agent: "codex",
277
+ label: "Codex",
278
+ settingsFile: ".codex/hooks.json",
279
+ map(payload) {
280
+ const type = HOOK_MAP2[payload.event];
281
+ if (!type) return void 0;
282
+ const data = payload.data ?? {};
283
+ const sessionId = asString2(data["session_id"]) ?? asString2(data["sessionId"]);
284
+ const toolName = asString2(data["tool_name"]) ?? asString2(data["toolName"]) ?? asString2(data["tool"]?.["name"]);
285
+ const transcriptPath = asString2(data["transcript_path"]) ?? asString2(data["transcriptPath"]);
286
+ return {
287
+ type,
288
+ ...sessionId !== void 0 ? { sessionId } : {},
289
+ ...toolName !== void 0 ? { toolName } : {},
290
+ ...transcriptPath !== void 0 ? { transcriptPath } : {}
291
+ };
292
+ },
293
+ async install(repoRoot, scope = "global") {
294
+ const path = resolveCodexPath(repoRoot, scope);
295
+ const settings = await readJson2(path);
296
+ const next = { ...settings ?? {} };
297
+ const hooks = {};
298
+ for (const [event, raw] of Object.entries(next.hooks ?? {})) {
299
+ hooks[event] = normalizeEventHooks2(raw);
300
+ }
301
+ for (const event of CODEX_HOOK_EVENTS) {
302
+ const withoutInsights = removeAgentInsightsMatchers2(hooks[event] ?? []);
303
+ hooks[event] = addAgentInsightsHook2(withoutInsights, event);
304
+ }
305
+ next.hooks = hooks;
306
+ await mkdir2(dirname2(path), { recursive: true });
307
+ await writeFile2(path, `${JSON.stringify(next, null, 2)}
308
+ `, "utf8");
309
+ return { written: true, path };
310
+ },
311
+ async uninstall(repoRoot, scope = "global") {
312
+ const path = resolveCodexPath(repoRoot, scope);
313
+ const settings = await readJson2(path);
314
+ if (!settings?.hooks) return { removed: false, path };
315
+ const hooks = {};
316
+ let touched = false;
317
+ for (const [event, raw] of Object.entries(settings.hooks)) {
318
+ const before = normalizeEventHooks2(raw);
319
+ const after = removeAgentInsightsMatchers2(before);
320
+ if (after.length !== before.length || JSON.stringify(after) !== JSON.stringify(before)) {
321
+ touched = true;
322
+ }
323
+ if (after.length > 0) hooks[event] = after;
324
+ }
325
+ settings.hooks = hooks;
326
+ await writeFile2(path, `${JSON.stringify(settings, null, 2)}
327
+ `, "utf8");
328
+ return { removed: touched, path };
329
+ },
330
+ async isInstalled(repoRoot, scope = "global") {
331
+ const settings = await readJson2(
332
+ resolveCodexPath(repoRoot, scope)
333
+ );
334
+ if (!settings?.hooks) return false;
335
+ return Object.values(settings.hooks).some(
336
+ (raw) => normalizeEventHooks2(raw).some(
337
+ (group) => group.hooks.some((h) => isAgentInsightsCommand2(h.command))
338
+ )
339
+ );
340
+ }
341
+ };
342
+ function resolveCodexPath(repoRoot, scope) {
343
+ return scope === "global" ? join2(homedir2(), ".codex", "hooks.json") : join2(repoRoot, ".codex", "hooks.json");
344
+ }
345
+ function isAgentInsightsCommand2(cmd) {
346
+ if (!cmd) return false;
347
+ return cmd.startsWith(`${HOOK_COMMAND_NAME2} hook`);
348
+ }
349
+ function isHookCommand2(value) {
350
+ if (!value || typeof value !== "object") return false;
351
+ const entry = value;
352
+ return entry.type === "command" && typeof entry.command === "string";
353
+ }
354
+ function normalizeEventHooks2(raw) {
355
+ const groups = [];
356
+ for (const entry of raw) {
357
+ if (!entry || typeof entry !== "object") continue;
358
+ const record = entry;
359
+ if (Array.isArray(record.hooks)) {
360
+ const commands = record.hooks.filter(isHookCommand2);
361
+ if (commands.length === 0) continue;
362
+ groups.push({
363
+ matcher: typeof record.matcher === "string" ? record.matcher : "",
364
+ hooks: commands
365
+ });
366
+ continue;
367
+ }
368
+ if (isHookCommand2(record)) {
369
+ groups.push({ matcher: "", hooks: [record] });
370
+ }
371
+ }
372
+ return groups;
373
+ }
374
+ function removeAgentInsightsMatchers2(matchers) {
375
+ const result = [];
376
+ for (const group of matchers) {
377
+ const hooks = group.hooks.filter(
378
+ (h) => !isAgentInsightsCommand2(h.command)
379
+ );
380
+ if (hooks.length > 0) result.push({ ...group, hooks });
381
+ }
382
+ return result;
383
+ }
384
+ function addAgentInsightsHook2(matchers, event) {
385
+ const command = `${HOOK_COMMAND_NAME2} hook ${event}`;
386
+ const entry = { type: "command", command };
387
+ for (const group of matchers) {
388
+ if (group.matcher === "") {
389
+ if (!group.hooks.some((h) => h.command === command)) {
390
+ group.hooks.push(entry);
391
+ }
392
+ return matchers;
393
+ }
394
+ }
395
+ return [...matchers, { matcher: "", hooks: [entry] }];
396
+ }
397
+ async function readJson2(path) {
398
+ try {
399
+ const raw = await readFile2(path, "utf8");
400
+ return JSON.parse(raw);
401
+ } catch (err) {
402
+ if (err.code === "ENOENT") return void 0;
403
+ throw err;
404
+ }
405
+ }
406
+ function asString2(v) {
407
+ return typeof v === "string" && v.length > 0 ? v : void 0;
408
+ }
409
+
410
+ // src/adapters/cursor.ts
411
+ import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
412
+ import { homedir as homedir3 } from "os";
413
+ import { dirname as dirname3, join as join3 } from "path";
414
+ var HOOK_COMMAND_NAME3 = "agent-insights";
415
+ var HOOK_MAP3 = {
266
416
  sessionStart: "session.start",
267
417
  sessionEnd: "session.end",
268
418
  beforeSubmitPrompt: "user.prompt.submit",
@@ -279,19 +429,19 @@ var HOOK_MAP2 = {
279
429
  afterFileEdit: "tool.end",
280
430
  workspaceOpen: "session.start"
281
431
  };
282
- var CURSOR_HOOK_EVENTS = Object.keys(HOOK_MAP2);
432
+ var CURSOR_HOOK_EVENTS = Object.keys(HOOK_MAP3);
283
433
  var cursorAdapter = {
284
434
  id: "cursor",
285
435
  agent: "cursor",
286
436
  label: "Cursor",
287
437
  settingsFile: ".cursor/hooks.json",
288
438
  map(payload) {
289
- const type = HOOK_MAP2[payload.event];
439
+ const type = HOOK_MAP3[payload.event];
290
440
  if (!type) return void 0;
291
441
  const data = payload.data ?? {};
292
- const sessionId = asString2(data["session_id"]) ?? asString2(data["sessionId"]) ?? asString2(data["conversation_id"]);
293
- const toolName = asString2(data["tool_name"]) ?? asString2(data["toolName"]);
294
- const transcriptPath = asString2(data["transcript_path"]) ?? asString2(data["transcriptPath"]) ?? asString2(process.env.CURSOR_TRANSCRIPT_PATH);
442
+ const sessionId = asString3(data["session_id"]) ?? asString3(data["sessionId"]) ?? asString3(data["conversation_id"]);
443
+ const toolName = asString3(data["tool_name"]) ?? asString3(data["toolName"]);
444
+ const transcriptPath = asString3(data["transcript_path"]) ?? asString3(data["transcriptPath"]) ?? asString3(process.env.CURSOR_TRANSCRIPT_PATH);
295
445
  return {
296
446
  type,
297
447
  ...sessionId !== void 0 ? { sessionId } : {},
@@ -301,7 +451,7 @@ var cursorAdapter = {
301
451
  },
302
452
  async install(repoRoot, scope = "global") {
303
453
  const path = resolveCursorPath(repoRoot, scope);
304
- const settings = await readJson2(path);
454
+ const settings = await readJson3(path);
305
455
  const next = {
306
456
  version: 1,
307
457
  ...settings ?? {}
@@ -309,26 +459,26 @@ var cursorAdapter = {
309
459
  const hooks = { ...next.hooks ?? {} };
310
460
  for (const event of CURSOR_HOOK_EVENTS) {
311
461
  const existing = (hooks[event] ?? []).filter(
312
- (h) => !isAgentInsightsCommand2(h.command)
462
+ (h) => !isAgentInsightsCommand3(h.command)
313
463
  );
314
- existing.push({ command: `${HOOK_COMMAND_NAME2} hook ${event}` });
464
+ existing.push({ command: `${HOOK_COMMAND_NAME3} hook ${event}` });
315
465
  hooks[event] = existing;
316
466
  }
317
467
  next.hooks = hooks;
318
- await mkdir2(dirname2(path), { recursive: true });
319
- await writeFile2(path, `${JSON.stringify(next, null, 2)}
468
+ await mkdir3(dirname3(path), { recursive: true });
469
+ await writeFile3(path, `${JSON.stringify(next, null, 2)}
320
470
  `, "utf8");
321
471
  return { written: true, path };
322
472
  },
323
473
  async uninstall(repoRoot, scope = "global") {
324
474
  const path = resolveCursorPath(repoRoot, scope);
325
- const settings = await readJson2(path);
475
+ const settings = await readJson3(path);
326
476
  if (!settings?.hooks) return { removed: false, path };
327
477
  const hooks = { ...settings.hooks };
328
478
  let touched = false;
329
479
  for (const [event, entries] of Object.entries(hooks)) {
330
480
  const filtered = entries.filter(
331
- (h) => !isAgentInsightsCommand2(h.command)
481
+ (h) => !isAgentInsightsCommand3(h.command)
332
482
  );
333
483
  if (filtered.length !== entries.length) touched = true;
334
484
  if (filtered.length === 0) {
@@ -338,44 +488,160 @@ var cursorAdapter = {
338
488
  }
339
489
  }
340
490
  settings.hooks = hooks;
341
- await writeFile2(path, `${JSON.stringify(settings, null, 2)}
491
+ await writeFile3(path, `${JSON.stringify(settings, null, 2)}
342
492
  `, "utf8");
343
493
  return { removed: touched, path };
344
494
  },
345
495
  async isInstalled(repoRoot, scope = "global") {
346
- const settings = await readJson2(
496
+ const settings = await readJson3(
347
497
  resolveCursorPath(repoRoot, scope)
348
498
  );
349
499
  if (!settings?.hooks) return false;
350
500
  return Object.values(settings.hooks).some(
351
- (entries) => entries.some((h) => isAgentInsightsCommand2(h.command))
501
+ (entries) => entries.some((h) => isAgentInsightsCommand3(h.command))
352
502
  );
353
503
  }
354
504
  };
355
505
  function resolveCursorPath(repoRoot, scope) {
356
- return scope === "global" ? join2(homedir2(), ".cursor", "hooks.json") : join2(repoRoot, ".cursor", "hooks.json");
506
+ return scope === "global" ? join3(homedir3(), ".cursor", "hooks.json") : join3(repoRoot, ".cursor", "hooks.json");
357
507
  }
358
- function isAgentInsightsCommand2(cmd) {
508
+ function isAgentInsightsCommand3(cmd) {
359
509
  if (!cmd) return false;
360
- return cmd.startsWith(`${HOOK_COMMAND_NAME2} hook`);
510
+ return cmd.startsWith(`${HOOK_COMMAND_NAME3} hook`);
361
511
  }
362
- async function readJson2(path) {
512
+ async function readJson3(path) {
363
513
  try {
364
- const raw = await readFile2(path, "utf8");
514
+ const raw = await readFile3(path, "utf8");
365
515
  return JSON.parse(raw);
366
516
  } catch (err) {
367
517
  if (err.code === "ENOENT") return void 0;
368
518
  throw err;
369
519
  }
370
520
  }
371
- function asString2(v) {
521
+ function asString3(v) {
522
+ return typeof v === "string" && v.length > 0 ? v : void 0;
523
+ }
524
+
525
+ // src/adapters/pi.ts
526
+ import { mkdir as mkdir4, readFile as readFile4, unlink, writeFile as writeFile4 } from "fs/promises";
527
+ import { homedir as homedir4 } from "os";
528
+ import { dirname as dirname4, join as join4 } from "path";
529
+ var EXTENSION_FILENAME = "agent-insights.ts";
530
+ var HOOK_MAP4 = {
531
+ session_start: "session.start",
532
+ session_shutdown: "session.end",
533
+ tool_call: "tool.start",
534
+ tool_result: "tool.end"
535
+ };
536
+ var PI_HOOK_EVENTS = Object.keys(HOOK_MAP4);
537
+ var EXTENSION_MARKER = "// installed-by: agent-insights";
538
+ function extensionSource() {
539
+ return `${EXTENSION_MARKER}
540
+ // Generated by \`agent-insights init\`. Edit-with-caution: it's overwritten on every install.
541
+
542
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
543
+ import { spawn } from "node:child_process";
544
+
545
+ const EVENTS = ${JSON.stringify(PI_HOOK_EVENTS)} as const;
546
+
547
+ function emit(event: string, payload: Record<string, unknown>): void {
548
+ try {
549
+ const child = spawn("agent-insights", ["hook", event], {
550
+ stdio: ["pipe", "ignore", "ignore"],
551
+ detached: true,
552
+ });
553
+ child.on("error", () => {});
554
+ child.stdin.end(JSON.stringify(payload));
555
+ child.unref();
556
+ } catch {
557
+ // best-effort
558
+ }
559
+ }
560
+
561
+ export default function (pi: ExtensionAPI) {
562
+ for (const event of EVENTS) {
563
+ pi.on(event as never, async (raw: unknown, ctx: { sessionManager?: { getSessionFile?: () => string | undefined; getSessionId?: () => string | undefined } }) => {
564
+ const transcript_path = ctx.sessionManager?.getSessionFile?.();
565
+ const session_id = ctx.sessionManager?.getSessionId?.();
566
+ const e = (raw ?? {}) as Record<string, unknown>;
567
+ emit(event, {
568
+ ...(session_id ? { session_id } : {}),
569
+ ...(transcript_path ? { transcript_path } : {}),
570
+ ...("toolName" in e && typeof e.toolName === "string"
571
+ ? { tool_name: e.toolName }
572
+ : {}),
573
+ ...("reason" in e ? { reason: e.reason } : {}),
574
+ });
575
+ });
576
+ }
577
+ }
578
+ `;
579
+ }
580
+ var piAdapter = {
581
+ id: "pi",
582
+ agent: "pi",
583
+ label: "Pi",
584
+ settingsFile: ".pi/extensions/agent-insights.ts",
585
+ map(payload) {
586
+ const type = HOOK_MAP4[payload.event];
587
+ if (!type) return void 0;
588
+ const data = payload.data ?? {};
589
+ const sessionId = asString4(data["session_id"]) ?? asString4(data["sessionId"]);
590
+ const toolName = asString4(data["tool_name"]) ?? asString4(data["toolName"]);
591
+ const transcriptPath = asString4(data["transcript_path"]) ?? asString4(data["transcriptPath"]);
592
+ return {
593
+ type,
594
+ ...sessionId !== void 0 ? { sessionId } : {},
595
+ ...toolName !== void 0 ? { toolName } : {},
596
+ ...transcriptPath !== void 0 ? { transcriptPath } : {}
597
+ };
598
+ },
599
+ async install(repoRoot, scope = "global") {
600
+ const path = resolvePath(repoRoot, scope);
601
+ await mkdir4(dirname4(path), { recursive: true });
602
+ await writeFile4(path, extensionSource(), "utf8");
603
+ return { written: true, path };
604
+ },
605
+ async uninstall(repoRoot, scope = "global") {
606
+ const path = resolvePath(repoRoot, scope);
607
+ try {
608
+ const raw = await readFile4(path, "utf8");
609
+ if (!raw.includes(EXTENSION_MARKER)) {
610
+ return { removed: false, path };
611
+ }
612
+ await unlink(path);
613
+ return { removed: true, path };
614
+ } catch (err) {
615
+ if (err.code === "ENOENT") {
616
+ return { removed: false, path };
617
+ }
618
+ throw err;
619
+ }
620
+ },
621
+ async isInstalled(repoRoot, scope = "global") {
622
+ const path = resolvePath(repoRoot, scope);
623
+ try {
624
+ const raw = await readFile4(path, "utf8");
625
+ return raw.includes(EXTENSION_MARKER);
626
+ } catch (err) {
627
+ if (err.code === "ENOENT") return false;
628
+ throw err;
629
+ }
630
+ }
631
+ };
632
+ function resolvePath(repoRoot, scope) {
633
+ return scope === "global" ? join4(homedir4(), ".pi", "agent", "extensions", EXTENSION_FILENAME) : join4(repoRoot, ".pi", "extensions", EXTENSION_FILENAME);
634
+ }
635
+ function asString4(v) {
372
636
  return typeof v === "string" && v.length > 0 ? v : void 0;
373
637
  }
374
638
 
375
639
  // src/adapters/registry.ts
376
640
  var adapters = {
377
641
  "claude-code": claudeCodeAdapter,
378
- cursor: cursorAdapter
642
+ cursor: cursorAdapter,
643
+ codex: codexAdapter,
644
+ pi: piAdapter
379
645
  };
380
646
  var adapterList = Object.values(adapters);
381
647
  function getAdapter(id) {
@@ -383,8 +649,8 @@ function getAdapter(id) {
383
649
  }
384
650
 
385
651
  // src/config/config.ts
386
- import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile3 } from "fs/promises";
387
- import { dirname as dirname3 } from "path";
652
+ import { mkdir as mkdir5, readFile as readFile5, writeFile as writeFile5 } from "fs/promises";
653
+ import { dirname as dirname5 } from "path";
388
654
 
389
655
  // src/config/analyzer.ts
390
656
  var DEFAULT_ANALYZER_URL = "https://agent-insights.labs.vercel.dev";
@@ -393,25 +659,25 @@ function getAnalyzerUrl() {
393
659
  }
394
660
 
395
661
  // src/config/paths.ts
396
- import { homedir as homedir3 } from "os";
397
- import { join as join3 } from "path";
662
+ import { homedir as homedir5 } from "os";
663
+ import { join as join5 } from "path";
398
664
  function configRoot() {
399
- return process.env.AGENT_INSIGHTS_HOME ?? join3(homedir3(), ".agent-insights");
665
+ return process.env.AGENT_INSIGHTS_HOME ?? join5(homedir5(), ".agent-insights");
400
666
  }
401
667
  function configFile() {
402
- return join3(configRoot(), "config.json");
668
+ return join5(configRoot(), "config.json");
403
669
  }
404
670
  function authFile() {
405
- return join3(configRoot(), "auth.json");
671
+ return join5(configRoot(), "auth.json");
406
672
  }
407
673
  function bypassSecretFile() {
408
- return join3(configRoot(), "bypass-secret");
674
+ return join5(configRoot(), "bypass-secret");
409
675
  }
410
676
  function sessionCacheDir() {
411
- return join3(configRoot(), "session-cache");
677
+ return join5(configRoot(), "session-cache");
412
678
  }
413
679
  function logsDir() {
414
- return join3(configRoot(), "logs");
680
+ return join5(configRoot(), "logs");
415
681
  }
416
682
 
417
683
  // src/config/config.ts
@@ -448,7 +714,9 @@ function defaultConfig() {
448
714
  },
449
715
  agents: {
450
716
  claudeCode: { enabled: false },
451
- cursor: { enabled: false }
717
+ cursor: { enabled: false },
718
+ codex: { enabled: false },
719
+ pi: { enabled: false }
452
720
  },
453
721
  privacy: {
454
722
  capturePrompts: false,
@@ -460,7 +728,7 @@ function defaultConfig() {
460
728
  }
461
729
  async function loadConfig() {
462
730
  try {
463
- const raw = await readFile3(configFile(), "utf8");
731
+ const raw = await readFile5(configFile(), "utf8");
464
732
  const parsed = JSON.parse(raw);
465
733
  return mergeConfig(defaultConfig(), parsed);
466
734
  } catch (err) {
@@ -470,13 +738,13 @@ async function loadConfig() {
470
738
  }
471
739
  async function saveConfig(cfg) {
472
740
  await ensureDirs();
473
- await writeFile3(configFile(), `${JSON.stringify(cfg, null, 2)}
741
+ await writeFile5(configFile(), `${JSON.stringify(cfg, null, 2)}
474
742
  `, "utf8");
475
743
  }
476
744
  async function ensureDirs() {
477
- await mkdir3(dirname3(configFile()), { recursive: true });
478
- await mkdir3(sessionCacheDir(), { recursive: true });
479
- await mkdir3(logsDir(), { recursive: true });
745
+ await mkdir5(dirname5(configFile()), { recursive: true });
746
+ await mkdir5(sessionCacheDir(), { recursive: true });
747
+ await mkdir5(logsDir(), { recursive: true });
480
748
  }
481
749
  function mergeConfig(base, patch) {
482
750
  return {
@@ -495,20 +763,22 @@ function mergeConfig(base, patch) {
495
763
  ...base.agents.claudeCode,
496
764
  ...patch.agents?.claudeCode ?? {}
497
765
  },
498
- cursor: { ...base.agents.cursor, ...patch.agents?.cursor ?? {} }
766
+ cursor: { ...base.agents.cursor, ...patch.agents?.cursor ?? {} },
767
+ codex: { ...base.agents.codex, ...patch.agents?.codex ?? {} },
768
+ pi: { ...base.agents.pi, ...patch.agents?.pi ?? {} }
499
769
  },
500
770
  privacy: base.privacy
501
771
  };
502
772
  }
503
773
 
504
774
  // src/transcript/store.ts
505
- import { readFile as readFile6 } from "fs/promises";
775
+ import { readFile as readFile8 } from "fs/promises";
506
776
  import { put } from "@vercel/blob";
507
777
 
508
778
  // src/auth/store.ts
509
- import { chmod, readFile as readFile4, writeFile as writeFile4 } from "fs/promises";
510
- import { dirname as dirname4 } from "path";
511
- import { mkdir as mkdir4 } from "fs/promises";
779
+ import { chmod, readFile as readFile6, writeFile as writeFile6 } from "fs/promises";
780
+ import { dirname as dirname6 } from "path";
781
+ import { mkdir as mkdir6 } from "fs/promises";
512
782
 
513
783
  // src/auth/oauth.ts
514
784
  import { createHash as createHash2, randomBytes } from "crypto";
@@ -540,7 +810,7 @@ async function refreshAccessToken(refreshToken) {
540
810
  var REFRESH_BUFFER_MS = 6e4;
541
811
  async function loadAuth() {
542
812
  try {
543
- const raw = await readFile4(authFile(), "utf8");
813
+ const raw = await readFile6(authFile(), "utf8");
544
814
  const parsed = JSON.parse(raw);
545
815
  if (typeof parsed.accessToken === "string" && parsed.accessToken.length > 0) {
546
816
  return parsed;
@@ -553,8 +823,8 @@ async function loadAuth() {
553
823
  }
554
824
  async function saveAuth(state) {
555
825
  const path = authFile();
556
- await mkdir4(dirname4(path), { recursive: true });
557
- await writeFile4(path, `${JSON.stringify(state, null, 2)}
826
+ await mkdir6(dirname6(path), { recursive: true });
827
+ await writeFile6(path, `${JSON.stringify(state, null, 2)}
558
828
  `, {
559
829
  encoding: "utf8",
560
830
  mode: 384
@@ -565,9 +835,9 @@ async function saveAuth(state) {
565
835
  }
566
836
  }
567
837
  async function clearAuth() {
568
- const { unlink: unlink2 } = await import("fs/promises");
838
+ const { unlink: unlink3 } = await import("fs/promises");
569
839
  try {
570
- await unlink2(authFile());
840
+ await unlink3(authFile());
571
841
  } catch (err) {
572
842
  if (err.code !== "ENOENT") throw err;
573
843
  }
@@ -598,13 +868,13 @@ async function getValidToken() {
598
868
  }
599
869
 
600
870
  // src/config/bypass.ts
601
- import { chmod as chmod2, mkdir as mkdir5, readFile as readFile5, unlink, writeFile as writeFile5 } from "fs/promises";
602
- import { dirname as dirname5 } from "path";
871
+ import { chmod as chmod2, mkdir as mkdir7, readFile as readFile7, unlink as unlink2, writeFile as writeFile7 } from "fs/promises";
872
+ import { dirname as dirname7 } from "path";
603
873
  async function loadBypassSecret() {
604
874
  const fromEnv = process.env.AGENT_INSIGHTS_BYPASS_SECRET || process.env.VERCEL_AUTOMATION_BYPASS_SECRET;
605
875
  if (fromEnv) return fromEnv;
606
876
  try {
607
- const raw = (await readFile5(bypassSecretFile(), "utf8")).trim();
877
+ const raw = (await readFile7(bypassSecretFile(), "utf8")).trim();
608
878
  return raw || void 0;
609
879
  } catch (err) {
610
880
  if (err.code === "ENOENT") return void 0;
@@ -636,7 +906,7 @@ var BlobTranscriptStore = class {
636
906
  token;
637
907
  prefix;
638
908
  async upload(input) {
639
- const body = await readFile6(input.transcriptPath);
909
+ const body = await readFile8(input.transcriptPath);
640
910
  const requestedPath = buildPathname(
641
911
  this.prefix,
642
912
  input.userHash,
@@ -667,7 +937,7 @@ var AnalyzerTranscriptStore = class {
667
937
  "transcript store: not logged in \u2014 run `agent-insights login`"
668
938
  );
669
939
  }
670
- const body = await readFile6(input.transcriptPath);
940
+ const body = await readFile8(input.transcriptPath);
671
941
  const url = new URL("/api/sessions/upload", this.analyzerUrl).toString();
672
942
  const headers = await withBypassHeader({
673
943
  authorization: `Bearer ${token}`,