@ironbee-ai/cli 0.30.0 → 0.31.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 (84) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/dist/analytics/claude/emit.js +1 -1
  3. package/dist/analytics/claude/state.js +1 -1
  4. package/dist/analytics/codex/events-emit.js +2 -2
  5. package/dist/analytics/codex/subagent-transcripts.js +3 -3
  6. package/dist/clients/claude/hooks/activity-end.js +1 -1
  7. package/dist/clients/claude/hooks/activity-start.js +1 -1
  8. package/dist/clients/claude/hooks/clear-verdict.js +1 -1
  9. package/dist/clients/claude/hooks/require-verdict.js +2 -2
  10. package/dist/clients/claude/hooks/require-verification.js +3 -3
  11. package/dist/clients/claude/hooks/session-end.js +1 -1
  12. package/dist/clients/claude/hooks/session-start.js +4 -4
  13. package/dist/clients/claude/hooks/session-status.js +2 -2
  14. package/dist/clients/claude/hooks/subagent-start.js +1 -1
  15. package/dist/clients/claude/hooks/subagent-stop.js +1 -1
  16. package/dist/clients/claude/hooks/track-action-monitor.js +1 -1
  17. package/dist/clients/claude/hooks/track-action.js +1 -1
  18. package/dist/clients/claude/hooks/verify-gate.js +4 -4
  19. package/dist/clients/claude/platforms/scenario.android.md +1 -0
  20. package/dist/clients/claude/platforms/skill.android.md +4 -0
  21. package/dist/clients/claude/process-analytics.js +1 -1
  22. package/dist/clients/claude/statusline-toggle.js +2 -2
  23. package/dist/clients/codex/hooks/activity-end.js +1 -1
  24. package/dist/clients/codex/hooks/activity-start.js +1 -1
  25. package/dist/clients/codex/hooks/clear-verdict.js +3 -3
  26. package/dist/clients/codex/hooks/require-verdict.js +2 -2
  27. package/dist/clients/codex/hooks/require-verification.js +3 -3
  28. package/dist/clients/codex/hooks/session-start.js +3 -3
  29. package/dist/clients/codex/hooks/subagent-start.js +1 -1
  30. package/dist/clients/codex/hooks/subagent-stop.js +1 -1
  31. package/dist/clients/codex/hooks/track-action-monitor.js +1 -1
  32. package/dist/clients/codex/hooks/track-action-pre.js +1 -1
  33. package/dist/clients/codex/hooks/track-action.js +1 -1
  34. package/dist/clients/codex/hooks/verify-gate.js +1 -1
  35. package/dist/clients/codex/index.js +2 -2
  36. package/dist/clients/codex/platforms/command-verify.android.md +1 -0
  37. package/dist/clients/codex/platforms/rule.android.md +2 -1
  38. package/dist/clients/codex/platforms/scenario.android.md +1 -0
  39. package/dist/clients/codex/platforms/skill.android.md +4 -0
  40. package/dist/clients/codex/process-analytics.js +2 -2
  41. package/dist/clients/codex/thread-map.js +1 -1
  42. package/dist/clients/codex/util.js +44 -31
  43. package/dist/clients/cursor/hooks/activity-end.js +1 -1
  44. package/dist/clients/cursor/hooks/activity-start.js +1 -1
  45. package/dist/clients/cursor/hooks/clear-verdict.js +1 -1
  46. package/dist/clients/cursor/hooks/require-verdict.js +2 -2
  47. package/dist/clients/cursor/hooks/require-verification.js +3 -3
  48. package/dist/clients/cursor/hooks/session-end.js +1 -1
  49. package/dist/clients/cursor/hooks/session-start.js +4 -4
  50. package/dist/clients/cursor/hooks/track-action-monitor.js +1 -1
  51. package/dist/clients/cursor/hooks/track-action.js +1 -1
  52. package/dist/clients/cursor/hooks/verify-gate.js +1 -1
  53. package/dist/clients/cursor/platforms/command-verify.android.md +1 -0
  54. package/dist/clients/cursor/platforms/rule.android.md +2 -1
  55. package/dist/clients/cursor/platforms/scenario.android.md +1 -0
  56. package/dist/clients/cursor/platforms/skill.android.md +4 -0
  57. package/dist/commands/config.js +1 -1
  58. package/dist/commands/hook.js +10 -10
  59. package/dist/commands/import.js +3 -3
  60. package/dist/commands/process-job-file.js +1 -1
  61. package/dist/commands/queue.js +16 -16
  62. package/dist/commands/status.js +1 -1
  63. package/dist/commands/uninstall.js +1 -1
  64. package/dist/commands/verify.js +2 -2
  65. package/dist/hooks/core/actions.js +7 -7
  66. package/dist/hooks/core/session-state.js +1 -1
  67. package/dist/hooks/core/verification-context.js +8 -8
  68. package/dist/import/marker.js +2 -2
  69. package/dist/import/skip.js +1 -1
  70. package/dist/lib/config.js +1 -1
  71. package/dist/lib/install-version.js +1 -1
  72. package/dist/lib/runtime-paths.js +1 -0
  73. package/dist/otel/claude/daemon/process.js +1 -1
  74. package/dist/otel/claude/daemon/reprocess.js +1 -1
  75. package/dist/otel/claude/daemon/response-usage.js +2 -2
  76. package/dist/queue/drain.js +1 -1
  77. package/dist/queue/flush.js +1 -1
  78. package/dist/queue/paths.js +1 -1
  79. package/dist/queue/process-file.js +2 -2
  80. package/dist/queue/spawn.js +1 -1
  81. package/dist/tui/config/schema.js +1 -1
  82. package/dist/tui/queue/read.js +4 -4
  83. package/dist/tui/sessions/read.js +2 -2
  84. package/package.json +1 -1
