Repository navigation
Deploy Studio to official website at /studio/ - #25
Conversation
- Configure Vite base path for production deployment - Update docs deployment workflow to build and deploy Studio - Add Studio navigation link to docs site - Create comprehensive Studio guide documentation - Make Studio primary CTA on homepage Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
- Add Chinese deployment guide (STUDIO_DEPLOYMENT.zh-CN.md) - Update README with Studio link and call-to-action - Provide comprehensive deployment and maintenance instructions Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
- Comprehensive summary of all changes - Technical implementation details - Testing results and verification - Maintenance instructions in Chinese Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
- Detailed user journey scenarios - Visual interface mockups - Feature demonstration flow - Performance metrics and expectations Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
- Complete Chinese explanation of the solution - Step-by-step deployment instructions - Testing and verification guide - Next steps and maintenance procedures Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
|
@copilot 网站官网是 www.objectui.org |
|
✅ All checks passed!
|
3 similar comments
|
✅ All checks passed!
|
|
✅ All checks passed!
|
|
✅ All checks passed!
|
Co-authored-by: huangyiirene <7665279+huangyiirene@users.noreply.github.com>
已更新所有文档中的URL引用,从 Changes in commit
|
There was a problem hiding this comment.
Pull request overview
This PR deploys the Object UI Studio (visual designer/playground) to the production website at https://www.objectui.org/studio/, making it publicly accessible for prototyping and learning.
Changes:
- Configured Vite to serve Studio from
/studio/path in production - Extended deployment workflow to build and copy Studio alongside documentation
- Added Studio navigation, homepage CTA, and comprehensive user guide
- Updated all promotional links to point to official domain
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
apps/playground/vite.config.ts |
Configured production base path to /studio/ for nested deployment |
.github/workflows/deploy-docs.yml |
Added Studio build step and file copying to docs distribution directory |
docs/.vitepress/config.mts |
Added Studio navigation links to top navbar and guide sidebar |
docs/index.md |
Added prominent Studio CTA button and visual editor promotional section |
docs/guide/studio.md |
Created comprehensive Studio user guide with features, shortcuts, and best practices |
README.md |
Added Studio link to main repository documentation |
|
|
||
| <div class="tip custom-block"> | ||
| <p><strong>Try it now!</strong></p> | ||
| <p>Access the Studio at: <a href="/studio/" target="_blank">/studio/</a></p> |
There was a problem hiding this comment.
The link should not open in a new tab when navigating within the same site. Remove target="_blank" or change the href to an absolute URL if external navigation is intended. For same-site navigation, users expect links to open in the same tab.
| <p>Access the Studio at: <a href="/studio/" target="_blank">/studio/</a></p> | |
| <p>Access the Studio at: <a href="/studio/">/studio/</a></p> |
| <p class="custom-block-title" style="color: #6366f1;">✨ Experience Object UI Studio</p> | ||
| <p>Explore our interactive visual editor with drag-and-drop design, live preview, and instant JSON export. Perfect for prototyping and learning!</p> | ||
| <p style="margin-top: 12px;"> | ||
| <a href="/studio/" style="display: inline-flex; align-items: center; gap: 8px; padding: 10px 20px; background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 8px; text-decoration: none; font-weight: 600; box-shadow: 0 4px 12px rgba(102, 126, 234, 0.3); transition: all 0.3s;"> |
There was a problem hiding this comment.
Inline styles should be avoided in documentation. Consider using CSS classes or VitePress custom theme styles. This makes the styling reusable and easier to maintain across the documentation site.
| run: pnpm docs:build | ||
|
|
||
| - name: Build Studio (Playground) | ||
| run: pnpm --filter @apps/playground build |
There was a problem hiding this comment.
The filter name @apps/playground appears inconsistent with typical monorepo naming conventions. Verify this matches the actual package name in apps/playground/package.json. Standard convention would be either @objectui/playground or just playground without the @apps/ scope.
| run: pnpm --filter @apps/playground build | |
| run: pnpm --filter ./apps/playground build |
|
✅ All checks passed!
|
…is not a dialect The `body`-dialect producer scan filed an item-carried `body` as `unruled:item-carrier` and reported the family question rather than answering it. The director seat answered it — summon #25 class-1 item 2, letter C, on objectui#9871 (2026-09-20): a `body` child list on a non-node ITEM is not inside objectui#6771's ruled family and not a second family. It is a producer violating the item's own published schema (`TabItemSchema` declares `content` and declares no `body`; `ListItem` likewise), fixed at the producer — done, objectui#9941. So `dispositionOf('item')` is now `ruled:not-a-dialect/item-schema-violation`. The name carries the answer instead of leaving a reader to guess it, and the ruling is cited where a reader MEETS the disposition: beside the constant, in the `KNOWN_LIMITS` entry every run emits in both modes, and in the note the text mode prints under the dispositions table. The behavioural half, which is not a string: the site leaves every pending list — it awaits no seat — while the arithmetic is unchanged. An item carrier is still never folded into objectui#6771's ruled total, and step 4's landability is judged on the node face only. The scan never computed that landability and still does not; `finalVerdict` already disclaimed it. The rename introduces one hazard and pins it in the same act: both answers now begin `ruled:`, so a prefix match would fold the item carrier straight into the ruled total. The discriminator is the CARRIER, and a new pin holds the two buckets apart on exactly that. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_018HrVaotisyhgmot9o2MLRq
…is not a dialect (objectstack-ai#10087) Fixes objectstack-ai#9871 `Clause-②: no` — an internal scanner's disposition string and the pins that read it. It moves no exported symbol and no key on a published payload. ## What this is The second flight on objectui#9871. The first one's code landed (PR objectstack-ai#9940, `Part of` on purpose, while the family question was still open). The director seat then answered it — **summon objectstack-ai#25 class-1 item 2, letter C**, 2026-09-20: > A `body` child list on a non-node ITEM (tab item, list item) is ⛔ not inside objectui#6771's ruled family and ⛔ not a second family: it is a producer violating the item's published schema, fixed at the producer (done: objectui#9941). The scanner's `unruled:item-carrier` disposition is renamed to a ruled, non-dialect disposition … and leaves any pending list; objectui#6771 step 4's landability is judged on the node face only. This PR is that rename and its pins. ⛔ The scan, the criterion and the census are ⛔ not re-opened. ## The spelling, and why it is not neutral `dispositionOf('item')` is now **`ruled:not-a-dialect/item-schema-violation`**. The name carries the answer rather than leaving a reader to guess it, and the ruling is cited **where a reader MEETS the disposition**, not only in the file header: - beside the constant (`dispositionOf`'s docblock); - in the `KNOWN_LIMITS` entry — id `unruled-item-carrier` becomes `item-carrier-not-in-ruled-total` — which **every run emits in both output modes**; - in the note the text mode prints under the dispositions table. Each of those three states in one line what the site actually IS: a producer violating the item's own published schema (`TabItemSchema` declares `content` and declares no `body`; `ListItem` likewise), fixed at the producer. ## The behavioural half, which is not a string - **It leaves every pending list.** The header section「The open question this scan REPORTS and ⛔ does not answer」is gone; its replacement states the ruling. The `KNOWN_LIMITS` entry no longer says「unruled … reports the question rather than answering it」, and the printed note no longer asks it. An `item` hit awaits no seat. - **The arithmetic did ⛔ NOT change.** An item carrier is still never folded into objectui#6771's ruled total. What changed is the reason — not that family at all, rather than not-yet-judged. - **Step 4 landability: already right, ⛔ not "fixed".** Read before changing, as the order required: the scan does ⛔ not compute or report objectui#6771 step 4's landability. `finalVerdict`'s docblock already disclaimed it in as many words (「It is NOT … the day objectui#6771 step 4 becomes landable」), and item carriers were already out of the ruled bucket. Only the prose moved, to state the node-face-only rule. ##⚠️ The hazard this rename introduces, pinned in the same act Both answers now begin `ruled:`. A reader that bucketed on that **prefix** would fold the item carrier straight into the ruled total — the one arithmetic the ruling says must not weaken. The discriminator is the **carrier**, never the prefix, and a new pin holds the two buckets apart on exactly that (`new Set(byDisposition).size` is 2 while both rows start `ruled:`). ## Evidence **RED before / GREEN after, file state proved in the SAME command.** The pins were written first and run against the byte-identical scanner: worktree blob `b51f13aaa` == `HEAD:scripts/body-dialect-producer-scan.mjs` `b51f13aaa`, and the run failed **4 of 26** — `expected 'unruled:item-carrier' to be 'ruled:not-a-dialect/item-schema-viola…'`, the two-bucket equality, the `KNOWN_LIMITS` id lookup (`expected undefined to be truthy`) and the CLI payload's id list. After the scanner change, blob `d42f6ac95` != HEAD: **2 files, 48 tests passed**. **The scan itself, before and after, both buckets lit.** On a planted corpus carrying BOTH carriers in one run, so the split is a discrimination and not an artifact of a one-shaped corpus: | disposition | before | after | |:--|--:|--:| | `ruled:6771` (node, the control) | 1 | 1 | | `unruled:item-carrier` | 1 | — | | `ruled:not-a-dialect/item-schema-violation` | — | 1 | On the **live tree**, nothing moved and nothing was supposed to: 0 producers before and after, with the same-subject controls identical in both runs — 5,189 files scanned, 1,067 candidate `body` spellings, 312 held out by C2, 5 passing C2 with no recognised emission channel. ⭐ Those controls are the point: a zero from a corpus that could not have held the subject would be a broken instrument, and this card exists because a classifier was provably blind in two directions. **Premise re-taken before any edit**, on `origin/main` `0c2eb5eee`, each leg with its control in the same command: the criterion header carries `C1 — EMISSION` / `C2 — RESOLUTION` / `C3 — CARRIER`; `unruled:item-carrier` was present at 8 sites in 3 files while the control spelling `ruled:6771` lit 4 sites in the same command (so the instrument distinguishes *this* spelling from *any* disposition); the shipped `tabs` `defaultProps` spell `content`, objectui#9941 is closed, and the producer-side repair the ruling rests on really is landed. **Gates, re-run as the last action before the push**, at `5d81f6cda` with `git diff HEAD` empty and nothing untracked: `check:control-bytes`, `check:entry-guard`, `check:new-line-citations`, `check:comment-mask-corpus`, `check:unreferenced-sources`, `check:test-path-roots`, `check:esm-specifiers`, `check:changeset-claims`, `check:pending-changeset-literals`, `check:changeset-presence`, `check-hand-rolled-comment-mask`, `check:vi-mock-specifiers`, `check:lint-rule-coverage`, `check:required-check-set --self-test` — all exit 0. Tests behind the shared verify lock (`VERDICT command-exit 0`). **Changeset: decided by the gate, ⛔ not from memory.** `node scripts/check-changeset-presence.mjs` at `5d81f6cda`: `No source or published contract of a released package changed in this range, so no changeset is owed.` (3 files changed, 0 of them published source.) **ESLint narrowing, declared with its three readings** at `5d81f6cda`: `eslint --no-inline-config --format json` over the 3 changed files — ② the JSON carries 3 file entries, 0 errors, 0 warnings; ① the population is read from `eslint.config.js` itself, whose 471 lines configure no type-aware linting (`projectService` / `parserOptions` / `project:` grep exits 1, with `languageOptions` / `rules:` lit as the control in the same command); ③ therefore this diff cannot move the verdict on any untouched file. The repo-wide `pnpm lint` run is CI's. ## Acceptance notes ⛔ No third file reads the disposition string. The census pin `scripts/__tests__/body-dialect-census.test.ts` is one of the scanner's pins under `scripts/__tests__/` and is inside the declared surface; `package.json` and `.changeset/9871-body-dialect-producer-scan.md` name the *script*, never the disposition, and are untouched.⚠️ The census pin's item-carrier assertion stays **vacuous on the live tree** — the item-carried set has been empty since objectui#9941, so the loop body never runs. It is updated to the new spelling and kept, ⛔ not deleted, exactly as its own comment instructs: it fires the moment an item-carried producer returns. The instrument that actually failed before this change is the producer-scan pin set, which is where the new assertions live. `noted, not filed:` `packages/components/src/renderers/layout/tabs.tsx` still reads `item.content || (item as any).body` — a lenient consumer fallback for the spelling the producer no longer emits. It is a **reader**, so the criterion correctly scores it as not a producer, and it is also what keeps C2's item leg resolvable. Retiring it is a consumer-side decision on the item face, ⛔ not this card's rename, and ⛔ not a dialect question under the ruling above. Successor: whoever holds the item face on objectui#9590. --- 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_018HrVaotisyhgmot9o2MLRq --- _Generated by [Claude Code](https://claude.ai/code/session_018HrVaotisyhgmot9o2MLRq)_ Co-authored-by: Claude <noreply@anthropic.com>
Enables public access to the Object UI Studio (visual designer + playground) by deploying it alongside the documentation site at the official domain www.objectui.org.
Changes
Build configuration
base: '/studio/'inapps/playground/vite.config.tsDeployment pipeline (
.github/workflows/deploy-docs.yml)NODE_ENV=productionafter docs buildapps/playground/dist/*todocs/.vitepress/dist/studio/apps/playground/**andpackages/**Documentation integration
/guide/studiowith features, shortcuts, use caseshttps://www.objectui.org/Documentation added
docs/guide/studio.md- User guideResult
Studio accessible at
https://www.objectui.org/studio/with:Verified build output shows correct asset paths:
Original prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.