Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
.DS_Store
/.agent/
/.build
__pycache__/
*.pyc
/tmp/
/Packages
xcuserdata/
Expand Down
40 changes: 37 additions & 3 deletions Documentation/Architecture/Calendar/Architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,45 @@ broad private Calendar implementation mechanism.
EventKit is the source of authority for accepted calendar and event identity,
authorization, recurrence, alarms, attendee metadata, and mutations.

Read and mutation workflows require full Calendar access. Mutations resolve
calendars and current events before writing; write-only access cannot supply
those identities. `apple` embeds its Calendar access purpose descriptions from
`Sources/AppleCLI/Info.plist` through the package's executable linker settings.
`calendar doctor` checks this metadata without requesting authorization.

## Implementation Mechanisms

Calendar uses EventKit for calendars, event list/search/read, occurrences,
availability, statistics, iCalendar export planning, and safety-gated
event create/update/delete.
Calendar uses EventKit for source/account reads, calendar list/read and
create/update/delete, event list/search/read, occurrences, availability,
statistics, iCalendar export planning, and event create/update/delete.

Calendar collection mutations use explicit source or calendar IDs. Source
identity is fixed when a calendar is created. Calendar updates modify only
requested title/color fields; immutable calendar attributes are separate from
permission to modify its events. Update/delete re-resolve and compare the
calendar record before writing. Successful saves require matching fields from
a fresh EventKit store; deletion requires absence there. Provider save failures
retain their diagnostics and require checking current state before retrying.

Event summaries and details expose all EventKit recurrence rules in
`recurrenceRules`; `recurrence` contains the first rule. Each rule retains
weekday ordinals, month/day/week selectors, set positions, recurrence-calendar
identity and the native first weekday. A zero first weekday means unspecified.
Custom recurrence input replaces the event's rules; other field updates leave
them intact. Invalid frequency/selector combinations are rejected before native
construction. The full EventKit initializer must retain the requested conditions
in its getters before the rule is attached to an event.

iCalendar export accepts non-recurring events. Bounded EventKit queries return
expanded occurrences without complete series masters and exception data.
Recurring or detached rows therefore return an unsupported result before an
artifact is written. Series export requires complete original occurrence,
exception, UID and time-zone data.

All-day export uses the observed event time zone, or the current macOS time
zone when EventKit supplies none. Its date-only end remains exclusive across
daylight-saving changes. Summaries/details retain the observed time-zone
identifier; timed export currently represents UTC instants.

## Validation

Expand Down
11 changes: 7 additions & 4 deletions Documentation/Architecture/Calendar/CapabilityList.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,16 @@ contract.

| Capability | CLI surface | Implementation mechanism | Gate / verifier / gap |
| --- | --- | --- | --- |
| Calendar reads | `calendars list` | EventKit | Read-only; authorization failures are explicit. |
| Event reads | `events list/search/read/occurrences/stats`, `availability check` | EventKit | Date ranges and limits bound output. |
| Event export | `events export` | EventKit plus file output | Supports `--dry-run`; execution requires `--allow-artifact-action`. |
| Event mutation | `events create/update/delete` | EventKit | Supports `--dry-run`; execution uses current event identity and attendee metadata. |
| Source/account reads | `sources list/read` | EventKit | Native source IDs, type, delegation state and event-calendar membership; `read` requires an ID. |
| Calendar reads | `calendars list/read` | EventKit | Full Calendar access; optional source-ID filtering, explicit-limit truncation and native source/type/attribute permissions/color metadata. |
| Calendar mutation | `calendars create/update/delete` | EventKit | Creation requires source ID; update/delete require calendar ID. Preview before writing; immutable attribute changes/deletion rejected; unchanged requests skip saves. Saves and deletion use fresh-store verification. Updates support title/color and preserve other projected fields. Provider restrictions remain explicit. |
| Event reads | `events list/search/read/occurrences/stats`, `availability check` | EventKit | Date ranges and limits bound output; invalid or noncanonical date-only values are rejected. Summaries/details retain all recurrence rules and their custom conditions. |
| Event export | `events export` | EventKit plus file output | Non-recurring events; supports `--dry-run` and requires `--allow-artifact-action` for execution. Recurring/detached rows require complete series and exception data and currently return unsupported before writing. |
| Event mutation | `events create/update/delete` | EventKit | Supports `--dry-run`; full Calendar access is required to resolve calendar and event identity. Custom weekday/month/week/year-day/set-position conditions are validated and checked against native rule getters; provider persistence requires controlled native validation. |

