docs(260729-je5): pre-dispatch plan for connected-nodes margin + companion intro skip
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
3a59953c87
commit
b8243000e9
@ -0,0 +1,242 @@
|
||||
---
|
||||
phase: quick-260729-je5
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- neode-ui/src/views/web5/Web5ConnectedNodes.vue
|
||||
- neode-ui/src/App.vue
|
||||
- neode-ui/src/views/RootRedirect.vue
|
||||
autonomous: true
|
||||
requirements: [QUICK-JE5-01, QUICK-JE5-02]
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- "Connected-nodes card (dashboard Web5 view): the visible nodes list grows/shrinks to fill the card so the gap above the Find Nodes / Refresh buttons is a constant pt-4, regardless of how tall the sibling Node Visibility card makes the xl 2-col grid row (QUICK-JE5-01)"
|
||||
- "Below xl (single-column/mobile) the list keeps its current max-h-72 cap — no visual/sizing change (QUICK-JE5-01)"
|
||||
- "Demo build opened inside the Android companion WebView shows NO typing splash and NO /onboarding/intro — it lands on /login as if the intro was already seen (QUICK-JE5-02)"
|
||||
- "Browser/PWA demo intro behavior is byte-identical to today (replays on every fresh root boot); the skip path writes NOTHING to localStorage (QUICK-JE5-02)"
|
||||
- "Non-demo builds are a complete no-op for both changes' runtime behavior (QUICK-JE5-02)"
|
||||
- "All existing unit tests stay green (697) and npm run build succeeds with the new strings present in the built bundle"
|
||||
artifacts:
|
||||
- "neode-ui/src/views/web5/Web5ConnectedNodes.vue (flex/scroll fix, no design change)"
|
||||
- "neode-ui/src/App.vue (companion+demo intro gate at both IS_DEMO branch sites)"
|
||||
- "neode-ui/src/views/RootRedirect.vue (companion+demo intro gate at both IS_DEMO branch sites)"
|
||||
key_links:
|
||||
- "isCompanionApp() from neode-ui/src/utils/openExternal.ts is the single companion-detection source at all four IS_DEMO intro branch sites (same convention as stores/appLauncher.ts lines 224/329)"
|
||||
- "Web5ConnectedNodes.vue card root is already `flex flex-col`; the fix works entirely inside that column flex (list = flexible middle, footer = non-shrinking bottom)"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Two small, isolated UI fixes in neode-ui (shared by real + demo builds):
|
||||
|
||||
1. **QUICK-JE5-01 — Connected-nodes list flex fix (both builds):** the scrollable nodes
|
||||
list in the dashboard "Connected Nodes" card must always end at a consistent margin
|
||||
above the bottom Find Nodes / Refresh buttons, even when the sibling card
|
||||
(Web5NodeVisibility) stretches the shared grid row. Today the list is hard-capped at
|
||||
`max-h-72` and the footer uses `mt-auto`, so a tall sibling opens a growing dead gap
|
||||
between list and buttons.
|
||||
|
||||
2. **QUICK-JE5-02 — Companion app skips demo intro (demo build only):** when the demo
|
||||
runs inside the Android companion WebView (`window.ArchipelagoNative` bridge
|
||||
injected), skip the typing splash + `/onboarding/intro` entirely and land on /login,
|
||||
without touching any state the browser demo relies on. Desktop/PWA browser demo
|
||||
intro must be completely unaffected — the user resets and relies on it before demos.
|
||||
|
||||
Purpose: fix a visible layout bug on every node dashboard, and stop the companion app
|
||||
from replaying the demo cinematic every time the demo is opened in-app.
|
||||
Output: 2 focused commits on main (frontend only), tests green, verified build.
|
||||
</objective>
|
||||
|
||||
<context>
|
||||
@/home/archipelago/Projects/archy/CLAUDE.md
|
||||
@/home/archipelago/Projects/archy/neode-ui/src/views/web5/Web5ConnectedNodes.vue
|
||||
@/home/archipelago/Projects/archy/neode-ui/src/utils/openExternal.ts
|
||||
@/home/archipelago/Projects/archy/neode-ui/src/composables/useDemoIntro.ts
|
||||
|
||||
Key facts already established (do not re-derive):
|
||||
- The "connected nodes" container is `neode-ui/src/views/web5/Web5ConnectedNodes.vue`.
|
||||
Its card root (line 3) is already `glass-card p-6 ... flex flex-col`. The three tab
|
||||
panes (Trusted ~line 57, Observers ~line 90, Requests ~line 120) each use
|
||||
`class="space-y-2 max-h-72 overflow-y-auto"` with `v-show`, and the button footer
|
||||
(~line 161) is `<div class="mt-auto pt-4 space-y-3">`. The row is
|
||||
`neode-ui/src/views/web5/Web5.vue` line 59: `grid grid-cols-1 xl:grid-cols-2 gap-6`
|
||||
with sibling `Web5NodeVisibility` (grid items stretch to row height by default).
|
||||
- Companion detection already exists: `isCompanionApp()` in
|
||||
`neode-ui/src/utils/openExternal.ts` (true iff the native shell injected
|
||||
`window.ArchipelagoNative` with an `openInApp` function; a plain browser/PWA never
|
||||
has it, and the bridge exists before page scripts run — appLauncher.ts already
|
||||
relies on it synchronously).
|
||||
- The demo intro fires from exactly four IS_DEMO branch sites:
|
||||
- `neode-ui/src/App.vue` ~line 433: `if (IS_DEMO && bootPath === '/') replayRequested = true` (typing splash on every root boot)
|
||||
- `neode-ui/src/App.vue` ~line 588: post-splash `if (IS_DEMO) { router.push('/onboarding/intro'); reveal(); return }`
|
||||
- `neode-ui/src/views/RootRedirect.vue` ~lines 82 and 149: `if (IS_DEMO) { demoRoute() }` → pushes `/onboarding/intro`
|
||||
- `views/web5/__tests__/Web5ConnectedNodes.test.ts` exists but does NOT assert on
|
||||
`max-h-72` / `mt-auto` classes (verified by grep) — class changes should not break it.
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Connected-nodes list fills the card — constant gap above footer buttons (QUICK-JE5-01)</name>
|
||||
<files>neode-ui/src/views/web5/Web5ConnectedNodes.vue</files>
|
||||
<action>
|
||||
Implement the column-flex fix per QUICK-JE5-01, exactly as scoped: flexible
|
||||
scrollable list + non-shrinking footer, replacing the fixed cap as the xl-row
|
||||
sizing mechanism. Concretely:
|
||||
|
||||
1. On EACH of the three v-show tab panes (Trusted, Observers, Requests — the divs
|
||||
currently classed `space-y-2 max-h-72 overflow-y-auto`), change the classes to:
|
||||
`space-y-2 flex-auto min-h-0 overflow-y-auto max-h-72 xl:max-h-none`
|
||||
- `flex-auto` (flex: 1 1 auto) + `min-h-0` is the standard fix: the visible pane
|
||||
becomes the flexible middle of the column-flex card, growing to absorb any
|
||||
extra height the grid row imposes and shrinking (with internal scroll) when
|
||||
constrained — so the space between list end and footer is always exactly the
|
||||
footer's own pt-4.
|
||||
- Keep `max-h-72` ONLY below xl (`xl:max-h-none` lifts it): below xl the grid is
|
||||
single-column (`grid-cols-1`), no sibling stretches the card, and the current
|
||||
mobile sizing must not change (constraint: no visual design change).
|
||||
- Hidden panes are `v-show` (display:none) so applying flex classes to all three
|
||||
is safe — only the visible one participates in layout.
|
||||
2. On the footer div (`mt-auto pt-4 space-y-3`), add `shrink-0` so the buttons can
|
||||
never be compressed by a long list. Keep `mt-auto` (harmless once the list is
|
||||
flex-auto — it only matters in the sub-xl capped case, where it preserves today's
|
||||
behavior exactly).
|
||||
3. Touch NOTHING else in the component: no color, spacing, typography, or markup
|
||||
changes. The card root already has `flex flex-col` — do not restructure it.
|
||||
4. Sanity-check the sibling row in `neode-ui/src/views/web5/Web5.vue` line 59 (read
|
||||
only): default grid item stretch is what feeds the card its height — no change
|
||||
needed there.
|
||||
|
||||
This component is shared by real and demo builds, so one fix covers both builds.
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd /home/archipelago/Projects/archy/neode-ui && npx vitest run src/views/web5/__tests__/Web5ConnectedNodes.test.ts</automated>
|
||||
Also: grep the component to confirm no pane retains a bare `max-h-72` without `xl:max-h-none`, and that all three panes have `flex-auto min-h-0`.
|
||||
</verify>
|
||||
<done>
|
||||
All three tab panes are `flex-auto min-h-0 overflow-y-auto max-h-72 xl:max-h-none`;
|
||||
footer has `shrink-0`; component test file passes; no other visual changes.
|
||||
</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Companion WebView + demo build skips the intro entirely (QUICK-JE5-02)</name>
|
||||
<files>neode-ui/src/App.vue, neode-ui/src/views/RootRedirect.vue</files>
|
||||
<action>
|
||||
Gate all four IS_DEMO intro branch sites on NOT-companion, per QUICK-JE5-02. Use the
|
||||
existing `isCompanionApp()` from `@/utils/openExternal` (do NOT invent new
|
||||
detection — this is the same convention appLauncher.ts uses at lines 224/329, and
|
||||
the `window.ArchipelagoNative` bridge is injected by the native shell before page
|
||||
scripts run, so it is safe to call synchronously at boot).
|
||||
|
||||
1. `neode-ui/src/App.vue` (~line 433): change
|
||||
`if (IS_DEMO && bootPath === '/') replayRequested = true`
|
||||
to also require `!isCompanionApp()` — companion never requests the demo
|
||||
splash replay.
|
||||
2. `neode-ui/src/App.vue` (~line 588): gate the post-splash
|
||||
`if (IS_DEMO) { router.push('/onboarding/intro') ... }` block with
|
||||
`!isCompanionApp()`. When companion+demo, prefer routing DIRECTLY to '/login'
|
||||
and `reveal()` (mirroring the "seenOnboarding === true" branch just below)
|
||||
rather than falling through to `checkOnboardingStatus()` — the mock backend
|
||||
reports onboarded and would land on /login anyway, but the direct route avoids
|
||||
the status-check retry ladder and any splash-adjacent behavior. Add a one-line
|
||||
comment: companion in-app demo skips the intro; browser demo unaffected.
|
||||
3. `neode-ui/src/views/RootRedirect.vue` (~lines 82 and 149): gate both
|
||||
`if (IS_DEMO) { demoRoute() }` calls the same way. When IS_DEMO and
|
||||
isCompanionApp(), route to '/login' (behaving exactly as an intro-already-seen
|
||||
demo session) instead of demoRoute(). Import `isCompanionApp` from
|
||||
'@/utils/openExternal' (static import is fine — the module is tiny and already
|
||||
in the main bundle).
|
||||
4. HARD invariants (from the task constraints):
|
||||
- Write NOTHING to localStorage/sessionStorage from any skip path (no
|
||||
`neode_intro_seen`, no `demo_intro_date`, nothing) — the browser demo's
|
||||
manually-reset intro state must be untouched.
|
||||
- Non-demo builds: `IS_DEMO` is false, so every gated branch short-circuits
|
||||
before `isCompanionApp()` matters — verify by inspection that no new code
|
||||
runs outside `IS_DEMO === true` paths (keep `isCompanionApp()` on the RIGHT
|
||||
side of the `&&` / inside the IS_DEMO block).
|
||||
- Browser/PWA demo: `isCompanionApp()` is false (no bridge) — all four sites
|
||||
behave byte-identically to today.
|
||||
5. If an existing unit test covers RootRedirect demo routing, update/extend it; if
|
||||
cheap, add a small test asserting `isCompanianApp`-style bridge detection drives
|
||||
the skip (stub `window.ArchipelagoNative = { openInApp: () => {} }`). Do not
|
||||
build heavy test scaffolding — the 697 existing tests staying green is the gate.
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd /home/archipelago/Projects/archy/neode-ui && npx vitest run</automated>
|
||||
Full suite green (697+ tests). Then grep both edited files to confirm every
|
||||
intro-triggering IS_DEMO branch also checks `isCompanionApp()`.
|
||||
</verify>
|
||||
<done>
|
||||
All four IS_DEMO intro branch sites (App.vue x2, RootRedirect.vue x2) skip the
|
||||
splash/intro and route to /login when `isCompanionApp()` is true; zero storage
|
||||
writes on the skip path; zero behavior change for browser demo and non-demo builds;
|
||||
full unit suite green.
|
||||
</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 3: Build verification + bundle grep + commits</name>
|
||||
<files>neode-ui/ (build only — no new source edits expected)</files>
|
||||
<action>
|
||||
Per CLAUDE.md "Build / verify" and "Commit & push every unit of work":
|
||||
|
||||
1. `cd /home/archipelago/Projects/archy/neode-ui && npm run build` (vue-tsc + vite;
|
||||
outputs to web/dist/neode-ui). Build must succeed with zero type errors.
|
||||
2. Bundle grep (build can silently no-op — always grep the built output):
|
||||
- Fix 1: `grep -rl "xl:max-h-none" /home/archipelago/Projects/archy/web/dist/neode-ui/assets/` must match at least one asset (the new Tailwind class proves the fresh component shipped).
|
||||
- Fix 2: the gate is inside IS_DEMO code, which a non-demo build may fold away, so
|
||||
verify against a scratch demo build:
|
||||
`VITE_DEMO=1 npx vite build --outDir /tmp/claude-1000/-home-archipelago-Projects-archy/3ca40190-d6bb-4f98-9d89-8d2479484065/scratchpad/demo-dist --emptyOutDir`
|
||||
then confirm a JS chunk contains BOTH the `demoRoute` log string and
|
||||
`ArchipelagoNative` (heuristic that the companion gate survived into the demo
|
||||
bundle):
|
||||
`grep -rl "demoRoute" <scratch>/demo-dist/assets/*.js | xargs grep -l "ArchipelagoNative"`
|
||||
Do NOT commit or deploy the scratch demo build — it is verification only.
|
||||
3. Commits (code only — the orchestrator commits .planning docs):
|
||||
- Commit 1: Web5ConnectedNodes.vue flex fix.
|
||||
- Commit 2: App.vue + RootRedirect.vue companion demo-intro skip (plus any test
|
||||
file touched in Task 2).
|
||||
- Stage EXPLICITLY by path (`git add neode-ui/src/...`), never `git add -A`.
|
||||
- NEVER stage anything under `indeedhub/` (git submodule) — check
|
||||
`git status --porcelain` before each commit and confirm no `indeedhub` entries
|
||||
are staged.
|
||||
- Do not commit `web/dist/` build output unless the repo already tracks it AND
|
||||
it changed as a direct product of these fixes (check `git status` — if dist is
|
||||
untracked/ignored, leave it alone).
|
||||
- Messages end with the `Co-Authored-By: Claude ...` trailer per CLAUDE.md.
|
||||
</action>
|
||||
<verify>
|
||||
<automated>cd /home/archipelago/Projects/archy/neode-ui && npm run build && grep -rl "xl:max-h-none" ../web/dist/neode-ui/assets/ | head -1</automated>
|
||||
Plus the demo-build co-occurrence grep from step 2, and `git log --oneline -2`
|
||||
showing the two focused commits with no indeedhub/ paths in either
|
||||
(`git show --stat` per commit).
|
||||
</verify>
|
||||
<done>
|
||||
`npm run build` green; both bundle greps confirm the new code is in the built
|
||||
output; two focused commits exist, each staged by explicit path, no indeedhub/
|
||||
content, Co-Authored-By trailer present.
|
||||
</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
- Full unit suite: `cd neode-ui && npx vitest run` — all tests green (697 baseline; new tests may raise the count, zero failures).
|
||||
- `npm run build` succeeds; `web/dist/neode-ui` contains `xl:max-h-none`.
|
||||
- Scratch `VITE_DEMO=1` build contains the companion gate (demoRoute + ArchipelagoNative co-occurrence).
|
||||
- Manual spot-check (optional, dev preview :8100 or `npm run dev:mock`): on a wide (xl) window, pad the Node Visibility card content tall and confirm the connected-nodes list expands so the buttons keep an unchanged pt-4 gap; on a narrow window the card looks exactly as before.
|
||||
- Grep confirms no localStorage writes were added in App.vue/RootRedirect.vue skip paths.
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- QUICK-JE5-01: nodes list ends at a constant pt-4 above the bottom buttons at any xl row height; sub-xl sizing unchanged; no visual design changes.
|
||||
- QUICK-JE5-02: companion WebView + demo lands on /login with no splash and no /onboarding/intro; browser/PWA demo and non-demo builds byte-identical in behavior; no intro-state storage writes from the skip path.
|
||||
- Tests green, build verified via bundle grep, two clean path-staged commits, nothing from indeedhub/ touched.
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
On completion create `.planning/quick/260729-je5-ui-fixes-connected-nodes-scrollable-list/260729-je5-SUMMARY.md` (committed by the orchestrator, not the executor).
|
||||
</output>
|
||||
Loading…
x
Reference in New Issue
Block a user