deepspace 0.14.0 → 0.16.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 +40 -0
- package/dist/cli.js +365 -734
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +26 -1
- package/dist/index.js +18 -5
- package/dist/index.js.map +1 -1
- package/dist/server.d.ts +25 -18
- package/dist/server.js +35 -14
- package/dist/server.js.map +1 -1
- package/dist/worker.d.ts +119 -18
- package/dist/worker.js +118 -14
- package/dist/worker.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,45 @@
|
|
|
1
1
|
# deepspace
|
|
2
2
|
|
|
3
|
+
## 0.16.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- **Storage is now a per-ACCOUNT total, and the schedule is much larger.** free 128 MiB → **1 GiB**, starter 512 MiB → **10 GiB**, premium 2 GiB → **30 GiB**, admin 10 GiB → **100 GiB**.
|
|
8
|
+
|
|
9
|
+
The number was per app, which meant an owner at their cap could create another app and keep writing — so the figure on the billing page described nothing enforceable. It is now the total across every app an owner holds: admission sums the owner's apps rather than only the one being written to, and a listing reports that same account total, so the number a caller sees is the number they are held to. Prefixes are swept concurrently, so the cost is the slowest single app rather than the sum, and an owner with one app — the common case — pays exactly what they did before. If the owner's apps cannot be enumerated the write fails closed, for the same reason a failed limit lookup does: an allocation that cannot be measured must not be written against.
|
|
10
|
+
|
|
11
|
+
**The repo store no longer rides the customer schedule.** Git packs, retained rollback bundles, and stored deploy assets are admitted against a flat 256 MiB per app, the same for every tier. They are platform bookkeeping, not something a customer buys, so the tier was never the right input — and tying them together meant every raise to the advertised number silently multiplied platform-side storage per app. It also put a **billing lookup on the path of every push, deploy, and rollback**, one that could degrade and refuse the write outright; that failure mode is gone with it. An app that cannot fit its source plus a few rollback bundles in 256 MiB has something in the wrong place: user uploads belong in the app-files allocation, which is what the account schedule sizes.
|
|
12
|
+
|
|
13
|
+
The dashboard advertised 5 GB while the platform enforced 128 MiB — a 40× overstatement that survived for months because they were two numbers instead of one. The billing page now reads the enforced schedule directly and cannot claim capacity the platform will not honor. `ACCOUNT_STORAGE_LIMIT_BYTES`, `storageLimitForTier`, and `formatBytes` are exported from the browser entry for that reason; `APP_STORAGE_LIMIT_BYTES` is renamed to `ACCOUNT_STORAGE_LIMIT_BYTES`, since what it means changed.
|
|
14
|
+
|
|
15
|
+
**An app still on a legacy name-shaped id can reach its own files again.** `/internal/files/*` shape-checked the caller's `x-app-id` against the public-id pattern — a pre-filter STRICTER than the registry action it feeds, which matches `app_id` OR `resource_id`. Apps registered before canonical ids resolve fine in the registry but never got the chance to ask, so their file storage answered 401 with no way out: they cannot redeploy either. It also caught any app in the window between migrating and its next deploy, whose worker still carries the old id in its `DEEPSPACE_APP_ID` binding. Authority is unchanged — the constant-time HMAC, then a registry lookup that fails closed for anything unregistered.
|
|
16
|
+
|
|
17
|
+
**A long AI stream is no longer cut short mid-completion.** The proxy's streaming pump ran inside `ctx.waitUntil` while the client read the other side of a TransformStream, and the runtime cancels that work on its own budget — independent of the client's read loop. Long completions died mid-stream, and the failure was invisible from the app: a cleanly ended SSE with no terminal event and no error. The body now pipes through an identity transform that accumulates the billing transcript as the client pulls, so delivery and invocation lifetime are the same thing and the stream lives exactly as long as its reader. Settlement moves to `flush()`: a completed stream settles actual usage as before, while a client that disconnects mid-stream leaves the bounded worst-case pre-charge standing rather than collecting a refund for bytes it never read — and upstream teardown stops paying the provider for tokens nobody receives.
|
|
18
|
+
|
|
19
|
+
## 0.15.0
|
|
20
|
+
|
|
21
|
+
### Minor Changes
|
|
22
|
+
|
|
23
|
+
- **`deepspace app migrate` is removed**, replaced by `deepspace app update` (below). It existed for one historical cutover — moving an app from a name-shaped id to a canonical one — and the platform endpoints behind it are unchanged, so an app still on a legacy id migrates with `npx deepspace@0.13.0 app migrate` and then upgrades normally.
|
|
24
|
+
|
|
25
|
+
A file that no longer exists now answers `404`, not the app's HTML. Deploys configured the asset layer with `not_found_handling: "single-page-application"`, so it answered EVERY unmatched path with `index.html` at 200 — correct for a client route, wrong for a file. A deploy replaces the hashed build chunks, so a tab still holding the previous `index.html` requested one and got HTML where JavaScript belonged: the script tag parsed it, failed, and the page went white with no error in any log, monitor, or network panel. The same answer went to agents probing `/llms.txt` and `/.well-known/mcp`, telling them the app publishes a manifest it does not have.
|
|
26
|
+
|
|
27
|
+
The asset layer cannot tell a route from a file. The app's worker can — it knows `/assets/*` is build output — so the decision moves there: `not_found_handling: "none"` makes the binding report a real miss, and the worker serves the shell for a route or 404s a file. This is what the scaffold's route handler was written for all along; the config had made every branch under its `status === 404` check unreachable, which is why the reservation shipped in 0.13.0 never worked.
|
|
28
|
+
|
|
29
|
+
**That setting is now the app's to declare, and the platform honors it.** It was first shipped as a platform-wide override, on the reasoning that every deployed app's catch-all already branched on a 404. The branch did exist — but it asked the asset layer for `/index.html`, which redirects to `/`. Under the old setting that branch never ran, so nothing showed; under a forced one it ran on every client route and handed the browser a 307 off the URL it asked for. An app built from the published template lost every deep link. A deploy that declares nothing keeps exactly the behavior the platform used to force, so an un-upgraded CLI cannot be broken by this release.
|
|
30
|
+
|
|
31
|
+
`deepspace app update` moves an existing app onto it, and replaces `deepspace migrate`. An app's worker is a copy its author owns, so a platform change that needs different app code reaches nobody without a command that carries those copies forward. It pins the SDK, applies the source edits that are deterministic, and for anything it cannot safely touch prints the file, the line, and the change required — output an agent can execute. Edits still land when such a change is outstanding, because withholding them would leave the app on the old behavior for the sake of an edit someone else has to make; what is withheld is the recorded-as-done stamp, so the next run looks again. A version gap too wide to carry in one step points at the upgrade guide rather than half-migrating.
|
|
32
|
+
|
|
33
|
+
Verified on a real deployment, not in a mock, on both sides of the change: an unmigrated `create-deepspace@0.13.0` app deploys and still serves `/settings` at 200 with no redirect, and the same app after `deepspace app update` answers a missing hashed chunk with `404 application/json` (including with a browser's `Sec-Fetch-Dest: script`), 404s `/llms.txt`, still serves `/favicon.ico`, and still serves a deep link at 200 **on the URL that was asked for**. A tab that outlives a deploy also now reloads itself once on Vite's `vite:preloadError` rather than leaving a lazily-loaded route silently dead.
|
|
34
|
+
|
|
35
|
+
An app's `compatibility_date` is honored instead of silently discarded. `wrangler.toml` declared one runtime and the deploy hardcoded another, so local dev and production could run different semantics with nothing reporting the divergence. The declared date is now used, floored at the platform minimum (an app may move forward onto semantics it has tested, never backward onto ones the platform no longer supports) and clamped if it is in the future. The date a release ran on is recorded in its bundle, so a rollback restores that runtime rather than today's. The navigation-routing flag is now stated explicitly in the upload rather than inherited from that date, so the routing contract cannot be silently undone the day the platform pin moves.
|
|
36
|
+
|
|
37
|
+
Make `deploy` and `rollback` mean it when they say a release is live. The wait polled with `fetch`, which keeps one connection alive — so every poll re-interviewed the single edge machine that answered first, agreed with itself instantly, and printed `Deployed!` while a quarter of fresh connections still served the previous release for up to 95 seconds. Each probe now opens its own connection and the wait succeeds only after ten independent ones agree. What cannot be verified is said plainly instead of implied: `--json` carries `serving: "confirmed" | "unconfirmed" | "unverifiable"`, and the human output distinguishes "the edge is still rolling this release out" from "serving could not be verified from here". The old reachability probe is gone — it proved the app answered, never which release did.
|
|
38
|
+
|
|
39
|
+
Also: `collaborators accept` now points at `clone`, the command that works when you have just been granted access and have no checkout (`pull` failed with `not_in_app_repo`); accepting an invite you already accepted reports that you are a member instead of sending you to ask the owner for another billed invite; `collaborators add --json` no longer prints the invite's `/join` token into terminals and CI logs; `collaborators invites` drops the `appName` field that echoed the app id under a name it did not have; a refused upload carries its numbers into `--json` (`usedBytes`, `limitBytes`) rather than leaving them in prose; and `app undeploy` refuses with `not_app_owner` like every other owner-only surface.
|
|
40
|
+
|
|
41
|
+
Internally, the routing decisions these fixes depend on now live in one place (`shared/app-routing.ts`) that the deploy worker, the CLI and the scaffold all read, replacing two hand-maintained copies of the reserved-path list whose divergence nothing would have reported. The scaffold's TOML cannot import a constant, so a test pins it to the same values — that is what keeps `deepspace dev` routing like production. `docs/platform/app-platform-contract.md` states the rules this boundary follows, including why a fix moves the platform to match app code rather than the reverse.
|
|
42
|
+
|
|
3
43
|
## 0.14.0
|
|
4
44
|
|
|
5
45
|
### Minor Changes
|