oblien 2.4.0 → 2.6.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 (105) hide show
  1. package/dist/access.d.ts +79 -0
  2. package/dist/access.d.ts.map +1 -0
  3. package/dist/access.js +42 -0
  4. package/dist/access.js.map +1 -0
  5. package/dist/billing.d.ts +6 -0
  6. package/dist/billing.d.ts.map +1 -1
  7. package/dist/billing.js +6 -0
  8. package/dist/billing.js.map +1 -1
  9. package/dist/cli/commands/scp.js +9 -2
  10. package/dist/cli/commands/scp.js.map +1 -1
  11. package/dist/cli/commands/ssh.d.ts.map +1 -1
  12. package/dist/cli/commands/ssh.js +12 -0
  13. package/dist/cli/commands/ssh.js.map +1 -1
  14. package/dist/cli/commands/workloads.d.ts.map +1 -1
  15. package/dist/cli/commands/workloads.js +26 -2
  16. package/dist/cli/commands/workloads.js.map +1 -1
  17. package/dist/cli/commands/workspaces.d.ts.map +1 -1
  18. package/dist/cli/commands/workspaces.js +8 -0
  19. package/dist/cli/commands/workspaces.js.map +1 -1
  20. package/dist/client.d.ts +8 -0
  21. package/dist/client.d.ts.map +1 -1
  22. package/dist/client.js +12 -0
  23. package/dist/client.js.map +1 -1
  24. package/dist/disks.d.ts +49 -0
  25. package/dist/disks.d.ts.map +1 -0
  26. package/dist/disks.js +143 -0
  27. package/dist/disks.js.map +1 -0
  28. package/dist/http.d.ts +2 -0
  29. package/dist/http.d.ts.map +1 -1
  30. package/dist/http.js +14 -0
  31. package/dist/http.js.map +1 -1
  32. package/dist/index.d.ts +5 -1
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +2 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/namespace.d.ts +8 -5
  37. package/dist/namespace.d.ts.map +1 -1
  38. package/dist/namespace.js +4 -3
  39. package/dist/namespace.js.map +1 -1
  40. package/dist/resources/desktop.d.ts +19 -3
  41. package/dist/resources/desktop.d.ts.map +1 -1
  42. package/dist/resources/desktop.js +19 -6
  43. package/dist/resources/desktop.js.map +1 -1
  44. package/dist/resources/images.d.ts +26 -0
  45. package/dist/resources/images.d.ts.map +1 -1
  46. package/dist/resources/images.js.map +1 -1
  47. package/dist/resources/logs.d.ts +5 -1
  48. package/dist/resources/logs.d.ts.map +1 -1
  49. package/dist/resources/logs.js +4 -1
  50. package/dist/resources/logs.js.map +1 -1
  51. package/dist/resources/ssh.d.ts +3 -0
  52. package/dist/resources/ssh.d.ts.map +1 -1
  53. package/dist/resources/ssh.js +4 -0
  54. package/dist/resources/ssh.js.map +1 -1
  55. package/dist/resources/workloads.d.ts +12 -3
  56. package/dist/resources/workloads.d.ts.map +1 -1
  57. package/dist/resources/workloads.js +20 -4
  58. package/dist/resources/workloads.js.map +1 -1
  59. package/dist/runtime/terminal.d.ts +10 -0
  60. package/dist/runtime/terminal.d.ts.map +1 -1
  61. package/dist/runtime/terminal.js +19 -0
  62. package/dist/runtime/terminal.js.map +1 -1
  63. package/dist/runtime/ws.d.ts.map +1 -1
  64. package/dist/runtime/ws.js +6 -2
  65. package/dist/runtime/ws.js.map +1 -1
  66. package/dist/types/access.d.ts +65 -0
  67. package/dist/types/access.d.ts.map +1 -0
  68. package/dist/types/access.js +2 -0
  69. package/dist/types/access.js.map +1 -0
  70. package/dist/types/billing.d.ts +61 -2
  71. package/dist/types/billing.d.ts.map +1 -1
  72. package/dist/types/billing.js +0 -8
  73. package/dist/types/billing.js.map +1 -1
  74. package/dist/types/client.d.ts +4 -0
  75. package/dist/types/client.d.ts.map +1 -1
  76. package/dist/types/disks.d.ts +153 -0
  77. package/dist/types/disks.d.ts.map +1 -0
  78. package/dist/types/disks.js +2 -0
  79. package/dist/types/disks.js.map +1 -0
  80. package/dist/types/index.d.ts +5 -3
  81. package/dist/types/index.d.ts.map +1 -1
  82. package/dist/types/namespace.d.ts +43 -3
  83. package/dist/types/namespace.d.ts.map +1 -1
  84. package/dist/types/runtime.d.ts +3 -1
  85. package/dist/types/runtime.d.ts.map +1 -1
  86. package/dist/types/workspace-resources.d.ts +25 -0
  87. package/dist/types/workspace-resources.d.ts.map +1 -1
  88. package/dist/types/workspace.d.ts +34 -0
  89. package/dist/types/workspace.d.ts.map +1 -1
  90. package/dist/workspace-handle.d.ts +2 -0
  91. package/dist/workspace-handle.d.ts.map +1 -1
  92. package/dist/workspace-handle.js +2 -0
  93. package/dist/workspace-handle.js.map +1 -1
  94. package/dist/workspace.d.ts +2 -0
  95. package/dist/workspace.d.ts.map +1 -1
  96. package/dist/workspace.js +23 -7
  97. package/dist/workspace.js.map +1 -1
  98. package/docs/billing.md +133 -6
  99. package/docs/desktop.md +32 -0
  100. package/docs/namespaces.md +70 -1
  101. package/docs/releases/2.6.0.md +16 -0
  102. package/docs/runtime.md +2 -0
  103. package/docs/webhooks.md +42 -0
  104. package/docs/workspaces.md +1 -1
  105. package/package.json +1 -1