## Rejected / Gated

- Occurrence-scoped mutation.
- Complete recurring-series iCalendar export.
- Attendee invite administration beyond accepted metadata behavior.
- Broad calendar-server administration.
10 changes: 5 additions & 5 deletions Documentation/Architecture/CapabilityList.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,22 +26,22 @@ Keep detailed target design out of this file. Target-specific truth belongs in
| Target | Accepted capability summary | Detailed capability list |
| --- | --- | --- |
| `notes` | Notes accounts, folders, Smart Folder metadata/criteria/matching-note reads plus single-tag create/update/rename/delete, tag listing/search/membership/rename/delete, attachment metadata/add/remove/export, link metadata/backlinks/resolution, web/app/file URL link add/update/remove, note-to-note link add/update/remove, paragraph note-link add/update/remove, visible-note PDF/Markdown/HTML/RTF/RTFD export, body structure, checklist add/set/set-all/convert/convert-range/reorder/indent/delete, single ordinary list item reorder/indent/delete, note state, list/search/read, safety-gated text note mutations, private-framework readiness checks, and capability diagnostics for rich Notes workflows. | [Notes](Notes/CapabilityList.md) |
| `calendar` | EventKit calendars, event reads/searches/occurrences/stats/availability/export, and safety-gated event create/update/delete. | [Calendar](Calendar/CapabilityList.md) |
| `calendar` | EventKit source/account and calendar reads, calendar lifecycle, event reads/searches/occurrences/stats/availability/export, and event create/update/delete. | [Calendar](Calendar/CapabilityList.md) |
| `reminders` | ReminderKit reads/writes, rich Reminders metadata, Smart Lists, list organization, and read-only SQLite verifier/doctor evidence. | [Reminders](Reminders/CapabilityList.md) |
| `contacts` | Contacts search/read/duplicates/groups, vCard import/export, contact mutations, and group membership changes. | [Contacts](Contacts/CapabilityList.md) |
| `mail` | Mail accounts/mailboxes/message reads, bounded body preview/search, draft/reply/forward/send, and mailbox mutations. | [Mail](Mail/CapabilityList.md) |
| `messages` | Local Messages conversation/message reads and safety-gated sends. | [Messages](Messages/CapabilityList.md) |
| `maps` | Place search/read, directions preview, and safety-gated Maps open actions. | [Maps](Maps/CapabilityList.md) |
| `maps` | Native address/POI search, place detail, saved favorite reads, collection lifecycle and existing member links, route calculation, ETA, directions links and safety-gated Maps open. | [Maps](Maps/CapabilityList.md) |
| `finder` | Path-bounded file metadata, open/reveal, move/trash/delete, tags, and bounded file text writes. | [Finder](Finder/CapabilityList.md) |
| `numbers` | `.numbers` document metadata, sheet/table reads, table export, single-cell text write, open, and QuickLook/package export. | [Numbers](Numbers/CapabilityList.md) |
| `pages` | `.pages` document metadata, open, and QuickLook/package export. | [Pages](Pages/CapabilityList.md) |
| `keynote` | `.key` presentation metadata, slide listing/export, open, and QuickLook/package export. | [Keynote](Keynote/CapabilityList.md) |
| `keynote` | `.key` file/package metadata, native slide reads/PDF export, cached previews, open and package copy. | [Keynote](Keynote/CapabilityList.md) |
| `facetime` | Contact resolution, call preparation, and safety-gated FaceTime call start. | [FaceTime](FaceTime/CapabilityList.md) |
| `safari` | Safari windows/tabs/pages/profile reads, selected browser actions, Reading List, gated page/extension actions, and Tab Group diagnostics. | [Safari](Safari/CapabilityList.md) |
| `photos` | Photos library/media/album/folder reads, import/export/report, metadata workflows, slideshow/actions, spotlight, and gated hooks. | [Photos](Photos/CapabilityList.md) |
| `print` | Printer/job inspection plus safety-gated print submission and cancellation. | [Print](Print/CapabilityList.md) |
| `clipboard` | Pasteboard type/read plus safety-gated write/clear. | [Clipboard](Clipboard/CapabilityList.md) |
| `notifications` | Notification preview and safety-gated send for notifications created by this tool. | [Notifications](Notifications/CapabilityList.md) |
| `clipboard` | Bounded text and ordered typed items, verified conditional replacement, current-device writes and clear. | [Clipboard](Clipboard/CapabilityList.md) |
| `notifications` | Preview, per-app settings, explicit authorization, callback-confirmed submission and scoped pending/delivered queries and removal. | [Notifications](Notifications/CapabilityList.md) |
| `intelligence` | Apple Intelligence local-cache support/doctor/verify and risk-flag-gated enablement/recovery/service workflows. | [Intelligence](Intelligence/CapabilityList.md) |
| `tcc` | TCC service/identity/database diagnostics, access preflight/request, reset, and gated private diagnostics. | [TCC](TCC/CapabilityList.md) |

