Compare commits

..

5 Commits

Author SHA1 Message Date
xiaoju 485bfcb0b6 chore: remove unused build scripts
All packages are pure Bun/TS — no build step needed.
The build scripts were all placeholder `echo 'TODO'` anyway.
2026-05-08 00:46:35 +00:00
xiaoju 7d3954097d docs: fix deprecated CLI commands in README
- workflow add (was: add)
- workflow list (was: list)
- thread list (was: threads)
- thread show (was: thread)

小橘 🍊
2026-05-07 16:15:29 +00:00
xiaoju 4a925b98af docs: create README.md, update architecture.md for current structure
- Create root README.md with project intro, concepts, packages, quickstart
- Remove workflow-role-* references from docs/architecture.md
- Roles now live inside template packages (src/roles/)
- Clean up untracked dist/packages/workflow-role-* remnants

Fixes #88
2026-05-07 16:10:37 +00:00
xingyue bfea771a52 Merge pull request 'fix(cli): improve usage format + fix skill index title' (#86) from fix/85-usage-format into main 2026-05-07 15:33:27 +00:00
xiaoju 5e411a1f19 fix(cli): improve usage output format + fix skill index title
- Usage: grouped sections with titles, aligned descriptions
- Header: 'uncaged-workflow — workflow engine CLI'
- Footer: 'Use <command> --help for subcommand details.'
- Fix skill index title: 'uncaged-workflow skill' (was: help --skill)
- 242 tests pass

Closes #85

小橘 🍊
2026-05-07 15:31:48 +00:00
13 changed files with 74 additions and 20 deletions
+71
View File
@@ -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.
+2 -5
View File
@@ -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.
-1
View File
@@ -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);
-1
View File
@@ -10,7 +10,6 @@
"yaml": "^2.8.4" "yaml": "^2.8.4"
}, },
"scripts": { "scripts": {
"build": "echo 'TODO'",
"test": "bun test" "test": "bun test"
} }
} }
+1 -1
View File
@@ -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": {
-1
View File
@@ -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": {
-1
View File
@@ -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": {