sourcefire 0.3.1__tar.gz → 0.3.4__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 (43) hide show
  1. {sourcefire-0.3.1/sourcefire.egg-info → sourcefire-0.3.4}/PKG-INFO +1 -1
  2. {sourcefire-0.3.1 → sourcefire-0.3.4}/pyproject.toml +1 -1
  3. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/cli.py +40 -25
  4. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/global_config.py +3 -3
  5. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/watcher.py +22 -0
  6. {sourcefire-0.3.1 → sourcefire-0.3.4/sourcefire.egg-info}/PKG-INFO +1 -1
  7. {sourcefire-0.3.1 → sourcefire-0.3.4}/LICENSE +0 -0
  8. {sourcefire-0.3.1 → sourcefire-0.3.4}/MANIFEST.in +0 -0
  9. {sourcefire-0.3.1 → sourcefire-0.3.4}/README.md +0 -0
  10. {sourcefire-0.3.1 → sourcefire-0.3.4}/setup.cfg +0 -0
  11. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/__init__.py +0 -0
  12. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/api/__init__.py +0 -0
  13. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/api/models.py +0 -0
  14. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/api/routes.py +0 -0
  15. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/chain/__init__.py +0 -0
  16. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/chain/prompts.py +0 -0
  17. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/chain/rag_chain.py +0 -0
  18. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/config.py +0 -0
  19. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/db.py +0 -0
  20. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/indexer/__init__.py +0 -0
  21. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/indexer/embeddings.py +0 -0
  22. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/indexer/language_profiles.py +0 -0
  23. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/indexer/metadata.py +0 -0
  24. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/indexer/pipeline.py +0 -0
  25. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/init.py +0 -0
  26. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/prompts/system.md +0 -0
  27. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/retriever/__init__.py +0 -0
  28. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/retriever/graph.py +0 -0
  29. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/retriever/search.py +0 -0
  30. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/static/app.js +0 -0
  31. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/static/index.html +0 -0
  32. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/static/styles.css +0 -0
  33. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire.egg-info/SOURCES.txt +0 -0
  34. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire.egg-info/dependency_links.txt +0 -0
  35. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire.egg-info/entry_points.txt +0 -0
  36. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire.egg-info/requires.txt +0 -0
  37. {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire.egg-info/top_level.txt +0 -0
  38. {sourcefire-0.3.1 → sourcefire-0.3.4}/tests/test_config.py +0 -0
  39. {sourcefire-0.3.1 → sourcefire-0.3.4}/tests/test_graph.py +0 -0
  40. {sourcefire-0.3.1 → sourcefire-0.3.4}/tests/test_metadata.py +0 -0
  41. {sourcefire-0.3.1 → sourcefire-0.3.4}/tests/test_prompts.py +0 -0
  42. {sourcefire-0.3.1 → sourcefire-0.3.4}/tests/test_routes.py +0 -0
  43. {sourcefire-0.3.1 → sourcefire-0.3.4}/tests/test_search.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcefire
3
- Version: 0.3.1
3
+ Version: 0.3.4
4
4
  Summary: Get instant context on any codebase. One command to index, ask questions in plain English, get answers grounded in actual code.
5
5
  Author-email: Athar Wani <athar@cravv.com>
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "sourcefire"
3
- version = "0.3.1"
3
+ version = "0.3.4"
4
4
  description = "Get instant context on any codebase. One command to index, ask questions in plain English, get answers grounded in actual code."
5
5
  readme = "README.md"
6
6
  license = {text = "MIT"}
@@ -46,13 +46,20 @@ def discover_project() -> tuple[Path, Path]:
46
46
  Returns (project_dir, sourcefire_dir).
47
47
  If not found, returns (cwd, cwd/.sourcefire).
48
48
  """
49
+ # Stop boundaries — never treat these as project roots
50
+ stop_dirs = {
51
+ Path.home().resolve(),
52
+ Path("/").resolve(),
53
+ }
54
+
49
55
  current = Path.cwd().resolve()
50
56
  while True:
51
57
  candidate = current / ".sourcefire"
52
- if candidate.is_dir():
58
+ # Only accept if it has a config.toml (project-level, not stale/global)
59
+ if candidate.is_dir() and (candidate / "config.toml").is_file():
53
60
  return current, candidate
54
61
  parent = current.parent
55
- if parent == current:
62
+ if parent == current or current in stop_dirs:
56
63
  break
57
64
  current = parent
58
65
 
@@ -146,7 +153,15 @@ async def lifespan(app: FastAPI):
146
153
  collection = get_collection(client)
147
154
 
148
155
  # Determine if this is a first run (empty collection)
149
- existing_count = collection.count()
156
+ try:
157
+ existing_count = collection.count()
158
+ except Exception:
159
+ # Corrupted or stale ChromaDB — reset
160
+ print("[sourcefire] ChromaDB state is corrupted — resetting...")
161
+ from sourcefire.db import reset_collection
162
+ collection = reset_collection(client)
163
+ existing_count = 0
164
+
150
165
  is_first_run = existing_count == 0
151
166
 
152
167
  # Run indexing
@@ -270,28 +285,28 @@ def main() -> None:
270
285
 
271
286
  project_dir, sourcefire_dir = discover_project()
272
287
 
273
- # Safety check: warn if running in a broad directory (home, /, etc.)
274
- needs_init = not sourcefire_dir.exists() or not (sourcefire_dir / "config.toml").exists()
275
- if needs_init:
276
- dangerous_dirs = {
277
- Path.home().resolve(),
278
- Path("/").resolve(),
279
- }
280
- # Also flag common broad directories
281
- for name in ("Documents", "Downloads", "Desktop"):
282
- dangerous_dirs.add((Path.home() / name).resolve())
283
-
284
- if project_dir.resolve() in dangerous_dirs:
285
- print(f"\n WARNING: You are about to index: {project_dir.resolve()}")
286
- print(" This is a broad directory and may index thousands of files.\n")
287
- try:
288
- confirm = input(" Do you trust this folder? (yes/no): ").strip().lower()
289
- except (EOFError, KeyboardInterrupt):
290
- print("\nAborted.")
291
- sys.exit(1)
292
- if confirm not in ("yes", "y"):
293
- print("Aborted. Run sourcefire from a project directory instead.")
294
- sys.exit(0)
288
+ # Safety check: block broad directories (home, /, Documents, etc.)
289
+ dangerous_dirs = {
290
+ Path.home().resolve(),
291
+ Path("/").resolve(),
292
+ }
293
+ for name in ("Documents", "Downloads", "Desktop", "Library", "Applications",
294
+ "Pictures", "Music", "Movies", "Public"):
295
+ dangerous_dirs.add((Path.home() / name).resolve())
296
+
297
+ resolved_project = project_dir.resolve()
298
+ if resolved_project in dangerous_dirs:
299
+ print(f"\n WARNING: You are about to index: {resolved_project}")
300
+ print(" This is a broad directory — it will index system files, app data, and more.\n")
301
+ print(" Please check twice. This is NOT a project directory.\n")
302
+ try:
303
+ confirm = input(" Do you trust this folder? (yes/no): ").strip().lower()
304
+ except (EOFError, KeyboardInterrupt):
305
+ print("\nAborted.")
306
+ sys.exit(1)
307
+ if confirm not in ("yes", "y"):
308
+ print("Aborted. cd into a project directory and run sourcefire there.")
309
+ sys.exit(0)
295
310
 
296
311
  # Acquire lock
297
312
  lock_fd = acquire_lock(sourcefire_dir / ".lock")
@@ -1,4 +1,4 @@
1
- """Global Sourcefire configuration — stored in ~/.sourcefire/
1
+ """Global Sourcefire configuration — stored in ~/.config/sourcefire/
2
2
 
3
3
  This directory holds user-level settings (API keys, preferences) that
4
4
  apply across all projects. Separate from the per-project .sourcefire/
@@ -20,13 +20,13 @@ import tomli_w
20
20
  def get_global_dir() -> Path:
21
21
  """Return the global Sourcefire config directory.
22
22
 
23
- - macOS/Linux: ~/.sourcefire/
23
+ - macOS/Linux: ~/.config/sourcefire/
24
24
  - Windows: %APPDATA%/sourcefire/
25
25
  """
26
26
  if platform.system() == "Windows":
27
27
  base = Path(os.environ.get("APPDATA", Path.home() / "AppData" / "Roaming"))
28
28
  return base / "sourcefire"
29
- return Path.home() / ".sourcefire"
29
+ return Path.home() / ".config" / "sourcefire"
30
30
 
31
31
 
32
32
  def get_global_config_path() -> Path:
@@ -16,8 +16,24 @@ from sourcefire.indexer.pipeline import index_files
16
16
  from sourcefire.retriever.graph import ImportGraph
17
17
 
18
18
 
19
+ # Always skip these regardless of config
20
+ _ALWAYS_EXCLUDE = (
21
+ ".sourcefire/",
22
+ ".git/",
23
+ "node_modules/",
24
+ "__pycache__/",
25
+ ".venv/",
26
+ "venv/",
27
+ )
28
+
29
+
19
30
  def _should_watch(rel_path: str, config: SourcefireConfig) -> bool:
20
31
  """Return True if the file matches include patterns and not exclude patterns."""
32
+ # Hard excludes — never watch these
33
+ for prefix in _ALWAYS_EXCLUDE:
34
+ if rel_path.startswith(prefix):
35
+ return False
36
+
21
37
  for pattern in config.exclude:
22
38
  if fnmatch.fnmatch(rel_path, pattern):
23
39
  return False
@@ -45,6 +61,12 @@ async def watch_and_reindex(
45
61
  """
46
62
  project_dir = config.project_dir
47
63
 
64
+ # Safety: refuse to watch home directory or root
65
+ dangerous = {Path.home().resolve(), Path("/").resolve()}
66
+ if project_dir.resolve() in dangerous:
67
+ print(f"[watcher] Refusing to watch {project_dir} — too broad. Watcher disabled.")
68
+ return
69
+
48
70
  print(f"[watcher] Watching {project_dir} for changes...")
49
71
 
50
72
  async for changes in awatch(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sourcefire
3
- Version: 0.3.1
3
+ Version: 0.3.4
4
4
  Summary: Get instant context on any codebase. One command to index, ask questions in plain English, get answers grounded in actual code.
5
5
  Author-email: Athar Wani <athar@cravv.com>
6
6
  License: MIT
File without changes
File without changes
File without changes
File without changes
File without changes