footprinter-cli 1.0.0rc1__py3-none-any.whl

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 (138) hide show
  1. footprinter/__init__.py +8 -0
  2. footprinter/access.py +431 -0
  3. footprinter/api/__init__.py +1 -0
  4. footprinter/api/db.py +61 -0
  5. footprinter/api/entities.py +250 -0
  6. footprinter/api/search.py +47 -0
  7. footprinter/api/semantic.py +33 -0
  8. footprinter/api/server.py +66 -0
  9. footprinter/api/status.py +15 -0
  10. footprinter/bundled/__init__.py +0 -0
  11. footprinter/bundled/config.example.yaml +161 -0
  12. footprinter/bundled/patterns/context_patterns.yaml +18 -0
  13. footprinter/bundled/patterns/extensions.yaml +283 -0
  14. footprinter/bundled/patterns/filename_patterns.yaml +61 -0
  15. footprinter/bundled/patterns/mime_mappings.yaml +68 -0
  16. footprinter/bundled/patterns/salesforce_rules.yaml +84 -0
  17. footprinter/bundled/patterns/security_patterns.yaml +27 -0
  18. footprinter/bundled/samples/hidden-client-file-sample.txt +2 -0
  19. footprinter/bundled/samples/opaque-project-file-sample.txt +2 -0
  20. footprinter/bundled/samples/visible-file-sample.txt +2 -0
  21. footprinter/cli/__init__.py +135 -0
  22. footprinter/cli/__main__.py +6 -0
  23. footprinter/cli/_common.py +327 -0
  24. footprinter/cli/_policy_helpers.py +646 -0
  25. footprinter/cli/_prompt.py +220 -0
  26. footprinter/cli/_sample_seed.py +204 -0
  27. footprinter/cli/api_cmd.py +32 -0
  28. footprinter/cli/connect.py +591 -0
  29. footprinter/cli/data.py +879 -0
  30. footprinter/cli/delete.py +128 -0
  31. footprinter/cli/ingest.py +543 -0
  32. footprinter/cli/mcp_cmd.py +750 -0
  33. footprinter/cli/mcp_setup.py +306 -0
  34. footprinter/cli/search.py +393 -0
  35. footprinter/cli/search_cmd.py +69 -0
  36. footprinter/cli/setup.py +2001 -0
  37. footprinter/cli/status.py +747 -0
  38. footprinter/cli/status_cmd.py +104 -0
  39. footprinter/cli/upsert.py +794 -0
  40. footprinter/cli/vectorize_cmd.py +215 -0
  41. footprinter/cli/view.py +322 -0
  42. footprinter/connectors/__init__.py +171 -0
  43. footprinter/connectors/config_utils.py +141 -0
  44. footprinter/db/__init__.py +37 -0
  45. footprinter/db/browser.py +198 -0
  46. footprinter/db/chats.py +602 -0
  47. footprinter/db/clients.py +307 -0
  48. footprinter/db/emails.py +279 -0
  49. footprinter/db/files.py +724 -0
  50. footprinter/db/folders.py +659 -0
  51. footprinter/db/messages.py +192 -0
  52. footprinter/db/policies.py +151 -0
  53. footprinter/db/projects.py +673 -0
  54. footprinter/db/search.py +573 -0
  55. footprinter/db/sql_utils.py +168 -0
  56. footprinter/db/status.py +320 -0
  57. footprinter/db/uploads.py +70 -0
  58. footprinter/ingest/__init__.py +0 -0
  59. footprinter/ingest/adapters/__init__.py +33 -0
  60. footprinter/ingest/adapters/browser.py +54 -0
  61. footprinter/ingest/adapters/chat.py +57 -0
  62. footprinter/ingest/adapters/ingest.py +146 -0
  63. footprinter/ingest/adapters/local_files.py +68 -0
  64. footprinter/ingest/adapters/local_folders.py +52 -0
  65. footprinter/ingest/adapters/protocol.py +174 -0
  66. footprinter/ingest/browser_indexer.py +216 -0
  67. footprinter/ingest/chat_dedup.py +156 -0
  68. footprinter/ingest/chat_indexer.py +487 -0
  69. footprinter/ingest/chat_parsers/__init__.py +8 -0
  70. footprinter/ingest/chat_parsers/chatgpt_parser.py +229 -0
  71. footprinter/ingest/chat_parsers/claude_parser.py +161 -0
  72. footprinter/ingest/cli.py +827 -0
  73. footprinter/ingest/content_extractors.py +117 -0
  74. footprinter/ingest/database.py +36 -0
  75. footprinter/ingest/db/__init__.py +1 -0
  76. footprinter/ingest/db/connector_schema.py +47 -0
  77. footprinter/ingest/db/migration.py +315 -0
  78. footprinter/ingest/db/schema.py +1043 -0
  79. footprinter/ingest/db/security.py +6 -0
  80. footprinter/ingest/file_indexer.py +223 -0
  81. footprinter/ingest/file_scanner.py +277 -0
  82. footprinter/ingest/folder_indexer.py +226 -0
  83. footprinter/ingest/full_content_extractor.py +321 -0
  84. footprinter/ingest/orchestrator.py +112 -0
  85. footprinter/ingest/pipe_runner.py +200 -0
  86. footprinter/ingest/processing.py +165 -0
  87. footprinter/ingest/registry.py +186 -0
  88. footprinter/ingest/run_record.py +91 -0
  89. footprinter/ingest/status.py +346 -0
  90. footprinter/mcp/__init__.py +0 -0
  91. footprinter/mcp/__main__.py +5 -0
  92. footprinter/mcp/db.py +67 -0
  93. footprinter/mcp/errors.py +105 -0
  94. footprinter/mcp/extraction.py +226 -0
  95. footprinter/mcp/server.py +39 -0
  96. footprinter/mcp/tools/__init__.py +0 -0
  97. footprinter/mcp/tools/navigation.py +70 -0
  98. footprinter/mcp/tools/read.py +75 -0
  99. footprinter/mcp/tools/search.py +158 -0
  100. footprinter/mcp/tools/semantic.py +79 -0
  101. footprinter/mcp/tools/status.py +19 -0
  102. footprinter/paths.py +117 -0
  103. footprinter/permissions.py +1152 -0
  104. footprinter/semantic/__init__.py +13 -0
  105. footprinter/semantic/chunking.py +52 -0
  106. footprinter/semantic/embeddings.py +23 -0
  107. footprinter/semantic/hybrid_search.py +273 -0
  108. footprinter/semantic/vector_store.py +471 -0
  109. footprinter/services/__init__.py +49 -0
  110. footprinter/services/access_service.py +342 -0
  111. footprinter/services/chat_service.py +85 -0
  112. footprinter/services/client_service.py +267 -0
  113. footprinter/services/content_service.py +181 -0
  114. footprinter/services/email_service.py +89 -0
  115. footprinter/services/file_service.py +83 -0
  116. footprinter/services/folder_service.py +122 -0
  117. footprinter/services/includes.py +19 -0
  118. footprinter/services/ingest_service.py +231 -0
  119. footprinter/services/project_service.py +262 -0
  120. footprinter/services/roles.py +25 -0
  121. footprinter/services/search_service.py +177 -0
  122. footprinter/services/semantic_service.py +360 -0
  123. footprinter/services/status_service.py +18 -0
  124. footprinter/services/visit_service.py +65 -0
  125. footprinter/source_registry.py +194 -0
  126. footprinter/utils/__init__.py +7 -0
  127. footprinter/utils/hash_utils.py +59 -0
  128. footprinter/utils/logging_config.py +68 -0
  129. footprinter/utils/mime.py +30 -0
  130. footprinter/utils/text.py +6 -0
  131. footprinter/utils/time.py +11 -0
  132. footprinter/visibility.py +1264 -0
  133. footprinter_cli-1.0.0rc1.dist-info/LICENSE +21 -0
  134. footprinter_cli-1.0.0rc1.dist-info/METADATA +223 -0
  135. footprinter_cli-1.0.0rc1.dist-info/RECORD +138 -0
  136. footprinter_cli-1.0.0rc1.dist-info/WHEEL +5 -0
  137. footprinter_cli-1.0.0rc1.dist-info/entry_points.txt +2 -0
  138. footprinter_cli-1.0.0rc1.dist-info/top_level.txt +1 -0
