workflowskill 0.3.0 → 0.3.1
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/dist/index.d.mts +2 -0
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +6 -3
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/skill/SKILL.md +62 -54
package/dist/index.d.mts
CHANGED
|
@@ -220,6 +220,7 @@ type RuntimeEvent = {
|
|
|
220
220
|
stepId: string;
|
|
221
221
|
stepType: StepType;
|
|
222
222
|
tool?: string;
|
|
223
|
+
description?: string;
|
|
223
224
|
} | {
|
|
224
225
|
type: 'step_complete';
|
|
225
226
|
stepId: string;
|
|
@@ -230,6 +231,7 @@ type RuntimeEvent = {
|
|
|
230
231
|
type: 'step_skip';
|
|
231
232
|
stepId: string;
|
|
232
233
|
reason: string;
|
|
234
|
+
description?: string;
|
|
233
235
|
} | {
|
|
234
236
|
type: 'step_retry';
|
|
235
237
|
stepId: string;
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types/index.ts","../src/parser/index.ts","../src/expression/lexer.ts","../src/expression/parser.ts","../src/expression/evaluator.ts","../src/expression/index.ts","../src/validator/index.ts","../src/adapters/mock-tool-adapter.ts","../src/config/index.ts","../src/executor/types.ts","../src/executor/transform.ts","../src/executor/conditional.ts","../src/executor/exit.ts","../src/executor/tool.ts","../src/executor/index.ts","../src/runtime/index.ts","../src/skill/index.ts"],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types/index.ts","../src/parser/index.ts","../src/expression/lexer.ts","../src/expression/parser.ts","../src/expression/evaluator.ts","../src/expression/index.ts","../src/validator/index.ts","../src/adapters/mock-tool-adapter.ts","../src/config/index.ts","../src/executor/types.ts","../src/executor/transform.ts","../src/executor/conditional.ts","../src/executor/exit.ts","../src/executor/tool.ts","../src/executor/index.ts","../src/runtime/index.ts","../src/skill/index.ts"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -1405,7 +1405,8 @@ async function runWorkflow(options) {
|
|
|
1405
1405
|
emit(onEvent, {
|
|
1406
1406
|
type: "step_skip",
|
|
1407
1407
|
stepId: step.id,
|
|
1408
|
-
reason
|
|
1408
|
+
reason,
|
|
1409
|
+
description: step.description
|
|
1409
1410
|
});
|
|
1410
1411
|
stepRecords.push({
|
|
1411
1412
|
id: step.id,
|
|
@@ -1491,7 +1492,8 @@ async function executeStepLifecycle(step, context, stepMap, branchStepIds, toolA
|
|
|
1491
1492
|
emit(onEvent, {
|
|
1492
1493
|
type: "step_skip",
|
|
1493
1494
|
stepId: step.id,
|
|
1494
|
-
reason: "Guard condition evaluated to false"
|
|
1495
|
+
reason: "Guard condition evaluated to false",
|
|
1496
|
+
description: step.description
|
|
1495
1497
|
});
|
|
1496
1498
|
records.push({
|
|
1497
1499
|
id: step.id,
|
|
@@ -1507,7 +1509,8 @@ async function executeStepLifecycle(step, context, stepMap, branchStepIds, toolA
|
|
|
1507
1509
|
type: "step_start",
|
|
1508
1510
|
stepId: step.id,
|
|
1509
1511
|
stepType: step.type,
|
|
1510
|
-
tool: step.type === "tool" ? step.tool : void 0
|
|
1512
|
+
tool: step.type === "tool" ? step.tool : void 0,
|
|
1513
|
+
description: step.description
|
|
1511
1514
|
});
|
|
1512
1515
|
if (step.each) return executeWithEach(step, context, toolAdapter, startTime, onEvent);
|
|
1513
1516
|
const resolvedInputs = resolveInputs(step.inputs, context, step.id);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["parseYaml"],"sources":["../src/parser/extract.ts","../src/parser/schema.ts","../src/parser/index.ts","../src/expression/lexer.ts","../src/expression/parser.ts","../src/expression/evaluator.ts","../src/expression/index.ts","../src/parser/parse-content.ts","../src/validator/index.ts","../src/adapters/mock-tool-adapter.ts","../src/config/index.ts","../src/executor/transform.ts","../src/executor/conditional.ts","../src/executor/exit.ts","../src/executor/types.ts","../src/executor/tool.ts","../src/executor/index.ts","../src/runtime/index.ts","../src/skill/index.ts"],"sourcesContent":["// Extract ```workflow fenced code block and YAML frontmatter from SKILL.md content.\n\n/** Result of extracting content from a SKILL.md file. */\nexport interface ExtractResult {\n frontmatter: string | null;\n workflowYaml: string;\n}\n\n/**\n * Extract YAML frontmatter from SKILL.md content.\n * Frontmatter is delimited by --- at the start of the file.\n */\nexport function extractFrontmatter(content: string): string | null {\n // Normalize Windows line endings before matching\n const normalized = content.replace(/\\r\\n/g, '\\n');\n const match = normalized.match(/^---\\n([\\s\\S]*?)\\n---/);\n return match?.[1] ?? null;\n}\n\n/**\n * Extract the ```workflow fenced code block from SKILL.md content.\n * Returns the YAML content inside the block.\n * Throws if no workflow block is found.\n */\nexport function extractWorkflowBlock(content: string): string {\n // Normalize Windows line endings before matching\n const normalized = content.replace(/\\r\\n/g, '\\n');\n // Match ```workflow ... ``` block\n const match = normalized.match(/```workflow\\s*\\n([\\s\\S]*?)\\n```/);\n if (!match?.[1]) {\n throw new ExtractError(\n 'No ```workflow fenced code block found in SKILL.md. ' +\n 'WorkflowSkill definitions must be wrapped in a ```workflow block.'\n );\n }\n return match[1];\n}\n\n/**\n * Extract both frontmatter and workflow block from SKILL.md content.\n */\nexport function extract(content: string): ExtractResult {\n return {\n frontmatter: extractFrontmatter(content),\n workflowYaml: extractWorkflowBlock(content),\n };\n}\n\n/** Error thrown during extraction. */\nexport class ExtractError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ExtractError';\n }\n}\n","// Zod schemas for WorkflowSkill YAML validation.\n// Isolated here so schema validation can be swapped (e.g., to TypeBox) during integration.\n\nimport { z } from 'zod';\n\n// ─── Primitive schemas ────────────────────────────────────────────────────────\n\nconst schemaTypeEnum = z.enum(['string', 'int', 'float', 'boolean', 'array', 'object']);\n\n// FieldSchema can be recursive (items/properties contain FieldSchema).\n// We avoid deep recursion issues by using z.unknown() for nested levels.\n// This is sufficient for validation — we don't need infinite depth.\n// Note: `default` is not supported at nested level (only workflow inputs use `default`).\nconst nestedFieldSchema = z.object({\n type: schemaTypeEnum,\n value: z.unknown().optional(),\n items: z.record(z.string(), z.unknown()).optional(),\n properties: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const fieldSchema = z.object({\n type: schemaTypeEnum,\n value: z.unknown().optional(),\n items: nestedFieldSchema.optional(),\n properties: z.record(z.string(), z.union([z.string(), nestedFieldSchema])).optional(),\n});\n\n// ─── Workflow inputs and outputs ──────────────────────────────────────────────\n\n// Workflow inputs use `default` as canonical field for fallback values.\nexport const workflowInputSchema = z.object({\n type: schemaTypeEnum,\n default: z.unknown().optional(),\n items: nestedFieldSchema.optional(),\n properties: z.record(z.string(), z.union([z.string(), nestedFieldSchema])).optional(),\n});\n\nconst workflowOutputBaseSchema = z.object({\n type: schemaTypeEnum,\n value: z.unknown().optional(),\n items: nestedFieldSchema.optional(),\n properties: z.record(z.string(), z.union([z.string(), nestedFieldSchema])).optional(),\n});\nexport const workflowOutputSchema = workflowOutputBaseSchema;\n\n// ─── Step inputs and outputs ──────────────────────────────────────────────────\n\nconst stepInputBaseSchema = z.object({\n type: schemaTypeEnum,\n value: z.unknown().optional(),\n items: nestedFieldSchema.optional(),\n properties: z.record(z.string(), z.union([z.string(), nestedFieldSchema])).optional(),\n});\nexport const stepInputSchema = stepInputBaseSchema;\n\nconst stepOutputBaseSchema = z.object({\n type: schemaTypeEnum,\n value: z.unknown().optional(),\n items: nestedFieldSchema.optional(),\n properties: z.record(z.string(), z.union([z.string(), nestedFieldSchema])).optional(),\n});\nexport const stepOutputSchema = stepOutputBaseSchema;\n\n// ─── Retry policy ─────────────────────────────────────────────────────────────\n\nexport const retryPolicySchema = z.object({\n max: z.number().int().positive(),\n delay: z.string(),\n backoff: z.number().positive(),\n});\n\n// ─── Common step fields ───────────────────────────────────────────────────────\n\nconst stepBaseSchema = z.object({\n id: z.string().min(1),\n type: z.enum(['tool', 'transform', 'conditional', 'exit']),\n description: z.string().optional(),\n inputs: z.record(z.string(), stepInputSchema).default({}),\n outputs: z.record(z.string(), stepOutputSchema).default({}),\n condition: z.string().optional(),\n each: z.string().optional(),\n delay: z.string().optional(),\n on_error: z.enum(['fail', 'ignore']).optional(),\n retry: retryPolicySchema.optional(),\n});\n\n// ─── Step type schemas ────────────────────────────────────────────────────────\n\nconst toolStepSchema = stepBaseSchema.extend({\n type: z.literal('tool'),\n tool: z.string().min(1),\n});\n\nconst transformFilterStepSchema = stepBaseSchema.extend({\n type: z.literal('transform'),\n operation: z.literal('filter'),\n where: z.string().min(1),\n});\n\nconst transformMapStepSchema = stepBaseSchema.extend({\n type: z.literal('transform'),\n operation: z.literal('map'),\n expression: z.record(z.string(), z.unknown()),\n});\n\nconst transformSortStepSchema = stepBaseSchema.extend({\n type: z.literal('transform'),\n operation: z.literal('sort'),\n field: z.string().min(1),\n direction: z.enum(['asc', 'desc']).optional(),\n});\n\nconst conditionalStepSchema = stepBaseSchema.extend({\n type: z.literal('conditional'),\n condition: z.string().min(1),\n then: z.array(z.string()).min(1),\n else: z.array(z.string()).optional(),\n});\n\nconst exitStepSchema = stepBaseSchema.extend({\n type: z.literal('exit'),\n status: z.enum(['success', 'failed']),\n // Output can be an expression string or an object literal (values may be expressions)\n output: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),\n});\n\n// Transform steps share type=\"transform\" but differ by operation.\n// Zod discriminatedUnion doesn't support duplicate discriminator values,\n// so we use a nested discriminatedUnion for transform operations.\nconst transformStepSchema = z.discriminatedUnion('operation', [\n transformFilterStepSchema,\n transformMapStepSchema,\n transformSortStepSchema,\n]);\n\n// Top-level step schema: discriminate by type, with transform handled by sub-union.\nexport const stepSchema = z.union([\n toolStepSchema,\n transformStepSchema,\n conditionalStepSchema,\n exitStepSchema,\n]);\n\n// ─── Workflow definition ──────────────────────────────────────────────────────\n\nexport const workflowDefinitionSchema = z.object({\n inputs: z.record(z.string(), workflowInputSchema).default({}),\n outputs: z.record(z.string(), workflowOutputSchema).default({}),\n steps: z.array(stepSchema).min(1, 'Workflow must have at least one step'),\n});\n\n// ─── SKILL.md frontmatter ─────────────────────────────────────────────────────\n\nexport const skillFrontmatterSchema = z.object({\n name: z.string().min(1),\n description: z.string().min(1),\n}).passthrough();\n","// WorkflowSkill parser: SKILL.md → typed WorkflowDefinition\n// Pipeline: extract markdown → parse YAML → validate with Zod → typed objects\n\nimport { parse as parseYaml } from 'yaml';\nimport { ZodError } from 'zod';\nimport { extract, extractWorkflowBlock, ExtractError } from './extract.js';\nimport { workflowDefinitionSchema, skillFrontmatterSchema } from './schema.js';\nimport type { WorkflowDefinition, ParsedSkill, SkillFrontmatter } from '../types/index.js';\n\n/** Error thrown when parsing fails. Includes structured details. */\nexport class ParseError extends Error {\n constructor(\n message: string,\n public readonly details: ParseErrorDetail[] = [],\n ) {\n super(message);\n this.name = 'ParseError';\n }\n}\n\nexport interface ParseErrorDetail {\n path: string;\n message: string;\n}\n\n/**\n * Convert Zod errors to our ParseErrorDetail format.\n */\nfunction zodToDetails(err: ZodError): ParseErrorDetail[] {\n return err.issues.map((issue) => ({\n path: issue.path.join('.'),\n message: issue.message,\n }));\n}\n\n/**\n * Parse a raw YAML string into a validated WorkflowDefinition.\n * Use this when you already have the YAML content (e.g., from extractWorkflowBlock).\n */\nexport function parseWorkflowYaml(yaml: string): WorkflowDefinition {\n let raw: unknown;\n try {\n raw = parseYaml(yaml);\n } catch (err) {\n throw new ParseError(`Invalid YAML: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n const result = workflowDefinitionSchema.safeParse(raw);\n if (!result.success) {\n throw new ParseError(\n 'Workflow validation failed',\n zodToDetails(result.error),\n );\n }\n\n // Zod discriminatedUnion handles step type validation, but transform steps\n // need the discriminatedUnion on 'type' first and then we rely on Zod for\n // operation-specific fields. Cast is safe because Zod validated the shape.\n return result.data as unknown as WorkflowDefinition;\n}\n\n/**\n * Parse a SKILL.md file content into a fully typed ParsedSkill.\n * Extracts frontmatter and workflow block, validates both.\n */\nexport function parseSkillMd(content: string): ParsedSkill {\n let extracted;\n try {\n extracted = extract(content);\n } catch (err) {\n if (err instanceof ExtractError) {\n throw new ParseError(err.message);\n }\n throw err;\n }\n\n // Parse frontmatter\n let frontmatter: SkillFrontmatter;\n if (extracted.frontmatter) {\n let rawFrontmatter: unknown;\n try {\n rawFrontmatter = parseYaml(extracted.frontmatter);\n } catch (err) {\n throw new ParseError(`Invalid frontmatter YAML: ${err instanceof Error ? err.message : String(err)}`);\n }\n const fmResult = skillFrontmatterSchema.safeParse(rawFrontmatter);\n if (!fmResult.success) {\n throw new ParseError('Frontmatter validation failed', zodToDetails(fmResult.error));\n }\n frontmatter = fmResult.data as SkillFrontmatter;\n } else {\n throw new ParseError('SKILL.md must have YAML frontmatter with name and description');\n }\n\n // Parse workflow\n const workflow = parseWorkflowYaml(extracted.workflowYaml);\n\n return { frontmatter, workflow };\n}\n\n/**\n * Parse just the workflow block from SKILL.md content.\n * Useful when you only need the workflow definition without frontmatter.\n */\nexport function parseWorkflowFromMd(content: string): WorkflowDefinition {\n let yaml;\n try {\n yaml = extractWorkflowBlock(content);\n } catch (err) {\n if (err instanceof ExtractError) {\n throw new ParseError(err.message);\n }\n throw err;\n }\n return parseWorkflowYaml(yaml);\n}\n\n// Re-export extract utilities\nexport { extractWorkflowBlock, extractFrontmatter } from './extract.js';\n","// Lexer for the WorkflowSkill expression language.\n// Tokenizes expressions like: $steps.fetch.output.messages.length >= 5\n\nexport type TokenType =\n | 'DOLLAR_REF' // $inputs, $steps, $item, $index\n | 'DOT' // .\n | 'IDENTIFIER' // field names, property names\n | 'NUMBER' // integer or float literals\n | 'STRING' // \"string\" or 'string' literals\n | 'BOOLEAN' // true, false\n | 'NULL' // null\n | 'EQ' // ==\n | 'NEQ' // !=\n | 'GT' // >\n | 'GTE' // >=\n | 'LT' // <\n | 'LTE' // <=\n | 'AND' // &&\n | 'OR' // ||\n | 'NOT' // !\n | 'CONTAINS' // contains\n | 'LPAREN' // (\n | 'RPAREN' // )\n | 'LBRACKET' // [\n | 'RBRACKET' // ]\n | 'EOF';\n\nexport interface Token {\n type: TokenType;\n value: string;\n position: number;\n}\n\nexport class LexError extends Error {\n constructor(message: string, public readonly position: number) {\n super(message);\n this.name = 'LexError';\n }\n}\n\nexport function lex(input: string): Token[] {\n const tokens: Token[] = [];\n let pos = 0;\n\n while (pos < input.length) {\n // Skip whitespace\n if (/\\s/.test(input[pos]!)) {\n pos++;\n continue;\n }\n\n const ch = input[pos]!;\n\n // Dollar references: $inputs, $steps, $item, $index, $result\n if (ch === '$') {\n const start = pos;\n pos++; // skip $\n let name = '';\n while (pos < input.length && /[a-zA-Z_]/.test(input[pos]!)) {\n name += input[pos]!;\n pos++;\n }\n if (!name) {\n throw new LexError(`Expected identifier after $`, start);\n }\n tokens.push({ type: 'DOLLAR_REF', value: name, position: start });\n continue;\n }\n\n // Dot\n if (ch === '.') {\n tokens.push({ type: 'DOT', value: '.', position: pos });\n pos++;\n continue;\n }\n\n // Parentheses\n if (ch === '(') {\n tokens.push({ type: 'LPAREN', value: '(', position: pos });\n pos++;\n continue;\n }\n if (ch === ')') {\n tokens.push({ type: 'RPAREN', value: ')', position: pos });\n pos++;\n continue;\n }\n\n // Brackets\n if (ch === '[') {\n tokens.push({ type: 'LBRACKET', value: '[', position: pos });\n pos++;\n continue;\n }\n if (ch === ']') {\n tokens.push({ type: 'RBRACKET', value: ']', position: pos });\n pos++;\n continue;\n }\n\n // Two-character operators\n if (pos + 1 < input.length) {\n const twoChar = input[pos]! + input[pos + 1]!;\n if (twoChar === '==') {\n tokens.push({ type: 'EQ', value: '==', position: pos });\n pos += 2;\n continue;\n }\n if (twoChar === '!=') {\n tokens.push({ type: 'NEQ', value: '!=', position: pos });\n pos += 2;\n continue;\n }\n if (twoChar === '>=') {\n tokens.push({ type: 'GTE', value: '>=', position: pos });\n pos += 2;\n continue;\n }\n if (twoChar === '<=') {\n tokens.push({ type: 'LTE', value: '<=', position: pos });\n pos += 2;\n continue;\n }\n if (twoChar === '&&') {\n tokens.push({ type: 'AND', value: '&&', position: pos });\n pos += 2;\n continue;\n }\n if (twoChar === '||') {\n tokens.push({ type: 'OR', value: '||', position: pos });\n pos += 2;\n continue;\n }\n }\n\n // Single-character operators\n if (ch === '>') {\n tokens.push({ type: 'GT', value: '>', position: pos });\n pos++;\n continue;\n }\n if (ch === '<') {\n tokens.push({ type: 'LT', value: '<', position: pos });\n pos++;\n continue;\n }\n if (ch === '!') {\n tokens.push({ type: 'NOT', value: '!', position: pos });\n pos++;\n continue;\n }\n\n // Number literals\n if (/[0-9]/.test(ch) || (ch === '-' && pos + 1 < input.length && /[0-9]/.test(input[pos + 1]!))) {\n const start = pos;\n if (ch === '-') pos++;\n while (pos < input.length && /[0-9]/.test(input[pos]!)) pos++;\n if (pos < input.length && input[pos] === '.') {\n pos++;\n while (pos < input.length && /[0-9]/.test(input[pos]!)) pos++;\n }\n tokens.push({ type: 'NUMBER', value: input.slice(start, pos), position: start });\n continue;\n }\n\n // String literals\n if (ch === '\"' || ch === \"'\") {\n const quote = ch;\n const start = pos;\n pos++; // skip opening quote\n let str = '';\n while (pos < input.length && input[pos] !== quote) {\n if (input[pos] === '\\\\' && pos + 1 < input.length) {\n pos++; // skip backslash\n }\n str += input[pos]!;\n pos++;\n }\n if (pos >= input.length) {\n throw new LexError(`Unterminated string literal`, start);\n }\n pos++; // skip closing quote\n tokens.push({ type: 'STRING', value: str, position: start });\n continue;\n }\n\n // Identifiers (also matches true, false, null)\n if (/[a-zA-Z_]/.test(ch)) {\n const start = pos;\n while (pos < input.length && /[a-zA-Z0-9_]/.test(input[pos]!)) pos++;\n const word = input.slice(start, pos);\n if (word === 'true' || word === 'false') {\n tokens.push({ type: 'BOOLEAN', value: word, position: start });\n } else if (word === 'null') {\n tokens.push({ type: 'NULL', value: word, position: start });\n } else if (word === 'contains') {\n tokens.push({ type: 'CONTAINS', value: word, position: start });\n } else {\n tokens.push({ type: 'IDENTIFIER', value: word, position: start });\n }\n continue;\n }\n\n throw new LexError(`Unexpected character: ${ch}`, pos);\n }\n\n tokens.push({ type: 'EOF', value: '', position: pos });\n return tokens;\n}\n","// Recursive-descent parser for the WorkflowSkill expression language.\n// Produces an AST from the token stream.\n\nimport type { Token, TokenType } from './lexer.js';\n\n// ─── AST node types ───────────────────────────────────────────────────────────\n\nexport type ASTNode =\n | ReferenceNode\n | PropertyAccessNode\n | IndexAccessNode\n | LiteralNode\n | BinaryNode\n | UnaryNode;\n\n/** $inputs, $steps, $item, $index, $result */\nexport interface ReferenceNode {\n kind: 'reference';\n name: string; // \"inputs\", \"steps\", \"item\", \"index\"\n}\n\n/** a.b.c property access chain */\nexport interface PropertyAccessNode {\n kind: 'property_access';\n object: ASTNode;\n property: string;\n}\n\n/** a[expr] bracket index access */\nexport interface IndexAccessNode {\n kind: 'index_access';\n object: ASTNode;\n index: ASTNode;\n}\n\n/** Literal values: number, string, boolean, null */\nexport interface LiteralNode {\n kind: 'literal';\n value: string | number | boolean | null;\n}\n\n/** Binary operations: ==, !=, >, <, >=, <=, &&, ||, contains */\nexport interface BinaryNode {\n kind: 'binary';\n operator: string;\n left: ASTNode;\n right: ASTNode;\n}\n\n/** Unary operations: ! */\nexport interface UnaryNode {\n kind: 'unary';\n operator: string;\n operand: ASTNode;\n}\n\n// ─── Parser ───────────────────────────────────────────────────────────────────\n\nexport class ParseExprError extends Error {\n constructor(message: string, public readonly position: number) {\n super(message);\n this.name = 'ParseExprError';\n }\n}\n\nexport function parseExpression(tokens: Token[]): ASTNode {\n let pos = 0;\n\n function current(): Token {\n return tokens[pos]!;\n }\n\n function expect(type: TokenType): Token {\n const tok = current();\n if (tok.type !== type) {\n throw new ParseExprError(\n `Expected ${type} but got ${tok.type} (\"${tok.value}\")`,\n tok.position,\n );\n }\n pos++;\n return tok;\n }\n\n function peek(): Token {\n return tokens[pos]!;\n }\n\n // Grammar (precedence low to high):\n // expression → or_expr\n // or_expr → and_expr ( \"||\" and_expr )*\n // and_expr → comparison ( \"&&\" comparison )*\n // comparison → unary ( (\"==\" | \"!=\" | \">\" | \"<\" | \">=\" | \"<=\") unary )?\n // unary → \"!\" unary | primary\n // primary → reference_chain | literal | \"(\" expression \")\"\n\n function parseOr(): ASTNode {\n let left = parseAnd();\n while (peek().type === 'OR') {\n const op = current().value;\n pos++;\n const right = parseAnd();\n left = { kind: 'binary', operator: op, left, right };\n }\n return left;\n }\n\n function parseAnd(): ASTNode {\n let left = parseComparison();\n while (peek().type === 'AND') {\n const op = current().value;\n pos++;\n const right = parseComparison();\n left = { kind: 'binary', operator: op, left, right };\n }\n return left;\n }\n\n function parseComparison(): ASTNode {\n let left = parseUnary();\n const t = peek().type;\n if (t === 'EQ' || t === 'NEQ' || t === 'GT' || t === 'GTE' || t === 'LT' || t === 'LTE' || t === 'CONTAINS') {\n const op = current().value;\n pos++;\n const right = parseUnary();\n left = { kind: 'binary', operator: op, left, right };\n }\n return left;\n }\n\n function parseUnary(): ASTNode {\n if (peek().type === 'NOT') {\n const op = current().value;\n pos++;\n const operand = parseUnary();\n return { kind: 'unary', operator: op, operand };\n }\n return parsePrimary();\n }\n\n function parsePrimary(): ASTNode {\n const tok = peek();\n\n // Parenthesized expression\n if (tok.type === 'LPAREN') {\n pos++;\n const expr = parseOr();\n expect('RPAREN');\n return expr;\n }\n\n // Dollar reference with possible property chain\n if (tok.type === 'DOLLAR_REF') {\n pos++;\n let node: ASTNode = { kind: 'reference', name: tok.value };\n // Postfix chain: .field or [expr]\n while (peek().type === 'DOT' || peek().type === 'LBRACKET') {\n if (peek().type === 'DOT') {\n pos++; // skip dot\n const prop = current();\n if (prop.type === 'IDENTIFIER' || prop.type === 'DOLLAR_REF') {\n pos++;\n node = { kind: 'property_access', object: node, property: prop.value };\n } else if (prop.type === 'NUMBER') {\n // Array index access: .0, .1\n pos++;\n node = { kind: 'property_access', object: node, property: prop.value };\n } else {\n throw new ParseExprError(\n `Expected property name after '.', got ${prop.type}`,\n prop.position,\n );\n }\n } else {\n // LBRACKET — bracket index access: [expr]\n pos++; // skip [\n const indexExpr = parseOr();\n expect('RBRACKET');\n node = { kind: 'index_access', object: node, index: indexExpr };\n }\n }\n return node;\n }\n\n // Number literal\n if (tok.type === 'NUMBER') {\n pos++;\n const num = tok.value.includes('.') ? parseFloat(tok.value) : parseInt(tok.value, 10);\n return { kind: 'literal', value: num };\n }\n\n // String literal\n if (tok.type === 'STRING') {\n pos++;\n return { kind: 'literal', value: tok.value };\n }\n\n // Boolean literal\n if (tok.type === 'BOOLEAN') {\n pos++;\n return { kind: 'literal', value: tok.value === 'true' };\n }\n\n // Null literal\n if (tok.type === 'NULL') {\n pos++;\n return { kind: 'literal', value: null };\n }\n\n throw new ParseExprError(\n `Unexpected token: ${tok.type} (\"${tok.value}\")`,\n tok.position,\n );\n }\n\n const ast = parseOr();\n\n // Ensure we consumed all tokens (except EOF)\n if (peek().type !== 'EOF') {\n const leftover = peek();\n throw new ParseExprError(\n `Unexpected token after expression: ${leftover.type} (\"${leftover.value}\")`,\n leftover.position,\n );\n }\n\n return ast;\n}\n","// Evaluator for the WorkflowSkill expression language.\n// Takes an AST and a RuntimeContext, produces a resolved value.\n\nimport type { RuntimeContext } from '../types/index.js';\nimport type { ASTNode } from './parser.js';\n\nexport class EvalError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'EvalError';\n }\n}\n\n/**\n * Evaluate an AST node against a runtime context.\n * Returns the resolved value (primitive, object, array, or null).\n */\nexport function evaluate(node: ASTNode, context: RuntimeContext): unknown {\n switch (node.kind) {\n case 'reference':\n return resolveReference(node.name, context);\n\n case 'property_access':\n return resolvePropertyAccess(node, context);\n\n case 'index_access':\n return resolveIndexAccess(node, context);\n\n case 'literal':\n return node.value;\n\n case 'binary':\n return evaluateBinary(node.operator, node.left, node.right, context);\n\n case 'unary':\n return evaluateUnary(node.operator, node.operand, context);\n }\n}\n\nfunction resolveReference(name: string, context: RuntimeContext): unknown {\n switch (name) {\n case 'inputs':\n return context.inputs;\n case 'steps':\n return context.steps;\n case 'item':\n return context.item;\n case 'index':\n return context.index;\n case 'result':\n return context.result;\n default:\n throw new EvalError(`Unknown reference: $${name}`);\n }\n}\n\nfunction resolvePropertyAccess(\n node: { object: ASTNode; property: string },\n context: RuntimeContext,\n): unknown {\n const obj = evaluate(node.object, context);\n\n if (obj === null || obj === undefined) {\n return undefined;\n }\n\n // Special property: .length on arrays\n if (node.property === 'length' && Array.isArray(obj)) {\n return obj.length;\n }\n\n if (typeof obj === 'object') {\n return (obj as Record<string, unknown>)[node.property];\n }\n\n return undefined;\n}\n\nfunction resolveIndexAccess(\n node: { object: ASTNode; index: ASTNode },\n context: RuntimeContext,\n): unknown {\n const obj = evaluate(node.object, context);\n const idx = evaluate(node.index, context);\n\n if (obj === null || obj === undefined) {\n return undefined;\n }\n\n if (Array.isArray(obj) && typeof idx === 'number') {\n return obj[idx];\n }\n\n if (typeof obj === 'object') {\n const key = typeof idx === 'number' ? String(idx) : idx;\n if (typeof key === 'string') {\n return (obj as Record<string, unknown>)[key];\n }\n }\n\n return undefined;\n}\n\nfunction evaluateBinary(\n op: string,\n left: ASTNode,\n right: ASTNode,\n context: RuntimeContext,\n): unknown {\n const lval = evaluate(left, context);\n const rval = evaluate(right, context);\n\n switch (op) {\n case '==':\n return lval === rval;\n case '!=':\n return lval !== rval;\n case '>':\n return toNumber(lval) > toNumber(rval);\n case '<':\n return toNumber(lval) < toNumber(rval);\n case '>=':\n return toNumber(lval) >= toNumber(rval);\n case '<=':\n return toNumber(lval) <= toNumber(rval);\n case '&&':\n // Returns boolean (not short-circuit value). The expression language is designed\n // for boolean guards (e.g. condition fields), not value coalescing.\n return isTruthy(lval) && isTruthy(rval);\n case '||':\n return isTruthy(lval) || isTruthy(rval);\n case 'contains':\n if (Array.isArray(lval)) return lval.includes(rval);\n return String(lval ?? '').includes(String(rval ?? ''));\n default:\n throw new EvalError(`Unknown operator: ${op}`);\n }\n}\n\nfunction evaluateUnary(op: string, operand: ASTNode, context: RuntimeContext): unknown {\n const val = evaluate(operand, context);\n switch (op) {\n case '!':\n return !isTruthy(val);\n default:\n throw new EvalError(`Unknown unary operator: ${op}`);\n }\n}\n\nfunction toNumber(val: unknown): number {\n if (typeof val === 'number') return val;\n if (typeof val === 'string') {\n const n = Number(val);\n if (!isNaN(n)) return n;\n }\n if (typeof val === 'boolean') return val ? 1 : 0;\n return 0;\n}\n\nfunction isTruthy(val: unknown): boolean {\n if (val === null || val === undefined) return false;\n if (typeof val === 'boolean') return val;\n if (typeof val === 'number') return val !== 0;\n if (typeof val === 'string') return val.length > 0;\n if (Array.isArray(val)) return val.length > 0;\n return true; // objects are truthy\n}\n","// Expression evaluator public API.\n// Provides resolveExpression (for source/condition/where/each fields)\n// and resolveTemplate (for ${...} template interpolation).\n\nimport type { RuntimeContext } from '../types/index.js';\nimport { lex } from './lexer.js';\nimport { parseExpression } from './parser.js';\nimport { evaluate } from './evaluator.js';\n\nexport { LexError } from './lexer.js';\nexport { ParseExprError } from './parser.js';\nexport { EvalError } from './evaluator.js';\n\n/**\n * Resolve a single expression string against a runtime context.\n * Used for source, condition, where, each, and output fields.\n * Example: \"$steps.fetch.output.messages.length >= 5\"\n */\nexport function resolveExpression(expr: string, context: RuntimeContext): unknown {\n const tokens = lex(expr);\n const ast = parseExpression(tokens);\n return evaluate(ast, context);\n}\n\n/**\n * Returns true if the string contains at least one ${...} template block.\n */\nexport function containsTemplate(value: string): boolean {\n return /\\$\\{[^}]+\\}/.test(value);\n}\n\n/**\n * Resolve a ${...} template string against a runtime context.\n *\n * Two modes:\n * - Whole-value `${ref}` (nothing else) — type is preserved (not coerced to string).\n * - Multi-block — each `${ref}` is evaluated and spliced into the surrounding string.\n * Use `$${` to produce a literal `${` inside a template.\n *\n * Inside `${...}`, references omit the leading `$` (the `$` is part of the delimiter).\n * Example: `\"https://example.com?q=${inputs.query}\"` → resolves `$inputs.query`.\n */\nexport function resolveTemplate(template: string, context: RuntimeContext): unknown {\n // Whole-value ${ref} — preserve the typed result\n const single = template.match(/^\\$\\{([^}]+)\\}$/);\n if (single) {\n return resolveExpression('$' + single[1]!, context);\n }\n // Multi-block: interpolate all ${...} blocks; ${ is the escape for literal ${\n return template.replace(/\\$\\$\\{|\\$\\{([^}]+)\\}/g, (match, expr?: string) => {\n if (match === '$${') return '${';\n return stringify(resolveExpression('$' + expr!, context));\n });\n}\n\n/**\n * Coerce a value to its string representation for prompt interpolation.\n * Per the spec: objects/arrays → JSON, null → empty string.\n */\nexport function stringify(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n return JSON.stringify(value);\n}\n","// Internal parse helper shared by runWorkflowSkill and validateWorkflowSkill.\n// Not exported from the barrel — internal use only.\n//\n// Tries parseSkillMd first (full SKILL.md with frontmatter), then falls back\n// to parseWorkflowFromMd (bare workflow YAML block). Returns a discriminated\n// union so callers never need to catch.\n\nimport { parseSkillMd, parseWorkflowFromMd, ParseError } from './index.js';\nimport type { WorkflowDefinition } from '../types/index.js';\n\nexport type ParseContentResult =\n | { ok: true; workflow: WorkflowDefinition; name: string | undefined }\n | { ok: false; message: string; details?: Array<{ path: string; message: string }> };\n\n/**\n * Parse content that is either a full SKILL.md or a bare workflow YAML block.\n * Never throws — failures are encoded in the returned union.\n */\nexport function parseContent(content: string): ParseContentResult {\n if (!content.trim()) {\n return { ok: false, message: 'Content is empty' };\n }\n\n // Try full SKILL.md (with frontmatter) first\n try {\n const skill = parseSkillMd(content);\n return { ok: true, workflow: skill.workflow, name: skill.frontmatter.name };\n } catch {\n // Fall through to bare workflow YAML\n }\n\n // Fall back to bare workflow block\n try {\n const workflow = parseWorkflowFromMd(content);\n return { ok: true, workflow, name: undefined };\n } catch (err) {\n let message: string;\n let details: Array<{ path: string; message: string }> | undefined;\n if (err instanceof ParseError) {\n message = err.message;\n details = err.details.length > 0 ? err.details : undefined;\n } else {\n message = err instanceof Error ? err.message : String(err);\n }\n return { ok: false, message, details };\n }\n}\n","// Pre-execution workflow validator.\n// Checks DAG resolution, type compatibility, tool availability, and structural correctness.\n// Returns ALL errors, not just the first.\n\nimport type {\n WorkflowDefinition,\n Step,\n ValidationError,\n ValidationResult,\n ToolAdapter,\n ConditionalStep,\n} from '../types/index.js';\nimport { parseContent } from '../parser/parse-content.js';\n\n/**\n * Validate a workflow definition before execution.\n * Checks structural correctness, reference graph, type compatibility, and tool availability.\n * Returns all errors found — does not fail fast.\n */\nexport function validateWorkflow(\n workflow: WorkflowDefinition,\n toolAdapter?: ToolAdapter,\n): ValidationResult {\n const errors: ValidationError[] = [];\n\n // Build step lookup\n const stepMap = new Map<string, Step>();\n const stepOrder = new Map<string, number>();\n for (let i = 0; i < workflow.steps.length; i++) {\n const step = workflow.steps[i]!;\n stepOrder.set(step.id, i);\n\n if (stepMap.has(step.id)) {\n errors.push({\n path: `steps[${i}].id`,\n message: `Duplicate step ID \"${step.id}\"`,\n });\n }\n stepMap.set(step.id, step);\n }\n\n // Collect branch step IDs (steps referenced in conditional then/else)\n const branchStepIds = new Set<string>();\n for (const step of workflow.steps) {\n if (step.type === 'conditional') {\n for (const id of step.then) branchStepIds.add(id);\n if (step.else) {\n for (const id of step.else) branchStepIds.add(id);\n }\n }\n }\n\n // Per-step checks\n for (let i = 0; i < workflow.steps.length; i++) {\n const step = workflow.steps[i]!;\n const path = `steps[${i}]`;\n\n // Structural: `each` not valid on exit steps\n if (step.each && step.type === 'exit') {\n errors.push({\n path: `${path}.each`,\n message: `\"each\" is not valid on exit steps`,\n });\n }\n\n // Structural: `each` not valid on conditional steps\n if (step.each && step.type === 'conditional') {\n errors.push({\n path: `${path}.each`,\n message: `\"each\" is not valid on conditional steps`,\n });\n }\n\n // Structural: `delay` requires `each`\n if (step.delay && !step.each) {\n errors.push({\n path: `${path}.delay`,\n message: `\"delay\" requires \"each\" to be present`,\n });\n }\n\n // Tool availability\n if (step.type === 'tool' && toolAdapter && !toolAdapter.has(step.tool)) {\n errors.push({\n path: `${path}.tool`,\n message: `Tool \"${step.tool}\" is not registered`,\n });\n }\n\n // Validate $steps references in input values (expressions and templates)\n for (const [inputName, input] of Object.entries(step.inputs)) {\n if (typeof input.value === 'string' && hasStepReferences(input.value)) {\n validateSourceReference(\n input.value,\n step.id,\n `${path}.inputs.${inputName}.value`,\n stepMap,\n stepOrder,\n branchStepIds,\n errors,\n );\n }\n }\n\n // Validate guard condition references\n if (step.condition) {\n validateExpressionReferences(\n step.condition,\n step.id,\n `${path}.condition`,\n stepMap,\n stepOrder,\n branchStepIds,\n errors,\n );\n }\n\n // Validate each references\n if (step.each) {\n validateExpressionReferences(\n step.each,\n step.id,\n `${path}.each`,\n stepMap,\n stepOrder,\n branchStepIds,\n errors,\n );\n }\n\n // Conditional: validate branch step IDs exist\n if (step.type === 'conditional') {\n validateBranchReferences(step, i, stepMap, errors);\n }\n\n // Exit: validate output expression references\n if (step.type === 'exit' && step.output) {\n if (typeof step.output === 'string') {\n validateExpressionReferences(\n step.output,\n step.id,\n `${path}.output`,\n stepMap,\n stepOrder,\n branchStepIds,\n errors,\n );\n } else {\n // Object literal — validate expression values within it\n for (const [key, val] of Object.entries(step.output)) {\n if (typeof val === 'string' && val.startsWith('$')) {\n validateExpressionReferences(\n val,\n step.id,\n `${path}.output.${key}`,\n stepMap,\n stepOrder,\n branchStepIds,\n errors,\n );\n }\n }\n }\n }\n }\n\n // Validate workflow output value references (expressions and templates)\n for (const [outputName, outputDef] of Object.entries(workflow.outputs)) {\n if (typeof outputDef.value === 'string' && hasStepReferences(outputDef.value)) {\n const refs = extractStepReferences(outputDef.value);\n for (const refId of refs) {\n if (!stepMap.has(refId)) {\n errors.push({\n path: `outputs.${outputName}.value`,\n message: `References undefined step \"${refId}\"`,\n });\n }\n }\n }\n }\n\n // Check for cycles in the step reference graph\n const cycleErrors = detectCycles(workflow.steps, stepMap);\n errors.push(...cycleErrors);\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n\n/**\n * Extract step IDs referenced from an expression or template string.\n * Handles both expression form ($steps.<id>) and template form (${steps.<id>...}).\n */\nfunction extractStepReferences(expr: string): string[] {\n const refs: string[] = [];\n // Expression form: $steps.<id>\n const exprRegex = /\\$steps\\.([a-zA-Z_][a-zA-Z0-9_]*)/g;\n // Template form: ${steps.<id>...}\n const tmplRegex = /\\$\\{steps\\.([a-zA-Z_][a-zA-Z0-9_]*)/g;\n let match;\n while ((match = exprRegex.exec(expr)) !== null) refs.push(match[1]!);\n while ((match = tmplRegex.exec(expr)) !== null) refs.push(match[1]!);\n // Deduplicate\n return [...new Set(refs)];\n}\n\n/** Returns true if the string contains $steps references in either expression or template form. */\nfunction hasStepReferences(value: string): boolean {\n return value.startsWith('$steps.') || /\\$\\{steps\\./.test(value);\n}\n\n/**\n * Validate that a source expression references valid, earlier-defined steps.\n */\nfunction validateSourceReference(\n source: string,\n currentStepId: string,\n path: string,\n stepMap: Map<string, Step>,\n stepOrder: Map<string, number>,\n branchStepIds: Set<string>,\n errors: ValidationError[],\n): void {\n const refs = extractStepReferences(source);\n const currentOrder = stepOrder.get(currentStepId) ?? -1;\n\n for (const refId of refs) {\n if (!stepMap.has(refId)) {\n errors.push({\n path,\n message: `References undefined step \"${refId}\"`,\n });\n } else {\n const refOrder = stepOrder.get(refId) ?? -1;\n // A step can only reference steps declared before it (or branch targets\n // which may be later in the array but only execute when selected).\n if (refOrder >= currentOrder && !branchStepIds.has(currentStepId)) {\n errors.push({\n path,\n message: `Step \"${currentStepId}\" references step \"${refId}\" which is not declared before it`,\n });\n }\n }\n }\n}\n\n/**\n * Validate expression references (condition, each, output).\n */\nfunction validateExpressionReferences(\n expr: string,\n currentStepId: string,\n path: string,\n stepMap: Map<string, Step>,\n stepOrder: Map<string, number>,\n branchStepIds: Set<string>,\n errors: ValidationError[],\n): void {\n const refs = extractStepReferences(expr);\n const currentOrder = stepOrder.get(currentStepId) ?? -1;\n\n for (const refId of refs) {\n if (!stepMap.has(refId)) {\n errors.push({\n path,\n message: `References undefined step \"${refId}\"`,\n });\n } else {\n const refOrder = stepOrder.get(refId) ?? -1;\n if (refOrder >= currentOrder && !branchStepIds.has(currentStepId)) {\n errors.push({\n path,\n message: `Step \"${currentStepId}\" references step \"${refId}\" which is not declared before it`,\n });\n }\n }\n }\n}\n\n/**\n * Validate conditional step branch references.\n */\nfunction validateBranchReferences(\n step: ConditionalStep,\n stepIndex: number,\n stepMap: Map<string, Step>,\n errors: ValidationError[],\n): void {\n const path = `steps[${stepIndex}]`;\n\n for (const id of step.then) {\n if (!stepMap.has(id)) {\n errors.push({\n path: `${path}.then`,\n message: `Branch references undefined step \"${id}\"`,\n });\n }\n }\n\n if (step.else) {\n for (const id of step.else) {\n if (!stepMap.has(id)) {\n errors.push({\n path: `${path}.else`,\n message: `Branch references undefined step \"${id}\"`,\n });\n }\n }\n }\n}\n\n/**\n * Detect cycles in the step reference graph.\n * Steps form a DAG through $steps references. Cycles would cause infinite loops.\n */\nfunction detectCycles(\n steps: Step[],\n stepMap: Map<string, Step>,\n): ValidationError[] {\n const errors: ValidationError[] = [];\n\n // Build adjacency list: step → set of steps it depends on\n const deps = new Map<string, Set<string>>();\n for (const step of steps) {\n const stepDeps = new Set<string>();\n\n // Collect data-flow dependencies from $steps references (expressions and templates).\n // Conditional branch targets are execution-order dependencies, NOT data-flow edges —\n // adding them here causes false cycle reports when branch steps reference the conditional.\n for (const input of Object.values(step.inputs)) {\n if (typeof input.value === 'string') {\n for (const ref of extractStepReferences(input.value)) {\n stepDeps.add(ref);\n }\n }\n }\n if (step.condition) {\n for (const ref of extractStepReferences(step.condition)) {\n stepDeps.add(ref);\n }\n }\n if (step.each) {\n for (const ref of extractStepReferences(step.each)) {\n stepDeps.add(ref);\n }\n }\n\n deps.set(step.id, stepDeps);\n }\n\n // Topological sort via DFS with cycle detection\n const visited = new Set<string>();\n const inStack = new Set<string>();\n\n function dfs(nodeId: string, pathStack: string[]): boolean {\n if (inStack.has(nodeId)) {\n const cycleStart = pathStack.indexOf(nodeId);\n const cycle = pathStack.slice(cycleStart).concat(nodeId);\n errors.push({\n path: `steps`,\n message: `Cycle detected: ${cycle.join(' → ')}`,\n });\n return true;\n }\n\n if (visited.has(nodeId)) return false;\n\n visited.add(nodeId);\n inStack.add(nodeId);\n pathStack.push(nodeId);\n\n const nodeDeps = deps.get(nodeId) ?? new Set();\n for (const dep of nodeDeps) {\n if (stepMap.has(dep)) {\n dfs(dep, pathStack);\n }\n }\n\n pathStack.pop();\n inStack.delete(nodeId);\n return false;\n }\n\n for (const step of steps) {\n if (!visited.has(step.id)) {\n dfs(step.id, []);\n }\n }\n\n return errors;\n}\n\n// ─── High-level API ──────────────────────────────────────────────────────────\n\nexport interface ValidateWorkflowSkillOptions {\n content: string;\n toolAdapter?: ToolAdapter;\n}\n\nexport interface ValidateWorkflowSkillResult {\n valid: boolean;\n errors: Array<{ path: string; message: string }>;\n name?: string;\n stepCount?: number;\n stepTypes?: string[];\n}\n\n/**\n * Parse content and validate the workflow in one synchronous call.\n * Matches the shape of the plugin's ValidateResult exactly.\n */\nexport function validateWorkflowSkill(options: ValidateWorkflowSkillOptions): ValidateWorkflowSkillResult {\n const { content, toolAdapter } = options;\n\n const parsed = parseContent(content);\n if (!parsed.ok) {\n return {\n valid: false,\n errors: parsed.details ?? [{ path: 'parse', message: parsed.message }],\n };\n }\n\n const result = validateWorkflow(parsed.workflow, toolAdapter);\n if (!result.valid) {\n return { valid: false, errors: result.errors };\n }\n\n const stepTypes = [...new Set(parsed.workflow.steps.map((s) => s.type))];\n return {\n valid: true,\n errors: [],\n name: parsed.name,\n stepCount: parsed.workflow.steps.length,\n stepTypes,\n };\n}\n","// Mock tool adapter for testing.\n// Allows registering per-tool handlers that return configurable results.\n\nimport type { ToolAdapter, ToolDescriptor, ToolResult } from '../types/index.js';\n\n/** Handler function for a registered mock tool. */\nexport type ToolHandler = (args: Record<string, unknown>) => ToolResult | Promise<ToolResult>;\n\nexport class MockToolAdapter implements ToolAdapter {\n private tools = new Map<\n string,\n { handler: ToolHandler; descriptor: ToolDescriptor }\n >();\n\n /** Register a tool handler with optional descriptor metadata. */\n register(\n toolName: string,\n handler: ToolHandler,\n descriptor?: Omit<ToolDescriptor, 'name'>,\n ): void {\n this.tools.set(toolName, {\n handler,\n descriptor: {\n name: toolName,\n description: descriptor?.description ?? '',\n ...(descriptor?.inputSchema && { inputSchema: descriptor.inputSchema }),\n ...(descriptor?.outputSchema && { outputSchema: descriptor.outputSchema }),\n },\n });\n }\n\n has(toolName: string): boolean {\n return this.tools.has(toolName);\n }\n\n /** List all registered tools with their descriptors. */\n list(): ToolDescriptor[] {\n return [...this.tools.values()].map((t) => t.descriptor);\n }\n\n async invoke(toolName: string, args: Record<string, unknown>): Promise<ToolResult> {\n const entry = this.tools.get(toolName);\n if (!entry) {\n return { output: null, error: `Tool \"${toolName}\" not registered` };\n }\n return entry.handler(args);\n }\n}\n","// Configuration loader — reads env vars with .env fallback.\n// No external dependencies (simple KEY=VALUE parser).\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/** WorkflowSkill configuration. Reserved for future host-level configuration. */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface WorkflowSkillConfig {}\n\n/**\n * Parse a .env file into key-value pairs.\n * Supports KEY=VALUE format, blank lines, and # comments.\n * Values may be optionally quoted with single or double quotes.\n */\nfunction parseDotenv(content: string): Record<string, string> {\n const vars: Record<string, string> = {};\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eqIdx = trimmed.indexOf('=');\n if (eqIdx === -1) continue;\n const key = trimmed.slice(0, eqIdx).trim();\n let value = trimmed.slice(eqIdx + 1).trim();\n // Strip surrounding quotes\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n vars[key] = value;\n }\n return vars;\n}\n\n/**\n * Find the package root by walking up from this module's directory\n * until we find a directory containing package.json.\n */\nfunction findPackageRoot(): string | undefined {\n let dir = dirname(fileURLToPath(import.meta.url));\n while (true) {\n if (existsSync(join(dir, 'package.json'))) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break; // true filesystem root\n dir = parent;\n }\n return undefined;\n}\n\n/**\n * Load configuration from environment variables, with .env fallback.\n * Environment variables take precedence over .env file values.\n *\n * .env search order:\n * 1. Explicit `cwd` parameter (for tests)\n * 2. Package root (found by walking up from this module)\n * 3. process.cwd()\n */\nexport function loadConfig(cwd?: string): WorkflowSkillConfig {\n // Try to read .env file (kept for future host-level config)\n let dotenvVars: Record<string, string> = {};\n const searchDirs = cwd\n ? [cwd]\n : [findPackageRoot(), process.cwd()].filter((d): d is string => d !== undefined);\n\n for (const dir of searchDirs) {\n try {\n const envPath = join(dir, '.env');\n const content = readFileSync(envPath, 'utf-8');\n dotenvVars = parseDotenv(content);\n break; // use the first .env found\n } catch {\n // No .env file in this directory — try next\n }\n }\n\n // Suppress unused variable warning — dotenvVars kept for future use\n void dotenvVars;\n\n return {};\n}\n","// Transform step executor: filter, map, sort.\n// Pure data manipulation — no external calls, no LLM.\n\nimport type {\n TransformStep,\n TransformFilterStep,\n TransformMapStep,\n TransformSortStep,\n RuntimeContext,\n} from '../types/index.js';\nimport { resolveExpression } from '../expression/index.js';\n\n/**\n * Execute a transform step.\n * Returns an object with the first declared output key mapped to the transformed array.\n */\nexport function executeTransform(\n step: TransformStep,\n resolvedInputs: Record<string, unknown>,\n context: RuntimeContext,\n): Record<string, unknown> {\n const items = getInputArray(resolvedInputs);\n let result: unknown[];\n\n switch (step.operation) {\n case 'filter':\n result = executeFilter(step, items, context);\n break;\n case 'map':\n result = executeMap(step, items, context);\n break;\n case 'sort':\n result = executeSort(step, items);\n break;\n }\n\n const outputKey = Object.keys(step.outputs)[0] ?? 'items';\n return { [outputKey]: result };\n}\n\n/** Find the array to transform from resolved inputs. */\nfunction getInputArray(inputs: Record<string, unknown>): unknown[] {\n // Convention: look for 'items' key first\n if ('items' in inputs && Array.isArray(inputs.items)) return inputs.items;\n // Fall back to first array value\n for (const val of Object.values(inputs)) {\n if (Array.isArray(val)) return val;\n }\n // Wrap single value in array for single-item transforms (e.g., echo fixture)\n const first = Object.values(inputs)[0];\n return first != null ? [first] : [];\n}\n\n/** Filter: keep items where the `where` expression is truthy. */\nfunction executeFilter(\n step: TransformFilterStep,\n items: unknown[],\n context: RuntimeContext,\n): unknown[] {\n return items.filter((item, index) => {\n const itemCtx: RuntimeContext = { ...context, item, index };\n return Boolean(resolveExpression(step.where, itemCtx));\n });\n}\n\n/** Map: project each item into a new shape using the `expression` object. */\nfunction executeMap(\n step: TransformMapStep,\n items: unknown[],\n context: RuntimeContext,\n): unknown[] {\n return items.map((item, index) => {\n const itemCtx: RuntimeContext = { ...context, item, index };\n const result: Record<string, unknown> = {};\n for (const [key, expr] of Object.entries(step.expression)) {\n result[key] = resolveMapValue(expr, itemCtx);\n }\n return result;\n });\n}\n\n/**\n * Resolve a map expression value.\n * - String starting with `$` → expression reference\n * - Non-string primitive (number, boolean, null) → pass through as literal\n * - Object (non-array) → recurse, applying same rules to each value\n * - String not starting with `$` → literal string\n */\nfunction resolveMapValue(value: unknown, context: RuntimeContext): unknown {\n if (typeof value === 'string') {\n if (value.startsWith('$')) {\n return resolveExpression(value, context);\n }\n return value;\n }\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n result[k] = resolveMapValue(v, context);\n }\n return result;\n }\n return value;\n}\n\n/** Sort: order items by a field path in the given direction (default: asc). */\nfunction executeSort(step: TransformSortStep, items: unknown[]): unknown[] {\n const direction = step.direction ?? 'asc';\n return [...items].sort((a, b) => {\n const aVal = getNestedField(a, step.field);\n const bVal = getNestedField(b, step.field);\n if (aVal == null && bVal == null) return 0;\n if (aVal == null) return 1;\n if (bVal == null) return -1;\n if (aVal < bVal) return direction === 'asc' ? -1 : 1;\n if (aVal > bVal) return direction === 'asc' ? 1 : -1;\n return 0;\n });\n}\n\n/** Access a nested field by dot-notation path (e.g., \"user.name\"). */\nfunction getNestedField(obj: unknown, path: string): unknown {\n const parts = path.split('.');\n let current: unknown = obj;\n for (const part of parts) {\n if (current == null || typeof current !== 'object') return undefined;\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n}\n","// Conditional step executor.\n// Evaluates the condition and returns which branch to take.\n\nimport type { ConditionalStep, RuntimeContext } from '../types/index.js';\nimport type { ConditionalOutput } from './types.js';\nimport { resolveExpression } from '../expression/index.js';\n\n/**\n * Execute a conditional step.\n * Evaluates the condition expression and returns the branch to execute.\n * The runtime is responsible for executing the branch steps.\n */\nexport function executeConditional(\n step: ConditionalStep,\n context: RuntimeContext,\n): ConditionalOutput {\n const conditionResult = resolveExpression(step.condition, context);\n const isTruthy = Boolean(conditionResult);\n\n if (isTruthy) {\n return { branch: 'then', stepIds: step.then };\n } else if (step.else) {\n return { branch: 'else', stepIds: step.else };\n } else {\n return { branch: null, stepIds: [] };\n }\n}\n","// Exit step executor.\n// Resolves the output expression and signals workflow termination.\n\nimport type { ExitStep, RuntimeContext } from '../types/index.js';\nimport type { ExitOutput } from './types.js';\nimport { resolveExpression, containsTemplate, resolveTemplate } from '../expression/index.js';\n\n/**\n * Execute an exit step.\n * Output can be:\n * - A string expression: resolved against context\n * - An object literal: each string value starting with $ is resolved, others kept as-is\n * - Undefined: null output\n */\nexport function executeExit(\n step: ExitStep,\n context: RuntimeContext,\n): ExitOutput {\n let output: unknown = null;\n if (step.output) {\n if (typeof step.output === 'string') {\n output = resolveExpression(step.output, context);\n } else {\n // Object literal — resolve expression values within it\n output = resolveOutputObject(step.output, context);\n }\n }\n return { status: step.status, output };\n}\n\nfunction resolveOutputObject(\n obj: Record<string, unknown>,\n context: RuntimeContext,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(obj)) {\n if (typeof val === 'string') {\n if (val.startsWith('$$')) {\n result[key] = val.slice(1);\n } else if (containsTemplate(val)) {\n result[key] = resolveTemplate(val, context);\n } else if (val.startsWith('$')) {\n result[key] = resolveExpression(val, context);\n } else {\n result[key] = val;\n }\n } else {\n result[key] = val;\n }\n }\n return result;\n}\n","// Executor result types and error class.\n\nimport type { ExitStatus } from '../types/index.js';\n\n/** Additional context attached to a step execution error. */\nexport interface StepErrorContext {\n /** Tool name if the error came from a tool step. */\n tool?: string;\n /** Expression string if the error came from expression resolution. */\n expression?: string;\n}\n\n/** Error thrown by step executors. */\nexport class StepExecutionError extends Error {\n constructor(\n message: string,\n /** Whether this error is retriable (network errors, rate limits, transient API failures). */\n public readonly retriable: boolean = false,\n /** Optional context about the error source. */\n public readonly context?: StepErrorContext,\n ) {\n super(message);\n this.name = 'StepExecutionError';\n }\n}\n\n/** Result from a standard step execution (tool, transform). */\nexport interface StepOutput {\n output: unknown;\n}\n\n/** Result from a conditional step execution. */\nexport interface ConditionalOutput {\n branch: 'then' | 'else' | null;\n stepIds: string[];\n}\n\n/** Result from an exit step execution. */\nexport interface ExitOutput {\n status: ExitStatus;\n output: unknown;\n}\n","// Tool step executor.\n// Invokes a registered tool via the ToolAdapter and returns the response.\n\nimport type { ToolStep, ToolAdapter } from '../types/index.js';\nimport type { StepOutput } from './types.js';\nimport { StepExecutionError } from './types.js';\n\n/**\n * Execute a tool step.\n * Passes resolved inputs as the tool's arguments. Returns the tool's response.\n * The runtime does not interpret the response (per spec).\n */\nexport async function executeTool(\n step: ToolStep,\n resolvedInputs: Record<string, unknown>,\n toolAdapter: ToolAdapter,\n): Promise<StepOutput> {\n const result = await toolAdapter.invoke(step.tool, resolvedInputs);\n if (result.error) {\n // Tool errors are considered retriable (network issues, rate limits, transient failures)\n throw new StepExecutionError(result.error, true, { tool: step.tool });\n }\n return { output: result.output };\n}\n","// Step executor dispatch.\n// Routes each step to the appropriate executor based on its type.\n\nimport type {\n Step,\n ToolAdapter,\n RuntimeContext,\n ExitStatus,\n} from '../types/index.js';\nimport { executeTransform } from './transform.js';\nimport { executeConditional } from './conditional.js';\nimport { executeExit } from './exit.js';\nimport { executeTool } from './tool.js';\n\nexport { StepExecutionError } from './types.js';\nexport type { StepOutput, ConditionalOutput, ExitOutput, StepErrorContext } from './types.js';\nexport { executeTransform } from './transform.js';\nexport { executeConditional } from './conditional.js';\nexport { executeExit } from './exit.js';\nexport { executeTool } from './tool.js';\n\n/** Discriminated result from dispatching a step. */\nexport type DispatchResult =\n | { kind: 'output'; output: unknown }\n | { kind: 'branch'; branch: 'then' | 'else' | null; stepIds: string[] }\n | { kind: 'exit'; status: ExitStatus; output: unknown };\n\n/**\n * Dispatch a step to the appropriate executor.\n * The runtime calls this for each step in the execution loop.\n */\nexport async function dispatch(\n step: Step,\n resolvedInputs: Record<string, unknown>,\n context: RuntimeContext,\n toolAdapter: ToolAdapter,\n): Promise<DispatchResult> {\n switch (step.type) {\n case 'tool': {\n const result = await executeTool(step, resolvedInputs, toolAdapter);\n return { kind: 'output', ...result };\n }\n case 'transform': {\n const output = executeTransform(step, resolvedInputs, context);\n return { kind: 'output', output };\n }\n case 'conditional': {\n const result = executeConditional(step, context);\n return { kind: 'branch', ...result };\n }\n case 'exit': {\n const result = executeExit(step, context);\n return { kind: 'exit', ...result };\n }\n }\n}\n","// Runtime orchestrator.\n// Validates the workflow, executes steps through the 9-step lifecycle, and produces a run log.\n\nimport type {\n WorkflowDefinition,\n WorkflowInput,\n Step,\n StepInput,\n StepOutput,\n RuntimeContext,\n ToolAdapter,\n RunLog,\n RunLogError,\n RunStatus,\n StepRecord,\n RetryRecord,\n ExitStatus,\n ValidationError,\n RuntimeEvent,\n} from '../types/index.js';\nimport { parseContent } from '../parser/parse-content.js';\nimport { resolveExpression, resolveTemplate, containsTemplate } from '../expression/index.js';\nimport { validateWorkflow } from '../validator/index.js';\nimport { dispatch, StepExecutionError } from '../executor/index.js';\nimport type { DispatchResult } from '../executor/index.js';\n\n/** Resolve a value field:\n * 1. starts with $$ → strip one $ (literal escape)\n * 2. contains ${...} → template interpolation\n * 3. starts with $ → whole expression\n * 4. otherwise → literal\n */\nfunction resolveValue(value: unknown, context: RuntimeContext): unknown {\n if (typeof value !== 'string') return value;\n if (value.startsWith('$$')) return value.slice(1);\n if (containsTemplate(value)) return resolveTemplate(value, context);\n if (value.startsWith('$')) return resolveExpression(value, context);\n return value;\n}\n\n/** Emit a runtime event if a callback is registered. */\nfunction emit(onEvent: ((event: RuntimeEvent) => void) | undefined, event: RuntimeEvent): void {\n onEvent?.(event);\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\nexport class WorkflowExecutionError extends Error {\n constructor(\n message: string,\n public readonly validationErrors?: ValidationError[],\n ) {\n super(message);\n this.name = 'WorkflowExecutionError';\n }\n}\n\n/**\n * Build a minimal RunLog for a pre-execution failure (parse or validate phase).\n * Every run attempt — even those that fail before execution begins — produces a structured artifact.\n */\nexport function buildFailedRunLog(\n workflowName: string,\n error: RunLogError,\n startedAt?: Date,\n): RunLog {\n const now = new Date();\n const start = startedAt ?? now;\n const durationMs = now.getTime() - start.getTime();\n return {\n id: crypto.randomUUID(),\n workflow: workflowName,\n status: 'failed',\n summary: {\n steps_executed: 0,\n steps_skipped: 0,\n total_duration_ms: durationMs,\n },\n started_at: start.toISOString(),\n completed_at: now.toISOString(),\n duration_ms: durationMs,\n inputs: {},\n steps: [],\n outputs: {},\n error,\n };\n}\n\nexport interface RunOptions {\n workflow: WorkflowDefinition;\n inputs?: Record<string, unknown>;\n toolAdapter: ToolAdapter;\n workflowName?: string;\n /** Optional callback for live progress events during execution. */\n onEvent?: (event: RuntimeEvent) => void;\n}\n\n/**\n * Execute a workflow and produce a run log.\n * Phase 1: Validate the workflow definition.\n * Phase 2: Execute steps in declaration order following the 9-step lifecycle.\n */\nexport async function runWorkflow(options: RunOptions): Promise<RunLog> {\n const { onEvent } = options;\n const startedAt = new Date();\n\n // Phase 1: Validate\n const validation = validateWorkflow(options.workflow, options.toolAdapter);\n if (!validation.valid) {\n const message = `Workflow validation failed: ${validation.errors.map((e) => e.message).join('; ')}`;\n return buildFailedRunLog(\n options.workflowName ?? 'unnamed',\n {\n phase: 'validate',\n message,\n details: validation.errors,\n },\n startedAt,\n );\n }\n\n const workflowName = options.workflowName ?? 'unnamed';\n emit(onEvent, {\n type: 'workflow_start',\n workflow: workflowName,\n totalSteps: options.workflow.steps.length,\n });\n\n // Phase 2: Execute\n const inputs = applyDefaults(options.workflow.inputs, options.inputs ?? {});\n const context: RuntimeContext = { inputs, steps: {} };\n const stepRecords: StepRecord[] = [];\n\n // Identify branch steps (only execute when selected by conditional)\n const branchStepIds = collectBranchStepIds(options.workflow.steps);\n const stepMap = new Map(options.workflow.steps.map((s) => [s.id, s]));\n\n let workflowStatus: RunStatus = 'success';\n let workflowOutput: unknown = null;\n let exitFired = false;\n let halted = false;\n\n for (const step of options.workflow.steps) {\n if (halted) break;\n\n // Branch steps are skipped during normal sequential execution.\n // They execute only when selected by a conditional step.\n if (branchStepIds.has(step.id)) continue;\n\n const result = await executeStepLifecycle(\n step,\n context,\n stepMap,\n branchStepIds,\n options.toolAdapter,\n onEvent,\n );\n stepRecords.push(...result.records);\n\n if (result.exit) {\n halted = true;\n exitFired = true;\n workflowStatus = result.exit.status === 'failed' ? 'failed' : 'success';\n workflowOutput = result.exit.output;\n } else if (result.failed) {\n halted = true;\n workflowStatus = 'failed';\n } else {\n workflowOutput = context.steps[step.id]?.output ?? null;\n }\n }\n\n // Account for unrecorded steps (spec: \"Every step is accounted for, including skipped ones.\")\n const recordedIds = new Set(stepRecords.map((r) => r.id));\n for (const step of options.workflow.steps) {\n if (!recordedIds.has(step.id)) {\n const reason = branchStepIds.has(step.id) ? 'Branch not selected' : 'Workflow halted';\n emit(onEvent, { type: 'step_skip', stepId: step.id, reason });\n stepRecords.push({\n id: step.id,\n executor: step.type,\n status: 'skipped',\n reason,\n duration_ms: 0,\n });\n }\n }\n\n // Build outputs\n const outputs = buildWorkflowOutputs(options.workflow, workflowOutput, context, exitFired);\n\n const completedAt = new Date();\n const durationMs = completedAt.getTime() - startedAt.getTime();\n\n // Build summary\n let stepsExecuted = 0;\n let stepsSkipped = 0;\n for (const rec of stepRecords) {\n if (rec.status === 'skipped') stepsSkipped++;\n else stepsExecuted++;\n }\n\n const summary = {\n steps_executed: stepsExecuted,\n steps_skipped: stepsSkipped,\n total_duration_ms: durationMs,\n };\n\n emit(onEvent, {\n type: 'workflow_complete',\n status: workflowStatus,\n duration_ms: durationMs,\n summary,\n });\n\n return {\n id: crypto.randomUUID(),\n workflow: workflowName,\n status: workflowStatus,\n summary,\n started_at: startedAt.toISOString(),\n completed_at: completedAt.toISOString(),\n duration_ms: durationMs,\n inputs,\n steps: stepRecords,\n outputs,\n };\n}\n\n// ─── High-level API ──────────────────────────────────────────────────────────\n\nexport interface RunWorkflowSkillOptions {\n /** SKILL.md content or raw workflow YAML block. */\n content: string;\n inputs?: Record<string, unknown>;\n toolAdapter: ToolAdapter;\n /** Fallback name used when content has no frontmatter. Defaults to 'inline'. */\n workflowName?: string;\n onEvent?: (event: RuntimeEvent) => void;\n}\n\n/**\n * Parse content and execute the workflow in one call. Never throws.\n * Empty or unparseable content → failed RunLog (phase: 'parse').\n * Unexpected execution exception → failed RunLog (phase: 'execute').\n * Validation failures are handled internally by runWorkflow.\n */\nexport async function runWorkflowSkill(options: RunWorkflowSkillOptions): Promise<RunLog> {\n const { content, inputs, toolAdapter, workflowName = 'inline', onEvent } = options;\n const startedAt = new Date();\n\n const parsed = parseContent(content);\n if (!parsed.ok) {\n return buildFailedRunLog(workflowName, {\n phase: 'parse',\n message: parsed.message,\n details: parsed.details,\n }, startedAt);\n }\n\n const resolvedName = parsed.name ?? workflowName;\n try {\n return await runWorkflow({\n workflow: parsed.workflow,\n inputs,\n toolAdapter,\n workflowName: resolvedName,\n onEvent,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return buildFailedRunLog(resolvedName, { phase: 'execute', message }, startedAt);\n }\n}\n\n// ─── Step lifecycle ─────────────────────────────────────────────────────────\n\ninterface LifecycleResult {\n records: StepRecord[];\n exit?: { status: ExitStatus; output: unknown };\n failed?: boolean;\n}\n\n/**\n * Execute one step through the 9-step lifecycle:\n * 1. Guard 2. Resolve inputs 3. Iterate (each) 4. Dispatch\n * 5. Map outputs 6. Validate output 7. Retry 8. Handle errors 9. Record\n */\nasync function executeStepLifecycle(\n step: Step,\n context: RuntimeContext,\n stepMap: Map<string, Step>,\n branchStepIds: Set<string>,\n toolAdapter: ToolAdapter,\n onEvent?: (event: RuntimeEvent) => void,\n): Promise<LifecycleResult> {\n const startTime = performance.now();\n const records: StepRecord[] = [];\n\n // 1. Guard — evaluate condition guard (not for conditional steps which use condition differently)\n if (step.condition && step.type !== 'conditional') {\n const guardResult = resolveExpression(step.condition, context);\n if (!guardResult) {\n context.steps[step.id] = { output: null };\n emit(onEvent, { type: 'step_skip', stepId: step.id, reason: 'Guard condition evaluated to false' });\n records.push({\n id: step.id,\n executor: step.type,\n status: 'skipped',\n reason: 'Guard condition evaluated to false',\n duration_ms: Math.round(performance.now() - startTime),\n });\n return { records };\n }\n }\n\n // step_start: emitted after guard passes, before input resolution\n emit(onEvent, {\n type: 'step_start',\n stepId: step.id,\n stepType: step.type,\n tool: step.type === 'tool' ? step.tool : undefined,\n });\n\n // 3. Iterate (each) — if present, execute once per element; each handles its own input resolution\n if (step.each) {\n return executeWithEach(\n step,\n context,\n toolAdapter,\n startTime,\n onEvent,\n );\n }\n\n // 2. Resolve inputs (only for non-each steps)\n const resolvedInputs = resolveInputs(step.inputs, context, step.id);\n\n // 4-7. Dispatch with retry + error handling\n try {\n const { result, retries } = await dispatchWithRetry(\n step,\n resolvedInputs,\n context,\n toolAdapter,\n onEvent,\n );\n\n // Handle dispatch result by kind\n if (result.kind === 'exit') {\n context.steps[step.id] = { output: result.output };\n const durationMs = Math.round(performance.now() - startTime);\n emit(onEvent, { type: 'step_complete', stepId: step.id, status: 'success', duration_ms: durationMs });\n records.push({\n id: step.id,\n executor: 'exit',\n status: 'success',\n duration_ms: durationMs,\n inputs: resolvedInputs,\n output: result.output,\n retries,\n });\n return { records, exit: { status: result.status, output: result.output } };\n }\n\n if (result.kind === 'branch') {\n // Execute the selected branch steps\n const branchRecords = await executeBranch(\n result.stepIds,\n context,\n stepMap,\n branchStepIds,\n toolAdapter,\n onEvent,\n );\n\n // Conditional step output = last branch step output\n const lastBranchStepId = result.stepIds[result.stepIds.length - 1];\n const conditionalOutput = lastBranchStepId\n ? (context.steps[lastBranchStepId]?.output ?? null)\n : null;\n context.steps[step.id] = { output: conditionalOutput };\n\n // Record the conditional step itself\n const durationMs = Math.round(performance.now() - startTime);\n emit(onEvent, { type: 'step_complete', stepId: step.id, status: 'success', duration_ms: durationMs });\n records.push({\n id: step.id,\n executor: 'conditional',\n status: 'success',\n duration_ms: durationMs,\n inputs: resolvedInputs,\n output: conditionalOutput,\n retries,\n });\n // Then the branch step records\n records.push(...branchRecords.records);\n\n return {\n records,\n exit: branchRecords.exit,\n failed: branchRecords.failed,\n };\n }\n\n // Normal output — apply step output source mapping\n const mappedOutput = applyStepOutputMapping(step.outputs, result.output, context);\n context.steps[step.id] = { output: mappedOutput };\n const durationMs = Math.round(performance.now() - startTime);\n emit(onEvent, {\n type: 'step_complete',\n stepId: step.id,\n status: 'success',\n duration_ms: durationMs,\n });\n records.push({\n id: step.id,\n executor: step.type,\n status: 'success',\n duration_ms: durationMs,\n inputs: resolvedInputs,\n output: mappedOutput,\n retries,\n });\n return { records };\n } catch (err) {\n // 6. Handle errors — apply on_error policy\n return handleStepError(step, err, context, startTime, resolvedInputs, undefined, onEvent);\n }\n}\n\n// ─── Each iteration ────────────────────────────────────────────────────────\n\nasync function executeWithEach(\n step: Step,\n context: RuntimeContext,\n toolAdapter: ToolAdapter,\n startTime: number,\n onEvent?: (event: RuntimeEvent) => void,\n): Promise<LifecycleResult> {\n const records: StepRecord[] = [];\n\n const eachArray = resolveExpression(step.each!, context);\n if (!Array.isArray(eachArray)) {\n return handleStepError(\n step,\n new StepExecutionError(`each expression must resolve to an array, got ${typeof eachArray}`),\n context,\n startTime,\n undefined,\n undefined,\n onEvent,\n );\n }\n\n // Resolve inputs with the base context (before iteration) for the record\n const baseResolvedInputs = resolveInputs(step.inputs, context, step.id);\n const results: unknown[] = [];\n let totalRetries: RetryRecord | undefined;\n\n try {\n for (let i = 0; i < eachArray.length; i++) {\n const itemContext: RuntimeContext = {\n ...context,\n item: eachArray[i],\n index: i,\n };\n const iterInputs = resolveInputs(step.inputs, itemContext, step.id);\n const { result, retries } = await dispatchWithRetry(\n step,\n iterInputs,\n itemContext,\n toolAdapter,\n onEvent,\n );\n\n if (retries) {\n totalRetries = totalRetries ?? { attempts: 0, errors: [] };\n totalRetries.attempts += retries.attempts;\n totalRetries.errors.push(...retries.errors);\n }\n\n if (result.kind === 'output') {\n // Apply per-element step output mapping\n const mappedIterOutput = applyStepOutputMapping(step.outputs, result.output, itemContext);\n results.push(mappedIterOutput);\n }\n\n emit(onEvent, { type: 'each_progress', stepId: step.id, current: i + 1, total: eachArray.length });\n\n // Inter-iteration delay for rate limiting\n if (step.delay && i < eachArray.length - 1) {\n await sleep(parseDelay(step.delay));\n }\n }\n } catch (err) {\n return handleStepError(step, err, context, startTime, baseResolvedInputs, totalRetries, onEvent);\n }\n\n context.steps[step.id] = { output: results };\n const durationMs = Math.round(performance.now() - startTime);\n emit(onEvent, {\n type: 'step_complete',\n stepId: step.id,\n status: 'success',\n duration_ms: durationMs,\n iterations: eachArray.length,\n });\n records.push({\n id: step.id,\n executor: step.type,\n status: 'success',\n duration_ms: durationMs,\n inputs: baseResolvedInputs,\n iterations: eachArray.length,\n output: results,\n retries: totalRetries,\n });\n\n return { records };\n}\n\n// ─── Branch execution ──────────────────────────────────────────────────────\n\nasync function executeBranch(\n stepIds: string[],\n context: RuntimeContext,\n stepMap: Map<string, Step>,\n branchStepIds: Set<string>,\n toolAdapter: ToolAdapter,\n onEvent?: (event: RuntimeEvent) => void,\n): Promise<LifecycleResult> {\n const records: StepRecord[] = [];\n\n for (const stepId of stepIds) {\n const branchStep = stepMap.get(stepId);\n if (!branchStep) continue;\n\n const result = await executeStepLifecycle(\n branchStep,\n context,\n stepMap,\n branchStepIds,\n toolAdapter,\n onEvent,\n );\n records.push(...result.records);\n\n if (result.exit) {\n return { records, exit: result.exit };\n }\n if (result.failed) {\n return { records, failed: true };\n }\n }\n\n return { records };\n}\n\n// ─── Retry logic ──────────────────────────────────────────────────────────\n\n/** Result from dispatchWithRetry: the dispatch result plus any retry tracking. */\ninterface RetryDispatchResult {\n result: DispatchResult;\n retries?: RetryRecord;\n}\n\nasync function dispatchWithRetry(\n step: Step,\n resolvedInputs: Record<string, unknown>,\n context: RuntimeContext,\n toolAdapter: ToolAdapter,\n onEvent?: (event: RuntimeEvent) => void,\n): Promise<RetryDispatchResult> {\n const retryPolicy = 'retry' in step ? step.retry : undefined;\n const maxRetries = retryPolicy?.max ?? 0;\n const baseDelay = retryPolicy ? parseDelay(retryPolicy.delay) : 0;\n const backoff = retryPolicy?.backoff ?? 1;\n\n let attempts = 0;\n const retryErrors: string[] = [];\n\n for (;;) {\n try {\n const result = await dispatch(step, resolvedInputs, context, toolAdapter);\n const retries = attempts > 0 ? { attempts, errors: retryErrors } : undefined;\n return { result, retries };\n } catch (err) {\n const isRetriable =\n err instanceof StepExecutionError && err.retriable && attempts < maxRetries;\n if (!isRetriable) {\n // Attach accumulated retry info to the error for handleStepError\n if (attempts > 0 && err instanceof Error) {\n (err as ErrorWithRetries).__retries = { attempts, errors: retryErrors };\n }\n throw err;\n }\n\n const errorMessage = err instanceof Error ? err.message : String(err);\n retryErrors.push(errorMessage);\n attempts++;\n emit(onEvent, { type: 'step_retry', stepId: step.id, attempt: attempts, error: errorMessage });\n const delay = baseDelay * Math.pow(backoff, attempts - 1);\n await sleep(delay);\n }\n }\n}\n\n// ─── Error handling ────────────────────────────────────────────────────────\n\n/** Error augmented with retry info by dispatchWithRetry. */\ninterface ErrorWithRetries extends Error {\n __retries?: RetryRecord;\n}\n\nfunction handleStepError(\n step: Step,\n err: unknown,\n context: RuntimeContext,\n startTime: number,\n resolvedInputs?: Record<string, unknown>,\n retries?: RetryRecord,\n onEvent?: (event: RuntimeEvent) => void,\n): LifecycleResult {\n // Enrich error message with context (tool name, expression)\n let errorMessage = err instanceof Error ? err.message : String(err);\n if (err instanceof StepExecutionError && err.context?.tool) {\n errorMessage = `Tool \"${err.context.tool}\": ${errorMessage}`;\n }\n // Extract retry info attached by dispatchWithRetry if not passed explicitly\n const effectiveRetries = retries ?? (err instanceof Error ? (err as ErrorWithRetries).__retries : undefined);\n const onError = step.on_error ?? 'fail';\n const durationMs = Math.round(performance.now() - startTime);\n\n context.steps[step.id] = { output: null };\n\n const record: StepRecord = {\n id: step.id,\n executor: step.type,\n status: 'failed',\n duration_ms: durationMs,\n inputs: resolvedInputs,\n error: errorMessage,\n retries: effectiveRetries,\n };\n\n emit(onEvent, { type: 'step_error', stepId: step.id, error: errorMessage, onError });\n emit(onEvent, { type: 'step_complete', stepId: step.id, status: 'failed', duration_ms: durationMs });\n\n if (onError === 'ignore') {\n // Log the error, set output to null, continue\n return { records: [record] };\n }\n\n // on_error: fail — halt the workflow\n return { records: [record], failed: true };\n}\n\n// ─── Input resolution ──────────────────────────────────────────────────────\n\nfunction resolveInputs(\n stepInputs: Record<string, StepInput>,\n context: RuntimeContext,\n stepId?: string,\n): Record<string, unknown> {\n const resolved: Record<string, unknown> = {};\n for (const [key, input] of Object.entries(stepInputs)) {\n if (input.value !== undefined) {\n try {\n resolved[key] = resolveValue(input.value, context);\n } catch (err) {\n const expr = typeof input.value === 'string' ? input.value : JSON.stringify(input.value);\n const prefix = stepId ? `Step \"${stepId}\" input \"${key}\"` : `Input \"${key}\"`;\n throw new StepExecutionError(\n `${prefix}: failed to resolve expression ${expr}: ${err instanceof Error ? err.message : String(err)}`,\n false,\n { expression: typeof input.value === 'string' ? input.value : undefined },\n );\n }\n }\n // If no value, the key is omitted (not set to null)\n }\n return resolved;\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────\n\nfunction applyDefaults(\n schema: Record<string, WorkflowInput>,\n provided: Record<string, unknown>,\n): Record<string, unknown> {\n const result = { ...provided };\n for (const [key, def] of Object.entries(schema)) {\n if (!(key in result) && def.default !== undefined) {\n result[key] = def.default;\n }\n }\n return result;\n}\n\nfunction collectBranchStepIds(steps: Step[]): Set<string> {\n const ids = new Set<string>();\n for (const step of steps) {\n if (step.type === 'conditional') {\n for (const id of step.then) ids.add(id);\n if (step.else) {\n for (const id of step.else) ids.add(id);\n }\n }\n }\n return ids;\n}\n\n/**\n * Apply step output value mapping.\n * For each declared output with a `value` expression, resolve against the raw executor result.\n * Outputs without `value` pass through from raw output by key name.\n */\nfunction applyStepOutputMapping(\n stepOutputs: Record<string, StepOutput>,\n rawOutput: unknown,\n context: RuntimeContext,\n): unknown {\n const hasValues = Object.values(stepOutputs).some((o) => o.value !== undefined);\n if (!hasValues) return rawOutput;\n\n // Create a temporary context with $result set to the raw executor result\n const tempContext: RuntimeContext = { ...context, result: rawOutput };\n const mapped: Record<string, unknown> = {};\n\n for (const [key, outputDef] of Object.entries(stepOutputs)) {\n if (outputDef.value !== undefined) {\n mapped[key] = resolveValue(outputDef.value, tempContext);\n } else if (rawOutput !== null && typeof rawOutput === 'object' && !Array.isArray(rawOutput)) {\n // Pass through by key name from raw output\n mapped[key] = (rawOutput as Record<string, unknown>)[key] ?? null;\n } else {\n mapped[key] = null;\n }\n }\n\n return mapped;\n}\n\nfunction buildWorkflowOutputs(\n workflow: WorkflowDefinition,\n finalOutput: unknown,\n context: RuntimeContext,\n exitFired: boolean,\n): Record<string, unknown> {\n const outputKeys = Object.keys(workflow.outputs);\n if (outputKeys.length === 0) return {};\n\n // If exit fired, use exit output (unchanged behavior)\n if (exitFired) {\n if (finalOutput !== null && typeof finalOutput === 'object' && !Array.isArray(finalOutput)) {\n const outputObj = finalOutput as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n for (const key of outputKeys) {\n result[key] = outputObj[key] ?? null;\n }\n return result;\n }\n if (outputKeys.length === 1) {\n return { [outputKeys[0]!]: finalOutput };\n }\n return { [outputKeys[0]!]: finalOutput };\n }\n\n // Normal completion — resolve workflow output value expressions\n const hasAnyValues = Object.values(workflow.outputs).some((o) => o.value !== undefined);\n if (hasAnyValues) {\n const result: Record<string, unknown> = {};\n for (const [key, outputDef] of Object.entries(workflow.outputs)) {\n if (outputDef.value !== undefined) {\n result[key] = resolveValue(outputDef.value, context);\n } else if (finalOutput !== null && typeof finalOutput === 'object' && !Array.isArray(finalOutput)) {\n // Fall back to key-matching against last step output\n result[key] = (finalOutput as Record<string, unknown>)[key] ?? null;\n } else {\n result[key] = null;\n }\n }\n return result;\n }\n\n // No value fields — pass through by key name from final output\n if (finalOutput !== null && typeof finalOutput === 'object' && !Array.isArray(finalOutput)) {\n const outputObj = finalOutput as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n for (const key of outputKeys) {\n result[key] = outputObj[key] ?? null;\n }\n return result;\n }\n\n // Wrap primitive/array in first output key\n if (outputKeys.length === 1) {\n return { [outputKeys[0]!]: finalOutput };\n }\n\n return { [outputKeys[0]!]: finalOutput };\n}\n\nfunction parseDelay(delay: string): number {\n const match = delay.match(/^(\\d+)(ms|s)$/);\n if (!match) return 0;\n const value = parseInt(match[1]!, 10);\n return match[2] === 's' ? value * 1000 : value;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nfunction readAuthoringSkill(): string {\n // For npm installs and dev (npm link): ../skill/SKILL.md relative to dist/\n // For tests running TypeScript source: ../../skill/SKILL.md relative to src/skill/\n const npmPath = join(import.meta.dirname, '../skill/SKILL.md');\n if (existsSync(npmPath)) {\n return readFileSync(npmPath, 'utf-8');\n }\n return readFileSync(join(import.meta.dirname, '../../skill/SKILL.md'), 'utf-8');\n}\n\nexport const AUTHORING_SKILL = readAuthoringSkill();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["parseYaml"],"sources":["../src/parser/extract.ts","../src/parser/schema.ts","../src/parser/index.ts","../src/expression/lexer.ts","../src/expression/parser.ts","../src/expression/evaluator.ts","../src/expression/index.ts","../src/parser/parse-content.ts","../src/validator/index.ts","../src/adapters/mock-tool-adapter.ts","../src/config/index.ts","../src/executor/transform.ts","../src/executor/conditional.ts","../src/executor/exit.ts","../src/executor/types.ts","../src/executor/tool.ts","../src/executor/index.ts","../src/runtime/index.ts","../src/skill/index.ts"],"sourcesContent":["// Extract ```workflow fenced code block and YAML frontmatter from SKILL.md content.\n\n/** Result of extracting content from a SKILL.md file. */\nexport interface ExtractResult {\n frontmatter: string | null;\n workflowYaml: string;\n}\n\n/**\n * Extract YAML frontmatter from SKILL.md content.\n * Frontmatter is delimited by --- at the start of the file.\n */\nexport function extractFrontmatter(content: string): string | null {\n // Normalize Windows line endings before matching\n const normalized = content.replace(/\\r\\n/g, '\\n');\n const match = normalized.match(/^---\\n([\\s\\S]*?)\\n---/);\n return match?.[1] ?? null;\n}\n\n/**\n * Extract the ```workflow fenced code block from SKILL.md content.\n * Returns the YAML content inside the block.\n * Throws if no workflow block is found.\n */\nexport function extractWorkflowBlock(content: string): string {\n // Normalize Windows line endings before matching\n const normalized = content.replace(/\\r\\n/g, '\\n');\n // Match ```workflow ... ``` block\n const match = normalized.match(/```workflow\\s*\\n([\\s\\S]*?)\\n```/);\n if (!match?.[1]) {\n throw new ExtractError(\n 'No ```workflow fenced code block found in SKILL.md. ' +\n 'WorkflowSkill definitions must be wrapped in a ```workflow block.'\n );\n }\n return match[1];\n}\n\n/**\n * Extract both frontmatter and workflow block from SKILL.md content.\n */\nexport function extract(content: string): ExtractResult {\n return {\n frontmatter: extractFrontmatter(content),\n workflowYaml: extractWorkflowBlock(content),\n };\n}\n\n/** Error thrown during extraction. */\nexport class ExtractError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'ExtractError';\n }\n}\n","// Zod schemas for WorkflowSkill YAML validation.\n// Isolated here so schema validation can be swapped (e.g., to TypeBox) during integration.\n\nimport { z } from 'zod';\n\n// ─── Primitive schemas ────────────────────────────────────────────────────────\n\nconst schemaTypeEnum = z.enum(['string', 'int', 'float', 'boolean', 'array', 'object']);\n\n// FieldSchema can be recursive (items/properties contain FieldSchema).\n// We avoid deep recursion issues by using z.unknown() for nested levels.\n// This is sufficient for validation — we don't need infinite depth.\n// Note: `default` is not supported at nested level (only workflow inputs use `default`).\nconst nestedFieldSchema = z.object({\n type: schemaTypeEnum,\n value: z.unknown().optional(),\n items: z.record(z.string(), z.unknown()).optional(),\n properties: z.record(z.string(), z.unknown()).optional(),\n});\n\nexport const fieldSchema = z.object({\n type: schemaTypeEnum,\n value: z.unknown().optional(),\n items: nestedFieldSchema.optional(),\n properties: z.record(z.string(), z.union([z.string(), nestedFieldSchema])).optional(),\n});\n\n// ─── Workflow inputs and outputs ──────────────────────────────────────────────\n\n// Workflow inputs use `default` as canonical field for fallback values.\nexport const workflowInputSchema = z.object({\n type: schemaTypeEnum,\n default: z.unknown().optional(),\n items: nestedFieldSchema.optional(),\n properties: z.record(z.string(), z.union([z.string(), nestedFieldSchema])).optional(),\n});\n\nconst workflowOutputBaseSchema = z.object({\n type: schemaTypeEnum,\n value: z.unknown().optional(),\n items: nestedFieldSchema.optional(),\n properties: z.record(z.string(), z.union([z.string(), nestedFieldSchema])).optional(),\n});\nexport const workflowOutputSchema = workflowOutputBaseSchema;\n\n// ─── Step inputs and outputs ──────────────────────────────────────────────────\n\nconst stepInputBaseSchema = z.object({\n type: schemaTypeEnum,\n value: z.unknown().optional(),\n items: nestedFieldSchema.optional(),\n properties: z.record(z.string(), z.union([z.string(), nestedFieldSchema])).optional(),\n});\nexport const stepInputSchema = stepInputBaseSchema;\n\nconst stepOutputBaseSchema = z.object({\n type: schemaTypeEnum,\n value: z.unknown().optional(),\n items: nestedFieldSchema.optional(),\n properties: z.record(z.string(), z.union([z.string(), nestedFieldSchema])).optional(),\n});\nexport const stepOutputSchema = stepOutputBaseSchema;\n\n// ─── Retry policy ─────────────────────────────────────────────────────────────\n\nexport const retryPolicySchema = z.object({\n max: z.number().int().positive(),\n delay: z.string(),\n backoff: z.number().positive(),\n});\n\n// ─── Common step fields ───────────────────────────────────────────────────────\n\nconst stepBaseSchema = z.object({\n id: z.string().min(1),\n type: z.enum(['tool', 'transform', 'conditional', 'exit']),\n description: z.string().optional(),\n inputs: z.record(z.string(), stepInputSchema).default({}),\n outputs: z.record(z.string(), stepOutputSchema).default({}),\n condition: z.string().optional(),\n each: z.string().optional(),\n delay: z.string().optional(),\n on_error: z.enum(['fail', 'ignore']).optional(),\n retry: retryPolicySchema.optional(),\n});\n\n// ─── Step type schemas ────────────────────────────────────────────────────────\n\nconst toolStepSchema = stepBaseSchema.extend({\n type: z.literal('tool'),\n tool: z.string().min(1),\n});\n\nconst transformFilterStepSchema = stepBaseSchema.extend({\n type: z.literal('transform'),\n operation: z.literal('filter'),\n where: z.string().min(1),\n});\n\nconst transformMapStepSchema = stepBaseSchema.extend({\n type: z.literal('transform'),\n operation: z.literal('map'),\n expression: z.record(z.string(), z.unknown()),\n});\n\nconst transformSortStepSchema = stepBaseSchema.extend({\n type: z.literal('transform'),\n operation: z.literal('sort'),\n field: z.string().min(1),\n direction: z.enum(['asc', 'desc']).optional(),\n});\n\nconst conditionalStepSchema = stepBaseSchema.extend({\n type: z.literal('conditional'),\n condition: z.string().min(1),\n then: z.array(z.string()).min(1),\n else: z.array(z.string()).optional(),\n});\n\nconst exitStepSchema = stepBaseSchema.extend({\n type: z.literal('exit'),\n status: z.enum(['success', 'failed']),\n // Output can be an expression string or an object literal (values may be expressions)\n output: z.union([z.string(), z.record(z.string(), z.unknown())]).optional(),\n});\n\n// Transform steps share type=\"transform\" but differ by operation.\n// Zod discriminatedUnion doesn't support duplicate discriminator values,\n// so we use a nested discriminatedUnion for transform operations.\nconst transformStepSchema = z.discriminatedUnion('operation', [\n transformFilterStepSchema,\n transformMapStepSchema,\n transformSortStepSchema,\n]);\n\n// Top-level step schema: discriminate by type, with transform handled by sub-union.\nexport const stepSchema = z.union([\n toolStepSchema,\n transformStepSchema,\n conditionalStepSchema,\n exitStepSchema,\n]);\n\n// ─── Workflow definition ──────────────────────────────────────────────────────\n\nexport const workflowDefinitionSchema = z.object({\n inputs: z.record(z.string(), workflowInputSchema).default({}),\n outputs: z.record(z.string(), workflowOutputSchema).default({}),\n steps: z.array(stepSchema).min(1, 'Workflow must have at least one step'),\n});\n\n// ─── SKILL.md frontmatter ─────────────────────────────────────────────────────\n\nexport const skillFrontmatterSchema = z.object({\n name: z.string().min(1),\n description: z.string().min(1),\n}).passthrough();\n","// WorkflowSkill parser: SKILL.md → typed WorkflowDefinition\n// Pipeline: extract markdown → parse YAML → validate with Zod → typed objects\n\nimport { parse as parseYaml } from 'yaml';\nimport { ZodError } from 'zod';\nimport { extract, extractWorkflowBlock, ExtractError } from './extract.js';\nimport { workflowDefinitionSchema, skillFrontmatterSchema } from './schema.js';\nimport type { WorkflowDefinition, ParsedSkill, SkillFrontmatter } from '../types/index.js';\n\n/** Error thrown when parsing fails. Includes structured details. */\nexport class ParseError extends Error {\n constructor(\n message: string,\n public readonly details: ParseErrorDetail[] = [],\n ) {\n super(message);\n this.name = 'ParseError';\n }\n}\n\nexport interface ParseErrorDetail {\n path: string;\n message: string;\n}\n\n/**\n * Convert Zod errors to our ParseErrorDetail format.\n */\nfunction zodToDetails(err: ZodError): ParseErrorDetail[] {\n return err.issues.map((issue) => ({\n path: issue.path.join('.'),\n message: issue.message,\n }));\n}\n\n/**\n * Parse a raw YAML string into a validated WorkflowDefinition.\n * Use this when you already have the YAML content (e.g., from extractWorkflowBlock).\n */\nexport function parseWorkflowYaml(yaml: string): WorkflowDefinition {\n let raw: unknown;\n try {\n raw = parseYaml(yaml);\n } catch (err) {\n throw new ParseError(`Invalid YAML: ${err instanceof Error ? err.message : String(err)}`);\n }\n\n const result = workflowDefinitionSchema.safeParse(raw);\n if (!result.success) {\n throw new ParseError(\n 'Workflow validation failed',\n zodToDetails(result.error),\n );\n }\n\n // Zod discriminatedUnion handles step type validation, but transform steps\n // need the discriminatedUnion on 'type' first and then we rely on Zod for\n // operation-specific fields. Cast is safe because Zod validated the shape.\n return result.data as unknown as WorkflowDefinition;\n}\n\n/**\n * Parse a SKILL.md file content into a fully typed ParsedSkill.\n * Extracts frontmatter and workflow block, validates both.\n */\nexport function parseSkillMd(content: string): ParsedSkill {\n let extracted;\n try {\n extracted = extract(content);\n } catch (err) {\n if (err instanceof ExtractError) {\n throw new ParseError(err.message);\n }\n throw err;\n }\n\n // Parse frontmatter\n let frontmatter: SkillFrontmatter;\n if (extracted.frontmatter) {\n let rawFrontmatter: unknown;\n try {\n rawFrontmatter = parseYaml(extracted.frontmatter);\n } catch (err) {\n throw new ParseError(`Invalid frontmatter YAML: ${err instanceof Error ? err.message : String(err)}`);\n }\n const fmResult = skillFrontmatterSchema.safeParse(rawFrontmatter);\n if (!fmResult.success) {\n throw new ParseError('Frontmatter validation failed', zodToDetails(fmResult.error));\n }\n frontmatter = fmResult.data as SkillFrontmatter;\n } else {\n throw new ParseError('SKILL.md must have YAML frontmatter with name and description');\n }\n\n // Parse workflow\n const workflow = parseWorkflowYaml(extracted.workflowYaml);\n\n return { frontmatter, workflow };\n}\n\n/**\n * Parse just the workflow block from SKILL.md content.\n * Useful when you only need the workflow definition without frontmatter.\n */\nexport function parseWorkflowFromMd(content: string): WorkflowDefinition {\n let yaml;\n try {\n yaml = extractWorkflowBlock(content);\n } catch (err) {\n if (err instanceof ExtractError) {\n throw new ParseError(err.message);\n }\n throw err;\n }\n return parseWorkflowYaml(yaml);\n}\n\n// Re-export extract utilities\nexport { extractWorkflowBlock, extractFrontmatter } from './extract.js';\n","// Lexer for the WorkflowSkill expression language.\n// Tokenizes expressions like: $steps.fetch.output.messages.length >= 5\n\nexport type TokenType =\n | 'DOLLAR_REF' // $inputs, $steps, $item, $index\n | 'DOT' // .\n | 'IDENTIFIER' // field names, property names\n | 'NUMBER' // integer or float literals\n | 'STRING' // \"string\" or 'string' literals\n | 'BOOLEAN' // true, false\n | 'NULL' // null\n | 'EQ' // ==\n | 'NEQ' // !=\n | 'GT' // >\n | 'GTE' // >=\n | 'LT' // <\n | 'LTE' // <=\n | 'AND' // &&\n | 'OR' // ||\n | 'NOT' // !\n | 'CONTAINS' // contains\n | 'LPAREN' // (\n | 'RPAREN' // )\n | 'LBRACKET' // [\n | 'RBRACKET' // ]\n | 'EOF';\n\nexport interface Token {\n type: TokenType;\n value: string;\n position: number;\n}\n\nexport class LexError extends Error {\n constructor(message: string, public readonly position: number) {\n super(message);\n this.name = 'LexError';\n }\n}\n\nexport function lex(input: string): Token[] {\n const tokens: Token[] = [];\n let pos = 0;\n\n while (pos < input.length) {\n // Skip whitespace\n if (/\\s/.test(input[pos]!)) {\n pos++;\n continue;\n }\n\n const ch = input[pos]!;\n\n // Dollar references: $inputs, $steps, $item, $index, $result\n if (ch === '$') {\n const start = pos;\n pos++; // skip $\n let name = '';\n while (pos < input.length && /[a-zA-Z_]/.test(input[pos]!)) {\n name += input[pos]!;\n pos++;\n }\n if (!name) {\n throw new LexError(`Expected identifier after $`, start);\n }\n tokens.push({ type: 'DOLLAR_REF', value: name, position: start });\n continue;\n }\n\n // Dot\n if (ch === '.') {\n tokens.push({ type: 'DOT', value: '.', position: pos });\n pos++;\n continue;\n }\n\n // Parentheses\n if (ch === '(') {\n tokens.push({ type: 'LPAREN', value: '(', position: pos });\n pos++;\n continue;\n }\n if (ch === ')') {\n tokens.push({ type: 'RPAREN', value: ')', position: pos });\n pos++;\n continue;\n }\n\n // Brackets\n if (ch === '[') {\n tokens.push({ type: 'LBRACKET', value: '[', position: pos });\n pos++;\n continue;\n }\n if (ch === ']') {\n tokens.push({ type: 'RBRACKET', value: ']', position: pos });\n pos++;\n continue;\n }\n\n // Two-character operators\n if (pos + 1 < input.length) {\n const twoChar = input[pos]! + input[pos + 1]!;\n if (twoChar === '==') {\n tokens.push({ type: 'EQ', value: '==', position: pos });\n pos += 2;\n continue;\n }\n if (twoChar === '!=') {\n tokens.push({ type: 'NEQ', value: '!=', position: pos });\n pos += 2;\n continue;\n }\n if (twoChar === '>=') {\n tokens.push({ type: 'GTE', value: '>=', position: pos });\n pos += 2;\n continue;\n }\n if (twoChar === '<=') {\n tokens.push({ type: 'LTE', value: '<=', position: pos });\n pos += 2;\n continue;\n }\n if (twoChar === '&&') {\n tokens.push({ type: 'AND', value: '&&', position: pos });\n pos += 2;\n continue;\n }\n if (twoChar === '||') {\n tokens.push({ type: 'OR', value: '||', position: pos });\n pos += 2;\n continue;\n }\n }\n\n // Single-character operators\n if (ch === '>') {\n tokens.push({ type: 'GT', value: '>', position: pos });\n pos++;\n continue;\n }\n if (ch === '<') {\n tokens.push({ type: 'LT', value: '<', position: pos });\n pos++;\n continue;\n }\n if (ch === '!') {\n tokens.push({ type: 'NOT', value: '!', position: pos });\n pos++;\n continue;\n }\n\n // Number literals\n if (/[0-9]/.test(ch) || (ch === '-' && pos + 1 < input.length && /[0-9]/.test(input[pos + 1]!))) {\n const start = pos;\n if (ch === '-') pos++;\n while (pos < input.length && /[0-9]/.test(input[pos]!)) pos++;\n if (pos < input.length && input[pos] === '.') {\n pos++;\n while (pos < input.length && /[0-9]/.test(input[pos]!)) pos++;\n }\n tokens.push({ type: 'NUMBER', value: input.slice(start, pos), position: start });\n continue;\n }\n\n // String literals\n if (ch === '\"' || ch === \"'\") {\n const quote = ch;\n const start = pos;\n pos++; // skip opening quote\n let str = '';\n while (pos < input.length && input[pos] !== quote) {\n if (input[pos] === '\\\\' && pos + 1 < input.length) {\n pos++; // skip backslash\n }\n str += input[pos]!;\n pos++;\n }\n if (pos >= input.length) {\n throw new LexError(`Unterminated string literal`, start);\n }\n pos++; // skip closing quote\n tokens.push({ type: 'STRING', value: str, position: start });\n continue;\n }\n\n // Identifiers (also matches true, false, null)\n if (/[a-zA-Z_]/.test(ch)) {\n const start = pos;\n while (pos < input.length && /[a-zA-Z0-9_]/.test(input[pos]!)) pos++;\n const word = input.slice(start, pos);\n if (word === 'true' || word === 'false') {\n tokens.push({ type: 'BOOLEAN', value: word, position: start });\n } else if (word === 'null') {\n tokens.push({ type: 'NULL', value: word, position: start });\n } else if (word === 'contains') {\n tokens.push({ type: 'CONTAINS', value: word, position: start });\n } else {\n tokens.push({ type: 'IDENTIFIER', value: word, position: start });\n }\n continue;\n }\n\n throw new LexError(`Unexpected character: ${ch}`, pos);\n }\n\n tokens.push({ type: 'EOF', value: '', position: pos });\n return tokens;\n}\n","// Recursive-descent parser for the WorkflowSkill expression language.\n// Produces an AST from the token stream.\n\nimport type { Token, TokenType } from './lexer.js';\n\n// ─── AST node types ───────────────────────────────────────────────────────────\n\nexport type ASTNode =\n | ReferenceNode\n | PropertyAccessNode\n | IndexAccessNode\n | LiteralNode\n | BinaryNode\n | UnaryNode;\n\n/** $inputs, $steps, $item, $index, $result */\nexport interface ReferenceNode {\n kind: 'reference';\n name: string; // \"inputs\", \"steps\", \"item\", \"index\"\n}\n\n/** a.b.c property access chain */\nexport interface PropertyAccessNode {\n kind: 'property_access';\n object: ASTNode;\n property: string;\n}\n\n/** a[expr] bracket index access */\nexport interface IndexAccessNode {\n kind: 'index_access';\n object: ASTNode;\n index: ASTNode;\n}\n\n/** Literal values: number, string, boolean, null */\nexport interface LiteralNode {\n kind: 'literal';\n value: string | number | boolean | null;\n}\n\n/** Binary operations: ==, !=, >, <, >=, <=, &&, ||, contains */\nexport interface BinaryNode {\n kind: 'binary';\n operator: string;\n left: ASTNode;\n right: ASTNode;\n}\n\n/** Unary operations: ! */\nexport interface UnaryNode {\n kind: 'unary';\n operator: string;\n operand: ASTNode;\n}\n\n// ─── Parser ───────────────────────────────────────────────────────────────────\n\nexport class ParseExprError extends Error {\n constructor(message: string, public readonly position: number) {\n super(message);\n this.name = 'ParseExprError';\n }\n}\n\nexport function parseExpression(tokens: Token[]): ASTNode {\n let pos = 0;\n\n function current(): Token {\n return tokens[pos]!;\n }\n\n function expect(type: TokenType): Token {\n const tok = current();\n if (tok.type !== type) {\n throw new ParseExprError(\n `Expected ${type} but got ${tok.type} (\"${tok.value}\")`,\n tok.position,\n );\n }\n pos++;\n return tok;\n }\n\n function peek(): Token {\n return tokens[pos]!;\n }\n\n // Grammar (precedence low to high):\n // expression → or_expr\n // or_expr → and_expr ( \"||\" and_expr )*\n // and_expr → comparison ( \"&&\" comparison )*\n // comparison → unary ( (\"==\" | \"!=\" | \">\" | \"<\" | \">=\" | \"<=\") unary )?\n // unary → \"!\" unary | primary\n // primary → reference_chain | literal | \"(\" expression \")\"\n\n function parseOr(): ASTNode {\n let left = parseAnd();\n while (peek().type === 'OR') {\n const op = current().value;\n pos++;\n const right = parseAnd();\n left = { kind: 'binary', operator: op, left, right };\n }\n return left;\n }\n\n function parseAnd(): ASTNode {\n let left = parseComparison();\n while (peek().type === 'AND') {\n const op = current().value;\n pos++;\n const right = parseComparison();\n left = { kind: 'binary', operator: op, left, right };\n }\n return left;\n }\n\n function parseComparison(): ASTNode {\n let left = parseUnary();\n const t = peek().type;\n if (t === 'EQ' || t === 'NEQ' || t === 'GT' || t === 'GTE' || t === 'LT' || t === 'LTE' || t === 'CONTAINS') {\n const op = current().value;\n pos++;\n const right = parseUnary();\n left = { kind: 'binary', operator: op, left, right };\n }\n return left;\n }\n\n function parseUnary(): ASTNode {\n if (peek().type === 'NOT') {\n const op = current().value;\n pos++;\n const operand = parseUnary();\n return { kind: 'unary', operator: op, operand };\n }\n return parsePrimary();\n }\n\n function parsePrimary(): ASTNode {\n const tok = peek();\n\n // Parenthesized expression\n if (tok.type === 'LPAREN') {\n pos++;\n const expr = parseOr();\n expect('RPAREN');\n return expr;\n }\n\n // Dollar reference with possible property chain\n if (tok.type === 'DOLLAR_REF') {\n pos++;\n let node: ASTNode = { kind: 'reference', name: tok.value };\n // Postfix chain: .field or [expr]\n while (peek().type === 'DOT' || peek().type === 'LBRACKET') {\n if (peek().type === 'DOT') {\n pos++; // skip dot\n const prop = current();\n if (prop.type === 'IDENTIFIER' || prop.type === 'DOLLAR_REF') {\n pos++;\n node = { kind: 'property_access', object: node, property: prop.value };\n } else if (prop.type === 'NUMBER') {\n // Array index access: .0, .1\n pos++;\n node = { kind: 'property_access', object: node, property: prop.value };\n } else {\n throw new ParseExprError(\n `Expected property name after '.', got ${prop.type}`,\n prop.position,\n );\n }\n } else {\n // LBRACKET — bracket index access: [expr]\n pos++; // skip [\n const indexExpr = parseOr();\n expect('RBRACKET');\n node = { kind: 'index_access', object: node, index: indexExpr };\n }\n }\n return node;\n }\n\n // Number literal\n if (tok.type === 'NUMBER') {\n pos++;\n const num = tok.value.includes('.') ? parseFloat(tok.value) : parseInt(tok.value, 10);\n return { kind: 'literal', value: num };\n }\n\n // String literal\n if (tok.type === 'STRING') {\n pos++;\n return { kind: 'literal', value: tok.value };\n }\n\n // Boolean literal\n if (tok.type === 'BOOLEAN') {\n pos++;\n return { kind: 'literal', value: tok.value === 'true' };\n }\n\n // Null literal\n if (tok.type === 'NULL') {\n pos++;\n return { kind: 'literal', value: null };\n }\n\n throw new ParseExprError(\n `Unexpected token: ${tok.type} (\"${tok.value}\")`,\n tok.position,\n );\n }\n\n const ast = parseOr();\n\n // Ensure we consumed all tokens (except EOF)\n if (peek().type !== 'EOF') {\n const leftover = peek();\n throw new ParseExprError(\n `Unexpected token after expression: ${leftover.type} (\"${leftover.value}\")`,\n leftover.position,\n );\n }\n\n return ast;\n}\n","// Evaluator for the WorkflowSkill expression language.\n// Takes an AST and a RuntimeContext, produces a resolved value.\n\nimport type { RuntimeContext } from '../types/index.js';\nimport type { ASTNode } from './parser.js';\n\nexport class EvalError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'EvalError';\n }\n}\n\n/**\n * Evaluate an AST node against a runtime context.\n * Returns the resolved value (primitive, object, array, or null).\n */\nexport function evaluate(node: ASTNode, context: RuntimeContext): unknown {\n switch (node.kind) {\n case 'reference':\n return resolveReference(node.name, context);\n\n case 'property_access':\n return resolvePropertyAccess(node, context);\n\n case 'index_access':\n return resolveIndexAccess(node, context);\n\n case 'literal':\n return node.value;\n\n case 'binary':\n return evaluateBinary(node.operator, node.left, node.right, context);\n\n case 'unary':\n return evaluateUnary(node.operator, node.operand, context);\n }\n}\n\nfunction resolveReference(name: string, context: RuntimeContext): unknown {\n switch (name) {\n case 'inputs':\n return context.inputs;\n case 'steps':\n return context.steps;\n case 'item':\n return context.item;\n case 'index':\n return context.index;\n case 'result':\n return context.result;\n default:\n throw new EvalError(`Unknown reference: $${name}`);\n }\n}\n\nfunction resolvePropertyAccess(\n node: { object: ASTNode; property: string },\n context: RuntimeContext,\n): unknown {\n const obj = evaluate(node.object, context);\n\n if (obj === null || obj === undefined) {\n return undefined;\n }\n\n // Special property: .length on arrays\n if (node.property === 'length' && Array.isArray(obj)) {\n return obj.length;\n }\n\n if (typeof obj === 'object') {\n return (obj as Record<string, unknown>)[node.property];\n }\n\n return undefined;\n}\n\nfunction resolveIndexAccess(\n node: { object: ASTNode; index: ASTNode },\n context: RuntimeContext,\n): unknown {\n const obj = evaluate(node.object, context);\n const idx = evaluate(node.index, context);\n\n if (obj === null || obj === undefined) {\n return undefined;\n }\n\n if (Array.isArray(obj) && typeof idx === 'number') {\n return obj[idx];\n }\n\n if (typeof obj === 'object') {\n const key = typeof idx === 'number' ? String(idx) : idx;\n if (typeof key === 'string') {\n return (obj as Record<string, unknown>)[key];\n }\n }\n\n return undefined;\n}\n\nfunction evaluateBinary(\n op: string,\n left: ASTNode,\n right: ASTNode,\n context: RuntimeContext,\n): unknown {\n const lval = evaluate(left, context);\n const rval = evaluate(right, context);\n\n switch (op) {\n case '==':\n return lval === rval;\n case '!=':\n return lval !== rval;\n case '>':\n return toNumber(lval) > toNumber(rval);\n case '<':\n return toNumber(lval) < toNumber(rval);\n case '>=':\n return toNumber(lval) >= toNumber(rval);\n case '<=':\n return toNumber(lval) <= toNumber(rval);\n case '&&':\n // Returns boolean (not short-circuit value). The expression language is designed\n // for boolean guards (e.g. condition fields), not value coalescing.\n return isTruthy(lval) && isTruthy(rval);\n case '||':\n return isTruthy(lval) || isTruthy(rval);\n case 'contains':\n if (Array.isArray(lval)) return lval.includes(rval);\n return String(lval ?? '').includes(String(rval ?? ''));\n default:\n throw new EvalError(`Unknown operator: ${op}`);\n }\n}\n\nfunction evaluateUnary(op: string, operand: ASTNode, context: RuntimeContext): unknown {\n const val = evaluate(operand, context);\n switch (op) {\n case '!':\n return !isTruthy(val);\n default:\n throw new EvalError(`Unknown unary operator: ${op}`);\n }\n}\n\nfunction toNumber(val: unknown): number {\n if (typeof val === 'number') return val;\n if (typeof val === 'string') {\n const n = Number(val);\n if (!isNaN(n)) return n;\n }\n if (typeof val === 'boolean') return val ? 1 : 0;\n return 0;\n}\n\nfunction isTruthy(val: unknown): boolean {\n if (val === null || val === undefined) return false;\n if (typeof val === 'boolean') return val;\n if (typeof val === 'number') return val !== 0;\n if (typeof val === 'string') return val.length > 0;\n if (Array.isArray(val)) return val.length > 0;\n return true; // objects are truthy\n}\n","// Expression evaluator public API.\n// Provides resolveExpression (for source/condition/where/each fields)\n// and resolveTemplate (for ${...} template interpolation).\n\nimport type { RuntimeContext } from '../types/index.js';\nimport { lex } from './lexer.js';\nimport { parseExpression } from './parser.js';\nimport { evaluate } from './evaluator.js';\n\nexport { LexError } from './lexer.js';\nexport { ParseExprError } from './parser.js';\nexport { EvalError } from './evaluator.js';\n\n/**\n * Resolve a single expression string against a runtime context.\n * Used for source, condition, where, each, and output fields.\n * Example: \"$steps.fetch.output.messages.length >= 5\"\n */\nexport function resolveExpression(expr: string, context: RuntimeContext): unknown {\n const tokens = lex(expr);\n const ast = parseExpression(tokens);\n return evaluate(ast, context);\n}\n\n/**\n * Returns true if the string contains at least one ${...} template block.\n */\nexport function containsTemplate(value: string): boolean {\n return /\\$\\{[^}]+\\}/.test(value);\n}\n\n/**\n * Resolve a ${...} template string against a runtime context.\n *\n * Two modes:\n * - Whole-value `${ref}` (nothing else) — type is preserved (not coerced to string).\n * - Multi-block — each `${ref}` is evaluated and spliced into the surrounding string.\n * Use `$${` to produce a literal `${` inside a template.\n *\n * Inside `${...}`, references omit the leading `$` (the `$` is part of the delimiter).\n * Example: `\"https://example.com?q=${inputs.query}\"` → resolves `$inputs.query`.\n */\nexport function resolveTemplate(template: string, context: RuntimeContext): unknown {\n // Whole-value ${ref} — preserve the typed result\n const single = template.match(/^\\$\\{([^}]+)\\}$/);\n if (single) {\n return resolveExpression('$' + single[1]!, context);\n }\n // Multi-block: interpolate all ${...} blocks; ${ is the escape for literal ${\n return template.replace(/\\$\\$\\{|\\$\\{([^}]+)\\}/g, (match, expr?: string) => {\n if (match === '$${') return '${';\n return stringify(resolveExpression('$' + expr!, context));\n });\n}\n\n/**\n * Coerce a value to its string representation for prompt interpolation.\n * Per the spec: objects/arrays → JSON, null → empty string.\n */\nexport function stringify(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n return JSON.stringify(value);\n}\n","// Internal parse helper shared by runWorkflowSkill and validateWorkflowSkill.\n// Not exported from the barrel — internal use only.\n//\n// Tries parseSkillMd first (full SKILL.md with frontmatter), then falls back\n// to parseWorkflowFromMd (bare workflow YAML block). Returns a discriminated\n// union so callers never need to catch.\n\nimport { parseSkillMd, parseWorkflowFromMd, ParseError } from './index.js';\nimport type { WorkflowDefinition } from '../types/index.js';\n\nexport type ParseContentResult =\n | { ok: true; workflow: WorkflowDefinition; name: string | undefined }\n | { ok: false; message: string; details?: Array<{ path: string; message: string }> };\n\n/**\n * Parse content that is either a full SKILL.md or a bare workflow YAML block.\n * Never throws — failures are encoded in the returned union.\n */\nexport function parseContent(content: string): ParseContentResult {\n if (!content.trim()) {\n return { ok: false, message: 'Content is empty' };\n }\n\n // Try full SKILL.md (with frontmatter) first\n try {\n const skill = parseSkillMd(content);\n return { ok: true, workflow: skill.workflow, name: skill.frontmatter.name };\n } catch {\n // Fall through to bare workflow YAML\n }\n\n // Fall back to bare workflow block\n try {\n const workflow = parseWorkflowFromMd(content);\n return { ok: true, workflow, name: undefined };\n } catch (err) {\n let message: string;\n let details: Array<{ path: string; message: string }> | undefined;\n if (err instanceof ParseError) {\n message = err.message;\n details = err.details.length > 0 ? err.details : undefined;\n } else {\n message = err instanceof Error ? err.message : String(err);\n }\n return { ok: false, message, details };\n }\n}\n","// Pre-execution workflow validator.\n// Checks DAG resolution, type compatibility, tool availability, and structural correctness.\n// Returns ALL errors, not just the first.\n\nimport type {\n WorkflowDefinition,\n Step,\n ValidationError,\n ValidationResult,\n ToolAdapter,\n ConditionalStep,\n} from '../types/index.js';\nimport { parseContent } from '../parser/parse-content.js';\n\n/**\n * Validate a workflow definition before execution.\n * Checks structural correctness, reference graph, type compatibility, and tool availability.\n * Returns all errors found — does not fail fast.\n */\nexport function validateWorkflow(\n workflow: WorkflowDefinition,\n toolAdapter?: ToolAdapter,\n): ValidationResult {\n const errors: ValidationError[] = [];\n\n // Build step lookup\n const stepMap = new Map<string, Step>();\n const stepOrder = new Map<string, number>();\n for (let i = 0; i < workflow.steps.length; i++) {\n const step = workflow.steps[i]!;\n stepOrder.set(step.id, i);\n\n if (stepMap.has(step.id)) {\n errors.push({\n path: `steps[${i}].id`,\n message: `Duplicate step ID \"${step.id}\"`,\n });\n }\n stepMap.set(step.id, step);\n }\n\n // Collect branch step IDs (steps referenced in conditional then/else)\n const branchStepIds = new Set<string>();\n for (const step of workflow.steps) {\n if (step.type === 'conditional') {\n for (const id of step.then) branchStepIds.add(id);\n if (step.else) {\n for (const id of step.else) branchStepIds.add(id);\n }\n }\n }\n\n // Per-step checks\n for (let i = 0; i < workflow.steps.length; i++) {\n const step = workflow.steps[i]!;\n const path = `steps[${i}]`;\n\n // Structural: `each` not valid on exit steps\n if (step.each && step.type === 'exit') {\n errors.push({\n path: `${path}.each`,\n message: `\"each\" is not valid on exit steps`,\n });\n }\n\n // Structural: `each` not valid on conditional steps\n if (step.each && step.type === 'conditional') {\n errors.push({\n path: `${path}.each`,\n message: `\"each\" is not valid on conditional steps`,\n });\n }\n\n // Structural: `delay` requires `each`\n if (step.delay && !step.each) {\n errors.push({\n path: `${path}.delay`,\n message: `\"delay\" requires \"each\" to be present`,\n });\n }\n\n // Tool availability\n if (step.type === 'tool' && toolAdapter && !toolAdapter.has(step.tool)) {\n errors.push({\n path: `${path}.tool`,\n message: `Tool \"${step.tool}\" is not registered`,\n });\n }\n\n // Validate $steps references in input values (expressions and templates)\n for (const [inputName, input] of Object.entries(step.inputs)) {\n if (typeof input.value === 'string' && hasStepReferences(input.value)) {\n validateSourceReference(\n input.value,\n step.id,\n `${path}.inputs.${inputName}.value`,\n stepMap,\n stepOrder,\n branchStepIds,\n errors,\n );\n }\n }\n\n // Validate guard condition references\n if (step.condition) {\n validateExpressionReferences(\n step.condition,\n step.id,\n `${path}.condition`,\n stepMap,\n stepOrder,\n branchStepIds,\n errors,\n );\n }\n\n // Validate each references\n if (step.each) {\n validateExpressionReferences(\n step.each,\n step.id,\n `${path}.each`,\n stepMap,\n stepOrder,\n branchStepIds,\n errors,\n );\n }\n\n // Conditional: validate branch step IDs exist\n if (step.type === 'conditional') {\n validateBranchReferences(step, i, stepMap, errors);\n }\n\n // Exit: validate output expression references\n if (step.type === 'exit' && step.output) {\n if (typeof step.output === 'string') {\n validateExpressionReferences(\n step.output,\n step.id,\n `${path}.output`,\n stepMap,\n stepOrder,\n branchStepIds,\n errors,\n );\n } else {\n // Object literal — validate expression values within it\n for (const [key, val] of Object.entries(step.output)) {\n if (typeof val === 'string' && val.startsWith('$')) {\n validateExpressionReferences(\n val,\n step.id,\n `${path}.output.${key}`,\n stepMap,\n stepOrder,\n branchStepIds,\n errors,\n );\n }\n }\n }\n }\n }\n\n // Validate workflow output value references (expressions and templates)\n for (const [outputName, outputDef] of Object.entries(workflow.outputs)) {\n if (typeof outputDef.value === 'string' && hasStepReferences(outputDef.value)) {\n const refs = extractStepReferences(outputDef.value);\n for (const refId of refs) {\n if (!stepMap.has(refId)) {\n errors.push({\n path: `outputs.${outputName}.value`,\n message: `References undefined step \"${refId}\"`,\n });\n }\n }\n }\n }\n\n // Check for cycles in the step reference graph\n const cycleErrors = detectCycles(workflow.steps, stepMap);\n errors.push(...cycleErrors);\n\n return {\n valid: errors.length === 0,\n errors,\n };\n}\n\n/**\n * Extract step IDs referenced from an expression or template string.\n * Handles both expression form ($steps.<id>) and template form (${steps.<id>...}).\n */\nfunction extractStepReferences(expr: string): string[] {\n const refs: string[] = [];\n // Expression form: $steps.<id>\n const exprRegex = /\\$steps\\.([a-zA-Z_][a-zA-Z0-9_]*)/g;\n // Template form: ${steps.<id>...}\n const tmplRegex = /\\$\\{steps\\.([a-zA-Z_][a-zA-Z0-9_]*)/g;\n let match;\n while ((match = exprRegex.exec(expr)) !== null) refs.push(match[1]!);\n while ((match = tmplRegex.exec(expr)) !== null) refs.push(match[1]!);\n // Deduplicate\n return [...new Set(refs)];\n}\n\n/** Returns true if the string contains $steps references in either expression or template form. */\nfunction hasStepReferences(value: string): boolean {\n return value.startsWith('$steps.') || /\\$\\{steps\\./.test(value);\n}\n\n/**\n * Validate that a source expression references valid, earlier-defined steps.\n */\nfunction validateSourceReference(\n source: string,\n currentStepId: string,\n path: string,\n stepMap: Map<string, Step>,\n stepOrder: Map<string, number>,\n branchStepIds: Set<string>,\n errors: ValidationError[],\n): void {\n const refs = extractStepReferences(source);\n const currentOrder = stepOrder.get(currentStepId) ?? -1;\n\n for (const refId of refs) {\n if (!stepMap.has(refId)) {\n errors.push({\n path,\n message: `References undefined step \"${refId}\"`,\n });\n } else {\n const refOrder = stepOrder.get(refId) ?? -1;\n // A step can only reference steps declared before it (or branch targets\n // which may be later in the array but only execute when selected).\n if (refOrder >= currentOrder && !branchStepIds.has(currentStepId)) {\n errors.push({\n path,\n message: `Step \"${currentStepId}\" references step \"${refId}\" which is not declared before it`,\n });\n }\n }\n }\n}\n\n/**\n * Validate expression references (condition, each, output).\n */\nfunction validateExpressionReferences(\n expr: string,\n currentStepId: string,\n path: string,\n stepMap: Map<string, Step>,\n stepOrder: Map<string, number>,\n branchStepIds: Set<string>,\n errors: ValidationError[],\n): void {\n const refs = extractStepReferences(expr);\n const currentOrder = stepOrder.get(currentStepId) ?? -1;\n\n for (const refId of refs) {\n if (!stepMap.has(refId)) {\n errors.push({\n path,\n message: `References undefined step \"${refId}\"`,\n });\n } else {\n const refOrder = stepOrder.get(refId) ?? -1;\n if (refOrder >= currentOrder && !branchStepIds.has(currentStepId)) {\n errors.push({\n path,\n message: `Step \"${currentStepId}\" references step \"${refId}\" which is not declared before it`,\n });\n }\n }\n }\n}\n\n/**\n * Validate conditional step branch references.\n */\nfunction validateBranchReferences(\n step: ConditionalStep,\n stepIndex: number,\n stepMap: Map<string, Step>,\n errors: ValidationError[],\n): void {\n const path = `steps[${stepIndex}]`;\n\n for (const id of step.then) {\n if (!stepMap.has(id)) {\n errors.push({\n path: `${path}.then`,\n message: `Branch references undefined step \"${id}\"`,\n });\n }\n }\n\n if (step.else) {\n for (const id of step.else) {\n if (!stepMap.has(id)) {\n errors.push({\n path: `${path}.else`,\n message: `Branch references undefined step \"${id}\"`,\n });\n }\n }\n }\n}\n\n/**\n * Detect cycles in the step reference graph.\n * Steps form a DAG through $steps references. Cycles would cause infinite loops.\n */\nfunction detectCycles(\n steps: Step[],\n stepMap: Map<string, Step>,\n): ValidationError[] {\n const errors: ValidationError[] = [];\n\n // Build adjacency list: step → set of steps it depends on\n const deps = new Map<string, Set<string>>();\n for (const step of steps) {\n const stepDeps = new Set<string>();\n\n // Collect data-flow dependencies from $steps references (expressions and templates).\n // Conditional branch targets are execution-order dependencies, NOT data-flow edges —\n // adding them here causes false cycle reports when branch steps reference the conditional.\n for (const input of Object.values(step.inputs)) {\n if (typeof input.value === 'string') {\n for (const ref of extractStepReferences(input.value)) {\n stepDeps.add(ref);\n }\n }\n }\n if (step.condition) {\n for (const ref of extractStepReferences(step.condition)) {\n stepDeps.add(ref);\n }\n }\n if (step.each) {\n for (const ref of extractStepReferences(step.each)) {\n stepDeps.add(ref);\n }\n }\n\n deps.set(step.id, stepDeps);\n }\n\n // Topological sort via DFS with cycle detection\n const visited = new Set<string>();\n const inStack = new Set<string>();\n\n function dfs(nodeId: string, pathStack: string[]): boolean {\n if (inStack.has(nodeId)) {\n const cycleStart = pathStack.indexOf(nodeId);\n const cycle = pathStack.slice(cycleStart).concat(nodeId);\n errors.push({\n path: `steps`,\n message: `Cycle detected: ${cycle.join(' → ')}`,\n });\n return true;\n }\n\n if (visited.has(nodeId)) return false;\n\n visited.add(nodeId);\n inStack.add(nodeId);\n pathStack.push(nodeId);\n\n const nodeDeps = deps.get(nodeId) ?? new Set();\n for (const dep of nodeDeps) {\n if (stepMap.has(dep)) {\n dfs(dep, pathStack);\n }\n }\n\n pathStack.pop();\n inStack.delete(nodeId);\n return false;\n }\n\n for (const step of steps) {\n if (!visited.has(step.id)) {\n dfs(step.id, []);\n }\n }\n\n return errors;\n}\n\n// ─── High-level API ──────────────────────────────────────────────────────────\n\nexport interface ValidateWorkflowSkillOptions {\n content: string;\n toolAdapter?: ToolAdapter;\n}\n\nexport interface ValidateWorkflowSkillResult {\n valid: boolean;\n errors: Array<{ path: string; message: string }>;\n name?: string;\n stepCount?: number;\n stepTypes?: string[];\n}\n\n/**\n * Parse content and validate the workflow in one synchronous call.\n * Matches the shape of the plugin's ValidateResult exactly.\n */\nexport function validateWorkflowSkill(options: ValidateWorkflowSkillOptions): ValidateWorkflowSkillResult {\n const { content, toolAdapter } = options;\n\n const parsed = parseContent(content);\n if (!parsed.ok) {\n return {\n valid: false,\n errors: parsed.details ?? [{ path: 'parse', message: parsed.message }],\n };\n }\n\n const result = validateWorkflow(parsed.workflow, toolAdapter);\n if (!result.valid) {\n return { valid: false, errors: result.errors };\n }\n\n const stepTypes = [...new Set(parsed.workflow.steps.map((s) => s.type))];\n return {\n valid: true,\n errors: [],\n name: parsed.name,\n stepCount: parsed.workflow.steps.length,\n stepTypes,\n };\n}\n","// Mock tool adapter for testing.\n// Allows registering per-tool handlers that return configurable results.\n\nimport type { ToolAdapter, ToolDescriptor, ToolResult } from '../types/index.js';\n\n/** Handler function for a registered mock tool. */\nexport type ToolHandler = (args: Record<string, unknown>) => ToolResult | Promise<ToolResult>;\n\nexport class MockToolAdapter implements ToolAdapter {\n private tools = new Map<\n string,\n { handler: ToolHandler; descriptor: ToolDescriptor }\n >();\n\n /** Register a tool handler with optional descriptor metadata. */\n register(\n toolName: string,\n handler: ToolHandler,\n descriptor?: Omit<ToolDescriptor, 'name'>,\n ): void {\n this.tools.set(toolName, {\n handler,\n descriptor: {\n name: toolName,\n description: descriptor?.description ?? '',\n ...(descriptor?.inputSchema && { inputSchema: descriptor.inputSchema }),\n ...(descriptor?.outputSchema && { outputSchema: descriptor.outputSchema }),\n },\n });\n }\n\n has(toolName: string): boolean {\n return this.tools.has(toolName);\n }\n\n /** List all registered tools with their descriptors. */\n list(): ToolDescriptor[] {\n return [...this.tools.values()].map((t) => t.descriptor);\n }\n\n async invoke(toolName: string, args: Record<string, unknown>): Promise<ToolResult> {\n const entry = this.tools.get(toolName);\n if (!entry) {\n return { output: null, error: `Tool \"${toolName}\" not registered` };\n }\n return entry.handler(args);\n }\n}\n","// Configuration loader — reads env vars with .env fallback.\n// No external dependencies (simple KEY=VALUE parser).\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n/** WorkflowSkill configuration. Reserved for future host-level configuration. */\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface WorkflowSkillConfig {}\n\n/**\n * Parse a .env file into key-value pairs.\n * Supports KEY=VALUE format, blank lines, and # comments.\n * Values may be optionally quoted with single or double quotes.\n */\nfunction parseDotenv(content: string): Record<string, string> {\n const vars: Record<string, string> = {};\n for (const line of content.split('\\n')) {\n const trimmed = line.trim();\n if (!trimmed || trimmed.startsWith('#')) continue;\n const eqIdx = trimmed.indexOf('=');\n if (eqIdx === -1) continue;\n const key = trimmed.slice(0, eqIdx).trim();\n let value = trimmed.slice(eqIdx + 1).trim();\n // Strip surrounding quotes\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n vars[key] = value;\n }\n return vars;\n}\n\n/**\n * Find the package root by walking up from this module's directory\n * until we find a directory containing package.json.\n */\nfunction findPackageRoot(): string | undefined {\n let dir = dirname(fileURLToPath(import.meta.url));\n while (true) {\n if (existsSync(join(dir, 'package.json'))) {\n return dir;\n }\n const parent = dirname(dir);\n if (parent === dir) break; // true filesystem root\n dir = parent;\n }\n return undefined;\n}\n\n/**\n * Load configuration from environment variables, with .env fallback.\n * Environment variables take precedence over .env file values.\n *\n * .env search order:\n * 1. Explicit `cwd` parameter (for tests)\n * 2. Package root (found by walking up from this module)\n * 3. process.cwd()\n */\nexport function loadConfig(cwd?: string): WorkflowSkillConfig {\n // Try to read .env file (kept for future host-level config)\n let dotenvVars: Record<string, string> = {};\n const searchDirs = cwd\n ? [cwd]\n : [findPackageRoot(), process.cwd()].filter((d): d is string => d !== undefined);\n\n for (const dir of searchDirs) {\n try {\n const envPath = join(dir, '.env');\n const content = readFileSync(envPath, 'utf-8');\n dotenvVars = parseDotenv(content);\n break; // use the first .env found\n } catch {\n // No .env file in this directory — try next\n }\n }\n\n // Suppress unused variable warning — dotenvVars kept for future use\n void dotenvVars;\n\n return {};\n}\n","// Transform step executor: filter, map, sort.\n// Pure data manipulation — no external calls, no LLM.\n\nimport type {\n TransformStep,\n TransformFilterStep,\n TransformMapStep,\n TransformSortStep,\n RuntimeContext,\n} from '../types/index.js';\nimport { resolveExpression } from '../expression/index.js';\n\n/**\n * Execute a transform step.\n * Returns an object with the first declared output key mapped to the transformed array.\n */\nexport function executeTransform(\n step: TransformStep,\n resolvedInputs: Record<string, unknown>,\n context: RuntimeContext,\n): Record<string, unknown> {\n const items = getInputArray(resolvedInputs);\n let result: unknown[];\n\n switch (step.operation) {\n case 'filter':\n result = executeFilter(step, items, context);\n break;\n case 'map':\n result = executeMap(step, items, context);\n break;\n case 'sort':\n result = executeSort(step, items);\n break;\n }\n\n const outputKey = Object.keys(step.outputs)[0] ?? 'items';\n return { [outputKey]: result };\n}\n\n/** Find the array to transform from resolved inputs. */\nfunction getInputArray(inputs: Record<string, unknown>): unknown[] {\n // Convention: look for 'items' key first\n if ('items' in inputs && Array.isArray(inputs.items)) return inputs.items;\n // Fall back to first array value\n for (const val of Object.values(inputs)) {\n if (Array.isArray(val)) return val;\n }\n // Wrap single value in array for single-item transforms (e.g., echo fixture)\n const first = Object.values(inputs)[0];\n return first != null ? [first] : [];\n}\n\n/** Filter: keep items where the `where` expression is truthy. */\nfunction executeFilter(\n step: TransformFilterStep,\n items: unknown[],\n context: RuntimeContext,\n): unknown[] {\n return items.filter((item, index) => {\n const itemCtx: RuntimeContext = { ...context, item, index };\n return Boolean(resolveExpression(step.where, itemCtx));\n });\n}\n\n/** Map: project each item into a new shape using the `expression` object. */\nfunction executeMap(\n step: TransformMapStep,\n items: unknown[],\n context: RuntimeContext,\n): unknown[] {\n return items.map((item, index) => {\n const itemCtx: RuntimeContext = { ...context, item, index };\n const result: Record<string, unknown> = {};\n for (const [key, expr] of Object.entries(step.expression)) {\n result[key] = resolveMapValue(expr, itemCtx);\n }\n return result;\n });\n}\n\n/**\n * Resolve a map expression value.\n * - String starting with `$` → expression reference\n * - Non-string primitive (number, boolean, null) → pass through as literal\n * - Object (non-array) → recurse, applying same rules to each value\n * - String not starting with `$` → literal string\n */\nfunction resolveMapValue(value: unknown, context: RuntimeContext): unknown {\n if (typeof value === 'string') {\n if (value.startsWith('$')) {\n return resolveExpression(value, context);\n }\n return value;\n }\n if (value !== null && typeof value === 'object' && !Array.isArray(value)) {\n const result: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(value as Record<string, unknown>)) {\n result[k] = resolveMapValue(v, context);\n }\n return result;\n }\n return value;\n}\n\n/** Sort: order items by a field path in the given direction (default: asc). */\nfunction executeSort(step: TransformSortStep, items: unknown[]): unknown[] {\n const direction = step.direction ?? 'asc';\n return [...items].sort((a, b) => {\n const aVal = getNestedField(a, step.field);\n const bVal = getNestedField(b, step.field);\n if (aVal == null && bVal == null) return 0;\n if (aVal == null) return 1;\n if (bVal == null) return -1;\n if (aVal < bVal) return direction === 'asc' ? -1 : 1;\n if (aVal > bVal) return direction === 'asc' ? 1 : -1;\n return 0;\n });\n}\n\n/** Access a nested field by dot-notation path (e.g., \"user.name\"). */\nfunction getNestedField(obj: unknown, path: string): unknown {\n const parts = path.split('.');\n let current: unknown = obj;\n for (const part of parts) {\n if (current == null || typeof current !== 'object') return undefined;\n current = (current as Record<string, unknown>)[part];\n }\n return current;\n}\n","// Conditional step executor.\n// Evaluates the condition and returns which branch to take.\n\nimport type { ConditionalStep, RuntimeContext } from '../types/index.js';\nimport type { ConditionalOutput } from './types.js';\nimport { resolveExpression } from '../expression/index.js';\n\n/**\n * Execute a conditional step.\n * Evaluates the condition expression and returns the branch to execute.\n * The runtime is responsible for executing the branch steps.\n */\nexport function executeConditional(\n step: ConditionalStep,\n context: RuntimeContext,\n): ConditionalOutput {\n const conditionResult = resolveExpression(step.condition, context);\n const isTruthy = Boolean(conditionResult);\n\n if (isTruthy) {\n return { branch: 'then', stepIds: step.then };\n } else if (step.else) {\n return { branch: 'else', stepIds: step.else };\n } else {\n return { branch: null, stepIds: [] };\n }\n}\n","// Exit step executor.\n// Resolves the output expression and signals workflow termination.\n\nimport type { ExitStep, RuntimeContext } from '../types/index.js';\nimport type { ExitOutput } from './types.js';\nimport { resolveExpression, containsTemplate, resolveTemplate } from '../expression/index.js';\n\n/**\n * Execute an exit step.\n * Output can be:\n * - A string expression: resolved against context\n * - An object literal: each string value starting with $ is resolved, others kept as-is\n * - Undefined: null output\n */\nexport function executeExit(\n step: ExitStep,\n context: RuntimeContext,\n): ExitOutput {\n let output: unknown = null;\n if (step.output) {\n if (typeof step.output === 'string') {\n output = resolveExpression(step.output, context);\n } else {\n // Object literal — resolve expression values within it\n output = resolveOutputObject(step.output, context);\n }\n }\n return { status: step.status, output };\n}\n\nfunction resolveOutputObject(\n obj: Record<string, unknown>,\n context: RuntimeContext,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(obj)) {\n if (typeof val === 'string') {\n if (val.startsWith('$$')) {\n result[key] = val.slice(1);\n } else if (containsTemplate(val)) {\n result[key] = resolveTemplate(val, context);\n } else if (val.startsWith('$')) {\n result[key] = resolveExpression(val, context);\n } else {\n result[key] = val;\n }\n } else {\n result[key] = val;\n }\n }\n return result;\n}\n","// Executor result types and error class.\n\nimport type { ExitStatus } from '../types/index.js';\n\n/** Additional context attached to a step execution error. */\nexport interface StepErrorContext {\n /** Tool name if the error came from a tool step. */\n tool?: string;\n /** Expression string if the error came from expression resolution. */\n expression?: string;\n}\n\n/** Error thrown by step executors. */\nexport class StepExecutionError extends Error {\n constructor(\n message: string,\n /** Whether this error is retriable (network errors, rate limits, transient API failures). */\n public readonly retriable: boolean = false,\n /** Optional context about the error source. */\n public readonly context?: StepErrorContext,\n ) {\n super(message);\n this.name = 'StepExecutionError';\n }\n}\n\n/** Result from a standard step execution (tool, transform). */\nexport interface StepOutput {\n output: unknown;\n}\n\n/** Result from a conditional step execution. */\nexport interface ConditionalOutput {\n branch: 'then' | 'else' | null;\n stepIds: string[];\n}\n\n/** Result from an exit step execution. */\nexport interface ExitOutput {\n status: ExitStatus;\n output: unknown;\n}\n","// Tool step executor.\n// Invokes a registered tool via the ToolAdapter and returns the response.\n\nimport type { ToolStep, ToolAdapter } from '../types/index.js';\nimport type { StepOutput } from './types.js';\nimport { StepExecutionError } from './types.js';\n\n/**\n * Execute a tool step.\n * Passes resolved inputs as the tool's arguments. Returns the tool's response.\n * The runtime does not interpret the response (per spec).\n */\nexport async function executeTool(\n step: ToolStep,\n resolvedInputs: Record<string, unknown>,\n toolAdapter: ToolAdapter,\n): Promise<StepOutput> {\n const result = await toolAdapter.invoke(step.tool, resolvedInputs);\n if (result.error) {\n // Tool errors are considered retriable (network issues, rate limits, transient failures)\n throw new StepExecutionError(result.error, true, { tool: step.tool });\n }\n return { output: result.output };\n}\n","// Step executor dispatch.\n// Routes each step to the appropriate executor based on its type.\n\nimport type {\n Step,\n ToolAdapter,\n RuntimeContext,\n ExitStatus,\n} from '../types/index.js';\nimport { executeTransform } from './transform.js';\nimport { executeConditional } from './conditional.js';\nimport { executeExit } from './exit.js';\nimport { executeTool } from './tool.js';\n\nexport { StepExecutionError } from './types.js';\nexport type { StepOutput, ConditionalOutput, ExitOutput, StepErrorContext } from './types.js';\nexport { executeTransform } from './transform.js';\nexport { executeConditional } from './conditional.js';\nexport { executeExit } from './exit.js';\nexport { executeTool } from './tool.js';\n\n/** Discriminated result from dispatching a step. */\nexport type DispatchResult =\n | { kind: 'output'; output: unknown }\n | { kind: 'branch'; branch: 'then' | 'else' | null; stepIds: string[] }\n | { kind: 'exit'; status: ExitStatus; output: unknown };\n\n/**\n * Dispatch a step to the appropriate executor.\n * The runtime calls this for each step in the execution loop.\n */\nexport async function dispatch(\n step: Step,\n resolvedInputs: Record<string, unknown>,\n context: RuntimeContext,\n toolAdapter: ToolAdapter,\n): Promise<DispatchResult> {\n switch (step.type) {\n case 'tool': {\n const result = await executeTool(step, resolvedInputs, toolAdapter);\n return { kind: 'output', ...result };\n }\n case 'transform': {\n const output = executeTransform(step, resolvedInputs, context);\n return { kind: 'output', output };\n }\n case 'conditional': {\n const result = executeConditional(step, context);\n return { kind: 'branch', ...result };\n }\n case 'exit': {\n const result = executeExit(step, context);\n return { kind: 'exit', ...result };\n }\n }\n}\n","// Runtime orchestrator.\n// Validates the workflow, executes steps through the 9-step lifecycle, and produces a run log.\n\nimport type {\n WorkflowDefinition,\n WorkflowInput,\n Step,\n StepInput,\n StepOutput,\n RuntimeContext,\n ToolAdapter,\n RunLog,\n RunLogError,\n RunStatus,\n StepRecord,\n RetryRecord,\n ExitStatus,\n ValidationError,\n RuntimeEvent,\n} from '../types/index.js';\nimport { parseContent } from '../parser/parse-content.js';\nimport { resolveExpression, resolveTemplate, containsTemplate } from '../expression/index.js';\nimport { validateWorkflow } from '../validator/index.js';\nimport { dispatch, StepExecutionError } from '../executor/index.js';\nimport type { DispatchResult } from '../executor/index.js';\n\n/** Resolve a value field:\n * 1. starts with $$ → strip one $ (literal escape)\n * 2. contains ${...} → template interpolation\n * 3. starts with $ → whole expression\n * 4. otherwise → literal\n */\nfunction resolveValue(value: unknown, context: RuntimeContext): unknown {\n if (typeof value !== 'string') return value;\n if (value.startsWith('$$')) return value.slice(1);\n if (containsTemplate(value)) return resolveTemplate(value, context);\n if (value.startsWith('$')) return resolveExpression(value, context);\n return value;\n}\n\n/** Emit a runtime event if a callback is registered. */\nfunction emit(onEvent: ((event: RuntimeEvent) => void) | undefined, event: RuntimeEvent): void {\n onEvent?.(event);\n}\n\n// ─── Public API ──────────────────────────────────────────────────────────────\n\nexport class WorkflowExecutionError extends Error {\n constructor(\n message: string,\n public readonly validationErrors?: ValidationError[],\n ) {\n super(message);\n this.name = 'WorkflowExecutionError';\n }\n}\n\n/**\n * Build a minimal RunLog for a pre-execution failure (parse or validate phase).\n * Every run attempt — even those that fail before execution begins — produces a structured artifact.\n */\nexport function buildFailedRunLog(\n workflowName: string,\n error: RunLogError,\n startedAt?: Date,\n): RunLog {\n const now = new Date();\n const start = startedAt ?? now;\n const durationMs = now.getTime() - start.getTime();\n return {\n id: crypto.randomUUID(),\n workflow: workflowName,\n status: 'failed',\n summary: {\n steps_executed: 0,\n steps_skipped: 0,\n total_duration_ms: durationMs,\n },\n started_at: start.toISOString(),\n completed_at: now.toISOString(),\n duration_ms: durationMs,\n inputs: {},\n steps: [],\n outputs: {},\n error,\n };\n}\n\nexport interface RunOptions {\n workflow: WorkflowDefinition;\n inputs?: Record<string, unknown>;\n toolAdapter: ToolAdapter;\n workflowName?: string;\n /** Optional callback for live progress events during execution. */\n onEvent?: (event: RuntimeEvent) => void;\n}\n\n/**\n * Execute a workflow and produce a run log.\n * Phase 1: Validate the workflow definition.\n * Phase 2: Execute steps in declaration order following the 9-step lifecycle.\n */\nexport async function runWorkflow(options: RunOptions): Promise<RunLog> {\n const { onEvent } = options;\n const startedAt = new Date();\n\n // Phase 1: Validate\n const validation = validateWorkflow(options.workflow, options.toolAdapter);\n if (!validation.valid) {\n const message = `Workflow validation failed: ${validation.errors.map((e) => e.message).join('; ')}`;\n return buildFailedRunLog(\n options.workflowName ?? 'unnamed',\n {\n phase: 'validate',\n message,\n details: validation.errors,\n },\n startedAt,\n );\n }\n\n const workflowName = options.workflowName ?? 'unnamed';\n emit(onEvent, {\n type: 'workflow_start',\n workflow: workflowName,\n totalSteps: options.workflow.steps.length,\n });\n\n // Phase 2: Execute\n const inputs = applyDefaults(options.workflow.inputs, options.inputs ?? {});\n const context: RuntimeContext = { inputs, steps: {} };\n const stepRecords: StepRecord[] = [];\n\n // Identify branch steps (only execute when selected by conditional)\n const branchStepIds = collectBranchStepIds(options.workflow.steps);\n const stepMap = new Map(options.workflow.steps.map((s) => [s.id, s]));\n\n let workflowStatus: RunStatus = 'success';\n let workflowOutput: unknown = null;\n let exitFired = false;\n let halted = false;\n\n for (const step of options.workflow.steps) {\n if (halted) break;\n\n // Branch steps are skipped during normal sequential execution.\n // They execute only when selected by a conditional step.\n if (branchStepIds.has(step.id)) continue;\n\n const result = await executeStepLifecycle(\n step,\n context,\n stepMap,\n branchStepIds,\n options.toolAdapter,\n onEvent,\n );\n stepRecords.push(...result.records);\n\n if (result.exit) {\n halted = true;\n exitFired = true;\n workflowStatus = result.exit.status === 'failed' ? 'failed' : 'success';\n workflowOutput = result.exit.output;\n } else if (result.failed) {\n halted = true;\n workflowStatus = 'failed';\n } else {\n workflowOutput = context.steps[step.id]?.output ?? null;\n }\n }\n\n // Account for unrecorded steps (spec: \"Every step is accounted for, including skipped ones.\")\n const recordedIds = new Set(stepRecords.map((r) => r.id));\n for (const step of options.workflow.steps) {\n if (!recordedIds.has(step.id)) {\n const reason = branchStepIds.has(step.id) ? 'Branch not selected' : 'Workflow halted';\n emit(onEvent, { type: 'step_skip', stepId: step.id, reason, description: step.description });\n stepRecords.push({\n id: step.id,\n executor: step.type,\n status: 'skipped',\n reason,\n duration_ms: 0,\n });\n }\n }\n\n // Build outputs\n const outputs = buildWorkflowOutputs(options.workflow, workflowOutput, context, exitFired);\n\n const completedAt = new Date();\n const durationMs = completedAt.getTime() - startedAt.getTime();\n\n // Build summary\n let stepsExecuted = 0;\n let stepsSkipped = 0;\n for (const rec of stepRecords) {\n if (rec.status === 'skipped') stepsSkipped++;\n else stepsExecuted++;\n }\n\n const summary = {\n steps_executed: stepsExecuted,\n steps_skipped: stepsSkipped,\n total_duration_ms: durationMs,\n };\n\n emit(onEvent, {\n type: 'workflow_complete',\n status: workflowStatus,\n duration_ms: durationMs,\n summary,\n });\n\n return {\n id: crypto.randomUUID(),\n workflow: workflowName,\n status: workflowStatus,\n summary,\n started_at: startedAt.toISOString(),\n completed_at: completedAt.toISOString(),\n duration_ms: durationMs,\n inputs,\n steps: stepRecords,\n outputs,\n };\n}\n\n// ─── High-level API ──────────────────────────────────────────────────────────\n\nexport interface RunWorkflowSkillOptions {\n /** SKILL.md content or raw workflow YAML block. */\n content: string;\n inputs?: Record<string, unknown>;\n toolAdapter: ToolAdapter;\n /** Fallback name used when content has no frontmatter. Defaults to 'inline'. */\n workflowName?: string;\n onEvent?: (event: RuntimeEvent) => void;\n}\n\n/**\n * Parse content and execute the workflow in one call. Never throws.\n * Empty or unparseable content → failed RunLog (phase: 'parse').\n * Unexpected execution exception → failed RunLog (phase: 'execute').\n * Validation failures are handled internally by runWorkflow.\n */\nexport async function runWorkflowSkill(options: RunWorkflowSkillOptions): Promise<RunLog> {\n const { content, inputs, toolAdapter, workflowName = 'inline', onEvent } = options;\n const startedAt = new Date();\n\n const parsed = parseContent(content);\n if (!parsed.ok) {\n return buildFailedRunLog(workflowName, {\n phase: 'parse',\n message: parsed.message,\n details: parsed.details,\n }, startedAt);\n }\n\n const resolvedName = parsed.name ?? workflowName;\n try {\n return await runWorkflow({\n workflow: parsed.workflow,\n inputs,\n toolAdapter,\n workflowName: resolvedName,\n onEvent,\n });\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return buildFailedRunLog(resolvedName, { phase: 'execute', message }, startedAt);\n }\n}\n\n// ─── Step lifecycle ─────────────────────────────────────────────────────────\n\ninterface LifecycleResult {\n records: StepRecord[];\n exit?: { status: ExitStatus; output: unknown };\n failed?: boolean;\n}\n\n/**\n * Execute one step through the 9-step lifecycle:\n * 1. Guard 2. Resolve inputs 3. Iterate (each) 4. Dispatch\n * 5. Map outputs 6. Validate output 7. Retry 8. Handle errors 9. Record\n */\nasync function executeStepLifecycle(\n step: Step,\n context: RuntimeContext,\n stepMap: Map<string, Step>,\n branchStepIds: Set<string>,\n toolAdapter: ToolAdapter,\n onEvent?: (event: RuntimeEvent) => void,\n): Promise<LifecycleResult> {\n const startTime = performance.now();\n const records: StepRecord[] = [];\n\n // 1. Guard — evaluate condition guard (not for conditional steps which use condition differently)\n if (step.condition && step.type !== 'conditional') {\n const guardResult = resolveExpression(step.condition, context);\n if (!guardResult) {\n context.steps[step.id] = { output: null };\n emit(onEvent, { type: 'step_skip', stepId: step.id, reason: 'Guard condition evaluated to false', description: step.description });\n records.push({\n id: step.id,\n executor: step.type,\n status: 'skipped',\n reason: 'Guard condition evaluated to false',\n duration_ms: Math.round(performance.now() - startTime),\n });\n return { records };\n }\n }\n\n // step_start: emitted after guard passes, before input resolution\n emit(onEvent, {\n type: 'step_start',\n stepId: step.id,\n stepType: step.type,\n tool: step.type === 'tool' ? step.tool : undefined,\n description: step.description,\n });\n\n // 3. Iterate (each) — if present, execute once per element; each handles its own input resolution\n if (step.each) {\n return executeWithEach(\n step,\n context,\n toolAdapter,\n startTime,\n onEvent,\n );\n }\n\n // 2. Resolve inputs (only for non-each steps)\n const resolvedInputs = resolveInputs(step.inputs, context, step.id);\n\n // 4-7. Dispatch with retry + error handling\n try {\n const { result, retries } = await dispatchWithRetry(\n step,\n resolvedInputs,\n context,\n toolAdapter,\n onEvent,\n );\n\n // Handle dispatch result by kind\n if (result.kind === 'exit') {\n context.steps[step.id] = { output: result.output };\n const durationMs = Math.round(performance.now() - startTime);\n emit(onEvent, { type: 'step_complete', stepId: step.id, status: 'success', duration_ms: durationMs });\n records.push({\n id: step.id,\n executor: 'exit',\n status: 'success',\n duration_ms: durationMs,\n inputs: resolvedInputs,\n output: result.output,\n retries,\n });\n return { records, exit: { status: result.status, output: result.output } };\n }\n\n if (result.kind === 'branch') {\n // Execute the selected branch steps\n const branchRecords = await executeBranch(\n result.stepIds,\n context,\n stepMap,\n branchStepIds,\n toolAdapter,\n onEvent,\n );\n\n // Conditional step output = last branch step output\n const lastBranchStepId = result.stepIds[result.stepIds.length - 1];\n const conditionalOutput = lastBranchStepId\n ? (context.steps[lastBranchStepId]?.output ?? null)\n : null;\n context.steps[step.id] = { output: conditionalOutput };\n\n // Record the conditional step itself\n const durationMs = Math.round(performance.now() - startTime);\n emit(onEvent, { type: 'step_complete', stepId: step.id, status: 'success', duration_ms: durationMs });\n records.push({\n id: step.id,\n executor: 'conditional',\n status: 'success',\n duration_ms: durationMs,\n inputs: resolvedInputs,\n output: conditionalOutput,\n retries,\n });\n // Then the branch step records\n records.push(...branchRecords.records);\n\n return {\n records,\n exit: branchRecords.exit,\n failed: branchRecords.failed,\n };\n }\n\n // Normal output — apply step output source mapping\n const mappedOutput = applyStepOutputMapping(step.outputs, result.output, context);\n context.steps[step.id] = { output: mappedOutput };\n const durationMs = Math.round(performance.now() - startTime);\n emit(onEvent, {\n type: 'step_complete',\n stepId: step.id,\n status: 'success',\n duration_ms: durationMs,\n });\n records.push({\n id: step.id,\n executor: step.type,\n status: 'success',\n duration_ms: durationMs,\n inputs: resolvedInputs,\n output: mappedOutput,\n retries,\n });\n return { records };\n } catch (err) {\n // 6. Handle errors — apply on_error policy\n return handleStepError(step, err, context, startTime, resolvedInputs, undefined, onEvent);\n }\n}\n\n// ─── Each iteration ────────────────────────────────────────────────────────\n\nasync function executeWithEach(\n step: Step,\n context: RuntimeContext,\n toolAdapter: ToolAdapter,\n startTime: number,\n onEvent?: (event: RuntimeEvent) => void,\n): Promise<LifecycleResult> {\n const records: StepRecord[] = [];\n\n const eachArray = resolveExpression(step.each!, context);\n if (!Array.isArray(eachArray)) {\n return handleStepError(\n step,\n new StepExecutionError(`each expression must resolve to an array, got ${typeof eachArray}`),\n context,\n startTime,\n undefined,\n undefined,\n onEvent,\n );\n }\n\n // Resolve inputs with the base context (before iteration) for the record\n const baseResolvedInputs = resolveInputs(step.inputs, context, step.id);\n const results: unknown[] = [];\n let totalRetries: RetryRecord | undefined;\n\n try {\n for (let i = 0; i < eachArray.length; i++) {\n const itemContext: RuntimeContext = {\n ...context,\n item: eachArray[i],\n index: i,\n };\n const iterInputs = resolveInputs(step.inputs, itemContext, step.id);\n const { result, retries } = await dispatchWithRetry(\n step,\n iterInputs,\n itemContext,\n toolAdapter,\n onEvent,\n );\n\n if (retries) {\n totalRetries = totalRetries ?? { attempts: 0, errors: [] };\n totalRetries.attempts += retries.attempts;\n totalRetries.errors.push(...retries.errors);\n }\n\n if (result.kind === 'output') {\n // Apply per-element step output mapping\n const mappedIterOutput = applyStepOutputMapping(step.outputs, result.output, itemContext);\n results.push(mappedIterOutput);\n }\n\n emit(onEvent, { type: 'each_progress', stepId: step.id, current: i + 1, total: eachArray.length });\n\n // Inter-iteration delay for rate limiting\n if (step.delay && i < eachArray.length - 1) {\n await sleep(parseDelay(step.delay));\n }\n }\n } catch (err) {\n return handleStepError(step, err, context, startTime, baseResolvedInputs, totalRetries, onEvent);\n }\n\n context.steps[step.id] = { output: results };\n const durationMs = Math.round(performance.now() - startTime);\n emit(onEvent, {\n type: 'step_complete',\n stepId: step.id,\n status: 'success',\n duration_ms: durationMs,\n iterations: eachArray.length,\n });\n records.push({\n id: step.id,\n executor: step.type,\n status: 'success',\n duration_ms: durationMs,\n inputs: baseResolvedInputs,\n iterations: eachArray.length,\n output: results,\n retries: totalRetries,\n });\n\n return { records };\n}\n\n// ─── Branch execution ──────────────────────────────────────────────────────\n\nasync function executeBranch(\n stepIds: string[],\n context: RuntimeContext,\n stepMap: Map<string, Step>,\n branchStepIds: Set<string>,\n toolAdapter: ToolAdapter,\n onEvent?: (event: RuntimeEvent) => void,\n): Promise<LifecycleResult> {\n const records: StepRecord[] = [];\n\n for (const stepId of stepIds) {\n const branchStep = stepMap.get(stepId);\n if (!branchStep) continue;\n\n const result = await executeStepLifecycle(\n branchStep,\n context,\n stepMap,\n branchStepIds,\n toolAdapter,\n onEvent,\n );\n records.push(...result.records);\n\n if (result.exit) {\n return { records, exit: result.exit };\n }\n if (result.failed) {\n return { records, failed: true };\n }\n }\n\n return { records };\n}\n\n// ─── Retry logic ──────────────────────────────────────────────────────────\n\n/** Result from dispatchWithRetry: the dispatch result plus any retry tracking. */\ninterface RetryDispatchResult {\n result: DispatchResult;\n retries?: RetryRecord;\n}\n\nasync function dispatchWithRetry(\n step: Step,\n resolvedInputs: Record<string, unknown>,\n context: RuntimeContext,\n toolAdapter: ToolAdapter,\n onEvent?: (event: RuntimeEvent) => void,\n): Promise<RetryDispatchResult> {\n const retryPolicy = 'retry' in step ? step.retry : undefined;\n const maxRetries = retryPolicy?.max ?? 0;\n const baseDelay = retryPolicy ? parseDelay(retryPolicy.delay) : 0;\n const backoff = retryPolicy?.backoff ?? 1;\n\n let attempts = 0;\n const retryErrors: string[] = [];\n\n for (;;) {\n try {\n const result = await dispatch(step, resolvedInputs, context, toolAdapter);\n const retries = attempts > 0 ? { attempts, errors: retryErrors } : undefined;\n return { result, retries };\n } catch (err) {\n const isRetriable =\n err instanceof StepExecutionError && err.retriable && attempts < maxRetries;\n if (!isRetriable) {\n // Attach accumulated retry info to the error for handleStepError\n if (attempts > 0 && err instanceof Error) {\n (err as ErrorWithRetries).__retries = { attempts, errors: retryErrors };\n }\n throw err;\n }\n\n const errorMessage = err instanceof Error ? err.message : String(err);\n retryErrors.push(errorMessage);\n attempts++;\n emit(onEvent, { type: 'step_retry', stepId: step.id, attempt: attempts, error: errorMessage });\n const delay = baseDelay * Math.pow(backoff, attempts - 1);\n await sleep(delay);\n }\n }\n}\n\n// ─── Error handling ────────────────────────────────────────────────────────\n\n/** Error augmented with retry info by dispatchWithRetry. */\ninterface ErrorWithRetries extends Error {\n __retries?: RetryRecord;\n}\n\nfunction handleStepError(\n step: Step,\n err: unknown,\n context: RuntimeContext,\n startTime: number,\n resolvedInputs?: Record<string, unknown>,\n retries?: RetryRecord,\n onEvent?: (event: RuntimeEvent) => void,\n): LifecycleResult {\n // Enrich error message with context (tool name, expression)\n let errorMessage = err instanceof Error ? err.message : String(err);\n if (err instanceof StepExecutionError && err.context?.tool) {\n errorMessage = `Tool \"${err.context.tool}\": ${errorMessage}`;\n }\n // Extract retry info attached by dispatchWithRetry if not passed explicitly\n const effectiveRetries = retries ?? (err instanceof Error ? (err as ErrorWithRetries).__retries : undefined);\n const onError = step.on_error ?? 'fail';\n const durationMs = Math.round(performance.now() - startTime);\n\n context.steps[step.id] = { output: null };\n\n const record: StepRecord = {\n id: step.id,\n executor: step.type,\n status: 'failed',\n duration_ms: durationMs,\n inputs: resolvedInputs,\n error: errorMessage,\n retries: effectiveRetries,\n };\n\n emit(onEvent, { type: 'step_error', stepId: step.id, error: errorMessage, onError });\n emit(onEvent, { type: 'step_complete', stepId: step.id, status: 'failed', duration_ms: durationMs });\n\n if (onError === 'ignore') {\n // Log the error, set output to null, continue\n return { records: [record] };\n }\n\n // on_error: fail — halt the workflow\n return { records: [record], failed: true };\n}\n\n// ─── Input resolution ──────────────────────────────────────────────────────\n\nfunction resolveInputs(\n stepInputs: Record<string, StepInput>,\n context: RuntimeContext,\n stepId?: string,\n): Record<string, unknown> {\n const resolved: Record<string, unknown> = {};\n for (const [key, input] of Object.entries(stepInputs)) {\n if (input.value !== undefined) {\n try {\n resolved[key] = resolveValue(input.value, context);\n } catch (err) {\n const expr = typeof input.value === 'string' ? input.value : JSON.stringify(input.value);\n const prefix = stepId ? `Step \"${stepId}\" input \"${key}\"` : `Input \"${key}\"`;\n throw new StepExecutionError(\n `${prefix}: failed to resolve expression ${expr}: ${err instanceof Error ? err.message : String(err)}`,\n false,\n { expression: typeof input.value === 'string' ? input.value : undefined },\n );\n }\n }\n // If no value, the key is omitted (not set to null)\n }\n return resolved;\n}\n\n// ─── Helpers ──────────────────────────────────────────────────────────────\n\nfunction applyDefaults(\n schema: Record<string, WorkflowInput>,\n provided: Record<string, unknown>,\n): Record<string, unknown> {\n const result = { ...provided };\n for (const [key, def] of Object.entries(schema)) {\n if (!(key in result) && def.default !== undefined) {\n result[key] = def.default;\n }\n }\n return result;\n}\n\nfunction collectBranchStepIds(steps: Step[]): Set<string> {\n const ids = new Set<string>();\n for (const step of steps) {\n if (step.type === 'conditional') {\n for (const id of step.then) ids.add(id);\n if (step.else) {\n for (const id of step.else) ids.add(id);\n }\n }\n }\n return ids;\n}\n\n/**\n * Apply step output value mapping.\n * For each declared output with a `value` expression, resolve against the raw executor result.\n * Outputs without `value` pass through from raw output by key name.\n */\nfunction applyStepOutputMapping(\n stepOutputs: Record<string, StepOutput>,\n rawOutput: unknown,\n context: RuntimeContext,\n): unknown {\n const hasValues = Object.values(stepOutputs).some((o) => o.value !== undefined);\n if (!hasValues) return rawOutput;\n\n // Create a temporary context with $result set to the raw executor result\n const tempContext: RuntimeContext = { ...context, result: rawOutput };\n const mapped: Record<string, unknown> = {};\n\n for (const [key, outputDef] of Object.entries(stepOutputs)) {\n if (outputDef.value !== undefined) {\n mapped[key] = resolveValue(outputDef.value, tempContext);\n } else if (rawOutput !== null && typeof rawOutput === 'object' && !Array.isArray(rawOutput)) {\n // Pass through by key name from raw output\n mapped[key] = (rawOutput as Record<string, unknown>)[key] ?? null;\n } else {\n mapped[key] = null;\n }\n }\n\n return mapped;\n}\n\nfunction buildWorkflowOutputs(\n workflow: WorkflowDefinition,\n finalOutput: unknown,\n context: RuntimeContext,\n exitFired: boolean,\n): Record<string, unknown> {\n const outputKeys = Object.keys(workflow.outputs);\n if (outputKeys.length === 0) return {};\n\n // If exit fired, use exit output (unchanged behavior)\n if (exitFired) {\n if (finalOutput !== null && typeof finalOutput === 'object' && !Array.isArray(finalOutput)) {\n const outputObj = finalOutput as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n for (const key of outputKeys) {\n result[key] = outputObj[key] ?? null;\n }\n return result;\n }\n if (outputKeys.length === 1) {\n return { [outputKeys[0]!]: finalOutput };\n }\n return { [outputKeys[0]!]: finalOutput };\n }\n\n // Normal completion — resolve workflow output value expressions\n const hasAnyValues = Object.values(workflow.outputs).some((o) => o.value !== undefined);\n if (hasAnyValues) {\n const result: Record<string, unknown> = {};\n for (const [key, outputDef] of Object.entries(workflow.outputs)) {\n if (outputDef.value !== undefined) {\n result[key] = resolveValue(outputDef.value, context);\n } else if (finalOutput !== null && typeof finalOutput === 'object' && !Array.isArray(finalOutput)) {\n // Fall back to key-matching against last step output\n result[key] = (finalOutput as Record<string, unknown>)[key] ?? null;\n } else {\n result[key] = null;\n }\n }\n return result;\n }\n\n // No value fields — pass through by key name from final output\n if (finalOutput !== null && typeof finalOutput === 'object' && !Array.isArray(finalOutput)) {\n const outputObj = finalOutput as Record<string, unknown>;\n const result: Record<string, unknown> = {};\n for (const key of outputKeys) {\n result[key] = outputObj[key] ?? null;\n }\n return result;\n }\n\n // Wrap primitive/array in first output key\n if (outputKeys.length === 1) {\n return { [outputKeys[0]!]: finalOutput };\n }\n\n return { [outputKeys[0]!]: finalOutput };\n}\n\nfunction parseDelay(delay: string): number {\n const match = delay.match(/^(\\d+)(ms|s)$/);\n if (!match) return 0;\n const value = parseInt(match[1]!, 10);\n return match[2] === 's' ? value * 1000 : value;\n}\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n","import { existsSync, readFileSync } from 'node:fs';\nimport { join } from 'node:path';\n\nfunction readAuthoringSkill(): string {\n // For npm installs and dev (npm link): ../skill/SKILL.md relative to dist/\n // For tests running TypeScript source: ../../skill/SKILL.md relative to src/skill/\n const npmPath = join(import.meta.dirname, '../skill/SKILL.md');\n if (existsSync(npmPath)) {\n return readFileSync(npmPath, 'utf-8');\n }\n return readFileSync(join(import.meta.dirname, '../../skill/SKILL.md'), 'utf-8');\n}\n\nexport const AUTHORING_SKILL = readAuthoringSkill();\n"],"mappings":"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"}
|
package/package.json
CHANGED
package/skill/SKILL.md
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: workflow-author
|
|
3
3
|
description: Generate valid WorkflowSkill YAML from natural language descriptions. Teaches Claude Code to author executable workflow definitions.
|
|
4
|
-
version: 0.1.0
|
|
5
|
-
tags:
|
|
6
|
-
- workflow
|
|
7
|
-
- automation
|
|
8
|
-
- authoring
|
|
9
|
-
- code-generation
|
|
10
4
|
---
|
|
11
5
|
|
|
12
6
|
# WorkflowSkill Author
|
|
@@ -25,12 +19,12 @@ A WorkflowSkill is a declarative workflow definition embedded in a SKILL.md file
|
|
|
25
19
|
|
|
26
20
|
Each step is one of four types:
|
|
27
21
|
|
|
28
|
-
| Type
|
|
29
|
-
|
|
30
|
-
| `tool`
|
|
31
|
-
| `transform`
|
|
32
|
-
| `conditional` | Branch execution based on a condition
|
|
33
|
-
| `exit`
|
|
22
|
+
| Type | Purpose |
|
|
23
|
+
| ------------- | -------------------------------------------------------------------------------- |
|
|
24
|
+
| `tool` | Invoke a registered tool via the host's ToolAdapter (APIs, functions, LLM calls) |
|
|
25
|
+
| `transform` | Filter, map, or sort data |
|
|
26
|
+
| `conditional` | Branch execution based on a condition |
|
|
27
|
+
| `exit` | Terminate the workflow early with a status |
|
|
34
28
|
|
|
35
29
|
All external calls — including LLM inference — go through `tool` steps. The runtime itself has no LLM dependency. The host registers whatever tools are available in the deployment context.
|
|
36
30
|
|
|
@@ -39,12 +33,14 @@ All external calls — including LLM inference — go through `tool` steps. The
|
|
|
39
33
|
The user should never have to think about workflow internals. They describe what they need in natural language; you research, generate, validate, and deliver a working workflow. No proposal step, no asking for confirmation mid-flow. The output should feel like magic.
|
|
40
34
|
|
|
41
35
|
### Phase 1: Understand
|
|
36
|
+
|
|
42
37
|
- Read the request carefully. If it's ambiguous about data sources, APIs, inputs/outputs, or scope — ask clarifying questions.
|
|
43
38
|
- Ask at most 2-3 focused questions at a time. Offer specific options.
|
|
44
39
|
- Bad: "What do you want to do?" Good: "Should results be filtered by date, category, or both?"
|
|
45
40
|
- If the request is clear, skip directly to Research.
|
|
46
41
|
|
|
47
42
|
### Phase 2: Research
|
|
43
|
+
|
|
48
44
|
- **Confirm available tools first.** The tools available in `tool` steps are the tools registered in the current runtime context — in an interactive agent session, these are the tools listed in your context. No built-in tools are provided by the runtime. All tool names depend on what the host registers. Do not assume any specific tool exists.
|
|
49
45
|
- If the workflow involves APIs, web services, or web scraping, investigate before generating:
|
|
50
46
|
1. **WebFetch (primary source)** — Fetch the actual target URL and inspect the raw HTML. This is the ground truth. Look for:
|
|
@@ -58,6 +54,7 @@ The user should never have to think about workflow internals. They describe what
|
|
|
58
54
|
- **Do not guess selectors.** If you cannot verify the HTML structure, tell the user what you need.
|
|
59
55
|
|
|
60
56
|
### Phase 3: Generate
|
|
57
|
+
|
|
61
58
|
Design the workflow internally following this checklist, then write the `.md` file:
|
|
62
59
|
|
|
63
60
|
1. **Identify data sources and operations** — What tools or APIs are needed? These become `tool` steps. All external calls (including LLM inference) are tool steps.
|
|
@@ -70,6 +67,7 @@ Design the workflow internally following this checklist, then write the `.md` fi
|
|
|
70
67
|
Write the workflow `.md` file using the Write tool.
|
|
71
68
|
|
|
72
69
|
### Phase 4: Validate & Test
|
|
70
|
+
|
|
73
71
|
- Validate the workflow against the runtime. If validation fails, fix the errors and revalidate.
|
|
74
72
|
- Run the workflow to verify it works end-to-end.
|
|
75
73
|
- For workflows with conditional exits, test both execution paths (e.g., "results found" vs. "no results"). If the primary path targets data that might currently be empty, test with known data to verify the non-empty path works.
|
|
@@ -78,41 +76,42 @@ Write the workflow `.md` file using the Write tool.
|
|
|
78
76
|
## YAML Structure
|
|
79
77
|
|
|
80
78
|
```yaml
|
|
81
|
-
inputs:
|
|
79
|
+
inputs: # object keyed by name — NOT an array
|
|
82
80
|
<name>:
|
|
83
81
|
type: string | int | float | boolean | array | object
|
|
84
|
-
default: <optional>
|
|
82
|
+
default: <optional> # default value for optional inputs
|
|
85
83
|
|
|
86
|
-
outputs:
|
|
84
|
+
outputs: # object keyed by name — NOT an array
|
|
87
85
|
<name>:
|
|
88
86
|
type: string | int | float | boolean | array | object
|
|
89
|
-
value: <$expression>
|
|
87
|
+
value: <$expression> # optional — resolves from $steps context after all steps
|
|
90
88
|
|
|
91
89
|
steps:
|
|
92
90
|
- id: <unique_identifier>
|
|
93
91
|
type: tool | transform | conditional | exit
|
|
94
92
|
description: <what this step does>
|
|
95
93
|
# Type-specific fields (see below)
|
|
96
|
-
inputs:
|
|
94
|
+
inputs: # object keyed by name (the field is "inputs", not "params")
|
|
97
95
|
<name>:
|
|
98
|
-
type: <type>
|
|
99
|
-
value: <$expression or literal>
|
|
96
|
+
type: <type> # required
|
|
97
|
+
value: <$expression or literal> # the value: expression ($-prefixed) or literal
|
|
100
98
|
outputs:
|
|
101
99
|
<name>:
|
|
102
100
|
type: <type>
|
|
103
|
-
value: <$expression>
|
|
101
|
+
value: <$expression> # optional — maps from $result (raw executor result)
|
|
104
102
|
# Optional common fields:
|
|
105
|
-
condition: <expression>
|
|
106
|
-
each: <expression>
|
|
107
|
-
delay: "<duration>"
|
|
108
|
-
on_error: fail | ignore
|
|
103
|
+
condition: <expression> # guard: skip if false
|
|
104
|
+
each: <expression> # iterate over array
|
|
105
|
+
delay: "<duration>" # inter-iteration pause (requires each). e.g., "1s", "500ms"
|
|
106
|
+
on_error: fail | ignore # default: fail
|
|
109
107
|
retry:
|
|
110
|
-
max: <int>
|
|
111
|
-
delay: "<duration>"
|
|
108
|
+
max: <int> # not "max_attempts"
|
|
109
|
+
delay: "<duration>" # e.g., "1s", "500ms" — not "backoff_ms"
|
|
112
110
|
backoff: <float>
|
|
113
111
|
```
|
|
114
112
|
|
|
115
113
|
**Step input rules:**
|
|
114
|
+
|
|
116
115
|
- Every step input requires `type`.
|
|
117
116
|
- Use `value` for both expressions and literals. Strings starting with `$` are auto-detected as expressions.
|
|
118
117
|
- Expressions: `value: $inputs.query`, `value: $steps.prev.output.field`
|
|
@@ -124,6 +123,7 @@ steps:
|
|
|
124
123
|
## Step Type Reference
|
|
125
124
|
|
|
126
125
|
### Tool Step
|
|
126
|
+
|
|
127
127
|
```yaml
|
|
128
128
|
- id: fetch_data
|
|
129
129
|
type: tool
|
|
@@ -138,7 +138,7 @@ steps:
|
|
|
138
138
|
outputs:
|
|
139
139
|
results:
|
|
140
140
|
type: array
|
|
141
|
-
value: $result.items
|
|
141
|
+
value: $result.items # map from raw executor result
|
|
142
142
|
```
|
|
143
143
|
|
|
144
144
|
### Transform Step
|
|
@@ -146,6 +146,7 @@ steps:
|
|
|
146
146
|
Transform steps operate on **arrays only** (filter, map, sort). They require an `items` input of type `array` and always output an `items` array. Do NOT use transform steps to extract fields from a single object — use an exit step with `$`-references for that.
|
|
147
147
|
|
|
148
148
|
**filter:**
|
|
149
|
+
|
|
149
150
|
```yaml
|
|
150
151
|
- id: filter_items
|
|
151
152
|
type: transform
|
|
@@ -161,6 +162,7 @@ Transform steps operate on **arrays only** (filter, map, sort). They require an
|
|
|
161
162
|
```
|
|
162
163
|
|
|
163
164
|
### Transform Step (map)
|
|
165
|
+
|
|
164
166
|
```yaml
|
|
165
167
|
- id: reshape
|
|
166
168
|
type: transform
|
|
@@ -201,12 +203,13 @@ When you have parallel arrays from different steps that need to be combined into
|
|
|
201
203
|
This is a pure data operation — never use a tool step for merging or zipping arrays when a transform step suffices.
|
|
202
204
|
|
|
203
205
|
### Transform Step (sort)
|
|
206
|
+
|
|
204
207
|
```yaml
|
|
205
208
|
- id: sort_results
|
|
206
209
|
type: transform
|
|
207
210
|
operation: sort
|
|
208
211
|
field: score
|
|
209
|
-
direction: desc
|
|
212
|
+
direction: desc # or asc (default)
|
|
210
213
|
inputs:
|
|
211
214
|
items:
|
|
212
215
|
type: array
|
|
@@ -239,6 +242,7 @@ Use exit steps for **conditional early termination** — to stop the workflow wh
|
|
|
239
242
|
`status` must be `success` or `failed` — those are the only valid values.
|
|
240
243
|
|
|
241
244
|
Early exit on empty result (success):
|
|
245
|
+
|
|
242
246
|
```yaml
|
|
243
247
|
- id: early_exit
|
|
244
248
|
type: exit
|
|
@@ -252,6 +256,7 @@ Early exit on empty result (success):
|
|
|
252
256
|
```
|
|
253
257
|
|
|
254
258
|
Early exit on error condition (failed):
|
|
259
|
+
|
|
255
260
|
```yaml
|
|
256
261
|
- id: guard_empty
|
|
257
262
|
type: exit
|
|
@@ -267,10 +272,10 @@ For normal workflow output, prefer `value` on workflow outputs instead of a trai
|
|
|
267
272
|
|
|
268
273
|
## Output Resolution
|
|
269
274
|
|
|
270
|
-
| Context
|
|
271
|
-
|
|
272
|
-
| Step output `value`
|
|
273
|
-
| Workflow output `value` | `$steps.<id>.output` | After all steps complete
|
|
275
|
+
| Context | Reference | When resolved |
|
|
276
|
+
| ----------------------- | -------------------- | ------------------------------- |
|
|
277
|
+
| Step output `value` | `$result` | Immediately after step executes |
|
|
278
|
+
| Workflow output `value` | `$steps.<id>.output` | After all steps complete |
|
|
274
279
|
|
|
275
280
|
Workflow outputs use `value` to map data from step results:
|
|
276
281
|
|
|
@@ -278,10 +283,11 @@ Workflow outputs use `value` to map data from step results:
|
|
|
278
283
|
outputs:
|
|
279
284
|
title:
|
|
280
285
|
type: string
|
|
281
|
-
value: $steps.fetch.output.title
|
|
286
|
+
value: $steps.fetch.output.title # resolved after all steps complete
|
|
282
287
|
```
|
|
283
288
|
|
|
284
289
|
**Resolution rules:**
|
|
290
|
+
|
|
285
291
|
1. **Normal completion** — each workflow output with `value` (an expression) is resolved from the final runtime context using `$steps` references.
|
|
286
292
|
2. **Exit step fires** — the exit step's `output` takes precedence. Its keys are matched against the declared workflow output keys.
|
|
287
293
|
3. **No value, no exit** — outputs are matched by key name against the last executed step's output (legacy behavior).
|
|
@@ -294,7 +300,7 @@ outputs:
|
|
|
294
300
|
outputs:
|
|
295
301
|
results:
|
|
296
302
|
type: array
|
|
297
|
-
value: $result.items
|
|
303
|
+
value: $result.items # maps from the tool's raw response
|
|
298
304
|
```
|
|
299
305
|
|
|
300
306
|
This is useful when the raw executor result has a different shape than what downstream steps need. Outputs without `value` pass through from the raw result by key name.
|
|
@@ -303,16 +309,16 @@ This is useful when the raw executor result has a different shape than what down
|
|
|
303
309
|
|
|
304
310
|
Use `$`-prefixed references to wire data between steps:
|
|
305
311
|
|
|
306
|
-
| Reference
|
|
307
|
-
|
|
308
|
-
| `$inputs.name`
|
|
309
|
-
| `$steps.<id>.output`
|
|
310
|
-
| `$steps.<id>.output.field`
|
|
311
|
-
| `$item`
|
|
312
|
-
| `$index`
|
|
313
|
-
| `$result`
|
|
314
|
-
| `$steps.<id>.output.field[0]` | First element of an array field
|
|
315
|
-
| `$item[$index]`
|
|
312
|
+
| Reference | Resolves To |
|
|
313
|
+
| ----------------------------- | ----------------------------------------------------------------- |
|
|
314
|
+
| `$inputs.name` | Workflow input parameter |
|
|
315
|
+
| `$steps.<id>.output` | A step's full output |
|
|
316
|
+
| `$steps.<id>.output.field` | A specific field from output |
|
|
317
|
+
| `$item` | Current item in `each` or transform iteration |
|
|
318
|
+
| `$index` | Current index in iteration |
|
|
319
|
+
| `$result` | Raw executor result (only valid in step output `value`) |
|
|
320
|
+
| `$steps.<id>.output.field[0]` | First element of an array field |
|
|
321
|
+
| `$item[$index]` | Nested array element at computed index (only valid inside `each`) |
|
|
316
322
|
|
|
317
323
|
Operators: `==`, `!=`, `>`, `<`, `>=`, `<=`, `&&`, `||`, `!`, `contains`
|
|
318
324
|
|
|
@@ -366,17 +372,17 @@ steps:
|
|
|
366
372
|
- id: fetch_details
|
|
367
373
|
type: tool
|
|
368
374
|
tool: api.get_item
|
|
369
|
-
each: $steps.get_ids.output.items
|
|
370
|
-
delay: "2s"
|
|
371
|
-
on_error: ignore
|
|
375
|
+
each: $steps.get_ids.output.items # iterate over items array
|
|
376
|
+
delay: "2s" # required: rate limit between calls
|
|
377
|
+
on_error: ignore # skip failed fetches, continue
|
|
372
378
|
inputs:
|
|
373
379
|
id:
|
|
374
380
|
type: string
|
|
375
|
-
value: $item.id
|
|
381
|
+
value: $item.id # each item's ID from the listing
|
|
376
382
|
outputs:
|
|
377
383
|
title:
|
|
378
384
|
type: string
|
|
379
|
-
value: $result.title
|
|
385
|
+
value: $result.title # mapped per iteration via $result
|
|
380
386
|
summary:
|
|
381
387
|
type: string
|
|
382
388
|
value: $result.summary
|
|
@@ -385,11 +391,12 @@ steps:
|
|
|
385
391
|
After this step, `$steps.fetch_details.output` is an array of `{ title, summary }` objects — one per iteration. Use `$steps.fetch_details.output` (the whole array) in downstream steps or workflow outputs.
|
|
386
392
|
|
|
387
393
|
**Workflow output for each+tool:**
|
|
394
|
+
|
|
388
395
|
```yaml
|
|
389
396
|
outputs:
|
|
390
397
|
details:
|
|
391
398
|
type: array
|
|
392
|
-
value: $steps.fetch_details.output
|
|
399
|
+
value: $steps.fetch_details.output # the collected array of per-iteration results
|
|
393
400
|
```
|
|
394
401
|
|
|
395
402
|
**Pattern: List → Slice → Fetch Details**
|
|
@@ -422,7 +429,7 @@ steps:
|
|
|
422
429
|
- id: slice_items
|
|
423
430
|
type: transform
|
|
424
431
|
operation: filter
|
|
425
|
-
where: $index < $inputs.count
|
|
432
|
+
where: $index < $inputs.count # cap iteration count to avoid rate limiting
|
|
426
433
|
inputs:
|
|
427
434
|
items: { type: array, value: $steps.get_listing.output.items }
|
|
428
435
|
outputs:
|
|
@@ -450,7 +457,7 @@ steps:
|
|
|
450
457
|
3. **Always declare inputs and outputs.** They enable validation and composability.
|
|
451
458
|
4. **Use `value` on workflow outputs** to explicitly map step results to workflow outputs. Use `$steps.<id>.output.<field>` expressions. This is preferred over exit steps for producing output.
|
|
452
459
|
5. **Use `value` on step outputs** to map fields from the raw executor result using `$result`. Useful when the tool's response shape differs from what downstream steps need.
|
|
453
|
-
6. **Use `each` for per-item processing** on tool steps. Always include `delay` on every `each` loop that calls an external service — `delay: "2s"` is a safe default. See
|
|
460
|
+
6. **Use `each` for per-item processing** on tool steps. Always include `delay` on every `each` loop that calls an external service — `delay: "2s"` is a safe default. See _Iteration Patterns_.
|
|
454
461
|
7. **Add `on_error: ignore` for non-critical steps** like notifications.
|
|
455
462
|
8. **Add `retry` for external API calls** (tool steps that might fail transiently).
|
|
456
463
|
9. **Use `condition` guards for early exits** rather than letting empty data flow through.
|
|
@@ -460,8 +467,8 @@ steps:
|
|
|
460
467
|
13. **Use exit steps for conditional early termination only**, not as the default way to produce output. Exit output keys must match the declared workflow output keys.
|
|
461
468
|
14. **Transform steps are for arrays only.** Never use a transform to extract fields from a single object.
|
|
462
469
|
15. **Use `map` with `$index` for cross-array merging.** When multiple steps produce parallel arrays, use a `map` transform with bracket indexing (`$steps.other.output.field[$index]`) to zip them into structured objects.
|
|
463
|
-
16. **Guard expensive steps behind deterministic exits.** Pattern: fetch → filter → exit guard → expensive tool. Use deterministic expressions (e.g., `$item.department == "Engineering"` or `$item.title contains "Product Manager"`) in `transform filter` steps before any costly tool call. See
|
|
464
|
-
17. **Prefer bulk endpoints over per-item iteration.** When per-item `each` + tool calls are unavoidable, always add `delay: "2s"` (minimum), cap iteration count, and add `retry` with `backoff`. `delay` is not optional — external APIs rate-limit without warning. See
|
|
470
|
+
16. **Guard expensive steps behind deterministic exits.** Pattern: fetch → filter → exit guard → expensive tool. Use deterministic expressions (e.g., `$item.department == "Engineering"` or `$item.title contains "Product Manager"`) in `transform filter` steps before any costly tool call. See _Patterns_.
|
|
471
|
+
17. **Prefer bulk endpoints over per-item iteration.** When per-item `each` + tool calls are unavoidable, always add `delay: "2s"` (minimum), cap iteration count, and add `retry` with `backoff`. `delay` is not optional — external APIs rate-limit without warning. See _Iteration Patterns_.
|
|
465
472
|
|
|
466
473
|
## Output Format
|
|
467
474
|
|
|
@@ -510,6 +517,7 @@ steps:
|
|
|
510
517
|
## Validation
|
|
511
518
|
|
|
512
519
|
After writing the file, always validate it against the runtime. The validation checklist:
|
|
520
|
+
|
|
513
521
|
- [ ] All step IDs are unique
|
|
514
522
|
- [ ] All `$steps` references point to earlier steps
|
|
515
523
|
- [ ] All tools referenced are confirmed available in this deployment context
|