3 Commits

Author SHA1 Message Date
Keysat b5a066750a Live-reload Gemini API key config + fix vendor module resolution
Two related changes that ship together because the second was uncovered
while testing the first.

1. Live config reload (the ostensible feature):

   The "Set Gemini API Key" StartOS action writes to /data/config/
   startos-config.json. The server used to read that file once at
   startup (and via a separate Python read in docker_entrypoint.sh
   before that), which meant a key change required a service restart
   to take effect. Now the server polls the file every 3 s
   (RECAP_CONFIG_POLL_MS, env-overridable) and updates serverApiKey
   in place. fs.watch was tried first and dropped — it's flaky on
   macOS (FSEvents single-file quirks) and behaves inconsistently with
   atomic-rename writes the SDK file model uses. Polling is dead
   simple and a stat call every 3 s is free.

   Also dropped the Python config read from docker_entrypoint.sh; the
   server now handles it natively. Entrypoint still loads /data/.env
   for arbitrary env vars (RECAP_*, etc.).

2. Vendor module resolution (the silently-broken thing):

   The earlier vendor change (move @keysat/licensing-client from a
   git+https dep to a file: dep at vendor/) created a symlink in
   server/node_modules. That symlink to the vendor dir was getting
   resolved by Node, so the keysat client tried to import @noble/
   ed25519 from /app/vendor/keysat-licensing-client/dist/, walked up
   to /app/vendor/, then /app/, neither of which had node_modules.

   Result: v0.2.0 and v0.2.1 would crash at startup with
   ERR_MODULE_NOT_FOUND on @noble/ed25519. The Docker BUILD succeeded
   because npm install with file: deps doesn't pull transitive deps
   into the parent node_modules — but the runtime would have failed
   the moment server/license.js ran.

   Fix:
     • Dockerfile builder now `npm install`s inside vendor/keysat-
       licensing-client/ so @noble/* lands in its own node_modules,
       where Node's resolver finds it.
     • Dockerfile runner now COPYs vendor/ to the runner image
       (previously not copied — the symlink in server/node_modules
       would have pointed at nothing).
     • vendor/keysat-licensing-client/package-lock.json is committed
       so the in-Docker install is reproducible.
2026-05-08 16:38:33 -05:00
Keysat 9282440143 Rename project: youtube-summarizer → recap
The product was always more than YouTube — it handles podcast feeds
too, and the upcoming multi-provider work makes it less Gemini-
specific. New name: Recap.

This is a coordinated identity change across:

  • StartOS package id: youtube-summarizer → recap
    (manifest.id; the .s9pk filename, Docker image namespace, and
    install path under StartOS all derive from this automatically)
  • Display name: "YouTube Summarizer" → "Recap"
    (manifest title, activation screen heading, page <title>, console
    log on boot, i18n strings, ABOUT.md, Dockerfile header,
    docker_entrypoint banner)
  • Keysat product slug: youtube-summarizer → recap
    (server/license.js PRODUCT_SLUG; frontend fallback strings)
  • Daemon subscription id: youtube-summarizer-sub → recap-sub
  • Env var prefix: YT_SUMMARIZER_* → RECAP_*
    (LICENSE_KEY, LICENSE_KEY_PATH, MAX_OFFLINE_DAYS,
    VALIDATE_INTERVAL_MS)
  • localStorage keys: yt-summarizer-* → recap-*
    (gemini-key, activation-skipped, clips)
  • Library export filename: youtube-summarizer-library.json →
    recap-library.json
  • npm package names: youtube-summarizer-{startos,server} → recap-*
  • Deploy paths: youtube-summarizer_x86_64.s9pk → recap_x86_64.s9pk
    (default values in bin/deploy.sh; .deploy.env on dev machine
    needs the same update before next push)
  • Self-hosted registry directory: startos-registry/packages/
    youtube-summarizer → .../recap (with package.json + INSTRUCTIONS
    rewritten)

What does NOT change:
  • Filesystem repo path (still /Users/.../youtube-summarizer/)
  • Git history / commit messages
  • Existing version files in startos/versions/ (kept as-is — the
    version chain belongs to the package's own history regardless of
    its display name)

User-side follow-ups required:
  1. Create "recap" product in Keysat admin, set up Core/Pro tier
     policies (same entitlements as before), mint a fresh test
     license. Old "youtube-summarizer" licenses won't activate
     against the new slug.
  2. Update .deploy.env (gitignored) so FILEBROWSER_PATH and
     REGISTRY_PUBLIC_URL point at recap_x86_64.s9pk.

StartOS will treat this as a brand-new app on install — existing
youtube-summarizer installs will not auto-migrate (acknowledged
intentional given no real users yet).
2026-05-08 13:35:27 -05:00
MacPro 68ec875ee7 Add StartOS 0.4.0 packaging 2026-04-09 15:03:31 -05:00