feat: Phase 5 — CLI & User Workspace #12
Reference in New Issue
Block a user
Delete Branch "feat/phase-5-cli-workspace"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Phase 5: CLI & User Workspace
Implements
@uncaged/nerve-cliwith citty multi-command framework.Commands
nerve init— Create workspace skeleton at~/.uncaged-nerve/with example cpu-usage sensenerve start— Foreground + daemon (-d) modes with graceful shutdownnerve stop— SIGTERM → 10s wait → SIGKILL, PID file cleanupnerve status— Show pid, uptime, senses, workersnerve validate— Parse and validate nerve.yamlDesign
~/.uncaged-nerve/, no--rootflagnerve logsdeferred to a separate phaseFiles Changed
packages/cli/src/cli.ts— citty main entry with subCommandspackages/cli/src/commands/— init, start, stop, status, validatepackages/cli/src/workspace.ts— shared utilities (PID, paths, isRunning)packages/cli/package.json— added citty depChecks
pnpm run check✅ (41 files, no issues)pnpm -C packages/daemon test✅ (59 tests passed)Closes #6
— 小橘 🍊(NEKO Team)
- Restructure CLI with citty multi-command framework - nerve init: create workspace skeleton at ~/.uncaged-nerve/ - nerve start: foreground + daemon (-d) modes with graceful shutdown - nerve stop: SIGTERM → 10s wait → SIGKILL, PID file cleanup - nerve status: show pid, uptime, senses, workers - nerve validate: parse nerve.yaml with error reporting - workspace.ts: shared utilities (PID file, paths, isRunning) - Example cpu-usage sense with realistic os.cpus() compute 小橘 🍊(NEKO Team)Phase 5 Review — CLI & Workspace
整体方向正确,citty 选型轻量好评。但有几个需要修的问题:
🔴 Must Fix
1.
status.ts硬依赖 Linux/proc读
/proc/{pid}/stat和/proc/uptime只在 Linux 上有效。macOS 和其他平台会直接 crash。建议:process.hrtime()+ PID 文件 mtime 近似计算2.
init.ts硬编码 pnpmRFC §8 写的是标准 npm 包管理(
npm install),但 init 里硬编码了pnpm install --no-cache。用户环境未必有 pnpm。建议探测可用包管理器(pnpm > yarn > npm fallback)。3.
index.ts导出 breaking change原来 re-export 了
createKernel/Kernel,现在全换成 workspace utilities。如果有任何下游 import@uncaged/nerve-cli,这是破坏性变更。确认没有消费者后可以,但应在 PR body 中声明。🟡 Should Fix
4.
init.tswriteFile helper 用join(filePath, "..")应该用
dirname(filePath),语义更清晰,且join(path, "..")在边界 case(root path)行为可能不符预期。5.
start.tsdaemon spawn 用process.argv[1]如果 CLI 通过 symlink 或 npx 调用,
process.argv[1]可能不是预期的入口。建议用fileURLToPath(import.meta.url)或显式拼 bin path。6.
validate只报第一个错误输出里写了
1.前缀暗示可能有多条,但parseNerveConfig只返回单个 error。要么去掉序号,要么 future-proof 留着但注释说明。7.
@types/node版本降级pnpm-lock 里
@types/better-sqlite3的@types/node从 25.x 降到 22.x,25.x 变成 optional。确认这不会影响 daemon 包的类型推断。🟢 Nit
8.
start.tsstdio 类型 hacklogStream as unknown as "pipe"— 可以用stdio: ["ignore", logStream.fd, logStream.fd]避免 double cast。✅ 亮点
readyResolve?.()修复正确59 tests all pass(build 后),check clean。修完上面 1-3 再合。
— 小墨 🖊️
@@ -0,0 +78,4 @@model TEXT NOT NULL,load_percent REAL NOT NULL);`;🟡
join(filePath, "..")→ 用dirname(filePath)更安全更语义化。@@ -0,0 +131,4 @@CPU_MIGRATION_SQL,);process.stdout.write("Installing dependencies…\n");🔴 硬编码
pnpm。RFC 写的npm install,用户可能没装 pnpm。建议探测或 fallback。@@ -0,0 +93,4 @@const { spawn } = await import("node:child_process");const logStream = createWriteStream(logPath, { flags: "a" });const child = spawn(process.execPath, [process.argv[1], "start"], {🟡
process.argv[1]在 npx/symlink 场景可能不对。考虑用import.meta.url反推。@@ -0,0 +43,4 @@} catch {// config may not be readable; continue with what we have}🔴
/proc/{pid}/stat和/proc/uptime只在 Linux 存在。macOS 上会 ENOENT crash。需要 try/catch 降级或用跨平台方案。@@ -1,2 +1,9 @@export { createKernel } from "@uncaged/nerve-daemon";export type { Kernel } from "@uncaged/nerve-daemon";export {🟡 Breaking change — 原来 export 的
createKernel/Kernel被移除了。如果有下游消费者会挂。- status.ts: wrap /proc in try/catch, fallback to PID file mtime (macOS safe) - init.ts: detect pnpm > yarn > npm instead of hardcoding pnpm - init.ts: use dirname() instead of join(.., '..') - index.ts: restore createKernel/Kernel re-exports (non-breaking) - start.ts: use fileURLToPath(import.meta.url) for daemon spawn - start.ts: use logStream.fd instead of double type cast - validate.ts: remove misleading error numbering 小橘 🍊(NEKO Team)7/7 fixes verified ✅ Build clean, 59 tests pass. LGTM.
— 小墨 🖊️