sync-worktrees 4.1.0 → 4.2.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/README.md CHANGED
@@ -31,6 +31,8 @@ The default — **worktree mode** — gives every remote branch its own director
31
31
  - Fetches latest changes (no merge — your local work stays untouched).
32
32
  - Removes directories for branches deleted upstream (preserves dirty trees and unpushed commits).
33
33
 
34
+ The bare repository is not an extra object store layered on top — it is the single Git database every worktree attaches to natively, so branches share history for free (no `--reference`, no alternates). The bare layout exists only so that no branch is a privileged "main" checkout: every branch, the default included, is a peer directory.
35
+
34
36
  Smallest config that produces this:
35
37
 
36
38
  ```javascript
@@ -1 +1 @@
1
- {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"BranchCreationWizard.d.ts","sourceRoot":"","sources":["../../src/components/BranchCreationWizard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAOjF,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtE,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzD,uBAAuB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACnD,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,mBAAmB,EAAE,CACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,KACf,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtE,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,KAAK,IAAI,CAAC;CACZ;AAED,QAAA,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CA8d7D,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
1
+ {"version":3,"file":"BranchCreationWizard.d.ts","sourceRoot":"","sources":["../../src/components/BranchCreationWizard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAOjF,MAAM,WAAW,yBAAyB;IACxC,YAAY,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtE,kBAAkB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IACzD,uBAAuB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACnD,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChD,mBAAmB,EAAE,CACnB,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,KACf,OAAO,CAAC;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtE,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE;QAC1B,SAAS,EAAE,MAAM,CAAC;QAClB,UAAU,EAAE,MAAM,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,KAAK,IAAI,CAAC;CACZ;AAED,QAAA,MAAM,oBAAoB,EAAE,KAAK,CAAC,EAAE,CAAC,yBAAyB,CA0e7D,CAAC;AAEF,eAAe,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"OpenEditorWizard.d.ts","sourceRoot":"","sources":["../../src/components/OpenEditorWizard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAKjF,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE/C,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtE,mBAAmB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACzF,oBAAoB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrF,sBAAsB,EAAE,CACtB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,KACf;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,QAAA,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CA6TrD,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
1
+ {"version":3,"file":"OpenEditorWizard.d.ts","sourceRoot":"","sources":["../../src/components/OpenEditorWizard.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAKjF,MAAM,MAAM,UAAU,GAAG,UAAU,GAAG,QAAQ,CAAC;AAE/C,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACtE,mBAAmB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC,CAAC;IACzF,oBAAoB,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACrF,sBAAsB,EAAE,CACtB,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,KACf;QAAE,OAAO,EAAE,OAAO,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED,QAAA,MAAM,gBAAgB,EAAE,KAAK,CAAC,EAAE,CAAC,qBAAqB,CAuUrD,CAAC;AAEF,eAAe,gBAAgB,CAAC"}
@@ -3,6 +3,7 @@ import type { AppSyncProgress } from "../utils/app-events";
3
3
  export interface StatusBarProps {
4
4
  status: "idle" | "syncing";
5
5
  syncProgressEntries?: AppSyncProgress[];
6
+ activeOps?: string[];
6
7
  maxProgressLines?: number;
7
8
  repositoryCount: number;
8
9
  lastSyncTime: Date | null;
@@ -1 +1 @@
1
- {"version":3,"file":"StatusBar.d.ts","sourceRoot":"","sources":["../../src/components/StatusBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,mBAAmB,CAAC,EAAE,eAAe,EAAE,CAAC;IACxC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,QAAA,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CA6GvC,CAAC;AAEF,eAAe,SAAS,CAAC"}
1
+ {"version":3,"file":"StatusBar.d.ts","sourceRoot":"","sources":["../../src/components/StatusBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAE3D,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,mBAAmB,CAAC,EAAE,eAAe,EAAE,CAAC;IACxC,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;IACrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,IAAI,GAAG,IAAI,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,QAAA,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAgHvC,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"WorktreeStatusView.d.ts","sourceRoot":"","sources":["../../src/components/WorktreeStatusView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAIjF,OAAO,KAAK,EACV,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAGlB,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAIpC,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,mBAAmB,EAAE,CAAC;IACpC,wBAAwB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAC5E,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACzE,6BAA6B,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC;IACpF,uBAAuB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AA2GD,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAyhBzD,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
1
+ {"version":3,"file":"WorktreeStatusView.d.ts","sourceRoot":"","sources":["../../src/components/WorktreeStatusView.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA4D,MAAM,OAAO,CAAC;AAIjF,OAAO,KAAK,EACV,mBAAmB,EACnB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACpB,MAAM,UAAU,CAAC;AAGlB,YAAY,EAAE,mBAAmB,EAAE,CAAC;AAIpC,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,mBAAmB,EAAE,CAAC;IACpC,wBAAwB,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAAC;IAC5E,sBAAsB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC;IACzE,6BAA6B,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAAC;IACpF,uBAAuB,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AA2GD,QAAA,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAqiBzD,CAAC;AAEF,eAAe,kBAAkB,CAAC"}
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  import { realpathSync as realpathSync2 } from "fs";
5
5
  import * as path17 from "path";
6
6
  import { fileURLToPath } from "url";
7
- import pLimit3 from "p-limit";
7
+ import pLimit4 from "p-limit";
8
8
 
9
9
  // src/constants.ts
10
10
  var GIT_CONSTANTS = {
@@ -141,6 +141,8 @@ var SyncWorktreesError = class extends Error {
141
141
  Caused by: ${cause.stack}`;
