workflowskill 0.2.1 → 0.3.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 +147 -106
- package/dist/index.d.mts +26 -84
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1779 -16
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -10
- package/skill/SKILL.md +77 -307
- package/dist/cli/index.d.mts +0 -1
- package/dist/cli/index.mjs +0 -187
- package/dist/cli/index.mjs.map +0 -1
- package/dist/runtime-CD81H1bx.mjs +0 -1977
- package/dist/runtime-CD81H1bx.mjs.map +0 -1
- package/dist/web-scrape-GeEM_JNl.mjs +0 -142
- package/dist/web-scrape-GeEM_JNl.mjs.map +0 -1
package/dist/cli/index.mjs
DELETED
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { S as ParseError, f as loadConfig, h as validateWorkflow, i as runWorkflowSkill, m as AnthropicLLMAdapter, p as BuiltinToolAdapter, w as parseWorkflowFromMd } from "../runtime-CD81H1bx.mjs";
|
|
3
|
-
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
|
-
import { basename, join } from "node:path";
|
|
5
|
-
import { Command } from "commander";
|
|
6
|
-
import pc from "picocolors";
|
|
7
|
-
|
|
8
|
-
//#region src/cli/validate.ts
|
|
9
|
-
function validateCommand(files) {
|
|
10
|
-
let hasErrors = false;
|
|
11
|
-
for (const file of files) {
|
|
12
|
-
let content;
|
|
13
|
-
try {
|
|
14
|
-
content = readFileSync(file, "utf-8");
|
|
15
|
-
} catch {
|
|
16
|
-
console.error(`✗ ${file}: Cannot read file`);
|
|
17
|
-
hasErrors = true;
|
|
18
|
-
continue;
|
|
19
|
-
}
|
|
20
|
-
let workflow;
|
|
21
|
-
try {
|
|
22
|
-
workflow = parseWorkflowFromMd(content);
|
|
23
|
-
} catch (err) {
|
|
24
|
-
if (err instanceof ParseError) {
|
|
25
|
-
console.error(`✗ ${file}: ${err.message}`);
|
|
26
|
-
for (const detail of err.details) console.error(` ${detail.path}: ${detail.message}`);
|
|
27
|
-
} else console.error(`✗ ${file}: ${err instanceof Error ? err.message : String(err)}`);
|
|
28
|
-
hasErrors = true;
|
|
29
|
-
continue;
|
|
30
|
-
}
|
|
31
|
-
const result = validateWorkflow(workflow);
|
|
32
|
-
if (!result.valid) {
|
|
33
|
-
console.error(`✗ ${file}: Validation errors`);
|
|
34
|
-
for (const error of result.errors) console.error(` ${error.path}: ${error.message}`);
|
|
35
|
-
hasErrors = true;
|
|
36
|
-
continue;
|
|
37
|
-
}
|
|
38
|
-
console.log(`✓ ${file} (${workflow.steps.length} steps)`);
|
|
39
|
-
}
|
|
40
|
-
if (hasErrors) process.exit(1);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
//#endregion
|
|
44
|
-
//#region src/cli/format.ts
|
|
45
|
-
const runtimeActiveSteps = /* @__PURE__ */ new Map();
|
|
46
|
-
const isTTY = !!process.stderr.isTTY;
|
|
47
|
-
const MOVE_UP = (n) => `\x1b[${n}A`;
|
|
48
|
-
const CLEAR_LINE = "\x1B[2K\r";
|
|
49
|
-
const MOVE_DOWN = (n) => `\x1b[${n}B`;
|
|
50
|
-
let linesSinceStepStart = 0;
|
|
51
|
-
let hasEachProgress = false;
|
|
52
|
-
/**
|
|
53
|
-
* Render a runtime event to stderr with live step-by-step progress output.
|
|
54
|
-
* All CLI live output goes to stderr; stdout is reserved for the JSON run log.
|
|
55
|
-
*
|
|
56
|
-
* On TTY: the yellow "running..." line is overwritten in-place by the green/red
|
|
57
|
-
* completion line, and each_progress updates a single line instead of appending.
|
|
58
|
-
* On non-TTY (pipes, files): append-only fallback — existing behavior.
|
|
59
|
-
*/
|
|
60
|
-
function renderRuntimeEvent(event) {
|
|
61
|
-
switch (event.type) {
|
|
62
|
-
case "workflow_start":
|
|
63
|
-
process.stderr.write(`\n${pc.bold("▶")} Running ${pc.cyan(event.workflow)} (${event.totalSteps} step${event.totalSteps !== 1 ? "s" : ""})\n\n`);
|
|
64
|
-
break;
|
|
65
|
-
case "step_start": {
|
|
66
|
-
linesSinceStepStart = 0;
|
|
67
|
-
hasEachProgress = false;
|
|
68
|
-
const typeLabel = event.tool ? `[tool] (${event.tool})` : `[${event.stepType}]`;
|
|
69
|
-
const line = ` ${pc.yellow("●")} ${event.stepId} ${pc.dim(typeLabel)} ${pc.dim("running...")}`;
|
|
70
|
-
runtimeActiveSteps.set(event.stepId, line);
|
|
71
|
-
process.stderr.write(line + "\n");
|
|
72
|
-
break;
|
|
73
|
-
}
|
|
74
|
-
case "step_complete": {
|
|
75
|
-
runtimeActiveSteps.delete(event.stepId);
|
|
76
|
-
const durationStr = formatDuration(event.duration_ms);
|
|
77
|
-
const extras = [];
|
|
78
|
-
if (event.tokens) extras.push(`${event.tokens.input + event.tokens.output} tokens`);
|
|
79
|
-
if (event.iterations !== void 0) extras.push(`${event.iterations} iterations`);
|
|
80
|
-
const extraStr = extras.length > 0 ? pc.dim(` (${extras.join(", ")})`) : "";
|
|
81
|
-
const completionLine = event.status === "success" ? ` ${pc.green("✓")} ${event.stepId} ${pc.dim(durationStr)}${extraStr}` : ` ${pc.red("✗")} ${event.stepId} ${pc.dim(durationStr)} ${pc.red("failed")}${extraStr}`;
|
|
82
|
-
if (isTTY) {
|
|
83
|
-
const up = linesSinceStepStart + 1;
|
|
84
|
-
process.stderr.write(MOVE_UP(up) + CLEAR_LINE + completionLine + "\n" + (linesSinceStepStart > 0 ? MOVE_DOWN(linesSinceStepStart) : ""));
|
|
85
|
-
} else process.stderr.write(completionLine + "\n");
|
|
86
|
-
break;
|
|
87
|
-
}
|
|
88
|
-
case "step_skip":
|
|
89
|
-
runtimeActiveSteps.delete(event.stepId);
|
|
90
|
-
process.stderr.write(` ${pc.dim("○")} ${pc.dim(event.stepId)} ${pc.dim("skipped")}: ${pc.dim(event.reason)}\n`);
|
|
91
|
-
break;
|
|
92
|
-
case "step_retry":
|
|
93
|
-
process.stderr.write(` ${pc.yellow("↻")} ${event.stepId} retry #${event.attempt}: ${pc.dim(event.error)}\n`);
|
|
94
|
-
linesSinceStepStart++;
|
|
95
|
-
break;
|
|
96
|
-
case "step_error":
|
|
97
|
-
process.stderr.write(` ${pc.red("✗")} ${event.stepId} error (${event.onError}): ${pc.dim(event.error)}\n`);
|
|
98
|
-
linesSinceStepStart++;
|
|
99
|
-
break;
|
|
100
|
-
case "each_progress":
|
|
101
|
-
if (isTTY && hasEachProgress) process.stderr.write(MOVE_UP(1) + CLEAR_LINE + ` ${pc.dim(`${event.current}/${event.total}`)}\n`);
|
|
102
|
-
else {
|
|
103
|
-
process.stderr.write(` ${pc.dim(`${event.current}/${event.total}`)}\n`);
|
|
104
|
-
linesSinceStepStart++;
|
|
105
|
-
hasEachProgress = true;
|
|
106
|
-
}
|
|
107
|
-
break;
|
|
108
|
-
case "workflow_complete": {
|
|
109
|
-
const durationStr = formatDuration(event.duration_ms);
|
|
110
|
-
const { steps_executed, steps_skipped, total_tokens } = event.summary;
|
|
111
|
-
const parts = [`${steps_executed} executed`];
|
|
112
|
-
if (steps_skipped > 0) parts.push(`${steps_skipped} skipped`);
|
|
113
|
-
if (total_tokens > 0) parts.push(`${total_tokens} tokens`);
|
|
114
|
-
const summary = parts.join(", ");
|
|
115
|
-
if (event.status === "success") process.stderr.write(`\n${pc.green(pc.bold("✓"))} ${pc.green("Success")} in ${durationStr} ${pc.dim(`(${summary})`)}\n`);
|
|
116
|
-
else process.stderr.write(`\n${pc.red(pc.bold("✗"))} ${pc.red("Failed")} in ${durationStr} ${pc.dim(`(${summary})`)}\n`);
|
|
117
|
-
break;
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
/** Format a duration in milliseconds as a human-readable string (e.g. "1.2s", "2m30s"). */
|
|
122
|
-
function formatDuration(ms) {
|
|
123
|
-
if (ms < 1e3) return `${ms}ms`;
|
|
124
|
-
const totalSeconds = ms / 1e3;
|
|
125
|
-
if (totalSeconds < 60) return `${totalSeconds.toFixed(1)}s`;
|
|
126
|
-
return `${Math.floor(totalSeconds / 60)}m${Math.round(totalSeconds % 60)}s`;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
//#endregion
|
|
130
|
-
//#region src/cli/run.ts
|
|
131
|
-
/** Write a run log to stdout and persist it to disk. */
|
|
132
|
-
function writeRunLog(log, logDir) {
|
|
133
|
-
const json = JSON.stringify(log, null, 2);
|
|
134
|
-
mkdirSync(logDir, { recursive: true });
|
|
135
|
-
const safeTimestamp = log.started_at.replace(/:/g, "-");
|
|
136
|
-
const logFile = join(logDir, `${log.workflow}-${safeTimestamp}.json`);
|
|
137
|
-
writeFileSync(logFile, json + "\n", "utf-8");
|
|
138
|
-
console.error(`Run log written to ${logFile}`);
|
|
139
|
-
console.log(json);
|
|
140
|
-
}
|
|
141
|
-
async function runCommand(file, options) {
|
|
142
|
-
const logDir = options.logDir ?? "runs";
|
|
143
|
-
const workflowName = basename(file, ".md");
|
|
144
|
-
let content;
|
|
145
|
-
try {
|
|
146
|
-
content = readFileSync(file, "utf-8");
|
|
147
|
-
} catch (err) {
|
|
148
|
-
console.error(`Error: Cannot read file "${file}": ${err instanceof Error ? err.message : String(err)}`);
|
|
149
|
-
process.exit(1);
|
|
150
|
-
}
|
|
151
|
-
let inputs = {};
|
|
152
|
-
if (options.input) try {
|
|
153
|
-
inputs = JSON.parse(options.input);
|
|
154
|
-
} catch {
|
|
155
|
-
console.error("Error: --input must be valid JSON");
|
|
156
|
-
process.exit(1);
|
|
157
|
-
}
|
|
158
|
-
const config = loadConfig();
|
|
159
|
-
const toolAdapter = await BuiltinToolAdapter.create();
|
|
160
|
-
let llmAdapter;
|
|
161
|
-
if (config.anthropicApiKey) llmAdapter = new AnthropicLLMAdapter(config.anthropicApiKey);
|
|
162
|
-
else llmAdapter = { call() {
|
|
163
|
-
throw new Error("ANTHROPIC_API_KEY not set. This workflow has LLM steps that require it.\nSet it in runtime/.env or export it in your shell: export ANTHROPIC_API_KEY=sk-ant-...");
|
|
164
|
-
} };
|
|
165
|
-
const log = await runWorkflowSkill({
|
|
166
|
-
content,
|
|
167
|
-
inputs,
|
|
168
|
-
toolAdapter,
|
|
169
|
-
llmAdapter,
|
|
170
|
-
workflowName,
|
|
171
|
-
onEvent: renderRuntimeEvent
|
|
172
|
-
});
|
|
173
|
-
writeRunLog(log, logDir);
|
|
174
|
-
process.exit(log.status === "success" ? 0 : 1);
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
//#endregion
|
|
178
|
-
//#region src/cli/index.ts
|
|
179
|
-
const program = new Command();
|
|
180
|
-
program.name("workflowskill").description("WorkflowSkill runtime CLI").version("0.1.0");
|
|
181
|
-
program.command("validate").description("Validate one or more workflow SKILL.md files without executing").argument("<files...>", "Workflow files to validate").action(validateCommand);
|
|
182
|
-
program.command("run <file>").description("Execute a workflow SKILL.md file").option("-i, --input <json>", "Workflow inputs as JSON string", "{}").option("-l, --log-dir <dir>", "Directory to write run logs", "runs").action(runCommand);
|
|
183
|
-
program.parse();
|
|
184
|
-
|
|
185
|
-
//#endregion
|
|
186
|
-
export { };
|
|
187
|
-
//# sourceMappingURL=index.mjs.map
|
package/dist/cli/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/cli/validate.ts","../../src/cli/format.ts","../../src/cli/run.ts","../../src/cli/index.ts"],"sourcesContent":["// CLI: validate command — check workflows without running them.\n\nimport { readFileSync } from 'node:fs';\nimport { parseWorkflowFromMd } from '../parser/index.js';\nimport { ParseError } from '../parser/index.js';\nimport { validateWorkflow } from '../validator/index.js';\n\nexport function validateCommand(files: string[]): void {\n let hasErrors = false;\n\n for (const file of files) {\n let content: string;\n try {\n content = readFileSync(file, 'utf-8');\n } catch {\n console.error(`✗ ${file}: Cannot read file`);\n hasErrors = true;\n continue;\n }\n\n // Parse\n let workflow;\n try {\n workflow = parseWorkflowFromMd(content);\n } catch (err) {\n if (err instanceof ParseError) {\n console.error(`✗ ${file}: ${err.message}`);\n for (const detail of err.details) {\n console.error(` ${detail.path}: ${detail.message}`);\n }\n } else {\n console.error(`✗ ${file}: ${err instanceof Error ? err.message : String(err)}`);\n }\n hasErrors = true;\n continue;\n }\n\n // Validate\n const result = validateWorkflow(workflow);\n if (!result.valid) {\n console.error(`✗ ${file}: Validation errors`);\n for (const error of result.errors) {\n console.error(` ${error.path}: ${error.message}`);\n }\n hasErrors = true;\n continue;\n }\n\n console.log(`✓ ${file} (${workflow.steps.length} steps)`);\n }\n\n if (hasErrors) {\n process.exit(1);\n }\n}\n","// CLI formatting module — runtime event rendering.\n// Uses picocolors for terminal colors and writes to stderr (keeping stdout clean for output).\n\nimport pc from 'picocolors';\nimport type { RuntimeEvent } from '../types/index.js';\n\n// ─── Runtime event renderer ───────────────────────────────────────────────────\n\n// Track in-progress step names for the \"running...\" line (keyed by stepId).\nconst runtimeActiveSteps = new Map<string, string>();\n\n// Whether stderr is a real TTY (enables in-place cursor movement).\nconst isTTY = !!process.stderr.isTTY;\n\n// ANSI helpers for in-place line updates (only used when isTTY is true).\nconst MOVE_UP = (n: number): string => `\\x1b[${n}A`;\nconst CLEAR_LINE = '\\x1b[2K\\r';\nconst MOVE_DOWN = (n: number): string => `\\x1b[${n}B`;\n\n// Lines printed between step_start and step_complete (retries, each_progress).\nlet linesSinceStepStart = 0;\n// Whether each_progress has been printed at least once for the current step.\nlet hasEachProgress = false;\n\n/**\n * Render a runtime event to stderr with live step-by-step progress output.\n * All CLI live output goes to stderr; stdout is reserved for the JSON run log.\n *\n * On TTY: the yellow \"running...\" line is overwritten in-place by the green/red\n * completion line, and each_progress updates a single line instead of appending.\n * On non-TTY (pipes, files): append-only fallback — existing behavior.\n */\nexport function renderRuntimeEvent(event: RuntimeEvent): void {\n switch (event.type) {\n case 'workflow_start':\n process.stderr.write(`\\n${pc.bold('▶')} Running ${pc.cyan(event.workflow)} (${event.totalSteps} step${event.totalSteps !== 1 ? 's' : ''})\\n\\n`);\n break;\n\n case 'step_start': {\n linesSinceStepStart = 0;\n hasEachProgress = false;\n const typeLabel = event.tool ? `[tool] (${event.tool})` : `[${event.stepType}]`;\n const line = ` ${pc.yellow('●')} ${event.stepId} ${pc.dim(typeLabel)} ${pc.dim('running...')}`;\n runtimeActiveSteps.set(event.stepId, line);\n process.stderr.write(line + '\\n');\n break;\n }\n\n case 'step_complete': {\n runtimeActiveSteps.delete(event.stepId);\n const durationStr = formatDuration(event.duration_ms);\n const extras: string[] = [];\n if (event.tokens) extras.push(`${event.tokens.input + event.tokens.output} tokens`);\n if (event.iterations !== undefined) extras.push(`${event.iterations} iterations`);\n const extraStr = extras.length > 0 ? pc.dim(` (${extras.join(', ')})`) : '';\n const completionLine =\n event.status === 'success'\n ? ` ${pc.green('✓')} ${event.stepId} ${pc.dim(durationStr)}${extraStr}`\n : ` ${pc.red('✗')} ${event.stepId} ${pc.dim(durationStr)} ${pc.red('failed')}${extraStr}`;\n\n if (isTTY) {\n // Move up past any intermediate lines + the \"running...\" line, overwrite it,\n // then move the cursor back down past the intermediate lines.\n const up = linesSinceStepStart + 1;\n process.stderr.write(\n MOVE_UP(up) + CLEAR_LINE + completionLine + '\\n' +\n (linesSinceStepStart > 0 ? MOVE_DOWN(linesSinceStepStart) : ''),\n );\n } else {\n process.stderr.write(completionLine + '\\n');\n }\n break;\n }\n\n case 'step_skip':\n runtimeActiveSteps.delete(event.stepId);\n process.stderr.write(` ${pc.dim('○')} ${pc.dim(event.stepId)} ${pc.dim('skipped')}: ${pc.dim(event.reason)}\\n`);\n break;\n\n case 'step_retry':\n process.stderr.write(` ${pc.yellow('↻')} ${event.stepId} retry #${event.attempt}: ${pc.dim(event.error)}\\n`);\n linesSinceStepStart++;\n break;\n\n case 'step_error':\n process.stderr.write(` ${pc.red('✗')} ${event.stepId} error (${event.onError}): ${pc.dim(event.error)}\\n`);\n linesSinceStepStart++;\n break;\n\n case 'each_progress':\n if (isTTY && hasEachProgress) {\n // Overwrite the previous each_progress line in-place.\n process.stderr.write(MOVE_UP(1) + CLEAR_LINE + ` ${pc.dim(`${event.current}/${event.total}`)}\\n`);\n } else {\n process.stderr.write(` ${pc.dim(`${event.current}/${event.total}`)}\\n`);\n linesSinceStepStart++;\n hasEachProgress = true;\n }\n break;\n\n case 'workflow_complete': {\n const durationStr = formatDuration(event.duration_ms);\n const { steps_executed, steps_skipped, total_tokens } = event.summary;\n const parts: string[] = [`${steps_executed} executed`];\n if (steps_skipped > 0) parts.push(`${steps_skipped} skipped`);\n if (total_tokens > 0) parts.push(`${total_tokens} tokens`);\n const summary = parts.join(', ');\n if (event.status === 'success') {\n process.stderr.write(`\\n${pc.green(pc.bold('✓'))} ${pc.green('Success')} in ${durationStr} ${pc.dim(`(${summary})`)}\\n`);\n } else {\n process.stderr.write(`\\n${pc.red(pc.bold('✗'))} ${pc.red('Failed')} in ${durationStr} ${pc.dim(`(${summary})`)}\\n`);\n }\n break;\n }\n }\n}\n\n/** Reset runtime format state (for testing). */\nexport function resetRuntimeFormatState(): void {\n runtimeActiveSteps.clear();\n linesSinceStepStart = 0;\n hasEachProgress = false;\n}\n\n/** Format a duration in milliseconds as a human-readable string (e.g. \"1.2s\", \"2m30s\"). */\nexport function formatDuration(ms: number): string {\n if (ms < 1000) return `${ms}ms`;\n const totalSeconds = ms / 1000;\n if (totalSeconds < 60) return `${totalSeconds.toFixed(1)}s`;\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = Math.round(totalSeconds % 60);\n return `${minutes}m${seconds}s`;\n}\n","// CLI: run command — execute a workflow and print the run log.\n\nimport { mkdirSync, readFileSync, writeFileSync } from 'node:fs';\nimport { basename, join } from 'node:path';\nimport { runWorkflowSkill } from '../runtime/index.js';\nimport type { RunLog } from '../types/index.js';\nimport { loadConfig } from '../config/index.js';\nimport { AnthropicLLMAdapter } from '../adapters/anthropic-llm-adapter.js';\nimport { BuiltinToolAdapter } from '../tools/builtin-tool-adapter.js';\nimport type { LLMAdapter, LLMResult } from '../types/index.js';\nimport { renderRuntimeEvent } from './format.js';\n\n/** Write a run log to stdout and persist it to disk. */\nfunction writeRunLog(log: RunLog, logDir: string): void {\n const json = JSON.stringify(log, null, 2);\n mkdirSync(logDir, { recursive: true });\n const safeTimestamp = log.started_at.replace(/:/g, '-');\n const logFile = join(logDir, `${log.workflow}-${safeTimestamp}.json`);\n writeFileSync(logFile, json + '\\n', 'utf-8');\n console.error(`Run log written to ${logFile}`);\n console.log(json);\n}\n\nexport async function runCommand(\n file: string,\n options: { input?: string; logDir?: string },\n): Promise<void> {\n const logDir = options.logDir ?? 'runs';\n const workflowName = basename(file, '.md');\n\n let content: string;\n try {\n content = readFileSync(file, 'utf-8');\n } catch (err) {\n console.error(`Error: Cannot read file \"${file}\": ${err instanceof Error ? err.message : String(err)}`);\n process.exit(1);\n }\n\n // Parse inputs\n let inputs: Record<string, unknown> = {};\n if (options.input) {\n try {\n inputs = JSON.parse(options.input) as Record<string, unknown>;\n } catch {\n console.error('Error: --input must be valid JSON');\n process.exit(1);\n }\n }\n\n // Load config and create adapters\n const config = loadConfig();\n const toolAdapter = await BuiltinToolAdapter.create();\n let llmAdapter: LLMAdapter;\n if (config.anthropicApiKey) {\n llmAdapter = new AnthropicLLMAdapter(config.anthropicApiKey);\n } else {\n // No API key — create an adapter that fails with a clear error on first use.\n // Workflows without LLM steps (e.g., hello-world.md) still work.\n llmAdapter = {\n call(): Promise<LLMResult> {\n throw new Error(\n 'ANTHROPIC_API_KEY not set. This workflow has LLM steps that require it.\\n' +\n 'Set it in runtime/.env or export it in your shell: export ANTHROPIC_API_KEY=sk-ant-...',\n );\n },\n };\n }\n\n const log = await runWorkflowSkill({\n content,\n inputs,\n toolAdapter,\n llmAdapter,\n workflowName,\n onEvent: renderRuntimeEvent,\n });\n\n writeRunLog(log, logDir);\n process.exit(log.status === 'success' ? 0 : 1);\n}\n","#!/usr/bin/env node\n// WorkflowSkill CLI — validate and run workflows.\n\nimport { Command } from 'commander';\nimport { validateCommand } from './validate.js';\nimport { runCommand } from './run.js';\n\nconst program = new Command();\n\nprogram\n .name('workflowskill')\n .description('WorkflowSkill runtime CLI')\n .version('0.1.0');\n\nprogram\n .command('validate')\n .description('Validate one or more workflow SKILL.md files without executing')\n .argument('<files...>', 'Workflow files to validate')\n .action(validateCommand);\n\nprogram\n .command('run <file>')\n .description('Execute a workflow SKILL.md file')\n .option('-i, --input <json>', 'Workflow inputs as JSON string', '{}')\n .option('-l, --log-dir <dir>', 'Directory to write run logs', 'runs')\n .action(runCommand);\n\nprogram.parse();\n"],"mappings":"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"}
|