@piagent/platform 1.15.2 → 1.16.1

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 (74) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +1 -1
  3. package/README.vi.md +1 -1
  4. package/docs/command-reference-vietnamese.md +2 -2
  5. package/docs/distribution-standard.md +6 -6
  6. package/docs/languages.json +2 -2
  7. package/docs/operator-manual-vietnamese.md +7 -7
  8. package/docs/publishing-for-teams.md +3 -1
  9. package/docs/release-install-policy.md +2 -2
  10. package/docs/team-onboarding.md +2 -2
  11. package/docs-site/architecture.html +1 -1
  12. package/docs-site/benchmark.html +1 -1
  13. package/docs-site/commands.html +1 -1
  14. package/docs-site/content/en/index.html +4 -4
  15. package/docs-site/content/en/whats-new.html +22 -0
  16. package/docs-site/content/index.html +4 -4
  17. package/docs-site/content/whats-new.html +22 -0
  18. package/docs-site/context-engine.html +1 -1
  19. package/docs-site/ecosystem.html +1 -1
  20. package/docs-site/en/architecture.html +1 -1
  21. package/docs-site/en/benchmark.html +1 -1
  22. package/docs-site/en/commands.html +1 -1
  23. package/docs-site/en/context-engine.html +1 -1
  24. package/docs-site/en/ecosystem.html +1 -1
  25. package/docs-site/en/index.html +5 -5
  26. package/docs-site/en/mcp-approval.html +1 -1
  27. package/docs-site/en/mcp-auth.html +1 -1
  28. package/docs-site/en/mcp-servers.html +1 -1
  29. package/docs-site/en/mcp.html +1 -1
  30. package/docs-site/en/permissions.html +1 -1
  31. package/docs-site/en/profiles.html +1 -1
  32. package/docs-site/en/quickstart.html +1 -1
  33. package/docs-site/en/runtime.html +1 -1
  34. package/docs-site/en/scope.html +1 -1
  35. package/docs-site/en/security.html +1 -1
  36. package/docs-site/en/team.html +1 -1
  37. package/docs-site/en/whats-new.html +23 -1
  38. package/docs-site/en/windows.html +1 -1
  39. package/docs-site/en/workflows.html +1 -1
  40. package/docs-site/index.html +5 -5
  41. package/docs-site/mcp-approval.html +1 -1
  42. package/docs-site/mcp-auth.html +1 -1
  43. package/docs-site/mcp-servers.html +1 -1
  44. package/docs-site/mcp.html +1 -1
  45. package/docs-site/permissions.html +1 -1
  46. package/docs-site/profiles.html +1 -1
  47. package/docs-site/quickstart.html +1 -1
  48. package/docs-site/runtime.html +1 -1
  49. package/docs-site/scope.html +1 -1
  50. package/docs-site/security.html +1 -1
  51. package/docs-site/team.html +1 -1
  52. package/docs-site/whats-new.html +23 -1
  53. package/docs-site/windows.html +1 -1
  54. package/docs-site/workflows.html +1 -1
  55. package/evals/private-holdout-v1/public-exposure.v2.json +2 -2
  56. package/package.json +1 -1
  57. package/packages/piagent-core/extensions/piagent-guard.ts +8 -1
  58. package/packages/piagent-core/extensions/update-check.js +2 -2
  59. package/packages/piagent-core/managed/permission.mjs +22 -0
  60. package/packages/piagent-core/managed/session.mjs +15 -7
  61. package/packages/piagent-core/package.json +1 -1
  62. package/packages/piagent-core/runtime/policy/bypass-policy.mjs +42 -0
  63. package/packages/piagent-webui/dist/client/assets/{MarkdownMessage-DjA3OGyI.js → MarkdownMessage-sL0LOqY0.js} +1 -1
  64. package/packages/piagent-webui/dist/client/assets/index-Bs8l37SR.js +228 -0
  65. package/packages/piagent-webui/dist/client/index.html +1 -1
  66. package/packages/piagent-webui/gateway/gateway-service.ts +2 -1
  67. package/packages/piagent-webui/gateway/managed-projection.ts +3 -1
  68. package/packages/piagent-webui/gateway/runtime-session-controls.ts +7 -1
  69. package/packages/piagent-webui/gateway/session-catalog.ts +3 -2
  70. package/packages/piagent-webui/gateway/update-center.ts +3 -2
  71. package/packages/piagent-webui/server/loopback-server.ts +1 -0
  72. package/packages/piagent-webui/server/session-auth.ts +13 -2
  73. package/schemas/piagent-webui/session-catalog-v1.schema.json +1 -1
  74. package/packages/piagent-webui/dist/client/assets/index-bE2DKmc1.js +0 -228
