* pwa: read vault values in the browser with a pasted identity key
The web app listed vaults but could never show a value: decryption needs the
member's X25519 secret key, which only lives in identity.json on the machine
that ran `logicsrc login`.
Each vault now has a page (/teams/:slug/vaults/:id, linked from the
dashboard) listing its secret names. Paste the identity key (or the whole
identity.json) and public/vault.js decrypts in the browser with the same
libsodium calls as the CLI: crypto_box_seal_open for the grant, then
crypto_secretbox_open_easy per value. Nothing is sent to the server.
- The pasted key is checked against the public key the server has on file
before use, so a key from another machine is named, not a generic failure.
- Show / Copy per value, Download .env, Forget key. The key is kept in
sessionStorage unless "remember on this device" is ticked.
- A member with no identity yet can create one in the browser. That
registers only the public half, and is offered only when no key is
registered, since replacing one would orphan every grant sealed to it.
- libsodium is served from node_modules at /vendor (no CDN), like simplewebauthn.
- Vault pages are no-store and the service worker no longer caches no-store pages.
- CLI: `logicsrc teams key` prints the secret key to stdout alone (pipe to
pbcopy) and warns when the server holds a different public key. The page
also gives a jq one-liner for CLIs released before this command.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* pwa: rename data-secret to data-key-name
ThreatCrush read data-secret="…" as a hardcoded credential (2 high, both
the attribute name, never a value).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* CLI 0.5.0 for teams key; install via install.sh, not npm
@logicsrc/cli is not on npm; the CLI ships through
curl -fsSL https://logicsrc.com/install.sh | sh, which builds master and
reports the version from packages/cli/package.json. 0.5.0 marks the first
build with teams key, and the vault page now says so and points older
installs at the jq fallback.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* Run on Bun: bun install, bun --bun next, both dev2 sites on Bun
Moves logicsrc.com and app.logicsrc.com (one image) off Node + npm onto Bun,
following the fleet recipe (phonenumbers.bot pilot).
- Package manager: bun.lock migrated from package-lock.json, so every resolved
version is unchanged; packageManager bun@1.4.2. Root scripts run each
workspace with `bun run --cwd <dir>` instead of `npm --workspace`.
- Bun 1.4.2, not the fleet's 1.4.0: 1.4.0 re-resolves this workspace's `file:`
cross-references differently on every install, so its own lockfile never
passes --frozen-lockfile. 1.4.2 is stable on it.
- Runtime: logicsrc-web runs `bun --bun next build/start`; apps/pwa (Express,
app.logicsrc.com) runs `bun src/server.mjs`.
- Image: .nixpacks/Dockerfile (the path both dev2 compose stacks build) is now
a hand-written oven/bun image carrying the whole workspace, run as the
non-root bun user. ENTRYPOINT stays `bash -l -c` so a compose `command:` is
one string, as before; app.logicsrc.com's compose starts it with
"npm --workspace @logicsrc/pwa run start", which .nixpacks/npm (the image's
only `npm`) turns into `bun run start` in apps/pwa. Port 3000, the PUBLIC_URL
build arg and the / health path are unchanged. The nixpacks .nix and
build.sh are gone.
- CI: both workflows install with bun and run every script through bun (Node
stays only as the interpreter for vitest/tsc/node --test/Playwright, as
before), and CI now boots the site under Bun.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* ci: boot check on port 3100 and stop it before Playwright needs 3000
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
* fix(web): keep next dev on port 5174, which Playwright waits on
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Production reads DATABASE_URL (postgres://) through @profullstack/libsql-pg,
which keeps the @libsql/client surface; no query changed. A missing,
non-Postgres or leftover libsql:// URL fails at boot in production. Dev and
tests keep libSQL (file:/:memory:) as a devDependency. Postgres migrations in
src/migrations-pg/ (converted with libsql-pg convert-schema, same file names
so the copied _migrations ledger matches); migrate.mjs picks the dialect.
Tests run against Postgres with PWA_TEST_DATABASE_URL.
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
Adds apps/pwa: an Express + libSQL/Turso app that is now the home of team
credential sharing, with the moshcode-style auth stack ported and reskinned to
match logicsrc.com (light theme, Inter, green accent).
apps/pwa
- auth: email/password (scrypt), passkeys (WebAuthn), CoinPay OAuth, cookie
sessions, and lsk_ API keys for the CLI via a loopback OAuth-PKCE flow
(/cli/authorize + /cli/token). Ported from the moshcode PWA.
- credshare API (/api/credshare/*): teams, members, invites, vaults, sealed
grants, ciphertext secrets, audit — authed by session OR Bearer lsk_ key.
Zero-knowledge: only ciphertext + sealed vault keys + public keys stored.
- teams dashboard, accept-invite, and settings (API keys) pages, server-rendered
in the LogicSRC brand (lib/html.mjs).
- migrations (libSQL) 001_auth + 002_credshare, migrate-on-boot; Turso via
TURSO_DATABASE_URL / TURSO_AUTH_TOKEN, or a local file db for dev.
- trimmed moshcode-specific approvals/credits/push/deliver.
CLI
- `logicsrc login` now does browser loopback OAuth-PKCE against the app and
stores an lsk_ token (email-OTP removed); --token for CI. Client repointed.
Distribution
- install.sh (served at logicsrc.com/install.sh) installs the CLI from the
GitHub repo: tarball -> npm install -> `npm run build:cli` -> logicsrc wrapper.
- root build:cli builds only the CLI's workspace chain (skips web/api/next).
Cleanup
- removed the commandboard-api credshare backend (superseded by the PWA) and its
Supabase/Turso stores + libsql dep; commandboard-api tests green (40).
- removed the Next.js /teams page (the PWA is the web UI now).
Verified end-to-end: two accounts register on the PWA, mint lsk_ keys, CLI login
uploads identity keys, owner pushes an encrypted .env, teammate invited ->
accepted -> granted -> pulls the exact file. Server stores ciphertext only.
Full workspace build + tests green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>