codiedev 0.10.0-beta.5 → 0.10.0-beta.6

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 (44) hide show
  1. package/README.md +4 -4
  2. package/dist/captureSignals.js +2 -0
  3. package/dist/cli.js +38 -50
  4. package/dist/codexHookTrust.js +67 -4
  5. package/dist/codie.js +23 -74
  6. package/dist/codieLauncher.js +18 -22
  7. package/dist/commands/agentTemplates.generated.js +136 -0
  8. package/dist/commands/agents.js +1066 -0
  9. package/dist/commands/agentsSdk.generated.js +7 -0
  10. package/dist/commands/doctor.js +12 -38
  11. package/dist/commands/evals.js +187 -0
  12. package/dist/commands/pack.js +1 -1
  13. package/dist/commands/traces.js +79 -15
  14. package/dist/commands/tracesLabel.js +348 -0
  15. package/dist/connect.js +11 -52
  16. package/dist/copilotHooks.js +0 -4
  17. package/dist/cursorHooks.js +0 -15
  18. package/dist/harnessDirs.js +4 -0
  19. package/dist/hook.js +33 -197
  20. package/dist/limitEventReporter.js +1 -1
  21. package/dist/managedPi.js +240 -0
  22. package/dist/mcp.js +0 -307
  23. package/dist/packs/harnesses.js +40 -3
  24. package/dist/packs/install.js +2 -1
  25. package/dist/piHooks.js +216 -0
  26. package/dist/piRuntime.js +120 -0
  27. package/dist/selfUpdate.js +47 -2
  28. package/dist/utils.js +232 -115
  29. package/package.json +5 -7
  30. package/dist/codieStartup.js +0 -27
  31. package/dist/commands/promote.js +0 -53
  32. package/dist/commands/react.js +0 -38
  33. package/dist/commands/reverseTicket.js +0 -444
  34. package/dist/commands/security.js +0 -156
  35. package/dist/prUrl.js +0 -28
  36. package/dist/security.js +0 -417
  37. package/dist/securityDeepScan.js +0 -235
  38. package/dist/securityDoctor.js +0 -61
  39. package/dist/securityFeature.js +0 -6
  40. package/dist/securityInstall.js +0 -232
  41. package/dist/securityInventory.js +0 -566
  42. package/dist/securityPilot.js +0 -59
  43. package/dist/securityPolicy.js +0 -181
  44. package/dist/securitySession.js +0 -72
package/dist/utils.js CHANGED
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.DIRECT_UPLOAD_THRESHOLD_CHARS = exports.SWEEP_MIN_AGE_MS = exports.CAPTURE_THROTTLE_MS = exports.FINISH_ORPHAN_AGE_MS = exports.CLAIM_STALE_MS = exports.UPLOAD_TTL_MS = exports.MAX_UPLOAD_ATTEMPTS = exports.CONFIG_PATH = exports.codiedevStateDir = void 0;
36
+ exports.DIRECT_UPLOAD_THRESHOLD_CHARS = exports.SWEEP_MIN_AGE_MS = exports.CAPTURE_THROTTLE_MS = exports.FINISH_ORPHAN_AGE_MS = exports.CLAIM_STALE_MS = exports.UPLOAD_TTL_MS = exports.MAX_UPLOAD_ATTEMPTS = exports.PI_EXTENSION_SUBCOMMANDS = exports.CONFIG_PATH = exports.codiedevStateDir = exports.piExtensionPath = exports.inspectPiExtension = void 0;
37
37
  exports.readConfig = readConfig;
38
38
  exports.writeConfig = writeConfig;
39
39
  exports.writeConfigAtPath = writeConfigAtPath;
@@ -64,6 +64,11 @@ exports.cursorInstalled = cursorInstalled;
64
64
  exports.copilotInstalled = copilotInstalled;
65
65
  exports.openCodeInstalled = openCodeInstalled;
66
66
  exports.installOpenCodeCapturePlugin = installOpenCodeCapturePlugin;
67
+ exports.ensureOpenCodePluginCurrent = ensureOpenCodePluginCurrent;
68
+ exports.piInstalled = piInstalled;
69
+ exports.piExtensionSource = piExtensionSource;
70
+ exports.installPiExtension = installPiExtension;
71
+ exports.ensurePiExtensionInstalled = ensurePiExtensionInstalled;
67
72
  exports.vscodeCopilotInstalled = vscodeCopilotInstalled;
68
73
  exports.upsertCodiedevHook = upsertCodiedevHook;
69
74
  exports.removeCodiedevHook = removeCodiedevHook;
@@ -78,8 +83,12 @@ exports.ensureSessionStartHookInstalled = ensureSessionStartHookInstalled;
78
83
  exports.installClaudeCodeInstructions = installClaudeCodeInstructions;
79
84
  exports.installCodexInstructions = installCodexInstructions;
80
85
  exports.copilotInstructionsPath = copilotInstructionsPath;
86
+ exports.piInstructionsPath = piInstructionsPath;
87
+ exports.installPiInstructions = installPiInstructions;
81
88
  exports.installCopilotInstructions = installCopilotInstructions;
82
89
  exports.installCursorInstructions = installCursorInstructions;
90
+ exports.installedInstructionsTargets = installedInstructionsTargets;
91
+ exports.refreshInstalledInstructions = refreshInstalledInstructions;
83
92
  exports.installClaudeCodeMcp = installClaudeCodeMcp;
84
93
  exports.installCursorMcp = installCursorMcp;
85
94
  exports.installVSCodeMcp = installVSCodeMcp;
@@ -139,6 +148,10 @@ const teamSkillContext_1 = require("./teamSkillContext");
139
148
  const nativeSteering_1 = require("./nativeSteering");
140
149
  const copilotHooks_1 = require("./copilotHooks");
141
150
  const harnessDirs_1 = require("./harnessDirs");
151
+ const piHooks_1 = require("./piHooks");
152
+ var piHooks_2 = require("./piHooks");
153
+ Object.defineProperty(exports, "inspectPiExtension", { enumerable: true, get: function () { return piHooks_2.inspectPiExtension; } });
154
+ Object.defineProperty(exports, "piExtensionPath", { enumerable: true, get: function () { return piHooks_2.piExtensionPath; } });
142
155
  const CONFIG_DIR = (0, configDir_1.codiedevStateDir)();
143
156
  exports.CONFIG_PATH = path.join(CONFIG_DIR, "config.json");
