npm package: @skill-kit/compose
Description: Workflow composer and orchestrator for Skill Kit
Latest version: 1.0.0

# @skill-kit/compose

Workflow composer and orchestrator for Skill Kit. Define, execute, and visualize complex workflows that combine multiple Skills.

## Installation

```bash
npm install @skill-kit/compose
# or
pnpm add @skill-kit/compose
```

## Quick Start

### Define a Workflow (YAML)

```yaml
# workflow.yaml
name: data-pipeline
description: Process and transform data
version: 1.0.0

inputs:
  source:
    type: string
    description: Data source URL

steps:
  - id: fetch
    skill: http-fetcher
    inputs:
      url: ${inputs.source}

  - id: validate
    skill: data-validator
    inputs:
      data: ${fetch.response}

  - id: transform
    skill: data-transformer
    inputs:
      data: ${validate.data}
    when: ${validate.isValid}

outputs:
  result:
    value: ${transform.output}
```

### Execute with CLI

```bash
# Run a workflow
skill-compose run workflow.yaml --input source=https://api.example.com/data

# Validate workflow syntax
skill-compose validate workflow.yaml

# Visualize workflow
skill-compose visualize workflow.yaml --format mermaid
```

### Use Programmatically

```typescript
import { parseWorkflowFile, executeWorkflow } from '@skill-kit/compose';

const { workflow } = await parseWorkflowFile('./workflow.yaml');

const result = await executeWorkflow(workflow, {
  inputs: { source: 'https://api.example.com/data' },
  skillExecutor: async (skillName, inputs) => {
    // Implement your skill execution logic
    return { output: `Executed ${skillName}` };
  },
});

console.log('Status:', result.status);
console.log('Outputs:', result.outputs);
```

## Features

### Control Flow

#### Parallel Execution

```yaml
steps:
  - id: parallel-tasks
    parallel:
      - id: task1
        skill: fast-task
      - id: task2
        skill: slow-task
    maxConcurrency: 2
    failureStrategy: wait-all # or fail-fast
```

#### Conditional Branching

```yaml
steps:
  - id: check
    condition:
      if: ${inputs.enabled} and ${validate.isValid}
      then:
        id: process
        skill: processor
      else:
        id: skip
        skill: logger
```

#### Loops (foreach)

```yaml
steps:
  - id: process-items
    foreach:
      items: ${inputs.items}
      as: item
      index: idx
      step:
        id: process
        skill: item-processor
        inputs:
          data: ${item}
          position: ${idx}
      maxConcurrency: 5
```

### Variable Interpolation

```yaml
inputs:
  name: Alice
  config:
    timeout: 5000

steps:
  - id: greet
    skill: greeter
    inputs:
      message: Hello ${inputs.name}!
      timeout: ${inputs.config.timeout}
      fallback: ${missing:-default-value}
      envVar: ${env.API_KEY}
```

### Error Handling

```yaml
steps:
  - id: flaky-step
    skill: unreliable-service
    onError:
      action: retry
      retry:
        maxRetries: 3
        initialDelay: 1000
        maxDelay: 30000
        exponential: true

  - id: optional-step
    skill: optional-service
    onError:
      action: continue
      fallback: { status: 'skipped' }
```

### Workflow-level Error Strategy

```yaml
name: robust-workflow
onError:
  action: fail # fail | continue | retry

steps:
  # ...
```

## Visualization

### ASCII Output

```
skill-compose visualize workflow.yaml --format simple
```

```
[data-pipeline]

├─ fetch: http-fetcher
├─ validate: data-validator
├─ transform: data-transformer
```

### Mermaid Output

```
skill-compose visualize workflow.yaml --format mermaid
```

```mermaid
flowchart TB
    fetch["http-fetcher"]
    validate["data-validator"]
    transform["data-transformer"]
    fetch --> validate
    validate --> transform
```

## API Reference

### Parser

```typescript
// Parse YAML string
const result = parseWorkflowString(yamlContent, { validate: true });

// Parse from file
const workflowFile = await parseWorkflowFile('./workflow.yaml');

// Validate workflow object
const validation = validateWorkflow(workflowObject);
```

### Executor

```typescript
// Create executor
const executor = createExecutor(workflow, {
  inputs: { ... },
  skillExecutor: async (name, inputs, context) => { ... },
  timeout: 30000,
  maxConcurrency: 10,
  onStepStart: (step, context) => { ... },
  onStepComplete: (step, result, context) => { ... },
});

// Execute
const result = await executor.execute();

// Cancel
executor.cancel();
```

### Visualization

```typescript
// ASCII
const ascii = toAscii(workflow);
const simple = toSimpleAscii(workflow);

// Mermaid
const mermaid = toMermaid(workflow, { direction: 'LR' });
```

## Types

```typescript
interface Workflow {
  name: string;
  description?: string;
  version?: string;
  inputs?: Record<string, InputDefinition>;
  outputs?: Record<string, OutputDefinition>;
  steps: WorkflowStep[];
  onError?: ErrorStrategy;
}

type WorkflowStep =
  | SkillStep
  | ParallelStep
  | ConditionStep
  | ForeachStep
  | WhileStep
  | SubWorkflowStep;

interface ExecutionResult {
  status: 'completed' | 'failed' | 'cancelled';
  outputs: Record<string, unknown>;
  steps: StepResult[];
  duration: number;
  error?: Error;
}
```

## License

MIT