Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
c4cc763
Restore `codedb serve --port` on Zig 0.16
justrach Apr 22, 2026
2fbc66c
Route MCP status output to stderr
justrach Apr 22, 2026
aaba92e
Make `codedb serve` port configurable via CODEDB_PORT
justrach Apr 22, 2026
c9d773c
O(1) `findSymbol` via complete symbol_index
justrach Apr 22, 2026
14c3160
Make `codedb serve` opt-in; require CODEDB_PORT with no default
justrach Apr 22, 2026
8b43e89
Revert `codedb serve` gate; default port 6767
justrach Apr 22, 2026
74ba881
Harden `server.isPathSafe` against backslash and null-byte paths
justrach Apr 22, 2026
6ef7185
Resolve `/file/read` paths against the indexed root
justrach Apr 22, 2026
fbb8b49
findAllSymbols: always merge index + outline scan
justrach Apr 22, 2026
814c03a
Merge feat/local-server-trial into release/0.2.579
justrach Apr 22, 2026
3233de4
Bump semver to 0.2.579
justrach Apr 22, 2026
1f04fad
codedb_remote: add 'wiki' backend (wiki.codes) alongside codegraff (#…
justrach Apr 22, 2026
56af2f6
codedb_remote: reject empty query on actions that consume it
justrach Apr 22, 2026
3988c1f
mcp: refresh last_activity during long bundle processing (#278)
justrach Apr 22, 2026
e7c9fd4
Add native C outline parser
justrach Apr 25, 2026
3e6dae9
Merge pull request #320 from justrach/fix/native-c-parser
justrach Apr 25, 2026
a514ea8
Merge pull request #316 from justrach/fix/remote-require-query
justrach Apr 25, 2026
d58e284
Merge pull request #317 from justrach/fix/278-bundle-activity-refresh
justrach Apr 25, 2026
ad52783
Add language detection for common extensions
justrach Apr 25, 2026
654ff5c
Merge pull request #321 from justrach/fix/extension-language-coverage
justrach Apr 25, 2026
27b8d81
Parse outlines for common detected extensions
justrach Apr 25, 2026
4e5864f
Merge pull request #322 from justrach/fix/common-extension-parsers
justrach Apr 25, 2026
3ca698b
Add golden parser checks for common extensions
justrach Apr 26, 2026
c83533b
Merge pull request #323 from justrach/fix/extension-parser-golden-tests
justrach Apr 26, 2026
5b76d9c
Fix benchmark noise status reporting
justrach Apr 26, 2026
07ac438
Merge pull request #324 from justrach/fix/bench-report-noise-status
justrach Apr 26, 2026
f6f12b6
Speed up snapshot JSON generation
justrach Apr 26, 2026
47a2f1a
Merge pull request #325 from justrach/fix/snapshot-json-performance
justrach Apr 26, 2026
d99041b
Cache snapshot responses by store sequence
justrach Apr 26, 2026
ae587b5
Merge pull request #326 from justrach/fix/snapshot-response-cache
justrach Apr 26, 2026
32b5e3f
Point codedb_remote at api.wiki.codes
justrach Apr 26, 2026
944e4ad
Merge pull request #327 from justrach/fix/wiki-api-host
justrach Apr 26, 2026
9a70fb4
Extend MCP idle timeout to one hour
justrach Apr 26, 2026
4e38a29
Merge pull request #328 from justrach/fix/mcp-hour-timeout
justrach Apr 26, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 16 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@
> **Alpha software — API is stabilizing but may change**
>
> codedb works and is used daily in production AI workflows, but:
> - **Language support** — Zig, Python, TypeScript/JavaScript, Rust, Go, PHP, Ruby, HCL, R, Dart/Flutter
> - **Parser support** — Zig, C/C++, Python, TypeScript/JavaScript, Rust, Go, PHP, Ruby, HCL, R, Dart/Flutter
> - **Lightweight outline support** — Java, Kotlin, Svelte, Vue, Astro, shell, CSS/SCSS, SQL, protobuf, Fortran, LLVM IR, MLIR, and TableGen
> - **No auth** — HTTP server binds to localhost only
> - **Snapshot format** may change between versions
> - **MCP protocol** is JSON-RPC 2.0 over stdio (stable)
Expand All @@ -53,7 +54,7 @@
| Auto-registration in Claude, Codex, Gemini, Cursor | |
| Polling file watcher with filtered directory walker | |
| Portable snapshot for instant MCP startup | |
| Singleton MCP with PID lock + 10min idle timeout | |
| Singleton MCP with PID lock + 1h idle timeout | |
| Sensitive file blocking (.env, credentials, keys) | |
| Codesigned + notarized macOS binaries | |
| SHA256 checksum verification in installer | |
Expand Down Expand Up @@ -137,25 +138,30 @@ codedb hot # recently modified files

### `codedb_remote` — Cloud Intelligence

Query any public GitHub repo without cloning it. Powered by `codedb.codegraff.com`.
Query any public GitHub repo without cloning it. The default backend uses `codedb.codegraff.com`; `backend="wiki"` uses `api.wiki.codes` for code intelligence plus dependency/security artifacts.

```
# Get the file tree of an external repo
# Get the file tree of an external repo via the default backend
codedb_remote repo="vercel/next.js" action="tree"

# Search for code in a dependency
codedb_remote repo="justrach/merjs" action="search" query="handleRequest"

# Get symbol outlines
codedb_remote repo="justrach/merjs" action="outline"
# Exact symbol lookup through api.wiki.codes
codedb_remote repo="justrach/codedb" backend="wiki" action="symbol" query="buildSnapshot"

# Get repo metadata
codedb_remote repo="justrach/merjs" action="meta"
# Check dependency CVE evidence; scope can be runtime or all
codedb_remote repo="axios/axios" backend="wiki" action="cves" scope="runtime"

# Raw wiki slugs are accepted for repos that are indexed that way
codedb_remote repo="chromium" backend="wiki" action="policy"
```

**Actions:** `tree`, `outline`, `search`, `meta`
**Default actions:** `tree`, `outline`, `search`, `meta`

**Wiki actions:** `tree`, `outline`, `search`, `symbol`, `policy`, `deps`, `score`, `cves`, `commits`, `branches`, `dep-history`

**Note:** This tool calls `codedb.codegraff.com` via HTTPS. No API key required. The service must be available for this tool to work.
**Note:** This tool calls remote HTTPS services. No API key required. The selected service must be available for this tool to work.

### CLI Commands

Expand Down
2 changes: 1 addition & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ JSON-RPC 2.0 over stdio with Content-Length framing. Implements the Model Contex
| `codedb_status` | Index status |
| `codedb_snapshot` | Full snapshot |
| `codedb_bundle` | Batch multiple queries (max 20 ops) |
| `codedb_remote` | Query GitHub repos via codedb.codegraff.com |
| `codedb_remote` | Query GitHub repos via codedb.codegraff.com or api.wiki.codes |
| `codedb_projects` | List locally indexed projects |
| `codedb_index` | Index a local folder |
**Safety:** path validation, oversized message handling (drains >1MB lines instead of killing the loop).
Expand Down
32 changes: 21 additions & 11 deletions scripts/compare-bench.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,28 @@ def pct_change(base_ns: int, head_ns: int) -> float:
return ((head_ns - base_ns) / base_ns) * 100.0


def render_markdown(rows: list[tuple[str, int, int, float]], threshold_pct: float) -> str:
def status_for(delta_pct: float, abs_delta_ns: int, threshold_pct: float, min_abs_ns: int) -> str:
if delta_pct <= threshold_pct:
return "OK"
if abs_delta_ns <= min_abs_ns:
return "NOISE"
return "FAIL"


def render_markdown(rows: list[tuple[str, int, int, float, int]], threshold_pct: float, min_abs_ns: int) -> str:
lines = [
"## Benchmark Regression Report",
"",
f"Threshold: {threshold_pct:.2f}%",
f"Thresholds: {threshold_pct:.2f}% and {min_abs_ns:,} ns absolute delta",
"",
"`NOISE` means the percentage threshold was exceeded, but the absolute delta was too small to fail CI.",
"",
"| Tool | Base (ns) | Head (ns) | Delta | Status |",
"| --- | ---: | ---: | ---: | --- |",
"| Tool | Base (ns) | Head (ns) | Delta | Abs Delta (ns) | Status |",
"| --- | ---: | ---: | ---: | ---: | --- |",
]
for tool, base_ns, head_ns, delta in rows:
status = "FAIL" if delta > threshold_pct else "OK"
lines.append(f"| `{tool}` | {base_ns} | {head_ns} | {delta:+.2f}% | {status} |")
for tool, base_ns, head_ns, delta, abs_delta in rows:
status = status_for(delta, abs_delta, threshold_pct, min_abs_ns)
lines.append(f"| `{tool}` | {base_ns} | {head_ns} | {delta:+.2f}% | {abs_delta:+d} | {status} |")
return "\n".join(lines) + "\n"


Expand All @@ -57,21 +67,21 @@ def main() -> int:
return 1
common = sorted(set(base) & set(head))

rows: list[tuple[str, int, int, float]] = []
rows: list[tuple[str, int, int, float, int]] = []
failures: list[str] = []

for tool in common:
base_ns = int(base[tool]["avg_latency_ns"])
head_ns = int(head[tool]["avg_latency_ns"])
delta = pct_change(base_ns, head_ns)
abs_delta = head_ns - base_ns
rows.append((tool, base_ns, head_ns, delta))
rows.append((tool, base_ns, head_ns, delta, abs_delta))
# Only flag as regression if BOTH percentage AND absolute delta exceed thresholds
# This prevents false positives on fast tools where CI noise dominates
if delta > args.threshold_pct and abs_delta > args.min_abs_ns:
failures.append(f"{tool} regressed by {delta:.2f}%")
failures.append(f"{tool} regressed by {delta:.2f}% ({abs_delta:+d} ns)")

report = render_markdown(rows, args.threshold_pct)
report = render_markdown(rows, args.threshold_pct, args.min_abs_ns)
sys.stdout.write(report)

if args.markdown_out:
Expand Down
35 changes: 35 additions & 0 deletions scripts/test_compare_bench.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env python3
from __future__ import annotations

import importlib.util
from pathlib import Path
import unittest


SCRIPT = Path(__file__).with_name("compare-bench.py")
spec = importlib.util.spec_from_file_location("compare_bench", SCRIPT)
assert spec is not None
compare_bench = importlib.util.module_from_spec(spec)
assert spec.loader is not None
spec.loader.exec_module(compare_bench)


class CompareBenchTests(unittest.TestCase):
def test_small_absolute_regression_is_noise(self) -> None:
self.assertEqual(compare_bench.status_for(22.54, 11_399, 10.0, 50_000), "NOISE")

def test_large_absolute_regression_fails(self) -> None:
self.assertEqual(compare_bench.status_for(12.0, 75_000, 10.0, 50_000), "FAIL")

def test_report_explains_noise_status(self) -> None:
report = compare_bench.render_markdown(
[("codedb_read", 50_580, 61_979, 22.54, 11_399)],
10.0,
50_000,
)
self.assertIn("50,000 ns absolute delta", report)
self.assertIn("| `codedb_read` | 50580 | 61979 | +22.54% | +11399 | NOISE |", report)


if __name__ == "__main__":
unittest.main()
Loading
Loading