@estebanforge/pi-ask-antigravity 1.3.3 → 1.3.4
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 +12 -0
- package/extensions/index.ts +21 -16
- package/package.json +4 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
|
|
5
|
+
## [1.3.4] - 2026-11-10
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- **The AskAntigravity defaults dialog reports blocked-on-user-input while open.** Pi 1.5.1 lets overlay dialogs declare a blocked program status (OSC 7501); the dialog now passes it, so terminal automation watching the session sees pi waiting on input instead of idle. Pi dependency floor moved to ^1.5.1.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- The finishing-window stop guard now reads the run's registry status instead of a wall-clock-aligned side set: same refusal behavior, and the test awaits the lifecycle transition instead of a fixed 250ms delay (flaked under full-suite load). Shared dependency floor moves to ^0.1.5 (`markFinishing`) once shared publishes.
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- Windows: `agy models` discovery now resolves the binary like the shared runner does (native `.exe`/`.com` on `PATH`, explicit `AGY_BIN` paths honored, npm shims reported as unavailable instead of a cryptic spawn failure), and every run kills its process tree via `taskkill` instead of POSIX group signals that never fire on Windows.
|
|
16
|
+
|
|
5
17
|
## [1.3.3] - 2026-11-02
|
|
6
18
|
|
|
7
19
|
### Fixed
|
package/extensions/index.ts
CHANGED
|
@@ -41,7 +41,7 @@ import {
|
|
|
41
41
|
} from "@earendil-works/pi-coding-agent";
|
|
42
42
|
|
|
43
43
|
import { Text } from "@earendil-works/pi-tui";
|
|
44
|
-
import { DIALOG_OPTIONS, DialogMenu, type DialogRow } from "@estebanforge/pi-tui-dialogs";
|
|
44
|
+
import { DIALOG_OPTIONS, DialogMenu, dialogBlocked, type DialogRow } from "@estebanforge/pi-tui-dialogs";
|
|
45
45
|
import { contentText } from "@earendil-works/pi-ai";
|
|
46
46
|
import { Type } from "typebox";
|
|
47
47
|
import {
|
|
@@ -65,6 +65,7 @@ import {
|
|
|
65
65
|
newConversationId,
|
|
66
66
|
parseModelLine,
|
|
67
67
|
resolveAgyModel,
|
|
68
|
+
resolveSpawnTarget,
|
|
68
69
|
RunSpawnError,
|
|
69
70
|
runProcess,
|
|
70
71
|
saveLayeredConfig,
|
|
@@ -350,9 +351,11 @@ const sleep = (ms: number) => new Promise<void>((r) => setTimeout(r, ms));
|
|
|
350
351
|
|
|
351
352
|
/** Query `agy models`. Returns [] on any failure (non-fatal). */
|
|
352
353
|
async function discoverModels(binary: string): Promise<ModelEntry[]> {
|
|
354
|
+
const target = resolveSpawnTarget(binary);
|
|
355
|
+
if (target.kind === "unavailable") return [];
|
|
353
356
|
try {
|
|
354
357
|
const text = await new Promise<string>((resolve, reject) => {
|
|
355
|
-
const proc = spawn(
|
|
358
|
+
const proc = spawn(target.file, ["models"], {
|
|
356
359
|
stdio: ["ignore", "pipe", "ignore"],
|
|
357
360
|
shell: false,
|
|
358
361
|
});
|
|
@@ -691,7 +694,11 @@ function shapeFinalText(details: AgyDetails, outcome: ProcessRunOutcome, timeout
|
|
|
691
694
|
return text + footer;
|
|
692
695
|
}
|
|
693
696
|
|
|
694
|
-
export default async function (
|
|
697
|
+
export default async function (
|
|
698
|
+
pi: ExtensionAPI,
|
|
699
|
+
// Injectable so tests can await lifecycle phases; production uses the default.
|
|
700
|
+
registry: BackgroundRunRegistry = new BackgroundRunRegistry({ toolName: "ask-antigravity" }),
|
|
701
|
+
) {
|
|
695
702
|
// If pi-antigravity-bridge is installed, it owns the AskAntigravity tool
|
|
696
703
|
// (and the provider). Stay silent and register nothing to avoid a
|
|
697
704
|
// duplicate-tool clash. Without the bridge, this extension behaves as
|
|
@@ -718,7 +725,6 @@ export default async function (pi: ExtensionAPI) {
|
|
|
718
725
|
// Pi wipes module state on /new, /resume, /fork and /reload: an in-flight
|
|
719
726
|
// background run is killed and its result is never delivered. Accepted
|
|
720
727
|
// trade-off, documented in the README.
|
|
721
|
-
const registry = new BackgroundRunRegistry({ toolName: "ask-antigravity" });
|
|
722
728
|
const kills = new Map<string, () => void>();
|
|
723
729
|
// Staged-artifact cleanup (contextFile + reviewer agent dir), keyed by run:
|
|
724
730
|
// the session_shutdown backstop runs these when a hard exit would skip the
|
|
@@ -727,10 +733,6 @@ export default async function (pi: ExtensionAPI) {
|
|
|
727
733
|
// One background run per conversationId at a time: two runs resuming the
|
|
728
734
|
// same conversation interleave their turns inside agy's SQLite state.
|
|
729
735
|
const busyHandles = new Set<string>();
|
|
730
|
-
// The child closed but the answer is not settled yet (discovery +
|
|
731
|
-
// classification): a stop in this window must refuse instead of settling
|
|
732
|
-
// failed and discarding a computed answer.
|
|
733
|
-
const finishing = new Set<string>();
|
|
734
736
|
const sendWake = createWakeSender(pi, {
|
|
735
737
|
customType: "ask-antigravity-result",
|
|
736
738
|
isDisposed: () => registry.isDisposed(),
|
|
@@ -746,9 +748,13 @@ export default async function (pi: ExtensionAPI) {
|
|
|
746
748
|
error: "stopped via /agy-stop",
|
|
747
749
|
}),
|
|
748
750
|
// The guard keeps /agy-stop from discarding an answer that already
|
|
749
|
-
// finished computing and is riding discovery to its wake.
|
|
751
|
+
// finished computing and is riding discovery to its wake. `finishing`
|
|
752
|
+
// lives in the registry (status set at child close), so the window is
|
|
753
|
+
// observable instead of wall-clock aligned.
|
|
750
754
|
guard: (run) =>
|
|
751
|
-
|
|
755
|
+
registry.get(run.runId)?.status === "finishing"
|
|
756
|
+
? `Run ${run.runId} already finished; its result is being delivered.`
|
|
757
|
+
: null,
|
|
752
758
|
});
|
|
753
759
|
pi.on("session_shutdown", () => {
|
|
754
760
|
// Latch first so close-handler wakes stay silent, then kill children,
|
|
@@ -858,7 +864,7 @@ export default async function (pi: ExtensionAPI) {
|
|
|
858
864
|
},
|
|
859
865
|
};
|
|
860
866
|
},
|
|
861
|
-
DIALOG_OPTIONS,
|
|
867
|
+
{ ...DIALOG_OPTIONS, blocked: dialogBlocked("AskAntigravity defaults") },
|
|
862
868
|
);
|
|
863
869
|
|
|
864
870
|
if (Object.keys(pending).length === 0) return;
|
|
@@ -993,7 +999,7 @@ export default async function (pi: ExtensionAPI) {
|
|
|
993
999
|
if (args.includeContext) tags.push("context=full");
|
|
994
1000
|
if (args.background) tags.push("bg");
|
|
995
1001
|
|
|
996
|
-
let text = theme.fg("
|
|
1002
|
+
let text = theme.fg("success", theme.bold("AskAntigravity "));
|
|
997
1003
|
text += `${theme.fg("accent", `[${tags.join(", ")}]`)} `;
|
|
998
1004
|
|
|
999
1005
|
const prompt = String(args.prompt ?? "");
|
|
@@ -1009,7 +1015,7 @@ export default async function (pi: ExtensionAPI) {
|
|
|
1009
1015
|
const d = result.details as AgyDetails | undefined;
|
|
1010
1016
|
if (isPartial) {
|
|
1011
1017
|
const status = result.content[0]?.type === "text" ? result.content[0].text : "working...";
|
|
1012
|
-
return new Text(theme.fg("
|
|
1018
|
+
return new Text(theme.fg("success", "◉ AskAntigravity ") + theme.fg("muted", status), 0, 0);
|
|
1013
1019
|
}
|
|
1014
1020
|
|
|
1015
1021
|
const body = result.content[0]?.type === "text" ? result.content[0].text : "";
|
|
@@ -1018,7 +1024,7 @@ export default async function (pi: ExtensionAPI) {
|
|
|
1018
1024
|
|
|
1019
1025
|
let text = errored
|
|
1020
1026
|
? theme.fg("error", "✗ AskAntigravity error")
|
|
1021
|
-
: theme.fg("
|
|
1027
|
+
: theme.fg("success", "✓ AskAntigravity");
|
|
1022
1028
|
|
|
1023
1029
|
const rTags: string[] = [];
|
|
1024
1030
|
if (d?.resolvedModel || d?.model) rTags.push(`model=${d?.resolvedModel ?? d?.model}`);
|
|
@@ -1469,7 +1475,7 @@ export default async function (pi: ExtensionAPI) {
|
|
|
1469
1475
|
onSpawn: (kill) => {
|
|
1470
1476
|
kills.set(runId, kill);
|
|
1471
1477
|
},
|
|
1472
|
-
onClose: () =>
|
|
1478
|
+
onClose: () => registry.markFinishing(runId),
|
|
1473
1479
|
})
|
|
1474
1480
|
.then((outcome) => {
|
|
1475
1481
|
kills.delete(runId);
|
|
@@ -1514,7 +1520,6 @@ export default async function (pi: ExtensionAPI) {
|
|
|
1514
1520
|
})
|
|
1515
1521
|
.finally(() => {
|
|
1516
1522
|
cleanups.delete(runId);
|
|
1517
|
-
finishing.delete(runId);
|
|
1518
1523
|
cleanupStaging();
|
|
1519
1524
|
if (o.conversationId) busyHandles.delete(o.conversationId);
|
|
1520
1525
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@estebanforge/pi-ask-antigravity",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.4",
|
|
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",
|
|
@@ -28,8 +28,8 @@
|
|
|
28
28
|
},
|
|
29
29
|
"type": "module",
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@estebanforge/pi-ask-shared": "^0.1.
|
|
32
|
-
"@estebanforge/pi-tui-dialogs": "^0.1.
|
|
31
|
+
"@estebanforge/pi-ask-shared": "^0.1.5",
|
|
32
|
+
"@estebanforge/pi-tui-dialogs": "^0.1.3"
|
|
33
33
|
},
|
|
34
34
|
"files": [
|
|
35
35
|
"extensions",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
]
|
|
44
44
|
},
|
|
45
45
|
"peerDependencies": {
|
|
46
|
-
"@earendil-works/pi-coding-agent": "^1.5.
|
|
46
|
+
"@earendil-works/pi-coding-agent": "^1.5.1"
|
|
47
47
|
},
|
|
48
48
|
"peerDependenciesMeta": {
|
|
49
49
|
"@earendil-works/pi-coding-agent": {
|