Files
suaveplan/openspec/archive/2026-04-28-drive-port/tasks.md
2026-05-27 23:29:53 +01:00

52 lines
3.3 KiB
Markdown

# Tasks: drive-port
## 1. Scaffold
- [x] 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`.
- [x] 1.2 Workspace deps: `@suaveplan/error`, `@suaveplan/types`, `@suaveplan/events`, `@suaveplan/storage`, `@suaveplan/streams`, `@opentelemetry/api`, `zod`. All `workspace:^`.
- [x] 1.3 Subpath exports: `.`, `./types`, `./errors`. (No `./manager`, `./plugins/*` — those live in sibling packages.)
## 2. Types and contract
- [x] 2.1 `src/types/drive.types.ts` — `DriveOptions`, `DriveStorage` (extends `AbstractStorage`), `StorageCapabilities`, `DrivePlugin<THandle>`, `DriveMiddleware`.
- [x] 2.2 `src/error-codes.ts` — `defineCodes("DRIVE", [...])` with codes from proposal §7. Sibling `DriveError` extends `SuaveplanError<DriveErrorCode>`.
- [x] 2.3 `src/schemas/` — Zod boundary schemas for `DriveOptions`. Marker `// schema: boundary-only`.
## 3. `Drive` class
- [x] 3.1 `src/drive/drive.ts` — overloaded constructor `()`, `(storage)`, `(storage, options)`, `(options)`. Generics `<TStorageMap>`. Internal `connectedByMe: WeakSet<DriveStorage>`, `state: "fresh" | "ready" | "disposed"`.
- [x] 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 })`.
- [x] 3.3 `Drive.dispose()` — idempotent; close only storages in `connectedByMe`; transition to terminal disposed state.
- [x] 3.4 `drive.use(id, storage)` — generic narrowing.
- [x] 3.5 `drive.getStorage(id)` — typed lookup; `DRIVE.STORAGE_NOT_FOUND` if absent.
- [x] 3.6 `Drive.fromConfig(config)` — resolves storage via `StorageFactory` from `@suaveplan/storage`.
## 4. File operations
- [x] 4.1 `src/file-operations/read.ts` / `write.ts` / `delete.ts` / `stat.ts` / `list.ts` — each runs through the middleware chain.
- [x] 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
- [x] 5.1 `src/plugins/registry.ts` — install/dispose lifecycle, middleware chain (outer-first request, outer-last response).
- [x] 5.2 `drive.use(plugin)` returns the plugin's typed handle.
- [x] 5.3 `drive.useMiddleware(middleware)` — registers middleware separately from plugin install.
## 6. Spec
- [x] 6.1 Create `openspec/specs/drive/spec.md` with `DRIVE-01`…`DRIVE-09`, each with `**Verified by:**` line.
## 7. Conformance tests
- [x] 7.1 `src/drive/drive.spec-conformance.test.ts` — DRIVE-01, DRIVE-02, DRIVE-03, DRIVE-04, DRIVE-08, DRIVE-09.
- [x] 7.2 `src/error-codes.spec-conformance.test.ts` — DRIVE-05.
- [x] 7.3 `src/plugins/registry.spec-conformance.test.ts` — DRIVE-06.
- [x] 7.4 `src/file-operations/streams.spec-conformance.test.ts` — DRIVE-07.
## 8. Verify
- [x] 8.1 `bunx turbo lint typecheck test --filter=@suaveplan/drive` green.
- [x] 8.2 `bunx turbo test:coverage --filter=@suaveplan/drive` 100/100/100/100.
- [x] 8.3 `bun scripts/openspec-conformance.ts @suaveplan/drive` PASS.
- [x] 8.4 Sibling `.md` exists for every non-test, non-types, non-barrel `.ts` in `src/`.