Skip to content

feat: add /api and /resume commands for remote management#227

Open
changqingyu wants to merge 2 commits into
xvirobotics:mainfrom
changqingyu:feat/api-and-resume
Open

feat: add /api and /resume commands for remote management#227
changqingyu wants to merge 2 commits into
xvirobotics:mainfrom
changqingyu:feat/api-and-resume

Conversation

@changqingyu

@changqingyu changqingyu commented Apr 29, 2026

Copy link
Copy Markdown

Summary

  • /api command: remotely switch Claude API endpoints from Feishu when quota is exhausted. Supports multiple saved configurations with connectivity validation and persistence (~/.claude/metabot-apis.json).
  • /resume command: enumerate and resume local Claude Code CLI sessions from Feishu, continuing unfinished tasks with full conversation context via the Agent SDK's listSessions() API.

Changes

  • New src/engines/claude/api-config-manager.ts — CRUD, validation, persistence for API configs
  • Modified src/engines/claude/executor.ts — inject API config env vars into subprocess + listHistorySessions() static method
  • Modified src/engines/claude/session-manager.tssetSession() for restoring CLI sessions
  • Modified src/bridge/command-handler.ts/api and /resume command handlers
  • Modified src/engines/claude/index.ts + src/engines/index.ts — re-exports
  • Modified src/utils/audit-logger.tssession_resumed event type

Test plan

  • /api set test https://api.example.com sk-xxx — validates and saves
  • /api list — shows saved configs with index
  • /api switch 1 — switches by index
  • /api current — displays active config
  • /api delete test — removes config
  • /resume — lists local CLI sessions
  • /resume 1 — resumes first session
  • npm run build passes (excluding pre-existing kimi SDK issue)
  • npm test — 207 tests pass

🤖 Generated with Claude Code

Qingyu Chang and others added 2 commits April 29, 2026 19:42
When Claude API quota is exhausted, users can now switch endpoints
directly from Feishu without SSH access. Supports multiple saved
configurations with connectivity validation and persistence.

- `/api set <name> <url> <token>` adds/updates with auto-validation
- `/api switch <name|index>` switches active config by name or index
- `/api list` / `/api current` / `/api delete <name>` for management
- New ApiConfigManager class persists to ~/.claude/metabot-apis.json
- Auto-syncs active config to ~/.claude/settings.json env block
- Injects ANTHROPIC_BASE_URL / ANTHROPIC_AUTH_TOKEN into Claude
  subprocess via createSpawnFn extraEnv parameter
- Singleton pattern shared between executor and command handler
- Retry logic (3 attempts) for first-time connection warmup

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
…ssions from Feishu

Users can now enumerate and resume local CLI sessions directly from
Feishu, continuing unfinished tasks with full conversation context.
Leverages the Agent SDK's listSessions() and query({ resume }) APIs.

- `/resume` lists recent sessions (title, branch, age, file size)
- `/resume <n>` resumes by index from the displayed list
- `/resume <id>` resumes by session ID prefix (8+ chars)
- ClaudeExecutor.listHistorySessions() wraps SDK listSessions()
- SessionManager.setSession() writes sessionId + workingDirectory
- CommandHandler caches session list per chat (5 min TTL)
- Validates original working directory, falls back to default
- Adds `session_resumed` audit event type

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
@floodsung

Copy link
Copy Markdown
Contributor

Thanks for the substantial PR. A few observations from a triage pass — leaving as comments rather than approving since this adds two new top-level command surfaces and persists API credentials to disk:

  1. Credential storage~/.claude/metabot-apis.json will store API keys in plaintext. Consider documenting the file permissions (or chmod 600 it on write) so users understand the trust boundary, especially for shared servers.

  2. /api access control — Since this remotely switches the API endpoint for an entire bot, any user who can DM the bot can swap to an arbitrary endpoint+key. Worth confirming whether this should be gated to admin users only (cf. how other commands handle authorization).

  3. /resume overlap with [Feature] 在飞书/Telegram 对话中支持 "/history" 与 "/resume",实现跨终端工作流无缝接力 #188 — Issue [Feature] 在飞书/Telegram 对话中支持 "/history" 与 "/resume",实现跨终端工作流无缝接力 #188 proposes /history + /resume with similar semantics. The /resume here covers the resume case via Agent SDK listSessions(). Aligning command names / output format with [Feature] 在飞书/Telegram 对话中支持 "/history" 与 "/resume",实现跨终端工作流无缝接力 #188's spec might reduce churn if both ship.

  4. Test plan — All checkboxes are checked but the build note mentions "excluding pre-existing kimi SDK issue". Worth surfacing what that is so reviewers know it's unrelated.

Leaving final review to maintainers.

@floodsung

Copy link
Copy Markdown
Contributor

Thanks for the contribution — both /api and /resume solve real pain points. Before merging, two issues need to be addressed:

1. Security: stop syncing tokens to ~/.claude/settings.json

api-config-manager.ts correctly creates ~/.claude/metabot-apis.json with mode: 0o600, but then writes the same ANTHROPIC_API_KEY into ~/.claude/settings.json, which doesn't have the same permission guarantee — and is shared with the Claude CLI itself for any user logged in on the box. That sync defeats the purpose of the 0o600 restriction.

The cleaner pattern is what executor.ts already does: keep the active API config in memory, and inject env vars only at subprocess spawn time via the extraEnv argument. No need to persist anything beyond metabot-apis.json itself. Please drop the settings.json write.

2. Scope overlap with #174 and issue #239

/resume lists local Claude CLI sessions (via the SDK's query.listSessions()), which is a different concern from #174's /sessions + /switch (which manages MetaBot's per-chatId multi-session groups). Both are useful, but the naming + UX needs to be aligned across the three threads (#174, #227, #239) before either lands, otherwise users will get a confusing mix of overlapping commands.

I've opened a design discussion on #239 to settle the unified command surface (working name proposal: /sessions, /session <prefix>, /resume — one for MetaBot multi-chat, one for switch by id, one for local CLI bridging). Could you weigh in there with what you'd like /resume to look like in the final design?

3. Minor: no CI runs

The PR has been open since 4/29 with no CI checks reported — likely needs a rebase to trigger workflows. Worth doing alongside the security fix above.

Once the settings.json write is removed and #239's design lands, /api is in good shape to merge as a focused PR; /resume should align with whatever the unified command surface ends up being.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants