@ironbee-ai/cli 0.22.0 → 0.23.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/assets/auth.html +79 -0
- package/dist/clients/claude/hooks/require-verification.js +5 -5
- package/dist/clients/codex/hooks/require-verification.js +3 -3
- package/dist/clients/cursor/hooks/require-verification.js +5 -5
- package/dist/commands/import.js +4 -4
- package/dist/commands/login.js +2 -2
- package/dist/lib/auth.js +5 -5
- package/dist/lib/collector.js +1 -1
- package/dist/lib/config.js +1 -1
- package/dist/tui/config/schema.js +1 -1
- package/package.json +1 -1
- package/dist/assets/login.html +0 -93
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.23.0 (2026-06-13)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
* **auth:** add OAuth support ([#23](https://github.com/ironbee-ai/ironbee-cli/issues/23)) ([20b650c](https://github.com/ironbee-ai/ironbee-cli/commit/20b650c75ca1b8c77cf7cc21dfa06a6b9a103532))
|
|
8
|
+
|
|
3
9
|
## 0.22.0 (2026-06-12)
|
|
4
10
|
|
|
5
11
|
### Features
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<title>{{TITLE}} — IronBee</title>
|
|
6
|
+
<style>
|
|
7
|
+
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
8
|
+
body {
|
|
9
|
+
font-family: system-ui, -apple-system, sans-serif;
|
|
10
|
+
display: flex;
|
|
11
|
+
align-items: center;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
min-height: 100vh;
|
|
14
|
+
background: #0f0f11;
|
|
15
|
+
color: #e5e5e5;
|
|
16
|
+
}
|
|
17
|
+
.container {
|
|
18
|
+
display: flex;
|
|
19
|
+
flex-direction: column;
|
|
20
|
+
align-items: center;
|
|
21
|
+
gap: 16px;
|
|
22
|
+
max-width: 840px;
|
|
23
|
+
padding: 2.5rem;
|
|
24
|
+
text-align: center;
|
|
25
|
+
}
|
|
26
|
+
.logo {
|
|
27
|
+
width: 288px;
|
|
28
|
+
height: 288px;
|
|
29
|
+
opacity: 0.95;
|
|
30
|
+
}
|
|
31
|
+
h1 {
|
|
32
|
+
font-size: 1.6rem;
|
|
33
|
+
font-weight: 700;
|
|
34
|
+
color: #e5e5e5;
|
|
35
|
+
letter-spacing: -0.3px;
|
|
36
|
+
}
|
|
37
|
+
p {
|
|
38
|
+
color: #888;
|
|
39
|
+
font-size: 0.9rem;
|
|
40
|
+
line-height: 1.6;
|
|
41
|
+
}
|
|
42
|
+
</style>
|
|
43
|
+
</head>
|
|
44
|
+
<body>
|
|
45
|
+
<div class="container">
|
|
46
|
+
<svg class="logo" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg" aria-label="IronBee">
|
|
47
|
+
<path d="M217.557 138.711C211.185 166.725 218.839 188.038 224.039 201.771L249.307 154.531L275.674 201.771C285.561 179.579 286.328 161.013 281.167 135.964C277.431 117.837 259.744 95.3889 249.307 84C241.91 92.6058 222.355 117.618 217.557 138.711Z" fill="url(#g0)"/>
|
|
48
|
+
<path d="M249.527 416C223.951 394.731 206.425 358.067 202.396 343.052L249.527 381.394L272.378 362.937L295.559 343.052C290.988 371.089 262.417 403.805 249.527 416Z" fill="url(#g1)"/>
|
|
49
|
+
<path d="M220.854 231.434L250.077 171.12L279.629 231.434L250.077 256.153L220.854 231.434Z" fill="url(#g2)"/>
|
|
50
|
+
<path d="M298.525 286.804C302.568 301.218 299.258 322.399 297.097 331.188L273.587 350.303L249.857 369.749L225.907 349.754L202.397 331.188C197.387 320.465 200.31 297.131 202.397 286.804L249.857 324.486L298.525 286.804Z" fill="url(#g3)"/>
|
|
51
|
+
<path d="M249.856 313.609L203.495 275.268C203.495 263.315 211.552 247.29 215.58 240.771L249.856 267.028L284.573 240.771C291.955 248.066 296.071 266.809 297.207 275.268L249.856 313.609Z" fill="url(#g4)"/>
|
|
52
|
+
<path d="M215.909 165.298C215.36 179.579 220.853 193.752 224.039 201.771L236.563 178.481L249.307 154.531L275.674 201.881C280.947 190.785 284.902 174.526 284.133 167.275C281.277 147.061 274.136 138.052 264.138 125.638C255.679 132.01 244.847 132.141 235.355 125.638C223.38 137.613 216.568 156.289 215.909 165.298Z" fill="url(#g5)" fill-opacity="0.7"/>
|
|
53
|
+
<path d="M249.856 347.996L202.396 286.804L249.856 324.486L298.525 286.804L249.856 347.996Z" fill="#333941" fill-opacity="0.64"/>
|
|
54
|
+
<path d="M249.527 292.296L215.58 240.771L249.857 267.028L284.573 240.771L249.527 292.296Z" fill="#333941" fill-opacity="0.35"/>
|
|
55
|
+
<path d="M249.419 404.685L202.396 343.053L249.419 381.614L295.559 343.053L249.419 404.685Z" fill="#0F0F0F" fill-opacity="0.1"/>
|
|
56
|
+
<path d="M285.482 209.139C297.06 183.136 300.205 166.929 294.24 132.4L346.304 224.989L319.38 218.541L350.314 284.253C319.826 267.918 305.852 251.479 285.482 209.139Z" fill="url(#g6)"/>
|
|
57
|
+
<path d="M214.785 209.139C203.206 183.136 200.062 166.929 206.027 132.4L153.963 224.989L180.887 218.541L149.953 284.253C180.44 267.918 194.414 251.479 214.785 209.139Z" fill="url(#g7)"/>
|
|
58
|
+
<path d="M458.055 281.287L306.25 134.086L375.851 242.958L344.516 235.599L359.745 289.281C390.46 298.849 431.254 294.285 458.055 281.287Z" fill="url(#g8)"/>
|
|
59
|
+
<path d="M42.2112 281.287L194.017 134.086L124.415 242.958L155.75 235.599L140.521 289.281C109.807 298.849 69.0124 294.285 42.2112 281.287Z" fill="url(#g9)"/>
|
|
60
|
+
<path d="M155.707 235.608C120.279 262.873 94.8569 272.188 42.5488 281.311C69.9036 294.823 110.553 298.339 140.546 289.221L155.707 235.608Z" fill="black" fill-opacity="0.16"/>
|
|
61
|
+
<path d="M344.558 235.608C380.054 262.765 405.526 272.042 457.935 281.129C430.527 294.588 389.799 298.089 359.748 289.007L344.558 235.608Z" fill="black" fill-opacity="0.16"/>
|
|
62
|
+
<defs>
|
|
63
|
+
<linearGradient id="g0" x1="248.978" y1="84" x2="248.978" y2="416" gradientUnits="userSpaceOnUse"><stop stop-color="#E5E5E5"/><stop offset="1" stop-color="#272F39"/></linearGradient>
|
|
64
|
+
<linearGradient id="g1" x1="248.978" y1="84" x2="248.978" y2="416" gradientUnits="userSpaceOnUse"><stop stop-color="#E5E5E5"/><stop offset="1" stop-color="#272F39"/></linearGradient>
|
|
65
|
+
<linearGradient id="g2" x1="250.032" y1="171.12" x2="250.032" y2="369.749" gradientUnits="userSpaceOnUse"><stop stop-color="#D9D9D9"/><stop offset="1" stop-color="#272F39"/></linearGradient>
|
|
66
|
+
<linearGradient id="g3" x1="250.032" y1="171.12" x2="250.032" y2="369.749" gradientUnits="userSpaceOnUse"><stop stop-color="#D9D9D9"/><stop offset="1" stop-color="#272F39"/></linearGradient>
|
|
67
|
+
<linearGradient id="g4" x1="250.351" y1="240.771" x2="250.351" y2="313.609" gradientUnits="userSpaceOnUse"><stop stop-color="#D9D9D9"/><stop offset="1" stop-color="#272F39"/></linearGradient>
|
|
68
|
+
<linearGradient id="g5" x1="250.05" y1="125.638" x2="250.05" y2="201.881" gradientUnits="userSpaceOnUse"><stop stop-color="#B1B1B2"/><stop offset="1" stop-color="#343B43"/></linearGradient>
|
|
69
|
+
<linearGradient id="g6" x1="315.879" y1="132.019" x2="318.569" y2="284.812" gradientUnits="userSpaceOnUse"><stop stop-color="#D9D9D9"/><stop offset="1" stop-color="#454B54"/></linearGradient>
|
|
70
|
+
<linearGradient id="g7" x1="184.387" y1="132.019" x2="181.698" y2="284.812" gradientUnits="userSpaceOnUse"><stop stop-color="#D9D9D9"/><stop offset="1" stop-color="#454B54"/></linearGradient>
|
|
71
|
+
<linearGradient id="g8" x1="380.834" y1="132.773" x2="383.683" y2="294.632" gradientUnits="userSpaceOnUse"><stop stop-color="#D9D9D9"/><stop offset="1" stop-color="#4A5159"/></linearGradient>
|
|
72
|
+
<linearGradient id="g9" x1="119.433" y1="132.773" x2="116.583" y2="294.632" gradientUnits="userSpaceOnUse"><stop stop-color="#D9D9D9"/><stop offset="1" stop-color="#4A5159"/></linearGradient>
|
|
73
|
+
</defs>
|
|
74
|
+
</svg>
|
|
75
|
+
<h1>{{TITLE}}</h1>
|
|
76
|
+
{{BODY}}
|
|
77
|
+
</div>
|
|
78
|
+
</body>
|
|
79
|
+
</html>
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
"use strict";var u=Object.defineProperty;var V=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var K=Object.prototype.hasOwnProperty;var
|
|
1
|
+
"use strict";var u=Object.defineProperty;var V=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var K=Object.prototype.hasOwnProperty;var S=(o,t)=>u(o,"name",{value:t,configurable:!0});var L=(o,t)=>{for(var s in t)u(o,s,{get:t[s],enumerable:!0})},j=(o,t,s,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let e of F(t))!K.call(o,e)&&e!==s&&u(o,e,{get:()=>t[e],enumerable:!(n=V(t,e))||n.enumerable});return o};var B=o=>j(u({},"__esModule",{value:!0}),o);var q={};L(q,{run:()=>M});module.exports=B(q);var w=require("crypto"),i=require("../../../hooks/core/session-state"),R=require("../../../hooks/core/actions"),$=require("../../../hooks/core/activity"),O=require("../../../hooks/core/verification-lifecycle"),E=require("../../../hooks/core/verification-context"),U=require("../../../lib/config"),A=require("../../../lib/recording-tools"),f=require("../../../lib/logger"),v=require("../util"),x=require("../../../lib/stdin");const D="browser-devtools";async function M(o,t){const s=t?.soft===!0;let n;try{n=JSON.parse((0,x.readStdin)())}catch(y){f.logger.debug(`failed to parse stdin: ${y}`),process.exit(0)}const e=n.session_id??"default",r=`${o}/.ironbee/sessions/${e}`;(0,f.setLogFile)(`${r}/session.log`);const _=`${r}/actions.jsonl`,h=(0,i.getActiveVerificationId)(r);!h&&!s&&(process.stderr.write(`BLOCKED: You must start a verification cycle before using devtools tools (browser-devtools / node-devtools / backend-devtools / android-devtools).
|
|
2
2
|
|
|
3
3
|
Start verification first:
|
|
4
4
|
echo '{"session_id":"${e}"}' | ironbee hook verification-start
|
|
5
5
|
|
|
6
6
|
Then use the verification tools for the active cycle(s) \u2014 bdt_* for browser, ndt_* for node, bedt_* for backend, adt_* for android.
|
|
7
|
-
`),process.exit(2));const b=
|
|
7
|
+
`),process.exit(2));const b=n.tool_name??"",l=(0,A.recordingToolsForServer)((0,v.extractMcpServerName)(b));!s&&l!==null&&(0,i.isRecordingRequired)(r)&&!(0,i.isRecordingActive)(r)&&!b.endsWith(l.startTool)&&(process.stderr.write(`BLOCKED: Recording is required but not started.
|
|
8
8
|
|
|
9
9
|
1. Start recording NOW:
|
|
10
|
-
Use mcp__${
|
|
10
|
+
Use mcp__${l.server}__${l.startTool}
|
|
11
11
|
|
|
12
12
|
2. Run the verification flow for the active cycle(s)
|
|
13
13
|
|
|
14
14
|
3. **Stop recording BEFORE submitting verdict:**
|
|
15
|
-
Use mcp__${
|
|
15
|
+
Use mcp__${l.server}__${l.stopTool}
|
|
16
16
|
submit-verdict will reject with "recording is still active" if you skip this.
|
|
17
|
-
`),process.exit(2)),await(0,$.startActivity)({sessionDir:r,actionsFile:_,source:"pre_tool_use"});let d=h;
|
|
17
|
+
`),process.exit(2)),await(0,$.startActivity)({sessionDir:r,actionsFile:_,source:"pre_tool_use"});let d=h;s&&!d&&(d=(await(0,O.startVerification)({sessionId:e,sessionDir:r,actionsFile:_,recordingEnabled:!1})).verificationId);const N=(0,i.getActiveTraceId)(r),p=(0,i.getActiveActivityId)(r),C=(0,R.resolveProjectName)(o),g=[`prj:${C}`,`sid:${e}`];p&&g.push(`aid:${p}`),d&&g.push(`vid:${d}`);const P=`ironbee=${g.join(";")}`,c=(0,U.loadConfig)(o),I={...n.tool_input??{}},a={projectName:C,sessionId:e,activityId:p,verificationId:d,traceId:N,traceState:P,toolCallId:(0,w.randomUUID)()};n.tool_use_id&&(a.toolUseId=n.tool_use_id),a.mcpServer=(0,v.extractMcpServerName)(n.tool_name)??D;const T=(0,i.getUserEmail)(r);T&&(a.userEmail=T),c.collector?.url&&(a.collectorUrl=c.collector.url),c.collector?.oauthToken?a.collectorOAuthToken=c.collector.oauthToken:c.collector?.apiKey&&(a.collectorApiKey=c.collector.apiKey),I._metadata=a;const m={hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"allow",updatedInput:I}},k=(0,E.buildVerificationContextOnceForCycle)({projectDir:o,sessionId:e,sessionDir:r,activeVerificationId:d,config:c});k.length>0&&m.hookSpecificOutput&&(m.hookSpecificOutput.additionalContext=k),process.stdout.write(JSON.stringify(m)),process.exit(0)}S(M,"run");0&&(module.exports={run});
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
"use strict";var u=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var K=Object.prototype.hasOwnProperty;var
|
|
1
|
+
"use strict";var u=Object.defineProperty;var j=Object.getOwnPropertyDescriptor;var F=Object.getOwnPropertyNames;var K=Object.prototype.hasOwnProperty;var R=(o,e)=>u(o,"name",{value:e,configurable:!0});var q=(o,e)=>{for(var s in e)u(o,s,{get:e[s],enumerable:!0})},B=(o,e,s,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of F(e))!K.call(o,t)&&t!==s&&u(o,t,{get:()=>e[t],enumerable:!(n=j(e,t))||n.enumerable});return o};var J=o=>B(u({},"__esModule",{value:!0}),o);var H={};q(H,{run:()=>L});module.exports=J(H);var C=require("crypto"),$=require("../../../hooks/core/activity"),i=require("../../../hooks/core/session-state"),x=require("../../../hooks/core/actions"),N=require("../../../hooks/core/verification-lifecycle"),E=require("../../../hooks/core/verification-context"),O=require("../../../lib/config"),m=require("../../../lib/logger"),U=require("../../../lib/recording-tools"),A=require("../../../lib/stdin"),f=require("../util");async function L(o,e){const s=e?.soft===!0,n=(0,f.parseCodexHookStdin)((0,A.readStdin)()),t=n.session_id??"default",r=`${o}/.ironbee/sessions/${t}`,y=`${r}/actions.jsonl`;(0,m.setLogFile)(`${r}/session.log`);const b=(0,i.getActiveVerificationId)(r);if(!b&&!s){const p=`BLOCKED: You must start a verification cycle before using devtools tools.
|
|
2
2
|
|
|
3
3
|
Start verification first:
|
|
4
4
|
echo '{"session_id":"${t}"}' | ironbee hook verification-start
|
|
5
5
|
|
|
6
|
-
Then use the verification tools for the active cycle(s) \u2014 mcp__browser-devtools__bdt_* for browser, mcp__node-devtools__ndt_* for node, mcp__backend-devtools__bedt_* for backend, mcp__android-devtools__adt_* for android.`;process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:p}})),process.exit(0);return}const g=n.tool_name??"",h=(0,
|
|
6
|
+
Then use the verification tools for the active cycle(s) \u2014 mcp__browser-devtools__bdt_* for browser, mcp__node-devtools__ndt_* for node, mcp__backend-devtools__bedt_* for backend, mcp__android-devtools__adt_* for android.`;process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:p}})),process.exit(0);return}const g=n.tool_name??"",h=(0,f.extractCodexMcpServer)(g),c=(0,U.recordingToolsForServer)(h),D=c!==null?(0,f.canonicalizeCodexToolName)(g.split("__").pop()??""):"";if(!s&&c!==null&&(0,i.isRecordingRequired)(r)&&!(0,i.isRecordingActive)(r)&&D!==c.startTool){const p=`BLOCKED: Recording is required but not started.
|
|
7
7
|
|
|
8
8
|
1. Start recording NOW:
|
|
9
9
|
Use mcp__${c.server}__${c.startTool}
|
|
@@ -12,4 +12,4 @@ Then use the verification tools for the active cycle(s) \u2014 mcp__browser-devt
|
|
|
12
12
|
|
|
13
13
|
3. **Stop recording BEFORE submitting verdict:**
|
|
14
14
|
Use mcp__${c.server}__${c.stopTool}
|
|
15
|
-
submit-verdict will reject with "recording is still active" if you skip this.`;process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:p}})),process.exit(0);return}await(0,$.startActivity)({sessionDir:r,actionsFile:y,source:"pre_tool_use"});let
|
|
15
|
+
submit-verdict will reject with "recording is still active" if you skip this.`;process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:p}})),process.exit(0);return}await(0,$.startActivity)({sessionDir:r,actionsFile:y,source:"pre_tool_use"});let l=b;s&&!l&&(l=(await(0,N.startVerification)({sessionId:t,sessionDir:r,actionsFile:y,recordingEnabled:!1})).verificationId);const V=(0,i.getActiveTraceId)(r),_=(0,i.getActiveActivityId)(r),k=(0,x.resolveProjectName)(o),v=[`prj:${k}`,`sid:${t}`];_&&v.push(`aid:${_}`),l&&v.push(`vid:${l}`);const P=`ironbee=${v.join(";")}`,a=(0,O.loadConfig)(o),S={...n.tool_input&&typeof n.tool_input=="object"?n.tool_input:{}},d={projectName:k,sessionId:t,activityId:_,verificationId:l,traceId:V,traceState:P,toolCallId:(0,C.randomUUID)()};n.tool_use_id&&(d.toolUseId=n.tool_use_id),d.mcpServer=h??"browser-devtools";const T=(0,i.getUserEmail)(r);T&&(d.userEmail=T),a.collector?.url&&(d.collectorUrl=a.collector.url),a.collector?.oauthToken?d.collectorOAuthToken=a.collector.oauthToken:a.collector?.apiKey&&(d.collectorApiKey=a.collector.apiKey),S._metadata=d;const w={hookEventName:"PreToolUse",permissionDecision:"allow",updatedInput:S},I=(0,E.buildVerificationContextOnceForCycle)({projectDir:o,sessionId:t,sessionDir:r,activeVerificationId:l,config:a});I.length>0&&(w.additionalContext=I),process.stdout.write(JSON.stringify({hookSpecificOutput:w})),m.logger.debug(`require-verification: allowed ${g} with _metadata`),process.exit(0)}R(L,"run");0&&(module.exports={run});
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
"use strict";var f=Object.defineProperty;var V=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var B=Object.prototype.hasOwnProperty;var
|
|
1
|
+
"use strict";var f=Object.defineProperty;var V=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var B=Object.prototype.hasOwnProperty;var w=(o,t)=>f(o,"name",{value:t,configurable:!0});var F=(o,t)=>{for(var c in t)f(o,c,{get:t[c],enumerable:!0})},K=(o,t,c,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of x(t))!B.call(o,r)&&r!==c&&f(o,r,{get:()=>t[r],enumerable:!(s=V(t,r))||s.enumerable});return o};var j=o=>K(f({},"__esModule",{value:!0}),o);var W={};F(W,{run:()=>L});module.exports=j(W);var h=require("crypto"),e=require("../../../hooks/core/session-state"),I=require("../../../hooks/core/actions"),k=require("../../../hooks/core/activity"),O=require("../../../hooks/core/verification-lifecycle"),S=require("../../../lib/config"),U=require("../../../lib/recording-tools"),g=require("../../../lib/logger"),E=require("../../../lib/stdin");const R={"MCP:bdt_":"browser-devtools","MCP:ndt_":"node-devtools","MCP:bedt_":"backend-devtools","MCP:adt_":"android-devtools"},J="browser-devtools";async function L(o,t){const c=t?.soft===!0;let s;try{s=JSON.parse((0,E.readStdin)())}catch(n){g.logger.debug(`failed to parse stdin: ${n}`);const N={permission:"allow"};process.stdout.write(JSON.stringify(N)),process.exit(0);return}const r=s.conversation_id??"default",i=`${o}/.ironbee/sessions/${r}`;(0,g.setLogFile)(`${i}/session.log`);const C=`${i}/actions.jsonl`,P=(0,e.getActiveVerificationId)(i);if(!P&&!c){const n={permission:"deny",agent_message:`BLOCKED: You must start a verification cycle before using devtools tools (browser-devtools / node-devtools / backend-devtools / android-devtools).
|
|
2
2
|
|
|
3
3
|
Start verification first:
|
|
4
4
|
echo '{"session_id":"${r}"}' | ironbee hook verification-start
|
|
5
5
|
|
|
6
|
-
Then use the verification tools for the active cycle(s) \u2014 MCP:bdt_* for browser, MCP:ndt_* for node, MCP:bedt_* for backend, MCP:adt_* for android.`};process.stdout.write(JSON.stringify(n)),process.exit(2);return}const p=s.tool_name??"",m=p.startsWith("MCP:")?p.slice(4):"",
|
|
6
|
+
Then use the verification tools for the active cycle(s) \u2014 MCP:bdt_* for browser, MCP:ndt_* for node, MCP:bedt_* for backend, MCP:adt_* for android.`};process.stdout.write(JSON.stringify(n)),process.exit(2);return}const p=s.tool_name??"",m=p.startsWith("MCP:")?p.slice(4):"",u=m?(0,U.recordingToolsForBareTool)(m):null;if(!c&&u!==null&&(0,e.isRecordingRequired)(i)&&!(0,e.isRecordingActive)(i)&&m!==u.startTool){const n={permission:"deny",agent_message:`BLOCKED: Recording is required but not started.
|
|
7
7
|
|
|
8
8
|
1. Start recording NOW:
|
|
9
|
-
Use MCP:${
|
|
9
|
+
Use MCP:${u.startTool}
|
|
10
10
|
|
|
11
11
|
2. Run the verification flow for the active cycle(s)
|
|
12
12
|
|
|
13
13
|
3. **Stop recording BEFORE submitting verdict:**
|
|
14
|
-
Use MCP:${
|
|
15
|
-
submit-verdict will reject with "recording is still active" if you skip this.`};process.stdout.write(JSON.stringify(n)),process.exit(2);return}await(0,
|
|
14
|
+
Use MCP:${u.stopTool}
|
|
15
|
+
submit-verdict will reject with "recording is still active" if you skip this.`};process.stdout.write(JSON.stringify(n)),process.exit(2);return}await(0,k.startActivity)({sessionDir:i,actionsFile:C,source:"pre_tool_use"});let a=P;c&&!a&&(a=(await(0,O.startVerification)({sessionId:r,sessionDir:i,actionsFile:C,recordingEnabled:!1})).verificationId);const M=(0,e.getActiveTraceId)(i),v=(0,e.getActiveActivityId)(i),b=(0,I.resolveProjectName)(o),_=[`prj:${b}`,`sid:${r}`];v&&_.push(`aid:${v}`),a&&_.push(`vid:${a}`);const $=`ironbee=${_.join(";")}`,l=(0,S.loadConfig)(o),y={...s.tool_input??{}},d={projectName:b,sessionId:r,activityId:v,verificationId:a,traceId:M,traceState:$,toolCallId:(0,h.randomUUID)()};s.tool_use_id&&(d.toolUseId=s.tool_use_id),d.mcpServer=(()=>{for(const n of Object.keys(R))if(p.startsWith(n))return R[n];return J})();const T=(0,e.getUserEmail)(i);T&&(d.userEmail=T),l.collector?.url&&(d.collectorUrl=l.collector.url),l.collector?.oauthToken?d.collectorOAuthToken=l.collector.oauthToken:l.collector?.apiKey&&(d.collectorApiKey=l.collector.apiKey),y._metadata=d;const A={permission:"allow",updated_input:y};process.stdout.write(JSON.stringify(A)),process.exit(0)}w(L,"run");0&&(module.exports={run});
|
package/dist/commands/import.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var x=Object.create;var g=Object.defineProperty;var _=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var k=Object.getPrototypeOf,N=Object.prototype.hasOwnProperty;var l=(e,o)=>g(e,"name",{value:o,configurable:!0});var P=(e,o)=>{for(var n in o)g(e,n,{get:o[n],enumerable:!0})},I=(e,o,n,s)=>{if(o&&typeof o=="object"||typeof o=="function")for(let r of j(o))!N.call(e,r)&&r!==n&&g(e,r,{get:()=>o[r],enumerable:!(s=_(o,r))||s.enumerable});return e};var O=(e,o,n)=>(n=e!=null?x(k(e)):{},I(o||!e||!e.__esModule?g(n,"default",{value:e,enumerable:!0}):n,e)),F=e=>I(g({},"__esModule",{value:!0}),e);var K={};P(K,{importCommand:()=>U,parseFlags:()=>$,promptYesNo:()=>R});module.exports=F(K);var y=require("commander"),w=require("fs"),h=require("path"),M=O(require("readline")),t=require("../lib/output"),S=require("../lib/config"),C=require("../lib/collector"),E=require("../lib/logger"),i=require("../import");const B=4,D=1,z=32,U=new y.Command("import").description("Import historical Claude Code + Codex sessions to the IronBee Collector").option("--since <duration>","import sessions started within the given duration (e.g. 30d, 2w, 6m, 12h)").option("--from <iso-date>","explicit start date (e.g. 2025-04-01)").option("--to <iso-date>","explicit end date (defaults to now)").option("--transcript <path>","import a single transcript .jsonl file (Claude or Codex \u2014 detected from path)").option("--projects <paths>","comma-separated absolute project paths").option("--all-projects","import sessions from every project under ~/.claude/projects/ and ~/.codex/sessions/").option("--dry-run","print the summary and exit without sending events").option("--yes","skip the interactive confirm prompt").option("--force","do not skip sessions with existing .ironbee/sessions/<id>/ directories").option("--concurrency <n>","number of sessions to import in parallel").option("--batch-size <n>","events per collector POST (default: 100). Set to 1 to isolate which event a 400 rejects.").action(async e=>{let o;try{o=$(e)}catch(c){t.log.error(c instanceof Error?c.message:String(c)),process.exit(1)}(0,C.getCollectorTarget)(process.cwd())===null&&(t.log.error("Collector is not configured. ironbee import has no destination to send events to."),t.log.blank(),t.log.dim("To configure, add a collector section to ~/.ironbee/config.json (or your project's .ironbee/config.json):"),t.log.blank(),console.log(t.pc.dim(` {
|
|
2
2
|
"collector": {
|
|
3
3
|
"url": "https://your-collector.example.com",
|
|
4
|
-
"
|
|
4
|
+
"oauthToken": "<from \`ironbee login\`>"
|
|
5
5
|
}
|
|
6
|
-
}`)),t.log.blank(),t.log.dim("
|
|
7
|
-
Received SIGINT \u2014 finishing in-flight sessions then exiting...`),p=!0});const b=await(0,
|
|
6
|
+
}`)),t.log.blank(),t.log.dim("Required: `url` (non-empty), `enable !== false`, and AT LEAST ONE of `oauthToken` (preferred \u2014 `ironbee login` writes this) or `apiKey` (shared-key path for CI / deployment tooling). The IRONBEE_COLLECTOR=false env override also disables."),process.exit(1));const s=(0,i.findTranscripts)(o.scope),r=(0,i.applyTimeRange)(s,o.timeRange);r.length===0&&(t.log.warn("No transcripts found matching the given scope and time range."),process.exit(0)),t.log.info(`Scanning ${r.length} transcript(s)...`);const d=(0,i.estimateImport)({targets:r,timeRange:o.timeRange,concurrency:o.concurrency,force:o.force});q(d,o.dryRun),o.dryRun&&process.exit(0),d.toImportCount===0&&(t.log.warn("Nothing to import (all sessions already tracked). Use --force to re-import."),process.exit(0)),o.yes||await R("Proceed?")||(t.log.info("Aborted."),process.exit(0));const m=r.filter(c=>!Y(c,o.force)),a=new i.ProgressReporter(m.length);let p=!1;process.on("SIGINT",()=>{t.log.warn(`
|
|
7
|
+
Received SIGINT \u2014 finishing in-flight sessions then exiting...`),p=!0});const b=await(0,i.runConcurrentPool)({items:m,concurrency:o.concurrency,shouldCancel:l(()=>p,"shouldCancel"),onStart:l((c,f)=>{a.onSessionStart(c.sessionId,f)},"onStart"),onComplete:l((c,f,T)=>{a.onSessionComplete(c,T)},"onComplete"),process:l(async c=>{try{return await(0,i.importSession)({target:c,force:o.force,batchSize:o.batchSize})}catch(f){return{sessionId:c.sessionId,status:"failed",eventsSent:(0,i.emptyEventCounts)(),reason:f instanceof Error?f.message:String(f)}}},"process")});a.finalSummary(),b.filter(c=>c.status==="failed").length>0&&process.exit(1)});function $(e){if([e.transcript!==void 0?1:0,e.projects!==void 0?1:0,e.allProjects===!0?1:0].reduce((a,p)=>a+p,0)>1)throw new Error("--transcript, --projects, and --all-projects are mutually exclusive");let n;if(e.transcript!==void 0)n={kind:"transcript",path:(0,h.resolve)(e.transcript)};else if(e.projects!==void 0){const a=e.projects.split(",").map(p=>p.trim()).filter(p=>p.length>0).map(p=>(0,h.resolve)(p));if(a.length===0)throw new Error("--projects must list at least one path");n={kind:"projects",paths:a}}else e.allProjects===!0?n={kind:"all-projects"}:n={kind:"current-project"};if(e.since!==void 0&&e.from!==void 0)throw new Error("--since and --from are mutually exclusive");let s=null;const r=Date.now();if(e.since!==void 0){const a=(0,i.parseSinceDuration)(e.since);if(a===null)throw new Error(`Invalid --since value: "${e.since}". Expected forms: 30d, 2w, 6m, 12h.`);s=(0,i.buildTimeRange)({sinceMs:a,nowMs:r})}else if(e.from!==void 0){const a=(0,i.parseIsoDate)(e.from);if(a===null)throw new Error(`Invalid --from value: "${e.from}". Expected ISO date (e.g. 2025-04-01).`);let p;if(e.to!==void 0){const b=(0,i.parseIsoDate)(e.to);if(b===null)throw new Error(`Invalid --to value: "${e.to}". Expected ISO date.`);p=b}s=(0,i.buildTimeRange)({fromMs:a,toMs:p,nowMs:r})}const d=A(e.concurrency),m=L(e.batchSize);return{scope:n,timeRange:s,dryRun:e.dryRun===!0,yes:e.yes===!0,force:e.force===!0,concurrency:d,batchSize:m}}l($,"parseFlags");function L(e){if(e===void 0)return null;const o=parseInt(e,10);if(!Number.isFinite(o)||o<1)throw new Error(`Invalid --batch-size value: "${e}". Must be an integer >= 1.`);return o}l(L,"resolveBatchSize");function A(e){if(e!==void 0){const s=parseInt(e,10);if(!Number.isFinite(s))throw new Error(`Invalid --concurrency value: "${e}". Must be an integer.`);return v(s)}const n=(0,S.loadConfig)(process.cwd()).import?.concurrency;return typeof n=="number"&&Number.isFinite(n)?v(n):B}l(A,"resolveConcurrency");function v(e){return Math.min(z,Math.max(D,Math.floor(e)))}l(v,"clamp");function Y(e,o){if(o)return!1;const n=`${e.projectDir}/.ironbee/sessions/${e.sessionId}`;try{return(0,w.existsSync)(n)}catch(s){return E.logger.debug(`import skip pre-check failed for ${n}: ${s instanceof Error?s.message:s}`),!1}}l(Y,"shouldSkipForRunner");function q(e,o){const n=o?"ironbee import \u2014 dry-run preview":"ironbee import \u2014 preview";t.log.blank(),console.log(t.pc.bold(n)),t.log.blank();const s=e.projects.reduce((r,d)=>r+d.found,0);console.log(`Scope: ${t.pc.bold(String(e.projects.length))} project(s), ${t.pc.bold(String(s))} session(s) found`);for(const r of e.projects)console.log(` ${t.pc.dim(r.projectDir.padEnd(50))} ${String(r.found).padStart(3)} sessions ${t.pc.dim(`${r.skipped} skipped`)}`);if(t.log.blank(),e.timeRange!==null){const r=new Date(e.timeRange.fromMs).toISOString().slice(0,10),d=new Date(e.timeRange.toMs).toISOString().slice(0,10);console.log(`Time range: ${t.pc.bold(r)} .. ${t.pc.bold(d)}`)}else console.log(`Time range: ${t.pc.dim("(no filter \u2014 every session)")}`);t.log.blank(),console.log(`To import: ${t.pc.bold(String(e.toImportCount))} session(s)`),console.log(" Estimated events:"),console.log(` session_start / session_end ${u(e.estimatedEvents.session_start+e.estimatedEvents.session_end)}`),console.log(` activity_start / activity_end ${u(e.estimatedEvents.activity_start+e.estimatedEvents.activity_end)}`),console.log(` tool_call ${u(e.estimatedEvents.tool_call)}`),console.log(` file_change ${u(e.estimatedEvents.file_change)}`),console.log(` api_request ${u(e.estimatedEvents.api_request)}`),console.log(` session_analytics ${u(e.estimatedEvents.session_analytics)}`),console.log(` session_turn_analytics ${u(e.estimatedEvents.session_turn_analytics)}`),console.log(` session_turn_step_analytics ${u(e.estimatedEvents.session_turn_step_analytics)}`),t.log.blank(),console.log(` Estimated total cost surfaced: ${t.pc.bold(`$${e.estimatedCostUsd.toFixed(2)}`)}`),console.log(` Estimated wire bytes: ${t.pc.dim(G(e.estimatedWireBytes))}`),console.log(` Collector endpoint: ${e.collectorUrl!==null?t.pc.bold(e.collectorUrl):t.pc.red("(not configured)")}`),console.log(` Concurrency: ${t.pc.bold(String(e.concurrency))} sessions in flight`),t.log.blank()}l(q,"renderSummary");function u(e){return e.toLocaleString("en-US")}l(u,"formatNum");function G(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(1)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}l(G,"formatBytes");async function R(e,o){const n=o?.createInterface??M.createInterface;return new Promise(s=>{const r=n({input:process.stdin,output:process.stdout});r.question(`${e} [Y/n] `,d=>{r.close();const m=d.trim().toLowerCase();if(m==="n"||m==="no"){s(!1);return}s(!0)})})}l(R,"promptYesNo");0&&(module.exports={importCommand,parseFlags,promptYesNo});
|
package/dist/commands/login.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var
|
|
2
|
-
`)}
|
|
1
|
+
"use strict";var d=Object.defineProperty;var U=Object.getOwnPropertyDescriptor;var T=Object.getOwnPropertyNames;var O=Object.prototype.hasOwnProperty;var a=(o,t)=>d(o,"name",{value:t,configurable:!0});var E=(o,t)=>{for(var r in t)d(o,r,{get:t[r],enumerable:!0})},x=(o,t,r,l)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of T(t))!O.call(o,n)&&n!==r&&d(o,n,{get:()=>t[n],enumerable:!(l=U(t,n))||l.enumerable});return o};var I=o=>x(d({},"__esModule",{value:!0}),o);var _={};E(_,{loginCommand:()=>F});module.exports=I(_);var S=require("commander"),h=require("os"),y=require("path"),s=require("fs"),e=require("../lib/output"),L=require("../lib/prompt"),i=require("../lib/auth");const w="https://console.ironbee.ai",v="https://collector.service.ironbee.ai";function k(){return(0,y.join)((0,h.homedir)(),".ironbee","config.json")}a(k,"globalConfigPath");function P(){const o=k();if(!(0,s.existsSync)(o))return{};try{return JSON.parse((0,s.readFileSync)(o,"utf-8"))}catch{return{}}}a(P,"readGlobalConfig");function N(o){const t=k();(0,s.mkdirSync)((0,y.join)(t,".."),{recursive:!0}),(0,s.writeFileSync)(t,JSON.stringify(o,null,2)+`
|
|
2
|
+
`)}a(N,"writeGlobalConfig");function $(o){const t=o.replace(/\/$/,"");return t.startsWith("http://")||t.startsWith("https://")?t:`${t.startsWith("localhost")||t.startsWith("127.0.0.1")?"http":"https"}://${t}`}a($,"withProtocol");function W(o){const t=(o??"").trim();if(t.length>0)return t;const r=(0,h.hostname)().trim();return r.length>0?r:"cli"}a(W,"resolveTokenName");const R=["\u280B","\u2819","\u2839","\u2838","\u283C","\u2834","\u2826","\u2827","\u2807","\u280F"];function A(){const o=Date.now();if(!(0,L.isInteractive)())return e.log.dim("Waiting for login... (timeout: 5 min) \u2014 press Ctrl+C to cancel"),()=>{};let r=0;const l=setInterval(()=>{const n=Math.floor((Date.now()-o)/1e3),c=Math.floor(n/60),u=n%60,f=c>0?`${c}m ${String(u).padStart(2,"0")}s`:`${u}s`,b=e.pc.dim(` ${R[r%R.length]} Waiting for browser login\u2026 ${f} (Ctrl+C to cancel)`);process.stdout.write(`\r${b}`),r++},100);return()=>{clearInterval(l),process.stdout.write("\r\x1B[2K")}}a(A,"startWaitSpinner");const F=new S.Command("login").description("Log in to IronBee and configure your access token").option("--console-url <url>",`Console URL, e.g. console.ironbee.dev or localhost:5173 (default: ${w})`).option("--collector-url <url>",`Collector base URL. Events POST to {url}/v1/events; pass the URL exactly as the collector exposes it (no path is appended). Examples: collector.service.ironbee.dev, localhost:8080, https://api.example.com/collect. Default: ${v}`).option("--name <label>","Label for the personal access token shown on the console's /access-tokens page (default: OS hostname)").action(async o=>{const t=$(o.consoleUrl??w),r=o.collectorUrl?$(o.collectorUrl):v,l=W(o.name);try{const n=await(0,i.findFreePort)(),c=(0,i.generateState)(),u=`http://localhost:${n}/callback`,f=`${t}/cli-auth?callback=${encodeURIComponent(u)}&state=${c}&name=${encodeURIComponent(l)}`;e.log.info(`Opening ${e.pc.cyan(t)} in your browser...`),e.log.blank(),e.log.dim(" If the browser does not open automatically, visit:"),e.log.dim(` ${f}`),e.log.blank();const b=A();let g;try{g=await(0,i.startCallbackServer)(n,c,300*1e3,()=>{(0,i.openBrowser)(f)})}finally{b()}const C=P(),p=C.collector,m=p&&typeof p=="object"&&!Array.isArray(p)?{...p}:{};if(m.url=r,g.accessToken)m.oauthToken=g.accessToken,delete m.apiKey;else if(g.apiKey)m.apiKey=g.apiKey,delete m.oauthToken;else throw new Error("the console did not return an access token or API key");C.collector=m,N(C),e.log.blank(),e.log.success("Logged in successfully!"),e.log.label("Console ",t),e.log.label("Collector",r),e.log.label("Token ",g.accessToken?`personal (${l})`:"shared account api key"),e.log.label("Config ",k())}catch(n){const c=n instanceof Error?n.message:String(n);e.log.blank(),e.log.error(`Login failed: ${c}`),process.exit(1)}});0&&(module.exports={loginCommand});
|
package/dist/lib/auth.js
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var T=Object.create;var c=Object.defineProperty;var E=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var P=Object.getPrototypeOf,_=Object.prototype.hasOwnProperty;var i=(e,t)=>c(e,"name",{value:t,configurable:!0});var A=(e,t)=>{for(var r in t)c(e,r,{get:t[r],enumerable:!0})},C=(e,t,r,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let a of I(t))!_.call(e,a)&&a!==r&&c(e,a,{get:()=>t[a],enumerable:!(s=E(t,a))||s.enumerable});return e};var m=(e,t,r)=>(r=e!=null?T(P(e)):{},C(t||!e||!e.__esModule?c(r,"default",{value:e,enumerable:!0}):r,e)),$=e=>C(c({},"__esModule",{value:!0}),e);var M={};A(M,{findFreePort:()=>F,generateState:()=>K,openBrowser:()=>O,startCallbackServer:()=>N});module.exports=$(M);var R=m(require("net")),B=m(require("http")),L=m(require("crypto")),Y=m(require("fs")),H=m(require("path")),k=require("child_process");function F(){return new Promise((e,t)=>{const r=R.createServer();r.listen(0,"127.0.0.1",()=>{const s=r.address();if(!s||typeof s=="string"){r.close(),t(new Error("Could not determine free port"));return}const a=s.port;r.close(()=>e(a))}),r.on("error",t)})}i(F,"findFreePort");function K(){return L.randomBytes(16).toString("hex")}i(K,"generateState");function N(e,t,r=300*1e3,s){return new Promise((a,u)=>{const n=B.createServer((y,o)=>{const x=y.url??"/",l=new URL(x,`http://127.0.0.1:${e}`);if(l.pathname!=="/callback"){o.writeHead(404),o.end();return}const S=l.searchParams.get("state"),g=l.searchParams.get("access_token"),f=l.searchParams.get("api_key"),b=l.searchParams.get("error");if(b){const v=z(b);o.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),o.end(p(v.title,`<p>${d(v.message)}</p><p>You can close this tab.</p>`)),n.closeAllConnections(),n.close(),u(new Error(v.message));return}if(S!==t){o.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),o.end(p("Something went wrong","<p>Invalid state parameter. You can close this tab.</p>")),n.closeAllConnections(),n.close(),u(new Error("State mismatch \u2014 possible CSRF"));return}if(!g&&!f){o.writeHead(400,{"Content-Type":"text/html; charset=utf-8"}),o.end(p("Something went wrong","<p>No credentials received. You can close this tab.</p>")),n.closeAllConnections(),n.close(),u(new Error("No access_token or api_key in callback"));return}o.writeHead(200,{"Content-Type":"text/html; charset=utf-8"}),o.end(p("IronBee CLI connected successfully","<p>You can close this tab.</p>"));const h={};g&&(h.accessToken=g),f&&(h.apiKey=f),a(h),n.closeAllConnections(),n.close()}),w=setTimeout(()=>{n.closeAllConnections(),n.close(),u(new Error("Login timed out after 5 minutes"))},r).unref();n.on("close",()=>clearTimeout(w)),n.listen(e,"127.0.0.1",()=>{s?.()})})}i(N,"startCallbackServer");function O(e){let t;process.platform==="darwin"?t=`open "${e}"`:process.platform==="win32"?t=`start "" "${e}"`:t=`xdg-open "${e}"`,(0,k.exec)(t,r=>{})}i(O,"openBrowser");const U=10;function z(e){return e==="token_limit_exceeded"?{title:"Token limit reached!",message:`You already have the maximum of ${U} access tokens, so a new one could not be issued for the CLI. Revoke one on the IronBee Console's API Tokens page, then run "ironbee login" again!`}:{title:"Login failed!",message:`IronBee Console reported an error (${e})`}}i(z,"describeCallbackError");function d(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}i(d,"escapeHtml");function p(e,t){try{const r=H.join(__dirname,"..","assets","auth.html");return Y.readFileSync(r,"utf-8").replace(/\{\{TITLE\}\}/g,d(e)).replace("{{BODY}}",()=>t)}catch{return D(e,t)}}i(p,"renderAuthPage");function D(e,t){return`<!DOCTYPE html>
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
|
-
<title>${
|
|
5
|
+
<title>${d(e)} \u2014 IronBee</title>
|
|
6
6
|
<style>
|
|
7
7
|
body { font-family: system-ui, sans-serif; display: flex; align-items: center;
|
|
8
8
|
justify-content: center; height: 100vh; margin: 0; background: #0f0f11; color: #e5e5e5; }
|
|
9
|
-
|
|
9
|
+
.card { text-align: center; max-width: 500px; padding: 2rem; }
|
|
10
10
|
h1 { font-size: 1.25rem; margin-bottom: 0.75rem; }
|
|
11
11
|
p { color: #999; font-size: 0.9rem; line-height: 1.6; }
|
|
12
12
|
</style>
|
|
13
13
|
</head>
|
|
14
14
|
<body>
|
|
15
|
-
<div><h1>${
|
|
15
|
+
<div class="card"><h1>${d(e)}</h1>${t}</div>
|
|
16
16
|
</body>
|
|
17
|
-
</html>`}
|
|
17
|
+
</html>`}i(D,"htmlPage");0&&(module.exports={findFreePort,generateState,openBrowser,startCallbackServer});
|
package/dist/lib/collector.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var T=Object.defineProperty;var S=Object.getOwnPropertyDescriptor;var O=Object.getOwnPropertyNames;var B=Object.prototype.hasOwnProperty;var c=(t,o)=>T(t,"name",{value:o,configurable:!0});var I=(t,o)=>{for(var e in o)T(t,e,{get:o[e],enumerable:!0})},x=(t,o,e,u)=>{if(o&&typeof o=="object"||typeof o=="function")for(let s of O(o))!B.call(t,s)&&s!==e&&T(t,s,{get:()=>o[s],enumerable:!(u=S(o,s))||u.enumerable});return t};var A=t=>x(T({},"__esModule",{value:!0}),t);var j={};I(j,{PermanentCollectorError:()=>k,RetriableCollectorError:()=>E,getCollectorTarget:()=>$,postEventsBatch:()=>v,sendEventsBatchToCollector:()=>N,sendToCollector:()=>H});module.exports=A(j);var M=require("https"),P=require("http"),R=require("./config"),g=require("./logger");const C=3e3,w=1e4,D=1e3,U=6e4,q="v1/events";function K(t){const o=new URL(t);return o.pathname.endsWith("/")||(o.pathname=`${o.pathname}/`),new URL(q,o)}c(K,"resolveEventsUrl");class E extends Error{static{c(this,"RetriableCollectorError")}constructor(o,e){super(o),this.name="RetriableCollectorError",this.status=e}}class k extends Error{static{c(this,"PermanentCollectorError")}constructor(o,e){super(o),this.name="PermanentCollectorError",this.status=e}}async function v(t,o,e){const u=e?.timeoutMs??C;return new Promise((s,p)=>{let n=!1;const r=c(i=>{n||(n=!0,s(i))},"settleResolve"),a=c(i=>{n||(n=!0,p(i))},"settleReject");try{const i=JSON.stringify(t),l=K(o.url),f=l.protocol==="https:",h=f?M.request:P.request,b=setTimeout(()=>{a(new Error("collector: send timeout"))},u),m=h({hostname:l.hostname,port:l.port||(f?443:80),path:l.pathname+l.search,method:"POST",headers:{"Content-Type":"application/json","Content-Length":Buffer.byteLength(i),...o.oauthToken?{"X-OAuth-Token":o.oauthToken}:o.apiKey?{"X-API-Key":o.apiKey}:{}},timeout:u},d=>{let y="";d.setEncoding("utf-8"),d.on("data",_=>{y+=_}),d.on("end",()=>{clearTimeout(b),r({status:d.statusCode??0,body:y})}),d.on("close",()=>{clearTimeout(b),r({status:d.statusCode??0,body:y})})});m.on("error",d=>{clearTimeout(b),a(d)}),m.on("timeout",()=>{clearTimeout(b),m.destroy(),a(new Error("collector: request timeout"))}),m.write(i),m.end()}catch(i){a(i instanceof Error?i:new Error(String(i)))}})}c(v,"postEventsBatch");function $(t){if(process.env.IRONBEE_COLLECTOR==="false")return null;const e=(0,R.loadConfig)(t).collector;if(!e||e.enable===!1||typeof e.url!="string"||e.url.length===0)return null;const u=typeof e.oauthToken=="string"&&e.oauthToken.length>0,s=typeof e.apiKey=="string"&&e.apiKey.length>0;return!u&&!s?null:{url:e.url,...u?{oauthToken:e.oauthToken}:{apiKey:e.apiKey},batchSize:typeof e.batchSize=="number"?e.batchSize:void 0,timeoutMs:typeof e.timeoutMs=="number"?L(e.timeoutMs):void 0}}c($,"getCollectorTarget");function L(t){return Number.isFinite(t)?Math.min(U,Math.max(D,Math.floor(t))):w}c(L,"clampTimeoutMs");async function H(t,o,e){const u=$(e);if(!u)return;const s=Date.now();let p;try{p=await v([t],u,{timeoutMs:C})}catch(i){const l=i instanceof Error?i.message:String(i);throw g.logger.debug(`collector: sendToCollector network/timeout type=${t.type} id=${t.id}: ${l}`),new E(`collector network error: ${l}`,null)}const n=p.status;if(n>=200&&n<300){g.logger.debug(`collector: posted type=${t.type} id=${t.id} in ${Date.now()-s}ms`);return}const r=200,a=p.body.length>r?`${p.body.slice(0,r)}\u2026`:p.body;throw n===429||n>=500?(g.logger.debug(`collector: sendToCollector retriable HTTP ${n} type=${t.type} id=${t.id}: ${a}`),new E(`collector HTTP ${n}: ${a}`,n)):(g.logger.debug(`collector: sendToCollector permanent HTTP ${n} type=${t.type} id=${t.id}: ${a}`),new k(`collector HTTP ${n}: ${a}`,n))}c(H,"sendToCollector");async function N(t,o,e,u){if(t.length===0)return;const s=u!==void 0?u:$(e);if(!s)return;const p=s.timeoutMs??w,n=Date.now();try{const r=await v(t,s,{timeoutMs:p});if(!(r.status>=200&&r.status<300)){const l=r.body.length>500?`${r.body.slice(0,500)}\u2026`:r.body,f=t[0]?.type??"(empty)",h={};for(const m of t)h[m.type]=(h[m.type]??0)+1;const b=Object.entries(h).map(([m,d])=>`${m}=${d}`).join(",");throw new Error(`collector: HTTP ${r.status} for batch of ${t.length} (first_type=${f}, types=${b})`+(l.length>0?`: ${l}`:""))}g.logger.debug(`collector: posted batch=${t.length} first_type=${t[0].type} in ${Date.now()-n}ms`)}catch(r){throw g.logger.debug(`collector: sendEventsBatchToCollector failed batch=${t.length}: ${r}`),r instanceof Error?r:new Error(String(r))}}c(N,"sendEventsBatchToCollector");0&&(module.exports={PermanentCollectorError,RetriableCollectorError,getCollectorTarget,postEventsBatch,sendEventsBatchToCollector,sendToCollector});
|
package/dist/lib/config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var E=Object.defineProperty;var ae=Object.getOwnPropertyDescriptor;var ce=Object.getOwnPropertyNames;var le=Object.prototype.hasOwnProperty;var r=(n,e)=>E(n,"name",{value:e,configurable:!0});var ue=(n,e)=>{for(var t in e)E(n,t,{get:e[t],enumerable:!0})},fe=(n,e,t,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of ce(e))!le.call(n,i)&&i!==t&&E(n,i,{get:()=>e[i],enumerable:!(o=ae(e,i))||o.enumerable});return n};var ge=n=>fe(E({},"__esModule",{value:!0}),n);var jn={};ue(jn,{ALL_CYCLES:()=>de,CONFIG_TARGETS_BY_PRECEDENCE:()=>xe,CYCLES_ENABLED_BY_DEFAULT:()=>D,CYCLE_DEFAULT_VERIFY_PATTERNS:()=>V,CYCLE_TOOL_PREFIXES:()=>be,CYCLE_TO_SERVER:()=>pe,DEFAULT_ANDROID_ALWAYS_REQUIRED:()=>X,DEFAULT_ANDROID_EVIDENCE_PATHS:()=>G,DEFAULT_ANDROID_VERIFY_PATTERNS:()=>F,DEFAULT_BACKEND_ALWAYS_REQUIRED:()=>Y,DEFAULT_BACKEND_EVIDENCE_PATHS:()=>K,DEFAULT_BACKEND_VERIFY_PATTERNS:()=>M,DEFAULT_BROWSER_ALWAYS_REQUIRED:()=>U,DEFAULT_BROWSER_VERIFY_PATTERNS:()=>N,DEFAULT_NODE_ALWAYS_REQUIRED:()=>q,DEFAULT_NODE_EVIDENCE_PATHS:()=>$,DEFAULT_NODE_VERIFY_PATTERNS:()=>P,DEFAULT_OAUTH_USAGE_TTL_SECONDS:()=>z,DEFAULT_OTEL_EMIT_MIN_INTERVAL_SECONDS:()=>ne,DEFAULT_OTEL_ENSURE_MIN_INTERVAL_SECONDS:()=>ee,DEFAULT_OTEL_IDLE_TIMEOUT_SECONDS:()=>Z,DEFAULT_OTEL_PORT:()=>J,DEFAULT_VERIFICATION_CONTEXT_COMMIT_DEPTH:()=>oe,DEFAULT_VERIFICATION_CONTEXT_MAX_BYTES:()=>re,ENV_OVERRIDES:()=>x,OPTIONAL_CYCLES:()=>I,applyEnvOverrides:()=>H,findActiveEnvOverride:()=>Oe,getActiveCycles:()=>W,getAnalyticsEmitOnStopMinIntervalSeconds:()=>An,getAndroidDevToolsMcpEntry:()=>Qe,getAutoVerifyEnabled:()=>te,getBackendDevToolsMcpEntry:()=>We,getCaptureFileChangeset:()=>_n,getClaudeOauthAccessEnabled:()=>rn,getClaudeOauthAccessUsageTtlSeconds:()=>on,getConfigLayerPaths:()=>T,getMaxChangesetBytes:()=>Cn,getMaxRetries:()=>ze,getMcpServerEntry:()=>Ge,getNodeDevToolsMcpEntry:()=>He,getOTELEmitMinIntervalSeconds:()=>un,getOTELEnsureMinIntervalSeconds:()=>ln,getOTELIdleTimeoutSeconds:()=>cn,getOTELPort:()=>an,getPrivacyEnabled:()=>se,getRequiredToolsConfig:()=>Se,getStatusLineEmitMinIntervalSeconds:()=>tn,getStatusLineRefreshInterval:()=>fn,getStatusLineRenderDefault:()=>nn,getTargetConfigPath:()=>je,getTelemetryEnabled:()=>ie,getVerificationContextCommitDepth:()=>pn,getVerificationContextEnabled:()=>gn,getVerificationContextMaxBytes:()=>bn,getVerificationContextSource:()=>dn,getVerificationEnabled:()=>w,getVerificationMode:()=>yn,getVerificationModel:()=>Ce,isAnalyticsApiRequestEventsEnabled:()=>xn,isAnalyticsEmitOnStopEnabled:()=>vn,isAnalyticsEnabled:()=>mn,isAnalyticsStepEventsEnabled:()=>Tn,isAnalyticsTurnEventsEnabled:()=>In,isCollectorConfigured:()=>j,isCycleEnabled:()=>Le,isCyclePatternsActive:()=>Q,isIgnoredVerifyPath:()=>En,isJobQueueEnabled:()=>Je,isOTELEnabled:()=>sn,isRecordingEnabled:()=>Ze,isSessionStatusEnabled:()=>en,loadConfig:()=>a,requiresVerification:()=>ke,resolveConfigTargetFromFlags:()=>we});module.exports=ge(jn);var p=require("fs"),m=require("path"),L=require("os"),S=require("./logger");const I=["node","backend","android"],de=["browser",...I],D=new Set(["browser"]),pe={browser:"browser-devtools",node:"node-devtools",backend:"backend-devtools",android:"android-devtools"},be={browser:"bdt_",node:"ndt_",backend:"bedt_",android:"adt_"},N=["*.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"],P=["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}"],M=["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}"],F=["android/**/*.{kt,java}","app/src/**/*.{kt,java}","mobile/**/*.{kt,java}","src/main/kotlin/**/*.kt","src/main/java/**/*.java","**/*.{kt,java}","**/res/**/*.xml","**/AndroidManifest.xml"],V={browser:N,node:P,backend:M,android:F},U=["bdt_navigation_go-to","bdt_content_take-screenshot","bdt_a11y_take-aria-snapshot","bdt_o11y_get-console-messages"],q=["ndt_debug_connect"],$=[{name:"probe",allOf:[{anyOf:["ndt_debug_put-tracepoint","ndt_debug_put-logpoint","ndt_debug_put-exceptionpoint"]},"ndt_debug_get-probe-snapshots"]},{name:"log",allOf:["ndt_debug_get-logs"]}],Y=[],K=[{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"]}]}],X=["adt_device_connect"],G=[{name:"device-evidence",allOf:[{anyOf:["adt_device_launch-app","adt_interaction_tap","adt_interaction_double-tap","adt_interaction_long-press","adt_interaction_input-text","adt_interaction_swipe","adt_interaction_scroll","adt_interaction_press-key","adt_interaction_deep-link"]},"adt_content_take-screenshot","adt_a11y_take-ui-snapshot"]},{name:"log-evidence",allOf:[{anyOf:["adt_o11y_log-read","adt_o11y_log-follow"]}]}],Ee=3;function ye(n){if(!(0,p.existsSync)(n))return{};try{return JSON.parse((0,p.readFileSync)(n,"utf-8"))}catch(e){return S.logger.debug(`failed to parse config ${n}: ${e}`),{}}}r(ye,"loadJsonFile");function _e(n,e){if(!Object.prototype.hasOwnProperty.call(n,"verification"))return;const t=n.verification;if(t===null||typeof t!="object"||Array.isArray(t))throw new Error(`Invalid IronBee config in ${e}: 'verification' must be an object. Expected shape: { "enable": boolean }.`);const o=t;if(Object.prototype.hasOwnProperty.call(o,"enable")&&typeof o.enable!="boolean")throw new Error(`Invalid IronBee config in ${e}: 'verification.enable' must be boolean. Got ${typeof o.enable}.`);if(Object.prototype.hasOwnProperty.call(o,"auto")&&typeof o.auto!="boolean")throw new Error(`Invalid IronBee config in ${e}: 'verification.auto' must be boolean. Got ${typeof o.auto}.`);if(Object.prototype.hasOwnProperty.call(o,"model")){const i=o.model,s=typeof i=="string",l=i!==null&&typeof i=="object"&&!Array.isArray(i)&&Object.values(i).every(c=>typeof c=="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}.`)}}r(_e,"assertVerificationShape");function Ce(n,e){const t=n.verification?.model;if(typeof t=="string")return t.length>0?t:void 0;if(t&&typeof t=="object"){const o=t[e];return typeof o=="string"&&o.length>0?o:void 0}}r(Ce,"getVerificationModel");function me(n,e){if(!Object.prototype.hasOwnProperty.call(n,"telemetry"))return;const t=n.telemetry;if(t===null||typeof t!="object"||Array.isArray(t))throw new Error(`Invalid IronBee config in ${e}: 'telemetry' must be an object. Expected shape: { "enable": boolean }.`);const o=t;if(Object.prototype.hasOwnProperty.call(o,"enable")&&typeof o.enable!="boolean")throw new Error(`Invalid IronBee config in ${e}: 'telemetry.enable' must be boolean. Got ${typeof o.enable}.`)}r(me,"assertTelemetryShape");function ve(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 o=t;if(Object.prototype.hasOwnProperty.call(o,"enable")&&typeof o.enable!="boolean")throw new Error(`Invalid IronBee config in ${e}: 'privacy.enable' must be boolean. Got ${typeof o.enable}.`)}r(ve,"assertPrivacyShape");function y(n,e){if(!(n===void 0&&e===void 0))return{...n??{},...e??{}}}r(y,"mergeCycleConfig");function O(n,e){const t={...n,...e};return t.browser=y(n.browser,e.browser),t.node=y(n.node,e.node),t.backend=y(n.backend,e.backend),t.android=y(n.android,e.android),t.claude=Te(n.claude,e.claude),t.verification=Ie(n.verification,e.verification),t.verificationContext=Ae(n.verificationContext,e.verificationContext),t}r(O,"mergeConfigLayers");function Ae(n,e){if(!(n===void 0&&e===void 0))return{...n??{},...e??{}}}r(Ae,"mergeVerificationContextConfig");function Ie(n,e){if(!(n===void 0&&e===void 0))return{...n??{},...e??{}}}r(Ie,"mergeVerificationConfig");function Te(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??{}}),t}r(Te,"mergeClaudeConfig");function T(n){return{global:(0,m.join)((0,L.homedir)(),".ironbee","config.json"),project:n?(0,m.join)(n,".ironbee","config.json"):void 0,local:n?(0,m.join)(n,".ironbee","config.local.json"):void 0}}r(T,"getConfigLayerPaths");const xe=["global","project","local"];function je(n,e){const t=T(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}r(je,"getTargetConfigPath");function we(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"}r(we,"resolveConfigTargetFromFlags");function v(n){const e=ye(n);return(0,p.existsSync)(n)&&(_e(e,n),me(e,n),ve(e,n)),e}r(v,"loadAndValidateLayer");const x=[{envVar:"IRONBEE_API_KEY",configPath:"collector.apiKey"}];function Re(n,e,t){const o=e.split(".");let i=n;for(let s=0;s<o.length-1;s++){const l=o[s],c=i[l];c!=null&&typeof c=="object"&&!Array.isArray(c)?i[l]={...c}:i[l]={},i=i[l]}i[o[o.length-1]]=t}r(Re,"setAtConfigPath");function H(n){let e;for(const t of x){const o=process.env[t.envVar];if(o===void 0||o.length===0)continue;e===void 0&&(e={...n});const i=t.coerce?t.coerce(o):o;Re(e,t.configPath,i)}return e??n}r(H,"applyEnvOverrides");function Oe(n){for(const e of x){if(e.configPath!==n)continue;const t=process.env[e.envVar];if(t!==void 0&&t.length>0)return e}}r(Oe,"findActiveEnvOverride");function a(n){const e=T(n),t=v(e.global),o=e.project?v(e.project):{},i=e.local?v(e.local):{},s=O(O(t,o),i);return H(s)}r(a,"loadConfig");function Be(n){let e=n.replace(/\{([^}]+)\}/g,(t,o)=>`(${o.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}$`)}r(Be,"globToRegExp");function _(n,e){const t=n.replace(/\\/g,"/");for(const o of e)if(Be(o).test(t))return!0;return!1}r(_,"matchesAny");function he(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}r(he,"getCycleBlock");function A(n,e){const t=he(n,e);if(t!==void 0&&t.enable===!1)return[];const o=V[e]??[];if(t===void 0)return D.has(e)?[...o]:[];if(Array.isArray(t.verifyPatterns)&&t.verifyPatterns.length===0)return[];const i=t.verifyPatterns??o,s=t.additionalVerifyPatterns??[];return[...i,...s]}r(A,"getCyclePatterns");function W(n,e){const t=e.ignoredVerifyPatterns??[];if(t.length>0&&_(n,t))return[];const o=[];_(n,A(e,"browser"))&&o.push("browser");for(const i of I){const s=A(e,i);s.length>0&&_(n,s)&&o.push(i)}return o}r(W,"getActiveCycles");function ke(n,e){return W(n,e).length>0}r(ke,"requiresVerification");function Le(n,e){return w(n)?Q(n,e):!1}r(Le,"isCycleEnabled");function Q(n,e){return A(n,e).length>0}r(Q,"isCyclePatternsActive");function Se(n,e){let t,o;if(e==="browser"?(t=n.browser?.alwaysRequired??U,o=n.browser?.evidencePaths??[]):e==="node"?(t=n.node?.alwaysRequired??q,o=n.node?.evidencePaths??$):e==="backend"?(t=n.backend?.alwaysRequired??Y,o=n.backend?.evidencePaths??K):e==="android"?(t=n.android?.alwaysRequired??X,o=n.android?.evidencePaths??G):(t=[],o=[]),t.length===0&&o.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:o}}r(Se,"getRequiredToolsConfig");const B="npx",De="^0.11.0",h=["-y",`@ironbee-ai/devtools@${De}`],Ne={TOOL_NAME_PREFIX:"bdt_",TOOL_INPUT_METADATA_ENABLE:"true"},Pe={PLATFORM:"node",TOOL_NAME_PREFIX:"ndt_",TOOL_INPUT_METADATA_ENABLE:"true"},Me={PLATFORM:"backend",TOOL_NAME_PREFIX:"bedt_",TOOL_INPUT_METADATA_ENABLE:"true"},Fe={PLATFORM:"android",TOOL_NAME_PREFIX:"adt_",TOOL_INPUT_METADATA_ENABLE:"true"},Ve={BROWSER_DEVTOOLS_INSTALL_CHROMIUM:"true"},Ue={},qe={},$e={};function Ye(n){return ie(n)?{}:{TELEMETRY_ENABLE:"false"}}r(Ye,"buildTelemetryEnv");function Ke(n){return se(n)?{COLLECTOR_EVENTS_TOOL_DETAILS_ENABLE:"false",COLLECTOR_ARTIFACTS_ENABLE:"false"}:{}}r(Ke,"buildPrivacyEnv");function Xe(n,e){if(!j(n))return{};const o={OTEL_ENABLE:"true",OTEL_EXPORTER_HTTP_URL:n.collector.url,OTEL_EXPORTER_HTTP_HEADERS:"X-API-Key=${file:~/.ironbee/config.json#collector.apiKey}",OTEL_EXPORTER_TYPE:"otlp/http-protobuf"};return e==="browser"&&(o.OTEL_INSTRUMENTATION_USER_INTERACTION_EVENTS="change,input,click",o.BROWSER_HEADLESS_ENABLE="true"),o}r(Xe,"buildOTELEnv");function C(n,e,t,o,i){const s=Xe(n,i),l=Ye(n),c=Ke(n),b=n[e];if(b&&typeof b=="object"&&!Array.isArray(b)){const u=b;if(u.mcp&&typeof u.mcp=="object"&&!Array.isArray(u.mcp)){const f={...u.mcp},g={...s,...l,...c,...f.env??{},...t};return f.env=g,f}const R={};if(u.env&&typeof u.env=="object"&&!Array.isArray(u.env)){const f=u.env;for(const g of Object.keys(f))typeof f[g]=="string"&&(R[g]=f[g])}return{command:B,args:[...h],env:{...o,...s,...l,...c,...R,...t}}}return{command:B,args:[...h],env:{...o,...s,...l,...c,...t}}}r(C,"buildMcpEntry");function Ge(n){const e=a(n);return C(e,"browserDevTools",Ne,Ve,"browser")}r(Ge,"getMcpServerEntry");function He(n){const e=a(n);return C(e,"nodeDevTools",Pe,Ue,"node")}r(He,"getNodeDevToolsMcpEntry");function We(n){const e=a(n);return C(e,"backendDevTools",Me,qe,"backend")}r(We,"getBackendDevToolsMcpEntry");function Qe(n){const e=a(n);return C(e,"androidDevTools",Fe,$e,"android")}r(Qe,"getAndroidDevToolsMcpEntry");function ze(n){return typeof n.maxRetries=="number"&&n.maxRetries>0?n.maxRetries:Ee}r(ze,"getMaxRetries");function j(n){if(process.env.IRONBEE_COLLECTOR==="false")return!1;const e=n.collector;return!(!e||e.enable===!1||typeof e.url!="string"||e.url.length===0||typeof e.apiKey!="string"||e.apiKey.length===0)}r(j,"isCollectorConfigured");function Je(n){const e=a(n);return d(e,e.jobQueue)}r(Je,"isJobQueueEnabled");function Ze(n){const e=a(n);return d(e,e.recording)}r(Ze,"isRecordingEnabled");function en(n){return d(n,n.statusLine)}r(en,"isSessionStatusEnabled");function nn(n){const e=n.statusLine;return e!==void 0&&e.renderDefault===!0}r(nn,"getStatusLineRenderDefault");function tn(n){const e=n.statusLine?.emitMinIntervalSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:10}r(tn,"getStatusLineEmitMinIntervalSeconds");const z=60;function rn(n){return n.claude?.oauthAccess?.enable!==!1}r(rn,"getClaudeOauthAccessEnabled");function on(n){const e=n.claude?.oauthAccess?.usageTtlSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:z}r(on,"getClaudeOauthAccessUsageTtlSeconds");const J=15986,Z=600,ee=30,ne=0;function sn(n){return d(n,n.otel)}r(sn,"isOTELEnabled");function an(n){const e=n.otel?.port;return typeof e=="number"&&Number.isInteger(e)&&e>0&&e<65536?e:J}r(an,"getOTELPort");function cn(n){const e=n.otel?.idleTimeoutSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>0?e:Z}r(cn,"getOTELIdleTimeoutSeconds");function ln(n){const e=n.otel?.ensureMinIntervalSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:ee}r(ln,"getOTELEnsureMinIntervalSeconds");function un(n){const e=n.otel?.emitMinIntervalSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:ne}r(un,"getOTELEmitMinIntervalSeconds");function fn(n){const e=n.statusLine?.refreshInterval;if(typeof e=="number"&&Number.isFinite(e)&&e>=1)return e}r(fn,"getStatusLineRefreshInterval");function d(n,e){return e!=null&&typeof e=="object"&&!Array.isArray(e)?e.enable!==!1:j(n)}r(d,"isFeatureEnabledWithCollectorAutoEnable");function Rn(n){return n==null||typeof n!="object"||Array.isArray(n)?!1:n.enable!==!1}r(Rn,"isPresenceEnabled");function w(n){const e=n.verification;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.enable!==!1}r(w,"getVerificationEnabled");function te(n){const e=n.verification;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.auto!==!1}r(te,"getAutoVerifyEnabled");const re=65536,oe=1;function gn(n){const e=n.verificationContext;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.enable!==!1}r(gn,"getVerificationContextEnabled");function dn(n){return n.verificationContext?.source==="actions"?"actions":"git"}r(dn,"getVerificationContextSource");function pn(n){const e=n.verificationContext?.commitDepth;return typeof e=="number"&&Number.isFinite(e)&&e>=0?Math.floor(e):oe}r(pn,"getVerificationContextCommitDepth");function bn(n){const e=n.verificationContext?.maxBytes;return typeof e=="number"&&Number.isFinite(e)&&e>0?Math.floor(e):re}r(bn,"getVerificationContextMaxBytes");function En(n,e){const t=n.ignoredVerifyPatterns??[];return t.length>0&&_(e,t)}r(En,"isIgnoredVerifyPath");function yn(n){return w(n)?te(n)?"enforce":"assist":"monitor"}r(yn,"getVerificationMode");function ie(n){const e=n.telemetry;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.enable!==!1}r(ie,"getTelemetryEnabled");function se(n){const e=n.privacy;return e==null||typeof e!="object"||Array.isArray(e)?!1:e.enable===!0}r(se,"getPrivacyEnabled");const k=65536;function _n(n){const e=n.fileChange;return!e||typeof e!="object"||Array.isArray(e)?!1:e.captureChangeset===!0}r(_n,"getCaptureFileChangeset");function Cn(n){const e=n.fileChange;if(!e||typeof e!="object"||Array.isArray(e))return k;const t=e.maxChangesetBytes;return typeof t!="number"||!Number.isFinite(t)||t<=0?k:Math.floor(t)}r(Cn,"getMaxChangesetBytes");function mn(n){const e=a(n);return d(e,e.analytics)}r(mn,"isAnalyticsEnabled");function vn(n){const t=a(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!0:t.emitOnStop!==!1}r(vn,"isAnalyticsEmitOnStopEnabled");function An(n){const t=a(n).analytics;if(t===null||typeof t!="object"||Array.isArray(t))return 0;const o=t.emitOnStopMinIntervalSeconds;return typeof o=="number"&&o>=0?o:0}r(An,"getAnalyticsEmitOnStopMinIntervalSeconds");function In(n){const t=a(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!1:t.emitTurnEvents===!0}r(In,"isAnalyticsTurnEventsEnabled");function Tn(n){const t=a(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!1:t.emitStepEvents===!0}r(Tn,"isAnalyticsStepEventsEnabled");function xn(n){const t=a(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!0:t.emitApiRequestEvents!==!1}r(xn,"isAnalyticsApiRequestEventsEnabled");0&&(module.exports={ALL_CYCLES,CONFIG_TARGETS_BY_PRECEDENCE,CYCLES_ENABLED_BY_DEFAULT,CYCLE_DEFAULT_VERIFY_PATTERNS,CYCLE_TOOL_PREFIXES,CYCLE_TO_SERVER,DEFAULT_ANDROID_ALWAYS_REQUIRED,DEFAULT_ANDROID_EVIDENCE_PATHS,DEFAULT_ANDROID_VERIFY_PATTERNS,DEFAULT_BACKEND_ALWAYS_REQUIRED,DEFAULT_BACKEND_EVIDENCE_PATHS,DEFAULT_BACKEND_VERIFY_PATTERNS,DEFAULT_BROWSER_ALWAYS_REQUIRED,DEFAULT_BROWSER_VERIFY_PATTERNS,DEFAULT_NODE_ALWAYS_REQUIRED,DEFAULT_NODE_EVIDENCE_PATHS,DEFAULT_NODE_VERIFY_PATTERNS,DEFAULT_OAUTH_USAGE_TTL_SECONDS,DEFAULT_OTEL_EMIT_MIN_INTERVAL_SECONDS,DEFAULT_OTEL_ENSURE_MIN_INTERVAL_SECONDS,DEFAULT_OTEL_IDLE_TIMEOUT_SECONDS,DEFAULT_OTEL_PORT,DEFAULT_VERIFICATION_CONTEXT_COMMIT_DEPTH,DEFAULT_VERIFICATION_CONTEXT_MAX_BYTES,ENV_OVERRIDES,OPTIONAL_CYCLES,applyEnvOverrides,findActiveEnvOverride,getActiveCycles,getAnalyticsEmitOnStopMinIntervalSeconds,getAndroidDevToolsMcpEntry,getAutoVerifyEnabled,getBackendDevToolsMcpEntry,getCaptureFileChangeset,getClaudeOauthAccessEnabled,getClaudeOauthAccessUsageTtlSeconds,getConfigLayerPaths,getMaxChangesetBytes,getMaxRetries,getMcpServerEntry,getNodeDevToolsMcpEntry,getOTELEmitMinIntervalSeconds,getOTELEnsureMinIntervalSeconds,getOTELIdleTimeoutSeconds,getOTELPort,getPrivacyEnabled,getRequiredToolsConfig,getStatusLineEmitMinIntervalSeconds,getStatusLineRefreshInterval,getStatusLineRenderDefault,getTargetConfigPath,getTelemetryEnabled,getVerificationContextCommitDepth,getVerificationContextEnabled,getVerificationContextMaxBytes,getVerificationContextSource,getVerificationEnabled,getVerificationMode,getVerificationModel,isAnalyticsApiRequestEventsEnabled,isAnalyticsEmitOnStopEnabled,isAnalyticsEnabled,isAnalyticsStepEventsEnabled,isAnalyticsTurnEventsEnabled,isCollectorConfigured,isCycleEnabled,isCyclePatternsActive,isIgnoredVerifyPath,isJobQueueEnabled,isOTELEnabled,isRecordingEnabled,isSessionStatusEnabled,loadConfig,requiresVerification,resolveConfigTargetFromFlags});
|
|
1
|
+
"use strict";var y=Object.defineProperty;var ce=Object.getOwnPropertyDescriptor;var le=Object.getOwnPropertyNames;var ue=Object.prototype.hasOwnProperty;var o=(n,e)=>y(n,"name",{value:e,configurable:!0});var fe=(n,e)=>{for(var t in e)y(n,t,{get:e[t],enumerable:!0})},ge=(n,e,t,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of le(e))!ue.call(n,i)&&i!==t&&y(n,i,{get:()=>e[i],enumerable:!(r=ce(e,i))||r.enumerable});return n};var de=n=>ge(y({},"__esModule",{value:!0}),n);var wn={};fe(wn,{ALL_CYCLES:()=>pe,CONFIG_TARGETS_BY_PRECEDENCE:()=>xe,CYCLES_ENABLED_BY_DEFAULT:()=>N,CYCLE_DEFAULT_VERIFY_PATTERNS:()=>U,CYCLE_TOOL_PREFIXES:()=>Ee,CYCLE_TO_SERVER:()=>be,DEFAULT_ANDROID_ALWAYS_REQUIRED:()=>H,DEFAULT_ANDROID_EVIDENCE_PATHS:()=>G,DEFAULT_ANDROID_VERIFY_PATTERNS:()=>V,DEFAULT_BACKEND_ALWAYS_REQUIRED:()=>Y,DEFAULT_BACKEND_EVIDENCE_PATHS:()=>X,DEFAULT_BACKEND_VERIFY_PATTERNS:()=>F,DEFAULT_BROWSER_ALWAYS_REQUIRED:()=>q,DEFAULT_BROWSER_VERIFY_PATTERNS:()=>P,DEFAULT_NODE_ALWAYS_REQUIRED:()=>$,DEFAULT_NODE_EVIDENCE_PATHS:()=>K,DEFAULT_NODE_VERIFY_PATTERNS:()=>M,DEFAULT_OAUTH_USAGE_TTL_SECONDS:()=>J,DEFAULT_OTEL_EMIT_MIN_INTERVAL_SECONDS:()=>te,DEFAULT_OTEL_ENSURE_MIN_INTERVAL_SECONDS:()=>ne,DEFAULT_OTEL_IDLE_TIMEOUT_SECONDS:()=>ee,DEFAULT_OTEL_PORT:()=>Z,DEFAULT_VERIFICATION_CONTEXT_COMMIT_DEPTH:()=>ie,DEFAULT_VERIFICATION_CONTEXT_MAX_BYTES:()=>re,ENV_OVERRIDES:()=>w,OPTIONAL_CYCLES:()=>I,applyEnvOverrides:()=>W,findActiveEnvOverride:()=>he,getActiveCycles:()=>Q,getAnalyticsEmitOnStopMinIntervalSeconds:()=>An,getAndroidDevToolsMcpEntry:()=>Qe,getAutoVerifyEnabled:()=>oe,getBackendDevToolsMcpEntry:()=>We,getCaptureFileChangeset:()=>_n,getClaudeOauthAccessEnabled:()=>on,getClaudeOauthAccessUsageTtlSeconds:()=>rn,getConfigLayerPaths:()=>x,getMaxChangesetBytes:()=>Cn,getMaxRetries:()=>ze,getMcpServerEntry:()=>He,getNodeDevToolsMcpEntry:()=>Ge,getOTELEmitMinIntervalSeconds:()=>un,getOTELEnsureMinIntervalSeconds:()=>ln,getOTELIdleTimeoutSeconds:()=>cn,getOTELPort:()=>an,getPrivacyEnabled:()=>ae,getRequiredToolsConfig:()=>Se,getStatusLineEmitMinIntervalSeconds:()=>tn,getStatusLineRefreshInterval:()=>fn,getStatusLineRenderDefault:()=>nn,getTargetConfigPath:()=>we,getTelemetryEnabled:()=>se,getVerificationContextCommitDepth:()=>pn,getVerificationContextEnabled:()=>gn,getVerificationContextMaxBytes:()=>bn,getVerificationContextSource:()=>dn,getVerificationEnabled:()=>R,getVerificationMode:()=>yn,getVerificationModel:()=>Ce,isAnalyticsApiRequestEventsEnabled:()=>xn,isAnalyticsEmitOnStopEnabled:()=>vn,isAnalyticsEnabled:()=>mn,isAnalyticsStepEventsEnabled:()=>In,isAnalyticsTurnEventsEnabled:()=>Tn,isCollectorConfigured:()=>j,isCycleEnabled:()=>Le,isCyclePatternsActive:()=>z,isIgnoredVerifyPath:()=>En,isJobQueueEnabled:()=>Je,isOTELEnabled:()=>sn,isRecordingEnabled:()=>Ze,isSessionStatusEnabled:()=>en,loadConfig:()=>c,requiresVerification:()=>Be,resolveConfigTargetFromFlags:()=>je});module.exports=de(wn);var E=require("fs"),b=require("path"),T=require("os"),D=require("./logger");const I=["node","backend","android"],pe=["browser",...I],N=new Set(["browser"]),be={browser:"browser-devtools",node:"node-devtools",backend:"backend-devtools",android:"android-devtools"},Ee={browser:"bdt_",node:"ndt_",backend:"bedt_",android:"adt_"},P=["*.ts","*.tsx","*.js","*.jsx","*.mjs","*.cjs","*.vue","*.svelte","*.html","*.htm","*.css","*.scss","*.sass","*.less","*.styl","*.py","*.rb","*.erb","*.go","*.rs","*.java","*.kt","*.kts","*.swift","*.c","*.cpp","*.h","*.hpp","*.cs","*.php","*.dart","*.ex","*.exs","*.erl","*.lua","*.r","*.R","*.scala","*.clj","*.cljs","*.zig","*.nim","*.hbs","*.ejs","*.pug","*.jade","*.astro"],M=["server/**/*.{ts,js,mjs,cjs}","src/server/**/*.{ts,js,mjs,cjs}","backend/**/*.{ts,js,mjs,cjs}","api/**/*.{ts,js,mjs,cjs}","src/api/**/*.{ts,js,mjs,cjs}","pages/api/**/*.{ts,js,mjs,cjs}","app/api/**/*.{ts,js,mjs,cjs}","routes/**/*.{ts,js,mjs,cjs}","**/server.{ts,js,mjs,cjs}"],F=["server/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","src/server/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","backend/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","api/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","src/api/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","pages/api/**/*.{ts,js,mjs,cjs}","app/api/**/*.{ts,js,mjs,cjs}","routes/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","controllers/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","handlers/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","services/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","**/server.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}","**/main.{go,py,java,rb,kt,scala}"],V=["android/**/*.{kt,java}","app/src/**/*.{kt,java}","mobile/**/*.{kt,java}","src/main/kotlin/**/*.kt","src/main/java/**/*.java","**/*.{kt,java}","**/res/**/*.xml","**/AndroidManifest.xml"],U={browser:P,node:M,backend:F,android:V},q=["bdt_navigation_go-to","bdt_content_take-screenshot","bdt_a11y_take-aria-snapshot","bdt_o11y_get-console-messages"],$=["ndt_debug_connect"],K=[{name:"probe",allOf:[{anyOf:["ndt_debug_put-tracepoint","ndt_debug_put-logpoint","ndt_debug_put-exceptionpoint"]},"ndt_debug_get-probe-snapshots"]},{name:"log",allOf:["ndt_debug_get-logs"]}],Y=[],X=[{name:"protocol-call",allOf:[{anyOf:["bedt_request_http","bedt_request_grpc","bedt_request_graphql","bedt_request_websocket-open","bedt_request_replay"]}]},{name:"log-evidence",allOf:["bedt_log_register-source",{anyOf:["bedt_log_read","bedt_log_read-multi","bedt_log_follow"]}]},{name:"db-evidence",allOf:["bedt_db_connect",{anyOf:["bedt_db_query","bedt_db_describe-table","bedt_db_list-tables","bedt_db_snapshot","bedt_db_diff","bedt_db_get-changes"]}]}],H=["adt_device_connect"],G=[{name:"device-evidence",allOf:[{anyOf:["adt_device_launch-app","adt_interaction_tap","adt_interaction_double-tap","adt_interaction_long-press","adt_interaction_input-text","adt_interaction_swipe","adt_interaction_scroll","adt_interaction_press-key","adt_interaction_deep-link"]},"adt_content_take-screenshot","adt_a11y_take-ui-snapshot"]},{name:"log-evidence",allOf:[{anyOf:["adt_o11y_log-read","adt_o11y_log-follow"]}]}],ye=3;function O(n){if(!(0,E.existsSync)(n))return{};try{return JSON.parse((0,E.readFileSync)(n,"utf-8"))}catch(e){return D.logger.debug(`failed to parse config ${n}: ${e}`),{}}}o(O,"loadJsonFile");function _e(n,e){if(!Object.prototype.hasOwnProperty.call(n,"verification"))return;const t=n.verification;if(t===null||typeof t!="object"||Array.isArray(t))throw new Error(`Invalid IronBee config in ${e}: 'verification' must be an object. Expected shape: { "enable": boolean }.`);const r=t;if(Object.prototype.hasOwnProperty.call(r,"enable")&&typeof r.enable!="boolean")throw new Error(`Invalid IronBee config in ${e}: 'verification.enable' must be boolean. Got ${typeof r.enable}.`);if(Object.prototype.hasOwnProperty.call(r,"auto")&&typeof r.auto!="boolean")throw new Error(`Invalid IronBee config in ${e}: 'verification.auto' must be boolean. Got ${typeof r.auto}.`);if(Object.prototype.hasOwnProperty.call(r,"model")){const i=r.model,s=typeof i=="string",l=i!==null&&typeof i=="object"&&!Array.isArray(i)&&Object.values(i).every(a=>typeof a=="string");if(!s&&!l)throw new Error(`Invalid IronBee config in ${e}: 'verification.model' must be a string (applies to all clients) or an object of string values (per-client, e.g. { "claude": "sonnet", "codex": "gpt-5.5" }). Got ${Array.isArray(i)?"array":typeof i}.`)}}o(_e,"assertVerificationShape");function Ce(n,e){const t=n.verification?.model;if(typeof t=="string")return t.length>0?t:void 0;if(t&&typeof t=="object"){const r=t[e];return typeof r=="string"&&r.length>0?r:void 0}}o(Ce,"getVerificationModel");function me(n,e){if(!Object.prototype.hasOwnProperty.call(n,"telemetry"))return;const t=n.telemetry;if(t===null||typeof t!="object"||Array.isArray(t))throw new Error(`Invalid IronBee config in ${e}: 'telemetry' must be an object. Expected shape: { "enable": boolean }.`);const r=t;if(Object.prototype.hasOwnProperty.call(r,"enable")&&typeof r.enable!="boolean")throw new Error(`Invalid IronBee config in ${e}: 'telemetry.enable' must be boolean. Got ${typeof r.enable}.`)}o(me,"assertTelemetryShape");function ve(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(ve,"assertPrivacyShape");function _(n,e){if(!(n===void 0&&e===void 0))return{...n??{},...e??{}}}o(_,"mergeCycleConfig");function k(n,e){const t={...n,...e};return t.browser=_(n.browser,e.browser),t.node=_(n.node,e.node),t.backend=_(n.backend,e.backend),t.android=_(n.android,e.android),t.claude=Ie(n.claude,e.claude),t.verification=Te(n.verification,e.verification),t.verificationContext=Ae(n.verificationContext,e.verificationContext),t}o(k,"mergeConfigLayers");function Ae(n,e){if(!(n===void 0&&e===void 0))return{...n??{},...e??{}}}o(Ae,"mergeVerificationContextConfig");function Te(n,e){if(!(n===void 0&&e===void 0))return{...n??{},...e??{}}}o(Te,"mergeVerificationConfig");function Ie(n,e){if(n===void 0&&e===void 0)return;const t={...n??{},...e??{}};return(n?.oauthAccess!==void 0||e?.oauthAccess!==void 0)&&(t.oauthAccess={...n?.oauthAccess??{},...e?.oauthAccess??{}}),t}o(Ie,"mergeClaudeConfig");function x(n){return{global:(0,b.join)((0,T.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 xe=["global","project","local"];function we(n,e){const t=x(e);if(n==="global")return t.global;if(n==="project"){if(t.project===void 0)throw new Error("Project layer requested but no projectDir was provided.");return t.project}if(t.local===void 0)throw new Error("Local layer requested but no projectDir was provided.");return t.local}o(we,"getTargetConfigPath");function je(n){if(n.global===!0&&n.local===!0)throw new Error("Pass at most one of --global / --local.");return n.global===!0?"global":n.local===!0?"local":"project"}o(je,"resolveConfigTargetFromFlags");function v(n){const e=O(n);return(0,E.existsSync)(n)&&(_e(e,n),me(e,n),ve(e,n)),e}o(v,"loadAndValidateLayer");const w=[{envVar:"IRONBEE_API_KEY",configPath:"collector.apiKey"},{envVar:"IRONBEE_OAUTH_TOKEN",configPath:"collector.oauthToken"}];function Re(n,e,t){const r=e.split(".");let i=n;for(let s=0;s<r.length-1;s++){const l=r[s],a=i[l];a!=null&&typeof a=="object"&&!Array.isArray(a)?i[l]={...a}:i[l]={},i=i[l]}i[r[r.length-1]]=t}o(Re,"setAtConfigPath");function W(n){let e;for(const t of w){const r=process.env[t.envVar];if(r===void 0||r.length===0)continue;e===void 0&&(e={...n});const i=t.coerce?t.coerce(r):r;Re(e,t.configPath,i)}return e??n}o(W,"applyEnvOverrides");function he(n){for(const e of w){if(e.configPath!==n)continue;const t=process.env[e.envVar];if(t!==void 0&&t.length>0)return e}}o(he,"findActiveEnvOverride");function c(n){const e=x(n),t=v(e.global),r=e.project?v(e.project):{},i=e.local?v(e.local):{},s=k(k(t,r),i);return W(s)}o(c,"loadConfig");function Oe(n){let e=n.replace(/\{([^}]+)\}/g,(t,r)=>`(${r.split(",").map(i=>i.trim()).join("|")})`);return e=e.replace(/\*\*\//g,"\0DSS\0").replace(/\*\*/g,"\0DS\0").replace(/\*/g,"\0SS\0").replace(/\?/g,"\0QM\0"),e=e.replace(/[.+^$\\[\]]/g,"\\$&"),e=e.replace(/\x00DSS\x00/g,"(?:.*/)?").replace(/\x00DS\x00/g,".*").replace(/\x00SS\x00/g,"[^/]*").replace(/\x00QM\x00/g,"[^/]"),new RegExp(`(^|/)${e}$`)}o(Oe,"globToRegExp");function C(n,e){const t=n.replace(/\\/g,"/");for(const r of e)if(Oe(r).test(t))return!0;return!1}o(C,"matchesAny");function ke(n,e){if(e==="browser")return n.browser;if(e==="node")return n.node;if(e==="backend")return n.backend;if(e==="android")return n.android}o(ke,"getCycleBlock");function A(n,e){const t=ke(n,e);if(t!==void 0&&t.enable===!1)return[];const r=U[e]??[];if(t===void 0)return N.has(e)?[...r]:[];if(Array.isArray(t.verifyPatterns)&&t.verifyPatterns.length===0)return[];const i=t.verifyPatterns??r,s=t.additionalVerifyPatterns??[];return[...i,...s]}o(A,"getCyclePatterns");function Q(n,e){const t=e.ignoredVerifyPatterns??[];if(t.length>0&&C(n,t))return[];const r=[];C(n,A(e,"browser"))&&r.push("browser");for(const i of I){const s=A(e,i);s.length>0&&C(n,s)&&r.push(i)}return r}o(Q,"getActiveCycles");function Be(n,e){return Q(n,e).length>0}o(Be,"requiresVerification");function Le(n,e){return R(n)?z(n,e):!1}o(Le,"isCycleEnabled");function z(n,e){return A(n,e).length>0}o(z,"isCyclePatternsActive");function Se(n,e){let t,r;if(e==="browser"?(t=n.browser?.alwaysRequired??q,r=n.browser?.evidencePaths??[]):e==="node"?(t=n.node?.alwaysRequired??$,r=n.node?.evidencePaths??K):e==="backend"?(t=n.backend?.alwaysRequired??Y,r=n.backend?.evidencePaths??X):e==="android"?(t=n.android?.alwaysRequired??H,r=n.android?.evidencePaths??G):(t=[],r=[]),t.length===0&&r.length===0)throw new Error(`Invalid required-tools config for cycle '${e}': both 'alwaysRequired' and 'evidencePaths' are empty. At least one must specify required tools.`);return{alwaysRequired:t,evidencePaths:r}}o(Se,"getRequiredToolsConfig");const B="npx",De="^0.11.0",L=["-y",`@ironbee-ai/devtools@${De}`],Ne={TOOL_NAME_PREFIX:"bdt_",TOOL_INPUT_METADATA_ENABLE:"true"},Pe={PLATFORM:"node",TOOL_NAME_PREFIX:"ndt_",TOOL_INPUT_METADATA_ENABLE:"true"},Me={PLATFORM:"backend",TOOL_NAME_PREFIX:"bedt_",TOOL_INPUT_METADATA_ENABLE:"true"},Fe={PLATFORM:"android",TOOL_NAME_PREFIX:"adt_",TOOL_INPUT_METADATA_ENABLE:"true"},Ve={BROWSER_DEVTOOLS_INSTALL_CHROMIUM:"true"},Ue={},qe={},$e={};function Ke(n){return se(n)?{}:{TELEMETRY_ENABLE:"false"}}o(Ke,"buildTelemetryEnv");function Ye(n){return ae(n)?{COLLECTOR_EVENTS_TOOL_DETAILS_ENABLE:"false",COLLECTOR_ARTIFACTS_ENABLE:"false"}:{}}o(Ye,"buildPrivacyEnv");function Xe(n,e){if(!j(n))return{};const t=n.collector,i=O((0,b.join)((0,T.homedir)(),".ironbee","config.json")).collector??{},s=typeof i.oauthToken=="string"&&i.oauthToken.length>0,l=typeof i.apiKey=="string"&&i.apiKey.length>0;let a;t.oauthToken?a=s?"X-OAuth-Token=${file:~/.ironbee/config.json#collector.oauthToken}":`X-OAuth-Token=${t.oauthToken}`:a=l?"X-API-Key=${file:~/.ironbee/config.json#collector.apiKey}":`X-API-Key=${t.apiKey}`;const u={OTEL_ENABLE:"true",OTEL_EXPORTER_HTTP_URL:t.url,OTEL_EXPORTER_HTTP_HEADERS:a,OTEL_EXPORTER_TYPE:"otlp/http-protobuf"};return e==="browser"&&(u.OTEL_INSTRUMENTATION_USER_INTERACTION_EVENTS="change,input,click",u.BROWSER_HEADLESS_ENABLE="true"),u}o(Xe,"buildOTELEnv");function m(n,e,t,r,i){const s=Xe(n,i),l=Ke(n),a=Ye(n),u=n[e];if(u&&typeof u=="object"&&!Array.isArray(u)){const f=u;if(f.mcp&&typeof f.mcp=="object"&&!Array.isArray(f.mcp)){const g={...f.mcp},d={...s,...l,...a,...g.env??{},...t};return g.env=d,g}const h={};if(f.env&&typeof f.env=="object"&&!Array.isArray(f.env)){const g=f.env;for(const d of Object.keys(g))typeof g[d]=="string"&&(h[d]=g[d])}return{command:B,args:[...L],env:{...r,...s,...l,...a,...h,...t}}}return{command:B,args:[...L],env:{...r,...s,...l,...a,...t}}}o(m,"buildMcpEntry");function He(n){const e=c(n);return m(e,"browserDevTools",Ne,Ve,"browser")}o(He,"getMcpServerEntry");function Ge(n){const e=c(n);return m(e,"nodeDevTools",Pe,Ue,"node")}o(Ge,"getNodeDevToolsMcpEntry");function We(n){const e=c(n);return m(e,"backendDevTools",Me,qe,"backend")}o(We,"getBackendDevToolsMcpEntry");function Qe(n){const e=c(n);return m(e,"androidDevTools",Fe,$e,"android")}o(Qe,"getAndroidDevToolsMcpEntry");function ze(n){return typeof n.maxRetries=="number"&&n.maxRetries>0?n.maxRetries:ye}o(ze,"getMaxRetries");function j(n){if(process.env.IRONBEE_COLLECTOR==="false")return!1;const e=n.collector;if(!e||e.enable===!1||typeof e.url!="string"||e.url.length===0)return!1;const t=typeof e.oauthToken=="string"&&e.oauthToken.length>0,r=typeof e.apiKey=="string"&&e.apiKey.length>0;return!(!t&&!r)}o(j,"isCollectorConfigured");function Je(n){const e=c(n);return p(e,e.jobQueue)}o(Je,"isJobQueueEnabled");function Ze(n){const e=c(n);return p(e,e.recording)}o(Ze,"isRecordingEnabled");function en(n){return p(n,n.statusLine)}o(en,"isSessionStatusEnabled");function nn(n){const e=n.statusLine;return e!==void 0&&e.renderDefault===!0}o(nn,"getStatusLineRenderDefault");function tn(n){const e=n.statusLine?.emitMinIntervalSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:10}o(tn,"getStatusLineEmitMinIntervalSeconds");const J=60;function on(n){return n.claude?.oauthAccess?.enable!==!1}o(on,"getClaudeOauthAccessEnabled");function rn(n){const e=n.claude?.oauthAccess?.usageTtlSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:J}o(rn,"getClaudeOauthAccessUsageTtlSeconds");const Z=15986,ee=600,ne=30,te=0;function sn(n){return p(n,n.otel)}o(sn,"isOTELEnabled");function an(n){const e=n.otel?.port;return typeof e=="number"&&Number.isInteger(e)&&e>0&&e<65536?e:Z}o(an,"getOTELPort");function cn(n){const e=n.otel?.idleTimeoutSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>0?e:ee}o(cn,"getOTELIdleTimeoutSeconds");function ln(n){const e=n.otel?.ensureMinIntervalSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:ne}o(ln,"getOTELEnsureMinIntervalSeconds");function un(n){const e=n.otel?.emitMinIntervalSeconds;return typeof e=="number"&&Number.isFinite(e)&&e>=0?e:te}o(un,"getOTELEmitMinIntervalSeconds");function fn(n){const e=n.statusLine?.refreshInterval;if(typeof e=="number"&&Number.isFinite(e)&&e>=1)return e}o(fn,"getStatusLineRefreshInterval");function p(n,e){return e!=null&&typeof e=="object"&&!Array.isArray(e)?e.enable!==!1:j(n)}o(p,"isFeatureEnabledWithCollectorAutoEnable");function Rn(n){return n==null||typeof n!="object"||Array.isArray(n)?!1:n.enable!==!1}o(Rn,"isPresenceEnabled");function R(n){const e=n.verification;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.enable!==!1}o(R,"getVerificationEnabled");function oe(n){const e=n.verification;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.auto!==!1}o(oe,"getAutoVerifyEnabled");const re=65536,ie=1;function gn(n){const e=n.verificationContext;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.enable!==!1}o(gn,"getVerificationContextEnabled");function dn(n){return n.verificationContext?.source==="actions"?"actions":"git"}o(dn,"getVerificationContextSource");function pn(n){const e=n.verificationContext?.commitDepth;return typeof e=="number"&&Number.isFinite(e)&&e>=0?Math.floor(e):ie}o(pn,"getVerificationContextCommitDepth");function bn(n){const e=n.verificationContext?.maxBytes;return typeof e=="number"&&Number.isFinite(e)&&e>0?Math.floor(e):re}o(bn,"getVerificationContextMaxBytes");function En(n,e){const t=n.ignoredVerifyPatterns??[];return t.length>0&&C(e,t)}o(En,"isIgnoredVerifyPath");function yn(n){return R(n)?oe(n)?"enforce":"assist":"monitor"}o(yn,"getVerificationMode");function se(n){const e=n.telemetry;return e==null||typeof e!="object"||Array.isArray(e)?!0:e.enable!==!1}o(se,"getTelemetryEnabled");function ae(n){const e=n.privacy;return e==null||typeof e!="object"||Array.isArray(e)?!1:e.enable===!0}o(ae,"getPrivacyEnabled");const S=65536;function _n(n){const e=n.fileChange;return!e||typeof e!="object"||Array.isArray(e)?!1:e.captureChangeset===!0}o(_n,"getCaptureFileChangeset");function Cn(n){const e=n.fileChange;if(!e||typeof e!="object"||Array.isArray(e))return S;const t=e.maxChangesetBytes;return typeof t!="number"||!Number.isFinite(t)||t<=0?S:Math.floor(t)}o(Cn,"getMaxChangesetBytes");function mn(n){const e=c(n);return p(e,e.analytics)}o(mn,"isAnalyticsEnabled");function vn(n){const t=c(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!0:t.emitOnStop!==!1}o(vn,"isAnalyticsEmitOnStopEnabled");function An(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(An,"getAnalyticsEmitOnStopMinIntervalSeconds");function Tn(n){const t=c(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!1:t.emitTurnEvents===!0}o(Tn,"isAnalyticsTurnEventsEnabled");function In(n){const t=c(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!1:t.emitStepEvents===!0}o(In,"isAnalyticsStepEventsEnabled");function xn(n){const t=c(n).analytics;return t===null||typeof t!="object"||Array.isArray(t)?!0:t.emitApiRequestEvents!==!1}o(xn,"isAnalyticsApiRequestEventsEnabled");0&&(module.exports={ALL_CYCLES,CONFIG_TARGETS_BY_PRECEDENCE,CYCLES_ENABLED_BY_DEFAULT,CYCLE_DEFAULT_VERIFY_PATTERNS,CYCLE_TOOL_PREFIXES,CYCLE_TO_SERVER,DEFAULT_ANDROID_ALWAYS_REQUIRED,DEFAULT_ANDROID_EVIDENCE_PATHS,DEFAULT_ANDROID_VERIFY_PATTERNS,DEFAULT_BACKEND_ALWAYS_REQUIRED,DEFAULT_BACKEND_EVIDENCE_PATHS,DEFAULT_BACKEND_VERIFY_PATTERNS,DEFAULT_BROWSER_ALWAYS_REQUIRED,DEFAULT_BROWSER_VERIFY_PATTERNS,DEFAULT_NODE_ALWAYS_REQUIRED,DEFAULT_NODE_EVIDENCE_PATHS,DEFAULT_NODE_VERIFY_PATTERNS,DEFAULT_OAUTH_USAGE_TTL_SECONDS,DEFAULT_OTEL_EMIT_MIN_INTERVAL_SECONDS,DEFAULT_OTEL_ENSURE_MIN_INTERVAL_SECONDS,DEFAULT_OTEL_IDLE_TIMEOUT_SECONDS,DEFAULT_OTEL_PORT,DEFAULT_VERIFICATION_CONTEXT_COMMIT_DEPTH,DEFAULT_VERIFICATION_CONTEXT_MAX_BYTES,ENV_OVERRIDES,OPTIONAL_CYCLES,applyEnvOverrides,findActiveEnvOverride,getActiveCycles,getAnalyticsEmitOnStopMinIntervalSeconds,getAndroidDevToolsMcpEntry,getAutoVerifyEnabled,getBackendDevToolsMcpEntry,getCaptureFileChangeset,getClaudeOauthAccessEnabled,getClaudeOauthAccessUsageTtlSeconds,getConfigLayerPaths,getMaxChangesetBytes,getMaxRetries,getMcpServerEntry,getNodeDevToolsMcpEntry,getOTELEmitMinIntervalSeconds,getOTELEnsureMinIntervalSeconds,getOTELIdleTimeoutSeconds,getOTELPort,getPrivacyEnabled,getRequiredToolsConfig,getStatusLineEmitMinIntervalSeconds,getStatusLineRefreshInterval,getStatusLineRenderDefault,getTargetConfigPath,getTelemetryEnabled,getVerificationContextCommitDepth,getVerificationContextEnabled,getVerificationContextMaxBytes,getVerificationContextSource,getVerificationEnabled,getVerificationMode,getVerificationModel,isAnalyticsApiRequestEventsEnabled,isAnalyticsEmitOnStopEnabled,isAnalyticsEnabled,isAnalyticsStepEventsEnabled,isAnalyticsTurnEventsEnabled,isCollectorConfigured,isCycleEnabled,isCyclePatternsActive,isIgnoredVerifyPath,isJobQueueEnabled,isOTELEnabled,isRecordingEnabled,isSessionStatusEnabled,loadConfig,requiresVerification,resolveConfigTargetFromFlags});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var a=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var h=Object.prototype.hasOwnProperty;var n=(e,t)=>a(e,"name",{value:t,configurable:!0});var g=(e,t)=>{for(var o in t)a(e,o,{get:t[o],enumerable:!0})},y=(e,t,o,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of u(t))!h.call(e,i)&&i!==o&&a(e,i,{get:()=>t[i],enumerable:!(r=p(t,i))||r.enumerable});return e};var b=e=>y(a({},"__esModule",{value:!0}),e);var k={};g(k,{ARTIFACT_AFFECTING_TOP_KEYS:()=>v,CONFIG_SCHEMA:()=>d,GROUP_ORDER:()=>s,GROUP_TITLES:()=>f,findSchemaEntry:()=>A,groupOf:()=>c,groupRank:()=>l,groupTitle:()=>w,orderedEntries:()=>T,topKey:()=>m});module.exports=b(k);const v=new Set(["verification","collector","browser","node","backend","android","browserDevTools","nodeDevTools","backendDevTools","androidDevTools","telemetry","privacy","statusLine","otel"]),s=["general","verification","verificationContext","browser","node","backend","android","collector","recording","jobQueue","analytics","statusLine","claude","telemetry","privacy","otel","fileChange","import","browserDevTools","nodeDevTools","backendDevTools","androidDevTools"],f={general:"General",verification:"Verification",verificationContext:"Verification context",browser:"Browser cycle",node:"Node cycle",backend:"Backend cycle",android:"Android cycle",collector:"Collector",recording:"Recording",jobQueue:"Job queue",analytics:"Analytics",statusLine:"Statusline",claude:"Claude",telemetry:"Telemetry",privacy:"Privacy",otel:"OTEL collector",fileChange:"File change",import:"Import",browserDevTools:"Browser DevTools MCP",nodeDevTools:"Node DevTools MCP",backendDevTools:"Backend DevTools MCP",androidDevTools:"Android DevTools MCP"};function m(e){const t=e.indexOf(".");return t===-1?e:e.slice(0,t)}n(m,"topKey");function c(e){const t=e.indexOf(".");return t===-1?"general":e.slice(0,t)}n(c,"groupOf");function w(e){return f[e]??e}n(w,"groupTitle");function l(e){const t=s.indexOf(e);return t===-1?s.length:t}n(l,"groupRank");const d=[{path:"ignoredVerifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns excluded from verification, applied to every cycle (browser / node / backend). Checked first \u2014 a match here activates no cycle regardless of other patterns.",def:"[]",artifactAffecting:!1},{path:"maxRetries",type:"number",editor:"number",description:"Max verification retry attempts before the gate allows completion despite failures. Single global counter regardless of how many cycles ran.",def:"3",artifactAffecting:!1},{path:"verification.enable",type:"boolean",editor:"toggle",description:"Master enforcement switch. Inverse semantics \u2014 verification is the core feature, opt out with false. When false, IronBee runs monitoring-only: no enforcement hooks, no skill/rule, no MCP servers; only session/activity/tool_call events flow to the collector.",def:"true",artifactAffecting:!0},{path:"verification.auto",type:"boolean",editor:"toggle",description:'Automatic-enforcement sub-toggle (only meaningful when verification.enable !== false). Inverse semantics \u2014 opt out with false for "assist mode": the /ironbee-verify command + MCP servers stay installed so the agent can verify manually, but nothing is enforced \u2014 no Stop gate, non-blocking (soft) PreToolUse hooks, and the skill/rule are omitted. true \u2192 full enforce mode.',def:"true",artifactAffecting:!0},{path:"verification.model",type:"json",editor:"json",description:`Model the delegated verifier sub-agent uses. Unset \u2192 the verifier inherits the session model (Claude verifier omits model: \u2192 inherit; Codex verifier omits agent-toml model \u2192 inherits config.toml's model). Set to PIN a specific model \u2014 e.g. verify on a cheaper/faster model than the main agent, or guarantee a model on Codex when config.toml has none. Two shapes: a string (applies to all clients, e.g. "sonnet" / "gpt-5.5") or a per-client object { claude: "sonnet", codex: "gpt-5.5" } when a project has both clients. Cursor has no verifier sub-agent \u2192 no-op there. Never resolves to a literal "inherit" on Codex (a 400). Artifact-affecting.`,def:"unset (inherit the session model)",artifactAffecting:!0},{path:"verificationContext.enable",type:"boolean",editor:"toggle",description:"Master switch for path-scoped verification context. When a cycle begins, the first devtools tool call injects the .ironbee/VERIFICATION.md files on/above the changed paths (author-written area guidance) into the agent's context via the host's additionalContext channel. Advisory only (does not gate). Inverse semantics \u2014 default-on, opt out with false. Not artifact-affecting (read live).",def:"true",artifactAffecting:!1},{path:"verificationContext.source",type:"string",editor:"enum",enumValues:["git","actions"],description:`Changed-path source. "git" (default) = working tree + last N commits, with an actions.jsonl fallback when not a git repo. "actions" = IronBee's own file_change events only (no git subprocess).`,def:"git",artifactAffecting:!1},{path:"verificationContext.commitDepth",type:"number",editor:"number",description:'Number of recent commits included on the git source (uncommitted \u222A last N commits). 0 = uncommitted only. Ignored when source is "actions".',def:"1",artifactAffecting:!1},{path:"verificationContext.maxBytes",type:"number",editor:"number",description:"Aggregate byte cap on the injected context string. When exceeded, the least-specific (root-side) docs are dropped first (leaf-first truncation priority).",def:"65536 (64 KB)",artifactAffecting:!1},{path:"browser.enable",type:"boolean",editor:"toggle",description:"Explicit on/off for the browser cycle. Written false by `browser disable`, stripped by `browser enable`. When false the cycle is disabled regardless of patterns.",def:"(absent \u2192 on; browser is the only default-on cycle)",artifactAffecting:!0},{path:"browser.verifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns for files requiring browser verification. Four-state: absent \u2192 code defaults (40+ extensions); [] \u2192 hard kill; non-empty \u2192 custom patterns (replaces defaults).",def:"40+ code extensions when unset; [] hard-disables",artifactAffecting:!0},{path:"browser.additionalVerifyPatterns",type:"string-array",editor:"string-list",description:"Extra patterns appended to browser.verifyPatterns (or to code defaults when verifyPatterns is unset). Ignored when verifyPatterns is [] (hard kill wins).",def:"[]",artifactAffecting:!0},{path:"browser.alwaysRequired",type:"string-array",editor:"string-list",description:"Browser-cycle required tools (all-of). The verify-gate blocks completion until every listed bdt_* tool was used.",def:"bdt_navigation_go-to, bdt_content_take-screenshot, bdt_a11y_take-aria-snapshot, bdt_o11y_get-console-messages",artifactAffecting:!0},{path:"browser.evidencePaths",type:"json",editor:"json",description:"Alternative tool-satisfaction paths (any-of). Browser uses pure all-of, so default is empty. Each path: { name, allOf: (string | { anyOf: string[] })[] }.",def:"[]",artifactAffecting:!0},{path:"node.enable",type:"boolean",editor:"toggle",description:"Explicit on/off for the Node.js runtime debug cycle (node-devtools, ndt_* V8 inspector probes). Opt-in \u2014 written by `node enable`.",def:"(absent \u2192 off; node is opt-in)",artifactAffecting:!0},{path:"node.verifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns for the Node.js runtime debug cycle. Default-off \u2014 block absent = inert. Block present + unset \u2192 9 code defaults (server/api/routes paths).",def:"block absent \u2192 disabled; present + unset \u2192 code defaults",artifactAffecting:!0},{path:"node.additionalVerifyPatterns",type:"string-array",editor:"string-list",description:"Extra patterns appended to node.verifyPatterns (or to code defaults when unset). Ignored when verifyPatterns is [].",def:"[]",artifactAffecting:!0},{path:"node.alwaysRequired",type:"string-array",editor:"string-list",description:"Node-cycle required tools (all-of). ndt_debug_connect always; evidence paths supply the rest.",def:"[ndt_debug_connect]",artifactAffecting:!0},{path:"node.evidencePaths",type:"json",editor:"json",description:"Alternative tool paths (any-of). Default: probe path (a put-*point AND get-probe-snapshots) OR log path (get-logs).",def:"probe path + log path",artifactAffecting:!0},{path:"backend.enable",type:"boolean",editor:"toggle",description:"Explicit on/off for the runtime-agnostic backend protocol cycle (backend-devtools, bedt_* HTTP/gRPC/GraphQL/WebSocket). Opt-in \u2014 written by `backend enable`.",def:"(absent \u2192 off; backend is opt-in)",artifactAffecting:!0},{path:"backend.verifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns for the backend protocol cycle. Default-off \u2014 block absent = inert. Block present + unset \u2192 13 multi-language code defaults (ts/js/py/go/java/rb/cs/rs/kt/scala/ex/php/clj).",def:"block absent \u2192 disabled; present + unset \u2192 code defaults",artifactAffecting:!0},{path:"backend.additionalVerifyPatterns",type:"string-array",editor:"string-list",description:"Extra patterns appended to backend.verifyPatterns (or to code defaults when unset). Ignored when verifyPatterns is [].",def:"[]",artifactAffecting:!0},{path:"backend.alwaysRequired",type:"string-array",editor:"string-list",description:"Backend-cycle required tools (all-of). Empty by default \u2014 backend uses any-of evidence paths instead.",def:"[]",artifactAffecting:!0},{path:"backend.evidencePaths",type:"json",editor:"json",description:"Alternative tool paths (any-of). Default three: protocol-call (any request tool) OR log-evidence (register-source + read) OR db-evidence (db_connect + a read op).",def:"protocol-call OR log-evidence OR db-evidence",artifactAffecting:!0},{path:"android.enable",type:"boolean",editor:"toggle",description:"Explicit on/off for the Android mobile verification cycle (android-devtools, adt_* device/emulator interaction). Opt-in \u2014 written by `android enable`.",def:"(absent \u2192 off; android is opt-in)",artifactAffecting:!0},{path:"android.verifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns for the Android mobile verification cycle. Default-off \u2014 block absent = inert. Block present + unset \u2192 code defaults (Android/React Native paths).",def:"block absent \u2192 disabled; present + unset \u2192 code defaults",artifactAffecting:!0},{path:"android.additionalVerifyPatterns",type:"string-array",editor:"string-list",description:"Extra patterns appended to android.verifyPatterns (or to code defaults when unset). Ignored when verifyPatterns is [].",def:"[]",artifactAffecting:!0},{path:"android.alwaysRequired",type:"string-array",editor:"string-list",description:"Android-cycle required tools (all-of). adt_device_connect always; evidence paths supply the rest.",def:"[adt_device_connect]",artifactAffecting:!0},{path:"android.evidencePaths",type:"json",editor:"json",description:"Alternative tool paths (any-of). Default two: device-evidence (UI interaction + screenshot + UI snapshot) OR log-evidence (Logcat read/follow).",def:"device-evidence OR log-evidence",artifactAffecting:!0},{path:"collector.enable",type:"boolean",editor:"toggle",description:"Master switch for the IronBee Collector. Implicitly true when the section has both url and apiKey; set false to suspend while keeping url/apiKey/batchSize around.",def:"implicit true when url + 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.apiKey",type:"string",editor:"text",description:"API key for collector auth (X-API-Key header). Required for the collector to be active. Can be supplied via the IRONBEE_API_KEY env var instead of committing it.",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:"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 T(){return[...d].sort((e,t)=>{const o=l(c(e.path)),r=l(c(t.path));return o!==r?o-r:e.path.localeCompare(t.path)})}n(T,"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,r)=>{if(t&&typeof t=="object"||typeof t=="function")for(let i of u(t))!h.call(e,i)&&i!==o&&a(e,i,{get:()=>t[i],enumerable:!(r=p(t,i))||r.enumerable});return e};var b=e=>y(a({},"__esModule",{value:!0}),e);var k={};g(k,{ARTIFACT_AFFECTING_TOP_KEYS:()=>v,CONFIG_SCHEMA:()=>d,GROUP_ORDER:()=>s,GROUP_TITLES:()=>f,findSchemaEntry:()=>A,groupOf:()=>c,groupRank:()=>l,groupTitle:()=>w,orderedEntries:()=>T,topKey:()=>m});module.exports=b(k);const v=new Set(["verification","collector","browser","node","backend","android","browserDevTools","nodeDevTools","backendDevTools","androidDevTools","telemetry","privacy","statusLine","otel"]),s=["general","verification","verificationContext","browser","node","backend","android","collector","recording","jobQueue","analytics","statusLine","claude","telemetry","privacy","otel","fileChange","import","browserDevTools","nodeDevTools","backendDevTools","androidDevTools"],f={general:"General",verification:"Verification",verificationContext:"Verification context",browser:"Browser cycle",node:"Node cycle",backend:"Backend cycle",android:"Android cycle",collector:"Collector",recording:"Recording",jobQueue:"Job queue",analytics:"Analytics",statusLine:"Statusline",claude:"Claude",telemetry:"Telemetry",privacy:"Privacy",otel:"OTEL collector",fileChange:"File change",import:"Import",browserDevTools:"Browser DevTools MCP",nodeDevTools:"Node DevTools MCP",backendDevTools:"Backend DevTools MCP",androidDevTools:"Android DevTools MCP"};function m(e){const t=e.indexOf(".");return t===-1?e:e.slice(0,t)}n(m,"topKey");function c(e){const t=e.indexOf(".");return t===-1?"general":e.slice(0,t)}n(c,"groupOf");function w(e){return f[e]??e}n(w,"groupTitle");function l(e){const t=s.indexOf(e);return t===-1?s.length:t}n(l,"groupRank");const d=[{path:"ignoredVerifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns excluded from verification, applied to every cycle (browser / node / backend). Checked first \u2014 a match here activates no cycle regardless of other patterns.",def:"[]",artifactAffecting:!1},{path:"maxRetries",type:"number",editor:"number",description:"Max verification retry attempts before the gate allows completion despite failures. Single global counter regardless of how many cycles ran.",def:"3",artifactAffecting:!1},{path:"verification.enable",type:"boolean",editor:"toggle",description:"Master enforcement switch. Inverse semantics \u2014 verification is the core feature, opt out with false. When false, IronBee runs monitoring-only: no enforcement hooks, no skill/rule, no MCP servers; only session/activity/tool_call events flow to the collector.",def:"true",artifactAffecting:!0},{path:"verification.auto",type:"boolean",editor:"toggle",description:'Automatic-enforcement sub-toggle (only meaningful when verification.enable !== false). Inverse semantics \u2014 opt out with false for "assist mode": the /ironbee-verify command + MCP servers stay installed so the agent can verify manually, but nothing is enforced \u2014 no Stop gate, non-blocking (soft) PreToolUse hooks, and the skill/rule are omitted. true \u2192 full enforce mode.',def:"true",artifactAffecting:!0},{path:"verification.model",type:"json",editor:"json",description:`Model the delegated verifier sub-agent uses. Unset \u2192 the verifier inherits the session model (Claude verifier omits model: \u2192 inherit; Codex verifier omits agent-toml model \u2192 inherits config.toml's model). Set to PIN a specific model \u2014 e.g. verify on a cheaper/faster model than the main agent, or guarantee a model on Codex when config.toml has none. Two shapes: a string (applies to all clients, e.g. "sonnet" / "gpt-5.5") or a per-client object { claude: "sonnet", codex: "gpt-5.5" } when a project has both clients. Cursor has no verifier sub-agent \u2192 no-op there. Never resolves to a literal "inherit" on Codex (a 400). Artifact-affecting.`,def:"unset (inherit the session model)",artifactAffecting:!0},{path:"verificationContext.enable",type:"boolean",editor:"toggle",description:"Master switch for path-scoped verification context. When a cycle begins, the first devtools tool call injects the .ironbee/VERIFICATION.md files on/above the changed paths (author-written area guidance) into the agent's context via the host's additionalContext channel. Advisory only (does not gate). Inverse semantics \u2014 default-on, opt out with false. Not artifact-affecting (read live).",def:"true",artifactAffecting:!1},{path:"verificationContext.source",type:"string",editor:"enum",enumValues:["git","actions"],description:`Changed-path source. "git" (default) = working tree + last N commits, with an actions.jsonl fallback when not a git repo. "actions" = IronBee's own file_change events only (no git subprocess).`,def:"git",artifactAffecting:!1},{path:"verificationContext.commitDepth",type:"number",editor:"number",description:'Number of recent commits included on the git source (uncommitted \u222A last N commits). 0 = uncommitted only. Ignored when source is "actions".',def:"1",artifactAffecting:!1},{path:"verificationContext.maxBytes",type:"number",editor:"number",description:"Aggregate byte cap on the injected context string. When exceeded, the least-specific (root-side) docs are dropped first (leaf-first truncation priority).",def:"65536 (64 KB)",artifactAffecting:!1},{path:"browser.enable",type:"boolean",editor:"toggle",description:"Explicit on/off for the browser cycle. Written false by `browser disable`, stripped by `browser enable`. When false the cycle is disabled regardless of patterns.",def:"(absent \u2192 on; browser is the only default-on cycle)",artifactAffecting:!0},{path:"browser.verifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns for files requiring browser verification. Four-state: absent \u2192 code defaults (40+ extensions); [] \u2192 hard kill; non-empty \u2192 custom patterns (replaces defaults).",def:"40+ code extensions when unset; [] hard-disables",artifactAffecting:!0},{path:"browser.additionalVerifyPatterns",type:"string-array",editor:"string-list",description:"Extra patterns appended to browser.verifyPatterns (or to code defaults when verifyPatterns is unset). Ignored when verifyPatterns is [] (hard kill wins).",def:"[]",artifactAffecting:!0},{path:"browser.alwaysRequired",type:"string-array",editor:"string-list",description:"Browser-cycle required tools (all-of). The verify-gate blocks completion until every listed bdt_* tool was used.",def:"bdt_navigation_go-to, bdt_content_take-screenshot, bdt_a11y_take-aria-snapshot, bdt_o11y_get-console-messages",artifactAffecting:!0},{path:"browser.evidencePaths",type:"json",editor:"json",description:"Alternative tool-satisfaction paths (any-of). Browser uses pure all-of, so default is empty. Each path: { name, allOf: (string | { anyOf: string[] })[] }.",def:"[]",artifactAffecting:!0},{path:"node.enable",type:"boolean",editor:"toggle",description:"Explicit on/off for the Node.js runtime debug cycle (node-devtools, ndt_* V8 inspector probes). Opt-in \u2014 written by `node enable`.",def:"(absent \u2192 off; node is opt-in)",artifactAffecting:!0},{path:"node.verifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns for the Node.js runtime debug cycle. Default-off \u2014 block absent = inert. Block present + unset \u2192 9 code defaults (server/api/routes paths).",def:"block absent \u2192 disabled; present + unset \u2192 code defaults",artifactAffecting:!0},{path:"node.additionalVerifyPatterns",type:"string-array",editor:"string-list",description:"Extra patterns appended to node.verifyPatterns (or to code defaults when unset). Ignored when verifyPatterns is [].",def:"[]",artifactAffecting:!0},{path:"node.alwaysRequired",type:"string-array",editor:"string-list",description:"Node-cycle required tools (all-of). ndt_debug_connect always; evidence paths supply the rest.",def:"[ndt_debug_connect]",artifactAffecting:!0},{path:"node.evidencePaths",type:"json",editor:"json",description:"Alternative tool paths (any-of). Default: probe path (a put-*point AND get-probe-snapshots) OR log path (get-logs).",def:"probe path + log path",artifactAffecting:!0},{path:"backend.enable",type:"boolean",editor:"toggle",description:"Explicit on/off for the runtime-agnostic backend protocol cycle (backend-devtools, bedt_* HTTP/gRPC/GraphQL/WebSocket). Opt-in \u2014 written by `backend enable`.",def:"(absent \u2192 off; backend is opt-in)",artifactAffecting:!0},{path:"backend.verifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns for the backend protocol cycle. Default-off \u2014 block absent = inert. Block present + unset \u2192 13 multi-language code defaults (ts/js/py/go/java/rb/cs/rs/kt/scala/ex/php/clj).",def:"block absent \u2192 disabled; present + unset \u2192 code defaults",artifactAffecting:!0},{path:"backend.additionalVerifyPatterns",type:"string-array",editor:"string-list",description:"Extra patterns appended to backend.verifyPatterns (or to code defaults when unset). Ignored when verifyPatterns is [].",def:"[]",artifactAffecting:!0},{path:"backend.alwaysRequired",type:"string-array",editor:"string-list",description:"Backend-cycle required tools (all-of). Empty by default \u2014 backend uses any-of evidence paths instead.",def:"[]",artifactAffecting:!0},{path:"backend.evidencePaths",type:"json",editor:"json",description:"Alternative tool paths (any-of). Default three: protocol-call (any request tool) OR log-evidence (register-source + read) OR db-evidence (db_connect + a read op).",def:"protocol-call OR log-evidence OR db-evidence",artifactAffecting:!0},{path:"android.enable",type:"boolean",editor:"toggle",description:"Explicit on/off for the Android mobile verification cycle (android-devtools, adt_* device/emulator interaction). Opt-in \u2014 written by `android enable`.",def:"(absent \u2192 off; android is opt-in)",artifactAffecting:!0},{path:"android.verifyPatterns",type:"string-array",editor:"string-list",description:"Glob patterns for the Android mobile verification cycle. Default-off \u2014 block absent = inert. Block present + unset \u2192 code defaults (Android/React Native paths).",def:"block absent \u2192 disabled; present + unset \u2192 code defaults",artifactAffecting:!0},{path:"android.additionalVerifyPatterns",type:"string-array",editor:"string-list",description:"Extra patterns appended to android.verifyPatterns (or to code defaults when unset). Ignored when verifyPatterns is [].",def:"[]",artifactAffecting:!0},{path:"android.alwaysRequired",type:"string-array",editor:"string-list",description:"Android-cycle required tools (all-of). adt_device_connect always; evidence paths supply the rest.",def:"[adt_device_connect]",artifactAffecting:!0},{path:"android.evidencePaths",type:"json",editor:"json",description:"Alternative tool paths (any-of). Default two: device-evidence (UI interaction + screenshot + UI snapshot) OR log-evidence (Logcat read/follow).",def:"device-evidence OR log-evidence",artifactAffecting:!0},{path:"collector.enable",type:"boolean",editor:"toggle",description:"Master switch for the IronBee Collector. Implicitly true when the section has url and at least one credential (oauthToken or apiKey); set false to suspend while keeping url/oauthToken/apiKey/batchSize around.",def:"implicit true when url + (oauthToken or apiKey) set",artifactAffecting:!0},{path:"collector.url",type:"string",editor:"text",description:"Remote collector endpoint URL (IronBee Platform). Required for the collector to be active. Events POST to {url}/v1/events.",def:"(unset \u2192 disabled)",artifactAffecting:!0},{path:"collector.oauthToken",type:"string",editor:"text",description:"Personal access token for collector auth (X-OAuth-Token header). Per-(user, account), independently revocable from the console's /access-tokens page. Minted by `ironbee login` \u2014 the primary path for interactive CLI use. Can be supplied via IRONBEE_OAUTH_TOKEN.",def:"(unset)",artifactAffecting:!0},{path:"collector.apiKey",type:"string",editor:"text",description:"Shared account API key for collector auth (X-API-Key header). Parallel first-class path alongside `oauthToken`, intended for CI / GitHub Actions / deployment tooling and other non-interactive integrations where rotating a per-engineer OAuth token is impractical. Either `oauthToken` OR `apiKey` is required for the collector to be active. Can be supplied via IRONBEE_API_KEY.",def:"(unset \u2192 disabled)",artifactAffecting:!0},{path:"collector.batchSize",type:"number",editor:"number",description:"Max events per POST from the send_event handler (the queue chunks bigger snapshots into N-sized POSTs).",def:"100",artifactAffecting:!0},{path:"collector.timeoutMs",type:"number",editor:"number",description:"Per-request HTTP timeout (ms) for batched analytics sends. Single-event interactive sends keep a fixed 3000ms cap. Clamped to [1000, 60000].",def:"10000",artifactAffecting:!0},{path:"recording.enable",type:"boolean",editor:"toggle",description:"Recording enforcement for the browser + android cycles. Presence opts in; enable:false opts out. Auto-enabled when a collector is configured. Node/backend cycles never trigger recording.",def:"implicit true when section present or collector configured",artifactAffecting:!1},{path:"jobQueue.enable",type:"boolean",editor:"toggle",description:"Master switch for the file-backed job queue. Presence opts in; enable:false opts out. Auto-enabled when a collector is configured (a collector is pointless without a queue feeding it).",def:"implicit true when section present or collector configured",artifactAffecting:!1},{path:"jobQueue.autoFlushSizeBytes",type:"number",editor:"number",description:"Size threshold (bytes) above which submit() spawns a detached worker mid-session. 0 / negative disables this check.",def:"32768 (32 KB)",artifactAffecting:!1},{path:"jobQueue.autoFlushIntervalSeconds",type:"number",editor:"number",description:"Interval threshold (seconds since the live jobs.jsonl was created) above which submit() spawns a detached worker. Complements size \u2014 whichever crosses first flushes. 0 / negative disables.",def:"60",artifactAffecting:!1},{path:"analytics.enable",type:"boolean",editor:"toggle",description:"Master switch for per-session structural analytics. Presence opts in; enable:false opts out. Auto-enabled when a collector is configured.",def:"implicit true when section present or collector configured",artifactAffecting:!1},{path:"analytics.emitOnStop",type:"boolean",editor:"toggle",description:"When true, project + emit analytics at every Stop hook. When false, only at SessionEnd.",def:"true",artifactAffecting:!1},{path:"analytics.emitOnStopMinIntervalSeconds",type:"number",editor:"number",description:"Throttle: skip Stop-hook projection if the last successful emit was within this many seconds. 0 disables the throttle (backend handles rate-limit / dedupe).",def:"0 (disabled)",artifactAffecting:!1},{path:"analytics.emitTurnEvents",type:"boolean",editor:"toggle",description:"Opt-in for per-turn session_turn_analytics wire records. High-volume secondary signal; the base session_analytics record always ships regardless.",def:"false",artifactAffecting:!1},{path:"analytics.emitStepEvents",type:"boolean",editor:"toggle",description:"Opt-in for per-step session_turn_step_analytics wire records (an order of magnitude higher volume than turn events). Independent of emitTurnEvents.",def:"false",artifactAffecting:!1},{path:"analytics.emitApiRequestEvents",type:"boolean",editor:"toggle",description:"Opt-OUT for per-API-request api_request wire records (one per assistant message, success + failure). Primary value for backend cost accounting, so ships by default.",def:"true",artifactAffecting:!1},{path:"statusLine.enable",type:"boolean",editor:"toggle",description:"Master switch for the Claude statusline integration (session_status event + statusline wrapper). Presence opts in; auto-enabled when a collector is configured. Claude-only.",def:"implicit true when section present or collector configured",artifactAffecting:!0},{path:"statusLine.renderDefault",type:"boolean",editor:"toggle",description:"When there is no upstream statusline to chain to, false keeps the statusline silent; true renders a minimal model + context-% line. No effect when the user already has a statusline.",def:"false",artifactAffecting:!0},{path:"statusLine.emitMinIntervalSeconds",type:"number",editor:"number",description:"Minimum seconds between two emitted session_status events, on top of skip-if-unchanged. Rapid changes coalesce to the latest state after the interval. 0 disables the throttle. Read live each tick.",def:"10",artifactAffecting:!0},{path:"statusLine.refreshInterval",type:"number",editor:"number",description:"Claude Code's own statusLine.refreshInterval (seconds, host min 1) \u2014 re-runs the statusline on a timer in addition to event-driven updates. Unset by default. Values < 1 treated as unset.",def:"unset",artifactAffecting:!0},{path:"claude.oauthAccess.enable",type:"boolean",editor:"toggle",description:"Whether IronBee may read the Claude Code OAuth token (macOS Keychain / ~/.claude/.credentials.json) and call OAuth-scoped Anthropic endpoints. Default-on (opt out with false or `ironbee claude oauth-access disable`). First consumer: the statusline rate-limit fallback \u2014 fetches /api/oauth/usage to fill rate_limits for plans the statusline JSON omits them for (team / enterprise). Claude-only; not artifact-affecting (read live).",def:"true",artifactAffecting:!1},{path:"claude.oauthAccess.usageTtlSeconds",type:"number",editor:"number",description:"TTL (seconds) for the statusline OAuth rate-limit fetch cache \u2014 the /api/oauth/usage call + credential read fire at most once per this interval even when the statusline ticks far more often. Default 60; 0 means every tick.",def:"60",artifactAffecting:!1},{path:"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 T(){return[...d].sort((e,t)=>{const o=l(c(e.path)),r=l(c(t.path));return o!==r?o-r:e.path.localeCompare(t.path)})}n(T,"orderedEntries");0&&(module.exports={ARTIFACT_AFFECTING_TOP_KEYS,CONFIG_SCHEMA,GROUP_ORDER,GROUP_TITLES,findSchemaEntry,groupOf,groupRank,groupTitle,orderedEntries,topKey});
|
package/package.json
CHANGED
package/dist/assets/login.html
DELETED
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8" />
|
|
5
|
-
<title>Connected — IronBee</title>
|
|
6
|
-
<style>
|
|
7
|
-
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
|
|
8
|
-
body {
|
|
9
|
-
font-family: system-ui, -apple-system, sans-serif;
|
|
10
|
-
display: flex;
|
|
11
|
-
align-items: center;
|
|
12
|
-
justify-content: center;
|
|
13
|
-
min-height: 100vh;
|
|
14
|
-
background: #0f0f11;
|
|
15
|
-
color: #e5e5e5;
|
|
16
|
-
}
|
|
17
|
-
.container {
|
|
18
|
-
display: flex;
|
|
19
|
-
flex-direction: column;
|
|
20
|
-
align-items: center;
|
|
21
|
-
gap: 20px;
|
|
22
|
-
max-width: 840px;
|
|
23
|
-
padding: 2.5rem;
|
|
24
|
-
text-align: center;
|
|
25
|
-
}
|
|
26
|
-
.logo {
|
|
27
|
-
width: 288px;
|
|
28
|
-
height: 288px;
|
|
29
|
-
opacity: 0.95;
|
|
30
|
-
}
|
|
31
|
-
.logo-row {
|
|
32
|
-
display: flex;
|
|
33
|
-
align-items: center;
|
|
34
|
-
gap: 12px;
|
|
35
|
-
}
|
|
36
|
-
.logo-name {
|
|
37
|
-
font-size: 1.4rem;
|
|
38
|
-
font-weight: 600;
|
|
39
|
-
letter-spacing: 2px;
|
|
40
|
-
color: #e5e5e5;
|
|
41
|
-
}
|
|
42
|
-
h1 {
|
|
43
|
-
font-size: 2rem;
|
|
44
|
-
font-weight: 700;
|
|
45
|
-
color: #e5e5e5;
|
|
46
|
-
letter-spacing: -0.3px;
|
|
47
|
-
margin-top: 4px;
|
|
48
|
-
}
|
|
49
|
-
p {
|
|
50
|
-
color: #888;
|
|
51
|
-
font-size: 0.9rem;
|
|
52
|
-
line-height: 1.6;
|
|
53
|
-
}
|
|
54
|
-
</style>
|
|
55
|
-
</head>
|
|
56
|
-
<body>
|
|
57
|
-
<div class="container">
|
|
58
|
-
<div class="logo-row">
|
|
59
|
-
<svg class="logo" viewBox="0 0 500 500" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
60
|
-
<path d="M217.557 138.711C211.185 166.725 218.839 188.038 224.039 201.771L249.307 154.531L275.674 201.771C285.561 179.579 286.328 161.013 281.167 135.964C277.431 117.837 259.744 95.3889 249.307 84C241.91 92.6058 222.355 117.618 217.557 138.711Z" fill="url(#g0)"/>
|
|
61
|
-
<path d="M249.527 416C223.951 394.731 206.425 358.067 202.396 343.052L249.527 381.394L272.378 362.937L295.559 343.052C290.988 371.089 262.417 403.805 249.527 416Z" fill="url(#g1)"/>
|
|
62
|
-
<path d="M220.854 231.434L250.077 171.12L279.629 231.434L250.077 256.153L220.854 231.434Z" fill="url(#g2)"/>
|
|
63
|
-
<path d="M298.525 286.804C302.568 301.218 299.258 322.399 297.097 331.188L273.587 350.303L249.857 369.749L225.907 349.754L202.397 331.188C197.387 320.465 200.31 297.131 202.397 286.804L249.857 324.486L298.525 286.804Z" fill="url(#g3)"/>
|
|
64
|
-
<path d="M249.856 313.609L203.495 275.268C203.495 263.315 211.552 247.29 215.58 240.771L249.856 267.028L284.573 240.771C291.955 248.066 296.071 266.809 297.207 275.268L249.856 313.609Z" fill="url(#g4)"/>
|
|
65
|
-
<path d="M215.909 165.298C215.36 179.579 220.853 193.752 224.039 201.771L236.563 178.481L249.307 154.531L275.674 201.881C280.947 190.785 284.902 174.526 284.133 167.275C281.277 147.061 274.136 138.052 264.138 125.638C255.679 132.01 244.847 132.141 235.355 125.638C223.38 137.613 216.568 156.289 215.909 165.298Z" fill="url(#g5)" fill-opacity="0.7"/>
|
|
66
|
-
<path d="M249.856 347.996L202.396 286.804L249.856 324.486L298.525 286.804L249.856 347.996Z" fill="#333941" fill-opacity="0.64"/>
|
|
67
|
-
<path d="M249.527 292.296L215.58 240.771L249.857 267.028L284.573 240.771L249.527 292.296Z" fill="#333941" fill-opacity="0.35"/>
|
|
68
|
-
<path d="M249.419 404.685L202.396 343.053L249.419 381.614L295.559 343.053L249.419 404.685Z" fill="#0F0F0F" fill-opacity="0.1"/>
|
|
69
|
-
<path d="M285.482 209.139C297.06 183.136 300.205 166.929 294.24 132.4L346.304 224.989L319.38 218.541L350.314 284.253C319.826 267.918 305.852 251.479 285.482 209.139Z" fill="url(#g6)"/>
|
|
70
|
-
<path d="M214.785 209.139C203.206 183.136 200.062 166.929 206.027 132.4L153.963 224.989L180.887 218.541L149.953 284.253C180.44 267.918 194.414 251.479 214.785 209.139Z" fill="url(#g7)"/>
|
|
71
|
-
<path d="M458.055 281.287L306.25 134.086L375.851 242.958L344.516 235.599L359.745 289.281C390.46 298.849 431.254 294.285 458.055 281.287Z" fill="url(#g8)"/>
|
|
72
|
-
<path d="M42.2112 281.287L194.017 134.086L124.415 242.958L155.75 235.599L140.521 289.281C109.807 298.849 69.0124 294.285 42.2112 281.287Z" fill="url(#g9)"/>
|
|
73
|
-
<path d="M155.707 235.608C120.279 262.873 94.8569 272.188 42.5488 281.311C69.9036 294.823 110.553 298.339 140.546 289.221L155.707 235.608Z" fill="black" fill-opacity="0.16"/>
|
|
74
|
-
<path d="M344.558 235.608C380.054 262.765 405.526 272.042 457.935 281.129C430.527 294.588 389.799 298.089 359.748 289.007L344.558 235.608Z" fill="black" fill-opacity="0.16"/>
|
|
75
|
-
<defs>
|
|
76
|
-
<linearGradient id="g0" x1="248.978" y1="84" x2="248.978" y2="416" gradientUnits="userSpaceOnUse"><stop stop-color="#E5E5E5"/><stop offset="1" stop-color="#272F39"/></linearGradient>
|
|
77
|
-
<linearGradient id="g1" x1="248.978" y1="84" x2="248.978" y2="416" gradientUnits="userSpaceOnUse"><stop stop-color="#E5E5E5"/><stop offset="1" stop-color="#272F39"/></linearGradient>
|
|
78
|
-
<linearGradient id="g2" x1="250.032" y1="171.12" x2="250.032" y2="369.749" gradientUnits="userSpaceOnUse"><stop stop-color="#D9D9D9"/><stop offset="1" stop-color="#272F39"/></linearGradient>
|
|
79
|
-
<linearGradient id="g3" x1="250.032" y1="171.12" x2="250.032" y2="369.749" gradientUnits="userSpaceOnUse"><stop stop-color="#D9D9D9"/><stop offset="1" stop-color="#272F39"/></linearGradient>
|
|
80
|
-
<linearGradient id="g4" x1="250.351" y1="240.771" x2="250.351" y2="313.609" gradientUnits="userSpaceOnUse"><stop stop-color="#D9D9D9"/><stop offset="1" stop-color="#272F39"/></linearGradient>
|
|
81
|
-
<linearGradient id="g5" x1="250.05" y1="125.638" x2="250.05" y2="201.881" gradientUnits="userSpaceOnUse"><stop stop-color="#B1B1B2"/><stop offset="1" stop-color="#343B43"/></linearGradient>
|
|
82
|
-
<linearGradient id="g6" x1="315.879" y1="132.019" x2="318.569" y2="284.812" gradientUnits="userSpaceOnUse"><stop stop-color="#D9D9D9"/><stop offset="1" stop-color="#454B54"/></linearGradient>
|
|
83
|
-
<linearGradient id="g7" x1="184.387" y1="132.019" x2="181.698" y2="284.812" gradientUnits="userSpaceOnUse"><stop stop-color="#D9D9D9"/><stop offset="1" stop-color="#454B54"/></linearGradient>
|
|
84
|
-
<linearGradient id="g8" x1="380.834" y1="132.773" x2="383.683" y2="294.632" gradientUnits="userSpaceOnUse"><stop stop-color="#D9D9D9"/><stop offset="1" stop-color="#4A5159"/></linearGradient>
|
|
85
|
-
<linearGradient id="g9" x1="119.433" y1="132.773" x2="116.583" y2="294.632" gradientUnits="userSpaceOnUse"><stop stop-color="#D9D9D9"/><stop offset="1" stop-color="#4A5159"/></linearGradient>
|
|
86
|
-
</defs>
|
|
87
|
-
</svg>
|
|
88
|
-
</div>
|
|
89
|
-
<h3>IronBee CLI connected to the IronBee platform successfully.</h3>
|
|
90
|
-
<p>You can close this tab.</p>
|
|
91
|
-
</div>
|
|
92
|
-
</body>
|
|
93
|
-
</html>
|