Skip to content

Latest commit

 

History

History
107 lines (71 loc) · 5.33 KB

AGENTS.md

File metadata and controls

107 lines (71 loc) · 5.33 KB

cryptly — notes for coding agents

About the project

Cryptly is a zero-knowledge, end-to-end encrypted secrets management platform (see cryptly.dev / github.com/cryptly-dev/cryptly). Teams use it to store API keys, credentials, and other secrets, share them with collaborators, track version history, and sync to GitHub.

The core promise is that the server never sees plaintext secrets or private keys. All encryption happens client-side: user RSA-OAEP key pairs are generated in the browser, the private key is encrypted with a user passphrase before it ever leaves the device, and per-project symmetric keys are wrapped with the user's public key. Sharing (invitation links, direct invites) is built on top of these primitives without ever exposing plaintext to the backend.

Security is the product

Because the whole value proposition is cryptographic, security bugs are product bugs of the highest severity. When working on anything that touches crypto, key storage, invitations, auth, or anything that could leak plaintext / keys / passphrases to the server or to logs:

  • Be extra careful and explicit about what is encrypted, where, and with which key.
  • Never add logging, telemetry, or error messages that could expose plaintext secrets, passphrases, private keys, or symmetric project keys.
  • Never move decryption to the server or send unwrapped keys to it, even "temporarily".
  • If something feels off about a crypto flow, stop and flag it rather than papering over it.

Commands

This section tells coding agents exactly which commands to run to verify changes. Do not improvise other commands (tsc -b, nest build --watch, ad-hoc jest invocations, etc.) — use only what's listed here.

Backend (backend/)

Two commands are all you need. Run them at the very end, once you're done editing, not iteratively while working.

# From backend/
pnpm test              # full jest suite
pnpm build             # nest build (compile check)
  • To narrow the test run, pass a filter flag, e.g. pnpm test invitations or pnpm test -- --testPathPattern=device-flow. Jest flags after -- are forwarded.
  • pnpm test already runs with --runInBand --forceExit; don't second-guess those.
  • If both test and build pass, the backend change is verified. There is no separate typecheck step.

Frontend (frontend/)

One command. Run it at the very end.

# From frontend/
pnpm build
  • pnpm build chains tsc -b && vite build, so it is the typecheck. Do not run tsc on its own.
  • There is no frontend test suite. Do not add one unless explicitly asked.

Web (apps/web/)

Two commands. Run them at the very end.

# From apps/web/
pnpm check             # svelte-kit sync + svelte-check
pnpm build             # vite build using the Cloudflare adapter
  • pnpm check is the typecheck for the SvelteKit app.
  • pnpm build verifies the Cloudflare Workers output.
  • Production (cryptly.dev) is served by Vercel: frontend/vercel.json builds apps/web with adapter-vercel (selected when VERCEL=1).
  • Public env is inlined at build time; production values live in apps/web/.env.production.
  • Analytics: Logdash, served first-party by apps/web/src/routes/_ld. Use track / identify from $lib/analytics/logdash. Never put emails, names, user IDs or other personal data in event names or props; add new dynamic routes to PATH_TEMPLATES in _ld/events/+server.ts.

Backend SDK (packages/backend-sdk/)

apps/web and cli talk to the backend only through this typed client, generated from the backend's OpenAPI document.

# From the repo root, after changing any backend controller or DTO
pnpm generate:backend-sdk
  • Commit the regenerated openapi.json and src/openapi.generated.ts. CI fails when they are stale.
  • Declare response bodies with @ApiOkResponse / @ApiCreatedResponse (matching the real status code), not @ApiResponse. Untyped default responses leave the SDK response type empty.

CLI (cli/)

# From cli/
pnpm test              # vitest run
pnpm build             # tsc --noEmit && tsup
  • pnpm build chains the typecheck into the bundle step. Do not run tsc on its own.
  • Both should pass at the end.

Releasing the CLI

After a change you want shipped to npm:

  1. From cli/, run pnpm changeset and describe the change (pick patch / minor / major).
  2. Commit the generated .changeset/*.md (repo root) alongside your code change.
  3. Merge to main. The cli-release workflow auto-bumps cli/package.json, commits the bump back to main, and publishes @cryptly/cli to npm in one run.

If you don't add a changeset, nothing publishes — the change just sits on main until someone bundles a changeset with it.

Package manager

This repo is a single pnpm workspace.

  • The root pnpm-workspace.yaml includes backend, cli, frontend, apps/*, and packages/*.
  • The root pnpm-lock.yaml is the only lockfile. Run pnpm install from the repo root; never add per-package lockfiles.
  • The backend Docker image is built from the repo root (docker build -f backend/Dockerfile .).

Repo shorthand

  • cm: commit and push only changes in files you made to the current branch, using the gh CLI for the push flow where relevant. Do not include unrelated user changes.