Commit Graph
161 Commits
Author SHA1 Message Date
Gabriel Brown 348c2d3d62 feat: add PostHog, move Plausible to v4, and drop Sentry session replay
Build and Deploy Spoon / quality (push) Successful in 1m40s
Build and Deploy Spoon / build-images (push) Successful in 12m23s
PostHog loads after the page is idle through a same-origin /ingest proxy and follows the signed-in Convex user. Plausible uses the per-site script through a /pa proxy. Sentry keeps errors and traces only. Pages load only the @spoon/ui modules they import, and client code reads public env from publicEnv.ts so zod stays out of the browser. Both analytics integrations stay off until their env is set in Infisical prod.
2026-10-01 17:17:21 -04:00
Gabriel Brown 587fa0fdcd chore: pin the dependencies that floated on latest
Build and Deploy Spoon / quality (push) Successful in 1m45s
Build and Deploy Spoon / build-images (push) Successful in 15m38s
Five dependencies used "latest", so every upstream release changed the resolution and CI's frozen install refused the lockfile. They now use ranges around the versions already locked and deployed, so nothing changes at runtime.
2026-10-01 15:45:15 -04:00
Gabriel Brown 26a4fd0705 ci: read the production env from Infisical and deploy on push
Build and Deploy Spoon / quality (push) Failing after 9s
Build and Deploy Spoon / build-images (push) Skipped
Each job logs in as the read-only spoon-ci machine identity and exports the Infisical prod environment, so production values no longer live in Gitea. After pushing the images, CI asks the VPS to redeploy podman-spoon.service over the forced-command deploy key, with the key passed through env so the printed script never contains it. Installs survive a half-written runner cache, and one production deploy runs at a time.

Infisical prod carries a valid JWKS; the copy in DOTENV_PROD had escaped quotes, so the Convex env sync had been serving invalid JSON at /.well-known/jwks.json. The first sync from Infisical replaces it.
2026-10-01 15:39:23 -04:00
Gabriel Brown 919d185a85 Merge feat/box-user: non-root box user + settable password
Build and Push Spoon Images / quality (push) Successful in 1m57s
Build and Push Spoon Images / build-images (push) Successful in 9m52s
2026-07-13 11:38:29 -04:00
Gabriel Brown 4505471149 fix(worker): keep-id compat, zombie tmux clients, nvm in box image
- Box init + chownInBox exec explicitly as root: under podman keep-id the
  container's default user is the mapped uid, which cannot useradd/chown.
- Init renames an existing uid-1000 passwd entry (podman keep-id injects one
  named after the HOST user) instead of adding a duplicate that would win the
  getpwuid lookup and make whoami report the wrong name.
- Terminal connections tag their shell with a per-connection marker and reap
  the process group on WebSocket close: closing the attach socket never
  killed the exec'd shell, so every disconnect leaked an attached tmux client
  (session stuck at the smallest zombie's size; enough dead clients starve
  tmux rendering for live ones).
- Job image: nvm 0.39.5 at /usr/local/nvm (user-writable) with
  /etc/profile.d/nvm.sh, matching what user dotfiles expect; docs for the box
  user + ownership model.
