A comprehensive guide to using omni-dev's AI-powered commit message intelligence.
- Your First Improvement
- Getting Started
- Core Concepts
- Command Reference
- Claude Code Integration
- Atlassian Integration
- Datadog Integration
- Gmail Integration
- Contextual Intelligence
- Workflows
- Advanced Usage
- Best Practices
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.
git checkout -b omni-dev-tutorial
echo "" >> README.md
git add README.md
git commit -m "wip"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.
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.
git log --oneline HEAD~1..HEADExpected: the subject line is now the AI-suggested message.
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.
git checkout - && git branch -D omni-dev-tutorialYou 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.
-
Install omni-dev
cargo install omni-dev
-
Authenticate. By default,
export CLAUDE_API_KEY="sk-ant-...". See Authentication for the full reference (alternative env-var names,.envfiles, CI/CD secrets, non-Anthropic backends). -
Verify Installation
omni-dev --version omni-dev help-all # See all available commands
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 descriptionomni-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- 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
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'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 infoThe output includes:
- Commit metadata (hash, author, date, message)
- File changes and diff statistics
- Conventional commit type detection
- Proposed improvements
- Remote branch tracking
Apply specific amendments from a YAML file:
# Apply amendments from file
omni-dev git commit message amend amendments.yamlYAML 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 controlAmending 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.yamlMain-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.
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 --twiddleKey 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 |
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.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).
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-7The session reads stdin one line at a time and prints the response. Type
Ctrl+D (EOF) to exit.
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 --pruneThe 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.
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-runEnd-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 --worktreesSame 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.
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 resolveGenerates 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 view → twiddle → branch 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-updateRun 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.
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.
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 logoutauth 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-tokenEnvironment 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 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, viaconfirm: 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) printsCancelled.and exits without calling the API. Two escape hatches:
--forceskips the prompt — for scripts.--dry-runprintsWould delete PROJ-123 (Fix login).and exits without calling the API.--dry-runtakes precedence over--force, so a scripted--forceinvocation can be sanity-checked by adding--dry-runwithout 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 explicitconfirm: trueparameter 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--forcemode and deletes without aconfirmparameter.Interactive prompts catch human accidents;
--forcekeeps scripts working;--dry-runis a server-free preview; the MCPconfirm: truerequirement gives assistants an explicit opt-in. See ADR-0027 for the full design rationale.
# 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:
- Fetches the issue and writes JFM to a temp file
- Prompts:
[A]ccept, [S]how, [E]dit, or [Q]uit? - 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...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 0Output is a formatted table: KEY | STATUS | ASSIGNEE | SUMMARY.
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-runMetadata 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.NAMEis everything before it (surrounding whitespace trimmed);VALUEis everything after, kept verbatim — spaces, parentheses, and further=are all literal, so the only quoting needed is your shell's. - Value typing.
VALUEis 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 number5for 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, soLabels=a , b ,sends["a", "b"]andLabels=""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.
NAMEresolves against the create screen for the target project + issue type. Acustomfield_<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-fieldentry overrides the frontmattercustom_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.
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 21Transitions 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.
# 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# Delete with confirmation prompt
omni-dev atlassian jira delete PROJ-123
# Skip confirmation
omni-dev atlassian jira delete PROJ-123 --force# List all accessible projects
omni-dev atlassian jira project list
omni-dev atlassian jira project list --limit 100Create-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 yamlFor 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 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 jsonOutput 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).
# 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"# 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# 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# 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 10010Manage 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 10001Add 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 staleManage 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 10000Resolve 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 100Show 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# 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-2Remote (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 10010View 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# 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# 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 12345Confluence 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...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 byrun.
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 forcompare 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-N—Nversions 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 thanNcharacters 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 to16384(~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-inlineEnd-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 onlySee also: confluence_compare / confluence_compare_section
for the MCP equivalents.
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# 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-runCopy 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"# 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 --purgeList 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# 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# 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 deprecatedManage 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 5b10ac8d82e05b22cc7d4ef5View 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 developersomni-dev atlassian confluence user search --query "Alice"
omni-dev atlassian confluence user search --query "@example.com" --limit 50Recursively 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-attachmentsManage 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.
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.
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 0JFM 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]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:prodEvery Datadog CLI subcommand has a matching datadog_* MCP tool — see
docs/mcp.md.
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 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
mkdir .omni-devTell 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*"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
## Examplesfeat(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
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 --checkEnd-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 reviewHandle 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-commitsWork 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 manuallyHandle 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.yamlImprove 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 neededSet 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 conventionsUse 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.mdAdjust 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-coherenceSet 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
}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.yamlAlways 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'Invest time in setting up .omni-dev/ configuration:
- Define meaningful scopes for your project
- Document your commit conventions
- Include file pattern matching for accuracy
| 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 |
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.yamlAlways 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-contextKeep 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.
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.mdOptimize 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 branchesSee Troubleshooting Guide for common issues and solutions.
- 📖 Configuration Guide - Detailed setup instructions
- 🔧 Troubleshooting - Common issues
- 📝 Examples - Real-world usage examples
- 💬 GitHub Discussions - Community support
- 🐛 GitHub Issues - Bug reports and features