Commit Graph
948 Commits
Author SHA1 Message Date
Gol3vka 2bc4a539ac fix(watcher): defer state_free in unwatch to prevent UAF
Signed-off-by: Gol3vka <gol3vka@163.com>
2026-06-26 09:36:20 +08:00
Gol3vka 3b93827fe2 fix: unwatch deleted projects to prevent zombie reindex
Signed-off-by: Gol3vka <gol3vka@163.com>
2026-06-26 09:36:19 +08:00
Martin Vogel b075f0506c Merge pull request #633 from DeusData/test/cpp-enclosing-attr-438
test(extract): guard C++ out-of-line method/ctor/dtor enclosing attribution
2026-06-25 22:47:19 +02:00
Martin Vogel 4953fcaf21 test(extract): guard C++ out-of-line method/ctor/dtor enclosing attribution
After the C declarator-name walker was de-duplicated into one shared helper
(cbm_resolve_c_declarator_name_node), the C/C++ enclosing-function resolver now
resolves qualified names (Foo::bar) via resolve_qualified_name() and no longer
treats type_identifier as a terminal name. Add reproduce-first coverage so the
#438 fix cannot silently regress on the qualified-declarator path:

- cpp_out_of_line_method_caller_attribution: a call inside `void Foo::bar()` must
  attribute to the method, not the module.
- cpp_out_of_line_ctor_dtor_caller_attribution: calls inside `Foo::Foo()` and
  `Foo::~Foo()` must attribute to the special member, not the module.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-06-25 21:42:31 +02:00
