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 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 Windows user
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 Windows App
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 command:
129
-
130
- - `/history` shows the latest N messages of the current session
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` 运行时:需要在同一 Windows 用户下完成 Codex 认证
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 Windows App
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
- - `/history` 查看当前会话最近 N 条消息
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`。
@@ -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 model (optional inherits from runtime's own default if not set)
17
- # CTI_DEFAULT_MODEL=
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
  }