LearnNewsExamplesServices
Frontmatter
id12265
titleFix portal timeline import paths after shared move
stateClosed
labels
bugjavascriptairegression
assigneesneo-gpt
createdAtMay 31, 2026, 8:26 PM
updatedAtMay 31, 2026, 8:53 PM
githubUrlhttps://github.com/neomjs/neo/issues/12265
authorneo-gpt
commentsCount0
parentIssue12204
subIssues[]
subIssuesCompleted0
subIssuesTotal0
blockedBy[]
blocking[]
closedAtMay 31, 2026, 8:53 PM

Fix portal timeline import paths after shared move

Closed v13.0.0/archive-v13-0-0-chunk-15 bugjavascriptairegression
neo-gpt
neo-gpt commented on May 31, 2026, 8:26 PM

Context

The operator reported that the portal app is unstable after the first resolved #12204 foundation PRs. The visible failure on /news/tickets is a dynamic-import failure for apps/portal/view/news/tickets/MainContainer.mjs.

This ticket is intentionally narrow: the tickets tab is stuck because the shared timeline view-glue moved under apps/portal/view/content/, but its framework imports still walk up one directory too far.

Duplicate sweep completed before filing:

  • ask_knowledge_base(query='Portal CanvasWrapper TimelineCanvas import path dynamic import tickets tab regression', type='ticket') surfaced older TimelineCanvas regressions, but none for the new shared-content import path break.
  • rg across resources/content/{issues,archive/issues,discussions,archive/discussions} found historical dynamic-import and TimelineCanvas tickets, but no equivalent active ticket for the CanvasWrapper / TimelineCanvas post-move path regression.
  • GitHub issue searches for the exact dynamic-import symptom and Portal.view.content.CanvasWrapper returned no duplicate.

The Problem

Portal.view.news.TabContainer lazy-loads the tickets tab via module: () => import('./tickets/MainContainer.mjs'). Live NL verification shows /news/tickets active but the tab body item remains isLoading: true and no Portal.view.news.tickets.MainContainer component mounts.

A direct ESM import falsifier exposes the underlying dependency break:

Error [ERR_MODULE_NOT_FOUND]: Cannot find module '/Users/Shared/codex/neomjs/src/container/Base.mjs' imported from /Users/Shared/codex/neomjs/neo/apps/portal/view/content/CanvasWrapper.mjs

From apps/portal/view/content/, ../../../../../src/... resolves above the repo root. The correct depth is ../../../../src/....

The Architectural Reality

The #12204 foundation refactor promotes shared timeline view-glue out of apps/portal/view/news/tickets/ and into apps/portal/view/content/.

Current source anchors:

  • apps/portal/view/news/tickets/MainContainer.mjs:1 imports ../../content/CanvasWrapper.mjs.
  • apps/portal/view/content/CanvasWrapper.mjs:1 imports ../../../../../src/container/Base.mjs, which resolves one level too high from its new directory.
  • apps/portal/view/content/TimelineCanvas.mjs:1 has the same depth issue for ../../../../../src/app/SharedCanvas.mjs.
  • The relevant styling surface already moved to resources/scss/src/apps/portal/content/CanvasWrapper.scss; ticket work must keep the shared content SCSS honored and must not silently strand theme-specific portal ticket overrides under resources/scss/theme-neo-{light,dark}/apps/portal/news/tickets/.

The Fix

  • Correct the shared content imports in apps/portal/view/content/CanvasWrapper.mjs and apps/portal/view/content/TimelineCanvas.mjs from five parent traversals to four.
  • Re-run the ESM import-chain falsifier until it reaches the expected runtime-only Neo global boundary instead of ERR_MODULE_NOT_FOUND.
  • Re-verify /news/tickets through Neural Link: the tickets main component must mount and the tab body must leave isLoading.
  • Check the portal SCSS paths touched by the move so the shared CanvasWrapper styling and existing light/dark ticket component overrides remain in the cascade.

Decision Record impact

none

Acceptance Criteria

  • node --input-type=module -e "await import('./apps/portal/view/news/tickets/MainContainer.mjs')" no longer fails with ERR_MODULE_NOT_FOUND for apps/portal/view/content/* imports.
  • Neural Link verification of /news/tickets shows Portal.view.news.tickets.MainContainer mounted under the news tab instead of a permanent loading item.
  • The tickets tab retains its shared canvas wrapper styling path under resources/scss/src/apps/portal/content/CanvasWrapper.scss and does not drop existing light/dark ticket component theme overrides.
  • No route/tab config changes are made unless a new falsifier proves they are required.

Out of Scope

  • Implementing PR or Discussion views from #12204.
  • Chunked lazy-load tree work (#12217-#12219).
  • Reworking the timeline parser, canvas physics, or route defaults.
  • Broad theming redesign beyond preserving the moved/shared style surfaces.

Avoided Traps

  • Do not hide the regression under the broad #12204 epic; this is a narrow import-path break with a concrete falsifier.
  • Do not revert the shared content move from #12206; the move is the right shape, but its relative imports must be updated for the new directory.
  • Do not treat the browser's MainContainer.mjs dynamic-import error as proof that MainContainer.mjs itself is missing; dependency import failure surfaces at the lazy module boundary.

Related

  • Parent epic: #12204
  • Regression source area: #12206
  • Open adjacent portal foundation lane: #12209

Handoff Retrieval Hints

  • portal tickets dynamic import CanvasWrapper TimelineCanvas relative path
  • apps/portal/view/content CanvasWrapper ../../../../../src ERR_MODULE_NOT_FOUND
  • NL /news/tickets isLoading true Portal.view.news.tickets.MainContainer not mounted
tobiu referenced in commit 51ee772 - "fix(portal): restore shared timeline import paths (#12265) (#12266) on May 31, 2026, 8:53 PM
tobiu closed this issue on May 31, 2026, 8:53 PM