Build Teaql App
teaql/teaql-agent-kit
Build or change a TeaQL application in Java, Rust, Go, Swift, Python, C/.NET, or TypeScript, including Kotlin/JVM applications that consume Java-generated libraries.
Writes Airflow task logic in Java, Kotlin, or any JVM language using the Airflow Java SDK.
$ npx skills add astronomer/agents --skill authoring-java-sdk-tasks -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install astronomer/agents authoring-java-sdk-tasks --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/astronomer/agents.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/authoring-java-sdk-tasks .claude/skills/authoring-java-sdk-tasks && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "authoring-java-sdk-tasks" agent skill from https://github.com/astronomer/agents/tree/main/skills/authoring-java-sdk-tasks into .claude/skills/authoring-java-sdk-tasks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "authoring-java-sdk-tasks", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/astronomer/agents/tree/main/skills/authoring-java-sdk-tasksType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add astronomer/agents --skill authoring-java-sdk-tasks -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install astronomer/agents authoring-java-sdk-tasks --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/astronomer/agents.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/authoring-java-sdk-tasks .agents/skills/authoring-java-sdk-tasks && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "authoring-java-sdk-tasks" agent skill from https://github.com/astronomer/agents/tree/main/skills/authoring-java-sdk-tasks into .agents/skills/authoring-java-sdk-tasks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "authoring-java-sdk-tasks", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add astronomer/agents --skill authoring-java-sdk-tasks -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install astronomer/agents authoring-java-sdk-tasks --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/astronomer/agents.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/authoring-java-sdk-tasks .cursor/skills/authoring-java-sdk-tasks && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "authoring-java-sdk-tasks" agent skill from https://github.com/astronomer/agents/tree/main/skills/authoring-java-sdk-tasks into .cursor/skills/authoring-java-sdk-tasks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "authoring-java-sdk-tasks", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/astronomer/agents.git --path skills/authoring-java-sdk-tasks--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add astronomer/agents --skill authoring-java-sdk-tasks -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install astronomer/agents authoring-java-sdk-tasks --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/astronomer/agents.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/authoring-java-sdk-tasks .gemini/skills/authoring-java-sdk-tasks && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "authoring-java-sdk-tasks" agent skill from https://github.com/astronomer/agents/tree/main/skills/authoring-java-sdk-tasks into .gemini/skills/authoring-java-sdk-tasks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "authoring-java-sdk-tasks", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install astronomer/agents authoring-java-sdk-tasksInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add astronomer/agents --skill authoring-java-sdk-tasks -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/astronomer/agents.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/authoring-java-sdk-tasks .github/skills/authoring-java-sdk-tasks && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "authoring-java-sdk-tasks" agent skill from https://github.com/astronomer/agents/tree/main/skills/authoring-java-sdk-tasks into .github/skills/authoring-java-sdk-tasks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "authoring-java-sdk-tasks", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add astronomer/agents --skill authoring-java-sdk-tasks -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install astronomer/agents authoring-java-sdk-tasks --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/astronomer/agents.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/authoring-java-sdk-tasks .opencode/skills/authoring-java-sdk-tasks && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "authoring-java-sdk-tasks" agent skill from https://github.com/astronomer/agents/tree/main/skills/authoring-java-sdk-tasks into .opencode/skills/authoring-java-sdk-tasks/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "authoring-java-sdk-tasks", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
authoring-java-sdk-tasksWrites Airflow task logic in Java, Kotlin, or any JVM language using the Airflow Java SDK.
Authoring Java SDK Tasks is an agent skill from astronomer/agents. Writes Airflow task logic in Java, Kotlin, or any JVM language using the Airflow Java SDK. Use when the user wants to implement Airflow tasks in Java/JVM, asks about @Builder.Dag/@Builder.Task/@Builder.XCom, the Task/BundleBuilder interfaces, reading connections/variables/XComs from Java, the JSON-to-Java type mapping, or logging from Java tasks. This skill covers the Java-specific native API; the shared Python-stub pattern and conceptual model live in authoring-language-sdk-tasks. For building/shipping the…
Its SKILL.md is about 2.6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Data & Analytics, covering Data pipelines and ETL and Android development. It works with Java, Apache Airflow, Python and Kotlin. The repository describes itself as: AI agent tooling for data engineering workflows. The licence is Apache-2.0.
Read from SKILL.md and the folder at commit 1ec1a1f. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are java and python).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Authoring Java SDK Tasks loads about 2.6k tokens when it runs. Until then it costs about 162 tokens; SKILL.md has 895 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from astronomer/agents at commit 1ec1a1f, republished under its Apache-2.0 licence (© astronomer). 895 words, ~2,603 tokens.
.claude/skills/authoring-java-sdk-tasks/SKILL.md (or your agent's skills folder).The Airflow Java SDK implements the language-SDK model for the JVM: your DAG stays in Python, and each task instance runs in a short-lived JVM subprocess. This skill covers the Java-specific native API. The shared model — the Python @task.stub pattern, ID matching, and the XCom-as-JSON contract — lives in authoring-language-sdk-tasks; read that first if you're new to language SDKs.
Experimental. The Java SDK is in preview. Artifact coordinates and APIs may change.
Related skills: authoring-language-sdk-tasks (shared Python stub + concepts), configuring-airflow-language-sdks (route the queue to
JavaCoordinator), deploying-java-sdk-bundles (compile and ship the JAR).
Java tasks are paired with Python stubs that carry no logic — they declare the task, queue, dependency graph, and retries. IDs must match the Java annotations exactly, and an upstream argument on a stub only declares the dependency (the value is fetched in Java). Full rules are in authoring-language-sdk-tasks; the minimal shape:
from airflow.sdk import dag, task
@dag
def sales_pipeline(): # dag_id "sales_pipeline" -> @Builder.Dag(id="sales_pipeline")
@task.stub(queue="java")
def extract(): ... # task_id "extract" -> @Builder.Task(id="extract")
@task.stub(queue="java")
def transform(extracted): ...
transform(extract())
sales_pipeline()Both APIs produce identical runtime behavior; pick by style, and you can mix them in one bundle.
Annotate a plain class; an annotation processor generates the wiring (<ClassName>Builder) at compile time.
import static java.lang.System.Logger.Level.INFO;
import org.apache.airflow.sdk.*;
@Builder.Dag(id = "sales_pipeline") // must match the Python dag_id
public class SalesPipeline {
private static final System.Logger log = System.getLogger(SalesPipeline.class.getName());
@Builder.Task(id = "extract") // must match the Python @task.stub name
public long extract(Client client) {
var conn = client.getConnection("sales_db");
log.log(INFO, "connected to {0}", conn.host);
return 42L; // return value is pushed as the return_value XCom
}
@Builder.Task(id = "transform")
public long transform(
Client client,
@Builder.XCom(task = "extract") long recordCount) { // pulls extract's return_value
var threshold = (String) client.getVariable("transform_threshold");
return recordCount * 2;
}
@Builder.Task // id omitted -> the method name "load" is used
public void load(Context context, @Builder.XCom(task = "transform") long transformed) {
log.log(INFO, "attempt {0}, value {1}", context.ti.tryNumber, transformed);
}
}Annotation reference:
| Annotation | Purpose |
|---|---|
@Builder.Dag(id = "...") | Marks the class as a task container. id must match the Python dag_id; if omitted, the class name is used. Optional to = "..." renames the generated builder (default <ClassName>Builder). |
@Builder.Task(id = "...") | Marks a method as a task. id must match the Python @task.stub function name; if omitted, the method name is used. |
@Builder.XCom(task = "...", key = "...") | Injects an upstream task's XCom as a parameter. task defaults to the parameter name; key defaults to the producing task's return_value. The parameter type must be compatible with the stored JSON value. |
A task method's return value is automatically pushed as that task's return_value XCom. A method may declare throws Exception; any uncaught exception fails the task instance (which triggers retries if the stub configured them).
Implement Task directly when you want full control over registration and XCom handling.
import org.apache.airflow.sdk.*;
public class ExtractTask implements Task {
@Override
public void execute(Context context, Client client) throws Exception {
var conn = client.getConnection("sales_db");
// ... do work ...
client.setXCom(42L); // push return_value explicitly
}
}Register tasks manually in a Dag and expose it through a BundleBuilder:
public class MyBundle implements BundleBuilder {
@Override
public Iterable<Dag> getDags() {
var dag = new Dag("sales_pipeline"); // DAG ID matches Python
dag.addTask("extract", ExtractTask.class);
dag.addTask("transform", TransformTask.class);
return java.util.List.of(dag);
}
}Each Task class needs a public no-arg constructor. Task IDs must be unique within a DAG, and DAG IDs unique within a bundle.
Every bundle has a main that hands your DAGs to the SDK server. The server connects to the coordinator, runs one task instance, and exits.
import java.util.List;
import org.apache.airflow.sdk.*;
public class Main implements BundleBuilder {
@Override
public Iterable<Dag> getDags() {
// With the annotation API, the *Builder classes are generated at compile time.
return List.of(SalesPipelineBuilder.build());
}
public static void main(String[] args) {
Server.create(args).serve(new Main().build());
}
}Server.create(args) parses the connection details Airflow passes on the command line — don't construct them by hand. Record this main class as the bundle's main class when you build it (see deploying-java-sdk-bundles).
ClientA Client is passed into every task and is scoped to the current DAG run and task instance.
| Call | Returns | Notes |
|---|---|---|
client.getConnection(id) | Connection | Fields: id, type, host, schema, login, password, port, extra. Any unset field is null. Throws if the connection doesn't exist. |
client.getVariable(key) | Object (or null) | Cast to the type you expect, e.g. (String) client.getVariable("threshold"). |
client.getXCom(taskId) | Object (or null) | Reads another task's return_value by default. Overloads accept key, dagId, runId, mapIndex, and includePriorDates for cross-DAG/run reads and mapped tasks. |
client.setXCom(value) | — | Pushes the return_value XCom (interface API). Value must be JSON-serializable. With the annotation API, returning a value does this for you. |
ContextThe Context parameter exposes run metadata: context.dagRun (dagId, runId) and context.ti (dagId, runId, taskId, mapIndex, tryNumber). tryNumber is useful for retry-aware logic.
XComs cross the boundary as JSON (the shared contract is in authoring-language-sdk-tasks). When you read one back in Java you get:
| Python type | JSON | Java type from getXCom |
|---|---|---|
int | integer | Long (or BigInteger if too large) |
float | decimal | Double |
str | string | String |
bool | boolean | Boolean |
None | null | null |
list | array | List<Object> |
dict | object | Map<String, Object> |
Declare @Builder.XCom parameter types to match. A mismatch (e.g. declaring int when the value is a String) fails the task.
Declare a logger as a static field named after the class — the conventional pattern regardless of framework:
private static final System.Logger log = System.getLogger(SalesPipeline.class.getName());For records to reach Airflow's task log store (and show in the UI), the bundle must include one of the SDK logging integration artifacts (airflow-sdk-jpl, airflow-sdk-slf4j, airflow-sdk-log4j2, or airflow-sdk-jul). The dependencies and per-framework setup are in the logging integration section of deploying-java-sdk-bundles. System.Logger (JPL) with airflow-sdk-jpl is the lightest option and needs no configuration.
The SDK repository includes a runnable example under java-sdk/example/:
src/resources/dags/java_examples.py — Python DAGs pairing Python tasks with Java stubs, including a load stub with retries=1.src/java/.../AnnotationExample.java — annotation API, including a task that fails on tryNumber == 1 and succeeds on retry.src/java/.../InterfaceExampleBuilder.java — the same tasks via the Task interface and Dag.addTask(...).src/java/.../ExampleBundleBuilder.java — a BundleBuilder returning both DAGs plus the main entry point.Point users there for an end-to-end reference.
Object returns deliberately. getVariable and getXCom return Object; match the cast to the JSON type (see the table above).@Builder.XCom parameter types must match the stored JSON type, or the task fails at runtime.<ClassName>Builder); it is not needed for the interface API. See deploying-java-sdk-bundles.java queue to JavaCoordinator and set JRE/coordinator options.© astronomer, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in skills/authoring-java-sdk-tasks of astronomer/agents.
Open the folder on GitHubat commit 1ec1a1f
Authoring Java SDK Tasks next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Authoring Java SDK Tasks this skillastronomer/agents | 450 | — | ~2.6k | Automated safety check: Pass | Apache-2.0 | |
| Build Teaql Appteaql/teaql-agent-kit | 2.8k | — | ~4.6k | Automated safety check: Pass | MIT | |
| Crap Analyzerswingerman/engineer | 154 | — | ~1.2k | Automated safety check: Pass | MIT | |
| Geogeometry Maintainerjillesvangurp/geogeometry | 138 | — | ~419 | Automated safety check: Pass | Custom licence | |
| Senior Data Engineerbenchflow-ai/skillsbench | 1.8k | — | ~5.9k | Automated safety check: Pass | MIT | |
| Version Bumpergodatadriven/whirl | 205 | — | ~1.2k | Automated safety check: Pass | Apache-2.0 |
teaql/teaql-agent-kit
Build or change a TeaQL application in Java, Rust, Go, Swift, Python, C/.NET, or TypeScript, including Kotlin/JVM applications that consume Java-generated libraries.
swingerman/engineer
A skill your agent uses to produce a risk-based refactor + test plan for recently-changed code on a diff/branch/PR by computing CRAP (complexity × untested) on changed methods.
jillesvangurp/geogeometry
A skill your agent uses for code, build, and test changes in geogeometry to preserve multiplatform support, geospatial correctness, and strict no-new-dependencies policy.
benchflow-ai/skillsbench
World-class data engineering skill for building scalable data pipelines, ETL/ELT systems, real-time streaming, and data infrastructure.
godatadriven/whirl
Bump the Airflow or Python version across all project files.
wshobson/agents
Patterns for writing production-ready Apache Airflow DAGs: task dependencies, custom operators and sensors, local testing, and rules for what to avoid.
astronomer/agents
Queries the data warehouse with SQL and answers business questions about data.
astronomer/agents
Queries, manages, and troubleshoots Apache Airflow using the af CLI.
astronomer/agents
Guide for migrating Dagster projects to Apache Airflow 3 on Astro.
astronomer/agents
Workflow and best practices for writing Apache Airflow DAGs.
astronomer/agents
Deploys Airflow DAGs and projects. An agent skill from astronomer/agents.
astronomer/agents
Trace downstream data lineage and impact analysis. An agent skill from astronomer/agents.
Works with
Categories
Writes Airflow task logic in Java, Kotlin, or any JVM language using the Airflow Java SDK. Authoring Java SDK Tasks is an agent skill from astronomer/agents. Writes Airflow task logic in Java, Kotlin, or any JVM language using the Airflow Java SDK.
Authoring Java SDK Tasks fits situations like: the user wants to implement Airflow tasks in Java/JVM; asks about @Builder.Dag/@Builder.Task/@Builder.XCom; the Task/BundleBuilder interfaces; reading connections/variables/XComs from Java.
Run `npx skills add astronomer/agents --skill authoring-java-sdk-tasks -a claude-code`. Or copy the skill folder (skills/authoring-java-sdk-tasks in astronomer/agents) into .claude/skills/authoring-java-sdk-tasks in your project. Claude Code loads it when a task matches its description.
Run `npx skills add astronomer/agents --skill authoring-java-sdk-tasks -a codex`. Or copy the skill folder (skills/authoring-java-sdk-tasks in astronomer/agents) into .agents/skills/authoring-java-sdk-tasks in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add astronomer/agents --skill authoring-java-sdk-tasks -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/authoring-java-sdk-tasks, .gemini/skills/authoring-java-sdk-tasks, .github/skills/authoring-java-sdk-tasks and .opencode/skills/authoring-java-sdk-tasks in your project.
SKILL.md names no scripts, command-line tools or credentials: Authoring Java SDK Tasks is instructions for the agent only. Our summary lists: Python 3.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Authoring Java SDK Tasks is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 2.6k tokens (SKILL.md is roughly 10k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Authoring Java SDK Tasks: Build Teaql App (teaql/teaql-agent-kit, 2.8k stars), Crap Analyzer (swingerman/engineer, 154 stars), Geogeometry Maintainer (jillesvangurp/geogeometry, 138 stars) and Senior Data Engineer (benchflow-ai/skillsbench, 1.8k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
astronomer (a GitHub organization) maintains it in astronomer/agents, which has 450 GitHub stars. The repository holds 34 skills in this directory. The repository was last updated on October 5, 2026.
Source: astronomer/agents on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.