Skip to content
Merged
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 .agents/patterns/command-changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ Use this pattern when modifying files under `src/commands/*`.

- Ensure stack context is validated before mutating state.
- Preserve submit linearity constraints during submit workflows.
- Keep undo behavior single-level unless a scoped change explicitly expands it.
- Preserve the multi-level `undo`/`redo` ring buffer contract (20 entries, mutating commands save before mutation, new mutations clear the redo log); don't shrink coverage without a scoped change.

## 4) Test Nearby

Expand Down
2 changes: 1 addition & 1 deletion .agents/skills/dubstack/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Use this skill whenever the user is working in a repo that uses `dub` for stacke
| Show parent/children/trunk | `dub parent`, `dub children`, `dub trunk` |
| Submit PR stack | `dub submit` / `dub ss` |
| Open PR in browser | `dub pr [branch|number]` |
| Undo last create/restack | `dub undo` |
| Undo / redo | `dub undo` / `dub redo` (multi-level, 20-entry ring) |

## Command Notes

Expand Down
6 changes: 5 additions & 1 deletion .agents/skills/dubstack/references/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,11 @@ This is a concise command reference for agents using `dub`.

| Command | Purpose |
|---|---|
| `dub undo` | Undo last `create` or `restack` mutation |
| `dub undo` | Undo the most recent mutating `dub` command (multi-level; 20-entry ring at `.git/dubstack/undo-log.json`) |
| `dub undo --steps N` | Roll back the last `N` operations in sequence |
| `dub undo --list` | Show what's on the ring (newest first) |
| `dub redo` | Replay the most recently undone operation |
| `dub continue` / `dub abort` | Resume/cancel an interrupted restack or rebase |

## Skills Management

Expand Down
10 changes: 7 additions & 3 deletions .agents/skills/dubstack/references/workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,12 +132,16 @@ dub pr 123
## 8) Recover from Mistakes

```bash
dub undo
dub undo # undo most recent mutation
dub undo --steps 3 # roll back the last 3
dub undo --list # inspect the ring
dub redo # replay the most recently undone op
```

Notes:
- `undo` supports one level.
- Intended for reverting last `create` or `restack`.
- `undo`/`redo` is multi-level (20-entry ring at `.git/dubstack/undo-log.json`).
- Covers `create`, `restack`, `move`, `reorder`, `absorb`, `unlink`, `rename`, `pop`, `modify`, `freeze`/`unfreeze`, `track`/`untrack`, `delete`, `sync`, `split`, and `submit` (PR body restore only — PR retargets and pushes are not reverted).
- A new mutating command clears the redo log.

## 9) Repair Untracked Branch Metadata

Expand Down
2 changes: 1 addition & 1 deletion .claude/agents/code-reviewer.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Apply these principles from the code-principles skill. Read the reference files
- `create` must auto-initialize state via `ensureState(...)` — never assume state exists
- `restack` and `submit` must fail clearly when stack context is invalid
- `submit` scope flags (`--upstack`/`--downstack`/`--stack`/`--branch`) are mutually exclusive; tree stacks are supported. Legacy `--path` emits a deprecation warning.
- `undo` is single-level only — don't silently extend it
- `undo`/`redo` is multi-level (20-entry ring at `.git/dubstack/undo-log.json`); mutating commands save an entry before mutation, and a new mutation clears the redo log
- Error messages are UX and tested — change them deliberately, update tests
- Keep command files thin, push logic to `src/lib/*`
- ESM imports, 2-space indent, single quotes, kebab-case files
Expand Down
36 changes: 33 additions & 3 deletions QUICKSTART.md
Original file line number Diff line number Diff line change
Expand Up @@ -368,13 +368,23 @@ dub stash list

Useful when you start working on the wrong branch and want to move the changes elsewhere.

## 11) Undo Last Stack Mutation
## 11) Undo and Redo

```bash
# Undo the most recent mutating dub command
dub undo

# Roll back the last N operations
dub undo --steps 3

# Show what's on the ring (newest first)
dub undo --list

# Replay the most recently undone operation
dub redo
```

