Open
Conversation
…e changes made: ## Summary of Changes ### New Files Created 1. **`src/commands/whoami.ts`** - Shows the current authenticated user and active organization 2. **`src/commands/list-stores.ts`** - Lists all stores in the current organization ### Modified Files 1. **`src/lib/organizations.ts`** - Added organization caching functionality: - `cacheOrganization()` - Caches org info to `~/.mgrep/organization.json` - `getCachedOrganization()` - Retrieves cached org info (no network required) - `clearCachedOrganization()` - Clears the cache - `getOrganizationById()` - Gets org info by ID - `getCurrentOrganizationInfo()` - Gets full org info with fallback to cache - Updated `selectOrganization()` to cache the selected org 2. **`src/lib/store.ts`** - Added store listing capability: - New `StoreSummary` interface - New `list()` method on `Store` interface - Implemented in both `MixedbreadStore` and `TestStore` 3. **`src/commands/logout.ts`** - Clears cached organization on logout 4. **`src/commands/watch.ts`** - Displays organization info when starting watch 5. **`src/index.ts`** - Registered new commands (`whoami`, `listStores`) ## New CLI Commands | Command | Description | |---------|-------------| | `mgrep whoami` | Shows current user and active organization | | `mgrep list-stores` (or `mgrep ls`) | Lists all stores in the current organization | | `mgrep switch-org` | Switch between organizations (already existed) | ## How Multi-User Support Works 1. **Organization Context**: The Mixedbread API scopes stores by organization through the JWT token. When a user logs in, they select an organization, and all subsequent API calls are scoped to that organization. 2. **Local Caching**: Organization info is cached locally at `~/.mgrep/organization.json` for display purposes without requiring network calls. 3. **Store Isolation**: Each organization has its own set of stores. Users in different organizations can have stores with the same name without conflicts. 4. **Visibility**: The `watch` command now displays the current organization and store name to help users understand which context they're working in.
1. **New `--shared` / `-S` flag** for `watch` and `search` commands - Enables relative path storage for multi-user collaboration 2. **Config file support** for `shared: true` in `.mgreprc.yaml` 3. **Environment variable** `MGREP_SHARED=true` support 4. **Path utility functions** in `src/lib/utils.ts`: - `toRelativePath()` - converts absolute to relative paths - `toAbsolutePath()` - converts relative to absolute paths - `getStoragePath()` - chooses the right path based on shared mode 5. **Updated `uploadFile()`** to accept `projectRoot` parameter and use relative paths in shared mode 6. **Updated `initialSync()`** to: - List store files without path prefix in shared mode - Compare files using storage paths (relative or absolute) - Delete files using storage paths 7. **Updated search command** to use relative paths for filtering in shared mode 8. **Updated `formatChunk()`** to properly display both absolute and relative paths 9. **README documentation** with: - Multi-User / Shared Mode section - Updated command tables - Updated config examples - Environment variable documentation **Without shared mode** (default): - Files stored as `/Users/alice/projects/myapp/src/auth.ts` - Only works for single user **With shared mode** (`--shared` or `shared: true`): - Files stored as `src/auth.ts` - Any team member can sync/search regardless of their local path
…e in README, but kept the actual command since it existed before), and `list-stores` commands: 1. **Deleted files:** - `src/commands/whoami.ts` - `src/commands/list-stores.ts` 2. **Reverted files to original:** - `src/lib/organizations.ts` - removed caching functions - `src/lib/store.ts` - removed `list()` method - `src/commands/logout.ts` - removed organization cache clearing 3. **Updated files:** - `src/index.ts` - removed imports and command registrations for `whoami` and `listStores` - `src/commands/watch.ts` - removed organization display code - `README.md` - removed `whoami` and `list-stores` from commands table and organization support section The shared mode implementation for multi-user support remains intact.
## Changes Made ### 1. Removed unused function from `src/lib/utils.ts` - Removed `toAbsolutePath()` function which was not used anywhere ### 2. Added tests for shared mode in `test/test.bats` Added 6 new tests: - **"Shared mode flag is recognized by watch"** - Tests `--shared` flag with watch command - **"Shared mode flag is recognized by search"** - Tests `--shared` flag with search command - **"Shared mode via config file"** - Tests `shared: true` in `.mgreprc.yaml` - **"Shared mode via environment variable"** - Tests `MGREP_SHARED=true` env var - **"Shared mode stores files with relative paths"** - Verifies paths don't contain absolute directory - **"Shared mode search with subdirectory"** - Tests subdirectory path filtering in shared mode
## Bug Fixes
### 1. Double slash in file paths (Medium Severity)
**Problem**: When `storedPath` was `/Users/alice/project/src/file.ts` and `pwd` was `/Users/alice/project`, the code produced `.//src/file.ts` because:
- `storedPath.replace(pwd, "")` → `/src/file.ts` (leading slash remains)
- `./${displayPath}` → `.//src/file.ts`
**Fix**: Added `.replace(/^\//, "")` to strip the leading slash after removing the pwd prefix.
### 2. Sync path root inconsistent with filter path in shared mode (Medium Severity)
**Problem**: When running `mgrep --shared --sync "query" sub`:
- Files were synced from `sub/` directory, stored as `file.ts` (relative to `sub/`)
- But filter used `toRelativePath(search_path, root)` = `sub`
- Filter `path starts_with "sub"` wouldn't match `file.ts`
**Fix**: In shared mode, sync always uses the project root (`root`) instead of `search_path`. This ensures files are stored as `sub/file.ts` (relative to project root), so the filter `sub` correctly matches.
1. **Windows absolute path detection** - Changed `storedPath.startsWith("/")` to `isAbsolute(storedPath)` which properly handles both Unix (`/path`) and Windows (`C:\path`) absolute paths. Also fixed `exec_path?.startsWith("/")` to use `isAbsolute()`.
2. **Home directory safety check bypass** - Moved the `syncRoot` calculation before the home directory check so that in shared mode (where `syncRoot = root`), the check validates the actual directory being synced, not just the search path argument.
Summary of changes in `src/commands/search.ts`:
- Line 1: Added `isAbsolute` import
- Lines 100-112: Changed path detection in `formatChunk` to use `isAbsolute()` and updated regex to handle both Unix and Windows path separators (`/^[\\/]/`)
- Lines 300-306: Moved `syncRoot` calculation before the home directory check
- Lines 307-316: Now validates `syncRoot` instead of `search_path` for the home directory safety check
**New command: `mgrep config`** with four subcommands: - `mgrep config set <key> <value>` — Set a global config value - `mgrep config get <key>` — Get a global config value (shows `(default)` if unset) - `mgrep config list` — List all config values - `mgrep config reset [key]` — Reset one key or all to defaults **Supported keys:** `maxFileSize`, `maxFileCount`, `shared` **Files changed:** - `src/commands/config.ts` (new) — The config command with type-safe value parsing and validation - `src/lib/config.ts` — Exported `DEFAULT_CONFIG`, `GLOBAL_CONFIG_DIR`, `getGlobalConfigPaths`, `CONFIG_KEYS`, and added `readGlobalConfig`, `writeGlobalConfig`, `getGlobalConfigFilePath` helpers - `src/index.ts` — Registered the config command - `test/test.bats` — Added 7 tests covering set/get, list, reset, and error cases
- Fix config reset single key bug where writeGlobalConfig re-merged the deleted key from file. Added saveGlobalConfig for direct writes. - Add fs.existsSync check before unlinkSync on reset single key - Remove unused Store.list() method and StoreSummary interface Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
769d536 to
a39945d
Compare
…nById Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- **Build**: Clean - **Lint**: No issues (31 files checked) - **Tests**: 51/51 passing The shared mode simplification is complete. The `SearchFilter` type cast was needed because the SDK types don't include the `"regex"` operator, but the API supports it. The cast at the call sites (`filters as SearchFilter | undefined`) is the cleanest approach to handle this SDK gap.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| } catch { | ||
| return null; | ||
| } | ||
| } |
There was a problem hiding this comment.
Exported function getCachedOrganization is never used
Low Severity
The getCachedOrganization function is exported but never imported or called anywhere in the codebase. While cacheOrganization (write) and clearCachedOrganization (delete) are both used, this "read" function is dead code that adds unnecessary maintenance burden.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Mixedbread supports organizations, a way for users to share the same stores. Let's support this in mgrep as well. Multiple users should be able to use the same store.
Note
Medium Risk
Medium risk because it changes core
search/watchscoping behavior via new regex-based path filters and new config precedence, which could affect result sets and sync boundaries across users.Overview
Adds multi-user shared mode (
--shared/MGREP_SHARED/ configshared: true) that changessearchfiltering fromstarts_withto regex suffix matching and adjusts sync scope so teams with different absolute paths can query the same store.Introduces a new
mgrep configcommand (set/get/list/reset) backed by global config file helpers inlib/config, and extends config/env/CLI precedence to includeshared.Improves org UX by caching the selected organization locally (and clearing it on logout), updates output path formatting for shared results, and expands README + bats tests to cover the new behaviors.
Written by Cursor Bugbot for commit c22e869. This will update automatically on new commits. Configure here.