feat: add user skill — CLI guide with quick start and typical workflows
Adds 'uwf skill user' command for agents/humans using the uwf CLI. Covers setup, workflow management, thread lifecycle, step operations, CAS queries, logging, and global options with a Quick Start guide. Refs #538
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
|||||||
cmdSkillCli,
|
cmdSkillCli,
|
||||||
cmdSkillList,
|
cmdSkillList,
|
||||||
cmdSkillModerator,
|
cmdSkillModerator,
|
||||||
|
cmdSkillUser,
|
||||||
cmdSkillYaml,
|
cmdSkillYaml,
|
||||||
} from "../commands/skill.js";
|
} from "../commands/skill.js";
|
||||||
|
|
||||||
@@ -23,6 +24,7 @@ describe("skill commands", () => {
|
|||||||
expect(result).toContain("yaml");
|
expect(result).toContain("yaml");
|
||||||
expect(result).toContain("moderator");
|
expect(result).toContain("moderator");
|
||||||
expect(result).toContain("actor");
|
expect(result).toContain("actor");
|
||||||
|
expect(result).toContain("user");
|
||||||
for (const name of result) {
|
for (const name of result) {
|
||||||
expect(name).toMatch(/^\S+$/);
|
expect(name).toMatch(/^\S+$/);
|
||||||
}
|
}
|
||||||
@@ -72,6 +74,16 @@ describe("skill commands", () => {
|
|||||||
expect(result.length).toBeGreaterThan(200);
|
expect(result.length).toBeGreaterThan(200);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("skill user returns non-empty markdown string", () => {
|
||||||
|
const result = cmdSkillUser();
|
||||||
|
expect(typeof result).toBe("string");
|
||||||
|
expect(result).toContain("uwf");
|
||||||
|
expect(result).toContain("thread");
|
||||||
|
expect(result).toContain("workflow");
|
||||||
|
expect(result).toContain("Quick Start");
|
||||||
|
expect(result.length).toBeGreaterThan(500);
|
||||||
|
});
|
||||||
|
|
||||||
test("skill help subcommand is suppressed", () => {
|
test("skill help subcommand is suppressed", () => {
|
||||||
const output = execFileSync("bun", ["src/cli.ts", "skill", "--help"], {
|
const output = execFileSync("bun", ["src/cli.ts", "skill", "--help"], {
|
||||||
cwd: join(__dirname, "..", ".."),
|
cwd: join(__dirname, "..", ".."),
|
||||||
@@ -84,6 +96,7 @@ describe("skill commands", () => {
|
|||||||
expect(output).toContain("yaml");
|
expect(output).toContain("yaml");
|
||||||
expect(output).toContain("moderator");
|
expect(output).toContain("moderator");
|
||||||
expect(output).toContain("actor");
|
expect(output).toContain("actor");
|
||||||
|
expect(output).toContain("user");
|
||||||
expect(output).toContain("list");
|
expect(output).toContain("list");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
cmdSkillCli,
|
cmdSkillCli,
|
||||||
cmdSkillList,
|
cmdSkillList,
|
||||||
cmdSkillModerator,
|
cmdSkillModerator,
|
||||||
|
cmdSkillUser,
|
||||||
cmdSkillYaml,
|
cmdSkillYaml,
|
||||||
} from "./commands/skill.js";
|
} from "./commands/skill.js";
|
||||||
import { cmdStepFork, cmdStepList, cmdStepRead, cmdStepShow } from "./commands/step.js";
|
import { cmdStepFork, cmdStepList, cmdStepRead, cmdStepShow } from "./commands/step.js";
|
||||||
@@ -518,6 +519,13 @@ skill
|
|||||||
console.log(cmdSkillModerator());
|
console.log(cmdSkillModerator());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
skill
|
||||||
|
.command("user")
|
||||||
|
.description("Print the user reference (CLI guide + typical workflows)")
|
||||||
|
.action(() => {
|
||||||
|
console.log(cmdSkillUser());
|
||||||
|
});
|
||||||
|
|
||||||
skill
|
skill
|
||||||
.command("list")
|
.command("list")
|
||||||
.description("List all available skill names")
|
.description("List all available skill names")
|
||||||
|
|||||||
@@ -3,10 +3,11 @@ export {
|
|||||||
generateArchitectureReference as cmdSkillArchitecture,
|
generateArchitectureReference as cmdSkillArchitecture,
|
||||||
generateCliReference as cmdSkillCli,
|
generateCliReference as cmdSkillCli,
|
||||||
generateModeratorReference as cmdSkillModerator,
|
generateModeratorReference as cmdSkillModerator,
|
||||||
|
generateUserReference as cmdSkillUser,
|
||||||
generateYamlReference as cmdSkillYaml,
|
generateYamlReference as cmdSkillYaml,
|
||||||
} from "@uncaged/workflow-util";
|
} from "@uncaged/workflow-util";
|
||||||
|
|
||||||
const SKILL_NAMES = ["cli", "architecture", "yaml", "moderator", "actor"] as const;
|
const SKILL_NAMES = ["cli", "architecture", "yaml", "moderator", "actor", "user"] as const;
|
||||||
|
|
||||||
export function cmdSkillList(): ReadonlyArray<string> {
|
export function cmdSkillList(): ReadonlyArray<string> {
|
||||||
return [...SKILL_NAMES];
|
return [...SKILL_NAMES];
|
||||||
|
|||||||
@@ -28,4 +28,5 @@ export { err, ok } from "./result.js";
|
|||||||
export { getDefaultWorkflowStorageRoot, getGlobalCasDir } from "./storage-root.js";
|
export { getDefaultWorkflowStorageRoot, getGlobalCasDir } from "./storage-root.js";
|
||||||
export type { LogFn, Result } from "./types.js";
|
export type { LogFn, Result } from "./types.js";
|
||||||
export { extractUlidTimestamp, generateUlid } from "./ulid.js";
|
export { extractUlidTimestamp, generateUlid } from "./ulid.js";
|
||||||
|
export { generateUserReference } from "./user-reference.js";
|
||||||
export { generateYamlReference } from "./yaml-reference.js";
|
export { generateYamlReference } from "./yaml-reference.js";
|
||||||
|
|||||||
@@ -0,0 +1,125 @@
|
|||||||
|
export function generateUserReference(): string {
|
||||||
|
return `# User Reference
|
||||||
|
|
||||||
|
Guide for using the uwf CLI to manage workflows and threads.
|
||||||
|
|
||||||
|
## Quick Start
|
||||||
|
|
||||||
|
\`\`\`bash
|
||||||
|
# 1. Configure provider and model
|
||||||
|
uwf setup
|
||||||
|
|
||||||
|
# 2. Register a workflow
|
||||||
|
uwf workflow add my-workflow.yaml
|
||||||
|
|
||||||
|
# 3. Start a thread (creates but does not execute)
|
||||||
|
uwf thread start my-workflow -p "Build a login page"
|
||||||
|
|
||||||
|
# 4. Execute the thread (runs moderator → agent → extract cycles)
|
||||||
|
uwf thread exec <thread-id> # one step
|
||||||
|
uwf thread exec <thread-id> -c 10 # up to 10 steps
|
||||||
|
uwf thread exec <thread-id> -c 10 --background # run in background
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## Concepts
|
||||||
|
|
||||||
|
- **Workflow** — YAML definition with roles and a routing graph; stored as a CAS node
|
||||||
|
- **Thread** — A running instance of a workflow; a chain of step nodes in CAS
|
||||||
|
- **Step** — One moderator → agent → extract cycle; contains the role's structured output
|
||||||
|
- **CAS** — Content-addressable store; every artifact is hashed (XXH64, Crockford Base32)
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
uwf setup # interactive wizard
|
||||||
|
uwf setup --provider <name> --base-url <url> \\
|
||||||
|
--api-key <key> --model <name> # non-interactive
|
||||||
|
[--agent <name>] # optional default agent
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
Config is stored at \`~/.uncaged/workflow/config.yaml\`. Override storage root with \`UNCAGED_WORKFLOW_STORAGE_ROOT\`.
|
||||||
|
|
||||||
|
## Workflow Commands
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
uwf workflow add <file> # register from YAML file
|
||||||
|
uwf workflow show <id> # show by name or CAS hash
|
||||||
|
uwf workflow list # list all registered workflows
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
You can also pass a file path directly to \`uwf thread start\` without registering first.
|
||||||
|
|
||||||
|
## Thread Lifecycle
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
uwf thread start <workflow> -p <prompt> # create thread
|
||||||
|
uwf thread exec <thread-id> # execute one step
|
||||||
|
[--agent <cmd>] # override agent
|
||||||
|
[-c, --count <n>] # run n steps
|
||||||
|
[--background] # run in background
|
||||||
|
uwf thread show <thread-id> # show head pointer
|
||||||
|
uwf thread list # list all threads
|
||||||
|
[--status <filter>] # idle, running, completed, cancelled, active (comma-separated)
|
||||||
|
[--after <thread-id>] # pagination: after this thread
|
||||||
|
[--before <thread-id>] # pagination: before this thread
|
||||||
|
[--skip <n>] # skip first n results
|
||||||
|
[--take <n>] # limit results
|
||||||
|
uwf thread read <thread-id> # render context as markdown
|
||||||
|
[--quota <chars>] # max output chars (default 4000)
|
||||||
|
[--before <step-hash>] # pagination
|
||||||
|
[--start] # include start step
|
||||||
|
uwf thread stop <thread-id> # stop background execution
|
||||||
|
uwf thread cancel <thread-id> # cancel and archive thread
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
### Typical Lifecycle
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
start → exec (repeat) → thread reaches $END → auto-completed
|
||||||
|
→ or: cancel to abort
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## Step Commands
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
uwf step list <thread-id> # list all steps
|
||||||
|
uwf step show <step-hash> # show step details
|
||||||
|
uwf step fork <step-hash> # fork thread from a step (branch)
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
Forking creates a new thread that shares history up to the fork point — useful for retrying from a known-good state.
|
||||||
|
|
||||||
|
## CAS Commands
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
uwf cas get <hash> # read a node (type + payload)
|
||||||
|
[--timestamp] # include timestamp
|
||||||
|
uwf cas put <type-hash> <data> # store typed JSON, print hash
|
||||||
|
uwf cas put-text <text> # store plain text, print hash
|
||||||
|
uwf cas has <hash> # check existence
|
||||||
|
uwf cas refs <hash> # list direct references
|
||||||
|
uwf cas walk <hash> # recursive traversal
|
||||||
|
uwf cas reindex # rebuild type index
|
||||||
|
uwf cas schema list # list schemas
|
||||||
|
uwf cas schema get <hash> # show schema definition
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## Log Commands
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
uwf log list # list log files
|
||||||
|
uwf log show # show log entries
|
||||||
|
[--thread <id>] # filter by thread
|
||||||
|
[--process <pid>] # filter by process
|
||||||
|
[--date <YYYY-MM-DD>] # filter by date
|
||||||
|
uwf log clean --before <date> # delete old logs
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## Global Options
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
uwf --format <json|yaml> # output format (default: json)
|
||||||
|
uwf -V, --version # print version
|
||||||
|
\`\`\`
|
||||||
|
`;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user