codex-to-im 0.1.5 → 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 +41 -5
- package/README_CN.md +38 -3
- package/config.env.example +27 -9
- package/dist/cli.mjs +9 -4
- package/dist/daemon.mjs +1596 -318
- package/dist/ui-server.mjs +520 -98
- package/docs/install-windows.md +34 -7
- package/package.json +2 -1
- package/scripts/patch-codex-sdk-windows-hide.js +83 -0
package/README.md
CHANGED
|
@@ -38,13 +38,13 @@ Windows host installation guide: [docs/install-windows.md](D:/codex/Claude-to-IM
|
|
|
38
38
|
### Prerequisites
|
|
39
39
|
|
|
40
40
|
- Node.js 20+
|
|
41
|
-
- If you use the `codex` or `auto` runtime, complete Codex authentication under the same
|
|
41
|
+
- If you use the `codex` or `auto` runtime, complete Codex authentication under the same OS user account
|
|
42
42
|
|
|
43
43
|
`codex-to-im` now ships with the required `@openai/codex-sdk` / Codex CLI platform dependency, so you do not need to install a separate global Codex CLI just to run the bridge.
|
|
44
44
|
|
|
45
45
|
You still need Codex credentials to be available for the current user. Any of these is sufficient:
|
|
46
46
|
|
|
47
|
-
- a logged-in Codex
|
|
47
|
+
- a logged-in Codex Desktop App
|
|
48
48
|
- an existing Codex CLI login state
|
|
49
49
|
- `CTI_CODEX_API_KEY`, `CODEX_API_KEY`, or `OPENAI_API_KEY`
|
|
50
50
|
|
|
@@ -125,10 +125,19 @@ codex-to-im stop
|
|
|
125
125
|
|
|
126
126
|
If LAN access is enabled, the easiest path is to copy the LAN login link from the local workbench and open it on your phone or another device on the same network.
|
|
127
127
|
|
|
128
|
-
Useful
|
|
129
|
-
|
|
130
|
-
- `/
|
|
128
|
+
Useful commands:
|
|
129
|
+
|
|
130
|
+
- `/` / `/status` shows the current session
|
|
131
|
+
- `/h` / `/help` shows help
|
|
132
|
+
- `/t` / `/threads` lists recent desktop threads, and `/t 1` / `/thread 1` binds the first one
|
|
133
|
+
- `/n proj1` / `/new proj1` creates a new project session under the default workspace root
|
|
134
|
+
- `/m` / `/mode` shows or changes the current mode; options: `code` / `plan` / `ask`
|
|
135
|
+
- `/r` / `/reasoning` shows or changes the current reasoning effort; options: `1|2|3|4|5`
|
|
136
|
+
- `/his` / `/history` shows the summarized history, and `/his raw` / `/history raw` shows raw history
|
|
137
|
+
- `/t 0` / `/thread 0` enters a temporary draft thread that does not pollute the main work thread
|
|
138
|
+
- `1 / 2 / 3` or `/perm ...` handles permission prompts
|
|
131
139
|
- N is configurable in the web workbench under the basic settings panel
|
|
140
|
+
- The workbench command guide shows both short commands and compatible original commands
|
|
132
141
|
|
|
133
142
|
If you enable Feishu streaming response cards, the Feishu app must have the required permissions published first, at minimum:
|
|
134
143
|
|
|
@@ -150,6 +159,33 @@ If creating a new session fails with `Not inside a trusted directory`, either:
|
|
|
150
159
|
- change the default working directory to a trusted Git repo, or
|
|
151
160
|
- enable `Allow Codex outside trusted Git repos` in the basic settings and restart the bridge
|
|
152
161
|
|
|
162
|
+
The configuration page also includes Codex runtime controls:
|
|
163
|
+
|
|
164
|
+
- `Default workspace root`
|
|
165
|
+
- parent directory used for `/new proj1`
|
|
166
|
+
- falls back to `~/cx2im` when left empty, expanded for the current OS
|
|
167
|
+
- `Codex filesystem permission`
|
|
168
|
+
- `read-only`, `workspace-write`, or `danger-full-access`
|
|
169
|
+
- default: `workspace-write`
|
|
170
|
+
- `Codex reasoning effort`
|
|
171
|
+
- global default reasoning level
|
|
172
|
+
- can be overridden per IM session with `/reasoning`
|
|
173
|
+
- official runtime levels are `minimal`, `low`, `medium`, `high`, `xhigh`
|
|
174
|
+
- IM numeric aliases are `1=minimal`, `2=low`, `3=medium`, `4=high`, `5=xhigh`
|
|
175
|
+
|
|
176
|
+
If you are using `codex-to-im` on your own development machine for real coding work, the more aggressive recommended setup is:
|
|
177
|
+
|
|
178
|
+
- set `Codex filesystem permission` to `danger-full-access`
|
|
179
|
+
- set `Codex reasoning effort` to `xhigh`
|
|
180
|
+
|
|
181
|
+
This is closer to a full-power `code` workflow. It fits a controlled local project, but is not a good default for unknown repositories or higher-risk environments.
|
|
182
|
+
|
|
183
|
+
The channel pages also expose a “Use Markdown for command feedback” switch:
|
|
184
|
+
- enabled by default for Feishu
|
|
185
|
+
- disabled by default for WeChat
|
|
186
|
+
- only affects bridge-generated feedback such as `/h`, `/status`, and `/threads`
|
|
187
|
+
- does not affect raw Codex replies
|
|
188
|
+
|
|
153
189
|
## Update
|
|
154
190
|
|
|
155
191
|
On Windows, `npm update -g codex-to-im` can fail with `EBUSY` if the background UI or bridge is still running from the global install directory.
|
package/README_CN.md
CHANGED
|
@@ -38,13 +38,13 @@ Windows 主机安装说明见:[docs/install-windows.md](D:/codex/Claude-to-IM-
|
|
|
38
38
|
### 依赖
|
|
39
39
|
|
|
40
40
|
- Node.js 20+
|
|
41
|
-
- 如果使用 `codex` 或 `auto`
|
|
41
|
+
- 如果使用 `codex` 或 `auto` 运行时:需要在同一系统用户下完成 Codex 认证
|
|
42
42
|
|
|
43
43
|
`codex-to-im` 当前已经随包带上运行所需的 `@openai/codex-sdk` / Codex CLI 平台依赖,正常使用 bridge 时不要求你额外再全局安装一份 Codex CLI。
|
|
44
44
|
|
|
45
45
|
但你仍然需要让 Codex 在当前用户下可用。推荐满足以下任一条件:
|
|
46
46
|
|
|
47
|
-
- 已安装并登录过 Codex
|
|
47
|
+
- 已安装并登录过 Codex Desktop App
|
|
48
48
|
- 已经有可用的 Codex CLI 登录态
|
|
49
49
|
- 已配置 `CTI_CODEX_API_KEY`、`CODEX_API_KEY` 或 `OPENAI_API_KEY`
|
|
50
50
|
|
|
@@ -127,8 +127,17 @@ codex-to-im stop
|
|
|
127
127
|
|
|
128
128
|
常用命令补充:
|
|
129
129
|
|
|
130
|
-
- `/
|
|
130
|
+
- `/` / `/status` 查看当前会话
|
|
131
|
+
- `/h` / `/help` 查看帮助
|
|
132
|
+
- `/t` / `/threads` 查看最近桌面会话,`/t 1` / `/thread 1` 接管第 1 条
|
|
133
|
+
- `/n proj1` / `/new proj1` 在默认工作空间下新建项目会话
|
|
134
|
+
- `/m` / `/mode` 查看或切换模式,可选 `code` / `plan` / `ask`
|
|
135
|
+
- `/r` / `/reasoning` 查看或切换思考级别,可选 `1|2|3|4|5`
|
|
136
|
+
- `/his` / `/history` 查看整理后的历史摘要,`/his raw` / `/history raw` 查看原始记录
|
|
137
|
+
- `/t 0` / `/thread 0` 进入临时草稿线程,不污染正式工作会话
|
|
138
|
+
- `1 / 2 / 3` 或 `/perm ...` 处理权限
|
|
131
139
|
- N 可在 Web 工作台的“基础配置”里调整
|
|
140
|
+
- Web 工作台的“命令说明”页会同时列出短命令和兼容原命令
|
|
132
141
|
|
|
133
142
|
如果你启用了飞书流式响应卡片,需要先在飞书应用侧开通并发布相关权限,至少包括:
|
|
134
143
|
|
|
@@ -150,6 +159,32 @@ codex-to-im stop
|
|
|
150
159
|
- 把默认工作目录改成一个你已经信任的 Git 仓库
|
|
151
160
|
- 或在基础配置里打开“允许在未信任 Git 目录运行 Codex”,然后重启 Bridge
|
|
152
161
|
|
|
162
|
+
当前配置页新增了几项和 Codex 运行行为直接相关的配置:
|
|
163
|
+
|
|
164
|
+
- `默认工作空间`
|
|
165
|
+
- 给 `/new proj1` 这类相对项目名提供父目录
|
|
166
|
+
- 留空时默认回退到 `~/cx2im`,并按当前系统展开为实际路径
|
|
167
|
+
- `Codex 文件系统权限`
|
|
168
|
+
- 可选 `read-only`、`workspace-write`、`danger-full-access`
|
|
169
|
+
- 默认 `workspace-write`
|
|
170
|
+
- `Codex 思考级别`
|
|
171
|
+
- 全局默认值,可在 IM 中用 `/reasoning` 对当前会话覆盖
|
|
172
|
+
- 官方仅有 5 个级别:`minimal`、`low`、`medium`、`high`、`xhigh`
|
|
173
|
+
- IM 中也支持数字别名:`1=minimal`、`2=low`、`3=medium`、`4=high`、`5=xhigh`
|
|
174
|
+
|
|
175
|
+
如果你是在自己的本地开发机上长期用 `codex-to-im` 做实际编码,当前更激进的推荐配置是:
|
|
176
|
+
|
|
177
|
+
- `Codex 文件系统权限` 设为 `danger-full-access`
|
|
178
|
+
- `Codex 思考级别` 设为 `xhigh`
|
|
179
|
+
|
|
180
|
+
这样更接近完整 `code` 模式下的开发体验。它适合你自己的受控项目目录,不适合直接照搬到陌生仓库或高风险环境。
|
|
181
|
+
|
|
182
|
+
通道页还支持“命令反馈使用 Markdown”开关:
|
|
183
|
+
- 飞书默认开启
|
|
184
|
+
- 微信默认关闭
|
|
185
|
+
- 只影响 `/h`、`/status`、`/threads` 这类 bridge 自己生成的反馈
|
|
186
|
+
- 不影响 Codex 原始回复内容
|
|
187
|
+
|
|
153
188
|
## 更新
|
|
154
189
|
|
|
155
190
|
Windows 上如果后台 UI 或 bridge 仍在运行,`npm update -g codex-to-im` 可能会因为安装目录被占用而报 `EBUSY`。
|
package/config.env.example
CHANGED
|
@@ -11,10 +11,15 @@ CTI_RUNTIME=codex
|
|
|
11
11
|
CTI_ENABLED_CHANNELS=feishu
|
|
12
12
|
|
|
13
13
|
# Default working directory for Codex / bridge sessions
|
|
14
|
-
CTI_DEFAULT_WORKDIR=/path/to/your/project
|
|
15
|
-
|
|
16
|
-
# Default
|
|
17
|
-
#
|
|
14
|
+
CTI_DEFAULT_WORKDIR=/path/to/your/project
|
|
15
|
+
|
|
16
|
+
# Default workspace root for `/new proj1` style project creation.
|
|
17
|
+
# When unset, codex-to-im falls back to `~/cx2im`
|
|
18
|
+
# and expands it per OS (Windows/macOS/Linux).
|
|
19
|
+
# CTI_DEFAULT_WORKSPACE_ROOT=/path/to/your/workspace
|
|
20
|
+
|
|
21
|
+
# Default model (optional — inherits from runtime's own default if not set)
|
|
22
|
+
# CTI_DEFAULT_MODEL=
|
|
18
23
|
|
|
19
24
|
# Default mode (code, plan, ask)
|
|
20
25
|
CTI_DEFAULT_MODE=code
|
|
@@ -43,6 +48,13 @@ CTI_DEFAULT_MODE=code
|
|
|
43
48
|
# Allow Codex to run when CTI_DEFAULT_WORKDIR is not inside a trusted Git repo.
|
|
44
49
|
# This project defaults it to true so first-time setup works more smoothly.
|
|
45
50
|
CTI_CODEX_SKIP_GIT_REPO_CHECK=true
|
|
51
|
+
# Default filesystem permission mode for Codex threads created by codex-to-im.
|
|
52
|
+
# Options: read-only | workspace-write | danger-full-access
|
|
53
|
+
CTI_CODEX_SANDBOX_MODE=workspace-write
|
|
54
|
+
# Default reasoning effort for Codex.
|
|
55
|
+
# Official SDK/runtime levels: minimal | low | medium | high | xhigh
|
|
56
|
+
# IM aliases also support: 1=minimal, 2=low, 3=medium, 4=high, 5=xhigh
|
|
57
|
+
CTI_CODEX_REASONING_EFFORT=medium
|
|
46
58
|
|
|
47
59
|
# ── Web 控制台访问 ──
|
|
48
60
|
# 默认仅允许本机访问本地工作台。开启后,局域网设备访问时需要先输入 token。
|
|
@@ -76,6 +88,9 @@ CTI_TG_CHAT_ID=your-chat-id
|
|
|
76
88
|
# Current Codex runtime note: thinking/progress can update live, but
|
|
77
89
|
# assistant body text may still arrive only at completion.
|
|
78
90
|
# CTI_FEISHU_STREAMING_ENABLED=true
|
|
91
|
+
# Use Markdown for bridge-generated command feedback such as /h or /status.
|
|
92
|
+
# Does not affect raw Codex replies.
|
|
93
|
+
# CTI_FEISHU_COMMAND_MARKDOWN_ENABLED=true
|
|
79
94
|
|
|
80
95
|
# ── QQ ──
|
|
81
96
|
# Required: obtain from https://q.qq.com/qqbot/openclaw
|
|
@@ -94,11 +109,14 @@ CTI_TG_CHAT_ID=your-chat-id
|
|
|
94
109
|
# Optional protocol overrides (normally leave unset)
|
|
95
110
|
# CTI_WEIXIN_BASE_URL=https://ilinkai.weixin.qq.com
|
|
96
111
|
# CTI_WEIXIN_CDN_BASE_URL=https://novac2c.cdn.weixin.qq.com/c2c
|
|
97
|
-
# Enable inbound media download/processing for image/file/video messages.
|
|
98
|
-
# Voice messages do not use raw audio download/transcription here: the bridge
|
|
99
|
-
# only accepts WeChat-provided speech-to-text text and otherwise returns an error.
|
|
100
|
-
# (default false for safety in CLI setups)
|
|
101
|
-
# CTI_WEIXIN_MEDIA_ENABLED=false
|
|
112
|
+
# Enable inbound media download/processing for image/file/video messages.
|
|
113
|
+
# Voice messages do not use raw audio download/transcription here: the bridge
|
|
114
|
+
# only accepts WeChat-provided speech-to-text text and otherwise returns an error.
|
|
115
|
+
# (default false for safety in CLI setups)
|
|
116
|
+
# CTI_WEIXIN_MEDIA_ENABLED=false
|
|
117
|
+
# Use Markdown for bridge-generated command feedback such as /h or /status.
|
|
118
|
+
# Does not affect raw Codex replies. Default is false for WeChat.
|
|
119
|
+
# CTI_WEIXIN_COMMAND_MARKDOWN_ENABLED=false
|
|
102
120
|
|
|
103
121
|
# ── Permission ──
|
|
104
122
|
# Auto-approve all tool permission requests without user confirmation.
|
package/dist/cli.mjs
CHANGED
|
@@ -14,6 +14,7 @@ import os from "node:os";
|
|
|
14
14
|
import path from "node:path";
|
|
15
15
|
var LEGACY_CTI_HOME = path.join(os.homedir(), ".claude-to-im");
|
|
16
16
|
var DEFAULT_CTI_HOME = path.join(os.homedir(), ".codex-to-im");
|
|
17
|
+
var DEFAULT_WORKSPACE_ROOT = path.join(os.homedir(), "cx2im");
|
|
17
18
|
function resolveDefaultCtiHome() {
|
|
18
19
|
if (fs.existsSync(DEFAULT_CTI_HOME)) return DEFAULT_CTI_HOME;
|
|
19
20
|
if (fs.existsSync(LEGACY_CTI_HOME)) return LEGACY_CTI_HOME;
|
|
@@ -31,6 +32,7 @@ var bridgePidFile = path2.join(runtimeDir, "bridge.pid");
|
|
|
31
32
|
var bridgeStatusFile = path2.join(runtimeDir, "status.json");
|
|
32
33
|
var uiStatusFile = path2.join(runtimeDir, "ui-server.json");
|
|
33
34
|
var uiPort = 4781;
|
|
35
|
+
var WINDOWS_HIDE = process.platform === "win32" ? { windowsHide: true } : {};
|
|
34
36
|
function ensureDirs() {
|
|
35
37
|
fs2.mkdirSync(runtimeDir, { recursive: true });
|
|
36
38
|
fs2.mkdirSync(logsDir, { recursive: true });
|
|
@@ -125,7 +127,8 @@ async function stopBridge() {
|
|
|
125
127
|
if (process.platform === "win32") {
|
|
126
128
|
await new Promise((resolve) => {
|
|
127
129
|
const killer = spawn("cmd", ["/c", "taskkill", "/PID", String(status.pid), "/T", "/F"], {
|
|
128
|
-
stdio: "ignore"
|
|
130
|
+
stdio: "ignore",
|
|
131
|
+
...WINDOWS_HIDE
|
|
129
132
|
});
|
|
130
133
|
killer.on("exit", () => resolve());
|
|
131
134
|
killer.on("error", () => resolve());
|
|
@@ -161,7 +164,8 @@ async function ensureUiServerRunning() {
|
|
|
161
164
|
...process.env,
|
|
162
165
|
CTI_HOME
|
|
163
166
|
},
|
|
164
|
-
stdio: ["ignore", stdoutFd, stderrFd]
|
|
167
|
+
stdio: ["ignore", stdoutFd, stderrFd],
|
|
168
|
+
...WINDOWS_HIDE
|
|
165
169
|
});
|
|
166
170
|
child.unref();
|
|
167
171
|
const status = await waitForUiServer();
|
|
@@ -180,7 +184,8 @@ async function stopUiServer() {
|
|
|
180
184
|
if (process.platform === "win32") {
|
|
181
185
|
await new Promise((resolve) => {
|
|
182
186
|
const killer = spawn("cmd", ["/c", "taskkill", "/PID", String(status.pid), "/T", "/F"], {
|
|
183
|
-
stdio: "ignore"
|
|
187
|
+
stdio: "ignore",
|
|
188
|
+
...WINDOWS_HIDE
|
|
184
189
|
});
|
|
185
190
|
killer.on("exit", () => resolve());
|
|
186
191
|
killer.on("error", () => resolve());
|
|
@@ -212,7 +217,7 @@ function writeUiServerStatus(status) {
|
|
|
212
217
|
}
|
|
213
218
|
function openBrowser(url) {
|
|
214
219
|
if (process.platform === "win32") {
|
|
215
|
-
const child2 = spawn("cmd", ["/c", "start", "", url], { detached: true, stdio: "ignore" });
|
|
220
|
+
const child2 = spawn("cmd", ["/c", "start", "", url], { detached: true, stdio: "ignore", ...WINDOWS_HIDE });
|
|
216
221
|
child2.unref();
|
|
217
222
|
return;
|
|
218
223
|
}
|