Skip to content

feat(workspace): add trace, symbol indexing, and watcher fixes for workspace mode#121

Merged
yoanbernabeu merged 17 commits intoyoanbernabeu:mainfrom
jugrajsingh:feature/workspace-trace-watcher-fixes
Feb 13, 2026
Merged

feat(workspace): add trace, symbol indexing, and watcher fixes for workspace mode#121
yoanbernabeu merged 17 commits intoyoanbernabeu:mainfrom
jugrajsingh:feature/workspace-trace-watcher-fixes

Conversation

@jugrajsingh
Copy link
Contributor

Summary

  • Fix watcher event routing: Workspace file events were silently dropped because handleWorkspaceFileEvent compared relative event paths against absolute project paths. Replaced path matching with per-project event tagging via projectFileEvent struct.
  • Add workspace symbol indexing: grepai watch --workspace now extracts symbols and builds per-project call graphs (stored in .grepai/symbols.gob per project, regardless of vector backend).
  • Add workspace trace CLI: grepai trace callers/callees/graph supports --workspace and --project flags for single-project or cross-project call graph analysis.
  • Add workspace trace MCP: All MCP trace tools and grepai_index_status support workspace and project parameters, with auto-injection when --workspace is set on mcp-serve.
  • Extract SymbolStore interface: Generic interface in trace/trace.go for symbol store implementations.
  • Fix GOBSymbolStore.Persist: Create parent directories automatically so workspace projects without .grepai/ don't fail.
  • Fix Windows path separators: Normalize path separators in projectPrefixStore for cross-platform compatibility.

Test plan

  • 33 new unit tests across 4 files (all passing with race detection)
  • make pre-commit passes (fmt, vet, lint, test)
  • gitleaks detect — no leaks
  • Integration tested with real 10-project test workspace (Qdrant + OpenAI)
    • grepai watch --workspace test — all projects indexed with symbols
    • grepai trace callers — single-project and cross-project aggregation
    • grepai trace callees — single-project with cross-file resolution
    • grepai trace graph --depth 3 — 60+ nodes, 100+ edges
    • grepai search --workspace test — vector search unaffected

Cover path prefixing behavior for SaveChunks, DeleteByFile, GetDocument,
SaveDocument, DeleteDocument with both absolute and relative paths.
Also verify projectFileEvent carries embedded FileEvent and Project context.
Add 26 tests covering workspace multi-project functionality:
- trace/store_test.go: 11 GOBSymbolStore tests (save, delete, lookup,
  callers, callees, call graph, persist/reload, stats, replace-on-save)
- cli/trace_test.go: 5 workspace trace CLI tests (error handling,
  closeSymbolStores, --project validation, cross-store aggregation)
- mcp/server_test.go: 10 MCP workspace tests (resolveWorkspace,
  workspace params on trace tools, index status schema,
  handleTraceCallersFromStores/CalleesFromStores aggregation)
Persist now calls MkdirAll before creating the GOB file, ensuring
workspace projects without a .grepai/ directory can write symbols.
Document --workspace/--project flags on trace commands, update MCP
tool parameter tables, and replace stale warning about trace tools
not working in workspace mode.
Replace hardcoded Unix paths with filepath.Join and t.TempDir() so
tests pass on Windows where filepath.Rel cannot resolve Unix-style
absolute paths.
Use filepath.ToSlash after filepath.Rel to ensure vector store paths
always use forward slashes regardless of OS. Extracts toRelSlash
helper to eliminate duplicated path resolution logic.
Use filepath.ToSlash after filepath.Rel to ensure vector store paths
always use forward slashes regardless of OS. Extracts toRelSlash
helper to eliminate duplicated path resolution logic.
…fixes' into feature/workspace-trace-watcher-fixes
@yoanbernabeu
Copy link
Owner

Hey @jugrajsingh 👋

Great work on this PR! The code looks solid overall — nice refactoring of projectPrefixStore with toRelSlash(), good test coverage (33 new tests), and clean workspace trace support.

However, this PR currently has merge conflicts with main (mergeStateStatus: DIRTY). Could you please rebase on the latest main and resolve the conflicts so we can proceed with the merge?

Thanks!

# Conflicts:
#	CHANGELOG.md
#	cli/watch.go
#	trace/store_test.go
- Remove orphaned ready-file block from watchProject (upstream uses onReady callback)
- Update handleWorkspaceFileEvent call signature in initialscan test
- Rewrite watch_test.go to match upstream function signatures
- Rename workspace fixture in tests to "test"
@codecov
Copy link

codecov bot commented Feb 10, 2026

Codecov Report