142
142
  }
143
143
  }
144
+ code;
145
+ cause;
144
146
  };
145
147
  var GitError = class extends SyncWorktreesError {
146
148
  constructor(message, code, cause) {
@@ -163,6 +165,8 @@ var WorktreeNotCleanError = class extends WorktreeError {
163
165
  this.path = path18;
164
166
  this.reasons = reasons;
165
167
  }
168
+ path;
169
+ reasons;
166
170
  };
167
171
  var ConfigError = class extends SyncWorktreesError {
168
172
  constructor(message, code, cause) {
@@ -175,18 +179,22 @@ var ConfigValidationError = class extends ConfigError {
175
179
  this.field = field;
176
180
  this.reason = reason;
177
181
  }
182
+ field;
183
+ reason;
178
184
  };
179
185
  var ConfigFileNotFoundError = class extends ConfigError {
180
186
  constructor(configPath) {
181
187
  super(`Config file not found: ${configPath}`, "FILE_NOT_FOUND");
182
188
  this.configPath = configPath;
183
189
  }
190
+ configPath;
184
191
  };
185
192
  var ConfigFileExistsError = class extends ConfigError {
186
193
  constructor(configPath) {
187
194
  super(`Config file already exists: ${configPath}`, "FILE_EXISTS");
188
195
  this.configPath = configPath;
189
196
  }
197
+ configPath;
190
198
  };
191
199
 
192
200
  // src/services/config-loader.service.ts
@@ -814,13 +822,13 @@ import React8 from "react";
814
822
  import * as path14 from "path";
815
823
  import { render } from "ink";
816
824
  import * as cron2 from "node-cron";
817
- import pLimit2 from "p-limit";
825
+ import pLimit3 from "p-limit";
818
826
  import { spawn as spawn2, spawnSync } from "child_process";
819
827
  import { existsSync as existsSync2 } from "fs";
820
828
 
821
829
  // src/components/App.tsx
822
830
  import React7, { useState as useState6, useEffect as useEffect6, useCallback as useCallback4, useRef as useRef5 } from "react";
823
- import { Box as Box7, useInput as useInput6, useStdout } from "ink";
831
+ import { Box as Box7, useInput as useInput6, useWindowSize } from "ink";
824
832
 
825
833
  // src/components/StatusBar.tsx
826
834
  import React, { useState, useEffect } from "react";
@@ -829,6 +837,7 @@ import { CronExpressionParser } from "cron-parser";
829
837
  var StatusBar = ({
830
838
  status,
831
839
  syncProgressEntries = [],
840
+ activeOps = [],
832
841
  maxProgressLines = 2,
833
842
  repositoryCount,
834
843
  lastSyncTime,
@@ -864,17 +873,14 @@ var StatusBar = ({
864
873
  const getStatusIcon = () => {
865
874
  return status === "syncing" ? "\u27F3" : "\u2713";
866
875
  };
867
- const formatProgress = (syncProgress) => {
868
- const percent = syncProgress.progress === void 0 || syncProgress.message.includes(`${syncProgress.progress}%`) ? "" : ` ${syncProgress.progress}%`;
869
- return `[${syncProgress.repo}] ${syncProgress.message}${percent}`;
870
- };
876
+ const formatProgress = (syncProgress) => `[${syncProgress.repo}] ${syncProgress.message}`;
871
877
  const progressLineCount = Math.max(1, maxProgressLines);
872
878
  const visibleProgress = syncProgressEntries.slice(-progressLineCount);
873
879
  return /* @__PURE__ */ React.createElement(Box, { borderStyle: "single", paddingX: 1 }, /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", width: "100%" }, /* @__PURE__ */ React.createElement(Box, { justifyContent: "space-between" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, getStatusIcon(), " Status:", " ", /* @__PURE__ */ React.createElement(Text, { color: getStatusColor() }, status === "syncing" ? "Syncing..." : "Running")), /* @__PURE__ */ React.createElement(Text, null, "Repositories: ", /* @__PURE__ */ React.createElement(Text, { bold: true, color: "cyan" }, repositoryCount))), /* @__PURE__ */ React.createElement(Box, { justifyContent: "space-between" }, /* @__PURE__ */ React.createElement(Text, null, "Last Sync: ", /* @__PURE__ */ React.createElement(Text, { color: "gray" }, formatTime(lastSyncTime))), cronSchedule && /* @__PURE__ */ React.createElement(Text, null, "Next Sync: ", /* @__PURE__ */ React.createElement(Text, { color: "gray" }, formatTime(nextSyncTime)))), status === "syncing" && Array.from({ length: progressLineCount }).map((_, index) => {
874
880
  const entry = visibleProgress[index];
875
881
  const message = entry ? formatProgress(entry) : index === 0 ? "waiting for progress events" : "";
876
882
  return /* @__PURE__ */ React.createElement(Box, { key: index }, /* @__PURE__ */ React.createElement(Text, { wrap: "truncate" }, message ? "Progress: " : " ", message && /* @__PURE__ */ React.createElement(Text, { color: "cyan" }, message)));
877
- }), /* @__PURE__ */ React.createElement(Box, { justifyContent: "space-between" }, /* @__PURE__ */ React.createElement(Text, null, "Disk Space: ", /* @__PURE__ */ React.createElement(Text, { color: "magenta" }, diskSpaceUsed || "Calculating...")), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "s"), "ync", " ", /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "c"), "reate", " ", /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "o"), "pen", " ", /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "w"), "tree", " ", /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "r"), "eload", " ", /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "?"), "help", " ", /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "q"), "uit"))));
883
+ }), activeOps.map((label, index) => /* @__PURE__ */ React.createElement(Box, { key: `op-${index}` }, /* @__PURE__ */ React.createElement(Text, { wrap: "truncate" }, /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "\u23F3 "), /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, label)))), /* @__PURE__ */ React.createElement(Box, { justifyContent: "space-between" }, /* @__PURE__ */ React.createElement(Text, null, "Disk Space: ", /* @__PURE__ */ React.createElement(Text, { color: "magenta" }, diskSpaceUsed || "Calculating...")), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "s"), "ync", " ", /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "c"), "reate", " ", /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "o"), "pen", " ", /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "w"), "tree", " ", /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "r"), "eload", " ", /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "?"), "help", " ", /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "q"), "uit"))));
878
884
  };
