npm package: @shipworthy/anchor
Description: TypeScript SDK that powers the [Anchor](../../README.md) ecosystem.  Import it in your own scripts or applications to programmatically query monitors, inspect window positions, and persist/restore layouts.
Latest version: 0.1.0

# `@shipworthy/anchor`

TypeScript SDK that powers the [Anchor](../../README.md) ecosystem.  Import it in your own scripts or applications to programmatically query monitors, inspect window positions, and persist/restore layouts.

> The SDK is **macOS-only** for now – it relies on AppleScript under the hood.  A cross-platform backend is on the roadmap.

---

## Install

```bash
npm i @shipworthy/anchor      # or yarn / pnpm
```

Because we publish ES Modules, make sure your `package.json` has `"type": "module"` **or** use dynamic `import()`.

## API Overview

```ts
import {
  applyWindowAnchors,
  checkPermission,
  getWindowAnchors,
  hashMonitorAnchors,
  list,
  load,
  remove,
  save,
} from "@shipworthy/anchor";

// 0. Check/request accessibility permissions (required on macOS)
const hasPermission = await checkPermission();
if (!hasPermission) {
  console.error("Please grant accessibility permissions and try again");
  process.exit(1);
}

// 1. Capture current layout and save it
const windows = await getWindowAnchors();
await save({
  id: crypto.randomUUID(),
  name: "my-setup",
  timestamp: new Date(),
  monitors: [/* fetched via monitorService (coming soon) */],
  windows,
  monitorHash: hashMonitorAnchors([]),
});

// 2. Restore later
const layout = await load("my-setup");
await applyWindowAnchors(layout.windows);
```

### Services

• **windowService** – List open windows and move/resize them.  
• **stateService** – Save / load layouts to `~/.anchor/states`.  
• **permissionService** – Check and request macOS accessibility permissions.  
• **utils** – Hashing, auto-naming & bounds-clamping helpers.

Additional services (monitorService, native provider bindings) will land in future minor versions.

## macOS Permissions

Anchor requires accessibility permissions to read window information and control window positions. The SDK provides helper functions:

```ts
import { 
  checkPermission,
} from "@shipworthy/anchor";

// Check if permissions are granted
const hasPermission = await checkPermission();
```

## Development

```bash
# At repo root
yarn dev       # incremental build in watch mode

# Unit tests
yarn test -F core
```

All source lives in `src/` and is compiled with **tsup** to ESM + d.ts
files in `dist/`.

## License

[MIT](../../LICENSE)

## Features

- Window state management (position, size, monitor)
- Monitor detection and multi-monitor support
- Layout persistence and restoration
- Permission checking for macOS accessibility

## Window Restoration Behavior

When restoring window layouts, Anchor uses intelligent matching:

1. **Exact Match**: First attempts to find and position windows with matching app name AND window title
2. **App-Based Fallback**: If no exact match is found, positions the frontmost window of the matching app

This means that applications like Arc browser will be restored to their saved positions even when browsing different tabs (which changes the window title). The same applies to code editors when different files are open.