`dub undo` supports one level for `create` and `restack` operations.
`dub undo` is backed by a 20-entry ring buffer at `.git/dubstack/undo-log.json`. It reverses `create`, `restack`, `move`, `reorder`, `absorb`, `unlink`, `rename`, `pop`, `modify`, `freeze`/`unfreeze`, `track`/`untrack`, `delete`, `sync`, `split`, and `submit` (PR body restore only — PR retargeting and pushes are not reverted). Any new mutating command clears the redo log; until then `dub undo` ↔ `dub redo` cycle freely.

## Fast Command List

Expand All @@ -401,7 +411,7 @@ dub undo
| `dub delete` | Stack-aware branch deletion |
| `dub freeze` / `dub unfreeze` | Set/clear the `frozen` flag; restack/sync/post-merge skip frozen branches |
| `dub continue` / `dub abort` | Resume/cancel interrupted operations |
| `dub undo` | Undo last create/restack |
| `dub undo` / `dub redo` | Multi-level undo and redo (20-entry ring) |
| `dub stash` / `dub stash pop` / `dub stash list` | Branch-aware stash (refuses pop on wrong branch) |
| `dub config ai-assistant on` | Enable repo-local AI assistant |
| `dub config ai-provider bedrock` | Pin the repo-local AI provider |
Expand All @@ -410,6 +420,26 @@ dub undo
| `dub flow --ai -a` | Stage, preview, create, and submit with AI |
| `dub history` | Show recent Dub command history |

## Programmatic And Agent Use

Every read-only command supports `--json`. Payloads carry `schemaVersion: 1` and a stable shape; failures emit `{ schemaVersion, error: { message, recovery } }` with non-zero exit. Covered: `log`, `info`, `branch info`, `status`, `doctor`, `history`, `parent`, `children`, `trunk`, `merge-check`, `ready`.

For MCP-aware agents (Claude Code, Cursor):

```bash
claude mcp add dubstack dub mcp
dub config mcp-mode interactive # read-only | interactive (default) | trusted
dub history # MCP calls are audited here
```

## Optional: Theming and Storage

```bash
dub config theme dark # or: light, auto (default), none
dub config storage-backend sqlite # opt into SQLite for large stacks
dub migrate storage --to sqlite # copy state.json → SQLite
```

## Local AI Evals

```bash
Expand Down
96 changes: 91 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ If you have `gt` muscle memory, use this as a fast map:
| `gt parent` | `dub parent` |
| `gt children` | `dub children` |
| `gt trunk` | `dub trunk` |
| `gt undo` | `dub undo` |
| `gt undo` | `dub undo` (multi-level; pair with `dub redo`) |

## Quick Start

Expand Down Expand Up @@ -747,14 +747,36 @@ dub unfreeze feat/auth-login

`dub log` marks frozen branches with 🔒 and `dub doctor` lists them as an informational notice. Freeze wins over destructive maintenance flags: if a branch is frozen, unfreeze it explicitly before using `dub sync --force` or any other branch-mutating maintenance.

### `dub undo`
### `dub undo` / `dub redo`

Undo the last `dub create`, `dub restack`, `dub rename`, `dub move`, `dub pop`, `dub freeze`, or `dub unfreeze` operation.
Multi-level undo and redo backed by a 20-entry ring buffer at
`.git/dubstack/undo-log.json`. Reversal coverage includes `create`,
`restack`, `move`, `reorder`, `absorb`, `unlink`, `rename`, `pop`, `modify`,
`freeze`/`unfreeze`, `track`/`untrack`, `delete`, `sync`, `split`, and
`submit` (PR body restore only — PR retargets and pushes are not reverted).
Comment thread
dubscode marked this conversation as resolved.

```bash
# Undo the most recent mutating dub command
dub undo

# Roll back the last N operations
dub undo --steps 3

# Show what's on the ring (newest first)
dub undo --list

# Wipe both undo and redo logs
dub undo --clear

