- Adds the Highlights block and groups the 164 entries the way 1.6.1's notes
are: New Features for the newly supported routes and newly indexed code,
Fixes under sub-headings (Windows; the background server and CLI; indexing;
across languages; then one per language family) so a skimmer finds their
area. Duplicates left by merges are folded together (the Windows console
window entry twice; two overlapping Vapor closure-route entries; three
Windows crash entries into one). No entry's wording is otherwise changed.
- The release workflow's "Verify every package is actually on the registry"
gave each package 60 s. 1.6.1 published all seven packages fine, but the
first took longer than that to appear and the run went red. It now waits up
to 5 minutes per package.
No viewer entries: those stay in docs/viewer-launch-changelog.md, and
`codegraph ui` stays behind CODEGRAPH_UI=1 (checked on a fresh build: absent
from --help, refused with the "not in this release yet" message).
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Three R1-era assumptions retired now that the kernel is the release's
headline rather than an optional speedup:
1. The kernel matrix drops continue-on-error (fail-fast stays false so
every platform leg reports). A Rust toolchain failure now blocks the
release instead of silently shipping wasm-only bundles under a
Rust-engine banner. First real risk it guards: the vendored-grammar-C
languages (kotlin/lua/scala/dart, incl. scala's 35MB parser.c) have
never compiled on these runners — no release has run since the kernel
merged.
2. The release-job gate expands from the two R1 suites to ALL
__tests__/kernel-*.test.ts (14 files today: contract, grammar-source
parity, and every language's walker byte-parity suite) — the glob
keeps it current as languages land.
3. A missing linux-x64 prebuild at the gate is now a hard failure (the
matrix guarantees it; absence means a wiring bug), and the artifact
download step loses its best-effort flag for the same reason.
No packaging changes needed: build-bundle.sh already stages
lib/kernel/codegraph-kernel.node per target and pack-npm.sh repacks
bundles verbatim into the per-platform npm packages.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Phase 0 of the Rust extraction-kernel migration (docs/design/
rust-kernel-migration-plan.md, now checked in with §3a recording the
shipped state):
- codegraph-kernel/ napi-rs crate: extractFile(path, content, language)
→ five flat buffers (meta/nodes/edges/refs/arena), one JS boundary
crossing per file. Node ids computed Rust-side, byte-identical to
generateNodeId (pinned by test vector). Reserved per-node metrics slot
for the Arc 3.2 code-metrics work.
- Generic .scm-driven emitter (@def.<kind>/@name/@ref.<kind> captures,
byte-range scope stack → ::-joined qualified names, contains edges,
refs attributed to the innermost enclosing symbol). Seed TS/JS queries
are smoke-level; R2 replaces them with the full port.
- Routing seam in extractFromSource with per-file wasm fallback.
DEFAULT_ROUTED is empty — no behavior change until a language passes
its equivalence gate (R3). Dev opt-in: CODEGRAPH_KERNEL_LANGS. Kill
switch: CODEGRAPH_KERNEL=0. Loader verifies ABI + kind tables before
routing; EDGE_KINDS became a runtime array because kind order is now
wire contract.
- Grammar-source parity: vendored TS/TSX/JS wasm grammars built from the
exact crate revisions (tree-sitter-typescript v0.23.2,
tree-sitter-javascript v0.25.0, checked-in parser.c, ts-cli 0.25.10) —
the tree-sitter-wasms builds were 2023-era, which the new
kernel-grammar-parity test caught on day one. Production TS/JS parsing
gets 2.5 years of grammar fixes; full suite green (2456 tests).
- Build/release wiring: scripts/build-kernel.sh + npm run build:kernel;
release.yml kernel prebuild matrix (continue-on-error — the kernel is
optional everywhere, bundles fall back to the wasm path); bundles stage
lib/kernel/codegraph-kernel.node; release job runs the kernel suites
with CODEGRAPH_KERNEL_EXPECT=1.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
All seven published packages (@colbymchenry/codegraph + six platform
bundles) now have this repo's release.yml configured as their trusted
publisher on npmjs.com, so publishes authenticate via the workflow's
OIDC identity instead of a long-lived NPM_TOKEN. The runner upgrades to
npm 11 (trusted publishing needs >= 11.5; Node 22 bundles npm 10) and
setup-node no longer writes a token-referencing .npmrc.
README gains a 'Verified releases' section + badges: how npm provenance
and the GitHub Release attestations work and the commands to verify them
(npm audit signatures / gh attestation verify).
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Every published artifact is now cryptographically verifiable as built by
this repo's Release workflow: npm publishes carry npm provenance (OIDC,
shows the Provenance badge on npmjs.com), and the GitHub Release bundles
+ SHA256SUMS get signed build attestations via
actions/attest-build-provenance, verifiable with
`gh attestation verify <file> -R colbymchenry/codegraph`.
pack-npm.sh now writes a repository field into the generated shim and
per-platform package.jsons — npm --provenance refuses to publish without
one matching the repo — and the root package.json gains the same field.
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The Release workflow's auto-promote ([Unreleased] → [<version>] in
CHANGELOG.md) and auto-sync (package-lock.json on version drift) steps
both `git push origin HEAD:main` using the default GITHUB_TOKEN. That
fails against the "Require PR approval for main branch" ruleset:
remote: error: GH013: Repository rule violations found for refs/heads/main.
remote: - Changes must be made through a pull request.
The ruleset's bypass_actors only contains the Admin repo role. The
obvious fix — adding the GitHub Actions integration to bypass_actors —
is rejected by GitHub on user-owned (non-org) repos:
Validation Failed: Actor GitHub Actions integration must be part
of the ruleset source or owner organization.
So instead, authenticate the checkout (and therefore all downstream git
operations) as the maintainer via a fine-grained PAT. The PAT owner is
admin → bypasses the ruleset → push lands. Setup is one-time: create a
fine-grained PAT scoped to contents:write on this repo, add it as the
RELEASE_PAT secret. After that, future releases auto-promote cleanly.
Hidden the same way previously: 0.9.5's CHANGELOG was hand-promoted
before triggering Release, so the workflow's promote step short-
circuited on `git diff --quiet -- CHANGELOG.md` and never tried the
push. 0.9.5 also exposed the same bug in the lock-sync step — patched
manually after the fact in #440. 0.9.6 is the first release to actually
hit the bug.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Paired with the maintainer-preference clarification that Claude
shouldn't proactively bump versions, and that version bumps are often
made via the GitHub web UI (single-file edit to package.json only).
**Workflow change** (`.github/workflows/release.yml`):
Adds a 'Sync package-lock.json if version drifted' step BEFORE the
existing `npm ci` step. It:
1. Reads the version field from both package.json and package-lock.json.
2. If they match, no-ops.
3. Otherwise runs `npm install --package-lock-only --ignore-scripts`
which rewrites just the lock file's version fields (top-level +
packages."") without touching node_modules — ~100ms locally.
4. Auto-commits + pushes the lock-file change back to main with
`[skip ci]`, same pattern as the prepare-release auto-promote step.
Effect: a maintainer can now edit ONLY package.json (e.g. via the
GitHub web UI) and trigger the workflow. The previously-fatal
`npm ci` mismatch is detected, fixed, and committed before the
build proceeds. Editing both files locally still works — the sync
step just no-ops in that case.
Verified the `npm install --package-lock-only --ignore-scripts`
mechanic against a synthetic drifted lock file locally: both the
top-level `version` and `packages."".version` get rewritten to
match package.json in one command.
**CLAUDE.md change** (§ Release flow):
Adds an explicit 'Claude does NOT bump the version unless explicitly
asked' rule. Documents that the maintainer typically bumps
package.json via the GitHub web UI (single-file edit). Explains the
new sync step and lists the workflow's 5-step internals (sync lock →
promote CHANGELOG → bundles → release → npm) for future Claude
sessions to understand.
940/942 existing tests still pass; no new tests needed (the sync step
is a thin wrapper around an npm CLI invocation; the verification was
the local synthetic-drift smoke test in the commit-message above).
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Fixes the silent-sparse-release-notes failure mode that surfaced on
v0.9.5: the Release workflow used to do a literal
`extract-release-notes.mjs <version>` lookup with an `[Unreleased]`
fallback. The fallback only triggered when the `[<version>]` block
DIDN'T exist at all — and in practice maintainers sometimes had a
sparse `[<version>]` block pre-populated (e.g. one early fix
documented before the rest of the work landed). The workflow then
extracted that sparse block, ignoring the much-larger `[Unreleased]`
section above it. Result: the published v0.9.5 release notes were
missing the shared MCP daemon, the per-file staleness banner, the
Objective-C indexing, AND the Mixed iOS/RN/Expo bridging.
The fix is a new `scripts/prepare-release.mjs` step that runs at the
start of the workflow:
Case A — `[<version>]` does not yet exist:
Rename `[Unreleased]` → `[<version>] - <today>`. Add a fresh
empty `[Unreleased]` above. The common path.
Case B — `[<version>]` exists AND `[Unreleased]` has content:
Merge `[Unreleased]`'s sub-sections (### Added / ### Fixed /
### Changed / ### Removed / ### Deprecated / ### Security) into
the corresponding sub-sections of `[<version>]`. Unmatched
sub-sections are appended. Then empty `[Unreleased]`.
Case C — `[Unreleased]` is empty:
No-op. Re-runs of the workflow are safe.
After the script runs, the workflow auto-commits + pushes the
CHANGELOG.md change back to main (with a `[skip ci]` tag in the
commit body) so future runs and human eyes both see the same
on-disk truth.
9 unit tests (`__tests__/prepare-release.test.ts`) cover all three
cases, idempotency, version-source precedence, and an
extract-release-notes.mjs integration check.
Workflow comment header rewritten to reflect the new flow.
Trigger reminder going forward: bump package.json. CHANGELOG entries
can live under `[Unreleased]` — the workflow takes care of moving
them.
937/939 existing tests pass (2 pre-existing skips); +9 new tests.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* udpated matrix
* feat(site): add landing page + Starlight docs site
Astro + Starlight site in site/ — a flat/paper editorial landing page
plus 18 docs pages seeded from the README. Monochrome theme, hairline
rules, square corners, live GitHub star count, light default + dark
toggle. Deploys to GitHub Pages via .github/workflows/deploy-site.yml.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Installing from a registry mirror (npmmirror/cnpm) that hadn't mirrored the
per-platform optionalDependency left codegraph failing with "no prebuilt
bundle for <platform>" — npm treats an unfetchable optional dep as success and
silently skips it. The npm-shim now self-heals: when the bundle is missing it
downloads the matching archive from GitHub Releases (checksum-verified, with a
download timeout) and caches it, so a global install works on any registry.
release.yml now publishes SHA256SUMS and triggers an npmmirror sync after
publish. Adds hermetic tests for the shim (resolution, cache reuse, disable
knob, download + checksum match/mismatch/absent).
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
GitHub deprecated Node.js 20 for actions: actions/checkout@v4 and
actions/setup-node@v4 run on Node 20 and emit a deprecation warning.
Node 24 becomes the forced default on 2026-06-02 and Node 20 is removed
on 2026-09-16. Bump both to @v6 (Node 24). Config is unchanged —
node-version: 22 and registry-url are both supported in v6.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The first 0.9.0 run published 6/7 npm packages: npm printed
`+ @colbymchenry/codegraph-linux-x64@0.9.0` but the registry never persisted it
(a known npm flake), so the job went green while linux-x64 npm installs were
broken. Now:
- the GitHub Release step is idempotent (create, else upload --clobber);
- the publish loop skips packages already on the registry, so a re-run only fills
gaps;
- a new verify step queries the registry (with retries) and fails the job if any
package@version is missing — green now means actually shipped.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(db): eliminate concurrent-read "database is locked"; add node:sqlite backend (#238)
WAL + busy_timeout were already enabled, so the issue's suggested fix was a
no-op. The real causes, addressed here:
- busy_timeout is now set first (before journal_mode) and lowered 120s -> 5s,
so open-time pragmas wait out a lock instead of hanging for two minutes.
- getCodeGraph no longer opens a second connection to the default project when
a tool passes its own projectPath (the in-process lock amplifier).
- The wasm fallback (no WAL) gets a bounded read-retry on SQLITE_BUSY.
- New: node:sqlite backend, preferred over wasm, so installs whose native
better-sqlite3 build fails land on a real-WAL backend instead of no-WAL wasm.
- codegraph status / codegraph_status now report the effective journal mode, so
a lock report is triageable (wal vs delete).
- CLI hard-blocks Node < 20 to actually enforce the engines floor.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* refactor(db)!: node:sqlite is the sole backend; drop better-sqlite3 + wasm
Now that distribution will bundle a Node 24 runtime, node:sqlite (real SQLite
with WAL + FTS5) is always available. Collapse the three-backend adapter to
node:sqlite only and remove the machinery the other two needed:
- Remove better-sqlite3 (optionalDependency) and node-sqlite3-wasm (dependency).
- Remove WasmDatabaseAdapter, the named->positional param translation, the
SQLITE_BUSY read-retry, the wasm fallback banner, the backend env override,
and the native/node-sqlite/wasm selection chain.
- createDatabase now opens node:sqlite directly, with a clear error pointing at
the bundled release / Node 22.5+ when the module is absent.
- NodeSqliteAdapter.close() is idempotent and pragma() supports { simple }, to
match the better-sqlite3 behavior callers relied on.
- status (CLI + MCP) reports the single node:sqlite backend; journal-mode
diagnostics and the getCodeGraph single-connection fix are retained.
- Tests repointed off better-sqlite3 onto node:sqlite.
Net -1044 lines. Running from source now requires Node 22.5+.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(dist): self-contained bundle prototype (vendored Node + install channels)
Phase 3 of the node:sqlite migration: ship a vendored Node runtime so CodeGraph
runs with no system Node and no native build (node:sqlite is built in).
- scripts/build-bundle.sh: build a per-platform archive (official Node + dist +
prod deps + launcher). Same recipe per platform; pins Node v24.16.0.
- install.sh: curl|sh installer (no Node required) — detects os/arch, pulls the
archive from Releases, symlinks onto PATH; re-run to upgrade, --uninstall to
remove. The VPS/SSH path.
- scripts/npm-shim.js: thin launcher for the npm channel — resolves the
per-platform optionalDependency bundle and execs it, so `npm i -g` keeps
working and the real work runs on the bundled Node regardless of the user's.
- BUNDLING.md: distribution design + release-pipeline TODO (CI matrix, platform
packages, code signing, brew, retiring the Node-version gate).
Validated end-to-end: darwin-arm64 and linux-x64 bundles both run init + index +
status (Backend: node:sqlite, Journal: wal) + FTS query with NO system Node —
linux-x64 verified in a clean ubuntu:24.04 amd64 container. Release archives are
gitignored; CI will produce and upload them.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(dist): add Windows PowerShell installer (install.ps1)
The `irm … | iex` one-liner for Windows, mirroring install.sh: detect arch,
pull the matching bundle from Releases, extract to %LOCALAPPDATA%\codegraph,
add it to user PATH. Re-run to upgrade. (Windows bundle production in
build-bundle.sh is still TODO.)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(dist): release workflow + npm packaging; README/CHANGELOG for bundled distro
- .github/workflows/release.yml: manually-triggered (workflow_dispatch) release
matrix. Builds a self-contained bundle per platform on its own runner
(darwin-arm64/x64, linux-x64/arm64), publishes a GitHub Release with all
archives, and publishes the npm thin-installer (shim + per-platform packages).
Windows targets are TODO (build-bundle.sh is unix-only).
- scripts/pack-npm.sh: assemble the npm packages from built bundles — per-platform
packages tagged os/cpu + the main shim package with them as optionalDependencies
(esbuild pattern). Proven locally: npm-install the tarballs, run via the shim,
resolves the bundle and runs on the bundled Node 24 (node:sqlite / WAL).
- README: install section now leads with the no-Node one-liners (curl|sh, irm|iex)
then npm/npx; "bundled · none required" badge.
- CHANGELOG: standout headline for the self-contained release, plus Added/Changed/
Removed for the install channels, node:sqlite backend, and dropped deps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(dist): Windows bundles + single-trigger release workflow
- build-bundle.sh: add win32-x64 / win32-arm64 targets — download Node's Windows
zip, bundle node.exe + a .cmd launcher, output a .zip. Verified structurally
(PE32+ node.exe, CRLF .cmd, portable node_modules). Since there are no native
addons, any target builds on any OS, so the whole matrix builds on one runner.
- pack-npm.sh: handle .zip bundles and win32 packages (os: win32, node.exe).
- release.yml: simplified to your spec — manual trigger reads the version from
package.json, builds all platform bundles, creates the GitHub Release with notes
pulled from CHANGELOG.md, and publishes the npm shim + platform packages.
- BUNDLING.md: Windows + build-anywhere notes; release pipeline documented.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>