6.8 KiB
6.8 KiB
Tasks — Font compress CLI
Every checkbox MUST reflect work actually done in this change. Do not retroactively tick boxes.
Audit Note (2026-05-02)
Minimal progress beyond spec authoring — DEFERRED, do not archive.
- §1 Spec authoring (9 tasks) is checked, and
proposal.md+tasks.mdexist — that's the only completed work. - No
packages/fonts/font-compress/src/bin/directory exists. Existing src dirs:constants,packer,unpacker,utils. package.jsonhas nobinfield — confirmed via grep.bunx turbo lint typecheck test --filter=@suaveplan/font-compressis GREEN — the green is for the existing pure-library surface; no CLI ships.- 35 of 44 tasks remain: dev-dep wiring (
@suaveplan/cli,@suaveplan/readline,@suaveplan/logger),binfield,suaveplan-font-compress.tsentry,format-utils.ts,FONT_COMPRESS.CLI_INVALID_ARGS, Vite shebang config, unit + spec-conformance + integration tests, sibling.mds, README CLI section.
1. Spec authoring
- 1.1 Read
../suaveplan/packages/universal/font-compress/src/cli.tsend-to-end (369 lines) - 1.2 Read
../suaveplan/packages/universal/font-compress/package.json(confirmbinfield shape) - 1.3 Read
openspec/specs/font-compress/spec.md(does not exist — capability spec authored fresh in this change) - 1.4 Read
openspec/AGENTS.mdSections 13, 13a, 14, 14a - 1.5 Read
packages/tooling/installer/src/bin/suaveplan-install.tsfor the genesis bin pattern - 1.6 Draft
proposal.mdfromopenspec/templates/proposal.md - 1.7 Fill in
## Source mappingtable — every requirement cites a line range OR appears in the "no source line" table with justification - 1.8 Draft
specs/font-compress/spec.mdfromopenspec/templates/spec-delta.md - 1.9 Every requirement in the spec delta carries a
**Verified by:**line naming concreteit(...)titles
2. Implementation
- 2.1 Add dev dep
@suaveplan/cli(already a workspace package — argument parser, ANSI styling, progress bar) - 2.2 Add dev dep
@suaveplan/readline(interactive prompts on overwrite confirmation) - 2.3 Add dep
@suaveplan/logger(structured CLI logging) - 2.4 Add
binfield topackage.json—"suaveplan-font-compress": "./dist/bin/suaveplan-font-compress.js" - 2.5 Add
./bin/suaveplan-font-compresssubpath topackage.jsonexports(so the bin script is in the dist tree and resolvable for tests) - 2.6 Author
src/bin/suaveplan-font-compress.ts— shebang, argument parser via@suaveplan/cli, dispatch (binary input →@suaveplan/font-convert::FontConverterorBatchConverter, thenBinaryFontPacker; JSON input →BinaryFontPackerdirectly), output writer, summary printer - 2.7 Author
src/bin/format-utils.ts— pure helpers (formatBytes, formatRatio, ANSI colour wrappers); separate file so the bin entry stays under the 250-line soft / 300-line hard budget - 2.8 Wire
FONT_COMPRESS.CLI_INVALID_ARGSinto the existingFONT_COMPRESS_CODESregistry (src/error-codes.ts) - 2.9 Update Vite build config so the bin entry is emitted as a separate chunk with the shebang preserved (
vite-plugin-shebangor equivalent) - 2.10 Update
tsconfig.lib.jsonincludeto coversrc/bin/**
3. Tests
- 3.1
src/bin/suaveplan-font-compress.test.ts— unit tests for the argument parser (every flag, conflicting flags, missing positional, unknown flag), exit-code mapping,--help/--versionshort-circuit. Drivemain()directly withprocess.argv-equivalent injection. - 3.2
src/bin/suaveplan-font-compress.spec-conformance.test.ts— pinsFONT_COMPRESS.CLI_INVALID_ARGSemission, structured logging through@suaveplan/logger, OTel spanfont-compress.cli.runrecorded via in-memory tracer - 3.3
src/bin/integration/cli-roundtrip.test.ts— integration test using a fixture TTF insrc/bin/integration/fixtures/: invokes the bin viaBun.spawn, verifies stdout banner, verifies.btffile written, verifies the.btfround-trips throughBinaryFontUnpacker - 3.4
src/bin/format-utils.test.ts— pure unit tests forformatBytes,formatRatio - 3.5 Every
it(...)carries{ timeout: 5000 }(or 30000 for genuinely async like the integration roundtrip)
4. Documentation
- 4.1
src/bin/suaveplan-font-compress.md— sibling doc, ≥200 words, basic + advanced examples (single file, directory, recursive, JSON intermediate, custom output), full flag reference, exit-code table, implementation notes covering the convert→pack pipeline composition - 4.2
src/bin/format-utils.md— sibling doc for the helper module - 4.3 README adds a new
## CLIsection linking the bin doc and showing an end-to-end example - 4.4 Update
CLAUDE.mdfont-compresslisting to mention the bin entry: "Bin:suaveplan-font-compress(TTF/OTF/WOFF/WOFF2 → BTF pipeline)"
5. Pre-archive verification (the 5-gate triple)
- 5.1
bun run check— Biome 0 errors / 0 warnings / 0 info - 5.2
bunx turbo lint typecheck test --filter=@suaveplan/font-compress— green - 5.3
bunx turbo test:coverage --filter=@suaveplan/font-compress— 100/100/100/100 - 5.4
bun scripts/openspec-conformance.ts @suaveplan/font-compress— exit 0, noerrorfindings - 5.5
bunx turbo build --filter=@suaveplan/font-compress— green ANDdist/bin/suaveplan-font-compress.jsstarts with#!/usr/bin/env nodeAND is executable - 5.6 Smoke test:
node packages/fonts/font-compress/dist/bin/suaveplan-font-compress.js --versionprints the version
6. Pre-archive 7-row checklist (AGENTS.md Section 13)
- 6.1 Generics threaded;
expectTypeOfassertions on the parser-result discriminated union - 6.2 Zod schemas wired at every public boundary (parsed args validated before any FS work)
- 6.3 Every error code in
error-codes.tsthrown by at least one production path (FONT_COMPRESS.CLI_INVALID_ARGScovered by the bad-args scenario) - 6.4 Strict-mode behaviors tested both on and off (
--forceon/off,--preserve-structureon/off) - 6.5 OTel span
font-compress.cli.runemitted from production paths and asserted with a real in-memoryTracerProvider - 6.6 Lifecycle dedup tested where claimed (multiple invocations against the same input directory with
--forceoff skip already-converted files; verified by spy onBinaryFontPacker.pack) - 6.7 No retroactive tick — every box above reflects work done in this change
7. Archive
- 7.1 Fold spec delta into
openspec/specs/font-compress/spec.md(creates the canonical capability spec from scratch since none exists) - 7.2 Move
openspec/changes/font-compress-cli/→openspec/archive/<yyyy-mm-dd>-font-compress-cli/ - 7.3 Refresh
MANIFEST.md(thebinfield is a new package surface; manifest should reflect it)