codemini-cli 0.6.4 → 0.6.5
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/codemini-web/dist/assets/{AboutDialog-MRopwNIL.js → AboutDialog-BUp8EzDg.js} +2 -2
- package/codemini-web/dist/assets/CodeWikiPanel-Fp0VKdzo.js +1 -0
- package/codemini-web/dist/assets/ConfigDialog-DIpj779O.js +1 -0
- package/codemini-web/dist/assets/{GitDiffDialog-gSysUg2J.js → GitDiffDialog-ZLEuX8Qm.js} +2 -2
- package/codemini-web/dist/assets/{MemoryDialog-DFUmo3Kl.js → MemoryDialog-D2YbENVd.js} +3 -3
- package/codemini-web/dist/assets/MessageBubble-BIgpZsLn.js +12 -0
- package/codemini-web/dist/assets/{PatchDiff-B8rwvEg5.js → PatchDiff-CvKNaHsw.js} +1 -1
- package/codemini-web/dist/assets/ProjectSelector-DXIep3lE.js +1 -0
- package/codemini-web/dist/assets/{SkillDialog-CQTjbSiw.js → SkillDialog-DjPF-XBx.js} +4 -4
- package/codemini-web/dist/assets/{SoulDialog-BLjUGqqB.js → SoulDialog-BfIoKETs.js} +1 -1
- package/codemini-web/dist/assets/chevron-right-CfNZHlyU.js +1 -0
- package/codemini-web/dist/assets/{chunk-BO2N2NFS-6uELoidu.js → chunk-BO2N2NFS-DMUdjM9q.js} +4 -4
- package/codemini-web/dist/assets/{highlighted-body-OFNGDK62-gb1UMBZ5.js → highlighted-body-OFNGDK62-8ch0jz7Z.js} +1 -1
- package/codemini-web/dist/assets/{index-CDXQGwPs.js → index-BhMtCC8_.js} +6 -6
- package/codemini-web/dist/assets/index-DRXwJ-n_.css +2 -0
- package/codemini-web/dist/assets/input-CYpdNDlR.js +1 -0
- package/codemini-web/dist/assets/mermaid-GHXKKRXX-KBEtMEB9.js +1 -0
- package/codemini-web/dist/assets/{pencil-BhT11Ztp.js → pencil-BdA2cEeE.js} +1 -1
- package/codemini-web/dist/assets/{refresh-cw-D7R5Lth6.js → refresh-cw-CJGgUGiS.js} +1 -1
- package/codemini-web/dist/assets/select-BLOccU1M.js +1 -0
- package/codemini-web/dist/assets/{trash-2-BfNZcWfX.js → trash-2-CQzNOch5.js} +1 -1
- package/codemini-web/dist/index.html +2 -2
- package/codemini-web/lib/runtime-bridge.js +7 -0
- package/codemini-web/server.js +10 -1
- package/package.json +1 -1
- package/src/core/agent-loop.js +6 -9
- package/src/core/chat-runtime.js +6 -4
- package/src/core/config-store.js +2 -4
- package/src/core/git-oplog-change-tracker.js +96 -15
- package/src/core/tools.js +102 -24
- package/codemini-web/dist/assets/CodeWikiPanel-UpK5xGE3.js +0 -1
- package/codemini-web/dist/assets/ConfigDialog-CNl28wsj.js +0 -1
- package/codemini-web/dist/assets/MessageBubble-CGnnViv0.js +0 -12
- package/codemini-web/dist/assets/ProjectSelector-BF59M1zb.js +0 -1
- package/codemini-web/dist/assets/chevron-right--85xg7qk.js +0 -1
- package/codemini-web/dist/assets/index-1xqD0R5t.css +0 -2
- package/codemini-web/dist/assets/input-Ca8O_061.js +0 -1
- package/codemini-web/dist/assets/mermaid-GHXKKRXX-ROliF8Yd.js +0 -1
- package/codemini-web/dist/assets/select-DBvcHBzs.js +0 -1
|
@@ -190,13 +190,26 @@ async function buildPatchForFile(root, relativePath, before, after) {
|
|
|
190
190
|
oldPath,
|
|
191
191
|
newPath
|
|
192
192
|
], { cwd: tmp, allowFailure: true, timeoutMs: 120_000 });
|
|
193
|
-
if (result.code !== 1) return '';
|
|
194
|
-
const escaped = relativePath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
195
|
-
|
|
196
|
-
.replace(new RegExp(`diff --git a/old/${escaped} b/new/${escaped}`), `diff --git a/${relativePath} b/${relativePath}`)
|
|
197
|
-
.replace(new RegExp(`--- a/old/${escaped}`), before.exists ? `--- a/${relativePath}` : '--- /dev/null')
|
|
198
|
-
.replace(new RegExp(`\\+\\+\\+ b/new/${escaped}`), after.exists ? `+++ b/${relativePath}` : '+++ /dev/null');
|
|
199
|
-
|
|
193
|
+
if (result.code !== 1) return '';
|
|
194
|
+
const escaped = relativePath.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
195
|
+
let patch = result.stdout
|
|
196
|
+
.replace(new RegExp(`diff --git a/old/${escaped} b/new/${escaped}`), `diff --git a/${relativePath} b/${relativePath}`)
|
|
197
|
+
.replace(new RegExp(`--- a/old/${escaped}`), before.exists ? `--- a/${relativePath}` : '--- /dev/null')
|
|
198
|
+
.replace(new RegExp(`\\+\\+\\+ b/new/${escaped}`), after.exists ? `+++ b/${relativePath}` : '+++ /dev/null');
|
|
199
|
+
if (!before.exists && after.exists && !/^new file mode /m.test(patch)) {
|
|
200
|
+
patch = patch.replace(
|
|
201
|
+
new RegExp(`^(diff --git a/${escaped} b/${escaped})$`, 'm'),
|
|
202
|
+
`$1\nnew file mode 100644`
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
if (before.exists && !after.exists && !/^deleted file mode /m.test(patch)) {
|
|
206
|
+
patch = patch.replace(
|
|
207
|
+
new RegExp(`^(diff --git a/${escaped} b/${escaped})$`, 'm'),
|
|
208
|
+
`$1\ndeleted file mode 100644`
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
return patch;
|
|
212
|
+
} finally {
|
|
200
213
|
await fs.rm(tmp, { recursive: true, force: true }).catch(() => {});
|
|
201
214
|
}
|
|
202
215
|
}
|
|
@@ -360,11 +373,11 @@ export async function readGitOplogPatch(tracker, opId) {
|
|
|
360
373
|
return fs.readFile(op.patchPath, 'utf8');
|
|
361
374
|
}
|
|
362
375
|
|
|
363
|
-
export async function undoGitOplogChange(tracker, opId) {
|
|
364
|
-
if (!isGitOplogChangeTrackerAvailable(tracker)) throw new Error('Git change oplog is not available for this session');
|
|
365
|
-
const op = await readGitOplogChange(tracker, opId);
|
|
366
|
-
if (op.revertedAt) {
|
|
367
|
-
return { ok: false, alreadyReverted: true, changeSetId: op.id, message: 'Change already reverted' };
|
|
376
|
+
export async function undoGitOplogChange(tracker, opId) {
|
|
377
|
+
if (!isGitOplogChangeTrackerAvailable(tracker)) throw new Error('Git change oplog is not available for this session');
|
|
378
|
+
const op = await readGitOplogChange(tracker, opId);
|
|
379
|
+
if (op.revertedAt) {
|
|
380
|
+
return { ok: false, alreadyReverted: true, changeSetId: op.id, message: 'Change already reverted' };
|
|
368
381
|
}
|
|
369
382
|
const patch = await fs.readFile(op.patchPath, 'utf8');
|
|
370
383
|
try {
|
|
@@ -382,6 +395,74 @@ export async function undoGitOplogChange(tracker, opId) {
|
|
|
382
395
|
timeoutMs: 120_000
|
|
383
396
|
});
|
|
384
397
|
op.revertedAt = new Date().toISOString();
|
|
385
|
-
await writeJson(path.join(tracker.opsDir, `${op.id}.json`), op);
|
|
386
|
-
return { ok: true, changeSetId: op.id };
|
|
387
|
-
}
|
|
398
|
+
await writeJson(path.join(tracker.opsDir, `${op.id}.json`), op);
|
|
399
|
+
return { ok: true, changeSetId: op.id };
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
export async function undoGitOplogChanges(tracker, opIds = []) {
|
|
403
|
+
if (!isGitOplogChangeTrackerAvailable(tracker)) throw new Error('Git change oplog is not available for this session');
|
|
404
|
+
const ids = [];
|
|
405
|
+
const seen = new Set();
|
|
406
|
+
for (const rawId of Array.isArray(opIds) ? opIds : [opIds]) {
|
|
407
|
+
const id = String(rawId || '').trim();
|
|
408
|
+
if (!id || seen.has(id)) continue;
|
|
409
|
+
seen.add(id);
|
|
410
|
+
ids.push(id);
|
|
411
|
+
}
|
|
412
|
+
if (!ids.length) throw new Error('Missing change ids');
|
|
413
|
+
if (ids.length === 1) return undoGitOplogChange(tracker, ids[0]);
|
|
414
|
+
|
|
415
|
+
const ops = await Promise.all(ids.map((id) => readGitOplogChange(tracker, id)));
|
|
416
|
+
const reverted = ops.find((op) => op.revertedAt);
|
|
417
|
+
if (reverted) {
|
|
418
|
+
return { ok: false, alreadyReverted: true, changeSetId: reverted.id, message: 'Change already reverted' };
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
const order = new Map(ids.map((id, index) => [id, index]));
|
|
422
|
+
ops.sort((a, b) => {
|
|
423
|
+
const byTime = String(b.createdAt || '').localeCompare(String(a.createdAt || ''));
|
|
424
|
+
if (byTime) return byTime;
|
|
425
|
+
return (order.get(b.id) ?? 0) - (order.get(a.id) ?? 0);
|
|
426
|
+
});
|
|
427
|
+
|
|
428
|
+
const patches = await Promise.all(ops.map(async (op) => ({
|
|
429
|
+
op,
|
|
430
|
+
patch: await fs.readFile(op.patchPath, 'utf8')
|
|
431
|
+
})));
|
|
432
|
+
if (!patches.some((item) => String(item.patch || '').trim())) throw new Error('Missing change patch');
|
|
433
|
+
|
|
434
|
+
const applied = [];
|
|
435
|
+
try {
|
|
436
|
+
for (const item of patches) {
|
|
437
|
+
if (!String(item.patch || '').trim()) continue;
|
|
438
|
+
await runGit(['apply', '-R', '--check', '--whitespace=nowarn'], {
|
|
439
|
+
cwd: tracker.workspaceRoot,
|
|
440
|
+
input: item.patch,
|
|
441
|
+
timeoutMs: 120_000
|
|
442
|
+
});
|
|
443
|
+
await runGit(['apply', '-R', '--whitespace=nowarn'], {
|
|
444
|
+
cwd: tracker.workspaceRoot,
|
|
445
|
+
input: item.patch,
|
|
446
|
+
timeoutMs: 120_000
|
|
447
|
+
});
|
|
448
|
+
applied.push(item);
|
|
449
|
+
}
|
|
450
|
+
} catch (error) {
|
|
451
|
+
for (const item of applied.reverse()) {
|
|
452
|
+
await runGit(['apply', '--whitespace=nowarn'], {
|
|
453
|
+
cwd: tracker.workspaceRoot,
|
|
454
|
+
input: item.patch,
|
|
455
|
+
allowFailure: true,
|
|
456
|
+
timeoutMs: 120_000
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
throw new Error(`Cannot undo this change cleanly because newer edits conflict with it. Undo newer changes first, or revert it manually. ${error?.message || ''}`.trim());
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
const revertedAt = new Date().toISOString();
|
|
463
|
+
for (const op of ops) {
|
|
464
|
+
op.revertedAt = revertedAt;
|
|
465
|
+
await writeJson(path.join(tracker.opsDir, `${op.id}.json`), op);
|
|
466
|
+
}
|
|
467
|
+
return { ok: true, changeSetIds: ops.map((op) => op.id) };
|
|
468
|
+
}
|
package/src/core/tools.js
CHANGED
|
@@ -1664,9 +1664,9 @@ function editResult(pathText, action, beforeContent, afterContent, changedLine =
|
|
|
1664
1664
|
};
|
|
1665
1665
|
}
|
|
1666
1666
|
|
|
1667
|
-
function lineRangeToOffsets(content, startLineRaw, endLineRaw) {
|
|
1668
|
-
const lines = splitLines(content);
|
|
1669
|
-
const totalLines = lines.length;
|
|
1667
|
+
function lineRangeToOffsets(content, startLineRaw, endLineRaw) {
|
|
1668
|
+
const lines = splitLines(content);
|
|
1669
|
+
const totalLines = lines.length;
|
|
1670
1670
|
const startLine = Math.max(1, Math.min(totalLines, Number(startLineRaw) || 1));
|
|
1671
1671
|
const endLine = Math.max(startLine, Math.min(totalLines, Number(endLineRaw) || startLine));
|
|
1672
1672
|
let startOffset = 0;
|
|
@@ -1678,12 +1678,64 @@ function lineRangeToOffsets(content, startLineRaw, endLineRaw) {
|
|
|
1678
1678
|
endOffset += lines[i - 1].length;
|
|
1679
1679
|
if (i < endLine) endOffset += 1;
|
|
1680
1680
|
}
|
|
1681
|
-
return { startLine, endLine, startOffset, endOffset };
|
|
1682
|
-
}
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
const
|
|
1686
|
-
const
|
|
1681
|
+
return { startLine, endLine, startOffset, endOffset };
|
|
1682
|
+
}
|
|
1683
|
+
|
|
1684
|
+
function normalizeNewlinesWithMap(text) {
|
|
1685
|
+
const source = String(text || '');
|
|
1686
|
+
const chars = [];
|
|
1687
|
+
const indexMap = [];
|
|
1688
|
+
for (let i = 0; i < source.length; i += 1) {
|
|
1689
|
+
const ch = source[i];
|
|
1690
|
+
if (ch === '\r') {
|
|
1691
|
+
chars.push('\n');
|
|
1692
|
+
indexMap.push(i);
|
|
1693
|
+
if (source[i + 1] === '\n') i += 1;
|
|
1694
|
+
continue;
|
|
1695
|
+
}
|
|
1696
|
+
chars.push(ch);
|
|
1697
|
+
indexMap.push(i);
|
|
1698
|
+
}
|
|
1699
|
+
return { text: chars.join(''), indexMap };
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1702
|
+
function detectEol(text) {
|
|
1703
|
+
const sample = String(text || '');
|
|
1704
|
+
const crlf = (sample.match(/\r\n/g) || []).length;
|
|
1705
|
+
const loneLf = (sample.match(/(?<!\r)\n/g) || []).length;
|
|
1706
|
+
const loneCr = (sample.match(/\r(?!\n)/g) || []).length;
|
|
1707
|
+
if (crlf >= loneLf && crlf >= loneCr && crlf > 0) return '\r\n';
|
|
1708
|
+
if (loneCr > loneLf && loneCr > 0) return '\r';
|
|
1709
|
+
return '\n';
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1712
|
+
function applyEol(text, eol) {
|
|
1713
|
+
return String(text || '').replace(/\r\n|\r|\n/g, eol || '\n');
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1716
|
+
function findLineEndingEquivalentMatches(content, oldText) {
|
|
1717
|
+
const normalizedOld = normalizeNewlinesWithMap(oldText).text;
|
|
1718
|
+
if (!normalizedOld) return [];
|
|
1719
|
+
const normalizedContent = normalizeNewlinesWithMap(content);
|
|
1720
|
+
const matches = [];
|
|
1721
|
+
let pos = 0;
|
|
1722
|
+
while (true) {
|
|
1723
|
+
const found = normalizedContent.text.indexOf(normalizedOld, pos);
|
|
1724
|
+
if (found === -1) break;
|
|
1725
|
+
const start = normalizedContent.indexMap[found] ?? 0;
|
|
1726
|
+
const endNorm = found + normalizedOld.length;
|
|
1727
|
+
const end = endNorm >= normalizedContent.text.length
|
|
1728
|
+
? String(content || '').length
|
|
1729
|
+
: normalizedContent.indexMap[endNorm];
|
|
1730
|
+
matches.push({ start, end });
|
|
1731
|
+
pos = found + Math.max(1, normalizedOld.length);
|
|
1732
|
+
}
|
|
1733
|
+
return matches;
|
|
1734
|
+
}
|
|
1735
|
+
|
|
1736
|
+
async function replaceBlock(root, args, config = {}) {
|
|
1737
|
+
const relativePath = String(args?.path || '').trim();
|
|
1738
|
+
const newContent = String(args?.new_content || args?.content || '');
|
|
1687
1739
|
const target = args?.target || {};
|
|
1688
1740
|
const state = await getFileState(root, relativePath, config);
|
|
1689
1741
|
const resolved = resolveReplaceBlockTarget(state, target);
|
|
@@ -1712,14 +1764,39 @@ async function replaceText(root, args, config = {}) {
|
|
|
1712
1764
|
const rangeStart = Number(args?.start_line || args?.line);
|
|
1713
1765
|
const rangeEnd = Number(args?.end_line || args?.line);
|
|
1714
1766
|
const hasRange = Number.isFinite(rangeStart) && rangeStart > 0;
|
|
1715
|
-
const range = hasRange
|
|
1716
|
-
? lineRangeToOffsets(state.content, rangeStart, Number.isFinite(rangeEnd) && rangeEnd >= rangeStart ? rangeEnd : rangeStart)
|
|
1717
|
-
: null;
|
|
1718
|
-
const searchContent = range ? state.content.slice(range.startOffset, range.endOffset) : state.content;
|
|
1719
|
-
const occurrences = searchContent.split(oldText).length - 1;
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1767
|
+
const range = hasRange
|
|
1768
|
+
? lineRangeToOffsets(state.content, rangeStart, Number.isFinite(rangeEnd) && rangeEnd >= rangeStart ? rangeEnd : rangeStart)
|
|
1769
|
+
: null;
|
|
1770
|
+
const searchContent = range ? state.content.slice(range.startOffset, range.endOffset) : state.content;
|
|
1771
|
+
const occurrences = searchContent.split(oldText).length - 1;
|
|
1772
|
+
let newlineMatches = null;
|
|
1773
|
+
if (occurrences === 0 && /[\r\n]/.test(oldText)) {
|
|
1774
|
+
newlineMatches = findLineEndingEquivalentMatches(searchContent, oldText);
|
|
1775
|
+
if ((replaceAll && newlineMatches.length > 0) || newlineMatches.length === 1) {
|
|
1776
|
+
let cursor = 0;
|
|
1777
|
+
let replaced = '';
|
|
1778
|
+
for (const match of newlineMatches) {
|
|
1779
|
+
const originalMatch = searchContent.slice(match.start, match.end);
|
|
1780
|
+
replaced += searchContent.slice(cursor, match.start);
|
|
1781
|
+
replaced += applyEol(newText, detectEol(originalMatch));
|
|
1782
|
+
cursor = match.end;
|
|
1783
|
+
if (!replaceAll) break;
|
|
1784
|
+
}
|
|
1785
|
+
replaced += searchContent.slice(cursor);
|
|
1786
|
+
const afterContent = range
|
|
1787
|
+
? `${state.content.slice(0, range.startOffset)}${replaced}${state.content.slice(range.endOffset)}`
|
|
1788
|
+
: replaced;
|
|
1789
|
+
await fs.writeFile(state.target, afterContent, 'utf8');
|
|
1790
|
+
const first = newlineMatches[0];
|
|
1791
|
+
const changedLine = range
|
|
1792
|
+
? range.startLine + splitLines(searchContent.slice(0, first.start)).length - 1
|
|
1793
|
+
: splitLines(state.content.slice(0, first.start)).length;
|
|
1794
|
+
return editResult(relativePath, 'replace_text', state.content, afterContent, changedLine);
|
|
1795
|
+
}
|
|
1796
|
+
}
|
|
1797
|
+
if (occurrences !== 1) {
|
|
1798
|
+
if (replaceAll && occurrences > 0) {
|
|
1799
|
+
const replaced = searchContent.replaceAll(oldText, newText);
|
|
1723
1800
|
const afterContent = range
|
|
1724
1801
|
? `${state.content.slice(0, range.startOffset)}${replaced}${state.content.slice(range.endOffset)}`
|
|
1725
1802
|
: state.content.replaceAll(oldText, newText);
|
|
@@ -1744,13 +1821,14 @@ async function replaceText(root, args, config = {}) {
|
|
|
1744
1821
|
lineDetails.push(` Line ${lineNum}: ${lineText}`);
|
|
1745
1822
|
searchPos = pos + oldText.length;
|
|
1746
1823
|
}
|
|
1747
|
-
const lineHint = lineDetails.length > 0 ? `\n${lineDetails.join('\n')}\n` : ' ';
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1824
|
+
const lineHint = lineDetails.length > 0 ? `\n${lineDetails.join('\n')}\n` : ' ';
|
|
1825
|
+
const effectiveOccurrences = newlineMatches?.length || occurrences;
|
|
1826
|
+
throw new Error(
|
|
1827
|
+
effectiveOccurrences === 0
|
|
1828
|
+
? 'replace_text old_text not found'
|
|
1829
|
+
: `replace_text old_text not unique; found ${effectiveOccurrences} occurrences:${lineHint}Use path:"${relativePath}:N-M" to narrow the range, set replace_all=true, or provide more unique old_text`
|
|
1830
|
+
);
|
|
1831
|
+
}
|
|
1754
1832
|
const replaced = searchContent.replace(oldText, newText);
|
|
1755
1833
|
const afterContent = range
|
|
1756
1834
|
? `${state.content.slice(0, range.startOffset)}${replaced}${state.content.slice(range.endOffset)}`
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-S-ySWqyJ.js";import{a as t,r as n}from"./bundle-mjs-C44PrJ2C.js";import{t as r}from"./refresh-cw-D7R5Lth6.js";import{$ as i,H as a,M as o,P as s,S as c,T as ee,U as te,ct as l,ft as u,h as ne,m as re,nt as ie,o as ae,p as oe,t as d,v as f,z as se}from"./index-CDXQGwPs.js";import{MessageBubble as ce,t as le}from"./MessageBubble-CGnnViv0.js";var ue=s(`circle-alert`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`line`,{x1:`12`,x2:`12`,y1:`8`,y2:`12`,key:`1pkeuh`}],[`line`,{x1:`12`,x2:`12.01`,y1:`16`,y2:`16`,key:`4dfq90`}]]),de=s(`grip-vertical`,[[`circle`,{cx:`9`,cy:`12`,r:`1`,key:`1vctgf`}],[`circle`,{cx:`9`,cy:`5`,r:`1`,key:`hp0tcf`}],[`circle`,{cx:`9`,cy:`19`,r:`1`,key:`fkjjf6`}],[`circle`,{cx:`15`,cy:`12`,r:`1`,key:`1tmaij`}],[`circle`,{cx:`15`,cy:`5`,r:`1`,key:`19l28e`}],[`circle`,{cx:`15`,cy:`19`,r:`1`,key:`f4zoj3`}]]),fe=s(`send-horizontal`,[[`path`,{d:`M3.714 3.048a.498.498 0 0 0-.683.627l2.843 7.627a2 2 0 0 1 0 1.396l-2.842 7.627a.498.498 0 0 0 .682.627l18-8.5a.5.5 0 0 0 0-.904z`,key:`117uat`}],[`path`,{d:`M6 12h16`,key:`s4cdu5`}]]),p=e(t(),1),m=n(),pe=`codemini:codewiki:qa-width`,h=320,me=760,g=420,he=!1;function ge(){if(typeof window>`u`)return g;let e=Number(window.localStorage.getItem(pe));return Number.isFinite(e)?Math.min(me,Math.max(h,e)):g}function _(){return[{value:`fast`,label:l(`generationDepthFast`)},{value:`standard`,label:l(`generationDepthStandard`)},{value:`deep`,label:l(`generationDepthDeep`)}]}function _e(e){if(!e)return``;try{return new Intl.DateTimeFormat(`zh-CN`,{month:`short`,day:`numeric`,hour:`2-digit`,minute:`2-digit`}).format(new Date(e))}catch{return``}}function v(e){let t=Number(e||0);return!Number.isFinite(t)||t<=0?``:t<1024?`${t} B`:t<1024*1024?`${Math.round(t/1024)} KB`:`${(t/1024/1024).toFixed(1)} MB`}function y(e,t){let n=Array.isArray(e)?e:[];if(!n.length)return{done:0,total:0,pct:8,label:t||l(`startingAnalysis`),detail:l(`preparingScan`)};let r=n.filter(e=>e.status===`done`).length,i=n.find(e=>e.status===`failed`),a=n.find(e=>e.status===`running`)||n.find(e=>e.status===`in_progress`)||n.find(e=>e.status===`pending`)||n[n.length-1];return{done:r,total:n.length,pct:Math.max(8,Math.round(r/n.length*100)),label:i?l(`generationFailed`):a?.title||t||l(`generatingCodeWiki`),detail:i?i.title:`${r}/${n.length} ${l(`stepsCompleted`)}${a?.role?` · ${a.role.toUpperCase()}`:``}`}}function b({steps:e,stageLabel:t,compact:n=!1}){let r=y(e,t);return(0,m.jsxs)(`div`,{className:u(`rounded-lg border border-(--border-default) bg-(--bg-primary) p-3 text-left`,n?`mt-3`:`mt-5 w-full max-w-md`),children:[(0,m.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,m.jsx)(`span`,{className:`truncate text-[12px] font-medium text-(--text-primary)`,children:r.label}),r.total>0&&(0,m.jsxs)(`span`,{className:`shrink-0 text-[11px] text-(--text-muted)`,children:[r.done,`/`,r.total]})]}),(0,m.jsx)(d,{value:r.pct,className:`mt-2 h-1.5`}),(0,m.jsx)(`p`,{className:`mt-2 truncate text-[11px] text-(--text-muted)`,children:r.detail})]})}function x(e,t){if(!Array.isArray(e)||e.length===0)return[{type:`tools`,cards:[t]}];let n=e[e.length-1];return n.type===`tools`?[...e.slice(0,-1),{...n,cards:[...n.cards,t]}]:[...e,{type:`tools`,cards:[t]}]}function S(e,t,n){return(Array.isArray(e)?e:[]).map(e=>{if(e.type!==`tools`)return e;let r=e.cards.findIndex(e=>e.id===t);if(r===-1)return e;let i=[...e.cards];return i[r]=n(i[r]),{...e,cards:i}})}function C(e){let t=Array.isArray(e)?e:[];return t.length===0?[{type:`text`,text:``,isStreaming:!1}]:t[t.length-1].type===`text`?t:[...t,{type:`text`,text:``,isStreaming:!1}]}function w(e,t){let n=String(t||``);if(!n)return Array.isArray(e)?e:[];let r=C(e),i=r[r.length-1];return[...r.slice(0,-1),{...i,text:`${i.text||``}${n}`,isStreaming:!0}]}function T(e,t){let n=C(e),r=n.length-1;return n.map((e,n)=>n===r&&e.type===`text`?{...e,text:t,isStreaming:!1}:e)}function E(e){return(Array.isArray(e)?e:[]).map(e=>e.type===`text`?{...e,isStreaming:!1}:e)}function ve(e,t){switch(t?.type){case`assistant:delta`:return{...e,segments:w(e.segments,t.text)};case`assistant:response`:return{...e,segments:t.text?T(e.segments,t.text):E(e.segments)};case`tool:start`:return{...e,segments:x(e.segments,{id:t.id,name:t.name,arguments:t.arguments,status:`running`,durationMs:null,summary:``,result:``})};case`tool:result`:return{...e,segments:S(e.segments,t.id,e=>({...e,result:t.content||e.result||``}))};case`tool:end`:return{...e,segments:S(e.segments,t.id,e=>({...e,status:`done`,durationMs:t.durationMs,summary:t.summary||e.summary||``}))};case`tool:error`:return{...e,segments:S(e.segments,t.id,e=>({...e,status:`error`,durationMs:t.durationMs,summary:t.summary||e.summary||``}))};case`tool:blocked`:return{...e,segments:S(e.segments,t.id,e=>({...e,status:`blocked`,summary:e.summary||`Tool blocked`}))};case`codewiki:done`:return{...e,loading:!1,segments:E(e.segments)};case`codewiki:error`:return{...e,role:`error`,loading:!1,segments:[{type:`text`,text:t.message||l(`codewikiFailed`),isStreaming:!1}]};default:return e}}function D({projectCwd:e,projectKey:t,busy:n,planSteps:s=[],stageLabel:d=``}){let[y,x]=(0,p.useState)([]),[S,C]=(0,p.useState)(``),[w,T]=(0,p.useState)(`report`),[E,D]=(0,p.useState)(!0),[ye,O]=(0,p.useState)(!1),[be,k]=(0,p.useState)(``),[xe,A]=(0,p.useState)(null),[j,M]=(0,p.useState)(!1),[Se,N]=(0,p.useState)(``),[Ce,P]=(0,p.useState)(!1),[F,I]=(0,p.useState)(``),[we,Te]=(0,p.useState)(``),[L,R]=(0,p.useState)(!1),[z,B]=(0,p.useState)(null),[Ee,V]=(0,p.useState)(!1),[H,U]=(0,p.useState)(`standard`),[W,G]=(0,p.useState)([]),[K,q]=(0,p.useState)(!1),[J,De]=(0,p.useState)(ge),[Oe,Y]=(0,p.useState)(!1),ke=(0,p.useRef)(null),X=(0,p.useRef)({startX:0,startWidth:g}),Z=(0,p.useMemo)(()=>y.find(e=>e.file===S)||null,[y,S]),Ae=Z?`/api/codewiki/report/${encodeURIComponent(Z.file)}${t?`?project=${encodeURIComponent(t)}`:``}`:``,je=(0,p.useCallback)(async()=>{O(!0),k(``);try{let e=await te(t);A(e),e?.error&&k(e.error)}catch(e){k(e?.message||`Failed to load code graph`)}finally{O(!1)}},[t]),Q=(0,p.useCallback)(async({preferNewest:e=!1}={})=>{D(!0),N(``);try{let n=await a(t),r=[...Array.isArray(n?.reports)?n.reports:[]].sort((e,t)=>new Date(t.mtime||0)-new Date(e.mtime||0));x(r),C(t=>e&&r[0]?r[0].file:r.some(e=>e.file===t)?t:r[0]?.file||``)}catch(e){N(e?.message||l(`failedToLoad`))}finally{D(!1)}},[t]);(0,p.useEffect)(()=>{x([]),C(``),T(`report`),P(!1),I(``),Te(``),G([]),q(!1),A(null),k(``),Q({preferNewest:!0})},[Q,je,t]),(0,p.useEffect)(()=>{let e=ke.current;e&&requestAnimationFrame(()=>{e.scrollTop=e.scrollHeight})},[W,K]),(0,p.useEffect)(()=>{j&&n&&R(!0)},[n,j]),(0,p.useEffect)(()=>{!j||n||!L||(Q({preferNewest:!0}),M(!1),R(!1))},[n,j,Q,L]),(0,p.useEffect)(()=>{window.localStorage.setItem(pe,String(J))},[J]);let Me=(0,p.useCallback)(e=>{e.preventDefault(),Y(!0),X.current={startX:e.clientX,startWidth:J};let t=e=>{let t=X.current.startX-e.clientX,n=Math.max(h,Math.min(me,window.innerWidth-720));De(Math.min(n,Math.max(h,X.current.startWidth+t)))},n=()=>{Y(!1),document.body.style.cursor=``,document.body.style.userSelect=``,window.removeEventListener(`mousemove`,t),window.removeEventListener(`mouseup`,n)};document.body.style.cursor=`col-resize`,document.body.style.userSelect=`none`,window.addEventListener(`mousemove`,t),window.addEventListener(`mouseup`,n)},[J]),Ne=async()=>{if(!(n||j)){N(``),M(!0),R(!1);try{let e=await i(H,t);e?.error&&(M(!1),N(e.message||l(`failedToStart`)))}catch(e){M(!1),N(e?.message||l(`failedToStart`))}}},Pe=async e=>{e.preventDefault();let n=F.trim();if(!n||$||K)return;let r=Date.now(),i=`cw-assistant-${r}`;Te(n),I(``),N(``),G(e=>[...e,{id:`cw-user-${r}`,role:`you`,text:n,segments:[{type:`text`,text:n,isStreaming:!1}],timestamp:new Date().toISOString()},{id:i,role:`general`,text:``,segments:[],timestamp:new Date().toISOString(),loading:!0}]),q(!0);try{await ie({question:n,reportFile:Z?.file||``,project:t,onEvent:e=>{G(t=>t.map(t=>t.id===i?ve(t,e):t))}})}catch(e){G(t=>t.map(t=>t.id===i?{...t,role:`error`,loading:!1,segments:[{type:`text`,text:e?.message||l(`codewikiFailed`),isStreaming:!1}]}:t))}finally{q(!1)}},Fe=async()=>{if(z){V(!0),N(``);try{let e=await se(z.file,t);e?.error?N(e.message||l(`failedToDelete`)):(B(null),P(!1),await Q({preferNewest:!1}))}catch(e){N(e?.message||l(`failedToDelete`))}finally{V(!1)}}},$=n||j,Ie=$||K;return(0,m.jsxs)(`div`,{className:`flex-1 min-h-0 bg-(--bg-primary) rounded-[18px] border border-(--border-default) border-b-0 overflow-hidden my-1 mx-1`,children:[(0,m.jsxs)(`div`,{className:`codewiki-layout h-full min-h-0`,style:{"--codewiki-qa-width":`${J}px`},children:[(0,m.jsxs)(`aside`,{className:`border-r border-(--border-default) bg-(--bg-secondary) min-h-0 flex flex-col max-lg:hidden`,children:[(0,m.jsxs)(`div`,{className:`p-4 border-b border-(--border-default)`,children:[(0,m.jsxs)(`div`,{className:`flex items-center gap-2 text-(--text-primary)`,children:[(0,m.jsx)(o,{size:18}),(0,m.jsx)(`span`,{className:`font-semibold text-[15px]`,children:`CodeWiki`})]}),(0,m.jsx)(`p`,{className:`mt-2 text-[12px] leading-5 text-(--text-muted) truncate`,title:e||``,children:e||l(`currentProject`)}),(0,m.jsx)(`div`,{className:`mt-4 grid grid-cols-3 gap-1 rounded-lg border border-(--border-default) bg-(--bg-primary) p-1`,children:_().map(e=>(0,m.jsx)(`button`,{type:`button`,className:u(`h-7 rounded-md text-[12px] text-(--text-muted) hover:bg-(--bg-hover) hover:text-(--text-primary) disabled:cursor-not-allowed disabled:opacity-60`,H===e.value&&`bg-(--bg-active) text-(--text-primary)`),disabled:$,onClick:()=>U(e.value),children:e.label},e.value))}),(0,m.jsxs)(`button`,{className:`mt-3 w-full h-9 rounded-lg border border-(--border-default) bg-(--bg-primary) text-[13px] text-(--text-primary) inline-flex items-center justify-center gap-2 hover:bg-(--bg-hover) disabled:cursor-not-allowed disabled:opacity-60`,onClick:Ne,disabled:$,children:[j?(0,m.jsx)(c,{size:15,className:`animate-spin`}):(0,m.jsx)(f,{size:15}),l(j?`generating`:`generateNew`)]}),j&&(0,m.jsx)(b,{steps:s,stageLabel:d,compact:!0})]}),(0,m.jsxs)(`div`,{className:`flex items-center justify-between px-4 py-3`,children:[(0,m.jsx)(`span`,{className:`text-[12px] font-medium text-(--text-muted)`,children:`Documents`}),(0,m.jsx)(`button`,{className:`inline-flex size-7 items-center justify-center rounded-md text-(--text-muted) hover:bg-(--bg-hover) hover:text-(--text-primary)`,onClick:()=>{Q({preferNewest:!0})},title:`Refresh`,"aria-label":`Refresh`,children:(0,m.jsx)(r,{size:14})})]}),(0,m.jsxs)(`div`,{className:`flex-1 overflow-y-auto px-2 pb-4`,children:[he,E&&(0,m.jsxs)(`div`,{className:`px-3 py-6 text-[12px] text-(--text-muted) inline-flex items-center gap-2`,children:[(0,m.jsx)(c,{size:14,className:`animate-spin`}),l(`loadingReport`)]}),!E&&y.length===0&&(0,m.jsx)(`div`,{className:`mx-2 rounded-lg border border-dashed border-(--border-default) px-3 py-4 text-[12px] leading-5 text-(--text-muted)`,children:l(`noReportYet`)}),(0,m.jsx)(`div`,{className:`flex flex-col gap-1`,children:y.map(e=>(0,m.jsxs)(`div`,{className:u(`group w-full rounded-lg px-3 py-2 text-left hover:bg-(--bg-hover) cursor-pointer`,w===`report`&&S===e.file&&`bg-(--bg-active)`),onClick:()=>{T(`report`),C(e.file),P(!1)},children:[(0,m.jsxs)(`span`,{className:`flex items-start gap-2 text-[13px] text-(--text-primary)`,children:[(0,m.jsx)(le,{size:14,className:`shrink-0 mt-0.5 text-(--text-muted)`}),(0,m.jsx)(`span`,{className:`min-w-0 flex-1 break-words`,children:e.file}),(0,m.jsxs)(oe,{children:[(0,m.jsx)(ne,{asChild:!0,children:(0,m.jsx)(`button`,{type:`button`,className:`inline-flex size-6 shrink-0 items-center justify-center rounded-md text-(--text-muted) opacity-0 hover:bg-(--bg-active) hover:text-(--text-primary) group-hover:opacity-100 focus:opacity-100`,onClick:e=>e.stopPropagation(),"aria-label":l(`reportActions`),children:(0,m.jsx)(ee,{size:14})})}),(0,m.jsx)(re,{align:`end`,className:`w-36 border-(--border-default) bg-(--bg-primary) p-1 text-(--text-primary)`,onClick:e=>e.stopPropagation(),children:(0,m.jsx)(`button`,{type:`button`,className:`w-full rounded-md px-2.5 py-2 text-left text-[13px] text-(--accent-red) hover:bg-(--accent-red-bg)`,onClick:()=>B(e),children:l(`deleteReport`)})})]})]}),(0,m.jsxs)(`span`,{className:`mt-1 block truncate pl-6 text-[11px] text-(--text-muted)`,children:[_e(e.mtime),v(e.size)?` · ${v(e.size)}`:``]})]},e.file))})]})]}),(0,m.jsxs)(`main`,{className:`min-w-0 min-h-0 flex flex-col bg-(--bg-primary)`,children:[Se&&(0,m.jsxs)(`div`,{className:`mx-5 mt-4 rounded-lg border border-red-500/30 bg-red-500/10 px-3 py-2 text-[12px] text-red-400 inline-flex items-center gap-2`,children:[(0,m.jsx)(ue,{size:14}),Se]}),(0,m.jsx)(`div`,{className:`flex-1 min-h-0 p-4`,children:!Z&&!E?(0,m.jsxs)(`div`,{className:`h-full min-h-[420px] rounded-xl border border-dashed border-(--border-default) bg-(--bg-secondary) flex flex-col items-center justify-center text-center px-8`,children:[(0,m.jsx)(o,{size:34,className:`text-(--text-muted)`}),(0,m.jsx)(`h2`,{className:`mt-4 text-[18px] font-semibold text-(--text-primary)`,children:l(`noCodeWiki`)}),(0,m.jsx)(`p`,{className:`mt-2 max-w-md text-[13px] leading-6 text-(--text-muted)`,children:l(`reportWillShow`)}),(0,m.jsxs)(`button`,{className:`mt-5 h-10 rounded-lg bg-(--text-primary) px-4 text-[13px] font-medium text-(--bg-primary) inline-flex items-center gap-2 disabled:cursor-not-allowed disabled:opacity-60`,onClick:Ne,disabled:$,children:[j?(0,m.jsx)(c,{size:16,className:`animate-spin`}):(0,m.jsx)(f,{size:16}),l(j?`generating`:`generateNew`)]}),(0,m.jsx)(`div`,{className:`mt-3 grid w-full max-w-xs grid-cols-3 gap-1 rounded-lg border border-(--border-default) bg-(--bg-primary) p-1`,children:_().map(e=>(0,m.jsx)(`button`,{type:`button`,className:u(`h-7 rounded-md text-[12px] text-(--text-muted) hover:bg-(--bg-hover) hover:text-(--text-primary) disabled:cursor-not-allowed disabled:opacity-60`,H===e.value&&`bg-(--bg-active) text-(--text-primary)`),disabled:$,onClick:()=>U(e.value),children:e.label},e.value))}),j&&(0,m.jsx)(b,{steps:s,stageLabel:d})]}):(0,m.jsx)(`div`,{className:`h-full min-h-[420px] overflow-hidden rounded-xl border border-(--border-default) bg-(--bg-secondary)`,children:Ce?(0,m.jsxs)(`div`,{className:`h-full flex flex-col items-center justify-center px-8 text-center`,children:[(0,m.jsx)(ue,{size:28,className:`text-(--text-muted)`}),(0,m.jsx)(`p`,{className:`mt-3 text-[13px] text-(--text-secondary)`,children:l(`reportLoadFailed`)}),(0,m.jsx)(`button`,{className:`mt-4 h-8 rounded-md border border-(--border-default) px-3 text-[12px] text-(--text-primary) hover:bg-(--bg-hover)`,onClick:()=>P(!1),children:l(`retry`)})]}):Z?(0,m.jsx)(`iframe`,{title:`CodeWiki ${Z.file}`,src:Ae,sandbox:`allow-scripts`,className:`h-full w-full border-0 bg-white`,onLoad:()=>P(!1),onError:()=>P(!0)},Z.file):(0,m.jsxs)(`div`,{className:`h-full flex items-center justify-center text-[13px] text-(--text-muted)`,children:[(0,m.jsx)(c,{size:16,className:`mr-2 animate-spin`}),l(`loading`)]})})})]}),(0,m.jsx)(`div`,{className:`codewiki-resizer max-xl:hidden`,role:`separator`,"aria-orientation":`vertical`,"aria-label":`Resize CodeWiki Q&A panel`,title:`Drag to resize`,onMouseDown:Me,children:(0,m.jsx)(`span`,{className:`codewiki-resizer-handle`,children:(0,m.jsx)(de,{size:14,"aria-hidden":`true`})})}),(0,m.jsxs)(`aside`,{className:`bg-(--bg-secondary) min-h-0 flex flex-col max-xl:hidden`,children:[(0,m.jsx)(`div`,{className:`p-4 border-b border-(--border-default)`,children:(0,m.jsx)(`p`,{className:`mt-2 text-[12px] leading-5 text-(--text-muted)`,children:l(j?`noQuestionsDuringGeneration`:`tempReadOnlyQa`)})}),(0,m.jsx)(`div`,{ref:ke,className:`flex-1 min-h-0 overflow-y-auto px-4 py-3`,children:W.length===0?(0,m.jsxs)(`div`,{className:`rounded-xl border border-(--border-default) bg-(--bg-primary) p-4`,children:[(0,m.jsx)(`p`,{className:`text-[13px] font-medium text-(--text-primary)`,children:l(j?`generatingCodeWiki`:K||n?`processingQuestion`:`canAskAboutProject`)}),(0,m.jsx)(`p`,{className:`mt-2 text-[12px] leading-5 text-(--text-muted)`,children:j?l(`askAfterGeneration`):we||l(`exampleQuestions`)})]}):(0,m.jsx)(`div`,{className:`flex flex-col`,children:W.map(e=>(0,m.jsxs)(`div`,{children:[(0,m.jsx)(ce,{message:e}),e.loading&&(!e.segments||e.segments.length===0)&&(0,m.jsxs)(`div`,{className:`mt-[-12px] mb-3 ml-1 inline-flex items-center gap-2 rounded-xl border border-(--border-default) bg-(--bg-primary) px-3 py-2 text-[12px] text-(--text-muted)`,children:[(0,m.jsx)(c,{size:14,className:`animate-spin`}),l(`answering`)]})]},e.id))})}),(0,m.jsx)(`form`,{className:`p-4 border-t border-(--border-default)`,onSubmit:Pe,children:(0,m.jsxs)(`div`,{className:`flex items-center gap-2 rounded-full border border-(--border-default) bg-(--bg-primary) px-3 py-2`,children:[(0,m.jsx)(`input`,{value:F,onChange:e=>I(e.target.value),placeholder:j?l(`generatingCodeWiki`):K||n?l(`answering`):`Ask about this repository`,disabled:Ie,className:`min-w-0 flex-1 border-0 bg-transparent text-[13px] text-(--text-primary) outline-none placeholder:text-(--text-muted) disabled:opacity-60`}),(0,m.jsx)(`button`,{type:`submit`,className:`inline-flex size-7 items-center justify-center rounded-full text-(--text-muted) hover:bg-(--bg-hover) hover:text-(--text-primary) disabled:cursor-not-allowed disabled:opacity-50`,disabled:Ie||!F.trim(),"aria-label":l(`sendingQuestion`),children:K?(0,m.jsx)(c,{size:15,className:`animate-spin`}):(0,m.jsx)(fe,{size:15})})]})})]})]}),Oe&&(0,m.jsx)(`div`,{className:`codewiki-resize-overlay`}),(0,m.jsx)(ae,{open:!!z,title:l(`deleteReportConfirm`),description:l(`deleteReportDescription`).replace(`{{report}}`,z?.title||z?.file||``),loading:Ee,onOpenChange:e=>!e&&B(null),onConfirm:Fe})]})}export{D as CodeWikiPanel};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./rolldown-runtime-S-ySWqyJ.js";import{a as t,r as n}from"./bundle-mjs-C44PrJ2C.js";import{a as r,i,n as a,r as o,t as s}from"./select-DBvcHBzs.js";import{P as c,W as l,a as u,c as d,ct as f,d as p,dt as m,f as h,ft as g,g as _,l as v,lt as y,s as b,tt as x,u as S,ut as C}from"./index-CDXQGwPs.js";import{t as w}from"./input-Ca8O_061.js";var T=c(`circle-question-mark`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3`,key:`1u773s`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}]]),E=e(t(),1),D=n();function O(e,t){return t.split(`.`).reduce((e,t)=>e?.[t],e)}function k(e){let t=Array.isArray(e?.options)?e.options.map(String):[];return t.length===2&&t.includes(`true`)&&t.includes(`false`)}function A({checked:e,onClick:t,title:n}){return(0,D.jsx)(`button`,{type:`button`,onClick:t,title:n,"aria-pressed":e,className:g(`relative h-5 w-9 rounded-full border shadow-inner transition-colors`,e?`border-(--text-primary) bg-(--text-primary)`:`border-(--border-strong) bg-(--bg-hover)`),children:(0,D.jsx)(`span`,{className:g(`absolute left-0.5 top-0.5 size-3.5 rounded-full transition-transform`,e?`bg-(--bg-primary)`:`bg-(--text-muted)`,e?`translate-x-4`:`translate-x-0`)})})}function j({open:e,onOpenChange:t,status:n=null,onSaved:c}){let g=[{title:f(`gateway`),keys:[{path:`gateway.base_url`,label:f(`baseUrl`),placeholder:`http://127.0.0.1:8000/v1`},{path:`gateway.api_key`,label:f(`apiKey`),type:`password`,placeholder:`sk-...`},{path:`gateway.timeout_ms`,label:f(`timeout`),type:`number`},{path:`gateway.max_retries`,label:f(`maxRetries`),type:`number`}]},{title:f(`sdk`),keys:[{path:`sdk.provider`,label:f(`provider`),options:[`openai-compatible`,`anthropic`],optionLogos:{"openai-compatible":`/logos/openai.svg`,anthropic:`/logos/claude-color.svg`}}]},{title:f(`model`),keys:[{path:`model.name`,label:f(`modelName`),placeholder:`gpt-4.1-mini`},{path:`model.fast_name`,label:f(`fastModel`),placeholder:`fallback to Model Name when empty`},{path:`model.max_context_tokens`,label:f(`maxContextTokens`),type:`number`}]},{title:f(`execution`),keys:[{path:`execution.mode`,label:f(`mode`),options:[`normal`,`plan`],optionLabels:{normal:f(`normalExecutionMode`),plan:f(`planMode`)}},{path:`execution.approval_mode`,label:f(`approvalMode`),options:[`review`,`auto`,`full_access`],optionLabels:{review:f(`reviewMode`),auto:f(`autoMode`),full_access:f(`fullAccessMode`)}},{path:`execution.max_steps`,label:f(`maxSteps`),type:`number`},{path:`ui.reply_language`,label:f(`replyLanguage`),options:[`zh`,`en`]}]},{title:f(`context`),keys:[{path:`context.preflight_trigger_pct`,label:f(`preflightTrigger`),type:`number`,placeholder:`60`},{path:`context.hard_limit_pct`,label:f(`hardLimit`),type:`number`,placeholder:`98`},{path:`context.tool_result_max_chars`,label:f(`toolResultMaxChars`),type:`number`,placeholder:`12000`},{path:`context.microcompact_enabled`,label:f(`microcompactEnabled`),options:[`true`,`false`]},{path:`context.microcompact_keep_recent`,label:f(`microcompactKeepRecent`),type:`number`,placeholder:`5`}]},{title:f(`shell`),keys:[{path:`shell.default`,label:f(`defaultShell`),options:[`bash`,`powershell`,`zsh`,`cmd`]}]},{title:f(`policy`),keys:[{path:`policy.safe_mode`,label:f(`safeMode`),options:[`true`,`false`]},{path:`policy.allowed_paths`,label:f(`allowedPaths`),placeholder:`["D:\\\\shared-assets","E:\\\\sibling-repo"]`,help:f(`allowedPathsHelp`)},{path:`policy.allow_dangerous_commands`,label:f(`allowDangerousCommands`),options:[`false`,`true`]}]}],[j,M]=(0,E.useState)(null),[N,P]=(0,E.useState)({}),[F,I]=(0,E.useState)(!1);(0,E.useEffect)(()=>{e&&(I(!0),l().then(e=>{M(e),P({})}).catch(()=>{}).finally(()=>I(!1)))},[e]);let L=(e,t)=>{P(n=>({...n,[e]:t}))},R=e=>{if(e in N)return N[e];let t=j?O(j,e):``;return Array.isArray(t)||t&&typeof t==`object`?JSON.stringify(t):String(t??``)},z=Object.keys(N).length>0;return(0,D.jsx)(b,{open:e,onOpenChange:t,children:(0,D.jsxs)(d,{className:`sm:max-w-[640px] max-h-[80vh] flex flex-col`,children:[(0,D.jsx)(S,{className:`shrink-0`,children:(0,D.jsx)(p,{children:f(`settingsTitle`)})}),(0,D.jsxs)(`div`,{className:`space-y-5 px-3.5 py-1 overflow-y-auto flex-1 min-h-0`,children:[n?.setupRequired&&(0,D.jsxs)(`div`,{className:`rounded-md border border-(--border-default) bg-(--bg-secondary) px-3 py-2 text-[13px] text-(--text-primary)`,children:[(0,D.jsx)(`div`,{className:`font-medium`,children:f(`configRequiredTitle`)}),(0,D.jsx)(`div`,{className:`mt-1 text-(--text-secondary)`,children:f(`configRequiredDesc`)})]}),F?(0,D.jsx)(`div`,{className:`flex items-center justify-center py-12`,children:(0,D.jsx)(u,{})}):g.map((e,t)=>(0,D.jsxs)(`div`,{children:[(0,D.jsx)(`div`,{className:`text-[13px] font-semibold text-(--text-secondary) mb-2.5 uppercase tracking-[0.3px]`,children:e.title}),(0,D.jsx)(`div`,{className:`space-y-2.5`,children:e.keys.map(e=>(0,D.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,D.jsxs)(`label`,{className:`text-[13px] text-(--text-muted) w-32 shrink-0`,children:[(0,D.jsx)(`span`,{children:e.label}),e.help&&(0,D.jsxs)(y,{children:[(0,D.jsx)(m,{asChild:!0,children:(0,D.jsx)(`button`,{type:`button`,className:`ml-1 inline-flex align-[-2px] text-(--text-muted) hover:text-(--text-primary)`,"aria-label":e.help,children:(0,D.jsx)(T,{size:13,strokeWidth:1.8})})}),(0,D.jsx)(C,{side:`right`,className:`max-w-[300px] leading-relaxed`,children:e.help})]})]}),k(e)?(0,D.jsx)(`div`,{className:`flex-1 flex items-center justify-end min-h-8`,children:(0,D.jsx)(A,{checked:R(e.path)===`true`,title:e.label,onClick:()=>L(e.path,R(e.path)!==`true`)})}):e.options?(0,D.jsxs)(s,{value:R(e.path),onValueChange:t=>L(e.path,t),children:[(0,D.jsx)(i,{className:`flex-1 h-8 text-[13px]`,children:(0,D.jsx)(r,{})}),(0,D.jsx)(a,{children:e.options.map(t=>(0,D.jsx)(o,{value:t,children:(0,D.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[e.optionLogos?.[t]&&(0,D.jsx)(`img`,{src:e.optionLogos[t],alt:``,width:13,height:13,className:`shrink-0 rounded-sm object-contain`}),e.optionLabels?.[t]||(e.optionLogos?t.toUpperCase():t)]})},t))})]}):(0,D.jsx)(w,{type:e.type||`text`,value:R(e.path),onChange:t=>L(e.path,t.target.value),placeholder:e.placeholder||``,className:`flex-1 h-8 text-[13px]`})]},e.path))}),t<g.length-1&&(0,D.jsx)(_,{className:`mt-4 bg-(--border-default)`})]},e.title))]}),(0,D.jsxs)(v,{className:`gap-2 shrink-0`,children:[(0,D.jsx)(h,{variant:`outline`,onClick:()=>t(!1),className:`text-[13px]`,children:f(`cancel`)}),(0,D.jsx)(h,{onClick:async()=>{try{for(let[e,t]of Object.entries(N)){let n=g.flatMap(e=>e.keys).find(t=>t.path===e);await x(e,k(n)?t===!0||t===`true`:n?.type===`number`?Number(t):t)}await c?.(),P({}),t(!1)}catch(e){console.error(`Config save failed:`,e)}},disabled:!z,className:`text-[13px]`,children:f(`saveChanges`)})]})]})})}export{j as ConfigDialog};
|