Frontend cockpit for the Wendao Studio gateway.
Qianji Studio is not a separate backend product. It is the interactive frontend layer that hydrates VFS, topology, graph, and semantic search data from the Wendao Studio runtime.
The current frontend lint lane is now a strict closure project instead of a
config-relaxation exercise. .oxlintrc.json stays unchanged as the acceptance
gate, and the active goal is to drive the current 377 warning baseline down
to 0 through code fixes and component-boundary refactors only.
Run commands from .data/qianji-studio and prefer the project environment:
direnv exec . npm run dev
direnv exec . npm run build
direnv exec . npm testnpm run build now also runs scripts/check-build-size.mjs after the Rspack
emit and fails if any emitted JS/CSS asset exceeds 2_400_000 bytes or if the
initial entry asset set referenced by dist/index.html exceeds 3_800_000
bytes. That file is now a stable CLI entrypoint only; the reusable size-check
implementation now lives behind scripts/build/index.mjs, with pure asset and
budget logic split into scripts/build/check-build-size-model.mjs and runtime
execution split into scripts/build/check-build-size-runtime.mjs. The Rspack
warning thresholds and the post-build gate now share the same normalized
scripts/rspack/build-size-budgets.mjs source so the budgets cannot drift. The
split-chunk cache-group and async vendor naming policy now also live in
scripts/rspack/chunk-policy.mjs, leaving rspack.config.ts as the assembly
surface instead of the policy monolith. Gateway target parsing, plugin
construction, and dev-server proxy assembly now also live in
scripts/rspack/build-environment.ts. Browser targets, minimizer assembly, and
shared Rspack performance/experiments settings now also live in
scripts/rspack/build-profile.ts. Asset-resource and SWC loader rules now also
live in scripts/rspack/module-rules.ts. Static entry, output, and resolve
config now also live in scripts/rspack/core-surface.ts. The same helper
surface is re-exported through scripts/rspack/index.ts, so rspack.config.ts
consumes one coherent build-tooling barrel instead of a flat import list. The
normalized scripts/rspack/* tree plus the normalized scripts/build/*
surface now define the active build helper surface.
The frontend resolves its default gateway target from:
wendao.toml
Current local bind:
[gateway]
bind = "127.0.0.1:9517"The dev proxy reads that bind and forwards /api/* requests to the configured Wendao Studio gateway. If that file cannot be read, the current fallback target is http://localhost:8001.
The dev proxy now uses an explicit keep-alive node:http.Agent for gateway
traffic. This is required because the underlying http-proxy default is
agent = false, which forces connection: close and creates a fresh upstream
socket for every proxied /api/* request. In local development that behavior
showed up as intermittent browser NetworkError events even while the gateway
process itself remained healthy.
The browser-facing Flight client under src/api/flight/generated/ is consumed
directly as TypeScript source by Rspack, so generated imports must stay
extensionless instead of ending in .js. scripts/generate-flight-client.mjs
now emits the protobuf v2 Flight_pb.ts surface directly through
protoc-gen-es 2.11.0; the old protoc-gen-connect-es stage has been retired.
The active Flight stack in package.json is now:
apache-arrow 21.1.0@connectrpc/connect 2.1.1@connectrpc/connect-web 2.1.1@bufbuild/protobuf 2.11.0@bufbuild/protoc-gen-es 2.11.0
For same-port Arrow Flight profiling against the live gateway, run:
direnv exec . bash -lc 'cd .data/wendao-frontend && npm run test:hotspot-perf'
direnv exec . bash -lc 'cd .data/wendao-frontend && npm run test:live-flight-perf'npm run test:hotspot-perf records hotspot unit-trace artifacts for the live
typing/render path, including scenario-level traces for sec lang:julia,
repo-backed code-open canonicalization, and App-side repo-code hydration
without graph fetches, plus large-result-list selection shifts that should only
rerender the affected rows, plus a large code-result typing scenario that
tracks the left-pane render budget under the current react-virtuoso
threshold/window contract, plus dropdown selection-shift traces under the
shared 12-item suggestion budget, plus a controller-level suggestion-hover
trace that proves the shell and left results pane stay stable when only the
dropdown highlight changes, plus an autocomplete-core no-op projection trace
that proves repeated identical suggestion collections do not add render churn,
plus a semantic refresh-key trace that proves equivalent filter/query rerenders
do not trigger another autocomplete.refresh(), plus a combined
SearchInputHeader -> autocomplete refresh trace that proves one semantic
input change only triggers one refresh, plus a SearchBar one-character
refinement trace that proves visible results settle on the refined query
without extra autocomplete churn, plus a keyboard suggestion-browsing trace
that proves selecting a highlighted dropdown suggestion settles the visible
results onto the selected query without stale result opens and closes the
dropdown instead of keeping suggestion churn alive after acceptance,
and writes
$PRJ_CACHE_HOME/agent/tmp/wendao_frontend_hotspot_perf_traces.json.
The default all scope now treats code filters as frontend semantics instead
of raw backend query text: search execution and autocomplete strip lang:,
repo:, kind:, and path: tokens down to the base query before calling the
gateway, pure filter-only queries stay local, and the visible-result contract
is now explicit in tests: matching code hits win when they exist, otherwise the
view falls back to non-code results.
The repo-aware code lane is now Flight-first across every repo-facing search
facet. Same-origin Flight owns repo-content hits through
src/api/flightRepoSearchTransport.ts, the gateway repo-search route now
accepts the repo identifier per request instead of using one fixed mounted
repo, and the explicit doc facet now uses the dedicated
/analysis/repo-doc-coverage Flight route instead of the older JSON surface.
That boundary is now explicit in the main search interface too: when a
repo-aware all or code query has no explicit repo facet, the frontend no
longer fans out to repo-intelligence module, symbol, or example JSON
endpoints. The default repo-aware interface stays on Flight-backed
repo-content plus Flight-backed references, and the remaining JSON surfaces
are now limited to the intentional control-plane routes for health, UI
config/capabilities, and Julia deployment artifact inspection.
Those remaining JSON/control routes are now explicitly centralized under
src/api/controlPlane/*. src/components/panels/VfsSidebar/VfsSidebar.tsx
no longer issues its own fetch('/api/vfs/scan'); it now consumes the shared
api.scanVfs() facade so production component code does not own raw /api/
calls on the active studio surface.
The explicit symbol facet now also rides that Flight route instead of the
older repo-intelligence symbol endpoint. Parsed kind: filters become
repo-search tagFilters, so queries such as repo:foo kind:function solve
stay on the same Flight-backed repo-content surface while still narrowing to
symbol-like code hits.
The explicit module facet now also rides that Flight route. Repo-aware
module queries enforce tagFilters = ["kind:module"] on repo-search Flight,
and the repo-overview display-name fallback now retries that same Flight path
instead of dropping back to /api/repo/module-search.
The explicit example facet now also rides that Flight route. Repo-aware
example queries enforce tagFilters = ["kind:example"] on repo-search Flight,
and the repo-overview display-name fallback now retries that same Flight path
instead of dropping back to /api/repo/example-search.
The explicit doc facet now also stays on Flight, but it intentionally uses a
dedicated repo doc-coverage route instead of repo-search hits. The frontend
now calls /analysis/repo-doc-coverage, which returns normalized coverage
rows plus summary metadata and an optional module filter without falling
back to /api/repo/doc-coverage.
Repo overview now also stays on Flight. The frontend api.getRepoOverview(...)
path now uses the dedicated /analysis/repo-overview route instead of
/api/repo/overview, so repo-overview status chips and repo-overview fallback
logic no longer depend on the JSON repo-analysis surface.
Repo index status now also stays on Flight. The frontend
api.getRepoIndexStatus(...) path now uses /analysis/repo-index-status
instead of /api/repo/index/status, so the active repo-aware status lane no
longer depends on the JSON repo-index status endpoint.
Repo sync now also stays on Flight. The frontend api.getRepoSync(...) path
now uses /analysis/repo-sync instead of /api/repo/sync, so the active
repo-aware query/status lane no longer depends on the JSON repo-sync surface.
Repo index commands now also stay on Flight. The frontend
api.enqueueRepoIndex(...) path now uses /analysis/repo-index with a
request-scoped command id instead of POST /api/repo/index, so the active
repo-aware mutation lane no longer depends on the JSON repo-index enqueue
surface either.
VFS scan and topology now also stay on same-origin Flight. The frontend
api.scanVfs() path now uses /vfs/scan, and api.get3DTopology() now uses
/topology/3d, so the remaining non-Flight /api/ surface is limited to the
intentional control-plane routes for health, UI config/capabilities, and Julia
deployment artifact inspection.
The legacy repo-intelligence JSON convenience methods
api.searchRepoModules(...), api.searchRepoSymbols(...), and
api.searchRepoExamples(...) are no longer part of the active public client
facade. The SearchBar repo-aware lane now proves its module / symbol /
example behavior directly against repo-search Flight contracts instead of
keeping those older JSON helper methods alive in the top-level runtime client.
The repo-index enqueue surface now also uses the dedicated
src/api/flightRepoIndexTransport.ts module. The older
repoIndexCommandTransport.ts helper is retired, so the frontend no longer
keeps a JSON-only repo-index command seam alongside the Flight-backed repo
status/search surfaces.
The harness reads the checked-in wendao.toml, pushes the current runtime UI config,
and measures /search/knowledge with the default query set diffeq, solver,
and optimization. The current local config defines 179
link_graph.projects.* entries. Override STUDIO_LIVE_FLIGHT_PERF_QUERIES,
STUDIO_LIVE_FLIGHT_PERF_LIMIT, STUDIO_LIVE_FLIGHT_PERF_WARMUP_RUNS, and
STUDIO_LIVE_FLIGHT_PERF_MEASURED_RUNS to tune the run. Each live run also
writes JSON and CSV artifacts to
$PRJ_CACHE_HOME/agent/tmp/wendao_frontend_live_flight_search_perf.{json,csv};
the harness now treats the exported PRJ_CACHE_HOME env var as the absolute
project cache root directly. The JSON artifact now also includes a per-phase
breakdown for GetFlightInfo, DoGet, Arrow IPC reassembly, hit decoding, and
metadata decoding so live runs can identify the actual hotspot instead of only
recording end-to-end latency, and it now also records the optional hotspot-unit
artifact path/count when
$PRJ_CACHE_HOME/agent/tmp/wendao_frontend_hotspot_perf_traces.json is
present. The harness now also retries transient
gateway-startup control-plane failures such as EADDRNOTAVAIL during the
/health and /ui/config preflight, normalizes loopback origins, and waits
for search/repo status to settle before measured runs begin, so a
just-restarted local gateway no longer pollutes the perf suite with bootstrap
noise. The latest same-port 127.0.0.1:9517 steady-state rerun after the
runtime DoGet encoded-frame reuse slice plus the explicit react-virtuoso
list-budget contract reports 2.49ms average, 5.17ms P95, with
GetFlightInfo averaging 0.91ms, DoGet averaging 0.78ms, and the shared
hotspot artifact carrying 19 scenario records across the default
179-repository config. The full report is in
docs/05_research/308_live_flight_search_perf_report.md.
- Indexed roots and VFS hydration
- Topology and graph navigation
- Graph auto-fallback to
/api/analysis/markdownwhen/api/graph/neighbors/<path>returnsNODE_NOT_FOUND - Selection paths are canonicalized before VFS or graph lookup; workspace-local
.data/wendao-frontend/...paths are never sent directly to the gateway. When a selection arrives withoutprojectName, App resolves the bare path through the gateway before hydration so the request still becomes project-scoped. - Graph actions are only exposed for note-backed results; code and attachment results do not advertise graph navigation
- The SearchBar wrapper now keeps scope and sort behind a compact dropdown filter so the status and results area stay visually primary; the old drawer surface has been removed
- Repo-index status separates adaptive analysis concurrency from the dedicated remote-sync semaphore and surfaces both in the status popover
- Repo-index totals intentionally exclude link-graph-only projects with
plugins = [], such as localkernel/maindocs roots - Repo-index status also condenses repeated unsupported layout failures into grouped reason summaries with repo previews, so common misses such as
missing Project.tomldo not hide inside the full issue list - Clicking the repo-index chip in the status bar now opens a dedicated diagnostics page with
#repo-diagnosticshash persistence; the selected diagnostics filter and reason focus are also encoded into the hash so the current triage slice is shareable - The diagnostics page now also supports repo-focused detail selection; clicking a failed or unsupported repo opens a detail pane and persists that repo focus into the hash via
repo=<id> - The selected repo detail pane now also exposes page-level remediation actions: failed repos can be retried directly from the diagnostics page, and any selected repo can export a single-repo diagnostics brief to the clipboard
- The same selected repo pane now also supports
Download remediation bundle, exporting a richer Markdown handoff bundle that includes the current diagnostics brief plus unsupported-repo remediation material when available - The diagnostics page header now also supports
Download current triage bundle, exporting the active filtered failed/unsupported slice as a shareable Markdown handoff bundle with runtime context, link-graph-only exclusions, failure-family grouping, failure-family remediation guidance, and batchFailure presetsinstead of limiting export to one selected repo - The same triage bundle now also includes batch
Unsupported presets, so grouped layout failures such asmissing Project.tomlexport concrete remediation blocks instead of only a grouped manifest - For unsupported repos, the same pane now also exposes
Copy fix template, so common layout failures such asmissing Project.tomlcan be handed off as a concrete remediation template instead of a raw error string - For
missing Project.tomlspecifically, the selected unsupported repo pane now also exposesCopy link-graph-only preset, producing a ready-to-editlink_graph.projects."<repo>"TOML snippet withplugins = [] - The same
missing Project.tomlpath now also exposesDownload config patchfor the selected repo andDownload current config patchfor the current unsupported slice, so link-graph-only remediation can be handed off as raw TOML instead of Markdown only - Selected failed repos now also render failure-specific guidance, so transient transport failures and auth/access failures no longer collapse into the same generic retry hint
- Selected failed repos now also expose
Copy failure preset, exporting a structured failure-family handoff that includes retryability, guidance, and category-specific next steps such as reduced sync concurrency or credential checks - Failed diagnostics now also expose
Download failure planfor the selected repo andDownload current failure planfor the current failed slice, so failure-family remediation can be handed off as raw TOML instead of clipboard-only presets - Raw TOML exports now also carry workspace-aware headers such as
scope_filter, current reason focus,current_repo, and concurrency context, so offline handoff preserves the operational context in which the export was generated - Repo-diagnostics failure families are now canonicalized before filtering and export, so repo-specific GitHub transport errors such as
failed to connect to github.com: Can't assign requested addresscollapse into one batch family instead of one preset per repo - Failure-plan and triage exports now also carry
reason_keyplus boundedsample_errors, so machine consumers can key off a stable family id while operators still retain raw error examples for the current slice - The same failure exports now also carry action-preset fields such as
action_key,retry_scope,env_overrides, andfollow_up_checks, so transient transport and auth/access families can be handed off as executable remediation plans instead of free-form guidance only - Selected failed repo panes now also expose
Copy remediation command, turning the current repo-level failure action preset into a clipboard-ready shell snippet instead of limiting execution handoff to TOML exports - Selected failed repo panes now also expose
Download remediation command, so the same repo-level failure action preset can be handed off as a runnable shell script instead of clipboard-only command text - The diagnostics page header now also exposes
Copy current remediation commandfor the active failed slice, so a canonical failure family can be copied as one batch remediation script instead of one repo at a time - The diagnostics page header now also exposes
Download current remediation command, so the active failed slice can be handed off as a runnable shell script instead of clipboard-only command text - Downloaded remediation scripts now also carry workspace-context comment headers such as
scope_filter, current reason focus, selected repo, and concurrency state, so the shell artifact remains self-describing after it leaves the diagnostics page - The same downloaded remediation scripts now also carry
generated_atplus canonicalreason_keyheader fields, so the exported shell artifact can be correlated back to one failure family without reopening the UI - Downloaded remediation scripts now also summarize canonical
action_keyandretry_scopein the top-level header, so operators can see the intended remediation mode before reading the shell body itself - Downloaded remediation scripts now also summarize
env_overridesandfollow_up_checksin the top-level header, so the required environment knobs and post-run validation steps are visible before the shell body itself - That same top-level script header now aggregates those fields across the exported scope, so current-slice remediation scripts expose one deduplicated environment-override set and one deduplicated validation checklist before the shell body itself
- The diagnostics page now also exposes
Download current remediation runbook, which packages the current failed slice as one Markdown handoff containing scope summary, failure plan, and the runnable remediation script instead of forcing operators to download those artifacts separately - Selected failed repo panes now also expose
Download remediation runbook, so repo-level handoff has the same single-artifact path instead of forcing operators to combine the repo failure plan and repo remediation script manually - The diagnostics page header now also exposes
Download current diagnostics pack, which combines the current triage bundle, current failed-slice remediation runbook, and current unsupported config patch into one Markdown handoff and adds a top-level operator summary (action_keys,follow_up_checks,suggested_sync_concurrency_limit,next_steps) instead of forcing operators to reconstruct current-scope actions from separate exports - That same operator summary is now also rendered directly on the diagnostics page as a current-slice action card, and its failure-family action rows plus unsupported-slice CTA now jump the page straight into the matching failed family or unsupported slice instead of leaving the summary as a read-only synthesis block
- Once a failed family or unsupported slice is focused, the page now also renders a dedicated focused action bar so the matching retry, export, runbook, and back-navigation actions are surfaced together instead of remaining scattered across the full header
- Focused failed/unsupported slices now also trim duplicate page-header actions, so the focused action bar becomes the primary slice-local control surface instead of mirroring the same command/download buttons in two places
- That focused action bar is now also compressed into a primary-action surface: failed slices keep
Retry filtered failedplus the remediation runbook visible, unsupported slices keep the highest-value patch/export visible, and the remaining secondary exports now sit behindMore exportsand reset when the focused slice changes - Repo diagnostics no longer live in the FileTree sidebar; the status-bar chip and
#repo-diagnosticspage are now the canonical triage surface - The diagnostics feature now owns its own
repoDiagnostics/module boundary for copy, state, drawer rendering, and controller logic, instead of continuing to hang underpanels/FileTree/ - The FileTree feature folder is now reduced to tree/runtime/view composition concerns:
types,copy,treeModel,TreeNode,useFileTreeRuntime,useFileTreeExpansion,useFileTreeStatus,FileTreeToolbar,FileTreeContent, andFileTreeNodes - Knowledge, symbols, AST, and references search
- Zen Search as the primary full-screen search workspace for knowledge, symbols, AST, references, and code-oriented structured projection flows
- The right-side Structured Intelligence Dashboard (SID) renders topology, fragments, relational projection, and a local connectome for non-code results. Code-backed results render through a dedicated
StructuredCodeInspectorwrapper that projects a single-column AST waterfall with a numbered file-path prelude, declaration identity, structured signature parts, logic block decomposition, symbol overlays, compact retrieval metadata (chunk id,semantic type,fingerprint,token estimate) across declaration, block, symbol, and ranked anchor atoms, and explicitPivot declaration/Pivot block/Pivot symbol/Pivot anchorplusCopy for RAGactions on those same code atoms, while markdown-backed DirectReader content renders throughMarkdownWaterfallinside a dedicated ZenSearch markdown reading tray with a document identity card that foregroundsTitle,Tags, andLinkedbefore compact heading-based section index cards, section-levelCopy for RAG/Pivot sectionactions, compact retrieval metadata (chunk id,semantic type,fingerprint,token estimate), and nested rich slots for tables, math, mermaid, bi-links, and fenced code blocks with shared slot headers. - Code AST declaration, logic-block, and symbol atoms now prefer backend-issued
retrievalAtomsfrom/api/analysis/code-ast; logic-block chunks now also carry backend-issued display labels and excerpts, and the logic-block rail still falls back to local inference only when no matching backend block chunk is available. - The top header now uses a compact two-line layout on wide screens and stacks responsively on narrower screens: the eyebrow/title share the first row, the focus chip sits inline on the same row when present, and the subtitle occupies the second row.
- The dashboard slots now use a balanced two-row grid with slightly tighter padding, keeping the four structured layers visually symmetric while preserving internal scroll for dense content, and each layer is exposed as a named landmark region with a compact header layer index for structured navigation.
- The local connectome mini-map now exposes incoming/outgoing side toggles, highlights the toggle that matches the active anchor side, and keeps a focused-anchor chip visible; the neighboring path trail now mirrors the same compact side badge, and both stay synchronized with the neighboring text anchors and top header active-anchor banner, whose path display is compacted while preserving the full path in the tooltip, while the mini-map itself uses a tighter viewport and node spacing so graph pivots hold one shared visual anchor instead of acting like a passive diagram, and switching to a different selected result clears that shared focus state.
- Code-backed Zen results now project through a dedicated
StructuredCodeInspectorwrapper into a single-column AST waterfall with a numbered file-path prelude, a compact declaration identity lane, structured signature parts with explicit parameter and return rows, a single vertical validation/execution/return block stack, grouped symbol overlays, compact retrieval metadata plus explicitPivot declaration/Pivot block/Pivot symbol/Pivot anchorandCopy for RAGon declaration, block, symbol, and ranked anchor atoms, and shared Shiki-backed generic syntax highlighting; the raw DirectReader content preview is reserved for non-code results CodeAstAnatomyView.tsxnow delegates locale copy, signature-row shaping, displayed line-range derivation, and declaration/block/symbol/anchor copy payload builders tocodeAstAnatomyViewModel.ts, so the AST waterfall UI shell no longer carries that helper logic inlinecodeAstAnatomy.tsnow delegates retrieval atom typing, backend lookup, frontend fallback atom construction, and shared retrieval-atom resolution tocodeAstRetrievalHelpers.ts, so AST projection code no longer mixes UI-model derivation with retrieval-contract plumbing in one filecodeAstAnatomy.tsnow also delegates shared projection primitives tocodeAstProjectionShared.ts, signature parsing/snippet extraction tocodeAstSignatureHelpers.ts, logic-block assembly tocodeAstBlockHelpers.ts, and symbol/anchor grouping tocodeAstSymbolHelpers.ts, so the AST anatomy layer is split by concern instead of continuing as one projection monolithStructuredIntelligenceDashboard.tsxnow delegates path/anchor formatting and focus resolution tostructuredDashboardShared.ts, and card/list/fragment renderer helpers tostructuredDashboardRenderers.tsx, so the dashboard shell stays focused on orchestration instead of carrying every structured rendering helper inlineCodeAstAnatomyView.tsxnow delegates the file prelude, declaration lane, logic-block lane, and symbol/anchor lane tocodeAstAnatomySections.tsx, so the main AST waterfall view focuses on preview-state wiring and model derivation instead of holding the full presentational body inline- The shared syntax highlighter now uses a curated fine-grained Shiki bundle instead of the full bundled runtime, and the markdown/rendering stack is split into its own initial chunk, so
npm run buildnow lands without the earlier oversizedvendors-async-misc.js/vendors.jsasset warnings - The Zen Search shell is lazy-loaded so the normal workspace startup path does not depend on the full Zen subtree at initial render time, then remains mounted as a persistent overlay once opened so the workspace state stays intact while the shell toggles visibility
StudioBootstrapnow lazy-loads the workspaceAppafter gateway health and UI-config sync succeed, so the initialmainentry keeps only the bootstrap shell instead of eagerly pulling the full workspace tree into first paint- Shiki syntax highlighting now loads as a small async runtime core plus per-language and per-theme lazy chunks, so code highlighting no longer emits one oversized monolithic async Shiki asset
- The
SearchBarwrapper remains internal only; the public search entrypoint isZenSearchWindow - Studio bootstrap now keeps a static blank loading shell until the app is ready or blocked, and the workspace itself stays hidden until the first VFS load completes, so the startup flow does not visibly paint a loading panel during gateway connection
- The frontend entrypoint renders
StudioBootstrapdirectly instead of wrapping it inReact.StrictMode, which avoids the dev-only double-mount flash during gateway connection - Source-focused reader mode with line highlighting; code files now enter source mode from their suffix even without a line target, and source lines reuse the shared Shiki-backed syntax highlighter used by fenced code blocks and AST/code fragments
- Markdown-backed reader mode now renders a waterfall layout with a document identity card, heading-based section cards, section-level
Copy for RAG/Pivot sectionactions, compact retrieval metadata (chunk id,semantic type,fingerprint,token estimate), and preserved rich slots for tables, math, mermaid, bi-links, and fenced code blocks while keeping source mode available for exact line inspection - Zen Search markdown preview now also requests
/api/analysis/markdownand prefers backend-issued document/sectionretrievalAtomsfor markdown waterfall cards when analysis is available; local chunk derivation remains the fallback for intro sections and other paths without backend atoms, while section copy payloads now also prefer backend-issued excerpts when present - Markdown code and mermaid rich slots now also prefer backend-issued markdown
retrievalAtomswhen/api/analysis/markdownincludescode blockatoms, and those rich slots now surface the same compact retrieval metadata plusCopy for RAGaction used by section cards; slot copy payloads also prefer backend-issued excerpts when present - Markdown table rich slots now also prefer backend-issued markdown
retrievalAtomswhen/api/analysis/markdownincludestableatoms, and those table slots now surface the same compact retrieval metadata plusCopy for RAGaction instead of remaining presentation-only; table copy payloads also prefer backend-issued excerpts when present - Markdown display-math rich slots now also prefer backend-issued markdown
retrievalAtomswhen/api/analysis/markdownincludesmath:blockatoms, and those formula slots now surface the same compact retrieval metadata plusCopy for RAGaction as the other markdown waterfall atoms; math copy payloads also prefer backend-issued excerpts when present - Markdown observation rich slots now also prefer backend-issued markdown
retrievalAtomswhen/api/analysis/markdownincludesobservationatoms, and those blockquote cards now surface the same compact retrieval metadata plusCopy for RAGaction as the other markdown waterfall atoms MarkdownWaterfall.tsxis now reduced to a thin orchestration shell, with shared copy/contracts, bi-link parsing, waterfall model assembly, and rich-slot rendering split into dedicated helper modules so the markdown retrieval surface no longer depends on a single 1500+ line fileZenSearchPreviewEntity.tsxnow delegates markdown-vs-structured preview detection tozenSearchPreviewSurface.ts, and delegates the markdown/structured bridge bodies tozenSearchPreviewBridges.tsx, so the Zen preview shell no longer mixes route selection with both preview render paths inlineuseZenSearchPreview.tsnow delegates preview-path planning and parallel content/graph/code-ast/markdown loading tozenSearchPreviewLoaders.ts, so the hook no longer mixes state orchestration with per-surface retrieval plumbing inlineZenSearchPreviewPane.tsxnow delegates the rendered pane frame toZenSearchPreviewPaneView.tsx, andZenSearchPreviewShell.tsxnow delegates placeholder-vs-entity branching tozenSearchPreviewShellContent.tsx, so the preview controller, container shell, and body routing each live in their own small module- Studio analysis bindings now expose a shared
RetrievalChunk/RetrievalChunkSurfacecontract across markdown and code AST responses, while markdown/code-specificretrievalAtomsremain narrowed views over that same cross-surface payload - The frontend now ships
apache-arrowand materializes retrieval atoms into shared Arrow-backed lookup tables, so code AST owner/surface resolution and markdown section/rich-slot range queries both run against the same columnar local query path instead of ad hocMap/array scans - Zen preview now consumes raw VFS content, markdown, and code-AST over the
same-origin Flight business routes, and the older
retrieval-arrowoverlay story is no longer the active architecture - Zen search knowledge, symbol, reference, attachment, and AST lanes now all
consume the canonical same-origin Flight business routes directly; the older
hits-arrowoverlay story is retired debt rather than the current frontend design - Arrow IPC remains only as the Flight record-batch codec used by the shared frontend decode helpers, not as a separate business transport surface
- The frontend API client now delegates search, repo-search, graph, workspace,
document, and analysis business routes to the dedicated
src/api/flight*.tstransport modules, sosrc/api/client.tsno longer owns business-route wiring inline - The frontend API client now also delegates repo-index commands to
src/api/flightRepoIndexTransport.ts, so the active repo-aware repo-index mutation lane no longer depends onPOST /api/repo/index - The frontend API client now also delegates its intentional JSON
control-plane surface to
src/api/controlPlane/*, whilesrc/api/uiConfigTransport.tskeeps the UI config sync/retry state and capabilities cache behavior - The frontend API client now also delegates shared
ApiClientError, JSON response parsing, and binary response parsing tosrc/api/responseTransport.ts, sosrc/api/client.tsno longer owns the common response-transport seam inline - The frontend API client now also delegates the remaining health seam through
src/api/controlPlane/*, while VFS scan and topology now ride the dedicatedsrc/api/flightWorkspaceTransport.tsandsrc/api/flightGraphTransport.tsbusiness transports - The frontend API client now also delegates projected-page-index and
refine-doc same-origin Flight wiring to
src/api/flightProjectedPageIndexTransport.tsandsrc/api/flightRefineEntityDocTransport.ts, sosrc/api/client.tsno longer owns the active document business-transport seam inline - The frontend API client now also delegates its remaining public repo/UI contract interfaces to
src/api/apiContracts.ts, sosrc/api/client.tsno longer owns the contract surface inline - The frontend API client now also keeps all runtime wiring in
src/api/clientRuntime.ts, whilesrc/api/client.tsis reduced to the stable public facade for runtime exports plus type re-exports - Internal API helpers no longer type-import the public
client.tsfacade; helper modules now consumesrc/api/apiContracts.tsdirectly so the helper dependency graph stays pointed inward src/api/index.tsnow acts as the stable public barrel for API consumers, re-exporting the facade plus the dedicated contract/error surface instead of remaining a trivial client forwarder- The frontend API client now also exposes the Studio Julia deployment artifact inspection surface through
api.getJuliaDeploymentArtifact()andapi.getJuliaDeploymentArtifactToml(), backed by a dedicatedUiJuliaDeploymentArtifactcontract insrc/api/apiContracts.ts - Qianji Studio now also consumes that deployment artifact in the workspace
StatusBar, surfacing a compact Julia rerank chip with a hover inspection popover for artifact metadata, transport coordinates, launcher path, service mode, and analyzer strategy - The same
StatusBarinspection popover now also exposesCopy TOMLandDownload JSONactions, so the resolved Julia deployment artifact can be exported directly from the live workspace shell - The Julia deployment inspection formatting and export behavior now also live in the feature folder
src/components/juliaDeploymentInspection/, split into explicitformat,actions,types, andindexseams soApp.tsxandStatusBar.tsxno longer each own their own artifact parsing/export rules inline - The same feature folder now also owns a dedicated
View.tsxsubview for the Julia deployment popover, soStatusBar.tsxremains the status-orchestration surface instead of also owning the artifact popover rendering tree StatusBar.tsxnow also mounts a dedicatedstatusBar/RepoIndexStatusView.tsxsubview for the repo-index diagnostics chip/popover, so both major status popovers now live below the top-level orchestration surface- The remaining derived status labels and tones now also live in
src/components/statusBar/model.ts, soStatusBar.tsxis reduced to state wiring plus subview assembly instead of mixing derivation and rendering concerns - The repo-index chip/popover contract now also lives in the shared
statusBar/feature-folder surface asRepoIndexStatusViewModel, sostatusBar/model.tsandRepoIndexStatusView.tsxshare one view contract instead of re-declaring the subview props inline - The Julia deployment inspection feature folder now also owns the local copy/download action-state controller in
src/components/juliaDeploymentInspection/controller.ts, soStatusBar.tsxno longer manages analyzer-export feedback state inline - Shared
RepoIndexStatus,RuntimeStatus, andVfsStatuscontracts now also live insrc/components/statusBar/types.tsbehind thestatusBar/index.tsfeature-folder surface, so repo-diagnostics, FileTree, and MainView code no longer import shared types back out ofStatusBar.tsx; those imports now also use explicitstatusBar/*file paths to avoidStatusBar.tsxvsstatusBar/ambiguity on case-insensitive filesystems - The left-pane SearchBar now also assembles its visible result list, section stack, and code-filter catalog through local Arrow-backed view helpers, so scope filtering, code-filter matching, dedupe, sort, and code facet extraction run against shared columnar tables before the existing
SearchResult[]rows and section props are handed back to the UI - SearchBar all-mode execution now delegates its multi-lane aggregation, fallback shaping, and merged runtime warning assembly to
searchExecutionAllMode.ts, so the main execution file no longer owns the largest cross-lane branch inline - SearchBar all-mode execution now further delegates fallback response builders and merged result/meta shaping to
searchExecutionAllModeHelpers.ts, so the all-mode module itself is down to fan-out orchestration plus settled-lane resolution - SearchBar all-mode execution now also preserves repo-aware code-search options from ZenSearch default scope, strips inline
repo:filters before the semantic lanes are issued, keeps the default repo-aware lane on repo-search Flight plus Flight-backed references, and still forwards the raw repo-aware query into backendcode_searchintent metadata, so repo-scoped code queries work from the default full-screen search surface instead of only from dedicated code mode - The frontend live gateway suite now also covers the JSON repo-intelligence search surface in
src/api/liveRepoSearchGateway.test.ts, so live repo search no longer rides only on unit mocks while same-origin Flightcode_searchis verified separately insrc/api/liveCodeSearchGateway.test.ts - SearchBar code-mode execution now also delegates its repo-aware orchestration, backend intent metadata resolution, and fallback result shaping to
searchExecutionCodeMode.ts, so the main execution file no longer owns the repo-specific code branch inline - SearchBar code-mode execution now further delegates repo-aware settled-result resolution, fallback selection, and standalone code-search shaping to
searchExecutionCodeModeHelpers.ts, so the code-mode module itself is down to fan-out orchestration and route selection - SearchBar simple execution responders now delegate their reference, attachment, AST, symbol, and knowledge index contracts to
searchExecutionSimpleModes.ts, sosearchExecution.tsis now a thin mode router instead of a mixed orchestration-plus-response formatter - SearchBar execution types now live in
searchExecutionTypes.ts, so helper modules no longer type-import the main router file and the execution surface is organized as one router plus explicit shared contracts useSearchBarController.tsxnow delegates data-flow, interaction, and view-model assembly touseSearchBarControllerPresentation.ts, so the top-level controller hook stays focused on state hooks, repo slice wiring, reset behavior, and final result assembly- ZenSearch preview loading now runs through explicit base, code-AST, and markdown lanes, so AST preview completion no longer waits for slower VFS, graph, or markdown work before the AST pane leaves its loading state
- The AST waterfall loading copy now says
Loading AST analysis...instead ofCompiling AST anatomy view..., so the UI no longer misattributes backend/proxy wait time to frontend compilation - The MainView content pane now mounts
DirectReaderthrough the same lazy loader surface used by the other heavy panels, and the Rspack markdown policy now splitsmarkdown-core,mermaid, andkatexinto async chunks; the production build no longer pulls the oldmarkdown.jsblob into the initial entrypoint, which is now down to0.481 MiB DirectReadernow defers its rich markdown runtime throughDirectReaderRichContent, soreact-markdown, Mermaid, KaTeX, and the markdown waterfall stay behind a panel-local lazy seam instead of being imported directly into the reader shell; focused DirectReader regressions were updated to wait for lazy rich hydration and the production build still holds the initial entrypoint at0.481 MiBMarkdownWaterfallnow further defers section-body markdown rendering throughMarkdownWaterfallSectionBody, so the identity card and section chrome render before the heaviestReactMarkdown/Mermaid/KaTeX/code-slot runtime hydrates; the focused waterfall and reader regressions remain green and the production build still keeps the initial entrypoint at0.481 MiBMarkdownWaterfallcode slots now further defer syntax-highlighted code rendering throughMarkdownWaterfallCodeSlot, so Shiki-backed code blocks no longer hydrate inline with the rest of the slot renderer path; focused reader/waterfall regressions remain green and the production build still keeps the initial entrypoint at0.481 MiB- A follow-up bundle audit now confirms those nested seams are real in the emitted assets:
MarkdownWaterfallCodeSlotlands as its own small async chunk (757.js), while the dominant remaining markdown-rich async asset is stillmermaid.js; the next optimization slice should therefore target Mermaid-specific runtime rather than more Shiki splitting MarkdownWaterfallMermaid slots now also defer theirbeautiful-mermaidruntime throughMarkdownWaterfallMermaidSlot, so Mermaid-backed markdown blocks no longer keep that runtime wired intomarkdownWaterfallComponents.tsx; source-map inspection confirms the Mermaid slot now lands behind its own async seam whilemermaid.jsremains the dominant markdown-rich asset- Mermaid runtime assembly now also lives behind the shared
src/components/panels/mermaidRuntime/surface, soDiagramWindow,DirectReaderRichContent, andMarkdownWaterfallMermaidSlotno longer own separate Mermaid import patterns; source grep now showsbeautiful-mermaidonly under that shared loader while the initial entrypoint still holds at0.481 MiB - Mermaid rendering now also runs through an explicit dialect preflight gate inside
src/components/panels/mermaidRuntime/analysis.ts, so only the inline-supported dialects (flowchart/graph,state, plus ambiguous sources) activate the shared runtime; explicitsequenceDiagram,classDiagram,erDiagram, andxychartblocks now fall back directly to source/error UI instead of pretending the inline renderer is still loading - Mermaid runtime loading now also runs through a provider-neutral adapter surface in
src/components/panels/mermaidRuntime/provider.tsandsrc/components/panels/mermaidRuntime/providers/beautifulMermaid.ts, so the currentbeautiful-mermaidimplementation is isolated behind one adapter instead of leaking a library-shaped contract into DiagramWindow or DirectReader consumers - Mermaid bundle telemetry now also has a stable CLI at
scripts/mermaid-bundle-report.mjsplus a split model/runtime surface underscripts/build/; the current rebuilt dist frontier reportsmermaid.jsat1604102bytes while the initial entrypoint still holds at0.481 MiB - The active Mermaid provider now also exposes a typed manifest with
providerName,packageName, supported inline dialects, and payload notes; the bundle report prints that manifest context before the asset sizes, so future provider swaps can be evaluated against an explicit contract instead of shell notes - The shared Mermaid runtime can now also load a bounded local
compact-flowspike provider by name; that provider does not depend on ELK orbeautiful-mermaid, only supports simple arrow-connectedflowchart/graph/statediagrams, and is currently intended for feasibility comparison rather than default UI rendering - Mermaid provider comparisons now also run against a fixed bakeoff corpus in
src/components/panels/mermaidRuntime/bakeoffFixtures.ts; the current corpus keepsbeautiful-mermaidgreen while pinningcompact-flowto an explicit bounded subset instead of an open-ended compatibility claim compact-flownow also supports single-layer flowchartsubgraphblocks through a bounded group-shell renderer, so the bakeoff corpus has advanced one step:subgraphis now green for the spike provider, while decision-node syntax remains the next explicit misscompact-flownow also supports flowchart decision nodes as bounded diamond nodes, so the current bakeoff corpus is green for the spike provider across the targeted flowchart subsetcompact-flownow also supports single-layer state composite blocks through the same bounded group-shell pattern used for flowchart subgraphs, so the bakeoff corpus is green across the currently targeted flowchart/state subset; nested composites and richer state-machine semantics remain intentionally unsupported- Studio capabilities no longer advertise a browser Arrow search transport; the active Julia deployment inspection surface now points directly at the Flight
/rerankroute and/healthz - DiagramWindow now renders the same MarkdownWaterfall fallback for markdown-backed files when no embedded Mermaid or BPMN diagram body is available, instead of collapsing to the empty diagram hint; the fallback identity card keeps the
Title / Tags / Linkedhierarchy visible before the section stack - MainView content and diagram panels now hold a loading fallback while selected file content is still hydrating, which avoids flashing the empty hint during gateway reconnects
- docs/README.md - Curated human entry point
- docs/index.md - Graph-structured docs kernel
- docs/01_core/102_developer_onboarding.md - Environment and startup flow
- docs/01_core/105_docs_conventions.md - How the docs kernel is organized
The highest-value targeted frontend suite today is:
The shared Shiki syntax renderer now falls back to the current file suffix when a code block arrives with a generic code label or no explicit language tag, so .py, .rs, and .jl content still renders with syntax coloring through the same renderer.
direnv exec . npm test -- src/App.test.tsx src/components/ZenSearch/__tests__/ZenSearchWindow.test.tsx src/components/ZenSearch/__tests__/ZenSearchLayout.test.tsx src/components/ZenSearch/__tests__/ZenSearchWorkspace.test.tsx src/components/ZenSearch/__tests__/ZenSearchPreviewShell.test.tsx src/components/ZenSearch/__tests__/ZenSearchPreviewEntity.test.tsx src/components/ZenSearch/__tests__/ZenSearchPreviewContent.test.tsx src/components/code-syntax/index.test.ts src/components/code-syntax/CodeSyntaxHighlighter.test.tsx src/components/ZenSearch/__tests__/CodeAstAnatomyView.test.tsx src/components/ZenSearch/StructuredDashboard/__tests__/StructuredCodeInspector.test.tsx src/components/ZenSearch/StructuredDashboard/__tests__/StructuredIntelligenceDashboard.test.tsx src/components/SearchBar/__tests__/SearchToolbar.test.tsx src/components/SearchBar/__tests__/SearchStatusBar.test.tsx src/components/SearchBar/__tests__/SearchBar.test.tsx src/components/panels/MainView/MainView.test.tsx src/components/panels/GraphView/__tests__/GraphView.test.tsx src/components/panels/DiagramWindow/__tests__/DiagramWindow.test.tsx src/components/panels/DirectReader/MarkdownWaterfall.test.tsx src/components/panels/DirectReader/DirectReader.test.tsxFor backend contract validation, pair that with:
direnv exec . cargo test -p xiuxian-wendao gateway::studio -- --nocapture