@sealant/mend 0.29.1 → 0.30.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.
Files changed (79) hide show
  1. package/README.md +3 -0
  2. package/dist/{chunk-C6O4LUE7.js → chunk-BMFB2UN7.js} +411 -65
  3. package/dist/{dashboard-JJYC4SNU.js → dashboard-OF5UXII2.js} +452 -228
  4. package/dist/main.js +1688 -825
  5. package/man/mend-accounts.1 +1 -1
  6. package/man/mend-adopt.1 +1 -1
  7. package/man/mend-attach.1 +9 -3
  8. package/man/mend-codex.1 +13 -3
  9. package/man/mend-completions.1 +1 -1
  10. package/man/mend-connect.1 +1 -1
  11. package/man/mend-continue.1 +1 -1
  12. package/man/mend-doctor.1 +1 -1
  13. package/man/mend-dotfiles-repo.1 +38 -0
  14. package/man/mend-dotfiles-sync.1 +3 -3
  15. package/man/mend-dotfiles.1 +3 -3
  16. package/man/mend-env-cluster.1 +1 -1
  17. package/man/mend-env-load.1 +1 -1
  18. package/man/mend-env-show.1 +1 -1
  19. package/man/mend-folder-create.1 +1 -1
  20. package/man/mend-folder-list.1 +1 -1
  21. package/man/mend-folder-push.1 +1 -1
  22. package/man/mend-folder-rm.1 +1 -1
  23. package/man/mend-help.1 +1 -1
  24. package/man/mend-invite.1 +1 -1
  25. package/man/mend-keys-init.1 +1 -1
  26. package/man/mend-keys-mode.1 +1 -1
  27. package/man/mend-keys-share.1 +1 -1
  28. package/man/mend-keys-show.1 +1 -1
  29. package/man/mend-land.1 +41 -0
  30. package/man/mend-login.1 +1 -1
  31. package/man/mend-logout.1 +1 -1
  32. package/man/mend-man.1 +1 -1
  33. package/man/mend-members.1 +1 -1
  34. package/man/mend-operator-exposure.1 +1 -1
  35. package/man/mend-operator-gate.1 +1 -1
  36. package/man/mend-operator-grant-owner.1 +1 -1
  37. package/man/mend-operator-org-create.1 +1 -1
  38. package/man/mend-operator-org-invite-owner.1 +1 -1
  39. package/man/mend-operator-org-list.1 +1 -1
  40. package/man/mend-operator-org-rename.1 +1 -1
  41. package/man/mend-operator-reset-link.1 +1 -1
  42. package/man/mend-pair.1 +1 -1
  43. package/man/mend-projects.1 +1 -1
  44. package/man/mend-pull.1 +29 -0
  45. package/man/mend-refresh.1 +1 -1
  46. package/man/mend-rejoin.1 +7 -2
  47. package/man/mend-resume.1 +1 -1
  48. package/man/mend-run.1 +1 -1
  49. package/man/mend-server-logs.1 +1 -1
  50. package/man/mend-server-restart.1 +1 -1
  51. package/man/mend-server-setup.1 +1 -1
  52. package/man/mend-server-start.1 +1 -1
  53. package/man/mend-server-status.1 +1 -1
  54. package/man/mend-server-stop.1 +1 -1
  55. package/man/mend-server-upgrade.1 +1 -1
  56. package/man/mend-server.1 +1 -1
  57. package/man/mend-service-add.1 +1 -1
  58. package/man/mend-service-connect.1 +3 -1
  59. package/man/mend-service-init.1 +1 -1
  60. package/man/mend-service-list.1 +1 -1
  61. package/man/mend-service-logs.1 +1 -1
  62. package/man/mend-service-restart.1 +1 -1
  63. package/man/mend-service-run.1 +1 -1
  64. package/man/mend-service-stop.1 +1 -1
  65. package/man/mend-session-share.1 +1 -1
  66. package/man/mend-sessions.1 +1 -1
  67. package/man/mend-shell.1 +1 -1
  68. package/man/mend-skills-push.1 +1 -1
  69. package/man/mend-skills.1 +1 -1
  70. package/man/mend-snake.1 +13 -0
  71. package/man/mend-ssh-setup.1 +1 -1
  72. package/man/mend-ssh.1 +1 -1
  73. package/man/mend-stop.1 +1 -1
  74. package/man/mend-ui.1 +8 -2
  75. package/man/mend-uninstall.1 +1 -1
  76. package/man/mend-version.1 +1 -1
  77. package/man/mend-worktrees.1 +1 -1
  78. package/man/mend.1 +14 -2
  79. package/package.json +3 -3
@@ -2,13 +2,15 @@ import {
2
2
  HARNESS_COMMANDS,
3
3
  LIVE_STATUSES,
4
4
  RepositoryCloneUrl,
5
+ createSseParser,
5
6
  cwdFacts,
7
+ eventFamilies,
6
8
  isPendingId,
7
9
  matchProjectByCwd,
8
10
  normalizeProjectName,
9
11
  pendingId,
10
12
  repositoryCloneUrlIssue
11
- } from "./chunk-C6O4LUE7.js";
13
+ } from "./chunk-BMFB2UN7.js";
12
14
 
13
15
  // src/dashboard.tsx
14
16
  import { CliRenderEvents, createCliRenderer } from "@opentui/core";
@@ -20,7 +22,7 @@ import {
20
22
  useQuery as useQuery2,
21
23
  useQueryClient as useQueryClient2
22
24
  } from "@tanstack/react-query";
23
- import { useEffect as useEffect2, useMemo as useMemo2, useRef as useRef2, useState as useState2, useSyncExternalStore } from "react";
25
+ import { useEffect as useEffect3, useMemo as useMemo2, useRef as useRef2, useState as useState3, useSyncExternalStore } from "react";
24
26
 
25
27
  // src/dashboard-adoption.ts
