cc-viewer 1.4.8 → 1.4.9

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.
@@ -29,4 +29,13 @@ body{margin:0;background-color:#0d0d0d}*{scrollbar-width:thin;scrollbar-color:#3
29
29
  * The original design remains. The terminal itself
30
30
  * has been extended to include xterm CSI codes, among
31
31
  * other features.
32
- */.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{font-family:monospace;-webkit-user-select:text;user-select:text;white-space:pre}.xterm .xterm-accessibility-tree>div{transform-origin:left;width:fit-content}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{text-decoration:double underline}.xterm-underline-3{text-decoration:wavy underline}.xterm-underline-4{text-decoration:dotted underline}.xterm-underline-5{text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{text-decoration:overline double underline}.xterm-overline.xterm-underline-3{text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}.xterm .xterm-scrollable-element>.scrollbar{cursor:default}.xterm .xterm-scrollable-element>.scrollbar>.scra{cursor:pointer;font-size:11px!important}.xterm .xterm-scrollable-element>.visible{opacity:1;background:#0000;transition:opacity .1s linear;z-index:11}.xterm .xterm-scrollable-element>.invisible{opacity:0;pointer-events:none}.xterm .xterm-scrollable-element>.invisible.fade{transition:opacity .8s linear}.xterm .xterm-scrollable-element>.shadow{position:absolute;display:none}.xterm .xterm-scrollable-element>.shadow.top{display:block;top:0;left:3px;height:3px;width:100%;box-shadow:var(--vscode-scrollbar-shadow, #000) 0 6px 6px -6px inset}.xterm .xterm-scrollable-element>.shadow.left{display:block;top:3px;left:0;height:100%;width:3px;box-shadow:var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset}.xterm .xterm-scrollable-element>.shadow.top-left-corner{display:block;top:0;left:0;height:3px;width:3px}.xterm .xterm-scrollable-element>.shadow.top.left{box-shadow:var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset}._terminalPanel_1slw1_1{height:100%;display:flex;flex-direction:column;background:#0a0a0a}._terminalContainer_1slw1_8{flex:1;overflow:hidden;padding:4px 8px;touch-action:none;overscroll-behavior:contain}._virtualKeybar_1slw1_16{display:flex;gap:6px;padding:8px 10px;background:#111;border-top:1px solid #222;overflow-x:auto;flex-shrink:0;-webkit-overflow-scrolling:touch}._virtualKey_1slw1_16{flex-shrink:0;padding:12px 20px;border:1px solid #333;border-radius:8px;background:#1a1a1a;color:#ccc;font-size:15px;font-family:Menlo,Monaco,monospace;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;touch-action:manipulation;min-width:44px;min-height:44px;display:flex;align-items:center;justify-content:center}._virtualKey_1slw1_16:active{background:#333;border-color:#555;color:#fff}._centerEmpty_1o094_1{display:flex;align-items:center;justify-content:center;height:100%}._container_1o094_8{flex:1;overflow:auto;padding:16px 24px;display:flex;flex-direction:column;-webkit-overflow-scrolling:touch;overscroll-behavior:contain}._sessionDividerText_1o094_18{font-size:11px;color:#555}._lastResponseLabel_1o094_23{font-size:11px}._splitContainer_1o094_27{display:flex;flex-direction:row;height:100%;overflow:hidden}._chatSection_1o094_34{display:flex;flex-direction:column;min-width:0;overflow:hidden}._vResizer_1o094_41{width:5px;background:#1a1a1a;cursor:col-resize;flex-shrink:0;border-left:1px solid #2a2a2a;border-right:1px solid #2a2a2a;transition:background .15s}._vResizer_1o094_41:hover{background:#333}._chatInputBar_1o094_55{display:flex;align-items:flex-end;gap:8px;padding:10px 16px;background:#111;border-top:1px solid #2a2a2a;flex-shrink:0}._chatInputWrapper_1o094_65{flex:1;display:flex;flex-direction:column;background:#1a1a1a;border:1px solid #333;border-radius:12px;transition:border-color .2s;overflow:hidden}._chatInputWrapper_1o094_65:focus-within{border-color:#555}._chatTextareaWrap_1o094_80{position:relative;flex:1}._chatTextarea_1o094_80{width:100%;min-height:22px;max-height:120px;padding:10px 14px;background:transparent;color:#e0e0e0;border:none;outline:none;resize:none;font-size:14px;line-height:1.5;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}._chatTextarea_1o094_80::placeholder{color:#555}._chatInputHint_1o094_104{font-size:11px;color:#444;padding:0 14px 6px;-webkit-user-select:none;user-select:none}._chatSendBtn_1o094_111{width:36px;height:36px;border-radius:10px;border:none;background:#4a9eff;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background .15s,opacity .15s}._chatSendBtn_1o094_111:hover{background:#3a8eef}._chatSendBtn_1o094_111:disabled{opacity:.35;cursor:default}._chatSendBtn_1o094_111 svg{width:18px;height:18px}._messageListWrap_1o094_140{position:relative;flex:1;min-height:0;display:flex;flex-direction:column}._stickyBottomBtn_1o094_148{position:absolute;left:0;bottom:0;display:flex;flex-direction:column;align-items:center;gap:2px;padding:8px 18px;height:60px;justify-content:center;border-radius:0;border:none;background:none;color:#999;font-size:12px;cursor:pointer;transition:color .15s;z-index:10;box-shadow:none}._stickyBottomBtn_1o094_148 span{background:#00000080;padding:2px 10px;border-radius:10px}._stickyBottomBtn_1o094_148:hover{color:#fff;background:none}._ptyPromptBubble_1o094_181{margin:8px 0;padding:12px 16px;border-radius:12px;border:1px solid #3a3a3a;background:#161616;animation:_ptyPromptFadeIn_1o094_1 .25s ease-out}._ptyPromptResolved_1o094_190{opacity:.55}@keyframes _ptyPromptFadeIn_1o094_1{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}._ptyPromptQuestion_1o094_199{font-size:13px;color:#ccc;margin-bottom:10px;line-height:1.4}._ptyPromptOptions_1o094_206{display:flex;flex-wrap:wrap;gap:8px}._ptyPromptOption_1o094_206{padding:6px 14px;border-radius:18px;border:1px solid #3a3a3a;background:#1a1a1a;color:#bbb;font-size:12px;cursor:pointer;transition:background .15s,color .15s,border-color .15s;white-space:nowrap}._ptyPromptOption_1o094_206:hover{background:#2a2a2a;color:#eee;border-color:#555}._ptyPromptOptionPrimary_1o094_230{padding:6px 14px;border-radius:18px;border:1px solid #4a9eff;background:#4a9eff26;color:#4a9eff;font-size:12px;cursor:pointer;transition:background .15s,color .15s,border-color .15s;white-space:nowrap}._ptyPromptOptionPrimary_1o094_230:hover{background:#4a9eff40;color:#6ab4ff;border-color:#6ab4ff}._ptyPromptOptionChosen_1o094_248{padding:6px 14px;border-radius:18px;border:1px solid #4a9eff;background:#4a9eff33;color:#4a9eff;font-size:12px;cursor:default;white-space:nowrap}._ptyPromptOptionDimmed_1o094_259{padding:6px 14px;border-radius:18px;border:1px solid #2a2a2a;background:transparent;color:#444;font-size:12px;cursor:default;white-space:nowrap}._ghostText_1o094_270{position:absolute;top:0;left:0;right:0;padding:10px 14px;color:#444;font-size:14px;line-height:1.5;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;pointer-events:none;white-space:pre-wrap;overflow:hidden;max-height:120px}._suggestionChip_1o094_286{display:flex;align-items:center;gap:8px;padding:8px 14px;background:#1a1a1a;border-top:1px solid #2a2a2a;cursor:pointer;flex-shrink:0;transition:background .15s}._suggestionChip_1o094_286:hover{background:#222}._suggestionChipText_1o094_302{flex:1;color:#555;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._suggestionChipAction_1o094_311{color:#4a9eff;font-size:14px;flex-shrink:0}._resizer_yamj2_1{width:6px;cursor:col-resize;background:#1f1f1f;flex-shrink:0;transition:background .2s}._resizer_yamj2_1:hover{background:#3b82f6}._layout_t1dhs_1{height:100vh;overflow:hidden}._header_t1dhs_6{background:#111;border-bottom:1px solid #1f1f1f;padding:0 24px;height:60px;line-height:60px}._content_t1dhs_14{flex:1;overflow:hidden}._mainContainer_t1dhs_19{display:flex;height:100%}._leftPanel_t1dhs_24{flex-shrink:0;border-right:1px solid #1f1f1f;display:flex;flex-direction:column;background:#0a0a0a}._leftPanelHeader_t1dhs_32{padding:10px 16px;border-bottom:1px solid #1f1f1f;font-size:13px;color:#9ca3af;font-weight:500;display:flex;justify-content:space-between;align-items:center}._leftPanelCount_t1dhs_43{font-size:12px;color:#555;font-weight:400}._leftPanelBody_t1dhs_49{flex:1;overflow:hidden}._rightPanel_t1dhs_54{flex:1;overflow:hidden;background:#0d0d0d}._modalActions_t1dhs_60{margin-bottom:12px}._spinCenter_t1dhs_64{text-align:center;padding:40px}._emptyCenter_t1dhs_69{text-align:center;color:#999;padding:40px}._logCheckbox_t1dhs_75{margin-right:8px}._logListContainer_t1dhs_79{background:#0d0d0d;border-radius:8px;overflow:hidden}._logListItem_t1dhs_85{cursor:pointer;padding:8px 12px;border-bottom:1px solid #222}._logItemRow_t1dhs_91{display:flex;align-items:center;width:100%;justify-content:space-between;flex-wrap:nowrap;gap:12px}._logItemRow_t1dhs_91>span:first-child{display:flex;align-items:center;flex:1;min-width:0;overflow:hidden}._logFileName_t1dhs_108{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._logItemRow_t1dhs_91>span:last-child{display:flex;align-items:center;flex-shrink:0;gap:8px}._logFileIcon_t1dhs_121{margin-right:8px;color:#3b82f6;flex-shrink:0}._loadingOverlay_t1dhs_127{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000000bf;display:flex;align-items:center;justify-content:center;z-index:9999}._loadingText_t1dhs_140{color:#fff;font-size:16px;font-weight:700}._footer_t1dhs_146{height:18px;background:#000;display:flex;align-items:center;justify-content:flex-end;padding:0 12px;flex-shrink:0}._footerRight_t1dhs_156{display:flex;align-items:center;gap:6px;font-size:11px;color:#555}._footerText_t1dhs_164{color:#444;margin-right:2px}._footerLink_t1dhs_169{display:inline-flex;align-items:center;gap:3px;color:#555;text-decoration:none}._footerLink_t1dhs_169:hover{color:#888}._footerIcon_t1dhs_181{width:12px;height:12px}._footerDivider_t1dhs_186{color:#333}._footerText_t1dhs_164{color:#555}._guideContainer_t1dhs_194{display:flex;align-items:center;justify-content:center;height:100%;background:#0a0a0a}._guideContent_t1dhs_202{max-width:560px;padding:40px}._guideTitle_t1dhs_207{font-size:20px;font-weight:600;color:#e0e0e0;margin:0 0 28px}._guideStep_t1dhs_214{display:flex;gap:14px;margin-bottom:22px}._guideStepNum_t1dhs_220{flex-shrink:0;width:24px;height:24px;border-radius:50%;background:#1a1a2e;color:#7c8aff;font-size:13px;font-weight:600;display:flex;align-items:center;justify-content:center;margin-top:1px}._guideStepBody_t1dhs_235{flex:1;min-width:0}._guideText_t1dhs_240{color:#aaa;font-size:14px;line-height:1.6;margin:0 0 8px}._guideCode_t1dhs_247{display:block;background:#141414;border:1px solid #252525;border-radius:6px;padding:10px 14px;color:#8b9cf7;font-size:13px;line-height:1.5;word-break:break-all;white-space:pre-wrap}._mobileChatOverlay_t1dhs_260{position:absolute;top:0;right:0;bottom:0;left:0;transform:translate(100%);transition:transform .3s ease;z-index:100;background:#0a0a0a;display:flex;flex-direction:column;overflow:hidden}._mobileChatOverlayVisible_t1dhs_272{transform:translate(0)}._mobileChatInner_t1dhs_276{flex:1;min-height:0;display:flex;flex-direction:column;zoom:.6}
32
+ */.xterm{cursor:text;position:relative;user-select:none;-ms-user-select:none;-webkit-user-select:none}.xterm.focus,.xterm:focus{outline:none}.xterm .xterm-helpers{position:absolute;top:0;z-index:5}.xterm .xterm-helper-textarea{padding:0;border:0;margin:0;position:absolute;opacity:0;left:-9999em;top:0;width:0;height:0;z-index:-5;white-space:nowrap;overflow:hidden;resize:none}.xterm .composition-view{background:#000;color:#fff;display:none;position:absolute;white-space:nowrap;z-index:1}.xterm .composition-view.active{display:block}.xterm .xterm-viewport{background-color:#000;overflow-y:scroll;cursor:default;position:absolute;right:0;left:0;top:0;bottom:0}.xterm .xterm-screen{position:relative}.xterm .xterm-screen canvas{position:absolute;left:0;top:0}.xterm-char-measure-element{display:inline-block;visibility:hidden;position:absolute;top:0;left:-9999em;line-height:normal}.xterm.enable-mouse-events{cursor:default}.xterm.xterm-cursor-pointer,.xterm .xterm-cursor-pointer{cursor:pointer}.xterm.column-select.focus{cursor:crosshair}.xterm .xterm-accessibility:not(.debug),.xterm .xterm-message{position:absolute;left:0;top:0;bottom:0;right:0;z-index:10;color:transparent;pointer-events:none}.xterm .xterm-accessibility-tree:not(.debug) *::selection{color:transparent}.xterm .xterm-accessibility-tree{font-family:monospace;-webkit-user-select:text;user-select:text;white-space:pre}.xterm .xterm-accessibility-tree>div{transform-origin:left;width:fit-content}.xterm .live-region{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}.xterm-dim{opacity:1!important}.xterm-underline-1{text-decoration:underline}.xterm-underline-2{text-decoration:double underline}.xterm-underline-3{text-decoration:wavy underline}.xterm-underline-4{text-decoration:dotted underline}.xterm-underline-5{text-decoration:dashed underline}.xterm-overline{text-decoration:overline}.xterm-overline.xterm-underline-1{text-decoration:overline underline}.xterm-overline.xterm-underline-2{text-decoration:overline double underline}.xterm-overline.xterm-underline-3{text-decoration:overline wavy underline}.xterm-overline.xterm-underline-4{text-decoration:overline dotted underline}.xterm-overline.xterm-underline-5{text-decoration:overline dashed underline}.xterm-strikethrough{text-decoration:line-through}.xterm-screen .xterm-decoration-container .xterm-decoration{z-index:6;position:absolute}.xterm-screen .xterm-decoration-container .xterm-decoration.xterm-decoration-top-layer{z-index:7}.xterm-decoration-overview-ruler{z-index:8;position:absolute;top:0;right:0;pointer-events:none}.xterm-decoration-top{z-index:2;position:relative}.xterm .xterm-scrollable-element>.scrollbar{cursor:default}.xterm .xterm-scrollable-element>.scrollbar>.scra{cursor:pointer;font-size:11px!important}.xterm .xterm-scrollable-element>.visible{opacity:1;background:#0000;transition:opacity .1s linear;z-index:11}.xterm .xterm-scrollable-element>.invisible{opacity:0;pointer-events:none}.xterm .xterm-scrollable-element>.invisible.fade{transition:opacity .8s linear}.xterm .xterm-scrollable-element>.shadow{position:absolute;display:none}.xterm .xterm-scrollable-element>.shadow.top{display:block;top:0;left:3px;height:3px;width:100%;box-shadow:var(--vscode-scrollbar-shadow, #000) 0 6px 6px -6px inset}.xterm .xterm-scrollable-element>.shadow.left{display:block;top:3px;left:0;height:100%;width:3px;box-shadow:var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset}.xterm .xterm-scrollable-element>.shadow.top-left-corner{display:block;top:0;left:0;height:3px;width:3px}.xterm .xterm-scrollable-element>.shadow.top.left{box-shadow:var(--vscode-scrollbar-shadow, #000) 6px 0 6px -6px inset}._terminalPanel_1slw1_1{height:100%;display:flex;flex-direction:column;background:#0a0a0a}._terminalContainer_1slw1_8{flex:1;overflow:hidden;padding:4px 8px;touch-action:none;overscroll-behavior:contain}._virtualKeybar_1slw1_16{display:flex;gap:6px;padding:8px 10px;background:#111;border-top:1px solid #222;overflow-x:auto;flex-shrink:0;-webkit-overflow-scrolling:touch}._virtualKey_1slw1_16{flex-shrink:0;padding:12px 20px;border:1px solid #333;border-radius:8px;background:#1a1a1a;color:#ccc;font-size:15px;font-family:Menlo,Monaco,monospace;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;touch-action:manipulation;min-width:44px;min-height:44px;display:flex;align-items:center;justify-content:center}._virtualKey_1slw1_16:active{background:#333;border-color:#555;color:#fff}._fileExplorer_1ae99_1{width:240px;flex-shrink:0;background:#111;border-right:1px solid #2a2a2a;display:flex;flex-direction:column;overflow:hidden;-webkit-user-select:none;user-select:none}._header_1ae99_12{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid #2a2a2a;flex-shrink:0}._headerTitle_1ae99_21{font-size:11px;font-weight:600;color:#888;text-transform:uppercase;letter-spacing:.5px}._collapseBtn_1ae99_29{width:20px;height:20px;border:none;background:none;color:#666;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:4px;padding:0}._collapseBtn_1ae99_29:hover{color:#ccc;background:#2a2a2a}._treeContainer_1ae99_48{flex:1;overflow:auto;padding:4px 0}._treeItem_1ae99_54{display:flex;align-items:center;height:26px;padding:0 8px;cursor:pointer;color:#ccc;font-size:13px;white-space:nowrap;transition:background .1s}._treeItem_1ae99_54:hover{background:#1a1a1a}._arrow_1ae99_70{width:16px;flex-shrink:0;font-size:10px;color:#666;text-align:center}._icon_1ae99_78{width:16px;height:16px;flex-shrink:0;margin-right:6px;display:flex;align-items:center;justify-content:center}._fileName_1ae99_88{overflow:hidden;text-overflow:ellipsis}._loading_1ae99_93{color:#555;font-size:12px;padding:4px 8px}._error_1ae99_99{color:#ff6b6b;font-size:12px;padding:4px 8px}pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
33
+ Theme: GitHub Dark
34
+ Description: Dark theme as seen on github.com
35
+ Author: github.com
36
+ Maintainer: @Hirse
37
+ Updated: 2021-05-15
38
+
39
+ Outdated base version: https://github.com/primer/github-syntax-dark
40
+ Current colors taken from GitHub's CSS
41
+ */.hljs{color:#c9d1d9;background:#0d1117}.hljs-doctag,.hljs-keyword,.hljs-meta .hljs-keyword,.hljs-template-tag,.hljs-template-variable,.hljs-type,.hljs-variable.language_{color:#ff7b72}.hljs-title,.hljs-title.class_,.hljs-title.class_.inherited__,.hljs-title.function_{color:#d2a8ff}.hljs-attr,.hljs-attribute,.hljs-literal,.hljs-meta,.hljs-number,.hljs-operator,.hljs-variable,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-id{color:#79c0ff}.hljs-regexp,.hljs-string,.hljs-meta .hljs-string{color:#a5d6ff}.hljs-built_in,.hljs-symbol{color:#ffa657}.hljs-comment,.hljs-code,.hljs-formula{color:#8b949e}.hljs-name,.hljs-quote,.hljs-selector-tag,.hljs-selector-pseudo{color:#7ee787}.hljs-subst{color:#c9d1d9}.hljs-section{color:#1f6feb;font-weight:700}.hljs-bullet{color:#f2cc60}.hljs-emphasis{color:#c9d1d9;font-style:italic}.hljs-strong{color:#c9d1d9;font-weight:700}.hljs-addition{color:#aff5b4;background-color:#033a16}.hljs-deletion{color:#ffdcd7;background-color:#67060c}._fileContentView_1sb22_1{display:flex;flex-direction:column;height:100%;background:#0d0d0d}._header_1sb22_8{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;border-bottom:1px solid #2a2a2a;background:#111;flex-shrink:0}._headerLeft_1sb22_18{display:flex;align-items:center;gap:8px;flex:1;min-width:0}._backBtn_1sb22_26{width:28px;height:28px;border:none;background:none;color:#666;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:6px;padding:0;flex-shrink:0;transition:background .15s,color .15s}._backBtn_1sb22_26:hover{color:#ccc;background:#1a1a1a}._filePath_1sb22_47{font-size:13px;color:#ccc;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._fileSize_1sb22_55{font-size:11px;color:#666;flex-shrink:0}._contentContainer_1sb22_61{flex:1;overflow:auto;background:#0d0d0d}._codeBlock_1sb22_67{min-height:100%}._codeContent_1sb22_71{padding:0;font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace;font-size:13px;line-height:1.5;color:#e0e0e0;overflow-x:auto;-moz-tab-size:2;tab-size:2;margin:0}._codeContent_1sb22_71 code{font-family:inherit;font-size:inherit;line-height:inherit;background:none;padding:0;display:block}._codeLine_1sb22_91{display:flex;min-height:1.5em}._codeLine_1sb22_91:hover{background:#ffffff08}._lineNumber_1sb22_100{flex-shrink:0;width:50px;padding:0 16px;text-align:right;color:#555;-webkit-user-select:none;user-select:none;border-right:1px solid #2a2a2a}._lineContent_1sb22_110{flex:1;padding:0 16px;white-space:pre;overflow-x:visible}._loading_1sb22_117{display:flex;align-items:center;justify-content:center;height:100%;color:#666;font-size:14px}._error_1sb22_126{display:flex;align-items:center;justify-content:center;height:100%;color:#ff6b6b;font-size:14px}._gitChanges_1fy65_1{width:240px;flex-shrink:0;background:#111;border-right:1px solid #2a2a2a;display:flex;flex-direction:column;overflow:hidden;-webkit-user-select:none;user-select:none}._header_1fy65_12{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid #2a2a2a;flex-shrink:0}._headerTitle_1fy65_21{font-size:11px;font-weight:600;color:#888;text-transform:uppercase;letter-spacing:.5px}._collapseBtn_1fy65_29{width:20px;height:20px;border:none;background:none;color:#666;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:4px;padding:0}._collapseBtn_1fy65_29:hover{color:#ccc;background:#2a2a2a}._changesContainer_1fy65_48{flex:1;overflow:auto;padding:4px 0}._changeItem_1fy65_54{display:flex;align-items:center;height:28px;padding:0 12px;cursor:pointer;color:#ccc;font-size:13px;white-space:nowrap;transition:background .1s;gap:8px}._changeItem_1fy65_54:hover{background:#1a1a1a}._status_1fy65_71{width:16px;flex-shrink:0;font-size:11px;font-weight:600;text-align:center}._icon_1fy65_79{width:16px;height:16px;flex-shrink:0;display:flex;align-items:center;justify-content:center}._fileName_1fy65_88{overflow:hidden;text-overflow:ellipsis;flex:1}._loading_1fy65_94{color:#555;font-size:12px;padding:8px 12px}._error_1fy65_100{color:#ff6b6b;font-size:12px;padding:8px 12px}._empty_1fy65_106{color:#666;font-size:12px;padding:8px 12px;text-align:center}._fullFileDiffView_e9dmx_1{width:100%;height:100%;display:flex;flex-direction:column;background:#0d0d0d;overflow:hidden}._diffSummary_e9dmx_10{padding:8px 16px;background:#111;border-bottom:1px solid #2a2a2a;display:flex;gap:8px;align-items:center;flex-shrink:0}._addedBadge_e9dmx_20{padding:2px 8px;background:#73c99126;border:1px solid rgba(115,201,145,.3);border-radius:4px;font-size:11px;font-weight:600;color:#73c991;font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace}._modifiedBadge_e9dmx_31{padding:2px 8px;background:#e2c08d26;border:1px solid rgba(226,192,141,.3);border-radius:4px;font-size:11px;font-weight:600;color:#e2c08d;font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace}._deletedBadge_e9dmx_42{padding:2px 8px;background:#f14c4c26;border:1px solid rgba(241,76,76,.3);border-radius:4px;font-size:11px;font-weight:600;color:#f14c4c;font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace}._codeContainer_e9dmx_53{flex:1;overflow:auto;font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace;font-size:13px;line-height:1.6}._codeLine_e9dmx_61{display:flex;position:relative;min-height:21px;transition:background .1s}._codeLine_e9dmx_61:hover{background:#ffffff08}._lineNumber_e9dmx_72{width:50px;flex-shrink:0;padding:0 12px 0 8px;text-align:right;color:#555;-webkit-user-select:none;user-select:none;font-size:12px}._lineContent_e9dmx_82{flex:1;padding-right:16px;color:#ccc;white-space:pre;overflow-x:auto}._lineNormal_e9dmx_90{background:transparent}._lineAdd_e9dmx_94{background:#73c9911a;border-left:3px solid #73c991}._lineAdd_e9dmx_94 ._lineNumber_e9dmx_72{color:#73c991;font-weight:600}._lineModify_e9dmx_104{background:#e2c08d1a;border-left:3px solid #e2c08d;position:relative}._lineModify_e9dmx_104 ._lineNumber_e9dmx_72{color:#e2c08d;font-weight:600}._lineDelete_e9dmx_115{background:#f14c4c1a;border-left:3px solid #f14c4c}._lineDelete_e9dmx_115 ._lineNumber_e9dmx_72{color:#f14c4c;font-weight:600}._lineDelete_e9dmx_115 ._lineContent_e9dmx_82{text-decoration:line-through;opacity:.8}._lineModify_e9dmx_104:hover ._oldContentTooltip_e9dmx_130{display:block}._oldContentTooltip_e9dmx_130{display:none;position:absolute;left:60px;top:100%;z-index:1000;background:#1a1a1a;border:1px solid #444;border-radius:4px;padding:8px 12px;max-width:600px;box-shadow:0 4px 12px #00000080;margin-top:4px}._tooltipLabel_e9dmx_149{font-size:10px;color:#888;margin-bottom:4px;text-transform:uppercase;letter-spacing:.5px}._tooltipContent_e9dmx_157{font-size:12px;color:#f14c4c;white-space:pre;font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace;text-decoration:line-through;opacity:.8}._gitDiffView_14i1p_1{flex:1;display:flex;flex-direction:column;background:#0d0d0d;overflow:hidden}._header_14i1p_9{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid #2a2a2a;background:#111;flex-shrink:0}._headerLeft_14i1p_19{display:flex;align-items:center;gap:12px;flex:1;min-width:0}._backBtn_14i1p_27{width:28px;height:28px;border:none;background:none;color:#888;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:4px;padding:0;flex-shrink:0;transition:all .15s}._backBtn_14i1p_27:hover{color:#ccc;background:#2a2a2a}._filePath_14i1p_48{font-size:13px;color:#ccc;font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._diffBadge_14i1p_57{padding:2px 8px;background:#2a2a2a;border:1px solid #444;border-radius:4px;font-size:10px;font-weight:600;color:#e2c08d;letter-spacing:.5px;flex-shrink:0}._contentContainer_14i1p_69{flex:1;overflow:auto;position:relative}._loading_14i1p_75{display:flex;align-items:center;justify-content:center;height:100%;color:#888;font-size:13px}._error_14i1p_84{display:flex;align-items:center;justify-content:center;height:100%;color:#ff6b6b;font-size:13px;padding:20px;text-align:center}._binaryNotice_14i1p_95{display:flex;align-items:center;justify-content:center;height:100%;color:#888;font-size:13px;font-style:italic;padding:20px;text-align:center}._largeFileWarning_14i1p_107{display:flex;flex-direction:column;align-items:center;justify-content:center;height:100%;color:#e2c08d;font-size:13px;padding:20px;text-align:center;gap:8px}._fileSize_14i1p_120{color:#888;font-size:12px;margin:0}._centerEmpty_1jjqw_1{display:flex;align-items:center;justify-content:center;height:100%}._container_1jjqw_8{flex:1;overflow:auto;padding:16px 24px;display:flex;flex-direction:column;-webkit-overflow-scrolling:touch;overscroll-behavior:contain}._sessionDividerText_1jjqw_18{font-size:11px;color:#555}._lastResponseLabel_1jjqw_23{font-size:11px}._splitContainer_1jjqw_27{display:flex;flex-direction:row;height:100%;overflow:hidden}._chatSection_1jjqw_34{display:flex;flex-direction:column;min-width:0;overflow:hidden}._vResizer_1jjqw_41{width:5px;background:#1a1a1a;cursor:col-resize;flex-shrink:0;border-left:1px solid #2a2a2a;border-right:1px solid #2a2a2a;transition:background .15s}._vResizer_1jjqw_41:hover{background:#333}._chatInputBar_1jjqw_55{display:flex;align-items:flex-end;gap:8px;padding:10px 16px;background:#111;border-top:1px solid #2a2a2a;flex-shrink:0}._chatInputWrapper_1jjqw_65{flex:1;display:flex;flex-direction:column;background:#1a1a1a;border:1px solid #333;border-radius:12px;transition:border-color .2s;overflow:hidden}._chatInputWrapper_1jjqw_65:focus-within{border-color:#555}._chatTextareaWrap_1jjqw_80{position:relative;flex:1}._chatTextarea_1jjqw_80{width:100%;min-height:22px;max-height:120px;padding:10px 14px;background:transparent;color:#e0e0e0;border:none;outline:none;resize:none;font-size:14px;line-height:1.5;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif}._chatTextarea_1jjqw_80::placeholder{color:#555}._chatInputHint_1jjqw_104{font-size:11px;color:#444;padding:0 14px 6px;-webkit-user-select:none;user-select:none}._chatSendBtn_1jjqw_111{width:36px;height:36px;border-radius:10px;border:none;background:#4a9eff;color:#fff;cursor:pointer;display:flex;align-items:center;justify-content:center;flex-shrink:0;transition:background .15s,opacity .15s}._chatSendBtn_1jjqw_111:hover{background:#3a8eef}._chatSendBtn_1jjqw_111:disabled{opacity:.35;cursor:default}._chatSendBtn_1jjqw_111 svg{width:18px;height:18px}._messageListWrap_1jjqw_140{position:relative;flex:1;min-height:0;display:flex;flex-direction:column}._stickyBottomBtn_1jjqw_148{position:absolute;left:0;bottom:0;display:flex;flex-direction:column;align-items:center;gap:2px;padding:8px 18px;height:60px;justify-content:center;border-radius:0;border:none;background:none;color:#999;font-size:12px;cursor:pointer;transition:color .15s;z-index:10;box-shadow:none}._stickyBottomBtn_1jjqw_148 span{background:#00000080;padding:2px 10px;border-radius:10px}._stickyBottomBtn_1jjqw_148:hover{color:#fff;background:none}._ptyPromptBubble_1jjqw_181{margin:8px 0;padding:12px 16px;border-radius:12px;border:1px solid #3a3a3a;background:#161616;animation:_ptyPromptFadeIn_1jjqw_1 .25s ease-out}._ptyPromptResolved_1jjqw_190{opacity:.55}@keyframes _ptyPromptFadeIn_1jjqw_1{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}._ptyPromptQuestion_1jjqw_199{font-size:13px;color:#ccc;margin-bottom:10px;line-height:1.4}._ptyPromptOptions_1jjqw_206{display:flex;flex-wrap:wrap;gap:8px}._ptyPromptOption_1jjqw_206{padding:6px 14px;border-radius:18px;border:1px solid #3a3a3a;background:#1a1a1a;color:#bbb;font-size:12px;cursor:pointer;transition:background .15s,color .15s,border-color .15s;white-space:nowrap}._ptyPromptOption_1jjqw_206:hover{background:#2a2a2a;color:#eee;border-color:#555}._ptyPromptOptionPrimary_1jjqw_230{padding:6px 14px;border-radius:18px;border:1px solid #4a9eff;background:#4a9eff26;color:#4a9eff;font-size:12px;cursor:pointer;transition:background .15s,color .15s,border-color .15s;white-space:nowrap}._ptyPromptOptionPrimary_1jjqw_230:hover{background:#4a9eff40;color:#6ab4ff;border-color:#6ab4ff}._ptyPromptOptionChosen_1jjqw_248{padding:6px 14px;border-radius:18px;border:1px solid #4a9eff;background:#4a9eff33;color:#4a9eff;font-size:12px;cursor:default;white-space:nowrap}._ptyPromptOptionDimmed_1jjqw_259{padding:6px 14px;border-radius:18px;border:1px solid #2a2a2a;background:transparent;color:#444;font-size:12px;cursor:default;white-space:nowrap}._ghostText_1jjqw_270{position:absolute;top:0;left:0;right:0;padding:10px 14px;color:#444;font-size:14px;line-height:1.5;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;pointer-events:none;white-space:pre-wrap;overflow:hidden;max-height:120px}._suggestionChip_1jjqw_286{display:flex;align-items:center;gap:8px;padding:8px 14px;background:#1a1a1a;border-top:1px solid #2a2a2a;cursor:pointer;flex-shrink:0;transition:background .15s}._suggestionChip_1jjqw_286:hover{background:#222}._suggestionChipText_1jjqw_302{flex:1;color:#555;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._suggestionChipAction_1jjqw_311{color:#4a9eff;font-size:14px;flex-shrink:0}._navSidebar_1jjqw_317{width:40px;flex-shrink:0;background:#0d0d0d;border-right:1px solid #2a2a2a;display:flex;flex-direction:column;align-items:center;padding-top:8px;gap:4px}._navBtn_1jjqw_329{width:32px;height:32px;border:none;background:none;color:#666;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:6px;padding:0;transition:background .15s,color .15s}._navBtn_1jjqw_329:hover{color:#ccc;background:#1a1a1a}._navBtnActive_1jjqw_349{width:32px;height:32px;border:none;background:#4a9eff26;color:#4a9eff;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:6px;padding:0;transition:background .15s,color .15s}._navBtnActive_1jjqw_349:hover{background:#4a9eff40;color:#6ab4ff}._resizer_yamj2_1{width:6px;cursor:col-resize;background:#1f1f1f;flex-shrink:0;transition:background .2s}._resizer_yamj2_1:hover{background:#3b82f6}._layout_t1dhs_1{height:100vh;overflow:hidden}._header_t1dhs_6{background:#111;border-bottom:1px solid #1f1f1f;padding:0 24px;height:60px;line-height:60px}._content_t1dhs_14{flex:1;overflow:hidden}._mainContainer_t1dhs_19{display:flex;height:100%}._leftPanel_t1dhs_24{flex-shrink:0;border-right:1px solid #1f1f1f;display:flex;flex-direction:column;background:#0a0a0a}._leftPanelHeader_t1dhs_32{padding:10px 16px;border-bottom:1px solid #1f1f1f;font-size:13px;color:#9ca3af;font-weight:500;display:flex;justify-content:space-between;align-items:center}._leftPanelCount_t1dhs_43{font-size:12px;color:#555;font-weight:400}._leftPanelBody_t1dhs_49{flex:1;overflow:hidden}._rightPanel_t1dhs_54{flex:1;overflow:hidden;background:#0d0d0d}._modalActions_t1dhs_60{margin-bottom:12px}._spinCenter_t1dhs_64{text-align:center;padding:40px}._emptyCenter_t1dhs_69{text-align:center;color:#999;padding:40px}._logCheckbox_t1dhs_75{margin-right:8px}._logListContainer_t1dhs_79{background:#0d0d0d;border-radius:8px;overflow:hidden}._logListItem_t1dhs_85{cursor:pointer;padding:8px 12px;border-bottom:1px solid #222}._logItemRow_t1dhs_91{display:flex;align-items:center;width:100%;justify-content:space-between;flex-wrap:nowrap;gap:12px}._logItemRow_t1dhs_91>span:first-child{display:flex;align-items:center;flex:1;min-width:0;overflow:hidden}._logFileName_t1dhs_108{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._logItemRow_t1dhs_91>span:last-child{display:flex;align-items:center;flex-shrink:0;gap:8px}._logFileIcon_t1dhs_121{margin-right:8px;color:#3b82f6;flex-shrink:0}._loadingOverlay_t1dhs_127{position:fixed;top:0;left:0;width:100vw;height:100vh;background:#000000bf;display:flex;align-items:center;justify-content:center;z-index:9999}._loadingText_t1dhs_140{color:#fff;font-size:16px;font-weight:700}._footer_t1dhs_146{height:18px;background:#000;display:flex;align-items:center;justify-content:flex-end;padding:0 12px;flex-shrink:0}._footerRight_t1dhs_156{display:flex;align-items:center;gap:6px;font-size:11px;color:#555}._footerText_t1dhs_164{color:#444;margin-right:2px}._footerLink_t1dhs_169{display:inline-flex;align-items:center;gap:3px;color:#555;text-decoration:none}._footerLink_t1dhs_169:hover{color:#888}._footerIcon_t1dhs_181{width:12px;height:12px}._footerDivider_t1dhs_186{color:#333}._footerText_t1dhs_164{color:#555}._guideContainer_t1dhs_194{display:flex;align-items:center;justify-content:center;height:100%;background:#0a0a0a}._guideContent_t1dhs_202{max-width:560px;padding:40px}._guideTitle_t1dhs_207{font-size:20px;font-weight:600;color:#e0e0e0;margin:0 0 28px}._guideStep_t1dhs_214{display:flex;gap:14px;margin-bottom:22px}._guideStepNum_t1dhs_220{flex-shrink:0;width:24px;height:24px;border-radius:50%;background:#1a1a2e;color:#7c8aff;font-size:13px;font-weight:600;display:flex;align-items:center;justify-content:center;margin-top:1px}._guideStepBody_t1dhs_235{flex:1;min-width:0}._guideText_t1dhs_240{color:#aaa;font-size:14px;line-height:1.6;margin:0 0 8px}._guideCode_t1dhs_247{display:block;background:#141414;border:1px solid #252525;border-radius:6px;padding:10px 14px;color:#8b9cf7;font-size:13px;line-height:1.5;word-break:break-all;white-space:pre-wrap}._mobileChatOverlay_t1dhs_260{position:absolute;top:0;right:0;bottom:0;left:0;transform:translate(100%);transition:transform .3s ease;z-index:100;background:#0a0a0a;display:flex;flex-direction:column;overflow:hidden}._mobileChatOverlayVisible_t1dhs_272{transform:translate(0)}._mobileChatInner_t1dhs_276{flex:1;min-height:0;display:flex;flex-direction:column;zoom:.6}
package/dist/index.html CHANGED
@@ -6,8 +6,8 @@
6
6
  <title>Claude Code Viewer</title>
7
7
  <link rel="icon" href="/favicon.ico?v=1">
8
8
  <link rel="shortcut icon" href="/favicon.ico?v=1">
9
- <script type="module" crossorigin src="/assets/index-CxuBY4Hs.js"></script>
10
- <link rel="stylesheet" crossorigin href="/assets/index-C9NseQNI.css">
9
+ <script type="module" crossorigin src="/assets/index-BtUV1IH_.js"></script>
10
+ <link rel="stylesheet" crossorigin href="/assets/index-Cplbs2JB.css">
11
11
  </head>
12
12
  <body>
13
13
  <div id="root"></div>
package/interceptor.js CHANGED
@@ -143,7 +143,7 @@ const _initPromise = (async () => {
143
143
 
144
144
  export { LOG_FILE, _initPromise, _resumeState, _choicePromise, resolveResumeChoice, _projectName, _logDir };
145
145
 
146
- const MAX_LOG_SIZE = 500 * 1024 * 1024; // 500MB
146
+ const MAX_LOG_SIZE = 300 * 1024 * 1024; // 300MB
147
147
 
148
148
  function isPreflightEntry(entry) {
149
149
  if (entry.mainAgent || entry.isHeartbeat || entry.isCountTokens) return false;
@@ -484,7 +484,7 @@ export function setupInterceptor() {
484
484
  }
485
485
  } catch { }
486
486
 
487
- // 用户新指令边界:检查日志文件大小,超过 500MB 则切换新文件
487
+ // 用户新指令边界:检查日志文件大小,超过 300MB 则切换新文件
488
488
  if (requestEntry?.mainAgent) {
489
489
  checkAndRotateLogFile();
490
490
  // 仅 mainAgent 请求时缓存模型名,避免 SubAgent 覆盖
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-viewer",
3
- "version": "1.4.8",
3
+ "version": "1.4.9",
4
4
  "description": "Claude Code Logger visualization management tool",
5
5
  "license": "MIT",
6
6
  "main": "server.js",
@@ -62,6 +62,7 @@
62
62
  "@xterm/xterm": "^6.0.0",
63
63
  "antd": "^5.29.2",
64
64
  "diff": "^8.0.3",
65
+ "highlight.js": "^11.11.1",
65
66
  "marked": "^17.0.2",
66
67
  "qrcode.react": "^4.2.0",
67
68
  "react": "^18.3.1",
package/server.js CHANGED
@@ -523,6 +523,74 @@ function handleRequest(req, res) {
523
523
  return;
524
524
  }
525
525
 
526
+ // 文件浏览器 API(CLI 模式下项目目录浏览)
527
+ if (url === '/api/files' && method === 'GET') {
528
+ const reqPath = parsedUrl.searchParams.get('path') || '.';
529
+ // 安全校验:拒绝绝对路径和 .. 路径穿越
530
+ if (reqPath.startsWith('/') || reqPath.includes('..')) {
531
+ res.writeHead(400, { 'Content-Type': 'application/json' });
532
+ res.end(JSON.stringify({ error: 'Invalid path' }));
533
+ return;
534
+ }
535
+ const cwd = process.env.CCV_PROJECT_DIR || process.cwd();
536
+ const targetDir = join(cwd, reqPath);
537
+ try {
538
+ const entries = readdirSync(targetDir, { withFileTypes: true });
539
+ const HIDDEN = new Set(['node_modules', '.git', '.svn', '.hg', '.DS_Store', '__pycache__', '.next', '.nuxt', 'dist', '.cache', '.idea', '.vscode']);
540
+ const items = entries
541
+ .filter(e => !e.name.startsWith('.') && !HIDDEN.has(e.name))
542
+ .map(e => ({ name: e.name, type: e.isDirectory() ? 'directory' : 'file' }))
543
+ .sort((a, b) => {
544
+ if (a.type !== b.type) return a.type === 'directory' ? -1 : 1;
545
+ return a.name.localeCompare(b.name);
546
+ });
547
+ res.writeHead(200, { 'Content-Type': 'application/json' });
548
+ res.end(JSON.stringify(items));
549
+ } catch (err) {
550
+ res.writeHead(404, { 'Content-Type': 'application/json' });
551
+ res.end(JSON.stringify({ error: 'Directory not found' }));
552
+ }
553
+ return;
554
+ }
555
+
556
+ // 读取文件内容 API
557
+ if (url === '/api/file-content' && method === 'GET') {
558
+ const reqPath = parsedUrl.searchParams.get('path');
559
+ if (!reqPath || reqPath.startsWith('/') || reqPath.includes('..')) {
560
+ res.writeHead(400, { 'Content-Type': 'application/json' });
561
+ res.end(JSON.stringify({ error: 'Invalid path' }));
562
+ return;
563
+ }
564
+ const cwd = process.env.CCV_PROJECT_DIR || process.cwd();
565
+ const targetFile = join(cwd, reqPath);
566
+ try {
567
+ if (!existsSync(targetFile)) {
568
+ res.writeHead(404, { 'Content-Type': 'application/json' });
569
+ res.end(JSON.stringify({ error: `File not found: ${targetFile}` }));
570
+ return;
571
+ }
572
+ const stat = statSync(targetFile);
573
+ if (!stat.isFile()) {
574
+ res.writeHead(400, { 'Content-Type': 'application/json' });
575
+ res.end(JSON.stringify({ error: 'Not a file' }));
576
+ return;
577
+ }
578
+ // 限制文件大小 5MB
579
+ if (stat.size > 5 * 1024 * 1024) {
580
+ res.writeHead(413, { 'Content-Type': 'application/json' });
581
+ res.end(JSON.stringify({ error: 'File too large' }));
582
+ return;
583
+ }
584
+ const content = readFileSync(targetFile, 'utf-8');
585
+ res.writeHead(200, { 'Content-Type': 'application/json' });
586
+ res.end(JSON.stringify({ path: reqPath, content, size: stat.size }));
587
+ } catch (err) {
588
+ res.writeHead(500, { 'Content-Type': 'application/json' });
589
+ res.end(JSON.stringify({ error: `Cannot read file: ${err.message}` }));
590
+ }
591
+ return;
592
+ }
593
+
526
594
  // CLI 模式检测
527
595
  if (url === '/api/cli-mode' && method === 'GET') {
528
596
  res.writeHead(200, { 'Content-Type': 'application/json' });
@@ -530,6 +598,118 @@ function handleRequest(req, res) {
530
598
  return;
531
599
  }
532
600
 
601
+ // Git 状态
602
+ if (url === '/api/git-status' && method === 'GET') {
603
+ try {
604
+ const cwd = process.env.CCV_PROJECT_DIR || process.cwd();
605
+ const output = execSync('git status --porcelain', { cwd, encoding: 'utf-8', timeout: 5000 });
606
+ const lines = output.split('\n').filter(line => line.trim());
607
+ const changes = lines.map(line => {
608
+ const status = line.substring(0, 2).trim();
609
+ const file = line.substring(3).trim();
610
+ return { status, file };
611
+ });
612
+ res.writeHead(200, { 'Content-Type': 'application/json' });
613
+ res.end(JSON.stringify({ changes }));
614
+ } catch (err) {
615
+ res.writeHead(500, { 'Content-Type': 'application/json' });
616
+ res.end(JSON.stringify({ error: err.message, changes: [] }));
617
+ }
618
+ return;
619
+ }
620
+
621
+ // Git diff 数据获取
622
+ if (url.startsWith('/api/git-diff') && method === 'GET') {
623
+ try {
624
+ const cwd = process.env.CCV_PROJECT_DIR || process.cwd();
625
+ const filesParam = parsedUrl.searchParams.get('files');
626
+
627
+ if (!filesParam) {
628
+ res.writeHead(400, { 'Content-Type': 'application/json' });
629
+ res.end(JSON.stringify({ error: 'Missing files parameter' }));
630
+ return;
631
+ }
632
+
633
+ const files = filesParam.split(',').map(f => f.trim()).filter(Boolean);
634
+ const diffs = [];
635
+
636
+ for (const file of files) {
637
+ // 安全检查:防止路径穿越
638
+ if (file.includes('..') || file.startsWith('/')) continue;
639
+
640
+ try {
641
+ const statusOutput = execSync(`git status --porcelain "${file}"`, { cwd, encoding: 'utf-8', timeout: 3000 });
642
+ if (!statusOutput.trim()) continue;
643
+
644
+ const status = statusOutput.substring(0, 2).trim();
645
+ const is_new = status === 'A' || status === '??';
646
+ const is_deleted = status === 'D';
647
+
648
+ // 检查是否为二进制文件
649
+ let is_binary = false;
650
+ try {
651
+ const diffCheck = execSync(`git diff --numstat HEAD "${file}"`, { cwd, encoding: 'utf-8', timeout: 3000 });
652
+ if (diffCheck.includes('-\t-\t')) {
653
+ is_binary = true;
654
+ }
655
+ } catch {}
656
+
657
+ let old_content = '';
658
+ let new_content = '';
659
+
660
+ if (!is_binary) {
661
+ // 获取旧内容(HEAD 版本)
662
+ if (!is_new) {
663
+ try {
664
+ old_content = execSync(`git show HEAD:"${file}"`, { cwd, encoding: 'utf-8', timeout: 5000, maxBuffer: 5 * 1024 * 1024 });
665
+ } catch {
666
+ old_content = '';
667
+ }
668
+ }
669
+
670
+ // 获取新内容(工作区版本)
671
+ if (!is_deleted) {
672
+ try {
673
+ const filePath = join(cwd, file);
674
+ if (existsSync(filePath)) {
675
+ const stat = statSync(filePath);
676
+ if (stat.size > 5 * 1024 * 1024) {
677
+ // 文件过大
678
+ diffs.push({ file, status, is_large: true, size: stat.size });
679
+ continue;
680
+ }
681
+ new_content = readFileSync(filePath, 'utf-8');
682
+ }
683
+ } catch {
684
+ new_content = '';
685
+ }
686
+ }
687
+ }
688
+
689
+ diffs.push({
690
+ file,
691
+ status,
692
+ old_content,
693
+ new_content,
694
+ is_binary,
695
+ is_new,
696
+ is_deleted
697
+ });
698
+ } catch (err) {
699
+ // 跳过无法处理的文件
700
+ continue;
701
+ }
702
+ }
703
+
704
+ res.writeHead(200, { 'Content-Type': 'application/json' });
705
+ res.end(JSON.stringify({ diffs }));
706
+ } catch (err) {
707
+ res.writeHead(500, { 'Content-Type': 'application/json' });
708
+ res.end(JSON.stringify({ error: err.message, diffs: [] }));
709
+ }
710
+ return;
711
+ }
712
+
533
713
  // 返回局域网访问地址
534
714
  if (url === '/api/local-url' && method === 'GET') {
535
715
  const nets = networkInterfaces();
@@ -758,8 +938,8 @@ export async function startViewer() {
758
938
  currentServer.listen(port, HOST, () => {
759
939
  server = currentServer;
760
940
  actualPort = port;
761
- const url = `http://${HOST}:${port}`;
762
- console.error(t('server.started', { host: HOST, port }));
941
+ const url = `http://127.0.0.1:${port}`;
942
+ console.error(t('server.started', { host: '127.0.0.1', port }));
763
943
  // v2.0.69 之前的版本会清空控制台,自动打开浏览器确保用户能看到界面
764
944
  try {
765
945
  const ccPkgPath = join(__dirname, '..', '@anthropic-ai', 'claude-code', 'package.json');