pi-webapp 0.1.23 → 0.1.25

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.
@@ -0,0 +1,76 @@
1
+ # macOS 小范围测试安装 / Small-group test installation
2
+
3
+ 适用于 **desktop build 7 起、采用新签名流程构建**的 macOS Apple Silicon / Intel 测试包。
4
+ 旧包不会因源码更新而自动修复;请安装新构建,不要覆盖发布过的同名安装包。
5
+
6
+ ## 这些测试包能保证什么?
7
+
8
+ - 默认以 `codesign` 的 ad-hoc 临时签名封装完整应用、Electron helpers 和内置运行时,
9
+ 无需 Developer ID 证书。打包和发布准备都要求通过 deep/strict 签名完整性检查。
10
+ - **不是 Developer ID 发布者签名,没有 Apple 公证**。这不是面向公众“下载即打开”的发行版。
11
+ Gatekeeper 仍可能拦截;`spctl --assess` 拒绝此包是预期限制,不等于打包签名校验失败。
12
+ - SHA-256 只核对发行文件;临时签名只检查包是否符合当前签名,不验证开发者身份,
13
+ 二者都不能证明软件安全。只邀请明确知情、愿意信任项目的测试用户。
14
+ - 当前主分支没有桌面自动更新器。测试包从 Release 下载、校验后手动安装。
15
+
16
+ ## 测试用户安装步骤
17
+
18
+ 1. 从项目官方 [GitHub Releases](https://github.com/chengzhiyi/pi-webapp/releases)
19
+ 下载明确邀请测试的构建 DMG 和同一 Release 的 `SHA256SUMS`。
20
+ 不要使用转发的未知安装包、源码 ZIP 或不匹配版本的校验文件。
21
+ 2. 在终端运行 `shasum -a 256 <下载的DMG路径>`,与 `SHA256SUMS` 中该 DMG 的一行比较。
22
+ 不一致就停止,不要关闭系统保护。`SHA256SUMS` 含四平台安装包;只下载一个 DMG 时,
23
+ 逐行比较该文件即可,不要因未下载其他平台文件而误判其校验结果。
24
+ 3. 退出旧桌面再替换应用。先完成所有聊天/终端任务;若旧桌面使用内置后台,
25
+ 从其原入口停止该后台再替换。不要停止仍需使用的外部 Web 后台,也不要删除 `~/.pi`。
26
+ 打开 DMG,把 **pi.app** 拖入“应用程序”。旧 **Pi Webapp.app** 不会自动被覆盖,
27
+ 请更新 Dock 快捷方式以免打开旧版。
28
+ 4. 检查安装后的应用完整性:
29
+
30
+ ```bash
31
+ codesign --verify --deep --strict --verbose=2 "/Applications/pi.app"
32
+ ```
33
+
34
+ **失败就停止**,保存报错、构建号及 DMG 校验结果反馈给维护者。
35
+ 不要自行重签,因为那会为可能被修改的内容建立新签名、掩盖原始问题。
36
+ 5. 尝试打开应用。如果被拦截,可在 macOS 提供该选项时使用
37
+ **系统设置 → 隐私与安全性 → 仍要打开**。
38
+ 如果仍因下载隔离无法启动,且你已核对来源、校验和、签名,并明确愿意信任该测试包,
39
+ 可以手动运行以下命令,**只针对此应用**移除下载隔离后重试:
40
+
41
+ ```bash
42
+ codesign --verify --deep --strict --verbose=2 "/Applications/pi.app" &&
43
+ xattr -dr com.apple.quarantine "/Applications/pi.app"
44
+ ```
45
+
46
+ 这会跳过该应用的下载隔离检查,**不代表 Apple 已认证其安全**。
47
+ 不要对来源不明的软件使用,不要全局关闭 Gatekeeper/SIP;遇到权限错误先反馈,
48
+ 不要盲目追加 `sudo`。项目不会自动执行此操作。
49
+ 6. 在 **pi → 关于 pi** 确认版本、桌面构建号及应用位置,再配置模型并测试聊天和终端。
50
+ 若启动失败,反馈系统版本、芯片、构建号及错误;不要上传 API 密钥、`auth.json` 或私钥。
51
+
52
+ 再次安装/更新未公证测试包时,可能需要重复信任步骤。不接受这些限制的用户可继续使用
53
+ Web 版,或从可信源码构建运行,不必购买开发者会员。
54
+
55
+ ## Release operator / 维护者验收
56
+
57
+ - 默认 `mac.identity` 为 `-`;证书自动发现保持关闭。
58
+ 正式签名须由有权限的操作员显式配置 `CSC_NAME`,不得把 ad-hoc 宣称为发布者签名。
59
+ - electron-builder 在生成 DMG **之前**,自内向外签署嵌套代码并做 strict 验证。
60
+ 默认 hardened runtime 及 Electron 所需 JIT/library-validation entitlements 由固定版本
61
+ electron-builder 提供;不得在签名后改写应用资源。
62
+ - `npm run desktop:package` 与发布准备均拒绝未封装资源或签名校验失败的应用。
63
+ `desktop-release.json` 的 `signing` 记录 `type` 和 `verified`;兼容字段 `unsigned: true`
64
+ 表示**没有发布者身份**,即使 ad-hoc 完整性校验通过也保持为 true。
65
+ - 打包命令还会只读挂载 DMG,自动校验其中实际应用的 deep/strict 签名。
66
+ 当前主分支保持 DMG 分发,不为此引入 ZIP 更新包或自动更新器。
67
+ 执行 packaged smoke(含 PTY/浏览器共享后台)。
68
+ 这些检查不能替代“浏览器下载 → Finder 安装 → 用户明确同意”的隔离场景人工验收。
69
+ - 每次交付递增 `desktop/release.json` 的构建号、重新生成校验和。
70
+ 不覆盖已有公开 Release,不以移除隔离或本机可启动宣称通过 Gatekeeper。
71
+
72
+ English summary: These are complete **ad-hoc signed**, **unnotarized** opt-in test builds,
73
+ not publisher-authenticated releases. Verify the official DMG checksum and the installed app's
74
+ `codesign --verify --deep --strict` result before trusting it. Stop on verification failure;
75
+ do not re-sign a downloaded app to hide a failure. Any quarantine exception must be a conscious,
76
+ manual, app-scoped tester choice. Never disable system security globally.
package/docs/desktop.md CHANGED
@@ -88,13 +88,24 @@ These are two separate release responsibilities:
88
88
  - **Safe updates** verify an update's publisher/integrity and replace a compatible
89
89
  application/runtime without destroying user data.
90
90
 
91
- The installers remain **unsigned/unnotarized test builds**, with no certificate
92
- discovery or automatic desktop updater. A GitHub prerelease is a download channel,
93
- not a claim of formal signed-distribution readiness.
94
- macOS Gatekeeper / Windows SmartScreen may warn or block an unsigned download.
95
- Do not disable OS security globally to use it. Public distribution needs a
96
- separately configured, authorized signing/notarization workflow; local successful
97
- packaging is not proof of public-distribution readiness.
91
+ Starting with desktop build 7, default macOS packages use **complete ad-hoc
92
+ signatures, without publisher identity or notarization**, for opt-in small-group
93
+ testing. No certificate is needed: `mac.identity` defaults to `-`; an authorized
94
+ operator may explicitly select `CSC_NAME` for Developer ID signing. Certificate
95
+ discovery stays disabled. Windows/Linux's unsigned release paths are unchanged.
96
+
97
+ Electron-builder signs nested code before creating the DMG. Packaging verifies
98
+ the app and the read-only mounted DMG; release preparation requires deep/strict
99
+ verification and a complete resource seal on both macOS architectures. macOS
100
+ receipts record `signing: { type: "ad-hoc" | "developer-id", verified: true }`;
101
+ `unsigned: true` means **no publisher identity**, including valid ad-hoc signatures.
102
+
103
+ **Ad-hoc is not Developer ID.** Gatekeeper can still block the download. Follow
104
+ the [tester installation and trust instructions](desktop-testing.md): verify the
105
+ checksum and signature, stop on verification failure, and only use a conscious,
106
+ manual, app-scoped trust exception for a known test build. Never disable OS
107
+ security globally. Public distribution needs authorized signing/notarization;
108
+ local packaging success is not proof of downloaded first-launch acceptance.
98
109
 
99
110
  For now, install a newer desktop package to upgrade; if replacing a running
100
111
  desktop-owned runtime, first finish tasks and stop that owned service. A desktop
@@ -158,8 +169,9 @@ The candidate build-6 pipeline adds four **native** targets:
158
169
 
159
170
  Each uses locked dependencies, standalone Node/Pi, full unit tests and actual
160
171
  installer-payload desktop/browser/PTY smoke. The smoke reads the installed Pi
161
- package and requires the same pinned version. Signing discovery and Sentry are
162
- disabled. ARM Windows/Linux and other targets are not implicitly supported.
172
+ package and requires the same pinned version. Certificate discovery and Sentry
173
+ are disabled; macOS ad-hoc signing and strict integrity checks are required from
174
+ build 7. ARM Windows/Linux and other targets are not implicitly supported.
163
175
 
164
176
  A read-only aggregation job requires **all four** verified receipts from the
165
177
  same source/version/build/Pi pair. It collects four installers, SHA256SUMS,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-webapp",
3
- "version": "0.1.23",
3
+ "version": "0.1.25",
4
4
  "type": "module",
5
5
  "description": "A browser interface for Pi with live chat, workspaces, models, and attachments",
6
6
  "repository": {
@@ -15,7 +15,7 @@
15
15
  "pi-webapp": "./bin/pi-webapp.mjs"
16
16
  },
17
17
  "pi": {
18
- "image": "https://cdn.jsdelivr.net/npm/pi-webapp@0.1.23/assets/cover-webapp.png",
18
+ "image": "https://cdn.jsdelivr.net/npm/pi-webapp@0.1.25/assets/cover-webapp.png",
19
19
  "extensions": [
20
20
  "./dist/extension.js"
21
21
  ]
@@ -32,6 +32,7 @@
32
32
  "docs/sentry.md",
33
33
  "docs/sentry-triage.md",
34
34
  "docs/desktop.md",
35
+ "docs/desktop-testing.md",
35
36
  "scripts/prepare-terminal.mjs"
36
37
  ],
37
38
  "scripts": {
@@ -122,13 +122,13 @@
122
122
  "isDynamicEntry": true
123
123
  },
124
124
  "../../node_modules/@shikijs/langs/dist/graphql.mjs": {
125
- "file": "assets/graphql-R1M_bSpj.js",
125
+ "file": "assets/graphql-DCmL4QvK.js",
126
126
  "name": "graphql",
127
127
  "src": "../../node_modules/@shikijs/langs/dist/graphql.mjs",
128
128
  "isDynamicEntry": true,
129
129
  "imports": [
130
130
  "_javascript-D_ijBMSX.js",
131
- "_app-C-H5rHq5.js",
131
+ "_app-DQXe2TPf.js",
132
132
  "index.html"
133
133
  ]
134
134
  },
@@ -161,12 +161,12 @@
161
161
  ]
