fix(studio): gate edit affordances on read-only packages, live-sync field API name#2263
Merged
Conversation
…ield API name Two P1 findings from the Studio package-create UX dogfood (objectstack-ai/framework#2615, mirrored as #2258): - Read-only packages accepted edit gestures client-side and only failed at save time. Thread package writability (from the same fetchPackages() the PackageSwitcher already uses) down into the Data pillar and hide/disable "Add field" (toolbar button, grid header "+", form-designer "+") and "New object" when the package isn't writable. Purely a courtesy gate — the server's writable_package_required check remains the authority. - A new field's API name never followed its label before first save, so a field relabeled to "Status" kept its auto-generated name (e.g. field_2) forever. Sync the name from the label live, per keystroke, while the name is still auto-generated (either the type-based or nextFieldName() field_N scheme) and un-customised — mirroring the existing object/app identifier behavior, using the same keystroke-safe toFieldNameLoose() slug.
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
Contributor
✅ Console Performance Budget
📦 Bundle Size Report
Size Limits
|
Merged
5 tasks
os-zhuang
pushed a commit
that referenced
this pull request
Jul 5, 2026
…8n sweep Upstream landed read-only gating + live API-name sync (#2263) and review-then-publish + changes detail (#2271) in parallel — take those implementations wholesale (they supersede this branch's #2259/#2260/#2261 work, including per-keystroke name sync and a structured diffFields-based detail). Kept from this branch: create-app nav scaffolding (#2262), the studio-design i18n sweep (#2264), ObjectFormDesigner's full read-only mode, and the nav-seeded skeleton conformance case; dropped the now- redundant blur-based derive tests in favour of upstream's. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DHQc5BdGhTzPfazex3vWdt
os-zhuang
pushed a commit
that referenced
this pull request
Jul 5, 2026
…name derive and changes-panel implementation, keep this PR's four-pillar readOnly gating, nav scaffold and i18n sweep
6 tasks
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.
Summary
Fixes two P1 findings from the Studio "create a package and build in it" browser dogfood (objectstack-ai/framework#2615, mirrored here as #2258). The framework-side item from that audit (error-copy citing an internal ADR path) already shipped in objectstack-ai/framework#2618.
fetchPackages()/PkgEntry.writablethePackageSwitcherbadge already reads) down into the Data pillar, and hid/disabled "Add field" (toolbar button, grid header "+", form-designer "+") and "New object" when the package isn't writable. This is a courtesy gate only — the server'swritable_package_requiredcheck (ADR-0070) remains the authority.field_2after relabeling to "Status", so the eventual data column name wasfield_2forever. The API name now syncs from the label live, per keystroke, while the name is still auto-generated (either the type-basedtext_2-style scheme or thenextFieldName()field_Nscheme) and hasn't been hand-edited — mirroring the existing object/app identifier behavior, reusing the same keystroke-safetoFieldNameLoose()slug.Test plan
ObjectFieldInspector.test.tsx— added 3 tests covering: live label→name sync for a freshfield_N-named field, sync stopping once the API name is hand-edited (via a stateful harness that round-tripsonPatchback intodraft, since the real parent does the same), and an already-meaningful name staying untouched. 19/19 passing.npx vitest run packages/app-shell— full package suite, 958/958 passing (no regressions).npx tsc -p packages/app-shell/tsconfig.json --noEmit— no new type errors in the touched files.npx eslinton the changed files — 0 errors (pre-existing warning patterns only, no new ones).Not covered here (no existing test harness for this large, router/context-heavy component): a
DataPillar-level test asserting the "Add field"/"New object" affordances are actually hidden/disabled for a read-only package. Worth a browser/e2e follow-up dogfood pass to confirm visually.🤖 Generated with Claude Code
Generated by Claude Code