@electric-agent/agent 1.4.3 → 1.4.6
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/dist/scaffold/index.js +3 -3
- package/package.json +3 -3
- package/dist/agents/clarifier.d.ts +0 -16
- package/dist/agents/clarifier.d.ts.map +0 -1
- package/dist/agents/clarifier.js +0 -158
- package/dist/agents/clarifier.js.map +0 -1
- package/dist/agents/coder.d.ts +0 -14
- package/dist/agents/coder.d.ts.map +0 -1
- package/dist/agents/coder.js +0 -126
- package/dist/agents/coder.js.map +0 -1
- package/dist/agents/planner.d.ts +0 -6
- package/dist/agents/planner.d.ts.map +0 -1
- package/dist/agents/planner.js +0 -69
- package/dist/agents/planner.js.map +0 -1
- package/dist/agents/prompts.d.ts +0 -9
- package/dist/agents/prompts.d.ts.map +0 -1
- package/dist/agents/prompts.js +0 -231
- package/dist/agents/prompts.js.map +0 -1
- package/dist/cli/headless.d.ts +0 -9
- package/dist/cli/headless.d.ts.map +0 -1
- package/dist/cli/headless.js +0 -506
- package/dist/cli/headless.js.map +0 -1
- package/dist/engine/message-parser.d.ts +0 -8
- package/dist/engine/message-parser.d.ts.map +0 -1
- package/dist/engine/message-parser.js +0 -106
- package/dist/engine/message-parser.js.map +0 -1
- package/dist/engine/orchestrator.d.ts +0 -50
- package/dist/engine/orchestrator.d.ts.map +0 -1
- package/dist/engine/orchestrator.js +0 -492
- package/dist/engine/orchestrator.js.map +0 -1
- package/dist/engine/stdio-adapter.d.ts +0 -24
- package/dist/engine/stdio-adapter.d.ts.map +0 -1
- package/dist/engine/stdio-adapter.js +0 -139
- package/dist/engine/stdio-adapter.js.map +0 -1
- package/dist/engine/stream-adapter.d.ts +0 -45
- package/dist/engine/stream-adapter.d.ts.map +0 -1
- package/dist/engine/stream-adapter.js +0 -154
- package/dist/engine/stream-adapter.js.map +0 -1
- package/dist/hooks/block-bash.d.ts +0 -7
- package/dist/hooks/block-bash.d.ts.map +0 -1
- package/dist/hooks/block-bash.js +0 -15
- package/dist/hooks/block-bash.js.map +0 -1
- package/dist/hooks/dependency-guard.d.ts +0 -7
- package/dist/hooks/dependency-guard.d.ts.map +0 -1
- package/dist/hooks/dependency-guard.js +0 -43
- package/dist/hooks/dependency-guard.js.map +0 -1
- package/dist/hooks/guardrail-inject.d.ts +0 -17
- package/dist/hooks/guardrail-inject.d.ts.map +0 -1
- package/dist/hooks/guardrail-inject.js +0 -69
- package/dist/hooks/guardrail-inject.js.map +0 -1
- package/dist/hooks/import-validation.d.ts +0 -7
- package/dist/hooks/import-validation.d.ts.map +0 -1
- package/dist/hooks/import-validation.js +0 -192
- package/dist/hooks/import-validation.js.map +0 -1
- package/dist/hooks/index.d.ts +0 -15
- package/dist/hooks/index.d.ts.map +0 -1
- package/dist/hooks/index.js +0 -42
- package/dist/hooks/index.js.map +0 -1
- package/dist/hooks/migration-validation.d.ts +0 -9
- package/dist/hooks/migration-validation.d.ts.map +0 -1
- package/dist/hooks/migration-validation.js +0 -62
- package/dist/hooks/migration-validation.js.map +0 -1
- package/dist/hooks/schema-consistency.d.ts +0 -12
- package/dist/hooks/schema-consistency.d.ts.map +0 -1
- package/dist/hooks/schema-consistency.js +0 -72
- package/dist/hooks/schema-consistency.js.map +0 -1
- package/dist/hooks/write-protection.d.ts +0 -7
- package/dist/hooks/write-protection.d.ts.map +0 -1
- package/dist/hooks/write-protection.js +0 -33
- package/dist/hooks/write-protection.js.map +0 -1
- package/dist/progress/reporter.d.ts +0 -15
- package/dist/progress/reporter.d.ts.map +0 -1
- package/dist/progress/reporter.js +0 -133
- package/dist/progress/reporter.js.map +0 -1
- package/dist/tools/build.d.ts +0 -3
- package/dist/tools/build.d.ts.map +0 -1
- package/dist/tools/build.js +0 -84
- package/dist/tools/build.js.map +0 -1
- package/dist/tools/playbook.d.ts +0 -14
- package/dist/tools/playbook.d.ts.map +0 -1
- package/dist/tools/playbook.js +0 -239
- package/dist/tools/playbook.js.map +0 -1
- package/dist/tools/server.d.ts +0 -3
- package/dist/tools/server.d.ts.map +0 -1
- package/dist/tools/server.js +0 -13
- package/dist/tools/server.js.map +0 -1
- package/dist/working-memory/errors.d.ts +0 -14
- package/dist/working-memory/errors.d.ts.map +0 -1
- package/dist/working-memory/errors.js +0 -89
- package/dist/working-memory/errors.js.map +0 -1
- package/dist/working-memory/session.d.ts +0 -12
- package/dist/working-memory/session.d.ts.map +0 -1
- package/dist/working-memory/session.js +0 -71
- package/dist/working-memory/session.js.map +0 -1
|
@@ -1,139 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Headless adapter that communicates via stdin/stdout NDJSON.
|
|
3
|
-
*
|
|
4
|
-
* Each line is a JSON object terminated by `\n`.
|
|
5
|
-
*
|
|
6
|
-
* Server → Agent (stdin):
|
|
7
|
-
* { type: "command", command: "new", description: "...", ... }
|
|
8
|
-
* { type: "gate_response", gate: "approval", decision: "approve" }
|
|
9
|
-
*
|
|
10
|
-
* Agent → Server (stdout):
|
|
11
|
-
* { type: "log", level: "task", message: "...", ts: "..." }
|
|
12
|
-
* { type: "session_end", success: true, ts: "..." }
|
|
13
|
-
*
|
|
14
|
-
* Stderr is used for non-protocol diagnostics only.
|
|
15
|
-
*/
|
|
16
|
-
import * as readline from "node:readline";
|
|
17
|
-
export function createStdioAdapter() {
|
|
18
|
-
// Pending gate response resolvers
|
|
19
|
-
const pendingGates = new Map();
|
|
20
|
-
// Buffered commands
|
|
21
|
-
const commandQueue = [];
|
|
22
|
-
let commandResolve = null;
|
|
23
|
-
// Config promise
|
|
24
|
-
let configResolve = null;
|
|
25
|
-
let gotConfig = false;
|
|
26
|
-
let closed = false;
|
|
27
|
-
const rl = readline.createInterface({
|
|
28
|
-
input: process.stdin,
|
|
29
|
-
terminal: false,
|
|
30
|
-
});
|
|
31
|
-
rl.on("line", (line) => {
|
|
32
|
-
if (closed)
|
|
33
|
-
return;
|
|
34
|
-
const trimmed = line.trim();
|
|
35
|
-
if (!trimmed)
|
|
36
|
-
return;
|
|
37
|
-
let msg;
|
|
38
|
-
try {
|
|
39
|
-
msg = JSON.parse(trimmed);
|
|
40
|
-
}
|
|
41
|
-
catch {
|
|
42
|
-
process.stderr.write(`[stdio-adapter] Invalid JSON: ${trimmed}\n`);
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
const type = msg.type;
|
|
46
|
-
if (type === "command" && !gotConfig) {
|
|
47
|
-
// First command is the initial config
|
|
48
|
-
gotConfig = true;
|
|
49
|
-
const { type: _, ...rest } = msg;
|
|
50
|
-
configResolve?.(rest);
|
|
51
|
-
return;
|
|
52
|
-
}
|
|
53
|
-
if (type === "command") {
|
|
54
|
-
const { type: _, ...rest } = msg;
|
|
55
|
-
if (commandResolve) {
|
|
56
|
-
const resolve = commandResolve;
|
|
57
|
-
commandResolve = null;
|
|
58
|
-
resolve(rest);
|
|
59
|
-
}
|
|
60
|
-
else {
|
|
61
|
-
commandQueue.push(rest);
|
|
62
|
-
}
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
if (type === "gate_response") {
|
|
66
|
-
const gate = msg.gate;
|
|
67
|
-
if (!gate)
|
|
68
|
-
return;
|
|
69
|
-
const entry = pendingGates.get(gate);
|
|
70
|
-
if (entry) {
|
|
71
|
-
pendingGates.delete(gate);
|
|
72
|
-
entry.resolve(msg);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
rl.on("close", () => {
|
|
77
|
-
closed = true;
|
|
78
|
-
});
|
|
79
|
-
function writeEvent(event) {
|
|
80
|
-
if (closed)
|
|
81
|
-
return;
|
|
82
|
-
process.stdout.write(`${JSON.stringify(event)}\n`);
|
|
83
|
-
}
|
|
84
|
-
function waitForGate(gateName) {
|
|
85
|
-
return new Promise((resolve) => {
|
|
86
|
-
pendingGates.set(gateName, {
|
|
87
|
-
resolve: resolve,
|
|
88
|
-
});
|
|
89
|
-
});
|
|
90
|
-
}
|
|
91
|
-
function readConfig() {
|
|
92
|
-
if (gotConfig) {
|
|
93
|
-
return Promise.reject(new Error("Config already read"));
|
|
94
|
-
}
|
|
95
|
-
return new Promise((resolve) => {
|
|
96
|
-
configResolve = resolve;
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
function waitForCommand() {
|
|
100
|
-
if (commandQueue.length > 0) {
|
|
101
|
-
return Promise.resolve(commandQueue.shift());
|
|
102
|
-
}
|
|
103
|
-
return new Promise((resolve) => {
|
|
104
|
-
commandResolve = (msg) => resolve(msg);
|
|
105
|
-
});
|
|
106
|
-
}
|
|
107
|
-
const callbacks = {
|
|
108
|
-
onEvent(event) {
|
|
109
|
-
writeEvent(event);
|
|
110
|
-
},
|
|
111
|
-
async onClarificationNeeded(_questions, _summary) {
|
|
112
|
-
const response = await waitForGate("clarification");
|
|
113
|
-
return response.answers;
|
|
114
|
-
},
|
|
115
|
-
async onPlanReady(_plan) {
|
|
116
|
-
const response = await waitForGate("approval");
|
|
117
|
-
return response.decision;
|
|
118
|
-
},
|
|
119
|
-
async onRevisionRequested() {
|
|
120
|
-
const response = await waitForGate("revision");
|
|
121
|
-
return response.feedback;
|
|
122
|
-
},
|
|
123
|
-
async onContinueNeeded() {
|
|
124
|
-
const response = await waitForGate("continue");
|
|
125
|
-
return response.proceed;
|
|
126
|
-
},
|
|
127
|
-
};
|
|
128
|
-
function close() {
|
|
129
|
-
closed = true;
|
|
130
|
-
rl.close();
|
|
131
|
-
}
|
|
132
|
-
return {
|
|
133
|
-
readConfig,
|
|
134
|
-
waitForCommand,
|
|
135
|
-
callbacks,
|
|
136
|
-
close,
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
//# sourceMappingURL=stdio-adapter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stdio-adapter.js","sourceRoot":"","sources":["../../src/engine/stdio-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAA;AAKzC,MAAM,UAAU,kBAAkB;IACjC,kCAAkC;IAClC,MAAM,YAAY,GAAG,IAAI,GAAG,EAAiD,CAAA;IAC7E,oBAAoB;IACpB,MAAM,YAAY,GAA8B,EAAE,CAAA;IAClD,IAAI,cAAc,GAAoD,IAAI,CAAA;IAE1E,iBAAiB;IACjB,IAAI,aAAa,GAA8C,IAAI,CAAA;IACnE,IAAI,SAAS,GAAG,KAAK,CAAA;IACrB,IAAI,MAAM,GAAG,KAAK,CAAA;IAElB,MAAM,EAAE,GAAG,QAAQ,CAAC,eAAe,CAAC;QACnC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,QAAQ,EAAE,KAAK;KACf,CAAC,CAAA;IAEF,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE;QACtB,IAAI,MAAM;YAAE,OAAM;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;QAC3B,IAAI,CAAC,OAAO;YAAE,OAAM;QAEpB,IAAI,GAA4B,CAAA;QAChC,IAAI,CAAC;YACJ,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAA4B,CAAA;QACrD,CAAC;QAAC,MAAM,CAAC;YACR,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,OAAO,IAAI,CAAC,CAAA;YAClE,OAAM;QACP,CAAC;QAED,MAAM,IAAI,GAAG,GAAG,CAAC,IAA0B,CAAA;QAE3C,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,SAAS,EAAE,CAAC;YACtC,sCAAsC;YACtC,SAAS,GAAG,IAAI,CAAA;YAChB,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,CAAA;YAChC,aAAa,EAAE,CAAC,IAAiC,CAAC,CAAA;YAClD,OAAM;QACP,CAAC;QAED,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACxB,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,CAAA;YAChC,IAAI,cAAc,EAAE,CAAC;gBACpB,MAAM,OAAO,GAAG,cAAc,CAAA;gBAC9B,cAAc,GAAG,IAAI,CAAA;gBACrB,OAAO,CAAC,IAAI,CAAC,CAAA;YACd,CAAC;iBAAM,CAAC;gBACP,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;YACxB,CAAC;YACD,OAAM;QACP,CAAC;QAED,IAAI,IAAI,KAAK,eAAe,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,GAAG,CAAC,IAAc,CAAA;YAC/B,IAAI,CAAC,IAAI;gBAAE,OAAM;YACjB,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;YACpC,IAAI,KAAK,EAAE,CAAC;gBACX,YAAY,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;gBACzB,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YACnB,CAAC;QACF,CAAC;IACF,CAAC,CAAC,CAAA;IAEF,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;QACnB,MAAM,GAAG,IAAI,CAAA;IACd,CAAC,CAAC,CAAA;IAEF,SAAS,UAAU,CAAC,KAAkB;QACrC,IAAI,MAAM;YAAE,OAAM;QAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACnD,CAAC;IAED,SAAS,WAAW,CAAI,QAAgB;QACvC,OAAO,IAAI,OAAO,CAAI,CAAC,OAAO,EAAE,EAAE;YACjC,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE;gBAC1B,OAAO,EAAE,OAAmC;aAC5C,CAAC,CAAA;QACH,CAAC,CAAC,CAAA;IACH,CAAC;IAED,SAAS,UAAU;QAClB,IAAI,SAAS,EAAE,CAAC;YACf,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAA;QACxD,CAAC;QACD,OAAO,IAAI,OAAO,CAAiB,CAAC,OAAO,EAAE,EAAE;YAC9C,aAAa,GAAG,OAAO,CAAA;QACxB,CAAC,CAAC,CAAA;IACH,CAAC;IAED,SAAS,cAAc;QACtB,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,EAA+B,CAAC,CAAA;QAC1E,CAAC;QACD,OAAO,IAAI,OAAO,CAAiB,CAAC,OAAO,EAAE,EAAE;YAC9C,cAAc,GAAG,CAAC,GAA4B,EAAE,EAAE,CAAC,OAAO,CAAC,GAAgC,CAAC,CAAA;QAC7F,CAAC,CAAC,CAAA;IACH,CAAC;IAED,MAAM,SAAS,GAA0B;QACxC,OAAO,CAAC,KAAkB;YACzB,UAAU,CAAC,KAAK,CAAC,CAAA;QAClB,CAAC;QAED,KAAK,CAAC,qBAAqB,CAAC,UAAU,EAAE,QAAQ;YAC/C,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAwB,eAAe,CAAC,CAAA;YAC1E,OAAO,QAAQ,CAAC,OAAO,CAAA;QACxB,CAAC;QAED,KAAK,CAAC,WAAW,CAAC,KAAK;YACtB,MAAM,QAAQ,GAAG,MAAM,WAAW,CAE/B,UAAU,CAAC,CAAA;YACd,OAAO,QAAQ,CAAC,QAAQ,CAAA;QACzB,CAAC;QAED,KAAK,CAAC,mBAAmB;YACxB,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAuB,UAAU,CAAC,CAAA;YACpE,OAAO,QAAQ,CAAC,QAAQ,CAAA;QACzB,CAAC;QAED,KAAK,CAAC,gBAAgB;YACrB,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAuB,UAAU,CAAC,CAAA;YACpE,OAAO,QAAQ,CAAC,OAAO,CAAA;QACxB,CAAC;KACD,CAAA;IAED,SAAS,KAAK;QACb,MAAM,GAAG,IAAI,CAAA;QACb,EAAE,CAAC,KAAK,EAAE,CAAA;IACX,CAAC;IAED,OAAO;QACN,UAAU;QACV,cAAc;QACd,SAAS;QACT,KAAK;KACL,CAAA;AACF,CAAC"}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Headless adapter that communicates via a hosted Durable Stream
|
|
3
|
-
* instead of stdin/stdout.
|
|
4
|
-
*
|
|
5
|
-
* The agent reads server messages (commands, gate responses) from the
|
|
6
|
-
* stream and writes agent events back, all tagged with a `source` field.
|
|
7
|
-
*
|
|
8
|
-
* Environment variables:
|
|
9
|
-
* DS_STREAM_URL — full stream endpoint URL
|
|
10
|
-
* DS_SECRET — Bearer token for auth
|
|
11
|
-
*/
|
|
12
|
-
import type { OrchestratorCallbacks } from "./orchestrator.js";
|
|
13
|
-
export interface HeadlessConfig {
|
|
14
|
-
command: "new" | "iterate" | "git";
|
|
15
|
-
description?: string;
|
|
16
|
-
projectName?: string;
|
|
17
|
-
baseDir?: string;
|
|
18
|
-
projectDir?: string;
|
|
19
|
-
request?: string;
|
|
20
|
-
resumeSessionId?: string;
|
|
21
|
-
initGit?: boolean;
|
|
22
|
-
gitOp?: "commit" | "push" | "create-repo" | "create-pr";
|
|
23
|
-
gitMessage?: string;
|
|
24
|
-
gitRepoName?: string;
|
|
25
|
-
gitRepoVisibility?: "public" | "private";
|
|
26
|
-
gitPrTitle?: string;
|
|
27
|
-
gitPrBody?: string;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Create a headless adapter that communicates via a hosted Durable Stream.
|
|
31
|
-
*
|
|
32
|
-
* Stream protocol:
|
|
33
|
-
* Server → Agent: { source: "server", type: "command", command: "new", ... }
|
|
34
|
-
* { source: "server", type: "gate_response", gate: "approval", ... }
|
|
35
|
-
* Agent → Server: { source: "agent", type: "pre_tool_use", ... }
|
|
36
|
-
* { source: "agent", type: "session_end", ... }
|
|
37
|
-
*/
|
|
38
|
-
export declare function createStreamAdapter(streamUrl: string, secret: string): {
|
|
39
|
-
startListening: () => Promise<void>;
|
|
40
|
-
readConfig: () => Promise<HeadlessConfig>;
|
|
41
|
-
waitForCommand: () => Promise<HeadlessConfig>;
|
|
42
|
-
callbacks: OrchestratorCallbacks;
|
|
43
|
-
close: () => void;
|
|
44
|
-
};
|
|
45
|
-
//# sourceMappingURL=stream-adapter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stream-adapter.d.ts","sourceRoot":"","sources":["../../src/engine/stream-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAA;AAE9D,MAAM,WAAW,cAAc;IAC9B,OAAO,EAAE,KAAK,GAAG,SAAS,GAAG,KAAK,CAAA;IAClC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,KAAK,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,aAAa,GAAG,WAAW,CAAA;IACvD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,iBAAiB,CAAC,EAAE,QAAQ,GAAG,SAAS,CAAA;IACxC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,MAAM,CAAA;CAClB;AAQD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;0BAyBnC,OAAO,CAAC,IAAI,CAAC;sBA+DvB,OAAO,CAAC,cAAc,CAAC;0BASnB,OAAO,CAAC,cAAc,CAAC;;iBAsChC,IAAI;EAetB"}
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Headless adapter that communicates via a hosted Durable Stream
|
|
3
|
-
* instead of stdin/stdout.
|
|
4
|
-
*
|
|
5
|
-
* The agent reads server messages (commands, gate responses) from the
|
|
6
|
-
* stream and writes agent events back, all tagged with a `source` field.
|
|
7
|
-
*
|
|
8
|
-
* Environment variables:
|
|
9
|
-
* DS_STREAM_URL — full stream endpoint URL
|
|
10
|
-
* DS_SECRET — Bearer token for auth
|
|
11
|
-
*/
|
|
12
|
-
import { DurableStream } from "@durable-streams/client";
|
|
13
|
-
/**
|
|
14
|
-
* Create a headless adapter that communicates via a hosted Durable Stream.
|
|
15
|
-
*
|
|
16
|
-
* Stream protocol:
|
|
17
|
-
* Server → Agent: { source: "server", type: "command", command: "new", ... }
|
|
18
|
-
* { source: "server", type: "gate_response", gate: "approval", ... }
|
|
19
|
-
* Agent → Server: { source: "agent", type: "pre_tool_use", ... }
|
|
20
|
-
* { source: "agent", type: "session_end", ... }
|
|
21
|
-
*/
|
|
22
|
-
export function createStreamAdapter(streamUrl, secret) {
|
|
23
|
-
const headers = {
|
|
24
|
-
Authorization: `Bearer ${secret}`,
|
|
25
|
-
};
|
|
26
|
-
const writer = new DurableStream({
|
|
27
|
-
url: streamUrl,
|
|
28
|
-
headers,
|
|
29
|
-
contentType: "application/json",
|
|
30
|
-
});
|
|
31
|
-
// Pending gate response resolvers
|
|
32
|
-
const pendingGates = new Map();
|
|
33
|
-
// Buffered commands
|
|
34
|
-
const commandQueue = [];
|
|
35
|
-
let commandResolve = null;
|
|
36
|
-
// Config promise
|
|
37
|
-
let configResolve = null;
|
|
38
|
-
let gotConfig = false;
|
|
39
|
-
let closed = false;
|
|
40
|
-
// Subscribe to the stream to receive server messages
|
|
41
|
-
let cancelSubscription = null;
|
|
42
|
-
async function startListening() {
|
|
43
|
-
const reader = new DurableStream({
|
|
44
|
-
url: streamUrl,
|
|
45
|
-
headers,
|
|
46
|
-
contentType: "application/json",
|
|
47
|
-
});
|
|
48
|
-
const response = await reader.stream({
|
|
49
|
-
offset: "-1",
|
|
50
|
-
live: true,
|
|
51
|
-
});
|
|
52
|
-
cancelSubscription = response.subscribeJson((batch) => {
|
|
53
|
-
for (const item of batch.items) {
|
|
54
|
-
if (item.source !== "server")
|
|
55
|
-
continue;
|
|
56
|
-
if (item.type === "command" && !gotConfig) {
|
|
57
|
-
// First command is the initial config
|
|
58
|
-
gotConfig = true;
|
|
59
|
-
const { source: _, type: _t, ...rest } = item;
|
|
60
|
-
configResolve?.(rest);
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
if (item.type === "command") {
|
|
64
|
-
const { source: _, type: _t, ...rest } = item;
|
|
65
|
-
if (commandResolve) {
|
|
66
|
-
const resolve = commandResolve;
|
|
67
|
-
commandResolve = null;
|
|
68
|
-
resolve(rest);
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
71
|
-
commandQueue.push(rest);
|
|
72
|
-
}
|
|
73
|
-
continue;
|
|
74
|
-
}
|
|
75
|
-
if (item.type === "gate_response") {
|
|
76
|
-
const gate = item.gate;
|
|
77
|
-
if (!gate)
|
|
78
|
-
continue;
|
|
79
|
-
const entry = pendingGates.get(gate);
|
|
80
|
-
if (entry) {
|
|
81
|
-
pendingGates.delete(gate);
|
|
82
|
-
entry.resolve(item);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
async function writeEvent(event) {
|
|
89
|
-
if (closed)
|
|
90
|
-
return;
|
|
91
|
-
const msg = { source: "agent", ...event };
|
|
92
|
-
await writer.append(JSON.stringify(msg));
|
|
93
|
-
}
|
|
94
|
-
function waitForGate(gateName) {
|
|
95
|
-
return new Promise((resolve) => {
|
|
96
|
-
pendingGates.set(gateName, {
|
|
97
|
-
resolve: resolve,
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
function readConfig() {
|
|
102
|
-
if (gotConfig) {
|
|
103
|
-
return Promise.reject(new Error("Config already read"));
|
|
104
|
-
}
|
|
105
|
-
return new Promise((resolve) => {
|
|
106
|
-
configResolve = resolve;
|
|
107
|
-
});
|
|
108
|
-
}
|
|
109
|
-
function waitForCommand() {
|
|
110
|
-
if (commandQueue.length > 0) {
|
|
111
|
-
return Promise.resolve(commandQueue.shift());
|
|
112
|
-
}
|
|
113
|
-
return new Promise((resolve) => {
|
|
114
|
-
commandResolve = (msg) => resolve(msg);
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
const callbacks = {
|
|
118
|
-
onEvent(event) {
|
|
119
|
-
// Fire-and-forget write to stream
|
|
120
|
-
writeEvent(event).catch(() => { });
|
|
121
|
-
},
|
|
122
|
-
async onClarificationNeeded(_questions, _summary) {
|
|
123
|
-
const response = await waitForGate("clarification");
|
|
124
|
-
return response.answers;
|
|
125
|
-
},
|
|
126
|
-
async onPlanReady(_plan) {
|
|
127
|
-
const response = await waitForGate("approval");
|
|
128
|
-
return response.decision;
|
|
129
|
-
},
|
|
130
|
-
async onRevisionRequested() {
|
|
131
|
-
const response = await waitForGate("revision");
|
|
132
|
-
return response.feedback;
|
|
133
|
-
},
|
|
134
|
-
async onContinueNeeded() {
|
|
135
|
-
const response = await waitForGate("continue");
|
|
136
|
-
return response.proceed;
|
|
137
|
-
},
|
|
138
|
-
};
|
|
139
|
-
function close() {
|
|
140
|
-
closed = true;
|
|
141
|
-
if (cancelSubscription) {
|
|
142
|
-
cancelSubscription();
|
|
143
|
-
cancelSubscription = null;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
return {
|
|
147
|
-
startListening,
|
|
148
|
-
readConfig,
|
|
149
|
-
waitForCommand,
|
|
150
|
-
callbacks,
|
|
151
|
-
close,
|
|
152
|
-
};
|
|
153
|
-
}
|
|
154
|
-
//# sourceMappingURL=stream-adapter.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"stream-adapter.js","sourceRoot":"","sources":["../../src/engine/stream-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { HookCallback } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
-
/**
|
|
3
|
-
* PreToolUse hook: Block all Bash tool usage.
|
|
4
|
-
* Used by the planner agent which should only read playbooks, not explore the filesystem.
|
|
5
|
-
*/
|
|
6
|
-
export declare const blockBash: HookCallback;
|
|
7
|
-
//# sourceMappingURL=block-bash.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"block-bash.d.ts","sourceRoot":"","sources":["../../src/hooks/block-bash.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAElE;;;GAGG;AACH,eAAO,MAAM,SAAS,EAAE,YAUvB,CAAA"}
|
package/dist/hooks/block-bash.js
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PreToolUse hook: Block all Bash tool usage.
|
|
3
|
-
* Used by the planner agent which should only read playbooks, not explore the filesystem.
|
|
4
|
-
*/
|
|
5
|
-
export const blockBash = async () => {
|
|
6
|
-
return {
|
|
7
|
-
suppressOutput: true,
|
|
8
|
-
hookSpecificOutput: {
|
|
9
|
-
hookEventName: "PreToolUse",
|
|
10
|
-
permissionDecision: "deny",
|
|
11
|
-
permissionDecisionReason: "Bash is not allowed. Use read_playbook and list_playbooks tools instead. Produce the plan from playbook knowledge.",
|
|
12
|
-
},
|
|
13
|
-
};
|
|
14
|
-
};
|
|
15
|
-
//# sourceMappingURL=block-bash.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"block-bash.js","sourceRoot":"","sources":["../../src/hooks/block-bash.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,SAAS,GAAiB,KAAK,IAAI,EAAE;IACjD,OAAO;QACN,cAAc,EAAE,IAAI;QACpB,kBAAkB,EAAE;YACnB,aAAa,EAAE,YAAqB;YACpC,kBAAkB,EAAE,MAAe;YACnC,wBAAwB,EACvB,oHAAoH;SACrH;KACD,CAAA;AACF,CAAC,CAAA"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { HookCallback } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
-
/**
|
|
3
|
-
* PreToolUse hook: Prevent removal of existing dependencies from package.json.
|
|
4
|
-
* Allows additions, blocks removals.
|
|
5
|
-
*/
|
|
6
|
-
export declare const dependencyGuard: HookCallback;
|
|
7
|
-
//# sourceMappingURL=dependency-guard.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-guard.d.ts","sourceRoot":"","sources":["../../src/hooks/dependency-guard.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,gCAAgC,CAAA;AAEvF;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,YAgC7B,CAAA"}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PreToolUse hook: Prevent removal of existing dependencies from package.json.
|
|
3
|
-
* Allows additions, blocks removals.
|
|
4
|
-
*/
|
|
5
|
-
export const dependencyGuard = async (input, _toolUseID, _opts) => {
|
|
6
|
-
const preInput = input;
|
|
7
|
-
const toolInput = preInput.tool_input;
|
|
8
|
-
const filePath = (toolInput?.file_path || "");
|
|
9
|
-
if (!filePath.endsWith("package.json"))
|
|
10
|
-
return {};
|
|
11
|
-
// For Write tool, compare new content against what exists
|
|
12
|
-
const newContent = toolInput?.content;
|
|
13
|
-
if (!newContent)
|
|
14
|
-
return {};
|
|
15
|
-
// For Edit tool, we get old_string and new_string
|
|
16
|
-
const oldString = toolInput?.old_string;
|
|
17
|
-
if (oldString) {
|
|
18
|
-
// Check if the edit removes dependency lines
|
|
19
|
-
const oldDeps = extractDependencyNames(oldString);
|
|
20
|
-
const newString = (toolInput?.new_string || "");
|
|
21
|
-
const newDeps = extractDependencyNames(newString);
|
|
22
|
-
const removed = oldDeps.filter((d) => !newDeps.includes(d));
|
|
23
|
-
if (removed.length > 0) {
|
|
24
|
-
return {
|
|
25
|
-
hookSpecificOutput: {
|
|
26
|
-
hookEventName: "PreToolUse",
|
|
27
|
-
permissionDecision: "deny",
|
|
28
|
-
permissionDecisionReason: `Cannot remove existing dependencies: ${removed.join(", ")}. Only additions are allowed.`,
|
|
29
|
-
},
|
|
30
|
-
};
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return {};
|
|
34
|
-
};
|
|
35
|
-
function extractDependencyNames(content) {
|
|
36
|
-
const deps = [];
|
|
37
|
-
const depRegex = /"([^"]+)":\s*"/g;
|
|
38
|
-
for (const match of content.matchAll(depRegex)) {
|
|
39
|
-
deps.push(match[1]);
|
|
40
|
-
}
|
|
41
|
-
return deps;
|
|
42
|
-
}
|
|
43
|
-
//# sourceMappingURL=dependency-guard.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"dependency-guard.js","sourceRoot":"","sources":["../../src/hooks/dependency-guard.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,eAAe,GAAiB,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE;IAC/E,MAAM,QAAQ,GAAG,KAA4B,CAAA;IAC7C,MAAM,SAAS,GAAG,QAAQ,CAAC,UAAiD,CAAA;IAE5E,MAAM,QAAQ,GAAG,CAAC,SAAS,EAAE,SAAS,IAAI,EAAE,CAAW,CAAA;IACvD,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,cAAc,CAAC;QAAE,OAAO,EAAE,CAAA;IAEjD,0DAA0D;IAC1D,MAAM,UAAU,GAAG,SAAS,EAAE,OAA6B,CAAA;IAC3D,IAAI,CAAC,UAAU;QAAE,OAAO,EAAE,CAAA;IAE1B,kDAAkD;IAClD,MAAM,SAAS,GAAG,SAAS,EAAE,UAAgC,CAAA;IAC7D,IAAI,SAAS,EAAE,CAAC;QACf,6CAA6C;QAC7C,MAAM,OAAO,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAA;QACjD,MAAM,SAAS,GAAG,CAAC,SAAS,EAAE,UAAU,IAAI,EAAE,CAAW,CAAA;QACzD,MAAM,OAAO,GAAG,sBAAsB,CAAC,SAAS,CAAC,CAAA;QAEjD,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;QAC3D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO;gBACN,kBAAkB,EAAE;oBACnB,aAAa,EAAE,YAAqB;oBACpC,kBAAkB,EAAE,MAAe;oBACnC,wBAAwB,EAAE,wCAAwC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,+BAA+B;iBACnH;aACD,CAAA;QACF,CAAC;IACF,CAAC;IAED,OAAO,EAAE,CAAA;AACV,CAAC,CAAA;AAED,SAAS,sBAAsB,CAAC,OAAe;IAC9C,MAAM,IAAI,GAAa,EAAE,CAAA;IACzB,MAAM,QAAQ,GAAG,iBAAiB,CAAA;IAClC,KAAK,MAAM,KAAK,IAAI,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChD,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;IACpB,CAAC;IACD,OAAO,IAAI,CAAA;AACZ,CAAC"}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { HookCallback } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
-
/**
|
|
3
|
-
* SessionStart hook: Auto-inject the electric-app-guardrails playbook content
|
|
4
|
-
* as additional context at the start of every coder session.
|
|
5
|
-
*
|
|
6
|
-
* This ensures the agent always has critical guardrail rules in context,
|
|
7
|
-
* regardless of whether the PLAN.md tells it to read the playbook or
|
|
8
|
-
* whether it skips Phase 0.
|
|
9
|
-
*/
|
|
10
|
-
export declare const guardrailInject: HookCallback;
|
|
11
|
-
/**
|
|
12
|
-
* Create a SessionStart hook that injects both guardrails AND ARCHITECTURE.md.
|
|
13
|
-
* ARCHITECTURE.md provides the coder with immediate structural knowledge of the app,
|
|
14
|
-
* saving 3-5 turns of file scanning on iterations.
|
|
15
|
-
*/
|
|
16
|
-
export declare function createSessionStartHook(projectDir: string): HookCallback;
|
|
17
|
-
//# sourceMappingURL=guardrail-inject.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"guardrail-inject.d.ts","sourceRoot":"","sources":["../../src/hooks/guardrail-inject.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAA;AAyBlE;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe,EAAE,YAU7B,CAAA;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,YAAY,CAuBvE"}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { fileURLToPath } from "node:url";
|
|
4
|
-
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
5
|
-
/**
|
|
6
|
-
* Resolve the bundled guardrails SKILL.md that ships with electric-agent.
|
|
7
|
-
* Returns the file content stripped of YAML frontmatter.
|
|
8
|
-
*/
|
|
9
|
-
function loadGuardrails() {
|
|
10
|
-
const dirs = [
|
|
11
|
-
path.resolve(__dirname, "../../playbooks/electric-app-guardrails/SKILL.md"),
|
|
12
|
-
path.resolve(__dirname, "../playbooks/electric-app-guardrails/SKILL.md"),
|
|
13
|
-
];
|
|
14
|
-
for (const filePath of dirs) {
|
|
15
|
-
if (fs.existsSync(filePath)) {
|
|
16
|
-
const raw = fs.readFileSync(filePath, "utf-8");
|
|
17
|
-
// Strip YAML frontmatter
|
|
18
|
-
return raw.replace(/^---\n[\s\S]*?\n---\n*/, "");
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
/**
|
|
24
|
-
* SessionStart hook: Auto-inject the electric-app-guardrails playbook content
|
|
25
|
-
* as additional context at the start of every coder session.
|
|
26
|
-
*
|
|
27
|
-
* This ensures the agent always has critical guardrail rules in context,
|
|
28
|
-
* regardless of whether the PLAN.md tells it to read the playbook or
|
|
29
|
-
* whether it skips Phase 0.
|
|
30
|
-
*/
|
|
31
|
-
export const guardrailInject = async () => {
|
|
32
|
-
const content = loadGuardrails();
|
|
33
|
-
if (!content)
|
|
34
|
-
return {};
|
|
35
|
-
return {
|
|
36
|
-
hookSpecificOutput: {
|
|
37
|
-
hookEventName: "SessionStart",
|
|
38
|
-
additionalContext: `<electric-app-guardrails>\n${content}\n</electric-app-guardrails>`,
|
|
39
|
-
},
|
|
40
|
-
};
|
|
41
|
-
};
|
|
42
|
-
/**
|
|
43
|
-
* Create a SessionStart hook that injects both guardrails AND ARCHITECTURE.md.
|
|
44
|
-
* ARCHITECTURE.md provides the coder with immediate structural knowledge of the app,
|
|
45
|
-
* saving 3-5 turns of file scanning on iterations.
|
|
46
|
-
*/
|
|
47
|
-
export function createSessionStartHook(projectDir) {
|
|
48
|
-
return async () => {
|
|
49
|
-
const parts = [];
|
|
50
|
-
const guardrails = loadGuardrails();
|
|
51
|
-
if (guardrails) {
|
|
52
|
-
parts.push(`<electric-app-guardrails>\n${guardrails}\n</electric-app-guardrails>`);
|
|
53
|
-
}
|
|
54
|
-
const archPath = path.join(projectDir, "ARCHITECTURE.md");
|
|
55
|
-
if (fs.existsSync(archPath)) {
|
|
56
|
-
const arch = fs.readFileSync(archPath, "utf-8");
|
|
57
|
-
parts.push(`<app-architecture>\n${arch}\n</app-architecture>`);
|
|
58
|
-
}
|
|
59
|
-
if (parts.length === 0)
|
|
60
|
-
return {};
|
|
61
|
-
return {
|
|
62
|
-
hookSpecificOutput: {
|
|
63
|
-
hookEventName: "SessionStart",
|
|
64
|
-
additionalContext: parts.join("\n\n"),
|
|
65
|
-
},
|
|
66
|
-
};
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
//# sourceMappingURL=guardrail-inject.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"guardrail-inject.js","sourceRoot":"","sources":["../../src/hooks/guardrail-inject.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAA;AACxB,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAGxC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAA;AAE9D;;;GAGG;AACH,SAAS,cAAc;IACtB,MAAM,IAAI,GAAG;QACZ,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,kDAAkD,CAAC;QAC3E,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,+CAA+C,CAAC;KACxE,CAAA;IAED,KAAK,MAAM,QAAQ,IAAI,IAAI,EAAE,CAAC;QAC7B,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YAC9C,yBAAyB;YACzB,OAAO,GAAG,CAAC,OAAO,CAAC,wBAAwB,EAAE,EAAE,CAAC,CAAA;QACjD,CAAC;IACF,CAAC;IAED,OAAO,IAAI,CAAA;AACZ,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,eAAe,GAAiB,KAAK,IAAI,EAAE;IACvD,MAAM,OAAO,GAAG,cAAc,EAAE,CAAA;IAChC,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAA;IAEvB,OAAO;QACN,kBAAkB,EAAE;YACnB,aAAa,EAAE,cAAuB;YACtC,iBAAiB,EAAE,8BAA8B,OAAO,8BAA8B;SACtF;KACD,CAAA;AACF,CAAC,CAAA;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,UAAkB;IACxD,OAAO,KAAK,IAAI,EAAE;QACjB,MAAM,KAAK,GAAa,EAAE,CAAA;QAE1B,MAAM,UAAU,GAAG,cAAc,EAAE,CAAA;QACnC,IAAI,UAAU,EAAE,CAAC;YAChB,KAAK,CAAC,IAAI,CAAC,8BAA8B,UAAU,8BAA8B,CAAC,CAAA;QACnF,CAAC;QAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,iBAAiB,CAAC,CAAA;QACzD,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;YAC/C,KAAK,CAAC,IAAI,CAAC,uBAAuB,IAAI,uBAAuB,CAAC,CAAA;QAC/D,CAAC;QAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAA;QACjC,OAAO;YACN,kBAAkB,EAAE;gBACnB,aAAa,EAAE,cAAuB;gBACtC,iBAAiB,EAAE,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC;aACrC;SACD,CAAA;IACF,CAAC,CAAA;AACF,CAAC"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { HookCallback } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
-
/**
|
|
3
|
-
* PreToolUse hook: Validate imports in file content against known-correct table.
|
|
4
|
-
* Denies writes that contain hallucinated or incorrect imports.
|
|
5
|
-
*/
|
|
6
|
-
export declare const importValidation: HookCallback;
|
|
7
|
-
//# sourceMappingURL=import-validation.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"import-validation.d.ts","sourceRoot":"","sources":["../../src/hooks/import-validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAuB,MAAM,gCAAgC,CAAA;AAsJvF;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,YAmD9B,CAAA"}
|