162
162
  },
163
163
  "../../node_modules/@shikijs/langs/dist/http.mjs": {
164
- "file": "assets/http-L5EnyzVP.js",
164
+ "file": "assets/http-D1RjONju.js",
165
165
  "name": "http",
166
166
  "src": "../../node_modules/@shikijs/langs/dist/http.mjs",
167
167
  "isDynamicEntry": true,
168
168
  "imports": [
169
- "_app-C-H5rHq5.js",
169
+ "_app-DQXe2TPf.js",
170
170
  "../../node_modules/@shikijs/langs/dist/xml.mjs",
171
171
  "../../node_modules/@shikijs/langs/dist/graphql.mjs",
172
172
  "index.html",
@@ -275,7 +275,7 @@
275
275
  ]
276
276
  },
277
277
  "../../node_modules/@shikijs/langs/dist/php.mjs": {
278
- "file": "assets/php-xdHBwAuB.js",
278
+ "file": "assets/php-D_vc4Tu2.js",
279
279
  "name": "php",
280
280
  "src": "../../node_modules/@shikijs/langs/dist/php.mjs",
281
281
  "isDynamicEntry": true,
@@ -284,7 +284,7 @@
284
284
  "../../node_modules/@shikijs/langs/dist/xml.mjs",
285
285
  "../../node_modules/@shikijs/langs/dist/sql.mjs",
286
286
  "_javascript-D_ijBMSX.js",
287
- "_app-C-H5rHq5.js",
287
+ "_app-DQXe2TPf.js",
288
288
  "../../node_modules/@shikijs/langs/dist/css.mjs",
289
289
  "../../node_modules/@shikijs/langs/dist/java.mjs",
290
290
  "index.html"
@@ -315,7 +315,7 @@
315
315
  "isDynamicEntry": true
316
316
  },
