deepspace 0.27.0 → 0.28.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 (53) hide show
  1. package/CHANGELOG.md +61 -0
  2. package/README.md +19 -8
  3. package/dist/{chunk-SF6GNPYL.js → chunk-652TIGI4.js} +2 -2
  4. package/dist/{chunk-SF6GNPYL.js.map → chunk-652TIGI4.js.map} +1 -1
  5. package/dist/cli.js +1819 -1068
  6. package/dist/cli.js.map +1 -1
  7. package/dist/documentation-client-core.js +1 -1
  8. package/dist/documentation-default-renderer.cjs +1 -1
  9. package/dist/documentation-react.js +1 -1
  10. package/dist/documentation-runtime.js +1 -1
  11. package/dist/documentation-server-core.js +1 -1
  12. package/dist/documentation.d.ts +0 -1
  13. package/dist/documentation.js +41 -21
  14. package/dist/documentation.js.map +1 -1
  15. package/dist/feature-installer.js +27 -61
  16. package/dist/feature-installer.js.map +1 -1
  17. package/dist/index.d.ts +6 -55
  18. package/dist/index.js +4 -20
  19. package/dist/index.js.map +1 -1
  20. package/dist/schema.js.map +1 -1
  21. package/dist/server.d.ts +8 -39
  22. package/dist/server.js +16 -64
  23. package/dist/server.js.map +1 -1
  24. package/dist/testing.js +2 -2
  25. package/dist/testing.js.map +1 -1
  26. package/dist/worker.d.ts +7 -80
  27. package/dist/worker.js +17 -69
  28. package/dist/worker.js.map +1 -1
  29. package/features/admin-page/feature.json +0 -1
  30. package/features/ai-chat/feature.json +0 -1
  31. package/features/canvas/feature.json +0 -1
  32. package/features/cron/feature.json +0 -1
  33. package/features/documents/feature.json +0 -1
  34. package/features/file-attachments/feature.json +0 -1
  35. package/features/file-manager/feature.json +0 -1
  36. package/features/integration-test/feature.json +0 -1
  37. package/features/items/feature.json +0 -1
  38. package/features/kanban/feature.json +0 -1
  39. package/features/landing/feature.json +0 -1
  40. package/features/leaderboard/feature.json +0 -1
  41. package/features/messaging/feature.json +0 -1
  42. package/features/search-bar/feature.json +0 -1
  43. package/features/tasks/feature.json +0 -1
  44. package/features/testing/feature.json +0 -1
  45. package/features/topbar/feature.json +1 -4
  46. package/features/tree/feature.json +1 -4
  47. package/package.json +1 -1
  48. package/dist/chunk-Q5YJGF5Z.js +0 -769
  49. package/dist/chunk-Q5YJGF5Z.js.map +0 -1
  50. package/dist/repo-api-7GDPVSFV.js +0 -14
  51. package/dist/repo-api-7GDPVSFV.js.map +0 -1
  52. package/features/presence-test/feature.json +0 -22
  53. package/features/presence-test/src/PresenceTestPage.tsx +0 -120
package/CHANGELOG.md CHANGED
@@ -1,5 +1,66 @@
1
1
  # deepspace
2
2
 
