@curviate/sdk 0.24.3 → 0.25.0

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/CHANGELOG.md CHANGED
@@ -7,7 +7,88 @@ Versioning: semantic. Minor for additive changes, patch for bug fixes; no stabil
7
7
 
8
8
  ---
9
9
 
10
- ## [Unreleased]
10
+ ## [0.25.0] - 2026-09-05
11
+
12
+ **BREAKING** for a consumer that pinned the old type declarations: `quotas[]`
13
+ on `GET /v1/accounts/{account_id}` is a different array, and `message_id` on
14
+ `startChat`, `sendMessage`, `sendInMail` and the company chat reply is now
15
+ `string | string[] | null` where it was `string`. Both are detailed under
16
+ "Regenerated types" below. Pre-1.0 a breaking change ships as a minor, so a
17
+ caret range on `0.24.x` will not pick this up.
18
+
19
+ ### Added
20
+
21
+ - **`BUDGET_EXHAUSTED`, the account-safety refusal, and its payload.** A `429`
22
+ that is Curviate's own ceiling rather than a request-rate limit: nothing
23
+ reached LinkedIn and nothing was spent. `CurviateError` gains `budgetRow`
24
+ (wire `row`), `resetAt` (`reset_at`, and `null` in the two cases no clock
25
+ frees: the `pending_invites` gauge and an InMail credit exhaustion),
26
+ `safetyHint` (`hint`, the settable parameter
27
+ on `PATCH /v1/{account_id}/safety-policy`), `safetyReason` (`reason`:
28
+ `ceiling` or `activity_window`) and `blocked`. All six ride `toJSON()`.
29
+ The code is deliberately NOT retryable: a monthly row's reset can be weeks
30
+ out, so a backoff loop burns retries against a wall that will not move.
31
+ On a successful response the same payload arrives under `safety_warning`
32
+ with `blocked: false`, typed on the generated response types.
33
+ - **`budgetRow` and `retryAfterSeconds` on a paused-row `PLATFORM_RATE_LIMIT`.**
34
+ Same wire `row`, different meaning: LinkedIn refused a recent call on that
35
+ row, so the next one is refused locally until the pause lifts. The pause is
36
+ scoped to `(account, row)`, so the recovery is to switch work rather than
37
+ back off across the account. `retry_after` is deliberately NOT folded into
38
+ `retryAfterMs`, which everything sleeps.
39
+ - **A response carrying `row` is never auto-retried, on any method.**
40
+ - **`LINKEDIN_SESSION_EVICTED`.** A 401 split from `LINKEDIN_AUTH_FAILED`
41
+ because the remedies differ: reconnecting does nothing while the other
42
+ session is open. Not retryable.
43
+
44
+ ### Changed
45
+
46
+ - **Fixture regenerated against the deployed production document**
47
+ (`https://api.curviate.com`, `git_sha 33b42521...`), and the generated
48
+ types with it. Two shape changes are BREAKING for a consumer that pinned
49
+ the old declarations, and one enum widened. See "Regenerated types" below.
50
+
51
+ ### Regenerated types
52
+
53
+ - **BREAKING - `quotas[]` on `GET /v1/accounts/{account_id}` is a different
54
+ array.** `quota_name`, `remaining`, `total`, `reset_time` and
55
+ `recommended_throttle_hint` are gone. Each row now carries `budget_row`,
56
+ `kind` (`debit` / `tally` / `gauge`), `window`, `window_start`, `resets_at`,
57
+ `used`, `ceiling`, `effective_ceiling`, `band`, `posture`, `over_default`,
58
+ `halt` and, on the gauge, `observed_at`. **Compare `used` against
59
+ `effective_ceiling`**, which is `ceiling` with the account's warm-up ramp
60
+ applied; on a new account the two differ by roughly a factor of seven.
61
+ `used` is `null` only on the gauge, and only before anything has observed
62
+ it. The per-minute REQUEST ceiling is deliberately not in this array.
63
+ - **BREAKING - `message_id` is `string | string[] | null`** on `startChat`,
64
+ `sendMessage`, `sendInMail` and the company chat reply, where it was
65
+ `string`. `null` when no message was actually sent, an array when the
66
+ message was delivered as several, one per attachment. Confirm a send with
67
+ `chat_id`, which is always present.
68
+ - Chat-search results: `type` gains `channel`. The generated comment used to
69
+ say search results are never channels; that is no longer true, so an
70
+ exhaustive `switch` over `type` needs a third arm.
71
+ - Additive: `GET`/`PATCH /v1/{account_id}/safety-policy`,
72
+ `GET /v1/{account_id}/safety-events`, the four retained-event operations
73
+ under `/v1/{account_id}/events`, a `SafetyWarning` component reachable as
74
+ `safety_warning` on 149 success responses, six new optional fields on the
75
+ shared `Error` component, `coverage` on chat search, `mode` and `max_age`
76
+ query params on the store-served reads, `account_states[]` on the account
77
+ resource, and `observed_at` / `source` / `withdrawn` becoming REQUIRED on
78
+ four entity reads (a response gaining guarantees, not losing them).
79
+
80
+ - **`postpublish` now notices a stale CLI pin.** After every `npm publish`,
81
+ `scripts/check-cli-notice.mjs` compares the version just published
82
+ against what `@curviate/cli` actually declares for `@curviate/sdk` on the
83
+ registry (never a dist-tag lookup, since `npm view @curviate/sdk version`
84
+ returns `latest` and this package's own RC/0.x releases route to `--tag
85
+ next`). Exits non-zero, loudly, when the CLI has not picked up the
86
+ release yet. It cannot undo the publish and does not try to; it replaces
87
+ the prior manual runbook step, which could not fail by construction
88
+ (the SDK-CLI drift-notice defect).
89
+ - `check:clean` now flags a committed npm auth token (`npm_`-prefixed
90
+ shape), and `.npmrc`/`*.tgz` are gitignored. Same gap as the sibling
91
+ `cli` package's copy of this scanner (security-auditor F3).
11
92
 
12
93
  ## [0.24.3] - 2026-08-27
13
94
 
package/README.md CHANGED
@@ -109,6 +109,16 @@ try {
109
109
  // err.retryAfterMs tells you exactly how long to wait
110
110
  await sleep(err.retryAfterMs ?? 5_000);
111
111
  break;
112
+ case "BUDGET_EXHAUSTED":
113
+ // Curviate's OWN account-safety ceiling, not a request-rate limit:
114
+ // nothing reached LinkedIn and nothing was spent, so backing off is the
115
+ // wrong move. Wait until err.resetAt, or raise the setting the hint
116
+ // names on PATCH /v1/{account_id}/safety-policy.
117
+ // resetAt is null in the two cases no clock frees: the pending_invites
118
+ // backlog, and an InMail credit pool LinkedIn regrants on its own schedule.
119
+ console.warn(`${err.budgetRow} is spent until ${err.resetAt ?? "no fixed time"}`);
120
+ console.warn(`change ${err.safetyHint?.parameter} to lift it`);
121
+ break;
112
122
  case "ACCOUNT_NOT_FOUND":
113
123
  console.error("Account does not exist for this tenant.");
114
124
  break;