@@ -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.15.2 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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.15.2 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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.15.2 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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>
@@ -104,6 +104,28 @@
104
104
  <h1>1.9.0: ask in plain language, the team's Harness checks</h1>
105
105
  <p>The task contract and workflow commands are gone. Company mode asks for checks and a review on its own; Stop, network commands on approval and clearer approval cards.</p>
106
106
  </div>
107
+ <section class="section">
108
+ <p class="section-kicker">v1.16.1 · 2026-10-07</p>
109
+ <h2 id="v1-16-1">New releases are announced, checked every hour</h2>
110
+ <p class="section-lead">When a new Piagent is out, the dashboard opens a dialog with what will change and <strong>Update now</strong>; <strong>Later</strong> asks again after an hour. After the update, the restarted dashboard says it worked. The dashboard and the Terminal check for a new release every hour.</p>
111
+ <ul>
112
+ <li>A dashboard tab no longer loses its sign-in when another Piagent server on the machine (the company runtime, another launch) signs in.</li>
113
+ <li>A tab whose sign-in is gone (Piagent restarted, older than 8 hours) no longer retries with 401 errors; it says how to open Piagent again: <span class="inline-code">piagent dashboard</span> or Agent Watch.</li>
114
+ </ul>
115
+ <p>Updating from 1.16.0 needs no re-import in Agent Watch.</p>
116
+ </section>
117
+
118
+ <section class="section">
119
+ <p class="section-kicker">v1.16.0 · 2026-10-07</p>
120
+ <h2 id="v1-16-0">Bypass for company conversations</h2>
121
+ <p class="section-lead">Choose <strong>Bypass</strong> in the new-chat options or the conversation header ("Ask first" stays the default). Commands that need the internet (package installs, downloads, git pull, tests with a server or browser) run without asking. You are still asked before anything that pushes or sends data out (git push, publish, deploy, uploads, ssh), database migrations, deletes with an unknown target, and sudo.</p>
122
+ <ul>
123
+ <li>A helper the company Harness adds while you work is available from your next message, without a new conversation. With Studio 0.20.1 a running turn is not stopped when the Harness is saved.</li>
124
+ <li>Personal sessions with full access no longer ask before a broad <span class="inline-code">git add</span>; deletes, migrations and external actions are still asked.</li>
125
+ </ul>
126
+ <p>Updating from 1.15.x needs no re-import in Agent Watch.</p>
127
+ </section>
128
+
107
129
  <section class="section">
108
130
  <p class="section-kicker">v1.15.2 · 2026-10-07</p>
109
131
  <h2 id="v1-15-2">Long company conversations shrink again, earlier</h2>
@@ -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.15.2 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 docs · EN</span>
34
34
  <nav class="language-switch" aria-label="Language">
35
35
  <a class="language-option" href="/windows" hreflang="vi" lang="vi">VI</a>
36
36
  <a class="language-option current" href="/en/windows" 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.15.2 docs · EN</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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.15.2 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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>
@@ -94,7 +94,7 @@
94
94
  <main>
95
95
  <div class="content-shell" data-article>
96
96
  <section class="hero">
97
- <p class="eyebrow">Piagent 1.15.2</p>
97
+ <p class="eyebrow">Piagent 1.16.1</p>
98
98
  <h1>Coding agent cho cả team, kiểm tra từng bước.</h1>
