Claude Code plugin for planning and implementing software with Linear and GitHub. Intended to work equally well with vanilla claude code running locally or as a self hosted Linear Agent driving the claude code sdk command line tool.
Install the required assistant dependencies first:
npx skills add shadcn/uiThen install this plugin:
claude plugin install linear-workflow@holos-runEnable agent teams for parent issue orchestration:
claude config set -g env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS 1Run the normal plan/implement loop:
/linear-workflow:plan-issue APP-123
/linear-workflow:implement-issue APP-234simple-workflow is the same plan/implement/review loop with every Linear call
replaced by plain markdown files in the repository's plans folder. Each plan and
phase is a file with YAML front matter for status and labels; every status
change is committed and pushed to main as it happens, and TODO.md in the
plans folder lists every open item. See
plugins/simple-workflow/README.md.
claude plugin install simple-workflow@holos-run
/simple-workflow:plan-issue "Add login with email and password"
/simple-workflow:implement-issue 001Label any Linear sub-issue to control which model implements it:
| Label | Runner |
|---|---|
| (none) | Claude Sonnet (default) |
sonnet |
Claude Sonnet |
opus |
Claude Opus (complex architecture, deep reasoning) |
codex |
Codex CLI (adversarial implementation via a separate model) |
The orchestrator reads these labels before dispatching each sub-agent, so you
can mix models within a single parent issue — assign opus to the hardest
sub-issues and leave the rest unlabeled for Sonnet. When conflicting labels are
present, precedence is: codex > opus > sonnet.
By default, when Cyrus picks up a sub-issue under a parent issue, its
determineBaseBranch rule resolves the base branch in this priority order:
[repo=<name>#<branch>]override tag at the top of the issue description- Graphite "blocked-by" relations
- Parent issue's branch (
parent-issuerule) - Repository default branch
Without an override tag, rule 3 wins for any sub-issue with a parent — so
Cyrus's activity message reads → cyrus/hol-1028-… and the sub-issue's
worktree is branched off the parent issue's branch instead of main. That
breaks the per-phase PR model: each sub-issue's commits stack on the parent's
branch and cannot merge to main independently.
plan-issue (v2.2.0+) prevents this by emitting a [repo=<repo-name>#main]
override on the very first line of every sub-issue description. The override
is the priority-0 commit-ish input to GitService and forces the sub-issue
worktree to branch from main.
implement-issue (v2.7.0+) defends against the same misrouting from the
other side. Before dispatching each child, the orchestrator inspects the
child's description and patches in the override if it is missing or points
somewhere other than main. Manually-created sub-issues, plans created by
older plan-issue versions, and follow-ups generated during review are
covered automatically.
The skill always runs in a Git worktree (Cyrus provisions a worktree per
issue). A given branch can only be checked out in one worktree at a time, so
the workflow never checks out main locally — main belongs to the
repo's primary worktree, not the issue worktree.
Instead, every leaf branch is created directly from origin/main:
git fetch origin
git checkout -b feat/<id>-<slug> origin/mainThat single checkout -b … origin/main form creates the new branch from the
fetched origin/main tip and sets the new branch's upstream tracking to
origin/main. Always push with git push origin HEAD (no -u) so the
upstream stays on origin/main; the PR is opened against main regardless.
Between sub-issue dispatches, the orchestrator stays on its own primary issue
branch and only runs git fetch origin to refresh remotes — it never moves
to main.
This plugin provides workflow skills that drive an adversarial
plan-implement-review cycle, plus targeted holos-console frontend skills
for dense resource UI and TanStack server-state work. Linear is the source of
truth for workflow-managed implementation; code ships through GitHub PRs. The
cycle works like this:
- A feature is described as a Linear issue.
- Plan — An agent explores the codebase, creates a new primary issue with a structured plan and phased sub-issues, then marks the original issue Done.
- Implement — For each sub-issue, an agent-team orchestrator dispatches teammates to:
- Implement the sub-issue (branch, code, tests, PR).
- Run adversarial code review (round 1).
- Fix round 1 findings.
- Run adversarial code review (round 2).
- Fix round 2 findings.
- Run a final review gate — if critical/important findings remain, the issue enters
needs-human-reviewand the skill stops. - Wait for CI; fix failures
- Merge to base branch.
- Repeat for all remaining sub-issues, then sweep for follow-ups.
- Summary posted back to the primary issue with wall clock timing.
The skills are project-agnostic — they read conventions (build commands,
test strategy, commit format) from the target repo's CLAUDE.md or AGENTS.md
rather than encoding them in the plugin.
claude plugin install linear-workflow@holos-run| Skill | Purpose |
|---|---|
/linear-workflow:plan-issue |
Explore codebase, create a new primary issue with phased sub-issues, relate back to original |
/linear-workflow:implement-issue |
Implement any Linear issue: leaf issues directly, parent issues via sub-agent orchestration |
/linear-workflow:enterprise-k8s-frontend |
Build dense operator-facing Vite + React resource list/detail workflows in holos-console using TanStack Router/Query/Table, ResourceGrid, shadcn/Tailwind, and ConnectRPC |
/linear-workflow:tanstack-query-and-grid |
Implement or refactor TanStack Query hooks, key factories, mutations, invalidation, and ResourceGrid toolbar/search/filter/sort server-state coordination |
# 1. Plan — creates a new primary issue with sub-issues
/linear-workflow:plan-issue APP-123
# 2. Implement — orchestrates all sub-issues under the new primary
/linear-workflow:implement-issue APP-234implement-issue self-detects whether the issue has children:
- No children → implements directly (branch, code, PR, review, CI, merge)
- Has children → spawns an agent-team, dispatches a teammate per sub-issue
- shadcn/ui assistant skill installed with
npx skills add shadcn/ui. Theenterprise-k8s-frontendandtanstack-query-and-gridskills rely on it for current shadcn project context, component docs, CLI behavior, and composition rules. - Linear MCP server configured (see below)
- GitHub CLI (
gh) authenticated with repo access - Git with a clean working directory
- Agent teams enabled for parent-mode orchestration (see below)
Parent-mode orchestration requires Claude Code agent-teams (experimental):
claude config set -g env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS 1Both Claude and any external review tools need persistent access to Linear. The
key pattern is mcp-remote with a Linear API key managed through direnv and
your system keychain.
Load the API key securely via direnv. Add to your project .envrc:
export LINEAR_API_KEY="$(ks show LINEAR_API_KEY)"This uses ks (keychain-store) to retrieve the key at shell init rather than storing it in plaintext.
Copy this to ~/.local/bin/linear-server and make executable.
#! /bin/bash
# Avoid reauth interruptions with an API key. install with:
# claude mcp remove linear-server
# claude mcp add linear-server --scope user -- ~/.local/bin/linear-server
set -euo pipefail
if [[ -z "${LINEAR_API_KEY}" ]]; then
echo "empty LINEAR_API_KEY" >&2
exit 1
fi
exec npx mcp-remote https://mcp.linear.app/mcp --header "Authorization: Bearer ${LINEAR_API_KEY}"Then configure the MCP:
claude mcp add linear-server --scope user -- ~/.local/bin/linear-serverThe implement-issue skill runs adversarial code review on every PR (up to 2 fix rounds + a final gate check). By default it detects the runtime performing the primary implementation and selects the opposite model family:
- Codex implementation → Claude Code CLI with
--model opus, the alias for the latest Claude Opus model - Claude Code implementation → the latest Codex frontier model resolved from the current Codex model catalog
The skill records the primary runtime before it launches a reviewer. Native host identity is authoritative; only an unidentified host consults environment markers such as CODEX_THREAD_ID. It never infers the runtime from command -v: both CLIs may be installed in the same environment.
--model and issue routing labels affect implementation only. Use the dedicated --reviewer option when an explicit reviewer override is required:
/linear-workflow:implement-issue APP-234 --reviewer codex
/linear-workflow:implement-issue APP-234 --reviewer opus
--reviewer claude and --reviewer opus both select the latest Claude Opus through the moving opus alias; fable, sonnet, and haiku remain explicit Claude reviewer choices.
An override that selects the implementation model family is allowed but called out in the PR review comment as same-family review.
- Both CLIs run in the foreground, with every network-dependent command bounded by
timeout --kill-afterso aSIGTERM-ignoring process still dies; the host shell tool's deadline stays strictly longer than the attempt's combined worst case so every exit status is observed. - The PR diff is supplied on stdin and final review text is captured before the workflow continues.
- Every review reports
APPROVEorREQUEST_CHANGESand uses[CRITICAL],[IMPORTANT], and[STYLE]findings. - A failed cross-runtime reviewer is retried once, then escalated to human review. It never falls back to the implementation model family. The escalation comment carries the captured evidence — exit status, stderr tail, and result envelope — so the failure is diagnosable.
Codex review resolves the visible model described as the latest frontier from codex debug models, then runs codex exec --model "$CODEX_FRONTIER_MODEL". A Codex MCP tool is eligible only when it can use that resolved slug; the GitHub Codex integration is not used because its review trigger cannot accept the selected frontier model.
Claude review requires an authenticated claude CLI with access to its latest opus alias, plus jq. Before the first round the skill proves the CLI end-to-end with a cheap bounded probe (claude --print --output-format json "Reply with exactly the word OK"), catching auth, model-access, and network failures up front. Review rounds also run with --output-format json and capture stderr separately: the JSON result envelope makes success machine-checkable where an empty text stream is ambiguous. A round counts as a review only when the diff fetch, the CLI call, and the strict envelope extraction all succeed and the review text contains an explicit verdict; anything else is retried once, then escalated with truncated, redacted evidence. All reviewer artifacts live in a private mktemp -d directory that is removed when review concludes.
If the primary runtime cannot be identified, a fenced reviewer command in the target project's CLAUDE.md or AGENTS.md ## Code Review section may be used. The command can reference $PR_NUMBER, $BRANCH, and $REPO:
## Code Review
```bash
CODEX_FRONTIER_MODEL=$(codex debug models | jq -er '
[.models[]
| select(.visibility == "list")
| select(((.description // "") | ascii_downcase) | contains("latest frontier"))]
| sort_by(.priority)
| (.[0].slug // empty)
')
test -n "$CODEX_FRONTIER_MODEL"
codex exec --model "$CODEX_FRONTIER_MODEL" --dangerously-bypass-approvals-and-sandbox \
"Review PR #$PR_NUMBER on branch $BRANCH in $REPO."
```
Without an explicit project command, the skill escalates rather than guessing.
Original issue (rough idea)
├── Agent explores codebase
├── Creates NEW primary issue with plan + sub-issues
│ ├── Sub-issue: phase 1
│ ├── Sub-issue: phase 2
│ └── Sub-issue: phase 3
├── Links original ←related→ new primary
└── Marks original Done ("planning complete")
The original issue's task is "plan this feature." When planning completes, that task is done. The new primary issue tracks implementation.
Issue
├── Branch + implement + open PR
├── Code review round 1 → fix
├── Code review round 2 → fix
├── Code review FINAL → escalate or proceed
├── CI checks → fix or escalate
├── Merge
└── Mark Done (or needs-human-review)
Parent issue
├── List children (sub-issues)
├── Create agent-team with sequential tasks
│
├── Teammate 1: implement-issue sub-issue-1 (leaf mode)
│ └── branch → code → PR → review → fix → CI → merge
├── Teammate 2: implement-issue sub-issue-2 (leaf mode)
│ └── branch → code → PR → review → fix → CI → merge
├── Teammate 3: implement-issue sub-issue-3 (leaf mode)
│ └── ...
│
├── Sweep for follow-up issues
├── Post summary with wall clock timing
└── Mark parent Done (if all children complete)