@@ -1 +1 @@
1
- "use strict";var t=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var m=(e,s)=>{for(var n in s)t(e,n,{get:s[n],enumerable:!0})},l=(e,s,n,o)=>{if(s&&typeof s=="object"||typeof s=="function")for(let r of p(s))!u.call(e,r)&&r!==n&&t(e,r,{get:()=>s[r],enumerable:!(o=g(s,r))||o.enumerable});return e};var y=e=>l(t({},"__esModule",{value:!0}),e);var S={};m(S,{claudeProcessAnalyticsCommand:()=>f});module.exports=y(S);var c=require("commander"),i=require("../../lib/logger"),a=require("../../analytics/claude/emit"),d=require("../../analytics/claude/log");const f=new c.Command("process-analytics").description("Internal worker \u2014 project + emit a session_analytics snapshot for one Claude trigger").requiredOption("--project <dir>","project directory (where .ironbee/sessions/<sid>/ lives)").requiredOption("--session <id>","session id").requiredOption("--trigger <type>","Stop | SessionEnd").option("--end-reason <reason>","SessionEnd reason (optional)").option("--transcript-source <src>","claude-code | cursor | missing").action(async e=>{const s=e.trigger==="SessionEnd"?"SessionEnd":"Stop",n=e.transcriptSource??"claude-code";(0,i.setLogFile)(`${e.project}/.ironbee/sessions/${e.session}/session.log`);const o=new d.AnalyticsLog(e.project,e.session);o.info(`worker: claude process-analytics start (trigger=${s} session=${e.session}${e.endReason?` end_reason=${e.endReason}`:""})`);try{const r=await(0,a.emitAnalytics)({projectDir:e.project,sessionId:e.session,triggerType:s,endReason:e.endReason,transcriptSource:n,log:o});o.info(`worker: claude process-analytics done (status=${r.status} reason=${r.reason})`)}catch(r){i.logger.debug(`claude process-analytics: unexpected error: ${r instanceof Error?r.message:r}`),o.error(`worker: unexpected error: ${r instanceof Error?r.message:r}`)}});0&&(module.exports={claudeProcessAnalyticsCommand});
1
+ "use strict";var t=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var l=(e,s)=>{for(var n in s)t(e,n,{get:s[n],enumerable:!0})},y=(e,s,n,o)=>{if(s&&typeof s=="object"||typeof s=="function")for(let r of m(s))!u.call(e,r)&&r!==n&&t(e,r,{get:()=>s[r],enumerable:!(o=g(s,r))||o.enumerable});return e};var f=e=>y(t({},"__esModule",{value:!0}),e);var w={};l(w,{claudeProcessAnalyticsCommand:()=>S});module.exports=f(w);var c=require("commander"),i=require("../../lib/logger"),a=require("../../analytics/claude/emit"),d=require("../../analytics/claude/log"),p=require("../../lib/runtime-paths");const S=new c.Command("process-analytics").description("Internal worker \u2014 project + emit a session_analytics snapshot for one Claude trigger").requiredOption("--project <dir>","project directory (where .ironbee/sessions/<sid>/ lives)").requiredOption("--session <id>","session id").requiredOption("--trigger <type>","Stop | SessionEnd").option("--end-reason <reason>","SessionEnd reason (optional)").option("--transcript-source <src>","claude-code | cursor | missing").action(async e=>{const s=e.trigger==="SessionEnd"?"SessionEnd":"Stop",n=e.transcriptSource??"claude-code";(0,i.setLogFile)((0,p.sessionLogFile)(e.project,e.session));const o=new d.AnalyticsLog(e.project,e.session);o.info(`worker: claude process-analytics start (trigger=${s} session=${e.session}${e.endReason?` end_reason=${e.endReason}`:""})`);try{const r=await(0,a.emitAnalytics)({projectDir:e.project,sessionId:e.session,triggerType:s,endReason:e.endReason,transcriptSource:n,log:o});o.info(`worker: claude process-analytics done (status=${r.status} reason=${r.reason})`)}catch(r){i.logger.debug(`claude process-analytics: unexpected error: ${r instanceof Error?r.message:r}`),o.error(`worker: unexpected error: ${r instanceof Error?r.message:r}`)}});0&&(module.exports={claudeProcessAnalyticsCommand});
@@ -1,2 +1,2 @@
1
- "use strict";var d=Object.defineProperty;var L=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var k=Object.prototype.hasOwnProperty;var u=(e,n)=>d(e,"name",{value:n,configurable:!0});var x=(e,n)=>{for(var t in n)d(e,t,{get:n[t],enumerable:!0})},E=(e,n,t,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let o of T(n))!k.call(e,o)&&o!==t&&d(e,o,{get:()=>n[o],enumerable:!(r=L(n,o))||r.enumerable});return e};var F=e=>E(d({},"__esModule",{value:!0}),e);var R={};x(R,{applyStatusLineToggle:()=>O,syncChainedStatusLine:()=>P});module.exports=F(R);var i=require("fs"),c=require("path"),S=require("../registry"),$=require("./hooks/session-status"),s=require("../../lib/config"),y=require("../../lib/gitignore"),C=require("../../lib/logger"),f=require("../../lib/output"),m=require("../../hooks/core/session-state");function N(e){if(!(0,i.existsSync)(e))return{};try{return JSON.parse((0,i.readFileSync)(e,"utf-8"))}catch(n){throw C.logger.debug(`failed to read ${e}: ${n}`),new Error(`Config at ${e} is not valid JSON: ${n instanceof Error?n.message:n}`)}}u(N,"readConfigFile");function J(e,n){(0,i.mkdirSync)((0,c.join)(e,".."),{recursive:!0}),(0,i.writeFileSync)(e,JSON.stringify(n,null,2)+`
2
- `)}u(J,"writeConfigFile");function O(e,n,t,r){const o=(0,s.getTargetConfigPath)(t,n),a=N(o),g=e?"enabled":"disabled",l=(0,s.loadConfig)(n);l.statusLine={...l.statusLine,enable:e};const b=(0,s.isSessionStatusEnabled)((0,s.loadConfig)(n)),w=(0,s.isSessionStatusEnabled)(l);if(b===w&&a.statusLine?.enable===e){console.log(`${f.pc.dim("\xB7")} Statusline already ${g} in ${t} config (${f.pc.dim(o)}). No-op.`);return}const h=(0,S.resolveTargetClients)(n,r);for(const B of h)B.install(n,l);t!=="global"&&(0,y.ensureIronBeeGitignored)(n);const p={...a,statusLine:{...a.statusLine,enable:e}};J(o,p);const v=e?"Enabled":"Disabled",I=e?"The statusline wrapper now emits session_status events and chains your existing statusline.":"Your original statusline is restored; no session_status events are emitted.";console.log(`${f.pc.green("\u2713")} ${v} statusline in ${t} config (${f.pc.dim(o)}).`),console.log(` ${f.pc.dim(I)}`),console.log(` ${f.pc.yellow("\u26A0")} Restart your editor / agent session for the change to take effect.`)}u(O,"applyStatusLineToggle");function P(e){const n=(0,$.resolveChainTarget)(e)??null,t=(0,c.join)(e,".ironbee","sessions");if(!(0,i.existsSync)(t))return 0;let r=0,o;try{o=(0,i.readdirSync)(t)}catch(a){return C.logger.debug(`statusline sync: failed to list ${t}: ${a}`),0}for(const a of o){const g=(0,c.join)(t,a);!(0,i.existsSync)((0,c.join)(g,"state.json"))||(0,m.readState)(g).chainedStatusLine===n||((0,m.setChainedStatusLine)(g,n),r++)}return r}u(P,"syncChainedStatusLine");0&&(module.exports={applyStatusLineToggle,syncChainedStatusLine});
1
+ "use strict";var c=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var x=Object.prototype.hasOwnProperty;var u=(e,n)=>c(e,"name",{value:n,configurable:!0});var E=(e,n)=>{for(var o in n)c(e,o,{get:n[o],enumerable:!0})},F=(e,n,o,r)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of k(n))!x.call(e,t)&&t!==o&&c(e,t,{get:()=>n[t],enumerable:!(r=T(n,t))||r.enumerable});return e};var N=e=>F(c({},"__esModule",{value:!0}),e);var _={};E(_,{applyStatusLineToggle:()=>O,syncChainedStatusLine:()=>P});module.exports=N(_);var i=require("fs"),d=require("path"),S=require("../registry"),$=require("./hooks/session-status"),y=require("../../lib/runtime-paths"),s=require("../../lib/config"),b=require("../../lib/gitignore"),C=require("../../lib/logger"),f=require("../../lib/output"),m=require("../../hooks/core/session-state");function R(e){if(!(0,i.existsSync)(e))return{};try{return JSON.parse((0,i.readFileSync)(e,"utf-8"))}catch(n){throw C.logger.debug(`failed to read ${e}: ${n}`),new Error(`Config at ${e} is not valid JSON: ${n instanceof Error?n.message:n}`)}}u(R,"readConfigFile");function J(e,n){(0,i.mkdirSync)((0,d.join)(e,".."),{recursive:!0}),(0,i.writeFileSync)(e,JSON.stringify(n,null,2)+`
2
+ `)}u(J,"writeConfigFile");function O(e,n,o,r){const t=(0,s.getTargetConfigPath)(o,n),a=R(t),g=e?"enabled":"disabled",l=(0,s.loadConfig)(n);l.statusLine={...l.statusLine,enable:e};const p=(0,s.isSessionStatusEnabled)((0,s.loadConfig)(n)),v=(0,s.isSessionStatusEnabled)(l);if(p===v&&a.statusLine?.enable===e){console.log(`${f.pc.dim("\xB7")} Statusline already ${g} in ${o} config (${f.pc.dim(t)}). No-op.`);return}const w=(0,S.resolveTargetClients)(n,r);for(const L of w)L.install(n,l);o!=="global"&&(0,b.ensureIronBeeGitignored)(n);const h={...a,statusLine:{...a.statusLine,enable:e}};J(t,h);const I=e?"Enabled":"Disabled",B=e?"The statusline wrapper now emits session_status events and chains your existing statusline.":"Your original statusline is restored; no session_status events are emitted.";console.log(`${f.pc.green("\u2713")} ${I} statusline in ${o} config (${f.pc.dim(t)}).`),console.log(` ${f.pc.dim(B)}`),console.log(` ${f.pc.yellow("\u26A0")} Restart your editor / agent session for the change to take effect.`)}u(O,"applyStatusLineToggle");function P(e){const n=(0,$.resolveChainTarget)(e)??null,o=(0,y.sessionsRoot)(e);if(!(0,i.existsSync)(o))return 0;let r=0,t;try{t=(0,i.readdirSync)(o)}catch(a){return C.logger.debug(`statusline sync: failed to list ${o}: ${a}`),0}for(const a of t){const g=(0,d.join)(o,a);!(0,i.existsSync)((0,d.join)(g,"state.json"))||(0,m.readState)(g).chainedStatusLine===n||((0,m.setChainedStatusLine)(g,n),r++)}return r}u(P,"syncChainedStatusLine");0&&(module.exports={applyStatusLineToggle,syncChainedStatusLine});
@@ -1 +1 @@
1
- "use strict";var d=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var w=Object.prototype.hasOwnProperty;var p=(i,t)=>d(i,"name",{value:t,configurable:!0});var E=(i,t)=>{for(var n in t)d(i,n,{get:t[n],enumerable:!0})},b=(i,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of A(t))!w.call(i,e)&&e!==n&&d(i,e,{get:()=>t[e],enumerable:!(o=v(t,e))||o.enumerable});return i};var h=i=>b(d({},"__esModule",{value:!0}),i);var x={};E(x,{run:()=>k});module.exports=h(x);var a=require("../../../hooks/core/actions"),m=require("../../../hooks/core/activity-end"),r=require("../../../lib/logger"),u=require("../../../lib/output"),f=require("../../../lib/stdin"),l=require("../../../analytics/codex/spawn"),c=require("../../../hooks/core/session-state"),y=require("../util");async function k(i){const t=(0,y.parseCodexHookStdin)((0,f.readStdin)()),n=t.session_id??"default",o=`${i}/.ironbee/sessions/${n}`,e=`${o}/actions.jsonl`;(0,r.setLogFile)(`${o}/session.log`);const g=(0,c.readState)(o)?.activeActivityId??"";if(await(0,m.runActivityEnd)({sessionDir:o,actionsFile:e,projectDir:i,sessionId:n})){const s=Date.now(),S={...(0,a.baseFields)(e),id:(0,a.deterministicSessionEndId)(n),type:"session_end",timestamp:s,session_id:n,duration:(0,a.findDurationSinceLastAction)(e,"session_start",s),reason:"checkpoint"};await(0,a.appendAction)(e,S)}try{const s=(0,c.readState)(o);(0,l.spawnDetachedCodexAnalyticsWorker)({projectDir:i,sessionId:n,rolloutPath:t.transcript_path,userEmail:s?.userEmail??void 0,usageType:s?.usageType??void 0,usagePlan:s?.usagePlan??void 0,activityId:g})}catch(s){r.logger.debug(`codex analytics spawn failed: ${s instanceof Error?s.message:s}`)}r.logger.debug(`activity-end: ${n}`),(0,u.writeAndExit)(JSON.stringify({}),0)}p(k,"run");0&&(module.exports={run});
1
+ "use strict";var d=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var w=Object.getOwnPropertyNames;var E=Object.prototype.hasOwnProperty;var p=(i,t)=>d(i,"name",{value:t,configurable:!0});var h=(i,t)=>{for(var n in t)d(i,n,{get:t[n],enumerable:!0})},k=(i,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of w(t))!E.call(i,e)&&e!==n&&d(i,e,{get:()=>t[e],enumerable:!(o=A(t,e))||o.enumerable});return i};var x=i=>k(d({},"__esModule",{value:!0}),i);var C={};h(C,{run:()=>b});module.exports=x(C);var r=require("../../../hooks/core/actions"),m=require("../../../hooks/core/activity-end"),a=require("../../../lib/logger"),u=require("../../../lib/output"),f=require("../../../lib/stdin"),l=require("../../../analytics/codex/spawn"),c=require("../../../hooks/core/session-state"),y=require("../util"),g=require("../../../lib/runtime-paths");async function b(i){const t=(0,y.parseCodexHookStdin)((0,f.readStdin)()),n=t.session_id??"default",o=(0,g.sessionDir)(i,n),e=`${o}/actions.jsonl`;(0,a.setLogFile)(`${o}/session.log`);const S=(0,c.readState)(o)?.activeActivityId??"";if(await(0,m.runActivityEnd)({sessionDir:o,actionsFile:e,projectDir:i,sessionId:n})){const s=Date.now(),v={...(0,r.baseFields)(e),id:(0,r.deterministicSessionEndId)(n),type:"session_end",timestamp:s,session_id:n,duration:(0,r.findDurationSinceLastAction)(e,"session_start",s),reason:"checkpoint"};await(0,r.appendAction)(e,v)}try{const s=(0,c.readState)(o);(0,l.spawnDetachedCodexAnalyticsWorker)({projectDir:i,sessionId:n,rolloutPath:t.transcript_path,userEmail:s?.userEmail??void 0,usageType:s?.usageType??void 0,usagePlan:s?.usagePlan??void 0,activityId:S})}catch(s){a.logger.debug(`codex analytics spawn failed: ${s instanceof Error?s.message:s}`)}a.logger.debug(`activity-end: ${n}`),(0,u.writeAndExit)(JSON.stringify({}),0)}p(b,"run");0&&(module.exports={run});
@@ -1 +1 @@
1
- "use strict";var r=Object.defineProperty;var u=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var a=(e,t)=>r(e,"name",{value:t,configurable:!0});var l=(e,t)=>{for(var i in t)r(e,i,{get:t[i],enumerable:!0})},x=(e,t,i,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of y(t))!_.call(e,o)&&o!==i&&r(e,o,{get:()=>t[o],enumerable:!(s=u(t,o))||s.enumerable});return e};var $=e=>x(r({},"__esModule",{value:!0}),e);var k={};l(k,{isNonUserUps:()=>m,run:()=>b});module.exports=$(k);var p=require("../../../hooks/core/actions"),d=require("../../../hooks/core/activity"),c=require("../../../hooks/core/session-state"),n=require("../../../lib/logger"),g=require("../../../lib/stdin"),f=require("../util");function m(e){if(e.agent_id!==void 0&&e.agent_id!==""||e.agent_type!==void 0&&e.agent_type!=="")return!0;const t=(e.prompt??"").replace(/^\s+/,"");return t.startsWith("<hook_prompt")||t.startsWith("<subagent_notification")}a(m,"isNonUserUps");async function b(e){const t=(0,f.parseCodexHookStdin)((0,g.readStdin)()),i=t.session_id??"default",s=`${e}/.ironbee/sessions/${i}`,o=`${s}/actions.jsonl`;(0,n.setLogFile)(`${s}/session.log`),m(t)&&(n.logger.debug(`activity-start: skip non-user UPS (agent_id=${t.agent_id??"-"}, agent_type=${t.agent_type??"-"})`),process.exit(0)),await(0,c.reconcileAbandonedActivity)(s,o,p.appendAction),await(0,d.startActivity)({sessionDir:s,actionsFile:o,source:"user_prompt"}),n.logger.debug(`activity-start: ${i}`),process.exit(0)}a(b,"run");0&&(module.exports={isNonUserUps,run});
1
+ "use strict";var n=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var l=Object.prototype.hasOwnProperty;var a=(e,t)=>n(e,"name",{value:t,configurable:!0});var x=(e,t)=>{for(var i in t)n(e,i,{get:t[i],enumerable:!0})},v=(e,t,i,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of _(t))!l.call(e,o)&&o!==i&&n(e,o,{get:()=>t[o],enumerable:!(s=y(t,o))||s.enumerable});return e};var S=e=>v(n({},"__esModule",{value:!0}),e);var k={};x(k,{isNonUserUps:()=>u,run:()=>b});module.exports=S(k);var p=require("../../../hooks/core/actions"),d=require("../../../hooks/core/activity"),c=require("../../../hooks/core/session-state"),r=require("../../../lib/logger"),g=require("../../../lib/stdin"),m=require("../util"),f=require("../../../lib/runtime-paths");function u(e){if(e.agent_id!==void 0&&e.agent_id!==""||e.agent_type!==void 0&&e.agent_type!=="")return!0;const t=(e.prompt??"").replace(/^\s+/,"");return t.startsWith("<hook_prompt")||t.startsWith("<subagent_notification")}a(u,"isNonUserUps");async function b(e){const t=(0,m.parseCodexHookStdin)((0,g.readStdin)()),i=t.session_id??"default",s=(0,f.sessionDir)(e,i),o=`${s}/actions.jsonl`;(0,r.setLogFile)(`${s}/session.log`),u(t)&&(r.logger.debug(`activity-start: skip non-user UPS (agent_id=${t.agent_id??"-"}, agent_type=${t.agent_type??"-"})`),process.exit(0)),await(0,c.reconcileAbandonedActivity)(s,o,p.appendAction),await(0,d.startActivity)({sessionDir:s,actionsFile:o,source:"user_prompt"}),r.logger.debug(`activity-start: ${i}`),process.exit(0)}a(b,"run");0&&(module.exports={isNonUserUps,run});
@@ -1,5 +1,5 @@
1
- "use strict";var C=Object.defineProperty;var D=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var V=Object.prototype.hasOwnProperty;var l=(n,t)=>C(n,"name",{value:t,configurable:!0});var W=(n,t)=>{for(var e in t)C(n,e,{get:t[e],enumerable:!0})},H=(n,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of T(t))!V.call(n,i)&&i!==e&&C(n,i,{get:()=>t[i],enumerable:!(o=D(t,i))||o.enumerable});return n};var K=n=>H(C({},"__esModule",{value:!0}),n);var z={};W(z,{applyPatchStashKey:()=>j,parseApplyPatchBody:()=>B,run:()=>Y});module.exports=K(z);var A=require("fs"),v=require("path"),x=require("../../../hooks/core/actions"),P=require("../../../import/ids"),S=require("../../../hooks/core/clear-verdict"),I=require("../../../hooks/core/verification-lifecycle"),w=require("../../../hooks/core/file-diff"),M=require("../../../hooks/core/session-state"),k=require("../../../hooks/core/tool-use-stash"),f=require("../../../lib/config"),m=require("../../../lib/logger"),U=require("../../../lib/output"),L=require("../../../lib/stdin"),O=require("../util");const q=".apply-patch";function j(n){return`${n}${q}`}l(j,"applyPatchStashKey");function J(n,t){if(t<=0)return n;const e=Buffer.from(n,"utf-8");if(e.length<=t)return n;const i=`
1
+ "use strict";var C=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var W=Object.prototype.hasOwnProperty;var l=(n,t)=>C(n,"name",{value:t,configurable:!0});var H=(n,t)=>{for(var e in t)C(n,e,{get:t[e],enumerable:!0})},K=(n,t,e,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of V(t))!W.call(n,i)&&i!==e&&C(n,i,{get:()=>t[i],enumerable:!(o=T(t,i))||o.enumerable});return n};var q=n=>K(C({},"__esModule",{value:!0}),n);var G={};H(G,{applyPatchStashKey:()=>j,parseApplyPatchBody:()=>B,run:()=>z});module.exports=q(G);var A=require("fs"),v=require("path"),x=require("../../../hooks/core/actions"),S=require("../../../import/ids"),P=require("../../../hooks/core/clear-verdict"),I=require("../../../hooks/core/verification-lifecycle"),w=require("../../../hooks/core/file-diff"),M=require("../../../hooks/core/session-state"),k=require("../../../hooks/core/tool-use-stash"),f=require("../../../lib/config"),m=require("../../../lib/logger"),D=require("../../../lib/output"),U=require("../../../lib/stdin"),L=require("../util"),O=require("../../../lib/runtime-paths");const J=".apply-patch";function j(n){return`${n}${J}`}l(j,"applyPatchStashKey");function N(n,t){if(t<=0)return n;const e=Buffer.from(n,"utf-8");if(e.length<=t)return n;const i=`
2
2
  ... (truncated, ${e.length-t} bytes omitted)
3
- `,d=Buffer.byteLength(i,"utf-8"),a=Math.max(0,t-d);return e.subarray(0,a).toString("utf-8")+i}l(J,"truncateChangeset");function N(n,t){return(0,v.isAbsolute)(t)?t:(0,v.join)(n,t)}l(N,"resolveFilePath");function X(n,t,e,o){const i=N(n,t.path);let d;try{d=t.operation==="delete"||!(0,A.existsSync)(i)?"":(0,A.readFileSync)(i,"utf-8")}catch(p){m.logger.debug(`failed to read post-state of ${i} for changeset: ${p}`);return}return(0,w.createUnifiedDiff)(e??"",d,o)??void 0}l(X,"buildUnifiedDiffChangeset");function B(n){const t=[];let e=null,o=[];const i=l(()=>{e&&(e.body=o.join(`
3
+ `,d=Buffer.byteLength(i,"utf-8"),a=Math.max(0,t-d);return e.subarray(0,a).toString("utf-8")+i}l(N,"truncateChangeset");function X(n,t){return(0,v.isAbsolute)(t)?t:(0,v.join)(n,t)}l(X,"resolveFilePath");function Y(n,t,e,o){const i=X(n,t.path);let d;try{d=t.operation==="delete"||!(0,A.existsSync)(i)?"":(0,A.readFileSync)(i,"utf-8")}catch(p){m.logger.debug(`failed to read post-state of ${i} for changeset: ${p}`);return}return(0,w.createUnifiedDiff)(e??"",d,o)??void 0}l(Y,"buildUnifiedDiffChangeset");function B(n){const t=[];let e=null,o=[];const i=l(()=>{e&&(e.body=o.join(`
4
4
  `),t.push(e),e=null,o=[])},"flushCurrent"),d=n.split(`
5
- `);for(const a of d){const r=a,p=r.match(/^\*\*\* Add File: (.+)$/),c=r.match(/^\*\*\* Update File: (.+)$/),u=r.match(/^\*\*\* Delete File: (.+)$/),y=r.match(/^\*\*\* (End Patch|Move to: .+)$/);if(p){i(),e={path:p[1].trim(),operation:"create",linesAdded:0,linesRemoved:0,body:""},o=[];continue}if(c){i(),e={path:c[1].trim(),operation:"update",linesAdded:0,linesRemoved:0,body:""},o=[];continue}if(u){i(),e={path:u[1].trim(),operation:"delete",linesAdded:0,linesRemoved:0,body:""},o=[];continue}if(y){i();continue}e&&(o.push(r),e.operation!=="delete"&&(r.startsWith("+")&&!r.startsWith("+++")?e.linesAdded+=1:r.startsWith("-")&&!r.startsWith("---")&&(e.linesRemoved+=1)))}return i(),t}l(B,"parseApplyPatchBody");async function Y(n){const t=(0,O.parseCodexHookStdin)((0,L.readStdin)()),e=t.session_id??"default",o=`${n}/.ironbee/sessions/${e}`,i=`${o}/actions.jsonl`,d=`${o}/verdict.json`;(0,m.setLogFile)(`${o}/session.log`);const a=t.tool_input;let r;if(typeof a=="string")r=a;else if(typeof a=="object"&&a!==null){const c=a;r=c.command??c.input}if(typeof r=="string"){const c=(0,f.loadConfig)(n),u=(0,f.getCaptureFileChangeset)(c),y=(0,f.getMaxChangesetBytes)(c),E=B(r),_=(0,M.getActiveActivityId)(o),b=t.tool_use_id??"",$=u&&b?(0,k.consumeToolUseData)(e,j(b)):null;for(let F=0;F<E.length;F++){const s=E[F];if(!(0,f.requiresVerification)(s.path,c))continue;const R=await(0,I.openFixCycleIfFixing)({sessionDir:o,actionsFile:i}),g={...(0,x.baseFields)(i),type:"file_change",timestamp:Date.now(),file_path:s.path,tool_name:"Edit",operation:s.operation,lines_added:s.operation==="delete"?null:s.linesAdded,lines_removed:s.operation==="delete"?null:s.operation==="create"?0:s.linesRemoved};if(_&&(g.activity_id=_),R&&(g.fix_id=R),b.length>0&&(g.id=(0,P.deriveFileChangeEventId)(e,`${b}:${F}:${s.path}`)),u){let h;$&&Object.prototype.hasOwnProperty.call($.prior_contents,s.path)&&(h=X(n,s,$.prior_contents[s.path],y)),h===void 0&&s.body.length>0&&(h=J(s.body,y)),h!==void 0&&(g.changeset=h)}await(0,x.appendAction)(i,g)}}(0,S.runClearVerdict)({verdictFile:d,sessionDir:o}),m.logger.debug(`clear-verdict: cleared for ${e}`),(0,U.writeAndExit)(JSON.stringify({}),0)}l(Y,"run");0&&(module.exports={applyPatchStashKey,parseApplyPatchBody,run});
5
+ `);for(const a of d){const r=a,p=r.match(/^\*\*\* Add File: (.+)$/),c=r.match(/^\*\*\* Update File: (.+)$/),u=r.match(/^\*\*\* Delete File: (.+)$/),y=r.match(/^\*\*\* (End Patch|Move to: .+)$/);if(p){i(),e={path:p[1].trim(),operation:"create",linesAdded:0,linesRemoved:0,body:""},o=[];continue}if(c){i(),e={path:c[1].trim(),operation:"update",linesAdded:0,linesRemoved:0,body:""},o=[];continue}if(u){i(),e={path:u[1].trim(),operation:"delete",linesAdded:0,linesRemoved:0,body:""},o=[];continue}if(y){i();continue}e&&(o.push(r),e.operation!=="delete"&&(r.startsWith("+")&&!r.startsWith("+++")?e.linesAdded+=1:r.startsWith("-")&&!r.startsWith("---")&&(e.linesRemoved+=1)))}return i(),t}l(B,"parseApplyPatchBody");async function z(n){const t=(0,L.parseCodexHookStdin)((0,U.readStdin)()),e=t.session_id??"default",o=(0,O.sessionDir)(n,e),i=`${o}/actions.jsonl`,d=`${o}/verdict.json`;(0,m.setLogFile)(`${o}/session.log`);const a=t.tool_input;let r;if(typeof a=="string")r=a;else if(typeof a=="object"&&a!==null){const c=a;r=c.command??c.input}if(typeof r=="string"){const c=(0,f.loadConfig)(n),u=(0,f.getCaptureFileChangeset)(c),y=(0,f.getMaxChangesetBytes)(c),_=B(r),$=(0,M.getActiveActivityId)(o),b=t.tool_use_id??"",E=u&&b?(0,k.consumeToolUseData)(e,j(b)):null;for(let F=0;F<_.length;F++){const s=_[F];if(!(0,f.requiresVerification)(s.path,c))continue;const R=await(0,I.openFixCycleIfFixing)({sessionDir:o,actionsFile:i}),g={...(0,x.baseFields)(i),type:"file_change",timestamp:Date.now(),file_path:s.path,tool_name:"Edit",operation:s.operation,lines_added:s.operation==="delete"?null:s.linesAdded,lines_removed:s.operation==="delete"?null:s.operation==="create"?0:s.linesRemoved};if($&&(g.activity_id=$),R&&(g.fix_id=R),b.length>0&&(g.id=(0,S.deriveFileChangeEventId)(e,`${b}:${F}:${s.path}`)),u){let h;E&&Object.prototype.hasOwnProperty.call(E.prior_contents,s.path)&&(h=Y(n,s,E.prior_contents[s.path],y)),h===void 0&&s.body.length>0&&(h=N(s.body,y)),h!==void 0&&(g.changeset=h)}await(0,x.appendAction)(i,g)}}(0,P.runClearVerdict)({verdictFile:d,sessionDir:o}),m.logger.debug(`clear-verdict: cleared for ${e}`),(0,D.writeAndExit)(JSON.stringify({}),0)}l(z,"run");0&&(module.exports={applyPatchStashKey,parseApplyPatchBody,run});
@@ -1,6 +1,6 @@
1
- "use strict";var d=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var a=(o,t)=>d(o,"name",{value:t,configurable:!0});var w=(o,t)=>{for(var n in t)d(o,n,{get:t[n],enumerable:!0})},P=(o,t,n,e)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of x(t))!_.call(o,s)&&s!==n&&d(o,s,{get:()=>t[s],enumerable:!(e=v(t,s))||e.enumerable});return o};var R=o=>P(d({},"__esModule",{value:!0}),o);var U={};w(U,{run:()=>A});module.exports=R(U);var f=require("fs"),g=require("path"),y=require("../../../hooks/core/actions"),b=require("../../../hooks/core/activity"),C=require("../../../hooks/core/tool-use-stash"),h=require("../../../lib/config"),l=require("../../../lib/logger"),S=require("../../../lib/stdin"),k=require("../util"),m=require("./clear-verdict");function T(o){const t=o.tool_input;if(typeof t=="string")return t;if(typeof t=="object"&&t!==null){const n=t,e=n.command??n.input;if(typeof e=="string")return e}return null}a(T,"readPatchBody");function F(o,t){return(0,g.isAbsolute)(t)?t:(0,g.join)(o,t)}a(F,"resolveFilePath");function $(o,t,n,e){const s=(0,m.parseApplyPatchBody)(e),i={};for(const r of s){if(r.operation==="create"){i[r.path]=null;continue}const c=F(o,r.path);try{i[r.path]=(0,f.existsSync)(c)?(0,f.readFileSync)(c,"utf-8"):null}catch(u){l.logger.debug(`failed to read prior content of ${c} for changeset stash: ${u}`),i[r.path]=null}}const p={prior_contents:i};(0,C.stashToolUseData)(t,(0,m.applyPatchStashKey)(n),p)}a($,"stashPriorContents");async function A(o,t){const n=t?.soft===!0,e=(0,k.parseCodexHookStdin)((0,S.readStdin)()),s=e.session_id??"default",i=`${o}/.ironbee/sessions/${s}`,p=`${i}/actions.jsonl`;if((0,l.setLogFile)(`${i}/session.log`),!n&&(0,y.hasToolCallsSinceLastVerdict)(p)){const c=`BLOCKED: You used devtools tools but haven't submitted a verdict yet.
1
+ "use strict";var d=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var _=Object.getOwnPropertyNames;var w=Object.prototype.hasOwnProperty;var a=(o,t)=>d(o,"name",{value:t,configurable:!0});var P=(o,t)=>{for(var e in t)d(o,e,{get:t[e],enumerable:!0})},R=(o,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of _(t))!w.call(o,s)&&s!==e&&d(o,s,{get:()=>t[s],enumerable:!(n=x(t,s))||n.enumerable});return o};var T=o=>R(d({},"__esModule",{value:!0}),o);var $={};P($,{run:()=>U});module.exports=T($);var f=require("fs"),g=require("path"),y=require("../../../hooks/core/actions"),S=require("../../../hooks/core/activity"),b=require("../../../hooks/core/tool-use-stash"),m=require("../../../lib/config"),l=require("../../../lib/logger"),C=require("../../../lib/stdin"),k=require("../util"),h=require("./clear-verdict"),v=require("../../../lib/runtime-paths");function F(o){const t=o.tool_input;if(typeof t=="string")return t;if(typeof t=="object"&&t!==null){const e=t,n=e.command??e.input;if(typeof n=="string")return n}return null}a(F,"readPatchBody");function A(o,t){return(0,g.isAbsolute)(t)?t:(0,g.join)(o,t)}a(A,"resolveFilePath");function D(o,t,e,n){const s=(0,h.parseApplyPatchBody)(n),i={};for(const r of s){if(r.operation==="create"){i[r.path]=null;continue}const c=A(o,r.path);try{i[r.path]=(0,f.existsSync)(c)?(0,f.readFileSync)(c,"utf-8"):null}catch(u){l.logger.debug(`failed to read prior content of ${c} for changeset stash: ${u}`),i[r.path]=null}}const p={prior_contents:i};(0,b.stashToolUseData)(t,(0,h.applyPatchStashKey)(e),p)}a(D,"stashPriorContents");async function U(o,t){const e=t?.soft===!0,n=(0,k.parseCodexHookStdin)((0,C.readStdin)()),s=n.session_id??"default",i=(0,v.sessionDir)(o,s),p=`${i}/actions.jsonl`;if((0,l.setLogFile)(`${i}/session.log`),!e&&(0,y.hasToolCallsSinceLastVerdict)(p)){const c=`BLOCKED: You used devtools tools but haven't submitted a verdict yet.
2
2
 
3
3
  You MUST submit a verdict before editing more code. Use:
4
4
  echo '{"session_id":"${s}","status":"fail","checks":["..."],"issues":["..."]}' | ironbee hook submit-verdict
5
5
 
6
- Then proceed with the edit.`;process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:c}})),process.exit(0);return}const r=e.tool_use_id??"";if(r){const c=(0,h.loadConfig)(o);if((0,h.getCaptureFileChangeset)(c)){const u=T(e);u!==null&&$(o,s,r,u)}}await(0,b.startActivity)({sessionDir:i,actionsFile:p,source:"pre_tool_use"}),l.logger.debug("require-verdict: allowed apply_patch"),process.exit(0)}a(A,"run");0&&(module.exports={run});
6
+ Then proceed with the edit.`;process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:c}})),process.exit(0);return}const r=n.tool_use_id??"";if(r){const c=(0,m.loadConfig)(o);if((0,m.getCaptureFileChangeset)(c)){const u=F(n);u!==null&&D(o,s,r,u)}}await(0,S.startActivity)({sessionDir:i,actionsFile:p,source:"pre_tool_use"}),l.logger.debug("require-verdict: allowed apply_patch"),process.exit(0)}a(U,"run");0&&(module.exports={run});
@@ -1,9 +1,9 @@
1
- "use strict";var u=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var q=Object.getOwnPropertyNames;var B=Object.prototype.hasOwnProperty;var C=(o,e)=>u(o,"name",{value:e,configurable:!0});var J=(o,e)=>{for(var s in e)u(o,s,{get:e[s],enumerable:!0})},L=(o,e,s,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of q(e))!B.call(o,t)&&t!==s&&u(o,t,{get:()=>e[t],enumerable:!(n=K(e,t))||n.enumerable});return o};var H=o=>L(u({},"__esModule",{value:!0}),o);var M={};J(M,{run:()=>z});module.exports=H(M);var $=require("crypto"),x=require("../../../hooks/core/activity"),i=require("../../../hooks/core/session-state"),N=require("../../../hooks/core/actions"),E=require("../../../hooks/core/verification-lifecycle"),O=require("../../../hooks/core/verification-context"),U=require("../../../lib/config"),m=require("../../../lib/logger"),A=require("../../../lib/recording-tools"),D=require("../../../hooks/core/scenario-tools"),V=require("../../../lib/stdin"),f=require("../util");async function z(o,e){const s=e?.soft===!0,n=(0,f.parseCodexHookStdin)((0,V.readStdin)()),t=n.session_id??"default",r=`${o}/.ironbee/sessions/${t}`,y=`${r}/actions.jsonl`;(0,m.setLogFile)(`${r}/session.log`);const g=(0,D.isScenarioTool)(n.tool_name),h=(0,i.getActiveVerificationId)(r);if(!h&&!s&&!g){const p=`BLOCKED: You must start a verification cycle before using devtools tools.
1
+ "use strict";var u=Object.defineProperty;var q=Object.getOwnPropertyDescriptor;var B=Object.getOwnPropertyNames;var J=Object.prototype.hasOwnProperty;var C=(o,e)=>u(o,"name",{value:e,configurable:!0});var L=(o,e)=>{for(var s in e)u(o,s,{get:e[s],enumerable:!0})},H=(o,e,s,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of B(e))!J.call(o,t)&&t!==s&&u(o,t,{get:()=>e[t],enumerable:!(r=q(e,t))||r.enumerable});return o};var z=o=>H(u({},"__esModule",{value:!0}),o);var W={};L(W,{run:()=>M});module.exports=z(W);var x=require("crypto"),N=require("../../../hooks/core/activity"),$=require("../../../lib/runtime-paths"),i=require("../../../hooks/core/session-state"),E=require("../../../hooks/core/actions"),O=require("../../../hooks/core/verification-lifecycle"),U=require("../../../hooks/core/verification-context"),D=require("../../../lib/config"),m=require("../../../lib/logger"),A=require("../../../lib/recording-tools"),V=require("../../../hooks/core/scenario-tools"),P=require("../../../lib/stdin"),f=require("../util");async function M(o,e){const s=e?.soft===!0,r=(0,f.parseCodexHookStdin)((0,P.readStdin)()),t=r.session_id??"default",n=(0,$.sessionDir)(o,t),b=`${n}/actions.jsonl`;(0,m.setLogFile)(`${n}/session.log`);const g=(0,V.isScenarioTool)(r.tool_name),h=(0,i.getActiveVerificationId)(n);if(!h&&!s&&!g){const p=`BLOCKED: You must start a verification cycle before using devtools tools.
2
2
 
3
3
  Start verification first:
4
4
  echo '{"session_id":"${t}"}' | ironbee hook verification-start
5
5
 
6
- Then use the verification tools for the active cycle(s) \u2014 mcp__browser-devtools__bdt_* for browser, mcp__node-devtools__ndt_* for node, mcp__backend-devtools__bedt_* for backend, mcp__android-devtools__adt_* for android.`;process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:p}})),process.exit(0);return}const _=n.tool_name??"",S=(0,f.extractCodexMcpServer)(_),c=(0,A.recordingToolsForServer)(S),P=c!==null?(0,f.canonicalizeCodexToolName)(_.split("__").pop()??""):"";if(!s&&!g&&c!==null&&(0,i.isRecordingRequired)(r)&&!(0,i.isRecordingActive)(r)&&P!==c.startTool){const p=`BLOCKED: Recording is required but not started.
6
+ Then use the verification tools for the active cycle(s) \u2014 mcp__browser-devtools__bdt_* for browser, mcp__node-devtools__ndt_* for node, mcp__backend-devtools__bedt_* for backend, mcp__android-devtools__adt_* for android.`;process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:p}})),process.exit(0);return}const _=r.tool_name??"",S=(0,f.extractCodexMcpServer)(_),c=(0,A.recordingToolsForServer)(S),j=c!==null?(0,f.canonicalizeCodexToolName)(_.split("__").pop()??""):"";if(!s&&!g&&c!==null&&(0,i.isRecordingRequired)(n)&&!(0,i.isRecordingActive)(n)&&j!==c.startTool){const p=`BLOCKED: Recording is required but not started.
7
7
 
8
8
  1. Start recording NOW:
9
9
  Use mcp__${c.server}__${c.startTool}
@@ -12,4 +12,4 @@ Then use the verification tools for the active cycle(s) \u2014 mcp__browser-devt
12
12
 
13
13
  3. **Stop recording BEFORE submitting verdict:**
14
14
  Use mcp__${c.server}__${c.stopTool}
15
- submit-verdict will reject with "recording is still active" if you skip this.`;process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:p}})),process.exit(0);return}await(0,x.startActivity)({sessionDir:r,actionsFile:y,source:"pre_tool_use"});let d=h;s&&!d&&!g&&(d=(await(0,E.startVerification)({sessionId:t,sessionDir:r,actionsFile:y,recordingEnabled:!1})).verificationId);const j=(0,i.getActiveTraceId)(r),v=(0,i.getActiveActivityId)(r),k=(0,N.resolveProjectName)(o),b=[`prj:${k}`,`sid:${t}`];v&&b.push(`aid:${v}`),d&&b.push(`vid:${d}`);const F=`ironbee=${b.join(";")}`,a=(0,U.loadConfig)(o),T={...n.tool_input&&typeof n.tool_input=="object"?n.tool_input:{}},l={projectName:k,sessionId:t,activityId:v,verificationId:d,traceId:j,traceState:F,toolCallId:(0,$.randomUUID)()};n.tool_use_id&&(l.toolUseId=n.tool_use_id),l.mcpServer=S??"browser-devtools";const w=(0,i.getUserEmail)(r);w&&(l.userEmail=w),a.collector?.url&&(l.collectorUrl=a.collector.url),a.collector?.oauthToken?l.collectorOAuthToken=a.collector.oauthToken:a.collector?.apiKey&&(l.collectorApiKey=a.collector.apiKey),T._metadata=l;const I={hookEventName:"PreToolUse",permissionDecision:"allow",updatedInput:T},R=(0,O.buildVerificationContextOnceForCycle)({projectDir:o,sessionId:t,sessionDir:r,activeVerificationId:d,config:a});R.length>0&&(I.additionalContext=R),process.stdout.write(JSON.stringify({hookSpecificOutput:I})),m.logger.debug(`require-verification: allowed ${_} with _metadata`),process.exit(0)}C(z,"run");0&&(module.exports={run});
15
+ submit-verdict will reject with "recording is still active" if you skip this.`;process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:p}})),process.exit(0);return}await(0,N.startActivity)({sessionDir:n,actionsFile:b,source:"pre_tool_use"});let d=h;s&&!d&&!g&&(d=(await(0,O.startVerification)({sessionId:t,sessionDir:n,actionsFile:b,recordingEnabled:!1})).verificationId);const F=(0,i.getActiveTraceId)(n),v=(0,i.getActiveActivityId)(n),k=(0,E.resolveProjectName)(o),y=[`prj:${k}`,`sid:${t}`];v&&y.push(`aid:${v}`),d&&y.push(`vid:${d}`);const K=`ironbee=${y.join(";")}`,a=(0,D.loadConfig)(o),T={...r.tool_input&&typeof r.tool_input=="object"?r.tool_input:{}},l={projectName:k,sessionId:t,activityId:v,verificationId:d,traceId:F,traceState:K,toolCallId:(0,x.randomUUID)()};r.tool_use_id&&(l.toolUseId=r.tool_use_id),l.mcpServer=S??"browser-devtools";const w=(0,i.getUserEmail)(n);w&&(l.userEmail=w),a.collector?.url&&(l.collectorUrl=a.collector.url),a.collector?.oauthToken?l.collectorOAuthToken=a.collector.oauthToken:a.collector?.apiKey&&(l.collectorApiKey=a.collector.apiKey),T._metadata=l;const I={hookEventName:"PreToolUse",permissionDecision:"allow",updatedInput:T},R=(0,U.buildVerificationContextOnceForCycle)({projectDir:o,sessionId:t,sessionDir:n,activeVerificationId:d,config:a});R.length>0&&(I.additionalContext=R),process.stdout.write(JSON.stringify({hookSpecificOutput:I})),m.logger.debug(`require-verification: allowed ${_} with _metadata`),process.exit(0)}C(M,"run");0&&(module.exports={run});
@@ -1,4 +1,4 @@
1
- "use strict";var c=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var k=Object.getOwnPropertyNames;var O=Object.prototype.hasOwnProperty;var g=(i,s)=>c(i,"name",{value:s,configurable:!0});var I=(i,s)=>{for(var e in s)c(i,e,{get:s[e],enumerable:!0})},w=(i,s,e,o)=>{if(s&&typeof s=="object"||typeof s=="function")for(let t of k(s))!O.call(i,t)&&t!==e&&c(i,t,{get:()=>s[t],enumerable:!(o=x(s,t))||o.enumerable});return i};var C=i=>w(c({},"__esModule",{value:!0}),i);var T={};I(T,{run:()=>N});module.exports=C(T);var r=require("../../../hooks/core/actions"),p=require("../../../import/ids"),n=require("../../../hooks/core/session-state"),d=require("../../../lib/config"),u=require("../../../lib/logger"),l=require("../../../lib/output"),S=require("../../../lib/stdin"),b=require("../../../lib/telemetry"),f=require("../util");async function N(i){const s=(0,f.parseCodexHookStdin)((0,S.readStdin)()),e=s.session_id??"default",o=`${i}/.ironbee/sessions/${e}`,t=`${o}/actions.jsonl`;(0,u.setLogFile)(`${o}/session.log`);const a=(0,f.resolveCodexUsage)();a.userEmail&&(0,n.setUserEmail)(o,a.userEmail),(0,n.setUsage)(o,{usage_type:a.usageType??null,usage_plan:a.usagePlan??null});const y={...(0,r.baseFields)(t),id:(0,p.deriveSessionStartEventId)(e),type:"session_start",timestamp:Date.now(),session_id:e,client:"codex",source:s.source??"startup"};await(0,r.appendAction)(t,y),await(0,n.reconcileSessionState)(o,t,r.appendAction);const m=(0,d.getVerificationEnabled)((0,d.loadConfig)(i));if(await(0,b.trackSessionStart)("codex",e,m,i),u.logger.debug(`session-start: ${e}`),!m){(0,l.writeAndExit)(JSON.stringify({}),0);return}const h=JSON.stringify({session_id:e,status:"pass",checks:["form submits successfully","new item appears in list"]}),v=JSON.stringify({session_id:e,status:"fail",checks:["form renders","submit button unresponsive"],issues:["button click handler not firing","TypeError in console"]}),E=`IRONBEE VERIFICATION \u2014 SESSION ACTIVE
1
+ "use strict";var c=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var g=(s,i)=>c(s,"name",{value:i,configurable:!0});var w=(s,i)=>{for(var e in i)c(s,e,{get:i[e],enumerable:!0})},C=(s,i,e,t)=>{if(i&&typeof i=="object"||typeof i=="function")for(let o of O(i))!I.call(s,o)&&o!==e&&c(s,o,{get:()=>i[o],enumerable:!(t=k(i,o))||t.enumerable});return s};var N=s=>C(c({},"__esModule",{value:!0}),s);var _={};w(_,{run:()=>T});module.exports=N(_);var r=require("../../../hooks/core/actions"),p=require("../../../import/ids"),n=require("../../../hooks/core/session-state"),d=require("../../../lib/config"),u=require("../../../lib/logger"),l=require("../../../lib/output"),S=require("../../../lib/stdin"),b=require("../../../lib/telemetry"),f=require("../util"),v=require("../../../lib/runtime-paths");async function T(s){const i=(0,f.parseCodexHookStdin)((0,S.readStdin)()),e=i.session_id??"default",t=(0,v.sessionDir)(s,e),o=`${t}/actions.jsonl`;(0,u.setLogFile)(`${t}/session.log`),(0,n.setProjectDir)(t,s);const a=(0,f.resolveCodexUsage)();a.userEmail&&(0,n.setUserEmail)(t,a.userEmail),(0,n.setUsage)(t,{usage_type:a.usageType??null,usage_plan:a.usagePlan??null});const y={...(0,r.baseFields)(o),id:(0,p.deriveSessionStartEventId)(e),type:"session_start",timestamp:Date.now(),session_id:e,client:"codex",source:i.source??"startup"};await(0,r.appendAction)(o,y),await(0,n.reconcileSessionState)(t,o,r.appendAction);const m=(0,d.getVerificationEnabled)((0,d.loadConfig)(s));if(await(0,b.trackSessionStart)("codex",e,m,s),u.logger.debug(`session-start: ${e}`),!m){(0,l.writeAndExit)(JSON.stringify({}),0);return}const h=JSON.stringify({session_id:e,status:"pass",checks:["form submits successfully","new item appears in list"]}),E=JSON.stringify({session_id:e,status:"fail",checks:["form renders","submit button unresponsive"],issues:["button click handler not firing","TypeError in console"]}),x=`IRONBEE VERIFICATION \u2014 SESSION ACTIVE
2
2
  Session ID: ${e}
3
3
 
4
4
  You MUST verify all code changes in the browser before completing any task.
@@ -10,8 +10,8 @@ Submit via shell:
10
10
  echo '${h}' | ironbee hook submit-verdict
11
11
 
12
12
  On fail (issues is required):
13
- echo '${v}' | ironbee hook submit-verdict
13
+ echo '${E}' | ironbee hook submit-verdict
14
14
 
15
15
  Required fields: session_id, status, checks
16
16
  On fail, include: issues (array of strings describing what failed)
17
- On pass after a previous fail, include: fixes (array of strings describing what was fixed)`;(0,l.writeAndExit)(JSON.stringify({hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:E}}),0)}g(N,"run");0&&(module.exports={run});
17
+ On pass after a previous fail, include: fixes (array of strings describing what was fixed)`;(0,l.writeAndExit)(JSON.stringify({hookSpecificOutput:{hookEventName:"SessionStart",additionalContext:x}}),0)}g(T,"run");0&&(module.exports={run});
@@ -1 +1 @@
1
- "use strict";var n=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var f=Object.prototype.hasOwnProperty;var d=(e,o)=>n(e,"name",{value:o,configurable:!0});var u=(e,o)=>{for(var s in o)n(e,s,{get:o[s],enumerable:!0})},x=(e,o,s,t)=>{if(o&&typeof o=="object"||typeof o=="function")for(let i of c(o))!f.call(e,i)&&i!==s&&n(e,i,{get:()=>o[i],enumerable:!(t=m(o,i))||t.enumerable});return e};var $=e=>x(n({},"__esModule",{value:!0}),e);var _={};u(_,{run:()=>S});module.exports=$(_);var r=require("../../../lib/logger"),g=require("../../../lib/stdin"),p=require("../util"),a=require("../thread-map");async function S(e){const o=(0,p.parseCodexHookStdin)((0,g.readStdin)()),s=o.session_id??"",t=o.agent_id??"";if(!s||!t){process.exit(0);return}(0,r.setLogFile)(`${e}/.ironbee/sessions/${s}/session.log`),(0,a.writeThreadMapping)(e,t,s),r.logger.debug(`subagent-start: mapped thread ${t} \u2192 session ${s} (agent_type=${o.agent_type??"?"})`),process.exit(0)}d(S,"run");0&&(module.exports={run});
1
+ "use strict";var n=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var c=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var d=(t,o)=>n(t,"name",{value:o,configurable:!0});var x=(t,o)=>{for(var e in o)n(t,e,{get:o[e],enumerable:!0})},S=(t,o,e,i)=>{if(o&&typeof o=="object"||typeof o=="function")for(let s of c(o))!u.call(t,s)&&s!==e&&n(t,s,{get:()=>o[s],enumerable:!(i=f(o,s))||i.enumerable});return t};var _=t=>S(n({},"__esModule",{value:!0}),t);var l={};x(l,{run:()=>k});module.exports=_(l);var r=require("../../../lib/logger"),p=require("../../../lib/stdin"),g=require("../util"),a=require("../thread-map"),m=require("../../../lib/runtime-paths");async function k(t){const o=(0,g.parseCodexHookStdin)((0,p.readStdin)()),e=o.session_id??"",i=o.agent_id??"";if(!e||!i){process.exit(0);return}(0,r.setLogFile)((0,m.sessionLogFile)(t,e)),(0,a.writeThreadMapping)(t,i,e),r.logger.debug(`subagent-start: mapped thread ${i} \u2192 session ${e} (agent_type=${o.agent_type??"?"})`),process.exit(0)}d(k,"run");0&&(module.exports={run});
@@ -1 +1 @@
1
- "use strict";var s=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var u=Object.prototype.hasOwnProperty;var a=(n,t)=>s(n,"name",{value:t,configurable:!0});var _=(n,t)=>{for(var o in t)s(n,o,{get:t[o],enumerable:!0})},x=(n,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of f(t))!u.call(n,e)&&e!==o&&s(n,e,{get:()=>t[e],enumerable:!(r=m(t,e))||r.enumerable});return n};var h=n=>x(s({},"__esModule",{value:!0}),n);var b={};_(b,{run:()=>S});module.exports=h(b);var i=require("../../../lib/logger"),p=require("../../../lib/stdin"),d=require("../util"),g=require("../thread-map"),c=require("../../../analytics/codex/subagent-transcripts");async function S(n){const t=(0,d.parseCodexHookStdin)((0,p.readStdin)()),o=t.session_id??"",r=t.agent_id??"";if(!r){process.exit(0);return}o&&(0,i.setLogFile)(`${n}/.ironbee/sessions/${o}/session.log`),(0,g.pruneThreadMapping)(n,r);const e=t.agent_transcript_path??"";o&&e&&(0,c.recordSubagentTranscript)(n,o,{agent_id:r,agent_type:t.agent_type,transcript_path:e,ts:Date.now()}),i.logger.debug(`subagent-stop: pruned thread ${r}; recorded transcript=${e||"(none)"}`),process.exit(0)}a(S,"run");0&&(module.exports={run});
1
+ "use strict";var i=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var a=(n,t)=>i(n,"name",{value:t,configurable:!0});var x=(n,t)=>{for(var o in t)i(n,o,{get:t[o],enumerable:!0})},h=(n,t,o,e)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of u(t))!_.call(n,r)&&r!==o&&i(n,r,{get:()=>t[r],enumerable:!(e=f(t,r))||e.enumerable});return n};var S=n=>h(i({},"__esModule",{value:!0}),n);var k={};x(k,{run:()=>b});module.exports=S(k);var s=require("../../../lib/logger"),p=require("../../../lib/stdin"),d=require("../util"),g=require("../thread-map"),c=require("../../../analytics/codex/subagent-transcripts"),m=require("../../../lib/runtime-paths");async function b(n){const t=(0,d.parseCodexHookStdin)((0,p.readStdin)()),o=t.session_id??"",e=t.agent_id??"";if(!e){process.exit(0);return}o&&(0,s.setLogFile)((0,m.sessionLogFile)(n,o)),(0,g.pruneThreadMapping)(n,e);const r=t.agent_transcript_path??"";o&&r&&(0,c.recordSubagentTranscript)(n,o,{agent_id:e,agent_type:t.agent_type,transcript_path:r,ts:Date.now()}),s.logger.debug(`subagent-stop: pruned thread ${e}; recorded transcript=${r||"(none)"}`),process.exit(0)}a(b,"run");0&&(module.exports={run});
@@ -1 +1 @@
1
- "use strict";var f=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var J=Object.getOwnPropertyNames;var F=Object.prototype.hasOwnProperty;var m=(o,t)=>f(o,"name",{value:t,configurable:!0});var B=(o,t)=>{for(var e in t)f(o,e,{get:t[e],enumerable:!0})},L=(o,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of J(t))!F.call(o,r)&&r!==e&&f(o,r,{get:()=>t[r],enumerable:!(n=$(t,r))||n.enumerable});return o};var M=o=>L(f({},"__esModule",{value:!0}),o);var P={};B(P,{run:()=>z});module.exports=M(P);var k=require("../../../hooks/core/actions"),C=require("../../../import/ids"),h=require("../../../hooks/core/activity"),S=require("../../../hooks/core/session-state"),v=require("../../../hooks/core/tool-use-stash"),I=require("../../../lib/config"),s=require("../../../lib/logger"),y=require("../../../lib/output"),N=require("../../../lib/stdin"),l=require("../../../queue"),i=require("../util");function O(o){if(o==null)return{isError:!1};if(typeof o=="object"&&o!==null){const t=o;if(t.isError===!0||t.is_error===!0){const e=t.error??t.message??t.errorMessage;return{isError:!0,errorText:typeof e=="string"?e:JSON.stringify(t).slice(0,500)}}}if(typeof o=="string"){const t=o;if(/(?:^|\n)Process exited with code [1-9]/.test(t)||/^Exit code:\s*[1-9]/m.test(t)||/apply_patch verification failed/i.test(t)||/failed to find expected lines/i.test(t)||/^\s*Error\b/.test(t)||/(?:^|\n)\[Request interrupted by user\]/.test(t)||/modified since (?:last )?read|stale read/i.test(t)||/file (?:is )?too large|exceeds/i.test(t)||/file not found|No such file or directory|does not exist/i.test(t))return{isError:!0,errorText:t.slice(0,500)}}return{isError:!1}}m(O,"detectFailureMonitor");function w(o){if(o==null)return 0;if(typeof o=="string")try{return Buffer.byteLength(o,"utf8")}catch{return 0}try{return Buffer.byteLength(JSON.stringify(o),"utf8")}catch{return 0}}m(w,"safeStringifyBytes");async function z(o){const t=(0,i.parseCodexHookStdin)((0,N.readStdin)()),e=t.session_id??"default",n=`${o}/.ironbee/sessions/${e}`,r=`${n}/actions.jsonl`;if((0,s.setLogFile)(`${n}/session.log`),await(0,h.startActivity)({sessionDir:n,actionsFile:r,source:"pre_tool_use"}),!(0,I.isJobQueueEnabled)(o)){(0,y.writeAndExit)(JSON.stringify({}),0);return}const u=t.tool_name??"",d=t.tool_use_id??"",_=t.tool_input,T=t.tool_response,g=(0,i.classifyCodexTool)(u),x=(0,S.getActiveActivityId)(n),A=(0,i.extractCodexToolInput)(u,_),b=(0,v.consumeToolUseData)(e,d);let E=null;if(b?.start_ns)try{E=Number((process.hrtime.bigint()-BigInt(b.start_ns))/1000000n)}catch(c){s.logger.debug(`derive duration failed: ${c}`)}const p=O(T),a={...(0,k.baseFields)(r),type:"tool_call",timestamp:Date.now(),tool_type:g.tool_type,tool_name:g.tool_name||(0,i.normalizeCodexToolName)(u),mcp_server:g.mcp_server,tool_input:A,tool_input_size:w(_),tool_response_size:p.isError?0:w(T),duration:E};x&&(a.activity_id=x),d&&(a.tool_use_id=d),d.length>0&&(a.id=(0,C.deriveToolCallEventIdFromToolUseId)(e,d)),p.isError&&(a.error=p.errorText);try{(0,l.submit)(o,e,l.SEND_EVENT_TYPE,a)}catch(c){c instanceof l.JobTooLargeError?s.logger.debug(`track-action-monitor: wire event too large for tool_call ${u}; dropping`):s.logger.debug(`queue submit failed for tool_call ${u}: ${c}`)}(0,y.writeAndExit)(JSON.stringify({}),0)}m(z,"run");0&&(module.exports={run});
1
+ "use strict";var c=Object.defineProperty;var $=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var B=Object.prototype.hasOwnProperty;var m=(o,t)=>c(o,"name",{value:t,configurable:!0});var D=(o,t)=>{for(var e in t)c(o,e,{get:t[e],enumerable:!0})},L=(o,t,e,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of F(t))!B.call(o,r)&&r!==e&&c(o,r,{get:()=>t[r],enumerable:!(n=$(t,r))||n.enumerable});return o};var M=o=>L(c({},"__esModule",{value:!0}),o);var P={};D(P,{run:()=>z});module.exports=M(P);var k=require("../../../hooks/core/actions"),C=require("../../../import/ids"),S=require("../../../hooks/core/activity"),h=require("../../../hooks/core/session-state"),v=require("../../../hooks/core/tool-use-stash"),I=require("../../../lib/config"),s=require("../../../lib/logger"),y=require("../../../lib/output"),N=require("../../../lib/stdin"),l=require("../../../queue"),A=require("../../../lib/runtime-paths"),i=require("../util");function O(o){if(o==null)return{isError:!1};if(typeof o=="object"&&o!==null){const t=o;if(t.isError===!0||t.is_error===!0){const e=t.error??t.message??t.errorMessage;return{isError:!0,errorText:typeof e=="string"?e:JSON.stringify(t).slice(0,500)}}}if(typeof o=="string"){const t=o;if(/(?:^|\n)Process exited with code [1-9]/.test(t)||/^Exit code:\s*[1-9]/m.test(t)||/apply_patch verification failed/i.test(t)||/failed to find expected lines/i.test(t)||/^\s*Error\b/.test(t)||/(?:^|\n)\[Request interrupted by user\]/.test(t)||/modified since (?:last )?read|stale read/i.test(t)||/file (?:is )?too large|exceeds/i.test(t)||/file not found|No such file or directory|does not exist/i.test(t))return{isError:!0,errorText:t.slice(0,500)}}return{isError:!1}}m(O,"detectFailureMonitor");function w(o){if(o==null)return 0;if(typeof o=="string")try{return Buffer.byteLength(o,"utf8")}catch{return 0}try{return Buffer.byteLength(JSON.stringify(o),"utf8")}catch{return 0}}m(w,"safeStringifyBytes");async function z(o){const t=(0,i.parseCodexHookStdin)((0,N.readStdin)()),e=t.session_id??"default",n=(0,A.sessionDir)(o,e),r=`${n}/actions.jsonl`;if((0,s.setLogFile)(`${n}/session.log`),await(0,S.startActivity)({sessionDir:n,actionsFile:r,source:"pre_tool_use"}),!(0,I.isJobQueueEnabled)(o)){(0,y.writeAndExit)(JSON.stringify({}),0);return}const u=t.tool_name??"",a=t.tool_use_id??"",_=t.tool_input,T=t.tool_response,g=(0,i.classifyCodexTool)(u),x=(0,h.getActiveActivityId)(n),J=(0,i.extractCodexToolInput)(u,_),b=(0,v.consumeToolUseData)(e,a);let E=null;if(b?.start_ns)try{E=Number((process.hrtime.bigint()-BigInt(b.start_ns))/1000000n)}catch(f){s.logger.debug(`derive duration failed: ${f}`)}const p=O(T),d={...(0,k.baseFields)(r),type:"tool_call",timestamp:Date.now(),tool_type:g.tool_type,tool_name:g.tool_name||(0,i.normalizeCodexToolName)(u),mcp_server:g.mcp_server,tool_input:J,tool_input_size:w(_),tool_response_size:p.isError?0:w(T),duration:E};x&&(d.activity_id=x),a&&(d.tool_use_id=a),a.length>0&&(d.id=(0,C.deriveToolCallEventIdFromToolUseId)(e,a)),p.isError&&(d.error=p.errorText);try{(0,l.submit)(o,e,l.SEND_EVENT_TYPE,d)}catch(f){f instanceof l.JobTooLargeError?s.logger.debug(`track-action-monitor: wire event too large for tool_call ${u}; dropping`):s.logger.debug(`queue submit failed for tool_call ${u}: ${f}`)}(0,y.writeAndExit)(JSON.stringify({}),0)}m(z,"run");0&&(module.exports={run});
@@ -1 +1 @@
1
- "use strict";var r=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var f=Object.prototype.hasOwnProperty;var a=(o,t)=>r(o,"name",{value:t,configurable:!0});var x=(o,t)=>{for(var s in t)r(o,s,{get:t[s],enumerable:!0})},u=(o,t,s,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of m(t))!f.call(o,e)&&e!==s&&r(o,e,{get:()=>t[e],enumerable:!(i=c(t,e))||i.enumerable});return o};var l=o=>u(r({},"__esModule",{value:!0}),o);var _={};x(_,{run:()=>S});module.exports=l(_);var n=require("../../../lib/logger"),d=require("../../../lib/stdin"),p=require("../../../hooks/core/tool-use-stash"),g=require("../util");async function S(o){const t=(0,g.parseCodexHookStdin)((0,d.readStdin)()),s=t.session_id??"",i=t.tool_use_id??"";if(!s||!i){process.exit(0);return}(0,n.setLogFile)(`${o}/.ironbee/sessions/${s}/session.log`);const e={start_ns:process.hrtime.bigint().toString()};(0,p.stashToolUseData)(s,i,e),n.logger.debug(`track-action-pre: stashed start_ns for ${i}`),process.exit(0)}a(S,"run");0&&(module.exports={run});
1
+ "use strict";var i=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var f=Object.getOwnPropertyNames;var x=Object.prototype.hasOwnProperty;var a=(o,t)=>i(o,"name",{value:t,configurable:!0});var u=(o,t)=>{for(var s in t)i(o,s,{get:t[s],enumerable:!0})},l=(o,t,s,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of f(t))!x.call(o,e)&&e!==s&&i(o,e,{get:()=>t[e],enumerable:!(r=c(t,e))||r.enumerable});return o};var S=o=>l(i({},"__esModule",{value:!0}),o);var C={};u(C,{run:()=>_});module.exports=S(C);var n=require("../../../lib/logger"),p=require("../../../lib/stdin"),d=require("../../../hooks/core/tool-use-stash"),m=require("../util"),g=require("../../../lib/runtime-paths");async function _(o){const t=(0,m.parseCodexHookStdin)((0,p.readStdin)()),s=t.session_id??"",r=t.tool_use_id??"";if(!s||!r){process.exit(0);return}(0,n.setLogFile)((0,g.sessionLogFile)(o,s));const e={start_ns:process.hrtime.bigint().toString()};(0,d.stashToolUseData)(s,r,e),n.logger.debug(`track-action-pre: stashed start_ns for ${r}`),process.exit(0)}a(_,"run");0&&(module.exports={run});
@@ -1 +1 @@
1
- "use strict";var N=Object.defineProperty;var G=Object.getOwnPropertyDescriptor;var K=Object.getOwnPropertyNames;var W=Object.prototype.hasOwnProperty;var b=(t,e)=>N(t,"name",{value:e,configurable:!0});var X=(t,e)=>{for(var o in e)N(t,o,{get:e[o],enumerable:!0})},Z=(t,e,o,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of K(e))!W.call(t,i)&&i!==o&&N(t,i,{get:()=>e[i],enumerable:!(n=G(e,i))||n.enumerable});return t};var ee=t=>Z(N({},"__esModule",{value:!0}),t);var ie={};X(ie,{run:()=>re});module.exports=ee(ie);var T=require("../../../hooks/core/actions"),v=require("../../../hooks/core/nested-tools"),R=require("../../../import/ids"),r=require("../../../hooks/core/session-state"),L=require("../../../hooks/core/tool-use-stash"),P=require("../../../lib/config"),a=require("../../../lib/logger"),h=require("../../../lib/output"),U=require("../../../lib/recording-tools"),q=require("../../../lib/stdin"),x=require("../../../queue"),d=require("../util");function A(t){if(t==null)return 0;if(typeof t=="string")try{return Buffer.byteLength(t,"utf8")}catch{return 0}try{return Buffer.byteLength(JSON.stringify(t),"utf8")}catch{return 0}}b(A,"safeStringifyBytes");function te(t){if(t==null)return{isError:!1,errorText:void 0};if(typeof t=="object"&&t!==null){const e=t;if(e.isError===!0||e.is_error===!0){const o=e.error??e.message??e.errorMessage;return{isError:!0,errorText:typeof o=="string"?o:JSON.stringify(e).slice(0,500)}}}if(typeof t=="string"){const e=t;if(/(?:^|\n)Process exited with code [1-9]/.test(e)||/^Exit code:\s*[1-9]/m.test(e)||/apply_patch verification failed/i.test(e)||/failed to find expected lines/i.test(e)||/^\s*Error\b/.test(e)||/(?:^|\n)\[Request interrupted by user\]/.test(e)||/modified since (?:last )?read|stale read/i.test(e)||/file (?:is )?too large|exceeds/i.test(e)||/file not found|No such file or directory|does not exist/i.test(e))return{isError:!0,errorText:e.slice(0,500)}}return{isError:!1,errorText:void 0}}b(te,"detectFailure");function oe(t){if(t===null||typeof t!="object")return;const e=t._metadata;if(e===null||typeof e!="object")return;const o=e.toolCallId;if(typeof o=="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(o))return o}b(oe,"extractMetadataToolCallId");function ne(t,e){const o=(0,L.consumeToolUseData)(t,e);if(!o?.start_ns)return null;try{const n=process.hrtime.bigint()-BigInt(o.start_ns);return Number(n/1000000n)}catch(n){return a.logger.debug(`failed to derive duration from stash: ${n}`),null}}b(ne,"deriveDurationMs");async function re(t){const e=(0,d.parseCodexHookStdin)((0,q.readStdin)()),o=e.session_id??"default",n=`${t}/.ironbee/sessions/${o}`,i=`${n}/actions.jsonl`;(0,a.setLogFile)(`${n}/session.log`);const y=e.tool_name??"",s=e.tool_use_id??"",g=e.tool_input,$=g&&typeof g=="object"?{...g,_metadata:void 0}:void 0,C=e.tool_response,l=(0,d.extractCodexMcpServer)(y),z=l==="browser-devtools"||l==="node-devtools"||l==="backend-devtools"||l==="android-devtools",F=ne(o,s),c=(0,d.classifyCodexTool)(y),J=z&&(0,v.isNestedToolContainer)(c.tool_name,l),D=J?(0,v.extractNestedToolCallsFromResponse)(C,l):null,u=D!==null?{isError:!1,errorText:void 0}:te(C);if(z){const w=c.tool_name,f=(0,U.recordingToolsForServer)(l);f!==null&&(w===f.startTool?(0,r.setRecordingActive)(n,!0):w===f.stopTool&&(0,r.setRecordingActive)(n,!1));const E=(0,r.getActiveActivityId)(n),m={...(0,T.baseFields)(i),type:"tool_call",timestamp:Date.now(),tool_type:c.tool_type,tool_name:c.tool_name,mcp_server:c.mcp_server??l,tool_input:$,tool_input_size:A($),tool_response:u.isError?void 0:C,tool_response_size:u.isError?0:A(C),duration:F};E&&(m.activity_id=E);const B=oe(g);B!==void 0?m.id=B:s.length>0&&(m.id=(0,R.deriveToolCallEventIdFromToolUseId)(o,s)),s&&(m.tool_use_id=s);const k=(0,r.getActiveVerificationId)(n);k&&(m.verification_id=k);const I=(0,r.getActiveTraceId)(n);if(I&&(m.trace_id=I),u.isError&&(m.error=u.errorText),await(0,T.appendAction)(i,m),J&&!u.isError){const Y=D??(0,v.extractNestedToolCalls)($??g,l);for(const _ of Y){f!==null&&(_.name===f.startTool?((0,r.setRecordingActive)(n,!0),a.logger.debug(`track-action (nested): recording started (${f.cycle})`)):_.name===f.stopTool&&((0,r.setRecordingActive)(n,!1),a.logger.debug(`track-action (nested): recording stopped (${f.cycle})`)));const S={...(0,T.baseFields)(i),type:"tool_call",timestamp:_.startTime??Date.now(),tool_name:_.name,tool_type:"mcp",tool_input:_.args,duration:_.duration??null,mcp_server:l,nested:!0,...s?{parent_tool_use_id:s}:{}};E&&(S.activity_id=E),k&&(S.verification_id=k),I&&(S.trace_id=I),await(0,T.appendAction)(i,S),a.logger.debug(`track-action (nested): ${_.name}`)}}(0,h.writeAndExit)(JSON.stringify({}),0);return}if(!(0,P.isJobQueueEnabled)(t)){(0,h.writeAndExit)(JSON.stringify({}),0);return}const M=(0,r.getActiveActivityId)(n),H=(0,d.extractCodexToolInput)(y,g),V=A(g),Q=u.isError?0:A(C),p={...(0,T.baseFields)(i),type:"tool_call",timestamp:Date.now(),tool_type:c.tool_type,tool_name:c.tool_name||(0,d.normalizeCodexToolName)(y),mcp_server:c.mcp_server,tool_input:H,tool_input_size:V,tool_response_size:Q,duration:F};M&&(p.activity_id=M),s.length>0&&(p.id=(0,R.deriveToolCallEventIdFromToolUseId)(o,s)),s&&(p.tool_use_id=s);const O=(0,r.getActiveVerificationId)(n);O&&(p.verification_id=O);const j=(0,r.getActiveTraceId)(n);j&&(p.trace_id=j),u.isError&&(p.error=u.errorText);try{(0,x.submit)(t,o,x.SEND_EVENT_TYPE,p)}catch(w){w instanceof x.JobTooLargeError?a.logger.debug(`track-action: wire event too large for tool_call ${y}; dropping`):a.logger.debug(`queue submit failed for tool_call ${y}: ${w}`)}(0,h.writeAndExit)(JSON.stringify({}),0)}b(re,"run");0&&(module.exports={run});
1
+ "use strict";var N=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var W=Object.getOwnPropertyNames;var X=Object.prototype.hasOwnProperty;var b=(t,e)=>N(t,"name",{value:e,configurable:!0});var Z=(t,e)=>{for(var o in e)N(t,o,{get:e[o],enumerable:!0})},ee=(t,e,o,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of W(e))!X.call(t,i)&&i!==o&&N(t,i,{get:()=>e[i],enumerable:!(n=K(e,i))||n.enumerable});return t};var te=t=>ee(N({},"__esModule",{value:!0}),t);var se={};Z(se,{run:()=>ie});module.exports=te(se);var T=require("../../../hooks/core/actions"),v=require("../../../hooks/core/nested-tools"),$=require("../../../import/ids"),L=require("../../../lib/runtime-paths"),r=require("../../../hooks/core/session-state"),P=require("../../../hooks/core/tool-use-stash"),U=require("../../../lib/config"),a=require("../../../lib/logger"),h=require("../../../lib/output"),q=require("../../../lib/recording-tools"),H=require("../../../lib/stdin"),x=require("../../../queue"),d=require("../util");function A(t){if(t==null)return 0;if(typeof t=="string")try{return Buffer.byteLength(t,"utf8")}catch{return 0}try{return Buffer.byteLength(JSON.stringify(t),"utf8")}catch{return 0}}b(A,"safeStringifyBytes");function oe(t){if(t==null)return{isError:!1,errorText:void 0};if(typeof t=="object"&&t!==null){const e=t;if(e.isError===!0||e.is_error===!0){const o=e.error??e.message??e.errorMessage;return{isError:!0,errorText:typeof o=="string"?o:JSON.stringify(e).slice(0,500)}}}if(typeof t=="string"){const e=t;if(/(?:^|\n)Process exited with code [1-9]/.test(e)||/^Exit code:\s*[1-9]/m.test(e)||/apply_patch verification failed/i.test(e)||/failed to find expected lines/i.test(e)||/^\s*Error\b/.test(e)||/(?:^|\n)\[Request interrupted by user\]/.test(e)||/modified since (?:last )?read|stale read/i.test(e)||/file (?:is )?too large|exceeds/i.test(e)||/file not found|No such file or directory|does not exist/i.test(e))return{isError:!0,errorText:e.slice(0,500)}}return{isError:!1,errorText:void 0}}b(oe,"detectFailure");function ne(t){if(t===null||typeof t!="object")return;const e=t._metadata;if(e===null||typeof e!="object")return;const o=e.toolCallId;if(typeof o=="string"&&/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(o))return o}b(ne,"extractMetadataToolCallId");function re(t,e){const o=(0,P.consumeToolUseData)(t,e);if(!o?.start_ns)return null;try{const n=process.hrtime.bigint()-BigInt(o.start_ns);return Number(n/1000000n)}catch(n){return a.logger.debug(`failed to derive duration from stash: ${n}`),null}}b(re,"deriveDurationMs");async function ie(t){const e=(0,d.parseCodexHookStdin)((0,H.readStdin)()),o=e.session_id??"default",n=(0,L.sessionDir)(t,o),i=`${n}/actions.jsonl`;(0,a.setLogFile)(`${n}/session.log`);const y=e.tool_name??"",s=e.tool_use_id??"",g=e.tool_input,R=g&&typeof g=="object"?{...g,_metadata:void 0}:void 0,C=e.tool_response,l=(0,d.extractCodexMcpServer)(y),D=l==="browser-devtools"||l==="node-devtools"||l==="backend-devtools"||l==="android-devtools",z=re(o,s),c=(0,d.classifyCodexTool)(y),F=D&&(0,v.isNestedToolContainer)(c.tool_name,l),J=F?(0,v.extractNestedToolCallsFromResponse)(C,l):null,f=J!==null?{isError:!1,errorText:void 0}:oe(C);if(D){const w=c.tool_name,u=(0,q.recordingToolsForServer)(l);u!==null&&(w===u.startTool?(0,r.setRecordingActive)(n,!0):w===u.stopTool&&(0,r.setRecordingActive)(n,!1));const E=(0,r.getActiveActivityId)(n),m={...(0,T.baseFields)(i),type:"tool_call",timestamp:Date.now(),tool_type:c.tool_type,tool_name:c.tool_name,mcp_server:c.mcp_server??l,tool_input:R,tool_input_size:A(R),tool_response:f.isError?void 0:C,tool_response_size:f.isError?0:A(C),duration:z};E&&(m.activity_id=E);const B=ne(g);B!==void 0?m.id=B:s.length>0&&(m.id=(0,$.deriveToolCallEventIdFromToolUseId)(o,s)),s&&(m.tool_use_id=s);const k=(0,r.getActiveVerificationId)(n);k&&(m.verification_id=k);const S=(0,r.getActiveTraceId)(n);if(S&&(m.trace_id=S),f.isError&&(m.error=f.errorText),await(0,T.appendAction)(i,m),F&&!f.isError){const G=J??(0,v.extractNestedToolCalls)(R??g,l);for(const _ of G){u!==null&&(_.name===u.startTool?((0,r.setRecordingActive)(n,!0),a.logger.debug(`track-action (nested): recording started (${u.cycle})`)):_.name===u.stopTool&&((0,r.setRecordingActive)(n,!1),a.logger.debug(`track-action (nested): recording stopped (${u.cycle})`)));const I={...(0,T.baseFields)(i),type:"tool_call",timestamp:_.startTime??Date.now(),tool_name:_.name,tool_type:"mcp",tool_input:_.args,duration:_.duration??null,mcp_server:l,nested:!0,...s?{parent_tool_use_id:s}:{}};E&&(I.activity_id=E),k&&(I.verification_id=k),S&&(I.trace_id=S),await(0,T.appendAction)(i,I),a.logger.debug(`track-action (nested): ${_.name}`)}}(0,h.writeAndExit)(JSON.stringify({}),0);return}if(!(0,U.isJobQueueEnabled)(t)){(0,h.writeAndExit)(JSON.stringify({}),0);return}const M=(0,r.getActiveActivityId)(n),V=(0,d.extractCodexToolInput)(y,g),Q=A(g),Y=f.isError?0:A(C),p={...(0,T.baseFields)(i),type:"tool_call",timestamp:Date.now(),tool_type:c.tool_type,tool_name:c.tool_name||(0,d.normalizeCodexToolName)(y),mcp_server:c.mcp_server,tool_input:V,tool_input_size:Q,tool_response_size:Y,duration:z};M&&(p.activity_id=M),s.length>0&&(p.id=(0,$.deriveToolCallEventIdFromToolUseId)(o,s)),s&&(p.tool_use_id=s);const O=(0,r.getActiveVerificationId)(n);O&&(p.verification_id=O);const j=(0,r.getActiveTraceId)(n);j&&(p.trace_id=j),f.isError&&(p.error=f.errorText);try{(0,x.submit)(t,o,x.SEND_EVENT_TYPE,p)}catch(w){w instanceof x.JobTooLargeError?a.logger.debug(`track-action: wire event too large for tool_call ${y}; dropping`):a.logger.debug(`queue submit failed for tool_call ${y}: ${w}`)}(0,h.writeAndExit)(JSON.stringify({}),0)}b(ie,"run");0&&(module.exports={run});
@@ -1 +1 @@
1
- "use strict";var c=Object.defineProperty;var I=Object.getOwnPropertyDescriptor;var h=Object.getOwnPropertyNames;var x=Object.prototype.hasOwnProperty;var p=(e,i)=>c(e,"name",{value:i,configurable:!0});var C=(e,i)=>{for(var t in i)c(e,t,{get:i[t],enumerable:!0})},$=(e,i,t,s)=>{if(i&&typeof i=="object"||typeof i=="function")for(let n of h(i))!x.call(e,n)&&n!==t&&c(e,n,{get:()=>i[n],enumerable:!(s=I(i,n))||s.enumerable});return e};var E=e=>$(c({},"__esModule",{value:!0}),e);var _={};C(_,{run:()=>R});module.exports=E(_);var r=require("../../../hooks/core/actions"),y=require("../../../hooks/core/activity"),S=require("../../../hooks/core/verify-gate"),f=require("../../../lib/config"),a=require("../../../lib/logger"),m=require("../../../lib/output"),v=require("../../../lib/stdin"),l=require("../../../queue"),k=require("../../../analytics/codex/spawn"),u=require("../../../hooks/core/session-state"),w=require("../util");async function R(e){const i=(0,w.parseCodexHookStdin)((0,v.readStdin)()),t=i.session_id??"default";(0,a.setLogFile)(`${e}/.ironbee/sessions/${t}/session.log`);const s=`${e}/.ironbee/sessions/${t}`,n=`${s}/actions.jsonl`,g=(0,f.loadConfig)(e),d=await(0,S.runVerifyGate)({sessionId:t,sessionDir:s,actionsFile:n,verdictFile:`${s}/verdict.json`,maxRetries:(0,f.getMaxRetries)(g),config:g,projectDir:e}),b=(0,u.readState)(s)?.activeActivityId??"";if(d.action==="allow"?await(0,y.endActivity)({sessionDir:s,actionsFile:n}):!1){const o=Date.now(),A={...(0,r.baseFields)(n),id:(0,r.deterministicSessionEndId)(t),type:"session_end",timestamp:o,session_id:t,duration:(0,r.findDurationSinceLastAction)(n,"session_start",o),reason:"checkpoint"};await(0,r.appendAction)(n,A)}try{const o=(0,u.readState)(s);(0,k.spawnDetachedCodexAnalyticsWorker)({projectDir:e,sessionId:t,rolloutPath:i.transcript_path,userEmail:o?.userEmail??void 0,usageType:o?.usageType??void 0,usagePlan:o?.usagePlan??void 0,activityId:b})}catch(o){a.logger.debug(`codex analytics spawn failed: ${o instanceof Error?o.message:o}`)}if((0,l.flushInBackground)(e,t),(0,l.flushStragglersInBackground)(e,t),a.logger.debug(`verify-gate: ${d.action}`),d.action==="block"){(0,m.writeAndExit)(JSON.stringify({decision:"block",reason:d.message??"Verification required."}),0);return}(0,m.writeAndExit)(JSON.stringify({}),0)}p(R,"run");0&&(module.exports={run});
1
+ "use strict";var c=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var C=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var y=(e,i)=>c(e,"name",{value:i,configurable:!0});var E=(e,i)=>{for(var t in i)c(e,t,{get:i[t],enumerable:!0})},R=(e,i,t,s)=>{if(i&&typeof i=="object"||typeof i=="function")for(let n of C(i))!b.call(e,n)&&n!==t&&c(e,n,{get:()=>i[n],enumerable:!(s=x(i,n))||s.enumerable});return e};var F=e=>R(c({},"__esModule",{value:!0}),e);var B={};E(B,{run:()=>_});module.exports=F(B);var r=require("../../../hooks/core/actions"),S=require("../../../hooks/core/activity"),v=require("../../../hooks/core/verify-gate"),f=require("../../../lib/config"),a=require("../../../lib/logger"),u=require("../../../lib/output"),k=require("../../../lib/stdin"),m=require("../../../queue"),w=require("../../../analytics/codex/spawn"),g=require("../../../hooks/core/session-state"),A=require("../util"),l=require("../../../lib/runtime-paths");async function _(e){const i=(0,A.parseCodexHookStdin)((0,k.readStdin)()),t=i.session_id??"default";(0,a.setLogFile)((0,l.sessionLogFile)(e,t));const s=(0,l.sessionDir)(e,t),n=`${s}/actions.jsonl`,p=(0,f.loadConfig)(e),d=await(0,v.runVerifyGate)({sessionId:t,sessionDir:s,actionsFile:n,verdictFile:`${s}/verdict.json`,maxRetries:(0,f.getMaxRetries)(p),config:p,projectDir:e}),I=(0,g.readState)(s)?.activeActivityId??"";if(d.action==="allow"?await(0,S.endActivity)({sessionDir:s,actionsFile:n}):!1){const o=Date.now(),h={...(0,r.baseFields)(n),id:(0,r.deterministicSessionEndId)(t),type:"session_end",timestamp:o,session_id:t,duration:(0,r.findDurationSinceLastAction)(n,"session_start",o),reason:"checkpoint"};await(0,r.appendAction)(n,h)}try{const o=(0,g.readState)(s);(0,w.spawnDetachedCodexAnalyticsWorker)({projectDir:e,sessionId:t,rolloutPath:i.transcript_path,userEmail:o?.userEmail??void 0,usageType:o?.usageType??void 0,usagePlan:o?.usagePlan??void 0,activityId:I})}catch(o){a.logger.debug(`codex analytics spawn failed: ${o instanceof Error?o.message:o}`)}if((0,m.flushInBackground)(e,t),(0,m.flushStragglersInBackground)(e,t),a.logger.debug(`verify-gate: ${d.action}`),d.action==="block"){(0,u.writeAndExit)(JSON.stringify({decision:"block",reason:d.message??"Verification required."}),0);return}(0,u.writeAndExit)(JSON.stringify({}),0)}y(_,"run");0&&(module.exports={run});
@@ -1,3 +1,3 @@
1
- "use strict";var R=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var ie=Object.getOwnPropertyNames;var re=Object.prototype.hasOwnProperty;var S=(f,e)=>R(f,"name",{value:e,configurable:!0});var se=(f,e)=>{for(var o in e)R(f,o,{get:e[o],enumerable:!0})},ae=(f,e,o,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of ie(e))!re.call(f,i)&&i!==o&&R(f,i,{get:()=>e[i],enumerable:!(r=te(e,i))||r.enumerable});return f};var le=f=>ae(R({},"__esModule",{value:!0}),f);var me={};se(me,{CodexClient:()=>ge});module.exports=le(me);var s=require("fs"),g=require("path"),K=require("../../lib/gitignore"),p=require("../../lib/logger"),l=require("../../lib/output"),B=require("../../lib/fs-prune"),d=require("../../lib/config"),C=require("../../lib/platform-section"),n=require("./util"),H=require("./thread-map"),U=require("./hooks/verify-gate"),q=require("./hooks/activity-end"),D=require("./hooks/session-start"),X=require("./hooks/activity-start"),W=require("./hooks/require-verification"),Y=require("./hooks/require-verdict"),z=require("./hooks/clear-verdict"),Q=require("./hooks/track-action"),Z=require("./hooks/track-action-monitor"),j=require("./hooks/track-action-pre"),ee=require("./hooks/subagent-start"),oe=require("./hooks/subagent-stop");const E="browser-devtools",A="node-devtools",_="backend-devtools",I="android-devtools",ce="ironbee",$="ironbee-verifier",V=30,N="Verifies recent code changes through real browser/runtime/backend tools and submits the IronBee verdict. Spawn this custom agent (by agent_type) after editing code to run the verification cycle out-of-band \u2014 it drives the devtools tools, judges the result, and records the verdict in the shared session. It does NOT edit code.",x="ironbee-scenario",L=["ironbee-manage-scenario","ironbee-search-scenario","ironbee-sync-scenario"],J="Manages and searches reusable IronBee verification scenarios via the devtools scenario tools. Spawn this custom agent (by agent_type) from the scenario slash commands to author/update/delete saved scenarios and find them by name/description/metadata. NOT a verification cycle (running a saved scenario to verify is done via $ironbee-verify scenario:<name>).";function P(f){return(0,g.join)(__dirname,"..",f,"platforms")}S(P,"platformsDirFor");function y(f){return l.pc.dim(f)}S(y,"codexColor");function F(f){return f.hooks.some(e=>e.command.includes(ce))}S(F,"isIronBeeHookGroup");function de(f){const e=Object.keys(f);return e.length===0?!0:e.length===1&&e[0]==="hooks"?Object.keys(f.hooks??{}).length===0:!1}S(de,"isCodexHooksEmpty");class ge{constructor(){this.name="codex";this.supportsVerifierModel=!0}static{S(this,"CodexClient")}detect(e){return(0,s.existsSync)((0,g.join)(e,".agents","skills","ironbee-verify"))}resolveProjectDir(){return process.env.CODEX_PROJECT_DIR??process.env.IRONBEE_PROJECT_DIR??process.cwd()}install(e,o){const r=o??(0,d.loadConfig)(e),i=(0,d.getVerificationMode)(r),t=i!=="monitor",a=(0,d.getCodexVerifierMode)(r);this.cleanupArtifacts(e);const m=(0,n.codexHooksJsonPath)(e);if(this.mergeHooksConfig(m,i,a),this.mergeConfigToml(e,r,t,a),t&&(i==="enforce"&&this.writeAgentsMdBlock(e,r,a),this.writeSkills(e,i==="enforce",r,a),(0,C.syncPlatformSectionsToConfig)(e,P)),(0,K.ensureIronBeeGitignored)(e),console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} hooks ${l.pc.dim("\u2192")} ${l.pc.dim(m)}`),console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} config ${l.pc.dim("\u2192")} ${l.pc.dim((0,n.codexConfigTomlPath)(e))}`),t){const b=a==="main-agent"?`${l.pc.yellow("main-agent")} (the main agent drives the devtools tools directly)`:`${l.pc.bold("sub-agent")} (delegated to the ironbee-verifier custom agent)`;console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} verify ${l.pc.dim("\u2192")} ${b}`)}i==="enforce"?(console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} agents ${l.pc.dim("\u2192")} ${l.pc.dim((0,g.join)(e,"AGENTS.md"))}`),console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} skill ${l.pc.dim("\u2192")} ${l.pc.dim((0,g.join)(e,".agents","skills","ironbee-verification","SKILL.md"))}`),console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} command ${l.pc.dim("\u2192")} ${l.pc.dim((0,g.join)(e,".agents","skills","ironbee-verify","SKILL.md"))}`)):i==="assist"?(console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} ${l.pc.yellow("assist mode")} (verification.auto: false) \u2014 manual $ironbee-verify only, no enforcement`),console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} command ${l.pc.dim("\u2192")} ${l.pc.dim((0,g.join)(e,".agents","skills","ironbee-verify","SKILL.md"))}`)):console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} ${l.pc.yellow("monitoring-only mode")} (verification.enable: false)`),console.log(),console.log(` ${l.pc.yellow("\u26A0")} ${l.pc.yellow("Codex requires one-time TUI setup:")}`),console.log(` ${l.pc.yellow("1.")} Run ${l.pc.bold("/hooks")} in a fresh Codex session to review and trust IronBee hooks`),console.log(` ${l.pc.yellow("2.")} Restart any open Codex sessions to pick up new hook config`)}uninstall(e){this.cleanupArtifacts(e),(0,s.existsSync)((0,n.codexHooksJsonPath)(e))||this.removeFeaturesHooksFlag(e),(0,B.pruneEmptyDirs)((0,g.join)(e,".codex"));const o=(0,H.codexThreadMapPath)(e);if((0,s.existsSync)(o))try{(0,s.unlinkSync)(o)}catch(r){p.logger.debug(`failed to remove codex thread map: ${r}`)}console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} removed hooks, MCP entries, AGENTS.md block, and skills`)}removeFeaturesHooksFlag(e){const o=(0,n.codexConfigTomlPath)(e);if((0,s.existsSync)(o))try{const r=(0,s.readFileSync)(o,"utf-8"),i=(0,n.removeFeaturesHooks)(r);i.trim().length===0?(0,s.unlinkSync)(o):i!==r&&(0,s.writeFileSync)(o,i)}catch(r){p.logger.debug(`failed to strip [features] hooks from config.toml: ${r}`)}}cleanupArtifacts(e){this.migrateAwayFromUserLevel();const o=(0,n.codexHooksJsonPath)(e);this.removeIronBeeHooks(o),this.maybeDeleteEmptyHooks(o),this.removeIronBeeMcpServers(e),this.removeVerifierAgentToml(e),this.removeScenarioAgentToml(e);const r=(0,g.join)(e,"AGENTS.md");if((0,s.existsSync)(r))try{const t=(0,s.readFileSync)(r,"utf-8"),a=(0,n.stripAgentsMdBlock)(t);a===null?(0,s.unlinkSync)(r):a!==t&&(0,s.writeFileSync)(r,a)}catch(t){p.logger.debug(`failed to strip AGENTS.md block: ${t}`)}const i=(0,g.join)(e,".agents","skills");this.removeDir((0,g.join)(i,"ironbee-verification")),this.removeDir((0,g.join)(i,"ironbee-verify"));for(const t of L)this.removeDir((0,g.join)(i,t));this.removeDir((0,g.join)(i,"ironbee-run-scenario")),(0,B.pruneEmptyDirs)((0,g.join)(e,".agents"))}async runVerifyGate(e){await(0,U.run)(e)}async runActivityEnd(e){await(0,q.run)(e)}async runSessionStart(e){await(0,D.run)(e)}async runActivityStart(e){await(0,X.run)(e)}async runRequireVerification(e,o){await(0,W.run)(e,o)}async runRequireVerdict(e,o){await(0,Y.run)(e,o)}async runClearVerdict(e){await(0,z.run)(e)}async runTrackAction(e){await(0,Q.run)(e)}async runTrackActionMonitor(e){await(0,Z.run)(e)}async runTrackActionPre(e){await(0,j.run)(e)}async runSubagentStart(e){await(0,ee.run)(e)}async runSubagentStop(e){await(0,oe.run)(e)}resolveAgentSessionId(e,o){const r=process.env.CODEX_THREAD_ID;if(typeof r=="string"&&r.length>0&&o)return(0,H.lookupThreadSession)(o,r)}async runSessionEnd(e){p.logger.debug("session-end: no-op on Codex (no SessionEnd hook event)")}mergeHooksConfig(e,o,r){const i=o!=="monitor",t=o==="assist"?" --soft":"";(0,s.mkdirSync)((0,g.dirname)(e),{recursive:!0});let a={hooks:{}};if((0,s.existsSync)(e))try{a=JSON.parse((0,s.readFileSync)(e,"utf-8")),a.hooks||(a.hooks={})}catch(v){p.logger.debug(`failed to parse ${e}: ${v}`),a={hooks:{}}}for(const v of Object.keys(a.hooks)){const c=a.hooks[v].filter(h=>!F(h));c.length===0?delete a.hooks[v]:a.hooks[v]=c}const m=S((v,c,h)=>{a.hooks[v]||(a.hooks[v]=[]),a.hooks[v].push({matcher:c,hooks:[{type:"command",command:h}]})},"addGroup");m("SessionStart",".*","ironbee hook session-start --client codex"),m("UserPromptSubmit",".*","ironbee hook activity-start --client codex"),m("PreToolUse",".*","ironbee hook track-action-pre --client codex"),i&&(m("PreToolUse","^mcp__(browser|node|backend|android)[-_]devtools__.*",`ironbee hook require-verification --client codex${t}`),m("PreToolUse","^apply_patch$",`ironbee hook require-verdict --client codex${t}`),m("PostToolUse","^apply_patch$","ironbee hook clear-verdict --client codex"),r==="sub-agent"&&m("SubagentStart",".*","ironbee hook subagent-start --client codex")),m("SubagentStop",".*","ironbee hook subagent-stop --client codex"),m("PostToolUse",".*",i?"ironbee hook track-action --client codex":"ironbee hook track-action-monitor --client codex"),m("Stop",".*",o==="enforce"?"ironbee hook verify-gate --client codex":"ironbee hook activity-end --client codex"),(0,s.writeFileSync)(e,JSON.stringify(a,null,2))}removeIronBeeHooks(e){if((0,s.existsSync)(e))try{const o=(0,s.readFileSync)(e,"utf-8"),r=JSON.parse(o);if(!r.hooks)return;let i=!1;for(const t of Object.keys(r.hooks)){const a=r.hooks[t].filter(m=>!F(m));a.length!==r.hooks[t].length&&(i=!0),a.length===0?delete r.hooks[t]:r.hooks[t]=a}i&&(0,s.writeFileSync)(e,JSON.stringify(r,null,2))}catch(o){p.logger.debug(`failed to strip IronBee hooks from ${e}: ${o}`)}}maybeDeleteEmptyHooks(e){if((0,s.existsSync)(e))try{const o=JSON.parse((0,s.readFileSync)(e,"utf-8"));de(o)&&(0,s.unlinkSync)(e)}catch(o){p.logger.debug(`failed to inspect ${e} for emptiness: ${o}`)}}mergeConfigToml(e,o,r,i){(0,s.mkdirSync)((0,g.join)(e,".codex"),{recursive:!0});let t=(0,n.readCodexConfigToml)(e);if(t=(0,n.ensureFeaturesHooksTrue)(t),t=(0,n.removeMcpServer)(t,E),t=(0,n.removeMcpServer)(t,A),t=(0,n.removeMcpServer)(t,_),t=(0,n.removeMcpServer)(t,I),r&&i==="main-agent"){t=this.upsertSessionMcpServers(t,e,o),t=(0,n.removeAgentsTable)(t,$),t=(0,n.removeAgentsTable)(t,x),t=(0,n.removeMultiAgentV2SpawnMetadata)(t),this.removeVerifierAgentToml(e),this.removeScenarioAgentToml(e),(0,n.writeCodexConfigToml)(e,t);return}if(r){const a=(0,d.getVerificationModel)(o,"codex"),m=(0,s.existsSync)((0,n.userCodexConfigTomlPath)())?(0,s.readFileSync)((0,n.userCodexConfigTomlPath)(),"utf-8"):"",b=(0,n.extractTomlTopLevelModel)(t)===null&&(0,n.extractTomlTopLevelModel)(m)===null;a===void 0&&b&&console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} ${l.pc.yellow("\u26A0 no model for the verifier")} \u2014 the ${l.pc.bold("ironbee-verifier")} sub-agent inherits the session model, but neither this project's .codex/config.toml nor ~/.codex/config.toml has a top-level ${l.pc.bold("model")}, so it may fail to spawn ("could not resolve the child model"). Fix: set ${l.pc.bold("model")} in ~/.codex/config.toml, or set ${l.pc.bold("verification.model")} in your ironbee config.`),this.writeVerifierAgentToml(e,o,a),t=(0,n.upsertAgentsTable)(t,$,[`description = ${JSON.stringify(N)}`,`config_file = ${JSON.stringify(`agents/${$}.toml`)}`]),t=(0,n.ensureMultiAgentV2SpawnMetadataExposed)(t),this.writeScenarioAgentToml(e,o,a),t=(0,n.upsertAgentsTable)(t,x,[`description = ${JSON.stringify(J)}`,`config_file = ${JSON.stringify(`agents/${x}.toml`)}`])}else t=(0,n.removeAgentsTable)(t,$),t=(0,n.removeAgentsTable)(t,x),t=(0,n.removeMultiAgentV2SpawnMetadata)(t),this.removeVerifierAgentToml(e),this.removeScenarioAgentToml(e);(0,n.writeCodexConfigToml)(e,t)}writeVerifierAgentToml(e,o,r){this.writeCustomAgentToml(e,o,r,$,N,"skill","read-only")}writeScenarioAgentToml(e,o,r){this.writeCustomAgentToml(e,o,r,x,J,"scenario","read-only")}writeCustomAgentToml(e,o,r,i,t,a,m){const b=(0,g.join)(__dirname,"agents",`${i}.md`);let u;try{u=(0,s.readFileSync)(b,"utf-8")}catch(k){p.logger.debug(`failed to read agent source ${b}: ${k}`);return}const v=P("codex");for(const k of d.ALL_CYCLES){const w=(0,d.isCycleEnabled)(o,k)?ne=>{const O=(0,g.join)(v,(0,C.fragmentFilename)(a,k,ne));return(0,s.existsSync)(O)?(0,s.readFileSync)(O,"utf-8").trimEnd():null}:null;u=(0,C.applyPlatformSection)(u,k,w,`${i}.toml`)}const c=[];c.push(`name = ${JSON.stringify(i)}`),c.push(`description = ${JSON.stringify(t)}`),c.push(`sandbox_mode = ${JSON.stringify(m)}`),r&&c.push(`model = ${JSON.stringify(r)}`),c.push("developer_instructions = '''"),c.push(u.replace(/'''/g,"```").trimEnd()),c.push("'''");const h=S((k,T,w)=>{k&&(c.push(""),c.push(`[mcp_servers.${T}]`),c.push(...G(w)),c.push(`startup_timeout_sec = ${V}`),c.push("required = true"),c.push('default_tools_approval_mode = "approve"'))},"addCycle");h((0,d.isCycleEnabled)(o,"browser"),E,(0,d.getMcpServerEntry)(e)),h((0,d.isCycleEnabled)(o,"node"),A,(0,d.getNodeDevToolsMcpEntry)(e)),h((0,d.isCycleEnabled)(o,"backend"),_,(0,d.getBackendDevToolsMcpEntry)(e)),h((0,d.isCycleEnabled)(o,"android"),I,(0,d.getAndroidDevToolsMcpEntry)(e));const M=(0,n.codexAgentTomlPath)(e,i);(0,s.mkdirSync)((0,g.dirname)(M),{recursive:!0}),(0,s.writeFileSync)(M,c.join(`
1
+ "use strict";var M=Object.defineProperty;var re=Object.getOwnPropertyDescriptor;var se=Object.getOwnPropertyNames;var ae=Object.prototype.hasOwnProperty;var S=(f,e)=>M(f,"name",{value:e,configurable:!0});var le=(f,e)=>{for(var o in e)M(f,o,{get:e[o],enumerable:!0})},ce=(f,e,o,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of se(e))!ae.call(f,i)&&i!==o&&M(f,i,{get:()=>e[i],enumerable:!(r=re(e,i))||r.enumerable});return f};var de=f=>ce(M({},"__esModule",{value:!0}),f);var fe={};le(fe,{CodexClient:()=>ue});module.exports=de(fe);var s=require("fs"),m=require("path"),U=require("../../lib/gitignore"),b=require("../../lib/logger"),l=require("../../lib/output"),O=require("../../lib/fs-prune"),d=require("../../lib/config"),C=require("../../lib/platform-section"),n=require("./util"),H=require("./thread-map"),q=require("../../lib/runtime-paths"),W=require("./hooks/verify-gate"),D=require("./hooks/activity-end"),X=require("./hooks/session-start"),Y=require("./hooks/activity-start"),z=require("./hooks/require-verification"),Q=require("./hooks/require-verdict"),Z=require("./hooks/clear-verdict"),j=require("./hooks/track-action"),ee=require("./hooks/track-action-monitor"),oe=require("./hooks/track-action-pre"),ne=require("./hooks/subagent-start"),te=require("./hooks/subagent-stop");const B="~/.ironbee/projects",E="browser-devtools",A="node-devtools",_="backend-devtools",I="android-devtools",ge="ironbee",$="ironbee-verifier",V=30,L="Verifies recent code changes through real browser/runtime/backend tools and submits the IronBee verdict. Spawn this custom agent (by agent_type) after editing code to run the verification cycle out-of-band \u2014 it drives the devtools tools, judges the result, and records the verdict in the shared session. It does NOT edit code.",x="ironbee-scenario",J=["ironbee-manage-scenario","ironbee-search-scenario","ironbee-sync-scenario"],F="Manages and searches reusable IronBee verification scenarios via the devtools scenario tools. Spawn this custom agent (by agent_type) from the scenario slash commands to author/update/delete saved scenarios and find them by name/description/metadata. NOT a verification cycle (running a saved scenario to verify is done via $ironbee-verify scenario:<name>).";function P(f){return(0,m.join)(__dirname,"..",f,"platforms")}S(P,"platformsDirFor");function y(f){return l.pc.dim(f)}S(y,"codexColor");function G(f){return f.hooks.some(e=>e.command.includes(ge))}S(G,"isIronBeeHookGroup");function me(f){const e=Object.keys(f);return e.length===0?!0:e.length===1&&e[0]==="hooks"?Object.keys(f.hooks??{}).length===0:!1}S(me,"isCodexHooksEmpty");class ue{constructor(){this.name="codex";this.supportsVerifierModel=!0}static{S(this,"CodexClient")}detect(e){return(0,s.existsSync)((0,m.join)(e,".agents","skills","ironbee-verify"))}resolveProjectDir(){return process.env.CODEX_PROJECT_DIR??process.env.IRONBEE_PROJECT_DIR??process.cwd()}install(e,o){const r=o??(0,d.loadConfig)(e),i=(0,d.getVerificationMode)(r),t=i!=="monitor",a=(0,d.getCodexVerifierMode)(r);this.cleanupArtifacts(e);const g=(0,n.codexHooksJsonPath)(e);if(this.mergeHooksConfig(g,i,a),this.mergeConfigToml(e,r,t,a),t&&(i==="enforce"&&this.writeAgentsMdBlock(e,r,a),this.writeSkills(e,i==="enforce",r,a),(0,C.syncPlatformSectionsToConfig)(e,P)),(0,U.ensureIronBeeGitignored)(e),console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} hooks ${l.pc.dim("\u2192")} ${l.pc.dim(g)}`),console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} config ${l.pc.dim("\u2192")} ${l.pc.dim((0,n.codexConfigTomlPath)(e))}`),t){const p=a==="main-agent"?`${l.pc.yellow("main-agent")} (the main agent drives the devtools tools directly)`:`${l.pc.bold("sub-agent")} (delegated to the ironbee-verifier custom agent)`;console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} verify ${l.pc.dim("\u2192")} ${p}`)}i==="enforce"?(console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} agents ${l.pc.dim("\u2192")} ${l.pc.dim((0,m.join)(e,"AGENTS.md"))}`),console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} skill ${l.pc.dim("\u2192")} ${l.pc.dim((0,m.join)(e,".agents","skills","ironbee-verification","SKILL.md"))}`),console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} command ${l.pc.dim("\u2192")} ${l.pc.dim((0,m.join)(e,".agents","skills","ironbee-verify","SKILL.md"))}`)):i==="assist"?(console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} ${l.pc.yellow("assist mode")} (verification.auto: false) \u2014 manual $ironbee-verify only, no enforcement`),console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} command ${l.pc.dim("\u2192")} ${l.pc.dim((0,m.join)(e,".agents","skills","ironbee-verify","SKILL.md"))}`)):console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} ${l.pc.yellow("monitoring-only mode")} (verification.enable: false)`),console.log(),console.log(` ${l.pc.yellow("\u26A0")} ${l.pc.yellow("Codex requires one-time TUI setup:")}`),console.log(` ${l.pc.yellow("1.")} Run ${l.pc.bold("/hooks")} in a fresh Codex session to review and trust IronBee hooks`),console.log(` ${l.pc.yellow("2.")} Restart any open Codex sessions to pick up new hook config`)}uninstall(e){this.cleanupArtifacts(e),(0,s.existsSync)((0,n.codexHooksJsonPath)(e))||this.removeFeaturesHooksFlag(e),(0,O.pruneEmptyDirs)((0,m.join)(e,".codex"));const o=(0,H.codexThreadMapPath)(e);if((0,s.existsSync)(o))try{(0,s.unlinkSync)(o)}catch(r){b.logger.debug(`failed to remove codex thread map: ${r}`)}console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} removed hooks, MCP entries, AGENTS.md block, and skills`)}removeFeaturesHooksFlag(e){const o=(0,n.codexConfigTomlPath)(e);if((0,s.existsSync)(o))try{const r=(0,s.readFileSync)(o,"utf-8");let i=(0,n.removeFeaturesHooks)(r);i=(0,n.removeSandboxWritableRoot)(i,B),i.trim().length===0?(0,s.unlinkSync)(o):i!==r&&(0,s.writeFileSync)(o,i)}catch(r){b.logger.debug(`failed to strip [features] hooks from config.toml: ${r}`)}}cleanupArtifacts(e){this.migrateAwayFromUserLevel();const o=(0,n.codexHooksJsonPath)(e);this.removeIronBeeHooks(o),this.maybeDeleteEmptyHooks(o),this.removeIronBeeMcpServers(e),this.removeVerifierAgentToml(e),this.removeScenarioAgentToml(e);const r=(0,m.join)(e,"AGENTS.md");if((0,s.existsSync)(r))try{const t=(0,s.readFileSync)(r,"utf-8"),a=(0,n.stripAgentsMdBlock)(t);a===null?(0,s.unlinkSync)(r):a!==t&&(0,s.writeFileSync)(r,a)}catch(t){b.logger.debug(`failed to strip AGENTS.md block: ${t}`)}const i=(0,m.join)(e,".agents","skills");this.removeDir((0,m.join)(i,"ironbee-verification")),this.removeDir((0,m.join)(i,"ironbee-verify"));for(const t of J)this.removeDir((0,m.join)(i,t));this.removeDir((0,m.join)(i,"ironbee-run-scenario")),(0,O.pruneEmptyDirs)((0,m.join)(e,".agents"))}async runVerifyGate(e){await(0,W.run)(e)}async runActivityEnd(e){await(0,D.run)(e)}async runSessionStart(e){await(0,X.run)(e)}async runActivityStart(e){await(0,Y.run)(e)}async runRequireVerification(e,o){await(0,z.run)(e,o)}async runRequireVerdict(e,o){await(0,Q.run)(e,o)}async runClearVerdict(e){await(0,Z.run)(e)}async runTrackAction(e){await(0,j.run)(e)}async runTrackActionMonitor(e){await(0,ee.run)(e)}async runTrackActionPre(e){await(0,oe.run)(e)}async runSubagentStart(e){await(0,ne.run)(e)}async runSubagentStop(e){await(0,te.run)(e)}resolveAgentSessionId(e,o){const r=process.env.CODEX_THREAD_ID;if(typeof r=="string"&&r.length>0&&o)return(0,H.lookupThreadSession)(o,r)}async runSessionEnd(e){b.logger.debug("session-end: no-op on Codex (no SessionEnd hook event)")}mergeHooksConfig(e,o,r){const i=o!=="monitor",t=o==="assist"?" --soft":"";(0,s.mkdirSync)((0,m.dirname)(e),{recursive:!0});let a={hooks:{}};if((0,s.existsSync)(e))try{a=JSON.parse((0,s.readFileSync)(e,"utf-8")),a.hooks||(a.hooks={})}catch(v){b.logger.debug(`failed to parse ${e}: ${v}`),a={hooks:{}}}for(const v of Object.keys(a.hooks)){const c=a.hooks[v].filter(h=>!G(h));c.length===0?delete a.hooks[v]:a.hooks[v]=c}const g=S((v,c,h)=>{a.hooks[v]||(a.hooks[v]=[]),a.hooks[v].push({matcher:c,hooks:[{type:"command",command:h}]})},"addGroup");g("SessionStart",".*","ironbee hook session-start --client codex"),g("UserPromptSubmit",".*","ironbee hook activity-start --client codex"),g("PreToolUse",".*","ironbee hook track-action-pre --client codex"),i&&(g("PreToolUse","^mcp__(browser|node|backend|android)[-_]devtools__.*",`ironbee hook require-verification --client codex${t}`),g("PreToolUse","^apply_patch$",`ironbee hook require-verdict --client codex${t}`),g("PostToolUse","^apply_patch$","ironbee hook clear-verdict --client codex"),r==="sub-agent"&&g("SubagentStart",".*","ironbee hook subagent-start --client codex")),g("SubagentStop",".*","ironbee hook subagent-stop --client codex"),g("PostToolUse",".*",i?"ironbee hook track-action --client codex":"ironbee hook track-action-monitor --client codex"),g("Stop",".*",o==="enforce"?"ironbee hook verify-gate --client codex":"ironbee hook activity-end --client codex"),(0,s.writeFileSync)(e,JSON.stringify(a,null,2))}removeIronBeeHooks(e){if((0,s.existsSync)(e))try{const o=(0,s.readFileSync)(e,"utf-8"),r=JSON.parse(o);if(!r.hooks)return;let i=!1;for(const t of Object.keys(r.hooks)){const a=r.hooks[t].filter(g=>!G(g));a.length!==r.hooks[t].length&&(i=!0),a.length===0?delete r.hooks[t]:r.hooks[t]=a}i&&(0,s.writeFileSync)(e,JSON.stringify(r,null,2))}catch(o){b.logger.debug(`failed to strip IronBee hooks from ${e}: ${o}`)}}maybeDeleteEmptyHooks(e){if((0,s.existsSync)(e))try{const o=JSON.parse((0,s.readFileSync)(e,"utf-8"));me(o)&&(0,s.unlinkSync)(e)}catch(o){b.logger.debug(`failed to inspect ${e} for emptiness: ${o}`)}}mergeConfigToml(e,o,r,i){(0,s.mkdirSync)((0,m.join)(e,".codex"),{recursive:!0});let t=(0,n.readCodexConfigToml)(e);if(t=(0,n.ensureFeaturesHooksTrue)(t),t=r&&(0,q.resolveRuntimeLocation)(e)==="external"?(0,n.ensureSandboxWritableRoot)(t,B):(0,n.removeSandboxWritableRoot)(t,B),t=(0,n.removeMcpServer)(t,E),t=(0,n.removeMcpServer)(t,A),t=(0,n.removeMcpServer)(t,_),t=(0,n.removeMcpServer)(t,I),r&&i==="main-agent"){t=this.upsertSessionMcpServers(t,e,o),t=(0,n.removeAgentsTable)(t,$),t=(0,n.removeAgentsTable)(t,x),t=(0,n.removeMultiAgentV2SpawnMetadata)(t),this.removeVerifierAgentToml(e),this.removeScenarioAgentToml(e),(0,n.writeCodexConfigToml)(e,t);return}if(r){const g=(0,d.getVerificationModel)(o,"codex"),p=(0,s.existsSync)((0,n.userCodexConfigTomlPath)())?(0,s.readFileSync)((0,n.userCodexConfigTomlPath)(),"utf-8"):"",u=(0,n.extractTomlTopLevelModel)(t)===null&&(0,n.extractTomlTopLevelModel)(p)===null;g===void 0&&u&&console.log(` ${l.pc.dim("\u2192")} ${y("[codex]")} ${l.pc.yellow("\u26A0 no model for the verifier")} \u2014 the ${l.pc.bold("ironbee-verifier")} sub-agent inherits the session model, but neither this project's .codex/config.toml nor ~/.codex/config.toml has a top-level ${l.pc.bold("model")}, so it may fail to spawn ("could not resolve the child model"). Fix: set ${l.pc.bold("model")} in ~/.codex/config.toml, or set ${l.pc.bold("verification.model")} in your ironbee config.`),this.writeVerifierAgentToml(e,o,g),t=(0,n.upsertAgentsTable)(t,$,[`description = ${JSON.stringify(L)}`,`config_file = ${JSON.stringify(`agents/${$}.toml`)}`]),t=(0,n.ensureMultiAgentV2SpawnMetadataExposed)(t),this.writeScenarioAgentToml(e,o,g),t=(0,n.upsertAgentsTable)(t,x,[`description = ${JSON.stringify(F)}`,`config_file = ${JSON.stringify(`agents/${x}.toml`)}`])}else t=(0,n.removeAgentsTable)(t,$),t=(0,n.removeAgentsTable)(t,x),t=(0,n.removeMultiAgentV2SpawnMetadata)(t),this.removeVerifierAgentToml(e),this.removeScenarioAgentToml(e);(0,n.writeCodexConfigToml)(e,t)}writeVerifierAgentToml(e,o,r){this.writeCustomAgentToml(e,o,r,$,L,"skill","read-only")}writeScenarioAgentToml(e,o,r){this.writeCustomAgentToml(e,o,r,x,F,"scenario","read-only")}writeCustomAgentToml(e,o,r,i,t,a,g){const p=(0,m.join)(__dirname,"agents",`${i}.md`);let u;try{u=(0,s.readFileSync)(p,"utf-8")}catch(k){b.logger.debug(`failed to read agent source ${p}: ${k}`);return}const v=P("codex");for(const k of d.ALL_CYCLES){const w=(0,d.isCycleEnabled)(o,k)?ie=>{const N=(0,m.join)(v,(0,C.fragmentFilename)(a,k,ie));return(0,s.existsSync)(N)?(0,s.readFileSync)(N,"utf-8").trimEnd():null}:null;u=(0,C.applyPlatformSection)(u,k,w,`${i}.toml`)}const c=[];c.push(`name = ${JSON.stringify(i)}`),c.push(`description = ${JSON.stringify(t)}`),c.push(`sandbox_mode = ${JSON.stringify(g)}`),r&&c.push(`model = ${JSON.stringify(r)}`),c.push("developer_instructions = '''"),c.push(u.replace(/'''/g,"```").trimEnd()),c.push("'''");const h=S((k,T,w)=>{k&&(c.push(""),c.push(`[mcp_servers.${T}]`),c.push(...K(w)),c.push(`startup_timeout_sec = ${V}`),c.push("required = true"),c.push('default_tools_approval_mode = "approve"'))},"addCycle");h((0,d.isCycleEnabled)(o,"browser"),E,(0,d.getMcpServerEntry)(e)),h((0,d.isCycleEnabled)(o,"node"),A,(0,d.getNodeDevToolsMcpEntry)(e)),h((0,d.isCycleEnabled)(o,"backend"),_,(0,d.getBackendDevToolsMcpEntry)(e)),h((0,d.isCycleEnabled)(o,"android"),I,(0,d.getAndroidDevToolsMcpEntry)(e));const R=(0,n.codexAgentTomlPath)(e,i);(0,s.mkdirSync)((0,m.dirname)(R),{recursive:!0}),(0,s.writeFileSync)(R,c.join(`
2
2
  `)+`
3
- `)}upsertSessionMcpServers(e,o,r){let i=e;const t=S((a,m,b)=>{if(!a)return;const u=[...G(b),`startup_timeout_sec = ${V}`,'default_tools_approval_mode = "approve"'];i=(0,n.upsertMcpServer)(i,m,u)},"addCycle");return t((0,d.isCycleEnabled)(r,"browser"),E,(0,d.getMcpServerEntry)(o)),t((0,d.isCycleEnabled)(r,"node"),A,(0,d.getNodeDevToolsMcpEntry)(o)),t((0,d.isCycleEnabled)(r,"backend"),_,(0,d.getBackendDevToolsMcpEntry)(o)),t((0,d.isCycleEnabled)(r,"android"),I,(0,d.getAndroidDevToolsMcpEntry)(o)),i}removeVerifierAgentToml(e){const o=(0,n.codexAgentTomlPath)(e,$);if((0,s.existsSync)(o))try{(0,s.unlinkSync)(o)}catch(r){p.logger.debug(`failed to remove verifier agent toml: ${r}`)}}removeScenarioAgentToml(e){const o=(0,n.codexAgentTomlPath)(e,x);if((0,s.existsSync)(o))try{(0,s.unlinkSync)(o)}catch(r){p.logger.debug(`failed to remove scenario agent toml: ${r}`)}}removeIronBeeMcpServers(e){let o=(0,n.readCodexConfigToml)(e);o&&(o=(0,n.removeMcpServer)(o,E),o=(0,n.removeMcpServer)(o,A),o=(0,n.removeMcpServer)(o,_),o=(0,n.removeMcpServer)(o,I),o=(0,n.removeAgentsTable)(o,$),o=(0,n.removeAgentsTable)(o,x),o=(0,n.removeMultiAgentV2SpawnMetadata)(o),(0,n.writeCodexConfigToml)(e,o))}migrateAwayFromUserLevel(){const e=(0,n.userCodexHooksJsonPath)();this.removeIronBeeHooks(e),this.maybeDeleteEmptyHooks(e);const o=(0,n.userCodexConfigTomlPath)();if((0,s.existsSync)(o))try{let i=(0,s.readFileSync)(o,"utf-8");const t=i;i=(0,n.removeMcpServer)(i,E),i=(0,n.removeMcpServer)(i,A),i=(0,n.removeMcpServer)(i,_),i=(0,n.removeMcpServer)(i,I),i=(0,n.removeAgentsTable)(i,$),i=(0,n.removeMultiAgentV2SpawnMetadata)(i),i!==t&&(0,s.writeFileSync)(o,i)}catch(i){p.logger.debug(`migrate: failed to clean user-level config.toml: ${i}`)}const r=(0,n.userCodexAgentTomlPath)($);if((0,s.existsSync)(r))try{(0,s.unlinkSync)(r)}catch(i){p.logger.debug(`migrate: failed to remove user-level verifier toml: ${i}`)}}writeAgentsMdBlock(e,o,r){const i=(0,g.join)(e,"AGENTS.md"),t=r==="main-agent"?"ironbee-verification.main.md":"ironbee-verification.md",a=(0,g.join)(__dirname,"rules",t);let m;try{m=(0,s.readFileSync)(a,"utf-8")}catch(c){p.logger.debug(`failed to read rule source ${a}: ${c}`);return}const b=P("codex");for(const c of d.ALL_CYCLES){const M=(0,d.isCycleEnabled)(o,c)?k=>{const T=(0,g.join)(b,(0,C.fragmentFilename)("rule",c,k));if(!(0,s.existsSync)(T)){const w=k.length>0?`${c}:${k}`:c;return p.logger.debug(`AGENTS.md platform-section ${w}: missing fragment ${T}, using placeholder`),null}return(0,s.readFileSync)(T,"utf-8").trimEnd()}:null;m=(0,C.applyPlatformSection)(m,c,M,"AGENTS.md")}const u=(0,s.existsSync)(i)?(0,s.readFileSync)(i,"utf-8"):"",v=(0,n.upsertAgentsMdBlock)(u,m);(0,s.writeFileSync)(i,v)}writeSkills(e,o,r,i){const t=(0,g.join)(e,".agents","skills"),a=i==="main-agent";if(o){const u=(0,g.join)(t,"ironbee-verification");(0,s.mkdirSync)(u,{recursive:!0});const v=(0,g.join)(__dirname,"skills",a?"ironbee-verification.main.md":"ironbee-verification.md");try{let c=(0,s.readFileSync)(v,"utf-8");a&&(c=this.spliceCycleFragments(c,"skill",r,"ironbee-verification/SKILL.md")),(0,s.writeFileSync)((0,g.join)(u,"SKILL.md"),c)}catch(c){p.logger.debug(`failed to copy skill ${v}: ${c}`)}}const m=(0,g.join)(t,"ironbee-verify");(0,s.mkdirSync)(m,{recursive:!0});const b=(0,g.join)(__dirname,"commands","ironbee-verify",a?"SKILL.main.md":"SKILL.md");try{let u=(0,s.readFileSync)(b,"utf-8");a&&(u=this.spliceCycleFragments(u,"command-verify",r,"ironbee-verify/SKILL.md")),(0,s.writeFileSync)((0,g.join)(m,"SKILL.md"),u)}catch(u){p.logger.debug(`failed to copy verify command ${b}: ${u}`)}for(const u of L){const v=(0,g.join)(t,u);(0,s.mkdirSync)(v,{recursive:!0});const c=(0,g.join)(__dirname,"commands",u,a?"SKILL.main.md":"SKILL.md");try{let h=(0,s.readFileSync)(c,"utf-8");a&&(h=this.spliceCycleFragments(h,"scenario",r,`${u}/SKILL.md`)),(0,s.writeFileSync)((0,g.join)(v,"SKILL.md"),h)}catch(h){p.logger.debug(`failed to copy scenario command ${c}: ${h}`)}}}spliceCycleFragments(e,o,r,i){const t=P("codex");let a=e;for(const m of d.ALL_CYCLES){const u=(0,d.isCycleEnabled)(r,m)?v=>{const c=(0,g.join)(t,(0,C.fragmentFilename)(o,m,v));return(0,s.existsSync)(c)?(0,s.readFileSync)(c,"utf-8").trimEnd():null}:null;a=(0,C.applyPlatformSection)(a,m,u,i)}return a}removeDir(e){if((0,s.existsSync)(e))try{(0,s.rmSync)(e,{recursive:!0,force:!0})}catch(o){p.logger.debug(`failed to remove ${e}: ${o}`)}}}function G(f){return(0,n.tomlBodyFromRecord)(f)}S(G,"mcpEntryToTomlBody");0&&(module.exports={CodexClient});
3
+ `)}upsertSessionMcpServers(e,o,r){let i=e;const t=S((a,g,p)=>{if(!a)return;const u=[...K(p),`startup_timeout_sec = ${V}`,'default_tools_approval_mode = "approve"'];i=(0,n.upsertMcpServer)(i,g,u)},"addCycle");return t((0,d.isCycleEnabled)(r,"browser"),E,(0,d.getMcpServerEntry)(o)),t((0,d.isCycleEnabled)(r,"node"),A,(0,d.getNodeDevToolsMcpEntry)(o)),t((0,d.isCycleEnabled)(r,"backend"),_,(0,d.getBackendDevToolsMcpEntry)(o)),t((0,d.isCycleEnabled)(r,"android"),I,(0,d.getAndroidDevToolsMcpEntry)(o)),i}removeVerifierAgentToml(e){const o=(0,n.codexAgentTomlPath)(e,$);if((0,s.existsSync)(o))try{(0,s.unlinkSync)(o)}catch(r){b.logger.debug(`failed to remove verifier agent toml: ${r}`)}}removeScenarioAgentToml(e){const o=(0,n.codexAgentTomlPath)(e,x);if((0,s.existsSync)(o))try{(0,s.unlinkSync)(o)}catch(r){b.logger.debug(`failed to remove scenario agent toml: ${r}`)}}removeIronBeeMcpServers(e){let o=(0,n.readCodexConfigToml)(e);o&&(o=(0,n.removeMcpServer)(o,E),o=(0,n.removeMcpServer)(o,A),o=(0,n.removeMcpServer)(o,_),o=(0,n.removeMcpServer)(o,I),o=(0,n.removeAgentsTable)(o,$),o=(0,n.removeAgentsTable)(o,x),o=(0,n.removeMultiAgentV2SpawnMetadata)(o),(0,n.writeCodexConfigToml)(e,o))}migrateAwayFromUserLevel(){const e=(0,n.userCodexHooksJsonPath)();this.removeIronBeeHooks(e),this.maybeDeleteEmptyHooks(e);const o=(0,n.userCodexConfigTomlPath)();if((0,s.existsSync)(o))try{let i=(0,s.readFileSync)(o,"utf-8");const t=i;i=(0,n.removeMcpServer)(i,E),i=(0,n.removeMcpServer)(i,A),i=(0,n.removeMcpServer)(i,_),i=(0,n.removeMcpServer)(i,I),i=(0,n.removeAgentsTable)(i,$),i=(0,n.removeMultiAgentV2SpawnMetadata)(i),i!==t&&(0,s.writeFileSync)(o,i)}catch(i){b.logger.debug(`migrate: failed to clean user-level config.toml: ${i}`)}const r=(0,n.userCodexAgentTomlPath)($);if((0,s.existsSync)(r))try{(0,s.unlinkSync)(r)}catch(i){b.logger.debug(`migrate: failed to remove user-level verifier toml: ${i}`)}}writeAgentsMdBlock(e,o,r){const i=(0,m.join)(e,"AGENTS.md"),t=r==="main-agent"?"ironbee-verification.main.md":"ironbee-verification.md",a=(0,m.join)(__dirname,"rules",t);let g;try{g=(0,s.readFileSync)(a,"utf-8")}catch(c){b.logger.debug(`failed to read rule source ${a}: ${c}`);return}const p=P("codex");for(const c of d.ALL_CYCLES){const R=(0,d.isCycleEnabled)(o,c)?k=>{const T=(0,m.join)(p,(0,C.fragmentFilename)("rule",c,k));if(!(0,s.existsSync)(T)){const w=k.length>0?`${c}:${k}`:c;return b.logger.debug(`AGENTS.md platform-section ${w}: missing fragment ${T}, using placeholder`),null}return(0,s.readFileSync)(T,"utf-8").trimEnd()}:null;g=(0,C.applyPlatformSection)(g,c,R,"AGENTS.md")}const u=(0,s.existsSync)(i)?(0,s.readFileSync)(i,"utf-8"):"",v=(0,n.upsertAgentsMdBlock)(u,g);(0,s.writeFileSync)(i,v)}writeSkills(e,o,r,i){const t=(0,m.join)(e,".agents","skills"),a=i==="main-agent";if(o){const u=(0,m.join)(t,"ironbee-verification");(0,s.mkdirSync)(u,{recursive:!0});const v=(0,m.join)(__dirname,"skills",a?"ironbee-verification.main.md":"ironbee-verification.md");try{let c=(0,s.readFileSync)(v,"utf-8");a&&(c=this.spliceCycleFragments(c,"skill",r,"ironbee-verification/SKILL.md")),(0,s.writeFileSync)((0,m.join)(u,"SKILL.md"),c)}catch(c){b.logger.debug(`failed to copy skill ${v}: ${c}`)}}const g=(0,m.join)(t,"ironbee-verify");(0,s.mkdirSync)(g,{recursive:!0});const p=(0,m.join)(__dirname,"commands","ironbee-verify",a?"SKILL.main.md":"SKILL.md");try{let u=(0,s.readFileSync)(p,"utf-8");a&&(u=this.spliceCycleFragments(u,"command-verify",r,"ironbee-verify/SKILL.md")),(0,s.writeFileSync)((0,m.join)(g,"SKILL.md"),u)}catch(u){b.logger.debug(`failed to copy verify command ${p}: ${u}`)}for(const u of J){const v=(0,m.join)(t,u);(0,s.mkdirSync)(v,{recursive:!0});const c=(0,m.join)(__dirname,"commands",u,a?"SKILL.main.md":"SKILL.md");try{let h=(0,s.readFileSync)(c,"utf-8");a&&(h=this.spliceCycleFragments(h,"scenario",r,`${u}/SKILL.md`)),(0,s.writeFileSync)((0,m.join)(v,"SKILL.md"),h)}catch(h){b.logger.debug(`failed to copy scenario command ${c}: ${h}`)}}}spliceCycleFragments(e,o,r,i){const t=P("codex");let a=e;for(const g of d.ALL_CYCLES){const u=(0,d.isCycleEnabled)(r,g)?v=>{const c=(0,m.join)(t,(0,C.fragmentFilename)(o,g,v));return(0,s.existsSync)(c)?(0,s.readFileSync)(c,"utf-8").trimEnd():null}:null;a=(0,C.applyPlatformSection)(a,g,u,i)}return a}removeDir(e){if((0,s.existsSync)(e))try{(0,s.rmSync)(e,{recursive:!0,force:!0})}catch(o){b.logger.debug(`failed to remove ${e}: ${o}`)}}}function K(f){return(0,n.tomlBodyFromRecord)(f)}S(K,"mcpEntryToTomlBody");0&&(module.exports={CodexClient});
@@ -18,6 +18,7 @@ If the project has android verification enabled (`ironbee android enable` once a
18
18
  4. **Pick an evidence path** for the changed code:
19
19
  - **Device-evidence** (proves the change is visible / functional): drive UI (`mcp__android-devtools__adt_interaction_tap` / `mcp__android-devtools__adt_interaction_input-text` / `mcp__android-devtools__adt_interaction_swipe`) → screenshot (`mcp__android-devtools__adt_content_take-screenshot`) → UI snapshot (`mcp__android-devtools__adt_a11y_take-ui-snapshot`). **STOP and visually analyze the screenshot** — readability, layout, cut-off content, expected state rendered; the snapshot reports structure, the screenshot shows what the user actually sees. Both are MANDATORY on this path.
20
20
  - **Log-evidence** (proves the changed code path executed): `mcp__android-devtools__adt_o11y_log-read` or `mcp__android-devtools__adt_o11y_log-follow`. Confirm expected log lines present AND no FATAL/crash from the app package.
21
+ - **Network-evidence** (proves a network/API change behaved correctly): `mcp__android-devtools__adt_o11y_get-http-requests` — forward-looking, so start capture, drive the app to trigger traffic, then read again; confirm the expected request(s)/status. Auxiliary (NOT gate evidence): `mcp__android-devtools__adt_o11y_new-trace-id` pins a correlation root; `mcp__android-devtools__adt_stub_*` mocks/intercepts responses for setup.
21
22
  5. **If recording was started, stop it now** — `mcp__android-devtools__adt_content_stop-recording`. submit-verdict rejects with `"recording is still active"` when this step is skipped.
22
23
  6. **Submit verdict** — platform-agnostic, just status + checks (+ issues/fixes).
23
24
 
@@ -21,8 +21,9 @@ These attach to the **Required steps** above — they don't replace any step. Nu
21
21
  - **Within step 3 (run flow):** also run the android flow: connect (`adt_device_connect`) → launch app (`adt_device_launch-app`) → pick ONE evidence path:
22
22
  - **Device-evidence**: drive UI (`adt_interaction_tap` / `adt_interaction_input-text` / `adt_interaction_swipe`) + screenshot (`adt_content_take-screenshot`) + UI snapshot (`adt_a11y_take-ui-snapshot`)
23
23
  - **Log-evidence**: read Logcat (`adt_o11y_log-read` or `adt_o11y_log-follow`) confirming expected output and no crashes
24
+ - **Network-evidence**: capture outgoing HTTP traffic (`adt_o11y_get-http-requests` — forward-looking: start capture, drive the app, read again) confirming the expected request(s)/status. Auxiliary setup only (NOT evidence): `adt_o11y_new-trace-id` (pin correlation), `adt_stub_*` (mock/intercept).
24
25
  - If `recording.enable` is on, the gate forces `adt_content_start-recording` BEFORE the android steps above and rejects the verdict if you don't call `adt_content_stop-recording` AFTER them. Always pair start/stop around the steps above.
25
- - **Within step 6 (submit verdict):** submit one platform-agnostic verdict with `status` + `checks` (+ `issues`/`fixes` as needed). Android-cycle pass criteria: device connected AND (UI-interaction + screenshot + UI snapshot taken) OR (Logcat read with no crashes).
26
+ - **Within step 6 (submit verdict):** submit one platform-agnostic verdict with `status` + `checks` (+ `issues`/`fixes` as needed). Android-cycle pass criteria: device connected AND (UI-interaction + screenshot + UI snapshot taken) OR (Logcat read with no crashes) OR (outgoing HTTP traffic captured and confirmed).
26
27
 
27
28
  ### Additional BANNED for android cycle
28
29
 
@@ -24,6 +24,7 @@ verification, so its script must collect what the android cycle collects). In th
24
24
  - **Log-evidence path** — `adt_o11y_log-read` / `adt_o11y_log-follow` (with `returnOutput: true`)
