@piagent/platform 1.1.7 → 1.1.9
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 +16 -0
- package/README.md +1 -1
- package/docs/capability-packs.md +1 -1
- package/docs/command-reference-vietnamese.md +3 -2
- package/docs/distribution-standard.md +7 -7
- package/docs/operator-manual-vietnamese.md +7 -7
- package/docs/publishing-for-teams.md +2 -0
- package/docs/release-install-policy.md +6 -6
- package/docs/security-threat-model.md +11 -1
- package/docs/team-onboarding.md +11 -3
- package/docs-site/index.html +2 -2
- package/package.json +2 -2
- package/packages/piagent-core/capabilities/capability-core.js +6 -1
- package/packages/piagent-core/extensions/piagent-guard.ts +22 -0
- package/packages/piagent-core/extensions/update-check.js +211 -0
- package/packages/piagent-core/package.json +1 -1
- package/scripts/install-global.sh +3 -3
- package/scripts/team-doctor.sh +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
This file records release-facing changes for Pi Agent Platform. Copy the relevant version block into GitHub Releases when publishing a tag.
|
|
4
4
|
|
|
5
|
+
## v1.1.9 - 2026-07-28
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- The update notice reaches the install path people actually use. v1.1.8 decided a platform tree was a maintainer's working copy when it found a `.git` directory in it — but `pi install git:...` clones the repository, so an ordinary install carries a `.git` and every other file a working copy carries. There is no mark inside the tree that separates them, which meant the notice never appeared for anyone who installed the documented way.
|
|
10
|
+
|
|
11
|
+
What separates them is where they sit: Pi puts packages it installed under its own agent directory, and npm puts the global helper under `node_modules`. A tree anywhere else is a working copy and is still told nothing. `PI_CODING_AGENT_DIR` is honoured, and both paths are resolved before comparison, because a home reached through a symlink is ordinary — macOS reaches `/var` that way — and comparing a real path against a symlinked one made an install look like it was somewhere else.
|
|
12
|
+
|
|
13
|
+
## v1.1.8 - 2026-07-28
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- Pi says when a release is out, and names the command that takes it. The notice appears in the session-start line as `Piagent update available: 1.1.7 -> 1.1.8. Run \`piagent-update\` to move this machine to it.` Nobody has to remember to go and check, which until now was the only way to find out.
|
|
18
|
+
|
|
19
|
+
It costs the session nothing. The session reads a cache and, when that cache is older than a day, leaves a detached `npm view` behind to refresh it — so the first session after a release may still be quiet and the next one carries the notice. This is the only network traffic the guard originates, it sends nothing about the project, and the registry's answer reaches the terminal only if it is exactly `MAJOR.MINOR.PATCH`, so neither a hostile registry nor an edited cache can put chosen text in front of an operator. A checkout is never told to update. `PIAGENT_NO_UPDATE_CHECK=1` switches it off.
|
|
20
|
+
|
|
5
21
|
## v1.1.7 - 2026-07-28
|
|
6
22
|
|
|
7
23
|
A platform update is one global install. It was not behaving like one: every project that selected capability packs stopped working after a release until its profile was reapplied by hand, and the policy a release corrected never reached a project that had already onboarded.
|
package/README.md
CHANGED
|
@@ -283,7 +283,7 @@ This repository intentionally excludes:
|
|
|
283
283
|
|
|
284
284
|
## Maturity
|
|
285
285
|
|
|
286
|
-
The current package version is read from package metadata and release tags. Personal machines may follow the unpinned package source when accepting ongoing updates; production/team quickstarts and committed project settings should pin an explicit tag such as `v1.1.
|
|
286
|
+
The current package version is read from package metadata and release tags. Personal machines may follow the unpinned package source when accepting ongoing updates; production/team quickstarts and committed project settings should pin an explicit tag such as `v1.1.9` or a reviewed commit.
|
|
287
287
|
|
|
288
288
|
Ready for:
|
|
289
289
|
|
package/docs/capability-packs.md
CHANGED
|
@@ -240,7 +240,7 @@ Thư mục nguồn phải chứa `packs/`, nằm trong project, và không chứ
|
|
|
240
240
|
piagent-capabilities vendor --profile .pi/piagent-profile.json
|
|
241
241
|
```
|
|
242
242
|
|
|
243
|
-
Lệnh này ghi vào `.pi/capability-vendor/<name>/` và in digest để review trước khi commit. Đây là chỗ duy nhất chạm network. Resolve và guard chỉ đọc thứ đã có trên đĩa, nên pack không đổi được giữa lúc review và lúc chạy. Nguồn khai mà chưa vendor thì resolve fail — không im lặng chạy với ít pack hơn profile yêu cầu.
|
|
243
|
+
Lệnh này ghi vào `.pi/capability-vendor/<name>/` và in digest để review trước khi commit. Đây là chỗ duy nhất trong đường capability chạm network — update check là đường riêng, xem `docs/security-threat-model.md`. Resolve và guard chỉ đọc thứ đã có trên đĩa, nên pack không đổi được giữa lúc review và lúc chạy. Nguồn khai mà chưa vendor thì resolve fail — không im lặng chạy với ít pack hơn profile yêu cầu.
|
|
244
244
|
|
|
245
245
|
### Vẫn deny by default
|
|
246
246
|
|
|
@@ -419,12 +419,13 @@ Các lệnh này chạy ngoài Pi.
|
|
|
419
419
|
| Command | Dùng khi nào |
|
|
420
420
|
|---|---|
|
|
421
421
|
| `npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.82.0` | Cài Pi CLI tương thích với release hiện tại. |
|
|
422
|
-
| `npm install -g --ignore-scripts @piagent/platform@1.1.
|
|
423
|
-
| `pi install git:github.com/Vt-mmm/piagent@v1.1.
|
|
422
|
+
| `npm install -g --ignore-scripts @piagent/platform@1.1.9` | Cài terminal helper `piagent-*` từ release tag hiện tại. |
|
|
423
|
+
| `pi install git:github.com/Vt-mmm/piagent@v1.1.9` | Cài pinned release khi cần reproducible team setup. |
|
|
424
424
|
| `pi install git:github.com/Vt-mmm/piagent` | Cài latest package platform cho máy cá nhân/sandbox. |
|
|
425
425
|
| `piagent-update --check` | Báo version hiện tại vs version sẽ lên cho cả ba thành phần; không cài gì. |
|
|
426
426
|
| `piagent-update` | Full update một lệnh: Pi host → npm-global helper → Pi package, đúng thứ tự release yêu cầu. Thêm `--project <path>` để chạy doctor sau. |
|
|
427
427
|
| `piagent-update --version X.Y.Z` | Update tới đúng một release thay vì latest; dùng cho rollout theo lô hoặc rollback. |
|
|
428
|
+
| `PIAGENT_NO_UPDATE_CHECK=1` | Tắt notice "có bản mới" ở đầu session Pi. Mặc định bật, hỏi registry nhiều nhất một lần mỗi 24 giờ ở tiến trình nền. |
|
|
428
429
|
| Cài exact Pi host của release, rồi `npm install -g --ignore-scripts @piagent/platform@X.Y.Z` và `piagent-install --stable` | Sequence thủ công tương đương. Thứ tự bắt buộc: `piagent-install` fail nếu Pi host lệch bản pin và không tự cài host. Version pin của từng release nằm trong [release/install policy](release-install-policy.md). |
|
|
429
430
|
| Cài exact Pi host ghi trong release cũ, rồi helper `vPREVIOUS` và `piagent-install --stable` | Full rollback; đánh giá dependency risk của host cũ trước khi hạ version. |
|
|
430
431
|
| `piagent-install --stable --dry-run` | Preview Pi package matching với helper hiện tại; stable resolve tag → commit SHA. |
|
|
@@ -14,9 +14,9 @@ Repo này phải chạy được cho nhiều project/domain khác nhau. Vì vậ
|
|
|
14
14
|
|
|
15
15
|
| Use case | Package source |
|
|
16
16
|
|---|---|
|
|
17
|
-
| Team pinned release | `git:github.com/Vt-mmm/piagent@v1.1.
|
|
17
|
+
| Team pinned release | `git:github.com/Vt-mmm/piagent@v1.1.9` |
|
|
18
18
|
| Personal/sandbox dev | `git:github.com/Vt-mmm/piagent` |
|
|
19
|
-
| Registry distribution | `npm:@piagent/platform@1.1.
|
|
19
|
+
| Registry distribution | `npm:@piagent/platform@1.1.9` |
|
|
20
20
|
| Enterprise npm (fork under another scope) | `npm:@your-scope/platform@x.y.z` |
|
|
21
21
|
| Local platform dev | `/path/to/piagent` |
|
|
22
22
|
|
|
@@ -26,7 +26,7 @@ Latest tiện cho máy cá nhân muốn nhận cập nhật nhanh. Pin tag/commi
|
|
|
26
26
|
|
|
27
27
|
| Channel | Command | Target | Policy |
|
|
28
28
|
|---|---|---|---|
|
|
29
|
-
| `stable` | `bash scripts/install-global.sh --stable` | Helper release tag resolved to commit SHA, currently `v1.1.
|
|
29
|
+
| `stable` | `bash scripts/install-global.sh --stable` | Helper release tag resolved to commit SHA, currently `v1.1.9` | Install the Pi package matching the helper. |
|
|
30
30
|
| `exact` | `bash scripts/install-global.sh --version vX.Y.Z --resolve-tag` | Requested tag resolved to commit SHA | Pi-package-only rollout, rollback, and incident recovery. |
|
|
31
31
|
| `dev` | `bash scripts/install-global.sh --dev` | Moving Git source | Personal/sandbox only; do not commit into project settings. |
|
|
32
32
|
| `local` | `bash scripts/install-global.sh --local` | Current checkout path | Platform development only. |
|
|
@@ -53,7 +53,7 @@ Root `package.json` có `pi` manifest trỏ tới:
|
|
|
53
53
|
Do đó team có thể:
|
|
54
54
|
|
|
55
55
|
```bash
|
|
56
|
-
pi install git:github.com/Vt-mmm/piagent@v1.1.
|
|
56
|
+
pi install git:github.com/Vt-mmm/piagent@v1.1.9
|
|
57
57
|
```
|
|
58
58
|
|
|
59
59
|
Không cần biết internal folder `packages/piagent-core`. Source không pin chỉ dành cho personal/sandbox như bảng channel ở trên.
|
|
@@ -65,12 +65,12 @@ Team nên install global package một lần:
|
|
|
65
65
|
```bash
|
|
66
66
|
node --version # >= 22.19.0
|
|
67
67
|
npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.82.0
|
|
68
|
-
npm install -g --ignore-scripts @piagent/platform@1.1.
|
|
68
|
+
npm install -g --ignore-scripts @piagent/platform@1.1.9
|
|
69
69
|
piagent-install --stable --dry-run
|
|
70
70
|
piagent-install --stable
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
`pi install git:github.com/Vt-mmm/piagent@v1.1.
|
|
73
|
+
`pi install git:github.com/Vt-mmm/piagent@v1.1.9` vẫn hợp lệ nếu chỉ cần cài Pi package. Lệnh đó không tự tạo các binary terminal `piagent-*`; muốn có helper global thì dùng `npm install -g --ignore-scripts @piagent/platform@1.1.9`.
|
|
74
74
|
|
|
75
75
|
Support matrix hiện tại: macOS Apple Silicon + Bash và Linux x64 + Bash đã được verify; macOS Intel + Bash và Linux ARM64 + Bash là supported target cần chạy smoke trước rollout; native Windows chưa phải target rollout team; WSL2 experimental. Chi tiết và version runtime nằm trong [release/install policy](release-install-policy.md).
|
|
76
76
|
|
|
@@ -103,7 +103,7 @@ Nếu muốn commit sẵn `.pi/piagent-profile.json` vào repo hoặc bootstrap
|
|
|
103
103
|
```bash
|
|
104
104
|
bash scripts/setup.sh /path/to/project \
|
|
105
105
|
--profile be-readonly-fe \
|
|
106
|
-
--package-source git:github.com/Vt-mmm/piagent@v1.1.
|
|
106
|
+
--package-source git:github.com/Vt-mmm/piagent@v1.1.9 \
|
|
107
107
|
--mcp-preset core \
|
|
108
108
|
--subagents-preset safe
|
|
109
109
|
```
|
|
@@ -18,12 +18,12 @@ Support matrix release hiện tại: macOS Apple Silicon + Bash và Linux x64 +
|
|
|
18
18
|
```bash
|
|
19
19
|
node --version # >= 22.19.0
|
|
20
20
|
npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.82.0
|
|
21
|
-
npm install -g --ignore-scripts @piagent/platform@1.1.
|
|
21
|
+
npm install -g --ignore-scripts @piagent/platform@1.1.9
|
|
22
22
|
piagent-install --stable --dry-run
|
|
23
23
|
piagent-install --stable
|
|
24
24
|
```
|
|
25
25
|
|
|
26
|
-
Khi seed `.pi/settings.json` cho team/repo cần audit lặp lại, giữ package source dạng pinned tag như `git:github.com/Vt-mmm/piagent@v1.1.
|
|
26
|
+
Khi seed `.pi/settings.json` cho team/repo cần audit lặp lại, giữ package source dạng pinned tag như `git:github.com/Vt-mmm/piagent@v1.1.9`. Máy cá nhân có thể dùng `git:github.com/Vt-mmm/piagent` để theo latest.
|
|
27
27
|
|
|
28
28
|
Nếu đang ở source checkout của platform, dùng helper theo channel để preview trước khi đổi:
|
|
29
29
|
|
|
@@ -99,7 +99,7 @@ install package once
|
|
|
99
99
|
|
|
100
100
|
```bash
|
|
101
101
|
npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.82.0
|
|
102
|
-
npm install -g --ignore-scripts @piagent/platform@1.1.
|
|
102
|
+
npm install -g --ignore-scripts @piagent/platform@1.1.9
|
|
103
103
|
piagent-install --stable --dry-run
|
|
104
104
|
piagent-install --stable
|
|
105
105
|
```
|
|
@@ -281,7 +281,7 @@ Không phải daily default. Dùng khi muốn tạo sẵn `.pi` files cho projec
|
|
|
281
281
|
bash /path/to/piagent/scripts/setup.sh /path/to/project \
|
|
282
282
|
--project-only \
|
|
283
283
|
--profile auto \
|
|
284
|
-
--package-source git:github.com/Vt-mmm/piagent@v1.1.
|
|
284
|
+
--package-source git:github.com/Vt-mmm/piagent@v1.1.9 \
|
|
285
285
|
--mcp-preset core \
|
|
286
286
|
--subagents-preset safe
|
|
287
287
|
```
|
|
@@ -854,8 +854,8 @@ Watchdog là optional adversarial reviewer ở cuối turn, không bật mặc
|
|
|
854
854
|
|
|
855
855
|
| Command | Dùng để |
|
|
856
856
|
|---|---|
|
|
857
|
-
| `npm install -g --ignore-scripts @piagent/platform@1.1.
|
|
858
|
-
| `pi install git:github.com/Vt-mmm/piagent@v1.1.
|
|
857
|
+
| `npm install -g --ignore-scripts @piagent/platform@1.1.9` | Cài terminal helper `piagent-*` từ release tag hiện tại. |
|
|
858
|
+
| `pi install git:github.com/Vt-mmm/piagent@v1.1.9` | Install pinned release cho reproducible team setup. |
|
|
859
859
|
| `pi install git:github.com/Vt-mmm/piagent` | Install latest platform package cho máy cá nhân/sandbox. |
|
|
860
860
|
| Cài exact Pi host của release, rồi `npm install -g --ignore-scripts @piagent/platform@X.Y.Z` và `piagent-install --stable` | Full update: đồng bộ host, terminal helper và Pi package. Mỗi release pin một Pi host chính xác; lấy đúng version của release đang cài trong [release/install policy](release-install-policy.md). |
|
|
861
861
|
| Cài exact Pi host ghi trong release cũ, rồi helper `vPREVIOUS` và `piagent-install --stable` | Full rollback; đánh giá lại dependency findings của host cũ trước khi hạ version. |
|
|
@@ -952,7 +952,7 @@ Mở lại Pi session sau khi install.
|
|
|
952
952
|
Cài lại terminal helper đúng release rồi kiểm tra `PATH`:
|
|
953
953
|
|
|
954
954
|
```bash
|
|
955
|
-
npm install -g --ignore-scripts @piagent/platform@1.1.
|
|
955
|
+
npm install -g --ignore-scripts @piagent/platform@1.1.9
|
|
956
956
|
command -v piagent-install
|
|
957
957
|
```
|
|
958
958
|
|
|
@@ -50,6 +50,8 @@ pi install /path/to/piagent
|
|
|
50
50
|
- `1.1.5`: thêm `piagent-update` — một lệnh update cả Pi host, terminal helper và Pi package đúng thứ tự.
|
|
51
51
|
- `1.1.6`: `be-readonly-fe` giữ được backend read-only trong monorepo, detect FE/BE đọc cả workspace, và rule detect gộp về một chỗ.
|
|
52
52
|
- `1.1.7`: update global không còn chặn project đang chạy — lock chỉ block khi grant thật sự đổi, và profile dạng `extends` nhận policy từ platform đang cài thay vì giữ bản copy lúc onboard.
|
|
53
|
+
- `1.1.8`: Pi báo ngay ở đầu session khi có release mới, kèm lệnh chạy update.
|
|
54
|
+
- `1.1.9`: notice update hiện đúng trên bản cài bằng `pi install git:` — bản cài nhận diện theo vị trí thư mục, không theo `.git`.
|
|
53
55
|
|
|
54
56
|
## Không publish
|
|
55
57
|
|
|
@@ -10,7 +10,7 @@ This file is the canonical install, update, rollback, and release checklist. Oth
|
|
|
10
10
|
|
|
11
11
|
All supported environments require Node.js `>=22.19.0` and Pi Coding Agent `0.82.0`. The Pi host is installed as a Node CLI; Pi Agent Platform still defines its own release matrix because the terminal helpers and shell policy rely on Bash/POSIX behavior.
|
|
12
12
|
|
|
13
|
-
| Surface | Status for v1.1.
|
|
13
|
+
| Surface | Status for v1.1.9 | Rollout guidance |
|
|
14
14
|
|---|---|---|
|
|
15
15
|
| macOS Apple Silicon (`darwin/arm64`) + Bash | Verified for this release. | Safe default for team rollout after normal project smoke tests. |
|
|
16
16
|
| Linux x64 + Bash | Verified in GitHub Actions. | Safe default for CI/server usage after normal project smoke tests. |
|
|
@@ -33,7 +33,7 @@ These three components are versioned independently. A full install, update, or r
|
|
|
33
33
|
|
|
34
34
|
| Channel | Source shape | Mutability | Use when |
|
|
35
35
|
|---|---|---:|---|
|
|
36
|
-
| `stable` | `git:github.com/Vt-mmm/piagent@<resolved-commit-sha>` from `v1.1.
|
|
36
|
+
| `stable` | `git:github.com/Vt-mmm/piagent@<resolved-commit-sha>` from `v1.1.9` | Fixed after resolution | Default for team rollout. |
|
|
37
37
|
| `exact` | Tag, reviewed commit, or a tag resolved with `--resolve-tag` | Fixed when using a commit SHA | Pi-package-only roll forward, rollback, or reproduction. |
|
|
38
38
|
| `dev` | `git:github.com/Vt-mmm/piagent` | Moving | Personal machine or sandbox only. |
|
|
39
39
|
| `local` | `/path/to/piagent` | Local workspace | Platform development and dry-run validation. |
|
|
@@ -53,7 +53,7 @@ Use this flow when the team needs both terminal commands and the Pi package:
|
|
|
53
53
|
```bash
|
|
54
54
|
node --version # >= 22.19.0
|
|
55
55
|
npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.82.0
|
|
56
|
-
npm install -g --ignore-scripts @piagent/platform@1.1.
|
|
56
|
+
npm install -g --ignore-scripts @piagent/platform@1.1.9
|
|
57
57
|
piagent-install --stable --dry-run
|
|
58
58
|
piagent-install --stable
|
|
59
59
|
```
|
|
@@ -61,8 +61,8 @@ piagent-install --stable
|
|
|
61
61
|
The stable preview and apply output includes:
|
|
62
62
|
|
|
63
63
|
```text
|
|
64
|
-
currentRelease: v1.1.
|
|
65
|
-
tag: v1.1.
|
|
64
|
+
currentRelease: v1.1.9 (helper package version)
|
|
65
|
+
tag: v1.1.9
|
|
66
66
|
resolvedCommit: <40-char-sha>
|
|
67
67
|
source: git:github.com/Vt-mmm/piagent@<40-char-sha>
|
|
68
68
|
```
|
|
@@ -79,7 +79,7 @@ bash scripts/install-global.sh --stable
|
|
|
79
79
|
Use this only when terminal commands are not needed:
|
|
80
80
|
|
|
81
81
|
```bash
|
|
82
|
-
pi install git:github.com/Vt-mmm/piagent@v1.1.
|
|
82
|
+
pi install git:github.com/Vt-mmm/piagent@v1.1.9
|
|
83
83
|
```
|
|
84
84
|
|
|
85
85
|
Direct `pi install` does not create `piagent-*` commands on `PATH`.
|
|
@@ -21,7 +21,7 @@ This document covers the packaged guard, project profiles, capability locks, ins
|
|
|
21
21
|
- The operator, operating-system account, Pi host, and explicitly trusted project repository are trusted to execute code.
|
|
22
22
|
- Project-local Pi resources are loaded only after Pi project trust or an explicit operator override.
|
|
23
23
|
- A human remains available to approve destructive and external-provider actions.
|
|
24
|
-
- Supported release verification covers macOS Apple Silicon + Bash, Linux x64 + Bash, Node.js `>=22.19.0`, and the exact Pi host version declared by the release. macOS Intel + Bash and Linux ARM64 + Bash are supported targets that need local smoke verification before broad rollout. Native Windows is not a team-rollout target for v1.1.
|
|
24
|
+
- Supported release verification covers macOS Apple Silicon + Bash, Linux x64 + Bash, Node.js `>=22.19.0`, and the exact Pi host version declared by the release. macOS Intel + Bash and Linux ARM64 + Bash are supported targets that need local smoke verification before broad rollout. Native Windows is not a team-rollout target for v1.1.9, and WSL2 is experimental/unverified.
|
|
25
25
|
- Registry, GitHub, model-provider, MCP-provider, and Vercel controls are external dependencies. Their account security and platform guarantees are not replaced by this repository.
|
|
26
26
|
|
|
27
27
|
## Threat actors and failure modes
|
|
@@ -55,6 +55,16 @@ The final category is outside the containment capability of the Piagent guard. I
|
|
|
55
55
|
|
|
56
56
|
`read-only`, `workspace-write`, and `trusted-full-access` change the allowed working scope; they do not disable protected paths, secret redaction, capability integrity, destructive confirmation, or external-provider confirmation. `trusted-full-access` is intended for an already trusted repository in an externally safe environment. It is not a bypass or sandbox mode.
|
|
57
57
|
|
|
58
|
+
## Outbound network from a session
|
|
59
|
+
|
|
60
|
+
A Pi session makes one outbound request of its own: at most once every 24 hours it leaves a detached `npm view @piagent/platform version` behind to learn whether a newer release exists. This is the only network traffic the guard originates.
|
|
61
|
+
|
|
62
|
+
What it sends is an npm registry request for a public package and nothing else — no project path, no repository name, no profile, no telemetry. The registry reply reaches the terminal only if it matches `MAJOR.MINOR.PATCH` exactly; anything else is discarded rather than displayed, so a hostile or compromised registry response cannot become a line of attacker-chosen text in the operator's terminal. The answer is cached at `~/.pi/piagent-update-check.json`, an ordinary user-writable file whose worst case is suppressing the notice.
|
|
63
|
+
|
|
64
|
+
The session never waits on it: the request runs in a detached process with no inherited stdio, and the notice appears on the session after the one that refreshed the cache. A checkout is never told to update.
|
|
65
|
+
|
|
66
|
+
Set `PIAGENT_NO_UPDATE_CHECK=1` to switch it off. Nothing else changes.
|
|
67
|
+
|
|
58
68
|
## Security verification
|
|
59
69
|
|
|
60
70
|
Release gates include policy regression tests, TypeScript checking, runtime smoke tests, redaction benchmarks, package-content inspection, release-identity checks, installer tests, exact Pi host/add-on dependency audit, and CI on Linux x64 plus the current macOS runner. CodeQL covers JavaScript/TypeScript and GitHub Actions.
|
package/docs/team-onboarding.md
CHANGED
|
@@ -9,7 +9,7 @@ Một thành viên mới không cần biết local path của maintainer. Luồn
|
|
|
9
9
|
```bash
|
|
10
10
|
node --version # >= 22.19.0
|
|
11
11
|
npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.82.0
|
|
12
|
-
npm install -g --ignore-scripts @piagent/platform@1.1.
|
|
12
|
+
npm install -g --ignore-scripts @piagent/platform@1.1.9
|
|
13
13
|
piagent-install --stable
|
|
14
14
|
cd /path/to/project
|
|
15
15
|
pi
|
|
@@ -42,7 +42,7 @@ Mặc định team dùng stable helper:
|
|
|
42
42
|
```bash
|
|
43
43
|
node --version # >= 22.19.0
|
|
44
44
|
npm install -g --ignore-scripts @earendil-works/pi-coding-agent@0.82.0
|
|
45
|
-
npm install -g --ignore-scripts @piagent/platform@1.1.
|
|
45
|
+
npm install -g --ignore-scripts @piagent/platform@1.1.9
|
|
46
46
|
piagent-install --stable --dry-run
|
|
47
47
|
piagent-install --stable
|
|
48
48
|
```
|
|
@@ -70,7 +70,15 @@ piagent-update --check
|
|
|
70
70
|
piagent-update --project /path/to/project
|
|
71
71
|
```
|
|
72
72
|
|
|
73
|
-
`--check` chỉ báo version, không đụng gì. Lên đúng một bản cụ thể thì `piagent-update --version 1.1.
|
|
73
|
+
`--check` chỉ báo version, không đụng gì. Lên đúng một bản cụ thể thì `piagent-update --version 1.1.9`.
|
|
74
|
+
|
|
75
|
+
Không cần ai nhớ đi kiểm tra: khi có release mới, Pi tự báo ngay ở dòng notice lúc mở session, kèm luôn lệnh chạy.
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
Piagent update available: 1.1.7 -> 1.1.8. Run `piagent-update` to move this machine to it.
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Version mới nhất được hỏi npm registry nhiều nhất một lần mỗi 24 giờ, ở tiến trình nền tách rời, nên session không chờ gì cả — lần mở đầu tiên sau khi có bản mới có thể chưa thấy notice, lần sau sẽ thấy. Checkout của maintainer không bao giờ được báo. Tắt bằng `PIAGENT_NO_UPDATE_CHECK=1`; chi tiết ở `docs/security-threat-model.md`.
|
|
74
82
|
|
|
75
83
|
Sequence thủ công vẫn dùng được, và bắt buộc theo thứ tự này — `piagent-install` **fail** nếu Pi host lệch bản pin, nó không tự nâng host:
|
|
76
84
|
|
package/docs-site/index.html
CHANGED
|
@@ -798,7 +798,7 @@
|
|
|
798
798
|
<span>Pi Agent Platform</span>
|
|
799
799
|
</a>
|
|
800
800
|
<div class="top-actions">
|
|
801
|
-
<span class="pill"><span class="pill-dot"></span>v1.1.
|
|
801
|
+
<span class="pill"><span class="pill-dot"></span>v1.1.9 docs</span>
|
|
802
802
|
<a class="button social" href="https://github.com/Vt-mmm/piagent" target="_blank" rel="noopener noreferrer" aria-label="Mở GitHub repository">
|
|
803
803
|
<svg viewBox="0 0 24 24" fill="none" aria-hidden="true">
|
|
804
804
|
<path d="M7 17 17 7M9 7h8v8" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
|
@@ -934,7 +934,7 @@
|
|
|
934
934
|
<article class="step">
|
|
935
935
|
<div>
|
|
936
936
|
<h3>Cài — hai lệnh</h3>
|
|
937
|
-
<p>Cần Node.js 22.19.0 trở lên. Không cần cài Pi Coding Agent trước: <span class="inline-code">piagent-setup</span> tự cài đúng bản <span class="inline-code">0.82.0</span> mà release <span class="inline-code">v1.1.
|
|
937
|
+
<p>Cần Node.js 22.19.0 trở lên. Không cần cài Pi Coding Agent trước: <span class="inline-code">piagent-setup</span> tự cài đúng bản <span class="inline-code">0.82.0</span> mà release <span class="inline-code">v1.1.9</span> đang pin. Chạy nó ngay trong thư mục project — nó cài Pi package, khởi tạo <span class="inline-code">.pi/</span>, cài MCP baseline cùng subagents, rồi chạy doctor. Thêm <span class="inline-code">--no-mcp</span>, <span class="inline-code">--no-subagents</span>, <span class="inline-code">--no-herdr</span> hoặc <span class="inline-code">--global-only</span> để bỏ bớt.</p>
|
|
938
938
|
<div class="table-wrap compact-table">
|
|
939
939
|
<table>
|
|
940
940
|
<thead>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@piagent/platform",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.9",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public",
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
],
|
|
104
104
|
"scripts": {
|
|
105
105
|
"verify": "bash scripts/verify-local.sh",
|
|
106
|
-
"test": "node --test tests/*.test.mjs",
|
|
106
|
+
"test": "PIAGENT_NO_UPDATE_CHECK=1 node --test tests/*.test.mjs",
|
|
107
107
|
"test:policy": "node --test tests/policy-core.test.mjs",
|
|
108
108
|
"test:golden": "node --test tests/golden-enforcement.test.mjs",
|
|
109
109
|
"typecheck": "tsc --noEmit",
|
|
@@ -803,7 +803,12 @@ function buildCoreIntegrity(root) {
|
|
|
803
803
|
// project-shape.js picks the profile a project is offered, and the profile is
|
|
804
804
|
// the document that carries protectedPaths and readOnlyPaths. Steering the
|
|
805
805
|
// recommendation is a way to choose what the guard will end up enforcing.
|
|
806
|
-
"packages/piagent-core/extensions/project-shape.js"
|
|
806
|
+
"packages/piagent-core/extensions/project-shape.js",
|
|
807
|
+
// update-check.js is the one file here that enforces nothing. It is pinned
|
|
808
|
+
// for a different reason: it starts a process on session start and puts a
|
|
809
|
+
// line in the operator's terminal, so tampering with it buys code execution
|
|
810
|
+
// and a message the operator has been trained to trust.
|
|
811
|
+
"packages/piagent-core/extensions/update-check.js"
|
|
807
812
|
];
|
|
808
813
|
return files.map((relativePath) => {
|
|
809
814
|
const resolved = resolveRegularFile(root, relativePath, MAX_ARTIFACT_BYTES);
|
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
redactSensitiveText
|
|
41
41
|
} from "./redaction-core.js";
|
|
42
42
|
import { detectProfileName } from "./project-shape.js";
|
|
43
|
+
import { evaluateUpdateCheck, isInstalledPlatform, readUpdateCache, startUpdateProbe } from "./update-check.js";
|
|
43
44
|
import { buildExtendingProfile, resolveProjectProfileDocument } from "../capabilities/project-profile.js";
|
|
44
45
|
import {
|
|
45
46
|
resolveCapabilityProfileDocument,
|
|
@@ -422,6 +423,23 @@ const DEFAULT_POLICY: BasePolicy = {
|
|
|
422
423
|
// Which platform supplies the adapters is fixed by where this file is installed,
|
|
423
424
|
// so it is resolved once here rather than threaded through every profile load.
|
|
424
425
|
const PLATFORM_ROOT = findPlatformRoot(path.dirname(fileURLToPath(import.meta.url)));
|
|
426
|
+
const UPDATE_CHECK_MODULE = fileURLToPath(new URL("./update-check.js", import.meta.url));
|
|
427
|
+
|
|
428
|
+
// The installed version, read from the package this file ships in. A maintainer
|
|
429
|
+
// working in the repository is not running a release and has nothing to update
|
|
430
|
+
// to, so only a tree Pi or npm placed is given a version to compare.
|
|
431
|
+
function installedPlatformVersion(): string | undefined {
|
|
432
|
+
if (!isInstalledPlatform(PLATFORM_ROOT)) return undefined;
|
|
433
|
+
return readJsonFile<{ version?: string }>(path.join(PLATFORM_ROOT, "package.json"))?.version;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
function updateAvailabilityNotice(): string | undefined {
|
|
437
|
+
const installed = installedPlatformVersion();
|
|
438
|
+
if (!installed) return undefined;
|
|
439
|
+
const decision = evaluateUpdateCheck({ installed, cache: readUpdateCache(), now: Date.now() });
|
|
440
|
+
if (decision.probe) startUpdateProbe(UPDATE_CHECK_MODULE);
|
|
441
|
+
return decision.notice;
|
|
442
|
+
}
|
|
425
443
|
|
|
426
444
|
function loadPolicy(extensionDir: string): BasePolicy {
|
|
427
445
|
const root = findPackageRoot(extensionDir);
|
|
@@ -3733,6 +3751,10 @@ export default function piagentGuard(pi: ExtensionAPI) {
|
|
|
3733
3751
|
if (permissionProfile.mode === "trusted-full-access") {
|
|
3734
3752
|
ctx.ui.notify("Piagent permission profile trusted-full-access is active; protected paths, secret redaction, and destructive/external confirmations remain enforced.", "warning");
|
|
3735
3753
|
}
|
|
3754
|
+
// Last, so a release announcement never pushes a security warning out of
|
|
3755
|
+
// the first thing the operator reads.
|
|
3756
|
+
const updateNotice = updateAvailabilityNotice();
|
|
3757
|
+
if (updateNotice) ctx.ui.notify(updateNotice, "info");
|
|
3736
3758
|
});
|
|
3737
3759
|
|
|
3738
3760
|
pi.on("input", async (event, ctx) => {
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { spawn, spawnSync } from "node:child_process";
|
|
5
|
+
import { fileURLToPath } from "node:url";
|
|
6
|
+
|
|
7
|
+
// Telling someone a new release exists is only useful if it costs them nothing.
|
|
8
|
+
// A session start that waits on the registry pays a network round trip every
|
|
9
|
+
// time Pi opens, for information that changes a few times a month, so the check
|
|
10
|
+
// never runs in the session's path: the session reads a cache file and, when
|
|
11
|
+
// that cache is old, leaves a detached process behind to refresh it. The notice
|
|
12
|
+
// lands on this session if the cache already knew, and on the next one if it did
|
|
13
|
+
// not.
|
|
14
|
+
//
|
|
15
|
+
// Everything read here comes from outside the process — a registry response and
|
|
16
|
+
// a file any local process can write — so the only value that ever reaches the
|
|
17
|
+
// terminal is a version string that matched RELEASE_VERSION. A registry that
|
|
18
|
+
// answers with a sentence, or a cache someone edited to carry one, produces no
|
|
19
|
+
// notice rather than a line of attacker-chosen text in the operator's terminal.
|
|
20
|
+
|
|
21
|
+
const HELPER_PACKAGE = "@piagent/platform";
|
|
22
|
+
const CACHE_FILE = "piagent-update-check.json";
|
|
23
|
+
const CACHE_TTL_MS = 24 * 60 * 60 * 1000;
|
|
24
|
+
const PROBE_TIMEOUT_MS = 10_000;
|
|
25
|
+
const MAX_CACHE_BYTES = 4096;
|
|
26
|
+
const RELEASE_VERSION = /^(0|[1-9]\d{0,8})\.(0|[1-9]\d{0,8})\.(0|[1-9]\d{0,8})$/;
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Whether this platform tree is an install rather than somebody's working copy.
|
|
30
|
+
*
|
|
31
|
+
* Identified by where it sits, not by what it contains. `pi install git:...`
|
|
32
|
+
* clones the repository, so an install made the ordinary way carries a `.git`
|
|
33
|
+
* directory and every other file a maintainer's checkout carries — there is no
|
|
34
|
+
* mark inside the tree that separates them. What does separate them is that Pi
|
|
35
|
+
* puts packages it installed under its own agent directory, and npm puts the
|
|
36
|
+
* global helper under node_modules. A tree anywhere else is a working copy, and
|
|
37
|
+
* telling its owner to install over it is worse than saying nothing.
|
|
38
|
+
*
|
|
39
|
+
* @param {string} platformRoot
|
|
40
|
+
* @param {{home?: string, env?: Record<string, string|undefined>}} [options]
|
|
41
|
+
* @returns {boolean}
|
|
42
|
+
*/
|
|
43
|
+
export function isInstalledPlatform(platformRoot, options = {}) {
|
|
44
|
+
if (typeof platformRoot !== "string" || platformRoot.length === 0) return false;
|
|
45
|
+
if (platformRoot.split(path.sep).includes("node_modules")) return true;
|
|
46
|
+
const env = options.env ?? process.env;
|
|
47
|
+
const configured = env.PI_CODING_AGENT_DIR?.trim();
|
|
48
|
+
const base = options.home ?? os.homedir();
|
|
49
|
+
const agentDir = configured || (typeof base === "string" && base.length > 0 ? path.join(base, ".pi", "agent") : undefined);
|
|
50
|
+
if (!agentDir) return false;
|
|
51
|
+
// Both sides are resolved before comparing. A home reached through a symlink
|
|
52
|
+
// is ordinary — macOS reaches /var that way — and comparing one real path
|
|
53
|
+
// against one symlinked path makes an install look like it is somewhere else.
|
|
54
|
+
const relative = path.relative(realPath(agentDir), realPath(platformRoot));
|
|
55
|
+
// Empty means the same directory, which is not a package inside it; a leading
|
|
56
|
+
// `..` or an absolute result means the tree is somewhere else entirely.
|
|
57
|
+
return relative.length > 0 && !relative.startsWith("..") && !path.isAbsolute(relative);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/** @param {string} value @returns {string} */
|
|
61
|
+
function realPath(value) {
|
|
62
|
+
try {
|
|
63
|
+
return fs.realpathSync(value);
|
|
64
|
+
} catch {
|
|
65
|
+
return value;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** @param {string} [home] @returns {string|undefined} */
|
|
70
|
+
export function updateCacheFile(home) {
|
|
71
|
+
const base = home ?? os.homedir();
|
|
72
|
+
if (typeof base !== "string" || base.length === 0) return undefined;
|
|
73
|
+
return path.join(base, ".pi", CACHE_FILE);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* A release version and nothing else. Prereleases and build metadata are
|
|
78
|
+
* rejected rather than parsed: this decides what to tell someone to install, and
|
|
79
|
+
* nudging an operator onto a prerelease is not what the notice is for.
|
|
80
|
+
* @param {unknown} value @returns {string|undefined}
|
|
81
|
+
*/
|
|
82
|
+
export function releaseVersion(value) {
|
|
83
|
+
if (typeof value !== "string") return undefined;
|
|
84
|
+
const trimmed = value.trim();
|
|
85
|
+
return RELEASE_VERSION.test(trimmed) ? trimmed : undefined;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Compare two release versions numerically. `1.1.10` is after `1.1.9`, which
|
|
90
|
+
* string ordering gets backwards.
|
|
91
|
+
* @param {string} left @param {string} right @returns {number}
|
|
92
|
+
*/
|
|
93
|
+
export function compareReleaseVersions(left, right) {
|
|
94
|
+
const leftParts = left.split(".").map(Number);
|
|
95
|
+
const rightParts = right.split(".").map(Number);
|
|
96
|
+
for (let index = 0; index < 3; index += 1) {
|
|
97
|
+
if (leftParts[index] !== rightParts[index]) return leftParts[index] < rightParts[index] ? -1 : 1;
|
|
98
|
+
}
|
|
99
|
+
return 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/** @param {string} [home] @returns {{latest?: string, checkedAt?: number}} */
|
|
103
|
+
export function readUpdateCache(home) {
|
|
104
|
+
const file = updateCacheFile(home);
|
|
105
|
+
if (!file) return {};
|
|
106
|
+
try {
|
|
107
|
+
// A cache larger than this is not something this code wrote.
|
|
108
|
+
if (fs.statSync(file).size > MAX_CACHE_BYTES) return {};
|
|
109
|
+
const document = JSON.parse(fs.readFileSync(file, "utf8"));
|
|
110
|
+
const checkedAt = Date.parse(document?.checkedAt);
|
|
111
|
+
return {
|
|
112
|
+
latest: releaseVersion(document?.latest),
|
|
113
|
+
checkedAt: Number.isFinite(checkedAt) ? checkedAt : undefined
|
|
114
|
+
};
|
|
115
|
+
} catch {
|
|
116
|
+
return {};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** @param {string|undefined} home @param {string} latest @param {number} now @returns {boolean} */
|
|
121
|
+
export function writeUpdateCache(home, latest, now) {
|
|
122
|
+
const file = updateCacheFile(home);
|
|
123
|
+
const version = releaseVersion(latest);
|
|
124
|
+
if (!file || !version) return false;
|
|
125
|
+
const document = {
|
|
126
|
+
schemaVersion: 1,
|
|
127
|
+
package: HELPER_PACKAGE,
|
|
128
|
+
latest: version,
|
|
129
|
+
checkedAt: new Date(now).toISOString()
|
|
130
|
+
};
|
|
131
|
+
try {
|
|
132
|
+
fs.mkdirSync(path.dirname(file), { recursive: true });
|
|
133
|
+
const temporary = `${file}.${process.pid}.tmp`;
|
|
134
|
+
fs.writeFileSync(temporary, `${JSON.stringify(document, null, 2)}\n`);
|
|
135
|
+
fs.renameSync(temporary, file);
|
|
136
|
+
return true;
|
|
137
|
+
} catch {
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* What the session should do about updates, decided from state alone so it can
|
|
144
|
+
* be tested without a registry or a clock.
|
|
145
|
+
* @param {{installed?: string, cache?: {latest?: string, checkedAt?: number}, now: number, env?: Record<string, string|undefined>}} options
|
|
146
|
+
* @returns {{notice?: string, probe: boolean}}
|
|
147
|
+
*/
|
|
148
|
+
export function evaluateUpdateCheck(options) {
|
|
149
|
+
const env = options.env ?? process.env;
|
|
150
|
+
if (env.PIAGENT_NO_UPDATE_CHECK?.trim()) return { probe: false };
|
|
151
|
+
|
|
152
|
+
const installed = releaseVersion(options.installed);
|
|
153
|
+
const cache = options.cache ?? {};
|
|
154
|
+
const latest = releaseVersion(cache.latest);
|
|
155
|
+
const probe = !(typeof cache.checkedAt === "number" && options.now - cache.checkedAt < CACHE_TTL_MS);
|
|
156
|
+
|
|
157
|
+
if (!installed || !latest || compareReleaseVersions(latest, installed) <= 0) return { probe };
|
|
158
|
+
return {
|
|
159
|
+
probe,
|
|
160
|
+
notice: `Piagent update available: ${installed} -> ${latest}. Run \`piagent-update\` to move this machine to it.`
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* Leave the refresh behind and return. The child is detached with no inherited
|
|
166
|
+
* stdio, so nothing it does can hold the session open or write into the
|
|
167
|
+
* terminal.
|
|
168
|
+
* @param {string} moduleFile @param {{spawn?: typeof spawn}} [options]
|
|
169
|
+
* @returns {boolean}
|
|
170
|
+
*/
|
|
171
|
+
export function startUpdateProbe(moduleFile, options = {}) {
|
|
172
|
+
try {
|
|
173
|
+
const child = (options.spawn ?? spawn)(process.execPath, [moduleFile, "--probe"], {
|
|
174
|
+
detached: true,
|
|
175
|
+
stdio: "ignore",
|
|
176
|
+
windowsHide: true
|
|
177
|
+
});
|
|
178
|
+
child.unref();
|
|
179
|
+
return true;
|
|
180
|
+
} catch {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/** @returns {string|undefined} */
|
|
186
|
+
function fetchLatestVersion() {
|
|
187
|
+
const result = spawnSync("npm", ["view", HELPER_PACKAGE, "version", "--json"], {
|
|
188
|
+
encoding: "utf8",
|
|
189
|
+
timeout: PROBE_TIMEOUT_MS,
|
|
190
|
+
windowsHide: true
|
|
191
|
+
});
|
|
192
|
+
if (result.status !== 0 || typeof result.stdout !== "string") return undefined;
|
|
193
|
+
try {
|
|
194
|
+
return releaseVersion(JSON.parse(result.stdout));
|
|
195
|
+
} catch {
|
|
196
|
+
return undefined;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/** @param {{now?: number, home?: string, fetch?: () => string|undefined}} [options] @returns {boolean} */
|
|
201
|
+
export function runUpdateProbe(options = {}) {
|
|
202
|
+
const latest = (options.fetch ?? fetchLatestVersion)();
|
|
203
|
+
// A registry that could not be reached leaves the cache alone, so the next
|
|
204
|
+
// session retries instead of recording "no update" as if it had been checked.
|
|
205
|
+
if (!latest) return false;
|
|
206
|
+
return writeUpdateCache(options.home, latest, options.now ?? Date.now());
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
if (process.argv[2] === "--probe" && process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url)) {
|
|
210
|
+
runUpdateProbe();
|
|
211
|
+
}
|
|
@@ -15,7 +15,7 @@ Package source examples:
|
|
|
15
15
|
# Installs the stable tag after resolving it to a commit SHA.
|
|
16
16
|
|
|
17
17
|
# Pin a specific release:
|
|
18
|
-
scripts/install-global.sh --version v1.1.
|
|
18
|
+
scripts/install-global.sh --version v1.1.9 --resolve-tag
|
|
19
19
|
|
|
20
20
|
# Preview the planned install/update without changing user config:
|
|
21
21
|
scripts/install-global.sh --stable --dry-run
|
|
@@ -127,7 +127,7 @@ detect_runtime_surface() {
|
|
|
127
127
|
printf 'native-windows/%s (not release-gated; terminal helpers require Bash semantics)' "$arch_name"
|
|
128
128
|
;;
|
|
129
129
|
*)
|
|
130
|
-
printf '%s/%s (outside v1.1.
|
|
130
|
+
printf '%s/%s (outside v1.1.9 release matrix)' "$os_name" "$arch_name"
|
|
131
131
|
;;
|
|
132
132
|
esac
|
|
133
133
|
}
|
|
@@ -135,7 +135,7 @@ detect_runtime_surface() {
|
|
|
135
135
|
warn_runtime_surface_if_needed() {
|
|
136
136
|
local surface="$1"
|
|
137
137
|
case "$surface" in
|
|
138
|
-
*"supported target"*|*"experimental"*|*"not release-gated"*|*"outside v1.1.
|
|
138
|
+
*"supported target"*|*"experimental"*|*"not release-gated"*|*"outside v1.1.9 release matrix"*)
|
|
139
139
|
echo "WARN: runtime surface is $surface." >&2
|
|
140
140
|
echo "WARN: For team rollout, run piagent-doctor plus the project smoke/verify suite on this machine before relying on it." >&2
|
|
141
141
|
;;
|
package/scripts/team-doctor.sh
CHANGED
|
@@ -137,7 +137,7 @@ function runtimeMatrixStatus() {
|
|
|
137
137
|
surface: `${platform}/${arch}`,
|
|
138
138
|
status: "outside-release-matrix",
|
|
139
139
|
teamRolloutReady: false,
|
|
140
|
-
note: "This runtime is outside the documented v1.1.
|
|
140
|
+
note: "This runtime is outside the documented v1.1.9 support matrix."
|
|
141
141
|
};
|
|
142
142
|
}
|
|
143
143
|
|