# DOX — packages/apple-tools

Files in this directory. One row per source file. See change: add-apple-tools-imcp-plugin.

| File | Purpose |
|------|---------|
| `README.md` | Package overview. iMCP (Apple PIM) provisioning for pi via pi-mcp-adapter. macOS-only, no Mail. Install/provision/manual-grant, nine provisioning states. |
| `package.json` | pi-dashboard-plugin manifest. id `apple-tools`, priority 100. `requires: { piExtensions: ["pi-mcp-adapter"], paths: ["${imcpServerPath}"] }`. `configSchema` `./config.schema.json`. Claims `settings-section`→`AppleToolsSettings` (no `tab` — renders under the plugin's own row). `bin` `pi-apple-tools-install`. `pi.skills` `.pi/skills/apple-tools`. Declares `pi-mcp-adapter` as a dep (documentary; NOT bundled, does NOT satisfy the piExtensions probe). No postinstall. |
| `config.schema.json` | JSON Schema 7. `imcpServerPath` only (default canonical `/Applications` location — the key the `paths` requirement interpolates). `directTools`/`disabled` deliberately absent: they are adapter-owned and live on the `mcpServers.iMCP` entry in mcp.json. |
| `vitest.config.ts` | jsdom + react, shared setup-home globalSetup. |
| `tsconfig.json` | Extends tsconfig.base; jsx react-jsx; noEmit. |
| `.pi/skills/apple-tools/SKILL.md` | Agent skill. Seven reachable services; Mail exclusion + redirect to `apple-mail-fast-export`; Messages=iMessage/SMS; load-time `--check`; TCC revocation → menu-bar remediation. |
| `src/detect.ts` | Pure injectable probes: `parseVersion`/`compareVersions`/`meetsMinimum` (numeric, MIN_MACOS 15.3), `candidatePaths`/`discoverServer` (override-as-preference, ordered candidate list). Constants: IMCP_RELATIVE, IMCP_DOWNLOAD_URL, IMCP_BREW_CASK. |
| `src/install.ts` | `runInstaller(env, {check})` — the nine-state provisioning machine (write + write-suppressed check twin). `TerminalState` / `TERMINAL_STATES`, `InstallerEnv`, `InstallResult`. Post-brew re-discovery gate. Pure over injected env. Owns NO writer: `env.mcps` is the `mcp-client.config` service — `ensureServerEntry("iMCP", {command}, {kind:"global"})`, `ensureAdapterPackage`, `checkConfigFiles`. `relayConfigFailure` maps `ConfigRefusal` onto terminal states: `write-failed` → `CONFIG_WRITE_FAILED`, else `CONFIG_UNPARSEABLE`. See change: extract-mcp-client-plugin. |
| `src/reconcile.ts` | `shouldReconcilePath` — server-side write-back guard (unset/default only, never over an operator override). `DEFAULT_IMCP_PATH`. |
| `src/doctor.ts` | `doctorProbe(env, packagePresent)` — read-only verdict from the shared checker; non-macOS never a remediation item. |
| `src/env.ts` | Real-environment `InstallerEnv` factory. The ONLY module that touches the real OS: `sw_vers`, brew via argv-array execFileSync (shared platform/exec wrapper). `createInstallerEnv`, BREW_TIMEOUT_MS. Builds `mcps` via `createMcpClientConfigService({configIO})` from `@blackbelt-technology/pi-dashboard-mcp-client-plugin/core` — hostless, global scope, `knownCwds` empty. Hardened atomic write (`wx` + random temp, 0600, fsync) moved to mcp-client `config-io.ts`; paths come from the adapter helpers, so `PI_CODING_AGENT_DIR` is honoured. See change: extract-mcp-client-plugin. |
| `src/bin/install.ts` | `pi-apple-tools-install [--check] [--path <p>]` CLI. Writes exactly two files in write mode; never the server plugin store. |
| `src/server/index.ts` | Plugin server entry. `ctx.consume<McpClientConfigService>("mcp-client.config")` at registration; absent → THROWS (fail closed — `dependsOn: ["mcp-client"]` guarantees ordering). `GET /api/apple-tools/status` (read-only, 10s TTL cache; iMCP readout via `readServerEntry("iMCP", {kind:"global"})`). `plugin_action` handler `run-installer` only (refuses the brew branch — delegates the long network install to the CLI). `set-disabled` / `set-direct-tools` DELETED — hard break, they live in mcp-client. Path reconciliation via `updatePluginConfig` on the action path only. See change: extract-mcp-client-plugin. |
| `src/client/index.tsx` | `AppleToolsSettings` settings-section panel. Status readout, Run installer, path override; no directTools, no disable toggle (moved to mcp-client) — links "Manage MCP servers →" to `MANAGE_MCP_PATH` `/settings/plugins/mcp-client`. `useMissingDeps` reads this plugin's `missingDeps` from `GET /api/plugins`; a `mcp-client` gap renders a banner and hides the installer. Non-macOS inert state. See change: extract-mcp-client-plugin. |