26
28
  var deriveAdoptOffer = (facts) => {
@@ -1948,56 +1950,181 @@ function ReviewScreen({
1948
1950
  );
1949
1951
  }
1950
1952
 
1951
- // src/workbench-events.ts
1952
- var createSseParser = () => {
1953
- let buffer = "";
1953
+ // src/snake.tsx
1954
+ import { useEffect as useEffect2, useState as useState2 } from "react";
1955
+
1956
+ // src/snake-game.ts
1957
+ var OPPOSITE = {
1958
+ up: "down",
1959
+ down: "up",
1960
+ left: "right",
1961
+ right: "left"
1962
+ };
1963
+ var STEP = {
1964
+ up: { x: 0, y: -1 },
1965
+ down: { x: 0, y: 1 },
1966
+ left: { x: -1, y: 0 },
1967
+ right: { x: 1, y: 0 }
1968
+ };
1969
+ var same = (a, b) => a.x === b.x && a.y === b.y;
1970
+ var placeFood = (width, height, snake, random) => {
1971
+ const free = [];
1972
+ for (let y = 0; y < height; y += 1)
1973
+ for (let x = 0; x < width; x += 1)
1974
+ if (!snake.some((cell) => cell.x === x && cell.y === y)) free.push({ x, y });
1975
+ if (free.length === 0) return snake[0] ?? { x: 0, y: 0 };
1976
+ return free[Math.min(free.length - 1, Math.floor(random() * free.length))] ?? free[0];
1977
+ };
1978
+ var newSnakeGame = (width, height, random) => {
1979
+ const w = Math.max(8, width);
1980
+ const h = Math.max(4, height);
1981
+ const y = Math.floor(h / 2);
1982
+ const x = Math.floor(w / 2);
1983
+ const snake = [
1984
+ { x, y },
1985
+ { x: x - 1, y },
1986
+ { x: x - 2, y }
1987
+ ];
1954
1988
  return {
1955
- push: (chunk) => {
1956
- buffer += chunk;
1957
- const payloads = [];
1958
- for (; ; ) {
1959
- const boundary = buffer.indexOf("\n\n");
1960
- if (boundary === -1) break;
1961
- const frame = buffer.slice(0, boundary);
1962
- buffer = buffer.slice(boundary + 2);
1963
- const data = frame.split("\n").filter((line) => line.startsWith("data:")).map((line) => line.slice("data:".length).replace(/^ /, "")).join("\n");
1964
- if (data !== "") payloads.push(data);
1965
- }
1966
- return payloads;
1967
- }
1989
+ width: w,
1990
+ height: h,
1991
+ snake,
1992
+ direction: "right",
1993
+ pending: null,
1994
+ food: placeFood(w, h, snake, random),
1995
+ score: 0,
1996
+ over: false
1968
1997
  };
1969
1998
  };
1970
- var eventFamilies = (payload) => {
1971
- let parsed;
1972
- try {
1973
- parsed = JSON.parse(payload);
1974
- } catch {
1975
- return [];
1976
- }
1977
- if (typeof parsed !== "object" || parsed === null || !("type" in parsed)) return [];
1978
- switch (parsed.type) {
1979
- case "project":
1980
- case "worktree":
1981
- case "session-process":
1982
- return ["workbench"];
1983
- // Settlement refreshes the final transcript immediately. Conversation
1984
- // items can arrive many times per second; the live preview's bounded
1985
- // polling reads those instead of repeatedly fetching the whole record.
1986
- case "session":
1987
- return ["workbench", "review", "transcript"];
1988
- case "agent-conversation":
1989
- return ["workbench", "review"];
1990
- // A comment moves the review AND the dashboard's open-comment counts.
1991
- case "session-change":
1992
- case "review-comment":
1993
- return ["workbench", "review"];
1994
- default:
1995
- return [];
1999
+ var turn = (game, direction) => {
2000
+ if (game.over) return game;
2001
+ if (direction === OPPOSITE[game.direction] || direction === game.direction) return game;
2002
+ return { ...game, pending: direction };
2003
+ };
2004
+ var tick = (game, random) => {
2005
+ if (game.over) return game;
2006
+ const direction = game.pending ?? game.direction;
2007
+ const head = game.snake[0];
2008
+ const next = {
2009
+ x: (head.x + STEP[direction].x + game.width) % game.width,
2010
+ y: (head.y + STEP[direction].y + game.height) % game.height
2011
+ };
2012
+ const eats = same(next, game.food);
2013
+ const body = eats ? game.snake : game.snake.slice(0, -1);
2014
+ if (body.some((cell) => same(cell, next))) {
2015
+ return { ...game, direction, pending: null, over: true };
1996
2016
  }
2017
+ const snake = [next, ...body];
2018
+ return {
2019
+ ...game,
2020
+ snake,
2021
+ direction,
2022
+ pending: null,
2023
+ score: eats ? game.score + 1 : game.score,
2024
+ food: eats ? placeFood(game.width, game.height, snake, random) : game.food
2025
+ };
2026
+ };
2027
+ var render = (game) => {
2028
+ const rows = [];
2029
+ for (let y = 0; y < game.height; y += 1) rows.push(Array.from({ length: game.width }, () => "\xB7"));
2030
+ rows[game.food.y][game.food.x] = "\u25CF";
2031
+ game.snake.forEach((cell, index) => {
2032
+ rows[cell.y][cell.x] = index === 0 ? "\u25C6" : "\u2588";
2033
+ });
2034
+ return rows.map((row) => row.join(""));
1997
2035
  };
1998
2036
 
1999
- // src/dashboard.tsx
2037
+ // src/snake.tsx
2000
2038
  import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "@opentui/react/jsx-runtime";
2039
+ var TICK_MS = 140;
2040
+ var useSnake = (options) => {
2041
+ const { width, height, enabled } = options;
2042
+ const [game, setGame] = useState2(() => newSnakeGame(width, height, Math.random));
2043
+ const [paused, setPaused] = useState2(false);
2044
+ useEffect2(() => {
2045
+ if (enabled) {
2046
+ setGame(newSnakeGame(width, height, Math.random));
2047
+ setPaused(false);
2048
+ }
2049
+ }, [width, height, enabled]);
2050
+ useEffect2(() => {
2051
+ if (!enabled || paused) return;
2052
+ const timer = setInterval(() => setGame((current) => tick(current, Math.random)), TICK_MS);
2053
+ return () => clearInterval(timer);
2054
+ }, [enabled, paused]);
2055
+ const steer = (direction) => {
2056
+ setPaused(false);
2057
+ setGame(
2058
+ (current) => current.over ? newSnakeGame(current.width, current.height, Math.random) : turn(current, direction)
2059
+ );
2060
+ };
2061
+ const togglePause = () => setPaused((current) => !current);
2062
+ return { game, paused, steer, togglePause };
2063
+ };
2064
+ var SnakeHeading = ({
2065
+ handle,
2066
+ hint
2067
+ }) => {
2068
+ const { game, paused } = handle;
2069
+ const state = game.over ? "over \xB7 any arrow starts again" : paused ? "paused" : null;
2070
+ return /* @__PURE__ */ jsxs2(Fragment2, { children: [
2071
+ /* @__PURE__ */ jsxs2("text", { height: 1, bg: "transparent", children: [
2072
+ /* @__PURE__ */ jsx2("span", { children: " " }),
2073
+ /* @__PURE__ */ jsx2("span", { fg: INK, children: "play snake while you wait" }),
2074
+ /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " \xB7 score " }),
2075
+ /* @__PURE__ */ jsx2("span", { fg: game.over ? MUTED : ACCENT, children: String(game.score) }),
2076
+ state === null ? null : /* @__PURE__ */ jsx2("span", { fg: FAINT, children: ` \xB7 ${state}` })
2077
+ ] }),
2078
+ /* @__PURE__ */ jsx2("text", { height: 1, bg: "transparent", fg: FAINT, children: ` ${hint}` })
2079
+ ] });
2080
+ };
2081
+ var SnakeBoard = ({
2082
+ handle,
2083
+ focused
2084
+ }) => {
2085
+ const { game } = handle;
2086
+ const rows = render(game);
2087
+ return /* @__PURE__ */ jsxs2(Fragment2, { children: [
2088
+ /* @__PURE__ */ jsx2(
2089
+ SnakeHeading,
2090
+ {
2091
+ handle,
2092
+ hint: focused ? "arrows steer \xB7 space pauses \xB7 esc puts it away" : "focus this pane to play \xB7 esc puts it away"
2093
+ }
2094
+ ),
2095
+ /* @__PURE__ */ jsx2(
2096
+ "box",
2097
+ {
2098
+ border: true,
2099
+ borderStyle: "rounded",
2100
+ borderColor: focused ? ACCENT : RULE,
2101
+ width: game.width + 2,
2102
+ height: game.height + 2,
2103
+ flexShrink: 0,
2104
+ marginLeft: 2,
2105
+ children: rows.map((row, index) => /* @__PURE__ */ jsx2("text", { height: 1, bg: "transparent", children: [...row].map((cell, x) => /* @__PURE__ */ jsx2(
2106
+ "span",
2107
+ {
2108
+ fg: cell === "\u25C6" ? ACCENT : cell === "\u2588" ? GREEN : cell === "\u25CF" ? INK : FAINT,
2109
+ children: cell === "\xB7" ? " " : cell
2110
+ },
2111
+ x
2112
+ )) }, index))
2113
+ }
2114
+ )
2115
+ ] });
2116
+ };
2117
+ var SnakeRows = ({ game }) => /* @__PURE__ */ jsx2(Fragment2, { children: render(game).map((row, index) => /* @__PURE__ */ jsx2("text", { height: 1, bg: "transparent", children: [...row].map((cell, x) => /* @__PURE__ */ jsx2(
2118
+ "span",
2119
+ {
2120
+ fg: cell === "\u25C6" ? ACCENT : cell === "\u2588" ? GREEN : cell === "\u25CF" ? INK : FAINT,
2121
+ children: cell === "\xB7" ? " " : cell
2122
+ },
2123
+ x
2124
+ )) }, index)) });
2125
+
2126
+ // src/dashboard.tsx
2127
+ import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs3 } from "@opentui/react/jsx-runtime";
2001
2128
  var STATUS_COLOR = {
2002
2129
  starting: INK_2,
2003
2130
  running: INK,
@@ -2028,7 +2155,7 @@ var COLUMN_TITLE = {
2028
2155
  };
2029
2156
  var WORKTREE_ROW_HEIGHT = 2;
2030
2157
  var SESSION_ROW_HEIGHT = 2;
2031
- var Gutter = ({ selected }) => /* @__PURE__ */ jsx2("span", { fg: selected ? ACCENT : FAINT, children: selected ? "\u258C " : " " });
2158
+ var Gutter = ({ selected }) => /* @__PURE__ */ jsx3("span", { fg: selected ? ACCENT : FAINT, children: selected ? "\u258C " : " " });
2032
2159
  var Pane = ({
2033
2160
  title,
2034
2161
  focused,
@@ -2036,7 +2163,7 @@ var Pane = ({
2036
2163
  width,
2037
2164
  height,
2038
2165
  grow
2039
- }) => /* @__PURE__ */ jsx2(
2166
+ }) => /* @__PURE__ */ jsx3(
2040
2167
  "box",
2041
2168
  {
2042
2169
  border: true,
@@ -2062,10 +2189,10 @@ var SummaryRow = ({
2062
2189
  }) => {
2063
2190
  const factWidth = fact === "" ? 0 : Math.min(fact.length, Math.max(0, width - 8));
2064
2191
  const nameWidth = Math.max(4, width - factWidth - 3);
2065
- return /* @__PURE__ */ jsxs2("text", { height: 1, bg: "transparent", children: [
2066
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " " }),
2067
- /* @__PURE__ */ jsx2("span", { fg: empty ? FAINT : INK_2, children: fit(name, nameWidth - 1).padEnd(nameWidth) }),
2068
- factWidth === 0 ? null : /* @__PURE__ */ jsx2("span", { fg: FAINT, children: fit(fact, factWidth) })
2192
+ return /* @__PURE__ */ jsxs3("text", { height: 1, bg: "transparent", children: [
2193
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " " }),
2194
+ /* @__PURE__ */ jsx3("span", { fg: empty ? FAINT : INK_2, children: fit(name, nameWidth - 1).padEnd(nameWidth) }),
2195
+ factWidth === 0 ? null : /* @__PURE__ */ jsx3("span", { fg: FAINT, children: fit(fact, factWidth) })
2069
2196
  ] });
2070
2197
  };
2071
2198
  var paneScrollStyle = {
@@ -2074,17 +2201,17 @@ var paneScrollStyle = {
2074
2201
  viewportOptions: { backgroundColor: "transparent" },
2075
2202
  contentOptions: { backgroundColor: "transparent" }
2076
2203
  };
2077
- var EmptyNote = ({ text }) => /* @__PURE__ */ jsx2("text", { height: 1, fg: FAINT, bg: "transparent", children: ` ${text}` });
2204
+ var EmptyNote = ({ text }) => /* @__PURE__ */ jsx3("text", { height: 1, fg: FAINT, bg: "transparent", children: ` ${text}` });
2078
2205
  var ProjectRow = ({
2079
2206
  item,
2080
2207
  selected,
2081
2208
  width
2082
2209
  }) => {
2083
2210
  const nameWidth = Math.max(6, width - 9);
2084
- return /* @__PURE__ */ jsx2("box", { height: 1, flexShrink: 0, backgroundColor: selected ? WASH : "transparent", children: /* @__PURE__ */ jsxs2("text", { height: 1, bg: "transparent", children: [
2085
- /* @__PURE__ */ jsx2(Gutter, { selected }),
2086
- /* @__PURE__ */ jsx2("span", { fg: INK, children: fit(item.project.name, nameWidth).padEnd(nameWidth + 1) }),
2087
- /* @__PURE__ */ jsx2("span", { fg: item.live > 0 ? MUTED : FAINT, children: item.live > 0 ? `${item.live}/${item.total}` : String(item.total) })
2211
+ return /* @__PURE__ */ jsx3("box", { height: 1, flexShrink: 0, backgroundColor: selected ? WASH : "transparent", children: /* @__PURE__ */ jsxs3("text", { height: 1, bg: "transparent", children: [
2212
+ /* @__PURE__ */ jsx3(Gutter, { selected }),
2213
+ /* @__PURE__ */ jsx3("span", { fg: INK, children: fit(item.project.name, nameWidth).padEnd(nameWidth + 1) }),
2214
+ /* @__PURE__ */ jsx3("span", { fg: item.live > 0 ? MUTED : FAINT, children: item.live > 0 ? `${item.live}/${item.total}` : String(item.total) })
2088
2215
  ] }) });
2089
2216
  };
2090
2217
  var WorktreeRow = ({
@@ -2109,13 +2236,13 @@ var WorktreeRow = ({
2109
2236
  ],
2110
2237
  factWidth
2111
2238
  );
2112
- return /* @__PURE__ */ jsxs2("box", { flexShrink: 0, flexDirection: "column", backgroundColor: selected ? WASH : "transparent", children: [
2113
- /* @__PURE__ */ jsx2("box", { height: 1, flexShrink: 0, backgroundColor: "transparent", children: /* @__PURE__ */ jsxs2("text", { height: 1, bg: "transparent", children: [
2114
- /* @__PURE__ */ jsx2(Gutter, { selected }),
2115
- /* @__PURE__ */ jsx2("span", { fg: INK, children: fit(group.name, nameWidth - 1).padEnd(nameWidth) }),
2116
- /* @__PURE__ */ jsx2("span", { fg: color, children: status })
2239
+ return /* @__PURE__ */ jsxs3("box", { flexShrink: 0, flexDirection: "column", backgroundColor: selected ? WASH : "transparent", children: [
2240
+ /* @__PURE__ */ jsx3("box", { height: 1, flexShrink: 0, backgroundColor: "transparent", children: /* @__PURE__ */ jsxs3("text", { height: 1, bg: "transparent", children: [
2241
+ /* @__PURE__ */ jsx3(Gutter, { selected }),
2242
+ /* @__PURE__ */ jsx3("span", { fg: INK, children: fit(group.name, nameWidth - 1).padEnd(nameWidth) }),
2243
+ /* @__PURE__ */ jsx3("span", { fg: color, children: status })
2117
2244
  ] }) }),
2118
- /* @__PURE__ */ jsx2("box", { height: 1, flexShrink: 0, backgroundColor: "transparent", children: /* @__PURE__ */ jsx2("text", { height: 1, bg: "transparent", fg: FAINT, children: ` ${facts}` }) })
2245
+ /* @__PURE__ */ jsx3("box", { height: 1, flexShrink: 0, backgroundColor: "transparent", children: /* @__PURE__ */ jsx3("text", { height: 1, bg: "transparent", fg: FAINT, children: ` ${facts}` }) })
2119
2246
  ] });
2120
2247
  };
2121
2248
  var SessionRow = ({
@@ -2140,23 +2267,23 @@ var SessionRow = ({
2140
2267
  ],
2141
2268
  factWidth
2142
2269
  );
2143
- return /* @__PURE__ */ jsxs2("box", { flexShrink: 0, flexDirection: "column", backgroundColor: selected ? WASH : "transparent", children: [
2144
- /* @__PURE__ */ jsx2("box", { height: 1, flexShrink: 0, backgroundColor: "transparent", children: /* @__PURE__ */ jsxs2("text", { height: 1, bg: "transparent", children: [
2145
- /* @__PURE__ */ jsx2(Gutter, { selected }),
2146
- /* @__PURE__ */ jsx2("span", { fg: INK, children: fit(sessionDisplayName(session), nameWidth - 1).padEnd(nameWidth) }),
2147
- /* @__PURE__ */ jsx2("span", { fg: color, children: status })
2270
+ return /* @__PURE__ */ jsxs3("box", { flexShrink: 0, flexDirection: "column", backgroundColor: selected ? WASH : "transparent", children: [
2271
+ /* @__PURE__ */ jsx3("box", { height: 1, flexShrink: 0, backgroundColor: "transparent", children: /* @__PURE__ */ jsxs3("text", { height: 1, bg: "transparent", children: [
2272
+ /* @__PURE__ */ jsx3(Gutter, { selected }),
2273
+ /* @__PURE__ */ jsx3("span", { fg: INK, children: fit(sessionDisplayName(session), nameWidth - 1).padEnd(nameWidth) }),
2274
+ /* @__PURE__ */ jsx3("span", { fg: color, children: status })
2148
2275
  ] }) }),
2149
- /* @__PURE__ */ jsx2("box", { height: 1, flexShrink: 0, backgroundColor: "transparent", children: /* @__PURE__ */ jsx2("text", { height: 1, bg: "transparent", fg: FAINT, children: ` ${facts}` }) })
2276
+ /* @__PURE__ */ jsx3("box", { height: 1, flexShrink: 0, backgroundColor: "transparent", children: /* @__PURE__ */ jsx3("text", { height: 1, bg: "transparent", fg: FAINT, children: ` ${facts}` }) })
2150
2277
  ] });
2151
2278
  };
2152
2279
  var HarnessRow = ({
2153
2280
  item,
2154
2281
  selected,
2155
2282
  background
2156
- }) => /* @__PURE__ */ jsx2("box", { height: 1, flexShrink: 0, backgroundColor: selected ? WASH : background, children: /* @__PURE__ */ jsxs2("text", { height: 1, bg: selected ? WASH : background, children: [
2157
- /* @__PURE__ */ jsx2(Gutter, { selected }),
2158
- /* @__PURE__ */ jsx2("span", { fg: INK, children: item.label.padEnd(12) }),
2159
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: item.hint })
2283
+ }) => /* @__PURE__ */ jsx3("box", { height: 1, flexShrink: 0, backgroundColor: selected ? WASH : background, children: /* @__PURE__ */ jsxs3("text", { height: 1, bg: selected ? WASH : background, children: [
2284
+ /* @__PURE__ */ jsx3(Gutter, { selected }),
2285
+ /* @__PURE__ */ jsx3("span", { fg: INK, children: item.label.padEnd(12) }),
2286
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: item.hint })
2160
2287
  ] }) });
2161
2288
  var PREVIEW_GLYPH = {
2162
2289
  user: "\u203A ",
@@ -2176,68 +2303,72 @@ var PREVIEW_COLOR = {
2176
2303
  meta: FAINT,
2177
2304
  blank: FAINT
2178
2305
  };
2179
- var PreviewRow = ({ line }) => /* @__PURE__ */ jsx2("box", { height: 1, flexShrink: 0, backgroundColor: "transparent", children: /* @__PURE__ */ jsxs2("text", { height: 1, bg: "transparent", children: [
2180
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: line.lead ? PREVIEW_GLYPH[line.kind] : " " }),
2181
- /* @__PURE__ */ jsx2("span", { fg: PREVIEW_COLOR[line.kind], children: line.text })
2306
+ var PreviewRow = ({ line }) => /* @__PURE__ */ jsx3("box", { height: 1, flexShrink: 0, backgroundColor: "transparent", children: /* @__PURE__ */ jsxs3("text", { height: 1, bg: "transparent", children: [
2307
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: line.lead ? PREVIEW_GLYPH[line.kind] : " " }),
2308
+ /* @__PURE__ */ jsx3("span", { fg: PREVIEW_COLOR[line.kind], children: line.text })
2182
2309
  ] }) });
2183
2310
  var SessionFacts = ({
2184
2311
  group,
2185
2312
  item,
2186
- rows
2313
+ rows,
2314
+ tunnels
2187
2315
  }) => {
2188
2316
  const { session, annotation, services } = item;
2189
2317
  const color = STATUS_COLOR[session.status] ?? MUTED;
2190
2318
  const summary = session.summary?.split("\n")[0] ?? null;
2191
2319
  const change = annotation ?? group?.annotation;
2192
2320
  const lines = [
2193
- /* @__PURE__ */ jsxs2("text", { height: 1, bg: "transparent", children: [
2194
- /* @__PURE__ */ jsx2("span", { children: " " }),
2195
- /* @__PURE__ */ jsx2("span", { fg: INK, children: sessionDisplayName(session) }),
2196
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: ` \xB7 ${session.harness}` })
2321
+ /* @__PURE__ */ jsxs3("text", { height: 1, bg: "transparent", children: [
2322
+ /* @__PURE__ */ jsx3("span", { children: " " }),
2323
+ /* @__PURE__ */ jsx3("span", { fg: INK, children: sessionDisplayName(session) }),
2324
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: ` \xB7 ${session.harness}` })
2197
2325
  ] }, "name"),
2198
- /* @__PURE__ */ jsxs2("text", { height: 1, bg: "transparent", children: [
2199
- /* @__PURE__ */ jsx2("span", { children: " " }),
2200
- /* @__PURE__ */ jsx2("span", { fg: color, children: session.status }),
2201
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " \xB7 " }),
2202
- /* @__PURE__ */ jsx2("span", { fg: MUTED, children: session.branch }),
2203
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: session.baseSha === "" ? "" : ` vs ${session.baseRef ?? session.baseSha.slice(0, 12)}` })
2326
+ /* @__PURE__ */ jsxs3("text", { height: 1, bg: "transparent", children: [
2327
+ /* @__PURE__ */ jsx3("span", { children: " " }),
2328
+ /* @__PURE__ */ jsx3("span", { fg: color, children: session.status }),
2329
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " \xB7 " }),
2330
+ /* @__PURE__ */ jsx3("span", { fg: MUTED, children: session.branch }),
2331
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: session.baseSha === "" ? "" : ` vs ${session.baseRef ?? session.baseSha.slice(0, 12)}` })
2204
2332
  ] }, "status"),
2205
- /* @__PURE__ */ jsx2("text", { height: 1, bg: "transparent", fg: FAINT, children: ` started ${timeAgo(session.createdAt)} \xB7 ${isPendingId(session.id) ? "provisioning" : session.id.slice(0, 8)}` }, "started"),
2206
- /* @__PURE__ */ jsxs2("text", { height: 1, bg: "transparent", children: [
2207
- /* @__PURE__ */ jsx2("span", { children: " " }),
2208
- services.length === 0 ? /* @__PURE__ */ jsx2("span", { fg: FAINT, children: "no services running" }) : services.slice(0, 2).map((service, index) => /* @__PURE__ */ jsxs2("span", { children: [
2209
- index > 0 ? /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " \xB7 " }) : null,
2210
- /* @__PURE__ */ jsx2("span", { fg: service.status === "reachable" ? INK_2 : MUTED, children: `${service.label ?? service.id.slice(0, 6)} :${service.workspacePort ?? "?"}${service.protocol === "udp" ? "u" : ""}\u2192${service.hostPort ?? "?"} ${service.status}` })
2211
- ] }, service.id)),
2212
- services.length > 2 ? /* @__PURE__ */ jsx2("span", { fg: FAINT, children: ` \xB7 +${services.length - 2} more` }) : null
2333
+ /* @__PURE__ */ jsx3("text", { height: 1, bg: "transparent", fg: FAINT, children: ` started ${timeAgo(session.createdAt)} \xB7 ${isPendingId(session.id) ? "provisioning" : session.id.slice(0, 8)}` }, "started"),
2334
+ /* @__PURE__ */ jsxs3("text", { height: 1, bg: "transparent", children: [
2335
+ /* @__PURE__ */ jsx3("span", { children: " " }),
2336
+ services.length === 0 ? /* @__PURE__ */ jsx3("span", { fg: FAINT, children: "no services running" }) : services.slice(0, 2).map((service, index) => {
2337
+ const tunnel = tunnels.find((candidate) => candidate.service.id === service.id);
2338
+ return /* @__PURE__ */ jsxs3("span", { children: [
2339
+ index > 0 ? /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " \xB7 " }) : null,
2340
+ /* @__PURE__ */ jsx3("span", { fg: service.status === "reachable" ? INK_2 : MUTED, children: tunnel === void 0 ? `${service.label ?? service.id.slice(0, 6)} :${service.workspacePort ?? "?"}${service.protocol === "udp" ? "u" : ""}\u2192${service.hostPort ?? "?"} ${service.status}` : tunnel.line })
2341
+ ] }, service.id);
2342
+ }),
2343
+ services.length > 2 ? /* @__PURE__ */ jsx3("span", { fg: FAINT, children: ` \xB7 +${services.length - 2} more` }) : null
2213
2344
  ] }, "services"),
2214
- /* @__PURE__ */ jsxs2("text", { height: 1, bg: "transparent", children: [
2215
- /* @__PURE__ */ jsx2("span", { children: " " }),
2216
- change === void 0 || change.openComments === 0 ? /* @__PURE__ */ jsx2("span", { fg: FAINT, children: "no open review comments" }) : /* @__PURE__ */ jsxs2("span", { fg: INK_2, children: [
2345
+ /* @__PURE__ */ jsxs3("text", { height: 1, bg: "transparent", children: [
2346
+ /* @__PURE__ */ jsx3("span", { children: " " }),
2347
+ change === void 0 || change.openComments === 0 ? /* @__PURE__ */ jsx3("span", { fg: FAINT, children: "no open review comments" }) : /* @__PURE__ */ jsxs3("span", { fg: INK_2, children: [
2217
2348
  change.openComments,
2218
2349
  " open comment",
2219
2350
  change.openComments === 1 ? "" : "s"
2220
2351
  ] }),
2221
- change?.pendingFollowUp === true ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
2222
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " \xB7 " }),
2223
- /* @__PURE__ */ jsx2("span", { fg: INK_2, children: "follow-up pending" })
2352
+ change?.pendingFollowUp === true ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
2353
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " \xB7 " }),
2354
+ /* @__PURE__ */ jsx3("span", { fg: INK_2, children: "follow-up pending" })
2224
2355
  ] }) : null,
2225
- change?.changeId == null ? null : /* @__PURE__ */ jsxs2(Fragment2, { children: [
2226
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " \xB7 " }),
2227
- /* @__PURE__ */ jsx2("span", { fg: MUTED, children: "v reviews the change" })
2356
+ change?.changeId == null ? null : /* @__PURE__ */ jsxs3(Fragment3, { children: [
2357
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " \xB7 " }),
2358
+ /* @__PURE__ */ jsx3("span", { fg: MUTED, children: "v reviews the change" })
2228
2359
  ] })
2229
2360
  ] }, "comments"),
2230
- /* @__PURE__ */ jsx2("text", { height: 1, bg: "transparent", fg: summary === null ? FAINT : MUTED, children: ` ${fit(summary ?? "no summary yet", 200)}` }, "summary")
2361
+ /* @__PURE__ */ jsx3("text", { height: 1, bg: "transparent", fg: summary === null ? FAINT : MUTED, children: ` ${fit(summary ?? "no summary yet", 200)}` }, "summary")
2231
2362
  ];
2232
- return /* @__PURE__ */ jsx2("box", { flexShrink: 0, flexDirection: "column", backgroundColor: "transparent", children: lines.slice(0, Math.max(0, rows)) });
2363
+ return /* @__PURE__ */ jsx3("box", { flexShrink: 0, flexDirection: "column", backgroundColor: "transparent", children: lines.slice(0, Math.max(0, rows)) });
2233
2364
  };
2234
2365
  var StatusLine = ({
2235
2366
  busy,
2236
2367
  busyStarted,
2237
2368
  status
2238
2369
  }) => {
2239
- const [now, setNow] = useState2(() => Date.now());
2240
- useEffect2(() => {
2370
+ const [now, setNow] = useState3(() => Date.now());
2371
+ useEffect3(() => {
2241
2372
  if (busy !== null) {
2242
2373
  const timer = setInterval(() => setNow(Date.now()), 1e3);
2243
2374
  return () => clearInterval(timer);
@@ -2249,7 +2380,7 @@ var StatusLine = ({
2249
2380
  return void 0;
2250
2381
  }, [busy, status]);
2251
2382
  const text = busy === null ? status !== null && Date.now() - status.at < 5e3 ? ` ${status.text}` : "" : ` ${busy} ${Math.max(0, Math.round((now - busyStarted) / 1e3))}s`;
2252
- return /* @__PURE__ */ jsx2("text", { height: 1, fg: INK_2, bg: "transparent", children: text });
2383
+ return /* @__PURE__ */ jsx3("text", { height: 1, fg: INK_2, bg: "transparent", children: text });
2253
2384
  };
2254
2385
  var errorText = (error) => error instanceof Error ? error.message : String(error);
2255
2386
  var keepSpanVisible = (scroll, top, height, viewRows) => {
@@ -2261,6 +2392,8 @@ var keepSpanVisible = (scroll, top, height, viewRows) => {
2261
2392
  var PREVIEW_MAX_LINES = 300;
2262
2393
  var SESSION_FACT_ROWS = 6;
2263
2394
  var noShare = () => "off";
2395
+ var NO_TUNNELS = [];
2396
+ var noTunnels = () => NO_TUNNELS;
2264
2397
  var App = ({ ctx, onQuit }) => {
2265
2398
  const renderer = useRenderer();
2266
2399
  const queryClient = useQueryClient2();
@@ -2271,30 +2404,35 @@ var App = ({ ctx, onQuit }) => {
2271
2404
  retry: true,
2272
2405
  retryDelay: 1e3
2273
2406
  });
2274
- const [focus, setFocusState] = useState2("sessions");
2275
- const [lastNav, setLastNav] = useState2("sessions");
2276
- const [projectKey, setProjectKey] = useState2(null);
2277
- const [worktreeKey, setWorktreeKey] = useState2(null);
2278
- const [sessionKey, setSessionKey] = useState2(null);
2279
- const [picker, setPicker] = useState2(null);
2280
- const [pickerIndex, setPickerIndex] = useState2(0);
2281
- const [busy, setBusy] = useState2(null);
2282
- const [busyStarted, setBusyStarted] = useState2(0);
2283
- const [status, setStatus] = useState2(null);
2407
+ const [focus, setFocusState] = useState3("sessions");
2408
+ const [lastNav, setLastNav] = useState3("sessions");
2409
+ const [projectKey, setProjectKey] = useState3(null);
2410
+ const [worktreeKey, setWorktreeKey] = useState3(null);
2411
+ const [sessionKey, setSessionKey] = useState3(null);
2412
+ const [picker, setPicker] = useState3(null);
2413
+ const [pickerIndex, setPickerIndex] = useState3(0);
2414
+ const [busy, setBusy] = useState3(null);
2415
+ const [busyStarted, setBusyStarted] = useState3(0);
2416
+ const [status, setStatus] = useState3(null);
2284
2417
  const shareState = useSyncExternalStore(
2285
2418
  (onChange) => ctx.agentShare?.subscribe(() => onChange()) ?? (() => {
2286
2419
  }),
2287
2420
  ctx.agentShare === null ? noShare : ctx.agentShare.snapshot
2288
2421
  );
2289
- const [editing, setEditing] = useState2(null);
2290
- const [stopArmed, setStopArmed] = useState2(null);
2291
- const [removeArmed, setRemoveArmed] = useState2(null);
2292
- const [creating, setCreating] = useState2(null);
2293
- const [adoptOffer, setAdoptOffer] = useState2(null);
2422
+ const openTunnels = useSyncExternalStore(
2423
+ (onChange) => ctx.tunnels?.subscribe(onChange) ?? (() => {
2424
+ }),
2425
+ ctx.tunnels === null ? noTunnels : ctx.tunnels.current
2426
+ );
2427
+ const [editing, setEditing] = useState3(null);
2428
+ const [stopArmed, setStopArmed] = useState3(null);
2429
+ const [removeArmed, setRemoveArmed] = useState3(null);
2430
+ const [creating, setCreating] = useState3(null);
2431
+ const [adoptOffer, setAdoptOffer] = useState3(null);
2294
2432
  const adoptOfferDecided = useRef2(false);
2295
- const [reviewing, setReviewing] = useState2(null);
2433
+ const [reviewing, setReviewing] = useState3(null);
2296
2434
  const lockRef = useRef2(false);
2297
- const [gate] = useState2(createLaunchGate);
2435
+ const [gate] = useState3(createLaunchGate);
2298
2436
  const creatingRef = useRef2(creating);
2299
2437
  creatingRef.current = creating;
2300
2438
  const branchRequest = useRef2(0);
@@ -2325,6 +2463,12 @@ var App = ({ ctx, onQuit }) => {
2325
2463
  const sectionRows = (section) => layout.sections.find((entry) => entry.section === section)?.rows ?? 0;
2326
2464
  const previewSessionId = selectedSession !== null && !isPendingId(selectedSession.id) ? selectedSession.id : null;
2327
2465
  const previewLive = selectedSession !== null && LIVE_STATUSES.has(selectedSession.status);
2466
+ useEffect3(() => {
2467
+ const tunnels = ctx.tunnels;
2468
+ if (tunnels === null) return;
2469
+ const timer = setTimeout(() => void tunnels.focus(previewSessionId), 600);
2470
+ return () => clearTimeout(timer);
2471
+ }, [ctx.tunnels, previewSessionId]);
2328
2472
  const transcript = useQuery2({
2329
2473
  queryKey: TRANSCRIPT_KEY(previewSessionId ?? "none"),
2330
2474
  queryFn: () => fetchTranscript(ctx.api, previewSessionId ?? ""),
@@ -2342,9 +2486,26 @@ var App = ({ ctx, onQuit }) => {
2342
2486
  }),
2343
2487
  [transcript.data, detailWidth]
2344
2488
  );
2345
- const [previewOffset, setPreviewOffset] = useState2(0);
2489
+ const [previewOffset, setPreviewOffset] = useState3(0);
2346
2490
  const factRows = Math.max(0, Math.min(SESSION_FACT_ROWS, layout.detailRows - 2));
2347
2491
  const showFactRule = factRows > 0 && layout.detailRows - factRows > 1;
2492
+ const waiting = selectedSession !== null && (selectedSession.status === "starting" || isPendingId(selectedSession.id));
2493
+ const snake = useSnake({
2494
+ width: Math.max(8, Math.min(40, detailWidth - 4)),
2495
+ // The pane minus the facts, the rule, the starting line, two lines of hints and the border.
2496
+ height: Math.max(4, Math.min(14, layout.detailRows - factRows - 8)),
2497
+ enabled: waiting
2498
+ });
2499
+ const [snakeAwayFor, setSnakeAwayFor] = useState3(null);
2500
+ const snakeShown = waiting && snakeAwayFor !== selectedSession?.id;
2501
+ const [snakeOverlay, setSnakeOverlay] = useState3(ctx.openSnake === true);
2502
+ const overlayWidth = Math.max(16, Math.min(60, terminalCols - 8));
2503
+ const overlayHeight = Math.max(6, Math.min(20, terminalRows - 10));
2504
+ const overlaySnake = useSnake({
2505
+ width: overlayWidth,
2506
+ height: overlayHeight,
2507
+ enabled: snakeOverlay
2508
+ });
2348
2509
  const previewRows = Math.max(1, layout.detailRows - factRows - (showFactRule ? 1 : 0));
2349
2510
  const previewView = previewWindow(preview, previewRows, previewOffset);
2350
2511
  const setFocus = (column) => {
@@ -2357,7 +2518,7 @@ var App = ({ ctx, onQuit }) => {
2357
2518
  };
2358
2519
  const say = (text) => setStatus({ text, at: Date.now() });
2359
2520
  const refetch = () => void queryClient.invalidateQueries({ queryKey: WORKBENCH_KEY });
2360
- useEffect2(() => {
2521
+ useEffect3(() => {
2361
2522
  const share = ctx.agentShare;
2362
2523
  if (share === null) return;
2363
2524
  return share.subscribe((event) => {
@@ -2368,7 +2529,7 @@ var App = ({ ctx, onQuit }) => {
2368
2529
  else if (event.kind === "not-signed") say(`\u2717 not signed \u2014 ${event.message}`);
2369
2530
  });
2370
2531
  }, [ctx.agentShare]);
2371
- useEffect2(() => {
2532
+ useEffect3(() => {
2372
2533
  if (data === void 0 || adoptOfferDecided.current) return;
2373
2534
  if (homeProject !== void 0) return;
2374
2535
  adoptOfferDecided.current = true;
@@ -2380,10 +2541,10 @@ var App = ({ ctx, onQuit }) => {
2380
2541
  const projectRows = sectionRows("projects");
2381
2542
  const worktreeRows = sectionRows("worktrees");
2382
2543
  const sessionRows = sectionRows("sessions");
2383
- useEffect2(() => {
2544
+ useEffect3(() => {
2384
2545
  keepSpanVisible(projectScrollRef.current, projectIndex, 1, projectRows);
2385
2546
  }, [projectIndex, projectRows]);
2386
- useEffect2(() => {
2547
+ useEffect3(() => {
2387
2548
  keepSpanVisible(
2388
2549
  worktreeScrollRef.current,
2389
2550
  worktreeIndex * WORKTREE_ROW_HEIGHT,
@@ -2391,7 +2552,7 @@ var App = ({ ctx, onQuit }) => {
2391
2552
  worktreeRows
2392
2553
  );
2393
2554
  }, [worktreeIndex, worktreeRows]);
2394
- useEffect2(() => {
2555
+ useEffect3(() => {
2395
2556
  keepSpanVisible(
2396
2557
  sessionScrollRef.current,
2397
2558
  sessionIndex * SESSION_ROW_HEIGHT,
@@ -2403,10 +2564,14 @@ var App = ({ ctx, onQuit }) => {
2403
2564
  const short = session.id.slice(0, 8);
2404
2565
  lockRef.current = true;
2405
2566
  renderer.suspend();
2406
- process.stdout.write(`
2567
+ const tunneled = openTunnels.filter((tunnel) => tunnel.service.sessionId === session.id).map((tunnel) => `\u25CF ${tunnel.line} \xB7 tunnel
2568
+ `).join("");
2569
+ process.stdout.write(
2570
+ `
2407
2571
  attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
2408
-
2409
- `);
2572
+ ${tunneled}
2573
+ `
2574
+ );
2410
2575
  let outcome;
2411
2576
  try {
2412
2577
  outcome = await ctx.attachTty(session.id, session.harness);
@@ -3022,6 +3187,28 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3022
3187
  if (reviewing !== null) return;
3023
3188
  if (lockRef.current) return;
3024
3189
  if (key.ctrl && key.name === "c") return onQuit();
3190
+ if (snakeOverlay) {
3191
+ if (key.name === "up" || key.name === "down" || key.name === "left" || key.name === "right") {
3192
+ overlaySnake.steer(key.name);
3193
+ } else if (key.name === "space") {
3194
+ overlaySnake.togglePause();
3195
+ } else if (key.name === "escape" || key.name === "q") {
3196
+ setSnakeOverlay(false);
3197
+ }
3198
+ return;
3199
+ }
3200
+ if (waiting && focus === "detail" && picker === null && editing === null && creating === null) {
3201
+ if (snakeShown) {
3202
+ if (key.name === "up" || key.name === "down" || key.name === "left" || key.name === "right") {
3203
+ snake.steer(key.name);
3204
+ return;
3205
+ }
3206
+ if (key.name === "space") return snake.togglePause();
3207
+ if (key.name === "escape") return setSnakeAwayFor(selectedSession?.id ?? null);
3208
+ } else if (key.name === "space") {
3209
+ return setSnakeAwayFor(null);
3210
+ }
3211
+ }
3025
3212
  const verb = verbForKey(key.name ?? "", key.shift === true);
3026
3213
  if (verb !== "stop") setStopArmed(null);
3027
3214
  if (verb !== "remove") setRemoveArmed(null);
@@ -3222,7 +3409,7 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3222
3409
  const footerText = adoptOffer === null ? editing === null ? creating === null ? picker === null ? ` ${fitHints(verbHints(focus), Math.max(12, terminalCols - 2))}` : " \u2191\u2193 move \xB7 enter start \xB7 esc cancel" : creating.step === "name" ? " enter continue \xB7 esc cancel" : creating.step === "base" ? " type to filter \xB7 \u2191\u2193 move \xB7 enter choose base \xB7 esc back" : " \u2191\u2193 move \xB7 enter launch \xB7 esc back" : " enter save \xB7 esc cancel" : " enter adopt \xB7 \u2190\u2192 auth mode \xB7 esc not now";
3223
3410
  const loadFailure = data === void 0 && failureReason !== null ? errorText(failureReason) : null;
3224
3411
  if (reviewing !== null) {
3225
- return /* @__PURE__ */ jsx2(
3412
+ return /* @__PURE__ */ jsx3(
3226
3413
  ReviewScreen,
3227
3414
  {
3228
3415
  ctx,
@@ -3258,13 +3445,13 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3258
3445
  const renderSection = (entry) => {
3259
3446
  const inner = Math.max(4, layout.sidebarWidth - 2);
3260
3447
  if (!entry.expanded) {
3261
- return /* @__PURE__ */ jsx2(
3448
+ return /* @__PURE__ */ jsx3(
3262
3449
  Pane,
3263
3450
  {
3264
3451
  title: paneTitle(entry.section, layout.sidebarWidth),
3265
3452
  focused: false,
3266
3453
  height: entry.height,
3267
- children: /* @__PURE__ */ jsx2(
3454
+ children: /* @__PURE__ */ jsx3(
3268
3455
  SummaryRow,
3269
3456
  {
3270
3457
  name: breadcrumbValue(entry.section),
@@ -3280,13 +3467,13 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3280
3467
  const focused = focus === entry.section;
3281
3468
  switch (entry.section) {
3282
3469
  case "projects":
3283
- return /* @__PURE__ */ jsx2(
3470
+ return /* @__PURE__ */ jsx3(
3284
3471
  Pane,
3285
3472
  {
3286
3473
  title: paneTitle("projects", layout.sidebarWidth),
3287
3474
  focused,
3288
3475
  grow: true,
3289
- children: /* @__PURE__ */ jsxs2(
3476
+ children: /* @__PURE__ */ jsxs3(
3290
3477
  "scrollbox",
3291
3478
  {
3292
3479
  ref: projectScrollRef,
@@ -3295,7 +3482,7 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3295
3482
  minHeight: 0,
3296
3483
  style: paneScrollStyle,
3297
3484
  children: [
3298
- projectItems.map((item, index) => /* @__PURE__ */ jsx2(
3485
+ projectItems.map((item, index) => /* @__PURE__ */ jsx3(
3299
3486
  ProjectRow,
3300
3487
  {
3301
3488
  item,
@@ -3304,7 +3491,7 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3304
3491
  },
3305
3492
  item.project.id
3306
3493
  )),
3307
- data !== void 0 && projectItems.length === 0 ? /* @__PURE__ */ jsx2(EmptyNote, { text: "none adopted yet" }) : null
3494
+ data !== void 0 && projectItems.length === 0 ? /* @__PURE__ */ jsx3(EmptyNote, { text: "none adopted yet" }) : null
3308
3495
  ]
3309
3496
  }
3310
3497
  )
@@ -3312,13 +3499,13 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3312
3499
  entry.section
3313
3500
  );
3314
3501
  case "worktrees":
3315
- return /* @__PURE__ */ jsx2(
3502
+ return /* @__PURE__ */ jsx3(
3316
3503
  Pane,
3317
3504
  {
3318
3505
  title: paneTitle("worktrees", layout.sidebarWidth),
3319
3506
  focused,
3320
3507
  grow: true,
3321
- children: /* @__PURE__ */ jsxs2(
3508
+ children: /* @__PURE__ */ jsxs3(
3322
3509
  "scrollbox",
3323
3510
  {
3324
3511
  ref: worktreeScrollRef,
@@ -3327,7 +3514,7 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3327
3514
  minHeight: 0,
3328
3515
  style: paneScrollStyle,
3329
3516
  children: [
3330
- worktreeGroups.map((group, index) => /* @__PURE__ */ jsx2(
3517
+ worktreeGroups.map((group, index) => /* @__PURE__ */ jsx3(
3331
3518
  WorktreeRow,
3332
3519
  {
3333
3520
  group,
@@ -3336,7 +3523,7 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3336
3523
  },
3337
3524
  group.key
3338
3525
  )),
3339
- data !== void 0 && worktreeGroups.length === 0 ? /* @__PURE__ */ jsx2(EmptyNote, { text: "no worktrees \u2014 w starts one" }) : null
3526
+ data !== void 0 && worktreeGroups.length === 0 ? /* @__PURE__ */ jsx3(EmptyNote, { text: "no worktrees \u2014 w starts one" }) : null
3340
3527
  ]
3341
3528
  }
3342
3529
  )
@@ -3344,13 +3531,13 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3344
3531
  entry.section
3345
3532
  );
3346
3533
  case "sessions":
3347
- return /* @__PURE__ */ jsx2(
3534
+ return /* @__PURE__ */ jsx3(
3348
3535
  Pane,
3349
3536
  {
3350
3537
  title: paneTitle("sessions", layout.sidebarWidth),
3351
3538
  focused,
3352
3539
  grow: true,
3353
- children: /* @__PURE__ */ jsxs2(
3540
+ children: /* @__PURE__ */ jsxs3(
3354
3541
  "scrollbox",
3355
3542
  {
3356
3543
  ref: sessionScrollRef,
@@ -3359,7 +3546,7 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3359
3546
  minHeight: 0,
3360
3547
  style: paneScrollStyle,
3361
3548
  children: [
3362
- sessionItems.map((item, index) => /* @__PURE__ */ jsx2(
3549
+ sessionItems.map((item, index) => /* @__PURE__ */ jsx3(
3363
3550
  SessionRow,
3364
3551
  {
3365
3552
  item,
@@ -3368,13 +3555,13 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3368
3555
  },
3369
3556
  item.session.id
3370
3557
  )),
3371
- data !== void 0 && sessionItems.length === 0 ? /* @__PURE__ */ jsx2(
3558
+ data !== void 0 && sessionItems.length === 0 ? /* @__PURE__ */ jsx3(
3372
3559
  EmptyNote,
3373
3560
  {
3374
3561
  text: selectedGroup === null ? "no worktree selected" : "no sessions \u2014 n starts one"
3375
3562
  }
3376
3563
  ) : null,
3377
- loadFailure === null ? null : /* @__PURE__ */ jsx2("text", { height: 1, fg: INK_2, bg: "transparent", children: ` ${loadFailure} \u2014 retrying` })
3564
+ loadFailure === null ? null : /* @__PURE__ */ jsx3("text", { height: 1, fg: INK_2, bg: "transparent", children: ` ${loadFailure} \u2014 retrying` })
3378
3565
  ]
3379
3566
  }
3380
3567
  )
@@ -3383,52 +3570,67 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3383
3570
  );
3384
3571
  }
3385
3572
  };
3386
- const renderDetail = () => /* @__PURE__ */ jsx2(Pane, { title: paneTitle("detail", detailWidth + 2), focused: focus === "detail", grow: true, children: selectedItem === null ? /* @__PURE__ */ jsx2(EmptyNote, { text: "no session selected \u2014 n starts one" }) : /* @__PURE__ */ jsxs2(Fragment2, { children: [
3387
- /* @__PURE__ */ jsx2(SessionFacts, { group: selectedGroup, item: selectedItem, rows: factRows }),
3388
- showFactRule ? /* @__PURE__ */ jsx2("text", { height: 1, bg: "transparent", fg: FAINT, children: ` ${"\u2500".repeat(Math.max(4, detailWidth - 4))}` }) : null,
3389
- /* @__PURE__ */ jsx2("box", { flexGrow: 1, flexShrink: 1, minHeight: 0, flexDirection: "column", children: previewSessionId === null ? /* @__PURE__ */ jsx2(EmptyNote, { text: "provisioning \u2014 no record yet" }) : selectedSession?.harness === "shell" ? /* @__PURE__ */ jsx2(EmptyNote, { text: "shell \u2014 no conversation record; a attaches if live" }) : transcript.isPending ? /* @__PURE__ */ jsx2(EmptyNote, { text: "reading the record\u2026" }) : transcript.error === null ? previewView.lines.length === 0 ? /* @__PURE__ */ jsx2(EmptyNote, { text: "no conversation recorded yet" }) : previewView.lines.map((line, index) => /* @__PURE__ */ jsx2(PreviewRow, { line }, `${index}-${line.kind}`)) : /* @__PURE__ */ jsx2("text", { height: 1, fg: INK_2, bg: "transparent", children: ` could not read the record \u2014 ${errorText(transcript.error)}` }) })
3573
+ const renderDetail = () => /* @__PURE__ */ jsx3(Pane, { title: paneTitle("detail", detailWidth + 2), focused: focus === "detail", grow: true, children: selectedItem === null ? /* @__PURE__ */ jsx3(EmptyNote, { text: "no session selected \u2014 n starts one" }) : /* @__PURE__ */ jsxs3(Fragment3, { children: [
3574
+ /* @__PURE__ */ jsx3(
3575
+ SessionFacts,
3576
+ {
3577
+ group: selectedGroup,
3578
+ item: selectedItem,
3579
+ rows: factRows,
3580
+ tunnels: openTunnels
3581
+ }
3582
+ ),
3583
+ showFactRule ? /* @__PURE__ */ jsx3("text", { height: 1, bg: "transparent", fg: FAINT, children: ` ${"\u2500".repeat(Math.max(4, detailWidth - 4))}` }) : null,
3584
+ /* @__PURE__ */ jsx3("box", { flexGrow: 1, flexShrink: 1, minHeight: 0, flexDirection: "column", children: waiting ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
3585
+ /* @__PURE__ */ jsxs3("text", { height: 1, bg: "transparent", children: [
3586
+ /* @__PURE__ */ jsx3("span", { children: " " }),
3587
+ /* @__PURE__ */ jsx3("span", { fg: INK_2, children: "starting" }),
3588
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " \xB7 the image builds, then the session boots \xB7 a first build on a new setup takes about 7 minutes" })
3589
+ ] }),
3590
+ snakeShown ? /* @__PURE__ */ jsx3(SnakeBoard, { handle: snake, focused: focus === "detail" }) : /* @__PURE__ */ jsx3(EmptyNote, { text: "snake is put away \xB7 space brings it back" })
3591
+ ] }) : previewSessionId === null ? /* @__PURE__ */ jsx3(EmptyNote, { text: "provisioning \u2014 no record yet" }) : selectedSession?.harness === "shell" ? /* @__PURE__ */ jsx3(EmptyNote, { text: "shell \u2014 no conversation record; a attaches if live" }) : transcript.isPending ? /* @__PURE__ */ jsx3(EmptyNote, { text: "reading the record\u2026" }) : transcript.error === null ? previewView.lines.length === 0 ? /* @__PURE__ */ jsx3(EmptyNote, { text: "no conversation recorded yet" }) : previewView.lines.map((line, index) => /* @__PURE__ */ jsx3(PreviewRow, { line }, `${index}-${line.kind}`)) : /* @__PURE__ */ jsx3("text", { height: 1, fg: INK_2, bg: "transparent", children: ` could not read the record \u2014 ${errorText(transcript.error)}` }) })
3390
3592
  ] }) });
3391
3593
  const offNav = layout.offscreen.filter(isNavSection);
3392
3594
  const detailOffscreen = layout.offscreen.includes("detail");
3393
- return /* @__PURE__ */ jsxs2("box", { flexGrow: 1, flexDirection: "column", backgroundColor: CANVAS, children: [
3394
- /* @__PURE__ */ jsxs2("box", { height: 1, flexDirection: "row", justifyContent: "space-between", children: [
3395
- /* @__PURE__ */ jsxs2("text", { height: 1, bg: "transparent", children: [
3396
- /* @__PURE__ */ jsx2("span", { fg: INK, children: " mend" }),
3397
- /* @__PURE__ */ jsxs2("span", { fg: MUTED, children: [
3595
+ return /* @__PURE__ */ jsxs3("box", { flexGrow: 1, flexDirection: "column", backgroundColor: CANVAS, children: [
3596
+ /* @__PURE__ */ jsxs3("box", { height: 1, flexDirection: "row", justifyContent: "space-between", children: [
3597
+ /* @__PURE__ */ jsxs3("text", { height: 1, bg: "transparent", children: [
3598
+ /* @__PURE__ */ jsx3("span", { fg: INK, children: " mend" }),
3599
+ /* @__PURE__ */ jsxs3("span", { fg: MUTED, children: [
3398
3600
  " ",
3399
3601
  projectItems.length,
3400
3602
  " project",
3401
3603
  projectItems.length === 1 ? "" : "s"
3402
3604
  ] }),
3403
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " \xB7 " }),
3404
- /* @__PURE__ */ jsxs2("span", { fg: liveTotal > 0 ? MUTED : FAINT, children: [
3605
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " \xB7 " }),
3606
+ /* @__PURE__ */ jsxs3("span", { fg: liveTotal > 0 ? MUTED : FAINT, children: [
3405
3607
  liveTotal,
3406
3608
  " live"
3407
3609
  ] }),
3408
- gate.count() > 0 ? /* @__PURE__ */ jsxs2(Fragment2, { children: [
3409
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " \xB7 " }),
3410
- /* @__PURE__ */ jsxs2("span", { fg: INK_2, children: [
3610
+ gate.count() > 0 ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
3611
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " \xB7 " }),
3612
+ /* @__PURE__ */ jsxs3("span", { fg: INK_2, children: [
3411
3613
  gate.count(),
3412
3614
  " starting"
3413
3615
  ] })
3414
3616
  ] }) : null,
3415
- shareState === "off" ? null : /* @__PURE__ */ jsxs2(Fragment2, { children: [
3416
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " \xB7 " }),
3417
- /* @__PURE__ */ jsx2("span", { fg: shareState === "connected" ? MUTED : FAINT, children: shareState === "connected" ? "agent shared" : "agent share reconnecting" })
3617
+ shareState === "off" ? null : /* @__PURE__ */ jsxs3(Fragment3, { children: [
3618
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " \xB7 " }),
3619
+ /* @__PURE__ */ jsx3("span", { fg: shareState === "connected" ? MUTED : FAINT, children: shareState === "connected" ? "agent shared" : "agent share reconnecting" })
3418
3620
  ] })
3419
3621
  ] }),
3420
- /* @__PURE__ */ jsx2("text", { height: 1, fg: FAINT, bg: "transparent", children: `${ctx.config.url} ` })
3622
+ /* @__PURE__ */ jsx3("text", { height: 1, fg: FAINT, bg: "transparent", children: `${ctx.config.url} ` })
3421
3623
  ] }),
3422
- !layout.breadcrumb ? null : /* @__PURE__ */ jsxs2("text", { height: 1, bg: "transparent", children: [
3423
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " " }),
3424
- offNav.map((column, index) => /* @__PURE__ */ jsxs2("span", { children: [
3425
- index > 0 ? /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " \u25B8 " }) : null,
3426
- /* @__PURE__ */ jsx2("span", { fg: index === offNav.length - 1 ? INK_2 : MUTED, children: fit(breadcrumbValue(column), 28) })
3624
+ !layout.breadcrumb ? null : /* @__PURE__ */ jsxs3("text", { height: 1, bg: "transparent", children: [
3625
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " " }),
3626
+ offNav.map((column, index) => /* @__PURE__ */ jsxs3("span", { children: [
3627
+ index > 0 ? /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " \u25B8 " }) : null,
3628
+ /* @__PURE__ */ jsx3("span", { fg: index === offNav.length - 1 ? INK_2 : MUTED, children: fit(breadcrumbValue(column), 28) })
3427
3629
  ] }, column)),
3428
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: detailOffscreen ? `${offNav.length > 0 ? " \xB7 " : ""}record hidden \xB7 \u2192 opens it` : " \u25B8" })
3630
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: detailOffscreen ? `${offNav.length > 0 ? " \xB7 " : ""}record hidden \xB7 \u2192 opens it` : " \u25B8" })
3429
3631
  ] }),
3430
- /* @__PURE__ */ jsxs2("box", { flexGrow: 1, flexShrink: 1, minHeight: 0, flexDirection: "row", children: [
3431
- layout.sidebarWidth === 0 ? null : /* @__PURE__ */ jsx2(
3632
+ /* @__PURE__ */ jsxs3("box", { flexGrow: 1, flexShrink: 1, minHeight: 0, flexDirection: "row", children: [
3633
+ layout.sidebarWidth === 0 ? null : /* @__PURE__ */ jsx3(
3432
3634
  "box",
3433
3635
  {
3434
3636
  width: layout.sidebarWidth,
@@ -3441,7 +3643,29 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3441
3643
  ),
3442
3644
  detailWidth === 0 ? null : renderDetail()
3443
3645
  ] }),
3444
- picker === null ? null : /* @__PURE__ */ jsx2(
3646
+ snakeOverlay ? /* @__PURE__ */ jsxs3(
3647
+ "box",
3648
+ {
3649
+ position: "absolute",
3650
+ zIndex: 13,
3651
+ left: Math.max(1, Math.floor((terminalCols - (overlayWidth + 4)) / 2)),
3652
+ top: Math.max(1, Math.floor((terminalRows - (overlayHeight + 5)) / 2)),
3653
+ width: overlayWidth + 4,
3654
+ height: overlayHeight + 5,
3655
+ border: true,
3656
+ borderStyle: "rounded",
3657
+ borderColor: ACCENT,
3658
+ title: " snake ",
3659
+ titleAlignment: "left",
3660
+ backgroundColor: SURFACE,
3661
+ flexDirection: "column",
3662
+ children: [
3663
+ /* @__PURE__ */ jsx3(SnakeHeading, { handle: overlaySnake, hint: "arrows steer \xB7 space pauses \xB7 esc closes" }),
3664
+ /* @__PURE__ */ jsx3("box", { marginLeft: 1, flexDirection: "column", children: /* @__PURE__ */ jsx3(SnakeRows, { game: overlaySnake.game }) })
3665
+ ]
3666
+ }
3667
+ ) : null,
3668
+ picker === null ? null : /* @__PURE__ */ jsx3(
3445
3669
  "box",
3446
3670
  {
3447
3671
  position: "absolute",
@@ -3457,7 +3681,7 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3457
3681
  titleAlignment: "left",
3458
3682
  backgroundColor: SURFACE,
3459
3683
  flexDirection: "column",
3460
- children: pickerItems.map((item, index) => /* @__PURE__ */ jsx2(
3684
+ children: pickerItems.map((item, index) => /* @__PURE__ */ jsx3(
3461
3685
  HarnessRow,
3462
3686
  {
3463
3687
  item,
@@ -3468,7 +3692,7 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3468
3692
  ))
3469
3693
  }
3470
3694
  ),
3471
- editing === null ? null : /* @__PURE__ */ jsx2(
3695
+ editing === null ? null : /* @__PURE__ */ jsx3(
3472
3696
  "box",
3473
3697
  {
3474
3698
  position: "absolute",
@@ -3484,7 +3708,7 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3484
3708
  backgroundColor: SURFACE,
3485
3709
  height: 3,
3486
3710
  flexShrink: 0,
3487
- children: /* @__PURE__ */ jsx2(
3711
+ children: /* @__PURE__ */ jsx3(
3488
3712
  "input",
3489
3713
  {
3490
3714
  focused: true,
@@ -3504,7 +3728,7 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3504
3728
  )
3505
3729
  }
3506
3730
  ),
3507
- adoptOffer === null ? null : /* @__PURE__ */ jsxs2(
3731
+ adoptOffer === null ? null : /* @__PURE__ */ jsxs3(
3508
3732
  "box",
3509
3733
  {
3510
3734
  position: "absolute",
@@ -3521,25 +3745,25 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3521
3745
  backgroundColor: SURFACE,
3522
3746
  flexDirection: "column",
3523
3747
  children: [
3524
- /* @__PURE__ */ jsxs2("text", { height: 1, bg: SURFACE, children: [
3525
- /* @__PURE__ */ jsx2("span", { children: " " }),
3526
- /* @__PURE__ */ jsx2("span", { fg: INK, children: adoptOffer.name }),
3527
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " \xB7 not in the store yet" })
3748
+ /* @__PURE__ */ jsxs3("text", { height: 1, bg: SURFACE, children: [
3749
+ /* @__PURE__ */ jsx3("span", { children: " " }),
3750
+ /* @__PURE__ */ jsx3("span", { fg: INK, children: adoptOffer.name }),
3751
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " \xB7 not in the store yet" })
3528
3752
  ] }),
3529
- /* @__PURE__ */ jsx2("text", { height: 1, bg: SURFACE, fg: MUTED, children: ` ${adoptOffer.source}` }),
3530
- /* @__PURE__ */ jsxs2("text", { height: 1, bg: SURFACE, children: [
3531
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " auth " }),
3532
- ADOPT_AUTH_MODES.map((candidate, index) => /* @__PURE__ */ jsxs2("span", { children: [
3533
- index > 0 ? /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " \xB7 " }) : null,
3534
- /* @__PURE__ */ jsx2("span", { fg: index === adoptOffer.modeIndex ? ACCENT : FAINT, children: index === adoptOffer.modeIndex ? `\u25B8 ${candidate.label}` : candidate.label })
3753
+ /* @__PURE__ */ jsx3("text", { height: 1, bg: SURFACE, fg: MUTED, children: ` ${adoptOffer.source}` }),
3754
+ /* @__PURE__ */ jsxs3("text", { height: 1, bg: SURFACE, children: [
3755
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " auth " }),
3756
+ ADOPT_AUTH_MODES.map((candidate, index) => /* @__PURE__ */ jsxs3("span", { children: [
3757
+ index > 0 ? /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " \xB7 " }) : null,
3758
+ /* @__PURE__ */ jsx3("span", { fg: index === adoptOffer.modeIndex ? ACCENT : FAINT, children: index === adoptOffer.modeIndex ? `\u25B8 ${candidate.label}` : candidate.label })
3535
3759
  ] }, candidate.mode))
3536
3760
  ] }),
3537
- /* @__PURE__ */ jsx2("text", { height: 1, bg: SURFACE, fg: FAINT, children: ` ${ADOPT_AUTH_MODES[adoptOffer.modeIndex]?.hint ?? ""}` }),
3538
- /* @__PURE__ */ jsx2("text", { height: 1, bg: SURFACE, fg: FAINT, children: " enter adopt \xB7 \u2190\u2192 auth mode \xB7 esc not now" })
3761
+ /* @__PURE__ */ jsx3("text", { height: 1, bg: SURFACE, fg: FAINT, children: ` ${ADOPT_AUTH_MODES[adoptOffer.modeIndex]?.hint ?? ""}` }),
3762
+ /* @__PURE__ */ jsx3("text", { height: 1, bg: SURFACE, fg: FAINT, children: " enter adopt \xB7 \u2190\u2192 auth mode \xB7 esc not now" })
3539
3763
  ]
3540
3764
  }
3541
3765
  ),
3542
- creating === null ? null : /* @__PURE__ */ jsxs2(
3766
+ creating === null ? null : /* @__PURE__ */ jsxs3(
3543
3767
  "box",
3544
3768
  {
3545
3769
  position: "absolute",
@@ -3556,14 +3780,14 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3556
3780
  backgroundColor: SURFACE,
3557
3781
  flexDirection: "column",
3558
3782
  children: [
3559
- /* @__PURE__ */ jsxs2("box", { height: 1, flexShrink: 0, flexDirection: "row", backgroundColor: SURFACE, children: [
3560
- /* @__PURE__ */ jsxs2("text", { height: 1, bg: SURFACE, children: [
3561
- /* @__PURE__ */ jsx2(Gutter, { selected: creating.step === "name" }),
3562
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: "name " }),
3563
- creating.step === "name" ? null : /* @__PURE__ */ jsx2("span", { fg: INK, children: creating.name === "" ? "auto" : creating.name }),
3564
- creating.joins ? /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " \xB7 joins the existing worktree" }) : null
3783
+ /* @__PURE__ */ jsxs3("box", { height: 1, flexShrink: 0, flexDirection: "row", backgroundColor: SURFACE, children: [
3784
+ /* @__PURE__ */ jsxs3("text", { height: 1, bg: SURFACE, children: [
3785
+ /* @__PURE__ */ jsx3(Gutter, { selected: creating.step === "name" }),
3786
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: "name " }),
3787
+ creating.step === "name" ? null : /* @__PURE__ */ jsx3("span", { fg: INK, children: creating.name === "" ? "auto" : creating.name }),
3788
+ creating.joins ? /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " \xB7 joins the existing worktree" }) : null
3565
3789
  ] }),
3566
- creating.step === "name" ? /* @__PURE__ */ jsx2(
3790
+ creating.step === "name" ? /* @__PURE__ */ jsx3(
3567
3791
  "input",
3568
3792
  {
3569
3793
  focused: true,
@@ -3588,13 +3812,13 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3588
3812
  }
3589
3813
  ) : null
3590
3814
  ] }),
3591
- /* @__PURE__ */ jsxs2("box", { height: 1, flexShrink: 0, flexDirection: "row", backgroundColor: SURFACE, children: [
3592
- /* @__PURE__ */ jsxs2("text", { height: 1, bg: SURFACE, children: [
3593
- /* @__PURE__ */ jsx2(Gutter, { selected: creating.step === "base" }),
3594
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: "base " }),
3595
- creating.step === "base" ? null : /* @__PURE__ */ jsx2("span", { fg: creating.step === "name" && !creating.joins ? FAINT : INK, children: creating.joins ? "fixed by the existing worktree" : creating.base ?? "default branch" })
3815
+ /* @__PURE__ */ jsxs3("box", { height: 1, flexShrink: 0, flexDirection: "row", backgroundColor: SURFACE, children: [
3816
+ /* @__PURE__ */ jsxs3("text", { height: 1, bg: SURFACE, children: [
3817
+ /* @__PURE__ */ jsx3(Gutter, { selected: creating.step === "base" }),
3818
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: "base " }),
3819
+ creating.step === "base" ? null : /* @__PURE__ */ jsx3("span", { fg: creating.step === "name" && !creating.joins ? FAINT : INK, children: creating.joins ? "fixed by the existing worktree" : creating.base ?? "default branch" })
3596
3820
  ] }),
3597
- creating.step === "base" && creating.branches !== null ? /* @__PURE__ */ jsx2(
3821
+ creating.step === "base" && creating.branches !== null ? /* @__PURE__ */ jsx3(
3598
3822
  "input",
3599
3823
  {
3600
3824
  focused: true,
@@ -3622,7 +3846,7 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3622
3846
  const active = creating.step === "base";
3623
3847
  if (branch === void 0) {
3624
3848
  const notice = creating.joins ? null : baseStepNotice(creating);
3625
- return /* @__PURE__ */ jsx2(
3849
+ return /* @__PURE__ */ jsx3(
3626
3850
  "text",
3627
3851
  {
3628
3852
  height: 1,
@@ -3634,42 +3858,42 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3634
3858
  );
3635
3859
  }
3636
3860
  const highlighted = active && index === creating.baseIndex;
3637
- return /* @__PURE__ */ jsx2(
3861
+ return /* @__PURE__ */ jsx3(
3638
3862
  "box",
3639
3863
  {
3640
3864
  height: 1,
3641
3865
  flexShrink: 0,
3642
3866
  backgroundColor: highlighted ? WASH : SURFACE,
3643
- children: /* @__PURE__ */ jsxs2("text", { height: 1, bg: highlighted ? WASH : SURFACE, children: [
3644
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " " }),
3645
- /* @__PURE__ */ jsx2(Gutter, { selected: highlighted }),
3646
- /* @__PURE__ */ jsx2("span", { fg: active ? INK : FAINT, children: branch.name.slice(0, 40).padEnd(41) }),
3647
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: branch.sha.slice(0, 8).padEnd(10) }),
3648
- /* @__PURE__ */ jsx2("span", { fg: active ? MUTED : FAINT, children: shortAge(branch.committedAt).padEnd(6) }),
3649
- branch.isDefault ? /* @__PURE__ */ jsx2("span", { fg: FAINT, children: "default" }) : null
3867
+ children: /* @__PURE__ */ jsxs3("text", { height: 1, bg: highlighted ? WASH : SURFACE, children: [
3868
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " " }),
3869
+ /* @__PURE__ */ jsx3(Gutter, { selected: highlighted }),
3870
+ /* @__PURE__ */ jsx3("span", { fg: active ? INK : FAINT, children: branch.name.slice(0, 40).padEnd(41) }),
3871
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: branch.sha.slice(0, 8).padEnd(10) }),
3872
+ /* @__PURE__ */ jsx3("span", { fg: active ? MUTED : FAINT, children: shortAge(branch.committedAt).padEnd(6) }),
3873
+ branch.isDefault ? /* @__PURE__ */ jsx3("span", { fg: FAINT, children: "default" }) : null
3650
3874
  ] })
3651
3875
  },
3652
3876
  branch.name
3653
3877
  );
3654
3878
  }),
3655
- /* @__PURE__ */ jsxs2("text", { height: 1, bg: SURFACE, children: [
3656
- /* @__PURE__ */ jsx2(Gutter, { selected: creating.step === "harness" }),
3657
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: "harness" })
3879
+ /* @__PURE__ */ jsxs3("text", { height: 1, bg: SURFACE, children: [
3880
+ /* @__PURE__ */ jsx3(Gutter, { selected: creating.step === "harness" }),
3881
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: "harness" })
3658
3882
  ] }),
3659
3883
  deriveHarnesses(null).map((item, index) => {
3660
3884
  const active = creating.step === "harness";
3661
3885
  const highlighted = active && index === creating.harnessIndex;
3662
- return /* @__PURE__ */ jsx2(
3886
+ return /* @__PURE__ */ jsx3(
3663
3887
  "box",
3664
3888
  {
3665
3889
  height: 1,
3666
3890
  flexShrink: 0,
3667
3891
  backgroundColor: highlighted ? WASH : SURFACE,
3668
- children: /* @__PURE__ */ jsxs2("text", { height: 1, bg: highlighted ? WASH : SURFACE, children: [
3669
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: " " }),
3670
- /* @__PURE__ */ jsx2(Gutter, { selected: highlighted }),
3671
- /* @__PURE__ */ jsx2("span", { fg: active ? INK : FAINT, children: item.label.padEnd(12) }),
3672
- /* @__PURE__ */ jsx2("span", { fg: FAINT, children: active ? item.hint : "" })
3892
+ children: /* @__PURE__ */ jsxs3("text", { height: 1, bg: highlighted ? WASH : SURFACE, children: [
3893
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: " " }),
3894
+ /* @__PURE__ */ jsx3(Gutter, { selected: highlighted }),
3895
+ /* @__PURE__ */ jsx3("span", { fg: active ? INK : FAINT, children: item.label.padEnd(12) }),
3896
+ /* @__PURE__ */ jsx3("span", { fg: FAINT, children: active ? item.hint : "" })
3673
3897
  ] })
3674
3898
  },
3675
3899
  String(item.harness)
@@ -3678,8 +3902,8 @@ attached \xB7 ${session.harness} \xB7 ${short} \xB7 detach: Ctrl+]
3678
3902
  ]
3679
3903
  }
3680
3904
  ),
3681
- loadFailure === null ? /* @__PURE__ */ jsx2(StatusLine, { busy, busyStarted, status }) : /* @__PURE__ */ jsx2("text", { height: 1, fg: ERROR, bg: "transparent", children: ` could not load workbench \u2014 ${loadFailure} \xB7 retrying` }),
3682
- /* @__PURE__ */ jsx2("text", { height: 1, fg: FAINT, bg: "transparent", children: footerText })
3905
+ loadFailure === null ? /* @__PURE__ */ jsx3(StatusLine, { busy, busyStarted, status }) : /* @__PURE__ */ jsx3("text", { height: 1, fg: ERROR, bg: "transparent", children: ` could not load workbench \u2014 ${loadFailure} \xB7 retrying` }),
3906
+ /* @__PURE__ */ jsx3("text", { height: 1, fg: FAINT, bg: "transparent", children: footerText })
3683
3907
  ] });
3684
3908
  };
3685
3909
  var runDashboard = async (ctx) => {
@@ -3743,7 +3967,7 @@ var runDashboard = async (ctx) => {
3743
3967
  };
3744
3968
  void watch();
3745
3969
  createRoot(renderer).render(
3746
- /* @__PURE__ */ jsx2(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx2(App, { ctx, onQuit: quit }) })
3970
+ /* @__PURE__ */ jsx3(QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsx3(App, { ctx, onQuit: quit }) })
3747
3971
  );
3748
3972
  await new Promise((resolve) => {
3749
3973
  renderer.once(CliRenderEvents.DESTROY, () => resolve());