@workflow-manager/runner 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -9,7 +9,7 @@ The core ideas:
9
9
  - **The envelope protocol.** Every step execution returns a structured result: an execution status (`SUCCESS`, `FAILED`, `QA_REJECTED`, `YIELD_EXTERNAL`) plus a QA routing action (`PROCEED`, `RETRY_CURRENT`, `ROLLBACK_PREVIOUS`, `RESTART_ALL`). That's what lets the engine retry a step, roll back to the previous one, or restart the whole run based on what the agent reported.
10
10
  - **Human-in-the-loop control.** While a run is active, wfm starts a local HTTP attach API (token-protected, with SSE event streaming), so a waiting step can be resolved either in the terminal prompt or from another shell with `wfm approve` / `wfm resume` / `wfm cancel`.
11
11
  - **A registry.** `wfm publish` / `pull` / `search` / `auth` talk to a Supabase-backed remote registry (the `apps/remote-registry` web app in this repo) for sharing workflows, with skills bundled and SHA-256 verified. Runs also emit opt-in telemetry there.
12
- - **Supporting commands.** `wfm scaffold` writes a starter workflow, `wfm validate` checks the schema and dependency cycles, `wfm doctor` verifies the host has the needed CLIs and API keys before a run, `wfm agent` drops an AGENTS.md rules file, and `wfm man` shows the man page.
12
+ - **Supporting commands.** `wfm scaffold` writes a starter workflow, `wfm validate` checks the schema and dependency cycles, `wfm doctor` verifies the host has the needed CLIs and API keys before a run, `wfm skill install` installs the bundled agent skills into Claude Code or opencode skill directories, and `wfm man` shows the man page.
13
13
 
14
14
  Install the latest prebuilt CLI with:
15
15
 
@@ -31,7 +31,7 @@ If `wfm` is not available immediately in the same terminal, run the shell reload
31
31
 
32
32
  ## Architecture
33
33
 
34
- - `src/index.ts`: CLI commands (`doctor`, `agent`, `scaffold`, `validate`, `run`)
34
+ - `src/index.ts`: CLI commands (`doctor`, `skill`, `scaffold`, `validate`, `run`)
35
35
  - `src/parser.ts`: parsing + validation
36
36
  - `src/engine.ts`: execution loop, confirmations, retries, rollback/restart
37
37
  - `src/piAgentExecutor.ts`: default executor driving the `pi` coding agent CLI
@@ -51,7 +51,7 @@ bun run build
51
51
  bun link
52
52
 
53
53
  wfm doctor
54
- wfm agent ./AGENTS.md
54
+ wfm skill install
55
55
  wfm scaffold ./example-workflow.md
56
56
  wfm validate ./example-workflow.md
57
57
  wfm doctor ./example-workflow.md
@@ -214,10 +214,11 @@ Manual help:
214
214
  wfm man
215
215
  ```
216
216
 
217
- Agent rules:
217
+ Agent skills:
218
218
 
219
219
  ```bash
220
- wfm agent ./AGENTS.md
220
+ wfm skill list
221
+ wfm skill install
221
222
  ```
222
223
 
223
224
  Remote registry commands:
@@ -230,13 +231,20 @@ wfm remote info alice/remote-bunny
230
231
 
231
232
  ## Agent skills
232
233
 
233
- The published `@workflow-manager/runner` npm package now ships the CLI runner and the bundled agent skills together.
234
+ The published `@workflow-manager/runner` npm package ships the CLI runner and the bundled agent skills together. The primary skill is `skills/workflow-manager-cli/SKILL.md`, which teaches an agent how to configure, author, run, and publish workflows with `wfm`.
234
235
 
235
- - bundled skill: `skills/workflow-manager-cli/SKILL.md`
236
- - discovery keyword: `tanstack-intent`
237
- - install flow: install `@workflow-manager/runner`, then run `npx @tanstack/intent@latest list` and `npx @tanstack/intent@latest install`
236
+ Install skills with the CLI:
238
237
 
239
- Example usage:
238
+ ```bash
239
+ wfm skill list # show bundled skills
240
+ wfm skill install # workflow-manager-cli -> ./.claude/skills/
241
+ wfm skill install --global # -> ~/.claude/skills/
242
+ wfm skill install --agent opencode # -> ./.opencode/skill/
243
+ wfm skill install --all # install every bundled skill
244
+ wfm skill install doc-sync --dir ./my/skills
245
+ ```
246
+
247
+ TanStack Intent discovery is also supported (package keyword `tanstack-intent`):
240
248
 
241
249
  ```bash
242
250
  npm install @workflow-manager/runner
package/dist/index.js CHANGED
@@ -5,6 +5,7 @@ import os from "node:os";
5
5
  import path from "node:path";
6
6
  import { spawnSync } from "node:child_process";
7
7
  import { fileURLToPath } from "node:url";
8
+ import matter from "gray-matter";
8
9
  import { CliRunRenderer } from "./cliRunRenderer.js";
9
10
  import { startRunnerApiServer } from "./runnerApi.js";
10
11
  import { RunnerSessionStore } from "./runnerSession.js";
