codex-lens 0.1.16 → 0.1.18

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,7 +4,7 @@
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-ssN8akn5.js"></script>
7
+ <script type="module" crossorigin src="./assets/main-Bno1eqbI.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="./assets/main-7-y-Utze.css">
9
9
  </head>
10
10
  <body>
@@ -0,0 +1,111 @@
1
+ # Codex-Lens
2
+
3
+ 一个可视化的 Codex 任务管理与代码审查工具。
4
+
5
+ ## 功能特性
6
+
7
+ ### 文件浏览器
8
+ - 实时监控项目文件变化,自动更新文件树
9
+ - 支持文件夹展开/折叠
10
+ - 右键菜单支持复制文件路径、在文件资源管理器中打开
11
+
12
+ ### 代码查看器
13
+ - 支持 20+ 种编程语言的语法高亮(JavaScript、Python、Java、C/C++、Go、Rust 等)
14
+ - 行号显示
15
+ - 代码缩略图(Minimap),支持拖动滑块滚动、点击跳转
16
+ - 文件变更 Diff 显示,清晰展示新增/删除/修改的内容
17
+
18
+ ### 终端集成
19
+ - 内置终端,直接与 Codex 交互
20
+ - 实时显示 Codex 输出
21
+ - 支持终端输入
22
+
23
+ ### 标签页管理
24
+ - 多文件标签页浏览
25
+ - 支持快捷键:`Ctrl+W` 关闭标签、`Ctrl+Tab` 切换标签
26
+ - 右键菜单:关闭、关闭其他、关闭所有
27
+
28
+ ### 其他特性
29
+ - WebSocket 实时通信,自动重连
30
+ - 版本检测与更新提示
31
+ - 现代化深色主题 UI
32
+
33
+ ## 前置要求
34
+
35
+ 在使用 Codex-Lens 之前,需要先安装 Codex:
36
+
37
+ ```bash
38
+ npm install -g @openai/codex
39
+ ```
40
+
41
+ ## 安装
42
+
43
+ ### 通过 npm 全局安装
44
+
45
+ ```bash
46
+ npm install -g codex-lens
47
+ ```
48
+
49
+ ### 使用
50
+
51
+ 在项目目录下运行:
52
+
53
+ ```bash
54
+ codexlens
55
+ ```
56
+
57
+ 工具会自动:
58
+ 1. 检测当前项目根目录
59
+ 2. 启动 Codex 进程
60
+ 3. 打开浏览器界面(http://localhost:5174)
61
+
62
+ ## 更新
63
+
64
+ ### 检查更新
65
+
66
+ 工具启动时会自动检查 npm 上的最新版本,如有更新会在界面右上角显示提示。
67
+
68
+ ### 手动更新
69
+
70
+ ```bash
71
+ npm update -g codex-lens
72
+ ```
73
+
74
+ ## 技术栈
75
+
76
+ - **前端**: React 18、Vite、CodeMirror 6
77
+ - **后端**: Node.js、Express、WebSocket
78
+ - **终端**: xterm.js、node-pty
79
+ - **文件监控**: chokidar
80
+ - **Diff 生成**: diff
81
+
82
+ ## 开发
83
+
84
+ ### 克隆项目
85
+
86
+ ```bash
87
+ git clone https://github.com/your-username/codex-lens.git
88
+ cd codex-lens
89
+ ```
90
+
91
+ ### 安装依赖
92
+
93
+ ```bash
94
+ npm install
95
+ ```
96
+
97
+ ### 开发模式
98
+
99
+ ```bash
100
+ # 构建项目
101
+ npm run build
102
+
103
+ # 启动服务
104
+ npm start
105
+ ```
106
+
107
+ 开发流程:修改代码后,需要重新运行 `npm run build` 构建项目,然后运行 `npm start` 启动服务查看效果。
108
+
109
+ ## 许可证
110
+
111
+ [MIT](LICENSE)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "codex-lens",
3
- "version": "0.1.16",
3
+ "version": "0.1.18",
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
@@ -76,7 +76,8 @@ class Aggregator {
76
76
  codexRunning: !!this.ptyProcess,
77
77
  version: current,
78
78
  latestVersion: latestVersion,
79
- hasUpdate: latestVersion && latestVersion !== current
79
+ hasUpdate: latestVersion && latestVersion !== current,
80
+ projectRoot: this.projectRoot
80
81
  });
