ragtime-cli 0.2.16__tar.gz → 0.2.18__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. {ragtime_cli-0.2.16/ragtime_cli.egg-info → ragtime_cli-0.2.18}/PKG-INFO +21 -3
  2. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/README.md +20 -2
  3. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/pyproject.toml +1 -1
  4. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18/ragtime_cli.egg-info}/PKG-INFO +21 -3
  5. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/cli.py +161 -7
  6. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/mcp_server.py +26 -3
  7. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/LICENSE +0 -0
  8. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/ragtime_cli.egg-info/SOURCES.txt +0 -0
  9. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/ragtime_cli.egg-info/dependency_links.txt +0 -0
  10. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/ragtime_cli.egg-info/entry_points.txt +0 -0
  11. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/ragtime_cli.egg-info/requires.txt +0 -0
  12. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/ragtime_cli.egg-info/top_level.txt +0 -0
  13. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/setup.cfg +0 -0
  14. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/__init__.py +0 -0
  15. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/commands/audit.md +0 -0
  16. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/commands/create-pr.md +0 -0
  17. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/commands/generate-docs.md +0 -0
  18. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/commands/handoff.md +0 -0
  19. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/commands/import-docs.md +0 -0
  20. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/commands/pr-graduate.md +0 -0
  21. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/commands/recall.md +0 -0
  22. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/commands/remember.md +0 -0
  23. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/commands/save.md +0 -0
  24. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/commands/start.md +0 -0
  25. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/config.py +0 -0
  26. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/db.py +0 -0
  27. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/feedback.py +0 -0
  28. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/indexers/__init__.py +0 -0
  29. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/indexers/code.py +0 -0
  30. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/indexers/docs.py +0 -0
  31. {ragtime_cli-0.2.16 → ragtime_cli-0.2.18}/src/memory.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ragtime-cli
3
- Version: 0.2.16
3
+ Version: 0.2.18
4
4
  Summary: Local-first memory and RAG system for Claude Code - semantic search over code, docs, and team knowledge
5
5
  Author-email: Bret Martineau <bretwardjames@gmail.com>
6
6
  License-Expression: MIT
@@ -54,9 +54,15 @@ pip install ragtime-cli
54
54
  ## Quick Start
55
55
 
56
56
  ```bash
57
- # Initialize in your project
57
+ # Initialize in your project (prompts to set up MCP server)
58
58
  ragtime init
59
59
 
60
+ # Or skip prompts with -y
61
+ ragtime -y init
62
+
63
+ # Or just enable MCP globally (works in any project)
64
+ ragtime init -G
65
+
60
66
  # Index your docs
61
67
  ragtime index
62
68
 
@@ -416,7 +422,17 @@ After `ragtime install --workspace`:
416
422
 
417
423
  ## MCP Server
418
424
 
419
- Add to your Claude config (`.mcp.json`):
425
+ The MCP server is automatically configured during `ragtime init`. You can also set it up manually:
426
+
427
+ ```bash
428
+ # Project-level: creates .mcp.json in current project
429
+ ragtime init
430
+
431
+ # Global: adds to ~/.claude/settings.json (works in any project)
432
+ ragtime init -G
433
+ ```
434
+
435
+ Or add manually to `.mcp.json`:
420
436
 
421
437
  ```json
422
438
  {
@@ -429,6 +445,8 @@ Add to your Claude config (`.mcp.json`):
429
445
  }
430
446
  ```
431
447
 
448
+ The MCP server automatically finds the project root (`.ragtime` directory) even when Claude is started from a subdirectory.
449
+
432
450
  Available tools:
433
451
  - `remember` - Store a memory
434
452
  - `search` - Semantic search (supports tiered mode and auto-extraction)
@@ -24,9 +24,15 @@ pip install ragtime-cli
24
24
  ## Quick Start
25
25
 
26
26
  ```bash
27
- # Initialize in your project
27
+ # Initialize in your project (prompts to set up MCP server)
28
28
  ragtime init
29
29
 
30
+ # Or skip prompts with -y
31
+ ragtime -y init
32
+
33
+ # Or just enable MCP globally (works in any project)
34
+ ragtime init -G
35
+
30
36
  # Index your docs
31
37
  ragtime index
32
38
 
@@ -386,7 +392,17 @@ After `ragtime install --workspace`:
386
392
 
387
393
  ## MCP Server
388
394
 
