codemini-cli 0.6.3 → 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.
Files changed (49) hide show
  1. package/codemini-web/dist/assets/{AboutDialog-jgqGjQgl.js → AboutDialog-BUp8EzDg.js} +2 -2
  2. package/codemini-web/dist/assets/CodeWikiPanel-Fp0VKdzo.js +1 -0
  3. package/codemini-web/dist/assets/ConfigDialog-DIpj779O.js +1 -0
  4. package/codemini-web/dist/assets/GitDiffDialog-ZLEuX8Qm.js +3 -0
  5. package/codemini-web/dist/assets/{MemoryDialog-BhxQgG0I.js → MemoryDialog-D2YbENVd.js} +3 -3
  6. package/codemini-web/dist/assets/MessageBubble-BIgpZsLn.js +12 -0
  7. package/codemini-web/dist/assets/PatchDiff-CvKNaHsw.js +230 -0
  8. package/codemini-web/dist/assets/ProjectSelector-DXIep3lE.js +1 -0
  9. package/codemini-web/dist/assets/{SkillDialog-DxS43NpR.js → SkillDialog-DjPF-XBx.js} +4 -4
  10. package/codemini-web/dist/assets/SoulDialog-BfIoKETs.js +1 -0
  11. package/codemini-web/dist/assets/chevron-right-CfNZHlyU.js +1 -0
  12. package/codemini-web/dist/assets/{chunk-BO2N2NFS-Budy_hfO.js → chunk-BO2N2NFS-DMUdjM9q.js} +6 -6
  13. package/codemini-web/dist/assets/{highlighted-body-OFNGDK62-CQS1PAvD.js → highlighted-body-OFNGDK62-8ch0jz7Z.js} +1 -1
  14. package/codemini-web/dist/assets/index-BhMtCC8_.js +65 -0
  15. package/codemini-web/dist/assets/index-DRXwJ-n_.css +2 -0
  16. package/codemini-web/dist/assets/input-CYpdNDlR.js +1 -0
  17. package/codemini-web/dist/assets/lib-BXWizt13.js +1 -0
  18. package/codemini-web/dist/assets/mermaid-GHXKKRXX-KBEtMEB9.js +1 -0
  19. package/codemini-web/dist/assets/{pencil-Ce_LFiEh.js → pencil-BdA2cEeE.js} +1 -1
  20. package/codemini-web/dist/assets/{refresh-cw-BKL-AZu5.js → refresh-cw-CJGgUGiS.js} +1 -1
  21. package/codemini-web/dist/assets/select-BLOccU1M.js +1 -0
  22. package/codemini-web/dist/assets/{trash-2-KmAlCwXd.js → trash-2-CQzNOch5.js} +1 -1
  23. package/codemini-web/dist/index.html +2 -2
  24. package/codemini-web/lib/runtime-bridge.js +332 -296
  25. package/codemini-web/server.js +319 -243
  26. package/package.json +1 -1
  27. package/src/core/agent-loop.js +188 -100
  28. package/src/core/chat-runtime.js +676 -571
  29. package/src/core/config-store.js +9 -3
  30. package/src/core/git-oplog-change-tracker.js +468 -0
  31. package/src/core/non-git-backup.js +116 -0
  32. package/src/core/paths.js +123 -123
  33. package/src/core/session-store.js +148 -99
  34. package/src/core/tools.js +555 -434
  35. package/src/tui/chat-app.js +196 -56
  36. package/codemini-web/dist/assets/CodeWikiPanel-EPuoerNv.js +0 -1
  37. package/codemini-web/dist/assets/ConfigDialog-B5IGZCc9.js +0 -1
  38. package/codemini-web/dist/assets/GitDiffDialog-Bb_Tw5ZK.js +0 -222
  39. package/codemini-web/dist/assets/MessageBubble-wUff4GP4.js +0 -6
  40. package/codemini-web/dist/assets/ProjectSelector-C0leTf6f.js +0 -1
  41. package/codemini-web/dist/assets/SoulDialog-XDTEGWvH.js +0 -1
  42. package/codemini-web/dist/assets/chevron-right-Dbzw7YzA.js +0 -1
  43. package/codemini-web/dist/assets/index-D0EGtNPr.js +0 -65
  44. package/codemini-web/dist/assets/index-wOUf3WkN.css +0 -2
  45. package/codemini-web/dist/assets/input-CNQgbKe6.js +0 -1
  46. package/codemini-web/dist/assets/lib-BOngVP_M.js +0 -11
  47. package/codemini-web/dist/assets/lib-DrOTTm_N.js +0 -1
  48. package/codemini-web/dist/assets/mermaid-GHXKKRXX-DrBu5KyC.js +0 -1
  49. package/codemini-web/dist/assets/select-BZXfigic.js +0 -1
@@ -299,7 +299,7 @@ const TUI_COPY = {
299
299
  answerLabel: '确认输入(yes/no)',
300
300
  answerPlaceholder: 'yes 或 no'
301
301
  },
