{"aiTooling":{"contributorOverrideExamplePath":"llm/project-ai/local-overrides.example.json","contributorOverridePath":"llm/project-ai/local-overrides.json","docsGuideSlug":"ai-tooling-and-mcp","llmManifestPath":"llm/manifest.json","machineReadablePath":"/api/admin-cli.json","openAPIPath":"/api/openapi.json","projectDefaultsAPIPath":"/api/ai/defaults.json","projectDefaultsPath":"llm/project-ai/defaults.json"},"commands":[{"arguments":[{"description":"Email for the first super admin operator.","name":"email","required":true}],"audiences":["admin","backend"],"commonness":"core","description":"Creates the first operator account, provisions TOTP, and returns recovery codes. This only works before any operator account exists.","examples":["./bin/admin-local operator bootstrap ops@example.com --display-name \"Primary Operator\""],"group":"operator","key":"operator bootstrap","mutating":true,"options":[{"description":"Display name to store on the new operator account.","flag":"--display-name","valueHint":"\"Primary Operator\""},{"description":"Password for the operator account. If omitted, the CLI will prompt.","flag":"--password","valueHint":"super-secret-password"}],"outputSummary":"Returns the created operator account, TOTP secret/provisioning URI, and one-time recovery codes.","productionSafe":true,"relatedAPI":["GET /api/admin/session","POST /api/admin/session/sign-in"],"slug":"operator-bootstrap","summary":"Bootstrap the first operator","useWhen":"Use this once when bringing up the operator platform in a fresh environment."},{"arguments":[{"description":"Operator email to authenticate.","name":"email","required":true}],"audiences":["admin","backend","ops"],"commonness":"core","description":"Signs in an operator account, verifies password plus TOTP or recovery code, and stores a local CLI session for the current environment.","examples":["./bin/admin-local operator login ops@example.com","./bin/admin-local operator login ops@example.com --password secret --otp 123456"],"group":"operator","key":"operator login","mutating":true,"options":[{"description":"Operator password. If omitted, the CLI will prompt.","flag":"--password","valueHint":"super-secret-password"},{"description":"Current TOTP code from the authenticator app.","flag":"--otp","valueHint":"123456"},{"description":"One-time recovery code to use instead of a TOTP code.","flag":"--recovery-code","valueHint":"ABCD-EF12"}],"outputSummary":"Returns the authenticated operator profile and session expiration.","productionSafe":true,"relatedAPI":["POST /api/admin/session/sign-in"],"slug":"operator-login","summary":"Login as an operator","useWhen":"Use this before any authenticated admin CLI work in a shell environment."},{"arguments":[],"audiences":["admin","backend","ops","support"],"commonness":"core","description":"Reads the active operator session stored for the current environment and verifies it against the backend session store.","examples":["./bin/admin-local operator whoami"],"group":"operator","key":"operator whoami","mutating":false,"outputSummary":"Returns the authenticated operator account and current session metadata.","productionSafe":true,"relatedAPI":["GET /api/admin/session"],"slug":"operator-whoami","summary":"Show current operator session","useWhen":"Use this to confirm which operator account is active before running support or ops commands."},{"arguments":[],"audiences":["admin","backend","ops","support"],"commonness":"core","description":"Revokes the active operator session stored for the current environment and removes the local CLI session file entry.","examples":["./bin/admin-local operator logout"],"group":"operator","key":"operator logout","mutating":true,"outputSummary":"Returns the environment that was signed out and whether a local session existed.","productionSafe":true,"relatedAPI":["POST /api/admin/session/sign-out"],"slug":"operator-logout","summary":"Logout the current operator","useWhen":"Use this when leaving a shell session or rotating between staging and production operator identities."},{"arguments":[],"audiences":["admin","backend"],"commonness":"common","description":"Lists all operator accounts and their current scopes.","examples":["./bin/admin-local operator list-accounts"],"group":"operator","key":"operator list-accounts","mutating":false,"outputSummary":"Returns every operator account with status and assigned scopes.","productionSafe":true,"relatedAPI":["GET /api/admin/operators"],"requiredScopes":["operator.admin.manage"],"slug":"operator-list-accounts","summary":"List operator accounts","useWhen":"Use this when auditing current internal access or confirming the scope layout in one environment."},{"arguments":[{"description":"Email for the new operator account.","name":"email","required":true}],"audiences":["admin","backend"],"commonness":"common","description":"Creates an additional operator account, provisions TOTP, and returns one-time recovery codes for secure handoff.","examples":["./bin/admin-local operator create-account support@example.com --display-name \"Support Lead\" --bundle support_admin"],"group":"operator","key":"operator create-account","mutating":true,"options":[{"description":"Display name to store on the new operator account.","flag":"--display-name","valueHint":"\"Support Lead\""},{"description":"Scope bundle to apply in addition to any explicit scopes.","flag":"--bundle","valueHint":"support_admin"},{"description":"Explicit scope to add. Pass multiple times to build a custom set.","flag":"--scope","valueHint":"operator.users.read"},{"description":"Password for the new operator account. If omitted, the CLI will prompt.","flag":"--password","valueHint":"temporary-password"}],"outputSummary":"Returns the created operator account, TOTP provisioning details, and one-time recovery codes.","productionSafe":true,"relatedAPI":["POST /api/admin/operators"],"requiredScopes":["operator.admin.manage"],"slug":"operator-create-account","summary":"Create an operator account","useWhen":"Use this to onboard a support or ops contributor with a scoped internal identity."},{"arguments":[{"description":"Operator account ID to update.","name":"operatorAccountID","required":true}],"audiences":["admin","backend"],"commonness":"common","description":"Replaces the scopes on an operator account from a bundle and optional explicit scopes.","examples":["./bin/admin-local operator set-scopes 8a50b2d0-8c30-4d4b-a6ac-dcbabca9b4c2 --bundle ops_admin"],"group":"operator","key":"operator set-scopes","mutating":true,"options":[{"description":"Scope bundle to apply in addition to any explicit scopes.","flag":"--bundle","valueHint":"ops_admin"},{"description":"Explicit scope to add. Pass multiple times to build a custom set.","flag":"--scope","valueHint":"operator.audit.read"}],"outputSummary":"Returns the updated operator profile with its final scope set.","productionSafe":true,"relatedAPI":["POST /api/admin/operators/:operatorID/scopes"],"requiredScopes":["operator.admin.manage"],"slug":"operator-set-scopes","summary":"Replace operator scopes","useWhen":"Use this when access needs to be expanded, tightened, or standardized after onboarding."},{"arguments":[{"description":"Operator account ID to rotate.","name":"operatorAccountID","required":true}],"audiences":["admin","backend"],"commonness":"common","description":"Rotates an operator password and revokes that operator’s existing sessions.","examples":["./bin/admin-local operator rotate-password 8a50b2d0-8c30-4d4b-a6ac-dcbabca9b4c2"],"group":"operator","key":"operator rotate-password","mutating":true,"options":[{"description":"New password for the operator account. If omitted, the CLI will prompt.","flag":"--password","valueHint":"new-password"}],"outputSummary":"Returns the updated operator profile after password rotation and session revocation.","productionSafe":true,"relatedAPI":["POST /api/admin/operators/:operatorID/password-rotate"],"requiredScopes":["operator.admin.manage"],"slug":"operator-rotate-password","summary":"Rotate an operator password","useWhen":"Use this when credentials need to be changed proactively or after suspected compromise."},{"arguments":[{"description":"Operator account ID to reset.","name":"operatorAccountID","required":true}],"audiences":["admin","backend"],"commonness":"common","description":"Regenerates TOTP provisioning details and one-time recovery codes, revoking that operator’s active sessions.","examples":["./bin/admin-local operator reset-totp 8a50b2d0-8c30-4d4b-a6ac-dcbabca9b4c2"],"group":"operator","key":"operator reset-totp","mutating":true,"outputSummary":"Returns the operator profile plus replacement TOTP and recovery-code material.","productionSafe":true,"relatedAPI":["POST /api/admin/operators/:operatorID/totp-reset"],"requiredScopes":["operator.admin.manage"],"slug":"operator-reset-totp","summary":"Reset operator TOTP","useWhen":"Use this when an operator loses access to their authenticator app or recovery codes."},{"arguments":[{"description":"Primary email for the target account.","name":"email","required":true}],"audiences":["support","backend"],"commonness":"core","description":"Reads the current local credential, local user, legacy Firebase state, and active lockout windows for one account.","examples":["./bin/admin-local auth show-auth-state skier@example.com","./bin/admin-production auth show-auth-state skier@example.com"],"group":"auth","key":"auth show-auth-state","mutating":false,"outputSummary":"Returns a JSON object with local user state, local credentials, legacy migration readiness, and lockout windows.","productionSafe":true,"relatedAPI":["GET /api/auth/sign-in","GET /api/user"],"slug":"auth-show-auth-state","summary":"Inspect auth state","useWhen":"Use this first when a user cannot sign in, when validating legacy migration readiness, or before running any auth-repair command."},{"arguments":[{"description":"Primary email for the legacy account to materialize locally.","name":"email","required":true}],"audiences":["support","backend"],"commonness":"core","description":"Materializes a legacy Firebase credential into the owned auth system so future sign-ins use the local auth path.","examples":["./bin/admin-local auth migrate-user legacy@example.com","./bin/admin-production auth migrate-user legacy@example.com"],"group":"auth","key":"auth migrate-user","mutating":true,"outputSummary":"Returns the materialization result plus the post-migration auth-state snapshot.","productionSafe":true,"relatedAPI":["POST /api/auth/sign-in"],"slug":"auth-migrate-user","summary":"Migrate a legacy auth user","useWhen":"Use this when support needs to proactively materialize a legacy account before the user signs in again."},{"arguments":[{"description":"Primary email for the locked account.","name":"email","required":true}],"audiences":["support","backend"],"commonness":"core","description":"Clears auth lockout windows for an account, optionally narrowed to one IP address.","examples":["./bin/admin-local auth unlock-user skier@example.com","./bin/admin-local auth unlock-user skier@example.com --ip 203.0.113.10"],"group":"auth","key":"auth unlock-user","mutating":true,"options":[{"description":"Optional IP address to clear only one lockout window instead of all windows for the email.","flag":"--ip","valueHint":"203.0.113.10"}],"outputSummary":"Returns the number of cleared windows and any remaining windows still on record.","productionSafe":true,"relatedAPI":["POST /api/auth/sign-in"],"slug":"auth-unlock-user","summary":"Unlock a user","useWhen":"Use this when repeated failed sign-ins or automated retries have triggered account lockout windows."},{"arguments":[{"description":"Primary email for the new test/support user.","name":"email","required":true}],"audiences":["support","backend","admin"],"commonness":"core","description":"Creates a real local product user with password auth, baseline profile state, and an optional membership preset for QA or support reproduction.","examples":["./bin/admin-local users create-account qa-demo@yopmail.com --display-name \"QA Demo\" --preset pro_member --justification \"Admin QA validation\""],"group":"users","key":"users create-account","mutating":true,"options":[{"description":"Display name for the new user. Defaults from the email local-part.","flag":"--display-name","valueHint":"\"QA Demo\""},{"description":"Password to set. If omitted, the CLI generates and returns a strong one-time password.","flag":"--password","valueHint":"temporary-password"},{"defaultValue":"blank","description":"Optional test-state preset: blank, ready_for_field, pro_member, or lifetime_member.","flag":"--preset","valueHint":"pro_member"},{"description":"Human-readable reason for creating the account. Stored in the operator audit log.","flag":"--justification","valueHint":"\"Admin QA validation\""}],"outputSummary":"Returns the created user profile, support summary, chosen preset, and the one-time credentials needed to sign in.","productionSafe":true,"relatedAPI":["POST /api/admin/users","POST /api/auth/register"],"slug":"users-create-account","summary":"Create a test user","useWhen":"Use this when QA or support needs a fresh local account with predictable baseline state and optional paid membership seeding."},{"arguments":[{"description":"Primary email for the target user.","name":"email","required":true}],"audiences":["support","backend"],"commonness":"core","description":"Returns the local user record, current settings envelope, and support-summary snapshot in one JSON payload.","examples":["./bin/admin-local users show-profile rider@example.com"],"group":"users","key":"users show-profile","mutating":false,"outputSummary":"Returns local user identity, settings, and support-summary data.","productionSafe":true,"relatedAPI":["GET /api/user","GET /api/user/settings","GET /api/user/support-summary"],"slug":"users-show-profile","summary":"Inspect a user profile","useWhen":"Use this when support needs a full account snapshot without manually calling several user-domain APIs."},{"arguments":[{"description":"Primary email for the target user.","name":"email","required":true}],"audiences":["support","backend"],"commonness":"common","description":"Builds the same compact support summary surfaced by the app settings/account area.","examples":["./bin/admin-local users support-summary rider@example.com"],"group":"users","key":"users support-summary","mutating":false,"outputSummary":"Returns favorite-zone, override, settings, and membership summary counts.","productionSafe":true,"relatedAPI":["GET /api/user/support-summary"],"slug":"users-support-summary","summary":"Load a support summary","useWhen":"Use this when support needs the compact account snapshot without the full profile and settings payloads."},{"arguments":[{"description":"Primary email for the target user.","name":"email","required":true}],"audiences":["support","backend"],"commonness":"common","description":"Recomputes the resolved commerce snapshot for one user from grants and fallback subscription records.","examples":["./bin/admin-local users recompute-membership member@example.com"],"group":"users","key":"users recompute-membership","mutating":true,"outputSummary":"Returns the resolved membership snapshot after recomputing grants and fallback state.","productionSafe":true,"relatedAPI":["GET /api/commerce/entitlements","POST /api/commerce/revenuecat/sync"],"slug":"users-recompute-membership","summary":"Recompute membership","useWhen":"Use this when entitlements look stale or support needs to verify the final resolved membership state for a user."},{"arguments":[{"description":"Primary email for the owner whose saved routes should be listed.","name":"email","required":true}],"audiences":["support","backend"],"commonness":"common","description":"Lists saved routes for one user, ordered by most recently updated.","examples":["./bin/admin-local routes list-routes rider@example.com","./bin/admin-local routes list-routes rider@example.com --limit 5"],"group":"routes","key":"routes list-routes","mutating":false,"options":[{"defaultValue":"20","description":"Maximum number of routes to return.","flag":"--limit","valueHint":"10"}],"outputSummary":"Returns the owner and a trimmed list of route contracts.","productionSafe":true,"relatedAPI":["GET /api/routes"],"slug":"routes-list-routes","summary":"List saved routes","useWhen":"Use this when support needs to confirm that routes are present, recent, and owned by the expected account."},{"arguments":[{"description":"Primary email for the owner whose plans should be listed.","name":"email","required":true}],"audiences":["support","backend"],"commonness":"common","description":"Lists route plans for one user, ordered by most recently updated.","examples":["./bin/admin-local routes list-plans rider@example.com","./bin/admin-local routes list-plans rider@example.com --limit 5"],"group":"routes","key":"routes list-plans","mutating":false,"options":[{"defaultValue":"20","description":"Maximum number of plans to return.","flag":"--limit","valueHint":"10"}],"outputSummary":"Returns the owner and a trimmed list of route-plan contracts.","productionSafe":true,"relatedAPI":["GET /api/route-plans"],"slug":"routes-list-plans","summary":"List route plans","useWhen":"Use this when support needs to confirm that plans, revisions, or shareable IDs exist for an account."},{"arguments":[{"description":"Route identifier to inspect.","name":"routeID","required":true}],"audiences":["support","backend"],"commonness":"common","description":"Loads one saved-route contract directly from persistence without requiring a signed-in session.","examples":["./bin/admin-local routes show-route 64eacdc0-0bc6-41ec-804c-2082db5bf53f"],"group":"routes","key":"routes show-route","mutating":false,"outputSummary":"Returns the full route contract or a not-found error.","productionSafe":true,"relatedAPI":["GET /api/routes/:routeID"],"slug":"routes-show-route","summary":"Inspect one saved route","useWhen":"Use this when support already has a route ID and needs the canonical backend route payload quickly."},{"arguments":[{"description":"Route-plan identifier to inspect.","name":"planID","required":true}],"audiences":["support","backend"],"commonness":"common","description":"Loads one route-plan contract directly from persistence without requiring the owner session.","examples":["./bin/admin-local routes show-plan 1c8f46c2-4d7d-4af0-a8cf-40bf1cf0f331"],"group":"routes","key":"routes show-plan","mutating":false,"outputSummary":"Returns the full route-plan contract or a not-found error.","productionSafe":true,"relatedAPI":["GET /api/route-plans/:planID"],"slug":"routes-show-plan","summary":"Inspect one route plan","useWhen":"Use this when support already has a plan ID and needs the canonical backend plan payload quickly."},{"arguments":[{"description":"Route identifier to analyze.","name":"routeID","required":true}],"audiences":["support","backend"],"commonness":"core","description":"Runs the same backend-owned terrain-analysis pipeline used by route details and graph overlays.","examples":["./bin/admin-local routes terrain-analysis 64eacdc0-0bc6-41ec-804c-2082db5bf53f","./bin/admin-local routes terrain-analysis 64eacdc0-0bc6-41ec-804c-2082db5bf53f --danger-level high"],"group":"routes","key":"routes terrain-analysis","mutating":false,"options":[{"defaultValue":"3","description":"Danger level label or integer used for slope guidance and danger overlays.","flag":"--danger-level","valueHint":"high"}],"outputSummary":"Returns the full terrain-analysis payload used for graphs, footprint roses, and overlays.","productionSafe":true,"relatedAPI":["GET /api/routes/:routeID/terrain-analysis","GET /api/catalog/routes/:routeID/terrain-analysis"],"slug":"routes-terrain-analysis","summary":"Run route terrain analysis","useWhen":"Use this when verifying graph data, footprint roses, slope distribution, or route safety overlays without going through the app UI."},{"arguments":[{"description":"Route identifier whose cached exposure should be refreshed.","name":"routeID","required":true}],"audiences":["support","backend"],"commonness":"core","description":"Recomputes and persists the backend route-exposure cache for one saved route.","examples":["./bin/admin-local routes recompute-exposure 64eacdc0-0bc6-41ec-804c-2082db5bf53f","./bin/admin-local routes recompute-exposure 64eacdc0-0bc6-41ec-804c-2082db5bf53f --danger-level considerable"],"group":"routes","key":"routes recompute-exposure","mutating":true,"options":[{"defaultValue":"3","description":"Danger level label or integer for the recomputed cache entry.","flag":"--danger-level","valueHint":"considerable"}],"outputSummary":"Returns the recomputed exposure summary plus persisted cache metadata.","productionSafe":true,"relatedAPI":["POST /api/routes/:routeID/exposure/recompute","GET /api/routes/:routeID/exposure"],"slug":"routes-recompute-exposure","summary":"Recompute route exposure","useWhen":"Use this when a route’s exposure data is stale, missing, or needs to be compared against the latest forecast revision."},{"arguments":[{"description":"Route-plan identifier whose trip history should be listed.","name":"planID","required":true}],"audiences":["support","backend"],"commonness":"common","description":"Lists recent trip sessions for one saved route plan, ordered from newest to oldest.","examples":["./bin/admin-local trips list-for-plan 1c8f46c2-4d7d-4af0-a8cf-40bf1cf0f331","./bin/admin-local trips list-for-plan 1c8f46c2-4d7d-4af0-a8cf-40bf1cf0f331 --limit 5"],"group":"trips","key":"trips list-for-plan","mutating":false,"options":[{"defaultValue":"8","description":"Maximum number of trip sessions to return.","flag":"--limit","valueHint":"5"}],"outputSummary":"Returns the saved plan contract plus recent trip-session summaries for that plan.","productionSafe":true,"relatedAPI":["GET /api/route-plans/:planID/trips","GET /api/route-plans/:planID/latest-trip"],"slug":"trips-list-for-plan","summary":"List trips for a plan","useWhen":"Use this when support needs the recent trip history for one saved plan before inspecting a specific active or finished session."},{"arguments":[{"description":"Route-plan identifier whose latest trip should be loaded.","name":"planID","required":true}],"audiences":["support","backend"],"commonness":"common","description":"Loads the latest trip-session for one saved route plan and includes the same support summary blocks used by trip debugging.","examples":["./bin/admin-local trips latest-for-plan 1c8f46c2-4d7d-4af0-a8cf-40bf1cf0f331"],"group":"trips","key":"trips latest-for-plan","mutating":false,"outputSummary":"Returns the latest trip-session summary for a plan, including contacts, latest heartbeat, alert counts, and debrief metadata when available.","productionSafe":true,"relatedAPI":["GET /api/route-plans/:planID/latest-trip","GET /api/trips/:id"],"slug":"trips-latest-for-plan","summary":"Load latest trip for a plan","useWhen":"Use this when an active or most recent trip is the likely root cause and support already has the saved plan ID."},{"arguments":[{"description":"Trip-session identifier to inspect.","name":"tripID","required":true}],"audiences":["support","backend"],"commonness":"core","description":"Loads one trip-session by ID with contacts, latest heartbeat, recent alerts, recent observations, and debrief metadata.","examples":["./bin/admin-local trips show-trip 8df15c8c-0be0-4c57-a25d-8599fcf3fe02"],"group":"trips","key":"trips show-trip","mutating":false,"outputSummary":"Returns the canonical trip-session record plus support-friendly related state for debugging field safety issues.","productionSafe":true,"relatedAPI":["GET /api/trips/:id","GET /api/trips/:id/status","GET /api/trips/:id/debrief"],"slug":"trips-show-trip","summary":"Inspect one trip","useWhen":"Use this when support or backend needs the full trip-state picture for one session without manually walking several API endpoints."},{"arguments":[{"description":"Email for the user whose registered push devices should be inspected.","name":"email","required":true}],"audiences":["support","backend","ops","admin"],"commonness":"common","description":"Lists the stored push-capable devices for one user and resolves the APNS gateway/topic the CLI would use for delivery.","examples":["./bin/admin-local notifications list-devices qa-demo@yopmail.com","./bin/admin-local notifications list-devices qa-demo@yopmail.com --environment staging --platform ios"],"group":"notifications","key":"notifications list-devices","mutating":false,"options":[{"description":"Filter or resolve using a stored device environment label such as local, staging, test, or production. Legacy `development` labels are still accepted.","flag":"--environment","valueHint":"staging"},{"description":"Explicit APNS channel override.","flag":"--channel","valueHint":"sandbox"},{"description":"Explicit APNS topic override. Otherwise bundleIdentifier metadata or environment defaults are used.","flag":"--topic","valueHint":"com.aspectavy.aspectavystaging"},{"description":"Filter to one platform, currently `ios`.","flag":"--platform","valueHint":"ios"},{"description":"Filter to one device-token suffix from `list-devices` output.","flag":"--token-suffix","valueHint":"1a2b3c4d"}],"outputSummary":"Returns the matched push devices, token suffixes, stored metadata, and resolved APNS channel/topic metadata.","productionSafe":true,"relatedAPI":["POST /api/push/devices"],"slug":"notifications-list-devices","summary":"List registered push devices","useWhen":"Use this before sending a test notification so you can confirm the target device, environment label, and APNS topic resolution."},{"arguments":[],"audiences":["support","backend","ops","admin"],"commonness":"common","description":"Builds the APNS headers and payload the CLI would send, including route-driven keys that the iOS app already parses.","examples":["./bin/admin-local notifications preview-payload --environment staging --route /search","./bin/admin-local notifications preview-payload --channel production --topic com.aspectavy.aspectavy --title \"AspectAvy QA\" --body \"Open settings\" --route /settings"],"group":"notifications","key":"notifications preview-payload","mutating":false,"options":[{"description":"Filter or resolve using a stored device environment label such as local, staging, test, or production. Legacy `development` labels are still accepted.","flag":"--environment","valueHint":"staging"},{"description":"Explicit APNS channel override.","flag":"--channel","valueHint":"sandbox"},{"description":"Explicit APNS topic override. Otherwise bundleIdentifier metadata or environment defaults are used.","flag":"--topic","valueHint":"com.aspectavy.aspectavystaging"},{"description":"Typed app route or URL to carry in the notification payload.","flag":"--route","valueHint":"/search"},{"description":"Visible alert title. Defaults to a QA title for alert pushes.","flag":"--title","valueHint":"\"AspectAvy QA\""},{"description":"Visible alert subtitle.","flag":"--subtitle","valueHint":"\"Search\""},{"description":"Visible alert body. Defaults to a route-based body when possible.","flag":"--body","valueHint":"\"Open the search hub\""},{"description":"APNS sound value, for example `default`.","flag":"--sound","valueHint":"\"default\""},{"description":"Numeric badge count to include in `aps.badge`.","flag":"--badge","valueHint":"1"},{"description":"Optional APNS category value.","flag":"--category","valueHint":"qa.test"},{"description":"Optional APNS thread identifier.","flag":"--thread-id","valueHint":"qa-thread"},{"description":"Explicit replay key stored in `app_route_replay_key`.","flag":"--replay-key","valueHint":"qa-search-001"},{"description":"Optional onboarding hint stored in `app_onboarding_hint`.","flag":"--onboarding-hint","valueHint":"powder-day"},{"description":"Optional referral code stored in `app_referral_code`.","flag":"--referral-code","valueHint":"buddy-42"},{"description":"APNS push type such as `alert` or `background`.","flag":"--push-type","valueHint":"alert"},{"description":"APNS priority. Must be 5 or 10.","flag":"--priority","valueHint":"10"},{"description":"APNS collapse identifier.","flag":"--collapse-id","valueHint":"qa.search"},{"description":"APNS expiration timestamp in Unix seconds. Use `0` for immediate expiry.","flag":"--expiration","valueHint":"0"},{"description":"Set `aps.content-available = 1`.","flag":"--content-available"},{"description":"Set `aps.mutable-content = 1`.","flag":"--mutable-content"},{"description":"Merge a JSON object from disk into the root payload.","flag":"--payload-file","valueHint":"./tmp/payload.json"},{"description":"Merge an inline JSON object into the root payload.","flag":"--payload-json","valueHint":"'{\"debug\":true}'"}],"outputSummary":"Returns the resolved APNS headers, topic source, payload JSON, payload size, and any configuration warnings.","productionSafe":true,"relatedAPI":["POST /api/push/devices"],"slug":"notifications-preview-payload","summary":"Preview APNS payload and headers","useWhen":"Use this before a live send when QA needs to inspect the exact route payload, APNS headers, or topic resolution."},{"arguments":[{"description":"Email for the user whose registered push devices should receive the test payload.","name":"email","required":true}],"audiences":["support","backend","ops","admin"],"commonness":"common","description":"Sends one APNS test payload to the matched registered devices for a user, with optional dry-run, route-driven payloads, and explicit topic/channel overrides.","examples":["./bin/admin-local notifications send-test qa-demo@yopmail.com --environment staging --route /search --justification \"QA staging push validation\"","./bin/admin-local notifications send-test qa-demo@yopmail.com --token-suffix 1a2b3c4d --title \"AspectAvy QA\" --body \"Open settings\" --route /settings --justification \"Verify settings route from push\""],"group":"notifications","key":"notifications send-test","mutating":true,"options":[{"description":"Filter or resolve using a stored device environment label such as local, staging, test, or production. Legacy `development` labels are still accepted.","flag":"--environment","valueHint":"staging"},{"description":"Explicit APNS channel override.","flag":"--channel","valueHint":"sandbox"},{"description":"Explicit APNS topic override. Otherwise bundleIdentifier metadata or environment defaults are used.","flag":"--topic","valueHint":"com.aspectavy.aspectavystaging"},{"description":"Filter to one platform, currently `ios`.","flag":"--platform","valueHint":"ios"},{"description":"Filter to one device-token suffix from `list-devices` output.","flag":"--token-suffix","valueHint":"1a2b3c4d"},{"description":"Preview the resolved APNS request without delivering it.","flag":"--dry-run"},{"description":"Required explanation for why the notification send is being performed.","flag":"--justification","valueHint":"\"QA push validation\""},{"description":"Typed app route or URL to carry in the notification payload.","flag":"--route","valueHint":"/search"},{"description":"Visible alert title. Defaults to a QA title for alert pushes.","flag":"--title","valueHint":"\"AspectAvy QA\""},{"description":"Visible alert subtitle.","flag":"--subtitle","valueHint":"\"Search\""},{"description":"Visible alert body. Defaults to a route-based body when possible.","flag":"--body","valueHint":"\"Open the search hub\""},{"description":"APNS sound value, for example `default`.","flag":"--sound","valueHint":"\"default\""},{"description":"Numeric badge count to include in `aps.badge`.","flag":"--badge","valueHint":"1"},{"description":"Optional APNS category value.","flag":"--category","valueHint":"qa.test"},{"description":"Optional APNS thread identifier.","flag":"--thread-id","valueHint":"qa-thread"},{"description":"Explicit replay key stored in `app_route_replay_key`.","flag":"--replay-key","valueHint":"qa-search-001"},{"description":"Optional onboarding hint stored in `app_onboarding_hint`.","flag":"--onboarding-hint","valueHint":"powder-day"},{"description":"Optional referral code stored in `app_referral_code`.","flag":"--referral-code","valueHint":"buddy-42"},{"description":"APNS push type such as `alert` or `background`.","flag":"--push-type","valueHint":"alert"},{"description":"APNS priority. Must be 5 or 10.","flag":"--priority","valueHint":"10"},{"description":"APNS collapse identifier.","flag":"--collapse-id","valueHint":"qa.search"},{"description":"APNS expiration timestamp in Unix seconds. Use `0` for immediate expiry.","flag":"--expiration","valueHint":"0"},{"description":"Set `aps.content-available = 1`.","flag":"--content-available"},{"description":"Set `aps.mutable-content = 1`.","flag":"--mutable-content"},{"description":"Merge a JSON object from disk into the root payload.","flag":"--payload-file","valueHint":"./tmp/payload.json"},{"description":"Merge an inline JSON object into the root payload.","flag":"--payload-json","valueHint":"'{\"debug\":true}'"}],"outputSummary":"Returns the matched devices plus a per-device APNS result with status code, APNS ID, resolved topic, and response body.","productionSafe":true,"relatedAPI":["POST /api/push/devices"],"slug":"notifications-send-test","summary":"Send an APNS test push to a registered user device","useWhen":"Use this when QA or operator validation needs a real push delivered to one of the user's registered devices without hand-building APNS requests."},{"arguments":[{"description":"Raw APNS device token to target directly.","name":"token","required":true}],"audiences":["backend","ops","admin"],"commonness":"advanced","description":"Sends one APNS test payload directly to a raw device token when you want to bypass stored device lookup.","examples":["./bin/admin-local notifications send-token deadbeef1234 --channel sandbox --topic com.aspectavy.aspectavydevelopment --route /search --justification \"Direct simulator token test\""],"group":"notifications","key":"notifications send-token","mutating":true,"options":[{"description":"Filter or resolve using a stored device environment label such as local, staging, test, or production. Legacy `development` labels are still accepted.","flag":"--environment","valueHint":"staging"},{"description":"Explicit APNS channel override.","flag":"--channel","valueHint":"sandbox"},{"description":"Explicit APNS topic override. Otherwise bundleIdentifier metadata or environment defaults are used.","flag":"--topic","valueHint":"com.aspectavy.aspectavystaging"},{"description":"Preview the resolved APNS request without delivering it.","flag":"--dry-run"},{"description":"Required explanation for why the notification send is being performed.","flag":"--justification","valueHint":"\"QA push validation\""},{"description":"Typed app route or URL to carry in the notification payload.","flag":"--route","valueHint":"/search"},{"description":"Visible alert title. Defaults to a QA title for alert pushes.","flag":"--title","valueHint":"\"AspectAvy QA\""},{"description":"Visible alert subtitle.","flag":"--subtitle","valueHint":"\"Search\""},{"description":"Visible alert body. Defaults to a route-based body when possible.","flag":"--body","valueHint":"\"Open the search hub\""},{"description":"APNS sound value, for example `default`.","flag":"--sound","valueHint":"\"default\""},{"description":"Numeric badge count to include in `aps.badge`.","flag":"--badge","valueHint":"1"},{"description":"Optional APNS category value.","flag":"--category","valueHint":"qa.test"},{"description":"Optional APNS thread identifier.","flag":"--thread-id","valueHint":"qa-thread"},{"description":"Explicit replay key stored in `app_route_replay_key`.","flag":"--replay-key","valueHint":"qa-search-001"},{"description":"Optional onboarding hint stored in `app_onboarding_hint`.","flag":"--onboarding-hint","valueHint":"powder-day"},{"description":"Optional referral code stored in `app_referral_code`.","flag":"--referral-code","valueHint":"buddy-42"},{"description":"APNS push type such as `alert` or `background`.","flag":"--push-type","valueHint":"alert"},{"description":"APNS priority. Must be 5 or 10.","flag":"--priority","valueHint":"10"},{"description":"APNS collapse identifier.","flag":"--collapse-id","valueHint":"qa.search"},{"description":"APNS expiration timestamp in Unix seconds. Use `0` for immediate expiry.","flag":"--expiration","valueHint":"0"},{"description":"Set `aps.content-available = 1`.","flag":"--content-available"},{"description":"Set `aps.mutable-content = 1`.","flag":"--mutable-content"},{"description":"Merge a JSON object from disk into the root payload.","flag":"--payload-file","valueHint":"./tmp/payload.json"},{"description":"Merge an inline JSON object into the root payload.","flag":"--payload-json","valueHint":"'{\"debug\":true}'"}],"outputSummary":"Returns the APNS delivery result for the direct token target, including APNS ID, resolved topic, and response body.","productionSafe":true,"relatedAPI":[],"slug":"notifications-send-token","summary":"Send an APNS test push to a raw device token","useWhen":"Use this when you already have the token from an external system or debugging session and do not need to resolve devices through a user account."},{"arguments":[],"audiences":["ops","backend","support"],"commonness":"core","description":"Returns forecast snapshot counts, zone counts, and the latest available forecast revision.","examples":["./bin/admin-local forecasts stats"],"group":"forecasts","key":"forecasts stats","mutating":false,"outputSummary":"Returns forecast inventory counts and the latest snapshot metadata.","productionSafe":true,"relatedAPI":["GET /api/forecast","GET /api/forecast/brief"],"slug":"forecasts-stats","summary":"Inspect forecast inventory","useWhen":"Use this when validating that forecast sync is running and that the backend has current bulletin inventory."},{"arguments":[],"audiences":["ops","backend"],"commonness":"common","description":"Runs the backend forecast-sync job immediately against the configured environment and returns refreshed inventory counts.","examples":["./bin/admin-local forecasts sync-now","./bin/admin-production forecasts sync-now"],"group":"forecasts","key":"forecasts sync-now","mutating":true,"outputSummary":"Returns the number of written snapshots plus refreshed forecast inventory stats.","productionSafe":true,"relatedAPI":["GET /api/forecast","GET /api/changes"],"slug":"forecasts-sync-now","summary":"Sync forecasts now","useWhen":"Use this when staging or production needs an immediate forecast refresh without waiting for the worker cadence."},{"arguments":[],"audiences":["ops","backend","support"],"commonness":"core","description":"Runs a compact runtime summary covering database connectivity, worker heartbeat health, and core record counts.","examples":["./bin/admin-local ops health-summary"],"group":"ops","key":"ops health-summary","mutating":false,"outputSummary":"Returns environment, database health, worker heartbeat age, and core row counts.","productionSafe":true,"relatedAPI":["GET /livez","GET /readyz"],"slug":"ops-health-summary","summary":"Load runtime health summary","useWhen":"Use this first when hosted staging or production looks unhealthy before drilling into one domain-specific command."},{"arguments":[],"audiences":["admin","backend","ops"],"commonness":"common","description":"Lists recent operator audit events with optional action, target, and status filtering.","examples":["./bin/admin-local audit list-events","./bin/admin-local audit list-events --action operator.account.create --limit 20"],"group":"audit","key":"audit list-events","mutating":false,"options":[{"defaultValue":"50","description":"Maximum number of audit events to return.","flag":"--limit","valueHint":"20"},{"description":"Filter to one audit action key.","flag":"--action","valueHint":"operator.account.create"},{"description":"Filter to one target type.","flag":"--target-type","valueHint":"user"},{"description":"Filter to one target ID.","flag":"--target-id","valueHint":"64eacdc0-0bc6-41ec-804c-2082db5bf53f"},{"description":"Filter to success or failure status.","flag":"--status","valueHint":"success"}],"outputSummary":"Returns a reverse-chronological list of operator audit events.","productionSafe":true,"relatedAPI":["GET /api/admin/audit"],"requiredScopes":["operator.audit.read"],"slug":"audit-list-events","summary":"List operator audit events","useWhen":"Use this when reviewing who changed data, which surface triggered it, and what target was affected."}],"generatedAt":"2026-04-15T05:18:19.474Z","groups":[{"description":"Operator account bootstrap, login, session inspection, and scope management.","id":"operator","title":"Operators"},{"description":"Legacy-account migration, auth inspection, and lockout recovery.","id":"auth","title":"Auth & Access"},{"description":"Test account creation, profile inspection, support summary, and membership repair commands.","id":"users","title":"Users & Membership"},{"description":"Saved-route, plan, terrain-analysis, and exposure inspection helpers.","id":"routes","title":"Routes & Plans"},{"description":"Trip-session inspection helpers for field safety, contacts, check-ins, alerts, and debrief state.","id":"trips","title":"Trips & Field Safety"},{"description":"Push-device inspection plus APNS payload preview and delivery helpers for QA and operator validation.","id":"notifications","title":"Notifications & APNS"},{"description":"Forecast inventory and manual sync helpers for server-side bulletin state.","id":"forecasts","title":"Forecasts"},{"description":"Backend/runtime health checks and environment-level support commands.","id":"ops","title":"Ops & Runtime"},{"description":"Filterable operator audit history for support, security, and review workflows.","id":"audit","title":"Audit Log"}],"guides":[{"category":"Admin CLI","description":"How to boot, authorize, and safely use the operator CLI against local, staging, or production.","relativePath":"documentation/api/admin-cli-getting-started.md","slug":"admin-cli-getting-started","title":"Admin CLI Getting Started"},{"category":"Admin CLI","description":"Common support and operator playbooks using the unified admin CLI.","relativePath":"documentation/api/admin-cli-playbooks.md","slug":"admin-cli-playbooks","title":"Admin CLI Playbooks"},{"category":"AI Tooling","description":"Project-owned AI constraints, machine-readable registries, and MCP integration guidance.","relativePath":"documentation/api/ai-tooling-and-mcp.md","slug":"ai-tooling-and-mcp","title":"AI Tooling & MCP"}],"info":{"description":"Machine-readable AspectAvy admin CLI catalog for operator tooling, docs generation, and AI-driven support workflows.","title":"AspectAvy Admin CLI","version":"1.0.0"}}