Skip to content

Add screenshot MCP server and Telegram handler - #8

Open
kruzaster-beep wants to merge 1 commit into
linuz90:mainfrom
kruzaster-beep:main
Open

Add screenshot MCP server and Telegram handler#8
kruzaster-beep wants to merge 1 commit into
linuz90:mainfrom
kruzaster-beep:main

Conversation

@kruzaster-beep

Copy link
Copy Markdown

Introduce a screenshot feature that lets Claude capture and send screenshots via Telegram. Adds an MCP server (screenshot_mcp/server.ts) that uses macOS screencapture and writes metadata to /tmp/telegram-bot, a handler (src/handlers/screenshot.ts) that monitors and sends screenshots to the chat, and integration in src/session.ts to poll for pending screenshots after the MCP tool runs. Also updates UI/formatting (src/formatting.ts) to show a 📸 status, exports the handler in src/handlers/index.ts, and updates the MCP example config (mcp-config.example.ts) and README to include the screenshot server. Includes docs and setup guides (SCREENSHOT-SETUP.md, SCREENSHOT-QUICKSTART.md, docs/*.md) and a changelog (CHANGELOG-SCREENSHOT.md). Note: feature is macOS-only (uses screencapture) and requires screen recording permissions; MCP server runs under Bun.

Introduce a screenshot feature that lets Claude capture and send screenshots via Telegram. Adds an MCP server (screenshot_mcp/server.ts) that uses macOS `screencapture` and writes metadata to /tmp/telegram-bot, a handler (src/handlers/screenshot.ts) that monitors and sends screenshots to the chat, and integration in src/session.ts to poll for pending screenshots after the MCP tool runs. Also updates UI/formatting (src/formatting.ts) to show a 📸 status, exports the handler in src/handlers/index.ts, and updates the MCP example config (mcp-config.example.ts) and README to include the screenshot server. Includes docs and setup guides (SCREENSHOT-SETUP.md, SCREENSHOT-QUICKSTART.md, docs/*.md) and a changelog (CHANGELOG-SCREENSHOT.md). Note: feature is macOS-only (uses screencapture) and requires screen recording permissions; MCP server runs under Bun.
@kruzaster-beep

Copy link
Copy Markdown
Author

@linuz90 Hey, nice project, i enjoyed most of it. Sometimes i wanted to see what happens on my mac so i made claude able to send me a screenshot of display in telegram

telegram-cloud-photo-size-2-5260421093573465725-w

@linuz90 linuz90 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey thanks for this! The feature is useful, and I like the direction. However, two blockers:

  1. It doesn't merge cleanly onto current main right now.
  2. The screenshot MCP server writes files to hardcoded /tmp/telegram-bot, while the current runtime path work moves temp/runtime files under the configured runtime dir. This means it will break once the runtime-path changes are in place?

miracleengineered pushed a commit to miracleengineered/miracle that referenced this pull request Apr 22, 2026
miracleengineered pushed a commit to miracleengineered/miracle that referenced this pull request Apr 23, 2026
Wires the Miracle slice into the bot behind MIRACLE_SLICE_ENABLED flag.
All new paths are inert when the flag is off.

Handlers (new):
- src/handlers/miracle-callback.ts — HMAC-verifies callback_data from
  approval cards, enforces single-use via miracle_approvals.status
  transition, max-1-concurrent running-plan check, dispatches to
  Approve (launches Executor) / Edit / Reject paths.
- src/handlers/miracle-commands.ts — /plan <intent>, /miracle_halt,
  /miracle_status, /miracle_cancel. /plan creates a new forum Topic,
  runs Planner, persists plan + approval, posts approval card.
  Underscores in command names because Telegram disallows hyphens.

Executor refactor:
- Module-level activeControllers Map indexed by planId. runExecutor
  registers AbortController on start, unregisters in finally. Exports
  haltPlanId / haltAllPlans / listRunningPlanIds for /miracle_halt and
  /miracle_cancel.

index.ts wiring:
- Behind MIRACLE_SLICE_ENABLED: dynamic-import handlers (so modules
  don't load when flag off), register 4 commands + callback router,
  extend setMyCommands list. Callback router tries miracle handler
  first via isMiracleCallback prefix check; falls through to existing
  handleCallback otherwise.

Routing table:
- Added miracle-planner → sonnet, miracle-executor → sonnet entries.

Automated smokes (24 new tests across 4 files):
- miracle-callback-hmac (linuz90#9): sign/verify round-trip, 64-byte budget,
  forged signature rejected, verdict-swap rejected, malformed input
  rejected, secret rotation invalidates old callbacks.
- miracle-executor-blocklist (linuz90#8): rm -rf /, sudo rm, mkfs, dd if=,
  case-insensitive match, embedded pattern match, non-Bash tools
  always allowed.
- miracle-planner-retry (linuz90#7): first-try success, retry-on-parse-fail,
  retry-on-zod-fail, both-fail-throws-PlanValidationError, code-fence
  tolerance. Uses vi.mock('@anthropic-ai/claude-agent-sdk').
- miracle-auth: withSliceApiKey env swap + restore in both happy and
  throwing cases.

Not yet shipped (launchd plist edit + flag flip = Gate 2 finalize step):
- MIRACLE_SLICE_ENABLED=true in the launchd plist
- MIRACLE_HMAC_SECRET generation + plist

Smoke linuz90#11 (MVP byte-identical when flag off) is live-verified by the
currently-running bot (PID 50496, MIRACLE_SLICE_ENABLED unset).
Smokes #1-6 and linuz90#10 require Telegram UI and are deferred to the
live-in phase with Tren's phone.

Total: 230 passed + 1 skipped (was 206+1).
didiowen referenced this pull request in didiowen/diet-coach-bot Jun 16, 2026
…ter dead code

- New utils/telegram-download.ts: shared getFile+fetch with retry on 504/ECONNRESET (backoff) and response.ok validation
- photo/voice/document handlers now use the shared helper
- streaming.ts: delete done-footer + Undo/Commit/Yes/Handoff button code (disabled at runtime by patch-ctb.sh #5/#8); drop 4 orphan imports
- fix two strict-null type errors (action.ts index key, security.ts 'before')
DAIJIROMATSUOKA pushed a commit to DAIJIROMATSUOKA/claude-telegram-bot that referenced this pull request Jul 12, 2026
…装のfirst-time-right化(②削除は前tickで2重verified済so①専任)。MORNING-MASTER①小fix 9件を、静的doc記述と別軸=各fixのlocationを実機srcで直読(grep+sed)し「行番号一致・fix記述一致・バグクラス完全性」まで独立照合。★9件すべて記載locationにコード実在+記述一致=削除/追加GO。★MED級実バグ4件は挙動まで追跡し全てreal確定=linuz90#5 text.ts:200-222 AI Session Bridge分岐がreturn(L221)にstopProcessing()を持たず他4分岐+fallthroughは全て呼ぶ=唯一の_isProcessingリーク/linuz90#6 streaming.ts segment_end editMessageText成功(L257-259)後にlastContent.set漏れ→done footer(L322)がstale読取=末尾巻戻し(streaming編集L203/208は都度set済so非対称)/linuz90#7 callback.ts:88 mt:restore execSync(timeout15s)がasync handler内=bot最大15sフリーズ/linuz90#8 file-handler.ts:69 sips Bun.spawnSyncがevent loopブロック。★バグクラス完全性=startProcessing()呼出は全src3箇所(text.ts:170+document.ts:240,385)を実機確定→document.ts2件はtry/finally構造soリーク不能=#5が唯一の漏れ=churn防止claim正しい。★朝への申し送り1点(soft cross-dependency)=#8の「hot-path exec 3サイトのみ」完全性claimは②削除依存(media-commands.ts:96,299 spawnSyncは削除で消える)+image-handler.ts:90 spawnSyncが①単独完了時に宙に浮く=呼出元live判定を1grepで確認要(live=同fix/dead=②削除待ち)。read-only(grep/sed=書込なし)+新規doc1本(VERIFY-fix-batch-2026-07-09-1945.md)+log追記のみ・可逆commit(state配下のみ)。src編集/削除/typecheck変更/送信/settings/hook/launchd/gate緩和=ゼロ(実装は朝DJ判断)。
DAIJIROMATSUOKA pushed a commit to DAIJIROMATSUOKA/claude-telegram-bot that referenced this pull request Jul 12, 2026
…er.ts:90はlive確定=linuz90#8 fixがbug-class INCOMPLETEと判明。

19:41tickが条件付きで残した申し送り(image-handler.ts:90 spawnSyncのlive/dead 1grep未確認)を実機で解決。★live確定=呼出元resolveLocalImage()がexported live handler4つ(handleEdit/handleOutpaint/handleAnimate/handleUndress)から呼ばれ、全てregisterMediaCommands(src/index.ts:64→barrel media/index.ts再export)経由でboot登録=DJが/edit等でローカルHEIC画像を渡すと同期実行=event loopブロック確定。よって「②削除待ちで消える」線は否定=独立に生きたバグ。

★結論=linuz90#8 morning fixはbug-class INCOMPLETE。file-handler.ts:69だけ直すとimage-handler.ts:90に同一バグ(Bun.spawnSync(sips)がevent loopブロック)が未修正で残る。src全体のBun.spawnSync(sips)=4サイト=media-commands.ts:96/299(②削除で消滅)+file-handler.ts:69(LIVE=#8対象)+image-handler.ts:90(LIVE=未修正)。types.ts:135はDANGEROUS_SYMBOL_PATTERNSの文字列定義=実exec無し=対象外。

★朝推奨=#8にimage-handler.ts:90も同一async化(Bun.spawn+await proc.exited)を含める(両サイトcode完全一致so同一パッチ適用可)。media-commands.ts:96/299は②削除で自然消滅so触らない。DoD=削除後grep -rn spawnSync src でlive残存ゼロ(types.ts/testの2件のみ残ればOK)。

read-only(grep/sed/awk=書込なし)+新規doc1本+log追記の可逆commit(state配下のみ)。src編集/削除/typecheck変更/送信/settings/hook/launchd/gate緩和=ゼロ(実装は朝DJ判断)。
DAIJIROMATSUOKA pushed a commit to DAIJIROMATSUOKA/claude-telegram-bot that referenced this pull request Jul 12, 2026
…RNING-MASTER ①の linuz90#5(text.ts isProcessingリーク)/linuz90#6(streaming footer巻戻し)/linuz90#7(callback execSync)/linuz90#8(file-handler spawnSync) を working tree直読で機械照合=4件とも記述と一致=朝そのまま実装可。#8のみ実装nuance=Bun.spawn化時 proc.exitCode(async ではnull)→(await proc.exited)判定に書換え必須=単純 spawnSync→spawn 置換だと変換失敗に退行=VERIFY docに明記。read-only+新規doc1本+log追記の可逆commit(state配下のみ)。src編集/送信/削除/gate緩和=ゼロ。
DAIJIROMATSUOKA pushed a commit to DAIJIROMATSUOKA/claude-telegram-bot that referenced this pull request Jul 12, 2026
MORNING-MASTER ①小fix のうち直近tick(19:45/21:44)で個別に詰め切っていなかった
#1(council.ts topic生replace)とlinuz90#9(callback.ts optionIndex NaN)を実機直読で閉じた。

#1: grep '.replace("{' でplaceholder string-replaceを全列挙=4サイトのみ。
{topic}未保護のstring-replaceは L243(t)/295(topic)/336(topic) の3サイトちょうど。
隣接の {r1Summary}(295)・{allRoundsText}(337) は既に ()=>関数形で保護済
=MASTERの「保護済」claim TRUE=朝は{topic}の3サイトだけ触ればよい(隣接は不変)。
fix意図=String.replace(str,str)は置換文字列の $&/$1 等を特殊解釈so topic本文に
$混入でプロンプト破損→()=>topic のリテラル挿入で無害化。バグクラス完全(他replaceは対象外)。

linuz90#9: L167 parseInt→NaN / L188 NaN<0 false ∧ NaN>=len false=validation通過→
options[NaN]=undefined。latent real確認。fix=条件先頭に Number.isNaN(optionIndex)|| 前置。
latent根拠=parts[2]は自bot生成の整数indexso非数値は改竄/破損時のみ=任意扱い妥当。

これで①小fix 9件は全件が行番号+バグクラス完全性レベルで独立verified
(linuz90#2-linuz90#8=19:45+21:44 / #1linuz90#9=本tick)。
read-only(council.ts/callback.ts直読+grep)+新規doc1本+log。src編集/削除/送信/gate緩和=ゼロ。
DAIJIROMATSUOKA pushed a commit to DAIJIROMATSUOKA/claude-telegram-bot that referenced this pull request Jul 12, 2026
…ER ① の全9件を live code 8ファイル直読で before→after まで確定(#1 council L243/295/336=生replace→()=>関数形/linuz90#2 security L174=includes("rm ")→/\brm\s//linuz90#3 jarvis-memory L420=per-row safe-parse/linuz90#4 snooze L259-269=per-item try-catch+成功実数log/linuz90#5 text L221=stopProcessing()漏れ1行/linuz90#6 streaming L259=lastContent.set漏れ1行(ユーザー可視MED)/linuz90#7 callback L88=execSync同期→execAsync await化(bot15秒フリーズMED・execSync使用はL12importとL88のみと機械確認)/linuz90#8 file-handler L69=spawnSync→spawn+await proc.exited nuance明記/linuz90#9 callback L188=Number.isNaN前置)。各fixに現状行・反転test・完全性根拠を併記。read-only+新規doc1本+log。src編集/送信/削除/gate緩和=ゼロ。
DAIJIROMATSUOKA pushed a commit to DAIJIROMATSUOKA/claude-telegram-bot that referenced this pull request Jul 12, 2026
…ORNING-MASTER-2026-07-09の陳腐化3点を本文へ畳込訂正=①linuz90#8 image-handler.ts:90はdead疑いでなく実LIVE(file-handler.ts:69と2サイト両方async化要・DoD=grep spawnSync src/handlers/media で0件・順序=②でmedia-commands.ts先削除すれば#8は2サイトで閉じる) ②council-config.ts削除は@types/js-yaml(package.json)の連動orphan=同commitでbun remove ③contact-log.ts対test削除は不要(偽陽性・independent verify確定)。+drift0検証(e6d2a90)+import-siteプリフライト(f9acce7)を統合so朝は補正doc個別追跡不要=本FINAL1枚で①9fix+②7削除を実行可。read-only(grep/sed/git)+新doc1本+log1行、既存src/MORNING-MASTER編集/送信/削除/gate緩和ゼロ。
DAIJIROMATSUOKA pushed a commit to DAIJIROMATSUOKA/claude-telegram-bot that referenced this pull request Jul 12, 2026
MORNING-MASTER-2026-07-09.md(19:01)は「この1枚が唯一の入口」を謳うが、その後の夜間tick(20:22〜06:05)で確定した7 findingsが散在 morning-approval-queue.jsonl のみに存在=朝DJがMASTERだけ開くと取りこぼす構造。1枚の追補docに集約した。

★最重要=A: MASTER fix linuz90#8 の訂正。MASTERは「image-handler.ts:90は呼出元dead疑いso file-handler.ts:69だけが安全最小」と書いたが、本tick実機grep再確認=image-handler.ts:90 の Bun.spawnSync(sips) はLIVE(commit 30e00ea)。片サイトだけで閉じると同一event-loopフリーズが残存=修正未完(INCOMPLETE)。正=両サイト同時にawait化。DoD=grep spawnSync src/handlers/media で0件。

追加orphan(可逆・②削除リスト未収録)=B session-bridge.ts 564行(要DJ1問「/ai不要?」)/C enrichment.ts+tool-preloader.ts 190行/D 直接依存zod(src import 0件を実機再確認・transitive残存so挙動不変)/E @types/js-yaml(②council-config.ts削除に連動する機械的orphan・js-yaml import=council-config.ts:12の1ファイルのみ再確認)。依存順(E=②と同コミット/B=DJ確認前提/C・D=独立)+共通DoD(typecheck0/test1169pass/対象symbol grep0)を明記。

F=bot zombie化fix spec(crash semantics変更=不可逆so DJ設計判断+外🦞レビュー枠)。G=死export64件(constants.ts 26定数=別レイヤー参考)。最短GOルートで朝の判断負荷を圧縮。

read-only(grep×3実機再確認=image-handler.ts:90 sips live/zod src import 0/js-yaml=council-config.ts:12のみ)+新規追補doc1本+queue1行+log1行、src編集/削除/送信/settings/hook/gate緩和ゼロ。
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