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
Binary file added .github/assets/logo/logo-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added .github/assets/logo/logo-light.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions .github/assets/terminal/recording.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"title": "Preview a notification with apple-cli",
"steps": [
{
"command": "apple --version",
"output": "0.1.0"
},
{
"command": "apple notifications preview --title Build --body Done --json --pretty",
"output": "{\n \"data\" : {\n \"externalAction\" : false,\n \"notification\" : {\n \"body\" : \"Done\",\n \"title\" : \"Build\"\n }\n },\n \"meta\" : {\n \"target\" : \"notifications\"\n },\n \"ok\" : true,\n \"warnings\" : [\n\n ]\n}"
}
]
}
5 changes: 5 additions & 0 deletions .github/assets/terminal/script.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
title: Preview a notification with apple-cli
executable: apple
steps:
- run: apple --version
- run: apple notifications preview --title Build --body Done --json --pretty
91 changes: 91 additions & 0 deletions .github/assets/terminal/terminal-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
91 changes: 91 additions & 0 deletions .github/assets/terminal/terminal-light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 0 additions & 18 deletions .github/brand/brand.lock.json

This file was deleted.

Binary file removed .github/brand/social.png
Binary file not shown.
25 changes: 19 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ on:
push:
branches: [master]
pull_request:
types: [opened, synchronize, reopened]
workflow_dispatch:

permissions:
contents: read

concurrency:
group: ci-${{ github.ref }}
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

jobs:
Expand All @@ -31,10 +32,10 @@ jobs:
key: dependencies-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('Package.resolved') }}
- name: Build, test and stage the release candidate
run: |
Scripts/validate-public-content
scripts/validate-public-content
python3 -B -m unittest discover -s Tests/ReleaseTools
Scripts/package-release --jobs 2
Scripts/verify-release --run-tests
scripts/package-release --jobs 2
scripts/verify-release --run-tests
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: apple-cli-macos-arm64-candidate-${{ github.run_id }}-${{ github.run_attempt }}
Expand All @@ -47,5 +48,17 @@ jobs:
name: validation-logs-${{ github.run_id }}-${{ github.run_attempt }}
path: .build/release-validation
if-no-files-found: ignore
brand:
uses: computer-mcp/.github/.github/workflows/brand-check.yml@f402911abcdfb87ef0c41a2759e8c51387b18935 # master
demo:
needs: package
uses: computer-mcp/github-workflows/.github/workflows/terminal-demo.yml@53ecce59bf7ed184528b2f7894c864f338932d37
with:
artifact: apple-cli-macos-arm64-candidate-${{ github.run_id }}-${{ github.run_attempt }}
archive: apple-cli-*-macos-arm64.tar.gz
executable: apple-cli-*-macos-arm64/bin/apple
runner: xcode-27
validate:
if: always()
needs: [package, demo]
uses: computer-mcp/github-workflows/.github/workflows/result.yml@53ecce59bf7ed184528b2f7894c864f338932d37
with:
needs-json: ${{ toJSON(needs) }}
18 changes: 4 additions & 14 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,6 @@ on:
permissions:
contents: read

concurrency:
group: release-${{ inputs.tag || github.ref_name }}
cancel-in-progress: false