Martin Vogel 66b3e3004b Merge pull request #614 from linze0721/berserk/fd632085-2b69-4b14-930b-47025d80d973
fix: get_architecture should honor path scope
2026-06-25 21:18:49 +02:00
Martin Vogel 677582ccf8 Merge pull request #539 from RithvikReddy0-0/fix/516-adr-persistence
fix(pipeline): preserve ADR across full re-index (#516)fix(pipeline): preserve ADR across full re-index (#516)
2026-06-25 21:18:33 +02:00
Martin Vogel 7d11db8ee4 Merge pull request #527 from Ravandevil25/fix/json-escape
fix(foundation): properly escape JSON control characters as \u00XX
2026-06-25 21:18:10 +02:00
Martin Vogel 1c3c5573c4 Merge pull request #463 from KerseyFabrications/fix/c-calls-function-source
fix(extract): attribute C/C++ CALLS edges to the enclosing function
2026-06-25 21:17:52 +02:00
Martin Vogel a76e97daaa Merge pull request #449 from isc-tdyar/fix/class-lines-zero
fix(extract): Class.lines always 0 for all languages
2026-06-25 21:17:35 +02:00
萧瑟 c80a294585 Merge branch 'main' into berserk/fd632085-2b69-4b14-930b-47025d80d973 2026-06-25 08:34:49 +08:00
Kris Kersey adc8304c57 refactor(extract): dedup C declarator-name walker into one shared helper
Addresses #463 review: the declarator-chain name resolver was copied into
helpers.c, extract_unified.c, and extract_defs.c, and CBM_DECLARATOR_DEPTH_LIMIT
was #defined twice -- the same triplication drift that caused #438.

- Add cbm_resolve_c_declarator_name_node() to helpers.{c,h} as the single
  source of truth, carrying is_c_terminal_name/resolve_qualified_name with it.
- Route the defs, calls, and unified extractors through it.
- Hoist CBM_DECLARATOR_DEPTH_LIMIT into helpers.h; extract_defs.c's
  DECLARATOR_DEPTH_LIMIT now derives from it.

Canonicalizes on the original extract_defs.c logic (operator/destructor aware)
so defs behavior is unchanged and calls/unified now agree with it.

Test: full suite green except an unrelated ASan RSS-budget check; clang-format clean.

Signed-off-by: Kris Kersey <kris@kerseyfabrications.com>
2026-06-24 12:42:38 -04:00
Kris Kersey 13c3429651 fix(extract): attribute C/C++ CALLS edges to the enclosing function
A CALLS edge whose caller is a C/C++/CUDA/GLSL function was sourced to the
file's Module node instead of the calling Function. "Find callers of X"
returned a file path, outbound trace_path returned empty, and
(:Function)-[:CALLS]->(:Function) queries missed for these languages.

Root cause: the enclosing-function resolvers read only tree-sitter's `name`
field, but a `function_definition` node has none — the name lives in the
declarator chain (pointer/function/parenthesized/array declarators). So
func_node_name() (internal/cbm/helpers.c) and resolve_func_name_node()
(internal/cbm/extract_unified.c) returned NULL, the enclosing scope fell
back to the module QN, and the edge was attributed to the Module node. This
is the C counterpart to #220, which fixed the definition-naming path but not
the enclosing-call path.

Fix: descend the declarator chain to the innermost name node (mirroring
resolve_c_declarator_name in extract_defs.c, including qualified and operator
names) when a function_definition lacks a `name` field. Adds the regression
test c_caller_attribution asserting a C call's enclosing_func_qn is the
function, not the module.

Fixes #438

Signed-off-by: Kris Kersey <kris@kerseyfabrications.com>
2026-06-24 12:42:38 -04:00
saurav kumar 078e9e2d85 Merge branch 'main' into fix/json-escape 2026-06-24 20:36:59 +05:30
Saurav Kumar fdcafbb53f fix(foundation): properly escape JSON control characters as \u00XX
Signed-off-by: Saurav Kumar <sauravsk2507@gmail.com>
2026-06-24 20:33:52 +05:30
Berserk Agent e270ceb8a4 style(store,mcp): clang-format-20 for CI lint (#604)
Signed-off-by: Berserk Agent <berserk@agent.local>
2026-06-24 13:54:33 +00:00
Berserk Agent 55058c05f0 fix(arch): normalize path trailing slashes; align MCP path_scoped with store (#604)
Signed-off-by: Berserk Agent <berserk@agent.local>
2026-06-24 12:54:45 +00:00
Berserk Agent adf602ec94 fix(mcp): document path on get_architecture and emit root/scoped totals (#604)
Signed-off-by: Berserk Agent <berserk@agent.local>
2026-06-24 12:50:49 +00:00
Berserk Agent 9332593b26 Store path scoping for get_architecture
Signed-off-by: Berserk Agent <berserk@agent.local>
2026-06-24 12:38:11 +00:00
Martin Vogel 34efbc0bc5 Merge pull request #596 from DeusData/chore/triage-automation 2026-06-24 08:35:12 +02:00
RithvikReddy0-0 98c4fc345a fix(pipeline): harden ADR preservation and add regression test (#516)
Addresses review on #539.

- Free p->saved_adr in cbm_pipeline_free so it is not leaked on error
  paths that exit before the restore in dump_and_persist_hashes (e.g. a
  cbm_gbuf_dump_to_sqlite failure).
- Check cbm_store_adr_store's return value on restore and log an error
  instead of silently dropping the ADR (the original #516 symptom).
- Add reproduce-first test pipeline_adr_survives_full_reindex: index,
  store an ADR, force a full re-index by adding files, assert the ADR
  survives unchanged. Passes against the fix.

Signed-off-by: RithvikReddy0-0 <rithvikreddymukkara@gmail.com>
2026-06-24 01:27:32 +00:00
RithvikReddy0-0 7f622b1cde fix(pipeline): preserve ADR across full re-index (#516)
manage_adr stores ADRs in project_summaries, but a full re-index
(triggered by file changes or new files) deletes the DB in
try_incremental_or_delete_db and rebuilds it from the graph buffer,
which writes an empty project_summaries table. file_hashes were
re-persisted after the rebuild but project_summaries were not, so the
ADR was silently lost.

Fix: capture the ADR before the DB is unlinked, stash it on the
pipeline struct, and restore it after the rebuilt DB is reopened in
dump_and_persist_hashes. The incremental path is unaffected (it never
rewrites the DB). Verified: ADR now survives a full re-index.

Signed-off-by: RithvikReddy0-0 <rithvikreddymukkara@gmail.com>
2026-06-24 01:24:06 +00:00
Martin Vogel 170d5a82ab fix(ci): allow-list MSYS2 toolchain URL in binary string audit
The MSYS2 CLANG64 toolchain bakes its package-tracker URL
(https://github.com/msys2/MINGW-packages) into the static Windows .exe via
libc++/compiler-rt. The Layer 2 binary string audit flagged it as an
unauthorized URL, failing smoke-windows (both the standard and ui variants)
while Linux smoke stayed green. Add it to ALLOWED_URLS alongside the other
compiler/linker toolchain URLs (gcc.gnu.org, sourceware.org, launchpad).

Add tests/test_security_strings_allowlist.sh as a reproduce-first regression
guard: it reproduces the BLOCKED failure with a binary fixture and includes a
negative control proving a genuinely unauthorized URL is still rejected. Wired
into scripts/test.sh as Step 6.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-06-24 03:15:36 +02:00
Martin Vogel dc5a1aa675 Merge pull request #590 from DeusData/vendor/objectscript-grammar
chore(vendor): vendor the InterSystems ObjectScript tree-sitter grammars
2026-06-24 01:21:51 +02:00
Martin Vogel c37848a73c ci: add issue-triage bots (stale, label-actions, area-labeler)
Three native GitHub Actions to automate the mechanical parts of issue
triage:

- stale.yml: actions/stale scoped to the awaiting-reporter label —
  warns at 21 days idle, closes at 35, auto-resets when the reporter
  replies. Never touches PRs or unlabeled issues.
- label-actions.yml + .github/label-actions.yml: posts a templated
  comment when duplicate or awaiting-reporter is applied (duplicates are
  linked, not auto-closed).
- issue-labeler.yml + .github/issue-labeler.yml: adds area labels
  (windows, stability/performance, parsing/quality, editor/integration,
  ux/behavior, cypher, language-request) from title/body keywords.
  Additive only; base bug/enhancement labels still come from the forms.

All third-party actions pinned to full commit SHAs with least-privilege
per-job permissions (issues: write only where required).

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-06-24 01:18:29 +02:00
Martin Vogel 5352d5229d Merge pull request #591 from DeusData/fix/security-alerts
chore(security): resolve flagged Scorecard + Dependabot alerts
2026-06-24 01:15:35 +02:00
Thomas Dyar 36e127c113 fix(extract): Class node lines property always 0
extract_class_def() sets start_line and end_line from the tree-sitter
node span, but left def.lines = 0 (zeroed by memset at function entry).
The equivalent function push_method_def() correctly computes
  def.lines = end_line - start_line + 1
The same one-liner was simply missing from the class extraction path.

This affects all languages — Python, TypeScript, Go, and any other
language where Class nodes are extracted via extract_class_def().

Regression test: after indexing a project, at least one Class node must
have c.lines > 0.

Signed-off-by: Thomas Dyar <tdyar@intersystems.com>
2026-06-23 19:14:09 -04:00
Martin Vogel a3336bf346 chore(security): resolve flagged Scorecard + Dependabot alerts
- graph-ui: bump vite ^6.4.2 -> ^6.4.3 and add overrides pinning the transitive
  form-data >=4.0.6 and @babel/core >=7.29.6 (all dev-scope build/test deps, not
  shipped in the binary). Clears the 4 open Dependabot alerts and Scorecard's
  VulnerabilitiesID. `npm audit` now reports 0 vulnerabilities.
- codeql.yml: move `security-events: write` from the workflow top level to the
  `analyze` job (top level is now `contents: read`), resolving Scorecard's
  TokenPermissionsID least-privilege finding. CodeQL still uploads results from the
  job-scoped token.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-06-24 00:34:05 +02:00
Martin Vogel 880f899099 Merge pull request #532 from DeusData/dependabot/github_actions/softprops/action-gh-release-3.0.1
build(deps): bump softprops/action-gh-release from 3.0.0 to 3.0.1
2026-06-24 00:30:35 +02:00
Martin Vogel 803aadc492 Merge pull request #458 from DeusData/dependabot/github_actions/msys2/setup-msys2-2.32.0
build(deps): bump msys2/setup-msys2 from 2.31.1 to 2.32.0
2026-06-24 00:30:30 +02:00
Martin Vogel 242988bd57 chore(vendor): vendor the InterSystems ObjectScript tree-sitter grammars
Vendors the two MIT-licensed grammars from intersystems/tree-sitter-objectscript
@a7ffcdf (the language vendor's official grammars, ABI 15) that PR #467 needs:

  internal/cbm/vendored/grammars/objectscript_udl/      (.cls)
  internal/cbm/vendored/grammars/objectscript_routine/  (.mac/.inc/.rtn/.int)

Each directory carries the verbatim generated parser.c + scanner.c + tree_sitter/
headers + LICENSE. The one adjustment: each scanner.c's upstream
`#include "../../common/scanner.h"` is repointed to a per-directory
`objectscript_common.h` (a verbatim copy of the upstream common/scanner.h), because
this repo's shared vendored/common/scanner.h belongs to the cfml/fsharp grammars and
differs. Updates MANIFEST.md + THIRD_PARTY.md.

These files are dormant until #467 (the grammar shims + extraction) is rebased on
top; main's build is unaffected.

Refs #462, #467.

Signed-off-by: Martin Vogel <martin.vogel.tech@gmail.com>
2026-06-24 00:20:57 +02:00
Martin Vogel 3d4236e861 Merge pull request #486 from mvanhorn/fix/400-windows-persistence-artifact-silent-failure
fix: Surface a real error when persistence artifact export silently fails on Windows
2026-06-23 23:52:36 +02:00
Martin Vogel 090a1a72d5 Merge pull request #542 from mvanhorn/fix/499-global-core-excludesfile-ignore-source
fix: honor git global core.excludesFile as an ignore source
2026-06-23 23:46:24 +02:00
Martin Vogel f82c6aee68 Merge pull request #526 from jstar0/fix/snippet-valid-utf8
fix(mcp): return valid UTF-8 snippets
2026-06-23 23:46:20 +02:00
Martin Vogel 96c1fc38fb Merge pull request #465 from KerseyFabrications/fix/cypher-with-node-props
fix(cypher): preserve node properties through WITH aggregation
2026-06-23 23:46:16 +02:00
Martin Vogel bbaca2a848 Merge pull request #447 from isc-tdyar/fix/string-dispatch-dead-code
fix(extract): string-dispatch CALLS edges never emitted — detection was in dead code
2026-06-23 23:46:13 +02:00
Martin Vogel ca5c0d2a27 Merge pull request #588 from GothUncc/fix/gcc15-strstr-const-qualifier
fix(cli): const-qualify local pointers in codex_hook_strip for gcc 15
2026-06-23 23:08:24 +02:00
Martin Vogel eeca97ecb2 Merge pull request #587 from HackAttack/fix-brew-formula-location
Fix homebrew formula location
2026-06-23 23:08:20 +02:00
Martin Vogel 5e40a24326 Merge pull request #579 from BombaxCeiba/fix/list-projects-2gb-windows
fix(mcp): replace `.db`-targeting `stat()` with `cbm_file_size` on Windows (> 2 GB)
2026-06-23 23:08:17 +02:00
Martin Vogel 56d36ba17e Merge pull request #572 from mvanhorn/fix/558-search-graph-degree-inherits-edges
fix: count INHERITS/IMPLEMENTS edges in search_graph degree
2026-06-23 23:08:13 +02:00
Martin Vogel 879c3cbe5b Merge pull request #566 from jsw6701/fix/kotlin-spring-routes
fix(extract): extract Spring routes from Kotlin controllers
2026-06-23 23:08:09 +02:00
Martin Vogel 008f6e3873 Merge pull request #506 from imateusdev/fix/route-param-canonicalization
fix(routes): canonicalize path parameters so client calls match handlers (#505)
2026-06-23 23:08:05 +02:00
Martin Vogel 4dd6ebd69e Merge pull request #456 from nguiaSoren/fix/334-committed-count-capture
fix(pipeline): make the #334 plausibility gate fire (capture committed_nodes before dump)
2026-06-23 23:08:01 +02:00
Jeremy MaserangandClaude Opus 4.8 c13a9db612 fix(cli): const-qualify local pointers in codex_hook_strip for gcc 15
Under -D_GNU_SOURCE with optimization, glibc's string.h macros make
strstr() on a `const char *` (with a constant needle) yield a
`const char *`. gcc 15 then rejects assigning that to `char *` with
-Werror=discarded-qualifiers, breaking the build:

    src/cli/cli.c:1503: error: initialization discards 'const'
    qualifier from pointer target type [-Werror=discarded-qualifiers]

Minimal repro (gcc 15.2):
    const char *c = "hello";
    char *p = strstr(c, "ell");   // gcc -D_GNU_SOURCE -O2 -Werror=discarded-qualifiers

codex_hook_strip only reads through begin/end/cut (offset math and
byte comparisons, never writes), so making them `const char *` is the
correct fix and preserves the function's existing const contract
(`content` is already const). The malloc'd output buffer stays char *.
No behavior change; build succeeds on gcc 15.2.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Jeremy Maserang <gothuncc@gothaunty.com>
2026-06-23 15:31:56 -04:00
Michael Hackner 9f963fd564 Fix homebrew formula location
Homebrew only discovers formulae under Formula/ at the tap root. Add a
symlink to the pkg/homebrew/ location so `brew install` works.

Signed-off-by: Michael Hackner <mhackner@gmail.com>
2026-06-23 11:54:17 -07:00
imateusdev 8b813675be fix(routes): canonicalize path parameters so client calls match handlers
Route QNs (__route__METHOD__/path) are the rendezvous key for joining a client
HTTP_CALLS to the server handler that serves it, but they were built from the raw
path. Frameworks write path parameters with different placeholder syntaxes
(":id" Express/clients, "{id}" Axum/Spring/OpenAPI, "<id>" Flask/Rocket), so a
client call and its handler produced different QNs and never joined. Static
routes joined; parameterized routes (most of a REST surface) did not.

Add cbm_route_canon_path() which collapses each parameter token (":name",
"{name}", "<name>", "${...}") to a single "{}" token, and apply it to the path
at every HTTP-route QN construction site (pass_route_nodes, pass_parallel,
pass_calls, pass_cross_repo). Broker/async/infra QNs are left untouched. Only the
QN (identity/dedup key) is canonicalized; the Route node display name keeps the
original path. Parameter names are intentionally discarded so the same logical
endpoint matches across services that name the variable differently.

Adds tests/test_route_canon.c (11 cases). Fixes #505.

Signed-off-by: imateusdev <imateusdev@gmail.com>
2026-06-23 13:52:08 -03:00
Dusk_NM02 0efc1ed366 fix(mcp): replace .db-targeting stat() with cbm_file_size on Windows (>2GB)
On Windows struct stat::st_size is a 32-bit long, so any .db larger than 2 GB
makes stat() fail with EOVERFLOW. Three call sites in src/mcp/mcp.c checked
.db files this way and silently mishandled the > 2 GB case: list_projects
dropped the project from the UI list, maybe_auto_index re-indexed it on every
server start, and try_artifact_bootstrap re-imported it from the artifact.
Replace all three with the existing cbm_file_size (platform.c), which is
wide-char + 64-bit clean on Windows (GetFileAttributesExW) and returns int64_t
on both platforms, so the size never rides through the 32-bit st_size.

Signed-off-by: Dusk_NM02 <dusk.11th@outlook.com>
2026-06-23 21:52:47 +08:00
Matt Van Horn 0714e46346 fix: address self-review findings — keep node_degree CALLS-only
cbm_store_node_degree backs the MCP get_code_snippet callers/callees
counts and the Cypher in_degree/out_degree virtual property, which are
deliberately CALLS-scoped. Restore it to CALLS-only and scope the
INHERITS/IMPLEMENTS broadening to cbm_store_search alone, which is the
search_graph surface issue #558 is about. Adjust the new tests so
node_degree assertions expect CALLS-only counts while the search_graph
result assertions expect the broadened structural degree.

Signed-off-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-06-23 04:08:36 -07:00
Matt Van Horn 65b8425648 fix: count INHERITS/IMPLEMENTS edges in search_graph degree
search_graph reported in_degree/out_degree of 0 for Class nodes that
have real INHERITS edges, because the degree computation in both
cbm_store_node_degree (Cypher virtual properties) and cbm_store_search
(result population and min_degree/max_degree filter) only counted CALLS
(and USAGE) edges. A min_degree filter therefore silently excluded
well-connected classes.

Broaden the edge-type predicate in both surfaces to
IN ('CALLS', 'USAGE', 'INHERITS', 'IMPLEMENTS') so search_graph and
Cypher report the same edge-type-agnostic degree and stay consistent.

Add regression tests covering: a parent class with N INHERITS children,
combined CALLS+INHERITS degree without double counting, min_degree now
including inheritance-only classes, and isolated nodes still reporting
zero.

Signed-off-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-06-23 04:08:36 -07:00
jsw6701 7aacf380dd fix(extract): extract Spring routes from Kotlin controllers
try_route_from_annotation read the annotation name via the "name" field
(ts_node_child_by_field_name). tree-sitter-kotlin annotation nodes have no
"name" field: the name lives in a nested type_identifier under (user_type)
or (constructor_invocation (user_type ...)). The lookup returned null, so
every Kotlin @RestController route was dropped (0 decorator-source routes)
while Java worked. Args are likewise under constructor_invocation as
value_arguments (each wrapped in value_argument), not Java argument_list.

Add annotation_name_node()/annotation_args_node() that fall back to the
Kotlin AST shape (Java path unchanged) and unwrap value_argument when
scanning for the route path. Kotlin @GetMapping/@PostMapping/etc. now yield
Route nodes and HANDLES edges. Adds handles_spring_kotlin regression test.

Signed-off-by: jsw6701 <86887824+jsw6701@users.noreply.github.com>
2026-06-23 03:59:45 +00:00
Thomas Dyar 0b94f44f96 fix(extract): string-dispatch calls in dead code path, never linked to target
Python calls of the form iris_obj.classMethodValue('Pkg.Class', 'Method')
emitted no CALLS edge. The detection existed in walk_calls, which is dead
code — the pipeline uses cbm_extract_unified → handle_calls, not walk_calls.

Move the IRIS Native API string-dispatch detection to handle_calls. When a
Python call's callee ends in .classMethodValue, .classMethodVoid,
.classMethodBoolean, or .classMethodObject, and both string-literal arguments
can be extracted, emit a synthetic CALLS edge to Arg1.Arg2.

The pattern generalizes beyond this specific API: any library that takes
class/method names as string literals follows the same shape.

Regression test: python_iris_classMethodValue in test_extraction.c.

Signed-off-by: Thomas Dyar <tdyar@intersystems.com>
2026-06-22 19:56:46 -04:00