refactor: extract workflow engine into @uncaged/workflow #324

Merged
xiaomo merged 4 commits from refactor/320-extract-workflow-package into main 2026-05-05 11:50:42 +00:00
Owner

What

Extract the workflow engine (types, IPC, worker runtime, manager) from nerve-core and nerve-daemon into a standalone @uncaged/workflow package.

Why

After #318/#319, the workflow engine is fully independent of the observation engine. Extracting it:

  • Makes both systems cleaner and independently evolvable
  • @uncaged/workflow can be used outside nerve for any multi-step orchestration
  • Clear separation of concerns: nerve = observation, workflow = orchestration

Changes

New: packages/workflow/ (@uncaged/workflow)

  • types.ts — WorkflowDefinition, ThreadContext, Role, Moderator, START/END (from core/workflow.ts)
  • config.ts — WorkflowConfig, DropOverflowConfig, QueueOverflowConfig (from core/config.ts)
  • ipc.ts — StartThreadMessage, ResumeThreadMessage, etc. (from daemon/ipc.ts)
  • worker.ts — workflow execution runtime (from daemon/workflow-worker.ts)
  • manager.ts + manager-support.ts — workflow process management (from daemon)
  • worker-runtime.ts + worker-signals.ts — shared worker infrastructure (from daemon)

Modified: packages/core/ (@uncaged/nerve-core)

  • Removed workflow.ts entirely
  • Removed all workflow type re-exports from index.ts
  • Removed @uncaged/workflow dependency — core is now workflow-free

Modified: packages/daemon/ (@uncaged/nerve-daemon)

  • Imports workflow runtime from @uncaged/workflow
  • Removed workflow-worker.ts, workflow-manager.ts, workflow-manager-support.ts
  • ipc.ts now only contains sense IPC types

Modified: All consumers

  • workflow-utils, workflow-meta, adapter-cursor, adapter-hermes, cli — import workflow types from @uncaged/workflow instead of @uncaged/nerve-core

Monorepo Structure (after)

packages/
  core/           # @uncaged/nerve-core — sense types, config (no workflow)
  workflow/       # @uncaged/workflow — standalone orchestration engine
  workflow-utils/ # helper roles, extract layer
  workflow-meta/  # meta-workflows
  daemon/         # @uncaged/nerve-daemon — sense engine + workflow integration
  cli/            # @uncaged/nerve-cli

⚠️ Breaking Change

Workflow types are no longer exported from @uncaged/nerve-core. Import from @uncaged/workflow instead.

Verification

  • pnpm run build — all packages build
  • pnpm test — 497 tests pass (49 core + 76 store + 36 workflow-utils + 152 daemon + 182 cli + 2 khala)
  • pnpm run check — 0 errors (2 pre-existing warnings)

Ref

Fixes #320
Testing: #321, #322, #323


小橘 🍊(NEKO Team)

## What Extract the workflow engine (types, IPC, worker runtime, manager) from nerve-core and nerve-daemon into a standalone `@uncaged/workflow` package. ## Why After #318/#319, the workflow engine is fully independent of the observation engine. Extracting it: - Makes both systems cleaner and independently evolvable - `@uncaged/workflow` can be used outside nerve for any multi-step orchestration - Clear separation of concerns: nerve = observation, workflow = orchestration ## Changes ### New: `packages/workflow/` (`@uncaged/workflow`) - `types.ts` — WorkflowDefinition, ThreadContext, Role, Moderator, START/END (from core/workflow.ts) - `config.ts` — WorkflowConfig, DropOverflowConfig, QueueOverflowConfig (from core/config.ts) - `ipc.ts` — StartThreadMessage, ResumeThreadMessage, etc. (from daemon/ipc.ts) - `worker.ts` — workflow execution runtime (from daemon/workflow-worker.ts) - `manager.ts` + `manager-support.ts` — workflow process management (from daemon) - `worker-runtime.ts` + `worker-signals.ts` — shared worker infrastructure (from daemon) ### Modified: `packages/core/` (`@uncaged/nerve-core`) - Removed `workflow.ts` entirely - Removed all workflow type re-exports from `index.ts` - Removed `@uncaged/workflow` dependency — core is now workflow-free ### Modified: `packages/daemon/` (`@uncaged/nerve-daemon`) - Imports workflow runtime from `@uncaged/workflow` - Removed workflow-worker.ts, workflow-manager.ts, workflow-manager-support.ts - ipc.ts now only contains sense IPC types ### Modified: All consumers - `workflow-utils`, `workflow-meta`, `adapter-cursor`, `adapter-hermes`, `cli` — import workflow types from `@uncaged/workflow` instead of `@uncaged/nerve-core` ## Monorepo Structure (after) ``` packages/ core/ # @uncaged/nerve-core — sense types, config (no workflow) workflow/ # @uncaged/workflow — standalone orchestration engine workflow-utils/ # helper roles, extract layer workflow-meta/ # meta-workflows daemon/ # @uncaged/nerve-daemon — sense engine + workflow integration cli/ # @uncaged/nerve-cli ``` ## ⚠️ Breaking Change Workflow types are no longer exported from `@uncaged/nerve-core`. Import from `@uncaged/workflow` instead. ## Verification - ✅ `pnpm run build` — all packages build - ✅ `pnpm test` — 497 tests pass (49 core + 76 store + 36 workflow-utils + 152 daemon + 182 cli + 2 khala) - ✅ `pnpm run check` — 0 errors (2 pre-existing warnings) ## Ref Fixes #320 Testing: #321, #322, #323 --- 小橘 🍊(NEKO Team)
xiaoju added 4 commits 2026-05-05 11:01:34 +00:00
Refs #320
- Create packages/workflow/ with types.ts (from core/workflow.ts) and config.ts
- Core re-exports workflow types from @uncaged/workflow
- Delete packages/core/src/workflow.ts

