All checks were successful
check / check (push) Successful in 59s
script/check ran script/test, script/lint and script/fmt-check. Since linting moved into Docker, script/lint is a build of Dockerfile.lint, which runs `prettier --check .` as a build step — so make check checked formatting twice over the same tree: once in the container and once on the host. script/precommit had the same pair. Drop the script/fmt-check call from both. The container keeps the check, because a successful Dockerfile.lint build is what CI treats as proof of a clean tree, and it is the stronger of the two verdicts: its prettier is digest-pinned and installed under --frozen-lockfile, while the host's is whatever the working tree happens to have. The pre-commit hook is unchanged in what it catches — script/lint still fails a badly formatted tree, and therefore the commit. script/fmt-check survives as a standalone entrypoint, as REPO_POLICIES.md requires, for asking the formatting question by itself without docker. Its verdict cannot drift from the container's: prettier is pinned to an exact version, installed from yarn.lock in both places, and reads .gitignore as its default ignore file, which is why .dockerignore keeps .gitignore in the build context. The count is asserted rather than promised. test/packaging/lint-once.test.ts walks the invocation graph from each entrypoint — through the Makefile shims, the script/ calls, the package.json scripts and the docker build into Dockerfile.lint's RUN steps — and counts prettier invocations: one per make check, one per script/precommit, and one each for make lint and make fmt-check alone, so neither can become a no-op that satisfies the count trivially. The walk also asserts which nodes it reached, so a restructure that defeats the resolver fails the test instead of quietly counting zero. Observed: 2 prettier invocations per make check before, 1 after.
100 lines
5.4 KiB
Markdown
100 lines
5.4 KiB
Markdown
# Workflow
|
|
|
|
- branch (from `main`)
|
|
- do the work in Next Step
|
|
- move Next Step to the top of Completed Steps
|
|
- move the top item of Future Steps into Next Step
|
|
- commit (`TODO.md` changes in the same commit as the work)
|
|
- merge to `main` if the branch is not protected, otherwise open a PR
|
|
- push
|
|
|
|
# Status
|
|
|
|
pre-1.0
|
|
|
|
# Next Step
|
|
|
|
Update the README API reference section to match the current implementation.
|
|
|
|
# Completed Steps
|
|
|
|
- 2026-08-10: Stopped `make check` running `prettier --check .` twice. Since
|
|
linting moved into Docker, the duplicate was one container pass and one host
|
|
pass of the same check: `script/lint` builds `Dockerfile.lint`, which runs
|
|
prettier as a build step, and `script/check` then called `script/fmt-check` as
|
|
well. The host call is gone from `script/check` and from `script/precommit`;
|
|
the container keeps checking formatting, because a successful
|
|
`Dockerfile.lint` build is what CI treats as proof of a clean tree, and it is
|
|
also what still fails the pre-commit hook on a badly formatted tree.
|
|
`script/fmt-check` survives as a standalone entrypoint, whose verdict cannot
|
|
drift from the container's. A test walks the invocation graph from each
|
|
entrypoint — through the Makefile shims, the `script/` calls and the
|
|
`docker build` — and asserts the prettier count, so the duplication cannot
|
|
come back unnoticed.
|
|
- 2026-08-10: Moved all linting into Docker. `script/lint` builds a new root
|
|
`Dockerfile.lint`, which copies the repo into the digest-pinned node image and
|
|
runs eslint and prettier as build steps, so a successful build is a clean
|
|
lint; no host lint path remains and `yarn lint` is gone from `package.json`. A
|
|
fail-closed `LINT_EPOCH` guard stops Docker serving the linter layers from
|
|
cache, which is how a lint build returns success in under a second having
|
|
linted nothing. The lint stage inside `Dockerfile` and its `COPY --from=lint`
|
|
ordering hack are gone: that image now runs `make test` and `make build` only,
|
|
because `script/check` calls `script/lint` and running it in a container would
|
|
mean docker inside docker. `script/cibuild` builds the lint image first, then
|
|
the test and build image.
|
|
- 2026-08-09: Made `make docker` green and policy-conformant. Multi-stage
|
|
Dockerfile: a lint stage runs `make fmt-check` and `make lint`, and the check
|
|
stage takes a `COPY --from=lint` dependency on it before running `make check`
|
|
and `make build`. `CHECK_EPOCH` and a fail-closed guard stop Docker serving
|
|
those two layers from cache, which is what let a build report success without
|
|
running the suite. `script/projectname` says `quak`, so the image is tagged
|
|
`quak`; `script/bootstrap` updates apt lists before installing, so a Debian
|
|
base works; `.dockerignore` no longer ships the compiled binary, the caches or
|
|
agent worktrees into the build context, and keeps `.gitignore` in it for
|
|
prettier.
|
|
- 2026-08-09: Fixed the TypeScript build. `rootDir` is the repo root, so `bin/`
|
|
compiles alongside `src/` instead of failing with TS6059; output is
|
|
`dist/src/` and `dist/bin/`, which is where `main`, `types` and `bin.quak` now
|
|
point. `script/build` verifies the declared entrypoints exist after the
|
|
compiler runs and makes the CLI executable, the Dockerfile runs `make build`
|
|
as well as `make check`, and a `quak` script makes the README's
|
|
`yarn quak <command>` examples work.
|
|
- 2026-08-09: Retry policy: no retry on 4xx (except `408` and `429`),
|
|
exponential backoff with full jitter on 5xx, transport failures and truncated
|
|
transfers, under per-attempt deadlines that cover the response body as well as
|
|
the request. Downloads retry request, stream consumption and decryption as one
|
|
unit; `postJSON` and `putJSON` are replayed only when the connection was never
|
|
established.
|
|
- 2026-08-09: Downloads verify the secretstream terminated on `TAG_FINAL` and
|
|
write output atomically: a truncated body is rejected instead of landing on
|
|
disk as a short file, and plaintext is staged in a sibling temp file and
|
|
renamed into place, so a failed download leaves the destination untouched.
|
|
- 2026-07-07 Adopted scripts-to-rule-them-all: `script/` entrypoints, Makefile
|
|
shims, README Entrypoints section
|
|
- 2026-06-10: Decrypted collections shared by other users (sealed-box keys);
|
|
listCollections drops deleted-collection tombstones.
|
|
- 2026-06-10: Login hardening: dual-2FA empty-string fields handled, TOTP
|
|
preferred when a passkey is also enrolled, interactive input via
|
|
@inquirer/prompts.
|
|
- 2026-06-10: Replaced sharp with pure JS (jpeg-js + exif-reader); added
|
|
single-binary bun build and make install.
|
|
- 2026-06-09: Added backup-metadata command (ML data always included, --exif
|
|
opt-in); rewrote README to match the implementation; added thumbnail helper
|
|
tests.
|
|
- 2026-05-13: Full CLI surface: login, backup with dedup symlink layout,
|
|
collections, files, get, get-thumb, thumbnail repair helpers.
|
|
- 2026-05-13: Client OO API with literate usage tests; file download and
|
|
decryption; all three metadata layers decrypted and persisted; renamed quack
|
|
to quak.
|
|
- 2026-05-11: SRP login flow (email OTP + TOTP) and ApiClient.
|
|
|
|
# Future Steps
|
|
|
|
- Tag v1.0.0.
|
|
- Future desktop client, separate repo:
|
|
- Electron app skeleton consuming this library.
|
|
- Local SQLite cache keyed on (collectionID, fileID, updationTime).
|
|
- Background sync worker streaming new files into the cache.
|
|
- Gallery UI: thumbnails, full-image view, basic search.
|
|
- Upload, delete, and share operations in the library.
|