25
25
  for the tag(s) relevant to the change; confirm expected lines appear AND no FATAL / crash (E/
26
26
  entries) for the app package.
27
+ - **Network-evidence path** — capture outgoing HTTP traffic with `adt_o11y_get-http-requests` (`returnOutput: true`): start capture, drive the app (`adt_interaction_*`) to trigger traffic, read again, and put the captured request(s)/status in your result. Optional setup helpers (NOT evidence): `adt_o11y_new-trace-id` to pin a correlation root, `adt_stub_*` to mock/intercept responses.
27
28
 
28
29
  `return` the evidence — UI-snapshot text, log lines, the screenshot `filePath`s — **plus explicit
29
30
  pass/fail assertions**. That returned result is what `$ironbee-verify scenario:<name>` reads to judge
@@ -32,6 +32,9 @@ If you see only `ios/`, `web/`, or no mobile directories — the project does NO
32
32
  - **Log-evidence path** (device logs confirm the changed code path executed):
33
33
  - Read Logcat output for the tag(s) relevant to the changed code: `mcp__android-devtools__adt_o11y_log-read` or `mcp__android-devtools__adt_o11y_log-follow` (drain a follow with `mcp__android-devtools__adt_o11y_log-get-followed`, stop it with `mcp__android-devtools__adt_o11y_log-stop-follow`).
