jinzd-ai-cli 0.4.74 → 0.4.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/dist/{chunk-BT2TCINO.js → chunk-2Q77FT3F.js} +12 -3
- package/dist/{chunk-265H5S5H.js → chunk-34NJTPWZ.js} +12 -3
- package/dist/chunk-6VRJGH25.js +115 -0
- package/dist/chunk-BJAT4GNC.js +113 -0
- package/dist/{chunk-VG3MFZYG.js → chunk-H4DQNZZ6.js} +1 -1
- package/dist/{chunk-FKVJRBPO.js → chunk-K3JJX2Z5.js} +1 -1
- package/dist/{chunk-D5ZDVEJJ.js → chunk-KR4FTJWB.js} +234 -4
- package/dist/chunk-NHNWUBXB.js +431 -0
- package/dist/chunk-RFQVUMDB.js +430 -0
- package/dist/{chunk-PLJUAA3J.js → chunk-XTH7S3AM.js} +2 -2
- package/dist/{hub-ABCHM2OR.js → hub-YPNEYO3Z.js} +1 -1
- package/dist/index.js +93 -14
- package/dist/{run-tests-FMEFXUGO.js → run-tests-2I5S24IH.js} +1 -1
- package/dist/{run-tests-HBLD2R6B.js → run-tests-MKKCDUUV.js} +2 -2
- package/dist/{server-NMMRIWT2.js → server-6MPBAH4K.js} +66 -12
- package/dist/{task-orchestrator-24UUKJW5.js → task-orchestrator-I5HPXTJY.js} +5 -3
- package/dist/wasm/tree-sitter-javascript.wasm +0 -0
- package/dist/wasm/tree-sitter-python.wasm +0 -0
- package/dist/wasm/tree-sitter-tsx.wasm +0 -0
- package/dist/wasm/tree-sitter-typescript.wasm +0 -0
- package/dist/wasm/web-tree-sitter.wasm +0 -0
- package/dist/web/client/app.js +142 -0
- package/dist/web/client/index.html +12 -0
- package/dist/web/client/style.css +71 -0
- package/package.json +9 -2
|
@@ -20,13 +20,7 @@ import {
|
|
|
20
20
|
persistToolRound,
|
|
21
21
|
rebuildExtraMessages,
|
|
22
22
|
setupProxy
|
|
23
|
-
} from "./chunk-
|
|
24
|
-
import {
|
|
25
|
-
AuthManager
|
|
26
|
-
} from "./chunk-BYNY5JPB.js";
|
|
27
|
-
import {
|
|
28
|
-
ConfigManager
|
|
29
|
-
} from "./chunk-VG3MFZYG.js";
|
|
23
|
+
} from "./chunk-XTH7S3AM.js";
|
|
30
24
|
import {
|
|
31
25
|
ToolExecutor,
|
|
32
26
|
ToolRegistry,
|
|
@@ -44,9 +38,17 @@ import {
|
|
|
44
38
|
spawnAgentContext,
|
|
45
39
|
truncateOutput,
|
|
46
40
|
undoStack
|
|
47
|
-
} from "./chunk-
|
|
41
|
+
} from "./chunk-KR4FTJWB.js";
|
|
48
42
|
import "./chunk-4BKXL7SM.js";
|
|
49
|
-
import "./chunk-
|
|
43
|
+
import "./chunk-NHNWUBXB.js";
|
|
44
|
+
import "./chunk-6VRJGH25.js";
|
|
45
|
+
import "./chunk-K3JJX2Z5.js";
|
|
46
|
+
import {
|
|
47
|
+
AuthManager
|
|
48
|
+
} from "./chunk-BYNY5JPB.js";
|
|
49
|
+
import {
|
|
50
|
+
ConfigManager
|
|
51
|
+
} from "./chunk-H4DQNZZ6.js";
|
|
50
52
|
import "./chunk-2ZD3YTVM.js";
|
|
51
53
|
import {
|
|
52
54
|
AGENTIC_BEHAVIOR_GUIDELINE,
|
|
@@ -66,7 +68,7 @@ import {
|
|
|
66
68
|
SKILLS_DIR_NAME,
|
|
67
69
|
VERSION,
|
|
68
70
|
buildUserIdentityPrompt
|
|
69
|
-
} from "./chunk-
|
|
71
|
+
} from "./chunk-2Q77FT3F.js";
|
|
70
72
|
|
|
71
73
|
// src/web/server.ts
|
|
72
74
|
import express from "express";
|
|
@@ -563,6 +565,15 @@ var SessionHandler = class _SessionHandler {
|
|
|
563
565
|
models: p.info.models.map((m) => ({ id: m.id, name: m.displayName ?? m.id }))
|
|
564
566
|
}));
|
|
565
567
|
const costUsd = computeCost(this.currentProvider, this.currentModel, this.sessionTokenUsage);
|
|
568
|
+
const sess = this.sessions.current;
|
|
569
|
+
const branches = sess ? sess.listBranches().map((b) => ({
|
|
570
|
+
id: b.id,
|
|
571
|
+
title: b.title,
|
|
572
|
+
parentBranchId: b.parentBranchId,
|
|
573
|
+
parentMessageIndex: b.parentMessageIndex,
|
|
574
|
+
created: b.created.toISOString(),
|
|
575
|
+
messageCount: b.id === sess.activeBranchId ? sess.messages.length : sess.getBranchMessages(b.id)?.length ?? 0
|
|
576
|
+
})) : [];
|
|
566
577
|
this.send({
|
|
567
578
|
type: "status",
|
|
568
579
|
provider: this.currentProvider,
|
|
@@ -574,7 +585,9 @@ var SessionHandler = class _SessionHandler {
|
|
|
574
585
|
thinkingMode: this.runtimeThinking ?? false,
|
|
575
586
|
tokenUsage: { ...this.sessionTokenUsage },
|
|
576
587
|
costUsd,
|
|
577
|
-
providers: providerList
|
|
588
|
+
providers: providerList,
|
|
589
|
+
branches,
|
|
590
|
+
activeBranchId: sess?.activeBranchId ?? "main"
|
|
578
591
|
});
|
|
579
592
|
}
|
|
580
593
|
async handleMessage(raw) {
|
|
@@ -1467,6 +1480,8 @@ Tokens: in=${this.sessionTokenUsage.inputTokens} out=${this.sessionTokenUsage.ou
|
|
|
1467
1480
|
" /diff [--stats] \u2014 Show file modifications in this session",
|
|
1468
1481
|
" /checkpoint [save|restore|delete] <name> \u2014 Session checkpoints",
|
|
1469
1482
|
" /fork [checkpoint] \u2014 Fork session from checkpoint or current",
|
|
1483
|
+
" /branch [list|new|switch|delete|rename] \u2014 Manage conversation branches",
|
|
1484
|
+
" /index [status|rebuild|clear] \u2014 Symbol index for find_symbol / get_outline / find_references",
|
|
1470
1485
|
" /review [--staged] \u2014 AI code review from git diff",
|
|
1471
1486
|
" /security-review \u2014 Security vulnerability scan on git diff",
|
|
1472
1487
|
" /rewind [list|<n>] \u2014 Rewind conversation & restore files to checkpoint",
|
|
@@ -1860,6 +1875,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
1860
1875
|
if (ok) {
|
|
1861
1876
|
await this.sessions.save();
|
|
1862
1877
|
this.send({ type: "info", message: `\u2713 Deleted branch "${id}"` });
|
|
1878
|
+
this.sendStatus();
|
|
1863
1879
|
} else {
|
|
1864
1880
|
this.send({ type: "error", message: `Cannot delete "${id}" (not found, active, or last remaining branch).` });
|
|
1865
1881
|
}
|
|
@@ -1876,6 +1892,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
1876
1892
|
if (ok) {
|
|
1877
1893
|
await this.sessions.save();
|
|
1878
1894
|
this.send({ type: "info", message: `\u2713 Renamed branch "${id}" \u2192 "${title}"` });
|
|
1895
|
+
this.sendStatus();
|
|
1879
1896
|
} else {
|
|
1880
1897
|
this.send({ type: "error", message: `Branch "${id}" not found.` });
|
|
1881
1898
|
}
|
|
@@ -1884,6 +1901,43 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
1884
1901
|
this.send({ type: "error", message: `Unknown subcommand: ${sub}. Use list/new/switch/delete/rename.` });
|
|
1885
1902
|
break;
|
|
1886
1903
|
}
|
|
1904
|
+
// ── /index ──────────────────────────────────────────────────────
|
|
1905
|
+
case "index": {
|
|
1906
|
+
const sub = (args[0] ?? "status").toLowerCase();
|
|
1907
|
+
const root = process.cwd();
|
|
1908
|
+
const { loadIndex, clearIndex } = await import("./store-S24SPPDZ.js");
|
|
1909
|
+
const { indexProject } = await import("./indexer-C7QYYHSZ.js");
|
|
1910
|
+
if (sub === "status") {
|
|
1911
|
+
const idx = loadIndex(root);
|
|
1912
|
+
if (!idx) {
|
|
1913
|
+
this.send({ type: "info", message: `No symbol index for ${root}. Run /index rebuild.` });
|
|
1914
|
+
} else {
|
|
1915
|
+
this.send({
|
|
1916
|
+
type: "info",
|
|
1917
|
+
message: [
|
|
1918
|
+
"\u{1F50E} Symbol index:",
|
|
1919
|
+
` Root: ${idx.root}`,
|
|
1920
|
+
` Generated: ${idx.generated}`,
|
|
1921
|
+
` Files: ${idx.fileCount}`,
|
|
1922
|
+
` Symbols: ${idx.symbolCount}`
|
|
1923
|
+
].join("\n")
|
|
1924
|
+
});
|
|
1925
|
+
}
|
|
1926
|
+
} else if (sub === "rebuild") {
|
|
1927
|
+
this.send({ type: "info", message: `Indexing ${root}\u2026` });
|
|
1928
|
+
const { stats } = await indexProject(root, { force: true });
|
|
1929
|
+
this.send({
|
|
1930
|
+
type: "info",
|
|
1931
|
+
message: `\u2713 Indexed ${stats.filesParsed} files (${stats.symbols} symbols) in ${stats.durationMs}ms`
|
|
1932
|
+
});
|
|
1933
|
+
} else if (sub === "clear") {
|
|
1934
|
+
clearIndex(root);
|
|
1935
|
+
this.send({ type: "info", message: `\u2713 Cleared symbol index for ${root}` });
|
|
1936
|
+
} else {
|
|
1937
|
+
this.send({ type: "error", message: `Unknown subcommand: ${sub}. Use status/rebuild/clear.` });
|
|
1938
|
+
}
|
|
1939
|
+
break;
|
|
1940
|
+
}
|
|
1887
1941
|
// ── /fork ───────────────────────────────────────────────────────
|
|
1888
1942
|
case "fork": {
|
|
1889
1943
|
const session = this.sessions.current;
|
|
@@ -2049,7 +2103,7 @@ ${undoResults.map((r) => ` \u2022 ${r}`).join("\n")}` });
|
|
|
2049
2103
|
case "test": {
|
|
2050
2104
|
this.send({ type: "info", message: "\u{1F9EA} Running tests..." });
|
|
2051
2105
|
try {
|
|
2052
|
-
const { executeTests } = await import("./run-tests-
|
|
2106
|
+
const { executeTests } = await import("./run-tests-MKKCDUUV.js");
|
|
2053
2107
|
const argStr = args.join(" ").trim();
|
|
2054
2108
|
let testArgs = {};
|
|
2055
2109
|
if (argStr) {
|
|
@@ -4,13 +4,15 @@ import {
|
|
|
4
4
|
getDangerLevel,
|
|
5
5
|
googleSearchContext,
|
|
6
6
|
truncateOutput
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-KR4FTJWB.js";
|
|
8
8
|
import "./chunk-4BKXL7SM.js";
|
|
9
|
-
import "./chunk-
|
|
9
|
+
import "./chunk-NHNWUBXB.js";
|
|
10
|
+
import "./chunk-6VRJGH25.js";
|
|
11
|
+
import "./chunk-K3JJX2Z5.js";
|
|
10
12
|
import "./chunk-2ZD3YTVM.js";
|
|
11
13
|
import {
|
|
12
14
|
SUBAGENT_ALLOWED_TOOLS
|
|
13
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-2Q77FT3F.js";
|
|
14
16
|
|
|
15
17
|
// src/hub/task-orchestrator.ts
|
|
16
18
|
import { createInterface } from "readline";
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/dist/web/client/app.js
CHANGED
|
@@ -519,6 +519,17 @@ function handleStatus(msg) {
|
|
|
519
519
|
}
|
|
520
520
|
if (msg.tokenUsage) targetTab.tokenUsage = msg.tokenUsage;
|
|
521
521
|
|
|
522
|
+
// B2: stash branch data on the tab so tab-switch keeps the picker in sync.
|
|
523
|
+
if (Array.isArray(msg.branches)) {
|
|
524
|
+
targetTab.branches = msg.branches;
|
|
525
|
+
targetTab.activeBranchId = msg.activeBranchId || 'main';
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
if (isActiveTarget) {
|
|
529
|
+
// Re-render the branches panel whenever the active tab gets a status.
|
|
530
|
+
renderBranchPanel(msg.branches || [], msg.activeBranchId || 'main', msg.sessionId || '');
|
|
531
|
+
}
|
|
532
|
+
|
|
522
533
|
if (isActiveTarget) {
|
|
523
534
|
// Active tab: full UI reflection
|
|
524
535
|
btnThink.classList.toggle('btn-active-toggle', msg.thinkingMode);
|
|
@@ -1179,6 +1190,137 @@ function renderReplayStep(m, idx) {
|
|
|
1179
1190
|
</div>`;
|
|
1180
1191
|
}
|
|
1181
1192
|
|
|
1193
|
+
// ── B2: Branch sidebar panel ─────────────────────────────
|
|
1194
|
+
let _cachedBranches = [];
|
|
1195
|
+
let _cachedActiveBranchId = 'main';
|
|
1196
|
+
|
|
1197
|
+
function renderBranchPanel(branches, activeId, sessionId) {
|
|
1198
|
+
_cachedBranches = branches;
|
|
1199
|
+
_cachedActiveBranchId = activeId;
|
|
1200
|
+
const listEl = document.getElementById('branch-list');
|
|
1201
|
+
const headerEl = document.getElementById('branches-header');
|
|
1202
|
+
if (!listEl) return;
|
|
1203
|
+
|
|
1204
|
+
if (!sessionId) {
|
|
1205
|
+
if (headerEl) headerEl.textContent = 'No session';
|
|
1206
|
+
listEl.innerHTML = '<div class="text-xs opacity-40 text-center py-4">Load a session to see branches</div>';
|
|
1207
|
+
return;
|
|
1208
|
+
}
|
|
1209
|
+
if (headerEl) {
|
|
1210
|
+
headerEl.textContent = `Session ${sessionId.slice(0, 8)} · ${branches.length} branch${branches.length === 1 ? '' : 'es'}`;
|
|
1211
|
+
}
|
|
1212
|
+
if (branches.length === 0) {
|
|
1213
|
+
listEl.innerHTML = '<div class="text-xs opacity-40 text-center py-4">No branches</div>';
|
|
1214
|
+
return;
|
|
1215
|
+
}
|
|
1216
|
+
|
|
1217
|
+
// Build tree: compute depth by walking parent chain.
|
|
1218
|
+
const byId = Object.fromEntries(branches.map(b => [b.id, b]));
|
|
1219
|
+
function depthOf(b) {
|
|
1220
|
+
let d = 0, cur = b;
|
|
1221
|
+
while (cur && cur.parentBranchId && byId[cur.parentBranchId]) {
|
|
1222
|
+
d++;
|
|
1223
|
+
cur = byId[cur.parentBranchId];
|
|
1224
|
+
if (d > 100) break; // safety
|
|
1225
|
+
}
|
|
1226
|
+
return d;
|
|
1227
|
+
}
|
|
1228
|
+
// Depth-first order: roots first, then children in order.
|
|
1229
|
+
const ordered = [];
|
|
1230
|
+
const visited = new Set();
|
|
1231
|
+
function visit(b) {
|
|
1232
|
+
if (visited.has(b.id)) return;
|
|
1233
|
+
visited.add(b.id);
|
|
1234
|
+
ordered.push(b);
|
|
1235
|
+
for (const c of branches) {
|
|
1236
|
+
if (c.parentBranchId === b.id) visit(c);
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
for (const b of branches) {
|
|
1240
|
+
if (!b.parentBranchId || !byId[b.parentBranchId]) visit(b);
|
|
1241
|
+
}
|
|
1242
|
+
// Any remaining (orphaned) — append at end.
|
|
1243
|
+
for (const b of branches) if (!visited.has(b.id)) visit(b);
|
|
1244
|
+
|
|
1245
|
+
listEl.innerHTML = ordered.map(b => {
|
|
1246
|
+
const depth = depthOf(b);
|
|
1247
|
+
const indent = depth === 0 ? '' : '│ '.repeat(depth - 1) + '└─ ';
|
|
1248
|
+
const isActive = b.id === activeId;
|
|
1249
|
+
const marker = isActive ? '●' : '○';
|
|
1250
|
+
const parentTag = b.parentBranchId
|
|
1251
|
+
? `<span class="branch-count">← ${escapeHtml(b.parentBranchId)}@${b.parentMessageIndex}</span>`
|
|
1252
|
+
: '';
|
|
1253
|
+
return `
|
|
1254
|
+
<div class="branch-item${isActive ? ' active' : ''}" data-branch-id="${escapeHtml(b.id)}" data-branch-active="${isActive ? '1' : '0'}">
|
|
1255
|
+
<span class="branch-indent">${indent}</span>
|
|
1256
|
+
<span class="branch-marker">${marker}</span>
|
|
1257
|
+
<span class="branch-title" title="${escapeHtml(b.title)}">${escapeHtml(b.title)}</span>
|
|
1258
|
+
<span class="branch-id">${escapeHtml(b.id)}</span>
|
|
1259
|
+
<span class="branch-count">${b.messageCount}m</span>
|
|
1260
|
+
${parentTag}
|
|
1261
|
+
<span class="branch-actions">
|
|
1262
|
+
<button data-branch-action="rename" title="Rename">✎</button>
|
|
1263
|
+
<button data-branch-action="delete" title="Delete">×</button>
|
|
1264
|
+
</span>
|
|
1265
|
+
</div>`;
|
|
1266
|
+
}).join('');
|
|
1267
|
+
|
|
1268
|
+
// Wire click handlers.
|
|
1269
|
+
listEl.querySelectorAll('.branch-item').forEach(el => {
|
|
1270
|
+
el.addEventListener('click', (e) => {
|
|
1271
|
+
const actionBtn = e.target.closest('button[data-branch-action]');
|
|
1272
|
+
const id = el.dataset.branchId;
|
|
1273
|
+
if (!id) return;
|
|
1274
|
+
if (actionBtn) {
|
|
1275
|
+
e.stopPropagation();
|
|
1276
|
+
const action = actionBtn.dataset.branchAction;
|
|
1277
|
+
if (action === 'rename') {
|
|
1278
|
+
const cur = byId[id];
|
|
1279
|
+
const title = prompt('New branch title:', cur?.title || '');
|
|
1280
|
+
if (title && title.trim() && title.trim() !== cur?.title) {
|
|
1281
|
+
send({ type: 'command', name: 'branch', args: ['rename', id, title.trim()] });
|
|
1282
|
+
}
|
|
1283
|
+
} else if (action === 'delete') {
|
|
1284
|
+
if (id === activeId) {
|
|
1285
|
+
alert('Cannot delete the active branch. Switch to another branch first.');
|
|
1286
|
+
return;
|
|
1287
|
+
}
|
|
1288
|
+
if (confirm(`Delete branch "${id}"? Its messages will be lost.`)) {
|
|
1289
|
+
send({ type: 'command', name: 'branch', args: ['delete', id] });
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
return;
|
|
1293
|
+
}
|
|
1294
|
+
// Plain click → switch branch.
|
|
1295
|
+
if (el.dataset.branchActive !== '1') {
|
|
1296
|
+
send({ type: 'command', name: 'branch', args: ['switch', id] });
|
|
1297
|
+
}
|
|
1298
|
+
});
|
|
1299
|
+
});
|
|
1300
|
+
}
|
|
1301
|
+
|
|
1302
|
+
// "+ Fork" button — fork the active branch at its current tip.
|
|
1303
|
+
document.getElementById('btn-branch-new')?.addEventListener('click', () => {
|
|
1304
|
+
const activeTab = sessionTabs[activeTabIdx];
|
|
1305
|
+
if (!activeTab || !activeTab.sessionId) {
|
|
1306
|
+
alert('Load a session first.');
|
|
1307
|
+
return;
|
|
1308
|
+
}
|
|
1309
|
+
const activeBranch = _cachedBranches.find(b => b.id === _cachedActiveBranchId);
|
|
1310
|
+
const tip = activeBranch?.messageCount ?? 0;
|
|
1311
|
+
const raw = prompt(`Fork from message # (0–${tip}, default ${tip}):`, String(tip));
|
|
1312
|
+
if (raw === null) return;
|
|
1313
|
+
const idx = parseInt(raw.trim() || String(tip), 10);
|
|
1314
|
+
if (isNaN(idx) || idx < 0 || idx > tip) {
|
|
1315
|
+
alert(`Invalid index. Range: 0–${tip}`);
|
|
1316
|
+
return;
|
|
1317
|
+
}
|
|
1318
|
+
const title = prompt('New branch title (optional):', '');
|
|
1319
|
+
if (title === null) return;
|
|
1320
|
+
const args = ['new', String(idx), ...(title.trim() ? [title.trim()] : [])];
|
|
1321
|
+
send({ type: 'command', name: 'branch', args });
|
|
1322
|
+
});
|
|
1323
|
+
|
|
1182
1324
|
function startSessionRename(itemEl, titleEl) {
|
|
1183
1325
|
const sessionId = itemEl.dataset.sessionId;
|
|
1184
1326
|
const currentTitle = titleEl.textContent.trim();
|
|
@@ -105,6 +105,7 @@
|
|
|
105
105
|
<!-- Sidebar tabs -->
|
|
106
106
|
<div class="flex border-b border-base-content/10 flex-shrink-0">
|
|
107
107
|
<button class="sidebar-tab active flex-1 text-xs font-semibold py-2 px-1 text-center" data-tab="sessions">📋 Sessions</button>
|
|
108
|
+
<button class="sidebar-tab flex-1 text-xs font-semibold py-2 px-1 text-center" data-tab="branches" title="Conversation branches (B2)">🌿 Branches</button>
|
|
108
109
|
<button class="sidebar-tab flex-1 text-xs font-semibold py-2 px-1 text-center" data-tab="tools">🔧 Tools</button>
|
|
109
110
|
<button class="sidebar-tab flex-1 text-xs font-semibold py-2 px-1 text-center" data-tab="files">📁 Files</button>
|
|
110
111
|
</div>
|
|
@@ -127,6 +128,17 @@
|
|
|
127
128
|
<div class="text-xs opacity-40 text-center py-4">No sessions yet</div>
|
|
128
129
|
</div>
|
|
129
130
|
</div>
|
|
131
|
+
<!-- Branches tab (B2) -->
|
|
132
|
+
<div id="tab-branches" class="sidebar-tab-content flex flex-col flex-1 overflow-hidden hidden">
|
|
133
|
+
<div class="p-2 border-b border-base-content/10 flex items-center gap-1">
|
|
134
|
+
<span class="text-xs opacity-60 flex-1 truncate" id="branches-header">No session</span>
|
|
135
|
+
<button id="btn-branch-new" class="btn btn-xs btn-primary btn-outline flex-shrink-0 whitespace-nowrap" title="Fork at current tip">+ Fork</button>
|
|
136
|
+
</div>
|
|
137
|
+
<div id="branch-list" class="flex-1 overflow-y-auto p-2 flex flex-col gap-1 text-sm">
|
|
138
|
+
<div class="text-xs opacity-40 text-center py-4">Load a session to see branches</div>
|
|
139
|
+
</div>
|
|
140
|
+
</div>
|
|
141
|
+
|
|
130
142
|
<!-- Tools tab -->
|
|
131
143
|
<div id="tab-tools" class="sidebar-tab-content flex flex-col flex-1 overflow-hidden hidden">
|
|
132
144
|
<div class="p-2 border-b border-base-content/10">
|
|
@@ -903,3 +903,74 @@ button, a, .session-item, .file-tree-row, .template-item, .tool-item, .mcp-serve
|
|
|
903
903
|
max-height: 12rem;
|
|
904
904
|
overflow-y: auto;
|
|
905
905
|
}
|
|
906
|
+
|
|
907
|
+
/* ── B2 Branch picker (sidebar) ─────────────────────────── */
|
|
908
|
+
.branch-item {
|
|
909
|
+
display: flex;
|
|
910
|
+
align-items: center;
|
|
911
|
+
gap: 0.35rem;
|
|
912
|
+
padding: 0.35rem 0.5rem;
|
|
913
|
+
border-radius: 0.35rem;
|
|
914
|
+
cursor: pointer;
|
|
915
|
+
border: 1px solid transparent;
|
|
916
|
+
transition: background 0.1s, border-color 0.1s;
|
|
917
|
+
font-size: 0.78rem;
|
|
918
|
+
line-height: 1.25;
|
|
919
|
+
position: relative;
|
|
920
|
+
}
|
|
921
|
+
.branch-item:hover {
|
|
922
|
+
background: rgba(128, 128, 128, 0.12);
|
|
923
|
+
}
|
|
924
|
+
.branch-item.active {
|
|
925
|
+
background: rgba(34, 197, 94, 0.12);
|
|
926
|
+
border-color: rgba(34, 197, 94, 0.45);
|
|
927
|
+
}
|
|
928
|
+
.branch-item .branch-marker {
|
|
929
|
+
flex-shrink: 0;
|
|
930
|
+
width: 0.8rem;
|
|
931
|
+
color: rgb(34, 197, 94);
|
|
932
|
+
}
|
|
933
|
+
.branch-item .branch-title {
|
|
934
|
+
flex: 1;
|
|
935
|
+
min-width: 0;
|
|
936
|
+
overflow: hidden;
|
|
937
|
+
text-overflow: ellipsis;
|
|
938
|
+
white-space: nowrap;
|
|
939
|
+
}
|
|
940
|
+
.branch-item .branch-id {
|
|
941
|
+
flex-shrink: 0;
|
|
942
|
+
opacity: 0.5;
|
|
943
|
+
font-family: ui-monospace, SFMono-Regular, monospace;
|
|
944
|
+
font-size: 0.7rem;
|
|
945
|
+
}
|
|
946
|
+
.branch-item .branch-count {
|
|
947
|
+
flex-shrink: 0;
|
|
948
|
+
opacity: 0.55;
|
|
949
|
+
font-size: 0.7rem;
|
|
950
|
+
}
|
|
951
|
+
.branch-item .branch-actions {
|
|
952
|
+
display: none;
|
|
953
|
+
gap: 0.15rem;
|
|
954
|
+
flex-shrink: 0;
|
|
955
|
+
}
|
|
956
|
+
.branch-item:hover .branch-actions {
|
|
957
|
+
display: flex;
|
|
958
|
+
}
|
|
959
|
+
.branch-item .branch-actions button {
|
|
960
|
+
background: transparent;
|
|
961
|
+
border: none;
|
|
962
|
+
padding: 0 0.2rem;
|
|
963
|
+
font-size: 0.72rem;
|
|
964
|
+
cursor: pointer;
|
|
965
|
+
opacity: 0.7;
|
|
966
|
+
}
|
|
967
|
+
.branch-item .branch-actions button:hover {
|
|
968
|
+
opacity: 1;
|
|
969
|
+
}
|
|
970
|
+
.branch-item .branch-indent {
|
|
971
|
+
flex-shrink: 0;
|
|
972
|
+
color: rgba(128, 128, 128, 0.5);
|
|
973
|
+
font-family: ui-monospace, SFMono-Regular, monospace;
|
|
974
|
+
font-size: 0.72rem;
|
|
975
|
+
white-space: pre;
|
|
976
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jinzd-ai-cli",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.76",
|
|
4
4
|
"description": "Cross-platform REPL-style AI CLI with multi-provider support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -38,7 +38,9 @@
|
|
|
38
38
|
},
|
|
39
39
|
"pkg": {
|
|
40
40
|
"scripts": "dist-cjs/index.cjs",
|
|
41
|
-
"assets": [
|
|
41
|
+
"assets": [
|
|
42
|
+
"dist/wasm/**/*"
|
|
43
|
+
],
|
|
42
44
|
"targets": [
|
|
43
45
|
"node22-win-x64",
|
|
44
46
|
"node22-macos-arm64",
|
|
@@ -61,6 +63,7 @@
|
|
|
61
63
|
"dist/agent-client-*.js",
|
|
62
64
|
"dist/task-orchestrator-*.js",
|
|
63
65
|
"dist/web/",
|
|
66
|
+
"dist/wasm/",
|
|
64
67
|
"README.md"
|
|
65
68
|
],
|
|
66
69
|
"keywords": [
|
|
@@ -90,8 +93,12 @@
|
|
|
90
93
|
"commander": "^13.0.0",
|
|
91
94
|
"express": "^5.2.1",
|
|
92
95
|
"openai": "^4.77.0",
|
|
96
|
+
"tree-sitter-javascript": "^0.25.0",
|
|
97
|
+
"tree-sitter-python": "^0.25.0",
|
|
98
|
+
"tree-sitter-typescript": "^0.23.2",
|
|
93
99
|
"undici": "^7.22.0",
|
|
94
100
|
"uuid": "^11.0.5",
|
|
101
|
+
"web-tree-sitter": "^0.26.8",
|
|
95
102
|
"ws": "^8.19.0",
|
|
96
103
|
"zod": "^3.24.1"
|
|
97
104
|
},
|