99
99
  <p>
100
100
  Một dashboard cho Terminal và trình duyệt. Dùng model bằng tài khoản của bạn, hoặc model của công ty qua Agent Watch và Agent Studio. Guard kiểm tra từng tool call; ở chế độ công ty, Harness của team tự yêu cầu chạy check, cho subagent review và báo kết quả ngay dưới câu trả lời.
@@ -108,7 +108,7 @@
108
108
  <div class="hero-actions">
109
109
  <a class="button primary" href="/quickstart">Bắt đầu</a>
110
110
  <a class="button" href="/ecosystem">Hệ sinh thái</a>
111
- <a class="button" href="/whats-new">Có gì mới trong 1.15.2</a>
111
+ <a class="button" href="/whats-new">Có gì mới trong 1.16.1</a>
112
112
  <a class="button" href="/commands">Xem command</a>
113
113
  </div>
114
114
  </section>
@@ -184,9 +184,9 @@ piagent-setup</code></pre>
184
184
  <h2 id="bat-dau-tu-dau">Bắt đầu từ đâu</h2>
185
185
  <div class="card-grid">
186
186
  <a class="doc-card" href="/whats-new">
187
- <span class="card-kicker">Bản 1.15.2</span>
187
+ <span class="card-kicker">Bản 1.16.1</span>
188
188
  <h3>Có gì mới</h3>
189
- <p>Cuộc trò chuyện công ty dài tự thu gọn trở lại, sớm hơn (90% cửa sổ, muộn nhất 300k token); ở 1.15.1: Studio thấy mỗi call của model dùng để làm gì, nhiều cuộc trò chuyện trong một folder không nhận nhầm thay đổi của nhau; ở 1.15.0: subagent bị từ chối nói đúng lý do; ở 1.14: cập nhật giữ model bạn đã chọn; ở 1.13: cuộc trò chuyện giữ chỗ đang đọc, chữ của agent có định dạng, Piagent trên Windows qua WSL2: sandbox công ty bằng bubblewrap và Agent Watch cho Windows; ở 1.12: @ chọn file và folder trên máy, skill và command dùng bằng /, nhánh cuộc trò chuyện công ty gửi được tin nhắn.</p>
189
+ <p>Bản mới được báo bằng dialog và kiểm tra mỗi giờ, tab dashboard không còn mất đăng nhập; ở 1.16.0: Bypass cho cuộc trò chuyện công ty, đổi Harness không làm gián đoạn; ở 1.15.2: cuộc trò chuyện dài tự thu gọn trở lại; ở 1.15.1: Studio thấy mỗi call của model dùng để làm gì, nhiều cuộc trò chuyện trong một folder không nhận nhầm thay đổi của nhau; ở 1.15.0: subagent bị từ chối nói đúng lý do; ở 1.14: cập nhật giữ model bạn đã chọn; ở 1.13: cuộc trò chuyện giữ chỗ đang đọc, chữ của agent có định dạng, Piagent trên Windows qua WSL2: sandbox công ty bằng bubblewrap và Agent Watch cho Windows; ở 1.12: @ chọn file và folder trên máy, skill và command dùng bằng /, nhánh cuộc trò chuyện công ty gửi được tin nhắn.</p>
190
190
  </a>
191
191
  <a class="doc-card" href="/ecosystem">
192
192
  <span class="card-kicker">Get started</span>
@@ -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.15.2 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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.15.2 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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.15.2 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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.15.2 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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.15.2 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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.15.2 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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.15.2 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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.15.2 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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.15.2 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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.15.2 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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.15.2 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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.15.2 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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>
@@ -104,6 +104,28 @@
104
104
  <h1>Bản 1.9.0: nói việc bằng lời, Harness của team kiểm tra</h1>
105
105
  <p>Bỏ task contract và lệnh workflow. Chế độ công ty tự yêu cầu check và review; nút Dừng, lệnh có mạng theo lần duyệt và thẻ duyệt dễ đọc hơn.</p>
