refactor: align package folder names with npm package names #22

Merged
xiaomo merged 1 commits from refactor/align-package-folder-names into main 2026-06-02 15:54:12 +00:00
266 changed files with 207 additions and 207 deletions
+6 -6
View File
@@ -2,23 +2,23 @@
"mode": "exit", "mode": "exit",
"tag": "alpha", "tag": "alpha",
"initialVersions": { "initialVersions": {
"@uncaged/cli-workflow": "0.4.5", "@uncaged/cli": "0.4.5",
"@uncaged/workflow-agent-cursor": "0.4.5", "@uncaged/workflow-agent-cursor": "0.4.5",
"@uncaged/workflow-agent-hermes": "0.4.5", "@uncaged/agent-hermes": "0.4.5",
"@uncaged/workflow-agent-llm": "0.4.5", "@uncaged/workflow-agent-llm": "0.4.5",
"@uncaged/workflow-agent-react": "0.4.5", "@uncaged/workflow-agent-react": "0.4.5",
"@uncaged/workflow-cas": "0.4.5", "@uncaged/workflow-cas": "0.4.5",
"@uncaged/workflow-dashboard": "0.1.0", "@uncaged/dashboard": "0.1.0",
"@uncaged/workflow-execute": "0.4.5", "@uncaged/workflow-execute": "0.4.5",
"@uncaged/workflow-gateway": "0.4.5", "@uncaged/workflow-gateway": "0.4.5",
"@uncaged/workflow-protocol": "0.4.5", "@uncaged/protocol": "0.4.5",
"@uncaged/workflow-reactor": "0.4.5", "@uncaged/workflow-reactor": "0.4.5",
"@uncaged/workflow-register": "0.4.5", "@uncaged/workflow-register": "0.4.5",
"@uncaged/workflow-runtime": "0.4.5", "@uncaged/workflow-runtime": "0.4.5",
"@uncaged/workflow-template-develop": "0.4.5", "@uncaged/workflow-template-develop": "0.4.5",
"@uncaged/workflow-template-solve-issue": "0.4.5", "@uncaged/workflow-template-solve-issue": "0.4.5",
"@uncaged/workflow-util": "0.4.5", "@uncaged/util": "0.4.5",
"@uncaged/workflow-util-agent": "0.4.5" "@uncaged/util-agent": "0.4.5"
}, },
"changesets": [ "changesets": [
"env-api-unify", "env-api-unify",
+3 -3
View File
@@ -45,9 +45,9 @@ roles:
cd /root/workflow && bun install cd /root/workflow && bun install
# bun link each package that has a bin entry # bun link each package that has a bin entry
cd packages/cli-workflow && bun link && cd ../.. cd packages/cli && bun link && cd ../..
cd packages/workflow-agent-hermes && bun link && cd ../.. cd packages/agent-hermes && bun link && cd ../..
cd packages/workflow-agent-builtin && bun link && cd ../.. cd packages/agent-builtin && bun link && cd ../..
' '
``` ```
3. Verify all three commands are available inside the container: 3. Verify all three commands are available inside the container:
+9 -9
View File
@@ -16,7 +16,7 @@ This guide helps any AI agent set up `uwf` (Uncaged Workflow) from scratch — o
### 1. Install uwf CLI ### 1. Install uwf CLI
```bash ```bash
bun install -g @uncaged/cli-workflow bun install -g @uncaged/cli
``` ```
**Check:** `uwf --version` prints a version number (e.g. `0.5.1`). **Check:** `uwf --version` prints a version number (e.g. `0.5.1`).
@@ -27,11 +27,11 @@ Install the adapter that matches your agent runtime. Pick **one**:
| Agent | Package | Binary | | Agent | Package | Binary |
|-------|---------|--------| |-------|---------|--------|
| Hermes | `@uncaged/workflow-agent-hermes` | `uwf-hermes` | | Hermes | `@uncaged/agent-hermes` | `uwf-hermes` |
```bash ```bash
# Example: Hermes agent # Example: Hermes agent
bun install -g @uncaged/workflow-agent-hermes bun install -g @uncaged/agent-hermes
``` ```
**Check:** `uwf-hermes --version` prints a version number. **Check:** `uwf-hermes --version` prints a version number.
@@ -128,19 +128,19 @@ uwf-hermes --version # or your agent adapter
Compare with latest published versions: Compare with latest published versions:
```bash ```bash
bun pm ls -g | grep -E "cli-workflow|workflow-agent" bun pm ls -g | grep -E "cli|workflow-agent"
npm info @uncaged/cli-workflow version npm info @uncaged/cli version
npm info @uncaged/workflow-agent-hermes version npm info @uncaged/agent-hermes version
``` ```
If local version < published version, upgrade: If local version < published version, upgrade:
```bash ```bash
bun install -g @uncaged/cli-workflow@latest bun install -g @uncaged/cli@latest
bun install -g @uncaged/workflow-agent-hermes@latest bun install -g @uncaged/agent-hermes@latest
``` ```
**Check:** `uwf --version` matches `npm info @uncaged/cli-workflow version`. **Check:** `uwf --version` matches `npm info @uncaged/cli version`.
### Config Check ### Config Check
+10 -10
View File
@@ -21,14 +21,14 @@ This monorepo implements a stateless workflow engine driven by a single-step CLI
``` ```
workflow/ workflow/
packages/ packages/
workflow-protocol/ # @united-workforce/protocol — shared types (WorkflowPayload, StepNodePayload, WorkflowConfig, etc.) protocol/ # @united-workforce/protocol — shared types (WorkflowPayload, StepNodePayload, WorkflowConfig, etc.)
workflow-util/ # @united-workforce/util — Crockford Base32, ULID, logger, frontmatter parsing/validation util/ # @united-workforce/util — Crockford Base32, ULID, logger, frontmatter parsing/validation
workflow-util-agent/ # @united-workforce/util-agent — createAgent factory, context builder, extract pipeline util-agent/ # @united-workforce/util-agent — createAgent factory, context builder, extract pipeline
workflow-agent-hermes/ # @united-workforce/agent-hermes — uwf-hermes CLI binary (spawns hermes chat) agent-hermes/ # @united-workforce/agent-hermes — uwf-hermes CLI binary (spawns hermes chat)
workflow-agent-claude-code/ # @united-workforce/agent-claude-code — uwf-claude-code CLI binary agent-claude-code/ # @united-workforce/agent-claude-code — uwf-claude-code CLI binary
workflow-agent-builtin/ # @united-workforce/agent-builtin — uwf-builtin CLI binary agent-builtin/ # @united-workforce/agent-builtin — uwf-builtin CLI binary
cli-workflow/ # @united-workforce/cli — uwf CLI binary (includes status-based moderator in src/moderator/) cli/ # @united-workforce/cli — uwf CLI binary (includes status-based moderator in src/moderator/)
workflow-dashboard/ # @united-workforce/dashboard — web dashboard (private, not published) dashboard/ # @united-workforce/dashboard — web dashboard (private, not published)
legacy-packages/ # Archived packages (preserved for reference, not active) legacy-packages/ # Archived packages (preserved for reference, not active)
examples/ # Workflow YAML examples (solve-issue.yaml) examples/ # Workflow YAML examples (solve-issue.yaml)
docs/ # Architecture docs docs/ # Architecture docs
@@ -36,7 +36,7 @@ workflow/
tsconfig.json # root TypeScript config tsconfig.json # root TypeScript config
``` ```
- Dependency layers: `workflow-protocol``workflow-util``workflow-util-agent``workflow-agent-hermes` / `workflow-agent-claude-code` / `workflow-agent-builtin` / `cli-workflow` - Dependency layers: `protocol``util``util-agent``agent-hermes` / `agent-claude-code` / `agent-builtin` / `cli`
- Packages use `workspace:^` protocol (resolves to `^x.y.z` on publish) - Packages use `workspace:^` protocol (resolves to `^x.y.z` on publish)
- External CAS: `@ocas/core` (store API, hashing, schema validation) + `@ocas/fs` (filesystem backend) - External CAS: `@ocas/core` (store API, hashing, schema validation) + `@ocas/fs` (filesystem backend)
@@ -225,7 +225,7 @@ Test files (`__tests__/**`) are exempt.
| **bun** | Package manager + runtime | | **bun** | Package manager + runtime |
| **TypeScript** | Type checking (strict mode) | | **TypeScript** | Type checking (strict mode) |
| **Biome** | Lint + format (replaces ESLint + Prettier) | | **Biome** | Lint + format (replaces ESLint + Prettier) |
| **vitest** | Test runner (`cli-workflow` uses vitest; other packages use `bun test`) | | **vitest** | Test runner (`cli` uses vitest; other packages use `bun test`) |
### Development Workflow ### Development Workflow
+9 -9
View File
@@ -36,7 +36,7 @@ See [CLAUDE.md](CLAUDE.md) for the full coding standard. Key points:
- **Functional-first** — `function` + `type`, not `class` + `interface` - **Functional-first** — `function` + `type`, not `class` + `interface`
- **No optional properties** — use `T | null` instead of `?:` - **No optional properties** — use `T | null` instead of `?:`
- **Named exports only** — no default exports - **Named exports only** — no default exports
- **No `console.log`** — use the structured logger from `@uncaged/workflow-util` - **No `console.log`** — use the structured logger from `@uncaged/util`
- **Static imports only** — no `await import()` in production code - **Static imports only** — no `await import()` in production code
- **Biome** for lint + format — run `bun run check` before committing - **Biome** for lint + format — run `bun run check` before committing
@@ -92,14 +92,14 @@ This creates a markdown file in `.changeset/` describing the change. It will be
``` ```
packages/ packages/
workflow-protocol/ # Shared types and JSON Schema protocol/ # Shared types and JSON Schema
workflow-util/ # Encoding, IDs, logging, frontmatter util/ # Encoding, IDs, logging, frontmatter
workflow-util-agent/ # createAgent factory, extract pipeline util-agent/ # createAgent factory, extract pipeline
workflow-agent-hermes/ # Hermes ACP agent agent-hermes/ # Hermes ACP agent
workflow-agent-builtin/ # Built-in LLM agent agent-builtin/ # Built-in LLM agent
workflow-agent-claude-code/ # Claude Code agent agent-claude-code/ # Claude Code agent
cli-workflow/ # uwf CLI binary cli/ # uwf CLI binary
workflow-dashboard/ # Web UI (private, alpha) dashboard/ # Web UI (private, alpha)
``` ```
Dependency flows downward — lower layers have no dependency on higher layers. See [CLAUDE.md](CLAUDE.md) for the full architecture. Dependency flows downward — lower layers have no dependency on higher layers. See [CLAUDE.md](CLAUDE.md) for the full architecture.
+17 -17
View File
@@ -47,24 +47,24 @@ Dependency layers (lower layers have no dependency on higher layers):
``` ```
Layer 0 — Contract Layer 0 — Contract
workflow-protocol Shared types and JSON Schema definitions protocol Shared types and JSON Schema definitions
Layer 1 — Shared infra Layer 1 — Shared infra
workflow-util Encoding, IDs, logging, frontmatter, paths util Encoding, IDs, logging, frontmatter, paths
Layer 2 — Agent framework Layer 2 — Agent framework
workflow-util-agent createAgent factory, context builder, extract pipeline util-agent createAgent factory, context builder, extract pipeline
Layer 3 — Agent implementations Layer 3 — Agent implementations
workflow-agent-hermes Hermes ACP agent (uwf-hermes) agent-hermes Hermes ACP agent (uwf-hermes)
workflow-agent-builtin Built-in LLM + tools agent (uwf-builtin) agent-builtin Built-in LLM + tools agent (uwf-builtin)
workflow-agent-claude-code Claude Code agent (uwf-claude-code) agent-claude-code Claude Code agent (uwf-claude-code)
Layer 4 — CLI Layer 4 — CLI
cli-workflow uwf binary — thread lifecycle, registry, CAS, setup (includes status-based moderator) cli uwf binary — thread lifecycle, registry, CAS, setup (includes status-based moderator)
App (uses protocol; not in the runtime engine stack) App (uses protocol; not in the runtime engine stack)
workflow-dashboard Web UI for visual workflow editing dashboard Web UI for visual workflow editing
``` ```
External CAS: [`@ocas/core`](https://www.npmjs.com/package/@ocas/core) (store API, hashing, schema validation) + `@ocas/fs` (filesystem backend). External CAS: [`@ocas/core`](https://www.npmjs.com/package/@ocas/core) (store API, hashing, schema validation) + `@ocas/fs` (filesystem backend).
@@ -75,14 +75,14 @@ See [docs/architecture.md](docs/architecture.md) for the full design — three-p
| Package | npm | Description | Type | README | | Package | npm | Description | Type | README |
|---------|-----|-------------|------|--------| |---------|-----|-------------|------|--------|
| `cli-workflow` | `@united-workforce/cli` | `uwf` CLI — thread lifecycle, workflow registry, CAS inspection, setup | cli | [README](packages/cli-workflow/README.md) | | `cli` | `@united-workforce/cli` | `uwf` CLI — thread lifecycle, workflow registry, CAS inspection, setup | cli | [README](packages/cli/README.md) |
| `workflow-protocol` | `@united-workforce/protocol` | Shared TypeScript types and JSON Schema constants | lib | [README](packages/workflow-protocol/README.md) | | `protocol` | `@united-workforce/protocol` | Shared TypeScript types and JSON Schema constants | lib | [README](packages/protocol/README.md) |
| `workflow-util-agent` | `@united-workforce/util-agent` | `createAgent` factory, context builder, extract pipeline | lib | [README](packages/workflow-util-agent/README.md) | | `util-agent` | `@united-workforce/util-agent` | `createAgent` factory, context builder, extract pipeline | lib | [README](packages/util-agent/README.md) |
| `workflow-util` | `@united-workforce/util` | Crockford Base32, ULID, logger, frontmatter parsing, storage paths | lib | [README](packages/workflow-util/README.md) | | `util` | `@united-workforce/util` | Crockford Base32, ULID, logger, frontmatter parsing, storage paths | lib | [README](packages/util/README.md) |
| `workflow-agent-hermes` | `@united-workforce/agent-hermes` | `uwf-hermes` — spawns Hermes chat via ACP | agent | [README](packages/workflow-agent-hermes/README.md) | | `agent-hermes` | `@united-workforce/agent-hermes` | `uwf-hermes` — spawns Hermes chat via ACP | agent | [README](packages/agent-hermes/README.md) |
| `workflow-agent-builtin` | `@united-workforce/agent-builtin` | `uwf-builtin` — built-in LLM agent with file/shell tools | agent | [README](packages/workflow-agent-builtin/README.md) | | `agent-builtin` | `@united-workforce/agent-builtin` | `uwf-builtin` — built-in LLM agent with file/shell tools | agent | [README](packages/agent-builtin/README.md) |
| `workflow-agent-claude-code` | `@united-workforce/agent-claude-code` | `uwf-claude-code` — spawns Claude Code CLI | agent | [README](packages/workflow-agent-claude-code/README.md) | | `agent-claude-code` | `@united-workforce/agent-claude-code` | `uwf-claude-code` — spawns Claude Code CLI | agent | [README](packages/agent-claude-code/README.md) |
| `workflow-dashboard` | `@united-workforce/dashboard` | Web graph editor for workflow YAML (private, alpha) | app | [README](packages/workflow-dashboard/README.md) | | `dashboard` | `@united-workforce/dashboard` | Web graph editor for workflow YAML (private, alpha) | app | [README](packages/dashboard/README.md) |
## CLI Reference ## CLI Reference
@@ -100,7 +100,7 @@ Global options: `-V, --version`, `--format <json|yaml>`, `-h, --help`.
Config is stored in `~/.uwf/config.yaml`. API keys go in `~/.uwf/.env`. Config is stored in `~/.uwf/config.yaml`. API keys go in `~/.uwf/.env`.
Detailed command usage, options, and examples: [packages/cli-workflow/README.md](packages/cli-workflow/README.md). Detailed command usage, options, and examples: [packages/cli/README.md](packages/cli/README.md).
## Development ## Development
+13 -13
View File
@@ -14,11 +14,11 @@ The implementation lives in **5** active packages under `packages/`, plus two ex
| Layer | Package | One-line role | | Layer | Package | One-line role |
|-------|---------|---------------| |-------|---------|---------------|
| Contract | `@united-workforce/protocol``workflow-protocol` | Shared TypeScript types (`WorkflowPayload`, `StepNodePayload`, `ModeratorContext`, `WorkflowConfig`, etc.). No runtime deps beyond `@ocas/fs`. | | Contract | `@united-workforce/protocol``protocol` | Shared TypeScript types (`WorkflowPayload`, `StepNodePayload`, `ModeratorContext`, `WorkflowConfig`, etc.). No runtime deps beyond `@ocas/fs`. |
| Shared infra | `@united-workforce/util``workflow-util` | Crockford Base32, ULID generation, `createLogger`, frontmatter parsing/validation. | | Shared infra | `@united-workforce/util``util` | Crockford Base32, ULID generation, `createLogger`, frontmatter parsing/validation. |
| Agent framework | `@united-workforce/util-agent``workflow-util-agent` | `createAgent` entrypoint factory, context builder, frontmatter fast-path extractor, LLM extract fallback, output format instruction builder. | | Agent framework | `@united-workforce/util-agent``util-agent` | `createAgent` entrypoint factory, context builder, frontmatter fast-path extractor, LLM extract fallback, output format instruction builder. |
| Agent: Hermes | `@united-workforce/agent-hermes``workflow-agent-hermes` | `uwf-hermes` CLI binary — spawns `hermes chat`, pipes prompt, captures session detail. | | Agent: Hermes | `@united-workforce/agent-hermes``agent-hermes` | `uwf-hermes` CLI binary — spawns `hermes chat`, pipes prompt, captures session detail. |
| CLI | `@united-workforce/cli``cli-workflow` | `uwf` binary — thread lifecycle, workflow registry, CAS inspection, setup. Includes status-based graph evaluator in `src/moderator/` (next role or `$END`). | | CLI | `@united-workforce/cli``cli` | `uwf` binary — thread lifecycle, workflow registry, CAS inspection, setup. Includes status-based graph evaluator in `src/moderator/` (next role or `$END`). |
### External dependencies ### External dependencies
@@ -26,8 +26,8 @@ The implementation lives in **5** active packages under `packages/`, plus two ex
|---------|------| |---------|------|
| `@ocas/core` | Content-addressed store API, XXH64 hashing, JSON Schema registration and validation. | | `@ocas/core` | Content-addressed store API, XXH64 hashing, JSON Schema registration and validation. |
| `@ocas/fs` | Filesystem backend for `ocas`. | | `@ocas/fs` | Filesystem backend for `ocas`. |
| `mustache` | Template renderer for edge prompts (used by `cli-workflow` moderator). | | `mustache` | Template renderer for edge prompts (used by `cli` moderator). |
| `commander` | CLI argument parsing (used by `cli-workflow`). | | `commander` | CLI argument parsing (used by `cli`). |
| `dotenv` | Loads `.env` files for API keys. | | `dotenv` | Loads `.env` files for API keys. |
| `yaml` | YAML parse/stringify. | | `yaml` | YAML parse/stringify. |
@@ -150,7 +150,7 @@ Key properties:
## Three-phase engine loop ## Three-phase engine loop
Each `uwf thread step` runs exactly one cycle: moderator → agent → extract. The CLI orchestrates this in `packages/cli-workflow/src/commands/thread.ts` (`cmdThreadStep`). Each `uwf thread step` runs exactly one cycle: moderator → agent → extract. The CLI orchestrates this in `packages/cli/src/commands/thread.ts` (`cmdThreadStep`).
``` ```
┌─→ Phase 1: MODERATOR ┌─→ Phase 1: MODERATOR
@@ -176,7 +176,7 @@ Each `uwf thread step` runs exactly one cycle: moderator → agent → extract.
### Context types ### Context types
Defined in `packages/workflow-protocol/src/types.ts`: Defined in `packages/protocol/src/types.ts`:
```typescript ```typescript
type StepContext = { type StepContext = {
@@ -218,7 +218,7 @@ Each agent is an external command invoked by `uwf thread step`:
Contract: Contract:
1. `uwf thread step` determines the next role via the moderator 1. `uwf thread step` determines the next role via the moderator
2. Agent CLI is spawned with `(thread-id, role)` as positional args 2. Agent CLI is spawned with `(thread-id, role)` as positional args
3. `workflow-util-agent` (`createAgent`) handles the boilerplate: 3. `util-agent` (`createAgent`) handles the boilerplate:
- Parses argv - Parses argv
- Loads `.env` from storage root - Loads `.env` from storage root
- Builds `AgentContext` by walking the CAS chain from `threads.yaml` head - Builds `AgentContext` by walking the CAS chain from `threads.yaml` head
@@ -251,11 +251,11 @@ scope: role
Fixed the login redirect by updating the auth middleware... Fixed the login redirect by updating the auth middleware...
``` ```
The `outputFormatInstruction` (built by `buildOutputFormatInstruction` in `workflow-util-agent`) is prepended to the role's system prompt, so the deliverable format is the first thing the agent sees. It lists the expected frontmatter fields derived from the role's `meta` JSON Schema. The `outputFormatInstruction` (built by `buildOutputFormatInstruction` in `util-agent`) is prepended to the role's system prompt, so the deliverable format is the first thing the agent sees. It lists the expected frontmatter fields derived from the role's `meta` JSON Schema.
## Two-layer extract ## Two-layer extract
Structured output extraction uses a two-layer strategy (`workflow-util-agent`): Structured output extraction uses a two-layer strategy (`util-agent`):
### Layer 1: frontmatter fast path (`frontmatter.ts`) ### Layer 1: frontmatter fast path (`frontmatter.ts`)
@@ -279,7 +279,7 @@ If the fast path returns `null` (no frontmatter, invalid, or doesn't satisfy sch
## Prompt injection ## Prompt injection
`workflow-util-agent` prepends two pieces of context to the agent's system prompt: `util-agent` prepends two pieces of context to the agent's system prompt:
1. **Deliverable format instruction** — generated from the role's `meta` schema, tells the agent exactly what frontmatter fields to produce and the expected format 1. **Deliverable format instruction** — generated from the role's `meta` schema, tells the agent exactly what frontmatter fields to produce and the expected format
2. **Scope constraint** — "Focus exclusively on YOUR role's deliverable. Do not perform actions outside your role's scope." 2. **Scope constraint** — "Focus exclusively on YOUR role's deliverable. Do not perform actions outside your role's scope."
+30 -30
View File
@@ -14,7 +14,7 @@
现有 agent 是怎么被 CLI 调用的?输入(argv、环境变量)和输出(stdout、CAS)格式是什么? 现有 agent 是怎么被 CLI 调用的?输入(argv、环境变量)和输出(stdout、CAS)格式是什么?
**调研要点:** **调研要点:**
- `cli-workflow``spawnAgent` 的完整实现 - `cli``spawnAgent` 的完整实现
- AgentConfig 类型定义 - AgentConfig 类型定义
- agent 进程的 exit code 约定 - agent 进程的 exit code 约定
- 环境变量传递(UWF_STORAGE_ROOT 等) - 环境变量传递(UWF_STORAGE_ROOT 等)
@@ -27,7 +27,7 @@
#### AgentConfig 类型 #### AgentConfig 类型
```146:149:packages/workflow-protocol/src/types.ts ```146:149:packages/protocol/src/types.ts
export type AgentConfig = { export type AgentConfig = {
command: string; command: string;
args: string[]; args: string[];
@@ -38,7 +38,7 @@ export type AgentConfig = {
#### spawnAgent 行为 #### spawnAgent 行为
```627:653:packages/cli-workflow/src/commands/thread.ts ```627:653:packages/cli/src/commands/thread.ts
function spawnAgent(agent: AgentConfig, threadId: ThreadId, role: string): CasRef { function spawnAgent(agent: AgentConfig, threadId: ThreadId, role: string): CasRef {
const argv = [...agent.args, threadId, role]; const argv = [...agent.args, threadId, role];
let stdout: string; let stdout: string;
@@ -78,9 +78,9 @@ Agent 解析优先级(`resolveAgentConfig`):
#### 环境变量:Storage Root #### 环境变量:Storage Root
文档中写的 `UWF_STORAGE_ROOT` **在当前代码中不存在**。实际优先级(`workflow-util-agent` / `cli-workflow` 一致): 文档中写的 `UWF_STORAGE_ROOT` **在当前代码中不存在**。实际优先级(`util-agent` / `cli` 一致):
```33:43:packages/workflow-util-agent/src/storage.ts ```33:43:packages/util-agent/src/storage.ts
export function resolveStorageRoot(): string { export function resolveStorageRoot(): string {
const internal = process.env.UNCAGED_WORKFLOW_STORAGE_ROOT; const internal = process.env.UNCAGED_WORKFLOW_STORAGE_ROOT;
if (internal !== undefined && internal !== "") { if (internal !== undefined && internal !== "") {
@@ -107,7 +107,7 @@ Agent 子进程通过继承的 `process.env` 与父 CLI 共享同一 storage roo
### Q2: createAgent 工厂 ### Q2: createAgent 工厂
workflow-util-agent 的 `createAgent` 做了什么?它的完整生命周期是什么? util-agent 的 `createAgent` 做了什么?它的完整生命周期是什么?
**调研要点:** **调研要点:**
- `AgentOptions` 类型的 `run` 和 `continue` 回调签名 - `AgentOptions` 类型的 `run` 和 `continue` 回调签名
@@ -119,7 +119,7 @@ workflow-util-agent 的 `createAgent` 做了什么?它的完整生命周期是
#### 类型定义 #### 类型定义
```4:35:packages/workflow-util-agent/src/types.ts ```4:35:packages/util-agent/src/types.ts
export type AgentContext = ModeratorContext & { export type AgentContext = ModeratorContext & {
threadId: ThreadId; threadId: ThreadId;
role: string; role: string;
@@ -156,7 +156,7 @@ export type AgentOptions = {
#### 生命周期(按执行顺序) #### 生命周期(按执行顺序)
```101:152:packages/workflow-util-agent/src/run.ts ```101:152:packages/util-agent/src/run.ts
export function createAgent(options: AgentOptions): () => Promise<void> { export function createAgent(options: AgentOptions): () => Promise<void> {
return async function main(): Promise<void> { return async function main(): Promise<void> {
const { threadId, role } = parseArgv(process.argv); const { threadId, role } = parseArgv(process.argv);
@@ -197,7 +197,7 @@ export function createAgent(options: AgentOptions): () => Promise<void> {
#### StepNode 写入结构 #### StepNode 写入结构
```44:68:packages/workflow-util-agent/src/run.ts ```44:68:packages/util-agent/src/run.ts
async function writeStepNode(options: { async function writeStepNode(options: {
store: AgentStore["store"]; store: AgentStore["store"];
schemas: AgentStore["schemas"]; schemas: AgentStore["schemas"];
@@ -242,21 +242,21 @@ async function writeStepNode(options: {
继承 `ModeratorContext`: 继承 `ModeratorContext`:
```60:68:packages/workflow-protocol/src/types.ts ```60:68:packages/protocol/src/types.ts
export type ModeratorContext = { export type ModeratorContext = {
start: StartNodePayload; start: StartNodePayload;
steps: StepContext[]; steps: StepContext[];
}; };
``` ```
```48:51:packages/workflow-protocol/src/types.ts ```48:51:packages/protocol/src/types.ts
export type StartNodePayload = { export type StartNodePayload = {
workflow: CasRef; workflow: CasRef;
prompt: string; prompt: string;
}; };
``` ```
```61:63:packages/workflow-protocol/src/types.ts ```61:63:packages/protocol/src/types.ts
export type StepContext = Omit<StepRecord, "output"> & { export type StepContext = Omit<StepRecord, "output"> & {
output: unknown; output: unknown;
}; };
@@ -274,7 +274,7 @@ export type StepContext = Omit<StepRecord, "output"> & {
`buildContextWithMeta` 还返回 `meta`: `buildContextWithMeta` 还返回 `meta`:
```148:154:packages/workflow-util-agent/src/context.ts ```148:154:packages/util-agent/src/context.ts
export type BuildContextMeta = { export type BuildContextMeta = {
storageRoot: string; storageRoot: string;
store: Store; store: Store;
@@ -327,7 +327,7 @@ agent 输出怎么被处理成结构化数据?
Workflow YAML 中每个 role 的 `frontmatter:` 段是 JSON Schema 对象;注册时: Workflow YAML 中每个 role 的 `frontmatter:` 段是 JSON Schema 对象;注册时:
```66:76:packages/cli-workflow/src/commands/workflow.ts ```66:76:packages/cli/src/commands/workflow.ts
async function resolveFrontmatterRef(..., frontmatter: unknown): Promise<CasRef> { async function resolveFrontmatterRef(..., frontmatter: unknown): Promise<CasRef> {
// 校验为 JSON Schema → putSchema → 返回 CasRef // 校验为 JSON Schema → putSchema → 返回 CasRef
} }
@@ -337,7 +337,7 @@ async function resolveFrontmatterRef(..., frontmatter: unknown): Promise<CasRef>
#### Frontmatter fast-path(createAgent 实际使用的路径) #### Frontmatter fast-path(createAgent 实际使用的路径)
```148:195:packages/workflow-util-agent/src/frontmatter.ts ```148:195:packages/util-agent/src/frontmatter.ts
export async function tryFrontmatterFastPath( export async function tryFrontmatterFastPath(
raw: string, raw: string,
outputSchema: CasRef, outputSchema: CasRef,
@@ -357,7 +357,7 @@ export async function tryFrontmatterFastPath(
#### LLM extract fallback(已实现但未接入 createAgent) #### LLM extract fallback(已实现但未接入 createAgent)
```135:181:packages/workflow-util-agent/src/extract.ts ```135:181:packages/util-agent/src/extract.ts
export async function extract( export async function extract(
rawOutput: string, rawOutput: string,
outputSchema: CasRef, outputSchema: CasRef,
@@ -374,7 +374,7 @@ export async function extract(
#### Correction prompt(retry) #### Correction prompt(retry)
```125:128:packages/workflow-util-agent/src/run.ts ```125:128:packages/util-agent/src/run.ts
const correctionMessage = const correctionMessage =
"Your previous response did not contain valid YAML frontmatter matching the role schema.\n" + "Your previous response did not contain valid YAML frontmatter matching the role schema.\n" +
"You MUST begin your response with a YAML frontmatter block (--- delimited).\n" + "You MUST begin your response with a YAML frontmatter block (--- delimited).\n" +
@@ -399,7 +399,7 @@ workflow 怎么配置和使用 model?
#### WorkflowConfig #### WorkflowConfig
```136:160:packages/workflow-protocol/src/types.ts ```136:160:packages/protocol/src/types.ts
export type ProviderConfig = { export type ProviderConfig = {
baseUrl: string; baseUrl: string;
apiKey: string; apiKey: string;
@@ -425,7 +425,7 @@ export type WorkflowConfig = {
#### resolveModel #### resolveModel
```32:50:packages/workflow-util-agent/src/extract.ts ```32:50:packages/util-agent/src/extract.ts
export function resolveModel(config: WorkflowConfig, alias: ModelAlias): ResolvedLlmProvider { export function resolveModel(config: WorkflowConfig, alias: ModelAlias): ResolvedLlmProvider {
const modelEntry = config.models[alias]; const modelEntry = config.models[alias];
const providerEntry = config.providers[modelEntry.provider]; const providerEntry = config.providers[modelEntry.provider];
@@ -438,7 +438,7 @@ export function resolveModel(config: WorkflowConfig, alias: ModelAlias): Resolve
Extract 专用别名解析: Extract 专用别名解析:
```18:30:packages/workflow-util-agent/src/extract.ts ```18:30:packages/util-agent/src/extract.ts
export function resolveExtractModelAlias(config: WorkflowConfig): ModelAlias { export function resolveExtractModelAlias(config: WorkflowConfig): ModelAlias {
return config.modelOverrides?.extract ?? (config.models.extract ? "extract" : config.models.default ? "default" : config.defaultModel); return config.modelOverrides?.extract ?? (config.models.extract ? "extract" : config.models.default ? "default" : config.defaultModel);
} }
@@ -448,7 +448,7 @@ export function resolveExtractModelAlias(config: WorkflowConfig): ModelAlias {
#### chatCompletionText #### chatCompletionText
```87:124:packages/workflow-util-agent/src/extract.ts ```87:124:packages/util-agent/src/extract.ts
async function chatCompletionText( async function chatCompletionText(
provider: ResolvedLlmProvider, provider: ResolvedLlmProvider,
messages: Array<{ role: "system" | "user"; content: string }>, messages: Array<{ role: "system" | "user"; content: string }>,
@@ -463,7 +463,7 @@ async function chatCompletionText(
| 多模态 | **无**(仅 text `content`) | | 多模态 | **无**(仅 text `content`) |
| Extract 专用 | `response_format: { type: "json_object" }` | | Extract 专用 | `response_format: { type: "json_object" }` |
builtin agent 的 run loop 需要**新写**带 `tools` 的 completion 客户端(可放在 `workflow-agent-builtin` 或扩展 `workflow-util-agent` 的 `llm/` 模块),不能复用当前 `chatCompletionText` 而不改。 builtin agent 的 run loop 需要**新写**带 `tools` 的 completion 客户端(可放在 `agent-builtin` 或扩展 `util-agent` 的 `llm/` 模块),不能复用当前 `chatCompletionText` 而不改。
--- ---
@@ -481,7 +481,7 @@ builtin agent 的 run loop 需要**新写**带 `tools` 的 completion 客户端
#### Prompt 组装 #### Prompt 组装
```40:53:packages/workflow-agent-hermes/src/hermes.ts ```40:53:packages/agent-hermes/src/hermes.ts
export function buildHermesPrompt(ctx: AgentContext): string { export function buildHermesPrompt(ctx: AgentContext): string {
const roleDef = ctx.workflow.roles[ctx.role]; const roleDef = ctx.workflow.roles[ctx.role];
const rolePrompt = roleDef !== undefined ? buildRolePrompt(roleDef) : ""; const rolePrompt = roleDef !== undefined ? buildRolePrompt(roleDef) : "";
@@ -508,13 +508,13 @@ Hermes 把**整段 prompt 作为单条 user 消息**传给 `hermes chat -q`(
首次: 首次:
```88:97:packages/workflow-agent-hermes/src/hermes.ts ```88:97:packages/agent-hermes/src/hermes.ts
spawnHermes(["chat", "-q", prompt, "--yolo", "--max-turns", "90", "--quiet"]); spawnHermes(["chat", "-q", prompt, "--yolo", "--max-turns", "90", "--quiet"]);
``` ```
续聊: 续聊:
```100:114:packages/workflow-agent-hermes/src/hermes.ts ```100:114:packages/agent-hermes/src/hermes.ts
spawnHermes(["chat", "--resume", sessionId, "-q", message, "--yolo", "--max-turns", "90", "--quiet"]); spawnHermes(["chat", "--resume", sessionId, "-q", message, "--yolo", "--max-turns", "90", "--quiet"]);
``` ```
@@ -526,7 +526,7 @@ spawnHermes(["chat", "--resume", sessionId, "-q", message, "--yolo", "--max-turn
#### 与 createAgent 的衔接 #### 与 createAgent 的衔接
```157:164:packages/workflow-agent-hermes/src/hermes.ts ```157:164:packages/agent-hermes/src/hermes.ts
export function createHermesAgent(): () => Promise<void> { export function createHermesAgent(): () => Promise<void> {
return createAgent({ name: "hermes", run: runHermes, continue: continueHermes }); return createAgent({ name: "hermes", run: runHermes, continue: continueHermes });
} }
@@ -534,7 +534,7 @@ export function createHermesAgent(): () => Promise<void> {
`uwf-hermes` 入口:`createHermesAgent()` 即 main。 `uwf-hermes` 入口:`createHermesAgent()` 即 main。
Claude Code 包(`workflow-agent-claude-code`)结构相同:`buildClaudeCodePrompt` 同构,`claude -p` + `--resume` + JSON stdout 解析。 Claude Code 包(`agent-claude-code`)结构相同:`buildClaudeCodePrompt` 同构,`claude -p` + `--resume` + JSON stdout 解析。
--- ---
@@ -591,7 +591,7 @@ Hermes 自带完整 agent runtime(`--yolo`、max-turns),tool 集由 Hermes
```mermaid ```mermaid
flowchart TB flowchart TB
subgraph cli ["cli-workflow"] subgraph cli ["cli"]
Step["uwf thread step"] Step["uwf thread step"]
Spawn["spawnAgent(uwf-builtin, threadId, role)"] Spawn["spawnAgent(uwf-builtin, threadId, role)"]
Step --> Spawn Step --> Spawn
@@ -609,7 +609,7 @@ flowchart TB
Loop --> Detail Loop --> Detail
end end
subgraph kit ["workflow-util-agent"] subgraph kit ["util-agent"]
Ctx["buildContextWithMeta"] Ctx["buildContextWithMeta"]
FM["tryFrontmatterFastPath"] FM["tryFrontmatterFastPath"]
Persist["persistStep"] Persist["persistStep"]
@@ -630,7 +630,7 @@ flowchart TB
Spawn -->|"stdout: step hash"| Step Spawn -->|"stdout: step hash"| Step
``` ```
**新包**:`packages/workflow-agent-builtin`,bin `uwf-builtin`,仅依赖 `workflow-util-agent`、`workflow-protocol`、`workflow-util`(可选 `@ocas/core` 写 detail schema)。 **新包**:`packages/agent-builtin`,bin `uwf-builtin`,仅依赖 `util-agent`、`protocol`、`util`(可选 `@ocas/core` 写 detail schema)。
**分层**: **分层**:
+7 -7
View File
@@ -43,7 +43,7 @@ Export from `packages/workflow/src/index.ts`.
**Objective:** CLI `cas get/put/list/rm` no longer needs threadId for storage location — CAS is global. But keep threadId in CLI for backward compat of planner/coder prompts (they pass threadId). **Objective:** CLI `cas get/put/list/rm` no longer needs threadId for storage location — CAS is global. But keep threadId in CLI for backward compat of planner/coder prompts (they pass threadId).
**Files:** **Files:**
- Modify: `packages/cli-workflow/src/cmd-cas.ts` - Modify: `packages/cli/src/cmd-cas.ts`
**Changes:** **Changes:**
- `resolveCasDir` → use `getGlobalCasDir(storageRoot)` instead of deriving from thread data path - `resolveCasDir` → use `getGlobalCasDir(storageRoot)` instead of deriving from thread data path
@@ -73,7 +73,7 @@ export async function cmdCasGet(
**Objective:** Since CAS is global, `thread rm` should NOT delete CAS entries. CAS cleanup is GC's job. **Objective:** Since CAS is global, `thread rm` should NOT delete CAS entries. CAS cleanup is GC's job.
**Files:** **Files:**
- Modify: `packages/cli-workflow/src/cmd-thread.ts` - Modify: `packages/cli/src/cmd-thread.ts`
- Check: remove any `rmdir` / `unlink` of `<threadId>.cas/` directory - Check: remove any `rmdir` / `unlink` of `<threadId>.cas/` directory
### Task 1.4: Rename `createThreadCas` → `createCasStore` ### Task 1.4: Rename `createThreadCas` → `createCasStore`
@@ -90,7 +90,7 @@ export async function cmdCasGet(
**Objective:** All CAS-related tests use global dir instead of thread-local. **Objective:** All CAS-related tests use global dir instead of thread-local.
**Files:** **Files:**
- Modify: `packages/cli-workflow/__tests__/commands.test.ts` - Modify: `packages/cli/__tests__/commands.test.ts`
- Verify: `bun test` passes - Verify: `bun test` passes
### Task 1.6: Clean up old thread-local `.cas/` references ### Task 1.6: Clean up old thread-local `.cas/` references
@@ -208,18 +208,18 @@ export async function garbageCollectCas(storageRoot: string): Promise<GcResult>
### Task 3.2: Add `uncaged-workflow gc` CLI command ### Task 3.2: Add `uncaged-workflow gc` CLI command
**Files:** **Files:**
- Create: `packages/cli-workflow/src/cmd-gc.ts` - Create: `packages/cli/src/cmd-gc.ts`
- Modify: `packages/cli-workflow/src/cli-dispatch.ts` — add `gc` subcommand - Modify: `packages/cli/src/cli-dispatch.ts` — add `gc` subcommand
### Task 3.3: Run GC on `thread rm` ### Task 3.3: Run GC on `thread rm`
**Files:** **Files:**
- Modify: `packages/cli-workflow/src/cmd-thread.ts` — after deleting thread data, optionally run GC - Modify: `packages/cli/src/cmd-thread.ts` — after deleting thread data, optionally run GC
### Task 3.4: Tests for GC ### Task 3.4: Tests for GC
**Files:** **Files:**
- Create: `packages/cli-workflow/__tests__/gc-cli.test.ts` - Create: `packages/cli/__tests__/gc-cli.test.ts`
--- ---
+3 -3
View File
@@ -253,10 +253,10 @@ Breaking change. Old `.data.jsonl` files become incompatible. No backward compat
| Package | Changes | | Package | Changes |
|---------|---------| |---------|---------|
| `workflow-protocol` | Replace `StartStep`, `RoleStep` types with `StartNode`, `StateNode`. Add `ContentMerkleNode` type. Expand `ExtractResult` to include `refs[]`. | | `protocol` | Replace `StartStep`, `RoleStep` types with `StartNode`, `StateNode`. Add `ContentMerkleNode` type. Expand `ExtractResult` to include `refs[]`. |
| `workflow-cas` | Add `findReachableHashes(roots)` for GC mark phase | | `workflow-cas` | Add `findReachableHashes(roots)` for GC mark phase |
| `workflow-execute` | Rewrite engine to write CAS nodes + update `threads.json` instead of appending JSONL. Move completed threads to `history/`. Simplify `gc.ts`. Simplify `fork-thread.ts`. Expand extract phase to produce refs. | | `workflow-execute` | Rewrite engine to write CAS nodes + update `threads.json` instead of appending JSONL. Move completed threads to `history/`. Simplify `gc.ts`. Simplify `fork-thread.ts`. Expand extract phase to produce refs. |
| `workflow-runtime` | `ThreadContext` built by walking chain from head. `start.prompt` resolved from CAS via StartNode.refs[0]. | | `workflow-runtime` | `ThreadContext` built by walking chain from head. `start.prompt` resolved from CAS via StartNode.refs[0]. |
| `cli-workflow` | `thread list/show/rm` read from `threads.json` + `history/`. SSE watches `threads.json`. | | `cli` | `thread list/show/rm` read from `threads.json` + `history/`. SSE watches `threads.json`. |
| `workflow-dashboard` | Watch `threads.json` instead of `.data.jsonl` | | `dashboard` | Watch `threads.json` instead of `.data.jsonl` |
| Templates & Agents | Update extract definitions to produce `refs[]`. Update `ctx.start.content` → CAS resolved. | | Templates & Agents | Update extract definitions to produce `refs[]`. Update `ctx.start.content` → CAS resolved. |
+1 -1
View File
@@ -145,7 +145,7 @@ STATE_D1(父 developer state)
### Phase 1: Protocol + CAS 层 ### Phase 1: Protocol + CAS 层
1. `workflow-protocol/src/cas-types.ts``StartNodePayload``parentState: string | null``StateNodePayload``childThread: string | null` 1. `protocol/src/cas-types.ts``StartNodePayload``parentState: string | null``StateNodePayload``childThread: string | null`
2. `workflow-cas/src/nodes.ts``putStartNode` 接受可选 `parentStateHash`,放入 refs;`putStateNode` 接受可选 `childThreadHash`,放入 refs 2. `workflow-cas/src/nodes.ts``putStartNode` 接受可选 `parentStateHash`,放入 refs;`putStateNode` 接受可选 `childThreadHash`,放入 refs
3. `workflow-cas/src/nodes.ts` — 解析逻辑兼容新字段(缺失时视为 null) 3. `workflow-cas/src/nodes.ts` — 解析逻辑兼容新字段(缺失时视为 null)
@@ -154,7 +154,7 @@ function getNodeStates(records: ThreadRecord[]): Map<string, "completed" | "acti
## 组件结构 ## 组件结构
``` ```
workflow-dashboard/src/ dashboard/src/
components/ components/
workflow-graph/ workflow-graph/
types.ts — NodeState 等前端类型 types.ts — NodeState 等前端类型
+7 -7
View File
@@ -9,7 +9,7 @@
| Package | 机制 | 能力 | | Package | 机制 | 能力 |
|---------|------|------| |---------|------|------|
| `workflow-agent-hermes` | spawn `hermes chat` | 完整工具链(文件、终端、浏览器…) | | `agent-hermes` | spawn `hermes chat` | 完整工具链(文件、终端、浏览器…) |
| `workflow-agent-cursor` | spawn `cursor-agent` | IDE 级别代码编辑 | | `workflow-agent-cursor` | spawn `cursor-agent` | IDE 级别代码编辑 |
| `workflow-agent-llm` | 单轮 chat completion | 纯文本,无工具 | | `workflow-agent-llm` | 单轮 chat completion | 纯文本,无工具 |
@@ -77,7 +77,7 @@ AdapterFn 的终止条件是"拿到符合 schema 的 T"——和 `workflow-react
```typescript ```typescript
import { createLlmFn, createThreadReactor } from "@uncaged/workflow-reactor"; import { createLlmFn, createThreadReactor } from "@uncaged/workflow-reactor";
import type { ThreadContext, LlmProvider } from "@uncaged/workflow-protocol"; import type { ThreadContext, LlmProvider } from "@uncaged/protocol";
import type { ToolDefinition } from "@uncaged/workflow-reactor"; import type { ToolDefinition } from "@uncaged/workflow-reactor";
type ReactToolHandler = (name: string, args: string) => Promise<string>; type ReactToolHandler = (name: string, args: string) => Promise<string>;
@@ -147,7 +147,7 @@ packages/workflow-agent-react/
``` ```
依赖: 依赖:
- `@uncaged/workflow-protocol``ThreadContext`, `LlmProvider` - `@uncaged/protocol``ThreadContext`, `LlmProvider`
- `@uncaged/workflow-reactor``createLlmFn`, `createThreadReactor`, types - `@uncaged/workflow-reactor``createLlmFn`, `createThreadReactor`, types
## 影响范围 ## 影响范围
@@ -162,16 +162,16 @@ packages/workflow-agent-react/
### 需修改的包 ### 需修改的包
1. `workflow-protocol` — 删除 `AgentContext`/`AgentFn`/`AgentFnResult`/`AgentBinding`,新增 `AdapterFn`/`RoleFn`/`AdapterBinding` 1. `protocol` — 删除 `AgentContext`/`AgentFn`/`AgentFnResult`/`AgentBinding`,新增 `AdapterFn`/`RoleFn`/`AdapterBinding`
2. `workflow-runtime` — 更新 re-export 2. `workflow-runtime` — 更新 re-export
3. `workflow-execute` — engine 调用 `adapter(prompt, schema)` 替代 `agent(ctx) + extract` 3. `workflow-execute` — engine 调用 `adapter(prompt, schema)` 替代 `agent(ctx) + extract`
4. `workflow-util-agent``buildAgentPrompt``buildThreadInput`,接收 `ThreadContext` 4. `util-agent``buildAgentPrompt``buildThreadInput`,接收 `ThreadContext`
5. 所有 bundle-entry — `agent:``adapter:` 5. 所有 bundle-entry — `agent:``adapter:`
### 不受影响 ### 不受影响
- `workflow-cas` / `workflow-register` / `workflow-reactor` / `workflow-dashboard` - `workflow-cas` / `workflow-register` / `workflow-reactor` / `dashboard`
- `workflow-agent-hermes` / `workflow-agent-cursor`(内部不改,外部用 `agentToAdapter` 包装) - `agent-hermes` / `workflow-agent-cursor`(内部不改,外部用 `agentToAdapter` 包装)
## Phases ## Phases
@@ -96,7 +96,7 @@
"zod": "^4.0.0" "zod": "^4.0.0"
}, },
"devDependencies": { "devDependencies": {
"@uncaged/workflow-protocol": "workspace:^" "@uncaged/protocol": "workspace:^"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
@@ -116,7 +116,7 @@
}, },
"include": ["src/**/*.ts"], "include": ["src/**/*.ts"],
"references": [ "references": [
{ "path": "../workflow-protocol" }, { "path": "../protocol" },
{ "path": "../workflow-runtime" }, { "path": "../workflow-runtime" },
{ "path": "../workflow-register" } { "path": "../workflow-register" }
] ]
@@ -160,7 +160,7 @@ export {};
```typescript ```typescript
// __tests__/document-template.test.ts // __tests__/document-template.test.ts
import { describe, expect, test } from "bun:test"; import { describe, expect, test } from "bun:test";
import { tableToModerator } from "@uncaged/workflow-protocol/moderator-table.js"; import { tableToModerator } from "@uncaged/protocol/moderator-table.js";
import { validateWorkflowDescriptor } from "@uncaged/workflow-register"; import { validateWorkflowDescriptor } from "@uncaged/workflow-register";
import { END, type ModeratorContext, type RoleStep, START } from "@uncaged/workflow-runtime"; import { END, type ModeratorContext, type RoleStep, START } from "@uncaged/workflow-runtime";
import { buildDocumentDescriptor } from "../src/descriptor.js"; import { buildDocumentDescriptor } from "../src/descriptor.js";
@@ -497,8 +497,8 @@ git commit -m "feat(template): add workflow-template-document with writer/differ
}, },
"dependencies": { "dependencies": {
"@uncaged/workflow-runtime": "workspace:^", "@uncaged/workflow-runtime": "workspace:^",
"@uncaged/workflow-util": "workspace:^", "@uncaged/util": "workspace:^",
"@uncaged/workflow-util-agent": "workspace:^" "@uncaged/util-agent": "workspace:^"
}, },
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
@@ -518,10 +518,10 @@ git commit -m "feat(template): add workflow-template-document with writer/differ
}, },
"include": ["src/**/*.ts"], "include": ["src/**/*.ts"],
"references": [ "references": [
{ "path": "../workflow-protocol" }, { "path": "../protocol" },
{ "path": "../workflow-runtime" }, { "path": "../workflow-runtime" },
{ "path": "../workflow-util" }, { "path": "../util" },
{ "path": "../workflow-util-agent" } { "path": "../util-agent" }
] ]
} }
``` ```
@@ -555,11 +555,11 @@ import { mkdirSync, writeFileSync } from "node:fs";
import { join } from "node:path"; import { join } from "node:path";
import { tmpdir } from "node:os"; import { tmpdir } from "node:os";
import { describe, expect, mock, test } from "bun:test"; import { describe, expect, mock, test } from "bun:test";
import { ok, err } from "@uncaged/workflow-util"; import { ok, err } from "@uncaged/util";
import type { SpawnCliConfig } from "@uncaged/workflow-util-agent"; import type { SpawnCliConfig } from "@uncaged/util-agent";
import { editDocument, generateDocument } from "../src/runner.js"; import { editDocument, generateDocument } from "../src/runner.js";
type MockSpawnResult = Awaited<ReturnType<typeof import("@uncaged/workflow-util-agent").spawnCli>>; type MockSpawnResult = Awaited<ReturnType<typeof import("@uncaged/util-agent").spawnCli>>;
function makeSpawn(result: MockSpawnResult) { function makeSpawn(result: MockSpawnResult) {
return mock(async (_cmd: string, _args: string[], _opts: SpawnCliConfig) => result); return mock(async (_cmd: string, _args: string[], _opts: SpawnCliConfig) => result);
@@ -705,7 +705,7 @@ export type OfficeAgentConfig = {
```typescript ```typescript
import { copyFile, mkdir, stat } from "node:fs/promises"; import { copyFile, mkdir, stat } from "node:fs/promises";
import { join } from "node:path"; import { join } from "node:path";
import { spawnCli } from "@uncaged/workflow-util-agent"; import { spawnCli } from "@uncaged/util-agent";
import type { OfficeAgentConfig } from "./types.js"; import type { OfficeAgentConfig } from "./types.js";
type SpawnCliFn = typeof spawnCli; type SpawnCliFn = typeof spawnCli;
@@ -769,9 +769,9 @@ export async function editDocument(
} }
``` ```
> **注意**:`throwSpawnError` 的参数类型可以简化为 `import type { SpawnCliError } from "@uncaged/workflow-util-agent"` 直接 import,避免复杂类型推导。把 `throwSpawnError` 的签名改成: > **注意**:`throwSpawnError` 的参数类型可以简化为 `import type { SpawnCliError } from "@uncaged/util-agent"` 直接 import,避免复杂类型推导。把 `throwSpawnError` 的签名改成:
> ```typescript > ```typescript
> import type { SpawnCliError } from "@uncaged/workflow-util-agent"; > import type { SpawnCliError } from "@uncaged/util-agent";
> function throwSpawnError(e: SpawnCliError): never { ... } > function throwSpawnError(e: SpawnCliError): never { ... }
> ``` > ```
@@ -839,7 +839,7 @@ Expected:`Cannot find module '../src/agent.js'`
import * as z from "zod/v4"; import * as z from "zod/v4";
import { join } from "node:path"; import { join } from "node:path";
import type { AdapterFn, RoleResult, ThreadContext, WorkflowRuntime } from "@uncaged/workflow-runtime"; import type { AdapterFn, RoleResult, ThreadContext, WorkflowRuntime } from "@uncaged/workflow-runtime";
import { createLogger } from "@uncaged/workflow-util"; import { createLogger } from "@uncaged/util";
import { editDocument, generateDocument } from "./runner.js"; import { editDocument, generateDocument } from "./runner.js";
import type { OfficeAgentConfig } from "./types.js"; import type { OfficeAgentConfig } from "./types.js";
@@ -976,7 +976,7 @@ git commit -m "feat(agent): add workflow-agent-office with generate/edit Adapter
}, },
"dependencies": { "dependencies": {
"@uncaged/workflow-runtime": "workspace:^", "@uncaged/workflow-runtime": "workspace:^",
"@uncaged/workflow-util-agent": "workspace:^", "@uncaged/util-agent": "workspace:^",
"@uncaged/workflow-template-document": "workspace:^" "@uncaged/workflow-template-document": "workspace:^"
}, },
"publishConfig": { "publishConfig": {
@@ -997,9 +997,9 @@ git commit -m "feat(agent): add workflow-agent-office with generate/edit Adapter
}, },
"include": ["src/**/*.ts"], "include": ["src/**/*.ts"],
"references": [ "references": [
{ "path": "../workflow-protocol" }, { "path": "../protocol" },
{ "path": "../workflow-runtime" }, { "path": "../workflow-runtime" },
{ "path": "../workflow-util-agent" }, { "path": "../util-agent" },
{ "path": "../workflow-template-document" } { "path": "../workflow-template-document" }
] ]
} }
@@ -1034,11 +1034,11 @@ import { mkdirSync, writeFileSync } from "node:fs";
import { join } from "node:path"; import { join } from "node:path";
import { tmpdir } from "node:os"; import { tmpdir } from "node:os";
import { describe, expect, mock, test } from "bun:test"; import { describe, expect, mock, test } from "bun:test";
import { ok, err } from "@uncaged/workflow-util"; import { ok, err } from "@uncaged/util";
import type { SpawnCliConfig } from "@uncaged/workflow-util-agent"; import type { SpawnCliConfig } from "@uncaged/util-agent";
import { runDocxDiff } from "../src/runner.js"; import { runDocxDiff } from "../src/runner.js";
type MockSpawnResult = Awaited<ReturnType<typeof import("@uncaged/workflow-util-agent").spawnCli>>; type MockSpawnResult = Awaited<ReturnType<typeof import("@uncaged/util-agent").spawnCli>>;
function makeSpawn(result: MockSpawnResult) { function makeSpawn(result: MockSpawnResult) {
return mock(async (_cmd: string, _args: string[], _opts: SpawnCliConfig) => result); return mock(async (_cmd: string, _args: string[], _opts: SpawnCliConfig) => result);
@@ -1165,8 +1165,8 @@ export type DocxDiffAgentConfig = {
```typescript ```typescript
import { stat } from "node:fs/promises"; import { stat } from "node:fs/promises";
import { spawnCli } from "@uncaged/workflow-util-agent"; import { spawnCli } from "@uncaged/util-agent";
import type { SpawnCliError } from "@uncaged/workflow-util-agent"; import type { SpawnCliError } from "@uncaged/util-agent";
import type { DocxDiffAgentConfig } from "./types.js"; import type { DocxDiffAgentConfig } from "./types.js";
type SpawnCliFn = typeof spawnCli; type SpawnCliFn = typeof spawnCli;
@@ -1365,7 +1365,7 @@ git commit -m "feat(agent): add workflow-agent-docx-diff with docx-diff AdapterF
- [ ] **Step 1:在 architecture.md 的 Package map 表格中补充三个包** - [ ] **Step 1:在 architecture.md 的 Package map 表格中补充三个包**
`Agent adapters` 分组下(`workflow-agent-hermes` 行之后)追加: `Agent adapters` 分组下(`agent-hermes` 行之后)追加:
```markdown ```markdown
| | `@uncaged/workflow-agent-office``workflow-agent-office` | `AdapterFn` via `office-agent` CLI; generates or edits Word documents, stores outputs per threadId. | | | `@uncaged/workflow-agent-office``workflow-agent-office` | `AdapterFn` via `office-agent` CLI; generates or edits Word documents, stores outputs per threadId. |
@@ -107,7 +107,7 @@ packages/workflow-template-document/
```json ```json
{ {
"@uncaged/workflow-protocol": "workspace:^", "@uncaged/protocol": "workspace:^",
"@uncaged/workflow-runtime": "workspace:^", "@uncaged/workflow-runtime": "workspace:^",
"@uncaged/workflow-register": "workspace:^", "@uncaged/workflow-register": "workspace:^",
"zod": "^4.0.0" "zod": "^4.0.0"
@@ -246,9 +246,9 @@ packages/workflow-agent-office/
```json ```json
{ {
"@uncaged/workflow-protocol": "workspace:^", "@uncaged/protocol": "workspace:^",
"@uncaged/workflow-util": "workspace:^", "@uncaged/util": "workspace:^",
"@uncaged/workflow-util-agent": "workspace:^" "@uncaged/util-agent": "workspace:^"
} }
``` ```
@@ -347,8 +347,8 @@ packages/workflow-agent-docx-diff/
```json ```json
{ {
"@uncaged/workflow-protocol": "workspace:^", "@uncaged/protocol": "workspace:^",
"@uncaged/workflow-util-agent": "workspace:^", "@uncaged/util-agent": "workspace:^",
"@uncaged/workflow-template-document": "workspace:^" "@uncaged/workflow-template-document": "workspace:^"
} }
``` ```
@@ -365,7 +365,7 @@ import {
documentWorkflowDefinition, documentWorkflowDefinition,
} from "@uncaged/workflow-template-document"; } from "@uncaged/workflow-template-document";
import { createWorkflow } from "@uncaged/workflow-runtime"; import { createWorkflow } from "@uncaged/workflow-runtime";
import { getDefaultWorkflowStorageRoot } from "@uncaged/workflow-util"; import { getDefaultWorkflowStorageRoot } from "@uncaged/util";
import { join } from "node:path"; import { join } from "node:path";
const outputDir = join(getDefaultWorkflowStorageRoot(), "outputs"); const outputDir = join(getDefaultWorkflowStorageRoot(), "outputs");
+1 -1
View File
@@ -16,7 +16,7 @@ The root README should have these sections in order:
3. **Architecture** — dependency layer diagram (text-based) 3. **Architecture** — dependency layer diagram (text-based)
4. **Packages** — table with ALL packages from packages/ directory, columns: Package, Description, Type (cli/lib/agent/app) 4. **Packages** — table with ALL packages from packages/ directory, columns: Package, Description, Type (cli/lib/agent/app)
5. **Quick Start** — install, build, register workflow, start thread, run step 5. **Quick Start** — install, build, register workflow, start thread, run step
6. **CLI Reference** — brief command list, detailed usage in cli-workflow README 6. **CLI Reference** — brief command list, detailed usage in cli README
7. **Development** — bun install / build / check / test 7. **Development** — bun install / build / check / test
## Per-Package README Structure ## Per-Package README Structure
+4 -4
View File
@@ -341,11 +341,11 @@ OPENROUTER_API_KEY=sk-or-...
``` ```
packages/ packages/
├── cli-workflow/ # @united-workforce/cli — uwf CLI(thread/workflow 命令,含 src/moderator/) ├── cli/ # @united-workforce/cli — uwf CLI(thread/workflow 命令,含 src/moderator/)
├── workflow-util-agent/ # @united-workforce/util-agent — Agent CLI 框架(含 extractor) ├── util-agent/ # @united-workforce/util-agent — Agent CLI 框架(含 extractor)
├── workflow-agent-hermes/ # @united-workforce/agent-hermes — uwf-hermes CLI ├── agent-hermes/ # @united-workforce/agent-hermes — uwf-hermes CLI
├── workflow-agent-cursor/ # @united-workforce/agent-cursor — uwf-cursor CLI ├── workflow-agent-cursor/ # @united-workforce/agent-cursor — uwf-cursor CLI
└── workflow-protocol/ # @united-workforce/protocol — 共享类型定义 └── protocol/ # @united-workforce/protocol — 共享类型定义
``` ```
**外部依赖:** **外部依赖:**
+1 -1
View File
@@ -6,7 +6,7 @@
"packages/*" "packages/*"
], ],
"scripts": { "scripts": {
"uwf": "bun packages/cli-workflow/src/cli.ts", "uwf": "bun packages/cli/src/cli.ts",
"preinstall": "npx only-allow bun", "preinstall": "npx only-allow bun",
"prepublishOnly": "echo 'Use bun run release instead' && exit 1", "prepublishOnly": "echo 'Use bun run release instead' && exit 1",
"build": "bunx tsc --build", "build": "bunx tsc --build",
@@ -36,7 +36,7 @@
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://git.shazhou.work/uncaged/workflow.git", "url": "https://git.shazhou.work/uncaged/workflow.git",
"directory": "packages/workflow-agent-builtin" "directory": "packages/agent-builtin"
}, },
"homepage": "https://git.shazhou.work/uncaged/workflow#readme", "homepage": "https://git.shazhou.work/uncaged/workflow#readme",
"bugs": { "bugs": {
@@ -5,5 +5,5 @@
"outDir": "dist" "outDir": "dist"
}, },
"include": ["src"], "include": ["src"],
"references": [{ "path": "../workflow-protocol" }, { "path": "../workflow-util" }] "references": [{ "path": "../util-agent" }, { "path": "../util" }]
} }
@@ -36,7 +36,7 @@
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://git.shazhou.work/uncaged/workflow.git", "url": "https://git.shazhou.work/uncaged/workflow.git",
"directory": "packages/workflow-agent-claude-code" "directory": "packages/agent-claude-code"
}, },
"homepage": "https://git.shazhou.work/uncaged/workflow#readme", "homepage": "https://git.shazhou.work/uncaged/workflow#readme",
"bugs": { "bugs": {
@@ -2,5 +2,5 @@
"extends": "../../tsconfig.json", "extends": "../../tsconfig.json",
"compilerOptions": { "rootDir": "src", "outDir": "dist" }, "compilerOptions": { "rootDir": "src", "outDir": "dist" },
"include": ["src"], "include": ["src"],
"references": [{ "path": "../workflow-util-agent" }] "references": [{ "path": "../util-agent" }]
} }
@@ -37,7 +37,7 @@
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://git.shazhou.work/uncaged/workflow.git", "url": "https://git.shazhou.work/uncaged/workflow.git",
"directory": "packages/workflow-agent-hermes" "directory": "packages/agent-hermes"
}, },
"homepage": "https://git.shazhou.work/uncaged/workflow#readme", "homepage": "https://git.shazhou.work/uncaged/workflow#readme",
"bugs": { "bugs": {
@@ -5,5 +5,5 @@
"outDir": "dist" "outDir": "dist"
}, },
"include": ["src"], "include": ["src"],
"references": [{ "path": "../workflow-util-agent" }] "references": [{ "path": "../util-agent" }]
} }
@@ -29,7 +29,7 @@ Included as the `uwf` binary when you install `@united-workforce/cli`:
```bash ```bash
bun add -g @united-workforce/cli bun add -g @united-workforce/cli
# or from the monorepo: # or from the monorepo:
bun link packages/cli-workflow bun link packages/cli
``` ```
## CLI Usage ## CLI Usage
@@ -35,7 +35,7 @@
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://git.shazhou.work/uncaged/workflow.git", "url": "https://git.shazhou.work/uncaged/workflow.git",
"directory": "packages/cli-workflow" "directory": "packages/cli"
}, },
"homepage": "https://git.shazhou.work/uncaged/workflow#readme", "homepage": "https://git.shazhou.work/uncaged/workflow#readme",
"bugs": { "bugs": {
@@ -13,7 +13,7 @@ import { parse } from "yaml";
*/ */
describe("solve-issue workflow: Gitea API PR creation", () => { describe("solve-issue workflow: Gitea API PR creation", () => {
// Navigate up from packages/cli-workflow/src/__tests__ to repo root // Navigate up from packages/cli/src/__tests__ to repo root
const workflowPath = join( const workflowPath = join(
import.meta.dirname, import.meta.dirname,
"..", "..",

Some files were not shown because too many files have changed in this diff Show More