4.0 KiB
4.0 KiB
Tasks: enterprise-image
Change ID: enterprise-image
Package: @suaveplan/image
Target path: universal/media/image
Prerequisite packages on Verdaccio: @suaveplan/error, @suaveplan/types, @suaveplan/mime, @suaveplan/crypto-utils
0. Pre-flight (non-negotiable)
- 0.1 Confirm clean working tree (
git statusreports nothing) and no in-flight worktrees with uncommitted work (git worktree listthengit statusin each) - 0.2 If any worktrees exist under
.claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against. - 0.3 Confirm the package set in
MANIFEST.mdmatchesfind packages -maxdepth 3 -name package.jsoncount. Drift here means a prior change archived without regenerating the manifest.
1. Scaffold
- Create directory
universal/media/image/withsrc/,tests/,src/__benchmarks__/, and all feature subdirectories per the layout inproposal.md. - Write
package.jsonat version0.1.0with"type": "module","sideEffects": false, fullexportsmap, deps:@suaveplan/error workspace:^,@suaveplan/types workspace:^,@suaveplan/mime workspace:^,@suaveplan/crypto-utils workspace:^,zod catalog:forms,@opentelemetry/api catalog:observability. - Write
tsconfig.jsonextending@suaveplan/typescript-config/library.json. - Write
vitest.config.tsusingcreateTestConfig()from@suaveplan/testing/config. - Add
lint,typecheck,test,test:coverage,build,docs:checkscripts.
2. Types + errors
- Write
src/types/common.ts—ImageFormat,ColorSpace,ImageMetadata,ResizeOptions,CropOptions,ConvertOptions,ImageAdapter,ImageProcessorOptionsinterfaces. - Write
src/types/common.md. - Write
src/error-codes.ts—ImageErrorCodeunion,IMAGE_ERROR_METADATA,registerImageErrorCodes(). - Write Zod schemas:
ResizeOptionsSchema,CropOptionsSchema,ConvertOptionsSchema,ImageMetadataSchema,ImageProcessorOptionsSchema.
3. MemoryImageAdapter
- Implement pure-JS pixel operations on raw RGBA
Uint8Array:readMetadata(parse JPEG/PNG headers for width/height),resize(nearest-neighbour),crop,rotate(90/180/270),flip,convert(PNG↔JPEG re-encode via raw header swapping — or format passthrough with explicit limitation in docs). - Write
memory-adapter.test.ts(≤500 lines): each operation, round-trip, edge cases (1×1, wide, tall). - Write
memory-adapter.md.
4. ImageProcessor
- Implement
ImageProcessorclass delegating all operations toadapter; wireAbortSignalpropagation. - Implement OTel: span
image.process, counterimage.operation_total, histogramimage.duration_ms. - Write
image-processor.test.ts(≤500 lines): each operation via MemoryImageAdapter, abort, invalid options throw. - Write
image-processor.md.
5. Utils
- Implement
src/utils/format-detect.ts— delegates to@suaveplan/mime; maps MIME type toImageFormat. - Write
format-detect.test.tsandformat-detect.md.
6. Benchmarks
- Write
src/__benchmarks__/image.bench.ts—metadataread,resize1920×1080→640×360,convertPNG→WebP (null adapter for format-convert path).
7. Tests
- Write
tests/integration.test.ts— full pipeline with MemoryImageAdapter. - Write
tests/property.test.ts(fast-check) — crop idempotency, resize monotonicity, flip involution.
8. Docs
- All co-located
.mdfiles (≥200 words each). - Write
README.mdat package root.
9. Verify and publish
bunx turbo lint typecheck test --filter=@suaveplan/image— green.bunx turbo test:coverage --filter=@suaveplan/image— 100%.bun scripts/publish.ts --package @suaveplan/image.- Archive to
openspec/archive/2026-04-24-enterprise-image/.