If that path doesn't exist, fall back to Glob with pattern
/skills//claude-to-im/SKILL.md
and derive the root from the result.
Command parsing
Parse the user's intent from
$ARGUMENTS
into one of these subcommands:
User says (examples)
Subcommand
setup
,
configure
,
配置
,
我想在飞书上用 Claude
,
帮我连接 Telegram
setup
start
,
start bridge
,
启动
,
启动桥接
start
stop
,
stop bridge
,
停止
,
停止桥接
stop
status
,
bridge status
,
状态
,
运行状态
,
怎么看桥接的运行状态
status
logs
,
logs 200
,
查看日志
,
查看日志 200
logs
reconfigure
,
修改配置
,
帮我改一下 token
,
换个 bot
reconfigure
doctor
,
diagnose
,
诊断
,
挂了
,
没反应了
,
bot 没反应
,
出问题了
doctor
Disambiguation:
status
vs
doctor
— Use
status
when the user just wants to check if the bridge is running (informational). Use
doctor
when the user reports a problem or suspects something is broken (diagnostic). When in doubt and the user describes a symptom (e.g., "没反应了", "挂了"), prefer
doctor
.
Extract optional numeric argument for
logs
(default 50).
Before asking users for any platform credentials, first read
SKILL_DIR/references/setup-guides.md
to get the detailed step-by-step guidance for that platform. Present the relevant guide text to the user via AskUserQuestion — users often don't know where to find bot tokens or app secrets, so showing the guide upfront saves back-and-forth.
Runtime detection
Before executing any subcommand, detect which environment you are running in:
Claude Code
—
AskUserQuestion
tool is available. Use it for interactive setup wizards.
Codex / other
—
AskUserQuestion
is NOT available. Fall back to non-interactive guidance: explain the steps, show
SKILL_DIR/config.env.example
, and ask the user to create
~/.claude-to-im/config.env
manually.
You can test this by checking if AskUserQuestion is in your available tools list.
Config check (applies to
start
,
stop
,
status
,
logs
,
reconfigure
,
doctor
)
Before running any subcommand other than
setup
, check if
~/.claude-to-im/config.env
exists:
If it does NOT exist:
In Claude Code: tell the user "No configuration found" and automatically start the
setup
wizard using AskUserQuestion.
In Codex: tell the user "No configuration found. Please create
~/.claude-to-im/config.env
based on the example:" then show the contents of
SKILL_DIR/config.env.example
and stop. Don't attempt to start the daemon — without config.env the process will crash on startup and leave behind a stale PID file that blocks future starts.
If it exists:
proceed with the requested subcommand.
Subcommands
setup
Run an interactive setup wizard. This subcommand requires
AskUserQuestion
. If it is not available (Codex environment), instead show the contents of
SKILL_DIR/config.env.example
with field-by-field explanations and instruct the user to create the config file manually.
When AskUserQuestion IS available, collect input
one field at a time
. After each answer, confirm the value back to the user (masking secrets to last 4 chars only) before moving to the next question.
Step 1 — Choose channels
Ask which channels to enable (telegram, discord, feishu, qq). Accept comma-separated input. Briefly describe each:
telegram
— Best for personal use. Streaming preview, inline permission buttons.
discord
— Good for team use. Server/channel/user-level access control.
feishu
(Lark) — For Feishu/Lark teams. Event-based messaging.
qq
— QQ C2C private chat only. No inline permission buttons, no streaming preview. Permissions use text
/perm ...
commands.
Step 2 — Collect tokens per channel
For each enabled channel, read
SKILL_DIR/references/setup-guides.md
and present the relevant platform guide to the user. Collect one credential at a time:
Telegram
Bot Token → confirm (masked) → Chat ID (see guide for how to get it) → confirm → Allowed User IDs (optional).
Important:
At least one of Chat ID or Allowed User IDs must be set, otherwise the bot will reject all messages.
At least one of Allowed User IDs or Allowed Channel IDs must be set, otherwise the bot will reject all messages (default-deny).
Feishu
App ID → confirm → App Secret → confirm (masked) → Domain (optional) → Allowed User IDs (optional). Guide through all 4 steps (A: batch permissions, B: enable bot, C: events & callbacks with long connection, D: publish version).
QQ
Collect two required fields, then optional ones:
QQ App ID (required) → confirm
QQ App Secret (required) → confirm (masked)
Tell the user: these two values can be found at
https://q.qq.com/qqbot/openclaw
Allowed User OpenIDs (optional, press Enter to skip) — note: this is
user_openid
, NOT QQ number. If the user doesn't have openid yet, they can leave it empty.
Image Enabled (optional, default true, press Enter to skip) — if the underlying provider doesn't support image input, set to false
Max Image Size MB (optional, default 20, press Enter to skip)
Remind user: QQ first version only supports C2C private chat sandbox access. No group/channel support, no inline buttons, no streaming preview.
Step 3 — General settings
Ask for runtime, default working directory, model, and mode:
Runtime
:
claude
(default),
codex
,
auto
claude
— uses Claude Code CLI + Claude Agent SDK (requires
claude
CLI installed)
codex
— uses OpenAI Codex SDK (requires
codex
CLI; auth via
codex auth login
or
OPENAI_API_KEY
)
auto
— tries Claude first, falls back to Codex if Claude CLI not found
Working Directory
default
$CWD
Model
(optional): Leave blank to inherit the runtime's own default model. If the user wants to override, ask them to enter a model name. Do NOT hardcode or suggest specific model names — the available models change over time.
Mode
:
code
(default),
plan
,
ask
Step 4 — Write config and validate
Show a final summary table with all settings (secrets masked to last 4 chars)
Ask user to confirm before writing
Use Bash to create directory structure:
mkdir -p ~/.claude-to-im/{data,logs,runtime,data/messages}
Use Write to create
~/.claude-to-im/config.env
with all settings in KEY=VALUE format
Use Bash to set permissions:
chmod 600 ~/.claude-to-im/config.env
Validate tokens — read
SKILL_DIR/references/token-validation.md
for the exact commands and expected responses for each platform. This catches typos and wrong credentials before the user tries to start the daemon.
Report results with a summary table. If any validation fails, explain what might be wrong and how to fix it.
On success, tell the user: "Setup complete! Run
/claude-to-im start
to start the bridge."
start
Pre-check:
Verify
~/.claude-to-im/config.env
exists (see "Config check" above). Without it, the daemon will crash immediately and leave a stale PID file.
Run:
bash "SKILL_DIR/scripts/daemon.sh" start
Show the output to the user. If it fails, tell the user:
Run
doctor
to diagnose:
/claude-to-im doctor
Check recent logs:
/claude-to-im logs
stop
Run:
bash "SKILL_DIR/scripts/daemon.sh" stop
status
Run:
bash "SKILL_DIR/scripts/daemon.sh" status
logs
Extract optional line count N from arguments (default 50).
Run:
bash "SKILL_DIR/scripts/daemon.sh" logs N
reconfigure
Read current config from
~/.claude-to-im/config.env
Show current settings in a clear table format, with all secrets masked (only last 4 chars visible)
Use AskUserQuestion to ask what the user wants to change
When collecting new values, read
SKILL_DIR/references/setup-guides.md
and present the relevant guide for that field
Update the config file atomically (write to tmp, rename)
Re-validate any changed tokens
Remind user: "Run
/claude-to-im stop
then
/claude-to-im start
to apply the changes."
doctor
Run:
bash "SKILL_DIR/scripts/doctor.sh"
Show results and suggest fixes for any failures. Common fixes:
SDK cli.js missing →
cd SKILL_DIR && npm install
dist/daemon.mjs stale →
cd SKILL_DIR && npm run build
Config missing → run
setup
For more complex issues (messages not received, permission timeouts, high memory, stale PID files), read
SKILL_DIR/references/troubleshooting.md
for detailed diagnosis steps.
Notes
Always mask secrets in output (show only last 4 characters) — users often share terminal output in bug reports, so exposed tokens would be a security incident.
Always check for config.env before starting the daemon — without it the process crashes on startup and leaves a stale PID file that blocks future starts (requiring manual cleanup).
The daemon runs as a background Node.js process managed by platform supervisor (launchd on macOS, setsid on Linux, WinSW/NSSM on Windows).
Config persists at
~/.claude-to-im/config.env
— survives across sessions.