@ironbee-ai/cli 0.27.0 → 0.28.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/rules/ironbee-verification.md +1 -1
- package/dist/clients/codex/cli.js +1 -1
- package/dist/clients/codex/commands/ironbee-verify/SKILL.main.md +114 -0
- package/dist/clients/codex/index.js +2 -2
- package/dist/clients/codex/rules/ironbee-verification.main.md +39 -0
- package/dist/clients/codex/rules/ironbee-verification.md +1 -1
- package/dist/clients/codex/skills/ironbee-verification.main.md +110 -0
- package/dist/clients/codex/verifier.js +2 -0
- package/dist/commands/config.js +1 -1
- package/dist/commands/install.js +1 -1
- package/dist/commands/mode-select.js +2 -2
- package/dist/commands/verification-toggle.js +1 -1
- package/dist/hooks/core/activity-end.js +1 -1
- package/dist/hooks/core/submit-verdict.js +3 -3
- package/dist/hooks/core/verification-lifecycle.js +1 -1
- package/dist/lib/config.js +1 -1
- package/dist/lib/install-version.js +1 -1
- package/dist/tui/config/schema.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.28.0 (2026-06-20)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* **verification:** default to assist mode instead of enforce ([#31](https://github.com/ironbee-ai/ironbee-cli/issues/31)) ([fd284f8](https://github.com/ironbee-ai/ironbee-cli/commit/fd284f88e1feee8efde7b534a943b348fad4a95e))
|
|
8
|
+
|
|
3
9
|
## 0.27.0 (2026-06-19)
|
|
4
10
|
|
|
5
11
|
## 0.26.0 (2026-06-18)
|
|
@@ -8,7 +8,7 @@ The Stop gate blocks completion until a verdict exists for your changes — dele
|
|
|
8
8
|
|
|
9
9
|
## BANNED
|
|
10
10
|
|
|
11
|
-
- Running the verification tools (`bdt_*` / `ndt_*` / `bedt_*`) or `ironbee hook verification-start` / `submit-verdict` yourself — those are the verifier's job. Delegate.
|
|
11
|
+
- Running the verification tools (`bdt_*` / `ndt_*` / `bedt_*`) or `ironbee hook verification-start` / `submit-verdict` yourself — those are the verifier's job. Delegate. The verifier already submitted the single verdict in this shared session; you only RELAY it in text. Re-running `submit-verdict` yourself is REJECTED ("no active verification cycle" — the cycle already closed) and records nothing — a duplicate, not a verdict.
|
|
12
12
|
- Reporting a task complete without delegating verification of your changes.
|
|
13
13
|
- Submitting a verdict based on assumptions, code reading, or prior knowledge — the verifier verifies through real tools.
|
|
14
14
|
- Writing `verdict.json` directly.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var i=Object.defineProperty;var C=Object.getOwnPropertyDescriptor;var t=Object.getOwnPropertyNames;var p=Object.prototype.hasOwnProperty;var s=(m,o)=>{for(var e in o)i(m,e,{get:o[e],enumerable:!0})},x=(m,o,e,a)=>{if(o&&typeof o=="object"||typeof o=="function")for(let d of t(o))!p.call(m,d)&&d!==e&&i(m,d,{get:()=>o[d],enumerable:!(a=C(o,d))||a.enumerable});return m};var f=m=>x(i({},"__esModule",{value:!0}),m);var y={};s(y,{codexCommand:()=>l});module.exports=f(y);var n=require("commander"),r=require("./process-analytics"),c=require("./verifier");const l=new n.Command("codex").description("Codex-specific capabilities (Codex CLI only).").addCommand(c.verifierCommand).addCommand(r.codexProcessAnalyticsCommand);0&&(module.exports={codexCommand});
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ironbee-verify
|
|
3
|
+
description: >
|
|
4
|
+
Verify the current code changes by driving the IronBee verification tools yourself — runs every
|
|
5
|
+
active cycle wired up for this project (see the platform sections at the bottom). Use when the
|
|
6
|
+
user types `$ironbee-verify`. Default is verify-only (report the verdict and stop); a leading
|
|
7
|
+
`fix` argument adds the fix-and-re-verify loop until pass. Optionally pass a custom scenario
|
|
8
|
+
(inline text or a file path) that defines what to verify.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# IronBee Verify
|
|
12
|
+
|
|
13
|
+
Verify the current code changes through real tools. This project runs IronBee in **main-agent**
|
|
14
|
+
mode — the devtools tools (`mcp__browser-devtools__*` / `mcp__node-devtools__*` /
|
|
15
|
+
`mcp__backend-devtools__*` / `mcp__android-devtools__*`) are wired into THIS session, so **you**
|
|
16
|
+
drive them (there is no verifier sub-agent). The gate runs every active cycle and all must be
|
|
17
|
+
satisfied within a single verification cycle for `status: pass`. The verdict shape is
|
|
18
|
+
platform-agnostic (`status`, `checks`, `issues?`, `fixes?`); the gate enforces that you called
|
|
19
|
+
each active cycle's required tools and that `checks` is non-empty.
|
|
20
|
+
|
|
21
|
+
Your **Session ID** is injected into your context by the SessionStart hook (a `Session ID: <sid>`
|
|
22
|
+
line); author it in every `ironbee hook` command's JSON.
|
|
23
|
+
|
|
24
|
+
## Mode
|
|
25
|
+
|
|
26
|
+
The FIRST whitespace-delimited token of whatever the user provided alongside this command selects
|
|
27
|
+
the mode; everything after it is the scenario:
|
|
28
|
+
|
|
29
|
+
- `fix` → **verify-and-fix**: on a fail verdict, fix the reported issues, rebuild, and re-verify
|
|
30
|
+
until the verdict passes.
|
|
31
|
+
- `report` → **verify-only** (the explicit form of the default).
|
|
32
|
+
- Anything else, or nothing → **verify-only** (default), and the WHOLE provided text is the scenario.
|
|
33
|
+
|
|
34
|
+
**Verify-only** means: submit the (possibly fail) verdict, report the issues, and STOP — do **not**
|
|
35
|
+
edit code, do **not** re-verify. The fail verdict is still recorded (an honest status report). If
|
|
36
|
+
the user wants the issues repaired, suggest `$ironbee-verify fix`. The mode token never overrides
|
|
37
|
+
the gate: if enforcement blocks completion because of this turn's edits, follow the gate.
|
|
38
|
+
|
|
39
|
+
## Verification scenario
|
|
40
|
+
|
|
41
|
+
A custom verification scenario may be supplied — either **inline text** or a **path to a file**
|
|
42
|
+
(read at run time). The scenario is whatever the user provided alongside the command, after
|
|
43
|
+
stripping a leading `fix` / `report` mode token.
|
|
44
|
+
|
|
45
|
+
- **If a scenario is supplied, it is authoritative**: verify exactly what it describes, exercising
|
|
46
|
+
precisely the flows/states/endpoints it names — this **replaces** the default "exercise the
|
|
47
|
+
changed pages/endpoints" guidance.
|
|
48
|
+
- **If the scenario is (or points to) a file path**, read that file and treat its contents as the
|
|
49
|
+
scenario. Do not assume a fixed location or format.
|
|
50
|
+
- **If the path does not resolve**, stop and report `scenario file not found: <path>`, then ask how
|
|
51
|
+
to proceed — do not verify the literal path string.
|
|
52
|
+
- **If no scenario is supplied**, fall back to exercising the changed pages/endpoints per the active
|
|
53
|
+
platform sections below.
|
|
54
|
+
|
|
55
|
+
## Universal steps
|
|
56
|
+
|
|
57
|
+
1. **Start verification — run this ALONE first** (Codex runs shell and MCP tools in separate lanes,
|
|
58
|
+
so the open must land before any devtools call):
|
|
59
|
+
```
|
|
60
|
+
echo '{"session_id":"<your-session-id>"}' | ironbee hook verification-start
|
|
61
|
+
```
|
|
62
|
+
**In fix mode**, add the intent flag so IronBee's completion gate enforces fix-until-pass:
|
|
63
|
+
```
|
|
64
|
+
echo '{"session_id":"<your-session-id>"}' | ironbee hook verification-start --intent fix
|
|
65
|
+
```
|
|
66
|
+
2. **Build and start** the application if not already running (don't guess ports). Track what YOU started.
|
|
67
|
+
3. **For every active cycle, run its flow** — driven by the scenario above when supplied, otherwise
|
|
68
|
+
per the platform sections near the bottom of this file. All active cycles must be exercised within
|
|
69
|
+
this same verification cycle.
|
|
70
|
+
4. **Stop** only what you started (dev server / container), then honor any cycle-specific teardown
|
|
71
|
+
(e.g. recording stop) BEFORE the verdict.
|
|
72
|
+
5. **Submit your verdict** via terminal. One verdict covers every active cycle:
|
|
73
|
+
- Pass: `echo '{"session_id":"...","status":"pass","checks":["..."]}' | ironbee hook submit-verdict`
|
|
74
|
+
- Fail: `echo '{"session_id":"...","status":"fail","checks":["..."],"issues":["..."]}' | ironbee hook submit-verdict`
|
|
75
|
+
6. **If failed** → collect ALL issues first (finish every active cycle) and submit ONE fail verdict.
|
|
76
|
+
Then branch by mode:
|
|
77
|
+
- **Verify-only (default)**: report the issues and stop — do not edit code. Suggest `$ironbee-verify fix`.
|
|
78
|
+
- **Fix mode (`fix` token)**: fix everything, rebuild, and re-verify until pass. Batch fixes to
|
|
79
|
+
avoid repeated build/restart cycles.
|
|
80
|
+
7. If pass after a previous fail, include `"fixes"` in the verdict describing what was fixed.
|
|
81
|
+
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
<!--IRONBEE:PLATFORM:browser-->
|
|
85
|
+
<!--/IRONBEE:PLATFORM:browser-->
|
|
86
|
+
|
|
87
|
+
<!--IRONBEE:PLATFORM:node-->
|
|
88
|
+
<!--/IRONBEE:PLATFORM:node-->
|
|
89
|
+
|
|
90
|
+
<!--IRONBEE:PLATFORM:backend-->
|
|
91
|
+
<!--/IRONBEE:PLATFORM:backend-->
|
|
92
|
+
|
|
93
|
+
<!--IRONBEE:PLATFORM:android-->
|
|
94
|
+
<!--/IRONBEE:PLATFORM:android-->
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
## When to FAIL
|
|
99
|
+
|
|
100
|
+
If you observe ANY problem on any active cycle — wrong data, unexpected errors, broken
|
|
101
|
+
interactions, missing evidence — you MUST submit a **fail** verdict. Do NOT rationalize problems
|
|
102
|
+
away. A FALSE failure (a valid, in-scope operation that should succeed but errors) is a FAIL, not
|
|
103
|
+
"verified failure handling".
|
|
104
|
+
|
|
105
|
+
## Verdict Quality
|
|
106
|
+
|
|
107
|
+
Your `checks` array must list **specific observations**, not generic statements:
|
|
108
|
+
- GOOD: `["login form renders with email and password fields", "submitted valid credentials, redirected to /dashboard", "console clean — 0 errors"]`
|
|
109
|
+
- BAD: `["it works", "looks good", "feature implemented"]`
|
|
110
|
+
|
|
111
|
+
## Important
|
|
112
|
+
- ALWAYS submit a verdict after every verification attempt — both pass AND fail.
|
|
113
|
+
- Do NOT edit code before submitting a fail verdict.
|
|
114
|
+
- Every `apply_patch` edit clears your verdict — re-verify after edits.
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"use strict";var E=Object.defineProperty;var W=Object.getOwnPropertyDescriptor;var Y=Object.getOwnPropertyNames;var z=Object.prototype.hasOwnProperty;var h=(g,o)=>E(g,"name",{value:o,configurable:!0});var Q=(g,o)=>{for(var n in o)E(g,n,{get:o[n],enumerable:!0})},Z=(g,o,n,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let e of Y(o))!z.call(g,e)&&e!==n&&E(g,e,{get:()=>o[e],enumerable:!(r=W(o,e))||r.enumerable});return g};var j=g=>Z(E({},"__esModule",{value:!0}),g);var ro={};Q(ro,{CodexClient:()=>to});module.exports=j(ro);var i=require("fs"),a=require("path"),B=require("../../lib/gitignore"),f=require("../../lib/logger"),l=require("../../lib/output"),P=require("../../lib/fs-prune"),u=require("../../lib/config"),$=require("../../lib/platform-section"),t=require("./util"),R=require("./thread-map"),N=require("./hooks/verify-gate"),V=require("./hooks/activity-end"),O=require("./hooks/session-start"),G=require("./hooks/activity-start"),J=require("./hooks/require-verification"),L=require("./hooks/require-verdict"),F=require("./hooks/clear-verdict"),K=require("./hooks/track-action"),U=require("./hooks/track-action-monitor"),q=require("./hooks/track-action-pre"),D=require("./hooks/subagent-start"),X=require("./hooks/subagent-stop");const T="browser-devtools",w="node-devtools",A="backend-devtools",_="android-devtools",oo="ironbee",k="ironbee-verifier",eo=30,I="Verifies recent code changes through real browser/runtime/backend tools and submits the IronBee verdict. Spawn this custom agent (by agent_type) after editing code to run the verification cycle out-of-band \u2014 it drives the devtools tools, judges the result, and records the verdict in the shared session. It does NOT edit code.";function H(g){return(0,a.join)(__dirname,"..",g,"platforms")}h(H,"platformsDirFor");function b(g){return l.pc.dim(g)}h(b,"codexColor");function M(g){return g.hooks.some(o=>o.command.includes(oo))}h(M,"isIronBeeHookGroup");function no(g){const o=Object.keys(g);return o.length===0?!0:o.length===1&&o[0]==="hooks"?Object.keys(g.hooks??{}).length===0:!1}h(no,"isCodexHooksEmpty");class to{constructor(){this.name="codex";this.supportsVerifierModel=!0}static{h(this,"CodexClient")}detect(o){return(0,i.existsSync)((0,a.join)(o,".agents","skills","ironbee-verify"))}resolveProjectDir(){return process.env.CODEX_PROJECT_DIR??process.env.IRONBEE_PROJECT_DIR??process.cwd()}install(o,n){const r=n??(0,u.loadConfig)(o),e=(0,u.getVerificationMode)(r),s=e!=="monitor";this.cleanupArtifacts(o);const c=(0,t.codexHooksJsonPath)(o);this.mergeHooksConfig(c,e),this.mergeConfigToml(o,r,s),s&&(e==="enforce"&&this.writeAgentsMdBlock(o,r),this.writeSkills(o,e==="enforce"),(0,$.syncPlatformSectionsToConfig)(o,H)),(0,B.ensureIronBeeGitignored)(o),console.log(` ${l.pc.dim("\u2192")} ${b("[codex]")} hooks ${l.pc.dim("\u2192")} ${l.pc.dim(c)}`),console.log(` ${l.pc.dim("\u2192")} ${b("[codex]")} config ${l.pc.dim("\u2192")} ${l.pc.dim((0,t.codexConfigTomlPath)(o))}`),e==="enforce"?(console.log(` ${l.pc.dim("\u2192")} ${b("[codex]")} agents ${l.pc.dim("\u2192")} ${l.pc.dim((0,a.join)(o,"AGENTS.md"))}`),console.log(` ${l.pc.dim("\u2192")} ${b("[codex]")} skill ${l.pc.dim("\u2192")} ${l.pc.dim((0,a.join)(o,".agents","skills","ironbee-verification","SKILL.md"))}`),console.log(` ${l.pc.dim("\u2192")} ${b("[codex]")} command ${l.pc.dim("\u2192")} ${l.pc.dim((0,a.join)(o,".agents","skills","ironbee-verify","SKILL.md"))}`)):e==="assist"?(console.log(` ${l.pc.dim("\u2192")} ${b("[codex]")} ${l.pc.yellow("assist mode")} (verification.auto: false) \u2014 manual $ironbee-verify only, no enforcement`),console.log(` ${l.pc.dim("\u2192")} ${b("[codex]")} command ${l.pc.dim("\u2192")} ${l.pc.dim((0,a.join)(o,".agents","skills","ironbee-verify","SKILL.md"))}`)):console.log(` ${l.pc.dim("\u2192")} ${b("[codex]")} ${l.pc.yellow("monitoring-only mode")} (verification.enable: false)`),console.log(),console.log(` ${l.pc.yellow("\u26A0")} ${l.pc.yellow("Codex requires one-time TUI setup:")}`),console.log(` ${l.pc.yellow("1.")} Run ${l.pc.bold("/hooks")} in a fresh Codex session to review and trust IronBee hooks`),console.log(` ${l.pc.yellow("2.")} Restart any open Codex sessions to pick up new hook config`)}uninstall(o){this.cleanupArtifacts(o),(0,P.pruneEmptyDirs)((0,a.join)(o,".codex"));const n=(0,R.codexThreadMapPath)(o);if((0,i.existsSync)(n))try{(0,i.unlinkSync)(n)}catch(r){f.logger.debug(`failed to remove codex thread map: ${r}`)}console.log(` ${l.pc.dim("\u2192")} ${b("[codex]")} removed hooks, MCP entries, AGENTS.md block, and skills`)}cleanupArtifacts(o){this.migrateAwayFromUserLevel();const n=(0,t.codexHooksJsonPath)(o);this.removeIronBeeHooks(n),this.maybeDeleteEmptyHooks(n),this.removeIronBeeMcpServers(o),this.removeVerifierAgentToml(o);const r=(0,a.join)(o,"AGENTS.md");if((0,i.existsSync)(r))try{const s=(0,i.readFileSync)(r,"utf-8"),c=(0,t.stripAgentsMdBlock)(s);c===null?(0,i.unlinkSync)(r):c!==s&&(0,i.writeFileSync)(r,c)}catch(s){f.logger.debug(`failed to strip AGENTS.md block: ${s}`)}const e=(0,a.join)(o,".agents","skills");this.removeDir((0,a.join)(e,"ironbee-verification")),this.removeDir((0,a.join)(e,"ironbee-verify")),(0,P.pruneEmptyDirs)((0,a.join)(o,".agents"))}async runVerifyGate(o){await(0,N.run)(o)}async runActivityEnd(o){await(0,V.run)(o)}async runSessionStart(o){await(0,O.run)(o)}async runActivityStart(o){await(0,G.run)(o)}async runRequireVerification(o,n){await(0,J.run)(o,n)}async runRequireVerdict(o,n){await(0,L.run)(o,n)}async runClearVerdict(o){await(0,F.run)(o)}async runTrackAction(o){await(0,K.run)(o)}async runTrackActionMonitor(o){await(0,U.run)(o)}async runTrackActionPre(o){await(0,q.run)(o)}async runSubagentStart(o){await(0,D.run)(o)}async runSubagentStop(o){await(0,X.run)(o)}resolveAgentSessionId(o,n){const r=process.env.CODEX_THREAD_ID;if(typeof r=="string"&&r.length>0&&n)return(0,R.lookupThreadSession)(n,r)}async runSessionEnd(o){f.logger.debug("session-end: no-op on Codex (no SessionEnd hook event)")}mergeHooksConfig(o,n){const r=n!=="monitor",e=n==="assist"?" --soft":"";(0,i.mkdirSync)((0,a.dirname)(o),{recursive:!0});let s={hooks:{}};if((0,i.existsSync)(o))try{s=JSON.parse((0,i.readFileSync)(o,"utf-8")),s.hooks||(s.hooks={})}catch(m){f.logger.debug(`failed to parse ${o}: ${m}`),s={hooks:{}}}for(const m of Object.keys(s.hooks)){const v=s.hooks[m].filter(y=>!M(y));v.length===0?delete s.hooks[m]:s.hooks[m]=v}const c=h((m,v,y)=>{s.hooks[m]||(s.hooks[m]=[]),s.hooks[m].push({matcher:v,hooks:[{type:"command",command:y}]})},"addGroup");c("SessionStart",".*","ironbee hook session-start --client codex"),c("UserPromptSubmit",".*","ironbee hook activity-start --client codex"),c("PreToolUse",".*","ironbee hook track-action-pre --client codex"),r&&(c("PreToolUse","^mcp__(browser|node|backend|android)[-_]devtools__.*",`ironbee hook require-verification --client codex${e}`),c("PreToolUse","^apply_patch$",`ironbee hook require-verdict --client codex${e}`),c("PostToolUse","^apply_patch$","ironbee hook clear-verdict --client codex"),c("SubagentStart",".*","ironbee hook subagent-start --client codex")),c("SubagentStop",".*","ironbee hook subagent-stop --client codex"),c("PostToolUse",".*",r?"ironbee hook track-action --client codex":"ironbee hook track-action-monitor --client codex"),c("Stop",".*",n==="enforce"?"ironbee hook verify-gate --client codex":"ironbee hook activity-end --client codex"),(0,i.writeFileSync)(o,JSON.stringify(s,null,2))}removeIronBeeHooks(o){if((0,i.existsSync)(o))try{const n=(0,i.readFileSync)(o,"utf-8"),r=JSON.parse(n);if(!r.hooks)return;let e=!1;for(const s of Object.keys(r.hooks)){const c=r.hooks[s].filter(d=>!M(d));c.length!==r.hooks[s].length&&(e=!0),c.length===0?delete r.hooks[s]:r.hooks[s]=c}e&&(0,i.writeFileSync)(o,JSON.stringify(r,null,2))}catch(n){f.logger.debug(`failed to strip IronBee hooks from ${o}: ${n}`)}}maybeDeleteEmptyHooks(o){if((0,i.existsSync)(o))try{const n=JSON.parse((0,i.readFileSync)(o,"utf-8"));no(n)&&(0,i.unlinkSync)(o)}catch(n){f.logger.debug(`failed to inspect ${o} for emptiness: ${n}`)}}mergeConfigToml(o,n,r){(0,i.mkdirSync)((0,a.join)(o,".codex"),{recursive:!0});let e=(0,t.readCodexConfigToml)(o);if(e=(0,t.ensureFeaturesHooksTrue)(e),e=(0,t.removeMcpServer)(e,T),e=(0,t.removeMcpServer)(e,w),e=(0,t.removeMcpServer)(e,A),e=(0,t.removeMcpServer)(e,_),r){const s=(0,u.getVerificationModel)(n,"codex"),c=(0,i.existsSync)((0,t.userCodexConfigTomlPath)())?(0,i.readFileSync)((0,t.userCodexConfigTomlPath)(),"utf-8"):"",d=(0,t.extractTomlTopLevelModel)(e)===null&&(0,t.extractTomlTopLevelModel)(c)===null;s===void 0&&d&&console.log(` ${l.pc.dim("\u2192")} ${b("[codex]")} ${l.pc.yellow("\u26A0 no model for the verifier")} \u2014 the ${l.pc.bold("ironbee-verifier")} sub-agent inherits the session model, but neither this project's .codex/config.toml nor ~/.codex/config.toml has a top-level ${l.pc.bold("model")}, so it may fail to spawn ("could not resolve the child model"). Fix: set ${l.pc.bold("model")} in ~/.codex/config.toml, or set ${l.pc.bold("verification.model")} in your ironbee config.`),this.writeVerifierAgentToml(o,n,s),e=(0,t.upsertAgentsTable)(e,k,[`description = ${JSON.stringify(I)}`,`config_file = ${JSON.stringify(`agents/${k}.toml`)}`]),e=(0,t.ensureMultiAgentV2SpawnMetadataExposed)(e)}else e=(0,t.removeAgentsTable)(e,k),e=(0,t.removeMultiAgentV2SpawnMetadata)(e),this.removeVerifierAgentToml(o);(0,t.writeCodexConfigToml)(o,e)}writeVerifierAgentToml(o,n,r){const e=(0,a.join)(__dirname,"agents",`${k}.md`);let s;try{s=(0,i.readFileSync)(e,"utf-8")}catch(v){f.logger.debug(`failed to read verifier agent source ${e}: ${v}`);return}const c=H("codex");for(const v of u.ALL_CYCLES){const S=(0,u.isCycleEnabled)(n,v)?C=>{const x=(0,a.join)(c,(0,$.fragmentFilename)("skill",v,C));return(0,i.existsSync)(x)?(0,i.readFileSync)(x,"utf-8").trimEnd():null}:null;s=(0,$.applyPlatformSection)(s,v,S,`${k}.toml`)}const d=[];d.push(`name = ${JSON.stringify(k)}`),d.push(`description = ${JSON.stringify(I)}`),d.push('sandbox_mode = "read-only"'),r&&d.push(`model = ${JSON.stringify(r)}`),d.push("developer_instructions = '''"),d.push(s.replace(/'''/g,"```").trimEnd()),d.push("'''");const p=h((v,y,S)=>{v&&(d.push(""),d.push(`[mcp_servers.${y}]`),d.push(...io(S)),d.push(`startup_timeout_sec = ${eo}`),d.push("required = true"),d.push('default_tools_approval_mode = "approve"'))},"addCycle");p((0,u.isCycleEnabled)(n,"browser"),T,(0,u.getMcpServerEntry)(o)),p((0,u.isCycleEnabled)(n,"node"),w,(0,u.getNodeDevToolsMcpEntry)(o)),p((0,u.isCycleEnabled)(n,"backend"),A,(0,u.getBackendDevToolsMcpEntry)(o)),p((0,u.isCycleEnabled)(n,"android"),_,(0,u.getAndroidDevToolsMcpEntry)(o));const m=(0,t.codexAgentTomlPath)(o,k);(0,i.mkdirSync)((0,a.dirname)(m),{recursive:!0}),(0,i.writeFileSync)(m,d.join(`
|
|
1
|
+
"use strict";var _=Object.defineProperty;var Z=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var ee=Object.prototype.hasOwnProperty;var y=(f,e)=>_(f,"name",{value:e,configurable:!0});var oe=(f,e)=>{for(var o in e)_(f,o,{get:e[o],enumerable:!0})},ne=(f,e,o,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of j(e))!ee.call(f,i)&&i!==o&&_(f,i,{get:()=>e[i],enumerable:!(s=Z(e,i))||s.enumerable});return f};var te=f=>ne(_({},"__esModule",{value:!0}),f);var le={};oe(le,{CodexClient:()=>se});module.exports=te(le);var r=require("fs"),g=require("path"),O=require("../../lib/gitignore"),b=require("../../lib/logger"),d=require("../../lib/output"),P=require("../../lib/fs-prune"),c=require("../../lib/config"),C=require("../../lib/platform-section"),n=require("./util"),M=require("./thread-map"),L=require("./hooks/verify-gate"),G=require("./hooks/activity-end"),J=require("./hooks/session-start"),F=require("./hooks/activity-start"),K=require("./hooks/require-verification"),U=require("./hooks/require-verdict"),q=require("./hooks/clear-verdict"),D=require("./hooks/track-action"),X=require("./hooks/track-action-monitor"),W=require("./hooks/track-action-pre"),Y=require("./hooks/subagent-start"),z=require("./hooks/subagent-stop");const x="browser-devtools",E="node-devtools",w="backend-devtools",T="android-devtools",ie="ironbee",k="ironbee-verifier",H=30,V="Verifies recent code changes through real browser/runtime/backend tools and submits the IronBee verdict. Spawn this custom agent (by agent_type) after editing code to run the verification cycle out-of-band \u2014 it drives the devtools tools, judges the result, and records the verdict in the shared session. It does NOT edit code.";function A(f){return(0,g.join)(__dirname,"..",f,"platforms")}y(A,"platformsDirFor");function h(f){return d.pc.dim(f)}y(h,"codexColor");function B(f){return f.hooks.some(e=>e.command.includes(ie))}y(B,"isIronBeeHookGroup");function re(f){const e=Object.keys(f);return e.length===0?!0:e.length===1&&e[0]==="hooks"?Object.keys(f.hooks??{}).length===0:!1}y(re,"isCodexHooksEmpty");class se{constructor(){this.name="codex";this.supportsVerifierModel=!0}static{y(this,"CodexClient")}detect(e){return(0,r.existsSync)((0,g.join)(e,".agents","skills","ironbee-verify"))}resolveProjectDir(){return process.env.CODEX_PROJECT_DIR??process.env.IRONBEE_PROJECT_DIR??process.cwd()}install(e,o){const s=o??(0,c.loadConfig)(e),i=(0,c.getVerificationMode)(s),t=i!=="monitor",a=(0,c.getCodexVerifierMode)(s);this.cleanupArtifacts(e);const l=(0,n.codexHooksJsonPath)(e);if(this.mergeHooksConfig(l,i,a),this.mergeConfigToml(e,s,t,a),t&&(i==="enforce"&&this.writeAgentsMdBlock(e,s,a),this.writeSkills(e,i==="enforce",s,a),(0,C.syncPlatformSectionsToConfig)(e,A)),(0,O.ensureIronBeeGitignored)(e),console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} hooks ${d.pc.dim("\u2192")} ${d.pc.dim(l)}`),console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} config ${d.pc.dim("\u2192")} ${d.pc.dim((0,n.codexConfigTomlPath)(e))}`),t){const p=a==="main-agent"?`${d.pc.yellow("main-agent")} (the main agent drives the devtools tools directly)`:`${d.pc.bold("sub-agent")} (delegated to the ironbee-verifier custom agent)`;console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} verify ${d.pc.dim("\u2192")} ${p}`)}i==="enforce"?(console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} agents ${d.pc.dim("\u2192")} ${d.pc.dim((0,g.join)(e,"AGENTS.md"))}`),console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} skill ${d.pc.dim("\u2192")} ${d.pc.dim((0,g.join)(e,".agents","skills","ironbee-verification","SKILL.md"))}`),console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} command ${d.pc.dim("\u2192")} ${d.pc.dim((0,g.join)(e,".agents","skills","ironbee-verify","SKILL.md"))}`)):i==="assist"?(console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} ${d.pc.yellow("assist mode")} (verification.auto: false) \u2014 manual $ironbee-verify only, no enforcement`),console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} command ${d.pc.dim("\u2192")} ${d.pc.dim((0,g.join)(e,".agents","skills","ironbee-verify","SKILL.md"))}`)):console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} ${d.pc.yellow("monitoring-only mode")} (verification.enable: false)`),console.log(),console.log(` ${d.pc.yellow("\u26A0")} ${d.pc.yellow("Codex requires one-time TUI setup:")}`),console.log(` ${d.pc.yellow("1.")} Run ${d.pc.bold("/hooks")} in a fresh Codex session to review and trust IronBee hooks`),console.log(` ${d.pc.yellow("2.")} Restart any open Codex sessions to pick up new hook config`)}uninstall(e){this.cleanupArtifacts(e),(0,P.pruneEmptyDirs)((0,g.join)(e,".codex"));const o=(0,M.codexThreadMapPath)(e);if((0,r.existsSync)(o))try{(0,r.unlinkSync)(o)}catch(s){b.logger.debug(`failed to remove codex thread map: ${s}`)}console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} removed hooks, MCP entries, AGENTS.md block, and skills`)}cleanupArtifacts(e){this.migrateAwayFromUserLevel();const o=(0,n.codexHooksJsonPath)(e);this.removeIronBeeHooks(o),this.maybeDeleteEmptyHooks(o),this.removeIronBeeMcpServers(e),this.removeVerifierAgentToml(e);const s=(0,g.join)(e,"AGENTS.md");if((0,r.existsSync)(s))try{const t=(0,r.readFileSync)(s,"utf-8"),a=(0,n.stripAgentsMdBlock)(t);a===null?(0,r.unlinkSync)(s):a!==t&&(0,r.writeFileSync)(s,a)}catch(t){b.logger.debug(`failed to strip AGENTS.md block: ${t}`)}const i=(0,g.join)(e,".agents","skills");this.removeDir((0,g.join)(i,"ironbee-verification")),this.removeDir((0,g.join)(i,"ironbee-verify")),(0,P.pruneEmptyDirs)((0,g.join)(e,".agents"))}async runVerifyGate(e){await(0,L.run)(e)}async runActivityEnd(e){await(0,G.run)(e)}async runSessionStart(e){await(0,J.run)(e)}async runActivityStart(e){await(0,F.run)(e)}async runRequireVerification(e,o){await(0,K.run)(e,o)}async runRequireVerdict(e,o){await(0,U.run)(e,o)}async runClearVerdict(e){await(0,q.run)(e)}async runTrackAction(e){await(0,D.run)(e)}async runTrackActionMonitor(e){await(0,X.run)(e)}async runTrackActionPre(e){await(0,W.run)(e)}async runSubagentStart(e){await(0,Y.run)(e)}async runSubagentStop(e){await(0,z.run)(e)}resolveAgentSessionId(e,o){const s=process.env.CODEX_THREAD_ID;if(typeof s=="string"&&s.length>0&&o)return(0,M.lookupThreadSession)(o,s)}async runSessionEnd(e){b.logger.debug("session-end: no-op on Codex (no SessionEnd hook event)")}mergeHooksConfig(e,o,s){const i=o!=="monitor",t=o==="assist"?" --soft":"";(0,r.mkdirSync)((0,g.dirname)(e),{recursive:!0});let a={hooks:{}};if((0,r.existsSync)(e))try{a=JSON.parse((0,r.readFileSync)(e,"utf-8")),a.hooks||(a.hooks={})}catch(u){b.logger.debug(`failed to parse ${e}: ${u}`),a={hooks:{}}}for(const u of Object.keys(a.hooks)){const m=a.hooks[u].filter(S=>!B(S));m.length===0?delete a.hooks[u]:a.hooks[u]=m}const l=y((u,m,S)=>{a.hooks[u]||(a.hooks[u]=[]),a.hooks[u].push({matcher:m,hooks:[{type:"command",command:S}]})},"addGroup");l("SessionStart",".*","ironbee hook session-start --client codex"),l("UserPromptSubmit",".*","ironbee hook activity-start --client codex"),l("PreToolUse",".*","ironbee hook track-action-pre --client codex"),i&&(l("PreToolUse","^mcp__(browser|node|backend|android)[-_]devtools__.*",`ironbee hook require-verification --client codex${t}`),l("PreToolUse","^apply_patch$",`ironbee hook require-verdict --client codex${t}`),l("PostToolUse","^apply_patch$","ironbee hook clear-verdict --client codex"),s==="sub-agent"&&l("SubagentStart",".*","ironbee hook subagent-start --client codex")),l("SubagentStop",".*","ironbee hook subagent-stop --client codex"),l("PostToolUse",".*",i?"ironbee hook track-action --client codex":"ironbee hook track-action-monitor --client codex"),l("Stop",".*",o==="enforce"?"ironbee hook verify-gate --client codex":"ironbee hook activity-end --client codex"),(0,r.writeFileSync)(e,JSON.stringify(a,null,2))}removeIronBeeHooks(e){if((0,r.existsSync)(e))try{const o=(0,r.readFileSync)(e,"utf-8"),s=JSON.parse(o);if(!s.hooks)return;let i=!1;for(const t of Object.keys(s.hooks)){const a=s.hooks[t].filter(l=>!B(l));a.length!==s.hooks[t].length&&(i=!0),a.length===0?delete s.hooks[t]:s.hooks[t]=a}i&&(0,r.writeFileSync)(e,JSON.stringify(s,null,2))}catch(o){b.logger.debug(`failed to strip IronBee hooks from ${e}: ${o}`)}}maybeDeleteEmptyHooks(e){if((0,r.existsSync)(e))try{const o=JSON.parse((0,r.readFileSync)(e,"utf-8"));re(o)&&(0,r.unlinkSync)(e)}catch(o){b.logger.debug(`failed to inspect ${e} for emptiness: ${o}`)}}mergeConfigToml(e,o,s,i){(0,r.mkdirSync)((0,g.join)(e,".codex"),{recursive:!0});let t=(0,n.readCodexConfigToml)(e);if(t=(0,n.ensureFeaturesHooksTrue)(t),t=(0,n.removeMcpServer)(t,x),t=(0,n.removeMcpServer)(t,E),t=(0,n.removeMcpServer)(t,w),t=(0,n.removeMcpServer)(t,T),s&&i==="main-agent"){t=this.upsertSessionMcpServers(t,e,o),t=(0,n.removeAgentsTable)(t,k),t=(0,n.removeMultiAgentV2SpawnMetadata)(t),this.removeVerifierAgentToml(e),(0,n.writeCodexConfigToml)(e,t);return}if(s){const a=(0,c.getVerificationModel)(o,"codex"),l=(0,r.existsSync)((0,n.userCodexConfigTomlPath)())?(0,r.readFileSync)((0,n.userCodexConfigTomlPath)(),"utf-8"):"",p=(0,n.extractTomlTopLevelModel)(t)===null&&(0,n.extractTomlTopLevelModel)(l)===null;a===void 0&&p&&console.log(` ${d.pc.dim("\u2192")} ${h("[codex]")} ${d.pc.yellow("\u26A0 no model for the verifier")} \u2014 the ${d.pc.bold("ironbee-verifier")} sub-agent inherits the session model, but neither this project's .codex/config.toml nor ~/.codex/config.toml has a top-level ${d.pc.bold("model")}, so it may fail to spawn ("could not resolve the child model"). Fix: set ${d.pc.bold("model")} in ~/.codex/config.toml, or set ${d.pc.bold("verification.model")} in your ironbee config.`),this.writeVerifierAgentToml(e,o,a),t=(0,n.upsertAgentsTable)(t,k,[`description = ${JSON.stringify(V)}`,`config_file = ${JSON.stringify(`agents/${k}.toml`)}`]),t=(0,n.ensureMultiAgentV2SpawnMetadataExposed)(t)}else t=(0,n.removeAgentsTable)(t,k),t=(0,n.removeMultiAgentV2SpawnMetadata)(t),this.removeVerifierAgentToml(e);(0,n.writeCodexConfigToml)(e,t)}writeVerifierAgentToml(e,o,s){const i=(0,g.join)(__dirname,"agents",`${k}.md`);let t;try{t=(0,r.readFileSync)(i,"utf-8")}catch(u){b.logger.debug(`failed to read verifier agent source ${i}: ${u}`);return}const a=A("codex");for(const u of c.ALL_CYCLES){const S=(0,c.isCycleEnabled)(o,u)?I=>{const $=(0,g.join)(a,(0,C.fragmentFilename)("skill",u,I));return(0,r.existsSync)($)?(0,r.readFileSync)($,"utf-8").trimEnd():null}:null;t=(0,C.applyPlatformSection)(t,u,S,`${k}.toml`)}const l=[];l.push(`name = ${JSON.stringify(k)}`),l.push(`description = ${JSON.stringify(V)}`),l.push('sandbox_mode = "read-only"'),s&&l.push(`model = ${JSON.stringify(s)}`),l.push("developer_instructions = '''"),l.push(t.replace(/'''/g,"```").trimEnd()),l.push("'''");const p=y((u,m,S)=>{u&&(l.push(""),l.push(`[mcp_servers.${m}]`),l.push(...N(S)),l.push(`startup_timeout_sec = ${H}`),l.push("required = true"),l.push('default_tools_approval_mode = "approve"'))},"addCycle");p((0,c.isCycleEnabled)(o,"browser"),x,(0,c.getMcpServerEntry)(e)),p((0,c.isCycleEnabled)(o,"node"),E,(0,c.getNodeDevToolsMcpEntry)(e)),p((0,c.isCycleEnabled)(o,"backend"),w,(0,c.getBackendDevToolsMcpEntry)(e)),p((0,c.isCycleEnabled)(o,"android"),T,(0,c.getAndroidDevToolsMcpEntry)(e));const v=(0,n.codexAgentTomlPath)(e,k);(0,r.mkdirSync)((0,g.dirname)(v),{recursive:!0}),(0,r.writeFileSync)(v,l.join(`
|
|
2
2
|
`)+`
|
|
3
|
-
`)}
|
|
3
|
+
`)}upsertSessionMcpServers(e,o,s){let i=e;const t=y((a,l,p)=>{if(!a)return;const v=[...N(p),`startup_timeout_sec = ${H}`,'default_tools_approval_mode = "approve"'];i=(0,n.upsertMcpServer)(i,l,v)},"addCycle");return t((0,c.isCycleEnabled)(s,"browser"),x,(0,c.getMcpServerEntry)(o)),t((0,c.isCycleEnabled)(s,"node"),E,(0,c.getNodeDevToolsMcpEntry)(o)),t((0,c.isCycleEnabled)(s,"backend"),w,(0,c.getBackendDevToolsMcpEntry)(o)),t((0,c.isCycleEnabled)(s,"android"),T,(0,c.getAndroidDevToolsMcpEntry)(o)),i}removeVerifierAgentToml(e){const o=(0,n.codexAgentTomlPath)(e,k);if((0,r.existsSync)(o))try{(0,r.unlinkSync)(o)}catch(s){b.logger.debug(`failed to remove verifier agent toml: ${s}`)}}removeIronBeeMcpServers(e){let o=(0,n.readCodexConfigToml)(e);o&&(o=(0,n.removeMcpServer)(o,x),o=(0,n.removeMcpServer)(o,E),o=(0,n.removeMcpServer)(o,w),o=(0,n.removeMcpServer)(o,T),o=(0,n.removeAgentsTable)(o,k),o=(0,n.removeMultiAgentV2SpawnMetadata)(o),(0,n.writeCodexConfigToml)(e,o))}migrateAwayFromUserLevel(){const e=(0,n.userCodexHooksJsonPath)();this.removeIronBeeHooks(e),this.maybeDeleteEmptyHooks(e);const o=(0,n.userCodexConfigTomlPath)();if((0,r.existsSync)(o))try{let i=(0,r.readFileSync)(o,"utf-8");const t=i;i=(0,n.removeMcpServer)(i,x),i=(0,n.removeMcpServer)(i,E),i=(0,n.removeMcpServer)(i,w),i=(0,n.removeMcpServer)(i,T),i=(0,n.removeAgentsTable)(i,k),i=(0,n.removeMultiAgentV2SpawnMetadata)(i),i!==t&&(0,r.writeFileSync)(o,i)}catch(i){b.logger.debug(`migrate: failed to clean user-level config.toml: ${i}`)}const s=(0,n.userCodexAgentTomlPath)(k);if((0,r.existsSync)(s))try{(0,r.unlinkSync)(s)}catch(i){b.logger.debug(`migrate: failed to remove user-level verifier toml: ${i}`)}}writeAgentsMdBlock(e,o,s){const i=(0,g.join)(e,"AGENTS.md"),t=s==="main-agent"?"ironbee-verification.main.md":"ironbee-verification.md",a=(0,g.join)(__dirname,"rules",t);let l;try{l=(0,r.readFileSync)(a,"utf-8")}catch(m){b.logger.debug(`failed to read rule source ${a}: ${m}`);return}const p=A("codex");for(const m of c.ALL_CYCLES){const I=(0,c.isCycleEnabled)(o,m)?$=>{const R=(0,g.join)(p,(0,C.fragmentFilename)("rule",m,$));if(!(0,r.existsSync)(R)){const Q=$.length>0?`${m}:${$}`:m;return b.logger.debug(`AGENTS.md platform-section ${Q}: missing fragment ${R}, using placeholder`),null}return(0,r.readFileSync)(R,"utf-8").trimEnd()}:null;l=(0,C.applyPlatformSection)(l,m,I,"AGENTS.md")}const v=(0,r.existsSync)(i)?(0,r.readFileSync)(i,"utf-8"):"",u=(0,n.upsertAgentsMdBlock)(v,l);(0,r.writeFileSync)(i,u)}writeSkills(e,o,s,i){const t=(0,g.join)(e,".agents","skills"),a=i==="main-agent";if(o){const v=(0,g.join)(t,"ironbee-verification");(0,r.mkdirSync)(v,{recursive:!0});const u=(0,g.join)(__dirname,"skills",a?"ironbee-verification.main.md":"ironbee-verification.md");try{let m=(0,r.readFileSync)(u,"utf-8");a&&(m=this.spliceCycleFragments(m,"skill",s,"ironbee-verification/SKILL.md")),(0,r.writeFileSync)((0,g.join)(v,"SKILL.md"),m)}catch(m){b.logger.debug(`failed to copy skill ${u}: ${m}`)}}const l=(0,g.join)(t,"ironbee-verify");(0,r.mkdirSync)(l,{recursive:!0});const p=(0,g.join)(__dirname,"commands","ironbee-verify",a?"SKILL.main.md":"SKILL.md");try{let v=(0,r.readFileSync)(p,"utf-8");a&&(v=this.spliceCycleFragments(v,"command-verify",s,"ironbee-verify/SKILL.md")),(0,r.writeFileSync)((0,g.join)(l,"SKILL.md"),v)}catch(v){b.logger.debug(`failed to copy verify command ${p}: ${v}`)}}spliceCycleFragments(e,o,s,i){const t=A("codex");let a=e;for(const l of c.ALL_CYCLES){const v=(0,c.isCycleEnabled)(s,l)?u=>{const m=(0,g.join)(t,(0,C.fragmentFilename)(o,l,u));return(0,r.existsSync)(m)?(0,r.readFileSync)(m,"utf-8").trimEnd():null}:null;a=(0,C.applyPlatformSection)(a,l,v,i)}return a}removeDir(e){if((0,r.existsSync)(e))try{(0,r.rmSync)(e,{recursive:!0,force:!0})}catch(o){b.logger.debug(`failed to remove ${e}: ${o}`)}}}function N(f){return(0,n.tomlBodyFromRecord)(f)}y(N,"mcpEntryToTomlBody");0&&(module.exports={CodexClient});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
You MUST verify all code changes before completing any task — by driving the IronBee verification tools yourself. This project runs IronBee in **main-agent** mode: the devtools tools (`mcp__browser-devtools__*` / `mcp__node-devtools__*` / `mcp__backend-devtools__*` / `mcp__android-devtools__*`) are wired into THIS session. There is no verifier sub-agent — you verify inline.
|
|
2
|
+
|
|
3
|
+
Your **Session ID** is injected into your context by the SessionStart hook (a `Session ID: <sid>` line); author it in every `ironbee hook` command's JSON.
|
|
4
|
+
|
|
5
|
+
After editing code (`apply_patch`), before reporting completion:
|
|
6
|
+
|
|
7
|
+
1. **Start verification — run this ALONE first** (Codex runs shell and MCP tools in separate lanes, so the open must land before any devtools call):
|
|
8
|
+
```
|
|
9
|
+
echo '{"session_id":"<your-session-id>"}' | ironbee hook verification-start
|
|
10
|
+
```
|
|
11
|
+
2. Build and start the app if it isn't already running (don't guess ports). Track what YOU started.
|
|
12
|
+
3. **Drive every active cycle's tools** (browser / runtime / backend / android, as wired up for this project — see the platform sections below) to exercise what changed. Reading code is NOT verification.
|
|
13
|
+
4. Tear down only what you started, then **submit one verdict**:
|
|
14
|
+
```
|
|
15
|
+
echo '{"session_id":"...","status":"pass","checks":["..."]}' | ironbee hook submit-verdict
|
|
16
|
+
```
|
|
17
|
+
On fail add `"issues":[...]`; on pass-after-fail add `"fixes":[...]`. Nothing to verify → N/A (`"status":"not_applicable","reason":[...]`, or per-platform `"not_applicable_cycles":[...]`).
|
|
18
|
+
5. If verification FAILS: submit the fail verdict first, then fix the issues, then re-verify (back to step 1) until it passes.
|
|
19
|
+
|
|
20
|
+
Every `apply_patch` clears the verdict, requiring re-verification. The Stop gate blocks completion until a valid verdict exists for your changes and the required tools were called for every active cycle.
|
|
21
|
+
|
|
22
|
+
<!--IRONBEE:PLATFORM:browser-->
|
|
23
|
+
<!--/IRONBEE:PLATFORM:browser-->
|
|
24
|
+
|
|
25
|
+
<!--IRONBEE:PLATFORM:node-->
|
|
26
|
+
<!--/IRONBEE:PLATFORM:node-->
|
|
27
|
+
|
|
28
|
+
<!--IRONBEE:PLATFORM:backend-->
|
|
29
|
+
<!--/IRONBEE:PLATFORM:backend-->
|
|
30
|
+
|
|
31
|
+
<!--IRONBEE:PLATFORM:android-->
|
|
32
|
+
<!--/IRONBEE:PLATFORM:android-->
|
|
33
|
+
|
|
34
|
+
## BANNED
|
|
35
|
+
|
|
36
|
+
- Reporting a task complete without verifying your changes through the real tools.
|
|
37
|
+
- Submitting a verdict based on assumptions, code reading, or prior knowledge — verify through real tools.
|
|
38
|
+
- Writing `verdict.json` directly (always use `ironbee hook submit-verdict`).
|
|
39
|
+
- Submitting `pass` when your own evidence shows a legitimate, in-scope operation breaking — that is a FALSE pass; fail it.
|
|
@@ -8,7 +8,7 @@ The Stop gate blocks completion until a verdict exists for your changes — dele
|
|
|
8
8
|
|
|
9
9
|
## BANNED
|
|
10
10
|
|
|
11
|
-
- Running the verification tools (`bdt_*` / `ndt_*` / `bedt_*`) or `ironbee hook verification-start` / `submit-verdict` yourself — those are the verifier's job. Delegate.
|
|
11
|
+
- Running the verification tools (`bdt_*` / `ndt_*` / `bedt_*`) or `ironbee hook verification-start` / `submit-verdict` yourself — those are the verifier's job. Delegate. The verifier already submitted the single verdict in this shared session; you only RELAY it in text. Re-running `submit-verdict` yourself is REJECTED ("no active verification cycle" — the cycle already closed) and records nothing — a duplicate, not a verdict.
|
|
12
12
|
- Using the generic `spawn_agent` tool / a plain fork to "be" the verifier — that spawns a DEFAULT agent without the devtools. Spawn the `ironbee-verifier` custom agent by its `agent_type`.
|
|
13
13
|
- Reporting a task complete without delegating verification of your changes.
|
|
14
14
|
- Submitting a verdict based on assumptions, code reading, or prior knowledge — the verifier verifies through real tools.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: ironbee-verification
|
|
3
|
+
description: >
|
|
4
|
+
MANDATORY verification after code changes. Activates when implementing features, fixing
|
|
5
|
+
bugs, modifying UI components, API endpoints, styles, refactoring, or any task that changes
|
|
6
|
+
application behavior. After editing code you MUST verify the affected cycle(s) through real
|
|
7
|
+
tools and submit a single verdict (pass or fail) before reporting task completion. You drive
|
|
8
|
+
the verification tools yourself — they are wired into this session.
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# IronBee Verification
|
|
12
|
+
|
|
13
|
+
> **You verify INLINE.** This project runs IronBee in **main-agent** mode: the devtools tools
|
|
14
|
+
> (`mcp__browser-devtools__*` / `mcp__node-devtools__*` / `mcp__backend-devtools__*` /
|
|
15
|
+
> `mcp__android-devtools__*`) are wired into THIS session — you drive them yourself. There is no
|
|
16
|
+
> verifier sub-agent to delegate to.
|
|
17
|
+
|
|
18
|
+
## Rule
|
|
19
|
+
No task is complete until your changes are verified through **real tools**, not by reading code or
|
|
20
|
+
inferring behavior. After verifying, you MUST submit a verdict (pass or fail) before doing
|
|
21
|
+
anything else. If verification fails, submit the fail verdict first, then fix and re-verify.
|
|
22
|
+
|
|
23
|
+
## Session id
|
|
24
|
+
IronBee's SessionStart hook injects your **Session ID** into your context at the top of the
|
|
25
|
+
session (a line `Session ID: <sid>`). Author it in every `ironbee hook` command's JSON.
|
|
26
|
+
|
|
27
|
+
## Cycles
|
|
28
|
+
IronBee runs verification in **cycles**. A single Stop hook can drive multiple cycles in
|
|
29
|
+
parallel — every active cycle must pass for your task to complete. You don't choose which cycle
|
|
30
|
+
runs — the edited file's path decides (pattern match). **See the platform sections near the
|
|
31
|
+
bottom of this file** for which cycles are active for this project, the tools they expose, and
|
|
32
|
+
the per-cycle flow.
|
|
33
|
+
|
|
34
|
+
## Universal flow
|
|
35
|
+
|
|
36
|
+
1. Finish your code edits (`apply_patch`).
|
|
37
|
+
2. **Start verification — run this ALONE first**, before any devtools call:
|
|
38
|
+
```
|
|
39
|
+
echo '{"session_id":"<your-session-id>"}' | ironbee hook verification-start
|
|
40
|
+
```
|
|
41
|
+
Devtools tools are blocked until this opens the cycle. **Codex runs shell commands and MCP
|
|
42
|
+
tools in separate lanes**, so a same-message ordering of this shell command before a devtools
|
|
43
|
+
call is NOT guaranteed — a devtools call that lands first is blocked. Once the cycle is open,
|
|
44
|
+
independent MCP calls can ride one message.
|
|
45
|
+
3. Build and start the application **only if it isn't already running** (check `docker compose ps`
|
|
46
|
+
/ process output / config — don't guess ports). Track whether YOU started it.
|
|
47
|
+
4. **Run the per-cycle flows for every active cycle** (see the platform sections below). All
|
|
48
|
+
active cycles must be exercised within this one verification cycle.
|
|
49
|
+
5. **Teardown** — stop ONLY what you started (the dev server / container you launched for this
|
|
50
|
+
verification); never stop a server that was already running. Honor any cycle-specific teardown
|
|
51
|
+
(e.g. stop an active screen recording) BEFORE the verdict.
|
|
52
|
+
6. **Submit your verdict immediately** — do NOT edit any code first:
|
|
53
|
+
```
|
|
54
|
+
echo '<verdict-json>' | ironbee hook submit-verdict
|
|
55
|
+
```
|
|
56
|
+
- Platform-agnostic shape: `session_id`, `status`, `checks`, optionally `issues` / `fixes`.
|
|
57
|
+
One verdict regardless of how many cycles ran.
|
|
58
|
+
- Pass → `{ "session_id": "...", "status": "pass", "checks": [...] }`
|
|
59
|
+
- Fail → add `"issues": [...]` describing what failed.
|
|
60
|
+
- Pass after a previous fail → add `"fixes": [...]` describing what was repaired.
|
|
61
|
+
- **A FALSE failure is a FAIL — not "verified failure handling".** Separate an EXPECTED
|
|
62
|
+
negative test (you deliberately fed invalid input and it correctly failed → supports a
|
|
63
|
+
`pass`) from a FALSE failure (a VALID, in-scope operation that SHOULD succeed but errors out
|
|
64
|
+
→ a DEFECT → `status: "fail"`).
|
|
65
|
+
- **Nothing to verify? Use N/A — never fake evidence.** When the change has no runtime surface
|
|
66
|
+
(type-only edit, behavior-neutral refactor, config/docs that still tripped a cycle): global
|
|
67
|
+
`{ "session_id": "...", "status": "not_applicable", "reason": ["why"] }` (no `checks`), or
|
|
68
|
+
per-platform on a pass/fail verdict `"not_applicable_cycles": ["browser"], "reason": ["..."]`
|
|
69
|
+
to exempt some cycles while verifying others. `reason` is REQUIRED. Strict mode rejects N/A.
|
|
70
|
+
Base "nothing to verify" on the FULL change set (the change is often already COMMITTED) —
|
|
71
|
+
check `git diff HEAD~1 HEAD --stat`, not just a clean `git status`.
|
|
72
|
+
7. If failed → fix → rebuild → go back to step 2 → repeat until pass (up to the retry cap).
|
|
73
|
+
|
|
74
|
+
## Speed — batch your tool calls (fewer LLM round-trips)
|
|
75
|
+
|
|
76
|
+
Each tool call is a separate LLM round-trip, and that round-trip — not the tool's execution — is
|
|
77
|
+
the dominant cost. Drive the tools in as few turns as you can:
|
|
78
|
+
|
|
79
|
+
- **Batch a scope's work into ONE `*_execute` call.** Each cycle exposes a batch tool
|
|
80
|
+
(`mcp__browser-devtools__bdt_execute` / `mcp__node-devtools__ndt_execute` /
|
|
81
|
+
`mcp__backend-devtools__bedt_execute` / `mcp__android-devtools__adt_execute`) that runs many
|
|
82
|
+
steps in one turn — nest each as a `callTool('<tool>', { … })`. A batch nests only that cycle's
|
|
83
|
+
own tools. It's a JS sandbox, so a later step can reuse a value an earlier `callTool` returned;
|
|
84
|
+
`*_execute` STOPS at the first failing nested call. Authoring the batch is not the work — read
|
|
85
|
+
each result and confirm real evidence came back.
|
|
86
|
+
- **Discovery stays standalone** — the step that reveals what to do (navigate / connect / snapshot)
|
|
87
|
+
runs first and on its own; THEN batch the actions it told you to take.
|
|
88
|
+
|
|
89
|
+
<!--IRONBEE:PLATFORM:browser-->
|
|
90
|
+
<!--/IRONBEE:PLATFORM:browser-->
|
|
91
|
+
|
|
92
|
+
<!--IRONBEE:PLATFORM:node-->
|
|
93
|
+
<!--/IRONBEE:PLATFORM:node-->
|
|
94
|
+
|
|
95
|
+
<!--IRONBEE:PLATFORM:backend-->
|
|
96
|
+
<!--/IRONBEE:PLATFORM:backend-->
|
|
97
|
+
|
|
98
|
+
<!--IRONBEE:PLATFORM:android-->
|
|
99
|
+
<!--/IRONBEE:PLATFORM:android-->
|
|
100
|
+
|
|
101
|
+
## Important
|
|
102
|
+
- **Always submit a verdict after every verification attempt** — both pass AND fail.
|
|
103
|
+
- Submit verdicts via `ironbee hook submit-verdict`, never write `verdict.json` directly.
|
|
104
|
+
- Every `apply_patch` edit automatically clears your session's verdict — re-verify after edits.
|
|
105
|
+
- After the retry cap, you may complete but must report unresolved issues.
|
|
106
|
+
|
|
107
|
+
## BANNED
|
|
108
|
+
- Reporting a task complete without verifying your changes through the real tools.
|
|
109
|
+
- Claiming verification passed based on code reading, assumptions, or prior knowledge.
|
|
110
|
+
- Submitting `pass` when your own evidence shows a legitimate operation breaking.
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var d=Object.defineProperty;var x=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var $=Object.prototype.hasOwnProperty;var g=(e,o)=>d(e,"name",{value:o,configurable:!0});var h=(e,o)=>{for(var l in o)d(e,l,{get:o[l],enumerable:!0})},w=(e,o,l,a)=>{if(o&&typeof o=="object"||typeof o=="function")for(let r of y(o))!$.call(e,r)&&r!==l&&d(e,r,{get:()=>o[r],enumerable:!(a=x(o,r))||a.enumerable});return e};var j=e=>w(d({},"__esModule",{value:!0}),e);var I={};h(I,{verifierCommand:()=>D});module.exports=j(I);var m=require("commander"),i=require("fs"),p=require("path"),s=require("../../lib/config"),b=require("../../lib/logger"),n=require("../../lib/output"),v=require("./index");function M(e){if(e.global===!0&&e.local===!0)throw new Error("Pass at most one of -g / --global, --local.");const o=e.projectDir??process.cwd();return e.global===!0?{target:"global",projectDir:o}:e.local===!0?{target:"local",projectDir:o}:{target:"project",projectDir:o}}g(M,"resolveTarget");function k(e){if(!(0,i.existsSync)(e))return{};try{return JSON.parse((0,i.readFileSync)(e,"utf-8"))}catch(o){throw new Error(`Config at ${e} is not valid JSON: ${o instanceof Error?o.message:o}`)}}g(k,"readConfigFile");function S(e,o){const l=(0,i.existsSync)(e)?(0,i.readFileSync)(e,"utf-8"):null,a=k(e),r={...a.codex??{}};return r.verifier={...r.verifier??{},mode:o},(0,i.mkdirSync)((0,p.join)(e,".."),{recursive:!0}),(0,i.writeFileSync)(e,JSON.stringify({...a,codex:r},null,2)+`
|
|
2
|
+
`),l}g(S,"writeVerifierMode");const E=new m.Command("mode").description(`Set the Codex verifier delivery mode: "sub-agent" (default \u2014 delegate to the ironbee-verifier custom agent) or "main-agent" (the main agent drives the devtools tools directly; the fallback when Codex's sub-agent machinery breaks).`).argument("<mode>",'"sub-agent" or "main-agent"').option("-p, --project-dir <dir>","Project directory (default: cwd).").option("-g, --global","Write to the global config (~/.ironbee/config.json).").option("--local","Write to the gitignored project-local override (<project>/.ironbee/config.local.json).").action((e,o)=>{e!=="sub-agent"&&e!=="main-agent"&&(console.error(`${n.pc.red("\u2717")} Invalid mode "${e}". Use ${n.pc.bold("sub-agent")} or ${n.pc.bold("main-agent")}.`),process.exit(1));const l=e;let a,r;try{({target:a,projectDir:r}=M(o))}catch(t){console.error(`${n.pc.red("\u2717")} ${t instanceof Error?t.message:t}`),process.exit(1);return}const c=(0,s.getTargetConfigPath)(a,r);let f=null;try{f=S(c,l)}catch(t){console.error(`${n.pc.red("\u2717")} ${t instanceof Error?t.message:t}`),process.exit(1);return}const u=new v.CodexClient;if(u.detect(r))try{u.install(r,(0,s.loadConfig)(r))}catch(t){if(f===null)try{(0,i.writeFileSync)(c,"")}catch{}else try{(0,i.writeFileSync)(c,f)}catch{}b.logger.debug(`verifier mode: rerender failed, rolled back ${c}: ${t}`),console.error(`${n.pc.red("\u2717")} Failed to re-render Codex artifacts: ${t instanceof Error?t.message:t}`),process.exit(1);return}else console.log(` ${n.pc.yellow("\u26A0")} Codex is not installed in this project \u2014 setting saved, run ${n.pc.bold("ironbee install --client codex")} to apply.`);const C=(0,s.getCodexVerifierMode)((0,s.loadConfig)(r));console.log(`${n.pc.green("\u2713")} Codex verifier mode set to ${n.pc.bold(l)} in ${a} config (${n.pc.dim(c)}).`),C!==l&&console.log(` ${n.pc.yellow("\u26A0")} Effective mode is ${n.pc.bold(C)} \u2014 a higher-priority config layer overrides this write.`),console.log(` ${n.pc.dim("\u21BB")} Restart any open Codex sessions to pick up the new config.`)}),D=new m.Command("verifier").description("Codex verifier settings. Subcommand: `mode <sub-agent|main-agent>` \u2014 how the verification cycle is driven (sub-agent delegation vs the main agent driving the tools directly).").addCommand(E);0&&(module.exports={verifierCommand});
|
package/dist/commands/config.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var m=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var q=Object.prototype.hasOwnProperty;var l=(e,o)=>m(e,"name",{value:o,configurable:!0});var L=(e,o)=>{for(var n in o)m(e,n,{get:o[n],enumerable:!0})},M=(e,o,n,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let i of V(o))!q.call(e,i)&&i!==n&&m(e,i,{get:()=>o[i],enumerable:!(r=K(o,i))||r.enumerable});return e};var Y=e=>M(m({},"__esModule",{value:!0}),e);var ie={};L(ie,{configCommand:()=>u,runGet:()=>U,runList:()=>W,runPath:()=>_,runSet:()=>F,runUnset:()=>B});module.exports=Y(ie);var D=require("commander"),g=require("fs"),N=require("os"),d=require("path"),f=require("../clients/registry"),I=require("./install"),b=require("../lib/config"),G=require("../lib/gitignore"),k=require("../lib/logger"),t=require("../lib/output"),h=require("../lib/prompt"),J=require("../lib/projects-registry");const z=new Set(["verification","collector","browser","node","backend","android","browserDevTools","nodeDevTools","backendDevTools","androidDevTools","telemetry","privacy","statusLine","otel"]);function C(e){return(0,d.join)((0,d.resolve)(e),".ironbee","config.json")}l(C,"projectConfigPath");function S(e){return(0,d.join)((0,d.resolve)(e),".ironbee","config.local.json")}l(S,"projectLocalConfigPath");function O(){return(0,d.join)((0,N.homedir)(),".ironbee","config.json")}l(O,"globalConfigPath");function w(e){if(!(0,g.existsSync)(e))return{};try{const o=(0,g.readFileSync)(e,"utf-8");return o.trim().length===0?{}:JSON.parse(o)}catch(o){throw k.logger.debug(`failed to read ${e}: ${o}`),new Error(`Config at ${e} is not valid JSON: ${o instanceof Error?o.message:o}`)}}l(w,"readConfigFile");function j(e,o){(0,g.mkdirSync)((0,d.join)(e,".."),{recursive:!0}),(0,g.writeFileSync)(e,JSON.stringify(o,null,2)+`
|
|
1
|
+
"use strict";var m=Object.defineProperty;var K=Object.getOwnPropertyDescriptor;var V=Object.getOwnPropertyNames;var q=Object.prototype.hasOwnProperty;var l=(e,o)=>m(e,"name",{value:o,configurable:!0});var L=(e,o)=>{for(var n in o)m(e,n,{get:o[n],enumerable:!0})},M=(e,o,n,r)=>{if(o&&typeof o=="object"||typeof o=="function")for(let i of V(o))!q.call(e,i)&&i!==n&&m(e,i,{get:()=>o[i],enumerable:!(r=K(o,i))||r.enumerable});return e};var Y=e=>M(m({},"__esModule",{value:!0}),e);var ie={};L(ie,{configCommand:()=>u,runGet:()=>U,runList:()=>W,runPath:()=>_,runSet:()=>F,runUnset:()=>B});module.exports=Y(ie);var D=require("commander"),g=require("fs"),N=require("os"),d=require("path"),f=require("../clients/registry"),I=require("./install"),b=require("../lib/config"),G=require("../lib/gitignore"),k=require("../lib/logger"),t=require("../lib/output"),h=require("../lib/prompt"),J=require("../lib/projects-registry");const z=new Set(["verification","collector","browser","node","backend","android","browserDevTools","nodeDevTools","backendDevTools","androidDevTools","telemetry","privacy","statusLine","otel","codex"]);function C(e){return(0,d.join)((0,d.resolve)(e),".ironbee","config.json")}l(C,"projectConfigPath");function S(e){return(0,d.join)((0,d.resolve)(e),".ironbee","config.local.json")}l(S,"projectLocalConfigPath");function O(){return(0,d.join)((0,N.homedir)(),".ironbee","config.json")}l(O,"globalConfigPath");function w(e){if(!(0,g.existsSync)(e))return{};try{const o=(0,g.readFileSync)(e,"utf-8");return o.trim().length===0?{}:JSON.parse(o)}catch(o){throw k.logger.debug(`failed to read ${e}: ${o}`),new Error(`Config at ${e} is not valid JSON: ${o instanceof Error?o.message:o}`)}}l(w,"readConfigFile");function j(e,o){(0,g.mkdirSync)((0,d.join)(e,".."),{recursive:!0}),(0,g.writeFileSync)(e,JSON.stringify(o,null,2)+`
|
|
2
2
|
`)}l(j,"writeConfigFile");function H(e){const o=e.indexOf(".");return o===-1?e:e.slice(0,o)}l(H,"topKey");function $(e){return z.has(H(e))}l($,"affectsArtifacts");function Q(e,o){if(o.length===0)return e;const n=o.split(".");let r=e;for(const i of n){if(r==null||typeof r!="object"||Array.isArray(r))return;r=r[i]}return r}l(Q,"getAtPath");function X(e,o,n){if(o.length===0)throw new Error("Cannot set the root config \u2014 pass a dotted key (e.g. `collector.url`).");const r=o.split(".");let i=e;for(let a=0;a<r.length-1;a++){const s=r[a],c=i[s];(c==null||typeof c!="object"||Array.isArray(c))&&(i[s]={}),i=i[s]}i[r[r.length-1]]=n}l(X,"setAtPath");function Z(e,o){if(o.length===0)return!1;const n=o.split(".");let r=e;for(let a=0;a<n.length-1;a++){const s=n[a],c=r[s];if(c==null||typeof c!="object"||Array.isArray(c))return!1;r=c}const i=n[n.length-1];return Object.prototype.hasOwnProperty.call(r,i)?(delete r[i],!0):!1}l(Z,"unsetAtPath");function ee(e,o){if(o)try{return JSON.parse(e)}catch(n){throw new Error(`--json was set but value is not valid JSON: ${n instanceof Error?n.message:n}`)}try{return JSON.parse(e)}catch{return e}}l(ee,"parseValue");function v(e){if(e.global===!0&&e.local===!0)throw new Error("Pass at most one of --global / --local.");if(e.global===!0)return{path:O(),label:"global",useGlobal:!0};const o=e.projectDir??process.cwd();return e.local===!0?{path:S(o),label:"local",useGlobal:!1}:{path:C(o),label:"project",useGlobal:!1}}l(v,"resolveWriteTarget");function A(e){if((e.global===!0?1:0)+(e.project===!0?1:0)+(e.local===!0?1:0)>1)throw new Error("Pass at most one of --global / --project / --local.");if(e.global===!0)return{label:"global",path:O()};const n=e.projectDir??process.cwd();return e.project===!0?{label:"project",path:C(n)}:e.local===!0?{label:"local",path:S(n)}:{label:"merged",path:n}}l(A,"resolveReadTarget");function P(e){return e.label==="merged"?(0,b.loadConfig)(e.path):w(e.path)}l(P,"readForGet");function oe(e){return e===void 0?"(unset)":typeof e=="string"?e:JSON.stringify(e,null,2)}l(oe,"formatValue");function ne(e,o){const n=(0,f.detectClients)(e);if(o===void 0&&n.length===0)return console.log(` ${t.pc.dim("\xB7")} ${t.pc.dim("no clients detected in")} ${t.pc.dim(e)} ${t.pc.dim("\u2014 skipping artifact rerender")}`),[];const r=(0,b.loadConfig)(e),i=(0,f.resolveTargetClients)(e,o);for(const a of i)a.install(e,r);return(0,G.ensureIronBeeGitignored)(e),i.map(a=>a.name)}l(ne,"rerenderArtifacts");function E(e,o,n,r){const i=(0,g.existsSync)(e)?(0,g.readFileSync)(e,"utf-8"):null;j(e,o);try{return ne(n,r)}catch(a){try{i===null?(0,g.existsSync)(e)&&(0,g.unlinkSync)(e):(0,g.writeFileSync)(e,i)}catch(s){k.logger.debug(`config rollback failed: ${s}`)}throw a}}l(E,"writeAndRerender");const R=10;function te(e){const o=(0,f.listActiveProjects)(),n=(0,J.canonicalizePath)(e);return o.filter(r=>r.path!==n)}l(te,"listOtherProjects");function re(e){const o=e.length===1?"other project":"other projects";console.log(` ${t.pc.yellow("\u26A0")} ${t.pc.bold(String(e.length))} ${o} registered in the inventory still on the prior state:`);const n=e.slice(0,R);for(const r of n)console.log(` ${t.pc.dim("\xB7")} ${t.pc.dim(r.path)}`);e.length>R&&console.log(` ${t.pc.dim("\u2026and")} ${t.pc.bold(String(e.length-R))} ${t.pc.dim("more")}`)}l(re,"printOtherProjectsBanner");async function T(e,o,n){if(!o)return;const r=te(e);if(r.length===0)return;re(r);let i;if(n===!0)i=!0;else if(n===!1){console.log(` ${t.pc.dim("Run")} ${t.pc.cyan("ironbee install --all")} ${t.pc.dim("later to apply, or")} ${t.pc.cyan("ironbee install")} ${t.pc.dim("in selected projects.")}`);return}else if((0,h.isInteractive)()){const a=r.length===1?"this project":`these ${r.length} projects`;i=await(0,h.promptYesNo)(` Apply this change to ${a} now?`,!0)}else{console.log(` ${t.pc.dim("Run")} ${t.pc.cyan("ironbee install --all")} ${t.pc.dim("to apply everywhere, or pass")} ${t.pc.cyan("--apply-all")} ${t.pc.dim("to skip this prompt.")}`);return}if(!i){console.log(` ${t.pc.dim("Skipped. Run")} ${t.pc.cyan("ironbee install --all")} ${t.pc.dim("later to apply.")}`);return}console.log(),await(0,I.runInstallAll)({})}l(T,"maybeApplyToOtherProjects");async function F(e,o,n){if(e.length===0)throw new Error("Key is required (dotted path, e.g. `collector.url`).");const r=v(n),i=ee(o,n.json===!0),a=w(r.path),s=JSON.parse(JSON.stringify(a));X(s,e,i);const c=n.projectDir??process.cwd(),p=n.rerender!==!1&&$(e);let y=[];p?y=E(r.path,s,c,n.client):j(r.path,s),console.log(`${t.pc.green("\u2713")} Set ${t.pc.cyan(e)} = ${t.pc.bold(oe(i))} in ${r.label} config (${t.pc.dim(r.path)}).`),p?y.length>0&&(console.log(` ${t.pc.dim("Re-rendered artifacts for:")} ${t.pc.bold(y.join(", "))}`),console.log(` ${t.pc.yellow("\u26A0")} Restart your editor / agent session for the change to take effect.`)):n.rerender===!1&&$(e)&&console.log(` ${t.pc.yellow("\u26A0")} --no-rerender set: artifacts may now be out of sync with config. Run ${t.pc.cyan("ironbee install")} to resync.`),x(e),r.useGlobal&&await T(c,p,n.applyAll)}l(F,"runSet");function x(e){const o=(0,b.findActiveEnvOverride)(e);o!==void 0&&console.log(` ${t.pc.yellow("\u26A0")} ${t.pc.cyan(o.envVar)} is set in this shell \u2014 env overrides file config, so ${t.pc.cyan(e)} reads will return the env value until ${t.pc.cyan(o.envVar)} is unset.`)}l(x,"warnIfEnvShadowed");async function B(e,o){if(e.length===0)throw new Error("Key is required (dotted path, e.g. `collector.url`).");const n=v(o),r=w(n.path),i=JSON.parse(JSON.stringify(r));if(!Z(i,e)){console.log(`${t.pc.dim("\xB7")} ${t.pc.cyan(e)} not present in ${n.label} config (${t.pc.dim(n.path)}). No-op.`);return}const s=o.projectDir??process.cwd(),c=o.rerender!==!1&&$(e);let p=[];c?p=E(n.path,i,s,o.client):j(n.path,i),console.log(`${t.pc.green("\u2713")} Unset ${t.pc.cyan(e)} in ${n.label} config (${t.pc.dim(n.path)}).`),c&&p.length>0&&(console.log(` ${t.pc.dim("Re-rendered artifacts for:")} ${t.pc.bold(p.join(", "))}`),console.log(` ${t.pc.yellow("\u26A0")} Restart your editor / agent session for the change to take effect.`)),x(e),n.useGlobal&&await T(s,c,o.applyAll)}l(B,"runUnset");function U(e,o){const n=A(o),r=P(n),i=Q(r,e);i===void 0&&(console.error(`${t.pc.dim("\xB7")} ${t.pc.cyan(e)} ${t.pc.dim("not set in")} ${n.label} ${t.pc.dim("config")}`),process.exit(1)),console.log(typeof i=="string"?i:JSON.stringify(i,null,2))}l(U,"runGet");function W(e){const o=A(e),n=P(o);console.log(JSON.stringify(n,null,2))}l(W,"runList");function _(e){const o=v(e);console.log(o.path)}l(_,"runPath");const u=new D.Command("config").description("Read or write IronBee configuration values (project or global). Smart re-render: artifact-affecting keys auto-update installed client files.");u.command("get <key>").description("Print the value at a dotted path. Default: merged effective value (global + project + local). --global / --project / --local narrow to one source.").option("-p, --project-dir <dir>","Project directory (default: cwd).").option("-g, --global","Read from global config only (~/.ironbee/config.json).").option("--project","Read from project config only (<project>/.ironbee/config.json).").option("--local","Read from project-local config only (<project>/.ironbee/config.local.json \u2014 gitignored).").action((e,o)=>{try{U(e,o)}catch(n){console.error(`${t.pc.red("\u2717")} ${n instanceof Error?n.message:n}`),process.exit(1)}}),u.command("set <key> <value>").description("Set a config value. Type-coerces (true/42/[\u2026]/{\u2026}) unless --json forces strict parsing. Re-renders client artifacts when the top-level key affects them. After a global write (`-g`) on an artifact-affecting key, prompts whether to apply the change to every other registered project. Use --local to write to the gitignored personal-override layer instead of the committed project config.").option("-p, --project-dir <dir>","Project directory (default: cwd).").option("-g, --global","Write to global config (~/.ironbee/config.json).").option("--local","Write to the gitignored project-local override (<project>/.ironbee/config.local.json) instead of the committed project config. Mutually exclusive with --global.").option("--client <name>",`Filter clients for artifact rerender (${(0,f.clientNames)()}), or "all". Default: detected clients.`).option("--no-rerender","Skip artifact rerender even when the key normally triggers it.").option("--json","Require value to parse as strict JSON (no string fallback).").option("--apply-all","After a global write on an artifact-affecting key, apply the change to every registered project without prompting.").option("--no-apply-all","After a global write on an artifact-affecting key, do NOT apply to other registered projects (suppress the prompt).").action(async(e,o,n)=>{try{await F(e,o,n)}catch(r){console.error(`${t.pc.red("\u2717")} ${r instanceof Error?r.message:r}`),process.exit(1)}}),u.command("unset <key>").description("Remove a config key. Idempotent \u2014 no-op when the key is absent. Re-renders client artifacts when the top-level key affects them. After a global unset (`-g`) on an artifact-affecting key, prompts whether to apply the change to every other registered project. Use --local to remove from the gitignored personal-override layer instead of the committed project config.").option("-p, --project-dir <dir>","Project directory (default: cwd).").option("-g, --global","Write to global config (~/.ironbee/config.json).").option("--local","Write to the gitignored project-local override (<project>/.ironbee/config.local.json) instead of the committed project config. Mutually exclusive with --global.").option("--client <name>",`Filter clients for artifact rerender (${(0,f.clientNames)()}), or "all". Default: detected clients.`).option("--no-rerender","Skip artifact rerender even when the key normally triggers it.").option("--apply-all","After a global unset on an artifact-affecting key, apply the change to every registered project without prompting.").option("--no-apply-all","After a global unset on an artifact-affecting key, do NOT apply to other registered projects (suppress the prompt).").action(async(e,o)=>{try{await B(e,o)}catch(n){console.error(`${t.pc.red("\u2717")} ${n instanceof Error?n.message:n}`),process.exit(1)}}),u.command("list").description("Print the entire config. Default: merged effective config; --global / --project / --local narrow to one source.").option("-p, --project-dir <dir>","Project directory (default: cwd).").option("-g, --global","Read from global config only.").option("--project","Read from project config only.").option("--local","Read from project-local config only (<project>/.ironbee/config.local.json \u2014 gitignored).").action(e=>{try{W(e)}catch(o){console.error(`${t.pc.red("\u2717")} ${o instanceof Error?o.message:o}`),process.exit(1)}}),u.command("path").description("Print the on-disk path of the targeted config file (project by default; --global for global, --local for the gitignored personal-override layer).").option("-p, --project-dir <dir>","Project directory (default: cwd).").option("-g, --global","Print global config path (~/.ironbee/config.json).").option("--local","Print project-local config path (<project>/.ironbee/config.local.json).").action(e=>{try{_(e)}catch(o){console.error(`${t.pc.red("\u2717")} ${o instanceof Error?o.message:o}`),process.exit(1)}});0&&(module.exports={configCommand,runGet,runList,runPath,runSet,runUnset});
|
package/dist/commands/install.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var y=Object.defineProperty;var V=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var u=(i,e)=>y(i,"name",{value:e,configurable:!0});var T=(i,e)=>{for(var o in e)y(i,o,{get:e[o],enumerable:!0})},R=(i,e,o,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of A(e))!N.call(i,r)&&r!==o&&y(i,r,{get:()=>e[r],enumerable:!(a=V(e,r))||a.enumerable});return i};var B=i=>R(y({},"__esModule",{value:!0}),i);var q={};T(q,{CYCLE_HINTS:()=>D,installCommand:()=>F,runInstallAll:()=>v,syncSchemaIfChanged:()=>W});module.exports=B(q);var $=require("commander"),P=require("fs"),x=require("path"),c=require("../clients/registry"),M=require("../clients/claude"),m=require("../lib/config"),t=require("../lib/output"),j=require("../lib/projects-registry"),f=require("../lib/prompt"),w=require("../lib/telemetry"),S=require("../lib/install-version"),p=require("../lib/schema-sync"),C=require("./cycle-toggle"),l=require("./mode-select");const D={browser:"web UI \xB7 DOM \xB7 console \xB7 a11y \xB7 screenshots \xB7 recording",node:"Node.js runtime \xB7 tracepoints \xB7 logpoints \xB7 exceptions \xB7 variables \xB7 logs",backend:"HTTP \xB7 gRPC \xB7 GraphQL \xB7 WebSocket \xB7 DB \xB7 logs"};async function _(i,e){if(e!==void 0)return e;if(!(0,f.isInteractive)())return;const o=(0,l.resolveInstallDefaultMode)(i),a=Math.max(0,l.ALL_MODES.indexOf(o)),r=l.ALL_MODES.map(d=>({label:l.MODE_LABELS[d],hint:l.MODE_HINTS[d]})),s=await(0,f.promptSelect)("Which verification mode?",r,a);return l.ALL_MODES[s]}u(_,"resolveModeSelection");function k(i,e){if(e===void 0)return;const a=(0,l.applyModeToLayer)(i,"project",e)?"":t.pc.dim(" (unchanged)");t.log.info(`Mode: ${t.pc.bold(l.MODE_LABELS[e])}${a}`)}u(k,"applyModeSelection");async function O(i,e,o){if(e!==void 0)return e;const a=(0,m.loadConfig)(i);if((o??(0,m.getVerificationMode)(a))==="monitor"||!(0,f.isInteractive)())return;const s=m.ALL_CYCLES.map(n=>({label:n,hint:D[n]})),d=m.ALL_CYCLES.map((n,g)=>(0,m.isCyclePatternsActive)(a,n)?g:-1).filter(n=>n>=0);return(await(0,f.promptMultiSelect)("Which platforms should require verification?",s,d)).map(n=>m.ALL_CYCLES[n])}u(O,"resolvePlatformSelection");function E(i,e){if(e===void 0)return;const o=(0,C.reconcileCyclesInLayer)(i,"project",e,!0),a=e.length>0?t.pc.bold(e.join(", ")):t.pc.dim("none (monitoring tools only)"),r=o.length>0?t.pc.dim(` \u2014 updated: ${o.join(", ")}`):"";t.log.info(`Platforms: ${a}${r}`)}u(E,"applyPlatformSelection");function H(i,e){return e!==void 0?(0,c.resolveTargetClients)(i.path,e):(0,c.detectClients)(i.path)}u(H,"clientsForBatchEntry");async function v(i){const e=(0,c.listActiveProjects)();if(e.length===0)return t.log.info("No registered projects to install. Run `ironbee install` somewhere first."),{failures:0,total:0};t.log.info(`Installing across ${t.pc.bold(String(e.length))} registered project(s)\u2026`),t.log.blank();let o=0;const a=[];for(const s of e)try{const d=H(s,i.client);if(d.length===0){t.log.warn(`Skipping ${s.path} \u2014 no resolvable clients`);continue}const h=d.map(n=>n.name);t.log.label("project",t.pc.dim(s.path)),t.log.step(`installing ${t.pc.bold(h.join(", "))}`),(0,M.prepareIronBeeDir)(s.path),k(s.path,i.mode),E(s.path,i.platforms);for(const n of d)n.install(s.path);(0,j.upsertProject)(s.path),a.push(...h)}catch(d){o++,t.log.error(` ${s.path}: ${d instanceof Error?d.message:String(d)}`)}t.log.blank(),o===0?t.log.success(`Installed across ${e.length} project(s). ${t.pc.dim("Restart your AI coding client(s) to apply.")}`):t.log.warn(`Completed with ${o} failure(s) \u2014 see above.`);const r=Array.from(new Set(a));return r.length>0&&await(0,w.trackInstall)(r),{failures:o,total:e.length}}u(v,"runInstallAll");async function W(){try{if((0,p.isAutoRerenderDisabled)()||(0,p.readSyncedSchemaVersion)()>=S.INSTALL_SCHEMA_VERSION)return!1;const e=(0,c.listActiveProjects)();if(e.length===0)return(0,p.writeSyncedSchemaVersion)(S.INSTALL_SCHEMA_VERSION),!1;if(!(0,f.isInteractive)())return!1;t.log.blank(),t.log.warn(`IronBee's installed setup structure changed in this version \u2014 re-rendering ${t.pc.bold(String(e.length))} registered project(s):`);for(const o of e.slice(0,10))t.log.label("project",t.pc.dim(o.path));return e.length>10&&t.log.info(t.pc.dim(` \u2026and ${e.length-10} more`)),await(0,f.promptAcknowledge)(t.pc.dim(" Press Enter to update them now\u2026 ")),await v({}),(0,p.writeSyncedSchemaVersion)(S.INSTALL_SCHEMA_VERSION),!0}catch(i){return t.log.blank(),t.log.warn(`IronBee schema sync skipped: ${i instanceof Error?i.message:String(i)}`),!1}}u(W,"syncSchemaIfChanged");const F=new $.Command("install").description("Install IronBee hooks and guidance files into a project. Use --all to install across every registered project (e.g. after a global config change).").argument("[project-dir]","target project directory",".").option("--client <name>",`client to install for (${(0,c.clientNames)()}), or "all"`).option("--all","Install across every project in the user-home inventory (~/.ironbee/projects.json) instead of just one. The [project-dir] argument is ignored when --all is set.").option("--platforms <list>",`comma-separated platforms to enable (${m.ALL_CYCLES.join(", ")}); skips the interactive picker. Empty ("") disables all. Default: interactive picker (pre-checked from current config), browser-only on a fresh non-interactive install.`).option("--mode <mode>",`verification mode (${l.ALL_MODES.join(", ")}); skips the interactive picker. enforce = full enforcement
|
|
1
|
+
"use strict";var y=Object.defineProperty;var V=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var N=Object.prototype.hasOwnProperty;var u=(i,e)=>y(i,"name",{value:e,configurable:!0});var T=(i,e)=>{for(var o in e)y(i,o,{get:e[o],enumerable:!0})},R=(i,e,o,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of A(e))!N.call(i,r)&&r!==o&&y(i,r,{get:()=>e[r],enumerable:!(a=V(e,r))||a.enumerable});return i};var B=i=>R(y({},"__esModule",{value:!0}),i);var q={};T(q,{CYCLE_HINTS:()=>D,installCommand:()=>F,runInstallAll:()=>v,syncSchemaIfChanged:()=>W});module.exports=B(q);var $=require("commander"),P=require("fs"),x=require("path"),c=require("../clients/registry"),M=require("../clients/claude"),m=require("../lib/config"),t=require("../lib/output"),j=require("../lib/projects-registry"),f=require("../lib/prompt"),w=require("../lib/telemetry"),S=require("../lib/install-version"),p=require("../lib/schema-sync"),C=require("./cycle-toggle"),l=require("./mode-select");const D={browser:"web UI \xB7 DOM \xB7 console \xB7 a11y \xB7 screenshots \xB7 recording",node:"Node.js runtime \xB7 tracepoints \xB7 logpoints \xB7 exceptions \xB7 variables \xB7 logs",backend:"HTTP \xB7 gRPC \xB7 GraphQL \xB7 WebSocket \xB7 DB \xB7 logs"};async function _(i,e){if(e!==void 0)return e;if(!(0,f.isInteractive)())return;const o=(0,l.resolveInstallDefaultMode)(i),a=Math.max(0,l.ALL_MODES.indexOf(o)),r=l.ALL_MODES.map(d=>({label:l.MODE_LABELS[d],hint:l.MODE_HINTS[d]})),s=await(0,f.promptSelect)("Which verification mode?",r,a);return l.ALL_MODES[s]}u(_,"resolveModeSelection");function k(i,e){if(e===void 0)return;const a=(0,l.applyModeToLayer)(i,"project",e)?"":t.pc.dim(" (unchanged)");t.log.info(`Mode: ${t.pc.bold(l.MODE_LABELS[e])}${a}`)}u(k,"applyModeSelection");async function O(i,e,o){if(e!==void 0)return e;const a=(0,m.loadConfig)(i);if((o??(0,m.getVerificationMode)(a))==="monitor"||!(0,f.isInteractive)())return;const s=m.ALL_CYCLES.map(n=>({label:n,hint:D[n]})),d=m.ALL_CYCLES.map((n,g)=>(0,m.isCyclePatternsActive)(a,n)?g:-1).filter(n=>n>=0);return(await(0,f.promptMultiSelect)("Which platforms should require verification?",s,d)).map(n=>m.ALL_CYCLES[n])}u(O,"resolvePlatformSelection");function E(i,e){if(e===void 0)return;const o=(0,C.reconcileCyclesInLayer)(i,"project",e,!0),a=e.length>0?t.pc.bold(e.join(", ")):t.pc.dim("none (monitoring tools only)"),r=o.length>0?t.pc.dim(` \u2014 updated: ${o.join(", ")}`):"";t.log.info(`Platforms: ${a}${r}`)}u(E,"applyPlatformSelection");function H(i,e){return e!==void 0?(0,c.resolveTargetClients)(i.path,e):(0,c.detectClients)(i.path)}u(H,"clientsForBatchEntry");async function v(i){const e=(0,c.listActiveProjects)();if(e.length===0)return t.log.info("No registered projects to install. Run `ironbee install` somewhere first."),{failures:0,total:0};t.log.info(`Installing across ${t.pc.bold(String(e.length))} registered project(s)\u2026`),t.log.blank();let o=0;const a=[];for(const s of e)try{const d=H(s,i.client);if(d.length===0){t.log.warn(`Skipping ${s.path} \u2014 no resolvable clients`);continue}const h=d.map(n=>n.name);t.log.label("project",t.pc.dim(s.path)),t.log.step(`installing ${t.pc.bold(h.join(", "))}`),(0,M.prepareIronBeeDir)(s.path),k(s.path,i.mode),E(s.path,i.platforms);for(const n of d)n.install(s.path);(0,j.upsertProject)(s.path),a.push(...h)}catch(d){o++,t.log.error(` ${s.path}: ${d instanceof Error?d.message:String(d)}`)}t.log.blank(),o===0?t.log.success(`Installed across ${e.length} project(s). ${t.pc.dim("Restart your AI coding client(s) to apply.")}`):t.log.warn(`Completed with ${o} failure(s) \u2014 see above.`);const r=Array.from(new Set(a));return r.length>0&&await(0,w.trackInstall)(r),{failures:o,total:e.length}}u(v,"runInstallAll");async function W(){try{if((0,p.isAutoRerenderDisabled)()||(0,p.readSyncedSchemaVersion)()>=S.INSTALL_SCHEMA_VERSION)return!1;const e=(0,c.listActiveProjects)();if(e.length===0)return(0,p.writeSyncedSchemaVersion)(S.INSTALL_SCHEMA_VERSION),!1;if(!(0,f.isInteractive)())return!1;t.log.blank(),t.log.warn(`IronBee's installed setup structure changed in this version \u2014 re-rendering ${t.pc.bold(String(e.length))} registered project(s):`);for(const o of e.slice(0,10))t.log.label("project",t.pc.dim(o.path));return e.length>10&&t.log.info(t.pc.dim(` \u2026and ${e.length-10} more`)),await(0,f.promptAcknowledge)(t.pc.dim(" Press Enter to update them now\u2026 ")),await v({}),(0,p.writeSyncedSchemaVersion)(S.INSTALL_SCHEMA_VERSION),!0}catch(i){return t.log.blank(),t.log.warn(`IronBee schema sync skipped: ${i instanceof Error?i.message:String(i)}`),!1}}u(W,"syncSchemaIfChanged");const F=new $.Command("install").description("Install IronBee hooks and guidance files into a project. Use --all to install across every registered project (e.g. after a global config change).").argument("[project-dir]","target project directory",".").option("--client <name>",`client to install for (${(0,c.clientNames)()}), or "all"`).option("--all","Install across every project in the user-home inventory (~/.ironbee/projects.json) instead of just one. The [project-dir] argument is ignored when --all is set.").option("--platforms <list>",`comma-separated platforms to enable (${m.ALL_CYCLES.join(", ")}); skips the interactive picker. Empty ("") disables all. Default: interactive picker (pre-checked from current config), browser-only on a fresh non-interactive install.`).option("--mode <mode>",`verification mode (${l.ALL_MODES.join(", ")}); skips the interactive picker. enforce = full enforcement, assist = tools installed but not enforced (default), monitor = monitoring-only. Default: interactive picker (pre-selecting the current mode), untouched on a non-interactive install.`).action(async(i,e)=>{let o;if(e.platforms!==void 0)try{o=(0,C.parsePlatformsFlag)(e.platforms)}catch(n){t.log.error(n instanceof Error?n.message:String(n)),process.exit(1)}let a;if(e.mode!==void 0)try{a=(0,l.parseModeFlag)(e.mode)}catch(n){t.log.error(n instanceof Error?n.message:String(n)),process.exit(1)}if(e.all===!0){(await v({client:e.client,platforms:o,mode:a})).failures>0&&process.exit(1);return}const r=(0,x.resolve)(i);(0,P.existsSync)(r)||(t.log.error(`Directory not found: ${r}`),process.exit(1));let s;if(e.client!==void 0)try{s=(0,c.resolveTargetClients)(r,e.client)}catch(n){t.log.error(n instanceof Error?n.message:String(n)),process.exit(1)}else{const n=(0,c.detectClients)(r);if(n.length>0){s=n;const g=n.map(I=>I.name).join(", ");t.log.info(`Detected client(s): ${t.pc.bold(g)}`)}else if((0,f.isInteractive)()){const g=[...c.REGISTERED_CLIENTS.map(b=>b.name),"all"],I=g.map(b=>({label:b,hint:b==="all"?"every registered client":void 0}));t.log.warn(`No client detected in ${t.pc.dim(r)}.`);const L=await(0,f.promptSelect)("Which client(s) to install for?",I,0);s=(0,c.resolveTargetClients)(r,g[L])}else t.log.warn(`No client detected. Defaulting to: ${c.REGISTERED_CLIENTS[0].name}`),s=[c.REGISTERED_CLIENTS[0]]}const d=await _(r,a),h=await O(r,o,d);t.log.blank(),(0,M.prepareIronBeeDir)(r),k(r,d),E(r,h);for(const n of s)n.install(r);(0,j.upsertProject)(r),t.log.blank(),t.log.label("project",t.pc.dim(r)),t.log.blank(),t.log.success(`IronBee installed. ${t.pc.dim("Restart your AI coding client to activate the hooks.")}`),await(0,w.trackInstall)(s.map(n=>n.name),r)});0&&(module.exports={CYCLE_HINTS,installCommand,runInstallAll,syncSchemaIfChanged});
|
|
@@ -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 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
|
|
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
|
+
"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",assist:"tools installed but not enforced \u2014 the agent verifies manually via /ironbee-verify (default)",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===!0?"enforce":"assist"}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});
|
|
@@ -1,2 +1,2 @@
|
|
|
1
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)
|
|
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)===!0,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 c=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var I=Object.prototype.hasOwnProperty;var l=(t,i)=>c(t,"name",{value:i,configurable:!0});var v=(t,i)=>{for(var r in i)c(t,r,{get:i[r],enumerable:!0})},A=(t,i,r,o)=>{if(i&&typeof i=="object"||typeof i=="function")for(let n of y(i))!I.call(t,n)&&n!==r&&c(t,n,{get:()=>i[n],enumerable:!(o=m(i,n))||o.enumerable});return t};var b=t=>A(c({},"__esModule",{value:!0}),t);var x={};v(x,{runActivityEnd:()=>P});module.exports=b(x);var u=require("./activity"),s=require("./activity-participants"),e=require("./session-state"),a=require("../../queue"),d=require("../../lib/logger");async function P(t){const{sessionDir:i,actionsFile:r,projectDir:o,sessionId:n}=t;if((0,e.isActive)(i)){const p=(0,s.anyNonMainParticipants)(i),g=(0,e.getLastVerdictStatus)(i)==="fail"&&(0,e.getVerifyIntent)(i)==="fix";if(p||g)return d.logger.debug(`assist activity-grouping defer (verifierRunning=${p} fixOwed=${g}) \u2014 keeping activity open, heartbeating main participant`),(0,s.enterActivity)(i,s.MAIN_PARTICIPANT_ID),(0,a.flushInBackground)(o,n),(0,a.flushStragglersInBackground)(o,n),!1}const f=await(0,u.closeActivityIfLastParticipant)({sessionDir:i,actionsFile:r},s.MAIN_PARTICIPANT_ID,()=>(0,e.closeOpenCycles)(i,r,"stop"));return f&&(0,e.clearVerifyIntent)(i),(0,a.flushInBackground)(o,n),(0,a.flushStragglersInBackground)(o,n),f}l(P,"runActivityEnd");0&&(module.exports={runActivityEnd});
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
"use strict";var m=Object.defineProperty;var
|
|
1
|
+
"use strict";var m=Object.defineProperty;var T=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var F=Object.prototype.hasOwnProperty;var _=(c,r)=>m(c,"name",{value:r,configurable:!0});var $=(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 I(r))!F.call(c,n)&&n!==i&&m(c,n,{get:()=>r[n],enumerable:!(o=T(r,n))||o.enumerable});return c};var J=c=>S(m({},"__esModule",{value:!0}),c);var L={};$(L,{runSubmitVerdict:()=>N});module.exports=J(L);var y=require("fs"),w=require("path"),l=require("../../lib/logger"),u=require("../../lib/config"),x=require("../../lib/recording-tools"),V=require("../../lib/telemetry"),a=require("./actions"),e=require("./session-state");function k(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)"]}_(k,"deriveFixes");async function N(c){const{sessionId:r,sessionDir:i,verdictFile:o,actionsFile:n,verdictJson:C,projectDir:v}=c;let t;try{t=JSON.parse(C)}catch(s){return l.logger.debug(`submit-verdict: invalid JSON: ${s}`),{success:!1,message:"REJECTED: verdict is not valid JSON."}}if((0,e.getActiveVerificationId)(i)===void 0)return l.logger.debug("submit-verdict: no active verification cycle \u2014 rejecting spurious/duplicate submit"),{success:!1,message:"REJECTED: no active verification cycle. A verdict is recorded by the verification cycle that submitted it; this submit has none \u2014 the cycle already closed (the verdict was already recorded), or none was ever opened. If you are the MAIN agent relaying a delegated verifier's verdict, do NOT submit it yourself and do NOT open a new cycle \u2014 just report the verdict the verifier already recorded."};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(d=>!u.ALL_CYCLES.includes(d));if(s.length>0)return{success:!1,message:`REJECTED: unknown cycle name(s) in not_applicable_cycles: ${s.join(", ")}. Valid: ${u.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(v!==void 0&&(0,u.getVerificationStrict)((0,u.loadConfig)(v)))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=k(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(d=>` ${d.stopTool} (${d.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,y.mkdirSync)((0,w.dirname)(o),{recursive:!0}),(0,y.writeFileSync)(o,JSON.stringify(t,null,2))}catch(
|
|
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 l.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.setLastVerdictHadIssues)(i,t.status==="pass"&&Array.isArray(t.issues)&&t.issues.length>0),(0,e.clearPendingFixes)(i),(0,e.isRecordingRequired)(i)&&(0,e.setRecordingRequired)(i,!1);const E=(0,e.getActiveActivityId)(i),h=(0,e.getActiveFixId)(i);if(h){const s=Date.now(),d={...(0,a.baseFields)(n),type:"fix_end",timestamp:s,fix_id:h,activity_id:E,duration:(0,a.findDurationSinceLastAction)(n,"fix_start",s)};await(0,a.appendAction)(n,d),(0,e.clearActiveFix)(i),(0,e.setPhase)(i,"coding"),l.logger.debug(`fix-end (verdict): ${h}`)}const p=(0,e.getActiveVerificationId)(i),A=(0,e.getActiveTraceId)(i);if(p){const s=Date.now(),d={...(0,a.baseFields)(n),type:"verification_end",timestamp:s,verification_id:p,activity_id:E,trace_id:A,duration:(0,a.findDurationSinceLastAction)(n,"verification_start",s),status:t.status};await(0,a.appendAction)(n,d),(0,e.clearActiveVerification)(i),l.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:E,trace_id:A,verdict:R};if(await(0,a.appendAction)(n,D),await(0,V.trackVerdictWrite)(r,t.status,v),l.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 +1 @@
|
|
|
1
|
-
"use strict";var v=Object.defineProperty;var
|
|
1
|
+
"use strict";var v=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var y=Object.getOwnPropertyNames;var V=Object.prototype.hasOwnProperty;var x=(n,t)=>v(n,"name",{value:t,configurable:!0});var A=(n,t)=>{for(var e in t)v(n,e,{get:t[e],enumerable:!0})},_=(n,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of y(t))!V.call(n,a)&&a!==e&&v(n,a,{get:()=>t[a],enumerable:!(s=p(t,a))||s.enumerable});return n};var F=n=>_(v({},"__esModule",{value:!0}),n);var D={};A(D,{endVerification:()=>b,openFixCycleIfFixing:()=>w,startVerification:()=>E});module.exports=F(D);var I=require("crypto"),f=require("../../lib/logger"),r=require("./actions"),i=require("./session-state");async function E(n){const{sessionDir:t,actionsFile:e}=n,s=(0,i.getActiveActivityId)(t),a=(0,i.getActiveFixId)(t);if(a){const g=Date.now(),u={...(0,r.baseFields)(e),type:"fix_end",timestamp:g,fix_id:a,activity_id:s,duration:(0,r.findDurationSinceLastAction)(e,"fix_start",g)};await(0,r.appendAction)(e,u),(0,i.clearActiveFix)(t),f.logger.debug(`fix-end: ${a} (starting new verification)`)}const c=(0,i.getActiveVerificationId)(t);if(c){const g=(0,i.getActiveTraceId)(t);f.logger.debug(`ending previous verification ${c} before starting new one`);const u=Date.now(),l={...(0,r.baseFields)(e),type:"verification_end",timestamp:u,verification_id:c,activity_id:s,trace_id:g,duration:(0,r.findDurationSinceLastAction)(e,"verification_start",u)};await(0,r.appendAction)(e,l),(0,i.clearActiveVerification)(t)}const o=(0,I.randomUUID)(),d=(0,i.generateTraceId)(),m={...(0,r.baseFields)(e),type:"verification_start",timestamp:Date.now(),verification_id:o,activity_id:s,trace_id:d};return await(0,r.appendAction)(e,m),(0,i.setActiveVerification)(t,o,d),n.recordingEnabled&&((0,i.setRecordingRequired)(t,!0),(0,i.setRecordingActive)(t,!1)),n.intent==="fix"?(0,i.setVerifyIntent)(t,"fix"):(0,i.getLastVerdictStatus)(t)!=="fail"&&(0,i.clearVerifyIntent)(t),f.logger.debug(`verification-start: ${o} trace=${d} recording=${!!n.recordingEnabled} intent=${n.intent??"-"}`),{verificationId:o,traceId:d}}x(E,"startVerification");async function w(n){const{sessionDir:t,actionsFile:e}=n;if(!(0,i.isFailLikeVerdictStatus)((0,i.getLastVerdictStatus)(t))&&!(0,i.getLastVerdictHadIssues)(t))return;const s=(0,i.getActiveFixId)(t);if(s)return s;const a=(0,i.getActiveActivityId)(t),c=(0,I.randomUUID)(),o={...(0,r.baseFields)(e),type:"fix_start",timestamp:Date.now(),fix_id:c,activity_id:a};return await(0,r.appendAction)(e,o),(0,i.setActiveFix)(t,c),(0,i.setPhase)(t,"fixing"),f.logger.debug(`fix-start (edit after fail / pass-with-issues): ${c}`),c}x(w,"openFixCycleIfFixing");async function b(n){const{sessionDir:t,actionsFile:e}=n,s=(0,i.getActiveVerificationId)(t);if(!s)return{success:!1,message:"No active verification to end."};const a=(0,i.getActiveTraceId)(t),c=(0,i.getActiveActivityId)(t),o=Date.now(),d={...(0,r.baseFields)(e),type:"verification_end",timestamp:o,verification_id:s,activity_id:c,trace_id:a,duration:(0,r.findDurationSinceLastAction)(e,"verification_start",o)};return await(0,r.appendAction)(e,d),(0,i.clearActiveVerification)(t),f.logger.debug(`verification-end: ${s} trace=${a}`),{success:!0,verificationId:s,traceId:a,message:`Verification ${s} ended.`}}x(b,"endVerification");0&&(module.exports={endVerification,openFixCycleIfFixing,startVerification});
|
package/dist/lib/config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
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.12.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
|
+
"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 Bn={};de(Bn,{ALL_CYCLES:()=>Ee,CONFIG_TARGETS_BY_PRECEDENCE:()=>Re,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:()=>Be,getActiveCycles:()=>J,getAnalyticsEmitOnStopMinIntervalSeconds:()=>Rn,getAndroidDevToolsMcpEntry:()=>Ze,getAutoVerifyEnabled:()=>ie,getBackendDevToolsMcpEntry:()=>Je,getCaptureFileChangeset:()=>Tn,getClaudeOauthAccessEnabled:()=>an,getClaudeOauthAccessUsageTtlSeconds:()=>un,getCodexVerifierMode:()=>cn,getConfigLayerPaths:()=>w,getMaxChangesetBytes:()=>xn,getMaxRetries:()=>en,getMcpServerEntry:()=>Qe,getNodeDevToolsMcpEntry:()=>ze,getOTELEmitMinIntervalSeconds:()=>bn,getOTELEnsureMinIntervalSeconds:()=>pn,getOTELIdleTimeoutSeconds:()=>dn,getOTELPort:()=>gn,getPrivacyEnabled:()=>le,getRequiredToolsConfig:()=>Pe,getStatusLineEmitMinIntervalSeconds:()=>sn,getStatusLineRefreshInterval:()=>En,getStatusLineRenderDefault:()=>rn,getTargetConfigPath:()=>Oe,getTelemetryEnabled:()=>ce,getVerificationContextCommitDepth:()=>mn,getVerificationContextEnabled:()=>_n,getVerificationContextMaxBytes:()=>An,getVerificationContextSource:()=>Cn,getVerificationEnabled:()=>O,getVerificationMode:()=>In,getVerificationModel:()=>Ae,getVerificationStrict:()=>yn,isAnalyticsApiRequestEventsEnabled:()=>kn,isAnalyticsEmitOnStopEnabled:()=>jn,isAnalyticsEnabled:()=>wn,isAnalyticsStepEventsEnabled:()=>hn,isAnalyticsTurnEventsEnabled:()=>On,isAutoModeAllowlistEnabled:()=>ln,isCollectorConfigured:()=>R,isCycleEnabled:()=>De,isCyclePatternsActive:()=>Z,isIgnoredVerifyPath:()=>vn,isJobQueueEnabled:()=>nn,isOTELEnabled:()=>fn,isRecordingEnabled:()=>tn,isSessionStatusEnabled:()=>on,loadConfig:()=>c,requiresVerification:()=>Ne,resolveConfigTargetFromFlags:()=>he,resolveIgnoredVerifyPatterns:()=>x});module.exports=be(Bn);var E=require("fs"),b=require("path"),I=require("os"),D=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 x(n){const e=n.ignoredVerifyPatterns??[];return[...q,...e]}o(x,"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 D.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=we(n.claude,e.claude),t.codex=je(n.codex,e.codex),t.verification=xe(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 xe(n,e){if(!(n===void 0&&e===void 0))return{...n??{},...e??{}}}o(xe,"mergeVerificationConfig");function we(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(we,"mergeClaudeConfig");function je(n,e){if(n===void 0&&e===void 0)return;const t={...n??{},...e??{}};return(n?.verifier!==void 0||e?.verifier!==void 0)&&(t.verifier={...n?.verifier??{},...e?.verifier??{}}),t}o(je,"mergeCodexConfig");function w(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(w,"getConfigLayerPaths");const Re=["global","project","local"];function Oe(n,e){const t=w(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(Oe,"getTargetConfigPath");function he(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(he,"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 ke(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(ke,"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;ke(e,t.configPath,i)}return e??n}o(z,"applyEnvOverrides");function Be(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(Be,"findActiveEnvOverride");function c(n){const e=w(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 Se(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(Se,"globToRegExp");function C(n,e){const t=n.replace(/\\/g,"/");for(const r of e)if(Se(r).test(t))return!0;return!1}o(C,"matchesAny");function Le(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(Le,"getCycleBlock");function v(n,e){const t=Le(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=x(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 Ne(n,e){return J(n,e).length>0}o(Ne,"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 Pe(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(Pe,"getRequiredToolsConfig");const S="npx",Me="^0.12.0",L=["-y",`@ironbee-ai/devtools@${Me}`],Fe={TOOL_NAME_PREFIX:"bdt_",TOOL_INPUT_METADATA_ENABLE:"true"},Ve={PLATFORM:"node",TOOL_NAME_PREFIX:"ndt_",TOOL_INPUT_METADATA_ENABLE:"true"},Ue={PLATFORM:"backend",TOOL_NAME_PREFIX:"bedt_",TOOL_INPUT_METADATA_ENABLE:"true"},$e={PLATFORM:"android",TOOL_NAME_PREFIX:"adt_",TOOL_INPUT_METADATA_ENABLE:"true"},qe={BROWSER_DEVTOOLS_INSTALL_CHROMIUM:"true"},Ke={},Ye={},Xe={};function He(n){return ce(n)?{}:{TELEMETRY_ENABLE:"false"}}o(He,"buildTelemetryEnv");function Ge(n){return le(n)?{COLLECTOR_EVENTS_TOOL_DETAILS_ENABLE:"false",COLLECTOR_ARTIFACTS_ENABLE:"false"}:{}}o(Ge,"buildPrivacyEnv");function We(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(We,"buildOTELEnv");function m(n,e,t,r,i){const s=We(n,i),l=He(n),a=Ge(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 Qe(n){const e=c(n);return m(e,"browserDevTools",Fe,qe,"browser")}o(Qe,"getMcpServerEntry");function ze(n){const e=c(n);return m(e,"nodeDevTools",Ve,Ke,"node")}o(ze,"getNodeDevToolsMcpEntry");function Je(n){const e=c(n);return m(e,"backendDevTools",Ue,Ye,"backend")}o(Je,"getBackendDevToolsMcpEntry");function Ze(n){const e=c(n);return m(e,"androidDevTools",$e,Xe,"android")}o(Ze,"getAndroidDevToolsMcpEntry");function en(n){return typeof n.maxRetries=="number"&&n.maxRetries>0?n.maxRetries:Ce}o(en,"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 nn(n){const e=c(n);return p(e,e.jobQueue)}o(nn,"isJobQueueEnabled");function tn(n){const e=c(n);return p(e,e.recording)}o(tn,"isRecordingEnabled");function on(n){return p(n,n.statusLine)}o(on,"isSessionStatusEnabled");function rn(n){const e=n.statusLine;return e!==void 0&&e.renderDefault===!0}o(rn,"getStatusLineRenderDefault");function sn(n){const e=n.statusLine?.emitMinIntervalSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:10}o(sn,"getStatusLineEmitMinIntervalSeconds");const ee=60;function an(n){return n.claude?.oauthAccess?.enable!==!1}o(an,"getClaudeOauthAccessEnabled");function cn(n){return n.codex?.verifier?.mode==="main-agent"?"main-agent":"sub-agent"}o(cn,"getCodexVerifierMode");function ln(n){return n.claude?.autoModeAllowlist?.enable!==!1}o(ln,"isAutoModeAllowlistEnabled");function un(n){const e=n.claude?.oauthAccess?.usageTtlSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:ee}o(un,"getClaudeOauthAccessUsageTtlSeconds");const ne=15986,te=600,oe=30,re=0;function fn(n){return p(n,n.otel)}o(fn,"isOTELEnabled");function gn(n){const e=n.otel?.port;return typeof e=="number"&&Number.isInteger(e)&&e>0&&e<65536?e:ne}o(gn,"getOTELPort");function dn(n){const e=n.otel?.idleTimeoutSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>0?e:te}o(dn,"getOTELIdleTimeoutSeconds");function pn(n){const e=n.otel?.ensureMinIntervalSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:oe}o(pn,"getOTELEnsureMinIntervalSeconds");function bn(n){const e=n.otel?.emitMinIntervalSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:re}o(bn,"getOTELEmitMinIntervalSeconds");function En(n){const e=n.statusLine?.refreshInterval;if(typeof e=="number"&&Number.isFinite(e)&&e>=1)return e}o(En,"getStatusLineRefreshInterval");function p(n,e){return e!=null&&typeof e=="object"&&!Array.isArray(e)?e.enable!==!1:R(n)}o(p,"isFeatureEnabledWithCollectorAutoEnable");function Ln(n){return n==null||typeof n!="object"||Array.isArray(n)?!1:n.enable!==!1}o(Ln,"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)?!1:e.auto===!0}o(ie,"getAutoVerifyEnabled");function yn(n){const e=n.verification;return e==null||typeof e!="object"||Array.isArray(e)?!1:e.strict===!0}o(yn,"getVerificationStrict");const se=65536,ae=1;function _n(n){const e=n.verificationContext;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.enable!==!1}o(_n,"getVerificationContextEnabled");function Cn(n){return n.verificationContext?.source==="actions"?"actions":"git"}o(Cn,"getVerificationContextSource");function mn(n){const e=n.verificationContext?.commitDepth;return typeof e=="number"&&Number.isFinite(e)&&e>=0?Math.floor(e):ae}o(mn,"getVerificationContextCommitDepth");function An(n){const e=n.verificationContext?.maxBytes;return typeof e=="number"&&Number.isFinite(e)&&e>0?Math.floor(e):se}o(An,"getVerificationContextMaxBytes");function vn(n,e){const t=x(n);return t.length>0&&C(e,t)}o(vn,"isIgnoredVerifyPath");function In(n){return O(n)?ie(n)?"enforce":"assist":"monitor"}o(In,"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 N=65536;function Tn(n){const e=n.fileChange;return!e||typeof e!="object"||Array.isArray(e)?!1:e.captureChangeset===!0}o(Tn,"getCaptureFileChangeset");function xn(n){const e=n.fileChange;if(!e||typeof e!="object"||Array.isArray(e))return N;const t=e.maxChangesetBytes;return typeof t!="number"||!Number.isFinite(t)||t<=0?N:Math.floor(t)}o(xn,"getMaxChangesetBytes");function wn(n){const e=c(n);return p(e,e.analytics)}o(wn,"isAnalyticsEnabled");function jn(n){const t=c(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!0:t.emitOnStop!==!1}o(jn,"isAnalyticsEmitOnStopEnabled");function Rn(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(Rn,"getAnalyticsEmitOnStopMinIntervalSeconds");function On(n){const t=c(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!1:t.emitTurnEvents===!0}o(On,"isAnalyticsTurnEventsEnabled");function hn(n){const t=c(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!1:t.emitStepEvents===!0}o(hn,"isAnalyticsStepEventsEnabled");function kn(n){const t=c(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!0:t.emitApiRequestEvents!==!1}o(kn,"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,getCodexVerifierMode,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=8;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,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
|
+
"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:()=>l,groupRank:()=>c,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","codex"]),s=["general","verification","verificationContext","browser","node","backend","android","collector","recording","jobQueue","analytics","statusLine","claude","codex","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",codex:"Codex",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 l(e){const t=e.indexOf(".");return t===-1?"general":e.slice(0,t)}n(l,"groupOf");function w(e){return f[e]??e}n(w,"groupTitle");function c(e){const t=s.indexOf(e);return t===-1?s.length:t}n(c,"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). Default FALSE \u2014 assist is the default mode (the safer default): 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. Opt into full enforcement with true (blocking Stop gate + skill/rule installed).",def:"false",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:"codex.verifier.mode",type:"string",editor:"enum",enumValues:["sub-agent","main-agent"],description:'How the Codex verification cycle is driven (Codex-only). "sub-agent" (default) delegates to the ironbee-verifier custom agent (per-agent MCP, SubagentStart bridge, slim delegation skill/rule/command). "main-agent" makes the MAIN agent drive the devtools tools directly (session-level [mcp_servers.*], no verifier agent, inline skill/rule/command) \u2014 the Cursor-style fallback for when Codex\'s sub-agent machinery regresses. Re-renders the Codex client. Toggle via `ironbee codex verifier mode <sub-agent|main-agent>`.',def:"sub-agent",artifactAffecting:!0},{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=c(l(e.path)),i=c(l(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});
|