Code reference detail
app.svelte.ts
packages/extension/webviews/activity-bar/state/app.svelte.ts
| Idea | Status | Tags | Summary | Katz |
|---|---|---|---|---|
| scope | TypeScript package standards for `packages/extension` ( npm `reqlan-extension` ), especially UI state. Complements [development_core.rust_mindset] and [extension_architecture.state_machine_mindset]. Webview inventory: [webview_doc.webview]. Package role: [core_architecture.extension_package]. | 0.040 | ||
| ui_state_management | done | Extension UI state is explicit, typed, and layered — not a single global store shared across host and webview. Choose the layer by lifetime and owner: - Host session / durable prefs live in the extension process ( `ExtensionContext`, plain modules ). - Webview view-models live in Svelte 5 runes ( `$state` / `$derived` / `$effect` ). - Cross-boundary traffic uses typed `postMessage` contracts only. Prefer small state machines ( named phases, request ids, clear transitions ) over ad-hoc flags. Related: [webview_app_state], [persistence_tiers], [zustand_boundary], [host_webview_ownership]. | 0.080 | |
| webview_app_state | done | Complex webviews ( activity bar, Ideas Summary ) own a single `AppState` class in `state/app.svelte.ts`. Fields that drive UI are Svelte 5 `$state` properties on that class; side effects and host I / O are methods. Export one module singleton ( `export const app = new AppState()` ) and inject it via [svelte_app_context]. Do not use `svelte/store` writable / readable stores for new UI, and do not put zustand inside webview code ( [zustand_boundary] ). Simple panels ( export form, onboarding, index diagnostics ) may keep `$state` on the root `App.svelte` instead of a separate AppState module when the surface is a single form / flow. Related: ["../extension/workspace-summary/ideas_summary/webview.rq".table_column_filters] `$derived` binding rule; ["../extension/workspace-summary/ideas_summary/graphical_graph.rq".graph_ui_persistence]. | 0.070 | |
| zustand_boundary | done | [extension_architecture.state_machine_mindset] still applies: design UI and host flows as state machines. Zustand is no longer used anywhere: the index lifecycle FSM ( `opening` / `syncing` / `ready` / `error` ), counts, file issues, and the document-update ring now live in Rust `WorkspaceIndexRuntime` and are read over napi via `statusSnapshot()` ( ["../core_analysis/rust_port.rq".native_bridge] ); durable diagnostics persist in `index-diagnostics.sqlite`. TypeScript keeps no parallel copy of that state. Do not reintroduce zustand ( or Redux-like globals ) in `packages/extension/webviews/**` or the analytical package. Extension-host TypeScript may keep plain mutable session modules when the surface is small and message-pushed; owned lifecycle / state machines belong in the Rust runtime. | 0.069 | |
| extension_startup_reliability | done | Reqlan startup must make the activity-bar shell and contributed commands available before optional indexing, parser construction, database initialization, or language-client startup can monopolize the extension host. The implementation contract is [first_paint_contract], [webview_claim_race], [deferred_startup_sequence], [lazy_runtime_dependencies], and [development_bundle_freshness]. Operational diagnosis follows [startup_diagnostics]. [activation.activation_sequence] [activitybar.loading_state] [indexer.nonblocking_index] [build.extension_bundle] | 0.046 | |
| first_paint_contract | done | The platform spinner ends only after VS Code loads the host module, calls `activate`, the provider registers, and `resolveWebviewView` assigns HTML. `resolveWebviewView` is async: it binds the view, yields one turn so the overlay can be claimed, then assigns the lightweight HTML / Svelte shell ( retry once on invalid-state ). It does **not** `postMessage` in that method. The webview installs its host message listener, mounts, waits for its first animation frame, then posts the one-shot `ready` signal from a queued task. Host messages start only after that handshake. Index discovery / sync waits for the same signal so synchronous parser or database setup cannot race the first visible frame. Windows overlay restore can dispose and re-resolve the sidebar; the provider rebinds and waits for a new `ready`. [activation.first_paint_startup] [webview_claim_race] ["../../../packages/extension/webviews/activity-bar/App.svelte"] ["../../../packages/extension/webviews/activity-bar/state/app.svelte.ts"] ["../../../packages/extension/src/extension/startup-gate.ts"] ["../../../packages/extension/src/shared/safe-webview-post.ts"] | 0.058 | |
| search_add_to_chat | done | From each [search_pane] hit, a split **Add to chat** control: - Primary button: place compact `#requirement` context into the **current** chat input without submitting. - ▾ menu ( visible secondary affordance ): **Add to current chat** or **Add to new chat** ( new session, then seed the same payload ). Tooltips name both behaviours; secondary is not right-click-only. Same payload shape as ["../../agent/features-ai.rq".add_to_chat] ( idea name, path: line, summary ) via [open_chat]. Host: [open_chat] with `{ query, isPartialQuery: true, target: 'current' | 'new' }`. Cursor note: do not use `workbench.action.chat.open` for **current** ( it always opens a new tab ); see ["../../agent/features-ai.rq".add_to_chat] / [open_chat]. Clipboard fallback when no chat command is available ( same spirit as ["../../agent/features-ai.rq".add_to_chat] ). Wire: [AddToChatButton] / [SearchPane] → [app_state] `addToChat(hit, target)` → [activity_bar_messages] → [activity_bar_webview] → [open_chat]. | 0.071 | |
| search_pane | done | Workspace idea search in the activity bar — find rq ideas by name, summary, or tags without leaving the sidebar. Complements the modal from [commands.search_code_actions]; this pane stays open for repeated lookups and inserts. Implemented by [SearchPane] under [CollapsiblePane]; host wire in [activity_bar_webview] / [activity_bar_messages] / [app_state]. [search_pane_query] [search_pane_layout] [search_pane_results] [search_pane_open_live_file] [search_pane_load_more] [search_pane_file_hits] [search_pane_insert_reference] [search_add_to_chat] [search_pane_advanced] [search_pane_empty_query] [search_pane_scoped_status] [search_progress] [search_pane_seed] [search_pane_match_highlighting] | 0.176 | |
| search_pane_advanced | done | [search_pane] header link **Advanced** opens [ideas_summary_doc.ideas_list] with the current query prefilled. | 0.063 | |
| search_pane_empty_query | done | Empty query in [search_pane]: prompt to type ideas or files ( do not dump the full catalog into the pane ). | 0.063 | |
| search_pane_file_hits | done | [search_pane] mixes [core_search.file_search] hits ( kind `file` ) into the ranked list with ideas. Click opens the file at line 0. File hits do not offer Insert ref or Pin ( those are idea actions ). Empty-state and placeholder copy mention files. | 0.115 | |
| search_pane_load_more | done | When ranked hits exceed the visible page, [search_pane] shows an exceeded-count label ( `40+ matches`, or `{n}+ matches` after further pages ) instead of a full total, and a **Show more** control at the bottom of the list that fetches the next page and appends. A new query resets to the first page. Uses [core_search.fuzzy_search_pages] ( `offset` + `truncated` ). | 0.095 | |
| search_pane_match_highlighting | done | The [search_pane_results] list highlights the parts of name, path, and summary that matched the query via [SearchHighlight]. Resilient to [core_search.fuzzy_search] / [core_search.fuzzy_search_whitespace]: contiguous and separator-insensitive spans, token prefixes / part matches, reordered words, and character-subsequence ( fuzzy / acronym ) marks on short fields such as the idea name — not scattered letters in long summaries. | 0.063 | |
| search_pane_query | done | [search_pane] search input posts a debounced host query. Ranking uses [core_search.fuzzy_search] in the native search module ( `NativeWorkspaceIndex.fuzzySearch` ); separator-insensitive `_` / `-` / `...` / whitespace. File-name hits: [search_pane_file_hits] / [core_search.file_search]. Pages: [search_pane_load_more] / [core_search.fuzzy_search_pages]. Highlighting stays in the TS `./fuzzy-search` export. | 0.063 | |
| search_pane_scoped_status | done | [search_pane] soft-waits when the index is not ready; scoped errors stay in the pane. Loading UX: [search_progress]. | 0.063 | |
| search_pane_seed | done | Host may seed [search_pane] via `focusIdeaSearch` ( query + optional pathFilter ) from the wildcard-matches webview **Open in Search** action ( ["../../../language/imports.rq".wildcard_references_webview] ). Path filter is a hard AND after ranking ( ["../../../language/imports.rq".idea_path_filter] ). | 0.090 | |
| search_progress | done | Activity-bar search ranks in the native [core_search.fuzzy_search] module ( rusqlite read + score in-process ). The host must not hydrate a JS idea catalog or worker before scoring — return only the capped hit list. A static " Searching … " / " Loading … " label must not be the only signal: the pane should show **live progress** so a slow wait reads as working, not hung. - Host posts progress for the in-flight search request while native scoring runs ( `Scoring ideas…` ). - [SearchPane] displays the phase label with a continuous activity affordance ( spinner / indeterminate bar ) and elapsed time while loading, for both the empty initial wait and the " Updating … " refresh path. - Stale progress from superseded queries must not overwrite a newer request; clear progress when results or a scoped error arrive. | 0.080 | |
| todo_pane | done | Workspace todo list in the activity bar — ideas that carry the `@todo` special attribute ( [ai_support.special_attributes] ), not ideas whose `@status` happens to be `todo`. Complements the planned Overview todos rollup in [ideas_summary_doc.overview_page]; this pane stays open for quick triage beside the editor. Layout matches [search_panel.search_pane_layout]: flat list in the pane body, not a nested boxed subsection. - List ideas in the active base where the `todo` attribute is present ( bare `@todo` / flag, or `@todo` with a note ). - Each row: idea name, source path, and the todo note when present ( omit empty / bare-true values ). - Click opens the idea in the editor ( same navigation as [search_panel.search_pane_results] ). - Results fill the pane body ( 100 % width ) and scroll inside the pane; do not nest a second capped NestedSection scroll. - List capped ( default ~ 40 ) with a “ showing N of M ” meta line when truncated; do not dump unbounded index results into the pane. - Soft-wait when the index is not ready; scoped errors stay in the pane. - Pane header **Refresh** reloads the list; also reload on index health / sync completion for the active base. - Optional affordance to create a stub via [commands.pallete_function_create_todo] when that command ships — do not block the list on it. Host query + wire: [activity_bar_webview] / [activity_bar_data] / [activity_bar_messages] / [app_state]; store query [sqlite_store]. Implemented by [TodoPane] under [CollapsiblePane]; same scroll / fill pattern as [SearchPane]. | 0.046 | |
| workspace_base_picker | done | Bases in the Workspace pane are chosen via a **searchable dropdown**, not a stacked list of base rows. - Closed: shows the active base label ( and compact ready / issue hint when useful ). - Open: type-to-filter over discovered bases by label and path; selecting a match **pins** the active base ( [bases.active_base_switch] ) — a pointer swap, not a sync. - Options surface label / path plus ready state and idea / edge / issue counts so the user can distinguish bases before committing. - Single-base workspaces still use the same control ( no special flat list ); empty discovery stays on the Create Base CTA. - Prefer VS Code dropdown tokens for chrome; keep the control compact so health / stats / actions remain the focus of the pane. Switch UX: - Selecting a base posts immediately; the picker may flash **Switching … ** until `indexHealth` confirms `activeBaseId` ( should be near-instant ). - Never kick soft / hard sync on switch; readiness / progress for a not-yet-ready base is whatever the index already reports. - Editor-follow must not overwrite a user-selected base on the same refresh that applies the selection. Implemented by [BasePicker] in [WorkspacePane]; filter helpers in [filter_bases]. | 0.072 | |
| workspace_pane | Multi-base index health, errors, and activity — without duplicating the full Index tab in [ideas_summary_doc.index_panel]. - [workspace_base_picker]: choose the active base; do not render a full always-visible base list. - For the selected base: state badge, sync progress ( processed / total + current file ), idea / edge counts, global and per-file errors, recent activity. - Clickable file issue list opens the source location in the editor. - Refresh / cancel in-flight sync / clear & rebuild for the selected base ( or all ); " Open index tab " hands off to [ideas_summary_panel] with that base selected. - When no bases exist: empty state with Create Base CTA ( [bases.create_base_onboarding] ). Non-blocking sync UX: ["../../../indexer/indexer.rq".nonblocking_index]. Implemented by [WorkspacePane]. | 0.146 | ||
| error_status_bar | done | When the activity bar status line ( ["../../../packages/extension/webviews/activity-bar/components/HeaderBar.svelte"] ) or Ideas Summary status chrome ( ["../../../packages/extension/webviews/ideas-summary/components/StatusBar.svelte"] ) is in an error state ( `statusError` ), surface the error **prominently** — do not mute it or bury it behind healthy index counts. - Lead the status text with the error summary or issue count; healthy idea / reference counts may follow as secondary context. - Use error foreground, error validation background, a distinct error label, and `role="alert"` so the message is visually and accessibly distinct from idle status. - Bootstrap error banner ( ["../../../packages/extension/webviews/activity-bar/components/BootstrapStatus.svelte"] in [loading_state] ) must not apply muted styling to the error detail. Soft-waits for an unready index stay non-error per [loading_state] / [workspace_panel.workspace_loading]; this idea covers true error states only. Shared copy helper: ["../../../packages/extension/webviews/ideas-summary/lib/index-status-text.ts"]. | 0.075 | |
| loading_state | done | After the activity bar shell mounts, the header may appear before pane data. Cover every sequencing beat with an explicit loading or error affordance — never a blank content area: 1. HTML shell ( before Svelte boots ): inline waiting markup in [get_activity_bar_html]. 2. Connecting: header visible; a post-first-frame `ready` handshake starts the index and requests the first host state. 3. Waiting for index: [workspace_panel.workspace_loading]. 4. Ready panes: [current_context_scope.context_panes_loading], [minigraph.minigraph_loading], and [search_panel.search_progress]. Index sync progress belongs in [workspace_panel.workspace_pane]; graph slice waits stay in [miniature_graph_pane]; idea-search phases stay in [search_panel.search_pane] — not a second global overlay. Host posts index health on `ready` and on subsequent status changes; soft-waits when the index is not ready instead of erroring the whole bar. Pane shells stay mounted through these phases per [activity_bar_styling]; only content / bootstrap banner reflect invalid or loading states. True error states ( status line + bootstrap banner ) must show the error prominently per [error_status_bar]. | 0.063 | |
| local_graph_view | The activity bar provides a local graph view scoped to the current file or selected idea. The local graph should show direct and optionally indirect references with a configurable depth. | 0.055 | ||
| import_keywords | The keywords import, from, and as are reserved for import statements. Import keywords may also appear as ordinary words in idea body text when not at statement start. | 0.047 | ||
| wildcard_references_webview | done | A click on the command document link for a [wildcard_references] target runs `reqlan.openWildcardReference` and opens a dedicated **wildcard matches** webview ( beside the editor ) that lists: - Stats: matching idea count, distinct file count, and @ status breakdown - Requirements: each matching idea with name, status, path, and summary ( click opens the idea ) - Files: each matching file with idea count ( click opens the file ) Secondary action **Open in Search** seeds the activity-bar ["../extension/local-context/activitybar-panels/search.rq".search_pane_seed] via `focusIdeaSearch` with: - `query`: idea pattern with glob meta softened for fuzzy search ( `import_*` → `import` ) - `pathFilter`: the path glob as a hard AND filter ( [idea_path_filter] ) Payload builder: `buildWildcardMatchesPayload` filters the index catalog by idea glob + path filter. Protocol for the matches panel is inline host ↔ webview ( `init` / `openIdea` / `openFile` / `openSearch` ). The document-link target is the command URI. Go-to-definition does not open the panel. Highlighting of the source reference must stay link-styled — see ["../extension/language/syntax/features-syntax.rq".syntax_highlighting] and ["../extension/language/syntax/features-syntax-highlighting.rq".wildcard_reference_highlighting]. | 0.199 |
Reference labels
"../../../../packages/extension/webviews/activity-bar/state/app.svelte.ts", "../../../packages/extension/webviews/activity-bar/state/app.svelte.ts", "../../packages/extension/webviews/activity-bar/state/app.svelte.ts", ../../../../packages/extension/webviews/activity-bar/state/app.svelte.ts, ../../../packages/extension/webviews/activity-bar/state/app.svelte.ts, ../../packages/extension/webviews/activity-bar/state/app.svelte.ts