# Replay the most recently undone operation
dub redo
```

A new mutating command **clears** the redo log; until then `dub undo` ↔
`dub redo` cycle freely. If part of an undo can't fully succeed (a branch
was force-pushed, GitHub rejected a PR body update, etc.) DubStack undoes
what it can and prints `⚠ …` warnings with manual recovery hints.

### `dub completion <shell>` and `dub man`

Generate shell completions and a man page from the live commander definitions.
Expand Down Expand Up @@ -1073,6 +1095,69 @@ recovery } }` with a non-zero exit code. Covered commands: `log`, `info`,
[Programmatic use guide](https://dubstack.dev/docs/guides/json-output) for
the full schema reference.

### `dub mcp` (Model Context Protocol)

Expose DubStack to MCP-aware agents (Claude Code, Cursor, etc.) so they
can drive the stack without shelling out to free-form commands.

```bash
claude mcp add dubstack dub mcp
```

Mutating tools are gated by repo-local mode:

```bash
dub config mcp-mode read-only # disable mutating tools entirely
dub config mcp-mode interactive # terminal confirmation (default)
dub config mcp-mode trusted # allow mutating tools without prompts
```

Every MCP tool invocation — success, refusal, or failure — is appended to
`dub history` with redacted args and a `args_sha256` fingerprint. See the
[MCP server guide](https://dubstack.dev/docs/guides/mcp) for the tool list
and security model.

### Multi-trunk repositories

Repositories with multiple long-lived trunks (e.g. `main` plus a release
branch) can register additional trunks. DubStack records which trunk each
stack tracks and the default trunk used by `dub create` at the root.

```bash
dub trunk list # show configured trunks
dub trunk add release/24.04 # register an additional trunk
dub trunk set-default release/24.04
dub trunk remove release/24.04
```

`dub doctor` surfaces orphaned trunks (branches that lost their tracked
trunk after a rename or deletion) and walks you through reattachment.

### Storage backend (SQLite)

DubStack state defaults to `.git/dubstack/state.json`. Repositories with
very large stacks can opt into a SQLite backend for faster reads.

```bash
dub config storage-backend # show
dub config storage-backend sqlite # switch backend (does not migrate data)
dub migrate storage --to sqlite # copy state.json → SQLite
dub migrate storage --to json # copy SQLite → state.json
```

### Terminal theming

```bash
dub config theme # show
dub config theme auto # auto-detect light/dark from COLORFGBG (default)
dub config theme dark
dub config theme light
dub config theme none # equivalent to --no-color globally
```

`--no-color` on any invocation overrides the configured theme for that
run. Affects `log`, `status`, `sync`, and any other colorized output.

## Typical Workflows

### Add review feedback to a middle branch
Expand Down Expand Up @@ -1143,7 +1228,7 @@ dub restack --continue
| Need metadata-only removal | Use `dub untrack` (or `--downstack`) |
| Need stack-aware branch deletion | Use `dub delete` with `--upstack` / `--downstack` |
| Sync skipped branch | Re-run with `--interactive` or `--force` as appropriate |
| Wrong operation during create/restack/move | Use `dub undo` (single-level) |
| Wrong operation during create/restack/move | Use `dub undo` (multi-level; `dub redo` to replay) |
| PR merge blocked by order or GitHub conflict | Run `dub merge-check --pr <number>` to verify stack order and remote mergeability |
| Manual merge left stack inconsistent | Run `dub post-merge` |

Expand Down Expand Up @@ -1175,7 +1260,8 @@ DubStack stores local state in your repo:
```text
.git/dubstack/
├── state.json
├── undo.json
├── undo-log.json
├── redo-log.json
└── restack-progress.json
```

Expand Down
110 changes: 110 additions & 0 deletions apps/docs/content/docs/commands/ai.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
---
title: dub ai
description: AI assistant utilities — provider setup, prompts, env vars, and conflict resolution.
---

## Usage

```bash
# Guided provider + model setup (interactive)
dub ai setup

# Ask the assistant a question
dub ai ask "what changed in this stack?"

# Or use the implicit shortcut from the root command
dub "summarize the diff on this branch"

# Write provider settings into your shell profile
dub ai env --anthropic-key sk-...
dub ai env --gemini-key ... --gemini-model gemini-2.5-pro
dub ai env --ollama-base-url http://localhost:11434 --ollama-model qwen2.5-coder

# AI-assisted conflict resolution during a rebase/restack
dub ai resolve
dub ai resolve --dry-run
dub ai resolve --adjudicate
```

## Subcommands

### `dub ai setup`

Interactive provider + model picker. Prompts for the provider, a model
(or a custom model ID), and where to store the model (global shell profile
or repo-local `.git/dubstack/config.json`). Writes the chosen provider env
vars to your shell profile and updates `ai-provider` (and, for repo scope,
`ai-model`) in repo-local config.

### `dub ai ask <prompt...>`

Send a prompt to the configured AI provider. Requires the assistant to be
enabled with `dub config ai-assistant on`. The assistant has read-only bash
access to the repo for context gathering — destructive commands are
sandboxed out.

### `dub ai env`

Write provider keys, model overrides, and Bedrock/Ollama settings into your
shell profile (`.zshrc`, `.bashrc`/`.bash_profile`, or `.profile`).

| Flag | Env var written |
|---|---|
| `--gemini-key <key>` | `DUBSTACK_GEMINI_API_KEY` |
| `--anthropic-key <key>` | `DUBSTACK_ANTHROPIC_API_KEY` |
| `--gateway-key <key>` | `DUBSTACK_AI_GATEWAY_API_KEY` |
| `--openai-key <key>` | `DUBSTACK_OPENAI_API_KEY` |
| `--ollama-base-url <url>` | `DUBSTACK_OLLAMA_BASE_URL` |
| `--gemini-model <model>` | `DUBSTACK_GEMINI_MODEL` |
| `--anthropic-model <model>` | `DUBSTACK_ANTHROPIC_MODEL` |
| `--gateway-model <model>` | `DUBSTACK_AI_GATEWAY_MODEL` |
| `--openai-model <model>` | `DUBSTACK_OPENAI_MODEL` |
| `--ollama-model <model>` | `DUBSTACK_OLLAMA_MODEL` |
| `--bedrock-profile <profile>` | `DUBSTACK_BEDROCK_AWS_PROFILE` |
| `--bedrock-region <region>` | `DUBSTACK_BEDROCK_AWS_REGION` |
| `--bedrock-model <model>` | `DUBSTACK_BEDROCK_MODEL` |
| `--profile <path>` | Override target profile path |
| `--shell <shell>` | Force shell detection (`zsh` or `bash`) |

At least one key, model, or Bedrock setting must be passed.

### `dub ai resolve`

AI-assisted conflict resolver for in-progress rebase/restack operations.
Reads the conflict markers, asks the configured provider for resolutions,
and previews them before applying. After applying, it tries `dub continue`;
on test failures or new conflicts it retries once with feedback.

| Flag | Description |
|---|---|
| `--dry-run` | Show proposed resolutions without applying |
| `--abort` | Abort the active rebase/restack operation |
| `--adjudicate` | Resolve with two configured providers and reconcile disagreements |
| `--no-adjudicate` | Force single-provider mode |

When two providers are configured, adjudication runs by default. With
`--adjudicate`, both providers propose resolutions; matching outputs apply
automatically with `high` confidence, and disagreements prompt for which
side to take (or `skip`/`abort`). Disagreements are also written to
`.git/dubstack/ai-eval-bank/*.json` for later evaluation.

`--dry-run` shows both providers' answers for disagreement files and the
first provider's pick is recorded as the dry-run choice.

## Providers

| Provider | Required env (or other) |
|---|---|
| Gemini | `DUBSTACK_GEMINI_API_KEY` |
| Vercel AI Gateway | `DUBSTACK_AI_GATEWAY_API_KEY` |
| Amazon Bedrock | `DUBSTACK_BEDROCK_AWS_PROFILE`, `DUBSTACK_BEDROCK_AWS_REGION` |
| Anthropic | `DUBSTACK_ANTHROPIC_API_KEY` |
| OpenAI | `DUBSTACK_OPENAI_API_KEY` |
| Ollama (and LM Studio) | `DUBSTACK_OLLAMA_BASE_URL` (default `http://localhost:11434`) |

Provider selection is repo-local — `dub config ai-provider <name>` (or
`auto` to pick based on which env vars are set). Per-provider model
overrides live in repo config (`dub config ai-model --provider <p> <model>`)
or in `DUBSTACK_<PROVIDER>_MODEL` env vars.

See also: `dub config ai-assistant`, `dub config ai-provider`, `dub config ai-model`, `dub flow`.
Loading
Loading