Voice-note capture as the primary mobile input channel. AudioPen polishes on their cloud, POSTs to a self-hosted receiver on the desktop (exposed via Tailscale Funnel so no router ports open and nothing behind Authentik). The receiver writes to inbox/raw/; a bash normaliser wraps each drop in frontmatter and moves it to inbox/; /triage-inbox routes them from there. scripts/audiopen-ingest.sh — 80-line bash normaliser. Idempotent; safe to re-run. Extracts title, slugifies, computes capture timestamp from mtime, rewrites with fleeting-note frontmatter. scripts/audiopen-webhook/main.py — stdlib-only Python HTTP server. Zero pip deps; binds to 127.0.0.1 by default. Accepts flexible payload shapes (title/name + body/output/summary/polished/ orig_transcript) so AudioPen version drift is logged rather than silently dropped. scripts/audiopen-webhook/*.example — systemd user-unit templates for the receiver and the path/service pair that fires the ingest wrapper on inbox/raw/ changes. scripts/pyproject.toml + README.md — Python venv convention. Zero deps today; venv location reserved at scripts/.venv/ (gitignored), manifest at scripts/pyproject.toml, bootstrap documented for both plain pip and uv. Optional-dependencies groups let individual tools pull what they need without bloating the whole env. docs/setup/audiopen.md — full setup guide: generating the shared secret, installing the systemd units, pairing with Tailscale Funnel, configuring AudioPen's webhook, and the IMAP-fallback path for setups that can't run a public-reachable receiver. docs/setup/sync.md — companion guide: Gitea SSH remote (works even with Authentik gating HTTPS), obsidian-git plugin configuration, Syncthing desktop↔phone pairing with the critical .stignore patterns, and the three phone-role tiers so the user can pick Tier 1 / 2 / 3 at their own pace. .gitignore gains **/.venv/, **/venv/, **/__pycache__/, and *.pyc so nobody accidentally commits a materialised environment. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
63 lines
2.6 KiB
Markdown
63 lines
2.6 KiB
Markdown
# scripts/
|
|
|
|
Operational scripts for the PKB. Everything here is side-effectful — writing files,
|
|
running webhooks, ingesting voice notes. Keep it small; anything analytical belongs
|
|
in `.claude/commands/` or in the `mql` CLI.
|
|
|
|
## Current contents
|
|
|
|
| Path | Language | Purpose |
|
|
|---|---|---|
|
|
| `audiopen-ingest.sh` | bash | Normalises raw AudioPen drops (`inbox/raw/*.md`) into properly-frontmattered fleeting notes in `inbox/`. Idempotent. |
|
|
| `audiopen-webhook/main.py` | Python (stdlib) | Tiny HTTP server that receives AudioPen webhook POSTs and writes to `inbox/raw/`. Designed to sit behind Tailscale Funnel. |
|
|
| `audiopen-webhook/*.example` | systemd | User-unit examples for the receiver + the path/service that runs `audiopen-ingest.sh` on file change. |
|
|
|
|
Setup guide for the full pipeline: [`docs/setup/audiopen.md`](../docs/setup/audiopen.md).
|
|
|
|
## Python venv convention
|
|
|
|
Python code in this repo is **stdlib-only as of now**. No pip-installable dependencies.
|
|
If/when a real dependency arrives (e.g. `watchdog`, `imap-tools`, anything heavier
|
|
than stdlib), the convention is:
|
|
|
|
- Venv lives at **`scripts/.venv/`** (gitignored — every user materialises locally).
|
|
- Dependencies tracked in **`scripts/pyproject.toml`** (committed).
|
|
- Bootstrap on a fresh machine:
|
|
|
|
```sh
|
|
cd scripts
|
|
python3 -m venv .venv
|
|
.venv/bin/pip install -e .
|
|
```
|
|
|
|
Or with `uv` (recommended if available):
|
|
|
|
```sh
|
|
cd scripts
|
|
uv venv
|
|
uv pip install -e .
|
|
```
|
|
|
|
- Scripts that need the venv should either:
|
|
- Invoke `scripts/.venv/bin/python3` explicitly in their shebang or systemd `ExecStart`.
|
|
- Or document activation (`source scripts/.venv/bin/activate`) before running.
|
|
|
|
Keeping the venv under `scripts/` rather than the repo root keeps the Obsidian file
|
|
tree uncluttered — `scripts/` is already excluded from Obsidian's index
|
|
(`userIgnoreFilters` in `.obsidian/app.json`) so nothing Python-related will ever
|
|
show in the graph or search.
|
|
|
|
**Don't create the venv preemptively.** When the first dependency lands, that's when
|
|
you create it. Keeps the repo lighter and avoids stale venv directories.
|
|
|
|
The `pyproject.toml` uses `[project.optional-dependencies]` to split deps by tool
|
|
— e.g. `pip install -e .[imap]` installs only the IMAP fetcher's deps. This lets
|
|
the webhook receiver stay dep-free while heavier tools can pull in what they need.
|
|
|
|
## Shell scripts
|
|
|
|
Kept in plain bash. Portable to any Linux running GNU coreutils (which Bazzite does).
|
|
No zsh-isms, no bashisms beyond `set -euo pipefail` and arrays. If a script grows
|
|
past ~200 lines or needs real argument parsing, rewrite it in Python (and you're now
|
|
back in the venv convention above).
|