@estebanforge/pi-antigravity-bridge 1.7.2 → 1.7.3

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 CHANGED
@@ -2,11 +2,17 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [1.7.3] - 2026-09-24
6
+
7
+ ### Fixed
8
+
9
+ - **Collapsed ACP tool cards no longer repeat the tool name.** The `agy-native-event` renderer filled the muted detail slot with the tool name itself whenever an event carried neither a path nor a recognized command argument, so `ls` and `exec_command` collapsed to "✓ ls ls" / "✓ exec_command exec_command". The detail now prefers the path basename, then the command's first line, then agy's own display text (the first line of the completed call's output, e.g. "Run make test in wicket-cli-atlas"), and stays empty when none exists; the name always stands alone. ACP tool_call frames carry no per-tool reasoning, so agy's display text is the closest honest signal.
10
+
5
11
  ## [1.7.2] - 2026-09-24
6
12
 
7
13
  ### Added
8
14
 
9
- - **ACP permission requests park on a human decision.** `session/request_permission` was answered silently in-process (skip turns auto-allowed, everything else auto-denied), making ACP turns all-or-nothing with no per-tool human say. Interactive turns now hold the JSON-RPC request open and surface the server's options as a pi select dialog under the dialog lock, with the turn budget paused while the human decides: 480 s park, deny on timeout/esc/throw/connection death, and a cancel instead of an answer when the server offers no reject option (a deny must never degrade into picking an allow). `skipPermissions` keeps the synchronous auto-allow; `approvals.mode allow` maps to it, deny and headless stay fail-closed. `allow_always`/`reject_always` answers are remembered per connection for identical later requests, and first settle wins: a late dialog answer after a timeout is forgotten. Nine new tests pin the behavior, including a scenario proving a late answer writes nothing. 1217 tests, tsc clean.
15
+ - **ACP permission requests park on a human decision.** `session/request_permission` was answered silently in-process (skip turns auto-allowed, everything else auto-denied), making ACP turns all-or-nothing with no per-tool human say. Interactive turns now hold the JSON-RPC request open and surface the server's options as a pi select dialog under the dialog lock, with the turn budget paused while the human decides: 480 s park, deny on timeout/esc/throw/connection death, and a cancel instead of an answer when the server offers no reject option (a deny must never degrade into picking an allow). `skipPermissions` keeps the synchronous auto-allow; `approvals.mode allow` maps to it, deny and headless stay fail-closed. `allow_always`/`reject_always` answers are remembered per connection for identical later requests, and first settle wins: a late dialog answer after a timeout is forgotten. Nine new tests pin the behavior, including a scenario proving a late answer writes nothing. tsc clean.
10
16
 
11
17
  ### Changed
12
18
 
package/README.md CHANGED
@@ -73,7 +73,7 @@ cards for read-only steps.
73
73
 
74
74
  ## Approval gate (agy native tools)
75
75
 
76
- agy runs its own agent loop with native tools (`run_command`, `create_file`, `edit_file`, ...), which pi's permission extensions never saw. The optional approval gate routes those calls through a pi-side approval: a staged PreToolUse hook parks the call, the provider surfaces it as a shadow `bash`/`write`/`edit` toolUse, and your permission extension (or the built-in ask/allow/deny fallback) decides before agy executes it. Off by default (`approvals.gateMode: auto` enables it only when a pi permission extension is detected); denials fail closed; read-only agy tools stay ungated.
76
+ agy runs its own agent loop with native tools (`run_command`, `create_file`, `edit_file`, ...), which pi's permission extensions never saw. The optional approval gate routes those calls through a pi-side approval: a staged PreToolUse hook parks the call, the provider surfaces it as a shadow `bash`/`write`/`edit` toolUse, and your permission extension (or the built-in ask/allow/deny fallback) decides before agy executes it. Off by default (`approvals.gateMode: auto` enables it only when a pi permission extension is detected); denials fail closed; read-only agy tools stay ungated. On ACP turns the server has its own per-tool permission ask: when one fires (`skipPermissions` off), the request parks on a real pi dialog instead of a silent deny, and allow-always choices are remembered per connection.
77
77
 
78
78
  Full mechanics, configuration, and a sample gate extension: [docs/APPROVAL-GATE.md](docs/APPROVAL-GATE.md).
79
79
 
@@ -357,9 +357,13 @@ export default async function (pi: ExtensionAPI): Promise<void> {
357
357
  if (engine === "acp") {
358
358
  pi.registerEntryRenderer<NativeDisplayEvent>("agy-native-event", (entry, { expanded }, theme) => {
359
359
  const event = entry.data;
360
- const title = (event?.path ? path.basename(event.path) : event?.command?.split(/\r?\n/, 1)[0] ?? event?.name ?? "tool").slice(0, 160);
360
+ // Collapsed detail: most-specific signal wins (path, command, agy's own
361
+ // display text). The name is NOT a fallback here - it rendered "ls ls"
362
+ // duplication whenever the event carried neither path nor command.
363
+ const firstLine = (value: string | undefined): string | undefined => value?.split(/\r?\n/, 1)[0].trim() || undefined;
364
+ const detail = event?.path ? path.basename(event.path) : firstLine(event?.command) ?? firstLine(event?.output);
361
365
  const status = event?.status === "failed" ? theme.fg("error", "✗") : theme.fg("success", "✓");
362
- const lines = [`${status} ${theme.fg("toolTitle", event?.name ?? "Antigravity")} ${theme.fg("muted", title)}`];
366
+ const lines = [`${status} ${theme.fg("toolTitle", event?.name ?? "Antigravity")}${detail ? ` ${theme.fg("muted", detail.slice(0, 160))}` : ""}`];
363
367
  if (expanded) {
364
368
  if (event?.path) lines.push(theme.fg("dim", event.path));
365
369
  if (event?.diff) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@estebanforge/pi-antigravity-bridge",
3
- "version": "1.7.2",
3
+ "version": "1.7.3",
4
4
  "description": "Gemini provider for Pi on the Antigravity ACP server (official Google ACP) or the stream-json agy CLI. antigravity/* models in Pi's /model picker, no-patch MCP bridge: agy runs Pi's tools. ToS safe to use.",
5
5
  "keywords": [
6
6
  "pi-package",