jobs:
build:
runs-on: xcode-27
Expand All @@ -34,21 +30,15 @@ jobs:
ref: ${{ inputs.tag || github.ref }}
fetch-depth: 0
persist-credentials: false
- uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: |
.build/repositories
.build/checkouts
key: dependencies-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('Package.resolved') }}
- name: Build and accept the tagged archive
id: candidate
env:
RELEASE_TAG: ${{ inputs.tag || github.ref_name }}
run: |
Scripts/validate-public-content
scripts/validate-public-content
python3 -B -m unittest discover -s Tests/ReleaseTools
Scripts/package-release --tag "$RELEASE_TAG" --jobs 2
Scripts/verify-release --tag "$RELEASE_TAG" --run-tests --github-output
scripts/package-release --tag "$RELEASE_TAG" --jobs 2
scripts/verify-release --tag "$RELEASE_TAG" --run-tests --github-output
printf 'artifact_name=%s\n' "$CANDIDATE_ARTIFACT" >> "$GITHUB_OUTPUT"
- uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
Expand Down Expand Up @@ -85,4 +75,4 @@ jobs:
GH_TOKEN: ${{ github.token }}
RELEASE_TAG: ${{ needs.build.outputs.tag }}
RELEASE_SOURCE_COMMIT: ${{ needs.build.outputs.source_commit }}
run: Scripts/publish-release
run: scripts/publish-release
19 changes: 19 additions & 0 deletions .github/workflows/source-policy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
name: Source policy checks
on:
pull_request:
types: [opened, synchronize, reopened, edited]
push:
branches: [master]
merge_group:
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true
jobs:
policy:
uses: computer-mcp/github-workflows/.github/workflows/policy.yml@53ecce59bf7ed184528b2f7894c864f338932d37
with:
declaration-revision: 5c54a40cb7953db7472ebbefd3db608036b7b3ab
path-exceptions: |
Tests/ReleaseTools/test_public_content.py
6 changes: 0 additions & 6 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,12 +178,6 @@ Current architecture truth lives in `Documentation/Architecture/`:
facts into architecture truth. External sources are inputs for target-local
reuse decisions, not the source of this repository's architecture.

## Brand Delivery

README headers and the social preview come from the Computer MCP organization
`.github` repository through `.github/brand/brand.lock.json`. Update them only
with that repository's `python3 Brand/brand.py sync`; CI verifies the lock.

## Implementation Boundary

Keep target ownership independent. The package declares exactly two executable
Expand Down
13 changes: 10 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ changes that touch scripts, tests, package manifests, or generated package
contents, also run the repository package validation commands.

```bash
Scripts/validate-public-content
Scripts/validate-version
scripts/validate-public-content
scripts/validate-version
python3 -B -m unittest discover -s Tests/ReleaseTools
Scripts/bootstrap
scripts/bootstrap
xcrun swift build --force-resolved-versions
xcrun swift test --force-resolved-versions
```
Expand All @@ -69,3 +69,10 @@ texts and `THIRD_PARTY_NOTICES.md` together. Version selection follows
[VERSIONING](VERSIONING.md).
See the [release reference](Documentation/Reference/Release.md) for candidate packaging,
compatibility evidence and publishing boundaries.

## Source Policy Exceptions

`Tests/ReleaseTools/test_public_content.py` contains synthetic home-directory
paths to verify that public-content validation rejects machine-local paths in
documents and release artifacts while allowing test fixtures. The source policy
exempts this file from path checks; attribution checks still apply.
Binary file removed Documentation/Brand/header-dark.png
Binary file not shown.
Binary file removed Documentation/Brand/header-light.png
Binary file not shown.
2 changes: 1 addition & 1 deletion Documentation/Reference/AppleCLIUserGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ apple <target> <resource?> <action> --help
When running from a development checkout, use:

```bash
Scripts/bootstrap
scripts/bootstrap
swift run apple --help
swift run apple <target> --help
```
Expand Down
6 changes: 3 additions & 3 deletions Documentation/Reference/FrameworkGeneration.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ names. Their generation commands share an Objective-C declaration merger and
retain separate module configurations:

```bash
Scripts/notes-private-framework-normalize-full-dump --dump-root <dump-root> --sources-root <sources-root>
Scripts/reminderkit-normalize-full-dump --dump-root <dump-root> --sources-root <sources-root>
scripts/notes-private-framework-normalize-full-dump --dump-root <dump-root> --sources-root <sources-root>
scripts/reminderkit-normalize-full-dump --dump-root <dump-root> --sources-root <sources-root>
```

