You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Let gx doctor auto-finish agent branches without a GitHub remote (#405)
autoFinishReadyAgentBranches now falls back to a local direct merge
when origin or gh is unavailable, instead of disabling the sweep, so
the doctor flow can commit, merge, and prune agent branches on repos
that have no GitHub-backed PR surface. The dirty-worktree skip is
replaced by an auto-commit step so pending payloads land on the base
branch automatically, matching the behavior of gx branch finish.
agent-branch-finish.sh also learns to merge into an already-checked-out
base worktree when running in --direct-only --no-push mode, avoiding
the "branch already used by worktree" failure that blocked local-only
finishes whenever the primary checkout sat on the target base.
Co-authored-by: NagyVikt <nagy.viktordp@gmail.com>
-`gx doctor` currently disables its `autoFinishReadyAgentBranches` sweep whenever a repo lacks an `origin` remote, a GitHub-flavored origin, or a usable `gh` CLI.
4
+
- Repos without a GitHub remote (local mirrors, file-backed remotes, purely local multi-worktree setups) therefore leave agent branches behind after completed work: `gx doctor` reports "skipped auto-finish sweep" and users must run `gx branch finish ... --direct-only` manually per branch.
5
+
- The screenshot scenario is common: a parent repo checked out on `main` with a nested agent worktree under `.omc/.omx/agent-worktrees/...`. Users expect `gx doctor` to detect the agent worktree, commit its changes, merge into `main`, and remove the branch + worktree.
6
+
-`agent-branch-finish.sh` in `--direct-only --no-push` mode also fails when `BASE_BRANCH` is already checked out in the primary worktree because it tries to `git worktree add` a helper for the same branch.
7
+
8
+
## What Changes
9
+
10
+
- Relax `autoFinishReadyAgentBranches` (`src/doctor/index.js`) so the sweep no longer short-circuits when origin / `gh` are unavailable. Instead pick a per-branch fallback:
11
+
- no origin → `--direct-only --no-push --cleanup` (local merge + worktree/branch prune, no push).
12
+
- origin present but not GitHub-flavored or `gh` missing → `--direct-only --cleanup` (local merge + git push).
- Teach `agent-branch-finish.sh` (both `scripts/` and `templates/scripts/`) to reuse an already-checked-out base worktree when running in `--direct-only --no-push` mode, so `gx doctor` can merge into `main` without trying to create a second `main` worktree.
-`scripts/agent-branch-finish.sh` and `templates/scripts/agent-branch-finish.sh` (integration-helper branch for local direct mode)
21
+
- Affected regression coverage:
22
+
- New case in `test/doctor.test.js` covering the no-origin local fallback.
23
+
- Risk is moderate. The doctor sweep behavior change only activates when origin / gh are unavailable, preserving the existing PR-flow path for GitHub repos. The finish-script branch narrows to `MERGE_MODE=direct && PUSH_ENABLED=0`, so existing direct-with-push and PR flows are untouched.
### Requirement: doctor auto-finish sweep falls back to local direct merge
4
+
5
+
Guardex SHALL auto-finish ready agent branches during `gx doctor` even when the host repo lacks a GitHub-flavored `origin` remote or the `gh` CLI.
6
+
7
+
#### Scenario: repo without origin remote
8
+
9
+
-**GIVEN** a repo where `gx doctor` runs on a non-agent base branch (e.g. `main`)
10
+
-**AND** the repo has no `origin` remote configured
11
+
-**AND** at least one clean `agent/*` branch is ahead of the base
12
+
-**WHEN**`autoFinishReadyAgentBranches` runs
13
+
-**THEN** Guardex SHALL invoke `agent-branch-finish` with `--direct-only --no-push --cleanup`
14
+
-**AND** the agent branch SHALL be merged into the base branch locally
15
+
-**AND** the agent branch and its worktree SHALL be pruned after the merge completes
16
+
-**AND** the sweep summary SHALL report `completed=1` for that branch.
17
+
18
+
#### Scenario: non-GitHub origin remote or missing gh CLI
19
+
20
+
-**GIVEN**`gx doctor` runs on a non-agent base branch
21
+
-**AND** the repo has an `origin` remote that is not GitHub-flavored, or the `gh` CLI is not installed
22
+
-**AND** at least one clean `agent/*` branch is ahead of the base
23
+
-**WHEN**`autoFinishReadyAgentBranches` runs
24
+
-**THEN** Guardex SHALL invoke `agent-branch-finish` with `--direct-only --cleanup` so the merge is pushed to `origin` without attempting a PR.
25
+
26
+
### Requirement: doctor auto-finish commits dirty agent worktrees before merging
27
+
28
+
Guardex SHALL auto-commit pending worktree changes on an agent branch before evaluating the merge-or-skip decision in the doctor auto-finish sweep.
29
+
30
+
#### Scenario: uncommitted payload in agent worktree
31
+
32
+
-**GIVEN**`gx doctor` runs with an agent worktree that has uncommitted tracked/untracked changes
33
+
-**AND** the agent branch is otherwise clean (no merge in progress, no unresolved conflicts)
34
+
-**WHEN**`autoFinishReadyAgentBranches` reaches that branch
35
+
-**THEN** Guardex SHALL claim locks for the changed files, stage them, and commit them under the agent branch before attempting the merge
36
+
-**AND** the subsequent merge + cleanup SHALL run against the freshly committed state
37
+
-**AND** the auto-commit failure (if any) SHALL be reported as `[fail] ${branch}: auto-commit failed (...)` without aborting the rest of the sweep.
38
+
39
+
### Requirement: direct-only finish reuses existing base worktree when push is disabled
40
+
41
+
Guardex SHALL merge an agent branch directly into an already-checked-out base worktree when `agent-branch-finish` runs in direct mode with push disabled, instead of attempting to add a second worktree for the same base branch.
42
+
43
+
#### Scenario: base branch is the primary checkout
44
+
45
+
-**GIVEN**`scripts/agent-branch-finish.sh` is invoked with `--direct-only --no-push`
46
+
-**AND** the target base branch is already checked out in the primary worktree
47
+
-**AND** that worktree is clean
48
+
-**WHEN** the finish script reaches the integration-helper step
49
+
-**THEN** it SHALL run `git merge --no-ff --no-edit <agent-branch>` inside the existing base worktree
50
+
-**AND** it SHALL not call `git worktree add` for the same base branch
51
+
-**AND** a merge conflict SHALL abort cleanly without leaving a dangling integration worktree.
-[x] Capture requirement delta for doctor auto-finish local fallback in `specs/doctor/spec.md`.
6
+
7
+
## 2. Tests
8
+
9
+
-[x] Add `test/doctor.test.js` case covering `doctor --allow-protected-base-write` falling back to local direct merge (no origin, no `gh`).
10
+
-[x] Add `test/doctor.test.js` case covering the auto-commit-before-merge path for a dirty agent worktree under the same local fallback.
11
+
12
+
## 3. Implementation
13
+
14
+
-[x] Replace GitHub-only early-exit gates in `autoFinishReadyAgentBranches` with a per-branch fallback-mode selection (`local` / `direct` / `pr`).
15
+
-[x] Build `finishArgs` based on fallback mode so the sweep passes `--direct-only --no-push --cleanup` when no origin, `--direct-only --cleanup` when origin is non-GitHub or `gh` is unavailable, and keeps `--via-pr --cleanup` otherwise.
16
+
-[x] Teach `scripts/agent-branch-finish.sh` + `templates/scripts/agent-branch-finish.sh` to merge directly into an existing clean base worktree when `MERGE_MODE=direct && PUSH_ENABLED=0`, avoiding the "branch already used by worktree" failure.
17
+
-[x] Export `autoCommitWorktreeForFinish` from `src/finish/index.js` and call it from the doctor sweep before the dirty-worktree skip, so the sweep now commits pending worktree changes before merging.
18
+
19
+
## 4. Verification
20
+
21
+
-[x]`node --test test/doctor.test.js` (18/19 pass; the pre-existing `agent/planner/` regex in test 9 fails locally under Claude env due to auto-claudification in `agent-branch-start.sh`, unrelated to this change).
22
+
-[x]`node --test test/finish.test.js` (16/16 pass) — direct/PR finish flows still green after the base-worktree-merge branch.
23
+
24
+
## 5. Cleanup
25
+
26
+
-[ ] Commit agent branch work.
27
+
-[ ] Push `agent/claude/doctor-auto-finish-local-merge-2026-04-23-21-47` and open a PR against `main`.
28
+
-[ ] Record PR URL and `MERGED` evidence once merge lands.
29
+
-[ ] Run `gx branch finish --branch "agent/claude/doctor-auto-finish-local-merge-2026-04-23-21-47" --base main --via-pr --wait-for-merge --cleanup` so the sandbox worktree is pruned after merge.
0 commit comments