Repository navigation
Description
Summary
Following the v0.7.0 fix in #308 (tsconfig.json paths), cross-package IMPORTS still produce zero edges for monorepos that use package.json workspaces + Lerna/Yarn workspaces (the most common JS monorepo pattern) instead of tsconfig path aliases.
The README claims this is supported via generic @myorg/pkg manifest resolution in pass_pkgmap.c:
Generic package / module resolution — bare specifiers like
@myorg/pkg,github.com/foo/bar,use my_crate::fooresolved via manifest scanning (package.json,go.mod,Cargo.toml, ...)
However, in my testing on v0.7.0 (macOS arm64), pass_pkgmap.c either does not run or silently produces zero entries — no pkgmap.scan_repo / pkgmap.scan / pkgmap.build log lines appear during indexing, and zero cross-package IMPORTS edges are produced.
Environment
- codebase-memory-mcp: 0.7.0 (verified
--version) - OS: macOS 24.6.0 (Darwin arm64)
- Install method: official
install.sh(ui variant)
Minimal reproduction
mkdir -p cbm-test/pkg-a/src cbm-test/pkg-b/src
cat > cbm-test/pkg-a/package.json <<EOF
{"name": "@test/pkg-a", "main": "src/index.js"}
EOF
cat > cbm-test/pkg-b/package.json <<EOF
{"name": "@test/pkg-b", "main": "src/index.js"}
EOF
cat > cbm-test/pkg-a/src/index.js <<EOF
import { foo } from '@test/pkg-b';
export const a = () => foo();
EOF
cat > cbm-test/pkg-b/src/index.js <<EOF
export const foo = () => 42;
EOF
codebase-memory-mcp cli index_repository '{"repo_path":"/tmp/cbm-test"}' 2>&1 | grep -iE "pkgmap"
# → no output (expected: pkgmap.scan_repo / pkgmap.build log lines)
codebase-memory-mcp cli query_graph '{"project":"tmp-cbm-test","query":"MATCH (a)-[r:IMPORTS]->(b) RETURN a.file_path, b.file_path"}'
# → 0 rowsExpected: an IMPORTS edge from pkg-a/src/index.js to pkg-b/src/index.js because the pkgmap should resolve @test/pkg-b via the package.json "name" field.
Actual: 0 IMPORTS edges, no pkgmap log lines.
Real-world impact
I'm indexing a 13-repo monorepo workspace (~140K nodes, ~214K edges, 13K files). All repos are Lerna+Yarn workspaces publishing internal packages under @pandora/ / @commerce-exp/. Cross-repo imports use the published package name. Expected behavior: graph treats them as a single fleet with normal IMPORTS edges. Actual: every cross-repo import is dropped.
Workaround attempted: synthesize a root tsconfig.json at the workspace level with paths mapping every internal @pandora/foo → <repo>/packages/foo/src/index.ts. This did trigger path_alias.c (saw path_alias.files.cap_hit kept=256_of_more warn) but still produced zero cross-repo edges because:
CBM_PATH_ALIAS_MAX_ENTRIES = 256per single tsconfig (we have 328+ packages → 70+ silently dropped)CBM_PATH_ALIAS_MAX_FILES = 256total tsconfigs per repo walk (we have 352 → root tsconfig may not be among the 256 selected)cbm_path_alias_find_for_filepicks the nearest ancestor scope, so every source file inside an inner package picks up its own localtsconfig.jsonrather than the workspace-root one we wrote, never seeing our cross-repo paths
Suggested improvements
- Diagnose
pass_pkgmap.csilent failure on JS/TS workspaces (no log emission at all suggests it isn't being invoked or returns NULL before logging). The walker logic inpkgmap_walk_dirlooks correct from the source. Add aninfolog even when 0 entries are produced. - Honor
package.jsonworkspacesarrays so a root manifest with"workspaces": ["packages/*"](or globs across child repos) gives a scope to bare-specifier resolution that spans them. - Aggregate tsconfig path aliases from ancestors rather than nearest-only — or, when a file matches no nearer alias, fall back to ancestors instead of stopping at the first tsconfig found.
- Raise (or make configurable) the
CBM_PATH_ALIAS_MAX_ENTRIES = 256andCBM_PATH_ALIAS_MAX_FILES = 256caps. Real monorepos easily exceed both. - Document the limitation in the README under "Cross-repo intelligence" — specifically that
@myorg/pkgresolution currently does not bridge acrosspackage.json-workspaces sibling repos, even though the README example "@myorg/pkg" implies it does.
Happy to test fixes against a public 13-repo repro if helpful.
Activity
Add reproduction for package.json workspaces cross-package IMPORTS (#408
Resolve package.json workspaces cross-package IMPORTS on Windows (#408)
DeusData commentedon Jun 7, 2026
Update: I dug into this and found + fixed one real gap — the repo-wide manifest walk (
cbm_pkgmap_scan_repo) was a no-op on Windows, sopackage.jsonworkspace names were never resolved there (cross-package IMPORTS = 0). It's now cross-platform and depth-bounded (cannot hang on directory junctions) onmain(586729b), with a regression test.That said, I want to be careful: on macOS/Linux I can't reproduce zero cross-package edges with a standard workspaces layout — a fixture where
packages/bimports a sibling by itsname(@org/a) resolves to a cross-packageIMPORTSedge for me (now covered bycontract_edge_workspaces_imports_issue408). Since your report was on macOS, your specific layout may be hitting a different path.Could you share a minimal repro? Specifically:
package.jsonand a couple of packagepackage.jsonfiles (do the packages set"name"?"main"or"exports"?),pkgmap.scan_repo/pkgmap.buildlines appear in the logs (now visible withCBM_LOG_LEVEL=debug).Leaving this open pending that — happy to chase the macOS case once I can reproduce it.
GonEbal commentedon Jun 10, 2026
Thanks for the quick turnaround on the Windows fix — and for keeping this open while we narrow down the macOS path.
Below is a minimal canonical-workspaces repro on macOS (Darwin arm64,
codebase-memory-mcp 0.7.0from the publishedinstall.sh) that produces 0 IMPORTS edges and 0pkgmap.*log lines even withCBM_LOG_LEVEL=debug. This is much smaller than my original case and uses the exact layout your newcontract_edge_workspaces_imports_issue408fixture should be modeled on, so it should be easy to compare against.Files
/tmp/cbm-issue408-repro/package.json:{ "name": "monorepo-root", "private": true, "workspaces": ["packages/*"] }/tmp/cbm-issue408-repro/packages/pkg-a/package.json:{ "name": "@test/pkg-a", "version": "1.0.0", "main": "src/index.js" }/tmp/cbm-issue408-repro/packages/pkg-b/package.json:{ "name": "@test/pkg-b", "version": "1.0.0", "main": "src/index.js" }packages/pkg-a/src/index.js:packages/pkg-b/src/index.js:Command + result
Full pipeline log lines that do appear (no
pkgmappass anywhere in the sequence):And the graph confirms:
So on macOS the
pkgmappass appears not to be scheduled at all (it’s not in thepass.startsequence), which would explain both theimports=0counter inpass=definitionsand the absence of anypkgmap.*log lines. That lines up with what I noticed earlier when readingpass_pkgmap.c: the walker logic looks right, it just doesn’t seem to be invoked on this platform.Answers to your questions
"name"?"main"/"exports"? Yes tonameandmain; noexportsin the repro. In my real-world workspace the inner packages additionally setmoduleandtypes, but noexports. Happy to test anexports-only variant if useful.packages/pkg-a/src/index.jsabove (import { foo } from '@test/pkg-b';).pkgmap.scan_repo/pkgmap.buildin logs? None, even atCBM_LOG_LEVEL=debug.Env
codebase-memory-mcp 0.7.0(release binary; commit586729bonmainnot yet shipped)install.sh(ui variant) →~/.local/bin/codebase-memory-mcpHappy to test a pre-release with the
586729bfix on macOS if you can publish one, or build frommainagainst a tag if you’d prefer. Also glad to run additional repro variants (exports-only, nested workspaces, scoped vs unscoped names,.jsvs.ts) — just say the word.DeusData commentedon Jun 12, 2026
Thanks for the minimal canonical-workspaces repro — exactly what's needed. Will investigate why the macOS path produces zero pkgmap log lines even at debug level.
test(repro): cross-file + trace reproductions for #408, #56, #480
test(repro): fix harness include + #408 comment; add #571, #523, #546
DeusData commentedon Jun 26, 2026
This is fixed.
cbm_pkgmap_build_from_reponow also walks the filesystem forpackage.jsonmanifests that the main discoverer filters out, then resolves a workspace specifier (@org/pkg) to the sibling package's entry-module QN — so a bare-specifier import likeimport { fromA } from '@org/a'between workspace packages produces the cross-package IMPORTS edge.Guarded with a fixture whose only possible IMPORTS edge is the cross-package one (no relative imports, no
dependenciesfield), so the guard genuinely exercises workspace resolution.Closing as fixed — reopen if a specific monorepo layout still yields zero cross-package edges. Thanks!