302
- runApproval: {
302
+ runApproval: {
303
303
  title: '确认执行命令?',
304
304
  commandLabel: '命令',
305
305
  riskLabel: '风险等级',
@@ -312,8 +312,19 @@ const TUI_COPY = {
312
312
  invalidAnswer: '请输入 yes 或 no。',
313
313
  inputLocked: '命令审批进行中,请输入 yes 或 no',
314
314
  answerLabel: '审批输入(yes/no)',
315
- answerPlaceholder: 'yes 或 no'
316
- },
315
+ answerPlaceholder: 'yes 或 no'
316
+ },
317
+ fileApproval: {
318
+ title: '确认文件变更?',
319
+ toolLabel: '工具',
320
+ pathLabel: '路径',
321
+ actionLabel: '操作',
322
+ prompt: '输入 yes 执行,输入 no 取消。',
323
+ invalidAnswer: '请输入 yes 或 no。',
324
+ inputLocked: '文件变更确认中;输入 yes 或 no',
325
+ answerLabel: '确认输入 (yes/no)',
326
+ answerPlaceholder: 'yes 或 no'
327
+ },
317
328
  fileChangeSummary: {
318
329
  title: '文件改动',
319
330
  fileLabel: '文件',
@@ -527,7 +538,7 @@ const TUI_COPY = {
527
538
  answerLabel: 'Approval input (yes/no)',
528
539
  answerPlaceholder: 'yes or no'
529
540
  },
530
- runApproval: {
541
+ runApproval: {
531
542
  title: 'Confirm command execution?',
532
543
  commandLabel: 'Command',
533
544
  riskLabel: 'Risk Level',
@@ -540,8 +551,19 @@ const TUI_COPY = {
540
551
  invalidAnswer: 'Please enter yes or no.',
541
552
  inputLocked: 'Command approval is active; type yes or no',
542
553
  answerLabel: 'Approval input (yes/no)',
543
- answerPlaceholder: 'yes or no'
544
- },
554
+ answerPlaceholder: 'yes or no'
555
+ },
556
+ fileApproval: {
557
+ title: 'Confirm file change?',
558
+ toolLabel: 'Tool',
559
+ pathLabel: 'Path',
560
+ actionLabel: 'Action',
561
+ prompt: 'Type yes to apply, or no to cancel.',
562
+ invalidAnswer: 'Please enter yes or no.',
563
+ inputLocked: 'File change approval is active; type yes or no',
564
+ answerLabel: 'Approval input (yes/no)',
565
+ answerPlaceholder: 'yes or no'
566
+ },
545
567
  fileChangeSummary: {
546
568
  title: 'File Changes',
547
569
  fileLabel: 'File',
@@ -1130,7 +1152,7 @@ export function parseDeleteApprovalAnswer(value) {
1130
1152
  return normalized ? 'invalid' : 'empty';
1131
1153
  }
1132
1154
 
1133
- export function normalizeRunApprovalRequest(request) {
1155
+ export function normalizeRunApprovalRequest(request) {
1134
1156
  if (!request || String(request?.name || '').trim() !== 'run') return null;
1135
1157
  const details =
1136
1158
  request?.approvalDetails && typeof request.approvalDetails === 'object' && !Array.isArray(request.approvalDetails)
@@ -1146,10 +1168,27 @@ export function normalizeRunApprovalRequest(request) {
1146
1168
  description: details.evaluation?.description || '',
1147
1169
  sideEffects: details.evaluation?.sideEffects || '',
1148
1170
  recommendation: details.evaluation?.recommendation || 'deny'
1149
- };
1150
- }
1151
-
1152
- export function parsePlanApprovalAnswer(value) {
1171
+ };
1172
+ }
1173
+
1174
+ export function normalizeFileApprovalRequest(request) {
1175
+ const toolName = String(request?.name || '').trim();
1176
+ if (!['edit', 'write'].includes(toolName)) return null;
1177
+ const args = request?.arguments && typeof request.arguments === 'object' && !Array.isArray(request.arguments)
1178
+ ? request.arguments
1179
+ : {};
1180
+ const edit = args.edit && typeof args.edit === 'object' && !Array.isArray(args.edit) ? args.edit : {};
1181
+ const pathValue = String(args.path || args.file || args.file_path || edit.path || edit.file || edit.file_path || '').trim();
1182
+ if (!pathValue) return null;
1183
+ return {
1184
+ id: String(request?.id || '').trim(),
1185
+ toolName,
1186
+ path: pathValue,
1187
+ action: String(args.kind || args.mode || edit.kind || toolName).trim() || toolName
1188
+ };
1189
+ }
1190
+
1191
+ export function parsePlanApprovalAnswer(value) {
1153
1192
  const raw = String(value || '').trim();
1154
1193
  if (!raw) return { action: 'empty', command: '' };
1155
1194
  const normalized = raw.toLowerCase();
@@ -3182,7 +3221,7 @@ function DeleteApprovalPanel({ request, inputValue, errorText, copy, cursorVisib
3182
3221
  );
3183
3222
  }
3184
3223
 
3185
- function RunApprovalPanel({ request, inputValue, errorText, copy, cursorVisible }) {
3224
+ function RunApprovalPanel({ request, inputValue, errorText, copy, cursorVisible }) {
3186
3225
  if (!request) return null;
3187
3226
  const details = request?.toolName === 'run' ? request : normalizeRunApprovalRequest(request);
3188
3227
  if (!details) return null;
@@ -3219,10 +3258,48 @@ function RunApprovalPanel({ request, inputValue, errorText, copy, cursorVisible
3219
3258
  })
3220
3259
  ),
3221
3260
  errorText ? h(Text, { color: 'yellowBright' }, errorText) : null
3222
- );
3223
- }
3224
-
3225
- function FileChangeSummary({ segments, copy }) {
3261
+ );
3262
+ }
3263
+
3264
+ function FileApprovalPanel({ request, inputValue, errorText, copy, cursorVisible }) {
3265
+ if (!request) return null;
3266
+ const details = request?.toolName === 'edit' || request?.toolName === 'write'
3267
+ ? request
3268
+ : normalizeFileApprovalRequest(request);
3269
+ if (!details) return null;
3270
+ const c = copy.fileApproval || {};
3271
+ const placeholder = String(c.answerPlaceholder || '').trim();
3272
+ return h(
3273
+ Box,
3274
+ {
3275
+ marginTop: 1,
3276
+ flexDirection: 'column',
3277
+ borderStyle: 'round',
3278
+ borderColor: 'yellowBright',
3279
+ paddingX: 1,
3280
+ paddingY: 0
3281
+ },
3282
+ h(Text, { color: 'yellowBright' }, c.title),
3283
+ h(Text, { color: 'white' }, `${c.toolLabel}: ${details.toolName}`),
3284
+ h(Text, { color: 'white' }, `${c.pathLabel}: ${details.path}`),
3285
+ h(Text, { color: 'white' }, `${c.actionLabel}: ${details.action}`),
3286
+ h(Text, { color: 'gray' }, c.prompt),
3287
+ h(
3288
+ Box,
3289
+ { marginTop: 1 },
3290
+ h(Text, { color: 'yellowBright' }, `${c.answerLabel}: `),
3291
+ h(ApprovalCursorLine, {
3292
+ inputValue,
3293
+ placeholder: placeholder || ' ',
3294
+ cursorVisible,
3295
+ accent: 'yellowBright'
3296
+ })
3297
+ ),
3298
+ errorText ? h(Text, { color: 'yellowBright' }, errorText) : null
3299
+ );
3300
+ }
3301
+
3302
+ function FileChangeSummary({ segments, copy }) {
3226
3303
  if (!Array.isArray(segments) || segments.length === 0) return null;
3227
3304
  const c = copy.fileChangeSummary || {};
3228
3305
  const changes = new Map();
@@ -3423,16 +3500,19 @@ export function ChatApp({ runtime, sessionId, model, sdkProvider = 'openai-compa
3423
3500
  const [pendingDeleteApproval, setPendingDeleteApproval] = useState(null);
3424
3501
  const [deleteApprovalInput, setDeleteApprovalInput] = useState('');
3425
3502
  const [deleteApprovalError, setDeleteApprovalError] = useState('');
3426
- const [pendingRunApproval, setPendingRunApproval] = useState(null);
3427
- const [runApprovalInput, setRunApprovalInput] = useState('');
3428
- const [runApprovalError, setRunApprovalError] = useState('');
3503
+ const [pendingRunApproval, setPendingRunApproval] = useState(null);
3504
+ const [runApprovalInput, setRunApprovalInput] = useState('');
3505
+ const [runApprovalError, setRunApprovalError] = useState('');
3506
+ const [pendingFileApproval, setPendingFileApproval] = useState(null);
3507
+ const [fileApprovalInput, setFileApprovalInput] = useState('');
3508
+ const [fileApprovalError, setFileApprovalError] = useState('');
3429
3509
  const [pendingPlanApproval, setPendingPlanApproval] = useState(null);
3430
3510
  const [planApprovalInput, setPlanApprovalInput] = useState('');
3431
3511
  const [planApprovalError, setPlanApprovalError] = useState('');
3432
3512
  const [pendingReflectApproval, setPendingReflectApproval] = useState(null);
3433
3513
  const [reflectApprovalInput, setReflectApprovalInput] = useState('');
3434
3514
  const [reflectApprovalError, setReflectApprovalError] = useState('');
3435
- const approvalLockActive = Boolean(pendingDeleteApproval || pendingRunApproval || pendingPlanApproval || pendingReflectApproval);
3515
+ const approvalLockActive = Boolean(pendingDeleteApproval || pendingRunApproval || pendingFileApproval || pendingPlanApproval || pendingReflectApproval);
3436
3516
  const activeAssistantIdRef = useRef(null);
3437
3517
  const activeAssistantAutoSkillNamesRef = useRef([]);
3438
3518
  const streamedAssistantHandledRef = useRef(false);
@@ -3446,8 +3526,9 @@ export function ChatApp({ runtime, sessionId, model, sdkProvider = 'openai-compa
3446
3526
  const activePlanStepRoleRef = useRef(null);
3447
3527
  const activePlanStepInfoRef = useRef(null);
3448
3528
  const activePlanStepTitleRef = useRef('');
3449
- const deleteApprovalResolverRef = useRef(null);
3450
- const runApprovalResolverRef = useRef(null);
3529
+ const deleteApprovalResolverRef = useRef(null);
3530
+ const runApprovalResolverRef = useRef(null);
3531
+ const fileApprovalResolverRef = useRef(null);
3451
3532
 
3452
3533
  useEffect(() => {
3453
3534
  const rawStartupActivities = runtime.consumeStartupEvents?.();
@@ -3483,22 +3564,32 @@ export function ChatApp({ runtime, sessionId, model, sdkProvider = 'openai-compa
3483
3564
  });
3484
3565
  }
3485
3566
  const runNorm = normalizeRunApprovalRequest(request);
3486
- if (runNorm) {
3487
- setRunApprovalInput('');
3488
- setRunApprovalError('');
3489
- setPendingRunApproval(runNorm);
3490
- return new Promise((resolve) => {
3491
- runApprovalResolverRef.current = resolve;
3492
- });
3493
- }
3494
- return Promise.resolve({ approved: false });
3567
+ if (runNorm) {
3568
+ setRunApprovalInput('');
3569
+ setRunApprovalError('');
3570
+ setPendingRunApproval(runNorm);
3571
+ return new Promise((resolve) => {
3572
+ runApprovalResolverRef.current = resolve;
3573
+ });
3574
+ }
3575
+ const fileNorm = normalizeFileApprovalRequest(request);
3576
+ if (fileNorm) {
3577
+ setFileApprovalInput('');
3578
+ setFileApprovalError('');
3579
+ setPendingFileApproval(fileNorm);
3580
+ return new Promise((resolve) => {
3581
+ fileApprovalResolverRef.current = resolve;
3582
+ });
3583
+ }
3584
+ return Promise.resolve({ approved: false });
3495
3585
  });
3496
3586
  return () => {
3497
3587
  runtime.setRequestToolApproval(null);
3498
- deleteApprovalResolverRef.current = null;
3499
- runApprovalResolverRef.current = null;
3500
- };
3501
- }, [runtime]);
3588
+ deleteApprovalResolverRef.current = null;
3589
+ runApprovalResolverRef.current = null;
3590
+ fileApprovalResolverRef.current = null;
3591
+ };
3592
+ }, [runtime]);
3502
3593
 
3503
3594
  useEffect(() => {
3504
3595
  messagesRef.current = messages;
@@ -4640,7 +4731,7 @@ export function ChatApp({ runtime, sessionId, model, sdkProvider = 'openai-compa
4640
4731
  return;
4641
4732
  }
4642
4733
 
4643
- if (pendingRunApproval) {
4734
+ if (pendingRunApproval) {
4644
4735
  if (key.return) {
4645
4736
  const answer = parseDeleteApprovalAnswer(runApprovalInput);
4646
4737
  if (answer === 'approve' || answer === 'deny') {
@@ -4677,10 +4768,50 @@ export function ChatApp({ runtime, sessionId, model, sdkProvider = 'openai-compa
4677
4768
  return;
4678
4769
  }
4679
4770
 
4680
- return;
4681
- }
4682
-
4683
- if (pendingPlanApproval) {
4771
+ return;
4772
+ }
4773
+
4774
+ if (pendingFileApproval) {
4775
+ if (key.return) {
4776
+ const answer = parseDeleteApprovalAnswer(fileApprovalInput);
4777
+ if (answer === 'approve' || answer === 'deny') {
4778
+ const resolver = fileApprovalResolverRef.current;
4779
+ fileApprovalResolverRef.current = null;
4780
+ setPendingFileApproval(null);
4781
+ setFileApprovalInput('');
4782
+ setFileApprovalError('');
4783
+ if (resolver) resolver({ approved: answer === 'approve' });
4784
+ } else {
4785
+ setFileApprovalError(copy.fileApproval.invalidAnswer);
4786
+ }
4787
+ return;
4788
+ }
4789
+
4790
+ if (isBackspaceKey(value, key) || isDeleteKey(value, key)) {
4791
+ setFileApprovalInput((prev) => prev.slice(0, -1));
4792
+ setFileApprovalError('');
4793
+ return;
4794
+ }
4795
+
4796
+ if (isPrintableInput(value, key)) {
4797
+ setFileApprovalInput((prev) => `${prev}${value}`);
4798
+ setFileApprovalError('');
4799
+ return;
4800
+ }
4801
+
4802
+ if (key.ctrl && value === 'c') {
4803
+ if (busy && typeof runtime.abort === 'function') {
4804
+ runtime.abort();
4805
+ return;
4806
+ }
4807
+ exit();
4808
+ return;
4809
+ }
4810
+
4811
+ return;
4812
+ }
4813
+
4814
+ if (pendingPlanApproval) {
4684
4815
  if (key.return) {
4685
4816
  const parsed = parsePlanApprovalAnswer(planApprovalInput);
4686
4817
  if (parsed.action === 'approve' || parsed.action === 'reject' || parsed.action === 'edit') {
@@ -5080,15 +5211,17 @@ export function ChatApp({ runtime, sessionId, model, sdkProvider = 'openai-compa
5080
5211
  activeUserMessageIdRef.current,
5081
5212
  activeAssistantIdRef.current
5082
5213
  );
5083
- const activeApprovalLock = pendingDeleteApproval
5084
- ? { text: copy.deleteApproval.inputLocked }
5085
- : pendingRunApproval
5086
- ? { text: copy.runApproval.inputLocked }
5087
- : pendingPlanApproval
5088
- ? { text: copy.planApproval.inputLocked }
5089
- : pendingReflectApproval
5090
- ? { text: copy.reflectApproval.inputLocked }
5091
- : null;
5214
+ const activeApprovalLock = pendingDeleteApproval
5215
+ ? { text: copy.deleteApproval.inputLocked }
5216
+ : pendingRunApproval
5217
+ ? { text: copy.runApproval.inputLocked }
5218
+ : pendingFileApproval
5219
+ ? { text: copy.fileApproval.inputLocked }
5220
+ : pendingPlanApproval
5221
+ ? { text: copy.planApproval.inputLocked }
5222
+ : pendingReflectApproval
5223
+ ? { text: copy.reflectApproval.inputLocked }
5224
+ : null;
5092
5225
 
5093
5226
  return h(
5094
5227
  Box,
@@ -5124,13 +5257,20 @@ export function ChatApp({ runtime, sessionId, model, sdkProvider = 'openai-compa
5124
5257
  copy,
5125
5258
  cursorVisible
5126
5259
  }),
5127
- h(RunApprovalPanel, {
5128
- request: pendingRunApproval,
5129
- inputValue: runApprovalInput,
5130
- errorText: runApprovalError,
5131
- copy,
5132
- cursorVisible
5133
- }),
5260
+ h(RunApprovalPanel, {
5261
+ request: pendingRunApproval,
5262
+ inputValue: runApprovalInput,
5263
+ errorText: runApprovalError,
5264
+ copy,
5265
+ cursorVisible
5266
+ }),
5267
+ h(FileApprovalPanel, {
5268
+ request: pendingFileApproval,
5269
+ inputValue: fileApprovalInput,
5270
+ errorText: fileApprovalError,
5271
+ copy,
5272
+ cursorVisible
5273
+ }),
5134
5274
  h(PlanApprovalPanel, {
5135
5275
  request: pendingPlanApproval,
5136
5276
  inputValue: planApprovalInput,
@@ -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-BKL-AZu5.js";import{B as i,L as a,M as o,V as ee,Z as te,at as s,et as ne,h as re,j as ie,lt as c,m as ae,o as oe,p as se,t as l,v as ce,w as le,x as u}from"./index-D0EGtNPr.js";import{MessageBubble as ue,t as de}from"./MessageBubble-wUff4GP4.js";var d=o(`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`}]]),fe=o(`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`}]]),pe=o(`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`}]]),f=e(t(),1),p=n(),m=`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(m));return Number.isFinite(e)?Math.min(me,Math.max(h,e)):g}function _(){return[{value:`fast`,label:s(`generationDepthFast`)},{value:`standard`,label:s(`generationDepthStandard`)},{value:`deep`,label:s(`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||s(`startingAnalysis`),detail:s(`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?s(`generationFailed`):a?.title||t||s(`generatingCodeWiki`),detail:i?i.title:`${r}/${n.length} ${s(`stepsCompleted`)}${a?.role?` · ${a.role.toUpperCase()}`:``}`}}function b({steps:e,stageLabel:t,compact:n=!1}){let r=y(e,t);return(0,p.jsxs)(`div`,{className:c(`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,p.jsxs)(`div`,{className:`flex items-center justify-between gap-3`,children:[(0,p.jsx)(`span`,{className:`truncate text-[12px] font-medium text-(--text-primary)`,children:r.label}),r.total>0&&(0,p.jsxs)(`span`,{className:`shrink-0 text-[11px] text-(--text-muted)`,children:[r.done,`/`,r.total]})]}),(0,p.jsx)(l,{value:r.pct,className:`mt-2 h-1.5`}),(0,p.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 ve(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 w(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 T(e){return(Array.isArray(e)?e:[]).map(e=>e.type===`text`?{...e,isStreaming:!1}:e)}function ye(e,t){switch(t?.type){case`assistant:delta`:return{...e,segments:ve(e.segments,t.text)};case`assistant:response`:return{...e,segments:t.text?w(e.segments,t.text):T(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:T(e.segments)};case`codewiki:error`:return{...e,role:`error`,loading:!1,segments:[{type:`text`,text:t.message||s(`codewikiFailed`),isStreaming:!1}]};default:return e}}function E({projectCwd:e,projectKey:t,busy:n,planSteps:o=[],stageLabel:l=``}){let[y,x]=(0,f.useState)([]),[S,C]=(0,f.useState)(``),[ve,w]=(0,f.useState)(`report`),[T,E]=(0,f.useState)(!0),[be,D]=(0,f.useState)(!1),[xe,O]=(0,f.useState)(``),[Se,k]=(0,f.useState)(null),[A,j]=(0,f.useState)(!1),[M,N]=(0,f.useState)(``),[Ce,P]=(0,f.useState)(!1),[F,I]=(0,f.useState)(``),[we,Te]=(0,f.useState)(``),[L,R]=(0,f.useState)(!1),[z,B]=(0,f.useState)(null),[Ee,V]=(0,f.useState)(!1),[H,U]=(0,f.useState)(`standard`),[W,G]=(0,f.useState)([]),[K,q]=(0,f.useState)(!1),[J,De]=(0,f.useState)(ge),[Oe,Y]=(0,f.useState)(!1),ke=(0,f.useRef)(null),X=(0,f.useRef)({startX:0,startWidth:g}),Z=(0,f.useMemo)(()=>y.find(e=>e.file===S)||null,[y,S]),Ae=Z?`/api/codewiki/report/${encodeURIComponent(Z.file)}${t?`?project=${encodeURIComponent(t)}`:``}`:``,je=(0,f.useCallback)(async()=>{D(!0),O(``);try{let e=await ee(t);k(e),e?.error&&O(e.error)}catch(e){O(e?.message||`Failed to load code graph`)}finally{D(!1)}},[t]),Q=(0,f.useCallback)(async({preferNewest:e=!1}={})=>{E(!0),N(``);try{let n=await i(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||s(`failedToLoad`))}finally{E(!1)}},[t]);(0,f.useEffect)(()=>{x([]),C(``),w(`report`),P(!1),I(``),Te(``),G([]),q(!1),k(null),O(``),Q({preferNewest:!0})},[Q,je,t]),(0,f.useEffect)(()=>{let e=ke.current;e&&requestAnimationFrame(()=>{e.scrollTop=e.scrollHeight})},[W,K]),(0,f.useEffect)(()=>{A&&n&&R(!0)},[n,A]),(0,f.useEffect)(()=>{!A||n||!L||(Q({preferNewest:!0}),j(!1),R(!1))},[n,A,Q,L]),(0,f.useEffect)(()=>{window.localStorage.setItem(m,String(J))},[J]);let Me=(0,f.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||A)){N(``),j(!0),R(!1);try{let e=await te(H,t);e?.error&&(j(!1),N(e.message||s(`failedToStart`)))}catch(e){j(!1),N(e?.message||s(`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 ne({question:n,reportFile:Z?.file||``,project:t,onEvent:e=>{G(t=>t.map(t=>t.id===i?ye(t,e):t))}})}catch(e){G(t=>t.map(t=>t.id===i?{...t,role:`error`,loading:!1,segments:[{type:`text`,text:e?.message||s(`codewikiFailed`),isStreaming:!1}]}:t))}finally{q(!1)}},Fe=async()=>{if(z){V(!0),N(``);try{let e=await a(z.file,t);e?.error?N(e.message||s(`failedToDelete`)):(B(null),P(!1),await Q({preferNewest:!1}))}catch(e){N(e?.message||s(`failedToDelete`))}finally{V(!1)}}},$=n||A,Ie=$||K;return(0,p.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,p.jsxs)(`div`,{className:`codewiki-layout h-full min-h-0`,style:{"--codewiki-qa-width":`${J}px`},children:[(0,p.jsxs)(`aside`,{className:`border-r border-(--border-default) bg-(--bg-secondary) min-h-0 flex flex-col max-lg:hidden`,children:[(0,p.jsxs)(`div`,{className:`p-4 border-b border-(--border-default)`,children:[(0,p.jsxs)(`div`,{className:`flex items-center gap-2 text-(--text-primary)`,children:[(0,p.jsx)(ie,{size:18}),(0,p.jsx)(`span`,{className:`font-semibold text-[15px]`,children:`CodeWiki`})]}),(0,p.jsx)(`p`,{className:`mt-2 text-[12px] leading-5 text-(--text-muted) truncate`,title:e||``,children:e||s(`currentProject`)}),(0,p.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,p.jsx)(`button`,{type:`button`,className:c(`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,p.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:[A?(0,p.jsx)(u,{size:15,className:`animate-spin`}):(0,p.jsx)(ce,{size:15}),s(A?`generating`:`generateNew`)]}),A&&(0,p.jsx)(b,{steps:o,stageLabel:l,compact:!0})]}),(0,p.jsxs)(`div`,{className:`flex items-center justify-between px-4 py-3`,children:[(0,p.jsx)(`span`,{className:`text-[12px] font-medium text-(--text-muted)`,children:`Documents`}),(0,p.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,p.jsx)(r,{size:14})})]}),(0,p.jsxs)(`div`,{className:`flex-1 overflow-y-auto px-2 pb-4`,children:[he,T&&(0,p.jsxs)(`div`,{className:`px-3 py-6 text-[12px] text-(--text-muted) inline-flex items-center gap-2`,children:[(0,p.jsx)(u,{size:14,className:`animate-spin`}),s(`loadingReport`)]}),!T&&y.length===0&&(0,p.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:s(`noReportYet`)}),(0,p.jsx)(`div`,{className:`flex flex-col gap-1`,children:y.map(e=>(0,p.jsxs)(`div`,{className:c(`group w-full rounded-lg px-3 py-2 text-left hover:bg-(--bg-hover) cursor-pointer`,ve===`report`&&S===e.file&&`bg-(--bg-active)`),onClick:()=>{w(`report`),C(e.file),P(!1)},children:[(0,p.jsxs)(`span`,{className:`flex items-start gap-2 text-[13px] text-(--text-primary)`,children:[(0,p.jsx)(de,{size:14,className:`shrink-0 mt-0.5 text-(--text-muted)`}),(0,p.jsx)(`span`,{className:`min-w-0 flex-1 break-words`,children:e.file}),(0,p.jsxs)(se,{children:[(0,p.jsx)(re,{asChild:!0,children:(0,p.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":s(`reportActions`),children:(0,p.jsx)(le,{size:14})})}),(0,p.jsx)(ae,{align:`end`,className:`w-36 border-(--border-default) bg-(--bg-primary) p-1 text-(--text-primary)`,onClick:e=>e.stopPropagation(),children:(0,p.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:s(`deleteReport`)})})]})]}),(0,p.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,p.jsxs)(`main`,{className:`min-w-0 min-h-0 flex flex-col bg-(--bg-primary)`,children:[M&&(0,p.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,p.jsx)(d,{size:14}),M]}),(0,p.jsx)(`div`,{className:`flex-1 min-h-0 p-4`,children:!Z&&!T?(0,p.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,p.jsx)(ie,{size:34,className:`text-(--text-muted)`}),(0,p.jsx)(`h2`,{className:`mt-4 text-[18px] font-semibold text-(--text-primary)`,children:s(`noCodeWiki`)}),(0,p.jsx)(`p`,{className:`mt-2 max-w-md text-[13px] leading-6 text-(--text-muted)`,children:s(`reportWillShow`)}),(0,p.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:[A?(0,p.jsx)(u,{size:16,className:`animate-spin`}):(0,p.jsx)(ce,{size:16}),s(A?`generating`:`generateNew`)]}),(0,p.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,p.jsx)(`button`,{type:`button`,className:c(`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))}),A&&(0,p.jsx)(b,{steps:o,stageLabel:l})]}):(0,p.jsx)(`div`,{className:`h-full min-h-[420px] overflow-hidden rounded-xl border border-(--border-default) bg-(--bg-secondary)`,children:Ce?(0,p.jsxs)(`div`,{className:`h-full flex flex-col items-center justify-center px-8 text-center`,children:[(0,p.jsx)(d,{size:28,className:`text-(--text-muted)`}),(0,p.jsx)(`p`,{className:`mt-3 text-[13px] text-(--text-secondary)`,children:s(`reportLoadFailed`)}),(0,p.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:s(`retry`)})]}):Z?(0,p.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,p.jsxs)(`div`,{className:`h-full flex items-center justify-center text-[13px] text-(--text-muted)`,children:[(0,p.jsx)(u,{size:16,className:`mr-2 animate-spin`}),s(`loading`)]})})})]}),(0,p.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,p.jsx)(`span`,{className:`codewiki-resizer-handle`,children:(0,p.jsx)(fe,{size:14,"aria-hidden":`true`})})}),(0,p.jsxs)(`aside`,{className:`bg-(--bg-secondary) min-h-0 flex flex-col max-xl:hidden`,children:[(0,p.jsx)(`div`,{className:`p-4 border-b border-(--border-default)`,children:(0,p.jsx)(`p`,{className:`mt-2 text-[12px] leading-5 text-(--text-muted)`,children:s(A?`noQuestionsDuringGeneration`:`tempReadOnlyQa`)})}),(0,p.jsx)(`div`,{ref:ke,className:`flex-1 min-h-0 overflow-y-auto px-4 py-3`,children:W.length===0?(0,p.jsxs)(`div`,{className:`rounded-xl border border-(--border-default) bg-(--bg-primary) p-4`,children:[(0,p.jsx)(`p`,{className:`text-[13px] font-medium text-(--text-primary)`,children:s(A?`generatingCodeWiki`:K||n?`processingQuestion`:`canAskAboutProject`)}),(0,p.jsx)(`p`,{className:`mt-2 text-[12px] leading-5 text-(--text-muted)`,children:A?s(`askAfterGeneration`):we||s(`exampleQuestions`)})]}):(0,p.jsx)(`div`,{className:`flex flex-col`,children:W.map(e=>(0,p.jsxs)(`div`,{children:[(0,p.jsx)(ue,{message:e}),e.loading&&(!e.segments||e.segments.length===0)&&(0,p.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,p.jsx)(u,{size:14,className:`animate-spin`}),s(`answering`)]})]},e.id))})}),(0,p.jsx)(`form`,{className:`p-4 border-t border-(--border-default)`,onSubmit:Pe,children:(0,p.jsxs)(`div`,{className:`flex items-center gap-2 rounded-full border border-(--border-default) bg-(--bg-primary) px-3 py-2`,children:[(0,p.jsx)(`input`,{value:F,onChange:e=>I(e.target.value),placeholder:A?s(`generatingCodeWiki`):K||n?s(`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,p.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":s(`sendingQuestion`),children:K?(0,p.jsx)(u,{size:15,className:`animate-spin`}):(0,p.jsx)(pe,{size:15})})]})})]})]}),Oe&&(0,p.jsx)(`div`,{className:`codewiki-resize-overlay`}),(0,p.jsx)(oe,{open:!!z,title:s(`deleteReportConfirm`),description:s(`deleteReportDescription`).replace(`{{report}}`,z?.title||z?.file||``),loading:Ee,onOpenChange:e=>!e&&B(null),onConfirm:Fe})]})}export{E 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-BZXfigic.js";import{$ as c,H as l,M as u,a as d,at as f,c as p,ct as m,d as h,f as g,g as _,l as v,ot as y,s as b,st as x,u as S}from"./index-D0EGtNPr.js";import{t as C}from"./input-CNQgbKe6.js";var w=u(`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`}]]),T=e(t(),1),E=n();function D(e,t){return t.split(`.`).reduce((e,t)=>e?.[t],e)}function O({open:e,onOpenChange:t,status:n=null,onSaved:u}){let O=[{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`,`auto`,`plan`],optionLabels:{normal:f(`normalExecutionMode`),auto:f(`autoMode`),plan:f(`planMode`)}},{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`]}]}],[k,A]=(0,T.useState)(null),[j,M]=(0,T.useState)({}),[N,P]=(0,T.useState)(!1);(0,T.useEffect)(()=>{e&&(P(!0),l().then(e=>{A(e),M({})}).catch(()=>{}).finally(()=>P(!1)))},[e]);let F=(e,t)=>{M(n=>({...n,[e]:t}))},I=e=>{if(e in j)return j[e];let t=k?D(k,e):``;return Array.isArray(t)||t&&typeof t==`object`?JSON.stringify(t):String(t??``)},L=Object.keys(j).length>0;return(0,E.jsx)(b,{open:e,onOpenChange:t,children:(0,E.jsxs)(p,{className:`sm:max-w-[640px] max-h-[80vh] flex flex-col`,children:[(0,E.jsx)(S,{className:`shrink-0`,children:(0,E.jsx)(h,{children:f(`settingsTitle`)})}),(0,E.jsxs)(`div`,{className:`space-y-5 px-2.5 py-1 overflow-y-auto flex-1 min-h-0`,children:[n?.setupRequired&&(0,E.jsxs)(`div`,{className:`rounded-md border border-(--border-default) bg-(--bg-secondary) px-3 py-2 text-[13px] text-(--text-primary)`,children:[(0,E.jsx)(`div`,{className:`font-medium`,children:f(`configRequiredTitle`)}),(0,E.jsx)(`div`,{className:`mt-1 text-(--text-secondary)`,children:f(`configRequiredDesc`)})]}),N?(0,E.jsx)(`div`,{className:`flex items-center justify-center py-12`,children:(0,E.jsx)(d,{})}):O.map((e,t)=>(0,E.jsxs)(`div`,{children:[(0,E.jsx)(`div`,{className:`text-[13px] font-semibold text-(--text-secondary) mb-2.5 uppercase tracking-[0.3px]`,children:e.title}),(0,E.jsx)(`div`,{className:`space-y-2.5`,children:e.keys.map(e=>(0,E.jsxs)(`div`,{className:`flex items-center gap-3`,children:[(0,E.jsxs)(`label`,{className:`text-[13px] text-(--text-muted) w-32 shrink-0`,children:[(0,E.jsx)(`span`,{children:e.label}),e.help&&(0,E.jsxs)(y,{children:[(0,E.jsx)(m,{asChild:!0,children:(0,E.jsx)(`button`,{type:`button`,className:`ml-1 inline-flex align-[-2px] text-(--text-muted) hover:text-(--text-primary)`,"aria-label":e.help,children:(0,E.jsx)(w,{size:13,strokeWidth:1.8})})}),(0,E.jsx)(x,{side:`right`,className:`max-w-[300px] leading-relaxed`,children:e.help})]})]}),e.options?(0,E.jsxs)(s,{value:I(e.path),onValueChange:t=>F(e.path,t),children:[(0,E.jsx)(i,{className:`flex-1 h-8 text-[13px]`,children:(0,E.jsx)(r,{})}),(0,E.jsx)(a,{children:e.options.map(t=>(0,E.jsx)(o,{value:t,children:(0,E.jsxs)(`span`,{className:`inline-flex items-center gap-1.5`,children:[e.optionLogos?.[t]&&(0,E.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,E.jsx)(C,{type:e.type||`text`,value:I(e.path),onChange:t=>F(e.path,t.target.value),placeholder:e.placeholder||``,className:`flex-1 h-8 text-[13px]`})]},e.path))}),t<O.length-1&&(0,E.jsx)(_,{className:`mt-4 bg-(--border-default)`})]},e.title))]}),(0,E.jsxs)(v,{className:`gap-2 shrink-0`,children:[(0,E.jsx)(g,{variant:`outline`,onClick:()=>t(!1),className:`text-[13px]`,children:f(`cancel`)}),(0,E.jsx)(g,{onClick:async()=>{try{for(let[e,t]of Object.entries(j))await c(e,O.flatMap(e=>e.keys).find(t=>t.path===e)?.type===`number`?Number(t):t);await u?.(),M({}),t(!1)}catch(e){console.error(`Config save failed:`,e)}},disabled:!L,className:`text-[13px]`,children:f(`saveChanges`)})]})]})})}export{O as ConfigDialog};