mexus-cli 1.0.0 → 1.0.1
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/package.json +1 -1
- package/packages/server/dist/cli.mjs +191 -12
- package/packages/server/dist/cli.mjs.map +1 -1
- package/packages/web/dist/assets/{_basePickBy-B0zzcSaC.js → _basePickBy-DQhOWiJk.js} +1 -1
- package/packages/web/dist/assets/{_baseUniq-B-4_EE7n.js → _baseUniq-DXTx6DDJ.js} +1 -1
- package/packages/web/dist/assets/{arc-DFOgsfTK.js → arc-D98xlvrt.js} +1 -1
- package/packages/web/dist/assets/{architectureDiagram-2XIMDMQ5-CNksmKJ-.js → architectureDiagram-2XIMDMQ5-BFC9xn2H.js} +1 -1
- package/packages/web/dist/assets/{blockDiagram-WCTKOSBZ-B1Tw0xWQ.js → blockDiagram-WCTKOSBZ-DJH8Soam.js} +1 -1
- package/packages/web/dist/assets/{c4Diagram-IC4MRINW-BC3Xs_CM.js → c4Diagram-IC4MRINW-w36rnsiL.js} +1 -1
- package/packages/web/dist/assets/channel-s9cXVaHr.js +1 -0
- package/packages/web/dist/assets/{chunk-4BX2VUAB-Bc_dSZCa.js → chunk-4BX2VUAB-SF13Eulk.js} +1 -1
- package/packages/web/dist/assets/{chunk-55IACEB6-BkpubxQa.js → chunk-55IACEB6-wMI9Klww.js} +1 -1
- package/packages/web/dist/assets/{chunk-FMBD7UC4-DfsMHPhA.js → chunk-FMBD7UC4-WwcC59gR.js} +1 -1
- package/packages/web/dist/assets/{chunk-JSJVCQXG-DQnDNPz7.js → chunk-JSJVCQXG-DvXmNU5-.js} +1 -1
- package/packages/web/dist/assets/{chunk-KX2RTZJC-BoujkdYL.js → chunk-KX2RTZJC-BdEEznCp.js} +1 -1
- package/packages/web/dist/assets/{chunk-NQ4KR5QH-BI0GEUMc.js → chunk-NQ4KR5QH-BwNAeHYs.js} +1 -1
- package/packages/web/dist/assets/{chunk-QZHKN3VN-Dq4w7tDq.js → chunk-QZHKN3VN-C2xATrOG.js} +1 -1
- package/packages/web/dist/assets/{chunk-WL4C6EOR-DSQ5ZWfk.js → chunk-WL4C6EOR-CEAL3q8O.js} +1 -1
- package/packages/web/dist/assets/classDiagram-VBA2DB6C-quXqjdGh.js +1 -0
- package/packages/web/dist/assets/classDiagram-v2-RAHNMMFH-quXqjdGh.js +1 -0
- package/packages/web/dist/assets/clone-BwNC5Rz2.js +1 -0
- package/packages/web/dist/assets/{cose-bilkent-S5V4N54A-Caq6VRnC.js → cose-bilkent-S5V4N54A-DMB9iF_s.js} +1 -1
- package/packages/web/dist/assets/{dagre-KLK3FWXG-D1rt0jGa.js → dagre-KLK3FWXG-B3CBp1UR.js} +1 -1
- package/packages/web/dist/assets/{diagram-E7M64L7V-BBrZhLH7.js → diagram-E7M64L7V-BP3gXbyt.js} +1 -1
- package/packages/web/dist/assets/{diagram-IFDJBPK2-BFSSudzv.js → diagram-IFDJBPK2-DiWKPyS1.js} +1 -1
- package/packages/web/dist/assets/{diagram-P4PSJMXO-C3oU7Ool.js → diagram-P4PSJMXO-BRwIWc-T.js} +1 -1
- package/packages/web/dist/assets/{erDiagram-INFDFZHY-D0cx2_2Y.js → erDiagram-INFDFZHY-CwNQ0bqL.js} +1 -1
- package/packages/web/dist/assets/{flowDiagram-PKNHOUZH-BXvZGiWz.js → flowDiagram-PKNHOUZH-CGwKqUfG.js} +1 -1
- package/packages/web/dist/assets/{ganttDiagram-A5KZAMGK-C9JOODgY.js → ganttDiagram-A5KZAMGK-CwfwEk-O.js} +1 -1
- package/packages/web/dist/assets/{gitGraphDiagram-K3NZZRJ6-BiIWik3M.js → gitGraphDiagram-K3NZZRJ6-BU-TCNoX.js} +1 -1
- package/packages/web/dist/assets/{graph-KIQcHS1V.js → graph-BpGuAB34.js} +1 -1
- package/packages/web/dist/assets/{index-CMzYPOPG.js → index-BQZEjwBD.js} +233 -193
- package/packages/web/dist/assets/{infoDiagram-LFFYTUFH-DV6kISOT.js → infoDiagram-LFFYTUFH-OgqnEPLD.js} +1 -1
- package/packages/web/dist/assets/{ishikawaDiagram-PHBUUO56-Dko7qIR3.js → ishikawaDiagram-PHBUUO56-C7q1YvZf.js} +1 -1
- package/packages/web/dist/assets/{journeyDiagram-4ABVD52K-_FLfsCtQ.js → journeyDiagram-4ABVD52K-BFTnwlYT.js} +1 -1
- package/packages/web/dist/assets/{kanban-definition-K7BYSVSG-Bjf_Hkam.js → kanban-definition-K7BYSVSG-BPNSFbTq.js} +1 -1
- package/packages/web/dist/assets/{layout-D09tLn9J.js → layout-DiHSY-T6.js} +1 -1
- package/packages/web/dist/assets/{linear-BnF-DuHG.js → linear-DcbEPsvj.js} +1 -1
- package/packages/web/dist/assets/{mindmap-definition-YRQLILUH-C4ui5Uen.js → mindmap-definition-YRQLILUH-CalG0npn.js} +1 -1
- package/packages/web/dist/assets/{pieDiagram-SKSYHLDU-Chjj2B6Z.js → pieDiagram-SKSYHLDU-D1PyVe3u.js} +1 -1
- package/packages/web/dist/assets/{quadrantDiagram-337W2JSQ-BgcnBVtA.js → quadrantDiagram-337W2JSQ-bTKx0-2j.js} +1 -1
- package/packages/web/dist/assets/{requirementDiagram-Z7DCOOCP-D8i7_HQl.js → requirementDiagram-Z7DCOOCP-DHyIVcFu.js} +1 -1
- package/packages/web/dist/assets/{sankeyDiagram-WA2Y5GQK-CE8F22pR.js → sankeyDiagram-WA2Y5GQK-CifZqZcJ.js} +1 -1
- package/packages/web/dist/assets/{sequenceDiagram-2WXFIKYE-BIpm8kwX.js → sequenceDiagram-2WXFIKYE-DK8qO73H.js} +1 -1
- package/packages/web/dist/assets/{stateDiagram-RAJIS63D-lboAMp3Q.js → stateDiagram-RAJIS63D-BoK_s4xU.js} +1 -1
- package/packages/web/dist/assets/stateDiagram-v2-FVOUBMTO-BKcMBcxU.js +1 -0
- package/packages/web/dist/assets/{timeline-definition-YZTLITO2-Dh94GN9W.js → timeline-definition-YZTLITO2-GwB8m3Pz.js} +1 -1
- package/packages/web/dist/assets/{treemap-KZPCXAKY-Cnfp1I4Q.js → treemap-KZPCXAKY-RvN0JaqD.js} +1 -1
- package/packages/web/dist/assets/{vennDiagram-LZ73GAT5-oM-IB92W.js → vennDiagram-LZ73GAT5-OnlpPkDW.js} +1 -1
- package/packages/web/dist/assets/{xychartDiagram-JWTSCODW-rBsEDTWK.js → xychartDiagram-JWTSCODW-Dv-KEW3d.js} +1 -1
- package/packages/web/dist/index.html +1 -1
- package/packages/web/dist/assets/channel-BolzzYH1.js +0 -1
- package/packages/web/dist/assets/classDiagram-VBA2DB6C-DXgRkMh7.js +0 -1
- package/packages/web/dist/assets/classDiagram-v2-RAHNMMFH-DXgRkMh7.js +0 -1
- package/packages/web/dist/assets/clone-BD_2Dvk1.js +0 -1
- package/packages/web/dist/assets/stateDiagram-v2-FVOUBMTO-BYDSvNCG.js +0 -1
package/package.json
CHANGED
|
@@ -45,9 +45,34 @@ var init_ConfigManager = __esm({
|
|
|
45
45
|
statusline: true,
|
|
46
46
|
env: {}
|
|
47
47
|
},
|
|
48
|
+
codex: {
|
|
49
|
+
bin: "codex",
|
|
50
|
+
continue_flag: "",
|
|
51
|
+
resume_flag: "",
|
|
52
|
+
yolo_flag: "",
|
|
53
|
+
statusline: false,
|
|
54
|
+
env: {}
|
|
55
|
+
},
|
|
48
56
|
opencode: {
|
|
49
57
|
bin: "opencode",
|
|
50
58
|
continue_flag: "--continue",
|
|
59
|
+
resume_flag: "",
|
|
60
|
+
yolo_flag: "--yolo",
|
|
61
|
+
statusline: false,
|
|
62
|
+
env: {}
|
|
63
|
+
},
|
|
64
|
+
"kimi-cli": {
|
|
65
|
+
bin: "kimi",
|
|
66
|
+
continue_flag: "--continue",
|
|
67
|
+
resume_flag: "",
|
|
68
|
+
yolo_flag: "",
|
|
69
|
+
statusline: false,
|
|
70
|
+
env: {}
|
|
71
|
+
},
|
|
72
|
+
qodercli: {
|
|
73
|
+
bin: "qodercli",
|
|
74
|
+
continue_flag: "-c",
|
|
75
|
+
resume_flag: "-r",
|
|
51
76
|
yolo_flag: "--yolo",
|
|
52
77
|
statusline: false,
|
|
53
78
|
env: {}
|
|
@@ -147,7 +172,7 @@ var init_ConfigManager = __esm({
|
|
|
147
172
|
{ key: "codex", bin: "codex", flag: "", statusline: false },
|
|
148
173
|
{ key: "opencode", bin: "opencode", flag: "--continue", statusline: false },
|
|
149
174
|
{ key: "kimi-cli", bin: "kimi", flag: "--continue", statusline: false },
|
|
150
|
-
{ key: "
|
|
175
|
+
{ key: "qodercli", bin: "qodercli", flag: "-c", statusline: false }
|
|
151
176
|
];
|
|
152
177
|
const results = await Promise.allSettled(
|
|
153
178
|
agentBins.map(async (agent) => {
|
|
@@ -210,7 +235,7 @@ var init_ConfigManager = __esm({
|
|
|
210
235
|
{ key: "codex", bin: "codex", installHint: "npm install -g @openai/codex" },
|
|
211
236
|
{ key: "opencode", bin: "opencode", installHint: "go install github.com/opencode-ai/opencode@latest" },
|
|
212
237
|
{ key: "kimi-cli", bin: "kimi", installHint: "pip install kimi-cli" },
|
|
213
|
-
{ key: "
|
|
238
|
+
{ key: "qodercli", bin: "qodercli", installHint: "See https://docs.qoder.com/zh/cli/using-cli" }
|
|
214
239
|
];
|
|
215
240
|
const checks = await Promise.allSettled(
|
|
216
241
|
knownAgents.map(async (agent) => {
|
|
@@ -275,6 +300,7 @@ var KNOWN_FIELDS = {
|
|
|
275
300
|
// Claude Code may add more fields — add them here as discovered
|
|
276
301
|
};
|
|
277
302
|
var MIN_KNOWN_FIELDS = 2;
|
|
303
|
+
var MAX_BUFFER_SIZE = 64 * 1024;
|
|
278
304
|
var StatuslineParser = class {
|
|
279
305
|
buffer = "";
|
|
280
306
|
/**
|
|
@@ -286,6 +312,9 @@ var StatuslineParser = class {
|
|
|
286
312
|
let meta = null;
|
|
287
313
|
if (!data.includes("\n")) {
|
|
288
314
|
this.buffer += data;
|
|
315
|
+
if (this.buffer.length > MAX_BUFFER_SIZE) {
|
|
316
|
+
this.buffer = "";
|
|
317
|
+
}
|
|
289
318
|
return { cleanData: data, meta: null };
|
|
290
319
|
}
|
|
291
320
|
const combined = this.buffer + data;
|
|
@@ -913,9 +942,17 @@ var PtyManager = class {
|
|
|
913
942
|
entry.stateAnalyzer.onOutput();
|
|
914
943
|
entry.scrollback.push(cleanData);
|
|
915
944
|
entry.scrollbackBytes += cleanData.length;
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
945
|
+
if (entry.scrollbackBytes > MAX_SCROLLBACK_BYTES) {
|
|
946
|
+
let bytesToRemove = entry.scrollbackBytes - MAX_SCROLLBACK_BYTES;
|
|
947
|
+
let removeCount = 0;
|
|
948
|
+
while (removeCount < entry.scrollback.length - 1 && bytesToRemove > 0) {
|
|
949
|
+
bytesToRemove -= entry.scrollback[removeCount].length;
|
|
950
|
+
entry.scrollbackBytes -= entry.scrollback[removeCount].length;
|
|
951
|
+
removeCount++;
|
|
952
|
+
}
|
|
953
|
+
if (removeCount > 0) {
|
|
954
|
+
entry.scrollback.splice(0, removeCount);
|
|
955
|
+
}
|
|
919
956
|
}
|
|
920
957
|
for (const cb of entry.onDataCallbacks) {
|
|
921
958
|
cb(cleanData);
|
|
@@ -1101,6 +1138,35 @@ var WorktreeManager = class {
|
|
|
1101
1138
|
this.worktrees.set(paneId, entry);
|
|
1102
1139
|
return { worktreePath, branch };
|
|
1103
1140
|
}
|
|
1141
|
+
/**
|
|
1142
|
+
* Restore a worktree from a previous session.
|
|
1143
|
+
* If the worktree directory still exists, re-register it.
|
|
1144
|
+
* If not, recreate it from the existing branch.
|
|
1145
|
+
* Returns false if the branch no longer exists (stale config).
|
|
1146
|
+
*/
|
|
1147
|
+
async restore(paneId, branch, worktreePath) {
|
|
1148
|
+
const baseBranch = await this.getCurrentBranch();
|
|
1149
|
+
try {
|
|
1150
|
+
await this.git.raw(["rev-parse", "--verify", branch]);
|
|
1151
|
+
} catch {
|
|
1152
|
+
return false;
|
|
1153
|
+
}
|
|
1154
|
+
if (fs3.existsSync(worktreePath)) {
|
|
1155
|
+
this.worktrees.set(paneId, { path: worktreePath, branch, baseBranch });
|
|
1156
|
+
return true;
|
|
1157
|
+
}
|
|
1158
|
+
try {
|
|
1159
|
+
await this.git.raw(["worktree", "prune"]).catch(() => {
|
|
1160
|
+
});
|
|
1161
|
+
fs3.mkdirSync(path3.dirname(worktreePath), { recursive: true });
|
|
1162
|
+
await this.git.raw(["worktree", "add", worktreePath, branch]);
|
|
1163
|
+
this.worktrees.set(paneId, { path: worktreePath, branch, baseBranch });
|
|
1164
|
+
return true;
|
|
1165
|
+
} catch (err) {
|
|
1166
|
+
console.warn(`[WorktreeManager] Failed to restore worktree for ${paneId}:`, err.message);
|
|
1167
|
+
return false;
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1104
1170
|
/**
|
|
1105
1171
|
* Remove a worktree. Branch is kept for later merge/PR.
|
|
1106
1172
|
*/
|
|
@@ -1181,6 +1247,60 @@ var WorktreeManager = class {
|
|
|
1181
1247
|
}
|
|
1182
1248
|
return diffs;
|
|
1183
1249
|
}
|
|
1250
|
+
/**
|
|
1251
|
+
* Merge the worktree branch into the base branch (e.g. main).
|
|
1252
|
+
* First commits any uncommitted changes in the worktree, then merges.
|
|
1253
|
+
*/
|
|
1254
|
+
async merge(paneId) {
|
|
1255
|
+
const entry = this.worktrees.get(paneId);
|
|
1256
|
+
if (!entry) {
|
|
1257
|
+
return { success: false, message: "Worktree not found for this pane" };
|
|
1258
|
+
}
|
|
1259
|
+
const wtGit = simpleGit(entry.path);
|
|
1260
|
+
try {
|
|
1261
|
+
const status = await wtGit.status();
|
|
1262
|
+
const hasChanges = status.modified.length > 0 || status.created.length > 0 || status.deleted.length > 0 || status.staged.length > 0 || status.not_added.length > 0;
|
|
1263
|
+
if (hasChanges) {
|
|
1264
|
+
await wtGit.add("-A");
|
|
1265
|
+
await wtGit.commit(`nexus: auto-commit before merge (${entry.branch})`);
|
|
1266
|
+
}
|
|
1267
|
+
const log = await wtGit.log([`${entry.baseBranch}..${entry.branch}`]);
|
|
1268
|
+
if (log.total === 0) {
|
|
1269
|
+
return { success: false, message: "No changes to merge" };
|
|
1270
|
+
}
|
|
1271
|
+
await this.git.merge([entry.branch]);
|
|
1272
|
+
return {
|
|
1273
|
+
success: true,
|
|
1274
|
+
message: `Merged ${log.total} commit${log.total !== 1 ? "s" : ""} from ${entry.branch} into ${entry.baseBranch}`
|
|
1275
|
+
};
|
|
1276
|
+
} catch (err) {
|
|
1277
|
+
try {
|
|
1278
|
+
await this.git.merge(["--abort"]);
|
|
1279
|
+
} catch {
|
|
1280
|
+
}
|
|
1281
|
+
return {
|
|
1282
|
+
success: false,
|
|
1283
|
+
message: `Merge conflict: ${err.message}`
|
|
1284
|
+
};
|
|
1285
|
+
}
|
|
1286
|
+
}
|
|
1287
|
+
/**
|
|
1288
|
+
* Discard all changes: remove worktree and delete the branch.
|
|
1289
|
+
*/
|
|
1290
|
+
async discard(paneId) {
|
|
1291
|
+
const entry = this.worktrees.get(paneId);
|
|
1292
|
+
if (!entry) {
|
|
1293
|
+
return { success: false, message: "Worktree not found for this pane" };
|
|
1294
|
+
}
|
|
1295
|
+
const branch = entry.branch;
|
|
1296
|
+
await this.forceRemoveWorktree(entry.path);
|
|
1297
|
+
try {
|
|
1298
|
+
await this.git.raw(["branch", "-D", branch]);
|
|
1299
|
+
} catch {
|
|
1300
|
+
}
|
|
1301
|
+
this.worktrees.delete(paneId);
|
|
1302
|
+
return { success: true, message: `Discarded branch ${branch}` };
|
|
1303
|
+
}
|
|
1184
1304
|
getWorktreePath(paneId) {
|
|
1185
1305
|
return this.worktrees.get(paneId)?.path;
|
|
1186
1306
|
}
|
|
@@ -1494,7 +1614,7 @@ var WorkspaceManager = class {
|
|
|
1494
1614
|
this.ptyManager = new PtyManager(configManager);
|
|
1495
1615
|
this.worktreeManager = new WorktreeManager(configManager.getProjectDir());
|
|
1496
1616
|
}
|
|
1497
|
-
init() {
|
|
1617
|
+
async init() {
|
|
1498
1618
|
const wsConfig = this.configManager.initWorkspace();
|
|
1499
1619
|
this.wsName = wsConfig.name;
|
|
1500
1620
|
this.wsDescription = wsConfig.description || "";
|
|
@@ -1511,8 +1631,25 @@ var WorkspaceManager = class {
|
|
|
1511
1631
|
if (paneConfig.sessionId && paneConfig.agent !== "__shell__") {
|
|
1512
1632
|
paneConfig.restore = "resume";
|
|
1513
1633
|
}
|
|
1634
|
+
if (paneConfig.isolation === "worktree" && paneConfig.branch && paneConfig.worktreePath) {
|
|
1635
|
+
try {
|
|
1636
|
+
const restored = await this.worktreeManager.restore(paneConfig.id, paneConfig.branch, paneConfig.worktreePath);
|
|
1637
|
+
if (!restored) {
|
|
1638
|
+
console.warn(`Skipping worktree pane ${paneConfig.id} (${paneConfig.name}): branch no longer exists`);
|
|
1639
|
+
failCount++;
|
|
1640
|
+
continue;
|
|
1641
|
+
}
|
|
1642
|
+
} catch (err) {
|
|
1643
|
+
console.warn(`Skipping worktree pane ${paneConfig.id} (${paneConfig.name}): restore failed:`, err.message);
|
|
1644
|
+
failCount++;
|
|
1645
|
+
continue;
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1514
1648
|
try {
|
|
1515
1649
|
this.spawnPane(paneConfig);
|
|
1650
|
+
if (paneConfig.isolation === "worktree" && paneConfig.worktreePath) {
|
|
1651
|
+
await this.startPaneGitService(paneConfig.id, paneConfig.worktreePath);
|
|
1652
|
+
}
|
|
1516
1653
|
} catch (err) {
|
|
1517
1654
|
console.warn(`Skipping stale pane ${paneConfig.id} (${paneConfig.name}):`, err.message);
|
|
1518
1655
|
failCount++;
|
|
@@ -1605,6 +1742,28 @@ var WorkspaceManager = class {
|
|
|
1605
1742
|
this.spawnPane(config);
|
|
1606
1743
|
this.updatePaneConfigSessionId(paneId, resolvedSessionId);
|
|
1607
1744
|
}
|
|
1745
|
+
async mergeWorktree(paneId) {
|
|
1746
|
+
const pane = this.panes.get(paneId);
|
|
1747
|
+
if (!pane || pane.isolation !== "worktree") {
|
|
1748
|
+
return { success: false, message: "Pane is not a worktree pane" };
|
|
1749
|
+
}
|
|
1750
|
+
return this.worktreeManager.merge(paneId);
|
|
1751
|
+
}
|
|
1752
|
+
async discardWorktree(paneId) {
|
|
1753
|
+
const pane = this.panes.get(paneId);
|
|
1754
|
+
if (!pane || pane.isolation !== "worktree") {
|
|
1755
|
+
return { success: false, message: "Pane is not a worktree pane" };
|
|
1756
|
+
}
|
|
1757
|
+
this.stopPaneGitService(paneId);
|
|
1758
|
+
const result = await this.worktreeManager.discard(paneId);
|
|
1759
|
+
if (result.success) {
|
|
1760
|
+
pane.isolation = "shared";
|
|
1761
|
+
pane.worktreePath = void 0;
|
|
1762
|
+
pane.branch = void 0;
|
|
1763
|
+
this.emit("onPaneDiff", paneId, []);
|
|
1764
|
+
}
|
|
1765
|
+
return result;
|
|
1766
|
+
}
|
|
1608
1767
|
writeToPane(paneId, data) {
|
|
1609
1768
|
this.ptyManager.write(paneId, data);
|
|
1610
1769
|
}
|
|
@@ -1795,7 +1954,6 @@ var WorkspaceManager = class {
|
|
|
1795
1954
|
for (const [paneId] of this.perPaneGitServices) {
|
|
1796
1955
|
this.stopPaneGitService(paneId);
|
|
1797
1956
|
}
|
|
1798
|
-
await this.worktreeManager.removeAll();
|
|
1799
1957
|
}
|
|
1800
1958
|
};
|
|
1801
1959
|
|
|
@@ -2024,18 +2182,23 @@ function setupWsHandlers(socket, workspaceManager, gitService) {
|
|
|
2024
2182
|
state
|
|
2025
2183
|
});
|
|
2026
2184
|
const SCROLLBACK_CHUNK_SIZE = 64 * 1024;
|
|
2027
|
-
|
|
2028
|
-
const
|
|
2029
|
-
|
|
2185
|
+
const replayScrollback = async () => {
|
|
2186
|
+
for (const pane of state.panes) {
|
|
2187
|
+
const scrollback = workspaceManager.getScrollback(pane.id);
|
|
2188
|
+
if (!scrollback) continue;
|
|
2030
2189
|
if (scrollback.length <= SCROLLBACK_CHUNK_SIZE) {
|
|
2031
2190
|
send({ type: "terminal.output", paneId: pane.id, data: scrollback });
|
|
2032
2191
|
} else {
|
|
2033
2192
|
for (let i = 0; i < scrollback.length; i += SCROLLBACK_CHUNK_SIZE) {
|
|
2193
|
+
if (socket.readyState !== socket.OPEN) return;
|
|
2034
2194
|
send({ type: "terminal.output", paneId: pane.id, data: scrollback.slice(i, i + SCROLLBACK_CHUNK_SIZE) });
|
|
2195
|
+
await new Promise((resolve) => setImmediate(resolve));
|
|
2035
2196
|
}
|
|
2036
2197
|
}
|
|
2037
2198
|
}
|
|
2038
|
-
}
|
|
2199
|
+
};
|
|
2200
|
+
replayScrollback().catch(() => {
|
|
2201
|
+
});
|
|
2039
2202
|
const paneDiffs = workspaceManager.getPaneDiffs();
|
|
2040
2203
|
for (const [paneId, diffs] of paneDiffs) {
|
|
2041
2204
|
if (diffs.length > 0) {
|
|
@@ -2163,6 +2326,22 @@ function setupWsHandlers(socket, workspaceManager, gitService) {
|
|
|
2163
2326
|
});
|
|
2164
2327
|
}
|
|
2165
2328
|
break;
|
|
2329
|
+
case "pane.merge":
|
|
2330
|
+
workspaceManager.mergeWorktree(event.paneId).then((result) => {
|
|
2331
|
+
send({ type: "pane.merge.result", paneId: event.paneId, ...result });
|
|
2332
|
+
gitService?.refresh();
|
|
2333
|
+
}).catch((err) => {
|
|
2334
|
+
send({ type: "pane.merge.result", paneId: event.paneId, success: false, message: String(err) });
|
|
2335
|
+
});
|
|
2336
|
+
break;
|
|
2337
|
+
case "pane.discard":
|
|
2338
|
+
workspaceManager.discardWorktree(event.paneId).then((result) => {
|
|
2339
|
+
send({ type: "pane.merge.result", paneId: event.paneId, ...result });
|
|
2340
|
+
gitService?.refresh();
|
|
2341
|
+
}).catch((err) => {
|
|
2342
|
+
send({ type: "pane.merge.result", paneId: event.paneId, success: false, message: String(err) });
|
|
2343
|
+
});
|
|
2344
|
+
break;
|
|
2166
2345
|
case "pane.diff.refresh":
|
|
2167
2346
|
workspaceManager.refreshPaneDiff(event.paneId);
|
|
2168
2347
|
break;
|
|
@@ -2742,7 +2921,7 @@ async function startServer(port, projectDir) {
|
|
|
2742
2921
|
const configManager = new ConfigManager(projectDir);
|
|
2743
2922
|
configManager.loadGlobalConfig();
|
|
2744
2923
|
const workspaceManager = new WorkspaceManager(configManager);
|
|
2745
|
-
workspaceManager.init();
|
|
2924
|
+
await workspaceManager.init();
|
|
2746
2925
|
const agentsWriter = new AgentsYamlWriter(projectDir);
|
|
2747
2926
|
workspaceManager.onEvents({
|
|
2748
2927
|
onPaneAdded: () => agentsWriter.update(workspaceManager.getPanes()),
|