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

6.2 KiB

Tasks: enterprise-imessage-adapter

Change ID: enterprise-imessage-adapter Package: @suaveplan/imessage-adapter Target path: packages/communication/messaging/imessage-adapter/ Prerequisite genesis packages: @suaveplan/error, @suaveplan/events, @suaveplan/types, @suaveplan/testing

Numbered requirement / scenario checklist (AGENTS.md §0c pre-flight #6).

R1 Public surface · R2 Error registry · R3 Zod boundary · R4 Apple-date decode · R5 Handle/chat/attachment resolution · R6 Phone normalisation · R7 SqliteReader seam · R8 Polling loop · R9 AbortSignal · R10 EventBus bridge · R11 Adapter MessageSourceAdapter · R12 InboundMessage projection · R13 OTel · R14 Real fixtures · R15 Runner discipline · R16 Docs coverage · R17 Subpath exports.

0. Pre-flight

  • 0.1 git status and git worktree list clean / accounted-for.
  • 0.2 bun:sqlite available in the genesis runner (Bun-managed).

1. Scaffold

  • 1.1 Create packages/communication/messaging/imessage-adapter/ with src/, tests/setup/.
  • 1.2 package.json at 0.1.0, "type":"module", sideEffects:false, subpath exports per design (R17), deps on @suaveplan/error, @suaveplan/events, @suaveplan/types, tslib, zod, @opentelemetry/api.
  • 1.3 vite.config.ts, vitest.config.ts, tsconfig.lib.json per slack-client sibling.
  • 1.4 tests/setup/polyfills.ts wiring in-memory OTel meter provider.

2. Error-code registry (R2)

  • 2.1 src/error-codes/error-codes.ts — defineCodes("IMESSAGE", [...]) with the ten codes, one typed error class per code.
  • 2.2 src/error-codes/error-codes.test.ts — every code reachable from a real call site (assert via instanceof from production-throwing helpers).
  • 2.3 src/error-codes/error-codes.md.

3. Schemas (R3)

  • 3.1 src/schemas/schemas.ts — Zod schemas for IMessageWatcherConfig + IMessageAdapterConfig + row + parsed shapes; parseWatcherConfig / parseAdapterConfig helpers that throw IMessageInvalidConfigError.
  • 3.2 src/schemas/schemas.test.ts — accept happy paths, reject negative pollIntervalMs and bad chatFilter types.
  • 3.3 src/schemas/schemas.md.

4. Types (no .md for .types.ts)

  • 4.1 src/types/imessage.types.ts — row, parsed, config interfaces (preserve upstream surface).
  • 4.2 src/types/adapter.types.ts — InboundMessage, MessageSourceAdapter.
  • 4.3 src/types/seams.types.ts — SqliteReader, SqliteHandle, SqliteStatement.

5. SQLite reader (R7)

  • 5.1 src/sqlite/bun-sqlite-reader.ts — bunSqliteReader: SqliteReader lazily importing bun:sqlite.
  • 5.2 src/sqlite/bun-sqlite-reader.test.ts — opens a real temp DB, runs a SELECT.
  • 5.3 src/sqlite/bun-sqlite-reader.md.

6. Fixtures

  • 6.1 src/fixtures/chat-db-fixture.ts — createChatDbFixture(reader, path) creating real chat.db-shaped tables + insert helpers.
  • 6.2 src/fixtures/chat-db-fixture.test.ts — round-trip insert + query.
  • 6.3 src/fixtures/chat-db-fixture.md.

7. Parser (R4, R5, R6)

  • 7.1 src/parser/imessage-parser.ts — IMessageParser with parseMessage / parseAppleDate / parseAttachment / isGroupChat / normalizePhoneNumber. parseAppleDate throws IMessageAppleDateParseError on NaN / non-finite.
  • 7.2 src/parser/imessage-parser.test.ts — covers every behaviour the upstream tests cover + the additional error paths.
  • 7.3 src/parser/imessage-parser.md.

8. Watcher (R8, R9, R10)

  • 8.1 src/watcher/imessage-watcher.ts — IMessageWatcher with EventBus bridge, AbortSignal, injectable reader, injectable clock + timers, OTel record calls.
  • 8.2 src/watcher/imessage-watcher.test.ts — real-bun:sqlite-fixture poll loop, AbortSignal short-circuit, includeFromMe / chatFilter, lastRowId monotonic, EventBus delivery, bus bridge via legacy on(), OTel emissions.
  • 8.3 src/watcher/imessage-watcher.md.

9. Adapter (R11, R12)

  • 9.1 src/adapter/imessage-adapter.ts — IMessageAdapter calling watcher, projecting InboundMessage, throwing IMessageAdapterNotInitializedError from poll() before initialize().
  • 9.2 src/adapter/imessage-adapter.test.ts — full surface assertion, projection rules, last-processed-id, idempotent close, sibling-.md & subpath presence asserted.
  • 9.3 src/adapter/imessage-adapter.md.

10. OTel (R13)

  • 10.1 src/otel/metrics.ts — recordMessageEmitted, recordAttachmentEmitted, recordPollError, recordPollDuration, refreshIMessageMeters.
  • 10.2 src/otel/metrics.test.ts — assert each instrument lands on the in-memory exporter.
  • 10.3 src/otel/metrics.md.

11. Package barrel + README

  • 11.1 src/index.ts — explicit named re-exports of the full public surface (R1), side-effect import of ./error-codes/index.js.
  • 11.2 Root README.md describing the package, install + usage, the four OTel instruments, the ten error codes, the SqliteReader seam.

12. Verify gates (R14, R15, R16, R17)

  • 12.1 grep -rnE "from ['\"](vitest|bun:test)['\"]" packages/communication/messaging/imessage-adapter/src/ packages/communication/messaging/imessage-adapter/tests/ → zero output.
  • 12.2 grep -rnE "vi\.mock|jest\.mock|mock\.module" packages/communication/messaging/imessage-adapter/ → zero output.
  • 12.3 grep -rn "biome-ignore\|TODO\|FIXME\|@deprecated\|ts-ignore\|ts-expect-error\|\.skip\|\.only" packages/communication/messaging/imessage-adapter/src/ → zero output.
  • 12.4 bunx turbo lint typecheck test build --filter=@suaveplan/imessage-adapter — green.
  • 12.5 bunx turbo test:coverage --filter=@suaveplan/imessage-adapter — 100/100/100/100.

13. Manifest + STATUS + finalisation

  • 13.1 bun scripts/folder-reorg/generate-manifest.ts.
  • 13.2 Flip STATUS.md imessage-adapter row to ✅ and bump the "Migrated" counter.
  • 13.3 Fold specs/imessage-adapter/spec.md into openspec/specs/imessage-adapter/spec.md.
  • 13.4 Move the change folder to openspec/archive/2026-05-25-enterprise-imessage-adapter/.

14. Commit (no push)

  • 14.1 Conventional commit + Co-Authored-By: Claude footer on branch feat/migrate-imessage-adapter.