@cestoliv/wt 0.4.0-pr16.gca5d1db → 0.4.0-pr17.gdfeea81

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.
@@ -3,8 +3,8 @@ import {
3
3
  openConfiguredIde,
4
4
  prepareWorktree,
5
5
  promptExistingWorktree
6
- } from "./chunk-ASVHQXDJ.js";
7
- import "./chunk-E2IOE23G.js";
6
+ } from "./chunk-AZACVCCB.js";
7
+ import "./chunk-P7WRUHUZ.js";
8
8
  import "./chunk-FNAMNRUH.js";
9
9
 
10
10
  // src/commands/agent.ts
@@ -13,7 +13,7 @@ import {
13
13
  runCommands,
14
14
  runRepoPicker,
15
15
  setUpstreamTracking
16
- } from "./chunk-E2IOE23G.js";
16
+ } from "./chunk-P7WRUHUZ.js";
17
17
  import {
18
18
  createStore,
19
19
  getEffectiveConfig
@@ -253,37 +253,56 @@ function shortenPath(p) {
253
253
  const home = process.env.HOME ?? "";
254
254
  return home && p.startsWith(home) ? `~${p.slice(home.length)}` : p;
255
255
  }
256
- function renderList(items, selectedIndex, query, mode) {
257
- const lines = [];
256
+ function buildListLayout(items, selectedIndex, query, mode) {
257
+ const header = [];
258
258
  if (mode === "global") {
259
- lines.push(
259
+ header.push(
260
260
  pc.dim("\u2139 Not in a git repository \u2014 showing all registered worktrees")
261
261
  );
262
- lines.push("");
262
+ header.push("");
263
263
  }
264
- lines.push(pc.cyan(`> ${query}_`));
265
- lines.push("");
264
+ header.push(pc.cyan(`> ${query}_`));
265
+ const body = [];
266
+ const itemSpans = [];
266
267
  const groups = groupByRepo(items);
267
268
  let i = 0;
268
269
  for (const [repoPath, groupItems] of groups) {
269
- lines.push(pc.bold(path2.basename(repoPath).toUpperCase()));
270
+ body.push(pc.bold(path2.basename(repoPath).toUpperCase()));
270
271
  for (const item of groupItems) {
272
+ const start = body.length;
271
273
  const cursor = i === selectedIndex ? pc.cyan("\u25B6") : " ";
272
274
  const branchLabel = item.isCurrent ? pc.dim(`${item.branch} (current)`) : pc.white(item.branch);
273
275
  const pathLabel = pc.dim(shortenPath(item.path));
274
- lines.push(` ${cursor} ${branchLabel} ${pathLabel}`);
276
+ body.push(` ${cursor} ${branchLabel} ${pathLabel}`);
275
277
  if (item.lastCommit) {
276
- lines.push(` ${pc.dim(item.lastCommit)}`);
278
+ body.push(` ${pc.dim(item.lastCommit)}`);
277
279
  }
280
+ itemSpans[i] = { start, end: body.length - 1 };
278
281
  i++;
279
282
  }
280
283
  }
281
- lines.push("");
282
284
  const createHint = mode === "repo" ? " \xB7 C create" : "";
283
- lines.push(
285
+ const footer = [
284
286
  pc.dim(`\u2195 navigate \xB7 Enter open \xB7 D delete${createHint} \xB7 Q quit`)
285
- );
286
- return lines.join("\n");
287
+ ];
288
+ return { header, body, footer, itemSpans };
289
+ }
290
+ function clampScroll(offset, span, viewportHeight, bodyLength) {
291
+ const maxOffset = Math.max(0, bodyLength - viewportHeight);
292
+ let next = offset;
293
+ if (span.start < next) next = span.start;
294
+ if (span.end >= next + viewportHeight) next = span.end - viewportHeight + 1;
295
+ return Math.max(0, Math.min(next, maxOffset));
296
+ }
297
+ function composeView(layout, offset, viewportHeight) {
298
+ const { header, body, footer } = layout;
299
+ const visible = body.slice(offset, offset + viewportHeight);
300
+ const topSlot = offset > 0 ? pc.dim(" \u2191 more") : "";
301
+ const bottomSlot = offset + viewportHeight < body.length ? pc.dim(" \u2193 more") : "";
302
+ return [...header, topSlot, ...visible, bottomSlot, ...footer].join("\n");
303
+ }
304
+ function fixedHeight(layout) {
305
+ return layout.header.length + layout.footer.length + 2;
287
306
  }
288
307
  function setupRawMode() {
289
308
  process.stdin.setRawMode(true);
@@ -435,10 +454,21 @@ async function runBranchInput(repoRoot) {
435
454
  async function runInteractiveList(allItems, mode, handlers) {
436
455
  let query = "";
437
456
  let selectedIndex = 0;
457
+ let scrollOffset = 0;
438
458
  let filtered = allItems;
439
459
  const render = () => {
460
+ const rows = process.stdout.rows ?? 24;
461
+ const layout = buildListLayout(filtered, selectedIndex, query, mode);
462
+ const viewport = Math.max(1, rows - fixedHeight(layout));
463
+ const span = layout.itemSpans[selectedIndex] ?? { start: 0, end: 0 };
464
+ scrollOffset = clampScroll(
465
+ scrollOffset,
466
+ span,
467
+ viewport,
468
+ layout.body.length
469
+ );
440
470
  process.stdout.write("\x1B[2J\x1B[H");
441
- process.stdout.write(renderList(filtered, selectedIndex, query, mode));
471
+ process.stdout.write(composeView(layout, scrollOffset, viewport));
442
472
  };
443
473
  setupRawMode();
444
474
  render();
@@ -447,11 +477,13 @@ async function runInteractiveList(allItems, mode, handlers) {
447
477
  const attachListener = () => {
448
478
  if (!listenerActive) {
449
479
  process.stdin.on("data", onData);
480
+ process.stdout.on("resize", render);
450
481
  listenerActive = true;
451
482
  }
452
483
  };
453
484
  const detachListener = () => {
454
485
  process.stdin.removeListener("data", onData);
486
+ process.stdout.removeListener("resize", render);
455
487
  listenerActive = false;
456
488
  };
457
489
  const onData = async (key) => {
@@ -513,11 +545,13 @@ async function runInteractiveList(allItems, mode, handlers) {
513
545
  query = query.slice(0, -1);
514
546
  filtered = filterItems(allItems, query);
515
547
  selectedIndex = 0;
548
+ scrollOffset = 0;
516
549
  render();
517
550
  } else if (key.length === 1 && key >= " ") {
518
551
  query += key;
519
552
  filtered = filterItems(allItems, query);
520
553
  selectedIndex = 0;
554
+ scrollOffset = 0;
521
555
  render();
522
556
  }
523
557
  } catch (err) {
package/dist/cli.js CHANGED
@@ -3,12 +3,12 @@
3
3
  // src/cli.ts
4
4
  import { Command } from "commander";
5
5
  var program = new Command();
6
- program.name("wt").description("Git worktree manager").version("0.4.0-pr16.gca5d1db").action(async () => {
7
- const { runList } = await import("./list-HIKXMDHJ.js");
6
+ program.name("wt").description("Git worktree manager").version("0.4.0-pr17.gdfeea81").action(async () => {
7
+ const { runList } = await import("./list-R74HQ6IX.js");
8
8
  await runList();
9
9
  });
10
10
  program.command("create [branch]").description("Create a new worktree").action(async (branch) => {
11
- const { createWorktree } = await import("./create-YBHDJOP5.js");
11
+ const { createWorktree } = await import("./create-FIUUAIUE.js");
12
12
  await createWorktree(branch);
13
13
  });
14
14
  program.command("agent <branch> <plan_prompt>").description("Create a worktree and auto-start an AI agent in Zed (macOS)").option(
@@ -17,7 +17,7 @@ program.command("agent <branch> <plan_prompt>").description("Create a worktree a
17
17
  "plan"
18
18
  ).action(
19
19
  async (branch, planPrompt, options) => {
20
- const { createAgentWorktree } = await import("./agent-WO3XIT4H.js");
20
+ const { createAgentWorktree } = await import("./agent-WC6RLKIW.js");
21
21
  await createAgentWorktree(branch, planPrompt, { mode: options.mode });
22
22
  }
23
23
  );
@@ -4,8 +4,8 @@ import {
4
4
  openConfiguredIde,
5
5
  prepareWorktree,
6
6
  promptExistingWorktree
7
- } from "./chunk-ASVHQXDJ.js";
8
- import "./chunk-E2IOE23G.js";
7
+ } from "./chunk-AZACVCCB.js";
8
+ import "./chunk-P7WRUHUZ.js";
9
9
  import "./chunk-FNAMNRUH.js";
10
10
  export {
11
11
  createWorktree,
@@ -9,7 +9,7 @@ import {
9
9
  removeWorktree,
10
10
  runCommands,
11
11
  runInteractiveList
12
- } from "./chunk-E2IOE23G.js";
12
+ } from "./chunk-P7WRUHUZ.js";
13
13
  import {
14
14
  createStore,
15
15
  getEffectiveConfig
@@ -125,7 +125,7 @@ ${dirty.map((f) => ` ${f}`).join("\n")}`
125
125
  },
126
126
  onCreate: async () => {
127
127
  if (repoRoot) {
128
- const { createWorktree } = await import("./create-YBHDJOP5.js");
128
+ const { createWorktree } = await import("./create-FIUUAIUE.js");
129
129
  await createWorktree(void 0, { cwd: repoRoot, store });
130
130
  }
131
131
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cestoliv/wt",
3
- "version": "0.4.0-pr16.gca5d1db",
3
+ "version": "0.4.0-pr17.gdfeea81",
4
4
  "description": "Fast, interactive TUI to browse, create, open, and delete git worktrees across repos.",
5
5
  "repository": {
6
6
  "type": "git",