Fix search, extract the dashboard, and ship it as a second binary - #22
Merged
Merged
Conversation
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>
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
🤖 Augment PR SummarySummary: This PR repairs search and dashboard startup behavior while publishing the dashboard as a second CLI binary.
🤖 Was this summary useful? React with 👍 or 👎 |
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>
This branch was previously deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.
searchByVectorhad a barecatchreturning[], 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:
falkordblitederives its Unix socket from the data directory and offers no override, so a moderately deep checkout exceeded the 104 bytesun_pathlimit on macOS and every endpoint failed. The data directory now falls back to a short deterministic path under~/.codegraph/graphs/<hash>..envwas never loaded. The server readprocess.envonly, so the graph connection, embedding provider and API keys were silently ignored.API_PORTwas dead configuration..envand docker-compose set it; the server readPORT.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
codeToHtmlfrom theshikientry 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 --prodaudits this workspace, not the artifact. The workspace passes only because rootpnpm.overridespins a patchedsharp, and overrides are not inherited by anyone installing from npm. A real install resolves a vulnerablesharpthrough@huggingface/transformerswhile CI reported clean.audit:consumerresolves the published manifest the way npm would for an end user. Thesharpadvisory 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
libc++ mutexabort was CGBench dispatching three concurrent queries against a Kuzu store that permits one process, not the concurrentingest_datastarts an earlier note blamed. Adapters can now cap their own query concurrency. The results explain why cognee still has no score, with measured numbers.apiandwebservices, which referenced Dockerfiles that have never existed in this repo.Verification
Run against the committed tree with
packages/dashboard/distandpackages/npm-package/distdeleted first, since both are gitignored and absent on a fresh checkout:release:check: build, validate, consumer audit, smoke with dashboard verification🤖 Generated with Claude Code