diff --git a/CHANGELOG.md b/CHANGELOG.md index 905de92a2..6f319ba18 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -86,6 +86,11 @@ writing `#hud-ais-vessel`; the application passes `src/hudReadouts.js`, which IntelHUD follows (samehkhamis). +- `initFirstRunExperience` (via `./application/chrome`) no longer writes the + launcher's classes, attributes or text, or removes the card: it presents + them to the welcome view's `gev-first-run` store (its new `store` option) + and connects the controls the view's buttons call (samehkhamis). + ## [0.3.0] — 2026-10-27 — Street Level, On Your Phone, in Your Language - Show a Street Level view facing 359.5° or more as 0°. The viewer caption diff --git a/docs/VUE-MIGRATION.md b/docs/VUE-MIGRATION.md index 8965938f1..734801db2 100644 --- a/docs/VUE-MIGRATION.md +++ b/docs/VUE-MIGRATION.md @@ -200,7 +200,13 @@ a feature supplying only its accent. readouts, the typing summary, the REC blink, visibility, layout variant and style colors; the vessel layer presents the selected vessel's readout through `src/hudReadouts.js` instead of writing into the HUD), - then + the first-run mission launcher (the welcome view renders the card's + visibility, busy state, status line, copy and scroll fade from the + `gev-first-run` store that `initFirstRunExperience` publishes to, and its + choices, DISMISS and "Don't show this again" call the launcher's + controls; a refused save hands the tick back to the view to revert. The + launcher still reads the rendered card for its hit test, keyboard trap, + focus and overflow measurement), then Cockpit (in progress: `CockpitBriefing` renders the briefing card's pages, cycle toggle, regional news and local conditions, and `CockpitContext` the Contact card's scope, navigation, counts, nearest diff --git a/scripts/format-scope.json b/scripts/format-scope.json index 501c50540..927a58c41 100644 --- a/scripts/format-scope.json +++ b/scripts/format-scope.json @@ -1157,5 +1157,8 @@ "src/hudReadouts.js", "src/ui/stores/hud.js", "src/ui/views/intelHudView.test.mjs", - "src/testSupport/hudReadouts.mjs" + "src/testSupport/hudReadouts.mjs", + "src/ui/stores/firstRun.js", + "src/firstRunLauncherView.test.mjs", + "src/firstRunCopy.js" ] diff --git a/scripts/package-boundaries.json b/scripts/package-boundaries.json index e69cfaa6b..bf6824c17 100644 --- a/scripts/package-boundaries.json +++ b/scripts/package-boundaries.json @@ -117,7 +117,9 @@ "src/ui/stores/awarenessDirection.js", "src/ui/views/panels/AwarenessDirection.vue", "src/ui/stores/hud.js", - "src/ui/views/IntelHudView.vue" + "src/ui/views/IntelHudView.vue", + "src/ui/stores/firstRun.js", + "src/firstRunCopy.js" ], "external": ["vue", "pinia"] }, @@ -3045,7 +3047,9 @@ "src/ui/stores/worldOverlayActions.js", "src/ui/stores/awarenessDirection.js", "src/hudReadouts.js", - "src/ui/stores/hud.js" + "src/ui/stores/hud.js", + "src/ui/stores/firstRun.js", + "src/firstRunCopy.js" ], "external": [ "hls.js", diff --git a/scripts/qa-firstrun-mutations.mjs b/scripts/qa-firstrun-mutations.mjs index 78eb8dfef..b15befc87 100644 --- a/scripts/qa-firstrun-mutations.mjs +++ b/scripts/qa-firstrun-mutations.mjs @@ -28,11 +28,14 @@ const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); const TESTS = [ 'src/firstRunExperience.test.mjs', 'src/standalone/startupChrome.test.mjs', + 'src/firstRunLauncherView.test.mjs', ]; const FILES = { keyboard: path.join(ROOT, 'src', 'ui', 'surfaceKeyboard.js'), module: path.join(ROOT, 'src', 'firstRunExperience.js'), + copy: path.join(ROOT, 'src', 'firstRunCopy.js'), + surfaces: path.join(ROOT, 'src', 'exclusiveSurfaces.js'), html: path.join(ROOT, 'src', 'ui', 'views', 'WelcomeView.vue'), css: path.join(ROOT, 'src', 'ui', 'styles', 'first-run.css'), voiceInstructions: path.join(ROOT, 'server/providers/openai/instructions.js'), @@ -146,7 +149,7 @@ const MUTATIONS = [ { defect: 'cockpit drops off the exclusive list and can stack with the launcher', - file: 'module', + file: 'surfaces', from: "export const EXCLUSIVE_SURFACE_CLASSES = Object.freeze([\n 'cockpit-mode',", to: 'export const EXCLUSIVE_SURFACE_CLASSES = Object.freeze([', }, @@ -219,8 +222,8 @@ const MUTATIONS = [ defect: 'a refused write leaves the box ticked, promising a suppression nobody stored', file: 'module', - from: ' if (setFirstRunSuppressed(wanted, storage)) return;', - to: ' setFirstRunSuppressed(wanted, storage);\n return;', + from: ' if (setFirstRunSuppressed(Boolean(wanted), storage)) return true;', + to: ' setFirstRunSuppressed(Boolean(wanted), storage);\n return true;', }, { defect: 'a missing storage area reports the write as saved', @@ -232,8 +235,8 @@ const MUTATIONS = [ defect: 'the scroll fade promises more list on a card where everything fits', file: 'module', - from: 'choiceList.dataset.scrollable = String(overflows);', - to: "choiceList.dataset.scrollable = 'true'; void overflows;", + from: 'present({ scrollable: String(overflows) });', + to: "present({ scrollable: 'true' }); void overflows;", }, { @@ -274,8 +277,8 @@ const MUTATIONS = [ { defect: 'the tile stops promising the fires it actually turns on', file: 'html', - from: 'Live earthquakes and active fires, from USGS and NASA', - to: 'Live earthquakes worldwide, straight from USGS', + from: " 'Live earthquakes and active fires, from USGS and NASA',", + to: " 'Live earthquakes worldwide, straight from USGS',", }, { defect: 'the owner-authored first-run line is quietly rewritten', @@ -322,9 +325,9 @@ const MUTATIONS = [ { defect: 'the fires/quakes tile name stops being switchable from one constant', - file: 'module', - from: 'return ENVIRONMENTAL_LABELS[choice] || ENVIRONMENTAL_LABELS.ENVIRONMENTAL;', - to: 'return ENVIRONMENTAL_LABELS.ENVIRONMENTAL;', + file: 'copy', + from: 'ENVIRONMENTAL_LABEL_KEYS[choice] || ENVIRONMENTAL_LABEL_KEYS.ENVIRONMENTAL;', + to: 'ENVIRONMENTAL_LABEL_KEYS.ENVIRONMENTAL;', }, // ── Defaults interplay (the ruling this whole integration turns on) ──────── @@ -367,9 +370,9 @@ const MUTATIONS = [ { defect: 'disabling the focused tile drops the keyboard to mid-flight', - file: 'module', - from: " for (const button of buttons)\n button.setAttribute('aria-disabled', String(next));", - to: ' for (const button of buttons) button.disabled = next;', + file: 'html', + from: ':aria-disabled="launcher?.busy ?? undefined" @click="controls?.choose(\'contacts\')"', + to: ':disabled="launcher?.busy === \'true\'" @click="controls?.choose(\'contacts\')"', }, { defect: 'Tab escapes into an app the visitor has not seen yet', @@ -442,19 +445,19 @@ const MUTATIONS = [ { defect: 'a mission tile is dropped from the menu', file: 'html', - from: '