Skip to content

Latest commit

 

History

History
2159 lines (1610 loc) · 72.8 KB

File metadata and controls

2159 lines (1610 loc) · 72.8 KB

omni-dev User Guide

A comprehensive guide to using omni-dev's AI-powered commit message intelligence.

Table of Contents

  1. Your First Improvement
  2. Getting Started
  3. Core Concepts
  4. Command Reference
  5. Claude Code Integration
  6. Atlassian Integration
  7. Datadog Integration
  8. Gmail Integration
  9. Contextual Intelligence
  10. Workflows
  11. Advanced Usage
  12. Best Practices

Your First Improvement

The fastest way to learn omni-dev is to run it on a throwaway commit you control end to end. This tutorial takes about 5 minutes in any git repo and walks through the three core commands — view, twiddle, check.

First-time setup (install + auth + .omni-dev/) is covered in Getting Started. This tutorial assumes you've done that already.

Step 1 — Make a deliberately bad commit on a scratch branch

git checkout -b omni-dev-tutorial
echo "" >> README.md
git add README.md
git commit -m "wip"

Step 2 — Inspect it with view

omni-dev git commit message view 'HEAD~1..HEAD'

Expected: YAML output describing the commit, its diff, and the field-presence summary. Skim it — you don't have to read it all.

Step 3 — Improve it with twiddle

omni-dev git commit message twiddle 'HEAD~1..HEAD'

Expected: omni-dev prints a suggested rewritten message (something like docs(readme): add trailing newline), shows a before/after diff, and prompts Apply these amendments? [y/N]. Press y.

Step 4 — Verify with git log

git log --oneline HEAD~1..HEAD

Expected: the subject line is now the AI-suggested message.

Step 5 — Validate against your guidelines with check

omni-dev git commit message check 'HEAD~1..HEAD'

Expected: the check passes (exit 0). If you have project-specific scopes in .omni-dev/scopes.yaml that the suggestion didn't use, re-run twiddle — see the Configuration Guide to teach omni-dev about your scopes.

Cleanup

git checkout - && git branch -D omni-dev-tutorial

What just happened

You ran the three core commands — view (analyse), twiddle (improve), check (validate) — that together cover the full omni-dev workflow. Everything else in this guide builds on these three.

Getting Started

Prerequisites

  1. Install omni-dev

    cargo install omni-dev
  2. Authenticate. By default, export CLAUDE_API_KEY="sk-ant-...". See Authentication for the full reference (alternative env-var names, .env files, CI/CD secrets, non-Anthropic backends).

  3. Verify Installation

    omni-dev --version
    omni-dev help-all  # See all available commands

First Use

Transform your commit messages and create professional PRs in 4 steps:

# 1. Navigate to your git repository
cd your-project

# 2. Improve recent commits with AI intelligence
omni-dev git commit message twiddle 'HEAD~5..HEAD' --use-context

# 3. Review and apply the suggestions
# The tool will show you before/after and ask for confirmation

# 4. Create a professional PR with AI-generated description
omni-dev git branch create pr
# Analyzes your commits and generates comprehensive PR description

Core Concepts

The Four-Command Workflow

omni-dev follows a simple analyze → improve → apply → ship workflow:

# 📊 ANALYZE: See detailed commit information
omni-dev git commit message view 'HEAD~3..HEAD'

# 🤖 IMPROVE: Get AI-powered suggestions
omni-dev git commit message twiddle 'HEAD~3..HEAD' --use-context

# ✏️ APPLY: Apply specific amendments manually
omni-dev git commit message amend amendments.yaml

# 🚀 SHIP: Create professional PR with AI description
omni-dev git branch create pr

Key Benefits

  • Contextual: Understands your project structure and conventions
  • Safe: Always asks for confirmation before making changes
  • Intelligent: Uses actual code changes, not just file names
  • Batch-Aware: Handles large commit ranges efficiently
  • Professional: Generates conventional commit format

Command Reference

twiddle - AI-Powered Improvement

The main command for improving commit messages:

# Basic usage with contextual intelligence
omni-dev git commit message twiddle 'origin/main..HEAD' --use-context

# Common options
omni-dev git commit message twiddle [RANGE] [OPTIONS]

Key Options:

Option Description Example
--fresh Ignore existing messages and generate fresh ones from the diffs alone (the default; conflicts with --refine) --fresh
--refine Use the existing messages as the starting point for AI refinement (conflicts with --fresh) --refine
--use-context Enable AI contextual intelligence --use-context
--work-context TEXT Describe the work being done to steer suggestions --work-context "feature: user auth"
--branch-context TEXT Override the context detected from the branch name --branch-context "bugfix: login flow"
--context-dir PATH Custom context directory --context-dir ./config
--no-context Disable contextual features --no-context
--model MODEL Claude API model to use (defaults from settings or the model registry) --model claude-sonnet-4-5
--beta-header KEY:VALUE Beta header to send with API requests (only sent if the model supports it) --beta-header key:value
--concurrency N Number of parallel commit processors (default: 4) --concurrency 2
--no-coherence Skip cross-commit coherence refinement pass --no-coherence
--no-ai Skip AI processing and only output the repository analysis YAML --no-ai
--auto-apply Apply changes without confirmation --auto-apply
--allow-pushed Allow amending commits already in remote main branches (rewrites published history) --allow-pushed
--check Run commit message validation after applying amendments --check
--save-only FILE Save suggestions to file instead of applying --save-only suggestions.yaml
--quiet Only show errors/warnings, suppress info-level output --quiet

Commit Range Examples:

# Last 5 commits
omni-dev git commit message twiddle 'HEAD~5..HEAD'

# All commits on current branch vs main
omni-dev git commit message twiddle 'origin/main..HEAD'

# Specific range between commits
omni-dev git commit message twiddle 'abc123..def456'

# Single commit
omni-dev git commit message twiddle 'HEAD^..HEAD'

view - Analysis and Inspection

Analyze commits without making changes:

# Analyze recent commits (YAML output)
omni-dev git commit message view 'HEAD~3..HEAD'

# Analyze current branch vs main
omni-dev git branch info main

# Without an argument, the base branch is resolved remote-first:
# origin/main, then origin/master, then local main/master
omni-dev git branch info

The output includes:

  • Commit metadata (hash, author, date, message)
  • File changes and diff statistics
  • Conventional commit type detection
  • Proposed improvements
  • Remote branch tracking

amend - Manual Application

Apply specific amendments from a YAML file:

# Apply amendments from file
omni-dev git commit message amend amendments.yaml

YAML format:

amendments:
  - commit: "abc123def456..."
    message: |
      feat(auth): implement OAuth2 authentication
      
      Add comprehensive authentication system:
      - OAuth2 integration with Google/GitHub
      - JWT token management
      - User session handling
      - Role-based access control

Safety: already-pushed commits

