Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

g1t.sh
2,071 linesCodeBlameRaw

Pick any line to see why it is the way it is: the commit, the pull request and issue it came from, and what the agent was thinking.

Download ZIP reads blobs eight batches at a time and deflates files together1import type { ComputeKind, Reservation } from "./compute";
Merge platform pause and the hourly usage watcher: staff can pause compute, schedules, indexing or renders for everyone, the watcher emails on a breach and is never blind quietly, and the models proxy holds each run to its cap (billing 0051, integrations 0006)2import type { PauseLevel } from "./platform";
Download ZIP reads blobs eight batches at a time and deflates files together3import type { User, Viewer } from "./identity";
4import type { RepoPath } from "./repos";
5import type { Result } from "./result";
6
7/** Millionths of a US dollar in one dollar: the unit money is held in. */
8export const MICROS_PER_DOLLAR = 1_000_000;
9
10/** Whether workspaces are charged for agents at all, and with real money. */
11export type BillingStatus = {
12 /**
13 * False when no card processor is configured: nothing is charged, and who
14 * may run agents is decided some other way.
15 */
16 enabled: boolean;
17 /** False while the card processor is in its test mode, where cards are not real. */
18 live: boolean;
19 /**
20 * True while g1t is being built out: runs are recorded with what they
21 * cost, but nothing is charged and no credit is needed. Not forever.
22 */
23 free?: boolean;
24};
25
26/** A workspace's standing. */
27export type BillingAccount = {
28 workspace: string;
29 /**
30 * Credit left, in millionths of a dollar. Can dip below zero by the cost
31 * of the runs that were under way when it ran out.
32 */
33 balanceMicros: number;
34 status: BillingStatus;
35 /** What is added to a run's cost, in percent. */
36 marginPercent: number;
37 /** The card charged near the limit and when a month closes, if one is saved. */
38 card?: { brand: string; last4: string; expMonth: number; expYear: number } | null;
39};
40
41/** One line of a workspace's statement. */
42export type LedgerEntry = {
43 id: string;
44 /** Credit bought with a card, or an agent's run. */
45 kind: "top_up" | "usage";
46 /** Positive for credit added, negative for usage. */
47 amountMicros: number;
48 description: string;
49 /** For usage: the repository and pull request the agent worked on. */
50 repo: string | null;
51 number: number | null;
52 /** For usage: `implement`, `review` or `update`. */
53 task: string | null;
54 /** For usage: the model, by its public name. */
55 model: string | null;
56 /** For usage: who paid the model provider. */
57 billedTo: "g1t" | "workspace";
58 /** For a top-up: the username of whoever paid. */
59 createdBy: string | null;
60 /** RFC 3339. */
61 createdAt: string;
62 /** The workspace the line belongs to, which tells an enterprise's lines apart. */
63 workspace?: string | null;
64 /** For usage: what the plan's included usage paid of it. `amountMicros` is what is left to pay. */
65 creditMicros?: number;
66 /** For usage: what the workspace's trial credit paid of it. */
67 trialMicros?: number;
68 /** For usage: what g1t's open-source pool paid of it. */
69 ossMicros?: number;
70 /** For usage: what g1t covered itself, such as a trial's last run past its credit. */
71 givenMicros?: number;
Billing: credits with a kind and expiry, discounts instead of comped, and safer charging72 /** For usage: what the account's discount took off its price. */
73 discountMicros?: number;
74 /** For a credit from g1t, and for what of one expired or was revoked: its kind. */
75 creditKind?: CreditKind;
Download ZIP reads blobs eight batches at a time and deflates files together76};
77
Billing: credits with a kind and expiry, discounts instead of comped, and safer charging78/**
79 * Why g1t gave a workspace credit. Promotional (a welcome, a referral) and
80 * goodwill (an apology) are given away when spent; a refund gives back
81 * money already paid, and never expires.
82 */
83export type CreditKind = "promotional" | "goodwill" | "refund" | "purchased";
84
85/** One credit g1t gave, with what of it was used: spent before anything paid in advance, the soonest-expiring first. */
86export type CreditGrant = {
87 /** `crd_…`, the grant's ledger reference. */
88 id: string;
89 workspace: string;
90 kind: CreditKind;
91 amountMicros: number;
92 usedMicros: number;
93 /** What can still be spent: nothing once it expired or was revoked. */
94 leftMicros: number;
95 note: string;
96 /** A refund: what it refunds, and the day of it. */
97 refundFor?: string | null;
98 refundDay?: string | null;
99 /** RFC 3339; null never expires. */
100 expiresAt: string | null;
101 createdBy: string;
102 createdAt: string;
103 state: "open" | "used" | "expired" | "revoked";
104 closedAt?: string | null;
105 closedNote?: string | null;
106 closedBy?: string | null;
107 /** What expiring or revoking took off the balance. */
108 closedMicros?: number;
109 /** What it pays for: all usage, or models only (spent first). */
110 scope?: "all" | "models";
111 /** Where it came from. */
Usage, Billing settings and prepaid AI credit; fixes from the UX audit112 source?: "staff" | "purchase" | "promo_code" | "upgrade";
Billing: credits with a kind and expiry, discounts instead of comped, and safer charging113};
114
115/** A workspace's credits from g1t, newest first. */
116export type Credits = { grants: CreditGrant[]; leftMicros: number };
117
118/** One month's credits of one kind: given, spent that month, and taken back unused. */
119export type CreditMonth = {
120 month: string;
121 kind: CreditKind;
122 givenMicros: number;
123 grants: number;
124 usedMicros: number;
125 expiredMicros: number;
126 revokedMicros: number;
127};
128
129/** Every credit g1t gave (at most 200, filtered), the last 12 months by kind, and who gave them. */
130export type AdminCredits = { grants: CreditGrant[]; months: CreditMonth[]; staff: string[] };
131
132/** What a credit from sudo is, past its amount and note. */
133export type CreditOptions = {
134 kind: CreditKind;
135 /** RFC 3339; never for a refund. */
136 expiresAt?: string | null;
137 /** A refund: what it is for, and the day refunded (`YYYY-MM-DD`). */
138 refundFor?: string | null;
139 refundDay?: string | null;
140};
141
Download ZIP reads blobs eight batches at a time and deflates files together142/** What lets a sandbox, and nothing else, report what its run cost. */
143export type RunTicket = { runId: string; token: string };
144
145/**
146 * What agents cost, charged to the workspace they worked for. A workspace
147 * buys credit; each run deducts its cost plus g1t's margin; with no credit,
148 * no agent starts.
149 */
150/**
151 * The free allowance on g1t's hosted models for a workspace not otherwise
152 * open to them: a few dollars of model cost each, out of one pool, until a
153 * date. Mirrors `Trial` in `crates/contracts/src/billing.rs`.
154 */
Billing: credits with a kind and expiry, discounts instead of comped, and safer charging155/**
156 * How an account is charged. Standard unless g1t set otherwise in sudo:
157 * custom terms are a discount (0 to 100%), a ceiling, or both. A 100%
158 * discount charges nothing and shows the usage at its price. `comped` is
159 * from before discounts and reads as 100%; billing no longer writes it.
160 */
Download ZIP reads blobs eight batches at a time and deflates files together161export type Terms = {
162 kind: "standard" | "comped" | "custom";
163 discountPercent: number;
164 ceilingMicros: number | null;
165 note: string;
166 until: string | null;
167 setBy: string | null;
168 setAt: string | null;
169};
170
171/**
172 * Who pays: a workspace's own account, or an enterprise's, which pays for
173 * several workspaces with one bill and one limit.
174 */
175export type PayingAccount = {
176 id: string;
177 kind: "workspace" | "enterprise";
178 name: string;
179 terms: Terms;
180 workspaces: string[];
181 /** Where an enterprise's invoices go. */
182 billingEmail?: string | null;
183 /** An enterprise's invoices, newest first. */
184 invoices?: EnterpriseInvoice[];
185 createdAt: string;
186 /** What g1t staff set for the account beyond its terms. */
187 allowances?: Allowances;
188};
189
190/** Set per account by g1t staff in sudo, on top of its terms. */
191export type Allowances = {
192 /** The g1t plan without its monthly price; usage is charged as usual. Comped accounts have it anyway. */
193 plan: boolean;
194 /** Each public repository's monthly cap on g1t's open-source pool; null for the default. */
195 ossRepoMicros: number | null;
196 /** Each workspace's trial credit, outside the monthly pool; null for the default. */
197 trialMicros: number | null;
198 /** Agents at once, in place of the plan's (2 in the first month or on the trial, then 10); null for the default. */
199 maxConcurrentAgents?: number | null;
200 /** One run's spend cap, in place of the owners' and the default $2; null for none. */
201 runCapMicros?: number | null;
202 /** What one issue's agents may spend in all, in place of the owners' and the default $10; null for none. */
203 issueCapMicros?: number | null;
204 /** Days of audit log its workspaces keep, in place of the plan's (7 free, 90 on the plan), longer or shorter; null for the plan's. */
205 auditRetentionDays?: number | null;
206 /** A hold on new compute, with why; null for none. */
207 hold?: string | null;
208};
209
210// --- Entitlements, and compute started under a reservation ------------------
211//
212// Every service that starts compute asks billing first:
213// 1. `entitlements(workspace)`: what it may do at all, its caps, and whether compute is paused.
214// 2. `reserve(...)`: holds the estimate against what may pay for it, so starts at the same moment
215// cannot overshoot together. Answers who pays first, or refuses with a stable code
216// (`not_paid`, `trial_used`, `limit`, `paused`, `oss_pool_empty`) and a message for the owner.
217// 3. `settle(reservationId, actualMicros)`: releases the hold. The charge goes on the ledger the usual way.
218// A reservation never settled lapses after `RESERVATION_HOURS`.
219
220/** A reservation that is never settled stops holding after this long. */
221export const RESERVATION_HOURS = 3;
222/** What a ceiling reads as when there is none (g1t's own workspaces). */
223export const UNLIMITED_MICROS = 1_000_000_000_000_000;
224
225/** What a workspace pays g1t on, as far as compute is concerned. Mirrors `PlanKind`. */
226export type PlanKind = "free" | "paid" | "internal" | "enterprise";
227
228// `ComputeKind` (what compute is for), `PaidBy` (who pays first: credit, trial, oss, on_demand) and
229// `Reservation` are in `./compute`, with the gate that calls `reserve` and `settle`.
230
231/** One level reached: 50, 75, 90 or 100 percent. */
232export type UsageAlert = {
233 /** `included` (the plan's included usage), `spend_limit` or `ceiling`. */
234 meter: "included" | "spend_limit" | "ceiling" | string;
235 level: number;
236 usedMicros: number;
237 limitMicros: number;
238 message: string;
239};
240
241/** An hour's spend well above the workspace's usual: new compute waits for an owner. */
242export type Spike = {
243 id: string;
244 /** `open` (waiting), `continued` (keep going) or `stopped`. */
245 status: "open" | "continued" | "stopped" | string;
246 hourMicros: number;
247 averageMicros: number;
248 detectedAt: string;
249 decidedBy?: string | null;
250 decidedAt?: string | null;
251 /** While continued: until when, unless spend doubles again first. */
252 until?: string | null;
253};
254
255/** What a workspace may do now. Mirrors `Entitlements` in `crates/contracts/src/billing.rs`. */
256export type Entitlements = {
257 workspace: string;
258 plan: PlanKind;
259 /** May start sandboxes, models, deployments and semantic search at all: paid, internal, enterprise, or free with trial credit left. */
260 compute: boolean;
261 /** The one-time trial credit left; 0 if none or used. */
262 trialMicrosLeft: number;
263 /** A card check has been done; the trial and the open-source pool need it. */
264 trialVerified: boolean;
265 /** A paid workspace still in its first billing cycle. */
266 firstMonth: boolean;
267 /** 2 in the first month or on the trial, 10 after; staff can override it. */
268 maxConcurrentAgents: number;
269 /** 60 in the first month or on the trial; otherwise the guardrails' own caps. */
270 maxRunMinutes: number;
271 /** One run's spend cap, $2 by default; staff can override it. */
272 runCapMicros: number;
273 /** Agent spend on one issue in all, $10 by default. */
274 issueCapMicros: number;
275 /** g1t's ceiling on usage not yet paid for; `UNLIMITED_MICROS` for g1t's own; 0 for free. */
276 ceilingMicros: number;
277 /** Usage not yet paid for this month, prepayment taken off. */
278 exposureMicros: number;
279 /** Why new compute is paused, for the owner; null when it is not. */
280 paused: string | null;
Merge branch 'open-signups'281 /** g1t staff put a hold on the account: nothing new is set up for it, such as a self-hosted runner. */
282 held?: boolean;
Download ZIP reads blobs eight batches at a time and deflates files together283 /** What open reservations hold now. */
284 heldMicros?: number;
285 /** Paid in advance and not used yet. */
286 prepaidMicros?: number;
287 /** The plan's included usage each month, and what of it is used. */
288 includedMicros?: number;
289 includedUsedMicros?: number;
290 /** How far back the audit log can be read and exported, and what is kept: the plan's days, or what g1t staff set for the account. */
291 auditRetentionDays: number;
292 /** Whether `auditRetentionDays` is what staff set for the account rather than the plan's. */
293 auditRetentionCustom?: boolean;
294 /** Private repository storage free for every workspace: past it, the plan pays and a free workspace's pushes stop. */
295 freePrivateStorageBytes: number;
296 /** The last daily measure of the workspace's private repositories (a lower bound). */
297 privateStorageBytes: number;
298 /** On a paid plan: package storage past the free amounts is charged, never refused. */
299 hasPlan?: boolean;
300 /** Package storage free for every workspace (public, and private): past it a free workspace's pushes are refused. */
301 packagePublicFreeBytes?: number;
302 packagePrivateFreeBytes?: number;
303 /** What g1t's open-source pool paid for the workspace this month. */
304 ossPaidMicros: number;
305 /** Deploy build time this month, every second of it metered. */
306 buildSecondsUsed?: number;
307 /** Git operations this month, and how many are free for every workspace. */
308 gitOperations?: number;
309 gitOperationsIncluded?: number;
310 /** The smallest amount a card is charged when a month closes. */
311 minChargeMicros: number;
312 /** A spend spike waiting for an owner, or decided. */
313 spike?: Spike | null;
314 /** Where usage stands against what is included and the limits, from 50%. */
315 alerts?: UsageAlert[];
316};
317
318/** A hold on a start's estimated cost, as billing answers it (`Reservation` in `./compute`, and more). */
319export type ReservationHeld = Reservation & {
320 /** What is held, at cost; may be less than the estimate for a free workspace's last bit of trial. */
321 heldMicros?: number;
322 /** When the hold lapses if never settled. */
323 expiresAt?: string;
324};
325
326/** A request to g1t: a higher limit, or help with usage past what was meant. */
327export type LimitRequest = {
328 id: string;
329 workspace: string;
330 kind: "limit" | "overage" | string;
331 amountMicros: number;
332 reason: string;
333 expectedMonthlyMicros: number;
334 status: "open" | "approved" | "declined" | string;
335 decidedMicros?: number | null;
336 decidedBy?: string | null;
337 /** The answer, as the owner sees it. */
338 answer?: string | null;
339 createdBy: string;
340 createdAt: string;
341 decidedAt?: string | null;
342};
343
344/** What staff see beside a request. */
345export type WorkspaceHistory = {
346 plan: PlanKind | null;
347 months: MonthFigures[];
348 paidClearedMicros: number;
349 payments: number;
350 disputes: number;
351 declines: number;
352 firstSeen: string | null;
353 ceilingMicros: number | null;
354 maxCeilingMicros: number | null;
355 spendLimitMicros: number | null;
356 lastHourMicros: number;
357 averageHourMicros: number;
358 lastDayMicros: number;
359};
360
361export type LimitRequestReview = { request: LimitRequest; history: WorkspaceHistory };
362
363/** What a one-time goodwill credit comes to: the margin on the overage, always, plus its cost up to the cap. */
364export type Goodwill = {
365 overageMicros: number;
366 marginMicros: number;
367 costMicros: number;
368 creditMicros: number;
369 absorbedMicros: number;
370};
371
372/** A workspace whose month went well past its usual, or hit a spike. */
373export type Overage = {
374 workspace: string;
375 plan: PlanKind;
376 typicalMonthMicros: number;
377 thisMonthMicros: number;
378 costMicros: number;
379 marginMicros: number;
380 spike: Spike | null;
381 topEntries: LedgerEntry[];
382 goodwill: Goodwill;
383 goodwillAvailable: boolean;
384 lastGoodwillAt: string | null;
385 request: LimitRequest | null;
386};
387
388/** One workspace's recent pace. */
389export type Velocity = {
390 workspace: string;
391 plan: PlanKind;
392 lastHourMicros: number;
393 averageHourMicros: number;
394 lastDayMicros: number;
395 thisMonthMicros: number;
396 ratio: number;
397 spike: Spike | null;
398 firstSeen: string | null;
399};
400
401/** g1t's capped budgets for free usage this month. */
402export type Pools = {
403 month: string;
404 trialGrantedMicros: number;
405 trialPoolMicros: number;
406 trialGrants: number;
407 ossUsedMicros: number;
408 ossPoolMicros: number;
409 ossRepoMicros: number;
410};
411
412export type AccountSummary = {
413 account: PayingAccount;
414 limit: Limit;
415 chargedMicros: number;
416 costMicros: number;
417 paidMicros: number;
418 /** The same figures for each of the account's workspaces that has any. */
419 byWorkspace: WorkspaceFigures[];
420 /** The last six months, oldest first. */
421 months?: MonthFigures[];
422};
423
424/** One workspace's share of an `AccountSummary`. */
425export type WorkspaceFigures = { workspace: string; chargedMicros: number; costMicros: number; paidMicros: number };
426
427export type StripeStatus = {
428 /** `test` or `live`, from the key; `off` without one. */
429 mode: "test" | "live" | "off" | string;
430 /** Whether `STRIPE_WEBHOOK_SECRET` is set, so events can be checked. */
431 secretSet: boolean;
432 /** The destination at billing's address in Stripe, as Stripe has it. */
433 webhook: { url: string; endpointId: string; status: "enabled" | "disabled" | string; events: string[]; createdAt: string } | null;
434 /** Events billing handles that the destination does not send. */
435 missingEvents: string[];
436 recentEvents: { id: string; kind: string; outcome: string; receivedAt: string }[];
437 error: string | null;
438};
439
440/** An enterprise's invoice: one line per workspace, paid on Stripe's page. */
441export type EnterpriseInvoice = {
442 invoiceId: string;
443 hostedUrl: string | null;
444 amountMicros: number;
445 status: "open" | "paid" | "overdue" | "void" | string;
446 period: string;
447 lines: { workspace: string; amountMicros: number }[];
448 createdAt: string;
449};
450
451/** A workspace's invoice: monthly, or when charged near its limit. Itemised, in Stripe's billing page. */
452export type WorkspaceInvoice = {
453 invoiceId: string;
454 workspace: string;
455 reason: "month" | "threshold" | string;
456 period: string;
457 amountMicros: number;
458 status: "paid" | "open" | "failed" | "void" | string;
459 hostedUrl: string | null;
460 pdfUrl: string | null;
461 lines: { description: string; amountMicros: number }[];
462 createdAt: string;
Merge Stripe Tax, the card fee on card payments, and one free workspace per person463 /** The card processing fee on top of `amountMicros` when charged to a card, and the tax Stripe added once known. */
464 feeMicros?: number;
465 taxMicros?: number;
Download ZIP reads blobs eight batches at a time and deflates files together466};
467
468/** A month of the ledger, grouped by day or project, a line per kind of charge. */
469export type Statement = {
470 month: string;
471 months: string[];
472 groups: {
473 key: string;
474 label: string;
475 /** `coveredMicros`: what the plan's included usage, the trial, the open-source pool or g1t paid, not in `chargedMicros`. */
Billing: credits with a kind and expiry, discounts instead of comped, and safer charging476 /** `priceMicros`: usage at its price; `discountMicros`: what the account's discount took off it. */
477 lines: {
478 kind: string;
479 count: number;
480 chargedMicros: number;
481 costMicros: number;
482 coveredMicros?: number;
483 priceMicros?: number;
484 discountMicros?: number;
Merge Stripe Tax, the card fee on card payments, and one free workspace per person485 /** On `Tax` and `Card processing fees` lines: what was paid with payments on top of what reached the balance. Never charged. */
486 passedMicros?: number;
Billing: credits with a kind and expiry, discounts instead of comped, and safer charging487 }[];
Download ZIP reads blobs eight batches at a time and deflates files together488 chargedMicros: number;
Billing: credits with a kind and expiry, discounts instead of comped, and safer charging489 priceMicros?: number;
490 discountMicros?: number;
Download ZIP reads blobs eight batches at a time and deflates files together491 }[];
492 totals: {
493 chargedMicros: number;
494 paidMicros: number;
495 costMicros: number;
496 entries: number;
Billing: credits with a kind and expiry, discounts instead of comped, and safer charging497 /** Usage at price, and what the discount took off: charged is the price less the discount and what paid for it. */
498 priceMicros?: number;
499 discountMicros?: number;
500 /** The account's discount now, in percent; absent without one. */
501 discountPercent?: number | null;
Download ZIP reads blobs eight batches at a time and deflates files together502 /** What paid for usage before it was charged, such as "Paid by g1t's open-source pool". */
503 covered?: { source: "included" | "trial" | "oss_pool" | "given" | string; label: string; micros: number }[];
504 /** Owed when the month closed but under the minimum charge: on the next invoice. */
505 carriedMicros?: number;
Merge Stripe Tax, the card fee on card payments, and one free workspace per person506 /** Tax and card processing fees paid with the month's payments, on top of `paidMicros`. */
507 taxMicros?: number;
508 cardFeeMicros?: number;
Download ZIP reads blobs eight batches at a time and deflates files together509 };
510};
511
512export type MonthFigures = {
513 month: string;
514 /** Usage charged, after what paid for it first. */
515 chargedMicros: number;
516 /** What usage cost g1t: never a workspace's own model provider. */
517 costMicros: number;
518 paidMicros: number;
519 /** The plan's monthly price, paid. */
520 plansMicros?: number;
521 /** What g1t gave at price (internal use, trials, the open-source pool, goodwill, covered). Not margin. */
522 givenMicros?: number;
523};
524
525/** What g1t gave this month from one source. */
526export type GivenFigures = { source: "internal" | "trial" | "oss_pool" | "goodwill" | "covered" | string; label: string; micros: number; costMicros: number };
527
528/** One internal workspace's use this month, and why it is not charged. */
529export type InternalUse = { workspace: string; reason: string; costMicros: number; entries: number };
530
531export type SignalKind = "at_limit" | "near_ceiling" | "declined" | "growing" | "established" | "first_payment" | "high_spend" | "cost_over_revenue";
532
533/** Why a workspace is worth reaching out to. */
534export type Signal = {
535 workspace: string;
536 kind: SignalKind;
537 detail: string;
538 valueMicros: number;
539 stage: string | null;
540 owner: string | null;
541 nextStep?: string | null;
542 /** When the next step is due, YYYY-MM-DD. */
543 nextAt?: string | null;
544};
545
546/** One invoice g1t has sent, a workspace's or an enterprise's. */
547export type InvoiceSummary = {
548 invoiceId: string;
549 kind: "workspace" | "enterprise";
550 account: string;
551 name: string;
552 reason: string;
553 period: string;
554 amountMicros: number;
555 status: string;
556 hostedUrl: string | null;
557 createdAt: string;
558 paidAt: string | null;
559};
560
561export type SalesStage = "none" | "lead" | "contacted" | "negotiating" | "won" | "lost" | "churn_risk";
562
563export type SalesRecord = {
564 workspace: string;
565 stage: SalesStage | string;
566 owner: string | null;
567 nextStep: string | null;
568 nextAt: string | null;
569 notes: { id: string; text: string; by: string; createdAt: string }[];
570 updatedAt: string | null;
571};
572
573export type Overview = {
574 month: string;
575 months: MonthFigures[];
576 byKind: { kind: string; chargedMicros: number; costMicros: number }[];
577 payingWorkspaces: number;
578 stopped: number;
579 nearCeiling: number;
580 declined: number;
581 openInvoicesMicros: number;
582 followUpsDue: number;
583 /** g1t's capped budgets for free usage, this month. */
584 pools?: Pools | null;
585 /** Usage charged plus the plan's price paid, this month. */
586 revenueMicros?: number;
587 activePlans?: number;
588 planMrrMicros?: number;
589 /** What g1t gave this month, by source, apart from its margin. */
590 given?: GivenFigures[];
591 /** g1t's own and Flagon's workspaces: what their use cost, and why they are not charged. */
592 internal?: InternalUse[];
593 openRequests?: number;
594 overages?: number;
595 openSpikes?: number;
596};
597
598/** A customer's Stripe billing page, for staff to send them. */
599export type BillingLink = {
600 /** One-time and short-lived, signed in already. */
601 portalUrl: string;
602 /** The page's sign-in, which does not expire: the customer signs in by email. */
603 loginUrl: string | null;
604 customerEmail: string | null;
605 expiresNote: string;
606};
607
608export type AdminAction = { id: string; account: string; action: string; detail: string; by: string; createdAt: string };
609
610export type AccountDetail = {
611 summary: AccountSummary;
612 workspaces: Limit[];
613 ledger: LedgerEntry[];
614 audit: AdminAction[];
615};
616
617/** Staff-only billing, for sudo.g1t.sh. Every change names who made it. */
618export interface BillingAdminApi {
619 accounts(query?: string): Promise<AccountSummary[]>;
620 account(id: string): Promise<Result<AccountDetail>>;
621 setTerms(id: string, terms: Terms, by: string): Promise<Result<PayingAccount>>;
622 /** Team on or off without charge, and the account's share of the pools. Needs a note. */
623 setAllowances(id: string, allowances: Allowances, note: string, by: string): Promise<Result<PayingAccount>>;
624 createEnterprise(name: string, workspaces: string[], by: string): Promise<Result<PayingAccount>>;
625 attach(workspace: string, account: string | null, by: string): Promise<Result<PayingAccount>>;
Billing: credits with a kind and expiry, discounts instead of comped, and safer charging626 /** Credit for a workspace: promotional, goodwill or a refund; the owners are emailed. */
627 credit(workspace: string, amountMicros: number, note: string, by: string, options?: CreditOptions): Promise<Result<LedgerEntry>>;
628 /** Every credit g1t gave, filtered, with each month's totals by kind. */
629 credits(filter?: { workspace?: string | null; kind?: CreditKind | null; month?: string | null; by?: string | null }): Promise<AdminCredits>;
630 /** What is left of a credit, taken back, with why. */
631 revokeCredit(id: string, note: string, by: string): Promise<Result<CreditGrant>>;
sudo: reset a test workspace's billing so it starts again as a new customer; refused on a live Stripe key, for comped workspaces and for an enterprise's632 /** A test workspace's billing wiped, to start again as a new customer. Only on Stripe's test key; never comped or enterprise. Logged. */
633 resetBilling(workspace: string, confirm: string, note: string, by: string): Promise<Result<BillingReset>>;
Download ZIP reads blobs eight batches at a time and deflates files together634 /** The workspace's Stripe billing page, to send to the customer. Logged. */
635 billingLink(workspace: string, by: string): Promise<Result<BillingLink>>;
636 /** Where billing stands with Stripe; with `setup`, registers the webhook first. */
637 /** Stripe's state for billing; `fix` enables the destination and adds missing events first. */
638 stripe(fix?: boolean, by?: string): Promise<StripeStatus>;
639 /** Where an enterprise's invoices go; makes its Stripe customer. */
640 enterpriseBilling(id: string, email: string, by: string): Promise<Result<PayingAccount>>;
Merge Stripe Tax, the card fee on card payments, and one free workspace per person641 /** The enterprise's billing address and tax ID, on its Stripe customer: Stripe Tax works its invoices out from them. */
642 enterpriseAddress(id: string, address: PostalAddress, taxIdType: string | null, taxId: string | null, by: string): Promise<Result<boolean>>;
Download ZIP reads blobs eight batches at a time and deflates files together643 /** Sends an enterprise its invoice now, for what its workspaces owe. */
644 invoiceEnterprise(id: string, by: string): Promise<Result<EnterpriseInvoice>>;
645 /** Exactly these workspaces' accounts, such as one page of the list. */
646 accountsFor(workspaces: string[]): Promise<AccountSummary[]>;
647 /** Every workspace worth reaching out to, most urgent first. */
648 signals(): Promise<Signal[]>;
649 /** The business at a glance. */
650 overview(): Promise<Overview>;
651 /** A workspace's sales record. */
652 sales(workspace: string): Promise<SalesRecord>;
653 setSales(workspace: string, record: { stage: string; owner?: string | null; nextStep?: string | null; nextAt?: string | null }, by: string): Promise<Result<SalesRecord>>;
654 addNote(workspace: string, text: string, by: string): Promise<Result<SalesRecord>>;
655 /** A workspace's invoices from g1t, for staff. */
656 workspaceInvoices(workspace: string): Promise<WorkspaceInvoice[]>;
657 /** Every invoice g1t has sent, newest first. */
658 allInvoices(filter?: { status?: string; month?: string }): Promise<InvoiceSummary[]>;
659 /** Every change made in sudo and by Stripe, newest first, 100 at a time. */
660 audit(filter?: { by?: string; action?: string; before?: string }): Promise<AdminAction[]>;
661 /** Limit and overage requests, with each workspace's history; `open` by default. */
662 limitRequests(status?: "open" | "approved" | "declined" | "all"): Promise<LimitRequestReview[]>;
663 /** Approve (at the amount asked, or another) or decline; the owner is told in the app and by email. */
664 decideLimitRequest(id: string, decision: "approve" | "decline", amountMicros: number | null, note: string, by: string): Promise<Result<LimitRequest>>;
665 /** The Overages queue. */
666 overages(): Promise<Overage[]>;
667 /** A goodwill credit; no amount is the one-click credit. Larger, or a second in 12 months, needs a reason. */
668 goodwill(workspace: string, amountMicros: number | null, reason: string, by: string, day?: string | null): Promise<Result<LedgerEntry>>;
669 /** Workspaces spending in the last day, fastest first. */
670 velocity(): Promise<Velocity[]>;
671 /** Money that reached g1t outside the card pages, such as a bank transfer: entered as a payment. */
672 recordPayment(workspace: string, amountMicros: number, reference: string, note: string, by: string): Promise<Result<LedgerEntry>>;
673 /** Costs & margin: Cloudflare's bill against what g1t charged, over the last `days` (7 to 90, 30 by default). */
674 costs(days?: number): Promise<CostsReport>;
675 /** The open margin alerts, for the banner on every page. */
676 costAlerts(): Promise<MarginAlert[]>;
677 /** g1t's own spend against its caps: the daily breaker and comped budgets. */
678 spendCaps(): Promise<SpendCaps>;
679 /** Lets hosted-model runs start again for the rest of today (UTC); needs a note. */
680 liftBreaker(note: string, by: string): Promise<Result<SpendCaps>>;
Merge platform pause and the hourly usage watcher: staff can pause compute, schedules, indexing or renders for everyone, the watcher emails on a breach and is never blind quietly, and the models proxy holds each run to its cap (billing 0051, integrations 0006)681 /** Platform pauses, the last hour of platform usage, the month so far and the last day's breaches (billing's platform.rs). */
682 platformGuard(): Promise<PlatformGuard>;
683 /** Pauses or resumes one level across g1t; needs a note, recorded in the audit log. */
684 setPause(level: PauseLevel, paused: boolean, note: string, by: string): Promise<Result<PlatformGuard>>;
Download ZIP reads blobs eight batches at a time and deflates files together685 /** Approve or reject a price proposal; a rejection needs a note. An approved rise waits out the notice period. */
686 decideProposal(id: string, decision: "approve" | "reject", note: string, by: string): Promise<Result<PriceProposal>>;
687 setCostSettings(settings: CostSettings, by: string): Promise<Result<CostSettings>>;
688 setCostMapping(mapping: CostMappingInput, by: string): Promise<Result<CostMapping>>;
689 /** Reads Cloudflare's bill and reconciles now, as the daily run does. */
690 runCosts(by: string): Promise<Result<CostsRun>>;
Merge branch 'main' into actions-toolkit-oidc-artifacts691 /** Agents & models: the catalogue, each purpose's default, and the latest checks. */
692 models(): Promise<AdminModels>;
693 /** Approve a model (its prices confirmed), retire it, or restore it. Needs a reason. */
694 decideModel(
695 model: string,
696 decision: "approve" | "retire" | "restore",
697 details: { name?: string | null; tierHint?: string | null; prices?: ModelPrices | null },
698 reason: string,
699 by: string,
700 ): Promise<Result<CatalogueModel>>;
701 /** One purpose's default: a model, or for a job its tier and effort. Needs a reason. */
702 setModelDefault(
703 purpose: string,
704 value: { model?: string | null; tier?: string | null; effort?: string | null },
705 reason: string,
706 by: string,
707 ): Promise<Result<ModelDefault>>;
Download ZIP reads blobs eight batches at a time and deflates files together708}
709
710/** How much a workspace has earned g1t's trust with money. */
711export type Trust = "new" | "paid" | "established" | "reviewed" | "internal";
712
713/**
714 * How far a workspace's unpaid usage has gone this month, and where its
715 * work stops: past `ceilingMicros`, no new sandboxes, builds or app
716 * requests. Usage counts at its cost to g1t or its charge, whichever is
717 * more, so it counts while g1t is free too.
718 */
719export type Limit = {
720 workspace: string;
721 /** The account that pays: the workspace's own (`ws_<slug>`), or its enterprise's. */
722 account: string;
723 accountName: string;
724 trust: Trust;
725 exposureMicros: number;
726 /** The lower of g1t's ceiling and the owner's spend limit; null for g1t's own. */
727 ceilingMicros: number | null;
728 trustCeilingMicros: number | null;
729 spendLimitMicros: number | null;
730 state: "ok" | "warning" | "stopped";
731 message: string | null;
Spend adds up on one ledger. Charged this month has one definition, price less discount, included usage and credit, shared by the plan card, the spend limit, Spend and the top bar; the limit had counted usage not yet closed at full price before the discount, so a comped workspace read as charged a cent. Every agent line on the ledger names the agent and who asked, repository runs by g1t included, so Spent is the sum of its products, Agents is the agent product, and by agent adds up to it; the billing API returns by_agent and by_person. The usage and billing guide says how spend is counted.732 /**
733 * Charged this month, which the spend limit is measured against: usage at
734 * price less the discount, included usage, the trial, pools and credit,
735 * with usage metered through the month counted on the same terms. The
736 * same number as the month's `UsageTotals.chargedMicros`.
737 */
Download ZIP reads blobs eight batches at a time and deflates files together738 spentMicros?: number;
739 /** True while the owners have not chosen a limit, so the automatic one applies: $200, or twice last month's spend. */
740 defaultSpendLimit?: boolean;
741 /** The most owners may set their own limit to without asking: the highest ceiling ever, plus what is prepaid. */
742 availableMicros?: number | null;
743 /** How the ceiling grows from here, in a sentence. */
744 growth?: string | null;
745 /** Paid in advance and not used yet; raises what can be used before work stops by as much. */
746 prepaidMicros?: number;
747 /** The highest ceiling the workspace has had. */
748 maxCeilingMicros?: number | null;
749 /** The most owners may raise the limit to themselves, once: twice the highest ceiling. Null once used. */
750 raiseOnceMicros?: number | null;
751 /** When the one-time raise was used. */
752 raisedAt?: string | null;
753 /** A paid workspace's first billing cycle, on the starting ceiling. */
754 firstMonth?: boolean;
Usage, Billing settings and prepaid AI credit; fixes from the UX audit755 /** The budget's alerts, in percent of the spend limit: some of 50, 75, 90 and 100. */
756 alertLevels?: number[];
757 /** Whether usage pauses at the spend limit (the default); off, it only alerts. */
758 pauseAtLimit?: boolean;
759 /** An HTTPS address told of each budget alert. */
760 budgetWebhook?: string | null;
Download ZIP reads blobs eight batches at a time and deflates files together761};
762
763/** One metered unit: what it costs g1t and what it is sold at; the price follows the cost. */
764export type Price = {
765 meter:
766 | "sandbox_second"
767 | "build_second"
768 | "app_requests"
769 | "app_cpu"
770 | "app_month"
771 | "custom_domain_month"
772 | "private_storage"
773 | "embedding_tokens"
774 | "scan_cpu"
775 | "scan_rows"
776 | string;
777 title: string;
778 unit: string;
779 costMicros: number;
780 markupPercent: number;
781 priceMicros: number;
782 /** `list`: Cloudflare's published price. `cloudflare`: measured from Cloudflare's bill. */
783 source: "list" | "cloudflare" | string;
784 checkedAt: string | null;
785 updatedAt: string;
786};
787
788export type PriceChange = {
789 meter: string;
790 oldCostMicros: number;
791 newCostMicros: number;
792 markupPercent: number;
793 /** The markup before, when the change was to the markup rather than the cost. */
794 oldMarkupPercent?: number;
795 reason: string;
796 createdAt: string;
797 /** When a change still to come takes effect: a rise is announced before it is charged. */
798 effectiveAt?: string;
799};
800
801export type PriceBook = {
802 prices: Price[];
803 changes: PriceChange[];
804 modelMarginPercent: number;
805 /** Every plan, as sold now. */
806 plans?: FeaturePlan[];
807 /** What is free, and the capped budgets that pay for it. */
808 free?: FreeTier | null;
809};
810
811/** One kind of meter's usage this month, from `usage_meters`. */
812export type MeterUsage = {
813 /** `agents`, `builds`, `requests`, `domains`, `git_storage` or `search_scans`. */
814 key: string;
815 label: string;
816 /** At price (cost plus 20%, on the account's terms), before what paid for it. */
817 micros: number;
818 /** How much, when it is known: `12 runs`, `41 build minutes`. */
819 quantity?: string | null;
820};
821
822/** What g1t gives without a plan; each is paid for by a capped budget. */
823export type FreeTier = {
824 /** Each new workspace's trial credit, once. */
825 trialWorkspaceMicros: number;
826 /** Trial grants each month, in all; new trials wait when it is spent. */
827 trialMonthlyPoolMicros: number;
828 /** g1t's open-source pool each month, and any one repository's share. */
829 ossPoolMicros: number;
830 ossRepoMicros: number;
831 /** Private repository storage free for every workspace. Past it, the plan pays; a free workspace's pushes stop. */
832 freePrivateStorageBytes: number;
833 /** Days of audit log a free workspace keeps. */
834 auditRetentionDays: number;
835 /** Days of audit log the g1t plan keeps, and g1t's own and enterprise workspaces; longer by arrangement. */
836 planAuditRetentionDays?: number;
837 /** The smallest amount a card is charged when a month closes; less carries over. */
838 minChargeMicros: number;
839 /** Git operations free for every workspace each month. Past it, the plan pays; a free workspace is slowed down. */
840 gitOperationsIncluded?: number;
841 /** A new paid workspace's ceiling in its first month. */
842 paidStartCeilingMicros?: number;
843 /** The most a one-click goodwill credit can cost g1t. */
844 overageForgiveCostMicros?: number;
845};
846
847/**
848 * A workspace's trial credit: one grant per workspace, made the first time
849 * it uses something, out of a pool that resets each calendar month. Mirrors
850 * `Trial` in `crates/contracts/src/billing.rs`.
851 */
852export type Trial = {
853 open: boolean;
854 usedMicros: number;
855 limitMicros: number;
856 /** No longer used: trials do not end on a date. */
857 endsAt: string | null;
858 /** Why it is closed: `off`, `used` (this workspace's grant is spent) or `pool` (this month's are given out). */
859 reason: "off" | "ended" | "used" | "pool" | null;
860 /** Whether the workspace has its grant already. */
861 granted?: boolean;
862 /** With `pool`: when new trials start again, the first of next month. */
863 waitsUntil?: string | null;
864};
865
866/**
Pricing says it plainly: models at the provider's price, the agent rate for what g1t runs around every model call (the gateway, secrets, routing, context and pass-through to your own provider, so your own keys too), everything else at cost plus 20%, your own runners free, no seats; Security and quality comes with the plan with no separate fee, and live activations end. Each agent has an effort setting, Auto to Max, with what a typical task has cost at each level, and Spend's Spend less, keep quality suggests a lower level only when the agent's own past work shows quality held, to apply or dismiss. The pricing, spend and agents guides say how.867 * What a workspace has: the g1t plan (`plan`), and Security and quality
868 * (`security`), which comes with the plan at no price of its own. Deployments
869 * are part of the plan too; `has_feature` for either answers whether the
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar870 * workspace has the plan. Mirrors `Feature` in `crates/contracts/src/billing.rs`.
Download ZIP reads blobs eight batches at a time and deflates files together871 */
Teams and CODEOWNERS, labels and milestones, dependency updates, the security suite, and a clearer top bar872export type Feature = "plan" | "deployments" | "security";
Download ZIP reads blobs eight batches at a time and deflates files together873
874/**
875 * What deployments cost g1t, in millionths of a dollar: fallbacks for when
876 * billing's price book cannot be read. Not an allowance: on the plan every
877 * unit is metered from the first, at cost plus 20%, and drawn from the
878 * plan's included usage first. Projects, previews and the apps behind them
879 * are not metered at all. Mirrors `deployment_costs`.
880 */
881export const DEPLOYMENT_COSTS = {
882 microsPerMillionRequests: 300_000,
883 microsPerMillionCpuMs: 20_000,
884 /** One second of a build's sandbox: a fallback; billing charges the price book's `build_second`. */
885 microsPerBuildSecond: 15,
886 /** One custom domain for a month. */
887 microsPerDomainMonth: 100_000,
Merge GitHub pull request #8 (claude/cool-newton-7nm8r9): Docker deployments on g1t.page behind a switch that stays off until Cloudflare's container APIs are checked live, workflows a workspace manages in its repositories, tarball and zipball downloads, refs/pull/* kept to g1t alone, framework detection for g1t.page builds, and a workflow's event payload matching GitHub's.888 /**
889 * Container apps, at Cloudflare Containers' list prices: a vCPU-second
890 * $0.00002, a GiB-second of memory $0.0000025, a GB-second of disk
891 * $0.00000007, the Durable Object in front of each instance while it
892 * runs (128 MB at $12.50 per million GB-seconds), and a GB of egress
893 * at $0.05, the most Cloudflare charges for one anywhere (Oceania, Korea
894 * and Taiwan; $0.025 in North America and Europe), since g1t cannot
895 * tell where a container's traffic went.
896 */
897 container: {
898 vcpuSecond: 20,
899 memoryGibSecond: 2.5,
900 diskGbSecond: 0.07,
901 instanceSecond: 1.5625,
902 egressGb: 50_000,
903 },
Download ZIP reads blobs eight batches at a time and deflates files together904} as const;
905
906export type FeaturePlan = {
907 feature: Feature;
908 title: string;
Merge Stripe Tax, the card fee on card payments, and one free workspace per person909 /** Charged every month while the plan is on, in cents, excluding tax. */
Download ZIP reads blobs eight batches at a time and deflates files together910 monthlyCents: number;
Merge Stripe Tax, the card fee on card payments, and one free workspace per person911 /** The card processing fee on top each month, in cents (0 when off), excluding tax. */
912 cardFeeCents?: number;
Download ZIP reads blobs eight batches at a time and deflates files together913 /** What the price includes, one line each. */
914 includes: string[];
915 /** How usage past the allowance is charged. */
916 overage: string;
917};
918
919export type SubscriptionStatus = "active" | "canceling" | "past_due" | "canceled";
920
921export type Subscription = {
922 feature: Feature;
923 status: SubscriptionStatus;
924 /** RFC 3339: when the period paid for ends. */
925 periodEnd: string | null;
926 startedBy: string;
927 startedAt: string;
928};
929
930/** A feature as a workspace sees it. */
931export type FeatureState = {
932 plan: FeaturePlan;
933 subscription: Subscription | null;
934 /** Whether the feature works for the workspace now. */
935 on: boolean;
936 /** On without a plan: comped terms, or given by g1t. Nothing to pay or turn off. */
937 included?: boolean;
938};
939
940export interface BillingApi {
941 status(): Promise<BillingStatus>;
942 /** Members of the workspace only. */
943 account(workspace: string, viewer: Viewer): Promise<Result<BillingAccount>>;
944 /** Newest first. Members of the workspace only. */
945 ledger(workspace: string, viewer: Viewer): Promise<Result<LedgerEntry[]>>;
Billing: credits with a kind and expiry, discounts instead of comped, and safer charging946 /** Credits from g1t, newest first, with what is left of each. Members only. */
947 credits(workspace: string, viewer: Viewer): Promise<Result<Credits>>;
Download ZIP reads blobs eight batches at a time and deflates files together948 /** A month of the ledger, grouped by `day` (default) or `project`. Members only. */
949 statement(workspace: string, viewer: Viewer, month?: string | null, group?: "day" | "project"): Promise<Result<Statement>>;
950 /** One statement line's entries, 50 at a time; `before` is the last id seen. */
951 statementEntries(
952 workspace: string,
953 viewer: Viewer,
954 filter: { month: string; kind: string; day?: string | null; project?: string | null; before?: string | null },
955 ): Promise<Result<LedgerEntry[]>>;
956 /** What the workspace's agents cost since `since`, broken down. Members only. */
957 usage(workspace: string, viewer: Viewer, since: string): Promise<Result<Usage>>;
958 /**
959 * The model tokens the workspace's runs used, day by day over the last
960 * `days` (42, at most 366), for everyone or for one `person`. Members
961 * only; a member may ask only for themselves, an owner for anyone.
962 */
963 tokenUsage(workspace: string, viewer: User, options?: { person?: string; days?: number }): Promise<Result<TokenUsage>>;
964 /**
965 * What one model answer used, added to its run's count for the day. The
966 * model proxy sends it; for usage views only, as runs are priced from AI
967 * Gateway. False when there was nothing to count.
968 */
Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens969 /** What the AI Gateway offers on g1t's key, with prices per million tokens. */
970 gatewayModels(): Promise<GatewayModel[]>;
Merge branch 'main' into actions-toolkit-oidc-artifacts971 /** Every purpose's default model as it applies now, and each job's tier and effort. */
972 modelDefaults(): Promise<ModelDefaults>;
973 /** What one provider lists now, from the models service's discovery. */
974 recordDiscovery(provider: string, models: ProviderModel[], by: string, error?: string | null): Promise<DiscoveryResult>;
Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens975 /**
976 * Whether a workspace's next AI Gateway request may go to g1t's models:
977 * fails with `payment_required` and what to do when it is over its spend
978 * limit, out of AI credit, or not on the plan.
979 */
980 gatewayAdmit(workspace: string): Promise<Result<boolean>>;
981 /** Logs one AI Gateway request, and charges it when it used tokens on g1t's models. */
982 recordGateway(record: GatewayRecord): Promise<Result<boolean>>;
983 /** A workspace's recent AI Gateway requests, newest first. Members only. */
984 gatewayRequests(workspace: string, viewer: Viewer, options?: { limit?: number; before?: string | null }): Promise<Result<GatewayRequests>>;
Download ZIP reads blobs eight batches at a time and deflates files together985 recordTokens(usage: {
986 workspace: string;
987 /** The model session's id, one per run. */
988 session: string;
989 /** The person the run is for, by username. */
990 person?: string | null;
991 model: string;
Merge branch 'model-routing'992 tier?: "small" | "large" | "frontier" | null;
Download ZIP reads blobs eight batches at a time and deflates files together993 input: number;
994 output: number;
995 cacheRead: number;
996 cacheWrite: number;
997 }): Promise<Result<boolean>>;
998 /**
999 * Prepays usage ($25 at least) and returns the page to send the person to:
1000 * by card with 3-D Secure, or by bank transfer from $1,000. Owners only.
1001 * The payment's id comes back to `returnUrl` as `session`.
1002 */
1003 checkout(
1004 actor: User,
1005 workspace: string,
1006 amountCents: number,
1007 returnUrl: string,
1008 method?: "card" | "bank_transfer",
1009 ): Promise<Result<{ url: string }>>;
1010 /**
1011 * Stripe's hosted billing page for the workspace: card, invoices, billing
1012 * email and address. g1t never handles card numbers. Owners only.
1013 */
1014 billingPortal(actor: User, workspace: string, returnUrl: string): Promise<Result<{ url: string }>>;
1015 /** Credits a payment once the processor says it was made. Safe to repeat. */
1016 confirm(workspace: string, viewer: Viewer, session: string): Promise<Result<BillingAccount>>;
1017 /**
1018 * Whether a workspace may start an agent now, asked before anything is
1019 * opened for it. A failure, with the reason to show, when it has no credit.
1020 */
1021 canStart(workspace: string): Promise<Result<boolean>>;
1022 /** A workspace's free allowance on g1t's hosted models; `exempt` are open to them anyway. */
1023 trial(workspace: string, exempt: string[]): Promise<Trial>;
1024 /**
1025 * Asks whether a workspace may start an agent and opens the run it will be
1026 * charged for. Null when billing is off; a failure when there is no credit.
1027 */
1028 /** Every paid feature and the workspace's plan for each. Members only. */
1029 features(workspace: string, viewer: Viewer): Promise<Result<FeatureState[]>>;
1030 /**
1031 * Starts the card page for a feature's monthly plan. Owners only. The
1032 * page's id comes back to `returnUrl` as `session`.
1033 */
1034 subscribe(actor: User, workspace: string, feature: Feature, returnUrl: string): Promise<Result<{ url: string }>>;
1035 /** Turns the feature on once the plan is paid for. Safe to repeat. */
1036 confirmSubscription(workspace: string, viewer: Viewer, session: string): Promise<Result<FeatureState>>;
1037 /** Ends a plan at the end of its period, or (`resume`) takes that back. Owners only. */
1038 cancelSubscription(actor: User, workspace: string, feature: Feature, resume?: boolean): Promise<Result<FeatureState>>;
Merge Stripe Tax, the card fee on card payments, and one free workspace per person1039 /** Which of the workspaces are free (on no paid plan); none where payments are not set up. */
1040 freeWorkspaces(workspaces: string[]): Promise<string[]>;
Download ZIP reads blobs eight batches at a time and deflates files together1041 /** Whether a feature works for a workspace now; a failure with the reason when not. */
1042 hasFeature(workspace: string, feature: Feature): Promise<Result<boolean>>;
1043 /**
1044 * Usage past a plan's allowance, charged from credit at cost plus the
1045 * margin, once per `reference`. False if it was charged before.
1046 */
1047 chargeFeature(charge: {
1048 workspace: string;
1049 feature: Feature;
1050 costMicros: number;
1051 description: string;
1052 repo?: string | null;
1053 reference: string;
1054 /** For a build: how long it ran, so the plan's included build time pays for what it can. */
1055 buildSeconds?: number | null;
1056 }): Promise<Result<boolean>>;
1057 /**
1058 * What a source cost g1t so far this month, so the workspace's limit
1059 * counts it now. Replaces the last report. Billing charges `context`
1060 * and `security` itself once the month is over; `deployments` charges
1061 * its own.
1062 */
1063 notePending(
1064 workspace: string,
1065 source: "deployments" | "domains" | "context" | "security",
1066 costMicros: number,
1067 /** How much of it, for the Billing page: `1.2 million requests and 3.4 million CPU ms`. */
1068 detail?: string | null,
1069 ): Promise<boolean>;
1070 /**
1071 * This month's usage, one line per kind of meter, at what it is charged
1072 * before the plan's included usage or a pool paid for it. Members only.
1073 */
1074 usageMeters(workspace: string, viewer: Viewer): Promise<Result<MeterUsage[]>>;
1075 /** What the workspace may do now: its plan, caps, pause, trial, and what the plan gives it. */
1076 entitlements(workspace: string): Promise<Entitlements>;
1077 /**
1078 * Holds a start's estimated cost before the work starts. A failure's code says why not:
1079 * `paused`, `limit`, `not_paid`, `trial_used` or `oss_pool_empty`, with a message for the owner.
1080 */
1081 reserve(reservation: {
1082 workspace: string;
1083 repo: RepoPath;
1084 public: boolean;
1085 kind: ComputeKind;
1086 /** The most the work is expected to cost g1t, before the margin. */
1087 estimateMicros: number;
1088 }): Promise<Result<ReservationHeld>>;
1089 /** Releases a reservation's hold with what the work cost g1t, before the margin. Safe to repeat. */
1090 settle(reservationId: string, actualMicros: number): Promise<Result<boolean>>;
1091 /** Stripe's page to save and verify a card (3-D Secure, never charged). Owners only. */
1092 cardCheck(actor: User, workspace: string, returnUrl: string): Promise<Result<{ url: string }>>;
1093 /** Records the card check once Stripe says it passed, and grants the trial if it can. Safe to repeat. */
1094 confirmCardCheck(workspace: string, viewer: Viewer, session: string): Promise<Result<Entitlements>>;
1095 /** An owner asks for a higher limit, or for help with usage past what was meant. */
1096 requestLimit(
1097 actor: User,
1098 workspace: string,
1099 request: { kind: "limit" | "overage"; amountMicros: number; reason: string; expectedMonthlyMicros: number },
1100 ): Promise<Result<LimitRequest>>;
1101 /** The workspace's requests and their answers, newest first. Members only. */
1102 limitRequests(workspace: string, viewer: Viewer): Promise<Result<LimitRequest[]>>;
1103 /**
1104 * The owners' own caps on agents: one run's spend ($0.10 to $100) and one issue's ($1 to $1,000).
1105 * Null goes back to the default ($2 and $10). A cap staff set wins. Owners only.
1106 */
1107 setCaps(actor: User, workspace: string, caps: { runCapMicros: number | null; issueCapMicros: number | null }): Promise<Result<Entitlements>>;
1108 /** An owner's answer to a spend spike: keep going for 24 hours, or stop. */
1109 confirmSpike(actor: User, workspace: string, keepGoing: boolean): Promise<Result<Entitlements>>;
1110 /** Every metered price and the recent changes. Public. */
1111 prices(): Promise<PriceBook>;
1112 /** A workspace's limit, for its members. */
1113 limit(workspace: string, viewer: Viewer): Promise<Result<Limit>>;
1114 /** The same, for the services that enforce it. */
1115 checkLimit(workspace: string): Promise<Result<Limit>>;
1116 /**
1117 * The owners' own monthly limit, up to what is available; null goes back
1118 * to the default, and `useFullLimit` uses everything available. Owners only.
1119 */
1120 setSpendLimit(
1121 actor: User,
1122 workspace: string,
1123 spendLimitMicros: number | null,
1124 useFullLimit?: boolean,
1125 /** Use the one-time raise: up to twice the highest ceiling, once per workspace. */
1126 raiseOnce?: boolean,
1127 ): Promise<Result<Limit>>;
1128 /** The workspace's invoices from g1t, newest first. Members only. */
1129 invoices(workspace: string, viewer: Viewer): Promise<Result<WorkspaceInvoice[]>>;
1130 /**
1131 * How long a sandbox ran for a workspace, reported when it stops. Its
1132 * cost is recorded and every second is charged, from the first. False if
1133 * `reference` was recorded before.
1134 */
1135 recordSandbox(usage: {
1136 workspace: string;
1137 seconds: number;
1138 description: string;
1139 repo?: string | null;
1140 reference: string;
1141 /** What ran; checks, workflows and the merge queue on public repositories may use the open-source pool. */
1142 kind?: ComputeKind | null;
1143 /** vCPU-seconds used, when the sandbox can tell: the run is priced on its own CPU. */
1144 cpuSeconds?: number | null;
1145 /** The reservation it started under, settled with this cost. */
1146 reservationId?: string | null;
1147 /** It ran on one of the workspace's self-hosted runners: its minutes go on usage at $0. */
1148 selfHosted?: boolean;
1149 /** The machine it ran on, by label (`g1t-4core`); absent, the standard one. */
1150 instance?: string | null;
Spend adds up on one ledger. Charged this month has one definition, price less discount, included usage and credit, shared by the plan card, the spend limit, Spend and the top bar; the limit had counted usage not yet closed at full price before the discount, so a comped workspace read as charged a cent. Every agent line on the ledger names the agent and who asked, repository runs by g1t included, so Spent is the sum of its products, Agents is the agent product, and by agent adds up to it; the billing API returns by_agent and by_person. The usage and billing guide says how spend is counted.1151 /** The agent whose work this was, by handle (`g1t` for g1t's own runs on a repository); absent for checks, workflows and builds. */
1152 agent?: string | null;
1153 /** Who asked for the work, by username. */
1154 askedBy?: string | null;
Download ZIP reads blobs eight batches at a time and deflates files together1155 }): Promise<Result<boolean>>;
1156 startRun(run: {
1157 workspace: string;
1158 repo: RepoPath;
1159 number: number;
1160 task: string;
1161 model: string;
1162 /** `workspace` when the run uses the workspace's own model provider. */
1163 billedTo?: "g1t" | "workspace";
Merge branch 'model-routing'1164 /**
1165 * The model session's id: the run is settled at AI Gateway's price by
1166 * it, and on the workspace's own provider its tokens are counted under
1167 * it for the agent rate.
1168 */
Download ZIP reads blobs eight batches at a time and deflates files together1169 session?: string | null;
Merge branch 'model-routing'1170 /** The tier g1t routed the run to: `small`, `large` or `frontier`. */
1171 tier?: "small" | "large" | "frontier" | null;
Spend adds up on one ledger. Charged this month has one definition, price less discount, included usage and credit, shared by the plan card, the spend limit, Spend and the top bar; the limit had counted usage not yet closed at full price before the discount, so a comped workspace read as charged a cent. Every agent line on the ledger names the agent and who asked, repository runs by g1t included, so Spent is the sum of its products, Agents is the agent product, and by agent adds up to it; the billing API returns by_agent and by_person. The usage and billing guide says how spend is counted.1172 /** The agent doing the work, by handle: a workspace agent's, or `g1t` for g1t's own work on a repository. Every line of the run carries it. */
1173 agent?: string | null;
1174 /** Who asked, by username; none for a routine's or another agent's work. */
1175 askedBy?: string | null;
Download ZIP reads blobs eight batches at a time and deflates files together1176 }): Promise<Result<RunTicket | null>>;
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1177 /** Usage over a range of days (`YYYY-MM-DD`, both included), at price, by product, meter, project and day. Members only. */
1178 usageReport(
1179 workspace: string,
1180 viewer: Viewer,
1181 range: { from: string; until: string; products?: string[]; projects?: string[] },
1182 ): Promise<Result<UsageReport>>;
1183 /** The workspace's prepaid AI credit, auto-reload and prices. Members only. */
1184 aiCredit(workspace: string, viewer: Viewer): Promise<Result<AiCredit>>;
1185 /** Stripe's page to buy AI credit ( to ,000, the card fee on its own line). Owners only. The page's id comes back to `returnUrl` as `ai_credit`. */
1186 buyAiCredit(actor: User, workspace: string, amountCents: number, returnUrl: string): Promise<Result<{ url: string }>>;
1187 /** Credits a purchase once Stripe says it was paid, once. Safe to repeat. */
1188 confirmAiCredit(workspace: string, viewer: Viewer, session: string): Promise<Result<AiCredit>>;
1189 /** Auto-reload's settings. Owners only. */
1190 setAiReload(
1191 actor: User,
1192 workspace: string,
1193 reload: { enabled: boolean; thresholdMicros: number; targetMicros: number; monthlyMaxMicros: number },
1194 ): Promise<Result<AiCredit>>;
1195 /** The monthly budget: the spend limit, its alerts, whether usage pauses at 100%, and a webhook. Owners only. */
1196 setBudget(
1197 actor: User,
1198 workspace: string,
1199 budget: { amountMicros: number | null; alerts: number[]; pauseAtLimit: boolean; webhook: string | null; keepLimit?: boolean },
1200 ): Promise<Result<Limit>>;
1201 /** Invoice details from the Stripe customer, the default payment method, invoices and the next invoice. Members only. */
1202 billingDetails(workspace: string, viewer: Viewer): Promise<Result<BillingDetails>>;
1203 /** Saves invoice details on the Stripe customer; absent fields stay, empty clears. Owners only. */
1204 setBillingDetails(actor: User, workspace: string, details: BillingDetailsInput): Promise<Result<BillingDetails>>;
Download ZIP reads blobs eight batches at a time and deflates files together1205}
1206
1207
1208/** One slice of usage: what it was for, what it cost, how many runs. */
1209export type UsageSlice = { key: string; micros: number; runs: number };
1210
1211/** The model tokens runs used over a window of days. */
1212export type TokenUsage = {
1213 /** `YYYY-MM-DD`, the first day counted. */
1214 since: string;
1215 /** The window's length: 42 unless asked, 366 at most. */
1216 days: number;
1217 /** Null for the whole workspace. */
1218 person: string | null;
1219 totalTokens: number;
1220 inputTokens: number;
1221 outputTokens: number;
1222 cacheReadTokens: number;
1223 cacheWriteTokens: number;
1224 /** What those runs were charged, as `usage` measures it. */
1225 costMicros: number;
1226 /** Days in the window with any tokens. */
1227 activeDays: number;
1228 /** Every day in the window, oldest first, zeros included. */
1229 byDay: { day: string; tokens: number }[];
1230};
1231
Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens1232// --- AI Gateway -------------------------------------------------------------
1233
1234/** A model the AI Gateway offers on g1t's key, with its prices per million tokens. */
1235export type GatewayModel = {
AI Gateway: OpenAI's format, open models, and your own providers1236 /**
1237 * The provider's own id, such as `claude-sonnet-5-5` or
1238 * `@cf/openai/gpt-oss-120b`. A request names it as it is or with its
1239 * provider in front (`anthropic/claude-sonnet-5-5`).
1240 */
Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens1241 model: string;
1242 /** For people: `Claude Sonnet 5.5`. */
1243 name: string;
AI Gateway: OpenAI's format, open models, and your own providers1244 /** `anthropic` or `workers-ai`. */
Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens1245 provider: string;
AI Gateway: OpenAI's format, open models, and your own providers1246 /** `chat`, or `embeddings` for a model that only embeds text. */
1247 kind?: "chat" | "embeddings";
Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens1248 inputMicros: number;
1249 outputMicros: number;
1250 cacheReadMicros: number;
AI Gateway: OpenAI's format, open models, and your own providers1251 /** Cache writes that live five minutes. */
Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens1252 cacheWriteMicros: number;
AI Gateway: OpenAI's format, open models, and your own providers1253 /** Cache writes that live an hour. */
1254 cacheWrite1hMicros?: number;
1255 /**
1256 * Priced by the prompt's length: a request whose prompt (input, cache
1257 * read and cache write tokens) is longer than this is charged entirely at
1258 * the `over` prices. 0 or absent for one price.
1259 */
1260 threshold?: number;
1261 overInputMicros?: number;
1262 overOutputMicros?: number;
1263 overCacheReadMicros?: number;
1264 overCacheWriteMicros?: number;
1265 overCacheWrite1hMicros?: number;
Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens1266};
1267
Merge branch 'main' into actions-toolkit-oidc-artifacts1268// --- The model catalogue ------------------------------------------------------
1269
1270/** Where a model stands: only `available` ones are routed to. */
1271export type ModelStatus = "available" | "new" | "deprecated" | "retired";
1272
1273/** One model in g1t's catalogue: its prices and what g1t knows about it. */
1274export type CatalogueModel = GatewayModel & {
1275 /** Other ids the provider lists it by, such as a dated one. */
1276 aliases: string[];
1277 family: string;
1278 /** The agent tier it suits: `small`, `large`, `frontier`, or empty. */
1279 tierHint: string;
1280 contextWindow: number;
1281 maxOutput: number;
1282 /** Any of `effort`, `thinking`, `tools`, `vision`, `embeddings`. */
1283 capabilities: string[];
1284 dimensions: number;
1285 status: ModelStatus;
1286 /** Its prices are known. An unpriced model is never routed to, offered or charged for. */
1287 priced: boolean;
1288 source: "discovered" | "staff";
1289 firstSeenAt: string | null;
1290 lastSeenAt: string | null;
1291 missingSince: string | null;
1292 approvedBy: string | null;
1293 approvedAt: string | null;
1294 note: string;
1295 /** A typical agent run on it, in millionths of a dollar; 0 when unpriced or embeddings. */
1296 typicalRunMicros: number;
1297};
1298
1299/** One model as its provider lists it, from the models service's discovery. */
1300export type ProviderModel = {
1301 id: string;
1302 name: string;
1303 /** `chat`, `embeddings`, or anything else (counted as listed, never added). */
1304 kind: string;
1305 contextWindow: number;
1306 maxOutput: number;
1307 capabilities: string[];
1308 /** Workers AI lists a price per million tokens; Anthropic does not. */
1309 price: { inputMicros: number; outputMicros: number } | null;
1310};
1311
1312/** What one check of a provider found. */
1313export type DiscoveryResult = {
1314 provider: string;
1315 checkedAt: string;
1316 by: string;
1317 listed: number;
1318 added: string[];
1319 deprecated: string[];
1320 restored: string[];
1321 error: string | null;
1322};
1323
1324/** The purposes a default model is chosen for. */
1325export type ModelPurpose = "tier_small" | "tier_large" | "tier_frontier" | "background" | "gateway_first";
1326
1327/** One purpose's default, as staff last set it. */
1328export type ModelDefault = {
1329 /** A `ModelPurpose`, or `job_<kind>`. */
1330 purpose: string;
1331 model: string | null;
1332 /** For a job: `small`, `large`, `frontier` or `change`. */
1333 tier: string | null;
1334 effort: string | null;
1335 updatedAt: string;
1336 updatedBy: string;
1337 reason: string;
1338};
1339
1340/** A model purpose's default as it applies now. */
1341export type ResolvedModel = {
1342 purpose: string;
1343 chosen: string;
1344 /** The model to use; null when nothing suits (callers keep their own fallback). */
1345 model: GatewayModel | null;
1346 capabilities: string[];
1347 /** Why it is not the chosen model, in a sentence. */
1348 note: string | null;
1349};
1350
1351/** One kind of agent job's starting tier and effort. */
1352export type JobDefault = { kind: string; tier: string; effort: string | null };
1353
1354/** Every purpose's model as it applies now, and each job's tier and effort. */
1355export type ModelDefaults = { models: ResolvedModel[]; jobs: JobDefault[] };
1356
1357/** One check of one provider. */
1358export type ModelCheck = {
1359 id: string;
1360 provider: string;
1361 checkedAt: string;
1362 by: string;
1363 listed: number;
1364 added: string[];
1365 deprecated: string[];
1366 error: string | null;
1367};
1368
1369/** The tokens of the typical agent run estimates are priced from. */
1370export type TypicalRun = { requests: number; input: number; output: number; cacheRead: number; cacheWrite: number };
1371
1372/** sudo's Agents & models. */
1373export type AdminModels = {
1374 catalogue: CatalogueModel[];
1375 defaults: ModelDefault[];
1376 resolved: ModelDefaults;
1377 checks: ModelCheck[];
1378 typical: TypicalRun;
1379};
1380
1381/** A model's prices as staff confirm them, per million tokens in millionths of a dollar. */
1382export type ModelPrices = {
1383 inputMicros: number;
1384 outputMicros: number;
1385 cacheReadMicros: number;
1386 cacheWriteMicros: number;
1387 cacheWrite1hMicros: number;
1388 threshold: number;
1389 overInputMicros: number;
1390 overOutputMicros: number;
1391 overCacheReadMicros: number;
1392 overCacheWriteMicros: number;
1393 overCacheWrite1hMicros: number;
1394};
1395
1396/** The models service's `Discovery` entrypoint, for sudo's "Check for new models". */
1397export interface ModelDiscoveryApi {
1398 /** Lists every provider's models now and records what changed: one result per provider. */
1399 check(by: string): Promise<DiscoveryResult[]>;
1400}
1401
AI Gateway: OpenAI's format, open models, and your own providers1402/** The format a gateway request was sent in. */
1403export type GatewayFormat = "anthropic" | "openai";
1404
Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens1405/** One AI Gateway request, as the model proxy reports it to billing. */
1406export type GatewayRecord = {
1407 /** `gw_…`, chosen by the proxy; recording it twice records it once. */
1408 id: string;
1409 workspace: string;
1410 tokenId: string;
1411 tokenName?: string | null;
1412 model: string;
1413 input: number;
1414 output: number;
1415 cacheRead: number;
AI Gateway: OpenAI's format, open models, and your own providers1416 /** Every cache write, of either lifetime. */
Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens1417 cacheWrite: number;
AI Gateway: OpenAI's format, open models, and your own providers1418 /** Of `cacheWrite`, those that live an hour. */
1419 cacheWriteHour?: number;
Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens1420 /** The HTTP status the caller was answered with. */
1421 status: number;
1422 /** On the workspace's own provider key: counted, never charged. */
1423 ownKey: boolean;
AI Gateway: OpenAI's format, open models, and your own providers1424 format: GatewayFormat;
1425 /**
1426 * Who served it: `anthropic` or `workers-ai` on g1t's key, the
1427 * connection's provider on the workspace's own. Empty when it never got
1428 * that far.
1429 */
1430 provider: string;
1431 /** On the workspace's own provider: the connection's name. */
1432 connection?: string | null;
Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens1433 streamed: boolean;
1434 durationMs: number;
1435 error?: string | null;
1436};
1437
1438/** One AI Gateway request, as its log keeps it. */
1439export type GatewayRequest = {
1440 id: string;
1441 createdAt: string;
1442 model: string;
1443 tokenId: string;
1444 tokenName: string | null;
1445 input: number;
1446 output: number;
1447 cacheRead: number;
1448 cacheWrite: number;
AI Gateway: OpenAI's format, open models, and your own providers1449 /** Of `cacheWrite`, those that live an hour. */
1450 cacheWriteHour: number;
Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens1451 /** What the tokens cost at the model's price. */
1452 costMicros: number;
1453 /** What the workspace was charged, before included usage and credit paid for it; 0 on its own key. */
1454 chargedMicros: number;
1455 status: number;
1456 ownKey: boolean;
AI Gateway: OpenAI's format, open models, and your own providers1457 format: GatewayFormat;
1458 /** `anthropic` or `workers-ai` on g1t's key; the connection's provider on the workspace's own. */
1459 provider: string;
1460 /** On the workspace's own provider: the connection's name. */
1461 connection: string | null;
Merge the AI Gateway: Anthropic's Messages API on a workspace's tokens1462 streamed: boolean;
1463 durationMs: number;
1464 error: string | null;
1465};
1466
1467/** A page of AI Gateway requests, newest first. */
1468export type GatewayRequests = {
1469 requests: GatewayRequest[];
1470 /** The `before` for the next page, when there is one. */
1471 next: string | null;
1472 /** How many days requests are kept. */
1473 retentionDays: number;
1474};
1475
Download ZIP reads blobs eight batches at a time and deflates files together1476/** What a workspace's agents cost over a period. */
1477export type Usage = {
1478 since: string;
1479 /** Charged, including g1t's margin. */
1480 spentMicros: number;
Billing and Usage reconcile: own-provider runs leave Billing's at-price total, and Usage's not-charged part is at price less charged1481 /** What g1t's usage came to at price, less what was charged: the plan's included usage, the trial, a pool or a free period paid it. Usage at price is `spentMicros` plus this. */
Billing's usage total is labeled at price, and Usage says what part of it was paid for1482 coveredMicros?: number;
Billing: credits with a kind and expiry, discounts instead of comped, and safer charging1483 /** What the account's discount took off the price; usage at price is spent + covered + this. */
1484 discountMicros?: number;
1485 /** The account's discount now, in percent; with one, the slices are at price. */
1486 discountPercent?: number | null;
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1487 /** Usage at price: spent + covered + discount, from the same ledger lines. The one usage figure every page shows. */
1488 priceMicros?: number;
Download ZIP reads blobs eight batches at a time and deflates files together1489 /** What g1t's model provider charged, before the margin. */
1490 costMicros: number;
1491 /** What runs on the workspace's own provider cost there, estimated. Not charged by g1t. */
1492 providerMicros: number;
1493 /** What the runs used, at cost: g1t's models and the workspace's own provider together. */
1494 usedMicros: number;
1495 /** g1t charges nothing for now; the slices then measure usage at cost. */
1496 free: boolean;
1497 runs: number;
1498 /** Spend per day and task, keyed `YYYY-MM-DD/task`. */
1499 byDay: UsageSlice[];
1500 byTask: UsageSlice[];
1501 byRepo: UsageSlice[];
1502 /** Keyed `namespace/name#number`. */
1503 byPull: UsageSlice[];
1504 byModel: UsageSlice[];
1505 /** Credit bought in the period. */
1506 addedMicros: number;
1507};
1508
1509/** One of g1t's products (a "bucket") on one day. Money in micros. */
1510export type CostDay = { day: string; bucket: string; cfCostMicros: number; ownCostMicros: number; valueMicros: number; cashMicros: number };
1511
1512/** One product over the range: what customers were charged at price against what it cost. */
1513export type ProductMargin = {
1514 bucket: string;
1515 title: string;
1516 /** Cloudflare's bill, or g1t's own figure where Cloudflare does not bill it (`costSource`). */
1517 costMicros: number;
1518 cfCostMicros: number;
1519 ownCostMicros: number;
1520 valueMicros: number;
1521 marginMicros: number;
1522 marginPercent: number | null;
1523 costSource: "cloudflare" | "ledger" | string;
1524 /** Running g1t, paid for by the plan. */
1525 overhead: boolean;
1526};
1527
1528/** All of g1t: money in (usage and the plan) against every cost. */
Costs: margin is measured on what was sold; comped workspaces, free periods, the trial and the pools are given away, a budget shown beside it1529export type OverallMargin = {
1530 usageMicros: number;
1531 plansMicros: number;
1532 costMicros: number;
1533 marginMicros: number;
1534 marginPercent: number | null;
1535 /** Of costMicros, what went on usage g1t gave away on purpose: comped workspaces, free periods, the trial and the open-source pool. */
1536 givenMicros?: number;
1537 /** Money in against costMicros - givenMicros. */
1538 soldMarginMicros?: number;
1539 soldMarginPercent?: number | null;
Costs: a statement that keeps usage sold, running g1t, subscriptions and what was given away (comped, free use, trial, pool) apart, and says who was paid; free use carries its own cost; the run button says it is running1540 /** Usage sold: usageMicros against what that usage cost, less what was given. */
1541 usageCostMicros?: number;
1542 usageMarginMicros?: number;
1543 usageMarginPercent?: number | null;
1544 /** Running g1t: plansMicros against the platform's cost, less its given share. */
1545 runningCostMicros?: number;
1546 /** Cost no mapping names, less its given share. */
1547 unmappedCostMicros?: number;
1548 /** givenMicros by why. Free is free periods, free allowances and overruns g1t covered. */
1549 givenCompedMicros?: number;
1550 givenFreeMicros?: number;
1551 givenTrialMicros?: number;
1552 givenPoolMicros?: number;
Merge branch 'worktree-agent-a633ac0f7f66d419d'1553 /** What discounts on an account's terms took below cost plus the margin: given, not margin lost. */
1554 givenDiscountMicros?: number;
Billing: credits with a kind and expiry, discounts instead of comped, and safer charging1555 /** Credits from g1t spent on usage, by kind: given, never money in. Refunds come off money in instead. */
1556 givenCreditPromotionalMicros?: number;
1557 givenCreditGoodwillMicros?: number;
Merge branch 'main' into worktree-agent-a69aeabc4b0deeb971558 /** What testing resets wiped that g1t paid for: the usage still happened, so its cost is given, never a leak. */
1559 givenResetMicros?: number;
Billing: credits with a kind and expiry, discounts instead of comped, and safer charging1560 /** Credits over the range: given (every kind), spent on usage, and refunds' money given back. */
1561 creditsGivenMicros?: number;
1562 creditsUsedMicros?: number;
1563 creditsRefundedMicros?: number;
Costs: a statement that keeps usage sold, running g1t, subscriptions and what was given away (comped, free use, trial, pool) apart, and says who was paid; free use carries its own cost; the run button says it is running1564 /** costMicros by who g1t pays: Cloudflare's bill (billed, after included allowances) and model providers (tokens, not on Cloudflare's bill). */
Costs: the plan's included usage counts as paid for the usage it covered, out of what plans leave for running g1t; the run button shows it is running with CSS alone (sudo ships no JavaScript)1565 /** What the plan's included usage paid for, at price: money in for usage, paid out of plansMicros. */
1566 includedMicros?: number;
Costs: a statement that keeps usage sold, running g1t, subscriptions and what was given away (comped, free use, trial, pool) apart, and says who was paid; free use carries its own cost; the run button says it is running1567 cloudflareCostMicros?: number;
1568 modelsCostMicros?: number;
Merge Stripe Tax, the card fee on card payments, and one free workspace per person1569 /** Tax collected with payments over the range, net of refunds: owed to tax authorities, never cash or revenue. */
1570 taxCollectedMicros?: number;
1571 /** Card processing fees passed on with card payments, net of refunds: they pay Stripe's fee, not revenue. */
1572 cardFeesMicros?: number;
Merge Cloudflare's usage over its billing cycle: every page read, included amounts once a cycle, a projection, test-mode charges never money in (billing 0052)1573 /** What workspaces were charged while payments were not live (Stripe's test mode): given, never money in. */
1574 givenUnpaidMicros?: number;
1575 /** Cloudflare's subscriptions over the range: each day's share of the billing cycle it is in. */
1576 subscriptionsMicros?: number;
1577 /** What AI Gateway priced g1t's own provider traffic at over the range, beside the ledger's model cost. */
1578 gatewayCostMicros?: number;
Costs: margin is measured on what was sold; comped workspaces, free periods, the trial and the pools are given away, a budget shown beside it1579};
Download ZIP reads blobs eight batches at a time and deflates files together1580
1581/** A count, cost or leak that does not add up. */
1582export type CostDrift = {
1583 bucket: string;
1584 title: string;
1585 kind: "count" | "cost" | "leak" | string;
1586 ours: number;
1587 cloudflare: number;
1588 deltaPercent: number | null;
1589 detail: string;
1590 foundAt: string;
1591};
1592
1593export type MarginAlert = {
1594 id: string;
1595 kind: "margin" | "overall" | "leak" | "drift" | "workspace" | string;
1596 /** The product, or the workspace. */
1597 subject: string;
1598 detail: string;
1599 since: string;
1600 openedAt: string;
1601 emailedAt: string | null;
1602};
1603
1604/** A change to a price, measured from what Cloudflare charged. */
1605export type PriceProposal = {
1606 id: string;
1607 meter: string;
1608 title: string;
1609 unit: string;
1610 currentCostMicros: number;
1611 proposedCostMicros: number;
1612 changePercent: number;
1613 markupPercent: number;
1614 reason: string;
1615 source: "keeper" | "reconciler" | string;
1616 /** Far off the current cost: look before approving. */
1617 suspect: boolean;
1618 status: "open" | "applied" | "approved" | "rejected" | "superseded" | string;
1619 createdAt: string;
1620 decidedAt: string | null;
1621 decidedBy: string | null;
1622 note: string | null;
1623 effectiveAt: string | null;
1624};
1625
1626/** One version of one meter's price; never changed once written. */
1627export type PriceVersion = {
1628 id: string;
1629 meter: string;
1630 version: number;
1631 costMicros: number;
1632 markupPercent: number;
1633 priceMicros: number;
1634 effectiveAt: string;
1635 reason: string;
1636 createdBy: string;
1637 appliedAt: string | null;
Merge costs and margin review: gateway query, own spend, discount meters, superseded rises1638 /**
1639 * What `costMicros` is: `cost`, what g1t pays for a unit; `rate`, a price
1640 * g1t sets with no cost behind it (the agent rate), so it is no cost;
1641 * `weight`, a multiplier in millionths, not money. Absent from older
1642 * billing: read as `cost`.
1643 */
1644 basis?: "cost" | "rate" | "weight" | "";
Download ZIP reads blobs eight batches at a time and deflates files together1645};
1646
sudo: reset a test workspace's billing so it starts again as a new customer; refused on a live Stripe key, for comped workspaces and for an enterprise's1647/** What `resetBilling` removed. */
sudo: a billing reset runs the costs analysis again so every figure is fresh; every submit button shows it is working (CSS only); no margin percentage on less than a cent sold1648export type BillingReset = { workspace: string; rows: number; refreshed?: boolean };
sudo: reset a test workspace's billing so it starts again as a new customer; refused on a live Stripe key, for comped workspaces and for an enterprise's1649
Costs: margin is measured on what was sold; comped workspaces, free periods, the trial and the pools are given away, a budget shown beside it1650export type WorkspaceCost = { workspace: string; costMicros: number; revenueMicros: number; givenMicros?: number; internal: boolean };
Download ZIP reads blobs eight batches at a time and deflates files together1651
1652export type CostLineSummary = {
1653 product: string;
1654 meter: string;
1655 rawName: string;
1656 unit: string;
1657 source: string;
1658 quantity: number;
1659 costMicros: number;
1660 /** Absent when no mapping claims it. */
1661 bucket: string | null;
1662};
1663
1664export type CostMapping = {
1665 product: string;
1666 meter: string;
1667 bucket: string;
1668 priceMeter: string | null;
1669 ownMeter: string | null;
1670 scaleToOwn: boolean;
1671 driftPercent: number;
1672 note: string;
1673 updatedAt: string;
1674 updatedBy: string;
1675};
1676
1677export type CostMappingInput = {
1678 product: string;
1679 meter: string;
1680 bucket?: string;
1681 priceMeter?: string | null;
1682 ownMeter?: string | null;
1683 scaleToOwn?: boolean;
1684 driftPercent?: number | null;
1685 note?: string;
1686 remove?: boolean;
1687};
1688
1689export type CostSettings = {
1690 autoApply: boolean;
1691 autoApplyPercent: number;
1692 noticeDays: number;
1693 marginFloorPercent: number;
1694 alertDays: number;
1695 minDailyCostMicros: number;
1696 anomalyFactor: number;
1697 anomalyFloorMicros: number;
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1698 /** Pass Stripe's card fee on as its own line when AI credit is bought by card. */
1699 cardFee: boolean;
Download ZIP reads blobs eight batches at a time and deflates files together1700};
1701
1702export type CostsReport = {
1703 configured: boolean;
1704 fetchedAt: string | null;
1705 since: string;
1706 until: string;
1707 days: CostDay[];
1708 products: ProductMargin[];
1709 overall: OverallMargin;
1710 drift: CostDrift[];
1711 alerts: MarginAlert[];
1712 proposals: PriceProposal[];
1713 versions: PriceVersion[];
1714 topWorkspaces: WorkspaceCost[];
1715 lines: CostLineSummary[];
1716 mappings: CostMapping[];
1717 settings: CostSettings;
1718 /** g1t's own spend against its two caps. */
1719 caps: SpendCaps;
Merge Cloudflare's usage over its billing cycle: every page read, included amounts once a cycle, a projection, test-mode charges never money in (billing 0052)1720 /** Cloudflare's current billing cycle: usage cost so far by meter, and the projection. Absent until the bill is read. */
1721 cycle?: CloudflareCycle | null;
1722 /** The last read of Cloudflare's billable usage: what came back. */
1723 billRead?: BillRead | null;
1724 /** Of the range's cost, what no workspace's usage could carry: running g1t, attributed to no one. */
1725 unattributedMicros?: number;
1726};
1727
1728/** Cloudflare's billing cycle, as its Billable usage page shows it. */
1729export type CloudflareCycle = {
1730 /** First and last days, YYYY-MM-DD, UTC. */
1731 start: string;
1732 end: string;
1733 days: number;
1734 /** Days from its start to today, today included. */
1735 daysElapsed: number;
1736 /** Usage cost so far, after the included allowances. */
1737 usageMicros: number;
1738 /** usageMicros over the days elapsed, times the cycle's days. */
1739 projectedMicros: number;
1740 averageDailyMicros: number;
1741 /** Cloudflare's subscriptions for the cycle (not on the usage bill). */
1742 subscriptionsMicros: number;
1743 meters: CycleMeter[];
1744};
1745
1746/** One of Cloudflare's meters over the cycle so far. */
1747export type CycleMeter = {
1748 product: string;
1749 meter: string;
1750 rawName: string;
1751 unit: string;
1752 quantity: number;
1753 /** What the cycle includes; null without a list price. */
1754 included: number | null;
1755 billableQuantity: number;
1756 costMicros: number;
1757 /** cloudflare: Cloudflare's own cost; list: the list price past the included amount; none: no list price known. */
1758 basis: "cloudflare" | "list" | "none" | string;
Download ZIP reads blobs eight batches at a time and deflates files together1759};
1760
Merge Cloudflare's usage over its billing cycle: every page read, included amounts once a cycle, a projection, test-mode charges never money in (billing 0052)1761/** What the last read of Cloudflare's billable usage got back. */
1762export type BillRead = {
1763 readAt: string;
1764 since: string;
1765 until: string;
1766 rows: number;
1767 pages: number;
1768 consumedRows: number;
1769 pricingOnlyRows: number;
1770 costedRows: number;
1771};
1772
Merge platform pause and the hourly usage watcher: staff can pause compute, schedules, indexing or renders for everyone, the watcher emails on a breach and is never blind quietly, and the models proxy holds each run to its cap (billing 0051, integrations 0006)1773/** One level of the platform pause, as sudo shows it. Snake case, as billing sends it. */
1774export type PauseState = {
1775 level: PauseLevel;
1776 paused: boolean;
1777 note: string | null;
1778 set_by: string | null;
1779 set_at: string | null;
1780 /** Set by billing's usage watcher, not a person. */
1781 auto: boolean;
1782};
1783
1784/** One platform metric over an hour or the month so far. */
1785export type PlatformMetric = {
1786 metric: string;
1787 title: string;
1788 value: number;
1789 /** Its hourly threshold (`PLATFORM_HOURLY_*`); 0: none. */
1790 threshold: number;
1791 /** The script, queue, database or namespace that counted most. */
1792 top_name: string | null;
1793 top_value: number | null;
1794};
1795
1796/** A breach billing's usage watcher found. */
1797export type PlatformBreach = {
1798 id: string;
1799 metric: string;
1800 hour: string;
1801 rule: "threshold" | "spike";
1802 value: number;
1803 threshold: number;
1804 severe: boolean;
1805 top_name: string | null;
1806 detail: string;
1807 /** Levels it paused. */
1808 paused: PauseLevel[];
1809 opened_at: string;
1810 emailed_at: string | null;
1811};
1812
The docs folder is gone, and what it held lives where people read it: how a self-hosted g1t runs and how to deploy g1t to Cloudflare are pages on docs.g1t.sh under Run g1t yourself, and speed, rate limits and operating g1t.sh are sections of CONTRIBUTING.md; code that cited a file in docs/ now points to the page or section that covers it, or says what it means itself, and applied migrations and the runner images are left as they were.1813/** Billing's `admin_platform_guard`: the platform pause and usage watcher
1814 * (docs.g1t.sh/guides/deploy-to-cloudflare/#spend-guardrails). */
Merge platform pause and the hourly usage watcher: staff can pause compute, schedules, indexing or renders for everyone, the watcher emails on a breach and is never blind quietly, and the models proxy holds each run to its cap (billing 0051, integrations 0006)1815export type PlatformGuard = {
1816 levels: PauseState[];
1817 /** The last hour read, `YYYY-MM-DDTHH:00:00Z`. */
1818 hour: string | null;
1819 last_hour: PlatformMetric[];
1820 month: string;
1821 month_to_date: PlatformMetric[];
1822 breaches: PlatformBreach[];
1823 /** Whether billing can read Cloudflare's analytics. */
1824 can_read: boolean;
1825 /** `AUTO_PAUSE`: the levels a severe breach may pause. */
1826 auto_pause: PauseLevel[];
1827 /** What the latest run could not see: each query that failed, with its error. */
1828 blind?: { key: string; dataset: string; error: string }[];
1829 /** The latest run found every dataset empty: the wrong account, or a token that cannot see it. */
1830 empty?: boolean;
1831 /** The hour the latest run read. */
1832 last_run?: string | null;
1833};
1834
Download ZIP reads blobs eight batches at a time and deflates files together1835/** What g1t pays for itself, at cost, against its caps (billing's `budget`). */
1836export type SpendCaps = {
1837 /** Today (UTC), YYYY-MM-DD, and this month, YYYY-MM. */
1838 day: string;
1839 month: string;
1840 /** What g1t paid for itself today across every workspace. */
1841 todayMicros: number;
1842 /** `PLATFORM_DAILY_SPEND_CAP_MICROS`; 0: no breaker. */
1843 dailyCapMicros: number;
1844 /** New hosted-model agent runs g1t would pay for are paused. */
1845 tripped: boolean;
1846 trippedAt: string | null;
1847 liftedBy: string | null;
1848 liftedAt: string | null;
1849 liftNote: string | null;
1850 /** This month so far, by what paid: comped, trial, oss, given, unpaid. */
1851 monthBuckets: { bucket: string; title: string; micros: number }[];
1852 comped: CompedBudget[];
1853 /** Free workspaces' share of reconciled costs this month (git, storage, platform). */
1854 freeTierMicros: number;
Costs: Cloudflare's subscriptions read from Cloudflare each day, the estimate only until then; sudo's costs split into Costs & margin and Bill & pricing1855 /** Cloudflare's subscriptions a month: read from Cloudflare each day, else `CLOUDFLARE_FIXED_MONTHLY_MICROS`, an estimate. */
Download ZIP reads blobs eight batches at a time and deflates files together1856 fixedMonthlyMicros: number;
Costs: Cloudflare's subscriptions read from Cloudflare each day, the estimate only until then; sudo's costs split into Costs & margin and Bill & pricing1857 fixedSource?: "cloudflare" | "estimate" | string;
1858 fixedReadAt?: string | null;
1859 /** Each subscription, when read from Cloudflare. */
1860 fixedItems?: { name: string; monthlyMicros: number }[];
Merge Cloudflare's usage over its billing cycle: every page read, included amounts once a cycle, a projection, test-mode charges never money in (billing 0052)1861 /** Of fixedMonthlyMicros, this calendar month's days so far, each at its billing cycle's daily share. */
1862 fixedMonthMicros?: number;
Download ZIP reads blobs eight batches at a time and deflates files together1863 /** Money in this month, through the last reconciled day. */
1864 revenueMicros: number;
Merge costs and margin review: gateway query, own spend, discount meters, superseded rises1865 /**
1866 * Of this month's buckets, what was spent on workspaces whose billing a
1867 * testing reset later wiped (still g1t's spend; the reconciled figures
1868 * have it only where the reset kept it), and those workspaces.
1869 */
1870 resetMicros?: number;
1871 resetWorkspaces?: string[];
Download ZIP reads blobs eight batches at a time and deflates files together1872};
1873
1874/** A comped account's monthly budget, at cost. */
1875export type CompedBudget = {
1876 account: string;
1877 name: string;
1878 usedMicros: number;
1879 /** 0: no budget. */
1880 ceilingMicros: number;
1881 /** `COMPED_MONTHLY_CEILING_MICROS`, not the account's own limit. */
1882 defaultCeiling: boolean;
1883 /** 50, 75, 90, 100, or 0. */
1884 level: number;
1885};
1886
1887export type CostsRun = { lines: number; days: number; proposals: number; alerts: number; problems: string[] };
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1888
1889/** The product families the Usage page groups meters into, in order. */
1890export const PRODUCTS = [
1891 { key: "agent", label: "Agent" },
1892 { key: "sandboxes", label: "Sandboxes" },
1893 { key: "gateway", label: "AI Gateway" },
1894 { key: "deployments", label: "Deployments" },
1895 { key: "git_storage", label: "Git & storage" },
1896 { key: "packages", label: "Packages" },
1897 { key: "security", label: "Security & quality" },
1898 { key: "search", label: "Search" },
1899] as const;
1900
1901export type ProductKey = (typeof PRODUCTS)[number]["key"];
1902
1903/** What usage came to over a range, and what paid for it: price − discount − included − credits = charged. */
1904export type UsageTotals = {
1905 /** Usage at price, pending usage included. */
1906 priceMicros: number;
1907 discountMicros: number;
1908 /** Paid by the plan's included usage, the trial and g1t's pools. */
1909 includedMicros: number;
1910 /** Paid by AI credit and credit from g1t. */
1911 creditsMicros: number;
1912 /** Left for the workspace to pay. */
1913 chargedMicros: number;
1914 /** Metered this month, charged when it closes. */
1915 pendingMicros: number;
Money is written one way. A single formatter turns millionths of a dollar into dollars, rounding half up on whole micros rather than on a float, so the same sum reads the same on every page: under a cent reads <$0.01 on a total and exactly nothing is $0.00, while the statement's lines, a session's receipt, the price book and an agent's effort costs carry up to four places where the fraction of a cent is the point; the six formatters that each rounded their own way are gone. This month is the calendar month in UTC from its first day to today everywhere, and billing counts the month's not-yet-closed usage in any range that reaches into the current month, so the top bar's pill, Spend, Home and Usage ask for the same days and get the same figure; Home now reads the usage report the others read instead of adding up statements. Usage's pending sentence says what of that usage the close will charge after the discount and included usage, which the billing API returns as pending_charged_micros. A reconciliation test holds the pill, Spend, Home and Usage to one number for one month. The usage and billing guide says how amounts are written and what this month means.1916 /** What of `pendingMicros` will be charged at the close, after the discount and what g1t covers; absent from an older billing. */
1917 pendingChargedMicros?: number;
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1918 costMicros: number;
1919};
1920
1921export type UsageDay = { day: string; product: string; micros: number };
1922
Spend adds up on one ledger. Charged this month has one definition, price less discount, included usage and credit, shared by the plan card, the spend limit, Spend and the top bar; the limit had counted usage not yet closed at full price before the discount, so a comped workspace read as charged a cent. Every agent line on the ledger names the agent and who asked, repository runs by g1t included, so Spent is the sum of its products, Agents is the agent product, and by agent adds up to it; the billing API returns by_agent and by_person. The usage and billing guide says how spend is counted.1923/** One agent's (by handle) or one person's (by username) share of the agent product, at price; an empty key for lines attributed to no one. */
1924export type UsageShare = { key: string; label: string; micros: number; count: number };
1925
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1926export type UsageAllowance = { used: number; of: number; unit: string };
1927
1928export type ProjectUsage = { project: string; micros: number; quantity: number };
1929
1930/** One meter over a range. */
1931export type MeterLine = {
1932 key: string;
1933 label: string;
1934 product: string;
1935 /** `tokens`, `seconds`, `bytes`, `operations`, `requests` or `entries`. */
1936 unit: string;
1937 quantity: number;
1938 micros: number;
1939 pendingMicros?: number;
1940 /** Every day of the range, oldest first, at price. */
1941 daily: number[];
1942 allowance?: UsageAllowance | null;
1943 byProject: ProjectUsage[];
Merge branch 'model-routing'1944 /** How the quantity is counted, when that needs saying (the agent rate's token weights). */
1945 note?: string | null;
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1946};
1947
1948export type FeatureUsage = { key: string; label: string; micros: number; count: number };
1949
1950export type ProductUsage = { key: string; label: string; micros: number; meters: MeterLine[]; features?: FeatureUsage[] };
1951
Merge branch 'model-routing'1952/** The tokens one model used over a range, as the model proxy counted them. */
1953export type ModelTokens = { model: string; input: number; output: number; cacheRead: number; cacheWrite: number };
1954
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1955export type UsageReport = {
1956 from: string;
1957 until: string;
1958 totals: UsageTotals;
1959 days: UsageDay[];
1960 products: ProductUsage[];
1961 projects: string[];
Merge branch 'model-routing'1962 /** Agent tokens by model over the range, most first. */
1963 models?: ModelTokens[];
Spend adds up on one ledger. Charged this month has one definition, price less discount, included usage and credit, shared by the plan card, the spend limit, Spend and the top bar; the limit had counted usage not yet closed at full price before the discount, so a comped workspace read as charged a cent. Every agent line on the ledger names the agent and who asked, repository runs by g1t included, so Spent is the sum of its products, Agents is the agent product, and by agent adds up to it; the billing API returns by_agent and by_person. The usage and billing guide says how spend is counted.1964 /** The agent product by the agent that did the work, most first; their sum is the agent product's total. */
1965 byAgent?: UsageShare[];
1966 /** The agent product by who asked; work no person asked for under an empty key. */
1967 byPerson?: UsageShare[];
Usage, Billing settings and prepaid AI credit; fixes from the UX audit1968 /** The plan's included usage this month, in micros. */
1969 included?: UsageAllowance | null;
1970 discountPercent?: number | null;
1971 aiCreditMicros: number;
1972 creditMicros: number;
1973 trialMicros?: number | null;
1974 plan: PlanKind;
1975 free: boolean;
1976};
1977
1978export type AiReload = {
1979 enabled: boolean;
1980 thresholdMicros: number;
1981 targetMicros: number;
1982 monthlyMaxMicros: number;
1983 reloadedMicros?: number;
1984 failedAt?: string | null;
1985 error?: string | null;
1986};
1987
1988export type CardFee = { on: boolean; percentMicros: number; fixedCents: number };
1989
1990/** Prepaid AI credit: what Agent and AI Gateway usage draws on. */
1991export type AiCredit = {
1992 balanceMicros: number;
1993 purchasedMicros: number;
1994 givenMicros: number;
1995 grants: CreditGrant[];
1996 /** A 100% discount pays for AI usage: nothing to buy. */
1997 freeViaDiscount: boolean;
1998 /** Invoiced after use (an enterprise). */
1999 postpaid: boolean;
2000 /** New runs on g1t's models are refused for want of credit. */
2001 blocked: boolean;
2002 canBuy: boolean;
2003 presetsCents: number[];
2004 minCents: number;
2005 maxCents: number;
2006 cardFee: CardFee;
2007 reload: AiReload;
2008 /** The agent rate per million tokens, at price. */
2009 agentRateMicros: number;
2010 modelMarkupPercent: number;
2011 gatewayMarkupPercent: number;
2012 upgradeCreditMicros: number;
2013 expiresDays: number;
2014};
2015
2016export type PostalAddress = { line1: string; line2: string; city: string; state: string; postalCode: string; country: string };
2017
2018export type PaymentMethod = {
2019 kind: string;
2020 brand?: string | null;
2021 last4?: string | null;
2022 expMonth?: number | null;
2023 expYear?: number | null;
2024};
2025
2026export type StripeInvoice = {
2027 id: string;
2028 number?: string | null;
2029 status: string;
2030 totalCents: number;
2031 currency: string;
2032 createdAt: string;
2033 description?: string | null;
2034 hostedUrl?: string | null;
2035 pdfUrl?: string | null;
2036};
2037
2038export type UpcomingInvoice = { closesAt: string; subscriptionsMicros: number; usageMicros: number; totalMicros: number };
2039
2040export type BillingDetails = {
2041 customer: boolean;
2042 email: string | null;
2043 name: string | null;
2044 address: PostalAddress | null;
2045 taxIdType: string | null;
2046 taxId: string | null;
2047 poNumber: string | null;
2048 language: string | null;
2049 paymentMethod: PaymentMethod | null;
2050 invoices: StripeInvoice[];
2051 upcoming: UpcomingInvoice;
2052 unavailable?: string | null;
Merge Stripe Tax, the card fee on card payments, and one free workspace per person2053 /** Whether Stripe Tax can place the customer from the address; without it nothing is charged. */
2054 taxLocation?: boolean;
2055 /** Set when g1t did not charge for want of a billing address. */
2056 taxAddressNeededAt?: string | null;
2057 /** Stripe's check of the tax ID: pending, verified, unverified or unavailable. */
2058 taxIdStatus?: string | null;
2059 /** none, exempt or reverse, as set at Stripe. */
2060 taxExempt?: string | null;
Usage, Billing settings and prepaid AI credit; fixes from the UX audit2061};
2062
2063export type BillingDetailsInput = {
2064 email?: string;
2065 name?: string;
2066 address?: PostalAddress;
2067 taxIdType?: string;
2068 taxId?: string;
2069 poNumber?: string;
2070 language?: string;
2071};

This file's history is long; its oldest lines are credited to the oldest commit read.