3
+ ## 0.28.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Every confirmed finding from the v0.27.0 AX round-1 pass. Records: `records.update` (and the action-tools `tools.update` built on it) is an UPDATE, never an upsert — a typo'd or stringified-undefined recordId used to silently create a phantom record and report success; it now refuses naming `records.create` as the spelling that creates. Source: it now LATCHES at the app's first release, permanently — the first `deepspace push` claims DeepSpace at the pack POST, the first deploy latches GitHub or DeepSpace from the checkout's selected remote, and every later check is one registry field. No flag and no consent gate; the latch is announced on stderr at the moment it happens, and a wrong latch is escaped like every wrong-source state, with `deepspace app init --new-id`. `pull` on an empty cloud repo refuses `no_cloud_repo` before writing the `space` remote or git identity (it used to mutate, then say `branch_not_found`/"push first" — and now matches `clone`'s code for the same state), and `pull` gains `--env`. Collaboration: `app collaborators list` names the OWNER (`owner: {userId, emailDisplay}` + an `OWNER:` line) — five refusals say "ask the owner" and no surface said who that was; the raw `Failed: <upstream>` family from `test accounts` maps to real refusals (`test_account_cap` with the freeing commands; a dead session says re-login instead of "Unauthorized"). Install healing: a zombie installer pid (containers whose PID 1 does not reap) no longer holds `install_in_progress` for 30 minutes — the sentinel age bound is 6 minutes, just past the install's own 5-minute timeout; if `npx deepspace` ITSELF fails `not found` after an interrupted install, run the package manager's `install` directly (npx cannot resolve a half-installed tree — documented in the contract). First deploy's unborn-HEAD commit says what it does ("Initial commit (DeepSpace scaffold + working tree)", with the file count on stderr) instead of silently labeling the user's own code "scaffold". `app_not_found` appends its staging paragraph only when DEEPSPACE_DEPLOY_URL is actually overridden. Scaffolder: `--no-register` prints a one-line deprecation note instead of silence. Docs: `computeHmacHex`/`timingSafeEqualHex` documented for webhook authors; `test run`'s `skippedSpecs` semantics (suite-level file selection, not runner-level test.skip) stated in the contract; developer deletion documented as auth-side only (registered apps are retained — undeploy first).
8
+ - Every confirmed finding from the v0.27.0 AX round-2 pass (workspaces, operations, testing lanes). Agent-loop killers: `stale_base` ships NO action — its old `deepspace pull` action looped forever after a workspace-branch release (pull answered `up_to_date`; the live commit sits on a ws/\* ref trunk can never fast-forward to; two lanes hit it independently) — the refusal now names the real choices (integrate, land, or `--ignore-stale`); `port_in_use`'s action always says `dev kill --port <n>` explicitly, because bare `dev kill` resolves through dev's own port precedence and could free a different port than the one that refused (`dev kill --help` now describes that precedence honestly). `workspace land` (and the sync recovery path) detect an unresolved merge and refuse with the merge-aware code instead of `dirty_worktree` advice that would commit `<<<<<<<` markers. `workspace attach`'s failed re-materialization hands back `git worktree prune` as the action (the verified one-step fix for a stale registration). `activity`'s human line names WHICH workspace synced (the JSON always did). Consent and honesty: `test accounts recover` is now a RETRIEVAL (the platform stores the credential for these synthetic QA identities), so `--all` from a second machine no longer invalidates the first machine's pool and needs no confirmation; only a pre-storage account rotates, once, reported via `rotated`. The rename prompt defaults to No (Enter must not move a live URL). `undeploy`'s consent text says app files survive too. Storage/billing truth: reported `usedBytes` re-measures when the summary is dirty, so deletes show up in the number users see (admission always self-healed at the refusal boundary; reporting lied at a 26 MB high-water mark indefinitely); a failed integration invoke's 502 says what happened to the money (`billing: 'released' | 'retained'` — retained means the upstream outcome is unknown and the worst-case pre-charge stands). Testing: `test run tests/<file>.spec.ts` with no such file refuses `spec_not_found` instead of `tests_failed`; `test screenshot --wait-for-selector` is wall-bounded (`screenshot_timeout` names the selector that never matched); duplicate test-account emails refuse `test_account_email_taken` stating the GLOBAL namespace; `secrets set/upload --json` carries `devRestartRequired` (the dev-restart fact only the human path stated). Scaffolder: the page `<title>` is the app's name, not "DeepSpace App"; `docs/migrations/` ships a README so `app update`'s `guidanceUrl` stops 404ing on the public mirror.
9
+ - Structural complexity reductions across five surfaces:
10
+ - One destructive-consent gate (`cli/lib/consent.ts` `requireConsent`) replaces
11
+ the six hand-rolled copies in `app undeploy`, `secrets configs delete`,
12
+ `domain buy`/`detach`, `test accounts clear`, and (before its deletion) the
13
+ `recover --all` gate; `domain`'s bespoke raw-stdin prompt is deleted, and an
14
+ interactive decline now uniformly refuses (exit 1) — `domain buy`/`detach`
15
+ and `test accounts clear` previously exited 0 with `cancelled: true`.
16
+ - The `install.pid` sentinel and its liveness check are gone: "still
17
+ installing" is `install.started` with no terminal sentinel and younger
18
+ than 6 minutes; the scaffolder's installer (which has no hard timeout)
19
+ keeps the sentinel's mtime fresh while it runs, bounded at 30 minutes so
20
+ a hung-but-alive package manager cannot hold `install_in_progress`
21
+ forever. The pid check's own-pid, recycled-pid, and zombie-pid bugs go
22
+ with it; a crashed install heals after the age bound instead of
23
+ immediately. The test harness's pid-ledger cleanup guard (which watched
24
+ for a detached installer that no longer exists) is deleted too.
25
+ - Test-account credentials are stored server-side (synthetic QA identities,
26
+ on purpose), so `test accounts recover` is a retrieval: other machines'
27
+ credentials stay valid, `--all` needs no confirmation and loses its
28
+ `--yes`. Pre-storage accounts rotate once (reported via `rotated`), then
29
+ are stored.
30
+ - The auth-worker's test-account endpoints return machine `code` fields
31
+ (`test_account_cap`, `test_account_email_taken`, `not_authenticated`, …);
32
+ the CLI keys remedies on the code alone.
33
+ - One dev-server port precedence (`resolveDevServerPort` in `cli/lib/port.ts`)
34
+ shared by `dev start`, `test run`, and `dev kill`, replacing `kill`'s
35
+ duplicated `pickKillPort`.
36
+ - Source LATCHES at the app's FIRST release, permanently — either DeepSpace
37
+ or GitHub, decided once, server-side, then one registry field forever:
38
+ the first `deepspace push` claims DeepSpace at the pack POST; the first
39
+ deploy latches from the checkout's selected GitHub remote (present ⇒
40
+ GitHub with the repository recorded, absent ⇒ DeepSpace) at the deploy
41
+ commit route, announced on stderr at the moment it happens. `push`'s
42
+ `--claim-source` flag and its pre-push refusal are deleted, and so is the
43
+ whole evidence-inference apparatus: no verb consults the release ledger
44
+ anymore — `pull`/`clone`/`workspace new` refusals on a GitHub app are the
45
+ server's field check (`source_managed_by_github`), which raw `git pull`
46
+ against a leftover remote gets too. Admin pushes
47
+ stay refused on every unclaimed app, and admin on-behalf deploys never
48
+ latch. A first release that latched from an accidental remote is escaped
49
+ the same way as every wrong-source state: `deepspace app init --new-id`.
50
+ Apps that deployed from GitHub before this release and never pushed are
51
+ simply still unclaimed — their next deploy latches GitHub.
52
+
53
+ ## 0.27.1
54
+
55
+ ### Patch Changes
56
+
57
+ - App-token failures during `dev`/`deploy` now carry their HTTP status and server code, and an app id the platform cannot resolve refuses loudly with `app_not_found` instead of silently writing `.dev.vars` without `APP_IDENTITY_TOKEN` — which made every platform call fail verification at runtime with nothing printed. Deploy's `--json` envelope distinguishes these failures too: a token/`.dev.vars` failure that is not an `ApiError` and not a refreshed-cache failure now reports its own `dev_vars_failed` code instead of riding `secrets_refresh_failed`.
58
+ - Deploy no longer uploads secret values: the deploy form names the secrets config (`secretsConfig`, `wranglerEnv ?? 'prd'`) and the platform reads its own store at commit — one authority, no plaintext values on the deploy wire. Store-side, the config-missing refusal is now enforced server-side (409 `secrets_config_missing`, with the same executable `secrets configs create` fix) where it cannot be bypassed, an uninitialized store deploys as authoritative-empty exactly as before, and a store read failure fails closed (503, nothing deployed). The CLI still refuses early — before build and uploads — and still rewrites `.dev.vars` for dev parity; it now also hard-requires the `secretsSource: 'store-read-v1'` capability from the deploy service so it can never deploy against an older server that would misread the new shape as an upload with no secret bindings and strip every live user secret from an owner deploy. One check moved later: a stored secret whose name is reserved or collides with a declared wrangler binding is now refused by the platform at commit (after asset upload) rather than by the CLI before build — the price of retiring the client-side copy of that check. For one release the server also accepts the legacy `userSecrets` field from pre-0.24 CLIs (mutually exclusive with `secretsConfig`; sending both is refused), so existing installs keep deploying through the transition; the legacy arm is removed in 0.25 — update to keep deploying after that.
59
+ - Feature installer: drop the never-used `css` integration area and per-file `overwrite` flag (no feature has ever declared either), and remove the internal `presence-test` feature.
60
+ - Remove dead client-era wire riders: `retagged` is gone from `POST /api/apps/:appId/transfer/accept` responses, `GET /api/deploy/:appId` (deployment-status read, no live consumer) is gone, and the GitHub-source `stale_base` guard plus the `baseReleaseId` deploy field (always null from every shipped CLI) are gone.
61
+ - Deploy/rollback contract fixes from review: a same-key deploy retry that straddles a concurrent `secrets set` now supersedes the still-prepared reservation and proceeds (instead of dying `idempotency_key_reused`; after activation the mismatch stays a hard refusal). Rollback's not-active refusal is now coded `app_undeployed` (was `app_suspended` — the suspended status was retired, and stale registry rows are normalized to `undeployed` on schema init). Rollback's `do_guard_unavailable` refusal now carries the Cloudflare-side cause as `detail`, which the CLI renders as its `Cause:` line. The CLI's dead `bindings_read_unavailable` passthrough (no server ever emits it) is removed.
62
+ - `/api/secrets/*` error contract: internal faults (registry down, binding missing) keep answering a generic 500 with no internal error text echoed to the client — unchanged — but the fault's own message is now logged server-side as a string, so those 500s stop being undiagnosable from Workers Logs. Also: `deploy`'s `secrets_config_missing` refusal now carries `actionRequired: true` with its executable `secrets configs create` action, matching the sibling refusals.
63
+
3
64
  ## 0.27.0
