@erichll/pi-auto-review 0.25.0 → 0.26.0

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
@@ -1,5 +1,24 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.26.0 - 2026-10-08
4
+
5
+ - Upgrade Pi development dependencies and peer floors to `^1.1.0`, require
6
+ permission-system `>=40.0.2`, and align the Node engine with Pi
7
+ (`>=22.19.0`). Node types (`^26.6.4`) and TypeScript (`^7.0.2`) already
8
+ match the latest stable registry versions.
9
+ - Retry `server_busy` and server-busy provider details within the existing
10
+ two-attempt review budget, aligning with Pi 1.1.0
11
+ ([#10543](https://github.com/earendil-works/pi/issues/10543)).
12
+ - Recognize the exact Mistral `finish_reason: "error"` message from pi-ai
13
+ 1.0.x as a transient server failure. pi-ai 1.1.0 adds a server-error suffix
14
+ that the existing classifier already recognizes
15
+ ([#10487](https://github.com/earendil-works/pi/issues/10487)); keep unknown,
16
+ authentication, and configuration failures non-retryable.
17
+ - Clear staged UI auto-confirmations and one-shot interceptors when Pi 1.1.0
18
+ emits `agent_settled.aborted: true`
19
+ ([#10607](https://github.com/earendil-works/pi/issues/10607)). Preserve
20
+ existing behavior when the field is absent, false, or malformed.
21
+
3
22
  ## 0.25.0 - 2026-10-07
4
23
 
5
24
  - Pass permission-system's matched bash spelling (#910) through the review and
package/README.md CHANGED
@@ -31,12 +31,11 @@ that dependency is a hard prerequisite (see [Install and enable](#install-and-en
31
31
  > **Prerequisite:** pi-auto-review is an authorizer inside
32
32
  > `@gotgenes/pi-permission-system`. Pi does not auto-install peer packages, so
33
33
  > install the permission system separately (once per machine) before this
34
- > extension. This release line requires Pi 1.0.0 or later and supports
35
- > permission-system 39.0.0 and later (development baseline validated against
36
- > permission-system 40.0.2). Use 40.0.2 or later for the bash-chain session-grant
37
- > security fix; the older peer floor is retained for API compatibility:
34
+ > extension. This release line requires Pi 1.1.0 or later and
35
+ > permission-system 40.0.2 or later, including the bash-chain session-grant
36
+ > security fix:
38
37
 
39
- Node-based Pi requires Node.js 22.13.0 or newer. Permission auditing uses the
38
+ Node-based Pi requires Node.js 22.19.0 or newer. Permission auditing uses the
40
39
  host runtime's built-in SQLite: `node:sqlite` on Node and `bun:sqlite` on Bun,
41
40
  including Bun-compiled Pi (verified with Bun 1.3.14). It does not require a
42
41
  SQLite CLI, system SQLite library, or npm SQLite package.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@erichll/pi-auto-review",
3
- "version": "0.25.0",
3
+ "version": "0.26.0",
4
4
  "description": "Fail-closed, model-backed approval broker for Pi: deterministically hard-denies dangerous operations, reviews dangerous boundaries with a reviewer model, and issues one-shot expiring grants that OS sandbox adapters must consume before retrying.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -24,7 +24,7 @@
24
24
  "access": "public"
25
25
  },
26
26
  "engines": {
27
- "node": ">=22.13.0"
27
+ "node": ">=22.19.0"
28
28
  },
29
29
  "files": [
30
30
  "src",
@@ -47,14 +47,14 @@
47
47
  "test": "node --disable-warning=ExperimentalWarning --experimental-transform-types --import ./test/register-external-ts.mjs --test test/*.test.ts"
48
48
  },
49
49
  "peerDependencies": {
50
- "@earendil-works/pi-ai": "^1.0.0",
51
- "@earendil-works/pi-coding-agent": "^1.0.0",
52
- "@gotgenes/pi-permission-system": ">=39.0.0"
50
+ "@earendil-works/pi-ai": "^1.1.0",
51
+ "@earendil-works/pi-coding-agent": "^1.1.0",
52
+ "@gotgenes/pi-permission-system": ">=40.0.2"
53
53
  },
54
54
  "devDependencies": {
55
- "@earendil-works/pi-ai": "^1.0.0",
56
- "@earendil-works/pi-coding-agent": "^1.0.0",
57
- "@earendil-works/pi-server": "^1.0.0",
55
+ "@earendil-works/pi-ai": "^1.1.0",
56
+ "@earendil-works/pi-coding-agent": "^1.1.0",
57
+ "@earendil-works/pi-server": "^1.1.0",
58
58
  "@gotgenes/pi-permission-system": "^40.0.2",
59
59
  "@types/node": "^26.6.4",
60
60
  "typescript": "^7.0.2"
package/src/index.ts CHANGED
@@ -669,6 +669,14 @@ export function createPiAutoReviewExtension(
669
669
  }
670
670
  });
671
671
 
672
+ pi.on("agent_settled", (event) => {
673
+ // Pi 1.0.x omits aborted. Only an explicit cancellation revokes staged
674
+ // allows and any one-shot UI interceptor left by that run.
675
+ if ((event as { aborted?: unknown }).aborted === true) {
676
+ uiAutoConfirmer.clear();
677
+ }
678
+ });
679
+
672
680
  pi.events.on("permissions:ui_prompt", (event) => {
673
681
  if (context) uiAutoConfirmer.handlePrompt(event, context);
674
682
  policyAudit.notePrompt(event);
@@ -128,6 +128,7 @@ export function classifyProviderFailure(
128
128
  }
129
129
 
130
130
  const code = errorCode(error);
131
+ if (code === "server_busy") return "transient_server";
131
132
  if (
132
133
  code &&
133
134
  new Set([
@@ -157,7 +158,13 @@ export function classifyProviderFailure(
157
158
  if (/\b429\b|rate.?limit|too many requests/i.test(detail)) {
158
159
  return "rate_limit";
159
160
  }
160
- if (/\b5(?:00|02|03|04)\b|service.?unavailable|server.?error|internal.?error|overloaded/i.test(detail)) {
161
+ if (/\b5(?:00|02|03|04)\b|service.?unavailable|server.?error|internal.?error|overloaded|\bservers?[ _-]busy\b|\bservers? (?:are|is) currently busy\b/i.test(detail)) {
162
+ return "transient_server";
163
+ }
164
+ // pi-ai 1.0.x maps Mistral finish_reason "error" to this exact message.
165
+ // 1.1.0 (#10487) adds "(server error)", covered above. Do not make all
166
+ // stopReason="error" messages retryable: auth/config failures use it too.
167
+ if (/^Provider stopped with: error$/i.test(detail.trim())) {
161
168
  return "transient_server";
162
169
  }
163
170
  if (/unknown model|model not found|invalid model|unsupported model/i.test(detail)) {