refactor: split @uncaged/workflow-runtime from engine #126

Merged
xiaomo merged 3 commits from refactor/121-split-workflow-runtime into main 2026-05-08 06:42:15 +00:00
Owner

What

Split @uncaged/workflow into two packages:

  • @uncaged/workflow-runtime — minimal, zero-dependency runtime for bundles
  • @uncaged/workflow — engine (CAS, merkle, registry, supervisor, dynamic import)

Why

Bundles were importing the entire engine just to get types and createWorkflow. Now they only depend on runtime (zero node:fs, zero external deps).

Changes

Phase 1: Create @uncaged/workflow-runtime

  • New package with types, createWorkflow, validateWorkflowDescriptor, Result, START/END
  • Zero external dependencies (zod as peer only)
  • CAS/ExtractFn injected via parameters, no I/O imports

Phase 2+3: Migrate downstream packages

  • agent-cursor, agent-hermes → pure runtime dependency
  • agent-llm, util-agent, templates → dual dependency (runtime for types, engine for CAS/merkle)

Phase 4: Clean break

  • Engine index.ts no longer re-exports runtime — breaking change
  • Bundle validator updated to allow @uncaged/workflow-runtime imports
  • Init templates updated

Breaking Changes

  • @uncaged/workflow no longer exports runtime types — import from @uncaged/workflow-runtime
  • AgentBinding.overrides is now Partial<Record<string, AgentFn>> | null (no ?:)

Verification

  • 378 tests passing
  • bun run build
  • bun run check

Fixes #121
Relates #122 #123 #124 #125

## What Split `@uncaged/workflow` into two packages: - **`@uncaged/workflow-runtime`** — minimal, zero-dependency runtime for bundles - **`@uncaged/workflow`** — engine (CAS, merkle, registry, supervisor, dynamic import) ## Why Bundles were importing the entire engine just to get types and `createWorkflow`. Now they only depend on runtime (zero `node:fs`, zero external deps). ## Changes ### Phase 1: Create `@uncaged/workflow-runtime` - New package with types, `createWorkflow`, `validateWorkflowDescriptor`, `Result`, `START`/`END` - Zero external dependencies (zod as peer only) - CAS/ExtractFn injected via parameters, no I/O imports ### Phase 2+3: Migrate downstream packages - `agent-cursor`, `agent-hermes` → pure runtime dependency - `agent-llm`, `util-agent`, templates → dual dependency (runtime for types, engine for CAS/merkle) ### Phase 4: Clean break - Engine `index.ts` no longer re-exports runtime — breaking change - Bundle validator updated to allow `@uncaged/workflow-runtime` imports - Init templates updated ## Breaking Changes - `@uncaged/workflow` no longer exports runtime types — import from `@uncaged/workflow-runtime` - `AgentBinding.overrides` is now `Partial<Record<string, AgentFn>> | null` (no `?:`) ## Verification - 378 tests passing - `bun run build` ✅ - `bun run check` ✅ Fixes #121 Relates #122 #123 #124 #125
xiaoju added 3 commits 2026-05-08 06:38:22 +00:00
Create packages/workflow-runtime with the minimal runtime subset:
- Types (WorkflowFn, RoleOutput, AgentBinding, etc.)
- createWorkflow (pure orchestration, zero I/O)
- validateWorkflowDescriptor
- Result/ok/err, START/END constants

Zero external dependencies (zod as peer only).
Zero node:fs/node:path imports.

Engine (@uncaged/workflow) now depends on workflow-runtime and
provides CAS/merkle/extract implementations via injection.

Refs #121, relates #122
- Verify createWorkflow in runtime has zero I/O imports
- Migrate agent-cursor, agent-hermes to pure workflow-runtime dependency
- Migrate agent-llm, util-agent, templates to dual dependency
  (runtime for types, engine for CAS/merkle/buildDescriptor)
- All 377 tests passing

Refs #121, relates #123 #124
- Remove all re-exports from @uncaged/workflow -> @uncaged/workflow-runtime
- Fix cli-workflow imports to use @uncaged/workflow-runtime for types
- Update bundle-validator to allow @uncaged/workflow-runtime imports
- Update init templates to reference @uncaged/workflow-runtime
- 378 tests passing, build + check clean

Refs #121, relates #125
xiaomo approved these changes 2026-05-08 06:42:11 +00:00
xiaomo left a comment
Owner

Review: split @uncaged/workflow-runtime from engine

分离做得很干净。核心要点:

做得好的

  • 依赖注入设计ResolveRoleMetaFn 作为注入点,runtime 定义契约,engine 提供实现,架构清晰
  • 零代码重复:runtime 是实际实现,engine 的 createWorkflow 是 thin wrapper
  • 文件夹模块纪律:新包 index.ts 纯 re-export,types 在 types.ts,符合规范
  • 所有 262 个测试通过,typecheck 通过

⚠️ 需注意

  1. Breaking change 文档@uncaged/workflow 不再 re-export 24 个 runtime 类型/值(START, END, AgentBinding 等)。内部消费者已全部更新,但外部用户需要迁移指引(changelog/release notes)
  2. Partial<Record<string, AgentFn>>(types.ts:121):Partial<> 产生 optional properties(?:),技术上违反 CLAUDE.md 约定。这是 pre-existing 的,且新代码实际上改善了处理方式,可后续跟进

💡 Nit

  • zod 作为 peerDep 是正确选择,"zero-dep" 指的是运行时依赖为零

Verdict: Approve — 拆分合理,测试完备,可以合并。

## Review: split @uncaged/workflow-runtime from engine ✅ 分离做得很干净。核心要点: ### ✅ 做得好的 - **依赖注入设计**:`ResolveRoleMetaFn` 作为注入点,runtime 定义契约,engine 提供实现,架构清晰 - **零代码重复**:runtime 是实际实现,engine 的 `createWorkflow` 是 thin wrapper - **文件夹模块纪律**:新包 index.ts 纯 re-export,types 在 types.ts,符合规范 - **所有 262 个测试通过,typecheck 通过** ### ⚠️ 需注意 1. **Breaking change 文档**:`@uncaged/workflow` 不再 re-export 24 个 runtime 类型/值(START, END, AgentBinding 等)。内部消费者已全部更新,但外部用户需要迁移指引(changelog/release notes) 2. **`Partial<Record<string, AgentFn>>`**(types.ts:121):`Partial<>` 产生 optional properties(`?:`),技术上违反 CLAUDE.md 约定。这是 pre-existing 的,且新代码实际上改善了处理方式,可后续跟进 ### 💡 Nit - `zod` 作为 peerDep 是正确选择,"zero-dep" 指的是运行时依赖为零 **Verdict: Approve** — 拆分合理,测试完备,可以合并。
xiaomo merged commit 46b552ec01 into main 2026-05-08 06:42:15 +00:00
Sign in to join this conversation.
No Reviewers
No Label
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: uncaged/workflow#126