@extrovert.dev/mcp 0.1.0-pre.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +313 -0
  3. package/dist/bin.d.ts +13 -0
  4. package/dist/bin.d.ts.map +1 -0
  5. package/dist/bin.js +89 -0
  6. package/dist/bin.js.map +1 -0
  7. package/dist/client.d.ts +956 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +1354 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/config.d.ts +51 -0
  12. package/dist/config.d.ts.map +1 -0
  13. package/dist/config.js +53 -0
  14. package/dist/config.js.map +1 -0
  15. package/dist/contract.d.ts +62 -0
  16. package/dist/contract.d.ts.map +1 -0
  17. package/dist/contract.js +78 -0
  18. package/dist/contract.js.map +1 -0
  19. package/dist/extract.d.ts +25 -0
  20. package/dist/extract.d.ts.map +1 -0
  21. package/dist/extract.js +131 -0
  22. package/dist/extract.js.map +1 -0
  23. package/dist/fixtures.d.ts +676 -0
  24. package/dist/fixtures.d.ts.map +1 -0
  25. package/dist/fixtures.js +2685 -0
  26. package/dist/fixtures.js.map +1 -0
  27. package/dist/http.d.ts +18 -0
  28. package/dist/http.d.ts.map +1 -0
  29. package/dist/http.js +124 -0
  30. package/dist/http.js.map +1 -0
  31. package/dist/index.d.ts +17 -0
  32. package/dist/index.d.ts.map +1 -0
  33. package/dist/index.js +18 -0
  34. package/dist/index.js.map +1 -0
  35. package/dist/server.d.ts +20 -0
  36. package/dist/server.d.ts.map +1 -0
  37. package/dist/server.js +36 -0
  38. package/dist/server.js.map +1 -0
  39. package/dist/stdio.d.ts +8 -0
  40. package/dist/stdio.d.ts.map +1 -0
  41. package/dist/stdio.js +22 -0
  42. package/dist/stdio.js.map +1 -0
  43. package/dist/tools.d.ts +27 -0
  44. package/dist/tools.d.ts.map +1 -0
  45. package/dist/tools.js +2752 -0
  46. package/dist/tools.js.map +1 -0
  47. package/dist/types.d.ts +1037 -0
  48. package/dist/types.d.ts.map +1 -0
  49. package/dist/types.js +83 -0
  50. package/dist/types.js.map +1 -0
  51. package/package.json +72 -0
