Metadata-Version: 2.4
Name: atlassian-skills-alm
Version: 0.3.0
Summary: Token-efficient CLI + Claude Code Skill for the Atlassian Server/DC ALM stack — Jira, Confluence, Bitbucket, Bamboo, and Codebeamer (fork of atlassian-skills with Codebeamer support).
Project-URL: Repository, https://github.com/illusoriso/atlassian_ALM-skills
Project-URL: Issues, https://github.com/illusoriso/atlassian_ALM-skills/issues
Author: Eunsan Jo
License-Expression: MIT
License-File: LICENSE
Keywords: atlassian,bamboo,bitbucket,claude-code,cli,codebeamer,confluence,jira,mcp-alternative
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Developers
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Python: >=3.10
Requires-Dist: cfxmark>=0.4
Requires-Dist: httpx>=0.27
Requires-Dist: platformdirs
Requires-Dist: pydantic>=2.5
Requires-Dist: rich>=13
Requires-Dist: tomli-w
Requires-Dist: tomli; python_version < '3.11'
Requires-Dist: typer>=0.12
Provides-Extra: keyring
Requires-Dist: keyring>=24; extra == 'keyring'
Description-Content-Type: text/markdown

# atlassian-skills-alm

[![PyPI version](https://img.shields.io/pypi/v/atlassian-skills-alm?color=blue)](https://pypi.org/project/atlassian-skills-alm/)
[![Python versions](https://img.shields.io/pypi/pyversions/atlassian-skills-alm)](https://pypi.org/project/atlassian-skills-alm/)
[![PyPI downloads](https://img.shields.io/pypi/dm/atlassian-skills-alm)](https://pypi.org/project/atlassian-skills-alm/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://opensource.org/licenses/MIT)
[![CI](https://github.com/illusoriso/atlassian_ALM-skills/actions/workflows/ci.yml/badge.svg)](https://github.com/illusoriso/atlassian_ALM-skills/actions/workflows/ci.yml)
[![GitHub stars](https://img.shields.io/github/stars/illusoriso/atlassian_ALM-skills?style=flat&color=yellow)](https://github.com/illusoriso/atlassian_ALM-skills/stargazers)

> Fork of [atlassian-skills](https://github.com/eunsanMountain/atlassian-skills) extending it with **Codebeamer (Swarm REST v3)** support for the broader ALM stack. CLI binary name (`atls`) is unchanged.

A token-efficient CLI that brings [mcp-atlassian](https://github.com/sooperset/mcp-atlassian) functionality to the command line — optimized for LLM agent workflows on Atlassian Server/DC.

mcp-atlassian is great for Cloud setups, but on Server/DC its MCP protocol overhead and verbose JSON responses consume tokens fast. It also lacks lossless Confluence markup round-tripping — edits via MCP can silently alter page content.

**atlassian-skills-alm** re-implements the same Jira and Confluence operations as a lightweight CLI with compact output, achieving **≥50% token reduction**, and adds **Codebeamer (Swarm REST v3)** for the broader ALM stack. It uses [cfxmark](https://github.com/eunsanMountain/cfxmark) for **lossless Confluence XHTML ↔ Markdown conversion**, enabling agents to pull a page as Markdown, edit it, and push it back without any content loss.

First-class integration with **Claude Code** and **Codex**. `atls setup all` registers atls as the default Atlassian tool for both — a comprehensive usage guide (command tree, format decision rules, write safety) is loaded via Claude's `/atls` slash command or Codex's auto-loaded skill, while a short preference directive in `CLAUDE.md` / `AGENTS.md` keeps the routing rule active in every conversation. Your agent translates "read PROJ-123" or "update the API page" into the right CLI call without further configuration.

## Why atlassian-skills-alm?

| | mcp-atlassian (MCP) | atlassian-skills-alm (CLI) |
|---|---|---|
| Interface | MCP protocol (JSON-RPC) | Shell CLI (`atls`) |
| Schema overhead per session | ~15,000 tokens | <400 tokens |
| Response payload size | Full JSON | 7–34% of MCP |
| Full workflow (end-to-end) | Baseline | 91% reduction |
| Confluence markup round-trip | Lossy (XHTML re-serialization) | Lossless via cfxmark (XHTML ↔ Markdown) |
| Jira body preservation | Drops special chars | Byte-preserving |
| Server/DC support | Partial | Full (primary target) |
| AI agent setup | Manual MCP config | One-line `atls setup all` for Claude Code + Codex |
| Bitbucket Server | Not supported | Full (0.2.0) — PR workflow, comments, tasks, build status |
| Bamboo | Not supported | Planned |
| Codebeamer Swarm REST v3 | Not supported | Full (0.3.0) — items, cbQL search, associations |

## Installation

**Recommended: `uv tool install`** — isolates atls in its own environment and makes `atls upgrade` a single command. `pipx` (the pip-world equivalent of `uv tool`) and plain `pip` also work; `atls upgrade` auto-detects all three.

### Step 1 — install your package manager (skip if you already have it)

Pick **one**: `uv` (recommended) or `pipx`. If you'll use plain `pip`, skip this step entirely.

<details open>
<summary><b>Option A — install <code>uv</code> (recommended)</b></summary>

**Linux / macOS**
```bash
curl -LsSf https://astral.sh/uv/install.sh | sh
```

**Windows (PowerShell)**
```powershell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

Alternatives: `brew install uv` (macOS), `winget install astral-sh.uv` (Windows), `pipx install uv` (cross-platform). Full options in the [uv installation docs](https://docs.astral.sh/uv/getting-started/installation/).
</details>

<details>
<summary><b>Option B — install <code>pipx</code></b></summary>

**Linux / macOS**
```bash
python3 -m pip install --user pipx
python3 -m pipx ensurepath
```

**Windows (PowerShell)**
```powershell
python -m pip install --user pipx
python -m pipx ensurepath
```

Alternatives: `apt install pipx` (Ubuntu 23.04+), `brew install pipx` (macOS), `scoop install pipx` or `winget install pipx` (Windows). Full options in the [pipx installation docs](https://pipx.pypa.io/stable/installation/).

After `ensurepath`, open a new terminal so the updated `PATH` is picked up.
</details>

### Step 2 — install atls

```bash
# Recommended — fastest, fully isolated
uv tool install atlassian-skills-alm

# Alternative — pipx (pip-world equivalent of `uv tool`, also isolated per tool)
pipx install atlassian-skills-alm

# Plain pip (installs into the current Python env; not recommended for CLI tools)
pip install atlassian-skills-alm

# Verify
atls --version

# Later — upgrade the CLI (auto-detects uv / pipx / pip) and refresh skill assets
atls upgrade
```

## Authentication

Server/DC only. Personal Access Token (PAT / Bearer) is the default auth method for Jira / Confluence / Bitbucket. Codebeamer Server does not issue PATs, so atls uses **Basic auth** (username + password) for Codebeamer by default — no extra configuration required.

### 1. Create access tokens

Generate tokens from your Atlassian instances:
- **Jira**: Profile → Personal Access Tokens → Create
- **Confluence**: Profile → Personal Access Tokens → Create
- **Bitbucket**: Profile → Manage Account → HTTP access tokens → Create (permissions: project read, repository read/write)
- **Codebeamer**: no token needed — your Codebeamer account username + password is enough

### 2. Configure server URLs

```bash
atls config set profiles.default.jira_url https://your-jira.example.com
atls config set profiles.default.confluence_url https://your-confluence.example.com
atls config set profiles.default.bitbucket_url https://your-bitbucket.example.com
atls config set profiles.default.codebeamer_url https://your-codebeamer.example.com/cb/api
```

Or via environment variables:

```bash
export ATLS_DEFAULT_JIRA_URL="https://your-jira.example.com"
export ATLS_DEFAULT_CONFLUENCE_URL="https://your-confluence.example.com"
export ATLS_DEFAULT_BITBUCKET_URL="https://your-bitbucket.example.com"
export ATLS_DEFAULT_CODEBEAMER_URL="https://your-codebeamer.example.com/cb/api"
```

For non-default profiles, replace `DEFAULT` with the profile name (e.g. `ATLS_CORP_JIRA_URL`).

> **Codebeamer URL** — accepts any of `https://host`, `https://host/cb`, `https://host/cb/api`, `https://host/cb/api/v3`. atls auto-normalizes to the v3 root.

### 3. Set credentials

**Environment variables (recommended)**

Add to `~/.zshrc` or `~/.bashrc`:

```bash
# Jira / Confluence / Bitbucket — PAT (compatible with existing MCP servers)
export JIRA_PERSONAL_TOKEN="your-jira-pat"
export CONFLUENCE_PERSONAL_TOKEN="your-confluence-pat"
export BITBUCKET_TOKEN="your-bitbucket-http-access-token"

# Codebeamer — Basic auth (id + password)
export CODEBEAMER_USERNAME="your-codebeamer-id"
export CODEBEAMER_PASSWORD="your-codebeamer-password"
```

For multi-profile setups:
```bash
export ATLS_CORP_JIRA_TOKEN="..."
export ATLS_CORP_CONFLUENCE_TOKEN="..."
export ATLS_CORP_BITBUCKET_TOKEN="..."
export ATLS_CORP_CODEBEAMER_USER="..."
export ATLS_CORP_CODEBEAMER_TOKEN="..."   # password goes here for Codebeamer
```

<details>
<summary>Secure file-based storage (alternative to plain env vars)</summary>

```bash
mkdir -p ~/.secrets && chmod 700 ~/.secrets
printf '%s' 'YOUR_JIRA_PAT'       > ~/.secrets/jira_pat
printf '%s' 'YOUR_CONFLUENCE_PAT' > ~/.secrets/confluence_pat
printf '%s' 'YOUR_BITBUCKET_PAT'  > ~/.secrets/bitbucket_pat
chmod 600 ~/.secrets/*_pat

# Then in ~/.zshrc or ~/.bashrc:
[ -f ~/.secrets/jira_pat ]       && export JIRA_PERSONAL_TOKEN="$(cat ~/.secrets/jira_pat)"
[ -f ~/.secrets/confluence_pat ] && export CONFLUENCE_PERSONAL_TOKEN="$(cat ~/.secrets/confluence_pat)"
[ -f ~/.secrets/bitbucket_pat ]  && export BITBUCKET_TOKEN="$(cat ~/.secrets/bitbucket_pat)"
```
</details>

<details>
<summary>Windows — native equivalents (System Properties GUI / PowerShell / setx)</summary>

atls runs natively on Windows; the only platform-specific piece is how you set environment variables. Pick whichever of the three Windows-native paths you prefer — all produce the same result as the `export` snippets above.

**System Properties GUI (recommended — permanent, no dotfile)**

Press `Win + R` → type `sysdm.cpl` → **Advanced** tab → **Environment Variables** → under **User variables** click **New**:

- `JIRA_PERSONAL_TOKEN` = `<your-pat>`
- `CONFLUENCE_PERSONAL_TOKEN` = `<your-pat>`
- `BITBUCKET_TOKEN` = `<your-http-access-token>`
- `CODEBEAMER_USERNAME` = `<your-codebeamer-id>` and `CODEBEAMER_PASSWORD` = `<your-password>`
- `ATLS_DEFAULT_JIRA_URL` = `https://your-jira.example.com` (and `*_CONFLUENCE_URL`, `*_BITBUCKET_URL`, `*_CODEBEAMER_URL`)

Open a *new* terminal afterward — existing shells and IDEs do not see the change until restarted.

**PowerShell (current session only)**

```powershell
$env:ATLS_DEFAULT_JIRA_URL = "https://your-jira.example.com"
$env:JIRA_PERSONAL_TOKEN   = "your-jira-pat"
```

**PowerShell (permanent, picked up by new sessions)**

```powershell
[Environment]::SetEnvironmentVariable("JIRA_PERSONAL_TOKEN", "your-jira-pat", "User")
[Environment]::SetEnvironmentVariable("ATLS_DEFAULT_JIRA_URL", "https://your-jira.example.com", "User")
```

**cmd / `setx` (permanent)**

```cmd
setx JIRA_PERSONAL_TOKEN "your-jira-pat"
setx ATLS_DEFAULT_JIRA_URL "https://your-jira.example.com"
```

> `atls config set ...` works identically on Windows — config is stored at `%APPDATA%\atlassian-skills\config.toml` via `platformdirs`. Tokens, however, must live in environment variables (config-based token storage is not yet implemented).
</details>

<details>
<summary>Basic auth (legacy instances without PAT support)</summary>

Older Jira (< 8.14) and Confluence (< 7.9) predate Personal Access Tokens. For those, switch to Basic auth with username + password (or API token):

```bash
export ATLS_DEFAULT_JIRA_AUTH=basic
export ATLS_DEFAULT_JIRA_USER=myname
export ATLS_DEFAULT_JIRA_TOKEN=<password-or-api-token>
```

Or persist in config:

```bash
atls config set profiles.default.auth.jira basic
```

The same `*_AUTH=basic` / `*_USER` / `*_TOKEN` triple works for `jira`, `confluence`, and `bitbucket`. On Windows, set the three variables via the GUI or `setx` as shown above.
</details>

**Priority**: CLI flags > `ATLS_*` vars > standard names (`JIRA_PERSONAL_TOKEN`, `CONFLUENCE_PERSONAL_TOKEN`, `BITBUCKET_TOKEN`, `CODEBEAMER_USERNAME` + `CODEBEAMER_PASSWORD`) > config file

### 4. Verify

```bash
atls auth status
```

## Quick Start

### 1. Set up your AI agent

```bash
atls setup all        # installs atls skill for Claude Code + Codex
atls auth status      # verify connection
```

**What gets installed:**
- **Claude Code**: `~/.claude/commands/atls.md` (full usage guide, load with `/atls`) + preference directive in `~/.claude/CLAUDE.md` (active every conversation, tells Claude to route Atlassian work through atls and navigate with `--help`).
- **Codex**: `~/.agents/skills/atls/SKILL.md` (auto-loaded skill with command tree, format rules, write-safety protocol) + routing directive in `~/.codex/AGENTS.md`.
- Run `atls setup status` to check what is installed.
- Run `atls setup paths` to see every resolved install path for your platform.

**Install paths (Windows / macOS / Linux):**

`atls` resolves install paths in this order — interactive override → environment variable → platform default. No extra configuration is required on any OS; `Path.home()` expands to `%USERPROFILE%` on Windows and `$HOME` on macOS/Linux.

| Target | Env var override | Default (Windows) | Default (macOS / Linux) |
|---|---|---|---|
| Claude config dir | `CLAUDE_CONFIG_DIR` | `C:\Users\<you>\.claude` | `~/.claude` |
| Codex config dir | `CODEX_HOME` | `C:\Users\<you>\.codex` | `~/.codex` |
| Agents skill dir | `AGENTS_HOME` | `C:\Users\<you>\.agents` | `~/.agents` |

To customize at install time, run any setup command with `--interactive` (or `-i`):

```bash
atls setup all --interactive
# Detected platform: windows
# Claude config dir: C:\Users\you\.claude  (source: default)
#   Press Enter to accept, or paste a custom path: D:\Tools\Claude
#   → using: D:\Tools\Claude
# Codex config dir: C:\Users\you\.codex  (source: default)
#   ...
```

Alternatively, export environment variables before running setup:

```bash
# Windows (PowerShell)
$env:CLAUDE_CONFIG_DIR = "D:\Tools\Claude"
$env:CODEX_HOME = "D:\Tools\Codex"
atls setup all

# macOS / Linux
export CLAUDE_CONFIG_DIR=~/work/claude
atls setup all
```

**Codex users note:** the Codex skill installs to `<AGENTS_HOME>/skills/atls/` (primary) and `<CODEX_HOME>/skills/atls/` (legacy compatibility). The routing directive in `AGENTS.md` keeps `atls` as the default Atlassian tool across conversations. Codex's session-start mechanism auto-loads `SKILL.md` — no manual load required.

### 2. Talk to your agent in natural language

Once set up, your AI agent knows how to use atls automatically. Just ask:

> "Read PROJ-123 and summarize the acceptance criteria."
>
> "Search for open bugs in the PLATFORM project assigned to me."
>
> "Pull the API Overview page from Confluence, add a rate-limiting section, and push it back."
>
> "Create a Story in PROJ: title 'Add retry logic to payment service', and paste the description from desc.md."
>
> "What changed on the Release Notes page since last week?"

The agent translates these into `atls` CLI calls, picks the right output format, and handles pagination and error codes for you.

### 3. Or use the CLI directly

```bash
# Jira
atls jira issue get PROJ-1
atls jira issue search "project=PROJ AND status=Open" --limit=20
atls jira issue create --project PROJ --type Story --summary "New feature" --body-file=story.md --body-format=md

# Confluence
atls confluence page get 12345
atls confluence page search "space=DOCS AND title=API"
atls confluence page push-md 12345 --md-file=page.md --if-version 15
atls confluence page pull-md 12345 --output=page.md --resolve-assets=sidecar --asset-dir=assets/

# Jira description from markdown
atls jira issue update PROJ-1 --body-file=desc.md --body-format=md --heading-promotion=jira

# Jira comment / worklog from markdown
atls jira comment add PROJ-1 --body-file=comment.md --body-format=md
atls jira comment edit PROJ-1 12345 --body-file=comment.md --body-format=md
atls jira worklog add PROJ-1 --time-spent-seconds 1800 --comment "$(cat note.md)" --comment-format=md

# Codebeamer
atls codebeamer item get 1234567                                        # read a single item
atls codebeamer item children 1234567                                   # list children of an item
atls codebeamer item search "tracker.id IN (6289127)" --page-size 10    # cbQL search
atls codebeamer association list-types
atls codebeamer item create 6289127 --body @new-item.json --dry-run     # preview new tracker item
```

### Agent usage tips

```bash
# 1. Token-efficient: compact format is the default (no extra flags needed)
atls jira issue search "project=PROJ AND status=Open"

# 2. Use md format only when you need to read the body
atls jira issue get PROJ-1 -f md

# 3. Use json format for automation/parsing
atls jira issue get PROJ-1 -f json | jq '{key, summary, status}'

# 4. Confluence page editing workflow
atls confluence page pull-md PAGE_ID -o page.md --resolve-assets=sidecar --asset-dir=assets/
# ... edit locally ...
atls confluence page push-md PAGE_ID --md-file page.md --if-version 15 --dry-run
atls confluence page push-md PAGE_ID --md-file page.md --if-version 15

# 5. Branch on exit codes
# 0=OK, 2=not found, 5=stale version, 6=auth failure, 11=rate limited
```

## Output Formats

| Format | Flag | Use case |
|---|---|---|
| compact | default | LLM scanning, minimal tokens |
| json | `--format=json` | Automation, structured parsing |
| md | `--format=md` | Body/description reading |
| raw | `--format=raw` | Byte-preserving body access |

`--format` can be placed globally or locally on subcommands:

```bash
# Global placement
atls --format=json jira issue get PROJ-1

# Local placement (preferred for readability)
atls jira issue get PROJ-1 --format=json
```

> Some commands use `-f` for file input (e.g. `push-md`). After the subcommand, always use the long form `--format=` to avoid ambiguity.

## Command Reference

### Jira (45 commands: 22 read + 23 write)
- `jira issue get|search|create|update|delete|transition|transitions|dates|sla|images`
- `jira comment add|edit`
- `jira field search|options`
- `jira project list|issues|versions|components|versions-create`
- `jira board list|issues`
- `jira sprint list|issues|create|update|add-issues`
- `jira link list-types|create|remote-list|remote-create|delete`
- `jira epic link`
- `jira watcher list|add|remove`
- `jira worklog list|add`
- `jira attachment download|upload|delete`
- `jira dev-info get|get-many`
- `jira service-desk list|queues|queue-issues`
- `jira user get`

### Confluence (23 commands: 13 read + 10 write)
- `confluence page get|search|children|history|diff|images|create|update|delete|move|push-md|pull-md|diff-local`
- `confluence space tree`
- `confluence comment list|add|reply`
- `confluence label list|add`
- `confluence attachment list|download|download-all|upload|upload-batch|delete`
- `confluence user search`

> `--passthrough-prefix` is supported on Confluence markdown round-trip commands only: `push-md`, `pull-md`, `diff-local`.

### Bitbucket (33 commands: 11 read + 22 write)
- `bitbucket project list`
- `bitbucket repo list|get`
- `bitbucket pr list|get|diff|comments|commits|activity|create|update|merge|decline|approve|unapprove|needs-work|reopen|diffstat|statuses|pending-review`
- `bitbucket branch list`
- `bitbucket file get`
- `bitbucket comment add|reply|update|delete|resolve|reopen`
- `bitbucket task list|get|create|update|delete`

> All write commands support `--dry-run`. PR diff and file get treat `--format=md` as raw text passthrough.

### Codebeamer (16 commands: 8 read + 8 write — Swarm REST v3)
- `codebeamer item get|children|search|search-advanced|relations`
- `codebeamer item create|update|delete|patch-children|bulk-update`
- `codebeamer association list-types|get|history`
- `codebeamer association create|update|delete`

> Default auth is **Basic** (username + password) — Codebeamer Server does not issue PATs. atls reads
> `CODEBEAMER_USERNAME` + `CODEBEAMER_PASSWORD` (compatible with the existing `alm-mcp-stdio` `.env`)
> or `ATLS_<PROFILE>_CODEBEAMER_USER` + `ATLS_<PROFILE>_CODEBEAMER_TOKEN` for multi-profile setups.
> Searches use **cbQL** (e.g. `tracker.id IN (1234)`). Write commands accept `--body '{...}'` or
> `--body @file.json` and all support `--dry-run`.

### Utility
- `auth login|status|list`
- `config get|set|path`
- `setup codex|claude|all|status|paths` (add `--interactive` to customize install paths per-platform)
- `upgrade`
- `version [--check]` — show installed version; `--check` compares against the latest PyPI release (exit 1 if outdated)

## Write Safety

All write commands support:
- `--dry-run`: Preview without executing
- `--body-file=-`: Pipe body content via stdin
- `--if-version N`: Optimistic concurrency (Confluence page update & push-md)
- `--if-updated ISO`: Stale check (Jira)
- `--attachment-if-exists skip|replace`: Duplicate attachment handling (push-md)
- `--asset-dir DIR`: Batch upload all files in a directory (push-md)

## Jira Custom Fields

For scripting, explicitly requested `customfield_*` keys are preserved in JSON output:

```bash
atls jira issue get PROJ-1 --fields=summary,customfield_10100 --format=json
atls jira issue search "project=PROJ" --fields=summary,customfield_10100 --format=json
```

For writes, `--set-customfield` verifies the result with a read-back check and exits with a validation error if Jira accepts the request but does not apply the value:

```bash
atls jira issue update PROJ-1 --set-customfield customfield_10100=EPIC-1
```

If the field expects a structured payload instead of a plain string/key, use `--fields-json` instead of `--set-customfield`.

## Migrating from mcp-atlassian

atlassian-skills-alm is a CLI re-implementation of mcp-atlassian's Jira and Confluence operations (plus Codebeamer). If you are currently using mcp-atlassian, here is what changes:

| mcp-atlassian | atlassian-skills-alm |
|---|---|
| MCP protocol (JSON-RPC over stdio) | Shell CLI (`atls <command>`) |
| Full JSON responses every call | `compact` by default, `json`/`md`/`raw` on demand |
| ~15k token schema overhead per session | <400 tokens (CLI help only when needed) |
| `JIRA_PERSONAL_TOKEN` env var | Same env var works, plus `ATLS_*` for multi-profile |
| Cloud + Server/DC | Server/DC only (primary target) |
| Separate Jira wiki / Confluence XHTML handling | Unified via `cfxmark` — single dependency for all markup |
| Confluence edits can silently alter content | Lossless XHTML ↔ Markdown round-trip via cfxmark |
| Silent character dropping in Jira descriptions | Byte-preserving `--format=raw` mode |

**Token-compatible auth**: If you already have `JIRA_PERSONAL_TOKEN` and `CONFLUENCE_PERSONAL_TOKEN` set for mcp-atlassian, atls picks them up automatically — no reconfiguration needed.

## Architecture

- **CLI-first**: All functionality accessible via the `atls` binary. AI agent skills are thin wrappers that invoke CLI commands.
- **Single HTTP client**: `httpx`-based `BaseClient` with retry (429/5xx), pagination, and auth.
- **cfxmark integration**: Lossless Confluence XHTML ↔ Markdown ↔ Jira wiki conversion via a single dependency. Pages survive unlimited round-trips (`pull-md` → edit → `push-md`) with zero content drift.
- **Pydantic v2 models**: Strict response parsing for stable fields, with Jira `customfield_*` passthrough in JSON output.

## Key Dependencies

| Package | Purpose |
|---|---|
| httpx | REST client (sync) |
| typer + rich | CLI framework |
| pydantic | Response models |
| cfxmark ≥ 0.4 | Markup conversion (Jira wiki + Confluence XHTML) |
| platformdirs | Config path resolution |

## Development

```bash
# Setup
uv sync

# Local install (editable)
uv tool install -e .              # from repo root
uv tool install --force -e .      # reinstall after entrypoint changes

# Test
uv run pytest

# Lint
uv run ruff check src/ tests/
uv run mypy src/

# Build
uv build
```

## Roadmap

- **0.1.x**: Jira + Confluence read/write, push-md/pull-md/diff-local, benchmarks, skills, GitHub Actions CI/release
- **0.2.0**: Bitbucket Server/DC — PR workflow (create, review, comment, merge, diff, tasks, build status)
- **0.3.0** (current): Codebeamer (Swarm REST v3) — items, cbQL search, associations, with `--dry-run` on every write
- **0.4.0**: Bamboo + workflow skills
- **0.5.0+**: Async client, caching

## License

[MIT](./LICENSE)