@@ -6,6 +6,13 @@ Group workspaces into isolated namespaces with **resource limits**, **spending q
6
6
  const ns = client.namespaces;
7
7
  ```
8
8
 
9
+ Account namespace counts are enforced atomically by both `create` and `ensure`:
10
+ the owner row is locked and the count and namespace insert share a transaction.
11
+ At the account limit a new namespace returns `409 namespace_limit_exceeded`;
12
+ ensuring an existing namespace remains idempotent. The owner's paid or
13
+ admin-granted Enterprise tier has no namespace-count cap. A customer namespace
14
+ subscription cannot raise it.
15
+
9
16
  ## Create + resource limits
10
17
 
11
18
  ```typescript
@@ -20,7 +27,19 @@ const { data } = await ns.create({
20
27
  });
21
28
  ```
22
29
 
23
- Resource limits are enforced **atomically at workspace create and resource upgrade** — over-limit returns `409 NAMESPACE_LIMIT_REACHED`. `max_workspaces` is race-proof (the namespace row is locked + the count re-checked inside the insert transaction). Update them with `ns.update(id, { resource_limits })`.
30
+ Workspace count is reserved **atomically at workspace create**; effective resource caps are checked at create, resize and start/resume/restart/wake/snapshot-resume — over-limit returns `409 NAMESPACE_LIMIT_REACHED`. `max_workspaces` is race-proof (the namespace row is locked + the count re-checked inside the insert transaction). Update them with `ns.update(id, { resource_limits })`.
31
+
32
+ Declare policy directly. `null` inherits Oblien capacity; zero denies that
33
+ allocation. VM policy integers may exceed current capacity: Oblien applies the
34
+ strictest declared, committed paid-offer, account and platform cap. Clients do
35
+ not calculate or copy the account's machine ceiling into customer contracts.
36
+ Invalid numbers and unknown keys return `invalid_resource_limits`.
37
+
38
+ `create`, `ensure`, `get` and `update` expose both `data.resource_limits` (saved
39
+ policy) and `data.effective_resource_limits` (current enforced ceilings). The
40
+ latter can change with account capacity while saved customer terms stay intact.
41
+ These limits do not reserve host capacity or funds. Account pool usage and
42
+ credits are checked independently at allocation time.
24
43
 
25
44
  ## Lifecycle
26
45
 
@@ -67,3 +86,53 @@ data.totals.vcpu_hours; // cpu_time_minutes/60, gb_hours, network_gb, disk_io_
67
86
  A namespace-scoped key is pinned to its namespace: list/get/usage/webhooks all auto-filter to it, and it can't widen scope. `user_id` is always the tenant gate.
68
87
 
69
88
  **Full reference:** [Namespaces API](https://oblien.com/docs/api/namespaces)
89
+
90
+
91
+ ## Namespace credit alerts and customer recovery
92
+
93
+ Oblien computes the warning state from the same quota row that enforces spending.
94
+ Read `quota.alert` from `GET /billing/entitlement?namespace=...`, or `alert` from
95
+ `GET /billing/balance?namespace=...`. Namespace quota rows also include `alert`.
96
+ Its `state` is `ok`, `low`, `grace`, `depleted`, `unlimited`, or `disabled`.
97
+ `percent` uses **included allowance + purchased top-ups**, excluding grace.
98
+ `remaining` is paid allowance left; `balance` also includes configured grace.
99
+ All amounts are JSON numbers in Oblien credits. Never add grace to `balance` again.
100
+
101
+ Subscribe to `namespace.quota.threshold`, `credits.low`, and `credits.depleted`:
102
+
103
+ - Warning percentages default to **80% and 95%** and can be configured per service.
104
+ `notificationThresholds: []` disables percentage warnings, not enforcement or
105
+ exhaustion alerts. A large usage window reports the most urgent crossed state.
106
+ - `credits.low` reports entry into configured grace. Zero grace remains the default.
107
+ `credits.depleted` reports exhaustion at `balance <= 0`.
108
+ - The usage debit, threshold marker and outgoing alert commit in **one payments
109
+ transaction**. Delivery retries after failures and API restarts, retaining its
110
+ signed body and event ID. Metering does not wait for your webhook or email server.
111
+ - Each event identifies `data.namespace`, `data.service`, `data.transaction_id`
112
+ and a numeric `data.alert` snapshot. Resolve the customer from your saved namespace
113
+ mapping, verify the signature, and durably save the event and notification job
114
+ before acknowledging. Deduplicate event IDs, then re-read current entitlement;
115
+ an old alert may arrive after a top-up or renewal. Do not use event amounts to
116
+ grant credits or override the current quota.
117
+ - Show a warning banner and a billing action. Use your server-defined top-up offer
118
+ to create a namespace-bound checkout after the customer chooses to buy. Payment
119
+ fulfillment increases purchased allowance once; your next entitlement read
120
+ clears the warning when funded. Workspaces stopped for billing can then be
121
+ restarted. A top-up does not change the plan's resource caps or grace policy.
122
+ - Paid renewals re-arm warnings and preserve custom notification percentages.
123
+ A top-up or usage refund that lowers usage below a warning band re-arms that
124
+ band for the larger remaining budget. Mode A cycles must still be reset by
125
+ your backend; Mode B cycles renew after verified paid invoices.
126
+
127
+ External email delivery is asynchronous and can repeat after a lost acknowledgment.
128
+ Use a durable notification queue, honor verified recipient preferences, recheck
129
+ organization membership before delivery, and bind billing links to the intended
130
+ organization. Keep a read-only dashboard warning while email is unavailable.
131
+
132
+ ## Combined capacity (SDK 2.6.0)
133
+
134
+ Set `max_total_vcpus`, `max_total_ram_mb` and `max_total_disk_gb` alongside per-VM caps. Total caps include stopped workspaces, build hosts, managed disks and pending resizes. `null` inherits, zero denies allocation. An Enterprise owner does not grant each namespace unlimited resources.
135
+
136
+ `namespaces.get()` returns `data.allocated_resource_usage` with `workspaces`, `vcpus`, `ram_mb`, `disk_gb` and `pending_updates`, plus `effective_resource_limits`. These are observations, not capacity reservations. Oblien checks again atomically on create/resize. A resource update may return `pending_capacity_verification: true`; its reservation remains until the provider confirms configuration and live allocation.
137
+
138
+ Use `billing.catalog().reseller.aggregateResourceLimits` to check deployed support. Credit top-ups do not change hardware capacity. Resource-limit patches preserve omitted fields atomically.
@@ -0,0 +1,16 @@
1
+ # SDK 2.6.0
2
+
3
+ This release adds typed total namespace capacity (`max_total_vcpus`,
4
+ `max_total_ram_mb`, `max_total_disk_gb`), `allocated_resource_usage`, and the
5
+ `billing.catalog().reseller.aggregateResourceLimits` capability. Deploy the
6
+ matching API before depending on total capacity enforcement. Credits and
7
+ hardware limits remain independent.
8
+
9
+ Log reads and streams now accept cancellation signals. Stopping iteration
10
+ cancels the underlying stream reader instead of leaving a connection open.
11
+ `workloads.logs(id, workload, { tail, signal })` keeps the signal out of the URL.
12
+ These fixes replace Openship's temporary log-cancellation package patch.
13
+
14
+ The package is prepared locally as 2.6.0 and must be published before consumers
15
+ can install it. Openship's capacity PR uses published 2.5.0 with the compatibility
16
+ patch, so its deployment does not require this release to be published first.
package/docs/runtime.md CHANGED
@@ -10,6 +10,8 @@ const rt = await client.workspace('ws_abc').runtime();
10
10
 
11
11
  This enables the Runtime API server (if needed), fetches a gateway JWT, and returns a `Runtime` instance. The token is cached — subsequent calls for the same workspace return instantly.
12
12
 
13
+ After starting, stopping, restarting or resuming a workspace, call `workspace.runtime()` again. These lifecycle calls invalidate its cached connection; an already-held `Runtime` object is not rewritten. Use `runtime({ force: true })` when the workspace was restarted outside this client.
14
+
13
15
  ## Namespaces
14
16
 
15
17
  | Namespace | What it does |
package/docs/webhooks.md CHANGED
@@ -40,3 +40,45 @@ await wh.delete(webhook.id);
40
40
  `credits.usage` is emitted per billing cycle with `{ namespace, workspace_id, usage: { cpu_time_minutes, memory_gb_minutes, disk_io_gb, network_gb } }` — a push alternative to polling [`namespaces.usageUnits`](./namespaces.md). Idempotent per event.
41
41
 
42
42
  **Full reference:** [Webhooks concept](https://oblien.com/docs/concepts/webhooks)
43
+
44
+
45
+ ## Namespace credit alerts and customer recovery
46
+
47
+ Oblien computes the warning state from the same quota row that enforces spending.
48
+ Read `quota.alert` from `GET /billing/entitlement?namespace=...`, or `alert` from
49
+ `GET /billing/balance?namespace=...`. Namespace quota rows also include `alert`.
50
+ Its `state` is `ok`, `low`, `grace`, `depleted`, `unlimited`, or `disabled`.
51
+ `percent` uses **included allowance + purchased top-ups**, excluding grace.
52
+ `remaining` is paid allowance left; `balance` also includes configured grace.
53
+ All amounts are JSON numbers in Oblien credits. Never add grace to `balance` again.
54
+
55
+ Subscribe to `namespace.quota.threshold`, `credits.low`, and `credits.depleted`:
56
+
57
+ - Warning percentages default to **80% and 95%** and can be configured per service.
58
+ `notificationThresholds: []` disables percentage warnings, not enforcement or
59
+ exhaustion alerts. A large usage window reports the most urgent crossed state.
60
+ - `credits.low` reports entry into configured grace. Zero grace remains the default.
61
+ `credits.depleted` reports exhaustion at `balance <= 0`.
62
+ - The usage debit, threshold marker and outgoing alert commit in **one payments
63
+ transaction**. Delivery retries after failures and API restarts, retaining its
64
+ signed body and event ID. Metering does not wait for your webhook or email server.
65
+ - Each event identifies `data.namespace`, `data.service`, `data.transaction_id`
66
+ and a numeric `data.alert` snapshot. Resolve the customer from your saved namespace
67
+ mapping, verify the signature, and durably save the event and notification job
68
+ before acknowledging. Deduplicate event IDs, then re-read current entitlement;
69
+ an old alert may arrive after a top-up or renewal. Do not use event amounts to
70
+ grant credits or override the current quota.
71
+ - Show a warning banner and a billing action. Use your server-defined top-up offer
72
+ to create a namespace-bound checkout after the customer chooses to buy. Payment
73
+ fulfillment increases purchased allowance once; your next entitlement read
74
+ clears the warning when funded. Workspaces stopped for billing can then be
75
+ restarted. A top-up does not change the plan's resource caps or grace policy.
76
+ - Paid renewals re-arm warnings and preserve custom notification percentages.
77
+ A top-up or usage refund that lowers usage below a warning band re-arms that
78
+ band for the larger remaining budget. Mode A cycles must still be reset by
79
+ your backend; Mode B cycles renew after verified paid invoices.
80
+
81
+ External email delivery is asynchronous and can repeat after a lost acknowledgment.
82
+ Use a durable notification queue, honor verified recipient preferences, recheck
83
+ organization membership before delivery, and bind billing links to the intended
84
+ organization. Keep a read-only dashboard warning while email is unavailable.
@@ -38,7 +38,7 @@ await ws.update(workspace.id, { name: 'my-api' });
38
38
  await ws.delete(workspace.id);
39
39
  ```
40
40
 
41
- Creating in a namespace enforces that namespace's **resource limits** (max workspaces, per-workspace vCPU/RAM/disk) atomically, and **status** (a suspended/over-quota namespace rejects new workspaces). See **[Namespaces](./namespaces.md)**.
41
+ Creating in a namespace enforces that namespace's **resource limits** (max workspaces, per-workspace and total vCPU/RAM/disk) atomically, and **status** (a suspended/over-quota namespace rejects new workspaces). See **[Namespaces](./namespaces.md)**.
42
42
 
43
43
  Workspace count, namespace, and owned resource pool limits return HTTP 409 with
44
44
  `SANDBOX_LIMIT_REACHED`, `NAMESPACE_LIMIT_REACHED`, or `POOL_LIMIT_REACHED`. The SDK
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oblien",
3
- "version": "2.4.0",
3
+ "version": "2.6.0",
4
4
  "description": "Official TypeScript SDK for the Oblien Workspace API",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",