Linear + jj workflow CLI for AI coding agents.
Ship bridges Linear task management with jj version control, providing AI coding agents with structured context about what to work on and how changes relate to tasks.
- Why Ship?
- Way of Working
- Quick Start
- Installation
- Commands
- OpenCode Integration
- Architecture
- Development
- Contributing
- Acknowledgments
AI coding agents need structured workflows. Ship provides:
- Task context - Know exactly what to work on next with
ship task ready - Dependency tracking - Understand what blocks what with
ship task blocked - Stacked changes - Manage jj-based stacked diffs tied to Linear tasks
- AI-first design - Built as an OpenCode plugin for seamless integration
Ship enforces a structured workflow that keeps AI agents (and humans) productive:
1. ship task ready → Find a task with no blockers
2. ship task start <id> → Mark it "In Progress" in Linear
3. ship stack create → Create an isolated workspace + jj change
4. [make changes] → Code in the workspace
5. ship stack sync → Rebase onto latest trunk
6. ship stack submit → Push and create/update PR
7. ship task done <id> → Mark task complete
Every stack create spins up an isolated jj workspace. This means:
- Parallel work - Multiple agents can work on different tasks simultaneously without conflicts
- Clean context - Each task gets its own working directory
- Safe experimentation - Abandon a workspace without affecting other work
Ship uses jj for stacked diffs:
trunk ← PR #1 (merged) ← PR #2 (in review) ← PR #3 (draft)
When PR #1 merges, ship stack sync automatically rebases your stack onto the new trunk. The webhook daemon notifies you when this happens.
Use ship task block to model dependencies between tasks:
ship task block BRI-100 BRI-101 # BRI-100 must complete before BRI-101ship task ready only shows tasks with no blockers, so agents always know what they can work on.
# Install globally
npm install -g @ship-cli/core
# Initialize in your project
ship init
# See what's ready to work on
ship task ready| Method | Command |
|---|---|
| npm (global) | npm install -g @ship-cli/core |
| pnpm (global) | pnpm add -g @ship-cli/core |
| npx (one-off) | npx @ship-cli/core init |
Add to your opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["@ship-cli/opencode"]
}Ship supports multiple task management backends:
| Provider | Status | Best For |
|---|---|---|
| Linear | Default | Teams using Linear for project management |
| Notion | Supported | Teams using Notion databases for tasks |
To use Notion instead of Linear, run ship init and select "Notion" when prompted, or see the Notion Setup Guide.
| Command | Description |
|---|---|
ship init |
Initialize ship (authenticate + select team/project) |
ship task ready |
List tasks with no blockers |
ship task list |
List all tasks |
ship task blocked |
List blocked tasks |
ship task show <id> |
Show task details |
ship task start <id> |
Start working on a task |
ship task done <id> |
Mark task as complete |
ship task create "<title>" |
Create a new task |
ship task update <id> |
Update task properties |
| Command | Description |
|---|---|
ship task block <blocker> <blocked> |
Mark task as blocking another |
ship task unblock <blocker> <blocked> |
Remove blocking relationship |
ship task relate <task> <related> |
Link related tasks |
| Command | Description |
|---|---|
ship stack log |
Show stack of changes |
ship stack status |
Show current change status |
ship stack create |
Create a new change in the stack |
ship stack sync |
Sync with remote (fetch + rebase) |
ship stack submit |
Push changes and create/update PRs |
ship stack squash |
Squash changes in the stack |
| Command | Description |
|---|---|
ship pr create |
Create PR for current bookmark with Linear task context |
ship pr stack |
Create stacked PRs for entire stack |
ship pr review [number] |
Fetch PR reviews and comments |
Creates a GitHub PR for the current bookmark with auto-populated task information:
ship pr create # Create PR with task context from Linear
ship pr create --draft # Create as draft PR
ship pr create --open # Open PR in browser after creationThe command extracts the task ID from your bookmark name (e.g., user/BRI-123-feature → BRI-123) and fetches task details from Linear to generate a rich PR body with summary, acceptance criteria, and task link.
Creates PRs for your entire stack with proper base branch targeting:
ship pr stack # Create PRs for all changes in stack
ship pr stack --dry-run # Preview what would be createdEach PR targets the previous PR's branch, enabling incremental code review:
trunk ← PR #1 (base: main) ← PR #2 (base: PR #1 branch) ← PR #3 (base: PR #2 branch)
Fetches PR reviews and comments in an AI-friendly format:
ship pr review # Review for current bookmark's PR
ship pr review 42 # Review for PR #42
ship pr review --unresolved # Show only actionable comments
ship pr review --json # Machine-readable outputOutput includes review verdicts, inline code comments with file:line context, and conversation threads - formatted for AI agents to understand and address feedback.
The @ship-cli/opencode plugin provides:
shiptool - Full task management within OpenCode sessions- Skill system - Detailed workflow guidance for AI agents
- Webhook events - Real-time notifications for PR reviews and comments
The ship tool exposes these actions to AI agents:
ready, list, blocked, show, start, done, create, update,
block, unblock, relate, status, stack-log, stack-status,
stack-create, stack-describe, stack-sync, stack-submit, ...
When OpenCode sessions are compacted to reduce context size, the Ship plugin automatically preserves task state:
- Current task ID - Which task the agent is working on
- Workspace path - The active jj workspace directory
After compaction, the agent is instructed to re-read the ship-cli skill and can seamlessly continue work on the same task without losing context.
Ship's webhook daemon enables real-time GitHub event notifications to AI agents. This closes the feedback loop between code review and agent response.
GitHub PR Event → smee.io → ship webhook daemon → OpenCode session
-
Start the daemon (once per machine):
ship webhook start
-
Auto-subscription on submit: When you run
ship stack submit, the agent is automatically subscribed to receive events for all PRs in the stack. -
Events routed to agents: The daemon routes GitHub events (merges, CI status, review comments) to the correct OpenCode session.
| Event | What Happens |
|---|---|
| PR Merged | Agent receives notification, can run stack-restack to rebase and push |
| CI Failed | Agent receives notification with failure details |
| Review Comment | Agent receives the comment, can address feedback |
| Changes Requested | Agent receives the review, can make fixes |
| PR Approved | Agent receives notification, can proceed with merge |
1. Agent submits PR #42 with `stack-submit`
→ Automatically subscribed to PR #42 events
2. Reviewer requests changes on PR #42
→ Agent receives: "[GitHub] Changes requested on PR #42"
3. Agent addresses feedback, runs `stack-submit` again
→ PR updated with new commits
4. PR #42 merged
→ Agent receives: "[GitHub] PR #42 merged"
→ Agent runs `stack-restack` to rebase and push remaining stack
This enables a tight feedback loop where agents can respond to code review without manual intervention.
Ship follows hexagonal architecture with Effect for type-safe, composable code:
packages/
cli/ # @ship-cli/core
src/
domain/ # Core entities (Task, Config)
ports/ # Interface definitions
adapters/
driven/ # External services (Linear, jj, GitHub)
driving/cli/ # CLI commands
infrastructure/ # Dependency injection layers
opencode-plugin/ # @ship-cli/opencode
# Clone and install
git clone https://github.com/EduSantosBrito/ship-cli
cd ship-cli
pnpm install
# Build all packages
pnpm build
# Run CLI in development
pnpm ship task ready
# Type check
pnpm check
# Test
pnpm testContributions are welcome! Please read our Contributing Guide for details on our development process, code style, and how to submit pull requests.
Ship is heavily inspired by:
- beads - Distributed, git-backed graph issue tracker for AI agents. The concept of giving AI agents structured task context and dependency tracking comes directly from beads.
- opencode-beads - OpenCode plugin for beads integration. Inspired the plugin architecture and OpenCode integration patterns.
Built with Effect for robust, type-safe TypeScript.