cc-viewer 1.6.7 → 1.6.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,7 +29,7 @@ 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_1k9rj_1{height:100%;display:flex;flex-direction:column;background:#0a0a0a}._terminalContainer_1k9rj_8{flex:1;overflow:hidden;padding:4px 8px;touch-action:none;overscroll-behavior:contain}._terminalToolbar_1k9rj_16{height:35px;flex-shrink:0;display:flex;align-items:center;padding:0 8px;gap:4px;border-top:1px solid #1f1f1f;background:#0d0d0d}._toolbarBtn_1k9rj_27{display:flex;align-items:center;gap:4px;padding:4px 10px;border:1px solid #333;border-radius:4px;background:#1a1a1a;color:#aaa;font-size:12px;cursor:pointer;white-space:nowrap}._toolbarBtn_1k9rj_27:hover{background:#2a2a2a;color:#ddd;border-color:#555}._toolbarBtn_1k9rj_27 svg{width:14px;height:14px}._virtualKeybar_1k9rj_52{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_1k9rj_52{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:pan-x;min-width:44px;min-height:44px;display:flex;align-items:center;justify-content:center}._virtualKeyPressed_1k9rj_83{background:#333;border-color:#555;color:#fff}._fileExplorer_dbq1c_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_dbq1c_12{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid #2a2a2a;flex-shrink:0}._headerTitle_dbq1c_21{font-size:11px;font-weight:600;color:#888;text-transform:uppercase;letter-spacing:.5px}._collapseBtn_dbq1c_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_dbq1c_29:hover{color:#ccc;background:#2a2a2a}._treeContainer_dbq1c_48{flex:1;overflow:auto;padding:4px 0}._treeItem_dbq1c_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_dbq1c_54:hover,._treeItemSelected_dbq1c_70{background:#1a1a1a}._arrow_dbq1c_74{width:16px;flex-shrink:0;color:#666;display:flex;align-items:center;justify-content:center}._icon_dbq1c_83{width:16px;height:16px;flex-shrink:0;margin-right:6px;display:flex;align-items:center;justify-content:center}._fileName_dbq1c_93{overflow:hidden;text-overflow:ellipsis}._loading_dbq1c_98{color:#555;font-size:12px;padding:4px 8px}._error_dbq1c_104{color:#ff6b6b;font-size:12px;padding:4px 8px}._treeItemGitIgnored_dbq1c_110{opacity:.4}._fileContentView_1mwk0_1{display:flex;flex-direction:column;height:100%;background:#0d0d0d}._editorBanner_1mwk0_8{padding:6px 16px;background:#1a3a2a;color:#4ade80;font-size:12px;text-align:center;flex-shrink:0;border-bottom:1px solid #2a5a3a;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background .15s}._editorBanner_1mwk0_8:hover{background:#245a3a}._header_1mwk0_25{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;border-bottom:1px solid #2a2a2a;background:#111;flex-shrink:0}._headerLeft_1mwk0_35{display:flex;align-items:center;gap:8px;flex:1;min-width:0}._headerRight_1mwk0_43{display:flex;align-items:center;gap:10px;flex-shrink:0}._backBtn_1mwk0_50{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_1mwk0_50:hover{color:#ccc;background:#1a1a1a}._filePath_1mwk0_71{font-size:13px;color:#ccc;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._fileSize_1mwk0_79{font-size:11px;color:#666;flex-shrink:0}._saveBtn_1mwk0_85{display:flex;align-items:center;gap:5px;padding:4px 12px;border:1px solid #3a3a3a;background:#1a1a1a;color:#ccc;font-size:12px;border-radius:6px;cursor:pointer;transition:background .15s,color .15s,border-color .15s;white-space:nowrap}._saveBtn_1mwk0_85:hover:not(:disabled){background:#2a2a2a;color:#fff;border-color:#4a4a4a}._saveBtn_1mwk0_85:disabled{opacity:.4;cursor:not-allowed}._saveStatus_1mwk0_111{font-size:11px;color:#888;white-space:nowrap}._saveStatusSaved_1mwk0_117{color:#4caf50}._saveStatusFailed_1mwk0_121{color:#ff6b6b}._contentContainer_1mwk0_125{flex:1;overflow:hidden;background:#0d0d0d;display:flex;min-height:0;min-width:0}._editorWrapper_1mwk0_134{flex:1;display:flex;min-height:0;min-width:0;overflow:hidden}._lineNumCol_1mwk0_142{flex-shrink:0;width:56px;overflow:hidden;background:#0d0d0d;border-right:1px solid #2a2a2a;-webkit-user-select:none;user-select:none;padding-top:4px}._lineNumRow_1mwk0_152{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}._editorCol_1mwk0_162{flex:1;min-width:0;min-height:0;display:flex}._editorCol_1mwk0_162 .cm-theme{flex:1;display:flex;min-height:0;min-width:0}._editorCol_1mwk0_162 .cm-editor{flex:1;min-width:0;min-height:0}._loading_1mwk0_182{display:flex;align-items:center;justify-content:center;height:100%;width:100%;color:#666;font-size:14px}._error_1mwk0_192{display:flex;align-items:center;justify-content:center;height:100%;width:100%;color:#ff6b6b;font-size:14px}._imageViewer_zpkv7_1{display:flex;flex-direction:column;height:100%;background:#0d0d0d}._header_zpkv7_8{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;border-bottom:1px solid #2a2a2a;background:#111;flex-shrink:0}._headerLeft_zpkv7_18{display:flex;align-items:center;gap:8px;flex:1;min-width:0}._headerRight_zpkv7_26{display:flex;align-items:center;gap:10px;flex-shrink:0}._backBtn_zpkv7_33{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_zpkv7_33:hover{color:#ccc;background:#1a1a1a}._filePath_zpkv7_54{font-size:13px;color:#ccc;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._fileSize_zpkv7_62{font-size:11px;color:#666;flex-shrink:0}._toolbar_zpkv7_68{display:flex;align-items:center;gap:4px;padding:6px 16px;background:#111;border-bottom:1px solid #2a2a2a;flex-shrink:0}._toolBtn_zpkv7_78{width:28px;height:28px;border:1px solid #3a3a3a;background:#1a1a1a;color:#999;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:6px;padding:0;transition:background .15s,color .15s,border-color .15s}._toolBtn_zpkv7_78:hover{background:#2a2a2a;color:#fff;border-color:#4a4a4a}._zoomLabel_zpkv7_99{font-size:11px;color:#888;min-width:42px;text-align:center;-webkit-user-select:none;user-select:none}._canvasArea_zpkv7_107{flex:1;overflow:hidden;position:relative;cursor:grab;background-color:#1a1a1a;background-image:linear-gradient(45deg,#222 25%,transparent 25%),linear-gradient(-45deg,#222 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#222 75%),linear-gradient(-45deg,transparent 75%,#222 75%);background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0}._canvasArea_zpkv7_107._dragging_zpkv7_122{cursor:grabbing}._imageWrap_zpkv7_126{position:absolute;top:0;left:0;transform-origin:0 0}._imageWrap_zpkv7_126 img{display:block;max-width:none;image-rendering:auto}._statusBar_zpkv7_139{display:flex;align-items:center;gap:16px;padding:4px 16px;background:#111;border-top:1px solid #2a2a2a;flex-shrink:0;font-size:11px;color:#666}._loading_zpkv7_151{display:flex;align-items:center;justify-content:center;height:100%;width:100%;color:#666;font-size:14px}._error_zpkv7_161{display:flex;align-items:center;justify-content:center;height:100%;width:100%;color:#ff6b6b;font-size:14px}._gitChanges_1in24_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_1in24_12{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid #2a2a2a;flex-shrink:0}._headerTitle_1in24_21{font-size:11px;font-weight:600;color:#888;text-transform:uppercase;letter-spacing:.5px}._collapseBtn_1in24_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_1in24_29:hover{color:#ccc;background:#2a2a2a}._changesContainer_1in24_48{flex:1;overflow:auto;padding:4px 0}._changeItem_1in24_54{display:flex;align-items:center;height:26px;padding:0 8px;cursor:pointer;color:#ccc;font-size:13px;white-space:nowrap;transition:background .1s;gap:6px}._changeItem_1in24_54:hover,._changeItemSelected_1in24_71{background:#1a1a1a}._dirItem_1in24_75{display:flex;align-items:center;height:26px;padding:0 8px;color:#999;font-size:13px;white-space:nowrap;gap:6px}._dirArrow_1in24_86{width:16px;flex-shrink:0;color:#666;display:flex;align-items:center;justify-content:center}._dirName_1in24_95{overflow:hidden;text-overflow:ellipsis}._status_1in24_100{width:16px;flex-shrink:0;font-size:11px;font-weight:600;text-align:center;margin-left:auto}._icon_1in24_109{width:16px;height:16px;flex-shrink:0;display:flex;align-items:center;justify-content:center}._fileName_1in24_118{overflow:hidden;text-overflow:ellipsis;flex:1}._loading_1in24_124{color:#555;font-size:12px;padding:8px 12px}._error_1in24_130{color:#ff6b6b;font-size:12px;padding:8px 12px}._empty_1in24_136{color:#666;font-size:12px;padding:8px 12px;text-align:center}pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
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_2havr_1{height:100%;display:flex;flex-direction:column;background:#0a0a0a}._terminalContainer_2havr_8{flex:1;overflow:hidden;padding:4px 8px;touch-action:none;overscroll-behavior:contain}._terminalContainer_2havr_8 .xterm-helper-textarea{caret-color:transparent!important}._terminalToolbar_2havr_21{height:35px;flex-shrink:0;display:flex;align-items:center;padding:0 8px;gap:4px;border-top:1px solid #1f1f1f;background:#0d0d0d}._toolbarBtn_2havr_32{display:flex;align-items:center;gap:4px;padding:4px 10px;border:1px solid #333;border-radius:4px;background:#1a1a1a;color:#aaa;font-size:12px;cursor:pointer;white-space:nowrap}._toolbarBtn_2havr_32:hover{background:#2a2a2a;color:#ddd;border-color:#555}._toolbarBtn_2havr_32 svg{width:14px;height:14px}._virtualKeybar_2havr_57{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_2havr_57{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:pan-x;min-width:44px;min-height:44px;display:flex;align-items:center;justify-content:center}._virtualKeyPressed_2havr_88{background:#333;border-color:#555;color:#fff}._fileExplorer_dbq1c_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_dbq1c_12{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid #2a2a2a;flex-shrink:0}._headerTitle_dbq1c_21{font-size:11px;font-weight:600;color:#888;text-transform:uppercase;letter-spacing:.5px}._collapseBtn_dbq1c_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_dbq1c_29:hover{color:#ccc;background:#2a2a2a}._treeContainer_dbq1c_48{flex:1;overflow:auto;padding:4px 0}._treeItem_dbq1c_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_dbq1c_54:hover,._treeItemSelected_dbq1c_70{background:#1a1a1a}._arrow_dbq1c_74{width:16px;flex-shrink:0;color:#666;display:flex;align-items:center;justify-content:center}._icon_dbq1c_83{width:16px;height:16px;flex-shrink:0;margin-right:6px;display:flex;align-items:center;justify-content:center}._fileName_dbq1c_93{overflow:hidden;text-overflow:ellipsis}._loading_dbq1c_98{color:#555;font-size:12px;padding:4px 8px}._error_dbq1c_104{color:#ff6b6b;font-size:12px;padding:4px 8px}._treeItemGitIgnored_dbq1c_110{opacity:.4}._fileContentView_1mwk0_1{display:flex;flex-direction:column;height:100%;background:#0d0d0d}._editorBanner_1mwk0_8{padding:6px 16px;background:#1a3a2a;color:#4ade80;font-size:12px;text-align:center;flex-shrink:0;border-bottom:1px solid #2a5a3a;cursor:pointer;-webkit-user-select:none;user-select:none;transition:background .15s}._editorBanner_1mwk0_8:hover{background:#245a3a}._header_1mwk0_25{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;border-bottom:1px solid #2a2a2a;background:#111;flex-shrink:0}._headerLeft_1mwk0_35{display:flex;align-items:center;gap:8px;flex:1;min-width:0}._headerRight_1mwk0_43{display:flex;align-items:center;gap:10px;flex-shrink:0}._backBtn_1mwk0_50{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_1mwk0_50:hover{color:#ccc;background:#1a1a1a}._filePath_1mwk0_71{font-size:13px;color:#ccc;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._fileSize_1mwk0_79{font-size:11px;color:#666;flex-shrink:0}._saveBtn_1mwk0_85{display:flex;align-items:center;gap:5px;padding:4px 12px;border:1px solid #3a3a3a;background:#1a1a1a;color:#ccc;font-size:12px;border-radius:6px;cursor:pointer;transition:background .15s,color .15s,border-color .15s;white-space:nowrap}._saveBtn_1mwk0_85:hover:not(:disabled){background:#2a2a2a;color:#fff;border-color:#4a4a4a}._saveBtn_1mwk0_85:disabled{opacity:.4;cursor:not-allowed}._saveStatus_1mwk0_111{font-size:11px;color:#888;white-space:nowrap}._saveStatusSaved_1mwk0_117{color:#4caf50}._saveStatusFailed_1mwk0_121{color:#ff6b6b}._contentContainer_1mwk0_125{flex:1;overflow:hidden;background:#0d0d0d;display:flex;min-height:0;min-width:0}._editorWrapper_1mwk0_134{flex:1;display:flex;min-height:0;min-width:0;overflow:hidden}._lineNumCol_1mwk0_142{flex-shrink:0;width:56px;overflow:hidden;background:#0d0d0d;border-right:1px solid #2a2a2a;-webkit-user-select:none;user-select:none;padding-top:4px}._lineNumRow_1mwk0_152{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}._editorCol_1mwk0_162{flex:1;min-width:0;min-height:0;display:flex}._editorCol_1mwk0_162 .cm-theme{flex:1;display:flex;min-height:0;min-width:0}._editorCol_1mwk0_162 .cm-editor{flex:1;min-width:0;min-height:0}._loading_1mwk0_182{display:flex;align-items:center;justify-content:center;height:100%;width:100%;color:#666;font-size:14px}._error_1mwk0_192{display:flex;align-items:center;justify-content:center;height:100%;width:100%;color:#ff6b6b;font-size:14px}._imageViewer_zpkv7_1{display:flex;flex-direction:column;height:100%;background:#0d0d0d}._header_zpkv7_8{display:flex;align-items:center;justify-content:space-between;padding:10px 16px;border-bottom:1px solid #2a2a2a;background:#111;flex-shrink:0}._headerLeft_zpkv7_18{display:flex;align-items:center;gap:8px;flex:1;min-width:0}._headerRight_zpkv7_26{display:flex;align-items:center;gap:10px;flex-shrink:0}._backBtn_zpkv7_33{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_zpkv7_33:hover{color:#ccc;background:#1a1a1a}._filePath_zpkv7_54{font-size:13px;color:#ccc;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}._fileSize_zpkv7_62{font-size:11px;color:#666;flex-shrink:0}._toolbar_zpkv7_68{display:flex;align-items:center;gap:4px;padding:6px 16px;background:#111;border-bottom:1px solid #2a2a2a;flex-shrink:0}._toolBtn_zpkv7_78{width:28px;height:28px;border:1px solid #3a3a3a;background:#1a1a1a;color:#999;cursor:pointer;display:flex;align-items:center;justify-content:center;border-radius:6px;padding:0;transition:background .15s,color .15s,border-color .15s}._toolBtn_zpkv7_78:hover{background:#2a2a2a;color:#fff;border-color:#4a4a4a}._zoomLabel_zpkv7_99{font-size:11px;color:#888;min-width:42px;text-align:center;-webkit-user-select:none;user-select:none}._canvasArea_zpkv7_107{flex:1;overflow:hidden;position:relative;cursor:grab;background-color:#1a1a1a;background-image:linear-gradient(45deg,#222 25%,transparent 25%),linear-gradient(-45deg,#222 25%,transparent 25%),linear-gradient(45deg,transparent 75%,#222 75%),linear-gradient(-45deg,transparent 75%,#222 75%);background-size:20px 20px;background-position:0 0,0 10px,10px -10px,-10px 0}._canvasArea_zpkv7_107._dragging_zpkv7_122{cursor:grabbing}._imageWrap_zpkv7_126{position:absolute;top:0;left:0;transform-origin:0 0}._imageWrap_zpkv7_126 img{display:block;max-width:none;image-rendering:auto}._statusBar_zpkv7_139{display:flex;align-items:center;gap:16px;padding:4px 16px;background:#111;border-top:1px solid #2a2a2a;flex-shrink:0;font-size:11px;color:#666}._loading_zpkv7_151{display:flex;align-items:center;justify-content:center;height:100%;width:100%;color:#666;font-size:14px}._error_zpkv7_161{display:flex;align-items:center;justify-content:center;height:100%;width:100%;color:#ff6b6b;font-size:14px}._gitChanges_1in24_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_1in24_12{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;border-bottom:1px solid #2a2a2a;flex-shrink:0}._headerTitle_1in24_21{font-size:11px;font-weight:600;color:#888;text-transform:uppercase;letter-spacing:.5px}._collapseBtn_1in24_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_1in24_29:hover{color:#ccc;background:#2a2a2a}._changesContainer_1in24_48{flex:1;overflow:auto;padding:4px 0}._changeItem_1in24_54{display:flex;align-items:center;height:26px;padding:0 8px;cursor:pointer;color:#ccc;font-size:13px;white-space:nowrap;transition:background .1s;gap:6px}._changeItem_1in24_54:hover,._changeItemSelected_1in24_71{background:#1a1a1a}._dirItem_1in24_75{display:flex;align-items:center;height:26px;padding:0 8px;color:#999;font-size:13px;white-space:nowrap;gap:6px}._dirArrow_1in24_86{width:16px;flex-shrink:0;color:#666;display:flex;align-items:center;justify-content:center}._dirName_1in24_95{overflow:hidden;text-overflow:ellipsis}._status_1in24_100{width:16px;flex-shrink:0;font-size:11px;font-weight:600;text-align:center;margin-left:auto}._icon_1in24_109{width:16px;height:16px;flex-shrink:0;display:flex;align-items:center;justify-content:center}._fileName_1in24_118{overflow:hidden;text-overflow:ellipsis;flex:1}._loading_1in24_124{color:#555;font-size:12px;padding:8px 12px}._error_1in24_130{color:#ff6b6b;font-size:12px;padding:8px 12px}._empty_1in24_136{color:#666;font-size:12px;padding:8px 12px;text-align:center}pre code.hljs{display:block;overflow-x:auto;padding:1em}code.hljs{padding:3px 5px}/*!
33
33
  Theme: GitHub Dark
34
34
  Description: Dark theme as seen on github.com
35
35
  Author: github.com
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-Dq-eDVvb.js"></script>
10
- <link rel="stylesheet" crossorigin href="/assets/index-7ty6PCA6.css">
9
+ <script type="module" crossorigin src="/assets/index-BJXIuGDI.js"></script>
10
+ <link rel="stylesheet" crossorigin href="/assets/index-Ca-rDbHa.css">
11
11
  </head>
12
12
  <body>
13
13
  <div id="root"></div>
package/interceptor.js CHANGED
@@ -64,12 +64,19 @@ function resolveResumeChoice(choice) {
64
64
  }
65
65
  LOG_FILE = recentFile;
66
66
  } else {
67
- // new: 将临时文件 rename 为正式新日志文件名
67
+ // new: 将临时文件 rename 为正式新日志文件名(空文件直接删除)
68
68
  const newPath = tempFile.replace('_temp.jsonl', '.jsonl');
69
+ let useNew = false;
69
70
  if (existsSync(tempFile)) {
70
- renameSync(tempFile, newPath);
71
+ const sz = statSync(tempFile).size;
72
+ if (sz > 0) {
73
+ renameSync(tempFile, newPath);
74
+ useNew = true;
75
+ } else {
76
+ try { unlinkSync(tempFile); } catch { }
77
+ }
71
78
  }
72
- LOG_FILE = newPath;
79
+ LOG_FILE = useNew ? newPath : recentFile || '';
73
80
  }
74
81
  } catch (err) {
75
82
  console.error('[CC Viewer] resolveResumeChoice error:', err);
@@ -0,0 +1,18 @@
1
+ /**
2
+ * 在隔离子进程中提取插件 name,避免不安全的插件代码影响主进程。
3
+ * 用法: node lib/extract-plugin-name.mjs <file-path>
4
+ * 输出: JSON { name: string } 到 stdout
5
+ */
6
+ const filePath = process.argv[2];
7
+ if (!filePath) {
8
+ process.stdout.write(JSON.stringify({ name: '' }));
9
+ process.exit(0);
10
+ }
11
+ try {
12
+ const mod = await import(`file://${filePath}`);
13
+ const plugin = mod.default || mod;
14
+ process.stdout.write(JSON.stringify({ name: plugin.name || '' }));
15
+ } catch {
16
+ process.stdout.write(JSON.stringify({ name: '' }));
17
+ }
18
+ process.exit(0);
@@ -1,4 +1,4 @@
1
- import { appendFileSync, existsSync, readdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from 'node:fs';
1
+ import { appendFileSync, existsSync, readdirSync, readFileSync, renameSync, statSync, unlinkSync, writeFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
 
4
4
  const SUBAGENT_SYSTEM_RE = /(?:command execution|file search|planning) specialist|general-purpose agent/i;
@@ -172,7 +172,13 @@ export function cleanupTempFiles(dir, projectName) {
172
172
  }
173
173
  unlinkSync(tempPath);
174
174
  } else {
175
- renameSync(tempPath, newPath);
175
+ // 只有非空 temp 文件才 rename,空文件直接删除
176
+ const sz = statSync(tempPath).size;
177
+ if (sz > 0) {
178
+ renameSync(tempPath, newPath);
179
+ } else {
180
+ unlinkSync(tempPath);
181
+ }
176
182
  }
177
183
  } catch { }
178
184
  }