879
885
  var StatusBar_default = StatusBar;
880
886
 
@@ -893,7 +899,7 @@ var HelpModal_default = HelpModal;
893
899
 
894
900
  // src/components/BranchCreationWizard.tsx
895
901
  import React3, { useState as useState2, useEffect as useEffect2, useCallback, useMemo, useRef } from "react";
896
- import { Box as Box3, Text as Text3, useInput as useInput2 } from "ink";
902
+ import { Box as Box3, Text as Text3, useInput as useInput2, usePaste } from "ink";
897
903
 
898
904
  // src/utils/git-validation.ts
899
905
  function isValidGitBranchName(name) {
@@ -1159,6 +1165,17 @@ var BranchCreationWizard = ({
1159
1165
  onComplete(result?.success ?? false);
1160
1166
  }
1161
1167
  });
1168
+ usePaste((text) => {
1169
+ if (step === "SELECT_PROJECT") {
1170
+ setProjectFilter((prev) => prev + text);
1171
+ setSelectedProjectIndex(0);
1172
+ } else if (step === "SELECT_BRANCH") {
1173
+ setBranchFilter((prev) => prev + text);
1174
+ setSelectedBranchIndex(0);
1175
+ } else if (step === "ENTER_NAME") {
1176
+ setBranchName((prev) => prev + text.replace(/[^a-zA-Z0-9/._-]/g, ""));
1177
+ }
1178
+ });
1162
1179
  const getStepNumber = () => {
1163
1180
  if (repositories.length === 1) {
1164
1181
  if (step === "SELECT_BRANCH") return 1;
@@ -1252,7 +1269,7 @@ var BranchCreationWizard_default = BranchCreationWizard;
1252
1269
 
1253
1270
  // src/components/OpenEditorWizard.tsx
1254
1271
  import React4, { useState as useState3, useEffect as useEffect3, useMemo as useMemo2, useCallback as useCallback2, useRef as useRef2 } from "react";
1255
- import { Box as Box4, Text as Text4, useInput as useInput3 } from "ink";
1272
+ import { Box as Box4, Text as Text4, useInput as useInput3, usePaste as usePaste2 } from "ink";
1256
1273
  var OpenEditorWizard = ({
1257
1274
  repositories,
1258
1275
  getWorktreesForRepo,
@@ -1370,6 +1387,15 @@ var OpenEditorWizard = ({
1370
1387
  onClose();
1371
1388
  }
1372
1389
  });
1390
+ usePaste2((text) => {
1391
+ if (step === "SELECT_PROJECT") {
1392
+ setProjectFilter((prev) => prev + text);
1393
+ setSelectedProjectIndex(0);
1394
+ } else if (step === "SELECT_WORKTREE") {
1395
+ setWorktreeFilter((prev) => prev + text);
1396
+ setSelectedWorktreeIndex(0);
1397
+ }
1398
+ });
1373
1399
  const getStepNumber = () => {
1374
1400
  if (repositories.length === 1) {
1375
1401
  return 1;
@@ -1441,7 +1467,7 @@ var OpenEditorWizard_default = OpenEditorWizard;
1441
1467
 
1442
1468
  // src/components/WorktreeStatusView.tsx
1443
1469
  import React5, { useState as useState4, useEffect as useEffect4, useMemo as useMemo3, useCallback as useCallback3, useRef as useRef3 } from "react";
1444
- import { Box as Box5, Text as Text5, useInput as useInput4 } from "ink";
1470
+ import { Box as Box5, Text as Text5, useInput as useInput4, usePaste as usePaste3 } from "ink";
1445
1471
 
1446
1472
  // src/utils/lfs-error.ts
1447
1473
  function getErrorMessage(error) {
@@ -1747,6 +1773,17 @@ var WorktreeStatusView = ({
1747
1773
  onClose();
1748
1774
  }
1749
1775
  });
1776
+ usePaste3((text) => {
1777
+ if (confirmDelete !== null) return;
1778
+ if (step === "SELECT_PROJECT") {
1779
+ setProjectFilter((prev) => prev + text);
1780
+ setSelectedProjectIndex(0);
1781
+ } else if (step === "VIEW_STATUS" && !loading) {
1782
+ setEntryFilter((prev) => prev + text);
1783
+ setSelectedEntryIndex(0);
1784
+ setExpandedEntry(null);
1785
+ }
1786
+ });
1750
1787
  const getStepNumber = () => {
1751
1788
  if (repositories.length === 1) return 1;
1752
1789
  return step === "SELECT_PROJECT" ? 1 : 2;
@@ -1971,13 +2008,15 @@ var App = ({
1971
2008
  const [showOpenEditorWizard, setShowOpenEditorWizard] = useState6(false);
1972
2009
  const [showWorktreeStatus, setShowWorktreeStatus] = useState6(false);
1973
2010
  const [status, setStatus] = useState6("idle");
2011
+ const [activeOps, setActiveOps] = useState6([]);
2012
+ const opIdRef = useRef5(0);
1974
2013
  const [syncProgressEntries, setSyncProgressEntries] = useState6([]);
1975
2014
  const [lastSyncTime, setLastSyncTime] = useState6(null);
1976
2015
  const [diskSpaceUsed, setDiskSpaceUsed] = useState6(null);
1977
2016
  const [logs, setLogs] = useState6([]);
1978
2017
  const [repoCount, setRepoCount] = useState6(repositoryCount);
1979
2018
  const [schedule2, setSchedule] = useState6(cronSchedule);
1980
- const { stdout } = useStdout();
2019
+ const { rows } = useWindowSize();
1981
2020
  const addLog = useCallback4((message, level = "info") => {
1982
2021
  setLogs((prev) => {
1983
2022
  const newLogs = [
@@ -2011,11 +2050,11 @@ var App = ({
2011
2050
  onQuit().catch((err) => console.error("Quit failed:", err));
2012
2051
  } else if (input2 === "?" || input2 === "h") {
2013
2052
  setShowHelp(true);
2014
- } else if (input2 === "c" && status === "idle") {
2053
+ } else if (input2 === "c") {
2015
2054
  setShowBranchWizard(true);
2016
- } else if (input2 === "o" && status === "idle") {
2055
+ } else if (input2 === "o") {
2017
2056
  setShowOpenEditorWizard(true);
2018
- } else if (input2 === "w" && status === "idle" && getWorktreeStatusForRepo) {
2057
+ } else if (input2 === "w" && getWorktreeStatusForRepo) {
2019
2058
  setShowWorktreeStatus(true);
2020
2059
  } else if (input2 === "s" && status !== "syncing") {
2021
2060
  setStatus("syncing");
@@ -2092,8 +2131,8 @@ var App = ({
2092
2131
  };
2093
2132
  }, []);
2094
2133
  const progressLineCount = status === "syncing" ? Math.max(1, maxProgressLines) : 0;
2095
- const statusBarHeight = 5 + progressLineCount;
2096
- const terminalRows = stdout.rows ?? 24;
2134
+ const statusBarHeight = 5 + progressLineCount + activeOps.length;
2135
+ const terminalRows = rows ?? 24;
2097
2136
  const logPanelHeight = Math.max(5, terminalRows - statusBarHeight);
2098
2137
  const showModal = showHelp || showBranchWizard || showOpenEditorWizard || showWorktreeStatus;
2099
2138
  return /* @__PURE__ */ React7.createElement(Box7, { flexDirection: "column", minHeight: terminalRows }, !showModal && /* @__PURE__ */ React7.createElement(LogPanel_default, { logs, height: logPanelHeight, isActive: !showModal }), showHelp && /* @__PURE__ */ React7.createElement(HelpModal_default, { onClose: () => setShowHelp(false) }), showBranchWizard && /* @__PURE__ */ React7.createElement(
@@ -2106,7 +2145,8 @@ var App = ({
2106
2145
  createAndPushBranch,
2107
2146
  onClose: () => setShowBranchWizard(false),
2108
2147
  onBranchCreated: (context) => {
2109
- setStatus("syncing");
2148
+ const opId = ++opIdRef.current;
2149
+ setActiveOps((prev) => [...prev, { id: opId, label: `Creating worktree ${context.newBranch}` }]);
2110
2150
  (async () => {
2111
2151
  try {
2112
2152
  await createWorktreeForBranch(context.repoIndex, context.newBranch);
@@ -2135,7 +2175,7 @@ var App = ({
2135
2175
  level: "error"
2136
2176
  });
2137
2177
  } finally {
2138
- setStatus("idle");
2178
+ setActiveOps((prev) => prev.filter((op) => op.id !== opId));
2139
2179
  }
2140
2180
  })().catch((err) => console.error("Branch creation unhandled error:", err));
2141
2181
  },
@@ -2167,6 +2207,7 @@ var App = ({
2167
2207
  {
2168
2208
  status,
2169
2209
  syncProgressEntries,
2210
+ activeOps: activeOps.map((op) => op.label),
2170
2211
  maxProgressLines,
2171
2212
  repositoryCount: repoCount,
2172
2213
  lastSyncTime,
@@ -2177,6 +2218,9 @@ var App = ({
2177
2218
  };
2178
2219
  var App_default = App;
2179
2220
 
2221
+ // src/services/worktree-sync.service.ts
2222
+ import pLimit2 from "p-limit";
2223
+
2180
2224
  // src/utils/retry.ts
2181
2225
  var DEFAULT_OPTIONS = {
2182
2226
  maxAttempts: "unlimited",
@@ -2577,6 +2621,7 @@ var SyncOutcomeAccumulator = class {
2577
2621
  constructor(options) {
2578
2622
  this.options = options;
2579
2623
  }
2624
+ options;
2580
2625
  counts = cloneCounts(EMPTY_COUNTS);
2581
2626
  actions = [];
2582
2627
  add(action) {
@@ -2653,6 +2698,9 @@ var CloneSyncService = class {
2653
2698
  this.progressEmitter = options.progressEmitter;
2654
2699
  this.onSkip = options.onSkip;
2655
2700
  }
2701
+ config;
2702
+ gitService;
2703
+ logger;
2656
2704
  initialized = false;
2657
2705
  resolvedBranch = null;
2658
2706
  branchCreatedActions;
@@ -3758,6 +3806,7 @@ var WorktreeStatusService = class {
3758
3806
  this.config = config;
3759
3807
  this.logger = logger ?? Logger.createDefault();
3760
3808
  }
3809
+ config;
3761
3810
  gitInstances = /* @__PURE__ */ new Map();
3762
3811
  logger;
3763
3812
  async checkWorktreeStatus(worktreePath) {
@@ -4116,6 +4165,8 @@ var GitService = class {
4116
4165
  this.statusService = new WorktreeStatusService({ skipLfs: this.config.skipLfs }, this.logger);
4117
4166
  this.sparseCheckoutService = new SparseCheckoutService(this.logger);
4118
4167
  }
4168
+ config;
4169
+ progressEmitter;
4119
4170
  git = null;
4120
4171
  bareRepoPath;
4121
4172
  mainWorktreePath;
@@ -5010,6 +5061,9 @@ var RepoOperationLock = class {
5010
5061
  this.gitService = gitService;
5011
5062
  this.logger = logger;
5012
5063
  }
5064
+ config;
5065
+ gitService;
5066
+ logger;
5013
5067
  updateLogger(logger) {
5014
5068
  this.logger = logger;
5015
5069
  }
@@ -5071,6 +5125,9 @@ var SyncRetryPolicy = class {
5071
5125
  this.gitService = gitService;
5072
5126
  this.logger = logger;
5073
5127
  }
5128
+ config;
5129
+ gitService;
5130
+ logger;
5074
5131
  updateLogger(logger) {
5075
5132
  this.logger = logger;
5076
5133
  }
@@ -5291,6 +5348,10 @@ var WorktreeModeSyncRunner = class {
5291
5348
  this.logger = logger;
5292
5349
  this.progressEmitter = progressEmitter;
5293
5350
  }
5351
+ config;
5352
+ gitService;
5353
+ logger;
5354
+ progressEmitter;
5294
5355
  pathResolution = new PathResolutionService();
5295
5356
  updateLogger(logger) {
5296
5357
  this.logger = logger;
@@ -5989,10 +6050,15 @@ var WorktreeSyncService = class {
5989
6050
  });
5990
6051
  }
5991
6052
  }
6053
+ config;
5992
6054
  gitService;
5993
6055
  cloneSyncService = null;
5994
6056
  logger;
5995
- syncInProgress = false;
6057
+ // In-process FIFO serializer for all bare-repo-mutating operations (sync, init,
6058
+ // interactive create). One per repo. wait:true callers queue behind an in-flight op;
6059
+ // wait:false callers fail fast. The cross-process file lock (RepoOperationLock) is
6060
+ // acquired inside the mutex body for multi-process safety.
6061
+ repoMutex = pLimit2(1);
5996
6062
  progressEmitter = new ProgressEmitter();
5997
6063
  repoOperationLock;
5998
6064
  retryPolicy;
@@ -6044,7 +6110,7 @@ var WorktreeSyncService = class {
6044
6110
  return this.gitService.isInitialized();
6045
6111
  }
6046
6112
  isSyncInProgress() {
6047
- return this.syncInProgress;
6113
+ return this.repoMutex.activeCount + this.repoMutex.pendingCount > 0;
6048
6114
  }
6049
6115
  getGitService() {
6050
6116
  return this.gitService;
@@ -6060,34 +6126,31 @@ var WorktreeSyncService = class {
6060
6126
  onProgress(listener) {
6061
6127
  return this.progressEmitter.onProgress(listener);
6062
6128
  }
6063
- async runExclusiveRepoOperation(operation) {
6064
- if (this.syncInProgress) {
6129
+ async runExclusiveRepoOperation(operation, options = {}) {
6130
+ if (!options.wait && this.repoMutex.activeCount + this.repoMutex.pendingCount > 0) {
6065
6131
  this.logger.warn("\u26A0\uFE0F Another repository operation is already in progress, skipping...");
6066
6132
  return { started: false, reason: "in_progress" };
6067
6133
  }
6068
- this.syncInProgress = true;
6069
- let release;
6070
- try {
6071
- release = await this.repoOperationLock.acquire();
6072
- } catch (error) {
6073
- this.syncInProgress = false;
6074
- throw error;
6075
- }
6076
- if (release === null) {
6077
- this.syncInProgress = false;
6078
- this.logger.warn("\u26A0\uFE0F Another process holds the sync lock for this repo, skipping...");
6079
- return { started: false, reason: "locked" };
6080
- }
6081
- try {
6082
- return { started: true, value: await operation() };
6083
- } finally {
6134
+ return this.repoMutex(async () => {
6135
+ const release = await this.repoOperationLock.acquire();
6136
+ if (release === null) {
6137
+ this.logger.warn("\u26A0\uFE0F Another process holds the sync lock for this repo, skipping...");
6138
+ return { started: false, reason: "locked" };
6139
+ }
6084
6140
  try {
6085
- await release();
6086
- } catch (releaseError) {
6087
- this.logger.warn(`Failed to release sync lock: ${getErrorMessage(releaseError)}`);
6141
+ return { started: true, value: await operation() };
6142
+ } finally {
6143
+ try {
6144
+ await release();
6145
+ } catch (releaseError) {
6146
+ this.logger.warn(`Failed to release sync lock: ${getErrorMessage(releaseError)}`);
6147
+ }
6088
6148
  }
6089
- this.syncInProgress = false;
6090
- }
6149
+ });
6150
+ }
6151
+ // Interactive variant: queues behind any in-flight sync/op instead of failing fast.
6152
+ async runQueuedRepoOperation(operation) {
6153
+ return this.runExclusiveRepoOperation(operation, { wait: true });
6091
6154
  }
6092
6155
  emitProgress(event) {
6093
6156
  this.progressEmitter.emit(event);
@@ -6393,7 +6456,7 @@ var InteractiveUIService = class {
6393
6456
  this.cronSchedule = cronSchedule;
6394
6457
  this.repositoryCount = syncServices.length;
6395
6458
  this.maxProgressLines = Math.max(1, maxParallel ?? DEFAULT_CONFIG.PARALLELISM.MAX_REPOSITORIES);
6396
- this.limit = pLimit2(this.maxProgressLines);
6459
+ this.limit = pLimit3(this.maxProgressLines);
6397
6460
  this.startBufferFlushCheck();
6398
6461
  this.renderUI();
6399
6462
  this.subscribeToServiceProgress();
@@ -6526,7 +6589,11 @@ var InteractiveUIService = class {
6526
6589
  createWorktreeForBranch: (repoIndex, branchName) => this.createWorktreeForBranch(repoIndex, branchName),
6527
6590
  executeOnBranchCreatedHooks: (repoIndex, context) => this.executeOnBranchCreatedHooks(repoIndex, context)
6528
6591
  }
6529
- )
6592
+ ),
6593
+ {
6594
+ alternateScreen: true,
6595
+ incrementalRendering: true
6596
+ }
6530
6597
  );
6531
6598
  }
6532
6599
  async handleManualSync() {
@@ -6721,11 +6788,12 @@ var InteractiveUIService = class {
6721
6788
  }
6722
6789
  const sizeBytes = bareSizeBytes + worktreeSizeBytes;
6723
6790
  const failedAllPaths = errors.length === sizeTargets.length;
6791
+ const partialFailure = errors.length > 0 && !failedAllPaths;
6724
6792
  return {
6725
6793
  repoIndex,
6726
6794
  repoName,
6727
6795
  sizeBytes: failedAllPaths ? null : sizeBytes,
6728
- sizeFormatted: failedAllPaths ? "N/A" : formatBytes(sizeBytes),
6796
+ sizeFormatted: failedAllPaths ? "N/A" : partialFailure ? `\u2265${formatBytes(sizeBytes)}` : formatBytes(sizeBytes),
6729
6797
  bareSizeBytes,
6730
6798
  worktreeSizeBytes,
6731
6799
  error: errors.length > 0 ? errors.join("; ") : void 0
@@ -6755,11 +6823,15 @@ var InteractiveUIService = class {
6755
6823
  throw new Error(`Invalid repository index: ${repoIndex}`);
6756
6824
  }
6757
6825
  const service = this.syncServices[repoIndex];
6758
- if (!service.isInitialized()) {
6759
- await service.initialize();
6826
+ const result = await service.runQueuedRepoOperation(async () => {
6827
+ if (!service.isInitialized()) {
6828
+ await service.initializeUnlocked();
6829
+ }
6830
+ await service.getGitService().fetchAll();
6831
+ });
6832
+ if (!result.started) {
6833
+ throw new Error("Another process holds the repository lock; fetch skipped. Try again.");
6760
6834
  }
6761
- const gitService = service.getGitService();
6762
- await gitService.fetchAll();
6763
6835
  }
6764
6836
  async createAndPushBranch(repoIndex, baseBranch, branchName) {
6765
6837
  if (repoIndex < 0 || repoIndex >= this.syncServices.length) {
@@ -6767,25 +6839,35 @@ var InteractiveUIService = class {
6767
6839
  }
6768
6840
  const service = this.syncServices[repoIndex];
6769
6841
  const gitService = service.getGitService();
6770
- const maxAttempts = 10;
6771
- let finalName = branchName;
6772
- let suffix = 0;
6773
- for (let attempt = 0; attempt < maxAttempts; attempt++) {
6774
- try {
6775
- await gitService.createBranch(finalName, baseBranch);
6776
- await gitService.pushBranch(finalName);
6777
- return { success: true, finalName };
6778
- } catch (error) {
6779
- const errorMessage = error instanceof Error ? error.message : String(error);
6780
- if (errorMessage.includes("already exists")) {
6781
- suffix++;
6782
- finalName = `${branchName}-${suffix}`;
6783
- continue;
6842
+ const result = await service.runQueuedRepoOperation(async () => {
6843
+ const maxAttempts = 10;
6844
+ let finalName = branchName;
6845
+ let suffix = 0;
6846
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
6847
+ try {
6848
+ await gitService.createBranch(finalName, baseBranch);
6849
+ await gitService.pushBranch(finalName);
6850
+ return { success: true, finalName };
6851
+ } catch (error) {
6852
+ const errorMessage = error instanceof Error ? error.message : String(error);
6853
+ if (errorMessage.includes("already exists")) {
6854
+ suffix++;
6855
+ finalName = `${branchName}-${suffix}`;
6856
+ continue;
6857
+ }
6858
+ return { success: false, finalName: branchName, error: errorMessage };
6784
6859
  }
6785
- return { success: false, finalName: branchName, error: errorMessage };
6786
6860
  }
6861
+ return { success: false, finalName: branchName, error: `Failed to create branch after ${maxAttempts} attempts` };
6862
+ });
6863
+ if (!result.started) {
6864
+ return {
6865
+ success: false,
6866
+ finalName: branchName,
6867
+ error: "Another process holds the repository lock; branch not created. Try again."
6868
+ };
6787
6869
  }
6788
- return { success: false, finalName: branchName, error: `Failed to create branch after ${maxAttempts} attempts` };
6870
+ return result.value;
6789
6871
  }
6790
6872
  async getWorktreesForRepo(repoIndex) {
6791
6873
  if (repoIndex < 0 || repoIndex >= this.syncServices.length) {
@@ -6887,7 +6969,12 @@ var InteractiveUIService = class {
6887
6969
  const gitService = service.getGitService();
6888
6970
  const worktreeDir = service.config.worktreeDir;
6889
6971
  const worktreePath = this.pathResolution.getBranchWorktreePath(worktreeDir, branchName);
6890
- await gitService.addWorktree(branchName, worktreePath);
6972
+ const result = await service.runQueuedRepoOperation(async () => {
6973
+ await gitService.addWorktree(branchName, worktreePath);
6974
+ });
6975
+ if (!result.started) {
6976
+ throw new Error("Another process holds the repository lock; worktree not created. Try again.");
6977
+ }
6891
6978
  }
6892
6979
  openEditorInWorktree(worktreePath) {
6893
6980
  const editor = process.env.EDITOR || process.env.VISUAL || "code";
@@ -7465,7 +7552,7 @@ async function runMultipleRepositories(configFile, repositories, configPath) {
7465
7552
  const globalLogger = Logger.createDefault();
7466
7553
  const runOnce = configFile.defaults?.runOnce ?? false;
7467
7554
  const maxParallel = configFile.parallelism?.maxRepositories ?? configFile.defaults?.parallelism?.maxRepositories ?? DEFAULT_CONFIG.PARALLELISM.MAX_REPOSITORIES;
7468
- const limit = pLimit3(maxParallel);
7555
+ const limit = pLimit4(maxParallel);
7469
7556
  if (runOnce) {
7470
7557
  globalLogger.info(`
7471
7558
  \u{1F504} Syncing ${repositories.length} repositories...`);