footprinter/paths.py ADDED
@@ -0,0 +1,117 @@
1
+ """Single source-of-truth path resolution for Footprinter.
2
+
3
+ Defaults to ``~/.footprinter/`` (installable-package compatible).
4
+ Every path can be overridden via environment variable.
5
+ """
6
+
7
+ import importlib.resources
8
+ import logging
9
+ import os
10
+ from pathlib import Path
11
+
12
+ _TEST_MARKER_NAME = ".test-active"
13
+ _TEST_ENV_NAME = ".test-env"
14
+
15
+
16
+ def get_home() -> Path:
17
+ """Return FOOTPRINTER_HOME, creating it if needed.
18
+
19
+ Priority: FOOTPRINTER_HOME env var > test-mode marker > default.
20
+ """
21
+ override = os.environ.get("FOOTPRINTER_HOME")
22
+ if override:
23
+ home = Path(override)
24
+ else:
25
+ real_home = Path.home() / ".footprinter"
26
+ marker = real_home / _TEST_MARKER_NAME
27
+ if marker.is_file():
28
+ home = Path(marker.read_text().strip())
29
+ else:
30
+ home = real_home
31
+ home.mkdir(parents=True, exist_ok=True)
32
+ return home
33
+
34
+
35
+ def get_real_home() -> Path:
36
+ """Return ``~/.footprinter/`` unconditionally (ignores env var and marker)."""
37
+ home = Path.home() / ".footprinter"
38
+ home.mkdir(parents=True, exist_ok=True)
39
+ return home
40
+
41
+
42
+ def is_test_mode() -> bool:
43
+ """Return True if the test-mode marker exists and no env var override is set."""
44
+ if os.environ.get("FOOTPRINTER_HOME"):
45
+ return False
46
+ marker = Path.home() / ".footprinter" / _TEST_MARKER_NAME
47
+ return marker.is_file()
48
+
49
+
50
+ def get_config_path() -> Path:
51
+ """Return the config file path. Respects FOOTPRINTER_CONFIG env var."""
52
+ env = os.environ.get("FOOTPRINTER_CONFIG")
53
+ return Path(env) if env else get_home() / "config.yaml"
54
+
55
+
56
+ def get_db_path() -> Path:
57
+ """Return the database path, creating the parent dir. Respects FOOTPRINTER_DB_PATH env var."""
58
+ env = os.environ.get("FOOTPRINTER_DB_PATH")
59
+ path = Path(env) if env else get_home() / "footprinter.db"
60
+ path.parent.mkdir(parents=True, exist_ok=True)
61
+ return path
62
+
63
+
64
+ def get_chroma_path() -> Path:
65
+ """Return the ChromaDB storage path."""
66
+ return get_home() / "chroma"
67
+
68
+
69
+ def get_log_path() -> Path:
70
+ """Return the setup log path."""
71
+ return get_home() / "setup.log"
72
+
73
+
74
+ def get_run_logs_dir() -> Path:
75
+ """Return the run logs directory (~/.footprinter/logs/), creating it if needed."""
76
+ d = get_home() / "logs"
77
+ d.mkdir(parents=True, exist_ok=True)
78
+ return d
79
+
80
+
81
+ def prune_run_logs(keep: int = 20) -> int:
82
+ """Remove old run log files, keeping the *keep* most recent.
83
+
84
+ Only targets ``run_*.log`` files. Returns the number of files removed.
85
+ """
86
+ log_dir = get_run_logs_dir()
87
+ logs = sorted(log_dir.glob("run_*.log"))
88
+ to_remove = logs[: max(0, len(logs) - keep)]
89
+ for path in to_remove:
90
+ path.unlink()
91
+ if to_remove:
92
+ logging.getLogger("footprinter").debug(
93
+ "Pruned %d old run log(s) from %s",
94
+ len(to_remove),
95
+ log_dir,
96
+ )
97
+ return len(to_remove)
98
+
99
+
100
+ def get_last_run_path() -> Path:
101
+ """Return the path to the last run record (~/.footprinter/last_run.json)."""
102
+ return get_home() / "last_run.json"
103
+
104
+
105
+ def get_run_lock_path() -> Path:
106
+ """Return the path to the run lockfile (~/.footprinter/run.lock)."""
107
+ return get_home() / "run.lock"
108
+
109
+
110
+ def get_bundled_path(name: str) -> Path:
111
+ """Return path to a bundled resource file shipped with the package."""
112
+ return importlib.resources.files("footprinter.bundled") / name
113
+
114
+
115
+ def get_bundled_patterns_dir() -> Path:
116
+ """Return path to the bundled patterns directory."""
117
+ return importlib.resources.files("footprinter.bundled") / "patterns"