@piagent/platform 1.48.1 → 1.48.3
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 +32 -0
- package/README.md +2 -0
- package/README.vi.md +2 -0
- package/docs/command-reference-vietnamese.md +4 -3
- package/docs/distribution-standard.md +6 -6
- package/docs/harness-conformance.md +4 -0
- 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/content/en/update.html +8 -0
- package/docs-site/content/update.html +8 -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 +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 +11 -3
- package/docs-site/en/whats-new.html +52 -27
- 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 +77 -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 +11 -3
- package/docs-site/whats-new.html +52 -27
- 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/piagent-guard.ts +4 -1
- package/packages/piagent-core/extensions/workspace-inspection.ts +4 -1
- package/packages/piagent-core/managed/check-waiver.mjs +35 -0
- package/packages/piagent-core/managed/command-tools.mjs +2 -2
- package/packages/piagent-core/managed/dist/workspace/manifest.json +1 -1
- package/packages/piagent-core/managed/dist/workspace/worker.mjs +7 -1
- package/packages/piagent-core/managed/patch-snapshot.mjs +28 -13
- package/packages/piagent-core/managed/review-snapshot-request.mjs +1 -1
- package/packages/piagent-core/managed/review-snapshot-worker.mjs +52 -11
- package/packages/piagent-core/managed/session.mjs +9 -9
- package/packages/piagent-core/managed/workflow.mjs +8 -7
- package/packages/piagent-core/package.json +1 -1
- package/packages/piagent-core/runtime/update/terminal-reload.mjs +122 -0
- package/packages/piagent-core/runtime/update/terminal-update-offer.mjs +1 -1
- package/packages/piagent-webui/dist/client/assets/{ActivityPanel-DxQ3_dyT.js → ActivityPanel-Bv-jc1s3.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/App-DqN7B1JR.js +5 -0
- package/packages/piagent-webui/dist/client/assets/AttachmentImage-eZKqLYZ2.js +1 -0
- package/packages/piagent-webui/dist/client/assets/GatewayApp-B3--WjSd.js +63 -0
- package/packages/piagent-webui/dist/client/assets/{InspectionApp-pD-BqBXm.js → InspectionApp-BKQiA0Ce.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/{LineReview-C_0ZpgCH.js → LineReview-CB3mQe7m.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/MarkdownMessage-zw5RxDmZ.js +29 -0
- package/packages/piagent-webui/dist/client/assets/{SessionAgentWorkspace-3tM7Q6HH.js → SessionAgentWorkspace-ZAdRbxVA.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/SessionInspectorDrawer-B2e4-1FG.js +2 -0
- package/packages/piagent-webui/dist/client/assets/SettingsNavigation-C3MC0X4P.js +3 -0
- package/packages/piagent-webui/dist/client/assets/SettingsPage-D4os5vHj.js +1 -0
- package/packages/piagent-webui/dist/client/assets/{TerminalPanel-CtZyb0tj.js → TerminalPanel-CVYUiDkn.js} +2 -2
- package/packages/piagent-webui/dist/client/assets/{TerminalView-yaIg6RCs.js → TerminalView-C3upxbKw.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/{WorkspaceCodeEditor-BS_ZrjPN.js → WorkspaceCodeEditor-E0Zopcke.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/WorkspaceExplorer-DldLoJyf.js +5 -0
- package/packages/piagent-webui/dist/client/assets/WorkspaceFilePreview-CvIBYige.js +1 -0
- package/packages/piagent-webui/dist/client/assets/{WorkspaceQuickOpen-CJmMBmK8.js → WorkspaceQuickOpen-Bi-kTEEU.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/index-DcrpSyBK.js +37 -0
- package/packages/piagent-webui/dist/client/assets/{tab-close-ITV4Cf4X.js → tab-close-BwkkhMH7.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/transcript-view-model-acWtHGyE.js +3 -0
- package/packages/piagent-webui/dist/client/assets/{ui-preferences-0waeSO-S.js → ui-preferences-OfS30-ZV.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/{vendor-CSDKB7mU.js → vendor-DNZbaWhT.js} +62 -26
- package/packages/piagent-webui/dist/client/assets/{workspace-api-D8sJkiZB.js → workspace-api-CFBR73lU.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/workspace-navigation-DW8zhH6U.js +1 -0
- package/packages/piagent-webui/dist/client/index.html +3 -3
- package/packages/piagent-webui/shared/process-copy.ts +2 -1
- package/schemas/piagent-webui/workspace-media-v1.schema.json +6 -0
- package/scripts/company-terminal.mjs +21 -1
- package/scripts/piagent-cli.mjs +44 -21
- package/scripts/piagent-studio.mjs +22 -2
- package/scripts/terminal-reload.mjs +15 -0
- package/scripts/update-global.mjs +10 -0
- package/packages/piagent-webui/dist/client/assets/App-fZeIRoaD.js +0 -5
- package/packages/piagent-webui/dist/client/assets/GatewayApp-CpC4lgYK.js +0 -99
- package/packages/piagent-webui/dist/client/assets/MarkdownMessage-DGt5B-6D.js +0 -29
- package/packages/piagent-webui/dist/client/assets/SessionInspectorDrawer-BJ94aQ6y.js +0 -2
- package/packages/piagent-webui/dist/client/assets/SettingsNavigation-BFfqMcuL.js +0 -3
- package/packages/piagent-webui/dist/client/assets/SettingsPage-CxpZ7cdM.js +0 -1
- package/packages/piagent-webui/dist/client/assets/WorkspaceExplorer-CkFBpcM7.js +0 -5
- package/packages/piagent-webui/dist/client/assets/index-CNdhIouM.js +0 -37
- package/packages/piagent-webui/dist/client/assets/transcript-view-model-CpEMY1xb.js +0 -3
- package/packages/piagent-webui/dist/client/assets/workspace-navigation-DkVobhwg.js +0 -1
package/docs-site/releases.json
CHANGED
|
@@ -1,4 +1,81 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "1.48.3",
|
|
4
|
+
"date": "2026-10-30",
|
|
5
|
+
"status": "stable",
|
|
6
|
+
"title": {
|
|
7
|
+
"en": "The agent sends pictures and files into the chat; reviews run across several repositories",
|
|
8
|
+
"vi": "Agent gửi thẳng hình và file vào chat; review chạy được trong thư mục nhiều repo"
|
|
9
|
+
},
|
|
10
|
+
"summary": {
|
|
11
|
+
"en": "Answers show pictures and file cards in place, an SVG opens as a picture, attached images are large and open full size, and a folder of repositories gets its review.",
|
|
12
|
+
"vi": "Câu trả lời hiện hình và thẻ file ngay trong chat, SVG mở ra hình, ảnh đính kèm lớn và bấm xem được, thư mục chứa nhiều repo được review bình thường."
|
|
13
|
+
},
|
|
14
|
+
"requires": null,
|
|
15
|
+
"items": [
|
|
16
|
+
{
|
|
17
|
+
"kind": "new",
|
|
18
|
+
"en": "The agent sends a picture or file into the chat with : a picture is drawn in place and opens full size, any other file is a card to open or download.",
|
|
19
|
+
"vi": "Agent gửi hình hoặc file vào chat bằng : hình hiện ngay và mở to được, file khác là thẻ để mở hoặc tải về."
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"kind": "improved",
|
|
23
|
+
"en": "An SVG opens as a picture with View code beside it, and every open file has Download.",
|
|
24
|
+
"vi": "SVG mở ra hình, có nút Xem mã bên cạnh; mọi file đang mở đều có nút Tải về."
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"kind": "improved",
|
|
28
|
+
"en": "An image attached to a message is a large thumbnail that opens full size, on the new conversation page too.",
|
|
29
|
+
"vi": "Ảnh đính kèm là thumbnail lớn, bấm để xem to, kể cả ở trang cuộc trò chuyện mới."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"kind": "fixed",
|
|
33
|
+
"en": "Review no longer fails with not_git in a folder holding several repositories: changes made by commands, committed or not, are found in each repository.",
|
|
34
|
+
"vi": "Review không còn lỗi not_git trong thư mục chứa nhiều repo: thay đổi do lệnh tạo ra, đã commit hay chưa, được nhận đúng theo từng repo."
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"kind": "fixed",
|
|
38
|
+
"en": "A review stopped by an update under a running conversation says so and asks to reopen it; an unnamed failure keeps its redacted words in the local log.",
|
|
39
|
+
"vi": "Review dừng vì Piagent được cập nhật giữa cuộc trò chuyện sẽ nói rõ và nhắc mở lại; lỗi chưa có mã giữ nội dung đã che trong log máy."
|
|
40
|
+
}
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"version": "1.48.2",
|
|
45
|
+
"date": "2026-10-30",
|
|
46
|
+
"status": "stable",
|
|
47
|
+
"title": {
|
|
48
|
+
"en": "Terminals load a new release without closing; only the member waives checks",
|
|
49
|
+
"vi": "Terminal nạp bản mới không cần đóng; chỉ member được bỏ qua kiểm tra"
|
|
50
|
+
},
|
|
51
|
+
"summary": {
|
|
52
|
+
"en": "After an update every open Terminal moves to the new release when idle and keeps its conversation, and a team's required checks can be skipped only by the member, on a card.",
|
|
53
|
+
"vi": "Sau khi cập nhật, mọi Terminal đang mở tự nạp bản mới khi rảnh và giữ nguyên cuộc trò chuyện; kiểm tra bắt buộc của team chỉ được bỏ qua khi member xác nhận trên thẻ."
|
|
54
|
+
},
|
|
55
|
+
"requires": null,
|
|
56
|
+
"items": [
|
|
57
|
+
{
|
|
58
|
+
"kind": "new",
|
|
59
|
+
"en": "piagent reload: every open Terminal (piagent and piagent studio) loads the installed release when idle and keeps its conversation; piagent-update asks for it after installing.",
|
|
60
|
+
"vi": "piagent reload: mọi Terminal đang mở (piagent và piagent studio) nạp bản đã cài khi rảnh, giữ nguyên cuộc trò chuyện; piagent-update tự yêu cầu sau khi cài."
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"kind": "improved",
|
|
64
|
+
"en": "A Terminal running a task is never cut off: it loads the new release when the task finishes, and its footer says it is waiting.",
|
|
65
|
+
"vi": "Terminal đang chạy task không bị cắt ngang: nạp bản mới khi task xong, footer ghi rõ đang chờ."
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"kind": "new",
|
|
69
|
+
"en": "Only the member can skip the checks a team requires: the agent asks on an approval card, once, for the code as it is then; later changes are checked again.",
|
|
70
|
+
"vi": "Chỉ member được bỏ qua kiểm tra mà team bắt buộc: agent hỏi trên thẻ duyệt, một lần, cho đúng code lúc đó; code đổi sau đó phải kiểm tra lại."
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"kind": "improved",
|
|
74
|
+
"en": "A turn whose checks the member skipped says so in its status, apart from a turn where no check ran; a push still asks as in every mode.",
|
|
75
|
+
"vi": "Lượt được member bỏ qua kiểm tra ghi rõ trong trạng thái, tách khỏi lượt không có kiểm tra nào chạy; push vẫn hỏi như mọi chế độ."
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
},
|
|
2
79
|
{
|
|
3
80
|
"version": "1.48.1",
|
|
4
81
|
"date": "2026-10-30",
|
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.48.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.48.3" title="v1.48.3 docs · VI"><span class="dot"></span>v1.48.3</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.48.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.48.3" title="v1.48.3 docs · VI"><span class="dot"></span>v1.48.3</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.48.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.48.3" title="v1.48.3 docs · VI"><span class="dot"></span>v1.48.3</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.48.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.48.3" title="v1.48.3 docs · VI"><span class="dot"></span>v1.48.3</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.48.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.48.3" title="v1.48.3 docs · VI"><span class="dot"></span>v1.48.3</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>
|
|
@@ -114,6 +114,14 @@
|
|
|
114
114
|
</div>
|
|
115
115
|
<p>Khởi động lại dashboard sau khi cập nhật để giao diện mới có hiệu lực.</p>
|
|
116
116
|
|
|
117
|
+
<h3 id="terminal-dang-mo">Terminal đang mở</h3>
|
|
118
|
+
<p>Không cần đóng Terminal. Sau khi cập nhật, mọi Terminal đang mở (<code>piagent</code> và <code>piagent studio</code>) tự nạp bản mới khi rảnh và giữ nguyên cuộc trò chuyện. Terminal đang chạy task thì chờ task xong rồi mới nạp; footer ghi rõ đang chờ. Terminal cá nhân nạp lại extension của Piagent; Terminal công ty mở lại trong chính cửa sổ đó, trên đúng cuộc trò chuyện. Muốn yêu cầu lại bất cứ lúc nào:</p>
|
|
119
|
+
<div class="command-card">
|
|
120
|
+
<header><span>Nạp bản đã cài vào mọi Terminal đang mở</span><button class="clip-btn" data-clip="piagent reload">Lấy lệnh</button></header>
|
|
121
|
+
<pre><code>piagent reload</code></pre>
|
|
122
|
+
</div>
|
|
123
|
+
<p>Bản mới chạy trên một bản Pi khác thì Terminal cá nhân báo cần mở lại <code>piagent</code>.</p>
|
|
124
|
+
|
|
117
125
|
<h3 id="cap-nhat-lam-gi">Lệnh này làm gì, theo thứ tự</h3>
|
|
118
126
|
<ol>
|
|
119
127
|
<li>Xác định bản đích và bản Pi mà bản đó pin.</li>
|
|
@@ -145,9 +153,9 @@
|
|
|
145
153
|
<h2 id="pin-cho-team">Pin một bản cho cả team</h2>
|
|
146
154
|
<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
155
|
<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.48.
|
|
156
|
+
<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.48.3 piagent-install --stable --dry-run piagent-install --stable">Lấy lệnh</button></header>
|
|
149
157
|
<pre><code>npm install -g --ignore-scripts @earendil-works/pi-coding-agent@1.3.0
|
|
150
|
-
npm install -g --ignore-scripts @piagent/platform@1.48.
|
|
158
|
+
npm install -g --ignore-scripts @piagent/platform@1.48.3
|
|
151
159
|
piagent-install --stable --dry-run
|
|
152
160
|
piagent-install --stable</code></pre>
|
|
153
161
|
</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.48.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.48.3" title="v1.48.3 docs · VI"><span class="dot"></span>v1.48.3</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-48-
|
|
111
|
+
<article class="release latest" id="v1-48-3" data-release>
|
|
112
|
+
<div class="release-meta"><a class="release-version" href="#v1-48-3">v1.48.3</a><time class="release-date" datetime="2026-10-30">30/10/2026</time></div>
|
|
113
|
+
<div class="release-body">
|
|
114
|
+
<h3 data-toc-skip id="v1-48-3-title">Agent gửi thẳng hình và file vào chat; review chạy được trong thư mục nhiều repo</h3>
|
|
115
|
+
<p>Câu trả lời hiện hình và thẻ file ngay trong chat, SVG mở ra hình, ảnh đính kèm lớn và bấm xem được, thư mục chứa nhiều repo được review bình thường.</p>
|
|
116
|
+
<ul class="release-items">
|
|
117
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Agent gửi hình hoặc file vào chat bằng : hình hiện ngay và mở to được, file khác là thẻ để mở hoặc tải về.</span></li>
|
|
118
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>SVG mở ra hình, có nút Xem mã bên cạnh; mọi file đang mở đều có nút Tải về.</span></li>
|
|
119
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Ảnh đính kèm là thumbnail lớn, bấm để xem to, kể cả ở trang cuộc trò chuyện mới.</span></li>
|
|
120
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Review không còn lỗi not_git trong thư mục chứa nhiều repo: thay đổi do lệnh tạo ra, đã commit hay chưa, được nhận đúng theo từng repo.</span></li>
|
|
121
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Review dừng vì Piagent được cập nhật giữa cuộc trò chuyện sẽ nói rõ và nhắc mở lại; lỗi chưa có mã giữ nội dung đã che trong log máy.</span></li>
|
|
122
|
+
</ul>
|
|
123
|
+
</div>
|
|
124
|
+
</article>
|
|
125
|
+
<article class="release" id="v1-48-2" data-release>
|
|
126
|
+
<div class="release-meta"><a class="release-version" href="#v1-48-2">v1.48.2</a><time class="release-date" datetime="2026-10-30">30/10/2026</time></div>
|
|
127
|
+
<div class="release-body">
|
|
128
|
+
<h3 data-toc-skip id="v1-48-2-title">Terminal nạp bản mới không cần đóng; chỉ member được bỏ qua kiểm tra</h3>
|
|
129
|
+
<p>Sau khi cập nhật, mọi Terminal đang mở tự nạp bản mới khi rảnh và giữ nguyên cuộc trò chuyện; kiểm tra bắt buộc của team chỉ được bỏ qua khi member xác nhận trên thẻ.</p>
|
|
130
|
+
<ul class="release-items">
|
|
131
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>piagent reload: mọi Terminal đang mở (piagent và piagent studio) nạp bản đã cài khi rảnh, giữ nguyên cuộc trò chuyện; piagent-update tự yêu cầu sau khi cài.</span></li>
|
|
132
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Chỉ member được bỏ qua kiểm tra mà team bắt buộc: agent hỏi trên thẻ duyệt, một lần, cho đúng code lúc đó; code đổi sau đó phải kiểm tra lại.</span></li>
|
|
133
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Terminal đang chạy task không bị cắt ngang: nạp bản mới khi task xong, footer ghi rõ đang chờ.</span></li>
|
|
134
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Lượt được member bỏ qua kiểm tra ghi rõ trong trạng thái, tách khỏi lượt không có kiểm tra nào chạy; push vẫn hỏi như mọi chế độ.</span></li>
|
|
135
|
+
</ul>
|
|
136
|
+
</div>
|
|
137
|
+
</article>
|
|
138
|
+
<article class="release" id="v1-48-1" data-release>
|
|
112
139
|
<div class="release-meta"><a class="release-version" href="#v1-48-1">v1.48.1</a><time class="release-date" datetime="2026-10-30">30/10/2026</time></div>
|
|
113
140
|
<div class="release-body">
|
|
114
141
|
<h3 data-toc-skip id="v1-48-1-title">Dashboard trả lời nhanh hơn, Enter trong Terminal hiện tin nhắn ngay</h3>
|
|
@@ -395,36 +422,34 @@
|
|
|
395
422
|
</ul>
|
|
396
423
|
</div>
|
|
397
424
|
</article>
|
|
398
|
-
<article class="release" id="v1-43-1" data-release>
|
|
399
|
-
<div class="release-meta"><a class="release-version" href="#v1-43-1">v1.43.1</a><time class="release-date" datetime="2026-10-26">26/10/2026</time></div>
|
|
400
|
-
<div class="release-body">
|
|
401
|
-
<h3 data-toc-skip id="v1-43-1-title">Dev chọn workflow, harness hỗ trợ BE/FE theo project <span class="tag">không phát hành</span></h3>
|
|
402
|
-
<p>Đã tag nhưng chưa publish: một bullet release note vượt giới hạn độ dài. Thay bằng 1.43.4.</p>
|
|
403
|
-
<ul class="release-items">
|
|
404
|
-
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Tự nhận diện repo/package FE, BE trong thư mục hội thoại và gợi ý checks phù hợp, làm mới theo task.</span></li>
|
|
405
|
-
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Context workflow tùy chọn nhớ nguồn requirement, plan và tasks của công việc khi mở lại hội thoại, truyền chỉ đọc cho helper và hỗ trợ đổi hoặc xóa.</span></li>
|
|
406
|
-
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Lifecycle là hướng dẫn theo workflow và điểm dừng Dev chọn, không ép file spec hoặc tự tạo gate release. Skill được chọn không cấp quyền hay bỏ qua kiểm chứng, review và duyệt deploy.</span></li>
|
|
407
|
-
</ul>
|
|
408
|
-
</div>
|
|
409
|
-
</article>
|
|
410
|
-
<article class="release" id="v1-43-0" data-release>
|
|
411
|
-
<div class="release-meta"><a class="release-version" href="#v1-43-0">v1.43.0</a><time class="release-date" datetime="2026-10-26">26/10/2026</time></div>
|
|
412
|
-
<div class="release-body">
|
|
413
|
-
<h3 data-toc-skip id="v1-43-0-title">Dev chọn workflow, harness hỗ trợ BE/FE theo project <span class="tag">không phát hành</span></h3>
|
|
414
|
-
<p>Đã tag nhưng chưa publish: gate wording tài liệu chặn phát hành. Thay bằng 1.43.4.</p>
|
|
415
|
-
<ul class="release-items">
|
|
416
|
-
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Tự nhận diện repo/package FE, BE trong thư mục hội thoại và gợi ý checks phù hợp, làm mới theo task.</span></li>
|
|
417
|
-
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Context workflow tùy chọn nhớ nguồn requirement, plan và tasks của công việc khi mở lại hội thoại, truyền chỉ đọc cho helper và hỗ trợ đổi hoặc xóa.</span></li>
|
|
418
|
-
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Lifecycle là hướng dẫn theo workflow và điểm dừng Dev chọn, không ép file spec hoặc tự tạo gate release. Skill được chọn không cấp quyền hay bỏ qua kiểm chứng, review và duyệt deploy.</span></li>
|
|
419
|
-
</ul>
|
|
420
|
-
</div>
|
|
421
|
-
</article>
|
|
422
425
|
</section>
|
|
423
426
|
<section class="section archive">
|
|
424
427
|
<h2 id="archive">Các bản trước</h2>
|
|
425
428
|
<p class="section-lead">Bản cũ hơn, gom theo tháng. Mở một tháng để xem từng thay đổi.</p>
|
|
426
429
|
<details class="release-archive">
|
|
427
|
-
<summary><span>Tháng 10/2026</span><span class="archive-count">
|
|
430
|
+
<summary><span>Tháng 10/2026</span><span class="archive-count">66</span></summary>
|
|
431
|
+
<div class="archive-row" id="v1-43-1">
|
|
432
|
+
<div class="archive-head"><a class="release-version" href="#v1-43-1">v1.43.1</a> <span class="release-date">26/10/2026</span></div>
|
|
433
|
+
<div class="archive-body">
|
|
434
|
+
<p><strong>Dev chọn workflow, harness hỗ trợ BE/FE theo project</strong> <span class="tag">không phát hành</span> — Đã tag nhưng chưa publish: một bullet release note vượt giới hạn độ dài. Thay bằng 1.43.4.</p>
|
|
435
|
+
<ul class="release-items">
|
|
436
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Tự nhận diện repo/package FE, BE trong thư mục hội thoại và gợi ý checks phù hợp, làm mới theo task.</span></li>
|
|
437
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Context workflow tùy chọn nhớ nguồn requirement, plan và tasks của công việc khi mở lại hội thoại, truyền chỉ đọc cho helper và hỗ trợ đổi hoặc xóa.</span></li>
|
|
438
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Lifecycle là hướng dẫn theo workflow và điểm dừng Dev chọn, không ép file spec hoặc tự tạo gate release. Skill được chọn không cấp quyền hay bỏ qua kiểm chứng, review và duyệt deploy.</span></li>
|
|
439
|
+
</ul>
|
|
440
|
+
</div>
|
|
441
|
+
</div>
|
|
442
|
+
<div class="archive-row" id="v1-43-0">
|
|
443
|
+
<div class="archive-head"><a class="release-version" href="#v1-43-0">v1.43.0</a> <span class="release-date">26/10/2026</span></div>
|
|
444
|
+
<div class="archive-body">
|
|
445
|
+
<p><strong>Dev chọn workflow, harness hỗ trợ BE/FE theo project</strong> <span class="tag">không phát hành</span> — Đã tag nhưng chưa publish: gate wording tài liệu chặn phát hành. Thay bằng 1.43.4.</p>
|
|
446
|
+
<ul class="release-items">
|
|
447
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Tự nhận diện repo/package FE, BE trong thư mục hội thoại và gợi ý checks phù hợp, làm mới theo task.</span></li>
|
|
448
|
+
<li data-kind="new"><span class="kind kind-new">Mới</span><span>Context workflow tùy chọn nhớ nguồn requirement, plan và tasks của công việc khi mở lại hội thoại, truyền chỉ đọc cho helper và hỗ trợ đổi hoặc xóa.</span></li>
|
|
449
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Lifecycle là hướng dẫn theo workflow và điểm dừng Dev chọn, không ép file spec hoặc tự tạo gate release. Skill được chọn không cấp quyền hay bỏ qua kiểm chứng, review và duyệt deploy.</span></li>
|
|
450
|
+
</ul>
|
|
451
|
+
</div>
|
|
452
|
+
</div>
|
|
428
453
|
<div class="archive-row" id="v1-42-1">
|
|
429
454
|
<div class="archive-head"><a class="release-version" href="#v1-42-1">v1.42.1</a> <span class="release-date">25/10/2026</span></div>
|
|
430
455
|
<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.48.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.48.3" title="v1.48.3 docs · VI"><span class="dot"></span>v1.48.3</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.48.
|
|
40
|
+
<a class="version-badge" href="/whats-new" data-docs-version="v1.48.3" title="v1.48.3 docs · VI"><span class="dot"></span>v1.48.3</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": 643,
|
|
260
|
+
"sha256": "1356b4a7b5dce44794b08a4b483941b90da597ed9d7b126c1b875fd58d6e25ff"
|
|
261
261
|
}
|
|
262
262
|
],
|
|
263
263
|
"custodianComparisonRules": {
|
package/package.json
CHANGED
|
@@ -166,6 +166,7 @@ import { prefixCompletions, registerPiagentTool as registerToolDefinition, regis
|
|
|
166
166
|
import { registerTaskEvidenceTools } from "../runtime/registration/task-evidence-tools.ts";
|
|
167
167
|
import { registerAgentResources } from "../runtime/registration/agent-resources.ts";
|
|
168
168
|
import { registerTerminalUpdateOffer } from "../runtime/update/terminal-update-offer.mjs";
|
|
169
|
+
import { registerPersonalTerminalReload } from "../runtime/update/terminal-reload.mjs";
|
|
169
170
|
import { registerStyleCommand } from "../runtime/terminal/terminal-style.mjs";
|
|
170
171
|
import { userSkillFolders } from "../runtime/resources/agent-resources.mjs";
|
|
171
172
|
import { FRESH_COMMAND_ACTIONS, FRESH_COMMAND_HELP, ONBOARDING_COMMAND_ACTIONS, WORKFLOW_COMMAND_EXCLUSIONS } from "../runtime/registration/operator-catalogs.ts";
|
|
@@ -4052,7 +4053,7 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4052
4053
|
}
|
|
4053
4054
|
|
|
4054
4055
|
const grants = sessionGrants.get(ctx.sessionManager.getSessionId()) ?? new Set<string>();
|
|
4055
|
-
const grantable = Boolean(pendingHumanApproval) && !/handoff/.test(String(pendingHumanApproval!.action.requestedScope));
|
|
4056
|
+
const grantable = Boolean(pendingHumanApproval) && !/handoff|waiver/.test(String(pendingHumanApproval!.action.requestedScope));
|
|
4056
4057
|
const grant = grantKey(event.toolName, typeof pendingHumanApproval?.action.commandPreview === "string" ? pendingHumanApproval.action.commandPreview : null, preparedInput.input);
|
|
4057
4058
|
if (pendingHumanApproval && grantable && grants.has(grant)) pendingHumanApproval = null;
|
|
4058
4059
|
if (pendingHumanApproval) {
|
|
@@ -4192,6 +4193,8 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4192
4193
|
registerAgentResources(pi);
|
|
4193
4194
|
// A new release is asked about in the Terminal, as the dashboard does.
|
|
4194
4195
|
registerTerminalUpdateOffer(pi, { installed: installedPlatformVersion(), packageRoot: PLATFORM_ROOT, restart: "pi" });
|
|
4196
|
+
// `piagent reload` and a finished update reach this Terminal: it reloads when idle.
|
|
4197
|
+
registerPersonalTerminalReload(pi, { installed: readJsonFile<{ version?: string }>(path.join(PLATFORM_ROOT, "package.json"))?.version });
|
|
4195
4198
|
// The Terminal's look (/style): Pi keeps the pick in its own settings.
|
|
4196
4199
|
registerStyleCommand(pi);
|
|
4197
4200
|
registerSessionCommands(pi, { ...registrationDeps, ...contextCommandApi });
|
|
@@ -140,7 +140,10 @@ export function inspectWorkspaceFile(root: string, relative: string, options: Wo
|
|
|
140
140
|
// An image the agent made or names, shown as a picture in the explorer (the
|
|
141
141
|
// page takes data: images only). Protected files are never read.
|
|
142
142
|
const IMAGE_MIMES: Record<string, string> = { png: "image/png", jpg: "image/jpeg", jpeg: "image/jpeg", gif: "image/gif",
|
|
143
|
-
webp: "image/webp", bmp: "image/bmp", ico: "image/x-icon", avif: "image/avif"
|
|
143
|
+
webp: "image/webp", bmp: "image/bmp", ico: "image/x-icon", avif: "image/avif", svg: "image/svg+xml",
|
|
144
|
+
// Not drawn: their bytes are what "Tải về" on a file the agent handed over saves.
|
|
145
|
+
pdf: "application/pdf", docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
146
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation", zip: "application/zip" };
|
|
144
147
|
const MAX_MEDIA_BYTES = 8 << 20;
|
|
145
148
|
export function inspectWorkspaceMedia(root: string, relative: string, options: WorkspacePolicy) {
|
|
146
149
|
validPath(relative);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// The member, never the agent, may waive the repository checks the Harness
|
|
2
|
+
// asks for ("bỏ qua test, đẩy luôn"). Before, the member's words changed
|
|
3
|
+
// nothing: under verify "require" the harness sent the agent back
|
|
4
|
+
// max_fix_loops times anyway, while the delivery prompt already said checks
|
|
5
|
+
// may be "explicitly human-waived". The agent now asks with waive_checks; the
|
|
6
|
+
// member answers on an approval card, once, for the code as it is then. A
|
|
7
|
+
// later change needs its checks again. The turn still reports that no check
|
|
8
|
+
// passed, and says the member waived them.
|
|
9
|
+
import { approve } from './command-tools.mjs';
|
|
10
|
+
|
|
11
|
+
const PARAMETERS = { type: 'object', properties: {
|
|
12
|
+
member_words: { type: 'string', minLength: 1, maxLength: 300, description: 'What the member said, quoted: the request to skip the checks.' },
|
|
13
|
+
reason: { type: 'string', minLength: 1, maxLength: 300, description: 'Which checks are skipped and what is left unverified.' } },
|
|
14
|
+
required: ['member_words', 'reason'], additionalProperties: false };
|
|
15
|
+
|
|
16
|
+
const text = value => ({ content: [{ type: 'text', text: value }], details: {} });
|
|
17
|
+
|
|
18
|
+
export function waiveChecksTool(self) {
|
|
19
|
+
return { name: 'waive_checks', label: 'Waive checks', parameters: PARAMETERS,
|
|
20
|
+
description: 'Ask the member to confirm that the repository checks are skipped for the code as it is now. Call it only when the member asked in this conversation to skip the tests or checks (quote them in member_words); never to end a turn sooner, never on your own judgment. The member answers on an approval card. Approved: the harness stops asking for checks on this exact code, and the turn reports that no check passed and that the member waived them. Change the code after it and the checks are required again. Pushing still asks the member as always.',
|
|
21
|
+
execute: async (id, args, signal, _onUpdate, ctx) => {
|
|
22
|
+
const run = self.run;
|
|
23
|
+
if (!run) throw Error('managed-checks-waiver-no-run: no member request is running.');
|
|
24
|
+
if (run.policy?.verify === 'off') return text('The Harness asks for no checks here: nothing to waive.');
|
|
25
|
+
const digest = await self.digest();
|
|
26
|
+
if (digest === null) throw Error('managed-checks-waiver-unreadable: the current code cannot be read, so a waiver could not be bound to it.');
|
|
27
|
+
await approve(self, id, signal, ctx, { toolName: 'waive_checks', rawAction: { digest }, commandPreview: `waive checks: ${args.member_words}`,
|
|
28
|
+
provider: 'harness', requestedScope: 'checks-waiver-once', reason: String(args.reason).slice(0, 300), riskClass: 'medium',
|
|
29
|
+
allowConsequence: 'The harness stops asking for checks on this exact code; the turn reports that no check passed and that you waived them.',
|
|
30
|
+
denyConsequence: 'The checks stay required; the agent runs them before it finishes.' },
|
|
31
|
+
{ title: 'Bỏ qua kiểm tra?', body: `Bạn đã nói: "${args.member_words}"\n\nBỏ qua: ${args.reason}\n\nĐồng ý: Harness không yêu cầu chạy kiểm tra cho đúng code hiện tại; lượt này ghi là chưa có kiểm tra nào qua và bạn đã miễn. Sửa code sau đó thì phải kiểm tra lại. Push vẫn hỏi bạn như thường.\nTừ chối: vẫn phải chạy kiểm tra trước khi xong.` });
|
|
32
|
+
run.waivedDigest = digest;
|
|
33
|
+
return text('The member waived the checks for the code as it is now. Do not run them again unless the member asks; say in your answer that the change is unverified.');
|
|
34
|
+
} };
|
|
35
|
+
}
|
|
@@ -75,11 +75,11 @@ export function stillAsks(self, reason) {
|
|
|
75
75
|
|
|
76
76
|
// One approval of the member (the dashboard card, else the Terminal). The
|
|
77
77
|
// member may allow it once, allow the same exact action for the rest of the
|
|
78
|
-
// conversation (never a handoff: its scope names it), deny it, or deny it and
|
|
78
|
+
// conversation (never a handoff or a waiver of checks: its scope names it), deny it, or deny it and
|
|
79
79
|
// stop the turn so the agent does not try again.
|
|
80
80
|
const CHOICES = { once: 'Đồng ý một lần', session: 'Đồng ý cho cả cuộc trò chuyện (đúng lệnh này)', deny: 'Từ chối', stop: 'Từ chối và dừng lượt này' };
|
|
81
81
|
export async function approve(self, id, signal, ctx, action, { title, body }) {
|
|
82
|
-
const grantable = !/handoff/.test(String(action.requestedScope ?? '')), key = `${action.toolName}\u0000${action.commandPreview ?? JSON.stringify(action.rawAction ?? {})}`;
|
|
82
|
+
const grantable = !/handoff|waiver/.test(String(action.requestedScope ?? '')), key = `${action.toolName}\u0000${action.commandPreview ?? JSON.stringify(action.rawAction ?? {})}`;
|
|
83
83
|
if (grantable && self.sessionApprovals?.has(key)) return;
|
|
84
84
|
const { piApprovalBroker } = await import('../runtime/inspection/approval-broker.ts');
|
|
85
85
|
const choices = ['once', ...(grantable ? ['session'] : []), 'deny', 'stop'];
|
|
@@ -526,7 +526,13 @@ var IMAGE_MIMES = {
|
|
|
526
526
|
webp: "image/webp",
|
|
527
527
|
bmp: "image/bmp",
|
|
528
528
|
ico: "image/x-icon",
|
|
529
|
-
avif: "image/avif"
|
|
529
|
+
avif: "image/avif",
|
|
530
|
+
svg: "image/svg+xml",
|
|
531
|
+
pdf: "application/pdf",
|
|
532
|
+
docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
533
|
+
xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
534
|
+
pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
|
|
535
|
+
zip: "application/zip"
|
|
530
536
|
};
|
|
531
537
|
var MAX_MEDIA_BYTES = 8 << 20;
|
|
532
538
|
function inspectWorkspaceMedia(root, relative, options) {
|
|
@@ -11,16 +11,20 @@ const MAX_SNAPSHOT = 16 * 1024 * 1024;
|
|
|
11
11
|
// `base`: the commit the patch starts from (the turn's starting HEAD), so a
|
|
12
12
|
// commit made during the turn stays part of its change; none: HEAD.
|
|
13
13
|
const BASE = /^[0-9a-f]{40}([0-9a-f]{24})?$/;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
// `bases`: in a folder of several repositories, where each started the turn.
|
|
15
|
+
async function worker(boundary, mode, scope = null, base = null, bases = null) {
|
|
16
|
+
const written = [];
|
|
17
|
+
const write = (prefix, value) => {
|
|
18
|
+
const name = `${prefix}-${randomUUID()}.json`;
|
|
19
|
+
fs.writeFileSync(path.join(boundary.temporary, name), JSON.stringify(value), { mode: 0o600, flag: 'wx' });
|
|
20
|
+
written.push(name);
|
|
21
|
+
};
|
|
22
|
+
if (scope) write('scope', [...scope]);
|
|
23
|
+
if (bases && Object.keys(bases).length) write('bases', bases);
|
|
20
24
|
let result;
|
|
21
|
-
const extra = [...
|
|
25
|
+
const extra = [...written, ...(typeof base === 'string' && BASE.test(base) ? [base] : [])];
|
|
22
26
|
try { result = await invokeReviewSnapshot(boundary, mode, extra); }
|
|
23
|
-
finally {
|
|
27
|
+
finally { for (const name of written) fs.rmSync(path.join(boundary.temporary, name), { force: true }); }
|
|
24
28
|
const text = textContent(result).trim();
|
|
25
29
|
if (result.details?.truncation?.truncated || text.includes('\n')) throw Error(/review-(patch|file|untracked)-limit/.exec(text)?.[0] ?? 'managed-review-patch-unreadable');
|
|
26
30
|
const [digest, bytes, name] = text.split(' ');
|
|
@@ -30,7 +34,17 @@ async function worker(boundary, mode, scope = null, base = null) {
|
|
|
30
34
|
|
|
31
35
|
// The digest of the patch a reviewer would see (diff against HEAD plus
|
|
32
36
|
// untracked files): whether a review is still current. Nothing else moves.
|
|
33
|
-
export async function readPatchDigest(boundary, scope = null, base = null) { return (await worker(boundary, 'digest', scope, base)).digest; }
|
|
37
|
+
export async function readPatchDigest(boundary, scope = null, base = null, bases = null) { return (await worker(boundary, 'digest', scope, base, bases)).digest; }
|
|
38
|
+
|
|
39
|
+
// Where each repository below a folder that is none itself stands now:
|
|
40
|
+
// { repository: commit }; empty inside one repository.
|
|
41
|
+
export async function readRepositoryHeads(boundary) {
|
|
42
|
+
try {
|
|
43
|
+
const { digest, bytes, name } = await worker(boundary, 'heads');
|
|
44
|
+
if (!/^heads-[0-9a-f-]{36}\.json$/.test(name ?? '')) return null;
|
|
45
|
+
return JSON.parse(readOnce(boundary, name, bytes, digest).toString('utf8'));
|
|
46
|
+
} catch { return null; }
|
|
47
|
+
}
|
|
34
48
|
|
|
35
49
|
// The commit HEAD names now, or null (no repository, no commit yet).
|
|
36
50
|
export async function readHead(boundary) {
|
|
@@ -69,8 +83,8 @@ export function emptySnapshot(snapshot) {
|
|
|
69
83
|
// it to the boundary's temporary directory and names it, with its digest, on
|
|
70
84
|
// its output; the file is read once, must match that digest (a file changed
|
|
71
85
|
// meanwhile never passes) and is removed.
|
|
72
|
-
export async function readPatchSnapshot(boundary, scope = null, base = null) {
|
|
73
|
-
const { digest, bytes, name } = await worker(boundary, 'file', scope, base);
|
|
86
|
+
export async function readPatchSnapshot(boundary, scope = null, base = null, bases = null) {
|
|
87
|
+
const { digest, bytes, name } = await worker(boundary, 'file', scope, base, bases);
|
|
74
88
|
if (!/^review-[0-9a-f-]{36}\.json$/.test(name ?? '')) throw Error('managed-review-patch-unreadable');
|
|
75
89
|
return { patch: readOnce(boundary, name, bytes, digest).toString('utf8'), digest };
|
|
76
90
|
}
|
|
@@ -79,8 +93,8 @@ export async function readPatchSnapshot(boundary, scope = null, base = null) {
|
|
|
79
93
|
// Compared before and after a command, it names the files that command
|
|
80
94
|
// changed, so a conversation answers for its own changes, not for another
|
|
81
95
|
// conversation's in the same folder.
|
|
82
|
-
export async function readChangedFiles(boundary, base = null) {
|
|
83
|
-
const { digest, bytes, name } = await worker(boundary, 'files', null, base);
|
|
96
|
+
export async function readChangedFiles(boundary, base = null, bases = null) {
|
|
97
|
+
const { digest, bytes, name } = await worker(boundary, 'files', null, base, bases);
|
|
84
98
|
if (!/^files-[0-9a-f-]{36}\.json$/.test(name ?? '')) throw Error('managed-review-patch-unreadable');
|
|
85
99
|
return new Map(Object.entries(JSON.parse(readOnce(boundary, name, bytes, digest).toString('utf8'))));
|
|
86
100
|
}
|
|
@@ -106,6 +120,7 @@ export function reviewUnavailableReason(message) {
|
|
|
106
120
|
if (/review-(patch|file|untracked)-limit|managed-review-patch-too-large/.test(text)) return 'too_large';
|
|
107
121
|
if (/not a git repository|Could not access 'HEAD'|managed-review-patch-unreadable/i.test(text)) return 'not_git';
|
|
108
122
|
if (/managed-helper-limit|helper_run_limit_reached/.test(text)) return 'limit';
|
|
123
|
+
if (/managed-runtime-changed/.test(text)) return 'runtime_changed';
|
|
109
124
|
return 'failed';
|
|
110
125
|
}
|
|
111
126
|
|
|
@@ -7,7 +7,7 @@ const quote = value => "'" + value.replaceAll("'", "'\"'\"'") + "'";
|
|
|
7
7
|
// Only fixed runtime snapshot reads preserve provenance. JSON tool arguments
|
|
8
8
|
// cannot forge this identity; freezing prevents substitution before dispatch.
|
|
9
9
|
export function invokeReviewSnapshot(boundary, mode, extra = []) {
|
|
10
|
-
if (!['head', 'since', 'branch-base', 'digest', 'file', 'files'].includes(mode)
|
|
10
|
+
if (!['head', 'heads', 'since', 'branch-base', 'digest', 'file', 'files'].includes(mode)
|
|
11
11
|
|| !Array.isArray(extra) || extra.some(value => typeof value !== 'string')) throw Error('review-request-invalid');
|
|
12
12
|
const args = Object.freeze({ command: [process.execPath, worker, mode, ...extra].map(quote).join(' '), timeout: 60 });
|
|
13
13
|
requests.add(args);
|