@logicseek/hello-cc 1.1.0-rc.8 → 1.1.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.
- package/CHANGELOG.md +107 -0
- package/README.md +2 -0
- package/README.zh-CN.md +2 -0
- package/docs/README.md +2 -0
- package/docs/README.zh-CN.md +2 -0
- package/docs/commands.md +16 -0
- package/docs/commands.zh-CN.md +14 -0
- package/docs/dsh.md +6 -0
- package/docs/dsh.zh-CN.md +5 -0
- package/docs/native.md +21 -1
- package/docs/native.zh-CN.md +19 -1
- package/docs/private-state.md +115 -0
- package/docs/private-state.zh-CN.md +92 -0
- package/lib/cli/app.mjs +46 -5
- package/lib/cli/commands/hook.mjs +31 -4
- package/lib/cli/commands/mcp.mjs +6 -0
- package/lib/cli/commands/native.mjs +17 -4
- package/lib/cli/commands/peer.mjs +3 -0
- package/lib/cli/commands/run.mjs +196 -62
- package/lib/cli/commands/tmux.mjs +28 -19
- package/lib/cli/commands/up.mjs +25 -17
- package/lib/cli-runtime.mjs +16 -1
- package/lib/core/coordination/event-retention.mjs +2 -0
- package/lib/core/sessions/codex-thread-root.mjs +144 -0
- package/lib/core/sessions/launch.mjs +4 -0
- package/lib/discover.mjs +95 -231
- package/lib/integrations/dsh-collaboration.mjs +9 -2
- package/lib/integrations/native/claude.mjs +6 -0
- package/lib/integrations/native/codex.mjs +4 -2
- package/lib/integrations/native/dsh-acp.mjs +1 -1
- package/lib/integrations/native/jsonrpc.mjs +2 -2
- package/lib/mcp/scope.mjs +50 -8
- package/lib/mcp/tools.mjs +15 -2
- package/lib/process/pinned-cwd.mjs +64 -0
- package/lib/process/pinned-guidance.mjs +1 -0
- package/lib/process/pinned-project-state.mjs +1 -0
- package/lib/process/tmux-cwd-handoff.mjs +277 -0
- package/lib/runtime/native/cli-submissions.mjs +220 -0
- package/lib/runtime/native/client.mjs +7 -1
- package/lib/runtime/native/launcher.mjs +20 -4
- package/lib/runtime/native/service.mjs +143 -50
- package/lib/runtime/native/store.mjs +303 -14
- package/lib/runtime/private-state.mjs +435 -24
- package/lib/runtime/project-path.mjs +53 -1
- package/lib/runtime/project-trust.mjs +6 -2
- package/lib/runtime/state-migration.mjs +66 -13
- package/lib/shared/redact.mjs +4 -1
- package/lib/terminal/tmux.mjs +13 -2
- package/lib/ui/help.mjs +1 -0
- package/lib/web/codex-app-server.mjs +3 -1
- package/lib/web/codex-sessions.mjs +68 -8
- package/lib/web/context-files.mjs +194 -41
- package/lib/web/http-routes.mjs +43 -12
- package/lib/web/native-sessions.mjs +3 -0
- package/lib/web/project-contexts.mjs +27 -5
- package/lib/web/project-files.mjs +108 -26
- package/lib/web/pty-sessions.mjs +15 -2
- package/lib/web/session-serialize.mjs +6 -1
- package/lib/web/startup.mjs +3 -1
- package/lib/web/tmux-sessions.mjs +153 -50
- package/lib/web/ui-interactions.mjs +7 -4
- package/native/bin/darwin-arm64/hcc-cwd-handoff +0 -0
- package/native/bin/darwin-x64/hcc-cwd-handoff +0 -0
- package/native/bin/linux-arm64/hcc-cwd-handoff +0 -0
- package/native/bin/linux-x64/hcc-cwd-handoff +0 -0
- package/native/cwd-handoff/README.md +45 -0
- package/native/cwd-handoff/hcc-cwd-handoff.c +693 -0
- package/package.json +8 -2
- package/scripts/build-cwd-handoff.mjs +47 -0
- package/scripts/pack-cwd-handoff.mjs +27 -0
- package/scripts/regression.mjs +113 -7
- package/scripts/verify-cwd-handoff-package.mjs +60 -0
- package/scripts/web-workbench-acceptance.mjs +79 -1
- package/scripts/web-workbench-installed-acceptance.mjs +11 -1
package/CHANGELOG.md
CHANGED
|
@@ -16,6 +16,113 @@ the release description from the current changelog section. Use
|
|
|
16
16
|
`npm run release:github` with `GH_TOKEN` or `GITHUB_TOKEN` only for local
|
|
17
17
|
backfills.
|
|
18
18
|
|
|
19
|
+
## 1.1.0
|
|
20
|
+
|
|
21
|
+
### Summary
|
|
22
|
+
|
|
23
|
+
This stable release promotes the multi-provider Web workbench, native Agent
|
|
24
|
+
coordination and project-identity protections developed through rc.9 to the
|
|
25
|
+
npm `latest` channel. Its runtime code is unchanged from rc.9; the stable
|
|
26
|
+
version has its own immutable package, tag and release acceptance receipts.
|
|
27
|
+
|
|
28
|
+
### Highlights
|
|
29
|
+
|
|
30
|
+
- Coordinate Codex, Claude and DeepSeek Harness sessions from the Web workbench
|
|
31
|
+
with project Agent defaults, structured conversations and tool/approval/user
|
|
32
|
+
input views. Retain terminal and App Server modes, guarded forks, retained
|
|
33
|
+
drafts, file previews, reconnect and snapshot-gap recovery.
|
|
34
|
+
- Bind project state, managed launches, Web/native sessions and Codex history
|
|
35
|
+
to the selected directory's filesystem identity. Replacement directories
|
|
36
|
+
receive separate generations. Private-state v1 migration requires independent
|
|
37
|
+
root verification and an explicit offline drain; old stores remain preserved.
|
|
38
|
+
- Ship authenticated directory-descriptor handoff helpers for Darwin and Linux
|
|
39
|
+
on arm64 and x64, with static Linux binaries, executable-mode and source-stamp
|
|
40
|
+
checks. Missing trusted helpers reject guarded launches without a pathname
|
|
41
|
+
fallback; operators can pause new launches with `HCC_PINNED_LAUNCH_MODE=hold`.
|
|
42
|
+
- Fence Native, hook and scoped MCP mutations by current ownership, process and
|
|
43
|
+
runtime/state generations. Journal submissions before admission, recover
|
|
44
|
+
original IDs and avoid automatically replaying uncertain provider execution.
|
|
45
|
+
- Add opt-in original-App cooperation adapters while retaining the App's own
|
|
46
|
+
execution. Harness idle-inbox wakeup and Claude hooks/plugins are separate
|
|
47
|
+
provider paths; a fully idle original Codex App is not automatically awakened.
|
|
48
|
+
- Keep background terminal snapshots asynchronous and bounded, and retain
|
|
49
|
+
separate ACL cache entries for Number and BigInt stats. Preserve exact inode,
|
|
50
|
+
change-time and ACL checks, and bounded shim-registration diagnostics.
|
|
51
|
+
|
|
52
|
+
### Validation
|
|
53
|
+
|
|
54
|
+
The unchanged rc.9 runtime passed 1,992 local unit tests with three
|
|
55
|
+
platform/privilege skips, all 13 regression stages and 45 browser checks per
|
|
56
|
+
source/temporary installation. Its master CI passed 14 jobs and its immutable
|
|
57
|
+
release/tag CI passed three jobs on their first attempts.
|
|
58
|
+
|
|
59
|
+
The 1.1.0 version, frozen package, installed-provider checks and final commit/tag
|
|
60
|
+
CI retain separate release receipts. Simulated-provider browser checks remain
|
|
61
|
+
separate from real model calls. CI/platform execution does not establish every
|
|
62
|
+
employee-device, provider, cross-device recovery or business workflow. Existing
|
|
63
|
+
preview archives and their evidence remain unchanged.
|
|
64
|
+
|
|
65
|
+
## 1.1.0-rc.9
|
|
66
|
+
|
|
67
|
+
### Summary
|
|
68
|
+
|
|
69
|
+
This preview binds project state, managed launches and Web/native sessions to
|
|
70
|
+
the selected directory's filesystem identity. Replacing a directory at the
|
|
71
|
+
same pathname no longer authorizes reuse of its old state or Codex history.
|
|
72
|
+
It continues the existing npm preview channel and adds packaged native helpers
|
|
73
|
+
for authenticated tmux directory-descriptor handoff.
|
|
74
|
+
|
|
75
|
+
### Highlights
|
|
76
|
+
|
|
77
|
+
- Introduce private-state v2 bindings with positive directory birth-time
|
|
78
|
+
receipts and separate replacement generations. Preserve the original store;
|
|
79
|
+
historical v1 upgrades require independent root verification, a matching
|
|
80
|
+
inspection receipt and an explicit offline drain. Interrupted upgrades remain
|
|
81
|
+
fenced until a reviewed retry completes.
|
|
82
|
+
- Pass an already-open directory descriptor to the authorized tmux pane through
|
|
83
|
+
a native broker/client, validating kernel peer identity and the bound receipt
|
|
84
|
+
before launch. Ship Darwin/Linux arm64/x64 helpers, static Linux binaries and
|
|
85
|
+
build/package checks; a missing trusted helper rejects the launch without a
|
|
86
|
+
pathname fallback. `HCC_PINNED_LAUNCH_MODE=hold` pauses new guarded sessions.
|
|
87
|
+
- Recheck selected-directory identity before CLI launches, hook registration
|
|
88
|
+
and managed discovery. Persist Codex thread-to-root receipts and require an
|
|
89
|
+
explicit verified thread for terminal resume/fork; pathname-only histories
|
|
90
|
+
and managed `--last` launches cannot establish that binding.
|
|
91
|
+
- Add a durable Native owner record alongside the existing file-lock guard.
|
|
92
|
+
Native, hook and scoped MCP mutations recheck runtime/state generations and
|
|
93
|
+
process identity under the writer fence. Journal CLI submissions before
|
|
94
|
+
admission and recover with the original ID; uncertain provider execution is
|
|
95
|
+
not automatically replayed. Retain sandbox and expected-generation checks.
|
|
96
|
+
- Bind Web project/session keys, Codex history and file/context operations to
|
|
97
|
+
the selected directory and database. Preserve active sessions' original
|
|
98
|
+
bindings when a replacement is explicitly selected. Keep tmux ownership and
|
|
99
|
+
cleanup conditional, reject invalid routes before state resolution, and make
|
|
100
|
+
user-question answers require current control and an explicit submit action.
|
|
101
|
+
- Document the migration, ownership and historical-session boundaries in
|
|
102
|
+
Chinese and English. Add four-platform helper build/installed-package CI and
|
|
103
|
+
verify executable modes and source stamps in the frozen npm package.
|
|
104
|
+
- Add bounded, structured shim-registration diagnostics that distinguish
|
|
105
|
+
provider entry, persisted binding/pane evidence and peer-list database
|
|
106
|
+
fallback. Public diagnostics retain fixture-owned booleans and finite enums.
|
|
107
|
+
- Keep separate ACL cache entries for Number and BigInt filesystem stats.
|
|
108
|
+
Alternating validation paths reuse unchanged results while preserving exact
|
|
109
|
+
inode and change-time checks; permission and ACL changes still force a fresh
|
|
110
|
+
inspection in both representations.
|
|
111
|
+
|
|
112
|
+
### Validation
|
|
113
|
+
|
|
114
|
+
The rc.9 source passed 1,992 local unit tests with three platform/privilege
|
|
115
|
+
skips and all 13 regression stages. The integration browser baseline passed
|
|
116
|
+
45 checks each for source and temporary npm installations. These checks use real
|
|
117
|
+
HTTP, WebSocket and SQLite with simulated providers, cover desktop and 390px
|
|
118
|
+
layouts, and retain separate cleanup and source-hash receipts.
|
|
119
|
+
|
|
120
|
+
Native helper formats, executable permissions, C-source stamps and packed-file
|
|
121
|
+
hashes are checked separately from platform execution. Final source-commit CI,
|
|
122
|
+
the immutable rc.9 archive and tag acceptance retain their own receipts.
|
|
123
|
+
These checks do not establish real-model calls, device upgrades or business
|
|
124
|
+
acceptance. Existing released archives and their evidence remain unchanged.
|
|
125
|
+
|
|
19
126
|
## 1.1.0-rc.8
|
|
20
127
|
|
|
21
128
|
### Summary
|
package/README.md
CHANGED
|
@@ -207,6 +207,8 @@ generic session-isolation assumptions.
|
|
|
207
207
|
- [User Guide](docs/guide.md): setup, Web console, workflows, coordination
|
|
208
208
|
semantics, and environment behavior.
|
|
209
209
|
- [Command Reference](docs/commands.md): compact public command list.
|
|
210
|
+
- [Project directory identity and private state](docs/private-state.md): v2
|
|
211
|
+
bindings, replacement generations, offline upgrades and verified Codex history.
|
|
210
212
|
- [DeepSeek Harness](docs/dsh.md): hooks/Cordis collaboration, ACP workers,
|
|
211
213
|
project setup and Web launch, with real-model and local-package acceptance evidence.
|
|
212
214
|
- [Native Workers](docs/native.md): HCC-owned Codex, Claude SDK, and dsh ACP
|
package/README.zh-CN.md
CHANGED
|
@@ -186,6 +186,8 @@ hcc task done --id 1 --summary "Done"
|
|
|
186
186
|
- [文档目录](docs/README.zh-CN.md):全部用户文档和实现文档入口。
|
|
187
187
|
- [用户指南](docs/guide.zh-CN.md):安装、Web 控制台、协作流程、协作语义和环境变量行为。
|
|
188
188
|
- [命令参考](docs/commands.zh-CN.md):紧凑公共命令清单。
|
|
189
|
+
- [项目目录身份与私有状态](docs/private-state.zh-CN.md):v2 绑定、替换目录分代、
|
|
190
|
+
离线升级及已核实的 Codex 历史边界。
|
|
189
191
|
- [DeepSeek Harness 接入](docs/dsh.zh-CN.md):hooks/Cordis 协作、ACP worker、
|
|
190
192
|
项目配置与 Web 启动;附真实模型和本地包验收记录。
|
|
191
193
|
- [Native 后台 worker](docs/native.zh-CN.md):HCC 持有的 Codex、Claude SDK、dsh ACP
|
package/docs/README.md
CHANGED
|
@@ -17,6 +17,8 @@ authenticated selection of any existing server directory are accepted risks.
|
|
|
17
17
|
workflow, stable peer identity, and environment behavior.
|
|
18
18
|
- [Command Reference](commands.md): compact list of public commands and the
|
|
19
19
|
intended use of each command group.
|
|
20
|
+
- [Project directory identity and private state](private-state.md): state locations,
|
|
21
|
+
v2 generations, cold migration receipts, launch holds and Codex history identity.
|
|
20
22
|
- [DeepSeek Harness](dsh.md): project setup, hooks/Cordis collaboration, ACP workers,
|
|
21
23
|
installable bundles, and session routing boundaries.
|
|
22
24
|
- [Native Workers](native.md): owned background workers, provider adapters,
|
package/docs/README.zh-CN.md
CHANGED
|
@@ -14,6 +14,8 @@ provider peer ID 已变更且不会映射旧 ID;受保护接口使用 Runtime
|
|
|
14
14
|
- [用户指南](guide.zh-CN.md):安装、启动、Web 控制台、协作语义、工作流、稳定
|
|
15
15
|
peer 身份和环境变量行为。
|
|
16
16
|
- [命令参考](commands.zh-CN.md):公共命令的紧凑清单,以及每组命令的用途。
|
|
17
|
+
- [项目目录身份与私有状态](private-state.zh-CN.md):状态位置、v2 分代、冷停机
|
|
18
|
+
迁移回执、暂停新启动和 Codex 历史身份。
|
|
17
19
|
- [DeepSeek Harness 接入](dsh.zh-CN.md):项目配置、hooks/Cordis 协作、ACP worker、
|
|
18
20
|
可安装 bundle 与会话路由边界。
|
|
19
21
|
- [Native 后台 worker](native.zh-CN.md):后台 worker 所有权、provider adapter、
|
package/docs/commands.md
CHANGED
|
@@ -21,6 +21,22 @@ hcc uninstall [--purge --yes]
|
|
|
21
21
|
hooks, shims, and the shell PATH entry; add `--purge --yes` only when you also want to remove the
|
|
22
22
|
current project's `.hello-cc` data and guidance blocks.
|
|
23
23
|
|
|
24
|
+
## Offline State Migration
|
|
25
|
+
|
|
26
|
+
```text
|
|
27
|
+
hcc --root DIR migrate-state --offline --yes
|
|
28
|
+
hcc --root DIR --json migrate-state --inspect-private-binding
|
|
29
|
+
hcc --root DIR migrate-state --upgrade-private-binding --offline --yes --assert-historical-root --expect-receipt=SHA256
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The first command snapshots retained project-local state into private storage.
|
|
33
|
+
The other two inspect and explicitly upgrade an existing private v1 directory
|
|
34
|
+
binding. Independently verify the historical root, back up its state and stop
|
|
35
|
+
all writers before an upgrade; the inspection receipt is not historical-root
|
|
36
|
+
proof. Interrupted publication stays fenced until a reviewed retry completes.
|
|
37
|
+
See [Project directory identity and private state](private-state.md) for recovery
|
|
38
|
+
boundaries, v2 replacement generations and `HCC_PINNED_LAUNCH_MODE=hold`.
|
|
39
|
+
|
|
24
40
|
## Read-only Diagnostics
|
|
25
41
|
|
|
26
42
|
```text
|
package/docs/commands.zh-CN.md
CHANGED
|
@@ -19,6 +19,20 @@ hcc uninstall [--purge --yes]
|
|
|
19
19
|
只有在确定也要删除当前项目的 `.hello-cc` 数据和指导块时,才加
|
|
20
20
|
`--purge --yes`。
|
|
21
21
|
|
|
22
|
+
## 离线状态迁移
|
|
23
|
+
|
|
24
|
+
```text
|
|
25
|
+
hcc --root DIR migrate-state --offline --yes
|
|
26
|
+
hcc --root DIR --json migrate-state --inspect-private-binding
|
|
27
|
+
hcc --root DIR migrate-state --upgrade-private-binding --offline --yes --assert-historical-root --expect-receipt=SHA256
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
第一条命令将保留的项目局部状态制作快照,迁入私有目录。后两条用于检查并
|
|
31
|
+
明确升级已有私有 v1 目录绑定。升级前独立核实历史根目录、备份状态,并停止
|
|
32
|
+
全部写入者;检查回执不证明当前目录就是历史根。发布中断时保留封锁标记,
|
|
33
|
+
经核实的重试完成后才恢复访问。恢复边界、v2 替换目录分代和
|
|
34
|
+
`HCC_PINNED_LAUNCH_MODE=hold` 见[项目目录身份与私有状态](private-state.zh-CN.md)。
|
|
35
|
+
|
|
22
36
|
## 只读诊断
|
|
23
37
|
|
|
24
38
|
```text
|
package/docs/dsh.md
CHANGED
|
@@ -20,6 +20,12 @@ Below, `hcc` means a CLI containing these changes. An older global installation
|
|
|
20
20
|
|
|
21
21
|
macOS 1.0.5 upgrades use a stable boot-session identity. Follow the [process identity migration notes](macos-process-identity.md) and restart owned runtimes normally.
|
|
22
22
|
|
|
23
|
+
Project state may resolve to private v2 storage. The `.hello-cc` paths below are
|
|
24
|
+
logical project-state paths; managed setup and session routing use the resolved
|
|
25
|
+
store. Stop Harness and other state writers before a migration. Existing private
|
|
26
|
+
v1 bindings require the explicit historical-root inspection and upgrade receipt
|
|
27
|
+
flow in [Project directory identity and private state](private-state.md).
|
|
28
|
+
|
|
23
29
|
## Choose An Entry Point
|
|
24
30
|
|
|
25
31
|
| Entry | Use | Lifecycle owner |
|
package/docs/dsh.zh-CN.md
CHANGED
|
@@ -20,6 +20,11 @@ node /absolute/path/to/hello-cc/bin/hcc.mjs --root /path/to/project dsh web -- -
|
|
|
20
20
|
|
|
21
21
|
macOS 从 1.0.5 起使用稳定的启动周期标记。升级时按[进程身份迁移说明](macos-process-identity.md)正常重启所管理的运行时,保留身份无法比较的旧进程。
|
|
22
22
|
|
|
23
|
+
项目状态可以解析到私有 v2 目录。下文 `.hello-cc` 路径表示逻辑项目状态位置;
|
|
24
|
+
受管理 setup 和会话路由使用解析后的状态目录。迁移前应停止 Harness 和其他
|
|
25
|
+
状态写入者。已有私有 v1 绑定必须经过明确核实历史根目录的检查与回执升级流程,
|
|
26
|
+
详见[项目目录身份与私有状态](private-state.zh-CN.md)。
|
|
27
|
+
|
|
23
28
|
## 选择入口
|
|
24
29
|
|
|
25
30
|
| 入口 | 适用场景 | 会话由谁持有 |
|
package/docs/native.md
CHANGED
|
@@ -16,6 +16,25 @@ multiple pending inbox messages into the same turn. ACP resume and session close
|
|
|
16
16
|
depend on the extensions the provider advertises. HCC does not claim that an ACP
|
|
17
17
|
resume replays the original conversation transcript.
|
|
18
18
|
|
|
19
|
+
## Runtime ownership and directory identity
|
|
20
|
+
|
|
21
|
+
The runtime retains its file-lock ownership guard and adds a durable SQLite
|
|
22
|
+
owner fence. The owner records runtime generation, mesh database, private-state
|
|
23
|
+
generation, root directory identity and process PID/start token/command hash.
|
|
24
|
+
Native writes and derived hook/scoped MCP writes recheck that owner under the
|
|
25
|
+
shared writer fence. A live or unverified owner blocks takeover; a successor can
|
|
26
|
+
claim released state or an owner proven to have exited. Directory replacement
|
|
27
|
+
and stale executor capabilities cannot authorize writes to the successor.
|
|
28
|
+
|
|
29
|
+
Old runtime pointers without a directory identity receipt or owner fence are
|
|
30
|
+
rejected with `PROJECT_PATH_CHANGED` or `NATIVE_OWNER_UNVERIFIED`, respectively.
|
|
31
|
+
Stop the old runtime using its running build and confirm exit before starting a new one. Native
|
|
32
|
+
provider processes use their scoped HCC MCP tools; ordinary `hcc` commands from
|
|
33
|
+
that environment are rejected with `NATIVE_CLI_SCOPE_REQUIRED`. These checks
|
|
34
|
+
retain the existing sandbox-policy and expected-runtime-generation rules.
|
|
35
|
+
See [Project directory identity and private state](private-state.md) for v1
|
|
36
|
+
binding upgrade receipts and replacement generations.
|
|
37
|
+
|
|
19
38
|
## Session fork and retries with the original ID
|
|
20
39
|
|
|
21
40
|
`hcc native fork --parent codex-reviewer --peer codex-branch` invokes the provider's
|
|
@@ -221,7 +240,8 @@ resolve the reported problem and retry `native down`.
|
|
|
221
240
|
|
|
222
241
|
Worker events retain semantic output and completion evidence; token deltas are
|
|
223
242
|
not persisted as delivery receipts. The runtime keeps local state under
|
|
224
|
-
`<project
|
|
243
|
+
`<resolved-project-state>/native/` (project-local or private storage described
|
|
244
|
+
above) and coordination records in the selected HCC
|
|
225
245
|
database. Runtime control is a local authenticated API, separate from the
|
|
226
246
|
browser terminal transport. Treat its local runtime pointer and log as private
|
|
227
247
|
project state.
|
package/docs/native.zh-CN.md
CHANGED
|
@@ -14,6 +14,23 @@ Native 模式运行由 HCC 创建并持有的后台 worker。共享 peer、任
|
|
|
14
14
|
不代表 host 会把多条待处理消息塞进同一个 turn。ACP 的 resume 和 session close
|
|
15
15
|
取决于 provider 声明的扩展;不能把 ACP resume 等同于重放原始会话历史。
|
|
16
16
|
|
|
17
|
+
## Runtime 所有权与目录身份
|
|
18
|
+
|
|
19
|
+
Runtime 保留原有 file-lock owner 保护,并增加持久化的 SQLite owner 校验。
|
|
20
|
+
owner 保存 runtime generation、mesh 数据库、私有状态 generation、根目录身份
|
|
21
|
+
以及进程 PID、启动标记和命令哈希。Native 写入及派生 hook/scoped MCP 写入在
|
|
22
|
+
同一个 writer fence 中复核 owner。存活或无法核实的 owner 阻止接管;后继进程
|
|
23
|
+
只能接管已释放或已证实退出的 owner。目录替换或旧执行器 capability 不能授权
|
|
24
|
+
写入后继状态。
|
|
25
|
+
|
|
26
|
+
旧 runtime pointer 缺少目录身份回执或 owner fence 时分别被
|
|
27
|
+
`PROJECT_PATH_CHANGED` 或 `NATIVE_OWNER_UNVERIFIED` 拒绝。
|
|
28
|
+
先用正在运行的旧版本停止它,确认退出后再启动新版本。Native provider 子进程
|
|
29
|
+
通过其 scoped HCC MCP 工具协作;在该环境中直接调用普通 `hcc` 命令会收到
|
|
30
|
+
`NATIVE_CLI_SCOPE_REQUIRED`。原 sandbox policy 和 expected runtime generation
|
|
31
|
+
规则继续生效。v1 绑定升级回执和替换目录分代见
|
|
32
|
+
[项目目录身份与私有状态](private-state.zh-CN.md)。
|
|
33
|
+
|
|
17
34
|
## 会话 fork 与原 ID 重试
|
|
18
35
|
|
|
19
36
|
`hcc native fork --parent codex-reviewer --peer codex-branch` 使用 provider 自身的
|
|
@@ -188,7 +205,8 @@ HCC 不为只读 worker 注入自有的任务/锁/结果写操作 MCP,也
|
|
|
188
205
|
`status.shutdown_error` 报告错误;处理所报问题后,再次执行 `native down`。
|
|
189
206
|
|
|
190
207
|
事件保留语义输出和完成证据,不把 token delta 持久化为投递回执。runtime 状态位于
|
|
191
|
-
|
|
208
|
+
`<解析后的项目状态目录>/native/`,可以是项目局部或上方说明的私有状态;协作记录
|
|
209
|
+
仍写入所选 HCC 数据库。控制接口是独立于 Web
|
|
192
210
|
终端传输的本地认证 API;其 runtime pointer 和日志属于项目私有状态。
|
|
193
211
|
|
|
194
212
|
## 如何理解投递回执
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# Project directory identity and private state
|
|
2
|
+
|
|
3
|
+
English | [中文](private-state.zh-CN.md)
|
|
4
|
+
|
|
5
|
+
Use a build containing the commands below; an older global installation may not
|
|
6
|
+
include them. These instructions describe state handling, not a receipt for an
|
|
7
|
+
installation, model call or production migration.
|
|
8
|
+
|
|
9
|
+
## Directory selection and state location
|
|
10
|
+
|
|
11
|
+
HCC binds a selected project to its canonical directory and filesystem identity
|
|
12
|
+
(`dev`, `ino`, and `birthtimeNs`). It checks that identity again before opening
|
|
13
|
+
state, launching a session and admitting managed mutations. A replacement at
|
|
14
|
+
the same pathname is a different project directory. `PROJECT_PATH_CHANGED`
|
|
15
|
+
requires selecting the current directory again; retained sessions keep their
|
|
16
|
+
original binding.
|
|
17
|
+
|
|
18
|
+
Stable trusted projects may keep state under `<project>/.hello-cc`. Projects that
|
|
19
|
+
need private state use `~/.hello-cc/projects/<SHA256-of-canonical-root>/`. Once a
|
|
20
|
+
private binding is established, it remains authoritative even if permissions
|
|
21
|
+
change or its directory disappears. HCC refuses to silently fall back to an
|
|
22
|
+
old project-local database.
|
|
23
|
+
|
|
24
|
+
Private binding format v2 records the full directory identity and requires a
|
|
25
|
+
positive filesystem birth time; an unavailable or zero value is rejected. If original A
|
|
26
|
+
has a valid v2 binding and the same path is later occupied by B, explicit Web
|
|
27
|
+
selection can provision B under
|
|
28
|
+
`~/.hello-cc/projects/<hash>.generations/<generation>/`. A's state directory and
|
|
29
|
+
root manifest are retained; the original authority marker is fenced against
|
|
30
|
+
older readers. B receives separate state and a separate managed tmux namespace.
|
|
31
|
+
Missing, conflicting or unbound generation records require recovery rather
|
|
32
|
+
than automatic reuse. This binding version is separate from the mesh database
|
|
33
|
+
schema version.
|
|
34
|
+
|
|
35
|
+
## Migrating project-local state
|
|
36
|
+
|
|
37
|
+
When HCC reports `STATE_MIGRATION_REQUIRED`, stop every writer before moving
|
|
38
|
+
the retained project-local store into private state. Include Web and Native
|
|
39
|
+
runtimes, PTY/tmux sessions, hooks, Harness processes and external database
|
|
40
|
+
clients. Back up the project-local store and any existing private state,
|
|
41
|
+
authority markers and generation records.
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
hcc --root /absolute/path/to/project migrate-state --offline --yes
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
The migrator checks known runtime/PTY/mesh process evidence, snapshots SQLite
|
|
48
|
+
including WAL, validates the snapshot and leaves the source directory intact.
|
|
49
|
+
`--offline` is the operator's assertion that all writers have stopped; observed
|
|
50
|
+
process records cannot establish the absence of unregistered writers. Managed
|
|
51
|
+
DSH artifacts are verified and archived, then rebuilt for the private path.
|
|
52
|
+
Edited managed DSH artifacts, unsafe filesystem entries or a source changing
|
|
53
|
+
during the snapshot fail closed.
|
|
54
|
+
|
|
55
|
+
## Upgrading a historical private v1 binding
|
|
56
|
+
|
|
57
|
+
`STATE_BINDING_UPGRADE_REQUIRED` means an existing private store lacks v2's
|
|
58
|
+
birth-time binding. Matching pathname, device and inode alone cannot identify
|
|
59
|
+
historical A. Independently verify A and cold-drain its writers before upgrade.
|
|
60
|
+
If the path now holds B, restore and verify A at that path first; selecting B
|
|
61
|
+
cannot upgrade A's historical v1 metadata automatically.
|
|
62
|
+
|
|
63
|
+
Inspect without changing the binding:
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
hcc --root /absolute/path/to/project --json migrate-state --inspect-private-binding
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
The result reports `status` and, when required or pending, a SHA256 `receipt`.
|
|
70
|
+
The receipt describes the currently observed metadata; it does not prove that
|
|
71
|
+
the current directory is historical A. After independent verification, backup
|
|
72
|
+
and cold drain, copy the exact receipt into:
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
hcc --root /absolute/path/to/project migrate-state \
|
|
76
|
+
--upgrade-private-binding --offline --yes --assert-historical-root \
|
|
77
|
+
--expect-receipt=COPY_THE_INSPECTION_SHA256
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Upgrade checks known writers both before and after publication, durably fences
|
|
81
|
+
v1 readers first, then writes the v2 root manifest and removes the pending
|
|
82
|
+
fence. It updates binding metadata without copying the store. A publication or
|
|
83
|
+
second offline-check failure leaves access fenced. Inspect again and retry
|
|
84
|
+
with the same verified root and a matching receipt; preserve all evidence if
|
|
85
|
+
manual recovery is reported. Do not fabricate markers or purge a historical
|
|
86
|
+
store to make an upgrade pass. Older readers can reject v2 state, so drain old
|
|
87
|
+
builds before switching execution.
|
|
88
|
+
|
|
89
|
+
## Pausing new launches
|
|
90
|
+
|
|
91
|
+
`HCC_PINNED_LAUNCH_MODE` accepts `pinned` (also the default when unset) or `hold`.
|
|
92
|
+
`hold` rejects new guarded session launches with `PINNED_LAUNCH_PAUSED`; it does
|
|
93
|
+
not terminate existing processes or revoke a launch already prepared. Invalid
|
|
94
|
+
values are rejected. A provider environment that strips HCC variables cannot
|
|
95
|
+
clear the parent process's hold. Maintenance workers used for pinned file and
|
|
96
|
+
guidance operations remain available.
|
|
97
|
+
|
|
98
|
+
Set this environment on the invoking HCC process. Changing a later shell's
|
|
99
|
+
environment does not update a running Web or Native runtime. A hold is not a
|
|
100
|
+
substitute for stopping every writer before migration.
|
|
101
|
+
|
|
102
|
+
## Codex terminal history
|
|
103
|
+
|
|
104
|
+
HCC's Codex history controls require a persisted thread-to-root identity receipt.
|
|
105
|
+
Built-in new/fork launches record the resulting thread's original directory;
|
|
106
|
+
resume and fork verify both that identity and the explicit thread ID. The Web
|
|
107
|
+
history list omits unverified or conflicting entries and reports their count.
|
|
108
|
+
An old cwd string, imported peer row or manually assembled command does not
|
|
109
|
+
establish a verified root. `CODEX_HISTORY_UNVERIFIED` and conflicting bindings
|
|
110
|
+
require manual review; HCC provides no automatic historical association command.
|
|
111
|
+
|
|
112
|
+
Terminal `codex resume --last` and `codex fork --last` cannot establish an exact
|
|
113
|
+
thread and are rejected by these managed controls. Select an explicit verified
|
|
114
|
+
thread ID. [Native workers](native.md) retain their separate saved-worker resume
|
|
115
|
+
and ownership rules, including `native start --resume last`.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# 项目目录身份与私有状态
|
|
2
|
+
|
|
3
|
+
[English](private-state.md) | 中文
|
|
4
|
+
|
|
5
|
+
请使用包含下方命令的版本;旧的全局安装可能尚未支持。这份文档说明状态处理
|
|
6
|
+
规则,不代表已完成设备安装、模型调用或生产状态迁移。
|
|
7
|
+
|
|
8
|
+
## 目录选择与状态位置
|
|
9
|
+
|
|
10
|
+
HCC 将所选项目绑定到 canonical 目录与文件系统身份(`dev`、`ino`、
|
|
11
|
+
`birthtimeNs`),并在打开状态、启动会话和接收受控修改前复核。同一路径被替换
|
|
12
|
+
后属于另一个项目目录。遇到 `PROJECT_PATH_CHANGED` 应重新选择当前目录;已有
|
|
13
|
+
会话仍保留原目录绑定。
|
|
14
|
+
|
|
15
|
+
稳定且可信的项目可以把状态保存在 `<project>/.hello-cc`。需要私有状态的项目
|
|
16
|
+
使用 `~/.hello-cc/projects/<canonical-root的SHA256>/`。私有绑定建立后,即使
|
|
17
|
+
权限变化或目录丢失,它仍是权威状态;HCC 不会静默退回旧的项目局部数据库。
|
|
18
|
+
|
|
19
|
+
私有绑定 v2 保存完整目录身份,要求文件系统提供正值的目录创建时间;缺失或
|
|
20
|
+
零值会被拒绝。原目录 A 已有有效 v2 绑定,而同一路径后来被
|
|
21
|
+
B 占用时,Web 的明确目录选择可在
|
|
22
|
+
`~/.hello-cc/projects/<hash>.generations/<generation>/` 为 B 建立独立状态。
|
|
23
|
+
A 的状态目录与根 manifest 保留,原 authority marker 增加阻止旧版读取的标记。
|
|
24
|
+
B 使用独立状态和 managed tmux namespace。分代记录丢失、冲突或没有对应绑定时
|
|
25
|
+
要求恢复,不会自动复用。私有绑定版本与 mesh 数据库 schema 版本彼此独立。
|
|
26
|
+
|
|
27
|
+
## 迁移项目局部状态
|
|
28
|
+
|
|
29
|
+
遇到 `STATE_MIGRATION_REQUIRED` 时,先停止全部写入者,再把保留的项目局部
|
|
30
|
+
状态迁入私有目录。写入者包括 Web、Native runtime、PTY/tmux 会话、hooks、
|
|
31
|
+
Harness 进程和外部数据库客户端。备份项目局部状态,以及已有的私有目录、
|
|
32
|
+
authority marker 和 generation 记录。
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
hcc --root /absolute/path/to/project migrate-state --offline --yes
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
迁移会检查已记录的 runtime、PTY 和 mesh 进程证据,创建包含 WAL 的 SQLite
|
|
39
|
+
快照并校验,保留源目录。`--offline` 是操作者对全部写入者已停止的断言;已记录
|
|
40
|
+
进程不能证明没有未登记写入者。受管理的 DSH 文件会先验证、归档,再按私有路径
|
|
41
|
+
重建。受管理 DSH 文件被改、文件系统条目不安全或快照期间来源改变时会被拒绝。
|
|
42
|
+
|
|
43
|
+
## 升级历史私有 v1 绑定
|
|
44
|
+
|
|
45
|
+
`STATE_BINDING_UPGRADE_REQUIRED` 表示已有私有状态缺少 v2 的目录创建时间绑定。
|
|
46
|
+
仅有相同路径、device 和 inode 不能确认当前目录就是历史 A。升级前应独立核实
|
|
47
|
+
A 的身份,并冷停机全部写入者。若当前路径已是 B,应先在该路径恢复并核实 A;
|
|
48
|
+
选择 B 不会自动升级 A 的历史 v1 元数据。
|
|
49
|
+
|
|
50
|
+
先检查,保持绑定不变:
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
hcc --root /absolute/path/to/project --json migrate-state --inspect-private-binding
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
结果包含 `status`;需要升级或尚未完成时包含 SHA256 `receipt`。回执描述当前
|
|
57
|
+
观察到的元数据,不能证明当前目录就是历史 A。独立核实、备份并完成冷停机后,
|
|
58
|
+
把本次准确回执复制到:
|
|
59
|
+
|
|
60
|
+
```sh
|
|
61
|
+
hcc --root /absolute/path/to/project migrate-state \
|
|
62
|
+
--upgrade-private-binding --offline --yes --assert-historical-root \
|
|
63
|
+
--expect-receipt=COPY_THE_INSPECTION_SHA256
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
升级在发布前后检查已知写入者,先持久化阻止 v1 读取的标记,再写入 v2 根
|
|
67
|
+
manifest,最后清除 pending 标记。它只升级绑定元数据,不复制状态目录。发布
|
|
68
|
+
失败或第二次离线检查失败时,状态仍被封锁。重新检查后,在同一个已核实根目录
|
|
69
|
+
和匹配回执下重试;报告需要人工恢复时保留全部证据。不要伪造 marker 或清空
|
|
70
|
+
历史状态来绕过升级。旧版本可能拒绝 v2 状态,应先停止旧版本的执行再切换。
|
|
71
|
+
|
|
72
|
+
## 暂停新启动
|
|
73
|
+
|
|
74
|
+
`HCC_PINNED_LAUNCH_MODE` 只接受 `pinned`(未设置时也是默认行为)或 `hold`。
|
|
75
|
+
`hold` 以 `PINNED_LAUNCH_PAUSED` 拒绝新的受控会话启动,不终止已有进程,也
|
|
76
|
+
不撤销已经准备完成的启动。其他取值被拒绝。provider 环境清除 HCC 变量也不能
|
|
77
|
+
解除父进程的 hold。用于固定目录文件或指导块操作的 maintenance worker 仍可运行。
|
|
78
|
+
|
|
79
|
+
环境变量应设置在调用 HCC 的进程上;后来修改另一个 shell 的环境不会更新正在
|
|
80
|
+
运行的 Web 或 Native runtime。hold 不能代替迁移前停止全部写入者。
|
|
81
|
+
|
|
82
|
+
## Codex 终端历史边界
|
|
83
|
+
|
|
84
|
+
HCC 的 Codex 历史入口要求持久化的 thread 与原根目录身份回执。内置 new/fork
|
|
85
|
+
启动记录最终 thread 的原目录,resume/fork 同时校验目录身份与明确 thread ID。
|
|
86
|
+
Web 历史列表省略未核实或冲突的记录,并返回这类记录的数量。旧的 cwd 字符串、
|
|
87
|
+
导入的 peer 记录或手工拼接命令都不能建立可信绑定。
|
|
88
|
+
`CODEX_HISTORY_UNVERIFIED` 和冲突绑定需要人工审查;HCC 未提供自动关联历史的命令。
|
|
89
|
+
|
|
90
|
+
终端 `codex resume --last` / `codex fork --last` 无法确定准确 thread,因此被这些
|
|
91
|
+
受控入口拒绝;应选择明确且已核实的 thread ID。[Native worker](native.zh-CN.md)
|
|
92
|
+
采用独立的保存会话与所有权规则,仍支持 `native start --resume last`。
|
package/lib/cli/app.mjs
CHANGED
|
@@ -91,7 +91,8 @@ import { assignTeamWorkers, expandTeamWorkers, inferTeamItems } from '../core/co
|
|
|
91
91
|
import { autoPeerBasis, autoPeerKind, autoPeerProviderSession, autoPeerResumeId, autoPeerSessionId, readAncestorCliInfo, resolveCurrentPeer, resumeIdFromArgs, shortHash } from '../integrations/peers/identity.mjs';
|
|
92
92
|
import { inspectProviderProcess } from '../integrations/peers/processes.mjs';
|
|
93
93
|
import { registerProjectActivity } from '../runtime/projects.mjs';
|
|
94
|
-
import { migrateLegacyProjectState } from '../runtime/state-migration.mjs';
|
|
94
|
+
import { assertPrivateStateOffline, migrateLegacyProjectState } from '../runtime/state-migration.mjs';
|
|
95
|
+
import { inspectPrivateProjectBindingUpgrade, upgradePrivateProjectBinding } from '../runtime/private-state.mjs';
|
|
95
96
|
import { projectDbPath } from '../runtime/paths.mjs';
|
|
96
97
|
import { ensureDshIntegration } from '../integrations/dsh.mjs';
|
|
97
98
|
|
|
@@ -590,13 +591,45 @@ function removeGuidanceBlocks(ctx, options = {}) {
|
|
|
590
591
|
|
|
591
592
|
function cmdMigrateState(ctx, args) {
|
|
592
593
|
if (wantsHelp(args)) {
|
|
593
|
-
console.log(`${CLI_NAME} migrate-state --offline --yes\n
|
|
594
|
+
console.log(`${CLI_NAME} migrate-state --offline --yes\n` +
|
|
595
|
+
`${CLI_NAME} migrate-state --inspect-private-binding\n` +
|
|
596
|
+
`${CLI_NAME} migrate-state --upgrade-private-binding --offline --yes ` +
|
|
597
|
+
'--assert-historical-root --expect-receipt=SHA256\n\n' +
|
|
594
598
|
'Stop all old hello-cc Web, Native, PTY, tmux, hook and external database writers first. ' +
|
|
595
|
-
'
|
|
599
|
+
'A private binding upgrade requires independent confirmation that the current root is the historical root. ' +
|
|
600
|
+
'The inspection receipt alone cannot prove this. The ordinary migration snapshots SQLite including WAL ' +
|
|
601
|
+
'and leaves the old directory untouched.');
|
|
596
602
|
return;
|
|
597
603
|
}
|
|
598
|
-
const opts = parseOpts(args, { booleans: ['offline', 'yes'
|
|
599
|
-
|
|
604
|
+
const opts = parseOpts(args, { booleans: ['offline', 'yes', 'inspect-private-binding',
|
|
605
|
+
'upgrade-private-binding', 'assert-historical-root'] });
|
|
606
|
+
validateOpts('migrate-state', opts, ['offline', 'yes', 'inspect-private-binding',
|
|
607
|
+
'upgrade-private-binding', 'assert-historical-root', 'expect-receipt']);
|
|
608
|
+
if (opts['inspect-private-binding'] === true) {
|
|
609
|
+
if (opts['upgrade-private-binding'] || opts.offline || opts.yes ||
|
|
610
|
+
opts['assert-historical-root'] || opts['expect-receipt']) {
|
|
611
|
+
throw new CliError('BAD_ARGS', '--inspect-private-binding cannot be combined with upgrade options');
|
|
612
|
+
}
|
|
613
|
+
const result = inspectPrivateProjectBindingUpgrade(ctx.root);
|
|
614
|
+
printResult(ctx, result, () => JSON.stringify(result, null, 2));
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
if (opts['upgrade-private-binding'] === true) {
|
|
618
|
+
const result = upgradePrivateProjectBinding(ctx.root, {
|
|
619
|
+
confirmedOffline: opts.offline === true,
|
|
620
|
+
confirmedHistoricalRoot: opts['assert-historical-root'] === true && opts.yes === true,
|
|
621
|
+
expectedReceipt: opts['expect-receipt'],
|
|
622
|
+
assertOffline: ({ stateDir }) => {
|
|
623
|
+
assertPrivateStateOffline(stateDir);
|
|
624
|
+
return true;
|
|
625
|
+
}
|
|
626
|
+
});
|
|
627
|
+
printResult(ctx, result, () => JSON.stringify(result, null, 2));
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
if (opts['assert-historical-root'] || opts['expect-receipt']) {
|
|
631
|
+
throw new CliError('BAD_ARGS', 'Private binding options require --upgrade-private-binding');
|
|
632
|
+
}
|
|
600
633
|
if (opts.offline !== true || opts.yes !== true) {
|
|
601
634
|
throw new CliError('STATE_MIGRATION_OFFLINE_REQUIRED',
|
|
602
635
|
'Stop every old project-state writer, then acknowledge downtime with migrate-state --offline --yes');
|
|
@@ -630,6 +663,14 @@ function cmdMigrateState(ctx, args) {
|
|
|
630
663
|
async function dispatch(ctx, rest) {
|
|
631
664
|
const command = rest[0];
|
|
632
665
|
const args = rest.slice(1);
|
|
666
|
+
// Native provider children inherit this marker. The ordinary CLI opens the
|
|
667
|
+
// mesh database outside the durable native owner transaction, so only the
|
|
668
|
+
// two owner-fenced entry points may run from that environment.
|
|
669
|
+
if (process.env.HCC_NATIVE_OWNER &&
|
|
670
|
+
!(command === 'hook' || (command === 'mcp' && args[0] === 'serve'))) {
|
|
671
|
+
throw new CliError('NATIVE_CLI_SCOPE_REQUIRED',
|
|
672
|
+
'Native workers must use their scoped MCP tools; ordinary hcc commands cannot write outside the native owner fence');
|
|
673
|
+
}
|
|
633
674
|
if (!command || command === '--help' || command === '-h' || command === 'help') return helpMain();
|
|
634
675
|
if (command === '--version' || command === 'version') return console.log(VERSION);
|
|
635
676
|
if (command === 'up') return cmdUp(ctx, args);
|