footprinter-cli 1.0.2__tar.gz → 1.0.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.
- {footprinter_cli-1.0.2/footprinter_cli.egg-info → footprinter_cli-1.0.4}/PKG-INFO +44 -79
- footprinter_cli-1.0.4/README.md +188 -0
- footprinter_cli-1.0.2/footprinter/access.py → footprinter_cli-1.0.4/footprinter/access_stamper.py +63 -21
- footprinter_cli-1.0.4/footprinter/api/db.py +38 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/api/server.py +1 -1
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/bundled/config.example.yaml +12 -4
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/__init__.py +7 -8
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/_common.py +9 -2
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/_policy_helpers.py +3 -12
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/_prompt.py +1 -1
- footprinter_cli-1.0.4/footprinter/cli/_vectorize_stage.py +117 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/connect.py +3 -3
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/doctor.py +6 -3
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/ingest.py +187 -5
- footprinter_cli-1.0.4/footprinter/cli/mcp_cmd.py +469 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/search.py +61 -3
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/setup.py +56 -54
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/status.py +144 -1
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/upsert.py +311 -17
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/connectors/__init__.py +2 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/__init__.py +8 -1
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/browser.py +6 -44
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/chats.py +48 -73
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/clients.py +2 -2
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/emails.py +4 -41
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/files.py +29 -48
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/folders.py +56 -62
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/projects.py +30 -17
- footprinter_cli-1.0.4/footprinter/db/protocols.py +16 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/search.py +13 -7
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/sql_utils.py +64 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/status.py +49 -2
- footprinter_cli-1.0.2/footprinter/mcp/db.py → footprinter_cli-1.0.4/footprinter/db_base.py +10 -25
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/browser.py +4 -4
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/browser_indexer.py +1 -1
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/chat_indexer.py +0 -2
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/db/schema.py +4 -36
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/file_indexer.py +17 -72
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/file_scanner.py +39 -14
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/folder_indexer.py +2 -3
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/full_content_extractor.py +49 -51
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/orchestrator.py +11 -3
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/pipe_runner.py +0 -7
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/processing.py +140 -2
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/registry.py +2 -2
- footprinter_cli-1.0.4/footprinter/ingest/scan_summary.py +78 -0
- footprinter_cli-1.0.2/footprinter/ingest/cli.py → footprinter_cli-1.0.4/footprinter/ingest/vector_ops.py +4 -5
- footprinter_cli-1.0.4/footprinter/mcp/db.py +34 -0
- footprinter_cli-1.0.4/footprinter/mcp/resources/__init__.py +1 -0
- footprinter_cli-1.0.4/footprinter/mcp/resources/discoverability.py +59 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/server.py +4 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/tools/navigation.py +3 -10
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/tools/read.py +1 -1
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/tools/search.py +22 -12
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/permissions.py +3 -3
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/semantic/chunking.py +27 -4
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/semantic/hybrid_search.py +3 -8
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/semantic/vector_store.py +29 -9
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/__init__.py +7 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/access_service.py +20 -6
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/content_service.py +15 -5
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/ingest_service.py +3 -5
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/project_service.py +1 -1
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/search_service.py +7 -41
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/source_registry.py +1 -1
- footprinter_cli-1.0.4/footprinter/utils/exceptions.py +5 -0
- footprinter_cli-1.0.4/footprinter/utils/paths.py +15 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/visibility.py +43 -5
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4/footprinter_cli.egg-info}/PKG-INFO +44 -79
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter_cli.egg-info/SOURCES.txt +12 -8
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/pyproject.toml +3 -1
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_access_control_bypasses.py +6 -6
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_access_control_docs.py +2 -2
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_access_recalculate.py +329 -50
- footprinter_cli-1.0.4/tests/test_db_base.py +96 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_edit_recalculate.py +2 -2
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_security_layer.py +0 -1
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_security_permissions.py +2 -2
- footprinter_cli-1.0.2/README.md +0 -225
- footprinter_cli-1.0.2/footprinter/api/db.py +0 -61
- footprinter_cli-1.0.2/footprinter/cli/mcp_cmd.py +0 -750
- footprinter_cli-1.0.2/footprinter/cli/search_cmd.py +0 -69
- footprinter_cli-1.0.2/footprinter/cli/status_cmd.py +0 -104
- footprinter_cli-1.0.2/footprinter/ingest/db/migration.py +0 -371
- footprinter_cli-1.0.2/footprinter/ingest/db/security.py +0 -6
- footprinter_cli-1.0.2/footprinter/mcp/resources/__init__.py +0 -1
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/LICENSE +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/__init__.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/api/__init__.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/api/entities.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/api/search.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/api/semantic.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/api/status.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/bundled/__init__.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/context_patterns.yaml +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/extensions.yaml +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/filename_patterns.yaml +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/mime_mappings.yaml +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/salesforce_rules.yaml +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/security_patterns.yaml +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/__main__.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/api_cmd.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/data.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/delete.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/mcp_setup.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/uninstall.py +0 -0
- /footprinter_cli-1.0.2/footprinter/cli/vectorize_cmd.py → /footprinter_cli-1.0.4/footprinter/cli/vectorize.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/view.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/connectors/config_utils.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/messages.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/policies.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/uploads.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/__init__.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/__init__.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/chat.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/ingest.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/local_files.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/local_folders.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/protocol.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/chat_parsers/__init__.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/chat_parsers/chatgpt_parser.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/chat_parsers/claude_parser.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/content_extractors.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/database.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/db/__init__.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/db/connector_schema.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/run_record.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/status.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/__init__.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/__main__.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/errors.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/resources/context.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/tools/__init__.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/tools/semantic.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/tools/status.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/paths.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/semantic/__init__.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/semantic/embeddings.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/chat_service.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/client_service.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/email_service.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/file_service.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/folder_service.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/includes.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/roles.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/semantic_service.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/status_service.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/visit_service.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/utils/__init__.py +0 -0
- {footprinter_cli-1.0.2/footprinter/mcp → footprinter_cli-1.0.4/footprinter/utils}/extraction.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/utils/hash_utils.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/utils/logging_config.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/utils/mime.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/utils/text.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/utils/time.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter_cli.egg-info/dependency_links.txt +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter_cli.egg-info/entry_points.txt +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter_cli.egg-info/requires.txt +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter_cli.egg-info/top_level.txt +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/setup.cfg +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_build_status_filter.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_bundled.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_e2e_install.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_e2e_pipeline.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_examples.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_files_rename.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_files_surface.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_inherit_resolution.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_logging.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_no_project_root.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_package_init.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_paths_no_test_marker.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_pip_install_e2e.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_prompt_safety.py +0 -0
- {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_resolver.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: footprinter-cli
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.4
|
|
4
4
|
Summary: A local context layer for your files, browser history, chats, and email — searchable, user-owned, MCP-served.
|
|
5
5
|
Author: SwellCity Group
|
|
6
6
|
License: MIT
|
|
@@ -20,6 +20,8 @@ Classifier: Operating System :: MacOS
|
|
|
20
20
|
Classifier: Operating System :: POSIX :: Linux
|
|
21
21
|
Classifier: Programming Language :: Python :: 3.11
|
|
22
22
|
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
25
|
Classifier: Topic :: Database
|
|
24
26
|
Classifier: Topic :: Text Processing :: Indexing
|
|
25
27
|
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
@@ -52,74 +54,59 @@ Requires-Dist: httpx<1.0,>=0.27.0; extra == "dev"
|
|
|
52
54
|
|
|
53
55
|
# Footprinter
|
|
54
56
|
|
|
55
|
-
[](https://github.com/harringjohn/footprinter-cli/actions/workflows/test.yml)
|
|
56
58
|
[](https://pypi.org/project/footprinter-cli/)
|
|
57
59
|
|
|
58
60
|
**A local context layer for your files, browser history, chats, and email — searchable, user-owned, and served to AI agents through [MCP](https://modelcontextprotocol.io/).**
|
|
59
61
|
|
|
60
|
-
Your work lives across
|
|
61
|
-
|
|
62
|
-
## Prerequisites
|
|
63
|
-
|
|
64
|
-
- **Python 3.11 or newer.** Stock macOS ships with Python 3.9, which won't work — install a newer Python from [python.org](https://www.python.org/downloads/) (recommended) or via `brew install python@3.11`.
|
|
65
|
-
- **macOS 13+** or **Linux**.
|
|
66
|
-
- **Full Disk Access on macOS** for browser history indexing. Grant it to your terminal app under *System Settings → Privacy & Security → Full Disk Access*. `fp setup` will guide you through this when needed.
|
|
62
|
+
Your work lives across filesystems, browsers, inboxes, chat histories, and other tools. Footprinter indexes those sources into a single local store, organizes them into the projects and groupings you define, and serves the result to AI agents through a governed access layer. You control what the agent can see. Everything stays on your machine.
|
|
67
63
|
|
|
68
64
|
## Install
|
|
69
65
|
|
|
70
|
-
|
|
66
|
+
Requires **Python 3.11+** and **macOS 13+** or **Linux**. The install script checks your Python version and handles the rest:
|
|
71
67
|
|
|
72
68
|
```bash
|
|
73
|
-
|
|
74
|
-
curl -fsSL https://raw.githubusercontent.com/swellcitygroup/footprinter/main/scripts/release/install.sh | bash
|
|
75
|
-
|
|
76
|
-
# Full install (adds semantic search + document parsing)
|
|
77
|
-
curl -fsSL https://raw.githubusercontent.com/swellcitygroup/footprinter/main/scripts/release/install-full.sh | bash
|
|
69
|
+
curl -fsSL https://raw.githubusercontent.com/harringjohn/footprinter-cli/main/scripts/release/install.sh | bash
|
|
78
70
|
```
|
|
79
71
|
|
|
80
|
-
|
|
72
|
+
Or install with **pipx** directly:
|
|
81
73
|
|
|
82
74
|
```bash
|
|
83
|
-
brew install pipx
|
|
84
|
-
pipx ensurepath # then restart your terminal
|
|
85
75
|
pipx install footprinter-cli
|
|
86
|
-
pipx install 'footprinter-cli[full]' # with semantic + parse
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
> **macOS caveats for manual installs:**
|
|
90
|
-
> - **zsh** treats `[...]` as a glob, so keep the single quotes around any bracketed extras specifier (e.g. `'footprinter-cli[full]'`). Without quotes you'll see `zsh: no matches found`.
|
|
91
|
-
> - **System and Homebrew Python** ship with PEP 668 enabled, which blocks bare `pip install` outside a venv. Use pipx (above) instead.
|
|
92
|
-
> - **python.org-distributed Python** doesn't enforce PEP 668, so a bare `pip install footprinter-cli` outside pipx or a venv may succeed but place `fp` in `/Library/Frameworks/Python.framework/Versions/<x.y>/bin`, which isn't on `PATH` by default. Use pipx (above) or the install script.
|
|
93
|
-
|
|
94
|
-
Inside an existing venv, `pip` works as expected:
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
./venv/bin/pip install footprinter-cli
|
|
98
|
-
./venv/bin/pip install 'footprinter-cli[full]'
|
|
99
76
|
```
|
|
100
77
|
|
|
101
|
-
|
|
78
|
+
Either method gives you the `fp` command with the indexing pipeline, CLI, MCP server, and HTTP API. Optional extras add more:
|
|
102
79
|
|
|
103
80
|
| Extra | What it adds |
|
|
104
81
|
|-------|-------------|
|
|
105
82
|
| `[semantic]` | Semantic search via ChromaDB + ONNX embeddings |
|
|
106
83
|
| `[parse]` | PDF, Word, Excel, PowerPoint content extraction |
|
|
107
|
-
| `[full]` |
|
|
84
|
+
| `[full]` | Both of the above |
|
|
108
85
|
|
|
109
|
-
|
|
110
|
-
> the ChromaDB client with `anonymized_telemetry=False`, so no telemetry is sent
|
|
111
|
-
> regardless of which version pip resolves. ChromaDB also removed product telemetry
|
|
112
|
-
> entirely in version 1.5.4. See
|
|
113
|
-
> [Chroma OSS overview](https://docs.trychroma.com/docs/overview/oss) for details.
|
|
86
|
+
To install with extras: use the [full install script](https://raw.githubusercontent.com/harringjohn/footprinter-cli/main/scripts/release/install-full.sh), or `pipx install 'footprinter-cli[full]'`.
|
|
114
87
|
|
|
115
|
-
|
|
88
|
+
<details>
|
|
89
|
+
<summary>Troubleshooting & alternative install methods</summary>
|
|
90
|
+
|
|
91
|
+
**Python version:** Stock macOS ships Python 3.9. Install 3.11+ from [python.org](https://www.python.org/downloads/) or `brew install python@3.11`.
|
|
92
|
+
|
|
93
|
+
**macOS caveats:**
|
|
94
|
+
- zsh treats `[...]` as a glob — quote extras specifiers: `'footprinter-cli[full]'`
|
|
95
|
+
- System/Homebrew Python blocks bare `pip install` (PEP 668) — use pipx or a venv instead
|
|
96
|
+
|
|
97
|
+
**Inside an existing venv:** `pip install footprinter-cli` works as expected.
|
|
98
|
+
|
|
99
|
+
**Full Disk Access:** Required for browser history indexing on macOS. `fp setup` will prompt you when needed.
|
|
100
|
+
|
|
101
|
+
**ChromaDB telemetry:** Footprinter sets `anonymized_telemetry=False`. ChromaDB also removed product telemetry in v1.5.4. See [Chroma OSS overview](https://docs.trychroma.com/docs/overview/oss).
|
|
116
102
|
|
|
117
|
-
|
|
103
|
+
</details>
|
|
104
|
+
|
|
105
|
+
### Uninstall
|
|
118
106
|
|
|
119
107
|
```bash
|
|
120
|
-
fp uninstall
|
|
121
|
-
pipx uninstall footprinter-cli
|
|
122
|
-
./venv/bin/pip uninstall footprinter-cli # if you installed inside a venv
|
|
108
|
+
fp uninstall # remove MCP entry + user data
|
|
109
|
+
pipx uninstall footprinter-cli # remove the package
|
|
123
110
|
```
|
|
124
111
|
|
|
125
112
|
## Quick Start
|
|
@@ -156,13 +143,11 @@ Once configured, Claude can search your files, browse projects, and find related
|
|
|
156
143
|
| **Local files** | Path, type, size, timestamps, content hash |
|
|
157
144
|
| **Browser history** | Safari and Chrome — URLs, titles, visit times |
|
|
158
145
|
| **Chat exports** | Claude and ChatGPT conversation exports |
|
|
159
|
-
| **Email** | Subject, sender, recipients, body, timestamps
|
|
146
|
+
| **Email** | Subject, sender, recipients, body, timestamps |
|
|
160
147
|
| **Documents** | PDF, Word, Excel, PowerPoint content (with `[parse]` extra) |
|
|
161
148
|
| **Semantic embeddings** | Conceptual similarity across all sources (with `[semantic]` extra) |
|
|
162
149
|
|
|
163
|
-
What lands in the database — and when — is controlled by the **content storage tier** you opt into. By default, Footprinter only indexes metadata; it does not read your file content until you explicitly enable it. See [Content Storage](https://github.com/
|
|
164
|
-
|
|
165
|
-
Additional sources are available through [connector plugins](#connectors).
|
|
150
|
+
What lands in the database — and when — is controlled by the **content storage tier** you opt into. By default, Footprinter only indexes metadata; it does not read your file content until you explicitly enable it. See [Content Storage](https://github.com/harringjohn/footprinter-cli/blob/main/reference/content-storage.md) for the full breakdown.
|
|
166
151
|
|
|
167
152
|
## CLI Commands
|
|
168
153
|
|
|
@@ -187,48 +172,28 @@ All commands use the `fp` entry point.
|
|
|
187
172
|
|
|
188
173
|
Run `fp <command> --help` for full usage.
|
|
189
174
|
|
|
190
|
-
## Connectors
|
|
191
|
-
|
|
192
|
-
Connector plugins add external data sources like email, cloud storage, and third-party services. They install alongside Footprinter and register automatically:
|
|
193
|
-
|
|
194
|
-
```bash
|
|
195
|
-
pip install footprinter-<name>
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
First-party and community connectors are in development — check the repository for updates.
|
|
199
|
-
|
|
200
|
-
Use `fp connect list` to see available connectors and their status.
|
|
201
|
-
|
|
202
175
|
## Architecture
|
|
203
176
|
|
|
204
177
|
Single-process CLI with optional MCP server. SQLite database. No containers, no cloud, no accounts.
|
|
205
178
|
|
|
206
179
|
Sources are scanned into SQLite with bidirectional links connecting local files to remote backups via content hash matching. Embeddings are generated at ingest time for semantic search. The MCP server exposes indexed data with two-layer access control (visibility + permissions) — you decide what agents can see.
|
|
207
180
|
|
|
208
|
-
## Requirements
|
|
209
|
-
|
|
210
|
-
- Python 3.11+
|
|
211
|
-
- macOS 13+ or Linux
|
|
212
|
-
- Full Disk Access on macOS (for browser history)
|
|
213
|
-
|
|
214
181
|
## Documentation
|
|
215
182
|
|
|
216
|
-
- [Interfaces](https://github.com/
|
|
217
|
-
- [Data Model](https://github.com/
|
|
218
|
-
- [Pipeline](https://github.com/
|
|
219
|
-
- [Content Storage](https://github.com/
|
|
220
|
-
- [Access Control](https://github.com/
|
|
183
|
+
- [Interfaces](https://github.com/harringjohn/footprinter-cli/blob/main/reference/interfaces.md) — CLI commands, MCP tools, Python API
|
|
184
|
+
- [Data Model](https://github.com/harringjohn/footprinter-cli/blob/main/reference/data-model.md) — database schema
|
|
185
|
+
- [Pipeline](https://github.com/harringjohn/footprinter-cli/blob/main/reference/pipeline.md) — indexing stages and configuration
|
|
186
|
+
- [Content Storage](https://github.com/harringjohn/footprinter-cli/blob/main/reference/content-storage.md) — metadata vs. snippet vs. full-content tiers
|
|
187
|
+
- [Access Control](https://github.com/harringjohn/footprinter-cli/blob/main/reference/mcp-access-control.md) — MCP security model
|
|
221
188
|
|
|
222
189
|
## Contributing
|
|
223
190
|
|
|
224
|
-
Bug fixes, documentation, and tests welcome. For new features or architectural changes, [open an issue](https://github.com/
|
|
225
|
-
|
|
226
|
-
Connector plugins use an internal API that isn't stable yet — we're not accepting connector contributions at this time.
|
|
191
|
+
Bug fixes, documentation, and tests welcome. For new features or architectural changes, [open an issue](https://github.com/harringjohn/footprinter-cli/issues) first to discuss the approach.
|
|
227
192
|
|
|
228
193
|
### Development setup
|
|
229
194
|
|
|
230
195
|
```bash
|
|
231
|
-
git clone https://github.com/
|
|
196
|
+
git clone https://github.com/harringjohn/footprinter-cli.git
|
|
232
197
|
cd footprinter
|
|
233
198
|
python3 -m venv venv
|
|
234
199
|
./venv/bin/pip install -e ".[dev]"
|
|
@@ -254,7 +219,7 @@ python3 -m venv venv
|
|
|
254
219
|
4. Run the test suite
|
|
255
220
|
5. Submit a PR targeting `main`
|
|
256
221
|
|
|
257
|
-
Never commit API keys, tokens, or credentials. Report security vulnerabilities privately — see [SECURITY.md](https://github.com/
|
|
222
|
+
Never commit API keys, tokens, or credentials. Report security vulnerabilities privately — see [SECURITY.md](https://github.com/harringjohn/footprinter-cli/blob/main/SECURITY.md).
|
|
258
223
|
|
|
259
224
|
### Pull request expectations
|
|
260
225
|
|
|
@@ -265,13 +230,13 @@ Never commit API keys, tokens, or credentials. Report security vulnerabilities p
|
|
|
265
230
|
|
|
266
231
|
All PRs are reviewed by the maintainer. Expect reviews within one week. CI must pass before review begins.
|
|
267
232
|
|
|
268
|
-
No Contributor License Agreement required. By submitting a PR, you agree your contribution is licensed under the project's [MIT License](https://github.com/
|
|
233
|
+
No Contributor License Agreement required. By submitting a PR, you agree your contribution is licensed under the project's [MIT License](https://github.com/harringjohn/footprinter-cli/blob/main/LICENSE).
|
|
269
234
|
|
|
270
235
|
## Community
|
|
271
236
|
|
|
272
|
-
- [Code of Conduct](https://github.com/
|
|
273
|
-
- [Security Policy](https://github.com/
|
|
237
|
+
- [Code of Conduct](https://github.com/harringjohn/footprinter-cli/blob/main/CODE_OF_CONDUCT.md)
|
|
238
|
+
- [Security Policy](https://github.com/harringjohn/footprinter-cli/blob/main/SECURITY.md)
|
|
274
239
|
|
|
275
240
|
## License
|
|
276
241
|
|
|
277
|
-
MIT — see [LICENSE](https://github.com/
|
|
242
|
+
MIT — see [LICENSE](https://github.com/harringjohn/footprinter-cli/blob/main/LICENSE).
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
# Footprinter
|
|
2
|
+
|
|
3
|
+
[](https://github.com/harringjohn/footprinter-cli/actions/workflows/test.yml)
|
|
4
|
+
[](https://pypi.org/project/footprinter-cli/)
|
|
5
|
+
|
|
6
|
+
**A local context layer for your files, browser history, chats, and email — searchable, user-owned, and served to AI agents through [MCP](https://modelcontextprotocol.io/).**
|
|
7
|
+
|
|
8
|
+
Your work lives across filesystems, browsers, inboxes, chat histories, and other tools. Footprinter indexes those sources into a single local store, organizes them into the projects and groupings you define, and serves the result to AI agents through a governed access layer. You control what the agent can see. Everything stays on your machine.
|
|
9
|
+
|
|
10
|
+
## Install
|
|
11
|
+
|
|
12
|
+
Requires **Python 3.11+** and **macOS 13+** or **Linux**. The install script checks your Python version and handles the rest:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
curl -fsSL https://raw.githubusercontent.com/harringjohn/footprinter-cli/main/scripts/release/install.sh | bash
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Or install with **pipx** directly:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pipx install footprinter-cli
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Either method gives you the `fp` command with the indexing pipeline, CLI, MCP server, and HTTP API. Optional extras add more:
|
|
25
|
+
|
|
26
|
+
| Extra | What it adds |
|
|
27
|
+
|-------|-------------|
|
|
28
|
+
| `[semantic]` | Semantic search via ChromaDB + ONNX embeddings |
|
|
29
|
+
| `[parse]` | PDF, Word, Excel, PowerPoint content extraction |
|
|
30
|
+
| `[full]` | Both of the above |
|
|
31
|
+
|
|
32
|
+
To install with extras: use the [full install script](https://raw.githubusercontent.com/harringjohn/footprinter-cli/main/scripts/release/install-full.sh), or `pipx install 'footprinter-cli[full]'`.
|
|
33
|
+
|
|
34
|
+
<details>
|
|
35
|
+
<summary>Troubleshooting & alternative install methods</summary>
|
|
36
|
+
|
|
37
|
+
**Python version:** Stock macOS ships Python 3.9. Install 3.11+ from [python.org](https://www.python.org/downloads/) or `brew install python@3.11`.
|
|
38
|
+
|
|
39
|
+
**macOS caveats:**
|
|
40
|
+
- zsh treats `[...]` as a glob — quote extras specifiers: `'footprinter-cli[full]'`
|
|
41
|
+
- System/Homebrew Python blocks bare `pip install` (PEP 668) — use pipx or a venv instead
|
|
42
|
+
|
|
43
|
+
**Inside an existing venv:** `pip install footprinter-cli` works as expected.
|
|
44
|
+
|
|
45
|
+
**Full Disk Access:** Required for browser history indexing on macOS. `fp setup` will prompt you when needed.
|
|
46
|
+
|
|
47
|
+
**ChromaDB telemetry:** Footprinter sets `anonymized_telemetry=False`. ChromaDB also removed product telemetry in v1.5.4. See [Chroma OSS overview](https://docs.trychroma.com/docs/overview/oss).
|
|
48
|
+
|
|
49
|
+
</details>
|
|
50
|
+
|
|
51
|
+
### Uninstall
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
fp uninstall # remove MCP entry + user data
|
|
55
|
+
pipx uninstall footprinter-cli # remove the package
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Quick Start
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
fp setup # Configure sources (interactive wizard)
|
|
62
|
+
fp ingest # Index your files
|
|
63
|
+
fp status # See what's indexed
|
|
64
|
+
fp search "meeting notes" # Find things
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
A few first-run notes:
|
|
68
|
+
|
|
69
|
+
- The first ingest is implicitly full; subsequent runs are incremental. If you change exclusions or add directories after the first run, re-run with `fp ingest --full` so previously skipped files get picked up.
|
|
70
|
+
- With `[semantic]` or `[full]`, the **first ingest downloads ~80MB** of ONNX embedding model weights. It's a one-time cost — subsequent ingests are fast.
|
|
71
|
+
- Keep the directories you want indexed **outside `~/Downloads`** — the default exclusion list skips it.
|
|
72
|
+
|
|
73
|
+
## Connect to Claude Desktop
|
|
74
|
+
|
|
75
|
+
Footprinter includes an MCP server that gives Claude Desktop (or any MCP client) structured access to your indexed data:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
fp setup mcp --claude # Configure MCP for Claude Desktop
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
After running this, **fully quit Claude Desktop (Cmd+Q) and relaunch** before the Footprinter tools appear in the conversation tools list. A simple window close isn't enough — the app keeps running in the menu bar.
|
|
82
|
+
|
|
83
|
+
Once configured, Claude can search your files, browse projects, and find related conversations — through natural language.
|
|
84
|
+
|
|
85
|
+
## What It Indexes
|
|
86
|
+
|
|
87
|
+
| Source | What's captured |
|
|
88
|
+
|--------|----------------|
|
|
89
|
+
| **Local files** | Path, type, size, timestamps, content hash |
|
|
90
|
+
| **Browser history** | Safari and Chrome — URLs, titles, visit times |
|
|
91
|
+
| **Chat exports** | Claude and ChatGPT conversation exports |
|
|
92
|
+
| **Email** | Subject, sender, recipients, body, timestamps |
|
|
93
|
+
| **Documents** | PDF, Word, Excel, PowerPoint content (with `[parse]` extra) |
|
|
94
|
+
| **Semantic embeddings** | Conceptual similarity across all sources (with `[semantic]` extra) |
|
|
95
|
+
|
|
96
|
+
What lands in the database — and when — is controlled by the **content storage tier** you opt into. By default, Footprinter only indexes metadata; it does not read your file content until you explicitly enable it. See [Content Storage](https://github.com/harringjohn/footprinter-cli/blob/main/reference/content-storage.md) for the full breakdown.
|
|
97
|
+
|
|
98
|
+
## CLI Commands
|
|
99
|
+
|
|
100
|
+
All commands use the `fp` entry point.
|
|
101
|
+
|
|
102
|
+
| Command | Purpose |
|
|
103
|
+
|---------|---------|
|
|
104
|
+
| `fp setup` | Configure sources and integrations |
|
|
105
|
+
| `fp ingest` | Run the indexing pipeline |
|
|
106
|
+
| `fp status` | System health and data counts |
|
|
107
|
+
| `fp search` | Search across all indexed sources |
|
|
108
|
+
| `fp connect` | Manage optional integrations |
|
|
109
|
+
| `fp mcp` | MCP server and access policies |
|
|
110
|
+
| `fp api` | Start the HTTP API server |
|
|
111
|
+
| `fp view` | Browse indexed data (files, folders, projects, clients, chats, emails, visits) |
|
|
112
|
+
| `fp upsert` | Create/update records, assign relationships, or soft-delete via `--status removed` |
|
|
113
|
+
| `fp data` | Export data, generate templates, or import metadata corrections |
|
|
114
|
+
| `fp delete` | Hard-delete a super entity (irreversible) |
|
|
115
|
+
| `fp vectorize` | Manage per-record vectorization control |
|
|
116
|
+
| `fp doctor` | Post-install health check (Python version, install location, FDA, MCP wiring) |
|
|
117
|
+
| `fp uninstall` | Remove Footprinter — MCP entry, user data, package |
|
|
118
|
+
|
|
119
|
+
Run `fp <command> --help` for full usage.
|
|
120
|
+
|
|
121
|
+
## Architecture
|
|
122
|
+
|
|
123
|
+
Single-process CLI with optional MCP server. SQLite database. No containers, no cloud, no accounts.
|
|
124
|
+
|
|
125
|
+
Sources are scanned into SQLite with bidirectional links connecting local files to remote backups via content hash matching. Embeddings are generated at ingest time for semantic search. The MCP server exposes indexed data with two-layer access control (visibility + permissions) — you decide what agents can see.
|
|
126
|
+
|
|
127
|
+
## Documentation
|
|
128
|
+
|
|
129
|
+
- [Interfaces](https://github.com/harringjohn/footprinter-cli/blob/main/reference/interfaces.md) — CLI commands, MCP tools, Python API
|
|
130
|
+
- [Data Model](https://github.com/harringjohn/footprinter-cli/blob/main/reference/data-model.md) — database schema
|
|
131
|
+
- [Pipeline](https://github.com/harringjohn/footprinter-cli/blob/main/reference/pipeline.md) — indexing stages and configuration
|
|
132
|
+
- [Content Storage](https://github.com/harringjohn/footprinter-cli/blob/main/reference/content-storage.md) — metadata vs. snippet vs. full-content tiers
|
|
133
|
+
- [Access Control](https://github.com/harringjohn/footprinter-cli/blob/main/reference/mcp-access-control.md) — MCP security model
|
|
134
|
+
|
|
135
|
+
## Contributing
|
|
136
|
+
|
|
137
|
+
Bug fixes, documentation, and tests welcome. For new features or architectural changes, [open an issue](https://github.com/harringjohn/footprinter-cli/issues) first to discuss the approach.
|
|
138
|
+
|
|
139
|
+
### Development setup
|
|
140
|
+
|
|
141
|
+
```bash
|
|
142
|
+
git clone https://github.com/harringjohn/footprinter-cli.git
|
|
143
|
+
cd footprinter
|
|
144
|
+
python3 -m venv venv
|
|
145
|
+
./venv/bin/pip install -e ".[dev]"
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### Running tests
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
./venv/bin/pytest tests/ -v --tb=short
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Code style
|
|
155
|
+
|
|
156
|
+
- PEP 8
|
|
157
|
+
- Type hints on function signatures
|
|
158
|
+
- `logging` over `print()` in library code
|
|
159
|
+
|
|
160
|
+
### Workflow
|
|
161
|
+
|
|
162
|
+
1. Fork the repository
|
|
163
|
+
2. Create a feature branch from `main`
|
|
164
|
+
3. Write tests (TDD preferred — tests before implementation)
|
|
165
|
+
4. Run the test suite
|
|
166
|
+
5. Submit a PR targeting `main`
|
|
167
|
+
|
|
168
|
+
Never commit API keys, tokens, or credentials. Report security vulnerabilities privately — see [SECURITY.md](https://github.com/harringjohn/footprinter-cli/blob/main/SECURITY.md).
|
|
169
|
+
|
|
170
|
+
### Pull request expectations
|
|
171
|
+
|
|
172
|
+
- Tests must pass
|
|
173
|
+
- No breaking changes to existing CLI commands
|
|
174
|
+
- Fill out the PR template
|
|
175
|
+
- One logical change per PR
|
|
176
|
+
|
|
177
|
+
All PRs are reviewed by the maintainer. Expect reviews within one week. CI must pass before review begins.
|
|
178
|
+
|
|
179
|
+
No Contributor License Agreement required. By submitting a PR, you agree your contribution is licensed under the project's [MIT License](https://github.com/harringjohn/footprinter-cli/blob/main/LICENSE).
|
|
180
|
+
|
|
181
|
+
## Community
|
|
182
|
+
|
|
183
|
+
- [Code of Conduct](https://github.com/harringjohn/footprinter-cli/blob/main/CODE_OF_CONDUCT.md)
|
|
184
|
+
- [Security Policy](https://github.com/harringjohn/footprinter-cli/blob/main/SECURITY.md)
|
|
185
|
+
|
|
186
|
+
## License
|
|
187
|
+
|
|
188
|
+
MIT — see [LICENSE](https://github.com/harringjohn/footprinter-cli/blob/main/LICENSE).
|
footprinter_cli-1.0.2/footprinter/access.py → footprinter_cli-1.0.4/footprinter/access_stamper.py
RENAMED
|
@@ -12,6 +12,7 @@ import sqlite3
|
|
|
12
12
|
from collections.abc import Callable
|
|
13
13
|
from typing import Any
|
|
14
14
|
|
|
15
|
+
from footprinter.db.policies import is_folder_path_scope
|
|
15
16
|
from footprinter.permissions import batch_resolve_permissions
|
|
16
17
|
from footprinter.visibility import batch_resolve_visibility
|
|
17
18
|
|
|
@@ -113,10 +114,21 @@ ENTITY_META: dict[str, dict[str, Any]] = {
|
|
|
113
114
|
"has_account": False,
|
|
114
115
|
"path_column": None,
|
|
115
116
|
},
|
|
117
|
+
"visit": {
|
|
118
|
+
"table": "visits",
|
|
119
|
+
"has_visibility": True,
|
|
120
|
+
"has_permissions": True,
|
|
121
|
+
"has_status": False,
|
|
122
|
+
"has_project_id": False,
|
|
123
|
+
"has_client_id": False,
|
|
124
|
+
"has_account": False,
|
|
125
|
+
"path_column": None,
|
|
126
|
+
},
|
|
116
127
|
}
|
|
117
128
|
|
|
118
129
|
# Reverse map: source scope suffix → entity type (e.g. "files" → "file")
|
|
119
130
|
_SOURCE_TO_ENTITY = {meta["table"]: etype for etype, meta in ENTITY_META.items()}
|
|
131
|
+
_SOURCE_TO_ENTITY["browser"] = "visit"
|
|
120
132
|
|
|
121
133
|
|
|
122
134
|
# ---------------------------------------------------------------------------
|
|
@@ -170,28 +182,58 @@ def _get_ids_for_scope(conn: sqlite3.Connection, scope: str) -> dict[str, list[i
|
|
|
170
182
|
return result
|
|
171
183
|
|
|
172
184
|
if prefix == "folder":
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
185
|
+
if is_folder_path_scope(scope):
|
|
186
|
+
# folder:{path} → files/folders with matching path prefix
|
|
187
|
+
path = os.path.expanduser(value)
|
|
188
|
+
# Escape LIKE metacharacters so literal %, _ in paths match correctly
|
|
189
|
+
escaped = path.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_")
|
|
190
|
+
result = {}
|
|
191
|
+
for etype in ENTITY_META:
|
|
192
|
+
meta = ENTITY_META[etype]
|
|
193
|
+
path_col = meta["path_column"]
|
|
194
|
+
if path_col is None:
|
|
195
|
+
continue
|
|
196
|
+
table = meta["table"]
|
|
197
|
+
where = f"{path_col} LIKE ? ESCAPE '\\'"
|
|
198
|
+
if meta["has_status"]:
|
|
199
|
+
where += " AND status = 'listed'"
|
|
200
|
+
rows = conn.execute(
|
|
201
|
+
f"SELECT id FROM {table} WHERE {where}",
|
|
202
|
+
(escaped + "%",),
|
|
203
|
+
).fetchall()
|
|
204
|
+
ids = [r["id"] for r in rows]
|
|
205
|
+
if ids:
|
|
206
|
+
result[etype] = ids
|
|
207
|
+
return result
|
|
208
|
+
else:
|
|
209
|
+
# folder:{id} → folder + all descendants via parent_folder_id
|
|
210
|
+
folder_id = int(value)
|
|
211
|
+
descendants_cte = """
|
|
212
|
+
WITH RECURSIVE descendants(id) AS (
|
|
213
|
+
SELECT id FROM folders WHERE id = ?
|
|
214
|
+
UNION ALL
|
|
215
|
+
SELECT folder.id FROM folders folder
|
|
216
|
+
JOIN descendants descendant ON folder.parent_folder_id = descendant.id
|
|
217
|
+
)
|
|
218
|
+
"""
|
|
219
|
+
cursor = conn.cursor()
|
|
220
|
+
cursor.execute(
|
|
221
|
+
f"{descendants_cte} SELECT id FROM descendants",
|
|
222
|
+
(folder_id,),
|
|
223
|
+
)
|
|
224
|
+
desc_ids = [row["id"] for row in cursor.fetchall()]
|
|
225
|
+
if not desc_ids:
|
|
226
|
+
return {}
|
|
227
|
+
result: dict[str, list[int]] = {"folder": desc_ids}
|
|
228
|
+
ph = ",".join("?" * len(desc_ids))
|
|
229
|
+
file_rows = conn.execute(
|
|
230
|
+
f"SELECT id FROM files WHERE folder_id IN ({ph}) AND status = 'listed'",
|
|
231
|
+
tuple(desc_ids),
|
|
190
232
|
).fetchall()
|
|
191
|
-
|
|
192
|
-
if
|
|
193
|
-
result[
|
|
194
|
-
|
|
233
|
+
file_ids = [r["id"] for r in file_rows]
|
|
234
|
+
if file_ids:
|
|
235
|
+
result["file"] = file_ids
|
|
236
|
+
return result
|
|
195
237
|
|
|
196
238
|
if prefix == "project":
|
|
197
239
|
project_id = int(value)
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Database connection for Footprinter HTTP API."""
|
|
2
|
+
|
|
3
|
+
import sqlite3
|
|
4
|
+
from contextlib import contextmanager
|
|
5
|
+
from typing import Generator
|
|
6
|
+
|
|
7
|
+
from footprinter.db_base import open_checked_connection
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@contextmanager
|
|
11
|
+
def get_db() -> Generator[sqlite3.Connection, None, None]:
|
|
12
|
+
"""Context manager for database connections.
|
|
13
|
+
|
|
14
|
+
Divergences from MCP's ``get_db()``:
|
|
15
|
+
|
|
16
|
+
- No ``PRAGMA query_only`` — the HTTP API uses Role.ADMIN and may need
|
|
17
|
+
write access for future endpoints.
|
|
18
|
+
- No ``handle_db_errors`` decorator — ``DatabaseNotInitializedError`` is
|
|
19
|
+
caught by a FastAPI exception handler registered in ``server.create_app()``.
|
|
20
|
+
|
|
21
|
+
Calls ``load_globals()`` to refresh the global visibility/permission
|
|
22
|
+
policy cache in ``access_service`` for the current request.
|
|
23
|
+
"""
|
|
24
|
+
with open_checked_connection() as conn:
|
|
25
|
+
yield conn
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def get_conn():
|
|
29
|
+
"""FastAPI dependency that yields a database connection.
|
|
30
|
+
|
|
31
|
+
Usage::
|
|
32
|
+
|
|
33
|
+
@router.get("/endpoint")
|
|
34
|
+
def handler(conn=Depends(get_conn)):
|
|
35
|
+
...
|
|
36
|
+
"""
|
|
37
|
+
with get_db() as conn:
|
|
38
|
+
yield conn
|
|
@@ -78,9 +78,12 @@ exclusions:
|
|
|
78
78
|
# Indexing configuration - INDEX ALL FILE TYPES
|
|
79
79
|
indexing:
|
|
80
80
|
supported_extensions: [] # Empty = index ALL file types
|
|
81
|
-
max_file_size_mb:
|
|
81
|
+
max_file_size_mb: 50 # MB; 0 = no size limit. 50 is generous for prose/docs.
|
|
82
82
|
lookback_days: 14 # Browser history window (days back to index)
|
|
83
83
|
content_snippets: false # Extract file/email content previews for keyword search
|
|
84
|
+
# `fp ingest --preview` (FPR-1723) — pre-scan summary tuning
|
|
85
|
+
preview_top_n: 10 # rows shown for top files / top directories
|
|
86
|
+
preview_size_threshold_mb: 50 # files at or above this size are flagged as outliers
|
|
84
87
|
|
|
85
88
|
# Semantic search — stores content as embeddings in a local ChromaDB database
|
|
86
89
|
# Enables finding files and chats by meaning, not just keywords
|
|
@@ -104,13 +107,18 @@ vectorization:
|
|
|
104
107
|
- .txt
|
|
105
108
|
- .pdf
|
|
106
109
|
- .docx
|
|
110
|
+
# Maximum file size (MB) eligible for vectorization. Applies even when
|
|
111
|
+
# indexing.max_file_size_mb is 0 (no limit). Chunking a multi-GB file
|
|
112
|
+
# produces millions of chunks and can OOM the host — this guardrail is
|
|
113
|
+
# always on. Skipped files appear in the post-ingest summary.
|
|
114
|
+
max_vectorize_size_mb: 100
|
|
107
115
|
# Chunk size in characters — tuned for MiniLM-L6-v2 (256-token input window).
|
|
108
116
|
# ~1000 chars ≈ 250 tokens. Larger chunks get silently truncated by the model,
|
|
109
117
|
# meaning content past the window is invisible to semantic search.
|
|
110
118
|
chunk_size: 1000
|
|
111
|
-
#
|
|
112
|
-
#
|
|
113
|
-
#
|
|
119
|
+
# Fractional overlap between consecutive chunks (0.0–1.0).
|
|
120
|
+
# 0.15 = 15% of chunk_size chars shared between adjacent chunks.
|
|
121
|
+
# Legacy integer values (>= 1) are accepted but deprecated.
|
|
114
122
|
chunk_overlap: 0.15
|
|
115
123
|
# Patterns (fnmatch syntax) for file paths to skip during vectorization.
|
|
116
124
|
# Matched against the full absolute path (e.g. ~/Work/file.json expands at runtime).
|
|
@@ -29,10 +29,9 @@ def main(argv=None) -> None:
|
|
|
29
29
|
|
|
30
30
|
if argv is None:
|
|
31
31
|
argv = _sys.argv[1:]
|
|
32
|
-
from footprinter.source_registry import ConfigError as _ConfigError
|
|
33
|
-
|
|
34
32
|
from footprinter import __version__
|
|
35
33
|
from footprinter.cli._common import FORMATTER
|
|
34
|
+
from footprinter.source_registry import ConfigError as _ConfigError
|
|
36
35
|
|
|
37
36
|
parser = argparse.ArgumentParser(
|
|
38
37
|
prog="fp",
|
|
@@ -89,12 +88,12 @@ def main(argv=None) -> None:
|
|
|
89
88
|
doctor,
|
|
90
89
|
ingest,
|
|
91
90
|
mcp_cmd,
|
|
92
|
-
|
|
91
|
+
search,
|
|
93
92
|
setup,
|
|
94
|
-
|
|
93
|
+
status,
|
|
95
94
|
uninstall,
|
|
96
95
|
upsert,
|
|
97
|
-
|
|
96
|
+
vectorize,
|
|
98
97
|
view,
|
|
99
98
|
)
|
|
100
99
|
|
|
@@ -102,15 +101,15 @@ def main(argv=None) -> None:
|
|
|
102
101
|
ingest,
|
|
103
102
|
mcp_cmd,
|
|
104
103
|
api_cmd,
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
status,
|
|
105
|
+
search,
|
|
107
106
|
setup,
|
|
108
107
|
connect,
|
|
109
108
|
view,
|
|
110
109
|
upsert,
|
|
111
110
|
data,
|
|
112
111
|
delete,
|
|
113
|
-
|
|
112
|
+
vectorize,
|
|
114
113
|
uninstall,
|
|
115
114
|
doctor,
|
|
116
115
|
]:
|