@oxygen-agent/cli 1.1010.650 → 1.1010.905
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/README.md +1 -1
- package/dist/auto-update.d.ts +129 -0
- package/dist/auto-update.js +392 -0
- package/dist/command-manifest.js +15 -1
- package/dist/credentials.d.ts +2 -0
- package/dist/credentials.js +6 -3
- package/dist/functions-commands.js +1 -1
- package/dist/http-client.js +28 -4
- package/dist/inbox-needs-reply-notice.d.ts +12 -0
- package/dist/inbox-needs-reply-notice.js +51 -0
- package/dist/index.js +756 -177
- package/dist/run-wait.d.ts +3 -1
- package/dist/run-wait.js +19 -5
- package/dist/skills.js +48 -22
- package/dist/streamed-file-import.d.ts +58 -0
- package/dist/streamed-file-import.js +115 -0
- package/dist/update.d.ts +29 -0
- package/dist/update.js +62 -16
- package/dist/workflow-plan-limit-notices.d.ts +8 -0
- package/dist/workflow-plan-limit-notices.js +28 -0
- package/node_modules/@oxygen/cli-ugc/dist/commands.js +3 -3
- package/node_modules/@oxygen/shared/dist/billing-anchors.d.ts +50 -2
- package/node_modules/@oxygen/shared/dist/billing-anchors.js +94 -2
- package/node_modules/@oxygen/shared/dist/billing.d.ts +247 -37
- package/node_modules/@oxygen/shared/dist/billing.js +418 -45
- package/node_modules/@oxygen/shared/dist/capability-discovery.js +66 -6
- package/node_modules/@oxygen/shared/dist/copilot-skills.generated.d.ts +6 -6
- package/node_modules/@oxygen/shared/dist/copilot-skills.generated.js +6 -6
- package/node_modules/@oxygen/shared/dist/cost-estimate-view.d.ts +50 -0
- package/node_modules/@oxygen/shared/dist/cost-estimate-view.js +90 -0
- package/node_modules/@oxygen/shared/dist/cost-estimate.d.ts +167 -0
- package/node_modules/@oxygen/shared/dist/cost-estimate.js +361 -0
- package/node_modules/@oxygen/shared/dist/credit-gate.d.ts +26 -0
- package/node_modules/@oxygen/shared/dist/credit-gate.js +65 -0
- package/node_modules/@oxygen/shared/dist/email-deliverability-policy.d.ts +51 -0
- package/node_modules/@oxygen/shared/dist/email-deliverability-policy.js +101 -0
- package/node_modules/@oxygen/shared/dist/email-hard-bounce.d.ts +27 -0
- package/node_modules/@oxygen/shared/dist/email-hard-bounce.js +27 -0
- package/node_modules/@oxygen/shared/dist/error-redaction.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/error-redaction.js +1 -1
- package/node_modules/@oxygen/shared/dist/feature-gates.d.ts +10 -1
- package/node_modules/@oxygen/shared/dist/feature-gates.js +12 -1
- package/node_modules/@oxygen/shared/dist/file-import.d.ts +13 -1
- package/node_modules/@oxygen/shared/dist/file-import.js +33 -6
- package/node_modules/@oxygen/shared/dist/hosted-ai.d.ts +73 -3
- package/node_modules/@oxygen/shared/dist/hosted-ai.js +246 -24
- package/node_modules/@oxygen/shared/dist/import-limits.d.ts +25 -1
- package/node_modules/@oxygen/shared/dist/import-limits.js +35 -2
- package/node_modules/@oxygen/shared/dist/index.d.ts +4 -23
- package/node_modules/@oxygen/shared/dist/index.js +4 -43
- package/node_modules/@oxygen/shared/dist/linkedin-sequences.d.ts +114 -0
- package/node_modules/@oxygen/shared/dist/linkedin-sequences.js +150 -0
- package/node_modules/@oxygen/shared/dist/object-storage.d.ts +9 -0
- package/node_modules/@oxygen/shared/dist/object-storage.js +17 -0
- package/node_modules/@oxygen/shared/dist/operational-telemetry.d.ts +41 -0
- package/node_modules/@oxygen/shared/dist/operational-telemetry.js +55 -0
- package/node_modules/@oxygen/shared/dist/otlp-log-sink.js +19 -2
- package/node_modules/@oxygen/shared/dist/plan-band.d.ts +234 -0
- package/node_modules/@oxygen/shared/dist/plan-band.js +312 -0
- package/node_modules/@oxygen/shared/dist/plan-capabilities.d.ts +77 -7
- package/node_modules/@oxygen/shared/dist/plan-capabilities.js +87 -7
- package/node_modules/@oxygen/shared/dist/plan-limits-view.d.ts +219 -0
- package/node_modules/@oxygen/shared/dist/plan-limits-view.js +330 -0
- package/node_modules/@oxygen/shared/dist/plan-limits.d.ts +335 -126
- package/node_modules/@oxygen/shared/dist/plan-limits.js +277 -86
- package/node_modules/@oxygen/shared/dist/pricing-sheet.d.ts +158 -49
- package/node_modules/@oxygen/shared/dist/pricing-sheet.js +139 -41
- package/node_modules/@oxygen/shared/dist/pricing-snapshot.generated.d.ts +42 -23
- package/node_modules/@oxygen/shared/dist/pricing-snapshot.generated.js +56 -37
- package/node_modules/@oxygen/shared/dist/process-resource.d.ts +4 -0
- package/node_modules/@oxygen/shared/dist/process-resource.js +25 -0
- package/node_modules/@oxygen/shared/dist/provider-http-error.d.ts +10 -0
- package/node_modules/@oxygen/shared/dist/provider-http-error.js +27 -0
- package/node_modules/@oxygen/shared/dist/repricing.d.ts +257 -0
- package/node_modules/@oxygen/shared/dist/repricing.js +721 -0
- package/node_modules/@oxygen/shared/dist/semver.d.ts +21 -0
- package/node_modules/@oxygen/shared/dist/semver.js +41 -0
- package/node_modules/@oxygen/shared/dist/sending-limits.d.ts +30 -0
- package/node_modules/@oxygen/shared/dist/sending-limits.js +43 -0
- package/node_modules/@oxygen/shared/dist/sending-seats.d.ts +18 -15
- package/node_modules/@oxygen/shared/dist/sending-seats.js +22 -17
- package/node_modules/@oxygen/shared/dist/sequence-failures.js +4 -1
- package/node_modules/@oxygen/shared/dist/spend-safety.d.ts +57 -8
- package/node_modules/@oxygen/shared/dist/spend-safety.js +64 -11
- package/node_modules/@oxygen/shared/dist/stripe-price-catalog.d.ts +33 -1
- package/node_modules/@oxygen/shared/dist/stripe-price-catalog.js +71 -1
- package/node_modules/@oxygen/shared/dist/table-capacity.d.ts +68 -10
- package/node_modules/@oxygen/shared/dist/table-capacity.js +85 -4
- package/node_modules/@oxygen/shared/dist/telemetry-export-observer.d.ts +6 -0
- package/node_modules/@oxygen/shared/dist/telemetry-export-observer.js +13 -5
- package/node_modules/@oxygen/shared/dist/telemetry-resource.d.ts +40 -0
- package/node_modules/@oxygen/shared/dist/telemetry-resource.js +35 -0
- package/node_modules/@oxygen/shared/dist/telemetry.d.ts +9 -0
- package/node_modules/@oxygen/shared/dist/telemetry.js +41 -2
- package/node_modules/@oxygen/shared/dist/trace-context.d.ts +29 -0
- package/node_modules/@oxygen/shared/dist/trace-context.js +88 -0
- package/node_modules/@oxygen/shared/dist/ugc.d.ts +15 -0
- package/node_modules/@oxygen/shared/dist/ugc.js +29 -0
- package/node_modules/@oxygen/shared/dist/version.d.ts +1 -3
- package/node_modules/@oxygen/shared/dist/version.generated.d.ts +1 -1
- package/node_modules/@oxygen/shared/dist/version.generated.js +1 -1
- package/node_modules/@oxygen/shared/dist/version.js +14 -27
- package/node_modules/@oxygen/shared/dist/workspace-file-storage.d.ts +5 -0
- package/node_modules/@oxygen/shared/dist/workspace-file-storage.js +5 -0
- package/node_modules/@oxygen/workflows/dist/graph/manifest-schema.d.ts +3 -3
- package/node_modules/@oxygen/workflows/dist/graph/types.d.ts +15 -1
- package/node_modules/@oxygen/workflows/dist/graph/types.js +15 -1
- package/node_modules/@oxygen/workflows/dist/index.d.ts +45 -0
- package/node_modules/@oxygen/workflows/dist/index.js +152 -2
- package/node_modules/@oxygen/workflows/dist/usage-estimate.d.ts +10 -1
- package/node_modules/@oxygen/workflows/dist/usage-estimate.js +33 -29
- package/package.json +1 -1
- package/node_modules/@oxygen/shared/dist/email-warmup-readiness.d.ts +0 -64
- package/node_modules/@oxygen/shared/dist/email-warmup-readiness.js +0 -90
|
@@ -4,30 +4,33 @@ export declare const PRICE_SHEET_VERIFIED = "2026-07";
|
|
|
4
4
|
export declare const CREDITS_PER_USD = 100;
|
|
5
5
|
/** The divisor in the markup formula; exact inverse of CREDITS_PER_USD. */
|
|
6
6
|
export declare const CREDIT_USD_VALUE = 0.01;
|
|
7
|
-
/**
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
/**
|
|
8
|
+
* On-demand top-up after the 2026-09 repricing, in USD cents per 100 credits.
|
|
9
|
+
* Never read directly to sell credits: creditTopupUsdCentsPer100() in billing.ts
|
|
10
|
+
* holds the previous rate until OXYGEN_REPRICING_2026_09_EFFECTIVE_AT passes.
|
|
11
|
+
*/
|
|
12
|
+
export declare const TOPUP_USD_CENTS_PER_100_CREDITS = 130;
|
|
13
|
+
/** Face value of a subscription credit, cheaper than any top-up; the $499+ plans' volume bonus lowers the effective rate further. */
|
|
12
14
|
export declare const SUBSCRIPTION_USD_PER_100 = 1;
|
|
13
|
-
export declare const MANAGED_INBOX_MARKUP = 1.25;
|
|
14
|
-
export declare const MANAGED_DOMAIN_MARKUP = 1.25;
|
|
15
|
-
export declare const VOICE_MARKUP = 5;
|
|
16
15
|
/** Applied to actual provider inference cost at settle time. */
|
|
17
16
|
export declare const COPILOT_CREDIT_MARKUP_MULTIPLIER = 5;
|
|
18
|
-
export declare const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH =
|
|
19
|
-
export declare const WHATSAPP_ACCOUNT_CREDITS_PER_MONTH =
|
|
17
|
+
export declare const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH = 3400;
|
|
18
|
+
export declare const WHATSAPP_ACCOUNT_CREDITS_PER_MONTH = 3000;
|
|
19
|
+
export declare const X_ACCOUNT_CREDITS_PER_MONTH = 1000;
|
|
20
20
|
export declare const EGRESS_IP_CREDITS_PER_MONTH = 2500;
|
|
21
21
|
export declare const SENDING_MAILBOX_CREDITS_PER_MONTH = 100;
|
|
22
|
-
export declare const MANAGED_INBOX_CREDITS_PER_MONTH =
|
|
23
|
-
export declare const MAILBOX_WARMUP_CREDITS_PER_MONTH =
|
|
24
|
-
export declare const DELIVERABILITY_SEAT_CREDITS_PER_MONTH =
|
|
22
|
+
export declare const MANAGED_INBOX_CREDITS_PER_MONTH = 400;
|
|
23
|
+
export declare const MAILBOX_WARMUP_CREDITS_PER_MONTH = 0;
|
|
24
|
+
export declare const DELIVERABILITY_SEAT_CREDITS_PER_MONTH = 135;
|
|
25
25
|
/** Included inbox-placement tests per subscribed inbox per cycle. */
|
|
26
26
|
export declare const DELIVERABILITY_INCLUDED_TESTS_PER_INBOX = 2;
|
|
27
27
|
/** A placement test beyond the included allowance. */
|
|
28
|
-
export declare const PLACEMENT_TEST_OVERAGE_CREDITS =
|
|
29
|
-
/**
|
|
30
|
-
|
|
28
|
+
export declare const PLACEMENT_TEST_OVERAGE_CREDITS = 66;
|
|
29
|
+
/**
|
|
30
|
+
* Representative, not billed: a .com at InboxKit's cost (1.0x), charged at purchase
|
|
31
|
+
* and again at each yearly renewal. The charged price is the vendor's live price.
|
|
32
|
+
*/
|
|
33
|
+
export declare const SENDING_DOMAIN_CREDITS_PER_YEAR_TYPICAL = 1250;
|
|
31
34
|
export declare const SENDING_SEAT_USD_CENTS: {
|
|
32
35
|
readonly linkedin: 3000;
|
|
33
36
|
readonly whatsapp: 3000;
|
|
@@ -35,13 +38,29 @@ export declare const SENDING_SEAT_USD_CENTS: {
|
|
|
35
38
|
readonly email_sender: 100;
|
|
36
39
|
};
|
|
37
40
|
export type SendingSeatKey = keyof typeof SENDING_SEAT_USD_CENTS;
|
|
38
|
-
export declare const
|
|
39
|
-
|
|
40
|
-
export declare const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
export declare const VOICE_NUMBER_CREDITS_PER_MONTH = 1000;
|
|
42
|
+
/** Per connected minute; answering-machine detection is included (repricing 2026-09, decision 7.3). */
|
|
43
|
+
export declare const VOICE_CREDITS_PER_MINUTE = 5;
|
|
44
|
+
/**
|
|
45
|
+
* Price of one workflow step after the 2026-09 repricing; row writes are free.
|
|
46
|
+
* Never read directly for billing: automationStepCredits() in billing.ts holds
|
|
47
|
+
* the previous price until OXYGEN_REPRICING_2026_09_EFFECTIVE_AT passes.
|
|
48
|
+
*/
|
|
49
|
+
export declare const AUTOMATION_ACTION_CREDITS = 0.05;
|
|
50
|
+
/**
|
|
51
|
+
* Platform fee on one provider call made with the customer's own API key
|
|
52
|
+
* (BYOK), after the 2026-09 repricing. Never read directly for billing:
|
|
53
|
+
* byokPlatformFeeCredits() in billing.ts holds 0 until
|
|
54
|
+
* OXYGEN_REPRICING_2026_09_EFFECTIVE_AT passes.
|
|
55
|
+
*/
|
|
56
|
+
export declare const BYOK_PLATFORM_FEE_CREDITS = 0.05;
|
|
57
|
+
/**
|
|
58
|
+
* Flat price of one LinkedIn URL found by the default LinkedIn-URL waterfall,
|
|
59
|
+
* after the 2026-09 repricing; a miss costs nothing. Never read directly for
|
|
60
|
+
* billing: linkedinUrlFoundCredits() in repricing.ts applies it only once
|
|
61
|
+
* OXYGEN_REPRICING_2026_09_EFFECTIVE_AT passes.
|
|
62
|
+
*/
|
|
63
|
+
export declare const LINKEDIN_URL_FOUND_CREDITS = 5;
|
|
45
64
|
/** Email, LinkedIn and WhatsApp sends are free; the pool pays for seats and inboxes. */
|
|
46
65
|
export declare const SEND_CREDITS = 0;
|
|
47
66
|
/** Every LinkedIn action is 0 under the pure seat model. */
|
|
@@ -19,32 +19,40 @@ export const PRICE_SHEET_VERIFIED = "2026-07";
|
|
|
19
19
|
export const CREDITS_PER_USD = 100;
|
|
20
20
|
/** The divisor in the markup formula; exact inverse of CREDITS_PER_USD. */
|
|
21
21
|
export const CREDIT_USD_VALUE = 0.01;
|
|
22
|
-
/**
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
22
|
+
/**
|
|
23
|
+
* On-demand top-up after the 2026-09 repricing, in USD cents per 100 credits.
|
|
24
|
+
* Never read directly to sell credits: creditTopupUsdCentsPer100() in billing.ts
|
|
25
|
+
* holds the previous rate until OXYGEN_REPRICING_2026_09_EFFECTIVE_AT passes.
|
|
26
|
+
*/
|
|
27
|
+
export const TOPUP_USD_CENTS_PER_100_CREDITS = 130;
|
|
28
|
+
/** Face value of a subscription credit, cheaper than any top-up; the $499+ plans' volume bonus lowers the effective rate further. */
|
|
27
29
|
export const SUBSCRIPTION_USD_PER_100 = 1;
|
|
28
30
|
// --- markups ----------------------------------------------------------------
|
|
29
|
-
export const MANAGED_INBOX_MARKUP = 1.25;
|
|
30
|
-
export const MANAGED_DOMAIN_MARKUP = 1.25;
|
|
31
|
-
export const VOICE_MARKUP = 5;
|
|
32
31
|
/** Applied to actual provider inference cost at settle time. */
|
|
33
32
|
export const COPILOT_CREDIT_MARKUP_MULTIPLIER = 5;
|
|
34
33
|
// --- seats and recurring charges --------------------------------------------
|
|
35
|
-
|
|
36
|
-
|
|
34
|
+
//
|
|
35
|
+
// The connected-account reservations (LinkedIn, WhatsApp, X, phone number) carry
|
|
36
|
+
// the 2026-09 repricing's NEW price. Until its effective-date switch the price in
|
|
37
|
+
// force is lower; a surface that shows or charges one resolves it with
|
|
38
|
+
// repricedChargeCredits (@oxygen/shared/repricing), never from this literal alone.
|
|
39
|
+
export const LINKEDIN_ACCOUNT_CREDITS_PER_MONTH = 3_400;
|
|
40
|
+
export const WHATSAPP_ACCOUNT_CREDITS_PER_MONTH = 3_000;
|
|
41
|
+
export const X_ACCOUNT_CREDITS_PER_MONTH = 1_000;
|
|
37
42
|
export const EGRESS_IP_CREDITS_PER_MONTH = 2_500;
|
|
38
43
|
export const SENDING_MAILBOX_CREDITS_PER_MONTH = 100;
|
|
39
|
-
export const MANAGED_INBOX_CREDITS_PER_MONTH =
|
|
40
|
-
export const MAILBOX_WARMUP_CREDITS_PER_MONTH =
|
|
41
|
-
export const DELIVERABILITY_SEAT_CREDITS_PER_MONTH =
|
|
44
|
+
export const MANAGED_INBOX_CREDITS_PER_MONTH = 400;
|
|
45
|
+
export const MAILBOX_WARMUP_CREDITS_PER_MONTH = 0;
|
|
46
|
+
export const DELIVERABILITY_SEAT_CREDITS_PER_MONTH = 135;
|
|
42
47
|
/** Included inbox-placement tests per subscribed inbox per cycle. */
|
|
43
48
|
export const DELIVERABILITY_INCLUDED_TESTS_PER_INBOX = 2;
|
|
44
49
|
/** A placement test beyond the included allowance. */
|
|
45
|
-
export const PLACEMENT_TEST_OVERAGE_CREDITS =
|
|
46
|
-
/**
|
|
47
|
-
|
|
50
|
+
export const PLACEMENT_TEST_OVERAGE_CREDITS = 66;
|
|
51
|
+
/**
|
|
52
|
+
* Representative, not billed: a .com at InboxKit's cost (1.0x), charged at purchase
|
|
53
|
+
* and again at each yearly renewal. The charged price is the vendor's live price.
|
|
54
|
+
*/
|
|
55
|
+
export const SENDING_DOMAIN_CREDITS_PER_YEAR_TYPICAL = 1_250;
|
|
48
56
|
// --- sending seats (USD, Stripe-billed) --------------------------------------
|
|
49
57
|
//
|
|
50
58
|
// The seat model (OXP-15). These are DOLLARS, not credits, and they do not
|
|
@@ -60,26 +68,37 @@ export const SENDING_SEAT_USD_CENTS = {
|
|
|
60
68
|
phone_number: 1_000,
|
|
61
69
|
email_sender: 100,
|
|
62
70
|
};
|
|
63
|
-
// --- email infrastructure
|
|
64
|
-
//
|
|
65
|
-
// Sold in dollars as real Stripe products, not credits. MANAGED_INBOX is ALL-IN:
|
|
66
|
-
// it already contains the sending seat and warm-up, so a customer never assembles
|
|
67
|
-
// a working mailbox out of parts and can never end up holding a mailbox with no
|
|
68
|
-
// seat to send from. A customer bringing their OWN mailbox pays the $1
|
|
69
|
-
// email_sender seat instead.
|
|
71
|
+
// --- email infrastructure ---------------------------------------------------
|
|
70
72
|
//
|
|
71
|
-
//
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
|
|
75
|
-
export const SENDING_DOMAIN_USD_CENTS = 1_250;
|
|
73
|
+
// No longer sold in dollars. A managed inbox is priced in credits (repricing
|
|
74
|
+
// 2026-09, S32): MANAGED_INBOX_CREDITS_PER_MONTH for a Google mailbox plus the
|
|
75
|
+
// SENDING_MAILBOX_CREDITS_PER_MONTH connection, warm-up included. Domains are
|
|
76
|
+
// bought in credits at InboxKit's cost (S33, SENDING_DOMAIN_CREDITS_PER_YEAR_TYPICAL).
|
|
76
77
|
// --- voice ------------------------------------------------------------------
|
|
77
|
-
export const VOICE_NUMBER_CREDITS_PER_MONTH =
|
|
78
|
-
|
|
79
|
-
export const
|
|
78
|
+
export const VOICE_NUMBER_CREDITS_PER_MONTH = 1_000;
|
|
79
|
+
/** Per connected minute; answering-machine detection is included (repricing 2026-09, decision 7.3). */
|
|
80
|
+
export const VOICE_CREDITS_PER_MINUTE = 5;
|
|
80
81
|
// --- per-action -------------------------------------------------------------
|
|
81
|
-
/**
|
|
82
|
-
|
|
82
|
+
/**
|
|
83
|
+
* Price of one workflow step after the 2026-09 repricing; row writes are free.
|
|
84
|
+
* Never read directly for billing: automationStepCredits() in billing.ts holds
|
|
85
|
+
* the previous price until OXYGEN_REPRICING_2026_09_EFFECTIVE_AT passes.
|
|
86
|
+
*/
|
|
87
|
+
export const AUTOMATION_ACTION_CREDITS = 0.05;
|
|
88
|
+
/**
|
|
89
|
+
* Platform fee on one provider call made with the customer's own API key
|
|
90
|
+
* (BYOK), after the 2026-09 repricing. Never read directly for billing:
|
|
91
|
+
* byokPlatformFeeCredits() in billing.ts holds 0 until
|
|
92
|
+
* OXYGEN_REPRICING_2026_09_EFFECTIVE_AT passes.
|
|
93
|
+
*/
|
|
94
|
+
export const BYOK_PLATFORM_FEE_CREDITS = 0.05;
|
|
95
|
+
/**
|
|
96
|
+
* Flat price of one LinkedIn URL found by the default LinkedIn-URL waterfall,
|
|
97
|
+
* after the 2026-09 repricing; a miss costs nothing. Never read directly for
|
|
98
|
+
* billing: linkedinUrlFoundCredits() in repricing.ts applies it only once
|
|
99
|
+
* OXYGEN_REPRICING_2026_09_EFFECTIVE_AT passes.
|
|
100
|
+
*/
|
|
101
|
+
export const LINKEDIN_URL_FOUND_CREDITS = 5;
|
|
83
102
|
/** Email, LinkedIn and WhatsApp sends are free; the pool pays for seats and inboxes. */
|
|
84
103
|
export const SEND_CREDITS = 0;
|
|
85
104
|
/** Every LinkedIn action is 0 under the pure seat model. */
|
|
@@ -97,12 +116,12 @@ export const ENRICHMENT_CREDITS_PER_ROW_TYPICAL = 10;
|
|
|
97
116
|
export const LINKEDIN_TYPICAL_ACTIONS_CREDITS_PER_MONTH = 0;
|
|
98
117
|
export const PRICING_PLAN_SNAPSHOT = [
|
|
99
118
|
{ planKey: "free", tier: "free", isLegacy: false, monthlyPriceCents: 0, monthlyCredits: 0, weeklyCreditsLimit: null, rolloverCap: null, byokEnabled: false },
|
|
100
|
-
{ planKey: "oxygen_49", tier: "oxygen", isLegacy: false, monthlyPriceCents: 4_900, monthlyCredits: 4_900, weeklyCreditsLimit: null, rolloverCap: 4_900, byokEnabled:
|
|
119
|
+
{ planKey: "oxygen_49", tier: "oxygen", isLegacy: false, monthlyPriceCents: 4_900, monthlyCredits: 4_900, weeklyCreditsLimit: null, rolloverCap: 4_900, byokEnabled: false },
|
|
101
120
|
{ planKey: "oxygen_99", tier: "oxygen", isLegacy: false, monthlyPriceCents: 9_900, monthlyCredits: 9_900, weeklyCreditsLimit: null, rolloverCap: 9_900, byokEnabled: true },
|
|
102
121
|
{ planKey: "oxygen_199", tier: "oxygen", isLegacy: false, monthlyPriceCents: 19_900, monthlyCredits: 19_900, weeklyCreditsLimit: null, rolloverCap: 19_900, byokEnabled: true },
|
|
103
|
-
{ planKey: "oxygen_499", tier: "oxygen", isLegacy: false, monthlyPriceCents: 49_900, monthlyCredits:
|
|
104
|
-
{ planKey: "oxygen_999", tier: "oxygen", isLegacy: false, monthlyPriceCents: 99_900, monthlyCredits:
|
|
105
|
-
{ planKey: "oxygen_1999", tier: "oxygen", isLegacy: false, monthlyPriceCents: 199_900, monthlyCredits:
|
|
122
|
+
{ planKey: "oxygen_499", tier: "oxygen", isLegacy: false, monthlyPriceCents: 49_900, monthlyCredits: 52_395, weeklyCreditsLimit: null, rolloverCap: 52_395, byokEnabled: true },
|
|
123
|
+
{ planKey: "oxygen_999", tier: "oxygen", isLegacy: false, monthlyPriceCents: 99_900, monthlyCredits: 109_890, weeklyCreditsLimit: null, rolloverCap: 109_890, byokEnabled: true },
|
|
124
|
+
{ planKey: "oxygen_1999", tier: "oxygen", isLegacy: false, monthlyPriceCents: 199_900, monthlyCredits: 229_885, weeklyCreditsLimit: null, rolloverCap: 229_885, byokEnabled: true },
|
|
106
125
|
{ planKey: "scale", tier: "scale", isLegacy: false, monthlyPriceCents: null, monthlyCredits: 1_000_000, weeklyCreditsLimit: null, rolloverCap: 1_000_000, byokEnabled: true },
|
|
107
126
|
{ planKey: "enterprise", tier: "enterprise", isLegacy: false, monthlyPriceCents: null, monthlyCredits: null, weeklyCreditsLimit: null, rolloverCap: null, byokEnabled: true },
|
|
108
127
|
{ planKey: "starter", tier: "starter", isLegacy: true, monthlyPriceCents: 9_900, monthlyCredits: 9_900, weeklyCreditsLimit: null, rolloverCap: 9_900, byokEnabled: true },
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { hostname } from "node:os";
|
|
3
|
+
/**
|
|
4
|
+
* The per-process OTel resource identity: which box, which process.
|
|
5
|
+
*
|
|
6
|
+
* The OTLP destinations turn resource auto-detection off (`autoDetectResources:
|
|
7
|
+
* false`) because Node's process detector copies argv verbatim — inline scripts
|
|
8
|
+
* and credentials included. That also dropped `host.name`, so every replica's
|
|
9
|
+
* spans, metrics and logs arrived indistinguishable. These two attributes are
|
|
10
|
+
* the safe part of what detection used to provide, stated explicitly.
|
|
11
|
+
*
|
|
12
|
+
* `service.instance.id` is minted once per process: a restart is a new
|
|
13
|
+
* instance, and two replicas on one host never collide the way a pid can.
|
|
14
|
+
*/
|
|
15
|
+
const SERVICE_INSTANCE_ID = randomUUID();
|
|
16
|
+
export function processResourceIdentity() {
|
|
17
|
+
let host = "unknown";
|
|
18
|
+
try {
|
|
19
|
+
host = hostname() || "unknown";
|
|
20
|
+
}
|
|
21
|
+
catch {
|
|
22
|
+
// A sandbox without os access still gets a stable instance id.
|
|
23
|
+
}
|
|
24
|
+
return { "host.name": host, "service.instance.id": SERVICE_INSTANCE_ID };
|
|
25
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const PROVIDER_HTTP_ERROR: unique symbol;
|
|
2
|
+
export type ProviderHttpError = Error & {
|
|
3
|
+
status: number;
|
|
4
|
+
retryable?: unknown;
|
|
5
|
+
body?: unknown;
|
|
6
|
+
};
|
|
7
|
+
/** True for an Error whose class is a provider HTTP error, whatever its numeric status. */
|
|
8
|
+
export declare function hasProviderHttpErrorIdentity(error: Error): boolean;
|
|
9
|
+
/** A provider HTTP error with a finite numeric status, ready to classify. */
|
|
10
|
+
export declare function isProviderHttpError(error: unknown): error is ProviderHttpError;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// A provider client error that carries the vendor's HTTP status.
|
|
2
|
+
//
|
|
3
|
+
// Surfaces that shape a failure for a customer (the /api/cli/* envelope, the
|
|
4
|
+
// operation-event projection) map these to provider_request_failed (4xx),
|
|
5
|
+
// provider_rate_limit (429) or provider_unavailable (5xx / retryable), and log the
|
|
6
|
+
// vendor's words to Axiom instead of showing them. They used to recognise such an
|
|
7
|
+
// error by its class NAME alone (`*ApiError`, `*AccessError`), so a client whose
|
|
8
|
+
// class was named anything else fell through to a 500 `unexpected_error`: on
|
|
9
|
+
// 2026-09-26 PredictLeads answered a 400 naming the invalid financing type, and the
|
|
10
|
+
// customer's agent was told "OXYGEN's server is erroring". The brand makes the
|
|
11
|
+
// contract explicit; the name rule stays so every class that works today keeps
|
|
12
|
+
// working.
|
|
13
|
+
export const PROVIDER_HTTP_ERROR = Symbol.for("oxygen.provider_http_error");
|
|
14
|
+
/** True for an Error whose class is a provider HTTP error, whatever its numeric status. */
|
|
15
|
+
export function hasProviderHttpErrorIdentity(error) {
|
|
16
|
+
if (error[PROVIDER_HTTP_ERROR] === true)
|
|
17
|
+
return true;
|
|
18
|
+
const name = error.name || "";
|
|
19
|
+
return name.endsWith("ApiError") || name.endsWith("AccessError");
|
|
20
|
+
}
|
|
21
|
+
/** A provider HTTP error with a finite numeric status, ready to classify. */
|
|
22
|
+
export function isProviderHttpError(error) {
|
|
23
|
+
if (!(error instanceof Error) || !hasProviderHttpErrorIdentity(error))
|
|
24
|
+
return false;
|
|
25
|
+
const status = error.status;
|
|
26
|
+
return typeof status === "number" && Number.isFinite(status);
|
|
27
|
+
}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
export declare const REPRICING_2026_09_EFFECTIVE_AT_ENV_VAR = "OXYGEN_REPRICING_2026_09_EFFECTIVE_AT";
|
|
2
|
+
/** Stable machine name of this price change, as reported on customer surfaces. */
|
|
3
|
+
export declare const REPRICING_2026_09_NAME = "repricing_2026_09";
|
|
4
|
+
type RepricingEnv = {
|
|
5
|
+
[key: string]: string | undefined;
|
|
6
|
+
};
|
|
7
|
+
export type RepricingOptions = {
|
|
8
|
+
env?: RepricingEnv;
|
|
9
|
+
/** The instant to resolve at. Defaults to the current time. */
|
|
10
|
+
now?: Date | number;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* `unset` and `invalid` both keep every old value. `scheduled` names a future
|
|
14
|
+
* instant (old values still in force); `in_force` means the new values apply.
|
|
15
|
+
*/
|
|
16
|
+
export type RepricingSwitchState = {
|
|
17
|
+
status: "unset";
|
|
18
|
+
effectiveAt: null;
|
|
19
|
+
} | {
|
|
20
|
+
status: "invalid";
|
|
21
|
+
effectiveAt: null;
|
|
22
|
+
raw: string;
|
|
23
|
+
} | {
|
|
24
|
+
status: "scheduled";
|
|
25
|
+
effectiveAt: Date;
|
|
26
|
+
} | {
|
|
27
|
+
status: "in_force";
|
|
28
|
+
effectiveAt: Date;
|
|
29
|
+
};
|
|
30
|
+
/** Parse the switch's raw value. `null` for unset, `undefined` for unparseable. */
|
|
31
|
+
export declare function parseRepricingEffectiveAt(raw: string | undefined): Date | null | undefined;
|
|
32
|
+
/** Where the switch stands at `now`. */
|
|
33
|
+
export declare function readRepricingSwitch(options?: RepricingOptions): RepricingSwitchState;
|
|
34
|
+
/** True once the switch names an instant that has passed. */
|
|
35
|
+
export declare function isRepricingInForce(options?: RepricingOptions): boolean;
|
|
36
|
+
/**
|
|
37
|
+
* The value an entry moves to and when, only while the switch names an instant
|
|
38
|
+
* still ahead (`scheduled`). `null` when unset, invalid or already in force, so a
|
|
39
|
+
* marketing surface that quotes "$1.25, $1.30 from <date>" announces nothing
|
|
40
|
+
* until an operator sets the date and stops announcing once the new value is
|
|
41
|
+
* the one in force.
|
|
42
|
+
*/
|
|
43
|
+
export declare function scheduledRepricedValue<T extends RepricedScalar>(value: {
|
|
44
|
+
readonly after: T;
|
|
45
|
+
}, options?: RepricingOptions): {
|
|
46
|
+
value: Widen<T>;
|
|
47
|
+
effectiveAt: Date;
|
|
48
|
+
} | null;
|
|
49
|
+
/** "October 27, 2026": how marketing copy names the switch's instant, in UTC. */
|
|
50
|
+
export declare function formatRepricingDate(effectiveAt: Date): string;
|
|
51
|
+
/**
|
|
52
|
+
* A price or limit value. `null` means "no bound", and only a limit's `before`
|
|
53
|
+
* may hold it: a limit that did not exist and now does is a tightening that
|
|
54
|
+
* waits for the switch (the email per-mailbox maximum, S52).
|
|
55
|
+
*/
|
|
56
|
+
export type RepricedScalar = number | boolean | string | null;
|
|
57
|
+
type Widen<T> = T extends null ? null : T extends number ? number : T extends boolean ? boolean : T extends string ? string : never;
|
|
58
|
+
/** The value in force: `before` until the switch's instant, `after` from it on. */
|
|
59
|
+
export declare function repricedValue<T extends RepricedScalar>(value: {
|
|
60
|
+
readonly before: T;
|
|
61
|
+
readonly after: T;
|
|
62
|
+
}, options?: RepricingOptions): Widen<T>;
|
|
63
|
+
/**
|
|
64
|
+
* One price that rises or one limit that tightens at the switch's instant.
|
|
65
|
+
* `key` is the stable machine name surfaces report (`topup.usd_cents_per_100_credits`),
|
|
66
|
+
* `slice` and `decision` point back at the specification and decision record.
|
|
67
|
+
*/
|
|
68
|
+
export type RepricedValue<T extends RepricedScalar = RepricedScalar> = {
|
|
69
|
+
readonly key: string;
|
|
70
|
+
readonly kind: "price" | "limit";
|
|
71
|
+
readonly slice: string;
|
|
72
|
+
readonly decision: string;
|
|
73
|
+
readonly unit: string;
|
|
74
|
+
readonly description: string;
|
|
75
|
+
readonly before: T;
|
|
76
|
+
readonly after: T;
|
|
77
|
+
};
|
|
78
|
+
export declare function defineRepricedValue<T extends RepricedScalar>(definition: RepricedValue<T>): RepricedValue<T>;
|
|
79
|
+
/** The hard per-mailbox maximum: none before the instant, 50 a day from it. */
|
|
80
|
+
export declare const EMAIL_MAILBOX_DAILY_CAP_MAXIMUM: RepricedValue<number | null>;
|
|
81
|
+
/**
|
|
82
|
+
* A mailbox still on the old default of 40 a day, which nobody set by hand, sends
|
|
83
|
+
* at the new default of 25 (P-58, proposed). The column was `DEFAULT 40`, so a
|
|
84
|
+
* deliberate 40 set before `daily_cap_source` existed cannot be told apart;
|
|
85
|
+
* setting the cap again records it as the customer's own, and it is then kept.
|
|
86
|
+
*/
|
|
87
|
+
export declare const EMAIL_MAILBOX_OLD_DEFAULT_DAILY_CAP: RepricedValue<25 | 40>;
|
|
88
|
+
/**
|
|
89
|
+
* S10 (decision 1.5): 100 on-demand top-up credits cost $1.30, up from $1.25.
|
|
90
|
+
* The seed and the generated snapshot carry the new rate; the rate sold until
|
|
91
|
+
* now stays in force until the switch's instant. `creditTopupUsdCentsPer100()`
|
|
92
|
+
* in billing.ts is the one runtime reader, and the packs on offer move with it
|
|
93
|
+
* (`creditTopupPacks()`, proposal P-7).
|
|
94
|
+
*/
|
|
95
|
+
export declare const TOPUP_RATE_REPRICING: RepricedValue<125 | 130>;
|
|
96
|
+
/**
|
|
97
|
+
* S20: the monthly credit reservation of every connected account (decisions
|
|
98
|
+
* 2.1–2.4). Each key is the pricing-seed charge key, so the seed row carries the
|
|
99
|
+
* new price and `repricedChargeCredits` holds the old one until the instant.
|
|
100
|
+
*
|
|
101
|
+
* A `before` of 0 means the kind had no credit reservation at all: X accounts
|
|
102
|
+
* were never priced, and a phone number was paid through its $10 Stripe seat
|
|
103
|
+
* rather than in credits. Such a kind reserves nothing until the instant.
|
|
104
|
+
*/
|
|
105
|
+
export declare const S20_RESERVATION_PRICE_RISES: readonly RepricedValue<number>[];
|
|
106
|
+
/**
|
|
107
|
+
* S40 (decision 6.1): a workflow step costs 0.05 credits, up from 0.001 per
|
|
108
|
+
* action. The seed and the generated snapshot carry the new price; the price
|
|
109
|
+
* charged until now stays in force until the switch's instant. Row writes inside
|
|
110
|
+
* a run are not steps and bill nothing (decision 6.2, live on release because it
|
|
111
|
+
* is a decrease), so the rise applies to steps only.
|
|
112
|
+
*/
|
|
113
|
+
export declare const AUTOMATION_STEP_CREDITS_REPRICING: RepricedValue<0.001 | 0.05>;
|
|
114
|
+
/**
|
|
115
|
+
* S40 (proposal P-45): once a step costs real money, the steps a live run
|
|
116
|
+
* executes count toward that run's approved `max_credits` and a trigger's
|
|
117
|
+
* per-delivery ceiling, next to its paid tool calls. Counting them tightens an
|
|
118
|
+
* approved ceiling, so it starts with the price and not before.
|
|
119
|
+
*/
|
|
120
|
+
export declare const AUTOMATION_STEPS_COUNT_TOWARD_RUN_CAP_REPRICING: RepricedValue<boolean>;
|
|
121
|
+
/**
|
|
122
|
+
* S30 (decision 3.5): EmailGuard monitoring per subscribed inbox, including the
|
|
123
|
+
* cycle's placement-test allowance, 100 -> 135 credits a month. Existing
|
|
124
|
+
* subscriptions pay the price in force at each renewal.
|
|
125
|
+
*/
|
|
126
|
+
export declare const DELIVERABILITY_SEAT_REPRICING: RepricedValue<100 | 135>;
|
|
127
|
+
/**
|
|
128
|
+
* S30 (decision 3.6; flat literal, proposal P-29): one managed placement test
|
|
129
|
+
* past an inbox's included allowance, or on an inbox with no monitoring
|
|
130
|
+
* subscription, 16.6 -> 66 credits. Tests on your own EmailGuard key stay 0.
|
|
131
|
+
*/
|
|
132
|
+
export declare const PLACEMENT_TEST_REPRICING: RepricedValue<16.6 | 66>;
|
|
133
|
+
/** EmailGuard monitoring per subscribed inbox-month, in credits, at the price in force. */
|
|
134
|
+
export declare function deliverabilitySeatCredits(options?: RepricingOptions): number;
|
|
135
|
+
/** One managed placement test beyond the included allowance, in credits, at the price in force. */
|
|
136
|
+
export declare function placementTestCredits(options?: RepricingOptions): number;
|
|
137
|
+
/** The flat monthly mailbox line of a managed Google inbox (the pricing seed's `commitment.managed_mailbox`). */
|
|
138
|
+
export declare const MANAGED_MAILBOX_REPRICING: RepricedValue<300 | 400>;
|
|
139
|
+
/** What a managed Google inbox costs a month, all-in: mailbox, connection and warm-up. */
|
|
140
|
+
export declare const MANAGED_INBOX_ALL_IN_REPRICING: RepricedValue<number>;
|
|
141
|
+
/** A managed Google inbox's monthly credits, all-in, at the switch state (marketing and docs). */
|
|
142
|
+
export declare function managedInboxAllInCredits(options?: RepricingOptions): number;
|
|
143
|
+
/**
|
|
144
|
+
* S41 (decision 6.3): a provider call made with the customer's own API key
|
|
145
|
+
* (BYOK) pays a 0.05-credit platform fee, up from nothing. The vendor still
|
|
146
|
+
* bills the call itself. The seed and the generated snapshot carry the fee; it
|
|
147
|
+
* is 0 until the switch's instant. Standing permissions approved while BYOK was
|
|
148
|
+
* free (armed auto-runs, workflow triggers) pay it from then on inside the
|
|
149
|
+
* per-delivery ceiling they already carry (proposal P-67).
|
|
150
|
+
*/
|
|
151
|
+
export declare const BYOK_PLATFORM_FEE_REPRICING: RepricedValue<0 | 0.05>;
|
|
152
|
+
/**
|
|
153
|
+
* L5.1 (decision L5.1; the free value and the rounding are PROPOSED P-54): the
|
|
154
|
+
* default credit ceiling of one unattended delivery is 10% of the plan's
|
|
155
|
+
* monthly credits, rounded half up. Integer arithmetic, because
|
|
156
|
+
* `229_885 * 0.1` is 22988.4999... in floating point and rounds the wrong way.
|
|
157
|
+
*/
|
|
158
|
+
export declare function tenthOfMonthlyCreditsRoundedHalfUp(monthlyCredits: number): number;
|
|
159
|
+
export declare const S56_DELIVERY_CREDIT_CEILING_CUTS: readonly RepricedValue<number>[];
|
|
160
|
+
/**
|
|
161
|
+
* L5.2 (decision L5.2): the free plan gains a default daily runaway guard. Free
|
|
162
|
+
* had none, because the guard scales from a monthly grant free does not have,
|
|
163
|
+
* so the guard itself is the tightening: no bound before the instant.
|
|
164
|
+
*/
|
|
165
|
+
export declare const FREE_ORG_DAILY_GUARD_WARN_CREDITS: RepricedValue<number | null>;
|
|
166
|
+
export declare const FREE_ORG_DAILY_GUARD_BLOCK_CREDITS: RepricedValue<number | null>;
|
|
167
|
+
/**
|
|
168
|
+
* L5.4 (decision L5.4; the inference half is PROPOSED P-56): the default credit
|
|
169
|
+
* ceilings of one Agent run on the team and scale limits rungs, which the $999
|
|
170
|
+
* and $1,999 plans, grandfathered Team plans and legacy scale plans read. A
|
|
171
|
+
* customer can still approve a higher ceiling for a single run.
|
|
172
|
+
*/
|
|
173
|
+
export declare const S56_AGENT_RUN_LIMIT_CUTS: readonly RepricedValue<number>[];
|
|
174
|
+
/**
|
|
175
|
+
* S53 (decision L4.2, ratified 2026-09-26): a free workspace may schedule a
|
|
176
|
+
* workflow or Agent cron at most every 15 minutes, down from every minute. Paid
|
|
177
|
+
* plans keep every minute. A new schedule that fires closer together is refused
|
|
178
|
+
* with `cron_interval_below_plan_minimum`; one already armed keeps running at the
|
|
179
|
+
* 15-minute interval instead and is never deleted (proposal P-47).
|
|
180
|
+
* `resolveCronMinIntervalMinutes` in plan-limits.ts resolves it, and a test pins
|
|
181
|
+
* `after` to `PLAN_LIMITS.free.workflows.cronMinIntervalMinutes`.
|
|
182
|
+
*/
|
|
183
|
+
export declare const FREE_CRON_MIN_INTERVAL_REPRICING: RepricedValue<1 | 15>;
|
|
184
|
+
/** A Lusha person enrichment that reveals a phone number, per contact. */
|
|
185
|
+
export declare const LUSHA_PHONE_REVEAL_CREDITS_REPRICING: RepricedValue<43.5 | 217.5>;
|
|
186
|
+
/** A Lusha person enrichment that reveals an email and a phone number, per contact. */
|
|
187
|
+
export declare const LUSHA_EMAIL_AND_PHONE_REVEAL_CREDITS_REPRICING: RepricedValue<43.5 | 261>;
|
|
188
|
+
/**
|
|
189
|
+
* Before the instant a Lusha or Apollo bulk person enrichment never costs more
|
|
190
|
+
* than its old flat price per request (43.5 and 100); from it on, it costs its
|
|
191
|
+
* per-record price times the contacts or records it holds.
|
|
192
|
+
*/
|
|
193
|
+
export declare const PERSON_REVEAL_PRICED_PER_RECORD_REPRICING: RepricedValue<boolean>;
|
|
194
|
+
export declare const S42_REVEAL_PRICE_RISES: readonly RepricedValue[];
|
|
195
|
+
/** Whether the LinkedIn-URL waterfall bills a flat price per URL found. */
|
|
196
|
+
export declare const LINKEDIN_URL_FLAT_PRICE_REPRICING: RepricedValue<boolean>;
|
|
197
|
+
/** True once a LinkedIn URL is priced per URL found (S43). */
|
|
198
|
+
export declare function linkedinUrlFlatPriceInForce(options?: RepricingOptions): boolean;
|
|
199
|
+
/** The flat price of one LinkedIn URL found, in credits (the pricing seed's `enrichment.linkedin_url_found`). */
|
|
200
|
+
export declare function linkedinUrlFoundCredits(): number;
|
|
201
|
+
/**
|
|
202
|
+
* S22 (decision 2.7): bringing your own provider keys (BYOK) needs the $99 plan
|
|
203
|
+
* or above. The pricing seed and snapshot carry the new value (`oxygen_49`
|
|
204
|
+
* `byokEnabled: false`); `resolveBasePricingPlan` holds the $49 plan at the old
|
|
205
|
+
* value until the switch's instant. From the instant on, a key the workspace
|
|
206
|
+
* connected before it keeps working until the plan changes (P-20, proposed):
|
|
207
|
+
* `byokConnectionGrandfathered` in plan-capabilities.ts.
|
|
208
|
+
*/
|
|
209
|
+
export declare const OXYGEN_49_BYOK_REPRICING: RepricedValue<boolean>;
|
|
210
|
+
/**
|
|
211
|
+
* Every value the 2026-09 switch moves. Each dark slice appends its entries
|
|
212
|
+
* here, so `oxygen limits show` can list them once a date is set and one test
|
|
213
|
+
* proves each resolves to its old value before the instant and its new value
|
|
214
|
+
* after it.
|
|
215
|
+
*/
|
|
216
|
+
export declare const REPRICING_2026_09_SCHEDULE: readonly RepricedValue[];
|
|
217
|
+
/** The schedule entry with this key, or undefined. */
|
|
218
|
+
export declare function findRepricedValue(key: string, schedule?: readonly RepricedValue[]): RepricedValue | undefined;
|
|
219
|
+
/**
|
|
220
|
+
* The credits a recurring charge costs right now, given the price stored in the
|
|
221
|
+
* pricing book (database row or seed).
|
|
222
|
+
*
|
|
223
|
+
* The seed and the S20 migration carry the NEW price, so a charge key with a
|
|
224
|
+
* scheduled rise must not reach a customer before the instant. Until then a
|
|
225
|
+
* stored price equal to the scheduled new price resolves to the old one. Any
|
|
226
|
+
* other stored price is a staff override made at /admin/costs and stands, as it
|
|
227
|
+
* always has. From the instant on the stored price stands. A key with no
|
|
228
|
+
* scheduled rise passes through unchanged. A result of 0 means "not priced yet":
|
|
229
|
+
* callers that reserve credits treat it as unpriced, never as free.
|
|
230
|
+
*/
|
|
231
|
+
export declare function repricedChargeCredits(chargeKey: string, storedCredits: number, options?: RepricingOptions): number;
|
|
232
|
+
/** Human-readable problems with a schedule; empty when it is sound. */
|
|
233
|
+
export declare function findRepricingScheduleViolations(schedule?: readonly RepricedValue[]): string[];
|
|
234
|
+
export type RepricingScheduleChange = {
|
|
235
|
+
key: string;
|
|
236
|
+
kind: "price" | "limit";
|
|
237
|
+
unit: string;
|
|
238
|
+
description: string;
|
|
239
|
+
value_in_force: RepricedScalar;
|
|
240
|
+
value_before: RepricedScalar;
|
|
241
|
+
value_after: RepricedScalar;
|
|
242
|
+
};
|
|
243
|
+
export type RepricingScheduleDescription = {
|
|
244
|
+
name: typeof REPRICING_2026_09_NAME;
|
|
245
|
+
effective_at: string;
|
|
246
|
+
status: "scheduled" | "in_force";
|
|
247
|
+
changes: RepricingScheduleChange[];
|
|
248
|
+
};
|
|
249
|
+
/**
|
|
250
|
+
* What customer surfaces report about the scheduled change. `null` while the
|
|
251
|
+
* switch is unset or unparseable: nothing is announced until an operator sets a
|
|
252
|
+
* valid instant, so an inert switch changes no customer-visible output.
|
|
253
|
+
*/
|
|
254
|
+
export declare function describeRepricingSchedule(options?: RepricingOptions & {
|
|
255
|
+
schedule?: readonly RepricedValue[];
|
|
256
|
+
}): RepricingScheduleDescription | null;
|
|
257
|
+
export {};
|