@ironbee-ai/cli 0.1.1 → 0.2.1
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 +4 -0
- package/README.md +38 -9
- package/dist/assets/banner.txt +9 -6
- package/dist/clients/base.d.ts +3 -1
- package/dist/clients/base.d.ts.map +1 -1
- package/dist/clients/claude/hooks/clear-verdict.d.ts.map +1 -1
- package/dist/clients/claude/hooks/clear-verdict.js +2 -1
- package/dist/clients/claude/hooks/clear-verdict.js.map +1 -1
- package/dist/clients/claude/hooks/require-verdict.d.ts +13 -0
- package/dist/clients/claude/hooks/require-verdict.d.ts.map +1 -0
- package/dist/clients/claude/hooks/require-verdict.js +42 -0
- package/dist/clients/claude/hooks/require-verdict.js.map +1 -0
- package/dist/clients/claude/hooks/session-start.d.ts +4 -3
- package/dist/clients/claude/hooks/session-start.d.ts.map +1 -1
- package/dist/clients/claude/hooks/session-start.js +22 -18
- package/dist/clients/claude/hooks/session-start.js.map +1 -1
- package/dist/clients/claude/index.d.ts +2 -1
- package/dist/clients/claude/index.d.ts.map +1 -1
- package/dist/clients/claude/index.js +46 -24
- package/dist/clients/claude/index.js.map +1 -1
- package/dist/clients/claude/rule.md +10 -8
- package/dist/clients/claude/skill.md +32 -9
- package/dist/clients/cursor/hooks/clear-verdict.d.ts +11 -0
- package/dist/clients/cursor/hooks/clear-verdict.d.ts.map +1 -0
- package/dist/clients/cursor/hooks/clear-verdict.js +57 -0
- package/dist/clients/cursor/hooks/clear-verdict.js.map +1 -0
- package/dist/clients/cursor/hooks/require-verdict.d.ts +12 -0
- package/dist/clients/cursor/hooks/require-verdict.d.ts.map +1 -0
- package/dist/clients/cursor/hooks/require-verdict.js +48 -0
- package/dist/clients/cursor/hooks/require-verdict.js.map +1 -0
- package/dist/clients/cursor/hooks/session-start.d.ts +9 -0
- package/dist/clients/cursor/hooks/session-start.d.ts.map +1 -0
- package/dist/clients/cursor/hooks/session-start.js +75 -0
- package/dist/clients/cursor/hooks/session-start.js.map +1 -0
- package/dist/clients/cursor/hooks/track-action.d.ts +16 -0
- package/dist/clients/cursor/hooks/track-action.d.ts.map +1 -0
- package/dist/clients/cursor/hooks/track-action.js +92 -0
- package/dist/clients/cursor/hooks/track-action.js.map +1 -0
- package/dist/clients/cursor/hooks/verify-gate.d.ts +13 -0
- package/dist/clients/cursor/hooks/verify-gate.d.ts.map +1 -0
- package/dist/clients/cursor/hooks/verify-gate.js +49 -0
- package/dist/clients/cursor/hooks/verify-gate.js.map +1 -0
- package/dist/clients/cursor/index.d.ts +20 -0
- package/dist/clients/cursor/index.d.ts.map +1 -0
- package/dist/clients/cursor/index.js +213 -0
- package/dist/clients/cursor/index.js.map +1 -0
- package/dist/clients/cursor/rule.md +42 -0
- package/dist/clients/cursor/skill.md +86 -0
- package/dist/clients/registry.d.ts.map +1 -1
- package/dist/clients/registry.js +2 -1
- package/dist/clients/registry.js.map +1 -1
- package/dist/commands/hook.d.ts.map +1 -1
- package/dist/commands/hook.js +61 -0
- package/dist/commands/hook.js.map +1 -1
- package/dist/commands/install.d.ts.map +1 -1
- package/dist/commands/install.js +1 -13
- package/dist/commands/install.js.map +1 -1
- package/dist/commands/status.js +3 -3
- package/dist/commands/verify.js +3 -3
- package/dist/hooks/core/actions.d.ts +7 -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/submit-verdict.d.ts +21 -0
- package/dist/hooks/core/submit-verdict.d.ts.map +1 -0
- package/dist/hooks/core/submit-verdict.js +109 -0
- package/dist/hooks/core/submit-verdict.js.map +1 -0
- package/dist/hooks/core/verify-gate.d.ts.map +1 -1
- package/dist/hooks/core/verify-gate.js +66 -49
- package/dist/hooks/core/verify-gate.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/lib/icon.js +1 -1
- package/dist/lib/icon.js.map +1 -1
- package/package.json +12 -4
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
You MUST verify all code changes in the browser before completing any task.
|
|
1
|
+
You MUST verify all code changes in the browser before completing any task. After every verification attempt, you MUST submit a verdict (pass or fail) via `ironbee hook submit-verdict` before doing anything else. If verification fails, submit the fail verdict first, then fix.
|
|
2
2
|
|
|
3
3
|
Verification is NOT just visual — you must functionally test the changes by interacting with the application through the browser-devtools MCP server. Click buttons, fill forms, trigger the flows you changed, and confirm things actually work end-to-end.
|
|
4
4
|
|
|
@@ -16,20 +16,22 @@ Required verification steps:
|
|
|
16
16
|
5. Check accessibility with `mcp__browser-devtools__a11y_take-aria-snapshot`
|
|
17
17
|
6. Check console for errors with `mcp__browser-devtools__o11y_get-console-messages`
|
|
18
18
|
7. Stop the dev server when done
|
|
19
|
-
8.
|
|
19
|
+
8. **IMMEDIATELY submit your verdict** — do NOT edit any code before submitting: `echo '<verdict-json>' | ironbee hook submit-verdict`
|
|
20
|
+
- Pass → submit pass verdict
|
|
21
|
+
- Fail → submit fail verdict with issues, THEN fix the code and re-verify
|
|
20
22
|
|
|
21
23
|
Steps 2, 4, 5, and 6 are enforced by the Stop hook. Step 3 is expected — do not just take a screenshot and call it done.
|
|
22
24
|
|
|
23
|
-
The SessionStart hook outputs your
|
|
25
|
+
The SessionStart hook outputs your session ID at the beginning of your session. After EVERY verification attempt, you MUST submit a verdict before doing anything else — even if it failed. Do not skip to fixing code. The submit-verdict command validates and records the verdict.
|
|
24
26
|
|
|
25
|
-
If verification fails
|
|
27
|
+
If verification fails: submit fail verdict → fix the code → re-verify → submit again.
|
|
26
28
|
|
|
27
29
|
Every code edit (Write/Edit) automatically clears your verdict, requiring re-verification.
|
|
28
30
|
|
|
29
31
|
## BANNED
|
|
30
32
|
|
|
31
|
-
- Writing
|
|
32
|
-
-
|
|
33
|
-
-
|
|
33
|
+
- Writing verdict.json directly — always use `ironbee hook submit-verdict`
|
|
34
|
+
- Skipping the fail verdict — always submit fail before fixing, so issues are tracked
|
|
35
|
+
- Submitting a verdict without actually performing browser verification
|
|
36
|
+
- Submitting a verdict based on assumptions, code reading, or prior knowledge
|
|
34
37
|
- Copying example verdicts from hook messages without doing real verification first
|
|
35
|
-
- Using Bash echo to write verdict files — always use the Write tool
|
|
@@ -4,13 +4,14 @@ description: >
|
|
|
4
4
|
MANDATORY browser verification after code changes. Activates when: implementing features,
|
|
5
5
|
fixing bugs, modifying UI components, changing API endpoints, updating styles, refactoring code,
|
|
6
6
|
or completing ANY task that changes application behavior. After writing or editing code files,
|
|
7
|
-
you MUST verify changes through the browser-devtools MCP server
|
|
7
|
+
you MUST verify changes through the browser-devtools MCP server and submit a verdict (pass or fail)
|
|
8
|
+
before reporting task completion. If verification fails, submit the fail verdict before fixing.
|
|
8
9
|
---
|
|
9
10
|
|
|
10
11
|
# IronBee Browser Verification
|
|
11
12
|
|
|
12
13
|
## Rule
|
|
13
|
-
No task is complete until changes are verified in the browser — visually AND functionally.
|
|
14
|
+
No task is complete until changes are verified in the browser — visually AND functionally. After verification, you MUST submit a verdict (pass or fail) before doing anything else. If verification fails, submit the fail verdict first, then fix.
|
|
14
15
|
|
|
15
16
|
## MCP Server
|
|
16
17
|
Verification is performed using the **browser-devtools** MCP server (`browser-devtools-mcp` package).
|
|
@@ -35,8 +36,11 @@ If the application is already running, skip the start step. If the build fails,
|
|
|
35
36
|
- **Console**: `mcp__browser-devtools__o11y_get-console-messages` — check for errors
|
|
36
37
|
Navigate, Screenshot, Accessibility, and Console tools are MANDATORY (the Stop hook checks the transcript for each one). Functional interaction is expected for every verification.
|
|
37
38
|
4. **Stop** the dev server when verification is complete
|
|
38
|
-
5.
|
|
39
|
-
|
|
39
|
+
5. **IMMEDIATELY submit your verdict** — do NOT edit any code before submitting: `echo '<verdict-json>' | ironbee hook submit-verdict`
|
|
40
|
+
- If everything works → submit pass verdict
|
|
41
|
+
- If something is broken → submit fail verdict with issues describing what failed
|
|
42
|
+
- **Never skip this step.** Every verification attempt must be recorded, pass or fail.
|
|
43
|
+
6. If you submitted a fail verdict → fix the code → rebuild → go back to step 2 → submit again → repeat until pass
|
|
40
44
|
|
|
41
45
|
## What good verification looks like
|
|
42
46
|
- Changed a form handler? → Start the app, fill the form, submit it, verify the response
|
|
@@ -46,9 +50,10 @@ If the application is already running, skip the start step. If the build fails,
|
|
|
46
50
|
- Changed styling? → Take a screenshot AND interact to ensure layout didn't break functionality
|
|
47
51
|
|
|
48
52
|
## How it works
|
|
49
|
-
- At session start, the SessionStart hook outputs your
|
|
50
|
-
- After verification,
|
|
51
|
-
-
|
|
53
|
+
- At session start, the SessionStart hook outputs your session ID
|
|
54
|
+
- After verification, submit your verdict: `echo '<verdict-json>' | ironbee hook submit-verdict`
|
|
55
|
+
- The submit-verdict command validates your verdict and records it
|
|
56
|
+
- When you stop, the Stop hook checks that browser tools were used AND a valid verdict exists
|
|
52
57
|
- If something is missing, the hook blocks you and gives you instructions
|
|
53
58
|
|
|
54
59
|
## Agent Teams
|
|
@@ -56,8 +61,26 @@ If the application is already running, skip the start step. If the build fails,
|
|
|
56
61
|
- The main orchestrator agent verifies ALL changes after subagents complete
|
|
57
62
|
- Each session's verification is isolated via session-specific verdict files
|
|
58
63
|
|
|
64
|
+
## Verdict format
|
|
65
|
+
|
|
66
|
+
On pass:
|
|
67
|
+
```json
|
|
68
|
+
{"session_id":"<your-session-id>","status":"pass","pages_tested":["http://localhost:3000/page"],"checks":["feature works"],"console_errors":0,"network_failures":0}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
On fail (issues is required):
|
|
72
|
+
```json
|
|
73
|
+
{"session_id":"<your-session-id>","status":"fail","pages_tested":["http://localhost:3000/page"],"checks":["feature broken"],"console_errors":1,"network_failures":0,"issues":["button click handler not firing"]}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
On pass after a previous fail (fixes is required):
|
|
77
|
+
```json
|
|
78
|
+
{"session_id":"<your-session-id>","status":"pass","pages_tested":["http://localhost:3000/page"],"checks":["feature works"],"console_errors":0,"network_failures":0,"fixes":["reattached click handler to submit button"]}
|
|
79
|
+
```
|
|
80
|
+
|
|
59
81
|
## Important
|
|
60
|
-
-
|
|
61
|
-
-
|
|
82
|
+
- **Always submit a verdict after every verification attempt** — both pass AND fail. Fail verdicts are tracked for analytics.
|
|
83
|
+
- The Stop hook checks BOTH that browser-devtools MCP tools were used AND a valid verdict exists
|
|
84
|
+
- Submit verdicts via `ironbee hook submit-verdict`, do NOT write verdict.json directly
|
|
62
85
|
- Every code edit (Write/Edit) automatically clears your session's verdict
|
|
63
86
|
- After 3 failed verification attempts, you may complete but must report issues
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor — clear-verdict hook adapter
|
|
3
|
+
*
|
|
4
|
+
* afterFileEdit hook — records file_edit and clears verdict
|
|
5
|
+
* when a code file is edited. Cursor provides file_path
|
|
6
|
+
* directly in the stdin payload.
|
|
7
|
+
*
|
|
8
|
+
* NOTE: afterFileEdit is fire-and-forget — output is ignored by Cursor.
|
|
9
|
+
*/
|
|
10
|
+
export declare function run(projectDir: string): void;
|
|
11
|
+
//# sourceMappingURL=clear-verdict.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clear-verdict.d.ts","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/clear-verdict.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAeH,wBAAgB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CA4C5C"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Cursor — clear-verdict hook adapter
|
|
4
|
+
*
|
|
5
|
+
* afterFileEdit hook — records file_edit and clears verdict
|
|
6
|
+
* when a code file is edited. Cursor provides file_path
|
|
7
|
+
* directly in the stdin payload.
|
|
8
|
+
*
|
|
9
|
+
* NOTE: afterFileEdit is fire-and-forget — output is ignored by Cursor.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.run = run;
|
|
13
|
+
const clear_verdict_1 = require("../../../hooks/core/clear-verdict");
|
|
14
|
+
const actions_1 = require("../../../hooks/core/actions");
|
|
15
|
+
const config_1 = require("../../../lib/config");
|
|
16
|
+
const logger_1 = require("../../../lib/logger");
|
|
17
|
+
const stdin_1 = require("../../../lib/stdin");
|
|
18
|
+
function run(projectDir) {
|
|
19
|
+
let input;
|
|
20
|
+
try {
|
|
21
|
+
input = JSON.parse((0, stdin_1.readStdin)());
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
logger_1.logger.debug(`failed to parse stdin: ${e}`);
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
const sessionId = input.conversation_id ?? "default";
|
|
28
|
+
(0, logger_1.setLogFile)(`${projectDir}/.ironbee/sessions/${sessionId}/session.log`);
|
|
29
|
+
const writtenFile = input.file_path;
|
|
30
|
+
// skip clear if the write target is the verdict file itself
|
|
31
|
+
if (writtenFile && writtenFile.includes(".ironbee/sessions/") && writtenFile.endsWith("verdict.json")) {
|
|
32
|
+
logger_1.logger.debug(`skipping clear-verdict: write target is verdict file ${writtenFile}`);
|
|
33
|
+
process.exit(0);
|
|
34
|
+
}
|
|
35
|
+
// skip if file does not require verification
|
|
36
|
+
if (writtenFile) {
|
|
37
|
+
const config = (0, config_1.loadConfig)(projectDir);
|
|
38
|
+
if (!(0, config_1.requiresVerification)(writtenFile, config)) {
|
|
39
|
+
logger_1.logger.debug(`skipping clear-verdict: file does not require verification (${writtenFile})`);
|
|
40
|
+
process.exit(0);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
// record file edit in actions.jsonl
|
|
44
|
+
const fileEditEntry = {
|
|
45
|
+
type: "file_edit",
|
|
46
|
+
timestamp: new Date().toISOString(),
|
|
47
|
+
tool_name: "file_edit",
|
|
48
|
+
file_path: writtenFile,
|
|
49
|
+
};
|
|
50
|
+
(0, actions_1.appendAction)(`${projectDir}/.ironbee/sessions/${sessionId}/actions.jsonl`, fileEditEntry);
|
|
51
|
+
(0, clear_verdict_1.runClearVerdict)({
|
|
52
|
+
verdictFile: `${projectDir}/.ironbee/sessions/${sessionId}/verdict.json`,
|
|
53
|
+
retryFile: `${projectDir}/.ironbee/sessions/${sessionId}/retries`,
|
|
54
|
+
});
|
|
55
|
+
process.exit(0);
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=clear-verdict.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clear-verdict.js","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/clear-verdict.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;AAeH,kBA4CC;AAzDD,qEAAoE;AACpE,yDAA2E;AAC3E,gDAAsF;AACtF,gDAAyD;AACzD,8CAA+C;AAS/C,SAAgB,GAAG,CAAC,UAAkB;IAClC,IAAI,KAA+B,CAAC;IACpC,IAAI,CAAC;QACD,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAS,GAAE,CAA6B,CAAC;IAChE,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QAClB,eAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,SAAS,GAAW,KAAK,CAAC,eAAe,IAAI,SAAS,CAAC;IAC7D,IAAA,mBAAU,EAAC,GAAG,UAAU,sBAAsB,SAAS,cAAc,CAAC,CAAC;IAEvE,MAAM,WAAW,GAAuB,KAAK,CAAC,SAAS,CAAC;IAExD,4DAA4D;IAC5D,IAAI,WAAW,IAAI,WAAW,CAAC,QAAQ,CAAC,oBAAoB,CAAC,IAAI,WAAW,CAAC,QAAQ,CAAC,cAAc,CAAC,EAAE,CAAC;QACpG,eAAM,CAAC,KAAK,CAAC,wDAAwD,WAAW,EAAE,CAAC,CAAC;QACpF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,6CAA6C;IAC7C,IAAI,WAAW,EAAE,CAAC;QACd,MAAM,MAAM,GAAkB,IAAA,mBAAU,EAAC,UAAU,CAAC,CAAC;QACrD,IAAI,CAAC,IAAA,6BAAoB,EAAC,WAAW,EAAE,MAAM,CAAC,EAAE,CAAC;YAC7C,eAAM,CAAC,KAAK,CAAC,+DAA+D,WAAW,GAAG,CAAC,CAAC;YAC5F,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,CAAC;IACL,CAAC;IAED,oCAAoC;IACpC,MAAM,aAAa,GAAmB;QAClC,IAAI,EAAE,WAAW;QACjB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,SAAS,EAAE,WAAW;QACtB,SAAS,EAAE,WAAW;KACzB,CAAC;IACF,IAAA,sBAAY,EAAC,GAAG,UAAU,sBAAsB,SAAS,gBAAgB,EAAE,aAAa,CAAC,CAAC;IAE1F,IAAA,+BAAe,EAAC;QACZ,WAAW,EAAE,GAAG,UAAU,sBAAsB,SAAS,eAAe;QACxE,SAAS,EAAE,GAAG,UAAU,sBAAsB,SAAS,UAAU;KACpE,CAAC,CAAC;IAEH,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor — require-verdict hook adapter
|
|
3
|
+
*
|
|
4
|
+
* preToolUse hook for Write — blocks file edits if the agent
|
|
5
|
+
* used browser-devtools tools but hasn't submitted a verdict yet.
|
|
6
|
+
* Forces the agent to submit a fail verdict before fixing code.
|
|
7
|
+
*
|
|
8
|
+
* Returns { permission: "deny", agent_message: "..." } to block,
|
|
9
|
+
* or { permission: "allow" } to proceed.
|
|
10
|
+
*/
|
|
11
|
+
export declare function run(projectDir: string): void;
|
|
12
|
+
//# sourceMappingURL=require-verdict.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"require-verdict.d.ts","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/require-verdict.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAkBH,wBAAgB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAiC5C"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Cursor — require-verdict hook adapter
|
|
4
|
+
*
|
|
5
|
+
* preToolUse hook for Write — blocks file edits if the agent
|
|
6
|
+
* used browser-devtools tools but hasn't submitted a verdict yet.
|
|
7
|
+
* Forces the agent to submit a fail verdict before fixing code.
|
|
8
|
+
*
|
|
9
|
+
* Returns { permission: "deny", agent_message: "..." } to block,
|
|
10
|
+
* or { permission: "allow" } to proceed.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.run = run;
|
|
14
|
+
const actions_1 = require("../../../hooks/core/actions");
|
|
15
|
+
const logger_1 = require("../../../lib/logger");
|
|
16
|
+
const stdin_1 = require("../../../lib/stdin");
|
|
17
|
+
function run(projectDir) {
|
|
18
|
+
let input;
|
|
19
|
+
try {
|
|
20
|
+
input = JSON.parse((0, stdin_1.readStdin)());
|
|
21
|
+
}
|
|
22
|
+
catch (e) {
|
|
23
|
+
logger_1.logger.debug(`failed to parse stdin: ${e}`);
|
|
24
|
+
const output = { permission: "allow" };
|
|
25
|
+
process.stdout.write(JSON.stringify(output));
|
|
26
|
+
process.exit(0);
|
|
27
|
+
}
|
|
28
|
+
const sessionId = input.conversation_id ?? "default";
|
|
29
|
+
(0, logger_1.setLogFile)(`${projectDir}/.ironbee/sessions/${sessionId}/session.log`);
|
|
30
|
+
const actionsFile = `${projectDir}/.ironbee/sessions/${sessionId}/actions.jsonl`;
|
|
31
|
+
if ((0, actions_1.hasToolCallsSinceLastVerdict)(actionsFile)) {
|
|
32
|
+
const output = {
|
|
33
|
+
permission: "deny",
|
|
34
|
+
agent_message: `BLOCKED: You used browser-devtools tools but did not submit a verdict. You MUST submit a verdict (pass or fail) before editing code.
|
|
35
|
+
|
|
36
|
+
Submit your verdict first:
|
|
37
|
+
echo '{"session_id":"${sessionId}","status":"fail","pages_tested":[...],"checks":[...],"console_errors":0,"network_failures":0,"issues":["describe what failed"]}' | ironbee hook submit-verdict
|
|
38
|
+
|
|
39
|
+
Then you can edit code to fix the issues.`,
|
|
40
|
+
};
|
|
41
|
+
process.stdout.write(JSON.stringify(output));
|
|
42
|
+
process.exit(2);
|
|
43
|
+
}
|
|
44
|
+
const output = { permission: "allow" };
|
|
45
|
+
process.stdout.write(JSON.stringify(output));
|
|
46
|
+
process.exit(0);
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=require-verdict.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"require-verdict.js","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/require-verdict.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;AAkBH,kBAiCC;AAjDD,yDAA2E;AAC3E,gDAAyD;AACzD,8CAA+C;AAc/C,SAAgB,GAAG,CAAC,UAAkB;IAClC,IAAI,KAA4B,CAAC;IACjC,IAAI,CAAC;QACD,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAS,GAAE,CAA0B,CAAC;IAC7D,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QAClB,eAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC;QAC5C,MAAM,MAAM,GAA2B,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;QAC/D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,SAAS,GAAW,KAAK,CAAC,eAAe,IAAI,SAAS,CAAC;IAC7D,IAAA,mBAAU,EAAC,GAAG,UAAU,sBAAsB,SAAS,cAAc,CAAC,CAAC;IAEvE,MAAM,WAAW,GAAW,GAAG,UAAU,sBAAsB,SAAS,gBAAgB,CAAC;IAEzF,IAAI,IAAA,sCAA4B,EAAC,WAAW,CAAC,EAAE,CAAC;QAC5C,MAAM,MAAM,GAA2B;YACnC,UAAU,EAAE,MAAM;YAClB,aAAa,EAAE;;;yBAGF,SAAS;;0CAEQ;SACjC,CAAC;QACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,MAAM,GAA2B,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC;IAC/D,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor — session-start hook adapter
|
|
3
|
+
*
|
|
4
|
+
* sessionStart hook — appends a session_start entry to actions.jsonl
|
|
5
|
+
* and outputs the session ID and submit-verdict instructions via
|
|
6
|
+
* additional_context (Cursor's field for injecting into agent context).
|
|
7
|
+
*/
|
|
8
|
+
export declare function run(projectDir: string): void;
|
|
9
|
+
//# sourceMappingURL=session-start.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-start.d.ts","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/session-start.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH,wBAAgB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAiE5C"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Cursor — session-start hook adapter
|
|
4
|
+
*
|
|
5
|
+
* sessionStart hook — appends a session_start entry to actions.jsonl
|
|
6
|
+
* and outputs the session ID and submit-verdict instructions via
|
|
7
|
+
* additional_context (Cursor's field for injecting into agent context).
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.run = run;
|
|
11
|
+
const actions_1 = require("../../../hooks/core/actions");
|
|
12
|
+
const logger_1 = require("../../../lib/logger");
|
|
13
|
+
const stdin_1 = require("../../../lib/stdin");
|
|
14
|
+
function run(projectDir) {
|
|
15
|
+
let input;
|
|
16
|
+
try {
|
|
17
|
+
input = JSON.parse((0, stdin_1.readStdin)());
|
|
18
|
+
}
|
|
19
|
+
catch (e) {
|
|
20
|
+
logger_1.logger.debug(`failed to parse stdin: ${e}`);
|
|
21
|
+
process.stdout.write(JSON.stringify({}));
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
const sessionId = input.conversation_id ?? "default";
|
|
25
|
+
const actionsFile = `${projectDir}/.ironbee/sessions/${sessionId}/actions.jsonl`;
|
|
26
|
+
(0, logger_1.setLogFile)(`${projectDir}/.ironbee/sessions/${sessionId}/session.log`);
|
|
27
|
+
const entry = {
|
|
28
|
+
type: "session_start",
|
|
29
|
+
timestamp: new Date().toISOString(),
|
|
30
|
+
session_id: sessionId,
|
|
31
|
+
source: "cursor",
|
|
32
|
+
};
|
|
33
|
+
(0, actions_1.appendAction)(actionsFile, entry);
|
|
34
|
+
logger_1.logger.debug(`session-start: ${sessionId}`);
|
|
35
|
+
const verdictPass = JSON.stringify({
|
|
36
|
+
session_id: sessionId,
|
|
37
|
+
status: "pass",
|
|
38
|
+
pages_tested: ["http://localhost:3000/affected-page"],
|
|
39
|
+
checks: ["form submits successfully", "new item appears in list"],
|
|
40
|
+
console_errors: 0,
|
|
41
|
+
network_failures: 0,
|
|
42
|
+
});
|
|
43
|
+
const verdictFail = JSON.stringify({
|
|
44
|
+
session_id: sessionId,
|
|
45
|
+
status: "fail",
|
|
46
|
+
pages_tested: ["http://localhost:3000/affected-page"],
|
|
47
|
+
checks: ["form renders", "submit button unresponsive"],
|
|
48
|
+
console_errors: 2,
|
|
49
|
+
network_failures: 0,
|
|
50
|
+
issues: ["button click handler not firing", "TypeError in console"],
|
|
51
|
+
});
|
|
52
|
+
const context = `IRONBEE VERIFICATION — SESSION ACTIVE
|
|
53
|
+
Session ID: ${sessionId}
|
|
54
|
+
|
|
55
|
+
You MUST verify all code changes in the browser before completing any task.
|
|
56
|
+
After EVERY verification attempt, you MUST submit a verdict BEFORE doing anything else.
|
|
57
|
+
- If pass → submit pass verdict
|
|
58
|
+
- If fail → submit fail verdict FIRST, then fix. Do NOT skip to fixing code without submitting.
|
|
59
|
+
|
|
60
|
+
Submit via terminal:
|
|
61
|
+
echo '${verdictPass}' | ironbee hook submit-verdict
|
|
62
|
+
|
|
63
|
+
On fail (issues is required):
|
|
64
|
+
echo '${verdictFail}' | ironbee hook submit-verdict
|
|
65
|
+
|
|
66
|
+
Required fields: session_id, status, pages_tested, checks, console_errors, network_failures
|
|
67
|
+
On fail, include: issues (array of strings describing what failed)
|
|
68
|
+
On pass after a previous fail, include: fixes (array of strings describing what was fixed)`;
|
|
69
|
+
const output = {
|
|
70
|
+
additional_context: context,
|
|
71
|
+
};
|
|
72
|
+
process.stdout.write(JSON.stringify(output));
|
|
73
|
+
process.exit(0);
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=session-start.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-start.js","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/session-start.ts"],"names":[],"mappings":";AAAA;;;;;;GAMG;;AAgBH,kBAiEC;AA/ED,yDAA+E;AAC/E,gDAAyD;AACzD,8CAA+C;AAY/C,SAAgB,GAAG,CAAC,UAAkB;IAClC,IAAI,KAA8B,CAAC;IACnC,IAAI,CAAC;QACD,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAS,GAAE,CAA4B,CAAC;IAC/D,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QAClB,eAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,SAAS,GAAW,KAAK,CAAC,eAAe,IAAI,SAAS,CAAC;IAC7D,MAAM,WAAW,GAAW,GAAG,UAAU,sBAAsB,SAAS,gBAAgB,CAAC;IACzF,IAAA,mBAAU,EAAC,GAAG,UAAU,sBAAsB,SAAS,cAAc,CAAC,CAAC;IAEvE,MAAM,KAAK,GAAuB;QAC9B,IAAI,EAAE,eAAe;QACrB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACnC,UAAU,EAAE,SAAS;QACrB,MAAM,EAAE,QAAQ;KACnB,CAAC;IAEF,IAAA,sBAAY,EAAC,WAAW,EAAE,KAAK,CAAC,CAAC;IACjC,eAAM,CAAC,KAAK,CAAC,kBAAkB,SAAS,EAAE,CAAC,CAAC;IAE5C,MAAM,WAAW,GAAW,IAAI,CAAC,SAAS,CAAC;QACvC,UAAU,EAAE,SAAS;QACrB,MAAM,EAAE,MAAM;QACd,YAAY,EAAE,CAAC,qCAAqC,CAAC;QACrD,MAAM,EAAE,CAAC,2BAA2B,EAAE,0BAA0B,CAAC;QACjE,cAAc,EAAE,CAAC;QACjB,gBAAgB,EAAE,CAAC;KACtB,CAAC,CAAC;IACH,MAAM,WAAW,GAAW,IAAI,CAAC,SAAS,CAAC;QACvC,UAAU,EAAE,SAAS;QACrB,MAAM,EAAE,MAAM;QACd,YAAY,EAAE,CAAC,qCAAqC,CAAC;QACrD,MAAM,EAAE,CAAC,cAAc,EAAE,4BAA4B,CAAC;QACtD,cAAc,EAAE,CAAC;QACjB,gBAAgB,EAAE,CAAC;QACnB,MAAM,EAAE,CAAC,iCAAiC,EAAE,sBAAsB,CAAC;KACtE,CAAC,CAAC;IAEH,MAAM,OAAO,GAAW;cACd,SAAS;;;;;;;;UAQb,WAAW;;;UAGX,WAAW;;;;2FAIsE,CAAC;IAExF,MAAM,MAAM,GAA6B;QACrC,kBAAkB,EAAE,OAAO;KAC9B,CAAC;IACF,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor — track-action hook adapter
|
|
3
|
+
*
|
|
4
|
+
* postToolUse hook for browser-devtools MCP tool calls.
|
|
5
|
+
* Filtered by matcher in hooks.json so only browser-devtools
|
|
6
|
+
* tools trigger this hook — no script-level filtering needed.
|
|
7
|
+
*
|
|
8
|
+
* Cursor's postToolUse uses `MCP:<tool_name>` format for tool_name.
|
|
9
|
+
* We normalize to `mcp__browser-devtools__<tool_name>` so that
|
|
10
|
+
* core verify-gate logic can match them consistently.
|
|
11
|
+
*
|
|
12
|
+
* Handles both direct tool calls and nested callTool() invocations
|
|
13
|
+
* inside the execute tool.
|
|
14
|
+
*/
|
|
15
|
+
export declare function run(projectDir: string): void;
|
|
16
|
+
//# sourceMappingURL=track-action.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"track-action.d.ts","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/track-action.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAmDH,wBAAgB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CA6C5C"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Cursor — track-action hook adapter
|
|
4
|
+
*
|
|
5
|
+
* postToolUse hook for browser-devtools MCP tool calls.
|
|
6
|
+
* Filtered by matcher in hooks.json so only browser-devtools
|
|
7
|
+
* tools trigger this hook — no script-level filtering needed.
|
|
8
|
+
*
|
|
9
|
+
* Cursor's postToolUse uses `MCP:<tool_name>` format for tool_name.
|
|
10
|
+
* We normalize to `mcp__browser-devtools__<tool_name>` so that
|
|
11
|
+
* core verify-gate logic can match them consistently.
|
|
12
|
+
*
|
|
13
|
+
* Handles both direct tool calls and nested callTool() invocations
|
|
14
|
+
* inside the execute tool.
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.run = run;
|
|
18
|
+
const actions_1 = require("../../../hooks/core/actions");
|
|
19
|
+
const logger_1 = require("../../../lib/logger");
|
|
20
|
+
const stdin_1 = require("../../../lib/stdin");
|
|
21
|
+
const CALL_TOOL_PATTERN = /callTool\(\s*['"]([^'"]+)['"]/g;
|
|
22
|
+
const MCP_PREFIX = "mcp__browser-devtools__";
|
|
23
|
+
const CURSOR_MCP_PREFIX = "MCP:";
|
|
24
|
+
const EXECUTE_TOOL = `${MCP_PREFIX}execute`;
|
|
25
|
+
/** Convert Cursor's MCP:<name> format to mcp__browser-devtools__<name>. */
|
|
26
|
+
function normalizeMcpToolName(cursorName) {
|
|
27
|
+
if (cursorName.startsWith(CURSOR_MCP_PREFIX)) {
|
|
28
|
+
return `${MCP_PREFIX}${cursorName.slice(CURSOR_MCP_PREFIX.length)}`;
|
|
29
|
+
}
|
|
30
|
+
if (cursorName.startsWith(MCP_PREFIX)) {
|
|
31
|
+
return cursorName;
|
|
32
|
+
}
|
|
33
|
+
return `${MCP_PREFIX}${cursorName}`;
|
|
34
|
+
}
|
|
35
|
+
function toFullName(shortName) {
|
|
36
|
+
return shortName.startsWith(MCP_PREFIX) ? shortName : `${MCP_PREFIX}${shortName}`;
|
|
37
|
+
}
|
|
38
|
+
function extractNestedToolNames(toolInput) {
|
|
39
|
+
const inputStr = typeof toolInput === "string"
|
|
40
|
+
? toolInput
|
|
41
|
+
: JSON.stringify(toolInput ?? "");
|
|
42
|
+
const names = new Set();
|
|
43
|
+
let match = CALL_TOOL_PATTERN.exec(inputStr);
|
|
44
|
+
while (match !== null) {
|
|
45
|
+
names.add(toFullName(match[1]));
|
|
46
|
+
match = CALL_TOOL_PATTERN.exec(inputStr);
|
|
47
|
+
}
|
|
48
|
+
return [...names];
|
|
49
|
+
}
|
|
50
|
+
function run(projectDir) {
|
|
51
|
+
let input;
|
|
52
|
+
try {
|
|
53
|
+
input = JSON.parse((0, stdin_1.readStdin)());
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
logger_1.logger.debug(`failed to parse stdin: ${e}`);
|
|
57
|
+
process.stdout.write(JSON.stringify({}));
|
|
58
|
+
process.exit(0);
|
|
59
|
+
}
|
|
60
|
+
const sessionId = input.conversation_id ?? "default";
|
|
61
|
+
const actionsFile = `${projectDir}/.ironbee/sessions/${sessionId}/actions.jsonl`;
|
|
62
|
+
(0, logger_1.setLogFile)(`${projectDir}/.ironbee/sessions/${sessionId}/session.log`);
|
|
63
|
+
const rawToolName = input.tool_name ?? "unknown";
|
|
64
|
+
const toolName = normalizeMcpToolName(rawToolName);
|
|
65
|
+
const timestamp = new Date().toISOString();
|
|
66
|
+
// record the direct tool call
|
|
67
|
+
const entry = {
|
|
68
|
+
type: "tool_call",
|
|
69
|
+
timestamp,
|
|
70
|
+
tool_name: toolName,
|
|
71
|
+
tool_input: input.tool_input,
|
|
72
|
+
tool_response: input.tool_output,
|
|
73
|
+
};
|
|
74
|
+
(0, actions_1.appendAction)(actionsFile, entry);
|
|
75
|
+
logger_1.logger.debug(`track-action: ${rawToolName} → ${toolName}`);
|
|
76
|
+
// for execute tool, extract and record nested callTool() invocations
|
|
77
|
+
if (toolName === EXECUTE_TOOL) {
|
|
78
|
+
const nested = extractNestedToolNames(input.tool_input);
|
|
79
|
+
for (const name of nested) {
|
|
80
|
+
const nestedEntry = {
|
|
81
|
+
type: "tool_call",
|
|
82
|
+
timestamp,
|
|
83
|
+
tool_name: name,
|
|
84
|
+
};
|
|
85
|
+
(0, actions_1.appendAction)(actionsFile, nestedEntry);
|
|
86
|
+
logger_1.logger.debug(`track-action (nested): ${name}`);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
process.stdout.write(JSON.stringify({}));
|
|
90
|
+
process.exit(0);
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=track-action.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"track-action.js","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/track-action.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cursor — verify-gate hook adapter
|
|
3
|
+
*
|
|
4
|
+
* stop hook — runs verification checks and outputs result.
|
|
5
|
+
* Uses `followup_message` to force the agent back into a new
|
|
6
|
+
* iteration when verification is missing or failed. Cursor's
|
|
7
|
+
* stop hook cannot return "permission": "deny", but
|
|
8
|
+
* followup_message auto-submits a new prompt to the agent,
|
|
9
|
+
* mechanically preventing completion until verification passes
|
|
10
|
+
* (up to Cursor's loop_limit, default 5).
|
|
11
|
+
*/
|
|
12
|
+
export declare function run(projectDir: string): void;
|
|
13
|
+
//# sourceMappingURL=verify-gate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-gate.d.ts","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/verify-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAmBH,wBAAgB,GAAG,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAkC5C"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Cursor — verify-gate hook adapter
|
|
4
|
+
*
|
|
5
|
+
* stop hook — runs verification checks and outputs result.
|
|
6
|
+
* Uses `followup_message` to force the agent back into a new
|
|
7
|
+
* iteration when verification is missing or failed. Cursor's
|
|
8
|
+
* stop hook cannot return "permission": "deny", but
|
|
9
|
+
* followup_message auto-submits a new prompt to the agent,
|
|
10
|
+
* mechanically preventing completion until verification passes
|
|
11
|
+
* (up to Cursor's loop_limit, default 5).
|
|
12
|
+
*/
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.run = run;
|
|
15
|
+
const verify_gate_1 = require("../../../hooks/core/verify-gate");
|
|
16
|
+
const config_1 = require("../../../lib/config");
|
|
17
|
+
const logger_1 = require("../../../lib/logger");
|
|
18
|
+
const stdin_1 = require("../../../lib/stdin");
|
|
19
|
+
function run(projectDir) {
|
|
20
|
+
let input;
|
|
21
|
+
try {
|
|
22
|
+
input = JSON.parse((0, stdin_1.readStdin)());
|
|
23
|
+
}
|
|
24
|
+
catch (e) {
|
|
25
|
+
logger_1.logger.debug(`failed to parse stdin: ${e}`);
|
|
26
|
+
process.stdout.write(JSON.stringify({}));
|
|
27
|
+
process.exit(0);
|
|
28
|
+
}
|
|
29
|
+
const sessionId = input.conversation_id ?? "default";
|
|
30
|
+
(0, logger_1.setLogFile)(`${projectDir}/.ironbee/sessions/${sessionId}/session.log`);
|
|
31
|
+
const config = (0, config_1.loadConfig)(projectDir);
|
|
32
|
+
const result = (0, verify_gate_1.runVerifyGate)({
|
|
33
|
+
sessionId,
|
|
34
|
+
actionsFile: `${projectDir}/.ironbee/sessions/${sessionId}/actions.jsonl`,
|
|
35
|
+
verdictFile: `${projectDir}/.ironbee/sessions/${sessionId}/verdict.json`,
|
|
36
|
+
retryFile: `${projectDir}/.ironbee/sessions/${sessionId}/retries`,
|
|
37
|
+
maxRetries: (0, config_1.getMaxRetries)(config),
|
|
38
|
+
});
|
|
39
|
+
const output = {};
|
|
40
|
+
// If verification blocks (action === "block"), send a followup_message
|
|
41
|
+
// to force the agent back into a new iteration. The agent cannot complete
|
|
42
|
+
// until it resolves the verification issue or loop_limit is reached.
|
|
43
|
+
if (result.action === "block" && result.message) {
|
|
44
|
+
output.followup_message = result.message;
|
|
45
|
+
}
|
|
46
|
+
process.stdout.write(JSON.stringify(output));
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=verify-gate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify-gate.js","sourceRoot":"","sources":["../../../../src/clients/cursor/hooks/verify-gate.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;AAmBH,kBAkCC;AAnDD,iEAAkF;AAClF,gDAA+E;AAC/E,gDAAyD;AACzD,8CAA+C;AAc/C,SAAgB,GAAG,CAAC,UAAkB;IAClC,IAAI,KAA0B,CAAC;IAC/B,IAAI,CAAC;QACD,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAS,GAAE,CAAwB,CAAC;IAC3D,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QAClB,eAAM,CAAC,KAAK,CAAC,0BAA0B,CAAC,EAAE,CAAC,CAAC;QAC5C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC;QACzC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IAED,MAAM,SAAS,GAAW,KAAK,CAAC,eAAe,IAAI,SAAS,CAAC;IAC7D,IAAA,mBAAU,EAAC,GAAG,UAAU,sBAAsB,SAAS,cAAc,CAAC,CAAC;IAEvE,MAAM,MAAM,GAAkB,IAAA,mBAAU,EAAC,UAAU,CAAC,CAAC;IAErD,MAAM,MAAM,GAAqB,IAAA,2BAAa,EAAC;QAC3C,SAAS;QACT,WAAW,EAAE,GAAG,UAAU,sBAAsB,SAAS,gBAAgB;QACzE,WAAW,EAAE,GAAG,UAAU,sBAAsB,SAAS,eAAe;QACxE,SAAS,EAAE,GAAG,UAAU,sBAAsB,SAAS,UAAU;QACjE,UAAU,EAAE,IAAA,sBAAa,EAAC,MAAM,CAAC;KACpC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAyB,EAAE,CAAC;IAExC,uEAAuE;IACvE,0EAA0E;IAC1E,qEAAqE;IACrE,IAAI,MAAM,CAAC,MAAM,KAAK,OAAO,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QAC9C,MAAM,CAAC,gBAAgB,GAAG,MAAM,CAAC,OAAO,CAAC;IAC7C,CAAC;IAED,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IAC7C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { IClient } from "../base";
|
|
2
|
+
export declare class CursorClient implements IClient {
|
|
3
|
+
readonly name: string;
|
|
4
|
+
detect(projectDir: string): boolean;
|
|
5
|
+
resolveProjectDir(): string;
|
|
6
|
+
install(projectDir: string): void;
|
|
7
|
+
uninstall(projectDir: string): void;
|
|
8
|
+
runVerifyGate(projectDir: string): void;
|
|
9
|
+
runClearVerdict(projectDir: string): void;
|
|
10
|
+
runTrackAction(projectDir: string): void;
|
|
11
|
+
runSessionStart(projectDir: string): void;
|
|
12
|
+
runRequireVerdict(projectDir: string): void;
|
|
13
|
+
private isIronBeeHook;
|
|
14
|
+
private mergeHooksConfig;
|
|
15
|
+
private removeIronBeeHooks;
|
|
16
|
+
private removeMcpServer;
|
|
17
|
+
private removeFile;
|
|
18
|
+
private writeMcpConfig;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/clients/cursor/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAwClC,qBAAa,YAAa,YAAW,OAAO;IACxC,SAAgB,IAAI,EAAE,MAAM,CAAY;IAEjC,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAInC,iBAAiB,IAAI,MAAM;IAI3B,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAiCjC,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAsBnC,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIvC,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIzC,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIxC,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIzC,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIlD,OAAO,CAAC,aAAa;IAIrB,OAAO,CAAC,gBAAgB;IAqExB,OAAO,CAAC,kBAAkB;IAuB1B,OAAO,CAAC,eAAe;IAgBvB,OAAO,CAAC,UAAU;IAMlB,OAAO,CAAC,cAAc;CAyBzB"}
|