griot-rag 0.2.0__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.
- griot_rag-0.2.0/LICENSE +190 -0
- griot_rag-0.2.0/PKG-INFO +295 -0
- griot_rag-0.2.0/README.md +250 -0
- griot_rag-0.2.0/pyproject.toml +119 -0
- griot_rag-0.2.0/setup.cfg +4 -0
- griot_rag-0.2.0/src/griot/__init__.py +42 -0
- griot_rag-0.2.0/src/griot/ask.py +79 -0
- griot_rag-0.2.0/src/griot/auth.py +287 -0
- griot_rag-0.2.0/src/griot/cli.py +699 -0
- griot_rag-0.2.0/src/griot/common.py +3355 -0
- griot_rag-0.2.0/src/griot/config.py +600 -0
- griot_rag-0.2.0/src/griot/doctor.py +400 -0
- griot_rag-0.2.0/src/griot/freshness.py +210 -0
- griot_rag-0.2.0/src/griot/golden_set.py +421 -0
- griot_rag-0.2.0/src/griot/harnesses.py +1232 -0
- griot_rag-0.2.0/src/griot/index_branches.py +268 -0
- griot_rag-0.2.0/src/griot/index_code.py +304 -0
- griot_rag-0.2.0/src/griot/index_commits.py +169 -0
- griot_rag-0.2.0/src/griot/index_platform.py +212 -0
- griot_rag-0.2.0/src/griot/index_tags.py +190 -0
- griot_rag-0.2.0/src/griot/jobs.py +520 -0
- griot_rag-0.2.0/src/griot/logdb.py +580 -0
- griot_rag-0.2.0/src/griot/mcp_server.py +2473 -0
- griot_rag-0.2.0/src/griot/platforms.py +702 -0
- griot_rag-0.2.0/src/griot/quality_check.py +331 -0
- griot_rag-0.2.0/src/griot/redaction.py +338 -0
- griot_rag-0.2.0/src/griot/repos.py +202 -0
- griot_rag-0.2.0/src/griot/resources/agents/claude-code/griot-setup-assistant.md +134 -0
- griot_rag-0.2.0/src/griot/resources/agents/opencode/griot-setup-assistant.md +135 -0
- griot_rag-0.2.0/src/griot/resources/instructions/claude-code.md +3 -0
- griot_rag-0.2.0/src/griot/resources/skills/griot-indexing/SKILL.md +195 -0
- griot_rag-0.2.0/src/griot/resources/skills/griot-onboarding/SKILL.md +158 -0
- griot_rag-0.2.0/src/griot/resources/skills/griot-operations/SKILL.md +216 -0
- griot_rag-0.2.0/src/griot/resources/skills/griot-troubleshooting/SKILL.md +167 -0
- griot_rag-0.2.0/src/griot/resources/skills/griot-workflows/SKILL.md +144 -0
- griot_rag-0.2.0/src/griot/retrieval_eval.py +230 -0
- griot_rag-0.2.0/src/griot/stats.py +827 -0
- griot_rag-0.2.0/src/griot_rag.egg-info/PKG-INFO +295 -0
- griot_rag-0.2.0/src/griot_rag.egg-info/SOURCES.txt +125 -0
- griot_rag-0.2.0/src/griot_rag.egg-info/dependency_links.txt +1 -0
- griot_rag-0.2.0/src/griot_rag.egg-info/entry_points.txt +2 -0
- griot_rag-0.2.0/src/griot_rag.egg-info/requires.txt +21 -0
- griot_rag-0.2.0/src/griot_rag.egg-info/top_level.txt +1 -0
- griot_rag-0.2.0/tests/test_ask.py +135 -0
- griot_rag-0.2.0/tests/test_audit_history.py +465 -0
- griot_rag-0.2.0/tests/test_audit_tool.py +323 -0
- griot_rag-0.2.0/tests/test_auth.py +361 -0
- griot_rag-0.2.0/tests/test_batch_sizes.py +243 -0
- griot_rag-0.2.0/tests/test_branches_few_git_calls.py +437 -0
- griot_rag-0.2.0/tests/test_bundled_skills.py +36 -0
- griot_rag-0.2.0/tests/test_chat_profiles.py +175 -0
- griot_rag-0.2.0/tests/test_chunk_text.py +63 -0
- griot_rag-0.2.0/tests/test_claude_config_dir.py +285 -0
- griot_rag-0.2.0/tests/test_cli.py +591 -0
- griot_rag-0.2.0/tests/test_cli_confirm.py +281 -0
- griot_rag-0.2.0/tests/test_cli_hints.py +139 -0
- griot_rag-0.2.0/tests/test_cli_search_filters.py +150 -0
- griot_rag-0.2.0/tests/test_client_release_race.py +252 -0
- griot_rag-0.2.0/tests/test_config_command.py +568 -0
- griot_rag-0.2.0/tests/test_config_dirs.py +219 -0
- griot_rag-0.2.0/tests/test_config_tool.py +288 -0
- griot_rag-0.2.0/tests/test_confirmation.py +359 -0
- griot_rag-0.2.0/tests/test_confirmation_copy.py +155 -0
- griot_rag-0.2.0/tests/test_correctness_fixes.py +451 -0
- griot_rag-0.2.0/tests/test_discovery_rules.py +311 -0
- griot_rag-0.2.0/tests/test_doctor.py +518 -0
- griot_rag-0.2.0/tests/test_embed_batching.py +115 -0
- griot_rag-0.2.0/tests/test_env_template.py +217 -0
- griot_rag-0.2.0/tests/test_gemini_direct.py +149 -0
- griot_rag-0.2.0/tests/test_git_control_characters.py +159 -0
- griot_rag-0.2.0/tests/test_git_hardening.py +234 -0
- griot_rag-0.2.0/tests/test_git_hooks.py +378 -0
- griot_rag-0.2.0/tests/test_git_hooks_every_route.py +947 -0
- griot_rag-0.2.0/tests/test_golden_set.py +400 -0
- griot_rag-0.2.0/tests/test_golden_set_suggest.py +238 -0
- griot_rag-0.2.0/tests/test_golden_set_suggest_tool.py +324 -0
- griot_rag-0.2.0/tests/test_harnesses.py +668 -0
- griot_rag-0.2.0/tests/test_http_connection_reuse.py +310 -0
- griot_rag-0.2.0/tests/test_index_branches.py +165 -0
- griot_rag-0.2.0/tests/test_index_commits.py +142 -0
- griot_rag-0.2.0/tests/test_index_platform.py +106 -0
- griot_rag-0.2.0/tests/test_index_preview.py +312 -0
- griot_rag-0.2.0/tests/test_index_status.py +359 -0
- griot_rag-0.2.0/tests/test_index_tags.py +136 -0
- griot_rag-0.2.0/tests/test_indexer_discover.py +113 -0
- griot_rag-0.2.0/tests/test_indexing.py +838 -0
- griot_rag-0.2.0/tests/test_install_flow.py +490 -0
- griot_rag-0.2.0/tests/test_jobs.py +464 -0
- griot_rag-0.2.0/tests/test_keychain.py +238 -0
- griot_rag-0.2.0/tests/test_lazy_embedding_import.py +50 -0
- griot_rag-0.2.0/tests/test_lock.py +123 -0
- griot_rag-0.2.0/tests/test_logdb.py +551 -0
- griot_rag-0.2.0/tests/test_mcp_environment_only_narrows.py +602 -0
- griot_rag-0.2.0/tests/test_mcp_output_types_on_the_oldest_python.py +101 -0
- griot_rag-0.2.0/tests/test_mcp_registration.py +396 -0
- griot_rag-0.2.0/tests/test_mcp_server.py +2498 -0
- griot_rag-0.2.0/tests/test_openai_compatible.py +145 -0
- griot_rag-0.2.0/tests/test_orphans.py +602 -0
- griot_rag-0.2.0/tests/test_platform_hardening.py +278 -0
- griot_rag-0.2.0/tests/test_platforms.py +411 -0
- griot_rag-0.2.0/tests/test_private_directories.py +192 -0
- griot_rag-0.2.0/tests/test_profiles.py +312 -0
- griot_rag-0.2.0/tests/test_profiles_use.py +265 -0
- griot_rag-0.2.0/tests/test_project_name.py +300 -0
- griot_rag-0.2.0/tests/test_quality_check.py +359 -0
- griot_rag-0.2.0/tests/test_quality_check_golden_set.py +363 -0
- griot_rag-0.2.0/tests/test_redaction.py +357 -0
- griot_rag-0.2.0/tests/test_redaction_wiring.py +444 -0
- griot_rag-0.2.0/tests/test_release.py +176 -0
- griot_rag-0.2.0/tests/test_repos.py +321 -0
- griot_rag-0.2.0/tests/test_repository_freshness.py +631 -0
- griot_rag-0.2.0/tests/test_retrieval_eval.py +278 -0
- griot_rag-0.2.0/tests/test_search_filters.py +269 -0
- griot_rag-0.2.0/tests/test_search_grouping.py +120 -0
- griot_rag-0.2.0/tests/test_search_results.py +294 -0
- griot_rag-0.2.0/tests/test_secret_leaks.py +105 -0
- griot_rag-0.2.0/tests/test_secure_files.py +167 -0
- griot_rag-0.2.0/tests/test_security_hardening.py +442 -0
- griot_rag-0.2.0/tests/test_server_instructions.py +136 -0
- griot_rag-0.2.0/tests/test_spend_circuit_breaker.py +134 -0
- griot_rag-0.2.0/tests/test_spend_without_usage.py +232 -0
- griot_rag-0.2.0/tests/test_stable_id.py +18 -0
- griot_rag-0.2.0/tests/test_stats.py +881 -0
- griot_rag-0.2.0/tests/test_stats_state.py +457 -0
- griot_rag-0.2.0/tests/test_supply_chain.py +248 -0
- griot_rag-0.2.0/tests/test_tag_chunks_and_hash.py +311 -0
- griot_rag-0.2.0/tests/test_tool_approval.py +565 -0
griot_rag-0.2.0/LICENSE
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
Apache License
|
|
2
|
+
Version 2.0, January 2004
|
|
3
|
+
http://www.apache.org/licenses/
|
|
4
|
+
|
|
5
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
6
|
+
|
|
7
|
+
1. Definitions.
|
|
8
|
+
|
|
9
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
10
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
11
|
+
|
|
12
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
13
|
+
the copyright owner that is granting the License.
|
|
14
|
+
|
|
15
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
16
|
+
other entities that control, are controlled by, or are under common
|
|
17
|
+
control with that entity. For the purposes of this definition,
|
|
18
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
19
|
+
direction or management of such entity, whether by contract or
|
|
20
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
21
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
22
|
+
|
|
23
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
24
|
+
exercising permissions granted by this License.
|
|
25
|
+
|
|
26
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
27
|
+
including but not limited to software source code, documentation
|
|
28
|
+
source, and configuration files.
|
|
29
|
+
|
|
30
|
+
"Object" form shall mean any form resulting from mechanical
|
|
31
|
+
transformation or translation of a Source form, including but
|
|
32
|
+
not limited to compiled object code, generated documentation,
|
|
33
|
+
and conversions to other media types.
|
|
34
|
+
|
|
35
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
36
|
+
Object form, made available under the License, as indicated by a
|
|
37
|
+
copyright notice that is included in or attached to the work
|
|
38
|
+
(an example is provided in the Appendix below).
|
|
39
|
+
|
|
40
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
41
|
+
form, that is based on (or derived from) the Work and for which the
|
|
42
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
43
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
44
|
+
of this License, Derivative Works shall not include works that remain
|
|
45
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
46
|
+
the Work and Derivative Works thereof.
|
|
47
|
+
|
|
48
|
+
"Contribution" shall mean any work of authorship, including
|
|
49
|
+
the original version of the Work and any modifications or additions
|
|
50
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
51
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
52
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
53
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
54
|
+
means any form of electronic, verbal, or written communication sent
|
|
55
|
+
to the Licensor or its representatives, including but not limited to
|
|
56
|
+
communication on electronic mailing lists, source code control systems,
|
|
57
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
58
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
59
|
+
excluding communication that is conspicuously marked or otherwise
|
|
60
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
61
|
+
|
|
62
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
63
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
64
|
+
subsequently incorporated within the Work.
|
|
65
|
+
|
|
66
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
67
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
68
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
69
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
70
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
71
|
+
Work and such Derivative Works in Source or Object form.
|
|
72
|
+
|
|
73
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
74
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
75
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
76
|
+
(except as stated in this section) patent license to make, have made,
|
|
77
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
78
|
+
where such license applies only to those patent claims licensable
|
|
79
|
+
by such Contributor that are necessarily infringed by their
|
|
80
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
81
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
82
|
+
institute patent litigation against any entity (including a
|
|
83
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
84
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
85
|
+
or contributory patent infringement, then any patent licenses
|
|
86
|
+
granted to You under this License for that Work shall terminate
|
|
87
|
+
as of the date such litigation is filed.
|
|
88
|
+
|
|
89
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
90
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
91
|
+
modifications, and in Source or Object form, provided that You
|
|
92
|
+
meet the following conditions:
|
|
93
|
+
|
|
94
|
+
(a) You must give any other recipients of the Work or
|
|
95
|
+
Derivative Works a copy of this License; and
|
|
96
|
+
|
|
97
|
+
(b) You must cause any modified files to carry prominent notices
|
|
98
|
+
stating that You changed the files; and
|
|
99
|
+
|
|
100
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
101
|
+
that You distribute, all copyright, patent, trademark, and
|
|
102
|
+
attribution notices from the Source form of the Work,
|
|
103
|
+
excluding those notices that do not pertain to any part of
|
|
104
|
+
the Derivative Works; and
|
|
105
|
+
|
|
106
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
107
|
+
distribution, then any Derivative Works that You distribute must
|
|
108
|
+
include a readable copy of the attribution notices contained
|
|
109
|
+
within such NOTICE file, excluding those notices that do not
|
|
110
|
+
pertain to any part of the Derivative Works, in at least one
|
|
111
|
+
of the following places: within a NOTICE text file distributed
|
|
112
|
+
as part of the Derivative Works; within the Source form or
|
|
113
|
+
documentation, if provided along with the Derivative Works; or,
|
|
114
|
+
within a display generated by the Derivative Works, if and
|
|
115
|
+
wherever such third-party notices normally appear. The contents
|
|
116
|
+
of the NOTICE file are for informational purposes only and
|
|
117
|
+
do not modify the License. You may add Your own attribution
|
|
118
|
+
notices within Derivative Works that You distribute, alongside
|
|
119
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
120
|
+
that such additional attribution notices cannot be construed
|
|
121
|
+
as modifying the License.
|
|
122
|
+
|
|
123
|
+
You may add Your own copyright statement to Your modifications and
|
|
124
|
+
may provide additional or different license terms and conditions
|
|
125
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
126
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
127
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
128
|
+
the conditions stated in this License.
|
|
129
|
+
|
|
130
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
131
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
132
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
133
|
+
this License, without any additional terms or conditions.
|
|
134
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
135
|
+
the terms of any separate license agreement you may have executed
|
|
136
|
+
with Licensor regarding such Contributions.
|
|
137
|
+
|
|
138
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
139
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
140
|
+
except as required for reasonable and customary use in describing the
|
|
141
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
142
|
+
|
|
143
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
144
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
145
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
146
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
147
|
+
implied, including, without limitation, any warranties or conditions
|
|
148
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
149
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
150
|
+
appropriateness of using or redistributing the Work and assume any
|
|
151
|
+
risks associated with Your exercise of permissions under this License.
|
|
152
|
+
|
|
153
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
154
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
155
|
+
unless required by applicable law (such as deliberate and grossly
|
|
156
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
157
|
+
liable to You for damages, including any direct, indirect, special,
|
|
158
|
+
incidental, or consequential damages of any character arising as a
|
|
159
|
+
result of this License or out of the use or inability to use the
|
|
160
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
161
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
162
|
+
other commercial damages or losses), even if such Contributor
|
|
163
|
+
has been advised of the possibility of such damages.
|
|
164
|
+
|
|
165
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
166
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
167
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
168
|
+
or other liability obligations and/or rights consistent with this
|
|
169
|
+
License. However, in accepting such obligations, You may act only
|
|
170
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
171
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
172
|
+
defend, and hold each Contributor harmless for any liability
|
|
173
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
174
|
+
of your accepting any such warranty or additional liability.
|
|
175
|
+
|
|
176
|
+
END OF TERMS AND CONDITIONS
|
|
177
|
+
|
|
178
|
+
Copyright 2026 johnt1000
|
|
179
|
+
|
|
180
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
181
|
+
you may not use this file except in compliance with the License.
|
|
182
|
+
You may obtain a copy of the License at
|
|
183
|
+
|
|
184
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
185
|
+
|
|
186
|
+
Unless required by applicable law or agreed to in writing, software
|
|
187
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
188
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
189
|
+
See the License for the specific language governing permissions and
|
|
190
|
+
limitations under the License.
|
griot_rag-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,295 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: griot-rag
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Local-first RAG over your git repositories — index code, git history and platform data (PRs/issues/releases) into an embedded vector store, search it and ask questions from the CLI or via MCP
|
|
5
|
+
Author: johnt1000
|
|
6
|
+
License-Expression: Apache-2.0
|
|
7
|
+
Project-URL: Homepage, https://github.com/johnt1000/griot
|
|
8
|
+
Project-URL: Repository, https://github.com/johnt1000/griot
|
|
9
|
+
Project-URL: Issues, https://github.com/johnt1000/griot/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/johnt1000/griot/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: rag,vector-search,git,mcp,mcp-server,claude-code,code-search,semantic-search,local-first,developer-tools,qdrant,embeddings
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Operating System :: MacOS
|
|
16
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Topic :: Software Development :: Version Control :: Git
|
|
23
|
+
Classifier: Topic :: Text Processing :: Indexing
|
|
24
|
+
Requires-Python: >=3.10
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Dist: requests
|
|
28
|
+
Requires-Dist: tqdm
|
|
29
|
+
Requires-Dist: python-dotenv
|
|
30
|
+
Requires-Dist: qdrant-client[fastembed]
|
|
31
|
+
Requires-Dist: psutil
|
|
32
|
+
Requires-Dist: qdrant-edge-py<0.9,>=0.8.0
|
|
33
|
+
Requires-Dist: mcp<3,>=2.0.0
|
|
34
|
+
Requires-Dist: typing-extensions>=4.6
|
|
35
|
+
Requires-Dist: pydantic>=2
|
|
36
|
+
Requires-Dist: anyio
|
|
37
|
+
Provides-Extra: dev
|
|
38
|
+
Requires-Dist: pytest; extra == "dev"
|
|
39
|
+
Requires-Dist: packaging; extra == "dev"
|
|
40
|
+
Requires-Dist: pyyaml; extra == "dev"
|
|
41
|
+
Requires-Dist: tomli; python_version < "3.11" and extra == "dev"
|
|
42
|
+
Provides-Extra: keychain
|
|
43
|
+
Requires-Dist: keyring>=24; extra == "keychain"
|
|
44
|
+
Dynamic: license-file
|
|
45
|
+
|
|
46
|
+
# griot
|
|
47
|
+
|
|
48
|
+
[](https://github.com/johnt1000/griot/actions/workflows/ci.yml)
|
|
49
|
+
|
|
50
|
+
Local-first RAG over your git repositories. griot indexes source code, git history (commits, tags, branches) and code-platform data (PRs/MRs, releases, issues) into an **embedded** vector store — no database server, no Docker — and lets you search it or ask questions about it, from the CLI or from an AI agent via [MCP](https://modelcontextprotocol.io/).
|
|
51
|
+
|
|
52
|
+
Named after the West African storyteller who keeps a community's history: griot remembers what your repositories have been through.
|
|
53
|
+
|
|
54
|
+
## Highlights
|
|
55
|
+
|
|
56
|
+
- **Fully local storage** — vectors live in an in-process [Qdrant Edge](https://qdrant.tech/edge/) shard under your XDG data dir. No services to run.
|
|
57
|
+
- **Free by default** — the default embedding profile (`jina-code`) runs locally via ONNX. Paid profiles (OpenAI, Gemini) are opt-in.
|
|
58
|
+
- **Spend circuit breaker** — daily ceiling + 5-minute velocity ceiling on every paid call, with atomic on-disk state. The `openai` and `deepseek` chat profiles refuse to run until you set their price (`griot config set openai-chat-price <USD per 1M tokens>`, or `deepseek-chat-price`), so the breaker always tracks real cost.
|
|
59
|
+
- **Five platforms** — GitHub, GitLab (incl. self-hosted), Bitbucket Cloud, Azure DevOps and Gitea/Forgejo adapters for PRs/releases/issues, detected from each repo's `origin` remote. These are built against each provider's documented API and covered by tests with mocked HTTP; only the GitHub path has been exercised against a live account.
|
|
60
|
+
- **MCP server** — expose search/status/quality tools to Claude Code, opencode or any MCP client. Indexing via agent is off by default and path-allowlisted.
|
|
61
|
+
- **Security-hardened** — API keys never in URLs or logs, 0600/0700 file modes on everything it writes, no credential ever follows a redirect. See [SECURITY.md](SECURITY.md).
|
|
62
|
+
|
|
63
|
+
**Status:** v0.2.0, beta. One maintainer, used daily by its author. The CLI surface and the on-disk layout may still change between 0.x releases.
|
|
64
|
+
|
|
65
|
+
## Installation
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pipx install griot-rag # the distribution is griot-rag; the command is griot
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Or from a checkout: `git clone https://github.com/johnt1000/griot && cd griot && pipx install .` (`pipx install -e .` for an editable install).
|
|
72
|
+
|
|
73
|
+
Requires Python ≥ 3.10 and `git`. **The first run of a local profile downloads its ONNX model from Hugging Face** (~1.1 GB for the default `jina-code`) and caches it under your data directory; `griot profiles list` shows each profile's RAM tier against the RAM you actually have. CI runs the suite on 3.10 and 3.13, scans for committed secrets, and installs the built wheel in a clean environment on every push.
|
|
74
|
+
|
|
75
|
+
## Quickstart
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
# 1. register the repos you want to index (asks you to confirm, in a terminal)
|
|
79
|
+
griot repos add ~/code/my-app
|
|
80
|
+
griot repos add ~/code/my-lib
|
|
81
|
+
|
|
82
|
+
# 2. see what would be indexed (never spends anything)
|
|
83
|
+
griot index all --repo my-app --dry-run
|
|
84
|
+
|
|
85
|
+
# 3. index for real (default profile is local & free)
|
|
86
|
+
griot index all --repo my-app
|
|
87
|
+
|
|
88
|
+
# 4. search (vector search only — free, no LLM)
|
|
89
|
+
griot search "where is the retry logic for the payment API?"
|
|
90
|
+
|
|
91
|
+
# 5. ask (search + LLM synthesis — requires a chat provider, see below)
|
|
92
|
+
griot ask "how does authentication work in this codebase?" --show-sources
|
|
93
|
+
|
|
94
|
+
# 6. keep an eye on usage and spend
|
|
95
|
+
griot stats
|
|
96
|
+
|
|
97
|
+
# 7. when something does not work: every check at once, reads only
|
|
98
|
+
griot doctor
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
`griot doctor` checks the whole setup in one go and says what to do about each finding. It changes no setting, index or file of yours; two things happen on the way and are said: loading the configuration closes a `.env` left open to other users, as every griot command does, and asking the harness which server it has registered may start that server for a moment, as `griot assist install` does. It checks settings the file holds that griot cannot start with, the configuration file and directories closed to other users, the active profile and its credential, the collection, the registered repositories and whether their index is behind, today's spend against the ceiling, the MCP registration and which read-only tools still ask before every call, the variables a server would ignore, git, the log. Exit status 1 only when a check fails; a warning is something to know.
|
|
102
|
+
|
|
103
|
+
`griot index all` runs the sources in order: `code`, `commits`, `tags`, `branches`, `platform`. Filter with `--sources code,commits`. Index an unregistered directory directly with `--path <dir>`.
|
|
104
|
+
|
|
105
|
+
In a git work tree `index code` reads what git does not ignore (tracked files and new ones), skips symlinks and files over 1 MB, and replaces credential-looking values before anything is embedded. After each run the points whose source is gone are removed: a deleted file, a deleted branch. That removal is held back when more than half of a repository would go (`--prune` overrides) and never happens for a `--path` run, so register a repository you index regularly. `--dry-run` says what a run would embed and remove, at no cost.
|
|
106
|
+
|
|
107
|
+
## Embedding profiles
|
|
108
|
+
|
|
109
|
+
Each profile gets its own collection (vectors from different models aren't comparable). Make one the active profile with `griot profiles use <name>`, which writes `GRIOT_EMBED_PROFILE` to `<config>/.env` (it asks first when the profile calls an API; `--yes` answers), or pick one for a single run with `--profile`. A profile switched to has its own, empty index until you run `griot index all`, and an MCP server that is already running keeps the profile it started with. A `GRIOT_EMBED_PROFILE` exported in the environment, or set in a server's own `env`, wins over the file.
|
|
110
|
+
|
|
111
|
+
| Profile | Backend | Cost | Notes |
|
|
112
|
+
|---|---|---|---|
|
|
113
|
+
| `jina-code` (default) | local ONNX | free | code-specialist, 768-dim |
|
|
114
|
+
| `bge-small`, `nomic-q`, `mxbai-large`, `bge-m3`, `bge-large-en` | local ONNX | free | RAM-tiered alternatives — `griot profiles list` shows what fits your machine |
|
|
115
|
+
| `openai-small` | OpenAI API | paid | needs `GRIOT_OPENAI_API_KEY` |
|
|
116
|
+
| `gemini` | Gemini API | paid | needs `GEMINI_TOKEN` |
|
|
117
|
+
|
|
118
|
+
`griot profiles list` shows every profile with RAM estimates and credential status. `griot profiles delete <profile>` permanently deletes that profile's on-disk collection to reclaim disk space (refuses the active profile, and refuses while any indexing run is in progress). It asks for confirmation at an interactive terminal and has no `--yes`.
|
|
119
|
+
|
|
120
|
+
## Chat profiles (`griot ask` only)
|
|
121
|
+
|
|
122
|
+
Search is controlled by the *embedding* profile above; the chat profile only decides which LLM writes the final answer. Select with `GRIOT_CHAT_PROFILE` or `--chat-profile`.
|
|
123
|
+
|
|
124
|
+
| Profile | Credential | Default model | Price config |
|
|
125
|
+
|---|---|---|---|
|
|
126
|
+
| `gemini` (default) | `GEMINI_TOKEN` | gemini flash | built-in |
|
|
127
|
+
| `openai` | `GRIOT_OPENAI_API_KEY` | gpt mini tier | **required**: `GRIOT_OPENAI_CHAT_PRICE_PER_1M_TOKENS` |
|
|
128
|
+
| `deepseek` | `GRIOT_DEEPSEEK_API_KEY` | deepseek-chat | **required**: `GRIOT_DEEPSEEK_CHAT_PRICE_PER_1M_TOKENS` |
|
|
129
|
+
| `groq` | `GRIOT_GROQ_API_KEY` | llama-3.3-70b-versatile | defaults to $0 (free tier — verify current limits in Groq's console) |
|
|
130
|
+
|
|
131
|
+
griot never assumes an unverified price: `openai`/`deepseek` refuse to run until you set their price (`griot config set openai-chat-price <USD per 1M tokens>`, or `deepseek-chat-price`), so the spend circuit breaker always tracks real cost.
|
|
132
|
+
|
|
133
|
+
## Credentials
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
griot auth set openai # hidden input; OS keychain when available, else <config>/.env at 0600
|
|
137
|
+
griot auth list # status per provider, keys always masked
|
|
138
|
+
griot auth remove openai # asks first; --yes skips the question
|
|
139
|
+
griot auth migrate # moves every credential already in the plaintext file into the keychain
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Install the optional `keychain` extra (`pip install "griot[keychain]"`) and credentials go to the OS keychain — macOS Keychain, Linux Secret Service, Windows Credential Manager — instead of the plaintext file. Without it, or where no backend is reachable, griot falls back to `<config>/.env` at mode 0600. A credential set before the extra was installed stays in the file until you run `griot auth migrate` (or re-run `griot auth set` for that one provider).
|
|
143
|
+
|
|
144
|
+
Platform tokens (only needed for `griot index platform`): `GITHUB_TOKEN`, `GITLAB_PERSONAL_ACCESS_TOKEN`, `BITBUCKET_ACCESS_TOKEN`, `AZURE_DEVOPS_PAT`, `GITEA_TOKEN`.
|
|
145
|
+
|
|
146
|
+
The first time you run any `griot` command, `<config>/.env` is generated for you with every setting listed, mode 0600: most with their default written out, those whose default may still change commented out, and credentials empty. You rarely need to open it: `griot config list` shows each setting, the value in force and where it comes from, and `griot config set` changes one.
|
|
147
|
+
|
|
148
|
+
## MCP server
|
|
149
|
+
|
|
150
|
+
The server has to be registered with your agent before its tools exist in a session. The installer can do it for you:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
griot assist install # for every project: copies the skills, then asks about the rest
|
|
154
|
+
griot assist install --scope local # for this project only
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
It first asks the harness what is registered already. A server that runs this griot is left alone, and so is one that runs anything else that is still there. One whose command no longer exists is offered to be replaced, showing the two commands it would run (remove, then add), and only at the scope being installed: an install for one project never removes what is registered for every project, and an install for every project never touches a project's own registration (it says so when that one is broken, since it takes precedence there). Otherwise it shows the exact command and runs it only after you type `y` (`--mcp` answers yes and makes the command fail if the registration does, `--no-mcp` skips the question). For Claude Code that command is `claude mcp add --scope user griot -- <path to griot> mcp`, and the way back is `claude mcp remove --scope user griot` (`--scope local` for a per-project registration); the installer prints it. Install griot as a tool first (`pipx` or `uv tool`): what gets registered is the path of the griot you ran, and one inside a project's virtual environment stops working when that environment goes.
|
|
158
|
+
|
|
159
|
+
The installer then **offers** to let the agent call griot's read-only tools without asking each time: an agent that has to ask before every search mostly does not search. For Claude Code it shows the rules (`mcp__griot__griot_search` and the other read-only tools, as the server itself marks them) and the file, and adds them to `permissions.allow` only after you type `y`: in `~/.claude/settings.json` with `--scope global`, otherwise in the project's personal `.claude/settings.local.json`. (Wherever this page says `~/.claude`, read the directory `CLAUDE_CONFIG_DIR` names when you have set it: Claude Code keeps its user files there, and the installer follows it for the skills, the agent, the instructions block and these rules.) Every other setting keeps its value (the file is written back as indented JSON, so its layout may change), a rule or pattern you already have under `deny` or `ask` wins and is left out, and a file griot cannot edit safely is not touched: not plain JSON settings, a key given twice, read-only. griot adds no rule for the tools that change anything, nor for the quality check. A rule matches any MCP server named `griot`, whoever defines it. There is no flag that answers yes, an MCP tool never does this, and `--no-allow-tools` skips the question. To undo, remove the rules from that file.
|
|
160
|
+
|
|
161
|
+
Registered for every project, each open session starts its own griot server. With a paid embedding profile that is light. With a local one each server loads the model on its first search, from about 100 MB to a few GB depending on the profile (`griot profiles list` shows each profile's estimate). What may be indexed does not change with where the server is registered: that is decided by `repos.json` and `GRIOT_MCP_INDEX_ROOTS`.
|
|
162
|
+
|
|
163
|
+
To register it yourself, per project:
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
claude mcp add --transport stdio griot --scope project -- griot mcp
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
or in `.mcp.json`:
|
|
170
|
+
|
|
171
|
+
```json
|
|
172
|
+
{
|
|
173
|
+
"mcpServers": {
|
|
174
|
+
"griot": {
|
|
175
|
+
"command": "griot",
|
|
176
|
+
"args": ["mcp"]
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Leave `env` out unless you want this project to differ from your own configuration. A variable set there wins over `griot config` for that server only where it narrows what your configuration says: one that would turn on indexing through MCP, add a directory an agent may index, raise a spend ceiling, send a platform token to another host, switch to a profile that calls an API or let an index run fail for longer is ignored (the server says so on stderr and in `griot_config_list`). Those are set with `griot config set` and `griot profiles use`, or, for a profile, with `--profile` in the server's `args`. `GRIOT_PROJECT` is the one that belongs in `env`. A server also refuses to start with its configuration or data directory inside the project it was started in.
|
|
183
|
+
|
|
184
|
+
The server sends instructions when it connects: what griot covers, when to search it first and when to read or grep instead. A client that passes server instructions on to the agent (Claude Code does) needs nothing installed for that.
|
|
185
|
+
|
|
186
|
+
`griot_search` takes an optional `group_by_document`: off by default (up to three chunks of one document, so it can answer in some depth without taking every slot), on when you want breadth (the best chunk of each document, so the same number of results reaches more files, commits and PRs). `repos` and `source_types` narrow a search to some repositories and to some kinds of source (`code`, `commit`, `tag`, `branch`, `merge_request`, `release`, `issue`); a repository with nothing indexed, or a kind that does not exist, is an error rather than an empty result. `griot search` takes the same as `--repo`, `--source-type` and `--group-by-document`. Each indexing run records what every repository looked like (its HEAD, and the tag and remote-branch refs), so `griot_index_status` says, per registered repository, whether its index is behind the repository and how: commits made since the code and commits sources ran (or that the indexed commit is no longer in the history: rewritten, or another branch checked out), whether the tags or remote branches changed (the base branch counts, since each branch is described against it), and which sources never ran; `griot_search` names the repositories among its results that are behind (`behind`), and `griot stats` lists them under attention. Pull requests and issues live on the platform, so nothing local can say whether that source is behind.
|
|
187
|
+
|
|
188
|
+
The server's own tool list is the inventory (your client shows it), and [docs/mcp-capability-coverage.md](docs/mcp-capability-coverage.md) maps each tool to its CLI command. The read-only ones cover search, index and spend status, the usage report, the lists of repositories, profiles and curated cases, the settings the server is running with, and which credentials are configured. Four more read without changing anything and still ask each time, because they cost or read far more than a search does: the quality check (the self-check and the curated golden set), a preview of what an index run would embed and remove (`griot_index_preview`: free, and available whether or not indexing through MCP is enabled), an audit of where the index holds credential-looking values, and candidate golden-set cases from a repository's git log.
|
|
189
|
+
|
|
190
|
+
Four prompts, which clients surface as slash commands:
|
|
191
|
+
|
|
192
|
+
| Command | What it does |
|
|
193
|
+
|---|---|
|
|
194
|
+
| `/mcp__griot__stats` | The same usage report `griot stats` prints, read for you. |
|
|
195
|
+
| `/mcp__griot__history` | Investigates a question across every source type — code, commits, PRs, issues — and answers as a cited history, oldest cause first. |
|
|
196
|
+
| `/mcp__griot__health` | Says whether the index is worth trusting, and which kind of failure it is if not. |
|
|
197
|
+
| `/mcp__griot__overview` | What is indexed here, and which registered repos are no longer usable. |
|
|
198
|
+
|
|
199
|
+
A prompt injects text; the work is still a tool call, so nothing here runs in the background or spends anything on its own.
|
|
200
|
+
|
|
201
|
+
The tools that change something register or remove a repository, delete a profile, curate the golden set, install the skills (`griot_assist_install`, below) and index a repository (`griot_index_repo`, **off by default** — it can spend money on paid profiles; you enable it with `griot config set mcp-index true`, which asks at a terminal, and even then it only accepts paths registered via `griot repos add` or under `GRIOT_MCP_INDEX_ROOTS`). None of them act unasked. Where your client can show a confirmation dialog they ask you, and only your answer counts: a `confirm=true` argument from the agent is ignored there, and a "no" is final. Where the client cannot ask, they refuse and hand back the equivalent `griot` command, and an explicit `confirm=true` argument re-runs them — which means that on such a client an agent that passes `confirm=true` up front executes without a human. That fallback is deliberate: it is the only thing that works on a client that cannot prompt. **Registering a new repo, deleting a profile, and installing assist skills/agents do not have it** — those accept nothing but a real human answer, because they widen what may be indexed, destroy data irreversibly, or install files a future AI session will auto-load and follow, and `confirm` is an argument the agent supplies to itself. Those three are also marked as requiring user interaction, which Claude Code honors: run headless, it denies the call before it reaches griot, even with an allow rule for the tool. (Full policy table: [docs/mcp-capability-coverage.md § The management surface](docs/mcp-capability-coverage.md#the-management-surface).)
|
|
202
|
+
|
|
203
|
+
### Claude Code / opencode skills and agent
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
griot assist install # every project: detects Claude Code and/or opencode, installs into whichever is present
|
|
207
|
+
griot assist install --scope local # this project only, into ./.claude or ./.opencode
|
|
208
|
+
griot assist install --harness opencode # skip detection, target one harness explicitly
|
|
209
|
+
griot assist install --skills-only # copy the skills and the agent, and ask nothing
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
After the files, the installer asks up to three things, in this order, each `[y/N]` with no as the default: registering the MCP server, letting the read-only tools run without a prompt, and (for every project only) the instructions block. The last two are offered only when the server is registered, since they are about its tools. It ends with a summary of what was done and what comes next. With no supported harness on the machine it installs nothing and exits with an error.
|
|
213
|
+
|
|
214
|
+
Copies a small bundle — five Skills (onboarding, indexing, day-to-day search/ask workflows, operations — running and recovering index runs from inside an agent session — and troubleshooting) and a setup Agent — written for whoever uses griot in **their own** project, not for contributing to griot itself. Claude Code gets `.claude/skills/`+`.claude/agents/`, opencode gets `.opencode/skills/`+`.opencode/agents/` (at `--scope global`: Claude Code's user directory, `~/.claude` or the one `CLAUDE_CONFIG_DIR` names, and `~/.config/opencode/`); Skills are one shared file per skill (both harnesses read the same `SKILL.md` layout), the setup Agent ships as two variants because the two harnesses use different frontmatter for a subagent definition. The same thing is also `griot_assist_install`, an MCP tool an already-connected agent can request on your behalf — it still needs a real human answer, for the same reason `repos_add`/`profiles_delete` do. Re-running it overwrites a file it installed before if griot's bundled version changed — including any edits you made to that file yourself; the command lists which files it overwrote.
|
|
215
|
+
|
|
216
|
+
At global scope, `griot assist install` also **offers** to add a short block to the harness's global instructions file (`~/.claude/CLAUDE.md` for Claude Code) that tells agents in every project when to use `griot_search`. It shows you the exact text and the file, and writes only if you type `y` at the prompt. With no interactive terminal (a script, a pipe) it writes nothing, and there is deliberately no flag that answers for you. That keeps the question from being skipped by accident or by an MCP tool. It is not a defence against a process that already has a shell on your machine: that process can edit the file directly, or drive a pseudo-terminal. `--no-instructions` skips the question. The block sits between `griot:begin` and `griot:end` markers, nothing outside them is touched, a symlinked file is written through, and deleting the block removes it. `griot_assist_install` (MCP) never touches this file.
|
|
217
|
+
|
|
218
|
+
Secrets are never an MCP operation. `griot_auth_guidance` tells an agent which providers are configured and which command you should run yourself; no tool takes or returns a key, masked or otherwise.
|
|
219
|
+
|
|
220
|
+
There is deliberately no `griot_ask` MCP tool: an agent calling MCP already has its own LLM — it needs retrieval, not a second synthesis layer.
|
|
221
|
+
|
|
222
|
+
### Running multiple sessions
|
|
223
|
+
|
|
224
|
+
The vector store is embedded (no server), so only one process can hold a given collection open at a time. Subagents and workflow-spawned agents share their parent session's MCP connection and never collide with each other. A genuinely separate session (another window, another project) using the **same** embedding profile can collide, though, and so can a `griot index` run from a shell while a server is attached. By default (`GRIOT_MCP_CONCURRENCY_MODE=multi`) the server releases the collection once it has gone `GRIOT_MCP_IDLE_RELEASE_SECONDS` (default 30) without a tool call and retries with backoff when it reopens, so another session or a shell command gets in after that window. The cost is one reopen, roughly 90 ms on a 15,000-point collection, on the first call after an idle stretch. Set `GRIOT_MCP_CONCURRENCY_MODE=single` to hold the collection for the server's whole life instead: no reopen cost, but any other process on that profile gets a hard error until the session ends. To index from inside a session without waiting for the idle window, enable `griot_index_repo` (`GRIOT_MCP_ENABLE_INDEX=true`): it lets go of the server's handle before starting the run, once no other griot tool call is using the index (it waits a few seconds for one to finish, and otherwise asks to be called again). The `griot-operations` skill walks through this. Sessions on different embedding profiles never collide, since each profile is a separate collection.
|
|
225
|
+
|
|
226
|
+
## Documentation
|
|
227
|
+
|
|
228
|
+
| | |
|
|
229
|
+
|---|---|
|
|
230
|
+
| [SECURITY.md](SECURITY.md) | What leaves your machine, what is protected on disk, and the MCP threat model |
|
|
231
|
+
| [ROADMAP.md](ROADMAP.md) | What is planned — and what was considered and rejected, with reasons |
|
|
232
|
+
| [docs/indexing-model.md](docs/indexing-model.md) | What a point is keyed by, what its payload carries, and why re-indexing is idempotent |
|
|
233
|
+
| [docs/mcp-capability-coverage.md](docs/mcp-capability-coverage.md) | Which MCP protocol capabilities griot uses, the CLI↔MCP parity table, and the confirmation policy |
|
|
234
|
+
| [docs/lessons-and-debts.md](docs/lessons-and-debts.md) | Decisions this project learned the hard way, and what it knowingly left undone |
|
|
235
|
+
| [CONTRIBUTING.md](CONTRIBUTING.md) | What the code expects from a change |
|
|
236
|
+
| [CHANGELOG.md](CHANGELOG.md) | Released changes |
|
|
237
|
+
|
|
238
|
+
## Where things live
|
|
239
|
+
|
|
240
|
+
| Path | Contents |
|
|
241
|
+
|---|---|
|
|
242
|
+
| `~/.config/griot/` | `.env` (credentials, 0600), `repos.json`, `quality_golden_set.json` |
|
|
243
|
+
| `~/.local/share/griot/` | `qdrant_data/` (vectors + indexed content), `models/` (local embedding models), `logs/`, `.spend_state.json` |
|
|
244
|
+
|
|
245
|
+
Override with `GRIOT_CONFIG_DIR` / `GRIOT_DATA_DIR` (XDG variables are also honored). Everything griot writes is chmod 0600 (files) / 0700 (dirs).
|
|
246
|
+
|
|
247
|
+
## Environment variables
|
|
248
|
+
|
|
249
|
+
`griot config list` shows every setting, the value in force and where it comes from (the environment, `<config>/.env`, or the default). `griot config set <name> <value>` checks a value and writes it to the file, `griot config unset <name>` goes back to the default, and `griot config get <name>` prints one value. A change that widens something is asked about at an interactive terminal, with no flag that answers: raising a spend ceiling, turning on indexing through MCP, adding a directory an agent may index, pointing a platform token at another host. A variable exported in the environment wins over the file, and a running MCP server keeps the values it started with: the `griot_config_list` tool answers for the server being asked, with the value each setting has there, where it came from, and whether the file has changed since. The embedding profile has its own command (`griot profiles use`), and credentials have `griot auth`.
|
|
250
|
+
|
|
251
|
+
The most used ones; `griot config list` shows them all.
|
|
252
|
+
|
|
253
|
+
| Variable | Purpose |
|
|
254
|
+
|---|---|
|
|
255
|
+
| `GRIOT_EMBED_PROFILE` | active embedding profile (default `jina-code`) |
|
|
256
|
+
| `GRIOT_CHAT_PROFILE` | active chat profile (default `gemini`) |
|
|
257
|
+
| `GRIOT_SPEND_CEILING_USD` | daily spend ceiling (default $3) |
|
|
258
|
+
| `GRIOT_SPEND_VELOCITY_CEILING_USD` | 5-minute window ceiling (default $1) |
|
|
259
|
+
| `GRIOT_LOG_QUESTIONS` | `false` omits question text from the query log |
|
|
260
|
+
| `GRIOT_PROJECT` | name recorded with each `griot ask`, `griot_search` and MCP tool call so `griot stats` can show usage by project (default: the folder `CLAUDE_PROJECT_DIR` names, else the folder `griot` runs in; set it in the `env` of that project's MCP server entry, not in `.env`) |
|
|
261
|
+
| `GRIOT_MCP_ENABLE_INDEX` | `true` enables the MCP indexing tool |
|
|
262
|
+
| `GRIOT_MCP_INDEX_ROOTS` | `:`-separated dir prefixes allowed for MCP indexing |
|
|
263
|
+
| `GRIOT_MCP_CONCURRENCY_MODE` | `multi` (default) or `single` — see "Running multiple sessions" above |
|
|
264
|
+
| `GRIOT_MCP_IDLE_RELEASE_SECONDS` | idle window before releasing the collection handle in `multi` mode (default 30) |
|
|
265
|
+
| `GRIOT_GITLAB_API_BASE` | self-hosted GitLab API base (default `https://gitlab.com/api/v4`) |
|
|
266
|
+
| `GRIOT_GITEA_HOSTS` | comma-separated Gitea/Forgejo hosts to recognize |
|
|
267
|
+
|
|
268
|
+
## Quality tooling
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
griot quality-check # self-check: sampled points must find themselves
|
|
272
|
+
griot golden-set suggest ~/code/my-app # derive curated test cases from that repository's git log (human-approved)
|
|
273
|
+
griot golden-set add "query" # curate a case from a real search
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
`griot quality-check` scores retrieval against your curated golden set — useful before/after switching embedding profiles.
|
|
277
|
+
|
|
278
|
+
### Credentials in indexed content
|
|
279
|
+
|
|
280
|
+
```bash
|
|
281
|
+
griot audit # where the index holds credential-looking values (never the values)
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
Text is scanned for credential-shaped values (private keys, a list of provider token formats, JWTs, passwords in URLs, random-looking values assigned to names like `API_KEY`) before it is embedded and stored, and they are replaced with a marker; the run tells you where. `griot audit` looks for the same shapes in what is already indexed. What this can and cannot find is in [SECURITY.md](SECURITY.md#credentials-in-what-is-indexed).
|
|
285
|
+
|
|
286
|
+
## Development
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
uv sync --locked --extra dev # the versions CI runs (or: pip install -e ".[dev]")
|
|
290
|
+
uv run pytest -q # no test ever calls a real API or needs credentials
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## License
|
|
294
|
+
|
|
295
|
+
[Apache-2.0](LICENSE)
|