@logicseek/hello-cc 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +81 -0
- package/README.md +27 -5
- package/README.zh-CN.md +26 -6
- package/assets/logo.svg +84 -0
- package/bin/hcc.mjs +77 -7
- package/docs/README.md +22 -0
- package/docs/README.zh-CN.md +22 -0
- package/docs/commands.md +104 -0
- package/docs/commands.zh-CN.md +101 -0
- package/docs/guide.md +28 -61
- package/docs/guide.zh-CN.md +27 -59
- package/package.json +5 -1
- package/scripts/regression.mjs +52 -3
- package/scripts/release-notes.mjs +112 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
This project keeps one changelog file. Add one section per release, with the
|
|
4
|
+
newest version first. Do not create a new changelog file for every release.
|
|
5
|
+
|
|
6
|
+
Before publishing, run:
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm run release:check
|
|
10
|
+
npm run release:notes
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Use the output of `npm run release:notes` as the GitHub Release description for
|
|
14
|
+
the current `package.json` version.
|
|
15
|
+
|
|
16
|
+
## 0.1.2
|
|
17
|
+
|
|
18
|
+
### Summary
|
|
19
|
+
|
|
20
|
+
hello-cc 0.1.2 tightens the public release surface after the first scoped npm
|
|
21
|
+
publish. It adds a first-class update command, makes uninstall discoverable in
|
|
22
|
+
top-level help, and reorganizes the documentation so the npm package page and
|
|
23
|
+
GitHub release notes have a clear, detailed description of what changed.
|
|
24
|
+
|
|
25
|
+
### Highlights
|
|
26
|
+
|
|
27
|
+
- Added `hcc update`, which updates the global npm install by running
|
|
28
|
+
`npm install -g @logicseek/hello-cc@latest`.
|
|
29
|
+
- Added `hcc update --tag`, `hcc update --registry`, and `hcc update --dry-run`
|
|
30
|
+
for controlled upgrades and release verification.
|
|
31
|
+
- Made `hcc uninstall` visible in top-level `hcc --help`, matching the README
|
|
32
|
+
and command reference.
|
|
33
|
+
- Kept uninstall behavior conservative: `hcc uninstall` removes hooks and
|
|
34
|
+
shims, while `hcc uninstall --purge --yes` is required to remove project data.
|
|
35
|
+
- Split documentation into a short README, a user guide, command reference, and
|
|
36
|
+
documentation index in both English and Chinese.
|
|
37
|
+
- Restored the Star History chart at the bottom of both README files.
|
|
38
|
+
- Included README-linked package assets in the npm tarball so the package page
|
|
39
|
+
renders the project logo correctly.
|
|
40
|
+
|
|
41
|
+
### Documentation
|
|
42
|
+
|
|
43
|
+
- `README.md` and `README.zh-CN.md` now focus on product positioning, install
|
|
44
|
+
and maintenance commands, quick start, a basic workflow, and links to docs.
|
|
45
|
+
- `docs/guide.md` and `docs/guide.zh-CN.md` describe practical usage and avoid
|
|
46
|
+
embedding the full command list.
|
|
47
|
+
- `docs/commands.md` and `docs/commands.zh-CN.md` provide the compact command
|
|
48
|
+
reference.
|
|
49
|
+
- `docs/README.md` and `docs/README.zh-CN.md` provide the documentation index.
|
|
50
|
+
- English documentation links now point to English user docs, and Chinese
|
|
51
|
+
documentation links point to Chinese user docs.
|
|
52
|
+
|
|
53
|
+
### Validation
|
|
54
|
+
|
|
55
|
+
The 0.1.2 release should be validated with:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
git diff --check
|
|
59
|
+
node --check bin/hcc.mjs
|
|
60
|
+
node --check scripts/regression.mjs
|
|
61
|
+
node --check lib/setup.mjs
|
|
62
|
+
node --check lib/discover.mjs
|
|
63
|
+
npm pack --dry-run --json
|
|
64
|
+
npm publish --dry-run --registry=https://registry.npmjs.org/ --access public
|
|
65
|
+
npm test
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The package dry run should include `CHANGELOG.md`, `assets/logo.svg`, and the
|
|
69
|
+
English and Chinese command reference files.
|
|
70
|
+
|
|
71
|
+
The expected full regression marker is:
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
FULL_REGRESSION_OK
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Release Notes Source
|
|
78
|
+
|
|
79
|
+
Use this changelog section as the source for the GitHub Release notes for
|
|
80
|
+
`v0.1.2`. The npm package metadata keeps a short description, while the package
|
|
81
|
+
README and this changelog provide the detailed release description.
|
package/README.md
CHANGED
|
@@ -37,7 +37,7 @@ doing.
|
|
|
37
37
|
- **One console, many projects**: one local Web runtime can switch between
|
|
38
38
|
registered project roots.
|
|
39
39
|
|
|
40
|
-
## Install
|
|
40
|
+
## Install And Manage
|
|
41
41
|
|
|
42
42
|
Node.js 24 or newer is required.
|
|
43
43
|
|
|
@@ -48,7 +48,7 @@ npm install -g @logicseek/hello-cc
|
|
|
48
48
|
Update an existing global install:
|
|
49
49
|
|
|
50
50
|
```bash
|
|
51
|
-
|
|
51
|
+
hcc update
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
Or run it without a global install:
|
|
@@ -57,6 +57,18 @@ Or run it without a global install:
|
|
|
57
57
|
npx @logicseek/hello-cc web
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
+
Remove hooks and shims from this machine:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
hcc uninstall
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Remove the global npm package:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
npm uninstall -g @logicseek/hello-cc
|
|
70
|
+
```
|
|
71
|
+
|
|
60
72
|
## Quick Start
|
|
61
73
|
|
|
62
74
|
Run this inside the project you want agents to share:
|
|
@@ -110,12 +122,14 @@ generic session-isolation assumptions.
|
|
|
110
122
|
|
|
111
123
|
## Documentation
|
|
112
124
|
|
|
113
|
-
- [
|
|
114
|
-
|
|
125
|
+
- [Documentation Index](docs/README.md): all user and implementation docs.
|
|
126
|
+
- [User Guide](docs/guide.md): setup, Web console, workflows, coordination
|
|
127
|
+
semantics, and environment behavior.
|
|
128
|
+
- [Command Reference](docs/commands.md): compact public command list.
|
|
129
|
+
- [Changelog](CHANGELOG.md): release notes for published versions.
|
|
115
130
|
- [Design Notes](docs/design.md): product boundaries and coordination model.
|
|
116
131
|
- [Implementation Notes](docs/implementation.md): architecture and internal
|
|
117
132
|
protocol.
|
|
118
|
-
- [中文用户指南](docs/guide.zh-CN.md)
|
|
119
133
|
|
|
120
134
|
## Testing
|
|
121
135
|
|
|
@@ -129,3 +143,11 @@ temporary tmux sessions, and a temporary Web runtime to test the main flows.
|
|
|
129
143
|
## License
|
|
130
144
|
|
|
131
145
|
[Apache-2.0](LICENSE)
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
<p align="center">
|
|
150
|
+
<a href="https://star-history.com/#Dullne/hello-cc&Date">
|
|
151
|
+
<img src="https://api.star-history.com/svg?repos=Dullne/hello-cc&type=Date" width="600" alt="Star History Chart">
|
|
152
|
+
</a>
|
|
153
|
+
</p>
|
package/README.zh-CN.md
CHANGED
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
- **resume 友好的稳定身份**:当 provider 暴露 session id 时,恢复会话会映射回稳定 peer。
|
|
27
27
|
- **一个控制台管理多个项目**:单个本地 Web runtime 可以在多个 project root 之间切换。
|
|
28
28
|
|
|
29
|
-
##
|
|
29
|
+
## 安装和维护
|
|
30
30
|
|
|
31
31
|
需要 Node.js 24 或更新版本。
|
|
32
32
|
|
|
@@ -37,7 +37,7 @@ npm install -g @logicseek/hello-cc
|
|
|
37
37
|
更新已有的全局安装:
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
|
-
|
|
40
|
+
hcc update
|
|
41
41
|
```
|
|
42
42
|
|
|
43
43
|
也可以不全局安装,直接运行:
|
|
@@ -46,6 +46,18 @@ npm install -g @logicseek/hello-cc@latest
|
|
|
46
46
|
npx @logicseek/hello-cc web
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
+
移除本机 hooks 和 shims:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
hcc uninstall
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
移除全局 npm 包:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
npm uninstall -g @logicseek/hello-cc
|
|
59
|
+
```
|
|
60
|
+
|
|
49
61
|
## 快速开始
|
|
50
62
|
|
|
51
63
|
在需要多个 agent 共享状态的项目中运行:
|
|
@@ -95,10 +107,10 @@ hcc task done --id 1 --summary "Done"
|
|
|
95
107
|
|
|
96
108
|
## 文档
|
|
97
109
|
|
|
98
|
-
- [
|
|
99
|
-
- [
|
|
100
|
-
- [
|
|
101
|
-
- [
|
|
110
|
+
- [文档目录](docs/README.zh-CN.md):全部用户文档和实现文档入口。
|
|
111
|
+
- [用户指南](docs/guide.zh-CN.md):安装、Web 控制台、协作流程、协作语义和环境变量行为。
|
|
112
|
+
- [命令参考](docs/commands.zh-CN.md):紧凑公共命令清单。
|
|
113
|
+
- [更新日志](CHANGELOG.md):已发布版本的 release notes。
|
|
102
114
|
|
|
103
115
|
## 测试
|
|
104
116
|
|
|
@@ -111,3 +123,11 @@ npm test
|
|
|
111
123
|
## License
|
|
112
124
|
|
|
113
125
|
[Apache-2.0](LICENSE)
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
<p align="center">
|
|
130
|
+
<a href="https://star-history.com/#Dullne/hello-cc&Date">
|
|
131
|
+
<img src="https://api.star-history.com/svg?repos=Dullne/hello-cc&type=Date" width="600" alt="Star History Chart">
|
|
132
|
+
</a>
|
|
133
|
+
</p>
|
package/assets/logo.svg
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 240 240" width="240" height="240">
|
|
2
|
+
<defs>
|
|
3
|
+
<filter id="outerGlow" x="-10%" y="-10%" width="120%" height="120%">
|
|
4
|
+
<feGaussianBlur stdDeviation="4" result="blur"/>
|
|
5
|
+
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
|
|
6
|
+
</filter>
|
|
7
|
+
<radialGradient id="bgGrad" cx="40%" cy="35%" r="70%">
|
|
8
|
+
<stop offset="0%" stop-color="#1a2028"/>
|
|
9
|
+
<stop offset="100%" stop-color="#0a0c0f"/>
|
|
10
|
+
</radialGradient>
|
|
11
|
+
<!-- Text gradient: white → teal, connects wordmark to mesh -->
|
|
12
|
+
<linearGradient id="textGrad" x1="0" y1="0" x2="0" y2="1">
|
|
13
|
+
<stop offset="0%" stop-color="#eef2f6"/>
|
|
14
|
+
<stop offset="100%" stop-color="#40c4aa"/>
|
|
15
|
+
</linearGradient>
|
|
16
|
+
</defs>
|
|
17
|
+
|
|
18
|
+
<!-- Badge -->
|
|
19
|
+
<circle cx="120" cy="120" r="114" fill="url(#bgGrad)" filter="url(#outerGlow)"/>
|
|
20
|
+
<circle cx="120" cy="120" r="113" fill="none" stroke="#303640" stroke-width="1.5"/>
|
|
21
|
+
<circle cx="120" cy="120" r="105" fill="none" stroke="#40c4aa" stroke-width="0.4" opacity="0.25"/>
|
|
22
|
+
|
|
23
|
+
<!--
|
|
24
|
+
Mesh pentagon — center (120, 108), circumradius R=65
|
|
25
|
+
Shifted down 8px from previous (was 100) for visual balance
|
|
26
|
+
|
|
27
|
+
Top: (120, 43)
|
|
28
|
+
Upper-right: (182, 88)
|
|
29
|
+
Lower-right: (158, 161)
|
|
30
|
+
Lower-left: ( 82, 161)
|
|
31
|
+
Upper-left: ( 58, 88)
|
|
32
|
+
-->
|
|
33
|
+
|
|
34
|
+
<!-- Connections -->
|
|
35
|
+
<g stroke="#40c4aa" stroke-width="1.4" opacity="0.20" fill="none">
|
|
36
|
+
<line x1="120" y1="43" x2="182" y2="88"/>
|
|
37
|
+
<line x1="120" y1="43" x2="158" y2="161"/>
|
|
38
|
+
<line x1="120" y1="43" x2="82" y2="161"/>
|
|
39
|
+
<line x1="120" y1="43" x2="58" y2="88"/>
|
|
40
|
+
<line x1="182" y1="88" x2="158" y2="161"/>
|
|
41
|
+
<line x1="182" y1="88" x2="82" y2="161"/>
|
|
42
|
+
<line x1="182" y1="88" x2="58" y2="88"/>
|
|
43
|
+
<line x1="158" y1="161" x2="82" y2="161"/>
|
|
44
|
+
<line x1="158" y1="161" x2="58" y2="88"/>
|
|
45
|
+
<line x1="82" y1="161" x2="58" y2="88"/>
|
|
46
|
+
</g>
|
|
47
|
+
|
|
48
|
+
<!-- Spoke lines from center hub -->
|
|
49
|
+
<g stroke="#40c4aa" stroke-width="0.8" opacity="0.12">
|
|
50
|
+
<line x1="120" y1="108" x2="120" y2="43"/>
|
|
51
|
+
<line x1="120" y1="108" x2="182" y2="88"/>
|
|
52
|
+
<line x1="120" y1="108" x2="158" y2="161"/>
|
|
53
|
+
<line x1="120" y1="108" x2="82" y2="161"/>
|
|
54
|
+
<line x1="120" y1="108" x2="58" y2="88"/>
|
|
55
|
+
</g>
|
|
56
|
+
|
|
57
|
+
<!-- Node halos — all equal (flat peer mesh, no hierarchy) -->
|
|
58
|
+
<circle cx="120" cy="43" r="14" fill="none" stroke="#40c4aa" stroke-width="1" opacity="0.20"/>
|
|
59
|
+
<circle cx="182" cy="88" r="14" fill="none" stroke="#40c4aa" stroke-width="1" opacity="0.20"/>
|
|
60
|
+
<circle cx="158" cy="161" r="14" fill="none" stroke="#40c4aa" stroke-width="1" opacity="0.20"/>
|
|
61
|
+
<circle cx="82" cy="161" r="14" fill="none" stroke="#40c4aa" stroke-width="1" opacity="0.20"/>
|
|
62
|
+
<circle cx="58" cy="88" r="14" fill="none" stroke="#40c4aa" stroke-width="1" opacity="0.20"/>
|
|
63
|
+
|
|
64
|
+
<!-- All 5 nodes — same size, same style -->
|
|
65
|
+
<circle cx="120" cy="43" r="10" fill="#40c4aa" opacity="0.85"/>
|
|
66
|
+
<circle cx="182" cy="88" r="10" fill="#40c4aa" opacity="0.85"/>
|
|
67
|
+
<circle cx="158" cy="161" r="10" fill="#40c4aa" opacity="0.85"/>
|
|
68
|
+
<circle cx="82" cy="161" r="10" fill="#40c4aa" opacity="0.85"/>
|
|
69
|
+
<circle cx="58" cy="88" r="10" fill="#40c4aa" opacity="0.85"/>
|
|
70
|
+
|
|
71
|
+
<!-- Center hub -->
|
|
72
|
+
<circle cx="120" cy="108" r="6" fill="#8ee8d8" opacity="1.0"/>
|
|
73
|
+
|
|
74
|
+
<!-- "hcc" wordmark -->
|
|
75
|
+
<text
|
|
76
|
+
x="120" y="210"
|
|
77
|
+
font-family="ui-monospace, SFMono-Regular, Menlo, Consolas, monospace"
|
|
78
|
+
font-size="30"
|
|
79
|
+
font-weight="700"
|
|
80
|
+
fill="url(#textGrad)"
|
|
81
|
+
text-anchor="middle"
|
|
82
|
+
letter-spacing="5"
|
|
83
|
+
>hcc</text>
|
|
84
|
+
</svg>
|
package/bin/hcc.mjs
CHANGED
|
@@ -16,9 +16,10 @@ const _libDir = path.resolve(fileURLToPath(import.meta.url), '..', '..', 'lib');
|
|
|
16
16
|
async function loadDiscover() { return import(path.join(_libDir, 'discover.mjs')); }
|
|
17
17
|
async function loadSetup() { return import(path.join(_libDir, 'setup.mjs')); }
|
|
18
18
|
|
|
19
|
-
const VERSION = '0.1.
|
|
19
|
+
const VERSION = '0.1.2';
|
|
20
20
|
const PRODUCT_NAME = 'hello-cc';
|
|
21
21
|
const CLI_NAME = 'hcc';
|
|
22
|
+
const NPM_PACKAGE_NAME = '@logicseek/hello-cc';
|
|
22
23
|
const DEFAULT_LOCK_TTL = 900;
|
|
23
24
|
const ACTIVE_PEER_TTL = 600;
|
|
24
25
|
// Directory under .hello-cc/ for optional external PTY buffer files.
|
|
@@ -128,6 +129,14 @@ function parseOpts(args, spec = {}) {
|
|
|
128
129
|
return opts;
|
|
129
130
|
}
|
|
130
131
|
|
|
132
|
+
function wantsHelp(args) {
|
|
133
|
+
const stop = args.indexOf('--');
|
|
134
|
+
const scan = stop >= 0 ? args.slice(0, stop) : args;
|
|
135
|
+
const index = scan.findIndex((arg) => arg === '--help' || arg === '-h');
|
|
136
|
+
if (index < 0) return false;
|
|
137
|
+
return index <= 1 || !String(scan[index - 1] || '').startsWith('--');
|
|
138
|
+
}
|
|
139
|
+
|
|
131
140
|
function validateOpts(command, opts, allowed = []) {
|
|
132
141
|
const allowedSet = new Set(['_', ...allowed]);
|
|
133
142
|
for (const key of Object.keys(opts)) {
|
|
@@ -2289,7 +2298,7 @@ async function cmdPeers(ctx, args) {
|
|
|
2289
2298
|
|
|
2290
2299
|
async function cmdTask(ctx, args) {
|
|
2291
2300
|
const sub = args[0];
|
|
2292
|
-
if (!sub ||
|
|
2301
|
+
if (!sub || wantsHelp(args)) return helpTask();
|
|
2293
2302
|
if (sub === 'create') return taskCreate(ctx, args.slice(1));
|
|
2294
2303
|
if (sub === 'list') return taskList(ctx, args.slice(1));
|
|
2295
2304
|
if (sub === 'claim') return taskClaim(ctx, args.slice(1));
|
|
@@ -2467,7 +2476,7 @@ async function taskDone(ctx, args) {
|
|
|
2467
2476
|
|
|
2468
2477
|
async function cmdMsg(ctx, args) {
|
|
2469
2478
|
const sub = args[0];
|
|
2470
|
-
if (!sub ||
|
|
2479
|
+
if (!sub || wantsHelp(args)) return helpMsg();
|
|
2471
2480
|
if (sub === 'send') return msgSend(ctx, args.slice(1));
|
|
2472
2481
|
if (sub === 'inbox') return msgInbox(ctx, args.slice(1));
|
|
2473
2482
|
if (sub === 'ack') return msgAck(ctx, args.slice(1));
|
|
@@ -2598,7 +2607,7 @@ async function cmdInject(ctx, args) {
|
|
|
2598
2607
|
|
|
2599
2608
|
async function cmdPeer(ctx, args) {
|
|
2600
2609
|
const sub = args[0];
|
|
2601
|
-
if (!sub ||
|
|
2610
|
+
if (!sub || wantsHelp(args)) return helpPeer();
|
|
2602
2611
|
if (sub === 'list') return peerList(ctx, args.slice(1));
|
|
2603
2612
|
if (sub === 'start') return peerStart(ctx, args.slice(1));
|
|
2604
2613
|
if (sub === 'attach') return peerAttach(ctx, args.slice(1));
|
|
@@ -2748,7 +2757,7 @@ async function peerStop(ctx, args) {
|
|
|
2748
2757
|
|
|
2749
2758
|
async function cmdLock(ctx, args) {
|
|
2750
2759
|
const sub = args[0];
|
|
2751
|
-
if (!sub ||
|
|
2760
|
+
if (!sub || wantsHelp(args)) return helpLock();
|
|
2752
2761
|
if (sub === 'acquire') return lockAcquire(ctx, args.slice(1));
|
|
2753
2762
|
if (sub === 'release') return lockRelease(ctx, args.slice(1));
|
|
2754
2763
|
if (sub === 'renew') return lockRenew(ctx, args.slice(1));
|
|
@@ -2847,7 +2856,7 @@ async function lockList(ctx, args) {
|
|
|
2847
2856
|
|
|
2848
2857
|
async function cmdHandoff(ctx, args) {
|
|
2849
2858
|
const sub = args[0];
|
|
2850
|
-
if (!sub ||
|
|
2859
|
+
if (!sub || wantsHelp(args)) return helpHandoff();
|
|
2851
2860
|
if (sub === 'create') return handoffCreate(ctx, args.slice(1));
|
|
2852
2861
|
if (sub === 'list') return handoffList(ctx, args.slice(1));
|
|
2853
2862
|
throw new CliError('BAD_ARGS', `Unknown handoff command: ${sub}`);
|
|
@@ -2900,7 +2909,7 @@ async function handoffList(ctx, args) {
|
|
|
2900
2909
|
|
|
2901
2910
|
async function cmdEvent(ctx, args) {
|
|
2902
2911
|
const sub = args[0];
|
|
2903
|
-
if (!sub ||
|
|
2912
|
+
if (!sub || wantsHelp(args)) return helpEvent();
|
|
2904
2913
|
if (sub === 'tail') return eventTail(ctx, args.slice(1));
|
|
2905
2914
|
throw new CliError('BAD_ARGS', `Unknown event command: ${sub}`);
|
|
2906
2915
|
}
|
|
@@ -5539,6 +5548,8 @@ Commands:
|
|
|
5539
5548
|
web Start coordination, shims, tmux, and browser console
|
|
5540
5549
|
up Initialize local coordination only
|
|
5541
5550
|
down Stop the running hello-cc web runtime
|
|
5551
|
+
update Update the global npm install of hello-cc
|
|
5552
|
+
uninstall Remove hooks, shims, and optional project data
|
|
5542
5553
|
init Initialize .hello-cc/mesh.db and guidance
|
|
5543
5554
|
register --peer ID Register or update a peer session identity
|
|
5544
5555
|
join --peer ID Register this shell and print eval-able env
|
|
@@ -5780,6 +5791,24 @@ Stops the web runtime started by hcc web for this project.
|
|
|
5780
5791
|
`);
|
|
5781
5792
|
}
|
|
5782
5793
|
|
|
5794
|
+
function helpUpdate() {
|
|
5795
|
+
console.log(`${CLI_NAME} update
|
|
5796
|
+
|
|
5797
|
+
Usage:
|
|
5798
|
+
${CLI_NAME} update [--tag TAG] [--registry URL] [--dry-run]
|
|
5799
|
+
|
|
5800
|
+
Examples:
|
|
5801
|
+
${CLI_NAME} update
|
|
5802
|
+
${CLI_NAME} update --tag latest
|
|
5803
|
+
${CLI_NAME} update --dry-run
|
|
5804
|
+
|
|
5805
|
+
Updates the global npm install by running:
|
|
5806
|
+
npm install -g ${NPM_PACKAGE_NAME}@TAG
|
|
5807
|
+
|
|
5808
|
+
The default TAG is latest.
|
|
5809
|
+
`);
|
|
5810
|
+
}
|
|
5811
|
+
|
|
5783
5812
|
function helpWeb() {
|
|
5784
5813
|
console.log(`${CLI_NAME} web
|
|
5785
5814
|
|
|
@@ -6103,6 +6132,46 @@ async function cmdSetup(ctx, args) {
|
|
|
6103
6132
|
log('\nDone. Run `hcc web` for the default coordinated terminal experience.');
|
|
6104
6133
|
}
|
|
6105
6134
|
|
|
6135
|
+
// ─── hcc update ──────────────────────────────────────────────────────────────
|
|
6136
|
+
|
|
6137
|
+
async function cmdUpdate(ctx, args) {
|
|
6138
|
+
if (args[0] === '--help' || args[0] === '-h') return helpUpdate();
|
|
6139
|
+
|
|
6140
|
+
const opts = parseOpts(args, { booleans: ['dry-run'] });
|
|
6141
|
+
validateOpts('update', opts, ['tag', 'registry', 'dry-run']);
|
|
6142
|
+
const tag = opts.tag || 'latest';
|
|
6143
|
+
if (!/^[A-Za-z0-9._+-]+$/.test(tag)) {
|
|
6144
|
+
throw new CliError('BAD_ARGS', '--tag must be an npm dist-tag or version');
|
|
6145
|
+
}
|
|
6146
|
+
|
|
6147
|
+
const packageSpec = `${NPM_PACKAGE_NAME}@${tag}`;
|
|
6148
|
+
const npmArgs = ['install', '-g', packageSpec];
|
|
6149
|
+
if (opts.registry) npmArgs.push('--registry', opts.registry);
|
|
6150
|
+
const command = shellCommand(['npm', ...npmArgs]);
|
|
6151
|
+
const data = { package: NPM_PACKAGE_NAME, tag, registry: opts.registry || null, command, dry_run: Boolean(opts['dry-run']) };
|
|
6152
|
+
|
|
6153
|
+
if (opts['dry-run']) {
|
|
6154
|
+
printResult(ctx, data, () => `would run: ${command}`);
|
|
6155
|
+
return;
|
|
6156
|
+
}
|
|
6157
|
+
|
|
6158
|
+
const result = spawnSync('npm', npmArgs, {
|
|
6159
|
+
encoding: ctx.json ? 'utf8' : undefined,
|
|
6160
|
+
stdio: ctx.json ? ['ignore', 'pipe', 'pipe'] : 'inherit'
|
|
6161
|
+
});
|
|
6162
|
+
if (result.error) {
|
|
6163
|
+
throw new CliError('UPDATE_FAILED', `npm update command failed: ${result.error.message}`);
|
|
6164
|
+
}
|
|
6165
|
+
if (result.status !== 0) {
|
|
6166
|
+
const output = ctx.json
|
|
6167
|
+
? [result.stdout, result.stderr].filter(Boolean).join('\n').trim()
|
|
6168
|
+
: '';
|
|
6169
|
+
throw new CliError('UPDATE_FAILED', output || `npm exited with status ${result.status}`);
|
|
6170
|
+
}
|
|
6171
|
+
|
|
6172
|
+
printResult(ctx, data, () => `updated ${packageSpec}`);
|
|
6173
|
+
}
|
|
6174
|
+
|
|
6106
6175
|
// ─── hcc uninstall ───────────────────────────────────────────────────────────
|
|
6107
6176
|
|
|
6108
6177
|
async function cmdUninstall(ctx, args) {
|
|
@@ -6326,6 +6395,7 @@ async function dispatch(ctx, rest) {
|
|
|
6326
6395
|
if (command === '--version' || command === 'version') return console.log(VERSION);
|
|
6327
6396
|
if (command === 'up') return cmdUp(ctx, args);
|
|
6328
6397
|
if (command === 'down') return cmdDown(ctx, args);
|
|
6398
|
+
if (command === 'update') return cmdUpdate(ctx, args);
|
|
6329
6399
|
if (command === 'uninstall') return cmdUninstall(ctx, args);
|
|
6330
6400
|
if (command === 'init') return cmdInit(ctx, args);
|
|
6331
6401
|
if (command === 'register') return cmdRegister(ctx, args);
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# hello-cc Documentation
|
|
2
|
+
|
|
3
|
+
Start with the [project README](../README.md) when you only need the project
|
|
4
|
+
summary and first command. Use these docs when you need more detail.
|
|
5
|
+
|
|
6
|
+
## User Docs
|
|
7
|
+
|
|
8
|
+
- [User Guide](guide.md): install, start, Web console, coordination semantics,
|
|
9
|
+
workflow, stable peer identity, and environment behavior.
|
|
10
|
+
- [Command Reference](commands.md): compact list of public commands and the
|
|
11
|
+
intended use of each command group.
|
|
12
|
+
- [Changelog](../CHANGELOG.md): release notes for published versions.
|
|
13
|
+
- Release notes: run `npm run release:check` before publishing, and use
|
|
14
|
+
`npm run release:notes` to print the current changelog section for GitHub
|
|
15
|
+
Release notes.
|
|
16
|
+
|
|
17
|
+
## Design And Implementation
|
|
18
|
+
|
|
19
|
+
- [Design Notes](design.md): product boundary, project boundary, capability
|
|
20
|
+
levels, coordination semantics, and provider-session binding.
|
|
21
|
+
- [Implementation Notes](implementation.md): architecture, protocol, command
|
|
22
|
+
surface, stack, shim behavior, and implementation plan.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# hello-cc 文档
|
|
2
|
+
|
|
3
|
+
只需要项目简介和第一条命令时,先看[仓库 README](../README.zh-CN.md)。
|
|
4
|
+
需要更多细节时,再看下面的文档。
|
|
5
|
+
|
|
6
|
+
## 用户文档
|
|
7
|
+
|
|
8
|
+
- [用户指南](guide.zh-CN.md):安装、启动、Web 控制台、协作语义、工作流、稳定
|
|
9
|
+
peer 身份和环境变量行为。
|
|
10
|
+
- [命令参考](commands.zh-CN.md):公共命令的紧凑清单,以及每组命令的用途。
|
|
11
|
+
- [更新日志](../CHANGELOG.md):已发布版本的 release notes。
|
|
12
|
+
- 发行说明:发布前运行 `npm run release:check`,用
|
|
13
|
+
`npm run release:notes` 输出当前版本的 changelog 小节,作为 GitHub
|
|
14
|
+
Release 描述。
|
|
15
|
+
|
|
16
|
+
## 设计和实现
|
|
17
|
+
|
|
18
|
+
- [设计说明](design.md):产品边界、项目边界、能力层级、协作语义和 provider
|
|
19
|
+
session 绑定。
|
|
20
|
+
- [实现说明](implementation.md):架构、协议、命令面、技术栈、shim 行为和实现计划。
|
|
21
|
+
|
|
22
|
+
设计和实现文档目前只有英文版。
|
package/docs/commands.md
ADDED
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# hello-cc Command Reference
|
|
2
|
+
|
|
3
|
+
Use `hcc --help` for the current top-level command list. Most subcommands also
|
|
4
|
+
accept `--help`, for example `hcc update --help`, `hcc peer --help`, and
|
|
5
|
+
`hcc task --help`.
|
|
6
|
+
|
|
7
|
+
## Install Maintenance
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
hcc update [--tag TAG] [--registry URL] [--dry-run]
|
|
11
|
+
hcc uninstall [--purge --yes]
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
`hcc update` updates the global npm install. `hcc uninstall` removes local
|
|
15
|
+
hooks and shims; add `--purge --yes` only when you also want to remove the
|
|
16
|
+
current project's `.hello-cc` data and guidance blocks.
|
|
17
|
+
|
|
18
|
+
## Start And Stop
|
|
19
|
+
|
|
20
|
+
```text
|
|
21
|
+
hcc web [--host HOST] [--port N] [--token TEXT] [--local] [--no-discover] [--no-guidance]
|
|
22
|
+
hcc down
|
|
23
|
+
hcc up [--no-discover] [--no-guidance]
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
`hcc web` is the default entry. It initializes coordination, installs hooks and
|
|
27
|
+
shims, starts or reuses the Web console, and returns the terminal to you. Use
|
|
28
|
+
`hcc up` only when you want coordination without the Web console or shims.
|
|
29
|
+
|
|
30
|
+
## Peers And Status
|
|
31
|
+
|
|
32
|
+
```text
|
|
33
|
+
hcc peers
|
|
34
|
+
hcc status [--peer ID]
|
|
35
|
+
hcc scan [--register]
|
|
36
|
+
hcc prompt --peer ID [--kind codex|claude|shell|other] [--role ROLE]
|
|
37
|
+
hcc join --peer ID [--kind codex|claude|shell|other] [--role ROLE]
|
|
38
|
+
hcc env --peer ID
|
|
39
|
+
hcc heartbeat [--peer ID] [--renew-locks --ttl 900]
|
|
40
|
+
hcc run --peer ID --kind codex|claude|shell --role ROLE -- COMMAND [ARGS...]
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Use these commands to inspect live project state, register terminals, and run a
|
|
44
|
+
CLI with `HCC_PEER`, `HCC_ROOT`, and `HCC_DB` set.
|
|
45
|
+
|
|
46
|
+
## Browser-Controllable Terminals
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
hcc peer list
|
|
50
|
+
hcc peer start PEER [--kind K] [--role R] [--cwd DIR] [--restart-env] -- COMMAND [ARGS...]
|
|
51
|
+
hcc peer start PEER --kind codex --resume SESSION_ID [--restart-env]
|
|
52
|
+
hcc peer start PEER --kind codex --last
|
|
53
|
+
hcc peer start PEER --kind claude --resume SESSION_ID [--restart-env]
|
|
54
|
+
hcc peer start PEER --kind claude --continue
|
|
55
|
+
hcc peer attach PEER [--pane PANE] [--kind K] [--role R] [--cwd DIR]
|
|
56
|
+
hcc peer stop PEER
|
|
57
|
+
hcc inject PEER TEXT [--no-enter]
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
These commands create or attach tmux-backed terminals that can be viewed and
|
|
61
|
+
controlled from the Web console.
|
|
62
|
+
|
|
63
|
+
## Messages
|
|
64
|
+
|
|
65
|
+
```text
|
|
66
|
+
hcc msg send [--from ID] [--to ID|all] --body TEXT [--task N] [--kind note|task|handoff]
|
|
67
|
+
hcc msg inbox [--peer ID] [--wait SEC] [--all] [--limit N]
|
|
68
|
+
hcc msg ack [--peer ID] --id N
|
|
69
|
+
hcc ask PEER MESSAGE [--from ID] [--task N] [--inject]
|
|
70
|
+
hcc broadcast MESSAGE [--from ID] [--task N] [--inject]
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Messages are addressed mailbox items. `ask` and `broadcast` also support live
|
|
74
|
+
terminal injection with `--inject`.
|
|
75
|
+
|
|
76
|
+
## Tasks
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
hcc task create --title TEXT [--body TEXT] [--from ID] [--to ID] [--priority N]
|
|
80
|
+
hcc task list [--status S] [--peer ID] [--all]
|
|
81
|
+
hcc task claim [--peer ID] --id N
|
|
82
|
+
hcc task next [--peer ID]
|
|
83
|
+
hcc task update [--peer ID] --id N --status running|review|blocked|done|abandoned [--summary TEXT] [--body TEXT] [--to ID]
|
|
84
|
+
hcc task done [--peer ID] --id N --summary TEXT
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Tasks are shared project facts. They remain visible until marked `done` or
|
|
88
|
+
`abandoned`.
|
|
89
|
+
|
|
90
|
+
## Locks, Handoffs, And Events
|
|
91
|
+
|
|
92
|
+
```text
|
|
93
|
+
hcc lock acquire [--peer ID] --resource PATH [--task N] [--ttl SEC] [--reason TEXT]
|
|
94
|
+
hcc lock renew [--peer ID] --resource PATH [--ttl SEC]
|
|
95
|
+
hcc lock release [--peer ID] --resource PATH [--force]
|
|
96
|
+
hcc lock list [--all]
|
|
97
|
+
hcc handoff create [--from ID] --summary TEXT [--task N] [--to ID] [--changed-files JSON_OR_CSV] [--tests TEXT] [--risks TEXT]
|
|
98
|
+
hcc handoff list [--task N] [--limit N]
|
|
99
|
+
hcc event tail [--limit N]
|
|
100
|
+
hcc gc [--older-than DAYS] [--yes]
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Locks are advisory coordination locks with TTLs. Handoffs preserve the result,
|
|
104
|
+
tests, changed files, and remaining risks when work moves between peers.
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
# hello-cc 命令参考
|
|
2
|
+
|
|
3
|
+
使用 `hcc --help` 查看当前顶层命令列表。大多数子命令也支持 `--help`,
|
|
4
|
+
例如 `hcc update --help`、`hcc peer --help` 和 `hcc task --help`。
|
|
5
|
+
|
|
6
|
+
## 安装维护
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
hcc update [--tag TAG] [--registry URL] [--dry-run]
|
|
10
|
+
hcc uninstall [--purge --yes]
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
`hcc update` 更新全局 npm 安装。`hcc uninstall` 移除本机 hooks 和 shims;
|
|
14
|
+
只有在确定也要删除当前项目的 `.hello-cc` 数据和指导块时,才加
|
|
15
|
+
`--purge --yes`。
|
|
16
|
+
|
|
17
|
+
## 启动和停止
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
hcc web [--host HOST] [--port N] [--token TEXT] [--local] [--no-discover] [--no-guidance]
|
|
21
|
+
hcc down
|
|
22
|
+
hcc up [--no-discover] [--no-guidance]
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`hcc web` 是默认入口。它会初始化协作状态,安装 hooks 和 shims,启动或复用
|
|
26
|
+
Web 控制台,然后把终端还给你。只想使用本地协作、不需要 Web 或 shims 时,
|
|
27
|
+
再使用 `hcc up`。
|
|
28
|
+
|
|
29
|
+
## Peers 和状态
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
hcc peers
|
|
33
|
+
hcc status [--peer ID]
|
|
34
|
+
hcc scan [--register]
|
|
35
|
+
hcc prompt --peer ID [--kind codex|claude|shell|other] [--role ROLE]
|
|
36
|
+
hcc join --peer ID [--kind codex|claude|shell|other] [--role ROLE]
|
|
37
|
+
hcc env --peer ID
|
|
38
|
+
hcc heartbeat [--peer ID] [--renew-locks --ttl 900]
|
|
39
|
+
hcc run --peer ID --kind codex|claude|shell --role ROLE -- COMMAND [ARGS...]
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
这些命令用于查看项目状态、注册终端,以及用 `HCC_PEER`、`HCC_ROOT`、
|
|
43
|
+
`HCC_DB` 环境运行 CLI。
|
|
44
|
+
|
|
45
|
+
## Web 可控终端
|
|
46
|
+
|
|
47
|
+
```text
|
|
48
|
+
hcc peer list
|
|
49
|
+
hcc peer start PEER [--kind K] [--role R] [--cwd DIR] [--restart-env] -- COMMAND [ARGS...]
|
|
50
|
+
hcc peer start PEER --kind codex --resume SESSION_ID [--restart-env]
|
|
51
|
+
hcc peer start PEER --kind codex --last
|
|
52
|
+
hcc peer start PEER --kind claude --resume SESSION_ID [--restart-env]
|
|
53
|
+
hcc peer start PEER --kind claude --continue
|
|
54
|
+
hcc peer attach PEER [--pane PANE] [--kind K] [--role R] [--cwd DIR]
|
|
55
|
+
hcc peer stop PEER
|
|
56
|
+
hcc inject PEER TEXT [--no-enter]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
这些命令创建或接入 tmux-backed 终端,让 Web 控制台可以观察和操作它们。
|
|
60
|
+
|
|
61
|
+
## 消息
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
hcc msg send [--from ID] [--to ID|all] --body TEXT [--task N] [--kind note|task|handoff]
|
|
65
|
+
hcc msg inbox [--peer ID] [--wait SEC] [--all] [--limit N]
|
|
66
|
+
hcc msg ack [--peer ID] --id N
|
|
67
|
+
hcc ask PEER MESSAGE [--from ID] [--task N] [--inject]
|
|
68
|
+
hcc broadcast MESSAGE [--from ID] [--task N] [--inject]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
消息是带收件人的邮箱记录。`ask` 和 `broadcast` 加 `--inject` 后,也会把内容
|
|
72
|
+
实时注入到终端。
|
|
73
|
+
|
|
74
|
+
## 任务
|
|
75
|
+
|
|
76
|
+
```text
|
|
77
|
+
hcc task create --title TEXT [--body TEXT] [--from ID] [--to ID] [--priority N]
|
|
78
|
+
hcc task list [--status S] [--peer ID] [--all]
|
|
79
|
+
hcc task claim [--peer ID] --id N
|
|
80
|
+
hcc task next [--peer ID]
|
|
81
|
+
hcc task update [--peer ID] --id N --status running|review|blocked|done|abandoned [--summary TEXT] [--body TEXT] [--to ID]
|
|
82
|
+
hcc task done [--peer ID] --id N --summary TEXT
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
任务是项目共享事实。任务会一直可见,直到被标记为 `done` 或 `abandoned`。
|
|
86
|
+
|
|
87
|
+
## 锁、交接和事件
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
hcc lock acquire [--peer ID] --resource PATH [--task N] [--ttl SEC] [--reason TEXT]
|
|
91
|
+
hcc lock renew [--peer ID] --resource PATH [--ttl SEC]
|
|
92
|
+
hcc lock release [--peer ID] --resource PATH [--force]
|
|
93
|
+
hcc lock list [--all]
|
|
94
|
+
hcc handoff create [--from ID] --summary TEXT [--task N] [--to ID] [--changed-files JSON_OR_CSV] [--tests TEXT] [--risks TEXT]
|
|
95
|
+
hcc handoff list [--task N] [--limit N]
|
|
96
|
+
hcc event tail [--limit N]
|
|
97
|
+
hcc gc [--older-than DAYS] [--yes]
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
锁是带 TTL 的协作式 advisory lock。交接记录用于保存结果、测试、变更文件和
|
|
101
|
+
剩余风险,方便工作在多个 peer 之间继续。
|
package/docs/guide.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# hello-cc User Guide
|
|
2
2
|
|
|
3
|
-
This guide
|
|
4
|
-
the
|
|
3
|
+
This guide covers the practical workflow for installing, starting, and using
|
|
4
|
+
hello-cc. For a compact command list, use the [Command Reference](commands.md).
|
|
5
5
|
|
|
6
|
-
## Install And
|
|
6
|
+
## Install, Update, And Uninstall
|
|
7
7
|
|
|
8
8
|
Install hello-cc globally:
|
|
9
9
|
|
|
@@ -14,11 +14,30 @@ npm install -g @logicseek/hello-cc
|
|
|
14
14
|
Update an existing global install:
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
-
|
|
17
|
+
hcc update
|
|
18
18
|
```
|
|
19
19
|
|
|
20
|
-
`hcc
|
|
21
|
-
|
|
20
|
+
`hcc update` runs `npm install -g @logicseek/hello-cc@latest`. Use
|
|
21
|
+
`hcc update --help` to see the available update options. `hcc task update`
|
|
22
|
+
updates a coordination task, not the installed package.
|
|
23
|
+
|
|
24
|
+
Remove hooks and shims from this machine:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
hcc uninstall
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Remove the current project's `.hello-cc` data and guidance blocks too:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
hcc uninstall --purge --yes
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Remove the global npm package:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm uninstall -g @logicseek/hello-cc
|
|
40
|
+
```
|
|
22
41
|
|
|
23
42
|
## Default Entry
|
|
24
43
|
|
|
@@ -222,62 +241,10 @@ Already-open raw terminals cannot be captured or controlled unconditionally
|
|
|
222
241
|
unless they started under tmux, screen, or a hello-cc shim. They can still
|
|
223
242
|
participate in tasks, messages, and locks through hooks and `hcc` commands.
|
|
224
243
|
|
|
225
|
-
##
|
|
244
|
+
## Command Reference
|
|
226
245
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
hcc web [--host HOST] [--port N] [--token TEXT] [--local] [--no-discover] [--no-guidance]
|
|
230
|
-
hcc down
|
|
231
|
-
|
|
232
|
-
# Local coordination without Web
|
|
233
|
-
hcc up [--no-discover] [--no-guidance]
|
|
234
|
-
|
|
235
|
-
# Peers and status
|
|
236
|
-
hcc peers
|
|
237
|
-
hcc status [--peer ID]
|
|
238
|
-
hcc scan [--register]
|
|
239
|
-
hcc prompt --peer ID [--kind codex|claude|shell|other] [--role ROLE]
|
|
240
|
-
hcc join --peer ID [--kind codex|claude|shell|other] [--role ROLE]
|
|
241
|
-
hcc env --peer ID
|
|
242
|
-
hcc heartbeat [--peer ID] [--renew-locks --ttl 900]
|
|
243
|
-
hcc run --peer ID --kind codex|claude|shell --role ROLE -- COMMAND [ARGS...]
|
|
244
|
-
|
|
245
|
-
# Browser-controllable terminals
|
|
246
|
-
hcc peer list
|
|
247
|
-
hcc peer start PEER [--kind K] [--role R] [--cwd DIR] [--restart-env] -- COMMAND [ARGS...]
|
|
248
|
-
hcc peer start PEER --kind codex --resume SESSION_ID [--restart-env]
|
|
249
|
-
hcc peer start PEER --kind codex --last
|
|
250
|
-
hcc peer start PEER --kind claude --resume SESSION_ID [--restart-env]
|
|
251
|
-
hcc peer start PEER --kind claude --continue
|
|
252
|
-
hcc peer attach PEER [--pane PANE] [--kind K] [--role R] [--cwd DIR]
|
|
253
|
-
hcc peer stop PEER
|
|
254
|
-
hcc inject PEER TEXT [--no-enter]
|
|
255
|
-
|
|
256
|
-
# Messages
|
|
257
|
-
hcc msg send [--from ID] [--to ID|all] --body TEXT [--task N] [--kind note|task|handoff]
|
|
258
|
-
hcc msg inbox [--peer ID] [--wait SEC] [--all] [--limit N]
|
|
259
|
-
hcc msg ack [--peer ID] --id N
|
|
260
|
-
hcc ask PEER MESSAGE [--from ID] [--task N] [--inject]
|
|
261
|
-
hcc broadcast MESSAGE [--from ID] [--task N] [--inject]
|
|
262
|
-
|
|
263
|
-
# Tasks
|
|
264
|
-
hcc task create --title TEXT [--body TEXT] [--from ID] [--to ID] [--priority N]
|
|
265
|
-
hcc task list [--status S] [--peer ID] [--all]
|
|
266
|
-
hcc task claim [--peer ID] --id N
|
|
267
|
-
hcc task next [--peer ID]
|
|
268
|
-
hcc task update [--peer ID] --id N --status running|review|blocked|done|abandoned [--summary TEXT] [--body TEXT] [--to ID]
|
|
269
|
-
hcc task done [--peer ID] --id N --summary TEXT
|
|
270
|
-
|
|
271
|
-
# Locks and handoffs
|
|
272
|
-
hcc lock acquire [--peer ID] --resource PATH [--task N] [--ttl SEC] [--reason TEXT]
|
|
273
|
-
hcc lock renew [--peer ID] --resource PATH [--ttl SEC]
|
|
274
|
-
hcc lock release [--peer ID] --resource PATH [--force]
|
|
275
|
-
hcc lock list [--all]
|
|
276
|
-
hcc handoff create [--from ID] --summary TEXT [--task N] [--to ID] [--changed-files JSON_OR_CSV] [--tests TEXT] [--risks TEXT]
|
|
277
|
-
hcc handoff list [--task N] [--limit N]
|
|
278
|
-
hcc event tail [--limit N]
|
|
279
|
-
hcc gc [--older-than DAYS] [--yes]
|
|
280
|
-
```
|
|
246
|
+
Use `hcc --help` for the command list and `hcc <command> --help` for a specific
|
|
247
|
+
command. The maintained summary lives in the [Command Reference](commands.md).
|
|
281
248
|
|
|
282
249
|
## Stable Peer Identity
|
|
283
250
|
|
package/docs/guide.zh-CN.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# hello-cc 用户指南
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
这份文档说明安装、启动和日常使用流程。紧凑命令清单见
|
|
4
|
+
[命令参考](commands.zh-CN.md)。
|
|
4
5
|
|
|
5
|
-
##
|
|
6
|
+
## 安装、更新和卸载
|
|
6
7
|
|
|
7
8
|
全局安装 hello-cc:
|
|
8
9
|
|
|
@@ -13,10 +14,29 @@ npm install -g @logicseek/hello-cc
|
|
|
13
14
|
更新已有的全局安装:
|
|
14
15
|
|
|
15
16
|
```bash
|
|
16
|
-
|
|
17
|
+
hcc update
|
|
17
18
|
```
|
|
18
19
|
|
|
19
|
-
`hcc`
|
|
20
|
+
`hcc update` 会执行 `npm install -g @logicseek/hello-cc@latest`。使用
|
|
21
|
+
`hcc update --help` 可以查看更新选项。`hcc task update` 更新的是协作任务状态,不是安装包版本。
|
|
22
|
+
|
|
23
|
+
移除本机 hooks 和 shims:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
hcc uninstall
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
同时移除当前项目的 `.hello-cc` 数据和指导块:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
hcc uninstall --purge --yes
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
移除全局 npm 包:
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm uninstall -g @logicseek/hello-cc
|
|
39
|
+
```
|
|
20
40
|
|
|
21
41
|
## 默认入口
|
|
22
42
|
|
|
@@ -194,62 +214,10 @@ Web 操作的是 hello-cc 管理的本机 tmux 终端:
|
|
|
194
214
|
|
|
195
215
|
已经打开的普通 raw 终端不能被无条件捕获或控制,除非它原本就在 tmux、screen 或 hello-cc shim 之下。它仍然可以通过 hooks 和 `hcc` 命令参与任务、消息和锁。
|
|
196
216
|
|
|
197
|
-
##
|
|
217
|
+
## 命令参考
|
|
198
218
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
hcc web [--host HOST] [--port N] [--token TEXT] [--local] [--no-discover] [--no-guidance]
|
|
202
|
-
hcc down
|
|
203
|
-
|
|
204
|
-
# 本地协调,无 Web
|
|
205
|
-
hcc up [--no-discover] [--no-guidance]
|
|
206
|
-
|
|
207
|
-
# 对等节点和状态
|
|
208
|
-
hcc peers
|
|
209
|
-
hcc status [--peer ID]
|
|
210
|
-
hcc scan [--register]
|
|
211
|
-
hcc prompt --peer ID [--kind codex|claude|shell|other] [--role ROLE]
|
|
212
|
-
hcc join --peer ID [--kind codex|claude|shell|other] [--role ROLE]
|
|
213
|
-
hcc env --peer ID
|
|
214
|
-
hcc heartbeat [--peer ID] [--renew-locks --ttl 900]
|
|
215
|
-
hcc run --peer ID --kind codex|claude|shell --role ROLE -- COMMAND [ARGS...]
|
|
216
|
-
|
|
217
|
-
# Web 可控终端
|
|
218
|
-
hcc peer list
|
|
219
|
-
hcc peer start PEER [--kind K] [--role R] [--cwd DIR] [--restart-env] -- COMMAND [ARGS...]
|
|
220
|
-
hcc peer start PEER --kind codex --resume SESSION_ID [--restart-env]
|
|
221
|
-
hcc peer start PEER --kind codex --last
|
|
222
|
-
hcc peer start PEER --kind claude --resume SESSION_ID [--restart-env]
|
|
223
|
-
hcc peer start PEER --kind claude --continue
|
|
224
|
-
hcc peer attach PEER [--pane PANE] [--kind K] [--role R] [--cwd DIR]
|
|
225
|
-
hcc peer stop PEER
|
|
226
|
-
hcc inject PEER TEXT [--no-enter]
|
|
227
|
-
|
|
228
|
-
# 消息
|
|
229
|
-
hcc msg send [--from ID] [--to ID|all] --body TEXT [--task N] [--kind note|task|handoff]
|
|
230
|
-
hcc msg inbox [--peer ID] [--wait SEC] [--all] [--limit N]
|
|
231
|
-
hcc msg ack [--peer ID] --id N
|
|
232
|
-
hcc ask PEER MESSAGE [--from ID] [--task N] [--inject]
|
|
233
|
-
hcc broadcast MESSAGE [--from ID] [--task N] [--inject]
|
|
234
|
-
|
|
235
|
-
# 任务
|
|
236
|
-
hcc task create --title TEXT [--body TEXT] [--from ID] [--to ID] [--priority N]
|
|
237
|
-
hcc task list [--status S] [--peer ID] [--all]
|
|
238
|
-
hcc task claim [--peer ID] --id N
|
|
239
|
-
hcc task next [--peer ID]
|
|
240
|
-
hcc task update [--peer ID] --id N --status running|review|blocked|done|abandoned [--summary TEXT] [--body TEXT] [--to ID]
|
|
241
|
-
hcc task done [--peer ID] --id N --summary TEXT
|
|
242
|
-
|
|
243
|
-
# 锁和交接
|
|
244
|
-
hcc lock acquire [--peer ID] --resource PATH [--task N] [--ttl SEC] [--reason TEXT]
|
|
245
|
-
hcc lock renew [--peer ID] --resource PATH [--ttl SEC]
|
|
246
|
-
hcc lock release [--peer ID] --resource PATH [--force]
|
|
247
|
-
hcc lock list [--all]
|
|
248
|
-
hcc handoff create [--from ID] --summary TEXT [--task N] [--to ID] [--changed-files JSON_OR_CSV] [--tests TEXT] [--risks TEXT]
|
|
249
|
-
hcc handoff list [--task N] [--limit N]
|
|
250
|
-
hcc event tail [--limit N]
|
|
251
|
-
hcc gc [--older-than DAYS] [--yes]
|
|
252
|
-
```
|
|
219
|
+
使用 `hcc --help` 查看命令列表,使用 `hcc <command> --help` 查看单个命令。
|
|
220
|
+
维护中的命令摘要见 [命令参考](commands.zh-CN.md)。
|
|
253
221
|
|
|
254
222
|
## 稳定 peer 身份
|
|
255
223
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@logicseek/hello-cc",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Local control plane for coordinating Claude Code, Codex, and other coding CLI sessions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -11,8 +11,10 @@
|
|
|
11
11
|
"bin/",
|
|
12
12
|
"lib/",
|
|
13
13
|
"scripts/",
|
|
14
|
+
"assets/",
|
|
14
15
|
"README.md",
|
|
15
16
|
"README.zh-CN.md",
|
|
17
|
+
"CHANGELOG.md",
|
|
16
18
|
"LICENSE",
|
|
17
19
|
"docs/"
|
|
18
20
|
],
|
|
@@ -20,6 +22,8 @@
|
|
|
20
22
|
"node": ">=24.0.0"
|
|
21
23
|
},
|
|
22
24
|
"scripts": {
|
|
25
|
+
"release:notes": "node ./scripts/release-notes.mjs",
|
|
26
|
+
"release:check": "node ./scripts/release-notes.mjs --check",
|
|
23
27
|
"smoke": "node ./bin/hcc.mjs --help",
|
|
24
28
|
"test": "node ./scripts/regression.mjs",
|
|
25
29
|
"test:regression": "node ./scripts/regression.mjs"
|
package/scripts/regression.mjs
CHANGED
|
@@ -1124,7 +1124,17 @@ async function downGcPackWorkflow() {
|
|
|
1124
1124
|
await stopRuntime();
|
|
1125
1125
|
await waitFor(() => !fs.existsSync(path.join(root, '.hello-cc', 'runtime.json')), 'runtime cleanup', 5000);
|
|
1126
1126
|
hcc(['gc', '--older-than', '0', '--yes']);
|
|
1127
|
-
run('npm', ['pack', '--dry-run']);
|
|
1127
|
+
const pack = JSON.parse(run('npm', ['pack', '--dry-run', '--json']));
|
|
1128
|
+
const files = new Set(pack[0]?.files?.map((entry) => entry.path) || []);
|
|
1129
|
+
for (const file of ['assets/logo.svg', 'CHANGELOG.md', 'docs/commands.md', 'docs/commands.zh-CN.md']) {
|
|
1130
|
+
if (!files.has(file)) fail(`npm package missing ${file}`);
|
|
1131
|
+
}
|
|
1132
|
+
const releaseCheck = run('npm', ['run', 'release:check']);
|
|
1133
|
+
if (!releaseCheck.includes('release notes ok: 0.1.2')) fail(`release check output wrong:\n${releaseCheck}`);
|
|
1134
|
+
const releaseNotes = run('npm', ['run', 'release:notes']);
|
|
1135
|
+
if (!releaseNotes.includes('## 0.1.2') || !releaseNotes.includes('### Summary')) {
|
|
1136
|
+
fail(`release notes output wrong:\n${releaseNotes}`);
|
|
1137
|
+
}
|
|
1128
1138
|
}
|
|
1129
1139
|
|
|
1130
1140
|
function oldNameScan() {
|
|
@@ -1157,12 +1167,51 @@ function syntaxAndHelp() {
|
|
|
1157
1167
|
run(process.execPath, ['--check', path.join(repoRoot, 'lib', 'setup.mjs')]);
|
|
1158
1168
|
run(process.execPath, ['--check', path.join(repoRoot, 'lib', 'discover.mjs')]);
|
|
1159
1169
|
const mainHelp = run(process.execPath, [hccBin, '--help']);
|
|
1160
|
-
if (mainHelp.includes('setup') || mainHelp.includes('
|
|
1170
|
+
if (mainHelp.includes('setup') || mainHelp.includes('--web-managed')) {
|
|
1161
1171
|
fail(`public help exposes maintenance or removed commands:\n${mainHelp}`);
|
|
1162
1172
|
}
|
|
1173
|
+
if (!mainHelp.includes(' update Update the global npm install of hello-cc')) {
|
|
1174
|
+
fail(`main help missing update command:\n${mainHelp}`);
|
|
1175
|
+
}
|
|
1176
|
+
if (!mainHelp.includes(' uninstall Remove hooks, shims, and optional project data')) {
|
|
1177
|
+
fail(`main help missing uninstall command:\n${mainHelp}`);
|
|
1178
|
+
}
|
|
1179
|
+
const updateHelp = run(process.execPath, [hccBin, 'update', '--help']);
|
|
1180
|
+
if (!updateHelp.includes('hcc update') || !updateHelp.includes('npm install -g @logicseek/hello-cc@TAG')) {
|
|
1181
|
+
fail(`update help missing expected content:\n${updateHelp}`);
|
|
1182
|
+
}
|
|
1183
|
+
const uninstallHelp = run(process.execPath, [hccBin, 'uninstall', '--help']);
|
|
1184
|
+
if (!uninstallHelp.includes('hcc uninstall') || !uninstallHelp.includes('hcc uninstall [--purge --yes]')) {
|
|
1185
|
+
fail(`uninstall help missing expected content:\n${uninstallHelp}`);
|
|
1186
|
+
}
|
|
1187
|
+
const updateDryRun = run(process.execPath, [hccBin, 'update', '--dry-run']);
|
|
1188
|
+
if (!updateDryRun.includes('would run: npm install -g @logicseek/hello-cc@latest')) {
|
|
1189
|
+
fail(`update dry-run output wrong:\n${updateDryRun}`);
|
|
1190
|
+
}
|
|
1191
|
+
const updateJson = JSON.parse(run(process.execPath, [hccBin, '--json', 'update', '--dry-run', '--tag', '0.1.2']));
|
|
1192
|
+
if (!updateJson.ok || updateJson.data.command !== 'npm install -g @logicseek/hello-cc@0.1.2') {
|
|
1193
|
+
fail(`update json dry-run output wrong:\n${JSON.stringify(updateJson)}`);
|
|
1194
|
+
}
|
|
1195
|
+
const updateBuildJson = JSON.parse(run(process.execPath, [hccBin, '--json', 'update', '--dry-run', '--tag', '1.2.3+build.1']));
|
|
1196
|
+
if (!updateBuildJson.ok || updateBuildJson.data.command !== 'npm install -g @logicseek/hello-cc@1.2.3+build.1') {
|
|
1197
|
+
fail(`update build-metadata dry-run output wrong:\n${JSON.stringify(updateBuildJson)}`);
|
|
1198
|
+
}
|
|
1163
1199
|
const runHelp = run(process.execPath, [hccBin, 'run', '--help']);
|
|
1164
1200
|
if (runHelp.includes('--web-managed')) fail(`run help exposes removed --web-managed:\n${runHelp}`);
|
|
1165
|
-
|
|
1201
|
+
const subcommandHelpCases = [
|
|
1202
|
+
['task', 'done', 'hcc task done'],
|
|
1203
|
+
['msg', 'ack', 'hcc msg ack'],
|
|
1204
|
+
['peer', 'attach', 'peer attach'],
|
|
1205
|
+
['lock', 'release', 'hcc lock release'],
|
|
1206
|
+
['handoff', 'create', 'hcc handoff create'],
|
|
1207
|
+
['event', 'tail', 'hcc event tail']
|
|
1208
|
+
];
|
|
1209
|
+
for (const [group, subcommand, expected] of subcommandHelpCases) {
|
|
1210
|
+
const help = run(process.execPath, [hccBin, group, subcommand, '--help']);
|
|
1211
|
+
if (!help.includes(expected)) {
|
|
1212
|
+
fail(`${group} ${subcommand} help missing expected content:\n${help}`);
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1166
1215
|
const removed = runMaybe(process.execPath, [hccBin, '--root', root, 'run', '--peer', 'bad', '--kind', 'shell', '--web-managed', '--', 'bash']);
|
|
1167
1216
|
if (removed.status === 0 || !String(removed.stderr || removed.stdout).includes('unknown option --web-managed')) {
|
|
1168
1217
|
fail(`run --web-managed was not rejected:\n${removed.stdout}\n${removed.stderr}`);
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import fs from 'node:fs';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import process from 'node:process';
|
|
6
|
+
|
|
7
|
+
const repoRoot = path.resolve(import.meta.dirname, '..');
|
|
8
|
+
|
|
9
|
+
function usage() {
|
|
10
|
+
console.log(`release-notes
|
|
11
|
+
|
|
12
|
+
Usage:
|
|
13
|
+
node scripts/release-notes.mjs [--version VERSION] [--check]
|
|
14
|
+
|
|
15
|
+
Reads CHANGELOG.md and prints the section for VERSION. If VERSION is omitted,
|
|
16
|
+
the current package.json version is used.
|
|
17
|
+
|
|
18
|
+
Keep one top-level CHANGELOG.md file. For each release, add a new section:
|
|
19
|
+
|
|
20
|
+
## 0.1.3
|
|
21
|
+
|
|
22
|
+
The printed section is the source for GitHub Release notes and detailed npm
|
|
23
|
+
package release descriptions.
|
|
24
|
+
`);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
function readJson(file) {
|
|
28
|
+
return JSON.parse(fs.readFileSync(file, 'utf8'));
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function parseArgs(argv) {
|
|
32
|
+
const opts = { check: false, help: false, version: null };
|
|
33
|
+
for (let i = 0; i < argv.length; i += 1) {
|
|
34
|
+
const arg = argv[i];
|
|
35
|
+
if (arg === '--help' || arg === '-h') {
|
|
36
|
+
opts.help = true;
|
|
37
|
+
} else if (arg === '--check') {
|
|
38
|
+
opts.check = true;
|
|
39
|
+
} else if (arg === '--version') {
|
|
40
|
+
opts.version = argv[++i];
|
|
41
|
+
if (opts.version === undefined) throw new Error('Missing value for --version');
|
|
42
|
+
} else if (arg.startsWith('--version=')) {
|
|
43
|
+
opts.version = arg.slice('--version='.length);
|
|
44
|
+
} else {
|
|
45
|
+
throw new Error(`Unknown argument: ${arg}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return opts;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function releaseSection(markdown, version) {
|
|
52
|
+
const lines = markdown.split(/\r?\n/);
|
|
53
|
+
const heading = `## ${version}`;
|
|
54
|
+
const start = lines.findIndex((line) => line.trim() === heading);
|
|
55
|
+
if (start < 0) return null;
|
|
56
|
+
|
|
57
|
+
let end = lines.length;
|
|
58
|
+
for (let i = start + 1; i < lines.length; i += 1) {
|
|
59
|
+
if (/^##\s+/.test(lines[i])) {
|
|
60
|
+
end = i;
|
|
61
|
+
break;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return lines.slice(start, end).join('\n').trimEnd();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function validateSection(section, version) {
|
|
68
|
+
const problems = [];
|
|
69
|
+
if (!section) {
|
|
70
|
+
problems.push(`CHANGELOG.md is missing section ## ${version}`);
|
|
71
|
+
return problems;
|
|
72
|
+
}
|
|
73
|
+
if (!section.includes('### Summary')) problems.push(`## ${version} is missing ### Summary`);
|
|
74
|
+
if (!section.includes('### Highlights')) problems.push(`## ${version} is missing ### Highlights`);
|
|
75
|
+
if (section.includes('TODO') || section.includes('TBD')) problems.push(`## ${version} still contains TODO/TBD text`);
|
|
76
|
+
const bulletCount = (section.match(/^- /gm) || []).length;
|
|
77
|
+
if (bulletCount < 2) problems.push(`## ${version} should include at least two release-note bullets`);
|
|
78
|
+
return problems;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function main() {
|
|
82
|
+
const opts = parseArgs(process.argv.slice(2));
|
|
83
|
+
if (opts.help) {
|
|
84
|
+
usage();
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
const pkg = readJson(path.join(repoRoot, 'package.json'));
|
|
89
|
+
const version = opts.version || pkg.version;
|
|
90
|
+
const changelog = fs.readFileSync(path.join(repoRoot, 'CHANGELOG.md'), 'utf8');
|
|
91
|
+
const section = releaseSection(changelog, version);
|
|
92
|
+
const problems = validateSection(section, version);
|
|
93
|
+
|
|
94
|
+
if (opts.check) {
|
|
95
|
+
if (problems.length) {
|
|
96
|
+
console.error(problems.join('\n'));
|
|
97
|
+
process.exitCode = 1;
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
console.log(`release notes ok: ${version}`);
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (problems.length) {
|
|
105
|
+
console.error(problems.join('\n'));
|
|
106
|
+
process.exitCode = 1;
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
console.log(section);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
main();
|