Developer productivity CLI that connects GitHub, Jira, Slack, and Claude to reduce context-switching friction.
- Tracks which branch maps to which Jira/Notion ticket and PR
- Allows actions to be performed on Jira/Notion from CLI and automatically transitions tickets
- Stashes/restores work when switching between tasks
- Generates AI-written PR descriptions and review summaries via Claude
- Generates standup updates from recent git activity and posts them to Slack
- Context-aware
morg: shows branch detail on a tracked branch, or the full branch table otherwise - Live branch detail (
morg status) with ticket, PR, CI state, commits, and diff summary - Branch table (
morg ls) listing all active tasks at a glance - Rich ticket detail view: parent, child issues, issue links, Markdown description
- Bun ≥ 1.3
- gh CLI (authenticated)
gittmuxandopencodeformorg agentsessionssqlite3for OpenCode session discovery
bun add -g @devdavi/morgOr link from source:
git clone https://github.com/developerdavi/morg
cd morg
bun install && bun run build && bun run link:localmorg config # set API keys and enable integrations
morg init # initialize the current repomorg config stores credentials in ~/.morg/config.json. morg init stores project state in .morg/ inside the repository and can add .morg/ to your global Git ignore file. You'll need:
| Integration | Credential |
|---|---|
| Claude (API) | Anthropic API key (sk-ant-...) |
| Claude (CLI) | None — uses the locally installed claude CLI |
| Jira | Base URL + user email + API token |
| Slack | Bot token (xoxb-...) with chat:write scope |
morg config lets you choose between anthropic-api, claude-cli, or none as the AI provider.
It also stores defaultAgentProvider, used by morg agent start when neither the CLI nor prompt frontmatter selects a provider.
morg start MORG-42 # fetch ticket, create branch, transition to In Progress
morg start feat/my-feature # start from a branch name directly
morg start MORG-42 --worktree # create a git worktree instead of checking out
morg switch MORG-42 # stash current work, switch to task's branch
morg track [branch] [ticket] # link an existing branch to a ticket
morg untrack [branch] # stop tracking a branch
morg complete # merge into default branch, mark ticket done
morg complete --yes # skip confirmation
morg delete [branch] # delete a fully-merged branch
morg delete -f # force-delete even with unmerged commits
morg clean # bulk-delete all fully-merged branchesmorg # context-aware: detail if on a tracked branch, table otherwise
morg ls # table of all active branches with PR and CI badges (alias: branches)
morg status # detail for current branch: ticket, PR, CI, commits, diff
morg status <branch> # detail for a specific branch (accepts ticket ID, case-insensitive)
morg status --json # all tracked branches as JSONmorg tickets # list your recently viewed tickets (interactive picker)
morg tickets --plain # non-interactive table output
morg tickets --json # output as JSON
morg ticket MORG-42 # view ticket detail with action menu
morg ticket MORG-42 --plain # non-interactive detail view
morg ticket --plain # current branch's linked ticketThe detail view shows issue type, parent, child issues (including epic children), issue links with correct direction ("is blocked by" vs "blocks"), and the description rendered as Markdown with clickable links.
morg pr create # create PR; Claude writes the description, opens $EDITOR to edit
morg pr create --no-ai # create PR with empty description
morg pr create --draft # create as draft
morg pr create --title "..." --body "..." --yes # non-interactive
morg pr view # view PR for current branch (shows CI status)
morg pr view MORG-42 # view PR for a specific branch or ticket
morg pr view --web # open in browser
morg pr view --json # output as JSON
morg pr view --wait # poll until all CI checks pass or fail
morg pr review # list open PRs
morg pr review --ai # list open PRs with Claude summariesmorg sync # pull default branch, sync PR statuses, clean merged
morg sync --all # also offer rebase/merge for all active branchesmorg standup # generate standup from recent commits + tasks
morg standup --post # generate and post to configured Slack channel
morg standup --channel C01234567 # post to a specific channelmorg worktree list # list all worktrees tracked by morg
morg worktree clean # remove worktrees for done/abandoned branchesJira-driven OpenCode sessions run inside tmux and are keyed by ticket + prompt template name. OpenCode session IDs are discovered from OpenCode's local SQLite database by worktree path and stored in morg session state when available. Claude sessions are also supported and use deterministic morg-owned session IDs.
morg agent start MORG-42 # interactively choose a prompt template and attach
morg agent start MORG-42 --session planning # start a named session
morg agent start MORG-42 --provider claude # override the default provider for this session
morg agent start MORG-42 -y # accept defaults without prompts
morg agent start MORG-42 --no-attach # create/resume without attaching
morg agent attach MORG-42 --session planning
morg agent stop MORG-42 --session planning # kill tmux only; OpenCode session remains resumable
morg agent done MORG-42 --session planning # mark the named session done
morg agent delete MORG-42 --session planning # delete local morg session record only
morg agent cleanup # delete done session records and unused worktrees
morg agent list # grouped by ticket
morg agent status MORG-42 # all sessions for one ticket
morg agent prompt MORG-42 --session planning # show initial rendered prompt
morg agent dashboard # interactive OpenTUI dashboard
morg agent doctor MORG-42 # read-only local diagnosticsPrompt templates define available session types:
morg agent prompts list
morg agent prompts validate
morg agent prompts init # copy built-ins to .morg/prompts/
morg agent prompts init --globalProject templates live in .morg/prompts/*.md, global templates live in ~/.morg/prompts/*.md, and built-ins are used as fallback. Provider selection precedence is CLI --provider, then prompt frontmatter provider, then defaultAgentProvider from morg config.
Profiles let you switch between GitHub accounts, Jira instances, etc. Each profile
is a full copy of the global config at ~/.morg/profiles/<name>/config.json.
morg config profile current # show active profile and its source
morg config profile list # list all profiles
morg config profile create work # create a profile from current config
morg config profile edit work # edit a profile with the interactive wizard
morg config profile use work # activate a profile globally
morg config profile use work --project # activate for current project only
MORG_PROFILE=work morg tickets # use a profile for a single commandPriority: MORG_PROFILE env > project-level profile > global activeProfile.
Displays the current task's ticket ID in your shell prompt:
# add to ~/.zshrc
eval "$(morg prompt --shell zsh)"
# add to ~/.bashrc
eval "$(morg prompt --shell bash)"# add to ~/.zshrc
eval "$(morg completion zsh)"
# add to ~/.bashrc
eval "$(morg completion bash)"morg config --show # display current config (tokens redacted)
morg update # update to latest version
morg install-claude-skill # install the morg skill into ~/.claude/skills/User-global state lives under ~/.morg/:
~/.morg/
├── config.json # global config (API keys, active profile)
├── projects.json # registered repos
├── prompts/ # global agent prompt templates
└── profiles/
└── <name>/
└── config.json # named profile (full GlobalConfig overlay)
Project-local state lives under the repository's .morg/ directory, which morg init can add to your global Git ignore file:
<repo>/.morg/
├── config.json # per-repo config (GitHub repo, Jira project key, profile)
├── branches.json # branch tracking (branch → ticket, PR status)
├── sessions.json # agent session state (tmux + OpenCode IDs)
├── prompts/ # project agent prompt templates
└── worktrees/ # morg-created git worktrees
bun install
bun run dev -- status # run a command with live reload (no rebuild needed)
bun run build # bundle to dist/index.js
bun run typecheck
bun run lint:fix
bun run test
bun run test tests/integrations/jira.test.ts # run a single test file