fix(showcase): a type: 'modal' target names a page — showcase_new_task becomes a form action (#6739) - #7237
Merged
Conversation
…task` becomes a form action (#6739) `showcase_new_task` declared `type: 'modal'` + `target: 'showcase_component_gallery'` — the showcase HOME PAGE. The dispatch opens the welcome page inside a dialog with zero form controls, so a command labelled "New Task" creates nothing. The issue's suggested one-key fix (point the modal at the `showcase_task` OBJECT) does not build: `defineStack`'s cross-reference walk accepts only declared PAGE names for a modal target. Per the maintainer ruling on #6739, that walk — together with the spec TSDoc and the published docs — IS the contract; objectui's page-then-object resolution is consumer leniency the renderer itself labels "Back-compat" and is being retired on its own sequenced card. So the fix is the TYPE, not the target: `type: 'form'` + `target: 'showcase_task.edit'`, structurally identical to `LogTimeAction`. PR #6737's inline `element:button` action of the same name is re-worked to the same shape in this commit (ruling item 1) — it depended on the object branch and only built because the cross-reference walk never visits an inline action (#6889). Pin tests assert the ruled shape on both sites plus the corpus-wide rule, so the reference corpus cannot drift back. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016R9de1FqP7NvwKvqXi92Gh
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
os-help
marked this pull request as ready for review
August 10, 2026 03:46
This was referenced Aug 10, 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.
Fixes #6739
Implements the maintainer ruling of 2026-08-09 (ruling A — a
type: 'modal'target names a PAGE, only), items 1 and 1-bis.What changed
Two corpus sites, one action name, one shape:
examples/app-showcase/src/ui/actions/index.ts— registeredNewTaskActiontype: 'modal',target: 'showcase_component_gallery'(a PAGE — the showcase home)type: 'form',target: 'showcase_task.edit'examples/app-showcase/src/ui/pages/index.ts— the inlineelement:buttonCTA landed by PR #6737type: 'modal',target: 'showcase_task'(an OBJECT, via the renderer's fallback)type: 'form',target: 'showcase_task.edit'Both are now structurally identical to
LogTimeActionin the same file, which builds and is spec-clean today. Plus pin tests inexamples/app-showcase/test/actions.test.ts.⛔ Deliberately NOT touched, per the ruling's scope:
packages/spec(the validator stays page-only — that IS the ruling), objectui (theresolveModalTargetfallback retirement is its own sequenced card, ruling item 2), and the inline-validation hole (#6889 owns it and is sequenced after this).Honest framing of what this fixes
The issue body's stated symptom — "the global_nav New Task command opens the home page in a dialog" — was disproven by the previous dev before the ruling:
global_navrenders nowhere in the running app (tracked separately as #6888), so no palette command exists to misbehave. This PR does not claim to fix a palette behavior.What it does fix is corpus correctness. The showcase is reference material that humans and AI authors copy, and it was teaching two wrong things at once: one action name meaning two different dispatches, and a dependence on a resolution branch that is entering retirement.
Browser verification — real click-through, the #6597 precedent
Chromium 141, showcase booted with
objectstack dev --ui --seed-admin, console served frompackages/console/distbuilt byscripts/build-console.shat the pinned.objectui-sha09987b680d53801c79f67d969b14e9bb732b8a22— i.e. the exact vendored renderer, not objectui HEAD. Full journey: land on the showcase home page, click the "Create Task" CTA, fill the form, submit.7 form controls, and a record actually created — matching the 7 controls the original #6739 probe measured for the Task create form, against the 0 controls the old
modal→ page dispatch produced. Screenshots taken at the filled-form and post-submit steps confirm it visually rather than by DOM dump alone.Independent server-side corroboration, before any clicking:
GET /api/v1/meta/view/showcase_task.editreturnsviewKind: "form"on objectshowcase_taskwith exactly those 7 fields (title,project,assignee,status,priority,due_date,notes) — so the target resolves as a form view, not as anything else.What the click-through also showed, stated rather than glossed
type: 'form'is a route-navigating action in the renderer (ActionRunner.executeForm→/forms/:name), and/forms/:nameis a top-level route outside the console shell, whose default post-submit panel is the anonymous-form "Thanks! Your submission has been received." So the CTA now leaves the app chrome and ends on a generic receipt instead of the created record. The previousmodalshape opened a dialog in place.This is pre-existing platform behavior —
showcase_log_timealready ships on the same route — and it is inherent to the shape the ruling directs, not something this PR introduces. But this PR newly routes the home page's primary CTA through it, so it should be a conscious call: filed as #7245 (observation-class, unassigned, nopm:queue) rather than fixed here.Static verification
Worktree
objectstack-issue-6739, branch offorigin/main@3566e5520.Suite — green (baseline 15 files / 154 tests; +4 new):
pnpm --filter @objectstack/example-showcase typecheckclean;objectstack validate→✓ Validation passed (1436ms);node scripts/check-nul-bytes.mjs→OK (scanned 6618 text file(s) … no raw ASCII control bytes).Reverse verification 1 — restore both sites to
origin/main, run the pin tests. Expected direction, and the result splits in a way worth stating rather than smoothing over:Note which assertion does not go red:
every REGISTERED modal action targets a declared pagestays GREEN on the old code, becauseshowcase_component_gallerygenuinely is a page. That is correct and is the point — the old registered action was spec-legal and still wrong, which is why the shape assertion carries that half. The corpus-wide rule catches the inline site, where the build gate cannot see (#6889).Reverse verification 2 — the issue's suggested one-key fix, re-measured on today's
main. Reproduces the previous dev's finding exactly:Every test file that imports
objectstack.config.tsdies at import. So the one-key swap is a build error, not a fix — this is what makes the ruling'stypechange (rather than atargetchange) the only shape that works.Coverage
coverage.test.tsrequires everyActionTypeand everyActionLocationto appear in the bundle. Neither is lost:modalstays covered byQuickViewAction, which targets the same page and whose "Quick View" label actually matches "open a dialog/page" semantics;global_navstays covered —NewTaskActionkeeps itslocations.Changeset
None — this is the
skip-changesetcase.examples/app-showcase/package.jsondeclares"private": true, so the package publishes nothing and a changeset would version nothing. The change is confined toexamples/app-showcase. Label applied.Generated by Claude Code