{"owner":"dkron-io","repo":"dkron","hasSkills":true,"totalSkillsCount":11,"totalTokensCount":4025,"categories":["anthropic-skill","root-instruction"],"hasMcp":false,"mcpConfig":null,"found":["website/versioned_docs/version-v3/usage/plugins/_category_.json","website/docs/usage/plugins/develop.md","website/docs/usage/plugins/_category_.json","AGENTS.md","website/docs/usage/plugins/index.md","website/versioned_docs/version-v2/usage/plugins/develop.md","website/versioned_docs/version-v1/usage/plugins/_index.md","website/versioned_docs/version-v3/usage/plugins/index.md","website/versioned_docs/version-v2/usage/plugins/_index.md","website/versioned_docs/version-v1/usage/plugins/develop.md","website/versioned_docs/version-v3/usage/plugins/develop.md"],"skills":{"website/versioned_docs/version-v3/usage/plugins/_category_.json":"{\n  \"label\": \"Plugins\"\n}\n","website/docs/usage/plugins/develop.md":"---\ntitle: Developing plugins\nweight: 99\n---\n\n## Developing a Plugin\n\n:::warning Advanced topic!\nPlugin development is a highly advanced topic, and is not required knowledge for day-to-day usage. If you don't plan on writing any plugins, we recommend not reading the following section of the documentation.\n:::\n\nDeveloping a plugin is simple. The only knowledge necessary to write a plugin is basic command-line skills and basic knowledge of the Go programming language.\n\nNote: A common pitfall is not properly setting up a `$GOPATH`. This can lead to strange errors. You can read more about this here to familiarize yourself.\n\nCreate a new Go project somewhere in your `$GOPATH`. If you're a GitHub user, we recommend creating the project in the directory `$GOPATH/src/github.com/USERNAME/dkron-NAME-TYPE`, where `USERNAME` is your GitHub username and `NAME` is the name of the plugin you're developing. This structure is what Go expects and simplifies things down the road.\n\nWith the directory made, create a main.go file. This project will be a binary so the package is \"main\":\n\n```go\npackage main\n\nimport (\n\t\"github.com/distribworks/dkron/v3/plugin\"\n)\n\nfunc main() {\n\tplugin.Serve(&plugin.ServeOpts{\n\t\tProcessor: new(MyPlugin),\n\t})\n}\n```\n\nAnd that's basically it! You'll have to change the argument given to plugin.Serve to be your actual plugin, but that is the only change you'll have to make. The argument should be a structure implementing one of the plugin interfaces (depending on what sort of plugin you're creating).\n\nDkron plugins must follow a very specific naming convention of `dkron-TYPE-NAME`. For example, `dkron-processor-files`, which tells Dkron that the plugin is a processor that can be referenced as \"files\".\n","website/docs/usage/plugins/_category_.json":"{\n  \"label\": \"Plugins\"\n}\n","AGENTS.md":"# AGENTS instructions\n\nThis file provides guidance to agents when working with code in this repository.\n\n## Project Overview\n\nDkron is a distributed, fault-tolerant job scheduling system (distributed cron) written in Go. It uses:\n- **Raft protocol** (HashiCorp Raft) for consensus and leader election\n- **Serf** (HashiCorp) for cluster membership and failure detection via gossip protocol\n- **BuntDB** for embedded storage\n- **gRPC** for inter-node communication\n- **Gin** for HTTP/REST API\n- **React Admin** for the web UI\n\nThe system is inspired by Google's \"Reliable Cron across the Planet\" whitepaper and Airbnb's Chronos.\n\n## Development Commands\n\n### Building\n```bash\n# Build the main binary (requires UI to be built first)\nmake main\n\n# Build main binary manually\ngo build main.go\n\n# Install built-in plugins (executors and processors)\nGOBIN=`pwd` go install ./builtin/...\n\n# Clean build artifacts\nmake clean\n```\n\n### Testing\n```bash\n# Run full test suite in Docker\nmake test\n\n# Run tests locally\nmake localtest\n# Or directly:\ngo test -v ./...\n\n# Run specific test\ngo test -v ./dkron -run TestJobName\n```\n\n### Frontend Development\n```bash\n# Install dependencies (uses Bun)\ncd ui && bun install\n\n# Start development server\ncd ui && npm start\n\n# Build UI for production (outputs to dkron/ui-dist)\ncd ui && yarn build --out-dir ../dkron/ui-dist\n# Or use make:\nmake ui\n```\n\n### Docker Development\n```bash\n# Start development cluster with live reload\ndocker compose -f docker-compose.dev.yml up\n\n# Start production-like cluster\ndocker compose up -d\n\n# Scale the cluster\ndocker compose up -d --scale dkron-server=4\ndocker compose up -d --scale dkron-agent=10\n\n# Access UI at http://localhost:8080/ui\n```\n\n### Protocol Buffers\n```bash\n# Generate Go code from proto files\nmake proto\n# Or manually:\nprotoc -I proto/ --go_out=types --go_opt=paths=source_relative \\\n  --go-grpc_out=types --go-grpc_opt=paths=source_relative proto/dkron.proto\n```\n\n### Code Generation\n```bash\n# Generate API client from OpenAPI spec\nmake client\n```\n\n## Architecture\n\n### Core Components\n\n**Agent** (`dkron/agent.go`)\n- Main orchestrator that combines all subsystems\n- Manages both server (Raft leader/follower) and agent (execution) roles\n- Contains: Serf cluster, Raft consensus, gRPC server/client, HTTP API, scheduler, storage, plugins\n\n**Storage** (`dkron/store.go`)\n- Interface: `Storage` defines operations (Get/SetJob, Get/SetExecution, etc.)\n- Implementation: `Store` uses BuntDB (embedded key-value store)\n- Stores jobs and executions with max 100 executions per job\n- Key prefixes: `jobs/` and `executions/`\n\n**Leader Election** (`dkron/leader.go`)\n- Raft-based leader election\n- Only the leader schedules jobs (prevents duplicate executions)\n- Leader runs the `Scheduler` which manages cron timers\n\n**Job Scheduling** (`dkron/scheduler.go`, `dkron/job.go`)\n- Cron-based scheduling using `robfig/cron/v3`\n- Extended cron syntax support via `extcron/` package\n- Jobs can have parent-child dependencies\n- Concurrency policies: `allow` or `forbid`\n- Hash symbol (`~`) in schedules is replaced with hash of job name for distribution\n\n**Execution** (`dkron/run.go`, `dkron/execution.go`)\n- Leader determines target nodes based on job tags\n- Nodes execute jobs via executor plugins\n- Results streamed back to leader via gRPC\n- Execution status: success, failed, running, partially_failed\n\n**Cluster Communication**\n- `dkron/serf.go`: Serf for membership, failure detection, and event propagation\n- `dkron/grpc.go`: gRPC server for job execution coordination\n- `dkron/grpc_client.go`: gRPC client for communicating with other nodes\n- `dkron/api.go`: REST API using Gin framework\n\n**Plugin System** (`plugin/`)\n- Two plugin types: **Executors** (run jobs) and **Processors** (process outputs)\n- Uses HashiCorp go-plugin for RPC-based plugins\n- Built-in executors: shell, http, grpc, kafka, nats, rabbitmq, gcppubsub\n- Built-in processors: log, files, syslog, fluent\n- Plugins live in `builtin/bins/`\n\n### Key Data Structures\n\n**Job** (`dkron/job.go`)\n- Name (unique ID), Schedule (cron expression), Timezone\n- Executor and ExecutorConfig\n- Parent job for dependencies\n- Tags for targeting specific nodes\n- Concurrency policy, retries, timeout\n\n**Execution** (`dkron/execution.go`)\n- Links to Job, records start/finish times\n- NodeName (where it ran), Output, Success/Error status\n\n### Configuration\n\nConfig loaded via Viper from:\n- Config files: `/etc/dkron/dkron.yaml`, `$HOME/.dkron/dkron.yaml`, `./config/dkron.yaml`\n- Environment variables: `DKRON_*` (e.g., `DKRON_NODE_NAME`)\n- CLI flags (via Cobra in `cmd/`)\n\nKey settings: `node-name`, `bind-addr`, `server`, `bootstrap-expect`, `data-dir`, `tags`\n\n### Module Structure\n\n- `cmd/`: CLI commands (agent, keygen, version, etc.)\n- `dkron/`: Core library (agent, storage, API, scheduler, clustering)\n- `builtin/bins/`: Built-in executor and processor plugin binaries\n- `plugin/`: Plugin interfaces and serving logic\n- `proto/`, `types/`: Protobuf definitions and generated code\n- `extcron/`: Extended cron parser supporting simple syntax\n- `ntime/`: Nullable time type\n- `logging/`: Custom logging setup\n- `client/`: Auto-generated API client\n- `ui/`: React Admin frontend (TypeScript/Vite)\n\n## Code Patterns\n\n### Working with Storage\nAlways use the `Storage` interface. Wrap operations in context and check for `buntdb.ErrNotFound` when getting jobs/executions.\n\n### Leader Operations\nCheck `a.IsLeader()` before performing leader-only operations like job scheduling or applying Raft logs.\n\n### gRPC Communication\nUse `GRPCClient.ExecutionDone()` to report execution results to the leader. The leader uses `AgentRun()` to trigger job execution on target nodes.\n\n### Plugin Development\nImplement `plugin.Executor` or `plugin.Processor` interfaces. Use `plugin.Serve()` to serve the plugin. See existing plugins in `builtin/bins/` for examples.\n\n## Important Notes\n\n- The system uses both Raft (for consistency) and Serf (for membership)\n- Jobs are only scheduled by the leader to avoid duplicates\n- Executions are tracked with a sliding window (max 100 per job)\n- The UI is embedded in the binary via Go embed (`dkron/ui-dist`)\n- Plugin communication uses HashiCorp's go-plugin over gRPC\n- Module path is `github.com/distribworks/dkron/v4` (note the v4 major version)\n","website/docs/usage/plugins/index.md":"# Plugins\n\n## Intro\n\nPlugins in Dkron allow you to add funcionality that integrates with the workflow of the job execution in Dkron. It's a powerful system that allows you to extend and adapt Dkron to your special needs.\n\nThis page documents the basics of how the plugin system in Dkron works, and how to setup a basic development environment for plugin development if you're writing a Dkron plugin.\n\n## How it Works\n\nDkron execution execution processors are provided via plugins. Each plugin exposes functionality for modifying the execution. Plugins are executed as a separate process and communicate with the main Dkron binary over an RPC interface.\n\nThe code within the binaries must adhere to certain interfaces. The network communication and RPC is handled automatically by higher-level libraries. The exact interface to implement is documented in its respective documentation section.\n\n## Installing a Plugin\n\nDkron searches for plugins at startup, to install a plugin just drop the binary in one of the following locations:\n\n1. /etc/dkron/plugins\n2. Dkron executable directory\n","website/versioned_docs/version-v2/usage/plugins/develop.md":"---\ntitle: Developing plugins\nweight: 99\n---\n\n## Developing a Plugin\n\n:::warning\n**Advanced topic!** Plugin development is a highly advanced topic, and is not required knowledge for day-to-day usage. If you don't plan on writing any plugins, we recommend not reading the following section of the documentation.\n:::\n\nDeveloping a plugin is simple. The only knowledge necessary to write a plugin is basic command-line skills and basic knowledge of the Go programming language.\n\nNote: A common pitfall is not properly setting up a `$GOPATH`. This can lead to strange errors. You can read more about this here to familiarize yourself.\n\nCreate a new Go project somewhere in your `$GOPATH`. If you're a GitHub user, we recommend creating the project in the directory `$GOPATH/src/github.com/USERNAME/dkron-NAME-TYPE`, where `USERNAME` is your GitHub username and `NAME` is the name of the plugin you're developing. This structure is what Go expects and simplifies things down the road.\n\nWith the directory made, create a main.go file. This project will be a binary so the package is \"main\":\n\n```go\npackage main\n\nimport (\n\t\"github.com/distribworks/dkron/v3/plugin\"\n)\n\nfunc main() {\n\tplugin.Serve(&plugin.ServeOpts{\n\t\tProcessor: new(MyPlugin),\n\t})\n}\n```\n\nAnd that's basically it! You'll have to change the argument given to plugin.Serve to be your actual plugin, but that is the only change you'll have to make. The argument should be a structure implementing one of the plugin interfaces (depending on what sort of plugin you're creating).\n\nDkron plugins must follow a very specific naming convention of `dkron-TYPE-NAME`. For example, `dkron-processor-files`, which tells Dkron that the plugin is a processor that can be referenced as \"files\".\n","website/versioned_docs/version-v1/usage/plugins/_index.md":"---\ntitle: Plugins\n---\n\n## Intro\n\nPlugins in Dkron allow you to add funcionality that integrates with the workflow of the job execution in Dkron. It's a powerful system that allows you to extend and adapt Dkron to your special needs.\n\nThis page documents the basics of how the plugin system in Dkron works, and how to setup a basic development environment for plugin development if you're writing a Dkron plugin.\n\n## How it Works\n\nDkron execution execution processors are provided via plugins. Each plugin exposes functionality for modifying the execution. Plugins are executed as a separate process and communicate with the main Dkron binary over an RPC interface.\n\nThe code within the binaries must adhere to certain interfaces. The network communication and RPC is handled automatically by higher-level libraries. The exact interface to implement is documented in its respective documentation section.\n\n## Installing a Plugin\n\nDkron searches for plugins at startup, to install a plugin just drop the binary in one of the following locations:\n\n1. /etc/dkron/plugins\n2. Dkron executable directory\n\n{{% children  %}}\n","website/versioned_docs/version-v3/usage/plugins/index.md":"# Plugins\n\n## Intro\n\nPlugins in Dkron allow you to add funcionality that integrates with the workflow of the job execution in Dkron. It's a powerful system that allows you to extend and adapt Dkron to your special needs.\n\nThis page documents the basics of how the plugin system in Dkron works, and how to setup a basic development environment for plugin development if you're writing a Dkron plugin.\n\n## How it Works\n\nDkron execution execution processors are provided via plugins. Each plugin exposes functionality for modifying the execution. Plugins are executed as a separate process and communicate with the main Dkron binary over an RPC interface.\n\nThe code within the binaries must adhere to certain interfaces. The network communication and RPC is handled automatically by higher-level libraries. The exact interface to implement is documented in its respective documentation section.\n\n## Installing a Plugin\n\nDkron searches for plugins at startup, to install a plugin just drop the binary in one of the following locations:\n\n1. /etc/dkron/plugins\n2. Dkron executable directory\n","website/versioned_docs/version-v2/usage/plugins/_index.md":"---\ntitle: Plugins\n---\n\n## Intro\n\nPlugins in Dkron allow you to add funcionality that integrates with the workflow of the job execution in Dkron. It's a powerful system that allows you to extend and adapt Dkron to your special needs.\n\nThis page documents the basics of how the plugin system in Dkron works, and how to setup a basic development environment for plugin development if you're writing a Dkron plugin.\n\n## How it Works\n\nDkron execution execution processors are provided via plugins. Each plugin exposes functionality for modifying the execution. Plugins are executed as a separate process and communicate with the main Dkron binary over an RPC interface.\n\nThe code within the binaries must adhere to certain interfaces. The network communication and RPC is handled automatically by higher-level libraries. The exact interface to implement is documented in its respective documentation section.\n\n## Installing a Plugin\n\nDkron searches for plugins at startup, to install a plugin just drop the binary in one of the following locations:\n\n1. /etc/dkron/plugins\n2. Dkron executable directory\n\n{{% children  %}}\n","website/versioned_docs/version-v1/usage/plugins/develop.md":"---\ntitle: Developing plugins\nweight: 99\n---\n\n## Developing a Plugin\n\n:::warning\n**Advanced topic!** Plugin development is a highly advanced topic, and is not required knowledge for day-to-day usage. If you don't plan on writing any plugins, we recommend not reading the following section of the documentation.\n:::\n\nDeveloping a plugin is simple. The only knowledge necessary to write a plugin is basic command-line skills and basic knowledge of the Go programming language.\n\nNote: A common pitfall is not properly setting up a `$GOPATH`. This can lead to strange errors. You can read more about this here to familiarize yourself.\n\nCreate a new Go project somewhere in your `$GOPATH`. If you're a GitHub user, we recommend creating the project in the directory `$GOPATH/src/github.com/USERNAME/dkron-NAME-TYPE`, where `USERNAME` is your GitHub username and `NAME` is the name of the plugin you're developing. This structure is what Go expects and simplifies things down the road.\n\nWith the directory made, create a main.go file. This project will be a binary so the package is \"main\":\n\n```go\npackage main\n\nimport (\n\t\"github.com/distribworks/dkron/plugin\"\n)\n\nfunc main() {\n\tplugin.Serve(&plugin.ServeOpts{\n\t\tProcessor: new(MyPlugin),\n\t})\n}\n```\n\nAnd that's basically it! You'll have to change the argument given to plugin.Serve to be your actual plugin, but that is the only change you'll have to make. The argument should be a structure implementing one of the plugin interfaces (depending on what sort of plugin you're creating).\n\nDkron plugins must follow a very specific naming convention of `dkron-TYPE-NAME`. For example, `dkron-processor-files`, which tells Dkron that the plugin is a processor that can be referenced as \"files\".\n","website/versioned_docs/version-v3/usage/plugins/develop.md":"---\ntitle: Developing plugins\nweight: 99\n---\n\n## Developing a Plugin\n\n:::warning Advanced topic!\nPlugin development is a highly advanced topic, and is not required knowledge for day-to-day usage. If you don't plan on writing any plugins, we recommend not reading the following section of the documentation.\n:::\n\nDeveloping a plugin is simple. The only knowledge necessary to write a plugin is basic command-line skills and basic knowledge of the Go programming language.\n\nNote: A common pitfall is not properly setting up a `$GOPATH`. This can lead to strange errors. You can read more about this here to familiarize yourself.\n\nCreate a new Go project somewhere in your `$GOPATH`. If you're a GitHub user, we recommend creating the project in the directory `$GOPATH/src/github.com/USERNAME/dkron-NAME-TYPE`, where `USERNAME` is your GitHub username and `NAME` is the name of the plugin you're developing. This structure is what Go expects and simplifies things down the road.\n\nWith the directory made, create a main.go file. This project will be a binary so the package is \"main\":\n\n```go\npackage main\n\nimport (\n\t\"github.com/distribworks/dkron/v3/plugin\"\n)\n\nfunc main() {\n\tplugin.Serve(&plugin.ServeOpts{\n\t\tProcessor: new(MyPlugin),\n\t})\n}\n```\n\nAnd that's basically it! You'll have to change the argument given to plugin.Serve to be your actual plugin, but that is the only change you'll have to make. The argument should be a structure implementing one of the plugin interfaces (depending on what sort of plugin you're creating).\n\nDkron plugins must follow a very specific naming convention of `dkron-TYPE-NAME`. For example, `dkron-processor-files`, which tells Dkron that the plugin is a processor that can be referenced as \"files\".\n"},"files":{"website/versioned_docs/version-v3/usage/plugins/_category_.json":"{\n  \"label\": \"Plugins\"\n}\n","website/docs/usage/plugins/develop.md":"---\ntitle: Developing plugins\nweight: 99\n---\n\n## Developing a Plugin\n\n:::warning Advanced topic!\nPlugin development is a highly advanced topic, and is not required knowledge for day-to-day usage. If you don't plan on writing any plugins, we recommend not reading the following section of the documentation.\n:::\n\nDeveloping a plugin is simple. The only knowledge necessary to write a plugin is basic command-line skills and basic knowledge of the Go programming language.\n\nNote: A common pitfall is not properly setting up a `$GOPATH`. This can lead to strange errors. You can read more about this here to familiarize yourself.\n\nCreate a new Go project somewhere in your `$GOPATH`. If you're a GitHub user, we recommend creating the project in the directory `$GOPATH/src/github.com/USERNAME/dkron-NAME-TYPE`, where `USERNAME` is your GitHub username and `NAME` is the name of the plugin you're developing. This structure is what Go expects and simplifies things down the road.\n\nWith the directory made, create a main.go file. This project will be a binary so the package is \"main\":\n\n```go\npackage main\n\nimport (\n\t\"github.com/distribworks/dkron/v3/plugin\"\n)\n\nfunc main() {\n\tplugin.Serve(&plugin.ServeOpts{\n\t\tProcessor: new(MyPlugin),\n\t})\n}\n```\n\nAnd that's basically it! You'll have to change the argument given to plugin.Serve to be your actual plugin, but that is the only change you'll have to make. The argument should be a structure implementing one of the plugin interfaces (depending on what sort of plugin you're creating).\n\nDkron plugins must follow a very specific naming convention of `dkron-TYPE-NAME`. For example, `dkron-processor-files`, which tells Dkron that the plugin is a processor that can be referenced as \"files\".\n","website/docs/usage/plugins/_category_.json":"{\n  \"label\": \"Plugins\"\n}\n","AGENTS.md":"# AGENTS instructions\n\nThis file provides guidance to agents when working with code in this repository.\n\n## Project Overview\n\nDkron is a distributed, fault-tolerant job scheduling system (distributed cron) written in Go. It uses:\n- **Raft protocol** (HashiCorp Raft) for consensus and leader election\n- **Serf** (HashiCorp) for cluster membership and failure detection via gossip protocol\n- **BuntDB** for embedded storage\n- **gRPC** for inter-node communication\n- **Gin** for HTTP/REST API\n- **React Admin** for the web UI\n\nThe system is inspired by Google's \"Reliable Cron across the Planet\" whitepaper and Airbnb's Chronos.\n\n## Development Commands\n\n### Building\n```bash\n# Build the main binary (requires UI to be built first)\nmake main\n\n# Build main binary manually\ngo build main.go\n\n# Install built-in plugins (executors and processors)\nGOBIN=`pwd` go install ./builtin/...\n\n# Clean build artifacts\nmake clean\n```\n\n### Testing\n```bash\n# Run full test suite in Docker\nmake test\n\n# Run tests locally\nmake localtest\n# Or directly:\ngo test -v ./...\n\n# Run specific test\ngo test -v ./dkron -run TestJobName\n```\n\n### Frontend Development\n```bash\n# Install dependencies (uses Bun)\ncd ui && bun install\n\n# Start development server\ncd ui && npm start\n\n# Build UI for production (outputs to dkron/ui-dist)\ncd ui && yarn build --out-dir ../dkron/ui-dist\n# Or use make:\nmake ui\n```\n\n### Docker Development\n```bash\n# Start development cluster with live reload\ndocker compose -f docker-compose.dev.yml up\n\n# Start production-like cluster\ndocker compose up -d\n\n# Scale the cluster\ndocker compose up -d --scale dkron-server=4\ndocker compose up -d --scale dkron-agent=10\n\n# Access UI at http://localhost:8080/ui\n```\n\n### Protocol Buffers\n```bash\n# Generate Go code from proto files\nmake proto\n# Or manually:\nprotoc -I proto/ --go_out=types --go_opt=paths=source_relative \\\n  --go-grpc_out=types --go-grpc_opt=paths=source_relative proto/dkron.proto\n```\n\n### Code Generation\n```bash\n# Generate API client from OpenAPI spec\nmake client\n```\n\n## Architecture\n\n### Core Components\n\n**Agent** (`dkron/agent.go`)\n- Main orchestrator that combines all subsystems\n- Manages both server (Raft leader/follower) and agent (execution) roles\n- Contains: Serf cluster, Raft consensus, gRPC server/client, HTTP API, scheduler, storage, plugins\n\n**Storage** (`dkron/store.go`)\n- Interface: `Storage` defines operations (Get/SetJob, Get/SetExecution, etc.)\n- Implementation: `Store` uses BuntDB (embedded key-value store)\n- Stores jobs and executions with max 100 executions per job\n- Key prefixes: `jobs/` and `executions/`\n\n**Leader Election** (`dkron/leader.go`)\n- Raft-based leader election\n- Only the leader schedules jobs (prevents duplicate executions)\n- Leader runs the `Scheduler` which manages cron timers\n\n**Job Scheduling** (`dkron/scheduler.go`, `dkron/job.go`)\n- Cron-based scheduling using `robfig/cron/v3`\n- Extended cron syntax support via `extcron/` package\n- Jobs can have parent-child dependencies\n- Concurrency policies: `allow` or `forbid`\n- Hash symbol (`~`) in schedules is replaced with hash of job name for distribution\n\n**Execution** (`dkron/run.go`, `dkron/execution.go`)\n- Leader determines target nodes based on job tags\n- Nodes execute jobs via executor plugins\n- Results streamed back to leader via gRPC\n- Execution status: success, failed, running, partially_failed\n\n**Cluster Communication**\n- `dkron/serf.go`: Serf for membership, failure detection, and event propagation\n- `dkron/grpc.go`: gRPC server for job execution coordination\n- `dkron/grpc_client.go`: gRPC client for communicating with other nodes\n- `dkron/api.go`: REST API using Gin framework\n\n**Plugin System** (`plugin/`)\n- Two plugin types: **Executors** (run jobs) and **Processors** (process outputs)\n- Uses HashiCorp go-plugin for RPC-based plugins\n- Built-in executors: shell, http, grpc, kafka, nats, rabbitmq, gcppubsub\n- Built-in processors: log, files, syslog, fluent\n- Plugins live in `builtin/bins/`\n\n### Key Data Structures\n\n**Job** (`dkron/job.go`)\n- Name (unique ID), Schedule (cron expression), Timezone\n- Executor and ExecutorConfig\n- Parent job for dependencies\n- Tags for targeting specific nodes\n- Concurrency policy, retries, timeout\n\n**Execution** (`dkron/execution.go`)\n- Links to Job, records start/finish times\n- NodeName (where it ran), Output, Success/Error status\n\n### Configuration\n\nConfig loaded via Viper from:\n- Config files: `/etc/dkron/dkron.yaml`, `$HOME/.dkron/dkron.yaml`, `./config/dkron.yaml`\n- Environment variables: `DKRON_*` (e.g., `DKRON_NODE_NAME`)\n- CLI flags (via Cobra in `cmd/`)\n\nKey settings: `node-name`, `bind-addr`, `server`, `bootstrap-expect`, `data-dir`, `tags`\n\n### Module Structure\n\n- `cmd/`: CLI commands (agent, keygen, version, etc.)\n- `dkron/`: Core library (agent, storage, API, scheduler, clustering)\n- `builtin/bins/`: Built-in executor and processor plugin binaries\n- `plugin/`: Plugin interfaces and serving logic\n- `proto/`, `types/`: Protobuf definitions and generated code\n- `extcron/`: Extended cron parser supporting simple syntax\n- `ntime/`: Nullable time type\n- `logging/`: Custom logging setup\n- `client/`: Auto-generated API client\n- `ui/`: React Admin frontend (TypeScript/Vite)\n\n## Code Patterns\n\n### Working with Storage\nAlways use the `Storage` interface. Wrap operations in context and check for `buntdb.ErrNotFound` when getting jobs/executions.\n\n### Leader Operations\nCheck `a.IsLeader()` before performing leader-only operations like job scheduling or applying Raft logs.\n\n### gRPC Communication\nUse `GRPCClient.ExecutionDone()` to report execution results to the leader. The leader uses `AgentRun()` to trigger job execution on target nodes.\n\n### Plugin Development\nImplement `plugin.Executor` or `plugin.Processor` interfaces. Use `plugin.Serve()` to serve the plugin. See existing plugins in `builtin/bins/` for examples.\n\n## Important Notes\n\n- The system uses both Raft (for consistency) and Serf (for membership)\n- Jobs are only scheduled by the leader to avoid duplicates\n- Executions are tracked with a sliding window (max 100 per job)\n- The UI is embedded in the binary via Go embed (`dkron/ui-dist`)\n- Plugin communication uses HashiCorp's go-plugin over gRPC\n- Module path is `github.com/distribworks/dkron/v4` (note the v4 major version)\n","website/docs/usage/plugins/index.md":"# Plugins\n\n## Intro\n\nPlugins in Dkron allow you to add funcionality that integrates with the workflow of the job execution in Dkron. It's a powerful system that allows you to extend and adapt Dkron to your special needs.\n\nThis page documents the basics of how the plugin system in Dkron works, and how to setup a basic development environment for plugin development if you're writing a Dkron plugin.\n\n## How it Works\n\nDkron execution execution processors are provided via plugins. Each plugin exposes functionality for modifying the execution. Plugins are executed as a separate process and communicate with the main Dkron binary over an RPC interface.\n\nThe code within the binaries must adhere to certain interfaces. The network communication and RPC is handled automatically by higher-level libraries. The exact interface to implement is documented in its respective documentation section.\n\n## Installing a Plugin\n\nDkron searches for plugins at startup, to install a plugin just drop the binary in one of the following locations:\n\n1. /etc/dkron/plugins\n2. Dkron executable directory\n","website/versioned_docs/version-v2/usage/plugins/develop.md":"---\ntitle: Developing plugins\nweight: 99\n---\n\n## Developing a Plugin\n\n:::warning\n**Advanced topic!** Plugin development is a highly advanced topic, and is not required knowledge for day-to-day usage. If you don't plan on writing any plugins, we recommend not reading the following section of the documentation.\n:::\n\nDeveloping a plugin is simple. The only knowledge necessary to write a plugin is basic command-line skills and basic knowledge of the Go programming language.\n\nNote: A common pitfall is not properly setting up a `$GOPATH`. This can lead to strange errors. You can read more about this here to familiarize yourself.\n\nCreate a new Go project somewhere in your `$GOPATH`. If you're a GitHub user, we recommend creating the project in the directory `$GOPATH/src/github.com/USERNAME/dkron-NAME-TYPE`, where `USERNAME` is your GitHub username and `NAME` is the name of the plugin you're developing. This structure is what Go expects and simplifies things down the road.\n\nWith the directory made, create a main.go file. This project will be a binary so the package is \"main\":\n\n```go\npackage main\n\nimport (\n\t\"github.com/distribworks/dkron/v3/plugin\"\n)\n\nfunc main() {\n\tplugin.Serve(&plugin.ServeOpts{\n\t\tProcessor: new(MyPlugin),\n\t})\n}\n```\n\nAnd that's basically it! You'll have to change the argument given to plugin.Serve to be your actual plugin, but that is the only change you'll have to make. The argument should be a structure implementing one of the plugin interfaces (depending on what sort of plugin you're creating).\n\nDkron plugins must follow a very specific naming convention of `dkron-TYPE-NAME`. For example, `dkron-processor-files`, which tells Dkron that the plugin is a processor that can be referenced as \"files\".\n","website/versioned_docs/version-v1/usage/plugins/_index.md":"---\ntitle: Plugins\n---\n\n## Intro\n\nPlugins in Dkron allow you to add funcionality that integrates with the workflow of the job execution in Dkron. It's a powerful system that allows you to extend and adapt Dkron to your special needs.\n\nThis page documents the basics of how the plugin system in Dkron works, and how to setup a basic development environment for plugin development if you're writing a Dkron plugin.\n\n## How it Works\n\nDkron execution execution processors are provided via plugins. Each plugin exposes functionality for modifying the execution. Plugins are executed as a separate process and communicate with the main Dkron binary over an RPC interface.\n\nThe code within the binaries must adhere to certain interfaces. The network communication and RPC is handled automatically by higher-level libraries. The exact interface to implement is documented in its respective documentation section.\n\n## Installing a Plugin\n\nDkron searches for plugins at startup, to install a plugin just drop the binary in one of the following locations:\n\n1. /etc/dkron/plugins\n2. Dkron executable directory\n\n{{% children  %}}\n","website/versioned_docs/version-v3/usage/plugins/index.md":"# Plugins\n\n## Intro\n\nPlugins in Dkron allow you to add funcionality that integrates with the workflow of the job execution in Dkron. It's a powerful system that allows you to extend and adapt Dkron to your special needs.\n\nThis page documents the basics of how the plugin system in Dkron works, and how to setup a basic development environment for plugin development if you're writing a Dkron plugin.\n\n## How it Works\n\nDkron execution execution processors are provided via plugins. Each plugin exposes functionality for modifying the execution. Plugins are executed as a separate process and communicate with the main Dkron binary over an RPC interface.\n\nThe code within the binaries must adhere to certain interfaces. The network communication and RPC is handled automatically by higher-level libraries. The exact interface to implement is documented in its respective documentation section.\n\n## Installing a Plugin\n\nDkron searches for plugins at startup, to install a plugin just drop the binary in one of the following locations:\n\n1. /etc/dkron/plugins\n2. Dkron executable directory\n","website/versioned_docs/version-v2/usage/plugins/_index.md":"---\ntitle: Plugins\n---\n\n## Intro\n\nPlugins in Dkron allow you to add funcionality that integrates with the workflow of the job execution in Dkron. It's a powerful system that allows you to extend and adapt Dkron to your special needs.\n\nThis page documents the basics of how the plugin system in Dkron works, and how to setup a basic development environment for plugin development if you're writing a Dkron plugin.\n\n## How it Works\n\nDkron execution execution processors are provided via plugins. Each plugin exposes functionality for modifying the execution. Plugins are executed as a separate process and communicate with the main Dkron binary over an RPC interface.\n\nThe code within the binaries must adhere to certain interfaces. The network communication and RPC is handled automatically by higher-level libraries. The exact interface to implement is documented in its respective documentation section.\n\n## Installing a Plugin\n\nDkron searches for plugins at startup, to install a plugin just drop the binary in one of the following locations:\n\n1. /etc/dkron/plugins\n2. Dkron executable directory\n\n{{% children  %}}\n","website/versioned_docs/version-v1/usage/plugins/develop.md":"---\ntitle: Developing plugins\nweight: 99\n---\n\n## Developing a Plugin\n\n:::warning\n**Advanced topic!** Plugin development is a highly advanced topic, and is not required knowledge for day-to-day usage. If you don't plan on writing any plugins, we recommend not reading the following section of the documentation.\n:::\n\nDeveloping a plugin is simple. The only knowledge necessary to write a plugin is basic command-line skills and basic knowledge of the Go programming language.\n\nNote: A common pitfall is not properly setting up a `$GOPATH`. This can lead to strange errors. You can read more about this here to familiarize yourself.\n\nCreate a new Go project somewhere in your `$GOPATH`. If you're a GitHub user, we recommend creating the project in the directory `$GOPATH/src/github.com/USERNAME/dkron-NAME-TYPE`, where `USERNAME` is your GitHub username and `NAME` is the name of the plugin you're developing. This structure is what Go expects and simplifies things down the road.\n\nWith the directory made, create a main.go file. This project will be a binary so the package is \"main\":\n\n```go\npackage main\n\nimport (\n\t\"github.com/distribworks/dkron/plugin\"\n)\n\nfunc main() {\n\tplugin.Serve(&plugin.ServeOpts{\n\t\tProcessor: new(MyPlugin),\n\t})\n}\n```\n\nAnd that's basically it! You'll have to change the argument given to plugin.Serve to be your actual plugin, but that is the only change you'll have to make. The argument should be a structure implementing one of the plugin interfaces (depending on what sort of plugin you're creating).\n\nDkron plugins must follow a very specific naming convention of `dkron-TYPE-NAME`. For example, `dkron-processor-files`, which tells Dkron that the plugin is a processor that can be referenced as \"files\".\n","website/versioned_docs/version-v3/usage/plugins/develop.md":"---\ntitle: Developing plugins\nweight: 99\n---\n\n## Developing a Plugin\n\n:::warning Advanced topic!\nPlugin development is a highly advanced topic, and is not required knowledge for day-to-day usage. If you don't plan on writing any plugins, we recommend not reading the following section of the documentation.\n:::\n\nDeveloping a plugin is simple. The only knowledge necessary to write a plugin is basic command-line skills and basic knowledge of the Go programming language.\n\nNote: A common pitfall is not properly setting up a `$GOPATH`. This can lead to strange errors. You can read more about this here to familiarize yourself.\n\nCreate a new Go project somewhere in your `$GOPATH`. If you're a GitHub user, we recommend creating the project in the directory `$GOPATH/src/github.com/USERNAME/dkron-NAME-TYPE`, where `USERNAME` is your GitHub username and `NAME` is the name of the plugin you're developing. This structure is what Go expects and simplifies things down the road.\n\nWith the directory made, create a main.go file. This project will be a binary so the package is \"main\":\n\n```go\npackage main\n\nimport (\n\t\"github.com/distribworks/dkron/v3/plugin\"\n)\n\nfunc main() {\n\tplugin.Serve(&plugin.ServeOpts{\n\t\tProcessor: new(MyPlugin),\n\t})\n}\n```\n\nAnd that's basically it! You'll have to change the argument given to plugin.Serve to be your actual plugin, but that is the only change you'll have to make. The argument should be a structure implementing one of the plugin interfaces (depending on what sort of plugin you're creating).\n\nDkron plugins must follow a very specific naming convention of `dkron-TYPE-NAME`. For example, `dkron-processor-files`, which tells Dkron that the plugin is a processor that can be referenced as \"files\".\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/dkron-io/dkron/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AGENTS instructions\n\nThis file provides guidance to agents when working with code in this repository.\n\n## Project Overview\n\nDkron is a distributed, fault-tolerant job scheduling system (distributed cron) written in Go. It uses:\n- **Raft protocol** (HashiCorp Raft) for consensus and leader election\n- **Serf** (HashiCorp) for cluster membership and failure detection via gossip protocol\n- **BuntDB** for embedded storage\n- **gRPC** for inter-node communication\n- **Gin** for HTTP/REST API\n- **React Admin** for the web UI\n\nThe system is inspired by Google's \"Reliable Cron across the Planet\" whitepaper and Airbnb's Chronos.\n\n## Development Commands\n\n### Building\n```bash\n# Build the main binary (requires UI to be built first)\nmake main\n\n# Build main binary manually\ngo build main.go\n\n# Install built-in plugins (executors and processors)\nGOBIN=`pwd` go install ./builtin/...\n\n# Clean build artifacts\nmake clean\n```\n\n### Testing\n```bash\n# Run full test suite in Docker\nmake test\n\n# Run tests locally\nmake localtest\n# Or directly:\ngo test -v ./...\n\n# Run specific test\ngo test -v ./dkron -run TestJobName\n```\n\n### Frontend Development\n```bash\n# Install dependencies (uses Bun)\ncd ui && bun install\n\n# Start development server\ncd ui && npm start\n\n# Build UI for production (outputs to dkron/ui-dist)\ncd ui && yarn build --out-dir ../dkron/ui-dist\n# Or use make:\nmake ui\n```\n\n### Docker Development\n```bash\n# Start development cluster with live reload\ndocker compose -f docker-compose.dev.yml up\n\n# Start production-like cluster\ndocker compose up -d\n\n# Scale the cluster\ndocker compose up -d --scale dkron-server=4\ndocker compose up -d --scale dkron-agent=10\n\n# Access UI at http://localhost:8080/ui\n```\n\n### Protocol Buffers\n```bash\n# Generate Go code from proto files\nmake proto\n# Or manually:\nprotoc -I proto/ --go_out=types --go_opt=paths=source_relative \\\n  --go-grpc_out=types --go-grpc_opt=paths=source_relative proto/dkron.proto\n```\n\n### Code Generation\n```bash\n# Generate API client from OpenAPI spec\nmake client\n```\n\n## Architecture\n\n### Core Components\n\n**Agent** (`dkron/agent.go`)\n- Main orchestrator that combines all subsystems\n- Manages both server (Raft leader/follower) and agent (execution) roles\n- Contains: Serf cluster, Raft consensus, gRPC server/client, HTTP API, scheduler, storage, plugins\n\n**Storage** (`dkron/store.go`)\n- Interface: `Storage` defines operations (Get/SetJob, Get/SetExecution, etc.)\n- Implementation: `Store` uses BuntDB (embedded key-value store)\n- Stores jobs and executions with max 100 executions per job\n- Key prefixes: `jobs/` and `executions/`\n\n**Leader Election** (`dkron/leader.go`)\n- Raft-based leader election\n- Only the leader schedules jobs (prevents duplicate executions)\n- Leader runs the `Scheduler` which manages cron timers\n\n**Job Scheduling** (`dkron/scheduler.go`, `dkron/job.go`)\n- Cron-based scheduling using `robfig/cron/v3`\n- Extended cron syntax support via `extcron/` package\n- Jobs can have parent-child dependencies\n- Concurrency policies: `allow` or `forbid`\n- Hash symbol (`~`) in schedules is replaced with hash of job name for distribution\n\n**Execution** (`dkron/run.go`, `dkron/execution.go`)\n- Leader determines target nodes based on job tags\n- Nodes execute jobs via executor plugins\n- Results streamed back to leader via gRPC\n- Execution status: success, failed, running, partially_failed\n\n**Cluster Communication**\n- `dkron/serf.go`: Serf for membership, failure detection, and event propagation\n- `dkron/grpc.go`: gRPC server for job execution coordination\n- `dkron/grpc_client.go`: gRPC client for communicating with other nodes\n- `dkron/api.go`: REST API using Gin framework\n\n**Plugin System** (`plugin/`)\n- Two plugin types: **Executors** (run jobs) and **Processors** (process outputs)\n- Uses HashiCorp go-plugin for RPC-based plugins\n- Built-in executors: shell, http, grpc, kafka, nats, rabbitmq, gcppubsub\n- Built-in processors: log, files, syslog, fluent\n- Plugins live in `builtin/bins/`\n\n### Key Data Structures\n\n**Job** (`dkron/job.go`)\n- Name (unique ID), Schedule (cron expression), Timezone\n- Executor and ExecutorConfig\n- Parent job for dependencies\n- Tags for targeting specific nodes\n- Concurrency policy, retries, timeout\n\n**Execution** (`dkron/execution.go`)\n- Links to Job, records start/finish times\n- NodeName (where it ran), Output, Success/Error status\n\n### Configuration\n\nConfig loaded via Viper from:\n- Config files: `/etc/dkron/dkron.yaml`, `$HOME/.dkron/dkron.yaml`, `./config/dkron.yaml`\n- Environment variables: `DKRON_*` (e.g., `DKRON_NODE_NAME`)\n- CLI flags (via Cobra in `cmd/`)\n\nKey settings: `node-name`, `bind-addr`, `server`, `bootstrap-expect`, `data-dir`, `tags`\n\n### Module Structure\n\n- `cmd/`: CLI commands (agent, keygen, version, etc.)\n- `dkron/`: Core library (agent, storage, API, scheduler, clustering)\n- `builtin/bins/`: Built-in executor and processor plugin binaries\n- `plugin/`: Plugin interfaces and serving logic\n- `proto/`, `types/`: Protobuf definitions and generated code\n- `extcron/`: Extended cron parser supporting simple syntax\n- `ntime/`: Nullable time type\n- `logging/`: Custom logging setup\n- `client/`: Auto-generated API client\n- `ui/`: React Admin frontend (TypeScript/Vite)\n\n## Code Patterns\n\n### Working with Storage\nAlways use the `Storage` interface. Wrap operations in context and check for `buntdb.ErrNotFound` when getting jobs/executions.\n\n### Leader Operations\nCheck `a.IsLeader()` before performing leader-only operations like job scheduling or applying Raft logs.\n\n### gRPC Communication\nUse `GRPCClient.ExecutionDone()` to report execution results to the leader. The leader uses `AgentRun()` to trigger job execution on target nodes.\n\n### Plugin Development\nImplement `plugin.Executor` or `plugin.Processor` interfaces. Use `plugin.Serve()` to serve the plugin. See existing plugins in `builtin/bins/` for examples.\n\n## Important Notes\n\n- The system uses both Raft (for consistency) and Serf (for membership)\n- Jobs are only scheduled by the leader to avoid duplicates\n- Executions are tracked with a sliding window (max 100 per job)\n- The UI is embedded in the binary via Go embed (`dkron/ui-dist`)\n- Plugin communication uses HashiCorp's go-plugin over gRPC\n- Module path is `github.com/distribworks/dkron/v4` (note the v4 major version)\n","isInternal":false,"tokens":1573,"sizeBytes":6299},{"name":"_category_.json","path":"website/docs/usage/plugins/_category_.json","rawUrl":"https://raw.githubusercontent.com/dkron-io/dkron/HEAD/website/docs/usage/plugins/_category_.json","title":"Plugins Skill","category":"anthropic-skill","format":"json","content":"{\n  \"label\": \"Plugins\"\n}\n","frontmatter":{"label":"Plugins"},"isInternal":false,"tokens":9,"sizeBytes":25},{"name":"develop.md","path":"website/docs/usage/plugins/develop.md","rawUrl":"https://raw.githubusercontent.com/dkron-io/dkron/HEAD/website/docs/usage/plugins/develop.md","title":"Plugins Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Developing plugins\nweight: 99\n---\n\n## Developing a Plugin\n\n:::warning Advanced topic!\nPlugin development is a highly advanced topic, and is not required knowledge for day-to-day usage. If you don't plan on writing any plugins, we recommend not reading the following section of the documentation.\n:::\n\nDeveloping a plugin is simple. The only knowledge necessary to write a plugin is basic command-line skills and basic knowledge of the Go programming language.\n\nNote: A common pitfall is not properly setting up a `$GOPATH`. This can lead to strange errors. You can read more about this here to familiarize yourself.\n\nCreate a new Go project somewhere in your `$GOPATH`. If you're a GitHub user, we recommend creating the project in the directory `$GOPATH/src/github.com/USERNAME/dkron-NAME-TYPE`, where `USERNAME` is your GitHub username and `NAME` is the name of the plugin you're developing. This structure is what Go expects and simplifies things down the road.\n\nWith the directory made, create a main.go file. This project will be a binary so the package is \"main\":\n\n```go\npackage main\n\nimport (\n\t\"github.com/distribworks/dkron/v3/plugin\"\n)\n\nfunc main() {\n\tplugin.Serve(&plugin.ServeOpts{\n\t\tProcessor: new(MyPlugin),\n\t})\n}\n```\n\nAnd that's basically it! You'll have to change the argument given to plugin.Serve to be your actual plugin, but that is the only change you'll have to make. The argument should be a structure implementing one of the plugin interfaces (depending on what sort of plugin you're creating).\n\nDkron plugins must follow a very specific naming convention of `dkron-TYPE-NAME`. For example, `dkron-processor-files`, which tells Dkron that the plugin is a processor that can be referenced as \"files\".\n","frontmatter":{"title":"Developing plugins","weight":99},"isInternal":false,"tokens":386,"sizeBytes":1734},{"name":"index.md","path":"website/docs/usage/plugins/index.md","rawUrl":"https://raw.githubusercontent.com/dkron-io/dkron/HEAD/website/docs/usage/plugins/index.md","title":"Plugins Skill","category":"anthropic-skill","format":"markdown","content":"# Plugins\n\n## Intro\n\nPlugins in Dkron allow you to add funcionality that integrates with the workflow of the job execution in Dkron. It's a powerful system that allows you to extend and adapt Dkron to your special needs.\n\nThis page documents the basics of how the plugin system in Dkron works, and how to setup a basic development environment for plugin development if you're writing a Dkron plugin.\n\n## How it Works\n\nDkron execution execution processors are provided via plugins. Each plugin exposes functionality for modifying the execution. Plugins are executed as a separate process and communicate with the main Dkron binary over an RPC interface.\n\nThe code within the binaries must adhere to certain interfaces. The network communication and RPC is handled automatically by higher-level libraries. The exact interface to implement is documented in its respective documentation section.\n\n## Installing a Plugin\n\nDkron searches for plugins at startup, to install a plugin just drop the binary in one of the following locations:\n\n1. /etc/dkron/plugins\n2. Dkron executable directory\n","isInternal":false,"tokens":217,"sizeBytes":1085},{"name":"_index.md","path":"website/versioned_docs/version-v1/usage/plugins/_index.md","rawUrl":"https://raw.githubusercontent.com/dkron-io/dkron/HEAD/website/versioned_docs/version-v1/usage/plugins/_index.md","title":"Plugins Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Plugins\n---\n\n## Intro\n\nPlugins in Dkron allow you to add funcionality that integrates with the workflow of the job execution in Dkron. It's a powerful system that allows you to extend and adapt Dkron to your special needs.\n\nThis page documents the basics of how the plugin system in Dkron works, and how to setup a basic development environment for plugin development if you're writing a Dkron plugin.\n\n## How it Works\n\nDkron execution execution processors are provided via plugins. Each plugin exposes functionality for modifying the execution. Plugins are executed as a separate process and communicate with the main Dkron binary over an RPC interface.\n\nThe code within the binaries must adhere to certain interfaces. The network communication and RPC is handled automatically by higher-level libraries. The exact interface to implement is documented in its respective documentation section.\n\n## Installing a Plugin\n\nDkron searches for plugins at startup, to install a plugin just drop the binary in one of the following locations:\n\n1. /etc/dkron/plugins\n2. Dkron executable directory\n\n{{% children  %}}\n","frontmatter":{"title":"Plugins"},"isInternal":false,"tokens":226,"sizeBytes":1117},{"name":"develop.md","path":"website/versioned_docs/version-v1/usage/plugins/develop.md","rawUrl":"https://raw.githubusercontent.com/dkron-io/dkron/HEAD/website/versioned_docs/version-v1/usage/plugins/develop.md","title":"Plugins Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Developing plugins\nweight: 99\n---\n\n## Developing a Plugin\n\n:::warning\n**Advanced topic!** Plugin development is a highly advanced topic, and is not required knowledge for day-to-day usage. If you don't plan on writing any plugins, we recommend not reading the following section of the documentation.\n:::\n\nDeveloping a plugin is simple. The only knowledge necessary to write a plugin is basic command-line skills and basic knowledge of the Go programming language.\n\nNote: A common pitfall is not properly setting up a `$GOPATH`. This can lead to strange errors. You can read more about this here to familiarize yourself.\n\nCreate a new Go project somewhere in your `$GOPATH`. If you're a GitHub user, we recommend creating the project in the directory `$GOPATH/src/github.com/USERNAME/dkron-NAME-TYPE`, where `USERNAME` is your GitHub username and `NAME` is the name of the plugin you're developing. This structure is what Go expects and simplifies things down the road.\n\nWith the directory made, create a main.go file. This project will be a binary so the package is \"main\":\n\n```go\npackage main\n\nimport (\n\t\"github.com/distribworks/dkron/plugin\"\n)\n\nfunc main() {\n\tplugin.Serve(&plugin.ServeOpts{\n\t\tProcessor: new(MyPlugin),\n\t})\n}\n```\n\nAnd that's basically it! You'll have to change the argument given to plugin.Serve to be your actual plugin, but that is the only change you'll have to make. The argument should be a structure implementing one of the plugin interfaces (depending on what sort of plugin you're creating).\n\nDkron plugins must follow a very specific naming convention of `dkron-TYPE-NAME`. For example, `dkron-processor-files`, which tells Dkron that the plugin is a processor that can be referenced as \"files\".\n","frontmatter":{"title":"Developing plugins","weight":99},"isInternal":false,"tokens":387,"sizeBytes":1735},{"name":"_index.md","path":"website/versioned_docs/version-v2/usage/plugins/_index.md","rawUrl":"https://raw.githubusercontent.com/dkron-io/dkron/HEAD/website/versioned_docs/version-v2/usage/plugins/_index.md","title":"Plugins Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Plugins\n---\n\n## Intro\n\nPlugins in Dkron allow you to add funcionality that integrates with the workflow of the job execution in Dkron. It's a powerful system that allows you to extend and adapt Dkron to your special needs.\n\nThis page documents the basics of how the plugin system in Dkron works, and how to setup a basic development environment for plugin development if you're writing a Dkron plugin.\n\n## How it Works\n\nDkron execution execution processors are provided via plugins. Each plugin exposes functionality for modifying the execution. Plugins are executed as a separate process and communicate with the main Dkron binary over an RPC interface.\n\nThe code within the binaries must adhere to certain interfaces. The network communication and RPC is handled automatically by higher-level libraries. The exact interface to implement is documented in its respective documentation section.\n\n## Installing a Plugin\n\nDkron searches for plugins at startup, to install a plugin just drop the binary in one of the following locations:\n\n1. /etc/dkron/plugins\n2. Dkron executable directory\n\n{{% children  %}}\n","frontmatter":{"title":"Plugins"},"isInternal":false,"tokens":226,"sizeBytes":1117},{"name":"develop.md","path":"website/versioned_docs/version-v2/usage/plugins/develop.md","rawUrl":"https://raw.githubusercontent.com/dkron-io/dkron/HEAD/website/versioned_docs/version-v2/usage/plugins/develop.md","title":"Plugins Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Developing plugins\nweight: 99\n---\n\n## Developing a Plugin\n\n:::warning\n**Advanced topic!** Plugin development is a highly advanced topic, and is not required knowledge for day-to-day usage. If you don't plan on writing any plugins, we recommend not reading the following section of the documentation.\n:::\n\nDeveloping a plugin is simple. The only knowledge necessary to write a plugin is basic command-line skills and basic knowledge of the Go programming language.\n\nNote: A common pitfall is not properly setting up a `$GOPATH`. This can lead to strange errors. You can read more about this here to familiarize yourself.\n\nCreate a new Go project somewhere in your `$GOPATH`. If you're a GitHub user, we recommend creating the project in the directory `$GOPATH/src/github.com/USERNAME/dkron-NAME-TYPE`, where `USERNAME` is your GitHub username and `NAME` is the name of the plugin you're developing. This structure is what Go expects and simplifies things down the road.\n\nWith the directory made, create a main.go file. This project will be a binary so the package is \"main\":\n\n```go\npackage main\n\nimport (\n\t\"github.com/distribworks/dkron/v3/plugin\"\n)\n\nfunc main() {\n\tplugin.Serve(&plugin.ServeOpts{\n\t\tProcessor: new(MyPlugin),\n\t})\n}\n```\n\nAnd that's basically it! You'll have to change the argument given to plugin.Serve to be your actual plugin, but that is the only change you'll have to make. The argument should be a structure implementing one of the plugin interfaces (depending on what sort of plugin you're creating).\n\nDkron plugins must follow a very specific naming convention of `dkron-TYPE-NAME`. For example, `dkron-processor-files`, which tells Dkron that the plugin is a processor that can be referenced as \"files\".\n","frontmatter":{"title":"Developing plugins","weight":99},"isInternal":false,"tokens":389,"sizeBytes":1738},{"name":"_category_.json","path":"website/versioned_docs/version-v3/usage/plugins/_category_.json","rawUrl":"https://raw.githubusercontent.com/dkron-io/dkron/HEAD/website/versioned_docs/version-v3/usage/plugins/_category_.json","title":"Plugins Skill","category":"anthropic-skill","format":"json","content":"{\n  \"label\": \"Plugins\"\n}\n","frontmatter":{"label":"Plugins"},"isInternal":false,"tokens":9,"sizeBytes":25},{"name":"develop.md","path":"website/versioned_docs/version-v3/usage/plugins/develop.md","rawUrl":"https://raw.githubusercontent.com/dkron-io/dkron/HEAD/website/versioned_docs/version-v3/usage/plugins/develop.md","title":"Plugins Skill","category":"anthropic-skill","format":"markdown","content":"---\ntitle: Developing plugins\nweight: 99\n---\n\n## Developing a Plugin\n\n:::warning Advanced topic!\nPlugin development is a highly advanced topic, and is not required knowledge for day-to-day usage. If you don't plan on writing any plugins, we recommend not reading the following section of the documentation.\n:::\n\nDeveloping a plugin is simple. The only knowledge necessary to write a plugin is basic command-line skills and basic knowledge of the Go programming language.\n\nNote: A common pitfall is not properly setting up a `$GOPATH`. This can lead to strange errors. You can read more about this here to familiarize yourself.\n\nCreate a new Go project somewhere in your `$GOPATH`. If you're a GitHub user, we recommend creating the project in the directory `$GOPATH/src/github.com/USERNAME/dkron-NAME-TYPE`, where `USERNAME` is your GitHub username and `NAME` is the name of the plugin you're developing. This structure is what Go expects and simplifies things down the road.\n\nWith the directory made, create a main.go file. This project will be a binary so the package is \"main\":\n\n```go\npackage main\n\nimport (\n\t\"github.com/distribworks/dkron/v3/plugin\"\n)\n\nfunc main() {\n\tplugin.Serve(&plugin.ServeOpts{\n\t\tProcessor: new(MyPlugin),\n\t})\n}\n```\n\nAnd that's basically it! You'll have to change the argument given to plugin.Serve to be your actual plugin, but that is the only change you'll have to make. The argument should be a structure implementing one of the plugin interfaces (depending on what sort of plugin you're creating).\n\nDkron plugins must follow a very specific naming convention of `dkron-TYPE-NAME`. For example, `dkron-processor-files`, which tells Dkron that the plugin is a processor that can be referenced as \"files\".\n","frontmatter":{"title":"Developing plugins","weight":99},"isInternal":false,"tokens":386,"sizeBytes":1734},{"name":"index.md","path":"website/versioned_docs/version-v3/usage/plugins/index.md","rawUrl":"https://raw.githubusercontent.com/dkron-io/dkron/HEAD/website/versioned_docs/version-v3/usage/plugins/index.md","title":"Plugins Skill","category":"anthropic-skill","format":"markdown","content":"# Plugins\n\n## Intro\n\nPlugins in Dkron allow you to add funcionality that integrates with the workflow of the job execution in Dkron. It's a powerful system that allows you to extend and adapt Dkron to your special needs.\n\nThis page documents the basics of how the plugin system in Dkron works, and how to setup a basic development environment for plugin development if you're writing a Dkron plugin.\n\n## How it Works\n\nDkron execution execution processors are provided via plugins. Each plugin exposes functionality for modifying the execution. Plugins are executed as a separate process and communicate with the main Dkron binary over an RPC interface.\n\nThe code within the binaries must adhere to certain interfaces. The network communication and RPC is handled automatically by higher-level libraries. The exact interface to implement is documented in its respective documentation section.\n\n## Installing a Plugin\n\nDkron searches for plugins at startup, to install a plugin just drop the binary in one of the following locations:\n\n1. /etc/dkron/plugins\n2. Dkron executable directory\n","isInternal":false,"tokens":217,"sizeBytes":1085}],"systemPromptSnippet":"<yakaai_skills repo=\"dkron-io/dkron\">\n<!-- File: AGENTS.md (Tokens: ~1573 | Category: root-instruction) -->\n# AGENTS instructions\n\nThis file provides guidance to agents when working with code in this repository.\n\n## Project Overview\n\nDkron is a distributed, fault-tolerant job scheduling system (distributed cron) written in Go. It uses:\n- **Raft protocol** (HashiCorp Raft) for consensus and leader election\n- **Serf** (HashiCorp) for cluster membership and failure detection via gossip protocol\n- **BuntDB** for embedded storage\n- **gRPC** for inter-node communication\n- **Gin** for HTTP/REST API\n- **React Admin** for the web UI\n\nThe system is inspired by Google's \"Reliable Cron across the Planet\" whitepaper and Airbnb's Chronos.\n\n## Development Commands\n\n### Building\n```bash\n# Build the main binary (requires UI to be built first)\nmake main\n\n# Build main binary manually\ngo build main.go\n\n# Install built-in plugins (executors and processors)\nGOBIN=`pwd` go install ./builtin/...\n\n# Clean build artifacts\nmake clean\n```\n\n### Testing\n```bash\n# Run full test suite in Docker\nmake test\n\n# Run tests locally\nmake localtest\n# Or directly:\ngo test -v ./...\n\n# Run specific test\ngo test -v ./dkron -run TestJobName\n```\n\n### Frontend Development\n```bash\n# Install dependencies (uses Bun)\ncd ui && bun install\n\n# Start development server\ncd ui && npm start\n\n# Build UI for production (outputs to dkron/ui-dist)\ncd ui && yarn build --out-dir ../dkron/ui-dist\n# Or use make:\nmake ui\n```\n\n### Docker Development\n```bash\n# Start development cluster with live reload\ndocker compose -f docker-compose.dev.yml up\n\n# Start production-like cluster\ndocker compose up -d\n\n# Scale the cluster\ndocker compose up -d --scale dkron-server=4\ndocker compose up -d --scale dkron-agent=10\n\n# Access UI at http://localhost:8080/ui\n```\n\n### Protocol Buffers\n```bash\n# Generate Go code from proto files\nmake proto\n# Or manually:\nprotoc -I proto/ --go_out=types --go_opt=paths=source_relative \\\n  --go-grpc_out=types --go-grpc_opt=paths=source_relative proto/dkron.proto\n```\n\n### Code Generation\n```bash\n# Generate API client from OpenAPI spec\nmake client\n```\n\n## Architecture\n\n### Core Components\n\n**Agent** (`dkron/agent.go`)\n- Main orchestrator that combines all subsystems\n- Manages both server (Raft leader/follower) and agent (execution) roles\n- Contains: Serf cluster, Raft consensus, gRPC server/client, HTTP API, scheduler, storage, plugins\n\n**Storage** (`dkron/store.go`)\n- Interface: `Storage` defines operations (Get/SetJob, Get/SetExecution, etc.)\n- Implementation: `Store` uses BuntDB (embedded key-value store)\n- Stores jobs and executions with max 100 executions per job\n- Key prefixes: `jobs/` and `executions/`\n\n**Leader Election** (`dkron/leader.go`)\n- Raft-based leader election\n- Only the leader schedules jobs (prevents duplicate executions)\n- Leader runs the `Scheduler` which manages cron timers\n\n**Job Scheduling** (`dkron/scheduler.go`, `dkron/job.go`)\n- Cron-based scheduling using `robfig/cron/v3`\n- Extended cron syntax support via `extcron/` package\n- Jobs can have parent-child dependencies\n- Concurrency policies: `allow` or `forbid`\n- Hash symbol (`~`) in schedules is replaced with hash of job name for distribution\n\n**Execution** (`dkron/run.go`, `dkron/execution.go`)\n- Leader determines target nodes based on job tags\n- Nodes execute jobs via executor plugins\n- Results streamed back to leader via gRPC\n- Execution status: success, failed, running, partially_failed\n\n**Cluster Communication**\n- `dkron/serf.go`: Serf for membership, failure detection, and event propagation\n- `dkron/grpc.go`: gRPC server for job execution coordination\n- `dkron/grpc_client.go`: gRPC client for communicating with other nodes\n- `dkron/api.go`: REST API using Gin framework\n\n**Plugin System** (`plugin/`)\n- Two plugin types: **Executors** (run jobs) and **Processors** (process outputs)\n- Uses HashiCorp go-plugin for RPC-based plugins\n- Built-in executors: shell, http, grpc, kafka, nats, rabbitmq, gcppubsub\n- Built-in processors: log, files, syslog, fluent\n- Plugins live in `builtin/bins/`\n\n### Key Data Structures\n\n**Job** (`dkron/job.go`)\n- Name (unique ID), Schedule (cron expression), Timezone\n- Executor and ExecutorConfig\n- Parent job for dependencies\n- Tags for targeting specific nodes\n- Concurrency policy, retries, timeout\n\n**Execution** (`dkron/execution.go`)\n- Links to Job, records start/finish times\n- NodeName (where it ran), Output, Success/Error status\n\n### Configuration\n\nConfig loaded via Viper from:\n- Config files: `/etc/dkron/dkron.yaml`, `$HOME/.dkron/dkron.yaml`, `./config/dkron.yaml`\n- Environment variables: `DKRON_*` (e.g., `DKRON_NODE_NAME`)\n- CLI flags (via Cobra in `cmd/`)\n\nKey settings: `node-name`, `bind-addr`, `server`, `bootstrap-expect`, `data-dir`, `tags`\n\n### Module Structure\n\n- `cmd/`: CLI commands (agent, keygen, version, etc.)\n- `dkron/`: Core library (agent, storage, API, scheduler, clustering)\n- `builtin/bins/`: Built-in executor and processor plugin binaries\n- `plugin/`: Plugin interfaces and serving logic\n- `proto/`, `types/`: Protobuf definitions and generated code\n- `extcron/`: Extended cron parser supporting simple syntax\n- `ntime/`: Nullable time type\n- `logging/`: Custom logging setup\n- `client/`: Auto-generated API client\n- `ui/`: React Admin frontend (TypeScript/Vite)\n\n## Code Patterns\n\n### Working with Storage\nAlways use the `Storage` interface. Wrap operations in context and check for `buntdb.ErrNotFound` when getting jobs/executions.\n\n### Leader Operations\nCheck `a.IsLeader()` before performing leader-only operations like job scheduling or applying Raft logs.\n\n### gRPC Communication\nUse `GRPCClient.ExecutionDone()` to report execution results to the leader. The leader uses `AgentRun()` to trigger job execution on target nodes.\n\n### Plugin Development\nImplement `plugin.Executor` or `plugin.Processor` interfaces. Use `plugin.Serve()` to serve the plugin. See existing plugins in `builtin/bins/` for examples.\n\n## Important Notes\n\n- The system uses both Raft (for consistency) and Serf (for membership)\n- Jobs are only scheduled by the leader to avoid duplicates\n- Executions are tracked with a sliding window (max 100 per job)\n- The UI is embedded in the binary via Go embed (`dkron/ui-dist`)\n- Plugin communication uses HashiCorp's go-plugin over gRPC\n- Module path is `github.com/distribworks/dkron/v4` (note the v4 major version)\n\n<!-- File: website/docs/usage/plugins/_category_.json (Tokens: ~9 | Category: anthropic-skill) -->\n{\n  \"label\": \"Plugins\"\n}\n\n<!-- File: website/docs/usage/plugins/develop.md (Tokens: ~386 | Category: anthropic-skill) -->\n---\ntitle: Developing plugins\nweight: 99\n---\n\n## Developing a Plugin\n\n:::warning Advanced topic!\nPlugin development is a highly advanced topic, and is not required knowledge for day-to-day usage. If you don't plan on writing any plugins, we recommend not reading the following section of the documentation.\n:::\n\nDeveloping a plugin is simple. The only knowledge necessary to write a plugin is basic command-line skills and basic knowledge of the Go programming language.\n\nNote: A common pitfall is not properly setting up a `$GOPATH`. This can lead to strange errors. You can read more about this here to familiarize yourself.\n\nCreate a new Go project somewhere in your `$GOPATH`. If you're a GitHub user, we recommend creating the project in the directory `$GOPATH/src/github.com/USERNAME/dkron-NAME-TYPE`, where `USERNAME` is your GitHub username and `NAME` is the name of the plugin you're developing. This structure is what Go expects and simplifies things down the road.\n\nWith the directory made, create a main.go file. This project will be a binary so the package is \"main\":\n\n```go\npackage main\n\nimport (\n\t\"github.com/distribworks/dkron/v3/plugin\"\n)\n\nfunc main() {\n\tplugin.Serve(&plugin.ServeOpts{\n\t\tProcessor: new(MyPlugin),\n\t})\n}\n```\n\nAnd that's basically it! You'll have to change the argument given to plugin.Serve to be your actual plugin, but that is the only change you'll have to make. The argument should be a structure implementing one of the plugin interfaces (depending on what sort of plugin you're creating).\n\nDkron plugins must follow a very specific naming convention of `dkron-TYPE-NAME`. For example, `dkron-processor-files`, which tells Dkron that the plugin is a processor that can be referenced as \"files\".\n\n<!-- File: website/docs/usage/plugins/index.md (Tokens: ~217 | Category: anthropic-skill) -->\n# Plugins\n\n## Intro\n\nPlugins in Dkron allow you to add funcionality that integrates with the workflow of the job execution in Dkron. It's a powerful system that allows you to extend and adapt Dkron to your special needs.\n\nThis page documents the basics of how the plugin system in Dkron works, and how to setup a basic development environment for plugin development if you're writing a Dkron plugin.\n\n## How it Works\n\nDkron execution execution processors are provided via plugins. Each plugin exposes functionality for modifying the execution. Plugins are executed as a separate process and communicate with the main Dkron binary over an RPC interface.\n\nThe code within the binaries must adhere to certain interfaces. The network communication and RPC is handled automatically by higher-level libraries. The exact interface to implement is documented in its respective documentation section.\n\n## Installing a Plugin\n\nDkron searches for plugins at startup, to install a plugin just drop the binary in one of the following locations:\n\n1. /etc/dkron/plugins\n2. Dkron executable directory\n\n<!-- File: website/versioned_docs/version-v1/usage/plugins/_index.md (Tokens: ~226 | Category: anthropic-skill) -->\n---\ntitle: Plugins\n---\n\n## Intro\n\nPlugins in Dkron allow you to add funcionality that integrates with the workflow of the job execution in Dkron. It's a powerful system that allows you to extend and adapt Dkron to your special needs.\n\nThis page documents the basics of how the plugin system in Dkron works, and how to setup a basic development environment for plugin development if you're writing a Dkron plugin.\n\n## How it Works\n\nDkron execution execution processors are provided via plugins. Each plugin exposes functionality for modifying the execution. Plugins are executed as a separate process and communicate with the main Dkron binary over an RPC interface.\n\nThe code within the binaries must adhere to certain interfaces. The network communication and RPC is handled automatically by higher-level libraries. The exact interface to implement is documented in its respective documentation section.\n\n## Installing a Plugin\n\nDkron searches for plugins at startup, to install a plugin just drop the binary in one of the following locations:\n\n1. /etc/dkron/plugins\n2. Dkron executable directory\n\n{{% children  %}}\n\n<!-- File: website/versioned_docs/version-v1/usage/plugins/develop.md (Tokens: ~387 | Category: anthropic-skill) -->\n---\ntitle: Developing plugins\nweight: 99\n---\n\n## Developing a Plugin\n\n:::warning\n**Advanced topic!** Plugin development is a highly advanced topic, and is not required knowledge for day-to-day usage. If you don't plan on writing any plugins, we recommend not reading the following section of the documentation.\n:::\n\nDeveloping a plugin is simple. The only knowledge necessary to write a plugin is basic command-line skills and basic knowledge of the Go programming language.\n\nNote: A common pitfall is not properly setting up a `$GOPATH`. This can lead to strange errors. You can read more about this here to familiarize yourself.\n\nCreate a new Go project somewhere in your `$GOPATH`. If you're a GitHub user, we recommend creating the project in the directory `$GOPATH/src/github.com/USERNAME/dkron-NAME-TYPE`, where `USERNAME` is your GitHub username and `NAME` is the name of the plugin you're developing. This structure is what Go expects and simplifies things down the road.\n\nWith the directory made, create a main.go file. This project will be a binary so the package is \"main\":\n\n```go\npackage main\n\nimport (\n\t\"github.com/distribworks/dkron/plugin\"\n)\n\nfunc main() {\n\tplugin.Serve(&plugin.ServeOpts{\n\t\tProcessor: new(MyPlugin),\n\t})\n}\n```\n\nAnd that's basically it! You'll have to change the argument given to plugin.Serve to be your actual plugin, but that is the only change you'll have to make. The argument should be a structure implementing one of the plugin interfaces (depending on what sort of plugin you're creating).\n\nDkron plugins must follow a very specific naming convention of `dkron-TYPE-NAME`. For example, `dkron-processor-files`, which tells Dkron that the plugin is a processor that can be referenced as \"files\".\n\n<!-- File: website/versioned_docs/version-v2/usage/plugins/_index.md (Tokens: ~226 | Category: anthropic-skill) -->\n---\ntitle: Plugins\n---\n\n## Intro\n\nPlugins in Dkron allow you to add funcionality that integrates with the workflow of the job execution in Dkron. It's a powerful system that allows you to extend and adapt Dkron to your special needs.\n\nThis page documents the basics of how the plugin system in Dkron works, and how to setup a basic development environment for plugin development if you're writing a Dkron plugin.\n\n## How it Works\n\nDkron execution execution processors are provided via plugins. Each plugin exposes functionality for modifying the execution. Plugins are executed as a separate process and communicate with the main Dkron binary over an RPC interface.\n\nThe code within the binaries must adhere to certain interfaces. The network communication and RPC is handled automatically by higher-level libraries. The exact interface to implement is documented in its respective documentation section.\n\n## Installing a Plugin\n\nDkron searches for plugins at startup, to install a plugin just drop the binary in one of the following locations:\n\n1. /etc/dkron/plugins\n2. Dkron executable directory\n\n{{% children  %}}\n\n<!-- File: website/versioned_docs/version-v2/usage/plugins/develop.md (Tokens: ~389 | Category: anthropic-skill) -->\n---\ntitle: Developing plugins\nweight: 99\n---\n\n## Developing a Plugin\n\n:::warning\n**Advanced topic!** Plugin development is a highly advanced topic, and is not required knowledge for day-to-day usage. If you don't plan on writing any plugins, we recommend not reading the following section of the documentation.\n:::\n\nDeveloping a plugin is simple. The only knowledge necessary to write a plugin is basic command-line skills and basic knowledge of the Go programming language.\n\nNote: A common pitfall is not properly setting up a `$GOPATH`. This can lead to strange errors. You can read more about this here to familiarize yourself.\n\nCreate a new Go project somewhere in your `$GOPATH`. If you're a GitHub user, we recommend creating the project in the directory `$GOPATH/src/github.com/USERNAME/dkron-NAME-TYPE`, where `USERNAME` is your GitHub username and `NAME` is the name of the plugin you're developing. This structure is what Go expects and simplifies things down the road.\n\nWith the directory made, create a main.go file. This project will be a binary so the package is \"main\":\n\n```go\npackage main\n\nimport (\n\t\"github.com/distribworks/dkron/v3/plugin\"\n)\n\nfunc main() {\n\tplugin.Serve(&plugin.ServeOpts{\n\t\tProcessor: new(MyPlugin),\n\t})\n}\n```\n\nAnd that's basically it! You'll have to change the argument given to plugin.Serve to be your actual plugin, but that is the only change you'll have to make. The argument should be a structure implementing one of the plugin interfaces (depending on what sort of plugin you're creating).\n\nDkron plugins must follow a very specific naming convention of `dkron-TYPE-NAME`. For example, `dkron-processor-files`, which tells Dkron that the plugin is a processor that can be referenced as \"files\".\n\n<!-- File: website/versioned_docs/version-v3/usage/plugins/_category_.json (Tokens: ~9 | Category: anthropic-skill) -->\n{\n  \"label\": \"Plugins\"\n}\n\n<!-- File: website/versioned_docs/version-v3/usage/plugins/develop.md (Tokens: ~386 | Category: anthropic-skill) -->\n---\ntitle: Developing plugins\nweight: 99\n---\n\n## Developing a Plugin\n\n:::warning Advanced topic!\nPlugin development is a highly advanced topic, and is not required knowledge for day-to-day usage. If you don't plan on writing any plugins, we recommend not reading the following section of the documentation.\n:::\n\nDeveloping a plugin is simple. The only knowledge necessary to write a plugin is basic command-line skills and basic knowledge of the Go programming language.\n\nNote: A common pitfall is not properly setting up a `$GOPATH`. This can lead to strange errors. You can read more about this here to familiarize yourself.\n\nCreate a new Go project somewhere in your `$GOPATH`. If you're a GitHub user, we recommend creating the project in the directory `$GOPATH/src/github.com/USERNAME/dkron-NAME-TYPE`, where `USERNAME` is your GitHub username and `NAME` is the name of the plugin you're developing. This structure is what Go expects and simplifies things down the road.\n\nWith the directory made, create a main.go file. This project will be a binary so the package is \"main\":\n\n```go\npackage main\n\nimport (\n\t\"github.com/distribworks/dkron/v3/plugin\"\n)\n\nfunc main() {\n\tplugin.Serve(&plugin.ServeOpts{\n\t\tProcessor: new(MyPlugin),\n\t})\n}\n```\n\nAnd that's basically it! You'll have to change the argument given to plugin.Serve to be your actual plugin, but that is the only change you'll have to make. The argument should be a structure implementing one of the plugin interfaces (depending on what sort of plugin you're creating).\n\nDkron plugins must follow a very specific naming convention of `dkron-TYPE-NAME`. For example, `dkron-processor-files`, which tells Dkron that the plugin is a processor that can be referenced as \"files\".\n\n<!-- File: website/versioned_docs/version-v3/usage/plugins/index.md (Tokens: ~217 | Category: anthropic-skill) -->\n# Plugins\n\n## Intro\n\nPlugins in Dkron allow you to add funcionality that integrates with the workflow of the job execution in Dkron. It's a powerful system that allows you to extend and adapt Dkron to your special needs.\n\nThis page documents the basics of how the plugin system in Dkron works, and how to setup a basic development environment for plugin development if you're writing a Dkron plugin.\n\n## How it Works\n\nDkron execution execution processors are provided via plugins. Each plugin exposes functionality for modifying the execution. Plugins are executed as a separate process and communicate with the main Dkron binary over an RPC interface.\n\nThe code within the binaries must adhere to certain interfaces. The network communication and RPC is handled automatically by higher-level libraries. The exact interface to implement is documented in its respective documentation section.\n\n## Installing a Plugin\n\nDkron searches for plugins at startup, to install a plugin just drop the binary in one of the following locations:\n\n1. /etc/dkron/plugins\n2. Dkron executable directory\n</yakaai_skills>"}