@estebanforge/pi-ask-antigravity 1.2.7 → 1.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +13 -0
- package/extensions/index.ts +222 -15
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.2.9] - 2026-09-28
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- **Plan-mode delegations enforce read-only instead of promising it.** Port of the bridge fix one commit earlier in the stack: the prompt-only guard failed in the field (a plan delegation behind an env-injected skip flag still edited files), so plan-mode runs now stage a temporary agy agent — `tools:` limited to `view_file` and `run_command`, `commandExecutionPolicy: auto`, `inheritMcp: false` — under the shared `~/.gemini/config/agents` discovery root and pass `--agent`. No file-editing tool in the toolset means no edit call is possible, with or without `--dangerously-skip-permissions` (probed on agy 1.2.12); the policy is what lets analysis commands run headless for users with no allow rules. With the agent staged, the skip flag returns under the shared `skipPermissions` knob; staging failure falls back fail-closed to no agent, no flag, and the strict all-commands-forbidden guard, with an env-injected skip flag stripped from `AGY_EXTRA_ARGS` on that path. Includes the standalone sweep for orphaned agent dirs (pid-marker doctrine), duplicated rather than extracted: the standalone stays self-contained per repo convention. Tool descriptions state the residual honestly: file-editing tools are hard-blocked, arbitrary shell execution under the flag is prompt-guarded alone.
|
|
10
|
+
- **Headless plan prompts say what they cannot do.** Same hardening as the bridge: plan prompts append an explicit no-commands constraint and a state-what-is-missing instruction, converting the soft-denied empty-output death of a shell-command attempt into a visible missing-content request. On the enforced path the guard yields to the mutation-forbidding variant; the command-forbidding rule remains on the fallback path.
|
|
11
|
+
|
|
12
|
+
## [1.2.8] - 2026-09-25
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- **Exit 0 with no output is a failure, not a silent success.** Same bug as the bridge fix: a headless `agy -p` run auto-denies a permission-gated tool call (the command gate in plan mode bites hardest since plan runs never receive the skip flag), prints the reason only to stderr, exits 0, and the execute path fell through to success, returning just the conversation footer. An empty answer now returns a loud failure note carrying the stderr plus the remedy (allow-list the command under `permissions.allow`, or rerun outside plan mode), and a new `details.empty` marker flips the TUI result row to its error glyph instead of a green checkmark. Three new tests pin both stderr shapes and the glyph flip through the fake-binary stub; HOME is pointed at an empty tmpdir during them so the bridge-deferral scan finds nothing and the factory registers.
|
|
17
|
+
|
|
5
18
|
## [1.2.7] - 2026-09-25
|
|
6
19
|
|
|
7
20
|
### Fixed
|
package/extensions/index.ts
CHANGED
|
@@ -29,6 +29,7 @@
|
|
|
29
29
|
*/
|
|
30
30
|
|
|
31
31
|
import { spawn } from "node:child_process";
|
|
32
|
+
import { randomBytes } from "node:crypto";
|
|
32
33
|
import * as fs from "node:fs";
|
|
33
34
|
import * as os from "node:os";
|
|
34
35
|
import * as path from "node:path";
|
|
@@ -156,7 +157,7 @@ TWO MODES (you choose):
|
|
|
156
157
|
- **Continued conversation**: pass the conversationId returned in the PREVIOUS call's details (details.conversationId). agy resumes that conversation with full context intact — use for follow-ups, multi-turn refinement, or when the user says "ask agy to follow up / continue / now do X based on what you just did". Thread the id from each result into the next call.
|
|
157
158
|
|
|
158
159
|
EXECUTION MODES (param: mode):
|
|
159
|
-
- **plan**: agy reviews and plans without writing. Use for cross-review and read-only tasks. Enforced: plan runs
|
|
160
|
+
- **plan**: agy reviews and plans without writing. Use for cross-review and read-only tasks. Enforced: plan runs execute in a temporary restricted agent whose toolset has NO file-editing tools (hard block); the reviewer may still execute arbitrary shell commands, kept read-only by the prompt guard alone. Inline the material to review - a plan run cannot fetch it.
|
|
160
161
|
- **accept-edits** (default): agy applies edits directly inside the workspace.
|
|
161
162
|
- For agy's orthogonal \`--sandbox\` shell-containment flag, set the \`AGY_EXTRA_ARGS=--sandbox\` env var.
|
|
162
163
|
|
|
@@ -282,6 +283,150 @@ function saveConfig(patch: Partial<Config>): SaveResult {
|
|
|
282
283
|
return { path: targetPath, routedToProject: projectShadows };
|
|
283
284
|
}
|
|
284
285
|
|
|
286
|
+
// --- Prompt assembly -------------------------------------------------------
|
|
287
|
+
|
|
288
|
+
/** Appended to every headless plan-mode prompt. `agy -p` cannot answer
|
|
289
|
+
* permission prompts: in plan mode a run_command attempt is soft-denied and
|
|
290
|
+
* the turn ends AT the denial (exit 0, empty stdout, notice only on stderr -
|
|
291
|
+
* the empty-output branch in execute). Probed 2026-09-28 on agy 1.2.12:
|
|
292
|
+
* allow rules ARE consulted (a verbatim allow-listed `git log` runs), but
|
|
293
|
+
* --sandbox does NOT relax the command gate, so the only input every user
|
|
294
|
+
* is guaranteed is the prompt itself. The guard steers the model to answer
|
|
295
|
+
* from that material. accept-edits runs keep their tools and never get it. */
|
|
296
|
+
export const PLAN_HEADLESS_GUARD = [
|
|
297
|
+
"",
|
|
298
|
+
"--- Headless session constraints ---",
|
|
299
|
+
"- Do not run shell commands. Command execution is denied in this session, and any attempt ends the session immediately with no answer.",
|
|
300
|
+
"- Work only from the material provided in this prompt.",
|
|
301
|
+
"- If information you need is missing, state exactly what is missing in your answer instead of trying to fetch it.",
|
|
302
|
+
].join("\n");
|
|
303
|
+
|
|
304
|
+
/** Guard for plan runs backed by the restricted reviewer agent. Difference
|
|
305
|
+
* to PLAN_HEADLESS_GUARD: commands are the analysis capability here (the
|
|
306
|
+
* agent's commandExecutionPolicy auto-approves them headless, probed
|
|
307
|
+
* 2026-09-28), so the guard forbids FILE MUTATION - by tool or by shell -
|
|
308
|
+
* and keeps the answer-from-material discipline. */
|
|
309
|
+
export const AGENT_REVIEW_GUARD = [
|
|
310
|
+
"",
|
|
311
|
+
"--- Review constraints ---",
|
|
312
|
+
"- Read-only review. Do not create, modify, or delete any files, including through shell commands (no redirects, tee, rm, mv, git commit).",
|
|
313
|
+
"- Read-only commands (git log, git diff, git show, rg, ls, cat, test runners) are allowed for analysis.",
|
|
314
|
+
"- Work from the material provided in this prompt; if information you need is missing, state exactly what is missing in your answer.",
|
|
315
|
+
].join("\n");
|
|
316
|
+
|
|
317
|
+
/** Assemble the prompt sent to agy: digest marker first (existing behavior),
|
|
318
|
+
* then the caller's prompt, then the plan-mode guard last - the position
|
|
319
|
+
* the model reads with the most recency. No user-config mutation: this is
|
|
320
|
+
* the only plan-mode lever the tool itself owns. */
|
|
321
|
+
export function buildFinalPrompt(
|
|
322
|
+
prompt: string,
|
|
323
|
+
mode: Mode,
|
|
324
|
+
digest: boolean,
|
|
325
|
+
/** True when the restricted reviewer agent is staged: its empty edit
|
|
326
|
+
* toolset is the hard block, so the prompt may ALLOW read-only commands. */
|
|
327
|
+
agentEnforced = false,
|
|
328
|
+
): string {
|
|
329
|
+
let out = digest ? `(Use compact digests, not full file contents.)\n${prompt}` : prompt;
|
|
330
|
+
if (mode === "plan") out += agentEnforced ? AGENT_REVIEW_GUARD : PLAN_HEADLESS_GUARD;
|
|
331
|
+
return out;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// --- Plan-mode reviewer agent ----------------------------------------------
|
|
335
|
+
|
|
336
|
+
const ASK_AGENT_PREFIX = "pi-bridge-ask-";
|
|
337
|
+
const ASK_AGENT_TOOLS = ["view_file", "run_command"];
|
|
338
|
+
|
|
339
|
+
/** Temp agent dirs share the ~/.gemini/config/agents discovery root; the
|
|
340
|
+
* AGY_AGENTS_ROOT override exists for tests and sandboxes. */
|
|
341
|
+
export function askAgentsRoot(): string {
|
|
342
|
+
return process.env.AGY_AGENTS_ROOT ?? path.join(os.homedir(), ".gemini", "config", "agents");
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/** agent.md for the plan-mode reviewer. The tools list is the ENFORCEMENT:
|
|
346
|
+
* with no file-editing tool present the model cannot emit an edit call at
|
|
347
|
+
* all (probed 2026-09-28 on agy 1.2.12: the toolset reports "none" for
|
|
348
|
+
* edits, with and without the skip flag). commandExecutionPolicy auto is
|
|
349
|
+
* what lets read commands run headless with no user allow rules. Never add
|
|
350
|
+
* a write-capable tool here. */
|
|
351
|
+
export function reviewerAgentMd(name: string): string {
|
|
352
|
+
return [
|
|
353
|
+
"---",
|
|
354
|
+
`name: ${name}`,
|
|
355
|
+
"description: Temporary Pi plan-mode reviewer",
|
|
356
|
+
"mainAgent: true",
|
|
357
|
+
"subagent: false",
|
|
358
|
+
"model: inherit",
|
|
359
|
+
"excludeDefaultComponents: true",
|
|
360
|
+
"inheritCustomizations: false",
|
|
361
|
+
"inheritMcp: false",
|
|
362
|
+
"commandExecutionPolicy: auto",
|
|
363
|
+
"tools:",
|
|
364
|
+
...ASK_AGENT_TOOLS.map((t) => ` - ${t}`),
|
|
365
|
+
"skills: []",
|
|
366
|
+
"rules: []",
|
|
367
|
+
"agents: []",
|
|
368
|
+
"mcpServers: []",
|
|
369
|
+
"---",
|
|
370
|
+
"",
|
|
371
|
+
"You are a strict read-only code reviewer. Review, analyze, and plan; never modify anything.",
|
|
372
|
+
"",
|
|
373
|
+
].join("\n");
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
/** Stage one unique reviewer agent (agent.md + pid marker) under root. Same
|
|
377
|
+
* hygiene doctrine as the web delegates: nonce-named, cleaned in finally,
|
|
378
|
+
* orphans swept by pid marker at registration. */
|
|
379
|
+
export function stageReviewerAgent(root: string): { name: string; dir: string } {
|
|
380
|
+
fs.mkdirSync(root, { recursive: true });
|
|
381
|
+
const name = `${ASK_AGENT_PREFIX}${process.pid}-${Date.now().toString(36)}-${randomBytes(4).toString("hex")}`;
|
|
382
|
+
const dir = path.join(root, name);
|
|
383
|
+
fs.mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
384
|
+
fs.writeFileSync(path.join(dir, "agent.md"), reviewerAgentMd(name), { mode: 0o600 });
|
|
385
|
+
fs.writeFileSync(path.join(dir, ".pid"), `${process.pid}\n`, { mode: 0o600 });
|
|
386
|
+
return { name, dir };
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/** Remove leftover reviewer agent dirs: dead-pid markers always, marker-less
|
|
390
|
+
* dirs only after the grace period (a live sibling may sit between mkdir and
|
|
391
|
+
* its pid write). Never touches foreign agent dirs. */
|
|
392
|
+
export function sweepStaleAskAgents(
|
|
393
|
+
root: string = askAgentsRoot(),
|
|
394
|
+
now = Date.now(),
|
|
395
|
+
prefix: string = ASK_AGENT_PREFIX,
|
|
396
|
+
): void {
|
|
397
|
+
let entries: string[];
|
|
398
|
+
try {
|
|
399
|
+
entries = fs.readdirSync(root);
|
|
400
|
+
} catch {
|
|
401
|
+
return; // no agents dir yet: nothing to sweep
|
|
402
|
+
}
|
|
403
|
+
for (const entry of entries) {
|
|
404
|
+
if (!entry.startsWith(prefix)) continue;
|
|
405
|
+
const dir = path.join(root, entry);
|
|
406
|
+
try {
|
|
407
|
+
let stale: boolean;
|
|
408
|
+
try {
|
|
409
|
+
const pid = Number.parseInt(fs.readFileSync(path.join(dir, ".pid"), "utf8").trim(), 10);
|
|
410
|
+
stale = Number.isInteger(pid) && pid > 0 ? !pidAlive(pid) : now - fs.statSync(dir).mtimeMs > 24 * 60 * 60 * 1000;
|
|
411
|
+
} catch {
|
|
412
|
+
stale = now - fs.statSync(dir).mtimeMs > 24 * 60 * 60 * 1000;
|
|
413
|
+
}
|
|
414
|
+
if (stale) fs.rmSync(dir, { recursive: true, force: true });
|
|
415
|
+
} catch {
|
|
416
|
+
// vanished mid-sweep: nothing to remove
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
function pidAlive(pid: number): boolean {
|
|
422
|
+
try {
|
|
423
|
+
process.kill(pid, 0);
|
|
424
|
+
return true;
|
|
425
|
+
} catch {
|
|
426
|
+
return false;
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
285
430
|
// --- Model parsing + alias resolution --------------------------------------
|
|
286
431
|
|
|
287
432
|
/** Parse one `agy models` line into a structured entry. */
|
|
@@ -762,6 +907,9 @@ interface AgyDetails {
|
|
|
762
907
|
exitCode: number;
|
|
763
908
|
aborted: boolean;
|
|
764
909
|
timedOut: boolean;
|
|
910
|
+
// Exit 0 with no answer on stdout (the empty-output failure branch).
|
|
911
|
+
// renderResult flips to the error glyph on it.
|
|
912
|
+
empty?: boolean;
|
|
765
913
|
durationMs: number;
|
|
766
914
|
stderr: string;
|
|
767
915
|
}
|
|
@@ -773,6 +921,14 @@ export default async function (pi: ExtensionAPI) {
|
|
|
773
921
|
// before (standalone tool).
|
|
774
922
|
if (isBridgeInstalled()) return;
|
|
775
923
|
|
|
924
|
+
// Orphan sweep for the plan-mode reviewer agents (SIGKILL can skip the
|
|
925
|
+
// run's finally): same pid-marker doctrine as the bridge's web delegates.
|
|
926
|
+
try {
|
|
927
|
+
sweepStaleAskAgents();
|
|
928
|
+
} catch {
|
|
929
|
+
// a sweep failure must never block registration
|
|
930
|
+
}
|
|
931
|
+
|
|
776
932
|
const binary = resolveAgy();
|
|
777
933
|
// Discovered once at load; frozen for the session. Run /reload after an
|
|
778
934
|
// `agy update` to refresh. Failure is non-fatal: resolveModel falls back
|
|
@@ -951,7 +1107,7 @@ export default async function (pi: ExtensionAPI) {
|
|
|
951
1107
|
],
|
|
952
1108
|
{
|
|
953
1109
|
description:
|
|
954
|
-
"agy execution mode. 'plan' = review-only
|
|
1110
|
+
"agy execution mode. 'plan' = review-only (--mode plan in a temporary restricted agent: file-editing tools are hard-blocked; arbitrary shell commands remain prompt-guarded only; with skipPermissions on, commands still run for analysis). 'accept-edits' = agy applies edits directly (--mode accept-edits, default). For agy's orthogonal --sandbox shell-containment flag, set the AGY_EXTRA_ARGS env var.",
|
|
955
1111
|
default: "accept-edits",
|
|
956
1112
|
},
|
|
957
1113
|
),
|
|
@@ -1027,7 +1183,8 @@ export default async function (pi: ExtensionAPI) {
|
|
|
1027
1183
|
}
|
|
1028
1184
|
|
|
1029
1185
|
const body = result.content[0]?.type === "text" ? result.content[0].text : "";
|
|
1030
|
-
const errored =
|
|
1186
|
+
const errored =
|
|
1187
|
+
d?.exitCode !== 0 || !!d?.aborted || !!d?.timedOut || !!d?.empty;
|
|
1031
1188
|
|
|
1032
1189
|
let text = errored
|
|
1033
1190
|
? theme.fg("error", "✗ AskAntigravity error")
|
|
@@ -1158,6 +1315,19 @@ export default async function (pi: ExtensionAPI) {
|
|
|
1158
1315
|
const snapshot = isContinuation ? null : snapshotConversations(CONVERSATIONS_DIR);
|
|
1159
1316
|
|
|
1160
1317
|
const mode: Mode = (params.mode as Mode | undefined) ?? "accept-edits";
|
|
1318
|
+
// Plan runs stage a restricted reviewer agent: its tools list has NO
|
|
1319
|
+
// file-editing tool, which is the hard edit block (the prompt guard
|
|
1320
|
+
// alone was observed failing once - a sub-agent still edited files).
|
|
1321
|
+
// Staging failure degrades to the legacy fallback: no agent, no skip
|
|
1322
|
+
// flag, the stricter command-forbidding guard.
|
|
1323
|
+
let reviewerAgent: { name: string; dir: string } | null = null;
|
|
1324
|
+
if (mode === "plan") {
|
|
1325
|
+
try {
|
|
1326
|
+
reviewerAgent = stageReviewerAgent(askAgentsRoot());
|
|
1327
|
+
} catch {
|
|
1328
|
+
reviewerAgent = null;
|
|
1329
|
+
}
|
|
1330
|
+
}
|
|
1161
1331
|
// digest default: on for plan (review-only contexts where full file
|
|
1162
1332
|
// contents are noise), off for accept-edits (agy applies edits and
|
|
1163
1333
|
// may need richer context for diffs).
|
|
@@ -1165,9 +1335,12 @@ export default async function (pi: ExtensionAPI) {
|
|
|
1165
1335
|
typeof params.digest === "boolean"
|
|
1166
1336
|
? params.digest
|
|
1167
1337
|
: mode === "plan";
|
|
1168
|
-
const finalPrompt: string =
|
|
1169
|
-
|
|
1170
|
-
|
|
1338
|
+
const finalPrompt: string = buildFinalPrompt(
|
|
1339
|
+
params.prompt,
|
|
1340
|
+
mode,
|
|
1341
|
+
useDigest,
|
|
1342
|
+
reviewerAgent !== null,
|
|
1343
|
+
);
|
|
1171
1344
|
|
|
1172
1345
|
// Opt-in full-context export (isolated stays the default).
|
|
1173
1346
|
let contextFile: string | null = null;
|
|
@@ -1193,22 +1366,30 @@ export default async function (pi: ExtensionAPI) {
|
|
|
1193
1366
|
: finalPrompt;
|
|
1194
1367
|
|
|
1195
1368
|
const args: string[] = ["--add-dir", cwd];
|
|
1196
|
-
const
|
|
1369
|
+
const extraRaw = extraArgs();
|
|
1370
|
+
// Fail-closed on the fallback path: AGY_EXTRA_ARGS lands before the
|
|
1371
|
+
// mode flags, so an env-injected skip flag would re-arm what the
|
|
1372
|
+
// plan-mode rule strips. Only the enforced agent makes the flag safe.
|
|
1373
|
+
const extra =
|
|
1374
|
+
mode === "plan" && !reviewerAgent
|
|
1375
|
+
? extraRaw.filter((a) => a !== "--dangerously-skip-permissions")
|
|
1376
|
+
: extraRaw;
|
|
1197
1377
|
if (extra.length) args.push(...extra);
|
|
1198
1378
|
if (resolved.model) args.push("--model", resolved.model);
|
|
1199
1379
|
if (resolved.effort) args.push("--effort", resolved.effort);
|
|
1200
1380
|
args.push("--mode", mode);
|
|
1381
|
+
if (reviewerAgent) args.push("--agent", reviewerAgent.name);
|
|
1201
1382
|
// accept-edits auto-approves file edits but NOT shell commands, so a
|
|
1202
1383
|
// run_command would hang on an unanswerable y/n prompt in non-interactive
|
|
1203
1384
|
// -p mode. Honor the shared permissions setting (same knob as the bridge).
|
|
1204
|
-
// Plan
|
|
1205
|
-
//
|
|
1206
|
-
//
|
|
1207
|
-
//
|
|
1208
|
-
//
|
|
1209
|
-
//
|
|
1210
|
-
//
|
|
1211
|
-
if (mode !== "plan"
|
|
1385
|
+
// Plan runs WITH the reviewer agent: the flag is safe again because the
|
|
1386
|
+
// agent's toolset has no file-editing tool - the 2026-09-25 write
|
|
1387
|
+
// incident rode edit tools that existed then; probed 2026-09-28 the
|
|
1388
|
+
// restricted toolset reports "none" for edits even with the flag. The
|
|
1389
|
+
// flag is what lets analysis commands (builds, test runners) run for
|
|
1390
|
+
// users without allow rules. Plan fallback (staging failed): strict
|
|
1391
|
+
// legacy behavior, no flag - the prompt guard is all that is left.
|
|
1392
|
+
if (config.skipPermissions && (mode !== "plan" || reviewerAgent !== null)) {
|
|
1212
1393
|
args.push("--dangerously-skip-permissions");
|
|
1213
1394
|
}
|
|
1214
1395
|
if (isContinuation) args.push("--conversation", rawConvId as string);
|
|
@@ -1439,6 +1620,27 @@ export default async function (pi: ExtensionAPI) {
|
|
|
1439
1620
|
};
|
|
1440
1621
|
}
|
|
1441
1622
|
|
|
1623
|
+
// Exit 0 with nothing on stdout is still a failure for the
|
|
1624
|
+
// caller: headless agy auto-denies a permission-gated tool call
|
|
1625
|
+
// (e.g. the command gate in plan mode), prints the reason only to
|
|
1626
|
+
// stderr, and ends cleanly. Falling through to the success path
|
|
1627
|
+
// here returned just the conversation footer, which read as an
|
|
1628
|
+
// empty success (silent-failure bug found 2026-09-25).
|
|
1629
|
+
if (!text) {
|
|
1630
|
+
details.empty = true;
|
|
1631
|
+
const note = [
|
|
1632
|
+
"agy exited cleanly but produced no output.",
|
|
1633
|
+
details.stderr.trim() ? `stderr: ${details.stderr.trim()}` : null,
|
|
1634
|
+
"Common cause: a tool call needed a permission that headless mode cannot prompt for (typically the command gate in plan mode), so it was auto-denied and the turn ended with no answer. Recovery: retry in plan mode with all needed content inlined in the prompt - plan runs cannot fetch it, commands are denied. Or rerun outside plan mode with skipPermissions, or add your own permissions.allow rules in ~/.gemini/antigravity-cli/settings.json.",
|
|
1635
|
+
]
|
|
1636
|
+
.filter(Boolean)
|
|
1637
|
+
.join(" ");
|
|
1638
|
+
return {
|
|
1639
|
+
content: [{ type: "text", text: note }],
|
|
1640
|
+
details,
|
|
1641
|
+
};
|
|
1642
|
+
}
|
|
1643
|
+
|
|
1442
1644
|
// Success. Clear the last partial status line (claude-bridge
|
|
1443
1645
|
// idiom) so the running-tail preview doesn't linger under the final
|
|
1444
1646
|
// answer, then append a conversation footer so the orchestrating model
|
|
@@ -1470,6 +1672,11 @@ export default async function (pi: ExtensionAPI) {
|
|
|
1470
1672
|
fs.unlinkSync(contextFile);
|
|
1471
1673
|
} catch {}
|
|
1472
1674
|
}
|
|
1675
|
+
if (reviewerAgent) {
|
|
1676
|
+
try {
|
|
1677
|
+
fs.rmSync(reviewerAgent.dir, { recursive: true, force: true });
|
|
1678
|
+
} catch {}
|
|
1679
|
+
}
|
|
1473
1680
|
}
|
|
1474
1681
|
},
|
|
1475
1682
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@estebanforge/pi-ask-antigravity",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.9",
|
|
4
4
|
"description": "Pi tool that delegates a self-contained sub-task to Google Antigravity's agy CLI (the CLI for Gemini). Friendly model aliases (flash/pro/gemini), configurable default model + thinking, and the AskAntigravity delegation tool.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"pi-package",
|