Skip to content

Fix search, extract the dashboard, and ship it as a second binary - #22

Merged
Phoenixrr2113 merged 9 commits into
mainfrom
feat/dashboard-and-search-fixes
Aug 19, 2026
Merged

Phoenixrr2113 merged 9 commits into
mainfrom
feat/dashboard-and-search-fixes

Conversation

@Phoenixrr2113

Copy link
Copy Markdown
Owner

Seven scoped commits. Each fixes something that was broken rather than adding surface area.

Search returned nothing, and it was not the search

Semantic search fell through to substring matching on every query. The vector index, the embeddings and the KNN query were all fine, verified one at a time. The cause was three layers up: when no scope is passed, search auto-scopes to the configured active projects, and a project directory that had been moved was still listed. Every candidate was filtered out by a path that no longer exists, silently.

  • Configured directories that do not exist are dropped from the scope, with a log line naming them.
  • An empty scoped search now sets a notice naming the scope instead of returning silence.
  • searchByVector had a bare catch returning [], which reports a real query failure as "no results". It now logs anything that is not a benign missing-index case.

The dashboard could not start at all

Four separate blockers, each verified fixed against a running server:

  1. Embedded database would not open. falkordblite derives its Unix socket from the data directory and offers no override, so a moderately deep checkout exceeded the 104 byte sun_path limit on macOS and every endpoint failed. The data directory now falls back to a short deterministic path under ~/.codegraph/graphs/<hash>.
  2. .env was never loaded. The server read process.env only, so the graph connection, embedding provider and API keys were silently ignored.
  3. API_PORT was dead configuration. .env and docker-compose set it; the server read PORT.
  4. CORS was pinned to port 3000. Next picks the next free port when 3000 is taken, and the UI then reported "API server is not running" while the API was running fine.

Dashboard extracted, initial load down 95 percent

It shared a Next app with the marketing site, so every visitor downloaded 2,382 KB gzipped, most of it landing page furniture the dashboard never imports. As a standalone Vite app the initial load is 107 KB gzipped.

Shiki needed attention too: importing codeToHtml from the shiki entry point pulls in every bundled grammar, producing 304 chunks and 9.9 MB. The code preview only highlights twelve languages, so the highlighter is built from shiki core with exactly those, using the JavaScript regex engine so the 600 KB WebAssembly payload never ships. Build is now 18 files.

The API serves the built UI from its own origin, which removes the CORS class of bug entirely.

The release gate was measuring the wrong thing

pnpm audit --prod audits this workspace, not the artifact. The workspace passes only because root pnpm.overrides pins a patched sharp, and overrides are not inherited by anyone installing from npm. A real install resolves a vulnerable sharp through @huggingface/transformers while CI reported clean.

audit:consumer resolves the published manifest the way npm would for an end user. The sharp advisory is acknowledged explicitly with the reason it cannot be fixed here, and a stale acknowledgement fails the build. SECURITY.md discloses it.

This is the first run of that gate in CI, so a finding there is informative rather than alarming.

Packaging

The dashboard ships as a second binary, codegraph-dashboard. Bundling the two servers separately duplicated their shared payload and took the package from 1.86 MB to 4.15 MB packed; a single split build brings it to 2.27 MB, so the whole dashboard costs about 0.4 MB.

Both gates were extended: the validator checks both binaries and the built UI, and the smoke test starts the packaged dashboard on a free port, waits for health, and fetches a real hashed asset.

Also

  • cgbench: cognee's libc++ mutex abort was CGBench dispatching three concurrent queries against a Kuzu store that permits one process, not the concurrent ingest_data starts an earlier note blamed. Adapters can now cap their own query concurrency. The results explain why cognee still has no score, with measured numbers.
  • docker-compose: removed the api and web services, which referenced Dockerfiles that have never existed in this repo.
  • Benchmark scripts no longer hardcode a home directory that no longer exists.

Verification

Run against the committed tree with packages/dashboard/dist and packages/npm-package/dist deleted first, since both are gitignored and absent on a fresh checkout:

  • 20 of 20 typecheck tasks
  • 32 of 32 test tasks
  • Full release:check: build, validate, consumer audit, smoke with dashboard verification

🤖 Generated with Claude Code

Phoenixrr2113 and others added 7 commits August 19, 2026 16:19
Semantic search returned nothing while the vector index, the embeddings and
the KNN query were all fine. When no scope is passed, search auto-scopes to
the configured active projects. A project directory that had been moved or
deleted was still listed, so every candidate was filtered out by a path that
no longer exists, and the caller saw an empty result with no explanation.

Three changes, each aimed at making that class of failure visible:

