@piagent/platform 1.28.0 → 1.28.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.
- package/CHANGELOG.md +18 -0
- package/README.md +1 -1
- package/README.vi.md +1 -1
- package/docs/command-reference-vietnamese.md +2 -2
- package/docs/distribution-standard.md +6 -6
- package/docs/languages.json +2 -2
- package/docs/operator-manual-vietnamese.md +7 -7
- package/docs/publishing-for-teams.md +1 -0
- package/docs/release-install-policy.md +2 -2
- package/docs/team-onboarding.md +2 -2
- package/docs-site/architecture.html +1 -1
- package/docs-site/benchmark.html +1 -1
- package/docs-site/commands.html +1 -1
- package/docs-site/content/en/index.html +4 -4
- package/docs-site/content/en/whats-new.html +6 -0
- package/docs-site/content/index.html +4 -4
- package/docs-site/content/whats-new.html +6 -0
- package/docs-site/context-engine.html +1 -1
- package/docs-site/ecosystem.html +1 -1
- package/docs-site/en/architecture.html +1 -1
- package/docs-site/en/benchmark.html +1 -1
- package/docs-site/en/commands.html +1 -1
- package/docs-site/en/context-engine.html +1 -1
- package/docs-site/en/ecosystem.html +1 -1
- package/docs-site/en/index.html +5 -5
- package/docs-site/en/mcp-approval.html +1 -1
- package/docs-site/en/mcp-auth.html +1 -1
- package/docs-site/en/mcp-servers.html +1 -1
- package/docs-site/en/mcp.html +1 -1
- package/docs-site/en/permissions.html +1 -1
- package/docs-site/en/profiles.html +1 -1
- package/docs-site/en/quickstart.html +1 -1
- package/docs-site/en/runtime.html +1 -1
- package/docs-site/en/scope.html +1 -1
- package/docs-site/en/security.html +1 -1
- package/docs-site/en/team.html +1 -1
- package/docs-site/en/whats-new.html +7 -1
- package/docs-site/en/windows.html +1 -1
- package/docs-site/en/workflows.html +1 -1
- package/docs-site/index.html +5 -5
- package/docs-site/mcp-approval.html +1 -1
- package/docs-site/mcp-auth.html +1 -1
- package/docs-site/mcp-servers.html +1 -1
- package/docs-site/mcp.html +1 -1
- package/docs-site/permissions.html +1 -1
- package/docs-site/profiles.html +1 -1
- package/docs-site/quickstart.html +1 -1
- package/docs-site/runtime.html +1 -1
- package/docs-site/scope.html +1 -1
- package/docs-site/security.html +1 -1
- package/docs-site/team.html +1 -1
- package/docs-site/whats-new.html +7 -1
- package/docs-site/windows.html +1 -1
- package/docs-site/workflows.html +1 -1
- package/evals/private-holdout-v1/public-exposure.v2.json +2 -2
- package/package.json +1 -1
- package/packages/piagent-core/extensions/company-session-guard.ts +36 -0
- package/packages/piagent-core/extensions/piagent-guard.ts +2 -0
- package/packages/piagent-core/package.json +1 -1
- package/scripts/company-terminal.mjs +12 -0
- package/scripts/install-global.sh +11 -0
- package/scripts/personal-pi-config.mjs +137 -0
- package/scripts/piagent-cli.mjs +8 -0
- package/scripts/piagent-studio.mjs +4 -0
- package/scripts/team-doctor.sh +4 -0
- package/scripts/update-global.mjs +9 -2
|
@@ -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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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,12 @@
|
|
|
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.28.1 · 2026-10-18</p>
|
|
109
|
+
<h2 id="v1-28-1">The company Terminal and personal Pi stop stepping on each other</h2>
|
|
110
|
+
<p class="section-lead">Personal Pi no longer fails to start when Piagent is loaded twice (an extension pointing into another Piagent copy): <span class="inline-code">piagent-update</span> and the installer remove it (with a backup) and <span class="inline-code">piagent-doctor</span> reports it. Old Agent Watch company entries in personal Pi (<span class="inline-code">agent_watch_*</span> providers, a default model naming them) are cleaned up once the machine has a company binding. Personal Pi no longer continues a company conversation and says to open it with <span class="inline-code">piagent studio</span>; the company Terminal says how to reopen it, answers <span class="inline-code">/help</span> itself (no model request) and stops fully when stopped from outside.</p>
|
|
111
|
+
</section>
|
|
112
|
+
|
|
107
113
|
<section class="section">
|
|
108
114
|
<p class="section-kicker">v1.28.0 · 2026-10-17</p>
|
|
109
115
|
<h2 id="v1-28-0">Team memory v2: each round once, a fresh brief after compaction</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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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>
|
package/docs-site/index.html
CHANGED
|
@@ -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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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.28.
|
|
97
|
+
<p class="eyebrow">Piagent 1.28.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.28.
|
|
111
|
+
<a class="button" href="/whats-new">Có gì mới trong 1.28.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.28.
|
|
187
|
+
<span class="card-kicker">Bản 1.28.1</span>
|
|
188
188
|
<h3>Có gì mới</h3>
|
|
189
|
-
<p>
|
|
189
|
+
<p>Terminal công ty và Pi cá nhân không còn giẫm chân nhau (không nạp Piagent hai lần, dọn cấu hình công ty cũ, cuộc trò chuyện công ty chỉ mở bằng piagent studio); ở 1.28.0: team memory v2; ở 1.27.1: team memory chạy ổn cả khi agent đang gọi model; ở 1.27.0: team memory, agent công ty nhớ quyết định và quy tắc của team trong từng repo; ở 1.26.1: đổi tên cuộc trò chuyện được cả khi lượt đang chạy; ở 1.26.0: lệnh / và phím tắt của Terminal ngay trên dashboard, /undo hoàn tác lượt trước của agent, dev server chạy qua nhiều lượt; ở 1.25.0: thiếu môi trường thì agent xin quyền và chạy được sau khi bạn duyệt (run_on_host ngoài sandbox, start_docker mở Docker ngay trong cuộc trò chuyện); ở 1.24.0: chọn Fast ngay trên trang tạo cuộc trò chuyện công ty, nút Fast đổi màu vàng khi đang bật; ở 1.23.1: câu hỏi của agent luôn nằm cuối cuộc trò chuyện, ngay trên ô nhập, và dễ đọc hơn; ở 1.23.0: nút Fast cho cuộc trò chuyện công ty khi Harness cho phép, tool lỗi được báo về Studio (Logs → Tool lỗi), cuộc trò chuyện mới gửi được tin nhắn đầu sau khi Harness đổi; ở 1.22.1: dashboard không còn quay mãi khi project nằm trên ổ Windows nhìn từ WSL (/mnt/d…) hoặc phiên công ty không trả lời; ở 1.22.0: đính kèm được mọi file code và văn bản (.html, .css, .ts, .py, Dockerfile…); ở 1.21.1: bật Bypass được cả khi lượt đang chạy và được giữ sau khi tải lại; ở 1.21.0: câu hỏi và yêu cầu duyệt hiện từng cái một (main agent trước), thông báo góc phải khi cuộc trò chuyện khác xong hay đang chờ bạn, Studio ghi lại mỗi lần compact; ở 1.20.0: cài package trong sandbox công ty không phải duyệt (npm, PyPI, Go, Maven, Gradle… qua proxy chỉ cho registry); ở 1.19.0: task công ty có checklist được làm đến hết, cuối mỗi lượt báo rõ xong, dừng giữa chừng hay lỗi, Docker trong sandbox công ty, folder chứa nhiều repo; ở 1.18.0: đổi nhánh Git trên dashboard, tự thử lại khi lỗi tạm thời, Claude Haiku 5.5; ở 1.17.0: dashboard hiện nhánh Git của project; ở 1.16.3: dashboard cập nhật xong vẫn tự kiểm tra bản mới; ở 1.16.2: Terminal nói giống dashboard: hỏi cập nhật, /bypass, lỗi và ghi chú Harness bằng tiếng Việt; ở 1.16.1: 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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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>
|
package/docs-site/mcp-auth.html
CHANGED
|
@@ -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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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>
|
package/docs-site/mcp.html
CHANGED
|
@@ -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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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>
|
package/docs-site/profiles.html
CHANGED
|
@@ -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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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>
|
package/docs-site/runtime.html
CHANGED
|
@@ -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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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>
|
package/docs-site/scope.html
CHANGED
|
@@ -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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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>
|
package/docs-site/security.html
CHANGED
|
@@ -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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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>
|
package/docs-site/team.html
CHANGED
|
@@ -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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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>
|
package/docs-site/whats-new.html
CHANGED
|
@@ -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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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,12 @@
|
|
|
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.28.1 · 2026-10-18</p>
|
|
109
|
+
<h2 id="v1-28-1">Terminal công ty và Pi cá nhân không còn giẫm chân nhau</h2>
|
|
110
|
+
<p class="section-lead">Pi cá nhân không còn chết khi Piagent bị nạp hai lần (extension trỏ vào một bản Piagent khác): <span class="inline-code">piagent-update</span> và installer tự gỡ (có backup), <span class="inline-code">piagent-doctor</span> báo lỗi. Các mục công ty cũ của Agent Watch trong Pi cá nhân (provider <span class="inline-code">agent_watch_*</span>, model mặc định trỏ vào đó) được dọn khi máy đã dùng binding công ty. Pi cá nhân không tiếp tục cuộc trò chuyện công ty nữa và chỉ cách mở bằng <span class="inline-code">piagent studio</span>; Terminal công ty cũng hướng dẫn mở lại đúng cách, trả lời <span class="inline-code">/help</span> tại chỗ (không gửi model), và dừng hẳn khi bị dừng từ bên ngoài.</p>
|
|
111
|
+
</section>
|
|
112
|
+
|
|
107
113
|
<section class="section">
|
|
108
114
|
<p class="section-kicker">v1.28.0 · 2026-10-17</p>
|
|
109
115
|
<h2 id="v1-28-0">Team memory v2: ghi mỗi lượt đúng một lần, tóm tắt lại sau compaction</h2>
|
package/docs-site/windows.html
CHANGED
|
@@ -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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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>
|
package/docs-site/workflows.html
CHANGED
|
@@ -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.28.
|
|
33
|
+
<span class="pill"><span class="pill-dot"></span>v1.28.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":
|
|
260
|
-
"sha256": "
|
|
259
|
+
"fileCount": 553,
|
|
260
|
+
"sha256": "d948a7a9e0266c7f0cbd453310dd5c7498e1a664620b4696b8f845ebdea5e312"
|
|
261
261
|
}
|
|
262
262
|
],
|
|
263
263
|
"custodianComparisonRules": {
|
package/package.json
CHANGED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
// A company conversation (Agent Watch's ManagedSessions store, or one that
|
|
2
|
+
// carries its run entries) belongs to `piagent studio`. Opened in personal Pi,
|
|
3
|
+
// for example through Pi's "To resume this session: pi --session-dir …", it
|
|
4
|
+
// would go on with the member's personal models, keys, extensions and
|
|
5
|
+
// settings, outside the team's Harness; personal Pi refuses it instead.
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
8
|
+
|
|
9
|
+
const COMPANY_PROVIDER = "agent_watch_managed";
|
|
10
|
+
const STORE = "/AgentWatch/ManagedSessions/";
|
|
11
|
+
|
|
12
|
+
export function isCompanySession(ctx: Pick<ExtensionContext, "sessionManager">): boolean {
|
|
13
|
+
const file = String(ctx.sessionManager?.getSessionFile?.() ?? "").split(path.sep).join("/");
|
|
14
|
+
if (file.includes(STORE)) return true;
|
|
15
|
+
try {
|
|
16
|
+
return ctx.sessionManager.getEntries().some((entry: any) => typeof entry?.customType === "string" && entry.customType.startsWith("agent-watch-run"));
|
|
17
|
+
} catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const quoted = (value: string) => /^[\w./~:-]+$/.test(value) ? value : `'${value.replaceAll("'", "'\\''")}'`;
|
|
23
|
+
export function companySessionNotice(cwd: string): string {
|
|
24
|
+
return `Đây là cuộc trò chuyện công ty: mở bằng \`piagent studio --project ${quoted(cwd)}\` rồi gõ /resume. `
|
|
25
|
+
+ "Pi cá nhân không tiếp tục nó, vì sẽ chạy bằng model, key và cấu hình cá nhân thay vì Harness của team.";
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function registerCompanySessionGuard(pi: ExtensionAPI) {
|
|
29
|
+
pi.on("input", (_event, ctx) => {
|
|
30
|
+
if (ctx.model?.provider === COMPANY_PROVIDER || !isCompanySession(ctx)) return { action: "continue" };
|
|
31
|
+
const notice = companySessionNotice(ctx.cwd);
|
|
32
|
+
if (ctx.hasUI) ctx.ui.notify(notice, "error");
|
|
33
|
+
else { process.stderr.write(`${notice}\n`); process.exitCode = 1; }
|
|
34
|
+
return { action: "handled" };
|
|
35
|
+
});
|
|
36
|
+
}
|
|
@@ -24,6 +24,7 @@ import { extractShellWritePathCandidates } from "./shell-write-targets.js";
|
|
|
24
24
|
import { isProjectMutatingShellCommand } from "./readonly-inline-inspection.ts";
|
|
25
25
|
import { commandMatchesVerifyPlan, createBashResultLedger, findMatchingObservedBashResult, readObservedBashResults } from "./runtime-evidence.js";
|
|
26
26
|
import { findPackageRoot, findPlatformRoot, readJsonFile } from "./guard-io.js";
|
|
27
|
+
import { registerCompanySessionGuard } from "./company-session-guard.ts";
|
|
27
28
|
import {
|
|
28
29
|
extractDocument,
|
|
29
30
|
resolveDocumentPath,
|
|
@@ -3459,6 +3460,7 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
3459
3460
|
const modelSelectionProvenance = new ModelSelectionProvenanceTracker();
|
|
3460
3461
|
const serviceTierRuntime = new ServiceTierRuntime({ environmentValue: process.env.PIAGENT_FAST_MODE });
|
|
3461
3462
|
const trajectoryRuntime = new TrajectoryRuntime();
|
|
3463
|
+
registerCompanySessionGuard(pi);
|
|
3462
3464
|
|
|
3463
3465
|
pi.on("model_select", (event, ctx) => {
|
|
3464
3466
|
modelSelectionProvenance.observeModelSelection(ctx.sessionManager.getSessionId(), event.source);
|
|
@@ -15,6 +15,12 @@ import { headlineText, outcomeText, processItems } from '../packages/piagent-web
|
|
|
15
15
|
import { turnEndCopy, turnEndOf } from '../packages/piagent-webui/shared/turn-end.ts';
|
|
16
16
|
|
|
17
17
|
const LOCALE = 'vi';
|
|
18
|
+
export const HELP_TEXT = [
|
|
19
|
+
'Cuộc trò chuyện công ty: /undo hoàn tác file lượt trước đã sửa · /bypass on|off|status quyền lệnh cần internet · /fast on|off|status (khi Harness cho phép) · /skill:<tên> hoặc /<lệnh> của bạn và của project.',
|
|
20
|
+
'Pi: /session thông tin cuộc trò chuyện · /resume mở cuộc trò chuyện công ty khác · /new cuộc mới · /compact nén ngữ cảnh · /tree, /fork nhánh · /name đặt tên · /copy, /export · /hotkeys toàn bộ phím tắt · /quit thoát.',
|
|
21
|
+
'Phím: ! <lệnh> chạy shell · Esc dừng lượt đang chạy · Ctrl+C xoá ô nhập, hai lần để thoát · Ctrl+O xem thêm.',
|
|
22
|
+
'Mở lại sau: piagent studio --project <thư mục>, rồi /resume. Đừng mở cuộc trò chuyện công ty bằng pi cá nhân.',
|
|
23
|
+
].join('\n');
|
|
18
24
|
const PERMISSION_STATUS = 'agent-watch-permission';
|
|
19
25
|
const ASK = 'Hỏi trước (mặc định)', BYPASS = 'Bypass: chỉ hỏi việc bắt buộc';
|
|
20
26
|
const PERMISSION_TEXT = {
|
|
@@ -117,6 +123,12 @@ export function companyTerminalExtension({ managed, packageRoot, sdkRoot, bindin
|
|
|
117
123
|
: 'Fast đang tắt: các lượt chạy tốc độ thường.', 'info');
|
|
118
124
|
} });
|
|
119
125
|
|
|
126
|
+
// /help is answered here, as on the dashboard: no model request (Pi has no
|
|
127
|
+
// /help of its own, so the text would otherwise go to the agent).
|
|
128
|
+
pi.registerCommand('help', {
|
|
129
|
+
description: 'Lệnh và phím tắt của Terminal công ty (không gửi model)',
|
|
130
|
+
handler: async (_args, ctx) => ctx.ui.notify(HELP_TEXT, 'info') });
|
|
131
|
+
|
|
120
132
|
// The Harness's notes carry English for the agent; the member reads them in Vietnamese.
|
|
121
133
|
pi.registerMessageRenderer('agent-watch-process', (message, _options, theme) => {
|
|
122
134
|
const lines = processLines(message.details);
|
|
@@ -781,6 +781,17 @@ if [[ "$WITH_HERDR" == true ]]; then
|
|
|
781
781
|
fi
|
|
782
782
|
fi
|
|
783
783
|
|
|
784
|
+
# Personal Pi must not load Piagent twice (an extension path into another
|
|
785
|
+
# Piagent copy beside the package) or keep old Agent Watch company providers:
|
|
786
|
+
# Pi refuses to start, or personal Pi reaches Studio outside the Harness.
|
|
787
|
+
echo
|
|
788
|
+
echo "Personal Pi configuration:"
|
|
789
|
+
if [[ "$DRY_RUN" == true ]]; then
|
|
790
|
+
print_cmd node "$PLATFORM_ROOT/scripts/personal-pi-config.mjs" repair
|
|
791
|
+
else
|
|
792
|
+
node "$PLATFORM_ROOT/scripts/personal-pi-config.mjs" repair || echo "WARN: could not check the personal Pi configuration; run: node \"$PLATFORM_ROOT/scripts/personal-pi-config.mjs\" check" >&2
|
|
793
|
+
fi
|
|
794
|
+
|
|
784
795
|
echo
|
|
785
796
|
echo "Installed packages:"
|
|
786
797
|
if [[ "$DRY_RUN" == true ]]; then
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// What in the member's personal Pi configuration (~/.pi/agent) conflicts with
|
|
3
|
+
// Piagent, and the repair. Personal Pi loads Piagent as a Pi package; an
|
|
4
|
+
// extension path that points into another Piagent copy registers the same
|
|
5
|
+
// tools twice and Pi refuses to start ("Tool … conflicts with …"). Older Agent
|
|
6
|
+
// Watch releases also wrote company providers (agent_watch_*, a direct key
|
|
7
|
+
// read from Agent Watch) and a company default model into personal Pi; with a
|
|
8
|
+
// managed binding (agent-watch-managed.json) the company runs only through
|
|
9
|
+
// `piagent studio`, so those entries are leftovers that send personal Pi to
|
|
10
|
+
// Studio outside the team's Harness, or fail.
|
|
11
|
+
//
|
|
12
|
+
// personal-pi-config.mjs check [--agent-dir <dir>] [--json] exit 1 when something conflicts
|
|
13
|
+
// personal-pi-config.mjs repair [--agent-dir <dir>] backs up, then removes what conflicts
|
|
14
|
+
import fs from "node:fs";
|
|
15
|
+
import os from "node:os";
|
|
16
|
+
import path from "node:path";
|
|
17
|
+
import { fileURLToPath } from "node:url";
|
|
18
|
+
|
|
19
|
+
const COMPANY_PROVIDER = /^agent_watch_/;
|
|
20
|
+
const SESSION_HEADER_EXTENSION = "agentwatch-studio-session.mjs";
|
|
21
|
+
|
|
22
|
+
const readJson = (file) => { try { return JSON.parse(fs.readFileSync(file, "utf8")); } catch { return null; } };
|
|
23
|
+
const real = (file) => { try { return fs.realpathSync(file); } catch { return null; } };
|
|
24
|
+
|
|
25
|
+
// The Piagent package a path belongs to (its root), or null.
|
|
26
|
+
export function piagentRootOf(file) {
|
|
27
|
+
let dir = real(file);
|
|
28
|
+
if (!dir) return null;
|
|
29
|
+
if (!fs.statSync(dir).isDirectory()) dir = path.dirname(dir);
|
|
30
|
+
for (; dir !== path.dirname(dir); dir = path.dirname(dir)) {
|
|
31
|
+
const manifest = readJson(path.join(dir, "package.json"));
|
|
32
|
+
if (manifest?.name === "@piagent/platform") return dir;
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const isPiagentSource = (source) => /^(git:github\.com\/Vt-mmm\/piagent|https:\/\/github\.com\/Vt-mmm\/piagent|npm:@piagent\/platform)(@|$)/.test(String(source));
|
|
38
|
+
|
|
39
|
+
// The installed Pi package's version (git:… sources live under <agentDir>/git/…).
|
|
40
|
+
export function packageVersion(agentDir, source) {
|
|
41
|
+
const match = /^git:([^@]+)/.exec(String(source));
|
|
42
|
+
if (match) return readJson(path.join(agentDir, "git", match[1], "package.json"))?.version ?? null;
|
|
43
|
+
const npm = /^npm:(@piagent\/platform)/.exec(String(source));
|
|
44
|
+
if (npm) return readJson(path.join(agentDir, "npm", "node_modules", npm[1], "package.json"))?.version ?? null;
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function inspect(agentDir) {
|
|
49
|
+
const settingsFile = path.join(agentDir, "settings.json"), modelsFile = path.join(agentDir, "models.json");
|
|
50
|
+
const settings = readJson(settingsFile) ?? {}, models = readJson(modelsFile) ?? {};
|
|
51
|
+
const managed = fs.existsSync(path.join(agentDir, "agent-watch-managed.json"));
|
|
52
|
+
const packages = Array.isArray(settings.packages) ? settings.packages : [];
|
|
53
|
+
const piagentPackages = packages.filter(isPiagentSource);
|
|
54
|
+
const extensions = Array.isArray(settings.extensions) ? settings.extensions : [];
|
|
55
|
+
const findings = [];
|
|
56
|
+
|
|
57
|
+
// Extensions inside a Piagent copy load beside the Pi package: duplicate tools.
|
|
58
|
+
const duplicate = extensions.filter((entry) => piagentRootOf(path.resolve(agentDir, String(entry))) && piagentPackages.length);
|
|
59
|
+
if (duplicate.length) findings.push({ kind: "duplicate-extensions", file: settingsFile, entries: duplicate,
|
|
60
|
+
text: `${duplicate.length} extension(s) point into another Piagent copy while the Piagent Pi package is installed: Pi refuses to start (tools registered twice).` });
|
|
61
|
+
if (piagentPackages.length > 1) findings.push({ kind: "duplicate-packages", file: settingsFile, entries: piagentPackages,
|
|
62
|
+
text: `${piagentPackages.length} Piagent Pi packages are registered; keep one.` });
|
|
63
|
+
|
|
64
|
+
if (managed) {
|
|
65
|
+
const providers = Object.keys(models.providers ?? {}).filter((name) => COMPANY_PROVIDER.test(name));
|
|
66
|
+
if (providers.length) findings.push({ kind: "company-providers", file: modelsFile, entries: providers,
|
|
67
|
+
text: `Old Agent Watch company providers (${providers.join(", ")}) are in personal Pi; company work runs only through \`piagent studio\`.` });
|
|
68
|
+
const defaults = [];
|
|
69
|
+
if (COMPANY_PROVIDER.test(String(settings.defaultProvider ?? ""))) defaults.push(`defaultProvider=${settings.defaultProvider}`);
|
|
70
|
+
for (const entry of Array.isArray(settings.enabledModels) ? settings.enabledModels : []) if (COMPANY_PROVIDER.test(String(entry))) defaults.push(`enabledModels:${entry}`);
|
|
71
|
+
if (defaults.length) findings.push({ kind: "company-defaults", file: settingsFile, entries: defaults,
|
|
72
|
+
text: "Personal Pi's default model or model list still names an old company provider." });
|
|
73
|
+
const header = extensions.filter((entry) => path.basename(String(entry)) === SESSION_HEADER_EXTENSION);
|
|
74
|
+
if (header.length) findings.push({ kind: "company-extension", file: settingsFile, entries: header,
|
|
75
|
+
text: "The old Agent Watch session-header extension is still loaded in personal Pi." });
|
|
76
|
+
}
|
|
77
|
+
return { agentDir, managed, findings, packages: piagentPackages.map((source) => ({ source, version: packageVersion(agentDir, source) })) };
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function backup(file, stamp) {
|
|
81
|
+
if (!fs.existsSync(file)) return null;
|
|
82
|
+
const copy = `${file}.before-piagent-repair-${stamp}`;
|
|
83
|
+
fs.copyFileSync(file, copy);
|
|
84
|
+
fs.chmodSync(copy, 0o600);
|
|
85
|
+
return copy;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function writeJson(file, value) {
|
|
89
|
+
const tmp = `${file}.${process.pid}.tmp`;
|
|
90
|
+
fs.writeFileSync(tmp, `${JSON.stringify(value, null, 2)}\n`, { mode: 0o600 });
|
|
91
|
+
fs.renameSync(tmp, file);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Removes what inspect() found (duplicate packages are left to the installer,
|
|
95
|
+
// which knows the one to keep). Every changed file is backed up first.
|
|
96
|
+
export function repair(agentDir, now = new Date()) {
|
|
97
|
+
const report = inspect(agentDir);
|
|
98
|
+
const kinds = new Set(report.findings.map((finding) => finding.kind));
|
|
99
|
+
const stamp = now.toISOString().replace(/[:.]/g, "-");
|
|
100
|
+
const changed = [], backups = [];
|
|
101
|
+
const settingsFile = path.join(agentDir, "settings.json"), modelsFile = path.join(agentDir, "models.json");
|
|
102
|
+
if (kinds.has("duplicate-extensions") || kinds.has("company-defaults") || kinds.has("company-extension")) {
|
|
103
|
+
const settings = readJson(settingsFile);
|
|
104
|
+
const drop = new Set(report.findings.filter((f) => f.kind === "duplicate-extensions" || f.kind === "company-extension").flatMap((f) => f.entries));
|
|
105
|
+
if (Array.isArray(settings.extensions)) settings.extensions = settings.extensions.filter((entry) => !drop.has(entry));
|
|
106
|
+
if (Array.isArray(settings.extensions) && !settings.extensions.length) delete settings.extensions;
|
|
107
|
+
if (COMPANY_PROVIDER.test(String(settings.defaultProvider ?? ""))) { delete settings.defaultProvider; delete settings.defaultModel; }
|
|
108
|
+
if (Array.isArray(settings.enabledModels)) settings.enabledModels = settings.enabledModels.filter((entry) => !COMPANY_PROVIDER.test(String(entry)));
|
|
109
|
+
backups.push(backup(settingsFile, stamp)); writeJson(settingsFile, settings); changed.push(settingsFile);
|
|
110
|
+
}
|
|
111
|
+
if (kinds.has("company-providers")) {
|
|
112
|
+
const models = readJson(modelsFile);
|
|
113
|
+
for (const name of Object.keys(models.providers ?? {})) if (COMPANY_PROVIDER.test(name)) delete models.providers[name];
|
|
114
|
+
backups.push(backup(modelsFile, stamp)); writeJson(modelsFile, models); changed.push(modelsFile);
|
|
115
|
+
}
|
|
116
|
+
return { ...report, changed, backups: backups.filter(Boolean), after: inspect(agentDir) };
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const invoked = process.argv[1] && real(process.argv[1]) === real(fileURLToPath(import.meta.url));
|
|
120
|
+
if (invoked) {
|
|
121
|
+
const args = process.argv.slice(2), command = args[0];
|
|
122
|
+
const at = args.indexOf("--agent-dir");
|
|
123
|
+
const agentDir = at >= 0 ? path.resolve(args[at + 1]) : (process.env.PI_CODING_AGENT_DIR || path.join(os.homedir(), ".pi", "agent"));
|
|
124
|
+
if (!["check", "repair"].includes(command)) { console.error("Usage: personal-pi-config.mjs check|repair [--agent-dir <dir>] [--json]"); process.exit(2); }
|
|
125
|
+
const result = command === "repair" ? repair(agentDir) : inspect(agentDir);
|
|
126
|
+
if (args.includes("--json")) console.log(JSON.stringify(result, null, 2));
|
|
127
|
+
else if (command === "repair") {
|
|
128
|
+
for (const finding of result.findings) console.log(`fixed: ${finding.text}`);
|
|
129
|
+
for (const file of result.backups) console.log(`backup: ${file}`);
|
|
130
|
+
if (!result.findings.length) console.log("personal Pi configuration: nothing to repair");
|
|
131
|
+
} else {
|
|
132
|
+
for (const finding of result.findings) console.log(`WARN: ${finding.text}`);
|
|
133
|
+
if (result.findings.length) console.log("Fix: piagent-update (or node scripts/personal-pi-config.mjs repair)");
|
|
134
|
+
else console.log("PASS: personal Pi configuration has no Piagent conflicts");
|
|
135
|
+
}
|
|
136
|
+
process.exit(command === "check" && result.findings.length ? 1 : 0);
|
|
137
|
+
}
|
package/scripts/piagent-cli.mjs
CHANGED
|
@@ -158,8 +158,16 @@ child.once("error", (error) => {
|
|
|
158
158
|
process.exit(1);
|
|
159
159
|
});
|
|
160
160
|
|
|
161
|
+
// A command stopped from outside (a script, an editor, a timeout) stops its
|
|
162
|
+
// child too, rather than leaving a company run going in the background. A
|
|
163
|
+
// terminal's Ctrl+C already reaches the whole process group: the launcher just
|
|
164
|
+
// stays until the child has finished.
|
|
165
|
+
for (const signal of ["SIGTERM", "SIGHUP"]) process.on(signal, () => { try { child.kill(signal); } catch { /* already gone */ } });
|
|
166
|
+
process.on("SIGINT", () => {});
|
|
167
|
+
|
|
161
168
|
child.once("exit", (code, signal) => {
|
|
162
169
|
if (signal) {
|
|
170
|
+
process.removeAllListeners(signal);
|
|
163
171
|
process.kill(process.pid, signal);
|
|
164
172
|
return;
|
|
165
173
|
}
|
|
@@ -162,6 +162,10 @@ try {
|
|
|
162
162
|
// (updating Pi breaks the Agent Watch import), no package-update, catalog or
|
|
163
163
|
// install-telemetry calls. Search tools were provisioned above.
|
|
164
164
|
process.env.PI_OFFLINE = '1'; process.env.PI_SKIP_VERSION_CHECK = '1';
|
|
165
|
+
// Pi's exit line names `pi --session-dir …`, which would open this company
|
|
166
|
+
// conversation in personal Pi; name the company Terminal instead.
|
|
167
|
+
const write = process.stdout.write.bind(process.stdout), project = /^[\w./~:-]+$/.test(cwd) ? cwd : `'${cwd.replaceAll("'", "'\\''")}'`;
|
|
168
|
+
process.stdout.write = (chunk, ...rest) => write(typeof chunk === 'string' && chunk.includes('To resume this session:') ? `Mở lại cuộc trò chuyện này: piagent studio --project ${project}, rồi /resume\n` : chunk, ...rest);
|
|
165
169
|
await new api.InteractiveMode(host, { verbose: false }).run();
|
|
166
170
|
}
|
|
167
171
|
}
|
package/scripts/team-doctor.sh
CHANGED
|
@@ -70,6 +70,10 @@ const warnings = [];
|
|
|
70
70
|
const { piagentInstallations } = await import(pathToFileURL(path.join(platformRoot, "scripts/piagent-installations.mjs")).href);
|
|
71
71
|
const installations = piagentInstallations();
|
|
72
72
|
if(installations.length>1) warnings.push("Multiple Piagent installations detected. Use the pinned Watch launcher; other PATHs may run an older build: "+installations.map(i=>`${i.version} [${i.fingerprint}] ${i.root}`).join("; "));
|
|
73
|
+
// Personal Pi loading Piagent twice does not start; old company providers send it to Studio outside the Harness.
|
|
74
|
+
const { inspect: inspectPersonalPi } = await import(pathToFileURL(path.join(platformRoot, "scripts/personal-pi-config.mjs")).href);
|
|
75
|
+
for (const finding of inspectPersonalPi(process.env.PI_CODING_AGENT_DIR || path.join(process.env.HOME || "", ".pi", "agent")).findings)
|
|
76
|
+
(finding.kind === "duplicate-extensions" ? errors : warnings).push(`personal Pi: ${finding.text} Fix: piagent-update`);
|
|
73
77
|
const { verifyCapabilityLock } = await import(pathToFileURL(path.join(platformRoot, "packages", "piagent-core", "capabilities", "capability-core.js")).href);
|
|
74
78
|
|
|
75
79
|
function exists(rel) {
|
|
@@ -21,6 +21,7 @@ import os from "node:os";
|
|
|
21
21
|
import path from "node:path";
|
|
22
22
|
import { spawnSync } from "node:child_process";
|
|
23
23
|
import { fileURLToPath } from "node:url";
|
|
24
|
+
import { inspect as inspectPersonalPi } from "./personal-pi-config.mjs";
|
|
24
25
|
|
|
25
26
|
const HELPER_PACKAGE = "@piagent/platform";
|
|
26
27
|
const HOST_PACKAGE = "@earendil-works/pi-coding-agent";
|
|
@@ -430,13 +431,19 @@ function main() {
|
|
|
430
431
|
console.log("Pi Agent Platform update");
|
|
431
432
|
console.log(` helper: ${currentHelper} -> ${targetHelper}${helperNeedsChange ? "" : " (already current)"}`);
|
|
432
433
|
console.log(` host: ${currentHost ?? "not installed"} -> ${targetHost}${hostNeedsChange ? "" : " (already current)"}`);
|
|
433
|
-
|
|
434
|
+
// The Pi package can lag the helper (installed from an older tag), and
|
|
435
|
+
// personal Pi can hold conflicting Piagent or old company entries.
|
|
436
|
+
const personal = inspectPersonalPi(process.env.PI_CODING_AGENT_DIR || path.join(os.homedir(), ".pi", "agent"));
|
|
437
|
+
const installedPackages = personal.packages.map((item) => item.version ?? "unknown");
|
|
438
|
+
const packageNeedsChange = options.package && (options.force || installedPackages.length !== 1 || installedPackages[0] !== targetHelper);
|
|
439
|
+
console.log(` package: ${installedPackages.join(", ") || "not installed"} -> v${targetHelper}${options.package ? packageNeedsChange ? " (reinstalled as a resolved commit)" : " (already current)" : " (skipped)"}`);
|
|
440
|
+
for (const finding of personal.findings) console.log(` personal Pi: ${finding.text}`);
|
|
434
441
|
if (options.project) {
|
|
435
442
|
console.log(` project: ${path.resolve(options.project)} (${options.migrate ? "migrate + doctor" : "doctor only"})`);
|
|
436
443
|
}
|
|
437
444
|
|
|
438
445
|
if (options.check) {
|
|
439
|
-
const pending = [helperNeedsChange && "helper", hostNeedsChange && "host"].filter(Boolean);
|
|
446
|
+
const pending = [helperNeedsChange && "helper", hostNeedsChange && "host", packageNeedsChange && "package", personal.findings.length && "personal Pi configuration"].filter(Boolean);
|
|
440
447
|
console.log(pending.length ? `\nUpdate available: ${pending.join(", ")}.` : "\nEverything is on the target release.");
|
|
441
448
|
return;
|
|
442
449
|
}
|