Skip to content

Commit 6ed2b3d

Browse files
committed
chore(package.json), feat(shell, chat, strategy-curator): pin pnpm version, env-configurable WS/remote URLs for Railway deploy (Build-Order Step 9)
Pin packageManager: pnpm@10.15.0 in root package.json — Railway's Railpack builder was resolving a different pnpm version than the one that generated pnpm-lock.yaml, causing `pnpm install --frozen-lockfile` to fail during the first deploy attempt (reproduced only on Railway; local installs were unaffected since node_modules was already in sync). shell/rsbuild.config.ts: strategyCurator and chat's federation remote URLs now read from PUBLIC_STRATEGY_CURATOR_REMOTE/PUBLIC_CHAT_REMOTE env vars at build time (localhost defaults preserved for dev) — the other twelve remotes stay hardcoded, since Module Federation remotes are lazy-loaded and nothing in the humain-vc flow ever navigates to them. shell/src/App.svelte, apps/chat/src/App.svelte, apps/strategy-curator/src/curation.svelte.ts: each app independently connects to workspace-service's WS endpoint (no shared workspace singleton across federation) — all three now read PUBLIC_WS_URL instead of a hardcoded ws://localhost:3001/ws. Files changed: - package.json - shell/rsbuild.config.ts - shell/src/App.svelte - apps/chat/src/App.svelte - apps/strategy-curator/src/curation.svelte.ts
1 parent 5796f18 commit 6ed2b3d

5 files changed

Lines changed: 51 additions & 8 deletions

File tree

