Commit Graph
129 Commits
Author SHA1 Message Date
inference-bot d099d31f6a Cream page background end-to-end: Dockerfile PWA colors, README, verify block
Follow-up to the custom.css/custom2.js change: the Dockerfile seds the web
manifest theme_color/background_color and the index.html light meta to
#eaf3ea, and the README's verify block asserted the green wash as correct
("an earlier version of this block asserted cream ... would have led you to
fix a correct deploy"). Both are the same regression: the wash was rejected
earlier, restored by accident, and then documented as intended.

- Dockerfile: manifest + index meta -> #faf8f5 (cream), with an explicit
  "keep these three in sync" note (this sed, custom.css html:not(.dark),
  custom2.js COOP_BG.light).
- README verify block: asserts cream again, plus a new step for the
  install-time colors no DOM check covers (manifest + light meta).
- README palette section: hover is #f0ede6 not the wash; --presentation is
  cream; source of truth is the DEPLOYED CSS of dashboard/portal/panel, with
  the read command; records the shared 4.32:1 / 3.93:1 accessibility caveat;
  notes that cloudron exec silently swallows multi-line sh -c.
2026-10-27 21:59:25 +00:00
inference-bot 3d03a80651 Light theme: cream page background and warm neutrals, matching the dashboard
v3 used the green wash #eaf3ea for --surface-primary, the page background,
which read as too green. Replaced with the palette read from the DEPLOYED
CSS of the dashboard, portal and panel (identical across all three):

  --surface-primary  #eaf3ea -> #faf8f5 (cream, page background)
  --surface-tertiary green   -> #f4f2ec (warm chip)
  --surface-hover    green   -> #f0ede6 (warm hover)
  --surface-composer-hover   -> #f0ede6
  --border-light     #cde0cb -> #e4e0d8 (warm neutral border)
  --presentation     #eaf3ea -> #faf8f5 (composer band)
  --link             #4a7a4a -> #4e7a4d (deeper green, 4.70:1 on cream)

Accents are unchanged (green-deep #5b8c5a, green-mid #6ba86b) — they are
the earthy greens the co-op design system already uses. Dark mode is
untouched. Also fixed the two hard-coded washes: the #loading-container
flash and the bare html/body background, plus custom2.js COOP_BG.light,
which was still painting the browser/PWA chrome #eaf3ea while the
manifest said cream.
2026-10-27 21:58:30 +00:00
inference-admin aca430cea6 release.sh: retry served-HTML checks during the post-deploy container swap
A fetch seconds after 'App is updated' can come back empty while the container
recreates, which false-negatived the x-coop-build check on the 1.4.5 deploy
(2026-10-26). http_body retries 3x before declaring failure.
2026-10-26 03:31:38 +00:00
inference-admin 91b274969b Pin manifest to 20261026-60ee597 2026-10-26 03:27:57 +00:00
inference-bot 60ee597792 Merge pull request 'Bump the appstore pin to 1.4.5 (uv 0.13.5)' (#3) from feat/appstore-1.4.5 into master 2026-10-26 03:25:23 +00:00
inference-admin f195f4509b Pin manifest to 20261026-13f2b3a 2026-10-26 03:24:17 +00:00
inference-bot 13f2b3a857 Merge pull request 'Run the per-member key seed from the image, not the volume' (#2) from feat/keysync-script-in-image into master 2026-10-26 03:20:59 +00:00
inference-admin bcc85709f6 release.sh: fix the builder-login detection (info output is multiline) 2026-10-26 02:13:48 +00:00
inference-admin cb7661dde6 release.sh: also accept a registry app password from the env
REGISTRY_BUILD_TOKEN (+ optional REGISTRY_BUILD_USERNAME) lets a build run from
any host with the token in its environment, no ~/.cloudron.json builder config
required. The narrow credential (app password scoped to the registry app) is the
least-privileged way to hand a host build rights; with no token and no builder
config the script prints both bootstrap routes and exits instead of guessing.
2026-10-26 02:13:28 +00:00
inference-admin b657030d24 release.sh: correct the build prerequisites (builds are remote, not docker-local)
I had it wrong: `cloudron builder build` uploads the build context and the
registry app's BuildKit builds it — the caller needs no docker, only a registry
login. The guard now checks for that login and prints both bootstrap routes
(narrow app password scoped to the registry app, or the CLI device flow) instead
of blaming a missing docker binary.
2026-10-26 01:39:38 +00:00
inference-admin 2357d5d55a release.sh: refuse to pin from a non-master branch (the pin commit lands on master) 2026-10-26 01:39:15 +00:00
inference-admin 8f9d6a1e20 Stage: bump the appstore pin to 1.4.5 (uv 0.13.5, LibreChat unchanged at 0.8.8)
Not deployed. Diffed against the official 1.4.5 manifest: version, changelog and
the base-image tag were the only differences, so this copy now matches official
field-for-field except dockerImage (+ our scheduler block).

The risk is the overlay, not the bump: every build-time patch runs against a new
base layer, and they are all non-fatal by design, so a silent no-op is the failure
mode. Verify on the rendered DOM. Rollback = repoint dockerImage to
20261023-65a38bb.
2026-10-26 01:36:11 +00:00
inference-admin 0102c1790f Stage: run the per-member key seed from the image, not the volume
Ready to build, not yet deployed — deploying the repointed scheduler command
without the new image would break the seed on schedule, which is why this sits on
a branch with the ordering written down.

- Dockerfile: COPY sync-keys.js /app/code/sync-keys.js; rule 3 in the header now
  states the one exception (operational scripts that must not depend on a volume).
- CloudronManifest.json: scheduler command repointed to /app/code/sync-keys.js.
- README: ordering (build -> deploy -> verify -> delete the volume copy), and the
  table row moved from the volume layer to the image layer.

After deploy: delete /app/data/sync-keys.js, but keep it until you are past the
rollback window — the previous image tag still runs the volume copy.
2026-10-26 01:35:06 +00:00
inference-admin bb2503bb47 Add release.sh; make the verify block honest; print the seed script's own revision
Three drifts between this repo and reality, found while moving the per-member key
seed into the app:

- The 'verify after every image deploy' block asserted the CREAM palette
  (rgb(250,248,245)). The deployed palette has been the green wash
  (rgb(234,243,234) with white text areas) for some time, so a correct deploy
  would have read as a failure — and invited someone to 'fix' the CSS back.
- The block still verified against librechat-test.inference.coop; the swap to
  chat.inference.coop happened 2026-10-21 and that alias is not provisioned.
- Nothing checked that the scheduler task's script exists in the running image,
  which is exactly the failure mode a manifest repoint can introduce.

release.sh encodes the documented release flow (dirty-tree guard, always
--no-cache, pin-before-deploy) and its verify subcommand runs checks 1-5 plus the
seed task's log lines. sync-keys.js now prints its own md5 prefix on every run,
so a stale volume copy can never hide again — the repo copy's md5 is the
authority.

Verified: ./release.sh verify passes all six checks against the live app;
./release.sh volume sync-keys.js confirms md5 parity.
2026-10-26 01:34:22 +00:00
inference-admin 2d66ea212d README: document the in-app key-sync scheduling, the creds file, and the fail-closed guards 2026-10-25 22:44:34 +00:00
inference-admin e544dc4a11 key sync: read CREDS_KEY/CREDS_IV from the volume, add a failure diagnostic
The first scheduled run failed closed (good) — Cloudron's scheduler addon runs
each task in its OWN container, so the app's process env is absent there and
/proc/1/environ belongs to the task launcher, not to LibreChat. CREDS_KEY/CREDS_IV
now come from /app/data/.librechat-creds (root:cloudron 0640), written from the
live app env; a stale key makes the decrypt-against-existing-rows guard refuse to
write rather than corrupt member keys. Credential failure now also writes
/app/data/key-sync-diag.txt so a future failure explains itself.

Verified: the 22:40 scheduled fire logged 'creds check: decrypt-ok (25 existing
row(s))' / 'done: 50 seeded, 15 skipped'.
2026-10-25 22:42:13 +00:00
inference-admin 4e28b7a612 Key sync runs inside the app: scheduler addon task every 10 min, plus write guards
The per-member key seed ran from a steward cron on the co-op agent VM, shelling
into this app over the Cloudron API. That made a member-facing function depend on
a separate machine's uptime and paths (it went silently stale once, exiting 127
on schedule while the job looked healthy).

- CloudronManifest.json: addons.scheduler gains librechat_key_sync
  (cd /app/code/librechat/api && node /app/data/sync-keys.js, */10 * * * *).
  Official addon set (postgresql, mongodb, localstorage, oidc, sendmail) and the
  dockerImage pin are untouched.
- sync-keys.js: refuse to write unless CREDS_KEY can first decrypt an existing
  key row, and unless each fresh ciphertext round-trips back to the plaintext.
  Scheduled runs get a different environment than an interactive exec, so a wrong
  or absent CREDS_KEY must fail loudly instead of overwriting working member keys.
2026-10-25 22:25:10 +00:00
Nathan Schneider f7a4fdb48d modelSpecs: webSearch default ON for all 8 specs (new conversations start with web search active; per-conversation toggle still wins) 2026-10-23 11:25:22 -06:00
Nathan Schneider 22f9422259 Pin manifest to 20261023-65a38bb 2026-10-23 11:11:45 -06:00
Nathan Schneider 65a38bbccd logguard: explicit stdout/stderr paths — supervisord's auto-named childlog dir crashes it 2026-10-23 11:11:08 -06:00
Nathan Schneider 10b63c9454 Pin manifest to 20261023-515c92c 2026-10-23 11:02:42 -06:00
Nathan Schneider 515c92c403 log-guard: root supervisord program keeps dated log files cloudron-owned
A host-side daily job creates the next day's dated log files as root:root at
00:00 UTC; LibreChat (cloudron user) then EACCES-crashes on its first log
write of the day (2026-10-22 and 2026-10-23 incidents). The guard pre-creates
today's and tomorrow's files as cloudron and repairs strays every minute.
Defense-in-depth until the host rotation config is fixed.
2026-10-23 10:57:25 -06:00
Nathan Schneider a21f496de2 README: PWA deploy lessons (stale COPY layer, icon cache-busting, maskable safe zone, Firefox crossorigin, theme bars) 2026-10-22 13:35:57 -06:00
Nathan Schneider 7e94135bc5 Pin manifest to 20261022-17e7c92 2026-10-22 13:32:33 -06:00
Nathan Schneider 17e7c92ece manifest icons: per-build version query — PWA icon URLs are cached 48h by the phone and remove/re-add does not clear that cache, so launchers kept rendering the previous build's icon bytes 2026-10-22 13:32:05 -06:00
Nathan Schneider 077e6141b3 Pin manifest to 20261022-4a2b9c1 (no-cache rebuild — stale COPY layer shipped the old maskable icon) 2026-10-22 12:31:00 -06:00
Nathan Schneider df55d7fafa PWA fixes: padded maskable icon (launcher crop), edge-to-edge bands, Firefox manifest fetch
- maskable-icon.png regenerated: logo at ~66% on the brand background —
  inside the maskable safe zone, so Android no longer crops it ('zoomed in').
- index.html: viewport-fit=cover + manifest link without
  crossorigin=use-credentials (Firefox Android fails to resolve manifest
  icons on credentialed fetches — missing launcher icon).
- custom.css: standalone-mode safe-area padding so app content clears the
  system bars; the bands show the theme-correct page background.
2026-10-21 22:16:29 -06:00
Nathan Schneider 637fcc3472 Pin manifest to 20261022-d86483e 2026-10-21 21:07:23 -06:00
Nathan Schneider d86483e5a1 restore green-wash theme (lost in the Oct 21 rebuild) + PWA band colors
The Oct 19 theming (light = #eaf3ea dashboard green wash, white cards/surfaces,
per approval) was never committed - the Oct 21 pin-migration rebuild from this
repo silently reverted the deployed theme to the older cream iteration.

- custom.css: light block restored to the approved green-wash palette
  (primary #eaf3ea, white secondary/chat cards, green hover/tertiary/border);
  loading screen + bare page background match.
- Dockerfile: manifest theme_color/background_color and the index.html
  theme-color media pair now follow the live palette (#eaf3ea light /
  #22271f deep pine dark).
- custom2.js: sync ONE meta theme-color to the app's resolved theme
  (html.dark class + prefers-color-scheme listener) so Android status/nav
  bands and iOS safe areas track the theme at runtime; the static media
  pair remains as the no-JS fallback.
2026-10-21 20:46:45 -06:00
Nathan Schneider 7eb13856d7 Pin manifest to 20261021-c2c674a 2026-10-20 22:29:25 -06:00
Nathan Schneider c2c674a83e favicon.ico also at dist root (/favicon.ico) 2026-10-20 22:29:17 -06:00
Nathan Schneider 2767536d1f Pin manifest to 20261021-db2dbe3 2026-10-20 22:27:31 -06:00
Nathan Schneider db2dbe3016 assets: add favicon.ico (48/32/16 from the 192 icon) — some Android icon-resolution flows request it; was 404 2026-10-20 22:27:22 -06:00
Nathan Schneider 28790d2fe7 Pin manifest to 20261021-c47c311 2026-10-20 22:21:10 -06:00
Nathan Schneider c47c311873 manifest icons: explicit any/maskable entries (no dual-purpose value — Firefox Android quirk), launcher sizes first 2026-10-20 22:21:00 -06:00
Nathan Schneider 0560c6e26b Pin manifest to 20261021-7e1de2f 2026-10-20 22:12:17 -06:00
Nathan Schneider 7e1de2f99b sw.js: per-build stamp — every deploy changes the service worker bytes so browsers update the worker and re-precache current content (manifest identity, index.html) 2026-10-20 22:11:41 -06:00
Nathan Schneider 6a6f8b4103 Pin manifest to 20261021-dcd7486 2026-10-20 21:57:03 -06:00
Nathan Schneider dcd7486415 patch_index: PWA identity — manifest name/short_name 'Inference Co-op'/'Inference', description, 512 icon purpose any+maskable (fixes generic Android icon + LibreChat label) 2026-10-20 21:56:42 -06:00
Nathan Schneider 04b217b306 Pin manifest to 20261020-0468562 2026-10-20 13:45:58 -06:00
Nathan Schneider 0468562aa0 index.html branding via patch_index.py + per-build x-coop-build marker (SW self-heal); replaces fragile sed chain 2026-10-20 13:45:33 -06:00
Nathan Schneider 4b534fcaa2 Dockerfile: stamp a unique x-coop-build meta into index.html every build — forces the service worker precache to update so stale clients self-heal on deploy 2026-10-20 13:44:37 -06:00
Nathan Schneider 3b706eed74 Pin manifest to 20261020-1594a60 2026-10-20 13:41:03 -06:00
Nathan Schneider 1594a60bac custom2.js: one-time pin migration — clear artifact PIN_MCP_/LAST_WEB_SEARCH_TOGGLE_pinned=false so corrected defaultPinnedTools applies to existing sessions 2026-10-20 13:40:27 -06:00
Nathan Schneider 94a0ee9614 defaultPinnedTools: include 'mcp' — omitting it unpins the Tools button itself (client seed sets PIN_MCP_=false) 2026-10-20 12:10:44 -06:00
Nathan Schneider f16ffe1fc4 interface.defaultPinnedTools: [web_search] — pin the Web Search badge next to Tools in the composer 2026-10-20 11:38:23 -06:00
Nathan Schneider 5864741233 Pin manifest to e9850d7 2026-10-19 21:43:56 -06:00
Nathan Schneider e9850d7148 PWA manifest sed: minified JSON has no space after colon — make match spacing-agnostic 2026-10-19 21:43:48 -06:00
Nathan Schneider 289ab2f9ff Pin manifest to 8abdc95 2026-10-19 21:41:48 -06:00
Nathan Schneider 8abdc95803 PWA chrome: manifest theme_color #009688 teal -> cream #faf8f5, background black -> cream; index.html theme-color light/dark pair; html/body bg matches theme (fixes green top bar + white bottom bar in Firefox PWA) 2026-10-19 21:41:31 -06:00