@managoat/fountain-sdk 1.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.
Files changed (55) hide show
  1. package/CHANGELOG.md +653 -0
  2. package/LICENSE +202 -0
  3. package/README.md +445 -0
  4. package/dist/client.d.ts +190 -0
  5. package/dist/client.js +225 -0
  6. package/dist/client.js.map +1 -0
  7. package/dist/config.d.ts +49 -0
  8. package/dist/config.js +87 -0
  9. package/dist/config.js.map +1 -0
  10. package/dist/conversation.d.ts +100 -0
  11. package/dist/conversation.js +189 -0
  12. package/dist/conversation.js.map +1 -0
  13. package/dist/errors.d.ts +102 -0
  14. package/dist/errors.js +197 -0
  15. package/dist/errors.js.map +1 -0
  16. package/dist/generated/openapi.d.ts +16654 -0
  17. package/dist/generated/openapi.js +6 -0
  18. package/dist/generated/openapi.js.map +1 -0
  19. package/dist/http.d.ts +37 -0
  20. package/dist/http.js +129 -0
  21. package/dist/http.js.map +1 -0
  22. package/dist/index.d.ts +14 -0
  23. package/dist/index.js +13 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/node.d.ts +2 -0
  26. package/dist/node.js +21 -0
  27. package/dist/node.js.map +1 -0
  28. package/dist/queue.d.ts +25 -0
  29. package/dist/queue.js +64 -0
  30. package/dist/queue.js.map +1 -0
  31. package/dist/resolve.d.ts +29 -0
  32. package/dist/resolve.js +89 -0
  33. package/dist/resolve.js.map +1 -0
  34. package/dist/resources.d.ts +126 -0
  35. package/dist/resources.js +206 -0
  36. package/dist/resources.js.map +1 -0
  37. package/dist/run.d.ts +81 -0
  38. package/dist/run.js +247 -0
  39. package/dist/run.js.map +1 -0
  40. package/dist/schemas.d.ts +90 -0
  41. package/dist/schemas.js +2 -0
  42. package/dist/schemas.js.map +1 -0
  43. package/dist/sse.d.ts +58 -0
  44. package/dist/sse.js +219 -0
  45. package/dist/sse.js.map +1 -0
  46. package/dist/team.d.ts +90 -0
  47. package/dist/team.js +183 -0
  48. package/dist/team.js.map +1 -0
  49. package/dist/turn.d.ts +46 -0
  50. package/dist/turn.js +205 -0
  51. package/dist/turn.js.map +1 -0
  52. package/dist/types.d.ts +144 -0
  53. package/dist/types.js +2 -0
  54. package/dist/types.js.map +1 -0
  55. package/package.json +61 -0