@@ -224,7 +230,8 @@ export function migrateConversationContext(oldFile, newFile) {
224
230
  if (remainingParts.length > 0) {
225
231
  writeFileSync(oldFile, remainingParts.join('\n---\n') + '\n---\n');
226
232
  } else {
227
- writeFileSync(oldFile, '');
233
+ // 所有内容已迁移到新文件,删除空旧文件
234
+ try { unlinkSync(oldFile); } catch { }
228
235
  }
229
236
  } catch { }
230
237
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cc-viewer",
3
- "version": "1.6.7",
3
+ "version": "1.6.9",
4
4
  "description": "Claude Code Logger visualization management tool",
5
5
  "license": "MIT",
6
6
  "main": "server.js",
package/server.js CHANGED
@@ -1262,6 +1262,102 @@ async function handleRequest(req, res) {
1262
1262
  return;
1263
1263
  }
1264
1264
 
1265
+ if (url === '/api/plugins/install-from-url' && method === 'POST') {
1266
+ let body = '';
1267
+ req.on('data', chunk => { body += chunk; if (body.length > MAX_POST_BODY) req.destroy(); });
1268
+ req.on('end', async () => {
1269
+ try {
1270
+ const { url: fileUrl } = JSON.parse(body);
1271
+ if (!fileUrl) {
1272
+ res.writeHead(400, { 'Content-Type': 'application/json' });
1273
+ res.end(JSON.stringify({ error: 'URL is required' }));
1274
+ return;
1275
+ }
1276
+ // 验证 URL 格式
1277
+ let parsedUrl;
1278
+ try {
1279
+ parsedUrl = new URL(fileUrl);
1280
+ } catch {
1281
+ res.writeHead(400, { 'Content-Type': 'application/json' });
1282
+ res.end(JSON.stringify({ error: 'Invalid URL' }));
1283
+ return;
1284
+ }
1285
+ if (parsedUrl.protocol !== 'http:' && parsedUrl.protocol !== 'https:') {
1286
+ res.writeHead(400, { 'Content-Type': 'application/json' });
1287
+ res.end(JSON.stringify({ error: 'Invalid URL' }));
1288
+ return;
1289
+ }
1290
+ // 下载远程文件(限制 5MB,超时 30s)
1291
+ const MAX_PLUGIN_SIZE = 5 * 1024 * 1024;
1292
+ let content;
1293
+ try {
1294
+ const resp = await fetch(fileUrl, { signal: AbortSignal.timeout(30000) });
1295
+ if (!resp.ok) throw new Error(`HTTP ${resp.status}`);
1296
+ const text = await resp.text();
1297
+ if (text.length > MAX_PLUGIN_SIZE) throw new Error('File too large (max 5MB)');
1298
+ content = text;
1299
+ } catch (fetchErr) {
1300
+ res.writeHead(500, { 'Content-Type': 'application/json' });
1301
+ res.end(JSON.stringify({ error: 'Failed to fetch: ' + fetchErr.message }));
1302
+ return;
1303
+ }
1304
+ // 通过子进程 import() 提取插件内部 name
1305
+ let saveName = '';
1306
+ const { tmpdir } = await import('node:os');
1307
+ const tmpFile = join(tmpdir(), `ccv-install-${Date.now()}.mjs`);
1308
+ writeFileSync(tmpFile, content, 'utf-8');
1309
+ try {
1310
+ const extractScript = join(__dirname, 'lib', 'extract-plugin-name.mjs');
1311
+ const result = await new Promise((resolve, reject) => {
1312
+ execFile('node', [extractScript, tmpFile], { timeout: 5000 }, (err, stdout) => {
1313
+ if (err) return reject(err);
1314
+ resolve(stdout);
1315
+ });
1316
+ });
1317
+ const parsed = JSON.parse(result);
1318
+ if (parsed.name) saveName = parsed.name;
1319
+ } catch { }
1320
+ try { unlinkSync(tmpFile); } catch { }
1321
+ // fallback:从 URL 路径提取文件名,排除通用名称
1322
+ if (!saveName) {
1323
+ const urlFilename = parsedUrl.pathname.split('/').pop();
1324
+ if (urlFilename && (urlFilename.endsWith('.js') || urlFilename.endsWith('.mjs'))
1325
+ && urlFilename !== 'index.js' && urlFilename !== 'index.mjs') {
1326
+ saveName = urlFilename.replace(/\.(js|mjs)$/, '');
1327
+ }
1328
+ }
1329
+ // 最终 fallback:使用 plugin-<timestamp>
1330
+ if (!saveName) {
1331
+ saveName = `plugin-${Date.now()}`;
1332
+ }
1333
+ let filename = (saveName.endsWith('.js') || saveName.endsWith('.mjs')) ? saveName : saveName + '.js';
1334
+ // 安全校验
1335
+ if (filename.includes('..') || filename.includes('/') || filename.includes('\\')) {
1336
+ filename = `plugin-${Date.now()}.js`;
1337
+ }
1338
+ // 确保插件目录存在
1339
+ if (!existsSync(PLUGINS_DIR)) {
1340
+ mkdirSync(PLUGINS_DIR, { recursive: true });
1341
+ }
1342
+ // 同名文件去重:追加唯一标识
1343
+ if (existsSync(join(PLUGINS_DIR, filename))) {
1344
+ const ext = filename.endsWith('.mjs') ? '.mjs' : '.js';
1345
+ const base = filename.slice(0, -ext.length);
1346
+ filename = `${base}-${Date.now()}${ext}`;
1347
+ }
1348
+ writeFileSync(join(PLUGINS_DIR, filename), content, 'utf-8');
1349
+ await loadPlugins();
1350
+ const plugins = getPluginsInfo();
1351
+ res.writeHead(200, { 'Content-Type': 'application/json' });
1352
+ res.end(JSON.stringify({ ok: true, plugins, pluginsDir: PLUGINS_DIR }));
1353
+ } catch (err) {
1354
+ res.writeHead(500, { 'Content-Type': 'application/json' });
1355
+ res.end(JSON.stringify({ error: err.message }));
1356
+ }
1357
+ });
1358
+ return;
1359
+ }
1360
+
1265
1361
  // 返回局域网访问地址