317
317
  "../../node_modules/@shikijs/langs/dist/rst.mjs": {
318
- "file": "assets/rst-D5vBXrc7.js",
318
+ "file": "assets/rst-CXMoyibL.js",
319
319
  "name": "rst",
320
320
  "src": "../../node_modules/@shikijs/langs/dist/rst.mjs",
321
321
  "isDynamicEntry": true,
@@ -324,7 +324,7 @@
324
324
  "../../node_modules/@shikijs/langs/dist/cpp.mjs",
325
325
  "../../node_modules/@shikijs/langs/dist/python.mjs",
326
326
  "_javascript-D_ijBMSX.js",
327
- "_app-C-H5rHq5.js",
327
+ "_app-DQXe2TPf.js",
328
328
  "../../node_modules/@shikijs/langs/dist/yaml.mjs",
329
329
  "../../node_modules/@shikijs/langs/dist/cmake.mjs",
330
330
  "../../node_modules/@shikijs/langs/dist/ruby.mjs",
@@ -340,7 +340,7 @@
340
340
  ]
341
341
  },
342
342
  "../../node_modules/@shikijs/langs/dist/ruby.mjs": {
343
- "file": "assets/ruby-CB8CtpFl.js",
343
+ "file": "assets/ruby-B2ZFKb7W.js",
344
344
  "name": "ruby",
345
345
  "src": "../../node_modules/@shikijs/langs/dist/ruby.mjs",
346
346
  "isDynamicEntry": true,
@@ -353,7 +353,7 @@
353
353
  "../../node_modules/@shikijs/langs/dist/graphql.mjs",
354
354
  "../../node_modules/@shikijs/langs/dist/cpp.mjs",
355
355
  "../../node_modules/@shikijs/langs/dist/c.mjs",
356
- "_app-C-H5rHq5.js",
356
+ "_app-DQXe2TPf.js",
357
357
  "../../node_modules/@shikijs/langs/dist/lua.mjs",
358
358
  "../../node_modules/@shikijs/langs/dist/yaml.mjs",
359
359
  "../../node_modules/@shikijs/langs/dist/java.mjs",
@@ -388,13 +388,13 @@
388
388
  "isDynamicEntry": true
389
389
  },
