# @zibby/test-automation-core

Core test automation engine with multi-agent support, DAG-based workflow execution, and extensible skill system.

## Features

- **Multi-Agent Support** — Cursor (via cursor-agent CLI) and Claude (via Anthropic API)
- **Workflow Engine** — DAG-based graph compiler with typed state, conditional branching, and lifecycle hooks
- **Skill System** — Extensible registry that maps capabilities to MCP servers
- **Node Registry** — Register custom workflow nodes with Zod schemas and prompts
- **Code Generator** — Compile workflow graphs into standalone executable scripts

## Installation

```bash
npm install @zibby/test-automation-core
```

## Usage

### Functional Style (recommended)

```javascript
import { workflow, z } from '@zibby/test-automation-core';
import '@zibby/skills';

const agent = workflow((graph) => {
  graph.addNode('plan', {
    name: 'plan',
    prompt: (state) => `Analyze: "${state.input}". Return JSON.`,
    outputSchema: z.object({ action: z.string() }),
  });
  graph.addNode('execute', {
    name: 'execute',
    skills: ['browser'],
    prompt: (state) => `Execute: ${state.plan.action}`,
    outputSchema: z.object({ result: z.string() }),
  });
  graph.setEntryPoint('plan');
  graph.addEdge('plan', 'execute');
  graph.addEdge('execute', 'END');
});

await agent.run('Navigate to example.com and verify the title');
```

### Class-Based Style

```javascript
import { WorkflowAgent, WorkflowGraph, z } from '@zibby/test-automation-core';

class MyAgent extends WorkflowAgent {
  buildGraph() {
    const graph = new WorkflowGraph();
    graph.addNode('plan', { /* ... */ });
    graph.addNode('execute', { /* ... */ });
    graph.setEntryPoint('plan');
    graph.addEdge('plan', 'execute');
    graph.addEdge('execute', 'END');
    return graph;
  }
}

const agent = new MyAgent();
await agent.run('Do something');
```

### Custom Nodes

Define workflow nodes with Zod output schemas:

```javascript
import { z } from '@zibby/test-automation-core';

export const myNode = {
  name: 'analyze',
  skills: ['browser'],
  prompt: (state) => `Analyze ${state.input} and extract key information`,
  outputSchema: z.object({
    title: z.string(),
    links: z.array(z.string()),
  }),
};
```

### Skill Registry

```javascript
import { registerSkill, getSkill, listSkillIds } from '@zibby/test-automation-core';

// Register a custom MCP skill
registerSkill({
  id: 'my-tool',
  serverName: 'my-mcp-server',
  command: 'npx',
  args: ['my-mcp-package'],
  allowedTools: ['do_thing'],
  resolve: () => ({ command: 'npx', args: ['my-mcp-package'] }),
});

// Query the registry
const skill = getSkill('browser');
const allIds = listSkillIds();
```

## Architecture

```
@zibby/test-automation-core
├── src/
│   ├── framework/           # Workflow engine
│   │   ├── graph.js         # WorkflowGraph (DAG builder)
│   │   ├── graph-compiler.js # Compiles graphs to execution plans
│   │   ├── node.js          # Node execution with agent invocation
│   │   ├── node-registry.js # Register/lookup custom nodes
│   │   ├── skill-registry.js # Skill → MCP server mapping
│   │   ├── tool-resolver.js # Resolves skills to MCP configs
│   │   ├── code-generator.js # Generate standalone scripts
│   │   ├── state.js         # Typed workflow state
│   │   └── agents/          # Agent strategies
│   │       ├── cursor-strategy.js
│   │       └── claude-strategy.js
│   ├── runtime/             # Browser runtime utilities
│   ├── utils/               # Helpers (logger, selectors, parsers)
│   └── index.js             # Public API
├── templates/               # Built-in workflow templates
│   ├── browser-test-automation/
│   └── code-analysis/
└── scripts/                 # Setup scripts (Playwright MCP, CI)
```

## Environment Variables

```bash
# Cursor agent (CI/CD only — local uses stored credentials)
CURSOR_API_KEY=your-cursor-token

# Claude agent
ANTHROPIC_API_KEY=sk-ant-...

# Cloud sync (optional)
ZIBBY_API_KEY=zby_xxx
```

## License

MIT
