@elizaos/plugin-health 2.0.0-beta.1 → 2.0.3-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +33 -27
- package/assets/hero.svg +67 -0
- package/package.json +67 -4
- package/dist/actions/index.d.ts +0 -20
- package/dist/actions/index.d.ts.map +0 -1
- package/dist/actions/index.js +0 -5
- package/dist/actions/index.js.map +0 -1
- package/dist/anchors/index.d.ts +0 -19
- package/dist/anchors/index.d.ts.map +0 -1
- package/dist/anchors/index.js +0 -9
- package/dist/anchors/index.js.map +0 -1
- package/dist/connectors/contract-stubs.d.ts +0 -112
- package/dist/connectors/contract-stubs.d.ts.map +0 -1
- package/dist/connectors/contract-stubs.js +0 -1
- package/dist/connectors/contract-stubs.js.map +0 -1
- package/dist/connectors/index.d.ts +0 -28
- package/dist/connectors/index.d.ts.map +0 -1
- package/dist/connectors/index.js +0 -202
- package/dist/connectors/index.js.map +0 -1
- package/dist/contracts/circadian-default.d.ts +0 -15
- package/dist/contracts/circadian-default.d.ts.map +0 -1
- package/dist/contracts/circadian-default.js +0 -30
- package/dist/contracts/circadian-default.js.map +0 -1
- package/dist/contracts/circadian.d.ts +0 -92
- package/dist/contracts/circadian.d.ts.map +0 -1
- package/dist/contracts/circadian.js +0 -14
- package/dist/contracts/circadian.js.map +0 -1
- package/dist/contracts/health.d.ts +0 -9
- package/dist/contracts/health.d.ts.map +0 -1
- package/dist/contracts/health.js +0 -21
- package/dist/contracts/health.js.map +0 -1
- package/dist/contracts/lifeops-connector-degradation.d.ts +0 -9
- package/dist/contracts/lifeops-connector-degradation.d.ts.map +0 -1
- package/dist/contracts/lifeops-connector-degradation.js +0 -17
- package/dist/contracts/lifeops-connector-degradation.js.map +0 -1
- package/dist/contracts/lifeops.d.ts +0 -3123
- package/dist/contracts/lifeops.d.ts.map +0 -1
- package/dist/contracts/lifeops.js +0 -635
- package/dist/contracts/lifeops.js.map +0 -1
- package/dist/contracts/permissions.d.ts +0 -39
- package/dist/contracts/permissions.d.ts.map +0 -1
- package/dist/contracts/permissions.js +0 -1
- package/dist/contracts/permissions.js.map +0 -1
- package/dist/default-packs/bedtime.d.ts +0 -14
- package/dist/default-packs/bedtime.d.ts.map +0 -1
- package/dist/default-packs/bedtime.js +0 -48
- package/dist/default-packs/bedtime.js.map +0 -1
- package/dist/default-packs/contract-stubs.d.ts +0 -161
- package/dist/default-packs/contract-stubs.d.ts.map +0 -1
- package/dist/default-packs/contract-stubs.js +0 -1
- package/dist/default-packs/contract-stubs.js.map +0 -1
- package/dist/default-packs/index.d.ts +0 -18
- package/dist/default-packs/index.d.ts.map +0 -1
- package/dist/default-packs/index.js +0 -39
- package/dist/default-packs/index.js.map +0 -1
- package/dist/default-packs/sleep-recap.d.ts +0 -14
- package/dist/default-packs/sleep-recap.d.ts.map +0 -1
- package/dist/default-packs/sleep-recap.js +0 -51
- package/dist/default-packs/sleep-recap.js.map +0 -1
- package/dist/default-packs/wake-up.d.ts +0 -14
- package/dist/default-packs/wake-up.d.ts.map +0 -1
- package/dist/default-packs/wake-up.js +0 -61
- package/dist/default-packs/wake-up.js.map +0 -1
- package/dist/health-bridge/health-bridge.d.ts +0 -57
- package/dist/health-bridge/health-bridge.d.ts.map +0 -1
- package/dist/health-bridge/health-bridge.js +0 -558
- package/dist/health-bridge/health-bridge.js.map +0 -1
- package/dist/health-bridge/health-connectors.d.ts +0 -23
- package/dist/health-bridge/health-connectors.d.ts.map +0 -1
- package/dist/health-bridge/health-connectors.js +0 -1018
- package/dist/health-bridge/health-connectors.js.map +0 -1
- package/dist/health-bridge/health-oauth.d.ts +0 -62
- package/dist/health-bridge/health-oauth.d.ts.map +0 -1
- package/dist/health-bridge/health-oauth.js +0 -432
- package/dist/health-bridge/health-oauth.js.map +0 -1
- package/dist/health-bridge/health-provider-registry.d.ts +0 -89
- package/dist/health-bridge/health-provider-registry.d.ts.map +0 -1
- package/dist/health-bridge/health-provider-registry.js +0 -141
- package/dist/health-bridge/health-provider-registry.js.map +0 -1
- package/dist/health-bridge/health-records.d.ts +0 -14
- package/dist/health-bridge/health-records.d.ts.map +0 -1
- package/dist/health-bridge/health-records.js +0 -45
- package/dist/health-bridge/health-records.js.map +0 -1
- package/dist/health-bridge/index.d.ts +0 -22
- package/dist/health-bridge/index.d.ts.map +0 -1
- package/dist/health-bridge/index.js +0 -7
- package/dist/health-bridge/index.js.map +0 -1
- package/dist/health-bridge/service-normalize-health.d.ts +0 -3
- package/dist/health-bridge/service-normalize-health.d.ts.map +0 -1
- package/dist/health-bridge/service-normalize-health.js +0 -96
- package/dist/health-bridge/service-normalize-health.js.map +0 -1
- package/dist/index.d.ts +0 -41
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -62
- package/dist/index.js.map +0 -1
- package/dist/screen-time/index.d.ts +0 -23
- package/dist/screen-time/index.d.ts.map +0 -1
- package/dist/screen-time/index.js +0 -1
- package/dist/screen-time/index.js.map +0 -1
- package/dist/sleep/awake-probability.d.ts +0 -11
- package/dist/sleep/awake-probability.d.ts.map +0 -1
- package/dist/sleep/awake-probability.js +0 -163
- package/dist/sleep/awake-probability.js.map +0 -1
- package/dist/sleep/circadian-rules.d.ts +0 -45
- package/dist/sleep/circadian-rules.d.ts.map +0 -1
- package/dist/sleep/circadian-rules.js +0 -258
- package/dist/sleep/circadian-rules.js.map +0 -1
- package/dist/sleep/index.d.ts +0 -21
- package/dist/sleep/index.d.ts.map +0 -1
- package/dist/sleep/index.js +0 -11
- package/dist/sleep/index.js.map +0 -1
- package/dist/sleep/sleep-cycle-dispatch.d.ts +0 -75
- package/dist/sleep/sleep-cycle-dispatch.d.ts.map +0 -1
- package/dist/sleep/sleep-cycle-dispatch.js +0 -102
- package/dist/sleep/sleep-cycle-dispatch.js.map +0 -1
- package/dist/sleep/sleep-cycle.d.ts +0 -38
- package/dist/sleep/sleep-cycle.d.ts.map +0 -1
- package/dist/sleep/sleep-cycle.js +0 -418
- package/dist/sleep/sleep-cycle.js.map +0 -1
- package/dist/sleep/sleep-episode-store.d.ts +0 -25
- package/dist/sleep/sleep-episode-store.d.ts.map +0 -1
- package/dist/sleep/sleep-episode-store.js +0 -69
- package/dist/sleep/sleep-episode-store.js.map +0 -1
- package/dist/sleep/sleep-episode-types.d.ts +0 -38
- package/dist/sleep/sleep-episode-types.d.ts.map +0 -1
- package/dist/sleep/sleep-episode-types.js +0 -14
- package/dist/sleep/sleep-episode-types.js.map +0 -1
- package/dist/sleep/sleep-recap.d.ts +0 -19
- package/dist/sleep/sleep-recap.d.ts.map +0 -1
- package/dist/sleep/sleep-recap.js +0 -1
- package/dist/sleep/sleep-recap.js.map +0 -1
- package/dist/sleep/sleep-regularity.d.ts +0 -19
- package/dist/sleep/sleep-regularity.d.ts.map +0 -1
- package/dist/sleep/sleep-regularity.js +0 -242
- package/dist/sleep/sleep-regularity.js.map +0 -1
- package/dist/sleep/sleep-wake-events.d.ts +0 -58
- package/dist/sleep/sleep-wake-events.d.ts.map +0 -1
- package/dist/sleep/sleep-wake-events.js +0 -135
- package/dist/sleep/sleep-wake-events.js.map +0 -1
- package/dist/sleep/source-reliability.d.ts +0 -38
- package/dist/sleep/source-reliability.d.ts.map +0 -1
- package/dist/sleep/source-reliability.js +0 -62
- package/dist/sleep/source-reliability.js.map +0 -1
- package/dist/util/index.d.ts +0 -10
- package/dist/util/index.d.ts.map +0 -1
- package/dist/util/index.js +0 -3
- package/dist/util/index.js.map +0 -1
- package/dist/util/normalize.d.ts +0 -22
- package/dist/util/normalize.d.ts.map +0 -1
- package/dist/util/normalize.js +0 -62
- package/dist/util/normalize.js.map +0 -1
- package/dist/util/time-util.d.ts +0 -10
- package/dist/util/time-util.d.ts.map +0 -1
- package/dist/util/time-util.js +0 -14
- package/dist/util/time-util.js.map +0 -1
- package/dist/util/time.d.ts +0 -17
- package/dist/util/time.d.ts.map +0 -1
- package/dist/util/time.js +0 -152
- package/dist/util/time.js.map +0 -1
- package/dist/util/token-encryption.d.ts +0 -42
- package/dist/util/token-encryption.d.ts.map +0 -1
- package/dist/util/token-encryption.js +0 -96
- package/dist/util/token-encryption.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/contracts/lifeops.ts"],"sourcesContent":["import type { LifeOpsConnectorDegradation } from \"./lifeops-connector-degradation.js\";\n\nexport type {\n LifeOpsConnectorDegradation,\n LifeOpsConnectorDegradationAxis,\n} from \"./lifeops-connector-degradation.js\";\nexport { LIFEOPS_CONNECTOR_DEGRADATION_AXES } from \"./lifeops-connector-degradation.js\";\n\nexport const LIFEOPS_TIME_WINDOW_NAMES = [\n \"morning\",\n \"afternoon\",\n \"evening\",\n \"night\",\n \"custom\",\n] as const;\n\nexport type LifeOpsTimeWindowName = (typeof LIFEOPS_TIME_WINDOW_NAMES)[number];\n\nexport const LIFEOPS_DEFINITION_KINDS = [\"task\", \"habit\", \"routine\"] as const;\nexport type LifeOpsDefinitionKind = (typeof LIFEOPS_DEFINITION_KINDS)[number];\n\nexport const LIFEOPS_DEFINITION_STATUSES = [\n \"active\",\n \"paused\",\n \"archived\",\n] as const;\nexport type LifeOpsDefinitionStatus =\n (typeof LIFEOPS_DEFINITION_STATUSES)[number];\n\nexport const LIFEOPS_OCCURRENCE_STATES = [\n \"pending\",\n \"visible\",\n \"snoozed\",\n \"completed\",\n \"skipped\",\n \"expired\",\n \"muted\",\n] as const;\nexport type LifeOpsOccurrenceState = (typeof LIFEOPS_OCCURRENCE_STATES)[number];\n\nexport const LIFEOPS_GOAL_STATUSES = [\n \"active\",\n \"paused\",\n \"archived\",\n \"satisfied\",\n] as const;\nexport type LifeOpsGoalStatus = (typeof LIFEOPS_GOAL_STATUSES)[number];\n\nexport const LIFEOPS_REVIEW_STATES = [\n \"idle\",\n \"needs_attention\",\n \"on_track\",\n \"at_risk\",\n] as const;\nexport type LifeOpsGoalReviewState = (typeof LIFEOPS_REVIEW_STATES)[number];\n\nexport const LIFEOPS_WORKFLOW_STATUSES = [\n \"active\",\n \"paused\",\n \"archived\",\n] as const;\nexport type LifeOpsWorkflowStatus = (typeof LIFEOPS_WORKFLOW_STATUSES)[number];\n\nexport const LIFEOPS_WORKFLOW_RUN_STATUSES = [\n \"queued\",\n \"running\",\n \"success\",\n \"failed\",\n \"cancelled\",\n] as const;\nexport type LifeOpsWorkflowRunStatus =\n (typeof LIFEOPS_WORKFLOW_RUN_STATUSES)[number];\n\nexport const LIFEOPS_WORKFLOW_TRIGGER_TYPES = [\n \"manual\",\n \"schedule\",\n \"event\",\n] as const;\nexport type LifeOpsWorkflowTriggerType =\n (typeof LIFEOPS_WORKFLOW_TRIGGER_TYPES)[number];\n\n/**\n * Registry of event kinds that can fire a LifeOps workflow.\n *\n * Each entry is a stable identifier (\"namespace.subject.verb\") emitted by a\n * detector inside the engine. Adding a new entry means adding a detector that\n * publishes matching occurrences to `runDueEventWorkflows`, and — optionally —\n * a filter shape under {@link LifeOpsEventFilters}.\n */\nexport const LIFEOPS_EVENT_KINDS = [\n \"calendar.event.ended\",\n \"gmail.message.received\",\n \"gmail.thread.needs_response\",\n \"lifeops.sleep.onset_candidate\",\n \"lifeops.sleep.detected\",\n \"lifeops.sleep.ended\",\n \"lifeops.wake.observed\",\n \"lifeops.wake.confirmed\",\n \"lifeops.nap.detected\",\n \"lifeops.bedtime.imminent\",\n \"lifeops.regularity.changed\",\n] as const;\nexport type LifeOpsEventKind = (typeof LIFEOPS_EVENT_KINDS)[number];\n\nexport interface LifeOpsCalendarEventEndedFilters {\n /** Only fire for events on these calendar ids (e.g. \"primary\"). */\n calendarIds?: string[];\n /** Only fire when event title matches one of these case-insensitive substrings. */\n titleIncludesAny?: string[];\n /** Only fire when the event lasted at least this many minutes. */\n minDurationMinutes?: number;\n /** Only fire when one attendee email contains one of these substrings. */\n attendeeEmailIncludesAny?: string[];\n}\n\nexport interface LifeOpsGmailEventFilters {\n /** Only fire for these Google connector grant ids. */\n grantIds?: string[];\n /** Only fire when the sender email/display contains one of these substrings. */\n fromIncludesAny?: string[];\n /** Only fire when the subject contains one of these case-insensitive substrings. */\n subjectIncludesAny?: string[];\n /** Only fire when at least one Gmail label id is present. */\n labelIds?: string[];\n /** Only fire when LifeOps classified the message/thread as needing a reply. */\n requiresReplyNeeded?: boolean;\n}\n\nexport interface LifeOpsSleepOnsetCandidateFilters {\n minConfidence?: number;\n}\n\nexport interface LifeOpsSleepDetectedFilters {\n minConfidence?: number;\n}\n\nexport interface LifeOpsSleepEndedFilters {\n minConfidence?: number;\n}\n\nexport interface LifeOpsWakeObservedFilters {\n offsetMinutes?: number;\n minConfidence?: number;\n}\n\nexport interface LifeOpsWakeConfirmedFilters {\n offsetMinutes?: number;\n minConfidence?: number;\n}\n\nexport interface LifeOpsNapDetectedFilters {\n minConfidence?: number;\n maxDurationMinutes?: number;\n}\n\nexport interface LifeOpsBedtimeImminentFilters {\n minutesBefore?: number;\n minConfidence?: number;\n}\n\nexport interface LifeOpsRegularityChangedFilters {\n /** Fires when regularity class transitions into this value. */\n becomes?: LifeOpsRegularityClass;\n}\n\nexport type LifeOpsEventFilters =\n | {\n kind: \"calendar.event.ended\";\n filters?: LifeOpsCalendarEventEndedFilters;\n }\n | {\n kind: \"gmail.message.received\";\n filters?: LifeOpsGmailEventFilters;\n }\n | {\n kind: \"gmail.thread.needs_response\";\n filters?: LifeOpsGmailEventFilters;\n }\n | {\n kind: \"lifeops.sleep.onset_candidate\";\n filters?: LifeOpsSleepOnsetCandidateFilters;\n }\n | {\n kind: \"lifeops.sleep.detected\";\n filters?: LifeOpsSleepDetectedFilters;\n }\n | {\n kind: \"lifeops.sleep.ended\";\n filters?: LifeOpsSleepEndedFilters;\n }\n | {\n kind: \"lifeops.wake.observed\";\n filters?: LifeOpsWakeObservedFilters;\n }\n | {\n kind: \"lifeops.wake.confirmed\";\n filters?: LifeOpsWakeConfirmedFilters;\n }\n | {\n kind: \"lifeops.nap.detected\";\n filters?: LifeOpsNapDetectedFilters;\n }\n | {\n kind: \"lifeops.bedtime.imminent\";\n filters?: LifeOpsBedtimeImminentFilters;\n }\n | {\n kind: \"lifeops.regularity.changed\";\n filters?: LifeOpsRegularityChangedFilters;\n };\n\nexport const LIFEOPS_NEGOTIATION_STATES = [\n \"initiated\",\n \"proposals_sent\",\n \"awaiting_response\",\n \"confirmed\",\n \"cancelled\",\n] as const;\nexport type LifeOpsNegotiationState =\n (typeof LIFEOPS_NEGOTIATION_STATES)[number];\n\nexport const LIFEOPS_PROPOSAL_STATUSES = [\n \"pending\",\n \"accepted\",\n \"declined\",\n \"expired\",\n] as const;\nexport type LifeOpsProposalStatus = (typeof LIFEOPS_PROPOSAL_STATUSES)[number];\n\nexport const LIFEOPS_PROPOSAL_PROPOSERS = [\n \"agent\",\n \"owner\",\n \"counterparty\",\n] as const;\nexport type LifeOpsProposalProposer =\n (typeof LIFEOPS_PROPOSAL_PROPOSERS)[number];\n\nexport interface LifeOpsSchedulingNegotiation {\n id: string;\n agentId: string;\n subject: string;\n relationshipId: string | null;\n durationMinutes: number;\n timezone: string;\n state: LifeOpsNegotiationState;\n acceptedProposalId: string | null;\n startedAt: string;\n finalizedAt: string | null;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface LifeOpsSchedulingProposal {\n id: string;\n agentId: string;\n negotiationId: string;\n startAt: string;\n endAt: string;\n proposedBy: LifeOpsProposalProposer;\n status: LifeOpsProposalStatus;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport const LIFEOPS_CONNECTOR_PROVIDERS = [\n \"google\",\n \"x\",\n \"telegram\",\n \"discord\",\n \"twilio\",\n \"signal\",\n \"whatsapp\",\n \"imessage\",\n \"strava\",\n \"fitbit\",\n \"withings\",\n \"oura\",\n] as const;\nexport type LifeOpsConnectorProvider =\n (typeof LIFEOPS_CONNECTOR_PROVIDERS)[number];\n\nexport const LIFEOPS_CONNECTOR_MODES = [\n \"local\",\n \"remote\",\n \"cloud_managed\",\n] as const;\nexport type LifeOpsConnectorMode = (typeof LIFEOPS_CONNECTOR_MODES)[number];\n\nexport const LIFEOPS_CONNECTOR_SIDES = [\"owner\", \"agent\"] as const;\nexport type LifeOpsConnectorSide = (typeof LIFEOPS_CONNECTOR_SIDES)[number];\n\nexport const LIFEOPS_CONNECTOR_EXECUTION_TARGETS = [\"local\", \"cloud\"] as const;\nexport type LifeOpsConnectorExecutionTarget =\n (typeof LIFEOPS_CONNECTOR_EXECUTION_TARGETS)[number];\n\nexport const LIFEOPS_CONNECTOR_SOURCES_OF_TRUTH = [\n \"local_storage\",\n \"cloud_connection\",\n \"connector_account\",\n] as const;\nexport type LifeOpsConnectorSourceOfTruth =\n (typeof LIFEOPS_CONNECTOR_SOURCES_OF_TRUTH)[number];\n\nexport const LIFEOPS_GOOGLE_CAPABILITIES = [\n \"google.basic_identity\",\n \"google.calendar.read\",\n \"google.calendar.write\",\n \"google.gmail.triage\",\n \"google.gmail.send\",\n \"google.gmail.manage\",\n] as const;\nexport type LifeOpsGoogleCapability =\n (typeof LIFEOPS_GOOGLE_CAPABILITIES)[number];\n\nexport const LIFEOPS_X_CAPABILITIES = [\n \"x.read\",\n \"x.write\",\n \"x.dm.read\",\n \"x.dm.write\",\n] as const;\nexport type LifeOpsXCapability = (typeof LIFEOPS_X_CAPABILITIES)[number];\n\nexport const LIFEOPS_HEALTH_CONNECTOR_PROVIDERS = [\n \"strava\",\n \"fitbit\",\n \"withings\",\n \"oura\",\n] as const;\nexport type LifeOpsHealthConnectorProvider =\n (typeof LIFEOPS_HEALTH_CONNECTOR_PROVIDERS)[number];\n\nexport const LIFEOPS_HEALTH_CONNECTOR_CAPABILITIES = [\n \"health.activity.read\",\n \"health.workouts.read\",\n \"health.sleep.read\",\n \"health.readiness.read\",\n \"health.body.read\",\n \"health.vitals.read\",\n] as const;\nexport type LifeOpsHealthConnectorCapability =\n (typeof LIFEOPS_HEALTH_CONNECTOR_CAPABILITIES)[number];\n\nexport const LIFEOPS_HEALTH_METRICS = [\n \"steps\",\n \"active_minutes\",\n \"sleep_hours\",\n \"sleep_score\",\n \"readiness_score\",\n \"heart_rate\",\n \"resting_heart_rate\",\n \"heart_rate_variability\",\n \"calories\",\n \"distance_meters\",\n \"weight_kg\",\n \"body_fat_percent\",\n \"blood_pressure_systolic\",\n \"blood_pressure_diastolic\",\n \"blood_oxygen_percent\",\n \"respiratory_rate\",\n \"body_temperature_celsius\",\n] as const;\nexport type LifeOpsHealthMetric = (typeof LIFEOPS_HEALTH_METRICS)[number];\n\nexport const LIFEOPS_SIGNAL_CAPABILITIES = [\n \"signal.read\",\n \"signal.send\",\n] as const;\nexport type LifeOpsSignalCapability =\n (typeof LIFEOPS_SIGNAL_CAPABILITIES)[number];\n\nexport const LIFEOPS_DISCORD_CAPABILITIES = [\n \"discord.read\",\n \"discord.send\",\n] as const;\nexport type LifeOpsDiscordCapability =\n (typeof LIFEOPS_DISCORD_CAPABILITIES)[number];\n\nexport const LIFEOPS_TELEGRAM_CAPABILITIES = [\n \"telegram.read\",\n \"telegram.send\",\n] as const;\nexport type LifeOpsTelegramCapability =\n (typeof LIFEOPS_TELEGRAM_CAPABILITIES)[number];\n\n// ---------------------------------------------------------------------------\n// Side-aware capability policy\n// Owner side = assistive (read-only). Agent side = autonomous (read + send).\n// ---------------------------------------------------------------------------\n\nexport function capabilitiesForSide<T extends string>(\n allCapabilities: readonly T[],\n side: LifeOpsConnectorSide,\n): T[] {\n if (side === \"agent\") return [...allCapabilities];\n return allCapabilities.filter((c) => c.endsWith(\".read\")) as T[];\n}\n\nexport const LIFEOPS_REMINDER_CHANNELS = [\n \"in_app\",\n \"sms\",\n \"voice\",\n \"telegram\",\n \"discord\",\n \"signal\",\n \"whatsapp\",\n \"imessage\",\n \"email\",\n \"push\",\n] as const;\nexport type LifeOpsReminderChannel = (typeof LIFEOPS_REMINDER_CHANNELS)[number];\n\nexport const LIFEOPS_CHANNEL_TYPES = [\n \"in_app\",\n \"sms\",\n \"voice\",\n \"telegram\",\n \"discord\",\n \"signal\",\n \"whatsapp\",\n \"imessage\",\n \"x\",\n \"browser\",\n \"email\",\n \"push\",\n // Note: \"cloud\" in LIFEOPS_REMINDER_CHANNELS is a deployment target, not a user-facing delivery channel\n] as const;\nexport type LifeOpsChannelType = (typeof LIFEOPS_CHANNEL_TYPES)[number];\n\nexport const LIFEOPS_PRIVACY_CLASSES = [\"private\", \"shared\", \"public\"] as const;\nexport type LifeOpsPrivacyClass = (typeof LIFEOPS_PRIVACY_CLASSES)[number];\n\nexport const LIFEOPS_DOMAINS = [\"user_lifeops\", \"agent_ops\"] as const;\nexport type LifeOpsDomain = (typeof LIFEOPS_DOMAINS)[number];\n\nexport const LIFEOPS_SUBJECT_TYPES = [\"owner\", \"agent\"] as const;\nexport type LifeOpsSubjectType = (typeof LIFEOPS_SUBJECT_TYPES)[number];\n\nexport const LIFEOPS_VISIBILITY_SCOPES = [\n \"owner_only\",\n \"agent_and_admin\",\n \"owner_agent_admin\",\n] as const;\nexport type LifeOpsVisibilityScope = (typeof LIFEOPS_VISIBILITY_SCOPES)[number];\n\nexport const LIFEOPS_CONTEXT_POLICIES = [\n \"never\",\n \"explicit_only\",\n \"sidebar_only\",\n \"allowed_in_private_chat\",\n] as const;\nexport type LifeOpsContextPolicy = (typeof LIFEOPS_CONTEXT_POLICIES)[number];\n\nexport const LIFEOPS_REMINDER_URGENCY_LEVELS = [\n \"low\",\n \"medium\",\n \"high\",\n \"critical\",\n] as const;\nexport type LifeOpsReminderUrgency =\n (typeof LIFEOPS_REMINDER_URGENCY_LEVELS)[number];\n\nexport const LIFEOPS_REMINDER_INTENSITIES = [\n \"minimal\",\n \"normal\",\n \"persistent\",\n \"high_priority_only\",\n] as const;\nexport type LifeOpsReminderIntensity =\n (typeof LIFEOPS_REMINDER_INTENSITIES)[number];\n\nexport const LIFEOPS_REMINDER_INTENSITY_COMPATIBILITY_VALUES = [\n \"paused\",\n \"low\",\n \"high\",\n] as const;\nexport type LifeOpsReminderIntensityCompatibility =\n (typeof LIFEOPS_REMINDER_INTENSITY_COMPATIBILITY_VALUES)[number];\n\nexport type LifeOpsReminderIntensityInput =\n | LifeOpsReminderIntensity\n | LifeOpsReminderIntensityCompatibility;\n\nexport const LIFEOPS_REMINDER_PREFERENCE_SOURCES = [\n \"default\",\n \"global_policy\",\n \"definition_metadata\",\n] as const;\nexport type LifeOpsReminderPreferenceSource =\n (typeof LIFEOPS_REMINDER_PREFERENCE_SOURCES)[number];\n\nexport const LIFEOPS_OWNER_TYPES = [\n \"definition\",\n \"occurrence\",\n \"goal\",\n \"workflow\",\n \"calendar_event\",\n \"gmail_message\",\n \"connector\",\n \"channel_policy\",\n \"browser_session\",\n \"circadian_state\",\n] as const;\nexport type LifeOpsOwnerType = (typeof LIFEOPS_OWNER_TYPES)[number];\n\nexport const LIFEOPS_AUDIT_EVENT_TYPES = [\n \"definition_created\",\n \"definition_updated\",\n \"definition_deleted\",\n \"occurrence_generated\",\n \"occurrence_completed\",\n \"occurrence_skipped\",\n \"occurrence_snoozed\",\n \"goal_created\",\n \"goal_updated\",\n \"goal_deleted\",\n \"goal_reviewed\",\n \"calendar_event_created\",\n \"calendar_event_updated\",\n \"calendar_event_deleted\",\n \"gmail_triage_synced\",\n \"gmail_reply_drafted\",\n \"gmail_reply_sent\",\n \"gmail_message_sent\",\n \"reminder_due\",\n \"reminder_delivered\",\n \"reminder_blocked\",\n \"reminder_escalation_started\",\n \"reminder_escalation_resolved\",\n \"workflow_created\",\n \"workflow_updated\",\n \"workflow_run\",\n \"connector_grant_updated\",\n \"channel_policy_updated\",\n \"browser_session_created\",\n \"browser_session_updated\",\n \"x_post_sent\",\n \"seeding_offered\",\n \"circadian_event_emitted\",\n \"manual_override_accepted\",\n] as const;\nexport type LifeOpsAuditEventType = (typeof LIFEOPS_AUDIT_EVENT_TYPES)[number];\n\nexport const LIFEOPS_ACTORS = [\n \"agent\",\n \"user\",\n \"workflow\",\n \"connector\",\n] as const;\nexport type LifeOpsActor = (typeof LIFEOPS_ACTORS)[number];\n\nexport interface LifeOpsOwnership {\n domain: LifeOpsDomain;\n subjectType: LifeOpsSubjectType;\n subjectId: string;\n visibilityScope: LifeOpsVisibilityScope;\n contextPolicy: LifeOpsContextPolicy;\n}\n\nexport interface LifeOpsOwnershipInput {\n domain?: LifeOpsDomain;\n subjectType?: LifeOpsSubjectType;\n subjectId?: string;\n visibilityScope?: LifeOpsVisibilityScope;\n contextPolicy?: LifeOpsContextPolicy;\n}\n\nexport interface LifeOpsTimeWindowDefinition {\n name: LifeOpsTimeWindowName;\n label: string;\n startMinute: number;\n endMinute: number;\n}\n\nexport interface LifeOpsWindowPolicy {\n timezone: string;\n windows: LifeOpsTimeWindowDefinition[];\n}\n\nexport interface LifeOpsDailySlot {\n key: string;\n label: string;\n minuteOfDay: number;\n durationMinutes: number;\n}\n\nexport interface LifeOpsIntervalCadence {\n kind: \"interval\";\n everyMinutes: number;\n windows: LifeOpsTimeWindowName[];\n startMinuteOfDay?: number;\n maxOccurrencesPerDay?: number;\n durationMinutes?: number;\n visibilityLeadMinutes?: number;\n visibilityLagMinutes?: number;\n}\n\nexport const LIFEOPS_WEBSITE_ACCESS_UNLOCK_MODES = [\n \"fixed_duration\",\n \"until_manual_lock\",\n \"until_callback\",\n] as const;\nexport type LifeOpsWebsiteAccessUnlockMode =\n (typeof LIFEOPS_WEBSITE_ACCESS_UNLOCK_MODES)[number];\n\nexport interface LifeOpsWebsiteAccessPolicy {\n groupKey: string;\n websites: string[];\n unlockMode: LifeOpsWebsiteAccessUnlockMode;\n unlockDurationMinutes?: number;\n callbackKey?: string | null;\n reason: string;\n}\n\nexport type LifeOpsCadence =\n | {\n kind: \"once\";\n dueAt: string;\n visibilityLeadMinutes?: number;\n visibilityLagMinutes?: number;\n }\n | {\n kind: \"daily\";\n windows: LifeOpsTimeWindowName[];\n visibilityLeadMinutes?: number;\n visibilityLagMinutes?: number;\n }\n | {\n kind: \"times_per_day\";\n slots: LifeOpsDailySlot[];\n visibilityLeadMinutes?: number;\n visibilityLagMinutes?: number;\n }\n | LifeOpsIntervalCadence\n | {\n kind: \"weekly\";\n weekdays: number[];\n windows: LifeOpsTimeWindowName[];\n visibilityLeadMinutes?: number;\n visibilityLagMinutes?: number;\n };\n\nexport type LifeOpsProgressionRule =\n | {\n kind: \"none\";\n }\n | {\n kind: \"linear_increment\";\n metric: string;\n start: number;\n step: number;\n unit?: string;\n };\n\nexport interface LifeOpsReminderStep {\n channel: LifeOpsReminderChannel;\n offsetMinutes: number;\n label: string;\n}\n\nexport interface LifeOpsQuietHoursPolicy {\n timezone: string;\n startMinute: number;\n endMinute: number;\n channels?: LifeOpsReminderChannel[];\n}\n\nexport interface LifeOpsReminderPlan {\n id: string;\n agentId: string;\n ownerType: LifeOpsOwnerType;\n ownerId: string;\n steps: LifeOpsReminderStep[];\n mutePolicy: Record<string, unknown>;\n quietHours: LifeOpsQuietHoursPolicy | Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface LifeOpsTaskDefinition {\n id: string;\n agentId: string;\n domain: LifeOpsDomain;\n subjectType: LifeOpsSubjectType;\n subjectId: string;\n visibilityScope: LifeOpsVisibilityScope;\n contextPolicy: LifeOpsContextPolicy;\n kind: LifeOpsDefinitionKind;\n title: string;\n description: string;\n originalIntent: string;\n timezone: string;\n status: LifeOpsDefinitionStatus;\n priority: number;\n cadence: LifeOpsCadence;\n windowPolicy: LifeOpsWindowPolicy;\n progressionRule: LifeOpsProgressionRule;\n websiteAccess: LifeOpsWebsiteAccessPolicy | null;\n reminderPlanId: string | null;\n goalId: string | null;\n source: string;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface LifeOpsOccurrence {\n id: string;\n agentId: string;\n domain: LifeOpsDomain;\n subjectType: LifeOpsSubjectType;\n subjectId: string;\n visibilityScope: LifeOpsVisibilityScope;\n contextPolicy: LifeOpsContextPolicy;\n definitionId: string;\n occurrenceKey: string;\n scheduledAt: string | null;\n dueAt: string | null;\n relevanceStartAt: string;\n relevanceEndAt: string;\n windowName: string | null;\n state: LifeOpsOccurrenceState;\n snoozedUntil: string | null;\n completionPayload: Record<string, unknown> | null;\n derivedTarget: Record<string, unknown> | null;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface LifeOpsOccurrenceView extends LifeOpsOccurrence {\n definitionKind: LifeOpsDefinitionKind;\n definitionStatus: LifeOpsDefinitionStatus;\n cadence: LifeOpsCadence;\n title: string;\n description: string;\n priority: number;\n timezone: string;\n source: string;\n goalId: string | null;\n}\n\nexport interface LifeOpsGoalDefinition {\n id: string;\n agentId: string;\n domain: LifeOpsDomain;\n subjectType: LifeOpsSubjectType;\n subjectId: string;\n visibilityScope: LifeOpsVisibilityScope;\n contextPolicy: LifeOpsContextPolicy;\n title: string;\n description: string;\n cadence: Record<string, unknown> | null;\n supportStrategy: Record<string, unknown>;\n successCriteria: Record<string, unknown>;\n status: LifeOpsGoalStatus;\n reviewState: LifeOpsGoalReviewState;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface LifeOpsGoalLink {\n id: string;\n agentId: string;\n goalId: string;\n linkedType: LifeOpsOwnerType;\n linkedId: string;\n createdAt: string;\n}\n\nexport interface LifeOpsWorkflowDefinition {\n id: string;\n agentId: string;\n domain: LifeOpsDomain;\n subjectType: LifeOpsSubjectType;\n subjectId: string;\n visibilityScope: LifeOpsVisibilityScope;\n contextPolicy: LifeOpsContextPolicy;\n title: string;\n triggerType: LifeOpsWorkflowTriggerType;\n schedule: LifeOpsWorkflowSchedule;\n actionPlan: LifeOpsWorkflowActionPlan;\n permissionPolicy: LifeOpsWorkflowPermissionPolicy;\n status: LifeOpsWorkflowStatus;\n createdBy: LifeOpsActor;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface LifeOpsWorkflowRun {\n id: string;\n agentId: string;\n workflowId: string;\n startedAt: string;\n finishedAt: string | null;\n status: LifeOpsWorkflowRunStatus;\n result: Record<string, unknown>;\n auditRef: string | null;\n}\n\nexport type LifeOpsWorkflowSchedule =\n | {\n kind: \"manual\";\n }\n | {\n kind: \"once\";\n runAt: string;\n timezone: string;\n }\n | {\n kind: \"interval\";\n everyMinutes: number;\n timezone: string;\n }\n | {\n kind: \"cron\";\n cronExpression: string;\n timezone: string;\n }\n | {\n kind: \"relative_to_wake\";\n /** Minutes offset from wake anchor (wake.confirmed). Negative = before. */\n offsetMinutes: number;\n timezone: string;\n onDays?: number[];\n /** Minimum regularity required before projecting an anchor. Default: `regular`. */\n requireRegularityAtLeast?: LifeOpsRegularityClass;\n /**\n * Minutes of sustained awake state after `wake.observed` required before\n * the workflow fires. When set, the resolver waits for a `wake.confirmed`\n * event rather than using the raw wake anchor.\n */\n stabilityWindowMinutes?: number;\n }\n | {\n kind: \"relative_to_bedtime\";\n offsetMinutes: number;\n timezone: string;\n onDays?: number[];\n requireRegularityAtLeast?: LifeOpsRegularityClass;\n }\n | {\n /**\n * Fires during the canonical \"morning\" window anchored on the latest\n * wake.confirmed. The window starts at `wakeConfirmedAt` and ends\n * `windowMinutesFromWake` later (default 240). Workflow scheduler emits\n * exactly once per morning window when the workflow becomes eligible.\n */\n kind: \"during_morning\";\n timezone: string;\n windowMinutesFromWake?: number;\n onDays?: number[];\n requireRegularityAtLeast?: LifeOpsRegularityClass;\n }\n | {\n /**\n * Fires during the canonical \"night\" window anchored on the projected\n * bedtime target. The window starts `windowMinutesBeforeSleepTarget`\n * before the bedtime target and ends at `sleep.detected`. Fires exactly\n * once per night window when the workflow becomes eligible.\n */\n kind: \"during_night\";\n timezone: string;\n windowMinutesBeforeSleepTarget?: number;\n onDays?: number[];\n requireRegularityAtLeast?: LifeOpsRegularityClass;\n }\n | {\n kind: \"event\";\n eventKind: LifeOpsEventKind;\n filters?: LifeOpsEventFilters;\n };\n\nexport interface LifeOpsWorkflowPermissionPolicy {\n allowBrowserActions: boolean;\n trustedBrowserActions: boolean;\n allowXPosts: boolean;\n trustedXPosting: boolean;\n requireConfirmationForBrowserActions: boolean;\n requireConfirmationForXPosts: boolean;\n}\n\n// Generic browser-companion + packaging contracts live in\n// `@elizaos/plugin-browser/contracts`. `LIFEOPS_BROWSER_KINDS`,\n// `LifeOpsBrowserKind`, `LIFEOPS_BROWSER_ACTION_KINDS`,\n// `LifeOpsBrowserActionKind`, and `LifeOpsBrowserAction` remain here\n// because workflow-linked session shapes below still reference them;\n// Phase 5 will revisit those references.\nexport const LIFEOPS_BROWSER_KINDS = [\"chrome\", \"safari\"] as const;\nexport type LifeOpsBrowserKind = (typeof LIFEOPS_BROWSER_KINDS)[number];\n\nexport const LIFEOPS_BROWSER_ACTION_KINDS = [\n \"open\",\n \"navigate\",\n \"focus_tab\",\n \"back\",\n \"forward\",\n \"reload\",\n \"click\",\n \"type\",\n \"submit\",\n \"read_page\",\n \"extract_links\",\n \"extract_forms\",\n] as const;\nexport type LifeOpsBrowserActionKind =\n (typeof LIFEOPS_BROWSER_ACTION_KINDS)[number];\n\nexport interface LifeOpsBrowserAction {\n id: string;\n kind: LifeOpsBrowserActionKind;\n label: string;\n browser?: LifeOpsBrowserKind | null;\n windowId?: string | null;\n tabId?: string | null;\n url: string | null;\n selector: string | null;\n text: string | null;\n accountAffecting: boolean;\n requiresConfirmation: boolean;\n metadata: Record<string, unknown>;\n}\n\nexport interface LifeOpsWorkflowActionBase {\n id?: string;\n resultKey?: string;\n}\n\nexport type LifeOpsWorkflowAction =\n | (LifeOpsWorkflowActionBase & {\n kind: \"create_task\";\n request: CreateLifeOpsDefinitionRequest;\n })\n | (LifeOpsWorkflowActionBase & {\n kind: \"relock_website_access\";\n request: {\n groupKey: string;\n };\n })\n | (LifeOpsWorkflowActionBase & {\n kind: \"resolve_website_access_callback\";\n request: {\n callbackKey: string;\n };\n })\n | (LifeOpsWorkflowActionBase & {\n kind: \"get_calendar_feed\";\n request?: GetLifeOpsCalendarFeedRequest;\n })\n | (LifeOpsWorkflowActionBase & {\n kind: \"get_gmail_triage\";\n request?: GetLifeOpsGmailTriageRequest;\n })\n | (LifeOpsWorkflowActionBase & {\n kind: \"get_gmail_unresponded\";\n request?: GetLifeOpsGmailUnrespondedRequest;\n })\n | (LifeOpsWorkflowActionBase & {\n kind: \"get_health_summary\";\n request?: GetLifeOpsHealthSummaryRequest;\n })\n | (LifeOpsWorkflowActionBase & {\n kind: \"dispatch_workflow\";\n workflowId: string;\n payload?: Record<string, unknown>;\n })\n | (LifeOpsWorkflowActionBase & {\n kind: \"summarize\";\n sourceKey?: string;\n prompt?: string;\n })\n | (LifeOpsWorkflowActionBase & {\n kind: \"browser\";\n sessionTitle: string;\n actions: Array<Omit<LifeOpsBrowserAction, \"id\">>;\n });\n\nexport interface LifeOpsWorkflowActionPlan {\n steps: LifeOpsWorkflowAction[];\n}\n\nexport const LIFEOPS_REMINDER_ATTEMPT_OUTCOMES = [\n \"delivered\",\n \"delivered_read\",\n \"delivered_unread\",\n \"blocked_policy\",\n \"blocked_quiet_hours\",\n \"blocked_urgency\",\n \"blocked_acknowledged\",\n \"blocked_connector\",\n \"skipped_duplicate\",\n] as const;\nexport type LifeOpsReminderAttemptOutcome =\n (typeof LIFEOPS_REMINDER_ATTEMPT_OUTCOMES)[number];\n\nexport type LifeOpsReminderReviewStatus =\n | \"unrelated\"\n | \"needs_clarification\"\n | \"no_response\"\n | \"resolved\"\n | \"escalated\"\n | \"clarification_requested\";\n\nexport interface LifeOpsReminderAttempt {\n id: string;\n agentId: string;\n planId: string;\n ownerType: LifeOpsOwnerType;\n ownerId: string;\n occurrenceId: string | null;\n channel: LifeOpsReminderChannel;\n stepIndex: number;\n scheduledFor: string;\n attemptedAt: string | null;\n outcome: LifeOpsReminderAttemptOutcome;\n connectorRef: string | null;\n deliveryMetadata: Record<string, unknown>;\n reviewAt?: string | null;\n reviewStatus?: LifeOpsReminderReviewStatus | null;\n}\n\nexport interface LifeOpsConnectorGrant {\n id: string;\n agentId: string;\n provider: LifeOpsConnectorProvider;\n /** LifeOps-owned stable account key; grant id remains legacy credential state. */\n connectorAccountId?: string | null;\n side: LifeOpsConnectorSide;\n identity: Record<string, unknown>;\n identityEmail?: string | null;\n grantedScopes: string[];\n capabilities: string[];\n tokenRef: string | null;\n mode: LifeOpsConnectorMode;\n executionTarget: LifeOpsConnectorExecutionTarget;\n sourceOfTruth: LifeOpsConnectorSourceOfTruth;\n preferredByAgent: boolean;\n cloudConnectionId: string | null;\n metadata: Record<string, unknown>;\n lastRefreshAt: string | null;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface LifeOpsChannelPolicy {\n id: string;\n agentId: string;\n channelType: LifeOpsChannelType;\n channelRef: string;\n privacyClass: LifeOpsPrivacyClass;\n allowReminders: boolean;\n allowEscalation: boolean;\n allowPosts: boolean;\n requireConfirmationForActions: boolean;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport const LIFEOPS_ACTIVITY_SIGNAL_SOURCES = [\n \"app_lifecycle\",\n \"page_visibility\",\n \"desktop_power\",\n \"desktop_interaction\",\n \"connector_activity\",\n \"imessage_outbound\",\n \"mobile_device\",\n \"mobile_health\",\n] as const;\nexport type LifeOpsActivitySignalSource =\n (typeof LIFEOPS_ACTIVITY_SIGNAL_SOURCES)[number];\n\nexport const LIFEOPS_ACTIVITY_SIGNAL_STATES = [\n \"active\",\n \"idle\",\n \"background\",\n \"locked\",\n \"sleeping\",\n] as const;\nexport type LifeOpsActivitySignalState =\n (typeof LIFEOPS_ACTIVITY_SIGNAL_STATES)[number];\n\nexport const LIFEOPS_HEALTH_SIGNAL_SOURCES = [\n \"healthkit\",\n \"health_connect\",\n \"strava\",\n \"fitbit\",\n \"withings\",\n \"oura\",\n] as const;\nexport type LifeOpsHealthSignalSource =\n (typeof LIFEOPS_HEALTH_SIGNAL_SOURCES)[number];\n\nexport interface LifeOpsHealthSignalSleepSummary {\n available: boolean;\n isSleeping: boolean;\n asleepAt: string | null;\n awakeAt: string | null;\n durationMinutes: number | null;\n stage: string | null;\n}\n\nexport interface LifeOpsHealthSignalBiometrics {\n sampleAt: string | null;\n heartRateBpm: number | null;\n restingHeartRateBpm: number | null;\n heartRateVariabilityMs: number | null;\n respiratoryRate: number | null;\n bloodOxygenPercent: number | null;\n}\n\nexport interface LifeOpsHealthSignal {\n source: LifeOpsHealthSignalSource;\n permissions: {\n sleep: boolean;\n biometrics: boolean;\n };\n sleep: LifeOpsHealthSignalSleepSummary;\n biometrics: LifeOpsHealthSignalBiometrics;\n warnings: string[];\n}\n\nexport const LIFEOPS_HEALTH_CONNECTOR_REASONS = [\n \"connected\",\n \"disconnected\",\n \"config_missing\",\n \"needs_reauth\",\n \"sync_failed\",\n] as const;\nexport type LifeOpsHealthConnectorReason =\n (typeof LIFEOPS_HEALTH_CONNECTOR_REASONS)[number];\n\nexport interface LifeOpsHealthConnectorStatus {\n provider: LifeOpsHealthConnectorProvider;\n side: LifeOpsConnectorSide;\n mode: LifeOpsConnectorMode;\n defaultMode: LifeOpsConnectorMode;\n availableModes: LifeOpsConnectorMode[];\n executionTarget: LifeOpsConnectorExecutionTarget;\n sourceOfTruth: LifeOpsConnectorSourceOfTruth;\n configured: boolean;\n connected: boolean;\n reason: LifeOpsHealthConnectorReason;\n identity: Record<string, unknown> | null;\n grantedCapabilities: LifeOpsHealthConnectorCapability[];\n grantedScopes: string[];\n expiresAt: string | null;\n hasRefreshToken: boolean;\n lastSyncAt: string | null;\n grant: LifeOpsConnectorGrant | null;\n degradations?: LifeOpsConnectorDegradation[];\n}\n\nexport interface LifeOpsHealthMetricSample {\n id: string;\n agentId: string;\n provider: LifeOpsHealthConnectorProvider;\n grantId: string;\n metric: LifeOpsHealthMetric;\n value: number;\n unit: string;\n startAt: string;\n endAt: string;\n localDate: string;\n sourceExternalId: string;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface LifeOpsHealthWorkout {\n id: string;\n agentId: string;\n provider: LifeOpsHealthConnectorProvider;\n grantId: string;\n sourceExternalId: string;\n workoutType: string;\n title: string;\n startAt: string;\n endAt: string | null;\n durationSeconds: number;\n distanceMeters: number | null;\n calories: number | null;\n averageHeartRate: number | null;\n maxHeartRate: number | null;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface LifeOpsHealthSyncState {\n id: string;\n agentId: string;\n provider: LifeOpsHealthConnectorProvider;\n grantId: string;\n cursor: string | null;\n lastSyncedAt: string | null;\n lastSyncStartedAt: string | null;\n lastSyncError: string | null;\n metadata: Record<string, unknown>;\n updatedAt: string;\n}\n\nexport const LIFEOPS_HEALTH_SLEEP_STAGES = [\n \"awake\",\n \"light\",\n \"deep\",\n \"rem\",\n \"restless\",\n \"unknown\",\n] as const;\nexport type LifeOpsHealthSleepStage =\n (typeof LIFEOPS_HEALTH_SLEEP_STAGES)[number];\n\nexport interface LifeOpsHealthSleepStageSample {\n stage: LifeOpsHealthSleepStage;\n startAt: string;\n endAt: string;\n confidence: number | null;\n providerCode: string | null;\n}\n\nexport interface LifeOpsHealthSleepEpisode {\n id: string;\n agentId: string;\n provider: LifeOpsHealthConnectorProvider;\n grantId: string;\n sourceExternalId: string;\n localDate: string;\n timezone: string | null;\n startAt: string;\n endAt: string;\n isMainSleep: boolean;\n sleepType: string | null;\n durationSeconds: number;\n timeInBedSeconds: number | null;\n efficiency: number | null;\n latencySeconds: number | null;\n awakeSeconds: number | null;\n lightSleepSeconds: number | null;\n deepSleepSeconds: number | null;\n remSleepSeconds: number | null;\n sleepScore: number | null;\n readinessScore: number | null;\n averageHeartRate: number | null;\n lowestHeartRate: number | null;\n averageHrvMs: number | null;\n respiratoryRate: number | null;\n bloodOxygenPercent: number | null;\n stageSamples: LifeOpsHealthSleepStageSample[];\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface LifeOpsHealthDailySummary {\n date: string;\n provider: LifeOpsHealthConnectorProvider | \"healthkit\" | \"google-fit\";\n steps: number;\n activeMinutes: number;\n sleepHours: number;\n calories: number | null;\n distanceMeters: number | null;\n heartRateAvg: number | null;\n restingHeartRate: number | null;\n hrvMs: number | null;\n sleepScore: number | null;\n readinessScore: number | null;\n weightKg: number | null;\n bloodPressureSystolic: number | null;\n bloodPressureDiastolic: number | null;\n bloodOxygenPercent: number | null;\n}\n\nexport interface GetLifeOpsHealthSummaryRequest {\n provider?: LifeOpsHealthConnectorProvider | null;\n mode?: LifeOpsConnectorMode;\n side?: LifeOpsConnectorSide;\n days?: number;\n startDate?: string | null;\n endDate?: string | null;\n metrics?: LifeOpsHealthMetric[];\n forceSync?: boolean;\n}\n\nexport interface LifeOpsHealthSummaryResponse {\n providers: LifeOpsHealthConnectorStatus[];\n summaries: LifeOpsHealthDailySummary[];\n samples: LifeOpsHealthMetricSample[];\n workouts: LifeOpsHealthWorkout[];\n sleepEpisodes: LifeOpsHealthSleepEpisode[];\n syncedAt: string;\n}\n\nexport interface StartLifeOpsHealthConnectorRequest {\n provider: LifeOpsHealthConnectorProvider;\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n redirectUrl?: string;\n capabilities?: LifeOpsHealthConnectorCapability[];\n}\n\nexport interface StartLifeOpsHealthConnectorResponse {\n provider: LifeOpsHealthConnectorProvider;\n side: LifeOpsConnectorSide;\n mode: LifeOpsConnectorMode;\n requestedCapabilities: LifeOpsHealthConnectorCapability[];\n redirectUri: string;\n authUrl: string | null;\n}\n\nexport interface DisconnectLifeOpsHealthConnectorRequest {\n provider: LifeOpsHealthConnectorProvider;\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n grantId?: string;\n}\n\nexport interface SyncLifeOpsHealthConnectorRequest {\n provider?: LifeOpsHealthConnectorProvider | null;\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n startDate?: string | null;\n endDate?: string | null;\n days?: number;\n}\n\nexport interface LifeOpsActivitySignal {\n id: string;\n agentId: string;\n source: LifeOpsActivitySignalSource;\n platform: string;\n state: LifeOpsActivitySignalState;\n observedAt: string;\n idleState: \"active\" | \"idle\" | \"locked\" | \"unknown\" | null;\n idleTimeSeconds: number | null;\n onBattery: boolean | null;\n health: LifeOpsHealthSignal | null;\n metadata: Record<string, unknown>;\n createdAt: string;\n}\n\n// ---------------------------------------------------------------------------\n// Telemetry event families (canonical store).\n//\n// See `eliza/plugins/app-lifeops/docs/telemetry-event-families.md` for the full\n// spec. Every telemetry payload is a fully-typed discriminated-union variant\n// per the no-`unknown`/no-`any` rule.\n// ---------------------------------------------------------------------------\n\nexport type LifeOpsDevicePlatform =\n | \"macos_desktop\"\n | \"macos_electrobun\"\n | \"ios_capacitor\"\n | \"ipados_capacitor\"\n | \"browser_web\";\n\nexport interface LifeOpsDevicePresencePayload {\n family: \"device_presence_event\";\n platform: LifeOpsDevicePlatform;\n state: LifeOpsActivitySignalState;\n deviceId: string;\n isTransition: boolean;\n sequence: number;\n}\n\nexport type LifeOpsDesktopPowerEventKind =\n | \"system_wake\"\n | \"system_sleep\"\n | \"screen_wake\"\n | \"screen_sleep\"\n | \"session_lock\"\n | \"session_unlock\"\n | \"ac_plug\"\n | \"ac_unplug\";\n\nexport interface LifeOpsDesktopPowerPayload {\n family: \"desktop_power_event\";\n platform: \"macos_desktop\" | \"macos_electrobun\";\n kind: LifeOpsDesktopPowerEventKind;\n batteryPercent: number | null;\n}\n\nexport interface LifeOpsDesktopIdleSamplePayload {\n family: \"desktop_idle_sample\";\n platform: \"macos_desktop\" | \"macos_electrobun\";\n idleSeconds: number;\n source: \"iokit_hid\" | \"cgevent\" | \"collector_synthesized\";\n isThresholdCrossing: boolean;\n}\n\nexport interface LifeOpsBrowserFocusPayload {\n family: \"browser_focus_window\";\n platform: \"browser_web\" | \"macos_electrobun\";\n startAt: string;\n endAt: string;\n domain: string;\n tabId: string;\n focusedSeconds: number;\n}\n\nexport interface LifeOpsMobileHealthPayload {\n family: \"mobile_health_snapshot\";\n platform: \"ios_capacitor\" | \"ipados_capacitor\";\n signal: LifeOpsHealthSignal;\n sampleId: string | null;\n}\n\nexport type LifeOpsMobileDeviceTelemetrySource =\n | \"capacitor_mobile_signals\"\n | \"macos_continuity_probe\";\n\nexport interface LifeOpsMobileDevicePayload {\n family: \"mobile_device_snapshot\";\n platform: \"ios_capacitor\" | \"ipados_capacitor\" | \"macos_desktop\";\n source: LifeOpsMobileDeviceTelemetrySource;\n locked: boolean;\n idleTimeSeconds: number | null;\n onBattery: boolean | null;\n batteryPercent: number | null;\n pairedDeviceId: string | null;\n}\n\nexport type LifeOpsTelemetryMessageChannel =\n | \"gmail\"\n | \"x_dm\"\n | \"discord\"\n | \"telegram\"\n | \"signal\"\n | \"imessage\"\n | \"whatsapp\"\n | \"sms\"\n | \"eliza_chat\";\n\nexport type LifeOpsMessageDirection = \"inbound\" | \"outbound_by_owner\";\n\nexport interface LifeOpsMessageActivityPayload {\n family: \"message_activity_event\";\n platform: LifeOpsDevicePlatform;\n channel: LifeOpsTelemetryMessageChannel;\n direction: LifeOpsMessageDirection;\n externalMessageId: string;\n senderHash: string;\n conversationHash: string;\n}\n\nexport type LifeOpsStatusPlatform = \"slack\" | \"discord\" | \"telegram\" | \"x\";\n\nexport type LifeOpsStatusTransition =\n | \"online\"\n | \"offline\"\n | \"away\"\n | \"do_not_disturb\"\n | \"custom_set\"\n | \"custom_cleared\";\n\nexport interface LifeOpsStatusActivityPayload {\n family: \"status_activity_event\";\n platform: LifeOpsStatusPlatform;\n transition: LifeOpsStatusTransition;\n}\n\nexport interface LifeOpsChargingPayload {\n family: \"charging_event\";\n platform: LifeOpsDevicePlatform;\n connected: boolean;\n batteryPercent: number;\n}\n\nexport interface LifeOpsScreenTimePerAppUsage {\n appBundleId: string;\n minutesUsed: number;\n}\n\nexport interface LifeOpsScreenTimeSummaryPayload {\n family: \"screen_time_summary\";\n platform: \"ios_capacitor\" | \"ipados_capacitor\" | \"macos_desktop\";\n intervalStartAt: string;\n intervalEndAt: string;\n totalMinutesUsed: number;\n apps: LifeOpsScreenTimePerAppUsage[];\n}\n\nexport type LifeOpsManualOverrideTelemetryKind =\n | \"going_to_bed\"\n | \"just_woke_up\";\n\nexport interface LifeOpsManualOverridePayload {\n family: \"manual_override_event\";\n platform: LifeOpsDevicePlatform;\n kind: LifeOpsManualOverrideTelemetryKind;\n note: string | null;\n}\n\nexport type LifeOpsTelemetryPayload =\n | LifeOpsDevicePresencePayload\n | LifeOpsDesktopPowerPayload\n | LifeOpsDesktopIdleSamplePayload\n | LifeOpsBrowserFocusPayload\n | LifeOpsMobileHealthPayload\n | LifeOpsMobileDevicePayload\n | LifeOpsMessageActivityPayload\n | LifeOpsStatusActivityPayload\n | LifeOpsChargingPayload\n | LifeOpsScreenTimeSummaryPayload\n | LifeOpsManualOverridePayload;\n\nexport type LifeOpsTelemetryFamily = LifeOpsTelemetryPayload[\"family\"];\n\nexport const LIFEOPS_TELEMETRY_FAMILIES: readonly LifeOpsTelemetryFamily[] = [\n \"device_presence_event\",\n \"desktop_power_event\",\n \"desktop_idle_sample\",\n \"browser_focus_window\",\n \"mobile_health_snapshot\",\n \"mobile_device_snapshot\",\n \"message_activity_event\",\n \"status_activity_event\",\n \"charging_event\",\n \"screen_time_summary\",\n \"manual_override_event\",\n];\n\nexport interface LifeOpsTelemetryEnvelope {\n id: string;\n agentId: string;\n family: LifeOpsTelemetryFamily;\n occurredAt: string;\n ingestedAt: string;\n dedupeKey: string;\n sourceReliability: number;\n}\n\nexport type LifeOpsTelemetryEvent = LifeOpsTelemetryEnvelope & {\n payload: LifeOpsTelemetryPayload;\n};\n\nexport interface LifeOpsReminderPreferenceSetting {\n intensity: LifeOpsReminderIntensity;\n source: LifeOpsReminderPreferenceSource;\n updatedAt: string | null;\n note: string | null;\n}\n\nexport interface LifeOpsReminderPreference {\n definitionId: string | null;\n definitionTitle: string | null;\n global: LifeOpsReminderPreferenceSetting;\n definition: LifeOpsReminderPreferenceSetting | null;\n effective: LifeOpsReminderPreferenceSetting;\n}\n\nexport interface LifeOpsAuditEvent {\n id: string;\n agentId: string;\n eventType: LifeOpsAuditEventType;\n ownerType: LifeOpsOwnerType;\n ownerId: string;\n reason: string;\n inputs: Record<string, unknown>;\n decision: Record<string, unknown>;\n actor: LifeOpsActor;\n createdAt: string;\n}\n\nexport interface LifeOpsActiveReminderView {\n domain: LifeOpsDomain;\n subjectType: LifeOpsSubjectType;\n subjectId: string;\n ownerType: \"occurrence\" | \"calendar_event\";\n ownerId: string;\n occurrenceId: string | null;\n definitionId: string | null;\n eventId: string | null;\n title: string;\n channel: LifeOpsReminderChannel;\n stepIndex: number;\n stepLabel: string;\n scheduledFor: string;\n dueAt: string | null;\n state: LifeOpsOccurrenceState | \"upcoming\";\n metadata?: Record<string, unknown>;\n htmlLink?: string | null;\n eventStartAt?: string | null;\n}\n\nexport interface LifeOpsOverviewSummary {\n activeOccurrenceCount: number;\n overdueOccurrenceCount: number;\n snoozedOccurrenceCount: number;\n activeReminderCount: number;\n activeGoalCount: number;\n}\n\nexport const LIFEOPS_CIRCADIAN_STATES = [\n \"awake\",\n \"winding_down\",\n \"sleeping\",\n \"waking\",\n \"napping\",\n \"unclear\",\n] as const;\n\nexport type LifeOpsCircadianState = (typeof LIFEOPS_CIRCADIAN_STATES)[number];\n\nexport const LIFEOPS_UNCLEAR_REASONS = [\n \"no_signals\",\n \"contradictory_signals\",\n \"insufficient_history\",\n \"permission_blocked\",\n \"signal_outage\",\n \"boot_cold_start\",\n \"stale_state\",\n] as const;\n\nexport type LifeOpsUnclearReason = (typeof LIFEOPS_UNCLEAR_REASONS)[number];\n\nexport type LifeOpsScheduleSleepStatus =\n | \"sleeping_now\"\n | \"slept\"\n | \"likely_missed\"\n | \"unknown\";\n\nexport type LifeOpsSleepCycleEvidenceSource = \"health\" | \"activity_gap\";\nexport type LifeOpsSleepCycleType = \"nap\" | \"overnight\" | \"unknown\";\n\nexport type LifeOpsRegularityClass =\n | \"very_regular\"\n | \"regular\"\n | \"irregular\"\n | \"very_irregular\"\n | \"insufficient_data\";\n\nexport interface LifeOpsScheduleRegularity {\n sri: number;\n bedtimeStddevMin: number;\n wakeStddevMin: number;\n midSleepStddevMin: number;\n regularityClass: LifeOpsRegularityClass;\n sampleCount: number;\n windowDays: number;\n}\n\n/**\n * Personal baseline derived from persisted sleep episodes over `windowDays`.\n * Medians are computed via circular mean (sin/cos projection) so bedtimes\n * crossing midnight produce correct answers. Returned as `null` on\n * `LifeOpsScheduleInsight` when `sampleCount < 5` — the scalar typical hours\n * that previously existed are deleted from the contract.\n */\nexport interface LifeOpsPersonalBaseline {\n /** Local wake hour in [0, 24). Circular mean over episode end instants. */\n medianWakeLocalHour: number;\n /** Local bedtime hour in [12, 36) (normalized so evening hours are next-day). Circular mean. */\n medianBedtimeLocalHour: number;\n /** Median sleep episode duration in minutes. */\n medianSleepDurationMin: number;\n /** Circular stddev of bedtime in minutes. */\n bedtimeStddevMin: number;\n /** Circular stddev of wake time in minutes. */\n wakeStddevMin: number;\n /** Number of persisted episodes that fed the computation. */\n sampleCount: number;\n /** Size of the look-back window in days (default 28). */\n windowDays: number;\n}\n\nexport type LifeOpsAwakeProbabilitySource =\n | LifeOpsActivitySignalSource\n | \"prior\"\n | \"health\"\n | \"activity_gap\";\n\nexport interface LifeOpsAwakeProbabilityContributor {\n source: LifeOpsAwakeProbabilitySource;\n logLikelihoodRatio: number;\n}\n\nexport interface LifeOpsAwakeProbability {\n pAwake: number;\n pAsleep: number;\n pUnknown: number;\n contributingSources: LifeOpsAwakeProbabilityContributor[];\n computedAt: string;\n}\n\nexport interface LifeOpsSleepCycleEvidence {\n startAt: string;\n endAt: string | null;\n source: LifeOpsSleepCycleEvidenceSource;\n confidence: number;\n}\n\nexport interface LifeOpsSleepCycle {\n cycleType: LifeOpsSleepCycleType;\n sleepStatus: LifeOpsScheduleSleepStatus;\n isProbablySleeping: boolean;\n sleepConfidence: number;\n currentSleepStartedAt: string | null;\n lastSleepStartedAt: string | null;\n lastSleepEndedAt: string | null;\n lastSleepDurationMinutes: number | null;\n evidence: LifeOpsSleepCycleEvidence[];\n}\n\nexport type LifeOpsDayBoundaryAnchor =\n | \"start_of_day\"\n | \"end_of_day\"\n | \"before_sleep\";\n\nexport interface LifeOpsDayBoundary {\n effectiveDayKey: string;\n localDate: string;\n timezone: string;\n anchor: LifeOpsDayBoundaryAnchor;\n startOfDayAt: string;\n endOfDayAt: string;\n beforeSleepAt: string | null;\n confidence: number;\n}\n\nexport type LifeOpsRelativeTimeAnchorSource =\n | \"sleep_cycle\"\n | \"activity\"\n | \"typical_sleep\"\n | \"day_boundary\";\n\nexport interface LifeOpsRelativeTime {\n computedAt: string;\n localNowAt: string;\n circadianState: LifeOpsCircadianState;\n stateConfidence: number;\n uncertaintyReason: LifeOpsUnclearReason | null;\n awakeProbability: LifeOpsAwakeProbability;\n wakeAnchorAt: string | null;\n wakeAnchorSource: LifeOpsRelativeTimeAnchorSource | null;\n minutesSinceWake: number | null;\n minutesAwake: number | null;\n bedtimeTargetAt: string | null;\n bedtimeTargetSource: LifeOpsRelativeTimeAnchorSource | null;\n minutesUntilBedtimeTarget: number | null;\n minutesSinceBedtimeTarget: number | null;\n dayBoundaryStartAt: string;\n dayBoundaryEndAt: string;\n minutesSinceDayBoundaryStart: number;\n minutesUntilDayBoundaryEnd: number;\n confidence: number;\n}\n\nexport type LifeOpsScheduleMealLabel = \"breakfast\" | \"lunch\" | \"dinner\";\n\nexport type LifeOpsScheduleMealSource =\n | \"activity_gap\"\n | \"expected_window\"\n | \"health\";\n\nexport interface LifeOpsScheduleMealInsight {\n label: LifeOpsScheduleMealLabel;\n detectedAt: string;\n confidence: number;\n source: LifeOpsScheduleMealSource;\n}\n\n/**\n * A single rule firing from `scoreCircadianRules`. Persisted on the schedule\n * insight so the inspection UI can explain *why* the state machine landed\n * where it did without re-running inference.\n */\nexport interface LifeOpsCircadianRuleFiring {\n name: string;\n contributes: LifeOpsCircadianState;\n weight: number;\n observedAt: string;\n reason: string;\n}\n\nexport interface LifeOpsScheduleInsight {\n effectiveDayKey: string;\n localDate: string;\n timezone: string;\n inferredAt: string;\n circadianState: LifeOpsCircadianState;\n stateConfidence: number;\n uncertaintyReason: LifeOpsUnclearReason | null;\n relativeTime: LifeOpsRelativeTime;\n awakeProbability: LifeOpsAwakeProbability;\n regularity: LifeOpsScheduleRegularity;\n baseline: LifeOpsPersonalBaseline | null;\n /**\n * Named-rules evidence from the circadian scorer. Ordered by descending\n * weight. Empty when `circadianState === \"unclear\"` and no rules fired.\n */\n circadianRuleFirings: LifeOpsCircadianRuleFiring[];\n sleepStatus: LifeOpsScheduleSleepStatus;\n sleepConfidence: number;\n currentSleepStartedAt: string | null;\n lastSleepStartedAt: string | null;\n lastSleepEndedAt: string | null;\n lastSleepDurationMinutes: number | null;\n wakeAt: string | null;\n firstActiveAt: string | null;\n lastActiveAt: string | null;\n meals: LifeOpsScheduleMealInsight[];\n lastMealAt: string | null;\n nextMealLabel: LifeOpsScheduleMealLabel | null;\n nextMealWindowStartAt: string | null;\n nextMealWindowEndAt: string | null;\n nextMealConfidence: number;\n}\n\nexport type LifeOpsCapabilityDomain =\n | \"core\"\n | \"schedule\"\n | \"reminders\"\n | \"activity\"\n | \"connectors\"\n | \"profile\";\n\nexport type LifeOpsCapabilityState =\n | \"working\"\n | \"degraded\"\n | \"blocked\"\n | \"not_configured\";\n\nexport interface LifeOpsCapabilityEvidence {\n label: string;\n state: LifeOpsCapabilityState;\n detail: string | null;\n observedAt: string | null;\n}\n\nexport interface LifeOpsCapabilityStatus {\n id: string;\n domain: LifeOpsCapabilityDomain;\n label: string;\n state: LifeOpsCapabilityState;\n summary: string;\n confidence: number;\n lastCheckedAt: string;\n evidence: LifeOpsCapabilityEvidence[];\n}\n\nexport interface LifeOpsCapabilitiesSummary {\n totalCount: number;\n workingCount: number;\n degradedCount: number;\n blockedCount: number;\n notConfiguredCount: number;\n}\n\nexport interface LifeOpsCapabilitiesStatus {\n generatedAt: string;\n appEnabled: boolean;\n relativeTime: LifeOpsRelativeTime | null;\n capabilities: LifeOpsCapabilityStatus[];\n summary: LifeOpsCapabilitiesSummary;\n}\n\nexport interface LifeOpsOverviewSection {\n occurrences: LifeOpsOccurrenceView[];\n goals: LifeOpsGoalDefinition[];\n reminders: LifeOpsActiveReminderView[];\n summary: LifeOpsOverviewSummary;\n}\n\nexport interface LifeOpsOverview {\n occurrences: LifeOpsOccurrenceView[];\n goals: LifeOpsGoalDefinition[];\n reminders: LifeOpsActiveReminderView[];\n summary: LifeOpsOverviewSummary;\n owner: LifeOpsOverviewSection;\n agentOps: LifeOpsOverviewSection;\n schedule: LifeOpsScheduleInsight | null;\n}\n\nexport interface LifeOpsCalendarEventAttendee {\n email: string | null;\n displayName: string | null;\n responseStatus: string | null;\n self: boolean;\n organizer: boolean;\n optional: boolean;\n}\n\nexport interface LifeOpsCalendarEvent {\n id: string;\n externalId: string;\n agentId: string;\n provider: \"google\";\n side: LifeOpsConnectorSide;\n calendarId: string;\n title: string;\n description: string;\n location: string;\n status: string;\n startAt: string;\n endAt: string;\n isAllDay: boolean;\n timezone: string | null;\n htmlLink: string | null;\n conferenceLink: string | null;\n organizer: Record<string, unknown> | null;\n attendees: LifeOpsCalendarEventAttendee[];\n metadata: Record<string, unknown>;\n syncedAt: string;\n updatedAt: string;\n /** Set on merged feeds so the UI can show which calendar an event came from. */\n calendarSummary?: string;\n /** LifeOps-owned account key for privacy egress; legacy cache rows may omit it until purge/resync. */\n connectorAccountId?: string;\n /** Google grant that owns this Gmail message cache row. */\n grantId?: string;\n /** Email address for the owning Google account when known. */\n accountEmail?: string;\n}\n\nexport interface LifeOpsCalendarFeed {\n calendarId: string;\n events: LifeOpsCalendarEvent[];\n source: \"cache\" | \"synced\";\n timeMin: string;\n timeMax: string;\n syncedAt: string | null;\n}\n\n/**\n * Summary of one Google Calendar the user has access to (from calendarList.list).\n * `includeInFeed` reflects whether the user has opted this calendar into the\n * aggregated sidebar feed / briefing. Defaults to true for every calendar the\n * user can see — opt-out, never opt-in, so new calendars are not silently\n * hidden from the agent's picture of the user's life.\n */\nexport interface LifeOpsCalendarSummary {\n provider: \"google\";\n side: LifeOpsConnectorSide;\n grantId: string;\n accountEmail: string | null;\n calendarId: string;\n summary: string;\n description: string | null;\n primary: boolean;\n accessRole: string;\n backgroundColor: string | null;\n foregroundColor: string | null;\n timeZone: string | null;\n selected: boolean;\n includeInFeed: boolean;\n}\n\nexport interface ListLifeOpsCalendarsRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n grantId?: string;\n}\n\nexport interface ListLifeOpsCalendarsResponse {\n calendars: LifeOpsCalendarSummary[];\n}\n\nexport interface SetLifeOpsCalendarIncludedRequest {\n calendarId: string;\n includeInFeed: boolean;\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n grantId?: string;\n}\n\nexport interface SetLifeOpsCalendarIncludedResponse {\n calendar: LifeOpsCalendarSummary;\n}\n\nexport interface GetLifeOpsCalendarFeedRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n /** Target a specific Google account by grant ID (multi-account). */\n grantId?: string;\n calendarId?: string;\n /**\n * Internal/agent override: when no calendarId is specified, include every\n * authorized calendar instead of only the user's feed-enabled subset.\n */\n includeHiddenCalendars?: boolean;\n timeMin?: string;\n timeMax?: string;\n timeZone?: string;\n forceSync?: boolean;\n}\n\nexport interface LifeOpsGmailMessageSummary {\n id: string;\n externalId: string;\n agentId: string;\n provider: \"google\";\n side: LifeOpsConnectorSide;\n threadId: string;\n subject: string;\n from: string;\n fromEmail: string | null;\n replyTo: string | null;\n to: string[];\n cc: string[];\n snippet: string;\n receivedAt: string;\n isUnread: boolean;\n isImportant: boolean;\n likelyReplyNeeded: boolean;\n triageScore: number;\n triageReason: string;\n labels: string[];\n htmlLink: string | null;\n metadata: Record<string, unknown>;\n syncedAt: string;\n updatedAt: string;\n /** LifeOps-owned account key for privacy egress; legacy cache rows may omit it until purge/resync. */\n connectorAccountId?: string;\n /** Set when aggregating across multiple Google accounts. */\n grantId?: string;\n /** Set when aggregating across multiple Google accounts. */\n accountEmail?: string;\n}\n\nexport interface LifeOpsGmailTriageSummary {\n unreadCount: number;\n importantNewCount: number;\n likelyReplyNeededCount: number;\n}\n\nexport interface LifeOpsGmailTriageFeed {\n messages: LifeOpsGmailMessageSummary[];\n source: \"cache\" | \"synced\";\n syncedAt: string | null;\n summary: LifeOpsGmailTriageSummary;\n}\n\nexport interface LifeOpsGmailNeedsResponseSummary {\n totalCount: number;\n unreadCount: number;\n importantCount: number;\n}\n\nexport interface LifeOpsGmailNeedsResponseFeed {\n messages: LifeOpsGmailMessageSummary[];\n source: \"cache\" | \"synced\";\n syncedAt: string | null;\n summary: LifeOpsGmailNeedsResponseSummary;\n}\n\nexport interface GetLifeOpsGmailTriageRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n /** Target a specific Google account by grant ID (multi-account). */\n grantId?: string;\n forceSync?: boolean;\n maxResults?: number;\n}\n\nexport interface GetLifeOpsGmailSearchRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n forceSync?: boolean;\n maxResults?: number;\n query: string;\n replyNeededOnly?: boolean;\n includeSpamTrash?: boolean;\n grantId?: string;\n}\n\nexport interface LifeOpsGmailSearchSummary {\n totalCount: number;\n unreadCount: number;\n importantCount: number;\n replyNeededCount: number;\n}\n\nexport interface LifeOpsGmailSearchFeed {\n query: string;\n messages: LifeOpsGmailMessageSummary[];\n source: \"cache\" | \"synced\";\n syncedAt: string | null;\n summary: LifeOpsGmailSearchSummary;\n}\n\nexport const LIFEOPS_GMAIL_RECOMMENDATION_KINDS = [\n \"reply\",\n \"archive\",\n \"mark_read\",\n \"review_spam\",\n] as const;\nexport type LifeOpsGmailRecommendationKind =\n (typeof LIFEOPS_GMAIL_RECOMMENDATION_KINDS)[number];\n\nexport const LIFEOPS_GMAIL_BULK_OPERATIONS = [\n \"archive\",\n \"trash\",\n \"delete\",\n \"report_spam\",\n \"mark_read\",\n \"mark_unread\",\n \"apply_label\",\n \"remove_label\",\n] as const;\nexport type LifeOpsGmailBulkOperation =\n (typeof LIFEOPS_GMAIL_BULK_OPERATIONS)[number];\n\nexport const LIFEOPS_GMAIL_MANAGE_EXECUTION_MODES = [\n \"proposal\",\n \"dry_run\",\n \"execute\",\n] as const;\nexport type LifeOpsGmailManageExecutionMode =\n (typeof LIFEOPS_GMAIL_MANAGE_EXECUTION_MODES)[number];\n\nexport const LIFEOPS_GMAIL_MANAGE_STATUSES = [\n \"proposed\",\n \"dry_run\",\n \"approved\",\n \"executed\",\n \"partial\",\n \"failed\",\n \"cancelled\",\n] as const;\nexport type LifeOpsGmailManageStatus =\n (typeof LIFEOPS_GMAIL_MANAGE_STATUSES)[number];\n\nexport const LIFEOPS_GMAIL_MANAGE_UNDO_STATUSES = [\n \"not_available\",\n \"available\",\n \"completed\",\n \"expired\",\n \"failed\",\n] as const;\nexport type LifeOpsGmailManageUndoStatus =\n (typeof LIFEOPS_GMAIL_MANAGE_UNDO_STATUSES)[number];\n\nexport interface LifeOpsGmailManageApprovalIdentity {\n proposalId?: string;\n approvalId?: string;\n proposedBy?: LifeOpsActor;\n approvedBy?: LifeOpsActor;\n approvedAt?: string;\n}\n\nexport interface LifeOpsGmailManagePlanIdentity {\n planId?: string;\n planHash?: string;\n idempotencyKey?: string;\n}\n\nexport interface LifeOpsGmailManageMessageSnapshot {\n messageId: string;\n externalId: string;\n threadId: string;\n subject: string;\n from: string;\n fromEmail: string | null;\n receivedAt: string;\n snippet: string;\n labels: string[];\n grantId?: string;\n accountEmail?: string;\n syncedAt?: string;\n snapshotHash?: string;\n}\n\nexport interface LifeOpsGmailManageChunkRequest {\n chunkId: string;\n chunkIndex: number;\n chunkCount: number;\n messageIds?: string[];\n cursor?: string;\n}\n\nexport interface LifeOpsGmailManageChunkStatus {\n chunkId: string;\n chunkIndex: number;\n chunkCount: number;\n processedCount: number;\n remainingCount: number;\n nextCursor: string | null;\n}\n\nexport interface LifeOpsGmailManageAuditContext {\n auditEventId?: string;\n auditRef?: string;\n parentAuditEventId?: string;\n actor?: LifeOpsActor;\n}\n\nexport interface LifeOpsGmailManageAuditState {\n auditEventId: string | null;\n auditRef: string | null;\n actor: LifeOpsActor;\n recordedAt: string | null;\n}\n\nexport interface LifeOpsGmailManageUndoRequest {\n undoId: string;\n auditEventId?: string;\n reason?: string;\n}\n\nexport interface LifeOpsGmailManageUndoState {\n status: LifeOpsGmailManageUndoStatus;\n undoId: string | null;\n undoExpiresAt: string | null;\n auditEventId: string | null;\n messageIds: string[];\n}\n\nexport interface ManageLifeOpsGmailMessagesRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n grantId?: string;\n operation: LifeOpsGmailBulkOperation;\n messageIds?: string[];\n query?: string;\n maxResults?: number;\n labelIds?: string[];\n confirmDestructive?: boolean;\n executionMode?: LifeOpsGmailManageExecutionMode;\n reason?: string;\n approval?: LifeOpsGmailManageApprovalIdentity;\n plan?: LifeOpsGmailManagePlanIdentity;\n selectedMessageSnapshots?: LifeOpsGmailManageMessageSnapshot[];\n chunk?: LifeOpsGmailManageChunkRequest;\n audit?: LifeOpsGmailManageAuditContext;\n undo?: LifeOpsGmailManageUndoRequest;\n}\n\nexport interface LifeOpsGmailManageResult {\n ok: true;\n operation: LifeOpsGmailBulkOperation;\n messageIds: string[];\n affectedCount: number;\n labelIds: string[];\n destructive: boolean;\n grantId?: string;\n accountEmail?: string;\n executionMode?: LifeOpsGmailManageExecutionMode;\n status?: LifeOpsGmailManageStatus;\n reason?: string;\n approval?: LifeOpsGmailManageApprovalIdentity;\n plan?: LifeOpsGmailManagePlanIdentity;\n selectedMessageSnapshots?: LifeOpsGmailManageMessageSnapshot[];\n chunk?: LifeOpsGmailManageChunkStatus;\n audit?: LifeOpsGmailManageAuditState;\n undo?: LifeOpsGmailManageUndoState;\n}\n\nexport interface LifeOpsGmailRecommendationMessage {\n messageId: string;\n subject: string;\n from: string;\n fromEmail: string | null;\n receivedAt: string;\n snippet: string;\n labels: string[];\n}\n\nexport interface LifeOpsGmailRecommendation {\n id: string;\n kind: LifeOpsGmailRecommendationKind;\n title: string;\n rationale: string;\n operation: LifeOpsGmailBulkOperation | null;\n messageIds: string[];\n query: string | null;\n labelIds: string[];\n affectedCount: number;\n destructive: boolean;\n requiresConfirmation: boolean;\n confidence: number;\n sampleMessages: LifeOpsGmailRecommendationMessage[];\n}\n\nexport interface LifeOpsGmailRecommendationsSummary {\n totalCount: number;\n replyCount: number;\n archiveCount: number;\n markReadCount: number;\n spamReviewCount: number;\n destructiveCount: number;\n}\n\nexport interface LifeOpsGmailRecommendationsFeed {\n recommendations: LifeOpsGmailRecommendation[];\n source: \"cache\" | \"synced\";\n syncedAt: string | null;\n summary: LifeOpsGmailRecommendationsSummary;\n}\n\nexport interface GetLifeOpsGmailRecommendationsRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n grantId?: string;\n forceSync?: boolean;\n maxResults?: number;\n query?: string;\n replyNeededOnly?: boolean;\n includeSpamTrash?: boolean;\n}\n\nexport const LIFEOPS_GMAIL_SPAM_REVIEW_STATUSES = [\n \"pending\",\n \"confirmed_spam\",\n \"not_spam\",\n \"dismissed\",\n] as const;\nexport type LifeOpsGmailSpamReviewStatus =\n (typeof LIFEOPS_GMAIL_SPAM_REVIEW_STATUSES)[number];\n\nexport interface LifeOpsGmailSpamReviewItem {\n id: string;\n agentId: string;\n provider: \"google\";\n side: LifeOpsConnectorSide;\n grantId: string;\n accountEmail: string | null;\n messageId: string;\n externalMessageId: string;\n threadId: string;\n subject: string;\n from: string;\n fromEmail: string | null;\n receivedAt: string;\n snippet: string;\n labels: string[];\n rationale: string;\n confidence: number;\n status: LifeOpsGmailSpamReviewStatus;\n createdAt: string;\n updatedAt: string;\n reviewedAt: string | null;\n}\n\nexport interface LifeOpsGmailSpamReviewSummary {\n totalCount: number;\n pendingCount: number;\n confirmedSpamCount: number;\n notSpamCount: number;\n dismissedCount: number;\n}\n\nexport interface LifeOpsGmailSpamReviewFeed {\n items: LifeOpsGmailSpamReviewItem[];\n summary: LifeOpsGmailSpamReviewSummary;\n}\n\nexport interface GetLifeOpsGmailSpamReviewRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n grantId?: string;\n status?: LifeOpsGmailSpamReviewStatus;\n maxResults?: number;\n}\n\nexport interface UpdateLifeOpsGmailSpamReviewItemRequest {\n status: LifeOpsGmailSpamReviewStatus;\n}\n\nexport interface LifeOpsGmailUnrespondedThread {\n threadId: string;\n messageId: string;\n subject: string;\n to: string[];\n cc: string[];\n lastOutboundAt: string;\n lastInboundAt: string | null;\n daysWaiting: number;\n snippet: string;\n labels: string[];\n htmlLink: string | null;\n grantId?: string;\n accountEmail?: string;\n}\n\nexport interface LifeOpsGmailUnrespondedSummary {\n totalCount: number;\n oldestDaysWaiting: number | null;\n}\n\nexport interface LifeOpsGmailUnrespondedFeed {\n threads: LifeOpsGmailUnrespondedThread[];\n source: \"synced\";\n syncedAt: string;\n summary: LifeOpsGmailUnrespondedSummary;\n}\n\nexport interface GetLifeOpsGmailUnrespondedRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n grantId?: string;\n olderThanDays?: number;\n maxResults?: number;\n}\n\nexport interface IngestLifeOpsGmailEventRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n grantId?: string;\n messageId: string;\n eventKind?: \"gmail.message.received\" | \"gmail.thread.needs_response\";\n occurredAt?: string;\n maxWorkflowRuns?: number;\n}\n\nexport interface LifeOpsGmailEventIngestResult {\n ok: true;\n event: {\n id: string;\n kind: \"gmail.message.received\" | \"gmail.thread.needs_response\";\n occurredAt: string;\n payload: Record<string, unknown>;\n };\n workflowRunIds: string[];\n}\n\nexport const LIFEOPS_GMAIL_DRAFT_TONES = [\"brief\", \"neutral\", \"warm\"] as const;\nexport type LifeOpsGmailDraftTone = (typeof LIFEOPS_GMAIL_DRAFT_TONES)[number];\n\nexport interface CreateLifeOpsGmailReplyDraftRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n messageId: string;\n grantId?: string;\n tone?: LifeOpsGmailDraftTone;\n intent?: string;\n includeQuotedOriginal?: boolean;\n conversationContext?: string[];\n actionHistory?: string[];\n trajectorySummary?: string | null;\n}\n\nexport interface LifeOpsGmailReplyDraft {\n messageId: string;\n threadId: string;\n subject: string;\n to: string[];\n cc: string[];\n bodyText: string;\n previewLines: string[];\n sendAllowed: boolean;\n requiresConfirmation: boolean;\n}\n\nexport interface CreateLifeOpsGmailBatchReplyDraftsRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n grantId?: string;\n forceSync?: boolean;\n maxResults?: number;\n query?: string;\n messageIds?: string[];\n tone?: LifeOpsGmailDraftTone;\n intent?: string;\n includeQuotedOriginal?: boolean;\n replyNeededOnly?: boolean;\n conversationContext?: string[];\n actionHistory?: string[];\n trajectorySummary?: string | null;\n}\n\nexport interface LifeOpsGmailBatchReplyDraftsSummary {\n totalCount: number;\n sendAllowedCount: number;\n requiresConfirmationCount: number;\n}\n\nexport interface LifeOpsGmailBatchReplyDraftsFeed {\n query: string | null;\n messages: LifeOpsGmailMessageSummary[];\n drafts: LifeOpsGmailReplyDraft[];\n source: \"cache\" | \"synced\";\n syncedAt: string | null;\n summary: LifeOpsGmailBatchReplyDraftsSummary;\n}\n\nexport interface SendLifeOpsGmailReplyRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n grantId?: string;\n messageId: string;\n bodyText: string;\n subject?: string;\n to?: string[];\n cc?: string[];\n confirmSend?: boolean;\n}\n\nexport interface SendLifeOpsGmailMessageRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n grantId?: string;\n to: string[];\n cc?: string[];\n bcc?: string[];\n subject: string;\n bodyText: string;\n confirmSend?: boolean;\n}\n\nexport interface LifeOpsGmailBatchReplySendItem {\n messageId: string;\n bodyText: string;\n subject?: string;\n to?: string[];\n cc?: string[];\n}\n\nexport interface SendLifeOpsGmailBatchReplyRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n grantId?: string;\n confirmSend?: boolean;\n items: LifeOpsGmailBatchReplySendItem[];\n}\n\nexport interface LifeOpsGmailBatchReplySendResult {\n ok: true;\n sentCount: number;\n}\n\nexport const LIFEOPS_CALENDAR_WINDOW_PRESETS = [\n \"tomorrow_morning\",\n \"tomorrow_afternoon\",\n \"tomorrow_evening\",\n] as const;\nexport type LifeOpsCalendarWindowPreset =\n (typeof LIFEOPS_CALENDAR_WINDOW_PRESETS)[number];\n\nexport interface CreateLifeOpsCalendarEventAttendee {\n email: string;\n displayName?: string;\n optional?: boolean;\n}\n\nexport interface CreateLifeOpsCalendarEventRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n calendarId?: string;\n grantId?: string;\n title: string;\n description?: string;\n location?: string;\n startAt?: string;\n endAt?: string;\n timeZone?: string;\n durationMinutes?: number;\n windowPreset?: LifeOpsCalendarWindowPreset;\n attendees?: CreateLifeOpsCalendarEventAttendee[];\n}\n\nexport interface LifeOpsNextCalendarEventContext {\n event: LifeOpsCalendarEvent | null;\n startsAt: string | null;\n startsInMinutes: number | null;\n attendeeCount: number;\n attendeeNames: string[];\n location: string | null;\n conferenceLink: string | null;\n preparationChecklist: string[];\n linkedMailState: \"unavailable\" | \"cache\" | \"synced\" | \"error\";\n linkedMailError: string | null;\n linkedMail: Array<\n Pick<\n LifeOpsGmailMessageSummary,\n \"id\" | \"subject\" | \"from\" | \"receivedAt\" | \"snippet\" | \"htmlLink\"\n >\n >;\n}\n\nexport interface LifeOpsCalendarEventUpdate {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n grantId?: string;\n calendarId?: string;\n title?: string;\n startAt?: string;\n endAt?: string;\n timeZone?: string;\n notes?: string;\n location?: string;\n attendees?: CreateLifeOpsCalendarEventAttendee[];\n}\n\nexport interface LifeOpsCalendarEventMutationResult {\n event: LifeOpsCalendarEvent;\n}\n\nexport const LIFEOPS_INBOX_CHANNELS = [\n \"gmail\",\n \"x_dm\",\n \"discord\",\n \"telegram\",\n \"signal\",\n \"imessage\",\n \"whatsapp\",\n \"sms\",\n] as const;\nexport type LifeOpsInboxChannel = (typeof LIFEOPS_INBOX_CHANNELS)[number];\n\nexport interface LifeOpsInboxMessageSender {\n id: string;\n displayName: string;\n email: string | null;\n avatarUrl: string | null;\n}\n\nexport interface LifeOpsInboxMessageSourceRef {\n channel: LifeOpsInboxChannel;\n externalId: string;\n}\n\nexport interface LifeOpsInboxMessage {\n /** Channel-prefixed, globally unique identifier. */\n id: string;\n channel: LifeOpsInboxChannel;\n sender: LifeOpsInboxMessageSender;\n /** Gmail-style subject; `null` for chat channels. */\n subject: string | null;\n snippet: string;\n /** ISO-8601 timestamp. */\n receivedAt: string;\n unread: boolean;\n deepLink: string | null;\n sourceRef: LifeOpsInboxMessageSourceRef;\n /** Stable per-conversation key. For chat: roomId. For Gmail: thread id from sourceRef. */\n threadId?: string;\n /** Present on Gmail messages when multiple accounts exist; identifies which Google grant the message came from. */\n gmailAccountId?: string;\n /** LifeOps-owned account key for privacy egress. */\n connectorAccountId?: string;\n /** Display label for the Gmail account (e.g., `work@example.com`). */\n gmailAccountEmail?: string;\n /** ISO timestamp of when the user last viewed this thread (UI updates on open). */\n lastSeenAt?: string;\n /** ISO timestamp if the user has replied since this message arrived. */\n repliedAt?: string;\n /** 0–100 score; higher = more important. */\n priorityScore?: number;\n /** Coarse semantic category from the priority scorer. */\n priorityCategory?: \"important\" | \"planning\" | \"casual\";\n /** DM, small/medium group chat, or public channel/broadcast. */\n chatType?: \"dm\" | \"group\" | \"channel\";\n /** For groups, number of participants. UI uses this to hide groups with >15 participants. */\n participantCount?: number;\n}\n\nexport interface LifeOpsInboxChannelCount {\n total: number;\n unread: number;\n}\n\nexport interface LifeOpsInboxThreadGroup {\n /** Stable per-conversation key (matches LifeOpsInboxMessage.threadId on member messages) */\n threadId: string;\n /** Channel this thread belongs to */\n channel: LifeOpsInboxChannel;\n /** dm | group | channel */\n chatType: \"dm\" | \"group\" | \"channel\";\n /** Most recent message in the thread */\n latestMessage: LifeOpsInboxMessage;\n /** Total messages in the visible window */\n totalCount: number;\n /** Unread messages in the visible window */\n unreadCount: number;\n /** Group/DM participant count if known */\n participantCount?: number;\n /** Highest priority score across messages in the thread */\n maxPriorityScore?: number;\n /** Coarse semantic category from the priority scorer (mirrors latestMessage). */\n priorityCategory?: \"important\" | \"planning\" | \"casual\";\n /** Messages in this visible thread window, newest first. */\n messages: LifeOpsInboxMessage[];\n}\n\nexport interface LifeOpsInbox {\n messages: LifeOpsInboxMessage[];\n channelCounts: Record<LifeOpsInboxChannel, LifeOpsInboxChannelCount>;\n fetchedAt: string;\n /** Populated when the caller requests grouped output via `groupByThread`. */\n threadGroups?: LifeOpsInboxThreadGroup[];\n}\n\nexport const LIFEOPS_INBOX_CACHE_MODES = [\n \"read-through\",\n \"refresh\",\n \"cache-only\",\n] as const;\nexport type LifeOpsInboxCacheMode = (typeof LIFEOPS_INBOX_CACHE_MODES)[number];\n\nexport interface GetLifeOpsInboxRequest {\n /** Cap on the total number of messages returned. Defaults to 100. */\n limit?: number;\n /** If omitted, all connected channels are included. */\n channels?: LifeOpsInboxChannel[];\n /** When true, response includes `threadGroups`. */\n groupByThread?: boolean;\n /** Filter messages by chat type. */\n chatTypeFilter?: Array<\"dm\" | \"group\" | \"channel\">;\n /** Exclude groups with more than this many participants. */\n maxParticipants?: number;\n /** Filter to a specific Google grant. */\n gmailAccountId?: string;\n /**\n * When true, only return messages where the user has not replied for >24h\n * and the priority score is at least 50. Applies at both the message and\n * thread-group layer.\n */\n missedOnly?: boolean;\n /**\n * When true, thread groups are sorted by max priority score desc, recency\n * tiebreaker. When false (default), groups are sorted by recency only.\n */\n sortByPriority?: boolean;\n /**\n * read-through: use fresh cache, otherwise fetch and cache;\n * refresh: force a connector pull and cache the full requested window;\n * cache-only: never hit connectors, only read persisted inbox messages.\n */\n cacheMode?: LifeOpsInboxCacheMode;\n /** Cap on messages pulled/read for cache operations. Defaults to a bounded full-cache window. */\n cacheLimit?: number;\n}\n\nexport const LIFEOPS_GOOGLE_CONNECTOR_REASONS = [\n \"connected\",\n \"disconnected\",\n \"config_missing\",\n \"token_missing\",\n \"needs_reauth\",\n] as const;\nexport type LifeOpsGoogleConnectorReason =\n (typeof LIFEOPS_GOOGLE_CONNECTOR_REASONS)[number];\n\nexport interface LifeOpsGoogleConnectorStatus {\n provider: \"google\";\n side: LifeOpsConnectorSide;\n mode: LifeOpsConnectorMode;\n defaultMode: LifeOpsConnectorMode;\n availableModes: LifeOpsConnectorMode[];\n executionTarget: LifeOpsConnectorExecutionTarget;\n sourceOfTruth: LifeOpsConnectorSourceOfTruth;\n configured: boolean;\n connected: boolean;\n reason: LifeOpsGoogleConnectorReason;\n preferredByAgent: boolean;\n cloudConnectionId: string | null;\n identity: Record<string, unknown> | null;\n grantedCapabilities: LifeOpsGoogleCapability[];\n grantedScopes: string[];\n expiresAt: string | null;\n hasRefreshToken: boolean;\n grant: LifeOpsConnectorGrant | null;\n degradations?: LifeOpsConnectorDegradation[];\n}\n\nexport interface LifeOpsXConnectorStatus {\n provider: \"x\";\n side?: LifeOpsConnectorSide;\n mode: LifeOpsConnectorMode;\n defaultMode?: LifeOpsConnectorMode;\n availableModes?: LifeOpsConnectorMode[];\n executionTarget?: LifeOpsConnectorExecutionTarget;\n sourceOfTruth?: LifeOpsConnectorSourceOfTruth;\n configured?: boolean;\n connected: boolean;\n reason?: \"connected\" | \"disconnected\" | \"config_missing\" | \"needs_reauth\";\n preferredByAgent?: boolean;\n cloudConnectionId?: string | null;\n grantedCapabilities: LifeOpsXCapability[];\n grantedScopes: string[];\n identity: Record<string, unknown> | null;\n hasCredentials: boolean;\n feedRead: boolean;\n feedWrite: boolean;\n dmRead: boolean;\n dmWrite: boolean;\n /**\n * DM inbound read is supported when `x.dm.read` capability is granted.\n * Use `syncXDms()` to pull and persist, then `getXDms()` or\n * `readXInboundDms()` to retrieve.\n */\n dmInbound: boolean;\n grant: LifeOpsConnectorGrant | null;\n degradations?: LifeOpsConnectorDegradation[];\n}\n\n// ---------------------------------------------------------------------------\n// Messaging connector types (Signal, Discord, Telegram)\n// ---------------------------------------------------------------------------\n\nexport const LIFEOPS_MESSAGING_CONNECTOR_REASONS = [\n \"connected\",\n \"disconnected\",\n \"pairing\",\n \"auth_pending\",\n \"auth_expired\",\n \"session_revoked\",\n] as const;\nexport type LifeOpsMessagingConnectorReason =\n (typeof LIFEOPS_MESSAGING_CONNECTOR_REASONS)[number];\n\nexport interface LifeOpsSignalConnectorStatus {\n provider: \"signal\";\n side: LifeOpsConnectorSide;\n connected: boolean;\n inbound: boolean;\n reason: LifeOpsMessagingConnectorReason;\n identity: { phoneNumber?: string; uuid?: string; deviceName?: string } | null;\n grantedCapabilities: LifeOpsSignalCapability[];\n pairing: LifeOpsSignalPairingStatus | null;\n grant: LifeOpsConnectorGrant | null;\n degradations?: LifeOpsConnectorDegradation[];\n}\n\nexport interface SendLifeOpsSignalMessageRequest {\n side?: LifeOpsConnectorSide;\n recipient: string;\n text: string;\n}\n\nexport interface SendLifeOpsSignalMessageResponse {\n provider: \"signal\";\n side: LifeOpsConnectorSide;\n recipient: string;\n ok: true;\n timestamp: number;\n}\n\n/**\n * A single inbound Signal message as returned by {@link readSignalInbound} and\n * the signal-local-client reader.\n */\nexport interface LifeOpsSignalInboundMessage {\n /** Stable message ID (from the Signal service memory store or signal-cli). */\n id: string;\n /** elizaOS room ID this message was placed into. */\n roomId: string;\n /** Signal channel ID (typically the sender's phone number or group ID). */\n channelId: string;\n /** Stable per-conversation key used for reply routing. */\n threadId: string;\n /** Human-readable conversation name when known. */\n roomName: string;\n /** Display name of the sender. */\n speakerName: string;\n /** Sender phone number when signal-cli exposes one. */\n senderNumber: string | null;\n /** Sender UUID when signal-cli exposes one. */\n senderUuid: string | null;\n /** Sender device ID when signal-cli exposes one. */\n sourceDevice: number | null;\n /** Signal group ID for group messages. */\n groupId: string | null;\n /** Signal group event/type when signal-cli exposes one. */\n groupType: string | null;\n /** Plain-text body of the message. */\n text: string;\n /** Unix millisecond timestamp of the message. */\n createdAt: number;\n /** True when the message was sent by a contact (not by the agent's account). */\n isInbound: boolean;\n /** True when the message was received in a group conversation. */\n isGroup: boolean;\n}\n\nexport interface GetLifeOpsSignalMessagesRequest {\n limit?: number;\n}\n\nexport interface GetLifeOpsSignalMessagesResponse {\n count: number;\n messages: LifeOpsSignalInboundMessage[];\n}\n\nexport interface LifeOpsDiscordDmPreview {\n channelId: string | null;\n href: string | null;\n label: string;\n selected: boolean;\n unread: boolean;\n snippet: string | null;\n}\n\nexport interface LifeOpsDiscordDmInboxStatus {\n visible: boolean;\n count: number;\n selectedChannelId: string | null;\n previews: LifeOpsDiscordDmPreview[];\n}\n\nexport const LIFEOPS_OWNER_BROWSER_ACCESS_SOURCES = [\n \"lifeops_browser\",\n \"desktop_browser\",\n \"discord_desktop\",\n] as const;\nexport type LifeOpsOwnerBrowserAccessSource =\n (typeof LIFEOPS_OWNER_BROWSER_ACCESS_SOURCES)[number];\n\nexport const LIFEOPS_OWNER_BROWSER_TAB_STATES = [\n \"missing\",\n \"background_discord\",\n \"discord_open\",\n \"dm_inbox_visible\",\n] as const;\nexport type LifeOpsOwnerBrowserTabState =\n (typeof LIFEOPS_OWNER_BROWSER_TAB_STATES)[number];\n\nexport const LIFEOPS_OWNER_BROWSER_AUTH_STATES = [\n \"unknown\",\n \"logged_out\",\n \"logged_in\",\n] as const;\nexport type LifeOpsOwnerBrowserAuthState =\n (typeof LIFEOPS_OWNER_BROWSER_AUTH_STATES)[number];\n\nexport const LIFEOPS_OWNER_BROWSER_NEXT_ACTIONS = [\n \"none\",\n \"connect_browser\",\n \"open_extension_popup\",\n \"enable_browser_access\",\n \"enable_browser_control\",\n \"open_discord\",\n \"open_dm_inbox\",\n \"focus_discord_manually\",\n \"focus_dm_inbox_manually\",\n \"log_in\",\n \"open_desktop_browser\",\n \"relaunch_discord\",\n] as const;\nexport type LifeOpsOwnerBrowserNextAction =\n (typeof LIFEOPS_OWNER_BROWSER_NEXT_ACTIONS)[number];\n\nexport interface LifeOpsOwnerBrowserAccessStatus {\n source: LifeOpsOwnerBrowserAccessSource;\n active: boolean;\n available: boolean;\n browser: LifeOpsBrowserKind | null;\n profileId: string | null;\n profileLabel: string | null;\n companionId: string | null;\n companionLabel: string | null;\n canControl: boolean;\n siteAccessOk: boolean | null;\n currentUrl: string | null;\n tabState: LifeOpsOwnerBrowserTabState;\n authState: LifeOpsOwnerBrowserAuthState;\n nextAction: LifeOpsOwnerBrowserNextAction;\n}\n\nexport interface LifeOpsDiscordConnectorStatus {\n provider: \"discord\";\n side: LifeOpsConnectorSide;\n /** A LifeOps browser path is available via the browser companion or the desktop browser workspace. */\n available: boolean;\n /** A logged-in Discord session was detected from the active browser path. */\n connected: boolean;\n reason: LifeOpsMessagingConnectorReason;\n identity: {\n id?: string;\n username?: string;\n discriminator?: string;\n email?: string;\n } | null;\n /** Whether the owner's DM inbox is visible inside the Discord tab right now. */\n dmInbox: LifeOpsDiscordDmInboxStatus;\n grantedCapabilities: LifeOpsDiscordCapability[];\n lastError: string | null;\n /** Browser Workspace tab hosting Discord, when that desktop path is in use. */\n tabId: string | null;\n /** Owner-side browser options for reaching the user's real Discord session. */\n browserAccess?: LifeOpsOwnerBrowserAccessStatus[];\n grant: LifeOpsConnectorGrant | null;\n degradations?: LifeOpsConnectorDegradation[];\n}\n\nexport const LIFEOPS_TELEGRAM_AUTH_STATES = [\n \"idle\",\n \"waiting_for_provisioning_code\",\n \"waiting_for_code\",\n \"waiting_for_password\",\n \"connected\",\n \"error\",\n] as const;\nexport type LifeOpsTelegramAuthState =\n (typeof LIFEOPS_TELEGRAM_AUTH_STATES)[number];\n\nexport interface LifeOpsWhatsAppConnectorStatus {\n provider: \"whatsapp\";\n /**\n * `connected` means at least one WhatsApp transport is live enough for\n * inbound or outbound work. A local auth file by itself is not connected until\n * the Baileys runtime service is actually online.\n */\n connected: boolean;\n /**\n * Inbound is always true for WhatsApp. Messages arrive via webhook push and\n * are buffered for periodic drain via `syncWhatsAppInbound()`.\n */\n inbound: true;\n phoneNumberId?: string;\n phoneNumber?: string | null;\n localAuthAvailable?: boolean;\n localAuthRegistered?: boolean | null;\n serviceConnected?: boolean;\n outboundReady?: boolean;\n inboundReady?: boolean;\n transport?: \"cloudapi\" | \"baileys\" | \"unconfigured\";\n lastCheckedAt: string;\n degradations?: LifeOpsConnectorDegradation[];\n}\n\nexport interface LifeOpsTelegramConnectorStatus {\n provider: \"telegram\";\n side: LifeOpsConnectorSide;\n connected: boolean;\n reason: LifeOpsMessagingConnectorReason;\n identity: {\n id?: string;\n username?: string;\n firstName?: string;\n phone?: string;\n } | null;\n grantedCapabilities: LifeOpsTelegramCapability[];\n authState: LifeOpsTelegramAuthState;\n authError: string | null;\n phone: string | null;\n managedCredentialsAvailable: boolean;\n storedCredentialsAvailable: boolean;\n grant: LifeOpsConnectorGrant | null;\n degradations?: LifeOpsConnectorDegradation[];\n}\n\nexport interface LifeOpsTelegramDialogSummary {\n id: string;\n title: string;\n username: string | null;\n lastMessageText: string | null;\n lastMessageAt: string | null;\n unreadCount: number;\n}\n\nexport interface VerifyLifeOpsTelegramConnectorRequest {\n side?: LifeOpsConnectorSide;\n recentLimit?: number;\n sendTarget?: string;\n sendMessage?: string;\n}\n\nexport interface VerifyLifeOpsTelegramConnectorResponse {\n provider: \"telegram\";\n side: LifeOpsConnectorSide;\n verifiedAt: string;\n read: {\n ok: boolean;\n error: string | null;\n dialogCount: number;\n dialogs: LifeOpsTelegramDialogSummary[];\n };\n send: {\n ok: boolean;\n error: string | null;\n target: string;\n message: string;\n messageId: string | null;\n };\n}\n\nexport interface StartLifeOpsSignalPairingRequest {\n side?: LifeOpsConnectorSide;\n}\n\nexport interface StartLifeOpsSignalPairingResponse {\n provider: \"signal\";\n side: LifeOpsConnectorSide;\n sessionId: string;\n}\n\nexport interface LifeOpsSignalPairingStatus {\n sessionId: string;\n state:\n | \"idle\"\n | \"generating_qr\"\n | \"waiting_for_scan\"\n | \"linking\"\n | \"connected\"\n | \"failed\";\n qrDataUrl: string | null;\n error: string | null;\n}\n\nexport interface StartLifeOpsDiscordConnectorRequest {\n side?: LifeOpsConnectorSide;\n source?: LifeOpsOwnerBrowserAccessSource;\n}\n\nexport interface SendLifeOpsDiscordMessageRequest {\n side?: LifeOpsConnectorSide;\n channelId?: string;\n text: string;\n}\n\nexport interface SendLifeOpsDiscordMessageResponse {\n provider: \"discord\";\n side: LifeOpsConnectorSide;\n channelId: string;\n ok: true;\n deliveryStatus: \"sent\" | \"sending\" | \"failed\" | \"unknown\";\n}\n\nexport interface VerifyLifeOpsDiscordConnectorRequest {\n side?: LifeOpsConnectorSide;\n channelId?: string;\n sendMessage?: string;\n}\n\nexport interface VerifyLifeOpsDiscordConnectorResponse {\n provider: \"discord\";\n side: LifeOpsConnectorSide;\n verifiedAt: string;\n status: LifeOpsDiscordConnectorStatus;\n send: {\n ok: boolean;\n error: string | null;\n channelId: string | null;\n message: string;\n deliveryStatus: \"sent\" | \"sending\" | \"failed\" | \"unknown\" | null;\n };\n}\n\nexport interface SendLifeOpsWhatsAppMessageRequest {\n to: string;\n text: string;\n replyToMessageId?: string;\n}\n\nexport interface StartLifeOpsTelegramAuthRequest {\n side?: LifeOpsConnectorSide;\n phone: string;\n apiId?: number;\n apiHash?: string;\n}\n\nexport interface StartLifeOpsTelegramAuthResponse {\n provider: \"telegram\";\n side: LifeOpsConnectorSide;\n state:\n | \"waiting_for_provisioning_code\"\n | \"waiting_for_code\"\n | \"waiting_for_password\"\n | \"connected\"\n | \"error\";\n error?: string;\n}\n\nexport interface SubmitLifeOpsTelegramAuthRequest {\n side?: LifeOpsConnectorSide;\n code?: string;\n password?: string;\n}\n\nexport interface DisconnectLifeOpsMessagingConnectorRequest {\n side?: LifeOpsConnectorSide;\n provider: \"signal\" | \"discord\" | \"telegram\";\n}\n\nexport interface StartLifeOpsGoogleConnectorRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n /** Re-authenticate an existing account by grant ID (multi-account). */\n grantId?: string;\n /** Create an additional account grant instead of reusing the side/mode grant. */\n createNewGrant?: boolean;\n capabilities?: LifeOpsGoogleCapability[];\n redirectUrl?: string;\n}\n\nexport interface StartLifeOpsGoogleConnectorResponse {\n provider: \"google\";\n side: LifeOpsConnectorSide;\n mode: LifeOpsConnectorMode;\n requestedCapabilities: LifeOpsGoogleCapability[];\n redirectUri: string;\n authUrl: string;\n}\n\nexport interface SelectLifeOpsGoogleConnectorPreferenceRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n}\n\nexport interface DisconnectLifeOpsGoogleConnectorRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n grantId?: string;\n}\n\nexport interface UpsertLifeOpsXConnectorRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n capabilities: LifeOpsXCapability[];\n grantedScopes?: string[];\n identity?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n}\n\nexport interface StartLifeOpsXConnectorRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n redirectUrl?: string;\n}\n\nexport interface StartLifeOpsXConnectorResponse {\n provider: \"x\";\n side: LifeOpsConnectorSide;\n mode: LifeOpsConnectorMode;\n requestedCapabilities: LifeOpsXCapability[];\n redirectUri: string;\n authUrl: string;\n}\n\nexport interface DisconnectLifeOpsXConnectorRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n}\n\nexport interface CreateLifeOpsXPostRequest {\n side?: LifeOpsConnectorSide;\n mode?: LifeOpsConnectorMode;\n text: string;\n confirmPost?: boolean;\n}\n\nexport interface LifeOpsXPostResponse {\n ok: boolean;\n status: number | null;\n postId?: string;\n error?: string;\n category:\n | \"success\"\n | \"auth\"\n | \"rate_limit\"\n | \"network\"\n | \"invalid\"\n | \"unknown\";\n}\n\nexport interface CreateLifeOpsDefinitionRequest {\n ownership?: LifeOpsOwnershipInput;\n kind: LifeOpsDefinitionKind;\n title: string;\n description?: string;\n originalIntent?: string;\n timezone?: string;\n priority?: number;\n cadence: LifeOpsCadence;\n windowPolicy?: LifeOpsWindowPolicy;\n progressionRule?: LifeOpsProgressionRule;\n websiteAccess?: LifeOpsWebsiteAccessPolicy | null;\n reminderPlan?: {\n steps: LifeOpsReminderStep[];\n mutePolicy?: Record<string, unknown>;\n quietHours?: Record<string, unknown>;\n } | null;\n goalId?: string | null;\n source?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateLifeOpsDefinitionRequest {\n ownership?: LifeOpsOwnershipInput;\n title?: string;\n description?: string;\n originalIntent?: string;\n timezone?: string;\n priority?: number;\n cadence?: LifeOpsCadence;\n windowPolicy?: LifeOpsWindowPolicy;\n progressionRule?: LifeOpsProgressionRule;\n websiteAccess?: LifeOpsWebsiteAccessPolicy | null;\n status?: LifeOpsDefinitionStatus;\n reminderPlan?: {\n steps: LifeOpsReminderStep[];\n mutePolicy?: Record<string, unknown>;\n quietHours?: Record<string, unknown>;\n } | null;\n goalId?: string | null;\n metadata?: Record<string, unknown>;\n}\n\nexport interface CreateLifeOpsGoalRequest {\n ownership?: LifeOpsOwnershipInput;\n title: string;\n description?: string;\n cadence?: Record<string, unknown> | null;\n supportStrategy?: Record<string, unknown>;\n successCriteria?: Record<string, unknown>;\n status?: LifeOpsGoalStatus;\n reviewState?: LifeOpsGoalReviewState;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateLifeOpsGoalRequest {\n ownership?: LifeOpsOwnershipInput;\n title?: string;\n description?: string;\n cadence?: Record<string, unknown> | null;\n supportStrategy?: Record<string, unknown>;\n successCriteria?: Record<string, unknown>;\n status?: LifeOpsGoalStatus;\n reviewState?: LifeOpsGoalReviewState;\n metadata?: Record<string, unknown>;\n}\n\nexport interface LifeOpsDefinitionRecord {\n definition: LifeOpsTaskDefinition;\n reminderPlan: LifeOpsReminderPlan | null;\n performance: LifeOpsDefinitionPerformance;\n}\n\nexport interface LifeOpsGoalRecord {\n goal: LifeOpsGoalDefinition;\n links: LifeOpsGoalLink[];\n}\n\nexport const LIFEOPS_GOAL_SUGGESTION_KINDS = [\n \"create_support\",\n \"focus_now\",\n \"resolve_overdue\",\n \"review_progress\",\n \"tighten_cadence\",\n] as const;\nexport type LifeOpsGoalSuggestionKind =\n (typeof LIFEOPS_GOAL_SUGGESTION_KINDS)[number];\n\nexport interface LifeOpsGoalSupportSuggestion {\n kind: LifeOpsGoalSuggestionKind;\n title: string;\n detail: string;\n definitionId: string | null;\n occurrenceId: string | null;\n}\n\nexport interface LifeOpsGoalReview {\n goal: LifeOpsGoalDefinition;\n links: LifeOpsGoalLink[];\n linkedDefinitions: LifeOpsTaskDefinition[];\n activeOccurrences: LifeOpsOccurrenceView[];\n overdueOccurrences: LifeOpsOccurrenceView[];\n recentCompletions: LifeOpsOccurrenceView[];\n suggestions: LifeOpsGoalSupportSuggestion[];\n audits: LifeOpsAuditEvent[];\n summary: {\n linkedDefinitionCount: number;\n activeOccurrenceCount: number;\n overdueOccurrenceCount: number;\n completedLast7Days: number;\n lastActivityAt: string | null;\n reviewState: LifeOpsGoalReviewState;\n explanation: string;\n progressScore?: number | null;\n confidence?: number | null;\n evidenceSummary?: string | null;\n missingEvidence?: string[];\n groundingState?: string | null;\n groundingSummary?: string | null;\n semanticReviewedAt?: string | null;\n };\n}\n\nexport interface LifeOpsGoalExperienceLoopSuggestion {\n sourceGoalId: string;\n definitionId: string | null;\n title: string;\n detail: string;\n}\n\nexport interface LifeOpsGoalExperienceLoopMatch {\n goalId: string;\n title: string;\n description: string;\n score: number;\n status: LifeOpsGoalStatus;\n reviewState: LifeOpsGoalReviewState;\n linkedDefinitionCount: number;\n completedLast7Days: number;\n lastActivityAt: string | null;\n explanation: string;\n carryForwardSuggestions: LifeOpsGoalExperienceLoopSuggestion[];\n}\n\nexport interface LifeOpsGoalExperienceLoop {\n referenceGoalId: string | null;\n referenceTitle: string;\n similarGoals: LifeOpsGoalExperienceLoopMatch[];\n suggestedCarryForward: LifeOpsGoalExperienceLoopSuggestion[];\n summary: string | null;\n}\n\nexport interface LifeOpsWeeklyGoalReview {\n generatedAt: string;\n reviewWindow: \"this_week\";\n summary: {\n totalGoals: number;\n onTrackCount: number;\n atRiskCount: number;\n needsAttentionCount: number;\n idleCount: number;\n };\n onTrack: LifeOpsGoalReview[];\n atRisk: LifeOpsGoalReview[];\n needsAttention: LifeOpsGoalReview[];\n idle: LifeOpsGoalReview[];\n}\n\nexport interface LifeOpsDefinitionPerformanceWindow {\n scheduledCount: number;\n completedCount: number;\n skippedCount: number;\n pendingCount: number;\n completionRate: number;\n perfectDayCount: number;\n}\n\nexport interface LifeOpsDefinitionPerformance {\n lastCompletedAt: string | null;\n lastSkippedAt: string | null;\n lastActivityAt: string | null;\n totalScheduledCount: number;\n totalCompletedCount: number;\n totalSkippedCount: number;\n totalPendingCount: number;\n currentOccurrenceStreak: number;\n bestOccurrenceStreak: number;\n currentPerfectDayStreak: number;\n bestPerfectDayStreak: number;\n last7Days: LifeOpsDefinitionPerformanceWindow;\n last30Days: LifeOpsDefinitionPerformanceWindow;\n}\n\nexport interface SnoozeLifeOpsOccurrenceRequest {\n minutes?: number;\n preset?: \"15m\" | \"30m\" | \"1h\" | \"tonight\" | \"tomorrow_morning\";\n}\n\nexport interface CompleteLifeOpsOccurrenceRequest {\n note?: string;\n metadata?: Record<string, unknown>;\n}\n\nexport interface LifeOpsOccurrenceExplanation {\n occurrence: LifeOpsOccurrenceView;\n definition: LifeOpsTaskDefinition;\n definitionPerformance: LifeOpsDefinitionPerformance;\n reminderPlan: LifeOpsReminderPlan | null;\n linkedGoal: LifeOpsGoalRecord | null;\n reminderInspection: LifeOpsReminderInspection;\n definitionAudits: LifeOpsAuditEvent[];\n summary: {\n originalIntent: string;\n source: string;\n whyVisible: string;\n lastReminderAt: string | null;\n lastReminderChannel: LifeOpsReminderChannel | null;\n lastReminderOutcome: LifeOpsReminderAttemptOutcome | null;\n lastActionSummary: string | null;\n };\n}\n\nexport interface UpsertLifeOpsChannelPolicyRequest {\n channelType: LifeOpsChannelType;\n channelRef: string;\n privacyClass?: LifeOpsPrivacyClass;\n allowReminders?: boolean;\n allowEscalation?: boolean;\n allowPosts?: boolean;\n requireConfirmationForActions?: boolean;\n metadata?: Record<string, unknown>;\n}\n\nexport interface SetLifeOpsReminderPreferenceRequest {\n intensity: LifeOpsReminderIntensityInput;\n definitionId?: string | null;\n note?: string;\n}\n\nexport interface CaptureLifeOpsPhoneConsentRequest {\n phoneNumber: string;\n consentGiven: boolean;\n allowSms: boolean;\n allowVoice: boolean;\n privacyClass?: LifeOpsPrivacyClass;\n metadata?: Record<string, unknown>;\n}\n\nexport interface CaptureLifeOpsActivitySignalRequest {\n source: LifeOpsActivitySignalSource;\n platform?: string;\n state: LifeOpsActivitySignalState;\n observedAt?: string;\n idleState?: \"active\" | \"idle\" | \"locked\" | \"unknown\" | null;\n idleTimeSeconds?: number | null;\n onBattery?: boolean | null;\n health?: LifeOpsHealthSignal | null;\n metadata?: Record<string, unknown>;\n}\n\n/**\n * User-attested circadian override. Emitted with maximum reliability weight;\n * force-transitions the state machine. See `sleep-wake-spec.md` §2 (manual\n * override row in the transition table).\n */\nexport const LIFEOPS_MANUAL_OVERRIDE_KINDS = [\n \"going_to_bed\",\n \"just_woke_up\",\n] as const;\nexport type LifeOpsManualOverrideKind =\n (typeof LIFEOPS_MANUAL_OVERRIDE_KINDS)[number];\n\nexport interface CaptureLifeOpsManualOverrideRequest {\n kind: LifeOpsManualOverrideKind;\n occurredAt?: string;\n /** Optional user note capped at 500 chars. */\n note?: string;\n}\n\nexport interface LifeOpsManualOverrideResult {\n accepted: true;\n kind: LifeOpsManualOverrideKind;\n occurredAt: string;\n circadianState: LifeOpsCircadianState;\n stateConfidence: number;\n}\n\nexport interface ProcessLifeOpsRemindersRequest {\n now?: string;\n limit?: number;\n}\n\nexport interface LifeOpsReminderProcessingResult {\n now: string;\n attempts: LifeOpsReminderAttempt[];\n}\n\nexport interface LifeOpsReminderInspection {\n ownerType: \"occurrence\" | \"calendar_event\";\n ownerId: string;\n reminderPlan: LifeOpsReminderPlan | null;\n attempts: LifeOpsReminderAttempt[];\n audits: LifeOpsAuditEvent[];\n}\n\nexport interface AcknowledgeLifeOpsReminderRequest {\n ownerType: \"occurrence\" | \"calendar_event\";\n ownerId: string;\n acknowledgedAt?: string;\n note?: string;\n}\n\nexport interface RelockLifeOpsWebsiteAccessRequest {\n groupKey: string;\n}\n\nexport interface ResolveLifeOpsWebsiteAccessCallbackRequest {\n callbackKey: string;\n}\n\nexport interface CreateLifeOpsWorkflowRequest {\n ownership?: LifeOpsOwnershipInput;\n title: string;\n triggerType: LifeOpsWorkflowTriggerType;\n schedule?: LifeOpsWorkflowSchedule;\n actionPlan: LifeOpsWorkflowActionPlan;\n permissionPolicy?: Partial<LifeOpsWorkflowPermissionPolicy>;\n status?: LifeOpsWorkflowStatus;\n createdBy?: LifeOpsActor;\n metadata?: Record<string, unknown>;\n}\n\nexport interface UpdateLifeOpsWorkflowRequest {\n ownership?: LifeOpsOwnershipInput;\n title?: string;\n triggerType?: LifeOpsWorkflowTriggerType;\n schedule?: LifeOpsWorkflowSchedule;\n actionPlan?: LifeOpsWorkflowActionPlan;\n permissionPolicy?: Partial<LifeOpsWorkflowPermissionPolicy>;\n status?: LifeOpsWorkflowStatus;\n metadata?: Record<string, unknown>;\n}\n\nexport interface RunLifeOpsWorkflowRequest {\n now?: string;\n confirmBrowserActions?: boolean;\n}\n\nexport interface LifeOpsWorkflowRecord {\n definition: LifeOpsWorkflowDefinition;\n runs: LifeOpsWorkflowRun[];\n}\n\nexport const LIFEOPS_BROWSER_SESSION_STATUSES = [\n \"awaiting_confirmation\",\n \"queued\",\n \"running\",\n \"done\",\n \"cancelled\",\n \"failed\",\n] as const;\nexport type LifeOpsBrowserSessionStatus =\n (typeof LIFEOPS_BROWSER_SESSION_STATUSES)[number];\n\nexport interface LifeOpsBrowserSession {\n id: string;\n agentId: string;\n domain: LifeOpsDomain;\n subjectType: LifeOpsSubjectType;\n subjectId: string;\n visibilityScope: LifeOpsVisibilityScope;\n contextPolicy: LifeOpsContextPolicy;\n workflowId: string | null;\n browser: LifeOpsBrowserKind | null;\n companionId: string | null;\n profileId: string | null;\n windowId: string | null;\n tabId: string | null;\n title: string;\n status: LifeOpsBrowserSessionStatus;\n actions: LifeOpsBrowserAction[];\n currentActionIndex: number;\n awaitingConfirmationForActionId: string | null;\n result: Record<string, unknown>;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n finishedAt: string | null;\n}\n\nexport interface CreateLifeOpsBrowserSessionRequest {\n ownership?: LifeOpsOwnershipInput;\n workflowId?: string | null;\n browser?: LifeOpsBrowserKind | null;\n companionId?: string | null;\n profileId?: string | null;\n windowId?: string | null;\n tabId?: string | null;\n title: string;\n actions: Array<Omit<LifeOpsBrowserAction, \"id\">>;\n}\n\nexport interface ConfirmLifeOpsBrowserSessionRequest {\n confirmed: boolean;\n}\n\nexport interface UpdateLifeOpsBrowserSessionProgressRequest {\n currentActionIndex?: number;\n result?: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n}\n\nexport interface CompleteLifeOpsBrowserSessionRequest {\n status?: Extract<LifeOpsBrowserSessionStatus, \"done\" | \"failed\">;\n result?: Record<string, unknown>;\n}\n\n// ── Settings card prop contracts ─────────────────────────────────────────────\n\nexport type AppBlockerSettingsMode = \"desktop\" | \"mobile\" | \"web\";\n\nexport interface AppBlockerSettingsCardProps {\n mode: AppBlockerSettingsMode;\n}\n\nexport type WebsiteBlockerSettingsMode = \"desktop\" | \"mobile\" | \"web\";\n\nexport interface WebsiteBlockerSettingsCardProps {\n mode: WebsiteBlockerSettingsMode;\n permission?: import(\"./permissions.js\").PermissionState;\n platform?: string;\n onOpenPermissionSettings?: () => void | Promise<void>;\n onRequestPermission?: () => void | Promise<void>;\n}\n\n// ── Occurrence action results ────────────────────────────────────────────────\n\nexport interface LifeOpsOccurrenceActionResult {\n occurrence: LifeOpsOccurrenceView;\n}\n\n// ── Sleep history / regularity / baseline responses ──────────────────────────\n\n/**\n * Single sleep episode entry returned by the sleep history endpoint.\n *\n * Mirrors `LifeOpsSleepEpisodeRecord` plus a derived `durationMin` so clients\n * never need to recompute it. `endedAt` and `durationMin` are `null` for\n * still-open (current) sleep episodes.\n */\nexport interface LifeOpsSleepHistoryEpisode {\n id: string;\n startedAt: string;\n endedAt: string | null;\n durationMin: number | null;\n cycleType: LifeOpsSleepCycleType;\n source: LifeOpsSleepCycleEvidenceSource | \"manual\";\n confidence: number;\n}\n\nexport interface LifeOpsSleepHistorySummary {\n cycleCount: number;\n averageDurationMin: number | null;\n overnightCount: number;\n napCount: number;\n openCount: number;\n}\n\nexport interface LifeOpsSleepHistoryResponse {\n episodes: LifeOpsSleepHistoryEpisode[];\n summary: LifeOpsSleepHistorySummary;\n windowDays: number;\n includeNaps: boolean;\n}\n\n/**\n * Wire-format response for the sleep regularity endpoint. Mirrors\n * `LifeOpsScheduleRegularity` (`sampleCount` is renamed to `sampleSize` here\n * for client-readable consistency with the baseline response).\n */\nexport interface LifeOpsSleepRegularityResponse {\n sri: number;\n classification: LifeOpsRegularityClass;\n bedtimeStddevMin: number;\n wakeStddevMin: number;\n midSleepStddevMin: number;\n sampleSize: number;\n windowDays: number;\n}\n\n/**\n * Wire-format response for the personal baseline endpoint. Mirrors\n * `LifeOpsPersonalBaseline` plus `sampleSize` (alias of `sampleCount`).\n *\n * Returns nullable medians when the underlying baseline has insufficient data.\n */\nexport interface LifeOpsPersonalBaselineResponse {\n medianBedtimeLocalHour: number | null;\n medianWakeLocalHour: number | null;\n medianSleepDurationMin: number | null;\n bedtimeStddevMin: number | null;\n wakeStddevMin: number | null;\n sampleSize: number;\n windowDays: number;\n}\n\n// ── Additional contracts (relationships, X read, cross-channel, screen time,\n// scheduling, dossier, iMessage, WhatsApp).\n\n// ── Message channels ─────────────────────────────────────────────────────────\n\nexport const LIFEOPS_MESSAGE_CHANNELS = [\n \"email\",\n \"telegram\",\n \"discord\",\n \"signal\",\n \"sms\",\n \"twilio_voice\",\n \"imessage\",\n \"whatsapp\",\n \"x_dm\",\n] as const;\n\nexport type LifeOpsMessageChannel = (typeof LIFEOPS_MESSAGE_CHANNELS)[number];\n\n// ── Follow-up statuses ───────────────────────────────────────────────────────\n\nexport const LIFEOPS_FOLLOW_UP_STATUSES = [\n \"pending\",\n \"completed\",\n \"snoozed\",\n \"cancelled\",\n] as const;\n\nexport type LifeOpsFollowUpStatus = (typeof LIFEOPS_FOLLOW_UP_STATUSES)[number];\n\n// ── X feed types ─────────────────────────────────────────────────────────────\n\nexport const LIFEOPS_X_FEED_TYPES = [\n \"home_timeline\",\n \"mentions\",\n \"search\",\n] as const;\n\nexport type LifeOpsXFeedType = (typeof LIFEOPS_X_FEED_TYPES)[number];\n\n// Note: `LIFEOPS_NEGOTIATION_STATES`, `LifeOpsNegotiationState`,\n// `LifeOpsSchedulingNegotiation`, and `LifeOpsSchedulingProposal` are\n// declared in the canonical `./lifeops.ts` contracts file, not here.\n\n// ── Relationship ─────────────────────────────────────────────────────────────\n\nexport interface LifeOpsRelationship {\n id: string;\n agentId: string;\n name: string;\n primaryChannel: string;\n primaryHandle: string;\n email: string | null;\n phone: string | null;\n notes: string;\n tags: string[];\n relationshipType: string;\n lastContactedAt: string | null;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface LifeOpsRelationshipInteraction {\n id: string;\n agentId: string;\n relationshipId: string;\n channel: string;\n direction: \"inbound\" | \"outbound\";\n summary: string;\n occurredAt: string;\n metadata: Record<string, unknown>;\n createdAt: string;\n}\n\nexport interface LifeOpsFollowUp {\n id: string;\n agentId: string;\n relationshipId: string;\n dueAt: string;\n reason: string;\n status: LifeOpsFollowUpStatus;\n priority: number;\n draft: LifeOpsCrossChannelDraft | null;\n completedAt: string | null;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\n// ── Cross-channel drafting ──────────────────────────────────────────────────\n\nexport interface LifeOpsCrossChannelDraft {\n channel: LifeOpsMessageChannel;\n target: string;\n subject: string | null;\n body: string;\n metadata: Record<string, unknown>;\n}\n\nexport interface LifeOpsCrossChannelSendRequest {\n draft: LifeOpsCrossChannelDraft;\n confirmed: boolean;\n}\n\n// ── X read ───────────────────────────────────────────────────────────────────\n\nexport interface LifeOpsXDm {\n id: string;\n agentId: string;\n externalDmId: string;\n conversationId: string;\n senderHandle: string;\n senderId: string;\n isInbound: boolean;\n text: string;\n receivedAt: string;\n readAt: string | null;\n repliedAt: string | null;\n metadata: Record<string, unknown>;\n syncedAt: string;\n updatedAt: string;\n}\n\nexport interface LifeOpsXFeedItem {\n id: string;\n agentId: string;\n externalTweetId: string;\n authorHandle: string;\n authorId: string;\n text: string;\n createdAtSource: string;\n feedType: LifeOpsXFeedType;\n metadata: Record<string, unknown>;\n syncedAt: string;\n updatedAt: string;\n}\n\nexport interface LifeOpsXSyncState {\n id: string;\n agentId: string;\n feedType: LifeOpsXFeedType;\n lastCursor: string | null;\n syncedAt: string;\n updatedAt: string;\n}\n\n// ── Screen time ──────────────────────────────────────────────────────────────\n\nexport interface LifeOpsScreenTimeSession {\n id: string;\n agentId: string;\n source: \"app\" | \"website\";\n identifier: string;\n displayName: string;\n startAt: string;\n endAt: string | null;\n durationSeconds: number;\n isActive: boolean;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface LifeOpsScreenTimeDaily {\n id: string;\n agentId: string;\n source: \"app\" | \"website\";\n identifier: string;\n date: string;\n totalSeconds: number;\n sessionCount: number;\n metadata: Record<string, unknown>;\n createdAt: string;\n updatedAt: string;\n}\n\nexport type LifeOpsScreenTimeSource = \"app\" | \"website\";\n\nexport type LifeOpsScreenTimeRangeKey = \"today\" | \"this-week\" | \"7d\" | \"30d\";\n\nexport const LIFEOPS_SCREEN_TIME_RANGES = [\n \"today\",\n \"this-week\",\n \"7d\",\n \"30d\",\n] as const satisfies readonly LifeOpsScreenTimeRangeKey[];\n\nexport interface LifeOpsScreenTimeSummaryRequest {\n since: string;\n until: string;\n source?: LifeOpsScreenTimeSource;\n identifier?: string;\n topN?: number;\n}\n\nexport interface LifeOpsScreenTimeSummaryItem {\n source: LifeOpsScreenTimeSource;\n identifier: string;\n displayName: string;\n totalSeconds: number;\n}\n\nexport interface LifeOpsScreenTimeSummary {\n items: LifeOpsScreenTimeSummaryItem[];\n totalSeconds: number;\n}\n\nexport type LifeOpsHabitCategory =\n | \"browser\"\n | \"communication\"\n | \"social\"\n | \"system\"\n | \"video\"\n | \"work\"\n | \"other\";\n\nexport type LifeOpsHabitDevice =\n | \"browser\"\n | \"computer\"\n | \"phone\"\n | \"tablet\"\n | \"unknown\";\n\nexport interface LifeOpsScreenTimeBucket {\n key: string;\n label: string;\n totalSeconds: number;\n}\n\nexport interface LifeOpsScreenTimeBreakdownItem\n extends LifeOpsScreenTimeSummaryItem {\n sessionCount: number;\n category: LifeOpsHabitCategory;\n device: LifeOpsHabitDevice;\n service: string | null;\n serviceLabel: string | null;\n browser: string | null;\n}\n\nexport interface LifeOpsScreenTimeBreakdown {\n items: LifeOpsScreenTimeBreakdownItem[];\n totalSeconds: number;\n bySource: LifeOpsScreenTimeBucket[];\n byCategory: LifeOpsScreenTimeBucket[];\n byDevice: LifeOpsScreenTimeBucket[];\n byService: LifeOpsScreenTimeBucket[];\n byBrowser: LifeOpsScreenTimeBucket[];\n fetchedAt: string;\n}\n\nexport interface LifeOpsSocialMessageChannel {\n channel: \"x_dm\";\n label: string;\n inbound: number;\n outbound: number;\n opened: number;\n replied: number;\n}\n\nexport type LifeOpsSocialHabitDataSourceState = \"live\" | \"partial\" | \"unwired\";\n\nexport interface LifeOpsSocialHabitDataSource {\n id: string;\n label: string;\n state: LifeOpsSocialHabitDataSourceState;\n statusLabel: string;\n detail: string;\n}\n\nexport interface LifeOpsSocialHabitSummary {\n since: string;\n until: string;\n totalSeconds: number;\n services: LifeOpsScreenTimeBucket[];\n devices: LifeOpsScreenTimeBucket[];\n surfaces: LifeOpsScreenTimeBucket[];\n browsers: LifeOpsScreenTimeBucket[];\n sessions: LifeOpsScreenTimeBreakdownItem[];\n messages: {\n channels: LifeOpsSocialMessageChannel[];\n inbound: number;\n outbound: number;\n opened: number;\n replied: number;\n };\n dataSources: LifeOpsSocialHabitDataSource[];\n fetchedAt: string;\n}\n\nexport interface LifeOpsScreenTimeWindow {\n since: string;\n until: string;\n}\n\nexport interface LifeOpsScreenTimeHistoryPoint extends LifeOpsScreenTimeWindow {\n date: string;\n label: string;\n totalSeconds: number;\n}\n\nexport interface LifeOpsScreenTimeDeltaMetrics {\n totalPercent: number | null;\n appPercent: number | null;\n webPercent: number | null;\n phonePercent: number | null;\n socialPercent: number | null;\n youtubePercent: number | null;\n xPercent: number | null;\n messageOpenedPercent: number | null;\n}\n\nexport interface LifeOpsScreenTimeMetrics {\n totalSeconds: number;\n appSeconds: number;\n webSeconds: number;\n phoneSeconds: number;\n socialSeconds: number;\n youtubeSeconds: number;\n xSeconds: number;\n messageOpened: number;\n messageOutbound: number;\n messageInbound: number;\n deltas: LifeOpsScreenTimeDeltaMetrics | null;\n}\n\nexport interface LifeOpsScreenTimeTargetBucket extends LifeOpsScreenTimeBucket {\n source: LifeOpsScreenTimeSource;\n identifier: string;\n}\n\nexport interface LifeOpsScreenTimeSessionBucket\n extends LifeOpsScreenTimeBucket {\n source: LifeOpsScreenTimeSource;\n identifier: string;\n}\n\nexport interface LifeOpsScreenTimeVisibleBuckets {\n categories: LifeOpsScreenTimeBucket[];\n devices: LifeOpsScreenTimeBucket[];\n browsers: LifeOpsScreenTimeBucket[];\n services: LifeOpsScreenTimeBucket[];\n surfaces: LifeOpsScreenTimeBucket[];\n topTargets: LifeOpsScreenTimeTargetBucket[];\n sessionBuckets: LifeOpsScreenTimeSessionBucket[];\n channels: LifeOpsSocialMessageChannel[];\n setupSources: LifeOpsSocialHabitDataSource[];\n hasMessageActivity: boolean;\n hasUsage: boolean;\n}\n\nexport interface LifeOpsScreenTimeHistoryResponse {\n range: LifeOpsScreenTimeRangeKey;\n label: string;\n window: LifeOpsScreenTimeWindow;\n priorWindow: LifeOpsScreenTimeWindow | null;\n breakdown: LifeOpsScreenTimeBreakdown;\n social: LifeOpsSocialHabitSummary;\n history: LifeOpsScreenTimeHistoryPoint[];\n metrics: LifeOpsScreenTimeMetrics;\n visible: LifeOpsScreenTimeVisibleBuckets;\n fetchedAt: string;\n}\n\n// Scheduling interfaces live in `./lifeops.ts` — see LifeOpsSchedulingNegotiation,\n// LifeOpsSchedulingProposal, LIFEOPS_PROPOSAL_STATUSES, LIFEOPS_PROPOSAL_PROPOSERS.\n\n// ── iMessage connector ───────────────────────────────────────────────────────\n\nexport type LifeOpsIMessageHostPlatform =\n | \"darwin\"\n | \"linux\"\n | \"win32\"\n | \"unknown\";\n\nexport interface LifeOpsIMessageConnectorStatus {\n available: boolean;\n connected: boolean;\n bridgeType: \"native\" | \"imsg\" | \"bluebubbles\" | \"none\";\n hostPlatform: LifeOpsIMessageHostPlatform;\n accountHandle: string | null;\n sendMode: \"cli\" | \"private-api\" | \"apple-script\" | \"none\";\n helperConnected: boolean | null;\n privateApiEnabled: boolean | null;\n diagnostics: string[];\n lastSyncAt: string | null;\n lastCheckedAt: string | null;\n error: string | null;\n chatDbAvailable?: boolean;\n sendOnly?: boolean;\n chatDbPath?: string;\n reason?: string | null;\n permissionAction?: {\n type: \"full_disk_access\";\n label: string;\n url: string;\n instructions: string[];\n } | null;\n degradations?: LifeOpsConnectorDegradation[];\n}\n\nexport interface LifeOpsIMessageChat {\n id: string;\n name: string;\n participants: string[];\n lastMessageAt?: string;\n}\n\nexport interface LifeOpsIMessageMessage {\n id: string;\n fromHandle: string;\n toHandles: string[];\n text: string;\n isFromMe: boolean;\n sentAt: string;\n chatId?: string;\n attachments?: Array<{ name: string; mimeType?: string; path?: string }>;\n}\n\nexport interface GetLifeOpsIMessageMessagesRequest {\n chatId?: string;\n since?: string;\n limit?: number;\n}\n\nexport interface SendLifeOpsIMessageRequest {\n to: string;\n text: string;\n attachmentPaths?: string[];\n}\n// ── Knowledge-graph: Entity + Relationship (W1-E) ──────────────────────────\n//\n// Frozen shapes per `eliza/plugins/app-lifeops/docs/audit/wave1-interfaces.md\n// §2`. The runtime stores live in `@elizaos/app-lifeops`. These contracts\n// expose the wire shape so other packages (UI, Cloud relay, tests) can work\n// against typed data without depending on the lifeops package.\n\nexport type LifeOpsEntityVisibility =\n | \"owner_only\"\n | \"agent_and_admin\"\n | \"owner_agent_admin\";\n\nexport type LifeOpsEntityIdentityAddedVia =\n | \"user_chat\"\n | \"merge\"\n | \"platform_observation\"\n | \"extraction\"\n | \"import\";\n\nexport interface LifeOpsEntityIdentity {\n platform: string;\n handle: string;\n displayName?: string;\n verified: boolean;\n confidence: number;\n addedAt: string;\n addedVia: LifeOpsEntityIdentityAddedVia;\n evidence: string[];\n}\n\nexport interface LifeOpsEntityAttribute {\n value: unknown;\n confidence: number;\n evidence: string[];\n updatedAt: string;\n}\n\nexport interface LifeOpsEntityState {\n lastObservedAt?: string;\n lastInboundAt?: string;\n lastOutboundAt?: string;\n lastInteractionPlatform?: string;\n}\n\nexport interface LifeOpsEntity {\n entityId: string;\n type: string;\n preferredName: string;\n fullName?: string;\n identities: LifeOpsEntityIdentity[];\n attributes?: Record<string, LifeOpsEntityAttribute>;\n state: LifeOpsEntityState;\n tags: string[];\n visibility: LifeOpsEntityVisibility;\n createdAt: string;\n updatedAt: string;\n}\n\nexport type LifeOpsGraphRelationshipSource =\n | \"user_chat\"\n | \"platform_observation\"\n | \"extraction\"\n | \"import\"\n | \"system\";\n\nexport type LifeOpsGraphRelationshipStatus = \"active\" | \"retired\";\n\nexport interface LifeOpsGraphRelationshipState {\n lastObservedAt?: string;\n lastInteractionAt?: string;\n interactionCount?: number;\n sentimentTrend?: \"positive\" | \"neutral\" | \"negative\";\n}\n\nexport interface LifeOpsGraphRelationship {\n relationshipId: string;\n fromEntityId: string;\n toEntityId: string;\n type: string;\n metadata?: Record<string, unknown>;\n state: LifeOpsGraphRelationshipState;\n evidence: string[];\n confidence: number;\n source: LifeOpsGraphRelationshipSource;\n status: LifeOpsGraphRelationshipStatus;\n retiredAt?: string;\n retiredReason?: string;\n createdAt: string;\n updatedAt: string;\n}\n"],"mappings":"AAMA,SAAS,0CAA0C;AAE5C,MAAM,4BAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,2BAA2B,CAAC,QAAQ,SAAS,SAAS;AAG5D,MAAM,8BAA8B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,4BAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,MAAM,wBAAwB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,MAAM,wBAAwB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,MAAM,4BAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AACF;AAGO,MAAM,gCAAgC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,iCAAiC;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AACF;AAYO,MAAM,sBAAsB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AA8GO,MAAM,6BAA6B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,4BAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,MAAM,6BAA6B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AACF;AAiCO,MAAM,8BAA8B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,0BAA0B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AACF;AAGO,MAAM,0BAA0B,CAAC,SAAS,OAAO;AAGjD,MAAM,sCAAsC,CAAC,SAAS,OAAO;AAI7D,MAAM,qCAAqC;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,8BAA8B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,yBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,MAAM,qCAAqC;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,wCAAwC;AAAA,EACnD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,yBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,MAAM,8BAA8B;AAAA,EACzC;AAAA,EACA;AACF;AAIO,MAAM,+BAA+B;AAAA,EAC1C;AAAA,EACA;AACF;AAIO,MAAM,gCAAgC;AAAA,EAC3C;AAAA,EACA;AACF;AASO,SAAS,oBACd,iBACA,MACK;AACL,MAAI,SAAS,QAAS,QAAO,CAAC,GAAG,eAAe;AAChD,SAAO,gBAAgB,OAAO,CAAC,MAAM,EAAE,SAAS,OAAO,CAAC;AAC1D;AAEO,MAAM,4BAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,MAAM,wBAAwB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA;AAEF;AAGO,MAAM,0BAA0B,CAAC,WAAW,UAAU,QAAQ;AAG9D,MAAM,kBAAkB,CAAC,gBAAgB,WAAW;AAGpD,MAAM,wBAAwB,CAAC,SAAS,OAAO;AAG/C,MAAM,4BAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AACF;AAGO,MAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,MAAM,kCAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,+BAA+B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,kDAAkD;AAAA,EAC7D;AAAA,EACA;AAAA,EACA;AACF;AAQO,MAAM,sCAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,sBAAsB;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,MAAM,4BAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,MAAM,iBAAiB;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAiDO,MAAM,sCAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AACF;AAiSO,MAAM,wBAAwB,CAAC,UAAU,QAAQ;AAGjD,MAAM,+BAA+B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AA6EO,MAAM,oCAAoC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAoEO,MAAM,kCAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,iCAAiC;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,gCAAgC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAiCO,MAAM,mCAAmC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AA2EO,MAAM,8BAA8B;AAAA,EACzC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AA2SO,MAAM,6BAAgE;AAAA,EAC3E;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAyEO,MAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,0BAA0B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAqdO,MAAM,qCAAqC;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,gCAAgC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,uCAAuC;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,gCAAgC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,qCAAqC;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AA4KO,MAAM,qCAAqC;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AA8GO,MAAM,4BAA4B,CAAC,SAAS,WAAW,MAAM;AAyG7D,MAAM,kCAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AACF;AA+DO,MAAM,yBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAsFO,MAAM,4BAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AACF;AAqCO,MAAM,mCAAmC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AA6DO,MAAM,sCAAsC;AAAA,EACjD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AA6FO,MAAM,uCAAuC;AAAA,EAClD;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,mCAAmC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,oCAAoC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,qCAAqC;AAAA,EAChD;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AA+CO,MAAM,+BAA+B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAsVO,MAAM,gCAAgC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAqLO,MAAM,gCAAgC;AAAA,EAC3C;AAAA,EACA;AACF;AAqFO,MAAM,mCAAmC;AAAA,EAC9C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAuJO,MAAM,2BAA2B;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMO,MAAM,6BAA6B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMO,MAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF;AAiJO,MAAM,6BAA6B;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared system permission contracts.
|
|
3
|
-
*/
|
|
4
|
-
export type SystemPermissionId = "accessibility" | "screen-recording" | "microphone" | "camera" | "shell" | "website-blocking" | "location";
|
|
5
|
-
export type PermissionStatus = "granted" | "denied" | "not-determined" | "restricted" | "not-applicable";
|
|
6
|
-
export type Platform = "darwin" | "win32" | "linux";
|
|
7
|
-
export interface SystemPermissionDefinition {
|
|
8
|
-
id: SystemPermissionId;
|
|
9
|
-
name: string;
|
|
10
|
-
description: string;
|
|
11
|
-
icon: string;
|
|
12
|
-
platforms: Platform[];
|
|
13
|
-
requiredForFeatures: string[];
|
|
14
|
-
}
|
|
15
|
-
export interface PermissionState {
|
|
16
|
-
id: SystemPermissionId;
|
|
17
|
-
status: PermissionStatus;
|
|
18
|
-
lastChecked: number;
|
|
19
|
-
canRequest: boolean;
|
|
20
|
-
reason?: string;
|
|
21
|
-
}
|
|
22
|
-
export interface PermissionCheckResult {
|
|
23
|
-
status: PermissionStatus;
|
|
24
|
-
canRequest: boolean;
|
|
25
|
-
reason?: string;
|
|
26
|
-
}
|
|
27
|
-
export interface AllPermissionsState {
|
|
28
|
-
accessibility: PermissionState;
|
|
29
|
-
"screen-recording": PermissionState;
|
|
30
|
-
microphone: PermissionState;
|
|
31
|
-
camera: PermissionState;
|
|
32
|
-
shell: PermissionState;
|
|
33
|
-
"website-blocking": PermissionState;
|
|
34
|
-
location: PermissionState;
|
|
35
|
-
}
|
|
36
|
-
export interface PermissionManagerConfig {
|
|
37
|
-
cacheTimeoutMs: number;
|
|
38
|
-
}
|
|
39
|
-
//# sourceMappingURL=permissions.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/contracts/permissions.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,MAAM,kBAAkB,GAC1B,eAAe,GACf,kBAAkB,GAClB,YAAY,GACZ,QAAQ,GACR,OAAO,GACP,kBAAkB,GAClB,UAAU,CAAC;AAEf,MAAM,MAAM,gBAAgB,GACxB,SAAS,GACT,QAAQ,GACR,gBAAgB,GAChB,YAAY,GACZ,gBAAgB,CAAC;AAErB,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,OAAO,GAAG,OAAO,CAAC;AAEpD,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,kBAAkB,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,kBAAkB,CAAC;IACvB,MAAM,EAAE,gBAAgB,CAAC;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,gBAAgB,CAAC;IACzB,UAAU,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,mBAAmB;IAClC,aAAa,EAAE,eAAe,CAAC;IAC/B,kBAAkB,EAAE,eAAe,CAAC;IACpC,UAAU,EAAE,eAAe,CAAC;IAC5B,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,eAAe,CAAC;IACvB,kBAAkB,EAAE,eAAe,CAAC;IACpC,QAAQ,EAAE,eAAe,CAAC;CAC3B;AAED,MAAM,WAAW,uBAAuB;IACtC,cAAc,EAAE,MAAM,CAAC;CACxB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=permissions.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `bedtime` default pack — fires a low-pressure reminder when the user is
|
|
3
|
-
* approaching their personal bedtime target.
|
|
4
|
-
*
|
|
5
|
-
* Trigger: `relative_to_anchor("bedtime.target", -30)` — 30 minutes before
|
|
6
|
-
* the bedtime target. Falls back to a fixed 22:30 local cron when the
|
|
7
|
-
* personal-baseline projection is unavailable.
|
|
8
|
-
*
|
|
9
|
-
* Per `wave1-interfaces.md` §5.4: plugin-health ships bedtime / wake-up /
|
|
10
|
-
* sleep-recap default `ScheduledTask` records consuming the W1-A schema.
|
|
11
|
-
*/
|
|
12
|
-
import type { DefaultPack } from "./contract-stubs.js";
|
|
13
|
-
export declare const bedtimeDefaultPack: DefaultPack;
|
|
14
|
-
//# sourceMappingURL=bedtime.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bedtime.d.ts","sourceRoot":"","sources":["../../src/default-packs/bedtime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,kBAAkB,EAAE,WA8ChC,CAAC"}
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
const bedtimeDefaultPack = {
|
|
2
|
-
key: "bedtime",
|
|
3
|
-
label: "Bedtime reminder",
|
|
4
|
-
description: "Low-pressure nudge 30 minutes before the user's personal bedtime target. Quiet when the user has already started winding down (circadian state = winding_down or sleeping).",
|
|
5
|
-
defaultEnabled: false,
|
|
6
|
-
records: [
|
|
7
|
-
{
|
|
8
|
-
kind: "reminder",
|
|
9
|
-
promptInstructions: "Remind the user gently that bedtime is coming up in about 30 minutes. Reference their personal baseline if available; do not lecture or moralize.",
|
|
10
|
-
contextRequest: {
|
|
11
|
-
includeOwnerFacts: ["preferredName", "timezone", "eveningWindow"]
|
|
12
|
-
},
|
|
13
|
-
trigger: {
|
|
14
|
-
kind: "relative_to_anchor",
|
|
15
|
-
anchorKey: "bedtime.target",
|
|
16
|
-
offsetMinutes: -30
|
|
17
|
-
},
|
|
18
|
-
priority: "low",
|
|
19
|
-
shouldFire: {
|
|
20
|
-
compose: "all",
|
|
21
|
-
gates: [{ kind: "circadian_state_in", params: { states: ["awake"] } }]
|
|
22
|
-
},
|
|
23
|
-
completionCheck: {
|
|
24
|
-
kind: "user_acknowledged",
|
|
25
|
-
followupAfterMinutes: 60
|
|
26
|
-
},
|
|
27
|
-
output: {
|
|
28
|
-
destination: "in_app_card",
|
|
29
|
-
persistAs: "task_metadata"
|
|
30
|
-
},
|
|
31
|
-
respectsGlobalPause: true,
|
|
32
|
-
source: "default_pack",
|
|
33
|
-
createdBy: "plugin-health",
|
|
34
|
-
ownerVisible: true,
|
|
35
|
-
metadata: {
|
|
36
|
-
defaultPackKey: "bedtime"
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
],
|
|
40
|
-
uiHints: {
|
|
41
|
-
summaryOnDayOne: "Your bedtime reminder will fire 30 minutes before your typical wind-down time.",
|
|
42
|
-
expectedFireCountPerDay: 1
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
export {
|
|
46
|
-
bedtimeDefaultPack
|
|
47
|
-
};
|
|
48
|
-
//# sourceMappingURL=bedtime.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/default-packs/bedtime.ts"],"sourcesContent":["/**\n * `bedtime` default pack — fires a low-pressure reminder when the user is\n * approaching their personal bedtime target.\n *\n * Trigger: `relative_to_anchor(\"bedtime.target\", -30)` — 30 minutes before\n * the bedtime target. Falls back to a fixed 22:30 local cron when the\n * personal-baseline projection is unavailable.\n *\n * Per `wave1-interfaces.md` §5.4: plugin-health ships bedtime / wake-up /\n * sleep-recap default `ScheduledTask` records consuming the W1-A schema.\n */\n\nimport type { DefaultPack } from \"./contract-stubs.js\";\n\nexport const bedtimeDefaultPack: DefaultPack = {\n key: \"bedtime\",\n label: \"Bedtime reminder\",\n description:\n \"Low-pressure nudge 30 minutes before the user's personal bedtime target. Quiet when the user has already started winding down (circadian state = winding_down or sleeping).\",\n defaultEnabled: false,\n records: [\n {\n kind: \"reminder\",\n promptInstructions:\n \"Remind the user gently that bedtime is coming up in about 30 minutes. Reference their personal baseline if available; do not lecture or moralize.\",\n contextRequest: {\n includeOwnerFacts: [\"preferredName\", \"timezone\", \"eveningWindow\"],\n },\n trigger: {\n kind: \"relative_to_anchor\",\n anchorKey: \"bedtime.target\",\n offsetMinutes: -30,\n },\n priority: \"low\",\n shouldFire: {\n compose: \"all\",\n gates: [{ kind: \"circadian_state_in\", params: { states: [\"awake\"] } }],\n },\n completionCheck: {\n kind: \"user_acknowledged\",\n followupAfterMinutes: 60,\n },\n output: {\n destination: \"in_app_card\",\n persistAs: \"task_metadata\",\n },\n respectsGlobalPause: true,\n source: \"default_pack\",\n createdBy: \"plugin-health\",\n ownerVisible: true,\n metadata: {\n defaultPackKey: \"bedtime\",\n },\n },\n ],\n uiHints: {\n summaryOnDayOne:\n \"Your bedtime reminder will fire 30 minutes before your typical wind-down time.\",\n expectedFireCountPerDay: 1,\n },\n};\n"],"mappings":"AAcO,MAAM,qBAAkC;AAAA,EAC7C,KAAK;AAAA,EACL,OAAO;AAAA,EACP,aACE;AAAA,EACF,gBAAgB;AAAA,EAChB,SAAS;AAAA,IACP;AAAA,MACE,MAAM;AAAA,MACN,oBACE;AAAA,MACF,gBAAgB;AAAA,QACd,mBAAmB,CAAC,iBAAiB,YAAY,eAAe;AAAA,MAClE;AAAA,MACA,SAAS;AAAA,QACP,MAAM;AAAA,QACN,WAAW;AAAA,QACX,eAAe;AAAA,MACjB;AAAA,MACA,UAAU;AAAA,MACV,YAAY;AAAA,QACV,SAAS;AAAA,QACT,OAAO,CAAC,EAAE,MAAM,sBAAsB,QAAQ,EAAE,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC;AAAA,MACvE;AAAA,MACA,iBAAiB;AAAA,QACf,MAAM;AAAA,QACN,sBAAsB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,QACN,aAAa;AAAA,QACb,WAAW;AAAA,MACb;AAAA,MACA,qBAAqB;AAAA,MACrB,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,cAAc;AAAA,MACd,UAAU;AAAA,QACR,gBAAgB;AAAA,MAClB;AAAA,IACF;AAAA,EACF;AAAA,EACA,SAAS;AAAA,IACP,iBACE;AAAA,IACF,yBAAyB;AAAA,EAC3B;AACF;","names":[]}
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Wave-1 contract stubs for the W1-A `ScheduledTask` schema and the W1-D
|
|
3
|
-
* `DefaultPack` envelope. Mirrors `wave1-interfaces.md` §1.1 / §6 byte-
|
|
4
|
-
* identically. Once W1-A / W1-D land, every `import` from this file should
|
|
5
|
-
* be replaced with the real path; nothing else needs to change because the
|
|
6
|
-
* shapes here are the frozen contract.
|
|
7
|
-
*
|
|
8
|
-
* Cross-references:
|
|
9
|
-
* - `eliza/plugins/app-lifeops/src/lifeops/wave1-types.ts` — W1-A's stub
|
|
10
|
-
* of the same `ScheduledTask` shape, kept in sync with this one.
|
|
11
|
-
* - `eliza/plugins/app-lifeops/src/default-packs/contract-stubs.ts` —
|
|
12
|
-
* W1-D's stub of the same shape, kept in sync with this one.
|
|
13
|
-
*
|
|
14
|
-
* No runtime behaviour lives here — types only.
|
|
15
|
-
*/
|
|
16
|
-
export type TerminalState = "completed" | "skipped" | "expired" | "failed" | "dismissed";
|
|
17
|
-
export type ScheduledTaskStatus = TerminalState | "scheduled" | "fired" | "acknowledged";
|
|
18
|
-
export type ScheduledTaskKind = "reminder" | "checkin" | "followup" | "approval" | "recap" | "watcher" | "output" | "custom";
|
|
19
|
-
export type ScheduledTaskPriority = "low" | "medium" | "high";
|
|
20
|
-
export type ScheduledTaskSource = "default_pack" | "user_chat" | "first_run" | "plugin";
|
|
21
|
-
export interface ScheduledTaskState {
|
|
22
|
-
status: ScheduledTaskStatus;
|
|
23
|
-
firedAt?: string;
|
|
24
|
-
acknowledgedAt?: string;
|
|
25
|
-
completedAt?: string;
|
|
26
|
-
followupCount: number;
|
|
27
|
-
lastFollowupAt?: string;
|
|
28
|
-
pipelineParentId?: string;
|
|
29
|
-
lastDecisionLog?: string;
|
|
30
|
-
}
|
|
31
|
-
export type ScheduledTaskTrigger = {
|
|
32
|
-
kind: "once";
|
|
33
|
-
atIso: string;
|
|
34
|
-
} | {
|
|
35
|
-
kind: "cron";
|
|
36
|
-
expression: string;
|
|
37
|
-
tz: string;
|
|
38
|
-
} | {
|
|
39
|
-
kind: "interval";
|
|
40
|
-
everyMinutes: number;
|
|
41
|
-
from?: string;
|
|
42
|
-
until?: string;
|
|
43
|
-
} | {
|
|
44
|
-
kind: "relative_to_anchor";
|
|
45
|
-
anchorKey: string;
|
|
46
|
-
offsetMinutes: number;
|
|
47
|
-
} | {
|
|
48
|
-
kind: "during_window";
|
|
49
|
-
windowKey: string;
|
|
50
|
-
} | {
|
|
51
|
-
kind: "event";
|
|
52
|
-
eventKind: string;
|
|
53
|
-
filter?: unknown;
|
|
54
|
-
} | {
|
|
55
|
-
kind: "manual";
|
|
56
|
-
} | {
|
|
57
|
-
kind: "after_task";
|
|
58
|
-
taskId: string;
|
|
59
|
-
outcome: TerminalState;
|
|
60
|
-
};
|
|
61
|
-
export interface ScheduledTaskCompletionCheck {
|
|
62
|
-
kind: string;
|
|
63
|
-
params?: unknown;
|
|
64
|
-
followupAfterMinutes?: number;
|
|
65
|
-
}
|
|
66
|
-
export interface ScheduledTaskSubject {
|
|
67
|
-
kind: "entity" | "relationship" | "thread" | "document" | "calendar_event" | "self";
|
|
68
|
-
id: string;
|
|
69
|
-
}
|
|
70
|
-
export interface EscalationStep {
|
|
71
|
-
delayMinutes: number;
|
|
72
|
-
channelKey: string;
|
|
73
|
-
intensity?: "soft" | "normal" | "urgent";
|
|
74
|
-
}
|
|
75
|
-
export interface ScheduledTask {
|
|
76
|
-
taskId: string;
|
|
77
|
-
kind: ScheduledTaskKind;
|
|
78
|
-
promptInstructions: string;
|
|
79
|
-
contextRequest?: {
|
|
80
|
-
includeOwnerFacts?: ReadonlyArray<"preferredName" | "timezone" | "morningWindow" | "eveningWindow" | "locale">;
|
|
81
|
-
includeEntities?: {
|
|
82
|
-
entityIds: string[];
|
|
83
|
-
fields?: ReadonlyArray<"preferredName" | "type" | "identities" | "state.lastInteractionPlatform">;
|
|
84
|
-
};
|
|
85
|
-
includeRelationships?: {
|
|
86
|
-
relationshipIds?: string[];
|
|
87
|
-
forEntityIds?: string[];
|
|
88
|
-
types?: string[];
|
|
89
|
-
};
|
|
90
|
-
includeRecentTaskStates?: {
|
|
91
|
-
kind?: ScheduledTaskKind;
|
|
92
|
-
lookbackHours?: number;
|
|
93
|
-
};
|
|
94
|
-
includeEventPayload?: boolean;
|
|
95
|
-
};
|
|
96
|
-
trigger: ScheduledTaskTrigger;
|
|
97
|
-
priority: ScheduledTaskPriority;
|
|
98
|
-
shouldFire?: {
|
|
99
|
-
compose?: "all" | "any" | "first_deny";
|
|
100
|
-
gates: Array<{
|
|
101
|
-
kind: string;
|
|
102
|
-
params?: unknown;
|
|
103
|
-
}>;
|
|
104
|
-
};
|
|
105
|
-
completionCheck?: ScheduledTaskCompletionCheck;
|
|
106
|
-
escalation?: {
|
|
107
|
-
ladderKey?: string;
|
|
108
|
-
steps?: EscalationStep[];
|
|
109
|
-
};
|
|
110
|
-
output?: {
|
|
111
|
-
destination: "in_app_card" | "channel" | "apple_notes" | "gmail_draft" | "memory";
|
|
112
|
-
target?: string;
|
|
113
|
-
persistAs?: "task_metadata" | "external_only";
|
|
114
|
-
};
|
|
115
|
-
pipeline?: {
|
|
116
|
-
onComplete?: Array<string | ScheduledTask>;
|
|
117
|
-
onSkip?: Array<string | ScheduledTask>;
|
|
118
|
-
onFail?: Array<string | ScheduledTask>;
|
|
119
|
-
};
|
|
120
|
-
subject?: ScheduledTaskSubject;
|
|
121
|
-
idempotencyKey?: string;
|
|
122
|
-
respectsGlobalPause: boolean;
|
|
123
|
-
state: ScheduledTaskState;
|
|
124
|
-
source: ScheduledTaskSource;
|
|
125
|
-
createdBy: string;
|
|
126
|
-
ownerVisible: boolean;
|
|
127
|
-
metadata?: Record<string, unknown>;
|
|
128
|
-
}
|
|
129
|
-
/** Default-pack records are `ScheduledTask`s without runner-managed fields. */
|
|
130
|
-
export type ScheduledTaskSeed = Omit<ScheduledTask, "taskId" | "state">;
|
|
131
|
-
export interface AnchorConsolidationPolicy {
|
|
132
|
-
anchorKey: string;
|
|
133
|
-
mode: "merge" | "sequential" | "parallel";
|
|
134
|
-
staggerMinutes?: number;
|
|
135
|
-
maxBatchSize?: number;
|
|
136
|
-
sortBy?: "priority_desc" | "fired_at_asc";
|
|
137
|
-
}
|
|
138
|
-
export type DefaultEscalationLadderKey = "priority_low_default" | "priority_medium_default" | "priority_high_default";
|
|
139
|
-
export interface EscalationLadder {
|
|
140
|
-
steps: EscalationStep[];
|
|
141
|
-
}
|
|
142
|
-
export interface DefaultPack {
|
|
143
|
-
key: string;
|
|
144
|
-
label: string;
|
|
145
|
-
description: string;
|
|
146
|
-
defaultEnabled: boolean;
|
|
147
|
-
requiredCapabilities?: string[];
|
|
148
|
-
records: ScheduledTaskSeed[];
|
|
149
|
-
consolidationPolicies?: AnchorConsolidationPolicy[];
|
|
150
|
-
escalationLadders?: Partial<Record<DefaultEscalationLadderKey, EscalationLadder>>;
|
|
151
|
-
uiHints?: {
|
|
152
|
-
summaryOnDayOne: string;
|
|
153
|
-
expectedFireCountPerDay: number;
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
export interface DefaultPackRegistry {
|
|
157
|
-
register(pack: DefaultPack): void;
|
|
158
|
-
list(): DefaultPack[];
|
|
159
|
-
get(key: string): DefaultPack | null;
|
|
160
|
-
}
|
|
161
|
-
//# sourceMappingURL=contract-stubs.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"contract-stubs.d.ts","sourceRoot":"","sources":["../../src/default-packs/contract-stubs.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
//# sourceMappingURL=contract-stubs.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|