@logicseek/hello-cc 0.1.7 → 0.1.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +107 -0
- package/README.md +20 -7
- package/README.zh-CN.md +15 -6
- package/bin/hcc.mjs +383 -62
- package/docs/commands.md +16 -7
- package/docs/commands.zh-CN.md +14 -7
- package/docs/guide.md +24 -7
- package/docs/guide.zh-CN.md +20 -6
- package/lib/core/coordination/timeline.mjs +1 -0
- package/lib/core/sessions/launch.mjs +3 -0
- package/lib/integrations/shims/script.mjs +66 -24
- package/lib/integrations/shims.mjs +45 -6
- package/lib/runtime/client.mjs +1 -1
- package/lib/runtime/state.mjs +6 -3
- package/lib/setup.mjs +1 -0
- package/lib/shell-path.mjs +31 -16
- package/lib/ui/help.mjs +36 -1
- package/lib/web/http.mjs +8 -1
- package/package.json +1 -1
- package/scripts/regression.mjs +651 -48
package/lib/shell-path.mjs
CHANGED
|
@@ -2,26 +2,28 @@ import fs from 'node:fs';
|
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
|
|
5
|
-
export function pathEntryLine(shellType) {
|
|
6
|
-
|
|
7
|
-
return
|
|
5
|
+
export function pathEntryLine(shellType, position = 'final') {
|
|
6
|
+
const suffix = position === 'early' ? 'early' : 'final';
|
|
7
|
+
if (shellType === 'fish') return `set -gx PATH $HOME/.hcc-shims $PATH # hello-cc shims (${suffix})`;
|
|
8
|
+
return `_hcc_shims="$HOME/.hcc-shims"; PATH="\${PATH//:\${_hcc_shims}:/:}"; PATH="\${PATH#\${_hcc_shims}:}"; PATH="\${PATH%:\${_hcc_shims}}"; export PATH="\${_hcc_shims}:$PATH"; unset _hcc_shims # hello-cc shims (${suffix})`;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
export function removePathEntryLines(content) {
|
|
11
12
|
return String(content || '')
|
|
12
13
|
.split('\n')
|
|
13
|
-
.filter(line => !line
|
|
14
|
+
.filter(line => !isHelloCcShimPathLine(line))
|
|
14
15
|
.join('\n')
|
|
15
16
|
.replace(/\n{3,}/g, '\n\n')
|
|
16
17
|
.replace(/\s+$/, '');
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
export function insertPathEntry(content, shellType) {
|
|
20
|
-
const line = pathEntryLine(shellType);
|
|
21
21
|
const cleaned = removePathEntryLines(content);
|
|
22
|
-
|
|
22
|
+
const finalLine = pathEntryLine(shellType, 'final');
|
|
23
|
+
if (shellType === 'fish' || shellType === 'zsh') return `${cleaned}${cleaned ? '\n' : ''}${finalLine}\n`;
|
|
23
24
|
|
|
24
25
|
const lines = cleaned ? cleaned.split('\n') : [];
|
|
26
|
+
const earlyLine = pathEntryLine(shellType, 'early');
|
|
25
27
|
let insertAt = 0;
|
|
26
28
|
if (lines[0]?.startsWith('#!')) insertAt = 1;
|
|
27
29
|
for (let i = insertAt; i < lines.length; i += 1) {
|
|
@@ -30,9 +32,9 @@ export function insertPathEntry(content, shellType) {
|
|
|
30
32
|
insertAt = i;
|
|
31
33
|
break;
|
|
32
34
|
}
|
|
33
|
-
lines.splice(insertAt, 0,
|
|
35
|
+
lines.splice(insertAt, 0, earlyLine);
|
|
34
36
|
const withEarlyEntry = lines.join('\n').replace(/\s+$/, '');
|
|
35
|
-
return `${withEarlyEntry}${withEarlyEntry ? '\n' : ''}${
|
|
37
|
+
return `${withEarlyEntry}${withEarlyEntry ? '\n' : ''}${finalLine}\n`;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
export function detectShellRc() {
|
|
@@ -49,21 +51,34 @@ export function installPathEntry() {
|
|
|
49
51
|
|
|
50
52
|
const next = insertPathEntry(content, shellType);
|
|
51
53
|
const alreadyPresent = next === (content.endsWith('\n') ? content : `${content}\n`);
|
|
52
|
-
if (!alreadyPresent)
|
|
54
|
+
if (!alreadyPresent) {
|
|
55
|
+
fs.mkdirSync(path.dirname(rcFile), { recursive: true });
|
|
56
|
+
fs.writeFileSync(rcFile, next);
|
|
57
|
+
}
|
|
53
58
|
return { rcFile, shellType, alreadyPresent };
|
|
54
59
|
}
|
|
55
60
|
|
|
56
61
|
export function uninstallPathEntry() {
|
|
57
62
|
const { path: rcFile } = detectShellRc();
|
|
63
|
+
let content = '';
|
|
64
|
+
try {
|
|
65
|
+
content = fs.readFileSync(rcFile, 'utf8');
|
|
66
|
+
} catch (err) {
|
|
67
|
+
if (err?.code === 'ENOENT') return { rcFile, removed: false, missing: true };
|
|
68
|
+
return { rcFile, removed: false, error: 'could not read shell rc' };
|
|
69
|
+
}
|
|
70
|
+
const filtered = removePathEntryLines(content);
|
|
71
|
+
if (filtered === content.replace(/\s+$/, '')) {
|
|
72
|
+
return { rcFile, removed: false };
|
|
73
|
+
}
|
|
58
74
|
try {
|
|
59
|
-
const content = fs.readFileSync(rcFile, 'utf8');
|
|
60
|
-
const filtered = content
|
|
61
|
-
.split('\n')
|
|
62
|
-
.filter(line => !line.includes('.hcc-shims'))
|
|
63
|
-
.join('\n');
|
|
64
75
|
fs.writeFileSync(rcFile, filtered);
|
|
65
|
-
return { rcFile };
|
|
76
|
+
return { rcFile, removed: true };
|
|
66
77
|
} catch {
|
|
67
|
-
return { rcFile, error: 'could not modify shell rc' };
|
|
78
|
+
return { rcFile, removed: false, error: 'could not modify shell rc' };
|
|
68
79
|
}
|
|
69
80
|
}
|
|
81
|
+
|
|
82
|
+
function isHelloCcShimPathLine(line) {
|
|
83
|
+
return String(line || '').includes('# hello-cc shims');
|
|
84
|
+
}
|
package/lib/ui/help.mjs
CHANGED
|
@@ -60,6 +60,8 @@ Environment:
|
|
|
60
60
|
|
|
61
61
|
Usage:
|
|
62
62
|
${cliName} task create --title TEXT [--body TEXT] [--from ID] [--to ID] [--priority N]
|
|
63
|
+
${cliName} task dispatch --to ID --title TEXT [--body TEXT] [--from ID] [--message TEXT] [--no-inject] [--force]
|
|
64
|
+
${cliName} task dispatch --to ID --id N [--from ID] [--message TEXT] [--no-inject] [--force]
|
|
63
65
|
${cliName} task create --title TEXT --parent N [--team-role ROLE]
|
|
64
66
|
${cliName} task list [--status pending|claimed|running|review|blocked|done|abandoned] [--peer ID] [--all]
|
|
65
67
|
${cliName} task claim [--peer ID] --id N[,N] [--id N] [--ids N,N] [--force]
|
|
@@ -74,6 +76,11 @@ Messages use per-peer unread ack state; tasks do not.
|
|
|
74
76
|
task next returns your existing claimed/running/review/blocked task before
|
|
75
77
|
claiming another pending task. Use --force when intentionally taking additional
|
|
76
78
|
pending tasks; combine it with --count N for explicit batch claims.
|
|
79
|
+
task dispatch explicitly assigns a new or existing task to one peer, sends a
|
|
80
|
+
durable task message, and injects the startup prompt only when the peer has a
|
|
81
|
+
running managed Claude/Codex terminal. Use --no-inject for message-only
|
|
82
|
+
dispatch; use --force only when intentionally injecting while the target already
|
|
83
|
+
owns another active task.
|
|
77
84
|
Use task takeover when explicitly taking over a non-complete task from another
|
|
78
85
|
owner; it records the previous owner, requires a reason, and notifies them.
|
|
79
86
|
Use --policy blocked, stale, or blocked-or-stale to require an auditable
|
|
@@ -380,7 +387,7 @@ Usage:
|
|
|
380
387
|
${cliName} uninstall [--purge --yes]
|
|
381
388
|
|
|
382
389
|
Stops the current project runtime and removes user-level hello-cc integrations:
|
|
383
|
-
Claude/Codex hooks
|
|
390
|
+
Claude/Codex hooks, claude/codex shims, and the shell PATH entry for shims.
|
|
384
391
|
|
|
385
392
|
With --purge --yes, also removes current project data:
|
|
386
393
|
.hello-cc/
|
|
@@ -388,6 +395,34 @@ With --purge --yes, also removes current project data:
|
|
|
388
395
|
`);
|
|
389
396
|
},
|
|
390
397
|
|
|
398
|
+
helpInstallHooks() {
|
|
399
|
+
console.log(`${cliName} install-hooks
|
|
400
|
+
|
|
401
|
+
Usage:
|
|
402
|
+
${cliName} install-hooks
|
|
403
|
+
${cliName} install-hooks --status
|
|
404
|
+
${cliName} install-hooks --uninstall
|
|
405
|
+
|
|
406
|
+
Installs, checks, or removes Claude Code and Codex hook entries used by
|
|
407
|
+
hello-cc. This is a maintenance command; hcc up, hcc web, and hcc setup install
|
|
408
|
+
hooks automatically when needed.
|
|
409
|
+
`);
|
|
410
|
+
},
|
|
411
|
+
|
|
412
|
+
helpShim() {
|
|
413
|
+
console.log(`${cliName} shim
|
|
414
|
+
|
|
415
|
+
Usage:
|
|
416
|
+
${cliName} shim install
|
|
417
|
+
${cliName} shim status
|
|
418
|
+
${cliName} shim uninstall
|
|
419
|
+
|
|
420
|
+
Installs, checks, or removes claude/codex shims in ~/.hcc-shims and manages the
|
|
421
|
+
shell PATH entry for that directory. hcc web and hcc setup install shims
|
|
422
|
+
automatically when provider CLIs are available on PATH.
|
|
423
|
+
`);
|
|
424
|
+
},
|
|
425
|
+
|
|
391
426
|
helpWeb() {
|
|
392
427
|
console.log(`${cliName} web
|
|
393
428
|
|
package/lib/web/http.mjs
CHANGED
|
@@ -19,7 +19,14 @@ function readRequestBody(req, limit = 1024 * 1024) {
|
|
|
19
19
|
export async function readJsonRequest(req) {
|
|
20
20
|
const body = await readRequestBody(req);
|
|
21
21
|
if (!body.trim()) return {};
|
|
22
|
-
|
|
22
|
+
try {
|
|
23
|
+
return JSON.parse(body);
|
|
24
|
+
} catch (err) {
|
|
25
|
+
if (err instanceof SyntaxError) {
|
|
26
|
+
throw new CliError('BAD_REQUEST', 'Invalid JSON request body');
|
|
27
|
+
}
|
|
28
|
+
throw err;
|
|
29
|
+
}
|
|
23
30
|
}
|
|
24
31
|
|
|
25
32
|
export function sendHttp(res, status, contentType, body) {
|