Uh oh!
There was an error while loading. Please reload this page.
Converge the dev stacks on one origin: empty VITE_SERVER_URL, proxy for the split host - #5765
Merged
Merged
Conversation
Empty `VITE_SERVER_URL` in both dev env files and give `console-starter` the `/api` dev proxy it never had, so a relative `type: 'api'` action target resolves SAME-ORIGIN and the Vite proxy makes the split-host hop. Both dev envs pointed `VITE_SERVER_URL` at `http://localhost:3000` while the page was served from `:5180` (console) and `:5173` (starter). Every client in these apps coalesces an unset value to '' and then builds a relative `/api/...` URL, so an empty value routes through the dev proxy instead of off-origin. This is the ruled prerequisite for the `sameOriginOnly` action-runtime default: under that default a non-empty `VITE_SERVER_URL` makes every relative-target `type: 'api'` action resolve cross-origin and be fetched bare -- no Authorization, no X-Tenant-ID, no Accept-Language -- i.e. a 401 for the standard `pnpm dev` stack. `examples/console-starter/.env.production` is emptied too. Its committed `https://demo.objectstack.ai` is the same pre-convergence value the sibling console carried until c351c96 ("default published SPA to same-origin") cleared it there for CORS-blank-page reasons and touched only `apps/console/.env.production`; the starter was left behind by that commit. As a fork-ready scaffold, its committed value is the production origin every fork inherits. No port is pinned for `console-starter` -- its README documents the example on Vite's default 5173.
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
os-zhuang
marked this pull request as ready for review
August 23, 2026 05:46
Uh oh!
There was an error while loading. Please reload this page.
This was referenced Aug 23, 2026
os-zhuang pushed a commit
that referenced
this pull request
Aug 23, 2026
…n READMEs PR #5765 emptied VITE_SERVER_URL in both dev env files (same-origin by default, per the 2026-08-23 ruling on #5702). Three doc-prose items had drifted from that: 1. apps/console/README.md's Quick Start and Development Mode sections still said VITE_SERVER_URL defaults to http://localhost:3000 — it now ships empty, with the Vite dev proxy (DEV_PROXY_TARGET, defaulting to http://localhost:3000) forwarding /api/* to the backend. 2. examples/console-starter/README.md's Backend table still tabulated the old non-empty .env.development/.env.production values — both now ship empty (same-origin), documented with the same DEV_PROXY_TARGET recipe. 3. apps/console/README.md claimed the dev proxy covers /api/* and /_account/* — vite.config.ts only ever proxied /api. Per triage discretion on #5766 (zero first-party producers of /_auth/ or /_account/ action targets on origin/main, and /_account is recorded as retired into the console SPA), this fixes the doc rather than widening the proxy: states /api/* only and notes /_auth/* and /_account/* are not proxied. Fixes#5766 Filed #5802 (out of scope) for the same stale-default drift in content/docs/guide/console.md, which sits outside this card's scope. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EuPCi56cnGyykygi3z9w4m
akarma-synetal pushed a commit
to akarma-synetal/objectui
that referenced
this pull request
Aug 23, 2026
…n READMEs (objectstack-ai#5803) PR objectstack-ai#5765 emptied VITE_SERVER_URL in both dev env files (same-origin by default, per the 2026-08-23 ruling on objectstack-ai#5702). Three doc-prose items had drifted from that: 1. apps/console/README.md's Quick Start and Development Mode sections still said VITE_SERVER_URL defaults to http://localhost:3000 — it now ships empty, with the Vite dev proxy (DEV_PROXY_TARGET, defaulting to http://localhost:3000) forwarding /api/* to the backend. 2. examples/console-starter/README.md's Backend table still tabulated the old non-empty .env.development/.env.production values — both now ship empty (same-origin), documented with the same DEV_PROXY_TARGET recipe. 3. apps/console/README.md claimed the dev proxy covers /api/* and /_account/* — vite.config.ts only ever proxied /api. Per triage discretion on objectstack-ai#5766 (zero first-party producers of /_auth/ or /_account/ action targets on origin/main, and /_account is recorded as retired into the console SPA), this fixes the doc rather than widening the proxy: states /api/* only and notes /_auth/* and /_account/* are not proxied. Fixesobjectstack-ai#5766 Filed objectstack-ai#5802 (out of scope) for the same stale-default drift in content/docs/guide/console.md, which sits outside this card's scope. Claude-Session: https://claude.ai/code/session_01EuPCi56cnGyykygi3z9w4m Co-authored-by: Claude <noreply@anthropic.com>
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 freeto 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#5745
The ruled prerequisite for #5702. Landing this alone is harmless; landing #5702 without it breaks the standard
pnpm devstack.What changed
apps/console/.env.developmentVITE_SERVER_URL=http://localhost:3000examples/console-starter/.env.developmentVITE_SERVER_URL=http://localhost:3000examples/console-starter/.env.productionVITE_SERVER_URL=https://demo.objectstack.aiexamples/console-starter/vite.config.tsserverblock at all/apiproxy stanza, no port pinnedapps/console/.env.productionandapps/console/vite.config.tsare untouched.The enumeration (this was the substance, not the three-line edit)
Full-repo scan, no
node_modulespresent at scan time: 114 mentions ofVITE_SERVER_URL, of which ~50 are executable read sites. Every one was traced to the path it actually builds — through prop-passing consumers (FlowRunner,createConsoleServerActionHandler,createObjectStackUploadAdapter,useEnvironmentEntitlements,createIdentityImportDataSource,MetadataClient,ObjectStackAdapter) and into@objectstack/client@17.1.0's own route table.Class 1 — statically under
/api(the overwhelming majority). Everyfetch-building site:/api/v1/...,/api/data/...,/api/settings. The existing/apiproxy covers all of them, because a Vite proxy key matches by prefix.Class 2 — suffix supplied by metadata or by server data.
${baseUrl}${resolvedTarget}(useConsoleActionRuntime.tsx:346,RecordDetailView.tsx:640),${apiBase}${resolved}(MetadataTypeActions.tsx:151), storage download URLs (RecordApprovalsPanel.tsx:312,ApprovalsInboxPage.tsx:723,RecordAttachmentsPanel.tsx:363),${apiBase}${url}/${apiBase}${warmUrl}(CloudAiModelStatus.tsx:99,CloudOnboardingNext.tsx:125). Not statically bounded — this is exactly the class #5702 exists for. Every first-party default in it is/api/....Class 3 — server-supplied route table.
@objectstack/client'sgetRoute()prefersdiscoveryInfo.routes[key]over its built-in map. That built-in map is 100%/api/v1/*and its own comment says both discovery producers emit the conventional paths — but a server could advertise a route outside/api, and the proxy would not cover it. Named, not solved.The counterexamples — reported, not worked around
The card's premise was that convergence is clean. It is, for every
fetch. It is not universally clean, and both exceptions are navigations, not fetches:packages/core/src/actions/ActionRunner.ts:1343promotes/api/,/_auth/and/_account/to${apiBase}${url}and then does a full-pagewindow.location.href./_auth/and/_account/are not under/apiand are covered by neither proxy. Reachability measured: 7 repo-wide hits, all CHANGELOG / test / doc prose — no first-party producer of such an action target exists./_account/*is a sibling SPA mount (apps/console/src/utils/consoleBase.ts:37), andapps/console/src/App.tsx:7records that it is being retired into the console SPA itself, so a same-origin/_account/...landing on the console is arguably the intended end state.packages/app-shell/src/environment/entitlements.ts:48—DEFAULT_UPGRADE_URL = '/settings/billing', rendered byresolveCtaHrefas${apiBase}/settings/billing. Non-/api, and an anchorhrefthat no proxy could help. Emptying improves this site: today it openshttp://localhost:3000/settings/billingin a new tab (external: Boolean(base)); empty makes it a same-origin in-app route — which is already the shipped production behaviour, sinceapps/console/.env.productionhas been empty since 2026-05-24.I did not widen
apps/console/vite.config.ts(read-only under this card's fence). Reason it is not needed: the/apiproxy already covers every fetch site, and the two non-/apipaths are navigations with no first-party producer. If the maintainer wants/_auth+/_accountproxied for symmetry, that is a one-stanza follow-up — flagged rather than taken..env.production— established, not guessedThe ruling said revisit, not change. What was established:
examples/console-starterisprivate: true, on the changesetignorelist, and referenced by no workflow, no vercel config, no deploy (controlled grep:apps/consolehits 3+ workflows,console-starterhits none).apps/console/.env.productioncarried the identicalhttps://demo.objectstack.aiuntilc351c9604, 2026-05-24, "fix(console): default published SPA to same-origin (clear VITE_SERVER_URL)" — whose changeset reads "CORS-blocked auth/i18n/discovery calls were preventing the SPA from rendering when embedded in any host other than the demo deployment." That commit touched onlyapps/console/.env.productionplus its changeset. The starter was left behind by it.10d2a5119(the starter's apparent origin commit) is a pure rename with 0-byte diffs, so the value predates it as a shared sibling default.Conclusion: not deliberate — it is the pre-convergence value that the 2026-05-24 same-origin fix did not reach. As a fork-ready scaffold its committed value is the production origin every fork inherits.
Port
console-starterstays on Vite's default 5173, deliberately: its README already documentspnpm dev # Vite; no server.port is set, so the default 5173, and pinning one would only collide with a real fork's choice.apps/consolekeeps 5180.Evidence
Union re-run at final commit
645b024cb, tree clean.Measured before/after of a relative action target, computed off the real env files (before read from git at the merge-base, after from the working tree) using the resolution rule copied verbatim from
useConsoleActionRuntime.tsx:326+:346:End-to-end, real dev server against a recording stub backend — the starter's new stanza actually forwards:
Ablation (stanza removed by taking
origin/main's config; mutation proved on disk by marker count —DEV_PROXY_TARGET0 occurrences, controlworkspaceAliasesstill 2; vite readsvite.config.tsdirectly at startup so no build step is involved; restore leg proved bygit status --porcelainempty). Predicted direction stated before running — hits go to zero while HTTP stays 200:That is also the hazard in miniature: without the proxy, an empty
VITE_SERVER_URLwould return HTML with a 200 rather than failing loudly.Gates, exit codes captured before any pipe, each line quoted from the gate's own verdict:
Tests chosen because they are the ones that actually read the changed files:
committed-telemetry-endpoint.test.ts(enumerates every committed.env*viagit ls-filesand parses it from disk),vite-alias-closure.test.ts(readsconsole-starter/vite.config.ts),runtimeConfigBootDedup.test.ts(pins the%VITE_SERVER_URL%HTML substitution, including the empty case).Lint narrowing is a measurement, not a skip: eslint itself was asked which of the 5 changed files it considers — 4 report as ignored, 1 is linted;
--format jsonreportsfiles linted: 1, errors: 0, warnings: 0; andeslint.config.jsdeclares noprojectService/parserOptions.project(grep exit 1, controlled byruleshitting 10x in the same file), so type-aware linting is off and this diff cannot move the verdict on any untouched file. Independently,check-lint-coveragereports 46/46 packages clean.process.envin the starter's vite config is safe:tsc --showConfigreports its program as 2 files (src/App.tsx,src/main.tsx) andincludes vite.config.ts: false, matching the__dirnamealready in that file; eslint does lint it and is clean.Not run and not claimed: the repo-wide
pnpm lint/pnpm testfarms, which CI runs exactly once regardless; and the three gauges known to be broken in a worktree (check-eager-closure-budget,check-doc-snippet-types,check-published-dist-tooling).Build Docsshould report a ~10s skip, since this diff touches neitherapps/site/norcontent/— that skip is not evidence the docs site builds.Known gap this PR does not close
Doc drift, outside this card's write fence, filed as #5766 —
examples/console-starter/README.mdstill tabulates the two old env values,apps/console/README.md:36still says "defaults tohttp://localhost:3000", andapps/console/README.md:54claims Vite proxies/api/*and/_account/*whenvite.config.ts:709-711proxies only/api(that last one is pre-existing). Say the word and I will fold the doc half in here.Generated by Claude Code