@ironbee-ai/cli 0.29.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 (125) hide show
  1. package/CHANGELOG.md +12 -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/agents/ironbee-scenario.md +191 -0
  7. package/dist/clients/claude/agents/ironbee-verifier.md +22 -5
  8. package/dist/clients/claude/commands/ironbee-manage-scenario.md +36 -0
  9. package/dist/clients/claude/commands/ironbee-search-scenario.md +22 -0
  10. package/dist/clients/claude/commands/ironbee-sync-scenario.md +31 -0
  11. package/dist/clients/claude/commands/ironbee-verify.md +13 -12
  12. package/dist/clients/claude/hooks/activity-end.js +1 -1
  13. package/dist/clients/claude/hooks/activity-start.js +1 -1
  14. package/dist/clients/claude/hooks/clear-verdict.js +1 -1
  15. package/dist/clients/claude/hooks/require-verdict.js +2 -2
  16. package/dist/clients/claude/hooks/require-verification.js +3 -3
  17. package/dist/clients/claude/hooks/session-end.js +1 -1
  18. package/dist/clients/claude/hooks/session-start.js +4 -4
  19. package/dist/clients/claude/hooks/session-status.js +2 -2
  20. package/dist/clients/claude/hooks/subagent-start.js +1 -1
  21. package/dist/clients/claude/hooks/subagent-stop.js +1 -1
  22. package/dist/clients/claude/hooks/track-action-monitor.js +1 -1
  23. package/dist/clients/claude/hooks/track-action.js +1 -1
  24. package/dist/clients/claude/hooks/verify-gate.js +4 -4
  25. package/dist/clients/claude/index.js +4 -4
  26. package/dist/clients/claude/platforms/scenario.android.md +32 -0
  27. package/dist/clients/claude/platforms/scenario.backend.md +26 -0
  28. package/dist/clients/claude/platforms/scenario.browser.md +41 -0
  29. package/dist/clients/claude/platforms/scenario.node.md +27 -0
  30. package/dist/clients/claude/platforms/skill.android.md +4 -0
  31. package/dist/clients/claude/process-analytics.js +1 -1
  32. package/dist/clients/claude/statusline-toggle.js +2 -2
  33. package/dist/clients/claude/trust.js +1 -0
  34. package/dist/clients/codex/agents/ironbee-scenario.md +179 -0
  35. package/dist/clients/codex/agents/ironbee-verifier.md +22 -5
  36. package/dist/clients/codex/commands/ironbee-manage-scenario/SKILL.main.md +102 -0
  37. package/dist/clients/codex/commands/ironbee-manage-scenario/SKILL.md +38 -0
  38. package/dist/clients/codex/commands/ironbee-search-scenario/SKILL.main.md +37 -0
  39. package/dist/clients/codex/commands/ironbee-search-scenario/SKILL.md +23 -0
  40. package/dist/clients/codex/commands/ironbee-sync-scenario/SKILL.main.md +55 -0
  41. package/dist/clients/codex/commands/ironbee-sync-scenario/SKILL.md +33 -0
  42. package/dist/clients/codex/commands/ironbee-verify/SKILL.main.md +12 -3
  43. package/dist/clients/codex/commands/ironbee-verify/SKILL.md +4 -3
  44. package/dist/clients/codex/hooks/activity-end.js +1 -1
  45. package/dist/clients/codex/hooks/activity-start.js +1 -1
  46. package/dist/clients/codex/hooks/clear-verdict.js +3 -3
  47. package/dist/clients/codex/hooks/require-verdict.js +2 -2
  48. package/dist/clients/codex/hooks/require-verification.js +3 -3
  49. package/dist/clients/codex/hooks/session-start.js +3 -3
  50. package/dist/clients/codex/hooks/subagent-start.js +1 -1
  51. package/dist/clients/codex/hooks/subagent-stop.js +1 -1
  52. package/dist/clients/codex/hooks/track-action-monitor.js +1 -1
  53. package/dist/clients/codex/hooks/track-action-pre.js +1 -1
  54. package/dist/clients/codex/hooks/track-action.js +1 -1
  55. package/dist/clients/codex/hooks/verify-gate.js +1 -1
  56. package/dist/clients/codex/index.js +2 -2
  57. package/dist/clients/codex/platforms/command-verify.android.md +1 -0
  58. package/dist/clients/codex/platforms/rule.android.md +2 -1
  59. package/dist/clients/codex/platforms/scenario.android.md +32 -0
  60. package/dist/clients/codex/platforms/scenario.backend.md +26 -0
  61. package/dist/clients/codex/platforms/scenario.browser.md +40 -0
  62. package/dist/clients/codex/platforms/scenario.node.md +27 -0
  63. package/dist/clients/codex/platforms/skill.android.md +4 -0
  64. package/dist/clients/codex/process-analytics.js +2 -2
  65. package/dist/clients/codex/thread-map.js +1 -1
  66. package/dist/clients/codex/util.js +44 -31
  67. package/dist/clients/cursor/commands/ironbee-manage-scenario/SKILL.md +100 -0
  68. package/dist/clients/cursor/commands/ironbee-search-scenario/SKILL.md +34 -0
  69. package/dist/clients/cursor/commands/ironbee-sync-scenario/SKILL.md +54 -0
  70. package/dist/clients/cursor/commands/ironbee-verify/SKILL.md +2 -1
  71. package/dist/clients/cursor/hooks/activity-end.js +1 -1
  72. package/dist/clients/cursor/hooks/activity-start.js +1 -1
  73. package/dist/clients/cursor/hooks/clear-verdict.js +1 -1
  74. package/dist/clients/cursor/hooks/require-verdict.js +2 -2
  75. package/dist/clients/cursor/hooks/require-verification.js +3 -3
  76. package/dist/clients/cursor/hooks/session-end.js +1 -1
  77. package/dist/clients/cursor/hooks/session-start.js +4 -4
  78. package/dist/clients/cursor/hooks/track-action-monitor.js +1 -1
  79. package/dist/clients/cursor/hooks/track-action.js +1 -1
  80. package/dist/clients/cursor/hooks/verify-gate.js +1 -1
  81. package/dist/clients/cursor/index.js +1 -1
  82. package/dist/clients/cursor/platforms/command-verify.android.md +1 -0
  83. package/dist/clients/cursor/platforms/rule.android.md +2 -1
  84. package/dist/clients/cursor/platforms/scenario.android.md +32 -0
  85. package/dist/clients/cursor/platforms/scenario.backend.md +26 -0
  86. package/dist/clients/cursor/platforms/scenario.browser.md +40 -0
  87. package/dist/clients/cursor/platforms/scenario.node.md +27 -0
  88. package/dist/clients/cursor/platforms/skill.android.md +4 -0
  89. package/dist/commands/config.js +1 -1
  90. package/dist/commands/hook.js +10 -10
  91. package/dist/commands/import.js +3 -3
  92. package/dist/commands/process-job-file.js +1 -1
  93. package/dist/commands/queue.js +16 -16
  94. package/dist/commands/scenario.js +1 -0
  95. package/dist/commands/status.js +1 -1
  96. package/dist/commands/uninstall.js +1 -1
  97. package/dist/commands/verify.js +2 -2
  98. package/dist/hooks/core/actions.js +7 -7
  99. package/dist/hooks/core/nested-tools.js +1 -1
  100. package/dist/hooks/core/scenario-tools.js +1 -0
  101. package/dist/hooks/core/session-state.js +1 -1
  102. package/dist/hooks/core/verification-context.js +8 -8
  103. package/dist/import/marker.js +2 -2
  104. package/dist/import/skip.js +1 -1
  105. package/dist/index.js +1 -1
  106. package/dist/lib/config.js +1 -1
  107. package/dist/lib/git.js +1 -1
  108. package/dist/lib/install-version.js +1 -1
  109. package/dist/lib/platform-section.js +3 -3
  110. package/dist/lib/runtime-paths.js +1 -0
  111. package/dist/lib/scenario-staleness.js +1 -0
  112. package/dist/otel/claude/daemon/process.js +1 -1
  113. package/dist/otel/claude/daemon/reprocess.js +1 -1
  114. package/dist/otel/claude/daemon/response-usage.js +2 -2
  115. package/dist/queue/drain.js +1 -1
  116. package/dist/queue/flush.js +1 -1
  117. package/dist/queue/paths.js +1 -1
  118. package/dist/queue/process-file.js +2 -2
  119. package/dist/queue/spawn.js +1 -1
  120. package/dist/tui/config/schema.js +1 -1
  121. package/dist/tui/queue/read.js +4 -4
  122. package/dist/tui/scenarios/area.js +2 -0
  123. package/dist/tui/sessions/read.js +2 -2
  124. package/dist/tui/shell/registry.js +1 -1
  125. package/package.json +1 -1
@@ -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 j=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var K=Object.prototype.hasOwnProperty;var R=(o,e)=>u(o,"name",{value:e,configurable:!0});var q=(o,e)=>{for(var s in e)u(o,s,{get:e[s],enumerable:!0})},B=(o,e,s,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of F(e))!K.call(o,t)&&t!==s&&u(o,t,{get:()=>e[t],enumerable:!(n=j(e,t))||n.enumerable});return o};var J=o=>B(u({},"__esModule",{value:!0}),o);var H={};q(H,{run:()=>L});module.exports=J(H);var C=require("crypto"),$=require("../../../hooks/core/activity"),i=require("../../../hooks/core/session-state"),x=require("../../../hooks/core/actions"),N=require("../../../hooks/core/verification-lifecycle"),E=require("../../../hooks/core/verification-context"),O=require("../../../lib/config"),m=require("../../../lib/logger"),U=require("../../../lib/recording-tools"),A=require("../../../lib/stdin"),f=require("../util");async function L(o,e){const s=e?.soft===!0,n=(0,f.parseCodexHookStdin)((0,A.readStdin)()),t=n.session_id??"default",r=`${o}/.ironbee/sessions/${t}`,y=`${r}/actions.jsonl`;(0,m.setLogFile)(`${r}/session.log`);const b=(0,i.getActiveVerificationId)(r);if(!b&&!s){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 g=n.tool_name??"",h=(0,f.extractCodexMcpServer)(g),c=(0,U.recordingToolsForServer)(h),D=c!==null?(0,f.canonicalizeCodexToolName)(g.split("__").pop()??""):"";if(!s&&c!==null&&(0,i.isRecordingRequired)(r)&&!(0,i.isRecordingActive)(r)&&D!==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,$.startActivity)({sessionDir:r,actionsFile:y,source:"pre_tool_use"});let l=b;s&&!l&&(l=(await(0,N.startVerification)({sessionId:t,sessionDir:r,actionsFile:y,recordingEnabled:!1})).verificationId);const V=(0,i.getActiveTraceId)(r),_=(0,i.getActiveActivityId)(r),k=(0,x.resolveProjectName)(o),v=[`prj:${k}`,`sid:${t}`];_&&v.push(`aid:${_}`),l&&v.push(`vid:${l}`);const P=`ironbee=${v.join(";")}`,a=(0,O.loadConfig)(o),S={...n.tool_input&&typeof n.tool_input=="object"?n.tool_input:{}},d={projectName:k,sessionId:t,activityId:_,verificationId:l,traceId:V,traceState:P,toolCallId:(0,C.randomUUID)()};n.tool_use_id&&(d.toolUseId=n.tool_use_id),d.mcpServer=h??"browser-devtools";const T=(0,i.getUserEmail)(r);T&&(d.userEmail=T),a.collector?.url&&(d.collectorUrl=a.collector.url),a.collector?.oauthToken?d.collectorOAuthToken=a.collector.oauthToken:a.collector?.apiKey&&(d.collectorApiKey=a.collector.apiKey),S._metadata=d;const w={hookEventName:"PreToolUse",permissionDecision:"allow",updatedInput:S},I=(0,E.buildVerificationContextOnceForCycle)({projectDir:o,sessionId:t,sessionDir:r,activeVerificationId:l,config:a});I.length>0&&(w.additionalContext=I),process.stdout.write(JSON.stringify({hookSpecificOutput:w})),m.logger.debug(`require-verification: allowed ${g} with _metadata`),process.exit(0)}R(L,"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 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"),R=require("../../../import/ids"),r=require("../../../hooks/core/session-state"),P=require("../../../hooks/core/tool-use-stash"),U=require("../../../lib/config"),a=require("../../../lib/logger"),A=require("../../../lib/output"),q=require("../../../lib/recording-tools"),H=require("../../../lib/stdin"),x=require("../../../queue"),l=require("../util");function h(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(h,"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,l.parseCodexHookStdin)((0,H.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??"",d=e.tool_use_id??"",m=e.tool_input,$=m&&typeof m=="object"?{...m,_metadata:void 0}:void 0,w=e.tool_response,s=(0,l.extractCodexMcpServer)(y),z=s==="browser-devtools"||s==="node-devtools"||s==="backend-devtools"||s==="android-devtools",F=re(o,d),c=(0,l.classifyCodexTool)(y),J=z&&(0,v.isNestedToolContainer)(c.tool_name,s),D=J?(0,v.extractNestedToolCallsFromResponse)(w,s):null,g=D!==null?{isError:!1,errorText:void 0}:oe(w);if(z){const C=c.tool_name,f=(0,q.recordingToolsForServer)(s);f!==null&&(C===f.startTool?(0,r.setRecordingActive)(n,!0):C===f.stopTool&&(0,r.setRecordingActive)(n,!1));const E=(0,r.getActiveActivityId)(n),u={...(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??s,tool_input:$,tool_input_size:h($),tool_response_size:g.isError?0:h(w),duration:F};E&&(u.activity_id=E);const B=ne(m);B!==void 0?u.id=B:d.length>0&&(u.id=(0,R.deriveToolCallEventIdFromToolUseId)(o,d)),d&&(u.tool_use_id=d);const k=(0,r.getActiveVerificationId)(n);k&&(u.verification_id=k);const S=(0,r.getActiveTraceId)(n);if(S&&(u.trace_id=S),g.isError&&(u.error=g.errorText),await(0,T.appendAction)(i,u),J&&!g.isError){const G=D??(0,v.extractNestedToolCalls)($??m,s),L=new Set;for(const _ of G){if(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})`))),L.has(_.name))continue;L.add(_.name);const I={...(0,T.baseFields)(i),type:"tool_call",timestamp:Date.now(),tool_name:_.name,tool_type:"mcp",tool_input:_.args,duration:null,mcp_server: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,A.writeAndExit)(JSON.stringify({}),0);return}if(!(0,U.isJobQueueEnabled)(t)){(0,A.writeAndExit)(JSON.stringify({}),0);return}const M=(0,r.getActiveActivityId)(n),V=(0,l.extractCodexToolInput)(y,m),Q=h(m),Y=g.isError?0:h(w),p={...(0,T.baseFields)(i),type:"tool_call",timestamp:Date.now(),tool_type:c.tool_type,tool_name:c.tool_name||(0,l.normalizeCodexToolName)(y),mcp_server:c.mcp_server,tool_input:V,tool_input_size:Q,tool_response_size:Y,duration:F};M&&(p.activity_id=M),d.length>0&&(p.id=(0,R.deriveToolCallEventIdFromToolUseId)(o,d)),d&&(p.tool_use_id=d);const O=(0,r.getActiveVerificationId)(n);O&&(p.verification_id=O);const j=(0,r.getActiveTraceId)(n);j&&(p.trace_id=j),g.isError&&(p.error=g.errorText);try{(0,x.submit)(t,o,x.SEND_EVENT_TYPE,p)}catch(C){C 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}: ${C}`)}(0,A.writeAndExit)(JSON.stringify({}),0)}b(ie,"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 _=Object.defineProperty;var Z=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var ee=Object.prototype.hasOwnProperty;var y=(f,e)=>_(f,"name",{value:e,configurable:!0});var oe=(f,e)=>{for(var o in e)_(f,o,{get:e[o],enumerable:!0})},ne=(f,e,o,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of j(e))!ee.call(f,i)&&i!==o&&_(f,i,{get:()=>e[i],enumerable:!(s=Z(e,i))||s.enumerable});return f};var te=f=>ne(_({},"__esModule",{value:!0}),f);var le={};oe(le,{CodexClient:()=>se});module.exports=te(le);var r=require("fs"),g=require("path"),O=require("../../lib/gitignore"),b=require("../../lib/logger"),d=require("../../lib/output"),P=require("../../lib/fs-prune"),c=require("../../lib/config"),C=require("../../lib/platform-section"),n=require("./util"),M=require("./thread-map"),L=require("./hooks/verify-gate"),F=require("./hooks/activity-end"),G=require("./hooks/session-start"),J=require("./hooks/activity-start"),K=require("./hooks/require-verification"),U=require("./hooks/require-verdict"),q=require("./hooks/clear-verdict"),D=require("./hooks/track-action"),X=require("./hooks/track-action-monitor"),W=require("./hooks/track-action-pre"),Y=require("./hooks/subagent-start"),z=require("./hooks/subagent-stop");const x="browser-devtools",w="node-devtools",E="backend-devtools",T="android-devtools",ie="ironbee",k="ironbee-verifier",R=30,V="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.";function A(f){return(0,g.join)(__dirname,"..",f,"platforms")}y(A,"platformsDirFor");function h(f){return d.pc.dim(f)}y(h,"codexColor");function B(f){return f.hooks.some(e=>e.command.includes(ie))}y(B,"isIronBeeHookGroup");function re(f){const e=Object.keys(f);return e.length===0?!0:e.length===1&&e[0]==="hooks"?Object.keys(f.hooks??{}).length===0:!1}y(re,"isCodexHooksEmpty");class se{constructor(){this.name="codex";this.supportsVerifierModel=!0}static{y(this,"CodexClient")}detect(e){return(0,r.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 s=o??(0,c.loadConfig)(e),i=(0,c.getVerificationMode)(s),t=i!=="monitor",a=(0,c.getCodexVerifierMode)(s);this.cleanupArtifacts(e);const l=(0,n.codexHooksJsonPath)(e);if(this.mergeHooksConfig(l,i,a),this.mergeConfigToml(e,s,t,a),t&&(i==="enforce"&&this.writeAgentsMdBlock(e,s,a),this.writeSkills(e,i==="enforce",s,a),(0,C.syncPlatformSectionsToConfig)(e,A)),(0,O.ensureIronBeeGitignored)(e),console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} hooks ${d.pc.dim("\u2192")} ${d.pc.dim(l)}`),console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} config ${d.pc.dim("\u2192")} ${d.pc.dim((0,n.codexConfigTomlPath)(e))}`),t){const p=a==="main-agent"?`${d.pc.yellow("main-agent")} (the main agent drives the devtools tools directly)`:`${d.pc.bold("sub-agent")} (delegated to the ironbee-verifier custom agent)`;console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} verify ${d.pc.dim("\u2192")} ${p}`)}i==="enforce"?(console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} agents ${d.pc.dim("\u2192")} ${d.pc.dim((0,g.join)(e,"AGENTS.md"))}`),console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} skill ${d.pc.dim("\u2192")} ${d.pc.dim((0,g.join)(e,".agents","skills","ironbee-verification","SKILL.md"))}`),console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} command ${d.pc.dim("\u2192")} ${d.pc.dim((0,g.join)(e,".agents","skills","ironbee-verify","SKILL.md"))}`)):i==="assist"?(console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} ${d.pc.yellow("assist mode")} (verification.auto: false) \u2014 manual $ironbee-verify only, no enforcement`),console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} command ${d.pc.dim("\u2192")} ${d.pc.dim((0,g.join)(e,".agents","skills","ironbee-verify","SKILL.md"))}`)):console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} ${d.pc.yellow("monitoring-only mode")} (verification.enable: false)`),console.log(),console.log(` ${d.pc.yellow("\u26A0")} ${d.pc.yellow("Codex requires one-time TUI setup:")}`),console.log(` ${d.pc.yellow("1.")} Run ${d.pc.bold("/hooks")} in a fresh Codex session to review and trust IronBee hooks`),console.log(` ${d.pc.yellow("2.")} Restart any open Codex sessions to pick up new hook config`)}uninstall(e){this.cleanupArtifacts(e),(0,r.existsSync)((0,n.codexHooksJsonPath)(e))||this.removeFeaturesHooksFlag(e),(0,P.pruneEmptyDirs)((0,g.join)(e,".codex"));const o=(0,M.codexThreadMapPath)(e);if((0,r.existsSync)(o))try{(0,r.unlinkSync)(o)}catch(s){b.logger.debug(`failed to remove codex thread map: ${s}`)}console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} removed hooks, MCP entries, AGENTS.md block, and skills`)}removeFeaturesHooksFlag(e){const o=(0,n.codexConfigTomlPath)(e);if((0,r.existsSync)(o))try{const s=(0,r.readFileSync)(o,"utf-8"),i=(0,n.removeFeaturesHooks)(s);i.trim().length===0?(0,r.unlinkSync)(o):i!==s&&(0,r.writeFileSync)(o,i)}catch(s){b.logger.debug(`failed to strip [features] hooks from config.toml: ${s}`)}}cleanupArtifacts(e){this.migrateAwayFromUserLevel();const o=(0,n.codexHooksJsonPath)(e);this.removeIronBeeHooks(o),this.maybeDeleteEmptyHooks(o),this.removeIronBeeMcpServers(e),this.removeVerifierAgentToml(e);const s=(0,g.join)(e,"AGENTS.md");if((0,r.existsSync)(s))try{const t=(0,r.readFileSync)(s,"utf-8"),a=(0,n.stripAgentsMdBlock)(t);a===null?(0,r.unlinkSync)(s):a!==t&&(0,r.writeFileSync)(s,a)}catch(t){b.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")),(0,P.pruneEmptyDirs)((0,g.join)(e,".agents"))}async runVerifyGate(e){await(0,L.run)(e)}async runActivityEnd(e){await(0,F.run)(e)}async runSessionStart(e){await(0,G.run)(e)}async runActivityStart(e){await(0,J.run)(e)}async runRequireVerification(e,o){await(0,K.run)(e,o)}async runRequireVerdict(e,o){await(0,U.run)(e,o)}async runClearVerdict(e){await(0,q.run)(e)}async runTrackAction(e){await(0,D.run)(e)}async runTrackActionMonitor(e){await(0,X.run)(e)}async runTrackActionPre(e){await(0,W.run)(e)}async runSubagentStart(e){await(0,Y.run)(e)}async runSubagentStop(e){await(0,z.run)(e)}resolveAgentSessionId(e,o){const s=process.env.CODEX_THREAD_ID;if(typeof s=="string"&&s.length>0&&o)return(0,M.lookupThreadSession)(o,s)}async runSessionEnd(e){b.logger.debug("session-end: no-op on Codex (no SessionEnd hook event)")}mergeHooksConfig(e,o,s){const i=o!=="monitor",t=o==="assist"?" --soft":"";(0,r.mkdirSync)((0,g.dirname)(e),{recursive:!0});let a={hooks:{}};if((0,r.existsSync)(e))try{a=JSON.parse((0,r.readFileSync)(e,"utf-8")),a.hooks||(a.hooks={})}catch(u){b.logger.debug(`failed to parse ${e}: ${u}`),a={hooks:{}}}for(const u of Object.keys(a.hooks)){const m=a.hooks[u].filter(S=>!B(S));m.length===0?delete a.hooks[u]:a.hooks[u]=m}const l=y((u,m,S)=>{a.hooks[u]||(a.hooks[u]=[]),a.hooks[u].push({matcher:m,hooks:[{type:"command",command:S}]})},"addGroup");l("SessionStart",".*","ironbee hook session-start --client codex"),l("UserPromptSubmit",".*","ironbee hook activity-start --client codex"),l("PreToolUse",".*","ironbee hook track-action-pre --client codex"),i&&(l("PreToolUse","^mcp__(browser|node|backend|android)[-_]devtools__.*",`ironbee hook require-verification --client codex${t}`),l("PreToolUse","^apply_patch$",`ironbee hook require-verdict --client codex${t}`),l("PostToolUse","^apply_patch$","ironbee hook clear-verdict --client codex"),s==="sub-agent"&&l("SubagentStart",".*","ironbee hook subagent-start --client codex")),l("SubagentStop",".*","ironbee hook subagent-stop --client codex"),l("PostToolUse",".*",i?"ironbee hook track-action --client codex":"ironbee hook track-action-monitor --client codex"),l("Stop",".*",o==="enforce"?"ironbee hook verify-gate --client codex":"ironbee hook activity-end --client codex"),(0,r.writeFileSync)(e,JSON.stringify(a,null,2))}removeIronBeeHooks(e){if((0,r.existsSync)(e))try{const o=(0,r.readFileSync)(e,"utf-8"),s=JSON.parse(o);if(!s.hooks)return;let i=!1;for(const t of Object.keys(s.hooks)){const a=s.hooks[t].filter(l=>!B(l));a.length!==s.hooks[t].length&&(i=!0),a.length===0?delete s.hooks[t]:s.hooks[t]=a}i&&(0,r.writeFileSync)(e,JSON.stringify(s,null,2))}catch(o){b.logger.debug(`failed to strip IronBee hooks from ${e}: ${o}`)}}maybeDeleteEmptyHooks(e){if((0,r.existsSync)(e))try{const o=JSON.parse((0,r.readFileSync)(e,"utf-8"));re(o)&&(0,r.unlinkSync)(e)}catch(o){b.logger.debug(`failed to inspect ${e} for emptiness: ${o}`)}}mergeConfigToml(e,o,s,i){(0,r.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,x),t=(0,n.removeMcpServer)(t,w),t=(0,n.removeMcpServer)(t,E),t=(0,n.removeMcpServer)(t,T),s&&i==="main-agent"){t=this.upsertSessionMcpServers(t,e,o),t=(0,n.removeAgentsTable)(t,k),t=(0,n.removeMultiAgentV2SpawnMetadata)(t),this.removeVerifierAgentToml(e),(0,n.writeCodexConfigToml)(e,t);return}if(s){const a=(0,c.getVerificationModel)(o,"codex"),l=(0,r.existsSync)((0,n.userCodexConfigTomlPath)())?(0,r.readFileSync)((0,n.userCodexConfigTomlPath)(),"utf-8"):"",p=(0,n.extractTomlTopLevelModel)(t)===null&&(0,n.extractTomlTopLevelModel)(l)===null;a===void 0&&p&&console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} ${d.pc.yellow("\u26A0 no model for the verifier")} \u2014 the ${d.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 ${d.pc.bold("model")}, so it may fail to spawn ("could not resolve the child model"). Fix: set ${d.pc.bold("model")} in ~/.codex/config.toml, or set ${d.pc.bold("verification.model")} in your ironbee config.`),this.writeVerifierAgentToml(e,o,a),t=(0,n.upsertAgentsTable)(t,k,[`description = ${JSON.stringify(V)}`,`config_file = ${JSON.stringify(`agents/${k}.toml`)}`]),t=(0,n.ensureMultiAgentV2SpawnMetadataExposed)(t)}else t=(0,n.removeAgentsTable)(t,k),t=(0,n.removeMultiAgentV2SpawnMetadata)(t),this.removeVerifierAgentToml(e);(0,n.writeCodexConfigToml)(e,t)}writeVerifierAgentToml(e,o,s){const i=(0,g.join)(__dirname,"agents",`${k}.md`);let t;try{t=(0,r.readFileSync)(i,"utf-8")}catch(u){b.logger.debug(`failed to read verifier agent source ${i}: ${u}`);return}const a=A("codex");for(const u of c.ALL_CYCLES){const S=(0,c.isCycleEnabled)(o,u)?H=>{const $=(0,g.join)(a,(0,C.fragmentFilename)("skill",u,H));return(0,r.existsSync)($)?(0,r.readFileSync)($,"utf-8").trimEnd():null}:null;t=(0,C.applyPlatformSection)(t,u,S,`${k}.toml`)}const l=[];l.push(`name = ${JSON.stringify(k)}`),l.push(`description = ${JSON.stringify(V)}`),l.push('sandbox_mode = "read-only"'),s&&l.push(`model = ${JSON.stringify(s)}`),l.push("developer_instructions = '''"),l.push(t.replace(/'''/g,"```").trimEnd()),l.push("'''");const p=y((u,m,S)=>{u&&(l.push(""),l.push(`[mcp_servers.${m}]`),l.push(...N(S)),l.push(`startup_timeout_sec = ${R}`),l.push("required = true"),l.push('default_tools_approval_mode = "approve"'))},"addCycle");p((0,c.isCycleEnabled)(o,"browser"),x,(0,c.getMcpServerEntry)(e)),p((0,c.isCycleEnabled)(o,"node"),w,(0,c.getNodeDevToolsMcpEntry)(e)),p((0,c.isCycleEnabled)(o,"backend"),E,(0,c.getBackendDevToolsMcpEntry)(e)),p((0,c.isCycleEnabled)(o,"android"),T,(0,c.getAndroidDevToolsMcpEntry)(e));const v=(0,n.codexAgentTomlPath)(e,k);(0,r.mkdirSync)((0,g.dirname)(v),{recursive:!0}),(0,r.writeFileSync)(v,l.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,s){let i=e;const t=y((a,l,p)=>{if(!a)return;const v=[...N(p),`startup_timeout_sec = ${R}`,'default_tools_approval_mode = "approve"'];i=(0,n.upsertMcpServer)(i,l,v)},"addCycle");return t((0,c.isCycleEnabled)(s,"browser"),x,(0,c.getMcpServerEntry)(o)),t((0,c.isCycleEnabled)(s,"node"),w,(0,c.getNodeDevToolsMcpEntry)(o)),t((0,c.isCycleEnabled)(s,"backend"),E,(0,c.getBackendDevToolsMcpEntry)(o)),t((0,c.isCycleEnabled)(s,"android"),T,(0,c.getAndroidDevToolsMcpEntry)(o)),i}removeVerifierAgentToml(e){const o=(0,n.codexAgentTomlPath)(e,k);if((0,r.existsSync)(o))try{(0,r.unlinkSync)(o)}catch(s){b.logger.debug(`failed to remove verifier agent toml: ${s}`)}}removeIronBeeMcpServers(e){let o=(0,n.readCodexConfigToml)(e);o&&(o=(0,n.removeMcpServer)(o,x),o=(0,n.removeMcpServer)(o,w),o=(0,n.removeMcpServer)(o,E),o=(0,n.removeMcpServer)(o,T),o=(0,n.removeAgentsTable)(o,k),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,r.existsSync)(o))try{let i=(0,r.readFileSync)(o,"utf-8");const t=i;i=(0,n.removeMcpServer)(i,x),i=(0,n.removeMcpServer)(i,w),i=(0,n.removeMcpServer)(i,E),i=(0,n.removeMcpServer)(i,T),i=(0,n.removeAgentsTable)(i,k),i=(0,n.removeMultiAgentV2SpawnMetadata)(i),i!==t&&(0,r.writeFileSync)(o,i)}catch(i){b.logger.debug(`migrate: failed to clean user-level config.toml: ${i}`)}const s=(0,n.userCodexAgentTomlPath)(k);if((0,r.existsSync)(s))try{(0,r.unlinkSync)(s)}catch(i){b.logger.debug(`migrate: failed to remove user-level verifier toml: ${i}`)}}writeAgentsMdBlock(e,o,s){const i=(0,g.join)(e,"AGENTS.md"),t=s==="main-agent"?"ironbee-verification.main.md":"ironbee-verification.md",a=(0,g.join)(__dirname,"rules",t);let l;try{l=(0,r.readFileSync)(a,"utf-8")}catch(m){b.logger.debug(`failed to read rule source ${a}: ${m}`);return}const p=A("codex");for(const m of c.ALL_CYCLES){const H=(0,c.isCycleEnabled)(o,m)?$=>{const I=(0,g.join)(p,(0,C.fragmentFilename)("rule",m,$));if(!(0,r.existsSync)(I)){const Q=$.length>0?`${m}:${$}`:m;return b.logger.debug(`AGENTS.md platform-section ${Q}: missing fragment ${I}, using placeholder`),null}return(0,r.readFileSync)(I,"utf-8").trimEnd()}:null;l=(0,C.applyPlatformSection)(l,m,H,"AGENTS.md")}const v=(0,r.existsSync)(i)?(0,r.readFileSync)(i,"utf-8"):"",u=(0,n.upsertAgentsMdBlock)(v,l);(0,r.writeFileSync)(i,u)}writeSkills(e,o,s,i){const t=(0,g.join)(e,".agents","skills"),a=i==="main-agent";if(o){const v=(0,g.join)(t,"ironbee-verification");(0,r.mkdirSync)(v,{recursive:!0});const u=(0,g.join)(__dirname,"skills",a?"ironbee-verification.main.md":"ironbee-verification.md");try{let m=(0,r.readFileSync)(u,"utf-8");a&&(m=this.spliceCycleFragments(m,"skill",s,"ironbee-verification/SKILL.md")),(0,r.writeFileSync)((0,g.join)(v,"SKILL.md"),m)}catch(m){b.logger.debug(`failed to copy skill ${u}: ${m}`)}}const l=(0,g.join)(t,"ironbee-verify");(0,r.mkdirSync)(l,{recursive:!0});const p=(0,g.join)(__dirname,"commands","ironbee-verify",a?"SKILL.main.md":"SKILL.md");try{let v=(0,r.readFileSync)(p,"utf-8");a&&(v=this.spliceCycleFragments(v,"command-verify",s,"ironbee-verify/SKILL.md")),(0,r.writeFileSync)((0,g.join)(l,"SKILL.md"),v)}catch(v){b.logger.debug(`failed to copy verify command ${p}: ${v}`)}}spliceCycleFragments(e,o,s,i){const t=A("codex");let a=e;for(const l of c.ALL_CYCLES){const v=(0,c.isCycleEnabled)(s,l)?u=>{const m=(0,g.join)(t,(0,C.fragmentFilename)(o,l,u));return(0,r.existsSync)(m)?(0,r.readFileSync)(m,"utf-8").trimEnd():null}:null;a=(0,C.applyPlatformSection)(a,l,v,i)}return a}removeDir(e){if((0,r.existsSync)(e))try{(0,r.rmSync)(e,{recursive:!0,force:!0})}catch(o){b.logger.debug(`failed to remove ${e}: ${o}`)}}}function N(f){return(0,n.tomlBodyFromRecord)(f)}y(N,"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
 
@@ -0,0 +1,32 @@
1
+ ### android platform (enabled)
2
+ - **Use for**: Android app scenarios on a real device / emulator.
3
+ - **Server**: `android-devtools` · **scenario tools**: the `adt_scenario-*` tools
4
+ (`adt_scenario-add` / `-update` / `-delete` / `-list` / `-search` / `-run`).
5
+ - **Store**: project → `.ironbee/scenarios/adt`, global → `~/.ironbee/scenarios/adt` (the
6
+ server's `SCENARIOS_DIR`; you pass `scope`, the server resolves the path).
7
+ - Scenario **scripts** call this platform's tools via `callTool('<bare-tool>', {...})` — discover
8
+ the available `adt_*` tool names from your connected MCP tool schemas; don't guess.
9
+
10
+ **What to test & how — capture the SAME evidence the verifier would** (a scenario runs FOR
11
+ verification, so its script must collect what the android cycle collects). In the script:
12
+ 1. **Connect + launch** — `adt_device_connect` (list targets with `adt_device_list-targets`; an
13
+ emulator is usually `emulator-5554`), then `adt_device_launch-app` with the package name.
14
+ 2. Pick an **evidence path** for the changed code area:
15
+ - **Device-evidence path** — drive the UI to exercise the change (`adt_interaction_tap` /
16
+ `adt_interaction_input-text` / `adt_interaction_swipe` / `adt_interaction_scroll`; locate elements
17
+ with `adt_a11y_find-element` / the UI-snapshot's element refs — do NOT hand-parse the snapshot
18
+ TEXT with regex), then capture **BOTH**: a screenshot (`adt_content_take-screenshot`
19
+ **with `returnOutput: true`** — put the returned `filePath` in your result; the verifier `Read`s
20
+ that file to judge the pixels. **Do NOT set `includeBase64`** — a nested scenario screenshot isn't
21
+ surfaced as an inline image and base64 only bloats the result) **AND** a UI snapshot
22
+ (`adt_a11y_take-ui-snapshot`, `returnOutput: true` — its TEXT view hierarchy / labels is what the
23
+ verifier reads). Both are MANDATORY (visual + structural, like the browser screenshot + aria pair).
24
+ - **Log-evidence path** — `adt_o11y_log-read` / `adt_o11y_log-follow` (with `returnOutput: true`)
25
+ for the tag(s) relevant to the change; confirm expected lines appear AND no FATAL / crash (E/
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.
28
+
29
+ `return` the evidence — UI-snapshot text, log lines, the screenshot `filePath`s — **plus explicit
30
+ pass/fail assertions**. That returned result is what `$ironbee-verify scenario:<name>` reads to judge
31
+ functional + structural (from the text) and **visual** (by `Read`ing the returned screenshot files).
32
+ **`android-devtools` is Android-only.**
@@ -0,0 +1,26 @@
1
+ ### backend platform (enabled)
2
+ - **Use for**: backend protocol scenarios (HTTP / gRPC / GraphQL / WebSocket / DB).
3
+ - **Server**: `backend-devtools` · **scenario tools**: the `bedt_scenario-*` tools
4
+ (`bedt_scenario-add` / `-update` / `-delete` / `-list` / `-search` / `-run`).
5
+ - **Store**: project → `.ironbee/scenarios/bedt`, global → `~/.ironbee/scenarios/bedt` (the
6
+ server's `SCENARIOS_DIR`; you pass `scope`, the server resolves the path).
7
+ - Scenario **scripts** call this platform's tools via `callTool('<bare-tool>', {...})` — discover
8
+ the available `bedt_*` tool names from your connected MCP tool schemas; don't guess.
9
+
10
+ **What to test & how — capture the SAME evidence the verifier would** (a scenario runs FOR
11
+ verification, so its script must collect what the backend cycle collects). At least ONE evidence path
12
+ is required — in the script, exercise one+:
13
+ - **Protocol-call** — `bedt_request_http` / `bedt_request_grpc` / `bedt_request_graphql` /
14
+ `bedt_request_websocket-open…` / `bedt_request_replay`; inspect the response `status` / body /
15
+ headers (4xx/5xx and gRPC non-OK are NORMAL results, not transport errors — decide pass/fail by what
16
+ the task requires). Chain POST→GET to confirm side effects.
17
+ - **Log-evidence** — `bedt_log_register-source` then `bedt_log_read` / `bedt_log_read-multi` /
18
+ `bedt_log_follow` (filter by level / pattern / trace-id) when an external driver hits the endpoint.
19
+ - **DB-evidence** — `bedt_db_connect` (read-only by default) then `bedt_db_query` /
20
+ `bedt_db_describe-table` / `bedt_db_snapshot` + `bedt_db_diff` to inspect state after a migration /
21
+ write.
22
+
23
+ `return` the responses / log lines / rows (capture each read with `returnOutput: true` so the data
24
+ reaches the script's `return`) **plus explicit pass/fail assertions** so a later verify run can judge
25
+ them. Runtime-agnostic —
26
+ works for any backend language (Node, Java, Python, Go, Rust, Ruby, .NET, …).
@@ -0,0 +1,40 @@
1
+ ### browser platform (enabled)
2
+ - **Use for**: UI / frontend scenarios driven through a real browser.
3
+ - **Server**: `browser-devtools` · **scenario tools**: the `bdt_scenario-*` tools
4
+ (`bdt_scenario-add` / `-update` / `-delete` / `-list` / `-search` / `-run`).
5
+ - **Store**: project → `.ironbee/scenarios/bdt`, global → `~/.ironbee/scenarios/bdt` (the
6
+ server's `SCENARIOS_DIR`; you pass `scope`, the server resolves the path).
7
+ - Scenario **scripts** call this platform's tools via `callTool('<bare-tool>', {...})` — discover
8
+ the available `bdt_*` tool names from your connected MCP tool schemas; don't guess.
9
+
10
+ **What to test & how — capture the SAME evidence the verifier would** (a scenario runs FOR
11
+ verification, so its script must collect what the browser cycle collects). In the script:
12
+ 1. **Navigate** — `bdt_navigation_go-to` to the affected page(s), then **actually interact** (click
13
+ buttons, fill forms, submit data, trigger the workflow that changed). A click-through that asserts
14
+ nothing verifies nothing — the interaction is what makes the evidence meaningful. **Target elements
15
+ with the `selector`/`ref` the aria-snapshot returns for each** (e.g. `getByRole(...)` or `@e12`) —
16
+ do NOT hand-parse the snapshot TEXT with regex/string-matching: embedded quotes or special chars in
17
+ labels make that brittle (it silently misses elements). This includes deriving a positional
18
+ **`.nth(i)`** index by parsing the snapshot — a quote or special char in any earlier label shifts
19
+ every index, so the click lands on the wrong element (or none). Pick each element by its own
20
+ `getByRole(...)`/`ref`, or scope it to the matching card/row with a CSS `:has()` selector (e.g.
21
+ `.product-card:has(h4:has-text('Widget')) button:has-text('Add to cart')`). NOTE: the
22
+ browser-devtools resolver accepts only a flat `getByXYZ(...)` expression OR a CSS string — Playwright
23
+ locator chaining like `.filter({ hasText })` does NOT parse. Never compute element positions from
24
+ snapshot text.
25
+ 2. **Screenshot** — `bdt_content_take-screenshot` (or `includeScreenshot: true` on a nav/interaction
26
+ call) **with `returnOutput: true`, and put the returned `filePath` (absolute path to the saved PNG)
27
+ in your result**. The later verifier opens that file with its `Read` tool to judge the pixels
28
+ (readability, layout, cut-off content, expected render). **Do NOT set `includeBase64`** — a nested
29
+ scenario screenshot is NOT surfaced as an inline MCP image (`scenario-run` strips nested image data)
30
+ and base64 only bloats the result; the returned `filePath` is how visual judging works.
31
+ 3. **Accessibility** — `bdt_a11y_take-aria-snapshot` (or `includeSnapshot: true`), called with
32
+ `returnOutput: true` — the snapshot TEXT is what the verifier reads to judge page structure.
33
+ 4. **Console** — `bdt_o11y_get-console-messages` with `returnOutput: true` to surface errors.
34
+
35
+ `return` the evidence — aria-snapshot text, page text (`bdt_content_get-as-text`), console errors, the
36
+ screenshot `filePath`s — **plus explicit pass/fail assertions**. That returned result is what
37
+ `$ironbee-verify scenario:<name>` reads to judge the run: functional + structural from the text, and
38
+ **visual by `Read`ing the returned screenshot files**. Capture the evidence AFTER the interactions
39
+ whose state you want to assert; for an intermediate state (a modal that opens then closes) capture at
40
+ that point too.
@@ -0,0 +1,27 @@
1
+ ### node platform (enabled)
2
+ - **Use for**: Node.js runtime-debug scenarios (V8 inspector probes / logs).
3
+ - **Server**: `node-devtools` · **scenario tools**: the `ndt_scenario-*` tools
4
+ (`ndt_scenario-add` / `-update` / `-delete` / `-list` / `-search` / `-run`).
5
+ - **Store**: project → `.ironbee/scenarios/ndt`, global → `~/.ironbee/scenarios/ndt` (the
6
+ server's `SCENARIOS_DIR`; you pass `scope`, the server resolves the path).
7
+ - Scenario **scripts** call this platform's tools via `callTool('<bare-tool>', {...})` — discover
8
+ the available `ndt_*` tool names from your connected MCP tool schemas; don't guess.
9
+
10
+ **What to test & how — capture the SAME evidence the verifier would** (a scenario runs FOR
11
+ verification, so its script must collect what the node cycle collects). In the script:
12
+ 1. **Connect** — `ndt_debug_connect` (one of `pid` / `processName` / `containerName` /
13
+ `inspectorPort` / `wsUrl`).
14
+ 2. Pick an **evidence path** for the changed code path:
15
+ - **Probe path** (proves the code path executed) — set a probe at the changed location
16
+ (`ndt_debug_put-tracepoint` / `ndt_debug_put-logpoint` / `ndt_debug_put-exceptionpoint`),
17
+ **exercise the path** (drive it via a request / CLI / another platform's call — without this the
18
+ probe never fires), then read `ndt_debug_get-probe-snapshots`; at least one probe must come back
19
+ `triggered: true`.
20
+ - **Log path** (proves no errors during execution) — exercise the path, then `ndt_debug_get-logs`
21
+ filtered to the error level (no ERROR-level entries = pass).
22
+
23
+ `return` the probe snapshots / logs (read them with `returnOutput: true` so their data reaches the
24
+ script's `return`) **plus explicit pass/fail assertions** so a later verify run can judge them.
25
+ **`node-devtools` is
26
+ Node.js ONLY** — never author `ndt_*` scenarios for Java / Python / Go / Rust / Ruby / .NET / PHP
27
+ backends; use the **backend** platform for those.
@@ -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});