Sources & TaskSets
Sources tell dicode where to find tasks. A source can be a local directory on disk or a remote Git repository. TaskSets provide a hierarchical composition model for organizing tasks across multiple repositories with namespace-scoped IDs and override cascades.
Local source
A local source watches a directory on disk for task changes.
# dicode.yaml
sources:
- type: local
path: /home/user/tasks- fsnotify: File changes are detected via OS filesystem notifications (fsnotify) with approximately 150ms debounce to handle editors that write via tmp-rename.
- Initial scan: On startup, all task directories are scanned and registered.
- Hot reload: Adding, modifying, or removing a task directory is detected in real time -- no restart needed.
Git source
A git source clones a remote repository and polls it for changes on a configurable interval.
# dicode.yaml
sources:
- type: git
url: https://github.com/myorg/my-tasks.git
branch: main # default: main
poll_interval: 30s # default: 30s
auth:
token_env: GITHUB_TOKEN # env var holding a PAT or access token- Clone on startup: The repository is cloned to a local cache directory under
~/.dicode/repos/. - Polling: dicode pulls the branch at the configured interval and diffs the snapshot to detect added, updated, or removed tasks.
- Token auth: For private repositories, set
auth.token_envto the name of an environment variable containing an HTTP Bearer / Basic-auth token (e.g. a GitHub PAT).
TaskSets
TaskSets are hierarchical YAML manifests that compose tasks from multiple sources with namespace scoping, override cascades, and deduplication. They are the recommended way to manage tasks at scale.
Structure
A TaskSet file has kind: TaskSet and contains named entries. Each entry can reference a local task directory, a git repository, or another nested TaskSet:
apiVersion: dicode/v1
kind: TaskSet
metadata:
name: my-taskset
spec:
defaults:
timeout: 30s
env:
- name: LOG_LEVEL
value: info
entries:
deploy-backend:
ref:
path: ./tasks/deploy-backend
deploy-frontend:
ref:
url: https://github.com/myorg/frontend-deploy.git
path: taskset.yaml
branch: main
overrides:
params:
environment: staging
monitoring:
ref:
url: https://github.com/myorg/monitoring-tasks.git
path: taskset.yamlNamespace-scoped IDs
Tasks within a TaskSet get namespaced IDs based on the entry hierarchy. For example, if the root TaskSet is named infra and has an entry deploy-backend, the task ID becomes infra/deploy-backend. Nested TaskSets add further segments: infra/monitoring/check-health.
This prevents name collisions across independently maintained task repositories.
Override precedence
TaskSets apply overrides in a three-level cascade (lowest to highest priority):
- task.yaml base spec -- The original task definition as written by the author.
- TaskSet defaults -- The
spec.defaultsblock of the TaskSet containing the entry. Applied to all entries in the set. - Per-entry overrides -- The
overridesblock on the specific entry. Highest priority, wins over everything.
For example:
spec:
defaults: # Level 2: applied to all entries
timeout: 60s
env:
- name: ENV
value: staging
entries:
my-task:
ref:
path: ./tasks/my-task # Level 1: task.yaml base
overrides: # Level 3: per-entry, wins
timeout: 120s
params:
limit: "50"What can be overridden
The override system can patch these fields without modifying the original task.yaml:
name,descriptiontrigger(cron, webhook, manual, chain, daemon, restart)params(add new params or change defaults of existing ones)env(add or replace env entries)net(replace network access list)timeoutruntimenotify(on_success, on_failure)dicodepermissions (tasks, mcp, list_tasks, get_runs, secrets_write)
Nested entry overrides
Parent TaskSets can patch specific tasks inside nested TaskSets using overrides.entries:
entries:
monitoring:
ref:
url: https://github.com/myorg/monitoring.git
path: taskset.yaml
overrides:
entries:
health-check: # patch a specific task inside the nested set
timeout: 120s
params:
endpoint: https://api.example.comGit refs in entries
Entries can reference tasks in remote Git repositories:
entries:
deploy:
ref:
url: https://github.com/myorg/deploy-tasks.git
path: tasks/deploy # path within the repo
branch: main
poll_interval: 60s
auth:
token_env: GITHUB_TOKENDev mode
TaskSet sources support a dev mode that temporarily swaps a remote git source for a local directory. This lets you develop and test changes to tasks without pushing to a remote repository.
Activating dev mode
Via the REST API:
curl -X PATCH http://localhost:8080/api/sources/my-source/dev \
-H 'Content-Type: application/json' \
-d '{"enabled": true, "local_path": "/home/user/my-local-tasks/taskset.yaml"}'Via MCP (for AI agent integrations):
switch_dev_mode(source="my-source", enabled=true, local_path="/home/user/my-local-tasks")Deactivating dev mode
curl -X PATCH http://localhost:8080/api/sources/my-source/dev \
-H 'Content-Type: application/json' \
-d '{"enabled": false}'When dev mode is deactivated, the source reverts to its configured git remote.
Dev refs
Entries can declare a dev_ref that is automatically substituted when dev mode is active:
entries:
my-task:
ref:
url: https://github.com/myorg/tasks.git
path: taskset.yaml
dev_ref:
path: /home/user/local-tasks/taskset.yaml