@extrovert.dev/sdk 0.1.0-pre.4 → 0.1.0-pre.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -30,7 +30,7 @@ for a stable release:
30
30
  npm install @extrovert.dev/sdk@next
31
31
  ```
32
32
 
33
- Pin `@extrovert.dev/sdk@0.1.0-pre.4` when a dogfood test needs a reproducible contract snapshot.
33
+ Pin `@extrovert.dev/sdk@0.1.0-pre.6` when a dogfood test needs a reproducible contract snapshot.
34
34
  Requires Node 18+ for global `fetch` and Web Crypto.
35
35
 
36
36
  ## Build and use from source
@@ -419,6 +419,7 @@ A key carries a subset of these capability scopes (`whoami().scopes`):
419
419
  | ----------------- | ---------------------------------------------------------------------- |
420
420
  | `mailbox:create` | Create inboxes. |
421
421
  | `mailbox:read` | Read inboxes, messages, threads. |
422
+ | `mailbox:credentials` | Export raw IMAP/SMTP credentials on paid plans; never implied by read. |
422
423
  | `mailbox:send` | Send / reply / forward. |
423
424
  | `mailbox:quota` | Change an inbox's effective daily recipient cap (opt-in). |
424
425
  | `mailbox:delete` | Delete inboxes. |
@@ -442,7 +443,7 @@ a wire protocol (there is no `/v1/contract` endpoint).
442
443
  ```ts
443
444
  import { CONTRACT_VERSION, CONTRACT_MANIFEST } from "@extrovert.dev/sdk";
444
445
 
445
- CONTRACT_VERSION; // "0.1.0-pre.4" — provisional, pre-1.0; pin it
446
+ CONTRACT_VERSION; // "0.1.0-pre.6" — provisional, pre-1.0; pin it
446
447
  CONTRACT_MANIFEST.stability; // "provisional"
447
448
  CONTRACT_MANIFEST.core_shapes; // ["ReviewIntent","ReviewFeedback","DiffJson","Rule","ReviewEvent"]