390
390
  "../../node_modules/@shikijs/langs/dist/svelte.mjs": {
391
- "file": "assets/svelte-qWxX2efJ.js",
391
+ "file": "assets/svelte-Or6lhjBs.js",
392
392
  "name": "svelte",
393
393
  "src": "../../node_modules/@shikijs/langs/dist/svelte.mjs",
394
394
  "isDynamicEntry": true,
395
395
  "imports": [
396
396
  "_javascript-D_ijBMSX.js",
397
- "_app-C-H5rHq5.js",
397
+ "_app-DQXe2TPf.js",
398
398
  "../../node_modules/@shikijs/langs/dist/css.mjs",
399
399
  "index.html"
400
400
  ]
@@ -430,14 +430,14 @@
430
430
  "isDynamicEntry": true
431
431
  },
432
432
  "../../node_modules/@shikijs/langs/dist/vue.mjs": {
433
- "file": "assets/vue-CTcHoOmv.js",
433
+ "file": "assets/vue-Di6p925N.js",
434
434
  "name": "vue",
435
435
  "src": "../../node_modules/@shikijs/langs/dist/vue.mjs",
436
436
  "isDynamicEntry": true,
437
437
  "imports": [
438
438
  "../../node_modules/@shikijs/langs/dist/css.mjs",
439
439
  "_javascript-D_ijBMSX.js",
440
- "_app-C-H5rHq5.js",
440
+ "_app-DQXe2TPf.js",
441
441
  "../../node_modules/@shikijs/langs/dist/html.mjs",
442
442
  "_html-derivative-C2Epw9Yg.js",
443
443
  "index.html"
@@ -704,37 +704,37 @@
704
704
  ]
705
705
  },
