feat(lanes,ui): per-lane git surface — Changes panel, VS Code-style diff, branch-aware Add lane, redesigned tooltips (#34, #35)
- Changes card beside lane detail with five modes: Files tree, overview, Review (whole diff, per-file collapse), single file, commit history. - LaneDiffView: unified / side-by-side with independent scroll on both axes and mirrored scrollLeft, expand/collapse context, intra-line emphasis. - Staged-only commit box; git actions (fetch/pull/push/stage/unstage/ discard/commit/switch/branch-create/branch-delete) guarded in git-ops.js. - Server: git-diff.js + git-ops.js behind GET /api/lanes/:id/git/* and POST /api/lanes/:id/git/:action; gitFacts gains upstream/ahead/behind. - Add lane: new/existing branch, current branch, worktree list, prefill from the git bar's "New lane here"; /api/run/cwds gains a repo kind. - GlobalTooltip upgrades every native title into a themed anchored bubble; chart/info popovers use theme tokens.
This commit is contained in:
@@ -22,13 +22,19 @@
|
||||
"add": "Add lane",
|
||||
"addLane": "Create a lane from a working directory",
|
||||
"addLaneBaseLabel": "Branch to fork from",
|
||||
"addLaneBranchHint": "Must be a valid, not-yet-existing git branch name.",
|
||||
"addLaneBranchBusy": "{{branch}} — already checked out at {{path}}",
|
||||
"addLaneBranchExistingHint": "The worktree checks this branch out as it is — no new branch, no base.",
|
||||
"addLaneBranchExistingLabel": "Branch to check out",
|
||||
"addLaneBranchHintAuto": "Leave empty to use the default name shown above.",
|
||||
"addLaneBranchLabel": "New branch name",
|
||||
"addLaneBranchModeCurrent": "Current branch",
|
||||
"addLaneBranchModeCurrentHint": "Work straight on this repo's checked-out branch (main) — no worktree, no fork. Switches to Repo mode.",
|
||||
"addLaneBranchModeExisting": "Existing branch",
|
||||
"addLaneBranchModeNew": "New branch",
|
||||
"addLaneBranchPlaceholder": "feat/my-feature",
|
||||
"addLaneNoBranches": "This repo has no commits yet — the worktree will start empty.",
|
||||
"addLaneNoFreeBranches": "Every branch in this repo is already checked out in a worktree. Create a new branch instead.",
|
||||
"addLaneNotARepo": "Not a git repository (or no read access) yet.",
|
||||
"addLanePipelineHint": "Which stages this lane's map shows. Pick the one the skill driving it declares against — nothing else in this UI changes it later.",
|
||||
"addLanePipelineLabel": "Pipeline template",
|
||||
"addLaneProvisionFailed": "Worktree provisioning failed or timed out — the lane exists but auto-setup was skipped. Check the lane's git facts, then run agents/mcp setup manually.",
|
||||
"addLaneRepoHint": "An existing git repo. The dashboard creates a new worktree for the lane, not a folder you pick.",
|
||||
"addLaneRepoHintAdopt": "An existing directory. The dashboard tracks it as-is — no worktree, no new branch.",
|
||||
@@ -52,11 +58,63 @@
|
||||
"addLaneToolClaude": "Claude Code",
|
||||
"addLaneToolCodex": "Codex",
|
||||
"addLaneToolHint": "Which CLI drives this lane. Cannot be changed later.",
|
||||
"autoStage": "auto: {{stage}}",
|
||||
"addLaneWorktreeDetached": "(detached)",
|
||||
"addLaneWorktreesMore": "+{{count}} more",
|
||||
"addLaneWorktreesTitle": "Worktrees of this repo ({{count}})",
|
||||
"browse.button": "Browse",
|
||||
"browse.empty": "This folder is empty.",
|
||||
"browse.select": "Select this folder",
|
||||
"browse.title": "Browse for a folder",
|
||||
"changes.back": "All files",
|
||||
"changes.bin": "bin",
|
||||
"changes.binary": "Binary file — not shown.",
|
||||
"changes.collapse": "Collapse the changes panel",
|
||||
"changes.collapseAll": "Collapse every file",
|
||||
"changes.collapseAllFolders": "Collapse all folders",
|
||||
"changes.collapseContext": "Show fewer surrounding lines",
|
||||
"changes.collapseFile": "Collapse {{path}}",
|
||||
"changes.commitPlaceholder": "Commit message",
|
||||
"changes.commitStaged": "Commit {{count}} staged",
|
||||
"changes.conflicted": "conflict",
|
||||
"changes.discard": "Discard this file's changes",
|
||||
"changes.discardConfirm": "Click again to discard — this cannot be undone",
|
||||
"changes.empty.branch": "This branch matches its base.",
|
||||
"changes.empty.commit": "This commit changed no files.",
|
||||
"changes.empty.work": "Nothing uncommitted.",
|
||||
"changes.expand": "Show the changes panel",
|
||||
"changes.expandAll": "Expand every file",
|
||||
"changes.expandAllFolders": "Expand all folders",
|
||||
"changes.expandContext": "Show more surrounding lines",
|
||||
"changes.expandFile": "Expand {{path}}",
|
||||
"changes.fileGone": "That file no longer has changes in this range.",
|
||||
"changes.fileTruncated": "Diff cut short — open the file in an editor for the rest.",
|
||||
"changes.layout.split": "Side-by-side",
|
||||
"changes.layout.unified": "Unified",
|
||||
"changes.loading": "Reading the working copy…",
|
||||
"changes.mode.browse": "Files",
|
||||
"changes.mode.history": "History",
|
||||
"changes.mode.overview": "Overview",
|
||||
"changes.mode.review": "Review",
|
||||
"changes.noCommits": "No commits yet.",
|
||||
"changes.noHunks": "No textual change.",
|
||||
"changes.noMatches": "No tracked file matches.",
|
||||
"changes.openFile": "Open {{path}}",
|
||||
"changes.quickOpen": "Find a file by path…",
|
||||
"changes.range.branch": "vs base",
|
||||
"changes.range.branchHint": "base...HEAD — everything this lane's branch adds on top of its base",
|
||||
"changes.range.work": "Uncommitted",
|
||||
"changes.range.workHint": "Working tree vs HEAD — what has been touched and not committed",
|
||||
"changes.refresh": "Refresh",
|
||||
"changes.resize": "Resize the changes panel (next: {{size}})",
|
||||
"changes.size.compact": "Narrow",
|
||||
"changes.size.half": "50 / 50",
|
||||
"changes.size.wide": "70 / 30",
|
||||
"changes.stage": "Stage this file",
|
||||
"changes.title": "Changes",
|
||||
"changes.truncated": "Some changes were left out to keep this panel responsive.",
|
||||
"changes.unavailable": "This lane's directory is not a readable git repository.",
|
||||
"changes.unstage": "Unstage this file",
|
||||
"changes.wholeFile": "Whole file",
|
||||
"confirmRemoveCancel": "Cancel",
|
||||
"confirmRemoveConfirm": "Remove",
|
||||
"confirmRemoveMessage": "This action cannot be undone.",
|
||||
@@ -94,7 +152,7 @@
|
||||
"destructive.reset.survives": "Gitignored files such as node_modules and .env are kept; untracked files are deleted.",
|
||||
"destructive.reset.title": "Reset managed worktree?",
|
||||
"destructive.warning.no-remote": "No Git remote is configured, so nothing here is backed up remotely. You can still proceed.",
|
||||
"empty.body": "A lane is one working directory the dashboard follows — its pipeline, sessions and terminal. Add one here, or from a terminal:",
|
||||
"empty.body": "A lane is one working directory the dashboard follows — its pipeline, sessions and terminal. Click anywhere on this card to add one, or from a terminal:",
|
||||
"empty.title": "No lanes yet",
|
||||
"features.archived": "archived",
|
||||
"features.live": "Live",
|
||||
@@ -105,6 +163,36 @@
|
||||
"git.filesMore_other": "… and {{count}} more files",
|
||||
"git.noDelta": "new",
|
||||
"git.uncommitted": "{{dirty}} modified · {{untracked}} untracked",
|
||||
"gitBar.branchCreate": "Create",
|
||||
"gitBar.branchCreateHint": "Create this branch without switching to it",
|
||||
"gitBar.branchDelete": "Delete",
|
||||
"gitBar.branchDeleteHint": "Delete the selected branch (refused if it has unmerged commits)",
|
||||
"gitBar.branchNewPlaceholder": "New branch name…",
|
||||
"gitBar.cancel": "Cancel",
|
||||
"gitBar.commit": "Commit",
|
||||
"gitBar.commitAll_one": "Commit {{count}} file",
|
||||
"gitBar.commitAll_other": "Commit {{count}} files",
|
||||
"gitBar.commitHint": "Stage everything and commit",
|
||||
"gitBar.commitNothing": "Nothing to commit",
|
||||
"gitBar.commitPlaceholder": "Commit message",
|
||||
"gitBar.commitStaged": "Commit staged",
|
||||
"gitBar.commitStagedHint": "Commit only what is staged in the Changes panel",
|
||||
"gitBar.fetch": "Fetch",
|
||||
"gitBar.fetchHint": "git fetch --all --prune",
|
||||
"gitBar.inSync": "in sync",
|
||||
"gitBar.newLane": "New lane here",
|
||||
"gitBar.newLaneHint": "Open Add lane for a sibling worktree on the selected branch",
|
||||
"gitBar.noUpstream": "not pushed",
|
||||
"gitBar.pull": "Pull",
|
||||
"gitBar.pullHint": "git pull --ff-only — refuses instead of merging when the branch has diverged",
|
||||
"gitBar.push": "Push",
|
||||
"gitBar.pushHint": "git push -u origin HEAD",
|
||||
"gitBar.switch": "Branch",
|
||||
"gitBar.switchApply": "Switch branch",
|
||||
"gitBar.switchCurrent": "current",
|
||||
"gitBar.switchDirty": "Commit or discard the uncommitted changes first",
|
||||
"gitBar.switchHint": "Switch this worktree to another local branch",
|
||||
"gitBar.switchLabel": "Switch branch…",
|
||||
"kind.adopted": "adopted",
|
||||
"kind.managed": "managed",
|
||||
"laneDetail.hide": "Hide details",
|
||||
@@ -142,7 +230,6 @@
|
||||
"splitView.paneCount": "{{count}} pane",
|
||||
"splitView.paneLaneLabel": "Pane lane selector",
|
||||
"splitView.pickLane": "Pick a lane",
|
||||
"stageUndeclared": "not declared",
|
||||
"status.failed": "failed",
|
||||
"status.idle": "idle",
|
||||
"status.provisioning": "provisioning",
|
||||
|
||||
Reference in New Issue
Block a user