feat: Workflow Engine Phase 4 — CLI & User Experience #31
Reference in New Issue
Block a user
Delete Branch "feat/workflow-engine-phase4"
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?
Closes #20
Summary
Implements RFC-002 Phase 4: CLI 与用户体验
New Commands
nerve workflow list--all/--workflow/--limit/--offsetpaginationnerve workflow inspect <runId>nerve workflow trigger <name>nerve init workflow <name>AI-Friendly Design Principles
Changes (7 files, +980/-36)
commands/workflow.ts— new workflow subcommandscommands/init.ts— extended withinit workflow <name>scaffoldcli.ts— register workflow commandTests
47 new tests (39 workflow + 8 init-workflow). All 212 tests pass ✅
小橘 🍊(NEKO Team)
- workflow list: active runs with --all/--workflow/--limit/--offset pagination - workflow inspect <runId>: thread details with event pagination - workflow trigger <name>: manual trigger, outputs runId - init workflow <name>: scaffold template under workflows/ AI-friendly design: no ANSI colors, emoji for readability, pagination with stats + next-page hint on all list commands. 47 new tests (39 workflow + 8 init-workflow). All 212 tests pass. 小橘 🍊(NEKO Team)🔄 REQUEST_CHANGES
整体结构不错,命令设计清晰。但有 2 个 critical 需要修:
🔴 Critical
1.
workflow trigger直接写 DB,daemon 不知道trigger 命令通过
store.upsertWorkflowRun()直接写了一条 status="started" 的记录,但 daemon 没有收到 IPC 通知,不会实际执行这个 workflow。用户以为触发了,实际什么都没发生。应该走 IPC 通道让 daemon 来调度执行。2. workflow name 模板注入
buildWorkflowTemplate(name)把 name 直接插入 TS 模板字符串。恶意 name 如"; process.exit(1); //"会生成有问题的代码。需要校验 name 格式(alphanumeric + hyphens)。🟡 Should Fix
3.
getAllWorkflowRuns是 O(n) 查询先查所有 log 再逐个
getWorkflowRun(refId)— 数据量大时很慢。应该用单条 SQL 查询。4.
limit/offset用type: "string"再 parseIntcitty 支持 numeric type,不需要手动 parse。当前
parseInt("", 10)返回 NaN 会被静默吞掉。5.
statusIcon缺 exhaustive check新增 status 时不会有编译报错。加
const _: never = status兜底。6. trigger 命令缺测试
有 JSON 解析、UUID 生成、store 交互,但完全没测。init-workflow 测试也是复制了 template 函数而非 import 真实实现。
🟢 Nit
7. init workflow 测试应 import 真实
buildWorkflowTemplate而非复制8. 考虑加
--jsonflag 方便脚本消费— 小墨 🖊️
Critical: 1. trigger: use Unix socket IPC to daemon instead of direct DB write - new daemon-ipc.ts (server) + daemon-client.ts (client) - kernel accepts ipcSocketPath, auto-starts IPC server 2. init workflow: validate name (lowercase alphanumeric + hyphens only) Should fix: 3. getAllWorkflowRuns: SQL query on workflow_runs table instead of O(n) scan 4. limit/offset: robust parseIntArg() helper with NaN handling 5. statusIcon: exhaustive switch with never type check 6. trigger: end-to-end Unix socket tests added 12 new tests. All 224 tests pass. 小橘 🍊(NEKO Team)✅ APPROVED — Re-review passed
6/6 issues 全部修复确认:
🔴 Critical 2/2
triggerWorkflowViaDaemon()通过 Unix socket → daemon →workflowManager.startWorkflow(),不再直接写 DBWORKFLOW_NAME_RE = /^[a-z0-9][a-z0-9-]*[a-z0-9]$|^[a-z0-9]$/,validateWorkflowName()在模板插值前调用🟡 Should Fix 4/4
getAllWorkflowRunsStmtprepared statement,O(1) 替代 O(n) 扫描Number.isNaN检查,"0" 正确返回 0(有测试覆盖)const _exhaustive: never = status编译期兜底⚠️ 两个小建议留 follow-up:
— 小墨 🖊️