@tarunspandit/codexflow 0.29.0

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.
Files changed (92) hide show
  1. package/AGENTS.example.md +18 -0
  2. package/CHANGELOG.md +311 -0
  3. package/CHATGPT_PROMPT.md +12 -0
  4. package/CODEX_PROMPT.md +12 -0
  5. package/CONTRIBUTING.md +51 -0
  6. package/DOMAIN_SETUP.md +241 -0
  7. package/FAQ.md +327 -0
  8. package/FAQ_ZH.md +279 -0
  9. package/LICENSE +21 -0
  10. package/NOTICE +9 -0
  11. package/PUBLIC_LAUNCH_CHECKLIST.md +111 -0
  12. package/README.md +287 -0
  13. package/README_ZH.md +461 -0
  14. package/SECURITY.md +145 -0
  15. package/config.example.env +31 -0
  16. package/dist/analysis/cache.js +27 -0
  17. package/dist/analysis/cache.js.map +1 -0
  18. package/dist/analysis/classify.js +102 -0
  19. package/dist/analysis/classify.js.map +1 -0
  20. package/dist/analysis/extract.js +139 -0
  21. package/dist/analysis/extract.js.map +1 -0
  22. package/dist/analysis/graph.js +22 -0
  23. package/dist/analysis/graph.js.map +1 -0
  24. package/dist/analysis/impact.js +167 -0
  25. package/dist/analysis/impact.js.map +1 -0
  26. package/dist/analysis/index.js +215 -0
  27. package/dist/analysis/index.js.map +1 -0
  28. package/dist/analysis/inventory.js +51 -0
  29. package/dist/analysis/inventory.js.map +1 -0
  30. package/dist/analysis/providers.js +24 -0
  31. package/dist/analysis/providers.js.map +1 -0
  32. package/dist/analysis/rank.js +27 -0
  33. package/dist/analysis/rank.js.map +1 -0
  34. package/dist/analysis/types.js +8 -0
  35. package/dist/analysis/types.js.map +1 -0
  36. package/dist/bashOps.js +233 -0
  37. package/dist/bashOps.js.map +1 -0
  38. package/dist/capabilitiesOps.js +365 -0
  39. package/dist/capabilitiesOps.js.map +1 -0
  40. package/dist/codexSessions.js +379 -0
  41. package/dist/codexSessions.js.map +1 -0
  42. package/dist/config.js +289 -0
  43. package/dist/config.js.map +1 -0
  44. package/dist/fsOps.js +286 -0
  45. package/dist/fsOps.js.map +1 -0
  46. package/dist/gitOps.js +79 -0
  47. package/dist/gitOps.js.map +1 -0
  48. package/dist/guard.js +198 -0
  49. package/dist/guard.js.map +1 -0
  50. package/dist/http.js +1671 -0
  51. package/dist/http.js.map +1 -0
  52. package/dist/proContext.js +274 -0
  53. package/dist/proContext.js.map +1 -0
  54. package/dist/profileStore.js +89 -0
  55. package/dist/profileStore.js.map +1 -0
  56. package/dist/projectCatalog.js +134 -0
  57. package/dist/projectCatalog.js.map +1 -0
  58. package/dist/redact.js +73 -0
  59. package/dist/redact.js.map +1 -0
  60. package/dist/searchOps.js +186 -0
  61. package/dist/searchOps.js.map +1 -0
  62. package/dist/server.js +2502 -0
  63. package/dist/server.js.map +1 -0
  64. package/dist/stdio.js +36 -0
  65. package/dist/stdio.js.map +1 -0
  66. package/dist/toolCardWidget.js +1155 -0
  67. package/dist/toolCardWidget.js.map +1 -0
  68. package/dist/workspaceOps.js +229 -0
  69. package/dist/workspaceOps.js.map +1 -0
  70. package/docs/.nojekyll +1 -0
  71. package/docs/favicon.svg +5 -0
  72. package/docs/index.html +638 -0
  73. package/docs/og.png +0 -0
  74. package/docs/script.js +80 -0
  75. package/docs/star.svg +11 -0
  76. package/docs/styles.css +1229 -0
  77. package/docs/zh.html +436 -0
  78. package/package.json +94 -0
  79. package/scripts/analysis-cli-smoke.mjs +81 -0
  80. package/scripts/analysis-smoke.mjs +179 -0
  81. package/scripts/clean.mjs +6 -0
  82. package/scripts/cli-smoke.mjs +168 -0
  83. package/scripts/codexflow.mjs +4375 -0
  84. package/scripts/doctor-smoke.mjs +90 -0
  85. package/scripts/execute-handoff-smoke.mjs +1110 -0
  86. package/scripts/http-smoke.mjs +812 -0
  87. package/scripts/pro-apply.mjs +141 -0
  88. package/scripts/pro-bundle.mjs +121 -0
  89. package/scripts/pro-smoke.mjs +95 -0
  90. package/scripts/settings-smoke.mjs +756 -0
  91. package/scripts/smoke.mjs +1194 -0
  92. package/scripts/stress.mjs +835 -0
