Capabilities
Compatibility
Verification
Tags
@kansodata/openclaw-airflow-dag-git-plugin
Native OpenClaw plugin for controlled Airflow DAG .py operations through a GitHub pull-request workflow.
Scope
What it does
- Reads one allowlisted DAG file from GitHub (
airflow_dag_git_read_file). - Creates or updates allowlisted DAG files through:
- branch creation,
- commit creation (single-file legacy, or one aggregated commit for multi-file),
- PR opening (
airflow_dag_git_open_pr).
What it does not do
- No direct writes to Airflow hosts.
- No auto-merge.
- No direct pushes to protected branches.
- No more than 2 files per PR operation.
- No delete/rename in V0.
- No move operations in V0.
- No CI workflow, secrets, or repo configuration edits.
Why Git/PR instead of direct host writes
The plugin enforces controlled change management with:
- reviewable diffs,
- branch isolation,
- auditable history,
- standard GitHub rollback mechanics.
This reduces operational risk compared to direct host mutation.
Architecture
flowchart LR
U[User / Agent] --> H[OpenClaw Host]
H --> P[airflow-dag-git plugin]
P --> G[GitHub API]
G --> R[(Target Repository)]
R --> G
G --> P
P --> H
Flow summary: OpenClaw routes the tool call to the plugin, the plugin validates policy and content, and GitHub receives branch/commit/PR operations against the target repository.
Security Model
- Read and PR workflow only.
- No direct writes to Airflow hosts.
- Fail-closed validation on owner/repo/path, file type, and content policy.
- Pull request is the controlled change boundary (no direct protected-branch mutation).
- Structured observability with per-execution
requestId, stage events, and stable validation/error codes. - Hardening-first telemetry: no full file contents, no full diffs, no tokens/secrets in emitted metadata.
Observability
airflow_dag_git_open_pr emits structured stage events and includes a requestId for traceability.
- Stage events:
open_pr_start,input_validated,change_set_planned,preview_generated,execution_blocked,branch_created,commit_created,pr_opened,open_pr_completed,open_pr_failed. - Stable code namespaces:
VAL_*,POL_*,GH_*,EXEC_*,PREVIEW_*. - Observability does not change functional scope or write behavior.
Installation
openclaw plugins install @kansodata/openclaw-airflow-dag-git-plugin
From ClawHub:
openclaw plugins install clawhub:@kansodata/openclaw-airflow-dag-git-plugin
Operational Prerequisites
GITHUB_TOKENis required (plugin configgithubTokenorGITHUB_TOKENenv var fallback).- The token must have permissions to read repository contents and create pull requests in allowlisted repositories.
Configuration
Configure under plugins.entries.airflow-dag-git.config.
{
"plugins": {
"entries": {
"airflow-dag-git": {
"enabled": true,
"config": {
"githubToken": "${secret:GITHUB_TOKEN}",
"allowedOwners": ["kansodata"],
"allowedRepos": ["airflow-dags"],
"allowedDagPaths": ["dags/", "airflow/dags/"],
"defaultBaseBranch": "main",
"maxFileSizeBytes": 200000,
"readOnly": false,
"allowedNetworkHosts": ["internal-api.company.local"]
}
}
}
}
}
Also supported: GITHUB_TOKEN environment variable fallback.
Tools
airflow_dag_git_read_file
Input:
owner(string)repo(string)ref(optional string)path(string)
Behavior:
- Validates owner/repo/path against allowlists.
- Requires
.pyunder allowlisted DAG paths. - Returns content, sha, resolved ref, and size.
airflow_dag_git_open_pr (optional side effects)
Input:
owner(string)repo(string)baseBranch(optional string)targetPath(string)newContent(string)files(optional array of{ targetPath, newContent }, max 2)commitMessage(string)prTitle(string)prBody(optional string)branchName(optional string)previewOnly(optional boolean, defaultfalse)
Behavior (fail-closed):
- Validates owner/repo/path against allowlists.
- Accepts only
.pyunder allowlisted DAG prefixes. - Rejects traversal and absolute paths.
- Rejects duplicated target paths.
- Rejects more than 2 files.
- Enforces max file size.
- Enforces aggregate validation for multi-file (total size + total diff constraints).
- Requires DAG marker (
DAG(or@dag). - Blocks dangerous patterns (
subprocess,os.system,eval(,exec(). - Blocks external
requests.*unless host is allowlisted. - Always validates owner/repo/path/content with the same guardrails used by execution mode.
- When
previewOnly !== true: creates one branch and opens one PR; single-file uses legacy write path, multi-file applies up to 2 file updates in one commit. - When
previewOnly === true: reads current file(s), computes safe preview output, and does not create branch/commit/PR. - Returns PR metadata in execution mode, or structured preview metadata (per-file + aggregate) in preview mode.
Tool selection guidance
- Use
airflow_dag_git_open_prwithpreviewOnly: truefirst for safe review before proposing side effects. - Use
airflow_dag_git_open_prwithoutpreviewOnlyto execute branch/commit/PR only after preview passes. - Use
airflow_dag_git_read_fileonly when explicit repository inspection is needed. - Prefer
open_prworkflow for change proposals because it preserves review and rollback controls. - Avoid routine pre-reads when the caller already has authoritative DAG content and only needs to propose an update.
Usage example
Example tool call for airflow_dag_git_open_pr:
{
"owner": "kansodata",
"repo": "airflow-dags",
"baseBranch": "main",
"targetPath": "dags/example_pipeline.py",
"newContent": "from airflow import DAG\n",
"commitMessage": "feat(dag): update example pipeline",
"prTitle": "Update example DAG",
"prBody": "Proposed via OpenClaw airflow-dag-git plugin."
}
Preview example (no side effects):
{
"owner": "kansodata",
"repo": "airflow-dags",
"baseBranch": "main",
"targetPath": "dags/example_pipeline.py",
"newContent": "from airflow import DAG\n",
"commitMessage": "feat(dag): update example pipeline",
"prTitle": "Preview update example DAG",
"previewOnly": true
}
Multi-file example (max 2 files):
{
"owner": "kansodata",
"repo": "airflow-dags",
"baseBranch": "main",
"files": [
{
"targetPath": "dags/example_a.py",
"newContent": "from airflow import DAG\n"
},
{
"targetPath": "dags/example_b.py",
"newContent": "from airflow import DAG\n"
}
],
"commitMessage": "feat(dag): update two dags",
"prTitle": "Update DAG set",
"previewOnly": true
}
Smoke test evidence
The plugin has been validated end-to-end in a sandbox repository with successful PR creation through airflow_dag_git_open_pr. This confirms the branch, commit, and PR path under the current V0 scope.
Current limitations
- At most 2 files per operation.
- No delete/rename.
- No file move operations.
- No auto-merge.
- No direct host writes.
- No CI workflow edits.
- Preview mode computes validation + diff only and never mutates GitHub state.
Limitations
- Does not execute DAGs.
- Does not read Airflow runtime logs.
- Does not provide direct access to Airflow hosts.
Release readiness notes
Validated:
- Tool contract wiring and schema checks.
- Guardrails for allowlists, path controls, DAG markers, and blocked patterns.
- End-to-end PR workflow in sandbox (branch + commit + PR creation).
Out of scope:
- Delete/rename operations.
- Direct Airflow host mutations.
- Auto-merge or direct branch pushes bypassing PR review.
Recommended checks before publishing to npm / ClawHub:
- Run
npm run lint,npm run typecheck, andnpm test. - Confirm
openclaw.plugin.jsonmetadata matches published package metadata. - Verify final package contents with
npm pack --dry-run.
Rollback flow
- Close the PR if not merged.
- Delete the created branch.
- If merged, revert the merge commit through standard GitHub process.
Development
npm install
npm run lint
npm run typecheck
npm test