apps/chat/src/App.svelte

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,30 @@
11
<script lang="ts">
22
// Chat root. Connects the workspace, mounts CharacterCastRow + ChatSurface.
33
// Standalone-mode-friendly: at :3006 the chat connects directly to
4-
// workspace-service at ws://localhost:3001/ws; in federation mode the
5-
// shell mounts this remote and the same connection is established.
4+
// workspace-service at PUBLIC_WS_URL (localhost:3001 default for dev); in
5+
// federation mode the shell mounts this remote and the same connection
6+
// is established independently (no shared workspace singleton).
67
78
import { onMount } from 'svelte';
89
import { workspace } from '@augment-it/workspace';
910
import CharacterCastRow from './CharacterCastRow.svelte';
1011
import ChatSurface from './ChatSurface.svelte';
1112
13+
// No `shared` block in federation (see shell/rsbuild.config.ts's note) —
14+
// this remote owns its own workspace singleton and connects independently
15+
// even when mounted inside the shell, so it needs the same env-configured
16+
// WS_URL the shell and strategy-curator each read (rsbuild inlines
17+
// PUBLIC_-prefixed vars into import.meta.env at build time).
18+
const WS_URL =
19+
((import.meta as { env?: Record<string, string> }).env?.PUBLIC_WS_URL as string | undefined) ??
20+
'ws://localhost:3001/ws';
21+
1222
let connectionStatus = $state<'connecting' | 'open' | 'closed' | 'error'>('connecting');
1323
1424
onMount(() => {
1525
const TOKEN_KEY = 'augment_it_session_token';
1626
workspace.connect({
17-
url: 'ws://localhost:3001/ws',
27+
url: WS_URL,
1828
getToken: () => localStorage.getItem(TOKEN_KEY),
1929
saveToken: (t) => localStorage.setItem(TOKEN_KEY, t),
2030
onStatus: (s) => {

apps/strategy-curator/src/curation.svelte.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,15 @@ import { workspace, WORKSPACE_CHANGED_EVENT, type WorkspaceSummary } from '@augm
1212
import type { ExtractKind, Source, Strategy } from './types';
1313

1414
const TOKEN_KEY = 'augment-it:session-token';
15-
const WS_URL = 'ws://localhost:3001/ws';
15+
// No `shared` block in federation (shell/rsbuild.config.ts) — this remote
16+
// owns its own workspace singleton and connects independently even when
17+
// mounted inside the shell, so it needs the same env-configured WS_URL the
18+
// shell and chat each read (rsbuild inlines PUBLIC_-prefixed vars into
19+
// import.meta.env at build time — applies to plain .ts modules too, not
20+
// just .svelte files).
21+
const WS_URL =
22+
((import.meta as { env?: Record<string, string> }).env?.PUBLIC_WS_URL as string | undefined) ??
23+
'ws://localhost:3001/ws';
1624
const ACTIVE_STRATEGY_KEY = 'augment-it:active-strategy';
1725
// The operator-chosen domain type this surface is currently browsing/
1826
// writing into ('strategy', 'thesis', or any other value they type at

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
"name": "augment-it",
33
"version": "3.0.1.0",
44
"private": true,
5+
"packageManager": "pnpm@10.15.0",
56
"workspaces": [
67
"apps/*",
78
"packages/*",

shell/rsbuild.config.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@ import { pluginModuleFederation } from '@module-federation/rsbuild-plugin';
77
// reactive singleton instance — that's the load-bearing trick that makes
88
// Window microfrontends + Chat panel all subscribe to one workspace state
99
// (Per-App-Workspace-Conventions blueprint).
10+
//
11+
// strategyCurator and chat are the only two remotes the humain-vc deploy
12+
// (Build-Order Step 9) actually mounts — their URLs are env-configurable so
13+
// a production build can point at real hosted remoteEntry.js files instead
14+
// of localhost. The other twelve stay hardcoded: they belong to flows this
15+
// deploy doesn't use, Module Federation remotes are lazy-loaded, and
16+
// leaving them pointed at localhost is the same "no isolation, they error
17+
// if poked" rule the build order already established, just now true for
18+
// federation URLs too — nobody on this instance ever navigates to them.
19+
const STRATEGY_CURATOR_REMOTE = process.env.PUBLIC_STRATEGY_CURATOR_REMOTE ?? 'http://localhost:3017/remoteEntry.js';
20+
const CHAT_REMOTE = process.env.PUBLIC_CHAT_REMOTE ?? 'http://localhost:3006/remoteEntry.js';
21+
1022
export default defineConfig({
1123
plugins: [
1224
pluginSvelte(),
@@ -17,15 +29,15 @@ export default defineConfig({
1729
promptTemplateManager: 'promptTemplateManager@http://localhost:3003/remoteEntry.js',
1830
requestReviewer: 'requestReviewer@http://localhost:3004/remoteEntry.js',
1931
responseReviewer: 'responseReviewer@http://localhost:3005/remoteEntry.js',
20-
chat: 'chat@http://localhost:3006/remoteEntry.js',
32+
chat: `chat@${CHAT_REMOTE}`,
2133
enhancedRecordsList: 'enhancedRecordsList@http://localhost:3007/remoteEntry.js',
2234
packRunner: 'packRunner@http://localhost:3009/remoteEntry.js',
2335
recordsSurface: 'recordsSurface@http://localhost:3011/remoteEntry.js',
2436
sortFilterLens: 'sortFilterLens@http://localhost:3013/remoteEntry.js',
2537
personEnrichment: 'personEnrichment@http://localhost:3015/remoteEntry.js',
2638
recordDbResolver: 'recordDbResolver@http://localhost:3008/remoteEntry.js',
2739
personDbResolver: 'personDbResolver@http://localhost:3010/remoteEntry.js',
28-
strategyCurator: 'strategyCurator@http://localhost:3017/remoteEntry.js',
40+
strategyCurator: `strategyCurator@${STRATEGY_CURATOR_REMOTE}`,
2941
affiliationRatingResolver: 'affiliationRatingResolver@http://localhost:3012/remoteEntry.js',
3042
},
3143
// No `shared` block — sharing Svelte 5's reactive runtime and a

shell/src/App.svelte

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,19 @@
2727
import { layout, type LayoutMode } from './layout.svelte';
2828
import { activeFlow, FLOWS } from './flows.svelte';
2929
30+
// workspace-service's WS endpoint — every app that connects to it directly
31+
// (this shell, plus the strategy-curator and chat remotes independently)
32+
// reads the same PUBLIC_WS_URL, defaulting to localhost for dev. Rsbuild
33+
// inlines PUBLIC_-prefixed env vars into import.meta.env at build time
34+
// (same convention DidiBadge.svelte's PUBLIC_ID_BASE already uses).
35+
// Deriving the plain-HTTP base from it (ws→http, wss→https) rather than a
36+
// second env var — Step 7's /config check needs the same origin, not the
37+
// WS scheme.
38+
const WS_URL =
39+
((import.meta as { env?: Record<string, string> }).env?.PUBLIC_WS_URL as string | undefined) ??
40+
'ws://localhost:3001/ws';
41+
const WS_HTTP_BASE = WS_URL.replace(/^ws/, 'http').replace(/\/ws$/, '');
42+
3043
// Chat rail visibility — persistent left-side companion to the focused
3144
// Window. Toggleable from the header; persisted to localStorage so a
3245
// user's preference survives reloads. Per the four-roles model in
@@ -267,14 +280,13 @@
267280
// second call is a no-op.
268281
onMount(() => {
269282
const TOKEN_KEY = 'augment_it_session_token';
270-
const WS_HTTP_BASE = 'http://localhost:3001';
271283
// Fire BEFORE/alongside connect(), not after — an anonymous WS upgrade
272284
// against a DIDI_AUTH=required instance is rejected (4401) before any
273285
// session frame ships, so this plain GET is the only way an
274286
// unauthenticated visitor's shell learns the wall should render.
275287
void workspace.fetchDidiAuthMode(WS_HTTP_BASE);
276288
workspace.connect({
277-
url: 'ws://localhost:3001/ws',
289+
url: WS_URL,
278290
getToken: () => localStorage.getItem(TOKEN_KEY),
279291
saveToken: (t) => localStorage.setItem(TOKEN_KEY, t),
280292
onStatus: () => {

0 commit comments

Comments
 (0)