- getActiveProjectPaths drops configured directories that do not exist and
  logs which ones. A path with nothing behind it can never be a useful scope.
- An empty scoped search now sets a notice naming the active scope and
  suggesting scope "all", reusing the channel the missing-provider case
  already used.
- searchByVector had a bare catch returning an empty array, which reports a
  real query failure as "no results". It now logs anything that is not a
  benign missing-index case.

The pre-existing test asserting the old behaviour used paths that do not
exist, so it has been updated to use real directories rather than deleted.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…mits

Every API endpoint failed on a fresh checkout with "Generated Unix socket
path is too long (111 bytes)". falkordblite derives its Unix socket from the
data directory and, as verified in the installed package source, gives the
caller no way to set the socket path directly. A checkout nested even
moderately deep therefore exceeds the 104-byte sun_path limit on macOS and
the embedded database cannot start at all.

The data directory now falls back to a short deterministic path under
~/.codegraph/graphs/<hash> when the configured one cannot fit a socket name,
so the same project always maps to the same database. One clear line explains
the relocation and points at CODEGRAPH_DB_PATH. Shallow checkouts keep their
existing location, and Windows is untouched since it uses named pipes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Four problems that together made the dashboard unusable on a fresh checkout.

The server never loaded .env. It read process.env only, so the graph
connection, embedding provider and API keys configured in the repository were
silently ignored. It now loads the nearest .env through the Node built-in,
feature-detected so the declared Node 20 floor still holds.

API_PORT was dead configuration. Both .env and docker-compose set it while
the server read PORT. Both are accepted now, and an unparseable value falls
back to the default instead of listening on port NaN.

CORS was pinned to port 3000. Next picks the next free port when 3000 is
taken, and every request from the dashboard was then rejected, which the UI
reported as "API server is not running" while the API was running fine. Any
loopback origin is accepted now, overridable with CODEGRAPH_CORS_ORIGINS for
a shared deployment. Foreign origins are still refused.

Finally, the built dashboard is served from the same origin as the API, which
removes the need for any CORS allowance in the shipped configuration. The
handler is written here rather than using serveStatic because that resolves
its root relative to the working directory and rejects absolute paths, which
does not work for a binary run from an arbitrary directory. Requests are
contained inside the root, covered by tests for encoded traversal, null bytes
and malformed percent-encoding.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The dashboard shared a Next app with the marketing site, so every visitor
downloaded the whole thing: 2,382 KB gzipped of client JavaScript, most of it
landing-page furniture the dashboard never imports. It needs seven UI
components and cytoscape.

Moving it into its own Vite build cuts the initial load to 107 KB gzipped, a
95 percent reduction. cytoscape was already a dynamic import, so it stays
lazy and loads when the graph mounts.

Shiki needed attention too. Importing codeToHtml from the shiki entry point
pulls in every bundled grammar, which produced 304 chunks and 9.9 MB of
output. The code preview only ever highlights twelve languages, so the
highlighter is now built from shiki core with exactly those, using the
JavaScript regex engine so the 600 KB WebAssembly payload never ships, and
the whole module is loaded on demand. That took the build to 18 files and
1.92 MB.

The API URL is resolved in one place and defaults to the same origin, since
the API serves these files.

The duplicate route is removed from apps/web so there is one dashboard rather
than two that drift. cytoscape and lib/cytoscape-config stay there because
the landing hero genuinely uses them.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…inary

The release gate ran pnpm audit --prod, which audits this workspace rather
than the artifact. The workspace passes only because root pnpm.overrides pins
a patched sharp, and package manager overrides are not inherited by anyone
installing from npm. A real install therefore resolves a vulnerable sharp
through @huggingface/transformers while CI reported clean.

audit:consumer resolves the published manifest the way npm would for an end
user and fails on any unacknowledged advisory at high severity or above. The
sharp advisory is acknowledged explicitly, with the reason it cannot be fixed
from here: every transformers release from 3.8.1 through 4.2.0 declares
sharp ^0.34.x, so no upstream version resolves to a patched one. An
acknowledgement that stops matching a real advisory also fails, so the list
cannot go stale quietly. SECURITY.md discloses it rather than hiding it.

The package now also ships the dashboard as a second binary. Bundling the two
servers separately emitted their shared payload twice and took the package
from 1.86 MB to 4.15 MB packed. A single split build brings that to 2.27 MB,
so the whole dashboard costs about 0.4 MB.

