Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
190 changes: 17 additions & 173 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -1,179 +1,23 @@
# Workflow Engine Copilot Instructions
# Workflow Engine - Copilot Instructions

Configuration-driven workflow orchestration engine (Go 1.26+) built on [`GoCodeAlone/modular`](https://github.com/GoCodeAlone/modular). YAML configs become running applications — API servers, event pipelines, state machines, scheduled jobs, and more — with 90+ built-in module types.
Configuration-driven workflow orchestration engine in Go. Keep this file short;
the detailed agent guide is `docs/AGENT_GUIDE.md`, and layout rules are in
`docs/REPO_LAYOUT.md`.

## Build, Test, Lint
## Must Follow

```sh
# Build (prefer make targets over raw go build)
make build-go # builds server binary → ./server
make build-wfctl # builds CLI → ./wfctl
make build # builds UI + server (full build)
make build-examples # builds example/ directory

# Test
make test # go test -race ./...
go test -run TestName ./module/ # single test
go test -run TestName -v ./... # single test, verbose, all packages
go test -cover ./... # with coverage
make test-configs # validate example YAML configs load correctly

# Lint
make lint # golangci-lint run --timeout=5m
make fmt # go fmt ./...
make vet # go vet ./...
make ci # fmt + vet + test + lint (pre-push suite)

# Benchmarks
make bench # full benchmark suite
make bench-baseline # save baseline (count=6)
make bench-compare # compare current vs baseline with benchstat

# UI (React + Vite)
cd ui && npm ci && npm run dev # dev server
cd ui && npm test -- --run # run tests
cd ui && npm run lint # ESLint
```

## Architecture

### Engine Core

`StdEngine` (root package `workflow`) is the central orchestrator:

- **`engine.go`** — `StdEngine` struct: holds the `modular.Application`, workflow handlers, loaded plugins, module/step/trigger factories, pipeline registry, secrets resolver, and infra provisioner.
- **`engine_builder.go`** — Fluent builder: `NewEngineBuilder().WithApplication(app).WithAllDefaults().WithPlugin(p).Build()`.
- **`interfaces/`** — Shared interfaces (`Trigger`, `StepRegistrar`, etc.) to avoid import cycles.

### Plugin System (the primary extension mechanism)

Everything is a plugin. The `EnginePlugin` interface (`plugin/engine_plugin.go`) provides:
- `ModuleFactories()` — register new module types
- `StepFactories()` — register new pipeline step types
- `TriggerFactories()` — register new trigger types
- `WorkflowHandlers()` — register new workflow handler types
- `ModuleSchemas()` / `StepSchemas()` — UI metadata
- `WiringHooks()` — post-init cross-module wiring
- `ConfigTransformHooks()` — pre-registration config transforms
- `DeployTargets()` / `SidecarProviders()` — deployment extensions

**Built-in plugins** live in `plugins/` (~32 packages: http, auth, messaging, statemachine, pipelinesteps, ai, storage, observability, etc.). They're loaded in `cmd/server/main.go` via `allplugins`.

**External plugins** (`workflow-plugin-*` sibling repos) are separate Go modules with a `plugin.json` manifest declaring capabilities (module types, step types, tier, minEngineVersion).

### Pipeline & Expression Engines

Pipelines are the primary way work flows through the system. Two template/expression syntaxes:

- **Go templates** `{{ .steps.prev.output }}` — processed by `pipeline/template.go` (`TemplateEngine`)
- **Expr-lang** `${ steps.prev.output }` — processed by `pipeline/expr.go` (`ExprEngine`, powered by `expr-lang/expr`)

Pipeline steps live in `module/pipeline_step_<name>.go` and are registered via `plugins/pipelinesteps/plugin.go`.

### Module System

All module implementations live in `module/` (~277 source files). Major categories:
- **HTTP**: server, router, handlers, middleware (auth, CORS, rate-limit, security headers, OTEL), reverse proxy
- **Messaging**: Kafka, NATS, memory broker, EventBus bridge
- **Database**: PostgreSQL, SQLite, DynamoDB, Redis, MongoDB
- **Cloud**: AWS (ECS, EKS, S3, Route53, CodeBuild), GCP, Azure, DigitalOcean
- **Platform**: Kubernetes, DNS, networking, IaC state
- **State**: state machine, state tracker, state connector
- **Auth**: JWT, OAuth2, M2M, token blacklist, user store
- **Observability**: OTEL tracing, Prometheus, health checks, SSE tracer
- **Pipeline**: 100+ step types (set, validate, transform, conditional, http_call, db_query, deploy, git, Docker, S3, circuit breaker, feature flags, etc.)

### Binaries (`cmd/`)

- **`cmd/server/`** — Main server. Flags: `-config`, `-addr`, `-jwt-secret`, `-database-dsn`, `-license-key`, etc.
- **`cmd/wfctl/`** — CLI tool with 34 commands (validate, inspect, run, deploy, plugin, mcp, test, secrets, security, wizard, etc.). Commands are defined in `cmd/wfctl/<command>.go`. The CLI itself runs through the workflow engine — commands are pipelines triggered via `"cli"` trigger.
- **`cmd/workflow-lsp-server/`** — LSP server for IDE integration.
- Use `GOWORK=off` for Go commands in this multi-repo workspace.
- Prefer make targets when available: `make build-wfctl`, `make build-examples`,
`make test-configs`.
- Keep examples in `example/`; do not add root `examples/`, `test-*`, or scratch
app directories.
- Update docs and tests with behavior, CLI, config, or layout changes.

### MCP Server (`mcp/`)
## Common Commands

Exposes the engine to AI assistants via [Model Context Protocol](https://modelcontextprotocol.io). Tools include `get_module_schema`, `get_step_schema`, `validate_template_expressions`, `infer_pipeline_context`, scaffold tools, and wfctl wrappers.

### Dynamic Hot-Reload (`dynamic/`)

Yaegi-based system (`GoCodeAlone/yaegi` fork) for loading Go components at runtime without recompilation.

## Key Conventions

### File Naming & Registration

- Module implementations: `module/<type>.go` (e.g., `module/http_server.go`)
- Pipeline steps: `module/pipeline_step_<name>.go`
- Template functions: registered in `module/pipeline_template.go` via `templateFuncMap()`
- Module factories: registered in plugin `ModuleFactories()` or `engine.go` `BuildFromConfig()`
- Plugin step/module factories: registered in `plugins/<name>/plugin.go`
- wfctl commands: `cmd/wfctl/<command>.go`

### Testing Patterns

- Tests colocated with source (`*_test.go` alongside `*.go`)
- Shared mocks in `mock/`
- Test helpers: `testhelpers_test.go` (root), `module/module_test_helpers.go`
- Isolated app per test: `modular.NewStdApplication(modular.NewStdConfigProvider(nil), mockLogger)`
- Use `testify` for assertions
- Always test with `-race` flag
- E2E tests at root: `e2e_execution_test.go`, `e2e_middleware_test.go`, etc.
- Use `app.SetConfigFeeders()` in tests, not global `modular.ConfigFeeders` mutation
- Coverage targets: 80%+ for most packages, 85%+ for `ai/`

### YAML Config Structure

```yaml
modules:
- name: my-server
type: http.server
config:
address: ":8080"

workflows:
http:
routes:
- method: GET
path: /api/health
handler: health-handler

pipelines:
process-request:
steps:
- name: validate
type: step.validate
config:
rules: [...]
```sh
GOWORK=off go test ./...
GOWORK=off go test ./cmd/wfctl -run TestName -count=1
GOWORK=off golangci-lint run
cd ui && npm test -- --run
```

### Documentation Updates

When adding functionality, update the corresponding docs:

| Change | Update |
|---|---|
| New module type | `DOCUMENTATION.md` module table, factory registration |
| New pipeline step | `DOCUMENTATION.md` step table, register in plugin |
| New template function | `DOCUMENTATION.md`, add to `templateFuncMap()` |
| New wfctl command | `docs/WFCTL.md`, update `main.go` usage() |
| New trigger type | `DOCUMENTATION.md` trigger types section |

### Commit Messages

Imperative mood, 50-char summary line. Reference issues with `Fixes #N` or `Relates to #N`.

### Error Handling

Return errors with context (`fmt.Errorf("action: %w", err)`), don't panic. Modules implementing `StartStopModule` must clean up resources in `Stop()`.

## Ecosystem

This repo is the hub of a multi-repo ecosystem under [GoCodeAlone](https://github.com/GoCodeAlone):

- **`modular`** — Core Go application framework (dependency injection, lifecycle, config, observers)
- **`workflow-cloud`** / **`workflow-cloud-ui`** — SaaS control plane (plugin registry, licensing, multi-tenant)
- **`workflow-ui`** — Shared React component library (React 19, Zustand, GitHub Packages)
- **`workflow-editor`** — Visual YAML editor (Vite, Playwright E2E)
- **`workflow-vscode`** / **`workflow-jetbrains`** — IDE plugins (LSP, schema validation, snippets)
- **`workflow-registry`** — Static plugin + template catalog (GitHub Pages)
- **`workflow-plugin-*`** — External plugins (auth, broker, discord, payments, dnd, worldsim, etc.)
- **`workflow-scenarios`** — Docker-based integration test scenarios
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ jobs:
- name: Build example runner binary
run: |
cd example
go build -o workflow-example ./...
go build -o workflow-example .

- name: Smoke test — run each config with timeout
run: |
Expand Down
8 changes: 8 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Agent Instructions

- Read `docs/AGENT_GUIDE.md` and `docs/REPO_LAYOUT.md` before broad changes.
- Use `GOWORK=off` for Go commands in this multi-repo workspace.
- Keep committed examples under `example/`; do not add root `examples/`,
`test-*`, or scratch app directories.
- Do not revert unrelated user changes. Use clean worktrees for larger tasks.
- Update docs and tests with behavior, CLI, config, or layout changes.
107 changes: 17 additions & 90 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -1,103 +1,30 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Short repo-local guidance for Claude Code. Detailed guidance lives in
`docs/AGENT_GUIDE.md`; layout rules live in `docs/REPO_LAYOUT.md`.

## Project Overview
## Must Follow

Configuration-driven workflow orchestration engine built in Go on the [modular](https://github.com/CrisisTextLine/modular) framework. Turns YAML configs into running applications — API servers, event pipelines, state machines, and more.
- Use `GOWORK=off` for Go commands in this multi-repo workspace.
- Prefer focused tests first, then broaden based on risk.
- Keep committed examples under `example/`; do not add root `examples/`,
`test-*`, or scratch app directories.
- Do not revert unrelated user changes.
- Update docs with behavior, CLI, config, or layout changes.

## Build & Run

If a `go.work` file in a parent directory links this repo into a multi-repo
workspace (common for GoCodeAlone contributors), prefix commands with
`GOWORK=off` so the build resolves against this repo's own `go.mod`:
## Useful Commands

```sh
# Build the server
GOWORK=off go build -o server ./cmd/server
./server -config example/api-server-config.yaml

# Build the CLI
GOWORK=off go build -o wfctl ./cmd/wfctl
./wfctl validate example/api-server-config.yaml

# Run tests
GOWORK=off go test ./...
GOWORK=off go test -race ./...

# UI development
cd ui && npm install && npm run dev

# Lint
go fmt ./...
GOWORK=off golangci-lint run
make build-wfctl
make build-examples
make test-configs
```

(When developing this repo standalone, `GOWORK=off` is redundant but harmless.)

## Project Structure

- `cmd/server/` — Server binary entry point
- `cmd/wfctl/` — CLI tool (validate, inspect, deploy, api extract, etc.)
- `config/` — YAML config structs
- `module/` — All module and pipeline step implementations
- `handlers/` — Workflow handler types (HTTP, Messaging, StateMachine, Scheduler, Integration)
- `plugins/` — Built-in engine plugins (auth, storage, pipeline-steps, etc.)
- `plugin/` — Plugin SDK (EnginePlugin interface, factories, hooks)
- `schema/` — JSON Schema generation for config validation
- `dynamic/` — Yaegi hot-reload system
- `ai/` — AI integration (Anthropic Claude, GitHub Copilot)
- `ui/` — React + ReactFlow visual builder (Vite, TypeScript)
- `example/` — Example YAML configs with companion .md docs
- `deploy/` — Deployment configs (Docker, Kubernetes/Helm, OpenTofu/AWS)
- `docs/` — Documentation (tutorials, ADRs, API reference)

## Key Conventions

- Module implementations live in `module/` with the naming pattern `module/<type>.go`
- Pipeline steps follow `module/pipeline_step_<name>.go`
- Template functions are registered in `module/pipeline_template.go` via `templateFuncMap()`
- Module factories are registered in `engine.go` `BuildFromConfig()`
- Plugin step/module factories are registered in `plugins/<name>/plugin.go`
- wfctl commands each have their own file in `cmd/wfctl/<command>.go`
- Tests follow standard Go conventions: `*_test.go` alongside source files

## Documentation Maintenance

**When adding new functionality, update the corresponding documentation:**

| Change | Update |
|--------|--------|
| New module type | `DOCUMENTATION.md` module table, `engine.go` factory registration |
| New pipeline step | `DOCUMENTATION.md` step table, register in plugin or engine |
| New template function | `DOCUMENTATION.md` template functions section, add to `templateFuncMap()` |
| New wfctl command | `docs/WFCTL.md` command reference, update `main.go` usage() |
| New trigger type | `DOCUMENTATION.md` trigger types section |
| Config format change | `DOCUMENTATION.md` configuration section |

## Common Tasks

### Adding a New Module Type
1. Create `module/<type>.go` implementing `modular.Module`
2. Register factory in `engine.go` `BuildFromConfig()` or in a plugin's `ModuleFactories()`
3. Add schema in the plugin's `ModuleSchemas()` or inline
4. Add example YAML in `example/`
5. Update `DOCUMENTATION.md`

### Adding a New Pipeline Step
1. Create `module/pipeline_step_<name>.go` implementing the step interface
2. Register in `plugins/pipelinesteps/plugin.go` `StepFactories()`
3. Update `DOCUMENTATION.md`

### Adding a Template Function
1. Add to `templateFuncMap()` in `module/pipeline_template.go`
2. Add tests in `module/pipeline_template_test.go`
3. Update `DOCUMENTATION.md` template functions section

## Links

- [Full Documentation](DOCUMENTATION.md)
- [CLI Reference](docs/WFCTL.md)
- [Deployment Guide](deploy/README.md)
- [Tutorials](docs/tutorials/)
- [Go Package Docs](https://pkg.go.dev/github.com/GoCodeAlone/workflow)
- `docs/AGENT_GUIDE.md`
- `docs/REPO_LAYOUT.md`
- `docs/WFCTL.md`
- `DOCUMENTATION.md`
19 changes: 3 additions & 16 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,9 @@ npm test

### Project Structure

```
cmd/server/ Server binary entry point
config/ YAML config structs
module/ 48 built-in module implementations
handlers/ 5 workflow handler types
dynamic/ Yaegi-based hot-reload system
ai/ AI integration (llm/, copilot/)
plugin/ Plugin registry, SDK, community validator
schema/ JSON Schema generation and validation
middleware/ HTTP middleware (validation, rate limiting)
audit/ Structured audit logging
ui/ React + ReactFlow visual builder
example/ YAML configs and application examples
mock/ Test helpers
docs/ API docs, tutorials, ADRs
```
See [Repository Layout](docs/REPO_LAYOUT.md) for the authoritative directory
map. Committed examples belong under `example/`; do not add root-level
`examples/`, `test-*`, or scratch generated app directories.

## How to Contribute

Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ install-hooks:

# Build example binary
build-examples:
cd example && go build -o workflow-example ./...
cd example && go build -o workflow-example .

# Validate all example configs load without error
test-configs:
Expand Down
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,9 @@ The workflow engine has a [registry of 51 public plugins](https://github.com/GoC

See the [Plugin Authoring Guide](docs/PLUGIN_AUTHORING.md) to build your own.

For repository layout and where to place examples, fixtures, and generated
scaffolds, see [Repository Layout](docs/REPO_LAYOUT.md).

## Quick Start

### Requirements
Expand Down
Loading
Loading