package/docs/zh.html ADDED
@@ -0,0 +1,436 @@
1
+ <!doctype html>
2
+ <html lang="zh-CN">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>CodexFlow — 一条命令,所有项目,任何对话</title>
7
+ <meta
8
+ name="description"
9
+ content="CodexFlow 通过 ChatGPT Developer Mode 和 MCP,把 ChatGPT Web 连接到你的本地代码仓库,支持读取、搜索、编辑、git 检查和安全验证。"
10
+ />
11
+ <meta property="og:title" content="CodexFlow 中文文档" />
12
+ <meta property="og:description" content="让 ChatGPT Web 看见 Codex 风格仓库上下文,并像本地代码代理一样工作。" />
13
+ <meta property="og:image" content="https://raw.githubusercontent.com/tarunspandit/codexflow/main/docs/og.png" />
14
+ <meta name="theme-color" content="#080a0c" />
15
+ <link rel="alternate" hreflang="en" href="./index.html" />
16
+ <link rel="icon" href="./favicon.svg" type="image/svg+xml" />
17
+ <link rel="stylesheet" href="./styles.css?v=2" />
18
+ </head>
19
+ <body>
20
+ <a class="skip-link" href="#quickstart">跳到设置</a>
21
+ <header class="site-header">
22
+ <a class="brand" href="#top" aria-label="CodexFlow 中文首页">
23
+ <img class="brand-mark" src="./favicon.svg" width="34" height="34" alt="" aria-hidden="true" />
24
+ <span>CodexFlow</span>
25
+ </a>
26
+ <nav aria-label="主导航">
27
+ <a href="#quickstart">开始</a>
28
+ <a href="#chatgpt">ChatGPT</a>
29
+ <a href="#url">稳定 URL</a>
30
+ <a href="#modes">模式</a>
31
+ <a href="#faq">FAQ</a>
32
+ <a href="./index.html">English</a>
33
+ <a class="nav-star" href="https://github.com/tarunspandit/codexflow"><img src="./star.svg" alt="" aria-hidden="true" />GitHub 点星</a>
34
+ </nav>
35
+ </header>
36
+
37
+ <main id="top">
38
+ <section class="hero">
39
+ <div class="hero-copy">
40
+ <p class="launch-pill"><img src="./star.svg" alt="" aria-hidden="true" />本地优先的编码基础设施</p>
41
+ <p class="eyebrow">一个 broker · 所有本地项目 · 独立对话</p>
42
+ <h1>一条命令。所有项目。<em>任何对话。</em></h1>
43
+ <p class="hero-lede">
44
+ 把网页上的 ChatGPT 变成理解本地项目的编码代理。一个 broker 自动发现项目,一个 tunnel 连接全部项目,每个对话都保留独立工作区;CodexFlow 不会调用 Codex CLI。
45
+ </p>
46
+ <div class="install-line" role="group" aria-label="安装命令">
47
+ <code>npm install -g @tarunspandit/codexflow
48
+ codexflow</code>
49
+ <button class="copy-button" data-copy="npm install -g @tarunspandit/codexflow&#10;codexflow">复制</button>
50
+ </div>
51
+ <p class="eyebrow">独立开源项目,与 OpenAI 没有隶属关系或官方背书。</p>
52
+ <div class="hero-proof" aria-label="核心能力">
53
+ <span>多项目选择器</span>
54
+ <span>每个聊天独立路由</span>
55
+ <span>AGENTS.md 上下文</span>
56
+ <span>.ai-bridge handoff</span>
57
+ <span>紧凑卡片</span>
58
+ <span>Codex session metadata 可选开启</span>
59
+ </div>
60
+ <div class="hero-actions">
61
+ <a class="button primary" href="#quickstart">安装 CodexFlow</a>
62
+ <a class="button secondary star-button" href="https://github.com/tarunspandit/codexflow"><img src="./star.svg" alt="" aria-hidden="true" />GitHub 点星</a>
63
+ <a class="button secondary" href="https://www.npmjs.com/package/@tarunspandit/codexflow">查看 npm</a>
64
+ </div>
65
+ </div>
66
+
67
+ <div class="hero-visual" aria-label="CodexFlow 工作区预览">
68
+ <div class="workspace-demo">
69
+ <div class="demo-status">
70
+ <span class="status-dot" aria-hidden="true"></span>
71
+ <div class="status-label">
72
+ <strong>自动同步项目</strong>
73
+ <small>一个 broker · 一个 tunnel · 多个聊天</small>
74
+ </div>
75
+ <span class="status-badge">ready</span>
76
+ </div>
77
+ <div class="demo-grid">
78
+ <div class="chat-pane">
79
+ <small>安装</small>
80
+ <p><code>npm install -g @tarunspandit/codexflow</code><br /><code>codexflow</code></p>
81
+ <div class="message-chip">Server URL 自动复制</div>
82
+ </div>
83
+ <div class="tool-pane">
84
+ <small>然后 ChatGPT 可以</small>
85
+ <div class="tool-card-mini active">
86
+ <span>read/search</span>
87
+ <strong>读取文件并搜索代码</strong>
88
+ </div>
89
+ <div class="tool-card-mini">
90
+ <span>edit/review</span>
91
+ <strong>工作区内精确替换</strong>
92
+ </div>
93
+ <div class="tool-card-mini">
94
+ <span>verify</span>
95
+ <strong>紧凑显示 npm test / lint / build 结果</strong>
96
+ </div>
97
+ </div>
98
+ </div>
99
+ <div class="repo-pane">
100
+ <div class="repo-row"><span>README.md</span><strong>只导出选中的上下文</strong></div>
101
+ <div class="repo-row"><span>src/server.ts</span><strong>仅在 workspace 内编辑</strong></div>
102
+ <div class="repo-row"><span>.ai-bridge/current-plan.md</span><strong>handoff ready</strong></div>
103
+ <div class="repo-row"><span>~/.codex/sessions</span><strong>metadata 模式才读取</strong></div>
104
+ </div>
105
+ </div>
106
+ <div class="floating-note">
107
+ <span>这就是全部设置</span>
108
+ <strong>CodexFlow</strong>
109
+ <small>从任何目录运行;项目会自动发现。</small>
110
+ </div>
111
+ </div>
112
+ </section>
113
+
114
+ <section class="strip" aria-label="核心流程">
115
+ <div>
116
+ <span>01</span>
117
+ <strong>Install</strong>
118
+ <p>先运行 <code>npm install -g @tarunspandit/codexflow</code>。</p>
119
+ </div>
120
+ <div>
121
+ <span>02</span>
122
+ <strong>Run</strong>
123
+ <p>从任何目录运行 <code>codexflow</code>。</p>
124
+ </div>
125
+ <div>
126
+ <span>03</span>
127
+ <strong>Paste</strong>
128
+ <p>创建 ChatGPT Plugin 时粘贴复制好的 Server URL。</p>
129
+ </div>
130
+ </section>
131
+
132
+ <section class="section value-section">
133
+ <div>
134
+ <p class="eyebrow">用好已有订阅</p>
135
+ <h2>把 ChatGPT 变成本地开发工作流的一部分。</h2>
136
+ <p>
137
+ CodexFlow 面向已经有 ChatGPT Apps / Developer Mode 权限的开发者。它让 ChatGPT 不再只是回答问题,而是通过 MCP 获取本地仓库工具:读取文件、精确编辑、搜索源码、查看 git 状态、查看 diff,并运行允许范围内的验证命令。
138
+ </p>
139
+ <p>
140
+ Codex 和 ChatGPT 是不同产品界面。某个工作流暂时不可用时,如果另一个你本来就有权限的界面仍然可用,CodexFlow 可以让它继续在同一个本地仓库上工作,但不会修改任何产品限制。
141
+ </p>
142
+ <p>
143
+ 如果你的 ChatGPT 账号在 Web 产品里提供更强模型,并且该模型界面可以调用 Developer Mode Apps,CodexFlow 可以让它通过 MCP 使用本地仓库工具。CodexFlow 不提供、不代理、不转售、也不解锁模型。
144
+ </p>
145
+ </div>
146
+ <div class="value-matrix">
147
+ <div>
148
+ <small>ChatGPT 可以看到</small>
149
+ <strong>AGENTS.md、.ai-bridge、git 状态、源码文件和显式 Codex 风格上下文</strong>
150
+ </div>
151
+ <div>
152
+ <small>默认编码模式可以</small>
153
+ <strong>读取、写入、编辑、搜索,并在工作区内运行安全验证</strong>
154
+ </div>
155
+ <div>
156
+ <small>Pro 上下文回退可以</small>
157
+ <strong>给不能调用 MCP 工具的模型导出持久上下文包</strong>
158
+ </div>
159
+ <div>
160
+ <small>账号要求</small>
161
+ <strong>能使用 Apps / Developer Mode 的 ChatGPT 账号。OpenAI 当前文档列出的 web 端范围包括 Pro、Plus、Business、Enterprise 和 Education;当前测试中 Free / Go 不支持这个 app 流程。</strong>
162
+ </div>
163
+ </div>
164
+ </section>
165
+
166
+ <section id="quickstart" class="section two-col">
167
+ <div>
168
+ <p class="eyebrow">快速开始</p>
169
+ <h2>安装一次,输入 CodexFlow,完成。</h2>
170
+ <p>
171
+ 裸命令会从本机 Codex metadata 发现项目,启动 normal coding 模式、安全 bash 和 Cloudflare quick tunnel,并复制连接 URL。
172
+ </p>
173
+ </div>
174
+ <div class="steps">
175
+ <div class="step">
176
+ <span>1</span>
177
+ <div>
178
+ <strong>全局安装</strong>
179
+ <pre><code>npm install -g @tarunspandit/codexflow</code></pre>
180
+ </div>
181
+ </div>
182
+ <div class="step">
183
+ <span>2</span>
184
+ <div>
185
+ <strong>启动全部服务</strong>
186
+ <pre><code>codexflow</code></pre>
187
+ </div>
188
+ </div>
189
+ <div class="step">
190
+ <span>3</span>
191
+ <div>
192
+ <strong>粘贴 URL</strong>
193
+ <p>把自动复制的 Server URL 添加到 ChatGPT Plugin。</p>
194
+ </div>
195
+ </div>
196
+ </div>
197
+ </section>
198
+
199
+ <section id="chatgpt" class="section two-col reverse">
200
+ <div class="command-stack">
201
+ <div>
202
+ <small>ChatGPT 设置路径</small>
203
+ <pre><code>Settings
204
+ -> Security and login
205
+ -> Developer mode: on
206
+ -> Enforce CSP in developer mode: on
207
+
208
+ Settings
209
+ -> Plugins
210
+ -> Create</code></pre>
211
+ </div>
212
+ <div>
213
+ <small>创建 Plugin 字段</small>
214
+ <pre><code>Name: CodexFlow
215
+ Connection: Server URL
216
+ Server URL: paste copied URL
217
+ Authentication: No Authentication / None</code></pre>
218
+ </div>
219
+ </div>
220
+ <div>
221
+ <p class="eyebrow">ChatGPT App 设置</p>
222
+ <h2>创建 Plugin 时粘贴 CodexFlow 复制的 URL。</h2>
223
+ <p>
224
+ 保持 Enforce CSP in developer mode 开启。CodexFlow 的小组件按 CSP 开启路径设计,不依赖远程脚本、外部字体、iframe 或第三方图片。
225
+ </p>
226
+ <p>
227
+ 复制的 Server URL 已包含私有 CodexFlow token。Authentication 选择 No Authentication / None,不需要单独粘贴 token。
228
+ </p>
229
+ </div>
230
+ </section>
231
+
232
+ <section id="url" class="section">
233
+ <div class="section-heading">
234
+ <p class="eyebrow">URL 选择</p>
235
+ <h2>根据使用场景选择 tunnel。</h2>
236
+ <p>quick tunnel 适合演示,稳定 URL 适合每天使用。</p>
237
+ </div>
238
+ <div class="compare-grid">
239
+ <article>
240
+ <span class="tag">最快</span>
241
+ <h3>Cloudflare quick tunnel</h3>
242
+ <p>不需要域名设置,适合 demo。每次重启 URL 都变,因此每次都要更新 ChatGPT App 的 Server URL。</p>
243
+ <pre><code>codexflow</code></pre>
244
+ </article>
245
+ <article>
246
+ <span class="tag">推荐</span>
247
+ <h3>ngrok free dev domain</h3>
248
+ <p>推荐给大多数用户。免费 ngrok 账号会给一个 dev domain,保存一次后每天可以复用同一个 ChatGPT App URL。</p>
249
+ <pre><code>ngrok config add-authtoken YOUR_TOKEN
250
+ codexflow settings set --tunnel ngrok --hostname your-name.ngrok-free.dev
251
+ codexflow</code></pre>
252
+ </article>
253
+ <article>
254
+ <span class="tag">自定义</span>
255
+ <h3>Cloudflare named tunnel</h3>
256
+ <p>适合已有域名的用户。把 DNS 路由到 <code>codexflow.example.com</code> 这样的 hostname,之后 URL 保持不变。</p>
257
+ <pre><code>codexflow stable --hostname codexflow.example.com --tunnel-name codexflow</code></pre>
258
+ </article>
259
+ <article>
260
+ <span class="tag">Tailnet</span>
261
+ <h3>Tailscale Funnel</h3>
262
+ <p>适合已经允许 Funnel HTTPS 的 tailnet。使用这台设备的 <code>.ts.net</code> hostname。</p>
263
+ <pre><code>codexflow tailscale --hostname your-device.your-tailnet.ts.net</code></pre>
264
+ </article>
265
+ </div>
266
+ </section>
267
+
268
+ <section id="modes" class="section">
269
+ <div class="section-heading">
270
+ <p class="eyebrow">工作模式</p>
271
+ <h2>根据任务风险选择控制级别。</h2>
272
+ </div>
273
+ <div class="mode-row">
274
+ <div>
275
+ <strong>Normal coding</strong>
276
+ <p>默认模式。ChatGPT 可以在工作区内读取、写入、编辑、搜索并验证。</p>
277
+ </div>
278
+ <div>
279
+ <strong>Handoff</strong>
280
+ <p>规划模式。ChatGPT 写 <code>.ai-bridge/current-plan.md</code>,本地代理执行。</p>
281
+ </div>
282
+ <div>
283
+ <strong>Pro context</strong>
284
+ <p>给不能调用连接器或 MCP 工具的模型导出持久上下文包。</p>
285
+ </div>
286
+ </div>
287
+ </section>
288
+
289
+ <section class="section reference-section">
290
+ <div class="section-heading">
291
+ <p class="eyebrow">工具清单</p>
292
+ <h2>ChatGPT 通过 MCP 获取的本地动作。</h2>
293
+ </div>
294
+ <div class="tool-reference">
295
+ <div>
296
+ <p class="eyebrow">Standard tools</p>
297
+ <h3>默认精简的仓库读取、编辑、验证和 handoff。</h3>
298
+ </div>
299
+ <div class="tool-list">
300
+ <span>CodexFlow</span>
301
+ <span>server_config</span>
302
+ <span>codexflow_self_test</span>
303
+ <span>open_current_workspace</span>
304
+ <span>open_workspace</span>
305
+ <span>tree</span>
306
+ <span>search</span>
307
+ <span>read</span>
308
+ <span>write</span>
309
+ <span>edit</span>
310
+ <span>bash</span>
311
+ <span>show_changes</span>
312
+ <span>read_handoff</span>
313
+ <span>wait_for_handoff</span>
314
+ <span>export_pro_context</span>
315
+ <span>handoff_to_agent</span>
316
+ </div>
317
+ </div>
318
+ <div class="reference-grid compact">
319
+ <article>
320
+ <small>安全默认值</small>
321
+ <h3>敏感路径默认阻止</h3>
322
+ <p><code>.env</code>、私钥、<code>.git</code>、<code>node_modules</code>、生成目录、缓存目录、工作区外路径和 symlink 逃逸会被拒绝。</p>
323
+ </article>
324
+ <article>
325
+ <small>safe bash</small>
326
+ <h3>验证而不是任意 shell</h3>
327
+ <p>safe 模式允许常见检查、git、test、lint、typecheck 和 build 命令。只在信任的本地仓库里使用 full bash。</p>
328
+ </article>
329
+ <article>
330
+ <small>不突然跑 shell</small>
331
+ <h3>关闭或显式命中 bash</h3>
332
+ <p>正在 Codex 里工作时可以用 <code>codexflow --no-bash</code>,也可以用 <code>--bash-session main --require-bash-session</code>。这个标签属于本地 CodexFlow,不是 Codex App 聊天。</p>
333
+ </article>
334
+ <article>
335
+ <small>本地页面</small>
336
+ <h3>状态和重启命令</h3>
337
+ <p>终端按 <code>o</code> 打开 token-protected 本地页面。页面显示 mode、session 状态、allowed roots,并提供 no-bash、required bash session、Codex session metadata/read 和 full transcript 的复制按钮。</p>
338
+ </article>
339
+ <article>
340
+ <small>运行状态</small>
341
+ <h3>检查 connector 是否仍在运行</h3>
342
+ <pre><code>codexflow status
343
+ codexflow status --json</code></pre>
344
+ <p>显示当前仓库的 launcher 是否还活着、Server URL、进程 id 和本地健康状态。</p>
345
+ </article>
346
+ <article>
347
+ <small>Codex 会话</small>
348
+ <h3>显式开启本地历史列表</h3>
349
+ <p><code>--codex-sessions metadata</code> 会列出本地 Codex session id、标题、cwd 和 resume 命令。<code>read</code> 模式才允许有限 transcript 读取;两者都不会附加到正在运行的 Codex 聊天。</p>
350
+ </article>
351
+ <article>
352
+ <small>可视卡片</small>
353
+ <h3>默认关闭,需要时开启</h3>
354
+ <p>默认只暴露纯 MCP 描述。用 <code>CODEXFLOW_TOOL_CARDS=1</code> 开启后,workspace 摘要、读写 diff、bash、git/tree/search/context 和 handoff/export 都会使用紧凑结构化视图;长输出会折叠或截断。</p>
355
+ </article>
356
+ <article>
357
+ <small>上下文持久化</small>
358
+ <h3>用文件保持连续性</h3>
359
+ <p>把项目规则写进 <code>AGENTS.md</code>,把计划和决策写进 <code>.ai-bridge</code>,让 ChatGPT 换会话后也能恢复上下文。</p>
360
+ </article>
361
+ <article>
362
+ <small>本地网页后台</small>
363
+ <h3>修改下一次启动的 profile</h3>
364
+ <p>token-protected 本地页面可以保存 tunnel、hostname、port、mode、bash、Codex sessions、write/tool mode、widget origin 和 tunnel config 路径,下一次 <code>codexflow</code> 生效。原始 tunnel token、账号切换和后台服务管理仍不放进浏览器。</p>
365
+ </article>
366
+ </div>
367
+ </section>
368
+
369
+ <section id="faq" class="section">
370
+ <div class="section-heading">
371
+ <p class="eyebrow">FAQ</p>
372
+ <h2>安装前最常见的问题。</h2>
373
+ </div>
374
+ <div class="faq-grid">
375
+ <article>
376
+ <h3>需要 Plus / Pro 吗?</h3>
377
+ <p>需要能访问 Apps / Developer Mode 的 ChatGPT 账号。OpenAI 当前文档列出的 web 端范围包括 Pro、Plus、Business、Enterprise 和 Education;当前测试中 Free / Go 不支持这个 app 创建流程。</p>
378
+ </article>
379
+ <article>
380
+ <h3>这会绕过限制吗?</h3>
381
+ <p>不会。CodexFlow 不绕过、不提升、不合并、不转售、不修改任何 ChatGPT、Codex、OpenAI 或第三方模型限制。</p>
382
+ </article>
383
+ <article>
384
+ <h3>Pro 模型一定能调用工具吗?</h3>
385
+ <p>不一定。账号权限和模型工具能力是两回事。某些规划模型界面不能调用连接器或 MCP 工具,此时用 <code>codexflow pro-bundle --copy</code>。</p>
386
+ </article>
387
+ <article>
388
+ <h3>ChatGPT 能看到 Codex 上下文吗?</h3>
389
+ <p>能看到显式文件:<code>AGENTS.md</code>、<code>.ai-bridge</code>、git status、git diff 和指定源码文件。它不能读取隐藏的 Codex 运行时记忆。</p>
390
+ </article>
391
+ <article>
392
+ <h3>如何避免每次改 URL?</h3>
393
+ <p>不要用 quick tunnel 做日常使用。用 ngrok free dev domain 或 Cloudflare named tunnel 保存稳定 hostname。</p>
394
+ </article>
395
+ <article>
396
+ <h3>如何停止?</h3>
397
+ <p>终端按 <code>q</code> 或 Ctrl+C。quick URL 会失效。稳定 hostname 仍然保留,下一次 <code>codexflow</code> 可复用。</p>
398
+ </article>
399
+ </div>
400
+ <div class="link-row" aria-label="中文文档链接">
401
+ <a class="star-link" href="https://github.com/tarunspandit/codexflow"><img src="./star.svg" alt="" aria-hidden="true" />GitHub 点星</a>
402
+ <a href="https://github.com/tarunspandit/codexflow/blob/main/README_ZH.md">中文 README</a>
403
+ <a href="https://github.com/tarunspandit/codexflow/blob/main/FAQ_ZH.md">中文 FAQ</a>
404
+ <a href="https://github.com/tarunspandit/codexflow/blob/main/DOMAIN_SETUP.md">稳定 URL 指南</a>
405
+ <a href="https://github.com/tarunspandit/codexflow/blob/main/SECURITY.md">安全说明</a>
406
+ </div>
407
+ </section>
408
+
409
+ <section class="section safety">
410
+ <div>
411
+ <p class="eyebrow">安全边界</p>
412
+ <h2>这是本地开发桥,不是操作系统级沙箱。</h2>
413
+ </div>
414
+ <ul>
415
+ <li>公网 tunnel 默认使用 token 保护。</li>
416
+ <li><code>.env</code>、私钥、<code>.git</code>、<code>node_modules</code> 和 symlink 逃逸默认阻止。</li>
417
+ <li>safe bash 用于常见检查和测试,不是任意 shell 控制。</li>
418
+ <li><code>--no-bash</code> 会关闭所有 ChatGPT 触发的 shell 命令。</li>
419
+ <li><code>--bash-session</code> 加 <code>--require-bash-session</code> 会要求 bash 调用显式命中本地会话标签。</li>
420
+ <li><code>--codex-sessions</code> 默认关闭;开启后只读取本地 Codex JSONL 历史,不进入正在运行的 Codex 聊天。</li>
421
+ <li>只想让 ChatGPT 做计划时,用 handoff 模式。</li>
422
+ </ul>
423
+ </section>
424
+ </main>
425
+
426
+ <footer class="site-footer">
427
+ <span>CodexFlow</span>
428
+ <a class="star-link" href="https://github.com/tarunspandit/codexflow"><img src="./star.svg" alt="" aria-hidden="true" />GitHub 点星</a>
429
+ <a href="https://www.npmjs.com/package/@tarunspandit/codexflow">npm</a>
430
+ <a href="./index.html">English</a>
431
+ <a href="https://github.com/tarunspandit/codexflow/blob/main/SECURITY.md">安全说明</a>
432
+ </footer>
433
+
434
+ <script src="./script.js?v=2"></script>
435
+ </body>
436
+ </html>
package/package.json ADDED
@@ -0,0 +1,94 @@
1
+ {
2
+ "name": "@tarunspandit/codexflow",
3
+ "version": "0.29.0",
4
+ "description": "Independent one-command local coding backend that gives ChatGPT project, file, git, terminal, skill, and plugin access.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/tarunspandit/codexflow.git"
10
+ },
11
+ "bugs": {
12
+ "url": "https://github.com/tarunspandit/codexflow/issues"
13
+ },
14
+ "homepage": "https://tarunspandit.github.io/codexflow/",
15
+ "keywords": [
16
+ "mcp",
17
+ "chatgpt",
18
+ "codex",
19
+ "apps-sdk",
20
+ "codexflow",
21
+ "local-development",
22
+ "cloudflare-tunnel",
23
+ "ngrok",
24
+ "tailscale"
25
+ ],
26
+ "engines": {
27
+ "node": ">=20"
28
+ },
29
+ "files": [
30
+ "dist",
31
+ "docs",
32
+ "scripts",
33
+ "README.md",
34
+ "README_ZH.md",
35
+ "PUBLIC_LAUNCH_CHECKLIST.md",
36
+ "DOMAIN_SETUP.md",
37
+ "LICENSE",
38
+ "NOTICE",
39
+ "SECURITY.md",
40
+ "CONTRIBUTING.md",
41
+ "FAQ.md",
42
+ "FAQ_ZH.md",
43
+ "CHANGELOG.md",
44
+ "CHATGPT_PROMPT.md",
45
+ "CODEX_PROMPT.md",
46
+ "AGENTS.example.md",
47
+ "config.example.env"
48
+ ],
49
+ "publishConfig": {
50
+ "access": "public"
51
+ },
52
+ "bin": {
53
+ "codexflow": "scripts/codexflow.mjs",
54
+ "codexflow-mcp": "dist/stdio.js",
55
+ "codexflow-mcp-http": "dist/http.js"
56
+ },
57
+ "scripts": {
58
+ "build": "node scripts/clean.mjs && tsc -p tsconfig.json",
59
+ "prepack": "npm run build",
60
+ "start": "node dist/stdio.js",
61
+ "start:stdio": "node dist/stdio.js",
62
+ "start:http": "node dist/http.js",
63
+ "dev:stdio": "tsx src/stdio.ts",
64
+ "dev:http": "tsx src/http.ts",
65
+ "smoke": "node scripts/analysis-smoke.mjs && node scripts/analysis-cli-smoke.mjs && node scripts/smoke.mjs && node scripts/http-smoke.mjs && node scripts/pro-smoke.mjs && node scripts/doctor-smoke.mjs && node scripts/settings-smoke.mjs && node scripts/cli-smoke.mjs && node scripts/execute-handoff-smoke.mjs",
66
+ "stress": "npm run build && node scripts/stress.mjs",
67
+ "analysis:smoke": "npm run build && node scripts/analysis-smoke.mjs",
68
+ "analysis:cli-smoke": "npm run build && node scripts/analysis-cli-smoke.mjs",
69
+ "doctor": "node scripts/codexflow.mjs doctor",
70
+ "connect": "node scripts/codexflow.mjs",
71
+ "connect:local": "node scripts/codexflow.mjs --tunnel none",
72
+ "connect:cloudflare": "node scripts/codexflow.mjs --tunnel cloudflare",
73
+ "connect:chatgpt": "node scripts/codexflow.mjs --tunnel cloudflare",
74
+ "connect:stable": "node scripts/codexflow.mjs --tunnel cloudflare-named",
75
+ "connect:ngrok": "node scripts/codexflow.mjs ngrok",
76
+ "connect:tailscale": "node scripts/codexflow.mjs tailscale",
77
+ "pro:bundle": "node scripts/pro-bundle.mjs",
78
+ "pro:apply": "node scripts/pro-apply.mjs"
79
+ },
80
+ "dependencies": {
81
+ "@modelcontextprotocol/sdk": "^1.17.4",
82
+ "cors": "^2.8.5",
83
+ "express": "^5.1.0",
84
+ "minimatch": "^10.0.1",
85
+ "zod": "^3.25.76"
86
+ },
87
+ "devDependencies": {
88
+ "@types/cors": "^2.8.19",
89
+ "@types/express": "^5.0.3",
90
+ "@types/node": "^24.0.0",
91
+ "tsx": "^4.20.3",
92
+ "typescript": "^5.8.3"
93
+ }
94
+ }
@@ -0,0 +1,81 @@
1
+ import assert from 'node:assert/strict';
2
+ import { spawnSync } from 'node:child_process';
3
+ import fs from 'node:fs/promises';
4
+ import os from 'node:os';
5
+ import path from 'node:path';
6
+ import { fileURLToPath } from 'node:url';
7
+
8
+ const projectRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
9
+ const cli = path.join(projectRoot, 'scripts', 'codexflow.mjs');
10
+ const root = await fs.mkdtemp(path.join(os.tmpdir(), 'codexflow-analysis-cli-'));
11
+ const home = await fs.mkdtemp(path.join(os.tmpdir(), 'codexflow-analysis-cli-home-'));
12
+
13
+ function run(args) {
14
+ return spawnSync(process.execPath, [cli, ...args], {
15
+ cwd: projectRoot,
16
+ encoding: 'utf8',
17
+ timeout: 5000,
18
+ env: { ...process.env, NO_COLOR: '1', CI: '1', CODEXFLOW_HOME: home }
19
+ });
20
+ }
21
+
22
+ try {
23
+ await fs.mkdir(path.join(root, 'src'), { recursive: true });
24
+ await fs.mkdir(path.join(root, 'test'), { recursive: true });
25
+ await fs.writeFile(path.join(root, 'package.json'), JSON.stringify({ name: 'cli-fixture', scripts: { test: 'node --test' } }, null, 2), 'utf8');
26
+ await fs.writeFile(path.join(root, 'src', 'auth.ts'), 'export function authenticate(user) { return Boolean(user); }\n', 'utf8');
27
+ await fs.writeFile(path.join(root, 'test', 'auth.test.ts'), "import { authenticate } from '../src/auth.js';\nvoid authenticate('test');\n", 'utf8');
28
+ for (const args of [['init'], ['add', '.']]) {
29
+ const result = spawnSync('git', args, { cwd: root, encoding: 'utf8' });
30
+ assert.equal(result.status, 0, result.stderr || result.stdout);
31
+ }
32
+ const commit = spawnSync('git', ['-c', 'user.email=cli@example.com', '-c', 'user.name=CLI Test', 'commit', '-m', 'fixture'], { cwd: root, encoding: 'utf8' });
33
+ assert.equal(commit.status, 0, commit.stderr || commit.stdout);
34
+ await fs.writeFile(path.join(root, 'src', 'auth.ts'), 'export function authenticate(user) { return Boolean(user?.trim()); }\n', 'utf8');
35
+
36
+ const inspect = run(['inspect', '--root', root, '--json']);
37
+ assert.equal(inspect.status, 0, inspect.stderr || inspect.stdout || inspect.error?.message);
38
+ const inspectJson = JSON.parse(inspect.stdout);
39
+ assert.equal(inspectJson.schema_version, 1);
40
+ assert(inspectJson.languages.includes('typescript'));
41
+ assert(inspectJson.entrypoints.length >= 0);
42
+
43
+ const review = run(['review', '--root', root, '--json']);
44
+ assert.equal(review.status, 0, review.stderr || review.stdout || review.error?.message);
45
+ const reviewJson = JSON.parse(review.stdout);
46
+ assert.equal(reviewJson.schema_version, 1);
47
+ assert(reviewJson.changed_files.includes('src/auth.ts'));
48
+ assert(reviewJson.risk_signals.some((risk) => risk.id === 'authentication'));
49
+ assert(reviewJson.related_tests.some((file) => file.path === 'test/auth.test.ts'));
50
+
51
+ const stage = spawnSync('git', ['add', 'src/auth.ts'], { cwd: root, encoding: 'utf8' });
52
+ assert.equal(stage.status, 0, stage.stderr || stage.stdout);
53
+ const stagedReview = run(['review', '--root', root, '--staged', '--path', 'src/auth.ts', '--json']);
54
+ assert.equal(stagedReview.status, 0, stagedReview.stderr || stagedReview.stdout || stagedReview.error?.message);
55
+ const stagedReviewJson = JSON.parse(stagedReview.stdout);
56
+ assert.deepEqual(stagedReviewJson.changed_files, ['src/auth.ts']);
57
+ assert(stagedReviewJson.risk_signals.some((risk) => risk.id === 'authentication'));
58
+
59
+ const human = run(['inspect', '--root', root]);
60
+ assert.equal(human.status, 0, human.stderr || human.stdout);
61
+ for (const heading of ['Workspace', 'Projects', 'Languages', 'Coverage']) assert(human.stdout.includes(heading));
62
+ assert(!/\u001b\[/.test(human.stdout));
63
+
64
+ const missing = run(['inspect', '--root', path.join(root, 'missing'), '--json']);
65
+ assert.notEqual(missing.status, 0);
66
+ assert.match(missing.stderr, /does not exist/i);
67
+
68
+ const nonGitRoot = await fs.mkdtemp(path.join(os.tmpdir(), 'codexflow-analysis-cli-non-git-'));
69
+ try {
70
+ const nonGitReview = run(['review', '--root', nonGitRoot, '--json']);
71
+ assert.notEqual(nonGitReview.status, 0);
72
+ assert.match(nonGitReview.stderr, /Unable to read Git changes/i);
73
+ } finally {
74
+ await fs.rm(nonGitRoot, { recursive: true, force: true });
75
+ }
76
+
77
+ console.log('✓ analysis CLI smoke test passed');
78
+ } finally {
79
+ await fs.rm(root, { recursive: true, force: true });
80
+ await fs.rm(home, { recursive: true, force: true });
81
+ }