# 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`, `DriveMiddleware`. - [x] 2.2 `src/error-codes.ts` — `defineCodes("DRIVE", [...])` with codes from proposal §7. Sibling `DriveError` extends `SuaveplanError`. - [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 ``. Internal `connectedByMe: WeakSet`, `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/`.