- The UI requests profile creation through
CodexerModel. ProfileStoreallocates a provider-scoped slug, directory, ownership marker, and persisted profile record under a cross-process lock.- The selected launcher validates the official provider bundle and its signing identity.
- Before a new Codex launch, AgentDock closes any provider-signed orphan helper
whose live executable remains contained by that profile's
CODEX_HOME. - AgentDock resolves the persisted Codex launch selection to that managed
profile's own default, Built-in Codex, or a safe profile-local
<name>.config.toml. Named profiles are translated into bounded--configoverrides accepted by the desktop app-server command. The official account follows the same flow against~/.codex. - AgentDock starts a new provider instance with the profile-specific local state contract.
- Post-launch discovery verifies the returned process before the UI marks the profile as running.
Changing the selection for a running Codex profile closes that exact instance, persists the new choice, refreshes its shortcut, and reopens it. A missing or unsafe named profile fails before the running instance is closed.
Failed persistence or validation rolls back partial state where safe. A destructive delete uses a separate confirmation and fails closed while the profile is in use.
Removing a profile from the list preserves its ownership identity. Restoring that managed directory reuses the verified marker identifier, so an existing profile shortcut remains bound to the same profile.
DesktopInstanceControllerfinds candidates carrying the exact managed profile root.- AgentDock resolves and validates the signed main process and any provider-signed helper executable contained by the selected profile root.
- Focus activates only that PID.
- Close sends graceful termination only to verified processes for the selected profile, tracks captured descendants by stable process identity, and bounds the wait for cleanup.
The stock provider app and other managed profiles do not match the selected profile path.
- AgentDock reads the selected profile's bounded, regular, non-symlink
CODEX_HOME/config.toml. A missingmodel_providermeans the built-inopenaiprovider. - Native OpenAI profiles retain the signed bundled app-server flow and call
account/rateLimits/readwith the selectedCODEX_HOME. - For a selected custom provider, AgentDock resolves the matching
model_providers.<id>.base_urland requests its<base_url>/usagequota endpoint. - HTTPS is accepted. Plain HTTP is accepted only for loopback providers; redirects must remain on the same safe origin. Requests and responses are time- and size-bounded.
- Provider headers, environment-backed headers, bearer-token environment keys, and query parameters are applied in memory. Their values and response bodies are never logged or added to analytics.
- Returned allowance meters are validated and shown with their percentage consumed, window, and reset time. Seven-day windows use the same Weekly presentation as native Codex limits.
- A missing, unsafe, unsupported, or failed custom-provider usage endpoint is shown as unavailable for that provider. AgentDock never substitutes native OpenAI quota for traffic sent to another provider.
AgentDock has no chat browser, transcript paging UI, transcript-copying action, or five-second chat change monitor. Automatic activity and process-status polling skip inactive periods. Native reset reminders continue to operate in the background independently of activity settings.
ProfileStatsScannerreads supported Codex databases for local activity and token statistics.- Claude summaries use shared
LocalChatSessionreaders for supported local Cowork/agent-session sources and, for the official installation, supported Claude Code history/session sources. - These readers validate source roots, reject symlinks, bound file counts and bytes, and use no-follow reads. Claude activity and usage summaries are cached in memory; the app no longer writes chat-browser indexes.
Removing the browser does not eliminate Claude local history reads needed for activity and token summaries.
For official and managed Claude sources, the same validated Cowork audit
sources also feed an in-memory usage summary. Assistant token records are
deduplicated by their message/request identity before aggregation, scans are
byte-bounded and cached by source size and modification time, and model totals
remain source-scoped. The overview uses the same usage and activity components
for both source types and lists the official installation beside managed
accounts for quick comparison and selection.
Claude rate_limit_event records contribute only their latest observed status,
bucket, reset time, and optional utilization. Missing utilization stays missing;
AgentDock does not carry an older percentage into a newer limit window.
Live Claude quota refresh is a separate flow:
- Official Claude uses the official Desktop OAuth cache exclusively. Managed profiles use only their own Desktop user-data root. A separate Claude Code login cannot replace the account displayed for Desktop.
- Background refresh reads Keychain without interaction. Manual refresh may request access to Claude Safe Storage.
- The active account and organization are resolved locally and verified with Anthropic before the usage response is assigned to a source.
- Access tokens remain in memory and are never copied, refreshed, persisted, or logged by AgentDock.
- HTTP 429 responses create a credential-scoped cooldown and retain only the last successful in-memory snapshot for that same login.
Older browser versions may have left metadata-only indexes containing no full transcript bodies or tool output. Explicit profile removal or deletion cleans up that profile's legacy indexes. Partial source coverage remains explicit in the activity summary.
- An undecided installation sends nothing and has no analytics identifier.
- When delivery is configured, the app asks for consent. An explicit grant creates a random UUID unrelated to local or provider data; denial exits without a payload, network request, or identifier.
- Call sites submit closed enum events to the single core boundary.
- The boundary validates properties, adds minimal platform context, disables GeoIP/person profiles, and holds at most 48 events in memory.
- Up to twelve events are sent in a bounded HTTPS batch after at most five seconds, with only one active delivery at a time. Failures are dropped without persistent retries or raw error logging.
- Opt-out synchronously purges pending events and deletes the UUID; re-enabling creates an unlinkable replacement.
No profile, provider-account, chat, transcript, session, filesystem, command, configuration, raw error, log, or crash content enters this flow.
- AgentDock validates the selected profile and official provider app.
ShortcutInstallercreates a native helper bundle in a temporary sibling.- The shortcut configuration is bound to the profile ownership marker.
- The completed shortcut atomically replaces the prior bundle under
~/Applications/AgentDock/.
- A
vMAJOR.MINOR.PATCHtag starts a Stable release. A successfulQualityrun for a push tomainstarts a ten-minute coalescing window, then creates and dispatches an immutable Alpha tag for the latest tested revision. - Stable releases run the full Swift test suite. Alpha releases reuse the
successful
Qualityresult for the exact tagged commit. - A production app is built with hardened runtime and a Developer ID signature.
- Sparkle.framework, its updater helper, and its XPC services are signed from the inside out before the outer app is signed.
- The app and DMG are submitted to Apple notarization and stapled.
- Gatekeeper, code-signature, DMG integrity, ZIP sidecar, and build-path privacy checks run before publication.
- GitHub Releases receives the ZIP, DMG, and SHA-256 checksum file using package_app.sh.
- Only after the immutable release ZIP exists, Sparkle's
generate_appcastsigns an enclosure pointing at that tagged asset. The signed appcast is the final publication, asappcast.xmlfor Stable orappcast-alpha.xmlfor Alpha on thegh-pagesbranch.
No release credential is stored in the repository or packaged artifact.