Files
2026-05-27 23:29:53 +01:00

3.3 KiB

Tasks: drive-port

1. Scaffold

  • 1.1 Create packages/drive/drive/ with package.json (@suaveplan/drive@0.0.0), tsconfig.json extending @suaveplan/typescript-config/library.json, vitest.config.ts via createTestConfig(), root README.md.
  • 1.2 Workspace deps: @suaveplan/error, @suaveplan/types, @suaveplan/events, @suaveplan/storage, @suaveplan/streams, @opentelemetry/api, zod. All workspace:^.
  • 1.3 Subpath exports: ., ./types, ./errors. (No ./manager, ./plugins/* — those live in sibling packages.)

2. Types and contract

  • 2.1 src/types/drive.types.ts — DriveOptions, DriveStorage (extends AbstractStorage), StorageCapabilities, DrivePlugin<THandle>, DriveMiddleware.
  • 2.2 src/error-codes.ts — defineCodes("DRIVE", [...]) with codes from proposal §7. Sibling DriveError extends SuaveplanError<DriveErrorCode>.
  • 2.3 src/schemas/ — Zod boundary schemas for DriveOptions. Marker // schema: boundary-only.

3. Drive class

  • 3.1 src/drive/drive.ts — overloaded constructor (), (storage), (storage, options), (options). Generics <TStorageMap>. Internal connectedByMe: WeakSet<DriveStorage>, state: "fresh" | "ready" | "disposed".
  • 3.2 Drive.initialize() — idempotent; for each storage, call connect?.() only when isConnected?.() !== true; record in connectedByMe; surface failures as DriveError(DRIVE.STORAGE_CONNECT_FAILED, { cause }).
  • 3.3 Drive.dispose() — idempotent; close only storages in connectedByMe; transition to terminal disposed state.
  • 3.4 drive.use(id, storage) — generic narrowing.
  • 3.5 drive.getStorage(id) — typed lookup; DRIVE.STORAGE_NOT_FOUND if absent.
  • 3.6 Drive.fromConfig(config) — resolves storage via StorageFactory from @suaveplan/storage.

4. File operations

  • 4.1 src/file-operations/read.ts / write.ts / delete.ts / stat.ts / list.ts — each runs through the middleware chain.
  • 4.2 src/file-operations/streams.ts — createReadStream(path) / createWriteStream(path); prefer storage's native streams when capabilities.nativeStreams === true, otherwise inherit AbstractStorage.defaultCreate{Read,Write}Stream.

5. Plugin slot

  • 5.1 src/plugins/registry.ts — install/dispose lifecycle, middleware chain (outer-first request, outer-last response).
  • 5.2 drive.use(plugin) returns the plugin's typed handle.
  • 5.3 drive.useMiddleware(middleware) — registers middleware separately from plugin install.

6. Spec

  • 6.1 Create openspec/specs/drive/spec.md with DRIVE-01…DRIVE-09, each with **Verified by:** line.

7. Conformance tests

  • 7.1 src/drive/drive.spec-conformance.test.ts — DRIVE-01, DRIVE-02, DRIVE-03, DRIVE-04, DRIVE-08, DRIVE-09.
  • 7.2 src/error-codes.spec-conformance.test.ts — DRIVE-05.
  • 7.3 src/plugins/registry.spec-conformance.test.ts — DRIVE-06.
  • 7.4 src/file-operations/streams.spec-conformance.test.ts — DRIVE-07.

8. Verify

  • 8.1 bunx turbo lint typecheck test --filter=@suaveplan/drive green.
  • 8.2 bunx turbo test:coverage --filter=@suaveplan/drive 100/100/100/100.
  • 8.3 bun scripts/openspec-conformance.ts @suaveplan/drive PASS.
  • 8.4 Sibling .md exists for every non-test, non-types, non-barrel .ts in src/.