Repository navigation
Conversation
…rpc) The sandbox daemon now serves the Deco content protocol over its working tree, the way `deco serve` does on a laptop: content lives in <app root>/.deco/blocks/*.json and is committed and pushed like code, with no CDN draft. - internal/content: a Go port of @decocms/blocks/protocol (server, fs storage, keys, secret guard incl. the legacy v7 secret-loader exemption, asset uploads). It writes the same bytes as the TS server, so it has its own JS-compatible JSON (property order, number formatting, escaping, lone surrogates) and UTF-16 string ordering. - POST /_sandbox/rpc and PUT /_sandbox/assets/<name>, both behind the daemon token. Commits and uploads take the worktree lock, then .deco/.blocks.lock; reads take no lock and nothing touches /health. - Every write goes through the fs routes' hook, so file-changed, the decofile version and branch status follow. /_sandbox/decofile (v7) is unchanged. - .deco/.blocks.lock and .deco/.tx-*/ go into .git/info/exclude. - daemon-e2e runs the published conformance suite (pinned @decocms/blocks 8.1.0-next.6) against the daemon, with and without a schema, and a byte-for-byte parity run against the reference server. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…ndbox/rpc A sandbox session of a Blocks v8 project now reads and saves content through the sandbox daemon's content protocol, the same way the editor talks to a local `deco serve`: the working tree's `.deco/blocks`, committed and pushed with git like code. Previews keep showing the sandbox's dev server. - api: `POST /api/:org/sandbox/:id/:branch/rpc` and `PUT .../assets/:name` proxy to the daemon's `/_sandbox/rpc` and `/_sandbox/assets/<name>` with the same claim and auth as the other sandbox routes; `proxyDaemon` can forward a buffered binary body. - web: a `sandbox` content source. Behind the `site_editor_content_protocol` org flag, once the working tree is there, a probe of the daemon decides: a `"blocksMajor": 8` schema uses the protocol, anything else (v7, or an older image without the route) stays legacy. Asset uploads go to the daemon; saves refresh the header's git status. Co-Authored-By: Claude Opus 5.5 <[email protected]>
…e-lock wait; stay inside the tree - site editor: a sandbox session is `legacy` unless the flag is on and the daemon confirmed a v8 working tree — never `pending`, so a v7 sandbox's editor isn't unmounted while the flag or the probe loads. A daemon that answers 404 on /_sandbox/rpc (an older image) is v7, not an error to poll. - daemon: protocol commits and uploads wait at most 10 s for the working-tree lock (a long publish/rebase/autosave), then answer Unavailable (retryAfterMs 500) — well under Studio's 30 s proxy timeout, so a write never lands after the editor reported it failed. - daemon: .deco, .deco/blocks and public/assets resolving through symlinks outside the working tree answer NotFound (OPEN: stricter than the TS fs storage). Co-Authored-By: Claude Opus 5.5 <[email protected]>
…ocms/blocks 8.1.0-next.7) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
… + @decocms/blocks 8.1.0-next.7) Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
…tent-protocol Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
Brings in the org_sites project link (#7796) and main. Conflict in sandbox-proxy.ts: main renamed the suggest-commit body cap to JUDGE_REVIEW_MAX_BODY_BYTES; kept that plus this branch's content caps. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
tlgimenes
added a commit
that referenced
this pull request
Oct 8, 2026
Makes the Studio stack one line: #7796 -> #7728 -> #7770 -> #7766. Conflict in content-protocol-api.ts (applyProtocolPatch doc): kept both the hosted CDN-draft and the sandbox working-tree notes. Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
This was referenced Oct 8, 2026
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WNwbSEePYNcY5YCgqZURig
Contributor
Author
This was referenced Oct 8, 2026
This was referenced Oct 8, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
In a sandbox session of a Blocks v8 project, the site editor now reads and saves content through the sandbox's own daemon. The daemon works on the sandbox's working tree, so content behaves the way it does on a developer's machine. It lives in
.deco/blocks/*.json, is edited over the content protocol, and is committed and pushed with git like code. The sandbox never uses a CDN draft. Previews still show the sandbox's dev server.Daemon (Go):
7d95845e4POST /_sandbox/rpcserves the content protocol: JSON-RPC 2.0 withdescribe,schema.get,blocks.listandblocks.apply.PUT /_sandbox/assets/<name>takes uploads, capped atassets.maxBytes. Both routes require the daemon token.@decocms/blocks/protocol, with the same file layout, file-name rules, error codes and shapes, and plaintext-secret guard (including the legacy v7 secret-loader exemption). The bytes it writes match the TS server's exactly..deco/.blocks.lock, and reuse the existing write hook. That keeps the v7/_sandbox/decofileand its change events up to date. The lock file and transaction folders are added to.git/info/exclude./healthis not touched.daemon-e2eruns the published conformance suite from@decocms/[email protected](pinned) against the daemon, so any drift fails the build. Results: 79 pass, 0 fail.Studio:
67123890dPOST /api/:org/sandbox/:id/:branch/rpcandPUT …/assets/:name, proxy to the daemon. They use the same claim and auth as the other sandbox routes. A sandbox-less session gets 404.sandbox, behind thesite_editor_content_protocolorg flag."blocksMajor": 8switches the editor to the protocol. Anything else stays on the legacy path, as before: a v7 site, or an older sandbox image that lacks the route./_sandbox/decofile.Review fixes:
c707d3dc9legacyunless the flag is on and the daemon confirmed a v8 working tree; it is neverpending, so a v7 sandbox's editor isn't unmounted while the flag or the probe loads. A daemon that answers 404 on/_sandbox/rpc(an older image) is read as v7 and not polled.UnavailablewithretryAfterMs: 500. That is well under Studio's 30 s proxy timeout, so a write never lands after the editor reported it failed..deco,.deco/blocksorpublic/assetsresolve through symlinks outside the working tree, every method exceptdescribeanswersNotFound, and uploads are refused.Stack
#7796 (org_sites project link, base:
main) → #7728 (blocks v8 support) → #7770 (this PR) → #7766 (hosted)Based on
feat/blocks-v8-support. Nothing here depends on the hosted branch: the daemon route, the proxy routes and the editor'ssandboxsource only need the content protocol client that #7728 already has. #7766 sits on top of this PR (it merged this branch).Merged #7728 with #7796 in
d59b05f5f. One conflict, insandbox-proxy.ts:mainrenamed the suggest-commit body cap toJUDGE_REVIEW_MAX_BODY_BYTES(its/git/suggest-commitroute is gone); this branch's content-protocol caps are kept. Then merged #7796's review fixes via #7728 in300678c19(no conflicts). Then merged #7796's PO decisions via #7728 ina39b13c80(no conflicts), and its comment tidy-up ine1a9d31e4(no conflicts).OPEN
Internal), like any other failed upload in the TS handler.fastPreviewHostedDraft,hosted/draft-git-compat.ts) lives on feat(site-editor): hosted Deco CMS v8 — publish to CDN, CDN drafts, releases, site tokens #7766 and is kept there pending a PO decision. It is only reached by sandbox-less (cms) sessions, never by a sandbox session.describereports the server version as"unknown".invalid-jsondiagnostic, and filesystem errors. The error codes are the same.Tests
go vet,go test -race, and the daemon conformance and parity e2e: green.go test ./...green (new: busy tree refused with nothing landing later; symlinked storage refused); alldaemon-e2especs 303 pass, 1 skip, 0 fail (conformance + parity included); Studiobun run test10480 pass, 0 fail; web typecheck,oxlint,biome formatpass; e2e (one worker)content-protocol-deco-serve,sandbox-drawer-site-editor,site-editor-breadcrumbs: 11 passed.sandbox-daemon.ymlonly triggers on PRs intomain, so it was dispatched on this branch: https://github.com/decocms/studio/actions/runs/37640092180 (success: daemon-e2e, docker-smoke).sandbox-proxy.content.test.tschecks that the JSON body is forwarded, that the daemon's errors pass through, that asset bytes and content type are forwarded, and that a sandbox-less session gets 404.content-backend.test.tsanduse-content-backend.test.ts.compact-page-layout, which fails the same way onfeat/blocks-v8-support.🤖 Generated with Claude Code