Repository navigation
V2/scaffold - #8
Open
marcelgundermann wants to merge 28 commits into
Open
marcelgundermann wants to merge 28 commits into
marcelgundermann wants to merge 28 commits into
Conversation
Static-assets-only Worker (encryptee-v1) pointing at a local build of the v1 branch. See deploy/v1/README.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
v1 lives on the v1 branch (tag v1.0.0) and is served from v1.encryptee.io. main now holds a pnpm 12 workspace with catalogs, TypeScript 7, Oxlint and oxfmt, and a one-day minimumReleaseAge supply-chain guard. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- age v1 header via typage (Encrypter as header builder, Decrypter.decryptHeader) - parallel STREAM payload: native WebCrypto ChaCha20-Poly1305 when present (Chrome 155+), @noble/ciphers otherwise; byte-identical to typage - coordinator worker + crypto pool wired over MessagePorts by the main thread; sliding window with in-order writes and backpressure - sinks: File System Access, service-worker streaming download, OPFS staging, memory and discard - Job API (subscribe/getSnapshot/cancel/done), wake lock and beforeunload guard - keys: PQ-by-default generation, age identity files, passphrase-protected key files, share links, IndexedDB contacts - Vitest browser tests: CCTV vectors, typage byte-identity, tamper cases, age CLI interop Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds the engine bench page (pnpm --filter @encryptee/engine bench) and its first headless results for Chromium and WebKit. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- tool page on the engine's Job API (functional skeleton until a design prototype is chosen), keys panel with protected key files, share links and contacts - content pages rendered to static HTML at build time, no JavaScript - vite-plugin-pwa injectManifest service worker: precache, SW download route, updates offered only between jobs, /security.json fail-closed check - strict CSP with Trusted Types (default policy for same-origin script URLs) - Playwright E2E against wrangler dev: SW download and OPFS round trips, offline, wrong passphrase, no CSP violations - GitHub Actions: lint, format, typecheck, engine tests with age CLI, E2E - engine: OPFS detection works on the main thread; typage stays in workers so the page bundle carries no crypto library Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Plan step 6. The tool follows the chosen prototype variant A: one drop surface, one centered card per step, oversized monochrome type, the mode inferred from the files' headers. - drop anywhere on the page; encrypt and decrypt cards; a single giant percentage with speed and time left while a job runs; per-file results - passphrases: a generated 10-word passphrase shown in full with copy, or the user's own typed twice; shared by the encrypt and keys screens - people: saved contacts as toggles, pasted public keys validated in the tools worker, share-link keys preselected, PQ/classic mixing warning - decrypt checks the passphrase or key file against the header before the save picker opens, so a wrong one is rejected on the card; if the check outlasts the click's activation, one more click opens the picker - keys: create (post-quantum default), save a protected key file before anything else is shown, open an existing key file, manage people - content pages restyled to match; native radios and <progress> for a11y - engine: checkCredentials (header-only, in the tools worker) and JobSnapshot.updatedAt for throughput Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Copy dmmulroy/anti-slop@13909c9 into tools/oxlint/anti-slop, register it as a JS plugin, and enable all 18 generic rules plus the native oxc/no-accumulating-spread at error. The Effect rules are copied but not registered. Pin @oxlint/plugins to 1.90.0 to match oxlint, and keep agent tooling directories and the vendored plugin out of lint and format. pnpm lint now reports 477 findings in existing source; cleanup follows separately. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Run oxlint --fix for the anti-slop require-readable-spacing rule, which only inserts blank lines between statements (424 lines across 54 files). pnpm lint drops from 477 to 53 findings; the rest need manual fixes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ring Drop the custom prerender Vite plugin. The content pages now mount with React like the tool page, from one entry that picks the page by `#root[data-page]`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Fix the 52 findings left after the spacing autofix; pnpm lint is now clean without disabling any rule. - Type assertions: remove 24 by tightening types instead. The payload key, cipher and batch paths take Uint8Array<ArrayBuffer>, tools-worker messages use named ToolArgs/ToolValue, and pickAndStart takes a per-member Omit so startJob needs no cast. The 10 left (missing DOM typings, RPC correlation, bench element ids) carry SAFETY comments. - unknown inputs: serializeError and errorMessage take `cause`; ByteSink.abort takes a SerializedError. - typeof checks and anonymous return types: replaced with truthiness checks and named Tuning, PassphraseChoice and Expectation types. Behaviour changes: - checkSafety reports `unsafe` when minSafeBuild is not a number (`null` used to pass as `ok`). - errorMessage checks `instanceof EngineError` instead of duck typing. - The bench drops unknown backend names; webcrypto only when native. - vitest.config throws on an unknown BROWSERS name and reads exit codes from child.exitCode. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Replace the 10 remaining casts, so no SAFETY comment is needed. The require-safety-comment-for-type-assertion rule stays enabled. - Missing DOM typings: declare userAgentData, FileSystemHandle.remove() and the `raw-secret` importKey overload via `declare global` next to their use in the engine, and trustedTypes and launchQueue on Window in apps/web/src/env.d.ts. - Service worker: annotate the untyped ExtendableMessageEvent data instead of asserting it. - Tools worker RPC: each call gets its own MessageChannel, so the reply is typed by the tool that was called; the pending map, ids and `worker!` go away. The worker switches on the tool name, which narrows args, and a tool without a case fails to compile. - Bench: `$` checks the element with instanceof, and the scenario is looked up in a const list. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The real wrangler.jsonc files carry the Cloudflare account_id, so they are git-ignored now. wrangler.example.jsonc and deploy/v1/wrangler.example.jsonc are the committed templates; CI copies the root one before the E2E run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
marcelgundermann
force-pushed
the
v2/scaffold
branch
from
October 29, 2026 14:14
54ba608 to
2c5fe3f
Compare
SwDownloadSink (the coordinator's end) moves next to createPortStream (the service worker's end). It only needs MessagePort, so it compiles under both tsconfigs, and the test now pairs the real producer with the real consumer over a MessageChannel instead of a hand-written copy of the producer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
RunningJob now asks the location for an output per file instead of switching on kinds in sinkFor and deliver. Each output carries its sink descriptor and transferables, what to do once the sink is open, how to finish, and what to release on failure; the SW download and OPFS staging kinds own their state. - A failure in any of those steps fails the file as save-failed and stops the job. A missing service worker no longer hangs it, and run() catches everything, so `done` never rejects. - The encrypt header write now honours cancel; before, a download that never granted credit could not be cancelled. - OPFS staging holds a Web Lock per staged file until its download has had time to finish, and sweeps unlocked files before staging. clearStagingArea, which nothing called, is gone. - SaveTarget is now SaveLocation, matching the glossary; FileOutput moves with it, and the OPFS sink reports 'saved' like the others. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
chooseSaveLocation runs straight from the click: it picks the kind for this browser and file count, shows the save or folder picker if there is one, and returns a SaveLocation or why not (dismissed, needs-gesture, unsupported, save-failed). It never throws, and it only picks OPFS staging once getDirectory() actually opens, which WebKit's private sessions refuse. whereToSave says beforehand whether Start will ask where to save. - The cards call chooseSaveLocation and startJob themselves; pickAndStart and asksWhereToSave are gone. Both cards now show save-failed. - chooseSink, detectCapabilities, sizeLimit, SIZE_LIMITS and outputName leave the public interface; preflight works out the save path itself. - The choice is tested through an internal seam with a fake browser: kinds, the picker error mapping, the gesture rule, and refused OPFS. - The bench uses outputName and OPFS_STAGING_DIR instead of copies. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
V2/save location
Vitest 5 writes them to .vitest/attachments/, which .vitest-attachments/ didn't match, so 26 screenshots from engine test runs were committed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Nothing loaded it, and oxlint's react plugin already runs the same rules, React Compiler ones included (react/hooks, exhaustive-deps, purity, refs, immutability, set-state-in-render). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The e2e test listed the pages by hand and skipped the 404 page. PAGES now lives in pages.ts, which vite.config.ts builds from and the test loops over, so a new page is checked once it's built. A path that doesn't exist gets the 404 page through not_found_handling. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
apps/web had no tests and ran Vitest with --passWithNoTests. It now runs them in Node with the app's own Vite config: - classify(), by the files' headers and never their names - checkSafety(), against the security.json this repo deploys, too - errorMessage() - _headers requires Trusted Types and allows exactly the policies trusted-types.ts creates - wrangler.example.jsonc serves the folder Vite builds into CI runs them in the check job. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
pnpm check runs format check, lint, typecheck, Knip and every package's tests: what to run before calling a change done. CI runs Knip in the check job. What Knip found on the first run: - the engine's direct @vitest/browser, which vitest/browser reaches through @vitest/browser-playwright - exports used only in their own file, now unexported, and SNIFF_SIZE and SinkKind, which nothing used - styles.css and with it tailwindcss, since Knip doesn't follow the pages' <link rel=stylesheet>: an entry in knip.jsonc, with why devEngines makes pnpm refuse a Node older than 24 instead of warning. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The commands and the environment variables they take, what to run before calling a change done, the workspace's rules, and the test conventions. The engine's and the app's write down the rules that lived only in lint config, package exports and comments: the engine's two entry points, byte-identity with typage, sw-stream.ts's APIs, the seams tests use instead of mocks, the CSP and Trusted Types, the pages and security.json. Claude Code reads AGENTS.md itself when there's no CLAUDE.md, so there is none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
V2/repo glue
vite-plus 1.4.0 replaces vite, vitest, oxlint, oxfmt and @oxlint/plugins. It bundles the same Vite 8.3.5, Rolldown 1.2.15 and Vitest 5.0.5, so apps/web/dist builds byte-for-byte as before. Oxlint and Oxfmt are one minor behind (1.89.0, 0.74.0), with no formatting changes. - `vp migrate` moved .oxlintrc.json and .oxfmtrc.json into the root vite.config.ts and rewrote imports to vite-plus. That includes the vendored anti-slop plugin, recorded in its UPSTREAM.md. It also aliased the catalog's vite to @voidzero-dev/vite-plus-core. - Its minimumReleaseAgeExclude list is gone. It exempted vite-plus, Oxlint, Oxfmt and Vitest from the one-day release delay. - Lint, format check, typecheck, Knip, and the app's unit tests and build are Vite+ tasks, cached and replayed when nothing they read changed. The engine's tests and e2e stay package.json scripts, so they always run, since the age CLI, browsers and wrangler are outside what the cache can see. - tsc still typechecks, and lint has no type-aware rules. With planted errors, tsgolint caught plain ones in every tsconfig but missed noUncheckedIndexedAccess and lib errors under tsconfig.sw, node and worker.json. It flagged `!` that tsc requires. - CI sets up with voidzero-dev/setup-vp, pinned to v1.22.0 by commit. Pull requests restore and save the task cache; pushes to main run with --no-cache. - Knip gets the bench's entries, since it doesn't read a `vp dev --config` command line. devEngines matches Vite+'s Node range. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The _headers CSP and Trusted Types apply only to responses served straight from static assets, so v2 deploys with no Worker script. That rules out Void, Cloudflare's full-stack framework, and SSR in general, and keeps share links fragment-only. A feature needing server state reopens it. The research note covers what Vite+ and Void are, their status and licenses, and what the migration found, with sources. The glossary's Share link now says the server never sees or stores the key. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
V2/vite plus
Encryptee now keeps no records in browser storage and puts no key in a URL (ADR 0006). A saved public key can be swapped by anything that runs in the origin, browser storage gets evicted or cleared, and a link that preselects a recipient lets its sender choose who can open the files. To encrypt for someone, the user pastes their public key. - The engine loses its IndexedDB contacts store and buildShareLink / parseShareLink, with their tests. - The Keys screen is a single card, with "Copy public key" as its only copy button. The People card is gone. - The encrypt card's methods are "Passphrase | Public keys", and #to= links no longer preselect a key. - ADRs 0003, 0004 and 0005 are amended by 0006. The glossary drops Contact and Share link. v2 is unreleased, so there is no stored data or link to migrate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch had an error being deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.