@piagent/platform 1.44.4 → 1.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/README.md +5 -3
- package/README.vi.md +5 -3
- 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 +2 -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/assets/search-en.json +1 -1
- package/docs-site/assets/search-vi.json +1 -1
- package/docs-site/benchmark.html +1 -1
- package/docs-site/commands.html +1 -1
- 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 +15 -15
- 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/update.html +3 -3
- package/docs-site/en/whats-new.html +58 -35
- package/docs-site/en/windows.html +1 -1
- package/docs-site/en/workflows.html +1 -1
- package/docs-site/index.html +15 -15
- 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/releases.json +75 -0
- 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/update.html +3 -3
- package/docs-site/whats-new.html +58 -35
- 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/benchmark/benchmark-bootstrap.js +3 -1
- package/packages/piagent-core/extensions/agent-home.d.ts +4 -0
- package/packages/piagent-core/extensions/agent-home.js +52 -0
- package/packages/piagent-core/extensions/piagent-guard.ts +5 -1
- package/packages/piagent-core/extensions/working-tree-snapshot-worker.mjs +9 -0
- package/packages/piagent-core/extensions/workspace-evidence-roots.js +28 -2
- package/packages/piagent-core/mcp/mcp-config-layers.js +4 -1
- package/packages/piagent-core/package.json +1 -1
- package/packages/piagent-core/runtime/hooks/input-hook.ts +17 -3
- package/packages/piagent-core/runtime/input/chat-images.ts +66 -10
- package/packages/piagent-core/runtime/input/file-arguments.ts +102 -0
- package/packages/piagent-core/runtime/inspection/webui-snapshot.ts +2 -6
- package/packages/piagent-core/runtime/inspection/working-tree-off-thread.ts +52 -0
- package/packages/piagent-core/runtime/solver/runtime-features.ts +15 -3
- package/packages/piagent-webui/extension/piagent-webui.ts +2 -0
- package/packages/piagent-webui/gateway/gateway-service.ts +4 -1
- package/packages/piagent-webui/gateway/pi-host.ts +2 -2
- package/packages/piagent-webui/ownership/profile-state.ts +10 -1
- package/packages/piagent-webui/server/benchmark-release-monitor.ts +2 -1
- package/scripts/benchmark-runner-support.mjs +2 -1
- package/scripts/dashboard-update-job.mjs +4 -2
- package/scripts/install-global.sh +113 -5
- package/scripts/model-scope-prune.mjs +2 -1
- package/scripts/personal-pi-config.mjs +2 -1
- package/scripts/personal-pi-restore.mjs +184 -0
- package/scripts/pi-usage-history.mjs +2 -1
- package/scripts/piagent-cli.mjs +49 -9
- package/scripts/piagent-dashboard.mjs +5 -3
- package/scripts/setup.sh +2 -6
- package/scripts/team-doctor.sh +11 -5
- package/scripts/uninstall-global.sh +17 -2
- package/scripts/update-global.mjs +5 -2
package/docs-site/releases.json
CHANGED
|
@@ -1,4 +1,79 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "1.46.0",
|
|
4
|
+
"date": "2026-10-28",
|
|
5
|
+
"status": "stable",
|
|
6
|
+
"title": {
|
|
7
|
+
"en": "Piagent runs from its own Pi home and your own pi stays stock",
|
|
8
|
+
"vi": "Piagent chạy trong Pi home riêng, pi của bạn giữ nguyên bản gốc"
|
|
9
|
+
},
|
|
10
|
+
"summary": {
|
|
11
|
+
"en": "Piagent installs into ~/.piagent/agent and opens with `piagent`. Plain `pi` no longer loads Piagent, its add-ons, model list or footer panel.",
|
|
12
|
+
"vi": "Piagent cài vào ~/.piagent/agent và mở bằng `piagent`. `pi` thường không còn nạp Piagent, add-on, danh sách model hay panel footer."
|
|
13
|
+
},
|
|
14
|
+
"items": [
|
|
15
|
+
{
|
|
16
|
+
"kind": "breaking",
|
|
17
|
+
"en": "Piagent installs into its own Pi home, ~/.piagent/agent, and opens with `piagent`. Plain `pi` in ~/.pi/agent stays stock.",
|
|
18
|
+
"vi": "Piagent cài vào Pi home riêng ~/.piagent/agent và mở bằng `piagent`. `pi` thường trong ~/.pi/agent giữ nguyên bản gốc."
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"kind": "new",
|
|
22
|
+
"en": "A first install in a terminal asks which add-ons to install and whether to reuse your pi login; flags answer up front.",
|
|
23
|
+
"vi": "Lần cài đầu trong terminal hỏi cài add-on nào và có dùng lại login của pi không; cờ dòng lệnh trả lời trước được."
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"kind": "new",
|
|
27
|
+
"en": "`piagent restore-pi --apply` moves an older install out of ~/.pi/agent with backups; the installer does it on update.",
|
|
28
|
+
"vi": "`piagent restore-pi --apply` dời bản cài cũ khỏi ~/.pi/agent, có sao lưu; installer tự làm khi cập nhật."
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
"kind": "fixed",
|
|
32
|
+
"en": "Pi's built-in mcp is turned off in Piagent's home when pi-mcp-adapter is installed, so /mcp no longer clashes.",
|
|
33
|
+
"vi": "Khi cài pi-mcp-adapter, Piagent tắt mcp có sẵn của Pi trong home của mình nên /mcp không còn xung đột."
|
|
34
|
+
}
|
|
35
|
+
],
|
|
36
|
+
"requires": {
|
|
37
|
+
"en": "Agent Watch 0.15.16 to list Piagent's personal sessions",
|
|
38
|
+
"vi": "Agent Watch 0.15.16 để thấy session cá nhân của Piagent"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"version": "1.45.0",
|
|
43
|
+
"date": "2026-10-28",
|
|
44
|
+
"status": "stable",
|
|
45
|
+
"title": {
|
|
46
|
+
"en": "Files and images in a prompt follow the read policy, and the terminal stays responsive",
|
|
47
|
+
"vi": "File và ảnh trong prompt theo đúng quyền đọc, terminal không còn đứng hình"
|
|
48
|
+
},
|
|
49
|
+
"summary": {
|
|
50
|
+
"en": "pi @file can no longer send a protected file to the model, images attach the way you add them, and a prompt in a folder of repositories no longer freezes the terminal.",
|
|
51
|
+
"vi": "pi @file không còn gửi file được bảo vệ cho model, ảnh được đính kèm theo mọi cách thêm vào, và prompt trong thư mục nhiều repo không còn làm terminal đứng hình."
|
|
52
|
+
},
|
|
53
|
+
"items": [
|
|
54
|
+
{
|
|
55
|
+
"kind": "security",
|
|
56
|
+
"en": "pi @file arguments follow the read policy: a protected file (.env) or one outside the project reaches the model as a withheld note, and its image is dropped.",
|
|
57
|
+
"vi": "Tham số pi @file theo quyền đọc: file được bảo vệ (.env) hoặc ngoài project chỉ tới model dưới dạng ghi chú bị giữ lại, ảnh của nó bị bỏ."
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
"kind": "new",
|
|
61
|
+
"en": "Images attach when named with @path or @\"path\", pasted with Ctrl+V, or dropped on the terminal; a skipped image says why and how to grant its folder.",
|
|
62
|
+
"vi": "Ảnh được đính kèm khi gọi bằng @path hoặc @\"path\", dán bằng Ctrl+V hay kéo thả vào terminal; ảnh bị bỏ qua nói rõ lý do và cách cấp quyền thư mục."
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"kind": "fixed",
|
|
66
|
+
"en": "An image passed as pi @image.png is attached once, not twice.",
|
|
67
|
+
"vi": "Ảnh truyền bằng pi @image.png chỉ được đính kèm một lần, không còn hai lần."
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
"kind": "improved",
|
|
71
|
+
"en": "In a folder of repositories a prompt no longer freezes the terminal for seconds: the change check asks Git and the inspector scans in the background.",
|
|
72
|
+
"vi": "Trong thư mục nhiều repo, prompt không còn làm terminal đứng hình vài giây: kiểm tra thay đổi hỏi Git, inspector quét ở nền."
|
|
73
|
+
}
|
|
74
|
+
],
|
|
75
|
+
"requires": null
|
|
76
|
+
},
|
|
2
77
|
{
|
|
3
78
|
"version": "1.44.4",
|
|
4
79
|
"date": "2026-10-28",
|
package/docs-site/runtime.html
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
|
|
38
38
|
<span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
|
|
39
39
|
</a>
|
|
40
|
-
<a class="version-badge" href="/whats-new" data-docs-version="v1.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.0" title="v1.46.0 docs · VI"><span class="dot"></span>v1.46.0</a>
|
|
41
41
|
<nav class="top-nav" aria-label="Tài liệu">
|
|
42
42
|
<a href="/quickstart">Tài liệu</a>
|
|
43
43
|
<a href="/whats-new">Changelog</a>
|
package/docs-site/scope.html
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
|
|
38
38
|
<span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
|
|
39
39
|
</a>
|
|
40
|
-
<a class="version-badge" href="/whats-new" data-docs-version="v1.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.0" title="v1.46.0 docs · VI"><span class="dot"></span>v1.46.0</a>
|
|
41
41
|
<nav class="top-nav" aria-label="Tài liệu">
|
|
42
42
|
<a href="/quickstart">Tài liệu</a>
|
|
43
43
|
<a href="/whats-new">Changelog</a>
|
package/docs-site/security.html
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
|
|
38
38
|
<span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
|
|
39
39
|
</a>
|
|
40
|
-
<a class="version-badge" href="/whats-new" data-docs-version="v1.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.0" title="v1.46.0 docs · VI"><span class="dot"></span>v1.46.0</a>
|
|
41
41
|
<nav class="top-nav" aria-label="Tài liệu">
|
|
42
42
|
<a href="/quickstart">Tài liệu</a>
|
|
43
43
|
<a href="/whats-new">Changelog</a>
|
package/docs-site/team.html
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
|
|
38
38
|
<span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
|
|
39
39
|
</a>
|
|
40
|
-
<a class="version-badge" href="/whats-new" data-docs-version="v1.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.0" title="v1.46.0 docs · VI"><span class="dot"></span>v1.46.0</a>
|
|
41
41
|
<nav class="top-nav" aria-label="Tài liệu">
|
|
42
42
|
<a href="/quickstart">Tài liệu</a>
|
|
43
43
|
<a href="/whats-new">Changelog</a>
|
package/docs-site/update.html
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
|
|
38
38
|
<span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
|
|
39
39
|
</a>
|
|
40
|
-
<a class="version-badge" href="/whats-new" data-docs-version="v1.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.0" title="v1.46.0 docs · VI"><span class="dot"></span>v1.46.0</a>
|
|
41
41
|
<nav class="top-nav" aria-label="Tài liệu">
|
|
42
42
|
<a href="/quickstart">Tài liệu</a>
|
|
43
43
|
<a href="/whats-new">Changelog</a>
|
|
@@ -145,9 +145,9 @@
|
|
|
145
145
|
<h2 id="pin-cho-team">Pin một bản cho cả team</h2>
|
|
146
146
|
<p>Khi rollout cho team, cài đúng bản Pi host và đúng bản platform, rồi chạy installer ở chế độ stable. Bước <code>--dry-run</code> in ra những gì sẽ đổi.</p>
|
|
147
147
|
<div class="command-card">
|
|
148
|
-
<header><span>Cài pin theo bản</span><button class="clip-btn" data-clip="npm install -g --ignore-scripts @earendil-works/pi-coding-agent@1.3.0 npm install -g --ignore-scripts @piagent/platform@1.
|
|
148
|
+
<header><span>Cài pin theo bản</span><button class="clip-btn" data-clip="npm install -g --ignore-scripts @earendil-works/pi-coding-agent@1.3.0 npm install -g --ignore-scripts @piagent/platform@1.46.0 piagent-install --stable --dry-run piagent-install --stable">Lấy lệnh</button></header>
|
|
149
149
|
<pre><code>npm install -g --ignore-scripts @earendil-works/pi-coding-agent@1.3.0
|
|
150
|
-
npm install -g --ignore-scripts @piagent/platform@1.
|
|
150
|
+
npm install -g --ignore-scripts @piagent/platform@1.46.0
|
|
151
151
|
piagent-install --stable --dry-run
|
|
152
152
|
piagent-install --stable</code></pre>
|
|
153
153
|
</div>
|
package/docs-site/whats-new.html
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
|
|
38
38
|
<span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
|
|
39
39
|
</a>
|
|
40
|
-
<a class="version-badge" href="/whats-new" data-docs-version="v1.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.0" title="v1.46.0 docs · VI"><span class="dot"></span>v1.46.0</a>
|
|
41
41
|
<nav class="top-nav" aria-label="Tài liệu">
|
|
42
42
|
<a href="/quickstart">Tài liệu</a>
|
|
43
43
|
<a href="/whats-new" aria-current="page">Changelog</a>
|
|
@@ -108,7 +108,34 @@
|
|
|
108
108
|
<div class="release-filter" role="toolbar" aria-label="Lọc theo loại thay đổi"><button type="button" data-filter-kind="all" aria-pressed="true">Tất cả</button><button type="button" data-filter-kind="new" aria-pressed="false">Mới</button><button type="button" data-filter-kind="improved" aria-pressed="false">Cải thiện</button><button type="button" data-filter-kind="fixed" aria-pressed="false">Sửa lỗi</button><button type="button" data-filter-kind="security" aria-pressed="false">Bảo mật</button></div>
|
|
109
109
|
<section class="section releases" data-releases>
|
|
110
110
|
<h2 id="latest" class="sr-only">Mới nhất</h2>
|
|
111
|
-
<article class="release latest" id="v1-
|
|
111
|
+
<article class="release latest" id="v1-46-0" data-release>
|
|
112
|
+
<div class="release-meta"><a class="release-version" href="#v1-46-0">v1.46.0</a><time class="release-date" datetime="2026-10-28">28/10/2026</time></div>
|
|
113
|
+
<div class="release-body">
|
|
114
|
+
<h3 data-toc-skip id="v1-46-0-title">Piagent chạy trong Pi home riêng, pi của bạn giữ nguyên bản gốc</h3>
|
|
115
|
+
<p>Piagent cài vào ~/.piagent/agent và mở bằng <code>piagent</code>. <code>pi</code> thường không còn nạp Piagent, add-on, danh sách model hay panel footer.</p>
|
|
116
|
+
<ul class="release-items">
|
|
117
|
+
<li data-kind="breaking"><span class="kind kind-breaking">Thay đổi lớn</span><span>Piagent cài vào Pi home riêng ~/.piagent/agent và mở bằng <code>piagent</code>. <code>pi</code> thường trong ~/.pi/agent giữ nguyên bản gốc.</span></li>
|
|
118
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Lần cài đầu trong terminal hỏi cài add-on nào và có dùng lại login của pi không; cờ dòng lệnh trả lời trước được.</span></li>
|
|
119
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span><code>piagent restore-pi --apply</code> dời bản cài cũ khỏi ~/.pi/agent, có sao lưu; installer tự làm khi cập nhật.</span></li>
|
|
120
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Khi cài pi-mcp-adapter, Piagent tắt mcp có sẵn của Pi trong home của mình nên /mcp không còn xung đột.</span></li>
|
|
121
|
+
</ul>
|
|
122
|
+
<p class="release-requires"><strong>Cần:</strong> Agent Watch 0.15.16 để thấy session cá nhân của Piagent</p>
|
|
123
|
+
</div>
|
|
124
|
+
</article>
|
|
125
|
+
<article class="release" id="v1-45-0" data-release>
|
|
126
|
+
<div class="release-meta"><a class="release-version" href="#v1-45-0">v1.45.0</a><time class="release-date" datetime="2026-10-28">28/10/2026</time></div>
|
|
127
|
+
<div class="release-body">
|
|
128
|
+
<h3 data-toc-skip id="v1-45-0-title">File và ảnh trong prompt theo đúng quyền đọc, terminal không còn đứng hình</h3>
|
|
129
|
+
<p>pi @file không còn gửi file được bảo vệ cho model, ảnh được đính kèm theo mọi cách thêm vào, và prompt trong thư mục nhiều repo không còn làm terminal đứng hình.</p>
|
|
130
|
+
<ul class="release-items">
|
|
131
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Ảnh được đính kèm khi gọi bằng @path hoặc @"path", dán bằng Ctrl+V hay kéo thả vào terminal; ảnh bị bỏ qua nói rõ lý do và cách cấp quyền thư mục.</span></li>
|
|
132
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Trong thư mục nhiều repo, prompt không còn làm terminal đứng hình vài giây: kiểm tra thay đổi hỏi Git, inspector quét ở nền.</span></li>
|
|
133
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Ảnh truyền bằng pi @image.png chỉ được đính kèm một lần, không còn hai lần.</span></li>
|
|
134
|
+
<li data-kind="security"><span class="kind kind-security">Bảo mật</span><span>Tham số pi @file theo quyền đọc: file được bảo vệ (.env) hoặc ngoài project chỉ tới model dưới dạng ghi chú bị giữ lại, ảnh của nó bị bỏ.</span></li>
|
|
135
|
+
</ul>
|
|
136
|
+
</div>
|
|
137
|
+
</article>
|
|
138
|
+
<article class="release" id="v1-44-4" data-release>
|
|
112
139
|
<div class="release-meta"><a class="release-version" href="#v1-44-4">v1.44.4</a><time class="release-date" datetime="2026-10-28">28/10/2026</time></div>
|
|
113
140
|
<div class="release-body">
|
|
114
141
|
<h3 data-toc-skip id="v1-44-4-title">Conversation công ty trở lại trong pane Herdr</h3>
|
|
@@ -394,44 +421,40 @@
|
|
|
394
421
|
</ul>
|
|
395
422
|
</div>
|
|
396
423
|
</article>
|
|
397
|
-
<article class="release" id="v1-38-0" data-release>
|
|
398
|
-
<div class="release-meta"><a class="release-version" href="#v1-38-0">v1.38.0</a><time class="release-date" datetime="2026-10-23">23/10/2026</time></div>
|
|
399
|
-
<div class="release-body">
|
|
400
|
-
<h3 data-toc-skip id="v1-38-0-title">Piagent thành editor, Bypass không hỏi gì <span class="tag">không phát hành</span></h3>
|
|
401
|
-
<p>Dashboard có file, terminal, review inline và checkpoint, cùng chế độ Bypass không hỏi gì, cả trong cuộc trò chuyện công ty khi Harness cho phép.</p>
|
|
402
|
-
<ul class="release-items">
|
|
403
|
-
<li data-kind="breaking"><span class="kind kind-breaking">Thay đổi lớn</span><span>Cuộc trò chuyện công ty có Hỏi trước, Toàn quyền (trước đây gọi là Bypass) và Bypass, chỉ có khi Harness cho phép.</span></li>
|
|
404
|
-
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Chế độ <code>bypass</code> (<code>/permission bypass</code>, <code>piagent-auto --bypass</code>) tắt mọi bước chặn; output vẫn được che secret và <code>/undo</code> vẫn hoàn tác được.</span></li>
|
|
405
|
-
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Dashboard mở, sửa, lưu, đổi tên và xóa file của project, có Cmd/Ctrl+P, tìm kiếm và báo xung đột khi file đã đổi trên đĩa.</span></li>
|
|
406
|
-
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Terminal của project ngay trên dashboard; terminal của cuộc trò chuyện công ty chạy trong sandbox, cả trên macOS, không bao giờ chạy trên host.</span></li>
|
|
407
|
-
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Review inline từng hunk agent sửa với Giữ và Hoàn tác, và khôi phục trong Timeline có xem trước, dùng chung checkpoint với <code>/undo</code>.</span></li>
|
|
408
|
-
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Checkpoint không tạo được từng chặn mọi lần sửa; giờ thì không, và snapshot mất khoảng 0,5 s thay vì 35 s trên repo 4.000 file.</span></li>
|
|
409
|
-
</ul>
|
|
410
|
-
<p class="release-requires"><strong>Cần:</strong> Agent Studio 0.38.0 và Agent Watch 0.15.14 (Windows 0.1.17) cho mức Bypass ở chế độ công ty</p>
|
|
411
|
-
</div>
|
|
412
|
-
</article>
|
|
413
|
-
<article class="release" id="v1-37-1" data-release>
|
|
414
|
-
<div class="release-meta"><a class="release-version" href="#v1-37-1">v1.37.1</a><time class="release-date" datetime="2026-10-22">22/10/2026</time></div>
|
|
415
|
-
<div class="release-body">
|
|
416
|
-
<h3 data-toc-skip id="v1-37-1-title">Đóng run và báo cáo helper mà Studio tin được</h3>
|
|
417
|
-
<p>Lần đóng run hỏi lại chỉ được tính khi tới Studio, helper giữ câu trả lời, và yêu cầu ra ngoài chặn mọi dạng IPv6 của địa chỉ nội bộ.</p>
|
|
418
|
-
<ul class="release-items">
|
|
419
|
-
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Lần đóng run hỏi lại sau lỗi thoáng qua có thể được ghi nhận dù không tới Studio; giờ chỉ được tính khi Studio nhận được.</span></li>
|
|
420
|
-
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Helper đóng lỗi trong chốc lát từng bị coi là thất bại; giờ nó giữ câu trả lời, và báo cáo được gửi lại sau lỗi thoáng qua.</span></li>
|
|
421
|
-
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Team memory từng gộp lỗi của hai lệnh khác nhau cùng một chương trình thành một bài học; giờ khóa là cả câu lệnh.</span></li>
|
|
422
|
-
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Phản hồi skill từng trộn các skill có tên giống nhau như <code>a/b</code> và <code>a_b</code>; giờ mỗi tên skill có file riêng.</span></li>
|
|
423
|
-
<li data-kind="security"><span class="kind kind-security">Bảo mật</span><span>Tool <code>web_fetch</code> và package proxy từng cho qua một số dạng IPv6 của địa chỉ nội bộ; giờ mọi dạng như vậy đều bị chặn.</span></li>
|
|
424
|
-
<li data-kind="security"><span class="kind kind-security">Bảo mật</span><span>Khi có upstream proxy của công ty (<code>HTTPS_PROXY</code>), package proxy giờ tự kiểm tra từng đích kết nối thay vì để upstream tự xử lý.</span></li>
|
|
425
|
-
</ul>
|
|
426
|
-
<p class="release-requires"><strong>Cần:</strong> Agent Watch 0.15.11 (Windows 0.1.16)</p>
|
|
427
|
-
</div>
|
|
428
|
-
</article>
|
|
429
424
|
</section>
|
|
430
425
|
<section class="section archive">
|
|
431
426
|
<h2 id="archive">Các bản trước</h2>
|
|
432
427
|
<p class="section-lead">Bản cũ hơn, gom theo tháng. Mở một tháng để xem từng thay đổi.</p>
|
|
433
428
|
<details class="release-archive">
|
|
434
|
-
<summary><span>Tháng 10/2026</span><span class="archive-count">
|
|
429
|
+
<summary><span>Tháng 10/2026</span><span class="archive-count">57</span></summary>
|
|
430
|
+
<div class="archive-row" id="v1-38-0">
|
|
431
|
+
<div class="archive-head"><a class="release-version" href="#v1-38-0">v1.38.0</a> <span class="release-date">23/10/2026</span></div>
|
|
432
|
+
<div class="archive-body">
|
|
433
|
+
<p><strong>Piagent thành editor, Bypass không hỏi gì</strong> <span class="tag">không phát hành</span> — Dashboard có file, terminal, review inline và checkpoint, cùng chế độ Bypass không hỏi gì, cả trong cuộc trò chuyện công ty khi Harness cho phép.</p>
|
|
434
|
+
<ul class="release-items">
|
|
435
|
+
<li data-kind="breaking"><span class="kind kind-breaking">Thay đổi lớn</span><span>Cuộc trò chuyện công ty có Hỏi trước, Toàn quyền (trước đây gọi là Bypass) và Bypass, chỉ có khi Harness cho phép.</span></li>
|
|
436
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Chế độ <code>bypass</code> (<code>/permission bypass</code>, <code>piagent-auto --bypass</code>) tắt mọi bước chặn; output vẫn được che secret và <code>/undo</code> vẫn hoàn tác được.</span></li>
|
|
437
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Dashboard mở, sửa, lưu, đổi tên và xóa file của project, có Cmd/Ctrl+P, tìm kiếm và báo xung đột khi file đã đổi trên đĩa.</span></li>
|
|
438
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Terminal của project ngay trên dashboard; terminal của cuộc trò chuyện công ty chạy trong sandbox, cả trên macOS, không bao giờ chạy trên host.</span></li>
|
|
439
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Review inline từng hunk agent sửa với Giữ và Hoàn tác, và khôi phục trong Timeline có xem trước, dùng chung checkpoint với <code>/undo</code>.</span></li>
|
|
440
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Checkpoint không tạo được từng chặn mọi lần sửa; giờ thì không, và snapshot mất khoảng 0,5 s thay vì 35 s trên repo 4.000 file.</span></li>
|
|
441
|
+
</ul>
|
|
442
|
+
</div>
|
|
443
|
+
</div>
|
|
444
|
+
<div class="archive-row" id="v1-37-1">
|
|
445
|
+
<div class="archive-head"><a class="release-version" href="#v1-37-1">v1.37.1</a> <span class="release-date">22/10/2026</span></div>
|
|
446
|
+
<div class="archive-body">
|
|
447
|
+
<p><strong>Đóng run và báo cáo helper mà Studio tin được</strong> — Lần đóng run hỏi lại chỉ được tính khi tới Studio, helper giữ câu trả lời, và yêu cầu ra ngoài chặn mọi dạng IPv6 của địa chỉ nội bộ.</p>
|
|
448
|
+
<ul class="release-items">
|
|
449
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Lần đóng run hỏi lại sau lỗi thoáng qua có thể được ghi nhận dù không tới Studio; giờ chỉ được tính khi Studio nhận được.</span></li>
|
|
450
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Helper đóng lỗi trong chốc lát từng bị coi là thất bại; giờ nó giữ câu trả lời, và báo cáo được gửi lại sau lỗi thoáng qua.</span></li>
|
|
451
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Team memory từng gộp lỗi của hai lệnh khác nhau cùng một chương trình thành một bài học; giờ khóa là cả câu lệnh.</span></li>
|
|
452
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Phản hồi skill từng trộn các skill có tên giống nhau như <code>a/b</code> và <code>a_b</code>; giờ mỗi tên skill có file riêng.</span></li>
|
|
453
|
+
<li data-kind="security"><span class="kind kind-security">Bảo mật</span><span>Tool <code>web_fetch</code> và package proxy từng cho qua một số dạng IPv6 của địa chỉ nội bộ; giờ mọi dạng như vậy đều bị chặn.</span></li>
|
|
454
|
+
<li data-kind="security"><span class="kind kind-security">Bảo mật</span><span>Khi có upstream proxy của công ty (<code>HTTPS_PROXY</code>), package proxy giờ tự kiểm tra từng đích kết nối thay vì để upstream tự xử lý.</span></li>
|
|
455
|
+
</ul>
|
|
456
|
+
</div>
|
|
457
|
+
</div>
|
|
435
458
|
<div class="archive-row" id="v1-37-0">
|
|
436
459
|
<div class="archive-head"><a class="release-version" href="#v1-37-0">v1.37.0</a> <span class="release-date">22/10/2026</span></div>
|
|
437
460
|
<div class="archive-body">
|
package/docs-site/windows.html
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
|
|
38
38
|
<span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
|
|
39
39
|
</a>
|
|
40
|
-
<a class="version-badge" href="/whats-new" data-docs-version="v1.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.0" title="v1.46.0 docs · VI"><span class="dot"></span>v1.46.0</a>
|
|
41
41
|
<nav class="top-nav" aria-label="Tài liệu">
|
|
42
42
|
<a href="/quickstart">Tài liệu</a>
|
|
43
43
|
<a href="/whats-new">Changelog</a>
|
package/docs-site/workflows.html
CHANGED
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<span class="brand-mark"><img src="/assets/piagent-logo.svg" alt="" width="28" height="28" /></span>
|
|
38
38
|
<span class="brand-name"><b>Piagent</b> <span>Platform</span></span>
|
|
39
39
|
</a>
|
|
40
|
-
<a class="version-badge" href="/whats-new" data-docs-version="v1.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.46.0" title="v1.46.0 docs · VI"><span class="dot"></span>v1.46.0</a>
|
|
41
41
|
<nav class="top-nav" aria-label="Tài liệu">
|
|
42
42
|
<a href="/quickstart">Tài liệu</a>
|
|
43
43
|
<a href="/whats-new">Changelog</a>
|
|
@@ -256,8 +256,8 @@
|
|
|
256
256
|
},
|
|
257
257
|
{
|
|
258
258
|
"path": "tests",
|
|
259
|
-
"fileCount":
|
|
260
|
-
"sha256": "
|
|
259
|
+
"fileCount": 635,
|
|
260
|
+
"sha256": "e192ed7528a5d5a992cd33c3837ee6f779b404e45cedc06f79978e2bfa9272eb"
|
|
261
261
|
}
|
|
262
262
|
],
|
|
263
263
|
"custodianComparisonRules": {
|
package/package.json
CHANGED
|
@@ -494,7 +494,9 @@ function requestedPiProvider(model, configRoot, credentials) {
|
|
|
494
494
|
}
|
|
495
495
|
|
|
496
496
|
function snapshotPiAgentHome(temporaryRoot, runtimeParent, argv, cwd, replay, { providerFreeFinalization = false } = {}) {
|
|
497
|
-
|
|
497
|
+
// Piagent's own Pi home holds the login benchmarks borrow (see extensions/agent-home.js).
|
|
498
|
+
const personal = path.resolve(os.homedir(), ".pi", "agent"), configured = process.env.PI_CODING_AGENT_DIR;
|
|
499
|
+
const sourceRoot = path.resolve(process.env.PIAGENT_AGENT_DIR || (configured && path.resolve(configured) !== personal ? configured : path.join(os.homedir(), ".piagent", "agent")));
|
|
498
500
|
const configRoot = path.join(temporaryRoot, "pi-agent-config");
|
|
499
501
|
fs.mkdirSync(configRoot, { recursive: true, mode: 0o700 });
|
|
500
502
|
const copied = [];
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export function personalPiAgentDir(home?: string): string;
|
|
2
|
+
export function piagentAgentDir(env?: NodeJS.ProcessEnv, home?: string): string;
|
|
3
|
+
export function agentWatchControlDir(home?: string): string;
|
|
4
|
+
export function dormantInPersonalPi(env?: NodeJS.ProcessEnv, home?: string, argv?: string[]): boolean;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
|
|
5
|
+
// Piagent runs Pi from its own home (~/.piagent/agent) so the member's
|
|
6
|
+
// personal `pi` stays the stock host: no Piagent package, add-ons, model scope
|
|
7
|
+
// or footer panel lands in ~/.pi/agent. Agent Watch still reads its control
|
|
8
|
+
// files (runtime record, managed binding, status) from ~/.pi/agent, so those
|
|
9
|
+
// stay where Watch looks; Pi itself ignores them.
|
|
10
|
+
|
|
11
|
+
/** The stock Pi home, the member's personal `pi`. */
|
|
12
|
+
export function personalPiAgentDir(home = os.homedir()) {
|
|
13
|
+
return path.resolve(home, ".pi", "agent");
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Where Piagent's Pi keeps settings, packages, login and sessions. An explicit
|
|
18
|
+
* PIAGENT_AGENT_DIR wins; a PI_CODING_AGENT_DIR that points anywhere but the
|
|
19
|
+
* personal home is honoured (tests, benchmarks, custom setups); otherwise
|
|
20
|
+
* ~/.piagent/agent.
|
|
21
|
+
*/
|
|
22
|
+
export function piagentAgentDir(env = process.env, home = os.homedir()) {
|
|
23
|
+
const own = env.PIAGENT_AGENT_DIR?.trim();
|
|
24
|
+
if (own) return path.resolve(own);
|
|
25
|
+
const configured = env.PI_CODING_AGENT_DIR?.trim();
|
|
26
|
+
if (configured && path.resolve(configured) !== personalPiAgentDir(home)) return path.resolve(configured);
|
|
27
|
+
return path.resolve(home, ".piagent", "agent");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Agent Watch's files: the runtime record, the managed binding and status. */
|
|
31
|
+
export function agentWatchControlDir(home = os.homedir()) {
|
|
32
|
+
return personalPiAgentDir(home);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function realpath(file) {
|
|
36
|
+
try { return fs.realpathSync(file); } catch { return path.resolve(file); }
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* True when this process is the stock `pi` command running from the personal
|
|
41
|
+
* home: Piagent was registered there by an older release or a project's
|
|
42
|
+
* .pi/settings.json, and it stays out of the member's way. Hosts that embed Pi
|
|
43
|
+
* (studio, dashboard gateway, benchmarks) and `piagent` itself are never
|
|
44
|
+
* dormant; PIAGENT_ACTIVE=1 opts a personal `pi` back in.
|
|
45
|
+
*/
|
|
46
|
+
export function dormantInPersonalPi(env = process.env, home = os.homedir(), argv = process.argv) {
|
|
47
|
+
if (env.PIAGENT_ACTIVE === "1") return false;
|
|
48
|
+
const configured = env.PI_CODING_AGENT_DIR?.trim();
|
|
49
|
+
if (configured && path.resolve(configured) !== personalPiAgentDir(home)) return false;
|
|
50
|
+
const entry = argv[1] ? realpath(argv[1]) : "";
|
|
51
|
+
return /[\\/]@earendil-works[\\/]pi-coding-agent[\\/]/.test(entry);
|
|
52
|
+
}
|
|
@@ -37,6 +37,7 @@ import {
|
|
|
37
37
|
} from "./redaction-core.js";
|
|
38
38
|
import { detectProfileName } from "./project-shape.js";
|
|
39
39
|
import { evaluateUpdateCheck, isInstalledPlatform, readUpdateCache, startUpdateProbe } from "./update-check.js";
|
|
40
|
+
import { dormantInPersonalPi, personalPiAgentDir } from "./agent-home.js";
|
|
40
41
|
import {
|
|
41
42
|
REPOSITORY_SCOPES,
|
|
42
43
|
collectServers,
|
|
@@ -366,7 +367,7 @@ const PLATFORM_ROOT = findPlatformRoot(path.dirname(fileURLToPath(import.meta.ur
|
|
|
366
367
|
// package's and the user's (also those kept for other coding agents, such as
|
|
367
368
|
// ~/.claude/skills). Reading them is allowed; writes stay in the project.
|
|
368
369
|
const SKILL_READ_ROOTS = [path.join(PLATFORM_ROOT, "packages", "piagent-core", "skills"),
|
|
369
|
-
path.join(process.env.PI_CODING_AGENT_DIR ||
|
|
370
|
+
path.join(process.env.PI_CODING_AGENT_DIR || personalPiAgentDir(), "skills"), path.join(personalPiAgentDir(), "skills"), ...userSkillFolders()]
|
|
370
371
|
.flatMap((root) => { try { return [fs.realpathSync.native(root)]; } catch { return []; } });
|
|
371
372
|
const UPDATE_CHECK_MODULE = fileURLToPath(new URL("./update-check.js", import.meta.url));
|
|
372
373
|
// The installed version, read from the package this file ships in. A maintainer
|
|
@@ -3452,6 +3453,9 @@ function activeSessionTask(_cwd: string, _sessionId: string): TaskContract | und
|
|
|
3452
3453
|
const noTask = (..._args: unknown[]): undefined => undefined;
|
|
3453
3454
|
|
|
3454
3455
|
export default function piagentGuard(pi: ExtensionAPI) {
|
|
3456
|
+
// The member's own `pi` stays stock even when an older install or a project
|
|
3457
|
+
// still registers this package there; Piagent runs through `piagent`.
|
|
3458
|
+
if (dormantInPersonalPi()) return;
|
|
3455
3459
|
const extensionDir = path.dirname(fileURLToPath(import.meta.url));
|
|
3456
3460
|
const policy = loadPolicy(extensionDir);
|
|
3457
3461
|
const bashResults = createBashResultLedger({ maxEntries: 300 });
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { parentPort, workerData } from 'node:worker_threads';
|
|
2
|
+
import { matchesProtectedPath } from './policy-core.js';
|
|
3
|
+
import { workingTreeSnapshot } from './task-state.js';
|
|
4
|
+
// Hash the working tree away from the thread that draws the terminal.
|
|
5
|
+
const { cwd, gitTimeoutMs, protectedPaths } = workerData;
|
|
6
|
+
parentPort.postMessage(workingTreeSnapshot(cwd, {
|
|
7
|
+
gitTimeoutMs,
|
|
8
|
+
isProtectedProjectPath: (projectPath) => Boolean(matchesProtectedPath(projectPath, protectedPaths))
|
|
9
|
+
}));
|
|
@@ -104,11 +104,17 @@ function directChildGitEvidenceRootDetails(cwd) {
|
|
|
104
104
|
complete = false;
|
|
105
105
|
continue;
|
|
106
106
|
}
|
|
107
|
-
|
|
107
|
+
// One Git process per child: a parent of thirty repositories ran sixty.
|
|
108
|
+
let inside, topLevel;
|
|
109
|
+
try {
|
|
110
|
+
[inside, topLevel] = gitOutput(child, ["rev-parse", "--is-inside-work-tree", "--show-toplevel"]).trim().split("\n");
|
|
111
|
+
} catch {
|
|
112
|
+
inside = "false";
|
|
113
|
+
}
|
|
114
|
+
if (inside !== "true" || !topLevel) {
|
|
108
115
|
complete = false;
|
|
109
116
|
continue;
|
|
110
117
|
}
|
|
111
|
-
const topLevel = gitOutput(child, ["rev-parse", "--show-toplevel"]).trim();
|
|
112
118
|
if (fs.realpathSync(topLevel) !== fs.realpathSync(child)) {
|
|
113
119
|
complete = false;
|
|
114
120
|
continue;
|
|
@@ -143,6 +149,26 @@ export function gitEvidenceRoots(cwd) {
|
|
|
143
149
|
return gitEvidenceRootDetails(cwd).roots;
|
|
144
150
|
}
|
|
145
151
|
|
|
152
|
+
// Whether the working tree differs from HEAD, without reading any file: the
|
|
153
|
+
// same answer as a non-empty workingTreeSnapshot, which hashes every changed
|
|
154
|
+
// and loose file and blocked the terminal for seconds on each prompt in a
|
|
155
|
+
// folder of repositories. Unknown counts as changed, as it does there.
|
|
156
|
+
export function workingTreeHasChanges(cwd, details = gitEvidenceRootDetails(cwd)) {
|
|
157
|
+
if (!details.complete) return true;
|
|
158
|
+
for (const root of details.roots) {
|
|
159
|
+
try {
|
|
160
|
+
const status = gitOutput(root.cwd, ["status", "--porcelain", "-z", "--untracked-files=normal",
|
|
161
|
+
"--", ".", ":(exclude).pi/piagent-state"]);
|
|
162
|
+
if (status) return true;
|
|
163
|
+
} catch {
|
|
164
|
+
return true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (details.roots.length === 0 || details.roots.some((root) => root.prefix === "")) return false;
|
|
168
|
+
const loose = nonGitWorkspaceFileDetails(cwd, details.roots.map((root) => root.prefix), 1);
|
|
169
|
+
return loose.files.length > 0 || !loose.complete;
|
|
170
|
+
}
|
|
171
|
+
|
|
146
172
|
function workspaceEvidenceFileLimit(value) {
|
|
147
173
|
return Number.isInteger(value)
|
|
148
174
|
? Math.max(1, Math.min(WORKSPACE_EVIDENCE_MAX_FILES, value))
|
|
@@ -44,7 +44,10 @@ export function configPathForScope(scope, options = {}) {
|
|
|
44
44
|
case "global":
|
|
45
45
|
return path.join(env.XDG_CONFIG_HOME || path.join(home, ".config"), "mcp", "mcp.json");
|
|
46
46
|
case "pi-global":
|
|
47
|
-
|
|
47
|
+
// Piagent's own Pi home, not the member's personal pi (see extensions/agent-home.js).
|
|
48
|
+
if (env.PIAGENT_AGENT_DIR) return path.join(env.PIAGENT_AGENT_DIR, "mcp.json");
|
|
49
|
+
if (env.PI_CODING_AGENT_DIR && path.resolve(env.PI_CODING_AGENT_DIR) !== path.resolve(home, ".pi", "agent")) return path.join(env.PI_CODING_AGENT_DIR, "mcp.json");
|
|
50
|
+
return path.join(home, ".piagent", "agent", "mcp.json");
|
|
48
51
|
case "project":
|
|
49
52
|
return path.join(projectPath, ".mcp.json");
|
|
50
53
|
case "pi-project":
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
|
|
1
3
|
import type { ExtensionAPI, ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
4
|
|
|
3
5
|
import { classifyContextTask } from "../../extensions/context-engine.js";
|
|
@@ -5,6 +7,7 @@ import { matchesProtectedPath } from "../../extensions/policy-core.js";
|
|
|
5
7
|
import type { TaskContract } from "../../extensions/guard-types.js";
|
|
6
8
|
import { attachLocalImagesFromText, extractLocalImagePathCandidates } from "../input/chat-images.ts";
|
|
7
9
|
import type { ChatImageAccessPolicy } from "../input/chat-images.ts";
|
|
10
|
+
import { reviewFileArguments } from "../input/file-arguments.ts";
|
|
8
11
|
import type { AuthorityResumeDecision } from "../policy/authority-resume-policy.ts";
|
|
9
12
|
import { registerAdaptiveContextGovernor } from "../session/adaptive-context-governor.ts";
|
|
10
13
|
import { toolGroupsForPrompt, PIAGENT_TOOL_NAMES, PIAGENT_TOOL_ORDER, PIAGENT_TOOL_GROUPS } from "../tools/tool-groups.ts";
|
|
@@ -74,10 +77,21 @@ export function registerInputHook(pi: ExtensionAPI, dependencies: InputHookDepen
|
|
|
74
77
|
.filter((group) => !["intake", "task", "recovery"].includes(group)));
|
|
75
78
|
dependencies.telemetry(ctx, { event: "user_input", turnId: turn.turnId, source: event.source,
|
|
76
79
|
promptHash: signal.promptHash, promptChars: text.length, inputMode: "freeform" });
|
|
77
|
-
const
|
|
80
|
+
const reviewed = reviewFileArguments(text, event.images, ctx.cwd, () => dependencies.imageAccess(ctx));
|
|
81
|
+
if (reviewed && !reviewed.text) {
|
|
82
|
+
ctx.ui.notify("Not sent: a file changed while Pi was reading the @file arguments. Run the command again.", "error");
|
|
83
|
+
return { action: "handled" };
|
|
84
|
+
}
|
|
85
|
+
if (reviewed) ctx.ui.notify(`Withheld ${reviewed.withheld.map((item) => `${path.basename(item.path)} (${item.reason})`).join(", ")}`, "warning");
|
|
86
|
+
const nextText = reviewed?.text ?? text;
|
|
87
|
+
const nextImages = reviewed ? reviewed.images as typeof event.images : event.images;
|
|
88
|
+
const attachment = attachLocalImagesFromText(nextText, nextImages, ctx.cwd, () => dependencies.imageAccess(ctx));
|
|
89
|
+
if (attachment?.skipped.length) {
|
|
90
|
+
ctx.ui.notify(`Skipped ${attachment.skipped.map((item) => `${path.basename(item.path)} (${item.reason})`).join(", ")}`, "warning");
|
|
91
|
+
}
|
|
78
92
|
if (attachment?.attached.length) return { action: "transform", text: attachment.text,
|
|
79
|
-
images: [...(
|
|
80
|
-
if (
|
|
93
|
+
images: [...(nextImages ?? []), ...attachment.images] };
|
|
94
|
+
if (reviewed) return { action: "transform", text: nextText, images: nextImages };
|
|
81
95
|
return { action: "continue" };
|
|
82
96
|
});
|
|
83
97
|
}
|