codex-lens 0.1.35 → 0.1.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29,4 +29,4 @@
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 .xterm-scroll-area{visibility:hidden}.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{-webkit-user-select:text;user-select:text;white-space:pre}.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}:root{--bg-primary: #000000;--bg-secondary: #0A0A0A;--bg-tertiary: #141414;--bg-elevated: #1A1A1A;--bg-surface: #0F0F0F;--text-primary: #F8FAFC;--text-secondary: #94A3B8;--text-muted: #64748B;--border-color: rgba(148, 163, 184, .15);--border-glow: rgba(34, 197, 94, .3);--accent-color: #22C55E;--accent-hover: #16A34A;--accent-glow: rgba(34, 197, 94, .4);--accent-soft: rgba(34, 197, 94, .1);--diff-add-bg: rgba(34, 197, 94, .12);--diff-add-text: #4ADE80;--diff-add-border: #22C55E;--diff-remove-bg: rgba(239, 68, 68, .12);--diff-remove-text: #F87171;--diff-remove-border: #EF4444;--danger-color: #EF4444;--danger-hover: #DC2626;--success-color: #22C55E;--success-hover: #16A34A;--warning-color: #F59E0B;--info-color: #3B82F6;--font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--font-display: "Space Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--font-mono: "JetBrains Mono", "Fira Code", "SF Mono", "Consolas", monospace;--shadow-xs: 0 1px 2px rgba(0, 0, 0, .2);--shadow-sm: 0 2px 4px rgba(0, 0, 0, .2);--shadow-md: 0 4px 12px rgba(0, 0, 0, .3);--shadow-lg: 0 8px 24px rgba(0, 0, 0, .4);--shadow-xl: 0 16px 48px rgba(0, 0, 0, .5);--shadow-glow: 0 0 24px var(--accent-glow);--shadow-glow-sm: 0 0 12px var(--accent-glow);--radius-xs: 4px;--radius-sm: 6px;--radius-md: 10px;--radius-lg: 14px;--radius-xl: 20px;--transition-fast: .12s ease;--transition-normal: .2s ease;--transition-slow: .3s ease;--blur-sm: 8px;--blur-md: 16px;--blur-lg: 24px}@media (prefers-reduced-motion: reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}*{margin:0;padding:0;box-sizing:border-box}html,body,#root{height:100%;width:100%;overflow:hidden}body{font-family:var(--font-family);background:var(--bg-primary);color:var(--text-primary);font-size:14px;line-height:1.6;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.app-container{display:flex;flex-direction:column;height:100vh;width:100vw;background:var(--bg-primary)}.top-bar{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;background:linear-gradient(180deg,#1e293bf2,#1e293bd9);-webkit-backdrop-filter:blur(var(--blur-md));backdrop-filter:blur(var(--blur-md));border-bottom:1px solid var(--border-color);min-height:52px;position:relative;z-index:100}.top-bar:after{content:"";position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--accent-color),transparent);opacity:.3}.top-bar-left,.top-bar-center,.top-bar-right{display:flex;align-items:center;gap:16px}.top-bar-left{width:260px}.top-bar-center{flex:1;justify-content:center}.top-bar-right{width:40%;justify-content:flex-end}.top-bar-title{font-family:var(--font-display);font-weight:600;font-size:13px;text-transform:uppercase;letter-spacing:1px;color:var(--text-secondary);display:flex;align-items:center;gap:8px}.top-bar-title:before{content:"";display:inline-block;width:3px;height:14px;background:var(--accent-color);border-radius:2px}.main-content{display:flex;flex:1;overflow:hidden;gap:1px;background:var(--border-color)}.panel{display:flex;flex-direction:column;overflow:hidden;background:linear-gradient(180deg,var(--bg-secondary) 0%,rgba(30,41,59,.95) 100%)}.left-panel{width:260px;flex-shrink:0}.middle-panel{flex:1;min-width:300px}.right-panel{width:40%;min-width:300px;max-width:60%}.panel-content{flex:1;overflow:auto;padding:8px}.file-tree{padding:4px}.file-item{padding:8px 12px;cursor:pointer;border-radius:var(--radius-sm);display:flex;align-items:center;gap:10px;transition:all var(--transition-fast);position:relative;margin:2px 0}.file-item:before{content:"";position:absolute;left:0;top:50%;transform:translateY(-50%);width:3px;height:0;background:var(--accent-color);border-radius:0 2px 2px 0;transition:height var(--transition-fast)}.file-item:hover{background:#94a3b814}.file-item:hover:before{height:60%}.file-item:active{transform:scale(.98)}.file-item.active{background:var(--accent-soft);color:var(--text-primary)}.file-item.active:before{height:70%}.file-icon{width:18px;height:18px;display:flex;align-items:center;justify-content:center;font-size:14px;opacity:.9}.file-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px}.diff-line{font-family:var(--font-mono);font-size:13px;padding:3px 16px 3px 20px;white-space:pre;border-left:3px solid transparent;transition:background var(--transition-fast);position:relative}.diff-line.added{background:var(--diff-add-bg);color:var(--diff-add-text);border-left-color:var(--diff-add-border)}.diff-line.removed{background:var(--diff-remove-bg);color:var(--diff-remove-text);border-left-color:var(--diff-remove-border)}.diff-line:before{display:inline-block;width:16px;margin-left:-16px;text-align:center;font-weight:600;font-size:12px}.diff-line.added:before{content:"+";color:var(--diff-add-text)}.diff-line.removed:before{content:"-";color:var(--diff-remove-text)}.tab-bar{display:flex;background:#0f172a99;border-bottom:1px solid var(--border-color);overflow-x:auto;min-height:40px;scrollbar-width:none}.tab-bar::-webkit-scrollbar{display:none}.tab{display:flex;align-items:center;gap:8px;padding:10px 16px;background:transparent;border-right:1px solid var(--border-color);cursor:pointer;min-width:100px;max-width:180px;font-size:13px;color:var(--text-muted);transition:all var(--transition-fast);position:relative}.tab:hover{background:#94a3b80d;color:var(--text-secondary)}.tab.active{background:var(--bg-secondary);color:var(--text-primary)}.tab.active:after{content:"";position:absolute;bottom:0;left:0;right:0;height:2px;background:var(--accent-color)}.tab-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tab-close{background:none;border:none;color:var(--text-muted);font-size:16px;cursor:pointer;padding:2px 6px;border-radius:var(--radius-xs);line-height:1;transition:all var(--transition-fast);opacity:.6}.tab-close:hover{background:#ef444433;color:var(--danger-color);opacity:1}.tab.modified .tab-name{color:var(--accent-color)}.tab-modified-mark{color:var(--accent-color);margin-right:4px;font-size:10px}.context-menu{position:fixed;background:linear-gradient(180deg,var(--bg-tertiary) 0%,var(--bg-secondary) 100%);border:1px solid var(--border-color);border-radius:var(--radius-md);padding:6px;min-width:160px;box-shadow:var(--shadow-lg);z-index:1000;animation:contextMenuIn .15s ease;-webkit-backdrop-filter:blur(var(--blur-sm));backdrop-filter:blur(var(--blur-sm))}@keyframes contextMenuIn{0%{opacity:0;transform:scale(.95) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}.context-menu-item{padding:10px 14px;cursor:pointer;font-size:13px;color:var(--text-primary);border-radius:var(--radius-sm);transition:all var(--transition-fast)}.context-menu-item:hover{background:var(--accent-soft);color:var(--accent-color)}.file-context-menu{position:fixed;background:linear-gradient(180deg,var(--bg-tertiary) 0%,var(--bg-secondary) 100%);border:1px solid var(--border-color);border-radius:var(--radius-md);padding:6px;min-width:200px;box-shadow:var(--shadow-lg);z-index:1000;animation:contextMenuIn .15s ease;-webkit-backdrop-filter:blur(var(--blur-sm));backdrop-filter:blur(var(--blur-sm))}.ws-status{display:inline-block;width:8px;height:8px;border-radius:50%;margin-left:8px;transition:all var(--transition-normal)}.ws-status.connected{background:var(--success-color);box-shadow:0 0 8px var(--success-color);animation:pulse 2s infinite}.ws-status.disconnected{background:var(--danger-color);box-shadow:0 0 8px var(--danger-color)}@keyframes pulse{0%,to{opacity:1;box-shadow:0 0 8px var(--success-color)}50%{opacity:.7;box-shadow:0 0 4px var(--success-color)}}.version-info{display:flex;align-items:center;gap:10px}.version-number{font-size:11px;color:var(--text-muted);font-weight:500;font-family:var(--font-mono);padding:3px 8px;background:#94a3b81a;border-radius:var(--radius-xs)}.update-badge{font-size:10px;padding:4px 10px;background:linear-gradient(135deg,var(--warning-color) 0%,#FBBF24 100%);color:var(--bg-primary);border-radius:var(--radius-sm);cursor:pointer;font-weight:600;transition:all var(--transition-fast)}.update-badge:hover{transform:translateY(-1px);box-shadow:0 4px 12px #f59e0b4d}.terminal-wrapper{flex:1;overflow:hidden;min-height:0}.section{margin-bottom:8px}.section-title{padding:10px 12px 6px;font-size:10px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.8px}.empty-state{padding:40px 24px;text-align:center;color:var(--text-muted);font-size:13px;display:flex;flex-direction:column;align-items:center;gap:12px}.empty-state:before{content:"";width:48px;height:48px;background:linear-gradient(135deg,var(--bg-tertiary) 0%,var(--bg-elevated) 100%);border-radius:var(--radius-lg);display:flex;align-items:center;justify-content:center}.code-panel{font-family:var(--font-mono)}.code-viewer-codemirror{height:100%;width:100%;display:flex;min-height:0;min-width:0}.code-viewer-codemirror .cm-theme{flex:1;display:flex;min-height:0;min-width:0}.code-viewer-codemirror .cm-editor{flex:1;min-width:0;min-height:0}.code-viewer-codemirror .cm-scroller{flex:1;overflow:auto!important;min-height:0}.code-content{padding:16px;white-space:pre-wrap;word-break:break-all;line-height:1.7;font-size:13px}.diff-container{font-family:var(--font-mono);font-size:13px;padding:8px 0}.task-btn{padding:8px 18px;border:none;border-radius:var(--radius-sm);font-size:12px;font-weight:600;cursor:pointer;transition:all var(--transition-fast);font-family:var(--font-family);display:inline-flex;align-items:center;gap:6px}.task-btn:hover{transform:translateY(-1px)}.task-btn:active{transform:translateY(0)}.task-btn-clear{background:transparent;color:var(--text-secondary);border:1px solid var(--border-color)}.task-btn-clear:hover{background:var(--accent-soft);border-color:var(--accent-color);color:var(--accent-color);box-shadow:var(--shadow-glow-sm)}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--bg-elevated);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--text-muted)}::-webkit-scrollbar-corner{background:transparent}.git-status-bar{display:flex;align-items:center;gap:16px;padding:6px 14px;background:#94a3b814;border-radius:var(--radius-sm);border:1px solid var(--border-color)}.git-branch{display:flex;align-items:center;gap:6px;font-family:var(--font-mono);font-size:12px;font-weight:600;color:var(--accent-color)}.git-branch-icon{font-size:14px;opacity:.8}.git-stats{display:flex;align-items:center;gap:12px}.git-staged,.git-unstaged{display:flex;align-items:center;gap:4px;font-size:11px;color:var(--text-secondary)}.git-staged-count{font-weight:600;color:var(--success-color)}.git-unstaged-count{font-weight:600;color:var(--warning-color)}.git-changes-btn{padding:4px 10px;font-size:11px;background:transparent;border:1px solid var(--border-color);border-radius:var(--radius-xs);color:var(--text-secondary);cursor:pointer;transition:all var(--transition-fast)}.git-changes-btn:hover{background:var(--accent-soft);border-color:var(--accent-color);color:var(--accent-color)}.staged-changes-panel{position:absolute;top:52px;left:0;right:0;max-height:400px;background:linear-gradient(180deg,var(--bg-tertiary) 0%,var(--bg-secondary) 100%);border-bottom:1px solid var(--border-color);z-index:99;overflow-y:auto;animation:slideDown .2s ease}@keyframes slideDown{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.staged-panel-header{display:flex;justify-content:space-between;align-items:center;padding:10px 16px;background:#0f172a99;border-bottom:1px solid var(--border-color);font-weight:600;font-size:12px;color:var(--text-secondary)}.staged-panel-actions{display:flex;gap:8px;align-items:center}.stage-btn,.unstage-btn{padding:4px 10px;font-size:11px;background:var(--bg-elevated);border:1px solid var(--border-color);border-radius:var(--radius-xs);color:var(--text-secondary);cursor:pointer;transition:all var(--transition-fast)}.stage-btn:hover,.unstage-btn:hover{background:var(--accent-soft);border-color:var(--accent-color);color:var(--accent-color)}.close-btn{width:24px;height:24px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;color:var(--text-muted);cursor:pointer;font-size:16px;border-radius:var(--radius-xs);transition:all var(--transition-fast)}.close-btn:hover{background:#ef444433;color:var(--danger-color)}.changes-section{padding:8px 0;border-bottom:1px solid var(--border-color)}.changes-section:last-child{border-bottom:none}.changes-section-header{padding:4px 16px}.changes-section-title{font-size:10px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.5px}.changes-list{display:flex;flex-direction:column}.change-item{display:flex;align-items:center;gap:8px;padding:6px 16px;cursor:pointer;transition:background var(--transition-fast)}.change-item:hover{background:#94a3b814}.change-item.staged{background:var(--accent-soft)}.change-icon{width:16px;text-align:center;font-size:12px;color:var(--text-muted)}.change-item.staged .change-icon{color:var(--success-color)}.change-status{width:14px;height:14px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;font-family:var(--font-mono);border-radius:2px}.change-status.M{background:var(--warning-color);color:var(--bg-primary)}.change-status.A{background:var(--success-color);color:var(--bg-primary)}.change-status.D{background:var(--danger-color);color:var(--text-primary)}.change-status.R{background:var(--info-color);color:var(--text-primary)}.change-status.\?{background:var(--text-muted);color:var(--bg-primary)}.change-path{flex:1;font-size:12px;font-family:var(--font-mono);color:var(--text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.no-changes{padding:24px;text-align:center;color:var(--text-muted);font-size:13px}.commit-section{display:flex;gap:8px;padding:12px 16px;background:#0f172a99;border-top:1px solid var(--border-color)}.commit-input{flex:1;padding:8px 12px;background:var(--bg-primary);border:1px solid var(--border-color);border-radius:var(--radius-sm);color:var(--text-primary);font-size:12px;font-family:var(--font-family)}.commit-input:focus{outline:none;border-color:var(--accent-color)}.commit-btn{padding:8px 16px;background:var(--accent-color);border:none;border-radius:var(--radius-sm);color:var(--bg-primary);font-size:12px;font-weight:600;cursor:pointer;transition:all var(--transition-fast)}.commit-btn:hover{background:var(--accent-hover);transform:translateY(-1px)}.file-git-badge{width:16px;height:16px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;font-family:var(--font-mono);border-radius:3px;margin-left:auto;flex-shrink:0}.file-git-badge.staged{background:var(--success-color);color:#000}.file-git-badge.wt{background:var(--warning-color);color:#000}.file-git-badge.untracked{background:var(--text-muted);color:#fff}@media (max-width: 1024px){.left-panel{width:220px}.right-panel{width:45%;min-width:250px}.top-bar-left{width:220px}}@media (max-width: 768px){.main-content{flex-direction:column}.left-panel,.right-panel{width:100%;max-width:none;min-width:auto}.middle-panel{min-height:300px}.top-bar{flex-wrap:wrap;padding:10px 16px}.top-bar-left,.top-bar-center,.top-bar-right{width:auto}.top-bar-center{order:3;width:100%;justify-content:flex-start;margin-top:8px;padding-top:8px;border-top:1px solid var(--border-color)}}
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 .xterm-scroll-area{visibility:hidden}.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{-webkit-user-select:text;user-select:text;white-space:pre}.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}:root{--bg-primary: #000000;--bg-secondary: #0A0A0A;--bg-tertiary: #141414;--bg-elevated: #1A1A1A;--bg-surface: #0F0F0F;--text-primary: #F8FAFC;--text-secondary: #94A3B8;--text-muted: #64748B;--border-color: rgba(148, 163, 184, .15);--border-glow: rgba(34, 197, 94, .3);--accent-color: #22C55E;--accent-hover: #16A34A;--accent-glow: rgba(34, 197, 94, .4);--accent-soft: rgba(34, 197, 94, .1);--diff-add-bg: rgba(34, 197, 94, .12);--diff-add-text: #4ADE80;--diff-add-border: #22C55E;--diff-remove-bg: rgba(239, 68, 68, .12);--diff-remove-text: #F87171;--diff-remove-border: #EF4444;--danger-color: #EF4444;--danger-hover: #DC2626;--success-color: #22C55E;--success-hover: #16A34A;--warning-color: #F59E0B;--info-color: #3B82F6;--font-family: "DM Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;--font-display: "Space Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;--font-mono: "JetBrains Mono", "Fira Code", "SF Mono", "Consolas", monospace;--shadow-xs: 0 1px 2px rgba(0, 0, 0, .2);--shadow-sm: 0 2px 4px rgba(0, 0, 0, .2);--shadow-md: 0 4px 12px rgba(0, 0, 0, .3);--shadow-lg: 0 8px 24px rgba(0, 0, 0, .4);--shadow-xl: 0 16px 48px rgba(0, 0, 0, .5);--shadow-glow: 0 0 24px var(--accent-glow);--shadow-glow-sm: 0 0 12px var(--accent-glow);--radius-xs: 4px;--radius-sm: 6px;--radius-md: 10px;--radius-lg: 14px;--radius-xl: 20px;--transition-fast: .12s ease;--transition-normal: .2s ease;--transition-slow: .3s ease;--blur-sm: 8px;--blur-md: 16px;--blur-lg: 24px}@media (prefers-reduced-motion: reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}*{margin:0;padding:0;box-sizing:border-box}html,body,#root{height:100%;width:100%;overflow:hidden}body{font-family:var(--font-family);background:var(--bg-primary);color:var(--text-primary);font-size:14px;line-height:1.6;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.app-container{display:flex;flex-direction:column;height:100vh;width:100vw;background:var(--bg-primary)}.top-bar{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;background:linear-gradient(180deg,#1e293bf2,#1e293bd9);-webkit-backdrop-filter:blur(var(--blur-md));backdrop-filter:blur(var(--blur-md));border-bottom:1px solid var(--border-color);min-height:52px;position:relative;z-index:100}.top-bar:after{content:"";position:absolute;bottom:0;left:0;right:0;height:1px;background:linear-gradient(90deg,transparent,var(--accent-color),transparent);opacity:.3}.top-bar-left,.top-bar-center,.top-bar-right{display:flex;align-items:center;gap:16px}.top-bar-left{width:260px}.top-bar-center{flex:1;justify-content:center}.top-bar-right{width:40%;justify-content:flex-end}.top-bar-title{font-family:var(--font-display);font-weight:600;font-size:13px;text-transform:uppercase;letter-spacing:1px;color:var(--text-secondary);display:flex;align-items:center;gap:8px}.top-bar-title:before{content:"";display:inline-block;width:3px;height:14px;background:var(--accent-color);border-radius:2px}.main-content{display:flex;flex:1;overflow:hidden;gap:1px;background:var(--border-color)}.panel{display:flex;flex-direction:column;overflow:hidden;background:linear-gradient(180deg,var(--bg-secondary) 0%,rgba(30,41,59,.95) 100%)}.left-panel{width:260px;flex-shrink:0}.middle-panel{flex:1;min-width:300px}.right-panel{width:40%;min-width:300px;max-width:60%}.panel-content{flex:1;overflow:auto;padding:8px}.file-tree{padding:4px}.file-item{padding:8px 12px;cursor:pointer;border-radius:var(--radius-sm);display:flex;align-items:center;gap:10px;transition:all var(--transition-fast);position:relative;margin:2px 0}.file-item:before{content:"";position:absolute;left:0;top:50%;transform:translateY(-50%);width:3px;height:0;background:var(--accent-color);border-radius:0 2px 2px 0;transition:height var(--transition-fast)}.file-item:hover{background:#94a3b814}.file-item:hover:before{height:60%}.file-item:active{transform:scale(.98)}.file-item.active{background:var(--accent-soft);color:var(--text-primary)}.file-item.active:before{height:70%}.file-icon{width:18px;height:18px;display:flex;align-items:center;justify-content:center;font-size:14px;opacity:.9}.file-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px}.diff-line{font-family:var(--font-mono);font-size:13px;padding:3px 16px 3px 20px;white-space:pre;border-left:3px solid transparent;transition:background var(--transition-fast);position:relative}.diff-line.added{background:var(--diff-add-bg);color:var(--diff-add-text);border-left-color:var(--diff-add-border)}.diff-line.removed{background:var(--diff-remove-bg);color:var(--diff-remove-text);border-left-color:var(--diff-remove-border)}.diff-line:before{display:inline-block;width:16px;margin-left:-16px;text-align:center;font-weight:600;font-size:12px}.diff-line.added:before{content:"+";color:var(--diff-add-text)}.diff-line.removed:before{content:"-";color:var(--diff-remove-text)}.tab-bar{display:flex;background:#0f172a99;border-bottom:1px solid var(--border-color);overflow-x:auto;min-height:40px;scrollbar-width:none}.tab-bar::-webkit-scrollbar{display:none}.tab{display:flex;align-items:center;gap:8px;padding:10px 16px;background:transparent;border-right:1px solid var(--border-color);cursor:pointer;min-width:100px;max-width:180px;font-size:13px;color:var(--text-muted);transition:all var(--transition-fast);position:relative}.tab:hover{background:#94a3b80d;color:var(--text-secondary)}.tab.active{background:var(--bg-secondary);color:var(--text-primary)}.tab.active:after{content:"";position:absolute;bottom:0;left:0;right:0;height:2px;background:var(--accent-color)}.tab-name{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.tab-close{background:none;border:none;color:var(--text-muted);font-size:16px;cursor:pointer;padding:2px 6px;border-radius:var(--radius-xs);line-height:1;transition:all var(--transition-fast);opacity:.6}.tab-close:hover{background:#ef444433;color:var(--danger-color);opacity:1}.tab.modified .tab-name{color:var(--accent-color)}.tab-modified-mark{color:var(--accent-color);margin-right:4px;font-size:10px}.context-menu{position:fixed;background:linear-gradient(180deg,var(--bg-tertiary) 0%,var(--bg-secondary) 100%);border:1px solid var(--border-color);border-radius:var(--radius-md);padding:6px;min-width:160px;box-shadow:var(--shadow-lg);z-index:1000;animation:contextMenuIn .15s ease;-webkit-backdrop-filter:blur(var(--blur-sm));backdrop-filter:blur(var(--blur-sm))}@keyframes contextMenuIn{0%{opacity:0;transform:scale(.95) translateY(-4px)}to{opacity:1;transform:scale(1) translateY(0)}}.context-menu-item{padding:10px 14px;cursor:pointer;font-size:13px;color:var(--text-primary);border-radius:var(--radius-sm);transition:all var(--transition-fast)}.context-menu-item:hover{background:var(--accent-soft);color:var(--accent-color)}.file-context-menu{position:fixed;background:linear-gradient(180deg,var(--bg-tertiary) 0%,var(--bg-secondary) 100%);border:1px solid var(--border-color);border-radius:var(--radius-md);padding:6px;min-width:200px;box-shadow:var(--shadow-lg);z-index:1000;animation:contextMenuIn .15s ease;-webkit-backdrop-filter:blur(var(--blur-sm));backdrop-filter:blur(var(--blur-sm))}.ws-status{display:inline-block;width:8px;height:8px;border-radius:50%;margin-left:8px;transition:all var(--transition-normal)}.ws-status.connected{background:var(--success-color);box-shadow:0 0 8px var(--success-color);animation:pulse 2s infinite}.ws-status.disconnected{background:var(--danger-color);box-shadow:0 0 8px var(--danger-color)}@keyframes pulse{0%,to{opacity:1;box-shadow:0 0 8px var(--success-color)}50%{opacity:.7;box-shadow:0 0 4px var(--success-color)}}.version-info{display:flex;align-items:center;gap:10px}.version-number{font-size:11px;color:var(--text-muted);font-weight:500;font-family:var(--font-mono);padding:3px 8px;background:#94a3b81a;border-radius:var(--radius-xs)}.update-badge{font-size:10px;padding:4px 10px;background:linear-gradient(135deg,var(--warning-color) 0%,#FBBF24 100%);color:var(--bg-primary);border-radius:var(--radius-sm);cursor:pointer;font-weight:600;transition:all var(--transition-fast)}.update-badge:hover{transform:translateY(-1px);box-shadow:0 4px 12px #f59e0b4d}.terminal-wrapper{flex:1;overflow:hidden;min-height:0}.section{margin-bottom:8px}.section-title{padding:10px 12px 6px;font-size:10px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.8px}.empty-state{padding:40px 24px;text-align:center;color:var(--text-muted);font-size:13px;display:flex;flex-direction:column;align-items:center;gap:12px}.empty-state:before{content:"";width:48px;height:48px;background:linear-gradient(135deg,var(--bg-tertiary) 0%,var(--bg-elevated) 100%);border-radius:var(--radius-lg);display:flex;align-items:center;justify-content:center}.code-panel{font-family:var(--font-mono)}.code-viewer-codemirror{height:100%;width:100%;display:flex;min-height:0;min-width:0}.code-viewer-codemirror .cm-theme{flex:1;display:flex;min-height:0;min-width:0}.code-viewer-codemirror .cm-editor{flex:1;min-width:0;min-height:0}.code-viewer-codemirror .cm-scroller{flex:1;overflow:auto!important;min-height:0}.code-content{padding:16px;white-space:pre-wrap;word-break:break-all;line-height:1.7;font-size:13px}.diff-container{font-family:var(--font-mono);font-size:13px;padding:8px 0}.task-btn{padding:8px 18px;border:none;border-radius:var(--radius-sm);font-size:12px;font-weight:600;cursor:pointer;transition:all var(--transition-fast);font-family:var(--font-family);display:inline-flex;align-items:center;gap:6px}.task-btn:hover{transform:translateY(-1px)}.task-btn:active{transform:translateY(0)}.task-btn-clear{background:transparent;color:var(--text-secondary);border:1px solid var(--border-color)}.task-btn-clear:hover{background:var(--accent-soft);border-color:var(--accent-color);color:var(--accent-color);box-shadow:var(--shadow-glow-sm)}::-webkit-scrollbar{width:6px;height:6px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--bg-elevated);border-radius:3px}::-webkit-scrollbar-thumb:hover{background:var(--text-muted)}::-webkit-scrollbar-corner{background:transparent}.git-status-bar{display:flex;align-items:center;gap:16px;padding:6px 14px;background:#94a3b814;border-radius:var(--radius-sm);border:1px solid var(--border-color)}.git-branch{display:flex;align-items:center;gap:6px;font-family:var(--font-mono);font-size:12px;font-weight:600;color:var(--accent-color)}.git-branch-icon{font-size:14px;opacity:.8}.git-stats{display:flex;align-items:center;gap:12px}.git-staged,.git-unstaged{display:flex;align-items:center;gap:4px;font-size:11px;color:var(--text-secondary)}.git-staged-count{font-weight:600;color:var(--success-color)}.git-unstaged-count{font-weight:600;color:var(--warning-color)}.git-changes-btn{padding:4px 10px;font-size:11px;background:transparent;border:1px solid var(--border-color);border-radius:var(--radius-xs);color:var(--text-secondary);cursor:pointer;transition:all var(--transition-fast)}.git-changes-btn:hover{background:var(--accent-soft);border-color:var(--accent-color);color:var(--accent-color)}.staged-changes-panel{position:absolute;top:52px;left:0;right:0;max-height:400px;background:linear-gradient(180deg,var(--bg-tertiary) 0%,var(--bg-secondary) 100%);border-bottom:1px solid var(--border-color);z-index:99;overflow-y:auto;animation:slideDown .2s ease}@keyframes slideDown{0%{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:translateY(0)}}.staged-panel-header{display:flex;justify-content:space-between;align-items:center;padding:10px 16px;background:#0f172a99;border-bottom:1px solid var(--border-color);font-weight:600;font-size:12px;color:var(--text-secondary)}.staged-panel-actions{display:flex;gap:8px;align-items:center}.stage-btn,.unstage-btn{padding:4px 10px;font-size:11px;background:var(--bg-elevated);border:1px solid var(--border-color);border-radius:var(--radius-xs);color:var(--text-secondary);cursor:pointer;transition:all var(--transition-fast)}.stage-btn:hover,.unstage-btn:hover{background:var(--accent-soft);border-color:var(--accent-color);color:var(--accent-color)}.close-btn{width:24px;height:24px;display:flex;align-items:center;justify-content:center;background:transparent;border:none;color:var(--text-muted);cursor:pointer;font-size:16px;border-radius:var(--radius-xs);transition:all var(--transition-fast)}.close-btn:hover{background:#ef444433;color:var(--danger-color)}.changes-section{padding:8px 0;border-bottom:1px solid var(--border-color)}.changes-section:last-child{border-bottom:none}.changes-section-header{padding:4px 16px}.changes-section-title{font-size:10px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.5px}.changes-list{display:flex;flex-direction:column}.change-item{display:flex;align-items:center;gap:8px;padding:6px 16px;cursor:pointer;transition:background var(--transition-fast)}.change-item:hover{background:#94a3b814}.change-item.staged{background:var(--accent-soft)}.change-icon{width:16px;text-align:center;font-size:12px;color:var(--text-muted)}.change-item.staged .change-icon{color:var(--success-color)}.change-status{width:14px;height:14px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;font-family:var(--font-mono);border-radius:2px}.change-status.M{background:var(--warning-color);color:var(--bg-primary)}.change-status.A{background:var(--success-color);color:var(--bg-primary)}.change-status.D{background:var(--danger-color);color:var(--text-primary)}.change-status.R{background:var(--info-color);color:var(--text-primary)}.change-status.\?{background:var(--text-muted);color:var(--bg-primary)}.change-path{flex:1;font-size:12px;font-family:var(--font-mono);color:var(--text-primary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.no-changes{padding:24px;text-align:center;color:var(--text-muted);font-size:13px}.commit-section{display:flex;gap:8px;padding:12px 16px;background:#0f172a99;border-top:1px solid var(--border-color)}.commit-input{flex:1;padding:8px 12px;background:var(--bg-primary);border:1px solid var(--border-color);border-radius:var(--radius-sm);color:var(--text-primary);font-size:12px;font-family:var(--font-family)}.commit-input:focus{outline:none;border-color:var(--accent-color)}.commit-btn{padding:8px 16px;background:var(--accent-color);border:none;border-radius:var(--radius-sm);color:var(--bg-primary);font-size:12px;font-weight:600;cursor:pointer;transition:all var(--transition-fast)}.commit-btn:hover{background:var(--accent-hover);transform:translateY(-1px)}.panel-divider{width:1px;height:20px;background:var(--border-color);margin:0 4px}.git-action-btn{padding:4px 10px;font-size:11px;background:var(--bg-elevated);border:1px solid var(--border-color);border-radius:var(--radius-xs);color:var(--text-secondary);cursor:pointer;transition:all var(--transition-fast)}.git-action-btn:hover:not(:disabled){background:var(--accent-soft);border-color:var(--accent-color);color:var(--accent-color)}.git-action-btn:disabled{opacity:.5;cursor:not-allowed}.git-push-btn{background:linear-gradient(135deg,rgba(34,197,94,.1) 0%,var(--bg-elevated) 100%);border-color:#22c55e4d;color:var(--success-color)}.git-push-btn:hover:not(:disabled){background:var(--success-color);border-color:var(--success-color);color:var(--bg-primary)}.toast{position:fixed;bottom:24px;right:24px;display:flex;align-items:center;gap:10px;padding:12px 16px;border-radius:var(--radius-md);background:var(--bg-elevated);border:1px solid var(--border-color);box-shadow:var(--shadow-lg);z-index:1000;animation:toastIn .2s ease;min-width:240px;max-width:400px}@keyframes toastIn{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.toast-success{border-color:var(--success-color);background:linear-gradient(135deg,rgba(34,197,94,.15) 0%,var(--bg-elevated) 100%)}.toast-error{border-color:var(--danger-color);background:linear-gradient(135deg,rgba(239,68,68,.15) 0%,var(--bg-elevated) 100%)}.toast-icon{width:20px;height:20px;display:flex;align-items:center;justify-content:center;border-radius:50%;font-size:12px;font-weight:700;flex-shrink:0}.toast-success .toast-icon{background:var(--success-color);color:var(--bg-primary)}.toast-error .toast-icon{background:var(--danger-color);color:var(--text-primary)}.toast-message{flex:1;font-size:13px;color:var(--text-primary)}.toast-close{background:none;border:none;color:var(--text-muted);cursor:pointer;font-size:16px;padding:2px 6px;border-radius:var(--radius-xs);transition:all var(--transition-fast);flex-shrink:0}.toast-close:hover{background:#ffffff1a;color:var(--text-primary)}.file-git-badge{width:16px;height:16px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:700;font-family:var(--font-mono);border-radius:3px;margin-left:auto;flex-shrink:0}.file-git-badge.staged{background:var(--success-color);color:#000}.file-git-badge.wt{background:var(--warning-color);color:#000}.file-git-badge.untracked{background:var(--text-muted);color:#fff}@media (max-width: 1024px){.left-panel{width:220px}.right-panel{width:45%;min-width:250px}.top-bar-left{width:220px}}@media (max-width: 768px){.main-content{flex-direction:column}.left-panel,.right-panel{width:100%;max-width:none;min-width:auto}.middle-panel{min-height:300px}.top-bar{flex-wrap:wrap;padding:10px 16px}.top-bar-left,.top-bar-center,.top-bar-right{width:auto}.top-bar-center{order:3;width:100%;justify-content:flex-start;margin-top:8px;padding-top:8px;border-top:1px solid var(--border-color)}}
@@ -4,8 +4,8 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Codex Lens</title>
7
- <script type="module" crossorigin src="./assets/main-CUb7GmCR.js"></script>
8
- <link rel="stylesheet" crossorigin href="./assets/main-9dRi3GOo.css">
7
+ <script type="module" crossorigin src="./assets/main-C24uyyBG.js"></script>
8
+ <link rel="stylesheet" crossorigin href="./assets/main-gnDZ_a0p.css">
9
9
  </head>
10
10
  <body>
11
11
  <div id="root"></div>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-lens",
3
- "version": "0.1.35",
3
+ "version": "0.1.36",
4
4
  "description": "A visualization tool for Codex that monitors API requests and file system changes",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/aggregator.js CHANGED
@@ -313,6 +313,27 @@ class Aggregator {
313
313
  await this.gitManager.commit(data.message);
314
314
  this.gitManager.broadcastUpdate();
315
315
  }
316
+ } else if (data.type === 'git_push') {
317
+ if (this.gitManager?.isGitRepo()) {
318
+ const result = await this.gitManager.push();
319
+ this.broadcast({ type: 'git_operation_result', operation: 'push', success: result.success, message: result.message });
320
+ if (result.success) {
321
+ this.gitManager.broadcastUpdate();
322
+ }
323
+ }
324
+ } else if (data.type === 'git_pull') {
325
+ if (this.gitManager?.isGitRepo()) {
326
+ const result = await this.gitManager.pull();
327
+ this.broadcast({ type: 'git_operation_result', operation: 'pull', success: result.success, message: result.message });
328
+ if (result.success) {
329
+ this.gitManager.broadcastUpdate();
330
+ }
331
+ }
332
+ } else if (data.type === 'git_fetch') {
333
+ if (this.gitManager?.isGitRepo()) {
334
+ const result = await this.gitManager.fetch();
335
+ this.broadcast({ type: 'git_operation_result', operation: 'fetch', success: result.success, message: result.message });
336
+ }
316
337
  }
