@jsayubi/ccgram 1.2.0 → 1.2.1
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 +65 -45
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -18,20 +18,23 @@ CCGram is a self-hosted Telegram bot that bridges Claude Code to your phone. Whe
|
|
|
18
18
|
```
|
|
19
19
|
Claude Code → ccgram hooks → Telegram bot → 📱 your phone
|
|
20
20
|
↑ ↓
|
|
21
|
-
|
|
21
|
+
└─ updatedInput / tmux / Ghostty / PTY ─┘
|
|
22
22
|
```
|
|
23
23
|
|
|
24
24
|
## Features
|
|
25
25
|
|
|
26
|
-
- **
|
|
27
|
-
- **
|
|
28
|
-
- **
|
|
26
|
+
- **Universal terminal support** — Works with tmux, Ghostty, bare zsh, screen — anything. Question answers flow back to Claude Code directly via the `updatedInput` hook output, no keystroke injection needed.
|
|
27
|
+
- **Permission approvals** — Allow, Deny, Always, or Defer with a single tap
|
|
28
|
+
- **Question answering** — Single-select, multi-select, and free-text questions answered via Telegram buttons
|
|
29
|
+
- **Rich `/status`** — Model, version, git branch, session ID, context window % (auto-detects 1M mode), rate limit + reset time, last activity, last assistant message — all from Claude Code's transcript
|
|
30
|
+
- **MCP elicitation forwarding** — Schema-aware MCP server input requests routed to Telegram, one prompt per form field
|
|
31
|
+
- **Smart notifications** — Task completions, errors, compaction, session lifecycle, subagent activity — silent at your terminal, instant when you're away
|
|
29
32
|
- **Remote command routing** — Send any command to any Claude session from Telegram
|
|
30
|
-
- **Session management** — List, switch
|
|
31
|
-
- **Resume conversations** — `/resume` reads your full Claude Code session history with conversation snippets — pick up any past conversation in one tap
|
|
33
|
+
- **Session management** — List, switch, interrupt; resume past conversations with `/resume`
|
|
32
34
|
- **Project launcher** — Start Claude in any project directory with `/new myproject`
|
|
35
|
+
- **Deep links** — `/link <prompt>` generates `claude-cli://open?q=...` URLs
|
|
33
36
|
- **Smart routing** — Prefix matching, default workspace, reply-to routing
|
|
34
|
-
- **
|
|
37
|
+
- **Ghostty support** — Auto-detected on macOS via `TERM_PROGRAM=ghostty`; full keystroke injection via AppleScript
|
|
35
38
|
- **tmux optional** — Falls back to a headless PTY session (`node-pty`) when tmux is unavailable
|
|
36
39
|
- **One-command setup** — Interactive wizard installs hooks, generates service file, starts bot
|
|
37
40
|
|
|
@@ -40,7 +43,10 @@ Claude Code → ccgram hooks → Telegram bot → 📱 your phone
|
|
|
40
43
|
- [Node.js](https://nodejs.org) 18+
|
|
41
44
|
- A Telegram bot token (from [@BotFather](https://t.me/BotFather))
|
|
42
45
|
- Your Telegram chat ID (from [@userinfobot](https://t.me/userinfobot))
|
|
43
|
-
-
|
|
46
|
+
- A terminal — any of:
|
|
47
|
+
- [tmux](https://github.com/tmux/tmux/wiki) (recommended; cross-platform)
|
|
48
|
+
- [Ghostty](https://ghostty.org) (auto-detected on macOS via `TERM_PROGRAM`)
|
|
49
|
+
- bare zsh / screen / anything else (PTY fallback via `node-pty`)
|
|
44
50
|
|
|
45
51
|
## Quick Start
|
|
46
52
|
|
|
@@ -58,7 +64,7 @@ Then open Telegram and message your bot — Claude Code will now notify you remo
|
|
|
58
64
|
|
|
59
65
|
## How It Works
|
|
60
66
|
|
|
61
|
-
CCGram integrates with [Claude Code hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) — shell scripts that Claude Code calls at key moments.
|
|
67
|
+
CCGram integrates with [Claude Code hooks](https://docs.anthropic.com/en/docs/claude-code/hooks) — shell scripts that Claude Code calls at key moments. Hooks send Telegram messages and, depending on the event, return your response to Claude Code directly via stdout (`updatedInput` for questions, `decision` for permissions) or inject keystrokes into the active session (tmux, Ghostty, or PTY).
|
|
62
68
|
|
|
63
69
|
### Hooks installed
|
|
64
70
|
|
|
@@ -122,7 +128,7 @@ Claude asks a question (AskUserQuestion)
|
|
|
122
128
|
| Command | Description |
|
|
123
129
|
|---------|-------------|
|
|
124
130
|
| `/<workspace> <command>` | Send a command to a specific Claude session |
|
|
125
|
-
| `/status [workspace]` |
|
|
131
|
+
| `/status [workspace]` | Rich status: model, version, branch, session ID, context %, rate limit, last activity, last message (and recent pane output for tmux/PTY) |
|
|
126
132
|
| `/stop [workspace]` | Send Ctrl+C to interrupt the running prompt |
|
|
127
133
|
| `/compact [workspace]` | Run `/compact` and wait for it to complete |
|
|
128
134
|
| `/effort [workspace] low\|medium\|high` | Set Claude's thinking effort level |
|
|
@@ -263,7 +269,7 @@ node dist/workspace-telegram-bot.js
|
|
|
263
269
|
```bash
|
|
264
270
|
npm run build # Compile TypeScript → dist/
|
|
265
271
|
npm run build:watch # Watch mode
|
|
266
|
-
npm test # Run
|
|
272
|
+
npm test # Run 120 tests (vitest)
|
|
267
273
|
```
|
|
268
274
|
|
|
269
275
|
**Note:** Claude Code hooks run from `~/.ccgram/dist/`, not the repo's `dist/`. After changing hook scripts during development, sync them:
|
|
@@ -279,34 +285,42 @@ End users don't need this — `ccgram init` handles it automatically.
|
|
|
279
285
|
```
|
|
280
286
|
src/
|
|
281
287
|
├── utils/
|
|
282
|
-
│ ├── active-check.ts
|
|
283
|
-
│ ├── pty-session-manager.ts
|
|
284
|
-
│ ├──
|
|
285
|
-
│ ├──
|
|
286
|
-
│ ├──
|
|
287
|
-
│
|
|
288
|
-
├──
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
288
|
+
│ ├── active-check.ts # Detect terminal activity; suppress notifications when present
|
|
289
|
+
│ ├── pty-session-manager.ts # Headless PTY backend via node-pty (tmux fallback)
|
|
290
|
+
│ ├── ghostty-session-manager.ts # Ghostty AppleScript backend (macOS, auto-detected)
|
|
291
|
+
│ ├── transcript-reader.ts # Read Claude Code session JSONL for /status (model, context %, last message)
|
|
292
|
+
│ ├── deep-link.ts # Generate claude-cli://open?q=... URLs for /link
|
|
293
|
+
│ ├── callback-parser.ts # Parse Telegram callback_data strings
|
|
294
|
+
│ ├── http-request.ts # Lightweight HTTPS wrapper (no axios)
|
|
295
|
+
│ ├── optional-require.ts # Graceful optional dependency loading
|
|
296
|
+
│ └── paths.ts # PROJECT_ROOT + CCGRAM_HOME constants
|
|
297
|
+
├── types/ # TypeScript interfaces
|
|
298
|
+
└── data/ # Runtime data (session map, history)
|
|
299
|
+
|
|
300
|
+
workspace-telegram-bot.ts # Main bot (long-polling, routing, callbacks, /status, /link, /effort, /model)
|
|
301
|
+
workspace-router.ts # Session map, prefix matching, default workspace, rate limit storage
|
|
302
|
+
prompt-bridge.ts # File-based IPC via /tmp/claude-prompts/
|
|
303
|
+
permission-hook.ts # Blocking permission approval hook
|
|
304
|
+
permission-denied-notify.ts # PermissionDenied hook with retry button
|
|
305
|
+
question-notify.ts # Blocking AskUserQuestion hook (returns updatedInput to Claude Code)
|
|
306
|
+
enhanced-hook-notify.ts # Status notifications (Stop, Notification, SessionStart/End, SubagentStop, StopFailure, PostCompact, TaskCreated, CwdChanged, InstructionsLoaded)
|
|
307
|
+
pre-compact-notify.ts # PreCompact hook with block button
|
|
308
|
+
elicitation-notify.ts # MCP elicitation hook (schema-aware, per-field)
|
|
309
|
+
user-prompt-hook.ts # UserPromptSubmit hook — writes terminal activity timestamp
|
|
310
|
+
setup.ts # Interactive setup wizard
|
|
311
|
+
cli.ts # ccgram CLI entry point
|
|
300
312
|
```
|
|
301
313
|
|
|
302
314
|
### Tests
|
|
303
315
|
|
|
304
316
|
```
|
|
305
317
|
test/
|
|
306
|
-
├── prompt-bridge.test.js
|
|
307
|
-
├── workspace-router.test.js
|
|
308
|
-
├── callback-parser.test.js
|
|
309
|
-
|
|
318
|
+
├── prompt-bridge.test.js # 15 tests — IPC write/read/update/clean/expiry
|
|
319
|
+
├── workspace-router.test.js # 43 tests — session map, prefix matching, defaults, reply-to, history, rate limits
|
|
320
|
+
├── callback-parser.test.js # 27 tests — all callback_data formats (perm, opt, new, rp, rs, rc, perm-denied, pre-compact)
|
|
321
|
+
├── active-check.test.js # 8 tests — terminal activity detection, thresholds
|
|
322
|
+
├── deep-link.test.js # 11 tests — claude-cli:// URL generation, encoding, character limits
|
|
323
|
+
└── ghostty-session-manager.test.js # 16 tests — Ghostty AppleScript session management (mocked)
|
|
310
324
|
```
|
|
311
325
|
|
|
312
326
|
Tests use isolated temp directories and run with `npm test` (vitest, no configuration needed).
|
|
@@ -336,18 +350,24 @@ Yes. Each Claude session maps to a named tmux or PTY session. Use `/sessions` to
|
|
|
336
350
|
Yes. `/resume` reads from Claude Code's own session storage, so it sees every conversation — not just ones started through the bot. If the session is still running in your terminal, you'll get a warning before resuming to prevent conflicts.
|
|
337
351
|
|
|
338
352
|
**Do I need tmux?**
|
|
339
|
-
No.
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
353
|
+
No. CCGram supports three injection backends and picks the right one automatically:
|
|
354
|
+
- **tmux** (default when running) — cross-platform, recommended
|
|
355
|
+
- **Ghostty** — auto-detected on macOS via `TERM_PROGRAM=ghostty`; uses AppleScript for keystroke injection and tab focus
|
|
356
|
+
- **PTY** (`node-pty`) — headless fallback when neither tmux nor Ghostty is available
|
|
357
|
+
|
|
358
|
+
For question answering specifically (the `AskUserQuestion` hook), CCGram returns answers to Claude Code directly via the `updatedInput` hook output — so it works on **any** terminal, including bare zsh, screen, or anything else, without keystroke injection at all.
|
|
359
|
+
|
|
360
|
+
To force a specific backend:
|
|
361
|
+
```bash
|
|
362
|
+
# in ~/.ccgram/.env
|
|
363
|
+
INJECTION_MODE=pty # or tmux
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
Then restart the bot: `launchctl kickstart -k gui/$(id -u)/com.ccgram` (macOS) or `sudo systemctl restart ccgram` (Linux).
|
|
367
|
+
|
|
368
|
+
To use PTY mode, install the optional dependency: `npm install node-pty` inside `~/.ccgram/`.
|
|
369
|
+
|
|
370
|
+
Full remote control — permission approvals, question answering, `/new`, `/stop` — works identically in all modes.
|
|
351
371
|
|
|
352
372
|
**Is my bot token stored securely?**
|
|
353
373
|
The token is stored in `~/.ccgram/.env`, readable only by your user. It's never logged or transmitted beyond Telegram's API.
|