Skip to content

Feature: remote capture from phone — voice notes, images & links + thoughts via direct-to-intake #37

Description

@wimaan3

Context

Capture ideas away from the desktop: send a voice note, an image, or a link (e.g. an Instagram post URL) plus some accompanying thoughts from a phone, and have grandplan organize it into a note like any hotkey capture — media preserved as attachments, URLs preserved as link resources.

Transport decision: direct-to-intake — a phone shortcut / minimal PWA that POSTs to the existing HTTP intake (src/grandplan/adapters/http_intake.py) over a private network (Tailscale/WireGuard or LAN). No messenger platform in the loop: content never transits a third-party cloud, so the offline/zero-egress invariant holds end-to-end (QAS-1). The core app still never makes an outbound request.

Much of this exists already:

  • http_intake.py — token-authed (constant-time), 127.0.0.1-default intake built exactly for "POST content from a phone over LAN/VPN".
  • voice.py — offline STT via faster-whisper (grandplan[voice]); mic-based today, but the same local model transcribes an audio file.
  • The organizer's resources pipeline already extracts URLs present in the capture text into the note's ## Resources block (with the anti-hallucination containment check), so "thoughts + IG link" → link lands in the note with no new code.

Threads

  • Attachments over intake — accept media alongside text (multipart or size-capped base64 field; current 1 MiB body cap must be rethought for voice notes/images, with an explicit new cap). Persist media into a vault attachments dir; reference from the note as file resources. Reject unexpected content types; never execute/render untrusted content.
  • Voice-note transcription — route received audio files through a file-based Transcriber (reuse faster-whisper, local, offline). Transcript becomes the capture text (plus any typed thoughts); original audio kept as an attachment (lossless: the source artifact is preserved).
  • Image + thoughts (v1) — store the image as an attachment resource; the accompanying text is the capture. (v2, deferred: optional local vision model to describe/extract — new multi-GB model on the 16 GB no-GPU target, needs its own evaluation.)
  • Phone-side sender — an iOS/Android Shortcut recipe and/or a single-file PWA served by the intake (share-sheet friendly: share a post/photo/voice memo → adds thoughts → POST). Documented setup for Tailscale/WireGuard reachability.

Acceptance criteria

  • A voice note POSTed from a phone becomes an organized note whose body is the local transcript; the audio file is saved in the vault and linked as a resource.
  • An image + text POST becomes a note with the image attached and linked.
  • Text containing a URL (e.g. an Instagram post) yields a note with that URL in ## Resources (existing behavior verified through the new path).
  • Intake stays token-gated and 127.0.0.1 by default; media size/type limits enforced before reading the body; auth failures leak nothing.
  • Zero network egress from grandplan itself — nothing is fetched; the app only receives. Fully offline processing (Whisper local).
  • Works on the 16 GB / no-GPU target.

Non-goals (for this issue)

  • Messenger-platform bridges (Telegram/WhatsApp bots). Considered and deferred: they route content through third-party clouds; if ever built, it would be a separate optional companion process, never core.
  • Vision-model understanding of images (v2 candidate).
  • Fetching remote content from shared URLs (violates zero-egress; the link itself is the artifact).

Related

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions