Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"name": "uberdev",
"source": "./plugins/uberdev",
"description": "GitHub workflow commands + full Superpowers skill suite (brainstorm with visual companion, write-plan, execute-plan, subagent-driven-dev wave-based parallel execution, finish-branch, systematic-debugging, TDD, worktrees, parallel-agents, verification, code-review pair, writing-skills, using-uberdev primer) and PR review agents. /solve and /turbo dispatch autonomous agents via a platform-aware dispatch backend (Workflow-native solver fleets by default, with detached wezterm / background transports opt-in — cross-platform on macOS, Linux, WSL2, native Windows); /issue creates well-investigated, deduped issues.",
"version": "0.56.1",
"version": "0.57.0",
"category": "workflow",
"tags": [
"github",
Expand Down
14 changes: 14 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,7 @@ jobs:
run_one bash tests/solve-fleet-workflow.test.sh
run_one bash tests/turbox-fleet.test.sh
run_one bash tests/turbox-fleet-runtime.test.sh
run_one bash tests/fix-lane.test.sh
run_one bash tests/review-pr-workflow.test.sh
run_one bash tests/goal-workflow.test.sh
run_one bash tests/uberthink-workflow.test.sh
Expand Down Expand Up @@ -1029,6 +1030,19 @@ jobs:
# uberscan-report. Its SHAPE twin,
# turbox-fleet.test.sh, is pure
# grep-and-assert and runs on BOTH jobs)
# - fix-lane.test.sh (RFC 0022: its FX-E rows EXECUTE the
# launcher and lib/turbox-fleet.sh, handing
# python3 absolute mktemp -d paths on argv
# — the same Git Bash path-translation
# class as turbox-fleet-runtime.test.sh.
# Executing those guards is the point: FX1
# and the FX2 knob check sit ahead of the
# first gh call so a refused run writes no
# claim, and only an executed row can prove
# that. The FX-S rows are pure grep, but
# they live in the same file rather than a
# shape twin, so the whole fixture is
# declared here)
# - sdd-wave-contract.test.sh (#650: hands python3 mktemp -d paths
# on argv, copies scratch trees under
# mktemp -d, and sources an extracted
Expand Down
66 changes: 66 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,72 @@ All notable changes to UberDev are documented here.

The format is based on [Keep a Changelog 1.1.0](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.57.0] — 2026-08-24

### Added — `/fix`, the lean single-issue lane (RFC 0022)

`/fix <issue#>` solves exactly one issue with **one** implementer, **one**
`code-reviewer` over the whole diff, at most one fix round, and a PR this
session pushes and parks. Two sequential agent rungs on the happy path, three
when the review comes back red — against `/turbox`'s eight or more.

It is a **narrowing of standard mode**, not a new transport: `commands/fix.md`
passes `--auto-mode=1 --turbo --standard --fix` to the same launcher, and
`skills/fix-fleet/SKILL.md` reuses `lib/turbox-fleet.sh` for `worktree-add`,
`stage-commit`, `round-permitted` and `audit` rather than forking them.

**What it drops** is design: no risk-gated security lens, no design-planner, no
plan-reviewer, no wave decomposition, no per-task `spec-compliance-reviewer`.
**What it keeps** is diligence: the full launcher preflight and claim protocol,
worktree isolation, the explicit-path staging refusal, an independent reviewer
validated through the canonical `uberdev_child_validate_phase1_review_result`
boundary, the project's full test suite, and the park-the-PR rule.

The lane's own failure mode is answered structurally rather than hoped away:
the implementer's return vocabulary carries **`TOO_BIG`**, a first-class answer
meaning *this issue wants a decomposition — run `/turbox`*. It ends the run with
the worktree and the claim intact, and the controller is told never to argue an
agent out of it.

Four circuit breakers (FX1–FX4) bound the arity, the fix ladder, the retest
ladder and unparseable returns. The one worth knowing at the CLI: a second
issue number is refused **before `gh` runs**, so a rejected invocation never
leaves an `uberdev:active` label behind. A red suite, standing blockers, or a
review result that never validated each open the PR as a **draft**. RFC 0022
section 3.6 has the table. Committed work never strands in a worktree, and the lane
never re-runs a suite hoping for a different answer.

### Changed

- `lib/turbox-fleet.sh` — `audit` gained an optional `--basename` (default
`turbox-audit.jsonl`; `/fix` passes `fix-audit.jsonl`). A name, not a path —
a `/` or `..` is refused.
- `lib/solve-launcher.sh` — the `--fix` launcher option (requires
`--standard`), the FX1 arity refusal and the FX2 knob validation ahead of the
first `gh` call, and Step 5f's `FIX_PLAN_BEGIN`/`FIX_PLAN_END` envelope — a
third marker pair, because each marker names exactly one executor.
- `CLAUDE.md` — the bump-lane table gained a fourth row. `/turbox` and `/fix`
open one PR per issue rather than a stack, so there is no once-per-stack
commit to carry the bump; it rides whatever lands the PR. Reviewing such a PR
as an unbumped user-facing change is a false positive.
- The short-form alias set is now **sixteen**. `/fix` was added across all six
alias surfaces — `lib/aliases-sync.sh` (the SSOT row **and** the notice
string), `commands/install-aliases.md`, `commands/uninstall-aliases.md`,
`README.md`, `skills/using-uberdev/references/configuration.md`, and
`tests/aliases.test.sh`. The five-surface recipe repeated across RFCs 0005,
0007, 0008, 0009 and 0010 omits `configuration.md`, which `docs-accuracy` T6b
provably enforces; the correction is now recorded in `tests/aliases.test.sh`'s
header.

### Fixed

- Pre-existing alias drift, surfaced by making the count correct: `/turbox` was
missing from the README alias table and the `UBERDEV_NO_AUTO_ALIAS` row while
the prose claimed fifteen forwarders, and `/turbox` and `/premerge` were
missing from `tests/aliases.test.sh`'s A1 and A6 enumeration loops — so
neither command's forwarder nor its `allowed-tools` byte-equality was ever
checked.

## [0.56.1] — 2026-08-24

### Changed — the project rule file is `CLAUDE.md`, not `AGENTS.md`
Expand Down
7 changes: 4 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,18 @@

**Every user-facing change MUST arrive on `main` with the project version advanced.** The invariant binds the **landing commit** — the commit that actually puts the change on `main` — not every pull request along the way. If users never see a version change they never pull the update from the marketplace, and the change is invisible to them no matter how good it is.

Which commit that is depends on the lane the change came through, and one lane deliberately forbids the PR author from bumping at all. Check the lane before reading the diff.
Which commit that is depends on the lane the change came through, and two of them deliberately forbid the PR author from bumping at all. Check the lane before reading the diff.

### Which commit carries the bump — the three lanes
### Which commit carries the bump — the four lanes

| Lane | Commit that carries the bump | What guarantees it |
|---|---|---|
| **`/goal`** | a `chore(release): vX.Y.Z` commit the pipeline pushes onto the PR branch on an **earlier pass** — the pass that pushes it deliberately withholds `/merge`, so the checks the push restarted can settle, and the dispatch happens on a later pass | `_uberdev_goal_ensure_version_bump` (`plugins/uberdev/lib/goal-state.sh`), called from the barrier-gated merge dispatch in `plugins/uberdev/lib/goal-watch.sh` (step 2c). It **fails closed**: any status it does not recognise as "bumped" withholds the `/merge` dispatch, and each failure stage it *does* recognise writes a `goal_merge_deferred` audit row with `reason=version_bump_failed` — the caller's catch-all arm withholds on an unrecognised status without writing a row of its own. Landing unbumped is the bug, so merging is never the fallback. |
| **`/solve` + `/turbo` fleet PRs** | the integration commit that lands the stack — `chore(stack): land #A #B … (vX.Y.Z)` — **once per stack**, never once per PR | `plugins/uberdev/skills/solve-fleet/workflow.js` tells every solver, in the dispatch prompt itself: *Do NOT bump the project version.* N solvers cut from one base all resolve the **same** next version; git auto-merges that identical edit with no conflict, so two intended releases collapse into one and a release is lost silently. |
| **`/turbox` + `/fix` session-fleet PRs** | the commit that lands that PR — a `/premerge` stack commit, or a `chore(release): vX.Y.Z` commit on the branch before a direct merge | `plugins/uberdev/skills/turbox-fleet/SKILL.md` Phase 6 and `plugins/uberdev/skills/fix-fleet/SKILL.md` Phase 5 each forbid the writer from bumping. These lanes open **one PR per issue**, not a stack, so there is no once-per-stack commit to carry it — the bump rides whatever lands the PR. |
| **Hand-authored PR landed directly** | the PR's own commits, or an immediately-preceding `chore(release): vX.Y.Z` commit on the same branch | the author. Nothing automated covers this lane. |

**A fleet PR whose diff carries no version surface is compliant.** Its bump belongs to the landing commit, and `plugins/uberdev/skills/solve-fleet/workflow.js` forbids the solver from writing one — so reviewing such a PR as an unbumped user-facing change is a false positive, not a blocker.
**A fleet PR whose diff carries no version surface is compliant.** Its bump belongs to the landing commit, and the writer is forbidden from producing one — `plugins/uberdev/skills/solve-fleet/workflow.js` for `/solve` and `/turbo`, `skills/turbox-fleet/SKILL.md` Phase 6 for `/turbox`, `skills/fix-fleet/SKILL.md` Phase 5 for `/fix`. Reviewing such a PR as an unbumped user-facing change is a false positive, not a blocker.

The lane carve-out governs **which commit carries the bump**, never **whether** a user-facing change may ship unbumped. **No exception for "small fixes" — even one-line patches get a patch-version bump on the commit that lands them.**

Expand Down
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

**Personal Claude Code marketplace — opinionated GitHub-workflow slash commands.**

[![Version](https://img.shields.io/badge/version-0.56.1-blue)](./CHANGELOG.md)
[![Version](https://img.shields.io/badge/version-0.57.0-blue)](./CHANGELOG.md)
[![License](https://img.shields.io/badge/license-MIT-green)](./LICENSE)
[![Claude Code](https://img.shields.io/badge/Claude%20Code-plugin-8B5CF6)](https://docs.claude.com/en/docs/claude-code/plugins)
[![Repo Agnostic](https://img.shields.io/badge/repo--agnostic-yes-success)](#configuration)
Expand Down Expand Up @@ -40,6 +40,7 @@ UberDev's whole personality is **parallel agent fanout**: `/issue` runs a 2-scou
| **`/solve <issue#>`** | Runs an autonomous solver per issue as a worktree-isolated agent in the session's Workflow runtime (watch with `/workflows`). Tier-aware: trivial issues skip design; medium gets a parallel research fan-out → spec → plan → implement chain. Detached transports remain available via `--backend=`. |
| **`/turbo <issue#>`** | Unattended `/solve`. Same pipeline, but the brainstorm phase auto-accepts the lead agent's recommendation and Q&A is resolved against the research bundle. Use when you trust the recommendation and want issue → PR with no babysitting. |
| **`/turbox <issue#>`** | Unattended `/turbo` in **standard mode**: this session orchestrates the fleet through the `Task` tool instead of the Workflow runtime, so the implementation phase runs **waves of parallel implementers over disjoint file sets** — which the Workflow lane's leaf agents structurally cannot do. Design and delivery fan out across issues too. Parallel-issue cap **3**. Costs session context; buys wall-clock. (RFC 0020) |
| **`/fix <issue#>`** | Lean single-issue lane — the speedup version of `/turbox`. **One** implementer, **one** `code-reviewer` over the whole diff, at most one fix round, then push and park the PR. Drops the security-research, design-planner, plan-reviewer and wave-decomposition rungs by construction: 2–3 sequential agent rungs against `/turbox`'s 8+. Exactly one issue per invocation — a second is refused before any claim is written. When the issue turns out to want a decomposition, the implementer answers `TOO_BIG` and the lane stops and points at `/turbox`. (RFC 0022) |
| **`/issue <description>`** | Creates a well-investigated, deduped, label-validated GitHub issue from a one-line ask. 2-scout fanout (codebase + triage) runs in <30 s, with conventional-commit titling and template-by-type. |
| **`/review-pr [<PR#>]`** | Comprehensive PR review using specialized agents in cap-controlled dispatch-before-wait waves — code review, simplifier, silent-failure hunter, type-design analyzer, comment analyzer, test analyzer. With more than one PR open it first offers (interactively, once) to combine them all onto a single review branch and run the pipeline once over the combined result — cheaper by a factor of N, at the cost of per-PR revert granularity and per-PR finding attribution. `--consolidate` accepts without asking; `--no-consolidate` declines permanently and wins over `--consolidate`. Never offered under `--turbo`, without a TTY, or on a chained `finish-branch` run. |
| **`/merge [<PR#> \| --all]`** | Lands an approved PR into the integration branch — autopilot. Bare invocation auto-discovers scope: single PR for the current branch, or all eligible open PRs against `integration_branch`. Ordering, per-PR strategy, conflict resolution (one parallel agent per conflicted file), and local sync, all unattended. |
Expand Down Expand Up @@ -73,7 +74,7 @@ Then in Claude Code:
/uberdev:issue trivial typo in README install step # smoke-test
```

The fifteen short-form aliases (`/issue`, `/solve`, `/turbo`, `/turbox`, `/simplify`, `/review-pr`, `/merge`, `/premerge`, `/dev`, `/testers`, `/ubergoal`, `/uberscan`, `/ubersimplify`, `/uberthink`, `/ubercluster`) are auto-installed on first session and refreshed on plugin upgrade — `jq` is not required, and if a short name collides with an existing file the session context reports which alias was skipped. The first-run notice confirms "installs 15 aliases". Opt out with `auto_install_aliases: false` in `.claude/uberdev.local.md` or `UBERDEV_NO_AUTO_ALIAS=1`.
The sixteen short-form aliases (`/issue`, `/solve`, `/turbo`, `/turbox`, `/fix`, `/simplify`, `/review-pr`, `/merge`, `/premerge`, `/dev`, `/testers`, `/ubergoal`, `/uberscan`, `/ubersimplify`, `/uberthink`, `/ubercluster`) are auto-installed on first session and refreshed on plugin upgrade — `jq` is not required, and if a short name collides with an existing file the session context reports which alias was skipped. The first-run notice confirms "installed 16 aliases". Opt out with `auto_install_aliases: false` in `.claude/uberdev.local.md` or `UBERDEV_NO_AUTO_ALIAS=1`.

> **Why a bootstrap script?** Upstream Claude Code has a bug where `/plugin install` populates the cache but does not write `enabledPlugins` in `~/.claude/settings.json` — so `/uberdev:*` commands silently 404. `install.sh` does the install **and** jq-patches `enabledPlugins`. Idempotent. Requires `jq`.
>
Expand Down Expand Up @@ -452,7 +453,7 @@ goal:
|---|---|---|
| `UBERDEV_FANOUT_SOLVE_BG` | `fanout_concurrency.solve_bg` | Cap on parallel solvers dispatched by `/turbo`; int [1, 50], default 6 |
| `SOLVE_AUTO` | `solve_auto` | When `1`/`true`, resolves the permission bypass pair `--dangerously-skip-permissions --permission-mode bypassPermissions` (post-#241 the AUTO tier was collapsed into this bypass; on the default `workflow` backend the solvers inherit the session's permission tier instead — see above) |
| `UBERDEV_NO_AUTO_ALIAS` | `auto_install_aliases` | When `1`/`true` (env) or `false` (file), suppresses session-start auto-install of `/issue`, `/solve`, `/turbo`, `/simplify`, `/review-pr`, `/merge`, `/premerge`, `/dev`, `/testers`, `/ubergoal`, `/uberscan`, `/ubersimplify`, `/uberthink`, `/ubercluster` forwarders |
| `UBERDEV_NO_AUTO_ALIAS` | `auto_install_aliases` | When `1`/`true` (env) or `false` (file), suppresses session-start auto-install of `/issue`, `/solve`, `/turbo`, `/turbox`, `/fix`, `/simplify`, `/review-pr`, `/merge`, `/premerge`, `/dev`, `/testers`, `/ubergoal`, `/uberscan`, `/ubersimplify`, `/uberthink`, `/ubercluster` forwarders |
| `UBERDEV_INTEGRATION_BRANCH` | `integration_branch` | `/merge` target branch |
| `UBERDEV_PR_BASE_BRANCH` | `pr_base_branch` | Base branch new PRs target (`gh pr create --base`) and the pre-push secret-scan range base; default unset → the origin default branch. Set to a parent PR's branch to open a stacked PR |
| `UBERDEV_GOAL_MAX_CYCLES` | `goal.max_cycles` | `/uberdev:goal` hard cycle ceiling; int [1, 20], default 5 |
Expand All @@ -463,13 +464,15 @@ Precedence: CLI flag > env var > `.claude/uberdev.local.md` > default. Missing f

## Short-form aliases

Plugin commands are addressed as `/uberdev:<command>` by default — the `uberdev:` prefix is required by Claude Code's plugin manifest. Auto-install drops fifteen forwarders into `~/.claude/commands/`:
Plugin commands are addressed as `/uberdev:<command>` by default — the `uberdev:` prefix is required by Claude Code's plugin manifest. Auto-install drops sixteen forwarders into `~/.claude/commands/`:

| Short form | Canonical |
|---|---|
| `/issue` | `/uberdev:issue` |
| `/solve` | `/uberdev:solve` |
| `/turbo` | `/uberdev:turbo` |
| `/turbox` | `/uberdev:turbox` |
| `/fix` | `/uberdev:fix` |
| `/simplify` | `/uberdev:simplify` |
| `/review-pr` | `/uberdev:review-pr` |
| `/merge` | `/uberdev:merge` |
Expand Down
4 changes: 2 additions & 2 deletions docs/rfc/0019-vendored-upstream-policy.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ UberDev standalone gets the attribution record with it.
```

Every directory under `plugins/uberdev/skills/` and every file under
`plugins/uberdev/agents/` is a component. There are **78** of them: 20
third-party and 58 carrying `"origin": "uberdev"`. The originals are two-field
`plugins/uberdev/agents/` is a component. There are **79** of them: 20
third-party and 59 carrying `"origin": "uberdev"`. The originals are two-field
stubs; their only job is to make coverage two-way, so that a *new* undeclared
vendored file cannot hide among them.

Expand Down
Loading
Loading