package/CHANGELOG.md ADDED
@@ -0,0 +1,653 @@
1
+ # Changelog
2
+
3
+ Notable changes to `@managoat/fountain-sdk`, published as
4
+ `@agentshit/fountain-sdk` up to 1.23.0. Format:
5
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/); versions follow
6
+ [SemVer](https://semver.org/).
7
+
8
+ The SDK versions independently of the Fountain server. It talks to the REST
9
+ API, which is additive, so a given SDK release keeps working against later
10
+ server releases.
11
+
12
+ ---
13
+
14
+ ## [1.25.0] — 2026-09-10
15
+
16
+ ### Changed
17
+
18
+ - **The package is now `@managoat/fountain-sdk`.** Same library, same API, same
19
+ version line: 1.25.0 follows 1.24.0. Update the dependency and the import
20
+ specifier; nothing else about your code changes.
21
+
22
+ ```
23
+ npm remove @agentshit/fountain-sdk
24
+ npm install @managoat/fountain-sdk
25
+ ```
26
+
27
+ `@agentshit/fountain-sdk` keeps every version it has ever published, so
28
+ existing installs and lockfiles go on resolving. It will receive no new
29
+ ones. The move follows the repository into the managoat organization
30
+ (`decisions/0048`), which is also where the scope that publishes this
31
+ package now lives.
32
+
33
+ ## [1.24.0] — 2026-09-10
34
+
35
+ ### Added
36
+
37
+ - Generated types cover the `Teammate`, `Schedule` and `Webhook` documents bulk apply now reconciles, the `unchanged` result action, and a webhook row's one-time `secret`.
38
+
39
+ ## [1.23.0] - 2026-09-07
40
+
41
+ ### Added
42
+
43
+ - Environment creation, update and response types expose `setup_timeout_seconds`
44
+ (1–900, default 120) for bounded cold setup.
45
+
46
+ ## [1.22.0] — 2026-09-07
47
+
48
+ ### Changed
49
+
50
+ - Turn usage exposes adapter accounting source, version, scope and completeness.
51
+ Metadata-only reports omit unmeasured input/output counters, so those fields
52
+ are now optional. Check for missing counts before arithmetic; missing means
53
+ unknown, not zero. Historical reports gain no invented accounting metadata.
54
+
55
+ ## [1.21.1] — 2026-09-06
56
+
57
+ ### Fixed
58
+
59
+ - Generated turn types expose model selection evidence: requested and effective models, selection status, evidence source, and failure details.
60
+
61
+ ## [1.21.0] — 2026-09-06
62
+
63
+ ### Added
64
+
65
+ - `vaults.secrets.update(vault, key, {expires_at})` changes advisory expiry without replacing the value. Null clears expiry; omission preserves it.
66
+ - `conversations({sandboxId})` filters by machine, alongside the existing root filter.
67
+
68
+ ### Fixed
69
+
70
+ - Generated types describe field-validation and coded 422 refusals with a dedicated schema.
71
+
72
+ ## [1.20.2] — 2026-09-06
73
+
74
+ ### Fixed
75
+
76
+ - Generated operation types include shared authentication, rate-limit and content-negotiation errors, plus documented controller refusals. Runtime request behavior is unchanged.
77
+
78
+ ## [1.20.1] — 2026-09-05
79
+
80
+ ### Added
81
+
82
+ - `me()` exposes `connections_enabled` separately from the account’s `brokered` status.
83
+
84
+ ## [1.20.0] — 2026-09-03
85
+
86
+ ### Changed
87
+
88
+ - `error.fieldErrors` now populates on a request the server rejected against
89
+ its OpenAPI schema, not only on one a changeset rejected. Those two
90
+ failures used to come back in different shapes — the schema validator sent
91
+ an array keyed by JSON pointer, which this client read as `{}` — so a
92
+ caller was told the request was invalid and not which field, on exactly the
93
+ failures where the field is the only useful information. The server now
94
+ sends one shape for every 422 (#1431). No API change here; the client got
95
+ better because the wire did.
96
+ - `ChangesetError` gains an optional `error`, the code every Fountain error
97
+ carries. On a validation body it is always `validation_failed`.
98
+
99
+ ---
100
+
101
+ ## [1.19.0] — 2026-09-03
102
+
103
+ ### Changed
104
+
105
+ - `LogEvent.stage` is typed `string | null` rather than `string`. The server
106
+ used to answer `""` for an event with no stage and no state, while its own
107
+ schema declared `state` as one of `started done failed interrupted` or
108
+ `null` — so `""` was a value the published contract did not allow, on the
109
+ busiest read in the API. The server now renders `null` for both fields
110
+ (#1430), which is what the schema always said for `state`; `stage` is typed
111
+ nullable here to match. `LogEvent.state`'s type is unchanged, because the
112
+ document already described it correctly and only the server was wrong.
113
+
114
+ Code that reads `event.stage` on an event that has no stage now sees `null`
115
+ where it saw `""`. This client's own readers were already null-safe. A
116
+ falsy check (`if (event.stage)`) behaves the same either way; `event.stage
117
+ .length` does not.
118
+
119
+ ---
120
+
121
+ ## [1.18.0] — 2026-09-03
122
+
123
+ ### Added
124
+
125
+ - `GET /api/catalog` now carries `first_request`: the one onboarding request
126
+ this deployment hands out (ADR 0038), as `curl` and as the TypeScript
127
+ equivalent, with the prompt and the placeholders a client must still
128
+ substitute. It is the same text the verified landing and the manual print,
129
+ so a client that shows a first request no longer keeps its own copy to
130
+ drift from. `fountain auth register` reads it from here (#1391).
131
+
132
+ ## [1.17.0] — 2026-09-02
133
+
134
+ ### Removed
135
+
136
+ - `onboarding_state` is gone from `AuthMe`, and `state` is gone from the
137
+ onboarding response. Both were the browser wizard's position. The wizard
138
+ went in #867, after which the field only ever said `step_1` or `completed`
139
+ — which is what `onboarding_completed` and `completed_at` already say. The
140
+ server dropped the column in #1393 (ADR 0038 makes `onboarding_completed_at`
141
+ the one source of truth), so these types now match what the API sends.
142
+
143
+ Nothing in the hand-written layer read either field, so this is a generated
144
+ types change only. Code that read `me.onboarding_state` should read
145
+ `me.onboarding_completed`; there is no replacement for a part-way step,
146
+ because the server no longer records one.
147
+
148
+ - `GET /api/account/onboarding` and `POST /api/account/onboarding/complete`
149
+ are unchanged and still work. Only the vestigial field went.
150
+
151
+ ## [1.16.0] — 2026-09-02
152
+
153
+ ### Changed
154
+
155
+ - `AuthMe` now types `id`, `email`, `role` and `email_verified` as always
156
+ present. They always were: the server's `AuthMeResponse` schema listed
157
+ `name`, `prefix` and `created_at` as required, three properties copied from
158
+ the API-key schema that this response does not have, and
159
+ `openapi-typescript` drops a required name with no property. The result was
160
+ a response type with every field optional. The server schema now names the
161
+ four fields `GET /api/auth/me` always renders, so the generated type does
162
+ too (#1411).
163
+
164
+ ### Added
165
+
166
+ - `npm run verify-contract`, which checks this client's declared wire
167
+ dependencies against `sdk/contract/contract.json`, the projection of the
168
+ server's OpenAPI document that all four SDKs now check against. `npm run
169
+ generate` defaults to the same artifact, `dist/openapi.json`, instead of a
170
+ path under `/tmp`.
171
+
172
+ ---
173
+
174
+ ## [1.15.0] — 2026-09-02
175
+
176
+ ### Added
177
+
178
+ - A sandbox's disk, read-only (ADR 0039), beside `sandboxes()`,
179
+ `sandbox(id)` and `resetSandbox(id)`: `sandboxFiles(id, path?)` lists a
180
+ directory, `sandboxFile(id, path, { maxBytes })` returns one file
181
+ (`content` is text or base64 per `encoding`, with `size` and
182
+ `truncated`), and `sandboxDiff(id, { path, staged, ref, maxBytes })`
183
+ returns `git diff`. The reads need a `full`-scope key, answer only for a
184
+ `ready` sandbox (`sandbox_not_ready` otherwise — a parked one is not
185
+ woken), are confined to `/home/sprite` and the runtime's workspace, and
186
+ come back redacted like the transcript. There is no exec, by decision.
187
+ Types `SandboxRecord`, `SandboxListing`, `SandboxEntry`, `SandboxFile`
188
+ and `SandboxDiff` are exported.
189
+
190
+ ## [1.14.0] — 2026-09-01
191
+
192
+ ### Added
193
+
194
+ - `client.catalog()` now returns `mcp_servers` (#1322): remote MCP servers
195
+ verified to complete the MCP authorization discovery chain, each with
196
+ `slug`, `name`, `url`, `dcr` (whether the server registers a client for
197
+ Fountain, RFC 7591) and `verified_on`, the date the chain last completed.
198
+ Suggestions, not an allowlist — any URL can still be discovered through
199
+ `client.connections.providers.create({ kind: "mcp", mcp_url })`. The
200
+ field is absent on servers older than this release.
201
+
202
+ ## [1.13.0] — 2026-09-01
203
+
204
+ ### Added
205
+
206
+ - `client.connections.providers`: where connections get their tokens (#1186).
207
+ `list()` (Google first, then the tenant's own), `get(id)`, `create(input)`,
208
+ `update(id, patch)`, `delete(id)` and `discover(id)`. `kind: "oauth2"` is
209
+ the tenant's own app registration at a service; `kind: "mcp"` takes only
210
+ `mcp_url`, and Fountain discovers the authorization server (RFC 9728 /
211
+ 8414) and registers a client there (RFC 7591) where it can. Each provider
212
+ carries the `redirect_uri` to register at the service, the `env_key` its
213
+ tokens are brokered under and the `token_hosts` the broker attaches them
214
+ to. `ConnectionProvider`, `ConnectionProviderInput` and
215
+ `ConnectionProviderPatch` types.
216
+ - `Connection.provider_id` (null for Google) and the `expired` status, for a
217
+ provider that issues no refresh token.
218
+ - An agent attaches a remote MCP server with a connection:
219
+ `{ linear: { type: "http", url: "https://mcp.linear.app/mcp", connection: "<id>" } }`.
220
+
221
+ ### Changed
222
+
223
+ - **Breaking:** `client.connections.providers()` (a method) is now
224
+ `client.connections.providers.list()`, and each entry is a full
225
+ `ConnectionProvider` (`id`, `slug`, `platform`, `configured`, …) rather
226
+ than the old `{provider, configured, scopes, env_key, connect_url}` row.
227
+
228
+ ## [1.12.0] — 2026-08-31
229
+
230
+ ### Added
231
+
232
+ - Generated types for device-authorization login (fountain #1305):
233
+ `POST /api/auth/device` starts a grant (`DeviceAuthResponse` — the
234
+ `user_code` a human types at the console's `/device` page, the
235
+ `device_code` the machine polls with) and `POST /api/auth/device/token`
236
+ polls it (`DeviceTokenRequest`), answering the RFC 8628 error vocabulary
237
+ until approval mints the same `AuthTokenResponse` as
238
+ `POST /api/auth/token`. This is the login path for accounts created with
239
+ "Sign up with GitHub", which have no password to exchange.
240
+
241
+ ## [1.11.1] — 2026-08-28
242
+
243
+ ### Changed
244
+
245
+ - `DEFAULT_APP_URL` is now
246
+ `https://fountain-conversations.demo.managoat.com/`. The conversations app
247
+ moved there when the demo suite left `jakegaylor.com` for
248
+ `*.demo.managoat.com`, and the old address stopped answering, so every deep
249
+ link `conversationUrl()` built against the default pointed nowhere. Callers
250
+ that pass `appUrl` or set `FOUNTAIN_APP_URL` are unaffected.
251
+
252
+ ## [1.11.0] — 2026-08-25
253
+
254
+ ### Added
255
+
256
+ - Generated types for the tool bridge on the OpenAI-compatible endpoint
257
+ (fountain #1202): `tools` and `tool_choice` on the chat-completions
258
+ request, `tool_calls` on the reply and `finish_reason: "tool_calls"`. The
259
+ SDK still does not wrap `/v1`; the types follow the spec.
260
+
261
+ ## [1.10.0] — 2026-08-25
262
+
263
+ ### Added
264
+
265
+ - Generated types for the server's OpenAI-compatible endpoints (fountain
266
+ ADR 0035, #1198): `POST /v1/chat/completions`, `GET /v1/models` and
267
+ `GET /v1/models/{model}`, where the `model` is a Fountain agent. The SDK
268
+ does not wrap them. It is for the real API, and any `openai` client
269
+ already speaks these, but their request and response shapes now ship in
270
+ `paths` for callers that want them typed.
271
+
272
+ ---
273
+
274
+ ## [1.9.0] — 2026-08-25
275
+
276
+ ### Added
277
+
278
+ - Agent config versions, generated from the server's OpenAPI spec (fountain
279
+ ADR 0029, #1051). `GET /api/agents/{id}/versions` lists an agent's config
280
+ history newest first and `GET /api/agents/{id}/versions/{version}` returns
281
+ one version with its full `config`; both are read-only. `Conversation`
282
+ gains `agent_version_id` and `agent_version`, the version the conversation
283
+ launched under (null for conversations that predate versioning; the number
284
+ is resolved on the conversation list and get endpoints). Types only: the
285
+ hand-written client does not yet wrap the new endpoints.
286
+
287
+ ## [1.8.0] — 2026-08-25
288
+
289
+ ### Changed
290
+
291
+ - `DEFAULT_BASE_URL` is `https://managoat.com`, the hosted Fountain's new
292
+ domain (fountain#1177). The old host redirects, so an SDK pinned before
293
+ this release keeps working; set `baseUrl` explicitly for a self-hosted
294
+ instance either way.
295
+
296
+ ## [1.7.0] — 2026-08-25
297
+
298
+ ### Added
299
+
300
+ - `client.connections`: the provider accounts the tenant signed in to once,
301
+ whose credentials Fountain holds (#1178). `list()`, `get(id)`,
302
+ `providers()` (what the deployment can connect and the console URL that
303
+ starts the flow) and `delete(id)`. Connecting is a browser round trip, so
304
+ there is no `create`. An agent uses one by naming it in `mcp_servers`:
305
+ `{ gmail: { connection: "<id>" } }`. `Connection` and `ConnectionProvider`
306
+ types. Only for accounts the egress broker is on for.
307
+
308
+ ## [1.6.0] — 2026-08-25
309
+
310
+ ### Added
311
+
312
+ - `brokered` on `GET /api/auth/me`: whether the account runs behind the egress
313
+ credential broker, so a client can label the mode without probing
314
+ `/api/secret-bindings` (#1154).
315
+ - `BrokerUnavailableError`: the 502 from `/egress` carries a sentence in
316
+ `message` and a stable `reason` word (`econnrefused`, `api_error_503`, ...)
317
+ instead of an inspected server term (#1153).
318
+
319
+ ### Changed
320
+
321
+ - `GET /api/conversations/:id/egress` needs a full-scope key; a sprite-scoped
322
+ token gets `403 insufficient_scope` (#1152). The `networking_config`
323
+ description says where `limited` is enforced.
324
+
325
+ ## [1.5.0] — 2026-08-25
326
+
327
+ ### Added
328
+
329
+ - Generated types for `GET /api/conversations/:id/egress`: what a brokered
330
+ conversation sent out through the egress broker (ADR 0019 gate 4).
331
+
332
+ ## [1.4.0] — 2026-08-25
333
+
334
+ ### Changed
335
+
336
+ - `SecretBinding.auth_type` gains `substitute`, now the default shape: the
337
+ broker replaces the secret's placeholder wherever it appears in a request to
338
+ the bound host.
339
+
340
+ ## [1.3.0] — 2026-08-25
341
+
342
+ ### Added
343
+
344
+ - Generated types for `/api/secret-bindings` (list, create, update, delete,
345
+ presets): which hosts a secret is attached to at the egress broker, and how
346
+ (ADR 0019 gate 1b). Only answers on an account the broker is on for; 404
347
+ `brokerage_not_enabled` otherwise. No client wrapper yet — use the raw
348
+ types with `client.request`.
349
+
350
+ ## [1.2.0] — 2026-08-25
351
+
352
+ ### Added
353
+
354
+ - `GET /api/account/billing` `usage.credit_burned_cents`: what the ledger
355
+ took this month (turns, rent, messages) — the charged number, where
356
+ `usage.turn_hours` is the metered one. Null with billing off.
357
+
358
+ ### Changed
359
+
360
+ - `usage.conversations` counts conversations that ran a turn in the month,
361
+ deleted or not, rather than sandbox provisions; a conversation on a
362
+ persistent home is now counted.
363
+
364
+ ## [1.1.1] — 2026-08-25
365
+
366
+ ### Changed
367
+
368
+ - `GET /api/account/billing` `period.end` is now the first instant of the
369
+ next month (a half-open window) rather than `23:59:59` of the last day.
370
+ Render the window as `end` minus a second.
371
+
372
+ ## [1.1.0] — 2026-08-25
373
+
374
+ ### Removed
375
+
376
+ - `GET /api/account/billing` no longer carries `period.source`: the window
377
+ is always the calendar month (ADR 0031), so the field had one value.
378
+
379
+ ## [1.0.1] — 2026-08-25
380
+
381
+ ### Changed
382
+
383
+ - `FountainErrorCode` names `insufficient_credits` and `fleet_full`, which
384
+ `errorForStatus` already mapped; the 402 message says the account is out
385
+ of credit rather than lacking a subscription.
386
+ - `GET /api/admin/users` takes `comped` (boolean) in place of the retired
387
+ `status` filter, and `sort` no longer offers `trial_end`; the billing
388
+ endpoint's summary reads "Credit balance and current-month usage".
389
+
390
+ ## [1.0.0] — 2026-08-25
391
+
392
+ ### Changed
393
+
394
+ - Credits are the product (ADR 0031). `GET /api/account/billing` returns
395
+ `comped`, `has_stripe_customer`, `sandbox_cap`, `period`, `credits` and
396
+ `usage`; the subscription fields (`status`, `plan`, `trial_ends_at`,
397
+ `current_period_*`, `cancel_at_period_end`) are gone.
398
+ - A `402` now carries `insufficient_credits` (mapped to
399
+ `SubscriptionRequiredError`, kept under that name); a full fleet is
400
+ `503 fleet_full` (mapped to `NotReadyError`).
401
+ - Admin user objects carry `comped` instead of `subscription_status`,
402
+ `plan`, `trial_ends_at` and the period fields; `/api/auth/me` carries
403
+ `comped`.
404
+
405
+ ### Removed
406
+
407
+ - `POST /api/account/billing/portal`, `POST /api/account/billing/checkout`,
408
+ `POST /api/admin/users/{id}/extend-trial`,
409
+ `POST /api/admin/users/{id}/resync-stripe`. Buying credit is
410
+ `POST /api/account/billing/credits/checkout`.
411
+
412
+ ## [0.4.0] — 2026-08-25
413
+
414
+ ### Removed
415
+
416
+ - `comped_contacts` on admin user objects. The Stripe teammate-contact
417
+ add-on is retired; contacts are rented from the prepaid balance, and an
418
+ operator who wants to give someone free numbers grants credit
419
+ (`POST /api/admin/users/{id}/credits`) or comps the account.
420
+
421
+ ## [0.3.0] — 2026-08-25
422
+
423
+ ### Changed
424
+
425
+ - `plan.included_turn_hours` on `GET /api/account/billing` is now
426
+ `plan.included_credit_cents`: what the plan puts into the prepaid balance
427
+ each billing period, in cents. A plan is denominated in credit, not hours,
428
+ so a change to the turn-hour price never changes what a plan includes.
429
+
430
+ ## [0.2.0] — 2026-08-24
431
+
432
+ ### Removed
433
+
434
+ - `usage.turn_hours_included` and `usage.turn_hours_remaining` on
435
+ `GET /api/account/billing`. The allowance is gone: the plan's hours size
436
+ the monthly credit grant (`plan.included_turn_hours`), and `credits` is
437
+ what acts. `usage.turn_hours` stays.
438
+
439
+ ## [0.1.15] — 2026-08-24
440
+
441
+ ### Added
442
+
443
+ - `POST /api/admin/users/{id}/credits` adds prepaid credit to an account
444
+ (`grant_admin`, never expires). Admin user objects carry
445
+ `credit_balance_cents`.
446
+ - A `402 insufficient_credits` response (same shape as
447
+ `subscription_required`, with `upgrade_url`) on every door that spends,
448
+ once the operator turns enforcement on.
449
+
450
+ ## [0.1.14] — 2026-08-24
451
+
452
+ ### Added
453
+
454
+ - `POST /api/account/billing/credits/checkout` mints a one-time Stripe
455
+ Checkout URL for a credit pack; `credits.packs_cents` on
456
+ `GET /api/account/billing` lists the packs. Refused with
457
+ `subscription_required` for a trialing account and `unknown_pack` for an
458
+ amount that is not on sale.
459
+
460
+ ## [0.1.13] — 2026-08-24
461
+
462
+ ### Added
463
+
464
+ - `GET /api/account/billing` carries `credits`: the prepaid balance in
465
+ cents, what expires and when, the purchased part, and the turn-hour
466
+ price. It is `null` while the deployment has not started burning
467
+ credits, so do not render a zero balance then. Nothing is refused at
468
+ zero yet (ADR 0030).
469
+
470
+ ## [0.1.12] — 2026-08-24
471
+
472
+ ### Changed
473
+
474
+ - `PATCH /api/agents/{id}`, `DELETE /api/environments/{id}` and
475
+ `DELETE /api/vaults/{id}` now carry a `409` response in the generated
476
+ types. Each of those requests can move a persistent home's identity key,
477
+ so the server retires the machine and refuses the request while a
478
+ conversation on it runs a turn (#1084). `FountainError` already maps 409
479
+ to `conflict`; the error body's `error` is `sandbox_mid_turn`.
480
+
481
+ ---
482
+
483
+ ## [0.1.11] — 2026-08-24
484
+
485
+ ### Added
486
+
487
+ - `Sandbox.checkpoint` — `{ id, at }` or `null`: the checkpoint Fountain
488
+ took of a persistent home the last time it parked, generated from the
489
+ server's spec. It is scoped to that machine (ADR 0023, #1073).
490
+
491
+ ## [0.1.10] — 2026-08-24
492
+
493
+ ### Added
494
+
495
+ - `Turn.origin` — `"user"` for a prompt somebody sent, `"autonomous"` for a
496
+ turn the server opened for a background cycle the agent ran after its
497
+ prompt was answered (part 2 of BinaryBourbon/fountain#817). Generated from
498
+ the server's spec; optional in the type because rows from before the field
499
+ read as `user`.
500
+
501
+ ## [0.1.9] — 2026-08-24
502
+
503
+ ### Changed
504
+
505
+ - Generated types follow the server's Buzz identity schema: `sandbox_mode`
506
+ on `POST /api/buzz/agents` and in the identity JSON (server #1070). No
507
+ client method changed.
508
+
509
+ ## [0.1.8] — 2026-08-24
510
+
511
+ ### Added
512
+
513
+ - `resetSandbox(id)` — `DELETE /api/sandboxes/:id`: destroy a persistent
514
+ sandbox (the agent's home) so the next launch on the same agent,
515
+ environment and vault builds a clean machine; the conversations on it are
516
+ kept. `sandbox_not_resettable` for an ephemeral or already-gone sandbox,
517
+ `sandbox_mid_turn` while a conversation on it runs a turn (#1071).
518
+
519
+ ## [0.1.7] — 2026-08-24
520
+
521
+ ### Added
522
+
523
+ - `run({ sandboxMode })` — `"ephemeral"` or `"persistent"`, replacing the
524
+ agent's default for that conversation. A persistent conversation lands on
525
+ the agent's own machine, which Fountain makes on the first such launch;
526
+ while that first launch is still building it, a second one gets
527
+ `provisioning` (retryable). Agents carry `sandbox_mode` and sandboxes carry
528
+ `mode`, both generated from the server's spec (ADR 0023).
529
+
530
+ ## [0.1.6] — 2026-08-24
531
+
532
+ ### Added
533
+
534
+ - `run({ sandbox })` attaches the new conversation to a sandbox you already
535
+ have, by id, instead of provisioning one — several conversations then run
536
+ on one disk at once (ADR 0023). `fountain.sandboxes()` and
537
+ `fountain.sandbox(id)` list your machines with the conversations on each
538
+ and which is mid-turn; `SandboxRecord` is their type. `Sandbox` records
539
+ now carry `agent_id`, `environment_id` and `vault_id`.
540
+ - Error codes: `sandbox_not_found`, `sandbox_not_attachable`,
541
+ `sandbox_identity_mismatch`, `sandbox_runtime_mismatch`, and
542
+ `sandbox_at_capacity` (retryable — a one-at-a-time runtime's machine is
543
+ busy with another conversation's turn).
544
+
545
+ ## [0.1.5] — 2026-08-24
546
+
547
+ ### Fixed
548
+
549
+ - No `User-Agent` header when running in a browser. Firefox lets a page set
550
+ one, which turned every call into a CORS preflight asking for `user-agent`,
551
+ and a Fountain whose allow-list did not name it refused the request ("CORS
552
+ Missing Allow Header") — the first thing a signed-in single-page app saw.
553
+ Node and other non-browser runtimes still send `fountain-sdk-js/<version>`.
554
+
555
+ ## [0.1.4] — 2026-08-24
556
+
557
+ ### Added
558
+
559
+ - `expires_at` on vault secrets, generated from the server's OpenAPI spec.
560
+ `VaultSecretRequest` accepts it (ISO 8601 date-time, or `null` to clear a
561
+ stored expiry) and `VaultSecret` returns it; a request that omits the field
562
+ leaves the stored expiry alone. It is advisory metadata: the server emails
563
+ the owner ahead of the date and enforces nothing on it, so an expired secret
564
+ is still injected as-is. Values stay write-only.
565
+
566
+ ## [0.1.3] — 2026-08-23
567
+
568
+ ### Added
569
+
570
+ - Turn-hour types, generated from the server's OpenAPI spec (fountain ADR 0026,
571
+ amended). `GET /api/account/billing` now reports what a plan includes and
572
+ what the account has spent against it.
573
+
574
+ - `plan.included_turn_hours` — turn hours the tier carries per billing
575
+ period.
576
+ - `usage.turn_hours`, `usage.turn_hours_included`,
577
+ `usage.turn_hours_remaining`.
578
+ - `current_period_start` beside the existing `current_period_end`.
579
+ - `period.source` — `"subscription"` or `"calendar_month"`.
580
+
581
+ A **turn hour is not a sandbox hour.** It counts time with a prompt in
582
+ flight, so an agent left running with nobody talking to it spends
583
+ `usage.sandbox_minutes` and none of the allowance. Do not present the two as
584
+ the same unit.
585
+
586
+ Read `period.source` before showing an allowance. `"calendar_month"` means
587
+ the server has no invoiced period for that account (comped, self-hosted, or
588
+ no subscription webhook yet), so the numbers do not line up with an invoice
589
+ and a UI that implies they do will be wrong for exactly those accounts.
590
+
591
+ Nothing is enforced against these numbers today — no request fails for
592
+ exceeding the included hours.
593
+
594
+ All fields are optional and additive; nothing existing changed shape.
595
+
596
+ ## [0.1.2] — 2026-08-23
597
+
598
+ ### Added
599
+
600
+ - Subscription plan types, generated from the server's OpenAPI spec
601
+ (fountain ADR 0026). `GET /api/account/billing` now returns a `plan` object —
602
+ `slug`, `name`, `monthly_cents`, `concurrent_sandboxes`, `sandbox_limit` and
603
+ `team_contacts` — and the checkout endpoint accepts a `plan` query parameter
604
+ naming the tier to buy.
605
+
606
+ Read `plan.sandbox_limit`, not `plan.concurrent_sandboxes`, when showing a
607
+ customer how many agents they may run at once. The first is what the server
608
+ actually enforces for that account; the second is the tier's number, and an
609
+ operator override can make them differ.
610
+
611
+ - Admin account types carry `plan`, `sandbox_limit_override` and
612
+ `comped_contacts`. `max_concurrent_sandboxes` keeps its name and its meaning
613
+ — the cap in force — so nothing reading it breaks.
614
+
615
+ ## [0.1.1] — 2026-08-23
616
+
617
+ No code change from 0.1.0. This is the first release published by CI through
618
+ npm's trusted publishing, so unlike 0.1.0 — which went out from a laptop — the
619
+ tarball carries a provenance attestation tying it to the workflow, the
620
+ repository and the commit that built it. Verify with `npm audit signatures`.
621
+
622
+ ## [0.1.0] — 2026-08-23
623
+
624
+ First published release.
625
+
626
+ ### Added
627
+
628
+ - `fountain.run(prompt, { agent, vault, environment })` — one call that
629
+ provisions a sandbox, runs the agent in it and folds the log feed into an
630
+ answer. `await` it, `for await` it, or read `.textStream`; all three are
631
+ views of one run.
632
+ - `fountain.resume(id)` — the sandbox and the agent's session are still there,
633
+ so a follow-up costs one prompt rather than a re-explanation.
634
+ - `agents`, `environments`, `vaults` — list, read, create, update, delete, and
635
+ write-only secrets. All of them take a **name** where an id would do.
636
+ - `team` — teammates, their standing threads, and their routines.
637
+ - Streams that reconnect from a cursor, so a deploy mid-turn neither drops the
638
+ answer nor replays it.
639
+ - Errors keyed on the API's `error` code rather than the status, because
640
+ `conversation_busy` is a 400, `sandbox_quota_exceeded` a 429 and
641
+ `provisioning` a 503, and what a caller does about each is unrelated to the
642
+ number. Every error carries `retryable`.
643
+ - `run.answer(requestId, optionId)` and `resume(id).answer(...)`, with a
644
+ `{ type: "permission" }` run event, for agents whose `permission_policy` has
645
+ an `ask` entry.
646
+ - Types generated from the server's own OpenAPI document, with CI failing on
647
+ any drift between the two.
648
+ - A browser entry with no Node built-in reachable from it, and a Node entry
649
+ that adds `~/.fountain/credentials`.
650
+
651
+ [1.16.0]: https://www.npmjs.com/package/@agentshit/fountain-sdk/v/1.16.0
652
+ [0.1.1]: https://www.npmjs.com/package/@agentshit/fountain-sdk/v/0.1.1
653
+ [0.1.0]: https://www.npmjs.com/package/@agentshit/fountain-sdk/v/0.1.0