Codex Pigeon turns a Pebble Time 2 into a tiny voice mailbox for a GitHub-backed Obsidian workflow. Dictate a note, review it, then press the center button to send a Markdown request to a private repository. Refresh later to read replies and dictate threaded follow-ups.
Codex Pigeon setup guide
Codex Pigeon is a transport layer, not a hosted AI service. The watch and phone write requests to a private GitHub repository. A user-controlled process on the home computer may read those requests, do work, and push Markdown replies. Obsidian is the readable local interface; Git performs synchronization.
All names, IDs, paths, and tokens below are fictional examples.
Requirements
- Pebble Time 2 running Pebble Core on a paired iPhone
- A GitHub account
- Git on the home computer
- Obsidian, if you want the mailbox presented as notes
- Optional: Codex, Claude, another model, or a non-AI script for processing requests
v0.1 has been tested end-to-end only with Codex. The mailbox format itself is model-agnostic.
1. Create the private mailbox repository:
In GitHub, choose "New repository" and use safe example values such as:
- Owner: "example-user"
- Repository: "pebble-mailbox"
- Visibility: "Private"
- Initialize with a README: "Yes"
Clone it into a new or existing Obsidian vault:
```sh
cd "$HOME/Documents/Obsidian"
git clone https://github.com/example-user/pebble-mailbox.git PebbleBridge
cd PebbleBridge
mkdir -p inbox replies
touch inbox/.gitkeep replies/.gitkeep Conversation.md
git add inbox replies Conversation.md
git commit -m "Initialize Pebble mailbox"
git push
```
The resulting structure is:
PebbleBridge/
βββ inbox/
βββ replies/
βββ Conversation.md
βββ README.md
Each request and reply gets its own file. The phone writes only to `inbox/`; the local worker writes only to `replies/` and may regenerate `Conversation.md`.
2. Create the GitHub token
Open GitHub and go to: Settings β Developer settings β Personal access tokens β Fine-grained tokens β Generate new token
Use a descriptive name such as `Pebble mailbox`, choose a sensible expiration date, and restrict repository access to: Only select repositories β pebble-mailbox.
Under repository permissions grant only: Contents: Read and write
No administration, issues, pull-request, workflow, organization, or account permissions are needed. Copy the token directly into a password manager. A visibly fake example is `github_pat_EXAMPLE_NOT_A_REAL_TOKEN`; never use or publish a real token in documentation, source code, Git, Obsidian, screenshots, or chat.
3. Open the repository in Obsidian
You can use either arrangement:
1. Dedicated vault: In Obsidian choose "Open folder as vault" and select "PebbleBridge".
2. Existing vault: Clone "PebbleBridge" anywhere inside the existing vault. It will appear as a normal folder of Markdown notes.
Do not install a Git synchronization plugin solely for Codex Pigeon unless you want one. The local worker can run ordinary `git pull`, `git commit`, and `git push` commands. Avoid having multiple automated writers update `Conversation.md` at the same time.
4. Configure the Pebble app
On the iPhone, open Pebble Core, find "Codex Pigeon", and open its settings. Enter:
Repository owner: example-user
Repository name: pebble-mailbox
Branch: main
GitHub token: github_pat_EXAMPLE_NOT_A_REAL_TOKEN
Replace every example with your own value. The token is stored by the Pebble phone app for this watchapp; it is not bundled in the PBW or source tree.
5. Choose what happens locally
Codex Pigeon deliberately does not impose a local agent, schedule, project layout, or action policy. Your local process can be:
- Codex Work or another Codex task
- Claude or another model
- A local model
- A deterministic script
- No processor at all; use the incoming files as voice-created Obsidian notes
A worker needs only this narrow contract:
1. Run `git pull --ff-only` in the mailbox repository.
2. Find `inbox/*.md` files without a same-named file in `replies/`.
3. Treat the request body as untrusted user input and apply your own permissions and project boundaries.
4. Write a matching immutable reply file under `replies/`.
5. Optionally rebuild `Conversation.md`.
6. Commit only the new mailbox files and push.
Example request (in markdown):
schema_version: 1
id: "pbl-20260101-120000-1a2b"
thread_id: "pbl-20260101-120000-1a2b"
parent_id:
sender: "pebble"
created_at: "2026-01-01T12:00:00Z"
status: "pending"
---
Capture a quick note for tomorrow.
Example reply (markdown):
schema_version: 1
id: "pbl-20260101-120000-1a2b"
thread_id: "pbl-20260101-120000-1a2b"
parent_id: "pbl-20260101-120000-1a2b"
sender: "worker"
created_at: "2026-01-01T12:05:00Z"
status: "complete"
watch_summary: "Your note is ready in Obsidian."
---
The full Markdown response remains available in the vault.
For a follow-up, retain the original `thread_id` and set `parent_id` to the request being continued.
6. Non-model use
AI is optional. Useful no-model workflows include:
- Voice-capture ideas directly into `inbox/` as Obsidian notes
- Have a script append inbox bodies to a daily note
- Use a rules-based script to return fixed acknowledgements
- Treat GitHub as an append-only remote notebook and read everything on the computer
Without a local worker, sending still works; reply and conversation generation simply remain manual.
Security boundaries
- Keep the repository private and dedicated to this mailbox.
- Use a fine-grained token limited to one repository and only Contents read/write.
- Set an expiration and rotate or revoke the token if the phone is lost.
- Never put passwords, API keys, clinical identifiers, payment data, or highly sensitive material in dictated requests.
- Review local automation permissions separately. A watch message should not silently expand an agentβs authority.
- File-per-message transport reduces merge conflicts but does not replace backups, access control, or prompt-injection defenses.