- Apple silicon Mac
- macOS 26 or newer
- Swift 6.2 or newer
- Xcode command-line tools
The official provider apps are optional for normal tests. Installed-app and live-lifecycle checks are explicitly opt in.
Package targets and dependency versions are defined in Package.swift and Package.resolved.
swift build
swift test
./script/build_and_run.shApp packaging builds only the main app and shortcut launcher with two jobs by
default. Override AGENTDOCK_BUILD_JOBS to change build concurrency. The separate
transcript-renderer showcase remains available for development, and is not linked
into the main app.
Local ad-hoc builds leave SUPublicEDKey empty and disable update checks.
They omit hardened runtime because ad-hoc signatures have no Team ID for
embedded-framework library validation. Developer ID builds retain hardened
runtime and timestamped signing. To
exercise the configured updater with an existing public key, run:
AGENTDOCK_SPARKLE_PUBLIC_KEY='<base64-public-key>' ./script/build_app.sh
./script/package_app.shThe public key is not secret. Never place the private Sparkle key in a command argument, tracked file, build artifact, or ordinary development environment.
Use ./script/build_and_run.sh --verify to build, launch, and verify that the
app process exists. Build products and packages are written under ignored
.build/ and dist/ directories.
The dependency-free static site is stored under site/. Validate
it locally with:
./script/validate_site.sh
AGENTDOCK_SITE_NETWORK_VALIDATION=1 ./script/validate_site.sh
python3 -m http.server 8080 --directory siteThe first command validates local HTML, JavaScript, assets, release-link
fallbacks, accessibility hooks, and repository hygiene. The opt-in network
check resolves the current GitHub release and verifies that its DMG is
reachable. The local server exposes the site at http://localhost:8080 for
responsive browser testing.
Run the repository-wide privacy audit before a release or after changing build, packaging, or publication behavior:
brew install gitleaks # one-time prerequisite
./script/audit_privacy.shThe audit scans the complete Git history with redacted output, rejects tracked machine-specific home paths and sensitive file formats, and runs the website privacy checks. Release packaging separately rejects private build paths in the signed ZIP and DMG without echoing the matched path into logs.
Assets/AppIcon.png is the source of truth for both
the macOS app icon and the website icon. After changing that artwork, regenerate
the tracked .icns and website copy with:
./script/generate_app_icon.sh
./script/validate_site.shGitHub Pages serves the contents of the gh-pages branch. Website publication
is manual; do not add a push-to-main, pull-request, or dispatch workflow. The
release workflow preserves the existing website and publishes only the signed
Stable or Alpha appcast plus .nojekyll update metadata after immutable
release assets are available.
swift testThe package includes
core tests,
app-model tests,
transcript-renderer tests, and vendored
parser tests. Tests must use real repository-native behavior; do not add mocks
or stubs. App-model fixtures must supply a temporary officialDataRootURL so
standard-provider reads stay inside the fixture as well as managed-profile
reads.
Synthetic UI acceptance images can be rendered without reading signed-in accounts or launching provider applications:
AGENTDOCK_VISUAL_AUDIT_DIR=/tmp/agentdock-visual-audit swift test \
--filter ProfileSelectionIsolationTests/testSyntheticVisualAuditThis opt-in harness uses real temporary profile files and isolated preferences to render the home and overview surfaces in light and dark appearances at regular and compact sizes, including long profile names and a synthetic reset inventory. Home fixtures keep notification preferences and inventory inside an isolated defaults suite. It briefly presents synthetic windows and requires Screen Recording access for native window capture. Inspect the resulting images for hierarchy, clipping, contrast, and source identity; render completion alone is not visual acceptance.
The two-profile lifecycle check uses temporary profiles and verifies separate processes, persistence through restart, and preservation of the other profile and existing provider instances. Failed checks preserve temporary data for manual diagnosis and can leave test instances running; verify exact process ownership before cleanup. It opens installed provider applications:
AGENTDOCK_LIVE_ISOLATION_TEST=1 swift test --filter LiveProfileIsolationTestsThe Claude check also inspects bounded open-file metadata for each verified process tree before and after restart. It requires files under that profile's UserData and none under the default or sibling root; output contains counts only. A vanished startup helper triggers a fresh inventory, while a changed main process identity fails the check.
Installed-app checks:
AGENTDOCK_INSTALLED_APP_TEST=1 swift test --filter 'testOfficialInstalledCodexSignatureIsAccepted|testInstalledCodexAcceptsIsolatedMCPConfigurationWhenEnabled|testInstalledAppServerRespondsFromAnIsolatedHomeWhenEnabled'
AGENTDOCK_LIVE_LIFECYCLE=1 swift test \
--filter CodexLauncherTests/testLiveProfileCanOpenAndCloseWithoutTouchingStockInstance
AGENTDOCK_LIVE_EXISTING_CODEX_PROFILE=/path/to/active/profile swift test \
--filter CodexLauncherTests/testLiveExistingCodexProfileClosesAllOwnedProcessesWithoutTouchingStock
AGENTDOCK_INSTALLED_CLAUDE_TEST=1 swift test \
--filter ClaudeDesktopTests/testInstalledClaudeSignatureAndStartupContract
AGENTDOCK_CLAUDE_LIVE_LIFECYCLE=1 swift test \
--filter ClaudeDesktopTests/testLiveClaudeProfileCanOpenAndCloseWithoutTouchingStockThe installed Codex configuration check validates the signed app and runs its
bundled CLI against a temporary managed MCP configuration without account data.
The app-server check initializes the real bundled executable and sends a usage
request from a fresh temporary home, expecting the unauthenticated response.
Set AGENTDOCK_CODEX_APP_PATH or AGENTDOCK_CLAUDE_APP_PATH to test an alternate
signed bundle in the installed-app and live lifecycle/isolation checks. These
overrides leave the normally installed app in place.
Repeat it after provider updates. Both installed-profile checks and runtime
launches resolve the current nested CLI bundle with a legacy fallback.
The separate renderer showcase omits Codex accounting-only token_usage_record
events from presentation; unknown history events appear as unsupported records.
The main app has no chat browser. Its Claude activity summaries retain shared
bounded session scanning.
These checks can open installed provider applications or terminate the exact active managed profile named in the environment. Run them only on a Mac where that interaction is expected.
- Keep provider-specific discovery and parsing in
CodexerCore. - Keep transcript presentation provider-neutral and capability-gated.
- Preserve stable event identities and exact source order.
- Bound file inventories, subprocess output, transcript pages, and layout work.
- Validate paths and signatures immediately before security-sensitive actions.
- Update README or focused docs with user-visible behavior and contract changes.
- Never commit profiles, chats, logs, databases, credentials, screenshots with real data, or build artifacts.
See Contributing for the pull-request workflow. Release builds use build_app.sh and package_app.sh.
Run sequential production-reader measurements on the same Mac, retaining JSON output outside the repository:
./script/benchmark_resources.sh 0acab4c /tmp/agentdock-resource-results
AGENTDOCK_BENCHMARK_LIVE_QUOTA=1 ./script/benchmark_resources.sh 0acab4c /tmp/agentdock-resource-live-resultsThe opt-in command reads the official signed-in native account but prints only success counts and resource counters. It never records account identity, quota amounts, credentials, or provider content. Both runs use the same installed provider processes. Keep those processes and their workload stable. The runner compiles optimized baseline and current readers, adds identical count-only instrumentation to temporary copies, and runs baseline then candidate three times. It reports wall and CPU time, child CPU, physical footprint, interrupt and package-idle wakeups, disk I/O, actual child launches, and validation calls. Per-process disk counters can stay zero when filesystem data is cached; they do not count every file metadata lookup. Network byte counters are not available in this harness. These are reader measurements, not app idle or thermal proof.
A self-contained native SwiftUI probe exercises activation, multiple windows,
closing/reopening all windows, and rapid hide/return transitions. Compile
script/probe_application_lifecycle.swift with
Sources/Codexer/ApplicationActivityMonitor.swift and run it in a temporary
application bundle. Its JSON trace contains only lifecycle booleans and window
counts, comparing the original scene callback gate with the current app-level
monitor. It does not access provider data. Native notification presentation,
actual sleep/wake, and sustained app idle measurements remain separate gates.