@piagent/platform 1.5.4 → 1.5.5

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.
Files changed (58) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/README.md +1 -1
  3. package/README.vi.md +1 -1
  4. package/catalog/capabilities.json +2 -2
  5. package/docs/command-reference-vietnamese.md +2 -2
  6. package/docs/distribution-standard.md +7 -7
  7. package/docs/languages.json +2 -2
  8. package/docs/operator-manual-vietnamese.md +7 -7
  9. package/docs/publishing-for-teams.md +4 -0
  10. package/docs/release-install-policy.md +6 -6
  11. package/docs/security-threat-model.md +1 -1
  12. package/docs/team-onboarding.md +2 -2
  13. package/docs-site/architecture.html +1 -1
  14. package/docs-site/benchmark.html +1 -1
  15. package/docs-site/commands.html +1 -1
  16. package/docs-site/context-engine.html +1 -1
  17. package/docs-site/en/architecture.html +1 -1
  18. package/docs-site/en/benchmark.html +1 -1
  19. package/docs-site/en/commands.html +1 -1
  20. package/docs-site/en/context-engine.html +1 -1
  21. package/docs-site/en/index.html +1 -1
  22. package/docs-site/en/mcp-approval.html +1 -1
  23. package/docs-site/en/mcp-auth.html +1 -1
  24. package/docs-site/en/mcp-servers.html +1 -1
  25. package/docs-site/en/mcp.html +1 -1
  26. package/docs-site/en/permissions.html +1 -1
  27. package/docs-site/en/profiles.html +1 -1
  28. package/docs-site/en/quickstart.html +1 -1
  29. package/docs-site/en/runtime.html +1 -1
  30. package/docs-site/en/scope.html +1 -1
  31. package/docs-site/en/security.html +1 -1
  32. package/docs-site/en/team.html +1 -1
  33. package/docs-site/en/whats-new.html +1 -1
  34. package/docs-site/en/workflows.html +1 -1
  35. package/docs-site/index.html +1 -1
  36. package/docs-site/mcp-approval.html +1 -1
  37. package/docs-site/mcp-auth.html +1 -1
  38. package/docs-site/mcp-servers.html +1 -1
  39. package/docs-site/mcp.html +1 -1
  40. package/docs-site/permissions.html +1 -1
  41. package/docs-site/profiles.html +1 -1
  42. package/docs-site/quickstart.html +1 -1
  43. package/docs-site/runtime.html +1 -1
  44. package/docs-site/scope.html +1 -1
  45. package/docs-site/security.html +1 -1
  46. package/docs-site/team.html +1 -1
  47. package/docs-site/whats-new.html +1 -1
  48. package/docs-site/workflows.html +1 -1
  49. package/package.json +1 -1
  50. package/packages/piagent-core/extensions/guard-types.ts +1 -0
  51. package/packages/piagent-core/extensions/piagent-guard.ts +17 -2
  52. package/packages/piagent-core/extensions/policy-core.js +1 -1
  53. package/packages/piagent-core/package.json +1 -1
  54. package/packages/piagent-core/policies/base-policy.json +1 -0
  55. package/packages/piagent-core/runtime/inspection/activity-event-adapter.ts +5 -1
  56. package/packages/piagent-core/runtime/inspection/approval-broker.ts +29 -5
  57. package/packages/piagent-webui/gateway/session-runtime-supervisor.ts +4 -0
  58. package/scripts/piagent-dashboard.mjs +13 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,25 @@ This file records release-facing changes for Pi Agent Platform. Copy the relevan
4
4
 
5
5
  ## Unreleased
6
6
 
7
+ ## v1.5.5 - 2026-08-21
8
+
9
+ ### WebUI command execution hotfix
10
+
11
+ - Fixed provider tool-call identifiers containing characters outside the
12
+ public WebUI reference alphabet. Gateway approvals now bind those opaque
13
+ identifiers to private deterministic references instead of falling back to
14
+ a terminal confirmation that does not exist in WebUI.
15
+ - Prevented search commands such as `rg` and `grep` from being mistaken for
16
+ migration execution merely because their search arguments contain
17
+ `migrate`. Real migration commands still require explicit confirmation.
18
+ - Made Stop cancel the exact pending approval before aborting the model
19
+ operation, so a session cannot remain stuck waiting for an approval after
20
+ the user stops it. Gateway approval failures now deny immediately rather
21
+ than waiting indefinitely.
22
+ - Corrected activity reporting so a tool call remains requested until native
23
+ execution actually starts, and strengthened Dashboard restart to wait for
24
+ the previous process to exit instead of silently reusing a hung instance.
25
+
7
26
  ## v1.5.4 - 2026-08-20
8
27
 
9
28
  ### WebUI workflow hotfix
package/README.md CHANGED
@@ -359,7 +359,7 @@ This repository intentionally excludes:
359
359
 
360
360
  ## Maturity
361
361
 
362
- The current package version is read from package metadata and release tags. Personal machines may follow the unpinned package source when accepting ongoing updates; production/team quickstarts and committed project settings should pin an explicit tag such as `v1.5.4` or a reviewed commit.
362
+ The current package version is read from package metadata and release tags. Personal machines may follow the unpinned package source when accepting ongoing updates; production/team quickstarts and committed project settings should pin an explicit tag such as `v1.5.5` or a reviewed commit.
363
363
 
