codex-to-im 0.1.2 → 0.1.6
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/README.md +51 -4
- package/README_CN.md +49 -3
- package/config.env.example +36 -12
- package/dist/cli.mjs +9 -4
- package/dist/daemon.mjs +1766 -356
- package/dist/ui-server.mjs +1046 -110
- package/docs/install-windows.md +44 -6
- package/package.json +2 -1
- package/scripts/patch-codex-sdk-windows-hide.js +83 -0
package/docs/install-windows.md
CHANGED
|
@@ -141,6 +141,15 @@ http://127.0.0.1:4781
|
|
|
141
141
|
|
|
142
142
|
如果 `4781` 已被占用,程序会自动查找一个可用端口,并在启动时把实际地址打印到命令行。
|
|
143
143
|
|
|
144
|
+
默认情况下,Web 工作台只允许本机访问。
|
|
145
|
+
|
|
146
|
+
如果你要在手机或局域网其他设备上打开配置页,可以在“配置”页里勾选“允许局域网访问 Web 控制台”。开启后:
|
|
147
|
+
|
|
148
|
+
- 工作台会显示当前可用的局域网地址
|
|
149
|
+
- 工作台会显示访问 token
|
|
150
|
+
- 局域网设备访问时会先看到登录页,输入 token 后才能进入工作台
|
|
151
|
+
- 也可以直接复制工作台里的局域网登录链接,链接中会附带 `?token=...`
|
|
152
|
+
|
|
144
153
|
如果之后忘记了当前 Web 地址,可以执行:
|
|
145
154
|
|
|
146
155
|
```powershell
|
|
@@ -167,22 +176,34 @@ codex-to-im stop
|
|
|
167
176
|
- 推荐:`codex`
|
|
168
177
|
2. 设置默认工作目录
|
|
169
178
|
3. 设置 `/history` 默认返回条数(可选)
|
|
170
|
-
4.
|
|
171
|
-
|
|
179
|
+
4. 设置默认工作空间
|
|
180
|
+
- 用于 `/new proj1` 这类相对项目名
|
|
181
|
+
- 留空时自动回退到 `~/cx2im`,并按当前系统展开为实际路径
|
|
182
|
+
5. 选择 Codex 文件系统权限
|
|
183
|
+
- 默认推荐 `workspace-write`
|
|
184
|
+
6. 选择 Codex 思考级别
|
|
185
|
+
- 默认推荐 `medium`
|
|
186
|
+
- 官方仅有 5 个级别:`minimal`、`low`、`medium`、`high`、`xhigh`
|
|
187
|
+
- 如果这台机器就是你自己的本地开发机,希望 `codex-to-im` 直接承担更强的编码执行能力,建议改成:
|
|
188
|
+
- 文件系统权限:`danger-full-access`
|
|
189
|
+
- 思考级别:`xhigh`
|
|
190
|
+
7. 如果目标目录不是 Codex 已信任的 Git 仓库,可勾选“允许在未信任 Git 目录运行 Codex”
|
|
191
|
+
8. 如果要从局域网设备访问配置页,可勾选“允许局域网访问 Web 控制台”
|
|
192
|
+
9. 勾选要启用的通道
|
|
172
193
|
- 飞书:勾选 `启用飞书`
|
|
173
194
|
- 微信:勾选 `启用微信`
|
|
174
|
-
|
|
195
|
+
10. 飞书场景下填写:
|
|
175
196
|
- `App ID`
|
|
176
197
|
- `App Secret`
|
|
177
198
|
- `Domain`
|
|
178
199
|
- `Allowed Users` 可选
|
|
179
200
|
- `启用飞书流式响应卡片` 可选
|
|
180
|
-
|
|
201
|
+
11. 微信场景下点击:
|
|
181
202
|
- `开始微信扫码`
|
|
182
|
-
|
|
203
|
+
12. 点击测试
|
|
183
204
|
- 飞书:`测试飞书凭据`
|
|
184
205
|
- Codex:`测试 Codex`
|
|
185
|
-
|
|
206
|
+
13. 点击:
|
|
186
207
|
- `启动 Bridge`
|
|
187
208
|
|
|
188
209
|
说明:
|
|
@@ -196,7 +217,24 @@ codex-to-im stop
|
|
|
196
217
|
- 缺权限时,`logs\\bridge.log` 里通常会出现 `99991672` 和 `cardkit:card:write`。
|
|
197
218
|
- 另外,当前 `codex` runtime 下正文通常不是逐字流式输出;更常见的效果是先显示 `Thinking / Tool Progress`,正文在回答完成时一次性落到卡片里。
|
|
198
219
|
- IM 里发送 `/history` 可以查看当前会话最近 N 条消息,N 由“基础配置”中的返回条数控制。
|
|
220
|
+
- IM 里发送 `/history` 默认返回整理后的摘要;发送 `/history raw` 才会查看最近 N 条原始消息。
|
|
221
|
+
- IM 里发送 `/reasoning high` 或 `/reasoning 4` 之类命令,可以只对当前会话覆盖思考级别。
|
|
222
|
+
- IM 里发送 `/thread 0` 会进入临时草稿线程,适合短讨论或临时想法。
|
|
223
|
+
- “通道”页里可以分别控制“命令反馈使用 Markdown”:
|
|
224
|
+
- 飞书默认开启
|
|
225
|
+
- 微信默认关闭
|
|
226
|
+
- 只影响 `/h`、`/status`、`/threads` 这类系统反馈,不影响 Codex 原始回复
|
|
227
|
+
- IM 里也支持一组短命令别名:
|
|
228
|
+
- `/` / `/status` 当前会话
|
|
229
|
+
- `/h` / `/help` 帮助
|
|
230
|
+
- `/t` / `/threads` 最近桌面会话,`/t 1` / `/thread 1` 接管
|
|
231
|
+
- `/n proj1` / `/new proj1` 新建项目会话
|
|
232
|
+
- `/m` / `/mode` 查看或切换模式,可选 `code` / `plan` / `ask`
|
|
233
|
+
- `/r` / `/reasoning` 查看或切换思考级别,也支持 `1|2|3|4|5`
|
|
234
|
+
- `/his` / `/history` 历史摘要,`/his raw` / `/history raw` 原始记录
|
|
235
|
+
- `/t 0` / `/thread 0` 临时草稿线程
|
|
199
236
|
- 如果 `测试 Codex` 失败,优先检查当前 Windows 用户下是否已经存在可用的 Codex 登录态或 API Key。
|
|
237
|
+
- 如果开启了局域网访问,建议直接从本机工作台复制局域网登录链接,再发给手机或其他设备打开。
|
|
200
238
|
|
|
201
239
|
## 7. 目标机上的目录说明
|
|
202
240
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "codex-to-im",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.6",
|
|
4
4
|
"description": "Installable Codex-to-IM bridge with local setup UI and background service",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"codex-to-im": "dist/cli.mjs"
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
|
+
"postinstall": "node scripts/patch-codex-sdk-windows-hide.js",
|
|
23
24
|
"build": "node scripts/build.js",
|
|
24
25
|
"typecheck": "tsc --noEmit",
|
|
25
26
|
"dev": "tsx src/main.ts",
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
|
|
4
|
+
const PATCH_MARKER = 'windowsHide: process.platform === "win32"';
|
|
5
|
+
const SUPPORTED_SDK_VERSION = /^0\.110\.\d+$/;
|
|
6
|
+
|
|
7
|
+
function logSkip(message) {
|
|
8
|
+
console.warn(`[postinstall] ${message}`);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function resolveSdkPaths() {
|
|
12
|
+
const packageRoot = path.join(process.cwd(), 'node_modules', '@openai', 'codex-sdk');
|
|
13
|
+
const packageJsonPath = path.join(packageRoot, 'package.json');
|
|
14
|
+
const entryPath = path.join(packageRoot, 'dist', 'index.js');
|
|
15
|
+
if (!fs.existsSync(packageJsonPath) || !fs.existsSync(entryPath)) {
|
|
16
|
+
return null;
|
|
17
|
+
}
|
|
18
|
+
return { packageJsonPath, entryPath };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function readSdkVersion(packageJsonPath) {
|
|
22
|
+
try {
|
|
23
|
+
const pkg = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
24
|
+
return typeof pkg.version === 'string' ? pkg.version : null;
|
|
25
|
+
} catch {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function applyPatch(filePath) {
|
|
31
|
+
const source = fs.readFileSync(filePath, 'utf-8');
|
|
32
|
+
if (source.includes(PATCH_MARKER)) {
|
|
33
|
+
console.log('[postinstall] codex-sdk windowsHide patch already applied');
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const patched = source.replace(
|
|
38
|
+
/const child = spawn\(this\.executablePath, commandArgs, \{\s*env,\s*signal: args\.signal\s*\}\);/,
|
|
39
|
+
`const child = spawn(this.executablePath, commandArgs, {
|
|
40
|
+
env,
|
|
41
|
+
windowsHide: process.platform === "win32",
|
|
42
|
+
signal: args.signal
|
|
43
|
+
});`,
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
if (patched === source) {
|
|
47
|
+
throw new Error(`Unable to locate Codex SDK spawn block in ${filePath}`);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
fs.writeFileSync(filePath, patched, 'utf-8');
|
|
51
|
+
console.log(`[postinstall] patched codex-sdk windowsHide in ${path.relative(process.cwd(), filePath)}`);
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (process.platform !== 'win32') {
|
|
56
|
+
console.log('[postinstall] non-Windows platform detected, skipping codex-sdk windowsHide patch');
|
|
57
|
+
process.exit(0);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const sdkPaths = resolveSdkPaths();
|
|
61
|
+
if (!sdkPaths) {
|
|
62
|
+
console.log('[postinstall] @openai/codex-sdk not installed, skipping windowsHide patch');
|
|
63
|
+
process.exit(0);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const sdkVersion = readSdkVersion(sdkPaths.packageJsonPath);
|
|
67
|
+
if (!sdkVersion) {
|
|
68
|
+
logSkip('unable to read @openai/codex-sdk version, skipping windowsHide patch');
|
|
69
|
+
process.exit(0);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!SUPPORTED_SDK_VERSION.test(sdkVersion)) {
|
|
73
|
+
logSkip(`unsupported @openai/codex-sdk version ${sdkVersion}; skipping windowsHide patch`);
|
|
74
|
+
process.exit(0);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
try {
|
|
78
|
+
applyPatch(sdkPaths.entryPath);
|
|
79
|
+
} catch (error) {
|
|
80
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
81
|
+
logSkip(`failed to patch codex-sdk windowsHide (${message}); install will continue and the Windows console may still appear`);
|
|
82
|
+
process.exit(0);
|
|
83
|
+
}
|