Amending rewrites history, so amend (and twiddle's apply step) refuses to touch a commit that is already contained in a remote main branch (for example origin/main). The same containment information appears in view output as the per-commit in_main_branches field.

If you are certain you want to rewrite published history, pass the override flag:

omni-dev git commit message amend --allow-pushed amendments.yaml

Main-branch detection is local and offline: it uses the remote's symbolic HEAD ref when available, falling back to common branch names (main/master/develop). Remotes whose main branch cannot be determined locally are skipped conservatively.

check - Commit Message Validation

Validate commit messages against guidelines without modifying anything. Useful in CI, pre-push hooks, and as a non-destructive sibling to twiddle.

# Default range: commits ahead of the default base branch, resolved
# remote-first (origin/main, then origin/master, then local main/master);
# errors if none of these exist — pass an explicit range in that case
omni-dev git commit message check

# Explicit range
omni-dev git commit message check 'HEAD~5..HEAD'

# CI-friendly: exit non-zero on any issue (warnings included)
omni-dev git commit message check --strict

# Quiet output (errors/warnings only)
omni-dev git commit message check --quiet

# Show analysis for passing commits too
omni-dev git commit message check --verbose
omni-dev git commit message check --show-passing

# Structured output for tooling
omni-dev git commit message check -o json
omni-dev git commit message check -o yaml

# Offer to apply suggested fixes when issues are found
omni-dev git commit message check --twiddle

Key Options:

Option Description
--strict Exit non-zero if any issue is reported (including warnings)
--quiet Suppress info-level output
--verbose Include detailed analysis for every commit
--show-passing Include passing commits in the report
-o, --output text|json|yaml Output format (default text)
--no-coherence Skip the cross-commit coherence pass
--no-suggestions Skip generating corrected message suggestions
--twiddle When issues are found, prompt to apply suggested fixes
--guidelines PATH Use a guidelines file outside .omni-dev/
--context-dir PATH Custom context directory
--concurrency N Maximum concurrent AI requests (default 4)
--model MODEL / --beta-header KEY:VALUE Override the Claude model and beta headers

create pr - AI-Powered Pull Request Creation

Generate professional pull requests with AI-analyzed descriptions:

# Create PR with AI-generated description
omni-dev git branch create pr

# Create PR for specific base branch
omni-dev git branch create pr main

# Common options
omni-dev git branch create pr [BASE_BRANCH] [OPTIONS]

Key Options:

Option Description Example
--base BRANCH Base branch (defaults to main / master) --base release/2.x
--ready Force the PR to open as ready-for-review --ready
--draft Force the PR to open as a draft --draft
--no-push Skip the implicit git push before creating the PR --no-push
--model MODEL Override the Claude model used to draft the PR body --model claude-opus-4-7
--context-dir PATH Custom context directory (defaults to .omni-dev/) --context-dir ./config
--auto-apply Create/update PR without confirmation --auto-apply
--save-only FILE Save PR details to YAML file instead of creating --save-only pr-details.yaml
--from-commits Drive PR generation from commit messages instead of the diff (faster, no diff bytes are sent to the AI) --from-commits

What it does:

  • Analyzes your branch commits and changes
  • Generates comprehensive PR title and description using AI
  • Fills in PR template sections automatically
  • Handles both new PR creation and existing PR updates
  • Creates YAML file with structured PR details for editing

Requirements:

  • Clean working directory (no uncommitted changes)
  • GitHub CLI (gh) installed and authenticated
  • Branch pushed to remote (will push automatically if needed)
  • Claude API key configured

Example Output:

The command creates a pr-details.yaml file with structure like:

title: "feat(auth): implement comprehensive OAuth2 authentication system"
description: |
  # Pull Request

  ## Description
  This PR implements a comprehensive OAuth2 authentication system that enables
  users to sign in using Google and GitHub providers. The implementation includes
  secure token management, session handling, and role-based access control.

  ## Type of Change
  - [x] New feature (non-breaking change which adds functionality)

  ## Changes Made
  - Added OAuth2 integration with Google and GitHub providers
  - Implemented JWT token validation and refresh mechanisms
  - Created user session management system
  - Added role-based access control middleware
  - Updated authentication documentation

  ## Testing
  - [x] All existing tests pass
  - [x] New tests added for authentication flows
  - [x] Manual testing performed with both providers

  ## Additional Notes
  This implementation follows OAuth2 best practices and includes comprehensive
  error handling for edge cases.

Claude Code Integration

omni-dev ships a family of subcommands that integrate with Claude Code — Anthropic's agentic coding CLI. These cover four use cases:

  • Conversational AI (ai chat) — one-shot Q&A against the configured model.
  • Conversation history export (ai claude history sync) — mirror Claude Code sessions to disk for analysis or coaching workflows.
  • Skill distribution (ai claude skills) — share .claude/skills/ definitions across repositories and worktrees.
  • Command-template generation (commands generate) — bootstrap canonical slash-commands into a project's .claude/commands/ directory.

All of these honour the same AI backend dispatch as the rest of omni-dev (see Configuration Guide — AI Backend Selection).

ai chat — Conversational AI

A lightweight CLI front-end for chatting with the configured Claude model. Use it when you want open-ended Q&A — twiddle is for commit-message amendments, check is for commit-message validation, view is for analysis, and ai chat is for everything else (a sanity check on a config, a rubber-duck on an error message, a quick "summarise this output").

Each prompt is single-turn from the model's perspective — the CLI wraps an interactive loop around independent calls and does not pass prior turns back. The interactive UX feels like multi-turn but the model sees each prompt fresh. If you need true multi-turn reasoning with full context, use Claude Code itself.

The CLI uses a hard-coded system prompt of "You are a helpful assistant."; MCP callers can override it via the system_prompt parameter (see the ai_chat tool entry).

# Start an interactive session against the configured backend
omni-dev ai chat

# Override the model for this session only
omni-dev ai chat --model claude-opus-4-7

The session reads stdin one line at a time and prints the response. Type Ctrl+D (EOF) to exit.

ai claude history sync — Export Conversation History

Export Claude Code conversation history to a target directory as one .jsonl (and optionally .md) per chat, grouped by encoded project slug. Re-running is idempotent: unchanged sessions are skipped, modified sessions are rewritten via tempfile + rename, and source mtime is preserved on the target so downstream tooling can sort chronologically.

# Basic export to ~/coaching/claude-history
omni-dev ai claude history sync --target ~/coaching/claude-history

# Both formats side-by-side (markdown is LLM-friendly with YAML frontmatter)
omni-dev ai claude history sync --target ~/history --output-format jsonl,markdown

# Restrict to one project (encoded slug or decoded cwd path)
omni-dev ai claude history sync --target ~/history --project -Users-jky-wrk

# Window: relative duration or RFC 3339
omni-dev ai claude history sync --target ~/history --since 7d
omni-dev ai claude history sync --target ~/history --since 2026-04-01T00:00:00Z

# Hide system-side events from markdown (jsonl is byte-identical regardless)
omni-dev ai claude history sync --target ~/history --output-format markdown --exclude-system

# Preview without touching the target
omni-dev ai claude history sync --target ~/history --dry-run

# Delete target files for sessions removed upstream (scoped to listed formats)
omni-dev ai claude history sync --target ~/history --prune

The export is a behavioural transcript — prompts, responses, thinking, tool calls, tool-result metadata, and structured agent-to-user interactions (AskUserQuestion, denials, interrupts). Sub-agent internal turns, large tool-output sidecars, and auto-memory are deliberately excluded. See omni-dev ai claude history sync --help for the complete flag reference.

ai claude skills — Distribute Skills Across Repositories

A Claude Code skill is a directory under .claude/skills/<name>/ containing a SKILL.md manifest plus any supporting files. Claude Code auto-discovers skills from the working directory, so the canonical pattern is to keep them in a project repository.

When the same skill set needs to be available across multiple repositories or worktrees, copying becomes a maintenance burden. ai claude skills solves this by symlinking each <target>/.claude/skills/<name> to <source>/.claude/skills/<name> and adding a managed block to <target>/.git/info/exclude so git ignores the symlinks. Updates in the source are seen immediately by every target; clean removes both the symlinks and the exclude-block entries; status reports residue.

# Sync skills from the current repo into itself and all its worktrees
omni-dev ai claude skills sync --worktrees

# Sync from a canonical source into a specific target
omni-dev ai claude skills sync --source ~/wrk/canonical --target ~/wrk/feature-branch

# Preview what would change
omni-dev ai claude skills sync --source ~/wrk/canonical --target ~/wrk/feature-branch --dry-run

# Inspect symlinks and exclude entries left behind by a prior sync
omni-dev ai claude skills status
omni-dev ai claude skills status --worktrees --format yaml

# Remove the symlinks and exclude-block entries
omni-dev ai claude skills clean --worktrees
omni-dev ai claude skills clean --dry-run

End-to-end walkthrough:

# 1. Add a new skill in your canonical repo
mkdir -p ~/wrk/canonical/.claude/skills/my-skill
$EDITOR ~/wrk/canonical/.claude/skills/my-skill/SKILL.md

# 2. Push it into every worktree of a downstream repo
cd ~/wrk/downstream
omni-dev ai claude skills sync --source ~/wrk/canonical --worktrees

# 3. Verify Claude Code picks it up (the symlink appears in the listing)
omni-dev ai claude skills status

# 4. Later, when you no longer want this skill set, clean up
omni-dev ai claude skills clean --worktrees

Same source and target is a no-op (the command short-circuits). The target's .git/info/exclude is the only file modified outside .claude/skills/, and the managed block is delimited so manual entries are preserved across syncs and cleans.

See also: claude_skills_sync / claude_skills_status / claude_skills_clean for the MCP equivalents, and CI Path-Split for the in-repo CI alternative — splitting required checks so skills can live in the project repo yet still iterate in seconds, instead of being symlinked in from a source.

ai claude cli model resolve — Model Resolution Diagnostics

Print how Claude Code resolves the active model in the current directory (useful when project / user / env settings disagree).

omni-dev ai claude cli model resolve

commands generate — Generate Claude Code Slash-Commands

Generates Claude Code slash-command templates into the project's .claude/commands/ directory. Each template is a self-contained workflow manifest (YAML frontmatter declaring allowed tools, argument hints, and model selection, followed by step-by-step instructions) that drives a multi-step omni-dev operation from inside a Claude Code session.

Three templates ship with omni-dev:

Subcommand Output file Purpose
commit-twiddle .claude/commands/commit-twiddle.md Invoke omni-dev twiddle, review the suggested amendments, apply them.
pr-create .claude/commands/pr-create.md Run the viewtwiddlebranch create pr pipeline end-to-end.
pr-update .claude/commands/pr-update.md Update an existing PR's body from the current commit set.
all All three of the above Bootstrap a fresh project.
# Bootstrap all three templates
omni-dev commands generate all

# Or generate them individually
omni-dev commands generate commit-twiddle
omni-dev commands generate pr-create
omni-dev commands generate pr-update

Run from the repository root; the command will create .claude/commands/ if it does not exist and writes one file per subcommand (e.g. ✅ Generated .claude/commands/commit-twiddle.md). Commit the files to share the workflows with your team — Claude Code picks them up automatically, so collaborators can invoke /commit-twiddle, /pr-create, or /pr-update inside a Claude Code session with no extra setup.

atlassian - JIRA and Confluence Integration

Read, edit, and manage JIRA issues and Confluence pages from the command line. Content is represented as JFM (JIRA-Flavored Markdown) with YAML frontmatter, enabling round-trip editing between your editor and Atlassian Cloud.

See the JFM Specification for full technical details on the markdown format.

Authentication Setup

Configure your Atlassian Cloud credentials:

# Interactive credential setup (prompts for instance URL, email, API token)
omni-dev atlassian auth login

# Verify credentials work
omni-dev atlassian auth status

# Remove stored Atlassian credentials from settings.json
omni-dev atlassian auth logout

auth logout removes the ATLASSIAN_INSTANCE_URL, ATLASSIAN_EMAIL, and ATLASSIAN_API_TOKEN keys from the active profile's env map (the base env map when no profile is selected), leaving all other settings intact.

Credentials are stored in ~/.omni-dev/settings.json. You can also use environment variables:

export ATLASSIAN_INSTANCE_URL=https://myorg.atlassian.net
export ATLASSIAN_EMAIL=you@example.com
export ATLASSIAN_API_TOKEN=your-token

Environment variables take precedence over the settings file.

To keep multiple Atlassian tenants (e.g. work and personal) on one machine and pick one per command, store each tenant's variables in a named profile and select it with --profile <name> (or OMNI_DEV_PROFILE). See Credential Profiles.

To override just the instance URL for a single invocation — for example to target a specific tenant without switching profiles — pass the global --instance <URL> flag (or set OMNI_DEV_ATLASSIAN_INSTANCE). It applies to every JIRA and Confluence command (email and API token still come from the environment/settings) and, being global, works before or after the subcommand:

omni-dev --instance https://other.atlassian.net atlassian jira read PROJ-1
omni-dev atlassian jira read PROJ-1 --instance https://other.atlassian.net

Destructive Commands

⚠️ Destructive commands require confirmation.

Atlassian's destructive subcommands (deletes and removes) prompt for confirmation by default and refuse to run unless either the user explicitly confirms (CLI, via --force/--dry-run) or the caller opts in (MCP, via confirm: true):

  • omni-dev atlassian jira delete <KEY>
  • omni-dev atlassian jira comment delete <KEY> <COMMENT_ID>
  • omni-dev atlassian jira worklog delete <KEY> <WORKLOG_ID>
  • omni-dev atlassian jira version delete <VERSION_ID>
  • omni-dev atlassian jira link remove --link-id <ID>
  • omni-dev atlassian jira link remote delete <KEY> --link-id <ID>
  • omni-dev atlassian jira watcher remove --user <ACCOUNT_ID> <KEY>
  • omni-dev atlassian confluence delete <ID>
  • omni-dev atlassian confluence comment delete <COMMENT_ID> --kind <KIND>
  • omni-dev atlassian confluence label remove --labels <LABELS> <ID>
  • omni-dev atlassian confluence attachment delete <ATTACHMENT_ID>

CLI behaviour. Each command prompts on stdin:

Delete PROJ-123 (Fix login)? [y/N]

Typing anything other than y (case-insensitive, whitespace-trimmed) prints Cancelled. and exits without calling the API. Two escape hatches:

  • --force skips the prompt — for scripts.
  • --dry-run prints Would delete PROJ-123 (Fix login). and exits without calling the API. --dry-run takes precedence over --force, so a scripted --force invocation can be sanity-checked by adding --dry-run without removing the force flag.

MCP behaviour. The matching MCP tools (jira_delete, jira_link_remove, jira_watcher_remove, confluence_delete, confluence_label_remove) require an explicit confirm: true parameter and refuse to run otherwise:

Refusing to delete PROJ-123: pass `confirm: true` to authorise this irreversible operation.

The exception is confluence_attachment_delete, which mirrors the CLI's --force mode and deletes without a confirm parameter.

Interactive prompts catch human accidents; --force keeps scripts working; --dry-run is a server-free preview; the MCP confirm: true requirement gives assistants an explicit opt-in. See ADR-0027 for the full design rationale.

JIRA: Reading and Writing Issues

# Read an issue as JFM markdown
omni-dev atlassian jira read PROJ-123
omni-dev atlassian jira read PROJ-123 --out-file issue.md
omni-dev atlassian jira read PROJ-123 --format adf   # raw ADF JSON

# Include specific custom fields
omni-dev atlassian jira read PROJ-123 --fields "Acceptance Criteria,customfield_10088"

# Include every populated custom field
omni-dev atlassian jira read PROJ-123 --all-fields

# Write changes back (prompts for confirmation)
omni-dev atlassian jira write PROJ-123 issue.md
omni-dev atlassian jira write PROJ-123 issue.md --force
omni-dev atlassian jira write PROJ-123 issue.md --dry-run

# Update fields without re-posting the description body
omni-dev atlassian jira write PROJ-123 --no-content --assignee 5b10a2844c20165700ede21g
omni-dev atlassian jira write PROJ-123 --no-content --reporter "" --set-field "Priority=High"

# Array fields take comma-separated values or a YAML list (same payload)
omni-dev atlassian jira write PROJ-123 --no-content --set-field "Labels=triage,backend"
omni-dev atlassian jira write PROJ-123 --no-content --set-field "Labels=[triage, backend]"

# Interactive edit: fetch -> $EDITOR -> push
omni-dev atlassian jira edit PROJ-123

--assignee / --reporter take an Atlassian accountId — pass the empty string "" to clear, or "-1" to trigger automatic assignment. Use jira user search to resolve a display name or email to an accountId. To set an issue's parent for hierarchy (Epic → Story or Story → Sub-task), use jira link parent — the canonical hierarchy surface.

The edit command opens an interactive loop:

  1. Fetches the issue and writes JFM to a temp file
  2. Prompts: [A]ccept, [S]how, [E]dit, or [Q]uit?
  3. On accept, converts back to ADF and pushes changes

JFM output example:

---
type: jira
instance: https://myorg.atlassian.net
key: PROJ-123
summary: Implement user authentication
status: In Progress
issue_type: Story
assignee: Alice Smith
labels:
  - backend
---

This story covers the implementation of OAuth2-based authentication...

JIRA: Search

Search issues using JQL or convenience flags:

# Raw JQL
omni-dev atlassian jira search --jql "project = PROJ AND status = Open"

# Convenience flags (combined with AND)
omni-dev atlassian jira search --project PROJ --status "In Progress"
omni-dev atlassian jira search --assignee alice --limit 100

# Fetch all results (auto-paginates)
omni-dev atlassian jira search --jql "project = PROJ" --limit 0

Output is a formatted table: KEY | STATUS | ASSIGNEE | SUMMARY.

JIRA: Create Issues

Create issues from JFM markdown or CLI flags:

# From a plain markdown body — no frontmatter needed (all metadata via flags)
omni-dev atlassian jira create body.md --project PROJ --type Story --summary "Fix login"

# From a JFM file (project, type, summary read from frontmatter)
omni-dev atlassian jira create issue.md

# Flags override matching frontmatter fields
omni-dev atlassian jira create issue.md --project PROJ --type Bug --summary "Fix login"

# From ADF JSON (all metadata via flags)
omni-dev atlassian jira create body.json --format adf --project PROJ --summary "Title"

# Set custom fields inline (repeatable)
omni-dev atlassian jira create issue.md --set-field "Story Points=5" \
  --set-field "Sprint=customfield_10020"

# Values may contain spaces, parentheses, and '=' — only shell quoting is needed
omni-dev atlassian jira create issue.md \
  --set-field "Work Type=Product Features (Planned)"

# Target a specific instance (overrides ATLASSIAN_INSTANCE_URL / settings.json)
omni-dev atlassian jira create issue.md --instance https://other.atlassian.net

# Preview without creating
omni-dev atlassian jira create issue.md --dry-run

Metadata is resolved with this precedence: CLI flags first, then JFM frontmatter, then a derived or default value (issue type defaults to Task). Flags always win.

Frontmatter is optional. A file with no --- block is treated entirely as the issue body, with every field taken from flags — the same way the MCP jira_create tool works. The frontmatter instance: field, if present, is ignored: it never routes requests. The target instance comes from --instance (when given), otherwise from auth config (ATLASSIAN_INSTANCE_URL env / settings.json), never from the document.

Prints the created issue key (e.g., PROJ-124) to stdout.

--set-field "NAME=VALUE" semantics:

  • Splitting. The argument is split on the first = only. NAME is everything before it (surrounding whitespace trimmed); VALUE is everything after, kept verbatim — spaces, parentheses, and further = are all literal, so the only quoting needed is your shell's.
  • Value typing. VALUE is parsed as a YAML scalar (number, bool) when possible, otherwise a string. The shape actually sent then follows the field's schema: option/select fields send {"value": "…"}, number fields send a JSON number, array fields take a list, and rich-text (ADF) fields take JFM markdown. So --set-field "Story Points=5" sends the number 5 for a numeric field, whereas an option field receives the string "5" wrapped as {"value": "5"}.
  • Array fields. Fields whose schema is array-typed (labels, components, fix versions, multi-selects) accept either a YAML flow list (Labels=[a, b, c]) or a comma-separated string (Labels=a,b,c) — both send the same payload. Comma-split elements are whitespace-trimmed and empty elements are dropped, so Labels=a , b , sends ["a", "b"] and Labels="" clears the field. A literal comma inside one element needs the list form: Labels=["a,b"]. The value replaces the field's current contents; appending requires read → merge → write.
  • Field resolution. NAME resolves against the create screen for the target project + issue type. A customfield_<digits> id is matched first; otherwise the display name is matched exactly. The field must be on the create screen — an unknown name fails up front with the list of accepted fields (it is never silently dropped), and an ambiguous display name lists the matching ids.
  • Option validation. For option fields whose allowed values are known, a value outside that set is rejected before the request with a clear, field-named error. Fields that do not enumerate their values are sent as-is and validated by JIRA (its error is surfaced verbatim).
  • Precedence. A --set-field entry overrides the frontmatter custom_fields: entry of the same name.

Run jira project create-meta to see which fields a project + issue type accepts, their types, and allowed values.

JIRA: Transitions

List and execute workflow transitions:

# List available transitions
omni-dev atlassian jira transition list PROJ-123

# Execute a transition by name (case-insensitive)
omni-dev atlassian jira transition execute PROJ-123 "In Progress"

# Execute by ID
omni-dev atlassian jira transition execute PROJ-123 21

Transitions whose screen requires input can supply it in the same request:

# Resolve an issue, setting the resolution and an atomic comment
omni-dev atlassian jira transition execute PROJ-123 Resolve \
  --resolution Fixed --comment "Resolved via CI"

# Set an arbitrary transition-screen field (same NAME=VALUE syntax as
# `jira write --set-field`); repeat for multiple fields
omni-dev atlassian jira transition execute PROJ-123 Resolve \
  --set-field "Severity=High"

--resolution NAME sets the resolution (sent as {"name": …}); --set-field "NAME=VALUE" resolves against the transition's screen fields; and --comment (JFM markdown) rides in the transition itself when the screen accepts a comment — satisfying a mandatory-comment screen — otherwise it is posted as a separate comment after the transition.

JIRA: Comments

# List comments on an issue
omni-dev atlassian jira comment list PROJ-123

# Add a comment from a file
omni-dev atlassian jira comment add PROJ-123 comment.md

# Add from stdin
echo "This is a comment" | omni-dev atlassian jira comment add PROJ-123

# Add ADF JSON comment
omni-dev atlassian jira comment add PROJ-123 body.json --format adf

# Edit an existing comment (needs the comment id from `comment list`)
omni-dev atlassian jira comment edit PROJ-123 10010 revised.md

# Delete a comment (prompts for confirmation; --force skips it, --dry-run previews)
omni-dev atlassian jira comment delete PROJ-123 10010

JIRA: Delete Issues

# Delete with confirmation prompt
omni-dev atlassian jira delete PROJ-123

# Skip confirmation
omni-dev atlassian jira delete PROJ-123 --force

JIRA: Projects

# List all accessible projects
omni-dev atlassian jira project list
omni-dev atlassian jira project list --limit 100

Create-screen introspection — before creating an issue, ask which fields the project + issue type actually requires and what values they accept. This is the pre-flight alternative to attempting a create, parsing the HTTP 400 (customfield_NNNNN is required), and chasing down field list / field options to recover:

# What does it take to create a Task in PROJ?
omni-dev atlassian jira project create-meta --project PROJ --issue-type Task

# Machine-readable output for scripting / agents
omni-dev atlassian jira project create-meta --project PROJ --issue-type Bug -o yaml

For each field on the create screen this reports field_id, name, required, schema_type, any custom plugin URI, the allowed_values (resolving option / select / cascading-select, including nested children), and a default_value when the screen defines one. The table view sorts required fields first. Output formats match the other list commands: table (default), json, yaml, yamls, and jsonl (one line per field).

JIRA: Fields

JIRA installations are heavily customised — most real projects add custom fields (story points, epic links, severity, customer impact, etc.) and each gets an opaque ID like customfield_10001. The names you see in the JIRA web UI are display labels; the API only accepts the IDs. The field subcommand is how you discover them.

A field can have different option lists per context (per-project, per-issue-type, or per-screen scoping). Most fields have exactly one context, in which case field options will auto-discover it. Fields with multiple contexts require --context-id to pick the right option set.

# List all field definitions (display name → customfield_NNNNN mapping)
omni-dev atlassian jira field list

# Search by name (case-insensitive substring match)
omni-dev atlassian jira field list --search "story"
omni-dev atlassian jira field list --search "severity"

# Show options for a custom field (auto-discovers context)
omni-dev atlassian jira field options --field-id customfield_10001

# Specify context explicitly when the field has multiple contexts
omni-dev atlassian jira field options --field-id customfield_10001 --context-id 12345

# Machine-readable output for scripting
omni-dev atlassian jira field list --search "epic" -o yaml
omni-dev atlassian jira field options --field-id customfield_10001 -o json

Output formats: table (default, human-readable), json, yaml, yamls (YAML stream), and jsonl (JSON Lines).

End-to-end walkthrough — set a custom field on a new issue:

# 1. Find the field by name
omni-dev atlassian jira field list --search "story points"
# → customfield_10016: "Story Points"

# 2. (Number fields have no options — skip step 3.)
#    For an enum-style field, list its allowed values:
omni-dev atlassian jira field list --search "severity"
# → customfield_10042: "Severity"
omni-dev atlassian jira field options --field-id customfield_10042
# → "Low", "Medium", "High", "Critical"

# 3. Pass the field ID and value when creating or writing the issue
#    (see `jira create` / `jira write` for the syntax).

See also: jira_field_list / jira_field_options / jira_project_create_meta for the MCP equivalents (search, field_id, and project / issue_type parameters mirror the CLI flags).

JIRA: Agile Boards

# List boards
omni-dev atlassian jira board list
omni-dev atlassian jira board list --project PROJ --type scrum

# List issues on a board
omni-dev atlassian jira board issues --board-id 1
omni-dev atlassian jira board issues --board-id 1 --jql "status = Open"

JIRA: Sprints

# List sprints for a board
omni-dev atlassian jira sprint list --board-id 1
omni-dev atlassian jira sprint list --board-id 1 --state active

# List issues in a sprint
omni-dev atlassian jira sprint issues --sprint-id 10
omni-dev atlassian jira sprint issues --sprint-id 10 --jql "status = Open"

# Add issues to a sprint
omni-dev atlassian jira sprint add --sprint-id 10 --issues PROJ-1,PROJ-2,PROJ-3

# Create a new sprint (start/end dates and goal optional)
omni-dev atlassian jira sprint create --board-id 1 --name "Sprint 42" \
  --start-date 2026-05-01 --end-date 2026-05-14 --goal "Ship checkout v2"

# Update an existing sprint (only supplied fields change)
omni-dev atlassian jira sprint update --sprint-id 10 --state active
omni-dev atlassian jira sprint update --sprint-id 10 --name "Sprint 42 (extended)" \
  --end-date 2026-05-21

# Delete a sprint (prompts to confirm; --force skips it, --dry-run previews)
omni-dev atlassian jira sprint delete --sprint-id 10

JIRA: Watchers

# List watchers
omni-dev atlassian jira watcher list PROJ-123

# Add or remove a watcher (account ID — use `jira user search` to resolve)
omni-dev atlassian jira watcher add PROJ-123 --user 5b10a2844c20165700ede21g
omni-dev atlassian jira watcher remove PROJ-123 --user 5b10a2844c20165700ede21g

JIRA: Worklogs

# List worklog entries
omni-dev atlassian jira worklog list PROJ-123
omni-dev atlassian jira worklog list PROJ-123 --limit 100

# Log time (`--time-spent` accepts JIRA duration format: "2h 30m", "1d", "45m")
omni-dev atlassian jira worklog add PROJ-123 --time-spent "2h 30m" \
  --comment "Investigated cache invalidation"
omni-dev atlassian jira worklog add PROJ-123 --time-spent 1d \
  --started "2026-04-16T09:00:00.000+0000"

# Correct an entry (needs the worklog id from `worklog list`; pass any subset of fields)
omni-dev atlassian jira worklog edit PROJ-123 10010 --time-spent "3h" \
  --comment "Revised estimate"

# Remove an entry (prompts to confirm; --force skips it, --dry-run previews)
omni-dev atlassian jira worklog delete PROJ-123 10010

JIRA: Versions

Manage a project's release versions (the values behind fixVersion / affectedVersion).

# List versions (filter with --released/--unreleased, --archived/--unarchived)
omni-dev atlassian jira version list --project PROJ
omni-dev atlassian jira version list --project PROJ --unreleased

# Create a version
omni-dev atlassian jira version create --project PROJ --name "1.0.0" \
  --release-date 2026-06-01

# Release / archive / rename an existing version (id from `version list`)
omni-dev atlassian jira version release 10000 --release-date 2026-06-01
omni-dev atlassian jira version archive 10000
omni-dev atlassian jira version rename 10000 "1.0.1" --description "Patch release"

# Delete a version (prompts to confirm; --force skips it, --dry-run previews).
# Optionally reassign issues' fix/affected versions first.
omni-dev atlassian jira version delete 10000
omni-dev atlassian jira version delete 10000 --move-fix-issues-to 10001

JIRA: Labels

Add or remove individual labels incrementally — leaving the issue's other labels untouched, unlike jira write --set labels=… (a full-array replace). JIRA labels cannot contain spaces.

omni-dev atlassian jira label add PROJ-123 --labels backend,urgent
omni-dev atlassian jira label remove PROJ-123 --labels stale

JIRA: Components

Manage a project's components (project-level CRUD, distinct from setting an issue's components field via jira create/write).