364
364
  Ready for:
365
365
 
package/README.vi.md CHANGED
@@ -164,7 +164,7 @@ chỉ validate kế hoạch, không dùng quota.
164
164
 
165
165
  Gate này chạy architecture check, test, typecheck, capability validation, runtime smoke và docs consistency trước khi release.
166
166
 
167
- Bản phát hành hiện tại là `v1.5.4`. Với team hoặc production, hãy pin tag này
167
+ Bản phát hành hiện tại là `v1.5.5`. Với team hoặc production, hãy pin tag này
168
168
  hoặc một commit đã review thay vì dựa vào nguồn package không cố định.
169
169
 
170
170
  ## Security
@@ -26,8 +26,8 @@
26
26
  "path": "evals/scenarios/capability-resolution.json"
27
27
  },
28
28
  {
29
- "byteSize": 6232,
30
- "digest": "sha256:a2c44a910a440e972579c2a2ec372ee15cfb73b63b27d01c1e3a053c176d11bf",
29
+ "byteSize": 6271,
30
+ "digest": "sha256:90dafc5b6c0bd555b932d89b10785b9eb50104ed22dcb06cfb8a2d306cc26d2f",
31
31
  "id": "base-policy",
32
32
  "kind": "policies",
33
33
  "path": "packages/piagent-core/policies/base-policy.json"
@@ -502,8 +502,8 @@ Các lệnh này chạy ngoài Pi.
502
502
  | Command | Dùng khi nào |
503
503
  |---|---|
504
504
  | `npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.84.1` | Cài Pi CLI tương thích với release hiện tại. |
505
- | `npm install -g --ignore-scripts @piagent/platform@1.5.4` | Cài terminal helper `piagent-*` từ release tag hiện tại. |
506
- | `pi install git:github.com/Vt-mmm/piagent@v1.5.4` | Cài pinned release khi cần reproducible team setup. |
505
+ | `npm install -g --ignore-scripts @piagent/platform@1.5.5` | Cài terminal helper `piagent-*` từ release tag hiện tại. |
506
+ | `pi install git:github.com/Vt-mmm/piagent@v1.5.5` | Cài pinned release khi cần reproducible team setup. |
507
507
  | `pi install git:github.com/Vt-mmm/piagent` | Cài latest package platform cho máy cá nhân/sandbox. |
508
508
  | `piagent-update --check` | Báo version hiện tại vs version sẽ lên cho cả ba thành phần; không cài gì. |
509
509
  | `piagent-update` | Full update global một lệnh cho cả máy: Pi host → npm-global helper → Pi package, đúng thứ tự release yêu cầu. |
@@ -15,9 +15,9 @@ Repo này phải chạy được cho nhiều project/domain khác nhau. Vì vậ
15
15
 
16
16
  | Use case | Package source |
17
17
  |---|---|
18
- | Team pinned release | `git:github.com/Vt-mmm/piagent@v1.5.4` |
18
+ | Team pinned release | `git:github.com/Vt-mmm/piagent@v1.5.5` |
19
19
  | Personal/sandbox dev | `git:github.com/Vt-mmm/piagent` |
20
- | Registry distribution | `npm:@piagent/platform@1.5.4` |
20
+ | Registry distribution | `npm:@piagent/platform@1.5.5` |
21
21
  | Enterprise npm (fork under another scope) | `npm:@your-scope/platform@x.y.z` |
22
22
  | Local platform dev | `/path/to/piagent` |
23
23
 
@@ -27,7 +27,7 @@ Latest tiện cho máy cá nhân muốn nhận cập nhật nhanh. Pin tag/commi
27
27
 
28
28
  | Channel | Command | Target | Policy |
29
29
  |---|---|---|---|
30
- | `stable` | `bash scripts/install-global.sh --stable` | Helper release tag resolved to commit SHA, currently `v1.5.4` | Install the Pi package matching the helper. |
30
+ | `stable` | `bash scripts/install-global.sh --stable` | Helper release tag resolved to commit SHA, currently `v1.5.5` | Install the Pi package matching the helper. |
31
31
  | `exact` | `bash scripts/install-global.sh --version vX.Y.Z --resolve-tag` | Requested tag resolved to commit SHA | Pi-package-only rollout, rollback, and incident recovery. |
32
32
  | `dev` | `bash scripts/install-global.sh --dev` | Moving Git source | Personal/sandbox only; do not commit into project settings. |
33
33
  | `local` | `bash scripts/install-global.sh --local` | Current checkout path | Platform development only. |
@@ -54,7 +54,7 @@ Root `package.json` có `pi` manifest trỏ tới:
54
54
  Do đó team có thể:
55
55
 
56
56
  ```bash
57
- pi install git:github.com/Vt-mmm/piagent@v1.5.4
57
+ pi install git:github.com/Vt-mmm/piagent@v1.5.5
58
58
  ```
59
59
 
60
60
  Không cần biết internal folder `packages/piagent-core`. Source không pin chỉ dành cho personal/sandbox như bảng channel ở trên.
@@ -66,12 +66,12 @@ Team nên install global package một lần:
66
66
  ```bash
67
67
  node --version # >= 22.19.0
68
68
  npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.84.1
69
- npm install -g --ignore-scripts @piagent/platform@1.5.4
69
+ npm install -g --ignore-scripts @piagent/platform@1.5.5
70
70
  piagent-install --stable --dry-run
71
71
  piagent-install --stable
72
72
  ```
73
73
 
74
- `pi install git:github.com/Vt-mmm/piagent@v1.5.4` vẫn hợp lệ nếu chỉ cần cài Pi package. Lệnh đó không tự tạo các binary terminal `piagent-*`; muốn có helper global thì dùng `npm install -g --ignore-scripts @piagent/platform@1.5.4`.
74
+ `pi install git:github.com/Vt-mmm/piagent@v1.5.5` vẫn hợp lệ nếu chỉ cần cài Pi package. Lệnh đó không tự tạo các binary terminal `piagent-*`; muốn có helper global thì dùng `npm install -g --ignore-scripts @piagent/platform@1.5.5`.
75
75
 
76
76
  Support matrix hiện tại: macOS Apple Silicon + Bash và Linux x64 + Bash đã được verify; macOS Intel + Bash và Linux ARM64 + Bash là supported target cần chạy smoke trước rollout; native Windows chưa phải target rollout team; WSL2 experimental. Chi tiết và version runtime nằm trong [release/install policy](release-install-policy.md).
77
77
 
@@ -121,7 +121,7 @@ Nếu muốn commit sẵn `.pi/piagent-profile.json` vào repo hoặc bootstrap
121
121
  ```bash
122
122
  bash scripts/setup.sh /path/to/project \
123
123
  --profile be-readonly-fe \
124
- --package-source git:github.com/Vt-mmm/piagent@v1.5.4 \
124
+ --package-source git:github.com/Vt-mmm/piagent@v1.5.5 \
125
125
  --mcp-preset core \
126
126
  --subagents-preset safe
127
127
  ```
@@ -21,8 +21,8 @@
21
21
  "en": "README.md",
22
22
  "vi": "README.vi.md",
23
23
  "consistentAt": {
24
- "en": "3d9082674ded9179175a10bb86a4a1c922faa269",
25
- "vi": "5c396247582381eafe741042fc4259982a527381"
24
+ "en": "1c890fe5b2a1f53f074b54f90d4610b5ed648242",
25
+ "vi": "6b7a18e5f6f18012a4d96a70b5e2815299629b05"
26
26
  }
27
27
  },
