npm install
npm run build
mkdir -p ~/.local/bin
ln -sf "$PWD/dist/mobile-code.js" ~/.local/bin/mobile-code
mobile-code --helpdist/ is generated and ignored by git. Re-run npm run build after editing src/.
Create ~/.mobile-code/config:
TELEGRAM_BOT_TOKEN="123456:ABC..."
TELEGRAM_CHAT_ID="<your numeric Telegram user id>"
TELEGRAM_PROXY="http://127.0.0.1:7890" # optional, needed when Mac cannot reach api.telegram.org directly
WORKER_TIMEOUT="20m"
# Feishu result push (optional). Configure either Telegram, Feishu, or both.
# Use the same self-built Feishu app as the Hermes Feishu gateway.
FEISHU_APP_ID="cli_xxxxxxxx"
FEISHU_APP_SECRET="xxxxxxxx"
FEISHU_CHAT_ID="oc_xxxxxxxx" # target group chat_id
# Optional: restrict which channels receive results. Default = every configured channel.
NOTIFY_CHANNELS="telegram,feishu"At least one channel (Telegram or Feishu) must be configured, otherwise a run fails immediately with a clear error (rather than silently). Each channel is tried independently; one failing only writes to the job log and never blocks the other or the job.
Then lock it down:
chmod 600 ~/.mobile-code/configThe CLI parses this file directly as dotenv-style text; it does not shell-source it.
- Create a Telegram bot with
@BotFather. - Get your numeric user id from
@userinfobot. - Configure Hermes Gateway with the same bot token.
- Set
TELEGRAM_ALLOWED_USERS=<your numeric user id>. - Install/start Hermes with launchd after
~/.local/bin,node, andclaudeare on PATH. - If PATH changes, re-run
hermes gateway installso launchd snapshots the new PATH.
Feishu uses one self-built app for both directions:
- inbound: Hermes Feishu gateway listens to group messages and invokes
mobile-code - outbound:
mobile-codesends job results with the same app's OpenAPI credentials
Create a Feishu self-built app in the Feishu Open Platform:
- Create an enterprise self-built app and copy its App ID / App Secret.
- Enable the bot capability.
- Grant permissions:
im:message:send_as_botim:messageim:chatorim:chat:readonly
- Configure events with websocket/long-connection mode, then subscribe to
im.message.receive_v1. - Publish the app and make its availability scope include the target group members.
- Add the app bot to the target group.
Configure Hermes Gateway for Feishu with the same app credentials:
FEISHU_APP_ID="cli_xxxxxxxx"
FEISHU_APP_SECRET="xxxxxxxx"
FEISHU_CONNECTION_MODE="websocket"
FEISHU_HOME_CHANNEL="oc_xxxxxxxx"FEISHU_HOME_CHANNEL and FEISHU_CHAT_ID are the same target group chat_id.
Keep both Hermes env and ~/.mobile-code/config permission-restricted because both store
the app secret. The webhook-style FEISHU_WEBHOOK / FEISHU_SECRET config is obsolete.
mobile-code runs the coding task through a pluggable backend:
claude(default): runsclaude -pwith an explicit--allowedToolsallowlist. The "can edit, cannot commit/push" guarantee is strong —git commit/pushare simply not on the allowlist (deny-by-default).codex: runscodex execwith a tier→sandbox mapping (tier 1 →read-only, tier 2 →workspace-write).
Select per run with --backend codex, or set a default in ~/.mobile-code/config:
DEFAULT_BACKEND="claude" # or "codex"
⚠️ codex no-commit is a weak guarantee. Underworkspace-write, codex can create its owngit commitinside the task (it is sandbox-enforced, not allowlist-enforced). mobile-code compensates at commit time:mobile-code 提交detects a codex self-commit on themobile/<job>branch andgit reset --softs back to the job'sstartHead, folding any in-task commits into the single user-confirmed commit. The claude backend needs no such compensation because its allowlist blocks commits outright.
mobile-code ships a Hermes skill so Hermes drives it via a structured intent contract
instead of ad-hoc NL parsing. The source of truth is committed in this repo at
skills/software-development/mobile-code/SKILL.md. Install it by copying into the
user-local Hermes skills tree:
mkdir -p ~/.hermes/skills/software-development/mobile-code
cp skills/software-development/mobile-code/SKILL.md \
~/.hermes/skills/software-development/mobile-code/SKILL.mdNotes:
- The skill loader initializes at session start, so the skill is only visible in a new Hermes session after install.
- The SKILL.md is the source; re-copy after editing it in the repo to keep the installed copy in sync.
The MVP uses one project alias:
test -> ~/Documents/project/mobile-code-test
The fixture is a separate git repository with a small sum(a,b) bug and node --test.
执行 mobile-code ping
执行 mobile-code detach-probe
执行 mobile-code 看 test 找出入口文件并总结
执行 mobile-code 改 test 修复 sum 的 bug,跑 npm test
执行 mobile-code 提交 test fix: 修复 sum 计算错误
执行 mobile-code 推送 test
执行 mobile-code 日志
看/查/读/分析/总结 map to tier 1 (read-only). 改/修/做/实现/新增 map to tier 2 (can edit, cannot commit or push). The old explicit form still works: mobile-code -t 1 test "..." and mobile-code -t 2 test "...".