# List a project's components
omni-dev atlassian jira component list --project PROJ

# Create / rename / delete a component
omni-dev atlassian jira component create --project PROJ --name Backend \
  --description "Server side"
omni-dev atlassian jira component update 10000 --name "Backend Services"
# Delete (prompts to confirm; --force skips it, --dry-run previews).
# Optionally reassign referencing issues first with --move-issues-to.
omni-dev atlassian jira component delete 10000

JIRA: User Search

Resolve a display name or email substring to an Atlassian accountId — required input for jira write --assignee/--reporter and jira watcher add/remove.

omni-dev atlassian jira user search --query "Alice"
omni-dev atlassian jira user search --query "@example.com" --limit 100

JIRA: Development Info

Show linked PRs, branches, and repositories for an issue (requires JIRA's GitHub/Bitbucket integration).

omni-dev atlassian jira dev PROJ-123
omni-dev atlassian jira dev PROJ-123 --type pullrequest
omni-dev atlassian jira dev PROJ-123 --app GitHub --summary

JIRA: Issue Links

# List links on an issue (shows link IDs)
omni-dev atlassian jira link list PROJ-123

# List available link types
omni-dev atlassian jira link types

# Create a link
omni-dev atlassian jira link create --type Blocks --inward PROJ-1 --outward PROJ-2

# Remove a link by ID (get IDs from `link list`)
omni-dev atlassian jira link remove --link-id 12345

# Set an issue's parent — Epic → Story or Story → Sub-task
# (`--epic`/`--issue` are accepted as aliases for `--parent`/`--child`)
omni-dev atlassian jira link parent --parent EPIC-1 --child PROJ-2

Remote (external-URL) links point out to non-JIRA resources (Confluence pages, Bitbucket PRs, external trackers):

# List remote links on an issue (shows remote link IDs)
omni-dev atlassian jira link remote list PROJ-123

# Add a remote link
omni-dev atlassian jira link remote create PROJ-123 \
  --url https://example.com/design --title "Design doc" --relationship "relates to"

# Delete a remote link by ID (prompts to confirm; --force skips it, --dry-run previews)
omni-dev atlassian jira link remote delete PROJ-123 --link-id 10010

JIRA: Changelog

View change history for one or more issues:

omni-dev atlassian jira changelog --keys PROJ-1
omni-dev atlassian jira changelog --keys PROJ-1,PROJ-2 --limit 100

JIRA: Attachments

# Upload one or more files to an issue (single multipart request)
omni-dev atlassian jira attachment upload PROJ-123 ./build.log
omni-dev atlassian jira attachment upload PROJ-123 ./build.log ./screenshot.png

# Download all attachments
omni-dev atlassian jira attachment download --key PROJ-123
omni-dev atlassian jira attachment download --key PROJ-123 --output-dir ./files

# Filter by filename
omni-dev atlassian jira attachment download --key PROJ-123 --filter screenshot

# Download only images (png, jpeg, gif, svg, webp)
omni-dev atlassian jira attachment images --key PROJ-123
omni-dev atlassian jira attachment images --key PROJ-123 --output-dir ./images

# Delete an attachment by ID (permanent — prompts for confirmation)
omni-dev atlassian jira attachment delete 10042
omni-dev atlassian jira attachment delete 10042 --dry-run   # preview, no API call
omni-dev atlassian jira attachment delete 10042 --force     # skip the prompt

Confluence: Reading and Writing Pages

# Read a page as JFM markdown
omni-dev atlassian confluence read 12345
omni-dev atlassian confluence read 12345 --out-file page.md
omni-dev atlassian confluence read 12345 --format adf

# Write changes back
omni-dev atlassian confluence write 12345 page.md
omni-dev atlassian confluence write 12345 page.md --force
omni-dev atlassian confluence write 12345 page.md --dry-run

# Interactive edit
omni-dev atlassian confluence edit 12345

Confluence JFM output example:

---
type: confluence
instance: https://myorg.atlassian.net
page_id: "12345"
title: Architecture Overview
space_key: ENG
status: current
version: 7
---

# Architecture Overview

Page body content here...

Confluence: Comparing Pages

Compares two versions of a Confluence page using a structurally-aware diff: the engine walks the ADF (Atlassian Document Format) tree and splits each version into heading-delimited sections (paths like /h2#background, /h3#implementation). The output describes which sections changed and how — not raw text deltas — which makes it ergonomic for AI agents and human reviewers alike.

Two commands:

  • omni-dev atlassian confluence compare run <PAGE_ID> — diff two versions of a page; emits a YAML envelope with per-section change summaries and drill-in cursors.
  • omni-dev atlassian confluence compare section --cursor <CURSOR> — drill into a single section using a cursor returned by run.

Detail levels (--detail):

  • summary — aggregate counts only (sections added, modified, removed; characters changed). Smallest output.
  • outline (default) — per-section change kind, one-line summaries, and drill-in cursors for compare section. Ideal balance for surveying a page.
  • full — embeds full per-section deltas. Budget-truncated if the output exceeds --budget (default ~16 KiB ≈ 4000 tokens).

Version selectors for --from and --to:

  • latest — the most recent version (default --to).
  • previous — the version before --to (default --from).
  • v-NN versions back from --to (e.g. v-3).
  • A bare integer — that exact version number.
  • An ISO 8601 timestamp — the version that was current at that time.

Filtering and trimming:

  • --filter-section /h2#name — restrict to sections matching the given path. Repeatable.
  • --min-change-chars <N> — drop sections with fewer than N characters of changed text. Useful for ignoring formatting-only edits.
  • --ignore-whitespace — collapse runs of whitespace inside text nodes before diffing.
  • --include body,title,labels,metadata — choose which top-level fields to diff. Default: body,title,metadata (labels and other metadata excluded by default).
  • --budget <BYTES> — output budget. Defaults to 16384 (~16 KiB).
# Outline of changes between the previous and latest versions
omni-dev atlassian confluence compare run 12345

# Compare a specific version range
omni-dev atlassian confluence compare run 12345 --from v-5 --to latest

# Compare by date (ISO 8601)
omni-dev atlassian confluence compare run 12345 \
    --from 2026-01-01T00:00:00Z --to 2026-05-11T00:00:00Z

# Just the totals
omni-dev atlassian confluence compare run 12345 --detail summary

# Full deltas, larger budget
omni-dev atlassian confluence compare run 12345 --detail full --budget 65536

# Restrict to specific sections and ignore whitespace
omni-dev atlassian confluence compare run 12345 \
    --filter-section /h2#background --filter-section /h2#design \
    --ignore-whitespace

# Drill into a single section using a cursor returned by `run`
omni-dev atlassian confluence compare section --cursor <CURSOR> --format unified
omni-dev atlassian confluence compare section --cursor <CURSOR> --format side-by-side
omni-dev atlassian confluence compare section --cursor <CURSOR> --format markdown-inline

End-to-end walkthrough:

# 1. Survey the changes between previous and latest
omni-dev atlassian confluence compare run 12345
# → outline with per-section summaries and cursors

# 2. Drill into a section flagged as modified
omni-dev atlassian confluence compare section --cursor <CURSOR_FROM_STEP_1>
# → unified diff for that section only

See also: confluence_compare / confluence_compare_section for the MCP equivalents.

Confluence: Search

Search pages using CQL or convenience flags:

# Raw CQL
omni-dev atlassian confluence search --cql "space = ENG AND title ~ 'auth'"

# Convenience flags
omni-dev atlassian confluence search --space ENG
omni-dev atlassian confluence search --title architecture
omni-dev atlassian confluence search --space ENG --title auth --limit 100

Confluence: Create Pages

# From JFM file
omni-dev atlassian confluence create page.md

# From CLI flags
omni-dev atlassian confluence create page.md --space ENG --title "New Page"

# With parent page
omni-dev atlassian confluence create page.md --space ENG --title "Child" --parent 12345

# Preview
omni-dev atlassian confluence create page.md --dry-run

Confluence: Copy Pages

Copy a single page under a destination parent, carrying its attachments, labels, and properties (but not its restrictions):

omni-dev atlassian confluence copy 12345 --parent 67890 --title "Copy of Page"

Confluence: Delete Pages

# Delete (moves to trash, prompts for confirmation)
omni-dev atlassian confluence delete 12345

# Skip confirmation
omni-dev atlassian confluence delete 12345 --force

# Permanently purge (requires space admin)
omni-dev atlassian confluence delete 12345 --force --purge

Confluence: Children

List direct children of a page or top-level pages in a space.

# Direct children of a page
omni-dev atlassian confluence children 12345

# Top-level pages in a space (no parent ID)
omni-dev atlassian confluence children --space ENG

# Recursive tree (--max-depth 0 = unlimited)
omni-dev atlassian confluence children 12345 --recursive
omni-dev atlassian confluence children --space ENG --recursive --max-depth 3

Confluence: Comments

# List comments
omni-dev atlassian confluence comment list 12345
omni-dev atlassian confluence comment list 12345 --limit 100

# Add a comment from a file or stdin
omni-dev atlassian confluence comment add 12345 comment.md
echo "Looks good" | omni-dev atlassian confluence comment add 12345

# Add an ADF JSON comment
omni-dev atlassian confluence comment add 12345 body.json --format adf

# Edit a comment's body (needs the comment id from `comment list` and its --kind)
omni-dev atlassian confluence comment edit 555 --kind footer revised.md

# Delete a comment (prompts to confirm; --force skips it, --dry-run previews)
omni-dev atlassian confluence comment delete 555 --kind inline

# Resolve / reopen an inline comment
omni-dev atlassian confluence comment resolve 555
omni-dev atlassian confluence comment reopen 555

Confluence: Labels

# List labels on a page
omni-dev atlassian confluence label list 12345

# Add or remove labels (comma-separated)
omni-dev atlassian confluence label add 12345 --labels architecture,reviewed
omni-dev atlassian confluence label remove 12345 --labels deprecated

Confluence: Watchers

Manage per-user watch state on a page. Confluence's public API exposes check/add/remove for a user (defaulting to the authenticated user) but not a list of every watcher, so this offers status rather than list.

# Check whether you (or --account-id <ID>) watch a page
omni-dev atlassian confluence watcher status 12345

# Start / stop watching a page
omni-dev atlassian confluence watcher add 12345
omni-dev atlassian confluence watcher remove 12345 --account-id 5b10ac8d82e05b22cc7d4ef5

Confluence: Restrictions

View and manage read/update restrictions on a page (who may view or edit it).

# Show the current restrictions
omni-dev atlassian confluence restriction get 12345

# Grant / revoke a user or group for an operation (read | update)
omni-dev atlassian confluence restriction grant 12345 --operation update \
  --account-id 5b10ac8d82e05b22cc7d4ef5
omni-dev atlassian confluence restriction revoke 12345 --operation read --group developers

Confluence: User Search

omni-dev atlassian confluence user search --query "Alice"
omni-dev atlassian confluence user search --query "@example.com" --limit 50

Confluence: Bulk Download

Recursively download a page tree (or an entire space) to disk. Each page is written to a <title>.md (or .adf.json) file mirroring the page tree.

# Download a subtree starting at a single page
omni-dev atlassian confluence download 12345 --output-dir ./pages

# Download every top-level page in a space
omni-dev atlassian confluence download --space ENG --output-dir ./eng-docs

# Download as raw ADF JSON instead of JFM
omni-dev atlassian confluence download 12345 --format adf

# Filter by title (case-insensitive substring; non-matching parents are
# still traversed so deeply-nested matches still surface)
omni-dev atlassian confluence download --space ENG --title-filter "auth"

# Resume after an interrupted run (uses a manifest to skip done pages)
omni-dev atlassian confluence download --space ENG --resume

# Tune concurrency and depth
omni-dev atlassian confluence download --space ENG --concurrency 16 --max-depth 5

# Conflict resolution when a file already exists
omni-dev atlassian confluence download --space ENG --on-conflict overwrite
omni-dev atlassian confluence download --space ENG --on-conflict skip

# Also fetch each page's attachment binaries into an `attachments/`
# subdirectory beside its content file (full-page snapshots)
omni-dev atlassian confluence download --space ENG --include-attachments

Confluence: Attachments

Manage attachment binaries on a page. Use list to discover attachment IDs, then download to pull a single binary off the page without dropping out to curl (credentials stay inside the wrapper).

# Upload a file as a new attachment
omni-dev atlassian confluence attachment upload 12345 ./diagram.png

# Upload a new binary VERSION of an existing attachment (bumps its version
# rather than adding a second attachment)
omni-dev atlassian confluence attachment update 12345 att-98765 ./diagram-v2.png \
  --comment "Updated diagram"

# List a page's attachments (the ID column feeds `download`/`update`/`delete`)
omni-dev atlassian confluence attachment list 12345

# Download one attachment by ID — defaults to its filename in the cwd
omni-dev atlassian confluence attachment download att-98765

# Write it to an explicit path (an existing directory is joined with the
# attachment's filename)
omni-dev atlassian confluence attachment download att-98765 --out-file ./diagram.png
omni-dev atlassian confluence attachment download att-98765 --out-file ./downloads/

To capture a whole page tree with its attachment binaries in one command, use confluence download --include-attachments (above).

--on-conflict accepts backup (default — writes .bak and overwrites), skip, or overwrite.

Offline Format Conversion

Convert between JFM markdown and ADF JSON locally without credentials:

# Markdown to ADF JSON
omni-dev atlassian convert to-adf issue.md
omni-dev atlassian convert to-adf issue.md --compact

# ADF JSON to markdown
omni-dev atlassian convert from-adf issue.json
omni-dev atlassian convert from-adf issue.json --strip-local-ids   # cleaner output

# Pipe for inspection
cat issue.md | omni-dev atlassian convert to-adf | jq .

--strip-local-ids drops the localId attributes ADF emits on tables, panels, etc. — useful when the rendered markdown is going to a human reviewer rather than back into Atlassian.

Auto-Pagination

All commands that query paginated endpoints auto-paginate transparently. Use --limit to control how many results are fetched:

# Default: up to 50 results
omni-dev atlassian jira search --project PROJ

# Fetch more
omni-dev atlassian jira search --project PROJ --limit 200

# Fetch all (no limit)
omni-dev atlassian jira search --project PROJ --limit 0

JFM Markdown Syntax

JFM supports standard GitHub-Flavored Markdown plus directives for JIRA-specific elements:

Standard markdown: headings, bold, italic, code, strikethrough, links, images, lists, task lists, tables, code blocks, blockquotes, horizontal rules.

Inline directives for JIRA constructs without markdown equivalents:

Status: :status[In Progress]{color=blue}
Assigned to: :mention[Alice]{id=abc123}
Due: :date[2026-04-15]
Emoji: :smile:

Container directives for panels and other blocks:

:::panel{type=info}
This is an info panel with **rich** content inside.
:::

:::expand{title="Click to expand"}
Hidden content here.
:::

Leaf block directives for smart links and cards:

::card[https://example.com/page]

Datadog Integration

omni-dev exposes read-only access to the Datadog v1/v2 APIs through the omni-dev datadog command tree. The full reference — authentication, every family's CLI subcommands with worked examples and sample output, rate-limit behaviour, and troubleshooting — lives in docs/datadog.md.

Quick orientation:

# One-time credential setup (writes ~/.omni-dev/settings.json)
omni-dev datadog auth login
omni-dev datadog auth status

# Examples from the nine capability families
omni-dev datadog metrics query --query 'avg:system.cpu.user{*}' --from 15m
omni-dev datadog monitor list --tags env:prod
omni-dev datadog dashboard list
omni-dev datadog logs search --filter 'service:api status:error' --from 1h
omni-dev datadog events list --filter 'service:api' --sources kubernetes
omni-dev datadog slo list --tags team:platform
omni-dev datadog downtime list --active-only
omni-dev datadog hosts list --filter env:prod

Every Datadog CLI subcommand has a matching datadog_* MCP tool — see docs/mcp.md.

Gmail Integration

omni-dev exposes read access (and, opt-in, label mutation) to the Gmail v1 API through the omni-dev gmail command tree, plus a durable local archive via gmail sync. New to this integration? Follow the Gmail Quickstart for a zero-to-synced-archive walkthrough. The full reference — prerequisites (bring-your-own Google Cloud OAuth2 client), authentication, every subcommand with worked examples, rate-limit behaviour, and troubleshooting — lives in docs/gmail.md.

Quick orientation:

# One-time OAuth2 client setup (create your own Google Cloud project first —
# see docs/gmail.md#prerequisites), then log in (opens a browser)
export GMAIL_CLIENT_ID=...
export GMAIL_CLIENT_SECRET=...
omni-dev gmail auth login
omni-dev gmail auth status

# Search, read, and browse
omni-dev gmail search --query 'label:finance after:2026/01/01' --limit 50
omni-dev gmail read <message-id>
omni-dev gmail thread <thread-id>
omni-dev gmail label list

# Label mutation needs the gmail.modify scope (auth login --modify)
omni-dev gmail label add <message-id> --label IMPORTANT
omni-dev gmail label remove <message-id> --label UNREAD

# Maintain a durable local archive (.eml files + a JSONL manifest)
omni-dev gmail sync --output-dir ~/mail-archive --query 'label:finance'

Every read-only Gmail CLI subcommand except sync has a matching gmail_* MCP tool — see docs/mcp.md. Label mutation and sync (a long-running bulk filesystem operation, a poor fit for a synchronous MCP call) are CLI-only in this release.

A second mailbox doesn't need a second --profile — an --account NAME flag (scoped to gmail commands) selects a named Gmail account independently of everything else in your environment; see gmail.md#multiple-accounts.

Contextual Intelligence

Overview

Contextual intelligence makes omni-dev understand your project to provide better suggestions:

  • Project Context: Conventions from .omni-dev/ configuration
  • Branch Context: Work type from branch naming patterns
  • File Context: Architectural understanding of changed files
  • Pattern Context: Recognition of work patterns across commits

Setting Up Context

1. Create Context Directory

mkdir .omni-dev

2. Define Project Scopes (.omni-dev/scopes.yaml)

Tell omni-dev about your project's areas. See omni-dev-directory.md for the file's format contract and validation behaviour.

scopes:
  - name: "auth"
    description: "Authentication and authorization systems"
    examples: 
      - "auth: add OAuth2 support"
      - "auth: fix token validation" 
    file_patterns:
      - "src/auth/**"
      - "auth.rs"
      - "middleware/auth.rs"

  - name: "api"  
    description: "REST API endpoints and handlers"
    examples:
      - "api: add user endpoints"
      - "api: improve error handling"
    file_patterns:
      - "src/api/**"
      - "handlers/**"
      - "routes/**"

  - name: "ui"
    description: "User interface components"
    examples:
      - "ui: add responsive navigation"  
      - "ui: fix mobile layout"
    file_patterns:
      - "src/components/**"
      - "*.vue"
      - "*.tsx"

  - name: "docs"
    description: "Documentation and guides"
    examples:
      - "docs: add API reference"
      - "docs: update installation guide"
    file_patterns:
      - "docs/**"
      - "*.md"
      - "README*"

3. Set Commit Guidelines (.omni-dev/commit-guidelines.md)

Define your project's commit message standards. See omni-dev-directory.md for the full format contract — including precedence between project-scope, user-scope, and global fallbacks — and the validation messages omni-dev emits on a malformed file.

# Project Commit Guidelines

## Format
Use conventional commits: `type(scope): description`

## Types We Use
- `feat` - New features  
- `fix` - Bug fixes
- `docs` - Documentation changes
- `refactor` - Code restructuring
- `test` - Adding tests
- `chore` - Build/tooling changes

## Style Rules
- Keep subject line under 50 characters
- Use imperative mood: "Add feature" not "Added feature"  
- Capitalize first letter of description
- No period at end of subject line

## Our Scopes
- `auth` - Authentication systems
- `api` - Backend API changes
- `ui` - Frontend interface
- `db` - Database changes
- `deploy` - Deployment/infrastructure

## Examples

feat(auth): add OAuth2 Google integration fix(api): resolve rate limiting edge case docs(readme): update installation instructions refactor(ui): extract common button component


### Branch Context Detection

omni-dev automatically detects work type from branch names:

| Branch Pattern | Detected Type | Example |
|----------------|---------------|---------|
| `feature/auth-system` | feature | Feature development |
| `fix/login-bug` | fix | Bug fix |
| `docs/api-guide` | docs | Documentation |
| `refactor/user-service` | refactor | Code restructuring |
| `JIRA-123-user-auth` | feature | Ticket-based |
| `username/feature-name` | feature | User branches |

### Intelligent Verbosity

omni-dev adjusts message detail based on change significance:

- **Comprehensive**: Major features, architectural changes
  - Multi-paragraph descriptions
  - Bulleted feature lists  
  - Impact statements

- **Detailed**: Moderate changes, multi-file updates
  - Subject + explanatory body
  - Key change highlights

- **Concise**: Minor changes, single-file updates
  - Clear conventional format
  - Essential information only

## Workflows

### Feature Branch Cleanup

Clean up commits before merging:

```bash
# 1. Work on feature branch with quick commits
git checkout -b feature/user-dashboard
git commit -m "wip"
git commit -m "fix stuff"  
git commit -m "add more"

# 2. Before merging, improve all commit messages
omni-dev git commit message twiddle 'main..HEAD' --use-context

# 3. Review suggestions and apply
# ✅ Professional commit history ready for review

Refine, Inspect, or Validate

By default twiddle generates fresh messages from the diffs alone (--fresh). When the existing messages are already close to right, refine them instead — and you can inspect the analysis or validate the result:

# Keep the existing messages as the AI's starting point
omni-dev git commit message twiddle 'main..HEAD' --refine

# Skip the AI entirely and print the repository analysis YAML
omni-dev git commit message twiddle 'main..HEAD' --no-ai

# Validate the amended messages right after applying them
omni-dev git commit message twiddle 'main..HEAD' --auto-apply --check

Complete Feature Development Workflow

End-to-end workflow from feature development to PR creation:

# 1. Create and work on feature branch
git checkout -b feature/user-authentication
# ... make changes and commits ...

# 2. Improve commit messages with AI
omni-dev git commit message twiddle 'main..HEAD' --use-context

# 3. Create professional PR with AI-generated description
omni-dev git branch create pr

# ✅ Complete: clean commits + comprehensive PR ready for team review

PR Creation and Updates

Handle PR creation and updates efficiently:

# Create new PR with AI-generated description
omni-dev git branch create pr main

# If PR already exists, update it with new description
omni-dev git branch create pr --auto-apply

# Save PR details for review before creating
omni-dev git branch create pr --save-only review-pr.yaml
# Review and edit the file...
# Then create manually using GitHub CLI or web interface

# Drive the PR description from commit messages (no diff sent to AI)
# Useful when the branch's commits are well-crafted and convey the intent
omni-dev git branch create pr --from-commits

Collaborative PR Workflow

Work with existing PRs and team feedback:

# Update existing PR after new commits
git add . && git commit -m "address review feedback"
omni-dev git branch create pr  # Updates existing PR

# Generate PR description without creating (for draft PRs)
omni-dev git branch create pr --save-only draft-pr.yaml
# Use the content to update draft PR manually

Large Codebase Migration

Handle large commit ranges efficiently:

# Process 100+ commits with parallel processing
omni-dev git commit message twiddle 'HEAD~100..HEAD' --concurrency 5

# Save suggestions for review before applying
omni-dev git commit message twiddle 'HEAD~50..HEAD' --save-only review.yaml

# Review the file, then apply manually
omni-dev git commit message amend review.yaml

Legacy Repository Cleanup

Improve old commit messages:

# Analyze what needs improvement
omni-dev git commit message view 'HEAD~20..HEAD'

# Apply contextual improvements
omni-dev git commit message twiddle 'HEAD~20..HEAD' --use-context

# For very old commits, might need specific handling
git rebase -i HEAD~20  # Interactive rebase first if needed

Team Onboarding

Set up consistent commit standards:

# 1. Set up project context (one-time setup)
mkdir .omni-dev
# Create scopes.yaml and commit-guidelines.md

# 2. Add to team documentation
echo "Use: omni-dev git commit message twiddle 'main..HEAD' --use-context" >> CONTRIBUTING.md

# 3. Include in CI/PR checks
# Add validation that commit messages follow conventions

Advanced Usage

Custom Context Directory

Use a different location for context files:

# Use custom context directory
omni-dev git commit message twiddle 'HEAD~5..HEAD' --context-dir ./project-config

# Context files would be in:
# ./project-config/scopes.yaml
# ./project-config/commit-guidelines.md

Concurrency Configuration

Adjust parallel processing based on your needs:

# Lower concurrency for complex commits (reduces API load)
omni-dev git commit message twiddle 'HEAD~20..HEAD' --concurrency 2

# Higher concurrency for faster processing
omni-dev git commit message twiddle 'HEAD~20..HEAD' --concurrency 8

# Skip coherence pass for independent commits
omni-dev git commit message twiddle 'HEAD~10..HEAD' --no-coherence

Integration with Git Hooks

Set up automatic improvement in git hooks:

# .git/hooks/pre-push (make executable)
#!/bin/bash
echo "🤖 Analyzing commit messages..."
omni-dev git commit message view 'origin/main..HEAD' --quiet || {
    echo "❌ Commit analysis failed"
    echo "💡 Consider running: omni-dev git commit message twiddle 'origin/main..HEAD' --use-context"
    exit 1
}

Save and Review Workflow

For high-stakes changes, save suggestions first:

# 1. Save suggestions to file
omni-dev git commit message twiddle 'HEAD~10..HEAD' --save-only suggestions.yaml

# 2. Review the suggestions file
cat suggestions.yaml

# 3. Edit if needed, then apply
omni-dev git commit message amend suggestions.yaml

Best Practices

1. Use Contextual Intelligence

Always use --use-context for best results:

# ✅ Good - uses project context
omni-dev git commit message twiddle 'main..HEAD' --use-context

# ⚠️ Basic - misses project-specific intelligence  
omni-dev git commit message twiddle 'main..HEAD'

2. Set Up Project Context

Invest time in setting up .omni-dev/ configuration:

  • Define meaningful scopes for your project
  • Document your commit conventions
  • Include file pattern matching for accuracy

3. Batch Size Guidelines

Repository Size Suggested Batch Size Reasoning
Small projects 6-8 commits Faster processing
Medium projects 4-5 commits Balanced accuracy/speed
Large projects 2-3 commits More context per batch
Complex changes 1-2 commits Maximum accuracy

4. Review Before Applying

For important branches, always review suggestions:

# Save first, review, then apply
omni-dev git commit message twiddle 'main..HEAD' --save-only review.yaml
# Review the file...
omni-dev git commit message amend review.yaml

5. Clean Working Directory

Always ensure clean working directory:

# Check status first
git status

# Commit or stash changes before running omni-dev
git add . && git commit -m "temp" || git stash
omni-dev git commit message twiddle 'HEAD~5..HEAD' --use-context

6. API Key Security

Keep your Claude API key in an environment variable or .env file; never in command-line arguments or scripts. See Authentication for the canonical setup guide.

7. Integration with Team Workflow

Make it part of your team's process:

# Add to PR template
echo "- [ ] Run \`omni-dev git commit message twiddle 'main..HEAD' --use-context\`" >> .github/pull_request_template.md

# Document in CONTRIBUTING.md
echo "Before creating a PR, clean up commit messages with omni-dev" >> CONTRIBUTING.md

# Add PR creation to workflow
echo "Create PR with: \`omni-dev git branch create pr\`" >> CONTRIBUTING.md

8. PR Creation Best Practices

Optimize your PR creation workflow:

# ✅ Good - Clean commits first, then create PR
omni-dev git commit message twiddle 'main..HEAD' --use-context
omni-dev git branch create pr

# ✅ Good - Review PR details before creating
omni-dev git branch create pr --save-only review.yaml
# Edit file if needed, then use GitHub CLI or web interface

# ⚠️ Caution - Ensure working directory is clean
git status  # Check for uncommitted changes first

# ✅ Good - Use base branch when not default
omni-dev git branch create pr develop  # For non-main base branches

Troubleshooting

See Troubleshooting Guide for common issues and solutions.

Need Help?