codex-lens 0.1.5 → 0.1.7

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.
@@ -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 Viewer</title>
7
- <script type="module" crossorigin src="./assets/main-B86_1Kr6.js"></script>
8
- <link rel="stylesheet" crossorigin href="./assets/main-CPDV3aMv.css">
7
+ <script type="module" crossorigin src="./assets/main-CDhlo8un.js"></script>
8
+ <link rel="stylesheet" crossorigin href="./assets/main-BfQHBPtk.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.5",
3
+ "version": "0.1.7",
4
4
  "description": "A visualization tool for Codex that monitors API requests and file system changes with task snapshot rollback",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/aggregator.js CHANGED
@@ -5,7 +5,7 @@ import express from 'express';
5
5
  import { createProxyServer } from './proxy.js';
6
6
  import { FileWatcher, scanDirectory } from './watcher.js';
7
7
  import { createLogger } from './lib/logger.js';
8
- import { spawnCodex, writeToPty, resizePty, killPty, onPtyData, onPtyExit, getPtyState } from './pty-manager.js';
8
+ import { spawnCodex, writeToPty, resizePty, killPty, onPtyData, onPtyExit, getPtyState, getOutputBuffer } from './pty-manager.js';
9
9
  import { SnapshotManager } from './snapshot-manager.js';
10
10
  import path from 'path';
11
11
  import { fileURLToPath } from 'url';
@@ -193,6 +193,11 @@ class Aggregator {
193
193
 
194
194
  const state = getPtyState();
195
195
  ws.send(JSON.stringify({ type: 'state', ...state }));
196
+
197
+ const bufferedOutput = getOutputBuffer();
198
+ if (bufferedOutput) {
199
+ ws.send(JSON.stringify({ type: 'data', data: bufferedOutput }));
200
+ }
196
201
  }
197
202
 
198
203
  broadcastToTerminal(event) {
@@ -448,6 +448,7 @@ function ContextMenu({ x, y, onClose, onCloseTab, onCloseOtherTabs, onCloseAllTa
448
448
 
449
449
  function LeftPanel({ files, recentChanges, activeFile, onFileClick }) {
450
450
  const [expandedDirs, setExpandedDirs] = useState({});
451
+ const [contextMenu, setContextMenu] = useState(null);
451
452
 
452
453
  function toggleDir(path) {
453
454
  setExpandedDirs(prev => ({
@@ -456,6 +457,28 @@ function LeftPanel({ files, recentChanges, activeFile, onFileClick }) {
456
457
  }));
457
458
  }
458
459
 
460
+ function handleContextMenu(e, item) {
461
+ if (item.type === 'directory') return;
462
+ e.preventDefault();
463
+ e.stopPropagation();
464
+ setContextMenu({
465
+ x: e.clientX,
466
+ y: e.clientY,
467
+ item
468
+ });
469
+ }
470
+
471
+ function handleCopyPath() {
472
+ if (contextMenu?.item?.path) {
473
+ navigator.clipboard.writeText(contextMenu.item.path).then(() => {
474
+ console.log('Path copied:', contextMenu.item.path);
475
+ }).catch(err => {
476
+ console.error('Failed to copy path:', err);
477
+ });
478
+ }
479
+ setContextMenu(null);
480
+ }
481
+
459
482
  function renderFileTree(items, depth = 0) {
460
483
  return items.map((item, i) => {
461
484
  const isDir = item.type === 'directory';
@@ -468,6 +491,7 @@ function LeftPanel({ files, recentChanges, activeFile, onFileClick }) {
468
491
  className={`file-item ${activeFile === item.path ? 'active' : ''}`}
469
492
  onClick={() => isDir ? toggleDir(item.path) : null}
470
493
  onDoubleClick={() => !isDir && onFileClick(item.path)}
494
+ onContextMenu={(e) => handleContextMenu(e, item)}
471
495
  style={{ paddingLeft: `${indent}px` }}
472
496
  >
473
497
  <span className="file-icon">
@@ -482,7 +506,7 @@ function LeftPanel({ files, recentChanges, activeFile, onFileClick }) {
482
506
  }
483
507
 
484
508
  return (
485
- <div className="panel left-panel">
509
+ <div className="panel left-panel" onClick={() => setContextMenu(null)}>
486
510
  <div className="panel-header">
487
511
  文件浏览器
488
512
  </div>
@@ -513,6 +537,17 @@ function LeftPanel({ files, recentChanges, activeFile, onFileClick }) {
513
537
  )}
514
538
  </div>
515
539
  </div>
540
+ {contextMenu && (
541
+ <div
542
+ className="file-context-menu"
543
+ style={{ left: contextMenu.x, top: contextMenu.y }}
544
+ onClick={(e) => e.stopPropagation()}
545
+ >
546
+ <div className="context-menu-item" onClick={handleCopyPath}>
547
+ 复制文件路径
548
+ </div>
549
+ </div>
550
+ )}
516
551
  </div>
517
552
  );
518
553
  }
package/src/global.css CHANGED
@@ -359,6 +359,17 @@ body {
359
359
  background: var(--accent-color);
360
360
  }
361
361
 
362
+ .file-context-menu {
363
+ position: fixed;
364
+ background: var(--bg-tertiary);
365
+ border: 1px solid var(--border-color);
366
+ border-radius: 4px;
367
+ padding: 4px 0;
368
+ min-width: 150px;
369
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
370
+ z-index: 1000;
371
+ }
372
+
362
373
  .task-bar {
363
374
  display: flex;
364
375
  align-items: center;