448
449
  ```
@@ -463,7 +464,7 @@ page and the agent skills (`extrovert-send-email`, `extrovert-writing-rules`).
463
464
  The Review-Loop shapes are an **open, documented contract — versioned *with* this SDK** (not a wire
464
465
  protocol; there is no `/v1/contract` endpoint). Three guarantees:
465
466
 
466
- - **One version, everywhere.** `CONTRACT_VERSION` is **`0.1.0-pre.4`**, reconciled across the SDK package
467
+ - **One version, everywhere.** `CONTRACT_VERSION` is **`0.1.0-pre.6`**, reconciled across the SDK package
467
468
  version, the MCP server, and the OpenAPI `info.version`. Pin it; pin `CONTRACT_MANIFEST` for the
468
469
  exact shape set you built against.
469
470
  - **Named, documented types.** The five canonical shapes — `ReviewIntent`, `ReviewFeedback`,
@@ -494,7 +495,7 @@ EXTROVERT_API_BASE_URL=mock npx tsx examples/wait-for-otp.ts
494
495
 
495
496
  ## Status
496
497
 
497
- > **Note.** This source SDK tracks the `/v1` contract at `CONTRACT_VERSION` `0.1.0-pre.4` — a
498
+ > **Note.** This source SDK tracks the `/v1` contract at `CONTRACT_VERSION` `0.1.0-pre.6` — a
498
499
  > deliberate **prerelease**, pre-1.0, expect additive change. The offline `mock` transport models the
499
500
  > live server closely enough to reproduce a 422 `intent_required` and a queued review, so build and
500
501
  > test against it before you have a key. Install from the `next` tag until a stable release is cut.
package/dist/index.cjs CHANGED
@@ -268,7 +268,7 @@ var CURRENT_API_VERSION = "2026-06-23";
268
268
  var API_VERSION_HEADER = "Extrovert-Version";
269
269
 
270
270
  // src/http.ts
271
- var SDK_VERSION = "0.1.0-pre.4";
271
+ var SDK_VERSION = "0.1.0-pre.6";
272
272
  function buildUrl(baseUrl, path, query) {
273
273
  const base = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
274
274
  const rel = path.startsWith("/") ? path : `/${path}`;
@@ -625,6 +625,23 @@ function decodeMockCursor(cursor) {
625
625
  return 0;
626
626
  }
627
627
  }
628
+ function mailboxQuickstart(address) {
629
+ return {
630
+ inbox: address,
631
+ list_mail: {
632
+ tool: "read_messages",
633
+ arguments: { inbox: address, limit: 20, unread_only: false }
634
+ },
635
+ read_message: {
636
+ tool: "get_message",
637
+ arguments: { id: "<message_id from read_messages>", format: "text", variant: "extracted" }
638
+ },
639
+ wait_for_mail: {
640
+ tool: "wait_for_email",
641
+ arguments: { inbox: address, since_now: true }
642
+ }
643
+ };
644
+ }
628
645
  var SHARED_SUBDOMAIN = "smtp.extrovert.dev";
629
646
  var MOCK_ORG_ID = "org_mock";
630
647
  var MOCK_PROJECT_ID = "prj_mock";
@@ -935,14 +952,14 @@ var MockBackend = class {
935
952
  const customerId = existing?.customerId ?? `cus_pn_signup_${rid("c").slice(2)}`;
936
953
  const agentId = existing?.agentId ?? rid("agt");
937
954
  const address = existing?.address ?? `${req.username ?? randomHandle()}@smtp.extrovert.dev`;
938
- const otp = String(Math.floor(1e5 + Math.random() * 9e5));
955
+ const otp = "492013";
939
956
  this.state.signupByEmail.set(email, { customerId, agentId, address, otp, verified: false });
940
957
  return {
941
958
  customer_id: customerId,
942
959
  agent_id: agentId,
943
960
  agent_key: `pk_agent_${agentId.slice(4)}_${rid("sk").slice(3)}`,
944
961
  key_prefix: `pk_agent_${agentId.slice(4, 8)}`,
945
- scopes: ["mailbox:read"],
962
+ scopes: ["signup:verify"],
946
963
  address,
947
964
  verified: false,
948
965
  otp_sent_to: email,
@@ -960,8 +977,10 @@ var MockBackend = class {
960
977
  agent_key: `pk_agent_${s.agentId.slice(4)}_${rid("sk").slice(3)}`,
961
978
  key_prefix: `pk_agent_${s.agentId.slice(4, 8)}`,
962
979
  scopes: ["mailbox:create", "mailbox:read", "mailbox:send"],
980
+ address: s.address,
963
981
  verified: true,
964
- message: "Verified. Use the new agent_key (full scopes)."
982
+ message: "Verified. The inbox is ready; use read_messages, then get_message with a returned message id.",
983
+ mailbox_quickstart: mailboxQuickstart(s.address)
965
984
  };
966
985
  }
967
986
  }
@@ -1971,7 +1990,15 @@ var MockBackend = class {
1971
1990
  category = active.filter((r) => r.scope === "category" && r.category_id === params.category_id).sort(byRank);
1972
1991
  }
1973
1992
  const items = [...category, ...general];
1974
- return { items, total: items.length };
1993
+ return {
1994
+ items,
1995
+ total: items.length,
1996
+ house_style_version: 1,
1997
+ category_rules_version: params.category_id ? 1 : 0,
1998
+ rule_high_water: params.category_id ? 1 : 0,
1999
+ composition_token: params.scope ? void 0 : `cmp_fixture_${params.category_id ?? "general"}`,
2000
+ composition_token_expires_at: params.scope ? void 0 : new Date(Date.now() + 6e5).toISOString()
2001
+ };
1975
2002
  }
1976
2003
  /** Save / edit a rule (mock) — append-only by supersession (D11). */
1977
2004
  saveRule(req) {
@@ -3579,7 +3606,13 @@ var HttpTransport = class {
3579
3606
  });
3580
3607
  }
3581
3608
  saveRule(req, signal) {
3582
- return this.call({ method: "PUT", path: "/v1/rules", body: req, signal });
3609
+ return this.call({
3610
+ method: "PUT",
3611
+ path: "/v1/rules",
3612
+ body: withoutIdempotencyKey(req),
3613
+ idempotencyKey: req.idempotency_key,
3614
+ signal
3615
+ });
3583
3616
  }
3584
3617
  promoteRule(ruleId, toScope, signal) {
3585
3618
  return this.call({
@@ -4976,6 +5009,8 @@ var ExtrovertClient = class _ExtrovertClient {
4976
5009
  * + a first inbox and returns a LIMITED-scope (read-only) agent key; a one-time
4977
5010
  * code is emailed to `human_email`. Call {@link verify} with the code to unlock
4978
5011
  * full scopes. Idempotent on `human_email`: re-calling rotates the key + resends.
5012
+ * When free signup is paused, this throws an `ApiError` with status 403 and
5013
+ * code `signup_disabled` without creating account state.
4979
5014
  */
4980
5015
  signUp(req, signal) {
4981
5016
  return this.transport.signUp(req, signal);
@@ -4983,6 +5018,10 @@ var ExtrovertClient = class _ExtrovertClient {
4983
5018
  /**
4984
5019
  * Confirm the emailed signup code and receive a NEW full-scope agent key (shown
4985
5020
  * once). Must be called with the limited key from {@link signUp} as the bearer.
5021
+ * The result repeats the ready inbox address and includes MCP-first list/read/wait
5022
+ * calls; SDK callers can pass `address` directly to `inboxes` and `messages`.
5023
+ * Pending verification is also fail-closed with 403 `signup_disabled` while
5024
+ * free signup is paused.
4986
5025
  */
4987
5026
  verify(req, signal) {
4988
5027
  return this.transport.verify(req, signal);
@@ -5150,7 +5189,7 @@ async function signWebhook(secret, body, timestampSeconds) {
5150
5189
  }
5151
5190
 
5152
5191
  // src/contract.ts
5153
- var CONTRACT_VERSION = "0.1.0-pre.4";
5192
+ var CONTRACT_VERSION = "0.1.0-pre.6";
5154
5193
  var CONTRACT_MANIFEST = {
5155
5194
  name: "extrovert.review-loop",
5156
5195
  version: CONTRACT_VERSION,