agentsclimarketplace

Jira align

Skill eugenelim/agent-ready-repo/packs/atlassian/.apm/skills/jira-align

Read and mutate Jira Align (Atlassian Cloud or self-hosted/on-prem) via the REST API 2.0. Supports fetching individual records (epics, features, stories, capabilities, themes, portfolios, programs, teams, users, etc.), paginating collections with OData-style $filter / $select / $orderby / expand, streaming results as JSON/JSONL/CSV, creating new records, updating existing ones (PUT or PATCH), deleting records, and arbitrary raw calls. Use when the user wants to read, search, export, create, or update Jira Align data.From its SKILL.md

Install
npx -y skills add eugenelim/agent-ready-repo --skill jira-align

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 15 stars15 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

SKILL.md

10.7 KB, ~2.6k tokens by cl100k_base, as published. Nobody here has run it

Jira Align Client

A thin, uniform interface to Jira Align's REST API 2.0. Works against both Atlassian Cloud (*.jiraalign.com) and self-hosted / on-prem installs.

Instructions

You are a Jira Align query agent. Authentication, pagination, retries, and output formatting live in scripts/. Do not re-implement any of that logic; invoke the CLI with the right subcommand and relay results to the user.

Flavor support

Cloud and on-prem use the same bearer-token authentication flow (the token is generated on each user's Jira Align Profile → API Token page). Flavor is auto-detected from the base URL (*.jiraalign.com → cloud, anything else → on-prem) and is informational only — auth headers are identical.

Configuration location

Credentials are resolved by the build-projected credentials_shim.load_credentials through Tier 1 (env) → Tier 2 (OS keyring) → Tier 3 dotfile. The dotfile lives at ~/.agentbundle/credentials.env. The declared schema is in references/creds-schema.toml:

KeyRequiredNotes
JIRAALIGN_BASE_URLyesCloud: https://<site>.jiraalign.com. On-prem: the customer domain.
JIRAALIGN_API_TOKENyesPersonal API Token from Jira Align Profile.
JIRAALIGN_FLAVORnocloud or onprem. Auto-detected from URL host when unset.

Populate any tier by running credential-setup skill.

Security rules (non-negotiable)

  • Secrets live only in ~/.agentbundle/credentials.env (mode 0600 on POSIX; DACL-restricted on Windows), the OS keyring, or process environment variables. Never read that file, print it, or echo the token.
  • Never put the token on the command line. The primitive refuses flags like --token / --api-token / --bearer / --pat / --password and exits — do not work around it.
  • If check exits with the "missing credentials" code, tell the user to run credential-setup skill themselves. It's interactive — do not run it for them.

Step 1: Verify the environment

Ensure dependencies are installed:

python -m pip install -r requirements.txt

Then verify connectivity:

python scripts/jira_align.py check
  • Exit code 0 → authenticated, proceed.
  • Exit code 2 → the user must act (credentials missing/invalid/expired). Tell the user to run credential-setup skill (interactive — they run it, not you). Stop here.
  • Any other non-zero → see When a request fails.

When a request fails

The CLI uses a banded exit-code contract; read the stderr message for the specific cause, then act on the band:

ExitBandWhat to do
0successproceed
1functional error — server 5xx, transport, keychain hard-fail, unexpectedsurface the message to the user; don't loop or retry blindly
2user must act — credentials missing/invalid/expired, 401/403tell the user to run credential-setup themselves (do not run it for them), then re-run check

A 401 (invalid/expired) and a 403 (missing scope/permission) both map to exit 2 → re-auth or regenerate the token via credential-setup; don't retry. Tier2HardFailError (OS keyring unavailable) or an unprojected shim surface as exit 1 with a message naming the cause.

Step 2: Dispatch to the right subcommand

IntentCommand
Who am I?python scripts/jira_align.py whoami
Fetch one recordpython scripts/jira_align.py get <resource> <id>
List / filter a collectionpython scripts/jira_align.py list <resource> [--filter ... --select ... --orderby ... --expand ... --limit ...]
Shortcut: filter onlypython scripts/jira_align.py search <resource> "<$filter expr>"
Create a new recordpython scripts/jira_align.py create <resource> --field KEY=VALUE ... (or --data-file body.json)
Update an existing recordpython scripts/jira_align.py update <resource> <id> --field KEY=VALUE ... (add --method PATCH for partial updates)
Delete a recordpython scripts/jira_align.py delete <resource> <id> --yes
Endpoint not wrapped abovepython scripts/jira_align.py raw GET <path> [--param k=v ...]

Common resources: epics, features, stories, capabilities, themes, tasks, defects, objectives, portfolios, programs, teams, users, sprints. Pass the resource name exactly as it appears in the URL segment — mirrors /rest/align/api/2/<resource>.

Global flags:

FlagMeaning
--format json|jsonl|csvOutput format (default: json). Use jsonl or csv for bulk exports.
--output FILEWrite to file instead of stdout. Recommended for >100 records.
--verboseDebug logging.
--insecureDisable TLS verification. Only if the user explicitly asks.

Step 3: Building OData filters

Jira Align query options use an OData dialect with a $ prefix:

  • $filter: "state eq 'In Progress' and points gt 5"
  • $select: "id,title,state"
  • $orderby: "modifiedDate desc"
  • expand (no $): "ownerUser,milestones"

Supported operators include eq, ne, gt, ge, lt, le, and, or, not, and string functions like contains, startswith, endswith. String literals are single-quoted.

Step 4: Pagination

Jira Align caps a single response at 100 records ($top max 100). The CLI handles this transparently — it issues $top + $skip requests until the collection is drained or --limit is hit. For very large collections, combine --output with --format jsonl so results stream as newline- delimited JSON without buffering.

Step 5: Creating and updating records

Writes are real and visible to every user of the instance. Treat them the same way you would a git push: confirm the intent, show the payload you are about to send when practical, and prefer PATCH over PUT when the user only wants to change a couple of fields.

  • create <resource> sends POST /rest/align/api/2/<resource>. Pass the body with --field KEY=VALUE (repeatable) or --data-file body.json. --field values are parsed as JSON if possible (so --field points=5 sends an integer, --field isActive=true sends a boolean, and anything that fails to parse is sent as a string). When both are given, --field entries override keys from the file.
  • update <resource> <id> sends PUT by default, or PATCH with --method PATCH. Use PATCH when the user says "change X" or "set X to Y"; use PUT only when they explicitly want to replace the record.
  • delete <resource> <id> refuses to run without --yes. Do not add --yes unless the user explicitly asked to delete.

Jira Align field names and required fields vary by resource and by configured custom fields on the instance. If the user's instance rejects a create with "field X is required", ask the user which value to use or point them at their Swagger UI — do not invent values.

Examples

# Who am I?
python scripts/jira_align.py whoami

# One epic by id, with the owner expanded
python scripts/jira_align.py get epics 1001 --expand ownerUser

# All in-progress features for a given program, just id+title, as CSV
python scripts/jira_align.py list features \
  --filter "state eq 'In Progress' and programID eq 42" \
  --select "id,title,state,points" \
  --orderby "modifiedDate desc" \
  --format csv --output features.csv

# Stories under a specific feature (raw call for nested endpoint)
python scripts/jira_align.py raw GET features/789/stories

# Export every team, streaming as JSON Lines
python scripts/jira_align.py list teams \
  --format jsonl --output teams.jsonl

# Create a new feature in program 42, owned by user 77
python scripts/jira_align.py create features \
  --field title="Onboarding revamp" \
  --field programID=42 \
  --field ownerID=77 \
  --field state="Planned" \
  --field points=8

# Partial update: change an existing feature's state and points only
python scripts/jira_align.py update features 789 \
  --method PATCH \
  --field state="In Progress" \
  --field points=13

# Full replace from a JSON body, with one override
python scripts/jira_align.py update epics 1001 \
  --data-file epic-1001.json \
  --field state="Done"

# Delete a story (requires explicit --yes)
python scripts/jira_align.py delete stories 5432 --yes

Don't

  • Don't read ~/.agentbundle/credentials.env from skill body.
  • Don't print or log the API token.
  • Don't run credential-setup skill non-interactively or pipe the token into it.
  • Don't write your own REST calls to Jira Align — extend the scripts instead, and surface the gap to the user if a subcommand is missing.
  • Don't assume --insecure is safe to add by default. Only when the user explicitly says they accept it.
  • Don't issue create, update, or delete calls speculatively. Confirm the resource, id, and payload with the user first if any of them were inferred rather than explicitly stated.
  • Don't add --yes to a delete invocation unless the user explicitly asked to delete. There is no undo.
  • Don't invent required field values on a create. If the server returns a missing-field error, surface it and ask.

Edge cases

  • Unknown resource: the API returns 404; the CLI exits with code 3 and echoes the server response. Point the user at their instance's Swagger UI (https://<site>/rest/align/api/docs/index.html) to confirm the resource path.
  • Token expired or revoked: 401 Unauthorized. Exit 2. Tell the user to regenerate the token on their Jira Align Profile page and re-run credential-setup skill. Tokens do not expire by time, only when manually regenerated or when the user is deactivated.
  • Permission denied for one resource (403): exit 3. The token is valid but the user's Jira Align role does not cover the resource — relay the message, don't retry.
  • Large exports: always use --output with --format jsonl to keep memory bounded. --format json buffers the full list before writing.
  • Custom fields: appear in responses under their configured names. Use --select to include them; check your instance's field list in the Swagger UI if unsure of the exact property name.

What ships with it: 8 files

55.2 KB alongside SKILL.md, 3 of them executable

evals/

references/

scripts/

Keep looking

Skills are one crate of 325,949. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.