Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 485bfcb0b6 | |||
| 7d3954097d | |||
| 4a925b98af | |||
| bfea771a52 | |||
| 5e411a1f19 |
@@ -0,0 +1,71 @@
|
|||||||
|
# @uncaged/workflow
|
||||||
|
|
||||||
|
A workflow engine that executes single-file ESM bundles. Each workflow is a self-contained `.esm.js` file identified by its XXH64 hash (Crockford Base32).
|
||||||
|
|
||||||
|
## Core Concepts
|
||||||
|
|
||||||
|
| Concept | Description |
|
||||||
|
|---------|-------------|
|
||||||
|
| **Workflow** | A single-file ESM module exporting `run` (workflow function) and `descriptor` (metadata). Identified by its XXH64 hash. |
|
||||||
|
| **Bundle** | The physical `.esm.js` file stored in `~/.uncaged/workflow/bundles/`. |
|
||||||
|
| **Thread** | A single execution of a workflow, identified by a ULID. Persisted as `.data.jsonl` + `.info.jsonl`. |
|
||||||
|
| **Role** | A named actor within a workflow. Each role produces output with typed `meta`. Roles live inside template packages (`src/roles/`). |
|
||||||
|
| **Registry** | `workflow.yaml` — maps workflow names to current/historical bundle hashes. |
|
||||||
|
| **CAS** | Content-Addressed Storage — bundles are immutable and addressed by hash. |
|
||||||
|
|
||||||
|
## Monorepo Packages
|
||||||
|
|
||||||
|
```
|
||||||
|
packages/
|
||||||
|
workflow/ # @uncaged/workflow — core lib (types, engine, hash, ULID, registry)
|
||||||
|
cli-workflow/ # @uncaged/cli-workflow — CLI (`uncaged-workflow` command)
|
||||||
|
workflow-template-develop/ # @uncaged/workflow-template-develop — develop workflow template (includes roles)
|
||||||
|
workflow-template-solve-issue/ # @uncaged/workflow-template-solve-issue — solve-issue workflow template (includes roles)
|
||||||
|
workflow-agent-hermes/ # @uncaged/workflow-agent-hermes — Hermes agent adapter
|
||||||
|
workflow-agent-cursor/ # @uncaged/workflow-agent-cursor — Cursor agent adapter
|
||||||
|
workflow-agent-llm/ # @uncaged/workflow-agent-llm — LLM agent adapter
|
||||||
|
workflow-util-agent/ # @uncaged/workflow-util-agent — agent utilities (buildAgentPrompt, spawnCli)
|
||||||
|
```
|
||||||
|
|
||||||
|
Managed with **bun workspace** using the `workspace:*` protocol.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Install dependencies
|
||||||
|
bun install
|
||||||
|
|
||||||
|
# Build all packages
|
||||||
|
bun run build
|
||||||
|
|
||||||
|
# Register a workflow bundle
|
||||||
|
uncaged-workflow workflow add solve-issue dist/packages/workflow-template-solve-issue/solve-issue.esm.js
|
||||||
|
|
||||||
|
# Run a workflow
|
||||||
|
uncaged-workflow run solve-issue --prompt "Fix bug #42"
|
||||||
|
```
|
||||||
|
|
||||||
|
## CLI Usage
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uncaged-workflow help # Show all commands
|
||||||
|
uncaged-workflow workflow list # List registered workflows
|
||||||
|
uncaged-workflow run <name> # Start a workflow thread
|
||||||
|
uncaged-workflow thread list # List all threads
|
||||||
|
uncaged-workflow thread show <id> # Inspect a thread
|
||||||
|
uncaged-workflow skill # Agent-consumable reference docs
|
||||||
|
```
|
||||||
|
|
||||||
|
See `uncaged-workflow help` for the full command reference.
|
||||||
|
|
||||||
|
## Development
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun run check # Biome lint + format check
|
||||||
|
bun run format # Auto-format with Biome
|
||||||
|
bun test # Run tests
|
||||||
|
```
|
||||||
|
|
||||||
|
## Architecture
|
||||||
|
|
||||||
|
See [docs/architecture.md](docs/architecture.md) for the full design — three-phase engine loop, bundle contract, storage layout, and design decisions.
|
||||||
@@ -17,11 +17,8 @@ A workflow engine that executes single-file ESM bundles. Each workflow is a self
|
|||||||
| `workflow-agent-cursor` | `@uncaged/workflow-agent-cursor` | Cursor CLI agent (extracts workspace from ctx) |
|
| `workflow-agent-cursor` | `@uncaged/workflow-agent-cursor` | Cursor CLI agent (extracts workspace from ctx) |
|
||||||
| `workflow-agent-hermes` | `@uncaged/workflow-agent-hermes` | Hermes CLI agent |
|
| `workflow-agent-hermes` | `@uncaged/workflow-agent-hermes` | Hermes CLI agent |
|
||||||
| `workflow-agent-llm` | `@uncaged/workflow-agent-llm` | OpenAI-compatible LLM agent |
|
| `workflow-agent-llm` | `@uncaged/workflow-agent-llm` | OpenAI-compatible LLM agent |
|
||||||
| `workflow-role-planner` | `@uncaged/workflow-role-planner` | Pure data: phased planning prompt + schema |
|
| `workflow-template-develop` | `@uncaged/workflow-template-develop` | Develop workflow template (roles in `src/roles/`) |
|
||||||
| `workflow-role-coder` | `@uncaged/workflow-role-coder` | Pure data: coding prompt + schema |
|
| `workflow-template-solve-issue` | `@uncaged/workflow-template-solve-issue` | Solve-issue workflow template (roles in `src/roles/`) |
|
||||||
| `workflow-role-reviewer` | `@uncaged/workflow-role-reviewer` | Pure data: code review prompt + schema |
|
|
||||||
| `workflow-role-committer` | `@uncaged/workflow-role-committer` | Pure data: git commit prompt + schema |
|
|
||||||
| `workflow-template-solve-issue` | `@uncaged/workflow-template-solve-issue` | Composes roles + moderator into a complete workflow |
|
|
||||||
| `workflow-util-agent` | `@uncaged/workflow-util-agent` | `buildAgentPrompt` + `spawnCli` utilities |
|
| `workflow-util-agent` | `@uncaged/workflow-util-agent` | `buildAgentPrompt` + `spawnCli` utilities |
|
||||||
|
|
||||||
Monorepo with **bun workspace**, `workspace:*` protocol.
|
Monorepo with **bun workspace**, `workspace:*` protocol.
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
"examples"
|
"examples"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "bun run --filter '*' build",
|
|
||||||
"check": "bunx tsc --build && biome check .",
|
"check": "bunx tsc --build && biome check .",
|
||||||
"typecheck": "bunx tsc --build",
|
"typecheck": "bunx tsc --build",
|
||||||
"format": "biome format --write .",
|
"format": "biome format --write .",
|
||||||
|
|||||||
@@ -42,11 +42,6 @@ describe("skill command", () => {
|
|||||||
expect(code).toBe(0);
|
expect(code).toBe(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test("skill --help returns 0", async () => {
|
|
||||||
const code = await runCli(STORAGE_ROOT, ["skill", "--help"]);
|
|
||||||
expect(code).toBe(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
test("skill unknown returns 1", async () => {
|
test("skill unknown returns 1", async () => {
|
||||||
const code = await runCli(STORAGE_ROOT, ["skill", "unknown"]);
|
const code = await runCli(STORAGE_ROOT, ["skill", "unknown"]);
|
||||||
expect(code).toBe(1);
|
expect(code).toBe(1);
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
"yaml": "^2.8.4"
|
"yaml": "^2.8.4"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "echo 'TODO'",
|
|
||||||
"test": "bun test"
|
"test": "bun test"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -682,7 +682,7 @@ async function dispatchCas(storageRoot: string, argv: string[]): Promise<number>
|
|||||||
|
|
||||||
async function dispatchSkill(_storageRoot: string, argv: string[]): Promise<number> {
|
async function dispatchSkill(_storageRoot: string, argv: string[]): Promise<number> {
|
||||||
const topic = argv[0];
|
const topic = argv[0];
|
||||||
if (topic === undefined || topic === "--help" || topic === "-h") {
|
if (topic === undefined) {
|
||||||
printCliLine(formatSkillIndex());
|
printCliLine(formatSkillIndex());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"types": "src/index.ts",
|
"types": "src/index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "echo 'TODO'",
|
|
||||||
"test": "bun test"
|
"test": "bun test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"types": "src/index.ts",
|
"types": "src/index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "echo 'TODO'",
|
|
||||||
"test": "bun test"
|
"test": "bun test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"types": "src/index.ts",
|
"types": "src/index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "echo 'TODO'",
|
|
||||||
"test": "bun test"
|
"test": "bun test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"types": "src/index.ts",
|
"types": "src/index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "echo 'TODO'",
|
|
||||||
"test": "bun test"
|
"test": "bun test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"types": "src/index.ts",
|
"types": "src/index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "echo 'TODO'",
|
|
||||||
"test": "bun test"
|
"test": "bun test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "echo 'TODO'",
|
|
||||||
"test": "bun test"
|
"test": "bun test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@
|
|||||||
"main": "src/index.ts",
|
"main": "src/index.ts",
|
||||||
"types": "src/index.ts",
|
"types": "src/index.ts",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "echo 'TODO'",
|
|
||||||
"test": "bun test"
|
"test": "bun test"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
Reference in New Issue
Block a user