@piagent/platform 1.48.0 → 1.48.2
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 +28 -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 -28
- 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 +72 -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 -28
- 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 +10 -2
- 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/session.mjs +2 -2
- package/packages/piagent-core/managed/workflow.mjs +4 -4
- package/packages/piagent-core/package.json +1 -1
- package/packages/piagent-core/runtime/inspection/runtime-event-store.ts +5 -1
- package/packages/piagent-core/runtime/solver/runtime-features.ts +52 -10
- 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/{App-fZeIRoaD.js → App-Dg6Firq1.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/{GatewayApp-CpC4lgYK.js → GatewayApp-CCczgphI.js} +3 -3
- package/packages/piagent-webui/dist/client/assets/{InspectionApp-pD-BqBXm.js → InspectionApp-CEilR0FG.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/{SessionAgentWorkspace-3tM7Q6HH.js → SessionAgentWorkspace-yh0py16t.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/{SessionInspectorDrawer-BJ94aQ6y.js → SessionInspectorDrawer-C-18TcGH.js} +2 -2
- package/packages/piagent-webui/dist/client/assets/{TerminalPanel-CtZyb0tj.js → TerminalPanel-B2-YAz2x.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/{WorkspaceCodeEditor-BS_ZrjPN.js → WorkspaceCodeEditor-DAdMuw6x.js} +1 -1
- package/packages/piagent-webui/dist/client/assets/{WorkspaceExplorer-CkFBpcM7.js → WorkspaceExplorer-97MLNtEa.js} +3 -3
- package/packages/piagent-webui/dist/client/assets/{index-CNdhIouM.js → index-B8tL7HFz.js} +2 -2
- package/packages/piagent-webui/dist/client/assets/{transcript-view-model-CpEMY1xb.js → transcript-view-model-DqO4xO12.js} +1 -1
- package/packages/piagent-webui/dist/client/index.html +1 -1
- package/packages/piagent-webui/gateway/session-inspection-registry.ts +9 -4
- 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/docs-site/releases.json
CHANGED
|
@@ -1,4 +1,76 @@
|
|
|
1
1
|
[
|
|
2
|
+
{
|
|
3
|
+
"version": "1.48.2",
|
|
4
|
+
"date": "2026-10-30",
|
|
5
|
+
"status": "stable",
|
|
6
|
+
"title": {
|
|
7
|
+
"en": "Terminals load a new release without closing; only the member waives checks",
|
|
8
|
+
"vi": "Terminal nạp bản mới không cần đóng; chỉ member được bỏ qua kiểm tra"
|
|
9
|
+
},
|
|
10
|
+
"summary": {
|
|
11
|
+
"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.",
|
|
12
|
+
"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ẻ."
|
|
13
|
+
},
|
|
14
|
+
"requires": null,
|
|
15
|
+
"items": [
|
|
16
|
+
{
|
|
17
|
+
"kind": "new",
|
|
18
|
+
"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.",
|
|
19
|
+
"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."
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
"kind": "improved",
|
|
23
|
+
"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.",
|
|
24
|
+
"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ờ."
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"kind": "new",
|
|
28
|
+
"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.",
|
|
29
|
+
"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."
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"kind": "improved",
|
|
33
|
+
"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.",
|
|
34
|
+
"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ế độ."
|
|
35
|
+
}
|
|
36
|
+
]
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
"version": "1.48.1",
|
|
40
|
+
"date": "2026-10-30",
|
|
41
|
+
"status": "stable",
|
|
42
|
+
"title": {
|
|
43
|
+
"en": "Faster first replies on the dashboard and an instant Enter in the Terminal",
|
|
44
|
+
"vi": "Dashboard trả lời nhanh hơn, Enter trong Terminal hiện tin nhắn ngay"
|
|
45
|
+
},
|
|
46
|
+
"summary": {
|
|
47
|
+
"en": "New dashboard conversations start on the model and thinking level you use in the Terminal, and sending a message no longer waits on repository checks or disk flushes.",
|
|
48
|
+
"vi": "Cuộc trò chuyện mới trên dashboard dùng đúng model và mức suy nghĩ bạn dùng ở Terminal, và gửi tin nhắn không còn phải chờ kiểm tra repository hay ghi đĩa."
|
|
49
|
+
},
|
|
50
|
+
"requires": null,
|
|
51
|
+
"items": [
|
|
52
|
+
{
|
|
53
|
+
"kind": "fixed",
|
|
54
|
+
"en": "A new dashboard conversation starts on the model and thinking level set in the Terminal, instead of always the highest reasoning model, so a short question gets a short wait.",
|
|
55
|
+
"vi": "Cuộc trò chuyện mới trên dashboard bắt đầu bằng model và mức suy nghĩ đã chọn ở Terminal, thay vì luôn dùng model suy nghĩ cao nhất, nên câu hỏi ngắn được trả lời nhanh."
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
"kind": "fixed",
|
|
59
|
+
"en": "The first message of a new dashboard conversation is always sent, including on models without a thinking mode; it no longer stays behind a \"session was created\" notice.",
|
|
60
|
+
"vi": "Tin nhắn đầu tiên của cuộc trò chuyện mới trên dashboard luôn được gửi, kể cả với model không có chế độ suy nghĩ; không còn kẹt ở thông báo \"Session đã được tạo\"."
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
"kind": "improved",
|
|
64
|
+
"en": "Pressing Enter shows your message right away: repository status is read in the background between turns, not while the message waits to appear.",
|
|
65
|
+
"vi": "Nhấn Enter là tin nhắn hiện ngay: trạng thái repository được đọc ở nền giữa các lượt, không còn chặn lúc tin nhắn chờ hiển thị."
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
"kind": "improved",
|
|
69
|
+
"en": "Live session events are written without a disk flush per event, which removes a pause before each message and each streamed update.",
|
|
70
|
+
"vi": "Sự kiện của phiên được ghi mà không ép ghi đĩa cho từng sự kiện, bỏ một nhịp chờ trước mỗi tin nhắn và mỗi đoạn stream."
|
|
71
|
+
}
|
|
72
|
+
]
|
|
73
|
+
},
|
|
2
74
|
{
|
|
3
75
|
"version": "1.48.0",
|
|
4
76
|
"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.2" title="v1.48.2 docs · VI"><span class="dot"></span>v1.48.2</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.2" title="v1.48.2 docs · VI"><span class="dot"></span>v1.48.2</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.2" title="v1.48.2 docs · VI"><span class="dot"></span>v1.48.2</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.2" title="v1.48.2 docs · VI"><span class="dot"></span>v1.48.2</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.2" title="v1.48.2 docs · VI"><span class="dot"></span>v1.48.2</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.2 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.2
|
|
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.2" title="v1.48.2 docs · VI"><span class="dot"></span>v1.48.2</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,33 @@
|
|
|
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-2" data-release>
|
|
112
|
+
<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>
|
|
113
|
+
<div class="release-body">
|
|
114
|
+
<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>
|
|
115
|
+
<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>
|
|
116
|
+
<ul class="release-items">
|
|
117
|
+
<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>
|
|
118
|
+
<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>
|
|
119
|
+
<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>
|
|
120
|
+
<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>
|
|
121
|
+
</ul>
|
|
122
|
+
</div>
|
|
123
|
+
</article>
|
|
124
|
+
<article class="release" id="v1-48-1" data-release>
|
|
125
|
+
<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>
|
|
126
|
+
<div class="release-body">
|
|
127
|
+
<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>
|
|
128
|
+
<p>Cuộc trò chuyện mới trên dashboard dùng đúng model và mức suy nghĩ bạn dùng ở Terminal, và gửi tin nhắn không còn phải chờ kiểm tra repository hay ghi đĩa.</p>
|
|
129
|
+
<ul class="release-items">
|
|
130
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Nhấn Enter là tin nhắn hiện ngay: trạng thái repository được đọc ở nền giữa các lượt, không còn chặn lúc tin nhắn chờ hiển thị.</span></li>
|
|
131
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Sự kiện của phiên được ghi mà không ép ghi đĩa cho từng sự kiện, bỏ một nhịp chờ trước mỗi tin nhắn và mỗi đoạn stream.</span></li>
|
|
132
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Cuộc trò chuyện mới trên dashboard bắt đầu bằng model và mức suy nghĩ đã chọn ở Terminal, thay vì luôn dùng model suy nghĩ cao nhất, nên câu hỏi ngắn được trả lời nhanh.</span></li>
|
|
133
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Tin nhắn đầu tiên của cuộc trò chuyện mới trên dashboard luôn được gửi, kể cả với model không có chế độ suy nghĩ; không còn kẹt ở thông báo "Session đã được tạo".</span></li>
|
|
134
|
+
</ul>
|
|
135
|
+
</div>
|
|
136
|
+
</article>
|
|
137
|
+
<article class="release" id="v1-48-0" data-release>
|
|
112
138
|
<div class="release-meta"><a class="release-version" href="#v1-48-0">v1.48.0</a><time class="release-date" datetime="2026-10-30">30/10/2026</time></div>
|
|
113
139
|
<div class="release-body">
|
|
114
140
|
<h3 data-toc-skip id="v1-48-0-title">Bypass dừng ở bước bàn giao: mọi chế độ hỏi trước khi việc rời khỏi máy</h3>
|
|
@@ -394,37 +420,35 @@
|
|
|
394
420
|
</ul>
|
|
395
421
|
</div>
|
|
396
422
|
</article>
|
|
397
|
-
<article class="release" id="v1-43-0" data-release>
|
|
398
|
-
<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>
|
|
399
|
-
<div class="release-body">
|
|
400
|
-
<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>
|
|
401
|
-
<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>
|
|
402
|
-
<ul class="release-items">
|
|
403
|
-
<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>
|
|
404
|
-
<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>
|
|
405
|
-
<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>
|
|
406
|
-
</ul>
|
|
407
|
-
</div>
|
|
408
|
-
</article>
|
|
409
|
-
<article class="release" id="v1-42-1" data-release>
|
|
410
|
-
<div class="release-meta"><a class="release-version" href="#v1-42-1">v1.42.1</a><time class="release-date" datetime="2026-10-25">25/10/2026</time></div>
|
|
411
|
-
<div class="release-body">
|
|
412
|
-
<h3 data-toc-skip id="v1-42-1-title">Dashboard tải nhanh hơn, hash workspace dùng ít bộ nhớ hơn</h3>
|
|
413
|
-
<p>Mã và CSS tĩnh được nén khi truyền; giao diện phụ tải khi cần, có cách phục hồi khi tải lỗi.</p>
|
|
414
|
-
<ul class="release-items">
|
|
415
|
-
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Dashboard local gửi JS/CSS gzip khi trình duyệt hỗ trợ, dùng lại dữ liệu đã nén.</span></li>
|
|
416
|
-
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Gateway và giao diện inspection tải riêng; lỗi tải Settings nằm trong dialog có thể đóng. Theme và tùy chọn trên server được giữ nguyên.</span></li>
|
|
417
|
-
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Hash file workspace nhỏ dùng buffer theo kích thước file, vẫn kiểm tra toàn bộ nội dung và định danh file.</span></li>
|
|
418
|
-
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Gateway khởi động trên Windows native và lưu receipt workspace có chữ ký mà không áp kiểm tra quyền POSIX hoặc fsync thư mục lên file Windows.</span></li>
|
|
419
|
-
</ul>
|
|
420
|
-
</div>
|
|
421
|
-
</article>
|
|
422
423
|
</section>
|
|
423
424
|
<section class="section archive">
|
|
424
425
|
<h2 id="archive">Các bản trước</h2>
|
|
425
426
|
<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
427
|
<details class="release-archive">
|
|
427
|
-
<summary><span>Tháng 10/2026</span><span class="archive-count">
|
|
428
|
+
<summary><span>Tháng 10/2026</span><span class="archive-count">65</span></summary>
|
|
429
|
+
<div class="archive-row" id="v1-43-0">
|
|
430
|
+
<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>
|
|
431
|
+
<div class="archive-body">
|
|
432
|
+
<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>
|
|
433
|
+
<ul class="release-items">
|
|
434
|
+
<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>
|
|
435
|
+
<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>
|
|
436
|
+
<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>
|
|
437
|
+
</ul>
|
|
438
|
+
</div>
|
|
439
|
+
</div>
|
|
440
|
+
<div class="archive-row" id="v1-42-1">
|
|
441
|
+
<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>
|
|
442
|
+
<div class="archive-body">
|
|
443
|
+
<p><strong>Dashboard tải nhanh hơn, hash workspace dùng ít bộ nhớ hơn</strong> — Mã và CSS tĩnh được nén khi truyền; giao diện phụ tải khi cần, có cách phục hồi khi tải lỗi.</p>
|
|
444
|
+
<ul class="release-items">
|
|
445
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Dashboard local gửi JS/CSS gzip khi trình duyệt hỗ trợ, dùng lại dữ liệu đã nén.</span></li>
|
|
446
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Gateway và giao diện inspection tải riêng; lỗi tải Settings nằm trong dialog có thể đóng. Theme và tùy chọn trên server được giữ nguyên.</span></li>
|
|
447
|
+
<li data-kind="improved"><span class="kind kind-improved">Cải thiện</span><span>Hash file workspace nhỏ dùng buffer theo kích thước file, vẫn kiểm tra toàn bộ nội dung và định danh file.</span></li>
|
|
448
|
+
<li data-kind="fixed"><span class="kind kind-fixed">Sửa lỗi</span><span>Gateway khởi động trên Windows native và lưu receipt workspace có chữ ký mà không áp kiểm tra quyền POSIX hoặc fsync thư mục lên file Windows.</span></li>
|
|
449
|
+
</ul>
|
|
450
|
+
</div>
|
|
451
|
+
</div>
|
|
428
452
|
<div class="archive-row" id="v1-42-0">
|
|
429
453
|
<div class="archive-head"><a class="release-version" href="#v1-42-0">v1.42.0</a> <span class="release-date">25/10/2026</span></div>
|
|
430
454
|
<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.2" title="v1.48.2 docs · VI"><span class="dot"></span>v1.48.2</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.2" title="v1.48.2 docs · VI"><span class="dot"></span>v1.48.2</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": "da53dba99cba2d0d9f5adc6101fb1a49d058038cb5eca770de3bf8785de3290c"
|
|
261
261
|
}
|
|
262
262
|
],
|
|
263
263
|
"custodianComparisonRules": {
|
package/package.json
CHANGED
|
@@ -148,7 +148,7 @@ import { parentRoutingModeFromEnvironment, routingObjectiveFromEnvironment } fro
|
|
|
148
148
|
import { ModelSelectionProvenanceTracker } from "../runtime/model/model-selection-provenance.ts";
|
|
149
149
|
import type { TaskFeatures } from "../runtime/solver/solver-types.ts";
|
|
150
150
|
import { planRetrievalRoute } from "../runtime/context/retrieval-route-policy.ts";
|
|
151
|
-
import { evaluateRuntimeSolver } from "../runtime/solver/runtime-features.ts";
|
|
151
|
+
import { evaluateRuntimeSolver, refreshGitShape } from "../runtime/solver/runtime-features.ts";
|
|
152
152
|
import { SolverShadowRuntime, solverModeFromEnvironment } from "../runtime/solver/solver-shadow.ts";
|
|
153
153
|
import { TrajectoryRuntime } from "../runtime/trajectory/trajectory-runtime.ts";
|
|
154
154
|
import { parseApplyPatchTargets, registerApplyPatchTool } from "../runtime/tools/apply-patch-tool.ts";
|
|
@@ -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";
|
|
@@ -3386,6 +3387,11 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
3386
3387
|
});
|
|
3387
3388
|
const runtimeSnapshotCapture = new RuntimeSnapshotCapture(), runtimeVersions = readRuntimeVersionMetadata(PLATFORM_ROOT);
|
|
3388
3389
|
const solverShadow = solverMode === "off" ? undefined : new SolverShadowRuntime(solverMode);
|
|
3390
|
+
if (solverShadow) {
|
|
3391
|
+
// The solver's Git shape is read ahead of the prompt (runtime-features.ts).
|
|
3392
|
+
pi.on("session_start", (_event, ctx) => { void refreshGitShape(ctx.cwd); });
|
|
3393
|
+
pi.on("agent_settled", (_event, ctx) => { void refreshGitShape(ctx.cwd); });
|
|
3394
|
+
}
|
|
3389
3395
|
const modelRouteRuntime = new ModelRouteRuntime(parentRoutingMode, routingObjective);
|
|
3390
3396
|
const modelSelectionProvenance = new ModelSelectionProvenanceTracker();
|
|
3391
3397
|
const serviceTierRuntime = new ServiceTierRuntime({ environmentValue: process.env.PIAGENT_FAST_MODE });
|
|
@@ -4047,7 +4053,7 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4047
4053
|
}
|
|
4048
4054
|
|
|
4049
4055
|
const grants = sessionGrants.get(ctx.sessionManager.getSessionId()) ?? new Set<string>();
|
|
4050
|
-
const grantable = Boolean(pendingHumanApproval) && !/handoff/.test(String(pendingHumanApproval!.action.requestedScope));
|
|
4056
|
+
const grantable = Boolean(pendingHumanApproval) && !/handoff|waiver/.test(String(pendingHumanApproval!.action.requestedScope));
|
|
4051
4057
|
const grant = grantKey(event.toolName, typeof pendingHumanApproval?.action.commandPreview === "string" ? pendingHumanApproval.action.commandPreview : null, preparedInput.input);
|
|
4052
4058
|
if (pendingHumanApproval && grantable && grants.has(grant)) pendingHumanApproval = null;
|
|
4053
4059
|
if (pendingHumanApproval) {
|
|
@@ -4187,6 +4193,8 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
4187
4193
|
registerAgentResources(pi);
|
|
4188
4194
|
// A new release is asked about in the Terminal, as the dashboard does.
|
|
4189
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 });
|
|
4190
4198
|
// The Terminal's look (/style): Pi keeps the pick in its own settings.
|
|
4191
4199
|
registerStyleCommand(pi);
|
|
4192
4200
|
registerSessionCommands(pi, { ...registrationDeps, ...contextCommandApi });
|
|
@@ -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'];
|
|
@@ -29,7 +29,7 @@ import { HELPER_CALLS, HELPER_ROLES, helperRoles, helperPrompt, webPrompt, deleg
|
|
|
29
29
|
import { loadAgentResources } from './agent-skills.mjs';
|
|
30
30
|
import { loadPiagentThemes } from '../runtime/terminal/terminal-style.mjs';
|
|
31
31
|
import { restorePermission, recordBypass, permissionSetter } from './permission.mjs';
|
|
32
|
-
import { commandTools, servicesPrompt } from './command-tools.mjs'; import { attachMemory, memoryToolsFor, openRound, closeRound, prepareMemoryContext, trackMemoryLessons } from './memory.mjs';
|
|
32
|
+
import { commandTools, servicesPrompt } from './command-tools.mjs'; import { waiveChecksTool } from './check-waiver.mjs'; import { attachMemory, memoryToolsFor, openRound, closeRound, prepareMemoryContext, trackMemoryLessons } from './memory.mjs';
|
|
33
33
|
|
|
34
34
|
const PROVIDER = 'agent_watch_managed';
|
|
35
35
|
export const HELPER_BEAT_MS = 60_000;
|
|
@@ -129,7 +129,7 @@ export class ManagedSession {
|
|
|
129
129
|
if (roles.length) customTools.push({ name: 'delegate', label: 'Subagent', description: delegateDescription(roles) + SPEC_PROMPT,
|
|
130
130
|
parameters: delegateParameters(), // the brief and its structured fields (helper-settlement.mjs)
|
|
131
131
|
execute: (_id, args, signal) => self.delegate(delegateArgs(self, args), signal) });
|
|
132
|
-
customTools.push(sessionPlanTool(self), ...(roles.length ? [resolveTool(self)] : [])); // the objection ledger's decisions (ledger.mjs)
|
|
132
|
+
customTools.push(sessionPlanTool(self), waiveChecksTool(self), ...(roles.length ? [resolveTool(self)] : [])); // the member's waiver of checks (check-waiver.mjs), the objection ledger's decisions (ledger.mjs)
|
|
133
133
|
// The member decides what the request leaves open: numbered options, or their own words.
|
|
134
134
|
customTools.push(workflowContextTool(() => self.session.sessionManager));
|
|
135
135
|
customTools.push(askTool(self), ...memoryToolsFor(self, agentDir)); // team memory's tools, once Studio answered memory here (memory.mjs)
|
|
@@ -148,7 +148,7 @@ export function workflowPrompt(policy, checks) {
|
|
|
148
148
|
if (policy.plan !== 'off') lines.push(`- Plan: for work with several steps keep a checklist with update_plan and update it as you go. When the member asks for several items (plans, files, tickets), put every item in the checklist and work through all of them; do not end your turn to report between items.${policy.plan === 'require' ? ' For a complex task, file edits are refused until a plan exists. A checklist left with pending steps sends you back to the next one until every step is completed or deferred: if you cannot go on without the member, ask with ask_user. Mark a step deferred only when the member asked to leave it for later or it is no longer needed; never mark completed a step you did not do.' : ''}`);
|
|
149
149
|
if (policy.verify !== 'off') {
|
|
150
150
|
const list = checks.commands.length ? `${checks.commands.map(c => '`' + c + '`').join(', ')}${checks.source === 'detected' ? ' (detected; the repository declares none in AGENTS.md "## Checks")' : ''}` : 'none declared: choose the tests, type check or build that cover the change';
|
|
151
|
-
lines.push(`- Verify: after changing code, run the repository checks that cover the change and fix failures before you finish. Repository checks: ${list}.${policy.verify === 'require' ? ' The turn does not end until a check has passed on the final code.' : ''}
|
|
151
|
+
lines.push(`- Verify: after changing code, run the repository checks that cover the change and fix failures before you finish. Repository checks: ${list}.${policy.verify === 'require' ? ' The turn does not end until a check has passed on the final code.' : ''} Only the member may skip the checks: when they ask to, call waive_checks with their words; never skip them on your own.`);
|
|
152
152
|
}
|
|
153
153
|
// What each severity asks: blocking is fixed or argued, major decided, minor only listed.
|
|
154
154
|
const severities = ' Blocking findings: fix them, or reject one with resolve_objection and the reviewer judges your reason; a disagreement that remains goes to the member. Major findings: fix them or reject them with resolve_objection; no new review follows. Minor findings are listed for the member and need nothing.';
|
|
@@ -350,7 +350,7 @@ export async function completionGate(managed, run, signal) {
|
|
|
350
350
|
// The member declined the approval a check needed (a JDK, Docker, the
|
|
351
351
|
// network): asking again would only repeat the same answer.
|
|
352
352
|
if (policy.verify === 'require' && !run.verified && run.approvalDeclined && run.fixLoops > 0) verifyGaveUp = true;
|
|
353
|
-
if (policy.verify === 'require' && !run.verified && !run.docsOnly && !verifyGaveUp) {
|
|
353
|
+
if (policy.verify === 'require' && !run.verified && !run.docsOnly && !verifyGaveUp && run.waivedDigest !== digest) {
|
|
354
354
|
run.fixLoops += 1;
|
|
355
355
|
const list = run.checks.commands.length ? run.checks.commands.map(c => '`' + c + '`').join(', ') : 'the tests, type check or build that cover the change';
|
|
356
356
|
await send(`Harness process check: code changed in this turn, but no check has passed on the current code. Run the checks that cover your change (${list}) and fix what fails. If a check cannot run because the machine lacks something (a runtime such as a JDK, Docker, a database or another service, the network), request the approval that makes it run (run_with_network, run_with_docker, start_docker, run_on_host) or ask the member with ask_user, then run it; install or start nothing without that approval. If it fails for a reason unrelated to your change, say so plainly.`,
|
|
@@ -441,8 +441,8 @@ export async function completionGate(managed, run, signal) {
|
|
|
441
441
|
if (!run.changed && !run.disputes.length && !ledgerOf(run).length) return;
|
|
442
442
|
const finalPlan = currentPlan(session.sessionManager), planOpen = run.planUpdated ? finalPlan?.plan?.filter(p => p.status === 'pending' || p.status === 'in_progress').length ?? 0 : 0;
|
|
443
443
|
const status = { verified: run.verified, reviewed: run.reviewed, blockingOpen: run.blockingOpen, checks: run.checksRun, fixLoops: run.fixLoops,
|
|
444
|
-
...(planOpen ? { planOpen } : {}), ...(run.planSkipped ? { planSkipped: true } : {}), ...(run.disputes.length ? { disputes: run.disputes.length } : {}), ...(run.changed ? {} : { unchanged: true }) };
|
|
445
|
-
const words = [...(run.changed ? [run.verified ? 'a check passed on the final code' : policy.verify === 'off' ? null : run.docsOnly ? 'only documentation changed: no check needed' : 'no check passed on the final code',
|
|
444
|
+
...(planOpen ? { planOpen } : {}), ...(run.planSkipped ? { planSkipped: true } : {}), ...(!run.verified && run.waivedDigest === digest ? { checksWaived: true } : {}), ...(run.disputes.length ? { disputes: run.disputes.length } : {}), ...(run.changed ? {} : { unchanged: true }) };
|
|
445
|
+
const words = [...(run.changed ? [run.verified ? 'a check passed on the final code' : policy.verify === 'off' ? null : run.docsOnly ? 'only documentation changed: no check needed' : run.waivedDigest === digest ? 'no check passed on the final code: the member waived the checks' : 'no check passed on the final code',
|
|
446
446
|
run.reviewed ? (run.blockingOpen ? `review: ${run.blockingOpen} blocking issue(s) still open` : 'review: no blocking issue') : policy.review === 'off' ? null : run.reviewUnavailable ? `review could not run (${run.reviewUnavailableReason})` : 'not reviewed',
|
|
447
447
|
run.planSkipped ? 'code was changed before the required plan existed' : null, planOpen ? `plan: ${planOpen} step(s) not completed` : null] : []),
|
|
448
448
|
run.disputes.length ? `${run.disputes.length} disagreement(s) between the main agent and a subagent go to the member` : null, ledgerWords(run)].filter(Boolean);
|
|
@@ -252,7 +252,11 @@ export class RuntimeEventStore {
|
|
|
252
252
|
const flags = fs.constants.O_WRONLY | fs.constants.O_APPEND | (fs.constants.O_NOFOLLOW ?? 0)
|
|
253
253
|
| (creating ? fs.constants.O_CREAT | fs.constants.O_EXCL : 0);
|
|
254
254
|
const descriptor = fs.openSync(target, flags, 0o600);
|
|
255
|
-
|
|
255
|
+
// No fsync: it ran for every event, Terminal sessions included, and three of
|
|
256
|
+
// them sat between Enter and the message showing. A store belongs to one
|
|
257
|
+
// runtime instance, and one left damaged by a power cut only sends the
|
|
258
|
+
// dashboard back to a snapshot (resyncRequired).
|
|
259
|
+
try { fs.writeFileSync(descriptor, `${JSON.stringify(event)}\n`); fs.fchmodSync(descriptor, 0o600); } finally { fs.closeSync(descriptor); }
|
|
256
260
|
segment.count += 1; this.events.push(event); this.eventById.set(event.eventId, event);
|
|
257
261
|
if (candidate) this.emissionGuard.recordAccepted(candidate);
|
|
258
262
|
try { this.enforceRetention(); } catch { this.corruptions.push("event-retention-failed"); }
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
|
|
1
3
|
import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
|
|
2
4
|
|
|
3
5
|
import { gitEvidenceRootDetails, workingTreeHasChanges } from "../../extensions/workspace-evidence-roots.js";
|
|
@@ -8,17 +10,57 @@ import type { TaskFeatureInput } from "./task-features.ts";
|
|
|
8
10
|
import type { SolverShadowEvaluation } from "./solver-shadow.ts";
|
|
9
11
|
import { SolverShadowRuntime } from "./solver-shadow.ts";
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
13
|
+
type GitShape = { gitReady: boolean; dirtyTree: boolean };
|
|
14
|
+
|
|
15
|
+
function readGitShape(cwd: string): GitShape {
|
|
16
|
+
try {
|
|
17
|
+
const details = gitEvidenceRootDetails(cwd);
|
|
18
|
+
return { gitReady: details.roots.length > 0, dirtyTree: workingTreeHasChanges(cwd, details) };
|
|
19
|
+
} catch { return { gitReady: false, dirtyTree: true }; }
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// The Git shape runs `git rev-parse` (once per child repository in a parent
|
|
23
|
+
// folder) and `git status`. Read synchronously on every prompt it held the
|
|
24
|
+
// Terminal between Enter and the message showing, longer the larger the
|
|
25
|
+
// repository. It is now read in a child process when the session starts and
|
|
26
|
+
// after each run, and a prompt takes the last answer. Only a prompt with no
|
|
27
|
+
// answer yet reads it inline, as before.
|
|
28
|
+
const SHAPE_FRESH_MS = 5_000;
|
|
29
|
+
const SHAPE_PROBE = `import(${JSON.stringify(new URL("../../extensions/workspace-evidence-roots.js", import.meta.url).href)}).then((git) => {
|
|
30
|
+
let shape; try { const details = git.gitEvidenceRootDetails(process.argv[1]);
|
|
31
|
+
shape = { gitReady: details.roots.length > 0, dirtyTree: git.workingTreeHasChanges(process.argv[1], details) };
|
|
32
|
+
} catch { shape = { gitReady: false, dirtyTree: true }; }
|
|
33
|
+
process.stdout.write(JSON.stringify(shape));
|
|
34
|
+
});`;
|
|
35
|
+
const shapes = new Map<string, { at: number; shape: GitShape }>();
|
|
36
|
+
const probing = new Map<string, Promise<void>>();
|
|
37
|
+
|
|
38
|
+
export function refreshGitShape(cwd: string): Promise<void> {
|
|
39
|
+
const running = probing.get(cwd);
|
|
40
|
+
if (running) return running;
|
|
41
|
+
const startedAt = Date.now();
|
|
42
|
+
const probe = new Promise<void>((resolve) => {
|
|
43
|
+
execFile(process.execPath, ["--input-type=module", "-e", SHAPE_PROBE, cwd], { timeout: 60_000, maxBuffer: 4096, windowsHide: true }, (error, stdout) => {
|
|
44
|
+
try {
|
|
45
|
+
const shape = JSON.parse(String(stdout)) as GitShape;
|
|
46
|
+
if (!error && typeof shape.gitReady === "boolean" && typeof shape.dirtyTree === "boolean") shapes.set(cwd, { at: startedAt, shape });
|
|
47
|
+
} catch { /* the next prompt reads it inline */ }
|
|
48
|
+
resolve();
|
|
49
|
+
});
|
|
50
|
+
}).finally(() => probing.delete(cwd));
|
|
51
|
+
probing.set(cwd, probe);
|
|
52
|
+
return probe;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function gitShape(cwd: string): GitShape {
|
|
56
|
+
const cached = shapes.get(cwd);
|
|
57
|
+
if (!cached) {
|
|
58
|
+
const shape = readGitShape(cwd);
|
|
59
|
+
shapes.set(cwd, { at: Date.now(), shape });
|
|
60
|
+
return shape;
|
|
20
61
|
}
|
|
21
|
-
|
|
62
|
+
if (Date.now() - cached.at > SHAPE_FRESH_MS) void refreshGitShape(cwd);
|
|
63
|
+
return cached.shape;
|
|
22
64
|
}
|
|
23
65
|
|
|
24
66
|
export function runtimeTaskFeatureInput(options: {
|