# Full Bridge Implementation Plan

> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.

**Goal:** Deliver full `bridge` (no `--review-only`): commit-message turn → code-review turn → git commit/push → mock GitLab PR creation, with `bridge-state.json` resume across `needs_host_agent` pauses.

**Architecture:** Keep Plan 2 `bridge --review-only` unchanged. Full bridge reuses preflight + `runHostAgentReview`, adds `resolveHostAgentCommitMessage` (`client.complete`, `purpose: "commit-message"`), git commit/push helpers, session `bridge-state.json` for skip-on-resume, and mock PR after push. No external LLM HTTP. No real GitLab API.

**Tech Stack:** TypeScript 5.6, Node 20+, `node:test`, existing HostAgentClient / SessionStore.

**Spec:** `docs/superpowers/specs/2026-08-10-host-agent-design.md`  
**Roadmap:** `docs/superpowers/plans/2026-08-10-host-agent-roadmap.md`  
**Reference CLI (read-only):** `/Users/nietao/VSCode-plugins/smart-commit-cli` @ `0.1.21`

**Plan 3 YAGNI:**
- No hybridGenerate / correction repair turns
- No passHistory / stagedChangeSummary writes (stubs stay disabled)
- No real GitLab/GitHub HTTP; mock only
- No pr-title / pr-description turns (title = commit subject)

---

## File structure

| Path | Responsibility |
|------|----------------|
| `src/git.ts` | Add `getCurrentBranch`, `createCommit`, `getHeadCommitSha`, `pushCurrentBranch` (+ timeout on `runGit`) |
| `src/commitMessage/protocol.ts` | Conventional validate + ticket helpers |
| `src/commitMessage/prompt.ts` | Messages + responseSchema string |
| `src/commitMessage/hostAgentCommitMessage.ts` | provided / autoGenerate via host agent |
| `src/bridge/state.ts` | Read/write/merge `bridge-state.json` |
| `src/pullRequest/mockCreate.ts` | Mock GitLab create payload |
| `src/commands/bridge.ts` | Full bridge orchestration; keep review-only |
| `src/test/gitCommitPush.test.ts` | Git helper tests |
| `src/test/commitMessage.test.ts` | Protocol + resolve tests |
| `src/test/bridgeState.test.ts` | State store tests |
| `src/test/bridgeFull.test.ts` | Multi-turn E2E |

---

### Task 1: Git commit/push helpers

**Files:**
- Modify: `src/git.ts`
- Test: `src/test/gitCommitPush.test.ts`

- [ ] **Step 1: Write failing tests** for `getCurrentBranch`, `createCommit`, `getHeadCommitSha`, and `pushCurrentBranch` (bare remote + no-upstream retry).

- [ ] **Step 2: Implement** by porting from CLI `src/git.ts` (read-only). Extend `runGit` with optional `timeoutMs`.

- [ ] **Step 3: `npm test` green; commit** `feat: add git commit and push helpers`

---

### Task 2: Commit message protocol + host-agent resolve

**Files:**
- Create: `src/commitMessage/protocol.ts`, `prompt.ts`, `hostAgentCommitMessage.ts`
- Test: `src/test/commitMessage.test.ts`

- [ ] **Step 1: Protocol tests** — conventional subject OK; empty → REQUIRED; invalid type → INVALID; ticket extract from branch when enabled.

- [ ] **Step 2: Implement simplified protocol** (subjectOnly; conventional/none/custom pattern; no full language script matrix — skip language text validation for Plan 3).

- [ ] **Step 3: `resolveHostAgentCommitMessage`**
  - `--commit-message` / `config.commitMessage.input` → validate → `source: "provided"`
  - else if `autoGenerate` → `client.complete` purpose `commit-message` → validate → `source: "generated"`
  - else → `COMMIT_MESSAGE_REQUIRED`
  - Invalid → `CommitMessageFlowError`

- [ ] **Step 4: Tests green; commit** `feat: add host-agent commit message resolve`

---

### Task 3: Bridge state store

**Files:**
- Create: `src/bridge/state.ts`
- Test: `src/test/bridgeState.test.ts`

State shape:

```typescript
export interface BridgeSessionState {
  commitMessage: string | null;
  commitMessageSource: "provided" | "generated" | "hybrid" | "missing" | null;
  reviewCompleted: boolean;
  reviewScore: number | null;
  reviewDecision: "pass" | "block" | null;
  reviewSummary: string | null;
  reviewDetails: Array<{ severity?: string; message: string; filePath?: string }>;
  didCommit: boolean;
  didPush: boolean;
  commitSha: string | null;
  pullRequestCreation: {
    enabled: boolean;
    status: "skipped" | "created" | "existing" | "error";
    platform: "github" | "gitlab" | null;
    sourceBranch: string | null;
    targetBranch: string | null;
    title: string | null;
    url: string | null;
    warnings: string[];
    error: string | null;
  } | null;
}
```

- [ ] **Step 1–3:** `loadBridgeState` / `saveBridgeState` / `mergeBridgeState` on `sessionPath/bridge-state.json`; default empty state; tests; commit `feat: add bridge session state persistence`

---

### Task 4: Full bridge + mock PR + E2E

**Files:**
- Modify: `src/commands/bridge.ts` (remove Plan 2-only gate; add `runFullBridge`)
- Create: `src/pullRequest/mockCreate.ts`
- Test: `src/test/bridgeFull.test.ts`
- Update: `src/test/bridgeReviewOnly.test.ts` — change “without --review-only returns config error” to a full-bridge smoke or remove

**Flow:**
1. Preflight (same as review-only staging)
2. Load/create session + load bridge-state
3. Resolve commit message (skip if state has message); persist
4. Review (skip if `reviewCompleted`); persist; block stops
5. If `!autoCommit` → passed phase review
6. If `!didCommit` → `createCommit` + sha; persist
7. If `!autoPush` → passed phase commit
8. If `!didPush` → `pushCurrentBranch`; persist
9. If `autoCreateAfterPush` and branch not in `skipBranches` → mock create; else skipped
10. Return passed phase push

**Flags:** `--no-commit` / `--no-push` override config git flags. `--commit-message` for provided message.

**Mock PR:** `createMockGitLabPullRequestCreation({ sourceBranch, targetBranch, title })` → `status: "created"`, `platform: "gitlab"`, `url: https://gitlab.example/mock/...`

- [ ] **Step 1:** E2E with provided commit message + `--no-push`: needs review → fixture → `didCommit=true`, `didPush=false`
- [ ] **Step 2:** E2E autoGenerate: needs cm → fixture text → needs review → fixture → commit with `--no-push`
- [ ] **Step 3:** With autoPush false and autoCreateAfterPush false, PR skipped
- [ ] **Step 4:** Mock PR when autoPush true (use local bare remote) + autoCreateAfterPush
- [ ] **Step 5:** `npm test`; commit `feat: implement full bridge with mock GitLab PR`

---

### Task 5: Docs

- Update `docs/parity-matrix.md` — `bridge` partial/aligned Plan 3
- Update `docs/superpowers/plans/2026-08-10-host-agent-roadmap.md` — Plan 3 complete; next Plan 4
- Update `README.md` — document full `bridge`

- [ ] Commit `docs: mark Plan 3 full bridge complete`

---

## Acceptance

- `npm test` all green
- `--review-only` still works
- Full bridge fixture path: needs_host_agent → resume → commit (and optional mock PR)
- Zero LLM HTTP; zero changes to `smart-commit-cli`