❌ Patch coverage is 28.02198% with 262 lines in your changes missing coverage. Please review.
✅ Project coverage is 44.77%. Comparing base (a322537) to head (2fff865).
⚠️ Report is 68 commits behind head on main.

Files with missing lines Patch % Lines
mcp/server.go 29.00% 138 Missing and 4 partials ⚠️
cli/trace.go 21.85% 115 Missing and 3 partials ⚠️
cli/watch.go 84.61% 1 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main     #121       +/-   ##
===========================================
+ Coverage   27.16%   44.77%   +17.61%     
===========================================
  Files          32       50       +18     
  Lines        3711     9348     +5637     
===========================================
+ Hits         1008     4186     +3178     
- Misses       2620     4794     +2174     
- Partials       83      368      +285     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Use filepath.ToSlash in test expectations to match the production code's
forward-slash normalization, fixing Windows CI failures.
Also rename workspace fixture in tests to generic "test".
Add tests for outputJSON, displayCallersResult, displayCalleesResult,
displayGraphResult, truncate, isTracedLanguage, stopWorkspaceWatchDaemon,
loadWorkspaceSymbolStores (with filter and error cases), and
runTraceCallees/Graph validation.
@jugrajsingh
Copy link
Contributor Author

Hey @yoanbernabeu, conflicts are resolved and all CI checks are passing (tests green on all platforms including Windows). Is there anything else blocking the merge or are we good to go?

@yoanbernabeu
Copy link
Owner

Hey @jugrajsingh 👋

Thanks for the rebase! Unfortunately, new merges on main have introduced new merge conflicts — the PR is currently in dirty state again and can't be merged.

I've done a thorough code review and here's my feedback:

✅ What looks great

  • Watcher event routing fix — The projectFileEvent approach is the right solution. The old path comparison (relative vs absolute) was silently dropping all events.
  • toRelSlash() refactoring — Great DRY improvement for projectPrefixStore, and the Windows path separator normalization is well done.
  • GOBSymbolStore.Persist creating parent directories — Necessary fix for workspace projects without pre-existing .grepai/.
  • SymbolStore interface extension with IsFileIndexed() — Clean extensibility.
  • 33 new tests — Good coverage of both happy paths and error cases.
  • Documentation fully updated across trace.md, mcp.md, watch-guide.md, workspace.md.

🔧 Suggestions for improvement (non-blocking)

  1. Code duplicationloadWorkspaceSymbolStores and closeSymbolStores are nearly identical in cli/trace.go and mcp/server.go. Consider extracting to a shared location (e.g., a helper in the trace package or a new workspace package). Not blocking but adds maintenance burden.

  2. Double scan in indexWorkspaceProjectscanner.Scan() is called twice: once by the indexer and once for symbol extraction. On large projects this could have a noticeable performance impact. Consider reusing the file list from the indexer.

  3. Silent error handling — Several places use symbols, _ := ss.LookupSymbol(...) without logging. Consider at least a log.Printf on error to ease debugging in production.

🚫 Blocking

  • Merge conflicts — Please rebase on the latest main to resolve the new conflicts.

Once the conflicts are resolved, we're good to merge! 🚀

…ce-watcher-fixes

# Conflicts:
#	cli/watch.go
#	mcp/server.go
#	trace/store.go
@jugrajsingh
Copy link
Contributor Author

Hey @yoanbernabeu, thanks for the detailed review!

Merge conflicts are resolved again — rebased on latest main and all CI checks are green (including Windows).

Regarding your suggestions:

  1. Code duplication (loadWorkspaceSymbolStores/closeSymbolStores) — Agreed, will extract to a shared helper in a follow-up PR.
  2. Double scan in indexWorkspaceProject — Good catch, will look into reusing the indexer's file list.
  3. Silent error handling — Will add logging for suppressed errors.

Happy to address these in a follow-up to keep this PR focused. Ready to merge whenever you are!

@yoanbernabeu yoanbernabeu merged commit fdc66c9 into yoanbernabeu:main Feb 13, 2026
10 checks passed
@jugrajsingh jugrajsingh deleted the feature/workspace-trace-watcher-fixes branch February 13, 2026 12:14
jugrajsingh added a commit to jugrajsingh/grepai that referenced this pull request Feb 24, 2026
Extract shared LoadWorkspaceSymbolStores and CloseSymbolStores
into trace/workspace.go, eliminating ~50 lines of duplication
between cli/trace.go and mcp/server.go.

Add ScannedFiles field to IndexStats so runInitialScan reuses
the file list from IndexAllWithBatchProgress instead of calling
scanner.ScanMetadata() a second time.

Replace ~21 silent error discards (_, _ :=) on symbol store
and config operations with log.Printf warnings in both
cli/trace.go and mcp/server.go.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants