@ironbee-ai/cli 0.24.0 → 0.25.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.
- package/CHANGELOG.md +6 -0
- package/dist/clients/claude/agents/ironbee-verifier.md +21 -2
- package/dist/clients/codex/agents/ironbee-verifier.md +7 -1
- package/dist/clients/codex/commands/ironbee-verify/SKILL.md +1 -0
- package/dist/clients/cursor/skills/ironbee-verification.md +2 -1
- package/dist/commands/mode-select.js +2 -2
- package/dist/commands/status.js +1 -1
- package/dist/commands/verification-toggle.js +2 -2
- package/dist/commands/verification.js +1 -1
- package/dist/commands/verify.js +3 -3
- package/dist/hooks/core/actions.js +7 -6
- package/dist/hooks/core/submit-verdict.js +3 -3
- package/dist/hooks/core/verify-gate.js +36 -26
- package/dist/lib/config.js +1 -1
- package/dist/lib/install-version.js +1 -1
- package/dist/tui/config/schema.js +1 -1
- package/dist/tui/sessions/area.js +3 -3
- package/dist/tui/sessions/read.js +2 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.25.0 (2026-06-16)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* **verification:** N/A verdicts (global + per-platform) + strict mode; break no_tools loop ([#27](https://github.com/ironbee-ai/ironbee-cli/issues/27)) ([afab236](https://github.com/ironbee-ai/ironbee-cli/commit/afab23606b478d801a86e6c297c9eef5911e26e5))
|
|
8
|
+
|
|
3
9
|
## 0.24.0 (2026-06-14)
|
|
4
10
|
|
|
5
11
|
### Features
|
|
@@ -74,8 +74,27 @@ echo '{"status":"pass","checks":["..."]}' | ironbee hook submit-verdict
|
|
|
74
74
|
- Fail → `{ "status": "fail", "checks": [...], "issues": [...] }` (what failed).
|
|
75
75
|
- You do **not** supply `fixes` — you didn't perform the fix. IronBee fills it from what
|
|
76
76
|
the main agent recorded / changed.
|
|
77
|
-
-
|
|
78
|
-
|
|
77
|
+
- **Nothing to verify? Use N/A — do NOT fake evidence.** If the change has no runtime
|
|
78
|
+
surface to exercise (a type-only edit, a pure refactor with no behavior change, a
|
|
79
|
+
config/constant tweak, a docs change that still tripped a cycle):
|
|
80
|
+
- Global N/A → `{ "status": "not_applicable", "reason": ["why there's no runtime surface"] }`
|
|
81
|
+
(no `checks` needed). Use this when NONE of the active cycles apply.
|
|
82
|
+
- Per-platform N/A → keep a normal `pass`/`fail` for the cycles you DID verify and
|
|
83
|
+
exempt the rest: `{ "status": "pass", "checks": [...], "not_applicable_cycles": ["browser"], "reason": ["server-only change, no UI path"] }`.
|
|
84
|
+
Use this for a mixed change — e.g. verify the backend/node cycle but exempt browser.
|
|
85
|
+
- `reason` is REQUIRED for either form. It is recorded and observable — be honest;
|
|
86
|
+
don't N/A something that genuinely has a surface.
|
|
87
|
+
- **Base "nothing to verify" on the FULL change set, not a clean working tree.**
|
|
88
|
+
The change you're verifying is often already COMMITTED (the main agent committed
|
|
89
|
+
before delegating). IronBee injects the changed-path list on your first devtools
|
|
90
|
+
call — it covers recent commits, not just uncommitted `git status`. Before
|
|
91
|
+
declaring N/A, check the committed changes too (e.g. `git diff HEAD~1 HEAD --stat`,
|
|
92
|
+
widen the range if the work spans more commits). A clean `git status` does NOT mean
|
|
93
|
+
there's nothing to verify.
|
|
94
|
+
- Strict mode rejects N/A (you'll be told). If so, actually exercise the tools or
|
|
95
|
+
report a fail.
|
|
96
|
+
- The Stop hook enforces that you called the required tools for every active (non-exempt)
|
|
97
|
+
cycle and that a pass/fail verdict carries non-empty `checks`.
|
|
79
98
|
6. Return a short summary to the main agent: the verdict status and, on fail, the issues so
|
|
80
99
|
it can fix and re-delegate.
|
|
81
100
|
|
|
@@ -55,9 +55,15 @@ echo '{"status":"pass","checks":["..."]}' | ironbee hook submit-verdict
|
|
|
55
55
|
```
|
|
56
56
|
echo '<verdict-json>' | ironbee hook submit-verdict
|
|
57
57
|
```
|
|
58
|
-
Platform-agnostic shape: `status`, `checks` (
|
|
58
|
+
Platform-agnostic shape: `status`, `checks` (required on pass/fail); add `issues` on fail. You
|
|
59
59
|
do NOT author `fixes` — the main agent records what it fixed (`record-fix`); `submit-verdict`
|
|
60
60
|
merges it. One verdict regardless of how many cycles ran.
|
|
61
|
+
**Nothing to verify? Use N/A — never fake evidence.** If the change has no runtime surface
|
|
62
|
+
(type-only edit, behavior-neutral refactor, config/docs that still tripped a cycle):
|
|
63
|
+
- Global N/A → `{"status":"not_applicable","reason":["why there's no runtime surface"]}` (no `checks`); use when NO active cycle applies.
|
|
64
|
+
- Per-platform N/A → a normal pass/fail for what you verified + exempt the rest: `{"status":"pass","checks":[...],"not_applicable_cycles":["browser"],"reason":["server-only change"]}`.
|
|
65
|
+
- `reason` is REQUIRED for either form (recorded + observable — be honest). Strict mode rejects N/A; if so, exercise the tools or report a fail.
|
|
66
|
+
- Base "nothing to verify" on the FULL change set, not a clean working tree — the change is often already COMMITTED. IronBee's injected changed-path list covers recent commits; also check `git diff HEAD~1 HEAD --stat` (widen if the work spans more commits) before declaring N/A.
|
|
61
67
|
|
|
62
68
|
## BANNED
|
|
63
69
|
- Writing `verdict.json` directly — always use `ironbee hook submit-verdict`.
|
|
@@ -48,6 +48,7 @@ Whatever the scenario directs, the gate is unchanged — you must still call eve
|
|
|
48
48
|
6. **Submit your verdict** via Bash. One verdict covers every active cycle:
|
|
49
49
|
- Pass: `echo '{"session_id":"...","status":"pass","checks":["..."]}' | ironbee hook submit-verdict`
|
|
50
50
|
- Fail: `echo '{"session_id":"...","status":"fail","checks":["..."],"issues":["describe what failed"]}' | ironbee hook submit-verdict`
|
|
51
|
+
- N/A (nothing to verify — never fake evidence): global `echo '{"session_id":"...","status":"not_applicable","reason":["no runtime surface — type-only/config/refactor"]}'`, or per-platform on a pass/fail verdict `"not_applicable_cycles":["browser"],"reason":["server-only change"]`. `reason` is REQUIRED (recorded + observable); strict mode rejects N/A.
|
|
51
52
|
7. **If failed** → collect ALL issues first (finish testing every active cycle) and submit ONE fail verdict with all issues. Then branch by mode:
|
|
52
53
|
- **Verify-only (default)**: report the issues to the user and stop — do not edit code. Suggest `$ironbee-verify fix` to repair them.
|
|
53
54
|
- **Fix mode (`fix` token)**: fix everything, rebuild, and re-verify until pass. Do not fix one issue at a time — batch fixes to avoid repeated build/restart cycles.
|
|
@@ -55,7 +55,8 @@ If already running, skip start. If the build fails, fix it before proceeding.
|
|
|
55
55
|
- Pass → `{ "session_id": "...", "status": "pass", "checks": [...] }`
|
|
56
56
|
- Fail → add `"issues": [...]` describing what failed.
|
|
57
57
|
- Pass after a previous fail → add `"fixes": [...]` describing what was repaired.
|
|
58
|
-
- **
|
|
58
|
+
- **Nothing to verify? Use N/A — never fake evidence.** When the change has no runtime surface (type-only edit, behavior-neutral refactor, config/docs that still tripped a cycle): global `{ "session_id": "...", "status": "not_applicable", "reason": ["why there's no runtime surface"] }` (no `checks`), or per-platform on a pass/fail verdict `"not_applicable_cycles": ["browser"], "reason": ["server-only change"]` to exempt some cycles while verifying others. `reason` is REQUIRED (recorded + observable); strict mode rejects N/A. Base "nothing to verify" on the FULL change set (the change is often already COMMITTED) — check `git diff HEAD~1 HEAD --stat`, not just a clean `git status`, before declaring N/A.
|
|
59
|
+
- **The stop hook enforces that you called the required tools for every active (non-exempt) cycle and that a pass/fail verdict carries non-empty `checks`.**
|
|
59
60
|
8. If failed → fix → rebuild → go back to step 2 → repeat until pass.
|
|
60
61
|
|
|
61
62
|
<!--IRONBEE:PLATFORM:browser-->
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var f=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var V=Object.prototype.hasOwnProperty;var
|
|
2
|
-
`)}
|
|
1
|
+
"use strict";var f=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var V=Object.prototype.hasOwnProperty;var t=(o,e)=>f(o,"name",{value:e,configurable:!0});var v=(o,e)=>{for(var n in e)f(o,n,{get:e[n],enumerable:!0})},M=(o,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of p(e))!V.call(o,i)&&i!==n&&f(o,i,{get:()=>e[i],enumerable:!(a=m(e,i))||a.enumerable});return o};var w=o=>M(f({},"__esModule",{value:!0}),o);var E={};v(E,{ALL_MODES:()=>g,MODE_HINTS:()=>C,MODE_LABELS:()=>L,applyModeToLayer:()=>O,buildVerificationBlockForMode:()=>y,parseModeFlag:()=>S,resolveInstallDefaultMode:()=>x});module.exports=w(E);var r=require("fs"),u=require("path"),c=require("../lib/config"),d=require("../lib/logger");const g=["enforce","assist","monitor"],L={enforce:"auto verify (enforce)",assist:"assist",monitor:"monitor only"},C={enforce:"block task completion until changes are verified \u2014 full enforcement (default)",assist:"tools installed but not enforced \u2014 the agent verifies manually via /ironbee-verify",monitor:"no enforcement \u2014 only track sessions / activity / tools for analytics"};function S(o){const e=o.trim().toLowerCase();if(e==="enforce"||e==="assist"||e==="monitor")return e;throw new Error(`Unknown mode '${o}'. Available: ${g.join(", ")}.`)}t(S,"parseModeFlag");function s(o){if(!(0,r.existsSync)(o))return{};try{return JSON.parse((0,r.readFileSync)(o,"utf-8"))}catch(e){throw d.logger.debug(`failed to read ${o}: ${e}`),new Error(`Config at ${o} is not valid JSON: ${e instanceof Error?e.message:e}`)}}t(s,"readLayerConfig");function B(o,e){(0,r.mkdirSync)((0,u.join)(o,".."),{recursive:!0}),(0,r.writeFileSync)(o,JSON.stringify(e,null,2)+`
|
|
2
|
+
`)}t(B,"writeLayerConfig");function l(o){const e=o.verification;if(e&&typeof e=="object"&&!Array.isArray(e))return e}t(l,"readVerificationBlock");function x(o){let e,n;for(const a of["project","local"]){const i=l(s((0,c.getTargetConfigPath)(a,o)));i!==void 0&&(typeof i.enable=="boolean"&&(e=i.enable),typeof i.auto=="boolean"&&(n=i.auto))}return e===!1?"monitor":n===!1?"assist":"enforce"}t(x,"resolveInstallDefaultMode");function y(o,e){const n={...o??{}};switch(e){case"enforce":n.enable=!0,n.auto=!0,n.strict=n.strict??!1;break;case"assist":n.enable=!0,n.auto=!1,n.strict=n.strict??!1;break;case"monitor":n.enable=!1,delete n.auto,delete n.strict;break}return n}t(y,"buildVerificationBlockForMode");function O(o,e,n){const a=(0,c.getTargetConfigPath)(e,o),i=s(a),b=JSON.stringify(i.verification??null);i.verification=y(l(i),n);const k=JSON.stringify(i.verification);return b===k?!1:(B(a,i),!0)}t(O,"applyModeToLayer");0&&(module.exports={ALL_MODES,MODE_HINTS,MODE_LABELS,applyModeToLayer,buildVerificationBlockForMode,parseModeFlag,resolveInstallDefaultMode});
|
package/dist/commands/status.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var d=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var m=(
|
|
1
|
+
"use strict";var d=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var m=(o,n)=>d(o,"name",{value:n,configurable:!0});var k=(o,n)=>{for(var e in n)d(o,e,{get:n[e],enumerable:!0})},S=(o,n,e,l)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of v(n))!h.call(o,t)&&t!==e&&d(o,t,{get:()=>n[t],enumerable:!(l=b(n,t))||l.enumerable});return o};var w=o=>S(d({},"__esModule",{value:!0}),o);var C={};k(C,{statusCommand:()=>_});module.exports=w(C);var y=require("commander"),i=require("fs"),c=require("path"),s=require("../lib/output");function j(o){const n=(0,c.join)(o,"actions.jsonl");if(!(0,i.existsSync)(n))return!1;let e;try{e=(0,i.readFileSync)(n,"utf-8")}catch{return!1}return e.includes('"type":"verification_requested"')||e.includes('"type": "verification_requested"')?!1:e.includes('"type":"session_start"')||e.includes('"type": "session_start"')}m(j,"isMonitoringOnlySession");const _=new y.Command("status").description("Show verification status for all active sessions").argument("[project-dir]","target project directory",".").action(o=>{const n=(0,c.resolve)(o),e=(0,c.join)(n,".ironbee","sessions");if(!(0,i.existsSync)(e)){s.log.warn("No .ironbee/sessions/ directory found. Run `ironbee install` first.");return}const l=(0,i.readdirSync)(e).filter(t=>(0,i.statSync)((0,c.join)(e,t)).isDirectory());if(l.length===0){s.log.dim(" .ironbee/sessions/ (no active sessions)");return}s.log.info(`Sessions in ${s.pc.dim(e)}`),s.log.blank();for(const t of l){const g=(0,c.join)(e,t,"verdict.json"),u=(0,c.join)(e,t,"retries"),a=(0,i.existsSync)(u)&&parseInt((0,i.readFileSync)(u,"utf-8"),10)||0;if(!(0,i.existsSync)(g)){console.log(` ${s.pc.bold(s.pc.cyan(t))}`),j((0,c.join)(e,t))?console.log(` ${s.pc.dim("verdict")} : ${s.pc.dim("none (monitoring-only session)")}`):console.log(` ${s.pc.dim("verdict")} : ${s.pc.yellow("missing")}`),a>0&&console.log(` ${s.pc.dim("retries")} : ${s.pc.yellow(`${a}/3`)}`),s.log.blank();continue}let r;try{r=JSON.parse((0,i.readFileSync)(g,"utf-8"))}catch{console.log(` ${s.pc.bold(s.pc.cyan(t))}`),console.log(` ${s.pc.dim("verdict")} : ${s.pc.red("invalid JSON")}`),s.log.blank();continue}const f=Array.isArray(r.checks)?r.checks.length:0,$=r.status==="pass"?s.pc.green:r.status==="not_applicable"?s.pc.dim:s.pc.red;if(console.log(` ${s.pc.bold(s.pc.cyan(t))}`),console.log(` ${s.pc.dim("status")} : ${$(r.status)}`),console.log(` ${s.pc.dim("checks")} : ${f>0?s.pc.green(String(f)):s.pc.yellow("0")}`),a>0&&console.log(` ${s.pc.dim("retries")} : ${s.pc.yellow(`${a}/3`)}`),r.status==="fail"&&r.issues?.length){console.log(` ${s.pc.dim("issues")} :`);for(const p of r.issues)console.log(` ${s.pc.red("\u2022")} ${p}`)}s.log.blank()}});0&&(module.exports={statusCommand});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`)}
|
|
1
|
+
"use strict";var k=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var M=Object.getOwnPropertyNames;var O=Object.prototype.hasOwnProperty;var c=(o,n)=>k(o,"name",{value:n,configurable:!0});var S=(o,n)=>{for(var i in n)k(o,i,{get:n[i],enumerable:!0})},W=(o,n,i,l)=>{if(n&&typeof n=="object"||typeof n=="function")for(let t of M(n))!O.call(o,t)&&t!==i&&k(o,t,{get:()=>n[t],enumerable:!(l=F(n,t))||l.enumerable});return o};var _=o=>W(k({},"__esModule",{value:!0}),o);var Y={};S(Y,{applyAutoVerifyToggle:()=>J,applyStrictVerifyToggle:()=>U,applyVerificationToggle:()=>G});module.exports=_(Y);var v=require("fs"),P=require("path"),B=require("../clients/registry"),r=require("../lib/config"),E=require("../lib/gitignore"),x=require("../lib/logger"),e=require("../lib/output");function p(o){if(!(0,v.existsSync)(o))return{};try{return JSON.parse((0,v.readFileSync)(o,"utf-8"))}catch(n){throw x.logger.debug(`failed to read ${o}: ${n}`),new Error(`Config at ${o} is not valid JSON: ${n instanceof Error?n.message:n}`)}}c(p,"readConfigFile");function N(o,n){(0,v.mkdirSync)((0,P.join)(o,".."),{recursive:!0}),(0,v.writeFileSync)(o,JSON.stringify(n,null,2)+`
|
|
2
|
+
`)}c(N,"writeConfigFile");function V(o,n){const i={global:void 0,project:void 0,local:void 0};for(const l of r.CONFIG_TARGETS_BY_PRECEDENCE){const t=(0,r.getTargetConfigPath)(l,o);if(!(0,v.existsSync)(t))continue;const C=p(t).verification?.[n];typeof C=="boolean"&&(i[l]=C)}return i}c(V,"readVerificationFieldByLayer");function L(o,n){const i=r.CONFIG_TARGETS_BY_PRECEDENCE,l=i.indexOf(o);for(let t=i.length-1;t>l;t--){const a=i[t];if(n[a]!==void 0)return a}return null}c(L,"detectOverridingLayer");function G(o,n,i,l){const t=(0,r.getTargetConfigPath)(i,n),a=p(t),d=(typeof a.verification?.enable=="boolean"?a.verification.enable:void 0)!==!1,m=(0,r.loadConfig)(n),g=(0,r.getVerificationEnabled)(m),R=o?"enabled":"disabled";if(d===o&&g===o){console.log(`${e.pc.dim("\xB7")} Verification already ${R} in ${i} config (${e.pc.dim(t)}). No-op.`);return}if(d===o&&g!==o){const h=V(n,"enable"),b=L(i,h),y=g?"enabled":"disabled";console.log(`${e.pc.yellow("\u26A0")} ${i} config already has verification.enable: ${o}, but the ${e.pc.bold(b??"another")} layer overrides it \u2014 effective state is ${e.pc.bold(y)}.`),b!==null&&console.log(` ${e.pc.dim("Run")} ${e.pc.cyan(`ironbee config unset verification.enable --${b}`)} ${e.pc.dim("to drop the override, or run this command with")} ${e.pc.cyan(`--${b}`)} ${e.pc.dim("to flip the layer that's actually winning.")}`);return}const w=(0,r.loadConfig)(n);w.verification={enable:o};const f=(0,B.resolveTargetClients)(n,l);l===void 0&&f.length===1&&!f[0].detect(n)&&console.log(`${e.pc.yellow("\u26A0")} No clients detected in ${e.pc.dim(n)} \u2014 applying to ${e.pc.bold(f[0].name)} as fallback.`);for(const h of f)h.install(n,w);i!=="global"&&(0,E.ensureIronBeeGitignored)(n);const u={...a,verification:{enable:o}};N(t,u);const s=o?"Enabled":"Disabled",T=o?"Full enforcement set installed (skill, rule, /ironbee-verify, MCP servers, all hooks).":"Monitoring-only mode \u2014 only session/activity/tool_call hooks are installed.";console.log(`${e.pc.green("\u2713")} ${s} verification in ${i} config (${e.pc.dim(t)}).`),console.log(` ${e.pc.dim(T)}`),console.log(` ${e.pc.yellow("\u26A0")} Restart your editor / agent session for the change to take effect.`)}c(G,"applyVerificationToggle");function J(o,n,i,l){const t=(0,r.getTargetConfigPath)(i,n),a=p(t),d=(typeof a.verification?.auto=="boolean"?a.verification.auto:void 0)!==!1,m=(0,r.loadConfig)(n),g=(0,r.getAutoVerifyEnabled)(m),R=(0,r.getVerificationEnabled)(m),w=o?"enabled":"disabled",f=c(()=>{R||console.log(` ${e.pc.yellow("\u26A0")} verification.enable is false (monitoring-only) \u2014 auto-verify has no effect until you run ${e.pc.cyan("ironbee verification enable")}.`)},"inertNote");if(d===o&&g===o){console.log(`${e.pc.dim("\xB7")} Auto-verify already ${w} in ${i} config (${e.pc.dim(t)}). No-op.`),f();return}if(d===o&&g!==o){const y=V(n,"auto"),$=L(i,y),I=g?"enabled":"disabled";console.log(`${e.pc.yellow("\u26A0")} ${i} config already has verification.auto: ${o}, but the ${e.pc.bold($??"another")} layer overrides it \u2014 effective auto-verify is ${e.pc.bold(I)}.`),$!==null&&console.log(` ${e.pc.dim("Run")} ${e.pc.cyan(`ironbee config unset verification.auto --${$}`)} ${e.pc.dim("to drop the override, or run this command with")} ${e.pc.cyan(`--${$}`)} ${e.pc.dim("to flip the layer that's actually winning.")}`);return}const u=(0,r.loadConfig)(n);u.verification={...u.verification,auto:o};const s=(0,B.resolveTargetClients)(n,l);l===void 0&&s.length===1&&!s[0].detect(n)&&console.log(`${e.pc.yellow("\u26A0")} No clients detected in ${e.pc.dim(n)} \u2014 applying to ${e.pc.bold(s[0].name)} as fallback.`);for(const y of s)y.install(n,u);i!=="global"&&(0,E.ensureIronBeeGitignored)(n);const T={...a,verification:{...a.verification,auto:o}};N(t,T);const h=o?"Enabled":"Disabled",b=o?"Enforce mode \u2014 blocking verify-gate + skill/rule/command + MCP servers installed.":"Assist mode \u2014 /ironbee-verify command + MCP servers installed; PreToolUse hooks run non-blocking, Stop never gates, skill/rule omitted.";console.log(`${e.pc.green("\u2713")} ${h} auto-verify in ${i} config (${e.pc.dim(t)}).`),console.log(` ${e.pc.dim(b)}`),f(),console.log(` ${e.pc.yellow("\u26A0")} Restart your editor / agent session for the change to take effect.`)}c(J,"applyAutoVerifyToggle");function U(o,n,i,l){const t=(0,r.getTargetConfigPath)(i,n),a=p(t),C=a.verification?.strict===!0,d=(0,r.loadConfig)(n),m=(0,r.getVerificationStrict)(d),g=(0,r.getVerificationEnabled)(d),R=(0,r.getAutoVerifyEnabled)(d),w=o?"enabled":"disabled",f=c(()=>{g?R||console.log(` ${e.pc.yellow("\u26A0")} verification.auto is false (assist mode) \u2014 the Stop gate never runs, so strict has no effect until you run ${e.pc.cyan("ironbee verification auto enable")}.`):console.log(` ${e.pc.yellow("\u26A0")} verification.enable is false (monitoring-only) \u2014 strict has no effect until you run ${e.pc.cyan("ironbee verification enable")}.`)},"inertNote");if(C===o&&m===o){console.log(`${e.pc.dim("\xB7")} Strict mode already ${w} in ${i} config (${e.pc.dim(t)}). No-op.`),f();return}if(C===o&&m!==o){const y=V(n,"strict"),$=L(i,y),I=m?"enabled":"disabled";console.log(`${e.pc.yellow("\u26A0")} ${i} config already has verification.strict: ${o}, but the ${e.pc.bold($??"another")} layer overrides it \u2014 effective strict is ${e.pc.bold(I)}.`),$!==null&&console.log(` ${e.pc.dim("Run")} ${e.pc.cyan(`ironbee config unset verification.strict --${$}`)} ${e.pc.dim("to drop the override, or run this command with")} ${e.pc.cyan(`--${$}`)} ${e.pc.dim("to flip the layer that's actually winning.")}`);return}const u=(0,r.loadConfig)(n);u.verification={...u.verification,strict:o};const s=(0,B.resolveTargetClients)(n,l);l===void 0&&s.length===1&&!s[0].detect(n)&&console.log(`${e.pc.yellow("\u26A0")} No clients detected in ${e.pc.dim(n)} \u2014 applying to ${e.pc.bold(s[0].name)} as fallback.`);for(const y of s)y.install(n,u);i!=="global"&&(0,E.ensureIronBeeGitignored)(n);const T={...a,verification:{...a.verification,strict:o}};N(t,T);const h=o?"Enabled":"Disabled",b=o?"Strict mode \u2014 the verify-gate refuses N/A verdicts (global + per-platform); every active cycle must produce real tool evidence.":"N/A accepted \u2014 the agent may declare a change (or a specific cycle) has no runtime surface; the gate allows it, recorded + observable.";console.log(`${e.pc.green("\u2713")} ${h} strict mode in ${i} config (${e.pc.dim(t)}).`),console.log(` ${e.pc.dim(b)}`),f(),console.log(` ${e.pc.yellow("\u26A0")} Restart your editor / agent session for the change to take effect.`)}c(U,"applyStrictVerifyToggle");0&&(module.exports={applyAutoVerifyToggle,applyStrictVerifyToggle,applyVerificationToggle});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var d=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var D=Object.getOwnPropertyNames;var x=Object.prototype.hasOwnProperty;var g=(o,e)=>d(o,"name",{value:e,configurable:!0});var k=(o,e)=>{for(var t in e)d(o,t,{get:e[t],enumerable:!0})},$=(o,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let l of D(e))!x.call(o,l)&&l!==t&&d(o,l,{get:()=>e[l],enumerable:!(s=T(e,l))||s.enumerable});return o};var M=o=>$(d({},"__esModule",{value:!0}),o);var E={};k(E,{autoDisableCommand:()=>h,autoEnableCommand:()=>b,strictDisableCommand:()=>C,strictEnableCommand:()=>y,verificationAutoCommand:()=>w,verificationCommand:()=>O,verificationDisableCommand:()=>u,verificationEnableCommand:()=>p,verificationModelCommand:()=>v,verificationStrictCommand:()=>j});module.exports=M(E);var r=require("commander"),m=require("../clients/registry"),n=require("../lib/config"),a=require("../lib/output"),i=require("./verification-toggle"),f=require("./verification-model");function c(o){return o.option("-p, --project-dir <dir>","Project directory (default: cwd).").option("-g, --global","Write to the global config (~/.ironbee/config.json) instead of the project.").option("--local","Write to the gitignored project-local override (<project>/.ironbee/config.local.json). Mutually exclusive with --global.").option("--client <name>",`Only re-render artifacts for this client (${(0,m.clientNames)()}), or "all". Default: detected clients.`)}g(c,"attachToggleOptions");const p=c(new r.Command("enable")).description("Turn verification enforcement back on (writes verification.enable: true and re-renders client artifacts). Default target is the committed project config; -g writes global, --local writes the gitignored personal layer.").action(o=>{try{const e=o.projectDir??process.cwd(),t=(0,n.resolveConfigTargetFromFlags)(o);(0,i.applyVerificationToggle)(!0,e,t,o.client)}catch(e){console.error(`${a.pc.red("\u2717")} ${e instanceof Error?e.message:e}`),process.exit(1)}}),u=c(new r.Command("disable")).description("Turn off verification enforcement; ironbee runs in monitoring-only mode (session/activity/tool_call telemetry still flows to the collector). Default target is the committed project config; -g writes global, --local writes the gitignored personal layer.").action(o=>{try{const e=o.projectDir??process.cwd(),t=(0,n.resolveConfigTargetFromFlags)(o);(0,i.applyVerificationToggle)(!1,e,t,o.client)}catch(e){console.error(`${a.pc.red("\u2717")} ${e instanceof Error?e.message:e}`),process.exit(1)}}),b=c(new r.Command("enable")).description("Turn automatic enforcement back on (enforce mode \u2014 writes verification.auto: true). Default target is the committed project config; -g writes global, --local writes the gitignored personal layer.").action(o=>{try{const e=o.projectDir??process.cwd(),t=(0,n.resolveConfigTargetFromFlags)(o);(0,i.applyAutoVerifyToggle)(!0,e,t,o.client)}catch(e){console.error(`${a.pc.red("\u2717")} ${e instanceof Error?e.message:e}`),process.exit(1)}}),h=c(new r.Command("disable")).description("Switch to assist mode (writes verification.auto: false): the /ironbee-verify command + MCP servers stay installed so the agent can verify manually, but nothing is enforced \u2014 no Stop gate, non-blocking PreToolUse hooks, no skill/rule. Default target is the committed project config; -g writes global, --local writes the gitignored personal layer.").action(o=>{try{const e=o.projectDir??process.cwd(),t=(0,n.resolveConfigTargetFromFlags)(o);(0,i.applyAutoVerifyToggle)(!1,e,t,o.client)}catch(e){console.error(`${a.pc.red("\u2717")} ${e instanceof Error?e.message:e}`),process.exit(1)}}),v=new r.Command("model").argument("<value>",'Model slug/alias the verifier sub-agent should use (e.g. "sonnet" / "opus" for Claude, "gpt-5.5" for Codex).').description("Pin the delegated verifier sub-agent's model (writes verification.model.<client>). Per-client by design \u2014 Claude/Codex use different slugs. --client selects which client's verifier to pin; omit it when exactly one client is detected (auto-resolved, like install), required when zero or multiple are present. Unset (back to inherit) with `ironbee config unset verification.model`.").option("-p, --project-dir <dir>","Project directory (default: cwd).").option("-g, --global","Write to the global config (~/.ironbee/config.json) instead of the project.").option("--local","Write to the gitignored project-local override. Mutually exclusive with --global.").option("--client <name>","Which client's verifier to pin (claude | codex). Optional when exactly one verifier client is detected; required for 0 or 2+.").action((o,e)=>{try{const t=e.projectDir??process.cwd(),s=(0,n.resolveConfigTargetFromFlags)(e);(0,f.applyVerificationModel)(o,t,s,e.client)}catch(t){console.error(`${a.pc.red("\u2717")} ${t instanceof Error?t.message:t}`),process.exit(1)}}),w=new r.Command("auto").description("Manage automatic enforcement (enable = enforce mode; disable = assist mode: manual /ironbee-verify only, no enforcement). Sub-toggle of `verification` \u2014 only meaningful when verification is enabled.").addCommand(b).addCommand(h),y=c(new r.Command("enable")).description("Turn on strict mode (writes verification.strict: true). The verify-gate refuses N/A verdicts (global + per-platform) \u2014 every active cycle must produce real tool evidence. Default target is the committed project config; -g writes global, --local writes the gitignored personal layer.").action(o=>{try{const e=o.projectDir??process.cwd(),t=(0,n.resolveConfigTargetFromFlags)(o);(0,i.applyStrictVerifyToggle)(!0,e,t,o.client)}catch(e){console.error(`${a.pc.red("\u2717")} ${e instanceof Error?e.message:e}`),process.exit(1)}}),C=c(new r.Command("disable")).description("Turn off strict mode (writes verification.strict: false \u2014 the default). N/A verdicts are accepted: the agent may declare a change (or a specific cycle) has no runtime surface and the gate allows it, recorded + observable. Default target is the committed project config; -g writes global, --local writes the gitignored personal layer.").action(o=>{try{const e=o.projectDir??process.cwd(),t=(0,n.resolveConfigTargetFromFlags)(o);(0,i.applyStrictVerifyToggle)(!1,e,t,o.client)}catch(e){console.error(`${a.pc.red("\u2717")} ${e instanceof Error?e.message:e}`),process.exit(1)}}),j=new r.Command("strict").description("Manage strict mode (enable = refuse N/A verdicts, require real tool evidence for every active cycle; disable = accept N/A, the default). Sub-toggle of `verification` \u2014 only meaningful in enforce mode.").addCommand(y).addCommand(C),O=new r.Command("verification").description("Manage the master verification toggle (enable / disable), the `auto` enforcement sub-toggle, and the `strict` N/A-rejection sub-toggle. Mirrors the `<cycle> <verb>` shape used by `browser` / `node` / `backend`.").addCommand(p).addCommand(u).addCommand(w).addCommand(j).addCommand(v);0&&(module.exports={autoDisableCommand,autoEnableCommand,strictDisableCommand,strictEnableCommand,verificationAutoCommand,verificationCommand,verificationDisableCommand,verificationEnableCommand,verificationModelCommand,verificationStrictCommand});
|
package/dist/commands/verify.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var p=Object.defineProperty;var k=Object.getOwnPropertyDescriptor;var v=Object.getOwnPropertyNames;var _=Object.prototype.hasOwnProperty;var c=(s,i)=>p(s,"name",{value:i,configurable:!0});var w=(s,i)=>{for(var n in i)p(s,n,{get:i[n],enumerable:!0})},A=(s,i,n,o)=>{if(i&&typeof i=="object"||typeof i=="function")for(let t of v(i))!_.call(s,t)&&t!==n&&p(s,t,{get:()=>i[t],enumerable:!(o=k(i,t))||o.enumerable});return s};var S=s=>A(p({},"__esModule",{value:!0}),s);var C={};w(C,{verifyCommand:()=>x});module.exports=S(C);var h=require("commander"),r=require("fs"),l=require("path"),e=require("../lib/output");function a(s){console.log(` ${e.pc.green("\u2713")} ${s}`)}c(a,"pass");function f(s,i){console.log(` ${e.pc.red("\u2717")} ${s}: ${e.pc.dim(i)}`)}c(f,"fail");function N(s){let i=!0;const n=s.status==="not_applicable",o=Array.isArray(s.not_applicable_cycles)?s.not_applicable_cycles:[];if(["pass","fail","not_applicable"].includes(s.status)?a(`status: ${s.status}`):(f("status",`unknown value "${s.status}" \u2014 must be "pass", "fail", or "not_applicable"`),i=!1),!n){const t=s.checks;Array.isArray(t)&&t.length>0?a(`checks (${t.length} item(s))`):(f("checks","checks is missing or empty"),i=!1)}return(n||o.length>0)&&(Array.isArray(s.reason)&&s.reason.length>0?a(`reason (${s.reason.length} item(s))`):(f("reason","required for N/A (global status or not_applicable_cycles)"),i=!1)),o.length>0&&a(`not_applicable_cycles: ${o.join(", ")}`),s.status==="fail"&&(!Array.isArray(s.issues)||s.issues.length===0?(f("issues",'required when status is "fail"'),i=!1):a(`errors (${s.issues.length} item(s))`)),i}c(N,"checkVerdict");function j(s){const i=(0,l.join)(s,"actions.jsonl");if(!(0,r.existsSync)(i))return!1;let n;try{n=(0,r.readFileSync)(i,"utf-8")}catch{return!1}return n.includes('"type":"verification_requested"')||n.includes('"type": "verification_requested"')?!1:n.includes('"type":"session_start"')||n.includes('"type": "session_start"')}c(j,"isMonitoringOnlySession");function D(s,i){if(i)return i;const n=(0,r.readdirSync)(s).filter(o=>(0,r.statSync)((0,l.join)(s,o)).isDirectory());return n.length===1?n[0]:null}c(D,"resolveSession");const x=new h.Command("verify").description("Validate a session verdict file (dry-run of the Stop hook checks)").argument("[session-id]","session ID to verify (auto-detected if only one active session)").option("-p, --project-dir <dir>","target project directory",".").action((s,i)=>{const n=(0,l.resolve)(i.projectDir),o=(0,l.join)(n,".ironbee","sessions");(0,r.existsSync)(o)||(e.log.error("No .ironbee/sessions/ directory found. Run `ironbee install` first."),process.exit(1));const t=D(o,s);if(!t){const g=(0,r.readdirSync)(o).filter($=>(0,r.statSync)((0,l.join)(o,$)).isDirectory());if(g.length===0){e.log.info("No sessions found. No verification has been written yet.");return}e.log.error(`Multiple sessions found. Specify a session ID:
|
|
2
2
|
${g.join(`
|
|
3
|
-
`)}`),process.exit(1)}const
|
|
4
|
-
${e.pc.dim("retries:")} ${e.pc.yellow(`${
|
|
3
|
+
`)}`),process.exit(1)}const d=(0,l.join)(o,t,"verdict.json"),m=(0,l.join)(o,t,"retries");if(e.log.info(`Verifying session: ${e.pc.bold(e.pc.cyan(t))}`),e.log.blank(),!(0,r.existsSync)(d)){const g=(0,l.join)(o,t);if(j(g)){e.log.info(`${e.pc.dim("\xB7")} No verdict found \u2014 this session ran in ${e.pc.bold("monitoring-only mode")} (verification.enable: false).`),e.log.dim(" Nothing to validate. Toggle on with `ironbee verification enable` if you want enforcement.");return}f("verdict file",`not found at ${e.pc.dim(d)}`),e.log.blank(),console.log(` ${e.pc.bold(e.pc.red("\u2717 FAIL"))} ${e.pc.dim("\u2014 no verdict written yet.")}`),process.exit(1)}a(`verdict file exists: ${e.pc.dim(d)}`);let u;try{u=JSON.parse((0,r.readFileSync)(d,"utf-8"))}catch{f("verdict file","invalid JSON"),e.log.blank(),console.log(` ${e.pc.bold(e.pc.red("\u2717 FAIL"))} ${e.pc.dim("\u2014 verdict is not valid JSON.")}`),process.exit(1)}a("verdict is valid JSON"),e.log.blank();const y=N(u),b=(0,r.existsSync)(m)&&parseInt((0,r.readFileSync)(m,"utf-8"),10)||0;b>0&&console.log(`
|
|
4
|
+
${e.pc.dim("retries:")} ${e.pc.yellow(`${b}/3`)}`),e.log.blank(),y&&u.status==="pass"?console.log(` ${e.pc.bold(e.pc.green("\u2713 PASS"))} ${e.pc.dim("\u2014 hook would allow completion.")}`):y&&u.status==="not_applicable"?console.log(` ${e.pc.bold(e.pc.green("\u2713 N/A"))} ${e.pc.dim("\u2014 no runtime surface; hook would allow (unless strict mode / fail-like prior verdict).")}`):y&&u.status==="fail"?console.log(` ${e.pc.bold(e.pc.red("\u2717 BLOCKED"))} ${e.pc.dim("\u2014 verdict status is fail. Fix issues and re-verify.")}`):console.log(` ${e.pc.bold(e.pc.red("\u2717 BLOCKED"))} ${e.pc.dim("\u2014 verdict has schema errors.")}`)});0&&(module.exports={verifyCommand});
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
"use strict";var v=Object.defineProperty;var
|
|
2
|
-
`)}catch(i){f.logger.debug(`failed to append action to ${t}: ${i}`)}if(e.type!=="tool_call"){const i=(0,a.basename)((0,a.dirname)(t)),r=(0,a.dirname)((0,a.dirname)((0,a.dirname)((0,a.dirname)(t))));try{await(0,b.sendToCollector)(e,i,r)}catch(s){s instanceof b.RetriableCollectorError?
|
|
3
|
-
`).filter(s=>s.length>0);for(let s=r.length-1;s>=0;s--)try{const o=JSON.parse(r[s]);if(o.type===e&&typeof o.timestamp=="number")return n-o.timestamp}catch{}}catch(i){f.logger.debug(`failed to find duration for ${e}: ${i}`)}}c(
|
|
4
|
-
`).filter(i=>i.length>0);for(let i=n.length-1;i>=0;i--)try{const r=JSON.parse(n[i]);if(typeof r.timestamp=="number")return r.timestamp}catch{}}catch(e){f.logger.debug(`failed to read last action timestamp from ${t}: ${e}`)}}c(
|
|
5
|
-
`).filter(o=>o.length>0);let r=-1;const s=[];for(let o=0;o<i.length;o++)try{const
|
|
6
|
-
`).filter(o=>o.length>0).map(o=>{try{return JSON.parse(o)}catch{return null}});let r=-1;for(let o=0;o<i.length;o++){const
|
|
1
|
+
"use strict";var v=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var c=(t,e)=>v(t,"name",{value:e,configurable:!0});var N=(t,e)=>{for(var n in e)v(t,n,{get:e[n],enumerable:!0})},j=(t,e,n,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of T(e))!R.call(t,r)&&r!==n&&v(t,r,{get:()=>e[r],enumerable:!(i=F(e,r))||i.enumerable});return t};var P=t=>j(v({},"__esModule",{value:!0}),t);var ee={};N(ee,{ActivityAwareEvent:()=>d.ActivityAwareEvent,Event:()=>d.Event,EventType:()=>d.EventType,EventTypeValue:()=>d.EventTypeValue,FixAwareEvent:()=>d.FixAwareEvent,VerificationAwareEvent:()=>d.VerificationAwareEvent,appendAction:()=>D,baseFields:()=>V,deterministicSessionEndId:()=>O,findDurationSinceLastAction:()=>J,findLastActionTimestamp:()=>G,getFileChangesSinceLastFailVerdict:()=>Y,getFileChangesSinceLastVerification:()=>Q,getToolCallsSinceLastFileChange:()=>z,getToolCallsSinceLastVerification:()=>W,hasFileChangesSinceLastVerification:()=>B,hasToolCallsSinceLastVerdict:()=>K,hasVerifierEverEngaged:()=>X,readActionsSinceLastMarker:()=>x,resolveProjectName:()=>S,summarizeFixFileChanges:()=>Z});module.exports=P(ee);var l=require("fs"),h=require("crypto"),a=require("path"),f=require("../../lib/logger"),b=require("../../lib/collector"),$=require("../../lib/config"),w=require("../../queue/submit"),k=require("../../queue/types"),C=require("../../queue/register-handlers"),d=require("../../lib/event");function S(t){let e=t,n;for(;;){const i=(0,a.join)(e,".git");if((0,l.existsSync)(i)){const s=L(i);if(s==="directory"){const o=E(i);return o||(0,a.basename)(e)}if(s==="linked-pointer"){const o=_(i),u=o!==void 0?E(o):void 0;return u||(0,a.basename)(e)}s==="worktree-pointer"&&n===void 0&&(n=M(i))}const r=(0,a.dirname)(e);if(r===e)break;e=r}return n??(0,a.basename)(t)}c(S,"resolveProjectName");function L(t){try{const e=(0,l.statSync)(t);if(e.isDirectory())return"directory";if(!e.isFile())return"other";const n=_(t);return n===void 0?"other":(0,l.existsSync)((0,a.join)(n,"commondir"))?"worktree-pointer":"linked-pointer"}catch(e){return f.logger.debug(`resolveProjectName: stat failed for ${t}: ${e instanceof Error?e.message:e}`),"other"}}c(L,"classifyGitEntry");function _(t){try{const n=(0,l.readFileSync)(t,"utf-8").trim().match(/^gitdir:\s*(.+)$/m);if(!n)return;const i=n[1].trim();return(0,a.isAbsolute)(i)?i:(0,a.resolve)((0,a.dirname)(t),i)}catch(e){f.logger.debug(`resolveProjectName: pointer at ${t} unreadable: ${e instanceof Error?e.message:e}`);return}}c(_,"readGitdirPointer");function E(t){try{const e=(0,a.join)(t,"config");if(!(0,l.existsSync)(e))return;const n=U((0,l.readFileSync)(e,"utf-8"));return n?q(n):void 0}catch(e){f.logger.debug(`resolveProjectName: failed to read git config at ${t}: ${e instanceof Error?e.message:e}`);return}}c(E,"repoNameFromGitConfig");function M(t){const e=_(t);if(e===void 0)return;const n=(0,a.join)(e,"commondir");let i;try{if((0,l.existsSync)(n)){const o=(0,l.readFileSync)(n,"utf-8").trim();i=(0,a.isAbsolute)(o)?o:(0,a.resolve)(e,o)}else i=e}catch(o){f.logger.debug(`resolveProjectName: commondir at ${n} unreadable: ${o instanceof Error?o.message:o}`);return}const r=E(i);if(r)return r;const s=(0,a.basename)(i)===".git"?(0,a.basename)((0,a.dirname)(i)):(0,a.basename)(i);return s.length>0?s:void 0}c(M,"repoNameFromWorktreePointer");function U(t){const e=t.split(/\r?\n/);let n=null,i=null,r,s;for(const o of e){const u=o.trim();if(u.length===0||u.startsWith("#")||u.startsWith(";"))continue;const p=u.match(/^\[([^\s\]]+)(?:\s+"([^"]*)")?\]$/);if(p){n=p[1].toLowerCase(),i=p[2]??null;continue}if(n!=="remote"||i===null)continue;const m=u.match(/^url\s*=\s*(.+?)\s*$/i);if(!m)continue;const g=m[1];i==="origin"&&(r=g),s===void 0&&(s=g)}return r??s}c(U,"readFirstRemoteUrl");function q(t){let e=t.trim();if(e.length===0)return;const n=e.match(/^[^/@]+@[^/:]+:(.+)$/);if(n?e=n[1]:e=e.replace(/^[a-z][a-z0-9+.-]*:\/\/[^/]*\//i,""),e=e.replace(/[?#].*$/,"").replace(/\/+$/,""),e.length===0)return;const r=(e.split("/").pop()??"").replace(/\.git$/i,"");return r.length>0?r:void 0}c(q,"repoNameFromRemoteUrl");function V(t){const e=(0,a.basename)((0,a.dirname)(t)),n=(0,a.dirname)((0,a.dirname)((0,a.dirname)((0,a.dirname)(t)))),i=(0,a.dirname)(t),{getUserEmail:r,getUsageType:s,getUsagePlan:o}=require("./session-state"),u=r(i),p=s(i),m=o(i),g={id:(0,h.randomUUID)(),session_id:e,project_name:S(n)};return u&&(g.user_email=u),p&&(g.usage_type=p),m&&(g.usage_plan=m),g}c(V,"baseFields");function O(t){const e=(0,h.createHash)("sha256").update("session_end:"+t).digest("hex");return`${e.slice(0,8)}-${e.slice(8,12)}-${e.slice(12,16)}-${e.slice(16,20)}-${e.slice(20,32)}`}c(O,"deterministicSessionEndId");async function D(t,e){const n=V(t);e.id||(e.id=n.id),e.session_id||(e.session_id=n.session_id),e.project_name||(e.project_name=n.project_name);try{(0,l.mkdirSync)((0,a.dirname)(t),{recursive:!0}),(0,l.appendFileSync)(t,JSON.stringify(e)+`
|
|
2
|
+
`)}catch(i){f.logger.debug(`failed to append action to ${t}: ${i}`)}if(e.type!=="tool_call"){const i=(0,a.basename)((0,a.dirname)(t)),r=(0,a.dirname)((0,a.dirname)((0,a.dirname)((0,a.dirname)(t))));try{await(0,b.sendToCollector)(e,i,r)}catch(s){s instanceof b.RetriableCollectorError?I(r,i,e,s):f.logger.debug(`failed to send action to collector: ${s}`)}}}c(D,"appendAction");function I(t,e,n,i){if(!(0,$.isJobQueueEnabled)(t)){f.logger.debug(`collector fallback: jobQueue disabled, dropping type=${n.type} id=${n.id} (cause: ${i.message})`);return}try{(0,w.submit)(t,e,C.SEND_EVENT_TYPE,n),f.logger.debug(`collector fallback: enqueued type=${n.type} id=${n.id} as send_event (cause: ${i.message})`)}catch(r){if(r instanceof k.JobTooLargeError){f.logger.debug(`collector fallback: event too large for queue (${r.sizeBytes} bytes), dropping type=${n.type} id=${n.id}`);return}f.logger.debug(`collector fallback: queue submit failed for type=${n.type} id=${n.id}: ${r}`)}}c(I,"enqueueCollectorFallback");function J(t,e,n){if((0,l.existsSync)(t))try{const r=(0,l.readFileSync)(t,"utf-8").trim().split(`
|
|
3
|
+
`).filter(s=>s.length>0);for(let s=r.length-1;s>=0;s--)try{const o=JSON.parse(r[s]);if(o.type===e&&typeof o.timestamp=="number")return n-o.timestamp}catch{}}catch(i){f.logger.debug(`failed to find duration for ${e}: ${i}`)}}c(J,"findDurationSinceLastAction");function x(t,e){return y(t,n=>n.type===e)}c(x,"readActionsSinceLastMarker");function G(t){if((0,l.existsSync)(t))try{const n=(0,l.readFileSync)(t,"utf-8").trim().split(`
|
|
4
|
+
`).filter(i=>i.length>0);for(let i=n.length-1;i>=0;i--)try{const r=JSON.parse(n[i]);if(typeof r.timestamp=="number")return r.timestamp}catch{}}catch(e){f.logger.debug(`failed to read last action timestamp from ${t}: ${e}`)}}c(G,"findLastActionTimestamp");function y(t,e){if(!(0,l.existsSync)(t))return[];try{const i=(0,l.readFileSync)(t,"utf-8").trim().split(`
|
|
5
|
+
`).filter(o=>o.length>0);let r=-1;const s=[];for(let o=0;o<i.length;o++)try{const u=JSON.parse(i[o]);s.push(u),e(u)&&(r=o)}catch{}return s.slice(r+1)}catch(n){return f.logger.debug(`failed to read actions from ${t}: ${n}`),[]}}c(y,"readActionsSinceMatch");function A(t){return t.type!=="verification_requested"?!1:t.action==="allow"}c(A,"isAllowVerificationRequested");function W(t){return y(t,A).filter(n=>n.type==="tool_call")}c(W,"getToolCallsSinceLastVerification");function z(t){return x(t,"file_change").filter(n=>n.type==="tool_call")}c(z,"getToolCallsSinceLastFileChange");function K(t){return x(t,"verdict_write").some(n=>n.type==="tool_call")}c(K,"hasToolCallsSinceLastVerdict");function B(t){return y(t,A).some(n=>n.type==="file_change")}c(B,"hasFileChangesSinceLastVerification");function Q(t){return y(t,A).filter(n=>n.type==="file_change")}c(Q,"getFileChangesSinceLastVerification");function H(t){return t.type!=="verdict_write"?!1:t.verdict?.status==="fail"}c(H,"isFailVerdictWrite");function Y(t){if(!(0,l.existsSync)(t))return[];try{const i=(0,l.readFileSync)(t,"utf-8").trim().split(`
|
|
6
|
+
`).filter(o=>o.length>0).map(o=>{try{return JSON.parse(o)}catch{return null}});let r=-1;for(let o=0;o<i.length;o++){const u=i[o];u!==null&&H(u)&&(r=o)}if(r<0)return[];const s=[];for(let o=r+1;o<i.length;o++){const u=i[o];u!==null&&u.type==="file_change"&&s.push(u)}return s}catch(e){return f.logger.debug(`failed to read file changes since last fail verdict: ${e}`),[]}}c(Y,"getFileChangesSinceLastFailVerdict");function X(t){if(!(0,l.existsSync)(t))return!1;try{const n=(0,l.readFileSync)(t,"utf-8").trim().split(`
|
|
7
|
+
`).filter(i=>i.length>0);for(const i of n){let r;try{r=JSON.parse(i)}catch{continue}if(r.type==="verification_start")return!0;if(r.type==="tool_call"){const s=r;if(s.tool_type==="mcp"&&typeof s.mcp_server=="string"&&s.mcp_server.endsWith("-devtools"))return!0}}return!1}catch(e){return f.logger.debug(`failed to scan verifier engagement in ${t}: ${e}`),!1}}c(X,"hasVerifierEverEngaged");function Z(t){if(t.length===0)return[];const e=new Map,n=[];for(const i of t){const r=i.file_path;let s=e.get(r);s||(s={op:i.operation,added:0,removed:0},e.set(r,s),n.push(r)),s.op=s.op==="create"||i.operation==="create"?"create":i.operation,s.added+=typeof i.lines_added=="number"?i.lines_added:0,s.removed+=typeof i.lines_removed=="number"?i.lines_removed:0}return n.map(i=>{const r=e.get(i);return`${r.op} ${i} (+${r.added}/-${r.removed})`})}c(Z,"summarizeFixFileChanges");0&&(module.exports={ActivityAwareEvent,Event,EventType,EventTypeValue,FixAwareEvent,VerificationAwareEvent,appendAction,baseFields,deterministicSessionEndId,findDurationSinceLastAction,findLastActionTimestamp,getFileChangesSinceLastFailVerdict,getFileChangesSinceLastVerification,getToolCallsSinceLastFileChange,getToolCallsSinceLastVerification,hasFileChangesSinceLastVerification,hasToolCallsSinceLastVerdict,hasVerifierEverEngaged,readActionsSinceLastMarker,resolveProjectName,summarizeFixFileChanges});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var m=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var $=Object.prototype.hasOwnProperty;var _=(c,r)=>m(c,"name",{value:r,configurable:!0});var I=(c,r)=>{for(var i in r)m(c,i,{get:r[i],enumerable:!0})},S=(c,r,i,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of T(r))!$.call(c,n)&&n!==i&&m(c,n,{get:()=>r[n],enumerable:!(o=F(r,n))||o.enumerable});return c};var k=c=>S(m({},"__esModule",{value:!0}),c);var P={};I(P,{runSubmitVerdict:()=>N});module.exports=k(P);var y=require("fs"),w=require("path"),u=require("../../lib/logger"),d=require("../../lib/config"),x=require("../../lib/recording-tools"),V=require("../../lib/telemetry"),a=require("./actions"),e=require("./session-state");function J(c,r){const i=(0,e.getPendingFixes)(c);if(i.length>0)return i;const o=(0,a.summarizeFixFileChanges)((0,a.getFileChangesSinceLastFailVerdict)(r));return o.length>0?o:["re-verified after a prior failure (no tracked code changes in this fix cycle)"]}_(J,"deriveFixes");async function N(c){const{sessionId:r,sessionDir:i,verdictFile:o,actionsFile:n,verdictJson:C,projectDir:E}=c;let t;try{t=JSON.parse(C)}catch(s){return u.logger.debug(`submit-verdict: invalid JSON: ${s}`),{success:!1,message:"REJECTED: verdict is not valid JSON."}}if(t.status!=="pass"&&t.status!=="fail"&&t.status!=="not_applicable")return{success:!1,message:`REJECTED: status must be "pass", "fail", or "not_applicable", got "${t.status}".`};const f=t.status==="not_applicable",g=Array.isArray(t.not_applicable_cycles)?t.not_applicable_cycles:[],b=g.length>0;if(f&&b)return{success:!1,message:'REJECTED: do not combine not_applicable_cycles with status "not_applicable" (global N/A already exempts every cycle). Use status "not_applicable" for the whole change, OR a pass/fail status with not_applicable_cycles for a subset.'};if(b){const s=g.filter(l=>!d.ALL_CYCLES.includes(l));if(s.length>0)return{success:!1,message:`REJECTED: unknown cycle name(s) in not_applicable_cycles: ${s.join(", ")}. Valid: ${d.ALL_CYCLES.join(" / ")}.`}}if(f||b){if((0,e.isFailLikeVerdictStatus)((0,e.getLastVerdictStatus)(i)))return{success:!1,message:"REJECTED: you reported a fail \u2014 N/A cannot reclassify it. Fix the issues and re-verify, or report the fail again."};if(!Array.isArray(t.reason)||t.reason.length===0)return{success:!1,message:`REJECTED: ${f?'status "not_applicable"':"not_applicable_cycles"} requires a non-empty "reason" array explaining why there is no runtime surface to verify.`};if(E!==void 0&&(0,d.getVerificationStrict)((0,d.loadConfig)(E)))return{success:!1,message:"REJECTED: strict mode \u2014 N/A is not accepted. Verify the change with the required tools, or report a fail."}}if(!f&&(!Array.isArray(t.checks)||t.checks.length===0))return{success:!1,message:"REJECTED: checks must be a non-empty array describing what you functionally tested."};if(t.status==="fail"&&(!Array.isArray(t.issues)||t.issues.length===0))return{success:!1,message:'REJECTED: when status is "fail", issues must be a non-empty array describing what failed.'};if(t.status==="pass"&&(0,e.isFailLikeVerdictStatus)((0,e.getLastVerdictStatus)(i))&&(!Array.isArray(t.fixes)||t.fixes.length===0)&&(t.fixes=J(i,n)),(0,e.isRecordingRequired)(i)&&(0,e.isRecordingActive)(i))return{success:!1,message:`REJECTED: recording is still active.
|
|
2
2
|
|
|
3
3
|
1. Stop recording first:
|
|
4
|
-
${(0,x.listRecordingCycleTools)().map(
|
|
4
|
+
${(0,x.listRecordingCycleTools)().map(l=>` ${l.stopTool} (${l.cycle} cycle)`).join(`
|
|
5
5
|
`)}
|
|
6
6
|
2. Then re-run the same submit-verdict command.
|
|
7
7
|
|
|
8
|
-
Recording start/stop must bracket the verification flow \u2014 start before devtools tools, stop before submit-verdict.`};try{(0,
|
|
8
|
+
Recording start/stop must bracket the verification flow \u2014 start before devtools tools, stop before submit-verdict.`};try{(0,y.mkdirSync)((0,w.dirname)(o),{recursive:!0}),(0,y.writeFileSync)(o,JSON.stringify(t,null,2))}catch(s){return u.logger.debug(`submit-verdict: failed to write ${o}: ${s}`),{success:!1,message:`REJECTED: failed to write verdict file: ${s}`}}(0,e.setLastVerdictStatus)(i,t.status),(0,e.clearPendingFixes)(i),(0,e.isRecordingRequired)(i)&&(0,e.setRecordingRequired)(i,!1);const v=(0,e.getActiveActivityId)(i),h=(0,e.getActiveFixId)(i);if(h){const s=Date.now(),l={...(0,a.baseFields)(n),type:"fix_end",timestamp:s,fix_id:h,activity_id:v,duration:(0,a.findDurationSinceLastAction)(n,"fix_start",s)};await(0,a.appendAction)(n,l),(0,e.clearActiveFix)(i),(0,e.setPhase)(i,"coding"),u.logger.debug(`fix-end (verdict): ${h}`)}const p=(0,e.getActiveVerificationId)(i),A=(0,e.getActiveTraceId)(i);if(p){const s=Date.now(),l={...(0,a.baseFields)(n),type:"verification_end",timestamp:s,verification_id:p,activity_id:v,trace_id:A,duration:(0,a.findDurationSinceLastAction)(n,"verification_start",s),status:t.status};await(0,a.appendAction)(n,l),(0,e.clearActiveVerification)(i),u.logger.debug(`verification-end (auto): ${p} trace=${A}`)}const R=t,D={...(0,a.baseFields)(n),type:"verdict_write",timestamp:Date.now(),verification_id:p,activity_id:v,trace_id:A,verdict:R};if(await(0,a.appendAction)(n,D),await(0,V.trackVerdictWrite)(r,t.status,E),u.logger.debug(`submit-verdict: session=${r} status=${t.status}`),t.status==="pass"){const s=t.fixes?.length?` Fixes: ${t.fixes.join(", ")}`:"";return{success:!0,message:`VERDICT ACCEPTED: pass.${g.length>0?` (N/A cycles: ${g.join(", ")})`:""}${s}`}}return t.status==="not_applicable"?{success:!0,message:`VERDICT ACCEPTED: not_applicable. ${(t.reason??[]).join(", ")}`}:{success:!0,message:`VERDICT ACCEPTED: fail. Issues: ${(t.issues??[]).join(", ")}. Fix and re-verify.`}}_(N,"runSubmitVerdict");0&&(module.exports={runSubmitVerdict});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var T=Object.defineProperty;var H=Object.getOwnPropertyDescriptor;var Q=Object.getOwnPropertyNames;var z=Object.prototype.hasOwnProperty;var d=(e,t)=>T(e,"name",{value:t,configurable:!0});var K=(e,t)=>{for(var i in t)T(e,i,{get:t[i],enumerable:!0})},W=(e,t,i,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Q(t))!z.call(e,s)&&s!==i&&T(e,s,{get:()=>t[s],enumerable:!(o=H(t,s))||o.enumerable});return e};var X=e=>W(T({},"__esModule",{value:!0}),e);var fe={};K(fe,{runVerifyGate:()=>ue});module.exports=X(fe);var v=require("fs"),u=require("../../lib/logger"),q=require("../../lib/telemetry"),h=require("./actions"),r=require("./session-state"),p=require("../../lib/config"),B=require("./required-tools");const Z=3,ee=1;function te(e){const t=p.CYCLE_TO_SERVER[e];if(t===void 0)throw new Error(`No MCP server registered for cycle '${e}'.`);return t}d(te,"mcpServerForCycle");function _(e){return JSON.stringify({session_id:e,status:"pass",checks:["form submits successfully","new item appears in list","no console errors"]})}d(_,"verdictExamplePass");function P(e){return JSON.stringify({session_id:e,status:"fail",checks:["form renders","submit button unresponsive"],issues:["button click handler not firing","TypeError in console"]})}d(P,"verdictExampleFail");function w(...e){for(const t of e)try{(0,v.existsSync)(t)&&(0,v.unlinkSync)(t)}catch(i){u.logger.debug(`failed to cleanup ${t}: ${i}`)}}d(w,"cleanup");function ie(e){if(!(0,v.existsSync)(e))return null;try{return JSON.parse((0,v.readFileSync)(e,"utf-8"))}catch{return null}}d(ie,"readVerdictQuietly");function oe(e,t){const i=(0,h.getFileChangesSinceLastVerification)(e),o=new Set;for(const f of i)for(const a of(0,p.getActiveCycles)(f.file_path,t))o.add(a);const s=[];o.has("browser")&&s.push("browser");for(const f of p.OPTIONAL_CYCLES)o.has(f)&&s.push(f);return s}d(oe,"computeActiveCycles");function re(e,t,i){const o=te(e),s=new Set(t.filter(a=>a.tool_type==="mcp"&&a.mcp_server===o).map(a=>a.tool_name)),f=(0,p.getRequiredToolsConfig)(i,e);return{cycle:e,result:(0,B.satisfyRequiredTools)(s,f),config:f,usedCount:s.size}}d(re,"checkCycleTools");function ne(e){return{cycle:"browser",valid:!0,passCriteriaMet:!0}}d(ne,"checkBrowserEvidence");function se(e){return{cycle:"node",valid:!0,passCriteriaMet:!0}}d(se,"checkNodeEvidence");function ae(e){return{cycle:"backend",valid:!0,passCriteriaMet:!0}}d(ae,"checkBackendEvidence");function ce(e){return{cycle:"android",valid:!0,passCriteriaMet:!0}}d(ce,"checkAndroidEvidence");function le(e,t){if(!Array.isArray(t.checks)||t.checks.length===0)return{cycle:e,valid:!1,reason:"missing checks"};if(e==="browser")return ne(t);if(e==="node")return se(t);if(e==="backend")return ae(t);if(e==="android")return ce(t);throw new Error(`No evidence checker registered for cycle '${e}'.`)}d(le,"checkCycleEvidence");function de(e){const t=e.cycle.charAt(0).toUpperCase()+e.cycle.slice(1);if(e.result.missing.length===0)return`${t} cycle: ok.`;const i=e.result.missing.map(o=>` - ${o}`).join(`
|
|
2
2
|
`);return e.config.evidencePaths.length>0&&e.result.pathName!==void 0?`${t} cycle: incomplete (closest path "${e.result.pathName}", tried [${e.result.triedPaths.join(", ")}]):
|
|
3
3
|
${i}`:`${t} cycle: missing required tools:
|
|
4
|
-
${i}`}
|
|
4
|
+
${i}`}d(de,"describeMissingTools");async function ue(e){const{sessionId:t,sessionDir:i,actionsFile:o,verdictFile:s,maxRetries:f}=e,a=f??Z,k=e.config??(0,p.loadConfig)(e.projectDir);if(u.logger.debug(`verify-gate: session=${t} verdictExists=${(0,v.existsSync)(s)}`),!(0,h.hasFileChangesSinceLastVerification)(o)){if((0,r.getLastVerdictStatus)(i)==="fail"){if((0,r.getVerifyIntent)(i)!=="fix")return u.logger.debug("fail verdict with no code changes in window \u2014 status report, allowing"),(0,r.setLastVerdictStatus)(i,"fail_reported"),await c(o,i,t,"allow","fail_verdict_reported",[],e.projectDir),{action:"allow"};const n=(0,r.incrementRetries)(i);return n>=a?(u.logger.debug(`fix intent declared but retries exhausted (${n}/${a}) \u2014 releasing`),(0,r.resetRetries)(i),await(0,r.closeOpenCycles)(i,o,"max_retries_exceeded"),await c(o,i,t,"allow","max_retries_exceeded",[],e.projectDir),{action:"allow",message:`VERIFICATION FAILED ${a} TIMES. Allowing completion.
|
|
5
5
|
|
|
6
|
-
The fail verdict was never resolved. Report the unresolved issues in your final response.`}):(
|
|
6
|
+
The fail verdict was never resolved. Report the unresolved issues in your final response.`}):(u.logger.debug(`fix intent declared, fail verdict not addressed \u2014 blocking (unaddressed, attempt ${n}/${a})`),await c(o,i,t,"block","fail_verdict_unaddressed",[],e.projectDir),{action:"block",message:`VERIFICATION FAILED \u2014 unaddressed (attempt ${n}/${a}).
|
|
7
7
|
|
|
8
8
|
You submitted a fail verdict but did not address the reported issues. Either:
|
|
9
9
|
|
|
@@ -13,11 +13,20 @@ You submitted a fail verdict but did not address the reported issues. Either:
|
|
|
13
13
|
|
|
14
14
|
2. Or \u2014 if the issues genuinely cannot be fixed \u2014 re-verify (keep the --intent fix flag)
|
|
15
15
|
to confirm the failure: each blocked stop counts toward maxRetries; once exhausted,
|
|
16
|
-
the gate will allow completion with the issues reported.`})}return
|
|
16
|
+
the gate will allow completion with the issues reported.`})}return u.logger.debug("no code changes detected, allowing completion"),await c(o,i,t,"allow","no_edits",[],e.projectDir),{action:"allow"}}const l=oe(o,k);if(l.length===0)return u.logger.debug("file changes match no cycle pattern, allowing completion"),await c(o,i,t,"allow","no_cycle_active",[],e.projectDir),{action:"allow"};const V=(0,p.getVerificationStrict)(k),M=(0,r.isFailLikeVerdictStatus)((0,r.getLastVerdictStatus)(i)),m=ie(s),x=!V&&!M&&m!==null&&Array.isArray(m.reason)&&m.reason.length>0;if(x&&m.status==="not_applicable")return u.logger.debug("global N/A verdict, allowing completion"),(0,r.resetRetries)(i),(0,r.setLastVerdictStatus)(i,"not_applicable"),await c(o,i,t,"allow","verdict_not_applicable",l,e.projectDir),{action:"allow"};let b=l;if(x&&Array.isArray(m.not_applicable_cycles)&&m.not_applicable_cycles.length>0){const n=new Set(m.not_applicable_cycles.filter(g=>l.includes(g)));if(b=l.filter(g=>!n.has(g)),b.length===0)return u.logger.debug("per-platform N/A exempted every active cycle \u2014 treating as global N/A"),(0,r.resetRetries)(i),(0,r.setLastVerdictStatus)(i,"not_applicable"),await c(o,i,t,"allow","verdict_not_applicable",l,e.projectDir),{action:"allow"};u.logger.debug(`per-platform N/A: exempt=[${[...n].join(",")}] enforced=[${b.join(",")}]`)}const U=(0,h.getToolCallsSinceLastFileChange)(o),S=b.map(n=>re(n,U,k)),D=S.filter(n=>!n.result.satisfied);if(D.length>0){const n=S.every(y=>y.usedCount===0),g=(0,r.incrementRetries)(i),$=!(0,h.hasVerifierEverEngaged)(o),J=$&&g>ee,G=g>=a;if(J||G){const y=$?"verifier_unavailable":"max_retries_exceeded";u.logger.debug(`tool-presence loop releasing (attempt ${g}/${a}, neverEngaged=${$}) \u2014 ${y}`),(0,r.resetRetries)(i),await(0,r.closeOpenCycles)(i,o,y),await c(o,i,t,"allow",y,l,e.projectDir);const A=l.join(", ");return $?{action:"allow",message:`VERIFICATION UNAVAILABLE \u2014 allowing completion.
|
|
17
|
+
|
|
18
|
+
The ${A} verification cycle could not run this session: no verification was ever started and no verification tool was recorded across the whole session. This points to an environment/setup problem rather than a skipped step. Check:
|
|
19
|
+
- the devtools MCP server is installed and loads (try \`npx -y @ironbee-ai/devtools\`);
|
|
20
|
+
- on Codex: the verifier sub-agent's model resolves (set \`verification.model\` or a config.toml model) and hooks are approved (\`/hooks\`);
|
|
21
|
+
- the verification delegation actually spawns the ironbee-verifier sub-agent.
|
|
22
|
+
|
|
23
|
+
Report this change as UNVERIFIED in your final response.`}:{action:"allow",message:`VERIFICATION NOT COMPLETED after ${a} attempts. Allowing completion.
|
|
24
|
+
|
|
25
|
+
The ${A} verification cycle was attempted but its required tools were not all completed within ${a} attempts. If the change has no runtime surface to verify (e.g. a test-only or config change) or the verification tools are unavailable in this environment, say so in your final response; otherwise report the unresolved verification gap.`}}if(n){await c(o,i,t,"block","no_tools",l,e.projectDir);const y=` echo '${_(t)}' | ironbee hook submit-verdict`,A=` On fail: echo '${P(t)}' | ironbee hook submit-verdict`;return{action:"block",message:`VERIFICATION REQUIRED (attempt ${g}/${a}).
|
|
17
26
|
|
|
18
27
|
You made code changes but did not verify them.
|
|
19
28
|
|
|
20
|
-
${
|
|
29
|
+
${b.includes("browser")?`Browser cycle (UI verification):
|
|
21
30
|
1. Build and start the application if not already running
|
|
22
31
|
2. Navigate to the affected page(s)
|
|
23
32
|
3. Functionally test your changes \u2014 click, type, submit, interact with the UI to confirm the code works
|
|
@@ -25,57 +34,58 @@ ${a.includes("browser")?`Browser cycle (UI verification):
|
|
|
25
34
|
5. Take an accessibility snapshot to verify page structure
|
|
26
35
|
6. Check console for errors
|
|
27
36
|
7. Stop the dev server when done
|
|
28
|
-
`:""}${
|
|
37
|
+
`:""}${b.includes("node")?`Node cycle (Node.js runtime debug):
|
|
29
38
|
1. Connect to the running Node process via ndt_debug_connect
|
|
30
39
|
2. Set probes (tracepoint / logpoint / exceptionpoint) at the changed code paths
|
|
31
40
|
3. Exercise the code path so probes fire
|
|
32
41
|
4. Read snapshots via ndt_debug_get-probe-snapshots, OR inspect runtime errors via ndt_debug_get-logs
|
|
33
|
-
`:""}${
|
|
42
|
+
`:""}${b.includes("backend")?`Backend cycle (runtime-agnostic service verification \u2014 pick ONE or more evidence paths):
|
|
34
43
|
1. Identify the backend layer affected by your change (HTTP / gRPC / GraphQL / WebSocket endpoint, log output, or database state)
|
|
35
44
|
2a. Protocol-call path: make a real call against the running service (bedt_request_http / bedt_request_grpc / bedt_request_graphql / bedt_request_websocket-open / bedt_request_replay), inspect status / body / traceId, chain follow-ups to verify side effects
|
|
36
45
|
2b. Log-evidence path (for when something else drives the request): bedt_log_register-source (file / docker / kubernetes), then bedt_log_read / bedt_log_read-multi / bedt_log_follow
|
|
37
46
|
2c. DB-evidence path (for schema / migration / seed / query-regression changes): bedt_db_connect (named, readonly by default), then bedt_db_query / bedt_db_describe-table / bedt_db_list-tables / bedt_db_snapshot / bedt_db_diff / bedt_db_get-changes
|
|
38
47
|
3. (Optional) Pin a correlation trace id for the run via bedt_o11y_new-trace-id / bedt_o11y_set-trace-context \u2014 IronBee already injects an active verification traceId, so the o11y pin only matters when you want a fresh root for log searches.
|
|
39
|
-
`:""}${
|
|
48
|
+
`:""}${b.includes("android")?`Android cycle (mobile device / emulator verification \u2014 pick ONE evidence path):
|
|
40
49
|
1. Connect to a running device or emulator: adt_device_connect
|
|
41
50
|
2a. Device-evidence path: drive the app UI (adt_device_launch-app / adt_interaction_tap / adt_interaction_input-text / adt_interaction_swipe), then capture BOTH a screenshot (adt_content_take-screenshot) AND a UI snapshot (adt_a11y_take-ui-snapshot) to confirm the visual + structural result
|
|
42
51
|
2b. Log-evidence path: read Logcat output for the changed code path (adt_o11y_log-read / adt_o11y_log-follow) and confirm expected log lines / absence of errors
|
|
43
52
|
`:""}
|
|
44
53
|
Then submit your verdict (single verdict covers every active cycle):
|
|
45
|
-
${
|
|
46
|
-
${
|
|
47
|
-
If failed, fix the code and re-verify until it passes.`}}
|
|
54
|
+
${y}
|
|
55
|
+
${A}
|
|
56
|
+
If failed, fix the code and re-verify until it passes.`}}await c(o,i,t,"block","incomplete_tools",l,e.projectDir);const Y=D.map(y=>de(y)).join(`
|
|
57
|
+
`);return{action:"block",message:`INCOMPLETE VERIFICATION (attempt ${g}/${a}).
|
|
48
58
|
|
|
49
59
|
You used the IronBee verification tools but skipped required checks:
|
|
50
60
|
|
|
51
|
-
${
|
|
52
|
-
`)}
|
|
61
|
+
${Y}
|
|
53
62
|
|
|
54
63
|
Run the missing tools, functionally test your changes, then submit your verdict:
|
|
55
|
-
Pass: echo '${
|
|
56
|
-
Fail: echo '${
|
|
64
|
+
Pass: echo '${_(t)}' | ironbee hook submit-verdict
|
|
65
|
+
Fail: echo '${P(t)}' | ironbee hook submit-verdict`}}if(!(0,v.existsSync)(s))return await c(o,i,t,"block","no_verdict",l,e.projectDir),{action:"block",message:`VERDICT MISSING.
|
|
57
66
|
|
|
58
|
-
You ran the verification tools but did not submit a verdict.${(0,
|
|
67
|
+
You ran the verification tools but did not submit a verdict.${(0,r.isRecordingActive)(i)?`
|
|
59
68
|
\u26A0 Recording is still active \u2014 call mcp__browser-devtools__bdt_content_stop-recording BEFORE submit-verdict (otherwise it will reject with "recording is still active").`:""}
|
|
60
69
|
|
|
61
70
|
Submit your verdict via:
|
|
62
|
-
echo '${
|
|
63
|
-
echo '${
|
|
64
|
-
|
|
71
|
+
echo '${_(t)}' | ironbee hook submit-verdict`};let C;try{C=JSON.parse((0,v.readFileSync)(s,"utf-8"))}catch(n){return u.logger.debug(`failed to parse verdict ${s}: ${n}`),w(s),await c(o,i,t,"block","invalid_verdict",l,e.projectDir),{action:"block",message:`INVALID VERDICT JSON. Re-submit valid JSON:
|
|
72
|
+
echo '${_(t)}' | ironbee hook submit-verdict`}}if(C.status==="not_applicable")return w(s),await c(o,i,t,"block","not_applicable_rejected",b,e.projectDir),{action:"block",message:`VERDICT REJECTED: ${V?"N/A is not accepted in strict mode \u2014 verify the change with the required tools.":"N/A is not honored here \u2014 verify the change with the required tools, or report a fail."}
|
|
73
|
+
echo '${_(t)}' | ironbee hook submit-verdict`};const N=b.map(n=>le(n,C)),F=N.filter(n=>!n.valid);if(F.length>0)return w(s),await c(o,i,t,"block","invalid_verdict",l,e.projectDir),{action:"block",message:`VERDICT REJECTED:
|
|
74
|
+
${F.map(g=>` - ${g.cycle} cycle: ${g.reason}`).join(`
|
|
65
75
|
`)}
|
|
66
76
|
|
|
67
77
|
Re-submit:
|
|
68
|
-
echo '${
|
|
69
|
-
echo '${
|
|
70
|
-
- `);return
|
|
78
|
+
echo '${_(t)}' | ironbee hook submit-verdict`};const E=C.status;if(E!=="pass"&&E!=="fail")return w(s),await c(o,i,t,"block","invalid_verdict",l,e.projectDir),{action:"block",message:`INVALID VERDICT STATUS: "${E}". Status must be "pass" or "fail".
|
|
79
|
+
echo '${_(t)}' | ironbee hook submit-verdict`};const R=N.filter(n=>n.passCriteriaMet===!1),j=E==="pass"&&R.length===0?"pass":"fail";if(E==="pass"&&j==="fail"&&u.logger.debug(`verify-gate: status=pass overridden to fail by cycle pass-criteria: ${R.map(n=>n.cycle).join(",")}`),j==="pass")return u.logger.debug("verdict passed, allowing completion"),(0,r.resetRetries)(i),await c(o,i,t,"allow","verdict_pass",l,e.projectDir),{action:"allow"};const L=(0,r.incrementRetries)(i),I=[];if(Array.isArray(C.issues))for(const n of C.issues)I.push(String(n));for(const n of R)I.push(`[${n.cycle}] ${n.passReason??"pass criteria not met"}`);I.length===0&&I.push("unknown");const O=I.join(`
|
|
80
|
+
- `);return L>=a?(w(s),(0,r.resetRetries)(i),await(0,r.closeOpenCycles)(i,o,"max_retries_exceeded"),await c(o,i,t,"allow","max_retries_exceeded",l,e.projectDir),{action:"allow",message:`VERIFICATION FAILED ${a} TIMES. Allowing completion.
|
|
71
81
|
|
|
72
82
|
Unresolved issues:
|
|
73
|
-
- ${
|
|
83
|
+
- ${O}
|
|
74
84
|
|
|
75
|
-
Report these issues in your final response.`}):(
|
|
85
|
+
Report these issues in your final response.`}):(w(s),await c(o,i,t,"block","verdict_fail",l,e.projectDir),{action:"block",message:`VERIFICATION FAILED (attempt ${L}/${a}).
|
|
76
86
|
|
|
77
87
|
Issues found:
|
|
78
|
-
- ${
|
|
88
|
+
- ${O}
|
|
79
89
|
|
|
80
90
|
Fix the issues, rebuild if needed, re-test functionally, and re-verify.
|
|
81
|
-
Submit verdict: echo '<verdict-json>' | ironbee hook submit-verdict`})}
|
|
91
|
+
Submit verdict: echo '<verdict-json>' | ironbee hook submit-verdict`})}d(ue,"runVerifyGate");async function c(e,t,i,o,s,f,a){o==="allow"&&(0,r.clearVerifyIntent)(t);const k={...(0,h.baseFields)(e),type:"verification_requested",timestamp:Date.now(),activity_id:(0,r.getActiveActivityId)(t),action:o,reason:s,modes:f.length>0?f:void 0};await(0,h.appendAction)(e,k),await(0,q.trackVerificationRequested)(i,o,s,a)}d(c,"recordMarker");0&&(module.exports={runVerifyGate});
|
package/dist/lib/config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var y=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var le=Object.getOwnPropertyNames;var ue=Object.prototype.hasOwnProperty;var o=(n,e)=>y(n,"name",{value:e,configurable:!0});var fe=(n,e)=>{for(var t in e)y(n,t,{get:e[t],enumerable:!0})},ge=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of le(e))!ue.call(n,i)&&i!==t&&y(n,i,{get:()=>e[i],enumerable:!(r=ce(e,i))||r.enumerable});return n};var de=n=>ge(y({},"__esModule",{value:!0}),n);var jn={};fe(jn,{ALL_CYCLES:()=>be,CONFIG_TARGETS_BY_PRECEDENCE:()=>xe,CYCLES_ENABLED_BY_DEFAULT:()=>N,CYCLE_DEFAULT_VERIFY_PATTERNS:()=>U,CYCLE_TOOL_PREFIXES:()=>Ee,CYCLE_TO_SERVER:()=>pe,DEFAULT_ANDROID_ALWAYS_REQUIRED:()=>H,DEFAULT_ANDROID_EVIDENCE_PATHS:()=>G,DEFAULT_ANDROID_VERIFY_PATTERNS:()=>V,DEFAULT_BACKEND_ALWAYS_REQUIRED:()=>Y,DEFAULT_BACKEND_EVIDENCE_PATHS:()=>X,DEFAULT_BACKEND_VERIFY_PATTERNS:()=>F,DEFAULT_BROWSER_ALWAYS_REQUIRED:()=>q,DEFAULT_BROWSER_VERIFY_PATTERNS:()=>P,DEFAULT_NODE_ALWAYS_REQUIRED:()=>$,DEFAULT_NODE_EVIDENCE_PATHS:()=>K,DEFAULT_NODE_VERIFY_PATTERNS:()=>M,DEFAULT_OAUTH_USAGE_TTL_SECONDS:()=>J,DEFAULT_OTEL_EMIT_MIN_INTERVAL_SECONDS:()=>te,DEFAULT_OTEL_ENSURE_MIN_INTERVAL_SECONDS:()=>ne,DEFAULT_OTEL_IDLE_TIMEOUT_SECONDS:()=>ee,DEFAULT_OTEL_PORT:()=>Z,DEFAULT_VERIFICATION_CONTEXT_COMMIT_DEPTH:()=>ie,DEFAULT_VERIFICATION_CONTEXT_MAX_BYTES:()=>re,ENV_OVERRIDES:()=>w,OPTIONAL_CYCLES:()=>I,applyEnvOverrides:()=>W,findActiveEnvOverride:()=>he,getActiveCycles:()=>Q,getAnalyticsEmitOnStopMinIntervalSeconds:()=>Tn,getAndroidDevToolsMcpEntry:()=>Qe,getAutoVerifyEnabled:()=>oe,getBackendDevToolsMcpEntry:()=>We,getCaptureFileChangeset:()=>Cn,getClaudeOauthAccessEnabled:()=>on,getClaudeOauthAccessUsageTtlSeconds:()=>sn,getConfigLayerPaths:()=>x,getMaxChangesetBytes:()=>mn,getMaxRetries:()=>ze,getMcpServerEntry:()=>He,getNodeDevToolsMcpEntry:()=>Ge,getOTELEmitMinIntervalSeconds:()=>fn,getOTELEnsureMinIntervalSeconds:()=>un,getOTELIdleTimeoutSeconds:()=>ln,getOTELPort:()=>cn,getPrivacyEnabled:()=>ae,getRequiredToolsConfig:()=>Se,getStatusLineEmitMinIntervalSeconds:()=>tn,getStatusLineRefreshInterval:()=>gn,getStatusLineRenderDefault:()=>nn,getTargetConfigPath:()=>we,getTelemetryEnabled:()=>se,getVerificationContextCommitDepth:()=>pn,getVerificationContextEnabled:()=>dn,getVerificationContextMaxBytes:()=>En,getVerificationContextSource:()=>bn,getVerificationEnabled:()=>R,getVerificationMode:()=>_n,getVerificationModel:()=>Ce,isAnalyticsApiRequestEventsEnabled:()=>wn,isAnalyticsEmitOnStopEnabled:()=>vn,isAnalyticsEnabled:()=>An,isAnalyticsStepEventsEnabled:()=>xn,isAnalyticsTurnEventsEnabled:()=>In,isAutoModeAllowlistEnabled:()=>rn,isCollectorConfigured:()=>j,isCycleEnabled:()=>Le,isCyclePatternsActive:()=>z,isIgnoredVerifyPath:()=>yn,isJobQueueEnabled:()=>Je,isOTELEnabled:()=>an,isRecordingEnabled:()=>Ze,isSessionStatusEnabled:()=>en,loadConfig:()=>c,requiresVerification:()=>Be,resolveConfigTargetFromFlags:()=>je});module.exports=de(jn);var E=require("fs"),p=require("path"),T=require("os"),D=require("./logger");const I=["node","backend","android"],be=["browser",...I],N=new Set(["browser"]),pe={browser:"browser-devtools",node:"node-devtools",backend:"backend-devtools",android:"android-devtools"},Ee={browser:"bdt_",node:"ndt_",backend:"bedt_",android:"adt_"},P=["*.ts","*.tsx","*.js","*.jsx","*.mjs","*.cjs","*.vue","*.svelte","*.html","*.htm","*.css","*.scss","*.sass","*.less","*.styl","*.py","*.rb","*.erb","*.go","*.rs","*.java","*.kt","*.kts","*.swift","*.c","*.cpp","*.h","*.hpp","*.cs","*.php","*.dart","*.ex","*.exs","*.erl","*.lua","*.r","*.R","*.scala","*.clj","*.cljs","*.zig","*.nim","*.hbs","*.ejs","*.pug","*.jade","*.astro"],M=["server/**/*.{ts,js,mjs,cjs}","src/server/**/*.{ts,js,mjs,cjs}","backend/**/*.{ts,js,mjs,cjs}","api/**/*.{ts,js,mjs,cjs}","src/api/**/*.{ts,js,mjs,cjs}","pages/api/**/*.{ts,js,mjs,cjs}","app/api/**/*.{ts,js,mjs,cjs}","routes/**/*.{ts,js,mjs,cjs}","**/server.{ts,js,mjs,cjs}"],F=["server/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","src/server/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","backend/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","api/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","src/api/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","pages/api/**/*.{ts,js,mjs,cjs}","app/api/**/*.{ts,js,mjs,cjs}","routes/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","controllers/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","handlers/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","services/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","**/server.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","**/main.{go,py,java,rb,kt,scala}"],V=["android/**/*.{kt,java}","app/src/**/*.{kt,java}","mobile/**/*.{kt,java}","src/main/kotlin/**/*.kt","src/main/java/**/*.java","**/*.{kt,java}","**/res/**/*.xml","**/AndroidManifest.xml"],U={browser:P,node:M,backend:F,android:V},q=["bdt_navigation_go-to","bdt_content_take-screenshot","bdt_a11y_take-aria-snapshot","bdt_o11y_get-console-messages"],$=["ndt_debug_connect"],K=[{name:"probe",allOf:[{anyOf:["ndt_debug_put-tracepoint","ndt_debug_put-logpoint","ndt_debug_put-exceptionpoint"]},"ndt_debug_get-probe-snapshots"]},{name:"log",allOf:["ndt_debug_get-logs"]}],Y=[],X=[{name:"protocol-call",allOf:[{anyOf:["bedt_request_http","bedt_request_grpc","bedt_request_graphql","bedt_request_websocket-open","bedt_request_replay"]}]},{name:"log-evidence",allOf:["bedt_log_register-source",{anyOf:["bedt_log_read","bedt_log_read-multi","bedt_log_follow"]}]},{name:"db-evidence",allOf:["bedt_db_connect",{anyOf:["bedt_db_query","bedt_db_describe-table","bedt_db_list-tables","bedt_db_snapshot","bedt_db_diff","bedt_db_get-changes"]}]}],H=["adt_device_connect"],G=[{name:"device-evidence",allOf:[{anyOf:["adt_device_launch-app","adt_interaction_tap","adt_interaction_double-tap","adt_interaction_long-press","adt_interaction_input-text","adt_interaction_swipe","adt_interaction_scroll","adt_interaction_press-key","adt_interaction_deep-link"]},"adt_content_take-screenshot","adt_a11y_take-ui-snapshot"]},{name:"log-evidence",allOf:[{anyOf:["adt_o11y_log-read","adt_o11y_log-follow"]}]}],ye=3;function O(n){if(!(0,E.existsSync)(n))return{};try{return JSON.parse((0,E.readFileSync)(n,"utf-8"))}catch(e){return D.logger.debug(`failed to parse config ${n}: ${e}`),{}}}o(O,"loadJsonFile");function _e(n,e){if(!Object.prototype.hasOwnProperty.call(n,"verification"))return;const t=n.verification;if(t===null||typeof t!="object"||Array.isArray(t))throw new Error(`Invalid IronBee config in ${e}: 'verification' must be an object. Expected shape: { "enable": boolean }.`);const r=t;if(Object.prototype.hasOwnProperty.call(r,"enable")&&typeof r.enable!="boolean")throw new Error(`Invalid IronBee config in ${e}: 'verification.enable' must be boolean. Got ${typeof r.enable}.`);if(Object.prototype.hasOwnProperty.call(r,"auto")&&typeof r.auto!="boolean")throw new Error(`Invalid IronBee config in ${e}: 'verification.auto' must be boolean. Got ${typeof r.auto}.`);if(Object.prototype.hasOwnProperty.call(r,"model")){const i=r.model,s=typeof i=="string",l=i!==null&&typeof i=="object"&&!Array.isArray(i)&&Object.values(i).every(a=>typeof a=="string");if(!s&&!l)throw new Error(`Invalid IronBee config in ${e}: 'verification.model' must be a string (applies to all clients) or an object of string values (per-client, e.g. { "claude": "sonnet", "codex": "gpt-5.5" }). Got ${Array.isArray(i)?"array":typeof i}.`)}}o(_e,"assertVerificationShape");function Ce(n,e){const t=n.verification?.model;if(typeof t=="string")return t.length>0?t:void 0;if(t&&typeof t=="object"){const r=t[e];return typeof r=="string"&&r.length>0?r:void 0}}o(Ce,"getVerificationModel");function me(n,e){if(!Object.prototype.hasOwnProperty.call(n,"telemetry"))return;const t=n.telemetry;if(t===null||typeof t!="object"||Array.isArray(t))throw new Error(`Invalid IronBee config in ${e}: 'telemetry' must be an object. Expected shape: { "enable": boolean }.`);const r=t;if(Object.prototype.hasOwnProperty.call(r,"enable")&&typeof r.enable!="boolean")throw new Error(`Invalid IronBee config in ${e}: 'telemetry.enable' must be boolean. Got ${typeof r.enable}.`)}o(me,"assertTelemetryShape");function Ae(n,e){if(!Object.prototype.hasOwnProperty.call(n,"privacy"))return;const t=n.privacy;if(t===null||typeof t!="object"||Array.isArray(t))throw new Error(`Invalid IronBee config in ${e}: 'privacy' must be an object. Expected shape: { "enable": boolean }.`);const r=t;if(Object.prototype.hasOwnProperty.call(r,"enable")&&typeof r.enable!="boolean")throw new Error(`Invalid IronBee config in ${e}: 'privacy.enable' must be boolean. Got ${typeof r.enable}.`)}o(Ae,"assertPrivacyShape");function _(n,e){if(!(n===void 0&&e===void 0))return{...n??{},...e??{}}}o(_,"mergeCycleConfig");function k(n,e){const t={...n,...e};return t.browser=_(n.browser,e.browser),t.node=_(n.node,e.node),t.backend=_(n.backend,e.backend),t.android=_(n.android,e.android),t.claude=Ie(n.claude,e.claude),t.verification=Te(n.verification,e.verification),t.verificationContext=ve(n.verificationContext,e.verificationContext),t}o(k,"mergeConfigLayers");function ve(n,e){if(!(n===void 0&&e===void 0))return{...n??{},...e??{}}}o(ve,"mergeVerificationContextConfig");function Te(n,e){if(!(n===void 0&&e===void 0))return{...n??{},...e??{}}}o(Te,"mergeVerificationConfig");function Ie(n,e){if(n===void 0&&e===void 0)return;const t={...n??{},...e??{}};return(n?.oauthAccess!==void 0||e?.oauthAccess!==void 0)&&(t.oauthAccess={...n?.oauthAccess??{},...e?.oauthAccess??{}}),(n?.autoModeAllowlist!==void 0||e?.autoModeAllowlist!==void 0)&&(t.autoModeAllowlist={...n?.autoModeAllowlist??{},...e?.autoModeAllowlist??{}}),t}o(Ie,"mergeClaudeConfig");function x(n){return{global:(0,p.join)((0,T.homedir)(),".ironbee","config.json"),project:n?(0,p.join)(n,".ironbee","config.json"):void 0,local:n?(0,p.join)(n,".ironbee","config.local.json"):void 0}}o(x,"getConfigLayerPaths");const xe=["global","project","local"];function we(n,e){const t=x(e);if(n==="global")return t.global;if(n==="project"){if(t.project===void 0)throw new Error("Project layer requested but no projectDir was provided.");return t.project}if(t.local===void 0)throw new Error("Local layer requested but no projectDir was provided.");return t.local}o(we,"getTargetConfigPath");function je(n){if(n.global===!0&&n.local===!0)throw new Error("Pass at most one of --global / --local.");return n.global===!0?"global":n.local===!0?"local":"project"}o(je,"resolveConfigTargetFromFlags");function A(n){const e=O(n);return(0,E.existsSync)(n)&&(_e(e,n),me(e,n),Ae(e,n)),e}o(A,"loadAndValidateLayer");const w=[{envVar:"IRONBEE_API_KEY",configPath:"collector.apiKey"},{envVar:"IRONBEE_OAUTH_TOKEN",configPath:"collector.oauthToken"}];function Re(n,e,t){const r=e.split(".");let i=n;for(let s=0;s<r.length-1;s++){const l=r[s],a=i[l];a!=null&&typeof a=="object"&&!Array.isArray(a)?i[l]={...a}:i[l]={},i=i[l]}i[r[r.length-1]]=t}o(Re,"setAtConfigPath");function W(n){let e;for(const t of w){const r=process.env[t.envVar];if(r===void 0||r.length===0)continue;e===void 0&&(e={...n});const i=t.coerce?t.coerce(r):r;Re(e,t.configPath,i)}return e??n}o(W,"applyEnvOverrides");function he(n){for(const e of w){if(e.configPath!==n)continue;const t=process.env[e.envVar];if(t!==void 0&&t.length>0)return e}}o(he,"findActiveEnvOverride");function c(n){const e=x(n),t=A(e.global),r=e.project?A(e.project):{},i=e.local?A(e.local):{},s=k(k(t,r),i);return W(s)}o(c,"loadConfig");function Oe(n){let e=n.replace(/\{([^}]+)\}/g,(t,r)=>`(${r.split(",").map(i=>i.trim()).join("|")})`);return e=e.replace(/\*\*\//g,"\0DSS\0").replace(/\*\*/g,"\0DS\0").replace(/\*/g,"\0SS\0").replace(/\?/g,"\0QM\0"),e=e.replace(/[.+^$\\[\]]/g,"\\$&"),e=e.replace(/\x00DSS\x00/g,"(?:.*/)?").replace(/\x00DS\x00/g,".*").replace(/\x00SS\x00/g,"[^/]*").replace(/\x00QM\x00/g,"[^/]"),new RegExp(`(^|/)${e}$`)}o(Oe,"globToRegExp");function C(n,e){const t=n.replace(/\\/g,"/");for(const r of e)if(Oe(r).test(t))return!0;return!1}o(C,"matchesAny");function ke(n,e){if(e==="browser")return n.browser;if(e==="node")return n.node;if(e==="backend")return n.backend;if(e==="android")return n.android}o(ke,"getCycleBlock");function v(n,e){const t=ke(n,e);if(t!==void 0&&t.enable===!1)return[];const r=U[e]??[];if(t===void 0)return N.has(e)?[...r]:[];if(Array.isArray(t.verifyPatterns)&&t.verifyPatterns.length===0)return[];const i=t.verifyPatterns??r,s=t.additionalVerifyPatterns??[];return[...i,...s]}o(v,"getCyclePatterns");function Q(n,e){const t=e.ignoredVerifyPatterns??[];if(t.length>0&&C(n,t))return[];const r=[];C(n,v(e,"browser"))&&r.push("browser");for(const i of I){const s=v(e,i);s.length>0&&C(n,s)&&r.push(i)}return r}o(Q,"getActiveCycles");function Be(n,e){return Q(n,e).length>0}o(Be,"requiresVerification");function Le(n,e){return R(n)?z(n,e):!1}o(Le,"isCycleEnabled");function z(n,e){return v(n,e).length>0}o(z,"isCyclePatternsActive");function Se(n,e){let t,r;if(e==="browser"?(t=n.browser?.alwaysRequired??q,r=n.browser?.evidencePaths??[]):e==="node"?(t=n.node?.alwaysRequired??$,r=n.node?.evidencePaths??K):e==="backend"?(t=n.backend?.alwaysRequired??Y,r=n.backend?.evidencePaths??X):e==="android"?(t=n.android?.alwaysRequired??H,r=n.android?.evidencePaths??G):(t=[],r=[]),t.length===0&&r.length===0)throw new Error(`Invalid required-tools config for cycle '${e}': both 'alwaysRequired' and 'evidencePaths' are empty. At least one must specify required tools.`);return{alwaysRequired:t,evidencePaths:r}}o(Se,"getRequiredToolsConfig");const B="npx",De="^0.11.0",L=["-y",`@ironbee-ai/devtools@${De}`],Ne={TOOL_NAME_PREFIX:"bdt_",TOOL_INPUT_METADATA_ENABLE:"true"},Pe={PLATFORM:"node",TOOL_NAME_PREFIX:"ndt_",TOOL_INPUT_METADATA_ENABLE:"true"},Me={PLATFORM:"backend",TOOL_NAME_PREFIX:"bedt_",TOOL_INPUT_METADATA_ENABLE:"true"},Fe={PLATFORM:"android",TOOL_NAME_PREFIX:"adt_",TOOL_INPUT_METADATA_ENABLE:"true"},Ve={BROWSER_DEVTOOLS_INSTALL_CHROMIUM:"true"},Ue={},qe={},$e={};function Ke(n){return se(n)?{}:{TELEMETRY_ENABLE:"false"}}o(Ke,"buildTelemetryEnv");function Ye(n){return ae(n)?{COLLECTOR_EVENTS_TOOL_DETAILS_ENABLE:"false",COLLECTOR_ARTIFACTS_ENABLE:"false"}:{}}o(Ye,"buildPrivacyEnv");function Xe(n,e){if(!j(n))return{};const t=n.collector,i=O((0,p.join)((0,T.homedir)(),".ironbee","config.json")).collector??{},s=typeof i.oauthToken=="string"&&i.oauthToken.length>0,l=typeof i.apiKey=="string"&&i.apiKey.length>0;let a;t.oauthToken?a=s?"X-OAuth-Token=${file:~/.ironbee/config.json#collector.oauthToken}":`X-OAuth-Token=${t.oauthToken}`:a=l?"X-API-Key=${file:~/.ironbee/config.json#collector.apiKey}":`X-API-Key=${t.apiKey}`;const u={OTEL_ENABLE:"true",OTEL_EXPORTER_HTTP_URL:t.url,OTEL_EXPORTER_HTTP_HEADERS:a,OTEL_EXPORTER_TYPE:"otlp/http-protobuf"};return e==="browser"&&(u.OTEL_INSTRUMENTATION_USER_INTERACTION_EVENTS="change,input,click",u.BROWSER_HEADLESS_ENABLE="true"),u}o(Xe,"buildOTELEnv");function m(n,e,t,r,i){const s=Xe(n,i),l=Ke(n),a=Ye(n),u=n[e];if(u&&typeof u=="object"&&!Array.isArray(u)){const f=u;if(f.mcp&&typeof f.mcp=="object"&&!Array.isArray(f.mcp)){const g={...f.mcp},d={...s,...l,...a,...g.env??{},...t};return g.env=d,g}const h={};if(f.env&&typeof f.env=="object"&&!Array.isArray(f.env)){const g=f.env;for(const d of Object.keys(g))typeof g[d]=="string"&&(h[d]=g[d])}return{command:B,args:[...L],env:{...r,...s,...l,...a,...h,...t}}}return{command:B,args:[...L],env:{...r,...s,...l,...a,...t}}}o(m,"buildMcpEntry");function He(n){const e=c(n);return m(e,"browserDevTools",Ne,Ve,"browser")}o(He,"getMcpServerEntry");function Ge(n){const e=c(n);return m(e,"nodeDevTools",Pe,Ue,"node")}o(Ge,"getNodeDevToolsMcpEntry");function We(n){const e=c(n);return m(e,"backendDevTools",Me,qe,"backend")}o(We,"getBackendDevToolsMcpEntry");function Qe(n){const e=c(n);return m(e,"androidDevTools",Fe,$e,"android")}o(Qe,"getAndroidDevToolsMcpEntry");function ze(n){return typeof n.maxRetries=="number"&&n.maxRetries>0?n.maxRetries:ye}o(ze,"getMaxRetries");function j(n){if(process.env.IRONBEE_COLLECTOR==="false")return!1;const e=n.collector;if(!e||e.enable===!1||typeof e.url!="string"||e.url.length===0)return!1;const t=typeof e.oauthToken=="string"&&e.oauthToken.length>0,r=typeof e.apiKey=="string"&&e.apiKey.length>0;return!(!t&&!r)}o(j,"isCollectorConfigured");function Je(n){const e=c(n);return b(e,e.jobQueue)}o(Je,"isJobQueueEnabled");function Ze(n){const e=c(n);return b(e,e.recording)}o(Ze,"isRecordingEnabled");function en(n){return b(n,n.statusLine)}o(en,"isSessionStatusEnabled");function nn(n){const e=n.statusLine;return e!==void 0&&e.renderDefault===!0}o(nn,"getStatusLineRenderDefault");function tn(n){const e=n.statusLine?.emitMinIntervalSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:10}o(tn,"getStatusLineEmitMinIntervalSeconds");const J=60;function on(n){return n.claude?.oauthAccess?.enable!==!1}o(on,"getClaudeOauthAccessEnabled");function rn(n){return n.claude?.autoModeAllowlist?.enable!==!1}o(rn,"isAutoModeAllowlistEnabled");function sn(n){const e=n.claude?.oauthAccess?.usageTtlSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:J}o(sn,"getClaudeOauthAccessUsageTtlSeconds");const Z=15986,ee=600,ne=30,te=0;function an(n){return b(n,n.otel)}o(an,"isOTELEnabled");function cn(n){const e=n.otel?.port;return typeof e=="number"&&Number.isInteger(e)&&e>0&&e<65536?e:Z}o(cn,"getOTELPort");function ln(n){const e=n.otel?.idleTimeoutSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>0?e:ee}o(ln,"getOTELIdleTimeoutSeconds");function un(n){const e=n.otel?.ensureMinIntervalSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:ne}o(un,"getOTELEnsureMinIntervalSeconds");function fn(n){const e=n.otel?.emitMinIntervalSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:te}o(fn,"getOTELEmitMinIntervalSeconds");function gn(n){const e=n.statusLine?.refreshInterval;if(typeof e=="number"&&Number.isFinite(e)&&e>=1)return e}o(gn,"getStatusLineRefreshInterval");function b(n,e){return e!=null&&typeof e=="object"&&!Array.isArray(e)?e.enable!==!1:j(n)}o(b,"isFeatureEnabledWithCollectorAutoEnable");function hn(n){return n==null||typeof n!="object"||Array.isArray(n)?!1:n.enable!==!1}o(hn,"isPresenceEnabled");function R(n){const e=n.verification;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.enable!==!1}o(R,"getVerificationEnabled");function oe(n){const e=n.verification;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.auto!==!1}o(oe,"getAutoVerifyEnabled");const re=65536,ie=1;function dn(n){const e=n.verificationContext;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.enable!==!1}o(dn,"getVerificationContextEnabled");function bn(n){return n.verificationContext?.source==="actions"?"actions":"git"}o(bn,"getVerificationContextSource");function pn(n){const e=n.verificationContext?.commitDepth;return typeof e=="number"&&Number.isFinite(e)&&e>=0?Math.floor(e):ie}o(pn,"getVerificationContextCommitDepth");function En(n){const e=n.verificationContext?.maxBytes;return typeof e=="number"&&Number.isFinite(e)&&e>0?Math.floor(e):re}o(En,"getVerificationContextMaxBytes");function yn(n,e){const t=n.ignoredVerifyPatterns??[];return t.length>0&&C(e,t)}o(yn,"isIgnoredVerifyPath");function _n(n){return R(n)?oe(n)?"enforce":"assist":"monitor"}o(_n,"getVerificationMode");function se(n){const e=n.telemetry;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.enable!==!1}o(se,"getTelemetryEnabled");function ae(n){const e=n.privacy;return e==null||typeof e!="object"||Array.isArray(e)?!1:e.enable===!0}o(ae,"getPrivacyEnabled");const S=65536;function Cn(n){const e=n.fileChange;return!e||typeof e!="object"||Array.isArray(e)?!1:e.captureChangeset===!0}o(Cn,"getCaptureFileChangeset");function mn(n){const e=n.fileChange;if(!e||typeof e!="object"||Array.isArray(e))return S;const t=e.maxChangesetBytes;return typeof t!="number"||!Number.isFinite(t)||t<=0?S:Math.floor(t)}o(mn,"getMaxChangesetBytes");function An(n){const e=c(n);return b(e,e.analytics)}o(An,"isAnalyticsEnabled");function vn(n){const t=c(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!0:t.emitOnStop!==!1}o(vn,"isAnalyticsEmitOnStopEnabled");function Tn(n){const t=c(n).analytics;if(t===null||typeof t!="object"||Array.isArray(t))return 0;const r=t.emitOnStopMinIntervalSeconds;return typeof r=="number"&&r>=0?r:0}o(Tn,"getAnalyticsEmitOnStopMinIntervalSeconds");function In(n){const t=c(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!1:t.emitTurnEvents===!0}o(In,"isAnalyticsTurnEventsEnabled");function xn(n){const t=c(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!1:t.emitStepEvents===!0}o(xn,"isAnalyticsStepEventsEnabled");function wn(n){const t=c(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!0:t.emitApiRequestEvents!==!1}o(wn,"isAnalyticsApiRequestEventsEnabled");0&&(module.exports={ALL_CYCLES,CONFIG_TARGETS_BY_PRECEDENCE,CYCLES_ENABLED_BY_DEFAULT,CYCLE_DEFAULT_VERIFY_PATTERNS,CYCLE_TOOL_PREFIXES,CYCLE_TO_SERVER,DEFAULT_ANDROID_ALWAYS_REQUIRED,DEFAULT_ANDROID_EVIDENCE_PATHS,DEFAULT_ANDROID_VERIFY_PATTERNS,DEFAULT_BACKEND_ALWAYS_REQUIRED,DEFAULT_BACKEND_EVIDENCE_PATHS,DEFAULT_BACKEND_VERIFY_PATTERNS,DEFAULT_BROWSER_ALWAYS_REQUIRED,DEFAULT_BROWSER_VERIFY_PATTERNS,DEFAULT_NODE_ALWAYS_REQUIRED,DEFAULT_NODE_EVIDENCE_PATHS,DEFAULT_NODE_VERIFY_PATTERNS,DEFAULT_OAUTH_USAGE_TTL_SECONDS,DEFAULT_OTEL_EMIT_MIN_INTERVAL_SECONDS,DEFAULT_OTEL_ENSURE_MIN_INTERVAL_SECONDS,DEFAULT_OTEL_IDLE_TIMEOUT_SECONDS,DEFAULT_OTEL_PORT,DEFAULT_VERIFICATION_CONTEXT_COMMIT_DEPTH,DEFAULT_VERIFICATION_CONTEXT_MAX_BYTES,ENV_OVERRIDES,OPTIONAL_CYCLES,applyEnvOverrides,findActiveEnvOverride,getActiveCycles,getAnalyticsEmitOnStopMinIntervalSeconds,getAndroidDevToolsMcpEntry,getAutoVerifyEnabled,getBackendDevToolsMcpEntry,getCaptureFileChangeset,getClaudeOauthAccessEnabled,getClaudeOauthAccessUsageTtlSeconds,getConfigLayerPaths,getMaxChangesetBytes,getMaxRetries,getMcpServerEntry,getNodeDevToolsMcpEntry,getOTELEmitMinIntervalSeconds,getOTELEnsureMinIntervalSeconds,getOTELIdleTimeoutSeconds,getOTELPort,getPrivacyEnabled,getRequiredToolsConfig,getStatusLineEmitMinIntervalSeconds,getStatusLineRefreshInterval,getStatusLineRenderDefault,getTargetConfigPath,getTelemetryEnabled,getVerificationContextCommitDepth,getVerificationContextEnabled,getVerificationContextMaxBytes,getVerificationContextSource,getVerificationEnabled,getVerificationMode,getVerificationModel,isAnalyticsApiRequestEventsEnabled,isAnalyticsEmitOnStopEnabled,isAnalyticsEnabled,isAnalyticsStepEventsEnabled,isAnalyticsTurnEventsEnabled,isAutoModeAllowlistEnabled,isCollectorConfigured,isCycleEnabled,isCyclePatternsActive,isIgnoredVerifyPath,isJobQueueEnabled,isOTELEnabled,isRecordingEnabled,isSessionStatusEnabled,loadConfig,requiresVerification,resolveConfigTargetFromFlags});
|
|
1
|
+
"use strict";var y=Object.defineProperty;var ue=Object.getOwnPropertyDescriptor;var fe=Object.getOwnPropertyNames;var ge=Object.prototype.hasOwnProperty;var o=(n,e)=>y(n,"name",{value:e,configurable:!0});var de=(n,e)=>{for(var t in e)y(n,t,{get:e[t],enumerable:!0})},pe=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of fe(e))!ge.call(n,i)&&i!==t&&y(n,i,{get:()=>e[i],enumerable:!(r=ue(e,i))||r.enumerable});return n};var be=n=>pe(y({},"__esModule",{value:!0}),n);var hn={};de(hn,{ALL_CYCLES:()=>Ee,CONFIG_TARGETS_BY_PRECEDENCE:()=>je,CYCLES_ENABLED_BY_DEFAULT:()=>P,CYCLE_DEFAULT_VERIFY_PATTERNS:()=>$,CYCLE_TOOL_PREFIXES:()=>_e,CYCLE_TO_SERVER:()=>ye,DEFAULT_ANDROID_ALWAYS_REQUIRED:()=>W,DEFAULT_ANDROID_EVIDENCE_PATHS:()=>Q,DEFAULT_ANDROID_VERIFY_PATTERNS:()=>U,DEFAULT_BACKEND_ALWAYS_REQUIRED:()=>H,DEFAULT_BACKEND_EVIDENCE_PATHS:()=>G,DEFAULT_BACKEND_VERIFY_PATTERNS:()=>V,DEFAULT_BROWSER_ALWAYS_REQUIRED:()=>K,DEFAULT_BROWSER_VERIFY_PATTERNS:()=>M,DEFAULT_IGNORED_VERIFY_PATTERNS:()=>q,DEFAULT_NODE_ALWAYS_REQUIRED:()=>Y,DEFAULT_NODE_EVIDENCE_PATHS:()=>X,DEFAULT_NODE_VERIFY_PATTERNS:()=>F,DEFAULT_OAUTH_USAGE_TTL_SECONDS:()=>ee,DEFAULT_OTEL_EMIT_MIN_INTERVAL_SECONDS:()=>re,DEFAULT_OTEL_ENSURE_MIN_INTERVAL_SECONDS:()=>oe,DEFAULT_OTEL_IDLE_TIMEOUT_SECONDS:()=>te,DEFAULT_OTEL_PORT:()=>ne,DEFAULT_VERIFICATION_CONTEXT_COMMIT_DEPTH:()=>ae,DEFAULT_VERIFICATION_CONTEXT_MAX_BYTES:()=>se,ENV_OVERRIDES:()=>j,OPTIONAL_CYCLES:()=>T,applyEnvOverrides:()=>z,findActiveEnvOverride:()=>ke,getActiveCycles:()=>J,getAnalyticsEmitOnStopMinIntervalSeconds:()=>xn,getAndroidDevToolsMcpEntry:()=>Je,getAutoVerifyEnabled:()=>ie,getBackendDevToolsMcpEntry:()=>ze,getCaptureFileChangeset:()=>vn,getClaudeOauthAccessEnabled:()=>sn,getClaudeOauthAccessUsageTtlSeconds:()=>cn,getConfigLayerPaths:()=>x,getMaxChangesetBytes:()=>In,getMaxRetries:()=>Ze,getMcpServerEntry:()=>We,getNodeDevToolsMcpEntry:()=>Qe,getOTELEmitMinIntervalSeconds:()=>dn,getOTELEnsureMinIntervalSeconds:()=>gn,getOTELIdleTimeoutSeconds:()=>fn,getOTELPort:()=>un,getPrivacyEnabled:()=>le,getRequiredToolsConfig:()=>Ne,getStatusLineEmitMinIntervalSeconds:()=>rn,getStatusLineRefreshInterval:()=>pn,getStatusLineRenderDefault:()=>on,getTargetConfigPath:()=>Re,getTelemetryEnabled:()=>ce,getVerificationContextCommitDepth:()=>_n,getVerificationContextEnabled:()=>En,getVerificationContextMaxBytes:()=>Cn,getVerificationContextSource:()=>yn,getVerificationEnabled:()=>O,getVerificationMode:()=>An,getVerificationModel:()=>Ae,getVerificationStrict:()=>bn,isAnalyticsApiRequestEventsEnabled:()=>On,isAnalyticsEmitOnStopEnabled:()=>wn,isAnalyticsEnabled:()=>Tn,isAnalyticsStepEventsEnabled:()=>Rn,isAnalyticsTurnEventsEnabled:()=>jn,isAutoModeAllowlistEnabled:()=>an,isCollectorConfigured:()=>R,isCycleEnabled:()=>De,isCyclePatternsActive:()=>Z,isIgnoredVerifyPath:()=>mn,isJobQueueEnabled:()=>en,isOTELEnabled:()=>ln,isRecordingEnabled:()=>nn,isSessionStatusEnabled:()=>tn,loadConfig:()=>c,requiresVerification:()=>Le,resolveConfigTargetFromFlags:()=>Oe,resolveIgnoredVerifyPatterns:()=>w});module.exports=be(hn);var E=require("fs"),b=require("path"),I=require("os"),N=require("./logger");const T=["node","backend","android"],Ee=["browser",...T],P=new Set(["browser"]),ye={browser:"browser-devtools",node:"node-devtools",backend:"backend-devtools",android:"android-devtools"},_e={browser:"bdt_",node:"ndt_",backend:"bedt_",android:"adt_"},M=["*.ts","*.tsx","*.js","*.jsx","*.mjs","*.cjs","*.vue","*.svelte","*.html","*.htm","*.css","*.scss","*.sass","*.less","*.styl","*.py","*.rb","*.erb","*.go","*.rs","*.java","*.kt","*.kts","*.swift","*.c","*.cpp","*.h","*.hpp","*.cs","*.php","*.dart","*.ex","*.exs","*.erl","*.lua","*.r","*.R","*.scala","*.clj","*.cljs","*.zig","*.nim","*.hbs","*.ejs","*.pug","*.jade","*.astro"],F=["server/**/*.{ts,js,mjs,cjs}","src/server/**/*.{ts,js,mjs,cjs}","backend/**/*.{ts,js,mjs,cjs}","api/**/*.{ts,js,mjs,cjs}","src/api/**/*.{ts,js,mjs,cjs}","pages/api/**/*.{ts,js,mjs,cjs}","app/api/**/*.{ts,js,mjs,cjs}","routes/**/*.{ts,js,mjs,cjs}","**/server.{ts,js,mjs,cjs}"],V=["server/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","src/server/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","backend/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","api/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","src/api/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","pages/api/**/*.{ts,js,mjs,cjs}","app/api/**/*.{ts,js,mjs,cjs}","routes/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","controllers/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","handlers/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","services/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","**/server.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","**/main.{go,py,java,rb,kt,scala}"],U=["android/**/*.{kt,java}","app/src/**/*.{kt,java}","mobile/**/*.{kt,java}","src/main/kotlin/**/*.kt","src/main/java/**/*.java","**/*.{kt,java}","**/res/**/*.xml","**/AndroidManifest.xml"],$={browser:M,node:F,backend:V,android:U},q=["**/*.spec.*","**/*.test.*","**/__tests__/**","**/__mocks__/**"];function w(n){const e=n.ignoredVerifyPatterns??[];return[...q,...e]}o(w,"resolveIgnoredVerifyPatterns");const K=["bdt_navigation_go-to","bdt_content_take-screenshot","bdt_a11y_take-aria-snapshot","bdt_o11y_get-console-messages"],Y=["ndt_debug_connect"],X=[{name:"probe",allOf:[{anyOf:["ndt_debug_put-tracepoint","ndt_debug_put-logpoint","ndt_debug_put-exceptionpoint"]},"ndt_debug_get-probe-snapshots"]},{name:"log",allOf:["ndt_debug_get-logs"]}],H=[],G=[{name:"protocol-call",allOf:[{anyOf:["bedt_request_http","bedt_request_grpc","bedt_request_graphql","bedt_request_websocket-open","bedt_request_replay"]}]},{name:"log-evidence",allOf:["bedt_log_register-source",{anyOf:["bedt_log_read","bedt_log_read-multi","bedt_log_follow"]}]},{name:"db-evidence",allOf:["bedt_db_connect",{anyOf:["bedt_db_query","bedt_db_describe-table","bedt_db_list-tables","bedt_db_snapshot","bedt_db_diff","bedt_db_get-changes"]}]}],W=["adt_device_connect"],Q=[{name:"device-evidence",allOf:[{anyOf:["adt_device_launch-app","adt_interaction_tap","adt_interaction_double-tap","adt_interaction_long-press","adt_interaction_input-text","adt_interaction_swipe","adt_interaction_scroll","adt_interaction_press-key","adt_interaction_deep-link"]},"adt_content_take-screenshot","adt_a11y_take-ui-snapshot"]},{name:"log-evidence",allOf:[{anyOf:["adt_o11y_log-read","adt_o11y_log-follow"]}]}],Ce=3;function k(n){if(!(0,E.existsSync)(n))return{};try{return JSON.parse((0,E.readFileSync)(n,"utf-8"))}catch(e){return N.logger.debug(`failed to parse config ${n}: ${e}`),{}}}o(k,"loadJsonFile");function me(n,e){if(!Object.prototype.hasOwnProperty.call(n,"verification"))return;const t=n.verification;if(t===null||typeof t!="object"||Array.isArray(t))throw new Error(`Invalid IronBee config in ${e}: 'verification' must be an object. Expected shape: { "enable": boolean }.`);const r=t;if(Object.prototype.hasOwnProperty.call(r,"enable")&&typeof r.enable!="boolean")throw new Error(`Invalid IronBee config in ${e}: 'verification.enable' must be boolean. Got ${typeof r.enable}.`);if(Object.prototype.hasOwnProperty.call(r,"auto")&&typeof r.auto!="boolean")throw new Error(`Invalid IronBee config in ${e}: 'verification.auto' must be boolean. Got ${typeof r.auto}.`);if(Object.prototype.hasOwnProperty.call(r,"strict")&&typeof r.strict!="boolean")throw new Error(`Invalid IronBee config in ${e}: 'verification.strict' must be boolean. Got ${typeof r.strict}.`);if(Object.prototype.hasOwnProperty.call(r,"model")){const i=r.model,s=typeof i=="string",l=i!==null&&typeof i=="object"&&!Array.isArray(i)&&Object.values(i).every(a=>typeof a=="string");if(!s&&!l)throw new Error(`Invalid IronBee config in ${e}: 'verification.model' must be a string (applies to all clients) or an object of string values (per-client, e.g. { "claude": "sonnet", "codex": "gpt-5.5" }). Got ${Array.isArray(i)?"array":typeof i}.`)}}o(me,"assertVerificationShape");function Ae(n,e){const t=n.verification?.model;if(typeof t=="string")return t.length>0?t:void 0;if(t&&typeof t=="object"){const r=t[e];return typeof r=="string"&&r.length>0?r:void 0}}o(Ae,"getVerificationModel");function ve(n,e){if(!Object.prototype.hasOwnProperty.call(n,"telemetry"))return;const t=n.telemetry;if(t===null||typeof t!="object"||Array.isArray(t))throw new Error(`Invalid IronBee config in ${e}: 'telemetry' must be an object. Expected shape: { "enable": boolean }.`);const r=t;if(Object.prototype.hasOwnProperty.call(r,"enable")&&typeof r.enable!="boolean")throw new Error(`Invalid IronBee config in ${e}: 'telemetry.enable' must be boolean. Got ${typeof r.enable}.`)}o(ve,"assertTelemetryShape");function Ie(n,e){if(!Object.prototype.hasOwnProperty.call(n,"privacy"))return;const t=n.privacy;if(t===null||typeof t!="object"||Array.isArray(t))throw new Error(`Invalid IronBee config in ${e}: 'privacy' must be an object. Expected shape: { "enable": boolean }.`);const r=t;if(Object.prototype.hasOwnProperty.call(r,"enable")&&typeof r.enable!="boolean")throw new Error(`Invalid IronBee config in ${e}: 'privacy.enable' must be boolean. Got ${typeof r.enable}.`)}o(Ie,"assertPrivacyShape");function _(n,e){if(!(n===void 0&&e===void 0))return{...n??{},...e??{}}}o(_,"mergeCycleConfig");function B(n,e){const t={...n,...e};return t.browser=_(n.browser,e.browser),t.node=_(n.node,e.node),t.backend=_(n.backend,e.backend),t.android=_(n.android,e.android),t.claude=xe(n.claude,e.claude),t.verification=we(n.verification,e.verification),t.verificationContext=Te(n.verificationContext,e.verificationContext),t}o(B,"mergeConfigLayers");function Te(n,e){if(!(n===void 0&&e===void 0))return{...n??{},...e??{}}}o(Te,"mergeVerificationContextConfig");function we(n,e){if(!(n===void 0&&e===void 0))return{...n??{},...e??{}}}o(we,"mergeVerificationConfig");function xe(n,e){if(n===void 0&&e===void 0)return;const t={...n??{},...e??{}};return(n?.oauthAccess!==void 0||e?.oauthAccess!==void 0)&&(t.oauthAccess={...n?.oauthAccess??{},...e?.oauthAccess??{}}),(n?.autoModeAllowlist!==void 0||e?.autoModeAllowlist!==void 0)&&(t.autoModeAllowlist={...n?.autoModeAllowlist??{},...e?.autoModeAllowlist??{}}),t}o(xe,"mergeClaudeConfig");function x(n){return{global:(0,b.join)((0,I.homedir)(),".ironbee","config.json"),project:n?(0,b.join)(n,".ironbee","config.json"):void 0,local:n?(0,b.join)(n,".ironbee","config.local.json"):void 0}}o(x,"getConfigLayerPaths");const je=["global","project","local"];function Re(n,e){const t=x(e);if(n==="global")return t.global;if(n==="project"){if(t.project===void 0)throw new Error("Project layer requested but no projectDir was provided.");return t.project}if(t.local===void 0)throw new Error("Local layer requested but no projectDir was provided.");return t.local}o(Re,"getTargetConfigPath");function Oe(n){if(n.global===!0&&n.local===!0)throw new Error("Pass at most one of --global / --local.");return n.global===!0?"global":n.local===!0?"local":"project"}o(Oe,"resolveConfigTargetFromFlags");function A(n){const e=k(n);return(0,E.existsSync)(n)&&(me(e,n),ve(e,n),Ie(e,n)),e}o(A,"loadAndValidateLayer");const j=[{envVar:"IRONBEE_API_KEY",configPath:"collector.apiKey"},{envVar:"IRONBEE_OAUTH_TOKEN",configPath:"collector.oauthToken"}];function he(n,e,t){const r=e.split(".");let i=n;for(let s=0;s<r.length-1;s++){const l=r[s],a=i[l];a!=null&&typeof a=="object"&&!Array.isArray(a)?i[l]={...a}:i[l]={},i=i[l]}i[r[r.length-1]]=t}o(he,"setAtConfigPath");function z(n){let e;for(const t of j){const r=process.env[t.envVar];if(r===void 0||r.length===0)continue;e===void 0&&(e={...n});const i=t.coerce?t.coerce(r):r;he(e,t.configPath,i)}return e??n}o(z,"applyEnvOverrides");function ke(n){for(const e of j){if(e.configPath!==n)continue;const t=process.env[e.envVar];if(t!==void 0&&t.length>0)return e}}o(ke,"findActiveEnvOverride");function c(n){const e=x(n),t=A(e.global),r=e.project?A(e.project):{},i=e.local?A(e.local):{},s=B(B(t,r),i);return z(s)}o(c,"loadConfig");function Be(n){let e=n.replace(/\{([^}]+)\}/g,(t,r)=>`(${r.split(",").map(i=>i.trim()).join("|")})`);return e=e.replace(/\*\*\//g,"\0DSS\0").replace(/\*\*/g,"\0DS\0").replace(/\*/g,"\0SS\0").replace(/\?/g,"\0QM\0"),e=e.replace(/[.+^$\\[\]]/g,"\\$&"),e=e.replace(/\x00DSS\x00/g,"(?:.*/)?").replace(/\x00DS\x00/g,".*").replace(/\x00SS\x00/g,"[^/]*").replace(/\x00QM\x00/g,"[^/]"),new RegExp(`(^|/)${e}$`)}o(Be,"globToRegExp");function C(n,e){const t=n.replace(/\\/g,"/");for(const r of e)if(Be(r).test(t))return!0;return!1}o(C,"matchesAny");function Se(n,e){if(e==="browser")return n.browser;if(e==="node")return n.node;if(e==="backend")return n.backend;if(e==="android")return n.android}o(Se,"getCycleBlock");function v(n,e){const t=Se(n,e);if(t!==void 0&&t.enable===!1)return[];const r=$[e]??[];if(t===void 0)return P.has(e)?[...r]:[];if(Array.isArray(t.verifyPatterns)&&t.verifyPatterns.length===0)return[];const i=t.verifyPatterns??r,s=t.additionalVerifyPatterns??[];return[...i,...s]}o(v,"getCyclePatterns");function J(n,e){const t=w(e);if(t.length>0&&C(n,t))return[];const r=[];C(n,v(e,"browser"))&&r.push("browser");for(const i of T){const s=v(e,i);s.length>0&&C(n,s)&&r.push(i)}return r}o(J,"getActiveCycles");function Le(n,e){return J(n,e).length>0}o(Le,"requiresVerification");function De(n,e){return O(n)?Z(n,e):!1}o(De,"isCycleEnabled");function Z(n,e){return v(n,e).length>0}o(Z,"isCyclePatternsActive");function Ne(n,e){let t,r;if(e==="browser"?(t=n.browser?.alwaysRequired??K,r=n.browser?.evidencePaths??[]):e==="node"?(t=n.node?.alwaysRequired??Y,r=n.node?.evidencePaths??X):e==="backend"?(t=n.backend?.alwaysRequired??H,r=n.backend?.evidencePaths??G):e==="android"?(t=n.android?.alwaysRequired??W,r=n.android?.evidencePaths??Q):(t=[],r=[]),t.length===0&&r.length===0)throw new Error(`Invalid required-tools config for cycle '${e}': both 'alwaysRequired' and 'evidencePaths' are empty. At least one must specify required tools.`);return{alwaysRequired:t,evidencePaths:r}}o(Ne,"getRequiredToolsConfig");const S="npx",Pe="^0.11.0",L=["-y",`@ironbee-ai/devtools@${Pe}`],Me={TOOL_NAME_PREFIX:"bdt_",TOOL_INPUT_METADATA_ENABLE:"true"},Fe={PLATFORM:"node",TOOL_NAME_PREFIX:"ndt_",TOOL_INPUT_METADATA_ENABLE:"true"},Ve={PLATFORM:"backend",TOOL_NAME_PREFIX:"bedt_",TOOL_INPUT_METADATA_ENABLE:"true"},Ue={PLATFORM:"android",TOOL_NAME_PREFIX:"adt_",TOOL_INPUT_METADATA_ENABLE:"true"},$e={BROWSER_DEVTOOLS_INSTALL_CHROMIUM:"true"},qe={},Ke={},Ye={};function Xe(n){return ce(n)?{}:{TELEMETRY_ENABLE:"false"}}o(Xe,"buildTelemetryEnv");function He(n){return le(n)?{COLLECTOR_EVENTS_TOOL_DETAILS_ENABLE:"false",COLLECTOR_ARTIFACTS_ENABLE:"false"}:{}}o(He,"buildPrivacyEnv");function Ge(n,e){if(!R(n))return{};const t=n.collector,i=k((0,b.join)((0,I.homedir)(),".ironbee","config.json")).collector??{},s=typeof i.oauthToken=="string"&&i.oauthToken.length>0,l=typeof i.apiKey=="string"&&i.apiKey.length>0;let a;t.oauthToken?a=s?"X-OAuth-Token=${file:~/.ironbee/config.json#collector.oauthToken}":`X-OAuth-Token=${t.oauthToken}`:a=l?"X-API-Key=${file:~/.ironbee/config.json#collector.apiKey}":`X-API-Key=${t.apiKey}`;const u={OTEL_ENABLE:"true",OTEL_EXPORTER_HTTP_URL:t.url,OTEL_EXPORTER_HTTP_HEADERS:a,OTEL_EXPORTER_TYPE:"otlp/http-protobuf"};return e==="browser"&&(u.OTEL_INSTRUMENTATION_USER_INTERACTION_EVENTS="change,input,click",u.BROWSER_HEADLESS_ENABLE="true"),u}o(Ge,"buildOTELEnv");function m(n,e,t,r,i){const s=Ge(n,i),l=Xe(n),a=He(n),u=n[e];if(u&&typeof u=="object"&&!Array.isArray(u)){const f=u;if(f.mcp&&typeof f.mcp=="object"&&!Array.isArray(f.mcp)){const g={...f.mcp},d={...s,...l,...a,...g.env??{},...t};return g.env=d,g}const h={};if(f.env&&typeof f.env=="object"&&!Array.isArray(f.env)){const g=f.env;for(const d of Object.keys(g))typeof g[d]=="string"&&(h[d]=g[d])}return{command:S,args:[...L],env:{...r,...s,...l,...a,...h,...t}}}return{command:S,args:[...L],env:{...r,...s,...l,...a,...t}}}o(m,"buildMcpEntry");function We(n){const e=c(n);return m(e,"browserDevTools",Me,$e,"browser")}o(We,"getMcpServerEntry");function Qe(n){const e=c(n);return m(e,"nodeDevTools",Fe,qe,"node")}o(Qe,"getNodeDevToolsMcpEntry");function ze(n){const e=c(n);return m(e,"backendDevTools",Ve,Ke,"backend")}o(ze,"getBackendDevToolsMcpEntry");function Je(n){const e=c(n);return m(e,"androidDevTools",Ue,Ye,"android")}o(Je,"getAndroidDevToolsMcpEntry");function Ze(n){return typeof n.maxRetries=="number"&&n.maxRetries>0?n.maxRetries:Ce}o(Ze,"getMaxRetries");function R(n){if(process.env.IRONBEE_COLLECTOR==="false")return!1;const e=n.collector;if(!e||e.enable===!1||typeof e.url!="string"||e.url.length===0)return!1;const t=typeof e.oauthToken=="string"&&e.oauthToken.length>0,r=typeof e.apiKey=="string"&&e.apiKey.length>0;return!(!t&&!r)}o(R,"isCollectorConfigured");function en(n){const e=c(n);return p(e,e.jobQueue)}o(en,"isJobQueueEnabled");function nn(n){const e=c(n);return p(e,e.recording)}o(nn,"isRecordingEnabled");function tn(n){return p(n,n.statusLine)}o(tn,"isSessionStatusEnabled");function on(n){const e=n.statusLine;return e!==void 0&&e.renderDefault===!0}o(on,"getStatusLineRenderDefault");function rn(n){const e=n.statusLine?.emitMinIntervalSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:10}o(rn,"getStatusLineEmitMinIntervalSeconds");const ee=60;function sn(n){return n.claude?.oauthAccess?.enable!==!1}o(sn,"getClaudeOauthAccessEnabled");function an(n){return n.claude?.autoModeAllowlist?.enable!==!1}o(an,"isAutoModeAllowlistEnabled");function cn(n){const e=n.claude?.oauthAccess?.usageTtlSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:ee}o(cn,"getClaudeOauthAccessUsageTtlSeconds");const ne=15986,te=600,oe=30,re=0;function ln(n){return p(n,n.otel)}o(ln,"isOTELEnabled");function un(n){const e=n.otel?.port;return typeof e=="number"&&Number.isInteger(e)&&e>0&&e<65536?e:ne}o(un,"getOTELPort");function fn(n){const e=n.otel?.idleTimeoutSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>0?e:te}o(fn,"getOTELIdleTimeoutSeconds");function gn(n){const e=n.otel?.ensureMinIntervalSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:oe}o(gn,"getOTELEnsureMinIntervalSeconds");function dn(n){const e=n.otel?.emitMinIntervalSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:re}o(dn,"getOTELEmitMinIntervalSeconds");function pn(n){const e=n.statusLine?.refreshInterval;if(typeof e=="number"&&Number.isFinite(e)&&e>=1)return e}o(pn,"getStatusLineRefreshInterval");function p(n,e){return e!=null&&typeof e=="object"&&!Array.isArray(e)?e.enable!==!1:R(n)}o(p,"isFeatureEnabledWithCollectorAutoEnable");function Bn(n){return n==null||typeof n!="object"||Array.isArray(n)?!1:n.enable!==!1}o(Bn,"isPresenceEnabled");function O(n){const e=n.verification;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.enable!==!1}o(O,"getVerificationEnabled");function ie(n){const e=n.verification;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.auto!==!1}o(ie,"getAutoVerifyEnabled");function bn(n){const e=n.verification;return e==null||typeof e!="object"||Array.isArray(e)?!1:e.strict===!0}o(bn,"getVerificationStrict");const se=65536,ae=1;function En(n){const e=n.verificationContext;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.enable!==!1}o(En,"getVerificationContextEnabled");function yn(n){return n.verificationContext?.source==="actions"?"actions":"git"}o(yn,"getVerificationContextSource");function _n(n){const e=n.verificationContext?.commitDepth;return typeof e=="number"&&Number.isFinite(e)&&e>=0?Math.floor(e):ae}o(_n,"getVerificationContextCommitDepth");function Cn(n){const e=n.verificationContext?.maxBytes;return typeof e=="number"&&Number.isFinite(e)&&e>0?Math.floor(e):se}o(Cn,"getVerificationContextMaxBytes");function mn(n,e){const t=w(n);return t.length>0&&C(e,t)}o(mn,"isIgnoredVerifyPath");function An(n){return O(n)?ie(n)?"enforce":"assist":"monitor"}o(An,"getVerificationMode");function ce(n){const e=n.telemetry;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.enable!==!1}o(ce,"getTelemetryEnabled");function le(n){const e=n.privacy;return e==null||typeof e!="object"||Array.isArray(e)?!1:e.enable===!0}o(le,"getPrivacyEnabled");const D=65536;function vn(n){const e=n.fileChange;return!e||typeof e!="object"||Array.isArray(e)?!1:e.captureChangeset===!0}o(vn,"getCaptureFileChangeset");function In(n){const e=n.fileChange;if(!e||typeof e!="object"||Array.isArray(e))return D;const t=e.maxChangesetBytes;return typeof t!="number"||!Number.isFinite(t)||t<=0?D:Math.floor(t)}o(In,"getMaxChangesetBytes");function Tn(n){const e=c(n);return p(e,e.analytics)}o(Tn,"isAnalyticsEnabled");function wn(n){const t=c(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!0:t.emitOnStop!==!1}o(wn,"isAnalyticsEmitOnStopEnabled");function xn(n){const t=c(n).analytics;if(t===null||typeof t!="object"||Array.isArray(t))return 0;const r=t.emitOnStopMinIntervalSeconds;return typeof r=="number"&&r>=0?r:0}o(xn,"getAnalyticsEmitOnStopMinIntervalSeconds");function jn(n){const t=c(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!1:t.emitTurnEvents===!0}o(jn,"isAnalyticsTurnEventsEnabled");function Rn(n){const t=c(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!1:t.emitStepEvents===!0}o(Rn,"isAnalyticsStepEventsEnabled");function On(n){const t=c(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!0:t.emitApiRequestEvents!==!1}o(On,"isAnalyticsApiRequestEventsEnabled");0&&(module.exports={ALL_CYCLES,CONFIG_TARGETS_BY_PRECEDENCE,CYCLES_ENABLED_BY_DEFAULT,CYCLE_DEFAULT_VERIFY_PATTERNS,CYCLE_TOOL_PREFIXES,CYCLE_TO_SERVER,DEFAULT_ANDROID_ALWAYS_REQUIRED,DEFAULT_ANDROID_EVIDENCE_PATHS,DEFAULT_ANDROID_VERIFY_PATTERNS,DEFAULT_BACKEND_ALWAYS_REQUIRED,DEFAULT_BACKEND_EVIDENCE_PATHS,DEFAULT_BACKEND_VERIFY_PATTERNS,DEFAULT_BROWSER_ALWAYS_REQUIRED,DEFAULT_BROWSER_VERIFY_PATTERNS,DEFAULT_IGNORED_VERIFY_PATTERNS,DEFAULT_NODE_ALWAYS_REQUIRED,DEFAULT_NODE_EVIDENCE_PATHS,DEFAULT_NODE_VERIFY_PATTERNS,DEFAULT_OAUTH_USAGE_TTL_SECONDS,DEFAULT_OTEL_EMIT_MIN_INTERVAL_SECONDS,DEFAULT_OTEL_ENSURE_MIN_INTERVAL_SECONDS,DEFAULT_OTEL_IDLE_TIMEOUT_SECONDS,DEFAULT_OTEL_PORT,DEFAULT_VERIFICATION_CONTEXT_COMMIT_DEPTH,DEFAULT_VERIFICATION_CONTEXT_MAX_BYTES,ENV_OVERRIDES,OPTIONAL_CYCLES,applyEnvOverrides,findActiveEnvOverride,getActiveCycles,getAnalyticsEmitOnStopMinIntervalSeconds,getAndroidDevToolsMcpEntry,getAutoVerifyEnabled,getBackendDevToolsMcpEntry,getCaptureFileChangeset,getClaudeOauthAccessEnabled,getClaudeOauthAccessUsageTtlSeconds,getConfigLayerPaths,getMaxChangesetBytes,getMaxRetries,getMcpServerEntry,getNodeDevToolsMcpEntry,getOTELEmitMinIntervalSeconds,getOTELEnsureMinIntervalSeconds,getOTELIdleTimeoutSeconds,getOTELPort,getPrivacyEnabled,getRequiredToolsConfig,getStatusLineEmitMinIntervalSeconds,getStatusLineRefreshInterval,getStatusLineRenderDefault,getTargetConfigPath,getTelemetryEnabled,getVerificationContextCommitDepth,getVerificationContextEnabled,getVerificationContextMaxBytes,getVerificationContextSource,getVerificationEnabled,getVerificationMode,getVerificationModel,getVerificationStrict,isAnalyticsApiRequestEventsEnabled,isAnalyticsEmitOnStopEnabled,isAnalyticsEnabled,isAnalyticsStepEventsEnabled,isAnalyticsTurnEventsEnabled,isAutoModeAllowlistEnabled,isCollectorConfigured,isCycleEnabled,isCyclePatternsActive,isIgnoredVerifyPath,isJobQueueEnabled,isOTELEnabled,isRecordingEnabled,isSessionStatusEnabled,loadConfig,requiresVerification,resolveConfigTargetFromFlags,resolveIgnoredVerifyPatterns});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var r=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var L=(e,S)=>{for(var o in S)r(e,o,{get:S[o],enumerable:!0})},N=(e,S,o,t)=>{if(S&&typeof S=="object"||typeof S=="function")for(let n of E(S))!I.call(e,n)&&n!==o&&r(e,n,{get:()=>S[n],enumerable:!(t=A(S,n))||t.enumerable});return e};var _=e=>N(r({},"__esModule",{value:!0}),e);var c={};L(c,{INSTALL_SCHEMA_VERSION:()=>b});module.exports=_(c);const b=
|
|
1
|
+
"use strict";var r=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var E=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var L=(e,S)=>{for(var o in S)r(e,o,{get:S[o],enumerable:!0})},N=(e,S,o,t)=>{if(S&&typeof S=="object"||typeof S=="function")for(let n of E(S))!I.call(e,n)&&n!==o&&r(e,n,{get:()=>S[n],enumerable:!(t=A(S,n))||t.enumerable});return e};var _=e=>N(r({},"__esModule",{value:!0}),e);var c={};L(c,{INSTALL_SCHEMA_VERSION:()=>b});module.exports=_(c);const b=4;0&&(module.exports={INSTALL_SCHEMA_VERSION});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var n=(e,t)=>a(e,"name",{value:t,configurable:!0});var g=(e,t)=>{for(var o in t)a(e,o,{get:t[o],enumerable:!0})},y=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of u(t))!h.call(e,i)&&i!==o&&a(e,i,{get:()=>t[i],enumerable:!(r=p(t,i))||r.enumerable});return e};var b=e=>y(a({},"__esModule",{value:!0}),e);var T={};g(T,{ARTIFACT_AFFECTING_TOP_KEYS:()=>v,CONFIG_SCHEMA:()=>d,GROUP_ORDER:()=>s,GROUP_TITLES:()=>f,findSchemaEntry:()=>A,groupOf:()=>c,groupRank:()=>l,groupTitle:()=>w,orderedEntries:()=>k,topKey:()=>m});module.exports=b(T);const v=new Set(["verification","collector","browser","node","backend","android","browserDevTools","nodeDevTools","backendDevTools","androidDevTools","telemetry","privacy","statusLine","otel"]),s=["general","verification","verificationContext","browser","node","backend","android","collector","recording","jobQueue","analytics","statusLine","claude","telemetry","privacy","otel","fileChange","import","browserDevTools","nodeDevTools","backendDevTools","androidDevTools"],f={general:"General",verification:"Verification",verificationContext:"Verification context",browser:"Browser cycle",node:"Node cycle",backend:"Backend cycle",android:"Android cycle",collector:"Collector",recording:"Recording",jobQueue:"Job queue",analytics:"Analytics",statusLine:"Statusline",claude:"Claude",telemetry:"Telemetry",privacy:"Privacy",otel:"OTEL collector",fileChange:"File change",import:"Import",browserDevTools:"Browser DevTools MCP",nodeDevTools:"Node DevTools MCP",backendDevTools:"Backend DevTools MCP",androidDevTools:"Android DevTools MCP"};function m(e){const t=e.indexOf(".");return t===-1?e:e.slice(0,t)}n(m,"topKey");function c(e){const t=e.indexOf(".");return t===-1?"general":e.slice(0,t)}n(c,"groupOf");function w(e){return f[e]??e}n(w,"groupTitle");function l(e){const t=s.indexOf(e);return t===-1?s.length:t}n(l,"groupRank");const d=[{path:"ignoredVerifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns excluded from verification, applied to every cycle (browser / node / backend). Checked first \u2014 a match here activates no cycle regardless of other patterns.",def:"[]",artifactAffecting:!1},{path:"maxRetries",type:"number",editor:"number",description:"Max verification retry attempts before the gate allows completion despite failures. Single global counter regardless of how many cycles ran.",def:"3",artifactAffecting:!1},{path:"verification.enable",type:"boolean",editor:"toggle",description:"Master enforcement switch. Inverse semantics \u2014 verification is the core feature, opt out with false. When false, IronBee runs monitoring-only: no enforcement hooks, no skill/rule, no MCP servers; only session/activity/tool_call events flow to the collector.",def:"true",artifactAffecting:!0},{path:"verification.auto",type:"boolean",editor:"toggle",description:'Automatic-enforcement sub-toggle (only meaningful when verification.enable !== false). Inverse semantics \u2014 opt out with false for "assist mode": the /ironbee-verify command + MCP servers stay installed so the agent can verify manually, but nothing is enforced \u2014 no Stop gate, non-blocking (soft) PreToolUse hooks, and the skill/rule are omitted. true \u2192 full enforce mode.',def:"true",artifactAffecting:!0},{path:"verification.model",type:"json",editor:"json",description:`Model the delegated verifier sub-agent uses. Unset \u2192 the verifier inherits the session model (Claude verifier omits model: \u2192 inherit; Codex verifier omits agent-toml model \u2192 inherits config.toml's model). Set to PIN a specific model \u2014 e.g. verify on a cheaper/faster model than the main agent, or guarantee a model on Codex when config.toml has none. Two shapes: a string (applies to all clients, e.g. "sonnet" / "gpt-5.5") or a per-client object { claude: "sonnet", codex: "gpt-5.5" } when a project has both clients. Cursor has no verifier sub-agent \u2192 no-op there. Never resolves to a literal "inherit" on Codex (a 400). Artifact-affecting.`,def:"unset (inherit the session model)",artifactAffecting:!0},{path:"verificationContext.enable",type:"boolean",editor:"toggle",description:"Master switch for path-scoped verification context. When a cycle begins, the first devtools tool call injects the .ironbee/VERIFICATION.md files on/above the changed paths (author-written area guidance) into the agent's context via the host's additionalContext channel. Advisory only (does not gate). Inverse semantics \u2014 default-on, opt out with false. Not artifact-affecting (read live).",def:"true",artifactAffecting:!1},{path:"verificationContext.source",type:"string",editor:"enum",enumValues:["git","actions"],description:`Changed-path source. "git" (default) = working tree + last N commits, with an actions.jsonl fallback when not a git repo. "actions" = IronBee's own file_change events only (no git subprocess).`,def:"git",artifactAffecting:!1},{path:"verificationContext.commitDepth",type:"number",editor:"number",description:'Number of recent commits included on the git source (uncommitted \u222A last N commits). 0 = uncommitted only. Ignored when source is "actions".',def:"1",artifactAffecting:!1},{path:"verificationContext.maxBytes",type:"number",editor:"number",description:"Aggregate byte cap on the injected context string. When exceeded, the least-specific (root-side) docs are dropped first (leaf-first truncation priority).",def:"65536 (64 KB)",artifactAffecting:!1},{path:"browser.enable",type:"boolean",editor:"toggle",description:"Explicit on/off for the browser cycle. Written false by `browser disable`, stripped by `browser enable`. When false the cycle is disabled regardless of patterns.",def:"(absent \u2192 on; browser is the only default-on cycle)",artifactAffecting:!0},{path:"browser.verifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns for files requiring browser verification. Four-state: absent \u2192 code defaults (40+ extensions); [] \u2192 hard kill; non-empty \u2192 custom patterns (replaces defaults).",def:"40+ code extensions when unset; [] hard-disables",artifactAffecting:!0},{path:"browser.additionalVerifyPatterns",type:"string-array",editor:"string-list",description:"Extra patterns appended to browser.verifyPatterns (or to code defaults when verifyPatterns is unset). Ignored when verifyPatterns is [] (hard kill wins).",def:"[]",artifactAffecting:!0},{path:"browser.alwaysRequired",type:"string-array",editor:"string-list",description:"Browser-cycle required tools (all-of). The verify-gate blocks completion until every listed bdt_* tool was used.",def:"bdt_navigation_go-to, bdt_content_take-screenshot, bdt_a11y_take-aria-snapshot, bdt_o11y_get-console-messages",artifactAffecting:!0},{path:"browser.evidencePaths",type:"json",editor:"json",description:"Alternative tool-satisfaction paths (any-of). Browser uses pure all-of, so default is empty. Each path: { name, allOf: (string | { anyOf: string[] })[] }.",def:"[]",artifactAffecting:!0},{path:"node.enable",type:"boolean",editor:"toggle",description:"Explicit on/off for the Node.js runtime debug cycle (node-devtools, ndt_* V8 inspector probes). Opt-in \u2014 written by `node enable`.",def:"(absent \u2192 off; node is opt-in)",artifactAffecting:!0},{path:"node.verifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns for the Node.js runtime debug cycle. Default-off \u2014 block absent = inert. Block present + unset \u2192 9 code defaults (server/api/routes paths).",def:"block absent \u2192 disabled; present + unset \u2192 code defaults",artifactAffecting:!0},{path:"node.additionalVerifyPatterns",type:"string-array",editor:"string-list",description:"Extra patterns appended to node.verifyPatterns (or to code defaults when unset). Ignored when verifyPatterns is [].",def:"[]",artifactAffecting:!0},{path:"node.alwaysRequired",type:"string-array",editor:"string-list",description:"Node-cycle required tools (all-of). ndt_debug_connect always; evidence paths supply the rest.",def:"[ndt_debug_connect]",artifactAffecting:!0},{path:"node.evidencePaths",type:"json",editor:"json",description:"Alternative tool paths (any-of). Default: probe path (a put-*point AND get-probe-snapshots) OR log path (get-logs).",def:"probe path + log path",artifactAffecting:!0},{path:"backend.enable",type:"boolean",editor:"toggle",description:"Explicit on/off for the runtime-agnostic backend protocol cycle (backend-devtools, bedt_* HTTP/gRPC/GraphQL/WebSocket). Opt-in \u2014 written by `backend enable`.",def:"(absent \u2192 off; backend is opt-in)",artifactAffecting:!0},{path:"backend.verifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns for the backend protocol cycle. Default-off \u2014 block absent = inert. Block present + unset \u2192 13 multi-language code defaults (ts/js/py/go/java/rb/cs/rs/kt/scala/ex/php/clj).",def:"block absent \u2192 disabled; present + unset \u2192 code defaults",artifactAffecting:!0},{path:"backend.additionalVerifyPatterns",type:"string-array",editor:"string-list",description:"Extra patterns appended to backend.verifyPatterns (or to code defaults when unset). Ignored when verifyPatterns is [].",def:"[]",artifactAffecting:!0},{path:"backend.alwaysRequired",type:"string-array",editor:"string-list",description:"Backend-cycle required tools (all-of). Empty by default \u2014 backend uses any-of evidence paths instead.",def:"[]",artifactAffecting:!0},{path:"backend.evidencePaths",type:"json",editor:"json",description:"Alternative tool paths (any-of). Default three: protocol-call (any request tool) OR log-evidence (register-source + read) OR db-evidence (db_connect + a read op).",def:"protocol-call OR log-evidence OR db-evidence",artifactAffecting:!0},{path:"android.enable",type:"boolean",editor:"toggle",description:"Explicit on/off for the Android mobile verification cycle (android-devtools, adt_* device/emulator interaction). Opt-in \u2014 written by `android enable`.",def:"(absent \u2192 off; android is opt-in)",artifactAffecting:!0},{path:"android.verifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns for the Android mobile verification cycle. Default-off \u2014 block absent = inert. Block present + unset \u2192 code defaults (Android/React Native paths).",def:"block absent \u2192 disabled; present + unset \u2192 code defaults",artifactAffecting:!0},{path:"android.additionalVerifyPatterns",type:"string-array",editor:"string-list",description:"Extra patterns appended to android.verifyPatterns (or to code defaults when unset). Ignored when verifyPatterns is [].",def:"[]",artifactAffecting:!0},{path:"android.alwaysRequired",type:"string-array",editor:"string-list",description:"Android-cycle required tools (all-of). adt_device_connect always; evidence paths supply the rest.",def:"[adt_device_connect]",artifactAffecting:!0},{path:"android.evidencePaths",type:"json",editor:"json",description:"Alternative tool paths (any-of). Default two: device-evidence (UI interaction + screenshot + UI snapshot) OR log-evidence (Logcat read/follow).",def:"device-evidence OR log-evidence",artifactAffecting:!0},{path:"collector.enable",type:"boolean",editor:"toggle",description:"Master switch for the IronBee Collector. Implicitly true when the section has url and at least one credential (oauthToken or apiKey); set false to suspend while keeping url/oauthToken/apiKey/batchSize around.",def:"implicit true when url + (oauthToken or apiKey) set",artifactAffecting:!0},{path:"collector.url",type:"string",editor:"text",description:"Remote collector endpoint URL (IronBee Platform). Required for the collector to be active. Events POST to {url}/v1/events.",def:"(unset \u2192 disabled)",artifactAffecting:!0},{path:"collector.oauthToken",type:"string",editor:"text",description:"Personal access token for collector auth (X-OAuth-Token header). Per-(user, account), independently revocable from the console's /access-tokens page. Minted by `ironbee login` \u2014 the primary path for interactive CLI use. Can be supplied via IRONBEE_OAUTH_TOKEN.",def:"(unset)",artifactAffecting:!0},{path:"collector.apiKey",type:"string",editor:"text",description:"Shared account API key for collector auth (X-API-Key header). Parallel first-class path alongside `oauthToken`, intended for CI / GitHub Actions / deployment tooling and other non-interactive integrations where rotating a per-engineer OAuth token is impractical. Either `oauthToken` OR `apiKey` is required for the collector to be active. Can be supplied via IRONBEE_API_KEY.",def:"(unset \u2192 disabled)",artifactAffecting:!0},{path:"collector.batchSize",type:"number",editor:"number",description:"Max events per POST from the send_event handler (the queue chunks bigger snapshots into N-sized POSTs).",def:"100",artifactAffecting:!0},{path:"collector.timeoutMs",type:"number",editor:"number",description:"Per-request HTTP timeout (ms) for batched analytics sends. Single-event interactive sends keep a fixed 3000ms cap. Clamped to [1000, 60000].",def:"10000",artifactAffecting:!0},{path:"recording.enable",type:"boolean",editor:"toggle",description:"Recording enforcement for the browser + android cycles. Presence opts in; enable:false opts out. Auto-enabled when a collector is configured. Node/backend cycles never trigger recording.",def:"implicit true when section present or collector configured",artifactAffecting:!1},{path:"jobQueue.enable",type:"boolean",editor:"toggle",description:"Master switch for the file-backed job queue. Presence opts in; enable:false opts out. Auto-enabled when a collector is configured (a collector is pointless without a queue feeding it).",def:"implicit true when section present or collector configured",artifactAffecting:!1},{path:"jobQueue.autoFlushSizeBytes",type:"number",editor:"number",description:"Size threshold (bytes) above which submit() spawns a detached worker mid-session. 0 / negative disables this check.",def:"32768 (32 KB)",artifactAffecting:!1},{path:"jobQueue.autoFlushIntervalSeconds",type:"number",editor:"number",description:"Interval threshold (seconds since the live jobs.jsonl was created) above which submit() spawns a detached worker. Complements size \u2014 whichever crosses first flushes. 0 / negative disables.",def:"60",artifactAffecting:!1},{path:"analytics.enable",type:"boolean",editor:"toggle",description:"Master switch for per-session structural analytics. Presence opts in; enable:false opts out. Auto-enabled when a collector is configured.",def:"implicit true when section present or collector configured",artifactAffecting:!1},{path:"analytics.emitOnStop",type:"boolean",editor:"toggle",description:"When true, project + emit analytics at every Stop hook. When false, only at SessionEnd.",def:"true",artifactAffecting:!1},{path:"analytics.emitOnStopMinIntervalSeconds",type:"number",editor:"number",description:"Throttle: skip Stop-hook projection if the last successful emit was within this many seconds. 0 disables the throttle (backend handles rate-limit / dedupe).",def:"0 (disabled)",artifactAffecting:!1},{path:"analytics.emitTurnEvents",type:"boolean",editor:"toggle",description:"Opt-in for per-turn session_turn_analytics wire records. High-volume secondary signal; the base session_analytics record always ships regardless.",def:"false",artifactAffecting:!1},{path:"analytics.emitStepEvents",type:"boolean",editor:"toggle",description:"Opt-in for per-step session_turn_step_analytics wire records (an order of magnitude higher volume than turn events). Independent of emitTurnEvents.",def:"false",artifactAffecting:!1},{path:"analytics.emitApiRequestEvents",type:"boolean",editor:"toggle",description:"Opt-OUT for per-API-request api_request wire records (one per assistant message, success + failure). Primary value for backend cost accounting, so ships by default.",def:"true",artifactAffecting:!1},{path:"statusLine.enable",type:"boolean",editor:"toggle",description:"Master switch for the Claude statusline integration (session_status event + statusline wrapper). Presence opts in; auto-enabled when a collector is configured. Claude-only.",def:"implicit true when section present or collector configured",artifactAffecting:!0},{path:"statusLine.renderDefault",type:"boolean",editor:"toggle",description:"When there is no upstream statusline to chain to, false keeps the statusline silent; true renders a minimal model + context-% line. No effect when the user already has a statusline.",def:"false",artifactAffecting:!0},{path:"statusLine.emitMinIntervalSeconds",type:"number",editor:"number",description:"Minimum seconds between two emitted session_status events, on top of skip-if-unchanged. Rapid changes coalesce to the latest state after the interval. 0 disables the throttle. Read live each tick.",def:"10",artifactAffecting:!0},{path:"statusLine.refreshInterval",type:"number",editor:"number",description:"Claude Code's own statusLine.refreshInterval (seconds, host min 1) \u2014 re-runs the statusline on a timer in addition to event-driven updates. Unset by default. Values < 1 treated as unset.",def:"unset",artifactAffecting:!0},{path:"claude.oauthAccess.enable",type:"boolean",editor:"toggle",description:"Whether IronBee may read the Claude Code OAuth token (macOS Keychain / ~/.claude/.credentials.json) and call OAuth-scoped Anthropic endpoints. Default-on (opt out with false or `ironbee claude oauth-access disable`). First consumer: the statusline rate-limit fallback \u2014 fetches /api/oauth/usage to fill rate_limits for plans the statusline JSON omits them for (team / enterprise). Claude-only; not artifact-affecting (read live).",def:"true",artifactAffecting:!1},{path:"claude.oauthAccess.usageTtlSeconds",type:"number",editor:"number",description:"TTL (seconds) for the statusline OAuth rate-limit fetch cache \u2014 the /api/oauth/usage call + credential read fire at most once per this interval even when the statusline ticks far more often. Default 60; 0 means every tick.",def:"60",artifactAffecting:!1},{path:"claude.autoModeAllowlist.enable",type:"boolean",editor:"toggle",description:"Whether IronBee writes the auto-mode allowlist carve-out for the verifier into .claude/settings.local.json. Claude Code 2.1.176+ ships a host-side sub-agent \"Content Integrity\" classifier (auto mode) that false-positives on IronBee's legitimate `ironbee hook submit-verdict` verdicts (the devtools calls happened earlier in the cycle, not re-shown in the handoff). When enabled (default), install adds a narrow, command-keyed autoMode.allow rule that exempts ONLY that command from the Content Integrity block ($defaults preserved \u2014 every other block rule still applies; IronBee's Stop-gate independently enforces real tool usage). Written only when verification is active (enforce/assist); inert when the host isn't in auto mode. Opt out with false \u2014 takes effect on the next `ironbee install`. Claude-only.",def:"true",artifactAffecting:!1},{path:"telemetry.enable",type:"boolean",editor:"toggle",description:"Master switch for anonymous PostHog telemetry (CLI's own product analytics). Inverse semantics \u2014 opt out with false. Disabling also injects TELEMETRY_ENABLE=false into devtools MCP env. Orthogonal to the collector pipeline.",def:"true",artifactAffecting:!0},{path:"privacy.enable",type:"boolean",editor:"toggle",description:"Privacy mode \u2014 a single cross-cutting switch (all platforms) that redacts potentially sensitive data from what the @ironbee-ai/devtools MCP servers ship to the collector. Opt-in, default OFF. When true, injects COLLECTOR_EVENTS_TOOL_DETAILS_ENABLE=false (tool input/output detail) + COLLECTOR_ARTIFACTS_ENABLE=false (screenshots, recordings) into every devtools MCP env. Devtools-side only \u2014 the CLI's own send_event pipeline already whitelists tool_input and strips tool_response. Orthogonal to telemetry (PostHog) and collector (the sink).",def:"false",artifactAffecting:!0},{path:"otel.enable",type:"boolean",editor:"toggle",description:"Master switch for the local OTEL collector pipeline (Claude Code OTLP raw-API-body export \u2192 local daemon \u2192 session_context context-usage events). Presence opts in; enable:false opts out; auto-enabled when a collector is configured. session_context derivation is the sole consumer, so this also gates whether the settings.json OTEL env block (incl. raw-bodies) is written. Orthogonal to telemetry (PostHog) and collector (event sink).",def:"implicit true when collector configured",artifactAffecting:!0},{path:"otel.port",type:"number",editor:"number",description:"Loopback port the shared OTEL collector daemon binds to, and which the settings.json OTEL endpoint env var points at. One daemon per machine across all sessions.",def:"15986",artifactAffecting:!0},{path:"otel.idleTimeoutSeconds",type:"number",editor:"number",description:"The daemon self-reaps (graceful shutdown) after this many seconds with no /health hit and no OTLP event. Restarted on the next session/turn ensure.",def:"600",artifactAffecting:!0},{path:"otel.ensureMinIntervalSeconds",type:"number",editor:"number",description:"Throttle (seconds) for the high-frequency liveness `ensure` from per-tool hooks, so we don't pay a /health check on every tool call. session-start / activity-start ensure are unthrottled.",def:"30",artifactAffecting:!0},{path:"otel.emitMinIntervalSeconds",type:"number",editor:"number",description:"Per-session session_context emit throttle: admit at most one event per session per interval (leading-edge \u2014 the first request in each window is emitted, in-between requests are coalesced away and their body files dropped). Applies to the live path only; the catch-up/reprocess path is never throttled. 0 = emit on every API request (full context-growth time series).",def:"0",artifactAffecting:!0},{path:"fileChange.captureChangeset",type:"boolean",editor:"toggle",description:"When true, every file_change event carries a hunks-only unified-diff changeset string. Off by default \u2014 the default wire shape stays metadata-only (operation + line counts).",def:"false",artifactAffecting:!1},{path:"fileChange.maxChangesetBytes",type:"number",editor:"number",description:"Hard cap on the changeset string size. Diffs over the cap are truncated with a footer so the collector POST stays within typical reverse-proxy body limits.",def:"65536 (64 KB)",artifactAffecting:!1},{path:"import.concurrency",type:"number",editor:"number",description:"Default number of sessions `ironbee import` processes in parallel. Resolution: --concurrency flag > this value > built-in default. Clamped to [1, 32].",def:"4",artifactAffecting:!1},{path:"browserDevTools.env",type:"json",editor:"json",description:"Env-var overrides merged into the browser-devtools MCP server entry. Operators can override individual OTEL keys; IronBee invariants (TOOL_NAME_PREFIX, \u2026) always win last.",def:"unset (defaults + auto-OTEL when collector configured)",artifactAffecting:!0},{path:"browserDevTools.mcp",type:"json",editor:"json",description:"Full-replacement MCP config for the browser-devtools server entry. Auto-OTEL + telemetry env are still injected; IronBee env wins last.",def:"unset (use default npx -y @ironbee-ai/devtools entry)",artifactAffecting:!0},{path:"nodeDevTools.env",type:"json",editor:"json",description:"Env-var overrides merged into the node-devtools MCP server entry. Same auto-OTEL injection as browserDevTools minus the browser-only vars.",def:"unset (defaults + auto-OTEL when collector configured)",artifactAffecting:!0},{path:"nodeDevTools.mcp",type:"json",editor:"json",description:"Full-replacement MCP config for the node-devtools server entry. IronBee env wins last.",def:"unset (use default npx -y @ironbee-ai/devtools entry)",artifactAffecting:!0},{path:"backendDevTools.env",type:"json",editor:"json",description:"Env-var overrides merged into the backend-devtools MCP server entry. Same auto-OTEL injection as nodeDevTools.",def:"unset (defaults + auto-OTEL when collector configured)",artifactAffecting:!0},{path:"backendDevTools.mcp",type:"json",editor:"json",description:"Full-replacement MCP config for the backend-devtools server entry. IronBee env wins last.",def:"unset (use default npx -y @ironbee-ai/devtools entry)",artifactAffecting:!0},{path:"androidDevTools.env",type:"json",editor:"json",description:"Env-var overrides merged into the android-devtools MCP server entry. Same auto-OTEL injection as nodeDevTools.",def:"unset (defaults + auto-OTEL when collector configured)",artifactAffecting:!0},{path:"androidDevTools.mcp",type:"json",editor:"json",description:"Full-replacement MCP config for the android-devtools server entry. IronBee env wins last.",def:"unset (use default npx -y @ironbee-ai/devtools entry)",artifactAffecting:!0}];function A(e){return d.find(t=>t.path===e)}n(A,"findSchemaEntry");function k(){return[...d].sort((e,t)=>{const o=l(c(e.path)),r=l(c(t.path));return o!==r?o-r:e.path.localeCompare(t.path)})}n(k,"orderedEntries");0&&(module.exports={ARTIFACT_AFFECTING_TOP_KEYS,CONFIG_SCHEMA,GROUP_ORDER,GROUP_TITLES,findSchemaEntry,groupOf,groupRank,groupTitle,orderedEntries,topKey});
|
|
1
|
+
"use strict";var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var n=(e,t)=>a(e,"name",{value:t,configurable:!0});var g=(e,t)=>{for(var o in t)a(e,o,{get:t[o],enumerable:!0})},y=(e,t,o,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of u(t))!h.call(e,r)&&r!==o&&a(e,r,{get:()=>t[r],enumerable:!(i=p(t,r))||i.enumerable});return e};var b=e=>y(a({},"__esModule",{value:!0}),e);var T={};g(T,{ARTIFACT_AFFECTING_TOP_KEYS:()=>v,CONFIG_SCHEMA:()=>d,GROUP_ORDER:()=>s,GROUP_TITLES:()=>f,findSchemaEntry:()=>A,groupOf:()=>c,groupRank:()=>l,groupTitle:()=>w,orderedEntries:()=>k,topKey:()=>m});module.exports=b(T);const v=new Set(["verification","collector","browser","node","backend","android","browserDevTools","nodeDevTools","backendDevTools","androidDevTools","telemetry","privacy","statusLine","otel"]),s=["general","verification","verificationContext","browser","node","backend","android","collector","recording","jobQueue","analytics","statusLine","claude","telemetry","privacy","otel","fileChange","import","browserDevTools","nodeDevTools","backendDevTools","androidDevTools"],f={general:"General",verification:"Verification",verificationContext:"Verification context",browser:"Browser cycle",node:"Node cycle",backend:"Backend cycle",android:"Android cycle",collector:"Collector",recording:"Recording",jobQueue:"Job queue",analytics:"Analytics",statusLine:"Statusline",claude:"Claude",telemetry:"Telemetry",privacy:"Privacy",otel:"OTEL collector",fileChange:"File change",import:"Import",browserDevTools:"Browser DevTools MCP",nodeDevTools:"Node DevTools MCP",backendDevTools:"Backend DevTools MCP",androidDevTools:"Android DevTools MCP"};function m(e){const t=e.indexOf(".");return t===-1?e:e.slice(0,t)}n(m,"topKey");function c(e){const t=e.indexOf(".");return t===-1?"general":e.slice(0,t)}n(c,"groupOf");function w(e){return f[e]??e}n(w,"groupTitle");function l(e){const t=s.indexOf(e);return t===-1?s.length:t}n(l,"groupRank");const d=[{path:"ignoredVerifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns excluded from verification, applied to every cycle (browser / node / backend). Checked first \u2014 a match here activates no cycle regardless of other patterns. Unioned on top of an always-on default set that excludes test files (**/*.spec.*, **/*.test.*, **/__tests__/**, **/__mocks__/**) \u2014 a test-only edit never activates a runtime-verification cycle.",def:"[] (plus always-on test-file defaults)",artifactAffecting:!1},{path:"maxRetries",type:"number",editor:"number",description:"Max verification retry attempts before the gate allows completion despite failures. Single global counter regardless of how many cycles ran.",def:"3",artifactAffecting:!1},{path:"verification.enable",type:"boolean",editor:"toggle",description:"Master enforcement switch. Inverse semantics \u2014 verification is the core feature, opt out with false. When false, IronBee runs monitoring-only: no enforcement hooks, no skill/rule, no MCP servers; only session/activity/tool_call events flow to the collector.",def:"true",artifactAffecting:!0},{path:"verification.auto",type:"boolean",editor:"toggle",description:'Automatic-enforcement sub-toggle (only meaningful when verification.enable !== false). Inverse semantics \u2014 opt out with false for "assist mode": the /ironbee-verify command + MCP servers stay installed so the agent can verify manually, but nothing is enforced \u2014 no Stop gate, non-blocking (soft) PreToolUse hooks, and the skill/rule are omitted. true \u2192 full enforce mode.',def:"true",artifactAffecting:!0},{path:"verification.strict",type:"boolean",editor:"toggle",description:`Strict mode (only meaningful in enforce mode). Default false. When true the verify-gate refuses N/A verdicts \u2014 both a global status "not_applicable" and per-platform not_applicable_cycles exemptions \u2014 so the agent must produce real verification tool evidence for every active cycle. Default (false) accepts N/A: the agent can declare a change has no runtime surface (globally or per-cycle) and the gate allows it, recorded + observable. Inert in assist/monitor (no gate runs). The gate reads it live; the rerender it shares with the rest of the verification block is idempotent (the N/A guidance is mode-agnostic, so the installed artifacts don't change).`,def:"false",artifactAffecting:!0},{path:"verification.model",type:"json",editor:"json",description:`Model the delegated verifier sub-agent uses. Unset \u2192 the verifier inherits the session model (Claude verifier omits model: \u2192 inherit; Codex verifier omits agent-toml model \u2192 inherits config.toml's model). Set to PIN a specific model \u2014 e.g. verify on a cheaper/faster model than the main agent, or guarantee a model on Codex when config.toml has none. Two shapes: a string (applies to all clients, e.g. "sonnet" / "gpt-5.5") or a per-client object { claude: "sonnet", codex: "gpt-5.5" } when a project has both clients. Cursor has no verifier sub-agent \u2192 no-op there. Never resolves to a literal "inherit" on Codex (a 400). Artifact-affecting.`,def:"unset (inherit the session model)",artifactAffecting:!0},{path:"verificationContext.enable",type:"boolean",editor:"toggle",description:"Master switch for path-scoped verification context. When a cycle begins, the first devtools tool call injects the .ironbee/VERIFICATION.md files on/above the changed paths (author-written area guidance) into the agent's context via the host's additionalContext channel. Advisory only (does not gate). Inverse semantics \u2014 default-on, opt out with false. Not artifact-affecting (read live).",def:"true",artifactAffecting:!1},{path:"verificationContext.source",type:"string",editor:"enum",enumValues:["git","actions"],description:`Changed-path source. "git" (default) = working tree + last N commits, with an actions.jsonl fallback when not a git repo. "actions" = IronBee's own file_change events only (no git subprocess).`,def:"git",artifactAffecting:!1},{path:"verificationContext.commitDepth",type:"number",editor:"number",description:'Number of recent commits included on the git source (uncommitted \u222A last N commits). 0 = uncommitted only. Ignored when source is "actions".',def:"1",artifactAffecting:!1},{path:"verificationContext.maxBytes",type:"number",editor:"number",description:"Aggregate byte cap on the injected context string. When exceeded, the least-specific (root-side) docs are dropped first (leaf-first truncation priority).",def:"65536 (64 KB)",artifactAffecting:!1},{path:"browser.enable",type:"boolean",editor:"toggle",description:"Explicit on/off for the browser cycle. Written false by `browser disable`, stripped by `browser enable`. When false the cycle is disabled regardless of patterns.",def:"(absent \u2192 on; browser is the only default-on cycle)",artifactAffecting:!0},{path:"browser.verifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns for files requiring browser verification. Four-state: absent \u2192 code defaults (40+ extensions); [] \u2192 hard kill; non-empty \u2192 custom patterns (replaces defaults).",def:"40+ code extensions when unset; [] hard-disables",artifactAffecting:!0},{path:"browser.additionalVerifyPatterns",type:"string-array",editor:"string-list",description:"Extra patterns appended to browser.verifyPatterns (or to code defaults when verifyPatterns is unset). Ignored when verifyPatterns is [] (hard kill wins).",def:"[]",artifactAffecting:!0},{path:"browser.alwaysRequired",type:"string-array",editor:"string-list",description:"Browser-cycle required tools (all-of). The verify-gate blocks completion until every listed bdt_* tool was used.",def:"bdt_navigation_go-to, bdt_content_take-screenshot, bdt_a11y_take-aria-snapshot, bdt_o11y_get-console-messages",artifactAffecting:!0},{path:"browser.evidencePaths",type:"json",editor:"json",description:"Alternative tool-satisfaction paths (any-of). Browser uses pure all-of, so default is empty. Each path: { name, allOf: (string | { anyOf: string[] })[] }.",def:"[]",artifactAffecting:!0},{path:"node.enable",type:"boolean",editor:"toggle",description:"Explicit on/off for the Node.js runtime debug cycle (node-devtools, ndt_* V8 inspector probes). Opt-in \u2014 written by `node enable`.",def:"(absent \u2192 off; node is opt-in)",artifactAffecting:!0},{path:"node.verifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns for the Node.js runtime debug cycle. Default-off \u2014 block absent = inert. Block present + unset \u2192 9 code defaults (server/api/routes paths).",def:"block absent \u2192 disabled; present + unset \u2192 code defaults",artifactAffecting:!0},{path:"node.additionalVerifyPatterns",type:"string-array",editor:"string-list",description:"Extra patterns appended to node.verifyPatterns (or to code defaults when unset). Ignored when verifyPatterns is [].",def:"[]",artifactAffecting:!0},{path:"node.alwaysRequired",type:"string-array",editor:"string-list",description:"Node-cycle required tools (all-of). ndt_debug_connect always; evidence paths supply the rest.",def:"[ndt_debug_connect]",artifactAffecting:!0},{path:"node.evidencePaths",type:"json",editor:"json",description:"Alternative tool paths (any-of). Default: probe path (a put-*point AND get-probe-snapshots) OR log path (get-logs).",def:"probe path + log path",artifactAffecting:!0},{path:"backend.enable",type:"boolean",editor:"toggle",description:"Explicit on/off for the runtime-agnostic backend protocol cycle (backend-devtools, bedt_* HTTP/gRPC/GraphQL/WebSocket). Opt-in \u2014 written by `backend enable`.",def:"(absent \u2192 off; backend is opt-in)",artifactAffecting:!0},{path:"backend.verifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns for the backend protocol cycle. Default-off \u2014 block absent = inert. Block present + unset \u2192 13 multi-language code defaults (ts/js/py/go/java/rb/cs/rs/kt/scala/ex/php/clj).",def:"block absent \u2192 disabled; present + unset \u2192 code defaults",artifactAffecting:!0},{path:"backend.additionalVerifyPatterns",type:"string-array",editor:"string-list",description:"Extra patterns appended to backend.verifyPatterns (or to code defaults when unset). Ignored when verifyPatterns is [].",def:"[]",artifactAffecting:!0},{path:"backend.alwaysRequired",type:"string-array",editor:"string-list",description:"Backend-cycle required tools (all-of). Empty by default \u2014 backend uses any-of evidence paths instead.",def:"[]",artifactAffecting:!0},{path:"backend.evidencePaths",type:"json",editor:"json",description:"Alternative tool paths (any-of). Default three: protocol-call (any request tool) OR log-evidence (register-source + read) OR db-evidence (db_connect + a read op).",def:"protocol-call OR log-evidence OR db-evidence",artifactAffecting:!0},{path:"android.enable",type:"boolean",editor:"toggle",description:"Explicit on/off for the Android mobile verification cycle (android-devtools, adt_* device/emulator interaction). Opt-in \u2014 written by `android enable`.",def:"(absent \u2192 off; android is opt-in)",artifactAffecting:!0},{path:"android.verifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns for the Android mobile verification cycle. Default-off \u2014 block absent = inert. Block present + unset \u2192 code defaults (Android/React Native paths).",def:"block absent \u2192 disabled; present + unset \u2192 code defaults",artifactAffecting:!0},{path:"android.additionalVerifyPatterns",type:"string-array",editor:"string-list",description:"Extra patterns appended to android.verifyPatterns (or to code defaults when unset). Ignored when verifyPatterns is [].",def:"[]",artifactAffecting:!0},{path:"android.alwaysRequired",type:"string-array",editor:"string-list",description:"Android-cycle required tools (all-of). adt_device_connect always; evidence paths supply the rest.",def:"[adt_device_connect]",artifactAffecting:!0},{path:"android.evidencePaths",type:"json",editor:"json",description:"Alternative tool paths (any-of). Default two: device-evidence (UI interaction + screenshot + UI snapshot) OR log-evidence (Logcat read/follow).",def:"device-evidence OR log-evidence",artifactAffecting:!0},{path:"collector.enable",type:"boolean",editor:"toggle",description:"Master switch for the IronBee Collector. Implicitly true when the section has url and at least one credential (oauthToken or apiKey); set false to suspend while keeping url/oauthToken/apiKey/batchSize around.",def:"implicit true when url + (oauthToken or apiKey) set",artifactAffecting:!0},{path:"collector.url",type:"string",editor:"text",description:"Remote collector endpoint URL (IronBee Platform). Required for the collector to be active. Events POST to {url}/v1/events.",def:"(unset \u2192 disabled)",artifactAffecting:!0},{path:"collector.oauthToken",type:"string",editor:"text",description:"Personal access token for collector auth (X-OAuth-Token header). Per-(user, account), independently revocable from the console's /access-tokens page. Minted by `ironbee login` \u2014 the primary path for interactive CLI use. Can be supplied via IRONBEE_OAUTH_TOKEN.",def:"(unset)",artifactAffecting:!0},{path:"collector.apiKey",type:"string",editor:"text",description:"Shared account API key for collector auth (X-API-Key header). Parallel first-class path alongside `oauthToken`, intended for CI / GitHub Actions / deployment tooling and other non-interactive integrations where rotating a per-engineer OAuth token is impractical. Either `oauthToken` OR `apiKey` is required for the collector to be active. Can be supplied via IRONBEE_API_KEY.",def:"(unset \u2192 disabled)",artifactAffecting:!0},{path:"collector.batchSize",type:"number",editor:"number",description:"Max events per POST from the send_event handler (the queue chunks bigger snapshots into N-sized POSTs).",def:"100",artifactAffecting:!0},{path:"collector.timeoutMs",type:"number",editor:"number",description:"Per-request HTTP timeout (ms) for batched analytics sends. Single-event interactive sends keep a fixed 3000ms cap. Clamped to [1000, 60000].",def:"10000",artifactAffecting:!0},{path:"recording.enable",type:"boolean",editor:"toggle",description:"Recording enforcement for the browser + android cycles. Presence opts in; enable:false opts out. Auto-enabled when a collector is configured. Node/backend cycles never trigger recording.",def:"implicit true when section present or collector configured",artifactAffecting:!1},{path:"jobQueue.enable",type:"boolean",editor:"toggle",description:"Master switch for the file-backed job queue. Presence opts in; enable:false opts out. Auto-enabled when a collector is configured (a collector is pointless without a queue feeding it).",def:"implicit true when section present or collector configured",artifactAffecting:!1},{path:"jobQueue.autoFlushSizeBytes",type:"number",editor:"number",description:"Size threshold (bytes) above which submit() spawns a detached worker mid-session. 0 / negative disables this check.",def:"32768 (32 KB)",artifactAffecting:!1},{path:"jobQueue.autoFlushIntervalSeconds",type:"number",editor:"number",description:"Interval threshold (seconds since the live jobs.jsonl was created) above which submit() spawns a detached worker. Complements size \u2014 whichever crosses first flushes. 0 / negative disables.",def:"60",artifactAffecting:!1},{path:"analytics.enable",type:"boolean",editor:"toggle",description:"Master switch for per-session structural analytics. Presence opts in; enable:false opts out. Auto-enabled when a collector is configured.",def:"implicit true when section present or collector configured",artifactAffecting:!1},{path:"analytics.emitOnStop",type:"boolean",editor:"toggle",description:"When true, project + emit analytics at every Stop hook. When false, only at SessionEnd.",def:"true",artifactAffecting:!1},{path:"analytics.emitOnStopMinIntervalSeconds",type:"number",editor:"number",description:"Throttle: skip Stop-hook projection if the last successful emit was within this many seconds. 0 disables the throttle (backend handles rate-limit / dedupe).",def:"0 (disabled)",artifactAffecting:!1},{path:"analytics.emitTurnEvents",type:"boolean",editor:"toggle",description:"Opt-in for per-turn session_turn_analytics wire records. High-volume secondary signal; the base session_analytics record always ships regardless.",def:"false",artifactAffecting:!1},{path:"analytics.emitStepEvents",type:"boolean",editor:"toggle",description:"Opt-in for per-step session_turn_step_analytics wire records (an order of magnitude higher volume than turn events). Independent of emitTurnEvents.",def:"false",artifactAffecting:!1},{path:"analytics.emitApiRequestEvents",type:"boolean",editor:"toggle",description:"Opt-OUT for per-API-request api_request wire records (one per assistant message, success + failure). Primary value for backend cost accounting, so ships by default.",def:"true",artifactAffecting:!1},{path:"statusLine.enable",type:"boolean",editor:"toggle",description:"Master switch for the Claude statusline integration (session_status event + statusline wrapper). Presence opts in; auto-enabled when a collector is configured. Claude-only.",def:"implicit true when section present or collector configured",artifactAffecting:!0},{path:"statusLine.renderDefault",type:"boolean",editor:"toggle",description:"When there is no upstream statusline to chain to, false keeps the statusline silent; true renders a minimal model + context-% line. No effect when the user already has a statusline.",def:"false",artifactAffecting:!0},{path:"statusLine.emitMinIntervalSeconds",type:"number",editor:"number",description:"Minimum seconds between two emitted session_status events, on top of skip-if-unchanged. Rapid changes coalesce to the latest state after the interval. 0 disables the throttle. Read live each tick.",def:"10",artifactAffecting:!0},{path:"statusLine.refreshInterval",type:"number",editor:"number",description:"Claude Code's own statusLine.refreshInterval (seconds, host min 1) \u2014 re-runs the statusline on a timer in addition to event-driven updates. Unset by default. Values < 1 treated as unset.",def:"unset",artifactAffecting:!0},{path:"claude.oauthAccess.enable",type:"boolean",editor:"toggle",description:"Whether IronBee may read the Claude Code OAuth token (macOS Keychain / ~/.claude/.credentials.json) and call OAuth-scoped Anthropic endpoints. Default-on (opt out with false or `ironbee claude oauth-access disable`). First consumer: the statusline rate-limit fallback \u2014 fetches /api/oauth/usage to fill rate_limits for plans the statusline JSON omits them for (team / enterprise). Claude-only; not artifact-affecting (read live).",def:"true",artifactAffecting:!1},{path:"claude.oauthAccess.usageTtlSeconds",type:"number",editor:"number",description:"TTL (seconds) for the statusline OAuth rate-limit fetch cache \u2014 the /api/oauth/usage call + credential read fire at most once per this interval even when the statusline ticks far more often. Default 60; 0 means every tick.",def:"60",artifactAffecting:!1},{path:"claude.autoModeAllowlist.enable",type:"boolean",editor:"toggle",description:"Whether IronBee writes the auto-mode allowlist carve-out for the verifier into .claude/settings.local.json. Claude Code 2.1.176+ ships a host-side sub-agent \"Content Integrity\" classifier (auto mode) that false-positives on IronBee's legitimate `ironbee hook submit-verdict` verdicts (the devtools calls happened earlier in the cycle, not re-shown in the handoff). When enabled (default), install adds a narrow, command-keyed autoMode.allow rule that exempts ONLY that command from the Content Integrity block ($defaults preserved \u2014 every other block rule still applies; IronBee's Stop-gate independently enforces real tool usage). Written only when verification is active (enforce/assist); inert when the host isn't in auto mode. Opt out with false \u2014 takes effect on the next `ironbee install`. Claude-only.",def:"true",artifactAffecting:!1},{path:"telemetry.enable",type:"boolean",editor:"toggle",description:"Master switch for anonymous PostHog telemetry (CLI's own product analytics). Inverse semantics \u2014 opt out with false. Disabling also injects TELEMETRY_ENABLE=false into devtools MCP env. Orthogonal to the collector pipeline.",def:"true",artifactAffecting:!0},{path:"privacy.enable",type:"boolean",editor:"toggle",description:"Privacy mode \u2014 a single cross-cutting switch (all platforms) that redacts potentially sensitive data from what the @ironbee-ai/devtools MCP servers ship to the collector. Opt-in, default OFF. When true, injects COLLECTOR_EVENTS_TOOL_DETAILS_ENABLE=false (tool input/output detail) + COLLECTOR_ARTIFACTS_ENABLE=false (screenshots, recordings) into every devtools MCP env. Devtools-side only \u2014 the CLI's own send_event pipeline already whitelists tool_input and strips tool_response. Orthogonal to telemetry (PostHog) and collector (the sink).",def:"false",artifactAffecting:!0},{path:"otel.enable",type:"boolean",editor:"toggle",description:"Master switch for the local OTEL collector pipeline (Claude Code OTLP raw-API-body export \u2192 local daemon \u2192 session_context context-usage events). Presence opts in; enable:false opts out; auto-enabled when a collector is configured. session_context derivation is the sole consumer, so this also gates whether the settings.json OTEL env block (incl. raw-bodies) is written. Orthogonal to telemetry (PostHog) and collector (event sink).",def:"implicit true when collector configured",artifactAffecting:!0},{path:"otel.port",type:"number",editor:"number",description:"Loopback port the shared OTEL collector daemon binds to, and which the settings.json OTEL endpoint env var points at. One daemon per machine across all sessions.",def:"15986",artifactAffecting:!0},{path:"otel.idleTimeoutSeconds",type:"number",editor:"number",description:"The daemon self-reaps (graceful shutdown) after this many seconds with no /health hit and no OTLP event. Restarted on the next session/turn ensure.",def:"600",artifactAffecting:!0},{path:"otel.ensureMinIntervalSeconds",type:"number",editor:"number",description:"Throttle (seconds) for the high-frequency liveness `ensure` from per-tool hooks, so we don't pay a /health check on every tool call. session-start / activity-start ensure are unthrottled.",def:"30",artifactAffecting:!0},{path:"otel.emitMinIntervalSeconds",type:"number",editor:"number",description:"Per-session session_context emit throttle: admit at most one event per session per interval (leading-edge \u2014 the first request in each window is emitted, in-between requests are coalesced away and their body files dropped). Applies to the live path only; the catch-up/reprocess path is never throttled. 0 = emit on every API request (full context-growth time series).",def:"0",artifactAffecting:!0},{path:"fileChange.captureChangeset",type:"boolean",editor:"toggle",description:"When true, every file_change event carries a hunks-only unified-diff changeset string. Off by default \u2014 the default wire shape stays metadata-only (operation + line counts).",def:"false",artifactAffecting:!1},{path:"fileChange.maxChangesetBytes",type:"number",editor:"number",description:"Hard cap on the changeset string size. Diffs over the cap are truncated with a footer so the collector POST stays within typical reverse-proxy body limits.",def:"65536 (64 KB)",artifactAffecting:!1},{path:"import.concurrency",type:"number",editor:"number",description:"Default number of sessions `ironbee import` processes in parallel. Resolution: --concurrency flag > this value > built-in default. Clamped to [1, 32].",def:"4",artifactAffecting:!1},{path:"browserDevTools.env",type:"json",editor:"json",description:"Env-var overrides merged into the browser-devtools MCP server entry. Operators can override individual OTEL keys; IronBee invariants (TOOL_NAME_PREFIX, \u2026) always win last.",def:"unset (defaults + auto-OTEL when collector configured)",artifactAffecting:!0},{path:"browserDevTools.mcp",type:"json",editor:"json",description:"Full-replacement MCP config for the browser-devtools server entry. Auto-OTEL + telemetry env are still injected; IronBee env wins last.",def:"unset (use default npx -y @ironbee-ai/devtools entry)",artifactAffecting:!0},{path:"nodeDevTools.env",type:"json",editor:"json",description:"Env-var overrides merged into the node-devtools MCP server entry. Same auto-OTEL injection as browserDevTools minus the browser-only vars.",def:"unset (defaults + auto-OTEL when collector configured)",artifactAffecting:!0},{path:"nodeDevTools.mcp",type:"json",editor:"json",description:"Full-replacement MCP config for the node-devtools server entry. IronBee env wins last.",def:"unset (use default npx -y @ironbee-ai/devtools entry)",artifactAffecting:!0},{path:"backendDevTools.env",type:"json",editor:"json",description:"Env-var overrides merged into the backend-devtools MCP server entry. Same auto-OTEL injection as nodeDevTools.",def:"unset (defaults + auto-OTEL when collector configured)",artifactAffecting:!0},{path:"backendDevTools.mcp",type:"json",editor:"json",description:"Full-replacement MCP config for the backend-devtools server entry. IronBee env wins last.",def:"unset (use default npx -y @ironbee-ai/devtools entry)",artifactAffecting:!0},{path:"androidDevTools.env",type:"json",editor:"json",description:"Env-var overrides merged into the android-devtools MCP server entry. Same auto-OTEL injection as nodeDevTools.",def:"unset (defaults + auto-OTEL when collector configured)",artifactAffecting:!0},{path:"androidDevTools.mcp",type:"json",editor:"json",description:"Full-replacement MCP config for the android-devtools server entry. IronBee env wins last.",def:"unset (use default npx -y @ironbee-ai/devtools entry)",artifactAffecting:!0}];function A(e){return d.find(t=>t.path===e)}n(A,"findSchemaEntry");function k(){return[...d].sort((e,t)=>{const o=l(c(e.path)),i=l(c(t.path));return o!==i?o-i:e.path.localeCompare(t.path)})}n(k,"orderedEntries");0&&(module.exports={ARTIFACT_AFFECTING_TOP_KEYS,CONFIG_SCHEMA,GROUP_ORDER,GROUP_TITLES,findSchemaEntry,groupOf,groupRank,groupTitle,orderedEntries,topKey});
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var A=Object.create;var c=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var T=Object.getPrototypeOf,j=Object.prototype.hasOwnProperty;var l=(e,
|
|
2
|
-
`)}l(w,"buildDetail");function p(){
|
|
3
|
-
`))}return l(D,"verifySession"),g.key(["up","k"],()=>m(-1)),g.key(["down","j"],()=>m(1)),g.key(["v"],()=>D()),g.key(["r"],()=>{
|
|
1
|
+
"use strict";var A=Object.create;var c=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var T=Object.getPrototypeOf,j=Object.prototype.hasOwnProperty;var l=(e,n)=>c(e,"name",{value:n,configurable:!0});var I=(e,n)=>{for(var i in n)c(e,i,{get:n[i],enumerable:!0})},S=(e,n,i,f)=>{if(n&&typeof n=="object"||typeof n=="function")for(let g of V(n))!j.call(e,g)&&g!==i&&c(e,g,{get:()=>n[g],enumerable:!(f=C(n,g))||f.enumerable});return e};var E=(e,n,i)=>(i=e!=null?A(T(e)):{},S(n||!e||!e.__esModule?c(i,"default",{value:e,enumerable:!0}):i,e)),x=e=>S(c({},"__esModule",{value:!0}),e);var B={};I(B,{sessionsArea:()=>_});module.exports=x(B);var b=E(require("blessed")),o=require("../shell/util"),u=require("./read");const L=" {bold}\u2191/\u2193{/bold} move {bold}v{/bold} verify {bold}r{/bold} refresh {bold}Esc{/bold} back {bold}q{/bold} quit";function v(e){return e==="pass"?"{green-fg}pass{/green-fg}":e==="fail"?"{red-fg}fail{/red-fg}":e==="fail_reported"?"{red-fg}fail (reported){/red-fg}":e==="not_applicable"?"{cyan-fg}n/a{/cyan-fg}":`{gray-fg}${(0,o.escapeTags)(e??"\u2014")}{/gray-fg}`}l(v,"verdictColor");function O(e){const n=e.session.projectDir;let i=(0,u.listSessions)(n),f=0;const g=b.list({parent:e.container,top:0,left:0,width:"55%",height:"100%",border:{type:"line"},label:" Sessions ",tags:!0,keys:!1,mouse:!1,scrollbar:{ch:" "},style:{selected:{bg:"blue",fg:"white"},border:{fg:"cyan"}},items:[]}),y=b.box({parent:e.container,top:0,left:"55%",width:"45%",height:"100%",border:{type:"line"},label:" Detail ",tags:!0,scrollable:!0,alwaysScroll:!0,scrollbar:{ch:" "},style:{border:{fg:"cyan"}},content:""});function $(r){const s=r.active===!0?"{green-fg}\u25CF{/green-fg}":"{gray-fg}\u25CB{/gray-fg}",t=r.id.length>18?r.id.slice(0,17)+"\u2026":r.id.padEnd(18," ");return`${s} ${(0,o.escapeTags)(t)} ${v(r.verdictStatus)}`}l($,"rowLabel");function h(r,s,t,a){if(t.length!==0){r.push(`{bold}${s}{/bold}`);for(const d of t)r.push(` {${a}-fg}\u2022{/${a}-fg} ${(0,o.escapeTags)(d)}`);r.push("")}}l(h,"pushList");function w(r){if(r===void 0)return"{gray-fg}No sessions for this project yet.{/gray-fg}";const s=(0,u.readSessionDetail)(n,r.id),t=[];t.push(`{bold}${(0,o.escapeTags)(r.id)}{/bold}`),t.push("{gray-fg}"+"\u2500".repeat(40)+"{/gray-fg}"),t.push(`{gray-fg}phase:{/gray-fg} ${(0,o.escapeTags)(r.phase??"\u2014")}`),t.push(`{gray-fg}verdict:{/gray-fg} ${v(r.verdictStatus)}`),t.push(`{gray-fg}active:{/gray-fg} ${r.active===void 0?"\u2014":String(r.active)}`),t.push(`{gray-fg}retries:{/gray-fg} ${r.retries===void 0?"\u2014":String(r.retries)}`);const a=s.firstTs!==void 0&&s.lastTs!==void 0?`${(0,o.escapeTags)(new Date(s.firstTs).toISOString())} \u2192 ${(0,o.escapeTags)(new Date(s.lastTs).toISOString())}`:r.mtimeMs>0?(0,o.escapeTags)(new Date(r.mtimeMs).toISOString()):"\u2014";t.push(`{gray-fg}span:{/gray-fg} ${a}`),t.push(""),t.push("{bold}events{/bold}");const d=s.counts;return t.push(` {gray-fg}activities{/gray-fg} ${d.activities} {gray-fg}verifications{/gray-fg} ${d.verifications} {gray-fg}verdicts{/gray-fg} ${d.verdicts}`),t.push(` {gray-fg}file_changes{/gray-fg} ${d.fileChanges} {gray-fg}tool_calls{/gray-fg} ${d.toolCalls}`),t.push(""),s.verdict!==void 0?(t.push(`{bold}last verdict{/bold} ${v(s.verdict.status)}`),h(t,"checks",s.verdict.checks,"green"),h(t,"issues",s.verdict.issues,"red"),h(t,"fixes",s.verdict.fixes,"yellow")):t.push("{gray-fg}no verdict on file{/gray-fg}"),t.join(`
|
|
2
|
+
`)}l(w,"buildDetail");function p(){i.length===0?g.setItems(["{gray-fg}(no sessions){/gray-fg}"]):(g.setItems(i.map(s=>$(s))),g.select((0,o.clamp)(f,0,i.length-1)));const r=i.length===0?void 0:i[(0,o.clamp)(f,0,i.length-1)];y.setContent(w(r)),y.setScroll(0),e.screen.render()}l(p,"render");function m(r){i.length!==0&&(f=(0,o.clamp)(f+r,0,i.length-1),p())}l(m,"move");function k(){return i.length===0?void 0:i[(0,o.clamp)(f,0,i.length-1)]}l(k,"current");function D(){const r=k();if(r===void 0)return;const s=(0,u.readSessionDetail)(n,r.id),t=(0,u.validateVerdict)(s.verdict,r.retries),a=[];if(!t.hasVerdict)a.push("{gray-fg}No verdict on file \u2014 nothing to validate.{/gray-fg}"),a.push("{gray-fg}(an enabled session writes verdict.json via submit-verdict; a monitoring-only session never does){/gray-fg}");else{for(const d of t.checks)a.push(d.ok?`{green-fg}\u2713{/green-fg} ${(0,o.escapeTags)(d.label)}`:`{red-fg}\u2717{/red-fg} ${(0,o.escapeTags)(d.label)} {gray-fg}\u2014 ${(0,o.escapeTags)(d.reason??"")}{/gray-fg}`);t.retries!==void 0&&t.retries>0&&a.push("",`{gray-fg}retries:{/gray-fg} {yellow-fg}${t.retries}{/yellow-fg}`),a.push(""),a.push(t.wouldAllow?"{green-fg}\u2713 PASS{/green-fg} \u2014 the Stop hook would allow completion.":"{red-fg}\u2717 BLOCKED{/red-fg} \u2014 the Stop hook would not allow completion.")}e.session.showPane(`Verify (dry-run) \u2014 ${r.id}`,a.join(`
|
|
3
|
+
`))}return l(D,"verifySession"),g.key(["up","k"],()=>m(-1)),g.key(["down","j"],()=>m(1)),g.key(["v"],()=>D()),g.key(["r"],()=>{i=(0,u.listSessions)(n),f=(0,o.clamp)(f,0,Math.max(0,i.length-1)),p()}),e.setStatus(L),p(),g.focus(),e.screen.render(),{unmount(){g.destroy(),y.destroy()}}}l(O,"mountSessionsView");const _={id:"sessions",title:"Sessions",summary:"Browse sessions + verify (dry-run verdict validation)",mount(e){return O(e)}};0&&(module.exports={sessionsArea});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var k=Object.defineProperty;var V=Object.getOwnPropertyDescriptor;var
|
|
2
|
-
`)){if(
|
|
1
|
+
"use strict";var k=Object.defineProperty;var V=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var C=Object.prototype.hasOwnProperty;var c=(e,s)=>k(e,"name",{value:s,configurable:!0});var x=(e,s)=>{for(var n in s)k(e,n,{get:s[n],enumerable:!0})},_=(e,s,n,t)=>{if(s&&typeof s=="object"||typeof s=="function")for(let i of A(s))!C.call(e,i)&&i!==n&&k(e,i,{get:()=>s[i],enumerable:!(t=V(s,i))||t.enumerable});return e};var j=e=>_(k({},"__esModule",{value:!0}),e);var $={};x($,{listSessions:()=>D,readSessionDetail:()=>M,validateVerdict:()=>R});module.exports=j($);var a=require("fs"),l=require("path");function S(e){if((0,a.existsSync)(e))try{const s=JSON.parse((0,a.readFileSync)(e,"utf-8"));return s===null||typeof s!="object"||Array.isArray(s)?void 0:s}catch{return}}c(S,"readJson");function g(e){return typeof e=="string"?e:void 0}c(g,"asString");function D(e){const s=(0,l.join)(e,".ironbee","sessions");if(!(0,a.existsSync)(s))return[];let n;try{n=(0,a.readdirSync)(s,{withFileTypes:!0}).filter(i=>i.isDirectory()).map(i=>i.name)}catch{return[]}const t=[];for(const i of n){const r=(0,l.join)(s,i),u=(0,l.join)(r,"state.json"),f=(0,l.join)(r,"verdict.json"),o=S(u),m=S(f);let d=0;try{d=(0,a.statSync)((0,a.existsSync)(u)?u:r).mtimeMs}catch{d=0}t.push({id:i,phase:g(o?.phase),verdictStatus:g(m?.status)??g(o?.lastVerdictStatus),active:typeof o?.active=="boolean"?o.active:void 0,retries:typeof o?.retries=="number"?o.retries:void 0,mtimeMs:d})}return t.sort((i,r)=>r.mtimeMs-i.mtimeMs),t}c(D,"listSessions");function R(e,s){if(e===void 0)return{hasVerdict:!1,status:void 0,checks:[],allPassed:!1,wouldAllow:!1,retries:s};const n=[];let t=!0;const i=e.status==="not_applicable";return e.status==="pass"||e.status==="fail"||e.status==="not_applicable"?n.push({label:`status: ${e.status}`,ok:!0}):(n.push({label:"status",ok:!1,reason:`unknown "${e.status??""}" \u2014 must be "pass", "fail", or "not_applicable"`}),t=!1),i||(e.checks.length>0?n.push({label:`checks (${e.checks.length} item(s))`,ok:!0}):(n.push({label:"checks",ok:!1,reason:"missing or empty"}),t=!1)),(i||e.notApplicableCycles.length>0)&&(e.reason.length>0?n.push({label:`reason (${e.reason.length} item(s))`,ok:!0}):(n.push({label:"reason",ok:!1,reason:"required for N/A (global or per-platform)"}),t=!1)),e.notApplicableCycles.length>0&&n.push({label:`not_applicable_cycles: ${e.notApplicableCycles.join(", ")}`,ok:!0}),e.status==="fail"&&(e.issues.length>0?n.push({label:`issues (${e.issues.length} item(s))`,ok:!0}):(n.push({label:"issues",ok:!1,reason:'required when status is "fail"'}),t=!1)),{hasVerdict:!0,status:e.status,checks:n,allPassed:t,wouldAllow:t&&(e.status==="pass"||e.status==="not_applicable"),retries:s}}c(R,"validateVerdict");function h(e){return Array.isArray(e)?e.filter(s=>typeof s=="string"):[]}c(h,"asStringArray");function M(e,s){const n=(0,l.join)(e,".ironbee","sessions",s),t=S((0,l.join)(n,"verdict.json")),i=t===void 0?void 0:{status:g(t.status),checks:h(t.checks),issues:h(t.issues),fixes:h(t.fixes),reason:h(t.reason),notApplicableCycles:h(t.not_applicable_cycles)},r={activities:0,verifications:0,fileChanges:0,toolCalls:0,verdicts:0};let u,f;const o=(0,l.join)(n,"actions.jsonl");if((0,a.existsSync)(o)){let m="";try{m=(0,a.readFileSync)(o,"utf-8")}catch{m=""}for(const d of m.split(`
|
|
2
|
+
`)){if(d.trim().length===0)continue;let w;try{const y=JSON.parse(d);if(y===null||typeof y!="object"||Array.isArray(y))continue;w=y}catch{continue}const b=g(w.type);b==="activity_start"?r.activities+=1:b==="verification_start"?r.verifications+=1:b==="file_change"?r.fileChanges+=1:b==="tool_call"?r.toolCalls+=1:b==="verdict_write"&&(r.verdicts+=1);const p=w.timestamp;typeof p=="number"&&Number.isFinite(p)&&(u=u===void 0?p:Math.min(u,p),f=f===void 0?p:Math.max(f,p))}}return{id:s,verdict:i,counts:r,firstTs:u,lastTs:f}}c(M,"readSessionDetail");0&&(module.exports={listSessions,readSessionDetail,validateVerdict});
|