Notes generates `NotesSupport`, `NotesHTML`, `NotesShared`, `NotesUI`,
Expand All @@ -20,7 +20,7 @@ Use exactly one of `--dump-root` and `--input-manifest`. A versioned manifest
follows [FrameworkInputManifest.schema.json](FrameworkInputManifest.schema.json):

```bash
Scripts/notes-private-framework-normalize-full-dump \
scripts/notes-private-framework-normalize-full-dump \
--input-manifest <manifest.json> \
--sources-root <sources-root> \
--report <diagnostic-report.json>
Expand Down
4 changes: 2 additions & 2 deletions Documentation/Reference/Notes/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ checks, and post-write verification. Direct Notes SQLite writes are rejected.
The current intake path follows the Reminders pattern:

```bash
Scripts/notes-private-framework-normalize-full-dump \
scripts/notes-private-framework-normalize-full-dump \
--dump-root <ipsw-class-dump-root> \
--sources-root Sources
```
Expand All @@ -58,7 +58,7 @@ when direct linking needs SDK allowed-client metadata removed. The overlays
must preserve system framework install names and should be audited before
production code relies on direct typed private class references.

From the repository root, run `Scripts/bootstrap` before the first build.
From the repository root, run `scripts/bootstrap` before the first build.
The default Notes target links the generated framework stub overlay at
`.build/notes-private-framework-link-stubs/current`. Bootstrap uses the selected
Xcode SDK, preserves system install names, and records SDK/toolchain and input
Expand Down
2 changes: 1 addition & 1 deletion Documentation/Reference/Photos/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The current command surface and safety gates are documented in
From the repository root, run:

```bash
Scripts/bootstrap
scripts/bootstrap
xcrun swift test --filter Photos --force-resolved-versions
```

Expand Down
40 changes: 20 additions & 20 deletions Documentation/Reference/Release.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
# Release

Release status: packaging, archive acceptance and GitHub publication are
implemented by [package-release](https://github.com/computer-mcp/apple-cli/blob/master/Scripts/package-release),
[verify-release](https://github.com/computer-mcp/apple-cli/blob/master/Scripts/verify-release),
[publish-release](https://github.com/computer-mcp/apple-cli/blob/master/Scripts/publish-release)
implemented by [package-release](https://github.com/computer-mcp/apple-cli/blob/master/scripts/package-release),
[verify-release](https://github.com/computer-mcp/apple-cli/blob/master/scripts/verify-release),
[publish-release](https://github.com/computer-mcp/apple-cli/blob/master/scripts/publish-release)
and the [release workflow](https://github.com/computer-mcp/apple-cli/blob/master/.github/workflows/release.yml).
Version selection, compatibility review and tag signature verification are
manual.
Expand All @@ -19,7 +19,7 @@ dependencies and target-specific validation limits.

| Shipped component | Version meaning | Version source | Mirrors and derived fields | Update and read-only check |
| --- | --- | --- | --- | --- |
| `apple` and its target commands | Shared product version | `CLIVersion.current` in `Sources/Utility/CLIVersion.swift` | `apple --version`, archive identity and provenance | Edit the declaration manually; `Scripts/validate-version`; `CLIExecutableTests` |
| `apple` and its target commands | Shared product version | `CLIVersion.current` in `Sources/Utility/CLIVersion.swift` | `apple --version`, archive identity and provenance | Edit the declaration manually; `scripts/validate-version`; `CLIExecutableTests` |
| `apple-cli-mcp` | Same product version | The same `CLIVersion.current` | `apple-cli-mcp --version`, MCP initialization `serverInfo.version` | Same declaration; `CLIExecutableTests`, `AppleMCPAdapterTests` and `MCPExecutableTests` |

Both executable products release together. Target modules and source skills
Expand Down Expand Up @@ -100,17 +100,17 @@ and need compatibility, lockfile and dependency-notice review.
| Field or artifact | Authority and production | Read-only verification |
| --- | --- | --- |
| Executable version and MCP `serverInfo.version` | Compiled from `CLIVersion.current` | Executable and MCP initialization tests; packager checks both staged `--version` results |
| Release notes | Matching entry in `CHANGELOG.md`; publisher renders that entry and source/Actions links | `Scripts/validate-version [--tag TAG]` and publisher input validation |
| Archive basename | `apple-cli-VERSION-macos-arm64`, derived by `Scripts/package-release` | `Scripts/verify-release` compares names, source version, tag and architecture |
| Release notes | Matching entry in `CHANGELOG.md`; publisher renders that entry and source/Actions links | `scripts/validate-version [--tag TAG]` and publisher input validation |
| Archive basename | `apple-cli-VERSION-macos-arm64`, derived by `scripts/package-release` | `scripts/verify-release` compares names, source version, tag and architecture |
| `.provenance.json` and embedded `provenance.json` | Packager records source commit/tree, lock digest and dependencies, environment, link inputs, linked libraries, run paths, binary/runtime hashes and successful validation-log hashes | Verifier checks source identity, lock digest, required checks, archive contents and embedded/adjacent manifest equality, apart from the adjacent archive digest |
| `.tar.gz.sha256` | Packager hashes the archive bytes | Verifier recomputes the archive digest and exact checksum contents |
| `.verification.json` | `Scripts/verify-release --run-tests` records archive/provenance/checksum hashes, checker hash, tested environment, successful checks and test-log digest; Actions adds run identity | `Scripts/verify-release --require-verification` checks identity, hashes, required checks and positive test/suite counts |
| `.verification.json` | `scripts/verify-release --run-tests` records archive/provenance/checksum hashes, checker hash, tested environment, successful checks and test-log digest; Actions adds run identity | `scripts/verify-release --require-verification` checks identity, hashes, required checks and positive test/suite counts |

Provenance and verification receipts use `schema_version: 1`. Provenance also
records a build timestamp. Build timestamps and compiler output can vary; the
packager does not claim bit-for-bit rebuilds.

[Scripts/validate-version](https://github.com/computer-mcp/apple-cli/blob/master/Scripts/validate-version)
[scripts/validate-version](https://github.com/computer-mcp/apple-cli/blob/master/scripts/validate-version)
requires exactly one canonical declaration in the supported version format.
For untagged validation, a changelog whose sole section is `Unreleased` may be
empty. Otherwise it requires exactly one nonempty entry for the product
Expand All @@ -131,17 +131,17 @@ repository, source, artifact or receipt identity fails validation.
then run the source gates:

```bash
Scripts/validate-version --json
Scripts/validate-public-content
scripts/validate-version --json
scripts/validate-public-content
python3 -B -m unittest discover -s Tests/ReleaseTools
```

2. Commit the complete candidate, including the lockfile, project license and
dependency notices. From its clean checkout, build and accept the archive:

```bash
Scripts/package-release --jobs 2
Scripts/verify-release --run-tests
scripts/package-release --jobs 2
scripts/verify-release --run-tests
```

The packager bootstraps SDK link inputs, builds tests, runs default
Expand All @@ -168,8 +168,8 @@ repository, source, artifact or receipt identity fails validation.
to both shared steps:

```bash
Scripts/package-release --tag vVERSION --jobs 2
Scripts/verify-release --tag vVERSION --run-tests
scripts/package-release --tag vVERSION --jobs 2
scripts/verify-release --tag vVERSION --run-tests
```

Packaging creates no tag, remote push or GitHub release. CI runs the source
Expand All @@ -190,7 +190,7 @@ repository, source, artifact or receipt identity fails validation.
prerelease flag. The publication step does not rebuild or re-sign.

The release scripts require Python 3.12 or newer for archive validation.
`Scripts/verify-release --require-verification` checks accepted files and the
`scripts/verify-release --require-verification` checks accepted files and the
receipt without executing macOS programs, as used by the Linux publisher.
Local candidate acceptance is development evidence; formal publication requires
the release workflow's accepted files and run identity. Installation and
Expand Down Expand Up @@ -243,12 +243,12 @@ values.

| Operation | Existing command or explicit manual procedure | Required access |
| --- | --- | --- |
| Version update and check | Manually edit `CLIVersion.current` and changelog; `Scripts/validate-version [--tag TAG] [--json]`. Automated version selection/update is not established. | Source write for edits; read for validation |
| Source/documentation checks | `Scripts/validate-public-content`; `python3 -B -m unittest discover -s Tests/ReleaseTools` | Source read; temporary fixture writes; Swift toolchain |
| Candidate validation and build | `Scripts/package-release [--output DIRECTORY] [--tag TAG] [--jobs COUNT]`, then `Scripts/verify-release [--directory DIRECTORY] [--tag TAG] --run-tests` | Clean source; native macOS arm64, Xcode/SDK and writable build output |
| Existing accepted-file check | `Scripts/verify-release [--directory DIRECTORY] [--tag TAG] --require-verification` | Clean matching source and artifact read; Python 3.12+ |
| Version update and check | Manually edit `CLIVersion.current` and changelog; `scripts/validate-version [--tag TAG] [--json]`. Automated version selection/update is not established. | Source write for edits; read for validation |
| Source/documentation checks | `scripts/validate-public-content`; `python3 -B -m unittest discover -s Tests/ReleaseTools` | Source read; temporary fixture writes; Swift toolchain |
| Candidate validation and build | `scripts/package-release [--output DIRECTORY] [--tag TAG] [--jobs COUNT]`, then `scripts/verify-release [--directory DIRECTORY] [--tag TAG] --run-tests` | Clean source; native macOS arm64, Xcode/SDK and writable build output |
| Existing accepted-file check | `scripts/verify-release [--directory DIRECTORY] [--tag TAG] --require-verification` | Clean matching source and artifact read; Python 3.12+ |
| Status and interrupted-run recovery | Inspect the Actions run and artifact manually; rerun its failed publication job with the original accepted files. A standalone status/recovery command is not established. | Actions read; workflow rerun permission |
| Acceptance and publication | Existing-tag release workflow; its publish job invokes `Scripts/publish-release [--directory DIRECTORY]` | Workflow environment, accepted artifact and scoped GitHub release write |
| Acceptance and publication | Existing-tag release workflow; its publish job invokes `scripts/publish-release [--directory DIRECTORY]` | Workflow environment, accepted artifact and scoped GitHub release write |
| Cleanup | Manually inventory and remove owned reproducible output; no cleanup command is established. | Write access to the owned output |

Output defaults to `.build/releases`. One verification directory contains just
Expand Down
2 changes: 1 addition & 1 deletion Documentation/Reference/ReleaseGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Keep the same selected Xcode for bootstrap and build. `DEVELOPER_DIR`, when set,
selects it for both scripts and `xcrun` commands.

```bash
Scripts/bootstrap
scripts/bootstrap
xcrun swift build --force-resolved-versions
xcrun swift test --force-resolved-versions
xcrun swift build -c release --force-resolved-versions
Expand Down
2 changes: 1 addition & 1 deletion Documentation/Reference/Reminders/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Ordinary usage lives in `UserGuide.md`.

## Framework Header Generation

`Scripts/reminderkit-normalize-full-dump` generates the official `ReminderKit`
`scripts/reminderkit-normalize-full-dump` generates the official `ReminderKit`
and `ReminderKitInternal` module surfaces from one dump or a digest-checked
versioned input manifest. It shares declaration merging and complete output
publication with the Notes generation command. See [Framework Header Generation](../FrameworkGeneration.md)
Expand Down
2 changes: 1 addition & 1 deletion Documentation/Reference/Safari/DeveloperGuide.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ listed in [Capability List](../../Architecture/Safari/CapabilityList.md).
## Package-Local Tests

```bash
Scripts/bootstrap
scripts/bootstrap
xcrun swift test --filter Safari --force-resolved-versions
```

Expand Down
Loading
Loading