Files
archy/.planning/quick/260729-je5-ui-fixes-connected-nodes-scrollable-list/260729-je5-SUMMARY.md
T
archipelagoandClaude Fable 5 7487aba2c2
Demo images / Build & push demo images (push) Successful in 4m55s
docs(quick-260729-je5,hj1): summaries + state for UI-fixes and media batch
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 14:20:06 -04:00

6.6 KiB

phase, plan, subsystem, tags, requirements, dependency-graph, tech-stack, key-files, decisions, metrics, status
phase plan subsystem tags requirements dependency-graph tech-stack key-files decisions metrics status
quick-260729-je5 01 neode-ui
web5
layout
demo
companion
onboarding-intro
QUICK-JE5-01
QUICK-JE5-02
requires provides affects
Connected-nodes card list flexes to fill xl grid-row height (constant pt-4 gap above footer buttons)
Companion WebView + demo build skips typing splash + /onboarding/intro, lands on /login
neode-ui demo build
companion app demo UX
Web5 dashboard
added patterns
Column-flex scroll pane: flex-auto min-h-0 overflow-y-auto with breakpoint-lifted max-h cap (max-h-72 xl:max-h-none)
isCompanionApp() as the single companion-detection source at IS_DEMO branch sites (same convention as appLauncher.ts)
created modified
neode-ui/src/utils/__tests__/openExternal.test.ts
neode-ui/src/views/web5/Web5ConnectedNodes.vue
neode-ui/src/App.vue
neode-ui/src/views/RootRedirect.vue
RootRedirect skip paths deliberately do NOT call log() — log() writes sessionStorage (archipelago_boot_log) and the skip path must write nothing to storage
Cheap test option chosen: unit test for isCompanionApp() bridge detection (the skip's driving mechanism) instead of heavy RootRedirect mount scaffolding
duration completed tasks tests
~15m 2026-07-29 3 700 passed (697 baseline + 3 new)
complete

Quick Task 260729-je5: Connected-Nodes Scrollable List + Companion Demo Intro Skip Summary

Connected-nodes list now flexes to fill the xl grid-row (constant pt-4 gap above Find Nodes/Refresh) and the Android companion demo skips the intro straight to /login via isCompanionApp() gates at all four IS_DEMO branch sites, with zero storage writes.

Task Commits

Task Name Commit Files
1 Connected-nodes list fills card (QUICK-JE5-01) b80e7c34 Web5ConnectedNodes.vue
2 Companion+demo intro skip (QUICK-JE5-02) d54517cf App.vue, RootRedirect.vue, openExternal.test.ts
3 Build verification + bundle greps — (verification only, no source edits)

What Was Done

QUICK-JE5-01 — Connected-nodes list flex fix (b80e7c34)

  • All three v-show tab panes (Trusted line 57, Observers line 90, Requests line 120) changed from space-y-2 max-h-72 overflow-y-auto to space-y-2 flex-auto min-h-0 overflow-y-auto max-h-72 xl:max-h-none — the visible pane is now the flexible middle of the card's existing column flex, growing to absorb row height from a tall sibling Web5NodeVisibility card and scrolling internally when constrained.
  • Below xl (single-column grid) the max-h-72 cap remains — sub-xl sizing byte-identical.
  • Footer div gets shrink-0 (kept mt-auto) so the buttons can never be compressed.
  • No other markup/design changes; Web5.vue grid row (line 59) untouched as planned.

QUICK-JE5-02 — Companion demo intro skip (d54517cf)

All four IS_DEMO intro branch sites gated on the existing isCompanionApp() from @/utils/openExternal (static import added to both files):

  1. App.vue line 435: if (IS_DEMO && bootPath === '/' && !isCompanionApp()) replayRequested = true — companion never requests the splash replay; with the mock backend reporting onboarded, shouldShowIntroSplash then suppresses the splash.
  2. App.vue post-splash block (~line 592): companion+demo routes directly to /login + reveal() (mirrors the seenOnboarding===true branch), avoiding the status-check retry ladder.
  3. RootRedirect.vue proceedToApp() (~line 87): companion+demo → router.replace('/login') instead of demoRoute().
  4. RootRedirect.vue onMounted server-up branch (~line 160): same gate.

Hard invariants verified:

  • Zero storage writes on any skip path — RootRedirect skip paths intentionally do NOT call log() because it writes sessionStorage.archipelago_boot_log; diff grep for added localStorage|sessionStorage lines matched only a comment.
  • Non-demo builds: isCompanionApp() sits on the right of IS_DEMO && / inside if (IS_DEMO) blocks — never reached when IS_DEMO is false (compile-time false in non-demo builds; demo scratch bundle confirmed dead-code folding of the non-demo path).
  • Browser/PWA demo: no bridge → isCompanionApp() false → all four sites behave byte-identically (intro replays on every fresh root boot).

New test src/utils/__tests__/openExternal.test.ts: 3 cases asserting bridge detection (no bridge → false; bridge with openInApp → true; bridge without callable openInApp → false).

Verification

  • Full unit suite: 700 passed, 0 failed (697 baseline + 3 new).
  • npm run build (vue-tsc + vite) green; web/dist/neode-ui/assets/Web5-CB3C73UV.js contains xl:max-h-none (fix 1 shipped).
  • Scratch VITE_DEMO=1 build (scratchpad only, not committed): the plan's single-chunk co-occurrence grep did not match because Vite splits chunks — demoRoute lives in RootRedirect-*.js while ArchipelagoNative lives in the shared index-*.js/Dashboard-*.js chunks. Verified semantically instead (stronger): RootRedirect chunk contains both gated sites compiled as if(E()){_.replace("/login")...;return}x();return where E is imported from the index chunk whose isCompanionApp implementation checks openInApp=="function" on ArchipelagoNative.
  • web/dist is gitignored — left untouched per plan; no dist output committed.
  • Both commits path-staged, submodule guard run before each, no indeedhub/ paths (git show --stat clean), Co-Authored-By: Claude trailer present.
  • Pre-existing untracked files from other agents (.planning/phases/01-.../01-PATTERNS.md, scripts/resilience/.gitignore-reports.tmp) left alone.

Deviations from Plan

Auto-fixed / adjusted

1. [Verification method] Demo-bundle co-occurrence grep replaced with per-chunk semantic verification

  • Found during: Task 3
  • Issue: The plan's heuristic (grep -rl demoRoute ... | xargs grep -l ArchipelagoNative) assumes both strings land in one JS chunk; Vite's code splitting puts them in different chunks.
  • Fix: Verified the actual gate in the RootRedirect demo chunk (minified if(E()){replace("/login")} at both sites, E = isCompanionApp import) and the openInApp=="function" detection in the index chunk.
  • Files modified: none (verification only).

No other deviations — plan executed as written.

Known Stubs

None.

Self-Check: PASSED

  • FOUND: neode-ui/src/views/web5/Web5ConnectedNodes.vue (3 panes with flex-auto min-h-0 ... xl:max-h-none; footer shrink-0)
  • FOUND: neode-ui/src/utils/tests/openExternal.test.ts
  • FOUND: commit b80e7c34 (Task 1)
  • FOUND: commit d54517cf (Task 2)