Expand Down
8 changes: 5 additions & 3 deletions Documentation/Architecture/CliContract.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,17 @@ Secondary resources remain explicit, such as `apple calendar events list`,
forward-draft/send/move/archive/delete.
- `messages`: conversations/messages search/read, iMessage send,
existing-chat conversation send, and explicit-recipient send-many.
- `maps`: place search/read, coordinate-aware directions, and open-in-Maps.
- `maps`: place search/read, saved favorite reads, collection lifecycle and existing
member links, route calculation and ETA,
coordinate-aware directions links, and open-in-Maps.
- `finder`: file listing, reveal/open, metadata/tag/search, move/trash/delete,
create-only text write, and single-file overwrite.
- `numbers`: document/sheet/table read, table CSV/TSV export, single-cell table
text write, document open, and QuickLook PDF/thumbnail/package export.
- `pages`: document read/open/export, including QuickLook
PDF/thumbnail/package export.
- `keynote`: presentation/slide read, slide image export, open, and QuickLook
PDF/thumbnail/package export.
- `keynote`: file/package metadata, native slide reads and PDF export, cached
preview reads/exports, open, and package copy.
- `facetime`: contact/call preparation and gated call initiation.
- `safari`: windows/tabs/current/read, profile, snapshot window, and Tab Group
snapshot reads including snapshot window mappings, bounded page text/source reads, state-action
Expand Down
58 changes: 48 additions & 10 deletions Documentation/Architecture/Clipboard/Architecture.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,64 @@
# Clipboard Architecture

`clipboard` owns local pasteboard workflows under `apple clipboard`.
`clipboard` owns the current macOS pasteboard under `apple clipboard`.

## Capability Maturity

Current level: `L0 Public Framework / SDEF / AppleScript`

Rationale: Clipboard currently uses NSPasteboard, a public system pasteboard
mechanism, for accepted read, write, and clear behavior. It does not currently
rely on a private pasteboard implementation mechanism.
Clipboard uses the public NSPasteboard and NSPasteboardItem APIs. Typed item
reads and replacement preserve item order, declared format order and raw bytes.
The target's capability list states the supported surface.

## Source Authority