28
28
  {
@@ -19,12 +19,12 @@ Support matrix release hiện tại: macOS Apple Silicon + Bash và Linux x64 +
19
19
  ```bash
20
20
  node --version # >= 22.19.0
21
21
  npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.84.1
22
- npm install -g --ignore-scripts @piagent/platform@1.5.4
22
+ npm install -g --ignore-scripts @piagent/platform@1.5.5
23
23
  piagent-install --stable --dry-run
24
24
  piagent-install --stable
25
25
  ```
26
26
 
27
- Khi seed `.pi/settings.json` cho team/repo cần audit lặp lại, giữ package source dạng pinned tag như `git:github.com/Vt-mmm/piagent@v1.5.4`. Máy cá nhân có thể dùng `git:github.com/Vt-mmm/piagent` để theo latest.
27
+ Khi seed `.pi/settings.json` cho team/repo cần audit lặp lại, giữ package source dạng pinned tag như `git:github.com/Vt-mmm/piagent@v1.5.5`. Máy cá nhân có thể dùng `git:github.com/Vt-mmm/piagent` để theo latest.
28
28
 
29
29
  Nếu đang ở source checkout của platform, dùng helper theo channel để preview trước khi đổi:
30
30
 
@@ -100,7 +100,7 @@ install package once
100
100
 
101
101
  ```bash
102
102
  npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.84.1
103
- npm install -g --ignore-scripts @piagent/platform@1.5.4
103
+ npm install -g --ignore-scripts @piagent/platform@1.5.5
104
104
  piagent-install --stable --dry-run
105
105
  piagent-install --stable
106
106
  ```
@@ -283,7 +283,7 @@ Không phải daily default. Dùng khi muốn tạo sẵn `.pi` files cho projec
283
283
  bash /path/to/piagent/scripts/setup.sh /path/to/project \
284
284
  --project-only \
285
285
  --profile auto \
286
- --package-source git:github.com/Vt-mmm/piagent@v1.5.4 \
286
+ --package-source git:github.com/Vt-mmm/piagent@v1.5.5 \
287
287
  --mcp-preset core \
288
288
  --subagents-preset safe
289
289
  ```
@@ -1042,8 +1042,8 @@ Watchdog là optional adversarial reviewer ở cuối turn, không bật mặc
1042
1042
 
1043
1043
  | Command | Dùng để |
1044
1044
  |---|---|
1045
- | `npm install -g --ignore-scripts @piagent/platform@1.5.4` | Cài terminal helper `piagent-*` từ release tag hiện tại. |
1046
- | `pi install git:github.com/Vt-mmm/piagent@v1.5.4` | Install pinned release cho reproducible team setup. |
1045
+ | `npm install -g --ignore-scripts @piagent/platform@1.5.5` | Cài terminal helper `piagent-*` từ release tag hiện tại. |
1046
+ | `pi install git:github.com/Vt-mmm/piagent@v1.5.5` | Install pinned release cho reproducible team setup. |
1047
1047
  | `pi install git:github.com/Vt-mmm/piagent` | Install latest platform package cho máy cá nhân/sandbox. |
1048
1048
  | Cài exact Pi host của release, rồi `npm install -g --ignore-scripts @piagent/platform@X.Y.Z` và `piagent-install --stable` | Full update: đồng bộ host, terminal helper và Pi package. Mỗi release pin một Pi host chính xác; lấy đúng version của release đang cài trong [release/install policy](release-install-policy.md). |
1049
1049
  | Cài exact Pi host ghi trong release cũ, rồi helper `vPREVIOUS` và `piagent-install --stable` | Full rollback; đánh giá lại dependency findings của host cũ trước khi hạ version. |
@@ -1155,7 +1155,7 @@ Mở lại Pi session sau khi install.
1155
1155
  Cài lại terminal helper đúng release rồi kiểm tra `PATH`:
1156
1156
 
1157
1157
  ```bash
1158
- npm install -g --ignore-scripts @piagent/platform@1.5.4
1158
+ npm install -g --ignore-scripts @piagent/platform@1.5.5
1159
1159
  command -v piagent-install
1160
1160
  ```
1161
1161
 
@@ -98,6 +98,10 @@ pi install /path/to/piagent
98
98
  Inspector; projection Task Changes / Working Tree / Staged có bounded diff,
99
99
  provenance và enforce protected path; session lease bền, recovery khi restart
100
100
  hoặc owner cũ treo, doctor có repair tường minh.
101
+ - `1.5.5`: hotfix WebUI command execution — approval nhận đúng opaque tool-call
102
+ ID, lệnh tìm kiếm không còn bị nhận nhầm thành migration, Stop hủy approval
103
+ đang chờ, activity chỉ báo running sau khi command thật sự chạy, và restart
104
+ không tái sử dụng process treo.
101
105
  - `1.5.4`: hotfix WebUI giữ ownership qua workflow dispatch bất đồng bộ, không
102
106
  còn báo `session-command-effect-unknown` giả; session đã tạo được tự đồng bộ
103
107
  mà không gửi lại, và transcript không lặp tin workflow sau khi persisted.
@@ -11,7 +11,7 @@ This file is the canonical install, update, rollback, and release checklist. Oth
11
11
 
12
12
  All supported environments require Node.js `>=22.19.0` and Pi Coding Agent `0.84.1`. The Pi host is installed as a Node CLI; Pi Agent Platform still defines its own release matrix because the terminal helpers and shell policy rely on Bash/POSIX behavior.
13
13
 
14
- | Surface | Status for v1.5.4 | Rollout guidance |
14
+ | Surface | Status for v1.5.5 | Rollout guidance |
15
15
  |---|---|---|
16
16
  | macOS Apple Silicon (`darwin/arm64`) + Bash | Verified for this release. | Safe default for team rollout after normal project smoke tests. |
17
17
  | Linux x64 + Bash | Verified in GitHub Actions. | Safe default for CI/server usage after normal project smoke tests. |
@@ -106,7 +106,7 @@ These three components are versioned independently. A full install, update, or r
106
106
 
107
107
  | Channel | Source shape | Mutability | Use when |
108
108
  |---|---|---:|---|
109
- | `stable` | `git:github.com/Vt-mmm/piagent@<resolved-commit-sha>` from `v1.5.4` | Fixed after resolution | Default for team rollout. |
109
+ | `stable` | `git:github.com/Vt-mmm/piagent@<resolved-commit-sha>` from `v1.5.5` | Fixed after resolution | Default for team rollout. |
110
110
  | `exact` | Tag, reviewed commit, or a tag resolved with `--resolve-tag` | Fixed when using a commit SHA | Pi-package-only roll forward, rollback, or reproduction. |
111
111
  | `dev` | `git:github.com/Vt-mmm/piagent` | Moving | Personal machine or sandbox only. |
112
112
  | `local` | `/path/to/piagent` | Local workspace | Platform development and dry-run validation. |
@@ -126,7 +126,7 @@ Use this flow when the team needs both terminal commands and the Pi package:
126
126
  ```bash
127
127
  node --version # >= 22.19.0
128
128
  npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.84.1
129
- npm install -g --ignore-scripts @piagent/platform@1.5.4
129
+ npm install -g --ignore-scripts @piagent/platform@1.5.5
130
130
  piagent-install --stable --dry-run
131
131
  piagent-install --stable
132
132
  ```
@@ -134,8 +134,8 @@ piagent-install --stable
134
134
  The stable preview and apply output includes:
135
135
 
136
136
  ```text
137
- currentRelease: v1.5.4 (helper package version)
138
- tag: v1.5.4
137
+ currentRelease: v1.5.5 (helper package version)
138
+ tag: v1.5.5
139
139
  resolvedCommit: <40-char-sha>
140
140
  source: git:github.com/Vt-mmm/piagent@<40-char-sha>
141
141
  ```
@@ -152,7 +152,7 @@ bash scripts/install-global.sh --stable
152
152
  Use this only when terminal commands are not needed:
153
153
 
154
154
  ```bash
155
- pi install git:github.com/Vt-mmm/piagent@v1.5.4
155
+ pi install git:github.com/Vt-mmm/piagent@v1.5.5
156
156
  ```
157
157
 
158
158
  Direct `pi install` does not create `piagent-*` commands on `PATH`.
@@ -25,7 +25,7 @@ This document covers the packaged guard, project profiles, capability locks, ins
25
25
  - The operator, operating-system account, Pi host, and explicitly trusted project repository are trusted to execute code.
26
26
  - Project-local Pi resources are loaded only after Pi project trust or an explicit operator override.
27
27
  - A human remains available to approve destructive and external-provider actions.
28
- - Supported release verification covers macOS Apple Silicon + Bash, Linux x64 + Bash, Node.js `>=22.19.0`, and the exact Pi host version declared by the release. macOS Intel + Bash and Linux ARM64 + Bash are supported targets that need local smoke verification before broad rollout. Native Windows is not a team-rollout target for v1.5.4, and WSL2 is experimental/unverified.
28
+ - Supported release verification covers macOS Apple Silicon + Bash, Linux x64 + Bash, Node.js `>=22.19.0`, and the exact Pi host version declared by the release. macOS Intel + Bash and Linux ARM64 + Bash are supported targets that need local smoke verification before broad rollout. Native Windows is not a team-rollout target for v1.5.5, and WSL2 is experimental/unverified.
29
29
  - Registry, GitHub, model-provider, MCP-provider, and Vercel controls are external dependencies. Their account security and platform guarantees are not replaced by this repository.
30
30
 
31
31
  ## Threat actors and failure modes
@@ -10,7 +10,7 @@ Một thành viên mới không cần biết local path của maintainer. Luồn
10
10
  ```bash
11
11
  node --version # >= 22.19.0
12
12
  npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.84.1
13
- npm install -g --ignore-scripts @piagent/platform@1.5.4
13
+ npm install -g --ignore-scripts @piagent/platform@1.5.5
14
14
  piagent-install --stable
15
15
  cd /path/to/project
16
16
  pi
@@ -44,7 +44,7 @@ Mặc định team dùng stable helper:
44
44
  ```bash
45
45
  node --version # >= 22.19.0
46
46
  npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.84.1
47
- npm install -g --ignore-scripts @piagent/platform@1.5.4
47
+ npm install -g --ignore-scripts @piagent/platform@1.5.5
48
48
  piagent-install --stable --dry-run
49
49
  piagent-install --stable
50
50
  ```
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/architecture" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/architecture" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/benchmark" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/benchmark" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/commands" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/commands" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/context-engine" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/context-engine" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/architecture" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/architecture" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/benchmark" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/benchmark" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/commands" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/commands" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/context-engine" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/context-engine" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/mcp-approval" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/mcp-approval" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/mcp-auth" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/mcp-auth" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/mcp-servers" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/mcp-servers" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/mcp" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/mcp" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/permissions" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/permissions" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/profiles" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/profiles" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/quickstart" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/quickstart" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/runtime" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/runtime" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/scope" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/scope" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/security" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/security" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/team" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/team" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/whats-new" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/whats-new" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/workflows" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/workflows" hreflang="en" lang="en" aria-current="true">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/mcp-approval" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/mcp-approval" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/mcp-auth" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/mcp-auth" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/mcp-servers" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/mcp-servers" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/mcp" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/mcp" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/permissions" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/permissions" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/profiles" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/profiles" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/quickstart" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/quickstart" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/runtime" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/runtime" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/scope" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/scope" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/security" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/security" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/team" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/team" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/whats-new" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/whats-new" hreflang="en" lang="en">EN</a>
@@ -30,7 +30,7 @@
30
30
  <span>Pi Agent Platform</span>
31
31
  </a>
32
32
  <div class="top-actions">
33
- <span class="pill"><span class="pill-dot"></span>v1.5.4 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.5.5 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/workflows" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/workflows" hreflang="en" lang="en">EN</a>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piagent/platform",
3
- "version": "1.5.4",
3
+ "version": "1.5.5",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -446,6 +446,7 @@ export type CommandRule = {
446
446
  id: string;
447
447
  action: "allow" | "prompt" | "forbid";
448
448
  match: "prefix" | "contains" | "regex";
449
+ ignoreSearchArguments?: boolean;
449
450
  value: string | string[];
450
451
  reason: string;
451
452
  };
@@ -90,7 +90,7 @@ import { completeTaskDigestRefresh } from "./task-digest-migration.js";
90
90
  import { WORKING_TREE_DIGEST_ALGORITHM, isCurrentWorkingTreeDigest, workingTreeObservation, workingTreeSnapshotUsesCurrentAlgorithm } from "./working-tree-digest.js";
91
91
  import { appendJsonlBounded } from "./state-retention.js";
92
92
  import { ensurePrivateStateDirectory, resolveLocalStatePath } from "./local-state-path.js";
93
- import { piApprovalBroker, type ApprovalActionDraft } from "../runtime/inspection/approval-broker.ts";
93
+ import { piApprovalBroker, type ApprovalActionDraft, type ApprovalUnavailableFallback } from "../runtime/inspection/approval-broker.ts";
94
94
  import { inspectTaskControlState } from "../runtime/inspection/task-control-journal.ts";
95
95
  import { createSourceMutationGuardBindings } from "../runtime/policy/source-mutation-guard-binding.ts";
96
96
  import {
@@ -1090,6 +1090,20 @@ function isPlainRecord(value: unknown): value is Record<string, unknown> {
1090
1090
  return prototype === Object.prototype || prototype === null;
1091
1091
  }
1092
1092
 
1093
+ function approvalUnavailableFallback(ctx: Pick<ExtensionContext, "ui">): ApprovalUnavailableFallback {
1094
+ // The symbol is a cross-package runtime marker, not an import, so piagent-core
1095
+ // remains independent of the WebUI package. A Gateway has no interactive
1096
+ // terminal behind `ctx.ui.confirm`; if brokering is unavailable it must fail
1097
+ // closed immediately instead of awaiting an impossible terminal response.
1098
+ try {
1099
+ return Reflect.get(ctx.ui as object, Symbol.for("piagent.webui.gateway-runtime-ui.v1")) === true
1100
+ ? "deny"
1101
+ : "terminal-confirm";
1102
+ } catch {
1103
+ return "terminal-confirm";
1104
+ }
1105
+ }
1106
+
1093
1107
  function evaluatePathLikeToolAccess(
1094
1108
  cwd: string,
1095
1109
  toolName: string,
@@ -4596,7 +4610,7 @@ export default function piagentGuard(pi: ExtensionAPI) {
4596
4610
  });
4597
4611
  if (phaseMutationDecision) return phaseMutationDecision;
4598
4612
  if (pendingHumanApproval && !sessionTask) {
4599
- const approval = await piApprovalBroker.request({ cwd: ctx.cwd, rawSessionId: ctx.sessionManager.getSessionId(), toolCallId: String(event.toolCallId), expectedTask: null, action: { ...pendingHumanApproval.action, preconditionClass: "runtime-only", treePrecondition: null }, terminalConfirm: () => ctx.ui.confirm(pendingHumanApproval!.prompt, pendingHumanApproval!.title) });
4613
+ const approval = await piApprovalBroker.request({ cwd: ctx.cwd, rawSessionId: ctx.sessionManager.getSessionId(), toolCallId: String(event.toolCallId), expectedTask: null, action: { ...pendingHumanApproval.action, preconditionClass: "runtime-only", treePrecondition: null }, terminalConfirm: () => ctx.ui.confirm(pendingHumanApproval!.prompt, pendingHumanApproval!.title), unavailableFallback: approvalUnavailableFallback(ctx) });
4600
4614
  if (!approval.allowed) return { block: true, reason: pendingHumanApproval.action.kind === "external-provider-action" && !SHELL_TOOL_NAMES.has(event.toolName) ? `User denied external provider action: ${event.toolName}` : `User denied command: ${pendingHumanApproval.action.reason}` };
4601
4615
  pendingHumanApproval = null;
4602
4616
  }
@@ -4659,6 +4673,7 @@ export default function piagentGuard(pi: ExtensionAPI) {
4659
4673
  : { workspaceRevision: `workspace-rev.${crypto.createHash("sha256").update(currentTreeDigest).digest("hex")}`, indexRevision: null, preimageDigest: currentTreeDigest };
4660
4674
  const approval = await piApprovalBroker.request({ cwd: ctx.cwd, rawSessionId: ctx.sessionManager.getSessionId(), toolCallId: String(event.toolCallId), expectedTask: sessionTask ? { taskId: sessionTask.taskId, taskRunId: sessionTask.taskRunId } : null,
4661
4675
  action: { ...pendingHumanApproval.action, treePrecondition }, terminalConfirm: () => ctx.ui.confirm(pendingHumanApproval!.prompt, pendingHumanApproval!.title),
4676
+ unavailableFallback: approvalUnavailableFallback(ctx),
4662
4677
  recheck: () => !treePrecondition || (() => { const current = workingTreeSnapshot(ctx.cwd);
4663
4678
  return !workingTreeSnapshotHasUnavailableEvidence(current) && workingTreeEvidenceDigest(current) === treePrecondition.preimageDigest; })() });
4664
4679
  if (!approval.allowed) return { block: true, reason: pendingHumanApproval.action.kind === "external-provider-action" && !SHELL_TOOL_NAMES.has(event.toolName) ? `User denied external provider action: ${event.toolName}` : `User denied command: ${pendingHumanApproval.action.reason}` };
@@ -664,7 +664,7 @@ function commandRuleMatches(rule, segment, words) {
664
664
  return arrayStartsWith(words, prefix);
665
665
  }
666
666
  const raw = Array.isArray(rule.value) ? rule.value.join(" ") : rule.value;
667
- if (rule.match === "contains") return segment.toLowerCase().includes(raw.toLowerCase());
667
+ if (rule.match === "contains") return !(rule.ignoreSearchArguments && ["grep", "egrep", "fgrep", "rg"].includes(commandBasename(stripWrapper(words)[0] ?? ""))) && segment.toLowerCase().includes(raw.toLowerCase());
668
668
  try {
669
669
  return new RegExp(raw, "i").test(segment);
670
670
  } catch {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piagent/core",
3
- "version": "1.5.4",
3
+ "version": "1.5.5",
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "license": "MIT",
@@ -99,6 +99,7 @@
99
99
  "id": "prompt-database-migration",
100
100
  "action": "prompt",
101
101
  "match": "contains",
102
+ "ignoreSearchArguments": true,
102
103
  "value": "migrate",
103
104
  "reason": "Database migrations require explicit human confirmation."
104
105
  }
@@ -54,7 +54,11 @@ export function adaptActivityTelemetryEvent(input: ActivityEventAdapterInput): R
54
54
  const activityType = hasOperation ? "tool" : ["bash", "shell", "exec"].includes(toolName) ? "command" : "other";
55
55
  const failed = eventName === "tool_result" && (event.isError === true || typeof event.exitCode === "number" && event.exitCode !== 0);
56
56
  const blocked = eventName === "tool_decision";
57
- const state = eventName === "tool_call" ? "started" : blocked ? "blocked" : failed ? "failed" : "finished";
57
+ // `tool_call` is emitted before policy authorization. Calling it "started"
58
+ // made the Dashboard claim a command was running while it was still waiting
59
+ // for (or had failed to obtain) permission. Native Gateway
60
+ // `tool_execution_start` remains the authoritative running boundary.
61
+ const state = eventName === "tool_call" ? "requested" : blocked ? "blocked" : failed ? "failed" : "finished";
58
62
  const kind = `activity.${state}`;
59
63
  const previewValue = blocked ? event.reason : event.command ?? event.targetPath ?? event.toolName;
60
64
  const preview = safeText(previewValue, 4000);
@@ -42,6 +42,7 @@ type Pending = { request: Request; resolve(value: ApprovalGuardDecision): void;
42
42
  export type ApprovalBrokerEvent = { kind: "requested" | "resolved" | "expired" | "cancelled"; approvalRef: string; request?: Request; receipt?: Receipt };
43
43
  export type ApprovalGuardDecision = { allowed: boolean; brokered: boolean; receipt: Receipt | null;
44
44
  consume(): boolean; cancel(reasonCode?: string): void };
45
+ export type ApprovalUnavailableFallback = "terminal-confirm" | "deny";
45
46
 
46
47
  function canonical(value: unknown): string {
47
48
  if (Array.isArray(value)) return `[${value.map(canonical).join(",")}]`;
@@ -60,6 +61,10 @@ function exactKeys(value: unknown, keys: string[]): boolean {
60
61
  function ref(prefix: string, secret: Buffer, value: unknown): string {
61
62
  return `${prefix}.${createHmac("sha256", secret).update(canonical(value)).digest("hex")}`;
62
63
  }
64
+ function providerRef(prefix: string, secret: Buffer, value: string): string | null {
65
+ if (!value) return null;
66
+ return REF.test(value) ? value : ref(prefix, secret, value);
67
+ }
63
68
  function digest(secret: Buffer, value: unknown): string { return `sha256:${createHmac("sha256", secret).update(canonical(value)).digest("hex")}`; }
64
69
  function safe(value: unknown, maximum: number): { text: string; redacted: boolean; truncated: boolean } {
65
70
  const raw = String(value ?? ""); const redacted = redactSensitiveText(raw);
@@ -104,6 +109,13 @@ export class PiApprovalBroker {
104
109
  return targets.length;
105
110
  }
106
111
 
112
+ cancelForOperation(cwd: string, rawSessionId: string, agentOperationId: string, reason = "operation-aborted"): number {
113
+ const binding = this.#bindings.get(key(cwd, rawSessionId)); if (!binding) return 0;
114
+ const targets = [...binding.pending.entries()].filter(([, pending]) => pending.request.identity.agentOperationId === agentOperationId);
115
+ for (const [approvalRef] of targets) this.#cancelPending(binding, approvalRef, reason, "runtime-control", "cancelled");
116
+ return targets.length;
117
+ }
118
+
107
119
  projection(cwd: string, rawSessionId: string): { revision: string | null; summary: Record<string, unknown> } {
108
120
  const binding = this.#bindings.get(key(cwd, rawSessionId));
109
121
  if (!binding) return { revision: null, summary: { state: "unknown", pending: [], recent: [],
@@ -123,22 +135,29 @@ export class PiApprovalBroker {
123
135
  }
124
136
 
125
137
  async request(input: { cwd: string; rawSessionId: string; toolCallId: string; action: ApprovalActionDraft;
126
- expectedTask?: { taskId: string; taskRunId: string } | null; terminalConfirm(): Promise<boolean>; recheck?(): boolean; ttlMs?: number }): Promise<ApprovalGuardDecision> {
138
+ expectedTask?: { taskId: string; taskRunId: string } | null; terminalConfirm(): Promise<boolean>;
139
+ unavailableFallback?: ApprovalUnavailableFallback; recheck?(): boolean; ttlMs?: number }): Promise<ApprovalGuardDecision> {
127
140
  const binding = this.#bindings.get(key(input.cwd, input.rawSessionId));
128
141
  const authority = binding?.authority();
142
+ // Provider tool-call IDs are opaque. OpenAI Responses IDs, for example,
143
+ // can contain `|`, while public WebUI refs deliberately cannot. Rejecting
144
+ // the provider alphabet sent Gateway approvals into the terminal fallback,
145
+ // where no terminal exists. Keep the provider value private and bind the
146
+ // approval to a deterministic broker-local ref instead.
147
+ const toolCallId = binding ? providerRef("tool", binding.secret, input.toolCallId) : null;
129
148
  if (!binding || !authority || authority.taskState !== "active" || input.expectedTask && (authority.identity.taskId !== input.expectedTask.taskId || authority.identity.taskRunId !== input.expectedTask.taskRunId)
130
149
  || !REF.test(authority.identity.agentOperationId)
131
- || !REF.test(input.toolCallId) || binding.pending.size >= MAX_PENDING) return this.#terminalOnly(input.terminalConfirm);
150
+ || !toolCallId || binding.pending.size >= MAX_PENDING) return this.#unavailable(input);
132
151
  const now = Date.now(), requestedAt = new Date(now).toISOString(), expiresAt = new Date(now + Math.min(Math.max(input.ttlMs ?? DEFAULT_TTL_MS, 5_000), DEFAULT_TTL_MS)).toISOString();
133
- const approvalRef = ref("approval", binding.secret, [input.toolCallId, now, randomUUID()]);
152
+ const approvalRef = ref("approval", binding.secret, [toolCallId, now, randomUUID()]);
134
153
  const decisionToken = randomBytes(32).toString("base64url");
135
154
  const nextRevision = this.#nextRevision(binding, "requested", approvalRef);
136
- const identity: Identity = { ...authority.identity, toolCallId: input.toolCallId };
155
+ const identity: Identity = { ...authority.identity, toolCallId };
137
156
  const action = this.#action(binding, input.action, input.cwd);
138
157
  const expectedRevisions: Revisions = { ...authority.revisions, approvalRevision: nextRevision,
139
158
  treePrecondition: input.action.preconditionClass === "runtime-only" ? null : input.action.treePrecondition ?? null };
140
159
  if ((input.action.preconditionClass !== "runtime-only" && !expectedRevisions.treePrecondition)
141
- || !this.#validTree(expectedRevisions.treePrecondition)) return this.#terminalOnly(input.terminalConfirm);
160
+ || !this.#validTree(expectedRevisions.treePrecondition)) return this.#unavailable(input);
142
161
  const request: Request = { schemaVersion: 1, version: "piagent-webui-approval-v1", recordType: "request", approvalRef, decisionToken,
143
162
  identity, action, expectedRevisions, state: "waiting", requestedAt, expiresAt, executor: "pi-guard", directExecution: false };
144
163
  const result = new Promise<ApprovalGuardDecision>((resolve) => {
@@ -183,6 +202,11 @@ export class PiApprovalBroker {
183
202
  consume: () => false, cancel: () => undefined }));
184
203
  }
185
204
 
205
+ #unavailable(input: { terminalConfirm(): Promise<boolean>; unavailableFallback?: ApprovalUnavailableFallback }): Promise<ApprovalGuardDecision> {
206
+ if (input.unavailableFallback !== "deny") return this.#terminalOnly(input.terminalConfirm);
207
+ return Promise.resolve({ allowed: false, brokered: false, receipt: null, consume: () => false, cancel: () => undefined });
208
+ }
209
+
186
210
  #action(binding: Binding, draft: ApprovalActionDraft, cwd: string): Record<string, unknown> {
187
211
  const command = draft.commandPreview === null || draft.commandPreview === undefined ? null : safe(draft.commandPreview, 4_000);
188
212
  const parameter = safe(draft.parameterPreview ?? "No additional parameters", 4_000);
@@ -298,6 +298,10 @@ export class SessionRuntimeSupervisor {
298
298
  const active = this.#active.get(sessionRef), session = active?.runtime.session;
299
299
  if (!active || !session || active.operationRef !== operationRef) throw new Error("session-operation-conflict");
300
300
  const completion = active.completion;
301
+ // Extension hooks do not receive the Agent abort signal while awaiting a
302
+ // human approval. Resolve the exact operation's broker promise first so a
303
+ // stop request can reach the host instead of waiting for approval expiry.
304
+ piApprovalBroker.cancelForOperation(active.info.cwd, active.info.id, operationRef);
301
305
  await session.abort();
302
306
  if (clearQueued) session.clearQueue();
303
307
  await completion;
@@ -122,6 +122,17 @@ async function currentLaunchUrl() {
122
122
  return null;
123
123
  }
124
124
 
125
+ async function waitForGatewayStopped(previous, timeoutMs = 8_000) {
126
+ const deadline = Date.now() + timeoutMs;
127
+ while (Date.now() < deadline) {
128
+ const previousAlive = Boolean(previous && processAlive(previous.pid));
129
+ const liveUrl = await currentLaunchUrl();
130
+ if (!previousAlive && !liveUrl) return;
131
+ await new Promise((resolve) => setTimeout(resolve, 80));
132
+ }
133
+ throw new Error("gateway-restart-stop-timeout\nThe previous Gateway did not stop; restart refused to reuse the old process.");
134
+ }
135
+
125
136
  async function ensureStarted() {
126
137
  const existing = await currentLaunchUrl();
127
138
  if (existing) return existing;
@@ -199,8 +210,9 @@ async function main() {
199
210
  return;
200
211
  }
201
212
  if (command === "restart") {
213
+ const previous = readGatewayDescriptor(gatewayProfileState(agentDir));
202
214
  try { await control("stop"); } catch { /* already stopped */ }
203
- await new Promise((resolve) => setTimeout(resolve, 150));
215
+ await waitForGatewayStopped(previous);
204
216
  const launchUrl = await ensureStarted();
205
217
  output(json ? { state: "running", launchUrl } : launchUrl);
206
218
  openBrowser(launchUrl);