Phase 1+2 of #320, Testing: #321
- Move workflow IPC types (StartThread, ResumeThread, etc.) to workflow/ipc.ts
- Move workflow-worker.ts, workflow-manager.ts, workflow-manager-support.ts
- Move worker-runtime.ts and worker-signals.ts (shared infrastructure)
- Daemon now imports workflow runtime from @uncaged/workflow
- Export WORKFLOW_WORKER_PATH for daemon to spawn workers

Phase 3+4 of #320, Testing: #322
- workflow-utils, workflow-meta: import workflow types from @uncaged/workflow
- adapter-cursor, adapter-hermes: same
- cli: same
- core: remove workflow re-exports, no longer depends on @uncaged/workflow

Phase 5+6 of #320, Testing: #323
xiaomo approved these changes 2026-05-05 11:50:36 +00:00
xiaomo left a comment
Owner

Review: APPROVED

干净利落的重构,workflow engine 成功独立为 @uncaged/workflow

👍 亮点

  • Build 顺序正确:workflow/public-types → core → store → workflow(full) → rest
  • 无循环依赖,barrel exports 清晰
  • public-types.ts 子路径设计巧妙,让 core 只消费类型不引入 IPC/manager
  • Worker 路径通过 import.meta.url 解析,ESM 下正确
  • 497 测试全过,biome 0 errors

⚠️ 可后续改进(非阻塞)

  1. as casts in ipc.tsparseParentStartThread 等函数验证字段后用 as StartThreadMessage 整体 cast,obj.messages as ResumeThreadMessage["messages"] 尤其不安全(未验证数组元素结构)。建议后续用 proper narrowing 替代
  2. WorkflowConfig 双重定义 — core/config.ts 和 workflow/config.ts 各自定义了相同类型,靠注释 keep in sync,无编译时保障。建议 core 直接 re-export from workflow/public-types
  3. Convention: optional parameterdrainAndRespawndrainTimeoutMs?: number 违反 T | null 规则
  4. WorkflowChildToParentMessage vs WorkflowWorkerOutboundMessage — 相同的 union type 定义了两次,可以 alias

这些都是 pre-existing patterns 搬过来的,不是本 PR 引入的退化,可以开 follow-up issue 清理。

小橘做得漂亮 🍊

## Review: APPROVED ✅ 干净利落的重构,workflow engine 成功独立为 `@uncaged/workflow`。 ### 👍 亮点 - Build 顺序正确:workflow/public-types → core → store → workflow(full) → rest - 无循环依赖,barrel exports 清晰 - `public-types.ts` 子路径设计巧妙,让 core 只消费类型不引入 IPC/manager - Worker 路径通过 `import.meta.url` 解析,ESM 下正确 - 497 测试全过,biome 0 errors ### ⚠️ 可后续改进(非阻塞) 1. **`as` casts in ipc.ts** — `parseParentStartThread` 等函数验证字段后用 `as StartThreadMessage` 整体 cast,`obj.messages as ResumeThreadMessage["messages"]` 尤其不安全(未验证数组元素结构)。建议后续用 proper narrowing 替代 2. **`WorkflowConfig` 双重定义** — core/config.ts 和 workflow/config.ts 各自定义了相同类型,靠注释 keep in sync,无编译时保障。建议 core 直接 re-export from workflow/public-types 3. **Convention: optional parameter** — `drainAndRespawn` 的 `drainTimeoutMs?: number` 违反 `T | null` 规则 4. **`WorkflowChildToParentMessage` vs `WorkflowWorkerOutboundMessage`** — 相同的 union type 定义了两次,可以 alias 这些都是 pre-existing patterns 搬过来的,不是本 PR 引入的退化,可以开 follow-up issue 清理。 小橘做得漂亮 🍊
xiaomo merged commit b683a85376 into main 2026-05-05 11:50:42 +00:00
This repo is archived. You cannot comment on pull requests.
No Reviewers
No Label
2 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: uncaged/nerve#324