Commit Graph

687 Commits

Author SHA1 Message Date
Martin Vogel a688d85cc8 Merge pull request #1093 from PR9000/freebsd-hw-physmem
fix(foundation): use HW_PHYSMEM for physical memory detection on FreeBSD
2026-07-16 17:33:20 +02:00
Martin Vogel 5d150ea051 Merge pull request #1109 from DeusData/fix/601-cypher-exec-deadline
fix(cypher): add a wall-clock execution deadline to abort runaway queries (#601)
2026-07-16 04:56:50 +02:00
Martin Vogel 3d6aa6791d Merge pull request #1048 from DeusData/fix/999-ci-config-infra-routes
fix(pipeline): stop CI/tooling config URLs from minting infra Route nodes
2026-07-16 04:19:42 +02:00
Martin Vogel 6bd11ffb58 fix(cypher): add a wall-clock execution deadline to abort runaway queries
DCO / dco (push) Has been cancelled
An unbounded whole-graph OPTIONAL MATCH or a GROUP BY that produces roughly one
group per node does O(bindings x groups) work in execute_return_agg and can run
for minutes on a large graph before emitting a single row. The 100k row ceiling
never fires (no rows are produced), so query_graph just hangs with no partial
result and no error (#601).

Arm a monotonic wall-clock budget (default 30s) at query entry and check it
(throttled, every 1024 iterations) in the scan, relationship-expansion and
aggregation hot loops. On expiry the query aborts with a clear, actionable error
instead of hanging. A thread-local test hook forces the budget so the guard is
covered by a deterministic reproduce-first test; a companion test confirms the
default budget does not false-positive on a normal query.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-16 03:09:27 +02:00
Martin Vogel 90d7315cf9 Merge pull request #1108 from DeusData/fix/964-1077-fqn-collision
fix(fqn): preserve full filename in File-node QNs so sibling files don't collide
2026-07-16 02:52:00 +02:00
Martin Vogel 848375912d Merge pull request #1098 from JhohanBustamante/fix/cypher-composite-props
fix(cypher): return whole value for composite and escaped properties
2026-07-16 02:47:38 +02:00
Martin Vogel b0aead257e Merge pull request #991 from harshitaajoshi/fix/cypher-coalesce-where-874
fix(cypher): support coalesce() and other multi-arg scalar functions in WHERE (#874)
2026-07-16 02:44:33 +02:00
Martin Vogel 81e7b73647 Merge remote-tracking branch 'origin/main' into HEAD
DCO / dco (push) Has been cancelled
# Conflicts:
#	tests/test_lang_contract.c
2026-07-16 02:31:18 +02:00
Martin Vogel 2308ae084e Merge pull request #940 from WarGloom/codex/fix-sqlite-writer-atomic-publish
Fix SQLite writer atomic cache publish
2026-07-16 02:11:27 +02:00
Martin Vogel 91d1a23161 Merge pull request #1043 from WarGloom/agent/fix-mcp-structured-content
fix(mcp): return structured compact results
2026-07-16 02:01:41 +02:00
Martin Vogel 751752bd21 fix(fqn): preserve full filename in File-node QNs so sibling files don't collide
DCO / dco (push) Has been cancelled
cbm_pipeline_fqn_compute stripped the file extension for EVERY qualified
name, including File-node QNs (name=="__file__"). Two different files
whose names share a stem therefore collided on the File QN and the
graph kept only one node per stem:

- .env / .env.local / .env.production all strip to ".env" — only one
  survives per directory (#1077).
- a C/C++ header and its same-stem source (NodeController.h vs .cpp)
  strip to the same stem, so the header got no File node of its own,
  leaving it disconnected (#964's remaining half after #983 fixed the
  include→Class resolution).

File-node QNs now keep the full filename (tokenize_path splits on '/'
only, so the extension rides in the last segment and stays unique).
Extension stripping is retained for MODULE/symbol QNs (name==NULL or a
symbol name) — that stem unification is load-bearing for C/C++
declaration↔definition cross-file resolution, and is left untouched.
All 26 __file__ QN sites route through this one function, so node
creation and every lookup stay consistent.

Reproduce-first:
- fqn_file_qn_preserves_dotfile_variants_issue1077 and
  fqn_file_qn_distinguishes_same_stem_header_source_issue964 assert the
  distinct File QNs (RED before: both collide to the stripped stem).
- fqn_module_qn_still_strips_extension guards that module QNs are
  unaffected.
- repro_issue964 now asserts the header keeps its own File node AND is
  connected (CONTAINS_FILE + DEFINES the class it declares), matching
  the reporter's zero-inbound disconnection metric — GREEN.

Closes #1077
Closes #964

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-16 01:21:45 +02:00
Martin Vogel 548927a849 Merge pull request #1106 from DeusData/fix/1085-jsx-alias-calls
fix(pipeline): restore parallel CALLS resolution for LSP-unresolvable targets
2026-07-16 01:14:09 +02:00
Pedro Ramos 08cb92f320 Merge branch 'main' into freebsd-hw-physmem 2026-07-15 23:28:09 +01:00
Harshita Joshi 57cd3f9e78 Merge branch 'main' into fix/cypher-coalesce-where-874 2026-07-15 16:59:09 -05:00
Martin Vogel 4c60111beb Merge pull request #983 from Sinjan-Debnath/main
fix: resolve C/C++ includes to header file targets by matching stems
2026-07-15 23:54:27 +02:00
Martin Vogel 8c394658b9 fix(pipeline): restore parallel CALLS resolution for LSP-unresolvable targets
DCO / dco (push) Has been cancelled
The parallel resolver dropped a CALLS edge whenever the LSP produced a
resolution whose callee_qn was not a node in the graph buffer: the
registry fallback lived in an else that ran only when NO LSP resolution
existed, so an LSP-with-unresolvable-target left res empty and the edge
was discarded outright. The sequential pass falls THROUGH to the
registry resolver in the same situation.

This diverged the two pipelines on the exact intersection the reporter
identified (#1085): a JSX component imported through a tsconfig paths
alias. The TS LSP resolves the element ref to an alias-path QN that
never matches a def node, so lsp_target is NULL and the parallel path
dropped it — while sequential resolved it via the import_map /
unique_name registry path. On a Next.js repo this silently removed
~21% of the call graph (every alias-imported JSX composition edge), and
the parallel path is the default above 50 files, so the default index
was the broken one.

The fix runs the registry fallback whenever the LSP did not yield a
gbuf-resolvable target, matching the sequential fall-through and
restoring seq/parallel parity.

Reproduce-first: calls_jsx_component_via_tsconfig_alias_parallel_issue1085
indexes the alias+JSX shape through the parallel path (et_index_parallel
pads past the 50-file threshold) and asserts the CALLS edges land on the
component. RED before (0 edges), GREEN after.

Closes #1085

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-15 23:43:52 +02:00
Martin Vogel 23f262c4b8 Merge pull request #995 from spde/fix/incremental-file-node-basename
fix(incremental): name File nodes by basename, matching the full pipeline
2026-07-15 22:59:44 +02:00
Martin Vogel 807a4a3129 Merge pull request #1046 from metehanulusoy/fix/missed-shadow-project-listing
fix(mcp): ignore ::missed shadow rows when resolving a db's project name
2026-07-15 22:38:07 +02:00
KolisCode 48fa9cbc03 fix(cypher): return whole value for composite and escaped properties
json_extract_prop() scanned a non-string property up to the first ',' and a
string property up to the first '"', ignoring nesting and backslash escapes.
Any array/object property was therefore truncated at its first INTERNAL comma,
and any string containing an escaped quote was cut short.

    decorators: ["@Roles('OWNER', 'ADMIN')","@Get()"]
    projected as: ["@Roles('OWNER'

This makes decorator/route/authz queries unusable on frameworks whose
decorators take multiple arguments (NestJS, Angular, Spring). Values are now
copied as balanced constructs, honoring string state and escape pairs; scalar
and plain-string paths are unchanged.

Signed-off-by: KolisCode <jhohantma@gmail.com>
2026-07-14 22:31:44 -05:00
Pedro Ramos 345ed4d3bc fix(foundation): use HW_PHYSMEM for physical memory detection on FreeBSD
Signed-off-by: Pedro Ramos <131530838+pr9000@users.noreply.github.com>
2026-07-15 00:44:30 +01:00
Harshita Joshi feae294c82 Merge branch 'main' into fix/cypher-coalesce-where-874 2026-07-14 18:42:59 -05:00
Martin Vogel feadbe1955 Merge pull request #467 from isc-tdyar/pr/objectscript-language-support
feat(objectscript): InterSystems IRIS ObjectScript language support
2026-07-15 01:33:19 +02:00
Harshita Joshi 755ffe57a5 fix(cypher): support coalesce() and other multi-arg scalar functions in WHERE (#874)
Signed-off-by: Harshita Joshi <j.harshitaa06@gmail.com>
2026-07-14 17:27:00 -05:00
Martin Vogel 6207d16fdf fix(review): keep vendored scanners byte-identical; wide-safe XML sniff
Two review items applied maintainer-side to save a roundtrip:

1. Restore both vendored ObjectScript scanner.c files to the pristine
   upstream bytes (a formatter pass had rewritten indentation/braces).
   Vendored grammar files stay byte-for-byte upstream except for the
   include repoint documented in MANIFEST.md - style churn breaks
   upstream diffability on re-vendor.
2. The Studio Export XML sniff in detect_file_language used a raw
   fopen on a repository path; cbm_fopen keeps it working on
   non-ASCII Windows paths (project rule, same class as #996).

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-15 00:04:05 +02:00
Martin Vogel aa2366811b fix: eliminate installer filesystem races
DCO / dco (push) Has been cancelled
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-14 21:13:52 +02:00
Martin Vogel 50df0997cf fix: scope legacy shim cleanup to Windows
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-14 19:25:45 +02:00
Martin Vogel 5ae6ef7875 fix: migrate Windows Claude hook scripts safely
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-14 19:08:54 +02:00
Nikita Bige 45b9a5c5e1 fix(sqlite_writer): publish rebuilt db atomically
Keep the live database visible until a synced temporary generation can
replace it. Preserve destination sidecars on replacement failure and use
UTF-8-safe Windows file operations.

Signed-off-by: Nikita Bige <wargloom@gmail.com>
2026-07-13 11:43:00 +03:00
Martin Vogel 9cda693acb fix: converge exact-owned hook updates
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-13 06:28:17 +02:00
Martin Vogel ecc6a5fdcd fix: migrate legacy Windows hook commands
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-13 05:21:36 +02:00
Martin Vogel 62d191b6d1 fix: restore cross-platform lint and builds
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-13 02:46:04 +02:00
Martin Vogel a537d3bd84 fix(cli): make Windows Claude hooks shell portable
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-13 02:18:10 +02:00
Martin Vogel 2040488cf4 fix(cli): preserve hook compatibility after rebase
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-13 02:00:44 +02:00
Martin Vogel d6c9d28bf5 style: apply current C formatting
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-13 02:00:32 +02:00
Martin Vogel f0db224140 feat: add coverage-aware agent integrations
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-13 01:50:03 +02:00
Martin Vogel a3903caa0b feat(cli): expand agent integration coverage
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-13 01:50:02 +02:00
Martin Vogel 37880b62e8 fix(store): reject null search handles
Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-13 01:48:29 +02:00
Martin Vogel 2469ecc3a7 Merge pull request #1059 from DeusData/fix/952-laravel-facade-routes
fix(routes): mint facade-style Laravel routes and compose group prefixes
2026-07-12 22:44:38 +02:00
Martin Vogel 8f3ee086a7 Merge pull request #1058 from DeusData/fix/996-writer-wide-fopen
fix(writer): open the graph DB wide-safe for non-ASCII cache paths
2026-07-12 21:49:34 +02:00
Martin Vogel da4c00671f Merge pull request #1057 from DeusData/fix/929-windows-cmd-hooks
fix(install): Windows hook scripts get .cmd form; legacy files removed
2026-07-12 21:30:21 +02:00
Martin Vogel 4ecfe4cd67 fix(routes): mint facade-style Laravel routes and compose group prefixes
Real Laravel apps register routes through the Illuminate facade, whose
class lives in vendor/ and is never indexed - and for that style the
graph minted ZERO Route nodes, flat or grouped. Three stacked defects:

1. The callee of Route::get(...) (scoped_call_expression) was
   extracted as bare 'get' via generic field resolution, so the
   empty-resolution route fallback ('::get' suffix table) could never
   engage. The extractor now emits the qualified 'Route::get' form,
   gated to the literal Route scope AND a route-method table match so
   Cache::get / Config::get keep bare names and can never mint junk
   (guarded by an inverse test; the path gate additionally requires a
   leading '/').
2. The sequential pass had no ROUTE_REG empty-resolution fallback at
   all (its comment claimed parity with the parallel path, which has
   one) - unresolvable route registrations were dropped entirely.
   Added, mirroring the parallel callee_suffix fallback.
3. Nothing composed enclosing prefix()->group() chains (same class as
   Spring's #734). At extraction - the only place the AST still exists
   - each route call inside group closures now walks its ancestors:
   every enclosing closure that is the argument of ->group(...)
   contributes the prefix('...') found on that group call's receiver
   chain, outer-to-inner for nested groups; middleware/name/domain
   chain links are skipped.

The existing handles_laravel_php test kept passing throughout because
its fixture defines an in-tree Route class, resolving by QN - which is
exactly how this class stayed unseen.

Closes #952

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-12 21:12:49 +02:00
Martin Vogel 5c9c554a2b Merge pull request #1055 from DeusData/fix/858-hook-deadline
fix(hook): raise + env-configure the augment deadline, breadcrumb on fire
2026-07-12 20:52:21 +02:00
Martin Vogel c1db9c5d02 Merge pull request #1056 from DeusData/fix/1032-aider-cli-instructions
fix(install): give Aider CLI-form instructions instead of MCP tool calls
2026-07-12 20:45:38 +02:00
WarGloom c43fabd955 Merge branch 'main' into agent/fix-mcp-structured-content 2026-07-12 21:24:47 +03:00
Martin Vogel faf5160cbb fix(platform): read environment variables wide on Windows
DCO / dco (push) Has been cancelled
Layer 2 of #996, forced by the new guard going RED on the Windows CI
leg with the writer fix alone: _environ holds ANSI-code-page bytes,
not UTF-8, so a non-ASCII USERPROFILE or CBM_CACHE_DIR arrives either
mojibake'd or with unrepresentable characters replaced by '?' - which
is invalid in Windows paths, so every downstream wide-safe file API
fails no matter how correct it is. cbm_safe_getenv now reads the value
via GetEnvironmentVariableW and converts to genuine UTF-8
(cbm_wide_to_utf8), matching the UTF-8-path convention the rest of the
codebase assumes; missing variables honor the fallback as before, and
conversion trouble falls back to the ANSI scan rather than failing.
POSIX untouched.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-12 20:24:17 +02:00
Martin Vogel b1502bf3eb fix(install): Windows hook scripts get .cmd form; legacy files removed
Extensionless bash shims under %USERPROFILE%\.claude\hooks triggered
the Windows 'How do you want to open this file?' dialog whenever an
editor (Cursor) scanned the hooks dir, and could not execute without
bash anyway. All three Claude hook scripts (discovery gate, session
reminder, subagent reminder) now install as .cmd files with cmd syntax
on Windows - @echo off bodies, caret-escaped pipes in the reminder
text, 2>/dev/null redirects - and the install removes the pre-existing
extensionless twin so upgrades stop triggering the dialog. The
settings.json command paths follow automatically since they are built
from the same script-name macros. POSIX behavior is byte-identical and
guarded (no .cmd twin).

Closes #929

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-12 19:45:29 +02:00
Martin Vogel 4b5bb757f9 fix(hook): compile the deadline knob out on Windows
DCO / dco (push) Has been cancelled
ha_deadline_ms was defined unconditionally but only used by the POSIX
ha_arm_deadline - unused-function under -Werror broke every Windows
leg. The knob, its constants and the doc comment now live inside the
same #ifndef _WIN32 block as the deadline machinery they configure;
Windows continues to rely solely on the settings.json hook timeout.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-12 19:27:56 +02:00
Martin Vogel 783892aa63 fix(install): give Aider CLI-form instructions instead of MCP tool calls
DCO / dco (push) Has been cancelled
Aider has no MCP support - it reads CONVENTIONS.md but can only run
shell commands. The installer wrote the shared MCP-tool-centric
instructions there, telling the model to call search_graph(...) etc.,
tools Aider cannot invoke; a reporter reasonably asked how that was
ever supposed to work (#1032).

Aider now gets a dedicated variant: the same discovery priority
expressed as runnable codebase-memory-mcp cli commands (usable via
/run), including first-index and list_projects bootstrapping, with the
no-MCP constraint stated explicitly.

Closes #1032

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-12 19:18:20 +02:00
Martin Vogel 39ffb97ceb fix(hook): raise + env-configure the augment deadline, breadcrumb on fire
The 300ms in-process SIGALRM budget in hook-augment self-terminated
with a silent _exit(0) on real cold starts (SQLite/mmap open under
load), so PreToolUse augmentation never appeared in real sessions
(reporter: 0/24 observed) while warm manual invocations worked - and a
fired deadline was indistinguishable from a legitimate no-match run.

Default budget is now 2000ms (the settings.json hook timeout stays the
outer backstop), overridable via CBM_HOOK_DEADLINE_MS (clamped
50..10000). When the deadline fires, the handler write()s a
pre-formatted breadcrumb (deadline, pid, the env knob to raise) to
~/.cache/codebase-memory-mcp/logs/hook-augment-timeouts.log before
exiting - fd and message are prepared at arm time so the handler stays
async-signal-safe; CBM_HOOK_TIMEOUT_LOG overrides the path for tests.
Windows keeps relying on the settings.json timeout (unchanged no-op).

Deterministic reproduction: stdin is a pipe whose writer never sends,
so the read blocks past a 60ms deadline - the timer must fire, exit 0
(fail-open), and leave the breadcrumb. RED before (no breadcrumb),
GREEN after.

Closes #858

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-12 19:06:47 +02:00
Martin Vogel 2432cc8bbb fix(mcp): resolve project arg by unique name tail when exact lookup misses
DCO / dco (push) Has been cancelled
Agents naturally pass the repo folder name (codebase-memory-mcp), but
indexed project names derive from the full path (E:\project\graph\x
-> E-project-graph-x), so every graph tool answered 'project not found
or not indexed' while list_projects clearly showed the project.

get_project_arg now falls back to a cache-dir filename scan when no
<project>.db exists: a passed name matching exactly ONE indexed
project as a segment-aligned tail (-<name>.db) adopts that project's
full name (logged); zero or several matches keep the original name so
the existing not-found error with the candidate list fires. Exact
names never enter the scan, and internal-name drift stays #704's
fallback in resolve_store.

Closes #1025

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-07-12 18:48:34 +02:00