34
34
  - Confirm expected log lines appear AND no unexpected crashes (FATAL / E/ entries for the app package).
35
+ - **Network-evidence path** (captured HTTP traffic confirms a network/API-related change):
36
+ - Capture the app's outgoing HTTP(S) requests: `mcp__android-devtools__adt_o11y_get-http-requests` (Frida/OkHttp in-process — no proxy, no CA install; OkHttp-based stacks only — Retrofit / React Native / HttpURLConnection). **Capture is forward-looking**: call it once to start capture, drive the app to trigger traffic (`mcp__android-devtools__adt_interaction_*`), then call it again to read. Confirm the expected request(s) / response status appear.
37
+ - **Auxiliary (NOT evidence — setup/correlation only):** to pin one correlation root across the flow, optionally `mcp__android-devtools__adt_o11y_new-trace-id` first (it stamps `traceparent` on every captured request; inspect/clear via `mcp__android-devtools__adt_o11y_set-trace-context` / `mcp__android-devtools__adt_o11y_get-trace-context`). To set up test conditions, `mcp__android-devtools__adt_stub_mock-http-response` / `mcp__android-devtools__adt_stub_intercept-http-request` mock or mutate responses (list/clear with `mcp__android-devtools__adt_stub_list` / `mcp__android-devtools__adt_stub_clear`). `mcp__android-devtools__adt_figma_compare-screen-with-design` checks emulator-vs-Figma parity (optional, requires `FIGMA_ACCESS_TOKEN`). None of these count toward the gate — they shape the test, they don't inspect it.
35
38
 
