glasspane-harness 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +215 -0
  2. package/README.zh-CN.md +173 -0
  3. package/package.json +3 -3
package/README.md ADDED
@@ -0,0 +1,215 @@
1
+ <h1 align="center">
2
+ <code>glasspane-harness</code>
3
+ </h1>
4
+
5
+ <p align="center">
6
+ <a href="README.md"><strong>English</strong></a> ·
7
+ <a href="README.zh-CN.md"><strong>简体中文</strong></a>
8
+ </p>
9
+
10
+ <p align="center">
11
+ <a href="https://www.npmjs.com/package/glasspane-harness"><img src="https://img.shields.io/npm/dt/glasspane-harness?label=Downloads&style=for-the-badge&color=2ea44f&logo=npm&logoColor=white" alt="npm downloads"></a>
12
+ <img src="https://img.shields.io/dynamic/json?url=https%3A%2F%2Fregistry.npmjs.org%2Fglasspane-harness%2Flatest&query=version&label=version&color=brightgreen" alt="version">
13
+ <a href="https://github.com/jingzhao-l/glasspane-harness/actions/workflows/ci.yml"><img src="https://github.com/jingzhao-l/glasspane-harness/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
14
+ <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow" alt="License"></a>
15
+ <img src="https://img.shields.io/badge/macOS-13%2B-blue?logo=apple&logoColor=white" alt="macOS 13+">
16
+ <a href="https://github.com/jingzhao-l/glasspane-harness"><img src="https://img.shields.io/github/stars/jingzhao-l/glasspane-harness?style=social&label=Star" alt="Stars"></a>
17
+ </p>
18
+
19
+ <p align="center">
20
+ <img src="assets/banner.svg" alt="GlassPane Harness — evidence-honest GUI verification for macOS apps" width="720">
21
+ </p>
22
+
23
+ ---
24
+
25
+ **The problem.** An AI agent driving a real macOS app cannot honestly say whether the UI
26
+ did what it asked. It sees its own tool output, guesses from prose, and reports success.
27
+ Screenshots don't help: they show *a* moment, not a *change*, and they cannot say whether
28
+ the change was caused by the click.
29
+
30
+ **GlassPane Harness** is a coding agent (an [opencode](https://github.com/anomalyco/opencode)
31
+ fork) wired to a Swift verification engine through a native `gp_*` tool surface. Every
32
+ action is measured — accessibility-tree diff, pixel diff, crash and responsiveness
33
+ signals — and the engine reports **its own** attribution (`strong` / `soft` / `none`,
34
+ circuit-breaker level, pass / fail / inconclusive). The harness transcribes; it never
35
+ invents a verdict. Verified calls are appended to a hash-chained decision log, and a
36
+ compaction hook re-injects the session's evidence anchors so summarising can never quietly
37
+ drop the audit chain.
38
+
39
+ The engine is [GlassPane](https://github.com/jingzhao-l/GlassPane). The harness is the
40
+ agent side of it.
41
+
42
+ ## This is a complete coding agent, not a stripped one
43
+
44
+ The verification wiring is the point of this fork, but it is **additive**. Everything
45
+ opencode does, this harness still does — same agents, same tools, same models, same
46
+ permissions, same LSP and MCP support, same TUI and web app, same SDK and plugin API.
47
+ Nothing was cut to make room for the kernel.
48
+
49
+ That is a measured claim, not a promise. The fork tracks upstream
50
+ [anomalyco/opencode](https://github.com/anomalyco/opencode) at a pinned tag, and
51
+ `harness/tools/fork-diff.mjs` compares every file in this tree against that tag on every
52
+ change:
53
+
54
+ ```
55
+ fork-diff vs v1.18.32: 6527/6687 byte-identical, 51 edited, 55 added, 54 deleted
56
+ ```
57
+
58
+ Roughly 98% of the upstream tree is byte-for-byte upstream. The edits are concentrated in
59
+ config/paths/branding, the `gp_*` tool surface, the kernel binding, the compaction hook,
60
+ and the packaging scripts. The deleted files are upstream's own publish plumbing for
61
+ channels this product does not use (ghcr images, AUR, a Homebrew tap, a hosted console
62
+ account) — plus, in 0.4.0, the first-party account surface described below.
63
+
64
+ What "additive" means in practice: if upstream ships a feature in a later release, this
65
+ fork can take it, because the feature is still here to take.
66
+
67
+ ### One exception, and it is deliberate: no account, bring your own key
68
+
69
+ Upstream lets you `auth login` to an opencode account, which unlocks opencode's own
70
+ model gateway (a first-party provider in the catalog) and remote session sharing. This
71
+ product has no such account, so that surface is removed rather than shipped broken:
72
+
73
+ - the `opencode` provider entry is filtered out of the model catalog
74
+ - `auth login` / `logout` / `switch`, the `/org` command and the org switcher are gone
75
+ - the `/experimental/console*` endpoints and the console-managed-provider state are gone
76
+ - session sharing to opencode's cloud is gone (`share` / `autoshare` config keys too)
77
+
78
+ **Everything else in the catalog is untouched.** Anthropic, OpenAI, Google, GitHub
79
+ Copilot, Amazon Bedrock, Azure, OpenRouter and the rest are all still there — hundreds of
80
+ models — and each one is unlocked by **your own API key**, supplied by environment
81
+ variable, by the config file with an `{env:NAME}` template, or by the TUI's `/connect`
82
+ dialog. There is nothing to sign up for and nothing to log into. See
83
+ [`docs/models-and-keys.md`](docs/models-and-keys.md).
84
+
85
+ ## Product surfaces
86
+
87
+ | Surface | What you get | How it ships |
88
+ |---|---|---|
89
+ | **CLI + TUI** | The agent in your terminal: interactive TUI, `run` for one-shot tasks, `serve` for headless clients | the `glasspane-harness` / `gp-harness` binaries, npm + one-click installer |
90
+ | **Web app** (embedded) | Browser UI served by the binary itself — no second process, no separate deploy | embedded in the binary (`--skip-embed-web-ui` for a CLI-only build) |
91
+ | **Docs** | This repository's `docs/` — install, tools, evidence, migration, troubleshooting | in-repo markdown (canonical; versioned with the code) |
92
+ | **SDKs** | TypeScript SDK and the plugin SDK for building your own `gp_*`-style tools | workspace packages, shipped with the tree |
93
+
94
+ Not shipped, on purpose: the upstream hosted console / enterprise stack (a private harness
95
+ has no use for an organisation-and-quota back office), the Electron desktop app (a second
96
+ batch — it needs signing and notarisation accounts), and the upstream docs *site*
97
+ (`packages/web` still holds upstream's Astro/Starlift content; it builds and stays in the
98
+ tree, but this product's canonical documentation is `docs/` until the site is rebuilt from
99
+ it). All three stay in the tree as lineage so future syncs from the pinned upstream tag
100
+ stay honest.
101
+
102
+ ## Install
103
+
104
+ ```bash
105
+ # npm (recommended)
106
+ npm install -g glasspane-harness
107
+
108
+ # or bun
109
+ bun add -g glasspane-harness
110
+
111
+ # or one-click (npm first, GitHub release asset as fallback)
112
+ curl -fsSL https://raw.githubusercontent.com/jingzhao-l/glasspane-harness/main/scripts/install.sh | bash
113
+ ```
114
+
115
+ Two commands are installed: **`glasspane-harness`** and the short alias **`gp-harness`**.
116
+
117
+ **macOS only.** The engine, the permission model and the evidence pipeline exist only on
118
+ macOS, so the npm distribution is macOS-only too: the package declares `os: darwin` and
119
+ npm refuses the install elsewhere instead of handing you a binary that cannot run. There
120
+ is no Linux or Windows build, by decision, not by omission.
121
+
122
+ Prerequisites: macOS 13+ (Apple silicon or Intel), and — for the `gp_*` tools — the **GlassPane** background
123
+ service running with Accessibility granted ([install GlassPane](https://github.com/jingzhao-l/GlassPane);
124
+ the installer prints the exact next steps). Without the engine every `gp_*` call answers
125
+ `GP_E_ENGINE_UNREACHABLE` with a remedy — that is the engine's word, not the installer's.
126
+
127
+ If npm's global prefix is not writable, use
128
+ `npm install -g --prefix "$HOME/.local" glasspane-harness` and put `~/.local/bin` on PATH;
129
+ the installer detects that failure and prints this remedy itself.
130
+
131
+ ## Quick start
132
+
133
+ ```bash
134
+ glasspane-harness # interactive TUI (the embedded web UI is served too)
135
+ glasspane-harness run "attach to Notes, type a heading, then tell me whether the UI proved it"
136
+ glasspane-harness serve --port 4096 # headless server; the web app is served from it
137
+ glasspane-harness --help
138
+ ```
139
+
140
+ The first thing to ask any session for is `gp_probe_status`: it reports the engine
141
+ version, advertised capabilities and permission state — and every remedy the tool surface
142
+ emits points back at it.
143
+
144
+ ## The `gp_*` tool surface
145
+
146
+ | Tool | What it does | Permission |
147
+ |---|---|---|
148
+ | `gp_probe_status` | engine self-report: version, capabilities, accessibility / input-monitoring / screen-recording / developer-tools state | prompts (diagnostic entry point) |
149
+ | `gp_attach` | attach to a running app by bundle id or pid | prompts |
150
+ | `gp_observe` | snapshot the attached window's accessibility tree (digest, node count) | prompts |
151
+ | `gp_act` | perform one accessibility action and return what the engine observed changing (op id ties it to an evidence pack) | prompts (moves a real app) |
152
+ | `gp_diagnose` | classify an operation from its pack (contaminated / out-of-band / callback / pre-existing / no-change) | prompts |
153
+ | `gp_last_evidence` | fetch the evidence pack the engine archived for an operation | prompts |
154
+
155
+ Whether a method exists is read from the running engine (`hello.capabilities`) — the list
156
+ is never hard-coded here, because it grows upstream of this file. Full reference:
157
+ [`docs/tools.md`](docs/tools.md).
158
+
159
+ ## The evidence discipline
160
+
161
+ 1. **Judgement stays in Swift.** Attribution, diagnosis class, circuit-breaker level and
162
+ the pass / fail / inconclusive outcome are computed by the GlassPane engine. The
163
+ harness transcribes; it never derives. A CI ratchet fails when a tool surface grows a
164
+ threshold, a pixel verdict or a pass/fail synthesis.
165
+ 2. **What the model reads is what the engine said.** Error codes and agent-executable
166
+ remedies go into the tool's `output` string, not only into metadata.
167
+ 3. **The audit chain is a product feature.** Verified calls are appended to a hash-chained
168
+ decision log (op id ↔ entry hash); the fixed points re-compute the chain with two
169
+ independent hashers, so the ledger can be verified without trusting the writer.
170
+ 4. **Compaction may not erase evidence.** The compaction hook injects the session's
171
+ evidence anchors into the summarisation prompt; absence is stated as arithmetic
172
+ (`gp_* calls: N · decisions recorded: M`), never assumed.
173
+
174
+ Details: [`docs/evidence.md`](docs/evidence.md).
175
+
176
+ ## Documentation
177
+
178
+ - [`docs/install.md`](docs/install.md) — install paths, permissions, verification
179
+ - [`docs/models-and-keys.md`](docs/models-and-keys.md) — the model catalog and how to supply
180
+ your own API keys
181
+ - [`docs/tools.md`](docs/tools.md) — the `gp_*` surface, argument by argument
182
+ - [`docs/evidence.md`](docs/evidence.md) — attribution, diagnosis, the decision log
183
+ - [`docs/migrate-from-opencode.md`](docs/migrate-from-opencode.md) — what the private
184
+ customisation changed, and what deliberately stayed
185
+ - [`docs/release.md`](docs/release.md) — cutting a release, and the npm trusted-publisher
186
+ setup
187
+ - [`docs/troubleshooting.md`](docs/troubleshooting.md) — engine unreachable, permission
188
+ denials, the `GP_E_*` codes
189
+ - [`FORK.md`](FORK.md) / [`SYNCLOG.md`](SYNCLOG.md) — the fork's coordinates, discipline
190
+ and per-batch measurements; [`NOTICE`](NOTICE) — attribution;
191
+ [`CHANGELOG.md`](CHANGELOG.md) — what shipped in each version
192
+
193
+ ## Development
194
+
195
+ ```bash
196
+ bun install # workspace (on TLS-intercepting networks bun needs
197
+ # NODE_EXTRA_CA_CERTS — see FORK.md)
198
+ bun run typecheck # per package
199
+ bun test --timeout 30000 # fixed-point tests (from packages/opencode)
200
+ bun run build --single # product build: CLI + TUI + embedded web app
201
+ ```
202
+
203
+ The repo-side gates live in the GlassPane repository under `harness/` (hook-liveness,
204
+ fork-diff, kernel-vendor, tool-surface, surface-semantics, product-surface,
205
+ brand-surface); their rationale, negative controls and known boundaries are documented in
206
+ `harness/README.md`. Every customisation commit carries the `[gp]` prefix.
207
+
208
+ ## License & attribution
209
+
210
+ MIT, like upstream. `LICENSE` is upstream's, unchanged; [`NOTICE`](NOTICE) records what
211
+ this fork changed and where the code came from. Upstream:
212
+ [anomalyco/opencode](https://github.com/anomalyco/opencode) `v1.18.32` © SST — without
213
+ them this product does not exist, and `FORK.md` exists so that claim stays true for
214
+ every future sync.
215
+
@@ -0,0 +1,173 @@
1
+ <h1 align="center">
2
+ <code>glasspane-harness</code>
3
+ </h1>
4
+
5
+ <p align="center">
6
+ <a href="README.zh-CN.md"><strong>简体中文</strong></a> ·
7
+ <a href="README.md"><strong>English</strong></a>
8
+ </p>
9
+
10
+ <p align="center">
11
+ <a href="https://www.npmjs.com/package/glasspane-harness"><img src="https://img.shields.io/npm/dt/glasspane-harness?label=Downloads&style=for-the-badge&color=2ea44f&logo=npm&logoColor=white" alt="npm downloads"></a>
12
+ <img src="https://img.shields.io/dynamic/json?url=https%3A%2F%2Fregistry.npmjs.org%2Fglasspane-harness%2Flatest&query=version&label=version&color=brightgreen" alt="version">
13
+ <a href="https://github.com/jingzhao-l/glasspane-harness/actions/workflows/ci.yml"><img src="https://github.com/jingzhao-l/glasspane-harness/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
14
+ <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow" alt="License"></a>
15
+ <img src="https://img.shields.io/badge/macOS-13%2B-blue?logo=apple&logoColor=white" alt="macOS 13+">
16
+ <a href="https://github.com/jingzhao-l/glasspane-harness"><img src="https://img.shields.io/github/stars/jingzhao-l/glasspane-harness?style=social&label=Star" alt="Stars"></a>
17
+ </p>
18
+
19
+ <p align="center">
20
+ <img src="assets/banner.svg" alt="GlassPane Harness — 证据诚实的 macOS 应用 GUI 验证 harness" width="720">
21
+ </p>
22
+
23
+ ---
24
+
25
+ **问题。** 一个驱动真实 macOS 应用的 AI agent,没法诚实地说清界面到底有没有按它要求的动。
26
+ 它只看得见自己的工具输出,于是靠散文猜测、报成功。截图也不解决问题:截图给的是**某个瞬间**,
27
+ 不是**某次变化**,更说不清这次变化是不是那次点击造成的。
28
+
29
+ **GlassPane Harness** 是一个编码 agent([opencode](https://github.com/anomalyco/opencode)
30
+ 的 fork),通过原生 `gp_*` 工具面接到 Swift 验证引擎上。每次动作都被测量——辅助功能树 diff、
31
+ 像素 diff、崩溃与响应性信号——然后由引擎给出**它自己的**归因(`strong` / `soft` / `none`、
32
+ 熔断级、pass / fail / inconclusive)。harness 只转录,不自己下结论。成包的验证调用进哈希链
33
+ 决策日志;压缩钩子会把会话的证据锚点重新注入压缩提示词,摘要再长也丢不掉审计链。
34
+
35
+ 引擎是 [GlassPane](https://github.com/jingzhao-l/GlassPane),harness 是它的 agent 侧。
36
+
37
+ ## 这是一个完整的编程 harness,不是被削过头的 fork
38
+
39
+ 验证接线是这次分叉的落点,但它是**加法**:opencode 会做的每一件事,这个 harness 都会做——
40
+ 同样的 agent、工具、模型、权限,同样的 LSP 与 MCP 支持,同样的 TUI 与 web 应用,同样的
41
+ SDK 与 plugin API。为了塞下内核,没有任何功能被砍掉。
42
+
43
+ 这句话是**量出来的**,不是承诺。分叉锚定上游
44
+ [anomalyco/opencode](https://github.com/anomalyco/opencode) 的某个 tag,
45
+ `harness/tools/fork-diff.mjs` 每次改动都会把本树与那个 tag 逐文件对比:
46
+
47
+ ```
48
+ fork-diff vs v1.18.32: 6527/6687 byte-identical, 51 edited, 55 added, 54 deleted
49
+ ```
50
+
51
+ 上游树约 98% 逐字节保持上游原样。改动集中在 config/paths/品牌、`gp_*` 工具面、内核绑定、
52
+ 压缩钩子和打包脚本;删掉的是上游**自己的**发布管道(ghcr 镜像、AUR、Homebrew tap、
53
+ 托管 console 账号)——外加 0.4.0 里下面说的第一方账号面。
54
+
55
+ "加法"在实践中的含义:上游后续版本发布的功能,这个 fork 接得住——因为功能还在那里。
56
+
57
+ ### 唯一的例外,而且是刻意的:没有账号,自带 API key
58
+
59
+ 上游可以 `auth login` 登录 opencode 账号,用来解锁 opencode 自家的模型网关(目录里的第一方
60
+ provider)和云端会话分享。本产品没有这个账号,所以这片面是**删掉**而不是留一个跑不通的壳:
61
+
62
+ - 目录里的 `opencode` provider 条目被过滤掉
63
+ - `auth login` / `logout` / `switch`、`/org` 命令、组织切换器全部移除
64
+ - `/experimental/console*` 端点与 console 托管 provider 状态全部移除
65
+ - 分享会话到 opencode 云端的能力移除(`share` / `autoshare` 配置键一并移除)
66
+
67
+ **目录里其他一切都原封不动。** Anthropic、OpenAI、Google、GitHub Copilot、Amazon Bedrock、
68
+ Azure、OpenRouter 等等全在——几百个模型——每一个都用**你自己的 API key** 解锁:环境变量、
69
+ 配置文件里的 `{env:NAME}` 模板,或 TUI 的 `/connect` 对话框。不用注册、不用登录。见
70
+ [`docs/models-and-keys.md`](docs/models-and-keys.md)。
71
+
72
+ ## 产品面
73
+
74
+ | 产品面 | 你拿到什么 | 怎么发 |
75
+ |---|---|---|
76
+ | **CLI + TUI** | 终端里的 agent:交互式 TUI、`run` 一次性任务、`serve` 无头服务 | `glasspane-harness` / `gp-harness` 二进制,npm + 一键安装器 |
77
+ | **Web 应用**(内嵌) | 二进制自己服务的浏览器界面——没有第二个进程、不单独部署 | 嵌进二进制(`--skip-embed-web-ui` 出纯 CLI 构建) |
78
+ | **文档** | 本仓 `docs/`——安装、工具面、证据、迁移、排障 | 仓内 markdown(canonical,与代码同版本) |
79
+ | **SDK** | TypeScript SDK 与 plugin SDK,用来写自己的 `gp_*` 式工具 | 工作区包,随树发布 |
80
+
81
+ **刻意不发**:上游的托管 console / enterprise 栈(私有 harness 不需要"组织与额度后台"这种形态)、
82
+ Electron 桌面 app(第二批——需要签名与公证账号),以及上游的**文档站**(`packages/web` 仍是上游
83
+ Astro/Starlight 内容,能构建、留树,但本产品的 canonical 文档是 `docs/`,等站点由它重建前不算我们的
84
+ 文档)。三者都留在树里做血缘,让将来对着钉点 tag 的每次同步仍然诚实。
85
+
86
+ ## 安装
87
+
88
+ ```bash
89
+ npm install -g glasspane-harness # 推荐
90
+ bun add -g glasspane-harness
91
+ curl -fsSL https://raw.githubusercontent.com/jingzhao-l/glasspane-harness/main/scripts/install.sh | bash
92
+ ```
93
+
94
+ 会装出两个命令:**`glasspane-harness`** 与短别名 **`gp-harness`**。
95
+
96
+ **只支持 macOS。** 引擎、权限模型、证据流水线都只存在于 macOS,npm 分发随之收成
97
+ macOS-only:包声明 `os: darwin`,非 macOS 上 npm 直接拒绝安装,而不是给你一个跑不了的
98
+ 二进制。**没有 Linux / Windows 构建,这是决定,不是遗漏。**
99
+
100
+ 前提:macOS 13+(Apple silicon 或 Intel);要用 `gp_*` 工具面还需要 **GlassPane** 后台服务在跑且已授予辅助功能权限
101
+ ([先装 GlassPane](https://github.com/jingzhao-l/GlassPane),安装器会把下一步说清楚)。没有引擎时,
102
+ 每个 `gp_*` 调用只会回 `GP_E_ENGINE_UNREACHABLE` 加一条 remedy——那是引擎的话,不是安装器的。
103
+
104
+ 若 npm 的全局前缀不可写,用 `npm install -g --prefix "$HOME/.local" glasspane-harness` 并把
105
+ `~/.local/bin` 放进 PATH;安装器会自己检测到这种失败并把这条补救打出来。
106
+
107
+ ## 上手
108
+
109
+ ```bash
110
+ glasspane-harness # 交互式 TUI(内嵌 web 应用也会被服务出来)
111
+ glasspane-harness run "attach 到备忘录,打一个标题,然后告诉我 UI 有没有给出证据"
112
+ glasspane-harness serve --port 4096 # 无头服务;web 应用由它提供
113
+ glasspane-harness --help
114
+ ```
115
+
116
+ 任何会话里第一件该问的事是 `gp_probe_status`:它报引擎版本、宣称的能力与权限状态——
117
+ 工具面里每条 remedy 都指回它。
118
+
119
+ ## `gp_*` 工具面
120
+
121
+ | 工具 | 作用 | 权限 |
122
+ |---|---|---|
123
+ | `gp_probe_status` | 引擎自报:版本、能力、辅助功能/输入监听/屏幕录制/开发者工具状态 | 询问(诊断入口) |
124
+ | `gp_attach` | 按 bundle id 或 pid 附着到运行中的应用 | 询问 |
125
+ | `gp_observe` | 快照附着窗口的辅助功能树(digest、节点数) | 询问 |
126
+ | `gp_act` | 执行一次辅助功能动作,返回引擎观察到的东西(op id 关联证据包) | 询问(会动真实应用) |
127
+ | `gp_diagnose` | 按证据包给操作定性(污染 / 带外 / 回调 / 既有问题 / 无变化) | 询问 |
128
+ | `gp_last_evidence` | 取回引擎为某次操作归档的证据包 | 询问 |
129
+
130
+ 方法是否存在**从运行中的引擎读**(`hello.capabilities`),本文件不写死清单——那份清单在本文件
131
+ 之后还会长。完整参考:[`docs/tools.md`](docs/tools.md)。
132
+
133
+ ## 证据纪律
134
+
135
+ 1. **判定留在 Swift**:归因、诊断类、熔断级、pass / fail / inconclusive 都由 GlassPane 引擎算;
136
+ harness 只转录、不推导。工具面长出阈值、像素裁决或 pass/fail 合成,CI 棘轮即红。
137
+ 2. **模型看到的必须是引擎说过的**:错误码与可执行 remedy 进工具的 `output` 文本,不只塞 metadata。
138
+ 3. **审计链是产品功能**:成包调用进哈希链决策日志(op id ↔ entry hash);固定点用两个独立哈希
139
+ 实现复算链条,账本不必信任写它的那段代码也能验。
140
+ 4. **压缩不许抹掉证据**:压缩钩子把证据锚点注入摘要提示词;缺席以算术呈现
141
+ (`gp_* calls: N · decisions recorded: M`),不许靠默认。
142
+
143
+ 细节:[`docs/evidence.md`](docs/evidence.md)。
144
+
145
+ ## 文档
146
+
147
+ - [`docs/install.md`](docs/install.md) — 安装通道、权限、自检
148
+ - [`docs/tools.md`](docs/tools.md) — 逐个参数的 `gp_*` 参考
149
+ - [`docs/evidence.md`](docs/evidence.md) — 归因、诊断、决策日志
150
+ - [`docs/migrate-from-opencode.md`](docs/migrate-from-opencode.md) — 私有化改了什么、刻意留了什么
151
+ - [`docs/troubleshooting.md`](docs/troubleshooting.md) — 引擎不可达、权限拒绝、`GP_E_*` 码表
152
+ - [`FORK.md`](FORK.md) / [`SYNCLOG.md`](SYNCLOG.md) — 分叉坐标、纪律、每批实测数字;
153
+ [`NOTICE`](NOTICE) — 署名;[`CHANGELOG.md`](CHANGELOG.md) — 每个版本发了什么
154
+
155
+ ## 开发
156
+
157
+ ```bash
158
+ bun install # 工作区(被 TLS 拦截的网络上 bun 需要 NODE_EXTRA_CA_CERTS,见 FORK.md)
159
+ bun run typecheck
160
+ bun test --timeout 30000 # 固定点测试(在 packages/opencode 里跑)
161
+ bun run build --single # 产品构建:CLI + TUI + 内嵌 web 应用
162
+ ```
163
+
164
+ 仓侧的闸住在 GlassPane 仓的 `harness/`(hook-liveness、fork-diff、kernel-vendor、
165
+ tool-surface、surface-semantics、product-surface、brand-surface),理由、反向控制与已知边界
166
+ 写在 `harness/README.md`。我们每个定制提交都带 `[gp]` 前缀。
167
+
168
+ ## 许可与署名
169
+
170
+ MIT,与上游一致。`LICENSE` 是上游原文未改,[`NOTICE`](NOTICE) 记录本 fork 改了什么、代码来自哪里。
171
+ 上游:[anomalyco/opencode](https://github.com/anomalyco/opencode) `v1.18.32` © SST——没有他们就没有
172
+ 这个产品,而 `FORK.md` 的存在是为了让这句话在未来的每次同步后仍然成立。
173
+
package/package.json CHANGED
@@ -25,7 +25,7 @@
25
25
  "scripts": {
26
26
  "postinstall": "node ./postinstall.mjs"
27
27
  },
28
- "version": "0.3.0",
28
+ "version": "0.4.0",
29
29
  "license": "MIT",
30
30
  "os": [
31
31
  "darwin"
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "sideEffects": false,
46
46
  "optionalDependencies": {
47
- "glasspane-harness-darwin-arm64": "0.3.0",
48
- "glasspane-harness-darwin-x64": "0.3.0"
47
+ "glasspane-harness-darwin-arm64": "0.4.0",
48
+ "glasspane-harness-darwin-x64": "0.4.0"
49
49
  }
50
50
  }