@workflow-manager/runner 0.1.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 +196 -0
- package/dist/engine.d.ts +2 -0
- package/dist/engine.js +217 -0
- package/dist/events.d.ts +7 -0
- package/dist/events.js +21 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +413 -0
- package/dist/mockExecutor.d.ts +2 -0
- package/dist/mockExecutor.js +110 -0
- package/dist/opencodeExecutor.d.ts +3 -0
- package/dist/opencodeExecutor.js +174 -0
- package/dist/parser.d.ts +5 -0
- package/dist/parser.js +101 -0
- package/dist/remote/api.d.ts +99 -0
- package/dist/remote/api.js +81 -0
- package/dist/remote/commands.d.ts +8 -0
- package/dist/remote/commands.js +183 -0
- package/dist/remote/config.d.ts +8 -0
- package/dist/remote/config.js +39 -0
- package/dist/remote/telemetry.d.ts +12 -0
- package/dist/remote/telemetry.js +69 -0
- package/dist/remote/types.d.ts +7 -0
- package/dist/remote/types.js +1 -0
- package/dist/types.d.ts +122 -0
- package/dist/types.js +1 -0
- package/man/wfm.1 +96 -0
- package/package.json +65 -0
- package/skills/README.md +63 -0
- package/skills/workflow-manager-cli/README.md +11 -0
- package/skills/workflow-manager-cli/SKILL.md +111 -0
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import os from "node:os";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
function configRoot() {
|
|
5
|
+
const override = process.env.WORKFLOW_MANAGER_CONFIG_DIR;
|
|
6
|
+
if (override) {
|
|
7
|
+
return override;
|
|
8
|
+
}
|
|
9
|
+
if (process.platform === "win32") {
|
|
10
|
+
return path.join(process.env.APPDATA ?? path.join(os.homedir(), "AppData", "Roaming"), "workflow-manager");
|
|
11
|
+
}
|
|
12
|
+
return path.join(os.homedir(), ".config", "workflow-manager");
|
|
13
|
+
}
|
|
14
|
+
export function configFilePath() {
|
|
15
|
+
return path.join(configRoot(), "config.json");
|
|
16
|
+
}
|
|
17
|
+
export function loadRemoteConfig() {
|
|
18
|
+
const filePath = configFilePath();
|
|
19
|
+
if (!fs.existsSync(filePath)) {
|
|
20
|
+
return {};
|
|
21
|
+
}
|
|
22
|
+
const raw = fs.readFileSync(filePath, "utf-8");
|
|
23
|
+
const parsed = JSON.parse(raw);
|
|
24
|
+
return typeof parsed === "object" && parsed ? parsed : {};
|
|
25
|
+
}
|
|
26
|
+
export function saveRemoteConfig(config) {
|
|
27
|
+
const filePath = configFilePath();
|
|
28
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
29
|
+
fs.writeFileSync(filePath, `${JSON.stringify(config, null, 2)}\n`, "utf-8");
|
|
30
|
+
}
|
|
31
|
+
export function clearRemoteConfig() {
|
|
32
|
+
const filePath = configFilePath();
|
|
33
|
+
if (fs.existsSync(filePath)) {
|
|
34
|
+
fs.rmSync(filePath);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export function resolveAuthToken() {
|
|
38
|
+
return process.env.WORKFLOW_MANAGER_TOKEN ?? loadRemoteConfig().token;
|
|
39
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RunResult, WorkflowDefinition } from "../types.js";
|
|
2
|
+
import { type RunTelemetryPayload } from "./api.js";
|
|
3
|
+
interface RunTelemetryOptions {
|
|
4
|
+
definition: WorkflowDefinition;
|
|
5
|
+
sourceFilePath: string;
|
|
6
|
+
durationMs: number;
|
|
7
|
+
result?: RunResult;
|
|
8
|
+
failureReason?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare function buildRunTelemetryPayload(options: RunTelemetryOptions): RunTelemetryPayload;
|
|
11
|
+
export declare function emitRunTelemetryBestEffort(options: RunTelemetryOptions): Promise<void>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { resolveAuthToken } from "./config.js";
|
|
4
|
+
import { trackRunTelemetry } from "./api.js";
|
|
5
|
+
function workflowSourceFormat(filePath) {
|
|
6
|
+
return path.extname(filePath).toLowerCase() === ".json" ? "json" : "markdown";
|
|
7
|
+
}
|
|
8
|
+
function cliVersion() {
|
|
9
|
+
try {
|
|
10
|
+
const packagePath = path.resolve(process.cwd(), "package.json");
|
|
11
|
+
const parsed = JSON.parse(fs.readFileSync(packagePath, "utf-8"));
|
|
12
|
+
return typeof parsed.version === "string" ? parsed.version : null;
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export function buildRunTelemetryPayload(options) {
|
|
19
|
+
const { definition, sourceFilePath, durationMs, result, failureReason } = options;
|
|
20
|
+
const stepRuns = result?.stepRuns ?? [];
|
|
21
|
+
const succeededSteps = stepRuns.filter((step) => step.status === "succeeded").length;
|
|
22
|
+
const failedSteps = stepRuns.filter((step) => step.status === "failed").length;
|
|
23
|
+
const waitingSteps = stepRuns.filter((step) => step.status === "waiting_for_approval").length;
|
|
24
|
+
const cancelledSteps = stepRuns.filter((step) => step.status === "cancelled").length;
|
|
25
|
+
const retriedSteps = stepRuns.reduce((sum, step) => sum + Math.max(step.attempt - 1, 0), 0);
|
|
26
|
+
const totalSteps = definition.steps.length;
|
|
27
|
+
const successRatio = totalSteps === 0 ? 0 : succeededSteps / totalSteps;
|
|
28
|
+
const retryPenalty = totalSteps === 0 ? 0 : Math.min(retriedSteps / totalSteps, 1) * 20;
|
|
29
|
+
const waitingPenalty = waitingSteps > 0 ? 15 : 0;
|
|
30
|
+
const failurePenalty = failedSteps > 0 ? 35 : 0;
|
|
31
|
+
const effectivenessScore = Math.max(0, Math.min(100, Math.round(successRatio * 100 - retryPenalty - waitingPenalty - failurePenalty)));
|
|
32
|
+
const terminalState = (result?.status ?? "failed");
|
|
33
|
+
return {
|
|
34
|
+
workflowKey: definition.key,
|
|
35
|
+
workflowTitle: definition.title,
|
|
36
|
+
runId: result?.runId ?? `failed-preflight:${definition.key}`,
|
|
37
|
+
terminalState,
|
|
38
|
+
totalSteps,
|
|
39
|
+
succeededSteps,
|
|
40
|
+
failedSteps,
|
|
41
|
+
waitingSteps,
|
|
42
|
+
cancelledSteps,
|
|
43
|
+
retriedSteps,
|
|
44
|
+
eventCount: result?.events.length ?? 0,
|
|
45
|
+
durationMs,
|
|
46
|
+
effectivenessScore,
|
|
47
|
+
outputKeys: Object.keys(result?.outputs ?? {}),
|
|
48
|
+
sourceName: path.basename(sourceFilePath),
|
|
49
|
+
sourceFormat: workflowSourceFormat(sourceFilePath),
|
|
50
|
+
cliVersion: cliVersion(),
|
|
51
|
+
failureReason: failureReason ?? (terminalState === "failed" ? "run failed" : null),
|
|
52
|
+
metadata: {
|
|
53
|
+
workflowObjectives: definition.objectives ?? [],
|
|
54
|
+
stepKeys: definition.steps.map((step) => step.key),
|
|
55
|
+
outputCount: Object.keys(result?.outputs ?? {}).length,
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
export async function emitRunTelemetryBestEffort(options) {
|
|
60
|
+
if (!resolveAuthToken()) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
await trackRunTelemetry(buildRunTelemetryPayload(options));
|
|
65
|
+
}
|
|
66
|
+
catch (error) {
|
|
67
|
+
console.warn(`Telemetry warning: ${error.message}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
export type WorkflowRunStatus = "queued" | "running" | "waiting_for_approval" | "paused" | "succeeded" | "failed" | "cancelled";
|
|
2
|
+
export type StepRunStatus = "pending" | "runnable" | "running" | "waiting_for_approval" | "succeeded" | "failed" | "cancelled";
|
|
3
|
+
export type StepKind = "task" | "approval" | "system";
|
|
4
|
+
export type NodeType = "AGENT" | "HUMAN" | "SYSTEM";
|
|
5
|
+
export type ExecutionStatus = "SUCCESS" | "QA_REJECTED" | "YIELD_EXTERNAL" | "FAILED";
|
|
6
|
+
export type QaAction = "PROCEED" | "RETRY_CURRENT" | "ROLLBACK_PREVIOUS" | "RESTART_ALL";
|
|
7
|
+
export type ValidationMode = "none" | "human" | "external";
|
|
8
|
+
export type AdapterKey = "mock" | "opencode" | "codex" | "claude-code";
|
|
9
|
+
export interface RetryPolicy {
|
|
10
|
+
maxAttempts?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface ValidationSpec {
|
|
13
|
+
mode?: ValidationMode;
|
|
14
|
+
required?: boolean;
|
|
15
|
+
autoConfirm?: boolean;
|
|
16
|
+
confirmerPolicy?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface TaskInitConfig {
|
|
19
|
+
context?: Record<string, unknown> | string;
|
|
20
|
+
skills?: string[];
|
|
21
|
+
mcps?: string[];
|
|
22
|
+
systemPrompts?: string[];
|
|
23
|
+
model?: string;
|
|
24
|
+
}
|
|
25
|
+
export interface StepDefinition {
|
|
26
|
+
key: string;
|
|
27
|
+
kind: StepKind;
|
|
28
|
+
title?: string;
|
|
29
|
+
objective?: string;
|
|
30
|
+
dependsOn?: string[];
|
|
31
|
+
timeoutSec?: number;
|
|
32
|
+
retryPolicy?: RetryPolicy;
|
|
33
|
+
validation?: ValidationSpec;
|
|
34
|
+
taskSpec?: {
|
|
35
|
+
adapterKey?: AdapterKey;
|
|
36
|
+
capabilityRequirements?: string[];
|
|
37
|
+
init?: TaskInitConfig;
|
|
38
|
+
payload?: Record<string, unknown>;
|
|
39
|
+
};
|
|
40
|
+
approvalSpec?: {
|
|
41
|
+
approverPolicy?: string;
|
|
42
|
+
autoApprove?: boolean;
|
|
43
|
+
validation?: ValidationSpec;
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export interface WorkflowDefinition {
|
|
47
|
+
key: string;
|
|
48
|
+
title: string;
|
|
49
|
+
description?: string;
|
|
50
|
+
objectives?: string[];
|
|
51
|
+
inputSchema?: Record<string, unknown>;
|
|
52
|
+
outputSchema?: Record<string, unknown>;
|
|
53
|
+
defaultRetryPolicy?: RetryPolicy;
|
|
54
|
+
steps: StepDefinition[];
|
|
55
|
+
}
|
|
56
|
+
export interface InputEnvelope {
|
|
57
|
+
global_context: {
|
|
58
|
+
workflow_id: string;
|
|
59
|
+
primary_objective: string;
|
|
60
|
+
workflow_objectives: string[];
|
|
61
|
+
global_state: Record<string, unknown>;
|
|
62
|
+
};
|
|
63
|
+
step_context: {
|
|
64
|
+
step_id: string;
|
|
65
|
+
step_objective: string;
|
|
66
|
+
previous_output: Record<string, unknown>;
|
|
67
|
+
assigned_node_type: NodeType;
|
|
68
|
+
};
|
|
69
|
+
priming_configuration: {
|
|
70
|
+
required_skills: string[];
|
|
71
|
+
mcp_endpoints: string[];
|
|
72
|
+
system_prompts: string[];
|
|
73
|
+
context?: Record<string, unknown> | string;
|
|
74
|
+
adapter?: AdapterKey;
|
|
75
|
+
model?: string;
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
export interface OutputEnvelope {
|
|
79
|
+
step_id: string;
|
|
80
|
+
execution_status: ExecutionStatus;
|
|
81
|
+
qa_routing: {
|
|
82
|
+
action: QaAction;
|
|
83
|
+
feedback_reason: string;
|
|
84
|
+
};
|
|
85
|
+
mutated_payload: Record<string, unknown>;
|
|
86
|
+
metadata: {
|
|
87
|
+
execution_time_ms: number;
|
|
88
|
+
external_intervention_required: boolean;
|
|
89
|
+
intervention_details?: Record<string, unknown>;
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
export interface StepRun {
|
|
93
|
+
stepKey: string;
|
|
94
|
+
status: StepRunStatus;
|
|
95
|
+
attempt: number;
|
|
96
|
+
confirmed: boolean;
|
|
97
|
+
output?: Record<string, unknown>;
|
|
98
|
+
}
|
|
99
|
+
export interface RunResult {
|
|
100
|
+
runId: string;
|
|
101
|
+
status: WorkflowRunStatus;
|
|
102
|
+
outputs: Record<string, unknown>;
|
|
103
|
+
stepRuns: StepRun[];
|
|
104
|
+
events: RunEvent[];
|
|
105
|
+
}
|
|
106
|
+
export interface RunOptions {
|
|
107
|
+
objective?: string;
|
|
108
|
+
input?: Record<string, unknown>;
|
|
109
|
+
actor?: string;
|
|
110
|
+
confirmations?: string[];
|
|
111
|
+
autoConfirmAll?: boolean;
|
|
112
|
+
}
|
|
113
|
+
export interface RunEvent {
|
|
114
|
+
id: string;
|
|
115
|
+
runId: string;
|
|
116
|
+
stepRunId?: string;
|
|
117
|
+
type: "run.created" | "run.started" | "run.waiting_for_approval" | "step.runnable" | "step.claimed" | "step.execution_started" | "step.execution_finished" | "step.waiting_for_approval" | "approval.resolved" | "step.retried" | "step.confirmed" | "run.completed" | "run.failed" | "run.cancelled";
|
|
118
|
+
sequenceNumber: number;
|
|
119
|
+
occurredAt: string;
|
|
120
|
+
actor: string;
|
|
121
|
+
payload: Record<string, unknown>;
|
|
122
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/man/wfm.1
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
.TH WFM 1 "April 2026" "@workflow-manager/runner" "User Commands"
|
|
2
|
+
.SH NAME
|
|
3
|
+
wfm \- run markdown or json workflows from the CLI
|
|
4
|
+
.SH SYNOPSIS
|
|
5
|
+
.B wfm
|
|
6
|
+
.I command
|
|
7
|
+
[options]
|
|
8
|
+
.SH DESCRIPTION
|
|
9
|
+
wfm parses a workflow definition file, validates it, and executes
|
|
10
|
+
it with deterministic in-memory orchestration.
|
|
11
|
+
|
|
12
|
+
Workflow files can be Markdown with YAML frontmatter or JSON.
|
|
13
|
+
.SH COMMANDS
|
|
14
|
+
.TP
|
|
15
|
+
.B questions
|
|
16
|
+
Print discovery questions used to design a workflow.
|
|
17
|
+
.TP
|
|
18
|
+
.B scaffold [path] [--format markdown|json]
|
|
19
|
+
Create a starter workflow file. Format defaults to markdown unless the output
|
|
20
|
+
path ends in .json.
|
|
21
|
+
.TP
|
|
22
|
+
.B validate <workflow.md|workflow.json>
|
|
23
|
+
Validate workflow structure and report schema errors.
|
|
24
|
+
.TP
|
|
25
|
+
.B run <workflow.md|workflow.json> [--input input.json] [--objective text] [--confirm list] [--auto-confirm-all]
|
|
26
|
+
Run the workflow and print a JSON result with events and per-step outputs.
|
|
27
|
+
.TP
|
|
28
|
+
.B auth <login|whoami|logout> [--token value]
|
|
29
|
+
Manage remote registry authentication for CLI publish and pull flows.
|
|
30
|
+
.TP
|
|
31
|
+
.B publish <workflow.md|workflow.json> [--slug slug] [--title text] [--description text] [--visibility public|private] [--version label] [--tag a,b] [--draft]
|
|
32
|
+
Publish a validated local workflow to the remote registry.
|
|
33
|
+
.TP
|
|
34
|
+
.B pull <owner/slug> [--version label] [--output path]
|
|
35
|
+
Download a remote workflow and write it to a local file.
|
|
36
|
+
.TP
|
|
37
|
+
.B search [query]
|
|
38
|
+
Search public workflows from the remote registry.
|
|
39
|
+
.TP
|
|
40
|
+
.B remote info <owner/slug>
|
|
41
|
+
Show metadata and source information for a remote workflow.
|
|
42
|
+
.TP
|
|
43
|
+
.B man
|
|
44
|
+
Open this man page.
|
|
45
|
+
.SH RUN OPTIONS
|
|
46
|
+
.TP
|
|
47
|
+
.B --input <path>
|
|
48
|
+
JSON file merged into global workflow input state.
|
|
49
|
+
.TP
|
|
50
|
+
.B --objective <text>
|
|
51
|
+
Override the default run objective.
|
|
52
|
+
.TP
|
|
53
|
+
.B --confirm <stepA,stepB:human,...>
|
|
54
|
+
Provide explicit confirmations for steps that require validation.
|
|
55
|
+
.TP
|
|
56
|
+
.B --auto-confirm-all
|
|
57
|
+
Bypass confirmation gating for all steps.
|
|
58
|
+
.SH EXAMPLES
|
|
59
|
+
.TP
|
|
60
|
+
Validate markdown workflow:
|
|
61
|
+
.B wfm validate ./example-workflow.md
|
|
62
|
+
.TP
|
|
63
|
+
Validate json workflow:
|
|
64
|
+
.B wfm validate ./example-workflow.json
|
|
65
|
+
.TP
|
|
66
|
+
Scaffold json workflow file:
|
|
67
|
+
.B wfm scaffold ./new-workflow.json --format json
|
|
68
|
+
.TP
|
|
69
|
+
Authenticate with a CLI token:
|
|
70
|
+
.B wfm auth login --token wm_exampletoken
|
|
71
|
+
.TP
|
|
72
|
+
Publish a workflow:
|
|
73
|
+
.B wfm publish ./example-workflow.json --visibility public --tag example,automation
|
|
74
|
+
.TP
|
|
75
|
+
Pull a remote workflow:
|
|
76
|
+
.B wfm pull alice/remote-bunny --output ./remote-bunny.json
|
|
77
|
+
.TP
|
|
78
|
+
Search the remote registry:
|
|
79
|
+
.B wfm search bunny
|
|
80
|
+
.TP
|
|
81
|
+
Run with explicit confirmations:
|
|
82
|
+
.B wfm run ./example-workflow.json --confirm discover:human,qa_gate:human
|
|
83
|
+
.SH FILES
|
|
84
|
+
.TP
|
|
85
|
+
.B man/wfm.1
|
|
86
|
+
The manual page source shipped with this repository.
|
|
87
|
+
.SH EXIT STATUS
|
|
88
|
+
.TP
|
|
89
|
+
.B 0
|
|
90
|
+
Successful command execution.
|
|
91
|
+
.TP
|
|
92
|
+
.B 1
|
|
93
|
+
Validation or runtime error.
|
|
94
|
+
.TP
|
|
95
|
+
.B 2
|
|
96
|
+
Run completed in non-success terminal status.
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@workflow-manager/runner",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI runner for in-memory and markdown workflow orchestration using ATEP-like envelopes",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"wfm": "dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"dist/",
|
|
15
|
+
"man/",
|
|
16
|
+
"skills/",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc -p tsconfig.json",
|
|
21
|
+
"build:bin": "bun build ./src/index.ts --compile --outfile ./dist/wfm",
|
|
22
|
+
"build:bin:macos": "bun build ./src/index.ts --compile --target bun-darwin-arm64 --outfile ./dist/wfm-macos-arm64",
|
|
23
|
+
"build:bin:linux": "bun build ./src/index.ts --compile --target bun-linux-x64 --outfile ./dist/wfm-linux-x64",
|
|
24
|
+
"build:bin:windows": "bun build ./src/index.ts --compile --target bun-windows-x64 --outfile ./dist/wfm-windows-x64.exe",
|
|
25
|
+
"build:bin:all": "bun run build:bin:macos && bun run build:bin:linux && bun run build:bin:windows",
|
|
26
|
+
"man": "man ./man/wfm.1",
|
|
27
|
+
"test:unit": "bun test tests/parser.test.ts tests/engine.test.ts tests/mockExecutor.test.ts tests/opencodeExecutor.test.ts tests/remote.test.ts tests/run-telemetry.test.ts tests/supabase-functions.test.ts tests/supabase-ops.test.ts tests/remote-registry-app.test.ts",
|
|
28
|
+
"test:e2e": "bun test tests/story-workflow.e2e.test.ts tests/opencode-real.e2e.test.ts",
|
|
29
|
+
"test:e2e:real": "WORKFLOW_MANAGER_REAL_OPENCODE=1 bun test tests/opencode-real.e2e.test.ts",
|
|
30
|
+
"test": "bun test",
|
|
31
|
+
"dev": "bun run ./src/index.ts",
|
|
32
|
+
"package:check": "npm pack --dry-run",
|
|
33
|
+
"prepack": "bun run build",
|
|
34
|
+
"supabase:start": "supabase start",
|
|
35
|
+
"supabase:stop": "supabase stop",
|
|
36
|
+
"supabase:status": "supabase status",
|
|
37
|
+
"supabase:db:reset": "supabase db reset",
|
|
38
|
+
"supabase:functions:deploy": "supabase functions deploy create-cli-token --project-ref whairnylpdvxxgbygbzu --use-api --no-verify-jwt && supabase functions deploy auth-whoami --project-ref whairnylpdvxxgbygbzu --use-api --no-verify-jwt && supabase functions deploy list-cli-tokens --project-ref whairnylpdvxxgbygbzu --use-api --no-verify-jwt && supabase functions deploy manage-workflow --project-ref whairnylpdvxxgbygbzu --use-api --no-verify-jwt && supabase functions deploy refresh-workflow-stats --project-ref whairnylpdvxxgbygbzu --use-api --no-verify-jwt && supabase functions deploy revoke-cli-token --project-ref whairnylpdvxxgbygbzu --use-api --no-verify-jwt && supabase functions deploy publish-workflow --project-ref whairnylpdvxxgbygbzu --use-api --no-verify-jwt && supabase functions deploy pull-workflow --project-ref whairnylpdvxxgbygbzu --use-api --no-verify-jwt && supabase functions deploy search-workflows --project-ref whairnylpdvxxgbygbzu --use-api --no-verify-jwt && supabase functions deploy workflow-analytics --project-ref whairnylpdvxxgbygbzu --use-api --no-verify-jwt && supabase functions deploy track-run-telemetry --project-ref whairnylpdvxxgbygbzu --use-api --no-verify-jwt && supabase functions deploy workflow-run-insights --project-ref whairnylpdvxxgbygbzu --use-api --no-verify-jwt",
|
|
39
|
+
"remote-registry:dev": "bun --cwd apps/remote-registry dev",
|
|
40
|
+
"remote-registry:build": "bun --cwd apps/remote-registry build",
|
|
41
|
+
"docs:dev": "vitepress dev doc",
|
|
42
|
+
"docs:build": "vitepress build doc",
|
|
43
|
+
"docs:preview": "vitepress preview doc"
|
|
44
|
+
},
|
|
45
|
+
"keywords": [
|
|
46
|
+
"workflow",
|
|
47
|
+
"orchestration",
|
|
48
|
+
"cli",
|
|
49
|
+
"atep",
|
|
50
|
+
"agent-skills",
|
|
51
|
+
"claude-code",
|
|
52
|
+
"opencode",
|
|
53
|
+
"tanstack-intent"
|
|
54
|
+
],
|
|
55
|
+
"license": "MIT",
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"gray-matter": "^4.0.3"
|
|
58
|
+
},
|
|
59
|
+
"devDependencies": {
|
|
60
|
+
"@types/node": "^24.6.0",
|
|
61
|
+
"bun-types": "^1.3.0",
|
|
62
|
+
"typescript": "^5.9.2",
|
|
63
|
+
"vitepress": "^1.5.0"
|
|
64
|
+
}
|
|
65
|
+
}
|
package/skills/README.md
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
# workflow-manager skills
|
|
2
|
+
|
|
3
|
+
`@workflow-manager/runner` now ships its TanStack Intent-compatible skills in the main npm package.
|
|
4
|
+
|
|
5
|
+
The first bundled skill is `workflow-manager-cli`, which teaches agents how to:
|
|
6
|
+
|
|
7
|
+
- design workflow definitions
|
|
8
|
+
- scaffold Markdown or JSON workflows
|
|
9
|
+
- validate and run workflows safely
|
|
10
|
+
- authenticate against the remote registry
|
|
11
|
+
- publish, search, and pull shared workflows
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
Install the main package in the project where you want the CLI and skill available:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @workflow-manager/runner
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Then use TanStack Intent to discover and map the shipped skill into your agent configuration:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
npx @tanstack/intent@latest list
|
|
25
|
+
npx @tanstack/intent@latest install
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Intent writes task-to-skill mappings into `AGENTS.md`-style config files and points them at the installed package path under `node_modules/@workflow-manager/runner/skills/...`.
|
|
29
|
+
|
|
30
|
+
## Packaged skill
|
|
31
|
+
|
|
32
|
+
- skill path: `skills/workflow-manager-cli/SKILL.md`
|
|
33
|
+
- package keyword: `tanstack-intent`
|
|
34
|
+
- published with: the root `@workflow-manager/runner` npm package
|
|
35
|
+
|
|
36
|
+
## Local development
|
|
37
|
+
|
|
38
|
+
From the repository root:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npm pack --dry-run
|
|
42
|
+
ls skills/workflow-manager-cli
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Publish
|
|
46
|
+
|
|
47
|
+
Publish from the repository root so the CLI runner and `skills/` ship together:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
npm publish
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Before publishing, verify the package contents:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
npm pack --dry-run
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## Package layout
|
|
60
|
+
|
|
61
|
+
- `skills/workflow-manager-cli/SKILL.md`: TanStack Intent skill entrypoint
|
|
62
|
+
- `skills/workflow-manager-cli/README.md`: local notes for contributors
|
|
63
|
+
- `package.json`: package metadata, published files, and `tanstack-intent` keyword
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# workflow-manager-cli skill
|
|
2
|
+
|
|
3
|
+
This skill ships inside the root `@workflow-manager/runner` npm package.
|
|
4
|
+
|
|
5
|
+
It is designed for TanStack Intent discovery and should stay aligned with the CLI behavior documented in:
|
|
6
|
+
|
|
7
|
+
- `README.md`
|
|
8
|
+
- `src/index.ts`
|
|
9
|
+
- `src/parser.ts`
|
|
10
|
+
- `src/engine.ts`
|
|
11
|
+
- `src/remote/commands.ts`
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: @workflow-manager/runner/cli
|
|
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 questions, scaffold,
|
|
7
|
+
validate, run, auth, publish, pull, search, and remote info.
|
|
8
|
+
type: core
|
|
9
|
+
library: @workflow-manager/runner
|
|
10
|
+
library_version: "0.1.0"
|
|
11
|
+
sources:
|
|
12
|
+
- "navio/workflow-manager:README.md"
|
|
13
|
+
- "navio/workflow-manager:src/index.ts"
|
|
14
|
+
- "navio/workflow-manager:src/parser.ts"
|
|
15
|
+
- "navio/workflow-manager:src/engine.ts"
|
|
16
|
+
- "navio/workflow-manager:src/remote/commands.ts"
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
# wfm CLI
|
|
20
|
+
|
|
21
|
+
Use this skill when you need to create or operate `workflow-manager` workflows from the terminal with `wfm`.
|
|
22
|
+
|
|
23
|
+
## When to use this skill
|
|
24
|
+
|
|
25
|
+
Use it when the user wants to:
|
|
26
|
+
|
|
27
|
+
- scaffold a new workflow definition
|
|
28
|
+
- validate or run a workflow file
|
|
29
|
+
- configure approvals, retry policy, or adapter initialization
|
|
30
|
+
- publish a workflow to the remote registry
|
|
31
|
+
- search for or pull a shared workflow
|
|
32
|
+
- understand the difference between Markdown and JSON workflow formats
|
|
33
|
+
|
|
34
|
+
## Core workflow
|
|
35
|
+
|
|
36
|
+
Use this sequence unless the user asks for a narrower task:
|
|
37
|
+
|
|
38
|
+
1. Discover the workflow intent with `wfm questions`
|
|
39
|
+
2. Scaffold a starter file with `wfm scaffold`
|
|
40
|
+
3. Edit the workflow definition
|
|
41
|
+
4. Validate the file with `wfm validate`
|
|
42
|
+
5. Execute it with `wfm run`
|
|
43
|
+
6. If needed, authenticate and publish with the remote registry commands
|
|
44
|
+
|
|
45
|
+
## Local workflow commands
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
wfm questions
|
|
49
|
+
|
|
50
|
+
wfm scaffold ./example-workflow.md
|
|
51
|
+
wfm scaffold ./example-workflow.json --format json
|
|
52
|
+
|
|
53
|
+
wfm validate ./example-workflow.md
|
|
54
|
+
wfm validate ./example-workflow.json
|
|
55
|
+
|
|
56
|
+
wfm run ./example-workflow.md --confirm discover,qa_gate:human
|
|
57
|
+
wfm run ./example-workflow.json --auto-confirm-all
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## Remote registry commands
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
wfm auth login --token <token>
|
|
64
|
+
wfm auth whoami
|
|
65
|
+
wfm auth logout
|
|
66
|
+
|
|
67
|
+
wfm search bunny
|
|
68
|
+
wfm remote info alice/remote-bunny
|
|
69
|
+
wfm publish ./example-workflow.json --visibility public --tag storytelling,example
|
|
70
|
+
wfm pull alice/remote-bunny --output ./remote-bunny.json
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Skill guidance
|
|
74
|
+
|
|
75
|
+
- Prefer `validate` before `run` or `publish`
|
|
76
|
+
- Keep `runWorkflow(...)` behavior registry-agnostic; registry operations belong in the CLI remote commands
|
|
77
|
+
- Use Markdown workflows when the user wants editable frontmatter plus notes
|
|
78
|
+
- Use JSON workflows when the user wants machine-generated or strongly structured files
|
|
79
|
+
- Use `--auto-confirm-all` only when the workflow is intentionally non-interactive
|
|
80
|
+
- When publishing, preserve the source format the user authored
|
|
81
|
+
|
|
82
|
+
## Workflow authoring checklist
|
|
83
|
+
|
|
84
|
+
- Set stable `key` and `title` values
|
|
85
|
+
- Define clear step `objective` text
|
|
86
|
+
- Add `dependsOn` relationships explicitly
|
|
87
|
+
- Set validation mode per step (`none`, `human`, `external`)
|
|
88
|
+
- Configure adapter initialization under `taskSpec.init`
|
|
89
|
+
- Use stable step keys because tests and docs may refer to them
|
|
90
|
+
|
|
91
|
+
## Adapter and validation notes
|
|
92
|
+
|
|
93
|
+
- Supported adapters include `mock`, `opencode`, `codex`, and `claude-code`
|
|
94
|
+
- Human approvals should stay explicit in workflow definitions
|
|
95
|
+
- External validation should be deterministic where possible
|
|
96
|
+
- Use the mock adapter for fast tests and scaffolding flows
|
|
97
|
+
|
|
98
|
+
## Recommended project references
|
|
99
|
+
|
|
100
|
+
- `src/index.ts`: CLI command entrypoint
|
|
101
|
+
- `src/parser.ts`: Markdown and JSON parsing plus validation
|
|
102
|
+
- `src/engine.ts`: orchestration loop
|
|
103
|
+
- `src/remote/commands.ts`: auth, publish, pull, search, and remote info commands
|
|
104
|
+
- `tests/`: unit and e2e coverage for workflow behavior
|
|
105
|
+
|
|
106
|
+
## Typical troubleshooting
|
|
107
|
+
|
|
108
|
+
- If validation fails, inspect the reported schema or dependency error before running again
|
|
109
|
+
- If `publish` fails, confirm the user is logged in with `wfm auth whoami`
|
|
110
|
+
- If remote calls fail in the browser, verify the remote registry app has valid Supabase `VITE_*` environment variables
|
|
111
|
+
- If a real adapter test fails, confirm the underlying external CLI is installed and available on `PATH`
|