4
65
 
5
66
  ### Minor Changes
package/README.md CHANGED
@@ -118,10 +118,11 @@ The hierarchy shown by `deepspace --help` keeps durable app lifecycle under
118
118
  operations stay top-level. The historical `deepspace app migrate` command was
119
119
  removed in 0.15.0; it is not an upgrade or recovery path.
120
120
 
121
- Every app has one authoritative Git repository, and which one it is follows
122
- from what you do rather than from anything you declare. DeepSpace source is the
123
- packaged default: on a checkout with no GitHub remote, the first
124
- `deepspace push` — or the source sync inside the first normal deploy — claims
121
+ Every app has one authoritative Git repository — DeepSpace's packaged repo or
122
+ GitHub — fixed permanently at the app's FIRST release, and which one it is
123
+ follows from what you do rather than from anything you declare. DeepSpace
124
+ source is the packaged default: on a checkout with no GitHub remote, the first
125
+ `deepspace push` — or the first normal deploy — claims
125
126
  it and publishes automatically. `deepspace push` publishes the current branch
126
127
  and `deepspace clone <app>` checks it out; both configure a `space` remote and
127
128
  credential helper, so normal `git fetch space` and `git push space` work
@@ -136,10 +137,11 @@ npx deepspace deploy
136
137
  ```
137
138
 
138
139
  Nothing to declare: a checkout with a GitHub remote deploys as GitHub
139
- automatically — DeepSpace never reads or writes the GitHub repository, and
140
- each release records which repository the checkout pointed at (and whether
141
- the tree was dirty). The first `deepspace push` instead claims DeepSpace
142
- source, permanently — using it is choosing it; there are no transfers.
140
+ automatically, and the first deploy fixes GitHub source permanently —
141
+ DeepSpace never reads or writes the GitHub repository, and each release
142
+ records which repository the checkout pointed at (and whether the tree was
143
+ dirty). The first `deepspace push` instead claims DeepSpace source,
144
+ permanently — using it is choosing it; there are no transfers.
143
145
  Inspect with `deepspace app source` (read-only). Commands support `--json`
144
146
  for agents. Use `deepspace --help`, command-specific `--help`, and the
145
147
  [public manual](https://docs.deep.space) for workspaces, releases, and
@@ -164,3 +166,12 @@ env binding on your Worker to emit per-connection `[DO Perf]` timing logs.
164
166
  ## License
165
167
 
166
168
  Apache-2.0
169
+
170
+ ## Verifying a signed webhook
171
+
172
+ `deepspace/server` exports the two halves of HMAC verification so apps never
173
+ hand-roll them: `computeHmacHex(secret, payload)` and
174
+ `timingSafeEqualHex(a, b)` (constant-time compare). Verify the raw request
175
+ body against the signature header before parsing, and reject stale
176
+ timestamps yourself — the r1 AX pass built exactly this and could not
177
+ discover either export from the docs.
@@ -1274,7 +1274,7 @@ function renderInlineMarkdown(value) {
1274
1274
  import { useEffect as useEffect6, useRef as useRef5, useState as useState5 } from "react";
1275
1275
 
1276
1276
  // package.json
1277
- var version = "0.27.0";
1277
+ var version = "0.28.0";
1278
1278
 
1279
1279
  // src/documentation/runtime/navigation.tsx
1280
1280
  import { Fragment as Fragment4, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
@@ -1954,4 +1954,4 @@ export {
1954
1954
  DefaultDocumentation,
1955
1955
  DocumentationContent
1956
1956
  };
1957
- //# sourceMappingURL=chunk-SF6GNPYL.js.map
1957
+ //# sourceMappingURL=chunk-652TIGI4.js.map