@@ -25,7 +26,8 @@ function usage() {
25
26
  const cli = cliDisplayName();
26
27
  console.log(`${cli} commands:
27
28
  doctor [workflow.md|workflow.json] [--json]
28
- agent [path] [--force]
29
+ skill list
30
+ skill install [name ...] [--agent claude|opencode] [--global] [--dir path] [--all] [--force]
29
31
  scaffold [path] [--format markdown|json]
30
32
  validate <workflow.md|workflow.json>
31
33
  run <workflow.md|workflow.json> [--input input.json] [--objective "string"] [--confirm stepA,stepB:human] [--auto-confirm-all] [--port 43121] [--verbose] [--json]
@@ -248,36 +250,6 @@ steps:
248
250
 
249
251
  Edit frontmatter to configure orchestration behavior.
250
252
  `;
251
- const AGENT_RULES_TEMPLATE = `# WFM Agent Rules
252
-
253
- Use these rules when creating, validating, running, or publishing workflow-manager workflows with the \`wfm\` CLI.
254
-
255
- ## Core Flow
256
-
257
- 1. Start with \`wfm doctor\` to inspect local adapter and API key setup.
258
- 2. Create a starter workflow with \`wfm scaffold ./workflow.md\` or \`wfm scaffold ./workflow.json --format json\`.
259
- 3. Edit stable workflow keys, step objectives, dependencies, validation modes, and adapter initialization.
260
- 4. Run \`wfm validate <workflow>\` before every run or publish.
261
- 5. Run \`wfm doctor <workflow>\` before using real host-backed adapters.
262
- 6. Run with \`wfm run <workflow>\`; use \`--verbose\` when agent logs are needed.
263
- 7. Publish only after validation succeeds with \`wfm publish <workflow>\`.
264
-
265
- ## Workflow Authoring
266
-
267
- - Keep workflow, step, and adapter keys stable; external tools and tests may reference them.
268
- - Omit \`taskSpec.adapterKey\` for the default \`pi-agent\` adapter.
269
- - Use \`adapterKey: mock\` for deterministic tests and examples.
270
- - Put skills, MCP endpoints, system prompts, model, and context under \`taskSpec.init\`.
271
- - Model-backed steps should declare required environment variables through provider-specific model names or \`taskSpec.payload.requiredEnv\`.
272
- - Human or external validation should be explicit in the workflow file.
273
-
274
- ## Running Safely
275
-
276
- - Do not use \`--auto-confirm-all\` unless the workflow is intentionally non-interactive.
277
- - Prefer \`wfm doctor <workflow>\` before runs that use \`pi-agent\`, real \`opencode\`, or real \`claude-code\`.
278
- - Use the attach API output from \`wfm run\` for approval, resume, and cancel commands.
279
- - Preserve Markdown workflows when humans will review notes; use JSON for generated or machine-edited workflows.
280
- `;
281
253
  function resolveScaffoldFormat(targetPath, explicitFormat) {
282
254
  if (explicitFormat === "markdown" || explicitFormat === "json") {
283
255
  return explicitFormat;
@@ -300,29 +272,138 @@ function parseScaffoldArgs(args) {
300
272
  }
301
273
  return { targetPath, format };
302
274
  }
303
- function parseAgentArgs(args) {
304
- let targetPath;
305
- let force = false;
306
- for (const arg of args) {
275
+ const DEFAULT_INSTALL_SKILL = "workflow-manager-cli";
276
+ const SKILL_INSTALL_TARGETS = {
277
+ claude: {
278
+ projectDir: path.join(".claude", "skills"),
279
+ globalDir: path.join(os.homedir(), ".claude", "skills"),
280
+ },
281
+ opencode: {
282
+ projectDir: path.join(".opencode", "skill"),
283
+ globalDir: path.join(os.homedir(), ".config", "opencode", "skill"),
284
+ },
285
+ };
286
+ function packagedSkillsDir() {
287
+ return path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..", "skills");
288
+ }
289
+ function listPackagedSkills() {
290
+ const root = packagedSkillsDir();
291
+ if (!fs.existsSync(root)) {
292
+ return [];
293
+ }
294
+ const skills = [];
295
+ for (const entry of fs.readdirSync(root, { withFileTypes: true })) {
296
+ if (!entry.isDirectory())
297
+ continue;
298
+ const dir = path.join(root, entry.name);
299
+ const skillFile = path.join(dir, "SKILL.md");
300
+ if (!fs.existsSync(skillFile))
301
+ continue;
302
+ let description = "";
303
+ try {
304
+ const parsed = matter(fs.readFileSync(skillFile, "utf-8"));
305
+ if (typeof parsed.data.description === "string") {
306
+ description = parsed.data.description.replace(/\s+/g, " ").trim();
307
+ }
308
+ }
309
+ catch {
310
+ // skills without parseable frontmatter are still installable
311
+ }
312
+ skills.push({ name: entry.name, dir, description });
313
+ }
314
+ return skills;
315
+ }
316
+ function cmdSkillList() {
317
+ const skills = listPackagedSkills();
318
+ if (skills.length === 0) {
319
+ console.error(`No bundled skills found at ${packagedSkillsDir()}.`);
320
+ return 1;
321
+ }
322
+ console.log("Bundled skills:\n");
323
+ for (const skill of skills) {
324
+ console.log(` ${skill.name}`);
325
+ if (skill.description) {
326
+ console.log(` ${skill.description}`);
327
+ }
328
+ }
329
+ console.log(`\nInstall with: ${cliDisplayName()} skill install <name> [--agent claude|opencode] [--global]`);
330
+ return 0;
331
+ }
332
+ function parseSkillInstallArgs(args) {
333
+ const parsed = { names: [], agent: "claude", global: false, force: false, all: false };
334
+ for (let i = 0; i < args.length; i += 1) {
335
+ const arg = args[i];
336
+ if (arg === "--agent") {
337
+ parsed.agent = args[i + 1] ?? "";
338
+ i += 1;
339
+ continue;
340
+ }
341
+ if (arg === "--dir") {
342
+ parsed.dir = args[i + 1];
343
+ i += 1;
344
+ continue;
345
+ }
346
+ if (arg === "--global" || arg === "-g") {
347
+ parsed.global = true;
348
+ continue;
349
+ }
307
350
  if (arg === "--force" || arg === "-f") {
308
- force = true;
351
+ parsed.force = true;
309
352
  continue;
310
353
  }
311
- if (!arg.startsWith("-") && !targetPath) {
312
- targetPath = arg;
354
+ if (arg === "--all") {
355
+ parsed.all = true;
356
+ continue;
357
+ }
358
+ if (!arg.startsWith("-")) {
359
+ parsed.names.push(arg);
313
360
  }
314
361
  }
315
- return { targetPath, force };
362
+ return parsed;
316
363
  }
317
- function cmdAgent(targetPath, force = false) {
318
- const resolvedPath = path.resolve(targetPath ?? "./AGENTS.md");
319
- if (fs.existsSync(resolvedPath) && !force) {
320
- console.error(`Agent rules already exist at ${resolvedPath}. Pass --force to overwrite.`);
364
+ function resolveSkillInstallRoot(args) {
365
+ if (args.dir) {
366
+ return path.resolve(args.dir);
367
+ }
368
+ const target = SKILL_INSTALL_TARGETS[args.agent];
369
+ if (!target) {
370
+ return undefined;
371
+ }
372
+ return args.global ? target.globalDir : path.resolve(target.projectDir);
373
+ }
374
+ function cmdSkillInstall(args) {
375
+ const parsed = parseSkillInstallArgs(args);
376
+ const targetRoot = resolveSkillInstallRoot(parsed);
377
+ if (!targetRoot) {
378
+ console.error(`Unknown --agent value: ${parsed.agent}. Supported agents: ${Object.keys(SKILL_INSTALL_TARGETS).join(", ")}. Use --dir for any other destination.`);
321
379
  return 1;
322
380
  }
323
- fs.mkdirSync(path.dirname(resolvedPath), { recursive: true });
324
- fs.writeFileSync(resolvedPath, AGENT_RULES_TEMPLATE, "utf-8");
325
- console.log(`Wrote WFM agent rules: ${resolvedPath}`);
381
+ const available = listPackagedSkills();
382
+ const names = parsed.all
383
+ ? available.map((skill) => skill.name)
384
+ : parsed.names.length > 0
385
+ ? parsed.names
386
+ : [DEFAULT_INSTALL_SKILL];
387
+ for (const name of names) {
388
+ const skill = available.find((candidate) => candidate.name === name);
389
+ if (!skill) {
390
+ console.error(`Unknown skill: ${name}. Run \`${cliDisplayName()} skill list\` to see bundled skills.`);
391
+ return 1;
392
+ }
393
+ const destDir = path.join(targetRoot, name);
394
+ const destFile = path.join(destDir, "SKILL.md");
395
+ if (fs.existsSync(destFile) && !parsed.force) {
396
+ console.error(`Skill already installed at ${destFile}. Pass --force to overwrite.`);
397
+ return 1;
398
+ }
399
+ fs.mkdirSync(destDir, { recursive: true });
400
+ for (const entry of fs.readdirSync(skill.dir, { withFileTypes: true })) {
401
+ if (!entry.isFile() || entry.name === "README.md")
402
+ continue;
403
+ fs.copyFileSync(path.join(skill.dir, entry.name), path.join(destDir, entry.name));
404
+ }
405
+ console.log(`Installed skill ${name} -> ${destDir}`);
406
+ }
326
407
  return 0;
327
408
  }
328
409
  function cmdScaffold(targetPath, format) {
@@ -677,9 +758,16 @@ async function main() {
677
758
  if (cmd === "doctor") {
678
759
  process.exit(cmdDoctor(process.argv.slice(3)));
679
760
  }
680
- if (cmd === "agent") {
681
- const { targetPath, force } = parseAgentArgs(process.argv.slice(3));
682
- process.exit(cmdAgent(targetPath, force));
761
+ if (cmd === "skill") {
762
+ const sub = process.argv[3];
763
+ if (sub === "list") {
764
+ process.exit(cmdSkillList());
765
+ }
766
+ if (sub === "install") {
767
+ process.exit(cmdSkillInstall(process.argv.slice(4)));
768
+ }
769
+ usage();
770
+ process.exit(1);
683
771
  }
684
772
  if (cmd === "scaffold") {
685
773
  const { targetPath, format } = parseScaffoldArgs(process.argv.slice(3));
package/dist/manPage.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const MAN_PAGE_SOURCE = ".TH WFM 1 \"April 2026\" \"@workflow-manager/runner\" \"User Commands\"\n.SH NAME\nwfm \\- run markdown or json workflows from the CLI\n.SH SYNOPSIS\n.B wfm\n.I command\n[options]\n.SH DESCRIPTION\nwfm parses a workflow definition file, validates it, and executes\nit with deterministic in-memory orchestration.\n\nWorkflow files can be Markdown with YAML frontmatter or JSON.\n.SH COMMANDS\n.TP\n.B doctor [workflow.md|workflow.json] [--json]\nInspect host adapter setup, LLM access keys, and current adapter implementation status. When a workflow path is provided, also validate schema and runtime requirements without executing steps.\n.TP\n.B agent [path] [--force]\nCreate WFM-focused agent rules. The default path is ./AGENTS.md. Existing files are not overwritten unless --force is passed.\n.TP\n.B scaffold [path] [--format markdown|json]\nCreate a starter workflow file. Format defaults to markdown unless the output\npath ends in .json.\n.TP\n.B validate <workflow.md|workflow.json>\nValidate workflow structure and report schema errors.\n.TP\n.B run <workflow.md|workflow.json> [--input input.json] [--objective text] [--confirm list] [--auto-confirm-all] [--port number] [--verbose] [--json]\nRun the workflow with live CLI progress and optional JSON output.\n.TP\n.B approve [--url value] [--token value] [--run-id value] [--step value] [--actor value] [--note text]\nApprove the current waiting runner step through the local attach API.\n.TP\n.B resume [--url value] [--token value] [--run-id value] [--step value] [--actor value] [--note text]\nAlias for approve, intended for external resume flows.\n.TP\n.B cancel [--url value] [--token value] [--run-id value] [--step value] [--actor value] [--note text]\nCancel the current waiting runner step through the local attach API.\n.TP\n.B auth <login|whoami|logout> [--token value]\nManage remote registry authentication for CLI publish and pull flows.\n.TP\n.B publish <workflow.md|workflow.json> [--slug slug] [--title text] [--description text] [--visibility public|private] [--version label] [--tag a,b] [--draft]\nPublish a validated local workflow to the remote registry.\n.TP\n.B pull <owner/slug> [--version label] [--output path]\nDownload a remote workflow and write it to a local file.\n.TP\n.B search [query]\nSearch public workflows from the remote registry.\n.TP\n.B remote info <owner/slug>\nShow metadata and source information for a remote workflow.\n.TP\n.B man\nOpen this man page.\n.SH RUN OPTIONS\n.TP\n.B --input <path>\nJSON file merged into global workflow input state.\n.TP\n.B --objective <text>\nOverride the default run objective.\n.TP\n.B --confirm <stepA,stepB:human,...>\nProvide explicit confirmations for steps that require validation.\n.TP\n.B --auto-confirm-all\nBypass confirmation gating for all steps.\n.TP\n.B --port <number>\nBind the local attach API to a specific port. If omitted, the OS assigns a free port on 127.0.0.1.\n.TP\n.B --verbose\nStream per-step agent output and execution updates to stderr while the workflow runs.\n.TP\n.B --json\nPrint the final run result as JSON on stdout while keeping live progress on stderr.\n.TP\nHuman approval steps in an interactive terminal show an inline review prompt so they can be approved or cancelled without a separate HTTP client.\n.TP\n.B --url <value>\nRunner attach API base URL for approve, resume, or cancel commands.\n.TP\n.B --token <value>\nRunner attach API bearer token for approve, resume, or cancel commands.\n.TP\n.B --run-id <value>\nRunner id to control. If omitted, the CLI reads it from /session.\n.TP\n.B --step <value>\nOptional step key when controlling a specific waiting step.\n.TP\n.B --actor <value>\nActor name recorded in approval audit events.\n.TP\n.B --note <text>\nOptional approval or cancellation note recorded in the event payload.\n.SH EXAMPLES\n.TP\nValidate markdown workflow:\n.B wfm validate ./example-workflow.md\n.TP\nValidate json workflow:\n.B wfm validate ./example-workflow.json\n.TP\nScaffold json workflow file:\n.B wfm scaffold ./new-workflow.json --format json\n.TP\nAuthenticate with a CLI token:\n.B wfm auth login --token wm_exampletoken\n.TP\nPublish a workflow:\n.B wfm publish ./example-workflow.json --visibility public --tag example,automation\n.TP\nPull a remote workflow:\n.B wfm pull alice/remote-bunny --output ./remote-bunny.json\n.TP\nSearch the remote registry:\n.B wfm search bunny\n.TP\nRun with explicit confirmations:\n.B wfm run ./example-workflow.json --confirm discover:human,qa_gate:human\n.TP\nInspect host setup:\n.B wfm doctor\n.TP\nCheck a workflow before running it:\n.B wfm doctor ./example-workflow.json\n.TP\nCreate agent rules:\n.B wfm agent ./AGENTS.md\n.SH FILES\n.TP\n.B man/wfm.1\nThe manual page source shipped with this repository.\n.SH EXIT STATUS\n.TP\n.B 0\nSuccessful command execution.\n.TP\n.B 1\nValidation or runtime error.\n.TP\n.B 2\nRun completed in non-success terminal status.\n";
1
+ export declare const MAN_PAGE_SOURCE = ".TH WFM 1 \"April 2026\" \"@workflow-manager/runner\" \"User Commands\"\n.SH NAME\nwfm \\- run markdown or json workflows from the CLI\n.SH SYNOPSIS\n.B wfm\n.I command\n[options]\n.SH DESCRIPTION\nwfm parses a workflow definition file, validates it, and executes\nit with deterministic in-memory orchestration.\n\nWorkflow files can be Markdown with YAML frontmatter or JSON.\n.SH COMMANDS\n.TP\n.B doctor [workflow.md|workflow.json] [--json]\nInspect host adapter setup, LLM access keys, and current adapter implementation status. When a workflow path is provided, also validate schema and runtime requirements without executing steps.\n.TP\n.B skill list\nList the agent skills bundled with the npm package.\n.TP\n.B skill install [name ...] [--agent claude|opencode] [--global] [--dir path] [--all] [--force]\nInstall bundled agent skills into an agent skill directory. Defaults to the workflow-manager-cli skill and the project-level Claude Code directory (./.claude/skills). Existing skills are not overwritten unless --force is passed.\n.TP\n.B scaffold [path] [--format markdown|json]\nCreate a starter workflow file. Format defaults to markdown unless the output\npath ends in .json.\n.TP\n.B validate <workflow.md|workflow.json>\nValidate workflow structure and report schema errors.\n.TP\n.B run <workflow.md|workflow.json> [--input input.json] [--objective text] [--confirm list] [--auto-confirm-all] [--port number] [--verbose] [--json]\nRun the workflow with live CLI progress and optional JSON output.\n.TP\n.B approve [--url value] [--token value] [--run-id value] [--step value] [--actor value] [--note text]\nApprove the current waiting runner step through the local attach API.\n.TP\n.B resume [--url value] [--token value] [--run-id value] [--step value] [--actor value] [--note text]\nAlias for approve, intended for external resume flows.\n.TP\n.B cancel [--url value] [--token value] [--run-id value] [--step value] [--actor value] [--note text]\nCancel the current waiting runner step through the local attach API.\n.TP\n.B auth <login|whoami|logout> [--token value]\nManage remote registry authentication for CLI publish and pull flows.\n.TP\n.B publish <workflow.md|workflow.json> [--slug slug] [--title text] [--description text] [--visibility public|private] [--version label] [--tag a,b] [--draft]\nPublish a validated local workflow to the remote registry.\n.TP\n.B pull <owner/slug> [--version label] [--output path]\nDownload a remote workflow and write it to a local file.\n.TP\n.B search [query]\nSearch public workflows from the remote registry.\n.TP\n.B remote info <owner/slug>\nShow metadata and source information for a remote workflow.\n.TP\n.B man\nOpen this man page.\n.SH RUN OPTIONS\n.TP\n.B --input <path>\nJSON file merged into global workflow input state.\n.TP\n.B --objective <text>\nOverride the default run objective.\n.TP\n.B --confirm <stepA,stepB:human,...>\nProvide explicit confirmations for steps that require validation.\n.TP\n.B --auto-confirm-all\nBypass confirmation gating for all steps.\n.TP\n.B --port <number>\nBind the local attach API to a specific port. If omitted, the OS assigns a free port on 127.0.0.1.\n.TP\n.B --verbose\nStream per-step agent output and execution updates to stderr while the workflow runs.\n.TP\n.B --json\nPrint the final run result as JSON on stdout while keeping live progress on stderr.\n.TP\nHuman approval steps in an interactive terminal show an inline review prompt so they can be approved or cancelled without a separate HTTP client.\n.TP\n.B --url <value>\nRunner attach API base URL for approve, resume, or cancel commands.\n.TP\n.B --token <value>\nRunner attach API bearer token for approve, resume, or cancel commands.\n.TP\n.B --run-id <value>\nRunner id to control. If omitted, the CLI reads it from /session.\n.TP\n.B --step <value>\nOptional step key when controlling a specific waiting step.\n.TP\n.B --actor <value>\nActor name recorded in approval audit events.\n.TP\n.B --note <text>\nOptional approval or cancellation note recorded in the event payload.\n.SH EXAMPLES\n.TP\nValidate markdown workflow:\n.B wfm validate ./example-workflow.md\n.TP\nValidate json workflow:\n.B wfm validate ./example-workflow.json\n.TP\nScaffold json workflow file:\n.B wfm scaffold ./new-workflow.json --format json\n.TP\nAuthenticate with a CLI token:\n.B wfm auth login --token wm_exampletoken\n.TP\nPublish a workflow:\n.B wfm publish ./example-workflow.json --visibility public --tag example,automation\n.TP\nPull a remote workflow:\n.B wfm pull alice/remote-bunny --output ./remote-bunny.json\n.TP\nSearch the remote registry:\n.B wfm search bunny\n.TP\nRun with explicit confirmations:\n.B wfm run ./example-workflow.json --confirm discover:human,qa_gate:human\n.TP\nInspect host setup:\n.B wfm doctor\n.TP\nCheck a workflow before running it:\n.B wfm doctor ./example-workflow.json\n.TP\nInstall the bundled CLI skill for Claude Code:\n.B wfm skill install\n.TP\nInstall every bundled skill globally:\n.B wfm skill install --all --global\n.SH FILES\n.TP\n.B man/wfm.1\nThe manual page source shipped with this repository.\n.SH EXIT STATUS\n.TP\n.B 0\nSuccessful command execution.\n.TP\n.B 1\nValidation or runtime error.\n.TP\n.B 2\nRun completed in non-success terminal status.\n";
package/dist/manPage.js CHANGED
@@ -15,8 +15,11 @@ Workflow files can be Markdown with YAML frontmatter or JSON.
15
15
  .B doctor [workflow.md|workflow.json] [--json]
16
16
  Inspect host adapter setup, LLM access keys, and current adapter implementation status. When a workflow path is provided, also validate schema and runtime requirements without executing steps.
17
17
  .TP
18
- .B agent [path] [--force]
19
- Create WFM-focused agent rules. The default path is ./AGENTS.md. Existing files are not overwritten unless --force is passed.
18
+ .B skill list
19
+ List the agent skills bundled with the npm package.
20
+ .TP
21
+ .B skill install [name ...] [--agent claude|opencode] [--global] [--dir path] [--all] [--force]
22
+ Install bundled agent skills into an agent skill directory. Defaults to the workflow-manager-cli skill and the project-level Claude Code directory (./.claude/skills). Existing skills are not overwritten unless --force is passed.
20
23
  .TP
21
24
  .B scaffold [path] [--format markdown|json]
22
25
  Create a starter workflow file. Format defaults to markdown unless the output
@@ -128,8 +131,11 @@ Inspect host setup:
128
131
  Check a workflow before running it:
129
132
  .B wfm doctor ./example-workflow.json
130
133
  .TP
131
- Create agent rules:
132
- .B wfm agent ./AGENTS.md
134
+ Install the bundled CLI skill for Claude Code:
135
+ .B wfm skill install
136
+ .TP
137
+ Install every bundled skill globally:
138
+ .B wfm skill install --all --global
133
139
  .SH FILES
134
140
  .TP
135
141
  .B man/wfm.1
package/man/wfm.1 CHANGED
@@ -15,8 +15,11 @@ Workflow files can be Markdown with YAML frontmatter or JSON.
15
15
  .B doctor [workflow.md|workflow.json] [--json]
16
16
  Inspect host adapter setup, LLM access keys, and current adapter implementation status. When a workflow path is provided, also validate schema and runtime requirements without executing steps.
17
17
  .TP
18
- .B agent [path] [--force]
19
- Create WFM-focused agent rules. The default path is ./AGENTS.md. Existing files are not overwritten unless --force is passed.
18
+ .B skill list
19
+ List the agent skills bundled with the npm package.
20
+ .TP
21
+ .B skill install [name ...] [--agent claude|opencode] [--global] [--dir path] [--all] [--force]
22
+ Install bundled agent skills into an agent skill directory. Defaults to the workflow-manager-cli skill and the project-level Claude Code directory (./.claude/skills). Existing skills are not overwritten unless --force is passed.
20
23
  .TP
21
24
  .B scaffold [path] [--format markdown|json]
22
25
  Create a starter workflow file. Format defaults to markdown unless the output
@@ -128,8 +131,11 @@ Inspect host setup:
128
131
  Check a workflow before running it:
129
132
  .B wfm doctor ./example-workflow.json
130
133
  .TP
131
- Create agent rules:
132
- .B wfm agent ./AGENTS.md
134
+ Install the bundled CLI skill for Claude Code:
135
+ .B wfm skill install
136
+ .TP
137
+ Install every bundled skill globally:
138
+ .B wfm skill install --all --global
133
139
  .SH FILES
134
140
  .TP
135
141
  .B man/wfm.1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workflow-manager/runner",
3
- "version": "0.3.0",
3
+ "version": "0.4.0",
4
4
  "description": "CLI runner for in-memory and markdown workflow orchestration using ATEP-like envelopes",
5
5
  "repository": {
6
6
  "type": "git",
package/skills/README.md CHANGED
@@ -18,7 +18,21 @@ Install the main package in the project where you want the CLI and skill availab
18
18
  npm install @workflow-manager/runner
19
19
  ```
20
20
 
21
- Then use TanStack Intent to discover and map the shipped skill into your agent configuration:
21
+ Then install bundled skills into an agent's skill directory with the CLI:
22
+
23
+ ```bash
24
+ wfm skill list # list bundled skills
25
+ wfm skill install # workflow-manager-cli -> ./.claude/skills/
26
+ wfm skill install --global # -> ~/.claude/skills/
27
+ wfm skill install --agent opencode # -> ./.opencode/skill/
28
+ wfm skill install --all # install every bundled skill
29
+ wfm skill install <name> --dir path # install into any directory
30
+ ```
31
+
32
+ `wfm skill install` copies the skill directory (`SKILL.md` plus any assets) into the
33
+ target so the agent loads it on demand; pass `--force` to overwrite an existing install.
34
+
35
+ Alternatively, use TanStack Intent to discover and map the shipped skills into your agent configuration:
22
36
 
23
37
  ```bash
24
38
  npx @tanstack/intent@latest list
@@ -1,116 +1,181 @@
1
1
  ---
2
- name: @workflow-manager/runner/cli
2
+ name: workflow-manager-cli
3
3
  description: >
4
- Load this skill when working with the wfm CLI from @workflow-manager/runner, authoring or
5
- validating workflow definitions, configuring step skills and adapters, or
6
- publishing workflows to the remote registry. Covers doctor, agent, scaffold,
7
- validate, run, auth, publish, pull, search, and remote info.
4
+ Load this skill when working with the wfm CLI from @workflow-manager/runner:
5
+ authoring, validating, or running workflow definitions, configuring adapters
6
+ and step skills, controlling runs through the attach API, or publishing
7
+ workflows to the remote registry. Covers doctor, skill, scaffold, validate,
8
+ run, approve, resume, cancel, auth, publish, pull, search, and remote info.
8
9
  type: core
9
- library: @workflow-manager/runner
10
- library_version: "0.1.0"
10
+ library: "@workflow-manager/runner"
11
11
  sources:
12
12
  - "navio/workflow-manager:README.md"
13
13
  - "navio/workflow-manager:src/index.ts"
14
14
  - "navio/workflow-manager:src/parser.ts"
15
15
  - "navio/workflow-manager:src/engine.ts"
16
+ - "navio/workflow-manager:src/runtimePreflight.ts"
17
+ - "navio/workflow-manager:src/skillResolver.ts"
16
18
  - "navio/workflow-manager:src/remote/commands.ts"
19
+ - "navio/workflow-manager:doc/guide/runner-api.md"
17
20
  ---
18
21
 
19
22
  # wfm CLI
20
23
 
21
- Use this skill when you need to create or operate `workflow-manager` workflows from the terminal with `wfm`.
24
+ `wfm` (also installed as `workflow-manager`) parses a workflow definition file (Markdown frontmatter or JSON), validates it, and executes its steps through pluggable agent adapters with deterministic dependency ordering, approvals, retries, and rollback routing.
22
25
 
23
- ## When to use this skill
26
+ ## Core flow
24
27
 
25
- Use it when the user wants to:
28
+ Follow this sequence unless the user asks for a narrower task:
26
29
 
27
- - scaffold a new workflow definition
28
- - create local agent rules for WFM usage
29
- - validate or run a workflow file
30
- - configure approvals, retry policy, or adapter initialization
31
- - publish a workflow to the remote registry
32
- - search for or pull a shared workflow
33
- - understand the difference between Markdown and JSON workflow formats
30
+ 1. `wfm doctor` inspect host adapter binaries and provider API keys.
31
+ 2. `wfm scaffold ./workflow.md` (or `--format json`) — generate a starter definition.
32
+ 3. Edit step keys, objectives, `dependsOn`, validation modes, and `taskSpec.init`.
33
+ 4. `wfm validate ./workflow.md` always validate before running or publishing.
34
+ 5. `wfm doctor ./workflow.md` preflight the specific workflow before real adapter runs.
35
+ 6. `wfm run ./workflow.md` execute with live progress; add `--verbose` for agent output.
36
+ 7. `wfm publish ./workflow.md` only after validation succeeds.
34
37
 
35
- ## Core workflow
38
+ ## Command reference
36
39
 
37
- Use this sequence unless the user asks for a narrower task:
40
+ ```bash
41
+ wfm doctor [workflow] [--json] # host + per-workflow preflight checks
42
+ wfm skill list # list skills bundled with the npm package
43
+ wfm skill install [name ...] # install bundled skills for an agent (see below)
44
+ wfm scaffold [path] [--format markdown|json]
45
+ wfm validate <workflow>
46
+ wfm run <workflow> [--input input.json] [--objective "text"] [--confirm stepA,stepB:human] [--auto-confirm-all] [--port 43121] [--verbose] [--json]
47
+ wfm approve|resume|cancel [--url ...] [--token ...] [--run-id ...] [--step ...] [--actor ...] [--note ...]
48
+ wfm auth <login|whoami|logout> [--token <token>]
49
+ wfm publish <workflow> [--slug s] [--title t] [--description d] [--visibility public|private] [--version v] [--tag a,b] [--draft]
50
+ wfm pull <owner/slug> [--version v] [--output path]
51
+ wfm search [query]
52
+ wfm remote info <owner/slug>
53
+ wfm man
54
+ ```
38
55
 
39
- 1. Inspect local setup with `wfm doctor`
40
- 2. Create project agent rules with `wfm agent` when local agent guidance is useful
41
- 3. Scaffold a starter file with `wfm scaffold`
42
- 4. Edit the workflow definition
43
- 5. Validate the file with `wfm validate`
44
- 6. Execute it with `wfm run`
45
- 7. If needed, authenticate and publish with the remote registry commands
56
+ Exit codes: `0` success, `1` validation or runtime error, `2` run finished in a non-success terminal status.
46
57
 
47
- ## Local workflow commands
58
+ ## Host configuration
48
59
 
49
- ```bash
50
- wfm doctor
51
- wfm agent ./AGENTS.md
60
+ Adapters (set per step via `taskSpec.adapterKey`; omit for the default):
52
61
 
53
- wfm scaffold ./example-workflow.md
54
- wfm scaffold ./example-workflow.json --format json
62
+ | Adapter | Kind | Notes |
63
+ | --- | --- | --- |
64
+ | `pi-agent` | real (default) | Drives the host `pi` coding agent CLI in print mode. `pi` must be on `PATH`; its auth lives in `~/.pi`, not env vars. |
65
+ | `opencode` | real (opt-in) | Requires the `opencode` CLI on `PATH`. |
66
+ | `claude-code` | real (opt-in) | Requires the `claude` CLI on `PATH`. |
67
+ | `codex` | mock-routed | Deterministic simulation. |
68
+ | `mock` | mock | Deterministic simulation for tests and examples. |
55
69
 
56
- wfm validate ./example-workflow.md
57
- wfm validate ./example-workflow.json
70
+ Provider API keys are inferred from `taskSpec.init.model` and checked by `wfm doctor` / run preflight:
58
71
 
59
- wfm run ./example-workflow.md --confirm discover,qa_gate:human
60
- wfm run ./example-workflow.json --auto-confirm-all
61
- ```
72
+ - `openrouter/...` `OPENROUTER_API_KEY`
73
+ - `openai/...`, `gpt-...` → `OPENAI_API_KEY`
74
+ - `anthropic/...`, `claude-...` → `ANTHROPIC_API_KEY`
62
75
 
63
- ## Remote registry commands
76
+ Steps can also declare extra required env vars in `taskSpec.payload.requiredEnv`.
64
77
 
65
- ```bash
66
- wfm auth login --token <token>
67
- wfm auth whoami
68
- wfm auth logout
78
+ For custom `pi-agent` commands, the run directory exposes `input.json` / `output.json` envelopes through the `WFM_PI_INPUT_FILE` and `WFM_PI_OUTPUT_FILE` env vars.
69
79
 
70
- wfm search bunny
71
- wfm remote info alice/remote-bunny
72
- wfm publish ./example-workflow.json --visibility public --tag storytelling,example
73
- wfm pull alice/remote-bunny --output ./remote-bunny.json
80
+ ## Workflow anatomy
81
+
82
+ Both formats describe the same schema; Markdown holds it in YAML frontmatter (body text is free-form notes), JSON holds it directly. Required top-level fields: `key`, `title`, `steps`. Optional: `description`, `objectives`, `inputSchema`, `outputSchema`, `defaultRetryPolicy`, `skills`.
83
+
84
+ ```yaml
85
+ ---
86
+ key: my-workflow # stable external identifier — change cautiously
87
+ title: My Workflow
88
+ objectives: [deliver a working implementation]
89
+ defaultRetryPolicy:
90
+ maxAttempts: 2
91
+ steps:
92
+ - key: discover # stable step key
93
+ kind: task # task | approval
94
+ objective: Understand requirements and constraints
95
+ dependsOn: []
96
+ validation: # mode: none | human | external
97
+ mode: human
98
+ required: true
99
+ autoConfirm: false
100
+ taskSpec:
101
+ # adapterKey omitted -> pi-agent
102
+ init:
103
+ context: { repo: example/repo }
104
+ skills: [architecture, planning] # resolved step skills, see below
105
+ mcps: [mcp://github]
106
+ systemPrompts: [Focus on architecture trade-offs]
107
+ model: openrouter/anthropic/claude-sonnet-4
108
+ payload: {}
109
+ - key: qa_gate
110
+ kind: approval # human checkpoint, no adapter
111
+ dependsOn: [discover]
112
+ approvalSpec:
113
+ autoApprove: false
114
+ validation: { mode: human, required: true, autoConfirm: false }
115
+ ---
74
116
  ```
75
117
 
76
- ## Skill guidance
118
+ Authoring rules:
119
+
120
+ - Workflow keys, step keys, and status strings are stable external identifiers; prefer additive, backward-compatible changes.
121
+ - Make `dependsOn` explicit; the engine resolves dependencies deterministically and rejects cycles.
122
+ - Keep validation modes explicit per step. `human` pauses for approval (inline terminal prompt or attach API); `external` expects an outside system to resume the run.
123
+ - Use `adapterKey: mock` for deterministic examples and tests; use Markdown when humans will review notes, JSON for machine-generated definitions.
124
+
125
+ Steps communicate via ATEP-like envelopes: an `InputEnvelope` (global/step context plus priming config) goes in, an `OutputEnvelope` comes out carrying execution status and a QA routing action — `PROCEED`, `RETRY_CURRENT`, `ROLLBACK_PREVIOUS`, or `RESTART_ALL` — which the engine uses to advance, retry, roll back, or restart the run.
77
126
 
78
- - Prefer `validate` before `run` or `publish`
79
- - Keep `runWorkflow(...)` behavior registry-agnostic; registry operations belong in the CLI remote commands
80
- - Use Markdown workflows when the user wants editable frontmatter plus notes
81
- - Use JSON workflows when the user wants machine-generated or strongly structured files
82
- - Use `--auto-confirm-all` only when the workflow is intentionally non-interactive
83
- - When publishing, preserve the source format the user authored
127
+ ## Step skills
84
128
 
85
- ## Workflow authoring checklist
129
+ `taskSpec.init.skills` names are resolved per step in this order:
86
130
 
87
- - Set stable `key` and `title` values
88
- - Define clear step `objective` text
89
- - Add `dependsOn` relationships explicitly
90
- - Set validation mode per step (`none`, `human`, `external`)
91
- - Configure adapter initialization under `taskSpec.init`
92
- - Use stable step keys because tests and docs may refer to them
131
+ 1. Embedded `skills.<name>.content` in the workflow file (how published workflows ship skills).
132
+ 2. `skills.<name>.source` a relative path that must match `skills/**/SKILL.md` under the workflow directory.
133
+ 3. `<workflow-dir>/skills/<name>/SKILL.md` (project-local).
134
+ 4. `~/.workflow-manager/skills/<name>/SKILL.md` (user-global).
135
+ 5. The npm-packaged skills under `node_modules`.
93
136
 
94
- ## Adapter and validation notes
137
+ `wfm publish` inlines resolved skill markdown into `skills[*].content` with a `contentSha256` integrity hash; pulled workflows are rejected when declared skill content is missing or tampered.
95
138
 
96
- - Supported adapters include default `pi-agent` plus explicit `mock`, `opencode`, `codex`, and `claude-code`
97
- - Omit `taskSpec.adapterKey` to run a task with the `pi` coding agent CLI
98
- - Put skills, MCP endpoints, system prompts, model, and context under `taskSpec.init`
99
- - Human approvals should stay explicit in workflow definitions
100
- - External validation should be deterministic where possible
101
- - Use the mock adapter for fast tests and scaffolding flows
139
+ ## Running and controlling runs
102
140
 
103
- ## Recommended project references
141
+ `wfm run` shows live progress on stderr and starts a local attach API on `127.0.0.1` for the lifetime of the run (OS-assigned port, or `--port`). The base URL and a per-run bearer token are printed to stderr before execution starts; every endpoint except `/health` requires `Authorization: Bearer <token>`. The API serves the session (`/session`), run snapshots, per-step detail, logs, an SSE event stream, and approve/resume/cancel endpoints (contract: `doc/guide/runner-api.md`).
104
142
 
105
- - `src/index.ts`: CLI command entrypoint
106
- - `src/parser.ts`: Markdown and JSON parsing plus validation
107
- - `src/engine.ts`: orchestration loop
108
- - `src/remote/commands.ts`: auth, publish, pull, search, and remote info commands
109
- - `tests/`: unit and e2e coverage for workflow behavior
143
+ - Interactive human approvals show an inline terminal prompt; non-interactive waits are resolved via `wfm approve` / `wfm resume` / `wfm cancel` using the printed URL and token.
144
+ - `--confirm stepA,stepB:human` pre-supplies confirmations for specific steps.
145
+ - Never use `--auto-confirm-all` unless the workflow is intentionally non-interactive — it bypasses every approval gate.
146
+ - `--json` prints the final result (including a `session` object) on stdout while progress stays on stderr.
147
+ - `--input input.json` merges a JSON file into global input state; `--objective` overrides the run objective.
148
+
149
+ ## Remote registry
150
+
151
+ ```bash
152
+ wfm auth login --token <token> # token created in the registry web app
153
+ wfm auth whoami
154
+ wfm search <query>
155
+ wfm remote info <owner/slug>
156
+ wfm publish ./workflow.md --visibility public --tag automation
157
+ wfm pull <owner/slug> --output ./pulled-workflow.json
158
+ ```
159
+
160
+ If `publish` fails, check login state with `wfm auth whoami`. Preserve the author's source format when publishing.
161
+
162
+ ## Installing these skills for agents
163
+
164
+ `wfm skill install` copies bundled skills into an agent's skill directory so the agent loads this guidance on demand:
165
+
166
+ ```bash
167
+ wfm skill list # see what ships with the package
168
+ wfm skill install # workflow-manager-cli -> ./.claude/skills/
169
+ wfm skill install --global # -> ~/.claude/skills/
170
+ wfm skill install --agent opencode # -> ./.opencode/skill/
171
+ wfm skill install --all --force # every bundled skill, overwrite existing
172
+ wfm skill install doc-sync --dir ./my/skills # any other destination
173
+ ```
110
174
 
111
- ## Typical troubleshooting
175
+ ## Troubleshooting
112
176
 
113
- - If validation fails, inspect the reported schema or dependency error before running again
114
- - If `publish` fails, confirm the user is logged in with `wfm auth whoami`
115
- - If remote calls fail in the browser, verify the remote registry app has valid Supabase `VITE_*` environment variables
116
- - If a real adapter test fails, confirm the underlying external CLI is installed and available on `PATH`
177
+ - Validation failure: fix the reported schema or dependency-cycle error before re-running; ordinary input errors are reported as messages, not stack traces.
178
+ - `doctor` failure for a real adapter: install the missing CLI (`pi`, `opencode`, `claude`) or export the missing provider API key.
179
+ - Run stuck `waiting_for_approval`: approve inline in the terminal, or use `wfm approve` with the attach URL/token printed at run start.
180
+ - Non-zero exit `2`: the run completed but not successfully re-run with `--json` or `--verbose` to inspect step output.
181
+ - Publish/pull failures: verify `wfm auth whoami`; for skill integrity errors, confirm the declared skill files exist and match their `contentSha256`.