NSPasteboard defines the accepted pasteboard type, read, write, and clear
behavior.
[NSPasteboard](https://developer.apple.com/documentation/appkit/nspasteboard)
and [NSPasteboardItem](https://developer.apple.com/documentation/appkit/nspasteboarditem)
define the pasteboard's ownership, representations and native conversions.

## Implementation Mechanisms

Clipboard uses NSPasteboard. It is a narrow system-domain target, not a broad
clipboard history or cross-device clipboard automation surface.
The backend uses the general pasteboard for CLI commands. It retains a
pasteboard name rather than sharing native item objects between operations.
Native items used for writes are fresh and unbound.

`types` returns metadata and an ownership counter. Legacy `read` retains
NSPasteboard's text selection and multi-item text joining behavior. `items read`
returns individual items, their native format order and base64 data. Unavailable
promised data stays unavailable; a missing representation is not empty data.

Byte caps bound accepted and returned raw representation data after AppKit
fetches it. AppKit obtains each complete representation from its provider;
these caps do not bound that provider's allocation or response time.

Replacement validates the entire payload before clearing the pasteboard.
Formats advertised by NSFilePromiseReceiver are rejected: their data contains
transfer metadata that requires a live provider to create the promised files.
Raw reads can inspect those bytes but do not accept or fulfill a file promise.
Write results require successful native writes, the requested item order,
format order and bytes, and unchanged ownership during readback. AppKit may
add compatibility formats. Complete identical payloads skip writing; RTF's
additional native plain-text formats permit a skip only when their decoded
text agrees with the RTF. Other extra formats require replacement.

Writes support `--current-host-only` through NSPasteboard's
`prepareForNewContents(with: .currentHostOnly)`. Contents options have no public
getter, so an explicit restriction always obtains new ownership, including
when the data is unchanged. Byte equality alone cannot verify that option.

The ownership counter and `--if-change-count` guard observable ownership
changes. NSPasteboard has no atomic compare-and-swap operation; an owner can
also supply promised data without changing that counter. These checks do not
provide an atomic content snapshot or reserve the pasteboard.

An unverified replacement reports an error with possible mutation, and does
not restore an old snapshot over a newer owner. Empty clear requests preserve
the counter and return `changed: false`. Programmatic reads follow the app's
macOS pasteboard access setting.

## Validation

Use command help and system-domain command tests. Detailed command status lives
in `CapabilityList.md`.
The SystemDomainCommandTests suite owns Clipboard contract regressions and
the opt-in native workflow. It uses a unique pasteboard, verifies native rich
text/image/URL consumers and checks empty cleanup before releasing it.
Detailed operating instructions live in the Developer Guide.
23 changes: 20 additions & 3 deletions Documentation/Architecture/Clipboard/CapabilityList.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,33 @@

## Source Authority

Clipboard capabilities are accepted from NSPasteboard behavior.
Clipboard capabilities follow public NSPasteboard and NSPasteboardItem behavior.

## Supported Capabilities

| Capability | CLI surface | Implementation mechanism | Gate / verifier / gap |
| --- | --- | --- | --- |
| Type/read | `types`, `read` | NSPasteboard | Sensitive bounded read. |
| Mutation | `write`, `clear` | NSPasteboard | Supports `--dry-run`; execution requires `--allow-persistent-action`. |
| Metadata | `types` | NSPasteboard | Type union and `changeCount`; no content output. |
| Text | `read [--type] [--max-bytes]` | NSPasteboard | Explicit sensitive read; UTF-8 byte cap; rejects changed ownership or unavailable declared text. |
| Typed items | `items read [--type] [--limit] [--max-bytes]` | NSPasteboardItem | Ordered items and representations, base64 bytes, unavailable data, total count and explicit filtered/truncated state. |
| Text replacement | `write --text` | Fresh NSPasteboardItem | Explicit empty text supported; size preflight, unchanged-state check and native readback. |
| Typed replacement | `items write --input` | Fresh NSPasteboardItems | Complete JSON payload/envelope; preserves declared order and bytes, reports native failures. Truncated, filtered, unavailable or file-promise snapshots cannot be replayed. |
| Device scope | `--current-host-only` on writes | NSPasteboard.ContentsOptions | Applies the current-device restriction when claiming new contents; renews ownership even for identical data. |
| Clear | `clear` | NSPasteboard | Empty no-op and native empty readback. |
| Conditional replacement | `--if-change-count` on writes/clear | Ownership counter | Refuses stale preconditions; does not reserve the pasteboard or provide atomic compare-and-swap. |
| Diagnostics | `doctor` | Metadata and macOS access behavior | Does not request content; exposes configured programmatic-read denial when available. |

All mutations support `--dry-run`; execution requires
`--allow-persistent-action`. Raw data defaults to 1 MiB with a 64 MiB ceiling.
Item reads default to 50 with a ceiling of 500. Oversized content produces an
error, not a partial successful representation.

## Rejected / Gated

- Clipboard history.
- Cross-device clipboard automation.
- Live file-promise transfer and drag-session ownership.

Consumers retain their own permission requirements for referenced file URLs.
Unique-pasteboard native validation does not prove general-pasteboard privacy
access or compatibility on other macOS versions.
Loading