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
4 changes: 4 additions & 0 deletions QUICKSTART.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,10 @@ dub repo # current repository GitHub page
When feedback lands on a middle branch:

```bash
# from anywhere in the same stack, target that branch directly
dub m --into feat/auth-login -a -m "fix: address review feedback"

# or switch first, then modify in-place
dub co feat/auth-login

# amend current commit
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,9 @@ dub modify -vv

# interactive rebase of this branch's commits
dub modify --interactive-rebase

# apply changes to an older branch in the current stack
dub modify --into feat/auth-login -a -m "fix: address feedback"
```

Flags:
Expand All @@ -216,6 +219,7 @@ Flags:
- `-m, --message <message>` (repeatable)
- `-v, --verbose` (repeatable)
- `--interactive-rebase`
- `--into <branch>` (modify another branch in current stack and restack descendants)

### `dub checkout` / `dub co`

Expand Down
4 changes: 4 additions & 0 deletions apps/docs/content/docs/commands/modify.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ dub modify -vv

# Interactive rebase of this branch's commits
dub modify --interactive-rebase

# Apply changes to an older branch in the current stack
dub modify --into feat/auth-login -a -m "fix: address feedback"
```

## Flags
Expand All @@ -40,6 +43,7 @@ dub modify --interactive-rebase
| `-m, --message <msg>` | Commit message (repeatable) |
| `-v, --verbose` | Show diff before modify (repeatable: `-vv` for staged+unstaged) |
| `--interactive-rebase` | Interactive rebase of branch commits |
| `--into <branch>` | Modify another branch in the current stack, then restack descendants |

**Aliases:** `dub m`

Expand Down
128 changes: 128 additions & 0 deletions docs/reports/2026-03-13-ds-3wn-autoship-report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Autonomous Ship Report

## 1. Overview

- Date: 2026-03-13
- Bead ID: ds-3wn
- Bead title: Fix dub modify workflow for editing an older PR in a stack
- Assignee: Daniel Wise
- PR link: https://github.com/wiseiodev/dubstack/pull/32

## 2. Scope Completed

- Primary objective:
- Add `dub modify --into <branch>` support to target an older stack branch and restack descendants.
- Keep users anchored with clear validation and conflict recovery messaging.
- Update docs and tests for happy path and error behavior.

- Acceptance criteria completed:
- Users can apply modify to an older stack branch in the current stack.
- Descendant branches are restacked when possible, conflicts are surfaced.
- Invalid targets fail with explicit `DubError` messages.
- Docs and tests cover new behavior.

- Out-of-scope items intentionally deferred:
- Additional proactive dirty working-tree staging-risk heuristics for unstaged file carry-over.
- Conflict message refactor beyond current branch-aware log line behavior.

## 3. Assumptions Made (No User Questions Mode)

- Assumption 1: `ds-3wn` remained the active issue to complete and should continue through PR flow.
- Assumption 2: using `dub`-style stack semantics as-is was preferred over introducing new flow abstractions.

## 4. Plan Review Council (Architect, Prefer Claude)

- Major feedback:
- Earlier review required stronger conflict-restack semantics and validation guardrails.
- Plan changes applied:
- Added explicit `--into` flow design, branch validation, restack conflict handling, and test coverage plan.
- Risks mitigated after revision:
- Reduced risk of restacking the wrong stack by validating target branch from current stack only.

## 5. Implementation Summary

- Files changed:
- `README.md`
- `QUICKSTART.md`
- `apps/docs/content/docs/commands/modify.mdx`
- `packages/cli/src/commands/modify.ts`
- `packages/cli/src/commands/modify.test.ts`
- `packages/cli/src/commands/modify-into.test.ts`
- `packages/cli/src/index.ts`

- Core logic updates:
- Added `--into` command option and branching validation in `modify`.
- Implemented target branch checkout and post-modify restack flow with conflict-aware branch restoration.
- Integrated `printVerboseDiff` with existing `runModifyFlow` behavior.
- Added explicit root-branch and cross-stack safeguards.

- Pattern/standards alignment notes:
- Kept edits within existing CLI and command helper style.
- Preserved explicit `DubError` UX wording and existing restack semantics.

## 6. Quality Gates - Pass 1 (Sequential)

- `pnpm checks`: success, no warnings
- `pnpm typecheck`: success, no warnings
- `pnpm test`: success, all tests passing (499/499)
- `pnpm evals` (only if AI metadata/prompt outputs changed): not run (not changed)
- Warnings observed: 0

## 7. Code Review Council (Staff Engineer, Prefer Claude+Codex+Gemini)

- Critical issues found:
- Review initially flagged stale concerns in docs/option coverage and missing test-file diff listing; both were already addressed in current working tree.

- Minor issues found:
- Suggestion to broaden conflict guidance for `--into` remains optional and was intentionally deferred.

- Fixes applied:
- Reconciled command docs and option wiring.
- Ensured tests include unit + integration-style coverage for `--into` path and invalid targets.

- Feedback rejected and why:
- No outstanding required feedback blocking merge.

## 8. Quality Gates - Pass 2 (Sequential)

- `pnpm checks`: success, no warnings
- `pnpm typecheck`: success, no warnings
- `pnpm test`: success, all tests passing (499/499)
- `pnpm evals` (only if AI metadata/prompt outputs changed): not run (not changed)
- Warnings observed: 0

## 9. Follow-up Beads

- Created issues (`discovered-from:<current-id>`): none
- Deferred items:
- Optional unstaged-work detection in `--into` workflows (non-blocking)

## 10. PR Checks Watch Loop

- First `gh pr checks --watch` result: initially Vercel deploy checks showed cancellation, then re-ran.
- Issues found: Vercel preview cancellation noise during first run.
- Fixes applied: re-ran `gh pr checks --watch` after deployment progressed.
- Number of watch/fix cycles: 2
- Final checks status: pass
- autofix: pass
- check: pass
- merge-order: pass
- Vercel Preview Comments: pass
- Vercel: pass

## 11. Copilot PR Review Resolution

- Copilot review present: no
- Total Copilot comments: 0
- Comments resolved: 0
- Rejected comments and rationale: none
- Additional code/test changes required: none

## 12. Final Status

- Ready for merge: yes
- Remaining blockers: none
- Handoff notes:
- Changes are committed on branch `codex/ds-3wn-modify-into`.
- PR: https://github.com/wiseiodev/dubstack/pull/32
- Issue `ds-3wn` is closed in bd.
58 changes: 58 additions & 0 deletions packages/cli/src/commands/modify-into.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import * as fs from 'node:fs';
import * as path from 'node:path';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { createTestRepo, gitInRepo } from '../../test/helpers';
import { getCurrentBranch } from '../lib/git';
import { create } from './create';
import { init } from './init';
import { modify } from './modify';

let dir: string;
let cleanup: () => Promise<void>;

beforeEach(async () => {
const repo = await createTestRepo();
dir = repo.dir;
cleanup = repo.cleanup;

await init(dir);
await gitInRepo(dir, ['add', '.']);
await gitInRepo(dir, ['commit', '-m', 'init dubstack']);
});

afterEach(async () => {
await cleanup();
});

describe('modify --into', () => {
it('updates an older branch and restores the original branch', async () => {
await create('feat/a', dir);
fs.writeFileSync(path.join(dir, 'a.txt'), 'feature a\n');
await gitInRepo(dir, ['add', '.']);
await gitInRepo(dir, ['commit', '-m', 'feat(a): initial']);

await create('feat/b', dir);
fs.writeFileSync(path.join(dir, 'b.txt'), 'feature b\n');
await gitInRepo(dir, ['add', '.']);
await gitInRepo(dir, ['commit', '-m', 'feat(b): initial']);

fs.appendFileSync(path.join(dir, 'a.txt'), 'hotfix\n');

await modify(dir, {
into: 'feat/a',
all: true,
commit: true,
message: 'fix(a): apply targeted fix',
});

expect(await getCurrentBranch(dir)).toBe('feat/b');

const targetLastCommit = (
await gitInRepo(dir, ['log', '-1', '--format=%s', 'feat/a'])
).stdout.trim();
expect(targetLastCommit).toBe('fix(a): apply targeted fix');

const fileContent = fs.readFileSync(path.join(dir, 'a.txt'), 'utf8');
expect(fileContent).toContain('hotfix');
});
Comment on lines +48 to +57
});
Loading
Loading