@solongate/proxy 0.82.10 → 0.82.12

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.
@@ -84,7 +84,7 @@ function listDirs() {
84
84
  const home = homedir();
85
85
  console.log("\n Default log directories:");
86
86
  console.log(` Claude Code \u2192 ${resolve(home, ".claude", "projects")}`);
87
- console.log(` Gemini CLI \u2192 ${resolve(home, ".gemini", "tmp")}`);
87
+ console.log(` Antigravity \u2192 ${resolve(home, ".gemini", "antigravity", "brain")}`);
88
88
  console.log(` OpenClaw \u2192 ${resolve(home, ".openclaw", "agents", "main", "sessions")}`);
89
89
  if (config.customDirs.length === 0) {
90
90
  console.log("\n Custom directories: (none)");
@@ -106,7 +106,7 @@ function searchLogs() {
106
106
  console.log("\n Searching for AI tool logs...\n");
107
107
  const defaults = [
108
108
  { name: "Claude Code", path: resolve(home, ".claude", "projects") },
109
- { name: "Gemini CLI", path: resolve(home, ".gemini", "tmp") },
109
+ { name: "Antigravity", path: resolve(home, ".gemini", "antigravity", "brain") },
110
110
  { name: "OpenClaw", path: resolve(home, ".openclaw", "agents", "main", "sessions") }
111
111
  ];
112
112
  for (const d of defaults) {
@@ -129,7 +129,7 @@ function searchLogs() {
129
129
  }
130
130
  const otherPaths = [
131
131
  { name: `Claude Code (${user})`, path: resolve(userHome, ".claude", "projects") },
132
- { name: `Gemini CLI (${user})`, path: resolve(userHome, ".gemini", "tmp") },
132
+ { name: `Antigravity (${user})`, path: resolve(userHome, ".gemini", "antigravity", "brain") },
133
133
  { name: `OpenClaw (${user})`, path: resolve(userHome, ".openclaw", "agents", "main", "sessions") }
134
134
  ];
135
135
  for (const d of otherPaths) {
@@ -152,7 +152,7 @@ function searchLogs() {
152
152
  if (userHome === home) continue;
153
153
  const otherPaths = [
154
154
  { name: `Claude Code (${user})`, path: resolve(userHome, ".claude", "projects") },
155
- { name: `Gemini CLI (${user})`, path: resolve(userHome, ".gemini", "tmp") },
155
+ { name: `Antigravity (${user})`, path: resolve(userHome, ".gemini", "antigravity", "brain") },
156
156
  { name: `OpenClaw (${user})`, path: resolve(userHome, ".openclaw", "agents", "main", "sessions") }
157
157
  ];
158
158
  for (const d of otherPaths) {
@@ -261,61 +261,74 @@ function collectClaude() {
261
261
  }
262
262
  return sessions;
263
263
  }
264
- function collectGemini() {
264
+ function collectAntigravity() {
265
265
  const sessions = [];
266
- const geminiDir = resolve2(homedir2(), ".gemini", "tmp");
267
- if (!existsSync2(geminiDir)) return sessions;
268
- for (const projectDir of readdirSync(geminiDir)) {
269
- const chatsDir = join2(geminiDir, projectDir, "chats");
270
- if (!existsSync2(chatsDir) || !statSync(chatsDir).isDirectory()) continue;
271
- for (const file of readdirSync(chatsDir)) {
272
- if (!file.startsWith("session-") || !file.endsWith(".json")) continue;
273
- const filePath = join2(chatsDir, file);
274
- try {
275
- const data = JSON.parse(readFileSync2(filePath, "utf-8"));
276
- const toolCalls = [];
277
- const userMessages = [];
278
- const sessionId = data.sessionId || file.replace(".json", "");
279
- for (const msg of data.messages || []) {
280
- if (msg.role === "user" && (msg.text || msg.content)) {
281
- const text = String(msg.text || msg.content).slice(0, 500);
282
- if (text.length > 0) {
283
- userMessages.push({ timestamp: msg.timestamp || data.startTime || "", text });
284
- }
266
+ const brainDir = resolve2(homedir2(), ".gemini", "antigravity", "brain");
267
+ if (!existsSync2(brainDir)) return sessions;
268
+ for (const convId of readdirSync(brainDir)) {
269
+ const convPath = join2(brainDir, convId);
270
+ try {
271
+ if (!statSync(convPath).isDirectory()) continue;
272
+ } catch {
273
+ continue;
274
+ }
275
+ const transcript = join2(convPath, ".system_generated", "logs", "transcript.jsonl");
276
+ if (!existsSync2(transcript)) continue;
277
+ try {
278
+ const lines = readFileSync2(transcript, "utf-8").split("\n").filter(Boolean);
279
+ const toolCalls = [];
280
+ const userMessages = [];
281
+ let startTime = "";
282
+ let endTime = "";
283
+ let model = "";
284
+ for (const line of lines) {
285
+ try {
286
+ const entry = JSON.parse(line);
287
+ const ts = entry.timestamp || entry.time || entry.ts || "";
288
+ if (ts) {
289
+ if (!startTime) startTime = ts;
290
+ endTime = ts;
285
291
  }
286
- if (!msg.toolCalls || !Array.isArray(msg.toolCalls)) continue;
287
- for (const tc of msg.toolCalls) {
292
+ if (!model && typeof entry.model === "string") model = entry.model;
293
+ const tc = entry.toolCall || (entry.type === "tool_call" ? entry : null);
294
+ if (tc && typeof tc === "object" && (tc.name || tc.toolName)) {
288
295
  toolCalls.push({
289
- id: tc.id || "",
290
- toolName: tc.name || "",
296
+ id: tc.id || (entry.stepIdx != null ? String(entry.stepIdx) : ""),
297
+ toolName: tc.name || tc.toolName || "",
291
298
  arguments: tc.args || tc.arguments || {},
292
- result: tc.result ? JSON.stringify(tc.result).slice(0, 2e3) : void 0,
293
- isError: tc.status === "error",
294
- timestamp: tc.timestamp || msg.timestamp || data.startTime || "",
295
- source: "gemini",
296
- sessionId
299
+ result: entry.result ? JSON.stringify(entry.result).slice(0, 2e3) : void 0,
300
+ isError: entry.status === "error" || entry.isError === true,
301
+ timestamp: ts,
302
+ source: "antigravity",
303
+ sessionId: convId
297
304
  });
298
305
  }
306
+ const role = entry.role || entry.type;
307
+ if ((role === "user" || role === "user_message") && (entry.text || entry.content)) {
308
+ const text = String(entry.text || entry.content).slice(0, 500);
309
+ if (text.length > 0) userMessages.push({ timestamp: ts, text });
310
+ }
311
+ } catch {
299
312
  }
300
- for (const um of userMessages) {
301
- const umTime = new Date(um.timestamp).getTime();
302
- const nextIdx = toolCalls.findIndex((tc) => new Date(tc.timestamp).getTime() > umTime);
303
- if (nextIdx >= 0) um.nextToolCallIndex = nextIdx;
304
- }
305
- if (toolCalls.length > 0) {
306
- sessions.push({
307
- id: sessionId,
308
- source: "gemini",
309
- startTime: data.startTime || "",
310
- endTime: data.lastUpdated || "",
311
- model: data.messages?.[0]?.model || "",
312
- toolCalls,
313
- userMessages,
314
- filePath
315
- });
316
- }
317
- } catch {
318
313
  }
314
+ for (const um of userMessages) {
315
+ const umTime = new Date(um.timestamp).getTime();
316
+ const nextIdx = toolCalls.findIndex((tc) => new Date(tc.timestamp).getTime() > umTime);
317
+ if (nextIdx >= 0) um.nextToolCallIndex = nextIdx;
318
+ }
319
+ if (toolCalls.length > 0) {
320
+ sessions.push({
321
+ id: convId,
322
+ source: "antigravity",
323
+ startTime,
324
+ endTime,
325
+ model,
326
+ toolCalls,
327
+ userMessages,
328
+ filePath: transcript
329
+ });
330
+ }
331
+ } catch {
319
332
  }
320
333
  }
321
334
  return sessions;
@@ -485,11 +498,11 @@ function collectCustomDirs() {
485
498
  for (const msg of data.messages) {
486
499
  if (!msg.toolCalls || !Array.isArray(msg.toolCalls)) continue;
487
500
  for (const tc of msg.toolCalls) {
488
- toolCalls.push({ id: tc.id || "", toolName: tc.name || "", arguments: tc.args || tc.arguments || {}, result: tc.result ? JSON.stringify(tc.result).slice(0, 2e3) : void 0, isError: tc.status === "error", timestamp: tc.timestamp || msg.timestamp || data.startTime || "", source: "gemini", sessionId });
501
+ toolCalls.push({ id: tc.id || "", toolName: tc.name || "", arguments: tc.args || tc.arguments || {}, result: tc.result ? JSON.stringify(tc.result).slice(0, 2e3) : void 0, isError: tc.status === "error", timestamp: tc.timestamp || msg.timestamp || data.startTime || "", source: "antigravity", sessionId });
489
502
  }
490
503
  }
491
504
  if (toolCalls.length > 0) {
492
- sessions.push({ id: sessionId, source: "gemini", startTime: data.startTime || "", endTime: data.lastUpdated || "", model: data.messages?.[0]?.model || "", toolCalls, filePath });
505
+ sessions.push({ id: sessionId, source: "antigravity", startTime: data.startTime || "", endTime: data.lastUpdated || "", model: data.messages?.[0]?.model || "", toolCalls, filePath });
493
506
  }
494
507
  } catch {
495
508
  }
@@ -502,13 +515,13 @@ function collectCustomDirs() {
502
515
  }
503
516
  function collectLogs() {
504
517
  const claudeSessions = collectClaude();
505
- const geminiSessions = collectGemini();
518
+ const antigravitySessions = collectAntigravity();
506
519
  const openclawSessions = collectOpenClaw();
507
520
  const customSessions = collectCustomDirs();
508
- const sessions = [...claudeSessions, ...geminiSessions, ...openclawSessions, ...customSessions].sort((a, b) => (a.startTime || "").localeCompare(b.startTime || ""));
521
+ const sessions = [...claudeSessions, ...antigravitySessions, ...openclawSessions, ...customSessions].sort((a, b) => (a.startTime || "").localeCompare(b.startTime || ""));
509
522
  const sources = [];
510
523
  if (claudeSessions.length > 0) sources.push("Claude Code");
511
- if (geminiSessions.length > 0) sources.push("Gemini CLI");
524
+ if (antigravitySessions.length > 0) sources.push("Antigravity");
512
525
  if (openclawSessions.length > 0) sources.push("OpenClaw");
513
526
  const allCalls = sessions.flatMap((s) => s.toolCalls);
514
527
  const timestamps = allCalls.map((t) => t.timestamp).filter(Boolean).sort();
@@ -2599,12 +2612,12 @@ function printFooter(results) {
2599
2612
  }
2600
2613
  var SOURCE_COLOR = {
2601
2614
  claude: source_default.magenta,
2602
- gemini: source_default.blue,
2615
+ antigravity: source_default.blue,
2603
2616
  openclaw: source_default.green
2604
2617
  };
2605
2618
  var SOURCE_LABEL = {
2606
2619
  claude: "Claude",
2607
- gemini: "Gemini",
2620
+ antigravity: "Antigravity",
2608
2621
  openclaw: "OClaw"
2609
2622
  };
2610
2623
  function truncate(s, max) {
@@ -2807,7 +2820,7 @@ function exportHTML({ data, results }) {
2807
2820
  };
2808
2821
  const sourceLabel = {
2809
2822
  claude: "Claude",
2810
- gemini: "Gemini",
2823
+ antigravity: "Antigravity",
2811
2824
  openclaw: "OpenClaw"
2812
2825
  };
2813
2826
  const pillClass = {
@@ -2922,7 +2935,7 @@ function exportHTML({ data, results }) {
2922
2935
  .code-tag { color: var(--accent); font-weight: 600; font-size: 11px; }
2923
2936
  .src-tag { display: inline-block; padding: 1px 7px; border-radius: 3px; font-size: 10px; font-weight: 600; }
2924
2937
  .src-claude { background: rgba(192,132,252,0.12); color: #c084fc; }
2925
- .src-gemini { background: rgba(96,165,250,0.12); color: #60a5fa; }
2938
+ .src-antigravity { background: rgba(96,165,250,0.12); color: #60a5fa; }
2926
2939
  .src-openclaw { background: rgba(74,222,128,0.12); color: #4ade80; }
2927
2940
  .err-tag { background: rgba(239,68,68,0.15); color: #f87171; padding: 0 5px; border-radius: 3px; font-size: 9px; font-weight: 700; margin-left: 4px; }
2928
2941
  .cat { font-weight: 500; }
@@ -3038,7 +3051,7 @@ function exportHTML({ data, results }) {
3038
3051
  <div class="sec-hdr">Tool Calls <span class="sec-count">${allCalls.length.toLocaleString()}</span></div>
3039
3052
  <div class="filters">
3040
3053
  <input type="text" id="q" placeholder="Search..." oninput="applyFilters()">
3041
- <select id="sf" onchange="applyFilters()"><option value="">All sources</option><option value="claude">Claude</option><option value="gemini">Gemini</option><option value="openclaw">OpenClaw</option></select>
3054
+ <select id="sf" onchange="applyFilters()"><option value="">All sources</option><option value="claude">Claude</option><option value="antigravity">Antigravity</option><option value="openclaw">OpenClaw</option></select>
3042
3055
  <select id="ef" onchange="applyFilters()"><option value="">All</option><option value="e">Errors</option><option value="s">Success</option></select>
3043
3056
  <select id="df" onchange="applyFilters()"><option value="">All dates</option></select>
3044
3057
  </div>
@@ -19,7 +19,7 @@ export interface ToolCall {
19
19
  result?: string;
20
20
  isError?: boolean;
21
21
  timestamp: string;
22
- source: 'claude' | 'gemini' | 'openclaw';
22
+ source: 'claude' | 'antigravity' | 'openclaw';
23
23
  sessionId: string;
24
24
  }
25
25
  export interface UserMessage {
@@ -29,7 +29,7 @@ export interface UserMessage {
29
29
  }
30
30
  export interface SessionInfo {
31
31
  id: string;
32
- source: 'claude' | 'gemini' | 'openclaw';
32
+ source: 'claude' | 'antigravity' | 'openclaw';
33
33
  startTime: string;
34
34
  endTime?: string;
35
35
  model?: string;
@@ -74,7 +74,7 @@ export interface PermissionDrift {
74
74
  newToolTypes: string[];
75
75
  }
76
76
  export interface SessionBaseline {
77
- source: 'claude' | 'gemini' | 'openclaw' | 'all';
77
+ source: 'claude' | 'antigravity' | 'openclaw' | 'all';
78
78
  avgToolCalls: number;
79
79
  stddevToolCalls: number;
80
80
  toolTypeDistribution: Record<string, number>;
package/dist/create.js CHANGED
@@ -213,7 +213,7 @@ console.log('MCP servers communicate over stdin/stdout \u2014 not HTTP.');
213
213
  console.log('You need an MCP client to connect:');
214
214
  console.log('');
215
215
  console.log(' Claude Code Open this folder, .mcp.json is auto-detected');
216
- console.log(' Gemini CLI Open this folder, .mcp.json is auto-detected');
216
+ console.log(' Antigravity .agents/mcp_config.json (or ~/.gemini/config/mcp_config.json)');
217
217
  console.log(' OpenClaw Uses openclaw.plugin.json config');
218
218
  console.log('');
219
219
  console.log('Press Ctrl+C to stop.');
@@ -5,9 +5,12 @@ export declare function globalPaths(): {
5
5
  sgDir: string;
6
6
  hooksDir: string;
7
7
  claudeDir: string;
8
+ antigravityDir: string;
8
9
  settingsPath: string;
9
10
  backupPath: string;
10
11
  configPath: string;
12
+ antigravityHooksPath: string;
13
+ antigravityBackupPath: string;
11
14
  };
12
15
  export declare function clearGuardUpdateCheck(): boolean;
13
16
  export declare function runGlobalRestore(): void;
@@ -71,7 +71,8 @@ function protectedTargets() {
71
71
  join(p.hooksDir, "stop.mjs"),
72
72
  join(p.hooksDir, "shield.mjs"),
73
73
  p.configPath,
74
- p.settingsPath
74
+ p.settingsPath,
75
+ p.antigravityHooksPath
75
76
  ];
76
77
  }
77
78
  function lockProtected() {
@@ -85,14 +86,21 @@ function globalPaths() {
85
86
  const sgDir = join(home, ".solongate");
86
87
  const hooksDir = join(sgDir, "hooks");
87
88
  const claudeDir = join(home, ".claude");
89
+ const antigravityDir = join(home, ".gemini", "config");
88
90
  return {
89
91
  home,
90
92
  sgDir,
91
93
  hooksDir,
92
94
  claudeDir,
95
+ antigravityDir,
93
96
  settingsPath: join(claudeDir, "settings.json"),
94
97
  backupPath: join(claudeDir, "settings.solongate.bak"),
95
- configPath: join(sgDir, "cloud-guard.json")
98
+ configPath: join(sgDir, "cloud-guard.json"),
99
+ // Antigravity reads global hooks from ~/.gemini/config/hooks.json. Only the
100
+ // guard is registered there (PreToolUse); Antigravity's ALLOW-path audit is
101
+ // covered by the passive session-log collector, not a hook.
102
+ antigravityHooksPath: join(antigravityDir, "hooks.json"),
103
+ antigravityBackupPath: join(antigravityDir, "hooks.solongate.bak")
96
104
  };
97
105
  }
98
106
  function clearGuardUpdateCheck() {
@@ -110,6 +118,42 @@ function readGuard() {
110
118
  const bundled = join(HOOKS_DIR, "guard.bundled.mjs");
111
119
  return existsSync(bundled) ? readFileSync(bundled, "utf-8") : readHook("guard.mjs");
112
120
  }
121
+ var ANTIGRAVITY_GROUP = "solongate-guard";
122
+ function antigravityHookCommand(guardAbs) {
123
+ const nodeBin = process.execPath.replace(/\\/g, "/");
124
+ const call = process.platform === "win32" ? "& " : "";
125
+ return `${call}"${nodeBin}" "${guardAbs.replace(/\\/g, "/")}" antigravity "Antigravity"`;
126
+ }
127
+ function installAntigravityGuard(p, guardAbs) {
128
+ mkdirSync(p.antigravityDir, { recursive: true });
129
+ let existing = {};
130
+ if (existsSync(p.antigravityHooksPath)) {
131
+ const raw = readFileSync(p.antigravityHooksPath, "utf-8");
132
+ if (!existsSync(p.antigravityBackupPath)) writeFileSync(p.antigravityBackupPath, raw);
133
+ try {
134
+ existing = JSON.parse(raw);
135
+ } catch {
136
+ existing = {};
137
+ }
138
+ }
139
+ const merged = {
140
+ ...existing,
141
+ [ANTIGRAVITY_GROUP]: {
142
+ PreToolUse: [{ matcher: "", hooks: [{ type: "command", command: antigravityHookCommand(guardAbs) }] }]
143
+ }
144
+ };
145
+ writeFileSync(p.antigravityHooksPath, JSON.stringify(merged, null, 2) + "\n");
146
+ }
147
+ function removeAntigravityGuard(p) {
148
+ if (!existsSync(p.antigravityHooksPath)) return;
149
+ try {
150
+ const s = JSON.parse(readFileSync(p.antigravityHooksPath, "utf-8"));
151
+ if (!(ANTIGRAVITY_GROUP in s)) return;
152
+ delete s[ANTIGRAVITY_GROUP];
153
+ writeFileSync(p.antigravityHooksPath, JSON.stringify(s, null, 2) + "\n");
154
+ } catch {
155
+ }
156
+ }
113
157
  function ask(question) {
114
158
  const rl = createInterface({ input: process.stdin, output: process.stderr });
115
159
  return new Promise((res) => rl.question(question, (a) => {
@@ -121,6 +165,7 @@ function runGlobalRestore() {
121
165
  const p = globalPaths();
122
166
  unlockProtected();
123
167
  removeClaudeShim();
168
+ removeAntigravityGuard(p);
124
169
  if (existsSync(p.backupPath)) {
125
170
  writeFileSync(p.settingsPath, readFileSync(p.backupPath, "utf-8"));
126
171
  console.log(` Restored ${p.settingsPath} from backup.`);
@@ -179,6 +224,10 @@ function installGlobalQuiet() {
179
224
  }
180
225
  };
181
226
  writeFileSync(p.settingsPath, JSON.stringify(merged, null, 2) + "\n");
227
+ try {
228
+ installAntigravityGuard(p, join(p.hooksDir, "guard.mjs").replace(/\\/g, "/"));
229
+ } catch {
230
+ }
182
231
  if (process.env["SOLONGATE_OS_LOCK"] === "1") lockProtected();
183
232
  return { ok: true, message: "guard installed (open a new session)" };
184
233
  } catch (e) {
@@ -218,6 +267,10 @@ function uninstallGlobalQuiet() {
218
267
  const p = globalPaths();
219
268
  unlockProtected();
220
269
  removeClaudeShim();
270
+ try {
271
+ removeAntigravityGuard(p);
272
+ } catch {
273
+ }
221
274
  if (!existsSync(p.settingsPath)) return { ok: true, message: "guard removed (open a new session)" };
222
275
  const s = JSON.parse(readFileSync(p.settingsPath, "utf-8"));
223
276
  delete s.hooks;
@@ -356,6 +409,11 @@ async function runGlobalInstall(opts = {}) {
356
409
  };
357
410
  writeFileSync(p.settingsPath, JSON.stringify(merged, null, 2) + "\n");
358
411
  console.log(` Registered global hooks \u2192 ${p.settingsPath}`);
412
+ try {
413
+ installAntigravityGuard(p, guardAbs);
414
+ console.log(` Registered Antigravity CLI guard \u2192 ${p.antigravityHooksPath}`);
415
+ } catch {
416
+ }
359
417
  if (process.env["SOLONGATE_OS_LOCK"] === "1") {
360
418
  lockProtected();
361
419
  console.log(" Locked protection files (OS-level read-only/immutable).");
package/dist/index.js CHANGED
@@ -10210,7 +10210,8 @@ function protectedTargets() {
10210
10210
  join11(p.hooksDir, "stop.mjs"),
10211
10211
  join11(p.hooksDir, "shield.mjs"),
10212
10212
  p.configPath,
10213
- p.settingsPath
10213
+ p.settingsPath,
10214
+ p.antigravityHooksPath
10214
10215
  ];
10215
10216
  }
10216
10217
  function lockProtected() {
@@ -10224,14 +10225,21 @@ function globalPaths() {
10224
10225
  const sgDir = join11(home, ".solongate");
10225
10226
  const hooksDir = join11(sgDir, "hooks");
10226
10227
  const claudeDir = join11(home, ".claude");
10228
+ const antigravityDir = join11(home, ".gemini", "config");
10227
10229
  return {
10228
10230
  home,
10229
10231
  sgDir,
10230
10232
  hooksDir,
10231
10233
  claudeDir,
10234
+ antigravityDir,
10232
10235
  settingsPath: join11(claudeDir, "settings.json"),
10233
10236
  backupPath: join11(claudeDir, "settings.solongate.bak"),
10234
- configPath: join11(sgDir, "cloud-guard.json")
10237
+ configPath: join11(sgDir, "cloud-guard.json"),
10238
+ // Antigravity reads global hooks from ~/.gemini/config/hooks.json. Only the
10239
+ // guard is registered there (PreToolUse); Antigravity's ALLOW-path audit is
10240
+ // covered by the passive session-log collector, not a hook.
10241
+ antigravityHooksPath: join11(antigravityDir, "hooks.json"),
10242
+ antigravityBackupPath: join11(antigravityDir, "hooks.solongate.bak")
10235
10243
  };
10236
10244
  }
10237
10245
  function readHook(filename) {
@@ -10241,6 +10249,41 @@ function readGuard() {
10241
10249
  const bundled = join11(HOOKS_DIR, "guard.bundled.mjs");
10242
10250
  return existsSync4(bundled) ? readFileSync9(bundled, "utf-8") : readHook("guard.mjs");
10243
10251
  }
10252
+ function antigravityHookCommand(guardAbs) {
10253
+ const nodeBin = process.execPath.replace(/\\/g, "/");
10254
+ const call = process.platform === "win32" ? "& " : "";
10255
+ return `${call}"${nodeBin}" "${guardAbs.replace(/\\/g, "/")}" antigravity "Antigravity"`;
10256
+ }
10257
+ function installAntigravityGuard(p, guardAbs) {
10258
+ mkdirSync8(p.antigravityDir, { recursive: true });
10259
+ let existing = {};
10260
+ if (existsSync4(p.antigravityHooksPath)) {
10261
+ const raw = readFileSync9(p.antigravityHooksPath, "utf-8");
10262
+ if (!existsSync4(p.antigravityBackupPath)) writeFileSync9(p.antigravityBackupPath, raw);
10263
+ try {
10264
+ existing = JSON.parse(raw);
10265
+ } catch {
10266
+ existing = {};
10267
+ }
10268
+ }
10269
+ const merged = {
10270
+ ...existing,
10271
+ [ANTIGRAVITY_GROUP]: {
10272
+ PreToolUse: [{ matcher: "", hooks: [{ type: "command", command: antigravityHookCommand(guardAbs) }] }]
10273
+ }
10274
+ };
10275
+ writeFileSync9(p.antigravityHooksPath, JSON.stringify(merged, null, 2) + "\n");
10276
+ }
10277
+ function removeAntigravityGuard(p) {
10278
+ if (!existsSync4(p.antigravityHooksPath)) return;
10279
+ try {
10280
+ const s = JSON.parse(readFileSync9(p.antigravityHooksPath, "utf-8"));
10281
+ if (!(ANTIGRAVITY_GROUP in s)) return;
10282
+ delete s[ANTIGRAVITY_GROUP];
10283
+ writeFileSync9(p.antigravityHooksPath, JSON.stringify(s, null, 2) + "\n");
10284
+ } catch {
10285
+ }
10286
+ }
10244
10287
  function installGlobalQuiet() {
10245
10288
  try {
10246
10289
  const p = globalPaths();
@@ -10283,6 +10326,10 @@ function installGlobalQuiet() {
10283
10326
  }
10284
10327
  };
10285
10328
  writeFileSync9(p.settingsPath, JSON.stringify(merged, null, 2) + "\n");
10329
+ try {
10330
+ installAntigravityGuard(p, join11(p.hooksDir, "guard.mjs").replace(/\\/g, "/"));
10331
+ } catch {
10332
+ }
10286
10333
  if (process.env["SOLONGATE_OS_LOCK"] === "1") lockProtected();
10287
10334
  return { ok: true, message: "guard installed (open a new session)" };
10288
10335
  } catch (e) {
@@ -10322,6 +10369,10 @@ function uninstallGlobalQuiet() {
10322
10369
  const p = globalPaths();
10323
10370
  unlockProtected();
10324
10371
  removeClaudeShim();
10372
+ try {
10373
+ removeAntigravityGuard(p);
10374
+ } catch {
10375
+ }
10325
10376
  if (!existsSync4(p.settingsPath)) return { ok: true, message: "guard removed (open a new session)" };
10326
10377
  const s = JSON.parse(readFileSync9(p.settingsPath, "utf-8"));
10327
10378
  delete s.hooks;
@@ -10364,12 +10415,13 @@ function removeClaudeShim() {
10364
10415
  }
10365
10416
  }
10366
10417
  }
10367
- var __dirname, HOOKS_DIR, SHIM_BEGIN, SHIM_END;
10418
+ var __dirname, HOOKS_DIR, ANTIGRAVITY_GROUP, SHIM_BEGIN, SHIM_END;
10368
10419
  var init_global_install = __esm({
10369
10420
  "src/global-install.ts"() {
10370
10421
  "use strict";
10371
10422
  __dirname = dirname3(fileURLToPath3(import.meta.url));
10372
10423
  HOOKS_DIR = resolve4(__dirname, "..", "hooks");
10424
+ ANTIGRAVITY_GROUP = "solongate-guard";
10373
10425
  SHIM_BEGIN = "# >>> SolonGate shield (auto secret redaction) >>>";
10374
10426
  SHIM_END = "# <<< SolonGate shield <<<";
10375
10427
  }
@@ -13453,7 +13505,7 @@ console.log('MCP servers communicate over stdin/stdout \u2014 not HTTP.');
13453
13505
  console.log('You need an MCP client to connect:');
13454
13506
  console.log('');
13455
13507
  console.log(' Claude Code Open this folder, .mcp.json is auto-detected');
13456
- console.log(' Gemini CLI Open this folder, .mcp.json is auto-detected');
13508
+ console.log(' Antigravity .agents/mcp_config.json (or ~/.gemini/config/mcp_config.json)');
13457
13509
  console.log(' OpenClaw Uses openclaw.plugin.json config');
13458
13510
  console.log('');
13459
13511
  console.log('Press Ctrl+C to stop.');
@@ -16390,7 +16442,7 @@ var SolonGateProxy = class {
16390
16442
  const lower = raw.toLowerCase();
16391
16443
  if (lower.includes("claude-code") || lower === "claude code") return { id: "claude-code", name: "Claude Code" };
16392
16444
  if (lower.includes("claude")) return { id: "claude-desktop", name: "Claude Desktop" };
16393
- if (lower.includes("gemini")) return { id: "gemini-cli", name: "Gemini CLI" };
16445
+ if (lower.includes("antigravity") || lower === "agy") return { id: "antigravity", name: "Antigravity" };
16394
16446
  return { id: raw.toLowerCase().replace(/\s+/g, "-"), name: raw };
16395
16447
  }
16396
16448
  /** Extract sub-agent identity from MCP _meta field */
package/dist/lib.js CHANGED
@@ -9394,7 +9394,7 @@ var SolonGateProxy = class {
9394
9394
  const lower = raw.toLowerCase();
9395
9395
  if (lower.includes("claude-code") || lower === "claude code") return { id: "claude-code", name: "Claude Code" };
9396
9396
  if (lower.includes("claude")) return { id: "claude-desktop", name: "Claude Desktop" };
9397
- if (lower.includes("gemini")) return { id: "gemini-cli", name: "Gemini CLI" };
9397
+ if (lower.includes("antigravity") || lower === "agy") return { id: "antigravity", name: "Antigravity" };
9398
9398
  return { id: raw.toLowerCase().replace(/\s+/g, "-"), name: raw };
9399
9399
  }
9400
9400
  /** Extract sub-agent identity from MCP _meta field */
package/dist/login.js CHANGED
@@ -98,7 +98,8 @@ function protectedTargets() {
98
98
  join(p.hooksDir, "stop.mjs"),
99
99
  join(p.hooksDir, "shield.mjs"),
100
100
  p.configPath,
101
- p.settingsPath
101
+ p.settingsPath,
102
+ p.antigravityHooksPath
102
103
  ];
103
104
  }
104
105
  function lockProtected() {
@@ -112,14 +113,21 @@ function globalPaths() {
112
113
  const sgDir = join(home, ".solongate");
113
114
  const hooksDir = join(sgDir, "hooks");
114
115
  const claudeDir = join(home, ".claude");
116
+ const antigravityDir = join(home, ".gemini", "config");
115
117
  return {
116
118
  home,
117
119
  sgDir,
118
120
  hooksDir,
119
121
  claudeDir,
122
+ antigravityDir,
120
123
  settingsPath: join(claudeDir, "settings.json"),
121
124
  backupPath: join(claudeDir, "settings.solongate.bak"),
122
- configPath: join(sgDir, "cloud-guard.json")
125
+ configPath: join(sgDir, "cloud-guard.json"),
126
+ // Antigravity reads global hooks from ~/.gemini/config/hooks.json. Only the
127
+ // guard is registered there (PreToolUse); Antigravity's ALLOW-path audit is
128
+ // covered by the passive session-log collector, not a hook.
129
+ antigravityHooksPath: join(antigravityDir, "hooks.json"),
130
+ antigravityBackupPath: join(antigravityDir, "hooks.solongate.bak")
123
131
  };
124
132
  }
125
133
  function readHook(filename) {
@@ -129,6 +137,32 @@ function readGuard() {
129
137
  const bundled = join(HOOKS_DIR, "guard.bundled.mjs");
130
138
  return existsSync(bundled) ? readFileSync(bundled, "utf-8") : readHook("guard.mjs");
131
139
  }
140
+ var ANTIGRAVITY_GROUP = "solongate-guard";
141
+ function antigravityHookCommand(guardAbs) {
142
+ const nodeBin = process.execPath.replace(/\\/g, "/");
143
+ const call = process.platform === "win32" ? "& " : "";
144
+ return `${call}"${nodeBin}" "${guardAbs.replace(/\\/g, "/")}" antigravity "Antigravity"`;
145
+ }
146
+ function installAntigravityGuard(p, guardAbs) {
147
+ mkdirSync(p.antigravityDir, { recursive: true });
148
+ let existing = {};
149
+ if (existsSync(p.antigravityHooksPath)) {
150
+ const raw = readFileSync(p.antigravityHooksPath, "utf-8");
151
+ if (!existsSync(p.antigravityBackupPath)) writeFileSync(p.antigravityBackupPath, raw);
152
+ try {
153
+ existing = JSON.parse(raw);
154
+ } catch {
155
+ existing = {};
156
+ }
157
+ }
158
+ const merged = {
159
+ ...existing,
160
+ [ANTIGRAVITY_GROUP]: {
161
+ PreToolUse: [{ matcher: "", hooks: [{ type: "command", command: antigravityHookCommand(guardAbs) }] }]
162
+ }
163
+ };
164
+ writeFileSync(p.antigravityHooksPath, JSON.stringify(merged, null, 2) + "\n");
165
+ }
132
166
  function ask(question) {
133
167
  const rl = createInterface({ input: process.stdin, output: process.stderr });
134
168
  return new Promise((res) => rl.question(question, (a) => {
@@ -257,6 +291,11 @@ async function runGlobalInstall(opts = {}) {
257
291
  };
258
292
  writeFileSync(p.settingsPath, JSON.stringify(merged, null, 2) + "\n");
259
293
  console.log(` Registered global hooks \u2192 ${p.settingsPath}`);
294
+ try {
295
+ installAntigravityGuard(p, guardAbs);
296
+ console.log(` Registered Antigravity CLI guard \u2192 ${p.antigravityHooksPath}`);
297
+ } catch {
298
+ }
260
299
  if (process.env["SOLONGATE_OS_LOCK"] === "1") {
261
300
  lockProtected();
262
301
  console.log(" Locked protection files (OS-level read-only/immutable).");
package/dist/tui/index.js CHANGED
@@ -3268,7 +3268,8 @@ function protectedTargets() {
3268
3268
  join6(p.hooksDir, "stop.mjs"),
3269
3269
  join6(p.hooksDir, "shield.mjs"),
3270
3270
  p.configPath,
3271
- p.settingsPath
3271
+ p.settingsPath,
3272
+ p.antigravityHooksPath
3272
3273
  ];
3273
3274
  }
3274
3275
  function lockProtected() {
@@ -3282,14 +3283,21 @@ function globalPaths() {
3282
3283
  const sgDir = join6(home, ".solongate");
3283
3284
  const hooksDir = join6(sgDir, "hooks");
3284
3285
  const claudeDir = join6(home, ".claude");
3286
+ const antigravityDir = join6(home, ".gemini", "config");
3285
3287
  return {
3286
3288
  home,
3287
3289
  sgDir,
3288
3290
  hooksDir,
3289
3291
  claudeDir,
3292
+ antigravityDir,
3290
3293
  settingsPath: join6(claudeDir, "settings.json"),
3291
3294
  backupPath: join6(claudeDir, "settings.solongate.bak"),
3292
- configPath: join6(sgDir, "cloud-guard.json")
3295
+ configPath: join6(sgDir, "cloud-guard.json"),
3296
+ // Antigravity reads global hooks from ~/.gemini/config/hooks.json. Only the
3297
+ // guard is registered there (PreToolUse); Antigravity's ALLOW-path audit is
3298
+ // covered by the passive session-log collector, not a hook.
3299
+ antigravityHooksPath: join6(antigravityDir, "hooks.json"),
3300
+ antigravityBackupPath: join6(antigravityDir, "hooks.solongate.bak")
3293
3301
  };
3294
3302
  }
3295
3303
  function readHook(filename) {
@@ -3299,6 +3307,42 @@ function readGuard() {
3299
3307
  const bundled = join6(HOOKS_DIR, "guard.bundled.mjs");
3300
3308
  return existsSync2(bundled) ? readFileSync4(bundled, "utf-8") : readHook("guard.mjs");
3301
3309
  }
3310
+ var ANTIGRAVITY_GROUP = "solongate-guard";
3311
+ function antigravityHookCommand(guardAbs) {
3312
+ const nodeBin = process.execPath.replace(/\\/g, "/");
3313
+ const call = process.platform === "win32" ? "& " : "";
3314
+ return `${call}"${nodeBin}" "${guardAbs.replace(/\\/g, "/")}" antigravity "Antigravity"`;
3315
+ }
3316
+ function installAntigravityGuard(p, guardAbs) {
3317
+ mkdirSync4(p.antigravityDir, { recursive: true });
3318
+ let existing = {};
3319
+ if (existsSync2(p.antigravityHooksPath)) {
3320
+ const raw = readFileSync4(p.antigravityHooksPath, "utf-8");
3321
+ if (!existsSync2(p.antigravityBackupPath)) writeFileSync5(p.antigravityBackupPath, raw);
3322
+ try {
3323
+ existing = JSON.parse(raw);
3324
+ } catch {
3325
+ existing = {};
3326
+ }
3327
+ }
3328
+ const merged = {
3329
+ ...existing,
3330
+ [ANTIGRAVITY_GROUP]: {
3331
+ PreToolUse: [{ matcher: "", hooks: [{ type: "command", command: antigravityHookCommand(guardAbs) }] }]
3332
+ }
3333
+ };
3334
+ writeFileSync5(p.antigravityHooksPath, JSON.stringify(merged, null, 2) + "\n");
3335
+ }
3336
+ function removeAntigravityGuard(p) {
3337
+ if (!existsSync2(p.antigravityHooksPath)) return;
3338
+ try {
3339
+ const s = JSON.parse(readFileSync4(p.antigravityHooksPath, "utf-8"));
3340
+ if (!(ANTIGRAVITY_GROUP in s)) return;
3341
+ delete s[ANTIGRAVITY_GROUP];
3342
+ writeFileSync5(p.antigravityHooksPath, JSON.stringify(s, null, 2) + "\n");
3343
+ } catch {
3344
+ }
3345
+ }
3302
3346
  function installGlobalQuiet() {
3303
3347
  try {
3304
3348
  const p = globalPaths();
@@ -3341,6 +3385,10 @@ function installGlobalQuiet() {
3341
3385
  }
3342
3386
  };
3343
3387
  writeFileSync5(p.settingsPath, JSON.stringify(merged, null, 2) + "\n");
3388
+ try {
3389
+ installAntigravityGuard(p, join6(p.hooksDir, "guard.mjs").replace(/\\/g, "/"));
3390
+ } catch {
3391
+ }
3344
3392
  if (process.env["SOLONGATE_OS_LOCK"] === "1") lockProtected();
3345
3393
  return { ok: true, message: "guard installed (open a new session)" };
3346
3394
  } catch (e) {
@@ -3380,6 +3428,10 @@ function uninstallGlobalQuiet() {
3380
3428
  const p = globalPaths();
3381
3429
  unlockProtected();
3382
3430
  removeClaudeShim();
3431
+ try {
3432
+ removeAntigravityGuard(p);
3433
+ } catch {
3434
+ }
3383
3435
  if (!existsSync2(p.settingsPath)) return { ok: true, message: "guard removed (open a new session)" };
3384
3436
  const s = JSON.parse(readFileSync4(p.settingsPath, "utf-8"));
3385
3437
  delete s.hooks;
@@ -6536,7 +6536,7 @@ import { resolve, join, dirname, isAbsolute } from "node:path";
6536
6536
  import { homedir } from "node:os";
6537
6537
  import { gunzipSync } from "node:zlib";
6538
6538
  import { createHash } from "node:crypto";
6539
- var HOOK_VERSION = 43;
6539
+ var HOOK_VERSION = 44;
6540
6540
  function localLogsOnly(security) {
6541
6541
  if (security && typeof security === "object") {
6542
6542
  const l = security.localLogs;
@@ -6797,7 +6797,7 @@ function sgFinish(code) {
6797
6797
  throw SG_DONE;
6798
6798
  }
6799
6799
  function blockTool(reason) {
6800
- if (AGENT_TYPE === "gemini-cli") {
6800
+ if (AGENT_TYPE === "antigravity") {
6801
6801
  process.stdout.write(JSON.stringify({
6802
6802
  decision: "deny",
6803
6803
  reason: `[SolonGate] ${reason}`
@@ -6817,7 +6817,7 @@ function blockTool(reason) {
6817
6817
  }
6818
6818
  }
6819
6819
  function allowTool() {
6820
- if (AGENT_TYPE === "gemini-cli") {
6820
+ if (AGENT_TYPE === "antigravity") {
6821
6821
  process.stdout.write(JSON.stringify({ decision: "allow" }));
6822
6822
  }
6823
6823
  sgFinish(0);
@@ -7072,7 +7072,12 @@ var TAMPER_PATH_FIELDS = /* @__PURE__ */ new Set([
7072
7072
  "to",
7073
7073
  "directory",
7074
7074
  "dir",
7075
- "folder"
7075
+ "folder",
7076
+ // Antigravity CLI file-tool arg names (camelCase, lowercased here): its
7077
+ // write/read/list tools carry the path in these, so tamper protection sees it.
7078
+ "targetfile",
7079
+ "absolutepath",
7080
+ "filepath"
7076
7081
  ]);
7077
7082
  function normTamperPath(p) {
7078
7083
  return String(p || "").replace(/\\/g, "/").toLowerCase();
@@ -7763,13 +7768,30 @@ if (!REFRESH_MODE) {
7763
7768
  }
7764
7769
  let mappedToolName = raw.tool_name || raw.toolName || "";
7765
7770
  let mappedToolInput = raw.tool_input || raw.toolInput || raw.params || {};
7771
+ let mappedSession = raw.session_id || raw.sessionId || raw.conversation_id || "";
7772
+ let mappedCwd = raw.cwd || "";
7773
+ if (raw.toolCall && typeof raw.toolCall === "object") {
7774
+ const tc = raw.toolCall;
7775
+ mappedToolName = mappedToolName || tc.name || "";
7776
+ const a = tc.args && typeof tc.args === "object" ? tc.args : {};
7777
+ mappedToolInput = { ...a };
7778
+ if (typeof a.CommandLine === "string" && mappedToolInput.command == null)
7779
+ mappedToolInput.command = a.CommandLine;
7780
+ mappedSession = mappedSession || raw.conversationId || "";
7781
+ if (!mappedCwd) {
7782
+ if (typeof a.Cwd === "string" && a.Cwd)
7783
+ mappedCwd = a.Cwd;
7784
+ else if (Array.isArray(raw.workspacePaths) && typeof raw.workspacePaths[0] === "string")
7785
+ mappedCwd = raw.workspacePaths[0];
7786
+ }
7787
+ }
7766
7788
  const data = {
7767
7789
  ...raw,
7768
7790
  tool_name: mappedToolName,
7769
7791
  tool_input: mappedToolInput,
7770
7792
  tool_response: raw.tool_response || raw.toolResponse || {},
7771
- cwd: raw.cwd || process.cwd(),
7772
- session_id: raw.session_id || raw.sessionId || raw.conversation_id || ""
7793
+ cwd: mappedCwd || process.cwd(),
7794
+ session_id: mappedSession
7773
7795
  };
7774
7796
  const args = data.tool_input;
7775
7797
  const toolName = data.tool_name || "";
@@ -7943,7 +7965,7 @@ if (!REFRESH_MODE) {
7943
7965
  } catch {
7944
7966
  }
7945
7967
  await maybeSelfUpdate();
7946
- if (AGENT_TYPE === "gemini-cli") {
7968
+ if (AGENT_TYPE === "antigravity") {
7947
7969
  process.stdout.write(JSON.stringify({ decision: "deny", reason: ghostHit }));
7948
7970
  sgFinish(0);
7949
7971
  }
@@ -7951,7 +7973,7 @@ if (!REFRESH_MODE) {
7951
7973
  process.stderr.write(ghostHit + "\n");
7952
7974
  sgFinish(2);
7953
7975
  }
7954
- if (AGENT_TYPE !== "gemini-cli" && toolName === "Bash") {
7976
+ if (AGENT_TYPE !== "antigravity" && toolName === "Bash") {
7955
7977
  const rw = ghostListingRewrite(args, securityCfg.ghost);
7956
7978
  if (rw) {
7957
7979
  await maybeSelfUpdate();
package/hooks/guard.mjs CHANGED
@@ -32,7 +32,7 @@ import { createHash } from 'node:crypto';
32
32
  // the installed hook self-updates when the cloud version is higher (see
33
33
  // maybeSelfUpdate). This is what makes guard fixes propagate without a manual
34
34
  // reinstall — the same trust model as the OPA WASM this hook already runs.
35
- const HOOK_VERSION = 43;
35
+ const HOOK_VERSION = 44;
36
36
 
37
37
  // True when local log storage is ON. In that mode logs are kept LOCAL ONLY and
38
38
  // nothing is sent to the cloud audit log.
@@ -276,7 +276,7 @@ async function maybeSelfUpdate() {
276
276
  // Two distinct identities, deliberately kept separate:
277
277
  //
278
278
  // AGENT_TYPE — the real AI client running this hook (claude-code /
279
- // gemini-cli / openclaw). Baked into the hook registration by the installer
279
+ // antigravity / openclaw). Baked into the hook registration by the installer
280
280
  // as argv[2] (e.g. `node guard.mjs claude-code`). Decides the response
281
281
  // format AND whether a selected policy actually applies to this client.
282
282
  //
@@ -344,8 +344,8 @@ if (REFRESH_MODE) { try { setTimeout(() => { try { process.exit(process.exitCode
344
344
 
345
345
  // ── Per-tool block/allow output ──
346
346
  // Response format depends on the agent:
347
- // Claude Code: exit 2 + stderr = BLOCK, exit 0 = ALLOW
348
- // Gemini CLI: {"decision": "deny/allow", "reason": "..."}
347
+ // Claude Code: exit 2 + stderr = BLOCK, exit 0 = ALLOW
348
+ // Antigravity CLI: {"decision": "deny/allow", "reason": "..."} on stdout (exit 0)
349
349
 
350
350
  // Terminate the hook WITHOUT forcing process.exit(). On Windows + Node 24, calling
351
351
  // process.exit() right after a fetch() (the cloud audit-log POST) aborts with
@@ -378,7 +378,7 @@ function sgFinish(code) {
378
378
  }
379
379
 
380
380
  function blockTool(reason) {
381
- if (AGENT_TYPE === 'gemini-cli') {
381
+ if (AGENT_TYPE === 'antigravity') {
382
382
  process.stdout.write(JSON.stringify({
383
383
  decision: 'deny',
384
384
  reason: `[SolonGate] ${reason}`,
@@ -408,7 +408,7 @@ function blockTool(reason) {
408
408
  }
409
409
 
410
410
  function allowTool() {
411
- if (AGENT_TYPE === 'gemini-cli') {
411
+ if (AGENT_TYPE === 'antigravity') {
412
412
  process.stdout.write(JSON.stringify({ decision: 'allow' }));
413
413
  }
414
414
  sgFinish(0);
@@ -784,6 +784,9 @@ const TAMPER_PATH_FIELDS = new Set([
784
784
  'file_path', 'path', 'target_file', 'notebook_path',
785
785
  'dest', 'destination', 'source', 'src', 'from', 'to',
786
786
  'directory', 'dir', 'folder',
787
+ // Antigravity CLI file-tool arg names (camelCase, lowercased here): its
788
+ // write/read/list tools carry the path in these, so tamper protection sees it.
789
+ 'targetfile', 'absolutepath', 'filepath',
787
790
  ]);
788
791
 
789
792
  function normTamperPath(p) {
@@ -1581,6 +1584,30 @@ if (!REFRESH_MODE) { try { input += readFileSync(0, 'utf-8'); } catch {} }
1581
1584
 
1582
1585
  let mappedToolName = raw.tool_name || raw.toolName || '';
1583
1586
  let mappedToolInput = raw.tool_input || raw.toolInput || raw.params || {};
1587
+ let mappedSession = raw.session_id || raw.sessionId || raw.conversation_id || '';
1588
+ let mappedCwd = raw.cwd || '';
1589
+
1590
+ // Antigravity CLI (PreToolUse) nests the tool under a `toolCall` object
1591
+ // ({ name, args: { CommandLine, Cwd, ... } }) and carries metadata in
1592
+ // camelCase (conversationId, workspacePaths) — a different shape from the
1593
+ // flat Claude/Gemini payload. Flatten it into the fields the guard's
1594
+ // extractors read, and alias the shell command (args.CommandLine) to
1595
+ // `command` so extractCommands / tamperCheck / command policies see it. Tool
1596
+ // NAMES need no remapping: guessPermission/tamperCheck already classify
1597
+ // Antigravity's snake_case names (run_command → EXECUTE via "run",
1598
+ // write_to_file → WRITE, read_file → READ) by substring.
1599
+ if (raw.toolCall && typeof raw.toolCall === 'object') {
1600
+ const tc = raw.toolCall;
1601
+ mappedToolName = mappedToolName || tc.name || '';
1602
+ const a = (tc.args && typeof tc.args === 'object') ? tc.args : {};
1603
+ mappedToolInput = { ...a };
1604
+ if (typeof a.CommandLine === 'string' && mappedToolInput.command == null) mappedToolInput.command = a.CommandLine;
1605
+ mappedSession = mappedSession || raw.conversationId || '';
1606
+ if (!mappedCwd) {
1607
+ if (typeof a.Cwd === 'string' && a.Cwd) mappedCwd = a.Cwd;
1608
+ else if (Array.isArray(raw.workspacePaths) && typeof raw.workspacePaths[0] === 'string') mappedCwd = raw.workspacePaths[0];
1609
+ }
1610
+ }
1584
1611
 
1585
1612
  // Normalize field names across tools
1586
1613
  const data = {
@@ -1588,8 +1615,8 @@ if (!REFRESH_MODE) { try { input += readFileSync(0, 'utf-8'); } catch {} }
1588
1615
  tool_name: mappedToolName,
1589
1616
  tool_input: mappedToolInput,
1590
1617
  tool_response: raw.tool_response || raw.toolResponse || {},
1591
- cwd: raw.cwd || process.cwd(),
1592
- session_id: raw.session_id || raw.sessionId || raw.conversation_id || '',
1618
+ cwd: mappedCwd || process.cwd(),
1619
+ session_id: mappedSession,
1593
1620
  };
1594
1621
  const args = data.tool_input;
1595
1622
  const toolName = data.tool_name || '';
@@ -1789,7 +1816,7 @@ if (!REFRESH_MODE) { try { input += readFileSync(0, 'utf-8'); } catch {} }
1789
1816
  });
1790
1817
  } catch {}
1791
1818
  await maybeSelfUpdate();
1792
- if (AGENT_TYPE === 'gemini-cli') { process.stdout.write(JSON.stringify({ decision: 'deny', reason: ghostHit })); sgFinish(0); }
1819
+ if (AGENT_TYPE === 'antigravity') { process.stdout.write(JSON.stringify({ decision: 'deny', reason: ghostHit })); sgFinish(0); }
1793
1820
  // Claude Code: JSON deny on stdout + exit 2 (reason on stderr). Exit 2 is
1794
1821
  // the only block enforced in auto-accept mode (see blockTool); the JSON is
1795
1822
  // the Windows fallback. ghostHit is a bare "No such file or directory", so
@@ -1800,7 +1827,7 @@ if (!REFRESH_MODE) { try { input += readFileSync(0, 'utf-8'); } catch {} }
1800
1827
  }
1801
1828
  // No direct hit: if this is a listing command, rewrite it so hidden
1802
1829
  // entries are filtered out of its output (Claude Code only).
1803
- if (AGENT_TYPE !== 'gemini-cli' && toolName === 'Bash') {
1830
+ if (AGENT_TYPE !== 'antigravity' && toolName === 'Bash') {
1804
1831
  const rw = ghostListingRewrite(args, securityCfg.ghost);
1805
1832
  if (rw) { await maybeSelfUpdate(); rewriteTool({ command: rw }); }
1806
1833
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@solongate/proxy",
3
- "version": "0.82.10",
3
+ "version": "0.82.12",
4
4
  "description": "AI tool security proxy: protect any AI tool server with customizable policies, path/command constraints, rate limiting, and audit logging. No code changes required.",
5
5
  "type": "module",
6
6
  "bin": {