81
82
  } else {
82
83
  next();
@@ -11,6 +11,7 @@ export function App() {
11
11
  const [version, setVersion] = useState(null);
12
12
  const [latestVersion, setLatestVersion] = useState(null);
13
13
  const [hasUpdate, setHasUpdate] = useState(false);
14
+ const [projectName, setProjectName] = useState('');
14
15
  const wsRef = useRef(null);
15
16
 
16
17
  useEffect(() => {
@@ -38,6 +39,10 @@ export function App() {
38
39
  setVersion(data.version);
39
40
  setLatestVersion(data.latestVersion);
40
41
  setHasUpdate(data.hasUpdate);
42
+ if (data.projectRoot) {
43
+ const parts = data.projectRoot.split(/[/\\]/);
44
+ setProjectName(parts[parts.length - 1] || data.projectRoot);
45
+ }
41
46
  }
42
47
  } catch (error) {
43
48
  console.error('Failed to fetch status:', error);
@@ -234,7 +239,7 @@ export function App() {
234
239
  <div className="app-container">
235
240
  <div className="top-bar">
236
241
  <div className="top-bar-left">
237
- <span className="top-bar-title">文件浏览器</span>
242
+ <span className="top-bar-title">当前工作区: {projectName}</span>
238
243
  </div>
239
244
  <div className="top-bar-center">
240
245
  <button className="task-btn task-btn-clear" onClick={clearAllDiff} title="清空所有 diff 显示">
@@ -1,8 +1,9 @@
1
1
  import React, { useMemo, useRef } from 'react';
2
2
  import CodeMirror from '@uiw/react-codemirror';
3
- import { EditorView } from '@codemirror/view';
3
+ import { EditorView, Decoration, ViewPlugin, ViewUpdate } from '@codemirror/view';
4
4
  import { HighlightStyle, syntaxHighlighting } from '@codemirror/language';
5
5
  import { tags as t } from '@lezer/highlight';
6
+ import { RangeSetBuilder } from '@codemirror/state';
6
7
  import { javascript } from '@codemirror/lang-javascript';
7
8
  import { python } from '@codemirror/lang-python';
8
9
  import { java } from '@codemirror/lang-java';
@@ -56,6 +57,58 @@ function getLanguageExtension(filePath) {
56
57
  return LANG_MAP[ext] ? [LANG_MAP[ext]()] : [];
57
58
  }
58
59
 
60
+ const addedLineDecoration = Decoration.line({
61
+ class: 'cm-diff-added-line',
62
+ attributes: { 'data-diff-type': 'added' }
63
+ });
64
+
65
+ const removedLineDecoration = Decoration.line({
66
+ class: 'cm-diff-removed-line',
67
+ attributes: { 'data-diff-type': 'removed' }
68
+ });
69
+
70
+ function createDiffHighlightPlugin(diffData) {
71
+ return ViewPlugin.fromClass(class {
72
+ decorations;
73
+
74
+ constructor(view) {
75
+ this.decorations = this.buildDecorations(view, diffData);
76
+ }
77
+
78
+ update(update) {
79
+ if (update.docChanged || update.viewportChanged) {
80
+ this.decorations = this.buildDecorations(update.view, diffData);
81
+ }
82
+ }
83
+
84
+ buildDecorations(view, diff) {
85
+ if (!diff || diff.length === 0) {
86
+ return Decoration.none;
87
+ }
88
+
89
+ const builder = new RangeSetBuilder();
90
+ const doc = view.state.doc;
91
+
92
+ for (let i = 1; i <= doc.lines; i++) {
93
+ const line = doc.line(i);
94
+ const diffLine = diff[i - 1];
95
+
96
+ if (diffLine) {
97
+ if (diffLine.added) {
98
+ builder.add(line.from, line.from, addedLineDecoration);
99
+ } else if (diffLine.removed) {
100
+ builder.add(line.from, line.from, removedLineDecoration);
101
+ }
102
+ }
103
+ }
104
+
105
+ return builder.finish();
106
+ }
107
+ }, {
108
+ decorations: v => v.decorations
109
+ });
110
+ }
111
+
59
112
  const darkTheme = EditorView.theme({
60
113
  '&': {
61
114
  backgroundColor: '#000000',
@@ -112,6 +165,20 @@ const darkTheme = EditorView.theme({
112
165
  background: 'rgba(34, 197, 94, 0.4)',
113
166
  cursor: 'grabbing',
114
167
  },
168
+ '.cm-diff-added-line': {
169
+ backgroundColor: 'rgba(34, 197, 94, 0.15)',
170
+ borderLeft: '3px solid #22c55e',
171
+ },
172
+ '.cm-diff-added-line .cm-gutterElement': {
173
+ color: '#4ade80',
174
+ },
175
+ '.cm-diff-removed-line': {
176
+ backgroundColor: 'rgba(239, 68, 68, 0.15)',
177
+ borderLeft: '3px solid #ef4444',
178
+ },
179
+ '.cm-diff-removed-line .cm-gutterElement': {
180
+ color: '#f87171',
181
+ },
115
182
  }, { dark: true });
116
183
 
117
184
  const darkHighlightStyle = HighlightStyle.define([
@@ -151,8 +218,13 @@ export function CodeViewer({ content, diff, isDiff, filePath }) {
151
218
  showOverlay: 'always',
152
219
  })),
153
220
  ];
221
+
222
+ if (isDiff && diff && diff.length > 0) {
223
+ exts.push(createDiffHighlightPlugin(diff));
224
+ }
225
+
154
226
  return exts;
155
- }, [filePath]);
227
+ }, [filePath, isDiff, diff]);
156
228
 
157
229
  const code = useMemo(() => {
158
230
  if (isDiff && diff) {
package/update.bat DELETED
@@ -1,23 +0,0 @@
1
- @echo off
2
- cd /d "%~dp0"
3
-
4
- echo Publishing to npm...
5
- call npm publish
6
- if %errorlevel% neq 0 (
7
- echo Failed to publish to npm
8
- pause
9
- exit /b 1
10
- )
11
-
12
- echo.
13
- echo Installing codex-lens globally...
14
- call npm install -g codex-lens
15
- if %errorlevel% neq 0 (
16
- echo Failed to install codex-lens globally
17
- pause
18
- exit /b 1
19
- )
20
-
21
- echo.
22
- echo Done! codex-lens has been published and installed globally.
23
- pause