@@ -0,0 +1,1037 @@
1
+ /**
2
+ * Extrovert API resource types.
3
+ *
4
+ * These mirror the Extrovert REST contract (`/v1` — enroll, inboxes, messages,
5
+ * threads, wait). They are the wire shapes the typed client returns. The offline
6
+ * fixture store produces the same shapes for tests and demos.
7
+ */
8
+ /** Onboarding mode for the domain an inbox is minted on (spec §7). */
9
+ export type OnboardingMode = "shared" | "purchased" | "ns_delegated" | "manual";
10
+ /**
11
+ * The ceiling tier an agent key encodes in its raw prefix (redesign §3.1):
12
+ * - `org` — `pk_agent_org_…` (reaches its org subtree; bare list = breadth_required)
13
+ * - `project` — `pk_agent_proj_…` (DEFAULT; project is implicit)
14
+ * - `inbox` — `pk_agent_inbox_…` (pinned to one inbox)
15
+ * A legacy bare `pk_agent_…` key (no tier segment) maps to `project`.
16
+ */
17
+ export type KeyTier = "org" | "project" | "inbox";
18
+ /** Capability strings carried by scoped agent keys. */
19
+ export type AgentScope = "mailbox:create" | "mailbox:read" | "mailbox:send" | "mailbox:quota" | "mailbox:delete" | "webhook:write" | "domain:manage" | "domain:purchase" | "review:act";
20
+ /**
21
+ * Derive the key tier from the raw agent-key prefix (redesign §3.1, Appendix A).
22
+ * The tier is encoded in the prefix segment after `pk_agent_`; a legacy bare
23
+ * `pk_agent_` key (or a non-agent / empty key) is treated as `project` — exactly
24
+ * today's behavior. The MCP never parses the secret tail.
25
+ */
26
+ export declare function keyTierFromRawKey(rawKey: string | undefined): KeyTier;
27
+ /** Lifecycle status of an inbox. */
28
+ export type InboxStatus = "provisioning" | "live" | "disabled" | "deleting";
29
+ /**
30
+ * Arbitrary key-value metadata an agent attaches to an inbox (AgentMail parity).
31
+ * Values are string, number, or boolean. On a read this is always an object
32
+ * (`{}` when none is set, never null). On a create/update request a top-level
33
+ * `null` clears all metadata and a key whose value is `null` deletes that key
34
+ * (see {@link CreateInboxInput}/{@link UpdateInboxInput}).
35
+ */
36
+ export type InboxMetadata = Record<string, string | number | boolean>;
37
+ /** A real, persistent inbox owned by an agent. */
38
+ export interface Inbox {
39
+ /**
40
+ * The resource object type — always `"inbox"` (RFC D9; every redesign resource
41
+ * carries `object`). Optional on the wire for older servers.
42
+ */
43
+ object?: "inbox";
44
+ /**
45
+ * The canonical OPAQUE inbox id and path key (`/v1/inboxes/{inbox_id}`), live
46
+ * value `pmbx_…`. Treat it as an opaque string — do NOT parse the prefix.
47
+ */
48
+ id: string;
49
+ /**
50
+ * The fixed org the inbox belongs to (RFC D9). Resolved from the key's scope;
51
+ * never a selector.
52
+ */
53
+ org_id?: string;
54
+ /**
55
+ * The fixed project the inbox belongs to (RFC D9). An agent key can only read or
56
+ * mutate inboxes in its bound project; `project_id` on a request is an ASSERTION,
57
+ * never a selector.
58
+ */
59
+ project_id?: string;
60
+ /**
61
+ * Full address, e.g. `agent7@smtp.extrovert.dev`. The within-project email alias —
62
+ * also accepted as a `{inbox_id}` path segment, but `id` is canonical.
63
+ */
64
+ address: string;
65
+ /** Display name attached to outbound mail, if any. */
66
+ display_name?: string;
67
+ /** The domain the address lives on. */
68
+ domain: string;
69
+ /** How the underlying domain was onboarded. */
70
+ onboarding_mode: OnboardingMode;
71
+ status: InboxStatus;
72
+ /** Agent that owns this inbox. */
73
+ agent_id: string;
74
+ /** Effective enforced rolling-24-hour recipient cap for this inbox. */
75
+ daily_send_limit: number;
76
+ /** ISO-8601 creation timestamp. */
77
+ created_at: string;
78
+ /** Whether outbound sender registration has completed — never skipped. */
79
+ sender_verified: boolean;
80
+ /**
81
+ * Optional HMAC-signed inbound webhook target, as returned by the API.
82
+ * The read shape uses the contract's `webhook_url` (Inbox schema); the agent-
83
+ * facing WRITE inputs name it `inbound_webhook_url` and the client remaps that
84
+ * to `webhook_url` on create/update.
85
+ */
86
+ webhook_url?: string;
87
+ /**
88
+ * Arbitrary key-value metadata stored on the inbox (AgentMail parity). Always
89
+ * an object on a read (`{}` when none is set, never null); project-scoped.
90
+ */
91
+ metadata: InboxMetadata;
92
+ /**
93
+ * The RESOLVED review policy governing every outbound send from THIS inbox: the
94
+ * per-inbox override, else the account default, else the `require_review` floor.
95
+ *
96
+ * Read it once, before the first send, and plan accordingly — under
97
+ * `require_review` (the default for every account that has not opted out) a send
98
+ * with no `intent` is refused with 422 `intent_required` and NOTHING is queued.
99
+ * Present only on the single-inbox read (`get_inbox`); the list path omits it
100
+ * because the value is identical for every inbox in the org.
101
+ */
102
+ effective_review_policy?: ReviewPolicy;
103
+ }
104
+ /**
105
+ * An account/inbox review policy (the server's closed set).
106
+ *
107
+ * - `require_review` every outbound send is queued for a human. THE DEFAULT
108
+ * and the floor: a policy the server cannot read resolves
109
+ * here, and a per-inbox override can only tighten toward it.
110
+ * - `auto_send_graduated` a send in a graduated category may auto-send; everything
111
+ * else is queued.
112
+ * - `allow_direct` the account has explicitly opted into unsupervised sends.
113
+ */
114
+ export type ReviewPolicy = "require_review" | "auto_send_graduated" | "allow_direct";
115
+ /** A participant address on a message. */
116
+ export interface Address {
117
+ name?: string;
118
+ email: string;
119
+ }
120
+ /**
121
+ * Attachment metadata (bytes fetched separately by id). Mirrors the canonical Go
122
+ * wire shape (`attachmentResponse`): `id` is the opaque attachment id addressing
123
+ * one MIME part; `size` is the decoded byte length.
124
+ */
125
+ export interface Attachment {
126
+ id: string;
127
+ filename: string;
128
+ content_type: string;
129
+ size: number;
130
+ }
131
+ /**
132
+ * An outbound attachment on send / reply. `content_base64` is the standard
133
+ * base64 of the file bytes. Mirrors the Go `attachmentRequest`.
134
+ */
135
+ export interface AttachmentInput {
136
+ filename: string;
137
+ content_type: string;
138
+ content_base64: string;
139
+ }
140
+ /** One attachment's bytes (base64) plus the metadata to save/serve it. */
141
+ export interface AttachmentDownload {
142
+ filename: string;
143
+ content_type: string;
144
+ content_base64: string;
145
+ }
146
+ /** Direction of a message relative to the owning inbox. */
147
+ export type MessageDirection = "inbound" | "outbound";
148
+ /**
149
+ * A single email message. This mirrors the canonical Go wire shape
150
+ * (`messageResponse`): `id` is the opaque, inbox-resolvable id; `inbox` is the
151
+ * owning address; `seen` is the native IMAP \Seen read state (no Gmail-style
152
+ * labels); `folder` is the IMAP mailbox the message lives in.
153
+ */
154
+ export interface Message {
155
+ id: string;
156
+ thread_id: string;
157
+ /** Owning inbox address (e.g. agent7@smtp.extrovert.dev). */
158
+ inbox: string;
159
+ direction: MessageDirection;
160
+ from: Address;
161
+ to: Address[];
162
+ cc?: Address[];
163
+ subject: string;
164
+ /** Decoded text/plain MIME alternative; never derived from HTML. */
165
+ text: string | null;
166
+ /** Decoded text/html MIME alternative; never synthesized from text. */
167
+ html?: string | null;
168
+ /** Best-effort derivative of text; never replaces the source field. */
169
+ extracted_text?: string | null;
170
+ /** Best-effort derivative of html; never replaces the source field. */
171
+ extracted_html?: string | null;
172
+ /** ISO-8601 received/sent timestamp (raw Date header). */
173
+ date: string;
174
+ /** RFC 5322 Message-ID. */
175
+ message_id: string;
176
+ /** Whether the message has been read (native IMAP \Seen flag). */
177
+ seen: boolean;
178
+ /** IMAP folder the message lives in (e.g. INBOX, Junk). */
179
+ folder?: string;
180
+ }
181
+ /**
182
+ * A conversation thread, grouped server-side by RFC 5322 References / In-Reply-To
183
+ * chaining (subject fallback). Mirrors the canonical Go `threadResponse`: `id` is
184
+ * stable across calls; `participants` are bare/display address strings; `snippet`
185
+ * is a preview of the latest message.
186
+ */
187
+ export interface Thread {
188
+ id: string;
189
+ /** Owning inbox address. */
190
+ inbox_id: string;
191
+ subject: string;
192
+ /** Number of messages in the thread. */
193
+ message_count: number;
194
+ /** Distinct participant addresses (display strings, e.g. `Name <email>`). */
195
+ participants: string[];
196
+ /** ISO-8601 timestamp of the most recent message. */
197
+ last_message_at: string;
198
+ /** Snippet of the latest message body. */
199
+ snippet: string;
200
+ }
201
+ /** A thread plus its messages (oldest-first) — `GET /v1/inboxes/{inbox_id}/threads/{id}`. */
202
+ export interface ThreadDetail extends Thread {
203
+ messages: Message[];
204
+ }
205
+ /**
206
+ * Canonical reply/forward result: `{message_id, thread_id}`, plus the ADDITIVE
207
+ * `review_id` handle.
208
+ *
209
+ * Every agent-plane send now passes through a review row even on the direct path,
210
+ * so `review_id` names the row that governed this delivery. It is what an agent
211
+ * that crashed between the request and the response uses to ask what became of the
212
+ * message (`get_review` → `closed`); without it the direct path hands back no
213
+ * handle at all. Absent only when talking to a server that predates it.
214
+ */
215
+ export interface SendResult {
216
+ message_id: string;
217
+ thread_id: string;
218
+ review_id?: string;
219
+ }
220
+ /**
221
+ * The legacy direct-send body for `POST /v1/inboxes/{id}/send`:
222
+ * `{status:"sent", message_id, review_id}` (HTTP 202).
223
+ *
224
+ * This is what a bare send returns ONLY when the account's policy permits a direct
225
+ * send. It is NOT the default outcome — under `require_review` a bare send with an
226
+ * intent answers {@link QueuedForReviewResult} instead, and one without an intent
227
+ * is refused with 422 `intent_required`.
228
+ */
229
+ export interface DirectSendResult {
230
+ status: "sent";
231
+ message_id: string;
232
+ review_id?: string;
233
+ }
234
+ /**
235
+ * The outcome of a bare (not review-overloaded) send: delivered on the policy's
236
+ * direct path, or parked in the human queue. Narrow on `"kind" in result` — the
237
+ * queued arm is the discriminated §5.1 envelope, the sent arm is the legacy body.
238
+ */
239
+ export type SendEmailResult = DirectSendResult | QueuedForReviewResult;
240
+ /**
241
+ * The outcome of a bare reply or forward: `{message_id, thread_id, review_id}` on
242
+ * the direct path, or parked in the human queue. Narrow on `"kind" in result`.
243
+ */
244
+ export type ReplyEmailResult = SendResult | QueuedForReviewResult;
245
+ /** Per-send agent assertion (D3/D6). The resolved policy may downgrade `direct`. */
246
+ export type ReviewMode = "review" | "direct";
247
+ /** Review-request state machine (spec §3.1). */
248
+ export type ReviewState = "needs_review" | "in_review" | "chatting" | "stale" | "approved" | "sent" | "auto_sent" | "rejected" | "stalled" | "cancelled" | "failed";
249
+ /** The agent's "for the human reviewer" intent (spec §11). */
250
+ export interface ReviewIntent {
251
+ summary: string;
252
+ meta?: {
253
+ goal?: string;
254
+ recipient?: string;
255
+ prior_touches?: number;
256
+ urgency?: string;
257
+ };
258
+ }
259
+ /** A review request (rr_…) — the pre-send record under the Review Loop. */
260
+ export interface Review {
261
+ id: string;
262
+ state: ReviewState;
263
+ mode: ReviewMode;
264
+ effective_mode: ReviewMode;
265
+ kind: "send" | "reply" | "forward";
266
+ from_address: string;
267
+ agent_id: string;
268
+ category_id?: string;
269
+ intent_summary: string;
270
+ intent_meta?: Record<string, unknown>;
271
+ revision: number;
272
+ version: number;
273
+ proposed_subject: string;
274
+ proposed_body_text: string;
275
+ proposed_body_html?: string;
276
+ proposed_to: string[];
277
+ proposed_cc?: string[];
278
+ proposed_bcc?: string[];
279
+ sent_subject?: string;
280
+ sent_body_text?: string;
281
+ diff_unified?: string;
282
+ sent_message_id?: string;
283
+ gate_outcome?: string;
284
+ stale_reason?: string;
285
+ decision_feedback?: string;
286
+ /**
287
+ * The DEFINITIVE per-review "am I done?" answer — the poll-side companion to the
288
+ * terminal nudges (`sent` / `send_failed` / `cancelled`). True for `sent`,
289
+ * `auto_sent`, `cancelled` AND `failed`.
290
+ *
291
+ * `failed` is included deliberately even though it is not formally terminal: the
292
+ * console cannot re-approve it and the only edge out is the composer's own
293
+ * cancel, so an agent told `closed:false` for a failed review would wait forever
294
+ * on a row nobody is going to move. Absent on a server that predates the field.
295
+ */
296
+ closed?: boolean;
297
+ /**
298
+ * The vendor-scrubbed delivery failure, present on a `failed` review. Until this
299
+ * field an agent could learn THAT its message failed and never WHY.
300
+ */
301
+ send_error?: string;
302
+ /**
303
+ * How the message got out: `human_reviewed` | `reviewer_approved` |
304
+ * `graduated_auto` | `agent_direct` — without fetching the turns.
305
+ */
306
+ send_path?: string;
307
+ created_at: string;
308
+ updated_at: string;
309
+ decided_at?: string;
310
+ sent_at?: string;
311
+ }
312
+ /** One immutable turn in a review's append-only thread (turn_…). */
313
+ export interface ReviewTurn {
314
+ id: string;
315
+ seq: number;
316
+ turn_type: string;
317
+ actor_kind: "agent" | "human" | "review_agent" | "system";
318
+ actor_id?: string;
319
+ body?: string;
320
+ revision?: number;
321
+ diff_json?: Record<string, unknown>;
322
+ metadata?: Record<string, unknown>;
323
+ created_at: string;
324
+ }
325
+ /** One human/agent comment in the assembled review feedback (spec §11). */
326
+ export interface ReviewFeedbackComment {
327
+ turn_id: string;
328
+ actor_kind: "agent" | "human" | "review_agent" | "system";
329
+ actor_id?: string;
330
+ body: string;
331
+ created_at: string;
332
+ }
333
+ /**
334
+ * The human's assembled feedback for a review (spec §11) returned by
335
+ * get_review_feedback: the unified + structured diff of the human edit, the human
336
+ * comments / rejection feedback, the decision, and the rules born from this review
337
+ * (rule_ ids whose source_review_id is this review). $0 LLM — pure assembly.
338
+ */
339
+ export interface ReviewFeedback {
340
+ review_id: string;
341
+ decision: string;
342
+ diff_unified?: string;
343
+ diff_json?: Record<string, unknown>;
344
+ comments: ReviewFeedbackComment[];
345
+ new_rules: string[];
346
+ }
347
+ /**
348
+ * The REVIEWER's read-only decision surface for a review (BYO review-agent plane;
349
+ * D5/§9) returned by get_review_decision_context: the intent + current draft + the
350
+ * append-only thread + the two-circuit-breaker budget. `force_to_human` is true when
351
+ * EITHER breaker has tripped — the reviewer's next reject would be FORCED to the human
352
+ * regardless of intent (the human is the only terminal authority, D17).
353
+ */
354
+ export interface ReviewDecisionContext {
355
+ review: Review;
356
+ turns: ReviewTurn[];
357
+ /** Circuit breaker (a): reviewer hand-backs so far. */
358
+ hop_count: number;
359
+ /** Circuit breaker (a): the ceiling; at hop_count ≥ max_hops the next action is forced to the human. */
360
+ max_hops: number;
361
+ /** Circuit breaker (b): the hard per-review wall-clock deadline (created_at + review_deadline_s). */
362
+ review_deadline: string;
363
+ /** Breaker (b) tripped. */
364
+ deadline_passed: boolean;
365
+ /** Breaker (a) tripped. */
366
+ hops_exhausted: boolean;
367
+ /** Either breaker tripped: a reject is overridden to a human escalation. */
368
+ force_to_human: boolean;
369
+ /** The tripped breaker (max_hops_reached | review_deadline_passed). */
370
+ force_reason?: string;
371
+ }
372
+ /** The reviewer's decision verb (BYO review-agent plane; §9). */
373
+ export type ReviewerAction = "approve" | "edit" | "reject" | "escalate";
374
+ /**
375
+ * The outcome of a reviewer decision (reviewer_decide; D5/§9). `kind=sent` when the
376
+ * platform ACS-sent with the COMPOSER's creds (approve/edit — the reviewer NEVER holds
377
+ * mailbox:send); `kind=sent_to_human` when the draft returned to the human queue
378
+ * (reject/escalate, or a reject FORCED to the human by a circuit breaker, with
379
+ * `forced_by_breaker` naming it).
380
+ */
381
+ export interface ReviewerDecisionResult {
382
+ kind: "sent" | "sent_to_human";
383
+ review: Review;
384
+ sent: boolean;
385
+ message_id?: string;
386
+ thread_id?: string;
387
+ sent_to_human: boolean;
388
+ forced_by_breaker?: string;
389
+ }
390
+ /**
391
+ * The reason a durable review nudge was enqueued (spec §4.5). The agent branches
392
+ * on it to decide what to do (redraft, learn, re-check a category, stop).
393
+ *
394
+ * EMITTED today — a drain loop must handle all of these:
395
+ * - `redraft_requested` a reviewer rejected/escalated, or a sweep handed the
396
+ * draft back: redraft with `submit_revision`.
397
+ * - `feedback_added` a HUMAN commented (an agent's own question emits
398
+ * none): answer it, or redraft.
399
+ * - `rejected` learn from the rejection, then redraft or stop.
400
+ * - `rule_changed` re-read `get_rules`, then redraft or `restamp_review`.
401
+ * - `recheck_category` re-check the draft's category assignment.
402
+ * - `propagate_general_rule` a rule was generalized to house style; re-apply it.
403
+ * - `sent` TERMINAL. The message went out (`payload.state` is
404
+ * `sent` or `auto_sent`, `payload.message_id` names it).
405
+ * Ack and stop polling this review.
406
+ * - `send_failed` TERMINAL. Delivery failed (`payload.error`). Do NOT
407
+ * retry this review — compose a NEW message.
408
+ * - `cancelled` TERMINAL. The review was withdrawn.
409
+ * - `front_run_next` you tried to mutate an already-terminal review.
410
+ * STOP RETRYING.
411
+ *
412
+ * RESERVED — published for forward compatibility, never emitted today:
413
+ * - `staleness` (no producer), `approved` (terminal success is `sent`).
414
+ *
415
+ * `sent` and `cancelled` close the review. `send_failed` reports the terminal
416
+ * delivery attempt but the failed row can then be explicitly closed with
417
+ * `cancel_review`, which emits a later `cancelled` nudge. Do not assume exactly
418
+ * one terminal-class nudge or that `send_failed` is the last sequence number.
419
+ * Handle unknown reasons with an ack-and-ignore default arm: the set is additive
420
+ * across 0.x.
421
+ */
422
+ export type ReviewEventReason = "redraft_requested" | "feedback_added" | "recheck_category" | "staleness" | "approved" | "rejected" | "front_run_next" | "rule_changed" | "propagate_general_rule" | "sent" | "send_failed" | "cancelled";
423
+ /**
424
+ * Nudge reasons that end the current unit of work. `send_failed` stops delivery
425
+ * retry for that review, but may be followed by `cancelled` after explicit
426
+ * close-out.
427
+ */
428
+ export declare const TERMINAL_REVIEW_EVENT_REASONS: readonly ["sent", "send_failed", "cancelled"];
429
+ /** True when the agent must stop the current delivery/review action. */
430
+ export declare function isTerminalReviewEvent(reason: ReviewEventReason): boolean;
431
+ /**
432
+ * One durable review nudge (ndg_…) drained from the AUTHORITATIVE liveness queue
433
+ * (spec §11). `seq` is the per-review monotonic ordinal the ack cursor advances
434
+ * against (0 for a broadcast nudge). Opaque typed ids only (D10).
435
+ */
436
+ export interface ReviewEvent {
437
+ seq: number;
438
+ id: string;
439
+ reason: ReviewEventReason;
440
+ review_id?: string;
441
+ category_id?: string;
442
+ payload?: Record<string, unknown>;
443
+ created_at: string;
444
+ }
445
+ /** The agent's per-(agent, review) ack frontier — its strict-FIFO position. */
446
+ export interface ReviewEventCursor {
447
+ review_id: string;
448
+ last_acked_seq: number;
449
+ }
450
+ /**
451
+ * A category (cat_…) in the Review Loop registry (D9/D10). `name` + `description`
452
+ * are skill-style metadata the agent fuzzy-matches against; nothing keys on the
453
+ * name (renames never break a reference). Categories are CUSTOMER-scoped and
454
+ * agent-attributed — the deliberate cross-agent-404 exception. Opaque ids only.
455
+ */
456
+ export interface Category {
457
+ id: string;
458
+ name: string;
459
+ description: string;
460
+ scope: "org_shared" | "agent_private";
461
+ state: "supervised" | "auto_notify" | "auto_silent";
462
+ /** Survivor id when this category was merged / soft-deleted (cat_…). */
463
+ merged_into?: string;
464
+ created_by_agent_id?: string;
465
+ author_kind: "agent" | "human";
466
+ rule_high_water: number;
467
+ rules_version: number;
468
+ created_at: string;
469
+ updated_at: string;
470
+ }
471
+ /**
472
+ * The account-wide default risk dial (Review Loop, D4/D12) — the values a per-
473
+ * category null override inherits. The single user-configurable brand-risk lever.
474
+ */
475
+ export interface AccountRiskDial {
476
+ min_confidence: number;
477
+ first_contact_gate: boolean;
478
+ drift_demote_after: number;
479
+ canary_rate: number;
480
+ graduate_min_approvals: number;
481
+ graduate_min_age_hours: number;
482
+ auto_send_cap_per_day: number;
483
+ }
484
+ /** The RESOLVED risk dial for a category: account default with per-category override applied (D12). */
485
+ export interface EffectiveRiskDial {
486
+ min_confidence: number;
487
+ first_contact_gate: boolean;
488
+ drift_demote_after: number;
489
+ canary_rate: number;
490
+ graduate_min_approvals: number;
491
+ graduate_min_age_hours: number;
492
+ auto_send_cap_per_day: number;
493
+ }
494
+ /**
495
+ * One category's risk-dial OVERRIDE columns (null = inherit the account default;
496
+ * D12) alongside the resolved effective dial.
497
+ */
498
+ export interface CategoryRiskDial {
499
+ category_id: string;
500
+ min_confidence: number | null;
501
+ first_contact_gate: boolean | null;
502
+ drift_demote_after: number | null;
503
+ canary_rate: number | null;
504
+ graduate_min_approvals: number | null;
505
+ graduate_min_age_hours: number | null;
506
+ effective: EffectiveRiskDial;
507
+ }
508
+ /**
509
+ * The effective risk dial (Review Loop, agent plane; D4/D12): the account default
510
+ * plus every category's overrides. Read-only — agents read but never flip it (D16).
511
+ */
512
+ export interface RiskDial {
513
+ account: AccountRiskDial;
514
+ categories: CategoryRiskDial[];
515
+ }
516
+ /**
517
+ * The graduation gate status toward the NEXT rung (Review Loop, D16): clean approvals
518
+ * (N / needed), category age, the maturity gate (auto_silent precondition), drift vs
519
+ * K, and whether a human graduate would succeed right now. Read-only.
520
+ */
521
+ export interface GraduationStatus {
522
+ category_id: string;
523
+ state: "supervised" | "auto_notify" | "auto_silent";
524
+ next_state: string;
525
+ never_graduate: boolean;
526
+ clean_approval_count: number;
527
+ graduate_min_approvals: number;
528
+ approvals_met: boolean;
529
+ age_hours: number;
530
+ graduate_min_age_hours: number;
531
+ age_met: boolean;
532
+ maturity_gate_met: boolean;
533
+ drift_count: number;
534
+ drift_demote_after: number;
535
+ can_graduate: boolean;
536
+ }
537
+ /**
538
+ * The D19/§8 backlog-reconciliation snapshot for a category (agent-readable, $0-LLM):
539
+ * how many QUEUED drafts are stale vs current-enough against the current rules-version.
540
+ * Read-only — agents READ the picture; the human / hooks TRIGGER the actual sweep.
541
+ */
542
+ export interface ScanBacklogStatus {
543
+ category_id: string;
544
+ state: "supervised" | "auto_notify" | "auto_silent" | "probation";
545
+ queued: number;
546
+ current_enough: number;
547
+ stale: number;
548
+ current_category_rules_version: number;
549
+ current_house_style_version: number;
550
+ staleness_tolerance: number;
551
+ }
552
+ /** One queued draft's pacing classification relative to the cursor + window (§8). */
553
+ export interface PacingItem {
554
+ review_id: string;
555
+ state: "behind_cursor" | "in_window_fresh" | "in_window_redrafting" | "ahead";
556
+ }
557
+ /**
558
+ * The demand-driven pacing snapshot for a category (agent-readable, $0-LLM — M7 Slice
559
+ * B/§8): the human review cursor, the effective window/ceiling/interval, the queued
560
+ * count, and each queued draft's in-window/redrafting/behind-cursor classification.
561
+ * Read-only; the cursor advances from the human's console approve/reject/edit actions.
562
+ */
563
+ export interface CategoryPacingState {
564
+ category_id: string;
565
+ cursor_review_id?: string;
566
+ cursor_advanced_count: number;
567
+ lookahead_window: number;
568
+ rework_batch_max: number;
569
+ nudge_min_interval_ms: number;
570
+ queued: number;
571
+ in_window: number;
572
+ redrafting: number;
573
+ items: PacingItem[];
574
+ }
575
+ /** Drain result for list/wait — un-acked events in FIFO seq order + cursors. */
576
+ export interface ReviewEventsResult {
577
+ events: ReviewEvent[];
578
+ cursors?: ReviewEventCursor[];
579
+ }
580
+ /**
581
+ * A learned writing rule (rule_…) in the Review Loop (D2/D11). House-style/general
582
+ * (scope='general', applies across all categories) or category-scoped. Append-only
583
+ * by supersession: an edit is a new rev (same lineage_id) with the prior flipped to
584
+ * superseded. Read by the agent at compose/redraft time via the ORDERED get_rules
585
+ * ladder; we never apply it (NO LLM on our side). Opaque ids only (D10).
586
+ */
587
+ export interface Rule {
588
+ id: string;
589
+ /**
590
+ * Ownership layer (org/project model). `org` = house-style inherited by every
591
+ * project in the org; `project` = layered on top (the agent-plane default).
592
+ * Project/per-agent rules outrank broader org rules in the ordered get_rules
593
+ * ladder. Agent-plane saves are ALWAYS `project`.
594
+ */
595
+ rule_layer?: "org" | "project";
596
+ /** The org this rule belongs to. */
597
+ org_id?: string;
598
+ /** The project this rule belongs to; empty for an org-layer rule. */
599
+ project_id?: string;
600
+ lineage_id: string;
601
+ rev: number;
602
+ scope: "general" | "category";
603
+ /** Set iff scope=category (cat_…). */
604
+ category_id?: string;
605
+ /** Set for a per-agent override; empty = all org agents. */
606
+ scope_agent_id?: string;
607
+ rule_text: string;
608
+ kind: "soft" | "hard";
609
+ priority: number;
610
+ status: "proposed" | "active" | "superseded" | "retired";
611
+ supersedes_id?: string;
612
+ author_kind: "agent" | "human";
613
+ created_at: string;
614
+ updated_at: string;
615
+ }
616
+ /** One append-only rule/category change & undo audit row (udo_…). */
617
+ export interface RuleAuditEntry {
618
+ id: string;
619
+ entity_kind: "rule" | "category";
620
+ entity_id: string;
621
+ action: "create" | "supersede" | "retire" | "rename" | "redescribe" | "merge" | "restore";
622
+ actor_kind: "agent" | "human" | "system";
623
+ actor_id?: string;
624
+ before_json?: string;
625
+ after_json?: string;
626
+ undone: boolean;
627
+ created_at: string;
628
+ }
629
+ /** A Review Loop submit that was parked for human review (202). */
630
+ export interface QueuedForReviewResult {
631
+ kind: "queued_for_review";
632
+ review: {
633
+ id: string;
634
+ state: ReviewState;
635
+ effective_mode?: ReviewMode;
636
+ };
637
+ }
638
+ /**
639
+ * A Review Loop submit that was sent immediately (200) — the policy permitted a
640
+ * direct or graduated auto-send.
641
+ *
642
+ * `review` is the handle for the row that governed the send. It is present even
643
+ * here, on the path that never queued, so an agent that crashed between the
644
+ * request and the response can still ask what became of the message.
645
+ */
646
+ export interface SentResult {
647
+ kind: "sent";
648
+ message: {
649
+ id: string;
650
+ thread_id?: string;
651
+ };
652
+ review?: {
653
+ id: string;
654
+ state?: ReviewState;
655
+ };
656
+ }
657
+ /** The discriminated outcome of a review-mode submit (queued OR sent). */
658
+ export type SubmitForReviewResult = QueuedForReviewResult | SentResult;
659
+ /**
660
+ * Outcome of a message or thread delete (DELETE .../messages/{id} or
661
+ * .../threads/{id}). `expunged` is true when removed permanently, false when
662
+ * moved to Trash. `count` is the number of messages affected.
663
+ */
664
+ export interface DeleteResult {
665
+ id: string;
666
+ deleted: true;
667
+ expunged: boolean;
668
+ count: number;
669
+ }
670
+ /**
671
+ * Per-id outcome of a batch message update (PATCH .../messages/batch):
672
+ * `updated` ids succeeded; `failed` ids were skipped (not found / not owned).
673
+ */
674
+ export interface BatchUpdateResult {
675
+ updated: string[];
676
+ failed: string[];
677
+ }
678
+ /** Result of redeeming an enrollment token for a scoped agent key (spec §5). */
679
+ export interface EnrollmentResult {
680
+ /** The minted agent identity. */
681
+ agent_id: string;
682
+ /** The scoped agent key — shown once. Format `pk_agent_<id>_<secret>`. */
683
+ agent_key: string;
684
+ /** Capability scopes granted to this key. */
685
+ scopes: AgentScope[];
686
+ /**
687
+ * The FIXED org the minted key is bound to (the token's resolved org). The
688
+ * agent cannot change it.
689
+ */
690
+ org_id?: string;
691
+ /**
692
+ * The FIXED project the minted key is bound to (the token's resolved project).
693
+ * The agent cannot change it — there is no mutable project selector.
694
+ */
695
+ project_id?: string;
696
+ }
697
+ /**
698
+ * Structured result of a `wait_for_email` call. Returns the matched message
699
+ * plus the extracted OTP code / verification link when present (spec §6).
700
+ */
701
+ export interface WaitForEmailResult {
702
+ /** True if a message matched before the timeout elapsed. */
703
+ matched: boolean;
704
+ /** The matched message, when `matched` is true. */
705
+ message?: Message;
706
+ /** Extracted one-time code (digits/alnum), when found. */
707
+ otp_code?: string;
708
+ /** Extracted verification/click-through link, when found. */
709
+ verification_link?: string;
710
+ /** Milliseconds spent waiting. */
711
+ waited_ms: number;
712
+ }
713
+ /** Result of a self-signup (Slice E). The key is LIMITED until verified. */
714
+ export interface SignUpResult {
715
+ customer_id: string;
716
+ agent_id: string;
717
+ /** Limited-scope agent key, shown once. */
718
+ agent_key: string;
719
+ key_prefix: string;
720
+ scopes: AgentScope[];
721
+ /** The first inbox minted for the agent. */
722
+ address: string;
723
+ verified: boolean;
724
+ /** Where the verification code was sent. */
725
+ otp_sent_to: string;
726
+ otp_expires_at: string;
727
+ message: string;
728
+ }
729
+ /** Result of confirming a signup OTP — a new full-scope key. */
730
+ export interface VerifyResult {
731
+ agent_id: string;
732
+ agent_key: string;
733
+ key_prefix: string;
734
+ scopes: AgentScope[];
735
+ verified: boolean;
736
+ message: string;
737
+ }
738
+ /**
739
+ * The verified principal behind an agent key (GET /v1/auth/me). `org_id` /
740
+ * `project_id` are the FIXED org/project the key is bound to (resolved from the
741
+ * stored key, never client input). There is NO mutable project selector for a
742
+ * scoped key — whoami is the canonical project-visibility surface; project
743
+ * selection happens when the human/admin issues the enrollment token or agent key.
744
+ */
745
+ export interface WhoAmI {
746
+ customer_id: string;
747
+ /** The fixed org the key is bound to. */
748
+ org_id?: string;
749
+ /** The fixed project the key is bound to. */
750
+ project_id?: string;
751
+ agent_id: string;
752
+ key_id: string;
753
+ scopes: AgentScope[];
754
+ }
755
+ /** Webhook event types Extrovert emits. */
756
+ /**
757
+ * A webhook event type the server accepts. `unsubscribe.received` fires when a
758
+ * recipient opts out (one-click List-Unsubscribe or a STOP reply) — the signal an
759
+ * agent needs to drop them from its own lists BEFORE the next send is refused
760
+ * with `recipient_suppressed`.
761
+ */
762
+ export type WebhookEvent = "message.received" | "unsubscribe.received";
763
+ /**
764
+ * A registered inbound webhook (mirrors the Go `webhookResponse`). `secret` is
765
+ * present only on the registration response (returned once); list/get reads omit
766
+ * it. `inbox` is null when the webhook covers every inbox the agent owns.
767
+ */
768
+ export interface Webhook {
769
+ id: string;
770
+ url: string;
771
+ events: WebhookEvent[];
772
+ inbox: string | null;
773
+ /** Agent that owns this webhook. */
774
+ agent_id?: string;
775
+ /** HMAC signing secret — returned ONCE at registration, omitted on reads. */
776
+ secret?: string;
777
+ /** Display prefix of the secret, safe to store/show. */
778
+ secret_prefix: string;
779
+ active: boolean;
780
+ created_at: string;
781
+ }
782
+ /** Whether a contact-list entry permits (allow) or rejects (block) a match. */
783
+ export type ContactListKind = "allow" | "block";
784
+ /** Traffic direction a contact-list entry governs. Only `send` is enforced today. */
785
+ export type ContactListDirection = "send" | "receive";
786
+ /**
787
+ * A contact allow/block-list entry (mirrors the Go `contactListEntryResponse`).
788
+ * `inbox` is null when the entry is account-wide (covers every inbox the agent
789
+ * owns). `pattern` is a bare email address or a bare domain.
790
+ */
791
+ export interface ContactListEntry {
792
+ id: string;
793
+ inbox: string | null;
794
+ kind: ContactListKind;
795
+ direction: ContactListDirection;
796
+ pattern: string;
797
+ created_at: string;
798
+ }
799
+ /**
800
+ * A page of results from a list endpoint, in the MCP's normalized internal shape.
801
+ *
802
+ * The canonical agent surface returns two wire shapes that the client normalizes
803
+ * INTO this one before handing it to the tools:
804
+ * - the §5.2 ONE envelope `{object:"list", data, has_more, next_cursor}` (the
805
+ * project-prefixed inbox list `/v1/projects/{id}/inboxes`), and
806
+ * - the legacy `{items, total, next_cursor}` page (messages/threads/attachments,
807
+ * webhooks, domains, contact-lists, reviews, rules — these KEEP `items`).
808
+ * Either way the tools read `.items` / `.next_cursor`.
809
+ */
810
+ export interface Page<T> {
811
+ items: T[];
812
+ /** Opaque cursor for the next page, when more results exist. Pass back as `?cursor`. */
813
+ next_cursor?: string;
814
+ /** Total count when cheaply known. */
815
+ total?: number;
816
+ }
817
+ /**
818
+ * The ONE canonical list envelope (redesign §5.2) for the cursor-paginated agent
819
+ * surface. `next_cursor` is an opaque pagination token (pass it back verbatim as
820
+ * `?cursor`); it is null when there are no more rows. The MCP client normalizes
821
+ * this into {@link Page} via {@link listEnvelopeToPage}.
822
+ */
823
+ export interface List<T> {
824
+ object: "list";
825
+ data: T[];
826
+ has_more: boolean;
827
+ next_cursor: string | null;
828
+ }
829
+ /** Normalize the §5.2 `List` envelope into the MCP's internal {@link Page} shape. */
830
+ export declare function listEnvelopeToPage<T>(list: List<T>): Page<T>;
831
+ /**
832
+ * The scope a suppression row applies at. The agent plane only ever sees `org`
833
+ * rows (the caller's OWN org) — a platform-`global` or `shared_domain` opt-out is
834
+ * never surfaced (non-leakage). The wider values exist for forward-compatibility.
835
+ */
836
+ export type SuppressionScope = "org" | "shared_domain" | "global";
837
+ /** How a suppression came to exist (which signal created the opt-out row). */
838
+ export type SuppressionSource = "one_click" | "page" | "mailto" | "reply_stop" | "manual" | "complaint" | "escalation";
839
+ /**
840
+ * One recipient opt-out row (mirrors the Go `suppressionResponse`). A recipient
841
+ * with an active (non-`revoked`) row for the sender's org is blocked from receiving
842
+ * mail; a send to them is rejected with `recipient_suppressed`. Revoke a row (with
843
+ * a reason) to re-enable sending to that recipient.
844
+ */
845
+ export interface SuppressionEntry {
846
+ id: string;
847
+ recipient: string;
848
+ recipient_raw?: string;
849
+ scope: SuppressionScope;
850
+ source: SuppressionSource;
851
+ narrow_agent_id?: string;
852
+ narrow_mailbox?: string;
853
+ origin_mailbox?: string;
854
+ origin_agent_id?: string;
855
+ origin_message_id?: string;
856
+ reactivation_count: number;
857
+ created_at: string;
858
+ revoked_at?: string;
859
+ revoked_by?: string;
860
+ revoke_reason?: string;
861
+ revoked: boolean;
862
+ }
863
+ /**
864
+ * The result of a pre-check (`GET /v1/suppressions?recipient=…`): whether the
865
+ * caller's OWN org suppresses the recipient, plus the matching org rows. Reflects
866
+ * only the caller's org state — never a global/shared/cross-tenant opt-out.
867
+ */
868
+ export interface SuppressionPrecheck {
869
+ recipient: string;
870
+ suppressed: boolean;
871
+ rows: SuppressionEntry[];
872
+ }
873
+ /** One provider/tenant's deliverability status within the org rollup. */
874
+ export interface ReputationProvider {
875
+ provider: string;
876
+ provider_account_id: string;
877
+ label?: string;
878
+ region?: string;
879
+ tenant_name?: string;
880
+ sending_status: string;
881
+ reputation_policy?: string;
882
+ aws_managed_status?: string;
883
+ customer_managed_status?: string;
884
+ /** `available` or `unavailable_vdm_disabled` (findings degrade when VDM is off). */
885
+ advisor_findings_status: string;
886
+ last_polled_at?: string;
887
+ }
888
+ /** The latest window's Sends/Bounces/Complaints rollup for the org. */
889
+ export interface ReputationMetrics {
890
+ window_start?: string;
891
+ window_end?: string;
892
+ sends: number;
893
+ bounces: number;
894
+ complaints: number;
895
+ bounce_rate: number;
896
+ complaint_rate: number;
897
+ }
898
+ /** The org's deliverability rollup (`GET /v1/reputation`). Read-only. */
899
+ export interface ReputationRollup {
900
+ object: "reputation";
901
+ org_id: string;
902
+ /** UI badge: healthy/at_risk/paused/enforced/unknown. */
903
+ status: string;
904
+ sending_status: string;
905
+ providers: ReputationProvider[];
906
+ metrics: ReputationMetrics;
907
+ open_findings: number;
908
+ }
909
+ /** One deliverability finding (`GET /v1/reputation/findings`). */
910
+ export interface ReputationFinding {
911
+ id: string;
912
+ type: string;
913
+ severity: string;
914
+ status: string;
915
+ domain?: string;
916
+ sender?: string;
917
+ title: string;
918
+ detail: string;
919
+ first_seen_at: string;
920
+ last_seen_at: string;
921
+ resolved_at?: string;
922
+ }
923
+ /** Filters for `GET /v1/reputation/findings`. */
924
+ export interface ListDeliverabilityFindingsInput {
925
+ status?: "open" | "resolved";
926
+ severity?: "low" | "high" | "unknown";
927
+ domain?: string;
928
+ sender?: string;
929
+ limit?: number;
930
+ cursor?: string;
931
+ }
932
+ /** One DNS record the customer must set (manual mode) or that we serve (ns_delegated). */
933
+ export interface DomainRecord {
934
+ name: string;
935
+ type: string;
936
+ value: string;
937
+ /** MX priority, when applicable. */
938
+ priority?: number | null;
939
+ ttl: number;
940
+ }
941
+ /**
942
+ * The agent-facing view of one onboarded domain (mirrors the Go `domainResponse`).
943
+ * `records` (and `delegation_ns` for ns_delegated) are present on get / onboard /
944
+ * verify and empty on list reads and for shared/purchased modes.
945
+ */
946
+ export interface Domain {
947
+ id: string;
948
+ domain: string;
949
+ mode: OnboardingMode;
950
+ verification_status: string;
951
+ dkim_status: string;
952
+ shared: boolean;
953
+ provisioning_phase?: string;
954
+ provisioning_error?: string;
955
+ created_at: string;
956
+ records?: DomainRecord[];
957
+ delegation_ns?: DomainRecord[];
958
+ /** Human-facing copy for what the customer must do next. */
959
+ instruction?: string;
960
+ }
961
+ /**
962
+ * Result of an ACCEPTED domain offboard (`DELETE /v1/domains/{domain}` → 202).
963
+ * Teardown runs as an async job; poll `status_url` (`GET /v1/jobs/{job_id}`) until
964
+ * `status` is terminal (succeeded/failed/cancelled).
965
+ */
966
+ export interface DomainOffboard {
967
+ domain: string;
968
+ job_id: string;
969
+ status: string;
970
+ status_url: string;
971
+ }
972
+ /**
973
+ * Poll-loop status for one async job (currently only the domain-offboard
974
+ * teardown's `status_url`). Mirrors `GET /v1/jobs/{job_id}`. `status` is
975
+ * terminal on succeeded/failed/cancelled; keep polling otherwise.
976
+ */
977
+ export interface Job {
978
+ object: "job";
979
+ id: string;
980
+ type: string;
981
+ status: string;
982
+ created_at: string;
983
+ updated_at: string;
984
+ finished_at?: string;
985
+ }
986
+ /** One IMAP/SMTP endpoint for a mailbox. */
987
+ export interface MailboxEndpoint {
988
+ host: string;
989
+ port: number;
990
+ /** "tls" = implicit TLS (IMAP 993); "starttls" = upgrade (SMTP 587). */
991
+ security: "tls" | "starttls";
992
+ }
993
+ /** Full connection config + login for a mailbox — enough to configure any mail
994
+ * client (Himalaya, mbsync, Thunderbird, …). */
995
+ export interface MailboxCredentials {
996
+ address: string;
997
+ username: string;
998
+ password: string;
999
+ imap: MailboxEndpoint;
1000
+ smtp: MailboxEndpoint;
1001
+ }
1002
+ /**
1003
+ * One machine-readable field hint on a problem response (`problem.errors[]`).
1004
+ *
1005
+ * The shape is deliberately narrow — `{field, code, detail}` only — and is reused
1006
+ * for more than validation: a remediation carries `{field:"retry_with",
1007
+ * code:"example", detail:"<the JSON to add>"}`, and a 409 carries the recovery
1008
+ * facts (`state`, `revision`, `version`, one `allowed_action` per legal verb) so a
1009
+ * retry needs no extra round trip.
1010
+ */
1011
+ export interface ProblemField {
1012
+ field: string;
1013
+ code: string;
1014
+ detail?: string;
1015
+ }
1016
+ /**
1017
+ * The CLOSED machine-code enum an agent switches on. Kept set-equal to the Go
1018
+ * `ProblemCode` constants and the openapi `Problem.code` enum; drift here is the
1019
+ * exact class of bug that let clients see `http_409` and no server message.
1020
+ */
1021
+ export type ProblemCode = "bad_request" | "unauthorized" | "forbidden_scope" | "not_found" | "conflict" | "idempotency_conflict" | "breadth_required" | "quota_exceeded" | "rate_limited" | "domain_not_allowed" | "recipient_blocked" | "recipient_suppressed" | "not_configured" | "domain_unavailable" | "internal" | "intent_required" | "wrong_state" | "terminal" | "stale" | "born_stale" | "send_needs_reconciliation" | "graduation_locked" | "maturity_gate_unmet" | "scope_taken" | "unavailable";
1022
+ /** The same closed enum as a runtime array (for membership checks + tests). */
1023
+ export declare const PROBLEM_CODES: readonly ProblemCode[];
1024
+ /**
1025
+ * The 409 codes an agent MAY retry, and only a bounded number of times: the CAS
1026
+ * lost a race (`stale`) or the draft was built against an older rule high-water
1027
+ * (`born_stale`). Re-read, re-apply on top of the other party's change, resubmit.
1028
+ *
1029
+ * Every OTHER 409 — `wrong_state`, `terminal`, `send_needs_reconciliation`,
1030
+ * `idempotency_conflict`, bare `conflict` — must NEVER be retried with the same
1031
+ * verb. That distinction is the whole point of splitting the taxonomy: a single
1032
+ * "409 → retry" handler loops forever on a review that is already sent.
1033
+ */
1034
+ export declare const RETRYABLE_PROBLEM_CODES: readonly ProblemCode[];
1035
+ /** True when this problem code is worth a bounded retry after re-reading state. */
1036
+ export declare function isRetryableProblemCode(code: string | undefined): boolean;
1037
+ //# sourceMappingURL=types.d.ts.map