345 Commits

Author SHA1 Message Date
Kenneth Lien
7074ac045b
Merge pull request #737 from anthropics/add-imessage-channel
Add imessage channel plugin
2026-03-23 23:13:45 -07:00
Kenneth Lien
d49d339d1e
Show input_preview only for Bash in permission prompts
Write/Edit previews are unbearably long over iMessage. Bash is the
dangerous one where seeing the command matters; everything else gets
tool_name + description only.
2026-03-23 23:05:00 -07:00
Noah Zweben
4b1e2a28ce
feat(telegram,discord): compact permission messages with expandable details (#952)
* feat(telegram,discord): compact permission messages with expandable details

Replace verbose permission request messages with a compact format showing
only the tool name. Adds a "See more" button that expands inline to show
tool_name, description, and pretty-printed input_preview JSON. Yes/No
buttons replace Allow/Deny. Bump plugin versions to 0.0.4.

* revert: restore Allow/Deny button labels
2026-03-23 22:53:47 -07:00
Daisy S. Hollman
b3a0714d7f
feat(telegram,discord): inline buttons for permission approval (#945)
Replace "Reply 'yes abcde' to allow" text instruction with native
inline buttons (Telegram InlineKeyboard, Discord ButtonBuilder).
One tap to approve/deny instead of typing a 5-char ID.

- Telegram: callback_query handler with allowFrom gate, edits message
  to show outcome and remove buttons after decision
- Discord: interactionCreate handler with allowFrom gate, updates
  interaction with outcome and clears components
- Text-reply path (PERMISSION_REPLY_RE) kept as fallback
- Bump both plugins to v0.0.3

🏠 Remote-Dev: homespace
2026-03-23 22:19:51 -07:00
Kenneth Lien
9693fd75c3
Document IMESSAGE_STATE_DIR in README 2026-03-23 20:12:20 -07:00
Kenneth Lien
bfed4635f5
feat(imessage): port permission-relay + lifecycle fixes from telegram
Brings the imessage channel to parity with recent telegram/discord
hardening:

- Permission-relay capability: declare claude/channel/permission,
  handle inbound permission_request notifications by fanning out to
  allowlisted DM chats + self-chat, intercept "yes/no <id>" replies
  after the gate check and emit structured permission events instead
  of relaying as chat. Groups excluded per single-user-mode policy.
- Global unhandledRejection/uncaughtException handlers so the server
  logs instead of dying silently.
- IMESSAGE_STATE_DIR env override for the state directory.
- .unref() on both setInterval timers so they don't block shutdown.
- stdin EOF / SIGTERM / SIGINT shutdown handler that closes chat.db
  and exits cleanly instead of leaving a zombie poll loop.

Adds zod as a direct dep (already transitively present via the MCP SDK)
for the notification handler schema.
2026-03-23 20:10:34 -07:00
Kenneth Lien
0f8c170fa7
Merge remote-tracking branch 'origin/main' into add-imessage-channel 2026-03-23 20:07:40 -07:00
Daisy S. Hollman
15268f03d2
Merge pull request #833 from anthropics/daisy/plugin-7/channel-permissions
feat(telegram,discord): permission-relay — approve Claude Code tool use from your phone
2026-03-23 13:15:41 -07:00
Daisy Hollman
daa84c99c8
feat(telegram,discord): permission-relay capability + bidirectional handlers
Complete the plugin side of anthropics/claude-cli-internal#23061 (permission
prompts over channels).

Capability: both servers now declare
  experimental["claude/channel/permission"]
which tells CC they can relay permission requests. This capability asserts the
server authenticates the replier — gate()/access.allowFrom filters
non-allowlisted senders before handleInbound runs.

Outbound (CC → user): setNotificationHandler for
  notifications/claude/channel/permission_request
formats the tool name, description, and input preview into a human-readable
message and sends it to every allowlisted DM. Groups are excluded — the
security thread resolution was "single-user mode for official plugins."

Inbound (user → CC): PERMISSION_REPLY_RE intercept in handleInbound catches
"yes xxxxx" / "no xxxxx" replies, emits the structured
  notifications/claude/channel/permission
event with {request_id, behavior}, reacts with checkmark/cross, and returns
without relaying the text to Claude as a chat message.

The regex is inlined from channelPermissions.ts (no cross-repo dep). IDs are
lowercased at the plugin boundary per the case-insensitive spec.

Version bumped 0.0.1 → 0.0.2 so the plugin reconciler picks up the change.

🏠 Remote-Dev: homespace
2026-03-23 08:59:02 +00:00
Sarah Deaton
92d061553f
Drop tab-complete check, keep just /reload-plugins line 2026-03-21 20:18:35 -07:00
Sarah Deaton
b4f0bdd93a
Restore /reload-plugins step in telegram/discord READMEs
Partially reverts #758. The reload step is not redundant: the configure
skill runs before the restart step, so it is not loaded yet when the user
types /telegram:configure. CLI prints 'Run /reload-plugins to activate.'
after install (pluginInstallationHelpers.ts:529). Mintlify reports
confirm users hit 'Unknown skill: discord:configure' at step 3.
2026-03-21 20:17:33 -07:00
Kenneth Lien
61c0597779
Merge pull request #825 from anthropics/kenneth/channels-rollup
Channels rollup: resilience + discord port + bucket-1 features
2026-03-20 17:40:59 -07:00
Tobin South
da61886c07
Merge pull request #823 from anthropics/claude/slack-add-claude-plugin-marketplace
fix(plugin): switch stripe plugin to git-subdir source and remove local copy
2026-03-20 23:02:17 +00:00
Kenneth Lien
6d0053f69e
Add IMESSAGE_APPEND_SIGNATURE env var (default true) 2026-03-20 14:51:47 -07:00
Kenneth Lien
252577f8de
Register imessage plugin in marketplace.json 2026-03-20 14:44:25 -07:00
Kenneth Lien
272de726d6
Merge branch 'main' into add-imessage-channel 2026-03-20 14:43:23 -07:00
Ralph Furman
d56d7b61f0
Merge pull request #755 from anthropics/ralph/add-math-olympiad
Add math-olympiad skill
2026-03-20 13:31:34 -07:00
Claude
802464cff3
Fix frontmatter validation to skip deleted files
The workflow was passing deleted files to the validation script, which
failed when trying to read them. Add --diff-filter=AMRC to only process
Added, Modified, Renamed, and Copied files.
2026-03-20 20:30:40 +00:00
Kenneth Lien
51bd7bd5f2
Merge remote-tracking branch 'origin/kenneth/telegram-all-file-types' into kenneth/channels-rollup 2026-03-20 13:13:58 -07:00
Kenneth Lien
71b102d75d
Merge remote-tracking branch 'origin/kenneth/telegram-bot-commands-795' into kenneth/channels-rollup
# Conflicts:
#	external_plugins/telegram/server.ts
2026-03-20 13:13:58 -07:00
Kenneth Lien
556b21af96
Merge remote-tracking branch 'origin/kenneth/telegram-bot-commands' into kenneth/channels-rollup 2026-03-20 13:13:08 -07:00
Kenneth Lien
87e0f09336
Merge remote-tracking branch 'origin/kenneth/discord-resilience' into kenneth/channels-rollup 2026-03-20 13:13:08 -07:00
Kenneth Lien
aa4f7c4fb0
Merge remote-tracking branch 'origin/kenneth/discord-edit-notif-guidance' into kenneth/channels-rollup 2026-03-20 13:13:08 -07:00
Kenneth Lien
24a170a704
Merge remote-tracking branch 'origin/kenneth/channels-state-dir' into kenneth/channels-rollup 2026-03-20 13:13:07 -07:00
Kenneth Lien
f3fc62a8e7
Merge remote-tracking branch 'origin/kenneth/telegram-409' into kenneth/channels-rollup
# Conflicts:
#	external_plugins/telegram/server.ts
2026-03-20 13:13:07 -07:00
Kenneth Lien
757480dd76
Merge remote-tracking branch 'origin/kenneth/telegram-shutdown' into kenneth/channels-rollup 2026-03-20 13:12:58 -07:00
Claude
af6b2c490b
Remove local stripe external plugin
Now that the stripe plugin sources from the stripe/ai git-subdir, the
locally vendored copy under external_plugins/stripe is no longer needed.
2026-03-20 20:09:40 +00:00
Claude
2bc9dfb449
Update stripe plugin to use git-subdir source
Change the stripe plugin source from local path (./external_plugins/stripe)
to git-subdir pointing to stripe/ai repo at providers/claude/plugin without
SHA pinning.
2026-03-20 19:59:36 +00:00
Kenneth Lien
1636fedbd4
Sanitize user-controlled filenames and download path components
- safeName() strips <>[]\r\n; from file_name/title before they hit the
  <channel> notification — delimiter chars would let an uploader break
  out of the tag or forge meta entries
- download_attachment strips ext/uniqueId to alphanumeric before join()
  — defense-in-depth against path traversal (file_unique_id is
  Telegram-controlled so this is belt-and-braces)
2026-03-20 11:56:57 -07:00
Kenneth Lien
ea382ec6a4
Tighten /start and /help copy
Less chatty, more precise. Explicitly mentions the /telegram:access
skill and the 6-char code format.
2026-03-20 11:55:56 -07:00
Kenneth Lien
9a101ba34c
Restrict bot commands to DMs (security)
- /status in a group would leak the sender's pending pairing code to
  other group members, who could then pair as that user
- Commands in non-allowlisted groups confirm bot presence and enable spam
- /start now acknowledges dmPolicy === 'disabled' instead of lying
- setMyCommands scoped to private chats so the / menu only shows in DMs
2026-03-20 11:54:48 -07:00
Kenneth Lien
a9bc23da6f
telegram: handle all inbound file types + download_attachment tool 2026-03-20 11:51:42 -07:00
Kenneth Lien
521f858e11
telegram: add /start /help /status bot commands 2026-03-20 11:47:39 -07:00
Kenneth Lien
a7cb39c269
telegram: add MarkdownV2 parse_mode to reply/edit_message 2026-03-20 11:45:46 -07:00
Kenneth Lien
aa71c24314
discord: port resilience fixes from telegram
Same patterns as #812/#813 for the discord channel:
- process-level unhandledRejection/uncaughtException handlers
- client.on('error') to log discord.js errors
- mcp.notification().catch() so inbound delivery failures surface
- stdin close / SIGTERM -> client.destroy() + exit (zombie fix)
- .unref() the approval-check interval
- client.login().catch() to log+exit on bad token instead of crashing

Discord is inherently more resilient than telegram (discord.js
auto-reconnects, no 409 equivalent), but these gaps were still there.
2026-03-20 11:28:51 -07:00
Kenneth Lien
5c58308be4
discord/telegram: guide assistant to send new reply on completion
Message edits don't trigger push notifications on the user's device.
Update system instructions and edit_message tool description to steer
the assistant toward edit-for-progress + new-reply-on-completion.

Fixes #786
2026-03-20 11:27:09 -07:00
Kenneth Lien
3d8042f259
Silently return when bot.stop() aborts the setup phase
If bot.stop() is called while bot.start() is still in setup (deleteWebhook/
getMe), grammy rejects with 'Aborted delay'. Expected, not an error.
2026-03-20 11:07:05 -07:00
Kenneth Lien
14927ff475
telegram/discord: make state dir configurable via env var
Hardcoded ~/.claude/channels/<name>/ meant only one bot per machine.
Respect TELEGRAM_STATE_DIR / DISCORD_STATE_DIR so users can run
multiple bots with separate tokens and allowlists.

Also fixed README path ('in your project' -> '~/...') to match the code.

Fixes #792
2026-03-20 10:56:57 -07:00
Kenneth Lien
1daff5f224
telegram: retry on 409 Conflict instead of crashing
During /mcp reload or when a zombie from a previous session still holds
the polling slot, the new process gets 409 Conflict on its first
getUpdates and dies immediately. Retry with backoff until the slot
frees — typically within a second or two.

Also handles the two-sessions case: the second Claude Code instance
keeps retrying (with a clear message about what's happening) and takes
over when the first one exits.

Fixes #804 #794, partial #788 (issue 4)
2026-03-20 10:55:27 -07:00
Kenneth Lien
2aa90a8387
telegram: exit when Claude Code closes the connection
When the MCP stdio transport closes, the bot kept polling Telegram as
a zombie process — holding the token and causing 409 Conflict for the
next session.

- Listen for stdin end/close and SIGTERM/SIGINT -> bot.stop() + exit
- Force-exit after 2s if bot.stop() stalls on the long-poll timeout
- unref the approval-check interval so it doesn't keep us alive

Fixes #793, partial #788 (issue 3)
2026-03-20 10:54:33 -07:00
Kenneth Lien
9f2a4feab9
telegram: add error handlers to stop silent polling death
The bot would silently stop delivering messages after the first error:
grammy's default handler calls bot.stop() on any middleware throw, and
void bot.start() / void mcp.notification() swallow rejections with no log.

- bot.catch(): log and keep polling on handler errors
- bot.start().catch(): log when polling dies (bad token, 409, network)
- mcp.notification().catch(): log when inbound delivery to Claude fails
- process-level unhandledRejection/uncaughtException as a safety net

Fixes #756 #759 #761 #777 #809, partial #788
2026-03-20 10:53:36 -07:00
Tobin South
90accf6fd2
add(plugin): mcp-server-dev — skills for building MCP servers (#731) 2026-03-20 17:51:32 +00:00
Kenneth Lien
562a27feec
Merge pull request #811 from anthropics/kenneth/chmod-env-files
Lock telegram/discord .env files to owner (chmod 600)
2026-03-20 10:48:05 -07:00
Tobin South
d687c591f4
Staging → main: plugin marketplace additions (#730) 2026-03-20 17:41:01 +00:00
Kenneth Lien
8140fbad22
Lock telegram/discord .env files to owner (chmod 600)
The bot token is a credential. Tighten perms on load so hand-written
or pre-existing .env files get locked down, and update the configure
skill to chmod after writing. No-op on Windows.
2026-03-20 10:37:13 -07:00
Kenneth Lien
b664e152af
Merge pull request #758 from anthropics/docs/readme-clarifications
README clarifications from docs walkthrough testing
2026-03-19 21:34:55 -07:00
Ralph Furman
c3f6d9e9fa
Fix YAML frontmatter — quote description, replace colon with em-dash
Unquoted colon in 'calibrated confidence: will say' broke strict YAML parsing.
CC's parser is lenient but fix for robustness.
2026-03-20 02:07:27 +00:00
Ralph Furman
9720278412
math-olympiad: forbid web access in deep mode
Deep-mode allows bounded local computation but must NOT use WebFetch
or WebSearch. Finding the solution on AoPS is not solving the problem.
Adds explicit NO WEB prompt block and orchestrator self-restraint note.

Found by Ralph's test run (skill solved 5/6 then started fetching
dgrozev.wordpress.com and artofproblemsolving.com for P6).
2026-03-20 00:39:08 +00:00
Sarah Deaton
b01fad3396
README clarifications from docs walkthrough testing
- Drop /reload-plugins (redundant, you restart with --channels next)
- Fix token save path: .claude/channels/ not ~/.claude/channels/
- Clarify bot only responds once channel is running (pairing step)
2026-03-19 16:58:17 -07:00
Kenneth Lien
8908a582f8
Merge pull request #757 from anthropics/kenneth/add-bun-prereq
Add Bun prerequisite to discord/telegram READMEs
2026-03-19 16:31:36 -07:00