106
106
  </div>
107
+ <section class="section">
108
+ <p class="section-kicker">v1.16.1 · 2026-10-07</p>
109
+ <h2 id="v1-16-1">Báo bản mới rõ ràng, kiểm tra mỗi giờ</h2>
110
+ <p class="section-lead">Khi có bản Piagent mới, dashboard mở một dialog ghi rõ sẽ đổi gì và nút <strong>Cập nhật ngay</strong>; chọn <strong>Để sau</strong> thì 1 giờ sau nhắc lại. Cập nhật xong, dashboard mở lại báo đã thành công. Dashboard và Terminal tự kiểm tra bản mới mỗi giờ.</p>
111
+ <ul>
112
+ <li>Tab dashboard không còn bị mất đăng nhập khi một server Piagent khác trên máy (runtime công ty, lần mở khác) đăng nhập.</li>
113
+ <li>Tab đã hết phiên (Piagent khởi động lại, quá 8 giờ) không còn gọi lại liên tục với lỗi 401 mà nói rõ cách mở lại: <span class="inline-code">piagent dashboard</span> hoặc Agent Watch.</li>
114
+ </ul>
115
+ <p>Cập nhật từ 1.16.0 không cần nhập lại cấu hình trong Agent Watch.</p>
116
+ </section>
117
+
118
+ <section class="section">
119
+ <p class="section-kicker">v1.16.0 · 2026-10-07</p>
120
+ <h2 id="v1-16-0">Bypass cho cuộc trò chuyện công ty</h2>
121
+ <p class="section-lead">Chọn <strong>Bypass</strong> trong tùy chọn cuộc trò chuyện mới hoặc trên thanh đầu cuộc trò chuyện ("Hỏi trước" vẫn là mặc định). Lệnh cần internet (cài package, tải file, git pull, test có server hay browser) chạy luôn, không hỏi. Vẫn hỏi trước khi đẩy hoặc gửi dữ liệu ra ngoài (git push, publish, deploy, upload, ssh), chạy migration database, xóa mà không rõ đích hoặc dùng sudo.</p>
122
+ <ul>
123
+ <li>Harness công ty thêm subagent trong lúc bạn đang làm: dùng được ngay từ tin nhắn kế tiếp, không cần mở cuộc trò chuyện mới. Với Studio 0.20.1, lượt đang chạy không bị dừng khi Harness được lưu.</li>
124
+ <li>Phiên cá nhân "Toàn quyền" không còn hỏi trước <span class="inline-code">git add</span> toàn bộ; xóa, migration và thao tác ra ngoài vẫn hỏi.</li>
125
+ </ul>
126
+ <p>Cập nhật từ 1.15.x không cần nhập lại cấu hình trong Agent Watch.</p>
127
+ </section>
128
+
107
129
  <section class="section">
108
130
  <p class="section-kicker">v1.15.2 · 2026-10-07</p>
109
131
  <h2 id="v1-15-2">Cuộc trò chuyện công ty dài tự thu gọn trở lại, và sớm hơn</h2>
@@ -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.15.2 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 docs · VI</span>
34
34
  <nav class="language-switch" aria-label="Ngôn ngữ">
35
35
  <a class="language-option current" href="/windows" hreflang="vi" lang="vi" aria-current="true">VI</a>
36
36
  <a class="language-option" href="/en/windows" 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.15.2 docs · VI</span>
33
+ <span class="pill"><span class="pill-dot"></span>v1.16.1 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>
@@ -256,8 +256,8 @@
256
256
  },
257
257
  {
258
258
  "path": "tests",
259
- "fileCount": 524,
260
- "sha256": "d35f964fb3f4cc90d79f2f65ada154f81f255fc44c3861e473bffab813189afd"
259
+ "fileCount": 525,
260
+ "sha256": "c9ef8c449f71514ed8f32161be6d5280ea4ccd702341cc5ca645c9e51f70fb7f"
261
261
  }
262
262
  ],
263
263
  "custodianComparisonRules": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piagent/platform",