144
157
  function readConfig() {
@@ -885,29 +898,21 @@ function openCodeInstalled() {
885
898
  return false;
886
899
  }
887
900
  }
888
- function installOpenCodeCapturePlugin(agentSecurityEnabled = true) {
901
+ function installOpenCodeCapturePlugin() {
889
902
  const start = resolveHookInvocation("session-start-opencode");
890
903
  const capture = resolveHookInvocation("capture-opencode");
891
904
  const finish = resolveHookInvocation("capture-opencode-final");
892
905
  const backup = resolveHookInvocation("backup");
893
906
  const prompt = resolveHookInvocation("discover-codie");
894
- const securityPre = resolveHookInvocation("security-pre-codie");
895
- const securityPost = resolveHookInvocation("security-post-codie");
896
- const securityFailure = resolveHookInvocation("security-failure-codie");
897
907
  const source = `// Managed by codiedev connect. Safe to remove and reinstall.\n` +
898
908
  `import { spawn, spawnSync } from "node:child_process";\n` +
899
909
  `import { mkdirSync, writeFileSync, renameSync } from "node:fs";\n` +
900
910
  `import os from "node:os";\n` +
901
911
  `import path from "node:path";\n\n` +
902
912
  `const START = ${JSON.stringify(start)};\n` +
903
- `const CAPTURE = ${JSON.stringify(capture)};\n` +
904
913
  `const FINISH = ${JSON.stringify(finish)};\n` +
905
914
  `const BACKUP = ${JSON.stringify(backup)};\n` +
906
915
  `const PROMPT = ${JSON.stringify(prompt)};\n` +
907
- `const SECURITY_PRE = ${JSON.stringify(securityPre)};\n` +
908
- `const SECURITY_POST = ${JSON.stringify(securityPost)};\n` +
909
- `const SECURITY_FAILURE = ${JSON.stringify(securityFailure)};\n` +
910
- `const AGENT_SECURITY_ENABLED = ${JSON.stringify(agentSecurityEnabled)};\n` +
911
916
  `// How this Codie process was started (run / serve / tui). OpenCode records\n` +
912
917
  `// nothing about it, so the plugin reads its own argv; see launchContext.ts.\n` +
913
918
  `const LAUNCH = (() => { const sub = process.argv.slice(2).find((a) => ["run", "serve", "acp", "web", "attach"].includes(a)); return sub ? "codie:" + sub : "codie:tui"; })();\n` +
@@ -935,20 +940,6 @@ function installOpenCodeCapturePlugin(agentSecurityEnabled = true) {
935
940
  ` } catch { return null; }\n` +
936
941
  `}\n\n` +
937
942
  `export const CodiedevCapture = async ({ client, directory, worktree }) => {\n` +
938
- ` const enforce = async (invocation, payload) => {\n` +
939
- ` const decision = invokeSync(invocation, payload);\n` +
940
- ` const denied = decision?.decision === "block" || decision?.hookSpecificOutput?.permissionDecision === "deny";\n` +
941
- ` const reason = denied ? (decision?.reason || decision?.hookSpecificOutput?.permissionDecisionReason || "Codie security policy blocked this action") : null;\n` +
942
- ` if (!reason) return decision;\n` +
943
- ` try { await client.tui.showToast({ title: "Codie Security", message: reason, variant: "error", duration: 10000 }); } catch {}\n` +
944
- ` if (process.env.CODIEDEV_SECURITY_BLOCK_OUTPUT === "marker") {\n` +
945
- ` process.stderr.write("__CODIEDEV_SECURITY_BLOCK__" + JSON.stringify({ reason }) + "\\n");\n` +
946
- ` process.exit(1);\n` +
947
- ` } else {\n` +
948
- ` process.stderr.write("\\nCodie Security blocked this action:\\n" + reason + "\\n");\n` +
949
- ` }\n` +
950
- ` throw new Error(reason);\n` +
951
- ` };\n` +
952
943
  ` const resolveCwd = async (id, hint) => {\n` +
953
944
  ` if (typeof hint === "string" && hint && hint !== "/") { sessionDirectories.set(id, hint); return hint; }\n` +
954
945
  ` const remembered = sessionDirectories.get(id);\n` +
@@ -974,7 +965,7 @@ function installOpenCodeCapturePlugin(agentSecurityEnabled = true) {
974
965
  ` const id = input?.sessionID ?? input?.sessionId ?? "unknown";\n` +
975
966
  ` const cwd = await resolveCwd(id);\n` +
976
967
  ` const prompt = Array.isArray(output?.parts) ? output.parts.filter((part) => part?.type === "text").map((part) => part.text || "").join("\\n") : "";\n` +
977
- ` const decision = await enforce(PROMPT, { session_id: id, cwd, prompt });\n` +
968
+ ` const decision = invokeSync(PROMPT, { session_id: id, cwd, prompt });\n` +
978
969
  ` const context = decision?.hookSpecificOutput?.additionalContext;\n` +
979
970
  ` if (context && Array.isArray(output?.parts)) {\n` +
980
971
  ` // Preserve the native part IDs required by current engine schemas.\n` +
@@ -982,19 +973,6 @@ function installOpenCodeCapturePlugin(agentSecurityEnabled = true) {
982
973
  ` if (part) part.text += "\\n\\n" + context;\n` +
983
974
  ` }\n` +
984
975
  ` },\n` +
985
- ` "tool.execute.before": async (input, output) => {\n` +
986
- ` if (!AGENT_SECURITY_ENABLED) return;\n` +
987
- ` const id = input?.sessionID ?? input?.sessionId ?? "unknown";\n` +
988
- ` const cwd = await resolveCwd(id);\n` +
989
- ` await enforce(SECURITY_PRE, { sessionId: id, cwd, toolName: input?.tool ?? "unknown", toolUseId: input?.callID, toolInput: output?.args ?? output });\n` +
990
- ` },\n` +
991
- ` "tool.execute.after": async (input, output) => {\n` +
992
- ` if (!AGENT_SECURITY_ENABLED) return;\n` +
993
- ` const id = input?.sessionID ?? input?.sessionId ?? "unknown";\n` +
994
- ` const cwd = await resolveCwd(id);\n` +
995
- ` const payload = { sessionId: id, cwd, toolName: input?.tool ?? "unknown", toolUseId: input?.callID, toolInput: input?.args, toolResponse: output };\n` +
996
- ` dispatch(output?.error ? SECURITY_FAILURE : SECURITY_POST, payload);\n` +
997
- ` },\n` +
998
976
  ` event: async ({ event }) => {\n` +
999
977
  ` const id = sessionId(event);\n` +
1000
978
  ` if (!id) return;\n` +
@@ -1040,6 +1018,140 @@ function installOpenCodeCapturePlugin(agentSecurityEnabled = true) {
1040
1018
  fs.writeFileSync(OPENCODE_PLUGIN_PATH, source, { encoding: "utf8", mode: 0o600 });
1041
1019
  fs.chmodSync(OPENCODE_PLUGIN_PATH, 0o600);
1042
1020
  }
1021
+ function ensureOpenCodePluginCurrent() {
1022
+ try {
1023
+ if (!fs.existsSync(OPENCODE_PLUGIN_PATH))
1024
+ return;
1025
+ if (!fs.readFileSync(OPENCODE_PLUGIN_PATH, "utf8").includes("SECURITY_PRE"))
1026
+ return;
1027
+ installOpenCodeCapturePlugin();
1028
+ }
1029
+ catch { }
1030
+ }
1031
+ function piInstalled() {
1032
+ if (fs.existsSync((0, harnessDirs_1.piAgentDir)()))
1033
+ return true;
1034
+ try {
1035
+ (0, child_process_1.execSync)(process.platform === "win32" ? "where pi" : "command -v pi", { stdio: ["pipe", "pipe", "pipe"] });
1036
+ return true;
1037
+ }
1038
+ catch {
1039
+ return false;
1040
+ }
1041
+ }
1042
+ exports.PI_EXTENSION_SUBCOMMANDS = [
1043
+ "session-start-pi", "backup-pi", "capture-pi-final", "discover-pi",
1044
+ ];
1045
+ function piExtensionSource() {
1046
+ const [start, backup, finish, prompt] = exports.PI_EXTENSION_SUBCOMMANDS.map((subcommand) => resolveHookInvocation(subcommand));
1047
+ return `// Managed by codiedev connect. Safe to remove; \`codiedev connect\` reinstalls it.\n` +
1048
+ `import { spawn, spawnSync } from "node:child_process";\n\n` +
1049
+ `const START = ${JSON.stringify(start)};\n` +
1050
+ `const FINISH = ${JSON.stringify(finish)};\n` +
1051
+ `const BACKUP = ${JSON.stringify(backup)};\n` +
1052
+ `const PROMPT = ${JSON.stringify(prompt)};\n` +
1053
+ `const CONTEXT_TYPE = ${JSON.stringify(piHooks_1.PI_CONTEXT_CUSTOM_TYPE)};\n` +
1054
+ `const piLaunchFromArgv = ${piHooks_1.piLaunchFromArgv.toString()};\n` +
1055
+ `const LAUNCH = piLaunchFromArgv(process.argv.slice(2));\n\n` +
1056
+ `function dispatch(invocation, payload) {\n` +
1057
+ ` try {\n` +
1058
+ ` const child = spawn(invocation.command, invocation.args, { detached: true, stdio: ["pipe", "ignore", "ignore"] });\n` +
1059
+ ` child.stdin.end(JSON.stringify(payload));\n` +
1060
+ ` child.unref();\n` +
1061
+ ` } catch {}\n` +
1062
+ `}\n\n` +
1063
+ `function dispatchSync(invocation, payload) {\n` +
1064
+ ` try { spawnSync(invocation.command, invocation.args, { input: JSON.stringify(payload), stdio: ["pipe", "ignore", "ignore"], timeout: 1500 }); } catch {}\n` +
1065
+ `}\n\n` +
1066
+ `function invokeSync(invocation, payload) {\n` +
1067
+ ` try {\n` +
1068
+ ` const result = spawnSync(invocation.command, invocation.args, { input: JSON.stringify(payload), encoding: "utf8", stdio: ["pipe", "pipe", "ignore"], timeout: 1500 });\n` +
1069
+ ` if (result.error) return null;\n` +
1070
+ ` return JSON.parse(result.stdout || "{}");\n` +
1071
+ ` } catch { return null; }\n` +
1072
+ `}\n\n` +
1073
+ `export default function codiedev(pi) {\n` +
1074
+ ` let session = null;\n` +
1075
+ ` let pendingContext = null;\n` +
1076
+ ` let finalized = false;\n` +
1077
+ ` const current = (ctx) => {\n` +
1078
+ ` const sm = ctx?.sessionManager;\n` +
1079
+ ` const id = sm?.getSessionId?.() ?? session?.id;\n` +
1080
+ ` const file = sm?.getSessionFile?.() ?? session?.file;\n` +
1081
+ ` const cwd = ctx?.cwd || session?.cwd || process.cwd();\n` +
1082
+ ` session = { id, file, cwd };\n` +
1083
+ ` return session;\n` +
1084
+ ` };\n` +
1085
+ ` const payload = (s, extra) => ({ session_id: s.id, transcript_path: s.file, cwd: s.cwd, workspace_roots: [s.cwd], launch: LAUNCH, ...extra });\n` +
1086
+ ` const finalize = () => {\n` +
1087
+ ` // No file (pi --no-session) still finalizes: the hook reports a skip, so\n` +
1088
+ ` // the start ping is not left open.\n` +
1089
+ ` if (finalized || !session?.id) return;\n` +
1090
+ ` finalized = true;\n` +
1091
+ ` dispatchSync(FINISH, payload(session));\n` +
1092
+ ` };\n` +
1093
+ ` // Print mode can exit without a shutdown event; the session is still over.\n` +
1094
+ ` // pi rebuilds extensions on every /new, /resume and /fork, so register one\n` +
1095
+ ` // exit hook per process and point it at the newest instance.\n` +
1096
+ ` globalThis.__codiedevPiFinalize = finalize;\n` +
1097
+ ` if (!globalThis.__codiedevPiExitHook) {\n` +
1098
+ ` globalThis.__codiedevPiExitHook = true;\n` +
1099
+ ` process.once("exit", () => globalThis.__codiedevPiFinalize?.());\n` +
1100
+ ` }\n\n` +
1101
+ ` pi.on("session_start", async (event, ctx) => {\n` +
1102
+ ` finalized = false;\n` +
1103
+ ` if (event?.reason === "reload") { current(ctx); return; }\n` +
1104
+ ` const s = current(ctx);\n` +
1105
+ ` // pi can announce one new session twice across an extension rebind.\n` +
1106
+ ` if (!s.id || globalThis.__codiedevPiStarted === s.id) return;\n` +
1107
+ ` globalThis.__codiedevPiStarted = s.id;\n` +
1108
+ ` dispatch(START, payload(s));\n` +
1109
+ ` });\n\n` +
1110
+ ` pi.on("input", async (event, ctx) => {\n` +
1111
+ ` if (event?.source === "extension") return { action: "continue" };\n` +
1112
+ ` const s = current(ctx);\n` +
1113
+ ` const decision = invokeSync(PROMPT, { session_id: s.id, cwd: s.cwd, prompt: event?.text ?? "" });\n` +
1114
+ ` pendingContext = decision?.hookSpecificOutput?.additionalContext || null;\n` +
1115
+ ` return { action: "continue" };\n` +
1116
+ ` });\n\n` +
1117
+ ` pi.on("before_agent_start", async () => {\n` +
1118
+ ` if (!pendingContext) return;\n` +
1119
+ ` const content = pendingContext;\n` +
1120
+ ` pendingContext = null;\n` +
1121
+ ` return { message: { customType: CONTEXT_TYPE, content, display: false } };\n` +
1122
+ ` });\n\n` +
1123
+ ` pi.on("agent_end", async (_event, ctx) => {\n` +
1124
+ ` const s = current(ctx);\n` +
1125
+ ` if (!s.id || !s.file) return;\n` +
1126
+ ` // Interim capture + artifact backup, like every harness's Stop hook. pi\n` +
1127
+ ` // retries provider errors itself; agent_end comes after the last try, so\n` +
1128
+ ` // the capture reports a hit limit once per run, not once per retry.\n` +
1129
+ ` dispatch(BACKUP, payload(s));\n` +
1130
+ ` });\n\n` +
1131
+ ` pi.on("session_shutdown", async (event, ctx) => {\n` +
1132
+ ` // A reload keeps the same session running.\n` +
1133
+ ` if (event?.reason === "reload") return;\n` +
1134
+ ` current(ctx);\n` +
1135
+ ` finalize();\n` +
1136
+ ` });\n` +
1137
+ `}\n`;
1138
+ }
1139
+ function installPiExtension() {
1140
+ const target = (0, piHooks_1.piExtensionPath)();
1141
+ fs.mkdirSync(path.dirname(target), { recursive: true, mode: 0o700 });
1142
+ const tmp = `${target}.${process.pid}.tmp`;
1143
+ fs.writeFileSync(tmp, piExtensionSource(), { encoding: "utf8", mode: 0o600 });
1144
+ fs.renameSync(tmp, target);
1145
+ }
1146
+ function ensurePiExtensionInstalled() {
1147
+ try {
1148
+ const file = (0, piHooks_1.piExtensionPath)();
1149
+ if (fs.existsSync(file) && fs.readFileSync(file, "utf8") === piExtensionSource())
1150
+ return;
1151
+ installPiExtension();
1152
+ }
1153
+ catch { }
1154
+ }
1043
1155
  function vscodeCopilotInstalled() {
1044
1156
  if (!fs.existsSync(VSCODE_EXTENSIONS_DIR))
1045
1157
  return false;
@@ -1108,7 +1220,8 @@ function removeCodiedevHook(hooks, eventName) {
1108
1220
  hooks[eventName] = filtered;
1109
1221
  return true;
1110
1222
  }
1111
- function installHook(agentSecurityEnabled = true) {
1223
+ const RETIRED_SECURITY_TOOL_EVENTS = ["PreToolUse", "PostToolUse", "PostToolUseFailure"];
1224
+ function installHook() {
1112
1225
  let settings = {};
1113
1226
  try {
1114
1227
  if (fs.existsSync(CLAUDE_SETTINGS_PATH)) {
@@ -1123,16 +1236,8 @@ function installHook(agentSecurityEnabled = true) {
1123
1236
  }
1124
1237
  const hooks = settings.hooks;
1125
1238
  upsertCodiedevHook(hooks, "SessionEnd", "capture");
1126
- if (agentSecurityEnabled) {
1127
- upsertCodiedevHook(hooks, "PreToolUse", "security-pre");
1128
- upsertCodiedevHook(hooks, "PostToolUse", "security-post");
1129
- upsertCodiedevHook(hooks, "PostToolUseFailure", "security-failure");
1130
- }
1131
- else {
1132
- removeCodiedevHook(hooks, "PreToolUse");
1133
- removeCodiedevHook(hooks, "PostToolUse");
1134
- removeCodiedevHook(hooks, "PostToolUseFailure");
1135
- }
1239
+ for (const eventName of RETIRED_SECURITY_TOOL_EVENTS)
1240
+ removeCodiedevHook(hooks, eventName);
1136
1241
  upsertCodiedevHook(hooks, "UserPromptSubmit", "discover");
1137
1242
  upsertCodiedevHook(hooks, "Stop", "backup");
1138
1243
  upsertCodiedevHook(hooks, "StopFailure", "limit", "rate_limit");
@@ -1202,7 +1307,7 @@ function ensureLimitHookInstalled() {
1202
1307
  }
1203
1308
  catch { }
1204
1309
  }
1205
- function ensureAllCodiedevHooksInstalled(agentSecurityEnabled = readConfig()?.agentSecurityEnabled === true) {
1310
+ function ensureAllCodiedevHooksInstalled() {
1206
1311
  try {
1207
1312
  if (!fs.existsSync(CLAUDE_SETTINGS_PATH))
1208
1313
  return;
@@ -1215,14 +1320,9 @@ function ensureAllCodiedevHooksInstalled(agentSecurityEnabled = readConfig()?.ag
1215
1320
  ["StopFailure", "limit", "rate_limit"],
1216
1321
  ["SessionStart", "session-start"],
1217
1322
  ];
1218
- if (agentSecurityEnabled) {
1219
- wanted.splice(1, 0, ["PreToolUse", "security-pre"], ["PostToolUse", "security-post"], ["PostToolUseFailure", "security-failure"]);
1220
- }
1221
1323
  let changed = false;
1222
- if (!agentSecurityEnabled) {
1223
- for (const eventName of ["PreToolUse", "PostToolUse", "PostToolUseFailure"]) {
1224
- changed = removeCodiedevHook(hooks, eventName) || changed;
1225
- }
1324
+ for (const eventName of RETIRED_SECURITY_TOOL_EVENTS) {
1325
+ changed = removeCodiedevHook(hooks, eventName) || changed;
1226
1326
  }
1227
1327
  const missing = wanted.filter(([eventName]) => !hasCodiedevHook(hooks, eventName));
1228
1328
  if (missing.length === 0 && !changed)
@@ -1240,16 +1340,17 @@ const DIRECT_HOOK_PATH = /codiedev[^"'\s/\\]*[\\/]+dist[\\/]+hook\.js/;
1240
1340
  function hasDirectHookPath(configText) {
1241
1341
  return DIRECT_HOOK_PATH.test(configText);
1242
1342
  }
1243
- function migrateHooksToLauncher(agentSecurityEnabled = readConfig()?.agentSecurityEnabled === true) {
1343
+ function migrateHooksToLauncher() {
1244
1344
  const probe = resolveHookInvocation("session-start");
1245
1345
  if (!(0, launcher_1.usesLauncher)(probe.args[0]))
1246
1346
  return [];
1247
1347
  const targets = [
1248
- ["claude-code", CLAUDE_SETTINGS_PATH, () => installHook(agentSecurityEnabled)],
1249
- ["codex", CODEX_HOOKS_PATH, () => installCodexHook(agentSecurityEnabled)],
1250
- ["cursor", CURSOR_HOOKS_PATH, () => installCursorHook(agentSecurityEnabled)],
1251
- ["copilot", copilotHooksPath(), () => installCopilotHook(agentSecurityEnabled)],
1252
- ["opencode", OPENCODE_PLUGIN_PATH, () => installOpenCodeCapturePlugin(agentSecurityEnabled)],
1348
+ ["claude-code", CLAUDE_SETTINGS_PATH, () => installHook()],
1349
+ ["codex", CODEX_HOOKS_PATH, () => installCodexHook()],
1350
+ ["cursor", CURSOR_HOOKS_PATH, () => installCursorHook()],
1351
+ ["copilot", copilotHooksPath(), () => installCopilotHook()],
1352
+ ["opencode", OPENCODE_PLUGIN_PATH, () => installOpenCodeCapturePlugin()],
1353
+ ["pi", (0, piHooks_1.piExtensionPath)(), () => installPiExtension()],
1253
1354
  ];
1254
1355
  const migrated = [];
1255
1356
  for (const [name, file, install] of targets) {
@@ -1321,15 +1422,20 @@ but does not install a global \`codiedev\` executable.
1321
1422
  | "any messages?" / "check my inbox" / "what did a teammate say?" | \`codiedev inbox\` |
1322
1423
  | "read that reply" / "mark that ping read" | \`codiedev read <ping-id>\` |
1323
1424
  | "note that X is a follow-up" / "remember X" | \`codiedev note "<text>"\` |
1324
- | "promote the extracted spec" | \`codiedev promote <artifact-id>\` |
1325
1425
  | "create a ticket" / "scope this into tickets" / "ticket this for me" | \`codiedev create-ticket [optional-inline-prompt]\` |
1326
1426
  | "share with a teammate" / "give someone access" (no notification) | \`codiedev share <key> <name> [--role read\\|edit]\` |
1327
1427
  | "send this to a teammate" / "ask someone to look at this" | \`codiedev send <key> <name> ["<msg>"]\` |
1328
1428
  | "find something about X" / "has anyone solved Y?" | \`codiedev search "<query>" [--limit N]\` |
1329
1429
  | "why did we…?" / "what does the team know about X?" | \`codiedev ask "<question>"\` (synthesized answer + citations) |
1330
1430
  | "show my library" / "what artifacts exist?" | \`codiedev library [--scope mine\\|shared\\|all] [--kind doc\\|skill]\` |
1331
- | "react 🛠 to that post" / "mark as used" | \`codiedev react <postId> <emoji>\` |
1332
- | "run my agent's test cases" / "check the suite on model Y" | \`codiedev traces cases <agent> [--suite <name>] [--model <id>]\` (writes cases + RUN_CASES.md + results.json; follow it, then \`codiedev traces report <results.json>\`) |
1431
+ | "run my agent's test cases" / "check the dataset on model Y" / "run v2 of the dataset" | \`codiedev traces cases <agent> [--dataset <name> [--version <n>]] [--model <id>]\` (writes cases + RUN_CASES.md + results.json; follow it, then \`codiedev traces report <results.json>\`) |
1432
+ | "how are my agents doing?" / "what's failing this week?" / "show the booking agent's failed runs" / "why did run X fail?" | \`codiedev traces overview\`; \`codiedev traces runs <agent> [--failed] [--flag <issue>] [--days n]\`; \`codiedev traces run <run> --agent <name>\` (add \`--json\` to read the data yourself) |
1433
+ | "add a helpfulness 1–5 score" / "make a review queue for tone" | \`codiedev traces score-kinds add <name> --type number --min 1 --max 5\`; \`codiedev traces queue create <name> --scores <a,b>\` |
1434
+ | "score that run 4 for helpfulness" / "how is my agent scoring?" | \`codiedev traces score <run> <score> <value> [--agent <name>] [--comment <why>]\`; \`codiedev traces scores <agent>\` |
1435
+ | "put this week's failed runs in the review queue" | \`codiedev traces queue list\`; \`codiedev traces queue add <queue> --agent <name> [--failed] [--days n]\` |
1436
+ | "have a judge score 10% of my agent's runs" / "turn off automatic scoring" | \`codiedev traces judge <agent> --on --scores <a,b> --sample 10 [--budget 25]\`; \`--off\`; no flags shows it |
1437
+ | "import these test cases from a CSV" / "add an example to the dataset" / "save the dataset as a version" | \`codiedev traces import <agent> <file> --dataset <name>\`; \`codiedev traces add-example <agent> --dataset <name> --input "…" [--expected "…"]\`; \`codiedev traces save-version <dataset>\`; \`codiedev traces versions <dataset>\` |
1438
+ | "what was the last eval on X?" / "file these eval results" | \`codiedev evals last <subject>\` before starting a related eval; \`codiedev evals report <run.json>\` after each variant runs (scores only — \`codiedev evals help\` for the shape) |
1333
1439
 
1334
1440
  **Just push the file — we'll figure out where it goes.** Every artifact
1335
1441
  is classified into one of two kinds at upload time:
@@ -1413,6 +1519,12 @@ function installCodexInstructions() {
1413
1519
  function copilotInstructionsPath() {
1414
1520
  return path.join((0, copilotHooks_1.copilotHome)(), "copilot-instructions.md");
1415
1521
  }
1522
+ function piInstructionsPath() {
1523
+ return path.join((0, harnessDirs_1.piAgentDir)(), "AGENTS.md");
1524
+ }
1525
+ function installPiInstructions() {
1526
+ writeInstructionsBlock(piInstructionsPath(), `${teamSkillContext_1.TEAM_SKILL_CONTEXT}\n\n${CODIEDEV_INSTRUCTIONS_BODY}`);
1527
+ }
1416
1528
  function installCopilotInstructions() {
1417
1529
  writeInstructionsBlock(copilotInstructionsPath(), `${teamSkillContext_1.TEAM_SKILL_CONTEXT}\n\n${CODIEDEV_INSTRUCTIONS_BODY}`);
1418
1530
  }
@@ -1455,6 +1567,38 @@ function installCursorInstructions() {
1455
1567
  }
1456
1568
  fs.writeFileSync(CURSOR_RULES_PATH, next, "utf8");
1457
1569
  }
1570
+ function installedInstructionsTargets() {
1571
+ const withTeamContext = `${teamSkillContext_1.TEAM_SKILL_CONTEXT}\n\n${CODIEDEV_INSTRUCTIONS_BODY}`;
1572
+ return [
1573
+ { path: CLAUDE_USER_INSTRUCTIONS_PATH, body: CODIEDEV_INSTRUCTIONS_BODY },
1574
+ { path: CODEX_USER_INSTRUCTIONS_PATH, body: CODIEDEV_INSTRUCTIONS_BODY },
1575
+ { path: copilotInstructionsPath(), body: withTeamContext },
1576
+ { path: CURSOR_RULES_PATH, body: withTeamContext },
1577
+ { path: piInstructionsPath(), body: withTeamContext },
1578
+ ];
1579
+ }
1580
+ function refreshInstalledInstructions(targets = installedInstructionsTargets()) {
1581
+ const refreshed = [];
1582
+ for (const target of targets) {
1583
+ try {
1584
+ const existing = fs.readFileSync(target.path, "utf8");
1585
+ const beginIdx = existing.indexOf(CODIEDEV_INSTRUCTIONS_BEGIN);
1586
+ const endIdx = existing.indexOf(CODIEDEV_INSTRUCTIONS_END);
1587
+ if (beginIdx === -1 || endIdx === -1 || endIdx <= beginIdx)
1588
+ continue;
1589
+ const next = existing.slice(0, beginIdx) +
1590
+ `${CODIEDEV_INSTRUCTIONS_BEGIN}\n${target.body}\n${CODIEDEV_INSTRUCTIONS_END}` +
1591
+ existing.slice(endIdx + CODIEDEV_INSTRUCTIONS_END.length);
1592
+ if (next === existing)
1593
+ continue;
1594
+ fs.writeFileSync(target.path, next, "utf8");
1595
+ refreshed.push(target.path);
1596
+ }
1597
+ catch {
1598
+ }
1599
+ }
1600
+ return refreshed;
1601
+ }
1458
1602
  function readMcpConfigSafely(path) {
1459
1603
  if (!fs.existsSync(path))
1460
1604
  return {};
@@ -1595,7 +1739,7 @@ function installCodexMcp() {
1595
1739
  fs.writeFileSync(CODEX_CONFIG_PATH, existing + block, "utf8");
1596
1740
  return true;
1597
1741
  }
1598
- function installCodexHook(agentSecurityEnabled = true) {
1742
+ function installCodexHook() {
1599
1743
  let hooksFile = {};
1600
1744
  try {
1601
1745
  if (fs.existsSync(CODEX_HOOKS_PATH)) {
@@ -1646,16 +1790,8 @@ function installCodexHook(agentSecurityEnabled = true) {
1646
1790
  ],
1647
1791
  });
1648
1792
  hooks.Stop = filtered;
1649
- if (agentSecurityEnabled) {
1650
- upsertCodiedevHook(hooks, "PreToolUse", "security-pre-codex");
1651
- upsertCodiedevHook(hooks, "PostToolUse", "security-post-codex");
1652
- upsertCodiedevHook(hooks, "PostToolUseFailure", "security-failure-codex");
1653
- }
1654
- else {
1655
- removeCodiedevHook(hooks, "PreToolUse");
1656
- removeCodiedevHook(hooks, "PostToolUse");
1657
- removeCodiedevHook(hooks, "PostToolUseFailure");
1658
- }
1793
+ for (const eventName of RETIRED_SECURITY_TOOL_EVENTS)
1794
+ removeCodiedevHook(hooks, eventName);
1659
1795
  upsertCodiedevHook(hooks, "UserPromptSubmit", "discover-codex", null);
1660
1796
  if (!fs.existsSync(CODEX_DIR)) {
1661
1797
  fs.mkdirSync(CODEX_DIR, { recursive: true });
@@ -1679,6 +1815,9 @@ function ensureCodexLimitHookInstalled() {
1679
1815
  return Array.isArray(inner) && inner.some((hook) => typeof hook.command === "string" && hook.command.trim().endsWith(subcommand));
1680
1816
  });
1681
1817
  let changed = false;
1818
+ for (const eventName of RETIRED_SECURITY_TOOL_EVENTS) {
1819
+ changed = removeCodiedevHook(hooks, eventName) || changed;
1820
+ }
1682
1821
  if (!hasCommand(stop, "limit-codex")) {
1683
1822
  stop.unshift({
1684
1823
  hooks: [{ type: "command", command: resolveHookCommand("limit-codex"), timeout: 10 }],
@@ -1702,7 +1841,7 @@ function ensureCodexLimitHookInstalled() {
1702
1841
  catch {
1703
1842
  }
1704
1843
  }
1705
- function installCursorHook(agentSecurityEnabled = true) {
1844
+ function installCursorHook() {
1706
1845
  if (!fs.existsSync(CURSOR_DIR)) {
1707
1846
  fs.mkdirSync(CURSOR_DIR, { recursive: true });
1708
1847
  }
@@ -1743,40 +1882,26 @@ function installCursorHook(agentSecurityEnabled = true) {
1743
1882
  replaceManaged("stop", ["backup-cursor"]);
1744
1883
  replaceManaged("subagentStart", ["observe-cursor"]);
1745
1884
  replaceManaged("subagentStop", ["observe-cursor"]);
1746
- if (agentSecurityEnabled) {
1747
- replaceManaged("beforeSubmitPrompt", ["security-prompt-cursor"]);
1748
- replaceManaged("preToolUse", ["security-pre-cursor"]);
1749
- replaceManaged("postToolUse", ["observe-cursor", "security-post-cursor"]);
1750
- replaceManaged("postToolUseFailure", ["observe-cursor", "security-failure-cursor"]);
1751
- }
1752
- else {
1753
- replaceManaged("beforeSubmitPrompt", []);
1754
- replaceManaged("preToolUse", []);
1755
- replaceManaged("postToolUse", ["observe-cursor"]);
1756
- replaceManaged("postToolUseFailure", ["observe-cursor"]);
1757
- }
1885
+ replaceManaged("beforeSubmitPrompt", []);
1886
+ replaceManaged("preToolUse", []);
1887
+ replaceManaged("postToolUse", ["observe-cursor"]);
1888
+ replaceManaged("postToolUseFailure", ["observe-cursor"]);
1758
1889
  fs.writeFileSync(CURSOR_HOOKS_PATH, JSON.stringify(hooksFile, null, 2), "utf8");
1759
1890
  }
1760
1891
  function copilotHooksPath() {
1761
1892
  return path.join((0, copilotHooks_1.copilotHome)(), "hooks", "codiedev.json");
1762
1893
  }
1763
- function copilotManagedHooks(agentSecurityEnabled) {
1894
+ function copilotManagedHooks() {
1764
1895
  return [
1765
1896
  ["sessionStart", "session-start-copilot", 10],
1766
1897
  ["userPromptSubmitted", "discover-copilot", 10],
1767
1898
  ["agentStop", "backup-copilot", 30],
1768
1899
  ["sessionEnd", "capture-copilot", 30],
1769
1900
  ["errorOccurred", "limit-copilot", 10],
1770
- ...(agentSecurityEnabled
1771
- ? [
1772
- ["preToolUse", "security-pre-copilot", 10],
1773
- ["postToolUse", "security-post-copilot", 10],
1774
- ]
1775
- : []),
1776
1901
  ];
1777
1902
  }
1778
1903
  const COPILOT_EVENTS = ["sessionStart", "userPromptSubmitted", "agentStop", "sessionEnd", "preToolUse", "postToolUse", "errorOccurred"];
1779
- function installCopilotHook(agentSecurityEnabled = false) {
1904
+ function installCopilotHook() {
1780
1905
  const hooksPath = copilotHooksPath();
1781
1906
  let hooksFile = {};
1782
1907
  try {
@@ -1790,7 +1915,7 @@ function installCopilotHook(agentSecurityEnabled = false) {
1790
1915
  }
1791
1916
  hooksFile.version = 1;
1792
1917
  const hooks = (hooksFile.hooks && typeof hooksFile.hooks === "object" ? hooksFile.hooks : {});
1793
- const managed = copilotManagedHooks(agentSecurityEnabled);
1918
+ const managed = copilotManagedHooks();
1794
1919
  for (const eventName of COPILOT_EVENTS) {
1795
1920
  const existing = Array.isArray(hooks[eventName]) ? hooks[eventName] : [];
1796
1921
  const preserved = existing.filter((hook) => !(0, detection_1.isCodiedevHookCommand)((hook.bash ?? hook.powershell ?? hook.command)));
@@ -1809,7 +1934,7 @@ function installCopilotHook(agentSecurityEnabled = false) {
1809
1934
  fs.mkdirSync(path.dirname(hooksPath), { recursive: true });
1810
1935
  fs.writeFileSync(hooksPath, JSON.stringify(hooksFile, null, 2), "utf8");
1811
1936
  }
1812
- function ensureCopilotCodiedevHooksInstalled(agentSecurityEnabled = readConfig()?.agentSecurityEnabled === true) {
1937
+ function ensureCopilotCodiedevHooksInstalled() {
1813
1938
  try {
1814
1939
  const hooksPath = copilotHooksPath();
1815
1940
  if (!fs.existsSync(hooksPath))
@@ -1819,17 +1944,17 @@ function ensureCopilotCodiedevHooksInstalled(agentSecurityEnabled = readConfig()
1819
1944
  const commandsFor = (eventName) => (Array.isArray(hooks[eventName]) ? hooks[eventName] : [])
1820
1945
  .map((entry) => (entry.bash ?? entry.powershell ?? entry.command))
1821
1946
  .filter((command) => typeof command === "string" && (0, detection_1.isCodiedevHookCommand)(command));
1822
- const required = copilotManagedHooks(agentSecurityEnabled);
1947
+ const required = copilotManagedHooks();
1823
1948
  const complete = required.every(([eventName, subcommand]) => commandsFor(eventName).filter((command) => command.trim().endsWith(subcommand)).length === 1);
1824
1949
  const stale = COPILOT_EVENTS.some((eventName) => commandsFor(eventName).length !== required.filter(([event]) => event === eventName).length);
1825
1950
  if (complete && !stale)
1826
1951
  return;
1827
- installCopilotHook(agentSecurityEnabled);
1952
+ installCopilotHook();
1828
1953
  }
1829
1954
  catch {
1830
1955
  }
1831
1956
  }
1832
- function ensureCursorCodiedevHooksInstalled(agentSecurityEnabled = readConfig()?.agentSecurityEnabled === true) {
1957
+ function ensureCursorCodiedevHooksInstalled() {
1833
1958
  try {
1834
1959
  if (!fs.existsSync(CURSOR_HOOKS_PATH))
1835
1960
  return;
@@ -1852,16 +1977,8 @@ function ensureCursorCodiedevHooksInstalled(agentSecurityEnabled = readConfig()?
1852
1977
  ["postToolUseFailure", "observe-cursor"],
1853
1978
  ["subagentStart", "observe-cursor"],
1854
1979
  ["subagentStop", "observe-cursor"],
1855
- ...(agentSecurityEnabled
1856
- ? [
1857
- ["beforeSubmitPrompt", "security-prompt-cursor"],
1858
- ["preToolUse", "security-pre-cursor"],
1859
- ["postToolUse", "security-post-cursor"],
1860
- ["postToolUseFailure", "security-failure-cursor"],
1861
- ]
1862
- : []),
1863
1980
  ];
1864
- const hasStaleSecurity = !agentSecurityEnabled && [
1981
+ const hasStaleSecurity = [
1865
1982
  "beforeSubmitPrompt", "preToolUse", "postToolUse", "postToolUseFailure",
1866
1983
  ].some((eventName) => {
1867
1984
  const entries = hooks[eventName];
@@ -1871,7 +1988,7 @@ function ensureCursorCodiedevHooksInstalled(agentSecurityEnabled = readConfig()?
1871
1988
  if (required.every(([eventName, subcommand]) => has(eventName, subcommand)) && !hasStaleSecurity) {
1872
1989
  return;
1873
1990
  }
1874
- installCursorHook(agentSecurityEnabled);
1991
+ installCursorHook();
1875
1992
  }
1876
1993
  catch {
1877
1994
  }
@@ -2360,9 +2477,9 @@ function sweepPendingCaptures(deps) {
2360
2477
  exports.CAPTURE_THROTTLE_MS = 10 * 60 * 1000;
2361
2478
  exports.SWEEP_MIN_AGE_MS = exports.CAPTURE_THROTTLE_MS + 2 * 60 * 1000;
2362
2479
  function resolveCaptureFinal(argv2) {
2363
- if (argv2 === "capture-opencode" || argv2 === "capture-desktop")
2480
+ if (argv2 === "capture-opencode" || argv2 === "capture-desktop" || argv2 === "capture-pi")
2364
2481
  return false;
2365
- if (argv2 === "capture-opencode-final" || argv2 === "capture-desktop-final")
2482
+ if (argv2 === "capture-opencode-final" || argv2 === "capture-desktop-final" || argv2 === "capture-pi-final")
2366
2483
  return true;
2367
2484
  return argv2 === "capture" || argv2 === "capture-cursor" || argv2 === "capture-copilot" || argv2 === undefined
2368
2485
  ? true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codiedev",
3
- "version": "0.10.0-beta.5",
3
+ "version": "0.10.0-beta.6",
4
4
  "description": "Connect Claude Code, Codex, Cursor, OpenCode, or VS Code Copilot to Codiedev for team session capture and artifact collaboration \u2014 and run the governed Codie harness",
5
5
  "bin": {
6
6
  "codiedev": "dist/cli.js",
@@ -12,14 +12,12 @@
12
12
  "dev": "tsc --watch",
13
13
  "prepublishOnly": "tsc",
14
14
  "test": "vitest run",
15
- "test:functional": "vitest run src/__tests__/limitEvent.functional.test.ts src/__tests__/harnessParity.functional.test.ts src/__tests__/cursorParity.functional.test.ts src/__tests__/copilotCapture.functional.test.ts",
16
- "test:harness-parity": "vitest run src/__tests__/harnessParity.functional.test.ts src/__tests__/cursorParity.functional.test.ts src/__tests__/copilotCapture.functional.test.ts",
15
+ "test:functional": "vitest run src/__tests__/limitEvent.functional.test.ts src/__tests__/harnessParity.functional.test.ts src/__tests__/cursorParity.functional.test.ts src/__tests__/copilotCapture.functional.test.ts src/__tests__/piCapture.functional.test.ts",
16
+ "test:harness-parity": "vitest run src/__tests__/harnessParity.functional.test.ts src/__tests__/cursorParity.functional.test.ts src/__tests__/copilotCapture.functional.test.ts src/__tests__/piCapture.functional.test.ts",
17
17
  "test:harness-binaries": "node scripts/checkHarnessBinaries.mjs",
18
- "test:security-beta": "vitest run src/__tests__/security.test.ts src/__tests__/securityCommandEntitlement.test.ts src/__tests__/securityDeepScan.test.ts src/__tests__/securityDoctor.test.ts src/__tests__/securityEntitlementInstall.test.ts src/__tests__/securityFeature.test.ts src/__tests__/securityInstall.test.ts src/__tests__/securityInventory.test.ts src/__tests__/securityPilot.test.ts src/__tests__/securityPolicy.test.ts src/__tests__/securitySession.test.ts src/__tests__/codexHookTrust.test.ts src/__tests__/codieSecurityAdapterWiring.test.ts src/__tests__/limitEvent.functional.test.ts && tsc && node dist/cli.js security pilot --json",
19
- "test:security-pilot": "vitest run src/__tests__/security.test.ts src/__tests__/securityInstall.test.ts src/__tests__/securityPilot.test.ts src/__tests__/codieSecurityAdapterWiring.test.ts && tsc && node dist/cli.js security pilot --json",
20
18
  "test:opencode-attribution": "vitest run src/__tests__/repoResolver.test.ts src/__tests__/openCodeCapture.test.ts src/__tests__/openCodePluginGitRefs.test.ts src/__tests__/capturePayloadFinal.test.ts src/__tests__/captureDirectUpload.test.ts src/__tests__/resolveCaptureFinal.test.ts && tsc",
21
19
  "test:watch": "vitest",
22
- "test:metadata-parity": "vitest run src/__tests__/sourceMetadataMatrix.test.ts src/__tests__/copilotCapture.functional.test.ts src/__tests__/copilotCapture.test.ts src/__tests__/cursorParity.functional.test.ts src/__tests__/nativeSourceParity.test.ts src/__tests__/harnessParity.functional.test.ts src/__tests__/subagents.test.ts src/__tests__/transcriptModels.test.ts src/__tests__/captureRetry.test.ts src/__tests__/limitEvent.functional.test.ts src/__tests__/captureExclusions.test.ts"
20
+ "test:metadata-parity": "vitest run src/__tests__/sourceMetadataMatrix.test.ts src/__tests__/copilotCapture.functional.test.ts src/__tests__/copilotCapture.test.ts src/__tests__/piCapture.functional.test.ts src/__tests__/piHooks.test.ts src/__tests__/cursorParity.functional.test.ts src/__tests__/nativeSourceParity.test.ts src/__tests__/harnessParity.functional.test.ts src/__tests__/subagents.test.ts src/__tests__/transcriptModels.test.ts src/__tests__/captureRetry.test.ts src/__tests__/limitEvent.functional.test.ts src/__tests__/captureExclusions.test.ts"
23
21
  },
24
22
  "files": [
25
23
  "dist",
@@ -64,7 +62,7 @@
64
62
  "@modelcontextprotocol/sdk": "^1.30.0"
65
63
  },
66
64
  "overrides": {
67
- "@hono/node-server": "^2.0.12",
65
+ "@hono/node-server": "^2.1.5",
68
66
  "ip-address": "^10.7.4",
69
67
  "esbuild": "^0.28.1"
70
68
  }