# @suaveplan/macos-contacts - Universal macOS Contacts.app bridge via AppleScript: injectable AppleScriptRunner seam (run tests on any platform without macOS), free-function ContactParser surface, injectable Clock for sync timestamps, six OTel counters + two histograms with outcome-partitioned attributes, typed MacOSContactsError hierarchy with stable MACOS_CONTACTS.* code registry, and Zod input validation at every boundary. Universal bridge to macOS Contacts.app via AppleScript. Reads contacts and groups through the platform `osascript` binary, parses the output into typed records, and exposes the result behind an injectable runner seam so tests run on any platform without macOS. ## Documentation tree - [applescript](./src/applescript/applescript.md) — AppleScript template builders for querying macOS Contacts.app. Each function returns a complete AppleScript string suit… - [applescript](./src/applescript/applescript.md) — AppleScript template builders for querying macOS Contacts.app. Each function returns a complete AppleScript string suit… - [bridge](./src/bridge/bridge.md) — `MacOSContactsBridge` is the high-level entry point for `@suaveplan/macos-contacts`. It composes the four building bloc… - [bridge](./src/bridge/bridge.md) — `MacOSContactsBridge` is the high-level entry point for `@suaveplan/macos-contacts`. It composes the four building bloc… - [error-codes](./src/error-codes/error-codes.md) — Defines the stable error-code registry and typed `MacOSContactsError` class for `@suaveplan/macos-contacts`. Every fail… - [error-codes](./src/error-codes/error-codes.md) — Defines the stable error-code registry and typed `MacOSContactsError` class for `@suaveplan/macos-contacts`. Every fail… - [executor](./src/executor/executor.md) — Defines the `AppleScriptRunner` injectable seam that `MacOSContactsBridge` depends on, plus a default implementation ba… - [executor](./src/executor/executor.md) — Defines the `AppleScriptRunner` injectable seam that `MacOSContactsBridge` depends on, plus a default implementation ba… - [otel](./src/otel/instruments.md) — Bundle of OpenTelemetry instruments emitted by `@suaveplan/macos-contacts`. The accessor `getMacOSContactsInstruments()… - [instruments](./src/otel/instruments.md) — Bundle of OpenTelemetry instruments emitted by `@suaveplan/macos-contacts`. The accessor `getMacOSContactsInstruments()… - [parser](./src/parser/parser.md) — Pure free-function parser for the raw text stream emitted by the AppleScript templates that drive `MacOSContactsBridge`… - [parser](./src/parser/parser.md) — Pure free-function parser for the raw text stream emitted by the AppleScript templates that drive `MacOSContactsBridge`… - [schemas](./src/schemas/schemas.md) — Zod schemas guarding every public input boundary of `@suaveplan/macos-contacts`. Validation runs before any side effect… - [schemas](./src/schemas/schemas.md) — Zod schemas guarding every public input boundary of `@suaveplan/macos-contacts`. Validation runs before any side effect… ## Install ```bash bun add @suaveplan/macos-contacts ``` ## Quick start ```ts import { MacOSContactsBridge } from "@suaveplan/macos-contacts"; const bridge = new MacOSContactsBridge({ timeoutMs: 30_000 }); if (await bridge.isAvailable()) { const contacts = await bridge.getAllContacts(); console.log(`${contacts.length} contacts`); const family = await bridge.getGroupMembers("Family"); } ``` ## Features - Injectable `AppleScriptRunner` seam — tests run on any platform without macOS by passing a fake runner that returns fixture strings. - Free-function parser surface (`parseContacts`, `parseGroups`, `normalizePhone`) — no static-only class, tree-shakeable at function granularity. - Typed `MacOSContactsError` hierarchy with the `MACOS_CONTACTS.*` code registry (`INVALID_INPUT`, `CONTACTS_NOT_FOUND`, `CONTACTS_PERMISSION_DENIED`, `CONTACTS_ACCESS_FAILED`, `CONTACTS_PARSE_FAILED`, `CONTACTS_UNAVAILABLE`). - Six OTel counters (partitioned by `outcome`) and two histograms wired through `@suaveplan/opentelemetry`. - Zod input validation at every public boundary; injectable `Clock` for sync timestamps; no `Date.now()` / `new Date()` in the production hot path. - `sync()` and `isAvailable()` never throw — failures surface through structured result fields. ## Modules - [`error-codes`](./src/error-codes/error-codes.md) — stable code registry + typed `MacOSContactsError`. - [`schemas`](./src/schemas/schemas.md) — Zod schemas + `parseOrThrow` boundary helper. - [`otel/instruments`](./src/otel/instruments.md) — OpenTelemetry counter + histogram bundle. - [`parser`](./src/parser/parser.md) — free-function parser for raw AppleScript output. - [`applescript`](./src/applescript/applescript.md) — AppleScript template builders. - [`executor`](./src/executor/executor.md) — `AppleScriptRunner` interface + default platform implementation. - [`bridge`](./src/bridge/bridge.md) — `MacOSContactsBridge` orchestrator.