1266
1362
  if (url === '/api/local-url' && method === 'GET') {
1267
1363
  const localIp = getLocalIp();
@@ -1300,6 +1396,7 @@ async function handleRequest(req, res) {
1300
1396
  const ts = match[2];
1301
1397
  const filePath = join(projectDir, f);
1302
1398
  const size = statSync(filePath).size;
1399
+ if (size === 0) continue; // 跳过空文件
1303
1400
  const turns = statsFiles?.[f]?.summary?.sessionCount || 0;
1304
1401
  if (!grouped[project]) grouped[project] = [];
1305
1402
  grouped[project].push({ file: `${project}/${f}`, timestamp: ts, size, turns, preview: statsFiles?.[f]?.preview || [] });
@@ -1953,8 +2050,14 @@ async function _doStop() {
1953
2050
  try {
1954
2051
  const { tempFile } = _resumeState;
1955
2052
  if (existsSync(tempFile)) {
1956
- const newPath = tempFile.replace('_temp.jsonl', '.jsonl');
1957
- renameSync(tempFile, newPath);
2053
+ // 只有非空 temp 文件才 rename 为正式文件,空文件直接删除
2054
+ const sz = statSync(tempFile).size;
2055
+ if (sz > 0) {
2056
+ const newPath = tempFile.replace('_temp.jsonl', '.jsonl');
2057
+ renameSync(tempFile, newPath);
2058
+ } else {
2059
+ unlinkSync(tempFile);
2060
+ }
1958
2061
  }
1959
2062
  } catch { }
1960
2063
  }