haiany

haiany 已經從鏡像同步了提交 mainhaiany/codegraph

  • a89315645d feat(go): index GoFrame g.Meta routes and bind them to controller methods (#747) (#957) GoFrame's standard router binds routes reflectively (group.Bind(ctrl)): the path and method live in a g.Meta struct tag on a request type, and the controller method that serves it is matched by that request type at runtime — so there was no path string and no edge from a route to its handler, and "where is this route handled / where are routes bound to controllers?" could only be answered lexically (issue #720's report). - frameworks/goframe.ts: detect gogf/gf in go.mod, extract each path-bearing g.Meta into a route node (requires path:, so response mime:-only tags are skipped), encoding the package-qualified request type for the join. - goframe-synthesizer.ts: join each route -> the controller method whose signature takes that request type — NOT by name (DeptSearchReq is served by List) — keyed pkg.Type to disambiguate the many identical bare names a large app defines one-per-module, with an addon-root tiebreak for cloned demo addons. Edge kind calls, provenance heuristic, synthesizedBy goframe-route, surfaced as a dynamic-dispatch hop in codegraph_explore. Validated on real repos: gf-demo-user 7/7, gfast 65/68 (3 genuinely handler-less), hotgo 242/247 (98%) — 100% precision (0 non-controller handlers, 0 core/addon cross-binding), node count stable. Agent A/B (gfast, sonnet/high, 2 runs/arm): with codegraph 1 explore call / 0 Read / ~20s vs without 7.5 Read avg + grep-hunting for the non-existent literal route string / ~42s; same correct answer. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 6459ead6aa fix(extraction): index files reached through in-root symlinks that point outside the repo (#935) (#956) The directory walk deliberately follows an in-root symlink whose target lives outside the repo root (the standard Dota custom-game layout, where `game/` and `content/` link into the SDK tree) and enumerates the files under it. But the read path then rejected every one of them via the strict symlink-escape guard, logging `Path traversal blocked in batch reader` and indexing nothing — discovery and the reader disagreed. Add an opt-in `allowSymlinkEscape` to validatePathWithinRoot that waives only the realpath-escape rejection (the lexical `../` guard still applies) and pass it at the three indexing read sites (batch reader, indexFile, indexFileWithContent). The content-serving sinks (ContextBuilder, MCP tools) keep the strict guard, so this stays inside the #527 model: indexing now follows the symlink, getCode still refuses to serve out-of-root contents. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • d1121e46f0 feat(config): map custom file extensions to languages via codegraph.json (#906) (#955) The extension → language table was hardcoded, so a codebase using a non-standard extension for a supported language (e.g. `.dota_lua` for Lua) had those files silently skipped — no way to opt them in short of patching the source. Add an opt-in, project-scoped `codegraph.json` at the repo root: { "extensions": { ".dota_lua": "lua", ".tpl": "php" } } Mappings merge on top of the built-in defaults and take precedence (so a built-in can be re-pointed, e.g. `.h` → `cpp`). Absent or malformed config is the zero-config default — byte-identical to prior behavior; an invalid target language or unparseable file is warned-and-skipped, never fatal. Implementation: - New `src/project-config.ts` — `loadExtensionOverrides(rootDir)`, validated against `isLanguageSupported`, mtime-cached per root. - `detectLanguage` / `isSourceFile` gain an optional `overrides` arg (omitting it is the existing behavior). - Overrides threaded per-operation through every extraction call site (scan/walk gates, git change-detection, grammar selection, extraction, the file watcher), resolved from the project root — no process-global state, so the multi-project daemon stays isolated. The parse worker receives the resolved language in its message. Tests: 13 new cases (unit, loader validation/normalization/caching, and a full-index integration proving a custom-extension file is extracted while the zero-config path indexes nothing). Worker path smoke-tested via the built CLI. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 查看 3 次提交的內容比對 »

6 小時之前

haiany 已經從鏡像同步了提交 mainhaiany/codegraph

  • ba209d9489 feat(c/c++): resolve function-pointer dispatch (#932) (#954) C/C++ polymorphism is the function pointer: a struct fn-pointer field, concrete functions registered into it through a table (`{"add", cmd_add}`), a designated initializer (`.handler = on_open`), or an assignment, then dispatched indirectly (`p->fn(argv)`). Static extraction captures neither the registration→field binding nor the indirect call, so the dispatcher→handler edge was missing — git's run_builtin looked like it called nothing, a vtable's implementations had no callers, and the hook_demo.c in the issue was unreachable. Add a resolution-layer synthesizer keyed by (struct type, fn-pointer field). It reads source (the established Celery/Sidekiq/Spring pattern — C extraction has no struct fields or indirect-call edges to build on) in passes: collect fn-pointer typedefs, parse struct field layouts, collect registrations (positional matched by field index, designated, and assignment), propagate field←field assignments (so a generic hook slot reassigned from a registry — the hook_demo.c `h->func = found->fn` shape — inherits the registry field's handlers), then link each indirect dispatch site to the registered handlers. Receiver type resolves from the enclosing function's params/locals, falling back to a field name unique to one struct. Covers both the command-table idiom (git, redis) and the ops-struct/vtable idiom (curl content-encoders, protocol handlers). Pure edge synthesis (no node growth); high precision via the (struct, field) key. Validated: git 502 edges (run_builtin→cmd_* plus git_hash_algo/archiver/reftable vtables), redis 357 (dictType.hashFunction, connection + reply-object vtables), curl 478 (Curl_cwtype.do_init → deflate/gzip/brotli/zstd); 0 non-function targets on all three; node-stable; 0 on the lua control (its {name,fn} tables register into the Lua VM, with no C indirect call to bridge). Full suite 1665 pass. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 826810f128 feat(java): index Lombok-generated members so call chains resolve (#912) (#953) Lombok generates getters/setters, builder(), equals/hashCode/toString, and the @Slf4j log field at compile time, so they never appear in the source AST. Static extraction missed them entirely, so a bean.getName() / User.builder() / log.info() call resolved to nothing and call-chain analysis broke silently — the agent would conclude the method didn't exist. Add a synthesizeMembers hook on LanguageExtractor, called at the end of class extraction (class still on the scope stack, real members already extracted), and a Java implementation that synthesizes the mechanical members for @Getter, @Setter, @Data, @Value, @Builder/@SuperBuilder, @ToString, @EqualsAndHashCode, and the @Log* family. Each node is anchored on the field/class name-token leaf (so it pulls in no spurious value-reference scope), marked with a `lombok` decorator and a docstring naming the generating annotation, and never overrides a member the source already declares. Methods and fields are deduped separately since they're distinct namespaces in Java (a boolean field `isRunning` and its generated getter `isRunning()` coexist). Deliberately not synthesized: constructors (new X() already links via instantiates, and overloaded @NoArgs/@AllArgs/@RequiredArgs ctors would collide on a synthetic node id), fluent builder setters, and @Accessors(fluent=true). Validated on eladmin (274 Java files, Lombok-heavy): 100% accessor precision (878/878 map to a real field), 722 previously-broken calls now resolve; spring-petclinic (no Lombok) control synthesizes nothing. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 3e1547bbe1 fix(mcp): bold labels instead of ATX headings in tool results (#778) (#951) MCP tool results used Markdown ATX headings (##/###/####) for section headers — the status summary, each search hit, every file section in an exploration — which Markdown-rendering clients (e.g. the Claude Code VSCode extension) blow up to H1–H4 font size, filling the transcript with oversized lines (worst on search/explore, where the noise scales with result count). Swap them all for bold labels, which render at body size while keeping the same structure. CLI/TTY output (ContextBuilder) is unchanged — the issue notes it's fine. The format is parse-coupled, so kept in sync: - The explore truncation boundary and the offload chunker (reasoning/reasoner.ts) both key off the per-file header, now a unique `**`-prefixed marker emitted via a shared fileSectionHeader() helper. - Updated the offload strip regexes and switched the opt-in report-style prompt off ATX headings (same client, same rendering issue). - Updated test helpers (sectionFor, sourcedFiles, the callers section-boundary scan) that scanned the old markers. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • ace8d8a0d0 fix(mcp): stop the first tool call hanging on a huge-repo catch-up reconcile (#905) (#950) On a very large repo (the report is a ~93k-file / 5.7GB-DB Java monorepo) the first MCP `tools/call` after a fresh `serve --mcp` could hang for 10+ minutes with zero output, and with the liveness watchdog on, the daemon was SIGKILLed mid-query instead. Root cause: the post-open catch-up reconcile that the first tool call is gated on does ~2*N synchronous `fs.existsSync`/`fs.statSync` calls plus a load-all-files query in two non-yielding loops. On a huge repo that wedges the event loop for minutes, which (a) trips the 60s watchdog (it SIGKILLs a process whose loop stops turning) and (b) blocks the first call the whole time. Two complementary fixes: - Make the reconcile yield. `ExtractionOrchestrator.sync()` now uses the yielding `scanDirectoryAsync`, and both O(files) reconcile loops `await setImmediate` every SYNC_RECONCILE_YIELD_INTERVAL (1000) files. The loop can no longer wedge the main thread, so the watchdog stays fed and the socket / any concurrent read stays responsive while a big reconcile runs. Results are unchanged — only yield points are added. - Time-box the catch-up gate. The first `tools/call` now waits on the reconcile for at most CODEGRAPH_CATCHUP_GATE_TIMEOUT_MS (default 3000ms), then serves and lets the reconcile finish in the background (which now yields, so the served call runs concurrently). `=0` restores the old unbounded wait. On a normal repo the reconcile finishes well under the budget, so behavior is unchanged. Tests: adds two time-box cases to mcp-catchup-gate (serves promptly when the reconcile runs long; `=0` restores the unbounded wait). Full suite green (1655 passed). Validated end-to-end through the real daemon: first call returns at the ~3s time-box instead of waiting an injected 8s reconcile; no-delay control unchanged; `=0` opt-out waits the full reconcile. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 2010c2d2b5 fix(sync): apply the ignore matcher to the git change-detection fast path (#766) (#949) Change detection's git fast path (collectGitStatus) consumed `git status` output with only an isSourceFile filter, on the assumption that git already omits ignored paths. It doesn't: gitignore is a no-op for *tracked* files, and the built-in default excludes (vendor/, node_modules/) aren't gitignore at all. So a tracked file inside a committed dependency dir, or under a .gitignored dir, surfaced as a change the full index never tracks — `codegraph status` reported phantom pending changes that `sync` (a filtered filesystem reconcile) never cleared, and the public getChangedFiles() API returned the same wrong list. Apply buildDefaultIgnore(repoDir) per recursion level, matching repo-relative paths — structurally equivalent to the full-index path's ScopeIgnore (each embedded repo judged by its own rules) with no extra git subprocess calls. Deletions stay unfiltered: getChangedFiles acts on one only when the path is already tracked in the DB, where removal is always correct, and that lets a newly-excluded dir's stale rows clean themselves up. Unblocks #699 (an .ignore overlay inherits this leak unless change detection consults the same matcher as enumeration). Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 查看 10 次提交的內容比對 »

14 小時之前

haiany 已經從鏡像同步並移除了參考 fix/936-ls-files-self-dir-entryhaiany/codegraph

14 小時之前

haiany 已經從鏡像同步了提交 mainhaiany/codegraph

  • e43ac82cdf fix(mcp): reopen the database when it's replaced on disk instead of serving a deleted inode (#925) (#940) A long-lived `serve --mcp` process opens `.codegraph/codegraph.db` and holds the fd for its whole life. If `.codegraph/` is removed and recreated AT THE SAME PATH while it runs — `git worktree remove <p>` + re-add, or `rm -rf .codegraph` + `codegraph init` — the held fd points at the now-unlinked inode and can never see the new index. The server serves the pre-removal snapshot (renamed/removed symbols still "live", new ones missing); `codegraph sync` can't refresh it and the CLI (a fresh process) diverges. Only a restart fixed it — and because the daemon registry is keyed by path, a same-path recreate routes new clients straight back to the same stale daemon, so the fix has to self-heal inside the running process. - DatabaseConnection records the DB file's (dev, ino) at open and exposes isReplacedOnDisk() — a different inode now at the same path. POSIX-gated: Windows can't unlink an open file and its st_ino is unreliable, so it never fires there. - CodeGraph.reopenIfReplaced() opens the live file first, then swaps the connection + query layers IN PLACE (via the new wireLayers() helper), so every holder of the instance (the daemon's default project, cached projectPath connections) heals without a restart. Closing the dead handle also frees the leaked db/-wal/-shm fds pinning the unlinked inode. - ToolHandler.getCodeGraph calls it (freshen) before serving — one stat() per call, a no-op unless the inode actually changed, never throws into a tool. Tests cover isReplacedOnDisk (unchanged / replaced / absent / Windows-gated) and an end-to-end reopen that heals a held instance after a same-path recreate (asserts the pre-heal staleness too). Validated on macOS with a dist probe of the raw instance and the MCP serving path; full suite green. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 62d5cdde2c fix(mcp): re-resolve a path's index every call so worktree state isn't pinned (#926) (#939) A long-lived MCP server (the shared daemon) cached both the project handle (projectCache) and the worktree-mismatch verdict (worktreeMismatchCache) for its whole lifetime — cleared only on shutdown — keyed off the input path and never re-checked. So a worktree path first resolved BEFORE it had its own .codegraph/ — when the walk-up reached the main checkout — stayed pinned to the main checkout: every query kept hitting the wrong index and every result carried a false "this index belongs to a different git working tree" warning, until the server restarted. The CLI was correct (fresh process per run); re-indexing didn't help. - getCodeGraph: re-resolve findNearestCodeGraphRoot on every call (cheap stat walk, no git, no reopen) and cache the open DB by RESOLVED ROOT only. Drops the input-path short-circuit that pinned the first resolution, and the double-keying (which also double-closed each instance in closeAll()). - worktreeMismatchFor: key the verdict on (startPath, indexRoot) so a changed index root recomputes instead of serving the stale "borrowed the parent's index" verdict. Adds a regression test that fails pre-fix (the stale warning survives the index-root flip); the existing "no further git spawn" caching test still passes. The query-staleness half (a second project opened through the handler) isn't unit-testable under vitest, so it was validated with a dist A/B. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • b218f625f7 Merge pull request #937 from colbymchenry/codegraph-ai Engine batch: dispatch-synthesizer family, React component/route coverage, installer UX + front-load hook
  • bd4814d8c1 feat(installer): stop auto-indexing on install + ship opt-in front-load prompt hook `codegraph install` no longer indexes the current directory — it wires up agents only, and building a project's graph is always the explicit `codegraph init` / `index`. Removes the global-vs-local inconsistency (a local install silently indexed, a global one didn't) and the docs/behavior mismatch (#826). README updated to match; the stale `init --index` note (indexing is default now) fixed. Adds an opt-in Claude Code front-load hook: a `UserPromptSubmit` hook that runs the new hidden `codegraph prompt-hook`, which injects codegraph_explore context for structural ("how / where / trace / impact") prompts so the agent answers from the graph instead of grepping to rebuild it. Prompted at install (default-yes; Claude-only — the only agent with prompt hooks), removed on uninstall, and `codegraph upgrade` self-heals it onto an already-configured global Claude install. Strictly additive + degradable: non-structural prompts, un-indexed projects, and any failure are silent no-ops. Disable without uninstalling via CODEGRAPH_NO_PROMPT_HOOK=1. 7 new installer-targets contract tests (write / idempotent / opt-out round-trip / sibling-preserved / uninstall / legacy-independent). Full suite green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 212dfc4b6a docs(changelog): note the sync cross-file caller-edge fix (#899) PR #927 (merged to main) fixed `sync()` dropping incoming cross-file calls/references edges on callee re-index but did not add a CHANGELOG entry; add it to [Unreleased] so it lands in the next release notes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 查看 34 次提交的內容比對 »

1 天之前

haiany 已經從鏡像同步了提交 fix/936-ls-files-self-dir-entryhaiany/codegraph

  • 621fdac6d6 fix(extraction): drop the `./` self-entry from `git ls-files --directory` (#936) When the indexed root is a directory an enclosing git repo ignores, `git ls-files --directory` collapses the whole cwd to a single literal `./` entry. That sentinel reached the `ignore` matcher, which rejects it ("path should be a `path.relative()`d string, but got "./""), aborting buildScopeIgnore — the one ignore-building call in FileWatcher.start(). So the MCP daemon's startWatching() threw, was caught as "Failed to open project", and auto-sync never started: the index silently went stale until a manual `codegraph sync` (CODEGRAPH_NO_DAEMON=1 was the only workaround). Filter the `./`/`.` self-entry wherever we consume `--directory` output (listIgnoredDirs + the untracked-dir loop in discoverEmbeddedRepoRoots). Semantically correct, not just a crash guard: `./` means "the whole cwd", never a nested repo to recurse into. Not platform-specific (reported on Codex/Windows, reproduced on macOS): the trigger is git state, not the OS. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • e43ac82cdf fix(mcp): reopen the database when it's replaced on disk instead of serving a deleted inode (#925) (#940) A long-lived `serve --mcp` process opens `.codegraph/codegraph.db` and holds the fd for its whole life. If `.codegraph/` is removed and recreated AT THE SAME PATH while it runs — `git worktree remove <p>` + re-add, or `rm -rf .codegraph` + `codegraph init` — the held fd points at the now-unlinked inode and can never see the new index. The server serves the pre-removal snapshot (renamed/removed symbols still "live", new ones missing); `codegraph sync` can't refresh it and the CLI (a fresh process) diverges. Only a restart fixed it — and because the daemon registry is keyed by path, a same-path recreate routes new clients straight back to the same stale daemon, so the fix has to self-heal inside the running process. - DatabaseConnection records the DB file's (dev, ino) at open and exposes isReplacedOnDisk() — a different inode now at the same path. POSIX-gated: Windows can't unlink an open file and its st_ino is unreliable, so it never fires there. - CodeGraph.reopenIfReplaced() opens the live file first, then swaps the connection + query layers IN PLACE (via the new wireLayers() helper), so every holder of the instance (the daemon's default project, cached projectPath connections) heals without a restart. Closing the dead handle also frees the leaked db/-wal/-shm fds pinning the unlinked inode. - ToolHandler.getCodeGraph calls it (freshen) before serving — one stat() per call, a no-op unless the inode actually changed, never throws into a tool. Tests cover isReplacedOnDisk (unchanged / replaced / absent / Windows-gated) and an end-to-end reopen that heals a held instance after a same-path recreate (asserts the pre-heal staleness too). Validated on macOS with a dist probe of the raw instance and the MCP serving path; full suite green. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 62d5cdde2c fix(mcp): re-resolve a path's index every call so worktree state isn't pinned (#926) (#939) A long-lived MCP server (the shared daemon) cached both the project handle (projectCache) and the worktree-mismatch verdict (worktreeMismatchCache) for its whole lifetime — cleared only on shutdown — keyed off the input path and never re-checked. So a worktree path first resolved BEFORE it had its own .codegraph/ — when the walk-up reached the main checkout — stayed pinned to the main checkout: every query kept hitting the wrong index and every result carried a false "this index belongs to a different git working tree" warning, until the server restarted. The CLI was correct (fresh process per run); re-indexing didn't help. - getCodeGraph: re-resolve findNearestCodeGraphRoot on every call (cheap stat walk, no git, no reopen) and cache the open DB by RESOLVED ROOT only. Drops the input-path short-circuit that pinned the first resolution, and the double-keying (which also double-closed each instance in closeAll()). - worktreeMismatchFor: key the verdict on (startPath, indexRoot) so a changed index root recomputes instead of serving the stale "borrowed the parent's index" verdict. Adds a regression test that fails pre-fix (the stale warning survives the index-root flip); the existing "no further git spawn" caching test still passes. The query-staleness half (a second project opened through the handler) isn't unit-testable under vitest, so it was validated with a dist A/B. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • b218f625f7 Merge pull request #937 from colbymchenry/codegraph-ai Engine batch: dispatch-synthesizer family, React component/route coverage, installer UX + front-load hook
  • bd4814d8c1 feat(installer): stop auto-indexing on install + ship opt-in front-load prompt hook `codegraph install` no longer indexes the current directory — it wires up agents only, and building a project's graph is always the explicit `codegraph init` / `index`. Removes the global-vs-local inconsistency (a local install silently indexed, a global one didn't) and the docs/behavior mismatch (#826). README updated to match; the stale `init --index` note (indexing is default now) fixed. Adds an opt-in Claude Code front-load hook: a `UserPromptSubmit` hook that runs the new hidden `codegraph prompt-hook`, which injects codegraph_explore context for structural ("how / where / trace / impact") prompts so the agent answers from the graph instead of grepping to rebuild it. Prompted at install (default-yes; Claude-only — the only agent with prompt hooks), removed on uninstall, and `codegraph upgrade` self-heals it onto an already-configured global Claude install. Strictly additive + degradable: non-structural prompts, un-indexed projects, and any failure are silent no-ops. Disable without uninstalling via CODEGRAPH_NO_PROMPT_HOOK=1. 7 new installer-targets contract tests (write / idempotent / opt-out round-trip / sibling-preserved / uninstall / legacy-independent). Full suite green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 查看 10 次提交的內容比對 »

1 天之前

haiany 已經從鏡像同步了參考 fix/936-ls-files-self-dir-entryhaiany/codegraph

1 天之前

haiany 已經從鏡像同步了提交 codegraph-aihaiany/codegraph

  • bd4814d8c1 feat(installer): stop auto-indexing on install + ship opt-in front-load prompt hook `codegraph install` no longer indexes the current directory — it wires up agents only, and building a project's graph is always the explicit `codegraph init` / `index`. Removes the global-vs-local inconsistency (a local install silently indexed, a global one didn't) and the docs/behavior mismatch (#826). README updated to match; the stale `init --index` note (indexing is default now) fixed. Adds an opt-in Claude Code front-load hook: a `UserPromptSubmit` hook that runs the new hidden `codegraph prompt-hook`, which injects codegraph_explore context for structural ("how / where / trace / impact") prompts so the agent answers from the graph instead of grepping to rebuild it. Prompted at install (default-yes; Claude-only — the only agent with prompt hooks), removed on uninstall, and `codegraph upgrade` self-heals it onto an already-configured global Claude install. Strictly additive + degradable: non-structural prompts, un-indexed projects, and any failure are silent no-ops. Disable without uninstalling via CODEGRAPH_NO_PROMPT_HOOK=1. 7 new installer-targets contract tests (write / idempotent / opt-out round-trip / sibling-preserved / uninstall / legacy-independent). Full suite green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 212dfc4b6a docs(changelog): note the sync cross-file caller-edge fix (#899) PR #927 (merged to main) fixed `sync()` dropping incoming cross-file calls/references edges on callee re-index but did not add a CHANGELOG entry; add it to [Unreleased] so it lands in the next release notes. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 64426cad93 fix(react): recognize forwardRef/memo/styled components + index JSX-file routes (#841) forwardRef/memo/styled-wrapped component consts were classified as plain `constant` nodes (the initializer is a call/tagged-template, not a bare arrow), so the JSX-render synthesizer and component resolution skipped them — callers and impact returned empty for the entire shadcn/ui-style UI layer. Recognize them in the tree-sitter extractor as `component` nodes (correct body range + callee capture), PascalCase-gated so a memoization util stays a constant. Separately, the `react` resolver's `languages` lacked 'tsx'/'jsx', so its `extract()` never ran on JSX files — React Router `<Route>`/createBrowserRouter and Next.js page routes (which only live in .tsx/.jsx) were never indexed. Add 'tsx'/'jsx' and make `extract()` route-only: the component/hook regex it carried duplicated tree-sitter nodes (a `useAuth` became two `function` nodes) and is fully superseded by the extractor now. Validated before/after: taxonomy 0->99 component nodes (35 w/ callers) + 1->15 routes; radix 0->262 components (80 w/ callers); cypress-realworld-app 45->52 routes (7 <Route> tags from .tsx); non-React control unchanged; node count stable. New tests: react-hoc-component.test.ts + a route e2e in frameworks-integration.test.ts. Root-caused by @maxmilian (#846); reported by @Arlandaren. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • b5090cbad5 docs(dispatch-backlog): shelve trezor barrel-registry as single-lineage/overfit Discovery across 15 independent diverse repos + GitHub-wide code search found the strict barrel-namespace shape (`import * as M from './api'` -> `M[runtimeKey]` -> `new` -> `.run()`) in exactly 2 repos: trezor-suite and OneKey hardware-js-sdk. But OneKey is a @trezor/connect fork (same findMethod/MethodConstructor skeleton), so it's 2 indexable repos but one design lineage = effectively n=1. Every independent registry-by-runtime-key found is a different shape the trezor-tuned synth wouldn't catch (n8n dynamic-import+DI, polkadot array-of-constructors, ccxt object-literal [already covered], typeorm/xrpl switch). The synth is the hard tier (cross-file barrel re-export enumeration + computed index + camel/Pascal transform + entry-method fan-out) -- meaningful complexity for a single-lineage win, which the overfit discipline says not to build. Feasibility was fine (the import resolver already chases re-export barrels); the blocker is corpus thinness. Reopen only if an independent (non-trezor-lineage) repo appears. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • feb2f641de feat(resolution): bridge Laravel event(new X) to its listener handles Laravel decouples an event dispatch from its listener(s), linked by the event class: event(new OrderShipped($order)) has no static edge to the handle(OrderShipped $event) that runs it (usually a separate app/Listeners/ class). laravelEventEdges bridges each event(new X(...)) site -> every listener's handle for X. Two registration mechanisms, both real and both needed (built together): - (A) auto-discovery: a typed handle(EventType $e) first param, read from the method declaration source (PHP method nodes carry no signature, like C#); a handle(A|B $e) union is split into two events. - (B) the `protected $listen = [XEvent::class => [Listener::class, ...]]` map in an EventServiceProvider, parsed from comment-stripped source (so a fully-commented map on an auto-discovery app contributes nothing). This is the only way to link a listener whose handle() is untyped. Job exclusion is free: queued jobs dispatch via ::dispatch()/dispatch() (not matched) and their handle() takes an injected service, never an event type, so matching only event(new X) excludes them by construction. `use Dispatchable` is not keyed on (unreliable in real apps). Surfaces as `dynamic: laravel event` via the generic synth-edge fallback. Validated 100% precision on two grep-confirmed repos exercising both mechanisms: koel (small, populated $listen map, 9 edges incl. the untyped-handle case and a fan-out) and firefly-iii (large, pure auto-discovery / empty $listen, 141 edges, 0 source/target false positives, 0 namespace mismatch, union split verified); 0 on the guzzle control. Namespace-agnostic (FireflyIII\ not hardcoded). Node-stable (pure edge synth). Suite 1623 green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 查看 5 次提交的內容比對 »

1 天之前

haiany 已經從鏡像同步了提交 codegraph-aihaiany/codegraph

  • 2c522c6254 feat(resolution): bridge Sidekiq Worker.perform_async to #perform Sidekiq decouples a job's enqueue site from the worker's perform method, linked by the worker class NAME: DestroyUserWorker.perform_async(id) has no static edge to DestroyUserWorker#perform (usually in app/workers/, away from the controller/model that enqueues it). sidekiqDispatchEdges bridges each Worker.perform_async/_in/_at(...) site -> that worker's instance perform. Name-keyed, like Celery: the receiver class must be a Sidekiq worker, gated by reading `include Sidekiq::Job|Worker` from the class body (the mixin is an external gem module that forms no resolvable edge). ActiveJob's perform_later/ _now is a different shape and deliberately not matched. Namespace disambiguation was the n>1 validation payoff: loomio's flat workers hid a collision bug that forem exposed (four SendEmailNotificationWorker classes across modules; simple-name resolution mis-targeted 7/143 edges to the wrong namespace). Fixed by resolving a namespaced receiver via exact qualified-name lookup first, falling back to the simple name only for a unique worker — an ambiguous unqualified collision bails (precision over recall). Surfaces as `dynamic: sidekiq dispatch` via the generic synth-edge fallback. Validated 100% precision on two grep-confirmed repos: loomio (medium, Sidekiq::Worker, 47 edges) and forem (large, both include aliases — 131 Sidekiq::Job + 11 Sidekiq::Worker, 142 edges, 0 worker/source false positives, 0 namespace mismatch); 0 on the jekyll control. Node-stable (pure edge synth). Suite 1621 green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • d1381e11f6 feat(resolution): bridge MediatR Send/Publish to its IRequestHandler.Handle MediatR decouples a _mediator.Send(x)/.Publish(x) call from the Handle method that runs it, linked by the request/notification TYPE (the IRequestHandler<X,…> generic), usually across files in a Clean Architecture layout — so flows dead-end at the mediator call and the agent reads to find the handler. mediatrDispatchEdges bridges each dispatch -> the matching handler's Handle. Same two-pass, type-keyed shape as the Spring synthesizer, with two C#-specific twists found by probing: - C# method nodes carry NO signature (csharp.ts defines no getSignature), so Pass 1 reads the request type from the handler CLASS base-list source (`: IRequestHandler<X,…>` first generic arg) and binds the class's Handle. - The dominant .NET idiom is VARIABLE-passed, not inline `Send(new X)` — eShop has zero genuine inline MediatR sends. So Pass 2 resolves the sent type from the argument three ways within the enclosing method: inline `new X(…)`, a local `var v = new X(…)` (backward scan), or a parameter/local declared `X v`. Two precision gates: the receiver must be mediator-ish (mediator/sender/ publisher — excludes MAUI MessagingCenter.Send, HttpClient.Send) AND the resolved type must have a handler (so a same-named non-request DTO is never bridged). Handles the IdentifiedCommand<T,R> wrapper and void IRequestHandler<T>. Surfaces as `dynamic: mediatr dispatch` via the generic synth-edge fallback. Validated 100% precision on two grep-confirmed repos: jasontaylordev/ CleanArchitecture (small, 9 edges, inline + param forms) and dotnet/eShop (medium, 9 edges, 0 false positives, variable-passed + IdentifiedCommand + the CancelOrderCommand DTO-collision correctly avoided); 0 on the Newtonsoft.Json control. Node-stable (pure edge synth). Suite 1619 green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 8591ea5993 chore: gitignore docs/business/ (confidential, keep out of public repo) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 9b7ca2e394 feat(resolution): bridge Spring publishEvent() to its @EventListener handlers Spring decouples an event publisher from its listener(s) through the application event bus, linked by the event TYPE: publishEvent(new XEvent(...)) has no static edge to the @EventListener void on(XEvent e) that handles it (usually a different class), so flows dead-end at the publish and the agent reads to find the handlers. springEventEdges bridges each publishEvent(new X) site -> every listener of X. Two-pass, type-keyed (no name resolution, so precision is structural): - Pass 1 builds Map<eventType, listenerMethod[]> from @EventListener / @TransactionalEventListener methods (event type = first param type off the node signature, or the @EventListener(X.class) value form) and the older `implements ApplicationListener<X>` onApplicationEvent methods. - Pass 2 links each publishEvent(new XEvent(...))'s enclosing method to every listener of XEvent; multi-line `publishEvent(\n new X(...))` handled. Key Java fact (probed): a method node's range INCLUDES its leading annotations (startLine is the first @-line, not the `public void` decl), so the annotation gate scans DOWNWARD from startLine bounded to consecutive @-lines, which can't bleed into an adjacent method. Surfaces as `dynamic: spring event` via the generic synth-edge fallback. Validated 100% precision on two grep-confirmed repos exercising all listener forms: halo (medium, 1254 java, 33 edges across 24 events, 0 publisher/listener false positives, param-typed + (X.class) + ApplicationListener + fan-out) and thombergs/code-examples (4 edges, adds @TransactionalEventListener); 0 on the gson control (no Spring). Node-stable (pure edge synth). Suite 1617 green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 查看 4 次提交的內容比對 »

1 天之前

haiany 已經從鏡像同步了提交 codegraph-aihaiany/codegraph

  • 6e5c3a9336 feat(resolution): bridge Celery .delay()/.apply_async() dispatch to the task body Celery decouples a task's call site from its body: a @shared_task / @app.task decorated def is invoked via task.delay(...) / task.apply_async(...), a dynamic hop with no static edge, so flows dead-end at the dispatch and the agent reads tasks.py to reconstruct them. celeryDispatchEdges links the enclosing function at each .delay/.apply_async site -> the task function body. Precision rests on a DECORATOR gate: the dispatched name must resolve to a Python function carrying a task decorator, read from the source lines ABOVE its def (the def's startLine excludes the decorator, and no decorates edge exists since @shared_task is an unresolved external import). The kind==='function' filter drops same-named test-method collisions; canvas forms (group(t).delay(), t.s()/.si()) have no single identifier before .delay so they're skipped, not mis-bridged; cross-module name collisions prefer a same-file task else bail. Surfaces as `dynamic: celery dispatch` via the generic synth-edge fallback. Validated 100% precision on two grep-confirmed repos exercising both decorator dialects: paperless-ngx (small, @shared_task, 31 edges, 31/31 real) and pretix (medium, @app.task, 63 edges across 21 tasks, 0/21 false positives); 0 on the httpie control (no Celery). Node-stable (pure edge synth). Suite 1615 green. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 80a1044d3d feat(resolution): bridge Vuex string dispatch/commit to actions and mutations Completes the Vue store dispatch family (the Pinia bridge was 8ea3205). Vuex dispatches by a runtime STRING key — `dispatch('user/login')` / `commit('SET_TOKEN')` / `this.$store.dispatch('app/toggleDevice')` — with no static edge to the handler. vuexDispatchEdges (callback-synthesizer.ts): the last `/` segment of the key is the action/mutation name, the preceding segment is the namespace (≈ the module file). Resolve the name to a function node IN A STORE FILE — the ≥2-signal store-file gate excludes a same-named `api/` helper (`getInfo`/`login` collide in practice) — disambiguated by the immediate namespace segment appearing in the path (handles deep nesting like `d2admin/user/set`), or the same file for a root local `commit('M')` inside an action. The .vue component is a dispatcher fallback for top-level setup calls. Surfaces in explore as `dynamic: vuex dispatch`. Also extracts the canonical Vuex MODULE shape `export default { namespaced, actions: {…}, mutations: {…} }` (tree-sitter.ts: extractStoreCollectionMethods off the export_statement, store-file gated) — its object-literal methods were otherwise never nodes, so d2-admin's actions couldn't be bridged. Validated 100% precision on three repos — vue-element-admin (55 edges), vue-admin-template (12), d2-admin (63): 0 non-store targets, 0 namespace mismatches (54/54 namespaced edges route to the correct module despite 6 colliding `load` actions in d2-admin), 0 on Redux controls (basetool/uwave — non-string `dispatch()` correctly ignored). Suite green (1613); new __tests__/vuex-dispatch-synthesizer.test.ts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 8ea32059b6 feat(resolution): bridge Pinia useStore().action() calls to the action The dispatch bridge for Pinia, on top of the store-action extraction foundation (cc9c2f7). A consumer does `const store = useXStore()` then `store.action()` — a method-on-instance call with no static edge to the action, which lives in the store module. So tracing "what does this view do when it loads" stopped at the `store.fetchUser()` line. piniaStoreEdges (callback-synthesizer.ts): map each `const useXStore = defineStore(...)` factory → its file; per consumer file, bind `const s = useXStore()` vars; link the enclosing function (or the .vue component, via a fallback) → the `s.method()` action node IN THE STORE'S FILE. The same-store-file gate is the precision lever — a Pinia built-in (`$patch`) or an unrelated same-named method resolves to nothing. Covers the options and setup store forms uniformly (the action is a function node in the store file either way) and surfaces in explore as `dynamic: pinia store`. Validated 100% precision (Geeker 41 edges, MallChat 64; 0 targets outside a store file), 0 on the Vuex-only element-admin control (no defineStore), n=2 in hand. Suite green (1612); new __tests__/pinia-store-synthesizer.test.ts. The Vuex string-key dispatch bridge (`dispatch('ns/action')`) remains a follow-up (n=1 in hand — needs a 2nd string-literal Vuex repo). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • cc9c2f7420 feat(extraction): index Vuex/Pinia store actions, mutations, and getters A Vue store's callable surface — Vuex `actions`/`mutations`/`getters` and Pinia store actions — lived only as object-literal properties, so the symbols an agent looks for (`login`, `getSessionList`, `getAuthMenuList`) were never nodes: `codegraph search`/`codegraph_node` returned "not found" and the agent had to read the store by hand. This extracts them as function nodes (with their real bodies + callees), the foundation under any later dispatch-bridge synthesis. A corpus probe (vue-element-admin, vue2-elm, Geeker-Admin, MallChatWeb) showed Vue store dispatch is NOT one clean string-keyed shape but ~5; extraction here covers the three dominant definition forms: - Vuex MODULE: non-exported `const actions/mutations = {…}` collections (gated by a ≥2-signal looksLikeVueStoreFile + the object-of-functions shape, so a Redux file's stray `const actions` is a 0-node no-op). - Pinia OPTIONS: `defineStore({ actions: {…}, getters: {…} })` — methods of the actions/mutations/getters properties of a store-factory config. - Pinia SETUP: `defineStore('id', () => { const foo = …; return {…} })` — the body-local function consts (findPiniaSetupFn + extractPiniaSetupBody; the generic body walk doesn't reach nested function scopes). Distinguished from an inline action map via objectHasInlineFunctions so zustand/SvelteKit extraction is unchanged. Validated findable on element-admin (50 fns), Geeker (21), MallChat (68); 0-node no-op on a non-Vue control (uwave-web, unchanged at 4496 nodes). Deferred (documented in the backlog): vue2-elm's `export default {…}` split-file + computed-key `commit(CONST)` form (n=1), and the dispatch BRIDGE synthesis (Vuex string-key + Pinia useStore().action()). Suite green (1610); new __tests__/vue-store-extraction.test.ts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • e9f7422223 feat(resolution): synthesize RTK Query hook→endpoint dispatch edges Adds the RTK Query member of the dispatch-through-indirection family (synthesizedBy:'rtk-query'). An RTK Query endpoint defined inside `createApi({ endpoints })` and the `useGetXQuery`/`useUpdateYMutation` hook it generates were both invisible to static extraction, so a `component → useGetXQuery → getX → queryFn` flow had nothing to connect and explore dead-ended on the API slice. Extraction (tree-sitter.ts): mint a function node per endpoint — named by its key, spanning the queryFn/query handler so its calls attribute — handling both the `endpoints: build => ({...})` arrow and `endpoints(builder){ return {...} }` method forms, with a bare-node fallback for factory handlers (`queryFn: makeFn(url)`); and a function node per generated-hook binding from `export const {...} = api`, carrying a sentinel signature. Resolution (callback-synthesizer.ts): rtkQueryEdges bridges each generated-hook node to its same-file endpoint by the naming convention (strip use + optional Lazy + Query|Mutation, lowercase head). Component→hook is normal import/call resolution; the hook→endpoint hop surfaces in explore as `dynamic: rtk query`. Validated 100% precision (hooks == synth edges, 0 cross-file) on basetool (54), minusx-metabase (11), shapeshift (13); 0 on the uwave-web control (no createApi → a complete no-op). The sentinel gate correctly ignores hand-written look-alikes (shapeshift's useFoxyQuery is a real custom hook, never bridged). Full suite green (1608); new __tests__/rtk-query-synthesizer.test.ts. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 查看 7 次提交的內容比對 »

2 天之前

haiany 已經從鏡像同步了提交 codegraph-aihaiany/codegraph

  • e5897d0334 feat: remove reasoning offload / CodeGraph AI managed reasoning feature Strips the bring-your-own-model reasoning offload and managed CodeGraph AI integration (login/logout/usage commands, offload config/credentials/reasoner modules, and the synthesizeOffload call in codegraph_explore). The eval findings showed raw source output outperformed the synthesized path on accuracy, so codegraph_explore reverts to returning verbatim retrieved source exclusively. CHANGELOG and README sections for reasoning offload are removed; test comments and DEFAULT_MCP_TOOLS description are updated to drop offload references.
  • e7d9f8c6fa feat(explore): surface interface/registry dispatch boundaries and window oversize spine methods Two gaps closed in `codegraph_explore` output quality: **Interface/registry dispatch (#687 extension).** When a named token resolves to a large same-name family (≥8 members) that doesn't land on the connected flow, the static path truly ends there — the target is chosen at runtime from N implementations (plugin/strategy/handler interface). `buildPolymorphicBoundaries` detects this via `implements`/`extends` edges, ranks candidate supertypes by their TRUE graph-wide implementer count (not FTS sample frequency, which is biased), and emits a "## Interface dispatch" section naming the supertype, implementer count, and a few concrete targets. Fires only for uncovered named tokens; a connected flow stays silent. **Oversize spine method windowing.** A flow entry that is a god-method (e.g. n8n's 962-line `processRunExecutionData`) previously lost the per-file budget to denser peripheral blocks and was dropped, forcing the agent to `Read` it back. The spine call site (edge line to the next hop) is now tracked via `spineCallSites` and used to window the method to its signature head + a ±28-line band around the call, keeping it under the OVERSIZE_SPINE_LINES threshold. Spine clusters also rank first in the budget sort and may exceed the per-file cap up to a 2.5× ceiling so they can never be starved by co-flow files. Test suite gains an `interface dispatch` describe block (announce, silent-on-connected, silent-below-threshold) and uses `beforeAll`/`afterAll` to pin `CODEGRAPH_OFFLOAD_DISABLE=1` so structural assertions are hermetic regardless of machine config.
  • 查看 2 次提交的內容比對 »

2 天之前

haiany 已經從鏡像同步了提交 codegraph-aihaiany/codegraph

  • 4f8782cbe5 test(agent-eval): add output-style A/B harness, cost/token analyzer, and DISALLOW/REP_START controls Three additions to tighten the eval loop: - offload-eval-styles.sh: new 4-arm eval (raw/refs/map/src) isolating the Worker's output shape's effect on main-session tokens, latency, and accuracy. Delegation blocked by default (DISALLOW=Agent) so variance from Haiku subagent spawning doesn't contaminate the measurement. - offload-eval-cost.mjs: cost/token analyzer that reads Claude Code's own per-model accounting (modelUsage.costUSD) rather than re-deriving from raw token counts, giving a correct main(Sonnet)/sub(Haiku) split with proper per-tier pricing. - offload-eval-3arm.sh: adds DISALLOW env to block sub-agent delegation across all arms, and REP_START to append reps to an existing run without clobbering earlier jsonls (e.g. REP_START=4 REPS=3 → reps 4,5,6). Also adds CODEGRAPH_OFFLOAD_STYLE forwarding to the managed gateway so the styles eval can drive output shape end-to-end; the field is stripped before the upstream model call and never sent to BYO endpoints.

3 天之前

haiany 已經從鏡像同步了提交 mainhaiany/codegraph

  • 4aa2752ef1 chore: stop tracking .claude/handoffs (local session notes only)

4 天之前

haiany 已經從鏡像同步了提交 codegraph-aihaiany/codegraph

  • 291b200ece chore: stop tracking .claude/handoffs (local session notes only)
  • f82a662ddb feat(mcp): pare default tool surface to codegraph_explore alone + redux-thunk synthesizer
  • 7ddd3fa7eb test(agent-eval): persist offload accuracy/adoption eval harness + front-load hook Reproducible suite measuring the managed CodeGraph AI offload and the front-load UserPromptSubmit hook (approach 1) vs raw codegraph and no-codegraph, across repo sizes, on time / main-session tokens+cost / CodeGraph-AI tokens+cost / accuracy. All agent arms run claude -p sonnet --effort high; eval-only, nothing shipped. - offload-eval-setup.sh: clone + index 4 memory-probe-verified "not-trained-on" repos (mtkruto/postybirb/shapeshift/trezor — small→large) so the no-codegraph baseline is honest. - offload-eval-3arm.sh / -frontload.sh: one repo, the arms (offload/raw/nocg, frontload). - offload-eval-matrix.sh / -frontload-matrix.sh: drive all 4 tiers. - offload-eval-hook.mjs: the front-load hook (self-locates its engine; CG_FRONTLOAD_DEBUG to log). - offload-eval-metrics.mjs / -judge.mjs (Sonnet) / -summarize.mjs: extract, score, aggregate. - offload-eval-ground-truth.json: source-verified canonical flows (the judge's reference). - offload-eval.md: usage + the 2026-06 findings (raw = the win; offload least-accurate; front-load solves adoption but exposes explore's dynamic-dispatch gaps). Scripts are path-portable (self-locating $HERE/$ENGINE; AGENT_EVAL_OUT scratch dir). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 6d5cb6b25c feat(reasoning): add `CODEGRAPH_OFFLOAD_DISABLE` kill-switch and per-call usage log `CODEGRAPH_OFFLOAD_DISABLE=1` immediately disables the offload for the current process without touching the persisted config or stored login — useful for A/B arms or sessions where raw source is preferred. `CODEGRAPH_OFFLOAD_USAGE_LOG=` appends one JSONL entry per call with token counts, charged credits, and derived cost (`creditsCharged / 100_000`) so a harness can attribute CodeGraph AI spend to a single run independently of the server's cumulative totals. Both features are best-effort and never disrupt the degradable offload path. Also fixes the `login` credit display to check `unlimited` before the numeric balance, so comped/internal accounts don't incorrectly show "0 remaining".
  • 查看 4 次提交的內容比對 »

4 天之前

haiany 已經從鏡像同步了提交 codegraph-aihaiany/codegraph

  • c9e207a0f2 feat(cli): add `codegraph usage` command to show AI balance and recent usage Adds a `usage` subcommand that pings `/v1/usage` with the stored token and displays balance, plan, 30-day explore/token counts, and allowance reset date. Degrades quietly in all non-happy-path states — signed out, BYO endpoint, or unreachable server — so managed reasoning remaining optional doesn't change. Also extends `OffloadUsage` with the fields the endpoint already returns (`unlimited`, `banned`, `tokensLast30`, `callsLast30`, `creditsLast30`) that were previously untyped.
  • 193722de45 feat(cli): replace `offload` subcommands with browser device-authorization `login` / `logout` The old `offload` command family required users to paste a token manually (`offload login --token `) and exposed bring-your-own-endpoint plumbing (`set-endpoint`, `status`, `disable`) as top-level CLI surface. This replaces it with a standard OAuth device flow (RFC 8628 shape) against the CodeGraph dashboard. `codegraph login` calls `/api/cli/device/start`, opens the browser to the returned URL, polls `/api/cli/device/token` until the user approves, then stores the minted token and enables managed reasoning. `codegraph logout` clears it. BYO-endpoint configuration moves entirely to env vars (`CODEGRAPH_OFFLOAD_URL` / `CODEGRAPH_OFFLOAD_KEY` / `CODEGRAPH_OFFLOAD_MODEL`), keeping the CLI surface minimal.
  • 8aa05380a2 Merge branch 'feat/offload-byo' into codegraph-ai
  • 3ba82681ea Merge branch 'fix/explore-corroboration-ranking' into codegraph-ai
  • da5c6c2f79 feat(offload): managed tier (CodeGraph AI) — metered reasoning via org token [WIP] Adds the managed offload mode: point codegraph_explore at the CodeGraph AI metered gateway (https://ai.getcodegraph.com) with an org token instead of a BYO provider key. Same synthesis client, pointed at codegraph-ai-proxy (a metered OpenAI-compatible gateway). - credentials.ts — org token in ~/.codegraph/credentials.json (0600); unlike a BYO provider key it's a revocable org-scoped auth token (gh/npm-login style), kept out of config.json - config.ts — managed branch in resolveOffload: default gateway URL + public model id (openai/gpt-oss-120b) + login token as bearer; managed requires a token to be enabled - reasoner.ts — fetchUsage() reads the credit balance from /v1/usage - bin/codegraph.ts — `codegraph offload login --token <t>` / `logout`; status shows the managed tier + live balance Proven GREEN end-to-end against a local wrangler-dev of the proxy: org token validated, credits prechecked, real Cerebras synthesis returned, and credits metered + charged (250,000 → 248,473). Graceful degrade on upstream failure; balance via /v1/usage. Phase 3 (codegraph login device flow) replaces the manual --token. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 查看 10 次提交的內容比對 »

5 天之前

haiany 已經從鏡像同步了參考 codegraph-aihaiany/codegraph

5 天之前

haiany 已經從鏡像同步了提交 fix/explore-corroboration-rankinghaiany/codegraph

  • 798cd0e21c fix(explore): keep multi-term backend files from being buried by a denser frontend layer codegraph_explore's file sort is primarily driven by Random-Walk-with-Restart graph-centrality mass, seeded from the query's text matches. In a cross-layer monorepo (an API server alongside a much larger, internally dense frontend that mirrors the same domain words), that mass skews to the bigger layer — so a backend service/handler that genuinely matches several query terms, even when it's the #1 search hit, sorts below hits=0 frontend files and gets truncated out of the response, and the agent reads it back. Add a corroboration tier above the graph signal: a file that is BOTH an entry/central file AND matched by >=2 distinct query terms is kept in. The entry/central guard prevents an incidental multi-term file (a type/util file that isn't the flow) from displacing a graph-central answer file — a blunt hits-only tier regressed that case. Single-layer repos are unaffected. Gated by CODEGRAPH_RANK_NO_MULTITERM=1. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • f34f606342 feat(extraction): same-file value-reference edges for impact analysis — 15 languages (#897) Adds same-file value-reference edges (reader symbol → const/var it reads) so impact analysis catches a constant's same-file consumers, closing the 'change this table, break its readers' hole. 15 languages validated S/M/L on public OSS: TS/JS/tsx, Go, Python, Rust, Ruby, C, Java, C#, PHP, Scala, Kotlin, Swift, Dart, Pascal/Delphi (+ Svelte/Vue/Astro inherited). Edges-only — node count identical on/off; default ON, CODEGRAPH_VALUE_REFS=0 opts out.
  • 2f6316500d feat(extraction): enable same-file value-reference edges by default (TS/JS) (#895) Value-reference edges (same-file `references` edges from a reader to the file-scope const/var it reads) shipped behind CODEGRAPH_VALUE_REFS pending an agent A/B. The A/B is in: on excalidraw the edges are correct and precise (node count unchanged) and they transform the impact/blast-radius API — `impact` on a const consumed by 103 readers goes from 1 affected symbol to the full radius. That blast-radius API is what `codegraph impact` and CodeGraph Pro's verdict engine consume, so the win is impact correctness; the agent path showed no regression. Flip the default on; CODEGRAPH_VALUE_REFS=0 disables. Also close the one precision gap the A/B surfaced: a bundled/Emscripten `const Module` re-declared as an inner `var Module` / param produced false positives (nested readers resolve to the inner binding). isGeneratedFile() is path-only and can't catch content-minified bundles, so prune SHADOWED targets at the syntax level — drop any value-ref target whose name is bound by more than one `variable_declarator` in the file. On excalidraw this removes the 23 false positives while preserving every real reader (impact unchanged at 170). Adds regression coverage (there was none): same-file readers are edged, they surface in the impact radius, shadowed consts are NOT edged, and CODEGRAPH_VALUE_REFS=0 emits nothing. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • b49147eab0 fix(cli): make `codegraph index` a full rebuild so it stops reporting 0 nodes (#874) (#894) `codegraph index` ran extraction against the already-populated DB without clearing it first. On an unchanged tree every file's content hash still matched, so the orchestrator skipped re-inserting all of them and the run reported its delta (after - before = 0) as "0 nodes, 0 edges" — which read as if `index` had wiped the graph. `init` only ever differed because it runs on a freshly created, empty DB. Clear the existing graph before re-indexing so `index` rebuilds from scratch and reports the same complete result as a fresh `init`. `--force` keeps its role as the home-dir/root-path override; `sync` stays the incremental path. Adds an end-to-end regression test driving the built binary (init -> index), asserting the graph stays populated and the summary is never "0 nodes, 0 edges". Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • ab107b325a fix(watcher): warn (don't degrade) on Linux inotify watch exhaustion (ENOSPC) (#893) On the Linux per-directory watch path, hitting fs.inotify.max_user_watches surfaces as ENOSPC — which the degrade logic added for #876 (EMFILE/ENFILE only) did not catch, so it fell through to the silent "skip this directory" branch: a large repo got a partial watch set with no hint why edits in unwatched directories stopped auto-syncing. ENOSPC is non-fatal — raise the limit and partial watching keeps working — so it now warns ONCE, naming the exact knob (fs.inotify.max_user_watches, with the sysctl to set it), instead of degrading. It also stops attempting further doomed watches for the session (every inotify_add_watch would fail too). Installed watches keep firing; `codegraph sync` / git sync hooks cover the remainder. Validated on macOS (forced per-directory path) and real Linux (Docker) — the new test asserts a single warning naming fs.inotify.max_user_watches, no degrade, and a live partial watch. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 查看 10 次提交的內容比對 »

5 天之前

haiany 已經從鏡像同步了參考 fix/explore-corroboration-rankinghaiany/codegraph

5 天之前

haiany 已經從鏡像同步了提交 feat/offload-byohaiany/codegraph

  • db4c9f3641 feat(offload): reasoning offload for codegraph_explore (bring-your-own endpoint) codegraph_explore can now hand the source it retrieved to a reasoning model you point at — any OpenAI-compatible endpoint (Cerebras, OpenAI, a local vLLM/Ollama) with your own key — and return that model's tight, cited answer instead of the raw source dump. The agent's main context gets the answer in far fewer tokens, at the cost of one network round-trip. Off by default. Configure with `codegraph offload set-endpoint <url> --model <m> --key-env <ENV>` (or the CODEGRAPH_OFFLOAD_* env vars); status/disable manage it. The API key is never written to disk — the config stores the NAME of an env var and the key is read from it at call time. Strictly degradable: any failure (no endpoint, network, timeout, empty answer) returns null and the call falls back to the local source, so the offload can never surface an error to the agent. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • f34f606342 feat(extraction): same-file value-reference edges for impact analysis — 15 languages (#897) Adds same-file value-reference edges (reader symbol → const/var it reads) so impact analysis catches a constant's same-file consumers, closing the 'change this table, break its readers' hole. 15 languages validated S/M/L on public OSS: TS/JS/tsx, Go, Python, Rust, Ruby, C, Java, C#, PHP, Scala, Kotlin, Swift, Dart, Pascal/Delphi (+ Svelte/Vue/Astro inherited). Edges-only — node count identical on/off; default ON, CODEGRAPH_VALUE_REFS=0 opts out.
  • 2f6316500d feat(extraction): enable same-file value-reference edges by default (TS/JS) (#895) Value-reference edges (same-file `references` edges from a reader to the file-scope const/var it reads) shipped behind CODEGRAPH_VALUE_REFS pending an agent A/B. The A/B is in: on excalidraw the edges are correct and precise (node count unchanged) and they transform the impact/blast-radius API — `impact` on a const consumed by 103 readers goes from 1 affected symbol to the full radius. That blast-radius API is what `codegraph impact` and CodeGraph Pro's verdict engine consume, so the win is impact correctness; the agent path showed no regression. Flip the default on; CODEGRAPH_VALUE_REFS=0 disables. Also close the one precision gap the A/B surfaced: a bundled/Emscripten `const Module` re-declared as an inner `var Module` / param produced false positives (nested readers resolve to the inner binding). isGeneratedFile() is path-only and can't catch content-minified bundles, so prune SHADOWED targets at the syntax level — drop any value-ref target whose name is bound by more than one `variable_declarator` in the file. On excalidraw this removes the 23 false positives while preserving every real reader (impact unchanged at 170). Adds regression coverage (there was none): same-file readers are edged, they surface in the impact radius, shadowed consts are NOT edged, and CODEGRAPH_VALUE_REFS=0 emits nothing. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • b49147eab0 fix(cli): make `codegraph index` a full rebuild so it stops reporting 0 nodes (#874) (#894) `codegraph index` ran extraction against the already-populated DB without clearing it first. On an unchanged tree every file's content hash still matched, so the orchestrator skipped re-inserting all of them and the run reported its delta (after - before = 0) as "0 nodes, 0 edges" — which read as if `index` had wiped the graph. `init` only ever differed because it runs on a freshly created, empty DB. Clear the existing graph before re-indexing so `index` rebuilds from scratch and reports the same complete result as a fresh `init`. `--force` keeps its role as the home-dir/root-path override; `sync` stays the incremental path. Adds an end-to-end regression test driving the built binary (init -> index), asserting the graph stays populated and the summary is never "0 nodes, 0 edges". Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • ab107b325a fix(watcher): warn (don't degrade) on Linux inotify watch exhaustion (ENOSPC) (#893) On the Linux per-directory watch path, hitting fs.inotify.max_user_watches surfaces as ENOSPC — which the degrade logic added for #876 (EMFILE/ENFILE only) did not catch, so it fell through to the silent "skip this directory" branch: a large repo got a partial watch set with no hint why edits in unwatched directories stopped auto-syncing. ENOSPC is non-fatal — raise the limit and partial watching keeps working — so it now warns ONCE, naming the exact knob (fs.inotify.max_user_watches, with the sysctl to set it), instead of degrading. It also stops attempting further doomed watches for the session (every inotify_add_watch would fail too). Installed watches keep firing; `codegraph sync` / git sync hooks cover the remainder. Validated on macOS (forced per-directory path) and real Linux (Docker) — the new test asserts a single warning naming fs.inotify.max_user_watches, no degrade, and a live partial watch. Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
  • 查看 10 次提交的內容比對 »

5 天之前

haiany 已經從鏡像同步了參考 feat/offload-byohaiany/codegraph

5 天之前

haiany 已經從鏡像同步了提交 mainhaiany/codegraph

  • f34f606342 feat(extraction): same-file value-reference edges for impact analysis — 15 languages (#897) Adds same-file value-reference edges (reader symbol → const/var it reads) so impact analysis catches a constant's same-file consumers, closing the 'change this table, break its readers' hole. 15 languages validated S/M/L on public OSS: TS/JS/tsx, Go, Python, Rust, Ruby, C, Java, C#, PHP, Scala, Kotlin, Swift, Dart, Pascal/Delphi (+ Svelte/Vue/Astro inherited). Edges-only — node count identical on/off; default ON, CODEGRAPH_VALUE_REFS=0 opts out.

6 天之前