sync-worktrees 4.0.0 → 4.1.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/components/App.d.ts +4 -6
- package/dist/components/App.d.ts.map +1 -1
- package/dist/components/StatusBar.d.ts +3 -0
- package/dist/components/StatusBar.d.ts.map +1 -1
- package/dist/components/WorktreeStatusView.d.ts +3 -6
- package/dist/components/WorktreeStatusView.d.ts.map +1 -1
- package/dist/index.js +199 -27
- package/dist/index.js.map +3 -3
- package/dist/mcp-server.js +7 -4
- package/dist/mcp-server.js.map +2 -2
- package/dist/services/InteractiveUIService.d.ts +6 -6
- package/dist/services/InteractiveUIService.d.ts.map +1 -1
- package/dist/services/git.service.d.ts +3 -1
- package/dist/services/git.service.d.ts.map +1 -1
- package/dist/types/index.d.ts +14 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/app-events.d.ts +10 -0
- package/dist/utils/app-events.d.ts.map +1 -1
- package/dist/utils/config-generator.d.ts.map +1 -1
- package/dist/utils/git-progress.d.ts +5 -5
- package/package.json +1 -1
package/dist/components/App.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import type { AppEventEmitter } from "../utils/app-events";
|
|
3
|
-
import type { HookContext, WorktreeStatusEntry, DivergedDirectoryInfo } from "../types";
|
|
3
|
+
import type { HookContext, WorktreeStatusEntry, DivergedDirectoryInfo, RepositoryListEntry, RepositoryDiskUsage } from "../types";
|
|
4
4
|
export type { HookContext, WorktreeStatusEntry };
|
|
5
5
|
export interface AppProps {
|
|
6
6
|
events: AppEventEmitter;
|
|
@@ -9,11 +9,9 @@ export interface AppProps {
|
|
|
9
9
|
onManualSync: () => void;
|
|
10
10
|
onReload: () => void;
|
|
11
11
|
onQuit: () => Promise<void>;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
repoUrl: string;
|
|
16
|
-
}>;
|
|
12
|
+
maxProgressLines?: number;
|
|
13
|
+
getRepositoryList: () => RepositoryListEntry[];
|
|
14
|
+
getRepositoryDiskUsage?: (index: number) => Promise<RepositoryDiskUsage>;
|
|
17
15
|
getBranchesForRepo: (index: number) => Promise<string[]>;
|
|
18
16
|
getDefaultBranchForRepo: (index: number) => string;
|
|
19
17
|
fetchForRepo?: (index: number) => Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAmD,MAAM,OAAO,CAAC;AAQxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"App.d.ts","sourceRoot":"","sources":["../../src/components/App.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
+
import type { AppSyncProgress } from "../utils/app-events";
|
|
2
3
|
export interface StatusBarProps {
|
|
3
4
|
status: "idle" | "syncing";
|
|
5
|
+
syncProgressEntries?: AppSyncProgress[];
|
|
6
|
+
maxProgressLines?: number;
|
|
4
7
|
repositoryCount: number;
|
|
5
8
|
lastSyncTime: Date | null;
|
|
6
9
|
cronSchedule?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StatusBar.d.ts","sourceRoot":"","sources":["../../src/components/StatusBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA8B,MAAM,OAAO,CAAC;AAInD,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,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,
|
|
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,13 +1,10 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import type { WorktreeStatusEntry, DivergedDirectoryInfo } from "../types";
|
|
2
|
+
import type { WorktreeStatusEntry, DivergedDirectoryInfo, RepositoryListEntry, RepositoryDiskUsage } from "../types";
|
|
3
3
|
export type { WorktreeStatusEntry };
|
|
4
4
|
export interface WorktreeStatusViewProps {
|
|
5
|
-
repositories:
|
|
6
|
-
index: number;
|
|
7
|
-
name: string;
|
|
8
|
-
repoUrl: string;
|
|
9
|
-
}>;
|
|
5
|
+
repositories: RepositoryListEntry[];
|
|
10
6
|
getWorktreeStatusForRepo: (index: number) => Promise<WorktreeStatusEntry[]>;
|
|
7
|
+
getRepositoryDiskUsage?: (index: number) => Promise<RepositoryDiskUsage>;
|
|
11
8
|
getDivergedDirectoriesForRepo?: (index: number) => Promise<DivergedDirectoryInfo[]>;
|
|
12
9
|
deleteDivergedDirectory?: (repoIndex: number, name: string) => Promise<void>;
|
|
13
10
|
onClose: () => void;
|
|
@@ -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,
|
|
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"}
|
package/dist/index.js
CHANGED
|
@@ -826,7 +826,15 @@ import { Box as Box7, useInput as useInput6, useStdout } from "ink";
|
|
|
826
826
|
import React, { useState, useEffect } from "react";
|
|
827
827
|
import { Box, Text } from "ink";
|
|
828
828
|
import { CronExpressionParser } from "cron-parser";
|
|
829
|
-
var StatusBar = ({
|
|
829
|
+
var StatusBar = ({
|
|
830
|
+
status,
|
|
831
|
+
syncProgressEntries = [],
|
|
832
|
+
maxProgressLines = 2,
|
|
833
|
+
repositoryCount,
|
|
834
|
+
lastSyncTime,
|
|
835
|
+
cronSchedule,
|
|
836
|
+
diskSpaceUsed
|
|
837
|
+
}) => {
|
|
830
838
|
const [nextSyncTime, setNextSyncTime] = useState(null);
|
|
831
839
|
useEffect(() => {
|
|
832
840
|
if (!cronSchedule) {
|
|
@@ -856,7 +864,17 @@ var StatusBar = ({ status, repositoryCount, lastSyncTime, cronSchedule, diskSpac
|
|
|
856
864
|
const getStatusIcon = () => {
|
|
857
865
|
return status === "syncing" ? "\u27F3" : "\u2713";
|
|
858
866
|
};
|
|
859
|
-
|
|
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
|
+
};
|
|
871
|
+
const progressLineCount = Math.max(1, maxProgressLines);
|
|
872
|
+
const visibleProgress = syncProgressEntries.slice(-progressLineCount);
|
|
873
|
+
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
|
+
const entry = visibleProgress[index];
|
|
875
|
+
const message = entry ? formatProgress(entry) : index === 0 ? "waiting for progress events" : "";
|
|
876
|
+
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"))));
|
|
860
878
|
};
|
|
861
879
|
var StatusBar_default = StatusBar;
|
|
862
880
|
|
|
@@ -1526,6 +1544,7 @@ var formatDivergedDate = (dateStr) => {
|
|
|
1526
1544
|
var WorktreeStatusView = ({
|
|
1527
1545
|
repositories,
|
|
1528
1546
|
getWorktreeStatusForRepo,
|
|
1547
|
+
getRepositoryDiskUsage,
|
|
1529
1548
|
getDivergedDirectoriesForRepo,
|
|
1530
1549
|
deleteDivergedDirectory,
|
|
1531
1550
|
onClose
|
|
@@ -1540,6 +1559,8 @@ var WorktreeStatusView = ({
|
|
|
1540
1559
|
const [entryFilter, setEntryFilter] = useState4("");
|
|
1541
1560
|
const [expandedEntry, setExpandedEntry] = useState4(null);
|
|
1542
1561
|
const [loading, setLoading] = useState4(false);
|
|
1562
|
+
const [repoDiskUsage, setRepoDiskUsage] = useState4({});
|
|
1563
|
+
const requestedDiskUsageRef = useRef3(/* @__PURE__ */ new Set());
|
|
1543
1564
|
const [confirmDelete, setConfirmDelete] = useState4(null);
|
|
1544
1565
|
const [deleting, setDeleting] = useState4(false);
|
|
1545
1566
|
const [error, setError] = useState4(null);
|
|
@@ -1595,6 +1616,29 @@ var WorktreeStatusView = ({
|
|
|
1595
1616
|
},
|
|
1596
1617
|
[getWorktreeStatusForRepo, getDivergedDirectoriesForRepo]
|
|
1597
1618
|
);
|
|
1619
|
+
useEffect4(() => {
|
|
1620
|
+
if (!getRepositoryDiskUsage) return void 0;
|
|
1621
|
+
let cancelled = false;
|
|
1622
|
+
const indexesToLoad = repositories.map((repo) => repo.index).filter((repoIndex) => !requestedDiskUsageRef.current.has(repoIndex));
|
|
1623
|
+
if (indexesToLoad.length === 0) return void 0;
|
|
1624
|
+
for (const repoIndex of indexesToLoad) {
|
|
1625
|
+
requestedDiskUsageRef.current.add(repoIndex);
|
|
1626
|
+
setRepoDiskUsage((prev) => ({ ...prev, [repoIndex]: { status: "loading" } }));
|
|
1627
|
+
void getRepositoryDiskUsage(repoIndex).then((usage) => {
|
|
1628
|
+
if (cancelled) return;
|
|
1629
|
+
setRepoDiskUsage((prev) => ({ ...prev, [repoIndex]: { status: "ready", usage } }));
|
|
1630
|
+
}).catch(() => {
|
|
1631
|
+
if (cancelled) return;
|
|
1632
|
+
setRepoDiskUsage((prev) => ({
|
|
1633
|
+
...prev,
|
|
1634
|
+
[repoIndex]: { status: "error" }
|
|
1635
|
+
}));
|
|
1636
|
+
});
|
|
1637
|
+
}
|
|
1638
|
+
return () => {
|
|
1639
|
+
cancelled = true;
|
|
1640
|
+
};
|
|
1641
|
+
}, [repositories, getRepositoryDiskUsage]);
|
|
1598
1642
|
useEffect4(() => {
|
|
1599
1643
|
if (step === "VIEW_STATUS" && entries.length === 0 && !loading && selectedRepoIndexRef.current >= 0) {
|
|
1600
1644
|
loadStatus(selectedRepoIndexRef.current);
|
|
@@ -1668,11 +1712,11 @@ var WorktreeStatusView = ({
|
|
|
1668
1712
|
} else if (key.downArrow) {
|
|
1669
1713
|
setSelectedProjectIndex((prev) => Math.min(filteredProjects.length - 1, prev + 1));
|
|
1670
1714
|
} else if (key.return && filteredProjects.length > 0) {
|
|
1671
|
-
const
|
|
1672
|
-
if (
|
|
1673
|
-
selectedRepoIndexRef.current =
|
|
1715
|
+
const selectedRepo2 = filteredProjects[selectedProjectIndex];
|
|
1716
|
+
if (selectedRepo2) {
|
|
1717
|
+
selectedRepoIndexRef.current = selectedRepo2.index;
|
|
1674
1718
|
setStep("VIEW_STATUS");
|
|
1675
|
-
loadStatus(
|
|
1719
|
+
loadStatus(selectedRepo2.index);
|
|
1676
1720
|
}
|
|
1677
1721
|
} else if (key.backspace || key.delete) {
|
|
1678
1722
|
setProjectFilter((prev) => prev.slice(0, -1));
|
|
@@ -1720,7 +1764,7 @@ var WorktreeStatusView = ({
|
|
|
1720
1764
|
return /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column", gap: 1 }, /* @__PURE__ */ React5.createElement(Text5, null, "Select repository:"), /* @__PURE__ */ React5.createElement(Box5, null, /* @__PURE__ */ React5.createElement(Text5, null, "Filter: "), /* @__PURE__ */ React5.createElement(Text5, { color: "cyan" }, projectFilter || "_"), /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, " ", "(", filteredProjects.length, "/", repositories.length, " matches)")), /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column" }, filteredProjects.length === 0 ? /* @__PURE__ */ React5.createElement(Text5, { color: "yellow" }, "No matches") : /* @__PURE__ */ React5.createElement(React5.Fragment, null, startIdx > 0 && /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, " ..."), visibleProjects.map((repo, idx) => {
|
|
1721
1765
|
const actualIdx = startIdx + idx;
|
|
1722
1766
|
const isSelected = actualIdx === selectedProjectIndex;
|
|
1723
|
-
return /* @__PURE__ */ React5.createElement(Box5, { key: repo.index }, /* @__PURE__ */ React5.createElement(Text5, { color: isSelected ? "cyan" : void 0 }, isSelected ? "> " : " ", repo.name));
|
|
1767
|
+
return /* @__PURE__ */ React5.createElement(Box5, { key: repo.index }, /* @__PURE__ */ React5.createElement(Text5, { color: isSelected ? "cyan" : void 0 }, isSelected ? "> " : " "), /* @__PURE__ */ React5.createElement(Box5, { width: 38 }, /* @__PURE__ */ React5.createElement(Text5, { color: isSelected ? "cyan" : void 0 }, repo.name)), getRepositoryDiskUsage && /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, " "), renderRepositoryDiskUsage(repo.index));
|
|
1724
1768
|
}), endIdx < filteredProjects.length && /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, " ..."))));
|
|
1725
1769
|
};
|
|
1726
1770
|
const renderDetailPanel = (entry) => {
|
|
@@ -1731,6 +1775,17 @@ var WorktreeStatusView = ({
|
|
|
1731
1775
|
const renderDivergedDetailPanel = (entry) => {
|
|
1732
1776
|
return /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column", marginLeft: 4, marginTop: 0, marginBottom: 1 }, /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, "Path: ", entry.path), /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, " Original branch: ", entry.originalBranch), entry.divergedAt && /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, " Diverged: ", entry.divergedAt), /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, " Size: ", entry.sizeFormatted));
|
|
1733
1777
|
};
|
|
1778
|
+
const renderRepositoryDiskUsage = (repoIndex) => {
|
|
1779
|
+
if (!getRepositoryDiskUsage) return null;
|
|
1780
|
+
const state = repoDiskUsage[repoIndex];
|
|
1781
|
+
if (!state || state.status === "loading") {
|
|
1782
|
+
return /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, "Size: calculating...");
|
|
1783
|
+
}
|
|
1784
|
+
if (state.status === "error") {
|
|
1785
|
+
return /* @__PURE__ */ React5.createElement(Text5, { color: "red" }, "Size: N/A");
|
|
1786
|
+
}
|
|
1787
|
+
return /* @__PURE__ */ React5.createElement(Text5, null, "Size: ", /* @__PURE__ */ React5.createElement(Text5, { color: "magenta" }, state.usage.sizeFormatted));
|
|
1788
|
+
};
|
|
1734
1789
|
const renderStatusList = () => {
|
|
1735
1790
|
if (loading) {
|
|
1736
1791
|
return /* @__PURE__ */ React5.createElement(Text5, { color: "yellow" }, "Loading worktree status...");
|
|
@@ -1784,7 +1839,8 @@ var WorktreeStatusView = ({
|
|
|
1784
1839
|
}
|
|
1785
1840
|
return /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, step === "VIEW_STATUS" ? isDivergedSelected ? "\u2191/\u2193 navigate \u2022 Type to filter \u2022 Enter to expand \u2022 d to delete \u2022 ESC to close" : "\u2191/\u2193 navigate \u2022 Type to filter \u2022 Enter to expand \u2022 ESC to close" : "\u2191/\u2193 navigate \u2022 Type to filter \u2022 Enter to select \u2022 ESC to cancel");
|
|
1786
1841
|
};
|
|
1787
|
-
|
|
1842
|
+
const selectedRepo = selectedRepoIndexRef.current >= 0 ? repositories.find((repo) => repo.index === selectedRepoIndexRef.current) : void 0;
|
|
1843
|
+
return /* @__PURE__ */ React5.createElement(Box5, { flexDirection: "column", marginTop: 1, marginBottom: 1 }, /* @__PURE__ */ React5.createElement(Box5, { borderStyle: "round", borderColor: "green", paddingX: 2, paddingY: 1, flexDirection: "column", width: 70 }, /* @__PURE__ */ React5.createElement(Box5, { marginBottom: 1 }, /* @__PURE__ */ React5.createElement(Text5, { bold: true, color: "green" }, "\u{1F4CA} Worktree Status", " ", step !== "ERROR" && /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, "(Step ", getStepNumber(), "/", getTotalSteps(), ")"))), step === "VIEW_STATUS" && selectedRepo && /* @__PURE__ */ React5.createElement(Box5, { marginBottom: 1 }, /* @__PURE__ */ React5.createElement(Text5, null, "Repository: ", /* @__PURE__ */ React5.createElement(Text5, { color: "cyan" }, selectedRepo.name)), getRepositoryDiskUsage && /* @__PURE__ */ React5.createElement(Text5, { dimColor: true }, " "), renderRepositoryDiskUsage(selectedRepo.index)), renderContent(), /* @__PURE__ */ React5.createElement(Box5, { marginTop: 1 }, renderFooter())));
|
|
1788
1844
|
};
|
|
1789
1845
|
var WorktreeStatusView_default = WorktreeStatusView;
|
|
1790
1846
|
|
|
@@ -1893,7 +1949,9 @@ var App = ({
|
|
|
1893
1949
|
onManualSync,
|
|
1894
1950
|
onReload,
|
|
1895
1951
|
onQuit,
|
|
1952
|
+
maxProgressLines = 2,
|
|
1896
1953
|
getRepositoryList,
|
|
1954
|
+
getRepositoryDiskUsage,
|
|
1897
1955
|
getBranchesForRepo,
|
|
1898
1956
|
getDefaultBranchForRepo,
|
|
1899
1957
|
fetchForRepo,
|
|
@@ -1913,6 +1971,7 @@ var App = ({
|
|
|
1913
1971
|
const [showOpenEditorWizard, setShowOpenEditorWizard] = useState6(false);
|
|
1914
1972
|
const [showWorktreeStatus, setShowWorktreeStatus] = useState6(false);
|
|
1915
1973
|
const [status, setStatus] = useState6("idle");
|
|
1974
|
+
const [syncProgressEntries, setSyncProgressEntries] = useState6([]);
|
|
1916
1975
|
const [lastSyncTime, setLastSyncTime] = useState6(null);
|
|
1917
1976
|
const [diskSpaceUsed, setDiskSpaceUsed] = useState6(null);
|
|
1918
1977
|
const [logs, setLogs] = useState6([]);
|
|
@@ -1983,15 +2042,36 @@ var App = ({
|
|
|
1983
2042
|
const updateLastSyncTime = useCallback4(() => {
|
|
1984
2043
|
setLastSyncTime(/* @__PURE__ */ new Date());
|
|
1985
2044
|
setStatus("idle");
|
|
2045
|
+
setSyncProgressEntries([]);
|
|
1986
2046
|
}, []);
|
|
1987
2047
|
useEffect6(() => {
|
|
1988
2048
|
const unsubscribers = [
|
|
1989
2049
|
events.on("updateLastSyncTime", () => {
|
|
1990
2050
|
setLastSyncTime(/* @__PURE__ */ new Date());
|
|
1991
2051
|
setStatus("idle");
|
|
2052
|
+
setSyncProgressEntries([]);
|
|
1992
2053
|
}),
|
|
1993
2054
|
events.on("setStatus", (newStatus) => {
|
|
1994
2055
|
setStatus(newStatus);
|
|
2056
|
+
if (newStatus === "idle") {
|
|
2057
|
+
setSyncProgressEntries([]);
|
|
2058
|
+
}
|
|
2059
|
+
}),
|
|
2060
|
+
events.on("setSyncProgress", (progress) => {
|
|
2061
|
+
if (progress === null) {
|
|
2062
|
+
setSyncProgressEntries([]);
|
|
2063
|
+
return;
|
|
2064
|
+
}
|
|
2065
|
+
setSyncProgressEntries((prev) => {
|
|
2066
|
+
if (progress.completed) {
|
|
2067
|
+
return prev.filter((entry) => entry.repo !== progress.repo);
|
|
2068
|
+
}
|
|
2069
|
+
const existingIndex = prev.findIndex((entry) => entry.repo === progress.repo);
|
|
2070
|
+
if (existingIndex === -1) {
|
|
2071
|
+
return [...prev, progress];
|
|
2072
|
+
}
|
|
2073
|
+
return prev.map((entry, index) => index === existingIndex ? progress : entry);
|
|
2074
|
+
});
|
|
1995
2075
|
}),
|
|
1996
2076
|
events.on("setDiskSpace", (diskSpace) => {
|
|
1997
2077
|
setDiskSpaceUsed(diskSpace);
|
|
@@ -2011,7 +2091,8 @@ var App = ({
|
|
|
2011
2091
|
unsubscribers.forEach((unsub) => unsub());
|
|
2012
2092
|
};
|
|
2013
2093
|
}, []);
|
|
2014
|
-
const
|
|
2094
|
+
const progressLineCount = status === "syncing" ? Math.max(1, maxProgressLines) : 0;
|
|
2095
|
+
const statusBarHeight = 5 + progressLineCount;
|
|
2015
2096
|
const terminalRows = stdout.rows ?? 24;
|
|
2016
2097
|
const logPanelHeight = Math.max(5, terminalRows - statusBarHeight);
|
|
2017
2098
|
const showModal = showHelp || showBranchWizard || showOpenEditorWizard || showWorktreeStatus;
|
|
@@ -2076,6 +2157,7 @@ var App = ({
|
|
|
2076
2157
|
{
|
|
2077
2158
|
repositories: getRepositoryList(),
|
|
2078
2159
|
getWorktreeStatusForRepo,
|
|
2160
|
+
getRepositoryDiskUsage,
|
|
2079
2161
|
getDivergedDirectoriesForRepo,
|
|
2080
2162
|
deleteDivergedDirectory,
|
|
2081
2163
|
onClose: () => setShowWorktreeStatus(false)
|
|
@@ -2084,6 +2166,8 @@ var App = ({
|
|
|
2084
2166
|
StatusBar_default,
|
|
2085
2167
|
{
|
|
2086
2168
|
status,
|
|
2169
|
+
syncProgressEntries,
|
|
2170
|
+
maxProgressLines,
|
|
2087
2171
|
repositoryCount: repoCount,
|
|
2088
2172
|
lastSyncTime,
|
|
2089
2173
|
cronSchedule: schedule2,
|
|
@@ -2287,7 +2371,7 @@ function makeGitProgressHandler(logger, emitProgress) {
|
|
|
2287
2371
|
lastBucket.set(key, bucket);
|
|
2288
2372
|
const total = event.total > 0 ? `${event.processed}/${event.total}` : `${event.processed}`;
|
|
2289
2373
|
const message = `${event.method} ${event.stage}: ${event.progress}% (${total})`;
|
|
2290
|
-
logger.
|
|
2374
|
+
logger.debug(` \u21B3 ${message}`);
|
|
2291
2375
|
emitProgress?.({
|
|
2292
2376
|
phase: event.method,
|
|
2293
2377
|
message,
|
|
@@ -4022,8 +4106,9 @@ function sanitizeGitEnv(env) {
|
|
|
4022
4106
|
return sanitized;
|
|
4023
4107
|
}
|
|
4024
4108
|
var GitService = class {
|
|
4025
|
-
constructor(config, logger) {
|
|
4109
|
+
constructor(config, logger, progressEmitter) {
|
|
4026
4110
|
this.config = config;
|
|
4111
|
+
this.progressEmitter = progressEmitter;
|
|
4027
4112
|
this.logger = logger ?? Logger.createDefault(void 0, config.debug);
|
|
4028
4113
|
this.bareRepoPath = this.config.bareRepoDir || getDefaultBareRepoDir(this.config.repoUrl);
|
|
4029
4114
|
this.mainWorktreePath = path8.join(this.config.worktreeDir, GIT_CONSTANTS.DEFAULT_BRANCH);
|
|
@@ -4064,7 +4149,9 @@ var GitService = class {
|
|
|
4064
4149
|
return git;
|
|
4065
4150
|
}
|
|
4066
4151
|
buildSimpleGitOptions(blockMs) {
|
|
4067
|
-
const options = {
|
|
4152
|
+
const options = {
|
|
4153
|
+
progress: makeGitProgressHandler(this.logger, (event) => this.progressEmitter?.(event))
|
|
4154
|
+
};
|
|
4068
4155
|
if (blockMs > 0) options.timeout = { block: blockMs };
|
|
4069
4156
|
return options;
|
|
4070
4157
|
}
|
|
@@ -5884,7 +5971,7 @@ var WorktreeSyncService = class {
|
|
|
5884
5971
|
constructor(config) {
|
|
5885
5972
|
this.config = config;
|
|
5886
5973
|
this.logger = config.logger ?? Logger.createDefault(void 0, config.debug);
|
|
5887
|
-
this.gitService = new GitService(config, this.logger);
|
|
5974
|
+
this.gitService = new GitService(config, this.logger, (event) => this.emitProgress(event));
|
|
5888
5975
|
this.repoOperationLock = new RepoOperationLock(config, this.gitService, this.logger);
|
|
5889
5976
|
this.retryPolicy = new SyncRetryPolicy(config, this.gitService, this.logger);
|
|
5890
5977
|
this.worktreeModeSyncRunner = new WorktreeModeSyncRunner(
|
|
@@ -6288,11 +6375,13 @@ var InteractiveUIService = class {
|
|
|
6288
6375
|
branchCreatedActions = new BranchCreatedActionsService();
|
|
6289
6376
|
pathResolution = new PathResolutionService();
|
|
6290
6377
|
limit;
|
|
6378
|
+
maxProgressLines;
|
|
6291
6379
|
reloadInProgress = false;
|
|
6292
6380
|
isDestroyed = false;
|
|
6293
6381
|
events;
|
|
6294
6382
|
ownsEvents;
|
|
6295
6383
|
unsubscribeCallbacks = [];
|
|
6384
|
+
progressUnsubscribers = [];
|
|
6296
6385
|
constructor(syncServices, configPath, cronSchedule, maxParallel, events) {
|
|
6297
6386
|
this.ownsEvents = events === void 0;
|
|
6298
6387
|
this.events = events ?? new AppEventEmitter();
|
|
@@ -6303,9 +6392,11 @@ var InteractiveUIService = class {
|
|
|
6303
6392
|
this.configPath = configPath;
|
|
6304
6393
|
this.cronSchedule = cronSchedule;
|
|
6305
6394
|
this.repositoryCount = syncServices.length;
|
|
6306
|
-
this.
|
|
6395
|
+
this.maxProgressLines = Math.max(1, maxParallel ?? DEFAULT_CONFIG.PARALLELISM.MAX_REPOSITORIES);
|
|
6396
|
+
this.limit = pLimit2(this.maxProgressLines);
|
|
6307
6397
|
this.startBufferFlushCheck();
|
|
6308
6398
|
this.renderUI();
|
|
6399
|
+
this.subscribeToServiceProgress();
|
|
6309
6400
|
this.injectLoggersIntoServices();
|
|
6310
6401
|
setTimeout(() => {
|
|
6311
6402
|
this.addLog("\u{1F680} sync-worktrees UI initialized", "info");
|
|
@@ -6343,6 +6434,26 @@ var InteractiveUIService = class {
|
|
|
6343
6434
|
);
|
|
6344
6435
|
}
|
|
6345
6436
|
}
|
|
6437
|
+
subscribeToServiceProgress() {
|
|
6438
|
+
for (const unsubscribe of this.progressUnsubscribers) {
|
|
6439
|
+
unsubscribe();
|
|
6440
|
+
}
|
|
6441
|
+
this.progressUnsubscribers = this.syncServices.map((service, index) => {
|
|
6442
|
+
const repoName = this.getRepoName(index);
|
|
6443
|
+
if (!service.onProgress) return () => void 0;
|
|
6444
|
+
return service.onProgress((event) => {
|
|
6445
|
+
if (this.isDestroyed) return;
|
|
6446
|
+
this.events.emit("setSyncProgress", {
|
|
6447
|
+
repo: repoName,
|
|
6448
|
+
phase: event.phase,
|
|
6449
|
+
message: event.message,
|
|
6450
|
+
progress: event.progress,
|
|
6451
|
+
processed: event.processed,
|
|
6452
|
+
total: event.total
|
|
6453
|
+
});
|
|
6454
|
+
});
|
|
6455
|
+
});
|
|
6456
|
+
}
|
|
6346
6457
|
addLog(message, level = "info") {
|
|
6347
6458
|
if (this.isDestroyed) return;
|
|
6348
6459
|
if (this.uiReady) {
|
|
@@ -6395,6 +6506,7 @@ var InteractiveUIService = class {
|
|
|
6395
6506
|
events: this.events,
|
|
6396
6507
|
repositoryCount: this.repositoryCount,
|
|
6397
6508
|
cronSchedule: this.cronSchedule,
|
|
6509
|
+
maxProgressLines: this.maxProgressLines,
|
|
6398
6510
|
onManualSync: () => this.handleManualSync(),
|
|
6399
6511
|
onReload: () => this.handleReload(),
|
|
6400
6512
|
onQuit: () => this.handleQuit(),
|
|
@@ -6405,6 +6517,7 @@ var InteractiveUIService = class {
|
|
|
6405
6517
|
createAndPushBranch: (repoIndex, baseBranch, branchName) => this.createAndPushBranch(repoIndex, baseBranch, branchName),
|
|
6406
6518
|
getWorktreesForRepo: (index) => this.getWorktreesForRepo(index),
|
|
6407
6519
|
getWorktreeStatusForRepo: (index) => this.getWorktreeStatusForRepo(index),
|
|
6520
|
+
getRepositoryDiskUsage: (index) => this.getRepositoryDiskUsage(index),
|
|
6408
6521
|
getDivergedDirectoriesForRepo: (index) => this.getDivergedDirectoriesForRepo(index),
|
|
6409
6522
|
deleteDivergedDirectory: (repoIndex, name) => this.deleteDivergedDirectory(repoIndex, name),
|
|
6410
6523
|
openEditorInWorktree: (path18) => this.openEditorInWorktree(path18),
|
|
@@ -6470,6 +6583,7 @@ var InteractiveUIService = class {
|
|
|
6470
6583
|
cronJobsCancelled = true;
|
|
6471
6584
|
this.syncServices = newServices;
|
|
6472
6585
|
this.repositoryCount = this.syncServices.length;
|
|
6586
|
+
this.subscribeToServiceProgress();
|
|
6473
6587
|
this.injectLoggersIntoServices();
|
|
6474
6588
|
const uniqueSchedules = [...new Set(this.syncServices.map((s) => s.config.cronSchedule))];
|
|
6475
6589
|
this.cronSchedule = uniqueSchedules.length === 1 ? uniqueSchedules[0] : void 0;
|
|
@@ -6546,6 +6660,9 @@ var InteractiveUIService = class {
|
|
|
6546
6660
|
setStatus(status) {
|
|
6547
6661
|
if (this.isDestroyed) return;
|
|
6548
6662
|
this.events.emit("setStatus", status);
|
|
6663
|
+
if (status === "idle") {
|
|
6664
|
+
this.events.emit("setSyncProgress", null);
|
|
6665
|
+
}
|
|
6549
6666
|
}
|
|
6550
6667
|
setDiskSpace(diskSpace) {
|
|
6551
6668
|
if (this.isDestroyed) return;
|
|
@@ -6575,6 +6692,45 @@ var InteractiveUIService = class {
|
|
|
6575
6692
|
const service = this.syncServices[index];
|
|
6576
6693
|
return service.config.name || `repo-${index}`;
|
|
6577
6694
|
}
|
|
6695
|
+
async getRepositoryDiskUsage(repoIndex) {
|
|
6696
|
+
if (repoIndex < 0 || repoIndex >= this.syncServices.length) {
|
|
6697
|
+
throw new Error(`Invalid repository index: ${repoIndex}`);
|
|
6698
|
+
}
|
|
6699
|
+
const service = this.syncServices[repoIndex];
|
|
6700
|
+
const config = service.config;
|
|
6701
|
+
const repoName = this.getRepoName(repoIndex);
|
|
6702
|
+
const mode = resolveMode(config);
|
|
6703
|
+
const sizeTargets = [
|
|
6704
|
+
...mode === "worktree" ? [{ kind: "bare", path: config.bareRepoDir || getDefaultBareRepoDir(config.repoUrl) }] : [],
|
|
6705
|
+
{ kind: "worktree", path: config.worktreeDir }
|
|
6706
|
+
];
|
|
6707
|
+
let bareSizeBytes = 0;
|
|
6708
|
+
let worktreeSizeBytes = 0;
|
|
6709
|
+
const errors = [];
|
|
6710
|
+
for (const target of sizeTargets) {
|
|
6711
|
+
try {
|
|
6712
|
+
const size = await calculateDirectorySize(target.path);
|
|
6713
|
+
if (target.kind === "bare") {
|
|
6714
|
+
bareSizeBytes = size;
|
|
6715
|
+
} else {
|
|
6716
|
+
worktreeSizeBytes = size;
|
|
6717
|
+
}
|
|
6718
|
+
} catch (error) {
|
|
6719
|
+
errors.push(`${target.path}: ${error instanceof Error ? error.message : String(error)}`);
|
|
6720
|
+
}
|
|
6721
|
+
}
|
|
6722
|
+
const sizeBytes = bareSizeBytes + worktreeSizeBytes;
|
|
6723
|
+
const failedAllPaths = errors.length === sizeTargets.length;
|
|
6724
|
+
return {
|
|
6725
|
+
repoIndex,
|
|
6726
|
+
repoName,
|
|
6727
|
+
sizeBytes: failedAllPaths ? null : sizeBytes,
|
|
6728
|
+
sizeFormatted: failedAllPaths ? "N/A" : formatBytes(sizeBytes),
|
|
6729
|
+
bareSizeBytes,
|
|
6730
|
+
worktreeSizeBytes,
|
|
6731
|
+
error: errors.length > 0 ? errors.join("; ") : void 0
|
|
6732
|
+
};
|
|
6733
|
+
}
|
|
6578
6734
|
async getBranchesForRepo(repoIndex) {
|
|
6579
6735
|
if (repoIndex < 0 || repoIndex >= this.syncServices.length) {
|
|
6580
6736
|
throw new Error(`Invalid repository index: ${repoIndex}`);
|
|
@@ -6870,19 +7026,28 @@ var InteractiveUIService = class {
|
|
|
6870
7026
|
}
|
|
6871
7027
|
async runSyncServices(services) {
|
|
6872
7028
|
const syncResults = await Promise.allSettled(
|
|
6873
|
-
services.map(
|
|
6874
|
-
|
|
7029
|
+
services.map((service) => {
|
|
7030
|
+
const repoName = service.config.name || service.config.repoUrl;
|
|
7031
|
+
return this.limit(async () => {
|
|
6875
7032
|
service.clearRecordedSkips();
|
|
6876
|
-
|
|
6877
|
-
|
|
7033
|
+
try {
|
|
7034
|
+
if (!service.isInitialized()) {
|
|
7035
|
+
await service.initialize();
|
|
7036
|
+
}
|
|
7037
|
+
const result = await service.sync();
|
|
7038
|
+
return { service, result };
|
|
7039
|
+
} finally {
|
|
7040
|
+
this.events.emit("setSyncProgress", {
|
|
7041
|
+
repo: repoName,
|
|
7042
|
+
phase: "complete",
|
|
7043
|
+
message: "Finished",
|
|
7044
|
+
completed: true
|
|
7045
|
+
});
|
|
6878
7046
|
}
|
|
6879
|
-
const result = await service.sync();
|
|
6880
|
-
return { service, result };
|
|
6881
7047
|
}).catch((error) => {
|
|
6882
|
-
const repoName = service.config.name || service.config.repoUrl;
|
|
6883
7048
|
throw Object.assign(error instanceof Error ? error : new Error(String(error)), { repoName });
|
|
6884
|
-
})
|
|
6885
|
-
)
|
|
7049
|
+
});
|
|
7050
|
+
})
|
|
6886
7051
|
);
|
|
6887
7052
|
const failures = [];
|
|
6888
7053
|
const skipped = [];
|
|
@@ -6977,6 +7142,10 @@ var InteractiveUIService = class {
|
|
|
6977
7142
|
unsubscribe();
|
|
6978
7143
|
}
|
|
6979
7144
|
this.unsubscribeCallbacks = [];
|
|
7145
|
+
for (const unsubscribe of this.progressUnsubscribers) {
|
|
7146
|
+
unsubscribe();
|
|
7147
|
+
}
|
|
7148
|
+
this.progressUnsubscribers = [];
|
|
6980
7149
|
if (this.ownsEvents) {
|
|
6981
7150
|
this.events.removeAllListeners();
|
|
6982
7151
|
}
|
|
@@ -7106,11 +7275,14 @@ async function generateConfigFile(input2, configPath, options = {}) {
|
|
|
7106
7275
|
const useRelativeBare = !bareRepoDirRelative.startsWith("../../../");
|
|
7107
7276
|
repository.bareRepoDir = useRelativeBare ? `./${bareRepoDirRelative}` : input2.bareRepoDir;
|
|
7108
7277
|
}
|
|
7278
|
+
const defaults = {
|
|
7279
|
+
cronSchedule: input2.cronSchedule
|
|
7280
|
+
};
|
|
7281
|
+
if (input2.runOnce) {
|
|
7282
|
+
defaults.runOnce = input2.runOnce;
|
|
7283
|
+
}
|
|
7109
7284
|
const configObject = {
|
|
7110
|
-
defaults
|
|
7111
|
-
cronSchedule: input2.cronSchedule,
|
|
7112
|
-
runOnce: input2.runOnce
|
|
7113
|
-
},
|
|
7285
|
+
defaults,
|
|
7114
7286
|
repositories: [repository]
|
|
7115
7287
|
};
|
|
7116
7288
|
const configContent = `// @ts-check
|