cc-viewer 1.4.9 → 1.4.11

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.
@@ -0,0 +1,41 @@
1
+ body{margin:0;background-color:#0d0d0d}*{scrollbar-width:thin;scrollbar-color:#3a3a3a #0d0d0d}@media(pointer:coarse){*{scrollbar-width:auto;scrollbar-color:auto}}@media(pointer:fine){*::-webkit-scrollbar{width:6px;height:6px}*::-webkit-scrollbar-track{background:#0d0d0d}*::-webkit-scrollbar-thumb{background:#3a3a3a;border-radius:3px}*::-webkit-scrollbar-thumb:hover{background:#555}}.code-highlight{color:#e6edf3}.hl-keyword{color:#ff7b72}.hl-string{color:#a5d6ff}.hl-comment{color:#8b949e;font-style:italic}.hl-number{color:#79c0ff}.hl-linenum{color:#484f58;-webkit-user-select:none;user-select:none}.chat-md pre{background:#0d1117;border:1px solid #2a2a2a;border-radius:6px;padding:12px;overflow-x:auto;font-size:13px;line-height:1.5}.chat-md code{background:#1a1a2e;padding:2px 6px;border-radius:4px;font-size:13px;color:#e5e7eb}.chat-md pre code{background:none;padding:0}.chat-md p{margin:6px 0}.chat-md ul,.chat-md ol{padding-left:20px;margin:6px 0}.chat-md li{margin:2px 0}.chat-md h1,.chat-md h2,.chat-md h3{margin:12px 0 6px;color:#fff}.chat-md h1{font-size:1.3em}.chat-md h2{font-size:1.15em}.chat-md h3{font-size:1.05em}.chat-md blockquote{border-left:3px solid #3b82f6;margin:8px 0;padding:4px 12px;color:#9ca3af}.chat-md table{border-collapse:collapse;margin:8px 0;font-size:13px}.chat-md th,.chat-md td{border:1px solid #2a2a2a;padding:6px 10px}.chat-md th{background:#1a1a1a;color:#fff}.chat-md a{color:#60a5fa}.chat-md hr{border:none;border-top:1px solid #2a2a2a;margin:12px 0}.chat-md strong{color:#f1f5f9}.chat-md em{color:#cbd5e1}.ant-tooltip .ant-tooltip-inner{background-color:#090909}.ant-tooltip .ant-tooltip-arrow:before,.ant-tooltip .ant-tooltip-arrow:after{background:#090909}._helpBtn_cvsqb_1{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;border-radius:50%;background:#1a1a1a;border:1px solid #444;color:#aaa;font-size:11px;line-height:1;cursor:pointer;margin-left:4px;vertical-align:middle;transition:background .2s;-webkit-user-select:none;user-select:none}._helpBtn_cvsqb_1:hover{background:#333}._modalBody_cvsqb_24{max-height:60vh;overflow-y:auto;line-height:1.7}._modalBody_cvsqb_24 h1,._modalBody_cvsqb_24 h2,._modalBody_cvsqb_24 h3{margin-top:.8em}._modalBody_cvsqb_24 p{margin:.5em 0}._modalBody_cvsqb_24 code{background:#2a2a2a;padding:1px 4px;border-radius:3px;font-size:.9em}._modalBody_cvsqb_24 pre{background:#1a1a1a;padding:12px;border-radius:6px;overflow-x:auto}._spinWrap_cvsqb_54{display:flex;justify-content:center;padding:40px 0}._modalBody_cvsqb_24 textarea{width:100%;min-height:200px;background:#1a1a1a;color:#d9d9d9;font-family:monospace;font-size:13px;line-height:1.6;border:1px solid #333;border-radius:6px;padding:10px 14px;resize:vertical;outline:none}._headerBar_1g6ok_2{display:flex;align-items:center;justify-content:space-between;width:100%;height:100%}._titleText_1g6ok_11{color:#fff;font-size:18px;cursor:pointer}._logoImage_1g6ok_17{height:24px;width:24px;margin-right:6px;border-radius:3px;vertical-align:text-bottom}._titleArrow_1g6ok_25{font-size:12px;margin-left:4px}._tokenStatsTag_1g6ok_31{border-radius:12px;cursor:pointer;background:#2a2a2a;border:1px solid #3a3a3a;color:#ccc}._tokenStatsIcon_1g6ok_39{margin-right:4px}._liveTag_1g6ok_44{border-radius:12px}._liveDotWrap_1g6ok_48{display:inline-flex;align-items:center;justify-content:center;width:10px;height:10px;vertical-align:middle;margin-right:2px;position:relative;top:-1px}._liveTag_1g6ok_44 .ant-badge-status-processing{animation:_breathe_1g6ok_1 2.5s ease-in-out infinite}@keyframes _breathe_1g6ok_1{0%,to{opacity:.4;transform:scale(.85)}50%{opacity:1;transform:scale(1.15)}}._liveSpinner_1g6ok_70{display:block;animation:_spinPlusStar_1g6ok_1 2s linear infinite}._liveSpinnerDiag_1g6ok_75{animation:_diagFade_1g6ok_1 2s ease-in-out infinite}@keyframes _spinPlusStar_1g6ok_1{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes _diagFade_1g6ok_1{0%,to{opacity:1}50%{opacity:0}}._inflightList_1g6ok_90{min-width:180px}._inflightItem_1g6ok_94{display:flex;align-items:center;gap:8px;padding:3px 0;font-size:12px}._inflightItem_1g6ok_94+._inflightItem_1g6ok_94{border-top:1px solid #333}._inflightTag_1g6ok_106{color:#52c41a;font-weight:500;white-space:nowrap}._inflightModel_1g6ok_112{color:#999;white-space:nowrap}._inflightTime_1g6ok_117{color:#666;margin-left:auto;white-space:nowrap}._liveTagHistory_1g6ok_123{background:#2a2a2a;border-color:#424242;color:#d1d5db}._liveTagText_1g6ok_129{margin-left:4px}._countdownStrong_1g6ok_134{font-variant-numeric:tabular-nums}._qrcodePopover_1g6ok_139{display:flex;flex-direction:column;align-items:center;padding:8px}._qrcodeSection_1g6ok_146{display:flex;flex-direction:column;align-items:center;padding:16px;margin-bottom:12px;border:1px solid #333;border-radius:8px;background:#111}._qrcodeTitle_1g6ok_157{font-size:14px;font-weight:600;color:#e5e5e5;margin-bottom:12px}._qrcodeUrlInput_1g6ok_164{margin-top:12px;font-size:12px;font-family:Menlo,Monaco,monospace}._qrcodeUrlCopy_1g6ok_170{cursor:pointer;color:#888;transition:color .2s}._qrcodeUrlCopy_1g6ok_170:hover{color:#3b82f6}._settingsGroupBox_1g6ok_181{border:1px solid #333;border-radius:8px;background:#111;padding:4px 16px;margin-bottom:12px}._settingsGroupTitle_1g6ok_189{font-size:14px;font-weight:600;color:#e5e5e5;padding:12px 0 4px;border-bottom:1px solid #333}._settingsItem_1g6ok_198{display:flex;justify-content:space-between;align-items:center;padding:12px 0}._settingsLabel_1g6ok_205{font-size:14px}._tokenStatsEmpty_1g6ok_210{padding:8px 4px;color:#999;font-size:13px}._tokenStatsContainer_1g6ok_217{display:flex;gap:12px;align-items:flex-start}._tokenStatsColumn_1g6ok_223{min-width:240px}._toolStatsColumn_1g6ok_227{min-width:180px}._modelCard_1g6ok_232{border:1px solid #333;border-radius:6px;padding:8px 10px;background:#111}._modelCardSpaced_1g6ok_239{margin-bottom:10px}._modelName_1g6ok_245{font-size:13px;font-weight:600;color:#e5e5e5;margin-bottom:8px;padding-bottom:4px;border-bottom:1px solid #333}._statsTable_1g6ok_255{width:100%;border-collapse:collapse}._th_1g6ok_260{padding:2px 12px;font-size:12px;font-family:monospace;white-space:nowrap;color:#888;font-weight:400;text-align:right}._td_1g6ok_270{padding:2px 12px;font-size:12px;font-family:monospace;white-space:nowrap;color:#e5e5e5;text-align:right}._label_1g6ok_279{padding:2px 12px;font-size:12px;font-family:monospace;white-space:nowrap;color:#aaa;font-weight:400;text-align:left}._rowBorder_1g6ok_289{border-bottom:1px solid #2a2a2a}._rebuildCard_1g6ok_293{border:1px solid #333;border-radius:6px;padding:8px 10px;margin-top:10px;background:#111}._rebuildTotalRow_1g6ok_301{border-top:1px solid #444}._rebuildTotalRow_1g6ok_301 td{font-weight:600}._promptExportBar_1g6ok_310{margin-bottom:12px}._promptScrollArea_1g6ok_314{max-height:500px;overflow:auto}._promptEmpty_1g6ok_319{color:#999;padding:12px}._promptTimestamp_1g6ok_325{color:#666;font-size:12px;margin:12px 0 4px;padding-bottom:6px}._textPromptCard_1g6ok_333{margin:4px 0;background:#141414;border-radius:6px;border:1px solid #303030;padding:10px 14px}._preText_1g6ok_342{white-space:pre-wrap;word-break:break-word;font-size:13px;line-height:1.6;color:#d9d9d9;margin:4px 0}._systemCollapse_1g6ok_352{margin:4px 0;background:#1a1a1a;border:1px solid #303030;border-radius:6px}._systemLabel_1g6ok_359{color:#888;font-size:12px}._preSys_1g6ok_364{white-space:pre-wrap;word-break:break-word;font-size:12px;line-height:1.5;color:#999;margin:0}._promptTextarea_1g6ok_374{box-sizing:border-box;background:#000;width:100%;min-height:400px;color:#d9d9d9;font-family:monospace;font-size:13px;line-height:1.6;border:none;resize:vertical;padding:10px 14px;outline:none}._projectStatsCenter_1g6ok_390{display:flex;justify-content:center;padding:40px 0}._projectStatsEmpty_1g6ok_396{color:#999;padding:40px 0;text-align:center;font-size:13px}._projectStatsContent_1g6ok_403{display:flex;flex-direction:column;gap:16px}._projectStatsUpdated_1g6ok_409{color:#666;font-size:12px;text-align:right}._projectStatsSummary_1g6ok_415{display:grid;grid-template-columns:1fr 1fr;gap:10px}._projectStatCard_1g6ok_421{background:#111;border:1px solid #333;border-radius:8px;padding:14px 12px;text-align:center}._projectStatValue_1g6ok_429{font-size:22px;font-weight:700;color:#e5e5e5;font-family:monospace;font-variant-numeric:tabular-nums}._projectStatLabel_1g6ok_437{font-size:12px;color:#888;margin-top:4px}._projectStatsSection_1g6ok_443{display:flex;flex-direction:column;gap:10px}._projectStatsSectionTitle_1g6ok_449{font-size:14px;font-weight:600;color:#ccc;padding-bottom:4px;border-bottom:1px solid #333}._projectStatsModelCard_1g6ok_457{background:#111;border:1px solid #333;border-radius:6px;padding:10px 12px}._projectStatsModelHeader_1g6ok_464{display:flex;justify-content:space-between;align-items:center;margin-bottom:8px;padding-bottom:4px;border-bottom:1px solid #333}._projectStatsModelName_1g6ok_473{font-size:13px;font-weight:600;color:#e5e5e5}._projectStatsModelCount_1g6ok_479{font-size:12px;color:#888;font-family:monospace}._centerEmpty_oxhcp_1{display:flex;align-items:center;justify-content:center;height:100%}._scrollContainer_oxhcp_8{overflow:auto;height:100%;-webkit-overflow-scrolling:touch;will-change:scroll-position}._listItem_oxhcp_15{cursor:pointer;padding:8px 12px;border-left:3px solid transparent;border-bottom:1px solid #1f1f1f;transition:background .15s}._listItem_oxhcp_15:hover{background:#151515}._listItemActive_oxhcp_27{background:#1a2332;border-left-color:#3b82f6}._listItemActive_oxhcp_27:hover{background:#1a2332}._itemContent_oxhcp_36{width:100%;min-width:0}._itemHeader_oxhcp_41{display:flex;align-items:center;gap:6px;margin-bottom:4px;font-size:12px}._tagNoMargin_oxhcp_49{margin:0;font-size:12px}._modelName_oxhcp_54{font-size:12px}._time_oxhcp_58{font-size:12px;color:#6b7280;margin-left:auto}._detailRow_oxhcp_64{display:flex;gap:8px;font-size:12px;align-items:center}._urlText_oxhcp_71{color:#555;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0}._duration_oxhcp_80{color:#6b7280;flex-shrink:0}._statusOk_oxhcp_85{color:#52c41a;opacity:.5;flex-shrink:0}._statusErr_oxhcp_91{color:#ef4444;flex-shrink:0}._statusDefault_oxhcp_96{color:#9ca3af;flex-shrink:0}._usageBox_oxhcp_101{background:#111;border-radius:4px;padding:3px 6px;margin-top:4px;font-size:12px;color:#6b7280;line-height:1.6}._cacheDot_oxhcp_111{display:inline-block;width:6px;height:6px;border-radius:50%;margin:0 3px;vertical-align:middle}._cacheDotLoss_oxhcp_120{background-color:#8b1a1a;cursor:help}._cacheDotNormal_oxhcp_125{background-color:#3a3a3a}._GzYRV{line-height:1.2;white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word}._3eOF8{margin-right:5px;font-weight:700}._3eOF8+._3eOF8{margin-left:-5px}._1MFti{cursor:pointer}._f10Tu{font-size:1.2em;margin-right:5px;-webkit-user-select:none;-moz-user-select:none;user-select:none}._1UmXx:after{content:"▸"}._1LId0:after{content:"▾"}._1pNG9{margin-right:5px}._1pNG9:after{content:"...";font-size:.8em}._2IvMF{background:#eee}._2bkNM{margin:0;padding:0 10px}._1BXBN{margin:0;padding:0}._1MGIk{font-weight:600;margin-right:5px;color:#000}._3uHL6{color:#000}._2T6PJ,._1Gho6{color:#df113a}._vGjyY{color:#2a3f3c}._1bQdo{color:#0b75f5}._3zQKs{color:#469038}._1xvuR{color:#43413d}._oLqym,._2AXVT,._2KJWg{color:#000}._11RoI{background:#002b36}._17H2C,._3QHg2,._3fDAz{color:#fdf6e3}._2bSDX{font-weight:bolder;margin-right:5px;color:#fdf6e3}._gsbQL{color:#fdf6e3}._LaAZe,._GTKgm{color:#81b5ac}._Chy1W{color:#cb4b16}._2bveF{color:#d33682}._2vRm-{color:#ae81ff}._1prJR{color:#268bd2}._container_1h2lr_1{background:#0d1117;border-radius:6px;border:1px solid #2a2a2a;padding:12px;font-size:13px;font-family:monospace;overflow:auto}._tag_17wfp_1{display:inline-block;font-size:10px;color:#6b7280;background:#ffffff0f;border:1px solid rgba(255,255,255,.1);border-radius:3px;padding:0 4px;margin-left:6px;cursor:pointer;line-height:18px;vertical-align:middle;transition:color .2s,border-color .2s;-webkit-user-select:none;user-select:none}._tag_17wfp_1:hover{color:#93c5fd;border-color:#93c5fd4d}._tagActive_17wfp_22{color:#93c5fd;border-color:#93c5fd40}._tagLoading_17wfp_27{cursor:wait;opacity:.7}._spinner_17wfp_32{display:inline-block;width:10px;height:10px;border:1.5px solid rgba(147,197,253,.3);border-top-color:#93c5fd;border-radius:50%;animation:_spin_17wfp_32 .6s linear infinite;margin-right:3px;vertical-align:middle}@keyframes _spin_17wfp_32{to{transform:rotate(360deg)}}._root_1bepf_1{display:flex;height:100%;min-height:0;gap:0}._sidebar_1bepf_9{width:220px;flex-shrink:0;border-right:1px solid #2a2a2a;overflow-y:auto;padding:4px 0;-webkit-overflow-scrolling:touch}._section_1bepf_18{-webkit-user-select:none;user-select:none}._sectionHeader_1bepf_22{display:flex;align-items:center;gap:6px;padding:6px 10px;cursor:pointer;color:#d1d5db;font-size:12px;font-weight:600;transition:background .15s}._sectionHeader_1bepf_22:hover{background:#ffffff0d}._arrow_1bepf_38{font-size:10px;color:#888;flex-shrink:0}._sectionTitle_1bepf_44{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._sectionCount_1bepf_52{font-size:11px;color:#666;background:#1f1f1f;border-radius:10px;padding:0 6px;line-height:18px}._sectionBody_1bepf_61{padding:2px 0}._historyToggle_1bepf_66{display:flex;align-items:center;gap:6px;padding:4px 10px 4px 14px;cursor:pointer;color:#666;font-size:11px;transition:color .15s,background .15s}._historyToggle_1bepf_66:hover{color:#888;background:#ffffff08}._historyToggleLabel_1bepf_82{flex:1}._item_1bepf_87{display:flex;align-items:center;justify-content:space-between;padding:5px 10px 5px 24px;font-size:12px;color:#888;cursor:pointer;transition:background .15s,color .15s}._item_1bepf_87:hover{background:#ffffff0a;color:#d1d5db}._itemActive_1bepf_103{background:#63b3ed1f;color:#63b3ed}._itemActive_1bepf_103:hover{background:#63b3ed29;color:#63b3ed}._itemContent_1bepf_113{flex:1;min-width:0;overflow:hidden}._itemLabel_1bepf_119{font-family:monospace;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:block}._itemSublabel_1bepf_127{font-size:10px;color:#555;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;margin-top:1px}._itemTime_1bepf_136{font-size:9px;color:#555;flex-shrink:0;margin-left:4px;font-family:monospace}._content_1bepf_145{flex:1;min-width:0;overflow:auto;padding:12px 16px;-webkit-overflow-scrolling:touch}._contentEmpty_1bepf_153{height:100%;display:flex;align-items:center;justify-content:center}._contentInner_1bepf_160{padding-bottom:20px}._emptyWrap_1bepf_164{display:flex;align-items:center;justify-content:center;height:200px}._roleHeader_1bepf_172{display:flex;align-items:center;gap:8px;margin-bottom:8px;flex-wrap:nowrap}._roleBadge_1bepf_180{font-size:10px;font-weight:600;letter-spacing:.04em;padding:2px 7px;border-radius:4px;flex-shrink:0}._role_user_1bepf_189{background:#3b82f62e;color:#60a5fa;border:1px solid rgba(59,130,246,.3)}._role_assistant_1bepf_195{background:#8b5cf62e;color:#a78bfa;border:1px solid rgba(139,92,246,.3)}._roleLabel_1bepf_201{font-size:11px;color:#666;flex:1;min-width:0}._contentTime_1bepf_208{margin-left:auto;font-size:10px;color:#555;font-family:monospace;flex-shrink:0}._turnDivider_1bepf_216{border:none;border-top:1px solid #1e1e1e;margin:14px 0}._textBlock_1bepf_223{margin-bottom:8px;border:1px solid #222;border-radius:6px;overflow:hidden}._textBlockBar_1bepf_230{display:flex;align-items:center;gap:6px;padding:4px 10px;background:#141414;border-bottom:1px solid #222}._textBlockBody_1bepf_239{padding:10px 12px;font-size:13px;line-height:1.7;color:#d1d5db;word-break:break-word}._textBlockCompact_1bepf_247{position:relative;padding:8px 10px;font-size:12px;color:#aaa}._textBlockCompactFloat_1bepf_254{float:right;margin-left:6px;margin-bottom:2px}._thinkingBlock_1bepf_261{margin-bottom:8px;border:1px solid #2a2a1e;border-radius:6px;overflow:hidden;background:#111108}._thinkingHeader_1bepf_269{display:flex;align-items:center;gap:6px;padding:5px 10px;cursor:pointer;font-size:12px;color:#888;transition:background .15s}._thinkingHeader_1bepf_269:hover{background:#ffffc808}._thinkingPreview_1bepf_284{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#666;font-size:11px}._thinkingBody_1bepf_294{padding:8px 12px;border-top:1px solid #2a2a1e}._toolBlock_1bepf_300{margin-bottom:8px;border:1px solid #222;border-radius:6px;overflow:hidden}._toolBlockResult_1bepf_307{border-color:#1a2a1a}._toolBlockError_1bepf_311{border-color:#2a1a1a}._toolBlockHeader_1bepf_315{display:flex;align-items:center;gap:8px;padding:5px 10px;background:#141414;border-bottom:1px solid #222;font-size:12px;flex-wrap:wrap}._toolBlockBody_1bepf_326{padding:8px 10px;font-size:12px}._toolName_1bepf_331{color:#d1d5db;font-weight:500;font-family:monospace}._toolId_1bepf_337{color:#555;font-size:10px;font-family:monospace;margin-left:auto}._errorLabel_1bepf_344{font-size:10px;color:#f87171;background:#ef44441f;border:1px solid rgba(239,68,68,.25);border-radius:3px;padding:1px 5px}._blockTag_1bepf_354{font-size:9px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;padding:1px 5px;border-radius:3px;background:#1a1a1a;color:#666;border:1px solid #2a2a2a;flex-shrink:0}._blockTagText_1bepf_367{background:#3b82f61a;color:#60a5fa;border-color:#3b82f633}._blockTagThinking_1bepf_373{background:#eab3081a;color:#ca8a04;border-color:#eab30833}._blockTagResult_1bepf_379{background:#22c55e1a;color:#4ade80;border-color:#22c55e33}._blockTagError_1bepf_385{background:#ef44441a;color:#f87171;border-color:#ef444433}._jsonBlock_1bepf_392{margin-bottom:8px;border:1px solid #222;border-radius:6px;overflow:hidden}._jsonBlockLabel_1bepf_399{font-size:10px;color:#666;padding:3px 10px;background:#141414;border-bottom:1px solid #222;font-family:monospace}._blockSeparator_1bepf_409{border:none;border-top:1px solid #2a2a2a;margin:16px 0}._markdownBody_1bepf_416{font-size:13px;line-height:1.7;color:#d1d5db;word-break:break-word}._container_i6t4e_1{height:100%;overflow:auto;padding:0 16px;-webkit-overflow-scrolling:touch;will-change:scroll-position}._emptyState_i6t4e_9{display:flex;align-items:center;justify-content:center;height:100%}._urlSection_i6t4e_16{padding:12px 0;border-bottom:1px solid #1f1f1f;display:flex;align-items:flex-start}._urlLeft_i6t4e_23{flex:1;min-width:0}._tokenStatsBox_i6t4e_28{flex-shrink:0;padding-left:12px;display:flex;align-items:center}._tokenGrid_i6t4e_35{display:flex;border:1px solid #303030;border-radius:6px;overflow:hidden;min-width:360px;font-size:11px;line-height:1.6}._tokenRows_i6t4e_45{flex:1}._tokenRow_i6t4e_45{display:flex}._tokenRowBorder_i6t4e_53{border-top:1px solid #303030}._tokenLabel_i6t4e_57{color:#888;padding:4px 8px;white-space:nowrap;font-weight:600}._tokenTd_i6t4e_64{flex:1;color:#d1d5db;text-align:right;padding:4px 8px;font-family:monospace;white-space:nowrap}._tokenHitRate_i6t4e_73{display:flex;flex-direction:column;align-items:center;justify-content:center;color:#d1d5db;padding:4px 8px;font-family:monospace;white-space:nowrap;border-left:1px solid #303030;min-width:100px}._tokenHitRateLabel_i6t4e_86{color:#888;font-size:10px;font-family:sans-serif}._tokenRowBorder_i6t4e_53 td{border-top:1px solid #303030}._urlText_i6t4e_96{color:#d1d5db;font-size:13px;margin-bottom:8px;word-break:break-all}._metaText_i6t4e_103,._headersContainer_i6t4e_107{font-size:12px}._headerRow_i6t4e_111{display:flex;padding:4px 0;border-bottom:1px solid #1f1f1f}._headerKey_i6t4e_117{min-width:200px;flex-shrink:0}._headerValue_i6t4e_122{word-break:break-all;margin-left:8px}._streamingBox_i6t4e_127{padding:20px;background:#1a1a1a;border-radius:6px;border:1px solid #2a2a2a}._bodyToolbar_i6t4e_134{display:flex;gap:8px;margin-bottom:8px}._rawTextPre_i6t4e_140{background:#0d1117;border:1px solid #2a2a2a;border-radius:6px;padding:12px;font-size:12px;color:#e5e7eb;overflow:auto;max-height:600px;white-space:pre-wrap;word-break:break-all}._tabContent_i6t4e_153{padding:12px 0}._collapseSpacing_i6t4e_157{margin-bottom:16px}._bodyLabel_i6t4e_161{margin:0}._bodyHeader_i6t4e_165{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}._diffSection_i6t4e_172{margin-bottom:16px}._diffToggle_i6t4e_176{display:inline-block;margin-bottom:8px;cursor:pointer}._diffIcon_i6t4e_182{font-size:12px;margin-left:4px}._viewInChatBtn_i6t4e_187{display:inline-flex;align-items:center;height:26px;border-radius:13px;border:1px solid #424242;background:transparent;color:#888;cursor:pointer;font-size:12px;transition:all .2s;padding:0 10px;white-space:nowrap}._viewInChatBtn_i6t4e_187:hover{border-color:#666;color:#d1d5db;background:#ffffff0f}._reminderSelect_i6t4e_208{min-width:140px;font-size:12px}._reminderSelect_i6t4e_208 .ant-select-selector{border-radius:2px!important;border-color:#424242!important;background:transparent!important;min-height:26px!important;height:auto!important;padding:0 8px!important;font-family:monospace}._reminderSelect_i6t4e_208 .ant-select-selection-placeholder{font-size:11px}._wrapper_1tbl3_1{margin:6px 0;background:#1a1a2e;border:1px solid #2a2a3e;border-radius:8px;padding:8px 12px}._header_1tbl3_9{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}._headerRight_1tbl3_16{display:flex;align-items:center;gap:12px}._filePath_1tbl3_22{color:#a78bfa;font-size:12px;font-weight:600}._toggle_1tbl3_28{color:#6b7280;font-size:11px;cursor:pointer;-webkit-user-select:none;user-select:none}._diffSummary_1tbl3_35{font-size:11px;color:#6b7280}._tableWrap_1tbl3_40{overflow-x:auto}._diffTable_1tbl3_44{width:100%;border-collapse:collapse;font-family:SF Mono,Cascadia Code,Fira Code,Menlo,Consolas,monospace;font-size:12px;line-height:1.5;table-layout:fixed}._diffTable_1tbl3_44 td{padding:0 4px;white-space:pre;vertical-align:top}._lineNumOld_1tbl3_59,._lineNumNew_1tbl3_60{width:40px;min-width:40px;max-width:40px;text-align:right;color:#484f58;-webkit-user-select:none;user-select:none;padding-right:6px}._prefix_1tbl3_70{width:16px;min-width:16px;max-width:16px;text-align:center;-webkit-user-select:none;user-select:none;font-weight:600}._lineContent_1tbl3_79{width:100%;overflow:hidden;text-overflow:ellipsis}._rowContext_1tbl3_85 td{color:#8b949e}._rowDel_1tbl3_89{background:#ef44441f}._rowDel_1tbl3_89 td{color:#fca5a5}._rowDel_1tbl3_89 ._prefix_1tbl3_70{color:#ef4444}._rowAdd_1tbl3_99{background:#22c55e1f}._rowAdd_1tbl3_99 td{color:#86efac}._rowAdd_1tbl3_99 ._prefix_1tbl3_70{color:#22c55e}._plainResult_1uh60_1{background:#111;border-radius:6px;font-size:12px}._plainTitle_1uh60_7{font-size:11px}._plainPre_1uh60_11{color:#d1d5db;margin:0;white-space:pre-wrap;word-break:break-all;font-size:12px;padding:8px 12px}._codeResult_1uh60_20{background:#0d1117;border-radius:6px;border:1px solid #1e2a3a;overflow:hidden}._codeHeader_1uh60_27{display:flex;justify-content:space-between;align-items:center;padding:4px 10px;background:#161b22;border-bottom:1px solid #1e2a3a}._codeTitle_1uh60_36{font-size:11px;color:#8b949e}._codeToggle_1uh60_41{font-size:11px;color:#484f58;cursor:pointer;-webkit-user-select:none;user-select:none}._codePre_1uh60_48{margin:0;padding:8px 12px;font-size:12px;line-height:1.5;overflow:auto;max-height:500px}._markdownBody_1uh60_57{padding:8px 12px;font-size:13px;line-height:1.6;overflow:auto;max-height:500px}._avatar_w9l4s_3{width:32px;height:32px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex-shrink:0}._avatarImg_w9l4s_13{width:32px;height:32px;border-radius:50%;flex-shrink:0;object-fit:cover}._bubble_w9l4s_21{border-radius:8px;padding:10px 14px;max-width:100%;font-size:14px;line-height:1.6;word-break:break-word}._messageRow_w9l4s_32{display:flex;gap:10px;padding:8px 0}._messageRowEnd_w9l4s_38{display:flex;gap:10px;padding:8px 0;justify-content:flex-end}._contentCol_w9l4s_47{min-width:0;flex:1}._contentColLimited_w9l4s_52{min-width:0;max-width:80%;width:fit-content}._labelRow_w9l4s_60{display:flex;justify-content:space-between;align-items:center;margin-bottom:2px}._labelRowEnd_w9l4s_67{display:flex;justify-content:flex-end;align-items:center;margin-bottom:2px}._labelRight_w9l4s_74{display:flex;align-items:center;gap:4px;flex-shrink:0;margin-left:auto}._labelText_w9l4s_82{font-size:11px}._timeText_w9l4s_86,._timeTextNoMargin_w9l4s_92{font-size:10px;color:#6b7280;flex-shrink:0}._labelTextRight_w9l4s_98{font-size:11px;margin-left:auto}._bubbleUser_w9l4s_105{background:#1668dc;color:#e5e7eb}._bubbleAssistant_w9l4s_111{background:#141414;color:#e5e7eb;transition:box-shadow 0s;position:relative}._bubbleHighlight_w9l4s_119{box-shadow:0 0 10px #1668dc99}._bubbleHighlightFading_w9l4s_123{box-shadow:0 0 10px #1668dc00;transition:box-shadow 5s ease-out}._borderSvg_w9l4s_128{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;pointer-events:none;overflow:visible}._borderSvgFading_w9l4s_137{opacity:0;transition:opacity 5s ease-out}._borderRect_w9l4s_142{animation:_dashRotate_w9l4s_1 4s linear infinite}@keyframes _dashRotate_w9l4s_1{0%{stroke-dashoffset:0}to{stroke-dashoffset:-100}}._bubblePlan_w9l4s_151{background:#141428;border:5px solid #1668dc;font-size:12px;color:#e5e7eb}._bubbleSubAgent_w9l4s_159{background:#1a1a2e;color:#e5e7eb}._bubbleSelection_w9l4s_165{background:#1a3a1a;color:#e5e7eb}._systemTagLabel_w9l4s_173{font-size:12px}._skillLabel_w9l4s_177{font-size:12px;color:#a78bfa}._systemTagPre_w9l4s_182{font-size:12px;color:#9ca3af;white-space:pre-wrap;word-break:break-all;margin:0}._collapseMargin_w9l4s_190{margin:4px 0}._collapseNoMargin_w9l4s_194{margin:0}._thinkingLabel_w9l4s_200{font-size:12px}._toolBox_w9l4s_206{background:#1a1a2e;border:1px solid #2a2a3e;border-radius:8px;padding:8px 12px;margin:6px 0;font-size:12px}._toolLabel_w9l4s_215{color:#a78bfa}._codePre_w9l4s_221{font-size:12px;margin:4px 0 0;white-space:pre-wrap;word-break:break-all;background:#0d1117;border-radius:4px;padding:6px 8px}._pathTag_w9l4s_233{color:#7dd3fc;font-size:11px}._descSpan_w9l4s_240{color:#6b7280;font-weight:400}._secondarySpan_w9l4s_245{color:#6b7280}._patternSpan_w9l4s_249{color:#fbbf24}._kvContainer_w9l4s_255{margin-top:4px;font-size:11px}._kvItem_w9l4s_260{margin:2px 0}._kvKey_w9l4s_264{color:#7dd3fc}._kvValue_w9l4s_268{color:#9ca3af}._toolResult_w9l4s_274{background:#111827;border:1px solid #1e293b;border-radius:6px;padding:6px 10px;margin:2px 0 6px;font-size:11px}._toolResultLabel_w9l4s_283{font-size:11px}._compactLabel_w9l4s_289{font-size:12px;color:#93c5fd}._compactPre_w9l4s_294{font-size:12px;color:#d1d5db;white-space:pre-wrap;word-break:break-all;margin:0}._viewRequestBtn_w9l4s_304{font-size:10px;color:#555;cursor:pointer;margin-left:6px;flex-shrink:0}._viewRequestBtn_w9l4s_304:hover{color:#93c5fd}._optionList_w9l4s_318{padding-left:8px}._optionDesc_w9l4s_322{color:#555;margin-left:6px;font-weight:400}._questionText_w9l4s_330{font-size:13px;color:#ccc;margin-bottom:4px}._questionSpacing_w9l4s_336{margin-bottom:10px}._option_w9l4s_318{font-size:12px;padding:1px 0}._askQuestionBox_w9l4s_349{background:#0d1f0d;border:1px solid #2ea043;border-radius:8px;padding:8px 12px;margin:6px 0;font-size:12px}._askQuestionHeader_w9l4s_358{display:inline-block;background:#1a3a1a;color:#7ee787;font-size:10px;padding:1px 6px;border-radius:4px;margin-bottom:4px;font-weight:600}._askQuestionText_w9l4s_369{color:#e5e7eb;font-size:13px;margin-bottom:4px}._askOptionItem_w9l4s_375{font-size:12px;color:#9ca3af;padding:1px 0}._planModeBox_w9l4s_383{background:#0d1528;border:1px solid #1668dc;border-radius:8px;padding:8px 12px;margin:6px 0;font-size:12px}._planModeLabel_w9l4s_392{color:#93c5fd;font-weight:600}._planModePermissions_w9l4s_397{margin-top:6px;padding-top:6px;border-top:1px solid #1e3a5f}._planModePermLabel_w9l4s_403{color:#6b7280;font-size:11px;margin-bottom:2px}/**
2
+ * Copyright (c) 2014 The xterm.js authors. All rights reserved.
3
+ * Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
4
+ * https://github.com/chjj/term.js
5
+ * @license MIT
6
+ *
7
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
8
+ * of this software and associated documentation files (the "Software"), to deal
9
+ * in the Software without restriction, including without limitation the rights
10
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
+ * copies of the Software, and to permit persons to whom the Software is
12
+ * furnished to do so, subject to the following conditions:
13
+ *
14
+ * The above copyright notice and this permission notice shall be included in
15
+ * all copies or substantial portions of the Software.
16
+ *
17
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
+ * THE SOFTWARE.
24
+ *
25
+ * Originally forked from (with the author's permission):
26
+ * Fabrice Bellard's javascript vt100 for jslinux:
27
+ * http://bellard.org/jslinux/
28
+ * Copyright (c) 2011 Fabrice Bellard
29
+ * The original design remains. The terminal itself
30
+ * has been extended to include xterm CSI codes, among
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}._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_1ti8s_1{display:flex;flex-direction:column;height:100%;background:#0d0d0d}._header_1ti8s_8{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;border-bottom:1px solid #2a2a2a;background:#111;flex-shrink:0}._headerLeft_1ti8s_18{display:flex;align-items:center;gap:8px;flex:1;min-width:0}._backBtn_1ti8s_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_1ti8s_26:hover{color:#ccc;background:#1a1a1a}._filePath_1ti8s_47{font-size:13px;color:#ccc;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._fileSize_1ti8s_55{font-size:11px;color:#666;flex-shrink:0}._contentContainer_1ti8s_61{flex:1;overflow:hidden;background:#0d0d0d;display:flex}._codeBlock_1ti8s_68{display:flex;flex:1;min-height:0;min-width:0;overflow:hidden}._lineNumberCol_1ti8s_76{flex-shrink:0;overflow:hidden;background:#0d0d0d;border-right:1px solid #2a2a2a;-webkit-user-select:none;user-select:none}._lineNumberRow_1ti8s_84{padding:0 16px;text-align:right;color:#555;font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace;font-size:13px;line-height:1.5;white-space:nowrap}._codeCol_1ti8s_94{flex:1;overflow:auto;min-width:0}._codeContent_1ti8s_100{padding:0;font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace;font-size:13px;line-height:1.5;color:#e0e0e0;-moz-tab-size:2;tab-size:2;margin:0;width:fit-content;min-width:100%}._codeContent_1ti8s_100 code{font-family:inherit;font-size:inherit;line-height:inherit;background:none;padding:0;display:block}._lineContentRow_1ti8s_121{padding:0 16px;white-space:pre}._loading_1ti8s_126{display:flex;align-items:center;justify-content:center;height:100%;color:#666;font-size:14px}._error_1ti8s_135{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_1u9hn_1{width:100%;height:100%;display:flex;flex-direction:column;background:#0d0d0d;overflow:hidden}._diffSummary_1u9hn_10{padding:8px 16px;background:#111;border-bottom:1px solid #2a2a2a;display:flex;gap:8px;align-items:center;flex-shrink:0}._addedBadge_1u9hn_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_1u9hn_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_1u9hn_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_1u9hn_53{flex:1;overflow:hidden;display:flex;min-height:0;font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace;font-size:13px;line-height:1.6}._lineNumberCol_1u9hn_63{flex-shrink:0;overflow:hidden;background:#0d0d0d;border-right:1px solid #2a2a2a;-webkit-user-select:none;user-select:none}._lineNumNormal_1u9hn_71{padding:0 12px 0 8px;text-align:right;color:#555;font-size:12px;min-height:21px}._lineNumAdd_1u9hn_79{padding:0 9px 0 8px;text-align:right;color:#73c991;font-weight:600;font-size:12px;min-height:21px;border-right:3px solid #73c991}._lineNumModify_1u9hn_89{padding:0 9px 0 8px;text-align:right;color:#e2c08d;font-weight:600;font-size:12px;min-height:21px;border-right:3px solid #e2c08d}._lineNumDelete_1u9hn_99{padding:0 9px 0 8px;text-align:right;color:#f14c4c;font-weight:600;font-size:12px;min-height:21px;border-right:3px solid #f14c4c}._codeCol_1u9hn_109{flex:1;overflow:auto;min-width:0}._codeInner_1u9hn_115{width:fit-content;min-width:100%}._codeLine_1u9hn_120{position:relative;min-height:21px;transition:background .1s}._codeLine_1u9hn_120:hover{background:#ffffff08}._lineContent_1u9hn_130{padding-right:16px;padding-left:8px;color:#ccc;white-space:pre}._lineNormal_1u9hn_137{background:transparent}._lineAdd_1u9hn_141{background:#73c9911a}._lineModify_1u9hn_145{background:#e2c08d1a;position:relative}._lineDelete_1u9hn_150{background:#f14c4c1a}._lineDelete_1u9hn_150 ._lineContent_1u9hn_130{text-decoration:line-through;opacity:.8}._lineModify_1u9hn_145:hover ._oldContentTooltip_1u9hn_159{display:block}._oldContentTooltip_1u9hn_159{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_1u9hn_178{font-size:10px;color:#888;margin-bottom:4px;text-transform:uppercase;letter-spacing:.5px}._tooltipContent_1u9hn_186{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_8tuwm_1{display:flex;align-items:center;justify-content:center;height:100%}._container_8tuwm_8{flex:1;overflow:auto;padding:16px 24px;display:flex;flex-direction:column;-webkit-overflow-scrolling:touch;overscroll-behavior:contain}._sessionDividerText_8tuwm_18{font-size:11px;color:#555}._lastResponseLabel_8tuwm_23{font-size:11px}._splitContainer_8tuwm_27{display:flex;flex-direction:row;height:100%;overflow:hidden}._chatSection_8tuwm_34{display:flex;flex-direction:column;min-width:0;overflow:hidden}._vResizer_8tuwm_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_8tuwm_41:hover{background:#2a2a2a}._snapLine_8tuwm_55{position:absolute;top:0;bottom:0;width:2px;background:transparent;border-left:2px dashed rgba(255,255,255,.1);pointer-events:none;z-index:1000;transition:all .15s}._snapLineActive_8tuwm_67{position:absolute;top:0;bottom:0;width:2px;background:transparent;border-left:2px dashed rgba(255,255,255,.5);pointer-events:none;z-index:1001}._snapLineLabel_8tuwm_78{position:absolute;top:50%;left:8px;transform:translateY(-50%);background:#ffffffe6;color:#000;padding:4px 8px;border-radius:4px;font-size:11px;font-weight:600;white-space:nowrap;font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace;box-shadow:0 2px 8px #0000004d}._snapPreview_8tuwm_94{position:absolute;top:0;bottom:0;background:#ffffff1a;pointer-events:none;z-index:999}._vResizer_8tuwm_41:hover{background:#333}._chatInputBar_8tuwm_107{display:flex;align-items:flex-end;gap:8px;padding:10px 16px;background:#111;border-top:1px solid #2a2a2a;flex-shrink:0}._chatInputWrapper_8tuwm_117{flex:1;display:flex;flex-direction:column;background:#1a1a1a;border:1px solid #333;border-radius:12px;transition:border-color .2s;overflow:hidden}._chatInputWrapper_8tuwm_117:focus-within{border-color:#555}._chatTextareaWrap_8tuwm_132{position:relative;flex:1}._chatTextarea_8tuwm_132{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_8tuwm_132::placeholder{color:#555}._chatInputHint_8tuwm_156{font-size:11px;color:#444;padding:0 14px 6px;-webkit-user-select:none;user-select:none}._chatSendBtn_8tuwm_163{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_8tuwm_163:hover{background:#3a8eef}._chatSendBtn_8tuwm_163:disabled{opacity:.35;cursor:default}._chatSendBtn_8tuwm_163 svg{width:18px;height:18px}._messageListWrap_8tuwm_192{position:relative;flex:1;min-height:0;display:flex;flex-direction:column}._stickyBottomBtn_8tuwm_200{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_8tuwm_200 span{background:#00000080;padding:2px 10px;border-radius:10px}._stickyBottomBtn_8tuwm_200:hover{color:#fff;background:none}._ptyPromptBubble_8tuwm_233{margin:8px 0;padding:12px 16px;border-radius:12px;border:1px solid #3a3a3a;background:#161616;animation:_ptyPromptFadeIn_8tuwm_1 .25s ease-out}._ptyPromptResolved_8tuwm_242{opacity:.55}@keyframes _ptyPromptFadeIn_8tuwm_1{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}._ptyPromptQuestion_8tuwm_251{font-size:13px;color:#ccc;margin-bottom:10px;line-height:1.4}._ptyPromptOptions_8tuwm_258{display:flex;flex-wrap:wrap;gap:8px}._ptyPromptOption_8tuwm_258{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_8tuwm_258:hover{background:#2a2a2a;color:#eee;border-color:#555}._ptyPromptOptionPrimary_8tuwm_282{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_8tuwm_282:hover{background:#4a9eff40;color:#6ab4ff;border-color:#6ab4ff}._ptyPromptOptionChosen_8tuwm_300{padding:6px 14px;border-radius:18px;border:1px solid #4a9eff;background:#4a9eff33;color:#4a9eff;font-size:12px;cursor:default;white-space:nowrap}._ptyPromptOptionDimmed_8tuwm_311{padding:6px 14px;border-radius:18px;border:1px solid #2a2a2a;background:transparent;color:#444;font-size:12px;cursor:default;white-space:nowrap}._ghostText_8tuwm_322{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_8tuwm_338{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_8tuwm_338:hover{background:#222}._suggestionChipText_8tuwm_354{flex:1;color:#555;font-size:13px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._suggestionChipAction_8tuwm_363{color:#4a9eff;font-size:14px;flex-shrink:0}._navSidebar_8tuwm_369{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_8tuwm_381{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_8tuwm_381:hover{color:#ccc;background:#1a1a1a}._navBtnActive_8tuwm_401{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_8tuwm_401: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}._container_19bb3_1{display:flex;flex-direction:column;height:100%;background:#0a0a0a;overflow:hidden}._fileListSection_19bb3_10{height:300px;flex-shrink:0;display:flex;flex-direction:column;background:#111;border-bottom:1px solid #2a2a2a}._header_19bb3_19{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid #2a2a2a;flex-shrink:0}._headerTitle_19bb3_28{font-size:11px;font-weight:600;color:#888;text-transform:uppercase;letter-spacing:.5px}._fileCount_19bb3_36{font-size:10px;color:#555;background:#1a1a1a;padding:1px 6px;border-radius:8px}._changesContainer_19bb3_44{flex:1;overflow:auto;padding:4px 0;-webkit-overflow-scrolling:touch}._changeItem_19bb3_51{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_19bb3_51:hover{background:#1a1a1a}._changeItemActive_19bb3_68{background:#4a9eff1f;color:#fff}._changeItemActive_19bb3_68:hover{background:#4a9eff2e}._status_19bb3_77{width:16px;flex-shrink:0;font-size:11px;font-weight:600;text-align:center}._icon_19bb3_85{width:16px;height:16px;flex-shrink:0;display:flex;align-items:center;justify-content:center}._fileName_19bb3_94{overflow:hidden;text-overflow:ellipsis;flex:1}._diffSection_19bb3_101{flex:1;display:flex;flex-direction:column;min-height:0;overflow:hidden}._diffHeader_19bb3_109{display:flex;align-items:center;gap:10px;padding:10px 12px;border-bottom:1px solid #2a2a2a;background:#111;flex-shrink:0}._diffFilePath_19bb3_119{font-size:12px;color:#ccc;font-family:SF Mono,Monaco,Cascadia Code,Roboto Mono,Consolas,Courier New,monospace;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;flex:1}._diffBadge_19bb3_129{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}._diffContent_19bb3_141{flex:1;overflow:auto;-webkit-overflow-scrolling:touch}._diffPlaceholder_19bb3_147{flex:1;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:12px;color:#333;font-size:13px}._statusText_19bb3_158{color:#555;font-size:12px;padding:16px 12px;text-align:center}._errorText_19bb3_165{color:#ff6b6b;font-size:12px;padding:16px 12px;text-align:center}._emptyText_19bb3_172{color:#666;font-size:12px;padding:16px 12px;text-align:center}._warningText_19bb3_179{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px;color:#e2c08d;font-size:13px;text-align:center;gap:8px}._layout_1iry8_1{height:100vh;overflow:hidden}._header_1iry8_6{background:#111;border-bottom:1px solid #1f1f1f;padding:0 24px;height:60px;line-height:60px}._content_1iry8_14{flex:1;overflow:hidden}._mainContainer_1iry8_19{display:flex;height:100%}._leftPanel_1iry8_24{flex-shrink:0;border-right:1px solid #1f1f1f;display:flex;flex-direction:column;background:#0a0a0a}._leftPanelHeader_1iry8_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_1iry8_43{font-size:12px;color:#555;font-weight:400}._leftPanelBody_1iry8_49{flex:1;overflow:hidden}._rightPanel_1iry8_54{flex:1;overflow:hidden;background:#0d0d0d}._modalActions_1iry8_60{margin-bottom:12px}._spinCenter_1iry8_64{text-align:center;padding:40px}._emptyCenter_1iry8_69{text-align:center;color:#999;padding:40px}._logCheckbox_1iry8_75{margin-right:8px}._logListContainer_1iry8_79{background:#0d0d0d;border-radius:8px;overflow:hidden}._logListItem_1iry8_85{cursor:pointer;padding:8px 12px;border-bottom:1px solid #222}._logItemRow_1iry8_91{display:flex;align-items:center;width:100%;justify-content:space-between;flex-wrap:nowrap;gap:12px}._logItemRow_1iry8_91>span:first-child{display:flex;align-items:center;flex:1;min-width:0;overflow:hidden}._logFileName_1iry8_108{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._logItemRow_1iry8_91>span:last-child{display:flex;align-items:center;flex-shrink:0;gap:8px}._logFileIcon_1iry8_121{margin-right:8px;color:#3b82f6;flex-shrink:0}._loadingOverlay_1iry8_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_1iry8_140{color:#fff;font-size:16px;font-weight:700}._footer_1iry8_146{height:18px;background:#000;display:flex;align-items:center;justify-content:flex-end;padding:0 12px;flex-shrink:0}._footerRight_1iry8_156{display:flex;align-items:center;gap:6px;font-size:11px;color:#555}._footerText_1iry8_164{color:#444;margin-right:2px}._footerLink_1iry8_169{display:inline-flex;align-items:center;gap:3px;color:#555;text-decoration:none}._footerLink_1iry8_169:hover{color:#888}._footerIcon_1iry8_181{width:12px;height:12px}._footerDivider_1iry8_186{color:#333}._footerText_1iry8_164{color:#555}._guideContainer_1iry8_194{display:flex;align-items:center;justify-content:center;height:100%;background:#0a0a0a}._guideContent_1iry8_202{max-width:560px;padding:40px}._guideTitle_1iry8_207{font-size:20px;font-weight:600;color:#e0e0e0;margin:0 0 28px}._guideStep_1iry8_214{display:flex;gap:14px;margin-bottom:22px}._guideStepNum_1iry8_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_1iry8_235{flex:1;min-width:0}._guideText_1iry8_240{color:#aaa;font-size:14px;line-height:1.6;margin:0 0 8px}._guideCode_1iry8_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_1iry8_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_1iry8_272{transform:translate(0)}._mobileChatInner_1iry8_276{flex:1;min-height:0;display:flex;flex-direction:column;zoom:.6}._mobileGitDiffOverlay_1iry8_284{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}._mobileGitDiffOverlayVisible_1iry8_296{transform:translate(0)}._mobileGitDiffInner_1iry8_300{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-BtUV1IH_.js"></script>
10
- <link rel="stylesheet" crossorigin href="/assets/index-Cplbs2JB.css">
9
+ <script type="module" crossorigin src="/assets/index-7tdB1QJS.js"></script>
10
+ <link rel="stylesheet" crossorigin href="/assets/index-DZrvl093.css">
11
11
  </head>
12
12
  <body>
13
13
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-viewer",
3
- "version": "1.4.9",
3
+ "version": "1.4.11",
4
4
  "description": "Claude Code Logger visualization management tool",
5
5
  "license": "MIT",
6
6
  "main": "server.js",
package/server.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { createServer } from 'node:http';
2
2
  import { createConnection } from 'node:net';
3
3
  import { randomBytes } from 'node:crypto';
4
- import { readFileSync, writeFileSync, existsSync, watchFile, unwatchFile, statSync, readdirSync, renameSync, unlinkSync, openSync, readSync, closeSync } from 'node:fs';
4
+ import { readFileSync, writeFileSync, existsSync, watchFile, unwatchFile, statSync, readdirSync, renameSync, unlinkSync, openSync, readSync, closeSync, realpathSync } from 'node:fs';
5
5
  import { fileURLToPath } from 'node:url';
6
6
  import { dirname, join, extname } from 'node:path';
7
7
  import { homedir, userInfo, platform, networkInterfaces } from 'node:os';
@@ -772,14 +772,21 @@ function handleRequest(req, res) {
772
772
  }
773
773
 
774
774
  // 读取指定本地日志文件(支持 project/file 路径)
775
- if (url.startsWith('/api/local-log?') && method === 'GET') {
776
- const params = new URLSearchParams(url.split('?')[1]);
777
- const file = params.get('file');
775
+ if (url === '/api/local-log' && method === 'GET') {
776
+ const file = parsedUrl.searchParams.get('file');
778
777
  if (!file || file.includes('..')) {
779
778
  res.writeHead(400, { 'Content-Type': 'application/json' });
780
779
  res.end(JSON.stringify({ error: 'Invalid file name' }));
781
780
  return;
782
781
  }
782
+
783
+ // 验证文件类型:只允许 .jsonl 文件
784
+ if (!file.endsWith('.jsonl')) {
785
+ res.writeHead(400, { 'Content-Type': 'application/json' });
786
+ res.end(JSON.stringify({ error: 'Invalid file type. Only .jsonl files are allowed.' }));
787
+ return;
788
+ }
789
+
783
790
  const filePath = join(LOG_DIR, file);
784
791
  try {
785
792
  if (!existsSync(filePath)) {
@@ -787,6 +794,16 @@ function handleRequest(req, res) {
787
794
  res.end(JSON.stringify({ error: 'File not found' }));
788
795
  return;
789
796
  }
797
+
798
+ // 验证文件确实在 LOG_DIR 内(防止路径穿越)
799
+ const realPath = realpathSync(filePath);
800
+ const realLogDir = realpathSync(LOG_DIR);
801
+ if (!realPath.startsWith(realLogDir)) {
802
+ res.writeHead(403, { 'Content-Type': 'application/json' });
803
+ res.end(JSON.stringify({ error: 'Access denied' }));
804
+ return;
805
+ }
806
+
790
807
  const content = readFileSync(filePath, 'utf-8');
791
808
  const entries = content.split('\n---\n').filter(line => line.trim()).map(entry => {
792
809
  try { return JSON.parse(entry); } catch { return null; }
@@ -852,10 +869,9 @@ function handleRequest(req, res) {
852
869
  }
853
870
 
854
871
  // GET /api/concept?lang=zh&doc=Tool-Bash
855
- if (method === 'GET' && url.startsWith('/api/concept')) {
856
- const conceptParams = new URL(url, 'http://localhost').searchParams;
857
- const lang = conceptParams.get('lang') || 'zh';
858
- const doc = conceptParams.get('doc') || '';
872
+ if (method === 'GET' && url === '/api/concept') {
873
+ const lang = parsedUrl.searchParams.get('lang') || 'zh';
874
+ const doc = parsedUrl.searchParams.get('doc') || '';
859
875
  // 安全校验:只允许字母、数字、连字符
860
876
  if (!/^[a-zA-Z0-9-]+$/.test(doc) || !/^[a-z]{2}(-[a-zA-Z]{2,})?$/.test(lang)) {
861
877
  res.writeHead(400, { 'Content-Type': 'application/json' });