@cerulin/chell
v0.5.5
Published
Mobile client for Claude Code, Codex, Gemini, and LM Studio
Readme
Chell CLI
Control Claude Code from your mobile device or integrate with Chell Desktop.
Free. Open source. Code anywhere.
Installation
# From npm registry
npm install -g @cerulin/chell
# Or install from local checkout
npm install -g .
# Or link for active development
npm linkUsage
chell claudeThis will:
- Start a Claude Code session
- Authenticate via Auth0 (opens browser for login)
- Allow real-time session sharing between Claude Code and your mobile app
Options
-h, --help- Show help-v, --version- Show version-m, --model <model>- Claude model to use (default: sonnet)-p, --permission-mode <mode>- Permission mode: auto, default, or plan--claude-env KEY=VALUE- Set environment variable for Claude Code--claude-arg ARG- Pass additional argument to Claude CLI
Terminal Status Detection
Chell CLI detects Claude Code's state by monitoring PTY output for specific visual indicators. These indicators are not part of any official API and may break if Anthropic changes Claude Code's UI.
Visual Indicators We Rely On
⚠️ FRAGILE: These patterns are reverse-engineered from Claude Code's terminal output. If status detection breaks after a Claude Code update, check these patterns first.
1. Spinner Characters (Thinking State)
Claude Code displays an animated spinner while processing. We detect these Unicode characters:
✱ ✲ ✳ ✴ ✵ ✶ ✷ ✸ ✹ (U+2731 - U+2739)
✻ ✼ ✽ ✾ ✿ (U+273B - U+273F)
❀ ❁ ❂ ❃ ❄ ❅ ❆ ❇ ❈ ❉ ❊ ❋ (U+2740 - U+274B)Detection logic: src/claude/claudeLocal.ts → checkForSpinner()
- Spinner present →
thinkingstate - No spinner for 1 second →
idlestate
2. "Interrupted" Text (Escape Key Detection)
When user presses Escape to cancel a permission prompt, Claude Code shows:
Interrupted · What should Claude do instead?Detection logic: src/claude/claudeLocal.ts → checks for "Interrupted" substring
- Clears permission state and transitions to idle
3. Permission Hook (Permission State)
Claude Code's hook system calls chell notify --hook when permission is requested.
Detection logic: src/claude/utils/startChellServer.ts → /permission-hook endpoint
- Hook triggered →
permissionstate - Hook resolved →
idlestate
State Machine
┌─────────────┐
│ idle │◄────────────────┐
└──────┬──────┘ │
│ spinner detected │ no spinner for 1s
▼ │
┌─────────────┐ │
┌─────────►│ thinking │─────────────────┘
│ └──────┬──────┘
│ │ permission hook
│ ▼
│ ┌─────────────┐
│ │ permission │
│ └──────┬──────┘
│ │ "Interrupted" or hook resolved or spinner
└─────────────────┘OSC Sequences Emitted
Chell emits OSC 777 sequences for Chell Desktop to parse:
ESC ] 777 ; chell ; status ; <thinking|idle|permission> BEL
ESC ] 777 ; chell ; unread ; <true|false> BEL
ESC ] 777 ; chell ; permission-type ; <bash|file-write|file-read|mcp|unknown> BELUpdating Detection Patterns
If Claude Code's UI changes, update these files:
| Pattern | File | Function/Location |
|---------|------|-------------------|
| Spinner characters | src/claude/claudeLocal.ts | spinnerChars regex |
| "Interrupted" text | src/claude/claudeLocal.ts | checkForSpinner() |
| Permission hook | src/claude/utils/injectHook.ts | Hook injection logic |
Requirements
- Node.js >= 20.0.0
- Claude CLI installed & logged in (
claudecommand available in PATH)
Developing locally
npm run dev # runs with tsx
# or
npm run build && node bin/chell.mjsLicense
MIT
