@cybedefend/vibedefend 1.7.0 → 1.8.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/README.md +22 -13
- package/dist/clients/antigravity.js +342 -0
- package/dist/clients/antigravity.js.map +1 -0
- package/dist/clients/registry.js +2 -0
- package/dist/clients/registry.js.map +1 -1
- package/dist/clients/windsurf.js +20 -8
- package/dist/clients/windsurf.js.map +1 -1
- package/dist/hook-runner.js +930 -227
- package/dist/hooks/install.js +1 -1
- package/dist/hooks/install.js.map +1 -1
- package/dist/hooks/runtime/antigravity-session.js +400 -0
- package/dist/hooks/runtime/antigravity-session.js.map +1 -0
- package/dist/hooks/runtime/emit.js +206 -0
- package/dist/hooks/runtime/emit.js.map +1 -1
- package/dist/hooks/runtime/exit-deadlock-guard.js +46 -0
- package/dist/hooks/runtime/exit-deadlock-guard.js.map +1 -0
- package/dist/hooks/runtime/fetch-rules.js +39 -3
- package/dist/hooks/runtime/fetch-rules.js.map +1 -1
- package/dist/hooks/runtime/pre-invocation.js +45 -0
- package/dist/hooks/runtime/pre-invocation.js.map +1 -0
- package/dist/hooks/runtime/runner-args.js +12 -0
- package/dist/hooks/runtime/runner-args.js.map +1 -0
- package/dist/hooks/runtime/session-activation.js +10 -4
- package/dist/hooks/runtime/session-activation.js.map +1 -1
- package/dist/hooks/runtime/session-review.js +42 -0
- package/dist/hooks/runtime/session-review.js.map +1 -1
- package/dist/hooks/runtime/session-start.js +21 -1
- package/dist/hooks/runtime/session-start.js.map +1 -1
- package/dist/hooks/runtime/sniff.js +345 -71
- package/dist/hooks/runtime/sniff.js.map +1 -1
- package/dist/hooks/runtime/work-dir.js +3 -0
- package/dist/hooks/runtime/work-dir.js.map +1 -1
- package/dist/hooks/shim.js +102 -5
- package/dist/hooks/shim.js.map +1 -1
- package/dist/install.js +17 -3
- package/dist/install.js.map +1 -1
- package/dist/json-file.js +6 -3
- package/dist/json-file.js.map +1 -1
- package/dist/shim.js +53 -3
- package/dist/utils.js +9 -0
- package/dist/utils.js.map +1 -1
- package/package.json +3 -2
package/dist/hook-runner.js
CHANGED
|
@@ -4630,6 +4630,34 @@ var require_re22 = __commonJS({
|
|
|
4630
4630
|
}
|
|
4631
4631
|
});
|
|
4632
4632
|
|
|
4633
|
+
// src/hooks/runtime/exit-deadlock-guard.ts
|
|
4634
|
+
import { setFlagsFromString } from "node:v8";
|
|
4635
|
+
|
|
4636
|
+
// src/hooks/runtime/runner-args.ts
|
|
4637
|
+
function parseRunnerArgs(argv) {
|
|
4638
|
+
const subcommand = argv[0] ?? "";
|
|
4639
|
+
let client = null;
|
|
4640
|
+
for (let i = 1; i < argv.length - 1; i++) {
|
|
4641
|
+
if (argv[i] === "--client" && argv[i + 1] === "antigravity") {
|
|
4642
|
+
client = "antigravity";
|
|
4643
|
+
break;
|
|
4644
|
+
}
|
|
4645
|
+
}
|
|
4646
|
+
return { subcommand, client };
|
|
4647
|
+
}
|
|
4648
|
+
|
|
4649
|
+
// src/hooks/runtime/exit-deadlock-guard.ts
|
|
4650
|
+
function exitDeadlockFlags(argv) {
|
|
4651
|
+
if (parseRunnerArgs(argv).client !== "antigravity") return [];
|
|
4652
|
+
return ["--no-concurrent-sparkplug", "--no-maglev"];
|
|
4653
|
+
}
|
|
4654
|
+
for (const flag of exitDeadlockFlags(process.argv.slice(2))) {
|
|
4655
|
+
try {
|
|
4656
|
+
setFlagsFromString(flag);
|
|
4657
|
+
} catch {
|
|
4658
|
+
}
|
|
4659
|
+
}
|
|
4660
|
+
|
|
4633
4661
|
// src/hooks/runtime/sniff.ts
|
|
4634
4662
|
import { homedir } from "node:os";
|
|
4635
4663
|
import { isAbsolute, resolve as resolvePath } from "node:path";
|
|
@@ -4869,65 +4897,220 @@ function filePathFromPatch(patch) {
|
|
|
4869
4897
|
}
|
|
4870
4898
|
return "";
|
|
4871
4899
|
}
|
|
4872
|
-
function
|
|
4873
|
-
if (!Array.isArray(
|
|
4874
|
-
return
|
|
4900
|
+
function joinStringField(entries, field) {
|
|
4901
|
+
if (!Array.isArray(entries)) return "";
|
|
4902
|
+
return entries.map((e) => {
|
|
4903
|
+
if (typeof e !== "object" || e === null) return "";
|
|
4904
|
+
const value = e[field];
|
|
4905
|
+
return typeof value === "string" ? value : "";
|
|
4906
|
+
}).filter((s) => s.length > 0).join("\n---\n");
|
|
4907
|
+
}
|
|
4908
|
+
function isAntigravityEnvelope(input2) {
|
|
4909
|
+
return typeof input2.conversationId === "string" && Array.isArray(input2.workspacePaths);
|
|
4910
|
+
}
|
|
4911
|
+
var ANTIGRAVITY_PATH_ARGS = [
|
|
4912
|
+
"TargetFile",
|
|
4913
|
+
"AbsolutePath",
|
|
4914
|
+
"Path",
|
|
4915
|
+
"FilePath",
|
|
4916
|
+
"file_path",
|
|
4917
|
+
"path"
|
|
4918
|
+
];
|
|
4919
|
+
var ANTIGRAVITY_OWN_PATH_ARG = /* @__PURE__ */ new Map([
|
|
4920
|
+
["write_to_file", "TargetFile"],
|
|
4921
|
+
["replace_file_content", "TargetFile"],
|
|
4922
|
+
["multi_replace_file_content", "TargetFile"],
|
|
4923
|
+
["view_file", "AbsolutePath"],
|
|
4924
|
+
["write_file", "Path"],
|
|
4925
|
+
["edit_file", "Path"],
|
|
4926
|
+
["read_file", "Path"]
|
|
4927
|
+
]);
|
|
4928
|
+
function antigravityFilePathArg(toolName, args) {
|
|
4929
|
+
const own2 = ANTIGRAVITY_OWN_PATH_ARG.get(toolName);
|
|
4930
|
+
for (const key of own2 === void 0 ? ANTIGRAVITY_PATH_ARGS : [own2, ...ANTIGRAVITY_PATH_ARGS]) {
|
|
4931
|
+
const value = args[key];
|
|
4932
|
+
if (typeof value === "string" && value.length > 0) return value;
|
|
4933
|
+
}
|
|
4934
|
+
return "";
|
|
4875
4935
|
}
|
|
4876
|
-
|
|
4877
|
-
|
|
4936
|
+
var ANTIGRAVITY_KNOWN_TOOLS = /* @__PURE__ */ new Set([
|
|
4937
|
+
...ANTIGRAVITY_OWN_PATH_ARG.keys(),
|
|
4938
|
+
"run_command",
|
|
4939
|
+
"read_url_content",
|
|
4940
|
+
"call_mcp_tool"
|
|
4941
|
+
]);
|
|
4942
|
+
var ANTIGRAVITY_CONTENT_KEY_RE = /content|replacement|chunk|edit|patch|diff/i;
|
|
4943
|
+
function classifyUnknownAntigravityTool(args) {
|
|
4944
|
+
const pathKeys = new Set(ANTIGRAVITY_PATH_ARGS);
|
|
4945
|
+
for (const key of Object.keys(args)) {
|
|
4946
|
+
if (pathKeys.has(key)) continue;
|
|
4947
|
+
if (ANTIGRAVITY_CONTENT_KEY_RE.test(key)) return "Write";
|
|
4948
|
+
}
|
|
4949
|
+
return "Read";
|
|
4950
|
+
}
|
|
4951
|
+
function unknownAntigravityContent(args) {
|
|
4952
|
+
const pathKeys = new Set(ANTIGRAVITY_PATH_ARGS);
|
|
4953
|
+
for (const key of Object.keys(args)) {
|
|
4954
|
+
if (pathKeys.has(key)) continue;
|
|
4955
|
+
if (!ANTIGRAVITY_CONTENT_KEY_RE.test(key)) continue;
|
|
4956
|
+
const value = args[key];
|
|
4957
|
+
if (typeof value === "string" && value.length > 0) return value;
|
|
4958
|
+
}
|
|
4959
|
+
return "";
|
|
4878
4960
|
}
|
|
4879
|
-
function
|
|
4880
|
-
|
|
4881
|
-
|
|
4882
|
-
|
|
4883
|
-
const
|
|
4884
|
-
|
|
4885
|
-
|
|
4886
|
-
|
|
4887
|
-
let toolName = action;
|
|
4888
|
-
if (action === "pre_write_code" || action === "post_write_code") {
|
|
4889
|
-
toolName = "Write";
|
|
4890
|
-
} else if (action === "pre_read_code" || action === "post_read_code") {
|
|
4891
|
-
toolName = "Read";
|
|
4961
|
+
function antigravityAllPathArgs(args) {
|
|
4962
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4963
|
+
const out = [];
|
|
4964
|
+
for (const key of ANTIGRAVITY_PATH_ARGS) {
|
|
4965
|
+
const value = args[key];
|
|
4966
|
+
if (typeof value === "string" && value.length > 0 && !seen.has(value)) {
|
|
4967
|
+
seen.add(value);
|
|
4968
|
+
out.push(value);
|
|
4892
4969
|
}
|
|
4970
|
+
}
|
|
4971
|
+
return out;
|
|
4972
|
+
}
|
|
4973
|
+
function resolveAntigravityTargetFile(value, w) {
|
|
4974
|
+
return value.length > 0 ? resolveWriteTarget(w, value) : "";
|
|
4975
|
+
}
|
|
4976
|
+
function stringArg(value) {
|
|
4977
|
+
return typeof value === "string" ? value : "";
|
|
4978
|
+
}
|
|
4979
|
+
function extractAntigravityShape(input2) {
|
|
4980
|
+
const workspacePaths = Array.isArray(input2.workspacePaths) ? input2.workspacePaths : [];
|
|
4981
|
+
const w = workspacePaths.find(
|
|
4982
|
+
(p) => typeof p === "string" && p.length > 0
|
|
4983
|
+
) ?? process.cwd();
|
|
4984
|
+
const toolCall = typeof input2.toolCall === "object" && input2.toolCall !== null ? input2.toolCall : void 0;
|
|
4985
|
+
if (toolCall === void 0) {
|
|
4893
4986
|
return {
|
|
4894
|
-
client: "
|
|
4895
|
-
toolName,
|
|
4896
|
-
filePath,
|
|
4897
|
-
filePaths:
|
|
4898
|
-
newContent,
|
|
4987
|
+
client: "antigravity",
|
|
4988
|
+
toolName: "",
|
|
4989
|
+
filePath: "",
|
|
4990
|
+
filePaths: [],
|
|
4991
|
+
newContent: "",
|
|
4899
4992
|
raw: input2
|
|
4900
4993
|
};
|
|
4901
4994
|
}
|
|
4902
|
-
|
|
4903
|
-
|
|
4995
|
+
const name = typeof toolCall.name === "string" ? toolCall.name : "";
|
|
4996
|
+
const args = toolCall.args ?? {};
|
|
4997
|
+
let toolName = name;
|
|
4998
|
+
let filePath = resolveAntigravityTargetFile(antigravityFilePathArg(name, args), w);
|
|
4999
|
+
let filePaths = [];
|
|
5000
|
+
let newContent = "";
|
|
5001
|
+
switch (name) {
|
|
5002
|
+
case "write_to_file":
|
|
5003
|
+
toolName = "Write";
|
|
5004
|
+
newContent = stringArg(args.CodeContent);
|
|
5005
|
+
break;
|
|
5006
|
+
case "write_file":
|
|
5007
|
+
toolName = "Write";
|
|
5008
|
+
newContent = stringArg(args.Content);
|
|
5009
|
+
break;
|
|
5010
|
+
case "replace_file_content":
|
|
5011
|
+
toolName = "Edit";
|
|
5012
|
+
newContent = stringArg(args.ReplacementContent);
|
|
5013
|
+
break;
|
|
5014
|
+
case "edit_file":
|
|
5015
|
+
toolName = "Edit";
|
|
5016
|
+
newContent = stringArg(args.Replacement);
|
|
5017
|
+
break;
|
|
5018
|
+
case "multi_replace_file_content":
|
|
5019
|
+
toolName = "MultiEdit";
|
|
5020
|
+
newContent = joinStringField(args.ReplacementChunks, "ReplacementContent");
|
|
5021
|
+
break;
|
|
5022
|
+
case "run_command": {
|
|
5023
|
+
toolName = "Bash";
|
|
5024
|
+
const command = typeof args.CommandLine === "string" ? args.CommandLine : "";
|
|
5025
|
+
newContent = command;
|
|
5026
|
+
const cwd = typeof args.Cwd === "string" && args.Cwd.length > 0 ? args.Cwd : w;
|
|
5027
|
+
filePaths = extractShellWriteTargets(command).map(
|
|
5028
|
+
(t) => resolveWriteTarget(cwd, t)
|
|
5029
|
+
);
|
|
5030
|
+
filePath = filePaths[0] ?? "";
|
|
5031
|
+
break;
|
|
5032
|
+
}
|
|
5033
|
+
default:
|
|
5034
|
+
if (name && filePath && !ANTIGRAVITY_KNOWN_TOOLS.has(name)) {
|
|
5035
|
+
if (classifyUnknownAntigravityTool(args) === "Write") {
|
|
5036
|
+
toolName = "Write";
|
|
5037
|
+
newContent = unknownAntigravityContent(args);
|
|
5038
|
+
}
|
|
5039
|
+
}
|
|
5040
|
+
break;
|
|
4904
5041
|
}
|
|
5042
|
+
if (filePaths.length === 0 && filePath) filePaths = [filePath];
|
|
5043
|
+
return { client: "antigravity", toolName, filePath, filePaths, newContent, raw: input2 };
|
|
5044
|
+
}
|
|
5045
|
+
function detectClient(input2) {
|
|
5046
|
+
if (isAntigravityEnvelope(input2)) return "antigravity";
|
|
5047
|
+
if (typeof input2.agent_action_name === "string") return "windsurf";
|
|
5048
|
+
if ("hookEventName" in input2) return "vscode";
|
|
4905
5049
|
if ("hook_event_name" in input2) {
|
|
4906
5050
|
const evt = typeof input2.hook_event_name === "string" ? input2.hook_event_name : "";
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
|
|
4915
|
-
|
|
4916
|
-
|
|
4917
|
-
|
|
4918
|
-
|
|
4919
|
-
|
|
4920
|
-
|
|
5051
|
+
if (/^[a-z]/.test(evt)) return "cursor";
|
|
5052
|
+
const toolName = typeof input2.tool_name === "string" ? input2.tool_name : "";
|
|
5053
|
+
if (toolName === "apply_patch" || "turn_id" in input2) return "codex";
|
|
5054
|
+
if (hasIsoTimestamp(input2)) return "vscode";
|
|
5055
|
+
return "claude-code";
|
|
5056
|
+
}
|
|
5057
|
+
return "unknown";
|
|
5058
|
+
}
|
|
5059
|
+
function extractWindsurfShape(input2) {
|
|
5060
|
+
const action = input2.agent_action_name;
|
|
5061
|
+
const toolInfo = input2.tool_info ?? {};
|
|
5062
|
+
if (action === "pre_run_command" || action === "post_run_command") {
|
|
5063
|
+
const command = typeof toolInfo.command_line === "string" ? toolInfo.command_line : "";
|
|
5064
|
+
const cwd = typeof toolInfo.cwd === "string" && toolInfo.cwd.length > 0 ? toolInfo.cwd : process.cwd();
|
|
5065
|
+
const filePaths = extractShellWriteTargets(command).map(
|
|
5066
|
+
(t) => resolveWriteTarget(cwd, t)
|
|
5067
|
+
);
|
|
5068
|
+
return {
|
|
5069
|
+
client: "windsurf",
|
|
5070
|
+
toolName: "Bash",
|
|
5071
|
+
filePath: filePaths[0] ?? "",
|
|
5072
|
+
filePaths,
|
|
5073
|
+
newContent: command,
|
|
5074
|
+
raw: input2
|
|
5075
|
+
};
|
|
5076
|
+
}
|
|
5077
|
+
const filePath = typeof toolInfo.file_path === "string" ? toolInfo.file_path : "";
|
|
5078
|
+
const newContent = joinStringField(toolInfo.edits, "new_string");
|
|
5079
|
+
let toolName = action;
|
|
5080
|
+
if (action === "pre_write_code" || action === "post_write_code") {
|
|
5081
|
+
toolName = "Write";
|
|
5082
|
+
} else if (action === "pre_read_code" || action === "post_read_code") {
|
|
5083
|
+
toolName = "Read";
|
|
4921
5084
|
}
|
|
4922
5085
|
return {
|
|
4923
|
-
client: "
|
|
4924
|
-
toolName
|
|
4925
|
-
filePath
|
|
4926
|
-
filePaths: [],
|
|
4927
|
-
newContent
|
|
5086
|
+
client: "windsurf",
|
|
5087
|
+
toolName,
|
|
5088
|
+
filePath,
|
|
5089
|
+
filePaths: filePath ? [filePath] : [],
|
|
5090
|
+
newContent,
|
|
4928
5091
|
raw: input2
|
|
4929
5092
|
};
|
|
4930
5093
|
}
|
|
5094
|
+
function sniff(input2) {
|
|
5095
|
+
const client = detectClient(input2);
|
|
5096
|
+
switch (client) {
|
|
5097
|
+
case "antigravity":
|
|
5098
|
+
return extractAntigravityShape(input2);
|
|
5099
|
+
case "windsurf":
|
|
5100
|
+
return extractWindsurfShape(input2);
|
|
5101
|
+
case "unknown":
|
|
5102
|
+
return {
|
|
5103
|
+
client: "unknown",
|
|
5104
|
+
toolName: "",
|
|
5105
|
+
filePath: "",
|
|
5106
|
+
filePaths: [],
|
|
5107
|
+
newContent: "",
|
|
5108
|
+
raw: input2
|
|
5109
|
+
};
|
|
5110
|
+
default:
|
|
5111
|
+
return extractToolInputShape(input2, client);
|
|
5112
|
+
}
|
|
5113
|
+
}
|
|
4931
5114
|
function hasIsoTimestamp(input2) {
|
|
4932
5115
|
return typeof input2.timestamp === "string" && /^\d{4}-\d{2}-\d{2}T/.test(input2.timestamp);
|
|
4933
5116
|
}
|
|
@@ -4955,9 +5138,7 @@ function extractToolInputShape(input2, client) {
|
|
|
4955
5138
|
newContent = typeof toolInput.new_string === "string" ? toolInput.new_string : "";
|
|
4956
5139
|
break;
|
|
4957
5140
|
case "MultiEdit":
|
|
4958
|
-
newContent =
|
|
4959
|
-
toolInput.edits
|
|
4960
|
-
);
|
|
5141
|
+
newContent = joinStringField(toolInput.edits, "new_string");
|
|
4961
5142
|
break;
|
|
4962
5143
|
case "apply_patch": {
|
|
4963
5144
|
const patch = typeof toolInput.patch === "string" ? toolInput.patch : typeof toolInput.command === "string" ? toolInput.command : "";
|
|
@@ -6184,9 +6365,15 @@ import { dirname as dirname4, isAbsolute as isAbsolute2, join as join6, resolve
|
|
|
6184
6365
|
import { fileURLToPath } from "node:url";
|
|
6185
6366
|
|
|
6186
6367
|
// src/hooks/runtime/emit.ts
|
|
6368
|
+
import { writeSync } from "node:fs";
|
|
6187
6369
|
var ENVELOPE_CLIENTS = {
|
|
6188
6370
|
SessionStart: /* @__PURE__ */ new Set(["codex"]),
|
|
6189
|
-
PreToolUse: /* @__PURE__ */ new Set(["claude-code", "codex", "vscode"])
|
|
6371
|
+
PreToolUse: /* @__PURE__ */ new Set(["claude-code", "codex", "vscode"]),
|
|
6372
|
+
// Antigravity never reaches this generic envelope: it has its own shapes
|
|
6373
|
+
// per event, handled in `emitAntigravityContext` below. Kept as an empty
|
|
6374
|
+
// set (rather than omitted) so `ENVELOPE_CLIENTS[hookEventName]` stays a
|
|
6375
|
+
// total function over `ContextHookEvent`.
|
|
6376
|
+
PreInvocation: /* @__PURE__ */ new Set()
|
|
6190
6377
|
};
|
|
6191
6378
|
var NO_MODEL_CHANNEL = {
|
|
6192
6379
|
PreToolUse: /* @__PURE__ */ new Set(["cursor"]),
|
|
@@ -6195,14 +6382,71 @@ var NO_MODEL_CHANNEL = {
|
|
|
6195
6382
|
function hasModelChannel(client, event) {
|
|
6196
6383
|
return !NO_MODEL_CHANNEL[event]?.has(client);
|
|
6197
6384
|
}
|
|
6385
|
+
var antigravityWritten = false;
|
|
6386
|
+
function writeStdoutSync(text) {
|
|
6387
|
+
const buf = Buffer.from(text, "utf8");
|
|
6388
|
+
const deadline = Date.now() + 2e3;
|
|
6389
|
+
let pause;
|
|
6390
|
+
let offset = 0;
|
|
6391
|
+
while (offset < buf.length) {
|
|
6392
|
+
let written = 0;
|
|
6393
|
+
try {
|
|
6394
|
+
written = writeSync(1, buf, offset, buf.length - offset);
|
|
6395
|
+
} catch (e) {
|
|
6396
|
+
if (e?.code !== "EAGAIN") return;
|
|
6397
|
+
}
|
|
6398
|
+
offset += written;
|
|
6399
|
+
if (written > 0) continue;
|
|
6400
|
+
if (Date.now() >= deadline) return;
|
|
6401
|
+
pause ??= new Int32Array(new SharedArrayBuffer(4));
|
|
6402
|
+
Atomics.wait(pause, 0, 0, 5);
|
|
6403
|
+
}
|
|
6404
|
+
}
|
|
6405
|
+
var antigravityWriter = writeStdoutSync;
|
|
6406
|
+
function writeAntigravityPayload(payload) {
|
|
6407
|
+
if (antigravityWritten) return;
|
|
6408
|
+
antigravityWritten = true;
|
|
6409
|
+
antigravityWriter(JSON.stringify(payload) + "\n");
|
|
6410
|
+
}
|
|
6411
|
+
function emitAntigravityDecision(decision, reason) {
|
|
6412
|
+
writeAntigravityPayload({ decision, ...reason ? { reason } : {} });
|
|
6413
|
+
}
|
|
6414
|
+
var PRE_TOOL_USE_SUBCOMMANDS = /* @__PURE__ */ new Set([
|
|
6415
|
+
"fetch-rules",
|
|
6416
|
+
"guard-check",
|
|
6417
|
+
"pre-tool-use",
|
|
6418
|
+
"PreToolUse"
|
|
6419
|
+
]);
|
|
6420
|
+
function finishAntigravityRun(subcommand) {
|
|
6421
|
+
const payload = PRE_TOOL_USE_SUBCOMMANDS.has(subcommand) ? { decision: "allow" } : {};
|
|
6422
|
+
writeAntigravityPayload(payload);
|
|
6423
|
+
}
|
|
6424
|
+
function emitAntigravityContext(body, hookEventName) {
|
|
6425
|
+
if (hookEventName === "PreToolUse") return;
|
|
6426
|
+
if (hookEventName === "SessionStart") {
|
|
6427
|
+
writeAntigravityPayload({
|
|
6428
|
+
injectSteps: [{ systemMessage: { systemMessage: body } }]
|
|
6429
|
+
});
|
|
6430
|
+
return;
|
|
6431
|
+
}
|
|
6432
|
+
writeAntigravityPayload({ injectSteps: [{ ephemeralMessage: body }] });
|
|
6433
|
+
}
|
|
6198
6434
|
function emit(body, client) {
|
|
6199
6435
|
if (!body) return;
|
|
6436
|
+
if (client === "antigravity") {
|
|
6437
|
+
writeAntigravityPayload({ injectSteps: [{ ephemeralMessage: body }] });
|
|
6438
|
+
return;
|
|
6439
|
+
}
|
|
6200
6440
|
if (client === "cursor") return;
|
|
6201
6441
|
process.stdout.write(body);
|
|
6202
6442
|
if (!body.endsWith("\n")) process.stdout.write("\n");
|
|
6203
6443
|
}
|
|
6204
6444
|
function emitContext(body, client, hookEventName) {
|
|
6205
6445
|
if (!body) return;
|
|
6446
|
+
if (client === "antigravity") {
|
|
6447
|
+
emitAntigravityContext(body, hookEventName);
|
|
6448
|
+
return;
|
|
6449
|
+
}
|
|
6206
6450
|
if (!hasModelChannel(client, hookEventName)) return;
|
|
6207
6451
|
if (client === "cursor" && hookEventName === "SessionStart") {
|
|
6208
6452
|
writeJson({ additional_context: body });
|
|
@@ -6262,6 +6506,9 @@ function emitStop(body, client, reason) {
|
|
|
6262
6506
|
case "cursor":
|
|
6263
6507
|
writeJson({ followup_message: body });
|
|
6264
6508
|
return;
|
|
6509
|
+
case "antigravity":
|
|
6510
|
+
writeAntigravityPayload({ decision: "continue", reason: body });
|
|
6511
|
+
return;
|
|
6265
6512
|
default:
|
|
6266
6513
|
emit(body, client);
|
|
6267
6514
|
}
|
|
@@ -6330,7 +6577,7 @@ function defaultInactiveSessionStore(file2 = defaultStoreFile(), now = Date.now)
|
|
|
6330
6577
|
};
|
|
6331
6578
|
}
|
|
6332
6579
|
function sessionIdOf(stdin) {
|
|
6333
|
-
for (const key of ["session_id", "sessionId", "conversation_id", "trajectory_id"]) {
|
|
6580
|
+
for (const key of ["session_id", "sessionId", "conversation_id", "trajectory_id", "conversationId"]) {
|
|
6334
6581
|
const v = stdin[key];
|
|
6335
6582
|
if (typeof v === "string" && v.length > 0) return v;
|
|
6336
6583
|
}
|
|
@@ -6343,6 +6590,9 @@ function sessionFolderOf(stdin, client, env = process.env) {
|
|
|
6343
6590
|
if (Array.isArray(roots)) candidates.push(roots[0]);
|
|
6344
6591
|
candidates.push(env.CURSOR_PROJECT_DIR);
|
|
6345
6592
|
}
|
|
6593
|
+
if (client === "antigravity" && Array.isArray(stdin.workspacePaths)) {
|
|
6594
|
+
candidates.push(...stdin.workspacePaths);
|
|
6595
|
+
}
|
|
6346
6596
|
candidates.push(stdin.cwd);
|
|
6347
6597
|
for (const c of candidates) {
|
|
6348
6598
|
const folder = absoluteFolder(c);
|
|
@@ -6453,10 +6703,260 @@ function projectDirForFile(file2, workDir) {
|
|
|
6453
6703
|
return fileRoot;
|
|
6454
6704
|
}
|
|
6455
6705
|
|
|
6706
|
+
// src/hooks/runtime/antigravity-session.ts
|
|
6707
|
+
import {
|
|
6708
|
+
appendFileSync,
|
|
6709
|
+
closeSync,
|
|
6710
|
+
constants,
|
|
6711
|
+
lstatSync,
|
|
6712
|
+
mkdirSync as mkdirSync6,
|
|
6713
|
+
openSync,
|
|
6714
|
+
readdirSync,
|
|
6715
|
+
readFileSync as readFileSync9,
|
|
6716
|
+
renameSync,
|
|
6717
|
+
rmSync,
|
|
6718
|
+
unlinkSync,
|
|
6719
|
+
utimesSync,
|
|
6720
|
+
writeFileSync as writeFileSync6,
|
|
6721
|
+
writeSync as writeSync2
|
|
6722
|
+
} from "node:fs";
|
|
6723
|
+
import { createHash as createHash2, randomBytes } from "node:crypto";
|
|
6724
|
+
import { homedir as homedir8 } from "node:os";
|
|
6725
|
+
import { join as join8 } from "node:path";
|
|
6726
|
+
var MAX_STASHED_CONTEXTS = 20;
|
|
6727
|
+
var DEFAULT_MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
6728
|
+
var STASH_NAME_RE = /^\d+-[0-9a-f]{8}\.md$/;
|
|
6729
|
+
var DIR_MODE = 448;
|
|
6730
|
+
var FILE_MODE = 384;
|
|
6731
|
+
function conversationKey(raw) {
|
|
6732
|
+
const id = raw.conversationId;
|
|
6733
|
+
if (typeof id !== "string" || id.length === 0 || id.length > 256) return null;
|
|
6734
|
+
return createHash2("sha256").update(id).digest("hex").slice(0, 32);
|
|
6735
|
+
}
|
|
6736
|
+
function antigravityStateDir() {
|
|
6737
|
+
return join8(homedir8(), ".cybedefend", "antigravity");
|
|
6738
|
+
}
|
|
6739
|
+
function keyDir(key, dir) {
|
|
6740
|
+
return join8(dir, key);
|
|
6741
|
+
}
|
|
6742
|
+
function isFinalStashName(name) {
|
|
6743
|
+
return STASH_NAME_RE.test(name);
|
|
6744
|
+
}
|
|
6745
|
+
function isUnsafePath(path) {
|
|
6746
|
+
try {
|
|
6747
|
+
return !lstatSync(path).isDirectory();
|
|
6748
|
+
} catch {
|
|
6749
|
+
return false;
|
|
6750
|
+
}
|
|
6751
|
+
}
|
|
6752
|
+
function isUnsafeFilePath(path) {
|
|
6753
|
+
try {
|
|
6754
|
+
return !lstatSync(path).isFile();
|
|
6755
|
+
} catch {
|
|
6756
|
+
return false;
|
|
6757
|
+
}
|
|
6758
|
+
}
|
|
6759
|
+
var NOFOLLOW_SUPPORTED = typeof constants.O_NOFOLLOW === "number";
|
|
6760
|
+
function appendLedgerLine(path, line) {
|
|
6761
|
+
if (NOFOLLOW_SUPPORTED) {
|
|
6762
|
+
const fd = openSync(
|
|
6763
|
+
path,
|
|
6764
|
+
constants.O_WRONLY | constants.O_APPEND | constants.O_CREAT | constants.O_NOFOLLOW,
|
|
6765
|
+
FILE_MODE
|
|
6766
|
+
);
|
|
6767
|
+
try {
|
|
6768
|
+
writeSync2(fd, line, null, "utf8");
|
|
6769
|
+
} finally {
|
|
6770
|
+
closeSync(fd);
|
|
6771
|
+
}
|
|
6772
|
+
return;
|
|
6773
|
+
}
|
|
6774
|
+
if (isUnsafeFilePath(path)) return;
|
|
6775
|
+
appendFileSync(path, line, { mode: FILE_MODE });
|
|
6776
|
+
}
|
|
6777
|
+
function writeMarkerFile(path, content) {
|
|
6778
|
+
if (NOFOLLOW_SUPPORTED) {
|
|
6779
|
+
const fd = openSync(
|
|
6780
|
+
path,
|
|
6781
|
+
constants.O_WRONLY | constants.O_CREAT | constants.O_TRUNC | constants.O_NOFOLLOW,
|
|
6782
|
+
FILE_MODE
|
|
6783
|
+
);
|
|
6784
|
+
try {
|
|
6785
|
+
writeSync2(fd, content, null, "utf8");
|
|
6786
|
+
} finally {
|
|
6787
|
+
closeSync(fd);
|
|
6788
|
+
}
|
|
6789
|
+
return;
|
|
6790
|
+
}
|
|
6791
|
+
if (isUnsafeFilePath(path)) return;
|
|
6792
|
+
writeFileSync6(path, content, { mode: FILE_MODE });
|
|
6793
|
+
}
|
|
6794
|
+
function ensureRealDir(path) {
|
|
6795
|
+
if (isUnsafePath(path)) return false;
|
|
6796
|
+
mkdirSync6(path, { recursive: true, mode: DIR_MODE });
|
|
6797
|
+
return true;
|
|
6798
|
+
}
|
|
6799
|
+
function ensureLiveKeyDir(key, dir, now) {
|
|
6800
|
+
const kd = keyDir(key, dir);
|
|
6801
|
+
if (!ensureRealDir(kd)) return null;
|
|
6802
|
+
try {
|
|
6803
|
+
const t = new Date(now);
|
|
6804
|
+
utimesSync(kd, t, t);
|
|
6805
|
+
} catch {
|
|
6806
|
+
}
|
|
6807
|
+
return kd;
|
|
6808
|
+
}
|
|
6809
|
+
function stashContext(key, body, dir = antigravityStateDir()) {
|
|
6810
|
+
let tmpPath;
|
|
6811
|
+
try {
|
|
6812
|
+
const now = Date.now();
|
|
6813
|
+
const kd = ensureLiveKeyDir(key, dir, now);
|
|
6814
|
+
if (!kd) return;
|
|
6815
|
+
const contextDir = join8(kd, "context");
|
|
6816
|
+
if (!ensureRealDir(contextDir)) return;
|
|
6817
|
+
const suffix = randomBytes(4).toString("hex");
|
|
6818
|
+
tmpPath = join8(contextDir, `.${now}-${suffix}.tmp`);
|
|
6819
|
+
writeFileSync6(tmpPath, body, { mode: FILE_MODE, flag: "wx" });
|
|
6820
|
+
const finalPath = join8(contextDir, `${now}-${suffix}.md`);
|
|
6821
|
+
renameSync(tmpPath, finalPath);
|
|
6822
|
+
tmpPath = void 0;
|
|
6823
|
+
const kept = readdirSync(contextDir).filter(isFinalStashName).sort();
|
|
6824
|
+
const excess = kept.length - MAX_STASHED_CONTEXTS;
|
|
6825
|
+
if (excess > 0) {
|
|
6826
|
+
for (const stale of kept.slice(0, excess)) {
|
|
6827
|
+
try {
|
|
6828
|
+
unlinkSync(join8(contextDir, stale));
|
|
6829
|
+
} catch {
|
|
6830
|
+
}
|
|
6831
|
+
}
|
|
6832
|
+
}
|
|
6833
|
+
} catch {
|
|
6834
|
+
if (tmpPath) {
|
|
6835
|
+
try {
|
|
6836
|
+
unlinkSync(tmpPath);
|
|
6837
|
+
} catch {
|
|
6838
|
+
}
|
|
6839
|
+
}
|
|
6840
|
+
}
|
|
6841
|
+
}
|
|
6842
|
+
function drainContext(key, dir = antigravityStateDir()) {
|
|
6843
|
+
try {
|
|
6844
|
+
const kd = keyDir(key, dir);
|
|
6845
|
+
if (isUnsafePath(kd)) return [];
|
|
6846
|
+
const contextDir = join8(kd, "context");
|
|
6847
|
+
if (isUnsafePath(contextDir)) return [];
|
|
6848
|
+
const entries = readdirSync(contextDir).filter(isFinalStashName).sort();
|
|
6849
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6850
|
+
const bodies = [];
|
|
6851
|
+
for (const name of entries) {
|
|
6852
|
+
const filePath = join8(contextDir, name);
|
|
6853
|
+
try {
|
|
6854
|
+
const body = readFileSync9(filePath, "utf8");
|
|
6855
|
+
if (!seen.has(body)) {
|
|
6856
|
+
seen.add(body);
|
|
6857
|
+
bodies.push(body);
|
|
6858
|
+
}
|
|
6859
|
+
} catch {
|
|
6860
|
+
}
|
|
6861
|
+
try {
|
|
6862
|
+
unlinkSync(filePath);
|
|
6863
|
+
} catch {
|
|
6864
|
+
}
|
|
6865
|
+
}
|
|
6866
|
+
return bodies;
|
|
6867
|
+
} catch {
|
|
6868
|
+
return [];
|
|
6869
|
+
}
|
|
6870
|
+
}
|
|
6871
|
+
function recordEdit(key, file2, dir = antigravityStateDir()) {
|
|
6872
|
+
try {
|
|
6873
|
+
const now = Date.now();
|
|
6874
|
+
const kd = ensureLiveKeyDir(key, dir, now);
|
|
6875
|
+
if (!kd) return;
|
|
6876
|
+
appendLedgerLine(join8(kd, "edits.jsonl"), JSON.stringify({ f: file2 }) + "\n");
|
|
6877
|
+
} catch {
|
|
6878
|
+
}
|
|
6879
|
+
}
|
|
6880
|
+
function readEdits(key, dir = antigravityStateDir()) {
|
|
6881
|
+
try {
|
|
6882
|
+
const kd = keyDir(key, dir);
|
|
6883
|
+
if (isUnsafePath(kd)) return { count: 0, files: [] };
|
|
6884
|
+
const editsPath = join8(kd, "edits.jsonl");
|
|
6885
|
+
if (isUnsafeFilePath(editsPath)) return { count: 0, files: [] };
|
|
6886
|
+
const content = readFileSync9(editsPath, "utf8");
|
|
6887
|
+
let count = 0;
|
|
6888
|
+
const files = [];
|
|
6889
|
+
const seen = /* @__PURE__ */ new Set();
|
|
6890
|
+
for (const line of content.split("\n")) {
|
|
6891
|
+
const trimmed = line.trim();
|
|
6892
|
+
if (!trimmed) continue;
|
|
6893
|
+
let parsed;
|
|
6894
|
+
try {
|
|
6895
|
+
parsed = JSON.parse(trimmed);
|
|
6896
|
+
} catch {
|
|
6897
|
+
continue;
|
|
6898
|
+
}
|
|
6899
|
+
if (typeof parsed.f !== "string") continue;
|
|
6900
|
+
count++;
|
|
6901
|
+
if (!seen.has(parsed.f)) {
|
|
6902
|
+
seen.add(parsed.f);
|
|
6903
|
+
files.push(parsed.f);
|
|
6904
|
+
}
|
|
6905
|
+
}
|
|
6906
|
+
return { count, files };
|
|
6907
|
+
} catch {
|
|
6908
|
+
return { count: 0, files: [] };
|
|
6909
|
+
}
|
|
6910
|
+
}
|
|
6911
|
+
function markReviewed(key, dir = antigravityStateDir()) {
|
|
6912
|
+
try {
|
|
6913
|
+
const now = Date.now();
|
|
6914
|
+
const kd = ensureLiveKeyDir(key, dir, now);
|
|
6915
|
+
if (!kd) return;
|
|
6916
|
+
writeMarkerFile(join8(kd, "reviewed"), String(now));
|
|
6917
|
+
} catch {
|
|
6918
|
+
}
|
|
6919
|
+
}
|
|
6920
|
+
function isReviewed(key, dir = antigravityStateDir()) {
|
|
6921
|
+
try {
|
|
6922
|
+
const kd = keyDir(key, dir);
|
|
6923
|
+
if (isUnsafePath(kd)) return false;
|
|
6924
|
+
return lstatSync(join8(kd, "reviewed")).isFile();
|
|
6925
|
+
} catch {
|
|
6926
|
+
return false;
|
|
6927
|
+
}
|
|
6928
|
+
}
|
|
6929
|
+
function pruneStale(dir = antigravityStateDir(), now = Date.now(), maxAgeMs = DEFAULT_MAX_AGE_MS) {
|
|
6930
|
+
try {
|
|
6931
|
+
const entries = readdirSync(dir);
|
|
6932
|
+
for (const name of entries) {
|
|
6933
|
+
const entryPath = join8(dir, name);
|
|
6934
|
+
try {
|
|
6935
|
+
const { mtimeMs } = lstatSync(entryPath);
|
|
6936
|
+
if (now - mtimeMs > maxAgeMs) {
|
|
6937
|
+
rmSync(entryPath, { recursive: true, force: true });
|
|
6938
|
+
}
|
|
6939
|
+
} catch {
|
|
6940
|
+
}
|
|
6941
|
+
}
|
|
6942
|
+
} catch {
|
|
6943
|
+
}
|
|
6944
|
+
}
|
|
6945
|
+
|
|
6456
6946
|
// src/hooks/runtime/fetch-rules.ts
|
|
6457
6947
|
function emitPreToolUseContext(body, client) {
|
|
6458
6948
|
emitContext(body, client, "PreToolUse");
|
|
6459
6949
|
}
|
|
6950
|
+
function defaultEmit(stdin, stateDir) {
|
|
6951
|
+
return (body, client) => {
|
|
6952
|
+
if (client === "antigravity") {
|
|
6953
|
+
const key = conversationKey(stdin);
|
|
6954
|
+
if (key) stashContext(key, body, stateDir);
|
|
6955
|
+
return;
|
|
6956
|
+
}
|
|
6957
|
+
emitPreToolUseContext(body, client);
|
|
6958
|
+
};
|
|
6959
|
+
}
|
|
6460
6960
|
var INTERESTED_TOOLS = /* @__PURE__ */ new Set([
|
|
6461
6961
|
"Edit",
|
|
6462
6962
|
"Write",
|
|
@@ -6471,13 +6971,17 @@ async function fetchRulesHook(deps = {}) {
|
|
|
6471
6971
|
const resolveTok = deps.resolveTokenFn ?? resolveToken;
|
|
6472
6972
|
const fetchRules = deps.fetchRulesFn ?? fetchBusinessRules;
|
|
6473
6973
|
const fetchSecRules = deps.fetchSecurityRulesFn ?? fetchSecurityRules;
|
|
6474
|
-
const emitFn = deps.emitFn ?? emitPreToolUseContext;
|
|
6475
6974
|
const usageNotifier = deps.usageNotifier ?? makeUsageNotifier();
|
|
6476
6975
|
const stdin = await readStdin();
|
|
6477
6976
|
const event = sniff(stdin);
|
|
6977
|
+
const emitFn = deps.emitFn ?? defaultEmit(stdin, deps.antigravityStateDir);
|
|
6478
6978
|
if (!INTERESTED_TOOLS.has(event.toolName)) return;
|
|
6479
6979
|
if (!event.filePath) return;
|
|
6480
6980
|
if (!hasModelChannel(event.client, "PreToolUse")) return;
|
|
6981
|
+
if (event.client === "antigravity" && (event.toolName === "Write" || event.toolName === "Edit" || event.toolName === "MultiEdit")) {
|
|
6982
|
+
const key = conversationKey(stdin);
|
|
6983
|
+
if (key) recordEdit(key, event.filePath, deps.antigravityStateDir);
|
|
6984
|
+
}
|
|
6481
6985
|
const config2 = loadConfig();
|
|
6482
6986
|
if (!config2) return;
|
|
6483
6987
|
const folder = sessionFolderOf(stdin, event.client);
|
|
@@ -6626,9 +7130,9 @@ var DIRECT_PROPOSE_DIRECTIVES = {
|
|
|
6626
7130
|
|
|
6627
7131
|
// src/hooks/runtime/self-update-check.ts
|
|
6628
7132
|
import { spawn } from "node:child_process";
|
|
6629
|
-
import { existsSync as existsSync11, readFileSync as
|
|
6630
|
-
import { homedir as
|
|
6631
|
-
import { join as
|
|
7133
|
+
import { existsSync as existsSync11, readFileSync as readFileSync10, rmSync as rmSync2, writeFileSync as writeFileSync7 } from "node:fs";
|
|
7134
|
+
import { homedir as homedir9 } from "node:os";
|
|
7135
|
+
import { join as join9 } from "node:path";
|
|
6632
7136
|
|
|
6633
7137
|
// src/hooks/runtime/semver.ts
|
|
6634
7138
|
function parseVersion(input2) {
|
|
@@ -6706,9 +7210,9 @@ function isValidRegistryVersion(value) {
|
|
|
6706
7210
|
}
|
|
6707
7211
|
async function selfUpdateCheck(deps) {
|
|
6708
7212
|
const now = deps.now ?? (() => Date.now());
|
|
6709
|
-
const dir = deps.cybeDir ??
|
|
6710
|
-
const throttlePath =
|
|
6711
|
-
const logPath =
|
|
7213
|
+
const dir = deps.cybeDir ?? join9(process.env.CYBEDEFEND_HOME ?? homedir9(), ".cybedefend");
|
|
7214
|
+
const throttlePath = join9(dir, "update-check.json");
|
|
7215
|
+
const logPath = join9(dir, "last-update.log");
|
|
6712
7216
|
const installMode = deps.installMode ?? (deps.runnerSource ? detectInstallMode(deps.runnerSource) : detectInstallMode(resolveScriptPath()));
|
|
6713
7217
|
const priorFailure = takeUpdateLogNotice(logPath);
|
|
6714
7218
|
const throttle = readThrottle(throttlePath);
|
|
@@ -6742,7 +7246,7 @@ function applyOrNotify(deps, installMode, latest, logPath) {
|
|
|
6742
7246
|
function readThrottle(path) {
|
|
6743
7247
|
try {
|
|
6744
7248
|
if (!existsSync11(path)) return null;
|
|
6745
|
-
const data = JSON.parse(
|
|
7249
|
+
const data = JSON.parse(readFileSync10(path, "utf8"));
|
|
6746
7250
|
if (typeof data.lastCheckedAt !== "number") return null;
|
|
6747
7251
|
return { lastCheckedAt: data.lastCheckedAt };
|
|
6748
7252
|
} catch {
|
|
@@ -6752,7 +7256,7 @@ function readThrottle(path) {
|
|
|
6752
7256
|
function writeThrottle(path, throttle) {
|
|
6753
7257
|
try {
|
|
6754
7258
|
ensureDirFor(path);
|
|
6755
|
-
|
|
7259
|
+
writeFileSync7(path, JSON.stringify(throttle) + "\n");
|
|
6756
7260
|
} catch {
|
|
6757
7261
|
}
|
|
6758
7262
|
}
|
|
@@ -6761,11 +7265,11 @@ function takeUpdateLogNotice(logPath) {
|
|
|
6761
7265
|
if (!existsSync11(logPath)) return null;
|
|
6762
7266
|
let parsed = {};
|
|
6763
7267
|
try {
|
|
6764
|
-
parsed = JSON.parse(
|
|
7268
|
+
parsed = JSON.parse(readFileSync10(logPath, "utf8"));
|
|
6765
7269
|
} catch {
|
|
6766
7270
|
parsed = {};
|
|
6767
7271
|
}
|
|
6768
|
-
|
|
7272
|
+
rmSync2(logPath, { force: true });
|
|
6769
7273
|
if (typeof parsed.exitCode === "number" && parsed.exitCode !== 0) {
|
|
6770
7274
|
return `\u26A0 vibedefend: last auto-update to ${parsed.to ?? "latest"} failed (exit ${parsed.exitCode}) \u2014 run \`vibedefend update --self\`.`;
|
|
6771
7275
|
}
|
|
@@ -6836,18 +7340,18 @@ function pmCommand(mode, spec) {
|
|
|
6836
7340
|
|
|
6837
7341
|
// src/hooks/runtime/hook-refresh-trigger.ts
|
|
6838
7342
|
import { spawn as spawn2 } from "node:child_process";
|
|
6839
|
-
import { existsSync as existsSync12, readFileSync as
|
|
6840
|
-
import { homedir as
|
|
6841
|
-
import { dirname as dirname6, join as
|
|
7343
|
+
import { existsSync as existsSync12, readFileSync as readFileSync11, writeFileSync as writeFileSync8 } from "node:fs";
|
|
7344
|
+
import { homedir as homedir10 } from "node:os";
|
|
7345
|
+
import { dirname as dirname6, join as join10 } from "node:path";
|
|
6842
7346
|
function maybeRefreshStaleWiring(deps) {
|
|
6843
7347
|
try {
|
|
6844
7348
|
const { config: config2, runnerVersion } = deps;
|
|
6845
7349
|
if (!config2.runnerSource || config2.installedVersion === runnerVersion) {
|
|
6846
7350
|
return false;
|
|
6847
7351
|
}
|
|
6848
|
-
const cliEntry =
|
|
7352
|
+
const cliEntry = join10(dirname6(dirname6(config2.runnerSource)), "bin", "vibedefend.js");
|
|
6849
7353
|
if (!(deps.exists ?? existsSync12)(cliEntry)) return false;
|
|
6850
|
-
const markerPath = deps.markerPath ??
|
|
7354
|
+
const markerPath = deps.markerPath ?? join10(process.env.CYBEDEFEND_HOME ?? homedir10(), ".cybedefend", "hook-refresh.json");
|
|
6851
7355
|
if (readMarkerVersion(markerPath) === runnerVersion) return false;
|
|
6852
7356
|
(deps.spawnRefresh ?? defaultSpawnRefresh)(cliEntry);
|
|
6853
7357
|
writeMarker(markerPath, runnerVersion);
|
|
@@ -6859,7 +7363,7 @@ function maybeRefreshStaleWiring(deps) {
|
|
|
6859
7363
|
function readMarkerVersion(path) {
|
|
6860
7364
|
try {
|
|
6861
7365
|
if (!existsSync12(path)) return null;
|
|
6862
|
-
const data = JSON.parse(
|
|
7366
|
+
const data = JSON.parse(readFileSync11(path, "utf8"));
|
|
6863
7367
|
return typeof data.version === "string" ? data.version : null;
|
|
6864
7368
|
} catch {
|
|
6865
7369
|
return null;
|
|
@@ -6868,7 +7372,7 @@ function readMarkerVersion(path) {
|
|
|
6868
7372
|
function writeMarker(path, version2) {
|
|
6869
7373
|
try {
|
|
6870
7374
|
ensureDirFor(path);
|
|
6871
|
-
|
|
7375
|
+
writeFileSync8(path, JSON.stringify({ version: version2, spawnedAt: Date.now() }) + "\n");
|
|
6872
7376
|
} catch {
|
|
6873
7377
|
}
|
|
6874
7378
|
}
|
|
@@ -6882,18 +7386,18 @@ function defaultSpawnRefresh(cliEntry) {
|
|
|
6882
7386
|
}
|
|
6883
7387
|
|
|
6884
7388
|
// src/version.ts
|
|
6885
|
-
import { readFileSync as
|
|
7389
|
+
import { readFileSync as readFileSync12 } from "node:fs";
|
|
6886
7390
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
6887
|
-
import { dirname as dirname7, join as
|
|
7391
|
+
import { dirname as dirname7, join as join11 } from "node:path";
|
|
6888
7392
|
var PKG_NAME = "@cybedefend/vibedefend";
|
|
6889
7393
|
function defaultPkgPath() {
|
|
6890
|
-
return
|
|
7394
|
+
return join11(dirname7(fileURLToPath3(import.meta.url)), "..", "package.json");
|
|
6891
7395
|
}
|
|
6892
7396
|
function readPackageMeta(opts = {}) {
|
|
6893
7397
|
if (typeof opts.bakedVersion === "string" && opts.bakedVersion.length > 0) {
|
|
6894
7398
|
return { name: PKG_NAME, version: opts.bakedVersion };
|
|
6895
7399
|
}
|
|
6896
|
-
const readFile = opts.readFile ?? ((p) =>
|
|
7400
|
+
const readFile = opts.readFile ?? ((p) => readFileSync12(p, "utf8"));
|
|
6897
7401
|
const pkgPath = opts.pkgPath ?? defaultPkgPath();
|
|
6898
7402
|
try {
|
|
6899
7403
|
return JSON.parse(readFile(pkgPath));
|
|
@@ -6902,7 +7406,7 @@ function readPackageMeta(opts = {}) {
|
|
|
6902
7406
|
}
|
|
6903
7407
|
}
|
|
6904
7408
|
var pkg = readPackageMeta({
|
|
6905
|
-
bakedVersion: true ? "1.
|
|
7409
|
+
bakedVersion: true ? "1.8.1" : void 0
|
|
6906
7410
|
});
|
|
6907
7411
|
|
|
6908
7412
|
// src/hooks/runtime/session-start.ts
|
|
@@ -6946,6 +7450,9 @@ async function sessionStartHook(deps = {}) {
|
|
|
6946
7450
|
}
|
|
6947
7451
|
if (sessionId) sessionStore.clear(sessionId);
|
|
6948
7452
|
const apiBase = process.env.CYBEDEFEND_API_BASE ?? configApiBase ?? config2.region.apiBase;
|
|
7453
|
+
if (event.client === "antigravity") {
|
|
7454
|
+
pruneStale(deps.antigravityStateDir);
|
|
7455
|
+
}
|
|
6949
7456
|
if (process.env.CYBEDEFEND_DRY_RUN === "1") {
|
|
6950
7457
|
emitFn(
|
|
6951
7458
|
`## CybeDefend session bootstrap (dry-run, client=${event.client})
|
|
@@ -6998,7 +7505,12 @@ async function sessionStartHook(deps = {}) {
|
|
|
6998
7505
|
" **before responding to the user request.**"
|
|
6999
7506
|
);
|
|
7000
7507
|
}
|
|
7001
|
-
const HARD_ENFORCEMENT_CLIENTS = /* @__PURE__ */ new Set([
|
|
7508
|
+
const HARD_ENFORCEMENT_CLIENTS = /* @__PURE__ */ new Set([
|
|
7509
|
+
"claude-code",
|
|
7510
|
+
"codex",
|
|
7511
|
+
"cursor",
|
|
7512
|
+
"antigravity"
|
|
7513
|
+
]);
|
|
7002
7514
|
lines.push("");
|
|
7003
7515
|
if (HARD_ENFORCEMENT_CLIENTS.has(event.client)) {
|
|
7004
7516
|
lines.push(
|
|
@@ -7036,23 +7548,23 @@ async function sessionStartHook(deps = {}) {
|
|
|
7036
7548
|
}
|
|
7037
7549
|
|
|
7038
7550
|
// src/hooks/runtime/session-review.ts
|
|
7039
|
-
import { existsSync as existsSync14, readFileSync as
|
|
7551
|
+
import { existsSync as existsSync14, readFileSync as readFileSync14 } from "node:fs";
|
|
7040
7552
|
|
|
7041
7553
|
// src/hooks/runtime/review-sessions.ts
|
|
7042
|
-
import { existsSync as existsSync13, mkdirSync as
|
|
7043
|
-
import { homedir as
|
|
7044
|
-
import { dirname as dirname8, join as
|
|
7554
|
+
import { existsSync as existsSync13, mkdirSync as mkdirSync7, readFileSync as readFileSync13, writeFileSync as writeFileSync9 } from "node:fs";
|
|
7555
|
+
import { homedir as homedir11 } from "node:os";
|
|
7556
|
+
import { dirname as dirname8, join as join12 } from "node:path";
|
|
7045
7557
|
var SESSIONS_CAP2 = 200;
|
|
7046
7558
|
function defaultStoreFile2() {
|
|
7047
|
-
const dir = process.env.CYBEDEFEND_BASELINE_DIR ??
|
|
7048
|
-
return
|
|
7559
|
+
const dir = process.env.CYBEDEFEND_BASELINE_DIR ?? join12(homedir11(), ".cybedefend");
|
|
7560
|
+
return join12(dir, "review-sessions.json");
|
|
7049
7561
|
}
|
|
7050
7562
|
var isCount = (n) => typeof n === "number" && Number.isInteger(n) && n >= 0;
|
|
7051
7563
|
function defaultReviewSessionStore(file2 = defaultStoreFile2(), now = Date.now) {
|
|
7052
7564
|
function load2() {
|
|
7053
7565
|
if (!existsSync13(file2)) return {};
|
|
7054
7566
|
try {
|
|
7055
|
-
const parsed = JSON.parse(
|
|
7567
|
+
const parsed = JSON.parse(readFileSync13(file2, "utf8"));
|
|
7056
7568
|
return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
|
|
7057
7569
|
} catch {
|
|
7058
7570
|
return {};
|
|
@@ -7060,8 +7572,8 @@ function defaultReviewSessionStore(file2 = defaultStoreFile2(), now = Date.now)
|
|
|
7060
7572
|
}
|
|
7061
7573
|
function save(map2) {
|
|
7062
7574
|
try {
|
|
7063
|
-
|
|
7064
|
-
|
|
7575
|
+
mkdirSync7(dirname8(file2), { recursive: true });
|
|
7576
|
+
writeFileSync9(file2, JSON.stringify(map2) + "\n", "utf8");
|
|
7065
7577
|
} catch {
|
|
7066
7578
|
}
|
|
7067
7579
|
}
|
|
@@ -7171,6 +7683,32 @@ async function sessionReviewHook(deps = {}) {
|
|
|
7171
7683
|
const config2 = loadConfig();
|
|
7172
7684
|
if (!config2) return;
|
|
7173
7685
|
if (!config2.hooks.enableSessionReview) return;
|
|
7686
|
+
if (event.client === "antigravity") {
|
|
7687
|
+
const key = conversationKey(stdin);
|
|
7688
|
+
const stateDir = deps.antigravityStateDir;
|
|
7689
|
+
if (!key || isReviewed(key, stateDir)) return;
|
|
7690
|
+
let { count, files } = readEdits(key, stateDir);
|
|
7691
|
+
if (process.env.CYBEDEFEND_DRY_RUN === "1") {
|
|
7692
|
+
count = parseInt(process.env.CYBEDEFEND_DRY_RUN_EDITS ?? "5", 10);
|
|
7693
|
+
}
|
|
7694
|
+
if (count === 0) return;
|
|
7695
|
+
if (count < resolveReviewThreshold(config2)) return;
|
|
7696
|
+
const folder2 = sessionFolderOf(stdin, "antigravity");
|
|
7697
|
+
if (isSessionInactive(stdin, { store: deps.sessionStore, cwd: folder2 })) return;
|
|
7698
|
+
const { projectId: projectId2 } = await (deps.resolveProject ?? resolveProjectIdWithApi)(folder2);
|
|
7699
|
+
if (!projectId2) return;
|
|
7700
|
+
const proposalMode2 = resolveProposalMode(config2);
|
|
7701
|
+
let body2 = composeReviewBody(count, "antigravity", "", proposalMode2);
|
|
7702
|
+
const withDiffScan2 = config2.hooks.enableDiffScan !== false;
|
|
7703
|
+
if (withDiffScan2) {
|
|
7704
|
+
body2 += "\n" + composeDiffScanBody(
|
|
7705
|
+
files.slice(0, CHANGED_FILES_MAX).map((f) => relativizePath(f, folder2))
|
|
7706
|
+
);
|
|
7707
|
+
}
|
|
7708
|
+
emitFn(body2, "antigravity", composeStopReason(withDiffScan2, proposalMode2));
|
|
7709
|
+
markReviewed(key, stateDir);
|
|
7710
|
+
return;
|
|
7711
|
+
}
|
|
7174
7712
|
const transcript = loadTranscript(stdin, readTranscriptFile);
|
|
7175
7713
|
const sessionId = sessionIdOf(stdin);
|
|
7176
7714
|
const store = sessionId ? deps.reviewStore ?? defaultReviewSessionStore() : null;
|
|
@@ -7247,7 +7785,7 @@ function loadTranscript(stdin, readFile) {
|
|
|
7247
7785
|
function defaultReadTranscript(path) {
|
|
7248
7786
|
if (!existsSync14(path)) return null;
|
|
7249
7787
|
try {
|
|
7250
|
-
return
|
|
7788
|
+
return readFileSync14(path, "utf8");
|
|
7251
7789
|
} catch {
|
|
7252
7790
|
return null;
|
|
7253
7791
|
}
|
|
@@ -7515,19 +8053,19 @@ async function preCompactHook(deps = {}) {
|
|
|
7515
8053
|
}
|
|
7516
8054
|
|
|
7517
8055
|
// src/hooks/runtime/user-prompt-submit.ts
|
|
7518
|
-
import { existsSync as existsSync15, mkdirSync as
|
|
7519
|
-
import { homedir as
|
|
7520
|
-
import { join as
|
|
8056
|
+
import { existsSync as existsSync15, mkdirSync as mkdirSync8, readFileSync as readFileSync15, writeFileSync as writeFileSync10 } from "node:fs";
|
|
8057
|
+
import { homedir as homedir12 } from "node:os";
|
|
8058
|
+
import { join as join13 } from "node:path";
|
|
7521
8059
|
var SESSIONS_CAP3 = 100;
|
|
7522
8060
|
function defaultSessionsFile() {
|
|
7523
|
-
const dir = process.env.CYBEDEFEND_BASELINE_DIR ??
|
|
7524
|
-
return
|
|
8061
|
+
const dir = process.env.CYBEDEFEND_BASELINE_DIR ?? join13(homedir12(), ".cybedefend");
|
|
8062
|
+
return join13(dir, "user-prompt-seen-sessions.json");
|
|
7525
8063
|
}
|
|
7526
8064
|
function defaultSessionTracker(file2 = defaultSessionsFile()) {
|
|
7527
8065
|
function load2() {
|
|
7528
8066
|
if (!existsSync15(file2)) return [];
|
|
7529
8067
|
try {
|
|
7530
|
-
const raw =
|
|
8068
|
+
const raw = readFileSync15(file2, "utf8");
|
|
7531
8069
|
const data = JSON.parse(raw);
|
|
7532
8070
|
if (!Array.isArray(data.sessions)) return [];
|
|
7533
8071
|
return data.sessions.filter((s) => typeof s === "string");
|
|
@@ -7544,8 +8082,8 @@ function defaultSessionTracker(file2 = defaultSessionsFile()) {
|
|
|
7544
8082
|
if (existing.includes(sessionId)) return;
|
|
7545
8083
|
const next = [...existing, sessionId].slice(-SESSIONS_CAP3);
|
|
7546
8084
|
try {
|
|
7547
|
-
|
|
7548
|
-
|
|
8085
|
+
mkdirSync8(join13(file2, ".."), { recursive: true });
|
|
8086
|
+
writeFileSync10(file2, JSON.stringify({ sessions: next }), "utf8");
|
|
7549
8087
|
} catch {
|
|
7550
8088
|
}
|
|
7551
8089
|
}
|
|
@@ -7633,6 +8171,20 @@ async function userPromptSubmitHook(deps = {}) {
|
|
|
7633
8171
|
}
|
|
7634
8172
|
}
|
|
7635
8173
|
|
|
8174
|
+
// src/hooks/runtime/pre-invocation.ts
|
|
8175
|
+
var STASH_SEPARATOR = "\n\n---\n\n";
|
|
8176
|
+
async function preInvocationHook(deps = {}) {
|
|
8177
|
+
const readStdin = deps.readStdin ?? readStdinJson;
|
|
8178
|
+
const stdin = await readStdin();
|
|
8179
|
+
if (!isAntigravityEnvelope(stdin)) return;
|
|
8180
|
+
const key = conversationKey(stdin);
|
|
8181
|
+
if (!key) return;
|
|
8182
|
+
const dir = deps.stateDir ?? antigravityStateDir();
|
|
8183
|
+
const bodies = drainContext(key, dir);
|
|
8184
|
+
if (bodies.length === 0) return;
|
|
8185
|
+
emitContext(bodies.join(STASH_SEPARATOR), "antigravity", "PreInvocation");
|
|
8186
|
+
}
|
|
8187
|
+
|
|
7636
8188
|
// src/guards-evaluator/glob.ts
|
|
7637
8189
|
function expandHome(pattern, homeDir) {
|
|
7638
8190
|
if (pattern === "~") return homeDir;
|
|
@@ -8364,7 +8916,7 @@ function buildCommandViews(raw) {
|
|
|
8364
8916
|
}
|
|
8365
8917
|
|
|
8366
8918
|
// src/guards-evaluator/redact.ts
|
|
8367
|
-
import { createHash as
|
|
8919
|
+
import { createHash as createHash3 } from "node:crypto";
|
|
8368
8920
|
var REDACTED = "[REDACTED]";
|
|
8369
8921
|
var PATTERNS = [
|
|
8370
8922
|
// 1. JWT — three base64url segments separated by dots
|
|
@@ -8476,7 +9028,7 @@ function redactScriptText(text) {
|
|
|
8476
9028
|
return redactTarget(masked, Number.MAX_SAFE_INTEGER);
|
|
8477
9029
|
}
|
|
8478
9030
|
function hashTarget(text) {
|
|
8479
|
-
return
|
|
9031
|
+
return createHash3("sha256").update(text, "utf8").digest("hex");
|
|
8480
9032
|
}
|
|
8481
9033
|
|
|
8482
9034
|
// src/guards-evaluator/evaluate.ts
|
|
@@ -11093,15 +11645,15 @@ function resolveCandidatePaths(rawPath, opts) {
|
|
|
11093
11645
|
// src/hooks/runtime/session-writes.ts
|
|
11094
11646
|
import {
|
|
11095
11647
|
existsSync as existsSync17,
|
|
11096
|
-
mkdirSync as
|
|
11097
|
-
readFileSync as
|
|
11098
|
-
renameSync,
|
|
11648
|
+
mkdirSync as mkdirSync9,
|
|
11649
|
+
readFileSync as readFileSync17,
|
|
11650
|
+
renameSync as renameSync2,
|
|
11099
11651
|
rmdirSync,
|
|
11100
11652
|
statSync as statSync3,
|
|
11101
|
-
writeFileSync as
|
|
11653
|
+
writeFileSync as writeFileSync11
|
|
11102
11654
|
} from "node:fs";
|
|
11103
|
-
import { homedir as
|
|
11104
|
-
import { join as
|
|
11655
|
+
import { homedir as homedir13 } from "node:os";
|
|
11656
|
+
import { join as join14, posix } from "node:path";
|
|
11105
11657
|
var DEFAULT_MAX_PATHS = 500;
|
|
11106
11658
|
var DEFAULT_SESSION_WRITES_TTL_MS = 4 * 60 * 60 * 1e3;
|
|
11107
11659
|
var SESSION_WRITES_FILE = "guards-session-writes.json";
|
|
@@ -11115,7 +11667,7 @@ function withLock(lockDir, fn) {
|
|
|
11115
11667
|
let held = false;
|
|
11116
11668
|
while (!held) {
|
|
11117
11669
|
try {
|
|
11118
|
-
|
|
11670
|
+
mkdirSync9(lockDir);
|
|
11119
11671
|
held = true;
|
|
11120
11672
|
} catch {
|
|
11121
11673
|
try {
|
|
@@ -11142,7 +11694,7 @@ function withLock(lockDir, fn) {
|
|
|
11142
11694
|
}
|
|
11143
11695
|
}
|
|
11144
11696
|
function defaultDir() {
|
|
11145
|
-
return process.env.CYBEDEFEND_BASELINE_DIR ??
|
|
11697
|
+
return process.env.CYBEDEFEND_BASELINE_DIR ?? join14(homedir13(), ".cybedefend");
|
|
11146
11698
|
}
|
|
11147
11699
|
function normalizePath(p) {
|
|
11148
11700
|
if (typeof p !== "string") return "";
|
|
@@ -11177,14 +11729,14 @@ function coerce(raw) {
|
|
|
11177
11729
|
}
|
|
11178
11730
|
function makeSessionWritesStore(opts = {}) {
|
|
11179
11731
|
const dir = opts.dir ?? defaultDir();
|
|
11180
|
-
const file2 =
|
|
11732
|
+
const file2 = join14(dir, SESSION_WRITES_FILE);
|
|
11181
11733
|
const now = opts.now ?? (() => Date.now());
|
|
11182
11734
|
const maxPaths = typeof opts.maxPaths === "number" && opts.maxPaths > 0 ? Math.floor(opts.maxPaths) : DEFAULT_MAX_PATHS;
|
|
11183
11735
|
const ttlMs = typeof opts.ttlMs === "number" && opts.ttlMs > 0 ? opts.ttlMs : DEFAULT_SESSION_WRITES_TTL_MS;
|
|
11184
11736
|
function readAll() {
|
|
11185
11737
|
if (!existsSync17(file2)) return {};
|
|
11186
11738
|
try {
|
|
11187
|
-
return coerce(JSON.parse(
|
|
11739
|
+
return coerce(JSON.parse(readFileSync17(file2, "utf8")));
|
|
11188
11740
|
} catch {
|
|
11189
11741
|
return {};
|
|
11190
11742
|
}
|
|
@@ -11199,10 +11751,10 @@ function makeSessionWritesStore(opts = {}) {
|
|
|
11199
11751
|
}
|
|
11200
11752
|
function writeAll(all) {
|
|
11201
11753
|
try {
|
|
11202
|
-
if (!existsSync17(dir))
|
|
11754
|
+
if (!existsSync17(dir)) mkdirSync9(dir, { recursive: true });
|
|
11203
11755
|
const tmp = `${file2}.${process.pid}.tmp`;
|
|
11204
|
-
|
|
11205
|
-
|
|
11756
|
+
writeFileSync11(tmp, JSON.stringify(all), "utf8");
|
|
11757
|
+
renameSync2(tmp, file2);
|
|
11206
11758
|
} catch {
|
|
11207
11759
|
}
|
|
11208
11760
|
}
|
|
@@ -11212,7 +11764,7 @@ function makeSessionWritesStore(opts = {}) {
|
|
|
11212
11764
|
const usable = paths.filter(isUsable);
|
|
11213
11765
|
if (usable.length === 0) return;
|
|
11214
11766
|
try {
|
|
11215
|
-
if (!existsSync17(dir))
|
|
11767
|
+
if (!existsSync17(dir)) mkdirSync9(dir, { recursive: true });
|
|
11216
11768
|
withLock(`${file2}.lock`, () => {
|
|
11217
11769
|
const t = now();
|
|
11218
11770
|
const all = pruneExpired(readAll(), t);
|
|
@@ -11528,10 +12080,10 @@ function nearMiss(req, rule) {
|
|
|
11528
12080
|
import { isAbsolute as isAbsolute6, resolve as resolvePath4 } from "node:path";
|
|
11529
12081
|
|
|
11530
12082
|
// src/hooks/runtime/guard-rules-cache.ts
|
|
11531
|
-
import { readFileSync as
|
|
12083
|
+
import { readFileSync as readFileSync18, writeFileSync as writeFileSync12, existsSync as existsSync18, mkdirSync as mkdirSync10 } from "node:fs";
|
|
11532
12084
|
import { dirname as dirname9 } from "node:path";
|
|
11533
|
-
import { homedir as
|
|
11534
|
-
import { join as
|
|
12085
|
+
import { homedir as homedir14 } from "node:os";
|
|
12086
|
+
import { join as join15 } from "node:path";
|
|
11535
12087
|
|
|
11536
12088
|
// node_modules/.pnpm/zod@4.6.7/node_modules/zod/v4/classic/external.js
|
|
11537
12089
|
var external_exports = {};
|
|
@@ -31338,7 +31890,7 @@ function retryAfterOf(e) {
|
|
|
31338
31890
|
}
|
|
31339
31891
|
|
|
31340
31892
|
// src/hooks/runtime/retry-policy.ts
|
|
31341
|
-
import { createHash as
|
|
31893
|
+
import { createHash as createHash4 } from "node:crypto";
|
|
31342
31894
|
var UNAUTHORIZED_BACKOFF_MS = [
|
|
31343
31895
|
6e4,
|
|
31344
31896
|
5 * 6e4,
|
|
@@ -31364,12 +31916,12 @@ function unauthorizedBackoffMs(consecutive) {
|
|
|
31364
31916
|
return UNAUTHORIZED_BACKOFF_MS[index];
|
|
31365
31917
|
}
|
|
31366
31918
|
function tokenFingerprint(token) {
|
|
31367
|
-
return
|
|
31919
|
+
return createHash4("sha256").update(token).digest("hex").slice(0, 16);
|
|
31368
31920
|
}
|
|
31369
31921
|
|
|
31370
31922
|
// src/hooks/runtime/guard-rules-cache.ts
|
|
31371
|
-
var DEFAULT_CACHE_FILE =
|
|
31372
|
-
|
|
31923
|
+
var DEFAULT_CACHE_FILE = join15(
|
|
31924
|
+
homedir14(),
|
|
31373
31925
|
".cybedefend",
|
|
31374
31926
|
"guards-cache.json"
|
|
31375
31927
|
);
|
|
@@ -31444,7 +31996,7 @@ function reportDroppedRules(dropped) {
|
|
|
31444
31996
|
}
|
|
31445
31997
|
function makeGuardRulesCache(opts) {
|
|
31446
31998
|
const cacheFile = opts.cacheFile ?? DEFAULT_CACHE_FILE;
|
|
31447
|
-
const failuresFile = opts.failuresFile ??
|
|
31999
|
+
const failuresFile = opts.failuresFile ?? join15(dirname9(cacheFile), "guards-cache-failures.json");
|
|
31448
32000
|
const staleSec = opts.staleSec ?? DEFAULT_STALE_SEC;
|
|
31449
32001
|
const fetchFn = opts.fetchFn;
|
|
31450
32002
|
const clock = opts.now ?? Date.now;
|
|
@@ -31549,7 +32101,7 @@ function makeGuardRulesCache(opts) {
|
|
|
31549
32101
|
function readCache(projectId) {
|
|
31550
32102
|
if (!existsSync18(cacheFile)) return null;
|
|
31551
32103
|
try {
|
|
31552
|
-
const raw =
|
|
32104
|
+
const raw = readFileSync18(cacheFile, "utf8");
|
|
31553
32105
|
const data = JSON.parse(raw);
|
|
31554
32106
|
if (data.projectId !== projectId) return null;
|
|
31555
32107
|
return data;
|
|
@@ -31560,7 +32112,7 @@ function makeGuardRulesCache(opts) {
|
|
|
31560
32112
|
function readFailures() {
|
|
31561
32113
|
try {
|
|
31562
32114
|
if (!existsSync18(failuresFile)) return {};
|
|
31563
|
-
const parsed = JSON.parse(
|
|
32115
|
+
const parsed = JSON.parse(readFileSync18(failuresFile, "utf8"));
|
|
31564
32116
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
31565
32117
|
return {};
|
|
31566
32118
|
}
|
|
@@ -31582,7 +32134,7 @@ function makeGuardRulesCache(opts) {
|
|
|
31582
32134
|
if (now - f.at > FAILURE_RETENTION_MS) delete failures[projectId];
|
|
31583
32135
|
}
|
|
31584
32136
|
ensureDirFor2(failuresFile);
|
|
31585
|
-
|
|
32137
|
+
writeFileSync12(failuresFile, JSON.stringify(failures), "utf8");
|
|
31586
32138
|
} catch {
|
|
31587
32139
|
}
|
|
31588
32140
|
}
|
|
@@ -31593,7 +32145,7 @@ function makeGuardRulesCache(opts) {
|
|
|
31593
32145
|
function writeCache(entry) {
|
|
31594
32146
|
try {
|
|
31595
32147
|
ensureDirFor2(cacheFile);
|
|
31596
|
-
|
|
32148
|
+
writeFileSync12(cacheFile, JSON.stringify(entry), "utf8");
|
|
31597
32149
|
} catch {
|
|
31598
32150
|
}
|
|
31599
32151
|
}
|
|
@@ -31602,7 +32154,7 @@ function makeGuardRulesCache(opts) {
|
|
|
31602
32154
|
function ensureDirFor2(filePath) {
|
|
31603
32155
|
const dir = dirname9(filePath);
|
|
31604
32156
|
if (!existsSync18(dir)) {
|
|
31605
|
-
|
|
32157
|
+
mkdirSync10(dir, { recursive: true });
|
|
31606
32158
|
}
|
|
31607
32159
|
}
|
|
31608
32160
|
var DEFAULT_TIMEOUT_MS2 = 8e3;
|
|
@@ -31742,11 +32294,11 @@ function detectPromptInjection(text) {
|
|
|
31742
32294
|
}
|
|
31743
32295
|
|
|
31744
32296
|
// src/hooks/runtime/judge-cache.ts
|
|
31745
|
-
import { readFileSync as
|
|
31746
|
-
import { dirname as dirname10, join as
|
|
31747
|
-
import { homedir as
|
|
31748
|
-
var DEFAULT_JUDGE_CACHE_FILE =
|
|
31749
|
-
|
|
32297
|
+
import { readFileSync as readFileSync19, writeFileSync as writeFileSync13, existsSync as existsSync19, mkdirSync as mkdirSync11 } from "node:fs";
|
|
32298
|
+
import { dirname as dirname10, join as join16 } from "node:path";
|
|
32299
|
+
import { homedir as homedir15 } from "node:os";
|
|
32300
|
+
var DEFAULT_JUDGE_CACHE_FILE = join16(
|
|
32301
|
+
homedir15(),
|
|
31750
32302
|
".cybedefend",
|
|
31751
32303
|
"guards-judge-cache.json"
|
|
31752
32304
|
);
|
|
@@ -31759,7 +32311,7 @@ function makeJudgeCache(opts = {}) {
|
|
|
31759
32311
|
function readAll() {
|
|
31760
32312
|
if (!existsSync19(cacheFile)) return {};
|
|
31761
32313
|
try {
|
|
31762
|
-
return JSON.parse(
|
|
32314
|
+
return JSON.parse(readFileSync19(cacheFile, "utf8"));
|
|
31763
32315
|
} catch {
|
|
31764
32316
|
return {};
|
|
31765
32317
|
}
|
|
@@ -31783,7 +32335,7 @@ function makeJudgeCache(opts = {}) {
|
|
|
31783
32335
|
for (const k of keys.slice(0, Math.max(0, keys.length - maxEntries))) delete all[k];
|
|
31784
32336
|
}
|
|
31785
32337
|
ensureDirFor3(cacheFile);
|
|
31786
|
-
|
|
32338
|
+
writeFileSync13(cacheFile, JSON.stringify(all), "utf8");
|
|
31787
32339
|
} catch {
|
|
31788
32340
|
}
|
|
31789
32341
|
}
|
|
@@ -31792,34 +32344,34 @@ function makeJudgeCache(opts = {}) {
|
|
|
31792
32344
|
function ensureDirFor3(filePath) {
|
|
31793
32345
|
const dir = dirname10(filePath);
|
|
31794
32346
|
if (!existsSync19(dir)) {
|
|
31795
|
-
|
|
32347
|
+
mkdirSync11(dir, { recursive: true });
|
|
31796
32348
|
}
|
|
31797
32349
|
}
|
|
31798
32350
|
|
|
31799
32351
|
// src/hooks/runtime/guard-check.ts
|
|
31800
32352
|
import { spawn as spawn3 } from "node:child_process";
|
|
31801
|
-
import { homedir as
|
|
31802
|
-
import { join as
|
|
32353
|
+
import { homedir as homedir18 } from "node:os";
|
|
32354
|
+
import { join as join19 } from "node:path";
|
|
31803
32355
|
|
|
31804
32356
|
// src/hooks/runtime/guard-violations-buffer.ts
|
|
31805
32357
|
import {
|
|
31806
|
-
appendFileSync,
|
|
31807
|
-
closeSync as
|
|
32358
|
+
appendFileSync as appendFileSync2,
|
|
32359
|
+
closeSync as closeSync3,
|
|
31808
32360
|
existsSync as existsSync20,
|
|
31809
|
-
openSync as
|
|
31810
|
-
readFileSync as
|
|
31811
|
-
writeFileSync as
|
|
31812
|
-
writeSync,
|
|
31813
|
-
mkdirSync as
|
|
31814
|
-
rmSync as
|
|
32361
|
+
openSync as openSync3,
|
|
32362
|
+
readFileSync as readFileSync20,
|
|
32363
|
+
writeFileSync as writeFileSync14,
|
|
32364
|
+
writeSync as writeSync3,
|
|
32365
|
+
mkdirSync as mkdirSync12,
|
|
32366
|
+
rmSync as rmSync3,
|
|
31815
32367
|
statSync as statSync4,
|
|
31816
|
-
utimesSync
|
|
32368
|
+
utimesSync as utimesSync2
|
|
31817
32369
|
} from "node:fs";
|
|
31818
32370
|
import { dirname as dirname11 } from "node:path";
|
|
31819
|
-
import { homedir as
|
|
31820
|
-
import { join as
|
|
31821
|
-
var DEFAULT_BUFFER_FILE =
|
|
31822
|
-
|
|
32371
|
+
import { homedir as homedir16 } from "node:os";
|
|
32372
|
+
import { join as join17 } from "node:path";
|
|
32373
|
+
var DEFAULT_BUFFER_FILE = join17(
|
|
32374
|
+
homedir16(),
|
|
31823
32375
|
".cybedefend",
|
|
31824
32376
|
"guards-violations-buffer.jsonl"
|
|
31825
32377
|
);
|
|
@@ -31830,8 +32382,8 @@ var MAX_RECORD_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
|
31830
32382
|
var FLUSH_LOCK_STALE_MS = 6e4;
|
|
31831
32383
|
function makeViolationsBuffer(opts = {}) {
|
|
31832
32384
|
const bufferFile = opts.bufferFile ?? DEFAULT_BUFFER_FILE;
|
|
31833
|
-
const holdsFile = opts.holdsFile ??
|
|
31834
|
-
const lockFile = opts.lockFile ??
|
|
32385
|
+
const holdsFile = opts.holdsFile ?? join17(dirname11(bufferFile), "guards-violations-holds.json");
|
|
32386
|
+
const lockFile = opts.lockFile ?? join17(dirname11(bufferFile), "guards-violations-flush.lock");
|
|
31835
32387
|
const now = opts.now ?? Date.now;
|
|
31836
32388
|
function bufferViolation2(ctx, v) {
|
|
31837
32389
|
const record2 = {
|
|
@@ -31841,7 +32393,7 @@ function makeViolationsBuffer(opts = {}) {
|
|
|
31841
32393
|
};
|
|
31842
32394
|
try {
|
|
31843
32395
|
ensureDirFor4(bufferFile);
|
|
31844
|
-
|
|
32396
|
+
appendFileSync2(bufferFile, JSON.stringify(record2) + "\n", "utf8");
|
|
31845
32397
|
} catch {
|
|
31846
32398
|
}
|
|
31847
32399
|
}
|
|
@@ -31923,7 +32475,7 @@ function makeViolationsBuffer(opts = {}) {
|
|
|
31923
32475
|
writeHolds(holds);
|
|
31924
32476
|
try {
|
|
31925
32477
|
const serialised = failed.map((r) => JSON.stringify(r) + "\n").join("");
|
|
31926
|
-
|
|
32478
|
+
writeFileSync14(bufferFile, serialised + appendedSince(snapshot.bytes), "utf8");
|
|
31927
32479
|
} catch {
|
|
31928
32480
|
}
|
|
31929
32481
|
}
|
|
@@ -31945,7 +32497,7 @@ function makeViolationsBuffer(opts = {}) {
|
|
|
31945
32497
|
}
|
|
31946
32498
|
function readBuffer() {
|
|
31947
32499
|
try {
|
|
31948
|
-
const raw =
|
|
32500
|
+
const raw = readFileSync20(bufferFile);
|
|
31949
32501
|
return { content: raw.toString("utf8"), bytes: raw.length };
|
|
31950
32502
|
} catch {
|
|
31951
32503
|
return null;
|
|
@@ -31953,7 +32505,7 @@ function makeViolationsBuffer(opts = {}) {
|
|
|
31953
32505
|
}
|
|
31954
32506
|
function appendedSince(bytes) {
|
|
31955
32507
|
try {
|
|
31956
|
-
const raw =
|
|
32508
|
+
const raw = readFileSync20(bufferFile);
|
|
31957
32509
|
return raw.length > bytes ? raw.subarray(bytes).toString("utf8") : "";
|
|
31958
32510
|
} catch {
|
|
31959
32511
|
return "";
|
|
@@ -31967,18 +32519,18 @@ function makeViolationsBuffer(opts = {}) {
|
|
|
31967
32519
|
}
|
|
31968
32520
|
for (let attempt = 0; attempt < 2; attempt++) {
|
|
31969
32521
|
try {
|
|
31970
|
-
const fd =
|
|
32522
|
+
const fd = openSync3(lockFile, "wx");
|
|
31971
32523
|
try {
|
|
31972
|
-
|
|
32524
|
+
writeSync3(fd, String(process.pid));
|
|
31973
32525
|
} finally {
|
|
31974
|
-
|
|
32526
|
+
closeSync3(fd);
|
|
31975
32527
|
}
|
|
31976
32528
|
return true;
|
|
31977
32529
|
} catch (e) {
|
|
31978
32530
|
if (e.code !== "EEXIST") return false;
|
|
31979
32531
|
if (!lockIsStale()) return false;
|
|
31980
32532
|
try {
|
|
31981
|
-
|
|
32533
|
+
rmSync3(lockFile, { force: true });
|
|
31982
32534
|
} catch {
|
|
31983
32535
|
return false;
|
|
31984
32536
|
}
|
|
@@ -31996,26 +32548,26 @@ function makeViolationsBuffer(opts = {}) {
|
|
|
31996
32548
|
function touchLock() {
|
|
31997
32549
|
try {
|
|
31998
32550
|
const t = /* @__PURE__ */ new Date();
|
|
31999
|
-
|
|
32551
|
+
utimesSync2(lockFile, t, t);
|
|
32000
32552
|
} catch {
|
|
32001
32553
|
}
|
|
32002
32554
|
}
|
|
32003
32555
|
function releaseLock() {
|
|
32004
32556
|
try {
|
|
32005
|
-
|
|
32557
|
+
rmSync3(lockFile, { force: true });
|
|
32006
32558
|
} catch {
|
|
32007
32559
|
}
|
|
32008
32560
|
}
|
|
32009
32561
|
function liftHolds() {
|
|
32010
32562
|
try {
|
|
32011
|
-
|
|
32563
|
+
rmSync3(holdsFile, { force: true });
|
|
32012
32564
|
} catch {
|
|
32013
32565
|
}
|
|
32014
32566
|
}
|
|
32015
32567
|
function readHolds() {
|
|
32016
32568
|
try {
|
|
32017
32569
|
if (!existsSync20(holdsFile)) return {};
|
|
32018
|
-
const parsed = JSON.parse(
|
|
32570
|
+
const parsed = JSON.parse(readFileSync20(holdsFile, "utf8"));
|
|
32019
32571
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
32020
32572
|
return {};
|
|
32021
32573
|
}
|
|
@@ -32040,11 +32592,11 @@ function makeViolationsBuffer(opts = {}) {
|
|
|
32040
32592
|
function writeHolds(holds) {
|
|
32041
32593
|
try {
|
|
32042
32594
|
if (Object.keys(holds).length === 0) {
|
|
32043
|
-
|
|
32595
|
+
rmSync3(holdsFile, { force: true });
|
|
32044
32596
|
return;
|
|
32045
32597
|
}
|
|
32046
32598
|
ensureDirFor4(holdsFile);
|
|
32047
|
-
|
|
32599
|
+
writeFileSync14(holdsFile, JSON.stringify(holds), "utf8");
|
|
32048
32600
|
} catch {
|
|
32049
32601
|
}
|
|
32050
32602
|
}
|
|
@@ -32077,7 +32629,7 @@ function capRecords(records, now) {
|
|
|
32077
32629
|
function ensureDirFor4(filePath) {
|
|
32078
32630
|
const dir = dirname11(filePath);
|
|
32079
32631
|
if (!existsSync20(dir)) {
|
|
32080
|
-
|
|
32632
|
+
mkdirSync12(dir, { recursive: true });
|
|
32081
32633
|
}
|
|
32082
32634
|
}
|
|
32083
32635
|
var _defaultBuffer = makeViolationsBuffer();
|
|
@@ -32086,9 +32638,9 @@ var flushViolations = _defaultBuffer.flushViolations.bind(_defaultBuffer);
|
|
|
32086
32638
|
var liftViolationHolds = _defaultBuffer.liftHolds.bind(_defaultBuffer);
|
|
32087
32639
|
|
|
32088
32640
|
// src/hooks/runtime/unmapped-tools.ts
|
|
32089
|
-
import { existsSync as existsSync21, mkdirSync as
|
|
32090
|
-
import { dirname as dirname12, join as
|
|
32091
|
-
import { homedir as
|
|
32641
|
+
import { existsSync as existsSync21, mkdirSync as mkdirSync13, readFileSync as readFileSync21, writeFileSync as writeFileSync15 } from "node:fs";
|
|
32642
|
+
import { dirname as dirname12, join as join18 } from "node:path";
|
|
32643
|
+
import { homedir as homedir17 } from "node:os";
|
|
32092
32644
|
var TARGETLESS_TOOL_RE = /^(?:ToolSearch|TodoRead|TodoWrite|Task|Agent|AskUserQuestion|Skill|SlashCommand|EnterPlanMode|ExitPlanMode|EnterWorktree|ExitWorktree|BashOutput|KillShell|KillBash|Monitor|ListMcpResourcesTool|ReadMcpResourceTool|ReadMcpResourceDirTool|ScheduleWakeup|PushNotification|CronCreate|CronDelete|CronList|SendMessage|ListAgents|TaskOutput|TaskStop|ReportFindings|Workflow)$/;
|
|
32093
32645
|
var OWN_MCP_TOOL_RE = /^mcp__cybedefend(?:-[A-Za-z0-9_-]+)?__/;
|
|
32094
32646
|
function isTargetlessTool(tool) {
|
|
@@ -32100,13 +32652,13 @@ function strictUnmappedPolicy() {
|
|
|
32100
32652
|
}
|
|
32101
32653
|
var MAX_TOOLS = 200;
|
|
32102
32654
|
function defaultUnmappedToolsFile() {
|
|
32103
|
-
const dir = process.env.CYBEDEFEND_BASELINE_DIR ??
|
|
32104
|
-
return
|
|
32655
|
+
const dir = process.env.CYBEDEFEND_BASELINE_DIR ?? join18(homedir17(), ".cybedefend");
|
|
32656
|
+
return join18(dir, "guards-unmapped-tools.json");
|
|
32105
32657
|
}
|
|
32106
32658
|
function load(file2) {
|
|
32107
32659
|
try {
|
|
32108
32660
|
if (!existsSync21(file2)) return { tools: {} };
|
|
32109
|
-
const parsed = JSON.parse(
|
|
32661
|
+
const parsed = JSON.parse(readFileSync21(file2, "utf8"));
|
|
32110
32662
|
if (!parsed || typeof parsed !== "object" || typeof parsed.tools !== "object" || !parsed.tools) {
|
|
32111
32663
|
return { tools: {} };
|
|
32112
32664
|
}
|
|
@@ -32130,8 +32682,8 @@ function makeUnmappedToolTelemetry(file2 = defaultUnmappedToolsFile()) {
|
|
|
32130
32682
|
if (names.length > MAX_TOOLS) {
|
|
32131
32683
|
names.sort((a, b) => data.tools[a].lastSeen.localeCompare(data.tools[b].lastSeen)).slice(0, names.length - MAX_TOOLS).forEach((n) => delete data.tools[n]);
|
|
32132
32684
|
}
|
|
32133
|
-
|
|
32134
|
-
|
|
32685
|
+
mkdirSync13(dirname12(file2), { recursive: true });
|
|
32686
|
+
writeFileSync15(file2, JSON.stringify(data, null, 2) + "\n", "utf8");
|
|
32135
32687
|
} catch {
|
|
32136
32688
|
}
|
|
32137
32689
|
}
|
|
@@ -32171,9 +32723,16 @@ function extractWriteTargets(req, rawCommand) {
|
|
|
32171
32723
|
}
|
|
32172
32724
|
return [];
|
|
32173
32725
|
}
|
|
32174
|
-
function normalizeToolName(tool) {
|
|
32726
|
+
function normalizeToolName(tool, client) {
|
|
32175
32727
|
if (!tool) return "";
|
|
32176
32728
|
const t = (tool.split(/[\r\n]/, 1)[0] ?? "").trim();
|
|
32729
|
+
if (client === "antigravity") {
|
|
32730
|
+
if (/^view_file$/i.test(t)) return "Read";
|
|
32731
|
+
if (/^(write_to_file|write_file)$/i.test(t)) return "Write";
|
|
32732
|
+
if (/^(replace_file_content|edit_file)$/i.test(t)) return "Edit";
|
|
32733
|
+
if (/^multi_replace_file_content$/i.test(t)) return "MultiEdit";
|
|
32734
|
+
if (/^read_url_content$/i.test(t)) return "WebFetch";
|
|
32735
|
+
}
|
|
32177
32736
|
if (/^(read|read_file|cat)$/i.test(t)) return "Read";
|
|
32178
32737
|
if (/^(write|create_file|new_file)$/i.test(t)) return "Write";
|
|
32179
32738
|
if (/^(edit|apply_patch|str_replace_editor)$/i.test(t)) return "Edit";
|
|
@@ -32189,11 +32748,11 @@ function appendDebugLog(entry) {
|
|
|
32189
32748
|
try {
|
|
32190
32749
|
const homeDir = process.env.HOME ?? process.env.USERPROFILE ?? "";
|
|
32191
32750
|
if (!homeDir) return;
|
|
32192
|
-
const { mkdirSync:
|
|
32193
|
-
const { join:
|
|
32194
|
-
const dir =
|
|
32195
|
-
|
|
32196
|
-
|
|
32751
|
+
const { mkdirSync: mkdirSync14, appendFileSync: appendFileSync3 } = __require("node:fs");
|
|
32752
|
+
const { join: join20 } = __require("node:path");
|
|
32753
|
+
const dir = join20(homeDir, ".cybedefend");
|
|
32754
|
+
mkdirSync14(dir, { recursive: true });
|
|
32755
|
+
appendFileSync3(join20(dir, "hook-debug.log"), entry + "\n", "utf8");
|
|
32197
32756
|
} catch {
|
|
32198
32757
|
}
|
|
32199
32758
|
}
|
|
@@ -32208,9 +32767,63 @@ function debugLog(entry) {
|
|
|
32208
32767
|
}
|
|
32209
32768
|
}
|
|
32210
32769
|
var UNNAMED_TOOL = "<unnamed>";
|
|
32770
|
+
function sniffCaller(envelope) {
|
|
32771
|
+
try {
|
|
32772
|
+
return sniff(envelope);
|
|
32773
|
+
} catch {
|
|
32774
|
+
}
|
|
32775
|
+
let client = "unknown";
|
|
32776
|
+
try {
|
|
32777
|
+
client = detectClient(envelope);
|
|
32778
|
+
} catch {
|
|
32779
|
+
}
|
|
32780
|
+
const rawTool = client === "antigravity" && isRecord(envelope.toolCall) ? envelope.toolCall.name : envelope?.tool_name;
|
|
32781
|
+
return {
|
|
32782
|
+
client,
|
|
32783
|
+
toolName: typeof rawTool === "string" ? rawTool : "",
|
|
32784
|
+
filePath: "",
|
|
32785
|
+
filePaths: [],
|
|
32786
|
+
newContent: "",
|
|
32787
|
+
raw: envelope
|
|
32788
|
+
};
|
|
32789
|
+
}
|
|
32211
32790
|
function argvToCommandLine(argv) {
|
|
32212
32791
|
return argv.map((a) => /^[A-Za-z0-9_./=:@%+,-]+$/.test(a) ? a : `'${a.replace(/'/g, "'\\''")}'`).join(" ");
|
|
32213
32792
|
}
|
|
32793
|
+
var MCP_SERVER_NAME_RE = /^[A-Za-z0-9]+(?:[-_][A-Za-z0-9]+)*$/;
|
|
32794
|
+
var MCP_SERVER_NAME_MAX = 64;
|
|
32795
|
+
var MCP_TOOL_NAME_RE = /^[A-Za-z0-9]+(?:[-_.][A-Za-z0-9]+)*$/;
|
|
32796
|
+
var MCP_TOOL_NAME_MAX = 128;
|
|
32797
|
+
function isRecord(v) {
|
|
32798
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
32799
|
+
}
|
|
32800
|
+
function readAntigravityCall(envelope) {
|
|
32801
|
+
const toolCall = isRecord(envelope.toolCall) ? envelope.toolCall : {};
|
|
32802
|
+
const args = isRecord(toolCall.args) ? toolCall.args : {};
|
|
32803
|
+
const str3 = (v) => typeof v === "string" ? v : void 0;
|
|
32804
|
+
const name = str3(toolCall.name);
|
|
32805
|
+
let tool = name;
|
|
32806
|
+
const server = str3(args.ServerName);
|
|
32807
|
+
const mcpTool = str3(args.ToolName);
|
|
32808
|
+
if (tool === "call_mcp_tool" && server !== void 0 && mcpTool !== void 0 && server.length <= MCP_SERVER_NAME_MAX && MCP_SERVER_NAME_RE.test(server) && mcpTool.length <= MCP_TOOL_NAME_MAX && MCP_TOOL_NAME_RE.test(mcpTool)) {
|
|
32809
|
+
tool = `mcp__${server}__${mcpTool}`;
|
|
32810
|
+
}
|
|
32811
|
+
const params = {};
|
|
32812
|
+
const filePath = antigravityFilePathArg(name ?? "", args);
|
|
32813
|
+
if (filePath) params.file_path = filePath;
|
|
32814
|
+
const command = str3(args.CommandLine);
|
|
32815
|
+
if (command !== void 0) params.command = command;
|
|
32816
|
+
const url2 = str3(args.Url);
|
|
32817
|
+
if (url2 !== void 0) params.url = url2;
|
|
32818
|
+
let classifiedTool;
|
|
32819
|
+
let extraFilePaths = [];
|
|
32820
|
+
if (name !== void 0 && filePath && !ANTIGRAVITY_KNOWN_TOOLS.has(name)) {
|
|
32821
|
+
classifiedTool = classifyUnknownAntigravityTool(args);
|
|
32822
|
+
extraFilePaths = antigravityAllPathArgs(args).filter((p) => p !== filePath);
|
|
32823
|
+
}
|
|
32824
|
+
const cwd = typeof args.Cwd === "string" && args.Cwd.length > 0 ? args.Cwd : sessionFolderOf(envelope, "antigravity");
|
|
32825
|
+
return { tool, classifiedTool, params, extraFilePaths, cwd, argKeys: Object.keys(args) };
|
|
32826
|
+
}
|
|
32214
32827
|
function commandField(params) {
|
|
32215
32828
|
const v = params.command;
|
|
32216
32829
|
if (typeof v === "string") return v;
|
|
@@ -32219,40 +32832,67 @@ function commandField(params) {
|
|
|
32219
32832
|
}
|
|
32220
32833
|
return null;
|
|
32221
32834
|
}
|
|
32222
|
-
function
|
|
32223
|
-
const
|
|
32224
|
-
|
|
32835
|
+
function windsurfToolCall(envelope) {
|
|
32836
|
+
const ev = sniffCaller(envelope);
|
|
32837
|
+
switch (ev.toolName) {
|
|
32838
|
+
case "Bash":
|
|
32839
|
+
return { rawTool: ev.toolName, params: { command: ev.newContent } };
|
|
32840
|
+
case "Read":
|
|
32841
|
+
case "Write":
|
|
32842
|
+
return { rawTool: ev.toolName, params: { file_path: ev.filePath } };
|
|
32843
|
+
default:
|
|
32844
|
+
return { rawTool: ev.toolName, params: {} };
|
|
32845
|
+
}
|
|
32846
|
+
}
|
|
32847
|
+
function fileMapping(agent, tool, params, homeDir, cwd, rawTool, extraFilePaths) {
|
|
32848
|
+
const filePath = typeof params.file_path === "string" ? params.file_path : typeof params.path === "string" ? params.path : null;
|
|
32849
|
+
if (!filePath) return { kind: "unmapped", tool: rawTool ?? UNNAMED_TOOL };
|
|
32850
|
+
const request = {
|
|
32851
|
+
agent,
|
|
32852
|
+
tool,
|
|
32853
|
+
target: { type: "file", path: filePath },
|
|
32854
|
+
homeDir,
|
|
32855
|
+
cwd
|
|
32856
|
+
};
|
|
32857
|
+
if (extraFilePaths.length === 0) return { kind: "mapped", request };
|
|
32858
|
+
return {
|
|
32859
|
+
kind: "mapped",
|
|
32860
|
+
request,
|
|
32861
|
+
additionalRequests: extraFilePaths.map((path) => ({
|
|
32862
|
+
agent,
|
|
32863
|
+
tool,
|
|
32864
|
+
target: { type: "file", path },
|
|
32865
|
+
homeDir,
|
|
32866
|
+
cwd
|
|
32867
|
+
}))
|
|
32868
|
+
};
|
|
32869
|
+
}
|
|
32870
|
+
function mapEnvelope(envelope, agent = sniffCaller(envelope).client) {
|
|
32871
|
+
const antigravity = agent === "antigravity" ? readAntigravityCall(envelope) : null;
|
|
32872
|
+
const windsurf = agent === "windsurf" ? windsurfToolCall(envelope) : null;
|
|
32873
|
+
const rawTool = antigravity ? antigravity.tool : windsurf ? windsurf.rawTool : typeof envelope.tool_name === "string" ? envelope.tool_name : typeof envelope.tool === "string" ? envelope.tool : void 0;
|
|
32874
|
+
const params = antigravity ? antigravity.params : windsurf ? windsurf.params : envelope.tool_input ?? envelope.params ?? envelope.input ?? {};
|
|
32875
|
+
const loggedKeys = antigravity ? antigravity.argKeys : Object.keys(params);
|
|
32225
32876
|
debugLog({
|
|
32226
32877
|
event: "pre_map",
|
|
32227
32878
|
raw_tool_name: rawTool ?? null,
|
|
32228
32879
|
has_tool_input: "tool_input" in envelope,
|
|
32229
32880
|
has_params: "params" in envelope,
|
|
32230
|
-
param_keys:
|
|
32881
|
+
param_keys: loggedKeys.slice(0, 12)
|
|
32231
32882
|
});
|
|
32232
32883
|
const homeDir = process.env.HOME ?? process.env.USERPROFILE ?? "/";
|
|
32233
|
-
const cwd = process.cwd();
|
|
32234
|
-
const tool = normalizeToolName(rawTool);
|
|
32884
|
+
const cwd = antigravity ? antigravity.cwd : process.cwd();
|
|
32885
|
+
const tool = antigravity?.classifiedTool ?? normalizeToolName(rawTool, agent);
|
|
32886
|
+
const extraFilePaths = antigravity?.extraFilePaths ?? [];
|
|
32235
32887
|
switch (tool) {
|
|
32236
32888
|
case "Read":
|
|
32237
32889
|
case "Glob":
|
|
32238
|
-
case "Grep":
|
|
32239
|
-
|
|
32240
|
-
if (!filePath) return { kind: "unmapped", tool: rawTool ?? UNNAMED_TOOL };
|
|
32241
|
-
return {
|
|
32242
|
-
kind: "mapped",
|
|
32243
|
-
request: { agent, tool, target: { type: "file", path: filePath }, homeDir, cwd }
|
|
32244
|
-
};
|
|
32245
|
-
}
|
|
32890
|
+
case "Grep":
|
|
32891
|
+
return fileMapping(agent, tool, params, homeDir, cwd, rawTool, extraFilePaths);
|
|
32246
32892
|
case "Write":
|
|
32247
32893
|
case "Edit":
|
|
32248
|
-
case "MultiEdit":
|
|
32249
|
-
|
|
32250
|
-
if (!filePath) return { kind: "unmapped", tool: rawTool ?? UNNAMED_TOOL };
|
|
32251
|
-
return {
|
|
32252
|
-
kind: "mapped",
|
|
32253
|
-
request: { agent, tool, target: { type: "file", path: filePath }, homeDir, cwd }
|
|
32254
|
-
};
|
|
32255
|
-
}
|
|
32894
|
+
case "MultiEdit":
|
|
32895
|
+
return fileMapping(agent, tool, params, homeDir, cwd, rawTool, extraFilePaths);
|
|
32256
32896
|
case "Bash": {
|
|
32257
32897
|
const command = commandField(params);
|
|
32258
32898
|
if (!command) return { kind: "unmapped", tool: rawTool ?? UNNAMED_TOOL };
|
|
@@ -32334,7 +32974,7 @@ function mapEnvelope(envelope, agent = sniff(envelope).client) {
|
|
|
32334
32974
|
JSON.stringify({
|
|
32335
32975
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
32336
32976
|
tool_name: rawTool ?? null,
|
|
32337
|
-
params_keys:
|
|
32977
|
+
params_keys: loggedKeys
|
|
32338
32978
|
})
|
|
32339
32979
|
);
|
|
32340
32980
|
return { kind: "unmapped", tool: rawTool ?? UNNAMED_TOOL };
|
|
@@ -32383,6 +33023,9 @@ function stringifyTarget(t) {
|
|
|
32383
33023
|
return `git ${t.subcommand}`;
|
|
32384
33024
|
}
|
|
32385
33025
|
}
|
|
33026
|
+
function verdictRank(v) {
|
|
33027
|
+
return v === "deny" ? 2 : v === "warn" ? 1 : 0;
|
|
33028
|
+
}
|
|
32386
33029
|
async function consultJudge(judge, sessionId, cacheKey, input2, cache = { get: (k) => judge.cacheGet(k), set: (k, r) => judge.cacheSet(k, r) }) {
|
|
32387
33030
|
const cached2 = cache.get(cacheKey);
|
|
32388
33031
|
if (cached2) return { kind: "result", res: cached2 };
|
|
@@ -32601,6 +33244,14 @@ ${JSON.stringify(payload)}` : targetStr);
|
|
|
32601
33244
|
}
|
|
32602
33245
|
return { engine: "llm", outcome: "confirmed", model: res.model };
|
|
32603
33246
|
}
|
|
33247
|
+
var SESSION_ID_MAX = 128;
|
|
33248
|
+
function antigravitySessionId(envelope) {
|
|
33249
|
+
const id = envelope.conversationId;
|
|
33250
|
+
return typeof id === "string" && id.length > 0 && id.length <= SESSION_ID_MAX ? id : void 0;
|
|
33251
|
+
}
|
|
33252
|
+
function denyExitCode(client) {
|
|
33253
|
+
return client === "antigravity" ? 0 : 2;
|
|
33254
|
+
}
|
|
32604
33255
|
async function runCatchJudgeStep(args) {
|
|
32605
33256
|
const {
|
|
32606
33257
|
judge,
|
|
@@ -32660,7 +33311,7 @@ async function runCatchJudgeStep(args) {
|
|
|
32660
33311
|
message
|
|
32661
33312
|
};
|
|
32662
33313
|
}
|
|
32663
|
-
function emitUnverifiedBanner(reason) {
|
|
33314
|
+
function emitUnverifiedBanner(reason, client) {
|
|
32664
33315
|
const banner = [
|
|
32665
33316
|
"\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2588",
|
|
32666
33317
|
"\u2588 VibeDefend Action Guards \u2014 UNVERIFIED \u2588",
|
|
@@ -32678,7 +33329,7 @@ function emitUnverifiedBanner(reason) {
|
|
|
32678
33329
|
].join("\n") + "\n";
|
|
32679
33330
|
process.stderr.write(banner);
|
|
32680
33331
|
const isCodex = typeof process.env.CODEX_SANDBOX !== "undefined" || typeof process.env.CODEX_AGENT !== "undefined";
|
|
32681
|
-
if (isCodex) {
|
|
33332
|
+
if (isCodex && client !== "antigravity") {
|
|
32682
33333
|
try {
|
|
32683
33334
|
const ctx = JSON.stringify({
|
|
32684
33335
|
additionalContext: `VibeDefend Action Guards UNVERIFIED \u2014 ${reason} Tool call allowed WITHOUT enforcement. Run \`vibedefend login\` to restore protection.`
|
|
@@ -32688,8 +33339,10 @@ function emitUnverifiedBanner(reason) {
|
|
|
32688
33339
|
}
|
|
32689
33340
|
}
|
|
32690
33341
|
}
|
|
32691
|
-
function sessionIdOf3(envelope) {
|
|
32692
|
-
|
|
33342
|
+
function sessionIdOf3(envelope, client) {
|
|
33343
|
+
if (typeof envelope.session_id === "string") return envelope.session_id;
|
|
33344
|
+
if (typeof envelope.sessionId === "string") return envelope.sessionId;
|
|
33345
|
+
return client === "antigravity" ? antigravitySessionId(envelope) : void 0;
|
|
32693
33346
|
}
|
|
32694
33347
|
async function runPreToolUseGuardWith(opts) {
|
|
32695
33348
|
const {
|
|
@@ -32702,21 +33355,22 @@ async function runPreToolUseGuardWith(opts) {
|
|
|
32702
33355
|
if (!projectContext) return 0;
|
|
32703
33356
|
if (rulesOutcome.kind === "unavailable") {
|
|
32704
33357
|
emitUnverifiedBanner(
|
|
32705
|
-
`Policy engine unreachable: ${rulesOutcome.reason}
|
|
33358
|
+
`Policy engine unreachable: ${rulesOutcome.reason}`,
|
|
33359
|
+
sniffCaller(stdinEnvelope).client
|
|
32706
33360
|
);
|
|
32707
33361
|
return 0;
|
|
32708
33362
|
}
|
|
32709
33363
|
if (rulesOutcome.kind === "blocked") {
|
|
32710
33364
|
const sentence = opts.usageNotifier?.notifyBlock(
|
|
32711
|
-
sessionIdOf3(stdinEnvelope),
|
|
33365
|
+
sessionIdOf3(stdinEnvelope, sniffCaller(stdinEnvelope).client),
|
|
32712
33366
|
rulesOutcome.block
|
|
32713
33367
|
);
|
|
32714
|
-
if (sentence) emitAgentMessage("warn", sentence);
|
|
33368
|
+
if (sentence) emitAgentMessage("warn", sentence, sniffCaller(stdinEnvelope).client);
|
|
32715
33369
|
return 0;
|
|
32716
33370
|
}
|
|
32717
33371
|
const rules = rulesOutcome.rules;
|
|
32718
|
-
const caller =
|
|
32719
|
-
const sessionId = sessionIdOf3(stdinEnvelope);
|
|
33372
|
+
const caller = sniffCaller(stdinEnvelope);
|
|
33373
|
+
const sessionId = sessionIdOf3(stdinEnvelope, caller.client);
|
|
32720
33374
|
const mapping = mapEnvelope(stdinEnvelope, caller.client);
|
|
32721
33375
|
if (mapping.kind === "targetless") return 0;
|
|
32722
33376
|
if (mapping.kind === "unmapped") {
|
|
@@ -32731,9 +33385,10 @@ async function runPreToolUseGuardWith(opts) {
|
|
|
32731
33385
|
if (strictUnmappedPolicy()) {
|
|
32732
33386
|
emitAgentMessage(
|
|
32733
33387
|
"deny",
|
|
32734
|
-
`Tool "${mapping.tool}" is not evaluated by Action Guards and CYBEDEFEND_GUARDS_STRICT is on \u2014 blocked (strict mode)
|
|
33388
|
+
`Tool "${mapping.tool}" is not evaluated by Action Guards and CYBEDEFEND_GUARDS_STRICT is on \u2014 blocked (strict mode).`,
|
|
33389
|
+
caller.client
|
|
32735
33390
|
);
|
|
32736
|
-
return
|
|
33391
|
+
return denyExitCode(caller.client);
|
|
32737
33392
|
}
|
|
32738
33393
|
if (opts.unmapped.noticeOnce(sessionId, mapping.tool)) {
|
|
32739
33394
|
process.stderr.write(
|
|
@@ -32744,12 +33399,24 @@ async function runPreToolUseGuardWith(opts) {
|
|
|
32744
33399
|
return 0;
|
|
32745
33400
|
}
|
|
32746
33401
|
const partial2 = mapping.request;
|
|
32747
|
-
|
|
33402
|
+
let guardRequest = {
|
|
32748
33403
|
...partial2,
|
|
32749
33404
|
projectId: projectContext.projectId,
|
|
32750
33405
|
sessionId
|
|
32751
33406
|
};
|
|
32752
33407
|
let decision = evaluateFn(rules, guardRequest);
|
|
33408
|
+
for (const extra of mapping.additionalRequests ?? []) {
|
|
33409
|
+
const extraRequest = {
|
|
33410
|
+
...extra,
|
|
33411
|
+
projectId: projectContext.projectId,
|
|
33412
|
+
sessionId
|
|
33413
|
+
};
|
|
33414
|
+
const extraDecision = evaluateFn(rules, extraRequest);
|
|
33415
|
+
if (verdictRank(extraDecision.verdict) > verdictRank(decision.verdict)) {
|
|
33416
|
+
decision = extraDecision;
|
|
33417
|
+
guardRequest = extraRequest;
|
|
33418
|
+
}
|
|
33419
|
+
}
|
|
32753
33420
|
let hardenedTier = "small";
|
|
32754
33421
|
let hardenedScripts = [];
|
|
32755
33422
|
if (opts.hardenedCommandAnalysis && opts.sessionWrites && guardRequest.target.type === "file" && (guardRequest.tool === "Write" || guardRequest.tool === "Edit" || guardRequest.tool === "MultiEdit")) {
|
|
@@ -32904,20 +33571,28 @@ async function runPreToolUseGuardWith(opts) {
|
|
|
32904
33571
|
matched_rule_ids: decision.matchedRuleIds
|
|
32905
33572
|
});
|
|
32906
33573
|
if (decision.verdict === "deny") {
|
|
32907
|
-
emitAgentMessage("deny", decision.message ?? "Action blocked.");
|
|
32908
|
-
return
|
|
33574
|
+
emitAgentMessage("deny", decision.message ?? "Action blocked.", caller.client);
|
|
33575
|
+
return denyExitCode(caller.client);
|
|
32909
33576
|
}
|
|
32910
33577
|
if (decision.verdict === "warn") {
|
|
32911
|
-
emitAgentMessage("warn", decision.message ?? "Action flagged.");
|
|
33578
|
+
emitAgentMessage("warn", decision.message ?? "Action flagged.", caller.client);
|
|
32912
33579
|
return 0;
|
|
32913
33580
|
}
|
|
32914
33581
|
return 0;
|
|
32915
33582
|
}
|
|
32916
|
-
|
|
33583
|
+
var ANTIGRAVITY_DECISIONS = {
|
|
33584
|
+
deny: "deny",
|
|
33585
|
+
warn: "allow"
|
|
33586
|
+
};
|
|
33587
|
+
function emitAgentMessage(verdict, message, client) {
|
|
32917
33588
|
const tag = verdict === "deny" ? "Action Guards" : "Action Guards \xB7 WARN";
|
|
32918
33589
|
const fullMessage = `[VibeDefend ${tag}] ${message}`;
|
|
32919
33590
|
process.stderr.write(fullMessage + "\n");
|
|
32920
33591
|
try {
|
|
33592
|
+
if (client === "antigravity") {
|
|
33593
|
+
emitAntigravityDecision(ANTIGRAVITY_DECISIONS[verdict], fullMessage);
|
|
33594
|
+
return;
|
|
33595
|
+
}
|
|
32921
33596
|
const payload = verdict === "deny" ? {
|
|
32922
33597
|
// Claude Code legacy — the call, not the agent, is stopped.
|
|
32923
33598
|
decision: "block",
|
|
@@ -32950,17 +33625,17 @@ function emitAgentMessage(verdict, message) {
|
|
|
32950
33625
|
}
|
|
32951
33626
|
function makeProductionJudgeDeps() {
|
|
32952
33627
|
const cache = makeJudgeCache();
|
|
32953
|
-
const warnDir = process.env.CYBEDEFEND_BASELINE_DIR ??
|
|
33628
|
+
const warnDir = process.env.CYBEDEFEND_BASELINE_DIR ?? join19(homedir18(), ".cybedefend");
|
|
32954
33629
|
const scriptCache = makeJudgeCache({
|
|
32955
|
-
cacheFile:
|
|
33630
|
+
cacheFile: join19(warnDir, "guards-judge-script-cache.json"),
|
|
32956
33631
|
ttlMs: SCRIPT_VERDICT_TTL_MS,
|
|
32957
33632
|
maxEntries: SCRIPT_VERDICT_MAX_ENTRIES
|
|
32958
33633
|
});
|
|
32959
33634
|
const warnTracker = defaultSessionTracker(
|
|
32960
|
-
|
|
33635
|
+
join19(warnDir, "guards-judge-warned-sessions.json")
|
|
32961
33636
|
);
|
|
32962
33637
|
const blockedTracker = defaultSessionTracker(
|
|
32963
|
-
|
|
33638
|
+
join19(warnDir, "guards-judge-blocked-sessions.json")
|
|
32964
33639
|
);
|
|
32965
33640
|
return {
|
|
32966
33641
|
usage: {
|
|
@@ -32988,8 +33663,8 @@ function makeProductionJudgeDeps() {
|
|
|
32988
33663
|
}
|
|
32989
33664
|
function makeProductionUnmappedDeps() {
|
|
32990
33665
|
const telemetry = makeUnmappedToolTelemetry();
|
|
32991
|
-
const dir = process.env.CYBEDEFEND_BASELINE_DIR ??
|
|
32992
|
-
const tracker = defaultSessionTracker(
|
|
33666
|
+
const dir = process.env.CYBEDEFEND_BASELINE_DIR ?? join19(homedir18(), ".cybedefend");
|
|
33667
|
+
const tracker = defaultSessionTracker(join19(dir, "guards-unmapped-notified.json"));
|
|
32993
33668
|
return {
|
|
32994
33669
|
record: telemetry.record,
|
|
32995
33670
|
noticeOnce: (sessionId, tool) => {
|
|
@@ -33043,7 +33718,8 @@ async function runPreToolUseGuard() {
|
|
|
33043
33718
|
});
|
|
33044
33719
|
if (!token && rulesOutcome.kind === "unavailable") {
|
|
33045
33720
|
emitUnverifiedBanner(
|
|
33046
|
-
"Not authenticated \u2014 run `vibedefend login` to restore Action Guards."
|
|
33721
|
+
"Not authenticated \u2014 run `vibedefend login` to restore Action Guards.",
|
|
33722
|
+
sniffCaller(envelope).client
|
|
33047
33723
|
);
|
|
33048
33724
|
return 0;
|
|
33049
33725
|
}
|
|
@@ -33080,7 +33756,7 @@ async function runPreToolUseGuard() {
|
|
|
33080
33756
|
scriptJudge: process.env.CYBEDEFEND_HARDENED_ANALYSIS !== "0" && process.env.CYBEDEFEND_SCRIPT_JUDGE !== "0",
|
|
33081
33757
|
// Level 1 — real script reader + per-session write memory.
|
|
33082
33758
|
scriptResolver: process.env.CYBEDEFEND_HARDENED_ANALYSIS !== "0" ? (command, cwd) => resolveExecutedScript(command, { cwd }) : void 0,
|
|
33083
|
-
sessionWrites: process.env.CYBEDEFEND_HARDENED_ANALYSIS !== "0" ? makeSessionWritesPort(sessionIdOf3(envelope)) : void 0,
|
|
33759
|
+
sessionWrites: process.env.CYBEDEFEND_HARDENED_ANALYSIS !== "0" ? makeSessionWritesPort(sessionIdOf3(envelope, sniffCaller(envelope).client)) : void 0,
|
|
33084
33760
|
resolvePaths: process.env.CYBEDEFEND_HARDENED_ANALYSIS !== "0" ? (rawPath, cwd, homeDir) => resolveCandidatePaths(rawPath, { cwd, homeDir }) : void 0,
|
|
33085
33761
|
// The refusal sentence goes out through the agent-message channels
|
|
33086
33762
|
// (stderr included), so this notifier itself writes nothing.
|
|
@@ -33177,7 +33853,31 @@ function toApiViolation(r) {
|
|
|
33177
33853
|
|
|
33178
33854
|
// src/hooks/runtime/index.ts
|
|
33179
33855
|
async function main() {
|
|
33180
|
-
const subcommand = process.argv
|
|
33856
|
+
const { subcommand, client } = parseRunnerArgs(process.argv.slice(2));
|
|
33857
|
+
const isAntigravity = client === "antigravity";
|
|
33858
|
+
const finish = (code) => {
|
|
33859
|
+
if (isAntigravity) {
|
|
33860
|
+
finishAntigravityRun(subcommand);
|
|
33861
|
+
process.exit(0);
|
|
33862
|
+
}
|
|
33863
|
+
process.exit(code);
|
|
33864
|
+
};
|
|
33865
|
+
if (isAntigravity) {
|
|
33866
|
+
let crashed = false;
|
|
33867
|
+
const onCrash = (e) => {
|
|
33868
|
+
if (crashed) return;
|
|
33869
|
+
crashed = true;
|
|
33870
|
+
try {
|
|
33871
|
+
const msg = e instanceof Error ? e.stack || e.message : String(e);
|
|
33872
|
+
process.stderr.write(`[vibedefend hook] ${subcommand}: ${msg}
|
|
33873
|
+
`);
|
|
33874
|
+
} catch {
|
|
33875
|
+
}
|
|
33876
|
+
finish(0);
|
|
33877
|
+
};
|
|
33878
|
+
process.on("uncaughtException", onCrash);
|
|
33879
|
+
process.on("unhandledRejection", onCrash);
|
|
33880
|
+
}
|
|
33181
33881
|
try {
|
|
33182
33882
|
switch (subcommand) {
|
|
33183
33883
|
case "fetch-rules":
|
|
@@ -33195,6 +33895,9 @@ async function main() {
|
|
|
33195
33895
|
case "user-prompt-submit":
|
|
33196
33896
|
await userPromptSubmitHook();
|
|
33197
33897
|
break;
|
|
33898
|
+
case "pre-invocation":
|
|
33899
|
+
await preInvocationHook();
|
|
33900
|
+
break;
|
|
33198
33901
|
case "flush-violations":
|
|
33199
33902
|
await runViolationsFlush();
|
|
33200
33903
|
break;
|
|
@@ -33202,21 +33905,21 @@ async function main() {
|
|
|
33202
33905
|
case "pre-tool-use":
|
|
33203
33906
|
case "PreToolUse": {
|
|
33204
33907
|
const code = await runPreToolUseGuard();
|
|
33205
|
-
|
|
33908
|
+
finish(code);
|
|
33206
33909
|
return;
|
|
33207
33910
|
}
|
|
33208
33911
|
case "":
|
|
33209
33912
|
case "--help":
|
|
33210
33913
|
case "-h":
|
|
33211
33914
|
process.stderr.write(
|
|
33212
|
-
"Usage: hook-runner.js <fetch-rules|session-start|session-review|pre-compact|user-prompt-submit|guard-check
|
|
33915
|
+
"Usage: hook-runner.js <fetch-rules|session-start|session-review|pre-compact|user-prompt-submit|pre-invocation|guard-check> [--client antigravity]\n"
|
|
33213
33916
|
);
|
|
33214
|
-
|
|
33917
|
+
finish(subcommand === "" ? 1 : 0);
|
|
33215
33918
|
return;
|
|
33216
33919
|
default:
|
|
33217
33920
|
process.stderr.write(`Unknown subcommand: ${subcommand}
|
|
33218
33921
|
`);
|
|
33219
|
-
|
|
33922
|
+
finish(1);
|
|
33220
33923
|
return;
|
|
33221
33924
|
}
|
|
33222
33925
|
} catch (e) {
|
|
@@ -33224,6 +33927,6 @@ async function main() {
|
|
|
33224
33927
|
process.stderr.write(`[vibedefend hook] ${subcommand}: ${msg}
|
|
33225
33928
|
`);
|
|
33226
33929
|
}
|
|
33227
|
-
|
|
33930
|
+
finish(0);
|
|
33228
33931
|
}
|
|
33229
33932
|
main();
|