706
706
  "../../src/plugins/builtin/files/client/plugin.tsx": {
707
- "file": "assets/plugin-DtJl1c8o.js",
707
+ "file": "assets/plugin-DNLljKtT.js",
708
708
  "name": "plugin",
709
709
  "src": "../../src/plugins/builtin/files/client/plugin.tsx",
710
710
  "isDynamicEntry": true,
711
711
  "imports": [
712
- "_app-C-H5rHq5.js",
712
+ "_app-DQXe2TPf.js",
713
713
  "index.html"
714
714
  ]
715
715
  },
716
716
  "../../src/plugins/builtin/git/client/plugin.tsx": {
717
- "file": "assets/plugin-DCamQdiP.js",
717
+ "file": "assets/plugin-Dt1cBQ6m.js",
718
718
  "name": "plugin",
719
719
  "src": "../../src/plugins/builtin/git/client/plugin.tsx",
720
720
  "isDynamicEntry": true,
721
721
  "imports": [
722
- "_app-C-H5rHq5.js",
722
+ "_app-DQXe2TPf.js",
723
723
  "index.html"
724
724
  ]
725
725
  },
726
726
  "../../src/plugins/builtin/terminal/client/plugin.tsx": {
727
- "file": "assets/plugin-CYps5zpH.js",
727
+ "file": "assets/plugin-Bjpcuu8G.js",
728
728
  "name": "plugin",
729
729
  "src": "../../src/plugins/builtin/terminal/client/plugin.tsx",
730
730
  "isDynamicEntry": true,
731
731
  "imports": [
732
- "_app-C-H5rHq5.js",
732
+ "_app-DQXe2TPf.js",
733
733
  "index.html"
734
734
  ]
735
735
  },
736
- "_app-C-H5rHq5.js": {
737
- "file": "assets/app-C-H5rHq5.js",
736
+ "_app-DQXe2TPf.js": {
737
+ "file": "assets/app-DQXe2TPf.js",
738
738
  "name": "app",
739
739
  "isDynamicEntry": true,
740
740
  "imports": [
@@ -882,7 +882,7 @@
882
882
  "isEntry": true,
883
883
  "dynamicImports": [
884
884
  "../../src/host/client/telemetry-client.ts",
885
- "_app-C-H5rHq5.js"
885
+ "_app-DQXe2TPf.js"
886
886
  ]
887
887
  },
888
888
  "style.css": {