jinzd-ai-cli 0.4.79 → 0.4.80
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/{batch-SMUURFMA.js → batch-OUBKAHXG.js} +2 -2
- package/dist/{chunk-RRL5572W.js → chunk-2ERX5Q55.js} +1 -1
- package/dist/{chunk-FU6WMYXS.js → chunk-63R2GIRK.js} +1 -1
- package/dist/{chunk-EGJAMKAZ.js → chunk-6HZTXVTF.js} +53 -2
- package/dist/{chunk-34OKHMTQ.js → chunk-C5QENJ4P.js} +1 -1
- package/dist/{chunk-HPDDAXFY.js → chunk-CQQQFNND.js} +38 -3
- package/dist/{chunk-MOE2D3NR.js → chunk-CU5ZSHGU.js} +3 -3
- package/dist/{chunk-UTCC3UMT.js → chunk-GTKJUEBS.js} +38 -3
- package/dist/{chunk-ZT7RZYWE.js → chunk-IGHC7D62.js} +1 -1
- package/dist/electron-server.js +121 -7
- package/dist/{hub-BDEFIXFF.js → hub-SFJU4KJK.js} +1 -1
- package/dist/index.js +83 -14
- package/dist/{run-tests-O2CYJF3Y.js → run-tests-4PZKLURD.js} +1 -1
- package/dist/{run-tests-WPSQCOIG.js → run-tests-7N2WILA3.js} +2 -2
- package/dist/{semantic-RBWU76MD.js → semantic-ICJ536BG.js} +3 -1
- package/dist/{semantic-MD7HYPWZ.js → semantic-MYAXLDCZ.js} +3 -1
- package/dist/{server-MHY4E453.js → server-HJ64OR7A.js} +74 -11
- package/dist/{task-orchestrator-MWZ7NMES.js → task-orchestrator-RVKRP6LI.js} +4 -4
- package/package.json +1 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
ConfigManager
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-C5QENJ4P.js";
|
|
5
5
|
import "./chunk-2ZD3YTVM.js";
|
|
6
|
-
import "./chunk-
|
|
6
|
+
import "./chunk-2ERX5Q55.js";
|
|
7
7
|
|
|
8
8
|
// src/cli/batch.ts
|
|
9
9
|
import Anthropic from "@anthropic-ai/sdk";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
schemaToJsonSchema,
|
|
4
4
|
truncateForPersist
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-CU5ZSHGU.js";
|
|
6
6
|
import {
|
|
7
7
|
AuthError,
|
|
8
8
|
ProviderError,
|
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
MCP_PROTOCOL_VERSION,
|
|
19
19
|
MCP_TOOL_PREFIX,
|
|
20
20
|
VERSION
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-2ERX5Q55.js";
|
|
22
22
|
|
|
23
23
|
// src/providers/claude.ts
|
|
24
24
|
import Anthropic from "@anthropic-ai/sdk";
|
|
@@ -2135,6 +2135,12 @@ function getContentText(content) {
|
|
|
2135
2135
|
function makeBranchId() {
|
|
2136
2136
|
return Math.random().toString(16).slice(2, 8);
|
|
2137
2137
|
}
|
|
2138
|
+
function messagesEqual(a, b) {
|
|
2139
|
+
if (a.role !== b.role) return false;
|
|
2140
|
+
if (JSON.stringify(a.content) !== JSON.stringify(b.content)) return false;
|
|
2141
|
+
if (JSON.stringify(a.toolCalls ?? null) !== JSON.stringify(b.toolCalls ?? null)) return false;
|
|
2142
|
+
return true;
|
|
2143
|
+
}
|
|
2138
2144
|
var Session = class _Session {
|
|
2139
2145
|
id;
|
|
2140
2146
|
provider;
|
|
@@ -2376,6 +2382,51 @@ var Session = class _Session {
|
|
|
2376
2382
|
const m = this._inactiveBranchMessages.get(id);
|
|
2377
2383
|
return m ? m.slice() : null;
|
|
2378
2384
|
}
|
|
2385
|
+
// ── B3 Branch diff + cherry-pick (v0.4.80+) ────────────────────────
|
|
2386
|
+
/**
|
|
2387
|
+
* Compare messages between two branches. Finds the longest common prefix
|
|
2388
|
+
* by message equality (role + content + toolCalls shape) — NOT by fork
|
|
2389
|
+
* point metadata, so user-edited histories still diff cleanly.
|
|
2390
|
+
*
|
|
2391
|
+
* @param sourceId Branch to compare
|
|
2392
|
+
* @param targetId Branch to compare against (defaults to active branch)
|
|
2393
|
+
* @returns BranchDiff, or null if either branch id is unknown
|
|
2394
|
+
*/
|
|
2395
|
+
diffBranches(sourceId, targetId) {
|
|
2396
|
+
const tgt = targetId ?? this.activeBranchId;
|
|
2397
|
+
const src = this.getBranchMessages(sourceId);
|
|
2398
|
+
const dst = this.getBranchMessages(tgt);
|
|
2399
|
+
if (!src || !dst) return null;
|
|
2400
|
+
let i = 0;
|
|
2401
|
+
while (i < src.length && i < dst.length && messagesEqual(src[i], dst[i])) i++;
|
|
2402
|
+
return {
|
|
2403
|
+
sourceId,
|
|
2404
|
+
targetId: tgt,
|
|
2405
|
+
commonPrefix: i,
|
|
2406
|
+
sourceOnly: src.slice(i),
|
|
2407
|
+
targetOnly: dst.slice(i)
|
|
2408
|
+
};
|
|
2409
|
+
}
|
|
2410
|
+
/**
|
|
2411
|
+
* Copy a single message from another branch into the active branch
|
|
2412
|
+
* (appended at the end). Timestamp is reset to now so it's clear when
|
|
2413
|
+
* the cherry-pick happened.
|
|
2414
|
+
*
|
|
2415
|
+
* @returns the cloned message, or null if sourceId / msgIndex is invalid
|
|
2416
|
+
*/
|
|
2417
|
+
cherryPickMessage(sourceId, msgIndex) {
|
|
2418
|
+
const src = this.getBranchMessages(sourceId);
|
|
2419
|
+
if (!src) return null;
|
|
2420
|
+
if (msgIndex < 0 || msgIndex >= src.length) return null;
|
|
2421
|
+
const orig = src[msgIndex];
|
|
2422
|
+
const copy = {
|
|
2423
|
+
...orig,
|
|
2424
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2425
|
+
};
|
|
2426
|
+
this.messages.push(copy);
|
|
2427
|
+
this.updated = /* @__PURE__ */ new Date();
|
|
2428
|
+
return copy;
|
|
2429
|
+
}
|
|
2379
2430
|
getMeta() {
|
|
2380
2431
|
return {
|
|
2381
2432
|
id: this.id,
|
|
@@ -12,8 +12,42 @@ import {
|
|
|
12
12
|
} from "./chunk-PFYAAX2S.js";
|
|
13
13
|
|
|
14
14
|
// src/symbols/semantic.ts
|
|
15
|
-
function
|
|
16
|
-
|
|
15
|
+
function pathTokens(absFile, root) {
|
|
16
|
+
if (!absFile) return "";
|
|
17
|
+
const norm = absFile.replace(/\\/g, "/");
|
|
18
|
+
let rel = norm;
|
|
19
|
+
if (root) {
|
|
20
|
+
const rootNorm = root.replace(/\\/g, "/").replace(/\/$/, "") + "/";
|
|
21
|
+
if (norm.toLowerCase().startsWith(rootNorm.toLowerCase())) {
|
|
22
|
+
rel = norm.slice(rootNorm.length);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const noExt = rel.replace(/\.[^./]+$/, "");
|
|
26
|
+
const parts = noExt.split(/[/.\-_]/).filter((t) => {
|
|
27
|
+
if (!t) return false;
|
|
28
|
+
if (t.length < 2) return false;
|
|
29
|
+
if (/^\d+$/.test(t)) return false;
|
|
30
|
+
if (t === "src" || t === "lib" || t === "app" || t === "dist") return false;
|
|
31
|
+
return true;
|
|
32
|
+
});
|
|
33
|
+
const seen = /* @__PURE__ */ new Set();
|
|
34
|
+
const out = [];
|
|
35
|
+
for (const t of parts) {
|
|
36
|
+
const lower = t.toLowerCase();
|
|
37
|
+
if (seen.has(lower)) continue;
|
|
38
|
+
seen.add(lower);
|
|
39
|
+
out.push(t);
|
|
40
|
+
if (out.length >= 6) break;
|
|
41
|
+
}
|
|
42
|
+
return out.join(" ");
|
|
43
|
+
}
|
|
44
|
+
function buildEmbeddingText(s, root) {
|
|
45
|
+
const parts = [];
|
|
46
|
+
if (root) {
|
|
47
|
+
const tokens = pathTokens(s.location.file, root);
|
|
48
|
+
if (tokens) parts.push(tokens);
|
|
49
|
+
}
|
|
50
|
+
parts.push(s.kind, s.name);
|
|
17
51
|
if (s.container) parts.push(`in ${s.container}`);
|
|
18
52
|
if (s.signature) parts.push(s.signature);
|
|
19
53
|
if (s.doc) parts.push(s.doc);
|
|
@@ -42,7 +76,7 @@ async function rebuildSemanticIndex(root, opts = {}) {
|
|
|
42
76
|
const batch = [];
|
|
43
77
|
for (let j = i; j < end; j++) {
|
|
44
78
|
symbolIdx[j] = j;
|
|
45
|
-
batch.push(buildEmbeddingText(index.symbols[j]));
|
|
79
|
+
batch.push(buildEmbeddingText(index.symbols[j], index.root));
|
|
46
80
|
}
|
|
47
81
|
const batchStart = Date.now();
|
|
48
82
|
const rows = await embed(batch);
|
|
@@ -77,6 +111,7 @@ function hasSemanticIndex(root) {
|
|
|
77
111
|
}
|
|
78
112
|
|
|
79
113
|
export {
|
|
114
|
+
pathTokens,
|
|
80
115
|
buildEmbeddingText,
|
|
81
116
|
rebuildSemanticIndex,
|
|
82
117
|
semanticSearch,
|
|
@@ -13,13 +13,13 @@ import {
|
|
|
13
13
|
import {
|
|
14
14
|
hasSemanticIndex,
|
|
15
15
|
semanticSearch
|
|
16
|
-
} from "./chunk-
|
|
16
|
+
} from "./chunk-CQQQFNND.js";
|
|
17
17
|
import {
|
|
18
18
|
loadIndex
|
|
19
19
|
} from "./chunk-6VRJGH25.js";
|
|
20
20
|
import {
|
|
21
21
|
runTestsTool
|
|
22
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-IGHC7D62.js";
|
|
23
23
|
import {
|
|
24
24
|
CONFIG_DIR_NAME,
|
|
25
25
|
DEFAULT_MAX_TOOL_OUTPUT_CHARS_CAP,
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
SUBAGENT_ALLOWED_TOOLS,
|
|
28
28
|
SUBAGENT_DEFAULT_MAX_ROUNDS,
|
|
29
29
|
SUBAGENT_MAX_ROUNDS_LIMIT
|
|
30
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-2ERX5Q55.js";
|
|
31
31
|
|
|
32
32
|
// src/tools/builtin/bash.ts
|
|
33
33
|
import { execSync } from "child_process";
|
|
@@ -11,8 +11,42 @@ import {
|
|
|
11
11
|
} from "./chunk-XMA222FQ.js";
|
|
12
12
|
|
|
13
13
|
// src/symbols/semantic.ts
|
|
14
|
-
function
|
|
15
|
-
|
|
14
|
+
function pathTokens(absFile, root) {
|
|
15
|
+
if (!absFile) return "";
|
|
16
|
+
const norm = absFile.replace(/\\/g, "/");
|
|
17
|
+
let rel = norm;
|
|
18
|
+
if (root) {
|
|
19
|
+
const rootNorm = root.replace(/\\/g, "/").replace(/\/$/, "") + "/";
|
|
20
|
+
if (norm.toLowerCase().startsWith(rootNorm.toLowerCase())) {
|
|
21
|
+
rel = norm.slice(rootNorm.length);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const noExt = rel.replace(/\.[^./]+$/, "");
|
|
25
|
+
const parts = noExt.split(/[/.\-_]/).filter((t) => {
|
|
26
|
+
if (!t) return false;
|
|
27
|
+
if (t.length < 2) return false;
|
|
28
|
+
if (/^\d+$/.test(t)) return false;
|
|
29
|
+
if (t === "src" || t === "lib" || t === "app" || t === "dist") return false;
|
|
30
|
+
return true;
|
|
31
|
+
});
|
|
32
|
+
const seen = /* @__PURE__ */ new Set();
|
|
33
|
+
const out = [];
|
|
34
|
+
for (const t of parts) {
|
|
35
|
+
const lower = t.toLowerCase();
|
|
36
|
+
if (seen.has(lower)) continue;
|
|
37
|
+
seen.add(lower);
|
|
38
|
+
out.push(t);
|
|
39
|
+
if (out.length >= 6) break;
|
|
40
|
+
}
|
|
41
|
+
return out.join(" ");
|
|
42
|
+
}
|
|
43
|
+
function buildEmbeddingText(s, root) {
|
|
44
|
+
const parts = [];
|
|
45
|
+
if (root) {
|
|
46
|
+
const tokens = pathTokens(s.location.file, root);
|
|
47
|
+
if (tokens) parts.push(tokens);
|
|
48
|
+
}
|
|
49
|
+
parts.push(s.kind, s.name);
|
|
16
50
|
if (s.container) parts.push(`in ${s.container}`);
|
|
17
51
|
if (s.signature) parts.push(s.signature);
|
|
18
52
|
if (s.doc) parts.push(s.doc);
|
|
@@ -41,7 +75,7 @@ async function rebuildSemanticIndex(root, opts = {}) {
|
|
|
41
75
|
const batch = [];
|
|
42
76
|
for (let j = i; j < end; j++) {
|
|
43
77
|
symbolIdx[j] = j;
|
|
44
|
-
batch.push(buildEmbeddingText(index.symbols[j]));
|
|
78
|
+
batch.push(buildEmbeddingText(index.symbols[j], index.root));
|
|
45
79
|
}
|
|
46
80
|
const batchStart = Date.now();
|
|
47
81
|
const rows = await embed(batch);
|
|
@@ -76,6 +110,7 @@ function hasSemanticIndex(root) {
|
|
|
76
110
|
}
|
|
77
111
|
|
|
78
112
|
export {
|
|
113
|
+
pathTokens,
|
|
79
114
|
buildEmbeddingText,
|
|
80
115
|
rebuildSemanticIndex,
|
|
81
116
|
semanticSearch,
|
package/dist/electron-server.js
CHANGED
|
@@ -36,11 +36,11 @@ import {
|
|
|
36
36
|
VERSION,
|
|
37
37
|
buildUserIdentityPrompt,
|
|
38
38
|
runTestsTool
|
|
39
|
-
} from "./chunk-
|
|
39
|
+
} from "./chunk-63R2GIRK.js";
|
|
40
40
|
import {
|
|
41
41
|
hasSemanticIndex,
|
|
42
42
|
semanticSearch
|
|
43
|
-
} from "./chunk-
|
|
43
|
+
} from "./chunk-GTKJUEBS.js";
|
|
44
44
|
import {
|
|
45
45
|
loadIndex
|
|
46
46
|
} from "./chunk-BJAT4GNC.js";
|
|
@@ -2516,6 +2516,12 @@ function getContentText(content) {
|
|
|
2516
2516
|
function makeBranchId() {
|
|
2517
2517
|
return Math.random().toString(16).slice(2, 8);
|
|
2518
2518
|
}
|
|
2519
|
+
function messagesEqual(a, b) {
|
|
2520
|
+
if (a.role !== b.role) return false;
|
|
2521
|
+
if (JSON.stringify(a.content) !== JSON.stringify(b.content)) return false;
|
|
2522
|
+
if (JSON.stringify(a.toolCalls ?? null) !== JSON.stringify(b.toolCalls ?? null)) return false;
|
|
2523
|
+
return true;
|
|
2524
|
+
}
|
|
2519
2525
|
var Session = class _Session {
|
|
2520
2526
|
id;
|
|
2521
2527
|
provider;
|
|
@@ -2757,6 +2763,51 @@ var Session = class _Session {
|
|
|
2757
2763
|
const m = this._inactiveBranchMessages.get(id);
|
|
2758
2764
|
return m ? m.slice() : null;
|
|
2759
2765
|
}
|
|
2766
|
+
// ── B3 Branch diff + cherry-pick (v0.4.80+) ────────────────────────
|
|
2767
|
+
/**
|
|
2768
|
+
* Compare messages between two branches. Finds the longest common prefix
|
|
2769
|
+
* by message equality (role + content + toolCalls shape) — NOT by fork
|
|
2770
|
+
* point metadata, so user-edited histories still diff cleanly.
|
|
2771
|
+
*
|
|
2772
|
+
* @param sourceId Branch to compare
|
|
2773
|
+
* @param targetId Branch to compare against (defaults to active branch)
|
|
2774
|
+
* @returns BranchDiff, or null if either branch id is unknown
|
|
2775
|
+
*/
|
|
2776
|
+
diffBranches(sourceId, targetId) {
|
|
2777
|
+
const tgt = targetId ?? this.activeBranchId;
|
|
2778
|
+
const src = this.getBranchMessages(sourceId);
|
|
2779
|
+
const dst = this.getBranchMessages(tgt);
|
|
2780
|
+
if (!src || !dst) return null;
|
|
2781
|
+
let i = 0;
|
|
2782
|
+
while (i < src.length && i < dst.length && messagesEqual(src[i], dst[i])) i++;
|
|
2783
|
+
return {
|
|
2784
|
+
sourceId,
|
|
2785
|
+
targetId: tgt,
|
|
2786
|
+
commonPrefix: i,
|
|
2787
|
+
sourceOnly: src.slice(i),
|
|
2788
|
+
targetOnly: dst.slice(i)
|
|
2789
|
+
};
|
|
2790
|
+
}
|
|
2791
|
+
/**
|
|
2792
|
+
* Copy a single message from another branch into the active branch
|
|
2793
|
+
* (appended at the end). Timestamp is reset to now so it's clear when
|
|
2794
|
+
* the cherry-pick happened.
|
|
2795
|
+
*
|
|
2796
|
+
* @returns the cloned message, or null if sourceId / msgIndex is invalid
|
|
2797
|
+
*/
|
|
2798
|
+
cherryPickMessage(sourceId, msgIndex) {
|
|
2799
|
+
const src = this.getBranchMessages(sourceId);
|
|
2800
|
+
if (!src) return null;
|
|
2801
|
+
if (msgIndex < 0 || msgIndex >= src.length) return null;
|
|
2802
|
+
const orig = src[msgIndex];
|
|
2803
|
+
const copy = {
|
|
2804
|
+
...orig,
|
|
2805
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
2806
|
+
};
|
|
2807
|
+
this.messages.push(copy);
|
|
2808
|
+
this.updated = /* @__PURE__ */ new Date();
|
|
2809
|
+
return copy;
|
|
2810
|
+
}
|
|
2760
2811
|
getMeta() {
|
|
2761
2812
|
return {
|
|
2762
2813
|
id: this.id,
|
|
@@ -10241,7 +10292,7 @@ Tokens: in=${this.sessionTokenUsage.inputTokens} out=${this.sessionTokenUsage.ou
|
|
|
10241
10292
|
" /diff [--stats] \u2014 Show file modifications in this session",
|
|
10242
10293
|
" /checkpoint [save|restore|delete] <name> \u2014 Session checkpoints",
|
|
10243
10294
|
" /fork [checkpoint] \u2014 Fork session from checkpoint or current",
|
|
10244
|
-
" /branch [list|new|switch|delete|rename] \u2014 Manage conversation branches",
|
|
10295
|
+
" /branch [list|new|switch|delete|rename|diff|cherry-pick] \u2014 Manage conversation branches (fork tree, cross-branch picks)",
|
|
10245
10296
|
" /index [status|rebuild|clear|semantic-rebuild|semantic-clear] \u2014 Symbol + semantic index (find_symbol / search_code)",
|
|
10246
10297
|
" /review [--staged] \u2014 AI code review from git diff",
|
|
10247
10298
|
" /security-review \u2014 Security vulnerability scan on git diff",
|
|
@@ -10581,7 +10632,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
10581
10632
|
lines.push(` ${marker}${b.id.padEnd(10)} ${b.title.padEnd(20)} (${count} msgs)${parent}`);
|
|
10582
10633
|
}
|
|
10583
10634
|
lines.push("");
|
|
10584
|
-
lines.push("Usage: /branch new <msgIndex> [title] | switch <id> | delete <id> | rename <id> <title>");
|
|
10635
|
+
lines.push("Usage: /branch new <msgIndex> [title] | switch <id> | delete <id> | rename <id> <title> | diff <id> | cherry-pick <id> <msgIndex>");
|
|
10585
10636
|
this.send({ type: "info", message: lines.join("\n") });
|
|
10586
10637
|
break;
|
|
10587
10638
|
}
|
|
@@ -10659,7 +10710,70 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
10659
10710
|
}
|
|
10660
10711
|
break;
|
|
10661
10712
|
}
|
|
10662
|
-
|
|
10713
|
+
if (sub === "diff") {
|
|
10714
|
+
const id = args[1];
|
|
10715
|
+
if (!id) {
|
|
10716
|
+
this.send({ type: "error", message: "Usage: /branch diff <id>" });
|
|
10717
|
+
break;
|
|
10718
|
+
}
|
|
10719
|
+
const d = session.diffBranches(id);
|
|
10720
|
+
if (!d) {
|
|
10721
|
+
this.send({ type: "error", message: `Branch "${id}" not found.` });
|
|
10722
|
+
break;
|
|
10723
|
+
}
|
|
10724
|
+
const preview = (m) => {
|
|
10725
|
+
const text = typeof m.content === "string" ? m.content : "[complex content]";
|
|
10726
|
+
return text.replace(/\s+/g, " ").trim().slice(0, 70);
|
|
10727
|
+
};
|
|
10728
|
+
const lines = [
|
|
10729
|
+
`\u{1F500} diff ${id} (source) \u2194 ${session.activeBranchId} (active)`,
|
|
10730
|
+
`Common prefix: ${d.commonPrefix} message(s)`
|
|
10731
|
+
];
|
|
10732
|
+
if (d.sourceOnly.length === 0 && d.targetOnly.length === 0) {
|
|
10733
|
+
lines.push("Branches are identical.");
|
|
10734
|
+
} else {
|
|
10735
|
+
if (d.sourceOnly.length > 0) {
|
|
10736
|
+
lines.push("", `Only in ${id} (${d.sourceOnly.length}):`);
|
|
10737
|
+
d.sourceOnly.forEach(
|
|
10738
|
+
(m, i) => lines.push(` [${d.commonPrefix + i}] ${m.role}: ${preview(m)}`)
|
|
10739
|
+
);
|
|
10740
|
+
}
|
|
10741
|
+
if (d.targetOnly.length > 0) {
|
|
10742
|
+
lines.push("", `Only in ${session.activeBranchId} (active) (${d.targetOnly.length}):`);
|
|
10743
|
+
d.targetOnly.forEach(
|
|
10744
|
+
(m, i) => lines.push(` [${d.commonPrefix + i}] ${m.role}: ${preview(m)}`)
|
|
10745
|
+
);
|
|
10746
|
+
}
|
|
10747
|
+
lines.push("", `Use /branch cherry-pick ${id} <index> to copy a message into the active branch.`);
|
|
10748
|
+
}
|
|
10749
|
+
this.send({ type: "info", message: lines.join("\n") });
|
|
10750
|
+
break;
|
|
10751
|
+
}
|
|
10752
|
+
if (sub === "cherry-pick") {
|
|
10753
|
+
const id = args[1];
|
|
10754
|
+
const idxStr = args[2];
|
|
10755
|
+
if (!id || !idxStr) {
|
|
10756
|
+
this.send({ type: "error", message: "Usage: /branch cherry-pick <source-id> <msg-index>" });
|
|
10757
|
+
break;
|
|
10758
|
+
}
|
|
10759
|
+
const idx = parseInt(idxStr, 10);
|
|
10760
|
+
if (Number.isNaN(idx)) {
|
|
10761
|
+
this.send({ type: "error", message: `Invalid message index: "${idxStr}"` });
|
|
10762
|
+
break;
|
|
10763
|
+
}
|
|
10764
|
+
const picked = session.cherryPickMessage(id, idx);
|
|
10765
|
+
if (!picked) {
|
|
10766
|
+
this.send({ type: "error", message: `Cherry-pick failed \u2014 branch "${id}" not found, or index ${idx} out of range.` });
|
|
10767
|
+
break;
|
|
10768
|
+
}
|
|
10769
|
+
await this.sessions.save();
|
|
10770
|
+
const preview = typeof picked.content === "string" ? picked.content.replace(/\s+/g, " ").trim().slice(0, 60) : "[complex content]";
|
|
10771
|
+
this.send({ type: "info", message: `\u2713 Cherry-picked ${picked.role} message from "${id}"[${idx}] \u2192 active branch (${session.messages.length} msgs): ${preview}` });
|
|
10772
|
+
this.sendSessionMessages();
|
|
10773
|
+
this.sendStatus();
|
|
10774
|
+
break;
|
|
10775
|
+
}
|
|
10776
|
+
this.send({ type: "error", message: `Unknown subcommand: ${sub}. Use list/new/switch/delete/rename/diff/cherry-pick.` });
|
|
10663
10777
|
break;
|
|
10664
10778
|
}
|
|
10665
10779
|
// ── /index ──────────────────────────────────────────────────────
|
|
@@ -10717,7 +10831,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
10717
10831
|
message: `Building semantic index for ${idx.symbolCount} symbols\u2026 (first run downloads ~117 MB model)`
|
|
10718
10832
|
});
|
|
10719
10833
|
try {
|
|
10720
|
-
const { rebuildSemanticIndex } = await import("./semantic-
|
|
10834
|
+
const { rebuildSemanticIndex } = await import("./semantic-MYAXLDCZ.js");
|
|
10721
10835
|
const stats = await rebuildSemanticIndex(root);
|
|
10722
10836
|
const first = stats.modelFirstLoadMs ? ` (model load+first batch ${stats.modelFirstLoadMs}ms)` : "";
|
|
10723
10837
|
this.send({
|
|
@@ -10904,7 +11018,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
10904
11018
|
case "test": {
|
|
10905
11019
|
this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
|
|
10906
11020
|
try {
|
|
10907
|
-
const { executeTests } = await import("./run-tests-
|
|
11021
|
+
const { executeTests } = await import("./run-tests-4PZKLURD.js");
|
|
10908
11022
|
const argStr = args.join(" ").trim();
|
|
10909
11023
|
let testArgs = {};
|
|
10910
11024
|
if (argStr) {
|
|
@@ -385,7 +385,7 @@ ${content}`);
|
|
|
385
385
|
}
|
|
386
386
|
}
|
|
387
387
|
async function runTaskMode(config, providers, configManager, topic) {
|
|
388
|
-
const { TaskOrchestrator } = await import("./task-orchestrator-
|
|
388
|
+
const { TaskOrchestrator } = await import("./task-orchestrator-RVKRP6LI.js");
|
|
389
389
|
const orchestrator = new TaskOrchestrator(config, providers, configManager);
|
|
390
390
|
let interrupted = false;
|
|
391
391
|
const onSigint = () => {
|
package/dist/index.js
CHANGED
|
@@ -30,10 +30,10 @@ import {
|
|
|
30
30
|
saveDevState,
|
|
31
31
|
sessionHasMeaningfulContent,
|
|
32
32
|
setupProxy
|
|
33
|
-
} from "./chunk-
|
|
33
|
+
} from "./chunk-6HZTXVTF.js";
|
|
34
34
|
import {
|
|
35
35
|
ConfigManager
|
|
36
|
-
} from "./chunk-
|
|
36
|
+
} from "./chunk-C5QENJ4P.js";
|
|
37
37
|
import {
|
|
38
38
|
ToolExecutor,
|
|
39
39
|
ToolRegistry,
|
|
@@ -49,16 +49,16 @@ import {
|
|
|
49
49
|
spawnAgentContext,
|
|
50
50
|
theme,
|
|
51
51
|
undoStack
|
|
52
|
-
} from "./chunk-
|
|
52
|
+
} from "./chunk-CU5ZSHGU.js";
|
|
53
53
|
import "./chunk-2ZD3YTVM.js";
|
|
54
54
|
import {
|
|
55
55
|
fileCheckpoints
|
|
56
56
|
} from "./chunk-4BKXL7SM.js";
|
|
57
57
|
import "./chunk-NHNWUBXB.js";
|
|
58
|
-
import "./chunk-
|
|
58
|
+
import "./chunk-CQQQFNND.js";
|
|
59
59
|
import "./chunk-6VRJGH25.js";
|
|
60
60
|
import "./chunk-PFYAAX2S.js";
|
|
61
|
-
import "./chunk-
|
|
61
|
+
import "./chunk-IGHC7D62.js";
|
|
62
62
|
import {
|
|
63
63
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
64
64
|
AUTHOR,
|
|
@@ -80,7 +80,7 @@ import {
|
|
|
80
80
|
SKILLS_DIR_NAME,
|
|
81
81
|
VERSION,
|
|
82
82
|
buildUserIdentityPrompt
|
|
83
|
-
} from "./chunk-
|
|
83
|
+
} from "./chunk-2ERX5Q55.js";
|
|
84
84
|
|
|
85
85
|
// src/index.ts
|
|
86
86
|
import { program } from "commander";
|
|
@@ -978,7 +978,7 @@ function createDefaultCommands() {
|
|
|
978
978
|
" /bug [--copy] - Generate bug report template (--copy to clipboard)",
|
|
979
979
|
" /diff [--stats] - Show all file modifications in this session",
|
|
980
980
|
" /fork [checkpoint] - Fork session from checkpoint or current position",
|
|
981
|
-
" /branch [list|new|switch|delete|rename] - Manage conversation branches (fork tree)",
|
|
981
|
+
" /branch [list|new|switch|delete|rename|diff|cherry-pick] - Manage conversation branches (fork tree, cross-branch picks)",
|
|
982
982
|
" /index [status|rebuild|clear|semantic-rebuild|semantic-clear] - Symbol + semantic index (find_symbol / search_code)",
|
|
983
983
|
" /yolo [on|off] - Toggle session auto-approve (skip confirmations)",
|
|
984
984
|
" /exit - Exit"
|
|
@@ -2254,7 +2254,7 @@ ${hint}` : "")
|
|
|
2254
2254
|
{
|
|
2255
2255
|
name: "branch",
|
|
2256
2256
|
description: "Manage conversation branches (fork/switch/list/delete/rename)",
|
|
2257
|
-
usage: "/branch [list | new <msgIndex> [title] | switch <id> | delete <id> | rename <id> <title>]",
|
|
2257
|
+
usage: "/branch [list | new <msgIndex> [title] | switch <id> | delete <id> | rename <id> <title> | diff <id> | cherry-pick <id> <msgIndex>]",
|
|
2258
2258
|
async execute(args, ctx) {
|
|
2259
2259
|
const session = ctx.sessions.current;
|
|
2260
2260
|
if (!session) {
|
|
@@ -2280,6 +2280,8 @@ ${hint}` : "")
|
|
|
2280
2280
|
console.log(theme.dim(" /branch switch <id> \u2014 switch active branch"));
|
|
2281
2281
|
console.log(theme.dim(" /branch delete <id> \u2014 delete inactive branch"));
|
|
2282
2282
|
console.log(theme.dim(" /branch rename <id> <title> \u2014 rename a branch"));
|
|
2283
|
+
console.log(theme.dim(" /branch diff <id> \u2014 compare branch with active, list divergent messages"));
|
|
2284
|
+
console.log(theme.dim(" /branch cherry-pick <id> <idx> \u2014 copy one message from branch <id> into active"));
|
|
2283
2285
|
console.log();
|
|
2284
2286
|
return;
|
|
2285
2287
|
}
|
|
@@ -2363,7 +2365,74 @@ ${hint}` : "")
|
|
|
2363
2365
|
}
|
|
2364
2366
|
return;
|
|
2365
2367
|
}
|
|
2366
|
-
|
|
2368
|
+
if (sub === "diff") {
|
|
2369
|
+
const id = args[1];
|
|
2370
|
+
if (!id) {
|
|
2371
|
+
ctx.renderer.renderError("Usage: /branch diff <id> \u2014 diff the given branch against the active branch");
|
|
2372
|
+
return;
|
|
2373
|
+
}
|
|
2374
|
+
const d = session.diffBranches(id);
|
|
2375
|
+
if (!d) {
|
|
2376
|
+
ctx.renderer.renderError(`Branch "${id}" not found.`);
|
|
2377
|
+
return;
|
|
2378
|
+
}
|
|
2379
|
+
const active = session.activeBranchId;
|
|
2380
|
+
console.log(`
|
|
2381
|
+
${theme.info("diff")} ${id} (source) \u2194 ${active} (active)`);
|
|
2382
|
+
console.log(theme.dim(` Common prefix: ${d.commonPrefix} message(s)`));
|
|
2383
|
+
if (d.sourceOnly.length === 0 && d.targetOnly.length === 0) {
|
|
2384
|
+
console.log(theme.success(" Branches are identical.\n"));
|
|
2385
|
+
return;
|
|
2386
|
+
}
|
|
2387
|
+
const preview = (m) => {
|
|
2388
|
+
const text = typeof m.content === "string" ? m.content : "[complex content]";
|
|
2389
|
+
return text.replace(/\s+/g, " ").trim().slice(0, 70);
|
|
2390
|
+
};
|
|
2391
|
+
if (d.sourceOnly.length > 0) {
|
|
2392
|
+
console.log(theme.dim(`
|
|
2393
|
+
Only in ${id} (${d.sourceOnly.length}):`));
|
|
2394
|
+
d.sourceOnly.forEach((m, i) => {
|
|
2395
|
+
console.log(` ${theme.dim(`[${d.commonPrefix + i}]`)} ${m.role}: ${preview(m)}`);
|
|
2396
|
+
});
|
|
2397
|
+
}
|
|
2398
|
+
if (d.targetOnly.length > 0) {
|
|
2399
|
+
console.log(theme.dim(`
|
|
2400
|
+
Only in ${active} (active) (${d.targetOnly.length}):`));
|
|
2401
|
+
d.targetOnly.forEach((m, i) => {
|
|
2402
|
+
console.log(` ${theme.dim(`[${d.commonPrefix + i}]`)} ${m.role}: ${preview(m)}`);
|
|
2403
|
+
});
|
|
2404
|
+
}
|
|
2405
|
+
console.log(theme.dim(`
|
|
2406
|
+
Use /branch cherry-pick ${id} <index> to copy a message into the active branch.
|
|
2407
|
+
`));
|
|
2408
|
+
return;
|
|
2409
|
+
}
|
|
2410
|
+
if (sub === "cherry-pick") {
|
|
2411
|
+
const id = args[1];
|
|
2412
|
+
const idxStr = args[2];
|
|
2413
|
+
if (!id || !idxStr) {
|
|
2414
|
+
ctx.renderer.renderError("Usage: /branch cherry-pick <source-id> <msg-index>");
|
|
2415
|
+
return;
|
|
2416
|
+
}
|
|
2417
|
+
const idx = parseInt(idxStr, 10);
|
|
2418
|
+
if (Number.isNaN(idx)) {
|
|
2419
|
+
ctx.renderer.renderError(`Invalid message index: "${idxStr}"`);
|
|
2420
|
+
return;
|
|
2421
|
+
}
|
|
2422
|
+
const picked = session.cherryPickMessage(id, idx);
|
|
2423
|
+
if (!picked) {
|
|
2424
|
+
ctx.renderer.renderError(`Cherry-pick failed \u2014 branch "${id}" not found, or index ${idx} out of range.`);
|
|
2425
|
+
return;
|
|
2426
|
+
}
|
|
2427
|
+
await ctx.sessions.save();
|
|
2428
|
+
const preview = typeof picked.content === "string" ? picked.content.replace(/\s+/g, " ").trim().slice(0, 60) : "[complex content]";
|
|
2429
|
+
console.log(theme.success(`
|
|
2430
|
+
\u2713 Cherry-picked ${picked.role} message from "${id}"[${idx}] \u2192 active branch (now ${session.messages.length} msgs)`));
|
|
2431
|
+
console.log(theme.dim(` ${preview}
|
|
2432
|
+
`));
|
|
2433
|
+
return;
|
|
2434
|
+
}
|
|
2435
|
+
ctx.renderer.renderError(`Unknown subcommand: ${sub}. Use list/new/switch/delete/rename/diff/cherry-pick.`);
|
|
2367
2436
|
}
|
|
2368
2437
|
},
|
|
2369
2438
|
// ── /index ────────────────────────────────────────────────────
|
|
@@ -2435,7 +2504,7 @@ ${hint}` : "")
|
|
|
2435
2504
|
}
|
|
2436
2505
|
console.log(theme.dim(` Building semantic index for ${idx.symbolCount} symbols\u2026`));
|
|
2437
2506
|
console.log(theme.dim(" (First run downloads ~117 MB embedding model to ~/.aicli/models/)"));
|
|
2438
|
-
const { rebuildSemanticIndex } = await import("./semantic-
|
|
2507
|
+
const { rebuildSemanticIndex } = await import("./semantic-ICJ536BG.js");
|
|
2439
2508
|
try {
|
|
2440
2509
|
const stats = await rebuildSemanticIndex(root, {
|
|
2441
2510
|
onProgress: (done, total) => {
|
|
@@ -2501,7 +2570,7 @@ ${hint}` : "")
|
|
|
2501
2570
|
usage: "/test [command|filter]",
|
|
2502
2571
|
async execute(args, ctx) {
|
|
2503
2572
|
try {
|
|
2504
|
-
const { executeTests } = await import("./run-tests-
|
|
2573
|
+
const { executeTests } = await import("./run-tests-7N2WILA3.js");
|
|
2505
2574
|
const argStr = args.join(" ").trim();
|
|
2506
2575
|
let testArgs = {};
|
|
2507
2576
|
if (argStr) {
|
|
@@ -6394,7 +6463,7 @@ program.command("web").description("Start Web UI server with browser-based chat
|
|
|
6394
6463
|
console.error("Error: Invalid port number. Must be between 1 and 65535.");
|
|
6395
6464
|
process.exit(1);
|
|
6396
6465
|
}
|
|
6397
|
-
const { startWebServer } = await import("./server-
|
|
6466
|
+
const { startWebServer } = await import("./server-HJ64OR7A.js");
|
|
6398
6467
|
await startWebServer({ port, host: options.host });
|
|
6399
6468
|
});
|
|
6400
6469
|
program.command("user [action] [username]").description("Manage Web UI users (list | create <name> | delete <name> | reset-password <name> | migrate <name>)").action(async (action, username) => {
|
|
@@ -6517,7 +6586,7 @@ program.command("sessions").description("List recent conversation sessions").act
|
|
|
6517
6586
|
});
|
|
6518
6587
|
program.command("batch <action> [arg] [arg2]").description("Anthropic Message Batches: submit | list | status <id> | results <id> [out] | cancel <id>").option("--dry-run", "Parse and validate input without submitting (submit only)").action(async (action, arg, arg2, options) => {
|
|
6519
6588
|
try {
|
|
6520
|
-
const batch = await import("./batch-
|
|
6589
|
+
const batch = await import("./batch-OUBKAHXG.js");
|
|
6521
6590
|
switch (action) {
|
|
6522
6591
|
case "submit":
|
|
6523
6592
|
if (!arg) {
|
|
@@ -6677,7 +6746,7 @@ program.command("hub [topic]").description("Start multi-agent hub (discuss / bra
|
|
|
6677
6746
|
}),
|
|
6678
6747
|
config.get("customProviders")
|
|
6679
6748
|
);
|
|
6680
|
-
const { startHub } = await import("./hub-
|
|
6749
|
+
const { startHub } = await import("./hub-SFJU4KJK.js");
|
|
6681
6750
|
await startHub(
|
|
6682
6751
|
{
|
|
6683
6752
|
topic: topic ?? "",
|
|
@@ -2,14 +2,16 @@
|
|
|
2
2
|
import {
|
|
3
3
|
buildEmbeddingText,
|
|
4
4
|
hasSemanticIndex,
|
|
5
|
+
pathTokens,
|
|
5
6
|
rebuildSemanticIndex,
|
|
6
7
|
semanticSearch
|
|
7
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-CQQQFNND.js";
|
|
8
9
|
import "./chunk-6VRJGH25.js";
|
|
9
10
|
import "./chunk-PFYAAX2S.js";
|
|
10
11
|
export {
|
|
11
12
|
buildEmbeddingText,
|
|
12
13
|
hasSemanticIndex,
|
|
14
|
+
pathTokens,
|
|
13
15
|
rebuildSemanticIndex,
|
|
14
16
|
semanticSearch
|
|
15
17
|
};
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildEmbeddingText,
|
|
3
3
|
hasSemanticIndex,
|
|
4
|
+
pathTokens,
|
|
4
5
|
rebuildSemanticIndex,
|
|
5
6
|
semanticSearch
|
|
6
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-GTKJUEBS.js";
|
|
7
8
|
import "./chunk-BJAT4GNC.js";
|
|
8
9
|
import "./chunk-XMA222FQ.js";
|
|
9
10
|
export {
|
|
10
11
|
buildEmbeddingText,
|
|
11
12
|
hasSemanticIndex,
|
|
13
|
+
pathTokens,
|
|
12
14
|
rebuildSemanticIndex,
|
|
13
15
|
semanticSearch
|
|
14
16
|
};
|
|
@@ -20,10 +20,10 @@ import {
|
|
|
20
20
|
persistToolRound,
|
|
21
21
|
rebuildExtraMessages,
|
|
22
22
|
setupProxy
|
|
23
|
-
} from "./chunk-
|
|
23
|
+
} from "./chunk-6HZTXVTF.js";
|
|
24
24
|
import {
|
|
25
25
|
ConfigManager
|
|
26
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-C5QENJ4P.js";
|
|
27
27
|
import {
|
|
28
28
|
ToolExecutor,
|
|
29
29
|
ToolRegistry,
|
|
@@ -41,14 +41,14 @@ import {
|
|
|
41
41
|
spawnAgentContext,
|
|
42
42
|
truncateOutput,
|
|
43
43
|
undoStack
|
|
44
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-CU5ZSHGU.js";
|
|
45
45
|
import "./chunk-2ZD3YTVM.js";
|
|
46
46
|
import "./chunk-4BKXL7SM.js";
|
|
47
47
|
import "./chunk-NHNWUBXB.js";
|
|
48
|
-
import "./chunk-
|
|
48
|
+
import "./chunk-CQQQFNND.js";
|
|
49
49
|
import "./chunk-6VRJGH25.js";
|
|
50
50
|
import "./chunk-PFYAAX2S.js";
|
|
51
|
-
import "./chunk-
|
|
51
|
+
import "./chunk-IGHC7D62.js";
|
|
52
52
|
import {
|
|
53
53
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
54
54
|
AUTHOR,
|
|
@@ -67,7 +67,7 @@ import {
|
|
|
67
67
|
SKILLS_DIR_NAME,
|
|
68
68
|
VERSION,
|
|
69
69
|
buildUserIdentityPrompt
|
|
70
|
-
} from "./chunk-
|
|
70
|
+
} from "./chunk-2ERX5Q55.js";
|
|
71
71
|
import {
|
|
72
72
|
AuthManager
|
|
73
73
|
} from "./chunk-BYNY5JPB.js";
|
|
@@ -1482,7 +1482,7 @@ Tokens: in=${this.sessionTokenUsage.inputTokens} out=${this.sessionTokenUsage.ou
|
|
|
1482
1482
|
" /diff [--stats] \u2014 Show file modifications in this session",
|
|
1483
1483
|
" /checkpoint [save|restore|delete] <name> \u2014 Session checkpoints",
|
|
1484
1484
|
" /fork [checkpoint] \u2014 Fork session from checkpoint or current",
|
|
1485
|
-
" /branch [list|new|switch|delete|rename] \u2014 Manage conversation branches",
|
|
1485
|
+
" /branch [list|new|switch|delete|rename|diff|cherry-pick] \u2014 Manage conversation branches (fork tree, cross-branch picks)",
|
|
1486
1486
|
" /index [status|rebuild|clear|semantic-rebuild|semantic-clear] \u2014 Symbol + semantic index (find_symbol / search_code)",
|
|
1487
1487
|
" /review [--staged] \u2014 AI code review from git diff",
|
|
1488
1488
|
" /security-review \u2014 Security vulnerability scan on git diff",
|
|
@@ -1822,7 +1822,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
1822
1822
|
lines.push(` ${marker}${b.id.padEnd(10)} ${b.title.padEnd(20)} (${count} msgs)${parent}`);
|
|
1823
1823
|
}
|
|
1824
1824
|
lines.push("");
|
|
1825
|
-
lines.push("Usage: /branch new <msgIndex> [title] | switch <id> | delete <id> | rename <id> <title>");
|
|
1825
|
+
lines.push("Usage: /branch new <msgIndex> [title] | switch <id> | delete <id> | rename <id> <title> | diff <id> | cherry-pick <id> <msgIndex>");
|
|
1826
1826
|
this.send({ type: "info", message: lines.join("\n") });
|
|
1827
1827
|
break;
|
|
1828
1828
|
}
|
|
@@ -1900,7 +1900,70 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
1900
1900
|
}
|
|
1901
1901
|
break;
|
|
1902
1902
|
}
|
|
1903
|
-
|
|
1903
|
+
if (sub === "diff") {
|
|
1904
|
+
const id = args[1];
|
|
1905
|
+
if (!id) {
|
|
1906
|
+
this.send({ type: "error", message: "Usage: /branch diff <id>" });
|
|
1907
|
+
break;
|
|
1908
|
+
}
|
|
1909
|
+
const d = session.diffBranches(id);
|
|
1910
|
+
if (!d) {
|
|
1911
|
+
this.send({ type: "error", message: `Branch "${id}" not found.` });
|
|
1912
|
+
break;
|
|
1913
|
+
}
|
|
1914
|
+
const preview = (m) => {
|
|
1915
|
+
const text = typeof m.content === "string" ? m.content : "[complex content]";
|
|
1916
|
+
return text.replace(/\s+/g, " ").trim().slice(0, 70);
|
|
1917
|
+
};
|
|
1918
|
+
const lines = [
|
|
1919
|
+
`\u{1F500} diff ${id} (source) \u2194 ${session.activeBranchId} (active)`,
|
|
1920
|
+
`Common prefix: ${d.commonPrefix} message(s)`
|
|
1921
|
+
];
|
|
1922
|
+
if (d.sourceOnly.length === 0 && d.targetOnly.length === 0) {
|
|
1923
|
+
lines.push("Branches are identical.");
|
|
1924
|
+
} else {
|
|
1925
|
+
if (d.sourceOnly.length > 0) {
|
|
1926
|
+
lines.push("", `Only in ${id} (${d.sourceOnly.length}):`);
|
|
1927
|
+
d.sourceOnly.forEach(
|
|
1928
|
+
(m, i) => lines.push(` [${d.commonPrefix + i}] ${m.role}: ${preview(m)}`)
|
|
1929
|
+
);
|
|
1930
|
+
}
|
|
1931
|
+
if (d.targetOnly.length > 0) {
|
|
1932
|
+
lines.push("", `Only in ${session.activeBranchId} (active) (${d.targetOnly.length}):`);
|
|
1933
|
+
d.targetOnly.forEach(
|
|
1934
|
+
(m, i) => lines.push(` [${d.commonPrefix + i}] ${m.role}: ${preview(m)}`)
|
|
1935
|
+
);
|
|
1936
|
+
}
|
|
1937
|
+
lines.push("", `Use /branch cherry-pick ${id} <index> to copy a message into the active branch.`);
|
|
1938
|
+
}
|
|
1939
|
+
this.send({ type: "info", message: lines.join("\n") });
|
|
1940
|
+
break;
|
|
1941
|
+
}
|
|
1942
|
+
if (sub === "cherry-pick") {
|
|
1943
|
+
const id = args[1];
|
|
1944
|
+
const idxStr = args[2];
|
|
1945
|
+
if (!id || !idxStr) {
|
|
1946
|
+
this.send({ type: "error", message: "Usage: /branch cherry-pick <source-id> <msg-index>" });
|
|
1947
|
+
break;
|
|
1948
|
+
}
|
|
1949
|
+
const idx = parseInt(idxStr, 10);
|
|
1950
|
+
if (Number.isNaN(idx)) {
|
|
1951
|
+
this.send({ type: "error", message: `Invalid message index: "${idxStr}"` });
|
|
1952
|
+
break;
|
|
1953
|
+
}
|
|
1954
|
+
const picked = session.cherryPickMessage(id, idx);
|
|
1955
|
+
if (!picked) {
|
|
1956
|
+
this.send({ type: "error", message: `Cherry-pick failed \u2014 branch "${id}" not found, or index ${idx} out of range.` });
|
|
1957
|
+
break;
|
|
1958
|
+
}
|
|
1959
|
+
await this.sessions.save();
|
|
1960
|
+
const preview = typeof picked.content === "string" ? picked.content.replace(/\s+/g, " ").trim().slice(0, 60) : "[complex content]";
|
|
1961
|
+
this.send({ type: "info", message: `\u2713 Cherry-picked ${picked.role} message from "${id}"[${idx}] \u2192 active branch (${session.messages.length} msgs): ${preview}` });
|
|
1962
|
+
this.sendSessionMessages();
|
|
1963
|
+
this.sendStatus();
|
|
1964
|
+
break;
|
|
1965
|
+
}
|
|
1966
|
+
this.send({ type: "error", message: `Unknown subcommand: ${sub}. Use list/new/switch/delete/rename/diff/cherry-pick.` });
|
|
1904
1967
|
break;
|
|
1905
1968
|
}
|
|
1906
1969
|
// ── /index ──────────────────────────────────────────────────────
|
|
@@ -1958,7 +2021,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
1958
2021
|
message: `Building semantic index for ${idx.symbolCount} symbols\u2026 (first run downloads ~117 MB model)`
|
|
1959
2022
|
});
|
|
1960
2023
|
try {
|
|
1961
|
-
const { rebuildSemanticIndex } = await import("./semantic-
|
|
2024
|
+
const { rebuildSemanticIndex } = await import("./semantic-ICJ536BG.js");
|
|
1962
2025
|
const stats = await rebuildSemanticIndex(root);
|
|
1963
2026
|
const first = stats.modelFirstLoadMs ? ` (model load+first batch ${stats.modelFirstLoadMs}ms)` : "";
|
|
1964
2027
|
this.send({
|
|
@@ -2145,7 +2208,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
2145
2208
|
case "test": {
|
|
2146
2209
|
this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
|
|
2147
2210
|
try {
|
|
2148
|
-
const { executeTests } = await import("./run-tests-
|
|
2211
|
+
const { executeTests } = await import("./run-tests-7N2WILA3.js");
|
|
2149
2212
|
const argStr = args.join(" ").trim();
|
|
2150
2213
|
let testArgs = {};
|
|
2151
2214
|
if (argStr) {
|
|
@@ -4,17 +4,17 @@ import {
|
|
|
4
4
|
getDangerLevel,
|
|
5
5
|
googleSearchContext,
|
|
6
6
|
truncateOutput
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-CU5ZSHGU.js";
|
|
8
8
|
import "./chunk-2ZD3YTVM.js";
|
|
9
9
|
import "./chunk-4BKXL7SM.js";
|
|
10
10
|
import "./chunk-NHNWUBXB.js";
|
|
11
|
-
import "./chunk-
|
|
11
|
+
import "./chunk-CQQQFNND.js";
|
|
12
12
|
import "./chunk-6VRJGH25.js";
|
|
13
13
|
import "./chunk-PFYAAX2S.js";
|
|
14
|
-
import "./chunk-
|
|
14
|
+
import "./chunk-IGHC7D62.js";
|
|
15
15
|
import {
|
|
16
16
|
SUBAGENT_ALLOWED_TOOLS
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-2ERX5Q55.js";
|
|
18
18
|
|
|
19
19
|
// src/hub/task-orchestrator.ts
|
|
20
20
|
import { createInterface } from "readline";
|