footprinter-cli 1.0.3__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.3/footprinter_cli.egg-info → footprinter_cli-1.0.4}/PKG-INFO +28 -63
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/README.md +25 -62
- footprinter_cli-1.0.3/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.3 → footprinter_cli-1.0.4}/footprinter/api/server.py +1 -1
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/bundled/config.example.yaml +3 -3
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/__init__.py +6 -6
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/_common.py +9 -2
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/_policy_helpers.py +3 -12
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/_prompt.py +1 -1
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/_vectorize_stage.py +1 -1
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/connect.py +3 -3
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/ingest.py +4 -4
- footprinter_cli-1.0.4/footprinter/cli/mcp_cmd.py +469 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/search.py +61 -3
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/setup.py +50 -54
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/status.py +84 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/upsert.py +309 -14
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/connectors/__init__.py +2 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/db/__init__.py +8 -1
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/db/browser.py +4 -41
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/db/chats.py +23 -59
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/db/emails.py +4 -41
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/db/files.py +18 -43
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/db/folders.py +46 -48
- footprinter_cli-1.0.4/footprinter/db/protocols.py +16 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/db/search.py +12 -7
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/db/sql_utils.py +64 -0
- footprinter_cli-1.0.3/footprinter/mcp/db.py → footprinter_cli-1.0.4/footprinter/db_base.py +10 -25
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/browser.py +4 -4
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/browser_indexer.py +1 -1
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/chat_indexer.py +0 -2
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/db/schema.py +4 -36
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/file_indexer.py +8 -2
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/file_scanner.py +12 -2
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/full_content_extractor.py +24 -39
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/orchestrator.py +6 -3
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/pipe_runner.py +0 -7
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/processing.py +1 -1
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/registry.py +2 -2
- footprinter_cli-1.0.3/footprinter/ingest/cli.py → footprinter_cli-1.0.4/footprinter/ingest/vector_ops.py +3 -4
- 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.3 → footprinter_cli-1.0.4}/footprinter/mcp/tools/navigation.py +3 -10
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/mcp/tools/read.py +1 -1
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/mcp/tools/search.py +1 -9
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/permissions.py +3 -3
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/semantic/chunking.py +27 -4
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/semantic/hybrid_search.py +3 -8
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/semantic/vector_store.py +25 -8
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/services/__init__.py +7 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/services/access_service.py +20 -6
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/services/content_service.py +15 -5
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/services/ingest_service.py +3 -5
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/services/search_service.py +7 -41
- {footprinter_cli-1.0.3 → 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.3 → footprinter_cli-1.0.4}/footprinter/visibility.py +43 -5
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4/footprinter_cli.egg-info}/PKG-INFO +28 -63
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter_cli.egg-info/SOURCES.txt +9 -8
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/pyproject.toml +3 -1
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_access_control_bypasses.py +6 -6
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_access_control_docs.py +2 -2
- {footprinter_cli-1.0.3 → 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.3 → footprinter_cli-1.0.4}/tests/test_edit_recalculate.py +2 -2
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_security_layer.py +0 -1
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_security_permissions.py +2 -2
- footprinter_cli-1.0.3/footprinter/api/db.py +0 -61
- footprinter_cli-1.0.3/footprinter/cli/mcp_cmd.py +0 -750
- footprinter_cli-1.0.3/footprinter/cli/search_cmd.py +0 -69
- footprinter_cli-1.0.3/footprinter/cli/status_cmd.py +0 -104
- footprinter_cli-1.0.3/footprinter/ingest/db/migration.py +0 -371
- footprinter_cli-1.0.3/footprinter/ingest/db/security.py +0 -6
- footprinter_cli-1.0.3/footprinter/mcp/resources/__init__.py +0 -1
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/LICENSE +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/__init__.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/api/__init__.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/api/entities.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/api/search.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/api/semantic.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/api/status.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/bundled/__init__.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/context_patterns.yaml +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/extensions.yaml +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/filename_patterns.yaml +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/mime_mappings.yaml +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/salesforce_rules.yaml +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/security_patterns.yaml +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/__main__.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/api_cmd.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/data.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/delete.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/doctor.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/mcp_setup.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/uninstall.py +0 -0
- /footprinter_cli-1.0.3/footprinter/cli/vectorize_cmd.py → /footprinter_cli-1.0.4/footprinter/cli/vectorize.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/cli/view.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/connectors/config_utils.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/db/clients.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/db/messages.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/db/policies.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/db/projects.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/db/status.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/db/uploads.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/__init__.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/__init__.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/chat.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/ingest.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/local_files.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/local_folders.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/protocol.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/chat_parsers/__init__.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/chat_parsers/chatgpt_parser.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/chat_parsers/claude_parser.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/content_extractors.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/database.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/db/__init__.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/db/connector_schema.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/folder_indexer.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/run_record.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/scan_summary.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/ingest/status.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/mcp/__init__.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/mcp/__main__.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/mcp/errors.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/mcp/resources/context.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/mcp/resources/discoverability.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/mcp/server.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/mcp/tools/__init__.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/mcp/tools/semantic.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/mcp/tools/status.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/paths.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/semantic/__init__.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/semantic/embeddings.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/services/chat_service.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/services/client_service.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/services/email_service.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/services/file_service.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/services/folder_service.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/services/includes.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/services/project_service.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/services/roles.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/services/semantic_service.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/services/status_service.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/services/visit_service.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/utils/__init__.py +0 -0
- {footprinter_cli-1.0.3/footprinter/mcp → footprinter_cli-1.0.4/footprinter/utils}/extraction.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/utils/hash_utils.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/utils/logging_config.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/utils/mime.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/utils/text.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter/utils/time.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter_cli.egg-info/dependency_links.txt +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter_cli.egg-info/entry_points.txt +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter_cli.egg-info/requires.txt +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/footprinter_cli.egg-info/top_level.txt +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/setup.cfg +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_build_status_filter.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_bundled.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_e2e_install.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_e2e_pipeline.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_examples.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_files_rename.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_files_surface.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_inherit_resolution.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_logging.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_no_project_root.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_package_init.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_paths_no_test_marker.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_pip_install_e2e.py +0 -0
- {footprinter_cli-1.0.3 → footprinter_cli-1.0.4}/tests/test_prompt_safety.py +0 -0
- {footprinter_cli-1.0.3 → 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
|
|
@@ -59,67 +61,52 @@ Requires-Dist: httpx<1.0,>=0.27.0; extra == "dev"
|
|
|
59
61
|
|
|
60
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.
|
|
61
63
|
|
|
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.
|
|
67
|
-
|
|
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
|
-
# Base install (CLI + MCP + HTTP API)
|
|
74
69
|
curl -fsSL https://raw.githubusercontent.com/harringjohn/footprinter-cli/main/scripts/release/install.sh | bash
|
|
75
|
-
|
|
76
|
-
# Full install (adds semantic search + document parsing)
|
|
77
|
-
curl -fsSL https://raw.githubusercontent.com/harringjohn/footprinter-cli/main/scripts/release/install-full.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,14 +143,12 @@ 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
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.
|
|
164
151
|
|
|
165
|
-
Additional sources are available through [connector plugins](#connectors).
|
|
166
|
-
|
|
167
152
|
## CLI Commands
|
|
168
153
|
|
|
169
154
|
All commands use the `fp` entry point.
|
|
@@ -187,30 +172,12 @@ 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
183
|
- [Interfaces](https://github.com/harringjohn/footprinter-cli/blob/main/reference/interfaces.md) — CLI commands, MCP tools, Python API
|
|
@@ -223,8 +190,6 @@ Sources are scanned into SQLite with bidirectional links connecting local files
|
|
|
223
190
|
|
|
224
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.
|
|
225
192
|
|
|
226
|
-
Connector plugins use an internal API that isn't stable yet — we're not accepting connector contributions at this time.
|
|
227
|
-
|
|
228
193
|
### Development setup
|
|
229
194
|
|
|
230
195
|
```bash
|
|
@@ -7,67 +7,52 @@
|
|
|
7
7
|
|
|
8
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
9
|
|
|
10
|
-
## Prerequisites
|
|
11
|
-
|
|
12
|
-
- **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`.
|
|
13
|
-
- **macOS 13+** or **Linux**.
|
|
14
|
-
- **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.
|
|
15
|
-
|
|
16
10
|
## Install
|
|
17
11
|
|
|
18
|
-
|
|
12
|
+
Requires **Python 3.11+** and **macOS 13+** or **Linux**. The install script checks your Python version and handles the rest:
|
|
19
13
|
|
|
20
14
|
```bash
|
|
21
|
-
# Base install (CLI + MCP + HTTP API)
|
|
22
15
|
curl -fsSL https://raw.githubusercontent.com/harringjohn/footprinter-cli/main/scripts/release/install.sh | bash
|
|
23
|
-
|
|
24
|
-
# Full install (adds semantic search + document parsing)
|
|
25
|
-
curl -fsSL https://raw.githubusercontent.com/harringjohn/footprinter-cli/main/scripts/release/install-full.sh | bash
|
|
26
16
|
```
|
|
27
17
|
|
|
28
|
-
|
|
18
|
+
Or install with **pipx** directly:
|
|
29
19
|
|
|
30
20
|
```bash
|
|
31
|
-
brew install pipx
|
|
32
|
-
pipx ensurepath # then restart your terminal
|
|
33
21
|
pipx install footprinter-cli
|
|
34
|
-
pipx install 'footprinter-cli[full]' # with semantic + parse
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
> **macOS caveats for manual installs:**
|
|
38
|
-
> - **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`.
|
|
39
|
-
> - **System and Homebrew Python** ship with PEP 668 enabled, which blocks bare `pip install` outside a venv. Use pipx (above) instead.
|
|
40
|
-
> - **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.
|
|
41
|
-
|
|
42
|
-
Inside an existing venv, `pip` works as expected:
|
|
43
|
-
|
|
44
|
-
```bash
|
|
45
|
-
./venv/bin/pip install footprinter-cli
|
|
46
|
-
./venv/bin/pip install 'footprinter-cli[full]'
|
|
47
22
|
```
|
|
48
23
|
|
|
49
|
-
|
|
24
|
+
Either method gives you the `fp` command with the indexing pipeline, CLI, MCP server, and HTTP API. Optional extras add more:
|
|
50
25
|
|
|
51
26
|
| Extra | What it adds |
|
|
52
27
|
|-------|-------------|
|
|
53
28
|
| `[semantic]` | Semantic search via ChromaDB + ONNX embeddings |
|
|
54
29
|
| `[parse]` | PDF, Word, Excel, PowerPoint content extraction |
|
|
55
|
-
| `[full]` |
|
|
30
|
+
| `[full]` | Both of the above |
|
|
56
31
|
|
|
57
|
-
|
|
58
|
-
> the ChromaDB client with `anonymized_telemetry=False`, so no telemetry is sent
|
|
59
|
-
> regardless of which version pip resolves. ChromaDB also removed product telemetry
|
|
60
|
-
> entirely in version 1.5.4. See
|
|
61
|
-
> [Chroma OSS overview](https://docs.trychroma.com/docs/overview/oss) for details.
|
|
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]'`.
|
|
62
33
|
|
|
63
|
-
|
|
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).
|
|
64
48
|
|
|
65
|
-
|
|
49
|
+
</details>
|
|
50
|
+
|
|
51
|
+
### Uninstall
|
|
66
52
|
|
|
67
53
|
```bash
|
|
68
|
-
fp uninstall
|
|
69
|
-
pipx uninstall footprinter-cli
|
|
70
|
-
./venv/bin/pip uninstall footprinter-cli # if you installed inside a venv
|
|
54
|
+
fp uninstall # remove MCP entry + user data
|
|
55
|
+
pipx uninstall footprinter-cli # remove the package
|
|
71
56
|
```
|
|
72
57
|
|
|
73
58
|
## Quick Start
|
|
@@ -104,14 +89,12 @@ Once configured, Claude can search your files, browse projects, and find related
|
|
|
104
89
|
| **Local files** | Path, type, size, timestamps, content hash |
|
|
105
90
|
| **Browser history** | Safari and Chrome — URLs, titles, visit times |
|
|
106
91
|
| **Chat exports** | Claude and ChatGPT conversation exports |
|
|
107
|
-
| **Email** | Subject, sender, recipients, body, timestamps
|
|
92
|
+
| **Email** | Subject, sender, recipients, body, timestamps |
|
|
108
93
|
| **Documents** | PDF, Word, Excel, PowerPoint content (with `[parse]` extra) |
|
|
109
94
|
| **Semantic embeddings** | Conceptual similarity across all sources (with `[semantic]` extra) |
|
|
110
95
|
|
|
111
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.
|
|
112
97
|
|
|
113
|
-
Additional sources are available through [connector plugins](#connectors).
|
|
114
|
-
|
|
115
98
|
## CLI Commands
|
|
116
99
|
|
|
117
100
|
All commands use the `fp` entry point.
|
|
@@ -135,30 +118,12 @@ All commands use the `fp` entry point.
|
|
|
135
118
|
|
|
136
119
|
Run `fp <command> --help` for full usage.
|
|
137
120
|
|
|
138
|
-
## Connectors
|
|
139
|
-
|
|
140
|
-
Connector plugins add external data sources like email, cloud storage, and third-party services. They install alongside Footprinter and register automatically:
|
|
141
|
-
|
|
142
|
-
```bash
|
|
143
|
-
pip install footprinter-<name>
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
First-party and community connectors are in development — check the repository for updates.
|
|
147
|
-
|
|
148
|
-
Use `fp connect list` to see available connectors and their status.
|
|
149
|
-
|
|
150
121
|
## Architecture
|
|
151
122
|
|
|
152
123
|
Single-process CLI with optional MCP server. SQLite database. No containers, no cloud, no accounts.
|
|
153
124
|
|
|
154
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.
|
|
155
126
|
|
|
156
|
-
## Requirements
|
|
157
|
-
|
|
158
|
-
- Python 3.11+
|
|
159
|
-
- macOS 13+ or Linux
|
|
160
|
-
- Full Disk Access on macOS (for browser history)
|
|
161
|
-
|
|
162
127
|
## Documentation
|
|
163
128
|
|
|
164
129
|
- [Interfaces](https://github.com/harringjohn/footprinter-cli/blob/main/reference/interfaces.md) — CLI commands, MCP tools, Python API
|
|
@@ -171,8 +136,6 @@ Sources are scanned into SQLite with bidirectional links connecting local files
|
|
|
171
136
|
|
|
172
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.
|
|
173
138
|
|
|
174
|
-
Connector plugins use an internal API that isn't stable yet — we're not accepting connector contributions at this time.
|
|
175
|
-
|
|
176
139
|
### Development setup
|
|
177
140
|
|
|
178
141
|
```bash
|
footprinter_cli-1.0.3/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
|
|
@@ -116,9 +116,9 @@ vectorization:
|
|
|
116
116
|
# ~1000 chars ≈ 250 tokens. Larger chunks get silently truncated by the model,
|
|
117
117
|
# meaning content past the window is invisible to semantic search.
|
|
118
118
|
chunk_size: 1000
|
|
119
|
-
#
|
|
120
|
-
#
|
|
121
|
-
#
|
|
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.
|
|
122
122
|
chunk_overlap: 0.15
|
|
123
123
|
# Patterns (fnmatch syntax) for file paths to skip during vectorization.
|
|
124
124
|
# Matched against the full absolute path (e.g. ~/Work/file.json expands at runtime).
|
|
@@ -88,12 +88,12 @@ def main(argv=None) -> None:
|
|
|
88
88
|
doctor,
|
|
89
89
|
ingest,
|
|
90
90
|
mcp_cmd,
|
|
91
|
-
|
|
91
|
+
search,
|
|
92
92
|
setup,
|
|
93
|
-
|
|
93
|
+
status,
|
|
94
94
|
uninstall,
|
|
95
95
|
upsert,
|
|
96
|
-
|
|
96
|
+
vectorize,
|
|
97
97
|
view,
|
|
98
98
|
)
|
|
99
99
|
|
|
@@ -101,15 +101,15 @@ def main(argv=None) -> None:
|
|
|
101
101
|
ingest,
|
|
102
102
|
mcp_cmd,
|
|
103
103
|
api_cmd,
|
|
104
|
-
|
|
105
|
-
|
|
104
|
+
status,
|
|
105
|
+
search,
|
|
106
106
|
setup,
|
|
107
107
|
connect,
|
|
108
108
|
view,
|
|
109
109
|
upsert,
|
|
110
110
|
data,
|
|
111
111
|
delete,
|
|
112
|
-
|
|
112
|
+
vectorize,
|
|
113
113
|
uninstall,
|
|
114
114
|
doctor,
|
|
115
115
|
]:
|
|
@@ -80,6 +80,10 @@ def connect_db(db_path: Union[str, Path]) -> Optional[sqlite3.Connection]:
|
|
|
80
80
|
def open_db(db_path=None):
|
|
81
81
|
"""Open the Footprinter DB; yields conn, closes on exit.
|
|
82
82
|
|
|
83
|
+
Calls :func:`~footprinter.services.access_service.load_globals` to
|
|
84
|
+
populate the global visibility/permission cache, mirroring the MCP
|
|
85
|
+
layer's ``get_db()``.
|
|
86
|
+
|
|
83
87
|
Exits with code 1 if the database file does not exist.
|
|
84
88
|
"""
|
|
85
89
|
if db_path is None:
|
|
@@ -92,6 +96,7 @@ def open_db(db_path=None):
|
|
|
92
96
|
"[red]Database not found.[/red] Run [bold]fp setup[/bold] then [bold]fp ingest[/bold] to initialize."
|
|
93
97
|
)
|
|
94
98
|
sys.exit(1)
|
|
99
|
+
_access.load_globals(conn)
|
|
95
100
|
try:
|
|
96
101
|
yield conn
|
|
97
102
|
finally:
|
|
@@ -261,8 +266,10 @@ def enrich_verbose_access(
|
|
|
261
266
|
"""Annotate rows in-place with access, access_source, visibility.
|
|
262
267
|
|
|
263
268
|
Uses ``resolve_inherit_visibility`` / ``resolve_inherit_permission``
|
|
264
|
-
so that ``inherit`` values resolve to the global policy
|
|
265
|
-
|
|
269
|
+
so that ``inherit`` values resolve to the global policy. Since
|
|
270
|
+
``open_db()`` calls ``load_globals`` before yielding, ``inherit``
|
|
271
|
+
values resolve to the actual global policy in normal CLI usage.
|
|
272
|
+
The baseline fallback remains as a defence-in-depth measure.
|
|
266
273
|
|
|
267
274
|
Three cases based on the ``mcp_read`` key in each row dict:
|
|
268
275
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"""Shared MCP access-policy helpers used by ``setup.py`` and ``mcp_cmd.py``
|
|
2
|
-
(``fp mcp
|
|
2
|
+
(``fp mcp check/set/reset/bulk``).
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import os
|
|
@@ -7,7 +7,7 @@ import sqlite3
|
|
|
7
7
|
|
|
8
8
|
from rich.table import Table
|
|
9
9
|
|
|
10
|
-
from footprinter.
|
|
10
|
+
from footprinter.access_stamper import (
|
|
11
11
|
count_affected_entities,
|
|
12
12
|
recalculate_access,
|
|
13
13
|
recalculate_access_batched,
|
|
@@ -22,6 +22,7 @@ from footprinter.db.policies import (
|
|
|
22
22
|
set_visibility_policy,
|
|
23
23
|
)
|
|
24
24
|
from footprinter.paths import get_db_path
|
|
25
|
+
from footprinter.utils.paths import abbreviate_home
|
|
25
26
|
|
|
26
27
|
CONFIRM_THRESHOLD = 100
|
|
27
28
|
"""Entity count above which policy changes require interactive confirmation."""
|
|
@@ -105,16 +106,6 @@ def normalize_path(path: str) -> str:
|
|
|
105
106
|
return normalized
|
|
106
107
|
|
|
107
108
|
|
|
108
|
-
def abbreviate_home(path: str) -> str:
|
|
109
|
-
"""Replace ``$HOME`` prefix with ``~`` for display."""
|
|
110
|
-
home = os.path.expanduser("~")
|
|
111
|
-
if path.startswith(home + os.sep):
|
|
112
|
-
return "~" + path[len(home) :]
|
|
113
|
-
elif path == home:
|
|
114
|
-
return "~"
|
|
115
|
-
return path
|
|
116
|
-
|
|
117
|
-
|
|
118
109
|
# ---------------------------------------------------------------------------
|
|
119
110
|
# Single-path check helpers
|
|
120
111
|
# ---------------------------------------------------------------------------
|
|
@@ -99,7 +99,7 @@ def run_vectorization_stage(*, quiet: bool = False) -> None:
|
|
|
99
99
|
trail += f", {skipped_large} too large"
|
|
100
100
|
console.print(f" [green]✓[/green] Deep Read complete: {new} embedded" + trail)
|
|
101
101
|
if skipped_large_files:
|
|
102
|
-
from footprinter.
|
|
102
|
+
from footprinter.utils.paths import abbreviate_home
|
|
103
103
|
|
|
104
104
|
console.print(
|
|
105
105
|
f" [yellow]⚠[/yellow] Skipped {len(skipped_large_files)}"
|
|
@@ -57,7 +57,7 @@ def register(subparsers) -> None:
|
|
|
57
57
|
"Connectors add support for external data sources.\n"
|
|
58
58
|
"Each connector is a separate package.\n\n"
|
|
59
59
|
"No connectors are installed.\n\n"
|
|
60
|
-
"Learn more: https://github.com/
|
|
60
|
+
"Learn more: https://github.com/harringjohn/footprinter-cli"
|
|
61
61
|
)
|
|
62
62
|
return
|
|
63
63
|
_parser.print_help()
|
|
@@ -190,7 +190,7 @@ def _cmd_list(args) -> None:
|
|
|
190
190
|
"No connectors installed.\n\n"
|
|
191
191
|
"Connectors are separate packages that plug into Footprinter's\n"
|
|
192
192
|
"ingest pipeline. To get started, visit:\n"
|
|
193
|
-
" https://github.com/
|
|
193
|
+
" https://github.com/harringjohn/footprinter-cli"
|
|
194
194
|
)
|
|
195
195
|
return
|
|
196
196
|
|
|
@@ -240,7 +240,7 @@ def _cmd_install(args) -> None:
|
|
|
240
240
|
console.print(f" [bold]{spec.name}[/bold] — {spec.description}")
|
|
241
241
|
console.print("\nInstall one: [bold]fp connect install <name>[/bold]")
|
|
242
242
|
else:
|
|
243
|
-
console.print("No connectors available.\n\nLearn more: https://github.com/
|
|
243
|
+
console.print("No connectors available.\n\nLearn more: https://github.com/harringjohn/footprinter-cli")
|
|
244
244
|
return
|
|
245
245
|
spec = connectors.get(name)
|
|
246
246
|
if spec is None:
|