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.
Files changed (175) hide show
  1. {footprinter_cli-1.0.2/footprinter_cli.egg-info → footprinter_cli-1.0.4}/PKG-INFO +44 -79
  2. footprinter_cli-1.0.4/README.md +188 -0
  3. footprinter_cli-1.0.2/footprinter/access.py → footprinter_cli-1.0.4/footprinter/access_stamper.py +63 -21
  4. footprinter_cli-1.0.4/footprinter/api/db.py +38 -0
  5. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/api/server.py +1 -1
  6. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/bundled/config.example.yaml +12 -4
  7. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/__init__.py +7 -8
  8. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/_common.py +9 -2
  9. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/_policy_helpers.py +3 -12
  10. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/_prompt.py +1 -1
  11. footprinter_cli-1.0.4/footprinter/cli/_vectorize_stage.py +117 -0
  12. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/connect.py +3 -3
  13. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/doctor.py +6 -3
  14. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/ingest.py +187 -5
  15. footprinter_cli-1.0.4/footprinter/cli/mcp_cmd.py +469 -0
  16. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/search.py +61 -3
  17. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/setup.py +56 -54
  18. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/status.py +144 -1
  19. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/upsert.py +311 -17
  20. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/connectors/__init__.py +2 -0
  21. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/__init__.py +8 -1
  22. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/browser.py +6 -44
  23. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/chats.py +48 -73
  24. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/clients.py +2 -2
  25. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/emails.py +4 -41
  26. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/files.py +29 -48
  27. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/folders.py +56 -62
  28. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/projects.py +30 -17
  29. footprinter_cli-1.0.4/footprinter/db/protocols.py +16 -0
  30. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/search.py +13 -7
  31. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/sql_utils.py +64 -0
  32. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/status.py +49 -2
  33. footprinter_cli-1.0.2/footprinter/mcp/db.py → footprinter_cli-1.0.4/footprinter/db_base.py +10 -25
  34. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/browser.py +4 -4
  35. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/browser_indexer.py +1 -1
  36. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/chat_indexer.py +0 -2
  37. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/db/schema.py +4 -36
  38. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/file_indexer.py +17 -72
  39. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/file_scanner.py +39 -14
  40. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/folder_indexer.py +2 -3
  41. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/full_content_extractor.py +49 -51
  42. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/orchestrator.py +11 -3
  43. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/pipe_runner.py +0 -7
  44. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/processing.py +140 -2
  45. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/registry.py +2 -2
  46. footprinter_cli-1.0.4/footprinter/ingest/scan_summary.py +78 -0
  47. footprinter_cli-1.0.2/footprinter/ingest/cli.py → footprinter_cli-1.0.4/footprinter/ingest/vector_ops.py +4 -5
  48. footprinter_cli-1.0.4/footprinter/mcp/db.py +34 -0
  49. footprinter_cli-1.0.4/footprinter/mcp/resources/__init__.py +1 -0
  50. footprinter_cli-1.0.4/footprinter/mcp/resources/discoverability.py +59 -0
  51. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/server.py +4 -0
  52. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/tools/navigation.py +3 -10
  53. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/tools/read.py +1 -1
  54. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/tools/search.py +22 -12
  55. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/permissions.py +3 -3
  56. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/semantic/chunking.py +27 -4
  57. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/semantic/hybrid_search.py +3 -8
  58. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/semantic/vector_store.py +29 -9
  59. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/__init__.py +7 -0
  60. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/access_service.py +20 -6
  61. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/content_service.py +15 -5
  62. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/ingest_service.py +3 -5
  63. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/project_service.py +1 -1
  64. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/search_service.py +7 -41
  65. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/source_registry.py +1 -1
  66. footprinter_cli-1.0.4/footprinter/utils/exceptions.py +5 -0
  67. footprinter_cli-1.0.4/footprinter/utils/paths.py +15 -0
  68. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/visibility.py +43 -5
  69. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4/footprinter_cli.egg-info}/PKG-INFO +44 -79
  70. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter_cli.egg-info/SOURCES.txt +12 -8
  71. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/pyproject.toml +3 -1
  72. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_access_control_bypasses.py +6 -6
  73. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_access_control_docs.py +2 -2
  74. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_access_recalculate.py +329 -50
  75. footprinter_cli-1.0.4/tests/test_db_base.py +96 -0
  76. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_edit_recalculate.py +2 -2
  77. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_security_layer.py +0 -1
  78. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_security_permissions.py +2 -2
  79. footprinter_cli-1.0.2/README.md +0 -225
  80. footprinter_cli-1.0.2/footprinter/api/db.py +0 -61
  81. footprinter_cli-1.0.2/footprinter/cli/mcp_cmd.py +0 -750
  82. footprinter_cli-1.0.2/footprinter/cli/search_cmd.py +0 -69
  83. footprinter_cli-1.0.2/footprinter/cli/status_cmd.py +0 -104
  84. footprinter_cli-1.0.2/footprinter/ingest/db/migration.py +0 -371
  85. footprinter_cli-1.0.2/footprinter/ingest/db/security.py +0 -6
  86. footprinter_cli-1.0.2/footprinter/mcp/resources/__init__.py +0 -1
  87. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/LICENSE +0 -0
  88. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/__init__.py +0 -0
  89. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/api/__init__.py +0 -0
  90. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/api/entities.py +0 -0
  91. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/api/search.py +0 -0
  92. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/api/semantic.py +0 -0
  93. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/api/status.py +0 -0
  94. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/bundled/__init__.py +0 -0
  95. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/context_patterns.yaml +0 -0
  96. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/extensions.yaml +0 -0
  97. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/filename_patterns.yaml +0 -0
  98. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/mime_mappings.yaml +0 -0
  99. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/salesforce_rules.yaml +0 -0
  100. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/bundled/patterns/security_patterns.yaml +0 -0
  101. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/__main__.py +0 -0
  102. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/api_cmd.py +0 -0
  103. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/data.py +0 -0
  104. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/delete.py +0 -0
  105. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/mcp_setup.py +0 -0
  106. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/uninstall.py +0 -0
  107. /footprinter_cli-1.0.2/footprinter/cli/vectorize_cmd.py → /footprinter_cli-1.0.4/footprinter/cli/vectorize.py +0 -0
  108. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/cli/view.py +0 -0
  109. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/connectors/config_utils.py +0 -0
  110. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/messages.py +0 -0
  111. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/policies.py +0 -0
  112. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/db/uploads.py +0 -0
  113. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/__init__.py +0 -0
  114. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/__init__.py +0 -0
  115. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/chat.py +0 -0
  116. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/ingest.py +0 -0
  117. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/local_files.py +0 -0
  118. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/local_folders.py +0 -0
  119. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/adapters/protocol.py +0 -0
  120. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/chat_parsers/__init__.py +0 -0
  121. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/chat_parsers/chatgpt_parser.py +0 -0
  122. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/chat_parsers/claude_parser.py +0 -0
  123. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/content_extractors.py +0 -0
  124. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/database.py +0 -0
  125. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/db/__init__.py +0 -0
  126. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/db/connector_schema.py +0 -0
  127. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/run_record.py +0 -0
  128. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/ingest/status.py +0 -0
  129. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/__init__.py +0 -0
  130. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/__main__.py +0 -0
  131. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/errors.py +0 -0
  132. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/resources/context.py +0 -0
  133. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/tools/__init__.py +0 -0
  134. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/tools/semantic.py +0 -0
  135. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/mcp/tools/status.py +0 -0
  136. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/paths.py +0 -0
  137. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/semantic/__init__.py +0 -0
  138. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/semantic/embeddings.py +0 -0
  139. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/chat_service.py +0 -0
  140. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/client_service.py +0 -0
  141. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/email_service.py +0 -0
  142. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/file_service.py +0 -0
  143. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/folder_service.py +0 -0
  144. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/includes.py +0 -0
  145. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/roles.py +0 -0
  146. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/semantic_service.py +0 -0
  147. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/status_service.py +0 -0
  148. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/services/visit_service.py +0 -0
  149. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/utils/__init__.py +0 -0
  150. {footprinter_cli-1.0.2/footprinter/mcp → footprinter_cli-1.0.4/footprinter/utils}/extraction.py +0 -0
  151. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/utils/hash_utils.py +0 -0
  152. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/utils/logging_config.py +0 -0
  153. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/utils/mime.py +0 -0
  154. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/utils/text.py +0 -0
  155. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter/utils/time.py +0 -0
  156. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter_cli.egg-info/dependency_links.txt +0 -0
  157. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter_cli.egg-info/entry_points.txt +0 -0
  158. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter_cli.egg-info/requires.txt +0 -0
  159. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/footprinter_cli.egg-info/top_level.txt +0 -0
  160. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/setup.cfg +0 -0
  161. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_build_status_filter.py +0 -0
  162. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_bundled.py +0 -0
  163. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_e2e_install.py +0 -0
  164. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_e2e_pipeline.py +0 -0
  165. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_examples.py +0 -0
  166. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_files_rename.py +0 -0
  167. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_files_surface.py +0 -0
  168. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_inherit_resolution.py +0 -0
  169. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_logging.py +0 -0
  170. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_no_project_root.py +0 -0
  171. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_package_init.py +0 -0
  172. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_paths_no_test_marker.py +0 -0
  173. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_pip_install_e2e.py +0 -0
  174. {footprinter_cli-1.0.2 → footprinter_cli-1.0.4}/tests/test_prompt_safety.py +0 -0
  175. {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.2
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
- [![Tests](https://github.com/swellcitygroup/footprinter/actions/workflows/test.yml/badge.svg)](https://github.com/swellcitygroup/footprinter/actions/workflows/test.yml)
57
+ [![Tests](https://github.com/harringjohn/footprinter-cli/actions/workflows/test.yml/badge.svg)](https://github.com/harringjohn/footprinter-cli/actions/workflows/test.yml)
56
58
  [![PyPI](https://img.shields.io/pypi/v/footprinter-cli)](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 a filesystem, a browser, an inbox, a chat history, and whatever other tools you reach for. 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
-
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
- The fastest path on a clean machine is the install script it ensures Python 3.11+ is present and installs `footprinter-cli`:
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
- 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
- If you prefer to manage the install yourself, use **pipx** (recommended) — it isolates Footprinter and sidesteps the macOS install caveats noted below:
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
- The base install includes the indexing pipeline, CLI, MCP server, HTTP API, and token encryption. Optional extras add more:
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]` | All optional extras (semantic + parse) |
84
+ | `[full]` | Both of the above |
108
85
 
109
- > **Privacy note:** The `[semantic]` extra installs ChromaDB. Footprinter initializes
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
- ### Uninstall
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
- `fp uninstall` cleans up the MCP entry and user data first, then run the appropriate package uninstall:
103
+ </details>
104
+
105
+ ### Uninstall
118
106
 
119
107
  ```bash
120
- fp uninstall # remove MCP entry + user data
121
- pipx uninstall footprinter-cli # if you installed via pipx
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 — ingested via [connector plugins](#connectors) |
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/swellcitygroup/footprinter/blob/main/reference/content-storage.md) for the full breakdown.
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/swellcitygroup/footprinter/blob/main/reference/interfaces.md) — CLI commands, MCP tools, Python API
217
- - [Data Model](https://github.com/swellcitygroup/footprinter/blob/main/reference/data-model.md) — database schema
218
- - [Pipeline](https://github.com/swellcitygroup/footprinter/blob/main/reference/pipeline.md) — indexing stages and configuration
219
- - [Content Storage](https://github.com/swellcitygroup/footprinter/blob/main/reference/content-storage.md) — metadata vs. snippet vs. full-content tiers
220
- - [Access Control](https://github.com/swellcitygroup/footprinter/blob/main/reference/mcp-access-control.md) — MCP security model
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/swellcitygroup/footprinter/issues) first to discuss the approach.
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/swellcitygroup/footprinter.git
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/swellcitygroup/footprinter/blob/main/SECURITY.md).
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/swellcitygroup/footprinter/blob/main/LICENSE).
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/swellcitygroup/footprinter/blob/main/CODE_OF_CONDUCT.md)
273
- - [Security Policy](https://github.com/swellcitygroup/footprinter/blob/main/SECURITY.md)
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/swellcitygroup/footprinter/blob/main/LICENSE).
242
+ MIT — see [LICENSE](https://github.com/harringjohn/footprinter-cli/blob/main/LICENSE).
@@ -0,0 +1,188 @@
1
+ # Footprinter
2
+
3
+ [![Tests](https://github.com/harringjohn/footprinter-cli/actions/workflows/test.yml/badge.svg)](https://github.com/harringjohn/footprinter-cli/actions/workflows/test.yml)
4
+ [![PyPI](https://img.shields.io/pypi/v/footprinter-cli)](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).
@@ -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
- # folder:{path} → files/folders with matching path prefix
174
- path = os.path.expanduser(value)
175
- # Escape LIKE metacharacters so literal %, _ in paths match correctly
176
- escaped = path.replace("\\", "\\\\").replace("%", "\\%").replace("_", "\\_")
177
- result = {}
178
- for etype in ENTITY_META:
179
- meta = ENTITY_META[etype]
180
- path_col = meta["path_column"]
181
- if path_col is None:
182
- continue
183
- table = meta["table"]
184
- where = f"{path_col} LIKE ? ESCAPE '\\'"
185
- if meta["has_status"]:
186
- where += " AND status = 'listed'"
187
- rows = conn.execute(
188
- f"SELECT id FROM {table} WHERE {where}",
189
- (escaped + "%",),
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
- ids = [r["id"] for r in rows]
192
- if ids:
193
- result[etype] = ids
194
- return result
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
@@ -3,7 +3,7 @@
3
3
  from fastapi import FastAPI, Request
4
4
  from fastapi.responses import JSONResponse
5
5
 
6
- from footprinter.api.db import DatabaseNotInitializedError
6
+ from footprinter.utils.exceptions import DatabaseNotInitializedError
7
7
 
8
8
 
9
9
  def create_app() -> "FastAPI":
@@ -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: 0 # 0 = no size limit (index everything)
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
- # Overlap between consecutive chunks (fraction of chunk_size, 0.0 to 1.0).
112
- # Applies to file vectorization only. Chat message chunking uses a fixed
113
- # character overlap defined in footprinter/semantic/chunking.py.
119
+ # Fractional overlap between consecutive chunks (0.01.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
- search_cmd,
91
+ search,
93
92
  setup,
94
- status_cmd,
93
+ status,
95
94
  uninstall,
96
95
  upsert,
97
- vectorize_cmd,
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
- status_cmd,
106
- search_cmd,
104
+ status,
105
+ search,
107
106
  setup,
108
107
  connect,
109
108
  view,
110
109
  upsert,
111
110
  data,
112
111
  delete,
113
- vectorize_cmd,
112
+ vectorize,
114
113
  uninstall,
115
114
  doctor,
116
115
  ]: