dubstack 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lib/errors.ts","../src/lib/git.ts","../src/lib/state.ts","../src/lib/undo-log.ts","../src/commands/restack.ts","../src/lib/skills.ts","../src/commands/skills.ts","../src/commands/modify.ts","../src/index.ts","../src/commands/branch.ts","../src/commands/checkout.ts","../src/commands/create.ts","../src/commands/init.ts","../src/commands/log.ts","../src/commands/navigate.ts","../src/lib/github.ts","../src/commands/pr.ts","../src/commands/submit.ts","../src/lib/pr-body.ts","../src/commands/sync.ts","../src/lib/sync/branch-status.ts","../src/lib/sync/cleanup.ts","../src/lib/sync/reconcile.ts","../src/lib/sync/report.ts","../src/commands/undo.ts"],"sourcesContent":["/**\n * Base error class for all user-facing DubStack errors.\n *\n * The CLI entry point catches instances of this class and prints\n * a clean, colored error message. Unknown errors get a full stack trace.\n *\n * @example\n * ```ts\n * throw new DubError(\"Branch 'feat/x' already exists\")\n * ```\n */\nexport class DubError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"DubError\";\n\t}\n}\n","import { execa } from \"execa\";\nimport { DubError } from \"./errors\";\n\n/**\n * Checks whether the given directory is inside a git repository.\n * @returns `true` if inside a git worktree, `false` otherwise. Never throws.\n */\nexport async function isGitRepo(cwd: string): Promise<boolean> {\n\ttry {\n\t\tconst { stdout } = await execa(\n\t\t\t\"git\",\n\t\t\t[\"rev-parse\", \"--is-inside-work-tree\"],\n\t\t\t{ cwd },\n\t\t);\n\t\treturn stdout.trim() === \"true\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Returns the absolute path to the repository root.\n * @throws {DubError} If not inside a git repository.\n */\nexport async function getRepoRoot(cwd: string): Promise<string> {\n\ttry {\n\t\tconst { stdout } = await execa(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n\t\t\tcwd,\n\t\t});\n\t\treturn stdout.trim();\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t\"Not a git repository. Run this command inside a git repo.\",\n\t\t);\n\t}\n}\n\n/**\n * Returns the name of the currently checked-out branch.\n * @throws {DubError} If HEAD is detached or the repo has no commits.\n */\nexport async function getCurrentBranch(cwd: string): Promise<string> {\n\ttry {\n\t\tconst { stdout } = await execa(\n\t\t\t\"git\",\n\t\t\t[\"rev-parse\", \"--abbrev-ref\", \"HEAD\"],\n\t\t\t{ cwd },\n\t\t);\n\t\tconst branch = stdout.trim();\n\t\tif (branch === \"HEAD\") {\n\t\t\tthrow new DubError(\n\t\t\t\t\"HEAD is detached. Checkout a branch before running this command.\",\n\t\t\t);\n\t\t}\n\t\treturn branch;\n\t} catch (error) {\n\t\tif (error instanceof DubError) throw error;\n\t\tthrow new DubError(\n\t\t\t\"Repository has no commits. Make at least one commit first.\",\n\t\t);\n\t}\n}\n\n/**\n * Checks whether a branch with the given name exists locally.\n * @returns `true` if the branch exists, `false` otherwise. Never throws.\n */\nexport async function branchExists(\n\tname: string,\n\tcwd: string,\n): Promise<boolean> {\n\ttry {\n\t\tawait execa(\"git\", [\"rev-parse\", \"--verify\", `refs/heads/${name}`], {\n\t\t\tcwd,\n\t\t});\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Creates a new branch and switches to it.\n * @throws {DubError} If a branch with that name already exists.\n */\nexport async function createBranch(name: string, cwd: string): Promise<void> {\n\tif (await branchExists(name, cwd)) {\n\t\tthrow new DubError(`Branch '${name}' already exists.`);\n\t}\n\tawait execa(\"git\", [\"checkout\", \"-b\", name], { cwd });\n}\n\n/**\n * Switches to an existing branch.\n * @throws {DubError} If the branch does not exist.\n */\nexport async function checkoutBranch(name: string, cwd: string): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"checkout\", name], { cwd });\n\t} catch {\n\t\tthrow new DubError(`Branch '${name}' not found.`);\n\t}\n}\n\n/**\n * Deletes a local branch forcefully. Used by undo to remove created branches.\n * @throws {DubError} If the branch does not exist.\n */\nexport async function deleteBranch(name: string, cwd: string): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"branch\", \"-D\", name], { cwd });\n\t} catch {\n\t\tthrow new DubError(`Failed to delete branch '${name}'. It may not exist.`);\n\t}\n}\n\n/**\n * Force-moves a branch pointer to a specific commit SHA.\n * Used by undo to reset branches to their pre-operation tips.\n */\nexport async function forceBranchTo(\n\tname: string,\n\tsha: string,\n\tcwd: string,\n): Promise<void> {\n\ttry {\n\t\tconst current = await getCurrentBranch(cwd).catch(() => null);\n\t\tif (current === name) {\n\t\t\tawait execa(\"git\", [\"reset\", \"--hard\", sha], { cwd });\n\t\t} else {\n\t\t\tawait execa(\"git\", [\"branch\", \"-f\", name, sha], { cwd });\n\t\t}\n\t} catch (error) {\n\t\tif (error instanceof DubError) throw error;\n\t\tthrow new DubError(`Failed to reset branch '${name}' to ${sha}.`);\n\t}\n}\n\n/**\n * Checks whether the working tree is clean (no uncommitted changes).\n * @returns `true` if clean (no output from `git status --porcelain`).\n */\nexport async function isWorkingTreeClean(cwd: string): Promise<boolean> {\n\tconst { stdout } = await execa(\"git\", [\"status\", \"--porcelain\"], { cwd });\n\treturn stdout.trim() === \"\";\n}\n\n/**\n * Performs `git rebase --onto` to move a branch from one base to another.\n *\n * @param newBase - The commit/branch to rebase onto\n * @param oldBase - The old base commit to replay from\n * @param branch - The branch being rebased\n * @throws {DubError} If a merge conflict occurs during rebase\n */\nexport async function rebaseOnto(\n\tnewBase: string,\n\toldBase: string,\n\tbranch: string,\n\tcwd: string,\n): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"rebase\", \"--onto\", newBase, oldBase, branch], { cwd });\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t`Conflict while restacking '${branch}'.\\n` +\n\t\t\t\t\" Resolve conflicts, stage changes, then run: dub restack --continue\",\n\t\t);\n\t}\n}\n\n/**\n * Continues an in-progress rebase after conflicts have been resolved.\n * @throws {DubError} If the rebase continue fails.\n */\nexport async function rebaseContinue(cwd: string): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"rebase\", \"--continue\"], {\n\t\t\tcwd,\n\t\t\tenv: { GIT_EDITOR: \"true\" },\n\t\t});\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t\"Failed to continue rebase. Ensure all conflicts are resolved and staged.\",\n\t\t);\n\t}\n}\n\n/**\n * Returns the merge-base (common ancestor) commit SHA of two branches.\n */\nexport async function getMergeBase(\n\ta: string,\n\tb: string,\n\tcwd: string,\n): Promise<string> {\n\ttry {\n\t\tconst { stdout } = await execa(\"git\", [\"merge-base\", a, b], { cwd });\n\t\treturn stdout.trim();\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t`Could not find common ancestor between '${a}' and '${b}'.`,\n\t\t);\n\t}\n}\n\n/**\n * Returns the commit SHA at the tip of a branch.\n * @throws {DubError} If the branch does not exist.\n */\nexport async function getBranchTip(name: string, cwd: string): Promise<string> {\n\ttry {\n\t\tconst { stdout } = await execa(\"git\", [\"rev-parse\", name], { cwd });\n\t\treturn stdout.trim();\n\t} catch {\n\t\tthrow new DubError(`Branch '${name}' not found.`);\n\t}\n}\n\n/**\n * Returns the subject line of the most recent commit on a branch.\n * @throws {DubError} If the branch has no commits.\n */\nexport async function getLastCommitMessage(\n\tbranch: string,\n\tcwd: string,\n): Promise<string> {\n\ttry {\n\t\tconst { stdout } = await execa(\n\t\t\t\"git\",\n\t\t\t[\"log\", \"-1\", \"--format=%s\", branch],\n\t\t\t{ cwd },\n\t\t);\n\t\tconst message = stdout.trim();\n\t\tif (!message) {\n\t\t\tthrow new DubError(`Branch '${branch}' has no commits.`);\n\t\t}\n\t\treturn message;\n\t} catch (error) {\n\t\tif (error instanceof DubError) throw error;\n\t\tthrow new DubError(`Failed to read commit message for '${branch}'.`);\n\t}\n}\n\n/**\n * Pushes a branch to origin with `--force-with-lease`.\n * @throws {DubError} If the push fails.\n */\nexport async function pushBranch(branch: string, cwd: string): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"push\", \"--force-with-lease\", \"origin\", branch], {\n\t\t\tcwd,\n\t\t});\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t`Failed to push '${branch}'. The remote ref may have been updated by someone else.`,\n\t\t);\n\t}\n}\n\n/**\n * Stages all changes (tracked, untracked, and deletions).\n * @throws {DubError} If git add fails.\n */\nexport async function stageAll(cwd: string): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"add\", \"-A\"], { cwd });\n\t} catch {\n\t\tthrow new DubError(\"Failed to stage changes.\");\n\t}\n}\n\n/**\n * Checks whether there are staged changes ready to commit.\n *\n * `git diff --cached --quiet` exits with code 1 when changes exist\n * and code 0 when there are none.\n */\nexport async function hasStagedChanges(cwd: string): Promise<boolean> {\n\ttry {\n\t\tawait execa(\"git\", [\"diff\", \"--cached\", \"--quiet\"], { cwd });\n\t\treturn false;\n\t} catch (error: unknown) {\n\t\tconst exitCode = (error as { exitCode?: number }).exitCode;\n\t\tif (exitCode === 1) return true;\n\t\tthrow new DubError(\"Failed to check staged changes.\");\n\t}\n}\n\n/**\n * Commits currently staged changes with the given message.\n * @throws {DubError} If the commit fails (e.g., nothing staged, hook rejection).\n */\nexport async function commitStaged(\n\tmessage: string,\n\tcwd: string,\n): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"commit\", \"-m\", message], { cwd });\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t`Commit failed. Ensure there are staged changes and git hooks pass.`,\n\t\t);\n\t}\n}\n\n/**\n * Commits currently staged changes, opening the editor if no message is provided.\n * @param cwd - The working directory.\n * @param options - Commit options (message, noEdit).\n * @throws {DubError} If the commit fails.\n */\nexport async function commit(\n\tcwd: string,\n\toptions?: { message?: string; noEdit?: boolean },\n): Promise<void> {\n\tconst args = [\"commit\"];\n\tif (options?.message) {\n\t\targs.push(\"-m\", options.message);\n\t}\n\tif (options?.noEdit) {\n\t\targs.push(\"--no-edit\");\n\t}\n\n\ttry {\n\t\tawait execa(\"git\", args, { cwd, stdio: \"inherit\" });\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t\"Commit failed. Ensure there are staged changes and git hooks pass.\",\n\t\t);\n\t}\n}\n\n/**\n * Amends the previous commit with currently staged changes.\n * @param cwd - The working directory.\n * @param options - Amend options (message, noEdit).\n * @throws {DubError} If the amend fails.\n */\nexport async function amendCommit(\n\tcwd: string,\n\toptions?: { message?: string; noEdit?: boolean },\n): Promise<void> {\n\tconst args = [\"commit\", \"--amend\"];\n\tif (options?.message) {\n\t\targs.push(\"-m\", options.message);\n\t}\n\tif (options?.noEdit) {\n\t\targs.push(\"--no-edit\");\n\t}\n\n\ttry {\n\t\tawait execa(\"git\", args, { cwd, stdio: \"inherit\" });\n\t} catch (e) {\n\t\tthrow new DubError(\n\t\t\t`Amend failed: ${e instanceof Error ? e.message : String(e)}`,\n\t\t);\n\t}\n}\n\n/**\n * Starts an interactive rebase from the given base.\n * Uses stdio: 'inherit' to allow user interaction.\n *\n * @param base - The commit or branch to rebase onto.\n * @param cwd - The working directory.\n * @throws {DubError} If rebase fails.\n */\nexport async function interactiveRebase(\n\tbase: string,\n\tcwd: string,\n): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"rebase\", \"-i\", base], { cwd, stdio: \"inherit\" });\n\t} catch {\n\t\tthrow new DubError(\"Interactive rebase failed or was cancelled.\");\n\t}\n}\n\n/**\n * Starts an interactive staging session (git add -p).\n * Uses stdio: 'inherit' to allow user interaction.\n *\n * @param cwd - The working directory.\n * @throws {DubError} If staging fails.\n */\nexport async function interactiveStage(cwd: string): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"add\", \"-p\"], { cwd, stdio: \"inherit\" });\n\t} catch {\n\t\tthrow new DubError(\"Interactive staging failed.\");\n\t}\n}\n\n/**\n * Stages all modified and deleted files (git add -u).\n *\n * @param cwd - The working directory.\n * @throws {DubError} If staging fails.\n */\nexport async function stageUpdate(cwd: string): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"add\", \"-u\"], { cwd });\n\t} catch {\n\t\tthrow new DubError(\"Failed to stage updates.\");\n\t}\n}\n\n/**\n * Returns the diff of changes.\n * @param staged - If true, shows staged changes (cached). If false, shows unstaged changes.\n */\nexport async function getDiff(cwd: string, staged: boolean): Promise<string> {\n\ttry {\n\t\tconst args = [\"diff\"];\n\t\tif (staged) args.push(\"--cached\");\n\t\tconst { stdout } = await execa(\"git\", args, { cwd });\n\t\treturn stdout;\n\t} catch {\n\t\treturn \"\";\n\t}\n}\n\n/**\n * Returns a list of all local branch names.\n */\nexport async function listBranches(cwd: string): Promise<string[]> {\n\ttry {\n\t\tconst { stdout } = await execa(\n\t\t\t\"git\",\n\t\t\t[\"branch\", \"--format=%(refname:short)\"],\n\t\t\t{ cwd },\n\t\t);\n\t\treturn stdout.trim().split(\"\\n\").filter(Boolean);\n\t} catch {\n\t\tthrow new DubError(\"Failed to list branches.\");\n\t}\n}\n\n/**\n * Fetches the provided branches from the remote.\n */\nexport async function fetchBranches(\n\tbranches: string[],\n\tcwd: string,\n\tremote = \"origin\",\n): Promise<void> {\n\tif (branches.length === 0) return;\n\tfor (const branch of branches) {\n\t\ttry {\n\t\t\tawait execa(\"git\", [\"fetch\", remote, branch], { cwd });\n\t\t} catch (error: unknown) {\n\t\t\tconst stderr =\n\t\t\t\ttypeof (error as { stderr?: unknown })?.stderr === \"string\"\n\t\t\t\t\t? (error as { stderr: string }).stderr\n\t\t\t\t\t: \"\";\n\t\t\tconst stdout =\n\t\t\t\ttypeof (error as { stdout?: unknown })?.stdout === \"string\"\n\t\t\t\t\t? (error as { stdout: string }).stdout\n\t\t\t\t\t: \"\";\n\t\t\tconst output = `${stderr}\\n${stdout}`;\n\t\t\tif (output.includes(\"couldn't find remote ref\")) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow new DubError(`Failed to fetch branches from '${remote}'.`);\n\t\t}\n\t}\n}\n\n/**\n * Returns whether a remote branch exists.\n */\nexport async function remoteBranchExists(\n\tbranch: string,\n\tcwd: string,\n\tremote = \"origin\",\n): Promise<boolean> {\n\ttry {\n\t\tawait execa(\"git\", [\"rev-parse\", \"--verify\", `${remote}/${branch}`], {\n\t\t\tcwd,\n\t\t});\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Reads a ref SHA.\n */\nexport async function getRefSha(ref: string, cwd: string): Promise<string> {\n\ttry {\n\t\tconst { stdout } = await execa(\"git\", [\"rev-parse\", ref], { cwd });\n\t\treturn stdout.trim();\n\t} catch {\n\t\tthrow new DubError(`Failed to read ref '${ref}'.`);\n\t}\n}\n\n/**\n * Returns true when `ancestor` is an ancestor of `descendant`.\n */\nexport async function isAncestor(\n\tancestor: string,\n\tdescendant: string,\n\tcwd: string,\n): Promise<boolean> {\n\ttry {\n\t\tawait execa(\"git\", [\"merge-base\", \"--is-ancestor\", ancestor, descendant], {\n\t\t\tcwd,\n\t\t});\n\t\treturn true;\n\t} catch (error: unknown) {\n\t\tconst exitCode = (error as { exitCode?: number }).exitCode;\n\t\tif (exitCode === 1) return false;\n\t\tthrow new DubError(\n\t\t\t`Failed to compare ancestry between '${ancestor}' and '${descendant}'.`,\n\t\t);\n\t}\n}\n\n/**\n * Creates or resets a local branch from a remote ref and checks it out.\n */\nexport async function checkoutRemoteBranch(\n\tbranch: string,\n\tcwd: string,\n\tremote = \"origin\",\n): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"checkout\", \"-B\", branch, `${remote}/${branch}`], {\n\t\t\tcwd,\n\t\t});\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t`Failed to create local branch '${branch}' from '${remote}/${branch}'.`,\n\t\t);\n\t}\n}\n\n/**\n * Resets a local branch hard to a ref.\n */\nexport async function hardResetBranchToRef(\n\tbranch: string,\n\tref: string,\n\tcwd: string,\n): Promise<void> {\n\ttry {\n\t\tconst current = await getCurrentBranch(cwd).catch(() => null);\n\t\tif (current !== branch) {\n\t\t\tawait checkoutBranch(branch, cwd);\n\t\t}\n\t\tawait execa(\"git\", [\"reset\", \"--hard\", ref], { cwd });\n\t} catch {\n\t\tthrow new DubError(`Failed to hard reset '${branch}' to '${ref}'.`);\n\t}\n}\n\n/**\n * Fast-forwards a local branch to a ref when possible.\n * Returns false when fast-forward is not possible.\n */\nexport async function fastForwardBranchToRef(\n\tbranch: string,\n\tref: string,\n\tcwd: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst current = await getCurrentBranch(cwd).catch(() => null);\n\t\tif (current !== branch) {\n\t\t\tawait checkoutBranch(branch, cwd);\n\t\t}\n\t\tawait execa(\"git\", [\"merge\", \"--ff-only\", ref], { cwd });\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Rebases a branch onto a target ref.\n * Returns false if conflicts occur.\n */\nexport async function rebaseBranchOntoRef(\n\tbranch: string,\n\tref: string,\n\tcwd: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst current = await getCurrentBranch(cwd).catch(() => null);\n\t\tif (current !== branch) {\n\t\t\tawait checkoutBranch(branch, cwd);\n\t\t}\n\t\tawait execa(\"git\", [\"rebase\", ref], { cwd });\n\t\treturn true;\n\t} catch {\n\t\ttry {\n\t\t\tawait execa(\"git\", [\"rebase\", \"--abort\"], { cwd });\n\t\t} catch {\n\t\t\t// no-op\n\t\t}\n\t\treturn false;\n\t}\n}\n","import * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { DubError } from \"./errors\";\nimport { getRepoRoot } from \"./git\";\n\n/** A branch within a stack. */\nexport interface Branch {\n\t/** Branch name, e.g. \"feat/api-endpoint\" */\n\tname: string;\n\t/** Set to \"root\" for the base branch (e.g. main). Omitted for children. */\n\ttype?: \"root\";\n\t/** Name of the parent branch. `null` only for root branches. */\n\tparent: string | null;\n\t/** GitHub PR number. Populated after `dub submit`. */\n\tpr_number: number | null;\n\t/** GitHub PR URL. Populated after `dub submit`. */\n\tpr_link: string | null;\n\t/** Last known remote baseline synced/submitted for this branch. */\n\tlast_submitted_version?: {\n\t\thead_sha: string;\n\t\tbase_sha: string;\n\t\tbase_branch: string;\n\t\tversion_number: number | null;\n\t\tsource: \"submit\" | \"sync\" | \"imported\";\n\t} | null;\n\t/** ISO timestamp of the most recent successful sync for this branch. */\n\tlast_synced_at?: string | null;\n\t/** Source of the branch's current sync baseline metadata. */\n\tsync_source?: \"submit\" | \"sync\" | \"imported\" | null;\n}\n\n/** A stack of dependent branches. */\nexport interface Stack {\n\t/** Unique identifier for this stack. */\n\tid: string;\n\t/** Ordered list of branches in the stack. */\n\tbranches: Branch[];\n}\n\n/** Root state persisted to `.git/dubstack/state.json`. */\nexport interface DubState {\n\t/** All tracked stacks in this repository. */\n\tstacks: Stack[];\n}\n\n/**\n * Returns the absolute path to the dubstack state file.\n * @throws {DubError} If not inside a git repository.\n */\nexport async function getStatePath(cwd: string): Promise<string> {\n\tconst root = await getRepoRoot(cwd);\n\treturn path.join(root, \".git\", \"dubstack\", \"state.json\");\n}\n\n/**\n * Returns the absolute path to the dubstack directory inside `.git`.\n * @throws {DubError} If not inside a git repository.\n */\nexport async function getDubDir(cwd: string): Promise<string> {\n\tconst root = await getRepoRoot(cwd);\n\treturn path.join(root, \".git\", \"dubstack\");\n}\n\n/**\n * Reads and parses the dubstack state file.\n * @throws {DubError} If the state file is missing or contains invalid JSON.\n */\nexport async function readState(cwd: string): Promise<DubState> {\n\tconst statePath = await getStatePath(cwd);\n\tif (!fs.existsSync(statePath)) {\n\t\tthrow new DubError(\"DubStack is not initialized. Run 'dub init' first.\");\n\t}\n\ttry {\n\t\tconst raw = fs.readFileSync(statePath, \"utf-8\");\n\t\treturn normalizeState(JSON.parse(raw) as DubState);\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t\"State file is corrupted. Delete .git/dubstack and run 'dub init' to re-initialize.\",\n\t\t);\n\t}\n}\n\n/**\n * Writes the dubstack state to disk.\n * Creates the parent directory if it doesn't exist.\n */\nexport async function writeState(state: DubState, cwd: string): Promise<void> {\n\tconst statePath = await getStatePath(cwd);\n\tconst dir = path.dirname(statePath);\n\tif (!fs.existsSync(dir)) {\n\t\tfs.mkdirSync(dir, { recursive: true });\n\t}\n\tfs.writeFileSync(statePath, `${JSON.stringify(state, null, 2)}\\n`);\n}\n\n/**\n * Initializes the dubstack state directory and file.\n * Idempotent — returns `\"already_exists\"` if already initialized.\n *\n * @returns `\"created\"` if freshly initialized, `\"already_exists\"` if state file already present.\n */\nexport async function initState(\n\tcwd: string,\n): Promise<\"created\" | \"already_exists\"> {\n\tconst statePath = await getStatePath(cwd);\n\tconst dir = path.dirname(statePath);\n\n\tif (fs.existsSync(statePath)) {\n\t\treturn \"already_exists\";\n\t}\n\n\tfs.mkdirSync(dir, { recursive: true });\n\tconst emptyState: DubState = { stacks: [] };\n\tfs.writeFileSync(statePath, `${JSON.stringify(emptyState, null, 2)}\\n`);\n\treturn \"created\";\n}\n\n/**\n * Returns state, auto-initializing if not yet set up.\n * Only catches the \"not initialized\" error — corrupt state still throws.\n */\nexport async function ensureState(cwd: string): Promise<DubState> {\n\ttry {\n\t\treturn await readState(cwd);\n\t} catch (error) {\n\t\tif (\n\t\t\terror instanceof DubError &&\n\t\t\terror.message.includes(\"not initialized\")\n\t\t) {\n\t\t\tawait initState(cwd);\n\t\t\treturn await readState(cwd);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * Finds the stack containing a given branch.\n * @returns The matching stack, or `undefined` if the branch isn't tracked.\n */\nexport function findStackForBranch(\n\tstate: DubState,\n\tname: string,\n): Stack | undefined {\n\treturn state.stacks.find((stack) =>\n\t\tstack.branches.some((b) => b.name === name),\n\t);\n}\n\n/**\n * Returns the parent branch name for a given branch.\n * @returns The parent branch name, or `undefined` if not found or is a root.\n */\nexport function getParent(\n\tstate: DubState,\n\tbranchName: string,\n): string | undefined {\n\tconst stack = findStackForBranch(state, branchName);\n\tif (!stack) return undefined;\n\n\tconst branch = stack.branches.find((b) => b.name === branchName);\n\treturn branch?.parent ?? undefined;\n}\n\n/**\n * Adds a child branch to the state, linking it to its parent.\n *\n * Decision tree:\n * 1. If `child` already exists in any stack → throws `DubError` (no duplicates)\n * 2. If `parent` is found in an existing stack → appends child to that stack\n * 3. If `parent` is not in any stack → creates a new stack with parent as root\n *\n * @param state - The state to mutate (modified in place)\n * @param child - Name of the new branch\n * @param parent - Name of the parent branch\n * @throws {DubError} If child branch already exists in state\n */\nexport function addBranchToStack(\n\tstate: DubState,\n\tchild: string,\n\tparent: string,\n): void {\n\tif (findStackForBranch(state, child)) {\n\t\tthrow new DubError(`Branch '${child}' is already tracked in a stack.`);\n\t}\n\n\tconst childBranch: Branch = {\n\t\tname: child,\n\t\tparent,\n\t\tpr_number: null,\n\t\tpr_link: null,\n\t\tlast_submitted_version: null,\n\t\tlast_synced_at: null,\n\t\tsync_source: null,\n\t};\n\tconst existingStack = findStackForBranch(state, parent);\n\n\tif (existingStack) {\n\t\texistingStack.branches.push(childBranch);\n\t} else {\n\t\tconst rootBranch: Branch = {\n\t\t\tname: parent,\n\t\t\ttype: \"root\",\n\t\t\tparent: null,\n\t\t\tpr_number: null,\n\t\t\tpr_link: null,\n\t\t\tlast_submitted_version: null,\n\t\t\tlast_synced_at: null,\n\t\t\tsync_source: null,\n\t\t};\n\t\tstate.stacks.push({\n\t\t\tid: crypto.randomUUID(),\n\t\t\tbranches: [rootBranch, childBranch],\n\t\t});\n\t}\n}\n\nfunction normalizeState(state: DubState): DubState {\n\treturn {\n\t\tstacks: state.stacks.map((stack) => ({\n\t\t\t...stack,\n\t\t\tbranches: stack.branches.map((branch) => normalizeBranch(branch)),\n\t\t})),\n\t};\n}\n\nfunction normalizeBranch(branch: Branch): Branch {\n\treturn {\n\t\t...branch,\n\t\tlast_submitted_version: branch.last_submitted_version ?? null,\n\t\tlast_synced_at: branch.last_synced_at ?? null,\n\t\tsync_source: branch.sync_source ?? null,\n\t};\n}\n\n/**\n * Returns branches in topological (BFS) order starting from the root.\n * Useful for operations that need to process parent branches before children.\n */\nexport function topologicalOrder(stack: Stack): Branch[] {\n\tconst result: Branch[] = [];\n\tconst root = stack.branches.find((b) => b.type === \"root\");\n\tif (!root) return result;\n\n\tconst childMap = new Map<string, Branch[]>();\n\tfor (const branch of stack.branches) {\n\t\tif (branch.parent) {\n\t\t\tconst children = childMap.get(branch.parent) ?? [];\n\t\t\tchildren.push(branch);\n\t\t\tchildMap.set(branch.parent, children);\n\t\t}\n\t}\n\n\tconst queue = [root];\n\twhile (queue.length > 0) {\n\t\tconst current = queue.shift();\n\t\tif (!current) break;\n\t\tresult.push(current);\n\t\tconst children = childMap.get(current.name) ?? [];\n\t\tqueue.push(...children);\n\t}\n\n\treturn result;\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { DubError } from \"./errors\";\nimport type { DubState } from \"./state\";\nimport { getDubDir } from \"./state\";\n\n/**\n * Snapshot of system state before a mutation, used by `dub undo`.\n * Only one undo level is supported — each new mutation overwrites the previous snapshot.\n */\nexport interface UndoEntry {\n\t/** Which command created this snapshot. */\n\toperation: \"create\" | \"restack\";\n\t/** ISO timestamp of when the snapshot was taken. */\n\ttimestamp: string;\n\t/** The branch user was on before the operation. */\n\tpreviousBranch: string;\n\t/** Full copy of state.json before mutation. */\n\tpreviousState: DubState;\n\t/** Map of branch name → commit SHA before mutation. */\n\tbranchTips: Record<string, string>;\n\t/** Branches created by this operation (to be deleted on undo). */\n\tcreatedBranches: string[];\n}\n\nasync function getUndoPath(cwd: string): Promise<string> {\n\tconst dubDir = await getDubDir(cwd);\n\treturn path.join(dubDir, \"undo.json\");\n}\n\n/**\n * Saves an undo entry to disk. Overwrites any previous entry (1 level only).\n */\nexport async function saveUndoEntry(\n\tentry: UndoEntry,\n\tcwd: string,\n): Promise<void> {\n\tconst undoPath = await getUndoPath(cwd);\n\tfs.writeFileSync(undoPath, `${JSON.stringify(entry, null, 2)}\\n`);\n}\n\n/**\n * Reads the most recent undo entry.\n * @throws {DubError} If no undo entry exists.\n */\nexport async function readUndoEntry(cwd: string): Promise<UndoEntry> {\n\tconst undoPath = await getUndoPath(cwd);\n\tif (!fs.existsSync(undoPath)) {\n\t\tthrow new DubError(\"Nothing to undo.\");\n\t}\n\tconst raw = fs.readFileSync(undoPath, \"utf-8\");\n\treturn JSON.parse(raw) as UndoEntry;\n}\n\n/**\n * Deletes the undo entry file. Called after a successful undo.\n */\nexport async function clearUndoEntry(cwd: string): Promise<void> {\n\tconst undoPath = await getUndoPath(cwd);\n\tif (fs.existsSync(undoPath)) {\n\t\tfs.unlinkSync(undoPath);\n\t}\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { DubError } from \"../lib/errors\";\nimport {\n\tbranchExists,\n\tcheckoutBranch,\n\tgetBranchTip,\n\tgetCurrentBranch,\n\tgetMergeBase,\n\trebaseContinue as gitRebaseContinue,\n\tisWorkingTreeClean,\n\trebaseOnto,\n} from \"../lib/git\";\nimport {\n\tgetDubDir,\n\treadState,\n\ttype Stack,\n\ttopologicalOrder,\n} from \"../lib/state\";\nimport { saveUndoEntry } from \"../lib/undo-log\";\n\ninterface RestackStep {\n\tbranch: string;\n\tparent: string;\n\tparentOldTip: string;\n\tstatus: \"pending\" | \"done\" | \"skipped\" | \"conflicted\";\n}\n\ninterface RestackProgress {\n\toriginalBranch: string;\n\tsteps: RestackStep[];\n}\n\ninterface RestackResult {\n\tstatus: \"success\" | \"conflict\" | \"up-to-date\";\n\trebased: string[];\n\tconflictBranch?: string;\n}\n\n/**\n * Rebases all branches in the current stack onto their updated parents.\n *\n * Uses a snapshot-before-rebase strategy: captures every branch's tip\n * BEFORE starting any rebases, then uses `git rebase --onto <parent_new_tip>\n * <parent_old_tip> <child>`. This prevents the duplication bug where a child\n * replays its parent's already-rebased commits.\n *\n * On conflict, writes progress to `restack-progress.json` so\n * `dub restack --continue` can resume.\n *\n * @param cwd - Working directory\n * @returns Result with status, list of rebased branches, and optional conflict branch\n * @throws {DubError} If not initialized, dirty tree, not in a stack, or branch missing\n */\nexport async function restack(cwd: string): Promise<RestackResult> {\n\tconst state = await readState(cwd);\n\n\tif (!(await isWorkingTreeClean(cwd))) {\n\t\tthrow new DubError(\n\t\t\t\"Working tree has uncommitted changes. Commit or stash them before restacking.\",\n\t\t);\n\t}\n\n\tconst originalBranch = await getCurrentBranch(cwd);\n\tconst targetStacks = getTargetStacks(state.stacks, originalBranch);\n\n\tif (targetStacks.length === 0) {\n\t\tthrow new DubError(\n\t\t\t`Branch '${originalBranch}' is not part of any stack. Run 'dub create' first.`,\n\t\t);\n\t}\n\n\tconst allBranches = targetStacks.flatMap((s) => s.branches);\n\tfor (const branch of allBranches) {\n\t\tif (!(await branchExists(branch.name, cwd))) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Branch '${branch.name}' is tracked in state but no longer exists in git.\\n` +\n\t\t\t\t\t\" Remove it from the stack or recreate it before restacking.\",\n\t\t\t);\n\t\t}\n\t}\n\n\t// Snapshot all branch tips BEFORE building steps or rebasing\n\tconst branchTips: Record<string, string> = {};\n\tfor (const branch of allBranches) {\n\t\tbranchTips[branch.name] = await getBranchTip(branch.name, cwd);\n\t}\n\n\tconst steps = await buildRestackSteps(targetStacks, cwd);\n\n\tif (steps.length === 0) {\n\t\treturn { status: \"up-to-date\", rebased: [] };\n\t}\n\n\tawait saveUndoEntry(\n\t\t{\n\t\t\toperation: \"restack\",\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tpreviousBranch: originalBranch,\n\t\t\tpreviousState: structuredClone(state),\n\t\t\tbranchTips,\n\t\t\tcreatedBranches: [],\n\t\t},\n\t\tcwd,\n\t);\n\n\tconst progress: RestackProgress = { originalBranch, steps };\n\tawait writeProgress(progress, cwd);\n\n\treturn executeRestackSteps(progress, cwd);\n}\n\n/**\n * Continues a restack after conflict resolution.\n *\n * Reads the saved progress file, finishes the in-progress rebase,\n * then resumes with remaining branches.\n *\n * @param cwd - Working directory\n * @throws {DubError} If no restack is in progress\n */\nexport async function restackContinue(cwd: string): Promise<RestackResult> {\n\tconst progress = await readProgress(cwd);\n\n\tif (!progress) {\n\t\tthrow new DubError(\"No restack in progress. Run 'dub restack' to start.\");\n\t}\n\n\tawait gitRebaseContinue(cwd);\n\n\tconst conflictedStep = progress.steps.find((s) => s.status === \"conflicted\");\n\tif (conflictedStep) {\n\t\tconflictedStep.status = \"done\";\n\t}\n\n\treturn executeRestackSteps(progress, cwd);\n}\n\nasync function executeRestackSteps(\n\tprogress: RestackProgress,\n\tcwd: string,\n): Promise<RestackResult> {\n\tconst rebased: string[] = [];\n\n\tfor (const step of progress.steps) {\n\t\tif (step.status !== \"pending\") {\n\t\t\tif (step.status === \"done\") rebased.push(step.branch);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst parentNewTip = await getBranchTip(step.parent, cwd);\n\t\tif (parentNewTip === step.parentOldTip) {\n\t\t\tstep.status = \"skipped\";\n\t\t\tawait writeProgress(progress, cwd);\n\t\t\tcontinue;\n\t\t}\n\n\t\ttry {\n\t\t\tawait rebaseOnto(parentNewTip, step.parentOldTip, step.branch, cwd);\n\t\t\tstep.status = \"done\";\n\t\t\trebased.push(step.branch);\n\t\t\tawait writeProgress(progress, cwd);\n\t\t} catch (error) {\n\t\t\tif (error instanceof DubError && error.message.includes(\"Conflict\")) {\n\t\t\t\tstep.status = \"conflicted\";\n\t\t\t\tawait writeProgress(progress, cwd);\n\t\t\t\treturn { status: \"conflict\", rebased, conflictBranch: step.branch };\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tawait clearProgress(cwd);\n\tawait checkoutBranch(progress.originalBranch, cwd);\n\n\tconst allSkipped = progress.steps.every(\n\t\t(s) => s.status === \"skipped\" || s.status === \"done\",\n\t);\n\treturn {\n\t\tstatus: rebased.length === 0 && allSkipped ? \"up-to-date\" : \"success\",\n\t\trebased,\n\t};\n}\n\nfunction getTargetStacks(stacks: Stack[], currentBranch: string): Stack[] {\n\t// If current branch is a root of any stacks, restack all of them\n\tconst rootStacks = stacks.filter((s) =>\n\t\ts.branches.some((b) => b.name === currentBranch && b.type === \"root\"),\n\t);\n\tif (rootStacks.length > 0) return rootStacks;\n\n\t// Otherwise, find the stack containing the current branch\n\tconst stack = stacks.find((s) =>\n\t\ts.branches.some((b) => b.name === currentBranch),\n\t);\n\treturn stack ? [stack] : [];\n}\n\nasync function buildRestackSteps(\n\tstacks: Stack[],\n\tcwd: string,\n): Promise<RestackStep[]> {\n\tconst steps: RestackStep[] = [];\n\n\tfor (const stack of stacks) {\n\t\tconst ordered = topologicalOrder(stack);\n\t\tfor (const branch of ordered) {\n\t\t\tif (branch.type === \"root\" || !branch.parent) continue;\n\t\t\tconst mergeBase = await getMergeBase(branch.parent, branch.name, cwd);\n\t\t\tsteps.push({\n\t\t\t\tbranch: branch.name,\n\t\t\t\tparent: branch.parent,\n\t\t\t\tparentOldTip: mergeBase,\n\t\t\t\tstatus: \"pending\",\n\t\t\t});\n\t\t}\n\t}\n\n\treturn steps;\n}\n\nasync function getProgressPath(cwd: string): Promise<string> {\n\tconst dubDir = await getDubDir(cwd);\n\treturn path.join(dubDir, \"restack-progress.json\");\n}\n\nasync function writeProgress(\n\tprogress: RestackProgress,\n\tcwd: string,\n): Promise<void> {\n\tconst progressPath = await getProgressPath(cwd);\n\tfs.writeFileSync(progressPath, `${JSON.stringify(progress, null, 2)}\\n`);\n}\n\nasync function readProgress(cwd: string): Promise<RestackProgress | null> {\n\tconst progressPath = await getProgressPath(cwd);\n\tif (!fs.existsSync(progressPath)) return null;\n\tconst raw = fs.readFileSync(progressPath, \"utf-8\");\n\treturn JSON.parse(raw) as RestackProgress;\n}\n\nasync function clearProgress(cwd: string): Promise<void> {\n\tconst progressPath = await getProgressPath(cwd);\n\tif (fs.existsSync(progressPath)) {\n\t\tfs.unlinkSync(progressPath);\n\t}\n}\n","export const AVAILABLE_SKILLS = {\n\tdubstack: \"wiseiodev/dubstack/skills/dubstack\",\n\t\"dub-flow\": \"wiseiodev/dubstack/skills/dub-flow\",\n} as const;\n\nexport type SkillName = keyof typeof AVAILABLE_SKILLS;\n\nexport function getSkillRemote(name: SkillName): string {\n\treturn AVAILABLE_SKILLS[name];\n}\n","import chalk from \"chalk\";\nimport { execa } from \"execa\";\nimport { DubError } from \"../lib/errors\";\nimport {\n\tAVAILABLE_SKILLS,\n\tgetSkillRemote,\n\ttype SkillName,\n} from \"../lib/skills\";\n\ninterface SkillsOptions {\n\tglobal?: boolean;\n\tdryRun?: boolean;\n}\n\nfunction validateSkills(skills: string[]): SkillName[] {\n\tconst invalidSkills = skills.filter((s) => !(s in AVAILABLE_SKILLS));\n\n\tif (invalidSkills.length > 0) {\n\t\tthrow new DubError(\n\t\t\t`Unknown skill(s): ${invalidSkills.join(\", \")}. Available skills: ${Object.keys(AVAILABLE_SKILLS).join(\", \")}`,\n\t\t);\n\t}\n\n\treturn skills as SkillName[];\n}\n\nexport async function addSkills(skills: string[], options: SkillsOptions = {}) {\n\tconst targets =\n\t\tskills.length > 0\n\t\t\t? validateSkills(skills)\n\t\t\t: (Object.keys(AVAILABLE_SKILLS) as SkillName[]);\n\n\tconsole.log(chalk.blue(`Adding ${targets.length} skill(s)...`));\n\n\tfor (const skill of targets) {\n\t\tconst remote = getSkillRemote(skill);\n\t\tconst args = [\"skills\", \"add\", remote];\n\t\tif (options.global) args.push(\"--global\");\n\n\t\tconst command = `npx ${args.join(\" \")}`;\n\t\tconsole.log(chalk.dim(`Running: ${command}`));\n\n\t\tif (!options.dryRun) {\n\t\t\ttry {\n\t\t\t\tawait execa(\"npx\", args, { stdio: \"inherit\" });\n\t\t\t\tconsole.log(chalk.green(`✔ Added skill: ${skill}`));\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(chalk.red(`✖ Failed to add skill: ${skill}`));\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport async function removeSkills(\n\tskills: string[],\n\toptions: SkillsOptions = {},\n) {\n\tconst targets =\n\t\tskills.length > 0\n\t\t\t? validateSkills(skills)\n\t\t\t: (Object.keys(AVAILABLE_SKILLS) as SkillName[]);\n\n\tconsole.log(chalk.blue(`Removing ${targets.length} skill(s)...`));\n\n\tfor (const skill of targets) {\n\t\tconst args = [\"skills\", \"remove\", skill];\n\t\tif (options.global) args.push(\"--global\");\n\n\t\tconst command = `npx ${args.join(\" \")}`;\n\t\tconsole.log(chalk.dim(`Running: ${command}`));\n\n\t\tif (!options.dryRun) {\n\t\t\ttry {\n\t\t\t\tawait execa(\"npx\", args, { stdio: \"inherit\" });\n\t\t\t\tconsole.log(chalk.green(`✔ Removed skill: ${skill}`));\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(chalk.red(`✖ Failed to remove skill: ${skill}`));\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t}\n}\n","import { DubError } from \"../lib/errors\";\nimport {\n\tamendCommit,\n\tcommit,\n\tgetBranchTip,\n\tgetCurrentBranch,\n\tgetDiff,\n\thasStagedChanges,\n\tinteractiveRebase,\n\tinteractiveStage,\n\tstageAll,\n\tstageUpdate,\n} from \"../lib/git\";\nimport { getParent, readState } from \"../lib/state\";\nimport { restack } from \"./restack\";\n\n/**\n * Options for the modify command.\n */\ninterface ModifyOptions {\n\t/** Stage all changes before committing. */\n\tall?: boolean;\n\t/** Create a new commit instead of amending. */\n\tcommit?: boolean;\n\t/** Open editor to edit the commit message. */\n\tedit?: boolean;\n\t/** Start an interactive rebase on the branch commits. */\n\tinteractiveRebase?: boolean;\n\t/** Amend staged changes to the specified branch. */\n\tinto?: string;\n\t/** Message for the new or amended commit. */\n\tmessage?: string | string[];\n\t/** Pick hunks to stage before committing. */\n\tpatch?: boolean;\n\t/** Set the author to the current user. */\n\tresetAuthor?: boolean;\n\t/** Stage all updates to tracked files. */\n\tupdate?: boolean;\n\t/** Show unified diff. */\n\tverbose?: number;\n}\n\n/**\n * Modifies the current branch by amending commits or creating new ones.\n * Automatically restacks descendant branches to keep the stack valid.\n *\n * @param cwd - The working directory.\n * @param options - Modification options.\n * @throws {DubError} If the parent branch cannot be determined for rebase, or if no changes are staged when creating a new commit.\n */\nexport async function modify(\n\tcwd: string,\n\toptions: ModifyOptions,\n): Promise<void> {\n\tconst currentBranch = await getCurrentBranch(cwd);\n\tconst state = await readState(cwd);\n\n\tif (options.interactiveRebase) {\n\t\tconst parent = getParent(state, currentBranch);\n\t\tif (!parent) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Could not determine parent branch for '${currentBranch}'. Cannot start interactive rebase.`,\n\t\t\t);\n\t\t}\n\n\t\tconst parentTip = await getBranchTip(parent, cwd);\n\n\t\tconsole.log(`Starting interactive rebase on top of '${parent}'...`);\n\t\tawait interactiveRebase(parentTip, cwd);\n\n\t\tawait restackChildren(cwd);\n\t\treturn;\n\t}\n\n\tif (options.patch) {\n\t\tawait interactiveStage(cwd);\n\t} else if (options.all) {\n\t\tawait stageAll(cwd);\n\t} else if (options.update) {\n\t\tawait stageUpdate(cwd);\n\t}\n\n\tawait printVerboseDiff(cwd, options.verbose ?? 0);\n\n\tconst hasStaged = await hasStagedChanges(cwd);\n\tconst shouldCreateNew = options.commit;\n\tconst message = normalizeMessage(options.message);\n\tconst noEdit = !options.edit && !!message;\n\n\tif (shouldCreateNew) {\n\t\tif (!hasStaged) {\n\t\t\tthrow new DubError(\"No staged changes to commit.\");\n\t\t}\n\t\tawait commit(cwd, { message, noEdit: !options.edit });\n\t} else {\n\t\t// When amending, git commit --amend handles empty staged changes by allowing rewording\n\t\tawait amendCommit(cwd, { message, noEdit });\n\t}\n\n\tawait restackChildren(cwd);\n}\n\nfunction normalizeMessage(message?: string | string[]): string | undefined {\n\tif (Array.isArray(message)) {\n\t\tconst chunks = message.map((part) => part.trim()).filter(Boolean);\n\t\treturn chunks.length > 0 ? chunks.join(\"\\n\\n\") : undefined;\n\t}\n\treturn message;\n}\n\nasync function printVerboseDiff(cwd: string, level: number): Promise<void> {\n\tif (level < 1) return;\n\n\tconst staged = await getDiff(cwd, true);\n\tconsole.log(staged || \"(no staged diff)\");\n\n\tif (level > 1) {\n\t\tconst unstaged = await getDiff(cwd, false);\n\t\tconsole.log(unstaged || \"(no unstaged diff)\");\n\t}\n}\n\n/**\n * Trigger a restack of the stack to ensure children are rebased onto the new tip.\n *\n * @param cwd - The working directory.\n */\nasync function restackChildren(cwd: string): Promise<void> {\n\ttry {\n\t\tawait restack(cwd);\n\t} catch (e) {\n\t\tif (e instanceof DubError && e.message.includes(\"Conflict\")) {\n\t\t\tconsole.log(\n\t\t\t\t\"⚠ Modify successful, but auto-restacking encountered conflicts.\",\n\t\t\t);\n\t\t\tconsole.log(\" Run 'dub restack --continue' to resolve.\");\n\t\t} else {\n\t\t\tconsole.log(\"⚠ Modify successful, but auto-restacking failed.\");\n\t\t\tconsole.log(` ${e instanceof Error ? e.message : String(e)}`);\n\t\t}\n\t}\n}\n","#!/usr/bin/env node\n\n/**\n * DubStack CLI — manage stacked diffs with ease.\n *\n * A local-first tool for managing chains of dependent git branches\n * (stacked diffs) without manually dealing with complex rebase chains.\n *\n * @example\n * ```bash\n * dub init # Initialize in current repo\n * dub create feat/my-branch # Create stacked branch\n * dub log # View stack tree\n * dub restack # Rebase stack onto updated parent\n * dub undo # Undo last dub operation\n * ```\n *\n * @packageDocumentation\n */\n\nimport { createRequire } from \"node:module\";\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { branchInfo, formatBranchInfo } from \"./commands/branch\";\nimport {\n\tcheckout,\n\tinteractiveCheckout,\n\tresolveCheckoutTrunk,\n} from \"./commands/checkout\";\nimport { create } from \"./commands/create\";\nimport { init } from \"./commands/init\";\nimport { log } from \"./commands/log\";\nimport { bottom, downBySteps, top, upBySteps } from \"./commands/navigate\";\nimport { pr } from \"./commands/pr\";\nimport { restack, restackContinue } from \"./commands/restack\";\nimport { submit } from \"./commands/submit\";\nimport { sync } from \"./commands/sync\";\nimport { undo } from \"./commands/undo\";\nimport { DubError } from \"./lib/errors\";\n\nconst require = createRequire(import.meta.url);\nconst { version } = require(\"../package.json\") as { version: string };\n\nconst program = new Command();\n\nprogram\n\t.name(\"dub\")\n\t.description(\"Manage stacked diffs (dependent git branches) with ease\")\n\t.version(version);\n\nprogram\n\t.command(\"init\")\n\t.description(\"Initialize DubStack in the current git repository\")\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\nExamples:\n $ dub init Initialize DubStack, creating .git/dubstack/ and updating .gitignore`,\n\t)\n\t.action(async () => {\n\t\tconst result = await init(process.cwd());\n\t\tif (result.status === \"created\") {\n\t\t\tconsole.log(chalk.green(\"✔ DubStack initialized\"));\n\t\t} else {\n\t\t\tconsole.log(chalk.yellow(\"⚠ DubStack already initialized\"));\n\t\t}\n\t});\n\nprogram\n\t.command(\"create\")\n\t.argument(\"<branch-name>\", \"Name of the new branch to create\")\n\t.description(\"Create a new branch stacked on top of the current branch\")\n\t.option(\"-m, --message <message>\", \"Commit staged changes with this message\")\n\t.option(\"-a, --all\", \"Stage all changes before committing (requires -m)\")\n\t.option(\n\t\t\"-u, --update\",\n\t\t\"Stage tracked file updates before committing (requires -m)\",\n\t)\n\t.option(\"-p, --patch\", \"Pick hunks to stage before committing (requires -m)\")\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\nExamples:\n $ dub create feat/api Create branch only\n $ dub create feat/api -m \"feat: add API\" Create branch + commit staged\n $ dub create feat/api -am \"feat: add API\" Stage all + create + commit`,\n\t)\n\t.action(\n\t\tasync (\n\t\t\tbranchName: string,\n\t\t\toptions: {\n\t\t\t\tmessage?: string;\n\t\t\t\tall?: boolean;\n\t\t\t\tupdate?: boolean;\n\t\t\t\tpatch?: boolean;\n\t\t\t},\n\t\t) => {\n\t\t\tconst result = await create(branchName, process.cwd(), {\n\t\t\t\tmessage: options.message,\n\t\t\t\tall: options.all,\n\t\t\t\tupdate: options.update,\n\t\t\t\tpatch: options.patch,\n\t\t\t});\n\t\t\tif (result.committed) {\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.green(\n\t\t\t\t\t\t`✔ Created '${result.branch}' on '${result.parent}' • ${result.committed}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.green(\n\t\t\t\t\t\t`✔ Created branch '${result.branch}' on top of '${result.parent}'`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t);\n\nprogram\n\t.command(\"log\")\n\t.alias(\"l\")\n\t.description(\"Display an ASCII tree of the current stack\")\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\nExamples:\n $ dub log Show the branch tree with current branch highlighted`,\n\t)\n\t.action(async () => {\n\t\tawait printLog(process.cwd());\n\t});\n\nprogram\n\t.command(\"ls\")\n\t.description(\"Display an ASCII tree of the current stack\")\n\t.action(async () => {\n\t\tawait printLog(process.cwd());\n\t});\n\nprogram\n\t.command(\"up\")\n\t.argument(\"[steps]\", \"Number of levels to traverse upstack\")\n\t.option(\"-n, --steps <count>\", \"Number of levels to traverse upstack\")\n\t.description(\"Checkout the child branch directly above the current branch\")\n\t.action(async (stepsArg: string | undefined, options: { steps?: string }) => {\n\t\tconst steps = parseSteps(stepsArg, options.steps);\n\t\tconst result = await upBySteps(process.cwd(), steps);\n\t\tif (result.changed) {\n\t\t\tconsole.log(chalk.green(`✔ Switched up to '${result.branch}'`));\n\t\t} else {\n\t\t\tconsole.log(chalk.yellow(`⚠ Already at top branch '${result.branch}'`));\n\t\t}\n\t});\n\nprogram\n\t.command(\"down\")\n\t.argument(\"[steps]\", \"Number of levels to traverse downstack\")\n\t.option(\"-n, --steps <count>\", \"Number of levels to traverse downstack\")\n\t.description(\"Checkout the parent branch directly below the current branch\")\n\t.action(async (stepsArg: string | undefined, options: { steps?: string }) => {\n\t\tconst steps = parseSteps(stepsArg, options.steps);\n\t\tconst result = await downBySteps(process.cwd(), steps);\n\t\tif (result.changed) {\n\t\t\tconsole.log(chalk.green(`✔ Switched down to '${result.branch}'`));\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\tchalk.yellow(`⚠ Already at bottom branch '${result.branch}'`),\n\t\t\t);\n\t\t}\n\t});\n\nprogram\n\t.command(\"top\")\n\t.description(\"Checkout the topmost branch in the current stack path\")\n\t.action(async () => {\n\t\tconst result = await top(process.cwd());\n\t\tif (result.changed) {\n\t\t\tconsole.log(chalk.green(`✔ Switched to top branch '${result.branch}'`));\n\t\t} else {\n\t\t\tconsole.log(chalk.yellow(`⚠ Already at top branch '${result.branch}'`));\n\t\t}\n\t});\n\nprogram\n\t.command(\"bottom\")\n\t.description(\n\t\t\"Checkout the first branch above the root in the current stack path\",\n\t)\n\t.action(async () => {\n\t\tconst result = await bottom(process.cwd());\n\t\tif (result.changed) {\n\t\t\tconsole.log(\n\t\t\t\tchalk.green(`✔ Switched to bottom stack branch '${result.branch}'`),\n\t\t\t);\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\tchalk.yellow(`⚠ Already at bottom stack branch '${result.branch}'`),\n\t\t\t);\n\t\t}\n\t});\n\nprogram\n\t.command(\"branch\")\n\t.description(\"Show DubStack branch metadata\")\n\t.addCommand(\n\t\tnew Command(\"info\")\n\t\t\t.description(\"Show tracked stack info for the current branch\")\n\t\t\t.argument(\"[branch]\", \"Branch to inspect (defaults to current branch)\")\n\t\t\t.action(async (branch?: string) => {\n\t\t\t\tconst info = await branchInfo(process.cwd(), branch);\n\t\t\t\tconsole.log(formatBranchInfo(info));\n\t\t\t}),\n\t);\n\nprogram\n\t.command(\"info\")\n\t.argument(\"[branch]\", \"Branch to inspect (defaults to current branch)\")\n\t.description(\"Show tracked stack info for a branch\")\n\t.action(async (branch?: string) => {\n\t\tconst info = await branchInfo(process.cwd(), branch);\n\t\tconsole.log(formatBranchInfo(info));\n\t});\n\nprogram\n\t.command(\"sync\")\n\t.description(\"Sync tracked branches with remote and reconcile divergence\")\n\t.option(\n\t\t\"--restack\",\n\t\t\"Restack branches after sync (disable with --no-restack)\",\n\t\ttrue,\n\t)\n\t.option(\"-f, --force\", \"Skip prompts for destructive sync decisions\")\n\t.option(\"-a, --all\", \"Sync all tracked stacks across trunks\")\n\t.option(\"--no-interactive\", \"Disable prompts and use deterministic behavior\")\n\t.action(\n\t\tasync (options: {\n\t\t\trestack?: boolean;\n\t\t\tforce?: boolean;\n\t\t\tall?: boolean;\n\t\t\tinteractive?: boolean;\n\t\t}) => {\n\t\t\tawait sync(process.cwd(), options);\n\t\t},\n\t);\n\nprogram\n\t.command(\"restack\")\n\t.description(\"Rebase all branches in the stack onto their updated parents\")\n\t.option(\"--continue\", \"Continue restacking after resolving conflicts\")\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\nExamples:\n $ dub restack Rebase the current stack\n $ dub restack --continue Continue after resolving conflicts`,\n\t)\n\t.action(async (options: { continue?: boolean }) => {\n\t\tconst result = options.continue\n\t\t\t? await restackContinue(process.cwd())\n\t\t\t: await restack(process.cwd());\n\n\t\tif (result.status === \"up-to-date\") {\n\t\t\tconsole.log(chalk.green(\"✔ Stack is already up to date\"));\n\t\t} else if (result.status === \"conflict\") {\n\t\t\tconsole.log(\n\t\t\t\tchalk.yellow(`⚠ Conflict while restacking '${result.conflictBranch}'`),\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\tchalk.dim(\n\t\t\t\t\t\" Resolve conflicts, stage changes, then run: dub restack --continue\",\n\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\tchalk.green(`✔ Restacked ${result.rebased.length} branch(es)`),\n\t\t\t);\n\t\t\tfor (const branch of result.rebased) {\n\t\t\t\tconsole.log(chalk.dim(` ↳ ${branch}`));\n\t\t\t}\n\t\t}\n\t});\n\nprogram\n\t.command(\"undo\")\n\t.description(\"Undo the last dub create or dub restack operation\")\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\nExamples:\n $ dub undo Roll back the last dub operation`,\n\t)\n\t.action(async () => {\n\t\tconst result = await undo(process.cwd());\n\t\tconsole.log(chalk.green(`✔ Undid '${result.undone}': ${result.details}`));\n\t});\n\nprogram\n\t.command(\"submit\")\n\t.description(\n\t\t\"Push branches and create/update GitHub PRs for the current stack\",\n\t)\n\t.option(\"--dry-run\", \"Print what would happen without executing\")\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\nExamples:\n $ dub submit Push and create/update PRs\n $ dub submit --dry-run Preview what would happen`,\n\t)\n\t.action(runSubmit);\n\nprogram\n\t.command(\"ss\")\n\t.description(\"Submit the current stack (alias for submit)\")\n\t.option(\"--dry-run\", \"Print what would happen without executing\")\n\t.action(runSubmit);\n\nprogram\n\t.command(\"checkout\")\n\t.alias(\"co\")\n\t.argument(\"[branch]\", \"Branch to checkout (interactive if omitted)\")\n\t.option(\"-t, --trunk\", \"Checkout the current trunk\")\n\t.option(\n\t\t\"-u, --show-untracked\",\n\t\t\"Include untracked branches in interactive selection\",\n\t)\n\t.option(\n\t\t\"-s, --stack\",\n\t\t\"Only show ancestors and descendants of current branch in interactive selection\",\n\t)\n\t.option(\n\t\t\"-a, --all\",\n\t\t\"Show branches across all tracked stacks in interactive selection\",\n\t)\n\t.description(\"Checkout a branch (interactive picker if no name given)\")\n\t.action(\n\t\tasync (\n\t\t\tbranch: string | undefined,\n\t\t\toptions: {\n\t\t\t\ttrunk?: boolean;\n\t\t\t\tshowUntracked?: boolean;\n\t\t\t\tstack?: boolean;\n\t\t\t\tall?: boolean;\n\t\t\t},\n\t\t) => {\n\t\t\tif (branch) {\n\t\t\t\tconst result = await checkout(branch, process.cwd());\n\t\t\t\tconsole.log(chalk.green(`✔ Switched to '${result.branch}'`));\n\t\t\t} else if (options.trunk) {\n\t\t\t\tconst trunk = await resolveCheckoutTrunk(process.cwd());\n\t\t\t\tconst result = await checkout(trunk, process.cwd());\n\t\t\t\tconsole.log(chalk.green(`✔ Switched to '${result.branch}'`));\n\t\t\t} else {\n\t\t\t\tconst result = await interactiveCheckout(process.cwd(), {\n\t\t\t\t\tshowUntracked: options.showUntracked,\n\t\t\t\t\tstack: options.stack,\n\t\t\t\t\tall: options.all,\n\t\t\t\t});\n\t\t\t\tif (result) {\n\t\t\t\t\tconsole.log(chalk.green(`✔ Switched to '${result.branch}'`));\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t);\n\nprogram\n\t.command(\"skills\")\n\t.description(\"Manage DubStack agent skills\")\n\t.addCommand(\n\t\tnew Command(\"add\")\n\t\t\t.description(\"Install agent skills (e.g. dubstack, dub-flow)\")\n\t\t\t.argument(\"[skills...]\", \"Names of skills to install (default: all)\")\n\t\t\t.option(\"-g, --global\", \"Install skills globally\")\n\t\t\t.option(\"--dry-run\", \"Preview actions without installing\")\n\t\t\t.action(async (skills, options) => {\n\t\t\t\tconst { addSkills } = await import(\"./commands/skills\");\n\t\t\t\tawait addSkills(skills, options);\n\t\t\t}),\n\t)\n\t.addCommand(\n\t\tnew Command(\"remove\")\n\t\t\t.description(\"Remove agent skills\")\n\t\t\t.argument(\"[skills...]\", \"Names of skills to remove (default: all)\")\n\t\t\t.option(\"-g, --global\", \"Remove skills globally\")\n\t\t\t.option(\"--dry-run\", \"Preview actions without removing\")\n\t\t\t.action(async (skills, options) => {\n\t\t\t\tconst { removeSkills } = await import(\"./commands/skills\");\n\t\t\t\tawait removeSkills(skills, options);\n\t\t\t}),\n\t);\n\nprogram\n\t.command(\"modify\")\n\t.alias(\"m\")\n\t.description(\n\t\t\"Modify the current branch by amending commits or creating new ones\",\n\t)\n\t.option(\"-a, --all\", \"Stage all changes before committing\")\n\t.option(\"-c, --commit\", \"Create a new commit instead of amending\")\n\t.option(\"-e, --edit\", \"Open editor to edit the commit message\")\n\t.option(\n\t\t\"-m, --message <message>\",\n\t\t\"Message for the new or amended commit\",\n\t\t(value: string, previous: string[] = []) => [...previous, value],\n\t\t[],\n\t)\n\t.option(\"-p, --patch\", \"Pick hunks to stage before committing\")\n\t.option(\"-u, --update\", \"Stage all updates to tracked files\")\n\t.option(\n\t\t\"-v, --verbose\",\n\t\t\"Show staged diff before modify (repeat for unstaged diff too)\",\n\t\t(_value: unknown, previous = 0) => previous + 1,\n\t\t0,\n\t)\n\t.option(\n\t\t\"--interactive-rebase\",\n\t\t\"Start an interactive rebase on the branch commits\",\n\t)\n\t// .option(\"--into <branch>\", \"Amend staged changes to the specified branch\") // TODO: Implement --into\n\t// .option(\"--reset-author\", \"Set the author to the current user\") // TODO: Implement --reset-author\n\t// .option(\"-v, --verbose\", \"Show unified diff\") // TODO: Implement verbose\n\t.action(async (options) => {\n\t\tconst { modify } = await import(\"./commands/modify\");\n\t\tconst normalizedOptions = {\n\t\t\t...options,\n\t\t\tmessage:\n\t\t\t\tArray.isArray(options.message) && options.message.length === 1\n\t\t\t\t\t? options.message[0]\n\t\t\t\t\t: options.message,\n\t\t};\n\t\tawait modify(process.cwd(), normalizedOptions);\n\t});\n\nprogram\n\t.command(\"pr\")\n\t.argument(\"[branch]\", \"Branch name or PR number to open\")\n\t.description(\"Open a branch PR in your browser\")\n\t.action(async (branch?: string) => {\n\t\tawait pr(process.cwd(), branch);\n\t});\n\nasync function runSubmit(options: { dryRun?: boolean }) {\n\tconst result = await submit(process.cwd(), options.dryRun ?? false);\n\n\tif (result.pushed.length > 0) {\n\t\tconsole.log(\n\t\t\tchalk.green(\n\t\t\t\t`✔ Pushed ${result.pushed.length} branch(es), created ${result.created.length} PR(s), updated ${result.updated.length} PR(s)`,\n\t\t\t),\n\t\t);\n\t\tfor (const branch of [...result.created, ...result.updated]) {\n\t\t\tconsole.log(chalk.dim(` ↳ ${branch}`));\n\t\t}\n\t}\n}\n\nasync function printLog(cwd: string) {\n\tconst output = await log(cwd);\n\tconst styled = output\n\t\t.replace(/\\*(.+?) \\(Current\\)\\*/g, chalk.bold.cyan(\"$1 (Current)\"))\n\t\t.replace(/⚠ \\(missing\\)/g, chalk.yellow(\"⚠ (missing)\"));\n\tconsole.log(styled);\n}\n\nfunction parseSteps(positional?: string, option?: string): number {\n\tconst raw = option ?? positional;\n\tif (!raw) return 1;\n\tconst parsed = Number.parseInt(raw, 10);\n\tif (!Number.isInteger(parsed) || parsed < 1) {\n\t\tthrow new DubError(\"Steps must be a positive integer.\");\n\t}\n\treturn parsed;\n}\n\nasync function main() {\n\ttry {\n\t\tawait program.parseAsync(process.argv);\n\t} catch (error) {\n\t\tif (error instanceof DubError) {\n\t\t\tconsole.error(chalk.red(`✖ ${error.message}`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nmain();\n","import { getCurrentBranch } from \"../lib/git\";\nimport { findStackForBranch, readState, type Stack } from \"../lib/state\";\n\nexport interface BranchInfoResult {\n\tcurrentBranch: string;\n\ttracked: boolean;\n\tstackId: string | null;\n\troot: string | null;\n\tparent: string | null;\n\tchildren: string[];\n}\n\nfunction findRootName(stack: Stack): string | null {\n\treturn stack.branches.find((branch) => branch.type === \"root\")?.name ?? null;\n}\n\nfunction getChildren(stack: Stack, branchName: string): string[] {\n\treturn stack.branches\n\t\t.filter((branch) => branch.parent === branchName)\n\t\t.map((branch) => branch.name)\n\t\t.sort();\n}\n\n/**\n * Returns tracked branch metadata for the current branch.\n */\nexport async function branchInfo(\n\tcwd: string,\n\tbranchName?: string,\n): Promise<BranchInfoResult> {\n\tconst state = await readState(cwd);\n\tconst resolvedBranch = branchName ?? (await getCurrentBranch(cwd));\n\tconst stack = findStackForBranch(state, resolvedBranch);\n\n\tif (!stack) {\n\t\treturn {\n\t\t\tcurrentBranch: resolvedBranch,\n\t\t\ttracked: false,\n\t\t\tstackId: null,\n\t\t\troot: null,\n\t\t\tparent: null,\n\t\t\tchildren: [],\n\t\t};\n\t}\n\n\tconst current = stack.branches.find(\n\t\t(branch) => branch.name === resolvedBranch,\n\t);\n\n\treturn {\n\t\tcurrentBranch: resolvedBranch,\n\t\ttracked: true,\n\t\tstackId: stack.id,\n\t\troot: findRootName(stack),\n\t\tparent: current?.parent ?? null,\n\t\tchildren: getChildren(stack, resolvedBranch),\n\t};\n}\n\n/**\n * Formats branch info in a human-readable layout.\n */\nexport function formatBranchInfo(info: BranchInfoResult): string {\n\tif (!info.tracked) {\n\t\treturn [\n\t\t\t`Branch: ${info.currentBranch}`,\n\t\t\t\"Tracked: no\",\n\t\t\t\"Status: not tracked by DubStack\",\n\t\t].join(\"\\n\");\n\t}\n\n\tconst childrenLabel =\n\t\tinfo.children.length > 0 ? info.children.join(\", \") : \"(none)\";\n\treturn [\n\t\t`Branch: ${info.currentBranch}`,\n\t\t\"Tracked: yes\",\n\t\t`Stack ID: ${info.stackId ?? \"(unknown)\"}`,\n\t\t`Root: ${info.root ?? \"(unknown)\"}`,\n\t\t`Parent: ${info.parent ?? \"(root)\"}`,\n\t\t`Children: ${childrenLabel}`,\n\t].join(\"\\n\");\n}\n","import search from \"@inquirer/search\";\nimport { DubError } from \"../lib/errors\";\nimport {\n\tbranchExists,\n\tcheckoutBranch,\n\tgetCurrentBranch,\n\tlistBranches,\n} from \"../lib/git\";\nimport { type DubState, findStackForBranch, readState } from \"../lib/state\";\n\n/**\n * Returns a sorted, deduplicated list of branch names tracked by DubStack.\n * Root branches that appear in multiple stacks are included only once.\n */\nexport function getTrackedBranches(state: DubState): string[] {\n\tconst names = new Set<string>();\n\tfor (const stack of state.stacks) {\n\t\tfor (const branch of stack.branches) {\n\t\t\tnames.add(branch.name);\n\t\t}\n\t}\n\treturn [...names].sort();\n}\n\n/**\n * Filters tracked branches against the list of actual local git branches.\n * Removes any branches that are tracked in state but have been deleted locally.\n */\nexport function getValidBranches(tracked: string[], local: string[]): string[] {\n\tconst localSet = new Set(local);\n\treturn tracked.filter((b) => localSet.has(b));\n}\n\n/**\n * Returns tracked branch names in the current stack (ancestors + descendants),\n * including the provided branch itself.\n */\nexport function getStackRelativeBranches(\n\tstate: DubState,\n\tbranchName: string,\n): string[] {\n\tconst stack = findStackForBranch(state, branchName);\n\tif (!stack) return [];\n\treturn [...new Set(stack.branches.map((branch) => branch.name))].sort();\n}\n\n/**\n * Resolves the current trunk branch for the active stack.\n * Falls back to local \"main\" or \"master\" if the current branch is untracked.\n */\nexport async function resolveCheckoutTrunk(cwd: string): Promise<string> {\n\tconst state = await readState(cwd);\n\tconst currentBranch = await getCurrentBranch(cwd);\n\tconst stack = findStackForBranch(state, currentBranch);\n\tconst trackedRoot =\n\t\tstack?.branches.find((branch) => branch.type === \"root\")?.name ?? null;\n\tif (trackedRoot) return trackedRoot;\n\tif (await branchExists(\"main\", cwd)) return \"main\";\n\tif (await branchExists(\"master\", cwd)) return \"master\";\n\tthrow new DubError(\n\t\t`Could not determine trunk branch for '${currentBranch}'.`,\n\t);\n}\n\n/**\n * Checks out the named branch.\n *\n * @param name - Branch to switch to\n * @param cwd - Working directory\n * @returns The checked-out branch name\n * @throws {DubError} If the branch does not exist\n */\nexport async function checkout(\n\tname: string,\n\tcwd: string,\n): Promise<{ branch: string }> {\n\tawait checkoutBranch(name, cwd);\n\treturn { branch: name };\n}\n\n/**\n * Launches an interactive search prompt listing DubStack-tracked branches.\n *\n * The current branch is shown but disabled. The user can type to filter,\n * use arrow keys to navigate, and press Enter to checkout.\n *\n * @param cwd - Working directory\n * @returns The checked-out branch, or `null` if the user cancelled (Ctrl+C)\n * @throws {DubError} If not initialized or no tracked branches exist\n */\nexport async function interactiveCheckout(\n\tcwd: string,\n\toptions: {\n\t\tshowUntracked?: boolean;\n\t\tstack?: boolean;\n\t\tall?: boolean;\n\t} = {},\n): Promise<{ branch: string } | null> {\n\tconst state = await readState(cwd);\n\tconst localBranches = await listBranches(cwd);\n\tconst currentBranch = await getCurrentBranch(cwd).catch(() => null);\n\tconst trackedBranches = getTrackedBranches(state);\n\tconst stackBranches = currentBranch\n\t\t? getStackRelativeBranches(state, currentBranch)\n\t\t: [];\n\n\tlet branchCandidates = options.showUntracked\n\t\t? [...new Set(localBranches)].sort()\n\t\t: getValidBranches(trackedBranches, localBranches);\n\n\tif (options.stack && stackBranches.length > 0) {\n\t\tconst stackSet = new Set(stackBranches);\n\t\tbranchCandidates = branchCandidates.filter((name) => stackSet.has(name));\n\t}\n\n\tconst validBranches = branchCandidates;\n\n\tif (validBranches.length === 0) {\n\t\tthrow new DubError(\n\t\t\t\"No valid tracked branches found. Run 'dub create' first.\",\n\t\t);\n\t}\n\n\t// Setup AbortController for Esc key support\n\tconst controller = new AbortController();\n\n\t// Listen for keypress events to handle Esc\n\tconst onKeypress = (_str: string, key: { name: string; ctrl: boolean }) => {\n\t\tif (key && key.name === \"escape\") {\n\t\t\tcontroller.abort();\n\t\t}\n\t};\n\tprocess.stdin.on(\"keypress\", onKeypress);\n\n\ttry {\n\t\tconst selected = await search(\n\t\t\t{\n\t\t\t\tmessage: \"Checkout a branch (autocomplete or arrow keys)\",\n\t\t\t\tsource(term: string | undefined) {\n\t\t\t\t\tconst filtered = term\n\t\t\t\t\t\t? validBranches.filter((b) =>\n\t\t\t\t\t\t\t\tb.toLowerCase().includes(term.toLowerCase()),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: validBranches;\n\n\t\t\t\t\treturn filtered.map((name) => ({\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tvalue: name,\n\t\t\t\t\t\tdisabled: name === currentBranch ? \"(current)\" : false,\n\t\t\t\t\t}));\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ signal: controller.signal },\n\t\t);\n\n\t\treturn checkout(selected, cwd);\n\t} catch (error: unknown) {\n\t\tif (error instanceof Error) {\n\t\t\tif (\n\t\t\t\terror.name === \"ExitPromptError\" ||\n\t\t\t\terror.name === \"AbortError\" ||\n\t\t\t\terror.name === \"AbortPromptError\"\n\t\t\t) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\tthrow error;\n\t} finally {\n\t\tprocess.stdin.off(\"keypress\", onKeypress);\n\t}\n}\n","import { DubError } from \"../lib/errors\";\nimport {\n\tbranchExists,\n\tcommitStaged,\n\tcreateBranch,\n\tgetCurrentBranch,\n\thasStagedChanges,\n\tinteractiveStage,\n\tstageAll,\n\tstageUpdate,\n} from \"../lib/git\";\nimport { addBranchToStack, ensureState, writeState } from \"../lib/state\";\nimport { saveUndoEntry } from \"../lib/undo-log\";\n\ninterface CreateOptions {\n\tmessage?: string;\n\tall?: boolean;\n\tupdate?: boolean;\n\tpatch?: boolean;\n}\n\ninterface CreateResult {\n\tbranch: string;\n\tparent: string;\n\tcommitted?: string;\n}\n\n/**\n * Creates a new branch stacked on top of the current branch.\n *\n * When `-m` is provided, also commits staged changes on the new branch.\n * When `-a` is provided, stages all changes first (requires `-m`).\n *\n * @param name - Name of the new branch to create\n * @param cwd - Working directory (auto-initializes if needed)\n * @param options - Optional message and all flags\n * @returns The created branch name, its parent, and committed message if applicable\n * @throws {DubError} If branch exists, HEAD is detached, -a without -m, or nothing to commit\n */\nexport async function create(\n\tname: string,\n\tcwd: string,\n\toptions?: CreateOptions,\n): Promise<CreateResult> {\n\tif ((options?.all || options?.update || options?.patch) && !options.message) {\n\t\tthrow new DubError(\n\t\t\t\"'--all', '--update', and '--patch' require '-m'. Pass a commit message.\",\n\t\t);\n\t}\n\n\tconst state = await ensureState(cwd);\n\tconst parent = await getCurrentBranch(cwd);\n\n\tif (await branchExists(name, cwd)) {\n\t\tthrow new DubError(`Branch '${name}' already exists.`);\n\t}\n\n\tif (options?.message) {\n\t\tif (options.patch) {\n\t\t\tawait interactiveStage(cwd);\n\t\t} else if (options.all) {\n\t\t\tawait stageAll(cwd);\n\t\t} else if (options.update) {\n\t\t\tawait stageUpdate(cwd);\n\t\t}\n\n\t\tif (!(await hasStagedChanges(cwd))) {\n\t\t\tconst hint = options.all\n\t\t\t\t? \"No changes to commit.\"\n\t\t\t\t: \"No staged changes. Stage files with 'git add' or use '-a' to stage all.\";\n\t\t\tthrow new DubError(hint);\n\t\t}\n\t}\n\n\tawait saveUndoEntry(\n\t\t{\n\t\t\toperation: \"create\",\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tpreviousBranch: parent,\n\t\t\tpreviousState: structuredClone(state),\n\t\t\tbranchTips: {},\n\t\t\tcreatedBranches: [name],\n\t\t},\n\t\tcwd,\n\t);\n\n\tawait createBranch(name, cwd);\n\taddBranchToStack(state, name, parent);\n\tawait writeState(state, cwd);\n\n\tif (options?.message) {\n\t\ttry {\n\t\t\tawait commitStaged(options.message, cwd);\n\t\t} catch (error) {\n\t\t\tconst reason = error instanceof DubError ? error.message : String(error);\n\t\t\tthrow new DubError(\n\t\t\t\t`Branch '${name}' was created but commit failed: ${reason}. Run 'dub undo' to clean up.`,\n\t\t\t);\n\t\t}\n\t\treturn { branch: name, parent, committed: options.message };\n\t}\n\n\treturn { branch: name, parent };\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { DubError } from \"../lib/errors\";\nimport { getRepoRoot, isGitRepo } from \"../lib/git\";\nimport { initState } from \"../lib/state\";\n\ninterface InitResult {\n\tstatus: \"created\" | \"already_exists\";\n\tgitignoreUpdated: boolean;\n}\n\n/**\n * Initializes DubStack in the current git repository.\n *\n * Creates `.git/dubstack/state.json` with an empty state and ensures\n * `.git/dubstack` is listed in `.gitignore`. Idempotent — safe to run\n * multiple times.\n *\n * @param cwd - Working directory (must be inside a git repo)\n * @returns Status indicating whether state was created or already existed\n * @throws {DubError} If not inside a git repository\n */\nexport async function init(cwd: string): Promise<InitResult> {\n\tif (!(await isGitRepo(cwd))) {\n\t\tthrow new DubError(\n\t\t\t\"Not a git repository. Run this command inside a git repo.\",\n\t\t);\n\t}\n\n\tconst status = await initState(cwd);\n\tconst repoRoot = await getRepoRoot(cwd);\n\tconst gitignorePath = path.join(repoRoot, \".gitignore\");\n\tconst entry = \".git/dubstack\";\n\tlet gitignoreUpdated = false;\n\n\tif (fs.existsSync(gitignorePath)) {\n\t\tconst content = fs.readFileSync(gitignorePath, \"utf-8\");\n\t\tconst lines = content.split(\"\\n\");\n\t\tif (!lines.some((line) => line.trim() === entry)) {\n\t\t\tconst separator = content.endsWith(\"\\n\") ? \"\" : \"\\n\";\n\t\t\tfs.writeFileSync(gitignorePath, `${content}${separator}${entry}\\n`);\n\t\t\tgitignoreUpdated = true;\n\t\t}\n\t} else {\n\t\tfs.writeFileSync(gitignorePath, `${entry}\\n`);\n\t\tgitignoreUpdated = true;\n\t}\n\n\treturn { status, gitignoreUpdated };\n}\n","import { branchExists, getCurrentBranch } from \"../lib/git\";\nimport type { Branch, Stack } from \"../lib/state\";\nimport { readState } from \"../lib/state\";\n\n/**\n * Renders an ASCII tree view of all tracked stacks.\n *\n * Highlights the current branch, marks branches missing from git,\n * and handles multiple stacks separated by blank lines.\n *\n * @param cwd - Working directory (must be inside an initialized dubstack repo)\n * @returns Formatted ASCII tree string (no ANSI colors — caller adds chalk)\n * @throws {DubError} If not initialized\n */\nexport async function log(cwd: string): Promise<string> {\n\tconst state = await readState(cwd);\n\n\tif (state.stacks.length === 0) {\n\t\treturn \"No stacks. Run 'dub create' to start.\";\n\t}\n\n\tlet currentBranch: string | null = null;\n\ttry {\n\t\tcurrentBranch = await getCurrentBranch(cwd);\n\t} catch {\n\t\t// Detached HEAD or empty repo — no branch highlighted\n\t}\n\n\tconst sections: string[] = [];\n\n\tfor (const stack of state.stacks) {\n\t\tconst tree = await renderStack(stack, currentBranch, cwd);\n\t\tsections.push(tree);\n\t}\n\n\treturn sections.join(\"\\n\\n\");\n}\n\nasync function renderStack(\n\tstack: Stack,\n\tcurrentBranch: string | null,\n\tcwd: string,\n): Promise<string> {\n\tconst root = stack.branches.find((b) => b.type === \"root\");\n\tif (!root) return \"\";\n\n\tconst childMap = new Map<string, Branch[]>();\n\tfor (const branch of stack.branches) {\n\t\tif (branch.parent) {\n\t\t\tconst children = childMap.get(branch.parent) ?? [];\n\t\t\tchildren.push(branch);\n\t\t\tchildMap.set(branch.parent, children);\n\t\t}\n\t}\n\n\tconst lines: string[] = [];\n\tawait renderNode(root, currentBranch, childMap, \"\", true, true, lines, cwd);\n\treturn lines.join(\"\\n\");\n}\n\nasync function renderNode(\n\tbranch: Branch,\n\tcurrentBranch: string | null,\n\tchildMap: Map<string, Branch[]>,\n\tprefix: string,\n\tisRoot: boolean,\n\tisLast: boolean,\n\tlines: string[],\n\tcwd: string,\n): Promise<void> {\n\tlet label: string;\n\tconst exists = await branchExists(branch.name, cwd);\n\n\tif (isRoot) {\n\t\tlabel = `(${branch.name})`;\n\t} else if (branch.name === currentBranch) {\n\t\tlabel = `*${branch.name} (Current)*`;\n\t} else if (!exists) {\n\t\tlabel = `${branch.name} ⚠ (missing)`;\n\t} else {\n\t\tlabel = branch.name;\n\t}\n\n\tif (isRoot) {\n\t\tlines.push(label);\n\t} else {\n\t\tconst connector = isLast ? \"└─ \" : \"├─ \";\n\t\tlines.push(`${prefix}${connector}${label}`);\n\t}\n\n\tconst children = childMap.get(branch.name) ?? [];\n\tconst childPrefix = isRoot ? \" \" : `${prefix}${isLast ? \" \" : \"│ \"}`;\n\n\tfor (let i = 0; i < children.length; i++) {\n\t\tconst isChildLast = i === children.length - 1;\n\t\tawait renderNode(\n\t\t\tchildren[i],\n\t\t\tcurrentBranch,\n\t\t\tchildMap,\n\t\t\tchildPrefix,\n\t\t\tfalse,\n\t\t\tisChildLast,\n\t\t\tlines,\n\t\t\tcwd,\n\t\t);\n\t}\n}\n","import { DubError } from \"../lib/errors\";\nimport { checkoutBranch, getCurrentBranch } from \"../lib/git\";\nimport { findStackForBranch, readState, type Stack } from \"../lib/state\";\n\ninterface NavigateResult {\n\tbranch: string;\n\tchanged: boolean;\n}\n\nfunction getBranchByName(stack: Stack, name: string) {\n\treturn stack.branches.find((branch) => branch.name === name);\n}\n\nfunction getChildren(stack: Stack, parent: string): string[] {\n\treturn stack.branches\n\t\t.filter((branch) => branch.parent === parent)\n\t\t.map((branch) => branch.name);\n}\n\nfunction getTrackedStackOrThrow(\n\tstateBranch: string,\n\tstack: Stack | undefined,\n): Stack {\n\tif (!stack) {\n\t\tthrow new DubError(\n\t\t\t`Current branch '${stateBranch}' is not tracked by DubStack.`,\n\t\t);\n\t}\n\treturn stack;\n}\n\n/**\n * Checkout the direct child branch of the current branch.\n * Requires a linear stack path.\n */\nexport async function up(cwd: string): Promise<NavigateResult> {\n\treturn upBySteps(cwd, 1);\n}\n\n/**\n * Checkout the child branch of the current branch by N steps.\n * Requires a linear stack path.\n */\nexport async function upBySteps(\n\tcwd: string,\n\tsteps: number,\n): Promise<NavigateResult> {\n\tif (!Number.isInteger(steps) || steps < 1) {\n\t\tthrow new DubError(\"'steps' must be a positive integer.\");\n\t}\n\n\tconst state = await readState(cwd);\n\tconst current = await getCurrentBranch(cwd);\n\tconst stack = getTrackedStackOrThrow(\n\t\tcurrent,\n\t\tfindStackForBranch(state, current),\n\t);\n\n\tlet target = current;\n\tfor (let i = 0; i < steps; i++) {\n\t\tconst children = getChildren(stack, target);\n\t\tif (children.length === 0) {\n\t\t\tthrow new DubError(`No branch above '${target}' in the current stack.`);\n\t\t}\n\t\tif (children.length > 1) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Branch '${target}' has multiple children; 'dub up' requires a linear stack path.`,\n\t\t\t);\n\t\t}\n\t\ttarget = children[0];\n\t}\n\n\tawait checkoutBranch(target, cwd);\n\treturn { branch: target, changed: target !== current };\n}\n\n/**\n * Checkout the direct parent branch of the current branch.\n */\nexport async function down(cwd: string): Promise<NavigateResult> {\n\treturn downBySteps(cwd, 1);\n}\n\n/**\n * Checkout the parent branch of the current branch by N steps.\n */\nexport async function downBySteps(\n\tcwd: string,\n\tsteps: number,\n): Promise<NavigateResult> {\n\tif (!Number.isInteger(steps) || steps < 1) {\n\t\tthrow new DubError(\"'steps' must be a positive integer.\");\n\t}\n\n\tconst state = await readState(cwd);\n\tconst current = await getCurrentBranch(cwd);\n\tconst stack = getTrackedStackOrThrow(\n\t\tcurrent,\n\t\tfindStackForBranch(state, current),\n\t);\n\tlet target = current;\n\tfor (let i = 0; i < steps; i++) {\n\t\tconst branch = getBranchByName(stack, target);\n\t\tif (!branch) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Current branch '${target}' is not tracked by DubStack.`,\n\t\t\t);\n\t\t}\n\t\tif (!branch.parent) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Already at the bottom of the stack (root branch '${target}').`,\n\t\t\t);\n\t\t}\n\t\ttarget = branch.parent;\n\t}\n\n\tawait checkoutBranch(target, cwd);\n\treturn { branch: target, changed: target !== current };\n}\n\n/**\n * Checkout the topmost descendant reachable by following a single-child path.\n */\nexport async function top(cwd: string): Promise<NavigateResult> {\n\tconst state = await readState(cwd);\n\tconst current = await getCurrentBranch(cwd);\n\tconst stack = getTrackedStackOrThrow(\n\t\tcurrent,\n\t\tfindStackForBranch(state, current),\n\t);\n\n\tlet target = current;\n\twhile (true) {\n\t\tconst children = getChildren(stack, target);\n\t\tif (children.length === 0) break;\n\t\tif (children.length > 1) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Branch '${target}' has multiple children; 'dub top' requires a linear stack path.`,\n\t\t\t);\n\t\t}\n\t\ttarget = children[0];\n\t}\n\n\tif (target !== current) {\n\t\tawait checkoutBranch(target, cwd);\n\t}\n\treturn { branch: target, changed: target !== current };\n}\n\n/**\n * Checkout the first branch above the root for the current stack path.\n */\nexport async function bottom(cwd: string): Promise<NavigateResult> {\n\tconst state = await readState(cwd);\n\tconst current = await getCurrentBranch(cwd);\n\tconst stack = getTrackedStackOrThrow(\n\t\tcurrent,\n\t\tfindStackForBranch(state, current),\n\t);\n\tconst branch = getBranchByName(stack, current);\n\n\tif (!branch) {\n\t\tthrow new DubError(\n\t\t\t`Current branch '${current}' is not tracked by DubStack.`,\n\t\t);\n\t}\n\n\tlet target = current;\n\tif (!branch.parent) {\n\t\tconst children = getChildren(stack, current);\n\t\tif (children.length === 0) {\n\t\t\tthrow new DubError(\n\t\t\t\t`No branch above root '${current}' in the current stack.`,\n\t\t\t);\n\t\t}\n\t\tif (children.length > 1) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Root branch '${current}' has multiple children; 'dub bottom' requires a linear stack path.`,\n\t\t\t);\n\t\t}\n\t\ttarget = children[0];\n\t} else {\n\t\tlet node = branch;\n\t\twhile (node.parent) {\n\t\t\tconst parent = getBranchByName(stack, node.parent);\n\t\t\tif (!parent) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (parent.parent === null) {\n\t\t\t\ttarget = node.name;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tnode = parent;\n\t\t}\n\t}\n\n\tif (target !== current) {\n\t\tawait checkoutBranch(target, cwd);\n\t}\n\treturn { branch: target, changed: target !== current };\n}\n","import { execa } from \"execa\";\nimport { DubError } from \"./errors\";\n\n/** Details of a GitHub Pull Request. */\nexport interface PrInfo {\n\tnumber: number;\n\turl: string;\n\ttitle: string;\n\tbody: string;\n}\n\nexport type BranchPrLifecycleState = \"OPEN\" | \"CLOSED\" | \"MERGED\" | \"NONE\";\n\nexport interface BranchPrSyncInfo {\n\tstate: BranchPrLifecycleState;\n\tbaseRefName: string | null;\n}\n\n/**\n * Ensures the `gh` CLI is installed and available in PATH.\n * @throws {DubError} If `gh` is not found.\n */\nexport async function ensureGhInstalled(): Promise<void> {\n\ttry {\n\t\tawait execa(\"gh\", [\"--version\"]);\n\t} catch {\n\t\tthrow new DubError(\"gh CLI not found. Install it: https://cli.github.com\");\n\t}\n}\n\n/**\n * Ensures the user is authenticated with `gh`.\n * @throws {DubError} If not authenticated.\n */\nexport async function checkGhAuth(): Promise<void> {\n\ttry {\n\t\tawait execa(\"gh\", [\"auth\", \"status\"]);\n\t} catch {\n\t\tthrow new DubError(\"Not authenticated with GitHub. Run 'gh auth login'.\");\n\t}\n}\n\n/**\n * Fetches the open PR for a given head branch, if one exists.\n * @returns The PR info, or `null` if no open PR exists for that branch.\n */\nexport async function getPr(\n\tbranch: string,\n\tcwd: string,\n): Promise<PrInfo | null> {\n\tconst { stdout } = await execa(\n\t\t\"gh\",\n\t\t[\n\t\t\t\"pr\",\n\t\t\t\"list\",\n\t\t\t\"--head\",\n\t\t\tbranch,\n\t\t\t\"--state\",\n\t\t\t\"open\",\n\t\t\t\"--json\",\n\t\t\t\"number,url,title,body\",\n\t\t\t\"--jq\",\n\t\t\t\".[0]\",\n\t\t],\n\t\t{ cwd },\n\t);\n\n\tconst trimmed = stdout.trim();\n\tif (!trimmed || trimmed === \"null\") return null;\n\n\ttry {\n\t\treturn JSON.parse(trimmed) as PrInfo;\n\t} catch {\n\t\tthrow new DubError(`Failed to parse PR info for branch '${branch}'.`);\n\t}\n}\n\n/**\n * Returns coarse lifecycle state of a PR associated with the branch head.\n */\nexport async function getBranchPrLifecycleState(\n\tbranch: string,\n\tcwd: string,\n): Promise<BranchPrLifecycleState> {\n\tconst info = await getBranchPrSyncInfo(branch, cwd);\n\treturn info.state;\n}\n\n/**\n * Returns PR lifecycle and base branch information for sync decisions.\n */\nexport async function getBranchPrSyncInfo(\n\tbranch: string,\n\tcwd: string,\n): Promise<BranchPrSyncInfo> {\n\tconst { stdout } = await execa(\n\t\t\"gh\",\n\t\t[\n\t\t\t\"pr\",\n\t\t\t\"list\",\n\t\t\t\"--head\",\n\t\t\tbranch,\n\t\t\t\"--state\",\n\t\t\t\"all\",\n\t\t\t\"--json\",\n\t\t\t\"state,mergedAt,baseRefName\",\n\t\t\t\"--jq\",\n\t\t\t\".[0]\",\n\t\t],\n\t\t{ cwd },\n\t);\n\n\tconst trimmed = stdout.trim();\n\tif (!trimmed || trimmed === \"null\") {\n\t\treturn { state: \"NONE\", baseRefName: null };\n\t}\n\n\ttry {\n\t\tconst parsed = JSON.parse(trimmed) as {\n\t\t\tstate?: string;\n\t\t\tmergedAt?: string | null;\n\t\t\tbaseRefName?: string | null;\n\t\t};\n\t\tif (parsed.mergedAt) {\n\t\t\treturn {\n\t\t\t\tstate: \"MERGED\",\n\t\t\t\tbaseRefName: parsed.baseRefName ?? null,\n\t\t\t};\n\t\t}\n\t\tif (parsed.state === \"CLOSED\") {\n\t\t\treturn {\n\t\t\t\tstate: \"CLOSED\",\n\t\t\t\tbaseRefName: parsed.baseRefName ?? null,\n\t\t\t};\n\t\t}\n\t\tif (parsed.state === \"OPEN\") {\n\t\t\treturn {\n\t\t\t\tstate: \"OPEN\",\n\t\t\t\tbaseRefName: parsed.baseRefName ?? null,\n\t\t\t};\n\t\t}\n\t\treturn { state: \"NONE\", baseRefName: parsed.baseRefName ?? null };\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t`Failed to parse PR lifecycle state for branch '${branch}'.`,\n\t\t);\n\t}\n}\n\n/**\n * Creates a new PR and returns its info.\n *\n * Parses the PR number from the URL printed to stdout by `gh pr create`,\n * avoiding an extra API round-trip.\n *\n * @param branch - Head branch\n * @param base - Base branch the PR merges into\n * @param title - PR title\n * @param bodyFile - Absolute path to a file containing the PR body\n */\nexport async function createPr(\n\tbranch: string,\n\tbase: string,\n\ttitle: string,\n\tbodyFile: string,\n\tcwd: string,\n): Promise<PrInfo> {\n\tlet stdout: string;\n\ttry {\n\t\tconst result = await execa(\n\t\t\t\"gh\",\n\t\t\t[\n\t\t\t\t\"pr\",\n\t\t\t\t\"create\",\n\t\t\t\t\"--head\",\n\t\t\t\tbranch,\n\t\t\t\t\"--base\",\n\t\t\t\tbase,\n\t\t\t\t\"--title\",\n\t\t\t\ttitle,\n\t\t\t\t\"--body-file\",\n\t\t\t\tbodyFile,\n\t\t\t],\n\t\t\t{ cwd },\n\t\t);\n\t\tstdout = result.stdout;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (message.includes(\"403\") || message.includes(\"insufficient\")) {\n\t\t\tthrow new DubError(\n\t\t\t\t\"GitHub token lacks required permissions. Run 'gh auth login' with the 'repo' scope.\",\n\t\t\t);\n\t\t}\n\t\tthrow new DubError(`Failed to create PR for '${branch}': ${message}`);\n\t}\n\n\tconst url = stdout.trim();\n\tconst numberMatch = url.match(/\\/pull\\/(\\d+)$/);\n\tif (!numberMatch) {\n\t\tthrow new DubError(`Unexpected output from 'gh pr create': ${url}`);\n\t}\n\n\treturn {\n\t\tnumber: Number.parseInt(numberMatch[1], 10),\n\t\turl,\n\t\ttitle,\n\t\tbody: \"\",\n\t};\n}\n\n/**\n * Updates a PR's body using a file.\n * @param prNumber - The PR number to update\n * @param bodyFile - Absolute path to a file containing the new body\n */\nexport async function updatePrBody(\n\tprNumber: number,\n\tbodyFile: string,\n\tcwd: string,\n): Promise<void> {\n\ttry {\n\t\tawait execa(\n\t\t\t\"gh\",\n\t\t\t[\"pr\", \"edit\", String(prNumber), \"--body-file\", bodyFile],\n\t\t\t{ cwd },\n\t\t);\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (message.includes(\"403\") || message.includes(\"insufficient\")) {\n\t\t\tthrow new DubError(\n\t\t\t\t\"GitHub token lacks required permissions. Run 'gh auth login' with the 'repo' scope.\",\n\t\t\t);\n\t\t}\n\t\tthrow new DubError(`Failed to update PR #${prNumber}: ${message}`);\n\t}\n}\n\n/**\n * Opens a PR in the browser via GitHub CLI.\n *\n * @param cwd - Working directory\n * @param target - Optional branch name, PR number, or URL\n */\nexport async function openPrInBrowser(\n\tcwd: string,\n\ttarget?: string,\n): Promise<void> {\n\tconst args = target\n\t\t? [\"pr\", \"view\", target, \"--web\"]\n\t\t: [\"pr\", \"view\", \"--web\"];\n\ttry {\n\t\tawait execa(\"gh\", args, { cwd, stdio: \"inherit\" });\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (message.toLowerCase().includes(\"no pull requests\")) {\n\t\t\tthrow new DubError(\n\t\t\t\ttarget\n\t\t\t\t\t? `No PR found for '${target}'.`\n\t\t\t\t\t: \"No PR found for the current branch.\",\n\t\t\t);\n\t\t}\n\t\tthrow new DubError(\n\t\t\ttarget\n\t\t\t\t? `Failed to open PR for '${target}': ${message}`\n\t\t\t\t: `Failed to open PR: ${message}`,\n\t\t);\n\t}\n}\n","import { checkGhAuth, ensureGhInstalled, openPrInBrowser } from \"../lib/github\";\n\nexport async function pr(cwd: string, branch?: string): Promise<void> {\n\tawait ensureGhInstalled();\n\tawait checkGhAuth();\n\tawait openPrInBrowser(cwd, branch);\n}\n","import * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { DubError } from \"../lib/errors\";\nimport {\n\tgetBranchTip,\n\tgetCurrentBranch,\n\tgetLastCommitMessage,\n\tpushBranch,\n} from \"../lib/git\";\nimport {\n\tcheckGhAuth,\n\tcreatePr,\n\tensureGhInstalled,\n\tgetPr,\n\ttype PrInfo,\n\tupdatePrBody,\n} from \"../lib/github\";\nimport {\n\tbuildMetadataBlock,\n\tbuildStackTable,\n\tcomposePrBody,\n} from \"../lib/pr-body\";\nimport {\n\ttype Branch,\n\tfindStackForBranch,\n\treadState,\n\ttopologicalOrder,\n\twriteState,\n} from \"../lib/state\";\n\ninterface SubmitResult {\n\tpushed: string[];\n\tcreated: string[];\n\tupdated: string[];\n}\n\n/**\n * Pushes branches in the current stack and creates/updates GitHub PRs.\n *\n * @param cwd - Working directory\n * @param dryRun - If true, prints what would happen without executing\n * @throws {DubError} If not in a stack, on root branch, stack is non-linear, or gh errors\n */\nexport async function submit(\n\tcwd: string,\n\tdryRun: boolean,\n): Promise<SubmitResult> {\n\tawait ensureGhInstalled();\n\tawait checkGhAuth();\n\n\tconst state = await readState(cwd);\n\tconst currentBranch = await getCurrentBranch(cwd);\n\tconst stack = findStackForBranch(state, currentBranch);\n\n\tif (!stack) {\n\t\tthrow new DubError(\n\t\t\t`Branch '${currentBranch}' is not part of any stack. Run 'dub create' first.`,\n\t\t);\n\t}\n\n\tconst ordered = topologicalOrder(stack);\n\tconst currentEntry = ordered.find((b) => b.name === currentBranch);\n\tif (currentEntry?.type === \"root\") {\n\t\tthrow new DubError(\n\t\t\t\"Cannot submit from a root branch. Checkout a stack branch first.\",\n\t\t);\n\t}\n\n\tconst nonRootBranches = ordered.filter((b) => b.type !== \"root\");\n\n\tvalidateLinearStack(ordered);\n\n\tconst result: SubmitResult = { pushed: [], created: [], updated: [] };\n\tconst prMap = new Map<string, PrInfo>();\n\n\tfor (const branch of nonRootBranches) {\n\t\tif (dryRun) {\n\t\t\tconsole.log(`[dry-run] would push ${branch.name}`);\n\t\t} else {\n\t\t\tawait pushBranch(branch.name, cwd);\n\t\t}\n\t\tresult.pushed.push(branch.name);\n\t}\n\n\tfor (const branch of nonRootBranches) {\n\t\tconst base = branch.parent as string;\n\n\t\tif (dryRun) {\n\t\t\tconsole.log(`[dry-run] would check/create PR: ${branch.name} → ${base}`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst existing = await getPr(branch.name, cwd);\n\t\tif (existing) {\n\t\t\tprMap.set(branch.name, existing);\n\t\t\tresult.updated.push(branch.name);\n\t\t} else {\n\t\t\tconst title = await getLastCommitMessage(branch.name, cwd);\n\t\t\tconst tmpFile = writeTempBody(\"\");\n\t\t\ttry {\n\t\t\t\tconst created = await createPr(branch.name, base, title, tmpFile, cwd);\n\t\t\t\tprMap.set(branch.name, created);\n\t\t\t\tresult.created.push(branch.name);\n\t\t\t} finally {\n\t\t\t\tcleanupTempFile(tmpFile);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!dryRun) {\n\t\tawait updateAllPrBodies(nonRootBranches, prMap, stack.id, cwd);\n\n\t\tfor (const branch of nonRootBranches) {\n\t\t\tconst pr = prMap.get(branch.name);\n\t\t\tif (pr) {\n\t\t\t\tconst stateBranch = stack.branches.find((b) => b.name === branch.name);\n\t\t\t\tif (stateBranch) {\n\t\t\t\t\tstateBranch.pr_number = pr.number;\n\t\t\t\t\tstateBranch.pr_link = pr.url;\n\t\t\t\t\tconst headSha = await getBranchTip(branch.name, cwd);\n\t\t\t\t\tconst baseSha = await getBranchTip(branch.parent as string, cwd);\n\t\t\t\t\tstateBranch.last_submitted_version = {\n\t\t\t\t\t\thead_sha: headSha,\n\t\t\t\t\t\tbase_sha: baseSha,\n\t\t\t\t\t\tbase_branch: branch.parent as string,\n\t\t\t\t\t\tversion_number: null,\n\t\t\t\t\t\tsource: \"submit\",\n\t\t\t\t\t};\n\t\t\t\t\tstateBranch.last_synced_at = new Date().toISOString();\n\t\t\t\t\tstateBranch.sync_source = \"submit\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tawait writeState(state, cwd);\n\t}\n\n\treturn result;\n}\n\nfunction validateLinearStack(ordered: Branch[]): void {\n\tconst childCount = new Map<string, number>();\n\tfor (const branch of ordered) {\n\t\tif (branch.parent) {\n\t\t\tchildCount.set(branch.parent, (childCount.get(branch.parent) ?? 0) + 1);\n\t\t}\n\t}\n\tfor (const [parent, count] of childCount) {\n\t\tif (count > 1) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Branch '${parent}' has ${count} children. ` +\n\t\t\t\t\t\"Branching stacks are not supported by submit. \" +\n\t\t\t\t\t\"Ensure each branch has at most one child.\",\n\t\t\t);\n\t\t}\n\t}\n}\n\nasync function updateAllPrBodies(\n\tbranches: Branch[],\n\tprMap: Map<string, PrInfo>,\n\tstackId: string,\n\tcwd: string,\n): Promise<void> {\n\tconst tableEntries = new Map<string, { number: number; title: string }>();\n\tfor (const branch of branches) {\n\t\tconst pr = prMap.get(branch.name);\n\t\tif (pr) {\n\t\t\ttableEntries.set(branch.name, { number: pr.number, title: pr.title });\n\t\t}\n\t}\n\n\tfor (let i = 0; i < branches.length; i++) {\n\t\tconst branch = branches[i];\n\t\tconst pr = prMap.get(branch.name);\n\t\tif (!pr) continue;\n\n\t\tconst prevPr =\n\t\t\ti > 0 ? (prMap.get(branches[i - 1].name)?.number ?? null) : null;\n\t\tconst nextPr =\n\t\t\ti < branches.length - 1\n\t\t\t\t? (prMap.get(branches[i + 1].name)?.number ?? null)\n\t\t\t\t: null;\n\n\t\tconst stackTable = buildStackTable(branches, tableEntries, branch.name);\n\t\tconst metadataBlock = buildMetadataBlock(\n\t\t\tstackId,\n\t\t\tpr.number,\n\t\t\tprevPr,\n\t\t\tnextPr,\n\t\t\tbranch.name,\n\t\t);\n\n\t\tconst existingBody = pr.body;\n\t\tconst finalBody = composePrBody(existingBody, stackTable, metadataBlock);\n\n\t\tconst tmpFile = writeTempBody(finalBody);\n\t\ttry {\n\t\t\tawait updatePrBody(pr.number, tmpFile, cwd);\n\t\t} finally {\n\t\t\tcleanupTempFile(tmpFile);\n\t\t}\n\t}\n}\n\nfunction writeTempBody(content: string): string {\n\tconst tmpDir = os.tmpdir();\n\tconst tmpFile = path.join(tmpDir, `dubstack-body-${Date.now()}.md`);\n\tfs.writeFileSync(tmpFile, content);\n\treturn tmpFile;\n}\n\nfunction cleanupTempFile(filePath: string): void {\n\ttry {\n\t\tfs.unlinkSync(filePath);\n\t} catch {\n\t\t// Best-effort cleanup\n\t}\n}\n","import type { Branch } from \"./state\";\n\ninterface StackEntry {\n\tnumber: number;\n\ttitle: string;\n}\n\nconst DUBSTACK_START = \"<!-- dubstack:start -->\";\nconst DUBSTACK_END = \"<!-- dubstack:end -->\";\nconst METADATA_START = \"<!-- dubstack-metadata\";\nconst METADATA_END = \"-->\";\n\n/**\n * Builds the visible stack navigation table wrapped in dubstack markers.\n *\n * @param orderedBranches - Non-root branches in topological order\n * @param prMap - Map of branch name → PR number + title\n * @param currentBranch - The branch to mark with 👈\n */\nexport function buildStackTable(\n\torderedBranches: Branch[],\n\tprMap: Map<string, StackEntry>,\n\tcurrentBranch: string,\n): string {\n\tconst lines = orderedBranches.map((branch) => {\n\t\tconst entry = prMap.get(branch.name);\n\t\tif (!entry) return `- ${branch.name}`;\n\t\tconst marker = branch.name === currentBranch ? \" 👈\" : \"\";\n\t\treturn `- #${entry.number} ${entry.title}${marker}`;\n\t});\n\n\treturn [\n\t\tDUBSTACK_START,\n\t\t\"---\",\n\t\t\"### 🥞 DubStack\",\n\t\t...lines,\n\t\tDUBSTACK_END,\n\t].join(\"\\n\");\n}\n\n/**\n * Builds the hidden metadata HTML comment block.\n */\nexport function buildMetadataBlock(\n\tstackId: string,\n\tprNumber: number,\n\tprevPr: number | null,\n\tnextPr: number | null,\n\tbranch: string,\n): string {\n\tconst metadata = {\n\t\tstack_id: stackId,\n\t\tpr_number: prNumber,\n\t\tprev_pr: prevPr,\n\t\tnext_pr: nextPr,\n\t\tbranch,\n\t};\n\treturn `${METADATA_START}\\n${JSON.stringify(metadata, null, 2)}\\n${METADATA_END}`;\n}\n\n/**\n * Strips all DubStack-generated sections from a PR body.\n * Preserves user-written content. Returns body unchanged if no markers exist.\n */\nexport function stripDubstackSections(body: string): string {\n\tlet result = body;\n\n\tconst startIdx = result.indexOf(DUBSTACK_START);\n\tconst endIdx = result.indexOf(DUBSTACK_END);\n\tif (startIdx !== -1 && endIdx !== -1) {\n\t\tresult =\n\t\t\tresult.slice(0, startIdx) + result.slice(endIdx + DUBSTACK_END.length);\n\t}\n\n\tconst metaStart = result.indexOf(METADATA_START);\n\tif (metaStart !== -1) {\n\t\tconst metaEnd = result.indexOf(\n\t\t\tMETADATA_END,\n\t\t\tmetaStart + METADATA_START.length,\n\t\t);\n\t\tif (metaEnd !== -1) {\n\t\t\tresult =\n\t\t\t\tresult.slice(0, metaStart) +\n\t\t\t\tresult.slice(metaEnd + METADATA_END.length);\n\t\t}\n\t}\n\n\treturn result.trimEnd();\n}\n\n/**\n * Composes the final PR body by combining user content with DubStack sections.\n *\n * @param existingBody - The existing PR body (may contain stale DubStack sections)\n * @param stackTable - Output of `buildStackTable`\n * @param metadataBlock - Output of `buildMetadataBlock`\n */\nexport function composePrBody(\n\texistingBody: string,\n\tstackTable: string,\n\tmetadataBlock: string,\n): string {\n\tconst userContent = stripDubstackSections(existingBody);\n\tconst parts = [userContent, stackTable, metadataBlock].filter(Boolean);\n\treturn parts.join(\"\\n\\n\");\n}\n","import { stdin as input, stdout as output } from \"node:process\";\nimport * as readline from \"node:readline/promises\";\nimport { DubError } from \"../lib/errors\";\nimport {\n\tbranchExists,\n\tcheckoutBranch,\n\tcheckoutRemoteBranch,\n\tdeleteBranch,\n\tfastForwardBranchToRef,\n\tfetchBranches,\n\tgetCurrentBranch,\n\tgetRefSha,\n\thardResetBranchToRef,\n\tisAncestor,\n\trebaseBranchOntoRef,\n\tremoteBranchExists,\n} from \"../lib/git\";\nimport {\n\tcheckGhAuth,\n\tensureGhInstalled,\n\tgetBranchPrLifecycleState,\n\tgetBranchPrSyncInfo,\n} from \"../lib/github\";\nimport {\n\ttype Branch,\n\tfindStackForBranch,\n\treadState,\n\twriteState,\n} from \"../lib/state\";\nimport { classifyBranchSyncStatus } from \"../lib/sync/branch-status\";\nimport { buildCleanupPlan } from \"../lib/sync/cleanup\";\nimport { resolveReconcileDecision } from \"../lib/sync/reconcile\";\nimport { printBranchOutcome, printSyncSummary } from \"../lib/sync/report\";\nimport type {\n\tBranchSyncOutcome,\n\tSyncOptions,\n\tSyncResult,\n} from \"../lib/sync/types\";\nimport { restack } from \"./restack\";\n\nfunction isInteractiveShell(): boolean {\n\treturn Boolean(process.stdout.isTTY && process.stdin.isTTY);\n}\n\nasync function confirm(question: string): Promise<boolean> {\n\tconst rl = readline.createInterface({ input, output });\n\ttry {\n\t\tconst answer = await rl.question(`${question} [Y/n] `);\n\t\tconst normalized = answer.trim().toLowerCase();\n\t\treturn normalized === \"\" || normalized === \"y\" || normalized === \"yes\";\n\t} finally {\n\t\trl.close();\n\t}\n}\n\nasync function choose(\n\tquestion: string,\n\tchoices: Array<{ label: string; value: string }>,\n): Promise<string> {\n\tconst rl = readline.createInterface({ input, output });\n\ttry {\n\t\tconsole.log(question);\n\t\tfor (let i = 0; i < choices.length; i++) {\n\t\t\tconsole.log(` ${i + 1}. ${choices[i].label}`);\n\t\t}\n\t\tconst answer = await rl.question(\"Select option: \");\n\t\tconst idx = Number.parseInt(answer.trim(), 10) - 1;\n\t\tif (Number.isNaN(idx) || idx < 0 || idx >= choices.length) {\n\t\t\treturn choices[choices.length - 1].value;\n\t\t}\n\t\treturn choices[idx].value;\n\t} finally {\n\t\trl.close();\n\t}\n}\n\nexport async function sync(\n\tcwd: string,\n\trawOptions: {\n\t\trestack?: boolean;\n\t\tforce?: boolean;\n\t\tall?: boolean;\n\t\tinteractive?: boolean;\n\t} = {},\n): Promise<SyncResult> {\n\tawait ensureGhInstalled();\n\tawait checkGhAuth();\n\n\tconst options: SyncOptions = {\n\t\trestack: rawOptions.restack ?? true,\n\t\tforce: rawOptions.force ?? false,\n\t\tall: rawOptions.all ?? false,\n\t\tinteractive: rawOptions.interactive ?? isInteractiveShell(),\n\t};\n\n\tconst state = await readState(cwd);\n\tconst originalBranch = await getCurrentBranch(cwd);\n\n\tconst scopeStacks = options.all\n\t\t? state.stacks\n\t\t: (() => {\n\t\t\t\tconst stack = findStackForBranch(state, originalBranch);\n\t\t\t\tif (!stack) {\n\t\t\t\t\tthrow new DubError(\n\t\t\t\t\t\t`Branch '${originalBranch}' is not part of any stack. Run 'dub create' first.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn [stack];\n\t\t\t})();\n\tconst stateBranchMap = new Map<string, Branch>(\n\t\tscopeStacks.flatMap((stack) => stack.branches.map((b) => [b.name, b])),\n\t);\n\n\tconst roots = Array.from(\n\t\tnew Set(\n\t\t\tscopeStacks\n\t\t\t\t.flatMap((s) => s.branches)\n\t\t\t\t.filter((b) => b.type === \"root\")\n\t\t\t\t.map((b) => b.name),\n\t\t),\n\t);\n\tconst stackBranches = Array.from(\n\t\tnew Set(\n\t\t\tscopeStacks\n\t\t\t\t.flatMap((s) => s.branches)\n\t\t\t\t.filter((b) => b.type !== \"root\")\n\t\t\t\t.map((b) => b.name),\n\t\t),\n\t);\n\n\tconst result: SyncResult = {\n\t\tfetched: [],\n\t\ttrunksSynced: [],\n\t\tcleaned: [],\n\t\tbranches: [],\n\t\trestacked: false,\n\t};\n\tconst rootHasRemote = new Map<string, boolean>();\n\n\tconsole.log(\"🌲 Fetching branches from remote...\");\n\tconst toFetch = [...new Set([...roots, ...stackBranches])];\n\tif (toFetch.length > 0) {\n\t\tawait fetchBranches(toFetch, cwd);\n\t\tresult.fetched = toFetch;\n\t}\n\n\tfor (const root of roots) {\n\t\tconst remoteRef = `origin/${root}`;\n\t\tconst hasRemoteRoot = await remoteBranchExists(root, cwd);\n\t\trootHasRemote.set(root, hasRemoteRoot);\n\t\tif (!hasRemoteRoot) continue;\n\n\t\tconst ff = await fastForwardBranchToRef(root, remoteRef, cwd);\n\t\tif (ff) {\n\t\t\tresult.trunksSynced.push(root);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (options.force) {\n\t\t\tawait hardResetBranchToRef(root, remoteRef, cwd);\n\t\t\tresult.trunksSynced.push(root);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (options.interactive) {\n\t\t\tconst takeRemote = await confirm(\n\t\t\t\t`Trunk '${root}' cannot be fast-forwarded. Overwrite local trunk with '${remoteRef}'?`,\n\t\t\t);\n\t\t\tif (takeRemote) {\n\t\t\t\tawait hardResetBranchToRef(root, remoteRef, cwd);\n\t\t\t\tresult.trunksSynced.push(root);\n\t\t\t}\n\t\t}\n\t}\n\n\tconsole.log(\"🧹 Cleaning up branches with merged/closed PRs...\");\n\tconst localTrackedBranches: string[] = [];\n\tfor (const branch of stackBranches) {\n\t\tconst hasLocal = await branchExists(branch, cwd);\n\t\tif (hasLocal) localTrackedBranches.push(branch);\n\t}\n\tconst cleanupPlan = await buildCleanupPlan({\n\t\tbranches: localTrackedBranches,\n\t\tgetPrStatus: (branch) => getBranchPrLifecycleState(branch, cwd),\n\t\tisMergedIntoAnyRoot: async (branch) => {\n\t\t\tfor (const root of roots) {\n\t\t\t\tconst compareRef = rootHasRemote.get(root) ? `origin/${root}` : root;\n\t\t\t\tif (await isAncestor(branch, compareRef, cwd)) return true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t});\n\tconst excludedFromSync = new Set<string>();\n\tfor (const skipped of cleanupPlan.skipped) {\n\t\tif (skipped.reason === \"commits-not-in-trunk\") {\n\t\t\texcludedFromSync.add(skipped.branch);\n\t\t\tfor (const child of getDescendants(scopeStacks, skipped.branch)) {\n\t\t\t\texcludedFromSync.add(child);\n\t\t\t}\n\t\t}\n\t}\n\tfor (const branch of cleanupPlan.toDelete) {\n\t\tif (excludedFromSync.has(branch)) continue;\n\t\tlet shouldDelete = options.force;\n\t\tif (!shouldDelete && options.interactive) {\n\t\t\tshouldDelete = await confirm(\n\t\t\t\t`Branch '${branch}' has merged/closed PR and is in trunk. Delete local branch?`,\n\t\t\t);\n\t\t}\n\t\tif (shouldDelete) {\n\t\t\tawait checkoutBranch(roots[0] ?? originalBranch, cwd);\n\t\t\tawait deleteBranch(branch, cwd);\n\t\t\tremoveBranchFromState(scopeStacks, branch);\n\t\t\tresult.cleaned.push(branch);\n\t\t}\n\t}\n\tfor (const skipped of cleanupPlan.skipped) {\n\t\tconsole.log(\n\t\t\t`• Skipped cleanup for '${skipped.branch}' (${skipped.reason}).`,\n\t\t);\n\t}\n\tfor (const excluded of excludedFromSync) {\n\t\tconsole.log(\n\t\t\t`• Excluding '${excluded}' from sync because its stack is not cleanable yet.`,\n\t\t);\n\t}\n\n\tconsole.log(\"🔄 Syncing branches...\");\n\tfor (const branch of stackBranches) {\n\t\tif (result.cleaned.includes(branch) || excludedFromSync.has(branch))\n\t\t\tcontinue;\n\n\t\tconst hasRemote = await remoteBranchExists(branch, cwd);\n\t\tconst hasLocal = await branchExists(branch, cwd);\n\t\tlet outcome: BranchSyncOutcome;\n\n\t\tconst remoteRef = `origin/${branch}`;\n\t\tconst localSha = hasLocal ? await getRefSha(branch, cwd) : null;\n\t\tconst remoteSha = hasRemote ? await getRefSha(remoteRef, cwd) : null;\n\t\tconst localBehind =\n\t\t\thasLocal && hasRemote ? await isAncestor(branch, remoteRef, cwd) : false;\n\t\tconst remoteBehind =\n\t\t\thasLocal && hasRemote ? await isAncestor(remoteRef, branch, cwd) : false;\n\t\tlet status = classifyBranchSyncStatus({\n\t\t\thasRemote,\n\t\t\thasLocal,\n\t\t\tlocalSha,\n\t\t\tremoteSha,\n\t\t\tlocalBehind,\n\t\t\tremoteBehind,\n\t\t\thasSubmittedBaseline:\n\t\t\t\tstateBranchMap.get(branch)?.last_submitted_version != null,\n\t\t});\n\t\tconst prSyncInfo = hasRemote\n\t\t\t? await getBranchPrSyncInfo(branch, cwd)\n\t\t\t: { state: \"NONE\" as const, baseRefName: null };\n\t\tconst localParent = stateBranchMap.get(branch)?.parent ?? null;\n\t\tif (\n\t\t\thasRemote &&\n\t\t\thasLocal &&\n\t\t\tlocalSha !== remoteSha &&\n\t\t\tprSyncInfo.baseRefName &&\n\t\t\tlocalParent &&\n\t\t\tprSyncInfo.baseRefName !== localParent\n\t\t) {\n\t\t\tstatus = \"needs-remote-sync\";\n\t\t}\n\n\t\tif (status === \"missing-remote\") {\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus,\n\t\t\t\taction: \"skipped\",\n\t\t\t\tmessage: `⚠ Skipped '${branch}' (missing on remote).`,\n\t\t\t};\n\t\t\tresult.branches.push(outcome);\n\t\t\tprintBranchOutcome(outcome);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (status === \"missing-local\") {\n\t\t\tawait checkoutRemoteBranch(branch, cwd);\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus,\n\t\t\t\taction: \"synced\",\n\t\t\t\tmessage: `✔ Restored '${branch}' from remote.`,\n\t\t\t};\n\t\t\tresult.branches.push(outcome);\n\t\t\tprintBranchOutcome(outcome);\n\t\t\tconst restoredSha = await getRefSha(branch, cwd);\n\t\t\tawait markBranchSynced(stateBranchMap, branch, restoredSha, cwd, {\n\t\t\t\tsource: \"sync\",\n\t\t\t\tbaseBranch: stateBranchMap.get(branch)?.parent ?? null,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (status === \"up-to-date\") {\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus,\n\t\t\t\taction: \"none\",\n\t\t\t\tmessage: `• '${branch}' is up to date.`,\n\t\t\t};\n\t\t\tresult.branches.push(outcome);\n\t\t\tprintBranchOutcome(outcome);\n\t\t\tawait markBranchSynced(\n\t\t\t\tstateBranchMap,\n\t\t\t\tbranch,\n\t\t\t\tlocalSha ?? remoteSha ?? null,\n\t\t\t\tcwd,\n\t\t\t\t{\n\t\t\t\t\tsource: \"sync\",\n\t\t\t\t\tbaseBranch: stateBranchMap.get(branch)?.parent ?? null,\n\t\t\t\t},\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (status === \"updated-outside-dubstack-but-up-to-date\") {\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus,\n\t\t\t\taction: \"none\",\n\t\t\t\tmessage: `• '${branch}' is up to date but was previously unmanaged by DubStack sync metadata.`,\n\t\t\t};\n\t\t\tresult.branches.push(outcome);\n\t\t\tprintBranchOutcome(outcome);\n\t\t\tawait markBranchSynced(\n\t\t\t\tstateBranchMap,\n\t\t\t\tbranch,\n\t\t\t\tlocalSha ?? remoteSha ?? null,\n\t\t\t\tcwd,\n\t\t\t\t{\n\t\t\t\t\tsource: \"imported\",\n\t\t\t\t\tbaseBranch: stateBranchMap.get(branch)?.parent ?? null,\n\t\t\t\t},\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (status === \"needs-remote-sync-safe\") {\n\t\t\tawait hardResetBranchToRef(branch, remoteRef, cwd);\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus,\n\t\t\t\taction: \"synced\",\n\t\t\t\tmessage: `✔ Synced '${branch}' to remote head.`,\n\t\t\t};\n\t\t\tresult.branches.push(outcome);\n\t\t\tprintBranchOutcome(outcome);\n\t\t\tawait markBranchSynced(stateBranchMap, branch, remoteSha, cwd, {\n\t\t\t\tsource: \"sync\",\n\t\t\t\tbaseBranch: stateBranchMap.get(branch)?.parent ?? null,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (status === \"local-ahead\") {\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus,\n\t\t\t\taction: \"kept-local\",\n\t\t\t\tmessage: `• Kept local '${branch}' (local commits ahead of remote).`,\n\t\t\t};\n\t\t\tresult.branches.push(outcome);\n\t\t\tprintBranchOutcome(outcome);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (status === \"unsubmitted\") {\n\t\t\tif (options.force) {\n\t\t\t\tawait hardResetBranchToRef(branch, remoteRef, cwd);\n\t\t\t\toutcome = {\n\t\t\t\t\tbranch,\n\t\t\t\t\tstatus,\n\t\t\t\t\taction: \"synced\",\n\t\t\t\t\tmessage: `✔ Synced unsubmitted branch '${branch}' to remote with --force.`,\n\t\t\t\t};\n\t\t\t\tawait markBranchSynced(stateBranchMap, branch, remoteSha, cwd, {\n\t\t\t\t\tsource: \"sync\",\n\t\t\t\t\tbaseBranch: localParent,\n\t\t\t\t});\n\t\t\t} else if (!options.interactive) {\n\t\t\t\toutcome = {\n\t\t\t\t\tbranch,\n\t\t\t\t\tstatus,\n\t\t\t\t\taction: \"skipped\",\n\t\t\t\t\tmessage: `⚠ Skipped unsubmitted branch '${branch}' (use --force or interactive mode).`,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tconst takeRemote = await confirm(\n\t\t\t\t\t`Branch '${branch}' has no DubStack submit baseline. Overwrite local with remote version?`,\n\t\t\t\t);\n\t\t\t\tif (takeRemote) {\n\t\t\t\t\tawait hardResetBranchToRef(branch, remoteRef, cwd);\n\t\t\t\t\toutcome = {\n\t\t\t\t\t\tbranch,\n\t\t\t\t\t\tstatus,\n\t\t\t\t\t\taction: \"synced\",\n\t\t\t\t\t\tmessage: `✔ Synced unsubmitted branch '${branch}' to remote.`,\n\t\t\t\t\t};\n\t\t\t\t\tawait markBranchSynced(stateBranchMap, branch, remoteSha, cwd, {\n\t\t\t\t\t\tsource: \"sync\",\n\t\t\t\t\t\tbaseBranch: localParent,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\toutcome = {\n\t\t\t\t\t\tbranch,\n\t\t\t\t\t\tstatus,\n\t\t\t\t\t\taction: \"kept-local\",\n\t\t\t\t\t\tmessage: `• Kept local unsubmitted branch '${branch}'.`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\tresult.branches.push(outcome);\n\t\t\tprintBranchOutcome(outcome);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (status === \"needs-remote-sync\") {\n\t\t\tif (options.force) {\n\t\t\t\tawait hardResetBranchToRef(branch, remoteRef, cwd);\n\t\t\t\tif (prSyncInfo.baseRefName && localParent !== prSyncInfo.baseRefName) {\n\t\t\t\t\tconst stateBranch = stateBranchMap.get(branch);\n\t\t\t\t\tif (stateBranch) stateBranch.parent = prSyncInfo.baseRefName;\n\t\t\t\t}\n\t\t\t\toutcome = {\n\t\t\t\t\tbranch,\n\t\t\t\t\tstatus,\n\t\t\t\t\taction: \"synced\",\n\t\t\t\t\tmessage: `✔ Synced '${branch}' to remote and adopted remote parent '${prSyncInfo.baseRefName ?? \"unknown\"}'.`,\n\t\t\t\t};\n\t\t\t\tawait markBranchSynced(stateBranchMap, branch, remoteSha, cwd, {\n\t\t\t\t\tsource: \"sync\",\n\t\t\t\t\tbaseBranch: prSyncInfo.baseRefName ?? localParent,\n\t\t\t\t});\n\t\t\t} else if (!options.interactive) {\n\t\t\t\toutcome = {\n\t\t\t\t\tbranch,\n\t\t\t\t\tstatus,\n\t\t\t\t\taction: \"skipped\",\n\t\t\t\t\tmessage: `⚠ Skipped '${branch}' parent-mismatch sync (run interactively or with --force).`,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tconst parentDecision = await choose(\n\t\t\t\t\t`Branch '${branch}' parent differs locally ('${localParent}') vs remote ('${prSyncInfo.baseRefName}').`,\n\t\t\t\t\t[\n\t\t\t\t\t\t{ label: \"Take remote version and remote parent\", value: \"remote\" },\n\t\t\t\t\t\t{ label: \"Keep local branch and parent\", value: \"local\" },\n\t\t\t\t\t\t{ label: \"Skip for now\", value: \"skip\" },\n\t\t\t\t\t],\n\t\t\t\t);\n\t\t\t\tif (parentDecision === \"remote\") {\n\t\t\t\t\tawait hardResetBranchToRef(branch, remoteRef, cwd);\n\t\t\t\t\tconst stateBranch = stateBranchMap.get(branch);\n\t\t\t\t\tif (stateBranch && prSyncInfo.baseRefName) {\n\t\t\t\t\t\tstateBranch.parent = prSyncInfo.baseRefName;\n\t\t\t\t\t}\n\t\t\t\t\toutcome = {\n\t\t\t\t\t\tbranch,\n\t\t\t\t\t\tstatus,\n\t\t\t\t\t\taction: \"synced\",\n\t\t\t\t\t\tmessage: `✔ Synced '${branch}' to remote and adopted remote parent.`,\n\t\t\t\t\t};\n\t\t\t\t\tawait markBranchSynced(stateBranchMap, branch, remoteSha, cwd, {\n\t\t\t\t\t\tsource: \"sync\",\n\t\t\t\t\t\tbaseBranch: prSyncInfo.baseRefName ?? localParent,\n\t\t\t\t\t});\n\t\t\t\t} else if (parentDecision === \"local\") {\n\t\t\t\t\toutcome = {\n\t\t\t\t\t\tbranch,\n\t\t\t\t\t\tstatus,\n\t\t\t\t\t\taction: \"kept-local\",\n\t\t\t\t\t\tmessage: `• Kept local parent and local state for '${branch}'.`,\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\toutcome = {\n\t\t\t\t\t\tbranch,\n\t\t\t\t\t\tstatus,\n\t\t\t\t\t\taction: \"skipped\",\n\t\t\t\t\t\tmessage: `⚠ Skipped '${branch}' parent-mismatch sync by user choice.`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\tresult.branches.push(outcome);\n\t\t\tprintBranchOutcome(outcome);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst decision = await resolveReconcileDecision({\n\t\t\tbranch,\n\t\t\tforce: options.force,\n\t\t\tinteractive: options.interactive,\n\t\t\tpromptChoice: () =>\n\t\t\t\tchoose(\n\t\t\t\t\t`Branch '${branch}' diverged from remote. How should sync proceed?`,\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: \"Take remote version (discard local divergence)\",\n\t\t\t\t\t\t\tvalue: \"take-remote\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ label: \"Keep local version\", value: \"keep-local\" },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: \"Attempt reconciliation and keep local commits\",\n\t\t\t\t\t\t\tvalue: \"reconcile\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ label: \"Skip this branch\", value: \"skip\" },\n\t\t\t\t\t],\n\t\t\t\t),\n\t\t});\n\n\t\tif (decision === \"take-remote\") {\n\t\t\tawait hardResetBranchToRef(branch, remoteRef, cwd);\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus: \"reconcile-needed\",\n\t\t\t\taction: \"synced\",\n\t\t\t\tmessage: `✔ Synced '${branch}' to remote version.`,\n\t\t\t};\n\t\t\tawait markBranchSynced(stateBranchMap, branch, remoteSha, cwd, {\n\t\t\t\tsource: \"sync\",\n\t\t\t\tbaseBranch: stateBranchMap.get(branch)?.parent ?? null,\n\t\t\t});\n\t\t} else if (decision === \"keep-local\") {\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus: \"reconcile-needed\",\n\t\t\t\taction: \"kept-local\",\n\t\t\t\tmessage: `• Kept local '${branch}' (remote divergence ignored).`,\n\t\t\t};\n\t\t} else if (decision === \"reconcile\") {\n\t\t\tconst reconciled = await rebaseBranchOntoRef(branch, remoteRef, cwd);\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus: \"reconcile-needed\",\n\t\t\t\taction: reconciled ? \"synced\" : \"kept-local\",\n\t\t\t\tmessage: reconciled\n\t\t\t\t\t? `✔ Reconciled '${branch}' by rebasing local commits onto remote.`\n\t\t\t\t\t: `⚠ Could not auto-reconcile '${branch}'. Kept local state; reconcile manually.`,\n\t\t\t};\n\t\t\tif (reconciled) {\n\t\t\t\tconst newSha = await getRefSha(branch, cwd);\n\t\t\t\tawait markBranchSynced(stateBranchMap, branch, newSha, cwd, {\n\t\t\t\t\tsource: \"sync\",\n\t\t\t\t\tbaseBranch: stateBranchMap.get(branch)?.parent ?? null,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus: \"reconcile-needed\",\n\t\t\t\taction: \"skipped\",\n\t\t\t\tmessage: options.interactive\n\t\t\t\t\t? `⚠ Skipped '${branch}' by user choice.`\n\t\t\t\t\t: `⚠ Skipped '${branch}' (diverged from remote; rerun with --force or interactive).`,\n\t\t\t};\n\t\t}\n\t\tresult.branches.push(outcome);\n\t\tprintBranchOutcome(outcome);\n\t}\n\n\tif (options.restack) {\n\t\tconsole.log(\"🥞 Restacking branches...\");\n\t\tconst rootsToRestack = options.all ? roots : [roots[0]].filter(Boolean);\n\t\tfor (const root of rootsToRestack) {\n\t\t\tawait checkoutBranch(root, cwd);\n\t\t\tawait restack(cwd);\n\t\t}\n\t\tresult.restacked = true;\n\t}\n\n\tawait writeState(state, cwd);\n\tawait checkoutBranch(originalBranch, cwd);\n\tprintSyncSummary(result);\n\treturn result;\n}\n\nasync function markBranchSynced(\n\tbranchMap: Map<string, Branch>,\n\tbranchName: string,\n\theadSha: string | null,\n\tcwd: string,\n\toptions: { source: \"sync\" | \"imported\"; baseBranch: string | null },\n): Promise<void> {\n\tif (!headSha) return;\n\tconst entry = branchMap.get(branchName);\n\tif (!entry) return;\n\tconst priorBaseline = entry.last_submitted_version;\n\tconst resolvedBaseBranch =\n\t\toptions.baseBranch ?? priorBaseline?.base_branch ?? null;\n\tlet resolvedBaseSha = priorBaseline?.base_sha ?? null;\n\tif (resolvedBaseBranch) {\n\t\ttry {\n\t\t\tresolvedBaseSha = await getRefSha(resolvedBaseBranch, cwd);\n\t\t} catch {\n\t\t\t// Keep existing baseline SHA if base ref isn't currently resolvable.\n\t\t}\n\t}\n\tif (!resolvedBaseBranch || !resolvedBaseSha) return;\n\tentry.last_submitted_version = {\n\t\thead_sha: headSha,\n\t\tbase_sha: resolvedBaseSha,\n\t\tbase_branch: resolvedBaseBranch,\n\t\tversion_number: priorBaseline?.version_number ?? null,\n\t\tsource: options.source,\n\t};\n\tentry.last_synced_at = new Date().toISOString();\n\tentry.sync_source = options.source;\n}\n\nfunction getDescendants(stacks: Array<{ branches: Branch[] }>, branch: string) {\n\tconst descendants: string[] = [];\n\tconst childMap = new Map<string, string[]>();\n\tfor (const stack of stacks) {\n\t\tfor (const node of stack.branches) {\n\t\t\tif (!node.parent) continue;\n\t\t\tconst children = childMap.get(node.parent) ?? [];\n\t\t\tchildren.push(node.name);\n\t\t\tchildMap.set(node.parent, children);\n\t\t}\n\t}\n\tconst queue = [...(childMap.get(branch) ?? [])];\n\twhile (queue.length > 0) {\n\t\tconst next = queue.shift();\n\t\tif (!next) break;\n\t\tdescendants.push(next);\n\t\tqueue.push(...(childMap.get(next) ?? []));\n\t}\n\treturn descendants;\n}\n\nfunction removeBranchFromState(\n\tstacks: Array<{ branches: Branch[] }>,\n\tbranch: string,\n) {\n\tfor (const stack of stacks) {\n\t\tconst deleted = stack.branches.find((b) => b.name === branch);\n\t\tif (!deleted) continue;\n\t\tconst newParent = deleted.parent;\n\t\tfor (const child of stack.branches) {\n\t\t\tif (child.parent === branch) {\n\t\t\t\tchild.parent = newParent;\n\t\t\t}\n\t\t}\n\t\tstack.branches = stack.branches.filter((b) => b.name !== branch);\n\t}\n}\n","import type { BranchSyncStatus } from \"./types\";\n\nexport function classifyBranchSyncStatus(input: {\n\thasRemote: boolean;\n\thasLocal: boolean;\n\tlocalSha: string | null;\n\tremoteSha: string | null;\n\tlocalBehind: boolean;\n\tremoteBehind: boolean;\n\thasSubmittedBaseline?: boolean;\n}): BranchSyncStatus {\n\tif (!input.hasRemote) return \"missing-remote\";\n\tif (!input.hasLocal) return \"missing-local\";\n\n\tif (input.localSha && input.remoteSha && input.localSha === input.remoteSha) {\n\t\tif (!input.hasSubmittedBaseline) {\n\t\t\treturn \"updated-outside-dubstack-but-up-to-date\";\n\t\t}\n\t\treturn \"up-to-date\";\n\t}\n\n\tif (!input.hasSubmittedBaseline) return \"unsubmitted\";\n\tif (input.localBehind) return \"needs-remote-sync-safe\";\n\tif (input.remoteBehind) return \"local-ahead\";\n\treturn \"reconcile-needed\";\n}\n","import type { BranchPrLifecycleState } from \"../github\";\n\nexport interface CleanupPlan {\n\ttoDelete: string[];\n\tskipped: Array<{ branch: string; reason: string }>;\n}\n\nexport async function buildCleanupPlan(input: {\n\tbranches: string[];\n\tgetPrStatus: (branch: string) => Promise<BranchPrLifecycleState>;\n\tisMergedIntoAnyRoot: (branch: string) => Promise<boolean>;\n}): Promise<CleanupPlan> {\n\tconst toDelete: string[] = [];\n\tconst skipped: Array<{ branch: string; reason: string }> = [];\n\n\tfor (const branch of input.branches) {\n\t\tconst prState = await input.getPrStatus(branch);\n\t\tif (prState !== \"MERGED\" && prState !== \"CLOSED\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst mergedIntoRoot = await input.isMergedIntoAnyRoot(branch);\n\t\tif (!mergedIntoRoot) {\n\t\t\tskipped.push({ branch, reason: \"commits-not-in-trunk\" });\n\t\t\tcontinue;\n\t\t}\n\n\t\ttoDelete.push(branch);\n\t}\n\n\treturn { toDelete, skipped };\n}\n","export type ReconcileDecision =\n\t| \"take-remote\"\n\t| \"keep-local\"\n\t| \"reconcile\"\n\t| \"skip\";\n\nexport async function resolveReconcileDecision(input: {\n\tbranch: string;\n\tforce: boolean;\n\tinteractive: boolean;\n\tpromptChoice: () => Promise<string>;\n}): Promise<ReconcileDecision> {\n\tif (input.force) return \"take-remote\";\n\tif (!input.interactive) return \"skip\";\n\n\tconst raw = await input.promptChoice();\n\tif (\n\t\traw === \"take-remote\" ||\n\t\traw === \"keep-local\" ||\n\t\traw === \"reconcile\" ||\n\t\traw === \"skip\"\n\t) {\n\t\treturn raw;\n\t}\n\treturn \"skip\";\n}\n","import type { BranchSyncOutcome, SyncResult } from \"./types\";\n\nexport function printBranchOutcome(outcome: BranchSyncOutcome): void {\n\tconsole.log(outcome.message);\n}\n\nexport function printSyncSummary(result: SyncResult): void {\n\tconst synced = result.branches.filter((b) => b.action === \"synced\").length;\n\tconst skipped = result.branches.filter((b) => b.action === \"skipped\").length;\n\tconst keptLocal = result.branches.filter(\n\t\t(b) => b.action === \"kept-local\",\n\t).length;\n\tconsole.log(\n\t\t`✔ Sync complete: ${synced} synced, ${keptLocal} kept-local, ${skipped} skipped, ${result.cleaned.length} cleaned`,\n\t);\n}\n","import { DubError } from \"../lib/errors\";\nimport {\n\tcheckoutBranch,\n\tdeleteBranch,\n\tforceBranchTo,\n\tgetCurrentBranch,\n\tisWorkingTreeClean,\n} from \"../lib/git\";\nimport { writeState } from \"../lib/state\";\nimport { clearUndoEntry, readUndoEntry } from \"../lib/undo-log\";\n\ninterface UndoResult {\n\tundone: \"create\" | \"restack\";\n\tdetails: string;\n}\n\n/**\n * Undoes the last `dub create` or `dub restack` operation.\n *\n * Reversal strategy:\n * - **create**: Deletes the created branch, restores state, checks out the previous branch.\n * - **restack**: Resets every rebased branch to its pre-rebase tip via `git branch -f`,\n * restores state, checks out the previous branch.\n *\n * Only one level of undo is supported. After undo, the undo entry is cleared.\n *\n * @param cwd - Working directory\n * @returns What was undone and a human-readable summary\n * @throws {DubError} If nothing to undo or working tree is dirty\n */\nexport async function undo(cwd: string): Promise<UndoResult> {\n\tconst entry = await readUndoEntry(cwd);\n\n\tif (!(await isWorkingTreeClean(cwd))) {\n\t\tthrow new DubError(\n\t\t\t\"Working tree has uncommitted changes. Commit or stash them before undoing.\",\n\t\t);\n\t}\n\n\tconst currentBranch = await getCurrentBranch(cwd);\n\n\tif (entry.operation === \"create\") {\n\t\t// If we're on a branch that's about to be deleted, switch away first\n\t\tconst needsCheckout = entry.createdBranches.includes(currentBranch);\n\t\tif (needsCheckout) {\n\t\t\tawait checkoutBranch(entry.previousBranch, cwd);\n\t\t}\n\n\t\tfor (const branch of entry.createdBranches) {\n\t\t\tawait deleteBranch(branch, cwd);\n\t\t}\n\n\t\tif (!needsCheckout && currentBranch !== entry.previousBranch) {\n\t\t\tawait checkoutBranch(entry.previousBranch, cwd);\n\t\t}\n\n\t\tawait writeState(entry.previousState, cwd);\n\t\tawait clearUndoEntry(cwd);\n\n\t\treturn {\n\t\t\tundone: \"create\",\n\t\t\tdetails: `Deleted branch${entry.createdBranches.length > 1 ? \"es\" : \"\"} '${entry.createdBranches.join(\"', '\")}'`,\n\t\t};\n\t}\n\n\t// restack undo: reset all branches to their pre-rebase tips\n\t// First checkout a safe branch so we don't conflict with force-moves\n\tawait checkoutBranch(entry.previousBranch, cwd);\n\n\tfor (const [name, sha] of Object.entries(entry.branchTips)) {\n\t\tif (name === entry.previousBranch) continue; // skip the branch we're on\n\t\tawait forceBranchTo(name, sha, cwd);\n\t}\n\n\t// Now force the branch we're on (if it was tracked)\n\tif (entry.branchTips[entry.previousBranch]) {\n\t\tawait forceBranchTo(\n\t\t\tentry.previousBranch,\n\t\t\tentry.branchTips[entry.previousBranch],\n\t\t\tcwd,\n\t\t);\n\t}\n\n\tawait writeState(entry.previousState, cwd);\n\tawait clearUndoEntry(cwd);\n\n\treturn {\n\t\tundone: \"restack\",\n\t\tdetails: `Reset ${Object.keys(entry.branchTips).length} branches to pre-restack state`,\n\t};\n}\n"],"mappings":"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","names":["output","fs","path","fs","path","execa","init_skills","chalk","fs","path","getChildren","getChildren","getChildren","execa","fs","path","pr","input","input","input","require","chalk","addSkills","removeSkills","modify","output"]}
1
+ {"version":3,"sources":["../src/lib/errors.ts","../src/lib/git.ts","../src/lib/state.ts","../src/lib/undo-log.ts","../src/commands/restack.ts","../src/lib/skills.ts","../src/commands/skills.ts","../src/commands/modify.ts","../src/index.ts","../src/commands/abort.ts","../src/lib/operation-state.ts","../src/commands/branch.ts","../src/commands/checkout.ts","../src/commands/children.ts","../src/commands/continue.ts","../src/commands/create.ts","../src/commands/delete.ts","../src/lib/delete.ts","../src/lib/graph.ts","../src/lib/invariants.ts","../src/commands/init.ts","../src/commands/log.ts","../src/commands/navigate.ts","../src/commands/parent.ts","../src/lib/github.ts","../src/commands/pr.ts","../src/commands/submit.ts","../src/lib/pr-body.ts","../src/commands/sync.ts","../src/lib/sync/branch-status.ts","../src/lib/sync/cleanup.ts","../src/lib/sync/reconcile.ts","../src/lib/sync/report.ts","../src/commands/track.ts","../src/lib/track.ts","../src/commands/trunk.ts","../src/commands/undo.ts","../src/commands/untrack.ts","../src/lib/untrack.ts"],"sourcesContent":["/**\n * Base error class for all user-facing DubStack errors.\n *\n * The CLI entry point catches instances of this class and prints\n * a clean, colored error message. Unknown errors get a full stack trace.\n *\n * @example\n * ```ts\n * throw new DubError(\"Branch 'feat/x' already exists\")\n * ```\n */\nexport class DubError extends Error {\n\tconstructor(message: string) {\n\t\tsuper(message);\n\t\tthis.name = \"DubError\";\n\t}\n}\n","import { execa } from \"execa\";\nimport { DubError } from \"./errors\";\n\n/**\n * Checks whether the given directory is inside a git repository.\n * @returns `true` if inside a git worktree, `false` otherwise. Never throws.\n */\nexport async function isGitRepo(cwd: string): Promise<boolean> {\n\ttry {\n\t\tconst { stdout } = await execa(\n\t\t\t\"git\",\n\t\t\t[\"rev-parse\", \"--is-inside-work-tree\"],\n\t\t\t{ cwd },\n\t\t);\n\t\treturn stdout.trim() === \"true\";\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Returns the absolute path to the repository root.\n * @throws {DubError} If not inside a git repository.\n */\nexport async function getRepoRoot(cwd: string): Promise<string> {\n\ttry {\n\t\tconst { stdout } = await execa(\"git\", [\"rev-parse\", \"--show-toplevel\"], {\n\t\t\tcwd,\n\t\t});\n\t\treturn stdout.trim();\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t\"Not a git repository. Run this command inside a git repo.\",\n\t\t);\n\t}\n}\n\n/**\n * Returns the name of the currently checked-out branch.\n * @throws {DubError} If HEAD is detached or the repo has no commits.\n */\nexport async function getCurrentBranch(cwd: string): Promise<string> {\n\ttry {\n\t\tconst { stdout } = await execa(\n\t\t\t\"git\",\n\t\t\t[\"rev-parse\", \"--abbrev-ref\", \"HEAD\"],\n\t\t\t{ cwd },\n\t\t);\n\t\tconst branch = stdout.trim();\n\t\tif (branch === \"HEAD\") {\n\t\t\tthrow new DubError(\n\t\t\t\t\"HEAD is detached. Checkout a branch before running this command.\",\n\t\t\t);\n\t\t}\n\t\treturn branch;\n\t} catch (error) {\n\t\tif (error instanceof DubError) throw error;\n\t\tthrow new DubError(\n\t\t\t\"Repository has no commits. Make at least one commit first.\",\n\t\t);\n\t}\n}\n\n/**\n * Checks whether a branch with the given name exists locally.\n * @returns `true` if the branch exists, `false` otherwise. Never throws.\n */\nexport async function branchExists(\n\tname: string,\n\tcwd: string,\n): Promise<boolean> {\n\ttry {\n\t\tawait execa(\"git\", [\"rev-parse\", \"--verify\", `refs/heads/${name}`], {\n\t\t\tcwd,\n\t\t});\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Creates a new branch and switches to it.\n * @throws {DubError} If a branch with that name already exists.\n */\nexport async function createBranch(name: string, cwd: string): Promise<void> {\n\tif (await branchExists(name, cwd)) {\n\t\tthrow new DubError(`Branch '${name}' already exists.`);\n\t}\n\tawait execa(\"git\", [\"checkout\", \"-b\", name], { cwd });\n}\n\n/**\n * Switches to an existing branch.\n * @throws {DubError} If the branch does not exist.\n */\nexport async function checkoutBranch(name: string, cwd: string): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"checkout\", name], { cwd });\n\t} catch {\n\t\tthrow new DubError(`Branch '${name}' not found.`);\n\t}\n}\n\n/**\n * Deletes a local branch forcefully. Used by undo to remove created branches.\n * @throws {DubError} If the branch does not exist.\n */\nexport async function deleteBranch(name: string, cwd: string): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"branch\", \"-D\", name], { cwd });\n\t} catch {\n\t\tthrow new DubError(`Failed to delete branch '${name}'. It may not exist.`);\n\t}\n}\n\n/**\n * Deletes a local branch using safe (`-d`) or force (`-D`) mode.\n */\nexport async function deleteLocalBranch(\n\tname: string,\n\tcwd: string,\n\tforce = false,\n): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"branch\", force ? \"-D\" : \"-d\", name], { cwd });\n\t} catch {\n\t\tif (force) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Failed to delete branch '${name}'. It may not exist or be checked out.`,\n\t\t\t);\n\t\t}\n\t\tthrow new DubError(\n\t\t\t`Branch '${name}' is not fully merged. Re-run with --force to delete it.`,\n\t\t);\n\t}\n}\n\n/**\n * Force-moves a branch pointer to a specific commit SHA.\n * Used by undo to reset branches to their pre-operation tips.\n */\nexport async function forceBranchTo(\n\tname: string,\n\tsha: string,\n\tcwd: string,\n): Promise<void> {\n\ttry {\n\t\tconst current = await getCurrentBranch(cwd).catch(() => null);\n\t\tif (current === name) {\n\t\t\tawait execa(\"git\", [\"reset\", \"--hard\", sha], { cwd });\n\t\t} else {\n\t\t\tawait execa(\"git\", [\"branch\", \"-f\", name, sha], { cwd });\n\t\t}\n\t} catch (error) {\n\t\tif (error instanceof DubError) throw error;\n\t\tthrow new DubError(`Failed to reset branch '${name}' to ${sha}.`);\n\t}\n}\n\n/**\n * Checks whether the working tree is clean (no uncommitted changes).\n * @returns `true` if clean (no output from `git status --porcelain`).\n */\nexport async function isWorkingTreeClean(cwd: string): Promise<boolean> {\n\tconst { stdout } = await execa(\"git\", [\"status\", \"--porcelain\"], { cwd });\n\treturn stdout.trim() === \"\";\n}\n\n/**\n * Performs `git rebase --onto` to move a branch from one base to another.\n *\n * @param newBase - The commit/branch to rebase onto\n * @param oldBase - The old base commit to replay from\n * @param branch - The branch being rebased\n * @throws {DubError} If a merge conflict occurs during rebase\n */\nexport async function rebaseOnto(\n\tnewBase: string,\n\toldBase: string,\n\tbranch: string,\n\tcwd: string,\n): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"rebase\", \"--onto\", newBase, oldBase, branch], { cwd });\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t`Conflict while restacking '${branch}'.\\n` +\n\t\t\t\t\" Resolve conflicts, stage changes, then run: dub restack --continue\",\n\t\t);\n\t}\n}\n\n/**\n * Continues an in-progress rebase after conflicts have been resolved.\n * @throws {DubError} If the rebase continue fails.\n */\nexport async function rebaseContinue(cwd: string): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"rebase\", \"--continue\"], {\n\t\t\tcwd,\n\t\t\tenv: { GIT_EDITOR: \"true\" },\n\t\t});\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t\"Failed to continue rebase. Ensure all conflicts are resolved and staged.\",\n\t\t);\n\t}\n}\n\n/**\n * Aborts an in-progress rebase operation.\n */\nexport async function rebaseAbort(cwd: string): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"rebase\", \"--abort\"], { cwd });\n\t} catch {\n\t\tthrow new DubError(\"Failed to abort rebase.\");\n\t}\n}\n\n/**\n * Returns the merge-base (common ancestor) commit SHA of two branches.\n */\nexport async function getMergeBase(\n\ta: string,\n\tb: string,\n\tcwd: string,\n): Promise<string> {\n\ttry {\n\t\tconst { stdout } = await execa(\"git\", [\"merge-base\", a, b], { cwd });\n\t\treturn stdout.trim();\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t`Could not find common ancestor between '${a}' and '${b}'.`,\n\t\t);\n\t}\n}\n\n/**\n * Returns the commit SHA at the tip of a branch.\n * @throws {DubError} If the branch does not exist.\n */\nexport async function getBranchTip(name: string, cwd: string): Promise<string> {\n\ttry {\n\t\tconst { stdout } = await execa(\"git\", [\"rev-parse\", name], { cwd });\n\t\treturn stdout.trim();\n\t} catch {\n\t\tthrow new DubError(`Branch '${name}' not found.`);\n\t}\n}\n\n/**\n * Returns the subject line of the most recent commit on a branch.\n * @throws {DubError} If the branch has no commits.\n */\nexport async function getLastCommitMessage(\n\tbranch: string,\n\tcwd: string,\n): Promise<string> {\n\ttry {\n\t\tconst { stdout } = await execa(\n\t\t\t\"git\",\n\t\t\t[\"log\", \"-1\", \"--format=%s\", branch],\n\t\t\t{ cwd },\n\t\t);\n\t\tconst message = stdout.trim();\n\t\tif (!message) {\n\t\t\tthrow new DubError(`Branch '${branch}' has no commits.`);\n\t\t}\n\t\treturn message;\n\t} catch (error) {\n\t\tif (error instanceof DubError) throw error;\n\t\tthrow new DubError(`Failed to read commit message for '${branch}'.`);\n\t}\n}\n\n/**\n * Pushes a branch to origin with `--force-with-lease`.\n * @throws {DubError} If the push fails.\n */\nexport async function pushBranch(branch: string, cwd: string): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"push\", \"--force-with-lease\", \"origin\", branch], {\n\t\t\tcwd,\n\t\t});\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t`Failed to push '${branch}'. The remote ref may have been updated by someone else.`,\n\t\t);\n\t}\n}\n\n/**\n * Stages all changes (tracked, untracked, and deletions).\n * @throws {DubError} If git add fails.\n */\nexport async function stageAll(cwd: string): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"add\", \"-A\"], { cwd });\n\t} catch {\n\t\tthrow new DubError(\"Failed to stage changes.\");\n\t}\n}\n\n/**\n * Checks whether there are staged changes ready to commit.\n *\n * `git diff --cached --quiet` exits with code 1 when changes exist\n * and code 0 when there are none.\n */\nexport async function hasStagedChanges(cwd: string): Promise<boolean> {\n\ttry {\n\t\tawait execa(\"git\", [\"diff\", \"--cached\", \"--quiet\"], { cwd });\n\t\treturn false;\n\t} catch (error: unknown) {\n\t\tconst exitCode = (error as { exitCode?: number }).exitCode;\n\t\tif (exitCode === 1) return true;\n\t\tthrow new DubError(\"Failed to check staged changes.\");\n\t}\n}\n\n/**\n * Commits currently staged changes with the given message.\n * @throws {DubError} If the commit fails (e.g., nothing staged, hook rejection).\n */\nexport async function commitStaged(\n\tmessage: string,\n\tcwd: string,\n): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"commit\", \"-m\", message], { cwd });\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t`Commit failed. Ensure there are staged changes and git hooks pass.`,\n\t\t);\n\t}\n}\n\n/**\n * Commits currently staged changes, opening the editor if no message is provided.\n * @param cwd - The working directory.\n * @param options - Commit options (message, noEdit).\n * @throws {DubError} If the commit fails.\n */\nexport async function commit(\n\tcwd: string,\n\toptions?: { message?: string; noEdit?: boolean },\n): Promise<void> {\n\tconst args = [\"commit\"];\n\tif (options?.message) {\n\t\targs.push(\"-m\", options.message);\n\t}\n\tif (options?.noEdit) {\n\t\targs.push(\"--no-edit\");\n\t}\n\n\ttry {\n\t\tawait execa(\"git\", args, { cwd, stdio: \"inherit\" });\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t\"Commit failed. Ensure there are staged changes and git hooks pass.\",\n\t\t);\n\t}\n}\n\n/**\n * Amends the previous commit with currently staged changes.\n * @param cwd - The working directory.\n * @param options - Amend options (message, noEdit).\n * @throws {DubError} If the amend fails.\n */\nexport async function amendCommit(\n\tcwd: string,\n\toptions?: { message?: string; noEdit?: boolean },\n): Promise<void> {\n\tconst args = [\"commit\", \"--amend\"];\n\tif (options?.message) {\n\t\targs.push(\"-m\", options.message);\n\t}\n\tif (options?.noEdit) {\n\t\targs.push(\"--no-edit\");\n\t}\n\n\ttry {\n\t\tawait execa(\"git\", args, { cwd, stdio: \"inherit\" });\n\t} catch (e) {\n\t\tthrow new DubError(\n\t\t\t`Amend failed: ${e instanceof Error ? e.message : String(e)}`,\n\t\t);\n\t}\n}\n\n/**\n * Starts an interactive rebase from the given base.\n * Uses stdio: 'inherit' to allow user interaction.\n *\n * @param base - The commit or branch to rebase onto.\n * @param cwd - The working directory.\n * @throws {DubError} If rebase fails.\n */\nexport async function interactiveRebase(\n\tbase: string,\n\tcwd: string,\n): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"rebase\", \"-i\", base], { cwd, stdio: \"inherit\" });\n\t} catch {\n\t\tthrow new DubError(\"Interactive rebase failed or was cancelled.\");\n\t}\n}\n\n/**\n * Starts an interactive staging session (git add -p).\n * Uses stdio: 'inherit' to allow user interaction.\n *\n * @param cwd - The working directory.\n * @throws {DubError} If staging fails.\n */\nexport async function interactiveStage(cwd: string): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"add\", \"-p\"], { cwd, stdio: \"inherit\" });\n\t} catch {\n\t\tthrow new DubError(\"Interactive staging failed.\");\n\t}\n}\n\n/**\n * Stages all modified and deleted files (git add -u).\n *\n * @param cwd - The working directory.\n * @throws {DubError} If staging fails.\n */\nexport async function stageUpdate(cwd: string): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"add\", \"-u\"], { cwd });\n\t} catch {\n\t\tthrow new DubError(\"Failed to stage updates.\");\n\t}\n}\n\n/**\n * Returns the diff of changes.\n * @param staged - If true, shows staged changes (cached). If false, shows unstaged changes.\n */\nexport async function getDiff(cwd: string, staged: boolean): Promise<string> {\n\ttry {\n\t\tconst args = [\"diff\"];\n\t\tif (staged) args.push(\"--cached\");\n\t\tconst { stdout } = await execa(\"git\", args, { cwd });\n\t\treturn stdout;\n\t} catch {\n\t\treturn \"\";\n\t}\n}\n\n/**\n * Returns a list of all local branch names.\n */\nexport async function listBranches(cwd: string): Promise<string[]> {\n\ttry {\n\t\tconst { stdout } = await execa(\n\t\t\t\"git\",\n\t\t\t[\"branch\", \"--format=%(refname:short)\"],\n\t\t\t{ cwd },\n\t\t);\n\t\treturn stdout.trim().split(\"\\n\").filter(Boolean);\n\t} catch {\n\t\tthrow new DubError(\"Failed to list branches.\");\n\t}\n}\n\n/**\n * Fetches the provided branches from the remote.\n */\nexport async function fetchBranches(\n\tbranches: string[],\n\tcwd: string,\n\tremote = \"origin\",\n): Promise<void> {\n\tif (branches.length === 0) return;\n\tfor (const branch of branches) {\n\t\ttry {\n\t\t\tawait execa(\"git\", [\"fetch\", remote, branch], { cwd });\n\t\t} catch (error: unknown) {\n\t\t\tconst stderr =\n\t\t\t\ttypeof (error as { stderr?: unknown })?.stderr === \"string\"\n\t\t\t\t\t? (error as { stderr: string }).stderr\n\t\t\t\t\t: \"\";\n\t\t\tconst stdout =\n\t\t\t\ttypeof (error as { stdout?: unknown })?.stdout === \"string\"\n\t\t\t\t\t? (error as { stdout: string }).stdout\n\t\t\t\t\t: \"\";\n\t\t\tconst output = `${stderr}\\n${stdout}`;\n\t\t\tif (output.includes(\"couldn't find remote ref\")) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tthrow new DubError(`Failed to fetch branches from '${remote}'.`);\n\t\t}\n\t}\n}\n\n/**\n * Returns whether a remote branch exists.\n */\nexport async function remoteBranchExists(\n\tbranch: string,\n\tcwd: string,\n\tremote = \"origin\",\n): Promise<boolean> {\n\ttry {\n\t\tawait execa(\"git\", [\"rev-parse\", \"--verify\", `${remote}/${branch}`], {\n\t\t\tcwd,\n\t\t});\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Reads a ref SHA.\n */\nexport async function getRefSha(ref: string, cwd: string): Promise<string> {\n\ttry {\n\t\tconst { stdout } = await execa(\"git\", [\"rev-parse\", ref], { cwd });\n\t\treturn stdout.trim();\n\t} catch {\n\t\tthrow new DubError(`Failed to read ref '${ref}'.`);\n\t}\n}\n\n/**\n * Returns true when `ancestor` is an ancestor of `descendant`.\n */\nexport async function isAncestor(\n\tancestor: string,\n\tdescendant: string,\n\tcwd: string,\n): Promise<boolean> {\n\ttry {\n\t\tawait execa(\"git\", [\"merge-base\", \"--is-ancestor\", ancestor, descendant], {\n\t\t\tcwd,\n\t\t});\n\t\treturn true;\n\t} catch (error: unknown) {\n\t\tconst exitCode = (error as { exitCode?: number }).exitCode;\n\t\tif (exitCode === 1) return false;\n\t\tthrow new DubError(\n\t\t\t`Failed to compare ancestry between '${ancestor}' and '${descendant}'.`,\n\t\t);\n\t}\n}\n\n/**\n * Creates or resets a local branch from a remote ref and checks it out.\n */\nexport async function checkoutRemoteBranch(\n\tbranch: string,\n\tcwd: string,\n\tremote = \"origin\",\n): Promise<void> {\n\ttry {\n\t\tawait execa(\"git\", [\"checkout\", \"-B\", branch, `${remote}/${branch}`], {\n\t\t\tcwd,\n\t\t});\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t`Failed to create local branch '${branch}' from '${remote}/${branch}'.`,\n\t\t);\n\t}\n}\n\n/**\n * Resets a local branch hard to a ref.\n */\nexport async function hardResetBranchToRef(\n\tbranch: string,\n\tref: string,\n\tcwd: string,\n): Promise<void> {\n\ttry {\n\t\tconst current = await getCurrentBranch(cwd).catch(() => null);\n\t\tif (current !== branch) {\n\t\t\tawait checkoutBranch(branch, cwd);\n\t\t}\n\t\tawait execa(\"git\", [\"reset\", \"--hard\", ref], { cwd });\n\t} catch {\n\t\tthrow new DubError(`Failed to hard reset '${branch}' to '${ref}'.`);\n\t}\n}\n\n/**\n * Fast-forwards a local branch to a ref when possible.\n * Returns false when fast-forward is not possible.\n */\nexport async function fastForwardBranchToRef(\n\tbranch: string,\n\tref: string,\n\tcwd: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst current = await getCurrentBranch(cwd).catch(() => null);\n\t\tif (current !== branch) {\n\t\t\tawait checkoutBranch(branch, cwd);\n\t\t}\n\t\tawait execa(\"git\", [\"merge\", \"--ff-only\", ref], { cwd });\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\n/**\n * Rebases a branch onto a target ref.\n * Returns false if conflicts occur.\n */\nexport async function rebaseBranchOntoRef(\n\tbranch: string,\n\tref: string,\n\tcwd: string,\n): Promise<boolean> {\n\ttry {\n\t\tconst current = await getCurrentBranch(cwd).catch(() => null);\n\t\tif (current !== branch) {\n\t\t\tawait checkoutBranch(branch, cwd);\n\t\t}\n\t\tawait execa(\"git\", [\"rebase\", ref], { cwd });\n\t\treturn true;\n\t} catch {\n\t\ttry {\n\t\t\tawait execa(\"git\", [\"rebase\", \"--abort\"], { cwd });\n\t\t} catch {\n\t\t\t// no-op\n\t\t}\n\t\treturn false;\n\t}\n}\n","import * as crypto from \"node:crypto\";\nimport * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { DubError } from \"./errors\";\nimport { getRepoRoot } from \"./git\";\n\n/** A branch within a stack. */\nexport interface Branch {\n\t/** Branch name, e.g. \"feat/api-endpoint\" */\n\tname: string;\n\t/** Set to \"root\" for the base branch (e.g. main). Omitted for children. */\n\ttype?: \"root\";\n\t/** Name of the parent branch. `null` only for root branches. */\n\tparent: string | null;\n\t/** GitHub PR number. Populated after `dub submit`. */\n\tpr_number: number | null;\n\t/** GitHub PR URL. Populated after `dub submit`. */\n\tpr_link: string | null;\n\t/** Last known remote baseline synced/submitted for this branch. */\n\tlast_submitted_version?: {\n\t\thead_sha: string;\n\t\tbase_sha: string;\n\t\tbase_branch: string;\n\t\tversion_number: number | null;\n\t\tsource: \"submit\" | \"sync\" | \"imported\";\n\t} | null;\n\t/** ISO timestamp of the most recent successful sync for this branch. */\n\tlast_synced_at?: string | null;\n\t/** Source of the branch's current sync baseline metadata. */\n\tsync_source?: \"submit\" | \"sync\" | \"imported\" | null;\n}\n\n/** A stack of dependent branches. */\nexport interface Stack {\n\t/** Unique identifier for this stack. */\n\tid: string;\n\t/** Ordered list of branches in the stack. */\n\tbranches: Branch[];\n}\n\n/** Root state persisted to `.git/dubstack/state.json`. */\nexport interface DubState {\n\t/** All tracked stacks in this repository. */\n\tstacks: Stack[];\n}\n\n/**\n * Returns the absolute path to the dubstack state file.\n * @throws {DubError} If not inside a git repository.\n */\nexport async function getStatePath(cwd: string): Promise<string> {\n\tconst root = await getRepoRoot(cwd);\n\treturn path.join(root, \".git\", \"dubstack\", \"state.json\");\n}\n\n/**\n * Returns the absolute path to the dubstack directory inside `.git`.\n * @throws {DubError} If not inside a git repository.\n */\nexport async function getDubDir(cwd: string): Promise<string> {\n\tconst root = await getRepoRoot(cwd);\n\treturn path.join(root, \".git\", \"dubstack\");\n}\n\n/**\n * Reads and parses the dubstack state file.\n * @throws {DubError} If the state file is missing or contains invalid JSON.\n */\nexport async function readState(cwd: string): Promise<DubState> {\n\tconst statePath = await getStatePath(cwd);\n\tif (!fs.existsSync(statePath)) {\n\t\tthrow new DubError(\"DubStack is not initialized. Run 'dub init' first.\");\n\t}\n\ttry {\n\t\tconst raw = fs.readFileSync(statePath, \"utf-8\");\n\t\treturn normalizeState(JSON.parse(raw) as DubState);\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t\"State file is corrupted. Delete .git/dubstack and run 'dub init' to re-initialize.\",\n\t\t);\n\t}\n}\n\n/**\n * Writes the dubstack state to disk.\n * Creates the parent directory if it doesn't exist.\n */\nexport async function writeState(state: DubState, cwd: string): Promise<void> {\n\tconst statePath = await getStatePath(cwd);\n\tconst dir = path.dirname(statePath);\n\tif (!fs.existsSync(dir)) {\n\t\tfs.mkdirSync(dir, { recursive: true });\n\t}\n\tfs.writeFileSync(statePath, `${JSON.stringify(state, null, 2)}\\n`);\n}\n\n/**\n * Initializes the dubstack state directory and file.\n * Idempotent — returns `\"already_exists\"` if already initialized.\n *\n * @returns `\"created\"` if freshly initialized, `\"already_exists\"` if state file already present.\n */\nexport async function initState(\n\tcwd: string,\n): Promise<\"created\" | \"already_exists\"> {\n\tconst statePath = await getStatePath(cwd);\n\tconst dir = path.dirname(statePath);\n\n\tif (fs.existsSync(statePath)) {\n\t\treturn \"already_exists\";\n\t}\n\n\tfs.mkdirSync(dir, { recursive: true });\n\tconst emptyState: DubState = { stacks: [] };\n\tfs.writeFileSync(statePath, `${JSON.stringify(emptyState, null, 2)}\\n`);\n\treturn \"created\";\n}\n\n/**\n * Returns state, auto-initializing if not yet set up.\n * Only catches the \"not initialized\" error — corrupt state still throws.\n */\nexport async function ensureState(cwd: string): Promise<DubState> {\n\ttry {\n\t\treturn await readState(cwd);\n\t} catch (error) {\n\t\tif (\n\t\t\terror instanceof DubError &&\n\t\t\terror.message.includes(\"not initialized\")\n\t\t) {\n\t\t\tawait initState(cwd);\n\t\t\treturn await readState(cwd);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * Finds the stack containing a given branch.\n * @returns The matching stack, or `undefined` if the branch isn't tracked.\n */\nexport function findStackForBranch(\n\tstate: DubState,\n\tname: string,\n): Stack | undefined {\n\treturn state.stacks.find((stack) =>\n\t\tstack.branches.some((b) => b.name === name),\n\t);\n}\n\n/**\n * Returns the parent branch name for a given branch.\n * @returns The parent branch name, or `undefined` if not found or is a root.\n */\nexport function getParent(\n\tstate: DubState,\n\tbranchName: string,\n): string | undefined {\n\tconst stack = findStackForBranch(state, branchName);\n\tif (!stack) return undefined;\n\n\tconst branch = stack.branches.find((b) => b.name === branchName);\n\treturn branch?.parent ?? undefined;\n}\n\n/**\n * Adds a child branch to the state, linking it to its parent.\n *\n * Decision tree:\n * 1. If `child` already exists in any stack → throws `DubError` (no duplicates)\n * 2. If `parent` is found in an existing stack → appends child to that stack\n * 3. If `parent` is not in any stack → creates a new stack with parent as root\n *\n * @param state - The state to mutate (modified in place)\n * @param child - Name of the new branch\n * @param parent - Name of the parent branch\n * @throws {DubError} If child branch already exists in state\n */\nexport function addBranchToStack(\n\tstate: DubState,\n\tchild: string,\n\tparent: string,\n): void {\n\tif (findStackForBranch(state, child)) {\n\t\tthrow new DubError(`Branch '${child}' is already tracked in a stack.`);\n\t}\n\n\tconst childBranch: Branch = {\n\t\tname: child,\n\t\tparent,\n\t\tpr_number: null,\n\t\tpr_link: null,\n\t\tlast_submitted_version: null,\n\t\tlast_synced_at: null,\n\t\tsync_source: null,\n\t};\n\tconst existingStack = findStackForBranch(state, parent);\n\n\tif (existingStack) {\n\t\texistingStack.branches.push(childBranch);\n\t} else {\n\t\tconst rootBranch: Branch = {\n\t\t\tname: parent,\n\t\t\ttype: \"root\",\n\t\t\tparent: null,\n\t\t\tpr_number: null,\n\t\t\tpr_link: null,\n\t\t\tlast_submitted_version: null,\n\t\t\tlast_synced_at: null,\n\t\t\tsync_source: null,\n\t\t};\n\t\tstate.stacks.push({\n\t\t\tid: crypto.randomUUID(),\n\t\t\tbranches: [rootBranch, childBranch],\n\t\t});\n\t}\n}\n\nfunction normalizeState(state: DubState): DubState {\n\treturn {\n\t\tstacks: state.stacks.map((stack) => ({\n\t\t\t...stack,\n\t\t\tbranches: stack.branches.map((branch) => normalizeBranch(branch)),\n\t\t})),\n\t};\n}\n\nfunction normalizeBranch(branch: Branch): Branch {\n\treturn {\n\t\t...branch,\n\t\tlast_submitted_version: branch.last_submitted_version ?? null,\n\t\tlast_synced_at: branch.last_synced_at ?? null,\n\t\tsync_source: branch.sync_source ?? null,\n\t};\n}\n\n/**\n * Returns branches in topological (BFS) order starting from the root.\n * Useful for operations that need to process parent branches before children.\n */\nexport function topologicalOrder(stack: Stack): Branch[] {\n\tconst result: Branch[] = [];\n\tconst root = stack.branches.find((b) => b.type === \"root\");\n\tif (!root) return result;\n\n\tconst childMap = new Map<string, Branch[]>();\n\tfor (const branch of stack.branches) {\n\t\tif (branch.parent) {\n\t\t\tconst children = childMap.get(branch.parent) ?? [];\n\t\t\tchildren.push(branch);\n\t\t\tchildMap.set(branch.parent, children);\n\t\t}\n\t}\n\n\tconst queue = [root];\n\twhile (queue.length > 0) {\n\t\tconst current = queue.shift();\n\t\tif (!current) break;\n\t\tresult.push(current);\n\t\tconst children = childMap.get(current.name) ?? [];\n\t\tqueue.push(...children);\n\t}\n\n\treturn result;\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { DubError } from \"./errors\";\nimport type { DubState } from \"./state\";\nimport { getDubDir } from \"./state\";\n\n/**\n * Snapshot of system state before a mutation, used by `dub undo`.\n * Only one undo level is supported — each new mutation overwrites the previous snapshot.\n */\nexport interface UndoEntry {\n\t/** Which command created this snapshot. */\n\toperation: \"create\" | \"restack\";\n\t/** ISO timestamp of when the snapshot was taken. */\n\ttimestamp: string;\n\t/** The branch user was on before the operation. */\n\tpreviousBranch: string;\n\t/** Full copy of state.json before mutation. */\n\tpreviousState: DubState;\n\t/** Map of branch name → commit SHA before mutation. */\n\tbranchTips: Record<string, string>;\n\t/** Branches created by this operation (to be deleted on undo). */\n\tcreatedBranches: string[];\n}\n\nasync function getUndoPath(cwd: string): Promise<string> {\n\tconst dubDir = await getDubDir(cwd);\n\treturn path.join(dubDir, \"undo.json\");\n}\n\n/**\n * Saves an undo entry to disk. Overwrites any previous entry (1 level only).\n */\nexport async function saveUndoEntry(\n\tentry: UndoEntry,\n\tcwd: string,\n): Promise<void> {\n\tconst undoPath = await getUndoPath(cwd);\n\tfs.writeFileSync(undoPath, `${JSON.stringify(entry, null, 2)}\\n`);\n}\n\n/**\n * Reads the most recent undo entry.\n * @throws {DubError} If no undo entry exists.\n */\nexport async function readUndoEntry(cwd: string): Promise<UndoEntry> {\n\tconst undoPath = await getUndoPath(cwd);\n\tif (!fs.existsSync(undoPath)) {\n\t\tthrow new DubError(\"Nothing to undo.\");\n\t}\n\tconst raw = fs.readFileSync(undoPath, \"utf-8\");\n\treturn JSON.parse(raw) as UndoEntry;\n}\n\n/**\n * Deletes the undo entry file. Called after a successful undo.\n */\nexport async function clearUndoEntry(cwd: string): Promise<void> {\n\tconst undoPath = await getUndoPath(cwd);\n\tif (fs.existsSync(undoPath)) {\n\t\tfs.unlinkSync(undoPath);\n\t}\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { DubError } from \"../lib/errors\";\nimport {\n\tbranchExists,\n\tcheckoutBranch,\n\tgetBranchTip,\n\tgetCurrentBranch,\n\tgetMergeBase,\n\trebaseContinue as gitRebaseContinue,\n\tisWorkingTreeClean,\n\trebaseOnto,\n} from \"../lib/git\";\nimport {\n\tgetDubDir,\n\treadState,\n\ttype Stack,\n\ttopologicalOrder,\n} from \"../lib/state\";\nimport { saveUndoEntry } from \"../lib/undo-log\";\n\ninterface RestackStep {\n\tbranch: string;\n\tparent: string;\n\tparentOldTip: string;\n\tstatus: \"pending\" | \"done\" | \"skipped\" | \"conflicted\";\n}\n\ninterface RestackProgress {\n\toriginalBranch: string;\n\tsteps: RestackStep[];\n}\n\ninterface RestackResult {\n\tstatus: \"success\" | \"conflict\" | \"up-to-date\";\n\trebased: string[];\n\tconflictBranch?: string;\n}\n\n/**\n * Rebases all branches in the current stack onto their updated parents.\n *\n * Uses a snapshot-before-rebase strategy: captures every branch's tip\n * BEFORE starting any rebases, then uses `git rebase --onto <parent_new_tip>\n * <parent_old_tip> <child>`. This prevents the duplication bug where a child\n * replays its parent's already-rebased commits.\n *\n * On conflict, writes progress to `restack-progress.json` so\n * `dub restack --continue` can resume.\n *\n * @param cwd - Working directory\n * @returns Result with status, list of rebased branches, and optional conflict branch\n * @throws {DubError} If not initialized, dirty tree, not in a stack, or branch missing\n */\nexport async function restack(cwd: string): Promise<RestackResult> {\n\tconst state = await readState(cwd);\n\n\tif (!(await isWorkingTreeClean(cwd))) {\n\t\tthrow new DubError(\n\t\t\t\"Working tree has uncommitted changes. Commit or stash them before restacking.\",\n\t\t);\n\t}\n\n\tconst originalBranch = await getCurrentBranch(cwd);\n\tconst targetStacks = getTargetStacks(state.stacks, originalBranch);\n\n\tif (targetStacks.length === 0) {\n\t\tthrow new DubError(\n\t\t\t`Branch '${originalBranch}' is not part of any stack. Run 'dub create' first.`,\n\t\t);\n\t}\n\n\tconst allBranches = targetStacks.flatMap((s) => s.branches);\n\tfor (const branch of allBranches) {\n\t\tif (!(await branchExists(branch.name, cwd))) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Branch '${branch.name}' is tracked in state but no longer exists in git.\\n` +\n\t\t\t\t\t\" Remove it from the stack or recreate it before restacking.\",\n\t\t\t);\n\t\t}\n\t}\n\n\t// Snapshot all branch tips BEFORE building steps or rebasing\n\tconst branchTips: Record<string, string> = {};\n\tfor (const branch of allBranches) {\n\t\tbranchTips[branch.name] = await getBranchTip(branch.name, cwd);\n\t}\n\n\tconst steps = await buildRestackSteps(targetStacks, cwd);\n\n\tif (steps.length === 0) {\n\t\treturn { status: \"up-to-date\", rebased: [] };\n\t}\n\n\tawait saveUndoEntry(\n\t\t{\n\t\t\toperation: \"restack\",\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tpreviousBranch: originalBranch,\n\t\t\tpreviousState: structuredClone(state),\n\t\t\tbranchTips,\n\t\t\tcreatedBranches: [],\n\t\t},\n\t\tcwd,\n\t);\n\n\tconst progress: RestackProgress = { originalBranch, steps };\n\tawait writeProgress(progress, cwd);\n\n\treturn executeRestackSteps(progress, cwd);\n}\n\n/**\n * Continues a restack after conflict resolution.\n *\n * Reads the saved progress file, finishes the in-progress rebase,\n * then resumes with remaining branches.\n *\n * @param cwd - Working directory\n * @throws {DubError} If no restack is in progress\n */\nexport async function restackContinue(cwd: string): Promise<RestackResult> {\n\tconst progress = await readProgress(cwd);\n\n\tif (!progress) {\n\t\tthrow new DubError(\"No restack in progress. Run 'dub restack' to start.\");\n\t}\n\n\tawait gitRebaseContinue(cwd);\n\n\tconst conflictedStep = progress.steps.find((s) => s.status === \"conflicted\");\n\tif (conflictedStep) {\n\t\tconflictedStep.status = \"done\";\n\t}\n\n\treturn executeRestackSteps(progress, cwd);\n}\n\nasync function executeRestackSteps(\n\tprogress: RestackProgress,\n\tcwd: string,\n): Promise<RestackResult> {\n\tconst rebased: string[] = [];\n\n\tfor (const step of progress.steps) {\n\t\tif (step.status !== \"pending\") {\n\t\t\tif (step.status === \"done\") rebased.push(step.branch);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst parentNewTip = await getBranchTip(step.parent, cwd);\n\t\tif (parentNewTip === step.parentOldTip) {\n\t\t\tstep.status = \"skipped\";\n\t\t\tawait writeProgress(progress, cwd);\n\t\t\tcontinue;\n\t\t}\n\n\t\ttry {\n\t\t\tawait rebaseOnto(parentNewTip, step.parentOldTip, step.branch, cwd);\n\t\t\tstep.status = \"done\";\n\t\t\trebased.push(step.branch);\n\t\t\tawait writeProgress(progress, cwd);\n\t\t} catch (error) {\n\t\t\tif (error instanceof DubError && error.message.includes(\"Conflict\")) {\n\t\t\t\tstep.status = \"conflicted\";\n\t\t\t\tawait writeProgress(progress, cwd);\n\t\t\t\treturn { status: \"conflict\", rebased, conflictBranch: step.branch };\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t}\n\n\tawait clearProgress(cwd);\n\tawait checkoutBranch(progress.originalBranch, cwd);\n\n\tconst allSkipped = progress.steps.every(\n\t\t(s) => s.status === \"skipped\" || s.status === \"done\",\n\t);\n\treturn {\n\t\tstatus: rebased.length === 0 && allSkipped ? \"up-to-date\" : \"success\",\n\t\trebased,\n\t};\n}\n\nfunction getTargetStacks(stacks: Stack[], currentBranch: string): Stack[] {\n\t// If current branch is a root of any stacks, restack all of them\n\tconst rootStacks = stacks.filter((s) =>\n\t\ts.branches.some((b) => b.name === currentBranch && b.type === \"root\"),\n\t);\n\tif (rootStacks.length > 0) return rootStacks;\n\n\t// Otherwise, find the stack containing the current branch\n\tconst stack = stacks.find((s) =>\n\t\ts.branches.some((b) => b.name === currentBranch),\n\t);\n\treturn stack ? [stack] : [];\n}\n\nasync function buildRestackSteps(\n\tstacks: Stack[],\n\tcwd: string,\n): Promise<RestackStep[]> {\n\tconst steps: RestackStep[] = [];\n\n\tfor (const stack of stacks) {\n\t\tconst ordered = topologicalOrder(stack);\n\t\tfor (const branch of ordered) {\n\t\t\tif (branch.type === \"root\" || !branch.parent) continue;\n\t\t\tconst mergeBase = await getMergeBase(branch.parent, branch.name, cwd);\n\t\t\tsteps.push({\n\t\t\t\tbranch: branch.name,\n\t\t\t\tparent: branch.parent,\n\t\t\t\tparentOldTip: mergeBase,\n\t\t\t\tstatus: \"pending\",\n\t\t\t});\n\t\t}\n\t}\n\n\treturn steps;\n}\n\nasync function getProgressPath(cwd: string): Promise<string> {\n\tconst dubDir = await getDubDir(cwd);\n\treturn path.join(dubDir, \"restack-progress.json\");\n}\n\nasync function writeProgress(\n\tprogress: RestackProgress,\n\tcwd: string,\n): Promise<void> {\n\tconst progressPath = await getProgressPath(cwd);\n\tfs.writeFileSync(progressPath, `${JSON.stringify(progress, null, 2)}\\n`);\n}\n\nasync function readProgress(cwd: string): Promise<RestackProgress | null> {\n\tconst progressPath = await getProgressPath(cwd);\n\tif (!fs.existsSync(progressPath)) return null;\n\tconst raw = fs.readFileSync(progressPath, \"utf-8\");\n\treturn JSON.parse(raw) as RestackProgress;\n}\n\nasync function clearProgress(cwd: string): Promise<void> {\n\tconst progressPath = await getProgressPath(cwd);\n\tif (fs.existsSync(progressPath)) {\n\t\tfs.unlinkSync(progressPath);\n\t}\n}\n","export const AVAILABLE_SKILLS = {\n\tdubstack: \"wiseiodev/dubstack/skills/dubstack\",\n\t\"dub-flow\": \"wiseiodev/dubstack/skills/dub-flow\",\n} as const;\n\nexport type SkillName = keyof typeof AVAILABLE_SKILLS;\n\nexport function getSkillRemote(name: SkillName): string {\n\treturn AVAILABLE_SKILLS[name];\n}\n","import chalk from \"chalk\";\nimport { execa } from \"execa\";\nimport { DubError } from \"../lib/errors\";\nimport {\n\tAVAILABLE_SKILLS,\n\tgetSkillRemote,\n\ttype SkillName,\n} from \"../lib/skills\";\n\ninterface SkillsOptions {\n\tglobal?: boolean;\n\tdryRun?: boolean;\n}\n\nfunction validateSkills(skills: string[]): SkillName[] {\n\tconst invalidSkills = skills.filter((s) => !(s in AVAILABLE_SKILLS));\n\n\tif (invalidSkills.length > 0) {\n\t\tthrow new DubError(\n\t\t\t`Unknown skill(s): ${invalidSkills.join(\", \")}. Available skills: ${Object.keys(AVAILABLE_SKILLS).join(\", \")}`,\n\t\t);\n\t}\n\n\treturn skills as SkillName[];\n}\n\nexport async function addSkills(skills: string[], options: SkillsOptions = {}) {\n\tconst targets =\n\t\tskills.length > 0\n\t\t\t? validateSkills(skills)\n\t\t\t: (Object.keys(AVAILABLE_SKILLS) as SkillName[]);\n\n\tconsole.log(chalk.blue(`Adding ${targets.length} skill(s)...`));\n\n\tfor (const skill of targets) {\n\t\tconst remote = getSkillRemote(skill);\n\t\tconst args = [\"skills\", \"add\", remote];\n\t\tif (options.global) args.push(\"--global\");\n\n\t\tconst command = `npx ${args.join(\" \")}`;\n\t\tconsole.log(chalk.dim(`Running: ${command}`));\n\n\t\tif (!options.dryRun) {\n\t\t\ttry {\n\t\t\t\tawait execa(\"npx\", args, { stdio: \"inherit\" });\n\t\t\t\tconsole.log(chalk.green(`✔ Added skill: ${skill}`));\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(chalk.red(`✖ Failed to add skill: ${skill}`));\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport async function removeSkills(\n\tskills: string[],\n\toptions: SkillsOptions = {},\n) {\n\tconst targets =\n\t\tskills.length > 0\n\t\t\t? validateSkills(skills)\n\t\t\t: (Object.keys(AVAILABLE_SKILLS) as SkillName[]);\n\n\tconsole.log(chalk.blue(`Removing ${targets.length} skill(s)...`));\n\n\tfor (const skill of targets) {\n\t\tconst args = [\"skills\", \"remove\", skill];\n\t\tif (options.global) args.push(\"--global\");\n\n\t\tconst command = `npx ${args.join(\" \")}`;\n\t\tconsole.log(chalk.dim(`Running: ${command}`));\n\n\t\tif (!options.dryRun) {\n\t\t\ttry {\n\t\t\t\tawait execa(\"npx\", args, { stdio: \"inherit\" });\n\t\t\t\tconsole.log(chalk.green(`✔ Removed skill: ${skill}`));\n\t\t\t} catch (error) {\n\t\t\t\tconsole.error(chalk.red(`✖ Failed to remove skill: ${skill}`));\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t}\n\t}\n}\n","import { DubError } from \"../lib/errors\";\nimport {\n\tamendCommit,\n\tcommit,\n\tgetBranchTip,\n\tgetCurrentBranch,\n\tgetDiff,\n\thasStagedChanges,\n\tinteractiveRebase,\n\tinteractiveStage,\n\tstageAll,\n\tstageUpdate,\n} from \"../lib/git\";\nimport { getParent, readState } from \"../lib/state\";\nimport { restack } from \"./restack\";\n\n/**\n * Options for the modify command.\n */\ninterface ModifyOptions {\n\t/** Stage all changes before committing. */\n\tall?: boolean;\n\t/** Create a new commit instead of amending. */\n\tcommit?: boolean;\n\t/** Open editor to edit the commit message. */\n\tedit?: boolean;\n\t/** Start an interactive rebase on the branch commits. */\n\tinteractiveRebase?: boolean;\n\t/** Amend staged changes to the specified branch. */\n\tinto?: string;\n\t/** Message for the new or amended commit. */\n\tmessage?: string | string[];\n\t/** Pick hunks to stage before committing. */\n\tpatch?: boolean;\n\t/** Set the author to the current user. */\n\tresetAuthor?: boolean;\n\t/** Stage all updates to tracked files. */\n\tupdate?: boolean;\n\t/** Show unified diff. */\n\tverbose?: number;\n}\n\n/**\n * Modifies the current branch by amending commits or creating new ones.\n * Automatically restacks descendant branches to keep the stack valid.\n *\n * @param cwd - The working directory.\n * @param options - Modification options.\n * @throws {DubError} If the parent branch cannot be determined for rebase, or if no changes are staged when creating a new commit.\n */\nexport async function modify(\n\tcwd: string,\n\toptions: ModifyOptions,\n): Promise<void> {\n\tconst currentBranch = await getCurrentBranch(cwd);\n\tconst state = await readState(cwd);\n\n\tif (options.interactiveRebase) {\n\t\tconst parent = getParent(state, currentBranch);\n\t\tif (!parent) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Could not determine parent branch for '${currentBranch}'. Cannot start interactive rebase.`,\n\t\t\t);\n\t\t}\n\n\t\tconst parentTip = await getBranchTip(parent, cwd);\n\n\t\tconsole.log(`Starting interactive rebase on top of '${parent}'...`);\n\t\tawait interactiveRebase(parentTip, cwd);\n\n\t\tawait restackChildren(cwd);\n\t\treturn;\n\t}\n\n\tif (options.patch) {\n\t\tawait interactiveStage(cwd);\n\t} else if (options.all) {\n\t\tawait stageAll(cwd);\n\t} else if (options.update) {\n\t\tawait stageUpdate(cwd);\n\t}\n\n\tawait printVerboseDiff(cwd, options.verbose ?? 0);\n\n\tconst hasStaged = await hasStagedChanges(cwd);\n\tconst shouldCreateNew = options.commit;\n\tconst message = normalizeMessage(options.message);\n\tconst noEdit = !options.edit && !!message;\n\n\tif (shouldCreateNew) {\n\t\tif (!hasStaged) {\n\t\t\tthrow new DubError(\"No staged changes to commit.\");\n\t\t}\n\t\tawait commit(cwd, { message, noEdit: !options.edit });\n\t} else {\n\t\t// When amending, git commit --amend handles empty staged changes by allowing rewording\n\t\tawait amendCommit(cwd, { message, noEdit });\n\t}\n\n\tawait restackChildren(cwd);\n}\n\nfunction normalizeMessage(message?: string | string[]): string | undefined {\n\tif (Array.isArray(message)) {\n\t\tconst chunks = message.map((part) => part.trim()).filter(Boolean);\n\t\treturn chunks.length > 0 ? chunks.join(\"\\n\\n\") : undefined;\n\t}\n\treturn message;\n}\n\nasync function printVerboseDiff(cwd: string, level: number): Promise<void> {\n\tif (level < 1) return;\n\n\tconst staged = await getDiff(cwd, true);\n\tconsole.log(staged || \"(no staged diff)\");\n\n\tif (level > 1) {\n\t\tconst unstaged = await getDiff(cwd, false);\n\t\tconsole.log(unstaged || \"(no unstaged diff)\");\n\t}\n}\n\n/**\n * Trigger a restack of the stack to ensure children are rebased onto the new tip.\n *\n * @param cwd - The working directory.\n */\nasync function restackChildren(cwd: string): Promise<void> {\n\ttry {\n\t\tawait restack(cwd);\n\t} catch (e) {\n\t\tif (e instanceof DubError && e.message.includes(\"Conflict\")) {\n\t\t\tconsole.log(\n\t\t\t\t\"⚠ Modify successful, but auto-restacking encountered conflicts.\",\n\t\t\t);\n\t\t\tconsole.log(\" Run 'dub restack --continue' to resolve.\");\n\t\t} else {\n\t\t\tconsole.log(\"⚠ Modify successful, but auto-restacking failed.\");\n\t\t\tconsole.log(` ${e instanceof Error ? e.message : String(e)}`);\n\t\t}\n\t}\n}\n","#!/usr/bin/env node\n\n/**\n * DubStack CLI — manage stacked diffs with ease.\n *\n * A local-first tool for managing chains of dependent git branches\n * (stacked diffs) without manually dealing with complex rebase chains.\n *\n * @example\n * ```bash\n * dub init # Initialize in current repo\n * dub create feat/my-branch # Create stacked branch\n * dub log # View stack tree\n * dub restack # Rebase stack onto updated parent\n * dub undo # Undo last dub operation\n * ```\n *\n * @packageDocumentation\n */\n\nimport { createRequire } from \"node:module\";\nimport chalk from \"chalk\";\nimport { Command } from \"commander\";\nimport { abortCommand } from \"./commands/abort\";\nimport { branchInfo, formatBranchInfo } from \"./commands/branch\";\nimport {\n\tcheckout,\n\tinteractiveCheckout,\n\tresolveCheckoutTrunk,\n} from \"./commands/checkout\";\nimport { children } from \"./commands/children\";\nimport { continueCommand } from \"./commands/continue\";\nimport { create } from \"./commands/create\";\nimport { deleteCommand } from \"./commands/delete\";\nimport { init } from \"./commands/init\";\nimport { log } from \"./commands/log\";\nimport { bottom, downBySteps, top, upBySteps } from \"./commands/navigate\";\nimport { parent } from \"./commands/parent\";\nimport { pr } from \"./commands/pr\";\nimport { restack, restackContinue } from \"./commands/restack\";\nimport { submit } from \"./commands/submit\";\nimport { sync } from \"./commands/sync\";\nimport { track } from \"./commands/track\";\nimport { trunk } from \"./commands/trunk\";\nimport { undo } from \"./commands/undo\";\nimport { untrack } from \"./commands/untrack\";\nimport { DubError } from \"./lib/errors\";\n\nconst require = createRequire(import.meta.url);\nconst { version } = require(\"../package.json\") as { version: string };\n\nconst program = new Command();\n\nprogram\n\t.name(\"dub\")\n\t.description(\"Manage stacked diffs (dependent git branches) with ease\")\n\t.version(version);\n\nprogram\n\t.command(\"init\")\n\t.description(\"Initialize DubStack in the current git repository\")\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\nExamples:\n $ dub init Initialize DubStack, creating .git/dubstack/ and updating .gitignore`,\n\t)\n\t.action(async () => {\n\t\tconst result = await init(process.cwd());\n\t\tif (result.status === \"created\") {\n\t\t\tconsole.log(chalk.green(\"✔ DubStack initialized\"));\n\t\t} else {\n\t\t\tconsole.log(chalk.yellow(\"⚠ DubStack already initialized\"));\n\t\t}\n\t});\n\nprogram\n\t.command(\"create\")\n\t.argument(\"<branch-name>\", \"Name of the new branch to create\")\n\t.description(\"Create a new branch stacked on top of the current branch\")\n\t.option(\"-m, --message <message>\", \"Commit staged changes with this message\")\n\t.option(\"-a, --all\", \"Stage all changes before committing (requires -m)\")\n\t.option(\n\t\t\"-u, --update\",\n\t\t\"Stage tracked file updates before committing (requires -m)\",\n\t)\n\t.option(\"-p, --patch\", \"Pick hunks to stage before committing (requires -m)\")\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\nExamples:\n $ dub create feat/api Create branch only\n $ dub create feat/api -m \"feat: add API\" Create branch + commit staged\n $ dub create feat/api -am \"feat: add API\" Stage all + create + commit`,\n\t)\n\t.action(\n\t\tasync (\n\t\t\tbranchName: string,\n\t\t\toptions: {\n\t\t\t\tmessage?: string;\n\t\t\t\tall?: boolean;\n\t\t\t\tupdate?: boolean;\n\t\t\t\tpatch?: boolean;\n\t\t\t},\n\t\t) => {\n\t\t\tconst result = await create(branchName, process.cwd(), {\n\t\t\t\tmessage: options.message,\n\t\t\t\tall: options.all,\n\t\t\t\tupdate: options.update,\n\t\t\t\tpatch: options.patch,\n\t\t\t});\n\t\t\tif (result.committed) {\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.green(\n\t\t\t\t\t\t`✔ Created '${result.branch}' on '${result.parent}' • ${result.committed}`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.green(\n\t\t\t\t\t\t`✔ Created branch '${result.branch}' on top of '${result.parent}'`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t);\n\nprogram\n\t.command(\"log\")\n\t.alias(\"l\")\n\t.description(\"Display an ASCII tree of the current stack\")\n\t.option(\"-s, --stack\", \"Only show the current stack\")\n\t.option(\"-a, --all\", \"Show all stacks (default)\")\n\t.option(\"-r, --reverse\", \"Reverse stack/child ordering\")\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\nExamples:\n $ dub log Show the branch tree with current branch highlighted`,\n\t)\n\t.action(\n\t\tasync (options: { stack?: boolean; all?: boolean; reverse?: boolean }) => {\n\t\t\tawait printLog(process.cwd(), options);\n\t\t},\n\t);\n\nprogram\n\t.command(\"ls\")\n\t.description(\"Display an ASCII tree of the current stack\")\n\t.option(\"-s, --stack\", \"Only show the current stack\")\n\t.option(\"-a, --all\", \"Show all stacks (default)\")\n\t.option(\"-r, --reverse\", \"Reverse stack/child ordering\")\n\t.action(\n\t\tasync (options: { stack?: boolean; all?: boolean; reverse?: boolean }) => {\n\t\t\tawait printLog(process.cwd(), options);\n\t\t},\n\t);\n\nprogram\n\t.command(\"up\")\n\t.argument(\"[steps]\", \"Number of levels to traverse upstack\")\n\t.option(\"-n, --steps <count>\", \"Number of levels to traverse upstack\")\n\t.description(\"Checkout the child branch directly above the current branch\")\n\t.action(async (stepsArg: string | undefined, options: { steps?: string }) => {\n\t\tconst steps = parseSteps(stepsArg, options.steps);\n\t\tconst result = await upBySteps(process.cwd(), steps);\n\t\tif (result.changed) {\n\t\t\tconsole.log(chalk.green(`✔ Switched up to '${result.branch}'`));\n\t\t} else {\n\t\t\tconsole.log(chalk.yellow(`⚠ Already at top branch '${result.branch}'`));\n\t\t}\n\t});\n\nprogram\n\t.command(\"down\")\n\t.argument(\"[steps]\", \"Number of levels to traverse downstack\")\n\t.option(\"-n, --steps <count>\", \"Number of levels to traverse downstack\")\n\t.description(\"Checkout the parent branch directly below the current branch\")\n\t.action(async (stepsArg: string | undefined, options: { steps?: string }) => {\n\t\tconst steps = parseSteps(stepsArg, options.steps);\n\t\tconst result = await downBySteps(process.cwd(), steps);\n\t\tif (result.changed) {\n\t\t\tconsole.log(chalk.green(`✔ Switched down to '${result.branch}'`));\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\tchalk.yellow(`⚠ Already at bottom branch '${result.branch}'`),\n\t\t\t);\n\t\t}\n\t});\n\nprogram\n\t.command(\"top\")\n\t.description(\"Checkout the topmost branch in the current stack path\")\n\t.action(async () => {\n\t\tconst result = await top(process.cwd());\n\t\tif (result.changed) {\n\t\t\tconsole.log(chalk.green(`✔ Switched to top branch '${result.branch}'`));\n\t\t} else {\n\t\t\tconsole.log(chalk.yellow(`⚠ Already at top branch '${result.branch}'`));\n\t\t}\n\t});\n\nprogram\n\t.command(\"bottom\")\n\t.description(\n\t\t\"Checkout the first branch above the root in the current stack path\",\n\t)\n\t.action(async () => {\n\t\tconst result = await bottom(process.cwd());\n\t\tif (result.changed) {\n\t\t\tconsole.log(\n\t\t\t\tchalk.green(`✔ Switched to bottom stack branch '${result.branch}'`),\n\t\t\t);\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\tchalk.yellow(`⚠ Already at bottom stack branch '${result.branch}'`),\n\t\t\t);\n\t\t}\n\t});\n\nprogram\n\t.command(\"branch\")\n\t.description(\"Show DubStack branch metadata\")\n\t.addCommand(\n\t\tnew Command(\"info\")\n\t\t\t.description(\"Show tracked stack info for the current branch\")\n\t\t\t.argument(\"[branch]\", \"Branch to inspect (defaults to current branch)\")\n\t\t\t.action(async (branch?: string) => {\n\t\t\t\tconst info = await branchInfo(process.cwd(), branch);\n\t\t\t\tconsole.log(formatBranchInfo(info));\n\t\t\t}),\n\t);\n\nprogram\n\t.command(\"info\")\n\t.argument(\"[branch]\", \"Branch to inspect (defaults to current branch)\")\n\t.description(\"Show tracked stack info for a branch\")\n\t.action(async (branch?: string) => {\n\t\tconst info = await branchInfo(process.cwd(), branch);\n\t\tconsole.log(formatBranchInfo(info));\n\t});\n\nprogram\n\t.command(\"track\")\n\t.argument(\"[branch]\", \"Branch to track (defaults to current branch)\")\n\t.option(\"-p, --parent <branch>\", \"Parent branch for tracking\")\n\t.option(\n\t\t\"--no-interactive\",\n\t\t\"Disable parent prompt and require deterministic behavior\",\n\t)\n\t.description(\"Track a branch or update its parent relationship\")\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\nExamples:\n $ dub track\n $ dub track feat/a --parent main`,\n\t)\n\t.action(\n\t\tasync (\n\t\t\tbranch: string | undefined,\n\t\t\toptions: { parent?: string; interactive?: boolean },\n\t\t) => {\n\t\t\tconst result = await track(process.cwd(), branch, {\n\t\t\t\tparent: options.parent,\n\t\t\t\tinteractive: options.interactive,\n\t\t\t});\n\t\t\tif (result.status === \"tracked\") {\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.green(`✔ Tracking '${result.branch}' on '${result.parent}'`),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (result.status === \"reparented\") {\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.green(\n\t\t\t\t\t\t`✔ Re-parented '${result.branch}' onto '${result.parent}'`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.dim(\n\t\t\t\t\t\t\" Run 'dub restack' if descendant branches now need rebasing.\",\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconsole.log(\n\t\t\t\tchalk.yellow(\n\t\t\t\t\t`⚠ '${result.branch}' is already tracked on '${result.parent}'.`,\n\t\t\t\t),\n\t\t\t);\n\t\t},\n\t);\n\nprogram\n\t.command(\"untrack\")\n\t.argument(\"[branch]\", \"Branch to untrack (defaults to current branch)\")\n\t.option(\"--downstack\", \"Also untrack descendants recursively\")\n\t.option(\"--no-interactive\", \"Disable prompts and require explicit flags\")\n\t.description(\n\t\t\"Remove branch metadata from DubStack without deleting git branches\",\n\t)\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\nExamples:\n $ dub untrack\n $ dub untrack feat/a --downstack`,\n\t)\n\t.action(\n\t\tasync (\n\t\t\tbranch: string | undefined,\n\t\t\toptions: { downstack?: boolean; interactive?: boolean },\n\t\t) => {\n\t\t\tconst result = await untrack(process.cwd(), branch, {\n\t\t\t\tdownstack: options.downstack,\n\t\t\t\tinteractive: options.interactive,\n\t\t\t});\n\t\t\tconsole.log(\n\t\t\t\tchalk.green(\n\t\t\t\t\t`✔ Untracked ${result.removed.length} branch(es): ${result.removed.join(\", \")}`,\n\t\t\t\t),\n\t\t\t);\n\t\t\tfor (const entry of result.reparented) {\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.dim(\n\t\t\t\t\t\t` ↳ Re-parented '${entry.branch}' to '${entry.parent ?? \"(none)\"}'`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t);\n\nprogram\n\t.command(\"delete\")\n\t.argument(\"[branch]\", \"Branch to delete (defaults to current branch)\")\n\t.option(\"--upstack\", \"Also delete descendants of the target branch\")\n\t.option(\"--downstack\", \"Also delete ancestors toward trunk\")\n\t.option(\"-f, --force\", \"Delete branches even when not merged\")\n\t.option(\"-q, --quiet\", \"Skip confirmation prompts\")\n\t.option(\"--no-interactive\", \"Disable prompts and require explicit flags\")\n\t.description(\"Delete local branches and update DubStack metadata\")\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\nExamples:\n $ dub delete feat/a\n $ dub delete feat/a --upstack -f -q`,\n\t)\n\t.action(\n\t\tasync (\n\t\t\tbranch: string | undefined,\n\t\t\toptions: {\n\t\t\t\tupstack?: boolean;\n\t\t\t\tdownstack?: boolean;\n\t\t\t\tforce?: boolean;\n\t\t\t\tquiet?: boolean;\n\t\t\t\tinteractive?: boolean;\n\t\t\t},\n\t\t) => {\n\t\t\tconst result = await deleteCommand(process.cwd(), branch, {\n\t\t\t\tupstack: options.upstack,\n\t\t\t\tdownstack: options.downstack,\n\t\t\t\tforce: options.force,\n\t\t\t\tquiet: options.quiet,\n\t\t\t\tinteractive: options.interactive,\n\t\t\t});\n\t\t\tif (result.cancelled) {\n\t\t\t\tconsole.log(chalk.yellow(\"⚠ Delete cancelled.\"));\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconsole.log(\n\t\t\t\tchalk.green(\n\t\t\t\t\t`✔ Deleted ${result.deleted.length} branch(es): ${result.deleted.join(\", \")}`,\n\t\t\t\t),\n\t\t\t);\n\t\t\tfor (const entry of result.reparented) {\n\t\t\t\tconsole.log(\n\t\t\t\t\tchalk.dim(\n\t\t\t\t\t\t` ↳ Re-parented '${entry.branch}' to '${entry.parent ?? \"(none)\"}'`,\n\t\t\t\t\t),\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\t);\n\nprogram\n\t.command(\"parent\")\n\t.argument(\"[branch]\", \"Branch to inspect (defaults to current branch)\")\n\t.description(\"Show the direct parent branch\")\n\t.action(async (branch?: string) => {\n\t\tconst result = await parent(process.cwd(), branch);\n\t\tconsole.log(result.parent);\n\t});\n\nprogram\n\t.command(\"children\")\n\t.argument(\"[branch]\", \"Branch to inspect (defaults to current branch)\")\n\t.description(\"Show direct child branches\")\n\t.action(async (branch?: string) => {\n\t\tconst result = await children(process.cwd(), branch);\n\t\tif (result.children.length === 0) {\n\t\t\tconsole.log(\"(none)\");\n\t\t\treturn;\n\t\t}\n\t\tfor (const child of result.children) {\n\t\t\tconsole.log(child);\n\t\t}\n\t});\n\nprogram\n\t.command(\"trunk\")\n\t.argument(\"[branch]\", \"Branch to inspect (defaults to current branch)\")\n\t.description(\"Show trunk/root branch for the active stack\")\n\t.action(async (branch?: string) => {\n\t\tconst result = await trunk(process.cwd(), branch);\n\t\tconsole.log(result.trunk);\n\t});\n\nprogram\n\t.command(\"sync\")\n\t.description(\"Sync tracked branches with remote and reconcile divergence\")\n\t.option(\n\t\t\"--restack\",\n\t\t\"Restack branches after sync (disable with --no-restack)\",\n\t\ttrue,\n\t)\n\t.option(\"-f, --force\", \"Skip prompts for destructive sync decisions\")\n\t.option(\"-a, --all\", \"Sync all tracked stacks across trunks\")\n\t.option(\"--no-interactive\", \"Disable prompts and use deterministic behavior\")\n\t.action(\n\t\tasync (options: {\n\t\t\trestack?: boolean;\n\t\t\tforce?: boolean;\n\t\t\tall?: boolean;\n\t\t\tinteractive?: boolean;\n\t\t}) => {\n\t\t\tawait sync(process.cwd(), options);\n\t\t},\n\t);\n\nprogram\n\t.command(\"restack\")\n\t.description(\"Rebase all branches in the stack onto their updated parents\")\n\t.option(\"--continue\", \"Continue restacking after resolving conflicts\")\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\nExamples:\n $ dub restack Rebase the current stack\n $ dub restack --continue Continue after resolving conflicts`,\n\t)\n\t.action(async (options: { continue?: boolean }) => {\n\t\tconst result = options.continue\n\t\t\t? await restackContinue(process.cwd())\n\t\t\t: await restack(process.cwd());\n\n\t\tif (result.status === \"up-to-date\") {\n\t\t\tconsole.log(chalk.green(\"✔ Stack is already up to date\"));\n\t\t} else if (result.status === \"conflict\") {\n\t\t\tconsole.log(\n\t\t\t\tchalk.yellow(`⚠ Conflict while restacking '${result.conflictBranch}'`),\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\tchalk.dim(\n\t\t\t\t\t\" Resolve conflicts, stage changes, then run: dub restack --continue\",\n\t\t\t\t),\n\t\t\t);\n\t\t} else {\n\t\t\tconsole.log(\n\t\t\t\tchalk.green(`✔ Restacked ${result.rebased.length} branch(es)`),\n\t\t\t);\n\t\t\tfor (const branch of result.rebased) {\n\t\t\t\tconsole.log(chalk.dim(` ↳ ${branch}`));\n\t\t\t}\n\t\t}\n\t});\n\nprogram\n\t.command(\"continue\")\n\t.description(\"Continue the active restack or git rebase operation\")\n\t.action(async () => {\n\t\tconst result = await continueCommand(process.cwd());\n\t\tif (result.continued === \"rebase\") {\n\t\t\tconsole.log(chalk.green(\"✔ Continued git rebase.\"));\n\t\t\treturn;\n\t\t}\n\t\tif (result.restackResult?.status === \"conflict\") {\n\t\t\tconsole.log(\n\t\t\t\tchalk.yellow(\n\t\t\t\t\t`⚠ Conflict while restacking '${result.restackResult.conflictBranch}'`,\n\t\t\t\t),\n\t\t\t);\n\t\t\tconsole.log(\n\t\t\t\tchalk.dim(\" Resolve conflicts, stage changes, then run: dub continue\"),\n\t\t\t);\n\t\t\treturn;\n\t\t}\n\t\tif (result.restackResult?.status === \"up-to-date\") {\n\t\t\tconsole.log(chalk.green(\"✔ Stack is already up to date.\"));\n\t\t\treturn;\n\t\t}\n\t\tconsole.log(chalk.green(\"✔ Continued restack.\"));\n\t});\n\nprogram\n\t.command(\"abort\")\n\t.description(\"Abort the active restack or git rebase operation\")\n\t.action(async () => {\n\t\tconst result = await abortCommand(process.cwd());\n\t\tif (result.aborted === \"restack\") {\n\t\t\tconsole.log(chalk.green(\"✔ Aborted restack and cleared progress.\"));\n\t\t\treturn;\n\t\t}\n\t\tconsole.log(chalk.green(\"✔ Aborted git rebase.\"));\n\t});\n\nprogram\n\t.command(\"undo\")\n\t.description(\"Undo the last dub create or dub restack operation\")\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\nExamples:\n $ dub undo Roll back the last dub operation`,\n\t)\n\t.action(async () => {\n\t\tconst result = await undo(process.cwd());\n\t\tconsole.log(chalk.green(`✔ Undid '${result.undone}': ${result.details}`));\n\t});\n\nprogram\n\t.command(\"submit\")\n\t.description(\n\t\t\"Push branches and create/update GitHub PRs for the current stack\",\n\t)\n\t.option(\"--dry-run\", \"Print what would happen without executing\")\n\t.addHelpText(\n\t\t\"after\",\n\t\t`\nExamples:\n $ dub submit Push and create/update PRs\n $ dub submit --dry-run Preview what would happen`,\n\t)\n\t.action(runSubmit);\n\nprogram\n\t.command(\"ss\")\n\t.description(\"Submit the current stack (alias for submit)\")\n\t.option(\"--dry-run\", \"Print what would happen without executing\")\n\t.action(runSubmit);\n\nprogram\n\t.command(\"checkout\")\n\t.alias(\"co\")\n\t.argument(\"[branch]\", \"Branch to checkout (interactive if omitted)\")\n\t.option(\"-t, --trunk\", \"Checkout the current trunk\")\n\t.option(\n\t\t\"-u, --show-untracked\",\n\t\t\"Include untracked branches in interactive selection\",\n\t)\n\t.option(\n\t\t\"-s, --stack\",\n\t\t\"Only show ancestors and descendants of current branch in interactive selection\",\n\t)\n\t.option(\n\t\t\"-a, --all\",\n\t\t\"Show branches across all tracked stacks in interactive selection\",\n\t)\n\t.description(\"Checkout a branch (interactive picker if no name given)\")\n\t.action(\n\t\tasync (\n\t\t\tbranch: string | undefined,\n\t\t\toptions: {\n\t\t\t\ttrunk?: boolean;\n\t\t\t\tshowUntracked?: boolean;\n\t\t\t\tstack?: boolean;\n\t\t\t\tall?: boolean;\n\t\t\t},\n\t\t) => {\n\t\t\tif (branch) {\n\t\t\t\tconst result = await checkout(branch, process.cwd());\n\t\t\t\tconsole.log(chalk.green(`✔ Switched to '${result.branch}'`));\n\t\t\t} else if (options.trunk) {\n\t\t\t\tconst trunk = await resolveCheckoutTrunk(process.cwd());\n\t\t\t\tconst result = await checkout(trunk, process.cwd());\n\t\t\t\tconsole.log(chalk.green(`✔ Switched to '${result.branch}'`));\n\t\t\t} else {\n\t\t\t\tconst result = await interactiveCheckout(process.cwd(), {\n\t\t\t\t\tshowUntracked: options.showUntracked,\n\t\t\t\t\tstack: options.stack,\n\t\t\t\t\tall: options.all,\n\t\t\t\t});\n\t\t\t\tif (result) {\n\t\t\t\t\tconsole.log(chalk.green(`✔ Switched to '${result.branch}'`));\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t);\n\nprogram\n\t.command(\"skills\")\n\t.description(\"Manage DubStack agent skills\")\n\t.addCommand(\n\t\tnew Command(\"add\")\n\t\t\t.description(\"Install agent skills (e.g. dubstack, dub-flow)\")\n\t\t\t.argument(\"[skills...]\", \"Names of skills to install (default: all)\")\n\t\t\t.option(\"-g, --global\", \"Install skills globally\")\n\t\t\t.option(\"--dry-run\", \"Preview actions without installing\")\n\t\t\t.action(async (skills, options) => {\n\t\t\t\tconst { addSkills } = await import(\"./commands/skills\");\n\t\t\t\tawait addSkills(skills, options);\n\t\t\t}),\n\t)\n\t.addCommand(\n\t\tnew Command(\"remove\")\n\t\t\t.description(\"Remove agent skills\")\n\t\t\t.argument(\"[skills...]\", \"Names of skills to remove (default: all)\")\n\t\t\t.option(\"-g, --global\", \"Remove skills globally\")\n\t\t\t.option(\"--dry-run\", \"Preview actions without removing\")\n\t\t\t.action(async (skills, options) => {\n\t\t\t\tconst { removeSkills } = await import(\"./commands/skills\");\n\t\t\t\tawait removeSkills(skills, options);\n\t\t\t}),\n\t);\n\nprogram\n\t.command(\"modify\")\n\t.alias(\"m\")\n\t.description(\n\t\t\"Modify the current branch by amending commits or creating new ones\",\n\t)\n\t.option(\"-a, --all\", \"Stage all changes before committing\")\n\t.option(\"-c, --commit\", \"Create a new commit instead of amending\")\n\t.option(\"-e, --edit\", \"Open editor to edit the commit message\")\n\t.option(\n\t\t\"-m, --message <message>\",\n\t\t\"Message for the new or amended commit\",\n\t\t(value: string, previous: string[] = []) => [...previous, value],\n\t\t[],\n\t)\n\t.option(\"-p, --patch\", \"Pick hunks to stage before committing\")\n\t.option(\"-u, --update\", \"Stage all updates to tracked files\")\n\t.option(\n\t\t\"-v, --verbose\",\n\t\t\"Show staged diff before modify (repeat for unstaged diff too)\",\n\t\t(_value: unknown, previous = 0) => previous + 1,\n\t\t0,\n\t)\n\t.option(\n\t\t\"--interactive-rebase\",\n\t\t\"Start an interactive rebase on the branch commits\",\n\t)\n\t// .option(\"--into <branch>\", \"Amend staged changes to the specified branch\") // TODO: Implement --into\n\t// .option(\"--reset-author\", \"Set the author to the current user\") // TODO: Implement --reset-author\n\t// .option(\"-v, --verbose\", \"Show unified diff\") // TODO: Implement verbose\n\t.action(async (options) => {\n\t\tconst { modify } = await import(\"./commands/modify\");\n\t\tconst normalizedOptions = {\n\t\t\t...options,\n\t\t\tmessage:\n\t\t\t\tArray.isArray(options.message) && options.message.length === 1\n\t\t\t\t\t? options.message[0]\n\t\t\t\t\t: options.message,\n\t\t};\n\t\tawait modify(process.cwd(), normalizedOptions);\n\t});\n\nprogram\n\t.command(\"pr\")\n\t.argument(\"[branch]\", \"Branch name or PR number to open\")\n\t.description(\"Open a branch PR in your browser\")\n\t.action(async (branch?: string) => {\n\t\tawait pr(process.cwd(), branch);\n\t});\n\nasync function runSubmit(options: { dryRun?: boolean }) {\n\tconst result = await submit(process.cwd(), options.dryRun ?? false);\n\n\tif (result.pushed.length > 0) {\n\t\tconsole.log(\n\t\t\tchalk.green(\n\t\t\t\t`✔ Pushed ${result.pushed.length} branch(es), created ${result.created.length} PR(s), updated ${result.updated.length} PR(s)`,\n\t\t\t),\n\t\t);\n\t\tfor (const branch of [...result.created, ...result.updated]) {\n\t\t\tconsole.log(chalk.dim(` ↳ ${branch}`));\n\t\t}\n\t}\n}\n\nasync function printLog(\n\tcwd: string,\n\toptions: { stack?: boolean; all?: boolean; reverse?: boolean } = {},\n) {\n\tconst output = await log(cwd, options);\n\tconst styled = output\n\t\t.replace(/\\*(.+?) \\(Current\\)\\*/g, chalk.bold.cyan(\"$1 (Current)\"))\n\t\t.replace(/⚠ \\(missing\\)/g, chalk.yellow(\"⚠ (missing)\"));\n\tconsole.log(styled);\n}\n\nfunction parseSteps(positional?: string, option?: string): number {\n\tconst raw = option ?? positional;\n\tif (!raw) return 1;\n\tconst parsed = Number.parseInt(raw, 10);\n\tif (!Number.isInteger(parsed) || parsed < 1) {\n\t\tthrow new DubError(\"Steps must be a positive integer.\");\n\t}\n\treturn parsed;\n}\n\nasync function main() {\n\ttry {\n\t\tawait program.parseAsync(process.argv);\n\t} catch (error) {\n\t\tif (error instanceof DubError) {\n\t\t\tconsole.error(chalk.red(`✖ ${error.message}`));\n\t\t\tprocess.exit(1);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nmain();\n","import { DubError } from \"../lib/errors\";\nimport { rebaseAbort } from \"../lib/git\";\nimport {\n\tclearRestackProgress,\n\tdetectActiveOperation,\n\thasGitRebaseInProgress,\n} from \"../lib/operation-state\";\n\ninterface AbortCommandResult {\n\taborted: \"rebase\" | \"restack\";\n}\n\nexport async function abortCommand(cwd: string): Promise<AbortCommandResult> {\n\tconst active = await detectActiveOperation(cwd);\n\tif (active === \"none\") {\n\t\tthrow new DubError(\"No operation in progress. Nothing to abort.\");\n\t}\n\n\tif (await hasGitRebaseInProgress(cwd)) {\n\t\tawait rebaseAbort(cwd);\n\t}\n\tif (active === \"restack\") {\n\t\tawait clearRestackProgress(cwd);\n\t}\n\n\treturn { aborted: active };\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { getRepoRoot } from \"./git\";\nimport { getDubDir } from \"./state\";\n\nexport type ActiveOperation = \"none\" | \"rebase\" | \"restack\";\n\nexport async function getRestackProgressPath(cwd: string): Promise<string> {\n\tconst dubDir = await getDubDir(cwd);\n\treturn path.join(dubDir, \"restack-progress.json\");\n}\n\nexport async function hasRestackProgress(cwd: string): Promise<boolean> {\n\tconst progressPath = await getRestackProgressPath(cwd);\n\treturn fs.existsSync(progressPath);\n}\n\nexport async function hasGitRebaseInProgress(cwd: string): Promise<boolean> {\n\tconst root = await getRepoRoot(cwd);\n\tconst rebaseMerge = path.join(root, \".git\", \"rebase-merge\");\n\tconst rebaseApply = path.join(root, \".git\", \"rebase-apply\");\n\treturn fs.existsSync(rebaseMerge) || fs.existsSync(rebaseApply);\n}\n\nexport async function detectActiveOperation(\n\tcwd: string,\n): Promise<ActiveOperation> {\n\tif (await hasRestackProgress(cwd)) return \"restack\";\n\tif (await hasGitRebaseInProgress(cwd)) return \"rebase\";\n\treturn \"none\";\n}\n\nexport async function clearRestackProgress(cwd: string): Promise<void> {\n\tconst progressPath = await getRestackProgressPath(cwd);\n\tif (!fs.existsSync(progressPath)) return;\n\tfs.unlinkSync(progressPath);\n}\n","import { getCurrentBranch } from \"../lib/git\";\nimport { findStackForBranch, readState, type Stack } from \"../lib/state\";\n\nexport interface BranchInfoResult {\n\tcurrentBranch: string;\n\ttracked: boolean;\n\tstackId: string | null;\n\troot: string | null;\n\tparent: string | null;\n\tchildren: string[];\n}\n\nfunction findRootName(stack: Stack): string | null {\n\treturn stack.branches.find((branch) => branch.type === \"root\")?.name ?? null;\n}\n\nfunction getChildren(stack: Stack, branchName: string): string[] {\n\treturn stack.branches\n\t\t.filter((branch) => branch.parent === branchName)\n\t\t.map((branch) => branch.name)\n\t\t.sort();\n}\n\n/**\n * Returns tracked branch metadata for the current branch.\n */\nexport async function branchInfo(\n\tcwd: string,\n\tbranchName?: string,\n): Promise<BranchInfoResult> {\n\tconst state = await readState(cwd);\n\tconst resolvedBranch = branchName ?? (await getCurrentBranch(cwd));\n\tconst stack = findStackForBranch(state, resolvedBranch);\n\n\tif (!stack) {\n\t\treturn {\n\t\t\tcurrentBranch: resolvedBranch,\n\t\t\ttracked: false,\n\t\t\tstackId: null,\n\t\t\troot: null,\n\t\t\tparent: null,\n\t\t\tchildren: [],\n\t\t};\n\t}\n\n\tconst current = stack.branches.find(\n\t\t(branch) => branch.name === resolvedBranch,\n\t);\n\n\treturn {\n\t\tcurrentBranch: resolvedBranch,\n\t\ttracked: true,\n\t\tstackId: stack.id,\n\t\troot: findRootName(stack),\n\t\tparent: current?.parent ?? null,\n\t\tchildren: getChildren(stack, resolvedBranch),\n\t};\n}\n\n/**\n * Formats branch info in a human-readable layout.\n */\nexport function formatBranchInfo(info: BranchInfoResult): string {\n\tif (!info.tracked) {\n\t\treturn [\n\t\t\t`Branch: ${info.currentBranch}`,\n\t\t\t\"Tracked: no\",\n\t\t\t\"Status: not tracked by DubStack\",\n\t\t].join(\"\\n\");\n\t}\n\n\tconst childrenLabel =\n\t\tinfo.children.length > 0 ? info.children.join(\", \") : \"(none)\";\n\treturn [\n\t\t`Branch: ${info.currentBranch}`,\n\t\t\"Tracked: yes\",\n\t\t`Stack ID: ${info.stackId ?? \"(unknown)\"}`,\n\t\t`Root: ${info.root ?? \"(unknown)\"}`,\n\t\t`Parent: ${info.parent ?? \"(root)\"}`,\n\t\t`Children: ${childrenLabel}`,\n\t].join(\"\\n\");\n}\n","import search from \"@inquirer/search\";\nimport { DubError } from \"../lib/errors\";\nimport {\n\tbranchExists,\n\tcheckoutBranch,\n\tgetCurrentBranch,\n\tlistBranches,\n} from \"../lib/git\";\nimport { type DubState, findStackForBranch, readState } from \"../lib/state\";\n\n/**\n * Returns a sorted, deduplicated list of branch names tracked by DubStack.\n * Root branches that appear in multiple stacks are included only once.\n */\nexport function getTrackedBranches(state: DubState): string[] {\n\tconst names = new Set<string>();\n\tfor (const stack of state.stacks) {\n\t\tfor (const branch of stack.branches) {\n\t\t\tnames.add(branch.name);\n\t\t}\n\t}\n\treturn [...names].sort();\n}\n\n/**\n * Filters tracked branches against the list of actual local git branches.\n * Removes any branches that are tracked in state but have been deleted locally.\n */\nexport function getValidBranches(tracked: string[], local: string[]): string[] {\n\tconst localSet = new Set(local);\n\treturn tracked.filter((b) => localSet.has(b));\n}\n\n/**\n * Returns tracked branch names in the current stack (ancestors + descendants),\n * including the provided branch itself.\n */\nexport function getStackRelativeBranches(\n\tstate: DubState,\n\tbranchName: string,\n): string[] {\n\tconst stack = findStackForBranch(state, branchName);\n\tif (!stack) return [];\n\treturn [...new Set(stack.branches.map((branch) => branch.name))].sort();\n}\n\n/**\n * Resolves the current trunk branch for the active stack.\n * Falls back to local \"main\" or \"master\" if the current branch is untracked.\n */\nexport async function resolveCheckoutTrunk(cwd: string): Promise<string> {\n\tconst state = await readState(cwd);\n\tconst currentBranch = await getCurrentBranch(cwd);\n\tconst stack = findStackForBranch(state, currentBranch);\n\tconst trackedRoot =\n\t\tstack?.branches.find((branch) => branch.type === \"root\")?.name ?? null;\n\tif (trackedRoot) return trackedRoot;\n\tif (await branchExists(\"main\", cwd)) return \"main\";\n\tif (await branchExists(\"master\", cwd)) return \"master\";\n\tthrow new DubError(\n\t\t`Could not determine trunk branch for '${currentBranch}'.`,\n\t);\n}\n\n/**\n * Checks out the named branch.\n *\n * @param name - Branch to switch to\n * @param cwd - Working directory\n * @returns The checked-out branch name\n * @throws {DubError} If the branch does not exist\n */\nexport async function checkout(\n\tname: string,\n\tcwd: string,\n): Promise<{ branch: string }> {\n\tawait checkoutBranch(name, cwd);\n\treturn { branch: name };\n}\n\n/**\n * Launches an interactive search prompt listing DubStack-tracked branches.\n *\n * The current branch is shown but disabled. The user can type to filter,\n * use arrow keys to navigate, and press Enter to checkout.\n *\n * @param cwd - Working directory\n * @returns The checked-out branch, or `null` if the user cancelled (Ctrl+C)\n * @throws {DubError} If not initialized or no tracked branches exist\n */\nexport async function interactiveCheckout(\n\tcwd: string,\n\toptions: {\n\t\tshowUntracked?: boolean;\n\t\tstack?: boolean;\n\t\tall?: boolean;\n\t} = {},\n): Promise<{ branch: string } | null> {\n\tconst state = await readState(cwd);\n\tconst localBranches = await listBranches(cwd);\n\tconst currentBranch = await getCurrentBranch(cwd).catch(() => null);\n\tconst trackedBranches = getTrackedBranches(state);\n\tconst stackBranches = currentBranch\n\t\t? getStackRelativeBranches(state, currentBranch)\n\t\t: [];\n\n\tlet branchCandidates = options.showUntracked\n\t\t? [...new Set(localBranches)].sort()\n\t\t: getValidBranches(trackedBranches, localBranches);\n\n\tif (options.stack && stackBranches.length > 0) {\n\t\tconst stackSet = new Set(stackBranches);\n\t\tbranchCandidates = branchCandidates.filter((name) => stackSet.has(name));\n\t}\n\n\tconst validBranches = branchCandidates;\n\n\tif (validBranches.length === 0) {\n\t\tthrow new DubError(\n\t\t\t\"No valid tracked branches found. Run 'dub create' first.\",\n\t\t);\n\t}\n\n\t// Setup AbortController for Esc key support\n\tconst controller = new AbortController();\n\n\t// Listen for keypress events to handle Esc\n\tconst onKeypress = (_str: string, key: { name: string; ctrl: boolean }) => {\n\t\tif (key && key.name === \"escape\") {\n\t\t\tcontroller.abort();\n\t\t}\n\t};\n\tprocess.stdin.on(\"keypress\", onKeypress);\n\n\ttry {\n\t\tconst selected = await search(\n\t\t\t{\n\t\t\t\tmessage: \"Checkout a branch (autocomplete or arrow keys)\",\n\t\t\t\tsource(term: string | undefined) {\n\t\t\t\t\tconst filtered = term\n\t\t\t\t\t\t? validBranches.filter((b) =>\n\t\t\t\t\t\t\t\tb.toLowerCase().includes(term.toLowerCase()),\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t: validBranches;\n\n\t\t\t\t\treturn filtered.map((name) => ({\n\t\t\t\t\t\tname,\n\t\t\t\t\t\tvalue: name,\n\t\t\t\t\t\tdisabled: name === currentBranch ? \"(current)\" : false,\n\t\t\t\t\t}));\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ signal: controller.signal },\n\t\t);\n\n\t\treturn checkout(selected, cwd);\n\t} catch (error: unknown) {\n\t\tif (error instanceof Error) {\n\t\t\tif (\n\t\t\t\terror.name === \"ExitPromptError\" ||\n\t\t\t\terror.name === \"AbortError\" ||\n\t\t\t\terror.name === \"AbortPromptError\"\n\t\t\t) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\tthrow error;\n\t} finally {\n\t\tprocess.stdin.off(\"keypress\", onKeypress);\n\t}\n}\n","import { DubError } from \"../lib/errors\";\nimport { getCurrentBranch } from \"../lib/git\";\nimport { findStackForBranch, readState } from \"../lib/state\";\n\ninterface ChildrenResult {\n\tbranch: string;\n\tchildren: string[];\n}\n\nexport async function children(\n\tcwd: string,\n\tbranchArg?: string,\n): Promise<ChildrenResult> {\n\tconst branch = branchArg ?? (await getCurrentBranch(cwd));\n\tconst state = await readState(cwd);\n\tconst stack = findStackForBranch(state, branch);\n\tif (!stack) {\n\t\tthrow new DubError(\n\t\t\t`Branch '${branch}' is not tracked. Run 'dub track ${branch} --parent <branch>' first.`,\n\t\t);\n\t}\n\tconst childBranches = stack.branches\n\t\t.filter((entry) => entry.parent === branch)\n\t\t.map((entry) => entry.name)\n\t\t.sort();\n\treturn { branch, children: childBranches };\n}\n","import { DubError } from \"../lib/errors\";\nimport { rebaseContinue } from \"../lib/git\";\nimport { detectActiveOperation } from \"../lib/operation-state\";\nimport { restackContinue } from \"./restack\";\n\ninterface ContinueCommandResult {\n\tcontinued: \"rebase\" | \"restack\";\n\trestackResult?: Awaited<ReturnType<typeof restackContinue>>;\n}\n\nexport async function continueCommand(\n\tcwd: string,\n): Promise<ContinueCommandResult> {\n\tconst active = await detectActiveOperation(cwd);\n\tif (active === \"none\") {\n\t\tthrow new DubError(\n\t\t\t\"No operation in progress. Start a restack or resolve a rebase first.\",\n\t\t);\n\t}\n\n\tif (active === \"restack\") {\n\t\tconst restackResult = await restackContinue(cwd);\n\t\treturn { continued: \"restack\", restackResult };\n\t}\n\n\tawait rebaseContinue(cwd);\n\treturn { continued: \"rebase\" };\n}\n","import { DubError } from \"../lib/errors\";\nimport {\n\tbranchExists,\n\tcommitStaged,\n\tcreateBranch,\n\tgetCurrentBranch,\n\thasStagedChanges,\n\tinteractiveStage,\n\tstageAll,\n\tstageUpdate,\n} from \"../lib/git\";\nimport { addBranchToStack, ensureState, writeState } from \"../lib/state\";\nimport { saveUndoEntry } from \"../lib/undo-log\";\n\ninterface CreateOptions {\n\tmessage?: string;\n\tall?: boolean;\n\tupdate?: boolean;\n\tpatch?: boolean;\n}\n\ninterface CreateResult {\n\tbranch: string;\n\tparent: string;\n\tcommitted?: string;\n}\n\n/**\n * Creates a new branch stacked on top of the current branch.\n *\n * When `-m` is provided, also commits staged changes on the new branch.\n * When `-a` is provided, stages all changes first (requires `-m`).\n *\n * @param name - Name of the new branch to create\n * @param cwd - Working directory (auto-initializes if needed)\n * @param options - Optional message and all flags\n * @returns The created branch name, its parent, and committed message if applicable\n * @throws {DubError} If branch exists, HEAD is detached, -a without -m, or nothing to commit\n */\nexport async function create(\n\tname: string,\n\tcwd: string,\n\toptions?: CreateOptions,\n): Promise<CreateResult> {\n\tif ((options?.all || options?.update || options?.patch) && !options.message) {\n\t\tthrow new DubError(\n\t\t\t\"'--all', '--update', and '--patch' require '-m'. Pass a commit message.\",\n\t\t);\n\t}\n\n\tconst state = await ensureState(cwd);\n\tconst parent = await getCurrentBranch(cwd);\n\n\tif (await branchExists(name, cwd)) {\n\t\tthrow new DubError(`Branch '${name}' already exists.`);\n\t}\n\n\tif (options?.message) {\n\t\tif (options.patch) {\n\t\t\tawait interactiveStage(cwd);\n\t\t} else if (options.all) {\n\t\t\tawait stageAll(cwd);\n\t\t} else if (options.update) {\n\t\t\tawait stageUpdate(cwd);\n\t\t}\n\n\t\tif (!(await hasStagedChanges(cwd))) {\n\t\t\tconst hint = options.all\n\t\t\t\t? \"No changes to commit.\"\n\t\t\t\t: \"No staged changes. Stage files with 'git add' or use '-a' to stage all.\";\n\t\t\tthrow new DubError(hint);\n\t\t}\n\t}\n\n\tawait saveUndoEntry(\n\t\t{\n\t\t\toperation: \"create\",\n\t\t\ttimestamp: new Date().toISOString(),\n\t\t\tpreviousBranch: parent,\n\t\t\tpreviousState: structuredClone(state),\n\t\t\tbranchTips: {},\n\t\t\tcreatedBranches: [name],\n\t\t},\n\t\tcwd,\n\t);\n\n\tawait createBranch(name, cwd);\n\taddBranchToStack(state, name, parent);\n\tawait writeState(state, cwd);\n\n\tif (options?.message) {\n\t\ttry {\n\t\t\tawait commitStaged(options.message, cwd);\n\t\t} catch (error) {\n\t\t\tconst reason = error instanceof DubError ? error.message : String(error);\n\t\t\tthrow new DubError(\n\t\t\t\t`Branch '${name}' was created but commit failed: ${reason}. Run 'dub undo' to clean up.`,\n\t\t\t);\n\t\t}\n\t\treturn { branch: name, parent, committed: options.message };\n\t}\n\n\treturn { branch: name, parent };\n}\n","import { stdin as input, stdout as output } from \"node:process\";\nimport * as readline from \"node:readline/promises\";\nimport { deleteTrackedBranch, getDeletePreview } from \"../lib/delete\";\nimport { DubError } from \"../lib/errors\";\nimport { getCurrentBranch } from \"../lib/git\";\n\ninterface DeleteCommandOptions {\n\tupstack?: boolean;\n\tdownstack?: boolean;\n\tforce?: boolean;\n\tquiet?: boolean;\n\tinteractive?: boolean;\n}\n\ninterface DeleteCommandResult {\n\tdeleted: string[];\n\treparented: Array<{ branch: string; parent: string | null }>;\n\tcancelled?: boolean;\n}\n\nfunction isInteractiveShell(): boolean {\n\treturn Boolean(process.stdout.isTTY && process.stdin.isTTY);\n}\n\nasync function confirmDelete(targets: string[]): Promise<boolean> {\n\tconst rl = readline.createInterface({ input, output });\n\ttry {\n\t\tconst answer = await rl.question(\n\t\t\t`Delete ${targets.length} branch(es): ${targets.join(\", \")}? [y/N] `,\n\t\t);\n\t\tconst normalized = answer.trim().toLowerCase();\n\t\treturn normalized === \"y\" || normalized === \"yes\";\n\t} finally {\n\t\trl.close();\n\t}\n}\n\nexport async function deleteCommand(\n\tcwd: string,\n\tbranchArg?: string,\n\toptions: DeleteCommandOptions = {},\n): Promise<DeleteCommandResult> {\n\tconst branch = branchArg ?? (await getCurrentBranch(cwd));\n\tconst interactive = options.interactive ?? isInteractiveShell();\n\tconst preview = await getDeletePreview(cwd, {\n\t\tbranch,\n\t\tupstack: options.upstack,\n\t\tdownstack: options.downstack,\n\t});\n\n\tif (!options.force && !options.quiet) {\n\t\tif (!interactive) {\n\t\t\tthrow new DubError(\n\t\t\t\t\"Delete requires confirmation. Re-run with --force or interactively.\",\n\t\t\t);\n\t\t}\n\t\tconst confirmed = await confirmDelete(preview.targets);\n\t\tif (!confirmed) {\n\t\t\treturn { deleted: [], reparented: [], cancelled: true };\n\t\t}\n\t}\n\n\tconst result = await deleteTrackedBranch(cwd, {\n\t\tbranch,\n\t\tupstack: options.upstack ?? false,\n\t\tdownstack: options.downstack ?? false,\n\t\tforce: options.force ?? false,\n\t});\n\treturn { ...result, cancelled: false };\n}\n","import { DubError } from \"./errors\";\nimport { checkoutBranch, deleteLocalBranch, getCurrentBranch } from \"./git\";\nimport { getAncestors, getDescendants } from \"./graph\";\nimport { assertStateInvariants } from \"./invariants\";\nimport { findStackForBranch, readState, type Stack, writeState } from \"./state\";\n\nexport interface DeleteTrackedOptions {\n\tbranch: string;\n\tupstack?: boolean;\n\tdownstack?: boolean;\n\tforce?: boolean;\n}\n\nexport interface DeleteTrackedResult {\n\tdeleted: string[];\n\treparented: Array<{ branch: string; parent: string | null }>;\n}\n\nexport interface DeletePreview {\n\tbranch: string;\n\ttargets: string[];\n}\n\nexport async function getDeletePreview(\n\tcwd: string,\n\toptions: Pick<DeleteTrackedOptions, \"branch\" | \"upstack\" | \"downstack\">,\n): Promise<DeletePreview> {\n\tconst state = await readState(cwd);\n\tconst stack = findStackForBranch(state, options.branch);\n\tif (!stack) {\n\t\tthrow new DubError(\n\t\t\t`Branch '${options.branch}' is not tracked. Run 'dub track ${options.branch} --parent <branch>' first.`,\n\t\t);\n\t}\n\tconst targets = collectTargets(stack, options);\n\treturn { branch: options.branch, targets };\n}\n\n/**\n * Deletes tracked branches from git and removes them from DubStack metadata.\n */\nexport async function deleteTrackedBranch(\n\tcwd: string,\n\toptions: DeleteTrackedOptions,\n): Promise<DeleteTrackedResult> {\n\tconst state = await readState(cwd);\n\tconst stack = findStackForBranch(state, options.branch);\n\tif (!stack) {\n\t\tthrow new DubError(\n\t\t\t`Branch '${options.branch}' is not tracked by DubStack.`,\n\t\t);\n\t}\n\n\tconst targets = collectTargets(stack, options);\n\tconst deleteSet = new Set(targets);\n\n\tconst currentBranch = await getCurrentBranch(cwd);\n\tif (deleteSet.has(currentBranch)) {\n\t\tconst fallback = resolveFallbackBranch(stack, options.branch, deleteSet);\n\t\tawait checkoutBranch(fallback, cwd);\n\t}\n\n\tfor (const branch of targets) {\n\t\tawait deleteLocalBranch(branch, cwd, options.force ?? false);\n\t}\n\n\tconst deletedParent = new Map<string, string | null>();\n\tfor (const branch of stack.branches) {\n\t\tif (deleteSet.has(branch.name)) {\n\t\t\tdeletedParent.set(branch.name, branch.parent);\n\t\t}\n\t}\n\n\tstack.branches = stack.branches.filter(\n\t\t(branch) => !deleteSet.has(branch.name),\n\t);\n\n\tconst reparented: Array<{ branch: string; parent: string | null }> = [];\n\tfor (const branch of stack.branches) {\n\t\tlet parent = branch.parent;\n\t\twhile (parent && deleteSet.has(parent)) {\n\t\t\tparent = deletedParent.get(parent) ?? null;\n\t\t}\n\t\tif (parent !== branch.parent) {\n\t\t\tbranch.parent = parent;\n\t\t\treparented.push({ branch: branch.name, parent: branch.parent });\n\t\t}\n\t}\n\n\tstate.stacks = state.stacks.filter(\n\t\t(candidate) => candidate.branches.length > 0,\n\t);\n\tassertStateInvariants(state.stacks);\n\tawait writeState(state, cwd);\n\n\treturn {\n\t\tdeleted: targets,\n\t\treparented,\n\t};\n}\n\nfunction collectTargets(\n\tstack: Stack,\n\toptions: Pick<DeleteTrackedOptions, \"branch\" | \"upstack\" | \"downstack\">,\n): string[] {\n\tconst target = stack.branches.find(\n\t\t(branch) => branch.name === options.branch,\n\t);\n\tif (!target) {\n\t\tthrow new DubError(\n\t\t\t`Branch '${options.branch}' is missing from tracked stack.`,\n\t\t);\n\t}\n\tif (target.type === \"root\") {\n\t\tthrow new DubError(\n\t\t\t`Cannot delete root branch '${options.branch}' via dub delete.`,\n\t\t);\n\t}\n\n\tconst stackBranchMap = new Map(\n\t\tstack.branches.map((branch) => [branch.name, branch]),\n\t);\n\tconst targets = new Set<string>([options.branch]);\n\n\tif (options.upstack) {\n\t\tfor (const descendant of getDescendants(stack, options.branch)) {\n\t\t\ttargets.add(descendant);\n\t\t}\n\t}\n\tif (options.downstack) {\n\t\tfor (const ancestor of getAncestors(stack, options.branch)) {\n\t\t\tif (stackBranchMap.get(ancestor)?.type === \"root\") continue;\n\t\t\ttargets.add(ancestor);\n\t\t}\n\t}\n\n\treturn [...targets].sort(\n\t\t(a, b) => getAncestors(stack, b).length - getAncestors(stack, a).length,\n\t);\n}\n\nfunction resolveFallbackBranch(\n\tstack: Stack,\n\ttargetBranch: string,\n\tdeleteSet: Set<string>,\n): string {\n\tconst ancestors = getAncestors(stack, targetBranch);\n\tfor (const ancestor of ancestors) {\n\t\tif (!deleteSet.has(ancestor)) return ancestor;\n\t}\n\tconst root = stack.branches.find((branch) => branch.type === \"root\")?.name;\n\tif (root && !deleteSet.has(root)) return root;\n\tthrow new DubError(\n\t\t\"Unable to determine a safe checkout target before deleting current branch.\",\n\t);\n}\n","import { DubError } from \"./errors\";\nimport type { Branch, Stack } from \"./state\";\n\nfunction buildChildMap(stack: Stack): Map<string, Branch[]> {\n\tconst childMap = new Map<string, Branch[]>();\n\tfor (const branch of stack.branches) {\n\t\tif (!branch.parent) continue;\n\t\tconst children = childMap.get(branch.parent) ?? [];\n\t\tchildren.push(branch);\n\t\tchildMap.set(branch.parent, children);\n\t}\n\treturn childMap;\n}\n\nfunction buildBranchMap(stack: Stack): Map<string, Branch> {\n\treturn new Map(stack.branches.map((branch) => [branch.name, branch]));\n}\n\n/**\n * Returns descendants of a branch in breadth-first order.\n */\nexport function getDescendants(stack: Stack, branchName: string): string[] {\n\tconst childMap = buildChildMap(stack);\n\tconst descendants: string[] = [];\n\tconst queue = [...(childMap.get(branchName) ?? [])];\n\n\twhile (queue.length > 0) {\n\t\tconst next = queue.shift();\n\t\tif (!next) break;\n\t\tdescendants.push(next.name);\n\t\tqueue.push(...(childMap.get(next.name) ?? []));\n\t}\n\n\treturn descendants;\n}\n\n/**\n * Returns ancestors of a branch, starting at the immediate parent.\n */\nexport function getAncestors(stack: Stack, branchName: string): string[] {\n\tconst branchMap = buildBranchMap(stack);\n\tconst ancestors: string[] = [];\n\tconst seen = new Set<string>();\n\n\tlet current = branchMap.get(branchName);\n\twhile (current?.parent) {\n\t\tif (seen.has(current.parent)) break;\n\t\tancestors.push(current.parent);\n\t\tseen.add(current.parent);\n\t\tcurrent = branchMap.get(current.parent);\n\t}\n\n\treturn ancestors;\n}\n\n/**\n * Throws if a stack contains a cycle in parent pointers.\n */\nexport function assertAcyclic(stack: Stack): void {\n\tconst branchMap = buildBranchMap(stack);\n\tconst visiting = new Set<string>();\n\tconst visited = new Set<string>();\n\n\tfunction visit(name: string) {\n\t\tif (visited.has(name)) return;\n\t\tif (visiting.has(name)) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Invalid stack '${stack.id}': cycle detected at '${name}'.`,\n\t\t\t);\n\t\t}\n\n\t\tvisiting.add(name);\n\t\tconst branch = branchMap.get(name);\n\t\tif (branch?.parent && branchMap.has(branch.parent)) {\n\t\t\tvisit(branch.parent);\n\t\t}\n\t\tvisiting.delete(name);\n\t\tvisited.add(name);\n\t}\n\n\tfor (const branch of stack.branches) {\n\t\tvisit(branch.name);\n\t}\n}\n","import { DubError } from \"./errors\";\nimport { assertAcyclic } from \"./graph\";\nimport type { Stack } from \"./state\";\n\n/**\n * Ensures stack metadata invariants hold after state mutations.\n */\nexport function assertStateInvariants(stacks: Stack[]) {\n\tfor (const stack of stacks) {\n\t\tassertAcyclic(stack);\n\t\tconst branchMap = new Map(\n\t\t\tstack.branches.map((branch) => [branch.name, branch]),\n\t\t);\n\t\tfor (const branch of stack.branches) {\n\t\t\tif (branch.type === \"root\") {\n\t\t\t\tif (branch.parent !== null) {\n\t\t\t\t\tthrow new DubError(\n\t\t\t\t\t\t`Invalid stack '${stack.id}': root '${branch.name}' must have no parent.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tif (!branch.parent || !branchMap.has(branch.parent)) {\n\t\t\t\tthrow new DubError(\n\t\t\t\t\t`Invalid stack '${stack.id}': branch '${branch.name}' has missing parent '${branch.parent ?? \"null\"}'.`,\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n","import * as fs from \"node:fs\";\nimport * as path from \"node:path\";\nimport { DubError } from \"../lib/errors\";\nimport { getRepoRoot, isGitRepo } from \"../lib/git\";\nimport { initState } from \"../lib/state\";\n\ninterface InitResult {\n\tstatus: \"created\" | \"already_exists\";\n\tgitignoreUpdated: boolean;\n}\n\n/**\n * Initializes DubStack in the current git repository.\n *\n * Creates `.git/dubstack/state.json` with an empty state and ensures\n * `.git/dubstack` is listed in `.gitignore`. Idempotent — safe to run\n * multiple times.\n *\n * @param cwd - Working directory (must be inside a git repo)\n * @returns Status indicating whether state was created or already existed\n * @throws {DubError} If not inside a git repository\n */\nexport async function init(cwd: string): Promise<InitResult> {\n\tif (!(await isGitRepo(cwd))) {\n\t\tthrow new DubError(\n\t\t\t\"Not a git repository. Run this command inside a git repo.\",\n\t\t);\n\t}\n\n\tconst status = await initState(cwd);\n\tconst repoRoot = await getRepoRoot(cwd);\n\tconst gitignorePath = path.join(repoRoot, \".gitignore\");\n\tconst entry = \".git/dubstack\";\n\tlet gitignoreUpdated = false;\n\n\tif (fs.existsSync(gitignorePath)) {\n\t\tconst content = fs.readFileSync(gitignorePath, \"utf-8\");\n\t\tconst lines = content.split(\"\\n\");\n\t\tif (!lines.some((line) => line.trim() === entry)) {\n\t\t\tconst separator = content.endsWith(\"\\n\") ? \"\" : \"\\n\";\n\t\t\tfs.writeFileSync(gitignorePath, `${content}${separator}${entry}\\n`);\n\t\t\tgitignoreUpdated = true;\n\t\t}\n\t} else {\n\t\tfs.writeFileSync(gitignorePath, `${entry}\\n`);\n\t\tgitignoreUpdated = true;\n\t}\n\n\treturn { status, gitignoreUpdated };\n}\n","import { DubError } from \"../lib/errors\";\nimport { branchExists, getCurrentBranch } from \"../lib/git\";\nimport type { Branch, Stack } from \"../lib/state\";\nimport { findStackForBranch, readState } from \"../lib/state\";\n\ninterface LogOptions {\n\tstack?: boolean;\n\tall?: boolean;\n\treverse?: boolean;\n}\n\n/**\n * Renders an ASCII tree view of all tracked stacks.\n *\n * Highlights the current branch, marks branches missing from git,\n * and handles multiple stacks separated by blank lines.\n *\n * @param cwd - Working directory (must be inside an initialized dubstack repo)\n * @returns Formatted ASCII tree string (no ANSI colors — caller adds chalk)\n * @throws {DubError} If not initialized\n */\nexport async function log(\n\tcwd: string,\n\toptions: LogOptions = {},\n): Promise<string> {\n\tconst state = await readState(cwd);\n\n\tif (state.stacks.length === 0) {\n\t\treturn \"No stacks. Run 'dub create' to start.\";\n\t}\n\n\tlet currentBranch: string | null = null;\n\ttry {\n\t\tcurrentBranch = await getCurrentBranch(cwd);\n\t} catch {\n\t\t// Detached HEAD or empty repo — no branch highlighted\n\t}\n\n\tlet stacksToRender = state.stacks;\n\tif (options.stack && !options.all) {\n\t\tif (!currentBranch) {\n\t\t\tthrow new DubError(\n\t\t\t\t\"Cannot determine current branch for --stack mode. Checkout a branch first.\",\n\t\t\t);\n\t\t}\n\t\tconst currentStack = findStackForBranch(state, currentBranch);\n\t\tif (!currentStack) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Current branch '${currentBranch}' is not tracked. Run 'dub track ${currentBranch} --parent <branch>' first.`,\n\t\t\t);\n\t\t}\n\t\tstacksToRender = [currentStack];\n\t}\n\tif (options.reverse) {\n\t\tstacksToRender = [...stacksToRender].reverse();\n\t}\n\n\tconst sections: string[] = [];\n\n\tfor (const stack of stacksToRender) {\n\t\tconst tree = await renderStack(stack, currentBranch, cwd, options);\n\t\tsections.push(tree);\n\t}\n\n\treturn sections.join(\"\\n\\n\");\n}\n\nasync function renderStack(\n\tstack: Stack,\n\tcurrentBranch: string | null,\n\tcwd: string,\n\toptions: LogOptions,\n): Promise<string> {\n\tconst root = stack.branches.find((b) => b.type === \"root\");\n\tif (!root) return \"\";\n\n\tconst childMap = new Map<string, Branch[]>();\n\tfor (const branch of stack.branches) {\n\t\tif (branch.parent) {\n\t\t\tconst children = childMap.get(branch.parent) ?? [];\n\t\t\tchildren.push(branch);\n\t\t\tchildMap.set(branch.parent, children);\n\t\t}\n\t}\n\n\tconst lines: string[] = [];\n\tawait renderNode(\n\t\troot,\n\t\tcurrentBranch,\n\t\tchildMap,\n\t\t\"\",\n\t\ttrue,\n\t\ttrue,\n\t\tlines,\n\t\tcwd,\n\t\toptions,\n\t);\n\treturn lines.join(\"\\n\");\n}\n\nasync function renderNode(\n\tbranch: Branch,\n\tcurrentBranch: string | null,\n\tchildMap: Map<string, Branch[]>,\n\tprefix: string,\n\tisRoot: boolean,\n\tisLast: boolean,\n\tlines: string[],\n\tcwd: string,\n\toptions: LogOptions,\n): Promise<void> {\n\tlet label: string;\n\tconst exists = await branchExists(branch.name, cwd);\n\n\tif (isRoot) {\n\t\tlabel = `(${branch.name})`;\n\t} else if (branch.name === currentBranch) {\n\t\tlabel = `*${branch.name} (Current)*`;\n\t} else if (!exists) {\n\t\tlabel = `${branch.name} ⚠ (missing)`;\n\t} else {\n\t\tlabel = branch.name;\n\t}\n\n\tif (isRoot) {\n\t\tlines.push(label);\n\t} else {\n\t\tconst connector = isLast ? \"└─ \" : \"├─ \";\n\t\tlines.push(`${prefix}${connector}${label}`);\n\t}\n\n\tconst children = options.reverse\n\t\t? [...(childMap.get(branch.name) ?? [])].reverse()\n\t\t: (childMap.get(branch.name) ?? []);\n\tconst childPrefix = isRoot ? \" \" : `${prefix}${isLast ? \" \" : \"│ \"}`;\n\n\tfor (let i = 0; i < children.length; i++) {\n\t\tconst isChildLast = i === children.length - 1;\n\t\tawait renderNode(\n\t\t\tchildren[i],\n\t\t\tcurrentBranch,\n\t\t\tchildMap,\n\t\t\tchildPrefix,\n\t\t\tfalse,\n\t\t\tisChildLast,\n\t\t\tlines,\n\t\t\tcwd,\n\t\t\toptions,\n\t\t);\n\t}\n}\n","import { DubError } from \"../lib/errors\";\nimport { checkoutBranch, getCurrentBranch } from \"../lib/git\";\nimport { findStackForBranch, readState, type Stack } from \"../lib/state\";\n\ninterface NavigateResult {\n\tbranch: string;\n\tchanged: boolean;\n}\n\nfunction getBranchByName(stack: Stack, name: string) {\n\treturn stack.branches.find((branch) => branch.name === name);\n}\n\nfunction getChildren(stack: Stack, parent: string): string[] {\n\treturn stack.branches\n\t\t.filter((branch) => branch.parent === parent)\n\t\t.map((branch) => branch.name);\n}\n\nfunction getTrackedStackOrThrow(\n\tstateBranch: string,\n\tstack: Stack | undefined,\n): Stack {\n\tif (!stack) {\n\t\tthrow new DubError(\n\t\t\t`Current branch '${stateBranch}' is not tracked by DubStack.`,\n\t\t);\n\t}\n\treturn stack;\n}\n\n/**\n * Checkout the direct child branch of the current branch.\n * Requires a linear stack path.\n */\nexport async function up(cwd: string): Promise<NavigateResult> {\n\treturn upBySteps(cwd, 1);\n}\n\n/**\n * Checkout the child branch of the current branch by N steps.\n * Requires a linear stack path.\n */\nexport async function upBySteps(\n\tcwd: string,\n\tsteps: number,\n): Promise<NavigateResult> {\n\tif (!Number.isInteger(steps) || steps < 1) {\n\t\tthrow new DubError(\"'steps' must be a positive integer.\");\n\t}\n\n\tconst state = await readState(cwd);\n\tconst current = await getCurrentBranch(cwd);\n\tconst stack = getTrackedStackOrThrow(\n\t\tcurrent,\n\t\tfindStackForBranch(state, current),\n\t);\n\n\tlet target = current;\n\tfor (let i = 0; i < steps; i++) {\n\t\tconst children = getChildren(stack, target);\n\t\tif (children.length === 0) {\n\t\t\tthrow new DubError(`No branch above '${target}' in the current stack.`);\n\t\t}\n\t\tif (children.length > 1) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Branch '${target}' has multiple children; 'dub up' requires a linear stack path.`,\n\t\t\t);\n\t\t}\n\t\ttarget = children[0];\n\t}\n\n\tawait checkoutBranch(target, cwd);\n\treturn { branch: target, changed: target !== current };\n}\n\n/**\n * Checkout the direct parent branch of the current branch.\n */\nexport async function down(cwd: string): Promise<NavigateResult> {\n\treturn downBySteps(cwd, 1);\n}\n\n/**\n * Checkout the parent branch of the current branch by N steps.\n */\nexport async function downBySteps(\n\tcwd: string,\n\tsteps: number,\n): Promise<NavigateResult> {\n\tif (!Number.isInteger(steps) || steps < 1) {\n\t\tthrow new DubError(\"'steps' must be a positive integer.\");\n\t}\n\n\tconst state = await readState(cwd);\n\tconst current = await getCurrentBranch(cwd);\n\tconst stack = getTrackedStackOrThrow(\n\t\tcurrent,\n\t\tfindStackForBranch(state, current),\n\t);\n\tlet target = current;\n\tfor (let i = 0; i < steps; i++) {\n\t\tconst branch = getBranchByName(stack, target);\n\t\tif (!branch) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Current branch '${target}' is not tracked by DubStack.`,\n\t\t\t);\n\t\t}\n\t\tif (!branch.parent) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Already at the bottom of the stack (root branch '${target}').`,\n\t\t\t);\n\t\t}\n\t\ttarget = branch.parent;\n\t}\n\n\tawait checkoutBranch(target, cwd);\n\treturn { branch: target, changed: target !== current };\n}\n\n/**\n * Checkout the topmost descendant reachable by following a single-child path.\n */\nexport async function top(cwd: string): Promise<NavigateResult> {\n\tconst state = await readState(cwd);\n\tconst current = await getCurrentBranch(cwd);\n\tconst stack = getTrackedStackOrThrow(\n\t\tcurrent,\n\t\tfindStackForBranch(state, current),\n\t);\n\n\tlet target = current;\n\twhile (true) {\n\t\tconst children = getChildren(stack, target);\n\t\tif (children.length === 0) break;\n\t\tif (children.length > 1) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Branch '${target}' has multiple children; 'dub top' requires a linear stack path.`,\n\t\t\t);\n\t\t}\n\t\ttarget = children[0];\n\t}\n\n\tif (target !== current) {\n\t\tawait checkoutBranch(target, cwd);\n\t}\n\treturn { branch: target, changed: target !== current };\n}\n\n/**\n * Checkout the first branch above the root for the current stack path.\n */\nexport async function bottom(cwd: string): Promise<NavigateResult> {\n\tconst state = await readState(cwd);\n\tconst current = await getCurrentBranch(cwd);\n\tconst stack = getTrackedStackOrThrow(\n\t\tcurrent,\n\t\tfindStackForBranch(state, current),\n\t);\n\tconst branch = getBranchByName(stack, current);\n\n\tif (!branch) {\n\t\tthrow new DubError(\n\t\t\t`Current branch '${current}' is not tracked by DubStack.`,\n\t\t);\n\t}\n\n\tlet target = current;\n\tif (!branch.parent) {\n\t\tconst children = getChildren(stack, current);\n\t\tif (children.length === 0) {\n\t\t\tthrow new DubError(\n\t\t\t\t`No branch above root '${current}' in the current stack.`,\n\t\t\t);\n\t\t}\n\t\tif (children.length > 1) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Root branch '${current}' has multiple children; 'dub bottom' requires a linear stack path.`,\n\t\t\t);\n\t\t}\n\t\ttarget = children[0];\n\t} else {\n\t\tlet node = branch;\n\t\twhile (node.parent) {\n\t\t\tconst parent = getBranchByName(stack, node.parent);\n\t\t\tif (!parent) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (parent.parent === null) {\n\t\t\t\ttarget = node.name;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tnode = parent;\n\t\t}\n\t}\n\n\tif (target !== current) {\n\t\tawait checkoutBranch(target, cwd);\n\t}\n\treturn { branch: target, changed: target !== current };\n}\n","import { DubError } from \"../lib/errors\";\nimport { getCurrentBranch } from \"../lib/git\";\nimport { findStackForBranch, readState } from \"../lib/state\";\n\ninterface ParentResult {\n\tbranch: string;\n\tparent: string;\n}\n\nexport async function parent(\n\tcwd: string,\n\tbranchArg?: string,\n): Promise<ParentResult> {\n\tconst branch = branchArg ?? (await getCurrentBranch(cwd));\n\tconst state = await readState(cwd);\n\tconst stack = findStackForBranch(state, branch);\n\tif (!stack) {\n\t\tthrow new DubError(\n\t\t\t`Branch '${branch}' is not tracked. Run 'dub track ${branch} --parent <branch>' first.`,\n\t\t);\n\t}\n\tconst entry = stack.branches.find((candidate) => candidate.name === branch);\n\tif (!entry || !entry.parent) {\n\t\tthrow new DubError(`Branch '${branch}' is at the root and has no parent.`);\n\t}\n\treturn { branch, parent: entry.parent };\n}\n","import { execa } from \"execa\";\nimport { DubError } from \"./errors\";\n\n/** Details of a GitHub Pull Request. */\nexport interface PrInfo {\n\tnumber: number;\n\turl: string;\n\ttitle: string;\n\tbody: string;\n}\n\nexport type BranchPrLifecycleState = \"OPEN\" | \"CLOSED\" | \"MERGED\" | \"NONE\";\n\nexport interface BranchPrSyncInfo {\n\tstate: BranchPrLifecycleState;\n\tbaseRefName: string | null;\n}\n\n/**\n * Ensures the `gh` CLI is installed and available in PATH.\n * @throws {DubError} If `gh` is not found.\n */\nexport async function ensureGhInstalled(): Promise<void> {\n\ttry {\n\t\tawait execa(\"gh\", [\"--version\"]);\n\t} catch {\n\t\tthrow new DubError(\"gh CLI not found. Install it: https://cli.github.com\");\n\t}\n}\n\n/**\n * Ensures the user is authenticated with `gh`.\n * @throws {DubError} If not authenticated.\n */\nexport async function checkGhAuth(): Promise<void> {\n\ttry {\n\t\tawait execa(\"gh\", [\"auth\", \"status\"]);\n\t} catch {\n\t\tthrow new DubError(\"Not authenticated with GitHub. Run 'gh auth login'.\");\n\t}\n}\n\n/**\n * Fetches the open PR for a given head branch, if one exists.\n * @returns The PR info, or `null` if no open PR exists for that branch.\n */\nexport async function getPr(\n\tbranch: string,\n\tcwd: string,\n): Promise<PrInfo | null> {\n\tconst { stdout } = await execa(\n\t\t\"gh\",\n\t\t[\n\t\t\t\"pr\",\n\t\t\t\"list\",\n\t\t\t\"--head\",\n\t\t\tbranch,\n\t\t\t\"--state\",\n\t\t\t\"open\",\n\t\t\t\"--json\",\n\t\t\t\"number,url,title,body\",\n\t\t\t\"--jq\",\n\t\t\t\".[0]\",\n\t\t],\n\t\t{ cwd },\n\t);\n\n\tconst trimmed = stdout.trim();\n\tif (!trimmed || trimmed === \"null\") return null;\n\n\ttry {\n\t\treturn JSON.parse(trimmed) as PrInfo;\n\t} catch {\n\t\tthrow new DubError(`Failed to parse PR info for branch '${branch}'.`);\n\t}\n}\n\n/**\n * Returns coarse lifecycle state of a PR associated with the branch head.\n */\nexport async function getBranchPrLifecycleState(\n\tbranch: string,\n\tcwd: string,\n): Promise<BranchPrLifecycleState> {\n\tconst info = await getBranchPrSyncInfo(branch, cwd);\n\treturn info.state;\n}\n\n/**\n * Returns PR lifecycle and base branch information for sync decisions.\n */\nexport async function getBranchPrSyncInfo(\n\tbranch: string,\n\tcwd: string,\n): Promise<BranchPrSyncInfo> {\n\tconst { stdout } = await execa(\n\t\t\"gh\",\n\t\t[\n\t\t\t\"pr\",\n\t\t\t\"list\",\n\t\t\t\"--head\",\n\t\t\tbranch,\n\t\t\t\"--state\",\n\t\t\t\"all\",\n\t\t\t\"--json\",\n\t\t\t\"state,mergedAt,baseRefName\",\n\t\t\t\"--jq\",\n\t\t\t\".[0]\",\n\t\t],\n\t\t{ cwd },\n\t);\n\n\tconst trimmed = stdout.trim();\n\tif (!trimmed || trimmed === \"null\") {\n\t\treturn { state: \"NONE\", baseRefName: null };\n\t}\n\n\ttry {\n\t\tconst parsed = JSON.parse(trimmed) as {\n\t\t\tstate?: string;\n\t\t\tmergedAt?: string | null;\n\t\t\tbaseRefName?: string | null;\n\t\t};\n\t\tif (parsed.mergedAt) {\n\t\t\treturn {\n\t\t\t\tstate: \"MERGED\",\n\t\t\t\tbaseRefName: parsed.baseRefName ?? null,\n\t\t\t};\n\t\t}\n\t\tif (parsed.state === \"CLOSED\") {\n\t\t\treturn {\n\t\t\t\tstate: \"CLOSED\",\n\t\t\t\tbaseRefName: parsed.baseRefName ?? null,\n\t\t\t};\n\t\t}\n\t\tif (parsed.state === \"OPEN\") {\n\t\t\treturn {\n\t\t\t\tstate: \"OPEN\",\n\t\t\t\tbaseRefName: parsed.baseRefName ?? null,\n\t\t\t};\n\t\t}\n\t\treturn { state: \"NONE\", baseRefName: parsed.baseRefName ?? null };\n\t} catch {\n\t\tthrow new DubError(\n\t\t\t`Failed to parse PR lifecycle state for branch '${branch}'.`,\n\t\t);\n\t}\n}\n\n/**\n * Creates a new PR and returns its info.\n *\n * Parses the PR number from the URL printed to stdout by `gh pr create`,\n * avoiding an extra API round-trip.\n *\n * @param branch - Head branch\n * @param base - Base branch the PR merges into\n * @param title - PR title\n * @param bodyFile - Absolute path to a file containing the PR body\n */\nexport async function createPr(\n\tbranch: string,\n\tbase: string,\n\ttitle: string,\n\tbodyFile: string,\n\tcwd: string,\n): Promise<PrInfo> {\n\tlet stdout: string;\n\ttry {\n\t\tconst result = await execa(\n\t\t\t\"gh\",\n\t\t\t[\n\t\t\t\t\"pr\",\n\t\t\t\t\"create\",\n\t\t\t\t\"--head\",\n\t\t\t\tbranch,\n\t\t\t\t\"--base\",\n\t\t\t\tbase,\n\t\t\t\t\"--title\",\n\t\t\t\ttitle,\n\t\t\t\t\"--body-file\",\n\t\t\t\tbodyFile,\n\t\t\t],\n\t\t\t{ cwd },\n\t\t);\n\t\tstdout = result.stdout;\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (message.includes(\"403\") || message.includes(\"insufficient\")) {\n\t\t\tthrow new DubError(\n\t\t\t\t\"GitHub token lacks required permissions. Run 'gh auth login' with the 'repo' scope.\",\n\t\t\t);\n\t\t}\n\t\tthrow new DubError(`Failed to create PR for '${branch}': ${message}`);\n\t}\n\n\tconst url = stdout.trim();\n\tconst numberMatch = url.match(/\\/pull\\/(\\d+)$/);\n\tif (!numberMatch) {\n\t\tthrow new DubError(`Unexpected output from 'gh pr create': ${url}`);\n\t}\n\n\treturn {\n\t\tnumber: Number.parseInt(numberMatch[1], 10),\n\t\turl,\n\t\ttitle,\n\t\tbody: \"\",\n\t};\n}\n\n/**\n * Updates a PR's body using a file.\n * @param prNumber - The PR number to update\n * @param bodyFile - Absolute path to a file containing the new body\n */\nexport async function updatePrBody(\n\tprNumber: number,\n\tbodyFile: string,\n\tcwd: string,\n): Promise<void> {\n\ttry {\n\t\tawait execa(\n\t\t\t\"gh\",\n\t\t\t[\"pr\", \"edit\", String(prNumber), \"--body-file\", bodyFile],\n\t\t\t{ cwd },\n\t\t);\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (message.includes(\"403\") || message.includes(\"insufficient\")) {\n\t\t\tthrow new DubError(\n\t\t\t\t\"GitHub token lacks required permissions. Run 'gh auth login' with the 'repo' scope.\",\n\t\t\t);\n\t\t}\n\t\tthrow new DubError(`Failed to update PR #${prNumber}: ${message}`);\n\t}\n}\n\n/**\n * Opens a PR in the browser via GitHub CLI.\n *\n * @param cwd - Working directory\n * @param target - Optional branch name, PR number, or URL\n */\nexport async function openPrInBrowser(\n\tcwd: string,\n\ttarget?: string,\n): Promise<void> {\n\tconst args = target\n\t\t? [\"pr\", \"view\", target, \"--web\"]\n\t\t: [\"pr\", \"view\", \"--web\"];\n\ttry {\n\t\tawait execa(\"gh\", args, { cwd, stdio: \"inherit\" });\n\t} catch (error) {\n\t\tconst message = error instanceof Error ? error.message : String(error);\n\t\tif (message.toLowerCase().includes(\"no pull requests\")) {\n\t\t\tthrow new DubError(\n\t\t\t\ttarget\n\t\t\t\t\t? `No PR found for '${target}'.`\n\t\t\t\t\t: \"No PR found for the current branch.\",\n\t\t\t);\n\t\t}\n\t\tthrow new DubError(\n\t\t\ttarget\n\t\t\t\t? `Failed to open PR for '${target}': ${message}`\n\t\t\t\t: `Failed to open PR: ${message}`,\n\t\t);\n\t}\n}\n","import { checkGhAuth, ensureGhInstalled, openPrInBrowser } from \"../lib/github\";\n\nexport async function pr(cwd: string, branch?: string): Promise<void> {\n\tawait ensureGhInstalled();\n\tawait checkGhAuth();\n\tawait openPrInBrowser(cwd, branch);\n}\n","import * as fs from \"node:fs\";\nimport * as os from \"node:os\";\nimport * as path from \"node:path\";\nimport { DubError } from \"../lib/errors\";\nimport {\n\tgetBranchTip,\n\tgetCurrentBranch,\n\tgetLastCommitMessage,\n\tpushBranch,\n} from \"../lib/git\";\nimport {\n\tcheckGhAuth,\n\tcreatePr,\n\tensureGhInstalled,\n\tgetPr,\n\ttype PrInfo,\n\tupdatePrBody,\n} from \"../lib/github\";\nimport {\n\tbuildMetadataBlock,\n\tbuildStackTable,\n\tcomposePrBody,\n} from \"../lib/pr-body\";\nimport {\n\ttype Branch,\n\tfindStackForBranch,\n\treadState,\n\ttopologicalOrder,\n\twriteState,\n} from \"../lib/state\";\n\ninterface SubmitResult {\n\tpushed: string[];\n\tcreated: string[];\n\tupdated: string[];\n}\n\n/**\n * Pushes branches in the current stack and creates/updates GitHub PRs.\n *\n * @param cwd - Working directory\n * @param dryRun - If true, prints what would happen without executing\n * @throws {DubError} If not in a stack, on root branch, stack is non-linear, or gh errors\n */\nexport async function submit(\n\tcwd: string,\n\tdryRun: boolean,\n): Promise<SubmitResult> {\n\tawait ensureGhInstalled();\n\tawait checkGhAuth();\n\n\tconst state = await readState(cwd);\n\tconst currentBranch = await getCurrentBranch(cwd);\n\tconst stack = findStackForBranch(state, currentBranch);\n\n\tif (!stack) {\n\t\tthrow new DubError(\n\t\t\t`Branch '${currentBranch}' is not part of any stack. Run 'dub create' first.`,\n\t\t);\n\t}\n\n\tconst ordered = topologicalOrder(stack);\n\tconst currentEntry = ordered.find((b) => b.name === currentBranch);\n\tif (currentEntry?.type === \"root\") {\n\t\tthrow new DubError(\n\t\t\t\"Cannot submit from a root branch. Run 'dub up' or 'dub checkout <branch>' first.\",\n\t\t);\n\t}\n\n\tconst nonRootBranches = ordered.filter((b) => b.type !== \"root\");\n\tconst rootBranch =\n\t\tordered.find((branch) => branch.type === \"root\")?.name ?? \"(unknown)\";\n\tconsole.log(\n\t\t`Submitting ${nonRootBranches.length} branch(es) from '${currentBranch}' onto trunk '${rootBranch}'.`,\n\t);\n\tif (dryRun) {\n\t\tconsole.log(\"[dry-run] no branches will be pushed or mutated.\");\n\t}\n\n\tvalidateLinearStack(ordered);\n\n\tconst result: SubmitResult = { pushed: [], created: [], updated: [] };\n\tconst prMap = new Map<string, PrInfo>();\n\n\tfor (const branch of nonRootBranches) {\n\t\tif (dryRun) {\n\t\t\tconsole.log(`[dry-run] would push ${branch.name}`);\n\t\t} else {\n\t\t\tawait pushBranch(branch.name, cwd);\n\t\t}\n\t\tresult.pushed.push(branch.name);\n\t}\n\n\tfor (const branch of nonRootBranches) {\n\t\tconst base = branch.parent as string;\n\n\t\tif (dryRun) {\n\t\t\tconsole.log(`[dry-run] would check/create PR: ${branch.name} → ${base}`);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst existing = await getPr(branch.name, cwd);\n\t\tif (existing) {\n\t\t\tprMap.set(branch.name, existing);\n\t\t\tresult.updated.push(branch.name);\n\t\t} else {\n\t\t\tconst title = await getLastCommitMessage(branch.name, cwd);\n\t\t\tconst tmpFile = writeTempBody(\"\");\n\t\t\ttry {\n\t\t\t\tconst created = await createPr(branch.name, base, title, tmpFile, cwd);\n\t\t\t\tprMap.set(branch.name, created);\n\t\t\t\tresult.created.push(branch.name);\n\t\t\t} finally {\n\t\t\t\tcleanupTempFile(tmpFile);\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!dryRun) {\n\t\tawait updateAllPrBodies(nonRootBranches, prMap, stack.id, cwd);\n\n\t\tfor (const branch of nonRootBranches) {\n\t\t\tconst pr = prMap.get(branch.name);\n\t\t\tif (pr) {\n\t\t\t\tconst stateBranch = stack.branches.find((b) => b.name === branch.name);\n\t\t\t\tif (stateBranch) {\n\t\t\t\t\tstateBranch.pr_number = pr.number;\n\t\t\t\t\tstateBranch.pr_link = pr.url;\n\t\t\t\t\tconst headSha = await getBranchTip(branch.name, cwd);\n\t\t\t\t\tconst baseSha = await getBranchTip(branch.parent as string, cwd);\n\t\t\t\t\tstateBranch.last_submitted_version = {\n\t\t\t\t\t\thead_sha: headSha,\n\t\t\t\t\t\tbase_sha: baseSha,\n\t\t\t\t\t\tbase_branch: branch.parent as string,\n\t\t\t\t\t\tversion_number: null,\n\t\t\t\t\t\tsource: \"submit\",\n\t\t\t\t\t};\n\t\t\t\t\tstateBranch.last_synced_at = new Date().toISOString();\n\t\t\t\t\tstateBranch.sync_source = \"submit\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tawait writeState(state, cwd);\n\t}\n\n\treturn result;\n}\n\nfunction validateLinearStack(ordered: Branch[]): void {\n\tconst childCount = new Map<string, number>();\n\tfor (const branch of ordered) {\n\t\tif (branch.parent) {\n\t\t\tchildCount.set(branch.parent, (childCount.get(branch.parent) ?? 0) + 1);\n\t\t}\n\t}\n\tfor (const [parent, count] of childCount) {\n\t\tif (count > 1) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Branch '${parent}' has ${count} children. ` +\n\t\t\t\t\t\"Branching stacks are not supported by submit. \" +\n\t\t\t\t\t\"Ensure each branch has at most one child. \" +\n\t\t\t\t\t\"Use 'dub track <child> --parent <branch>' to re-parent branches and linearize the stack before submitting.\",\n\t\t\t);\n\t\t}\n\t}\n}\n\nasync function updateAllPrBodies(\n\tbranches: Branch[],\n\tprMap: Map<string, PrInfo>,\n\tstackId: string,\n\tcwd: string,\n): Promise<void> {\n\tconst tableEntries = new Map<string, { number: number; title: string }>();\n\tfor (const branch of branches) {\n\t\tconst pr = prMap.get(branch.name);\n\t\tif (pr) {\n\t\t\ttableEntries.set(branch.name, { number: pr.number, title: pr.title });\n\t\t}\n\t}\n\n\tfor (let i = 0; i < branches.length; i++) {\n\t\tconst branch = branches[i];\n\t\tconst pr = prMap.get(branch.name);\n\t\tif (!pr) continue;\n\n\t\tconst prevPr =\n\t\t\ti > 0 ? (prMap.get(branches[i - 1].name)?.number ?? null) : null;\n\t\tconst nextPr =\n\t\t\ti < branches.length - 1\n\t\t\t\t? (prMap.get(branches[i + 1].name)?.number ?? null)\n\t\t\t\t: null;\n\n\t\tconst stackTable = buildStackTable(branches, tableEntries, branch.name);\n\t\tconst metadataBlock = buildMetadataBlock(\n\t\t\tstackId,\n\t\t\tpr.number,\n\t\t\tprevPr,\n\t\t\tnextPr,\n\t\t\tbranch.name,\n\t\t);\n\n\t\tconst existingBody = pr.body;\n\t\tconst finalBody = composePrBody(existingBody, stackTable, metadataBlock);\n\n\t\tconst tmpFile = writeTempBody(finalBody);\n\t\ttry {\n\t\t\tawait updatePrBody(pr.number, tmpFile, cwd);\n\t\t} finally {\n\t\t\tcleanupTempFile(tmpFile);\n\t\t}\n\t}\n}\n\nfunction writeTempBody(content: string): string {\n\tconst tmpDir = os.tmpdir();\n\tconst tmpFile = path.join(tmpDir, `dubstack-body-${Date.now()}.md`);\n\tfs.writeFileSync(tmpFile, content);\n\treturn tmpFile;\n}\n\nfunction cleanupTempFile(filePath: string): void {\n\ttry {\n\t\tfs.unlinkSync(filePath);\n\t} catch {\n\t\t// Best-effort cleanup\n\t}\n}\n","import type { Branch } from \"./state\";\n\ninterface StackEntry {\n\tnumber: number;\n\ttitle: string;\n}\n\nconst DUBSTACK_START = \"<!-- dubstack:start -->\";\nconst DUBSTACK_END = \"<!-- dubstack:end -->\";\nconst METADATA_START = \"<!-- dubstack-metadata\";\nconst METADATA_END = \"-->\";\n\n/**\n * Builds the visible stack navigation table wrapped in dubstack markers.\n *\n * @param orderedBranches - Non-root branches in topological order\n * @param prMap - Map of branch name → PR number + title\n * @param currentBranch - The branch to mark with 👈\n */\nexport function buildStackTable(\n\torderedBranches: Branch[],\n\tprMap: Map<string, StackEntry>,\n\tcurrentBranch: string,\n): string {\n\tconst lines = orderedBranches.map((branch) => {\n\t\tconst entry = prMap.get(branch.name);\n\t\tif (!entry) return `- ${branch.name}`;\n\t\tconst marker = branch.name === currentBranch ? \" 👈\" : \"\";\n\t\treturn `- #${entry.number} ${entry.title}${marker}`;\n\t});\n\n\treturn [\n\t\tDUBSTACK_START,\n\t\t\"---\",\n\t\t\"### 🥞 DubStack\",\n\t\t...lines,\n\t\tDUBSTACK_END,\n\t].join(\"\\n\");\n}\n\n/**\n * Builds the hidden metadata HTML comment block.\n */\nexport function buildMetadataBlock(\n\tstackId: string,\n\tprNumber: number,\n\tprevPr: number | null,\n\tnextPr: number | null,\n\tbranch: string,\n): string {\n\tconst metadata = {\n\t\tstack_id: stackId,\n\t\tpr_number: prNumber,\n\t\tprev_pr: prevPr,\n\t\tnext_pr: nextPr,\n\t\tbranch,\n\t};\n\treturn `${METADATA_START}\\n${JSON.stringify(metadata, null, 2)}\\n${METADATA_END}`;\n}\n\n/**\n * Strips all DubStack-generated sections from a PR body.\n * Preserves user-written content. Returns body unchanged if no markers exist.\n */\nexport function stripDubstackSections(body: string): string {\n\tlet result = body;\n\n\tconst startIdx = result.indexOf(DUBSTACK_START);\n\tconst endIdx = result.indexOf(DUBSTACK_END);\n\tif (startIdx !== -1 && endIdx !== -1) {\n\t\tresult =\n\t\t\tresult.slice(0, startIdx) + result.slice(endIdx + DUBSTACK_END.length);\n\t}\n\n\tconst metaStart = result.indexOf(METADATA_START);\n\tif (metaStart !== -1) {\n\t\tconst metaEnd = result.indexOf(\n\t\t\tMETADATA_END,\n\t\t\tmetaStart + METADATA_START.length,\n\t\t);\n\t\tif (metaEnd !== -1) {\n\t\t\tresult =\n\t\t\t\tresult.slice(0, metaStart) +\n\t\t\t\tresult.slice(metaEnd + METADATA_END.length);\n\t\t}\n\t}\n\n\treturn result.trimEnd();\n}\n\n/**\n * Composes the final PR body by combining user content with DubStack sections.\n *\n * @param existingBody - The existing PR body (may contain stale DubStack sections)\n * @param stackTable - Output of `buildStackTable`\n * @param metadataBlock - Output of `buildMetadataBlock`\n */\nexport function composePrBody(\n\texistingBody: string,\n\tstackTable: string,\n\tmetadataBlock: string,\n): string {\n\tconst userContent = stripDubstackSections(existingBody);\n\tconst parts = [userContent, stackTable, metadataBlock].filter(Boolean);\n\treturn parts.join(\"\\n\\n\");\n}\n","import { stdin as input, stdout as output } from \"node:process\";\nimport * as readline from \"node:readline/promises\";\nimport { DubError } from \"../lib/errors\";\nimport {\n\tbranchExists,\n\tcheckoutBranch,\n\tcheckoutRemoteBranch,\n\tdeleteBranch,\n\tfastForwardBranchToRef,\n\tfetchBranches,\n\tgetCurrentBranch,\n\tgetRefSha,\n\thardResetBranchToRef,\n\tisAncestor,\n\trebaseBranchOntoRef,\n\tremoteBranchExists,\n} from \"../lib/git\";\nimport {\n\tcheckGhAuth,\n\tensureGhInstalled,\n\tgetBranchPrLifecycleState,\n\tgetBranchPrSyncInfo,\n} from \"../lib/github\";\nimport {\n\ttype Branch,\n\tfindStackForBranch,\n\treadState,\n\twriteState,\n} from \"../lib/state\";\nimport { classifyBranchSyncStatus } from \"../lib/sync/branch-status\";\nimport { buildCleanupPlan } from \"../lib/sync/cleanup\";\nimport { resolveReconcileDecision } from \"../lib/sync/reconcile\";\nimport { printBranchOutcome, printSyncSummary } from \"../lib/sync/report\";\nimport type {\n\tBranchSyncOutcome,\n\tSyncOptions,\n\tSyncResult,\n} from \"../lib/sync/types\";\nimport { restack } from \"./restack\";\n\nfunction isInteractiveShell(): boolean {\n\treturn Boolean(process.stdout.isTTY && process.stdin.isTTY);\n}\n\nasync function confirm(question: string): Promise<boolean> {\n\tconst rl = readline.createInterface({ input, output });\n\ttry {\n\t\tconst answer = await rl.question(`${question} [Y/n] `);\n\t\tconst normalized = answer.trim().toLowerCase();\n\t\treturn normalized === \"\" || normalized === \"y\" || normalized === \"yes\";\n\t} finally {\n\t\trl.close();\n\t}\n}\n\nasync function choose(\n\tquestion: string,\n\tchoices: Array<{ label: string; value: string }>,\n): Promise<string> {\n\tconst rl = readline.createInterface({ input, output });\n\ttry {\n\t\tconsole.log(question);\n\t\tfor (let i = 0; i < choices.length; i++) {\n\t\t\tconsole.log(` ${i + 1}. ${choices[i].label}`);\n\t\t}\n\t\tconst answer = await rl.question(\"Select option: \");\n\t\tconst idx = Number.parseInt(answer.trim(), 10) - 1;\n\t\tif (Number.isNaN(idx) || idx < 0 || idx >= choices.length) {\n\t\t\treturn choices[choices.length - 1].value;\n\t\t}\n\t\treturn choices[idx].value;\n\t} finally {\n\t\trl.close();\n\t}\n}\n\nexport async function sync(\n\tcwd: string,\n\trawOptions: {\n\t\trestack?: boolean;\n\t\tforce?: boolean;\n\t\tall?: boolean;\n\t\tinteractive?: boolean;\n\t} = {},\n): Promise<SyncResult> {\n\tawait ensureGhInstalled();\n\tawait checkGhAuth();\n\n\tconst options: SyncOptions = {\n\t\trestack: rawOptions.restack ?? true,\n\t\tforce: rawOptions.force ?? false,\n\t\tall: rawOptions.all ?? false,\n\t\tinteractive: rawOptions.interactive ?? isInteractiveShell(),\n\t};\n\n\tconst state = await readState(cwd);\n\tconst originalBranch = await getCurrentBranch(cwd);\n\n\tconst scopeStacks = options.all\n\t\t? state.stacks\n\t\t: (() => {\n\t\t\t\tconst stack = findStackForBranch(state, originalBranch);\n\t\t\t\tif (!stack) {\n\t\t\t\t\tthrow new DubError(\n\t\t\t\t\t\t`Branch '${originalBranch}' is not part of any stack. Run 'dub create' first.`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\treturn [stack];\n\t\t\t})();\n\tconst stateBranchMap = new Map<string, Branch>(\n\t\tscopeStacks.flatMap((stack) => stack.branches.map((b) => [b.name, b])),\n\t);\n\n\tconst roots = Array.from(\n\t\tnew Set(\n\t\t\tscopeStacks\n\t\t\t\t.flatMap((s) => s.branches)\n\t\t\t\t.filter((b) => b.type === \"root\")\n\t\t\t\t.map((b) => b.name),\n\t\t),\n\t);\n\tconst stackBranches = Array.from(\n\t\tnew Set(\n\t\t\tscopeStacks\n\t\t\t\t.flatMap((s) => s.branches)\n\t\t\t\t.filter((b) => b.type !== \"root\")\n\t\t\t\t.map((b) => b.name),\n\t\t),\n\t);\n\n\tconst result: SyncResult = {\n\t\tfetched: [],\n\t\ttrunksSynced: [],\n\t\tcleaned: [],\n\t\tbranches: [],\n\t\trestacked: false,\n\t};\n\tconst rootHasRemote = new Map<string, boolean>();\n\n\tconsole.log(\"🌲 Fetching branches from remote...\");\n\tconst toFetch = [...new Set([...roots, ...stackBranches])];\n\tif (toFetch.length > 0) {\n\t\tawait fetchBranches(toFetch, cwd);\n\t\tresult.fetched = toFetch;\n\t}\n\n\tfor (const root of roots) {\n\t\tconst remoteRef = `origin/${root}`;\n\t\tconst hasRemoteRoot = await remoteBranchExists(root, cwd);\n\t\trootHasRemote.set(root, hasRemoteRoot);\n\t\tif (!hasRemoteRoot) continue;\n\n\t\tconst ff = await fastForwardBranchToRef(root, remoteRef, cwd);\n\t\tif (ff) {\n\t\t\tresult.trunksSynced.push(root);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (options.force) {\n\t\t\tawait hardResetBranchToRef(root, remoteRef, cwd);\n\t\t\tresult.trunksSynced.push(root);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (options.interactive) {\n\t\t\tconst takeRemote = await confirm(\n\t\t\t\t`Trunk '${root}' cannot be fast-forwarded. Overwrite local trunk with '${remoteRef}'?`,\n\t\t\t);\n\t\t\tif (takeRemote) {\n\t\t\t\tawait hardResetBranchToRef(root, remoteRef, cwd);\n\t\t\t\tresult.trunksSynced.push(root);\n\t\t\t}\n\t\t}\n\t}\n\n\tconsole.log(\"🧹 Cleaning up branches with merged/closed PRs...\");\n\tconst localTrackedBranches: string[] = [];\n\tfor (const branch of stackBranches) {\n\t\tconst hasLocal = await branchExists(branch, cwd);\n\t\tif (hasLocal) localTrackedBranches.push(branch);\n\t}\n\tconst cleanupPlan = await buildCleanupPlan({\n\t\tbranches: localTrackedBranches,\n\t\tgetPrStatus: (branch) => getBranchPrLifecycleState(branch, cwd),\n\t\tisMergedIntoAnyRoot: async (branch) => {\n\t\t\tfor (const root of roots) {\n\t\t\t\tconst compareRef = rootHasRemote.get(root) ? `origin/${root}` : root;\n\t\t\t\tif (await isAncestor(branch, compareRef, cwd)) return true;\n\t\t\t}\n\t\t\treturn false;\n\t\t},\n\t});\n\tconst excludedFromSync = new Set<string>();\n\tfor (const skipped of cleanupPlan.skipped) {\n\t\tif (skipped.reason === \"commits-not-in-trunk\") {\n\t\t\texcludedFromSync.add(skipped.branch);\n\t\t\tfor (const child of getDescendants(scopeStacks, skipped.branch)) {\n\t\t\t\texcludedFromSync.add(child);\n\t\t\t}\n\t\t}\n\t}\n\tfor (const branch of cleanupPlan.toDelete) {\n\t\tif (excludedFromSync.has(branch)) continue;\n\t\tlet shouldDelete = options.force;\n\t\tif (!shouldDelete && options.interactive) {\n\t\t\tshouldDelete = await confirm(\n\t\t\t\t`Branch '${branch}' has merged/closed PR and is in trunk. Delete local branch?`,\n\t\t\t);\n\t\t}\n\t\tif (shouldDelete) {\n\t\t\tawait checkoutBranch(roots[0] ?? originalBranch, cwd);\n\t\t\tawait deleteBranch(branch, cwd);\n\t\t\tremoveBranchFromState(scopeStacks, branch);\n\t\t\tresult.cleaned.push(branch);\n\t\t}\n\t}\n\tfor (const skipped of cleanupPlan.skipped) {\n\t\tconsole.log(\n\t\t\t`• Skipped cleanup for '${skipped.branch}' (${skipped.reason}).`,\n\t\t);\n\t}\n\tfor (const excluded of excludedFromSync) {\n\t\tconsole.log(\n\t\t\t`• Excluding '${excluded}' from sync because its stack is not cleanable yet.`,\n\t\t);\n\t}\n\n\tconsole.log(\"🔄 Syncing branches...\");\n\tfor (const branch of stackBranches) {\n\t\tif (result.cleaned.includes(branch) || excludedFromSync.has(branch))\n\t\t\tcontinue;\n\n\t\tconst hasRemote = await remoteBranchExists(branch, cwd);\n\t\tconst hasLocal = await branchExists(branch, cwd);\n\t\tlet outcome: BranchSyncOutcome;\n\n\t\tconst remoteRef = `origin/${branch}`;\n\t\tconst localSha = hasLocal ? await getRefSha(branch, cwd) : null;\n\t\tconst remoteSha = hasRemote ? await getRefSha(remoteRef, cwd) : null;\n\t\tconst localBehind =\n\t\t\thasLocal && hasRemote ? await isAncestor(branch, remoteRef, cwd) : false;\n\t\tconst remoteBehind =\n\t\t\thasLocal && hasRemote ? await isAncestor(remoteRef, branch, cwd) : false;\n\t\tlet status = classifyBranchSyncStatus({\n\t\t\thasRemote,\n\t\t\thasLocal,\n\t\t\tlocalSha,\n\t\t\tremoteSha,\n\t\t\tlocalBehind,\n\t\t\tremoteBehind,\n\t\t\thasSubmittedBaseline:\n\t\t\t\tstateBranchMap.get(branch)?.last_submitted_version != null,\n\t\t});\n\t\tconst prSyncInfo = hasRemote\n\t\t\t? await getBranchPrSyncInfo(branch, cwd)\n\t\t\t: { state: \"NONE\" as const, baseRefName: null };\n\t\tconst localParent = stateBranchMap.get(branch)?.parent ?? null;\n\t\tif (\n\t\t\thasRemote &&\n\t\t\thasLocal &&\n\t\t\tlocalSha !== remoteSha &&\n\t\t\tprSyncInfo.baseRefName &&\n\t\t\tlocalParent &&\n\t\t\tprSyncInfo.baseRefName !== localParent\n\t\t) {\n\t\t\tstatus = \"needs-remote-sync\";\n\t\t}\n\n\t\tif (status === \"missing-remote\") {\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus,\n\t\t\t\taction: \"skipped\",\n\t\t\t\tmessage: `⚠ Skipped '${branch}' (missing on remote).`,\n\t\t\t};\n\t\t\tresult.branches.push(outcome);\n\t\t\tprintBranchOutcome(outcome);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (status === \"missing-local\") {\n\t\t\tawait checkoutRemoteBranch(branch, cwd);\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus,\n\t\t\t\taction: \"synced\",\n\t\t\t\tmessage: `✔ Restored '${branch}' from remote.`,\n\t\t\t};\n\t\t\tresult.branches.push(outcome);\n\t\t\tprintBranchOutcome(outcome);\n\t\t\tconst restoredSha = await getRefSha(branch, cwd);\n\t\t\tawait markBranchSynced(stateBranchMap, branch, restoredSha, cwd, {\n\t\t\t\tsource: \"sync\",\n\t\t\t\tbaseBranch: stateBranchMap.get(branch)?.parent ?? null,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (status === \"up-to-date\") {\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus,\n\t\t\t\taction: \"none\",\n\t\t\t\tmessage: `• '${branch}' is up to date.`,\n\t\t\t};\n\t\t\tresult.branches.push(outcome);\n\t\t\tprintBranchOutcome(outcome);\n\t\t\tawait markBranchSynced(\n\t\t\t\tstateBranchMap,\n\t\t\t\tbranch,\n\t\t\t\tlocalSha ?? remoteSha ?? null,\n\t\t\t\tcwd,\n\t\t\t\t{\n\t\t\t\t\tsource: \"sync\",\n\t\t\t\t\tbaseBranch: stateBranchMap.get(branch)?.parent ?? null,\n\t\t\t\t},\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (status === \"updated-outside-dubstack-but-up-to-date\") {\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus,\n\t\t\t\taction: \"none\",\n\t\t\t\tmessage: `• '${branch}' is up to date but was previously unmanaged by DubStack sync metadata.`,\n\t\t\t};\n\t\t\tresult.branches.push(outcome);\n\t\t\tprintBranchOutcome(outcome);\n\t\t\tawait markBranchSynced(\n\t\t\t\tstateBranchMap,\n\t\t\t\tbranch,\n\t\t\t\tlocalSha ?? remoteSha ?? null,\n\t\t\t\tcwd,\n\t\t\t\t{\n\t\t\t\t\tsource: \"imported\",\n\t\t\t\t\tbaseBranch: stateBranchMap.get(branch)?.parent ?? null,\n\t\t\t\t},\n\t\t\t);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (status === \"needs-remote-sync-safe\") {\n\t\t\tawait hardResetBranchToRef(branch, remoteRef, cwd);\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus,\n\t\t\t\taction: \"synced\",\n\t\t\t\tmessage: `✔ Synced '${branch}' to remote head.`,\n\t\t\t};\n\t\t\tresult.branches.push(outcome);\n\t\t\tprintBranchOutcome(outcome);\n\t\t\tawait markBranchSynced(stateBranchMap, branch, remoteSha, cwd, {\n\t\t\t\tsource: \"sync\",\n\t\t\t\tbaseBranch: stateBranchMap.get(branch)?.parent ?? null,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (status === \"local-ahead\") {\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus,\n\t\t\t\taction: \"kept-local\",\n\t\t\t\tmessage: `• Kept local '${branch}' (local commits ahead of remote).`,\n\t\t\t};\n\t\t\tresult.branches.push(outcome);\n\t\t\tprintBranchOutcome(outcome);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (status === \"unsubmitted\") {\n\t\t\tif (options.force) {\n\t\t\t\tawait hardResetBranchToRef(branch, remoteRef, cwd);\n\t\t\t\toutcome = {\n\t\t\t\t\tbranch,\n\t\t\t\t\tstatus,\n\t\t\t\t\taction: \"synced\",\n\t\t\t\t\tmessage: `✔ Synced unsubmitted branch '${branch}' to remote with --force.`,\n\t\t\t\t};\n\t\t\t\tawait markBranchSynced(stateBranchMap, branch, remoteSha, cwd, {\n\t\t\t\t\tsource: \"sync\",\n\t\t\t\t\tbaseBranch: localParent,\n\t\t\t\t});\n\t\t\t} else if (!options.interactive) {\n\t\t\t\toutcome = {\n\t\t\t\t\tbranch,\n\t\t\t\t\tstatus,\n\t\t\t\t\taction: \"skipped\",\n\t\t\t\t\tmessage: `⚠ Skipped unsubmitted branch '${branch}' (use --force or interactive mode).`,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tconst takeRemote = await confirm(\n\t\t\t\t\t`Branch '${branch}' has no DubStack submit baseline. Overwrite local with remote version?`,\n\t\t\t\t);\n\t\t\t\tif (takeRemote) {\n\t\t\t\t\tawait hardResetBranchToRef(branch, remoteRef, cwd);\n\t\t\t\t\toutcome = {\n\t\t\t\t\t\tbranch,\n\t\t\t\t\t\tstatus,\n\t\t\t\t\t\taction: \"synced\",\n\t\t\t\t\t\tmessage: `✔ Synced unsubmitted branch '${branch}' to remote.`,\n\t\t\t\t\t};\n\t\t\t\t\tawait markBranchSynced(stateBranchMap, branch, remoteSha, cwd, {\n\t\t\t\t\t\tsource: \"sync\",\n\t\t\t\t\t\tbaseBranch: localParent,\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\toutcome = {\n\t\t\t\t\t\tbranch,\n\t\t\t\t\t\tstatus,\n\t\t\t\t\t\taction: \"kept-local\",\n\t\t\t\t\t\tmessage: `• Kept local unsubmitted branch '${branch}'.`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\tresult.branches.push(outcome);\n\t\t\tprintBranchOutcome(outcome);\n\t\t\tcontinue;\n\t\t}\n\n\t\tif (status === \"needs-remote-sync\") {\n\t\t\tif (options.force) {\n\t\t\t\tawait hardResetBranchToRef(branch, remoteRef, cwd);\n\t\t\t\tif (prSyncInfo.baseRefName && localParent !== prSyncInfo.baseRefName) {\n\t\t\t\t\tconst stateBranch = stateBranchMap.get(branch);\n\t\t\t\t\tif (stateBranch) stateBranch.parent = prSyncInfo.baseRefName;\n\t\t\t\t}\n\t\t\t\toutcome = {\n\t\t\t\t\tbranch,\n\t\t\t\t\tstatus,\n\t\t\t\t\taction: \"synced\",\n\t\t\t\t\tmessage: `✔ Synced '${branch}' to remote and adopted remote parent '${prSyncInfo.baseRefName ?? \"unknown\"}'.`,\n\t\t\t\t};\n\t\t\t\tawait markBranchSynced(stateBranchMap, branch, remoteSha, cwd, {\n\t\t\t\t\tsource: \"sync\",\n\t\t\t\t\tbaseBranch: prSyncInfo.baseRefName ?? localParent,\n\t\t\t\t});\n\t\t\t} else if (!options.interactive) {\n\t\t\t\toutcome = {\n\t\t\t\t\tbranch,\n\t\t\t\t\tstatus,\n\t\t\t\t\taction: \"skipped\",\n\t\t\t\t\tmessage: `⚠ Skipped '${branch}' parent-mismatch sync (run interactively or with --force).`,\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tconst parentDecision = await choose(\n\t\t\t\t\t`Branch '${branch}' parent differs locally ('${localParent}') vs remote ('${prSyncInfo.baseRefName}').`,\n\t\t\t\t\t[\n\t\t\t\t\t\t{ label: \"Take remote version and remote parent\", value: \"remote\" },\n\t\t\t\t\t\t{ label: \"Keep local branch and parent\", value: \"local\" },\n\t\t\t\t\t\t{ label: \"Skip for now\", value: \"skip\" },\n\t\t\t\t\t],\n\t\t\t\t);\n\t\t\t\tif (parentDecision === \"remote\") {\n\t\t\t\t\tawait hardResetBranchToRef(branch, remoteRef, cwd);\n\t\t\t\t\tconst stateBranch = stateBranchMap.get(branch);\n\t\t\t\t\tif (stateBranch && prSyncInfo.baseRefName) {\n\t\t\t\t\t\tstateBranch.parent = prSyncInfo.baseRefName;\n\t\t\t\t\t}\n\t\t\t\t\toutcome = {\n\t\t\t\t\t\tbranch,\n\t\t\t\t\t\tstatus,\n\t\t\t\t\t\taction: \"synced\",\n\t\t\t\t\t\tmessage: `✔ Synced '${branch}' to remote and adopted remote parent.`,\n\t\t\t\t\t};\n\t\t\t\t\tawait markBranchSynced(stateBranchMap, branch, remoteSha, cwd, {\n\t\t\t\t\t\tsource: \"sync\",\n\t\t\t\t\t\tbaseBranch: prSyncInfo.baseRefName ?? localParent,\n\t\t\t\t\t});\n\t\t\t\t} else if (parentDecision === \"local\") {\n\t\t\t\t\toutcome = {\n\t\t\t\t\t\tbranch,\n\t\t\t\t\t\tstatus,\n\t\t\t\t\t\taction: \"kept-local\",\n\t\t\t\t\t\tmessage: `• Kept local parent and local state for '${branch}'.`,\n\t\t\t\t\t};\n\t\t\t\t} else {\n\t\t\t\t\toutcome = {\n\t\t\t\t\t\tbranch,\n\t\t\t\t\t\tstatus,\n\t\t\t\t\t\taction: \"skipped\",\n\t\t\t\t\t\tmessage: `⚠ Skipped '${branch}' parent-mismatch sync by user choice.`,\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\tresult.branches.push(outcome);\n\t\t\tprintBranchOutcome(outcome);\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst decision = await resolveReconcileDecision({\n\t\t\tbranch,\n\t\t\tforce: options.force,\n\t\t\tinteractive: options.interactive,\n\t\t\tpromptChoice: () =>\n\t\t\t\tchoose(\n\t\t\t\t\t`Branch '${branch}' diverged from remote. How should sync proceed?`,\n\t\t\t\t\t[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: \"Take remote version (discard local divergence)\",\n\t\t\t\t\t\t\tvalue: \"take-remote\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ label: \"Keep local version\", value: \"keep-local\" },\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tlabel: \"Attempt reconciliation and keep local commits\",\n\t\t\t\t\t\t\tvalue: \"reconcile\",\n\t\t\t\t\t\t},\n\t\t\t\t\t\t{ label: \"Skip this branch\", value: \"skip\" },\n\t\t\t\t\t],\n\t\t\t\t),\n\t\t});\n\n\t\tif (decision === \"take-remote\") {\n\t\t\tawait hardResetBranchToRef(branch, remoteRef, cwd);\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus: \"reconcile-needed\",\n\t\t\t\taction: \"synced\",\n\t\t\t\tmessage: `✔ Synced '${branch}' to remote version.`,\n\t\t\t};\n\t\t\tawait markBranchSynced(stateBranchMap, branch, remoteSha, cwd, {\n\t\t\t\tsource: \"sync\",\n\t\t\t\tbaseBranch: stateBranchMap.get(branch)?.parent ?? null,\n\t\t\t});\n\t\t} else if (decision === \"keep-local\") {\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus: \"reconcile-needed\",\n\t\t\t\taction: \"kept-local\",\n\t\t\t\tmessage: `• Kept local '${branch}' (remote divergence ignored).`,\n\t\t\t};\n\t\t} else if (decision === \"reconcile\") {\n\t\t\tconst reconciled = await rebaseBranchOntoRef(branch, remoteRef, cwd);\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus: \"reconcile-needed\",\n\t\t\t\taction: reconciled ? \"synced\" : \"kept-local\",\n\t\t\t\tmessage: reconciled\n\t\t\t\t\t? `✔ Reconciled '${branch}' by rebasing local commits onto remote.`\n\t\t\t\t\t: `⚠ Could not auto-reconcile '${branch}'. Kept local state; reconcile manually.`,\n\t\t\t};\n\t\t\tif (reconciled) {\n\t\t\t\tconst newSha = await getRefSha(branch, cwd);\n\t\t\t\tawait markBranchSynced(stateBranchMap, branch, newSha, cwd, {\n\t\t\t\t\tsource: \"sync\",\n\t\t\t\t\tbaseBranch: stateBranchMap.get(branch)?.parent ?? null,\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\toutcome = {\n\t\t\t\tbranch,\n\t\t\t\tstatus: \"reconcile-needed\",\n\t\t\t\taction: \"skipped\",\n\t\t\t\tmessage: options.interactive\n\t\t\t\t\t? `⚠ Skipped '${branch}' by user choice.`\n\t\t\t\t\t: `⚠ Skipped '${branch}' (diverged from remote; rerun with --force or interactive).`,\n\t\t\t};\n\t\t}\n\t\tresult.branches.push(outcome);\n\t\tprintBranchOutcome(outcome);\n\t}\n\n\tif (options.restack) {\n\t\tconsole.log(\"🥞 Restacking branches...\");\n\t\tconst rootsToRestack = options.all ? roots : [roots[0]].filter(Boolean);\n\t\tfor (const root of rootsToRestack) {\n\t\t\tawait checkoutBranch(root, cwd);\n\t\t\tawait restack(cwd);\n\t\t}\n\t\tresult.restacked = true;\n\t}\n\n\tawait writeState(state, cwd);\n\tawait checkoutBranch(originalBranch, cwd);\n\tprintSyncSummary(result);\n\treturn result;\n}\n\nasync function markBranchSynced(\n\tbranchMap: Map<string, Branch>,\n\tbranchName: string,\n\theadSha: string | null,\n\tcwd: string,\n\toptions: { source: \"sync\" | \"imported\"; baseBranch: string | null },\n): Promise<void> {\n\tif (!headSha) return;\n\tconst entry = branchMap.get(branchName);\n\tif (!entry) return;\n\tconst priorBaseline = entry.last_submitted_version;\n\tconst resolvedBaseBranch =\n\t\toptions.baseBranch ?? priorBaseline?.base_branch ?? null;\n\tlet resolvedBaseSha = priorBaseline?.base_sha ?? null;\n\tif (resolvedBaseBranch) {\n\t\ttry {\n\t\t\tresolvedBaseSha = await getRefSha(resolvedBaseBranch, cwd);\n\t\t} catch {\n\t\t\t// Keep existing baseline SHA if base ref isn't currently resolvable.\n\t\t}\n\t}\n\tif (!resolvedBaseBranch || !resolvedBaseSha) return;\n\tentry.last_submitted_version = {\n\t\thead_sha: headSha,\n\t\tbase_sha: resolvedBaseSha,\n\t\tbase_branch: resolvedBaseBranch,\n\t\tversion_number: priorBaseline?.version_number ?? null,\n\t\tsource: options.source,\n\t};\n\tentry.last_synced_at = new Date().toISOString();\n\tentry.sync_source = options.source;\n}\n\nfunction getDescendants(stacks: Array<{ branches: Branch[] }>, branch: string) {\n\tconst descendants: string[] = [];\n\tconst childMap = new Map<string, string[]>();\n\tfor (const stack of stacks) {\n\t\tfor (const node of stack.branches) {\n\t\t\tif (!node.parent) continue;\n\t\t\tconst children = childMap.get(node.parent) ?? [];\n\t\t\tchildren.push(node.name);\n\t\t\tchildMap.set(node.parent, children);\n\t\t}\n\t}\n\tconst queue = [...(childMap.get(branch) ?? [])];\n\twhile (queue.length > 0) {\n\t\tconst next = queue.shift();\n\t\tif (!next) break;\n\t\tdescendants.push(next);\n\t\tqueue.push(...(childMap.get(next) ?? []));\n\t}\n\treturn descendants;\n}\n\nfunction removeBranchFromState(\n\tstacks: Array<{ branches: Branch[] }>,\n\tbranch: string,\n) {\n\tfor (const stack of stacks) {\n\t\tconst deleted = stack.branches.find((b) => b.name === branch);\n\t\tif (!deleted) continue;\n\t\tconst newParent = deleted.parent;\n\t\tfor (const child of stack.branches) {\n\t\t\tif (child.parent === branch) {\n\t\t\t\tchild.parent = newParent;\n\t\t\t}\n\t\t}\n\t\tstack.branches = stack.branches.filter((b) => b.name !== branch);\n\t}\n}\n","import type { BranchSyncStatus } from \"./types\";\n\nexport function classifyBranchSyncStatus(input: {\n\thasRemote: boolean;\n\thasLocal: boolean;\n\tlocalSha: string | null;\n\tremoteSha: string | null;\n\tlocalBehind: boolean;\n\tremoteBehind: boolean;\n\thasSubmittedBaseline?: boolean;\n}): BranchSyncStatus {\n\tif (!input.hasRemote) return \"missing-remote\";\n\tif (!input.hasLocal) return \"missing-local\";\n\n\tif (input.localSha && input.remoteSha && input.localSha === input.remoteSha) {\n\t\tif (!input.hasSubmittedBaseline) {\n\t\t\treturn \"updated-outside-dubstack-but-up-to-date\";\n\t\t}\n\t\treturn \"up-to-date\";\n\t}\n\n\tif (!input.hasSubmittedBaseline) return \"unsubmitted\";\n\tif (input.localBehind) return \"needs-remote-sync-safe\";\n\tif (input.remoteBehind) return \"local-ahead\";\n\treturn \"reconcile-needed\";\n}\n","import type { BranchPrLifecycleState } from \"../github\";\n\nexport interface CleanupPlan {\n\ttoDelete: string[];\n\tskipped: Array<{ branch: string; reason: string }>;\n}\n\nexport async function buildCleanupPlan(input: {\n\tbranches: string[];\n\tgetPrStatus: (branch: string) => Promise<BranchPrLifecycleState>;\n\tisMergedIntoAnyRoot: (branch: string) => Promise<boolean>;\n}): Promise<CleanupPlan> {\n\tconst toDelete: string[] = [];\n\tconst skipped: Array<{ branch: string; reason: string }> = [];\n\n\tfor (const branch of input.branches) {\n\t\tconst prState = await input.getPrStatus(branch);\n\t\tif (prState !== \"MERGED\" && prState !== \"CLOSED\") {\n\t\t\tcontinue;\n\t\t}\n\n\t\tconst mergedIntoRoot = await input.isMergedIntoAnyRoot(branch);\n\t\tif (!mergedIntoRoot) {\n\t\t\tskipped.push({ branch, reason: \"commits-not-in-trunk\" });\n\t\t\tcontinue;\n\t\t}\n\n\t\ttoDelete.push(branch);\n\t}\n\n\treturn { toDelete, skipped };\n}\n","export type ReconcileDecision =\n\t| \"take-remote\"\n\t| \"keep-local\"\n\t| \"reconcile\"\n\t| \"skip\";\n\nexport async function resolveReconcileDecision(input: {\n\tbranch: string;\n\tforce: boolean;\n\tinteractive: boolean;\n\tpromptChoice: () => Promise<string>;\n}): Promise<ReconcileDecision> {\n\tif (input.force) return \"take-remote\";\n\tif (!input.interactive) return \"skip\";\n\n\tconst raw = await input.promptChoice();\n\tif (\n\t\traw === \"take-remote\" ||\n\t\traw === \"keep-local\" ||\n\t\traw === \"reconcile\" ||\n\t\traw === \"skip\"\n\t) {\n\t\treturn raw;\n\t}\n\treturn \"skip\";\n}\n","import type { BranchSyncOutcome, SyncResult } from \"./types\";\n\nexport function printBranchOutcome(outcome: BranchSyncOutcome): void {\n\tconsole.log(outcome.message);\n}\n\nexport function printSyncSummary(result: SyncResult): void {\n\tconst synced = result.branches.filter((b) => b.action === \"synced\").length;\n\tconst skipped = result.branches.filter((b) => b.action === \"skipped\").length;\n\tconst keptLocal = result.branches.filter(\n\t\t(b) => b.action === \"kept-local\",\n\t).length;\n\tconsole.log(\n\t\t`✔ Sync complete: ${synced} synced, ${keptLocal} kept-local, ${skipped} skipped, ${result.cleaned.length} cleaned`,\n\t);\n}\n","import { stdin as input, stdout as output } from \"node:process\";\nimport * as readline from \"node:readline/promises\";\nimport { DubError } from \"../lib/errors\";\nimport { branchExists, getCurrentBranch } from \"../lib/git\";\nimport { type TrackBranchResult, trackBranch } from \"../lib/track\";\n\ninterface TrackOptions {\n\tparent?: string;\n\tinteractive?: boolean;\n}\n\nfunction isInteractiveShell(): boolean {\n\treturn Boolean(process.stdout.isTTY && process.stdin.isTTY);\n}\n\nasync function promptForParent(\n\tbranch: string,\n\tsuggestedParent: string | null,\n): Promise<string> {\n\tconst rl = readline.createInterface({ input, output });\n\ttry {\n\t\tconst suffix = suggestedParent ? ` [${suggestedParent}]` : \"\";\n\t\tconst answer = await rl.question(\n\t\t\t`Parent branch for '${branch}'${suffix}: `,\n\t\t);\n\t\tconst parent = answer.trim() || suggestedParent;\n\t\tif (!parent) {\n\t\t\tthrow new DubError(\n\t\t\t\t`No parent selected for '${branch}'. Re-run with --parent <branch>.`,\n\t\t\t);\n\t\t}\n\t\treturn parent;\n\t} finally {\n\t\trl.close();\n\t}\n}\n\nasync function resolveSuggestedParent(\n\tcwd: string,\n\tbranch: string,\n\tcurrentBranch: string,\n): Promise<string | null> {\n\tif (currentBranch !== branch) return currentBranch;\n\tif (await branchExists(\"main\", cwd)) return \"main\";\n\tif (await branchExists(\"master\", cwd)) return \"master\";\n\treturn null;\n}\n\n/**\n * Tracks a branch or re-parents an already tracked branch.\n */\nexport async function track(\n\tcwd: string,\n\tbranchArg?: string,\n\toptions: TrackOptions = {},\n): Promise<TrackBranchResult> {\n\tconst currentBranch = await getCurrentBranch(cwd);\n\tconst branch = branchArg ?? currentBranch;\n\tconst interactive = options.interactive ?? isInteractiveShell();\n\n\tlet parent = options.parent;\n\tif (!parent) {\n\t\tconst suggestedParent = await resolveSuggestedParent(\n\t\t\tcwd,\n\t\t\tbranch,\n\t\t\tcurrentBranch,\n\t\t);\n\t\tif (interactive) {\n\t\t\tparent = await promptForParent(branch, suggestedParent);\n\t\t} else if (suggestedParent) {\n\t\t\tparent = suggestedParent;\n\t\t}\n\t}\n\n\tif (!parent) {\n\t\tthrow new DubError(\n\t\t\t`Could not infer parent for '${branch}'. Re-run with --parent <branch>.`,\n\t\t);\n\t}\n\n\treturn trackBranch(cwd, { branch, parent });\n}\n","import * as crypto from \"node:crypto\";\nimport { DubError } from \"./errors\";\nimport { branchExists } from \"./git\";\nimport { getDescendants } from \"./graph\";\nimport { assertStateInvariants } from \"./invariants\";\nimport {\n\taddBranchToStack,\n\tensureState,\n\tfindStackForBranch,\n\twriteState,\n} from \"./state\";\n\nexport interface TrackBranchOptions {\n\tbranch: string;\n\tparent: string;\n}\n\nexport interface TrackBranchResult {\n\tbranch: string;\n\tparent: string;\n\tstatus: \"tracked\" | \"reparented\" | \"unchanged\";\n}\n\nexport async function validateTrackParent(\n\tcwd: string,\n\tbranch: string,\n\tparent: string,\n): Promise<void> {\n\tif (branch === parent) {\n\t\tthrow new DubError(\"Branch cannot be its own parent.\");\n\t}\n\tif (!(await branchExists(parent, cwd))) {\n\t\tthrow new DubError(`Parent branch '${parent}' does not exist locally.`);\n\t}\n}\n\n/**\n * Tracks an existing local branch or updates its parent relationship.\n */\nexport async function trackBranch(\n\tcwd: string,\n\toptions: TrackBranchOptions,\n): Promise<TrackBranchResult> {\n\tconst { branch, parent } = options;\n\tif (!(await branchExists(branch, cwd))) {\n\t\tthrow new DubError(`Branch '${branch}' does not exist locally.`);\n\t}\n\tawait validateTrackParent(cwd, branch, parent);\n\n\tconst state = await ensureState(cwd);\n\tconst sourceStack = findStackForBranch(state, branch);\n\tconst destinationStack = findStackForBranch(state, parent);\n\n\tif (!sourceStack) {\n\t\taddBranchToStack(state, branch, parent);\n\t\tassertStateInvariants(state.stacks);\n\t\tawait writeState(state, cwd);\n\t\treturn { branch, parent, status: \"tracked\" };\n\t}\n\n\tconst branchEntry = sourceStack.branches.find(\n\t\t(entry) => entry.name === branch,\n\t);\n\tif (!branchEntry) {\n\t\tthrow new DubError(`Branch '${branch}' is missing from tracked state.`);\n\t}\n\tif (branchEntry.type === \"root\") {\n\t\tthrow new DubError(\n\t\t\t`Branch '${branch}' is a stack root and cannot be re-parented.`,\n\t\t);\n\t}\n\tif (branchEntry.parent === parent) {\n\t\treturn { branch, parent, status: \"unchanged\" };\n\t}\n\n\tconst descendants = new Set(getDescendants(sourceStack, branch));\n\tif (descendants.has(parent)) {\n\t\tthrow new DubError(\n\t\t\t`Cannot track '${branch}' onto '${parent}' because it would create a cycle.`,\n\t\t);\n\t}\n\n\tif (sourceStack.id === destinationStack?.id) {\n\t\tbranchEntry.parent = parent;\n\t\tassertStateInvariants(state.stacks);\n\t\tawait writeState(state, cwd);\n\t\treturn { branch, parent, status: \"reparented\" };\n\t}\n\n\tconst movingNames = new Set([branch, ...descendants]);\n\tconst movingBranches = sourceStack.branches.filter((entry) =>\n\t\tmovingNames.has(entry.name),\n\t);\n\tsourceStack.branches = sourceStack.branches.filter(\n\t\t(entry) => !movingNames.has(entry.name),\n\t);\n\n\tconst movingRoot = movingBranches.find((entry) => entry.name === branch);\n\tif (!movingRoot) {\n\t\tthrow new DubError(`Failed to move subtree for '${branch}'.`);\n\t}\n\tmovingRoot.parent = parent;\n\tmovingRoot.type = undefined;\n\n\tif (destinationStack) {\n\t\tdestinationStack.branches.push(...movingBranches);\n\t} else {\n\t\tstate.stacks.push({\n\t\t\tid: crypto.randomUUID(),\n\t\t\tbranches: [\n\t\t\t\t{\n\t\t\t\t\tname: parent,\n\t\t\t\t\ttype: \"root\",\n\t\t\t\t\tparent: null,\n\t\t\t\t\tpr_number: null,\n\t\t\t\t\tpr_link: null,\n\t\t\t\t\tlast_submitted_version: null,\n\t\t\t\t\tlast_synced_at: null,\n\t\t\t\t\tsync_source: null,\n\t\t\t\t},\n\t\t\t\t...movingBranches,\n\t\t\t],\n\t\t});\n\t}\n\n\tstate.stacks = state.stacks.filter((stack) => stack.branches.length > 0);\n\tassertStateInvariants(state.stacks);\n\tawait writeState(state, cwd);\n\treturn { branch, parent, status: \"reparented\" };\n}\n","import { DubError } from \"../lib/errors\";\nimport { getCurrentBranch } from \"../lib/git\";\nimport { findStackForBranch, readState } from \"../lib/state\";\n\ninterface TrunkResult {\n\tbranch: string;\n\ttrunk: string;\n}\n\nexport async function trunk(\n\tcwd: string,\n\tbranchArg?: string,\n): Promise<TrunkResult> {\n\tconst branch = branchArg ?? (await getCurrentBranch(cwd));\n\tconst state = await readState(cwd);\n\tconst stack = findStackForBranch(state, branch);\n\tif (!stack) {\n\t\tthrow new DubError(\n\t\t\t`Branch '${branch}' is not tracked. Run 'dub track ${branch} --parent <branch>' first.`,\n\t\t);\n\t}\n\tconst root = stack.branches.find((candidate) => candidate.type === \"root\");\n\tif (!root) {\n\t\tthrow new DubError(\n\t\t\t`Stack for '${branch}' is missing a root branch. Re-run 'dub track' to repair metadata.`,\n\t\t);\n\t}\n\treturn { branch, trunk: root.name };\n}\n","import { DubError } from \"../lib/errors\";\nimport {\n\tcheckoutBranch,\n\tdeleteBranch,\n\tforceBranchTo,\n\tgetCurrentBranch,\n\tisWorkingTreeClean,\n} from \"../lib/git\";\nimport { writeState } from \"../lib/state\";\nimport { clearUndoEntry, readUndoEntry } from \"../lib/undo-log\";\n\ninterface UndoResult {\n\tundone: \"create\" | \"restack\";\n\tdetails: string;\n}\n\n/**\n * Undoes the last `dub create` or `dub restack` operation.\n *\n * Reversal strategy:\n * - **create**: Deletes the created branch, restores state, checks out the previous branch.\n * - **restack**: Resets every rebased branch to its pre-rebase tip via `git branch -f`,\n * restores state, checks out the previous branch.\n *\n * Only one level of undo is supported. After undo, the undo entry is cleared.\n *\n * @param cwd - Working directory\n * @returns What was undone and a human-readable summary\n * @throws {DubError} If nothing to undo or working tree is dirty\n */\nexport async function undo(cwd: string): Promise<UndoResult> {\n\tconst entry = await readUndoEntry(cwd);\n\n\tif (!(await isWorkingTreeClean(cwd))) {\n\t\tthrow new DubError(\n\t\t\t\"Working tree has uncommitted changes. Commit or stash them before undoing.\",\n\t\t);\n\t}\n\n\tconst currentBranch = await getCurrentBranch(cwd);\n\n\tif (entry.operation === \"create\") {\n\t\t// If we're on a branch that's about to be deleted, switch away first\n\t\tconst needsCheckout = entry.createdBranches.includes(currentBranch);\n\t\tif (needsCheckout) {\n\t\t\tawait checkoutBranch(entry.previousBranch, cwd);\n\t\t}\n\n\t\tfor (const branch of entry.createdBranches) {\n\t\t\tawait deleteBranch(branch, cwd);\n\t\t}\n\n\t\tif (!needsCheckout && currentBranch !== entry.previousBranch) {\n\t\t\tawait checkoutBranch(entry.previousBranch, cwd);\n\t\t}\n\n\t\tawait writeState(entry.previousState, cwd);\n\t\tawait clearUndoEntry(cwd);\n\n\t\treturn {\n\t\t\tundone: \"create\",\n\t\t\tdetails: `Deleted branch${entry.createdBranches.length > 1 ? \"es\" : \"\"} '${entry.createdBranches.join(\"', '\")}'`,\n\t\t};\n\t}\n\n\t// restack undo: reset all branches to their pre-rebase tips\n\t// First checkout a safe branch so we don't conflict with force-moves\n\tawait checkoutBranch(entry.previousBranch, cwd);\n\n\tfor (const [name, sha] of Object.entries(entry.branchTips)) {\n\t\tif (name === entry.previousBranch) continue; // skip the branch we're on\n\t\tawait forceBranchTo(name, sha, cwd);\n\t}\n\n\t// Now force the branch we're on (if it was tracked)\n\tif (entry.branchTips[entry.previousBranch]) {\n\t\tawait forceBranchTo(\n\t\t\tentry.previousBranch,\n\t\t\tentry.branchTips[entry.previousBranch],\n\t\t\tcwd,\n\t\t);\n\t}\n\n\tawait writeState(entry.previousState, cwd);\n\tawait clearUndoEntry(cwd);\n\n\treturn {\n\t\tundone: \"restack\",\n\t\tdetails: `Reset ${Object.keys(entry.branchTips).length} branches to pre-restack state`,\n\t};\n}\n","import { stdin as input, stdout as output } from \"node:process\";\nimport * as readline from \"node:readline/promises\";\nimport { DubError } from \"../lib/errors\";\nimport { getCurrentBranch } from \"../lib/git\";\nimport {\n\tgetUntrackContext,\n\ttype UntrackResult,\n\tuntrackBranch,\n} from \"../lib/untrack\";\n\ninterface UntrackCommandOptions {\n\tdownstack?: boolean;\n\tinteractive?: boolean;\n}\n\nfunction isInteractiveShell(): boolean {\n\treturn Boolean(process.stdout.isTTY && process.stdin.isTTY);\n}\n\nasync function confirmDownstack(branch: string, descendants: string[]) {\n\tconst rl = readline.createInterface({ input, output });\n\ttry {\n\t\tconst answer = await rl.question(\n\t\t\t`Branch '${branch}' has descendants (${descendants.join(\", \")}). Untrack them too? [y/N] `,\n\t\t);\n\t\tconst normalized = answer.trim().toLowerCase();\n\t\treturn normalized === \"y\" || normalized === \"yes\";\n\t} finally {\n\t\trl.close();\n\t}\n}\n\nexport async function untrack(\n\tcwd: string,\n\tbranchArg?: string,\n\toptions: UntrackCommandOptions = {},\n): Promise<UntrackResult> {\n\tconst branch = branchArg ?? (await getCurrentBranch(cwd));\n\tconst interactive = options.interactive ?? isInteractiveShell();\n\tlet downstack = options.downstack ?? false;\n\n\tconst context = await getUntrackContext(cwd, branch);\n\tif (context.descendants.length > 0 && !downstack) {\n\t\tif (!interactive) {\n\t\t\tthrow new DubError(\n\t\t\t\t`Branch '${branch}' has descendants (${context.descendants.join(\", \")}). Re-run with --downstack or interactive mode.`,\n\t\t\t);\n\t\t}\n\t\tdownstack = await confirmDownstack(branch, context.descendants);\n\t}\n\n\treturn untrackBranch(cwd, { branch, downstack });\n}\n","import { DubError } from \"./errors\";\nimport { getDescendants } from \"./graph\";\nimport { assertStateInvariants } from \"./invariants\";\nimport { findStackForBranch, readState, type Stack, writeState } from \"./state\";\n\nexport interface UntrackOptions {\n\tbranch: string;\n\tdownstack?: boolean;\n}\n\nexport interface UntrackResult {\n\tremoved: string[];\n\treparented: Array<{ branch: string; parent: string | null }>;\n}\n\nexport interface UntrackContext {\n\tstack: Stack;\n\tbranch: string;\n\tdescendants: string[];\n}\n\nexport async function getUntrackContext(\n\tcwd: string,\n\tbranch: string,\n): Promise<UntrackContext> {\n\tconst state = await readState(cwd);\n\tconst stack = findStackForBranch(state, branch);\n\tif (!stack) {\n\t\tthrow new DubError(\n\t\t\t`Branch '${branch}' is not tracked. Run 'dub track ${branch} --parent <branch>' first.`,\n\t\t);\n\t}\n\treturn {\n\t\tstack,\n\t\tbranch,\n\t\tdescendants: getDescendants(stack, branch),\n\t};\n}\n\n/**\n * Removes a branch from DubStack tracking metadata without deleting git branches.\n */\nexport async function untrackBranch(\n\tcwd: string,\n\toptions: UntrackOptions,\n): Promise<UntrackResult> {\n\tconst state = await readState(cwd);\n\tconst stack = findStackForBranch(state, options.branch);\n\tif (!stack) {\n\t\tthrow new DubError(\n\t\t\t`Branch '${options.branch}' is not tracked by DubStack.`,\n\t\t);\n\t}\n\n\tconst entry = stack.branches.find((branch) => branch.name === options.branch);\n\tif (!entry) {\n\t\tthrow new DubError(\n\t\t\t`Branch '${options.branch}' is missing from tracked stack.`,\n\t\t);\n\t}\n\n\tconst descendants = getDescendants(stack, options.branch);\n\tconst removedSet = new Set<string>(\n\t\toptions.downstack ? [options.branch, ...descendants] : [options.branch],\n\t);\n\n\tif (entry.type === \"root\" && !options.downstack && descendants.length > 0) {\n\t\tthrow new DubError(\n\t\t\t`Branch '${options.branch}' is a root with descendants. Use --downstack to untrack the whole subtree.`,\n\t\t);\n\t}\n\n\tconst reparented: Array<{ branch: string; parent: string | null }> = [];\n\tif (!options.downstack) {\n\t\tfor (const branch of stack.branches) {\n\t\t\tif (branch.parent !== options.branch) continue;\n\t\t\tbranch.parent = entry.parent;\n\t\t\treparented.push({ branch: branch.name, parent: branch.parent });\n\t\t}\n\t}\n\n\tstack.branches = stack.branches.filter(\n\t\t(branch) => !removedSet.has(branch.name),\n\t);\n\tstate.stacks = state.stacks.filter(\n\t\t(candidate) => candidate.branches.length > 0,\n\t);\n\n\tassertStateInvariants(state.stacks);\n\tawait writeState(state, cwd);\n\n\treturn {\n\t\tremoved: [options.branch, ...(options.downstack ? descendants : [])],\n\t\treparented,\n\t};\n}\n"],"mappings":"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","names":["output","parent","children","fs","path","fs","path","execa","init_skills","parent","chalk","fs","path","parent","children","parent","fs","path","children","getChildren","parent","children","getChildren","children","getChildren","parent","execa","fs","path","pr","parent","input","output","readline","input","input","input","isInteractiveShell","input","output","getDescendants","children","input","output","readline","crypto","parent","isInteractiveShell","input","output","parent","input","output","readline","isInteractiveShell","input","output","require","chalk","trunk","addSkills","removeSkills","modify","output"]}