3
- "version": "1.15.2",
3
+ "version": "1.16.1",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -547,6 +547,9 @@ function verifyProjectCapabilityState(
547
547
  }
548
548
  }
549
549
 
550
+ // Exec-policy prompts a full-access session does not show: local, reversible.
551
+ const FULL_ACCESS_SKIPPED_PROMPTS = ["prompt-git-add-broad"];
552
+
550
553
  function evaluateExecPolicy(command: string, profile: ProjectProfile, policy: BasePolicy): {
551
554
  mode: RuntimePolicySettings["execPolicy"];
552
555
  decision: "allow" | "prompt" | "forbid";
@@ -3953,7 +3956,11 @@ export default function piagentGuard(pi: ExtensionAPI) {
3953
3956
  return { block: true, reason: unresolvedExpansionReason("Command", unresolvedExpansions) };
3954
3957
  }
3955
3958
 
3956
- const confirmationReasons = execDecision.mode !== "off" && execDecision.decision === "prompt" ? [...execDecision.reasons] : [];
3959
+ // Full access skips the prompts for local, reversible steps; deletes,
3960
+ // migrations and anything sent outside this machine are still asked.
3961
+ const confirmationReasons = (execDecision.mode !== "off" && execDecision.decision === "prompt" ? [...execDecision.reasons] : [])
3962
+ .filter((reason) => permissionProfile.mode !== "trusted-full-access"
3963
+ || !FULL_ACCESS_SKIPPED_PROMPTS.some((id) => reason.startsWith(`Prompt required by exec policy ${id}:`)));
3957
3964
  const externalReason = findShellExternalConfirmationReason(execDecision.segments, externalActionPolicyConfig(policy));
3958
3965
  if (externalReason) confirmationReasons.push(externalReason);
3959
3966
  if (confirmationReasons.length > 0) {
@@ -6,7 +6,7 @@ import { fileURLToPath } from "node:url";
6
6
 
7
7
  // Telling someone a new release exists is only useful if it costs them nothing.
8
8
  // A session start that waits on the registry pays a network round trip every
9
- // time Pi opens, for information that changes a few times a month, so the check
9
+ // time Pi opens, for information that can change several times a day, so the check
10
10
  // never runs in the session's path: the session reads a cache file and, when
11
11
  // that cache is old, leaves a detached process behind to refresh it. The notice
12
12
  // lands on this session if the cache already knew, and on the next one if it did
@@ -20,7 +20,7 @@ import { fileURLToPath } from "node:url";
20
20
 
21
21
  const HELPER_PACKAGE = "@piagent/platform";
22
22
  const CACHE_FILE = "piagent-update-check.json";
23
- const CACHE_TTL_MS = 24 * 60 * 60 * 1000;
23
+ const CACHE_TTL_MS = 60 * 60 * 1000;
24
24
  const PROBE_TIMEOUT_MS = 10_000;
25
25
  const MAX_CACHE_BYTES = 4096;
26
26
  const RELEASE_VERSION = /^(0|[1-9]\d{0,8})\.(0|[1-9]\d{0,8})\.(0|[1-9]\d{0,8})$/;
@@ -0,0 +1,22 @@
1
+ // A company conversation's access, chosen by the member and kept with the
2
+ // conversation: "workspace-write" asks before every command that needs the
3
+ // internet; "trusted-full-access" (Bypass) asks only for what must be
4
+ // confirmed (runtime/policy/bypass-policy.mjs).
5
+ import { mustConfirm } from '../runtime/policy/bypass-policy.mjs';
6
+
7
+ export const PERMISSIONS = ['workspace-write', 'trusted-full-access'];
8
+ const ENTRY = 'agent-watch-permission';
9
+
10
+ export function restorePermission(manager) {
11
+ const chosen = manager.getEntries().filter(e => e.type === 'custom' && e.customType === ENTRY).at(-1)?.data?.mode;
12
+ return PERMISSIONS.includes(chosen) ? chosen : 'workspace-write';
13
+ }
14
+ export function permissionSetter(owner, manager) {
15
+ return mode => {
16
+ if (!PERMISSIONS.includes(mode)) throw Error('managed-permission-unavailable');
17
+ manager.appendCustomEntry(ENTRY, { mode, at: new Date().toISOString() }); owner.permission = mode;
18
+ };
19
+ }
20
+ // Why a network command must still be asked about: null runs it in Bypass,
21
+ // 'ask' when the member asks first.
22
+ export const networkConfirmation = (owner, command) => owner.permission === 'trusted-full-access' ? mustConfirm(command) : 'ask';
@@ -23,6 +23,7 @@ import { workflowPolicy, repositoryChecks, planTool, currentPlan, PLAN_ENTRY, wo
23
23
  import { beforeDelegate } from './objections.mjs';
24
24
  import { HELPER_CALLS, HELPER_ROLES, helperRoles, helperPrompt, webPrompt, delegateDescription } from './helper-roles.mjs';
25
25
  import { loadAgentResources } from './agent-skills.mjs';
26
+ import { restorePermission, permissionSetter, networkConfirmation } from './permission.mjs';
26
27
 
27
28
  const PROVIDER = 'agent_watch_managed';
28
29
  // Who the agent is: the model account may put another product's name in an
@@ -109,6 +110,7 @@ export class ManagedSession {
109
110
  parameters:{type:'object',properties:{},additionalProperties:false},
110
111
  execute:async(id,_args,signal,_update,ctx)=>{
111
112
  const plan=await repositoryFetchPlan(self.boundary);
113
+ if(self.permission==='trusted-full-access'&&!signal?.aborted)return executeRepositoryFetch(self.boundary,plan,signal);
112
114
  const {piApprovalBroker}=await import('../runtime/inspection/approval-broker.ts');
113
115
  const decision=await piApprovalBroker.request({cwd:self.cwd,rawSessionId:self.session.sessionManager.getSessionId(),toolCallId:id,
114
116
  action:{kind:'external-provider-action',preconditionClass:'runtime-only',toolName:'fetch_origin',rawAction:plan,
@@ -125,10 +127,11 @@ export class ManagedSession {
125
127
  customTools.push({name:'run_with_network',label:'Run with network',description:'Run one shell command that needs the internet (package install, download, git pull of a public repository), or that starts a local server or a browser (end-to-end tests with Playwright\'s Chromium against a server on 127.0.0.1), after the user approves that exact command. Normal bash has no network and cannot listen on a port. Credentials (.npmrc, SSH keys, Keychain) stay unavailable, so private registries and git push are not possible here.',
126
128
  parameters:{type:'object',properties:{command:{type:'string',minLength:1,maxLength:4000},reason:{type:'string',minLength:1,maxLength:300},timeout:{type:'number',minimum:1,maximum:1800}},required:['command','reason'],additionalProperties:false},
127
129
  execute:async(id,args,signal,onUpdate,ctx)=>{
128
- const {piApprovalBroker}=await import('../runtime/inspection/approval-broker.ts');
129
- const decision=await piApprovalBroker.request({cwd:self.cwd,rawSessionId:self.session.sessionManager.getSessionId(),toolCallId:id,
130
+ // Bypass runs it without asking, unless it is one the member must confirm.
131
+ const confirm=await networkConfirmation(self,args.command);
132
+ const decision=confirm===null?{allowed:true,consume:()=>true}:await (await import('../runtime/inspection/approval-broker.ts')).piApprovalBroker.request({cwd:self.cwd,rawSessionId:self.session.sessionManager.getSessionId(),toolCallId:id,
130
133
  action:{kind:'external-provider-action',preconditionClass:'runtime-only',toolName:'run_with_network',rawAction:{command:args.command},commandPreview:String(args.command),
131
- targetPaths:[self.cwd],provider:'network',urlOrigin:null,requestedScope:'network-command-once',reason:String(args.reason).slice(0,300),riskClass:'medium',
134
+ targetPaths:[self.cwd],provider:'network',urlOrigin:null,requestedScope:'network-command-once',reason:(confirm==='ask'?String(args.reason):`Bypass still asks: ${confirm}. ${args.reason}`).slice(0,300),riskClass:'medium',
132
135
  allowConsequence:'Run this exact command once, with internet access; a server it starts accepts connections while it runs.',denyConsequence:'The command does not run; the agent is told you declined.'},
133
136
  terminalConfirm:()=>ctx?.ui?.confirm?.('Run with network',`Allow internet access for: ${args.command}`)??Promise.resolve(false),
134
137
  unavailableFallback:'terminal-confirm',recheck:()=>!signal?.aborted&&Boolean(self.grant)});
@@ -138,11 +141,14 @@ export class ManagedSession {
138
141
  try { const result=await self.boundary.invoke('bash',{command:args.command,...(args.timeout?{timeout:args.timeout}:{})},signal,onUpdate,ctx?.model,{network:true}); ok=!result?.isError; return result; }
139
142
  finally { await self.claimChanges(before); await self.run?.afterTool('bash',args,ok,()=>self.digest()); await self.refreshReview(); }
140
143
  }});
141
- // The helpers of the Harness this conversation enrolled with. A later
142
- // enrollment that drops one is refused at the call (delegate).
144
+ // Every helper role passes the tool's schema: Pi fixes a tool's schema
145
+ // and description when the conversation opens, so a helper a Harness
146
+ // saved later adds must already pass it. The system prompt, rebuilt each
147
+ // turn, names the Harness's current helpers; delegate refuses one the
148
+ // Harness does not have.
143
149
  const roles = helperRoles(manifest);
144
150
  if (roles.length) customTools.push({ name: 'delegate', label: 'Subagent', description: delegateDescription(roles),
145
- parameters: { type: 'object', properties: { role: { type: 'string', enum: roles }, title: { type: 'string', maxLength: 120, description: 'One line naming the job, for the company logs (for example "Find where login tokens are stored").' }, task: { type: 'string', minLength: 1, maxLength: 12000 } }, required: ['role', 'task'], additionalProperties: false },
151
+ parameters: { type: 'object', properties: { role: { type: 'string', enum: HELPER_ROLES }, title: { type: 'string', maxLength: 120, description: 'One line naming the job, for the company logs (for example "Find where login tokens are stored").' }, task: { type: 'string', minLength: 1, maxLength: 12000 } }, required: ['role', 'task'], additionalProperties: false },
146
152
  execute: (_id, args, signal) => self.delegate(args, signal) });
147
153
  customTools.push(planTool(async plan => {
148
154
  self.session.sessionManager.appendCustomEntry(PLAN_ENTRY, { ...plan, at: new Date().toISOString() });
@@ -185,6 +191,8 @@ export class ManagedSession {
185
191
  self.extensionsResult = result.extensionsResult;
186
192
  self.session = result.session;
187
193
  self.session.managedExecution = true;
194
+ // The member's access for this conversation: ask first, or Bypass (permission.mjs).
195
+ self.permission = restorePermission(manager); self.session.managedSetPermission = permissionSetter(self, manager);
188
196
  // A helper's receipt (its tokens, the patch it read) is for the member's
189
197
  // eyes: the agent has the helper's answer as the tool result, and a
190
198
  // receipt in its context reads as a message from the member.
@@ -353,7 +361,7 @@ export class ManagedSession {
353
361
  this.blocked = this.scope && sameMember(this.scope, scope) ? null : 'managed-session-scope-changed';
354
362
  if (this.blocked) throw Error(this.blocked);
355
363
  if (!sameKey(this.scope, scope)) { this.session.sessionManager.appendCustomEntry('agent-watch-scope', scope); this.scope = scope; }
356
- this.session?.setActiveToolsByName(this.session.getActiveToolNames()); // the new Harness workflow reaches the prompt
364
+ this.session?.setActiveToolsByName(this.session.getActiveToolNames()); // the new Harness workflow and helpers reach the prompt
357
365
  }
358
366
  async digest() { try { return await this.changeDigest(); } catch { return null; } }
359
367
  refusedAsTooLong() {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@piagent/core",
3
- "version": "1.15.2",
3
+ "version": "1.16.1",
4
4
  "type": "module",
5
5
  "private": true,
6
6
  "license": "MIT",
@@ -0,0 +1,42 @@
1
+ // What a company conversation in "Bypass" mode still asks the member about
2
+ // (owner, 2026-10-07: a member who chose bypass is not asked again, except for
3
+ // what must be confirmed). Everything else runs without asking.
4
+ // Always asked: anything that changes or sends data outside this machine
5
+ // (git push, publish, deploy, a request that uploads or writes, remote
6
+ // shells, cloud and cluster tools), database migrations, deletes whose
7
+ // target is only known at run time, removing Docker volumes, and sudo.
8
+ import fs from 'node:fs';
9
+ import { fileURLToPath } from 'node:url';
10
+ import { evaluateExecPolicyCore } from '../../extensions/policy-core.js';
11
+
12
+ const POLICY = JSON.parse(fs.readFileSync(fileURLToPath(new URL('../../policies/base-policy.json', import.meta.url)), 'utf8'));
13
+ // Exec-policy prompts a member in bypass may skip: local, reversible.
14
+ const BYPASSABLE_RULES = new Set(['prompt-git-add-broad']);
15
+ // Tools that reach other machines or accounts; none runs without asking.
16
+ const REMOTE = new Set(['ssh', 'scp', 'sftp', 'sudo', 'doas', 'vercel', 'netlify', 'fly', 'flyctl', 'heroku', 'firebase', 'aws', 'gcloud', 'gsutil', 'az',
17
+ 'kubectl', 'helm', 'terraform', 'tofu', 'pulumi', 'eas', 'wrangler', 'supabase', 'railway', 'render', 'doctl']);
18
+ const basename = word => String(word ?? '').split('/').pop();
19
+ const WRAPPERS = new Set(['env', 'command', 'exec', 'time', 'nohup', 'npx', 'bunx', 'pnpx']);
20
+ function executable(words) {
21
+ let i = 0;
22
+ while (i < words.length && (/^[A-Za-z_][A-Za-z0-9_]*=/.test(words[i]) || WRAPPERS.has(basename(words[i])) || words[i].startsWith('-'))) i += 1;
23
+ return { name: basename(words[i]), args: words.slice(i + 1) };
24
+ }
25
+
26
+ // Why this command must still be confirmed, or null when bypass may run it.
27
+ export async function mustConfirm(command) {
28
+ const result = evaluateExecPolicyCore(String(command), { policy: POLICY, mode: 'enforce' });
29
+ const kept = result.reasons.filter(reason => ![...BYPASSABLE_RULES].some(id => reason.startsWith(`Prompt required by exec policy ${id}:`)));
30
+ if (result.decision !== 'allow' && kept.length) return kept[0];
31
+ const { findShellExternalConfirmationReason } = await import('../../extensions/guard-shell-analysis.ts');
32
+ const external = findShellExternalConfirmationReason(result.segments, { defaultMode: 'enforce', ...POLICY.externalActionPolicy });
33
+ if (external) return external;
34
+ for (const segment of result.segments) {
35
+ const { name, args } = executable(segment.words);
36
+ if (REMOTE.has(name)) return `${name} reaches another machine or account`;
37
+ if (name === 'rsync' && args.some(arg => /^[^/\s]*:/.test(arg) && !arg.startsWith('-'))) return 'rsync to another machine';
38
+ if (name === 'docker' && ['push', 'login'].includes(args.find(arg => !arg.startsWith('-')))) return `docker ${args.find(arg => !arg.startsWith('-'))} sends to a registry`;
39
+ if (name === 'git' && args.some(arg => ['push', 'send-email', 'request-pull'].includes(arg))) return 'git sends to a remote';
40
+ }
41
+ return null;
42
+ }