v0.21.0
·
28 commits
to main
since this release
Minor Changes
- Cron mutation receipts:
useCronMonitor's trigger/pause/resume now resolve a typedCronMutationResultover a newcron.ackframe (a trigger resolves once the run completes; its execution record arrives viahistory), and the hook surfaces previously dropped server ERROR frames aslastError. Pause/resume of an unknown task now rejects withunknown_task(and a missingtaskNamewithfailed) instead of acking success. - The files round trip works and failures are visible.
upload/uploadBase64accept{ key }to place an object at an exact location within the scope (slashes allowed, upsert semantics — the server contract the CLI already used), souploadthenlist(prefix)finds what you stored;namestays display metadata.list()now throws a humanized error on auth/server failures instead of silently returning an empty directory, accepts{ limit, cursor }, and the newlistPage()returns{ files, cursor, truncated }for real pagination past the server cap. Entries and upload results carryrelativeKey(the key within your scope). Also fixes a cross-page listing bug where a cursor continuation could re-list keys earlier pages already returned. The file-manager feature renders list failures with a retry instead of an empty grid. - Integration failures arrive typed and human at the same time.
IntegrationResponse.erroris now the human-readable message (it was the machine slug — which is why rawinsufficient_creditsreached product copy); the slug moves tocode, withstatusand structureddetails(for exampleavailableCredits/requiredCreditson a 402) preserved instead of discarded.useCheckout/useSubscriptionsurface the same typedcode(soowner_connect_not_readyis branchable, not string-matched), andintegrations invokeprints the human line while carrying the real slug in its refusal. Chat completions that spend the entire token budget on reasoning before any visible output now fail typed asoutput_budget_exhaustedwith the budget in the message, instead of returning an empty string. Onoutput_budget_exhaustedthe worst-case pre-charge stands (no reconciliation), the same as any other handler failure. - Testing stops lying to you. Cached Playwright sign-in state is validated against the target app before reuse (session probe plus identity match, keyed by auth scope + app origin + email) instead of trusted for seven days on file age alone — a fresh-but-dead state file can no longer poison every protected test.
test accounts listnow shows the fixture selector name and ausableByFixtureflag (with--usableto filter and passwords masked behind--revealin human output;--jsonstill carries them for automation), and accounts created without--namedefault it from the email so they are always selectable.test runaccepts--grep,--project, and--headed.dev startno longer lets Vite clear the terminal over the CLI's own preflight output. The newdeepspace/testing/mcpsubpath ships a dependency-free MCP wire client (initialize/listTools/callTool/notify) used by the SDK's own new wire tests. Breaking for test-harness code that reached into the cache internals:readCachedStateis removed fromdeepspace/testing(validation replaced age-based reuse),getStatePathForEmailnow requires abaseURLsecond argument because cache identity is keyed by auth scope + app origin + email, andEnsureStorageStateOptions.maxAgeMsis gone.
Patch Changes
- ChatPanel's first chat can no longer vanish. When mounted with
chatId={null}, the panel now keeps the chat it creates (prop changes still win, including back to null for "new chat"), so messages render and persist without requiring the parent to wireonChatCreated— previously the screen stayed permanently empty and every further send leaked another chat record.onChatCreatedis a plain notification again. The AI chat page also stops offering "Retry" (which created a new chat) after a failed delete, and surfaces rename failures instead of logging them. - Brandable AuthOverlay (title/description/logo props,
--ds-auth-backdropvar), an in-page signed-out fallback for the scaffold's protected routes, Modal long-string wrapping, integration-test catalog error/retry states, and a token-styled cron log page. - Fix agent-reported workspace continuations, file metadata and generated file-manager behavior, collaborator recovery guidance, documentation theme strict mode, and source-mode guidance.
- Deploys are bounded, faster, and tell you where the time went. Every deploy HTTP call now carries an explicit per-attempt timeout (60s; the commit POST gets 240s and retries once instead of three times, since each re-POST records a release) — a hung deploy service surfaces as a fast retryable failure instead of a silent multi-minute stall. Asset uploads run 16-wide instead of 4-wide, which matters exactly on many-small-file first deploys where per-request round trips, not bandwidth, dominate. The CLI now prints phase durations —
Built (Ns),Uploaded N file(s) in Ns,Platform commit: Ns,Deployed! (edge confirmed in Ns)— so a slow deploy names its slow phase instead of demanding forensics. - Native documentation gains
theme.density: "compact"— one config key that tightens type scale, measure, padding, header, and sidebar through new geometry tokens (--documentation-font-size,--documentation-line-height,--documentation-content-width,--documentation-reader-pad), so matching a compact host no longer takes hundreds of lines of custom CSS. Unknownthemekeys now warn instead of silently vanishing, and the config input type now carries exactly the settable keys —preset(never implemented) is gone, and resolved-only keys (backgroundDark,backgroundDecoration, the font fields,codeBlockMode,eyebrowStyle,logoHref) moved to the newResolvedDocumentationThemetype (Mintlify normalization is unaffected). Documentation output now records thedeepspaceversion that built it — in the manifest and as a small footer line — so a docs site can't silently describe an older SDK. The machine surfaces get honest edges:documentation_searchflags weak matches with an explicit notice instead of returning confidently-scored misses,documentation_readaccepts slash-less routes and returns just the requested#fragmentsection (whole page plus a notice when the fragment is unknown), and a missing.mdpage answers with a one-line plain-text 404 instead of the styled HTML page. - The integration catalog now tells you what each endpoint does before you call it:
deepspace integrations listprints a one-line description per endpoint (with an OAuth tag where the platform manages the OAuth connection), andintegrations infoadds the description, a Requires-OAuth explanation of the retry flow, and a curated output schema for endpoints whose success shape the platform defines.--jsoncarries the same fields.