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

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions