clawt 2.19.0 → 2.20.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 CHANGED
@@ -567,8 +567,14 @@ var CLEAR_SCREEN = "\x1B[2J";
567
567
  var CURSOR_HOME = "\x1B[H";
568
568
 
569
569
  // src/constants/prompt.ts
570
+ import chalk from "chalk";
570
571
  var SELECT_ALL_NAME = "__select_all__";
571
572
  var SELECT_ALL_LABEL = "[select-all]";
573
+ var GROUP_SELECT_ALL_PREFIX = "__group_select_all_";
574
+ var GROUP_SELECT_ALL_LABEL = (dateLabel) => `[select-all: ${dateLabel}]`;
575
+ var GROUP_SEPARATOR_LABEL = (dateLabel, relativeTime) => `\u2550\u2550\u2550\u2550 ${chalk.bold.hex("#FF8C00")(dateLabel)}\uFF08${chalk.hex("#FF8C00")(relativeTime)}\uFF09 \u2550\u2550\u2550\u2550`;
576
+ var UNKNOWN_DATE_GROUP = "\u672A\u77E5\u65E5\u671F";
577
+ var UNKNOWN_DATE_SEPARATOR_LABEL = `\u2550\u2550\u2550\u2550 ${chalk.bold.hex("#FF8C00")("\u672A\u77E5\u65E5\u671F")} \u2550\u2550\u2550\u2550`;
572
578
 
573
579
  // src/errors/index.ts
574
580
  var ClawtError = class extends Error {
@@ -588,7 +594,7 @@ var ClawtError = class extends Error {
588
594
  // src/logger/index.ts
589
595
  import winston from "winston";
590
596
  import DailyRotateFile from "winston-daily-rotate-file";
591
- import chalk from "chalk";
597
+ import chalk2 from "chalk";
592
598
  import { existsSync, mkdirSync } from "fs";
593
599
  if (!existsSync(LOGS_DIR)) {
594
600
  mkdirSync(LOGS_DIR, { recursive: true });
@@ -613,13 +619,13 @@ var logger = winston.createLogger({
613
619
  transports: [dailyRotateTransport]
614
620
  });
615
621
  var LEVEL_COLORS = {
616
- error: chalk.red,
617
- warn: chalk.yellow,
618
- info: chalk.cyan,
619
- debug: chalk.gray
622
+ error: chalk2.red,
623
+ warn: chalk2.yellow,
624
+ info: chalk2.cyan,
625
+ debug: chalk2.gray
620
626
  };
621
627
  function colorizeLevel(level) {
622
- const colorFn = LEVEL_COLORS[level] || chalk.white;
628
+ const colorFn = LEVEL_COLORS[level] || chalk2.white;
623
629
  return colorFn(level.toUpperCase().padEnd(5));
624
630
  }
625
631
  function enableConsoleTransport() {
@@ -630,7 +636,7 @@ function enableConsoleTransport() {
630
636
  return;
631
637
  }
632
638
  const consoleFormat = winston.format.printf(({ level, message, timestamp }) => {
633
- return `${chalk.gray(timestamp)} ${colorizeLevel(level)} ${message}`;
639
+ return `${chalk2.gray(timestamp)} ${colorizeLevel(level)} ${message}`;
634
640
  });
635
641
  const consoleTransport = new winston.transports.Console({
636
642
  level: "debug",
@@ -898,22 +904,22 @@ function getBranchCreatedAt(branchName, cwd) {
898
904
  }
899
905
 
900
906
  // src/utils/formatter.ts
901
- import chalk2 from "chalk";
907
+ import chalk3 from "chalk";
902
908
  import { createInterface } from "readline";
903
909
  function printSuccess(message) {
904
- console.log(chalk2.green(message));
910
+ console.log(chalk3.green(message));
905
911
  }
906
912
  function printError(message) {
907
- console.error(chalk2.red(`\u2717 ${message}`));
913
+ console.error(chalk3.red(`\u2717 ${message}`));
908
914
  }
909
915
  function printWarning(message) {
910
- console.log(chalk2.yellow(`\u26A0 ${message}`));
916
+ console.log(chalk3.yellow(`\u26A0 ${message}`));
911
917
  }
912
918
  function printInfo(message) {
913
919
  console.log(message);
914
920
  }
915
921
  function printHint(message) {
916
- console.log(chalk2.hex("#FF8C00")(message));
922
+ console.log(chalk3.hex("#FF8C00")(message));
917
923
  }
918
924
  function printSeparator() {
919
925
  console.log(MESSAGES.SEPARATOR);
@@ -934,7 +940,7 @@ function confirmAction(question) {
934
940
  });
935
941
  }
936
942
  function confirmDestructiveAction(dangerousCommand, description) {
937
- printWarning(`\u5373\u5C06\u6267\u884C ${chalk2.red.bold(dangerousCommand)}\uFF0C${description}`);
943
+ printWarning(`\u5373\u5C06\u6267\u884C ${chalk3.red.bold(dangerousCommand)}\uFF0C${description}`);
938
944
  return confirmAction("\u662F\u5426\u7EE7\u7EED\uFF1F");
939
945
  }
940
946
  function isWorktreeIdle(status) {
@@ -942,17 +948,17 @@ function isWorktreeIdle(status) {
942
948
  }
943
949
  function formatWorktreeStatus(status) {
944
950
  const parts = [];
945
- parts.push(chalk2.yellow(`${status.commitCount} \u4E2A\u63D0\u4EA4`));
951
+ parts.push(chalk3.yellow(`${status.commitCount} \u4E2A\u63D0\u4EA4`));
946
952
  if (status.insertions === 0 && status.deletions === 0) {
947
953
  parts.push("\u65E0\u53D8\u66F4");
948
954
  } else {
949
955
  const diffParts = [];
950
- diffParts.push(chalk2.green(`+${status.insertions}`));
951
- diffParts.push(chalk2.red(`-${status.deletions}`));
956
+ diffParts.push(chalk3.green(`+${status.insertions}`));
957
+ diffParts.push(chalk3.red(`-${status.deletions}`));
952
958
  parts.push(diffParts.join(" "));
953
959
  }
954
960
  if (status.hasDirtyFiles) {
955
- parts.push(chalk2.gray("(\u672A\u63D0\u4EA4\u4FEE\u6539)"));
961
+ parts.push(chalk3.gray("(\u672A\u63D0\u4EA4\u4FEE\u6539)"));
956
962
  }
957
963
  return parts.join(" ");
958
964
  }
@@ -1454,6 +1460,7 @@ function removeProjectSnapshots(projectName) {
1454
1460
 
1455
1461
  // src/utils/worktree-matcher.ts
1456
1462
  import Enquirer2 from "enquirer";
1463
+ import { statSync as statSync3 } from "fs";
1457
1464
  function findExactMatch(worktrees, branchName) {
1458
1465
  return worktrees.find((wt) => wt.branch === branchName);
1459
1466
  }
@@ -1558,9 +1565,142 @@ async function resolveTargetWorktree(worktrees, messages, branchName) {
1558
1565
  const allBranches = worktrees.map((wt) => wt.branch);
1559
1566
  throw new ClawtError(messages.noMatch(branchName, allBranches));
1560
1567
  }
1568
+ function formatLocalDate(date) {
1569
+ const year = date.getFullYear();
1570
+ const month = String(date.getMonth() + 1).padStart(2, "0");
1571
+ const day = String(date.getDate()).padStart(2, "0");
1572
+ return `${year}-${month}-${day}`;
1573
+ }
1574
+ function getWorktreeCreatedDate(dirPath) {
1575
+ try {
1576
+ const stat = statSync3(dirPath);
1577
+ return formatLocalDate(stat.birthtime);
1578
+ } catch {
1579
+ return null;
1580
+ }
1581
+ }
1582
+ function formatRelativeDate(dateStr) {
1583
+ const today = formatLocalDate(/* @__PURE__ */ new Date());
1584
+ const todayMs = new Date(today).getTime();
1585
+ const targetMs = new Date(dateStr).getTime();
1586
+ const diffDays = Math.round((todayMs - targetMs) / (1e3 * 60 * 60 * 24));
1587
+ if (diffDays === 0) return "\u4ECA\u5929";
1588
+ if (diffDays === 1) return "\u6628\u5929";
1589
+ if (diffDays < 30) return `${diffDays} \u5929\u524D`;
1590
+ if (diffDays < 365) {
1591
+ const months = Math.floor(diffDays / 30);
1592
+ return `${months} \u4E2A\u6708\u524D`;
1593
+ }
1594
+ const years = Math.floor(diffDays / 365);
1595
+ return `${years} \u5E74\u524D`;
1596
+ }
1597
+ function groupWorktreesByDate(worktrees) {
1598
+ const groups = /* @__PURE__ */ new Map();
1599
+ for (const wt of worktrees) {
1600
+ const dateKey = getWorktreeCreatedDate(wt.path) ?? UNKNOWN_DATE_GROUP;
1601
+ if (!groups.has(dateKey)) {
1602
+ groups.set(dateKey, []);
1603
+ }
1604
+ groups.get(dateKey).push(wt);
1605
+ }
1606
+ const sortedEntries = [...groups.entries()].sort((a, b) => {
1607
+ if (a[0] === UNKNOWN_DATE_GROUP) return 1;
1608
+ if (b[0] === UNKNOWN_DATE_GROUP) return -1;
1609
+ return b[0].localeCompare(a[0]);
1610
+ });
1611
+ return new Map(sortedEntries);
1612
+ }
1613
+ function buildGroupedChoices(groups) {
1614
+ const choices = [];
1615
+ choices.push({ name: SELECT_ALL_NAME, message: SELECT_ALL_LABEL });
1616
+ for (const [dateKey, worktreeList] of groups) {
1617
+ if (dateKey === UNKNOWN_DATE_GROUP) {
1618
+ choices.push({ role: "separator", message: UNKNOWN_DATE_SEPARATOR_LABEL });
1619
+ } else {
1620
+ const relativeTime = formatRelativeDate(dateKey);
1621
+ choices.push({ role: "separator", message: GROUP_SEPARATOR_LABEL(dateKey, relativeTime) });
1622
+ }
1623
+ const groupSelectAllName = `${GROUP_SELECT_ALL_PREFIX}${dateKey}`;
1624
+ choices.push({ name: groupSelectAllName, message: GROUP_SELECT_ALL_LABEL(dateKey) });
1625
+ for (const wt of worktreeList) {
1626
+ choices.push({ name: wt.branch, message: wt.branch });
1627
+ }
1628
+ }
1629
+ return choices;
1630
+ }
1631
+ function buildGroupMembershipMap(groups) {
1632
+ const map = /* @__PURE__ */ new Map();
1633
+ for (const [dateKey, worktreeList] of groups) {
1634
+ const groupSelectAllName = `${GROUP_SELECT_ALL_PREFIX}${dateKey}`;
1635
+ map.set(groupSelectAllName, worktreeList.map((wt) => wt.branch));
1636
+ }
1637
+ return map;
1638
+ }
1639
+ async function promptGroupedMultiSelectBranches(worktrees, message) {
1640
+ const groups = groupWorktreesByDate(worktrees);
1641
+ const choices = buildGroupedChoices(groups);
1642
+ const groupMembershipMap = buildGroupMembershipMap(groups);
1643
+ const groupSelectAllNames = new Set(groupMembershipMap.keys());
1644
+ const allBranchNames = new Set(worktrees.map((wt) => wt.branch));
1645
+ const MultiSelect = Enquirer2.MultiSelect;
1646
+ class MultiSelectWithGroupSelectAll extends MultiSelect {
1647
+ space() {
1648
+ if (!this.focused) return;
1649
+ const focusedName = this.focused.name;
1650
+ if (focusedName === SELECT_ALL_NAME) {
1651
+ const willEnable = !this.focused.enabled;
1652
+ for (const ch of this.choices) {
1653
+ ch.enabled = willEnable;
1654
+ }
1655
+ return this.render();
1656
+ }
1657
+ if (groupSelectAllNames.has(focusedName)) {
1658
+ const willEnable = !this.focused.enabled;
1659
+ const memberNames = groupMembershipMap.get(focusedName);
1660
+ this.focused.enabled = willEnable;
1661
+ for (const ch of this.choices) {
1662
+ if (memberNames.includes(ch.name)) {
1663
+ ch.enabled = willEnable;
1664
+ }
1665
+ }
1666
+ syncGlobalSelectAll(this.choices);
1667
+ return this.render();
1668
+ }
1669
+ this.toggle(this.focused);
1670
+ syncGroupSelectAll(this.choices, focusedName);
1671
+ syncGlobalSelectAll(this.choices);
1672
+ return this.render();
1673
+ }
1674
+ }
1675
+ function syncGlobalSelectAll(choiceList) {
1676
+ const selectAllChoice = choiceList.find((ch) => ch.name === SELECT_ALL_NAME);
1677
+ if (!selectAllChoice) return;
1678
+ const branchItems = choiceList.filter((ch) => allBranchNames.has(ch.name));
1679
+ selectAllChoice.enabled = branchItems.length > 0 && branchItems.every((ch) => ch.enabled);
1680
+ }
1681
+ function syncGroupSelectAll(choiceList, branchName) {
1682
+ for (const [groupName, memberNames] of groupMembershipMap) {
1683
+ if (!memberNames.includes(branchName)) continue;
1684
+ const groupChoice = choiceList.find((ch) => ch.name === groupName);
1685
+ if (!groupChoice) continue;
1686
+ const memberChoices = choiceList.filter((ch) => memberNames.includes(ch.name));
1687
+ groupChoice.enabled = memberChoices.length > 0 && memberChoices.every((ch) => ch.enabled);
1688
+ break;
1689
+ }
1690
+ }
1691
+ const selectedBranches = await new MultiSelectWithGroupSelectAll({
1692
+ message,
1693
+ choices,
1694
+ // 使用空心圆/实心圆作为选中指示符
1695
+ symbols: {
1696
+ indicator: { on: "\u25CF", off: "\u25CB" }
1697
+ }
1698
+ }).run();
1699
+ return worktrees.filter((wt) => selectedBranches.includes(wt.branch));
1700
+ }
1561
1701
 
1562
1702
  // src/utils/progress-render.ts
1563
- import chalk3 from "chalk";
1703
+ import chalk4 from "chalk";
1564
1704
  import stringWidth from "string-width";
1565
1705
  var ANSI_RESET = "\x1B[0m";
1566
1706
  function truncateToTerminalWidth(text, maxWidth) {
@@ -1597,23 +1737,23 @@ function renderTaskLine(task, total, maxPathWidth, spinnerChar) {
1597
1737
  const pathStr = task.path.padEnd(maxPathWidth);
1598
1738
  switch (task.status) {
1599
1739
  case "pending": {
1600
- return `${indexStr} ${pathStr} ${chalk3.gray(TASK_STATUS_ICONS.PENDING)} ${chalk3.gray(TASK_STATUS_LABELS.PENDING)}`;
1740
+ return `${indexStr} ${pathStr} ${chalk4.gray(TASK_STATUS_ICONS.PENDING)} ${chalk4.gray(TASK_STATUS_LABELS.PENDING)}`;
1601
1741
  }
1602
1742
  case "running": {
1603
1743
  const elapsed = formatDuration(Date.now() - task.startedAt);
1604
- const detail = task.activity ? ` ${chalk3.dim(task.activity)}` : "";
1605
- return `${indexStr} ${pathStr} ${chalk3.cyan(spinnerChar)} ${chalk3.cyan(TASK_STATUS_LABELS.RUNNING)} ${chalk3.gray(elapsed)}${detail}`;
1744
+ const detail = task.activity ? ` ${chalk4.dim(task.activity)}` : "";
1745
+ return `${indexStr} ${pathStr} ${chalk4.cyan(spinnerChar)} ${chalk4.cyan(TASK_STATUS_LABELS.RUNNING)} ${chalk4.gray(elapsed)}${detail}`;
1606
1746
  }
1607
1747
  case "done": {
1608
1748
  const duration = task.durationMs != null ? formatDuration(task.durationMs) : "N/A";
1609
1749
  const cost = task.costUsd != null ? `$${task.costUsd.toFixed(2)}` : "";
1610
- const preview = task.resultPreview ? ` ${chalk3.dim(task.resultPreview)}` : "";
1611
- return `${indexStr} ${pathStr} ${chalk3.green(TASK_STATUS_ICONS.DONE)} ${chalk3.green(TASK_STATUS_LABELS.DONE)} ${chalk3.gray(duration)} ${chalk3.yellow(cost)}${preview}`;
1750
+ const preview = task.resultPreview ? ` ${chalk4.dim(task.resultPreview)}` : "";
1751
+ return `${indexStr} ${pathStr} ${chalk4.green(TASK_STATUS_ICONS.DONE)} ${chalk4.green(TASK_STATUS_LABELS.DONE)} ${chalk4.gray(duration)} ${chalk4.yellow(cost)}${preview}`;
1612
1752
  }
1613
1753
  case "failed": {
1614
1754
  const duration = task.durationMs != null ? formatDuration(task.durationMs) : "N/A";
1615
- const preview = task.resultPreview ? ` ${chalk3.dim(task.resultPreview)}` : "";
1616
- return `${indexStr} ${pathStr} ${chalk3.red(TASK_STATUS_ICONS.FAILED)} ${chalk3.red(TASK_STATUS_LABELS.FAILED)} ${chalk3.gray(duration)}${preview}`;
1755
+ const preview = task.resultPreview ? ` ${chalk4.dim(task.resultPreview)}` : "";
1756
+ return `${indexStr} ${pathStr} ${chalk4.red(TASK_STATUS_ICONS.FAILED)} ${chalk4.red(TASK_STATUS_LABELS.FAILED)} ${chalk4.gray(duration)}${preview}`;
1617
1757
  }
1618
1758
  }
1619
1759
  }
@@ -1623,10 +1763,10 @@ function renderSummaryLine(tasks, total) {
1623
1763
  const failed = tasks.filter((t) => t.status === "failed").length;
1624
1764
  const pending = tasks.filter((t) => t.status === "pending").length;
1625
1765
  const parts = [];
1626
- if (running > 0) parts.push(chalk3.cyan(`${running}/${total} ${TASK_STATUS_LABELS.RUNNING}`));
1627
- if (done > 0) parts.push(chalk3.green(`${done}/${total} ${TASK_STATUS_LABELS.DONE}`));
1628
- if (failed > 0) parts.push(chalk3.red(`${failed}/${total} ${TASK_STATUS_LABELS.FAILED}`));
1629
- if (pending > 0) parts.push(chalk3.gray(`${pending}/${total} ${TASK_STATUS_LABELS.PENDING}`));
1766
+ if (running > 0) parts.push(chalk4.cyan(`${running}/${total} ${TASK_STATUS_LABELS.RUNNING}`));
1767
+ if (done > 0) parts.push(chalk4.green(`${done}/${total} ${TASK_STATUS_LABELS.DONE}`));
1768
+ if (failed > 0) parts.push(chalk4.red(`${failed}/${total} ${TASK_STATUS_LABELS.FAILED}`));
1769
+ if (pending > 0) parts.push(chalk4.gray(`${pending}/${total} ${TASK_STATUS_LABELS.PENDING}`));
1630
1770
  return `[${parts.join(", ")}]`;
1631
1771
  }
1632
1772
 
@@ -2241,7 +2381,7 @@ async function executeBatchTasks(worktrees, tasks, concurrency) {
2241
2381
  }
2242
2382
 
2243
2383
  // src/utils/dry-run.ts
2244
- import chalk4 from "chalk";
2384
+ import chalk5 from "chalk";
2245
2385
  import { join as join6 } from "path";
2246
2386
  var DRY_RUN_TASK_DESC_MAX_LENGTH = 80;
2247
2387
  function truncateTaskDesc(task) {
@@ -2255,7 +2395,7 @@ function printDryRunPreview(branchNames, tasks, concurrency) {
2255
2395
  const projectDir = getProjectWorktreeDir();
2256
2396
  const isInteractive = tasks.length === 0;
2257
2397
  printDoubleSeparator();
2258
- printInfo(` ${chalk4.bold(MESSAGES.DRY_RUN_TITLE)}`);
2398
+ printInfo(` ${chalk5.bold(MESSAGES.DRY_RUN_TITLE)}`);
2259
2399
  printDoubleSeparator();
2260
2400
  const summaryParts = [
2261
2401
  MESSAGES.DRY_RUN_TASK_COUNT(branchNames.length),
@@ -2265,7 +2405,7 @@ function printDryRunPreview(branchNames, tasks, concurrency) {
2265
2405
  if (isInteractive) {
2266
2406
  summaryParts.push(MESSAGES.DRY_RUN_INTERACTIVE_MODE);
2267
2407
  }
2268
- printInfo(summaryParts.join(chalk4.gray(" \u2502 ")));
2408
+ printInfo(summaryParts.join(chalk5.gray(" \u2502 ")));
2269
2409
  printSeparator();
2270
2410
  let hasConflict = false;
2271
2411
  for (let i = 0; i < branchNames.length; i++) {
@@ -2275,21 +2415,21 @@ function printDryRunPreview(branchNames, tasks, concurrency) {
2275
2415
  if (exists) hasConflict = true;
2276
2416
  const indexLabel = `[${i + 1}/${branchNames.length}]`;
2277
2417
  if (exists) {
2278
- printInfo(`${chalk4.yellow("\u26A0")} ${indexLabel} ${chalk4.yellow(branch)} ${chalk4.gray("\u2014")} ${chalk4.yellow(MESSAGES.DRY_RUN_BRANCH_EXISTS_WARNING(branch))}`);
2418
+ printInfo(`${chalk5.yellow("\u26A0")} ${indexLabel} ${chalk5.yellow(branch)} ${chalk5.gray("\u2014")} ${chalk5.yellow(MESSAGES.DRY_RUN_BRANCH_EXISTS_WARNING(branch))}`);
2279
2419
  } else {
2280
- printInfo(`${chalk4.green("\u2713")} ${indexLabel} ${chalk4.cyan(branch)}`);
2420
+ printInfo(`${chalk5.green("\u2713")} ${indexLabel} ${chalk5.cyan(branch)}`);
2281
2421
  }
2282
- printInfo(` ${chalk4.gray("\u8DEF\u5F84:")} ${worktreePath}`);
2422
+ printInfo(` ${chalk5.gray("\u8DEF\u5F84:")} ${worktreePath}`);
2283
2423
  if (!isInteractive) {
2284
- printInfo(` ${chalk4.gray("\u4EFB\u52A1:")} ${truncateTaskDesc(tasks[i])}`);
2424
+ printInfo(` ${chalk5.gray("\u4EFB\u52A1:")} ${truncateTaskDesc(tasks[i])}`);
2285
2425
  }
2286
2426
  printInfo("");
2287
2427
  }
2288
2428
  printDoubleSeparator();
2289
2429
  if (hasConflict) {
2290
- printInfo(chalk4.yellow(`\u26A0 ${MESSAGES.DRY_RUN_HAS_CONFLICT}`));
2430
+ printInfo(chalk5.yellow(`\u26A0 ${MESSAGES.DRY_RUN_HAS_CONFLICT}`));
2291
2431
  } else {
2292
- printInfo(chalk4.green(`\u2713 ${MESSAGES.DRY_RUN_READY}`));
2432
+ printInfo(chalk5.green(`\u2713 ${MESSAGES.DRY_RUN_READY}`));
2293
2433
  }
2294
2434
  }
2295
2435
 
@@ -2307,7 +2447,7 @@ function applyAliases(program2, aliases) {
2307
2447
  }
2308
2448
 
2309
2449
  // src/utils/config-strategy.ts
2310
- import chalk5 from "chalk";
2450
+ import chalk6 from "chalk";
2311
2451
  import Enquirer3 from "enquirer";
2312
2452
  function isValidConfigKey(key) {
2313
2453
  return key in DEFAULT_CONFIG;
@@ -2351,9 +2491,9 @@ async function promptConfigValue(key, currentValue) {
2351
2491
  }
2352
2492
  function formatConfigValue(value) {
2353
2493
  if (typeof value === "boolean") {
2354
- return value ? chalk5.green("true") : chalk5.yellow("false");
2494
+ return value ? chalk6.green("true") : chalk6.yellow("false");
2355
2495
  }
2356
- return chalk5.cyan(String(value));
2496
+ return chalk6.cyan(String(value));
2357
2497
  }
2358
2498
  async function promptBooleanValue(key, currentValue) {
2359
2499
  const choices = [
@@ -2400,7 +2540,7 @@ async function promptStringValue(key, currentValue) {
2400
2540
  import { readFileSync as readFileSync4, writeFileSync as writeFileSync3 } from "fs";
2401
2541
  import { execSync as execSync3 } from "child_process";
2402
2542
  import { request } from "https";
2403
- import chalk6 from "chalk";
2543
+ import chalk7 from "chalk";
2404
2544
  import stringWidth2 from "string-width";
2405
2545
  function readUpdateCache() {
2406
2546
  try {
@@ -2475,12 +2615,12 @@ function detectPackageManager() {
2475
2615
  }
2476
2616
  function printUpdateNotification(currentVersion, latestVersion) {
2477
2617
  const updateText = UPDATE_MESSAGES.UPDATE_AVAILABLE(
2478
- chalk6.red(currentVersion),
2479
- chalk6.green(latestVersion)
2618
+ chalk7.red(currentVersion),
2619
+ chalk7.green(latestVersion)
2480
2620
  );
2481
2621
  const pm = detectPackageManager();
2482
2622
  const updateCommand = UPDATE_COMMANDS[pm] || UPDATE_COMMANDS.npm;
2483
- const commandText = UPDATE_MESSAGES.UPDATE_HINT(chalk6.cyan(updateCommand));
2623
+ const commandText = UPDATE_MESSAGES.UPDATE_HINT(chalk7.cyan(updateCommand));
2484
2624
  const updateTextWidth = stringWidth2(updateText);
2485
2625
  const commandTextWidth = stringWidth2(commandText);
2486
2626
  const innerWidth = Math.max(updateTextWidth, commandTextWidth) + 4;
@@ -2528,7 +2668,7 @@ async function checkForUpdates(currentVersion) {
2528
2668
  }
2529
2669
 
2530
2670
  // src/commands/list.ts
2531
- import chalk7 from "chalk";
2671
+ import chalk8 from "chalk";
2532
2672
  function registerListCommand(program2) {
2533
2673
  program2.command("list").description("\u5217\u51FA\u5F53\u524D\u9879\u76EE\u6240\u6709 worktree").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").action((options) => {
2534
2674
  handleList(options);
@@ -2565,12 +2705,12 @@ function printListAsText(projectName, worktrees) {
2565
2705
  for (const wt of worktrees) {
2566
2706
  const status = getWorktreeStatus(wt);
2567
2707
  const isIdle = status ? isWorktreeIdle(status) : false;
2568
- const pathDisplay = isIdle ? chalk7.hex("#FF8C00")(wt.path) : wt.path;
2708
+ const pathDisplay = isIdle ? chalk8.hex("#FF8C00")(wt.path) : wt.path;
2569
2709
  printInfo(` ${pathDisplay} [${wt.branch}]`);
2570
2710
  if (status) {
2571
2711
  printInfo(` ${formatWorktreeStatus(status)}`);
2572
2712
  } else {
2573
- printInfo(` ${chalk7.yellow(MESSAGES.WORKTREE_STATUS_UNAVAILABLE)}`);
2713
+ printInfo(` ${chalk8.yellow(MESSAGES.WORKTREE_STATUS_UNAVAILABLE)}`);
2574
2714
  }
2575
2715
  printInfo("");
2576
2716
  }
@@ -2778,7 +2918,12 @@ async function handleResume(options) {
2778
2918
  validateClaudeCodeInstalled();
2779
2919
  logger.info(`resume \u547D\u4EE4\u6267\u884C\uFF0C\u5206\u652F\u8FC7\u6EE4: ${options.branch ?? "(\u65E0)"}`);
2780
2920
  const worktrees = getProjectWorktrees();
2781
- const targetWorktrees = await resolveTargetWorktrees(worktrees, RESUME_RESOLVE_MESSAGES, options.branch);
2921
+ let targetWorktrees;
2922
+ if (!options.branch && worktrees.length > 1) {
2923
+ targetWorktrees = await promptGroupedMultiSelectBranches(worktrees, RESUME_RESOLVE_MESSAGES.selectBranch);
2924
+ } else {
2925
+ targetWorktrees = await resolveTargetWorktrees(worktrees, RESUME_RESOLVE_MESSAGES, options.branch);
2926
+ }
2782
2927
  if (targetWorktrees.length === 0) {
2783
2928
  return;
2784
2929
  }
@@ -3253,7 +3398,7 @@ async function handleMerge(options) {
3253
3398
  }
3254
3399
 
3255
3400
  // src/commands/config.ts
3256
- import chalk8 from "chalk";
3401
+ import chalk9 from "chalk";
3257
3402
  import Enquirer5 from "enquirer";
3258
3403
  function registerConfigCommand(program2) {
3259
3404
  const configCmd = program2.command("config").description("\u4EA4\u4E92\u5F0F\u67E5\u770B\u548C\u4FEE\u6539\u5168\u5C40\u914D\u7F6E").action(async () => {
@@ -3314,7 +3459,7 @@ async function handleInteractiveConfigSet() {
3314
3459
  const isObject = typeof DEFAULT_CONFIG[k] === "object";
3315
3460
  return {
3316
3461
  name: k,
3317
- message: `${k}: ${isObject ? chalk8.dim(JSON.stringify(config2[k])) : formatConfigValue(config2[k])} ${chalk8.dim(`\u2014 ${CONFIG_DESCRIPTIONS[k]}`)}`,
3462
+ message: `${k}: ${isObject ? chalk9.dim(JSON.stringify(config2[k])) : formatConfigValue(config2[k])} ${chalk9.dim(`\u2014 ${CONFIG_DESCRIPTIONS[k]}`)}`,
3318
3463
  ...isObject && { disabled: CONFIG_ALIAS_DISABLED_HINT }
3319
3464
  };
3320
3465
  });
@@ -3369,7 +3514,7 @@ async function handleReset() {
3369
3514
  }
3370
3515
 
3371
3516
  // src/commands/status.ts
3372
- import chalk9 from "chalk";
3517
+ import chalk10 from "chalk";
3373
3518
  function registerStatusCommand(program2) {
3374
3519
  program2.command("status").description("\u663E\u793A\u9879\u76EE\u5168\u5C40\u72B6\u6001\u603B\u89C8").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").action((options) => {
3375
3520
  handleStatus(options);
@@ -3482,7 +3627,7 @@ function printStatusAsJson(result) {
3482
3627
  }
3483
3628
  function printStatusAsText(result) {
3484
3629
  printDoubleSeparator();
3485
- printInfo(` ${chalk9.bold.cyan(MESSAGES.STATUS_TITLE(result.main.projectName))}`);
3630
+ printInfo(` ${chalk10.bold.cyan(MESSAGES.STATUS_TITLE(result.main.projectName))}`);
3486
3631
  printDoubleSeparator();
3487
3632
  printInfo("");
3488
3633
  printMainSection(result.main);
@@ -3495,17 +3640,17 @@ function printStatusAsText(result) {
3495
3640
  printDoubleSeparator();
3496
3641
  }
3497
3642
  function printMainSection(main2) {
3498
- printInfo(` ${chalk9.bold("\u25C6")} ${chalk9.bold(MESSAGES.STATUS_MAIN_SECTION)}`);
3499
- printInfo(` \u5206\u652F: ${chalk9.bold(main2.branch)}`);
3643
+ printInfo(` ${chalk10.bold("\u25C6")} ${chalk10.bold(MESSAGES.STATUS_MAIN_SECTION)}`);
3644
+ printInfo(` \u5206\u652F: ${chalk10.bold(main2.branch)}`);
3500
3645
  if (main2.isClean) {
3501
- printInfo(` \u72B6\u6001: ${chalk9.green("\u2713 \u5E72\u51C0")}`);
3646
+ printInfo(` \u72B6\u6001: ${chalk10.green("\u2713 \u5E72\u51C0")}`);
3502
3647
  } else {
3503
- printInfo(` \u72B6\u6001: ${chalk9.yellow("\u2717 \u6709\u672A\u63D0\u4EA4\u4FEE\u6539")}`);
3648
+ printInfo(` \u72B6\u6001: ${chalk10.yellow("\u2717 \u6709\u672A\u63D0\u4EA4\u4FEE\u6539")}`);
3504
3649
  }
3505
3650
  printInfo("");
3506
3651
  }
3507
3652
  function printWorktreesSection(worktrees, total) {
3508
- printInfo(` ${chalk9.bold("\u25C6")} ${chalk9.bold(MESSAGES.STATUS_WORKTREES_SECTION)} (${total} \u4E2A)`);
3653
+ printInfo(` ${chalk10.bold("\u25C6")} ${chalk10.bold(MESSAGES.STATUS_WORKTREES_SECTION)} (${total} \u4E2A)`);
3509
3654
  printInfo("");
3510
3655
  if (worktrees.length === 0) {
3511
3656
  printInfo(` ${MESSAGES.STATUS_NO_WORKTREES}`);
@@ -3517,56 +3662,56 @@ function printWorktreesSection(worktrees, total) {
3517
3662
  }
3518
3663
  function printWorktreeItem(wt) {
3519
3664
  const statusLabel = formatChangeStatusLabel(wt.changeStatus);
3520
- printInfo(` ${chalk9.bold("\u25CF")} ${chalk9.bold(wt.branch)} [${statusLabel}]`);
3665
+ printInfo(` ${chalk10.bold("\u25CF")} ${chalk10.bold(wt.branch)} [${statusLabel}]`);
3521
3666
  if (wt.insertions > 0 || wt.deletions > 0) {
3522
- printInfo(` ${chalk9.green(`+${wt.insertions}`)} ${chalk9.red(`-${wt.deletions}`)}`);
3667
+ printInfo(` ${chalk10.green(`+${wt.insertions}`)} ${chalk10.red(`-${wt.deletions}`)}`);
3523
3668
  }
3524
3669
  if (wt.commitsAhead > 0) {
3525
- printInfo(` ${chalk9.yellow(`${wt.commitsAhead} \u4E2A\u672C\u5730\u63D0\u4EA4`)}`);
3670
+ printInfo(` ${chalk10.yellow(`${wt.commitsAhead} \u4E2A\u672C\u5730\u63D0\u4EA4`)}`);
3526
3671
  }
3527
3672
  if (wt.commitsBehind > 0) {
3528
- printInfo(` ${chalk9.yellow(`\u843D\u540E\u4E3B\u5206\u652F ${wt.commitsBehind} \u4E2A\u63D0\u4EA4`)}`);
3673
+ printInfo(` ${chalk10.yellow(`\u843D\u540E\u4E3B\u5206\u652F ${wt.commitsBehind} \u4E2A\u63D0\u4EA4`)}`);
3529
3674
  } else {
3530
- printInfo(` ${chalk9.green("\u4E0E\u4E3B\u5206\u652F\u540C\u6B65")}`);
3675
+ printInfo(` ${chalk10.green("\u4E0E\u4E3B\u5206\u652F\u540C\u6B65")}`);
3531
3676
  }
3532
3677
  if (wt.createdAt) {
3533
3678
  const relativeTime = formatRelativeTime(wt.createdAt);
3534
3679
  if (relativeTime) {
3535
- printInfo(` ${chalk9.gray(MESSAGES.STATUS_CREATED_AT(relativeTime))}`);
3680
+ printInfo(` ${chalk10.gray(MESSAGES.STATUS_CREATED_AT(relativeTime))}`);
3536
3681
  }
3537
3682
  }
3538
3683
  if (wt.snapshotTime) {
3539
3684
  const relativeTime = formatRelativeTime(wt.snapshotTime);
3540
3685
  if (relativeTime) {
3541
- printInfo(` ${chalk9.green(MESSAGES.STATUS_LAST_VALIDATED(relativeTime))}`);
3686
+ printInfo(` ${chalk10.green(MESSAGES.STATUS_LAST_VALIDATED(relativeTime))}`);
3542
3687
  }
3543
3688
  } else {
3544
- printInfo(` ${chalk9.red(MESSAGES.STATUS_NOT_VALIDATED)}`);
3689
+ printInfo(` ${chalk10.red(MESSAGES.STATUS_NOT_VALIDATED)}`);
3545
3690
  }
3546
3691
  printInfo("");
3547
3692
  }
3548
3693
  function formatChangeStatusLabel(status) {
3549
3694
  switch (status) {
3550
3695
  case "committed":
3551
- return chalk9.green(MESSAGES.STATUS_CHANGE_COMMITTED);
3696
+ return chalk10.green(MESSAGES.STATUS_CHANGE_COMMITTED);
3552
3697
  case "uncommitted":
3553
- return chalk9.yellow(MESSAGES.STATUS_CHANGE_UNCOMMITTED);
3698
+ return chalk10.yellow(MESSAGES.STATUS_CHANGE_UNCOMMITTED);
3554
3699
  case "conflict":
3555
- return chalk9.red(MESSAGES.STATUS_CHANGE_CONFLICT);
3700
+ return chalk10.red(MESSAGES.STATUS_CHANGE_CONFLICT);
3556
3701
  case "clean":
3557
- return chalk9.gray(MESSAGES.STATUS_CHANGE_CLEAN);
3702
+ return chalk10.gray(MESSAGES.STATUS_CHANGE_CLEAN);
3558
3703
  }
3559
3704
  }
3560
3705
  function printSnapshotsSection(snapshots) {
3561
- printInfo(` ${chalk9.bold("\u25C6")} ${chalk9.bold(MESSAGES.STATUS_SNAPSHOTS_SECTION)} (${snapshots.total} \u4E2A)`);
3706
+ printInfo(` ${chalk10.bold("\u25C6")} ${chalk10.bold(MESSAGES.STATUS_SNAPSHOTS_SECTION)} (${snapshots.total} \u4E2A)`);
3562
3707
  if (snapshots.orphaned > 0) {
3563
- printInfo(` ${chalk9.yellow(MESSAGES.STATUS_SNAPSHOT_ORPHANED(snapshots.orphaned))}`);
3708
+ printInfo(` ${chalk10.yellow(MESSAGES.STATUS_SNAPSHOT_ORPHANED(snapshots.orphaned))}`);
3564
3709
  }
3565
3710
  printInfo("");
3566
3711
  }
3567
3712
 
3568
3713
  // src/commands/alias.ts
3569
- import chalk10 from "chalk";
3714
+ import chalk11 from "chalk";
3570
3715
  function getRegisteredCommandNames(program2) {
3571
3716
  return program2.commands.map((cmd) => cmd.name());
3572
3717
  }
@@ -3587,7 +3732,7 @@ ${MESSAGES.ALIAS_LIST_TITLE}
3587
3732
  `);
3588
3733
  printSeparator();
3589
3734
  for (const [alias, command] of entries) {
3590
- printInfo(` ${chalk10.bold(alias)} \u2192 ${chalk10.cyan(command)}`);
3735
+ printInfo(` ${chalk11.bold(alias)} \u2192 ${chalk11.cyan(command)}`);
3591
3736
  }
3592
3737
  printInfo("");
3593
3738
  printSeparator();
@@ -3634,9 +3779,9 @@ function registerAliasCommand(program2) {
3634
3779
  }
3635
3780
 
3636
3781
  // src/commands/projects.ts
3637
- import { existsSync as existsSync9, readdirSync as readdirSync5, statSync as statSync3 } from "fs";
3782
+ import { existsSync as existsSync9, readdirSync as readdirSync5, statSync as statSync4 } from "fs";
3638
3783
  import { join as join7 } from "path";
3639
- import chalk11 from "chalk";
3784
+ import chalk12 from "chalk";
3640
3785
  function registerProjectsCommand(program2) {
3641
3786
  program2.command("projects [name]").description("\u5C55\u793A\u6240\u6709\u9879\u76EE\u7684 worktree \u6982\u89C8\uFF0C\u6216\u67E5\u770B\u6307\u5B9A\u9879\u76EE\u7684 worktree \u8BE6\u60C5").option("--json", "\u4EE5 JSON \u683C\u5F0F\u8F93\u51FA").action((name, options) => {
3642
3787
  handleProjects({ name, json: options.json });
@@ -3728,7 +3873,7 @@ function collectProjectDetail(name, projectDir) {
3728
3873
  };
3729
3874
  }
3730
3875
  function collectSingleWorktreeDetail(branch, wtPath) {
3731
- const stat = statSync3(wtPath);
3876
+ const stat = statSync4(wtPath);
3732
3877
  const diskUsage = calculateDirSize(wtPath);
3733
3878
  return {
3734
3879
  branch,
@@ -3738,10 +3883,10 @@ function collectSingleWorktreeDetail(branch, wtPath) {
3738
3883
  };
3739
3884
  }
3740
3885
  function resolveProjectLastActiveTime(projectDir, worktreePaths) {
3741
- let latestTime = statSync3(projectDir).mtime;
3886
+ let latestTime = statSync4(projectDir).mtime;
3742
3887
  for (const wtPath of worktreePaths) {
3743
3888
  try {
3744
- const wtStat = statSync3(wtPath);
3889
+ const wtStat = statSync4(wtPath);
3745
3890
  if (wtStat.mtime > latestTime) {
3746
3891
  latestTime = wtStat.mtime;
3747
3892
  }
@@ -3755,7 +3900,7 @@ function sortByLastActiveTimeDesc(projects) {
3755
3900
  }
3756
3901
  function printProjectsOverviewAsText(result) {
3757
3902
  printDoubleSeparator();
3758
- printInfo(` ${chalk11.bold.cyan(MESSAGES.PROJECTS_OVERVIEW_TITLE)}`);
3903
+ printInfo(` ${chalk12.bold.cyan(MESSAGES.PROJECTS_OVERVIEW_TITLE)}`);
3759
3904
  printDoubleSeparator();
3760
3905
  printInfo("");
3761
3906
  if (result.projects.length === 0) {
@@ -3769,7 +3914,7 @@ function printProjectsOverviewAsText(result) {
3769
3914
  }
3770
3915
  printSeparator();
3771
3916
  printInfo("");
3772
- printInfo(` \u5171 ${chalk11.bold(String(result.totalProjects))} \u4E2A\u9879\u76EE ${chalk11.gray(MESSAGES.PROJECTS_TOTAL_DISK_USAGE(formatDiskSize(result.totalDiskUsage)))}`);
3917
+ printInfo(` \u5171 ${chalk12.bold(String(result.totalProjects))} \u4E2A\u9879\u76EE ${chalk12.gray(MESSAGES.PROJECTS_TOTAL_DISK_USAGE(formatDiskSize(result.totalDiskUsage)))}`);
3773
3918
  printInfo("");
3774
3919
  printDoubleSeparator();
3775
3920
  }
@@ -3777,16 +3922,16 @@ function printProjectOverviewItem(project) {
3777
3922
  const relativeTime = formatRelativeTime(project.lastActiveTime);
3778
3923
  const activeLabel = relativeTime ? MESSAGES.PROJECTS_LAST_ACTIVE(relativeTime) : "";
3779
3924
  const diskLabel = MESSAGES.PROJECTS_DISK_USAGE(formatDiskSize(project.diskUsage));
3780
- printInfo(` ${chalk11.bold("\u25CF")} ${chalk11.bold(project.name)}`);
3781
- printInfo(` ${MESSAGES.PROJECTS_WORKTREE_COUNT(project.worktreeCount)} ${chalk11.gray(activeLabel)} ${chalk11.gray(diskLabel)}`);
3925
+ printInfo(` ${chalk12.bold("\u25CF")} ${chalk12.bold(project.name)}`);
3926
+ printInfo(` ${MESSAGES.PROJECTS_WORKTREE_COUNT(project.worktreeCount)} ${chalk12.gray(activeLabel)} ${chalk12.gray(diskLabel)}`);
3782
3927
  printInfo("");
3783
3928
  }
3784
3929
  function printProjectDetailAsText(result) {
3785
3930
  printDoubleSeparator();
3786
- printInfo(` ${chalk11.bold.cyan(MESSAGES.PROJECTS_DETAIL_TITLE(result.name))}`);
3931
+ printInfo(` ${chalk12.bold.cyan(MESSAGES.PROJECTS_DETAIL_TITLE(result.name))}`);
3787
3932
  printDoubleSeparator();
3788
3933
  printInfo("");
3789
- printInfo(` ${chalk11.bold("\u25C6")} ${chalk11.bold(MESSAGES.PROJECTS_PATH(result.projectDir))}`);
3934
+ printInfo(` ${chalk12.bold("\u25C6")} ${chalk12.bold(MESSAGES.PROJECTS_PATH(result.projectDir))}`);
3790
3935
  printInfo(` ${MESSAGES.PROJECTS_TOTAL_DISK_USAGE(formatDiskSize(result.totalDiskUsage))}`);
3791
3936
  printInfo("");
3792
3937
  printSeparator();
@@ -3806,9 +3951,9 @@ function printWorktreeDetailItem(wt) {
3806
3951
  const relativeTime = formatRelativeTime(wt.lastModifiedTime);
3807
3952
  const modifiedLabel = relativeTime ? MESSAGES.PROJECTS_LAST_MODIFIED(relativeTime) : "";
3808
3953
  const diskLabel = MESSAGES.PROJECTS_DISK_USAGE(formatDiskSize(wt.diskUsage));
3809
- printInfo(` ${chalk11.bold("\u25CF")} ${chalk11.bold(wt.branch)}`);
3954
+ printInfo(` ${chalk12.bold("\u25CF")} ${chalk12.bold(wt.branch)}`);
3810
3955
  printInfo(` ${wt.path}`);
3811
- printInfo(` ${chalk11.gray(modifiedLabel)} ${chalk11.gray(diskLabel)}`);
3956
+ printInfo(` ${chalk12.gray(modifiedLabel)} ${chalk12.gray(diskLabel)}`);
3812
3957
  printInfo("");
3813
3958
  }
3814
3959
 
@@ -3864,7 +4009,7 @@ compdef _clawt_completion clawt
3864
4009
  }
3865
4010
 
3866
4011
  // src/utils/completion-engine.ts
3867
- import { existsSync as existsSync10, readdirSync as readdirSync6, statSync as statSync4 } from "fs";
4012
+ import { existsSync as existsSync10, readdirSync as readdirSync6, statSync as statSync5 } from "fs";
3868
4013
  import { join as join8, dirname, basename as basename2 } from "path";
3869
4014
  function completeFilePath(partial) {
3870
4015
  const cwd = process.cwd();
@@ -3882,7 +4027,7 @@ function completeFilePath(partial) {
3882
4027
  if (entry.startsWith(".")) continue;
3883
4028
  const fullPath = join8(searchDir, entry);
3884
4029
  try {
3885
- const stat = statSync4(fullPath);
4030
+ const stat = statSync5(fullPath);
3886
4031
  if (stat.isDirectory()) {
3887
4032
  results.push(dirPrefix + entry + "/");
3888
4033
  } else if (stat.isFile()) {