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.
- package/dist/assets/{index-Dq-eDVvb.js → index-BJXIuGDI.js} +177 -177
- package/dist/assets/{index-7ty6PCA6.css → index-Ca-rDbHa.css} +1 -1
- package/dist/index.html +2 -2
- package/interceptor.js +10 -3
- package/lib/extract-plugin-name.mjs +18 -0
- package/lib/interceptor-core.js +10 -3
- package/package.json +1 -1
- package/server.js +105 -2
|
@@ -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-
|
|
10
|
-
<link rel="stylesheet" crossorigin href="/assets/index-
|
|
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
|
-
|
|
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);
|
package/lib/interceptor-core.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
233
|
+
// 所有内容已迁移到新文件,删除空旧文件
|
|
234
|
+
try { unlinkSync(oldFile); } catch { }
|
|
228
235
|
}
|
|
229
236
|
} catch { }
|
|
230
237
|
}
|
package/package.json
CHANGED
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
|
-
|
|
1957
|
-
|
|
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
|
}
|