@elizaos/plugin-finances 2.0.3-beta.5 → 2.0.3-beta.7
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/dist/actions/finances.d.ts +38 -0
- package/dist/actions/finances.d.ts.map +1 -0
- package/dist/actions/finances.js +368 -0
- package/dist/actions/finances.js.map +1 -0
- package/dist/components/finances/FinancesSpatialView.d.ts +80 -0
- package/dist/components/finances/FinancesSpatialView.d.ts.map +1 -0
- package/dist/components/finances/FinancesSpatialView.js +157 -0
- package/dist/components/finances/FinancesSpatialView.js.map +1 -0
- package/dist/components/finances/FinancesView.d.ts +97 -0
- package/dist/components/finances/FinancesView.d.ts.map +1 -0
- package/dist/components/finances/FinancesView.js +231 -0
- package/dist/components/finances/FinancesView.js.map +1 -0
- package/dist/components/finances/finances-view-bundle.d.ts +10 -0
- package/dist/components/finances/finances-view-bundle.d.ts.map +1 -0
- package/dist/components/finances/finances-view-bundle.js +5 -0
- package/dist/components/finances/finances-view-bundle.js.map +1 -0
- package/dist/db/finances-repository.d.ts +51 -0
- package/dist/db/finances-repository.d.ts.map +1 -0
- package/dist/db/finances-repository.js +521 -0
- package/dist/db/finances-repository.js.map +1 -0
- package/dist/db/index.d.ts +3 -0
- package/dist/db/index.d.ts.map +1 -0
- package/dist/db/index.js +6 -0
- package/dist/db/index.js.map +1 -0
- package/dist/db/schema.d.ts +2615 -0
- package/dist/db/schema.d.ts.map +1 -0
- package/dist/db/schema.js +133 -0
- package/dist/db/schema.js.map +1 -0
- package/dist/db/sql.d.ts +65 -0
- package/dist/db/sql.d.ts.map +1 -0
- package/dist/db/sql.js +182 -0
- package/dist/db/sql.js.map +1 -0
- package/dist/finance-normalize.d.ts +24 -0
- package/dist/finance-normalize.d.ts.map +1 -0
- package/dist/finance-normalize.js +66 -0
- package/dist/finance-normalize.js.map +1 -0
- package/dist/finances-service.d.ts +179 -0
- package/dist/finances-service.d.ts.map +1 -0
- package/dist/finances-service.js +1122 -0
- package/dist/finances-service.js.map +1 -0
- package/dist/index.d.ts +32 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +109 -0
- package/dist/index.js.map +1 -0
- package/dist/payment-csv-import.d.ts +23 -0
- package/dist/payment-csv-import.d.ts.map +1 -0
- package/dist/payment-csv-import.js +271 -0
- package/dist/payment-csv-import.js.map +1 -0
- package/dist/payment-recurrence.d.ts +14 -0
- package/dist/payment-recurrence.d.ts.map +1 -0
- package/dist/payment-recurrence.js +190 -0
- package/dist/payment-recurrence.js.map +1 -0
- package/dist/payment-types.d.ts +158 -0
- package/dist/payment-types.d.ts.map +1 -0
- package/dist/payment-types.js +1 -0
- package/dist/payment-types.js.map +1 -0
- package/dist/plugin.d.ts +15 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +31 -0
- package/dist/plugin.js.map +1 -0
- package/dist/register-terminal-view.d.ts +15 -0
- package/dist/register-terminal-view.d.ts.map +1 -0
- package/dist/register-terminal-view.js +21 -0
- package/dist/register-terminal-view.js.map +1 -0
- package/dist/register.d.ts +9 -0
- package/dist/register.d.ts.map +1 -0
- package/dist/register.js +5 -0
- package/dist/register.js.map +1 -0
- package/dist/services/browser-bridge-seam.d.ts +40 -0
- package/dist/services/browser-bridge-seam.d.ts.map +1 -0
- package/dist/services/browser-bridge-seam.js +39 -0
- package/dist/services/browser-bridge-seam.js.map +1 -0
- package/dist/services/gmail-seam.d.ts +40 -0
- package/dist/services/gmail-seam.d.ts.map +1 -0
- package/dist/services/gmail-seam.js +208 -0
- package/dist/services/gmail-seam.js.map +1 -0
- package/dist/services/migration.d.ts +65 -0
- package/dist/services/migration.d.ts.map +1 -0
- package/dist/services/migration.js +116 -0
- package/dist/services/migration.js.map +1 -0
- package/dist/services/subscriptions-service.d.ts +76 -0
- package/dist/services/subscriptions-service.d.ts.map +1 -0
- package/dist/services/subscriptions-service.js +1002 -0
- package/dist/services/subscriptions-service.js.map +1 -0
- package/dist/subscriptions-playbooks.d.ts +79 -0
- package/dist/subscriptions-playbooks.d.ts.map +1 -0
- package/dist/subscriptions-playbooks.js +871 -0
- package/dist/subscriptions-playbooks.js.map +1 -0
- package/dist/subscriptions-types.d.ts +80 -0
- package/dist/subscriptions-types.d.ts.map +1 -0
- package/dist/subscriptions-types.js +1 -0
- package/dist/subscriptions-types.js.map +1 -0
- package/dist/token-encryption.d.ts +42 -0
- package/dist/token-encryption.d.ts.map +1 -0
- package/dist/token-encryption.js +96 -0
- package/dist/token-encryption.js.map +1 -0
- package/dist/types.d.ts +55 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +18 -0
- package/dist/types.js.map +1 -0
- package/dist/views/bundle.js +411 -0
- package/dist/views/bundle.js.map +1 -0
- package/package.json +11 -11
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/subscriptions-playbooks.ts"],"sourcesContent":["import type { LifeOpsSubscriptionExecutor } from \"./subscriptions-types.js\";\n\nexport type SubscriptionAutomationStep =\n | {\n kind: \"open\";\n url: string;\n }\n | {\n kind: \"navigate\";\n url: string;\n }\n | {\n kind: \"wait_text\";\n text: string;\n timeoutMs?: number;\n }\n | {\n kind: \"wait_selector\";\n selector: string;\n timeoutMs?: number;\n }\n | {\n kind: \"click_text\";\n text: string;\n destructive?: boolean;\n }\n | {\n kind: \"click_selector\";\n selector: string;\n destructive?: boolean;\n }\n | {\n kind: \"assert_text\";\n text: string;\n }\n | {\n kind: \"screenshot\";\n label: string;\n };\n\nexport type SubscriptionCancellationCapability =\n | {\n kind: \"executable_playbook\";\n label: \"Executable cancellation playbook\";\n executionSurface: \"browser_steps\";\n manualFallback: false;\n }\n | {\n kind: \"management_url_manual_fallback\";\n label: \"Management URL manual fallback\";\n executionSurface: \"management_url\";\n manualFallback: true;\n reason: \"no_verified_click_flow\";\n };\n\nexport interface LifeOpsSubscriptionPlaybook {\n key: string;\n serviceName: string;\n aliases: string[];\n executorPreference: LifeOpsSubscriptionExecutor;\n cancellationCapability: SubscriptionCancellationCapability;\n managementUrl: string;\n managementPath?: string;\n auditDomains: string[];\n auditSubjectKeywords: string[];\n loginMarkers: string[];\n mfaMarkers: string[];\n phoneOnlyMarkers: string[];\n chatOnlyMarkers: string[];\n cancellationMarkers: string[];\n /**\n * Concrete browser automation steps. When undefined, the service has no\n * real click-flow implemented — the caller must report a\n * `PLAYBOOK_NOT_IMPLEMENTED` failure rather than pretend to cancel.\n */\n steps?: SubscriptionAutomationStep[];\n companionSelectors?: {\n cancel?: string;\n confirm?: string;\n };\n}\n\nconst FIXTURE_BASE_URL_ENV = \"ELIZA_SUBSCRIPTION_FIXTURE_BASE_URL\";\n\n/**\n * Error-code prefix used by the subscriptions mixin and action when a\n * playbook is registered (we know the management URL) but no concrete\n * click-flow is available yet. Shared with the action so callers\n * can pattern-match structured failures instead of parsing free text.\n */\nexport const PLAYBOOK_UNSUPPORTED_FLOW_ERROR = \"PLAYBOOK_UNSUPPORTED_FLOW\";\n\nfunction configuredFixtureBaseUrl(): string | null {\n const value = process.env[FIXTURE_BASE_URL_ENV]?.trim();\n if (!value) {\n return null;\n }\n return value.replace(/\\/+$/, \"\");\n}\n\nfunction withFixtureOverride(path: string, fallback: string): string {\n const base = configuredFixtureBaseUrl();\n return base ? `${base}${path}` : fallback;\n}\n\nconst GENERIC_LOGIN_MARKERS = [\n \"sign in\",\n \"log in\",\n \"login\",\n \"password\",\n \"email address\",\n] as const;\n\nconst GENERIC_MFA_MARKERS = [\n \"verification code\",\n \"two-factor\",\n \"2-step verification\",\n \"enter code\",\n] as const;\n\nconst GENERIC_CANCELLATION_MARKERS = [\n \"canceled\",\n \"cancelled\",\n \"subscription ended\",\n \"membership ended\",\n \"membership canceled\",\n \"subscription canceled\",\n \"cancellation confirmed\",\n \"you won't be charged\",\n \"your plan ends\",\n];\n\nconst EXECUTABLE_PLAYBOOK_CAPABILITY = {\n kind: \"executable_playbook\",\n label: \"Executable cancellation playbook\",\n executionSurface: \"browser_steps\",\n manualFallback: false,\n} as const satisfies SubscriptionCancellationCapability;\n\nconst MANAGEMENT_URL_MANUAL_FALLBACK_CAPABILITY = {\n kind: \"management_url_manual_fallback\",\n label: \"Management URL manual fallback\",\n executionSurface: \"management_url\",\n manualFallback: true,\n reason: \"no_verified_click_flow\",\n} as const satisfies SubscriptionCancellationCapability;\n\nfunction cancellationCapabilityForSteps(\n steps: SubscriptionAutomationStep[] | undefined,\n): SubscriptionCancellationCapability {\n return steps && steps.length > 0\n ? { ...EXECUTABLE_PLAYBOOK_CAPABILITY }\n : { ...MANAGEMENT_URL_MANUAL_FALLBACK_CAPABILITY };\n}\n\n/**\n * Build a management-URL-only playbook for services where the cancellation\n * flow is behind login, retention offers, or app-store ownership. This covers\n * the long tail of popular subscriptions without pretending URL knowledge is\n * the same as a verified click-flow.\n */\nfunction definePlaybook(\n partial: Pick<\n LifeOpsSubscriptionPlaybook,\n | \"key\"\n | \"serviceName\"\n | \"aliases\"\n | \"managementUrl\"\n | \"auditDomains\"\n | \"auditSubjectKeywords\"\n > &\n Partial<\n Pick<\n LifeOpsSubscriptionPlaybook,\n | \"executorPreference\"\n | \"managementPath\"\n | \"loginMarkers\"\n | \"mfaMarkers\"\n | \"phoneOnlyMarkers\"\n | \"chatOnlyMarkers\"\n | \"cancellationMarkers\"\n | \"steps\"\n | \"companionSelectors\"\n >\n >,\n): LifeOpsSubscriptionPlaybook {\n const managementUrl = partial.managementUrl;\n return {\n key: partial.key,\n serviceName: partial.serviceName,\n aliases: partial.aliases,\n executorPreference: partial.executorPreference ?? \"user_browser\",\n cancellationCapability: cancellationCapabilityForSteps(partial.steps),\n managementUrl,\n managementPath: partial.managementPath,\n auditDomains: partial.auditDomains,\n auditSubjectKeywords: partial.auditSubjectKeywords,\n loginMarkers: partial.loginMarkers ?? [...GENERIC_LOGIN_MARKERS],\n mfaMarkers: partial.mfaMarkers ?? [...GENERIC_MFA_MARKERS],\n phoneOnlyMarkers: partial.phoneOnlyMarkers ?? [],\n chatOnlyMarkers: partial.chatOnlyMarkers ?? [],\n cancellationMarkers:\n partial.cancellationMarkers ?? GENERIC_CANCELLATION_MARKERS,\n // No default steps: opening the management URL + a screenshot is NOT a\n // cancellation. Services without an explicit click-flow are handled by\n // the caller as PLAYBOOK_NOT_IMPLEMENTED so we don't silently report\n // fake success. See service-mixin-subscriptions.ts.\n steps: partial.steps,\n companionSelectors: partial.companionSelectors,\n };\n}\n\nexport const LIFEOPS_SUBSCRIPTION_PLAYBOOKS: readonly LifeOpsSubscriptionPlaybook[] =\n [\n {\n key: \"google_play\",\n serviceName: \"Google Play\",\n aliases: [\"google play\", \"play store\", \"play subscriptions\"],\n executorPreference: \"agent_browser\",\n cancellationCapability: { ...EXECUTABLE_PLAYBOOK_CAPABILITY },\n managementUrl: withFixtureOverride(\n \"/stores/google-play\",\n \"https://play.google.com/store/account/subscriptions\",\n ),\n managementPath: \"/stores/google-play\",\n auditDomains: [\"google.com\", \"googleplay.com\"],\n auditSubjectKeywords: [\n \"google play\",\n \"subscription\",\n \"renewal\",\n \"receipt\",\n ],\n loginMarkers: [...GENERIC_LOGIN_MARKERS],\n mfaMarkers: [...GENERIC_MFA_MARKERS],\n phoneOnlyMarkers: [\"phone support\"],\n chatOnlyMarkers: [\"chat support\"],\n cancellationMarkers: [\"subscription canceled\", \"canceled on\"],\n steps: [\n {\n kind: \"open\",\n url: withFixtureOverride(\n \"/stores/google-play\",\n \"https://play.google.com/store/account/subscriptions\",\n ),\n },\n { kind: \"wait_text\", text: \"Subscriptions\" },\n { kind: \"click_text\", text: \"Cancel subscription\" },\n { kind: \"wait_text\", text: \"Confirm cancellation\" },\n { kind: \"click_text\", text: \"Confirm cancellation\", destructive: true },\n { kind: \"wait_text\", text: \"subscription canceled\" },\n { kind: \"screenshot\", label: \"google-play-cancelled\" },\n ],\n companionSelectors: {\n cancel: \"[data-lifeops-action='cancel-subscription']\",\n confirm: \"[data-lifeops-action='confirm-cancellation']\",\n },\n },\n {\n key: \"apple_subscriptions\",\n serviceName: \"Apple subscriptions\",\n aliases: [\n \"apple subscriptions\",\n \"app store\",\n \"itunes subscription\",\n \"apple services\",\n ],\n executorPreference: \"agent_browser\",\n cancellationCapability: { ...EXECUTABLE_PLAYBOOK_CAPABILITY },\n managementUrl: withFixtureOverride(\n \"/stores/apple-subscriptions\",\n \"https://account.apple.com/account/manage/section/subscriptions\",\n ),\n managementPath: \"/stores/apple-subscriptions\",\n auditDomains: [\"apple.com\", \"itunes.com\"],\n auditSubjectKeywords: [\n \"app store\",\n \"apple subscription\",\n \"renewal receipt\",\n ],\n loginMarkers: [...GENERIC_LOGIN_MARKERS, \"apple id\"],\n mfaMarkers: [...GENERIC_MFA_MARKERS, \"trusted device\"],\n phoneOnlyMarkers: [\"contact apple support by phone\"],\n chatOnlyMarkers: [\"chat with apple support\"],\n cancellationMarkers: [\"subscription canceled\", \"expires on\"],\n steps: [\n {\n kind: \"open\",\n url: withFixtureOverride(\n \"/stores/apple-subscriptions\",\n \"https://account.apple.com/account/manage/section/subscriptions\",\n ),\n },\n { kind: \"wait_text\", text: \"Subscriptions\" },\n { kind: \"click_text\", text: \"Cancel subscription\" },\n { kind: \"wait_text\", text: \"Confirm cancellation\" },\n { kind: \"click_text\", text: \"Confirm cancellation\", destructive: true },\n { kind: \"wait_text\", text: \"subscription canceled\" },\n { kind: \"screenshot\", label: \"apple-subscriptions-cancelled\" },\n ],\n companionSelectors: {\n cancel: \"[data-lifeops-action='cancel-subscription']\",\n confirm: \"[data-lifeops-action='confirm-cancellation']\",\n },\n },\n {\n key: \"fixture_streaming\",\n serviceName: \"Fixture Streaming\",\n aliases: [\"fixture streaming\", \"streaming fixture\", \"test streaming\"],\n executorPreference: \"agent_browser\",\n cancellationCapability: { ...EXECUTABLE_PLAYBOOK_CAPABILITY },\n managementUrl: withFixtureOverride(\n \"/services/fixture-streaming\",\n \"https://example.com/account/subscription\",\n ),\n managementPath: \"/services/fixture-streaming\",\n auditDomains: [\"fixture-streaming.example\"],\n auditSubjectKeywords: [\"fixture streaming\", \"monthly plan\", \"receipt\"],\n loginMarkers: [...GENERIC_LOGIN_MARKERS],\n mfaMarkers: [...GENERIC_MFA_MARKERS],\n phoneOnlyMarkers: [\"call us to cancel\"],\n chatOnlyMarkers: [\"chat with support to cancel\"],\n cancellationMarkers: [\"subscription canceled\"],\n steps: [\n {\n kind: \"open\",\n url: withFixtureOverride(\n \"/services/fixture-streaming\",\n \"https://example.com/account/subscription\",\n ),\n },\n { kind: \"wait_text\", text: \"Fixture Streaming\" },\n { kind: \"click_text\", text: \"Cancel subscription\" },\n { kind: \"wait_text\", text: \"Confirm cancellation\" },\n { kind: \"click_text\", text: \"Confirm cancellation\", destructive: true },\n { kind: \"wait_text\", text: \"subscription canceled\" },\n { kind: \"screenshot\", label: \"fixture-streaming-cancelled\" },\n ],\n companionSelectors: {\n cancel: \"[data-lifeops-action='cancel-subscription']\",\n confirm: \"[data-lifeops-action='confirm-cancellation']\",\n },\n },\n {\n key: \"fixture_login_required\",\n serviceName: \"Fixture Access Wall\",\n aliases: [\n \"fixture access wall\",\n \"test access wall\",\n \"fixture sign in handoff\",\n \"fixture sign-in handoff\",\n \"test sign in handoff\",\n \"test sign-in handoff\",\n ],\n executorPreference: \"agent_browser\",\n cancellationCapability: { ...EXECUTABLE_PLAYBOOK_CAPABILITY },\n managementUrl: withFixtureOverride(\n \"/services/login-required\",\n \"https://example.com/account/subscription\",\n ),\n managementPath: \"/services/login-required\",\n auditDomains: [\"login-required.example\"],\n auditSubjectKeywords: [\"login required\", \"membership receipt\"],\n loginMarkers: [...GENERIC_LOGIN_MARKERS],\n mfaMarkers: [...GENERIC_MFA_MARKERS],\n phoneOnlyMarkers: [],\n chatOnlyMarkers: [],\n cancellationMarkers: [\"subscription canceled\"],\n steps: [\n {\n kind: \"open\",\n url: withFixtureOverride(\n \"/services/login-required\",\n \"https://example.com/account/subscription\",\n ),\n },\n { kind: \"wait_text\", text: \"Sign in to continue\" },\n ],\n companionSelectors: {},\n },\n {\n key: \"fixture_phone_only\",\n serviceName: \"Fixture Phone Only\",\n aliases: [\"fixture phone only\", \"test phone only\"],\n executorPreference: \"agent_browser\",\n cancellationCapability: { ...EXECUTABLE_PLAYBOOK_CAPABILITY },\n managementUrl: withFixtureOverride(\n \"/services/phone-only\",\n \"https://example.com/account/subscription\",\n ),\n managementPath: \"/services/phone-only\",\n auditDomains: [\"phone-only.example\"],\n auditSubjectKeywords: [\"phone only\", \"billing receipt\"],\n loginMarkers: [],\n mfaMarkers: [],\n phoneOnlyMarkers: [\"call us to cancel\"],\n chatOnlyMarkers: [],\n cancellationMarkers: [],\n steps: [\n {\n kind: \"open\",\n url: withFixtureOverride(\n \"/services/phone-only\",\n \"https://example.com/account/subscription\",\n ),\n },\n { kind: \"wait_text\", text: \"Call us to cancel\" },\n ],\n companionSelectors: {},\n },\n\n // ---- Streaming video ---------------------------------------------------\n definePlaybook({\n key: \"netflix\",\n serviceName: \"Netflix\",\n aliases: [\"netflix\"],\n managementUrl: \"https://www.netflix.com/cancelplan\",\n auditDomains: [\"netflix.com\"],\n auditSubjectKeywords: [\"netflix\", \"your monthly charge\", \"membership\"],\n }),\n definePlaybook({\n key: \"hulu\",\n serviceName: \"Hulu\",\n aliases: [\"hulu\"],\n managementUrl: \"https://secure.hulu.com/account/cancel\",\n auditDomains: [\"hulu.com\"],\n auditSubjectKeywords: [\"hulu\", \"your hulu receipt\"],\n }),\n definePlaybook({\n key: \"disney_plus\",\n serviceName: \"Disney+\",\n aliases: [\"disney plus\", \"disneyplus\", \"disney+\"],\n managementUrl: \"https://www.disneyplus.com/account/subscription\",\n auditDomains: [\"disneyplus.com\", \"mail.disneyplus.com\"],\n auditSubjectKeywords: [\n \"disney+\",\n \"disney plus\",\n \"your disney+ subscription\",\n ],\n }),\n definePlaybook({\n key: \"max_hbo\",\n serviceName: \"Max (HBO)\",\n aliases: [\"max\", \"hbo max\", \"hbomax\"],\n managementUrl: \"https://auth.max.com/my-account\",\n auditDomains: [\"max.com\", \"hbomax.com\", \"mail.max.com\"],\n auditSubjectKeywords: [\"max\", \"hbo max\", \"your max subscription\"],\n }),\n definePlaybook({\n key: \"peacock\",\n serviceName: \"Peacock\",\n aliases: [\"peacock\", \"peacock tv\"],\n managementUrl: \"https://www.peacocktv.com/account/plans\",\n auditDomains: [\"peacocktv.com\", \"nbcuni.com\"],\n auditSubjectKeywords: [\"peacock\", \"your peacock plan\"],\n }),\n definePlaybook({\n key: \"paramount_plus\",\n serviceName: \"Paramount+\",\n aliases: [\"paramount plus\", \"paramount+\"],\n managementUrl: \"https://www.paramountplus.com/account/subscription\",\n auditDomains: [\"paramountplus.com\", \"cbs.com\"],\n auditSubjectKeywords: [\"paramount+\", \"paramount plus\"],\n }),\n definePlaybook({\n key: \"apple_tv_plus\",\n serviceName: \"Apple TV+\",\n aliases: [\"apple tv+\", \"apple tv plus\", \"tv+\"],\n managementUrl: \"https://tv.apple.com/account\",\n auditDomains: [\"apple.com\", \"itunes.com\"],\n auditSubjectKeywords: [\"apple tv+\", \"apple tv plus\"],\n }),\n definePlaybook({\n key: \"amazon_prime_video\",\n serviceName: \"Amazon Prime Video\",\n aliases: [\"amazon prime video\", \"prime video\"],\n managementUrl: \"https://www.amazon.com/gp/video/settings\",\n auditDomains: [\"amazon.com\", \"primevideo.com\"],\n auditSubjectKeywords: [\"prime video\", \"amazon video\"],\n }),\n definePlaybook({\n key: \"amazon_prime\",\n serviceName: \"Amazon Prime\",\n aliases: [\"amazon prime\", \"prime membership\"],\n managementUrl:\n \"https://www.amazon.com/gp/help/customer/contact-us/?nodeId=G34EUPKVMYFW8N2U\",\n auditDomains: [\"amazon.com\"],\n auditSubjectKeywords: [\"your amazon prime\", \"prime membership\"],\n }),\n definePlaybook({\n key: \"youtube_premium\",\n serviceName: \"YouTube Premium\",\n aliases: [\"youtube premium\", \"yt premium\", \"youtube music premium\"],\n managementUrl: \"https://www.youtube.com/paid_memberships\",\n auditDomains: [\"youtube.com\", \"google.com\"],\n auditSubjectKeywords: [\"youtube premium\", \"youtube music\"],\n }),\n definePlaybook({\n key: \"crunchyroll\",\n serviceName: \"Crunchyroll\",\n aliases: [\"crunchyroll\"],\n managementUrl: \"https://www.crunchyroll.com/account/membership\",\n auditDomains: [\"crunchyroll.com\"],\n auditSubjectKeywords: [\"crunchyroll\", \"premium subscription\"],\n }),\n definePlaybook({\n key: \"espn_plus\",\n serviceName: \"ESPN+\",\n aliases: [\"espn+\", \"espn plus\"],\n managementUrl: \"https://www.espn.com/watch/account\",\n auditDomains: [\"espn.com\"],\n auditSubjectKeywords: [\"espn+\", \"espn plus\"],\n }),\n\n // ---- Music -------------------------------------------------------------\n definePlaybook({\n key: \"spotify\",\n serviceName: \"Spotify\",\n aliases: [\"spotify\", \"spotify premium\"],\n managementUrl: \"https://www.spotify.com/account/subscription/\",\n auditDomains: [\"spotify.com\"],\n auditSubjectKeywords: [\"spotify\", \"premium receipt\"],\n }),\n definePlaybook({\n key: \"apple_music\",\n serviceName: \"Apple Music\",\n aliases: [\"apple music\"],\n managementUrl: \"https://music.apple.com/account/settings\",\n auditDomains: [\"apple.com\", \"itunes.com\"],\n auditSubjectKeywords: [\"apple music\"],\n }),\n definePlaybook({\n key: \"tidal\",\n serviceName: \"Tidal\",\n aliases: [\"tidal\"],\n managementUrl: \"https://listen.tidal.com/account/subscription\",\n auditDomains: [\"tidal.com\"],\n auditSubjectKeywords: [\"tidal\", \"your tidal subscription\"],\n }),\n definePlaybook({\n key: \"pandora\",\n serviceName: \"Pandora\",\n aliases: [\"pandora\", \"pandora premium\", \"pandora plus\"],\n managementUrl: \"https://www.pandora.com/account/subscription\",\n auditDomains: [\"pandora.com\"],\n auditSubjectKeywords: [\"pandora\", \"pandora premium\", \"pandora plus\"],\n }),\n definePlaybook({\n key: \"siriusxm\",\n serviceName: \"SiriusXM\",\n aliases: [\"siriusxm\", \"sirius xm\", \"sirius\"],\n managementUrl: \"https://www.siriusxm.com/account/managesubscriptions\",\n auditDomains: [\"siriusxm.com\"],\n auditSubjectKeywords: [\"siriusxm\", \"your sirius\"],\n phoneOnlyMarkers: [\"call to cancel\", \"1-866-635-5027\"],\n }),\n\n // ---- News / media ------------------------------------------------------\n definePlaybook({\n key: \"nytimes\",\n serviceName: \"The New York Times\",\n aliases: [\"nyt\", \"new york times\", \"nytimes\"],\n managementUrl: \"https://www.nytimes.com/subscription/manage/downgrade\",\n auditDomains: [\"nytimes.com\"],\n auditSubjectKeywords: [\"new york times\", \"nyt subscription\"],\n chatOnlyMarkers: [\"chat with us\"],\n }),\n definePlaybook({\n key: \"wsj\",\n serviceName: \"Wall Street Journal\",\n aliases: [\"wsj\", \"wall street journal\"],\n managementUrl: \"https://customercenter.wsj.com/view/subscriptions.html\",\n auditDomains: [\"wsj.com\", \"dowjones.com\"],\n auditSubjectKeywords: [\"wsj\", \"wall street journal\"],\n }),\n definePlaybook({\n key: \"washington_post\",\n serviceName: \"The Washington Post\",\n aliases: [\"wapo\", \"washington post\", \"washingtonpost\"],\n managementUrl:\n \"https://subscribe.washingtonpost.com/profile/subscription\",\n auditDomains: [\"washingtonpost.com\"],\n auditSubjectKeywords: [\"washington post\", \"wapo subscription\"],\n }),\n definePlaybook({\n key: \"the_atlantic\",\n serviceName: \"The Atlantic\",\n aliases: [\"the atlantic\", \"atlantic subscription\"],\n managementUrl: \"https://accounts.theatlantic.com/account/subscription/\",\n auditDomains: [\"theatlantic.com\"],\n auditSubjectKeywords: [\"the atlantic\", \"atlantic subscription\"],\n }),\n definePlaybook({\n key: \"medium\",\n serviceName: \"Medium\",\n aliases: [\"medium\", \"medium membership\"],\n managementUrl: \"https://medium.com/me/membership\",\n auditDomains: [\"medium.com\"],\n auditSubjectKeywords: [\"medium membership\", \"medium receipt\"],\n }),\n definePlaybook({\n key: \"substack\",\n serviceName: \"Substack\",\n aliases: [\"substack\"],\n managementUrl: \"https://substack.com/account\",\n auditDomains: [\"substack.com\"],\n auditSubjectKeywords: [\"substack\", \"your substack subscription\"],\n }),\n definePlaybook({\n key: \"bloomberg\",\n serviceName: \"Bloomberg\",\n aliases: [\"bloomberg\", \"bloomberg subscription\"],\n managementUrl: \"https://www.bloomberg.com/account/subscriptions\",\n auditDomains: [\"bloomberg.com\"],\n auditSubjectKeywords: [\"bloomberg\", \"bloomberg subscription\"],\n }),\n\n // ---- Software / Cloud --------------------------------------------------\n definePlaybook({\n key: \"icloud\",\n serviceName: \"iCloud+\",\n aliases: [\"icloud\", \"icloud+\", \"icloud plus\"],\n managementUrl: \"https://www.icloud.com/settings/storage\",\n auditDomains: [\"apple.com\", \"icloud.com\"],\n auditSubjectKeywords: [\"icloud\", \"your icloud storage\"],\n }),\n definePlaybook({\n key: \"google_one\",\n serviceName: \"Google One\",\n aliases: [\"google one\", \"googleone\"],\n managementUrl: \"https://one.google.com/storage/management\",\n auditDomains: [\"google.com\"],\n auditSubjectKeywords: [\"google one\", \"storage plan\"],\n }),\n definePlaybook({\n key: \"dropbox\",\n serviceName: \"Dropbox\",\n aliases: [\"dropbox\", \"dropbox plus\"],\n managementUrl: \"https://www.dropbox.com/account/plan\",\n auditDomains: [\"dropbox.com\"],\n auditSubjectKeywords: [\"dropbox\", \"your dropbox plan\"],\n }),\n definePlaybook({\n key: \"microsoft_365\",\n serviceName: \"Microsoft 365\",\n aliases: [\"microsoft 365\", \"office 365\", \"m365\"],\n managementUrl: \"https://account.microsoft.com/services/\",\n auditDomains: [\"microsoft.com\"],\n auditSubjectKeywords: [\"microsoft 365\", \"office 365\"],\n }),\n definePlaybook({\n key: \"adobe_creative_cloud\",\n serviceName: \"Adobe Creative Cloud\",\n aliases: [\n \"adobe\",\n \"adobe creative cloud\",\n \"creative cloud\",\n \"photoshop subscription\",\n ],\n managementUrl: \"https://account.adobe.com/plans\",\n auditDomains: [\"adobe.com\"],\n auditSubjectKeywords: [\"adobe\", \"creative cloud\"],\n chatOnlyMarkers: [\"chat with agent\"],\n }),\n definePlaybook({\n key: \"canva\",\n serviceName: \"Canva\",\n aliases: [\"canva\", \"canva pro\"],\n managementUrl: \"https://www.canva.com/account/subscription/\",\n auditDomains: [\"canva.com\"],\n auditSubjectKeywords: [\"canva\", \"your canva pro\"],\n }),\n definePlaybook({\n key: \"notion\",\n serviceName: \"Notion\",\n aliases: [\"notion\", \"notion plus\", \"notion personal pro\"],\n managementUrl: \"https://www.notion.so/my-plan\",\n auditDomains: [\"notion.so\"],\n auditSubjectKeywords: [\"notion\", \"your notion plan\"],\n }),\n definePlaybook({\n key: \"evernote\",\n serviceName: \"Evernote\",\n aliases: [\"evernote\", \"evernote premium\"],\n managementUrl: \"https://www.evernote.com/AccountSummary.action\",\n auditDomains: [\"evernote.com\"],\n auditSubjectKeywords: [\"evernote\"],\n }),\n definePlaybook({\n key: \"onepassword\",\n serviceName: \"1Password\",\n aliases: [\"1password\", \"one password\"],\n managementUrl: \"https://my.1password.com/billing\",\n auditDomains: [\"1password.com\"],\n auditSubjectKeywords: [\"1password\", \"your 1password membership\"],\n }),\n\n // ---- Gaming ------------------------------------------------------------\n definePlaybook({\n key: \"xbox_game_pass\",\n serviceName: \"Xbox Game Pass\",\n aliases: [\"xbox game pass\", \"game pass\", \"xbox live\"],\n managementUrl: \"https://account.microsoft.com/services/\",\n auditDomains: [\"microsoft.com\", \"xbox.com\"],\n auditSubjectKeywords: [\"xbox\", \"game pass\"],\n }),\n definePlaybook({\n key: \"playstation_plus\",\n serviceName: \"PlayStation Plus\",\n aliases: [\"ps plus\", \"playstation plus\", \"ps+\"],\n managementUrl:\n \"https://www.playstation.com/en-us/support/subscriptions/playstation-plus-cancel/\",\n auditDomains: [\"playstation.com\", \"sony.com\"],\n auditSubjectKeywords: [\"playstation plus\", \"ps plus\"],\n }),\n definePlaybook({\n key: \"nintendo_switch_online\",\n serviceName: \"Nintendo Switch Online\",\n aliases: [\"nintendo switch online\", \"nso\", \"nintendo online\"],\n managementUrl: \"https://accounts.nintendo.com/subscription/management\",\n auditDomains: [\"nintendo.com\"],\n auditSubjectKeywords: [\"nintendo switch online\", \"nso\"],\n }),\n definePlaybook({\n key: \"ea_play\",\n serviceName: \"EA Play\",\n aliases: [\"ea play\", \"ea access\", \"origin access\"],\n managementUrl: \"https://www.ea.com/ea-play/manage-subscription\",\n auditDomains: [\"ea.com\"],\n auditSubjectKeywords: [\"ea play\", \"ea access\"],\n }),\n\n // ---- AI / developer ----------------------------------------------------\n definePlaybook({\n key: \"chatgpt_plus\",\n serviceName: \"ChatGPT Plus\",\n aliases: [\n \"chatgpt plus\",\n \"chatgpt\",\n \"openai plus\",\n \"chatgpt subscription\",\n ],\n managementUrl: \"https://chatgpt.com/#settings/Subscription\",\n auditDomains: [\"openai.com\", \"chatgpt.com\"],\n auditSubjectKeywords: [\"chatgpt plus\", \"openai receipt\", \"your chatgpt\"],\n }),\n definePlaybook({\n key: \"claude_pro\",\n serviceName: \"Claude Pro\",\n aliases: [\"claude pro\", \"anthropic\", \"claude subscription\"],\n managementUrl: \"https://claude.ai/settings/billing\",\n auditDomains: [\"anthropic.com\", \"claude.ai\"],\n auditSubjectKeywords: [\"claude pro\", \"anthropic receipt\"],\n }),\n definePlaybook({\n key: \"github_copilot\",\n serviceName: \"GitHub Copilot\",\n aliases: [\"github copilot\", \"copilot\", \"github\"],\n managementUrl: \"https://github.com/settings/copilot\",\n auditDomains: [\"github.com\"],\n auditSubjectKeywords: [\"github copilot\", \"your copilot\"],\n }),\n definePlaybook({\n key: \"perplexity_pro\",\n serviceName: \"Perplexity Pro\",\n aliases: [\"perplexity\", \"perplexity pro\"],\n managementUrl: \"https://www.perplexity.ai/settings/account\",\n auditDomains: [\"perplexity.ai\"],\n auditSubjectKeywords: [\"perplexity\", \"your perplexity pro\"],\n }),\n\n // ---- Fitness / health --------------------------------------------------\n definePlaybook({\n key: \"peloton\",\n serviceName: \"Peloton\",\n aliases: [\"peloton\", \"peloton app\", \"peloton membership\"],\n managementUrl:\n \"https://members.onepeloton.com/preferences/account/subscription\",\n auditDomains: [\"onepeloton.com\"],\n auditSubjectKeywords: [\"peloton\", \"membership receipt\"],\n }),\n definePlaybook({\n key: \"apple_fitness_plus\",\n serviceName: \"Apple Fitness+\",\n aliases: [\"apple fitness+\", \"apple fitness plus\", \"fitness+\"],\n managementUrl: \"https://fitness.apple.com/account\",\n auditDomains: [\"apple.com\", \"itunes.com\"],\n auditSubjectKeywords: [\"apple fitness+\", \"fitness plus\"],\n }),\n definePlaybook({\n key: \"strava_premium\",\n serviceName: \"Strava Premium\",\n aliases: [\"strava\", \"strava premium\", \"strava subscription\"],\n managementUrl: \"https://www.strava.com/settings/billing\",\n auditDomains: [\"strava.com\"],\n auditSubjectKeywords: [\"strava\", \"your strava subscription\"],\n }),\n definePlaybook({\n key: \"myfitnesspal_premium\",\n serviceName: \"MyFitnessPal Premium\",\n aliases: [\"myfitnesspal\", \"mfp premium\", \"mfp\"],\n managementUrl: \"https://www.myfitnesspal.com/account/premium\",\n auditDomains: [\"myfitnesspal.com\"],\n auditSubjectKeywords: [\"myfitnesspal\", \"mfp premium\"],\n }),\n definePlaybook({\n key: \"calm\",\n serviceName: \"Calm\",\n aliases: [\"calm app\", \"calm subscription\"],\n managementUrl: \"https://app.www.calm.com/settings/subscription\",\n auditDomains: [\"calm.com\"],\n auditSubjectKeywords: [\"calm\", \"your calm subscription\"],\n }),\n definePlaybook({\n key: \"headspace\",\n serviceName: \"Headspace\",\n aliases: [\"headspace\"],\n managementUrl: \"https://www.headspace.com/subscription/details\",\n auditDomains: [\"headspace.com\"],\n auditSubjectKeywords: [\"headspace\", \"your headspace\"],\n }),\n definePlaybook({\n key: \"noom\",\n serviceName: \"Noom\",\n aliases: [\"noom\"],\n managementUrl: \"https://www.noom.com/myaccount\",\n auditDomains: [\"noom.com\"],\n auditSubjectKeywords: [\"noom\"],\n chatOnlyMarkers: [\"noom coach\", \"message to cancel\"],\n }),\n\n // ---- Meal / food -------------------------------------------------------\n definePlaybook({\n key: \"hellofresh\",\n serviceName: \"HelloFresh\",\n aliases: [\"hellofresh\", \"hello fresh\"],\n managementUrl: \"https://www.hellofresh.com/account-settings/subscription\",\n auditDomains: [\"hellofresh.com\"],\n auditSubjectKeywords: [\"hellofresh\", \"your hellofresh order\"],\n }),\n definePlaybook({\n key: \"blue_apron\",\n serviceName: \"Blue Apron\",\n aliases: [\"blue apron\"],\n managementUrl: \"https://www.blueapron.com/users/edit\",\n auditDomains: [\"blueapron.com\"],\n auditSubjectKeywords: [\"blue apron\"],\n }),\n definePlaybook({\n key: \"factor\",\n serviceName: \"Factor\",\n aliases: [\"factor\", \"factor 75\"],\n managementUrl: \"https://www.factor75.com/account/subscription\",\n auditDomains: [\"factor75.com\", \"factormeals.com\"],\n auditSubjectKeywords: [\"factor\", \"your factor order\"],\n }),\n definePlaybook({\n key: \"doordash_dashpass\",\n serviceName: \"DoorDash DashPass\",\n aliases: [\"doordash\", \"dashpass\"],\n managementUrl: \"https://www.doordash.com/dashpass/manage\",\n auditDomains: [\"doordash.com\"],\n auditSubjectKeywords: [\"doordash\", \"dashpass\"],\n }),\n definePlaybook({\n key: \"uber_one\",\n serviceName: \"Uber One\",\n aliases: [\"uber one\", \"uber eats pass\"],\n managementUrl: \"https://www.uber.com/go/uber-one-manage\",\n auditDomains: [\"uber.com\"],\n auditSubjectKeywords: [\"uber one\", \"uber eats pass\"],\n }),\n definePlaybook({\n key: \"instacart_plus\",\n serviceName: \"Instacart+\",\n aliases: [\"instacart\", \"instacart plus\", \"instacart+\"],\n managementUrl: \"https://www.instacart.com/store/account/instacart-plus\",\n auditDomains: [\"instacart.com\"],\n auditSubjectKeywords: [\"instacart+\", \"instacart plus\"],\n }),\n definePlaybook({\n key: \"grubhub_plus\",\n serviceName: \"Grubhub+\",\n aliases: [\"grubhub\", \"grubhub+\", \"grubhub plus\"],\n managementUrl: \"https://www.grubhub.com/grubhub-plus-membership\",\n auditDomains: [\"grubhub.com\"],\n auditSubjectKeywords: [\"grubhub+\", \"grubhub plus\"],\n }),\n\n // ---- Other consumer ----------------------------------------------------\n definePlaybook({\n key: \"audible\",\n serviceName: \"Audible\",\n aliases: [\n \"audible\",\n \"audible membership\",\n \"audible plus\",\n \"audible premium plus\",\n ],\n managementUrl: \"https://www.audible.com/account/membership-details\",\n auditDomains: [\"audible.com\", \"amazon.com\"],\n auditSubjectKeywords: [\"audible\", \"audible membership\"],\n }),\n definePlaybook({\n key: \"kindle_unlimited\",\n serviceName: \"Kindle Unlimited\",\n aliases: [\"kindle unlimited\", \"ku\"],\n managementUrl: \"https://www.amazon.com/kindleunlimited/manage\",\n auditDomains: [\"amazon.com\"],\n auditSubjectKeywords: [\"kindle unlimited\"],\n }),\n definePlaybook({\n key: \"linkedin_premium\",\n serviceName: \"LinkedIn Premium\",\n aliases: [\"linkedin premium\", \"linkedin\"],\n managementUrl: \"https://www.linkedin.com/premium/manage/\",\n auditDomains: [\"linkedin.com\"],\n auditSubjectKeywords: [\"linkedin premium\", \"your linkedin premium\"],\n }),\n definePlaybook({\n key: \"duolingo_plus\",\n serviceName: \"Duolingo Super\",\n aliases: [\"duolingo\", \"duolingo plus\", \"duolingo super\"],\n managementUrl: \"https://www.duolingo.com/settings/super\",\n auditDomains: [\"duolingo.com\"],\n auditSubjectKeywords: [\"duolingo\"],\n }),\n definePlaybook({\n key: \"grammarly_premium\",\n serviceName: \"Grammarly Premium\",\n aliases: [\"grammarly\", \"grammarly premium\"],\n managementUrl: \"https://account.grammarly.com/subscription\",\n auditDomains: [\"grammarly.com\"],\n auditSubjectKeywords: [\"grammarly\", \"your grammarly subscription\"],\n }),\n definePlaybook({\n key: \"tinder\",\n serviceName: \"Tinder\",\n aliases: [\"tinder\", \"tinder gold\", \"tinder plus\"],\n managementUrl: \"https://tinder.com/app/settings\",\n auditDomains: [\"tinder.com\"],\n auditSubjectKeywords: [\"tinder\", \"tinder gold\", \"tinder plus\"],\n }),\n definePlaybook({\n key: \"bumble\",\n serviceName: \"Bumble\",\n aliases: [\"bumble\", \"bumble premium\", \"bumble boost\"],\n managementUrl: \"https://bumble.com/app/settings\",\n auditDomains: [\"bumble.com\"],\n auditSubjectKeywords: [\"bumble\"],\n }),\n definePlaybook({\n key: \"hinge\",\n serviceName: \"Hinge\",\n aliases: [\"hinge\", \"hinge preferred\"],\n managementUrl: \"https://hinge.co/subscription\",\n auditDomains: [\"hinge.co\"],\n auditSubjectKeywords: [\"hinge\"],\n }),\n definePlaybook({\n key: \"masterclass\",\n serviceName: \"MasterClass\",\n aliases: [\"masterclass\"],\n managementUrl: \"https://www.masterclass.com/account\",\n auditDomains: [\"masterclass.com\"],\n auditSubjectKeywords: [\"masterclass\"],\n }),\n definePlaybook({\n key: \"skillshare\",\n serviceName: \"Skillshare\",\n aliases: [\"skillshare\"],\n managementUrl: \"https://www.skillshare.com/settings/payments\",\n auditDomains: [\"skillshare.com\"],\n auditSubjectKeywords: [\"skillshare\"],\n }),\n definePlaybook({\n key: \"coursera_plus\",\n serviceName: \"Coursera Plus\",\n aliases: [\"coursera\", \"coursera plus\"],\n managementUrl: \"https://www.coursera.org/account-settings\",\n auditDomains: [\"coursera.org\"],\n auditSubjectKeywords: [\"coursera plus\", \"your coursera\"],\n }),\n ];\n\nfunction normalizeName(value: string): string {\n return value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, \" \")\n .trim();\n}\n\nexport function listLifeOpsSubscriptionPlaybooks(): readonly LifeOpsSubscriptionPlaybook[] {\n return LIFEOPS_SUBSCRIPTION_PLAYBOOKS;\n}\n\nexport function findLifeOpsSubscriptionPlaybook(\n serviceNameOrSlug: string | null | undefined,\n): LifeOpsSubscriptionPlaybook | null {\n if (!serviceNameOrSlug) {\n return null;\n }\n const normalized = normalizeName(serviceNameOrSlug);\n for (const playbook of LIFEOPS_SUBSCRIPTION_PLAYBOOKS) {\n if (normalizeName(playbook.key) === normalized) {\n return playbook;\n }\n if (normalizeName(playbook.serviceName) === normalized) {\n return playbook;\n }\n if (playbook.aliases.some((alias) => normalizeName(alias) === normalized)) {\n return playbook;\n }\n if (\n normalized.includes(normalizeName(playbook.key)) ||\n normalized.includes(normalizeName(playbook.serviceName)) ||\n playbook.aliases.some((alias) =>\n normalized.includes(normalizeName(alias)),\n )\n ) {\n return playbook;\n }\n }\n return null;\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
export type LifeOpsSubscriptionAuditStatus = "completed" | "failed";
|
|
2
|
+
export type LifeOpsSubscriptionSource = "gmail" | "manual";
|
|
3
|
+
export type LifeOpsSubscriptionState = "active" | "canceled" | "uncertain";
|
|
4
|
+
export type LifeOpsSubscriptionCadence = "monthly" | "annual" | "unknown";
|
|
5
|
+
export type LifeOpsSubscriptionExecutor = "user_browser" | "agent_browser" | "desktop_native";
|
|
6
|
+
export type LifeOpsSubscriptionCancellationStatus = "draft" | "awaiting_confirmation" | "running" | "completed" | "already_canceled" | "needs_login" | "needs_mfa" | "needs_user_choice" | "retention_offer" | "phone_only" | "chat_only" | "unsupported_surface" | "blocked" | "failed";
|
|
7
|
+
export interface LifeOpsSubscriptionAudit {
|
|
8
|
+
id: string;
|
|
9
|
+
agentId: string;
|
|
10
|
+
source: LifeOpsSubscriptionSource;
|
|
11
|
+
queryWindowDays: number;
|
|
12
|
+
status: LifeOpsSubscriptionAuditStatus;
|
|
13
|
+
totalCandidates: number;
|
|
14
|
+
activeCandidates: number;
|
|
15
|
+
canceledCandidates: number;
|
|
16
|
+
uncertainCandidates: number;
|
|
17
|
+
summary: string;
|
|
18
|
+
metadata: Record<string, unknown>;
|
|
19
|
+
createdAt: string;
|
|
20
|
+
updatedAt: string;
|
|
21
|
+
}
|
|
22
|
+
export interface LifeOpsSubscriptionCandidate {
|
|
23
|
+
id: string;
|
|
24
|
+
agentId: string;
|
|
25
|
+
auditId: string;
|
|
26
|
+
serviceSlug: string;
|
|
27
|
+
serviceName: string;
|
|
28
|
+
provider: string;
|
|
29
|
+
cadence: LifeOpsSubscriptionCadence;
|
|
30
|
+
state: LifeOpsSubscriptionState;
|
|
31
|
+
confidence: number;
|
|
32
|
+
annualCostEstimateUsd: number | null;
|
|
33
|
+
managementUrl: string | null;
|
|
34
|
+
latestEvidenceAt: string | null;
|
|
35
|
+
evidenceJson: Array<Record<string, unknown>>;
|
|
36
|
+
metadata: Record<string, unknown>;
|
|
37
|
+
createdAt: string;
|
|
38
|
+
updatedAt: string;
|
|
39
|
+
}
|
|
40
|
+
export interface LifeOpsSubscriptionCancellation {
|
|
41
|
+
id: string;
|
|
42
|
+
agentId: string;
|
|
43
|
+
auditId: string | null;
|
|
44
|
+
candidateId: string | null;
|
|
45
|
+
serviceSlug: string;
|
|
46
|
+
serviceName: string;
|
|
47
|
+
executor: LifeOpsSubscriptionExecutor;
|
|
48
|
+
status: LifeOpsSubscriptionCancellationStatus;
|
|
49
|
+
confirmed: boolean;
|
|
50
|
+
currentStep: string | null;
|
|
51
|
+
browserSessionId: string | null;
|
|
52
|
+
evidenceSummary: string | null;
|
|
53
|
+
artifactCount: number;
|
|
54
|
+
managementUrl: string | null;
|
|
55
|
+
error: string | null;
|
|
56
|
+
metadata: Record<string, unknown>;
|
|
57
|
+
createdAt: string;
|
|
58
|
+
updatedAt: string;
|
|
59
|
+
finishedAt: string | null;
|
|
60
|
+
}
|
|
61
|
+
export interface LifeOpsSubscriptionAuditSummary {
|
|
62
|
+
audit: LifeOpsSubscriptionAudit;
|
|
63
|
+
candidates: LifeOpsSubscriptionCandidate[];
|
|
64
|
+
}
|
|
65
|
+
export interface LifeOpsSubscriptionCancellationSummary {
|
|
66
|
+
cancellation: LifeOpsSubscriptionCancellation;
|
|
67
|
+
candidate: LifeOpsSubscriptionCandidate | null;
|
|
68
|
+
}
|
|
69
|
+
export interface LifeOpsSubscriptionDiscoveryRequest {
|
|
70
|
+
queryWindowDays?: number;
|
|
71
|
+
serviceQuery?: string | null;
|
|
72
|
+
}
|
|
73
|
+
export interface LifeOpsSubscriptionCancellationRequest {
|
|
74
|
+
candidateId?: string | null;
|
|
75
|
+
serviceName?: string | null;
|
|
76
|
+
serviceSlug?: string | null;
|
|
77
|
+
executor?: LifeOpsSubscriptionExecutor | null;
|
|
78
|
+
confirmed?: boolean;
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=subscriptions-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"subscriptions-types.d.ts","sourceRoot":"","sources":["../src/subscriptions-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
//# sourceMappingURL=subscriptions-types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AES-256-GCM encryption helpers for LifeOps connector tokens at rest.
|
|
3
|
+
*
|
|
4
|
+
* Connector tokens are encrypted at rest with AES-256-GCM using a symmetric
|
|
5
|
+
* key sourced from one of:
|
|
6
|
+
*
|
|
7
|
+
* 1. `ELIZA_TOKEN_ENCRYPTION_KEY` env var (32 raw bytes, base64- or
|
|
8
|
+
* hex-encoded). Preferred — operators who manage their own secret
|
|
9
|
+
* management can inject the key directly.
|
|
10
|
+
* 2. `<credentials-dir>/.encryption-key` file (mode 0600). Generated lazily
|
|
11
|
+
* the first time we need to write a token and no env var is configured.
|
|
12
|
+
* The agent reuses this key on subsequent boots.
|
|
13
|
+
*
|
|
14
|
+
* The on-disk format is intentionally minimal: encrypted blobs are JSON
|
|
15
|
+
* objects with a top-level `__enc` discriminator.
|
|
16
|
+
*/
|
|
17
|
+
declare const ENVELOPE_VERSION = 1;
|
|
18
|
+
declare const ENVELOPE_DISCRIMINATOR: "__enc";
|
|
19
|
+
export interface EncryptedTokenEnvelope {
|
|
20
|
+
readonly [ENVELOPE_DISCRIMINATOR]: "aes-256-gcm";
|
|
21
|
+
readonly v: typeof ENVELOPE_VERSION;
|
|
22
|
+
readonly iv: string;
|
|
23
|
+
readonly tag: string;
|
|
24
|
+
readonly ct: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Resolve the symmetric key for token encryption.
|
|
28
|
+
*
|
|
29
|
+
* Resolution order: env var (`ELIZA_TOKEN_ENCRYPTION_KEY`) → file at
|
|
30
|
+
* `<credentialsDir>/.encryption-key`. The file is created (with mode 0600)
|
|
31
|
+
* lazily on first call so existing deployments keep working without an env
|
|
32
|
+
* var.
|
|
33
|
+
*/
|
|
34
|
+
export declare function resolveTokenEncryptionKey(credentialsDir: string, env?: NodeJS.ProcessEnv): Buffer;
|
|
35
|
+
export declare function encryptTokenPayload(plaintextJson: string, key: Buffer): EncryptedTokenEnvelope;
|
|
36
|
+
export declare function decryptTokenEnvelope(envelope: EncryptedTokenEnvelope, key: Buffer): string;
|
|
37
|
+
/**
|
|
38
|
+
* Returns true when the parsed JSON value looks like an encrypted envelope.
|
|
39
|
+
*/
|
|
40
|
+
export declare function isEncryptedTokenEnvelope(value: unknown): value is EncryptedTokenEnvelope;
|
|
41
|
+
export {};
|
|
42
|
+
//# sourceMappingURL=token-encryption.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"token-encryption.d.ts","sourceRoot":"","sources":["../src/token-encryption.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAWH,QAAA,MAAM,gBAAgB,IAAI,CAAC;AAC3B,QAAA,MAAM,sBAAsB,EAAG,OAAgB,CAAC;AAEhD,MAAM,WAAW,sBAAsB;IACrC,QAAQ,CAAC,CAAC,sBAAsB,CAAC,EAAE,aAAa,CAAC;IACjD,QAAQ,CAAC,CAAC,EAAE,OAAO,gBAAgB,CAAC;IACpC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;CACrB;AAiCD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CACvC,cAAc,EAAE,MAAM,EACtB,GAAG,GAAE,MAAM,CAAC,UAAwB,GACnC,MAAM,CAMR;AAED,wBAAgB,mBAAmB,CACjC,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,MAAM,GACV,sBAAsB,CAuBxB;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,sBAAsB,EAChC,GAAG,EAAE,MAAM,GACV,MAAM,CAiBR;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,sBAAsB,CAMjC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import crypto from "node:crypto";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
const KEY_ENV_VAR = "ELIZA_TOKEN_ENCRYPTION_KEY";
|
|
5
|
+
const KEY_FILENAME = ".encryption-key";
|
|
6
|
+
const KEY_BYTES = 32;
|
|
7
|
+
const IV_BYTES = 12;
|
|
8
|
+
const AUTH_TAG_BYTES = 16;
|
|
9
|
+
const ENVELOPE_VERSION = 1;
|
|
10
|
+
const ENVELOPE_DISCRIMINATOR = "__enc";
|
|
11
|
+
function decodeKeyMaterial(raw) {
|
|
12
|
+
const trimmed = raw.trim();
|
|
13
|
+
if (/^[0-9a-fA-F]+$/.test(trimmed) && trimmed.length === KEY_BYTES * 2) {
|
|
14
|
+
return Buffer.from(trimmed, "hex");
|
|
15
|
+
}
|
|
16
|
+
const buf = Buffer.from(trimmed, "base64");
|
|
17
|
+
if (buf.length === KEY_BYTES) {
|
|
18
|
+
return buf;
|
|
19
|
+
}
|
|
20
|
+
throw new Error(
|
|
21
|
+
`${KEY_ENV_VAR} must decode to exactly ${KEY_BYTES} bytes (got ${buf.length})`
|
|
22
|
+
);
|
|
23
|
+
}
|
|
24
|
+
function loadOrCreateKeyFile(credentialsDir) {
|
|
25
|
+
const filePath = path.join(credentialsDir, KEY_FILENAME);
|
|
26
|
+
if (fs.existsSync(filePath)) {
|
|
27
|
+
const raw = fs.readFileSync(filePath, "utf8");
|
|
28
|
+
return decodeKeyMaterial(raw);
|
|
29
|
+
}
|
|
30
|
+
fs.mkdirSync(credentialsDir, { recursive: true, mode: 448 });
|
|
31
|
+
const key = crypto.randomBytes(KEY_BYTES);
|
|
32
|
+
fs.writeFileSync(filePath, key.toString("base64"), {
|
|
33
|
+
encoding: "utf8",
|
|
34
|
+
mode: 384
|
|
35
|
+
});
|
|
36
|
+
return key;
|
|
37
|
+
}
|
|
38
|
+
function resolveTokenEncryptionKey(credentialsDir, env = process.env) {
|
|
39
|
+
const fromEnv = env[KEY_ENV_VAR]?.trim();
|
|
40
|
+
if (fromEnv) {
|
|
41
|
+
return decodeKeyMaterial(fromEnv);
|
|
42
|
+
}
|
|
43
|
+
return loadOrCreateKeyFile(credentialsDir);
|
|
44
|
+
}
|
|
45
|
+
function encryptTokenPayload(plaintextJson, key) {
|
|
46
|
+
if (key.length !== KEY_BYTES) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
`Token encryption key must be ${KEY_BYTES} bytes (got ${key.length})`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
const iv = crypto.randomBytes(IV_BYTES);
|
|
52
|
+
const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);
|
|
53
|
+
const ciphertext = Buffer.concat([
|
|
54
|
+
cipher.update(plaintextJson, "utf8"),
|
|
55
|
+
cipher.final()
|
|
56
|
+
]);
|
|
57
|
+
const authTag = cipher.getAuthTag();
|
|
58
|
+
if (authTag.length !== AUTH_TAG_BYTES) {
|
|
59
|
+
throw new Error("AES-GCM auth tag had unexpected length");
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
[ENVELOPE_DISCRIMINATOR]: "aes-256-gcm",
|
|
63
|
+
v: ENVELOPE_VERSION,
|
|
64
|
+
iv: iv.toString("base64"),
|
|
65
|
+
tag: authTag.toString("base64"),
|
|
66
|
+
ct: ciphertext.toString("base64")
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
function decryptTokenEnvelope(envelope, key) {
|
|
70
|
+
if (envelope[ENVELOPE_DISCRIMINATOR] !== "aes-256-gcm") {
|
|
71
|
+
throw new Error("Unsupported token envelope algorithm");
|
|
72
|
+
}
|
|
73
|
+
if (envelope.v !== ENVELOPE_VERSION) {
|
|
74
|
+
throw new Error(`Unsupported token envelope version: ${envelope.v}`);
|
|
75
|
+
}
|
|
76
|
+
const iv = Buffer.from(envelope.iv, "base64");
|
|
77
|
+
const tag = Buffer.from(envelope.tag, "base64");
|
|
78
|
+
const ciphertext = Buffer.from(envelope.ct, "base64");
|
|
79
|
+
const decipher = crypto.createDecipheriv("aes-256-gcm", key, iv);
|
|
80
|
+
decipher.setAuthTag(tag);
|
|
81
|
+
const plaintext = Buffer.concat([
|
|
82
|
+
decipher.update(ciphertext),
|
|
83
|
+
decipher.final()
|
|
84
|
+
]);
|
|
85
|
+
return plaintext.toString("utf8");
|
|
86
|
+
}
|
|
87
|
+
function isEncryptedTokenEnvelope(value) {
|
|
88
|
+
return typeof value === "object" && value !== null && value[ENVELOPE_DISCRIMINATOR] === "aes-256-gcm";
|
|
89
|
+
}
|
|
90
|
+
export {
|
|
91
|
+
decryptTokenEnvelope,
|
|
92
|
+
encryptTokenPayload,
|
|
93
|
+
isEncryptedTokenEnvelope,
|
|
94
|
+
resolveTokenEncryptionKey
|
|
95
|
+
};
|
|
96
|
+
//# sourceMappingURL=token-encryption.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/token-encryption.ts"],"sourcesContent":["/**\n * AES-256-GCM encryption helpers for LifeOps connector tokens at rest.\n *\n * Connector tokens are encrypted at rest with AES-256-GCM using a symmetric\n * key sourced from one of:\n *\n * 1. `ELIZA_TOKEN_ENCRYPTION_KEY` env var (32 raw bytes, base64- or\n * hex-encoded). Preferred — operators who manage their own secret\n * management can inject the key directly.\n * 2. `<credentials-dir>/.encryption-key` file (mode 0600). Generated lazily\n * the first time we need to write a token and no env var is configured.\n * The agent reuses this key on subsequent boots.\n *\n * The on-disk format is intentionally minimal: encrypted blobs are JSON\n * objects with a top-level `__enc` discriminator.\n */\n\nimport crypto from \"node:crypto\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\n\nconst KEY_ENV_VAR = \"ELIZA_TOKEN_ENCRYPTION_KEY\";\nconst KEY_FILENAME = \".encryption-key\";\nconst KEY_BYTES = 32; // AES-256\nconst IV_BYTES = 12; // GCM standard nonce length\nconst AUTH_TAG_BYTES = 16;\nconst ENVELOPE_VERSION = 1;\nconst ENVELOPE_DISCRIMINATOR = \"__enc\" as const;\n\nexport interface EncryptedTokenEnvelope {\n readonly [ENVELOPE_DISCRIMINATOR]: \"aes-256-gcm\";\n readonly v: typeof ENVELOPE_VERSION;\n readonly iv: string;\n readonly tag: string;\n readonly ct: string;\n}\n\nfunction decodeKeyMaterial(raw: string): Buffer {\n const trimmed = raw.trim();\n // Hex first (deterministic length check).\n if (/^[0-9a-fA-F]+$/.test(trimmed) && trimmed.length === KEY_BYTES * 2) {\n return Buffer.from(trimmed, \"hex\");\n }\n // Otherwise assume base64 / base64url.\n const buf = Buffer.from(trimmed, \"base64\");\n if (buf.length === KEY_BYTES) {\n return buf;\n }\n throw new Error(\n `${KEY_ENV_VAR} must decode to exactly ${KEY_BYTES} bytes (got ${buf.length})`,\n );\n}\n\nfunction loadOrCreateKeyFile(credentialsDir: string): Buffer {\n const filePath = path.join(credentialsDir, KEY_FILENAME);\n if (fs.existsSync(filePath)) {\n const raw = fs.readFileSync(filePath, \"utf8\");\n return decodeKeyMaterial(raw);\n }\n fs.mkdirSync(credentialsDir, { recursive: true, mode: 0o700 });\n const key = crypto.randomBytes(KEY_BYTES);\n fs.writeFileSync(filePath, key.toString(\"base64\"), {\n encoding: \"utf8\",\n mode: 0o600,\n });\n return key;\n}\n\n/**\n * Resolve the symmetric key for token encryption.\n *\n * Resolution order: env var (`ELIZA_TOKEN_ENCRYPTION_KEY`) → file at\n * `<credentialsDir>/.encryption-key`. The file is created (with mode 0600)\n * lazily on first call so existing deployments keep working without an env\n * var.\n */\nexport function resolveTokenEncryptionKey(\n credentialsDir: string,\n env: NodeJS.ProcessEnv = process.env,\n): Buffer {\n const fromEnv = env[KEY_ENV_VAR]?.trim();\n if (fromEnv) {\n return decodeKeyMaterial(fromEnv);\n }\n return loadOrCreateKeyFile(credentialsDir);\n}\n\nexport function encryptTokenPayload(\n plaintextJson: string,\n key: Buffer,\n): EncryptedTokenEnvelope {\n if (key.length !== KEY_BYTES) {\n throw new Error(\n `Token encryption key must be ${KEY_BYTES} bytes (got ${key.length})`,\n );\n }\n const iv = crypto.randomBytes(IV_BYTES);\n const cipher = crypto.createCipheriv(\"aes-256-gcm\", key, iv);\n const ciphertext = Buffer.concat([\n cipher.update(plaintextJson, \"utf8\"),\n cipher.final(),\n ]);\n const authTag = cipher.getAuthTag();\n if (authTag.length !== AUTH_TAG_BYTES) {\n throw new Error(\"AES-GCM auth tag had unexpected length\");\n }\n return {\n [ENVELOPE_DISCRIMINATOR]: \"aes-256-gcm\",\n v: ENVELOPE_VERSION,\n iv: iv.toString(\"base64\"),\n tag: authTag.toString(\"base64\"),\n ct: ciphertext.toString(\"base64\"),\n };\n}\n\nexport function decryptTokenEnvelope(\n envelope: EncryptedTokenEnvelope,\n key: Buffer,\n): string {\n if (envelope[ENVELOPE_DISCRIMINATOR] !== \"aes-256-gcm\") {\n throw new Error(\"Unsupported token envelope algorithm\");\n }\n if (envelope.v !== ENVELOPE_VERSION) {\n throw new Error(`Unsupported token envelope version: ${envelope.v}`);\n }\n const iv = Buffer.from(envelope.iv, \"base64\");\n const tag = Buffer.from(envelope.tag, \"base64\");\n const ciphertext = Buffer.from(envelope.ct, \"base64\");\n const decipher = crypto.createDecipheriv(\"aes-256-gcm\", key, iv);\n decipher.setAuthTag(tag);\n const plaintext = Buffer.concat([\n decipher.update(ciphertext),\n decipher.final(),\n ]);\n return plaintext.toString(\"utf8\");\n}\n\n/**\n * Returns true when the parsed JSON value looks like an encrypted envelope.\n */\nexport function isEncryptedTokenEnvelope(\n value: unknown,\n): value is EncryptedTokenEnvelope {\n return (\n typeof value === \"object\" &&\n value !== null &&\n (value as Record<string, unknown>)[ENVELOPE_DISCRIMINATOR] === \"aes-256-gcm\"\n );\n}\n"],"mappings":"AAiBA,OAAO,YAAY;AACnB,OAAO,QAAQ;AACf,OAAO,UAAU;AAEjB,MAAM,cAAc;AACpB,MAAM,eAAe;AACrB,MAAM,YAAY;AAClB,MAAM,WAAW;AACjB,MAAM,iBAAiB;AACvB,MAAM,mBAAmB;AACzB,MAAM,yBAAyB;AAU/B,SAAS,kBAAkB,KAAqB;AAC9C,QAAM,UAAU,IAAI,KAAK;AAEzB,MAAI,iBAAiB,KAAK,OAAO,KAAK,QAAQ,WAAW,YAAY,GAAG;AACtE,WAAO,OAAO,KAAK,SAAS,KAAK;AAAA,EACnC;AAEA,QAAM,MAAM,OAAO,KAAK,SAAS,QAAQ;AACzC,MAAI,IAAI,WAAW,WAAW;AAC5B,WAAO;AAAA,EACT;AACA,QAAM,IAAI;AAAA,IACR,GAAG,WAAW,2BAA2B,SAAS,eAAe,IAAI,MAAM;AAAA,EAC7E;AACF;AAEA,SAAS,oBAAoB,gBAAgC;AAC3D,QAAM,WAAW,KAAK,KAAK,gBAAgB,YAAY;AACvD,MAAI,GAAG,WAAW,QAAQ,GAAG;AAC3B,UAAM,MAAM,GAAG,aAAa,UAAU,MAAM;AAC5C,WAAO,kBAAkB,GAAG;AAAA,EAC9B;AACA,KAAG,UAAU,gBAAgB,EAAE,WAAW,MAAM,MAAM,IAAM,CAAC;AAC7D,QAAM,MAAM,OAAO,YAAY,SAAS;AACxC,KAAG,cAAc,UAAU,IAAI,SAAS,QAAQ,GAAG;AAAA,IACjD,UAAU;AAAA,IACV,MAAM;AAAA,EACR,CAAC;AACD,SAAO;AACT;AAUO,SAAS,0BACd,gBACA,MAAyB,QAAQ,KACzB;AACR,QAAM,UAAU,IAAI,WAAW,GAAG,KAAK;AACvC,MAAI,SAAS;AACX,WAAO,kBAAkB,OAAO;AAAA,EAClC;AACA,SAAO,oBAAoB,cAAc;AAC3C;AAEO,SAAS,oBACd,eACA,KACwB;AACxB,MAAI,IAAI,WAAW,WAAW;AAC5B,UAAM,IAAI;AAAA,MACR,gCAAgC,SAAS,eAAe,IAAI,MAAM;AAAA,IACpE;AAAA,EACF;AACA,QAAM,KAAK,OAAO,YAAY,QAAQ;AACtC,QAAM,SAAS,OAAO,eAAe,eAAe,KAAK,EAAE;AAC3D,QAAM,aAAa,OAAO,OAAO;AAAA,IAC/B,OAAO,OAAO,eAAe,MAAM;AAAA,IACnC,OAAO,MAAM;AAAA,EACf,CAAC;AACD,QAAM,UAAU,OAAO,WAAW;AAClC,MAAI,QAAQ,WAAW,gBAAgB;AACrC,UAAM,IAAI,MAAM,wCAAwC;AAAA,EAC1D;AACA,SAAO;AAAA,IACL,CAAC,sBAAsB,GAAG;AAAA,IAC1B,GAAG;AAAA,IACH,IAAI,GAAG,SAAS,QAAQ;AAAA,IACxB,KAAK,QAAQ,SAAS,QAAQ;AAAA,IAC9B,IAAI,WAAW,SAAS,QAAQ;AAAA,EAClC;AACF;AAEO,SAAS,qBACd,UACA,KACQ;AACR,MAAI,SAAS,sBAAsB,MAAM,eAAe;AACtD,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AACA,MAAI,SAAS,MAAM,kBAAkB;AACnC,UAAM,IAAI,MAAM,uCAAuC,SAAS,CAAC,EAAE;AAAA,EACrE;AACA,QAAM,KAAK,OAAO,KAAK,SAAS,IAAI,QAAQ;AAC5C,QAAM,MAAM,OAAO,KAAK,SAAS,KAAK,QAAQ;AAC9C,QAAM,aAAa,OAAO,KAAK,SAAS,IAAI,QAAQ;AACpD,QAAM,WAAW,OAAO,iBAAiB,eAAe,KAAK,EAAE;AAC/D,WAAS,WAAW,GAAG;AACvB,QAAM,YAAY,OAAO,OAAO;AAAA,IAC9B,SAAS,OAAO,UAAU;AAAA,IAC1B,SAAS,MAAM;AAAA,EACjB,CAAC;AACD,SAAO,UAAU,SAAS,MAAM;AAClC;AAKO,SAAS,yBACd,OACiC;AACjC,SACE,OAAO,UAAU,YACjB,UAAU,QACT,MAAkC,sBAAsB,MAAM;AAEnE;","names":[]}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared type definitions for the @elizaos/plugin-finances surface.
|
|
3
|
+
*
|
|
4
|
+
* Kept intentionally minimal during the LifeOps decomposition scaffold —
|
|
5
|
+
* the real types will be migrated from
|
|
6
|
+
* `plugins/plugin-personal-assistant/src/actions/owner-surfaces.ts` (ownerFinancesAction)
|
|
7
|
+
* and `plugins/plugin-personal-assistant/src/actions/payments.ts` /
|
|
8
|
+
* `payments-recurring.ts` in a follow-up phase.
|
|
9
|
+
*/
|
|
10
|
+
/** Currency code in ISO 4217 form (e.g. "USD"). */
|
|
11
|
+
export type CurrencyCode = string;
|
|
12
|
+
/** Status values a transaction row can hold. */
|
|
13
|
+
export declare const TRANSACTION_STATUSES: readonly ["pending", "posted", "void", "refunded"];
|
|
14
|
+
export type TransactionStatus = (typeof TRANSACTION_STATUSES)[number];
|
|
15
|
+
/** Cadence options for a recurring charge. */
|
|
16
|
+
export declare const RECURRING_CADENCES: readonly ["daily", "weekly", "monthly", "quarterly", "yearly"];
|
|
17
|
+
export type RecurringCadence = (typeof RECURRING_CADENCES)[number];
|
|
18
|
+
/** DTO surfaced to the FinancesView for one transaction row. */
|
|
19
|
+
export interface FinanceTransactionDTO {
|
|
20
|
+
id: string;
|
|
21
|
+
occurredAt: string;
|
|
22
|
+
amountMinor: number;
|
|
23
|
+
currency: CurrencyCode;
|
|
24
|
+
description: string;
|
|
25
|
+
category: string | null;
|
|
26
|
+
merchant: string | null;
|
|
27
|
+
status: TransactionStatus;
|
|
28
|
+
source: string | null;
|
|
29
|
+
}
|
|
30
|
+
/** DTO surfaced to the FinancesView for one recurring-charge row. */
|
|
31
|
+
export interface RecurringChargeDTO {
|
|
32
|
+
id: string;
|
|
33
|
+
label: string;
|
|
34
|
+
amountMinor: number;
|
|
35
|
+
currency: CurrencyCode;
|
|
36
|
+
cadence: RecurringCadence;
|
|
37
|
+
nextChargeAt: string | null;
|
|
38
|
+
merchant: string | null;
|
|
39
|
+
active: boolean;
|
|
40
|
+
}
|
|
41
|
+
/** Aggregate balance summary shown at the top of the finances dashboard. */
|
|
42
|
+
export interface FinanceBalanceSummaryDTO {
|
|
43
|
+
netBalanceMinor: number;
|
|
44
|
+
currency: CurrencyCode;
|
|
45
|
+
monthlyIncomeMinor: number;
|
|
46
|
+
monthlyOutflowMinor: number;
|
|
47
|
+
asOf: string;
|
|
48
|
+
}
|
|
49
|
+
/** Props for the FinancesView React component (the dashboard surface). */
|
|
50
|
+
export interface FinancesViewProps {
|
|
51
|
+
balance?: FinanceBalanceSummaryDTO;
|
|
52
|
+
transactions?: FinanceTransactionDTO[];
|
|
53
|
+
recurring?: RecurringChargeDTO[];
|
|
54
|
+
}
|
|
55
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,mDAAmD;AACnD,MAAM,MAAM,YAAY,GAAG,MAAM,CAAC;AAElC,gDAAgD;AAChD,eAAO,MAAM,oBAAoB,oDAKvB,CAAC;AACX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEtE,8CAA8C;AAC9C,eAAO,MAAM,kBAAkB,gEAMrB,CAAC;AACX,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,kBAAkB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEnE,gEAAgE;AAChE,MAAM,WAAW,qBAAqB;IACpC,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED,qEAAqE;AACrE,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,YAAY,CAAC;IACvB,OAAO,EAAE,gBAAgB,CAAC;IAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,4EAA4E;AAC5E,MAAM,WAAW,wBAAwB;IACvC,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,YAAY,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,IAAI,EAAE,MAAM,CAAC;CACd;AAED,0EAA0E;AAC1E,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,wBAAwB,CAAC;IACnC,YAAY,CAAC,EAAE,qBAAqB,EAAE,CAAC;IACvC,SAAS,CAAC,EAAE,kBAAkB,EAAE,CAAC;CAClC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
const TRANSACTION_STATUSES = [
|
|
2
|
+
"pending",
|
|
3
|
+
"posted",
|
|
4
|
+
"void",
|
|
5
|
+
"refunded"
|
|
6
|
+
];
|
|
7
|
+
const RECURRING_CADENCES = [
|
|
8
|
+
"daily",
|
|
9
|
+
"weekly",
|
|
10
|
+
"monthly",
|
|
11
|
+
"quarterly",
|
|
12
|
+
"yearly"
|
|
13
|
+
];
|
|
14
|
+
export {
|
|
15
|
+
RECURRING_CADENCES,
|
|
16
|
+
TRANSACTION_STATUSES
|
|
17
|
+
};
|
|
18
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts"],"sourcesContent":["/**\n * Shared type definitions for the @elizaos/plugin-finances surface.\n *\n * Kept intentionally minimal during the LifeOps decomposition scaffold —\n * the real types will be migrated from\n * `plugins/plugin-personal-assistant/src/actions/owner-surfaces.ts` (ownerFinancesAction)\n * and `plugins/plugin-personal-assistant/src/actions/payments.ts` /\n * `payments-recurring.ts` in a follow-up phase.\n */\n\n/** Currency code in ISO 4217 form (e.g. \"USD\"). */\nexport type CurrencyCode = string;\n\n/** Status values a transaction row can hold. */\nexport const TRANSACTION_STATUSES = [\n \"pending\",\n \"posted\",\n \"void\",\n \"refunded\",\n] as const;\nexport type TransactionStatus = (typeof TRANSACTION_STATUSES)[number];\n\n/** Cadence options for a recurring charge. */\nexport const RECURRING_CADENCES = [\n \"daily\",\n \"weekly\",\n \"monthly\",\n \"quarterly\",\n \"yearly\",\n] as const;\nexport type RecurringCadence = (typeof RECURRING_CADENCES)[number];\n\n/** DTO surfaced to the FinancesView for one transaction row. */\nexport interface FinanceTransactionDTO {\n id: string;\n occurredAt: string;\n amountMinor: number;\n currency: CurrencyCode;\n description: string;\n category: string | null;\n merchant: string | null;\n status: TransactionStatus;\n source: string | null;\n}\n\n/** DTO surfaced to the FinancesView for one recurring-charge row. */\nexport interface RecurringChargeDTO {\n id: string;\n label: string;\n amountMinor: number;\n currency: CurrencyCode;\n cadence: RecurringCadence;\n nextChargeAt: string | null;\n merchant: string | null;\n active: boolean;\n}\n\n/** Aggregate balance summary shown at the top of the finances dashboard. */\nexport interface FinanceBalanceSummaryDTO {\n netBalanceMinor: number;\n currency: CurrencyCode;\n monthlyIncomeMinor: number;\n monthlyOutflowMinor: number;\n asOf: string;\n}\n\n/** Props for the FinancesView React component (the dashboard surface). */\nexport interface FinancesViewProps {\n balance?: FinanceBalanceSummaryDTO;\n transactions?: FinanceTransactionDTO[];\n recurring?: RecurringChargeDTO[];\n}\n"],"mappings":"AAcO,MAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIO,MAAM,qBAAqB;AAAA,EAChC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;","names":[]}
|