2026-07-13 10:36:44 -04:00
Gabriel Brown 028fbebcd6 feat(next): box user card on /machine 2026-07-13 10:11:11 -04:00
Gabriel Brown 134bab93a5 feat(next): box password API 2026-07-13 10:08:48 -04:00
Gabriel Brown 78aae034b5 feat(worker): live box password apply route 2026-07-13 10:07:06 -04:00
Gabriel Brown 58bd101793 feat(worker): run terminals and agent turns as the box user 2026-07-13 10:04:14 -04:00
Gabriel Brown a956d63e16 feat(backend): boxSettings table + box password actions 2026-07-13 09:56:08 -04:00
Gabriel Brown 37a82098c2 feat(worker): exec-as-user, stdin input, chown + userns plumbing 2026-07-13 09:52:45 -04:00
Gabriel Brown 78cb3d90c2 feat(worker): box-user script builders + username sanitizer 2026-07-13 09:49:59 -04:00
Gabriel Brown a91c8551ac docs: box user implementation plan 2026-07-13 09:48:25 -04:00
Gabriel Brown aea2aa2c5c docs: box user design spec (non-root box + user-set password) 2026-07-12 22:42:32 -04:00
Gabriel Brown b038a31520 fix(box): bump job image base to Fedora 44 for Neovim 0.12
fedora:41 ships Neovim 0.10.4, below LazyVim's >= 0.11 requirement, so
dotfiles-managed editors failed inside the box. F44 ships 0.12.4.
2026-07-12 22:26:45 -04:00
Gabriel Brown a640b5cb94 fix(terminal): bun-safe exec attach, box self-heal, surfaced errors
The workspace terminal died everywhere: bun's node:http client never
emits the client 'upgrade' event (it surfaces the 101 as a plain
response), so docker-modem's exec.start({hijack:true}) waited forever —
a connected WebSocket with no bytes flowing (prod), or an instant close
when the socket was unreachable (dev). The pre-Phase-1 bridge avoided
dockerode attach for exactly this reason; the real-TTY-resize rewrite
reintroduced it.

- runtime/exec-stream.ts: speak the exec-start HTTP upgrade over a raw
  net socket (docker and podman both answer 101 UPGRADED). Works under
  bun and node; honors the modem's socketPath/host:port. The stream is
  returned paused so the first screen paint can't race the caller's
  data handler. Exec create/resize stay on dockerode (plain POSTs).
- user-container.ts: acquireUserBox re-ensures the container on every
  acquire instead of trusting a cached "initialized" flag, so a box
  removed behind the worker's back (manual rm, another instance's
  reaper) is recreated instead of bricking terminals and agent turns
  until restart.
- terminal.ts: bridge failures are logged and close the WebSocket with
  a clamped human-readable reason instead of a silent catch;
  xterm-session.tsx displays that reason instead of a mute
  "Session ended". Also roomier terminal line spacing (1.2 -> 1.35).
2026-07-12 22:14:37 -04:00
Gabriel Brown c0dd8759af fix(expo): support anthropic_oauth_json auth type in provider form
Build and Push Spoon Images / quality (push) Successful in 2m29s
Build and Push Spoon Images / build-images (push) Successful in 8m44s
The backend aiProviderProfiles authType union added 'anthropic_oauth_json'
but the Expo provider form's local AuthType type was stale, breaking
typecheck. Add the literal, a picker option, help text, and multiline
handling to match the Next app.

