~/notes/projects/Captain's Logonmain

Captain's Log


Overview

I’ve always loved those scenes in movies where a character uses a voice recorder to capture real-time notes, but never quite enough to buy a voice recorder. I have however, been interested in the Pebble since the initial run, and since they came back and I have adult money, I’ve acquired a Pebble Time 2.

It seems like everyone’s first project with the Pebble is to re-invent voice notes, and I’m no different.

Technical Details

Architecture

flowchart LR
    subgraph Watch["Pebble Watch"]
        A[Voice Note<br/>Recording]
        H[Sync Action]
    end

    subgraph Phone["iPhone"]
        B["Dictation API<br/>(Local Transcription)"]
        C["Review Screen<br/>(optional)"]
        F{Server<br/>Available?}
        G[(Pending Queue<br/>localStorage)]
    end

    subgraph Mac["MacBook Server"]
        D[Webhook<br/>Endpoint]
        E[(Obsidian Vault<br/>Inbox)]
    end

    A -->|"audio"| B
    B -->|"transcript"| C
    B -.->|"skip review"| F
    C -->|"confirmed text"| F
    F -- yes --> D
    F -- no --> G
    H -.->|"trigger flush"| G
    G -->|"flush pending"| D
    D -->|"writes note"| E

Use

The first priority here is easy voice recording. To that end, the app is built with a pair of interaction modes:

Quick Launch

When started with the APP_LAUNCH_QUICK_LAUNCH launch reason, Captain's Log immediately begins a dictation session. When the dictation session is ended (either by button press or timeout1), the transcript is optionally presented to the user for review. This review behavior is configurable, but transcription is off often enough that I’ve left it on.

When the transcript is approved (or automatically, if review is disabled), the text is sent to a configured webhook URL by PebbleKit JS running phone-side. If that request fails for any reason, the transcript is stored in localStorage, and a count of pending transcripts is sent back to the watch to display on the App Glance.

Log Management

When started by any other launch reason, the app opens into an action menu, allowing the user to:

  1. trigger bulk sync of pending transcripts to the webhook
  2. review individual transcripts, allowing for sync or deletion
  3. add a new entry

Issues and Next Steps

Frankly, local transcription on the iPhone isn’t great. The Pebble app uses parakeet-tdt-0.6b-v3 on my iPhone, and it is both slow and inaccurate. I’d love for raw recordings to be made available such that I could pass a recording to the server on my MacBook to transcribe using a beefier model, but the Pebble doesn’t expose that functionality yet.

This PR looks like it’ll add mic API support to the OS, enabling raw recordings to be shipped to the server for transcription; I’ll be watching that before making further updates.

I haven’t opened the code here, for the primary reason that it’s heavily vibe-coded and I want to take a cleanup pass before doing so. Once that’s done, I’ll open the repo and link here.