@ironbee-ai/cli 0.8.2 → 0.9.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 +12 -0
- package/README.md +48 -17
- package/dist/clients/claude/commands/ironbee-verify.md +19 -106
- package/dist/clients/claude/hooks/clear-verdict.d.ts.map +1 -1
- package/dist/clients/claude/hooks/clear-verdict.js +25 -4
- package/dist/clients/claude/hooks/clear-verdict.js.map +1 -1
- package/dist/clients/claude/hooks/require-verdict.d.ts +3 -3
- package/dist/clients/claude/hooks/require-verdict.d.ts.map +1 -1
- package/dist/clients/claude/hooks/require-verdict.js +26 -8
- package/dist/clients/claude/hooks/require-verdict.js.map +1 -1
- package/dist/clients/claude/hooks/require-verification.d.ts +6 -5
- package/dist/clients/claude/hooks/require-verification.d.ts.map +1 -1
- package/dist/clients/claude/hooks/require-verification.js +20 -17
- package/dist/clients/claude/hooks/require-verification.js.map +1 -1
- package/dist/clients/claude/hooks/track-action-monitor.d.ts.map +1 -1
- package/dist/clients/claude/hooks/track-action-monitor.js +4 -1
- package/dist/clients/claude/hooks/track-action-monitor.js.map +1 -1
- package/dist/clients/claude/hooks/track-action.d.ts +11 -8
- package/dist/clients/claude/hooks/track-action.d.ts.map +1 -1
- package/dist/clients/claude/hooks/track-action.js +14 -9
- package/dist/clients/claude/hooks/track-action.js.map +1 -1
- package/dist/clients/claude/index.d.ts.map +1 -1
- package/dist/clients/claude/index.js +79 -18
- package/dist/clients/claude/index.js.map +1 -1
- package/dist/clients/claude/platforms/command-verify.backend.md +74 -0
- package/dist/clients/claude/platforms/command-verify.browser.md +108 -0
- package/dist/clients/claude/platforms/command-verify.node.md +67 -0
- package/dist/clients/claude/platforms/rule.backend.md +23 -0
- package/dist/clients/claude/platforms/rule.browser.md +17 -0
- package/dist/clients/claude/{fragments → platforms}/rule.node.md +3 -3
- package/dist/clients/claude/platforms/skill.backend.md +65 -0
- package/dist/clients/claude/platforms/skill.browser.md +31 -0
- package/dist/clients/claude/{fragments → platforms}/skill.node.md +2 -2
- package/dist/clients/claude/rules/ironbee-verification.md +14 -13
- package/dist/clients/claude/skills/ironbee-verification.md +19 -49
- package/dist/clients/cursor/commands/ironbee-verify/SKILL.md +21 -108
- package/dist/clients/cursor/hooks/clear-verdict.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/clear-verdict.js +31 -5
- package/dist/clients/cursor/hooks/clear-verdict.js.map +1 -1
- package/dist/clients/cursor/hooks/require-verdict.d.ts +1 -1
- package/dist/clients/cursor/hooks/require-verdict.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/require-verdict.js +27 -6
- package/dist/clients/cursor/hooks/require-verdict.js.map +1 -1
- package/dist/clients/cursor/hooks/require-verification.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/require-verification.js +9 -5
- package/dist/clients/cursor/hooks/require-verification.js.map +1 -1
- package/dist/clients/cursor/hooks/track-action-monitor.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/track-action-monitor.js +4 -1
- package/dist/clients/cursor/hooks/track-action-monitor.js.map +1 -1
- package/dist/clients/cursor/hooks/track-action.d.ts +14 -12
- package/dist/clients/cursor/hooks/track-action.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/track-action.js +25 -16
- package/dist/clients/cursor/hooks/track-action.js.map +1 -1
- package/dist/clients/cursor/index.d.ts.map +1 -1
- package/dist/clients/cursor/index.js +45 -11
- package/dist/clients/cursor/index.js.map +1 -1
- package/dist/clients/cursor/platforms/command-verify.backend.md +74 -0
- package/dist/clients/cursor/platforms/command-verify.browser.md +108 -0
- package/dist/clients/cursor/platforms/command-verify.node.md +67 -0
- package/dist/clients/cursor/platforms/rule.backend.md +23 -0
- package/dist/clients/cursor/platforms/rule.browser.md +17 -0
- package/dist/clients/cursor/{fragments → platforms}/rule.node.md +3 -3
- package/dist/clients/cursor/platforms/skill.backend.md +65 -0
- package/dist/clients/cursor/platforms/skill.browser.md +31 -0
- package/dist/clients/cursor/{fragments → platforms}/skill.node.md +2 -2
- package/dist/clients/cursor/rules/ironbee-verification.mdc +14 -13
- package/dist/clients/cursor/skills/ironbee-verification.md +19 -49
- package/dist/commands/backend.d.ts +17 -0
- package/dist/commands/backend.d.ts.map +1 -0
- package/dist/commands/backend.js +58 -0
- package/dist/commands/backend.js.map +1 -0
- package/dist/commands/browser.d.ts +19 -0
- package/dist/commands/browser.d.ts.map +1 -0
- package/dist/commands/browser.js +60 -0
- package/dist/commands/browser.js.map +1 -0
- package/dist/commands/config.d.ts +45 -10
- package/dist/commands/config.d.ts.map +1 -1
- package/dist/commands/config.js +80 -28
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/cycle-toggle.d.ts +89 -0
- package/dist/commands/cycle-toggle.d.ts.map +1 -0
- package/dist/commands/cycle-toggle.js +264 -0
- package/dist/commands/cycle-toggle.js.map +1 -0
- package/dist/commands/disable-verification.d.ts.map +1 -1
- package/dist/commands/disable-verification.js +5 -2
- package/dist/commands/disable-verification.js.map +1 -1
- package/dist/commands/enable-verification.d.ts.map +1 -1
- package/dist/commands/enable-verification.js +5 -2
- package/dist/commands/enable-verification.js.map +1 -1
- package/dist/commands/node.d.ts +16 -0
- package/dist/commands/node.d.ts.map +1 -0
- package/dist/commands/node.js +57 -0
- package/dist/commands/node.js.map +1 -0
- package/dist/commands/verification-toggle.d.ts +18 -1
- package/dist/commands/verification-toggle.d.ts.map +1 -1
- package/dist/commands/verification-toggle.js +96 -21
- package/dist/commands/verification-toggle.js.map +1 -1
- package/dist/hooks/core/actions.d.ts +20 -2
- package/dist/hooks/core/actions.d.ts.map +1 -1
- package/dist/hooks/core/actions.js.map +1 -1
- package/dist/hooks/core/file-diff.d.ts +17 -0
- package/dist/hooks/core/file-diff.d.ts.map +1 -1
- package/dist/hooks/core/file-diff.js +72 -0
- package/dist/hooks/core/file-diff.js.map +1 -1
- package/dist/hooks/core/tool-use-stash.d.ts +7 -1
- package/dist/hooks/core/tool-use-stash.d.ts.map +1 -1
- package/dist/hooks/core/tool-use-stash.js.map +1 -1
- package/dist/hooks/core/verify-gate.d.ts.map +1 -1
- package/dist/hooks/core/verify-gate.js +44 -14
- package/dist/hooks/core/verify-gate.js.map +1 -1
- package/dist/index.js +9 -6
- package/dist/index.js.map +1 -1
- package/dist/lib/config.d.ts +218 -36
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +359 -95
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/gitignore.d.ts +26 -11
- package/dist/lib/gitignore.d.ts.map +1 -1
- package/dist/lib/gitignore.js +71 -24
- package/dist/lib/gitignore.js.map +1 -1
- package/dist/lib/platform-section.d.ts +126 -0
- package/dist/lib/platform-section.d.ts.map +1 -0
- package/dist/lib/platform-section.js +279 -0
- package/dist/lib/platform-section.js.map +1 -0
- package/package.json +1 -1
- package/dist/clients/claude/fragments/command-verify.node.md +0 -33
- package/dist/clients/cursor/fragments/command-verify.node.md +0 -33
- package/dist/commands/backend-toggle.d.ts +0 -45
- package/dist/commands/backend-toggle.d.ts.map +0 -1
- package/dist/commands/backend-toggle.js +0 -192
- package/dist/commands/backend-toggle.js.map +0 -1
- package/dist/commands/disable-backend.d.ts +0 -14
- package/dist/commands/disable-backend.d.ts.map +0 -1
- package/dist/commands/disable-backend.js +0 -34
- package/dist/commands/disable-backend.js.map +0 -1
- package/dist/commands/enable-backend.d.ts +0 -15
- package/dist/commands/enable-backend.d.ts.map +0 -1
- package/dist/commands/enable-backend.js +0 -35
- package/dist/commands/enable-backend.js.map +0 -1
- package/dist/lib/runtime-section.d.ts +0 -118
- package/dist/lib/runtime-section.d.ts.map +0 -1
- package/dist/lib/runtime-section.js +0 -256
- package/dist/lib/runtime-section.js.map +0 -1
package/dist/lib/config.js
CHANGED
|
@@ -2,31 +2,38 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* IronBee — Configuration Loader
|
|
4
4
|
*
|
|
5
|
-
* Loads config from
|
|
6
|
-
* 1. Global:
|
|
7
|
-
* 2. Project:
|
|
5
|
+
* Loads config from up to three sources and merges them in order:
|
|
6
|
+
* 1. Global: ~/.ironbee/config.json
|
|
7
|
+
* 2. Project: <projectDir>/.ironbee/config.json (committed)
|
|
8
|
+
* 3. Project-local: <projectDir>/.ironbee/config.local.json (gitignored)
|
|
8
9
|
*
|
|
9
|
-
*
|
|
10
|
-
* shallow for primitives
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* `backend.<runtime>.*`).
|
|
10
|
+
* Each later layer overrides earlier ones (deep merge for nested cycle
|
|
11
|
+
* blocks: `browser`, `node`, `backend`; shallow for primitives and other
|
|
12
|
+
* top-level keys). The local layer is intended for personal / per-machine
|
|
13
|
+
* overrides (debug toggles, machine-specific paths, alternate collector
|
|
14
|
+
* endpoints) and must not be committed — `ironbee install` adds
|
|
15
|
+
* `.ironbee/config.local.json` to `.gitignore` automatically.
|
|
16
16
|
*/
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
-
exports.
|
|
18
|
+
exports.CONFIG_TARGETS_BY_PRECEDENCE = exports.DEFAULT_BACKEND_EVIDENCE_PATHS = exports.DEFAULT_BACKEND_ALWAYS_REQUIRED = exports.DEFAULT_NODE_EVIDENCE_PATHS = exports.DEFAULT_NODE_ALWAYS_REQUIRED = exports.DEFAULT_BROWSER_ALWAYS_REQUIRED = exports.CYCLE_DEFAULT_VERIFY_PATTERNS = exports.DEFAULT_BACKEND_VERIFY_PATTERNS = exports.DEFAULT_NODE_VERIFY_PATTERNS = exports.DEFAULT_BROWSER_VERIFY_PATTERNS = exports.CYCLE_TO_SERVER = exports.CYCLES_ENABLED_BY_DEFAULT = exports.ALL_CYCLES = exports.OPTIONAL_CYCLES = void 0;
|
|
19
|
+
exports.getConfigLayerPaths = getConfigLayerPaths;
|
|
20
|
+
exports.getTargetConfigPath = getTargetConfigPath;
|
|
21
|
+
exports.resolveConfigTargetFromFlags = resolveConfigTargetFromFlags;
|
|
19
22
|
exports.loadConfig = loadConfig;
|
|
20
23
|
exports.getActiveCycles = getActiveCycles;
|
|
21
24
|
exports.requiresVerification = requiresVerification;
|
|
25
|
+
exports.isCycleEnabled = isCycleEnabled;
|
|
22
26
|
exports.getRequiredToolsConfig = getRequiredToolsConfig;
|
|
23
27
|
exports.getMcpServerEntry = getMcpServerEntry;
|
|
24
28
|
exports.getNodeDevToolsMcpEntry = getNodeDevToolsMcpEntry;
|
|
29
|
+
exports.getBackendDevToolsMcpEntry = getBackendDevToolsMcpEntry;
|
|
25
30
|
exports.getMaxRetries = getMaxRetries;
|
|
26
31
|
exports.isCollectorConfigured = isCollectorConfigured;
|
|
27
32
|
exports.isJobQueueEnabled = isJobQueueEnabled;
|
|
28
33
|
exports.isRecordingEnabled = isRecordingEnabled;
|
|
29
34
|
exports.getVerificationEnabled = getVerificationEnabled;
|
|
35
|
+
exports.getCaptureFileChangeset = getCaptureFileChangeset;
|
|
36
|
+
exports.getMaxChangesetBytes = getMaxChangesetBytes;
|
|
30
37
|
exports.isAnalyticsEnabled = isAnalyticsEnabled;
|
|
31
38
|
exports.isAnalyticsEmitOnStopEnabled = isAnalyticsEmitOnStopEnabled;
|
|
32
39
|
exports.getAnalyticsEmitOnStopMinIntervalSeconds = getAnalyticsEmitOnStopMinIntervalSeconds;
|
|
@@ -37,13 +44,44 @@ const fs_1 = require("fs");
|
|
|
37
44
|
const path_1 = require("path");
|
|
38
45
|
const os_1 = require("os");
|
|
39
46
|
const logger_1 = require("./logger");
|
|
40
|
-
/**
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Optional cycles — those that default to **disabled** (empty `verifyPatterns`)
|
|
49
|
+
* until the operator explicitly opts in via `ironbee <cycle> enable`. The
|
|
50
|
+
* always-on browser cycle is the only default-enabled cycle and is excluded
|
|
51
|
+
* from this list. Order is the canonical sort order used by verify-gate when
|
|
52
|
+
* building per-cycle messages.
|
|
53
|
+
*/
|
|
54
|
+
exports.OPTIONAL_CYCLES = ["node", "backend"];
|
|
55
|
+
/**
|
|
56
|
+
* Every cycle the runtime knows about — browser plus all optional cycles.
|
|
57
|
+
* Used by the platform-section sync (skill / rule / command-verify md files
|
|
58
|
+
* carry one marker block per cycle) and by toggle commands when validating
|
|
59
|
+
* the cycle name. Order matches verify-gate's canonical block ordering
|
|
60
|
+
* (browser first, then OPTIONAL_CYCLES).
|
|
61
|
+
*/
|
|
62
|
+
exports.ALL_CYCLES = ["browser", ...exports.OPTIONAL_CYCLES];
|
|
63
|
+
/**
|
|
64
|
+
* Cycles whose default state is "enabled" (the cycle activates without the
|
|
65
|
+
* operator having to write `verifyPatterns` in config). Currently only the
|
|
66
|
+
* browser cycle ships with built-in default patterns; node and backend cycles
|
|
67
|
+
* default to inert (`[]`) and require `ironbee <cycle> enable`.
|
|
68
|
+
*
|
|
69
|
+
* Used by `getCyclePatterns` runtime fallback (block-absent + default-on
|
|
70
|
+
* → code defaults activate) and by toggle commands. `<cycle> disable` records
|
|
71
|
+
* its intent via the top-level `disabled` list — that takes precedence over
|
|
72
|
+
* the default-on fallback, so a disabled browser stays off even though
|
|
73
|
+
* `CYCLES_ENABLED_BY_DEFAULT` contains it.
|
|
74
|
+
*/
|
|
75
|
+
exports.CYCLES_ENABLED_BY_DEFAULT = new Set(["browser"]);
|
|
76
|
+
/** Map cycle key → MCP server name. Browser is always `browser-devtools`. */
|
|
77
|
+
exports.CYCLE_TO_SERVER = {
|
|
78
|
+
browser: "browser-devtools",
|
|
44
79
|
node: "node-devtools",
|
|
80
|
+
backend: "backend-devtools",
|
|
45
81
|
};
|
|
46
|
-
/** Browser default verify patterns —
|
|
82
|
+
/** Browser default verify patterns — kicks in whenever the browser block is
|
|
83
|
+
* present without an explicit `verifyPatterns`, OR (since browser is
|
|
84
|
+
* default-on) whenever no browser block is present at any layer. */
|
|
47
85
|
exports.DEFAULT_BROWSER_VERIFY_PATTERNS = [
|
|
48
86
|
"*.ts", "*.tsx",
|
|
49
87
|
"*.js", "*.jsx", "*.mjs", "*.cjs",
|
|
@@ -71,6 +109,65 @@ exports.DEFAULT_BROWSER_VERIFY_PATTERNS = [
|
|
|
71
109
|
"*.hbs", "*.ejs", "*.pug", "*.jade",
|
|
72
110
|
"*.astro",
|
|
73
111
|
];
|
|
112
|
+
/**
|
|
113
|
+
* Node-cycle default verify patterns — kicks in when the `node` block is
|
|
114
|
+
* present without an explicit `verifyPatterns`. The node cycle is opt-in so
|
|
115
|
+
* the block must be present (a fully-absent block keeps the cycle disabled).
|
|
116
|
+
*
|
|
117
|
+
* Heuristic-tuned for typical Node.js backends — server entry points, API
|
|
118
|
+
* route handlers (Next.js / Remix / SvelteKit conventions), and the routes/
|
|
119
|
+
* folder.
|
|
120
|
+
*/
|
|
121
|
+
exports.DEFAULT_NODE_VERIFY_PATTERNS = [
|
|
122
|
+
"server/**/*.{ts,js,mjs,cjs}",
|
|
123
|
+
"src/server/**/*.{ts,js,mjs,cjs}",
|
|
124
|
+
"backend/**/*.{ts,js,mjs,cjs}",
|
|
125
|
+
"api/**/*.{ts,js,mjs,cjs}",
|
|
126
|
+
"src/api/**/*.{ts,js,mjs,cjs}",
|
|
127
|
+
"pages/api/**/*.{ts,js,mjs,cjs}",
|
|
128
|
+
"app/api/**/*.{ts,js,mjs,cjs}",
|
|
129
|
+
"routes/**/*.{ts,js,mjs,cjs}",
|
|
130
|
+
"**/server.{ts,js,mjs,cjs}",
|
|
131
|
+
];
|
|
132
|
+
/**
|
|
133
|
+
* Backend-cycle default verify patterns — kicks in when the `backend` block
|
|
134
|
+
* is present without an explicit `verifyPatterns`. Multi-language coverage —
|
|
135
|
+
* the cycle drives wire protocols, not language-specific tooling, so the
|
|
136
|
+
* heuristic spans every common server-side language.
|
|
137
|
+
*/
|
|
138
|
+
exports.DEFAULT_BACKEND_VERIFY_PATTERNS = [
|
|
139
|
+
"server/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}",
|
|
140
|
+
"src/server/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}",
|
|
141
|
+
"backend/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}",
|
|
142
|
+
"api/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}",
|
|
143
|
+
"src/api/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}",
|
|
144
|
+
"pages/api/**/*.{ts,js,mjs,cjs}",
|
|
145
|
+
"app/api/**/*.{ts,js,mjs,cjs}",
|
|
146
|
+
"routes/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}",
|
|
147
|
+
"controllers/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}",
|
|
148
|
+
"handlers/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}",
|
|
149
|
+
"services/**/*.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}",
|
|
150
|
+
"**/server.{ts,js,mjs,cjs,py,go,java,rb,cs,rs,kt,scala,ex,exs,php,clj}",
|
|
151
|
+
"**/main.{go,py,java,rb,kt,scala}",
|
|
152
|
+
];
|
|
153
|
+
/**
|
|
154
|
+
* Per-cycle default `verifyPatterns` lookup. Single source of truth used by:
|
|
155
|
+
*
|
|
156
|
+
* - `getCyclePatterns` runtime fallback when the cycle block is present
|
|
157
|
+
* without an explicit `verifyPatterns`.
|
|
158
|
+
* - For browser only: also kicks in when the cycle block is fully absent
|
|
159
|
+
* (browser is the default-on cycle — `CYCLES_ENABLED_BY_DEFAULT`).
|
|
160
|
+
*
|
|
161
|
+
* `<cycle> enable` does NOT materialize these into config.json; the cycle
|
|
162
|
+
* block is written empty (`{}`) and these defaults flow in at runtime.
|
|
163
|
+
* Keeps `config.json` minimal and lets defaults track the CLI version
|
|
164
|
+
* automatically.
|
|
165
|
+
*/
|
|
166
|
+
exports.CYCLE_DEFAULT_VERIFY_PATTERNS = {
|
|
167
|
+
browser: exports.DEFAULT_BROWSER_VERIFY_PATTERNS,
|
|
168
|
+
node: exports.DEFAULT_NODE_VERIFY_PATTERNS,
|
|
169
|
+
backend: exports.DEFAULT_BACKEND_VERIFY_PATTERNS,
|
|
170
|
+
};
|
|
74
171
|
/** Browser-cycle required tools — strict all-of, no alternative paths. */
|
|
75
172
|
exports.DEFAULT_BROWSER_ALWAYS_REQUIRED = [
|
|
76
173
|
"bdt_navigation_go-to",
|
|
@@ -79,10 +176,10 @@ exports.DEFAULT_BROWSER_ALWAYS_REQUIRED = [
|
|
|
79
176
|
"bdt_o11y_get-console-messages",
|
|
80
177
|
];
|
|
81
178
|
/** Node-cycle required tools — connect always; then probe path or log path. */
|
|
82
|
-
exports.
|
|
179
|
+
exports.DEFAULT_NODE_ALWAYS_REQUIRED = [
|
|
83
180
|
"ndt_debug_connect",
|
|
84
181
|
];
|
|
85
|
-
exports.
|
|
182
|
+
exports.DEFAULT_NODE_EVIDENCE_PATHS = [
|
|
86
183
|
{
|
|
87
184
|
name: "probe",
|
|
88
185
|
allOf: [
|
|
@@ -101,6 +198,29 @@ exports.DEFAULT_BACKEND_NODE_EVIDENCE_PATHS = [
|
|
|
101
198
|
allOf: ["ndt_debug_get-logs"],
|
|
102
199
|
},
|
|
103
200
|
];
|
|
201
|
+
/**
|
|
202
|
+
* Backend-cycle required tools — no single tool is mandatory (different
|
|
203
|
+
* tasks need different protocols), so `alwaysRequired` is empty and the
|
|
204
|
+
* gate is satisfied by any one protocol-call evidence path. The replay
|
|
205
|
+
* tool counts because it issues a real protocol call against the target.
|
|
206
|
+
*/
|
|
207
|
+
exports.DEFAULT_BACKEND_ALWAYS_REQUIRED = [];
|
|
208
|
+
exports.DEFAULT_BACKEND_EVIDENCE_PATHS = [
|
|
209
|
+
{
|
|
210
|
+
name: "protocol-call",
|
|
211
|
+
allOf: [
|
|
212
|
+
{
|
|
213
|
+
anyOf: [
|
|
214
|
+
"bedt_request_http",
|
|
215
|
+
"bedt_request_grpc",
|
|
216
|
+
"bedt_request_graphql",
|
|
217
|
+
"bedt_request_websocket-open",
|
|
218
|
+
"bedt_request_replay",
|
|
219
|
+
],
|
|
220
|
+
},
|
|
221
|
+
],
|
|
222
|
+
},
|
|
223
|
+
];
|
|
104
224
|
const DEFAULT_MAX_RETRIES = 3;
|
|
105
225
|
function loadJsonFile(filePath) {
|
|
106
226
|
if (!(0, fs_1.existsSync)(filePath)) {
|
|
@@ -114,21 +234,6 @@ function loadJsonFile(filePath) {
|
|
|
114
234
|
return {};
|
|
115
235
|
}
|
|
116
236
|
}
|
|
117
|
-
/** Detect pre-split flat config. Loud failure per design D6. */
|
|
118
|
-
function assertNoLegacyShape(config, sourcePath) {
|
|
119
|
-
const legacy = [];
|
|
120
|
-
if (Object.prototype.hasOwnProperty.call(config, "verifyPatterns")) {
|
|
121
|
-
legacy.push("'verifyPatterns'");
|
|
122
|
-
}
|
|
123
|
-
if (Object.prototype.hasOwnProperty.call(config, "additionalVerifyPatterns")) {
|
|
124
|
-
legacy.push("'additionalVerifyPatterns'");
|
|
125
|
-
}
|
|
126
|
-
if (legacy.length === 0) {
|
|
127
|
-
return;
|
|
128
|
-
}
|
|
129
|
-
throw new Error(`Legacy IronBee config detected in ${sourcePath}: ${legacy.join(", ")} at the top level is no longer supported. ` +
|
|
130
|
-
`Move them under 'browser.*' (or the appropriate runtime under 'backend.<runtime>.*').`);
|
|
131
|
-
}
|
|
132
237
|
function assertVerificationShape(config, sourcePath) {
|
|
133
238
|
if (!Object.prototype.hasOwnProperty.call(config, "verification")) {
|
|
134
239
|
return;
|
|
@@ -144,51 +249,96 @@ function assertVerificationShape(config, sourcePath) {
|
|
|
144
249
|
`Got ${typeof block.enable}.`);
|
|
145
250
|
}
|
|
146
251
|
}
|
|
147
|
-
/** Deep merge for
|
|
252
|
+
/** Deep merge for a single cycle block (browser / node / backend). */
|
|
148
253
|
function mergeCycleConfig(base, override) {
|
|
149
254
|
if (base === undefined && override === undefined) {
|
|
150
255
|
return undefined;
|
|
151
256
|
}
|
|
152
257
|
return { ...(base ?? {}), ...(override ?? {}) };
|
|
153
258
|
}
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
259
|
+
/**
|
|
260
|
+
* Merge two `IronBeeConfig` layers — `override` wins. Top-level keys are
|
|
261
|
+
* shallow-merged; the cycle blocks (`browser`, `node`, `backend`) deep-merge
|
|
262
|
+
* so a project override of `browser.verifyPatterns` doesn't wipe a global
|
|
263
|
+
* `browser.evidencePaths` (and vice-versa for the local layer).
|
|
264
|
+
*/
|
|
265
|
+
function mergeConfigLayers(base, override) {
|
|
266
|
+
const merged = { ...base, ...override };
|
|
267
|
+
merged.browser = mergeCycleConfig(base.browser, override.browser);
|
|
268
|
+
merged.node = mergeCycleConfig(base.node, override.node);
|
|
269
|
+
merged.backend = mergeCycleConfig(base.backend, override.backend);
|
|
166
270
|
return merged;
|
|
167
271
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
272
|
+
/** Returns the on-disk paths of all three config layers without reading them. */
|
|
273
|
+
function getConfigLayerPaths(projectDir) {
|
|
274
|
+
return {
|
|
275
|
+
global: (0, path_1.join)((0, os_1.homedir)(), ".ironbee", "config.json"),
|
|
276
|
+
project: projectDir ? (0, path_1.join)(projectDir, ".ironbee", "config.json") : undefined,
|
|
277
|
+
local: projectDir ? (0, path_1.join)(projectDir, ".ironbee", "config.local.json") : undefined,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
/** Layers in merge-precedence order, low → high. Used by override detection. */
|
|
281
|
+
exports.CONFIG_TARGETS_BY_PRECEDENCE = ["global", "project", "local"];
|
|
282
|
+
/**
|
|
283
|
+
* Returns the on-disk path for a single config layer. Throws when the
|
|
284
|
+
* caller asks for a project-scoped layer without a `projectDir` (e.g.
|
|
285
|
+
* `--local` outside a project context). Used by all write-side commands
|
|
286
|
+
* to keep the targeted-path resolution in one place.
|
|
287
|
+
*/
|
|
288
|
+
function getTargetConfigPath(target, projectDir) {
|
|
289
|
+
const paths = getConfigLayerPaths(projectDir);
|
|
290
|
+
if (target === "global") {
|
|
291
|
+
return paths.global;
|
|
292
|
+
}
|
|
293
|
+
if (target === "project") {
|
|
294
|
+
if (paths.project === undefined) {
|
|
295
|
+
throw new Error("Project layer requested but no projectDir was provided.");
|
|
183
296
|
}
|
|
297
|
+
return paths.project;
|
|
184
298
|
}
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
299
|
+
// local
|
|
300
|
+
if (paths.local === undefined) {
|
|
301
|
+
throw new Error("Local layer requested but no projectDir was provided.");
|
|
302
|
+
}
|
|
303
|
+
return paths.local;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Resolves a `ConfigTarget` from CLI flag booleans, enforcing mutual
|
|
307
|
+
* exclusion. Used by every write-side command that exposes
|
|
308
|
+
* `-g / --global` and `--local` flags (`config set`, `config unset`,
|
|
309
|
+
* `enable-verification`, `disable-verification`, `backend enable`,
|
|
310
|
+
* `backend disable`) so the flag-resolution rules stay identical.
|
|
311
|
+
*
|
|
312
|
+
* Returns `"project"` when neither flag is set (the default for
|
|
313
|
+
* project-scoped commands). Throws on the impossible `--global --local`
|
|
314
|
+
* combination — commander doesn't enforce mutual exclusion across
|
|
315
|
+
* arbitrary option pairs, so we do.
|
|
316
|
+
*/
|
|
317
|
+
function resolveConfigTargetFromFlags(opts) {
|
|
318
|
+
if (opts.global === true && opts.local === true) {
|
|
319
|
+
throw new Error("Pass at most one of --global / --local.");
|
|
320
|
+
}
|
|
321
|
+
if (opts.global === true) {
|
|
322
|
+
return "global";
|
|
323
|
+
}
|
|
324
|
+
if (opts.local === true) {
|
|
325
|
+
return "local";
|
|
326
|
+
}
|
|
327
|
+
return "project";
|
|
328
|
+
}
|
|
329
|
+
function loadAndValidateLayer(path) {
|
|
330
|
+
const raw = loadJsonFile(path);
|
|
331
|
+
if ((0, fs_1.existsSync)(path)) {
|
|
332
|
+
assertVerificationShape(raw, path);
|
|
333
|
+
}
|
|
334
|
+
return raw;
|
|
335
|
+
}
|
|
336
|
+
function loadConfig(projectDir) {
|
|
337
|
+
const paths = getConfigLayerPaths(projectDir);
|
|
338
|
+
const globalConfig = loadAndValidateLayer(paths.global);
|
|
339
|
+
const projectConfig = paths.project ? loadAndValidateLayer(paths.project) : {};
|
|
340
|
+
const localConfig = paths.local ? loadAndValidateLayer(paths.local) : {};
|
|
341
|
+
return mergeConfigLayers(mergeConfigLayers(globalConfig, projectConfig), localConfig);
|
|
192
342
|
}
|
|
193
343
|
// Glob → RegExp. Supports *, **, ** + slash (zero-or-more segments), ?, and
|
|
194
344
|
// brace expansion {a,b,c} → (a|b|c). The trailing-slash form of ** matches
|
|
@@ -226,26 +376,76 @@ function matchesAny(filePath, patterns) {
|
|
|
226
376
|
}
|
|
227
377
|
return false;
|
|
228
378
|
}
|
|
229
|
-
/** Returns the
|
|
230
|
-
function
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
379
|
+
/** Returns the per-cycle config block. Always-on browser, opt-in node / backend. */
|
|
380
|
+
function getCycleBlock(config, cycle) {
|
|
381
|
+
if (cycle === "browser") {
|
|
382
|
+
return config.browser;
|
|
383
|
+
}
|
|
384
|
+
if (cycle === "node") {
|
|
385
|
+
return config.node;
|
|
386
|
+
}
|
|
387
|
+
if (cycle === "backend") {
|
|
388
|
+
return config.backend;
|
|
389
|
+
}
|
|
390
|
+
return undefined;
|
|
235
391
|
}
|
|
236
|
-
/**
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
392
|
+
/**
|
|
393
|
+
* Returns the effective pattern set for a cycle. Resolution order:
|
|
394
|
+
*
|
|
395
|
+
* 1. **`block.enable === false`** → cycle-specific disable signal written
|
|
396
|
+
* by `<cycle> disable`. Mirrors `recording.enable` / `jobQueue.enable`
|
|
397
|
+
* / `verification.enable`.
|
|
398
|
+
* 2. **Block absent** → for default-on cycles (browser), the code defaults
|
|
399
|
+
* kick in. For default-off cycles (node, backend), no patterns.
|
|
400
|
+
* 3. **`verifyPatterns: []`** → hard kill (legacy disable marker — still
|
|
401
|
+
* respected for older configs; new disables write `enable: false`).
|
|
402
|
+
* 4. **Block present, `verifyPatterns` undefined** → enabled with code
|
|
403
|
+
* defaults (`CYCLE_DEFAULT_VERIFY_PATTERNS[cycle]`). Post-`<cycle> enable`
|
|
404
|
+
* shape — minimal config, defaults track CLI version.
|
|
405
|
+
* 5. **`verifyPatterns: [...non-empty]`** → enabled with custom patterns.
|
|
406
|
+
*
|
|
407
|
+
* `additionalVerifyPatterns` is appended to whatever base resolves at step
|
|
408
|
+
* 4/5 — EXCEPT when the cycle is disabled via step 1 or 3.
|
|
409
|
+
*
|
|
410
|
+
* **Note:** does NOT check the master `verification.enable` switch. That
|
|
411
|
+
* happens at the verification-level (install-time gating + the higher-level
|
|
412
|
+
* {@link isCycleEnabled} helper). This function returns the cycle's pattern
|
|
413
|
+
* shape independent of master state — useful for code paths that want
|
|
414
|
+
* pattern info even when enforcement is off.
|
|
415
|
+
*/
|
|
416
|
+
function getCyclePatterns(config, cycle) {
|
|
417
|
+
const block = getCycleBlock(config, cycle);
|
|
418
|
+
// Explicit per-cycle disable signal.
|
|
419
|
+
if (block !== undefined && block.enable === false) {
|
|
420
|
+
return [];
|
|
421
|
+
}
|
|
422
|
+
const cycleDefaults = exports.CYCLE_DEFAULT_VERIFY_PATTERNS[cycle] ?? [];
|
|
423
|
+
if (block === undefined) {
|
|
424
|
+
// Block absent: only default-on cycles activate via code defaults.
|
|
425
|
+
if (exports.CYCLES_ENABLED_BY_DEFAULT.has(cycle)) {
|
|
426
|
+
return [...cycleDefaults];
|
|
427
|
+
}
|
|
428
|
+
return [];
|
|
429
|
+
}
|
|
430
|
+
// Legacy hard kill: `verifyPatterns: []` still fully disables. Newer
|
|
431
|
+
// configs use `enable: false` (above) but pre-existing configs may
|
|
432
|
+
// carry this older marker — keep honoring it.
|
|
433
|
+
if (Array.isArray(block.verifyPatterns) && block.verifyPatterns.length === 0) {
|
|
434
|
+
return [];
|
|
435
|
+
}
|
|
436
|
+
// Block present, enabled: `verifyPatterns` wins when set; otherwise
|
|
437
|
+
// fall back to code defaults (post-`<cycle> enable` shape).
|
|
438
|
+
const base = block.verifyPatterns ?? cycleDefaults;
|
|
439
|
+
const additional = block.additionalVerifyPatterns ?? [];
|
|
241
440
|
return [...base, ...additional];
|
|
242
441
|
}
|
|
243
442
|
/**
|
|
244
443
|
* Returns the names of cycles whose pattern set matches `filePath`.
|
|
245
444
|
* Used by verify-gate to determine which cycles are active for a Stop hook.
|
|
246
445
|
*
|
|
247
|
-
* Order: browser first, then each
|
|
248
|
-
* applies globally — a file matched there
|
|
446
|
+
* Order: browser first, then each optional cycle in {@link OPTIONAL_CYCLES}
|
|
447
|
+
* order. `ignoredVerifyPatterns` applies globally — a file matched there
|
|
448
|
+
* activates no cycles.
|
|
249
449
|
*/
|
|
250
450
|
function getActiveCycles(filePath, config) {
|
|
251
451
|
const ignored = config.ignoredVerifyPatterns ?? [];
|
|
@@ -253,17 +453,13 @@ function getActiveCycles(filePath, config) {
|
|
|
253
453
|
return [];
|
|
254
454
|
}
|
|
255
455
|
const active = [];
|
|
256
|
-
if (matchesAny(filePath,
|
|
456
|
+
if (matchesAny(filePath, getCyclePatterns(config, "browser"))) {
|
|
257
457
|
active.push("browser");
|
|
258
458
|
}
|
|
259
|
-
for (const
|
|
260
|
-
const
|
|
261
|
-
if (runtime === undefined) {
|
|
262
|
-
continue;
|
|
263
|
-
}
|
|
264
|
-
const patterns = getBackendRuntimePatterns(config, runtime);
|
|
459
|
+
for (const cycle of exports.OPTIONAL_CYCLES) {
|
|
460
|
+
const patterns = getCyclePatterns(config, cycle);
|
|
265
461
|
if (patterns.length > 0 && matchesAny(filePath, patterns)) {
|
|
266
|
-
active.push(
|
|
462
|
+
active.push(cycle);
|
|
267
463
|
}
|
|
268
464
|
}
|
|
269
465
|
return active;
|
|
@@ -276,6 +472,34 @@ function getActiveCycles(filePath, config) {
|
|
|
276
472
|
function requiresVerification(filePath, config) {
|
|
277
473
|
return getActiveCycles(filePath, config).length > 0;
|
|
278
474
|
}
|
|
475
|
+
/**
|
|
476
|
+
* Returns true if `cycle` is currently enabled for verification in `config`
|
|
477
|
+
* (effective merged shape).
|
|
478
|
+
*
|
|
479
|
+
* Two conditions must BOTH hold:
|
|
480
|
+
* 1. The master switch `verification.enable` is on (or absent — defaults
|
|
481
|
+
* to true). When `verification.enable: false`, every cycle is off
|
|
482
|
+
* regardless of its own block — per-cycle settings never override the
|
|
483
|
+
* master switch.
|
|
484
|
+
* 2. The cycle's own resolution per {@link getCyclePatterns} yields
|
|
485
|
+
* non-empty patterns:
|
|
486
|
+
* - `block.enable === false` → disabled (canonical signal).
|
|
487
|
+
* - Block absent + default-on (browser) → enabled (code defaults).
|
|
488
|
+
* - Block absent + default-off (node, backend) → disabled.
|
|
489
|
+
* - `verifyPatterns: []` (legacy) → disabled.
|
|
490
|
+
* - Block present with `verifyPatterns` undefined → enabled (defaults).
|
|
491
|
+
* - Block present with non-empty `verifyPatterns` → enabled (custom).
|
|
492
|
+
*
|
|
493
|
+
* Used by `platform-section.syncPlatformSectionsToConfig` to decide whether to
|
|
494
|
+
* splice the cycle's fragment or the placeholder into installed md files,
|
|
495
|
+
* and by client `install` paths to gate MCP server entries + permissions.
|
|
496
|
+
*/
|
|
497
|
+
function isCycleEnabled(config, cycle) {
|
|
498
|
+
if (!getVerificationEnabled(config)) {
|
|
499
|
+
return false;
|
|
500
|
+
}
|
|
501
|
+
return getCyclePatterns(config, cycle).length > 0;
|
|
502
|
+
}
|
|
279
503
|
/**
|
|
280
504
|
* Per-cycle resolved required-tools spec. Falls back to defaults at this layer
|
|
281
505
|
* so consumers always get a complete `{ alwaysRequired, evidencePaths }` shape.
|
|
@@ -291,13 +515,16 @@ function getRequiredToolsConfig(config, cycle) {
|
|
|
291
515
|
evidencePaths = config.browser?.evidencePaths ?? [];
|
|
292
516
|
}
|
|
293
517
|
else if (cycle === "node") {
|
|
294
|
-
alwaysRequired = config.
|
|
295
|
-
evidencePaths = config.
|
|
518
|
+
alwaysRequired = config.node?.alwaysRequired ?? exports.DEFAULT_NODE_ALWAYS_REQUIRED;
|
|
519
|
+
evidencePaths = config.node?.evidencePaths ?? exports.DEFAULT_NODE_EVIDENCE_PATHS;
|
|
520
|
+
}
|
|
521
|
+
else if (cycle === "backend") {
|
|
522
|
+
alwaysRequired = config.backend?.alwaysRequired ?? exports.DEFAULT_BACKEND_ALWAYS_REQUIRED;
|
|
523
|
+
evidencePaths = config.backend?.evidencePaths ?? exports.DEFAULT_BACKEND_EVIDENCE_PATHS;
|
|
296
524
|
}
|
|
297
525
|
else {
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
evidencePaths = block?.evidencePaths ?? [];
|
|
526
|
+
alwaysRequired = [];
|
|
527
|
+
evidencePaths = [];
|
|
301
528
|
}
|
|
302
529
|
if (alwaysRequired.length === 0 && evidencePaths.length === 0) {
|
|
303
530
|
throw new Error(`Invalid required-tools config for cycle '${cycle}': both 'alwaysRequired' and 'evidencePaths' are empty. ` +
|
|
@@ -316,10 +543,16 @@ const NODE_IRONBEE_ENV = {
|
|
|
316
543
|
TOOL_NAME_PREFIX: "ndt_",
|
|
317
544
|
TOOL_INPUT_METADATA_ENABLE: "true",
|
|
318
545
|
};
|
|
546
|
+
const BACKEND_IRONBEE_ENV = {
|
|
547
|
+
PLATFORM: "backend",
|
|
548
|
+
TOOL_NAME_PREFIX: "bedt_",
|
|
549
|
+
TOOL_INPUT_METADATA_ENABLE: "true",
|
|
550
|
+
};
|
|
319
551
|
const BROWSER_DEFAULT_MCP_ENV = {
|
|
320
552
|
BROWSER_DEVTOOLS_INSTALL_CHROMIUM: "true",
|
|
321
553
|
};
|
|
322
554
|
const NODE_DEFAULT_MCP_ENV = {};
|
|
555
|
+
const BACKEND_DEFAULT_MCP_ENV = {};
|
|
323
556
|
/**
|
|
324
557
|
* Auto-derive OTEL exporter env for the devtools MCP server when the
|
|
325
558
|
* IronBee Collector is configured + enabled. Returns `{}` when the
|
|
@@ -334,7 +567,8 @@ const NODE_DEFAULT_MCP_ENV = {};
|
|
|
334
567
|
* by setting `OTEL_ENABLE: "false"` in their override.
|
|
335
568
|
*
|
|
336
569
|
* `runtime` toggles browser-only vars (USER_INTERACTION_EVENTS,
|
|
337
|
-
* BROWSER_HEADLESS_ENABLE) — node-devtools
|
|
570
|
+
* BROWSER_HEADLESS_ENABLE) — node-devtools and backend-devtools don't
|
|
571
|
+
* honor those.
|
|
338
572
|
*/
|
|
339
573
|
function buildOtelEnv(config, runtime) {
|
|
340
574
|
if (!isCollectorConfigured(config)) {
|
|
@@ -423,6 +657,11 @@ function getNodeDevToolsMcpEntry(projectDir) {
|
|
|
423
657
|
const config = loadConfig(projectDir);
|
|
424
658
|
return buildMcpEntry(config, "nodeDevTools", NODE_IRONBEE_ENV, NODE_DEFAULT_MCP_ENV, "node");
|
|
425
659
|
}
|
|
660
|
+
/** Returns the MCP server entry for `backend-devtools` (PLATFORM=backend, bedt_). */
|
|
661
|
+
function getBackendDevToolsMcpEntry(projectDir) {
|
|
662
|
+
const config = loadConfig(projectDir);
|
|
663
|
+
return buildMcpEntry(config, "backendDevTools", BACKEND_IRONBEE_ENV, BACKEND_DEFAULT_MCP_ENV, "backend");
|
|
664
|
+
}
|
|
426
665
|
function getMaxRetries(config) {
|
|
427
666
|
return (typeof config.maxRetries === "number" && config.maxRetries > 0)
|
|
428
667
|
? config.maxRetries
|
|
@@ -533,6 +772,31 @@ function getVerificationEnabled(config) {
|
|
|
533
772
|
}
|
|
534
773
|
return section.enable !== false;
|
|
535
774
|
}
|
|
775
|
+
const DEFAULT_MAX_CHANGESET_BYTES = 65536;
|
|
776
|
+
/**
|
|
777
|
+
* Returns true when `file_change` events should carry a unified-diff
|
|
778
|
+
* `changeset` string. Off by default — the default wire shape stays
|
|
779
|
+
* metadata-only (operation + line counts).
|
|
780
|
+
*/
|
|
781
|
+
function getCaptureFileChangeset(config) {
|
|
782
|
+
const section = config.fileChange;
|
|
783
|
+
if (!section || typeof section !== "object" || Array.isArray(section)) {
|
|
784
|
+
return false;
|
|
785
|
+
}
|
|
786
|
+
return section.captureChangeset === true;
|
|
787
|
+
}
|
|
788
|
+
/** Per-event hard cap in bytes for the `changeset` string. Truncated past this. */
|
|
789
|
+
function getMaxChangesetBytes(config) {
|
|
790
|
+
const section = config.fileChange;
|
|
791
|
+
if (!section || typeof section !== "object" || Array.isArray(section)) {
|
|
792
|
+
return DEFAULT_MAX_CHANGESET_BYTES;
|
|
793
|
+
}
|
|
794
|
+
const raw = section.maxChangesetBytes;
|
|
795
|
+
if (typeof raw !== "number" || !Number.isFinite(raw) || raw <= 0) {
|
|
796
|
+
return DEFAULT_MAX_CHANGESET_BYTES;
|
|
797
|
+
}
|
|
798
|
+
return Math.floor(raw);
|
|
799
|
+
}
|
|
536
800
|
/**
|
|
537
801
|
* Returns true when analytics collection is enabled for this project.
|
|
538
802
|
* Same resolution as `isJobQueueEnabled` / `isRecordingEnabled`:
|