389
- Add to your Claude config (`.mcp.json`):
395
+ The MCP server is automatically configured during `ragtime init`. You can also set it up manually:
396
+
397
+ ```bash
398
+ # Project-level: creates .mcp.json in current project
399
+ ragtime init
400
+
401
+ # Global: adds to ~/.claude/settings.json (works in any project)
402
+ ragtime init -G
403
+ ```
404
+
405
+ Or add manually to `.mcp.json`:
390
406
 
391
407
  ```json
392
408
  {
@@ -399,6 +415,8 @@ Add to your Claude config (`.mcp.json`):
399
415
  }
400
416
  ```
401
417
 
418
+ The MCP server automatically finds the project root (`.ragtime` directory) even when Claude is started from a subdirectory.
419
+
402
420
  Available tools:
403
421
  - `remember` - Store a memory
404
422
  - `search` - Semantic search (supports tiered mode and auto-extraction)
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ragtime-cli"
3
- version = "0.2.16"
3
+ version = "0.2.18"
4
4
  description = "Local-first memory and RAG system for Claude Code - semantic search over code, docs, and team knowledge"
5
5
  readme = "README.md"
6
6
  license = "MIT"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ragtime-cli
3
- Version: 0.2.16
3
+ Version: 0.2.18
4
4
  Summary: Local-first memory and RAG system for Claude Code - semantic search over code, docs, and team knowledge
5
5
  Author-email: Bret Martineau <bretwardjames@gmail.com>
6
6
  License-Expression: MIT
@@ -54,9 +54,15 @@ pip install ragtime-cli
54
54
  ## Quick Start
55
55
 
56
56
  ```bash
57
- # Initialize in your project
57
+ # Initialize in your project (prompts to set up MCP server)
58
58
  ragtime init
59
59
 
60
+ # Or skip prompts with -y
61
+ ragtime -y init
62
+
63
+ # Or just enable MCP globally (works in any project)
64
+ ragtime init -G
65
+
60
66
  # Index your docs
61
67
  ragtime index
62
68
 
@@ -416,7 +422,17 @@ After `ragtime install --workspace`:
416
422
 
417
423
  ## MCP Server
418
424
 
419
- Add to your Claude config (`.mcp.json`):
425
+ The MCP server is automatically configured during `ragtime init`. You can also set it up manually:
426
+
427
+ ```bash
428
+ # Project-level: creates .mcp.json in current project
429
+ ragtime init
430
+
431
+ # Global: adds to ~/.claude/settings.json (works in any project)
432
+ ragtime init -G
433
+ ```
434
+
435
+ Or add manually to `.mcp.json`:
420
436
 
421
437
  ```json
422
438
  {
@@ -429,6 +445,8 @@ Add to your Claude config (`.mcp.json`):
429
445
  }
430
446
  ```
431
447
 
448
+ The MCP server automatically finds the project root (`.ragtime` directory) even when Claude is started from a subdirectory.
449
+
432
450
  Available tools:
433
451
  - `remember` - Store a memory
434
452
  - `search` - Semantic search (supports tiered mode and auto-extraction)
@@ -3,6 +3,7 @@ Ragtime CLI - semantic search and memory storage.
3
3
  """
4
4
 
5
5
  from pathlib import Path
6
+ import json
6
7
  import subprocess
7
8
  import click
8
9
  import os
@@ -168,17 +169,166 @@ def get_remote_branches_with_ragtime(path: Path) -> list[str]:
168
169
  return []
169
170
 
170
171
 
172
+ def setup_mcp_server(project_path: Path, force: bool = False) -> bool:
173
+ """Offer to configure MCP server for Claude Code integration.
174
+
175
+ Args:
176
+ project_path: The project directory
177
+ force: If True, add MCP server without prompting
178
+
179
+ Returns True if MCP was configured, False otherwise.
180
+ """
181
+ mcp_config_path = project_path / ".mcp.json"
182
+
183
+ ragtime_config = {
184
+ "command": "ragtime-mcp",
185
+ "args": ["--path", "."]
186
+ }
187
+
188
+ if mcp_config_path.exists():
189
+ # Read file once
190
+ try:
191
+ existing = json.loads(mcp_config_path.read_text())
192
+ except (IOError, OSError) as e:
193
+ click.echo(f"\n✗ Could not read .mcp.json: {e}", err=True)
194
+ return False
195
+ except json.JSONDecodeError as e:
196
+ click.echo(f"\n! Warning: .mcp.json contains invalid JSON: {e}", err=True)
197
+ if not (force or click.confirm("? Overwrite with new config?", default=False)):
198
+ return False
199
+ existing = {}
200
+
201
+ # Check if ragtime is already configured
202
+ if "mcpServers" in existing and "ragtime" in existing.get("mcpServers", {}):
203
+ click.echo("\n✓ MCP server already configured in .mcp.json")
204
+ return True
205
+
206
+ # Add ragtime to existing config
207
+ if force or click.confirm("\n? Add ragtime MCP server to existing .mcp.json?", default=True):
208
+ try:
209
+ if "mcpServers" not in existing:
210
+ existing["mcpServers"] = {}
211
+ existing["mcpServers"]["ragtime"] = ragtime_config
212
+ mcp_config_path.write_text(json.dumps(existing, indent=2) + "\n")
213
+ click.echo("\n✓ Added ragtime to .mcp.json")
214
+ return True
215
+ except IOError as e:
216
+ click.echo(f"\n✗ Failed to update .mcp.json: {e}", err=True)
217
+ return False
218
+ else:
219
+ # Create new config
220
+ if force or click.confirm("\n? Create .mcp.json to enable Claude Code MCP integration?", default=True):
221
+ mcp_config = {
222
+ "mcpServers": {
223
+ "ragtime": ragtime_config
224
+ }
225
+ }
226
+ try:
227
+ mcp_config_path.write_text(json.dumps(mcp_config, indent=2) + "\n")
228
+ click.echo("\n✓ Created .mcp.json with ragtime server")
229
+ return True
230
+ except IOError as e:
231
+ click.echo(f"\n✗ Failed to create .mcp.json: {e}", err=True)
232
+ return False
233
+
234
+ return False
235
+
236
+
237
+ def setup_mcp_global(force: bool = False) -> bool:
238
+ """Add ragtime MCP server to global Claude settings.
239
+
240
+ Args:
241
+ force: If True, add without prompting
242
+
243
+ Returns True if configured, False otherwise.
244
+ """
245
+ claude_dir = Path.home() / ".claude"
246
+ settings_path = claude_dir / "settings.json"
247
+
248
+ ragtime_config = {
249
+ "command": "ragtime-mcp",
250
+ "args": ["--path", "."]
251
+ }
252
+
253
+ # Ensure ~/.claude exists
254
+ try:
255
+ claude_dir.mkdir(parents=True, exist_ok=True)
256
+ except OSError as e:
257
+ click.echo(f"✗ Failed to create {claude_dir}: {e}", err=True)
258
+ return False
259
+
260
+ if settings_path.exists():
261
+ # Read file once
262
+ try:
263
+ existing = json.loads(settings_path.read_text())
264
+ except (IOError, OSError) as e:
265
+ click.echo(f"✗ Could not read ~/.claude/settings.json: {e}", err=True)
266
+ return False
267
+ except json.JSONDecodeError as e:
268
+ click.echo(f"! Warning: ~/.claude/settings.json contains invalid JSON: {e}", err=True)
269
+ if not (force or click.confirm("? Overwrite with new config?", default=False)):
270
+ return False
271
+ existing = {}
272
+
273
+ # Check if ragtime is already configured
274
+ if "mcpServers" in existing and "ragtime" in existing.get("mcpServers", {}):
275
+ click.echo("✓ MCP server already configured in ~/.claude/settings.json")
276
+ return True
277
+
278
+ # Add ragtime to existing config
279
+ if force or click.confirm("? Add ragtime MCP server to ~/.claude/settings.json?", default=True):
280
+ try:
281
+ if "mcpServers" not in existing:
282
+ existing["mcpServers"] = {}
283
+ existing["mcpServers"]["ragtime"] = ragtime_config
284
+ settings_path.write_text(json.dumps(existing, indent=2) + "\n")
285
+ click.echo("✓ Added ragtime to ~/.claude/settings.json")
286
+ return True
287
+ except IOError as e:
288
+ click.echo(f"✗ Failed to update settings: {e}", err=True)
289
+ return False
290
+ else:
291
+ # Create new settings file
292
+ if force or click.confirm("? Create ~/.claude/settings.json with ragtime MCP server?", default=True):
293
+ settings = {
294
+ "mcpServers": {
295
+ "ragtime": ragtime_config
296
+ }
297
+ }
298
+ try:
299
+ settings_path.write_text(json.dumps(settings, indent=2) + "\n")
300
+ click.echo("✓ Created ~/.claude/settings.json with ragtime server")
301
+ return True
302
+ except IOError as e:
303
+ click.echo(f"✗ Failed to create settings: {e}", err=True)
304
+ return False
305
+
306
+ return False
307
+
308
+
171
309
  @click.group()
172
- @click.version_option(version="0.2.9")
173
- def main():
310
+ @click.version_option(version="0.2.18")
311
+ @click.option("-y", "--force-defaults", is_flag=True, help="Accept all defaults without prompting")
312
+ @click.pass_context
313
+ def main(ctx, force_defaults: bool):
174
314
  """Ragtime - semantic search over code and documentation."""
175
- pass
315
+ ctx.ensure_object(dict)
316
+ ctx.obj["force_defaults"] = force_defaults
176
317
 
177
318
 
178
319
  @main.command()
179
- @click.argument("path", type=click.Path(exists=True, path_type=Path), default=".")
180
- def init(path: Path):
181
- """Initialize ragtime config for a project."""
320
+ @click.argument("path", type=click.Path(exists=True, path_type=Path), default=".", required=False)
321
+ @click.option("-G", "--global", "global_install", is_flag=True, help="Add MCP server to ~/.claude/settings.json")
322
+ @click.pass_context
323
+ def init(ctx, path: Path, global_install: bool):
324
+ """Initialize ragtime config for a project, or globally with -G."""
325
+ force = (ctx.obj or {}).get("force_defaults", False)
326
+
327
+ # Global install: just add MCP to ~/.claude/settings.json
328
+ if global_install:
329
+ setup_mcp_global(force=force)
330
+ return
331
+
182
332
  path = path.resolve()
183
333
  config = init_config(path)
184
334
  click.echo(f"Created .ragtime/config.yaml with defaults:")
@@ -257,6 +407,9 @@ Add your team's conventions above. Each rule should be:
257
407
  click.echo(f"\n• ghp-cli not found")
258
408
  click.echo(f" Install for enhanced workflow: npm install -g @bretwardjames/ghp-cli")
259
409
 
410
+ # Offer MCP server setup for Claude Code integration
411
+ setup_mcp_server(path, force=(ctx.obj or {}).get("force_defaults", False))
412
+
260
413
 
261
414
  # Batch size for ChromaDB upserts (embedding computation happens here)
262
415
  INDEX_BATCH_SIZE = 100
@@ -281,7 +434,8 @@ def _upsert_entries(db, entries, entry_type: str = "docs", label: str = " Embed
281
434
  if entry_type == "code":
282
435
  ids = [f"{e.file_path}:{e.line_number}:{e.symbol_name}" for e in batch]
283
436
  else:
284
- ids = [e.file_path for e in batch]
437
+ # Include chunk_index for hierarchical doc chunks
438
+ ids = [f"{e.file_path}:{e.chunk_index}" for e in batch]
285
439
 
286
440
  documents = [e.content for e in batch]
287
441
  metadatas = [e.to_metadata() for e in batch]
@@ -16,6 +16,28 @@ from .memory import Memory, MemoryStore
16
16
  from .feedback import FeedbackStore, SearchFeedback
17
17
 
18
18
 
19
+ def find_project_root(start_path: Path) -> Path:
20
+ """Walk up directory tree to find project root containing .ragtime.
21
+
22
+ Similar to how git finds .git directory from any subdirectory.
23
+
24
+ Args:
25
+ start_path: Starting directory to search from
26
+
27
+ Returns:
28
+ Project root path, or start_path if .ragtime not found
29
+ """
30
+ current = start_path.resolve()
31
+
32
+ while current != current.parent: # Stop at filesystem root
33
+ if (current / ".ragtime").is_dir():
34
+ return current
35
+ current = current.parent
36
+
37
+ # Fallback to start path if .ragtime not found
38
+ return start_path.resolve()
39
+
40
+
19
41
  class RagtimeMCPServer:
20
42
  """MCP Server that exposes ragtime operations as tools."""
21
43
 
@@ -24,9 +46,10 @@ class RagtimeMCPServer:
24
46
  Initialize the MCP server.
25
47
 
26
48
  Args:
27
- project_path: Root of the project (defaults to cwd)
49
+ project_path: Root of the project (defaults to cwd, walks up to find .ragtime)
28
50
  """
29
- self.project_path = project_path or Path.cwd()
51
+ start_path = project_path or Path.cwd()
52
+ self.project_path = find_project_root(start_path)
30
53
  self._db = None
31
54
  self._store = None
32
55
  self._feedback = None
@@ -612,7 +635,7 @@ class RagtimeMCPServer:
612
635
  "protocolVersion": "2024-11-05",
613
636
  "serverInfo": {
614
637
  "name": "ragtime",
615
- "version": "0.2.16",
638
+ "version": "0.2.18",
616
639
  },
617
640
  "capabilities": {
618
641
  "tools": {},
File without changes
File without changes
File without changes
File without changes
File without changes