Claude-Session: https://claude.ai/code/session_01ScyZ1NhfN84LAnHpwhfEQk
2026-07-12 12:09:33 -04:00
Gabriel Brown ed88478ce6 Merge codex/spoon-stabilize-unify-build: 5-phase stabilize/unify/build (65 tasks)
Phases 1-5 complete: stabilization criticals, runtime unification (codex/opencode/claude
in per-user box), dev-box /machine surface, GitHub sync correctness + webhooks,
notifications + polish. Final whole-branch review passed; all packages green.
2026-07-12 02:53:40 -04:00
Gabriel Brown a255a06a35 docs: rewrite for box-first model + webhooks + notifications 2026-07-11 18:23:49 -04:00
Gabriel Brown 1fbb2dd0a1 chore: remove dead routes/components + fix redact/env cleanup 2026-07-11 18:11:22 -04:00
Gabriel Brown f89dfce3b8 fix(workspace): scroll/diff-race/recovery/editor/mobile polish 2026-07-11 17:59:25 -04:00
Gabriel Brown b00141130c fix(a11y): remove nested-interactive role='link' on spoon/thread lists 2026-07-11 17:42:33 -04:00
Gabriel Brown cc241c8bbf fix(ui): profile page directive + avatar dropdown links/fallbacks 2026-07-11 17:32:49 -04:00
Gabriel Brown d873c8eaf7 fix(auth): retain input on failure + copy fixes 2026-07-11 17:23:25 -04:00
Gabriel Brown a3ec04ad99 fix(ui): re-sync settings/thread forms on loaded record 2026-07-11 17:14:06 -04:00
Gabriel Brown bca86196fb fix(ui): error-handle fire-and-forget mutations in settings panels 2026-07-11 16:59:16 -04:00
Gabriel Brown 8c579d060a fix(ui): loading skeletons for dashboard/spoons/threads 2026-07-11 16:50:24 -04:00
Gabriel Brown 8d7486bc8c feat(notifications): settings notification preferences 2026-07-11 16:41:35 -04:00
Gabriel Brown c241941e41 feat(notifications): header notification bell 2026-07-11 16:25:08 -04:00
Gabriel Brown 5776841e2f feat(notifications): inbox query + mark-read mutations 2026-07-11 16:13:42 -04:00
Gabriel Brown 3766a29871 feat(notifications): emit at maintenance/turn/sync/reauth events 2026-07-11 16:08:22 -04:00
Gabriel Brown 4eb0c963ff feat(notifications): add emit helper + UseSend email dispatch 2026-07-11 15:52:26 -04:00
Gabriel Brown 05eabcb0fa feat(notifications): add notifications + notificationPreferences tables 2026-07-11 15:42:14 -04:00
Gabriel Brown 0347d58f71 chore: fix eslint errors introduced in phase 4 backend 2026-07-11 15:37:51 -04:00
Gabriel Brown 75d7592cf3 feat(settings): surface GitHub connection needs_reauth/revoked 2026-07-11 14:49:28 -04:00
Gabriel Brown bce6769277 fix(convex): order spoonCommits by committedAt via index so bounding keeps newest 2026-07-11 14:41:31 -04:00
Gabriel Brown 9067d16734 perf(convex): bound unbounded owner-wide collects on hot paths 2026-07-11 14:41:31 -04:00
Gabriel Brown e4a7f96633 fix(sync): don't misclassify plain 403 auth errors as rate limited 2026-07-11 14:28:02 -04:00
Gabriel Brown 4769a76274 feat(sync): add Octokit retry/throttle and rate-limited status 2026-07-11 14:28:02 -04:00
Gabriel Brown f1dbf8cd50 feat(webhooks): add signature-verified GitHub webhook route 2026-07-11 14:18:55 -04:00
Gabriel Brown 68dc7bb4ee feat(spoons): find owned spoons by pushed repo (indexed) 2026-07-11 14:12:30 -04:00
Gabriel Brown f7c3aa6482 feat(github): index connections by installation + status mutation 2026-07-11 14:07:57 -04:00
Gabriel Brown 18cb424b99 feat(webhooks): add GitHub webhook signature verifier 2026-07-11 14:04:32 -04:00
Gabriel Brown 675d6b2316 fix(sync): use stable dedup key and skip threads when head unresolved 2026-07-11 14:00:16 -04:00
Gabriel Brown 0e894f8e67 refactor(threads): dedup maintenance threads by stable key via index 2026-07-11 14:00:16 -04:00
Gabriel Brown c3f73ac656 feat(sync): add deterministic maintenance-thread dedup key 2026-07-11 13:48:49 -04:00
Gabriel Brown 4684617fed fix(sync): paginate compare and resolve real head SHA 2026-07-11 13:44:10 -04:00
Gabriel Brown c8200a6747 feat(sync): add resolveBranchHead to fetch branch tip SHA 2026-07-11 13:39:36 -04:00
Gabriel Brown 696f03e867 fix(web): /machine terminal visible prop, stop/restart confirmation, accurate waiting label 2026-07-11 13:36:54 -04:00
Gabriel Brown a5bc0434f3 chore: fix eslint errors introduced across phases 1-3 2026-07-11 13:27:23 -04:00