@ironbee-ai/cli 0.2.1 → 0.4.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 +31 -3
- package/README.md +118 -3
- package/dist/analysis/code-changes.d.ts +22 -0
- package/dist/analysis/code-changes.d.ts.map +1 -0
- package/dist/analysis/code-changes.js +141 -0
- package/dist/analysis/code-changes.js.map +1 -0
- package/dist/analysis/cross-session.d.ts +34 -0
- package/dist/analysis/cross-session.d.ts.map +1 -0
- package/dist/analysis/cross-session.js +230 -0
- package/dist/analysis/cross-session.js.map +1 -0
- package/dist/analysis/fix-effectiveness.d.ts +16 -0
- package/dist/analysis/fix-effectiveness.d.ts.map +1 -0
- package/dist/analysis/fix-effectiveness.js +99 -0
- package/dist/analysis/fix-effectiveness.js.map +1 -0
- package/dist/analysis/scoring.d.ts +15 -0
- package/dist/analysis/scoring.d.ts.map +1 -0
- package/dist/analysis/scoring.js +57 -0
- package/dist/analysis/scoring.js.map +1 -0
- package/dist/analysis/time-analysis.d.ts +22 -0
- package/dist/analysis/time-analysis.d.ts.map +1 -0
- package/dist/analysis/time-analysis.js +174 -0
- package/dist/analysis/time-analysis.js.map +1 -0
- package/dist/analysis/verdict-details.d.ts +23 -0
- package/dist/analysis/verdict-details.d.ts.map +1 -0
- package/dist/analysis/verdict-details.js +59 -0
- package/dist/analysis/verdict-details.js.map +1 -0
- package/dist/analysis/verification-quality.d.ts +19 -0
- package/dist/analysis/verification-quality.d.ts.map +1 -0
- package/dist/analysis/verification-quality.js +182 -0
- package/dist/analysis/verification-quality.js.map +1 -0
- package/dist/clients/base.d.ts +2 -0
- package/dist/clients/base.d.ts.map +1 -1
- package/dist/clients/claude/commands/ironbee-analyze.md +42 -0
- package/dist/clients/claude/hooks/clear-verdict.js +1 -1
- package/dist/clients/claude/hooks/clear-verdict.js.map +1 -1
- package/dist/clients/claude/hooks/require-verification.d.ts +15 -0
- package/dist/clients/claude/hooks/require-verification.d.ts.map +1 -0
- package/dist/clients/claude/hooks/require-verification.js +61 -0
- package/dist/clients/claude/hooks/require-verification.js.map +1 -0
- package/dist/clients/claude/hooks/session-start.d.ts +1 -1
- package/dist/clients/claude/hooks/session-start.d.ts.map +1 -1
- package/dist/clients/claude/hooks/session-start.js +10 -1
- package/dist/clients/claude/hooks/session-start.js.map +1 -1
- package/dist/clients/claude/hooks/track-action.d.ts +1 -1
- package/dist/clients/claude/hooks/track-action.d.ts.map +1 -1
- package/dist/clients/claude/hooks/track-action.js +58 -13
- package/dist/clients/claude/hooks/track-action.js.map +1 -1
- package/dist/clients/claude/hooks/verify-gate.d.ts +1 -1
- package/dist/clients/claude/hooks/verify-gate.d.ts.map +1 -1
- package/dist/clients/claude/hooks/verify-gate.js +3 -3
- package/dist/clients/claude/hooks/verify-gate.js.map +1 -1
- package/dist/clients/claude/index.d.ts +2 -0
- package/dist/clients/claude/index.d.ts.map +1 -1
- package/dist/clients/claude/index.js +43 -9
- package/dist/clients/claude/index.js.map +1 -1
- package/dist/clients/claude/rule.md +9 -7
- package/dist/clients/claude/skill.md +11 -8
- package/dist/clients/claude/skills/ironbee-analyze.md +39 -0
- package/dist/clients/cursor/commands/ironbee-analyze/SKILL.md +48 -0
- package/dist/clients/cursor/hooks/clear-verdict.js +1 -1
- package/dist/clients/cursor/hooks/clear-verdict.js.map +1 -1
- package/dist/clients/cursor/hooks/require-verification.d.ts +15 -0
- package/dist/clients/cursor/hooks/require-verification.d.ts.map +1 -0
- package/dist/clients/cursor/hooks/require-verification.js +63 -0
- package/dist/clients/cursor/hooks/require-verification.js.map +1 -0
- package/dist/clients/cursor/hooks/session-start.d.ts +1 -1
- package/dist/clients/cursor/hooks/session-start.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/session-start.js +6 -1
- package/dist/clients/cursor/hooks/session-start.js.map +1 -1
- package/dist/clients/cursor/hooks/track-action.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/track-action.js +62 -12
- package/dist/clients/cursor/hooks/track-action.js.map +1 -1
- package/dist/clients/cursor/hooks/verify-gate.d.ts +1 -1
- package/dist/clients/cursor/hooks/verify-gate.d.ts.map +1 -1
- package/dist/clients/cursor/hooks/verify-gate.js +3 -3
- package/dist/clients/cursor/hooks/verify-gate.js.map +1 -1
- package/dist/clients/cursor/index.d.ts +2 -0
- package/dist/clients/cursor/index.d.ts.map +1 -1
- package/dist/clients/cursor/index.js +31 -6
- package/dist/clients/cursor/index.js.map +1 -1
- package/dist/clients/cursor/rule.md +9 -7
- package/dist/clients/cursor/skill.md +11 -8
- package/dist/commands/analyze.d.ts +3 -0
- package/dist/commands/analyze.d.ts.map +1 -0
- package/dist/commands/analyze.js +298 -0
- package/dist/commands/analyze.js.map +1 -0
- package/dist/commands/hook.d.ts.map +1 -1
- package/dist/commands/hook.js +81 -2
- package/dist/commands/hook.js.map +1 -1
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +3 -1
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/uninstall.d.ts.map +1 -1
- package/dist/commands/uninstall.js +3 -1
- package/dist/commands/uninstall.js.map +1 -1
- package/dist/hooks/core/actions.d.ts +19 -0
- package/dist/hooks/core/actions.d.ts.map +1 -1
- package/dist/hooks/core/actions.js +5 -0
- package/dist/hooks/core/actions.js.map +1 -1
- package/dist/hooks/core/clear-verdict.d.ts +1 -1
- package/dist/hooks/core/clear-verdict.d.ts.map +1 -1
- package/dist/hooks/core/clear-verdict.js +13 -9
- package/dist/hooks/core/clear-verdict.js.map +1 -1
- package/dist/hooks/core/session-state.d.ts +47 -0
- package/dist/hooks/core/session-state.d.ts.map +1 -0
- package/dist/hooks/core/session-state.js +192 -0
- package/dist/hooks/core/session-state.js.map +1 -0
- package/dist/hooks/core/submit-verdict.d.ts +2 -1
- package/dist/hooks/core/submit-verdict.d.ts.map +1 -1
- package/dist/hooks/core/submit-verdict.js +38 -28
- package/dist/hooks/core/submit-verdict.js.map +1 -1
- package/dist/hooks/core/verification-lifecycle.d.ts +30 -0
- package/dist/hooks/core/verification-lifecycle.d.ts.map +1 -0
- package/dist/hooks/core/verification-lifecycle.js +75 -0
- package/dist/hooks/core/verification-lifecycle.js.map +1 -0
- package/dist/hooks/core/verify-gate.d.ts +2 -2
- package/dist/hooks/core/verify-gate.d.ts.map +1 -1
- package/dist/hooks/core/verify-gate.js +28 -33
- package/dist/hooks/core/verify-gate.js.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/telemetry.d.ts +23 -0
- package/dist/lib/telemetry.d.ts.map +1 -0
- package/dist/lib/telemetry.js +265 -0
- package/dist/lib/telemetry.js.map +1 -0
- package/dist/scripts/postinstall.d.ts +7 -0
- package/dist/scripts/postinstall.d.ts.map +1 -0
- package/dist/scripts/postinstall.js +12 -0
- package/dist/scripts/postinstall.js.map +1 -0
- package/dist/scripts/preuninstall.d.ts +8 -0
- package/dist/scripts/preuninstall.d.ts.map +1 -0
- package/dist/scripts/preuninstall.js +13 -0
- package/dist/scripts/preuninstall.js.map +1 -0
- package/package.json +6 -3
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* IronBee — Session State Management
|
|
4
|
+
*
|
|
5
|
+
* Centralized state management for session data.
|
|
6
|
+
* All session state (retries, activeVerificationId, lastVerdictStatus)
|
|
7
|
+
* is stored in a single state.json file per session.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.generateTraceId = generateTraceId;
|
|
11
|
+
exports.readState = readState;
|
|
12
|
+
exports.writeState = writeState;
|
|
13
|
+
exports.getActiveVerificationId = getActiveVerificationId;
|
|
14
|
+
exports.setActiveVerification = setActiveVerification;
|
|
15
|
+
exports.getActiveTraceId = getActiveTraceId;
|
|
16
|
+
exports.clearActiveVerification = clearActiveVerification;
|
|
17
|
+
exports.getRetries = getRetries;
|
|
18
|
+
exports.incrementRetries = incrementRetries;
|
|
19
|
+
exports.resetRetries = resetRetries;
|
|
20
|
+
exports.getLastVerdictStatus = getLastVerdictStatus;
|
|
21
|
+
exports.setLastVerdictStatus = setLastVerdictStatus;
|
|
22
|
+
exports.setActiveFix = setActiveFix;
|
|
23
|
+
exports.getActiveFixId = getActiveFixId;
|
|
24
|
+
exports.clearActiveFix = clearActiveFix;
|
|
25
|
+
exports.setPhase = setPhase;
|
|
26
|
+
exports.getPhase = getPhase;
|
|
27
|
+
exports.reconcileSessionState = reconcileSessionState;
|
|
28
|
+
const crypto_1 = require("crypto");
|
|
29
|
+
const fs_1 = require("fs");
|
|
30
|
+
const path_1 = require("path");
|
|
31
|
+
const logger_1 = require("../../lib/logger");
|
|
32
|
+
const STATE_FILE = "state.json";
|
|
33
|
+
const DEFAULT_STATE = {
|
|
34
|
+
retries: 0,
|
|
35
|
+
activeVerificationId: null,
|
|
36
|
+
activeTraceId: null,
|
|
37
|
+
lastVerdictStatus: null,
|
|
38
|
+
activeFixId: null,
|
|
39
|
+
phase: null,
|
|
40
|
+
};
|
|
41
|
+
/** Generate an OTEL-compatible trace ID (32 hex chars / 16 bytes). */
|
|
42
|
+
function generateTraceId() {
|
|
43
|
+
return (0, crypto_1.randomBytes)(16).toString("hex");
|
|
44
|
+
}
|
|
45
|
+
function readState(sessionDir) {
|
|
46
|
+
const filePath = (0, path_1.join)(sessionDir, STATE_FILE);
|
|
47
|
+
if (!(0, fs_1.existsSync)(filePath)) {
|
|
48
|
+
return { ...DEFAULT_STATE };
|
|
49
|
+
}
|
|
50
|
+
try {
|
|
51
|
+
const content = (0, fs_1.readFileSync)(filePath, "utf-8");
|
|
52
|
+
const parsed = JSON.parse(content);
|
|
53
|
+
const validPhases = ["coding", "verifying", "fixing"];
|
|
54
|
+
return {
|
|
55
|
+
retries: typeof parsed.retries === "number" ? parsed.retries : 0,
|
|
56
|
+
activeVerificationId: typeof parsed.activeVerificationId === "string" ? parsed.activeVerificationId : null,
|
|
57
|
+
activeTraceId: typeof parsed.activeTraceId === "string" ? parsed.activeTraceId : null,
|
|
58
|
+
lastVerdictStatus: typeof parsed.lastVerdictStatus === "string" ? parsed.lastVerdictStatus : null,
|
|
59
|
+
activeFixId: typeof parsed.activeFixId === "string" ? parsed.activeFixId : null,
|
|
60
|
+
phase: typeof parsed.phase === "string" && validPhases.includes(parsed.phase) ? parsed.phase : null,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
catch (e) {
|
|
64
|
+
logger_1.logger.debug(`failed to read state from ${filePath}: ${e}`);
|
|
65
|
+
return { ...DEFAULT_STATE };
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function writeState(sessionDir, state) {
|
|
69
|
+
const filePath = (0, path_1.join)(sessionDir, STATE_FILE);
|
|
70
|
+
try {
|
|
71
|
+
(0, fs_1.mkdirSync)(sessionDir, { recursive: true });
|
|
72
|
+
(0, fs_1.writeFileSync)(filePath, JSON.stringify(state, null, 2));
|
|
73
|
+
}
|
|
74
|
+
catch (e) {
|
|
75
|
+
logger_1.logger.debug(`failed to write state to ${filePath}: ${e}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
function getActiveVerificationId(sessionDir) {
|
|
79
|
+
const state = readState(sessionDir);
|
|
80
|
+
return state.activeVerificationId ?? undefined;
|
|
81
|
+
}
|
|
82
|
+
function setActiveVerification(sessionDir, verificationId, traceId) {
|
|
83
|
+
const state = readState(sessionDir);
|
|
84
|
+
state.activeVerificationId = verificationId;
|
|
85
|
+
state.activeTraceId = traceId;
|
|
86
|
+
state.phase = "verifying";
|
|
87
|
+
writeState(sessionDir, state);
|
|
88
|
+
}
|
|
89
|
+
function getActiveTraceId(sessionDir) {
|
|
90
|
+
const state = readState(sessionDir);
|
|
91
|
+
return state.activeTraceId ?? undefined;
|
|
92
|
+
}
|
|
93
|
+
function clearActiveVerification(sessionDir) {
|
|
94
|
+
const state = readState(sessionDir);
|
|
95
|
+
state.activeVerificationId = null;
|
|
96
|
+
state.activeTraceId = null;
|
|
97
|
+
state.phase = "coding";
|
|
98
|
+
writeState(sessionDir, state);
|
|
99
|
+
}
|
|
100
|
+
function getRetries(sessionDir) {
|
|
101
|
+
const state = readState(sessionDir);
|
|
102
|
+
return state.retries;
|
|
103
|
+
}
|
|
104
|
+
function incrementRetries(sessionDir) {
|
|
105
|
+
const state = readState(sessionDir);
|
|
106
|
+
state.retries = state.retries + 1;
|
|
107
|
+
writeState(sessionDir, state);
|
|
108
|
+
return state.retries;
|
|
109
|
+
}
|
|
110
|
+
function resetRetries(sessionDir) {
|
|
111
|
+
const state = readState(sessionDir);
|
|
112
|
+
state.retries = 0;
|
|
113
|
+
writeState(sessionDir, state);
|
|
114
|
+
}
|
|
115
|
+
function getLastVerdictStatus(sessionDir) {
|
|
116
|
+
const state = readState(sessionDir);
|
|
117
|
+
return state.lastVerdictStatus ?? undefined;
|
|
118
|
+
}
|
|
119
|
+
function setLastVerdictStatus(sessionDir, status) {
|
|
120
|
+
const state = readState(sessionDir);
|
|
121
|
+
state.lastVerdictStatus = status;
|
|
122
|
+
writeState(sessionDir, state);
|
|
123
|
+
}
|
|
124
|
+
function setActiveFix(sessionDir, fixId) {
|
|
125
|
+
const state = readState(sessionDir);
|
|
126
|
+
state.activeFixId = fixId;
|
|
127
|
+
writeState(sessionDir, state);
|
|
128
|
+
}
|
|
129
|
+
function getActiveFixId(sessionDir) {
|
|
130
|
+
const state = readState(sessionDir);
|
|
131
|
+
return state.activeFixId ?? undefined;
|
|
132
|
+
}
|
|
133
|
+
function clearActiveFix(sessionDir) {
|
|
134
|
+
const state = readState(sessionDir);
|
|
135
|
+
state.activeFixId = null;
|
|
136
|
+
writeState(sessionDir, state);
|
|
137
|
+
}
|
|
138
|
+
function setPhase(sessionDir, phase) {
|
|
139
|
+
const state = readState(sessionDir);
|
|
140
|
+
state.phase = phase;
|
|
141
|
+
writeState(sessionDir, state);
|
|
142
|
+
}
|
|
143
|
+
function getPhase(sessionDir) {
|
|
144
|
+
const state = readState(sessionDir);
|
|
145
|
+
return state.phase;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Reconcile session state on session start/resume.
|
|
149
|
+
* Closes any open verification or fix cycles, records appropriate
|
|
150
|
+
* end entries in actions.jsonl, and resets phase to "coding".
|
|
151
|
+
*
|
|
152
|
+
* @param appendFn — action appender function (avoids circular import with actions.ts)
|
|
153
|
+
*/
|
|
154
|
+
function reconcileSessionState(sessionDir, actionsFile, appendFn) {
|
|
155
|
+
const state = readState(sessionDir);
|
|
156
|
+
let dirty = false;
|
|
157
|
+
// close abandoned verification
|
|
158
|
+
if (state.activeVerificationId) {
|
|
159
|
+
appendFn(actionsFile, {
|
|
160
|
+
type: "verification_end",
|
|
161
|
+
timestamp: new Date().toISOString(),
|
|
162
|
+
verification_id: state.activeVerificationId,
|
|
163
|
+
trace_id: state.activeTraceId,
|
|
164
|
+
reason: "session_reconcile",
|
|
165
|
+
});
|
|
166
|
+
logger_1.logger.debug(`reconcile: ended abandoned verification ${state.activeVerificationId}`);
|
|
167
|
+
state.activeVerificationId = null;
|
|
168
|
+
state.activeTraceId = null;
|
|
169
|
+
dirty = true;
|
|
170
|
+
}
|
|
171
|
+
// close abandoned fix
|
|
172
|
+
if (state.activeFixId) {
|
|
173
|
+
appendFn(actionsFile, {
|
|
174
|
+
type: "fix_end",
|
|
175
|
+
timestamp: new Date().toISOString(),
|
|
176
|
+
fix_id: state.activeFixId,
|
|
177
|
+
reason: "session_reconcile",
|
|
178
|
+
});
|
|
179
|
+
logger_1.logger.debug(`reconcile: ended abandoned fix ${state.activeFixId}`);
|
|
180
|
+
state.activeFixId = null;
|
|
181
|
+
dirty = true;
|
|
182
|
+
}
|
|
183
|
+
// reset phase to coding
|
|
184
|
+
if (state.phase !== "coding") {
|
|
185
|
+
state.phase = "coding";
|
|
186
|
+
dirty = true;
|
|
187
|
+
}
|
|
188
|
+
if (dirty) {
|
|
189
|
+
writeState(sessionDir, state);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
//# sourceMappingURL=session-state.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-state.js","sourceRoot":"","sources":["../../../src/hooks/core/session-state.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AA8BH,0CAEC;AAED,8BAqBC;AAED,gCAQC;AAED,0DAGC;AAED,sDAMC;AAED,4CAGC;AAED,0DAMC;AAED,gCAGC;AAED,4CAKC;AAED,oCAIC;AAED,oDAGC;AAED,oDAIC;AAED,oCAIC;AAED,wCAGC;AAED,wCAIC;AAED,4BAIC;AAED,4BAGC;AASD,sDA6CC;AAxMD,mCAAqC;AACrC,2BAAwE;AACxE,+BAA4B;AAC5B,6CAA0C;AAa1C,MAAM,UAAU,GAAW,YAAY,CAAC;AAExC,MAAM,aAAa,GAAiB;IAChC,OAAO,EAAE,CAAC;IACV,oBAAoB,EAAE,IAAI;IAC1B,aAAa,EAAE,IAAI;IACnB,iBAAiB,EAAE,IAAI;IACvB,WAAW,EAAE,IAAI;IACjB,KAAK,EAAE,IAAI;CACd,CAAC;AAEF,sEAAsE;AACtE,SAAgB,eAAe;IAC3B,OAAO,IAAA,oBAAW,EAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AAC3C,CAAC;AAED,SAAgB,SAAS,CAAC,UAAkB;IACxC,MAAM,QAAQ,GAAW,IAAA,WAAI,EAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACtD,IAAI,CAAC,IAAA,eAAU,EAAC,QAAQ,CAAC,EAAE,CAAC;QACxB,OAAO,EAAE,GAAG,aAAa,EAAE,CAAC;IAChC,CAAC;IACD,IAAI,CAAC;QACD,MAAM,OAAO,GAAW,IAAA,iBAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,MAAM,GAAiB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAiB,CAAC;QACjE,MAAM,WAAW,GAAa,CAAC,QAAQ,EAAE,WAAW,EAAE,QAAQ,CAAC,CAAC;QAChE,OAAO;YACH,OAAO,EAAE,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAChE,oBAAoB,EAAE,OAAO,MAAM,CAAC,oBAAoB,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC,IAAI;YAC1G,aAAa,EAAE,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI;YACrF,iBAAiB,EAAE,OAAO,MAAM,CAAC,iBAAiB,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI;YACjG,WAAW,EAAE,OAAO,MAAM,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI;YAC/E,KAAK,EAAE,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,WAAW,CAAC,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAqB,CAAC,CAAC,CAAC,IAAI;SACtH,CAAC;IACN,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QAClB,eAAM,CAAC,KAAK,CAAC,6BAA6B,QAAQ,KAAK,CAAC,EAAE,CAAC,CAAC;QAC5D,OAAO,EAAE,GAAG,aAAa,EAAE,CAAC;IAChC,CAAC;AACL,CAAC;AAED,SAAgB,UAAU,CAAC,UAAkB,EAAE,KAAmB;IAC9D,MAAM,QAAQ,GAAW,IAAA,WAAI,EAAC,UAAU,EAAE,UAAU,CAAC,CAAC;IACtD,IAAI,CAAC;QACD,IAAA,cAAS,EAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3C,IAAA,kBAAa,EAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC5D,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QAClB,eAAM,CAAC,KAAK,CAAC,4BAA4B,QAAQ,KAAK,CAAC,EAAE,CAAC,CAAC;IAC/D,CAAC;AACL,CAAC;AAED,SAAgB,uBAAuB,CAAC,UAAkB;IACtD,MAAM,KAAK,GAAiB,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,OAAO,KAAK,CAAC,oBAAoB,IAAI,SAAS,CAAC;AACnD,CAAC;AAED,SAAgB,qBAAqB,CAAC,UAAkB,EAAE,cAAsB,EAAE,OAAe;IAC7F,MAAM,KAAK,GAAiB,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,KAAK,CAAC,oBAAoB,GAAG,cAAc,CAAC;IAC5C,KAAK,CAAC,aAAa,GAAG,OAAO,CAAC;IAC9B,KAAK,CAAC,KAAK,GAAG,WAAW,CAAC;IAC1B,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,SAAgB,gBAAgB,CAAC,UAAkB;IAC/C,MAAM,KAAK,GAAiB,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,OAAO,KAAK,CAAC,aAAa,IAAI,SAAS,CAAC;AAC5C,CAAC;AAED,SAAgB,uBAAuB,CAAC,UAAkB;IACtD,MAAM,KAAK,GAAiB,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,KAAK,CAAC,oBAAoB,GAAG,IAAI,CAAC;IAClC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;IAC3B,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC;IACvB,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,SAAgB,UAAU,CAAC,UAAkB;IACzC,MAAM,KAAK,GAAiB,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,OAAO,KAAK,CAAC,OAAO,CAAC;AACzB,CAAC;AAED,SAAgB,gBAAgB,CAAC,UAAkB;IAC/C,MAAM,KAAK,GAAiB,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC;IAClC,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAC9B,OAAO,KAAK,CAAC,OAAO,CAAC;AACzB,CAAC;AAED,SAAgB,YAAY,CAAC,UAAkB;IAC3C,MAAM,KAAK,GAAiB,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC;IAClB,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,SAAgB,oBAAoB,CAAC,UAAkB;IACnD,MAAM,KAAK,GAAiB,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,OAAO,KAAK,CAAC,iBAAiB,IAAI,SAAS,CAAC;AAChD,CAAC;AAED,SAAgB,oBAAoB,CAAC,UAAkB,EAAE,MAAqB;IAC1E,MAAM,KAAK,GAAiB,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,KAAK,CAAC,iBAAiB,GAAG,MAAM,CAAC;IACjC,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,SAAgB,YAAY,CAAC,UAAkB,EAAE,KAAa;IAC1D,MAAM,KAAK,GAAiB,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,KAAK,CAAC,WAAW,GAAG,KAAK,CAAC;IAC1B,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,SAAgB,cAAc,CAAC,UAAkB;IAC7C,MAAM,KAAK,GAAiB,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,OAAO,KAAK,CAAC,WAAW,IAAI,SAAS,CAAC;AAC1C,CAAC;AAED,SAAgB,cAAc,CAAC,UAAkB;IAC7C,MAAM,KAAK,GAAiB,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,SAAgB,QAAQ,CAAC,UAAkB,EAAE,KAAmB;IAC5D,MAAM,KAAK,GAAiB,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,KAAK,CAAC,KAAK,GAAG,KAAK,CAAC;IACpB,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;AAClC,CAAC;AAED,SAAgB,QAAQ,CAAC,UAAkB;IACvC,MAAM,KAAK,GAAiB,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,OAAO,KAAK,CAAC,KAAK,CAAC;AACvB,CAAC;AAED;;;;;;GAMG;AACH,SAAgB,qBAAqB,CACjC,UAAkB,EAClB,WAAmB,EACnB,QAAoG;IAEpG,MAAM,KAAK,GAAiB,SAAS,CAAC,UAAU,CAAC,CAAC;IAClD,IAAI,KAAK,GAAY,KAAK,CAAC;IAE3B,+BAA+B;IAC/B,IAAI,KAAK,CAAC,oBAAoB,EAAE,CAAC;QAC7B,QAAQ,CAAC,WAAW,EAAE;YAClB,IAAI,EAAE,kBAAkB;YACxB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,eAAe,EAAE,KAAK,CAAC,oBAAoB;YAC3C,QAAQ,EAAE,KAAK,CAAC,aAAa;YAC7B,MAAM,EAAE,mBAAmB;SAC9B,CAAC,CAAC;QACH,eAAM,CAAC,KAAK,CAAC,2CAA2C,KAAK,CAAC,oBAAoB,EAAE,CAAC,CAAC;QACtF,KAAK,CAAC,oBAAoB,GAAG,IAAI,CAAC;QAClC,KAAK,CAAC,aAAa,GAAG,IAAI,CAAC;QAC3B,KAAK,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,sBAAsB;IACtB,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;QACpB,QAAQ,CAAC,WAAW,EAAE;YAClB,IAAI,EAAE,SAAS;YACf,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,MAAM,EAAE,KAAK,CAAC,WAAW;YACzB,MAAM,EAAE,mBAAmB;SAC9B,CAAC,CAAC;QACH,eAAM,CAAC,KAAK,CAAC,kCAAkC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;QACpE,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;QACzB,KAAK,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,wBAAwB;IACxB,IAAI,KAAK,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC3B,KAAK,CAAC,KAAK,GAAG,QAAQ,CAAC;QACvB,KAAK,GAAG,IAAI,CAAC;IACjB,CAAC;IAED,IAAI,KAAK,EAAE,CAAC;QACR,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;AACL,CAAC"}
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
export interface SubmitVerdictInput {
|
|
11
11
|
sessionId: string;
|
|
12
|
+
sessionDir: string;
|
|
12
13
|
verdictFile: string;
|
|
13
14
|
actionsFile: string;
|
|
14
15
|
verdictJson: string;
|
|
@@ -17,5 +18,5 @@ export interface SubmitVerdictResult {
|
|
|
17
18
|
success: boolean;
|
|
18
19
|
message: string;
|
|
19
20
|
}
|
|
20
|
-
export declare function runSubmitVerdict(input: SubmitVerdictInput): SubmitVerdictResult
|
|
21
|
+
export declare function runSubmitVerdict(input: SubmitVerdictInput): Promise<SubmitVerdictResult>;
|
|
21
22
|
//# sourceMappingURL=submit-verdict.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submit-verdict.d.ts","sourceRoot":"","sources":["../../../src/hooks/core/submit-verdict.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"submit-verdict.d.ts","sourceRoot":"","sources":["../../../src/hooks/core/submit-verdict.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAUH,MAAM,WAAW,kBAAkB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACnB;AAYD,wBAAsB,gBAAgB,CAAC,KAAK,EAAE,kBAAkB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAgH9F"}
|
|
@@ -10,37 +10,15 @@
|
|
|
10
10
|
*/
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.runSubmitVerdict = runSubmitVerdict;
|
|
13
|
+
const crypto_1 = require("crypto");
|
|
13
14
|
const fs_1 = require("fs");
|
|
14
15
|
const path_1 = require("path");
|
|
15
16
|
const logger_1 = require("../../lib/logger");
|
|
17
|
+
const telemetry_1 = require("../../lib/telemetry");
|
|
16
18
|
const actions_1 = require("./actions");
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
try {
|
|
22
|
-
const content = (0, fs_1.readFileSync)(actionsFile, "utf-8");
|
|
23
|
-
const lines = content.trim().split("\n").filter((l) => l.length > 0);
|
|
24
|
-
for (let i = lines.length - 1; i >= 0; i--) {
|
|
25
|
-
try {
|
|
26
|
-
const entry = JSON.parse(lines[i]);
|
|
27
|
-
if (entry.type === "verdict_write") {
|
|
28
|
-
const verdict = entry.verdict;
|
|
29
|
-
return typeof verdict.status === "string" ? verdict.status : undefined;
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
catch {
|
|
33
|
-
// skip malformed lines
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return undefined;
|
|
37
|
-
}
|
|
38
|
-
catch {
|
|
39
|
-
return undefined;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
function runSubmitVerdict(input) {
|
|
43
|
-
const { sessionId, verdictFile, actionsFile, verdictJson } = input;
|
|
19
|
+
const session_state_1 = require("./session-state");
|
|
20
|
+
async function runSubmitVerdict(input) {
|
|
21
|
+
const { sessionId, sessionDir, verdictFile, actionsFile, verdictJson } = input;
|
|
44
22
|
// parse JSON
|
|
45
23
|
let verdict;
|
|
46
24
|
try {
|
|
@@ -75,7 +53,7 @@ function runSubmitVerdict(input) {
|
|
|
75
53
|
}
|
|
76
54
|
// validate fixes — required when pass after a previous fail
|
|
77
55
|
if (verdict.status === "pass") {
|
|
78
|
-
const lastStatus = getLastVerdictStatus(
|
|
56
|
+
const lastStatus = (0, session_state_1.getLastVerdictStatus)(sessionDir);
|
|
79
57
|
if (lastStatus === "fail") {
|
|
80
58
|
if (!Array.isArray(verdict.fixes) || verdict.fixes.length === 0) {
|
|
81
59
|
return { success: false, message: "REJECTED: when status is \"pass\" after a previous fail, fixes must be a non-empty array describing what was fixed." };
|
|
@@ -91,13 +69,45 @@ function runSubmitVerdict(input) {
|
|
|
91
69
|
logger_1.logger.debug(`submit-verdict: failed to write ${verdictFile}: ${e}`);
|
|
92
70
|
return { success: false, message: `REJECTED: failed to write verdict file: ${e}` };
|
|
93
71
|
}
|
|
72
|
+
// update last verdict status in session state
|
|
73
|
+
(0, session_state_1.setLastVerdictStatus)(sessionDir, verdict.status);
|
|
74
|
+
// auto-record verification_end if there's an active verification
|
|
75
|
+
const verificationId = (0, session_state_1.getActiveVerificationId)(sessionDir);
|
|
76
|
+
const traceId = (0, session_state_1.getActiveTraceId)(sessionDir);
|
|
77
|
+
if (verificationId) {
|
|
78
|
+
const endEntry = {
|
|
79
|
+
type: "verification_end",
|
|
80
|
+
timestamp: new Date().toISOString(),
|
|
81
|
+
verification_id: verificationId,
|
|
82
|
+
trace_id: traceId,
|
|
83
|
+
};
|
|
84
|
+
(0, actions_1.appendAction)(actionsFile, endEntry);
|
|
85
|
+
(0, session_state_1.clearActiveVerification)(sessionDir);
|
|
86
|
+
logger_1.logger.debug(`verification-end (auto): ${verificationId} trace=${traceId}`);
|
|
87
|
+
}
|
|
94
88
|
// record verdict_write action
|
|
95
89
|
const entry = {
|
|
96
90
|
type: "verdict_write",
|
|
97
91
|
timestamp: new Date().toISOString(),
|
|
92
|
+
verification_id: verificationId,
|
|
93
|
+
trace_id: traceId,
|
|
98
94
|
verdict: verdict,
|
|
99
95
|
};
|
|
100
96
|
(0, actions_1.appendAction)(actionsFile, entry);
|
|
97
|
+
await (0, telemetry_1.trackVerdictWrite)(sessionId, verdict.status);
|
|
98
|
+
// record fix_start when verdict is fail
|
|
99
|
+
if (verdict.status === "fail") {
|
|
100
|
+
const fixId = (0, crypto_1.randomUUID)();
|
|
101
|
+
const fixEntry = {
|
|
102
|
+
type: "fix_start",
|
|
103
|
+
timestamp: new Date().toISOString(),
|
|
104
|
+
fix_id: fixId,
|
|
105
|
+
};
|
|
106
|
+
(0, actions_1.appendAction)(actionsFile, fixEntry);
|
|
107
|
+
(0, session_state_1.setActiveFix)(sessionDir, fixId);
|
|
108
|
+
(0, session_state_1.setPhase)(sessionDir, "fixing");
|
|
109
|
+
logger_1.logger.debug(`fix-start: ${fixId} (verdict was fail)`);
|
|
110
|
+
}
|
|
101
111
|
logger_1.logger.debug(`submit-verdict: session=${sessionId} status=${verdict.status}`);
|
|
102
112
|
if (verdict.status === "pass") {
|
|
103
113
|
const fixesInfo = verdict.fixes?.length ? ` Fixes: ${verdict.fixes.join(", ")}` : "";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submit-verdict.js","sourceRoot":"","sources":["../../../src/hooks/core/submit-verdict.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;
|
|
1
|
+
{"version":3,"file":"submit-verdict.js","sourceRoot":"","sources":["../../../src/hooks/core/submit-verdict.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* IronBee — Verification Lifecycle Core Logic
|
|
3
|
+
*
|
|
4
|
+
* Manages verification start/end boundaries.
|
|
5
|
+
* Each verification cycle gets a unique ID and an OTEL-compatible trace ID
|
|
6
|
+
* linking start → end → verdict.
|
|
7
|
+
*/
|
|
8
|
+
export interface VerificationStartInput {
|
|
9
|
+
sessionId: string;
|
|
10
|
+
sessionDir: string;
|
|
11
|
+
actionsFile: string;
|
|
12
|
+
}
|
|
13
|
+
export interface VerificationStartResult {
|
|
14
|
+
verificationId: string;
|
|
15
|
+
traceId: string;
|
|
16
|
+
}
|
|
17
|
+
export interface VerificationEndInput {
|
|
18
|
+
sessionId: string;
|
|
19
|
+
sessionDir: string;
|
|
20
|
+
actionsFile: string;
|
|
21
|
+
}
|
|
22
|
+
export interface VerificationEndResult {
|
|
23
|
+
success: boolean;
|
|
24
|
+
verificationId?: string;
|
|
25
|
+
traceId?: string;
|
|
26
|
+
message: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function startVerification(input: VerificationStartInput): VerificationStartResult;
|
|
29
|
+
export declare function endVerification(input: VerificationEndInput): VerificationEndResult;
|
|
30
|
+
//# sourceMappingURL=verification-lifecycle.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification-lifecycle.d.ts","sourceRoot":"","sources":["../../../src/hooks/core/verification-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH,MAAM,WAAW,sBAAsB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,uBAAuB;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,sBAAsB,GAAG,uBAAuB,CA8CxF;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,qBAAqB,CAsBlF"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* IronBee — Verification Lifecycle Core Logic
|
|
4
|
+
*
|
|
5
|
+
* Manages verification start/end boundaries.
|
|
6
|
+
* Each verification cycle gets a unique ID and an OTEL-compatible trace ID
|
|
7
|
+
* linking start → end → verdict.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.startVerification = startVerification;
|
|
11
|
+
exports.endVerification = endVerification;
|
|
12
|
+
const crypto_1 = require("crypto");
|
|
13
|
+
const logger_1 = require("../../lib/logger");
|
|
14
|
+
const actions_1 = require("./actions");
|
|
15
|
+
const session_state_1 = require("./session-state");
|
|
16
|
+
function startVerification(input) {
|
|
17
|
+
const { sessionDir, actionsFile } = input;
|
|
18
|
+
// if there's an active fix, end it before starting verification
|
|
19
|
+
const activeFixId = (0, session_state_1.getActiveFixId)(sessionDir);
|
|
20
|
+
if (activeFixId) {
|
|
21
|
+
const fixEndEntry = {
|
|
22
|
+
type: "fix_end",
|
|
23
|
+
timestamp: new Date().toISOString(),
|
|
24
|
+
fix_id: activeFixId,
|
|
25
|
+
};
|
|
26
|
+
(0, actions_1.appendAction)(actionsFile, fixEndEntry);
|
|
27
|
+
(0, session_state_1.clearActiveFix)(sessionDir);
|
|
28
|
+
logger_1.logger.debug(`fix-end: ${activeFixId} (starting new verification)`);
|
|
29
|
+
}
|
|
30
|
+
// if there's already an active verification, end it first
|
|
31
|
+
const existingId = (0, session_state_1.getActiveVerificationId)(sessionDir);
|
|
32
|
+
if (existingId) {
|
|
33
|
+
const existingTraceId = (0, session_state_1.getActiveTraceId)(sessionDir);
|
|
34
|
+
logger_1.logger.debug(`ending previous verification ${existingId} before starting new one`);
|
|
35
|
+
const endEntry = {
|
|
36
|
+
type: "verification_end",
|
|
37
|
+
timestamp: new Date().toISOString(),
|
|
38
|
+
verification_id: existingId,
|
|
39
|
+
trace_id: existingTraceId,
|
|
40
|
+
};
|
|
41
|
+
(0, actions_1.appendAction)(actionsFile, endEntry);
|
|
42
|
+
(0, session_state_1.clearActiveVerification)(sessionDir);
|
|
43
|
+
}
|
|
44
|
+
const verificationId = (0, crypto_1.randomUUID)();
|
|
45
|
+
const traceId = (0, session_state_1.generateTraceId)();
|
|
46
|
+
const entry = {
|
|
47
|
+
type: "verification_start",
|
|
48
|
+
timestamp: new Date().toISOString(),
|
|
49
|
+
verification_id: verificationId,
|
|
50
|
+
trace_id: traceId,
|
|
51
|
+
};
|
|
52
|
+
(0, actions_1.appendAction)(actionsFile, entry);
|
|
53
|
+
(0, session_state_1.setActiveVerification)(sessionDir, verificationId, traceId);
|
|
54
|
+
logger_1.logger.debug(`verification-start: ${verificationId} trace=${traceId}`);
|
|
55
|
+
return { verificationId, traceId };
|
|
56
|
+
}
|
|
57
|
+
function endVerification(input) {
|
|
58
|
+
const { sessionDir, actionsFile } = input;
|
|
59
|
+
const verificationId = (0, session_state_1.getActiveVerificationId)(sessionDir);
|
|
60
|
+
if (!verificationId) {
|
|
61
|
+
return { success: false, message: "No active verification to end." };
|
|
62
|
+
}
|
|
63
|
+
const traceId = (0, session_state_1.getActiveTraceId)(sessionDir);
|
|
64
|
+
const entry = {
|
|
65
|
+
type: "verification_end",
|
|
66
|
+
timestamp: new Date().toISOString(),
|
|
67
|
+
verification_id: verificationId,
|
|
68
|
+
trace_id: traceId,
|
|
69
|
+
};
|
|
70
|
+
(0, actions_1.appendAction)(actionsFile, entry);
|
|
71
|
+
(0, session_state_1.clearActiveVerification)(sessionDir);
|
|
72
|
+
logger_1.logger.debug(`verification-end: ${verificationId} trace=${traceId}`);
|
|
73
|
+
return { success: true, verificationId, traceId, message: `Verification ${verificationId} ended.` };
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=verification-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification-lifecycle.js","sourceRoot":"","sources":["../../../src/hooks/core/verification-lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,14 +7,14 @@
|
|
|
7
7
|
*/
|
|
8
8
|
export interface VerifyGateInput {
|
|
9
9
|
sessionId: string;
|
|
10
|
+
sessionDir: string;
|
|
10
11
|
actionsFile: string;
|
|
11
12
|
verdictFile: string;
|
|
12
|
-
retryFile: string;
|
|
13
13
|
maxRetries?: number;
|
|
14
14
|
}
|
|
15
15
|
export interface VerifyGateResult {
|
|
16
16
|
action: "allow" | "block";
|
|
17
17
|
message?: string;
|
|
18
18
|
}
|
|
19
|
-
export declare function runVerifyGate(input: VerifyGateInput): VerifyGateResult
|
|
19
|
+
export declare function runVerifyGate(input: VerifyGateInput): Promise<VerifyGateResult>;
|
|
20
20
|
//# sourceMappingURL=verify-gate.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"verify-gate.d.ts","sourceRoot":"","sources":["../../../src/hooks/core/verify-gate.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;
|
|
1
|
+
{"version":3,"file":"verify-gate.d.ts","sourceRoot":"","sources":["../../../src/hooks/core/verify-gate.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAcH,MAAM,WAAW,eAAe;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAgB;IAC7B,MAAM,EAAE,OAAO,GAAG,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAgED,wBAAsB,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAsLrF"}
|
|
@@ -9,9 +9,10 @@
|
|
|
9
9
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
10
|
exports.runVerifyGate = runVerifyGate;
|
|
11
11
|
const fs_1 = require("fs");
|
|
12
|
-
const path_1 = require("path");
|
|
13
12
|
const logger_1 = require("../../lib/logger");
|
|
13
|
+
const telemetry_1 = require("../../lib/telemetry");
|
|
14
14
|
const actions_1 = require("./actions");
|
|
15
|
+
const session_state_1 = require("./session-state");
|
|
15
16
|
const DEFAULT_MAX_RETRIES = 3;
|
|
16
17
|
function verdictExamplePass(sessionId) {
|
|
17
18
|
return JSON.stringify({
|
|
@@ -35,11 +36,12 @@ function verdictExampleFail(sessionId) {
|
|
|
35
36
|
});
|
|
36
37
|
}
|
|
37
38
|
const MCP_SERVER = "browser-devtools";
|
|
39
|
+
const TOOL_PREFIX = "bdt_";
|
|
38
40
|
const REQUIRED_TOOLS = [
|
|
39
|
-
{ toolName: `mcp__${MCP_SERVER}
|
|
40
|
-
{ toolName: `mcp__${MCP_SERVER}
|
|
41
|
-
{ toolName: `mcp__${MCP_SERVER}
|
|
42
|
-
{ toolName: `mcp__${MCP_SERVER}
|
|
41
|
+
{ toolName: `mcp__${MCP_SERVER}__${TOOL_PREFIX}navigation_go-to`, name: `mcp__${MCP_SERVER}__${TOOL_PREFIX}navigation_go-to`, purpose: "navigate to a page" },
|
|
42
|
+
{ toolName: `mcp__${MCP_SERVER}__${TOOL_PREFIX}content_take-screenshot`, name: `mcp__${MCP_SERVER}__${TOOL_PREFIX}content_take-screenshot`, purpose: "take a screenshot" },
|
|
43
|
+
{ toolName: `mcp__${MCP_SERVER}__${TOOL_PREFIX}a11y_take-aria-snapshot`, name: `mcp__${MCP_SERVER}__${TOOL_PREFIX}a11y_take-aria-snapshot`, purpose: "check accessibility/page structure" },
|
|
44
|
+
{ toolName: `mcp__${MCP_SERVER}__${TOOL_PREFIX}o11y_get-console-messages`, name: `mcp__${MCP_SERVER}__${TOOL_PREFIX}o11y_get-console-messages`, purpose: "check console for errors" },
|
|
43
45
|
];
|
|
44
46
|
function cleanup(...files) {
|
|
45
47
|
for (const f of files) {
|
|
@@ -53,19 +55,19 @@ function cleanup(...files) {
|
|
|
53
55
|
}
|
|
54
56
|
}
|
|
55
57
|
}
|
|
56
|
-
function runVerifyGate(input) {
|
|
57
|
-
const { sessionId: sid, actionsFile, verdictFile,
|
|
58
|
+
async function runVerifyGate(input) {
|
|
59
|
+
const { sessionId: sid, sessionDir, actionsFile, verdictFile, maxRetries: inputMaxRetries } = input;
|
|
58
60
|
const maxRetries = inputMaxRetries ?? DEFAULT_MAX_RETRIES;
|
|
59
61
|
logger_1.logger.debug(`verify-gate: session=${sid} verdictExists=${(0, fs_1.existsSync)(verdictFile)}`);
|
|
60
62
|
// ── Check 1: Were code files edited? ───────────────────
|
|
61
63
|
const hasEdit = (0, actions_1.hasFileEditsSinceLastVerification)(actionsFile);
|
|
62
64
|
if (!hasEdit) {
|
|
63
65
|
logger_1.logger.debug("no code edits detected, allowing completion");
|
|
64
|
-
recordMarker(actionsFile, "allow", "no_edits");
|
|
66
|
+
await recordMarker(actionsFile, sid, "allow", "no_edits");
|
|
65
67
|
return { action: "allow" };
|
|
66
68
|
}
|
|
67
|
-
// ── Check 2: Were required IronBee tools used?
|
|
68
|
-
const toolCalls = (0, actions_1.
|
|
69
|
+
// ── Check 2: Were required IronBee tools used AFTER the latest code edit? ─
|
|
70
|
+
const toolCalls = (0, actions_1.getToolCallsSinceLastFileEdit)(actionsFile);
|
|
69
71
|
const usedToolNames = new Set(toolCalls.map((t) => t.tool_name));
|
|
70
72
|
const missingTools = REQUIRED_TOOLS.filter((t) => !usedToolNames.has(t.toolName));
|
|
71
73
|
logger_1.logger.debug(`verify-gate: missingTools=${missingTools.length}/${REQUIRED_TOOLS.length} usedTools=${[...usedToolNames].join(",")}`);
|
|
@@ -98,7 +100,7 @@ You made code changes but did not verify them through the browser.
|
|
|
98
100
|
}
|
|
99
101
|
if (missingTools.length > 0) {
|
|
100
102
|
const missing = missingTools.map((t) => ` - ${t.name} (${t.purpose})`).join("\n");
|
|
101
|
-
recordMarker(actionsFile, "block", "incomplete_tools");
|
|
103
|
+
await recordMarker(actionsFile, sid, "block", "incomplete_tools");
|
|
102
104
|
return {
|
|
103
105
|
action: "block",
|
|
104
106
|
message: `INCOMPLETE VERIFICATION.
|
|
@@ -112,7 +114,7 @@ Run the missing tools, functionally test your changes, then submit your verdict:
|
|
|
112
114
|
}
|
|
113
115
|
// ── Check 3: Verdict file exists? ──────────────────────
|
|
114
116
|
if (!(0, fs_1.existsSync)(verdictFile)) {
|
|
115
|
-
recordMarker(actionsFile, "block", "no_verdict");
|
|
117
|
+
await recordMarker(actionsFile, sid, "block", "no_verdict");
|
|
116
118
|
return {
|
|
117
119
|
action: "block",
|
|
118
120
|
message: `VERDICT MISSING.
|
|
@@ -130,7 +132,7 @@ Submit your verdict:
|
|
|
130
132
|
catch (e) {
|
|
131
133
|
logger_1.logger.debug(`failed to parse verdict ${verdictFile}: ${e}`);
|
|
132
134
|
cleanup(verdictFile);
|
|
133
|
-
recordMarker(actionsFile, "block", "invalid_verdict");
|
|
135
|
+
await recordMarker(actionsFile, sid, "block", "invalid_verdict");
|
|
134
136
|
return {
|
|
135
137
|
action: "block",
|
|
136
138
|
message: `INVALID VERDICT. Submit valid JSON:
|
|
@@ -142,7 +144,7 @@ Submit your verdict:
|
|
|
142
144
|
const checks = verdict.checks;
|
|
143
145
|
if (!Array.isArray(pages) || pages.length === 0) {
|
|
144
146
|
cleanup(verdictFile);
|
|
145
|
-
recordMarker(actionsFile, "block", "invalid_verdict");
|
|
147
|
+
await recordMarker(actionsFile, sid, "block", "invalid_verdict");
|
|
146
148
|
return {
|
|
147
149
|
action: "block",
|
|
148
150
|
message: `VERDICT REJECTED: missing pages_tested.
|
|
@@ -153,7 +155,7 @@ Your verdict must include which pages you tested.
|
|
|
153
155
|
}
|
|
154
156
|
if (!Array.isArray(checks) || checks.length === 0) {
|
|
155
157
|
cleanup(verdictFile);
|
|
156
|
-
recordMarker(actionsFile, "block", "invalid_verdict");
|
|
158
|
+
await recordMarker(actionsFile, sid, "block", "invalid_verdict");
|
|
157
159
|
return {
|
|
158
160
|
action: "block",
|
|
159
161
|
message: `VERDICT REJECTED: missing checks.
|
|
@@ -164,7 +166,7 @@ Your verdict must describe what you functionally tested.
|
|
|
164
166
|
}
|
|
165
167
|
if (typeof verdict.console_errors !== "number" || typeof verdict.network_failures !== "number") {
|
|
166
168
|
cleanup(verdictFile);
|
|
167
|
-
recordMarker(actionsFile, "block", "invalid_verdict");
|
|
169
|
+
await recordMarker(actionsFile, sid, "block", "invalid_verdict");
|
|
168
170
|
return {
|
|
169
171
|
action: "block",
|
|
170
172
|
message: `VERDICT REJECTED: missing console_errors or network_failures count.
|
|
@@ -176,25 +178,17 @@ Your verdict must include error counts.
|
|
|
176
178
|
// ── Check 6: Pass or fail? ─────────────────────────────
|
|
177
179
|
if (verdict.status === "pass") {
|
|
178
180
|
logger_1.logger.debug("verdict passed, allowing completion");
|
|
179
|
-
|
|
180
|
-
recordMarker(actionsFile, "allow", "verdict_pass");
|
|
181
|
+
(0, session_state_1.resetRetries)(sessionDir);
|
|
182
|
+
await recordMarker(actionsFile, sid, "allow", "verdict_pass");
|
|
181
183
|
return { action: "allow" };
|
|
182
184
|
}
|
|
183
185
|
if (verdict.status === "fail") {
|
|
184
|
-
|
|
185
|
-
try {
|
|
186
|
-
retries = parseInt((0, fs_1.readFileSync)(retryFile, "utf-8"), 10) || 0;
|
|
187
|
-
}
|
|
188
|
-
catch (e) {
|
|
189
|
-
logger_1.logger.debug(`failed to read retry file ${retryFile}: ${e}`);
|
|
190
|
-
}
|
|
191
|
-
retries++;
|
|
192
|
-
(0, fs_1.mkdirSync)((0, path_1.dirname)(retryFile), { recursive: true });
|
|
193
|
-
(0, fs_1.writeFileSync)(retryFile, String(retries));
|
|
186
|
+
const retries = (0, session_state_1.incrementRetries)(sessionDir);
|
|
194
187
|
const issues = (verdict.issues ?? ["unknown"]).join("\n - ");
|
|
195
188
|
if (retries >= maxRetries) {
|
|
196
|
-
cleanup(verdictFile
|
|
197
|
-
|
|
189
|
+
cleanup(verdictFile);
|
|
190
|
+
(0, session_state_1.resetRetries)(sessionDir);
|
|
191
|
+
await recordMarker(actionsFile, sid, "allow", "max_retries_exceeded");
|
|
198
192
|
return {
|
|
199
193
|
action: "allow",
|
|
200
194
|
message: `VERIFICATION FAILED ${maxRetries} TIMES. Allowing completion.
|
|
@@ -206,7 +200,7 @@ Report these issues in your final response.`,
|
|
|
206
200
|
};
|
|
207
201
|
}
|
|
208
202
|
cleanup(verdictFile);
|
|
209
|
-
recordMarker(actionsFile, "block", "verdict_fail");
|
|
203
|
+
await recordMarker(actionsFile, sid, "block", "verdict_fail");
|
|
210
204
|
return {
|
|
211
205
|
action: "block",
|
|
212
206
|
message: `VERIFICATION FAILED (attempt ${retries}/${maxRetries}).
|
|
@@ -220,14 +214,14 @@ Submit verdict: echo '<verdict-json>' | ironbee hook submit-verdict`,
|
|
|
220
214
|
}
|
|
221
215
|
// ── Unknown status ─────────────────────────────────────
|
|
222
216
|
cleanup(verdictFile);
|
|
223
|
-
recordMarker(actionsFile, "block", "invalid_verdict");
|
|
217
|
+
await recordMarker(actionsFile, sid, "block", "invalid_verdict");
|
|
224
218
|
return {
|
|
225
219
|
action: "block",
|
|
226
220
|
message: `INVALID VERDICT STATUS: "${verdict.status}". Status must be "pass" or "fail".
|
|
227
221
|
echo '${verdictExamplePass(sid)}' | ironbee hook submit-verdict`,
|
|
228
222
|
};
|
|
229
223
|
}
|
|
230
|
-
function recordMarker(actionsFile, action, reason) {
|
|
224
|
+
async function recordMarker(actionsFile, sessionId, action, reason) {
|
|
231
225
|
const marker = {
|
|
232
226
|
type: "verification_requested",
|
|
233
227
|
timestamp: new Date().toISOString(),
|
|
@@ -235,5 +229,6 @@ function recordMarker(actionsFile, action, reason) {
|
|
|
235
229
|
reason,
|
|
236
230
|
};
|
|
237
231
|
(0, actions_1.appendAction)(actionsFile, marker);
|
|
232
|
+
await (0, telemetry_1.trackVerificationRequested)(sessionId, action, reason);
|
|
238
233
|
}
|
|
239
234
|
//# sourceMappingURL=verify-gate.js.map
|