Both gates were extended to match: the validator checks both binaries and the
presence of the built UI, and the smoke test starts the packaged dashboard on
a free port, waits for health, and fetches a real hashed asset, so a broken
dashboard cannot ship.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
cognee aborted natively with "libc++ mutex lock failed" partway through
bench run-all, which earlier notes attributed to concurrent ingest_data task
starts. That was a symptom in the logs, not the cause. Ingest completes
before any query dispatches. The runner then fires three queries at once, and
the cognee adapter opens its Kuzu store in a fresh subprocess per query,
which Kuzu does not permit for one database directory.

maxQueryConcurrency is now part of the adapter contract and the runner clamps
its semaphore to it. cognee declares 1. Any future adapter with a
single-writer backend gets the same protection without touching the runner.
Verified end to end: cognee ingests and queries the fixture, ranking retry.ts
first for "function that retries failed requests".

The results now explain why cognee still has no score. The blocker is
inference cost, measured rather than assumed: 160 seconds and 31 generation
calls for 882 bytes of fixture code, which extrapolates to a multi-day local
run for the full battery. Publishing a column measured on a different corpus
size would not be a comparison.

A fairness caveat is recorded too. The adapter drives cognee's general text
pipeline, not its code path, because cognee-community-tasks-codify pins
cognee 0.5.6 against a 1.5.0 core.

Also resolves the corpus and benchmark script paths relative to the checkout
instead of a hardcoded home directory that no longer exists.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The api and web services referenced packages/api/Dockerfile and
packages/web/Dockerfile. Neither file has ever existed in this repository,
and packages/web is not a real path since the marketing site lives in
apps/web. Running docker compose --profile full up always failed.

Writing two untested Dockerfiles would just replace broken config with
unverified config, so the services are removed and a comment records what
replaced them: the API and dashboard now run as one process, via
pnpm dashboard from a checkout or npx codegraph-dashboard from the package.

The FalkorDB services, which do work, are untouched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Aug 19, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
v0-landing-page-build Skipped Skipped Aug 19, 2026 9:22pm

@augmentcode

augmentcode Bot commented Aug 19, 2026

Copy link
Copy Markdown
🤖 Augment PR Summary

Summary: This PR repairs search and dashboard startup behavior while publishing the dashboard as a second CLI binary.

  • Filters missing active-project directories so stale scopes do not suppress every search result.
  • Adds a scoped-search notice and logs unexpected vector-search failures.
  • Relocates overly deep embedded FalkorDBLite data paths to avoid Unix-socket limits.
  • Adds `.env` discovery, `API_PORT` handling, and flexible loopback CORS behavior.
  • Extracts the dashboard from the Next marketing app into a standalone Vite application.
  • Serves built dashboard assets from the API origin with SPA fallback and cache headers.
  • Uses a narrowly configured, lazily loaded Shiki highlighter to reduce dashboard output.
  • Packages dashboard assets and adds the `codegraph-dashboard` executable.
  • Extends release validation, smoke coverage, and consumer dependency auditing.
  • Adds adapter-specific query-concurrency limits for the Cognee benchmark integration.
  • Removes obsolete Compose services and makes benchmark scripts checkout-independent.

🤖 Was this summary useful? React with 👍 or 👎

@augmentcode augmentcode Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review completed. 2 suggestions posted.

Fix All in Augment

Comment augment review to trigger a new review at any time.

Comment thread packages/api/src/env.ts Outdated
Comment thread packages/graph/src/drivers/falkordblite.ts Outdated
CI rejected the branch with ERR_PNPM_OUTDATED_LOCKFILE. The npm package gained
@codegraph/api and @codegraph/dashboard as devDependencies, but the install
that followed was filtered to a single package, so the lockfile never recorded
them. Regenerated across the whole workspace and confirmed
pnpm install --frozen-lockfile now succeeds, which is what CI runs.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both raised in review on #22 and both correct.

loadEnvironment searched upward from the installed module directory. Under npx
or a global install that directory sits in a package cache whose ancestors have
nothing to do with the user's project, so the .env they configured would never
be found, defeating the point of the change for exactly the CLI use this branch
adds. It now searches from the working directory of the invoking process.

The embedded socket budget compared against the full documented sun_path
capacity. That buffer must also hold a terminating NUL, so a pathname occupying
the entire capacity still fails to bind. The budget now reserves that byte, with
tests pinning the boundary at exactly the limit and one over it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@Phoenixrr2113
Phoenixrr2113 merged commit 63cb9e6 into main Aug 19, 2026
12 checks passed
@Phoenixrr2113
Phoenixrr2113 deleted the feat/dashboard-and-search-fixes branch August 19, 2026 21:34

This branch was previously deployed

1 inactive deployment
Preview — 9f02216b Deployed Aug 19, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant