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.
- {sourcefire-0.3.1/sourcefire.egg-info → sourcefire-0.3.4}/PKG-INFO +1 -1
- {sourcefire-0.3.1 → sourcefire-0.3.4}/pyproject.toml +1 -1
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/cli.py +40 -25
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/global_config.py +3 -3
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/watcher.py +22 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4/sourcefire.egg-info}/PKG-INFO +1 -1
- {sourcefire-0.3.1 → sourcefire-0.3.4}/LICENSE +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/MANIFEST.in +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/README.md +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/setup.cfg +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/__init__.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/api/__init__.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/api/models.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/api/routes.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/chain/__init__.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/chain/prompts.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/chain/rag_chain.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/config.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/db.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/indexer/__init__.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/indexer/embeddings.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/indexer/language_profiles.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/indexer/metadata.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/indexer/pipeline.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/init.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/prompts/system.md +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/retriever/__init__.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/retriever/graph.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/retriever/search.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/static/app.js +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/static/index.html +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire/static/styles.css +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire.egg-info/SOURCES.txt +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire.egg-info/dependency_links.txt +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire.egg-info/entry_points.txt +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire.egg-info/requires.txt +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/sourcefire.egg-info/top_level.txt +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/tests/test_config.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/tests/test_graph.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/tests/test_metadata.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/tests/test_prompts.py +0 -0
- {sourcefire-0.3.1 → sourcefire-0.3.4}/tests/test_routes.py +0 -0
- {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.
|
|
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
|
|
@@ -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
|
|
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
|
-
|
|
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:
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
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.
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|