36
39
  **Batch (speed):** connect + launch-app run standalone first (prerequisites). On the device-evidence path, batch the UI interactions + the UI snapshot into one `mcp__android-devtools__adt_execute`; the snapshot captures the state after the batched interactions, so to assert an intermediate state take a snapshot at that point too. The device-evidence screenshot is usually pixel-judged (a visual change) — take THAT one standalone with `includeBase64: true` so you can see it; batch it only when it's purely gate evidence. Log-evidence reads batch together too.
37
40
 
@@ -51,6 +54,7 @@ On fail, include `issues`. On pass after a previous fail, include `fixes`.
51
54
  Android-cycle pass criteria:
52
55
  - **Device-evidence**: at least one UI interaction tool fired AND a screenshot was taken AND a UI snapshot was taken AND both show the expected UI state/structure.
53
56
  - **Log-evidence**: Logcat was read AND the expected log lines are present AND no crash (FATAL / unhandled exception) from the app's package.
57
+ - **Network-evidence**: the app's outgoing HTTP traffic was captured AND the expected request(s) / response status confirm the change behaved correctly.
54
58
 
55
59
  ## Multi-cycle (browser + android simultaneously)
56
60
 
@@ -1,2 +1,2 @@
1
- "use strict";var a=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var f=Object.prototype.hasOwnProperty;var l=(e,i)=>a(e,"name",{value:i,configurable:!0});var y=(e,i)=>{for(var o in i)a(e,o,{get:i[o],enumerable:!0})},x=(e,i,o,n)=>{if(i&&typeof i=="object"||typeof i=="function")for(let s of g(i))!f.call(e,s)&&s!==o&&a(e,s,{get:()=>i[s],enumerable:!(n=m(i,s))||n.enumerable});return e};var h=e=>x(a({},"__esModule",{value:!0}),e);var v={};y(v,{codexProcessAnalyticsCommand:()=>C});module.exports=h(v);var c=require("commander"),r=require("fs"),t=require("../../lib/logger"),d=require("../../analytics/codex/events-emit"),u=require("../../analytics/codex/emit"),p=require("../../analytics/codex/transcript");const C=new c.Command("process-analytics").description("Internal worker \u2014 emit Codex api_request + session_status + session_analytics events for one Stop trigger").requiredOption("--project <dir>","project directory (where .ironbee/sessions/<sid>/ lives)").requiredOption("--session <id>","session id").option("--rollout-path <path>","rollout JSONL path (from Codex hook stdin); falls back to discovery walk").option("--user-email <email>","session user email (from state.json:userEmail)").option("--usage-type <type>","api | subscription (from state.json:usageType)").option("--usage-plan <plan>","subscription plan id (from state.json:usagePlan)").option("--activity-id <id>","current active activity id (for session_status correlation)").action(async e=>{(0,t.setLogFile)(`${e.project}/.ironbee/sessions/${e.session}/session.log`);const i=e.usageType==="api"||e.usageType==="subscription"?e.usageType:void 0;let o=e.rolloutPath;(o===void 0||!(0,r.existsSync)(o))&&(o=(0,p.findCodexRolloutPath)(e.session)??void 0);let n;if(o!==void 0&&(0,r.existsSync)(o))try{n=P(o)}catch(s){t.logger.debug(`codex process-analytics rollout parse failed: ${s instanceof Error?s.message:s}`)}await Promise.allSettled([(0,d.emitCodexAnalytics)({projectDir:e.project,sessionId:e.session,rolloutPath:o,preloadedLines:n,userEmail:e.userEmail,usageType:i,usagePlan:e.usagePlan,activityId:e.activityId??""}).catch(s=>{t.logger.debug(`codex process-analytics emit failed: ${s instanceof Error?s.message:s}`)}),(0,u.emitCodexSessionAnalytics)({projectDir:e.project,sessionId:e.session,rolloutPath:o,preloadedLines:n,userEmail:e.userEmail,usageType:i,usagePlan:e.usagePlan,isFinal:!1}).catch(s=>{t.logger.debug(`codex process-analytics session-emit failed: ${s instanceof Error?s.message:s}`)})]),t.logger.debug(`codex process-analytics: complete session=${e.session}`),process.exit(0)});function P(e){const i=(0,r.readFileSync)(e,"utf-8"),o=[];for(const n of i.split(`
2
- `))if(n.length!==0)try{o.push(JSON.parse(n))}catch{}return o}l(P,"parseRolloutLines");0&&(module.exports={codexProcessAnalyticsCommand});
1
+ "use strict";var a=Object.defineProperty;var f=Object.getOwnPropertyDescriptor;var g=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var l=(e,i)=>a(e,"name",{value:i,configurable:!0});var x=(e,i)=>{for(var o in i)a(e,o,{get:i[o],enumerable:!0})},h=(e,i,o,n)=>{if(i&&typeof i=="object"||typeof i=="function")for(let s of g(i))!y.call(e,s)&&s!==o&&a(e,s,{get:()=>i[s],enumerable:!(n=f(i,s))||n.enumerable});return e};var C=e=>h(a({},"__esModule",{value:!0}),e);var j={};x(j,{codexProcessAnalyticsCommand:()=>P});module.exports=C(j);var c=require("commander"),r=require("fs"),t=require("../../lib/logger"),d=require("../../analytics/codex/events-emit"),u=require("../../analytics/codex/emit"),p=require("../../analytics/codex/transcript"),m=require("../../lib/runtime-paths");const P=new c.Command("process-analytics").description("Internal worker \u2014 emit Codex api_request + session_status + session_analytics events for one Stop trigger").requiredOption("--project <dir>","project directory (where .ironbee/sessions/<sid>/ lives)").requiredOption("--session <id>","session id").option("--rollout-path <path>","rollout JSONL path (from Codex hook stdin); falls back to discovery walk").option("--user-email <email>","session user email (from state.json:userEmail)").option("--usage-type <type>","api | subscription (from state.json:usageType)").option("--usage-plan <plan>","subscription plan id (from state.json:usagePlan)").option("--activity-id <id>","current active activity id (for session_status correlation)").action(async e=>{(0,t.setLogFile)((0,m.sessionLogFile)(e.project,e.session));const i=e.usageType==="api"||e.usageType==="subscription"?e.usageType:void 0;let o=e.rolloutPath;(o===void 0||!(0,r.existsSync)(o))&&(o=(0,p.findCodexRolloutPath)(e.session)??void 0);let n;if(o!==void 0&&(0,r.existsSync)(o))try{n=v(o)}catch(s){t.logger.debug(`codex process-analytics rollout parse failed: ${s instanceof Error?s.message:s}`)}await Promise.allSettled([(0,d.emitCodexAnalytics)({projectDir:e.project,sessionId:e.session,rolloutPath:o,preloadedLines:n,userEmail:e.userEmail,usageType:i,usagePlan:e.usagePlan,activityId:e.activityId??""}).catch(s=>{t.logger.debug(`codex process-analytics emit failed: ${s instanceof Error?s.message:s}`)}),(0,u.emitCodexSessionAnalytics)({projectDir:e.project,sessionId:e.session,rolloutPath:o,preloadedLines:n,userEmail:e.userEmail,usageType:i,usagePlan:e.usagePlan,isFinal:!1}).catch(s=>{t.logger.debug(`codex process-analytics session-emit failed: ${s instanceof Error?s.message:s}`)})]),t.logger.debug(`codex process-analytics: complete session=${e.session}`),process.exit(0)});function v(e){const i=(0,r.readFileSync)(e,"utf-8"),o=[];for(const n of i.split(`
2
+ `))if(n.length!==0)try{o.push(JSON.parse(n))}catch{}return o}l(v,"parseRolloutLines");0&&(module.exports={codexProcessAnalyticsCommand});
@@ -1 +1 @@
1
- "use strict";var d=Object.defineProperty;var g=Object.getOwnPropertyDescriptor;var m=Object.getOwnPropertyNames;var T=Object.prototype.hasOwnProperty;var a=(n,e)=>d(n,"name",{value:e,configurable:!0});var y=(n,e)=>{for(var r in e)d(n,r,{get:e[r],enumerable:!0})},l=(n,e,r,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of m(e))!T.call(n,t)&&t!==r&&d(n,t,{get:()=>e[t],enumerable:!(i=g(e,t))||i.enumerable});return n};var E=n=>l(d({},"__esModule",{value:!0}),n);var w={};y(w,{codexThreadMapPath:()=>c,lookupThreadSession:()=>x,pruneThreadMapping:()=>v,writeThreadMapping:()=>F});module.exports=E(w);var s=require("fs"),u=require("path"),p=require("../../lib/logger");const M=256,b=1440*60*1e3;function c(n){return(0,u.join)(n,".ironbee","codex-threads.json")}a(c,"codexThreadMapPath");function h(n){try{const e=(0,s.readFileSync)(n,"utf-8"),r=JSON.parse(e);if(r&&typeof r=="object"&&r.version===1){const i=r;if(i.threads&&typeof i.threads=="object")return i}}catch{}return{version:1,threads:{}}}a(h,"readMap");function S(n,e){const r=Object.entries(n).filter(([,t])=>e-t.ts<b).sort((t,o)=>o[1].ts-t[1].ts).slice(0,M),i={};for(const[t,o]of r)i[t]=o;return i}a(S,"pruneStale");function f(n,e){(0,s.mkdirSync)((0,u.dirname)(n),{recursive:!0});const r=`${n}.${process.pid}.tmp`;(0,s.writeFileSync)(r,JSON.stringify(e),"utf-8"),(0,s.renameSync)(r,n)}a(f,"writeMapAtomic");function F(n,e,r,i=Date.now()){if(!(!e||!r))try{const t=c(n),o=h(t);o.threads[e]={session_id:r,ts:i},o.threads=S(o.threads,i),f(t,o)}catch(t){p.logger.debug(`codex thread-map write failed: ${t instanceof Error?t.message:String(t)}`)}}a(F,"writeThreadMapping");function x(n,e){if(!e)return;const r=c(n);return(0,s.existsSync)(r)?h(r).threads[e]?.session_id:void 0}a(x,"lookupThreadSession");function v(n,e){if(e)try{const r=c(n);if(!(0,s.existsSync)(r))return;const i=h(r);i.threads[e]!==void 0&&(delete i.threads[e],f(r,i))}catch(r){p.logger.debug(`codex thread-map prune failed: ${r instanceof Error?r.message:String(r)}`)}}a(v,"pruneThreadMapping");0&&(module.exports={codexThreadMapPath,lookupThreadSession,pruneThreadMapping,writeThreadMapping});
1
+ "use strict";var d=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var y=Object.prototype.hasOwnProperty;var a=(t,e)=>d(t,"name",{value:e,configurable:!0});var l=(t,e)=>{for(var r in e)d(t,r,{get:e[r],enumerable:!0})},E=(t,e,r,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let n of T(e))!y.call(t,n)&&n!==r&&d(t,n,{get:()=>e[n],enumerable:!(i=m(e,n))||i.enumerable});return t};var M=t=>E(d({},"__esModule",{value:!0}),t);var k={};l(k,{codexThreadMapPath:()=>c,lookupThreadSession:()=>v,pruneThreadMapping:()=>w,writeThreadMapping:()=>x});module.exports=M(k);var s=require("fs"),u=require("path"),p=require("../../lib/logger"),g=require("../../lib/runtime-paths");const S=256,b=1440*60*1e3;function c(t){return(0,u.join)((0,g.runtimeDir)(t),"codex-threads.json")}a(c,"codexThreadMapPath");function h(t){try{const e=(0,s.readFileSync)(t,"utf-8"),r=JSON.parse(e);if(r&&typeof r=="object"&&r.version===1){const i=r;if(i.threads&&typeof i.threads=="object")return i}}catch{}return{version:1,threads:{}}}a(h,"readMap");function F(t,e){const r=Object.entries(t).filter(([,n])=>e-n.ts<b).sort((n,o)=>o[1].ts-n[1].ts).slice(0,S),i={};for(const[n,o]of r)i[n]=o;return i}a(F,"pruneStale");function f(t,e){(0,s.mkdirSync)((0,u.dirname)(t),{recursive:!0});const r=`${t}.${process.pid}.tmp`;(0,s.writeFileSync)(r,JSON.stringify(e),"utf-8"),(0,s.renameSync)(r,t)}a(f,"writeMapAtomic");function x(t,e,r,i=Date.now()){if(!(!e||!r))try{const n=c(t),o=h(n);o.threads[e]={session_id:r,ts:i},o.threads=F(o.threads,i),f(n,o)}catch(n){p.logger.debug(`codex thread-map write failed: ${n instanceof Error?n.message:String(n)}`)}}a(x,"writeThreadMapping");function v(t,e){if(!e)return;const r=c(t);return(0,s.existsSync)(r)?h(r).threads[e]?.session_id:void 0}a(v,"lookupThreadSession");function w(t,e){if(e)try{const r=c(t);if(!(0,s.existsSync)(r))return;const i=h(r);i.threads[e]!==void 0&&(delete i.threads[e],f(r,i))}catch(r){p.logger.debug(`codex thread-map prune failed: ${r instanceof Error?r.message:String(r)}`)}}a(w,"pruneThreadMapping");0&&(module.exports={codexThreadMapPath,lookupThreadSession,pruneThreadMapping,writeThreadMapping});