[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-93032":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":15,"subscribersCount":15,"size":15,"stars1d":15,"stars7d":15,"stars30d":16,"stars90d":15,"forks30d":15,"starsTrendScore":15,"compositeScore":17,"rankGlobal":10,"rankLanguage":10,"license":18,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":21,"hasPages":19,"topics":22,"createdAt":10,"pushedAt":10,"updatedAt":23,"readmeContent":24,"aiSummary":25,"trendingCount":15,"starSnapshotCount":15,"syncStatus":26,"lastSyncTime":27,"discoverSource":28},93032,"smart_remarkable","yangg1224\u002Fsmart_remarkable","yangg1224","Integrate LLM with your remarkable ink screen ","",null,"Rust",52,6,51,0,1,42.64,"MIT License",false,"main",true,[],"2026-07-22 04:02:08","# Smart Remarkable\n\nA Vision-LLM agent for the reMarkable tablet. It watches what you write, and\nwhen you trigger it, sends a screenshot to an LLM and draws (or types) the\nresponse back onto the screen.\n\nThis project is a fork of [awwaiid\u002Fghostwriter](https:\u002F\u002Fgithub.com\u002Fawwaiid\u002Fghostwriter), extended with Select Mode.\n\n\u003Cimg src=\"docs\u002Fselect-mode-demo.gif\" width=\"300\">\n\nIt also has a **Select Mode**: lasso a region of handwriting, get an LLM\nanswer drawn into a box you choose. Because the answer is real pen strokes,\nyou can afterwards move and resize it with reMarkable's own selection tool.\n\n**New: LLM button.** When you lasso text with reMarkable's own selection\ntool, an **LLM** button now shows up right beside the usual cut\u002Fcopy\u002Fpaste\nmenu — tap it to kick off Select Mode on that selection, no corner tap or\ngesture required. It's added by a small extension\n(`xovi-ext\u002Fllmbutton`) that hooks into xochitl's UI.\n\n\u003Cimg src=\"docs\u002Fllm-button.jpeg\" width=\"300\">\n\n**New: Draw button.** A second button, **Draw**, sits right beside the LLM\nbutton (same extension). Lasso a region and tap it instead of LLM: if the\nselection is mostly handwritten\u002Ftyped text, it sketches a small pencil-scratch\ndoodle illustrating what you wrote, drawn below the selection; if the\nselection is already a drawing or sketch, it erases the original and redraws\nan improved, more detailed version of it in the same spot. See\n[SELECT_MODE.md](SELECT_MODE.md) for details.\n\n**New: image-generation drawing (`--image-model`).** By default the Draw\nbutton's artwork is SVG written by the chat LLM, which tops out at schematic\nline art. Pass `--image-model` (default `gemini-2.5-flash-image`, Google's\n\"nano banana\") and the sketch is instead rendered by a real image-generation\nmodel — the chat LLM only classifies the selection and writes the image\nprompt — then skeleton-traced into pen strokes. Sketch enhancement becomes\ntrue image-to-image: your lassoed drawing is attached to the request, and\nthe original strokes are removed via xochitl's own selection-delete before\nthe refined version draws in their place. Needs `GEMINI_API_KEY` or\n`GOOGLE_API_KEY`.\n\n\u003Cimg src=\"docs\u002Fimage-draw-demo.gif\" width=\"300\">\n\n## Contents\n\n- [Features](#features)\n- [Usage](#usage)\n- [Install](#install)\n- [LLM API Keys](#llm-api-keys)\n- [Architecture](#architecture)\n- [License](#license)\n- [Credits](#credits)\n\n## Features\n\n- **Watch-and-draw loop.** A background task waits for a touch trigger (tap\n  a screen corner, a four-finger tap, or a physical \"LLM\" button press — see\n  below), screenshots the current page straight out of xochitl's\n  framebuffer, sends it to a vision-capable LLM, and writes the answer back\n  onto the screen — either typed via a virtual keyboard (`draw_text`) or\n  hand-drawn as pen strokes from an LLM-generated SVG (`draw_svg`).\n\n- **Select Mode** (`--select-mode`). Tap the trigger corner, then tap two\n  opposite corners around a piece of handwriting to select it, then two more\n  corners to choose where the answer should be drawn. The cropped selection\n  is sent to the LLM, and the answer comes back as real ink scaled\u002Fcentered\n  into your placement box — genuine pen strokes you can move and resize\n  afterward with reMarkable's native selection tool. See `SELECT_MODE.md`\n  for the full walkthrough.\n\n- **LLM button (`xovi-ext\u002Fllmbutton`).** A XOVI native extension\n  (`llmbutton.so`) that hooks into the running `xochitl` process at the Qt\n  scene-graph level and injects an \"LLM\" button next to the stock\n  cut\u002Fcopy\u002Fpaste selection menu. Tapping it writes a trigger file\n  (`\u002Ftmp\u002Fllm_button_trigger`) that kicks off Select Mode on the current\n  selection — no corner tap needed.\n\n- **Draw button** (same extension). A second injected button beside LLM.\n  Tapping it after lassoing a region writes `\u002Ftmp\u002Fdraw_button_trigger` and\n  routes to `prompts\u002Fdraw.json`'s `draw_sketch` tool instead of an LLM\n  answer: if the selection is mostly text, the model draws an illustrative\n  doodle below it; if the selection is already a drawing, the app erases\n  the original ink and redraws an improved version in the same spot. See\n  [SELECT_MODE.md](SELECT_MODE.md) for the full mechanics.\n\n- **Image-generation drawing** (`--image-model`, `--image-api-key`).\n  Reroutes the Draw button through an image-generation model (default\n  `gemini-2.5-flash-image`, \"nano banana\"): the chat LLM classifies the\n  selection and writes a detailed image prompt (`prompts\u002Fdraw_image.json`),\n  `src\u002Fimage_gen.rs` calls the Gemini image API — attaching the upscaled,\n  background-cleaned crop of your sketch in enhancement mode — and the\n  returned line art is thresholded, thinned to a 1-px skeleton, and traced\n  as pen strokes (`Pen::draw_bitmap_centerline`). For the in-place redraw,\n  the original strokes are deleted exactly via xochitl's own selection menu\n  (the app locates and taps its trash button; dense hardware-eraser sweeps\n  are the fallback), and only after generation succeeded — a failed API\n  call never destroys your sketch.\n\n- **Rotation-aware input.** Each screenshot detects whether xochitl's UI is\n  rendered 180° rotated (device held upside down), normalizes the image to\n  the user's orientation for the LLM and marquee detection, and mirrors all\n  synthetic pen\u002Ftouch coordinates back at the injection boundary — so taps,\n  erasing, and drawing land correctly either way you hold the tablet.\n\n- **Web config UI** (`--web-server`, `--web-port`). A `warp`-based HTTP\n  server (default port `8080`) serving a small static UI for viewing and\n  live-editing the running config, applying changes immediately (in-memory,\n  hot-reloaded via a watch channel, with in-flight LLM calls cancelled) and\n  persisting them to `~\u002F.smart_remarkable.toml`. Also exposes\n  `POST \u002Fapi\u002Fsimulation\u002Ftrigger` to fire a trigger manually without touching\n  the device.\n\n- **Image segmentation** (`--apply-segmentation`). Runs contour-based region\n  detection (`imageproc`) over the screenshot before calling the LLM,\n  appending a text description of detected ink regions to the prompt for\n  better spatial grounding.\n\n- **Anthropic-only extras: thinking and web search.** `--thinking` enables\n  extended thinking (`--thinking-tokens`, default `5000`, sets the budget);\n  `--web-search` gives Claude a server-side web-search tool (max 5 uses per\n  call). Both are no-ops on OpenAI\u002FGoogle engines.\n\n- **Layered, persistable config.** `--save-config` writes the fully-resolved\n  config (defaults \u003C `~\u002F.smart_remarkable.toml` \u003C `SMART_REMARKABLE_*` env\n  vars \u003C CLI args) to `~\u002F.smart_remarkable.toml` and exits, so you can bake\n  in your preferred flags instead of retyping them every launch.\n\n- **Simulation \u002F offline testing.** `--input-png` swaps a live screenshot\n  for a static image; `--test-mode \u003Crm2|rmpp>` plus\n  `--test-touch-events-file`, `--test-screenshot-dir`,\n  `--test-auto-trigger-delay`, and `--test-interaction-log` let the entire\n  touch→screenshot→LLM→draw pipeline run headlessly on a desktop, no\n  hardware required. `--no-draw`, `--no-submit`, `--no-loop`, and\n  `--no-trigger` combine for fully offline, single-shot runs (used by\n  `run_eval.sh`'s evaluation harness).\n\n## Usage\n\n**Normal mode**, from an SSH session on the device:\n\n```bash\nANTHROPIC_API_KEY=sk-... .\u002Fsmart_remarkable\n```\n\n1. Write something on the page.\n2. Tap the trigger corner (default upper-right; change with\n   `--trigger-corner`).\n3. The tool screenshots the page, sends it to the LLM, and types or draws\n   the answer back onto the screen.\n\n**Select Mode**:\n\n```bash\nANTHROPIC_API_KEY=sk-... .\u002Fsmart_remarkable --select-mode\n```\n\n1. Tap the trigger corner to arm.\n2. Tap two opposite corners around the handwritten question (a minimum\n   40px box is enforced, so imprecise taps are fine).\n3. Tap two opposite corners of where the answer should be drawn.\n4. The cropped selection is sent to the LLM; the answer is scaled and drawn\n   as pen strokes into the placement box. Move\u002Fresize it afterward with\n   xochitl's native selection tool.\n\nThere's no on-screen guidance between taps — the sequence is always\ntrigger → 2 selection taps → 2 placement taps. Run with `--log-level debug`\nover SSH while you're learning the gesture.\n\n**LLM button \u002F Draw button**: with `xovi-ext\u002Fllmbutton` installed, lassoing\ntext with xochitl's own selection tool shows **LLM** and **Draw** buttons\nbeside cut\u002Fcopy\u002Fpaste — tap either to run Select Mode on that selection\nwithout a corner-tap trigger, using the LLM-answer flow or the\nsketch\u002Fredraw flow respectively.\n\n**Key CLI flags**\n\n| Flag | Default | Purpose |\n|---|---|---|\n| `--engine` | auto-guessed from `--model` | Force `openai` \u002F `anthropic` \u002F `google` |\n| `-m, --model` | `claude-sonnet-4-6` | Model name |\n| `--engine-base-url` | provider default | Override API base URL |\n| `--engine-api-key` | from env var | API key |\n| `--prompt` | `general.json` | Prompt template (auto-switches to `selection.json` in select mode) |\n| `--select-mode` | off | Enable Select Mode |\n| `--image-model` | off (`gemini-2.5-flash-image` if passed bare) | Render Draw-button sketches with an image-generation model |\n| `--image-api-key` | `GEMINI_API_KEY` \u002F `GOOGLE_API_KEY` | API key for the image model |\n| `--trigger-corner` | `UR` | `UR`\u002F`UL`\u002F`LR`\u002F`LL` |\n| `--apply-segmentation` | off | Add CV-derived spatial hints to the prompt |\n| `--web-search` \u002F `--thinking` \u002F `--thinking-tokens` | off \u002F off \u002F `5000` | Anthropic-only extras |\n| `--web-server` \u002F `--web-port` | off \u002F `8080` | Live config UI\u002FAPI |\n| `--save-config` | off | Persist resolved config and exit |\n| `--log-level` | `info` | `debug`, `trace`, etc. |\n| `--input-png`, `--test-mode`, `--test-touch-events-file`, `--test-screenshot-dir`, `--test-auto-trigger-delay` | — | Offline simulation \u002F testing |\n| `--no-submit`, `--no-draw`, `--no-loop`, `--no-trigger` | off | Skip pieces of the pipeline for testing |\n| `--debug-tap`, `--debug-drag`, `--debug-lasso`, `--debug-type`, `--debug-svg`, `--debug-erase` | — | One-shot device-I\u002FO helpers, exit after running |\n\n**Example commands**\n\n```bash\n# Run with Claude, corner trigger on upper-left, verbose logging\nANTHROPIC_API_KEY=sk-... .\u002Fsmart_remarkable --trigger-corner UL --log-level debug\n\n# Select Mode with a specific Gemini model and the web config UI enabled\nGOOGLE_API_KEY=... .\u002Fsmart_remarkable --select-mode -m gemini-2.5-pro --web-server\n\n# Offline test against a saved screenshot, no drawing, single pass\n.\u002Fsmart_remarkable --input-png .\u002Ftest.png --no-draw --no-loop --no-trigger --no-submit\n\n# Select Mode with nano-banana image generation for the Draw button\nOPENAI_API_KEY=... GEMINI_API_KEY=... .\u002Fsmart_remarkable --select-mode \\\n  --trigger-corner four-finger -m gpt-5.4 --image-model\n```\n\n## Install\n\n**Toolchain**: Rust `1.92.0` (pinned in `.tool-versions`).\n\n**Build locally**\n\n```bash\ncargo build --release\n# or\n.\u002Fbuild.sh local\n```\n\nBinary: `target\u002Frelease\u002Fsmart_remarkable`.\n\n**Cross-compile with Docker (`cross`)**\n\n```bash\ncargo install cross --git https:\u002F\u002Fgithub.com\u002Fcross-rs\u002Fcross\nrustup target add armv7-unknown-linux-gnueabihf aarch64-unknown-linux-gnu\n\n# reMarkable 2 (armv7)\ncross build --release --target=armv7-unknown-linux-gnueabihf\n# or: .\u002Fbuild.sh\n\n# Paper Pro (aarch64)\ncross build --release --target=aarch64-unknown-linux-gnu\n# or: .\u002Fbuild.sh rmpp\n```\n\n`build.sh` can also scp the result for you: pass a hostname as the first\nargument (default `remarkable`); anything starting with `rmpp` builds\u002Fships\naarch64 to `root@\u003Chost>`, anything else builds\u002Fships armv7. E.g.\n`.\u002Fbuild.sh rmpp-mytablet` or `.\u002Fbuild.sh 192.168.1.117`.\n\n**Cross-compile without Docker (macOS, Paper Pro \u002F aarch64 only)**\n\n```bash\nbrew tap messense\u002Fmacos-cross-toolchains && brew install aarch64-unknown-linux-gnu\nrustup target add aarch64-unknown-linux-gnu\nCARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-unknown-linux-gnu-gcc \\\n  cargo build --release --target aarch64-unknown-linux-gnu\n```\n\nThere's no verified Docker-free path for the reMarkable 2 (armv7) target in\nthis repo — `.cargo\u002Fconfig.toml` has a commented-out template for a\nmessense-style `arm-remarkable-linux-gnueabi-gcc` toolchain, but it isn't\nfilled in or active.\n\n**Deploy via scp**\n\n```bash\nscp target\u002Farmv7-unknown-linux-gnueabihf\u002Frelease\u002Fsmart_remarkable root@\u003Cdevice-ip>:\n# or\nscp target\u002Faarch64-unknown-linux-gnu\u002Frelease\u002Fsmart_remarkable root@\u003Cdevice-ip>:\n```\n\nFind the device IP and root password under Settings → Help → About on the\ntablet.\n\n**Run on-device**\n\n```bash\nssh root@\u003Cdevice-ip>\nANTHROPIC_API_KEY=sk-... .\u002Fsmart_remarkable --select-mode\n```\n\n- **Developer Mode is required** (Settings → General → Software →\n  Advanced). Enabling it factory-resets the device and voids the warranty.\n- Run in the background with `nohup .\u002Fsmart_remarkable &`.\n- **Paper Pro uinput note**: the bundled uinput kernel module auto-loads and\n  is prebuilt for OS versions 3.16–3.18 and 3.22 (`utils\u002Frmpp\u002Fuinput-3.16.ko`,\n  `-3.17.ko`, `-3.18.ko`, `-3.22.ko`). Other OS versions may need a rebuilt\n  module — see `utils\u002Frmpp\u002F`.\n\n## LLM API Keys\n\nSet whichever provider's key you plan to use as an environment variable, or\ndrop them in a local `.env` file (loaded via `dotenv`):\n\n```bash\nexport OPENAI_API_KEY=your-key-here\nexport ANTHROPIC_API_KEY=your-key-here\nexport GOOGLE_API_KEY=your-key-here\nexport GEMINI_API_KEY=your-key-here   # image generation (--image-model); GOOGLE_API_KEY also works\n```\n\nNote: image generation is not in the Gemini free tier — the key's Google AI\nStudio project needs billing enabled (`gemini-2.5-flash-image` is ~$0.04 per\nimage).\n\n- `--engine` picks the backend explicitly (`openai`, `anthropic`,\n  `google`). If omitted, it's guessed from the `--model` name's prefix\n  (`gpt*` → openai, `claude*` → anthropic, `gemini*` → google); if it can't\n  guess, it errors and asks you to pass `--engine`.\n- `--engine-api-key` \u002F `--engine-base-url` override the corresponding\n  provider env var (`OPENAI_API_KEY`\u002F`OPENAI_BASE_URL`,\n  `ANTHROPIC_API_KEY`\u002F`ANTHROPIC_BASE_URL`,\n  `GOOGLE_API_KEY`\u002F`GOOGLE_BASE_URL`). If neither the CLI flag nor the env\n  var is set for the API key, the process will panic — there's no fallback.\n  Base URLs do have hardcoded fallbacks (`api.openai.com`,\n  `api.anthropic.com`, `generativelanguage.googleapis.com`).\n- **Default model**: `claude-sonnet-4-6`, which auto-resolves to the\n  `anthropic` engine when `--engine` isn't specified.\n\n## Architecture\n\n**Data flow**: touch trigger → screenshot → LLM → draw\u002Ftype.\n\n1. **Trigger** (`touch.rs`, `coordinator::trigger_task`) — waits on\n   `\u002Fdev\u002Finput\u002FeventN` for a corner-tap release, a four-finger tap, or an\n   external write to `\u002Ftmp\u002Fllm_button_trigger` or `\u002Ftmp\u002Fdraw_button_trigger`\n   (from the `llmbutton` xovi extension). Which one fired is tracked as\n   `touch::TriggerSource` (`Touch` \u002F `LlmButton` \u002F `DrawButton`) and threaded\n   through `TriggerEvent`\u002F`processing_task`, which picks `prompts\u002Fdraw.json`\n   over the configured `--prompt` only for `DrawButton`. In Select Mode it\n   also collects the two pairs of corner taps defining the selection rect\n   and the placement rect.\n2. **Capture** (`screenshot.rs`) — reads `xochitl`'s framebuffer directly\n   out of `\u002Fproc\u002F\u003Cpid>\u002Fmem`, decodes\u002Frotates\u002Fcolor-corrects it into a\n   normalized 768×1024 PNG; can detect the native selection marquee via\n   connected-component analysis.\n3. **Coordinate** (`coordinator.rs`) — an async pipeline of `tokio` tasks\n   (`trigger_task` → `processing_task` → `progress_task`) joined by\n   `mpsc`\u002F`watch` channels. `processing_task` optionally crops to the\n   selection rect, optionally runs `segmenter.rs`, loads the JSON prompt\n   template, and hands the base64 image + prompt to the LLM engine.\n   `progress_task` types a \"Thinking...\" dot animation via the virtual\n   keyboard while waiting.\n4. **LLM call** (`src\u002Fllm_engine\u002F`) — a shared `LLMEngine` trait\n   abstracts over `openai.rs`, `anthropic.rs`, `google.rs`. Each builds a\n   provider-specific tool-forcing request and invokes the callback for\n   whichever tool the model calls: `draw_text`, `draw_svg`, `draw_answer`\n   (structured line-based layout for Select Mode), or `draw_sketch` (Draw\n   button — reports `selection_is_drawing` to pick doodle-below-selection\n   vs. erase-and-redraw-in-place).\n5. **Draw** (`pen.rs`, `keyboard.rs`) — `pen.rs` parses SVG via\n   `resvg`\u002F`usvg` (text-to-path) and `svg2polylines` (tracing), converting\n   it into virtual pen strokes injected as raw `evdev` events; `skeleton.rs`\n   offers an alternative centerline-tracing render path via Zhang-Suen\n   thinning. For in-place redraws, `Pen::erase_rect` first sweeps\n   `BTN_TOOL_RUBBER` (real eraser-tip hardware signal) passes across the\n   box — xochitl ignores normal pen strokes as erasing regardless of the\n   selected toolbar tool. `keyboard.rs` drives a `uinput` virtual keyboard\n   to type text and the progress-dot animation.\n\n**Key modules**\n\n| Module | Responsibility |\n|---|---|\n| `main.rs` | CLI entry point, config\u002Fengine wiring, tool registration, restart-on-config-change loop, `--debug-*` one-shot helpers |\n| `coordinator.rs` | Async task graph: trigger detection, progress reporting, screenshot→LLM→tool pipeline |\n| `touch.rs` | Raw touch\u002Fevdev reading, corner\u002Ffour-finger trigger detection, coordinate mapping, gesture helpers |\n| `screenshot.rs` | Framebuffer capture, decode, selection-marquee detection, cropping |\n| `pen.rs` | Virtual pen (`evdev`\u002Fuinput): SVG\u002Fbitmap rendering strategies |\n| `keyboard.rs` | Virtual keyboard (`evdev`\u002Fuinput): text typing, progress-dot animation |\n| `device.rs` | `DeviceModel` detection (RM2 \u002F Paper Pro) and per-device constants |\n| `segmenter.rs` | Contour-based region detection for spatial grounding |\n| `skeleton.rs` | Zhang-Suen thinning \u002F centerline tracing |\n| `util.rs` | SVG↔bitmap rasterization, fit-to-rect logic, uinput setup |\n| `llm_engine\u002F` | `LLMEngine` trait + `openai.rs`\u002F`anthropic.rs`\u002F`google.rs` |\n| `image_gen.rs` | Gemini image-generation client for `--image-model` (nano banana) |\n| `config.rs` | Layered config via `figment`\u002F`toml`, hot-reload watch channel |\n| `cancellation.rs` | Cooperative cancellation tokens |\n| `status.rs` | Shared status snapshot for the web UI |\n| `web_server.rs` + `src\u002Fweb\u002F` | Optional `warp` HTTP server + static config UI |\n| `simulation\u002F` | Desktop stand-ins for touch\u002Fscreenshot hardware, interaction logging |\n| `src\u002Fbin\u002Fexperiment.rs` | Secondary binary for ad-hoc experimentation |\n| `embedded_assets.rs` | Bundles `prompts\u002F*.json` into the compiled binary via `rust-embed` |\n\n**Stack**: Rust + `tokio` async task graph; `clap` for CLI; `reqwest`\u002F`ureq`\nfor LLM HTTP calls; `resvg`\u002F`usvg`\u002F`svg2polylines` for SVG-to-stroke\nrendering; `evdev`\u002F`uinput` for virtual touch\u002Fpen\u002Fkeyboard devices;\n`figment`\u002F`toml` for layered config; `warp` for the optional web UI;\n`cross`-rs (Docker) or the messense toolchain for cross-compilation to\narmv7\u002Faarch64; a `prompts\u002F*.json` system (`general.json`, `selection.json`,\nplus one `tool_*.json` schema per registered tool) that drives LLM\ntool-calling across all three provider backends.\n\nThe **LLM\u002FDraw button** extension (`xovi-ext\u002Fllmbutton`) is architecturally\nseparate: it's a standalone C shared object built against the XOVI\nextension framework, loaded into the *stock* `xochitl` process itself\n(resolving Qt6 symbols via `dlsym`, walking the live QtQuick scene graph to\ninject both buttons into the native selection menu) rather than part of the\nRust `smart_remarkable` binary — the two communicate only via the\nfilesystem trigger files `\u002Ftmp\u002Fllm_button_trigger` and\n`\u002Ftmp\u002Fdraw_button_trigger`.\n\n## License\n\nMIT — see [LICENSE](LICENSE). The release binary also embeds a GPL-2.0\nkernel module; see [THIRD_PARTY_LICENSES.md](THIRD_PARTY_LICENSES.md).\n\n## Credits\n\nForked from [awwaiid\u002Fghostwriter](https:\u002F\u002Fgithub.com\u002Fawwaiid\u002Fghostwriter).\n\nReferences this project has drawn from:\n* [Awesome reMarkable](https:\u002F\u002Fgithub.com\u002FreHackable\u002Fawesome-reMarkable)\n* Screen capture adapted from [reSnap](https:\u002F\u002Fgithub.com\u002Fcloudsftp\u002FreSnap)\n* Screen-drawing technique inspired by [rmkit lamp](https:\u002F\u002Fgithub.com\u002Frmkit-dev\u002Frmkit\u002Fblob\u002Fmaster\u002Fsrc\u002Flamp\u002Fmain.cpy)\n* SVG-to-PNG via [resvg](https:\u002F\u002Fgithub.com\u002FRazrFalcon\u002Fresvg)\n* Virtual keyboard input via [rM-input-devices](https:\u002F\u002Fgithub.com\u002Fpl-semiotics\u002FrM-input-devices)\n","这是一个为reMarkable电子墨水屏设备设计的视觉-大语言模型（Vision-LLM）智能代理工具，实现手写内容的实时识别、理解与响应。核心功能包括：触发后自动截取屏幕并调用多模态LLM分析手写内容，将文本回复以虚拟键盘输入或SVG笔迹形式回写到屏幕；支持Select Mode——通过套索选区直接调用LLM生成答案或AI绘图，并以真实笔迹呈现，可被原生选区工具移动\u002F缩放；新增LLM按钮与Draw按钮集成至系统选区菜单，支持图像生成模型（如gemini-2.5-flash-image）驱动的草图增强与重绘。适用于笔记批注、手写转录、教学辅助及创意草图迭代等场景。",2,"2026-07-11 02:30:42","CREATED_QUERY"]