317
338
  }
318
339
 
@@ -21,6 +21,9 @@ export function App() {
21
21
  unstagedCount: 0
22
22
  });
23
23
  const [showStagedPanel, setShowStagedPanel] = useState(false);
24
+ const [gitOperationLoading, setGitOperationLoading] = useState(false);
25
+ const [gitOperationType, setGitOperationType] = useState(null);
26
+ const [toast, setToast] = useState(null);
24
27
  const wsRef = useRef(null);
25
28
 
26
29
  useEffect(() => {
@@ -139,6 +142,11 @@ export function App() {
139
142
  unstagedCount: msg.data.unstagedCount
140
143
  });
141
144
  break;
145
+ case 'git_operation_result':
146
+ setGitOperationLoading(false);
147
+ setGitOperationType(null);
148
+ setToast({ type: msg.success ? 'success' : 'error', message: msg.message });
149
+ break;
142
150
  case 'connected':
143
151
  console.log('Server confirmed connection');
144
152
  break;
@@ -165,6 +173,12 @@ export function App() {
165
173
  sendGitCommand('git_commit', { message });
166
174
  }
167
175
 
176
+ function handleGitOperation(operationType) {
177
+ setGitOperationLoading(true);
178
+ setGitOperationType(operationType);
179
+ sendGitCommand(`git_${operationType}`, {});
180
+ }
181
+
168
182
  function openFileInTab(data) {
169
183
  const fileName = data.path.split(/[/\\]/).pop();
170
184
 
@@ -521,9 +535,15 @@ export function App() {
521
535
  onStage={handleStage}
522
536
  onUnstage={handleUnstage}
523
537
  onCommit={handleCommit}
538
+ onPush={() => handleGitOperation('push')}
539
+ onPull={() => handleGitOperation('pull')}
540
+ onFetch={() => handleGitOperation('fetch')}
541
+ operationLoading={gitOperationLoading}
542
+ operationType={gitOperationType}
524
543
  onClose={() => setShowStagedPanel(false)}
525
544
  />
526
545
  )}
546
+ <Toast toast={toast} onClose={() => setToast(null)} />
527
547
  <div className="panel right-panel">
528
548
  <div className="terminal-wrapper">
529
549
  <TerminalPanel />
@@ -585,7 +605,28 @@ function ContextMenu({ x, y, tab, tabs, saving, onClose, onCloseTab, onCloseOthe
585
605
  );
586
606
  }
587
607
 
588
- function StagedChangesPanel({ gitInfo, onStage, onUnstage, onCommit, onClose }) {
608
+ function Toast({ toast, onClose }) {
609
+ const timerRef = useRef(null);
610
+
611
+ useEffect(() => {
612
+ if (toast) {
613
+ timerRef.current = setTimeout(onClose, 4000);
614
+ }
615
+ return () => clearTimeout(timerRef.current);
616
+ }, [toast, onClose]);
617
+
618
+ if (!toast) return null;
619
+
620
+ return (
621
+ <div className={`toast toast-${toast.type}`}>
622
+ <span className="toast-icon">{toast.type === 'success' ? '✓' : '✗'}</span>
623
+ <span className="toast-message">{toast.message}</span>
624
+ <button className="toast-close" onClick={onClose}>×</button>
625
+ </div>
626
+ );
627
+ }
628
+
629
+ function StagedChangesPanel({ gitInfo, onStage, onUnstage, onCommit, onPush, onPull, onFetch, operationLoading, operationType, onClose }) {
589
630
  if (!gitInfo.isRepo || !gitInfo.status) return null;
590
631
 
591
632
  const { staged, unstaged, untracked } = gitInfo.status;
@@ -595,6 +636,16 @@ function StagedChangesPanel({ gitInfo, onStage, onUnstage, onCommit, onClose })
595
636
  <div className="staged-panel-header">
596
637
  <span>Git 变更</span>
597
638
  <div className="staged-panel-actions">
639
+ <button onClick={onFetch} className="git-action-btn" disabled={operationLoading} title="Fetch from remote">
640
+ {operationLoading && operationType === 'fetch' ? '...' : 'Fetch'}
641
+ </button>
642
+ <button onClick={onPull} className="git-action-btn" disabled={operationLoading} title="Pull from remote">
643
+ {operationLoading && operationType === 'pull' ? '...' : 'Pull'}
644
+ </button>
645
+ <button onClick={onPush} className="git-action-btn git-push-btn" disabled={operationLoading} title="Push to remote">
646
+ {operationLoading && operationType === 'push' ? '...' : 'Push'}
647
+ </button>
648
+ <span className="panel-divider"></span>
598
649
  <button onClick={() => onStage(null)} className="stage-btn">Stage All</button>
599
650
  <button onClick={() => onUnstage(null)} className="unstage-btn">Unstage All</button>
600
651
  <button onClick={onClose} className="close-btn">×</button>
@@ -138,6 +138,18 @@ class GitManager {
138
138
  return this.getStatus();
139
139
  }
140
140
 
141
+ async runRemoteOperation(operation, args, successMsg) {
142
+ const result = await this.runGitCommand(args);
143
+ return {
144
+ success: result.code === 0,
145
+ message: result.code === 0 ? successMsg : (result.stderr || `${operation} 失败`),
146
+ };
147
+ }
148
+
149
+ async push() { return this.runRemoteOperation('Push', ['push'], 'Push 成功'); }
150
+ async pull() { return this.runRemoteOperation('Pull', ['pull'], 'Pull 成功'); }
151
+ async fetch() { return this.runRemoteOperation('Fetch', ['fetch', '--all'], 'Fetch 成功'); }
152
+
141
153
  async broadcastUpdate() {
142
154
  const branch = await this.getCurrentBranch();
143
155
  const status = await this.getStatus();
package/src/global.css CHANGED
@@ -923,6 +923,133 @@ body {
923
923
  transform: translateY(-1px);
924
924
  }
925
925
 
926
+ /* ==================== Git Remote Action Buttons ==================== */
927
+ .panel-divider {
928
+ width: 1px;
929
+ height: 20px;
930
+ background: var(--border-color);
931
+ margin: 0 4px;
932
+ }
933
+
934
+ .git-action-btn {
935
+ padding: 4px 10px;
936
+ font-size: 11px;
937
+ background: var(--bg-elevated);
938
+ border: 1px solid var(--border-color);
939
+ border-radius: var(--radius-xs);
940
+ color: var(--text-secondary);
941
+ cursor: pointer;
942
+ transition: all var(--transition-fast);
943
+ }
944
+
945
+ .git-action-btn:hover:not(:disabled) {
946
+ background: var(--accent-soft);
947
+ border-color: var(--accent-color);
948
+ color: var(--accent-color);
949
+ }
950
+
951
+ .git-action-btn:disabled {
952
+ opacity: 0.5;
953
+ cursor: not-allowed;
954
+ }
955
+
956
+ .git-push-btn {
957
+ background: linear-gradient(135deg, rgba(34, 197, 94, 0.1) 0%, var(--bg-elevated) 100%);
958
+ border-color: rgba(34, 197, 94, 0.3);
959
+ color: var(--success-color);
960
+ }
961
+
962
+ .git-push-btn:hover:not(:disabled) {
963
+ background: var(--success-color);
964
+ border-color: var(--success-color);
965
+ color: var(--bg-primary);
966
+ }
967
+
968
+ /* ==================== Toast Notifications ==================== */
969
+ .toast {
970
+ position: fixed;
971
+ bottom: 24px;
972
+ right: 24px;
973
+ display: flex;
974
+ align-items: center;
975
+ gap: 10px;
976
+ padding: 12px 16px;
977
+ border-radius: var(--radius-md);
978
+ background: var(--bg-elevated);
979
+ border: 1px solid var(--border-color);
980
+ box-shadow: var(--shadow-lg);
981
+ z-index: 1000;
982
+ animation: toastIn 0.2s ease;
983
+ min-width: 240px;
984
+ max-width: 400px;
985
+ }
986
+
987
+ @keyframes toastIn {
988
+ from {
989
+ opacity: 0;
990
+ transform: translateY(8px);
991
+ }
992
+ to {
993
+ opacity: 1;
994
+ transform: translateY(0);
995
+ }
996
+ }
997
+
998
+ .toast-success {
999
+ border-color: var(--success-color);
1000
+ background: linear-gradient(135deg, rgba(34, 197, 94, 0.15) 0%, var(--bg-elevated) 100%);
1001
+ }
1002
+
1003
+ .toast-error {
1004
+ border-color: var(--danger-color);
1005
+ background: linear-gradient(135deg, rgba(239, 68, 68, 0.15) 0%, var(--bg-elevated) 100%);
1006
+ }
1007
+
1008
+ .toast-icon {
1009
+ width: 20px;
1010
+ height: 20px;
1011
+ display: flex;
1012
+ align-items: center;
1013
+ justify-content: center;
1014
+ border-radius: 50%;
1015
+ font-size: 12px;
1016
+ font-weight: bold;
1017
+ flex-shrink: 0;
1018
+ }
1019
+
1020
+ .toast-success .toast-icon {
1021
+ background: var(--success-color);
1022
+ color: var(--bg-primary);
1023
+ }
1024
+
1025
+ .toast-error .toast-icon {
1026
+ background: var(--danger-color);
1027
+ color: var(--text-primary);
1028
+ }
1029
+
1030
+ .toast-message {
1031
+ flex: 1;
1032
+ font-size: 13px;
1033
+ color: var(--text-primary);
1034
+ }
1035
+
1036
+ .toast-close {
1037
+ background: none;
1038
+ border: none;
1039
+ color: var(--text-muted);
1040
+ cursor: pointer;
1041
+ font-size: 16px;
1042
+ padding: 2px 6px;
1043
+ border-radius: var(--radius-xs);
1044
+ transition: all var(--transition-fast);
1045
+ flex-shrink: 0;
1046
+ }
1047
+
1048
+ .toast-close:hover {
1049
+ background: rgba(255, 255, 255, 0.1);
1050
+ color: var(--text-primary);
1051
+ }
1052
+
926
1053
  /* ==================== File Tree Git Badges ==================== */
927
1054
  .file-git-badge {
928
1055
  width: 16px;