Skip to content

Commit 5b54292

Browse files
improvement(setup): land the wizard handoff on signup
A freshly provisioned deployment has no accounts and / renders the marketing landing page, so the bare origin left operators hunting for the CTA. Single-source the URLs and point every open-Sim handoff at /signup across all three modes.
1 parent 4d115b3 commit 5b54292

6 files changed

Lines changed: 26 additions & 18 deletions

File tree

scripts/setup/lifecycle.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import { forwardCommands, isLocalKubeContext } from './modes/k8s.ts'
88
import { httpHealth } from './probes.ts'
99
import * as p from './prompter.ts'
1010
import { glyph, theme } from './theme.ts'
11+
import { APP_SIGNUP_URL, APP_URL } from './urls.ts'
1112

12-
const APP_URL = 'http://localhost:3000'
1313
const REALTIME_HEALTH = 'http://localhost:3002/health'
1414
const POSTGRES_VOLUME = 'sim-postgres-data'
1515
const COMPOSE_FILES = ['docker-compose.prod.yml', 'docker-compose.local.yml'] as const
@@ -258,7 +258,7 @@ function start(install: Install): void {
258258
dockerRun(composeArgs(install, 'up', '-d'), 'docker compose up failed', install.dir)
259259
spin.stop('Containers up')
260260
p.note(
261-
[`open ${APP_URL}`, 'follow logs: sim logs', 'stop: sim stop'].join('\n'),
261+
[`open ${APP_SIGNUP_URL}`, 'follow logs: sim logs', 'stop: sim stop'].join('\n'),
262262
'Running'
263263
)
264264
return
@@ -312,7 +312,7 @@ function restart(install: Install): void {
312312
spin.start('Restarting containers…')
313313
dockerRun(composeArgs(install, 'restart'), 'docker compose restart failed', install.dir)
314314
spin.stop('Containers restarted')
315-
p.note(`open ${APP_URL}`, 'Running')
315+
p.note(`open ${APP_SIGNUP_URL}`, 'Running')
316316
return
317317
}
318318
if (install.kind === 'dev') {

scripts/setup/modes/compose.ts

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import {
1919
promptUnlocks,
2020
} from '../steps.ts'
2121
import { glyph, theme } from '../theme.ts'
22+
import { APP_SIGNUP_URL, APP_URL } from '../urls.ts'
2223

2324
const REQUIRED_PORTS = [3000, 3002] as const
2425

@@ -118,7 +119,7 @@ export async function runComposeMode(detection: Detection, quick: boolean): Prom
118119
if (!quick) {
119120
const storage = await promptStorage(root.vars, true)
120121
if (storage) Object.assign(values, storage)
121-
const appUrl = root.vars.get('NEXT_PUBLIC_APP_URL') ?? 'http://localhost:3000'
122+
const appUrl = root.vars.get('NEXT_PUBLIC_APP_URL') ?? APP_URL
122123
Object.assign(values, await promptSignInProviders(root.vars, appUrl))
123124
Object.assign(values, await promptEmail(root.vars))
124125
const security = await promptSecurity(root.vars)
@@ -152,11 +153,7 @@ export async function runComposeMode(detection: Detection, quick: boolean): Prom
152153

153154
const spin = p.spinner()
154155
spin.start('Waiting for Sim to come up (first run pulls images and migrates)…')
155-
const appHealthy = await waitFor(
156-
() => httpHealth('http://localhost:3000/api/health'),
157-
300_000,
158-
3000
159-
)
156+
const appHealthy = await waitFor(() => httpHealth(`${APP_URL}/api/health`), 300_000, 3000)
160157
const realtimeHealthy =
161158
appHealthy && (await waitFor(() => httpHealth('http://localhost:3002/health'), 60_000, 2000))
162159
if (!appHealthy || !realtimeHealthy) {
@@ -165,7 +162,7 @@ export async function runComposeMode(detection: Detection, quick: boolean): Prom
165162
`${!appHealthy ? 'the app (:3000)' : 'realtime (:3002)'} never answered its health check.`,
166163
[
167164
`follow the logs: ${theme.command(`docker compose -f ${composeFile} logs -f`)}`,
168-
'first boots on slow disks can exceed the wait — if containers are still starting, just wait and open http://localhost:3000',
165+
`first boots on slow disks can exceed the wait — if containers are still starting, just wait and open ${APP_SIGNUP_URL}`,
169166
]
170167
)
171168
}

scripts/setup/modes/dev.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@ import {
2121
promptUnlocks,
2222
} from '../steps.ts'
2323
import { glyph, theme } from '../theme.ts'
24-
25-
const APP_URL = 'http://localhost:3000'
24+
import { APP_URL } from '../urls.ts'
2625

2726
/**
2827
* A migrate failure on a never-migrated database means setup failed — abort.

scripts/setup/modes/k8s.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ import { waitFor } from '../probes.ts'
88
import * as p from '../prompter.ts'
99
import { chatFlagValues, mothershipOverride, promptCopilotKey } from '../steps.ts'
1010
import { glyph, theme } from '../theme.ts'
11+
import { APP_SIGNUP_URL, APP_URL } from '../urls.ts'
1112

12-
const APP_URL = 'http://localhost:3000'
1313
const RELEASE = 'sim-dev'
1414
const NAMESPACE = 'sim-dev'
1515
const LOCAL_CONTEXT_PREFIXES = ['kind-', 'docker-desktop', 'minikube', 'orbstack']
@@ -416,7 +416,7 @@ export async function runK8sMode(detection: Detection): Promise<void> {
416416

417417
p.note(
418418
[
419-
`open ${APP_URL} (needs both forwards below)`,
419+
`open ${APP_SIGNUP_URL} (needs both forwards below)`,
420420
`pods: kubectl --context ${shq(context)} -n ${NAMESPACE} get pods`,
421421
`app logs: kubectl --context ${shq(context)} -n ${NAMESPACE} logs deploy/${RELEASE}-app --tail 50`,
422422
// Both, always: the app alone loads but the editor's socket has nothing to
@@ -454,7 +454,7 @@ export function forwardCommands(context: string): string[] {
454454
*/
455455
async function offerPortForward(context: string): Promise<void> {
456456
const forward = await p.confirm({
457-
message: `Port-forward now so you can open ${APP_URL}?`,
457+
message: `Port-forward now so you can open ${APP_SIGNUP_URL}?`,
458458
initialValue: true,
459459
})
460460
if (!forward) {

scripts/setup/urls.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/** Origin the wizard provisions Sim on locally, and the base for its env twins. */
2+
export const APP_URL = 'http://localhost:3000'
3+
4+
/**
5+
* Where the wizard tells an operator to open Sim.
6+
*
7+
* A freshly provisioned deployment has no accounts yet and `/` renders the
8+
* marketing landing page, so handing over the bare origin leaves the operator
9+
* hunting for a CTA before they can create the first account. Deep-linking to
10+
* signup lands them on the one thing they can actually do.
11+
*/
12+
export const APP_SIGNUP_URL = `${APP_URL}/signup`

scripts/setup/wizard.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { runK8sMode } from './modes/k8s.ts'
99
import { ensurePortsFree } from './ports.ts'
1010
import * as p from './prompter.ts'
1111
import { glyph, theme } from './theme.ts'
12+
import { APP_SIGNUP_URL } from './urls.ts'
1213

1314
export type WizardMode = 'compose' | 'dev' | 'k8s'
1415

@@ -159,10 +160,9 @@ export async function runWizard(flags: WizardFlags): Promise<void> {
159160

160161
if (mode !== 'k8s' && !startDevNow) await finalVerify()
161162

162-
const url = 'http://localhost:3000'
163163
p.note(
164164
[
165-
mode === 'k8s' ? `port-forward, then open ${url}` : `open ${url}`,
165+
mode === 'k8s' ? `port-forward, then open ${APP_SIGNUP_URL}` : `open ${APP_SIGNUP_URL}`,
166166
'manage it: bun run sim start · stop · status · logs',
167167
'check your setup: bun run sim doctor',
168168
mode === 'dev' && !startDevNow ? `start Sim: bun run ${devScript}` : null,
@@ -175,7 +175,7 @@ export async function runWizard(flags: WizardFlags): Promise<void> {
175175
p.outro(theme.accent('Sim is ready.'))
176176

177177
if (mode === 'compose' && process.platform === 'darwin') {
178-
spawnSync('open', [url], { stdio: 'ignore' })
178+
spawnSync('open', [APP_SIGNUP_URL], { stdio: 'ignore' })
179179
}
180180
if (startDevNow) {
181181
// dev:full binds 3000 (app) and 3002 (realtime) — resolve any conflict

0 commit comments

Comments
 (0)