klyd 0.2.2__tar.gz → 0.2.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.
- {klyd-0.2.2 → klyd-0.2.4}/LICENSE +21 -21
- klyd-0.2.4/MANIFEST.in +4 -0
- klyd-0.2.4/PKG-INFO +278 -0
- klyd-0.2.4/README.md +266 -0
- klyd-0.2.4/klyd/__init__.py +10 -0
- klyd-0.2.4/klyd/cli.py +1205 -0
- klyd-0.2.4/klyd/config.py +115 -0
- klyd-0.2.4/klyd/db.py +552 -0
- {klyd-0.2.2 → klyd-0.2.4}/klyd/extractor.py +184 -137
- klyd-0.2.4/klyd/hook_templates/post-commit.sh +2 -0
- klyd-0.2.4/klyd/hook_templates/pre-commit.sh +2 -0
- klyd-0.2.4/klyd/hooks.py +113 -0
- klyd-0.2.4/klyd/injector.py +184 -0
- klyd-0.2.4/klyd/logger.py +88 -0
- klyd-0.2.4/klyd/schema/v1.sql +17 -0
- klyd-0.2.4/klyd.egg-info/PKG-INFO +278 -0
- {klyd-0.2.2 → klyd-0.2.4}/klyd.egg-info/SOURCES.txt +5 -4
- {klyd-0.2.2 → klyd-0.2.4}/pyproject.toml +26 -21
- {klyd-0.2.2 → klyd-0.2.4}/setup.cfg +4 -4
- klyd-0.2.2/AGENTS.md.txt +0 -25
- klyd-0.2.2/MANIFEST.in +0 -2
- klyd-0.2.2/PKG-INFO +0 -415
- klyd-0.2.2/README.md +0 -403
- klyd-0.2.2/hooks/post-commit.sh +0 -2
- klyd-0.2.2/hooks/pre-commit.sh +0 -2
- klyd-0.2.2/klyd/__init__.py +0 -10
- klyd-0.2.2/klyd/cli.py +0 -434
- klyd-0.2.2/klyd/config.py +0 -44
- klyd-0.2.2/klyd/db.py +0 -124
- klyd-0.2.2/klyd/hooks.py +0 -40
- klyd-0.2.2/klyd/injector.py +0 -18
- klyd-0.2.2/klyd.egg-info/PKG-INFO +0 -415
- {klyd-0.2.2 → klyd-0.2.4}/klyd.egg-info/dependency_links.txt +0 -0
- {klyd-0.2.2 → klyd-0.2.4}/klyd.egg-info/entry_points.txt +0 -0
- {klyd-0.2.2 → klyd-0.2.4}/klyd.egg-info/requires.txt +0 -0
- {klyd-0.2.2 → klyd-0.2.4}/klyd.egg-info/top_level.txt +0 -0
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 klyd contributors
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 klyd contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
klyd-0.2.4/MANIFEST.in
ADDED
klyd-0.2.4/PKG-INFO
ADDED
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: klyd
|
|
3
|
+
Version: 0.2.4
|
|
4
|
+
Summary: A CLI tool that wraps coding agents via git hooks to inject architectural memory
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Requires-Dist: click
|
|
9
|
+
Requires-Dist: anthropic
|
|
10
|
+
Requires-Dist: rich
|
|
11
|
+
Dynamic: license-file
|
|
12
|
+
|
|
13
|
+
<div align="center">
|
|
14
|
+
<img src="https://raw.githubusercontent.com/kaadipranav/kaadipranav/refs/heads/main/assets/klydnewposter.png" />
|
|
15
|
+
</div>
|
|
16
|
+
|
|
17
|
+
# KLYD
|
|
18
|
+
|
|
19
|
+
### Decision memory for coding agents.
|
|
20
|
+
|
|
21
|
+
Coding agents can generate code quickly but often lose the architectural decisions that shaped a repository.
|
|
22
|
+
|
|
23
|
+
Klyd records, retrieves, and reintroduces those decisions so future agent sessions can work with the project's existing reasoning instead of repeatedly rediscovering it.
|
|
24
|
+
|
|
25
|
+
[PyPI: klyd](https://pypi.org/project/klyd/) · [GitHub](https://github.com/klyd-studio/klyd-harness) · [License: MIT](./LICENSE)
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## The problem
|
|
30
|
+
|
|
31
|
+
A coding agent may know the current files but not the reasons behind them:
|
|
32
|
+
|
|
33
|
+
- why a database choice was made;
|
|
34
|
+
- why a workaround exists;
|
|
35
|
+
- why an API must remain stable;
|
|
36
|
+
- why a previous approach was rejected;
|
|
37
|
+
- which architectural constraints are non-negotiable.
|
|
38
|
+
|
|
39
|
+
Without that context, agents can produce locally plausible changes that violate the system's existing design. Over multiple sessions, a codebase accumulates conflicting architectural patterns, turning into a patchwork of fragmented decisions.
|
|
40
|
+
|
|
41
|
+
---
|
|
42
|
+
|
|
43
|
+
## The workflow
|
|
44
|
+
|
|
45
|
+
Klyd operates invisibly through standard Git hooks without requiring a background daemon or wrapping agent subprocesses with intrusive proxies:
|
|
46
|
+
|
|
47
|
+
```mermaid
|
|
48
|
+
graph TD
|
|
49
|
+
A[Developer commits] --> B["post-commit hook
|
|
50
|
+
kl extract-commit"]
|
|
51
|
+
B --> C["LLM Extraction
|
|
52
|
+
classify: NEW / REINFORCE / CONTRADICT"]
|
|
53
|
+
C -->|NEW or REINFORCE| D[("SQLite Store
|
|
54
|
+
.klyd/memory.db")]
|
|
55
|
+
C -->|CONTRADICT| E["Flagged for Review
|
|
56
|
+
kl review"]
|
|
57
|
+
E -->|Resolve: Accept / Merge / Edit| D
|
|
58
|
+
|
|
59
|
+
F[Agent stages changes] --> G["pre-commit hook
|
|
60
|
+
kl prepare-injection"]
|
|
61
|
+
G --> H["Single-pass query:
|
|
62
|
+
glob match + cosine similarity"]
|
|
63
|
+
H --> D
|
|
64
|
+
H --> I[".klyd/injection.txt
|
|
65
|
+
formatted context"]
|
|
66
|
+
I --> J["kl run aider
|
|
67
|
+
context injected"]
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
All state remains strictly local to `.klyd/` inside the target git repository.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Example
|
|
75
|
+
|
|
76
|
+
A repository previously decided:
|
|
77
|
+
|
|
78
|
+
> Authentication must remain inside the existing WebCrypto-based boundary. External token libraries must not be introduced.
|
|
79
|
+
|
|
80
|
+
Months later, an autonomous agent tasked with fixing an auth endpoint proposes adding a third-party token parser.
|
|
81
|
+
|
|
82
|
+
Before the change is committed, Klyd inspects the staged files, retrieves the earlier decision and its rationale from `.klyd/memory.db`, and injects the constraint directly into the agent's context window. The agent refactors the code within the established WebCrypto pattern instead of introducing an incompatible dependency.
|
|
83
|
+
|
|
84
|
+
*(Note: This is an illustrative example of an architectural boundary constraint captured from commit history and reintroduced to guide subsequent agent turns).*
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Technical design
|
|
89
|
+
|
|
90
|
+
Klyd currently uses:
|
|
91
|
+
|
|
92
|
+
- **SQLite for persistent decision storage**: Embedded relational database maintaining schema versions, embeddings, and decision records.
|
|
93
|
+
- **Git hooks for repository lifecycle integration**: `post-commit` extracts decisions asynchronously from diffs; `pre-commit` prepares context from staged changes.
|
|
94
|
+
- **Semantic similarity for retrieval**: Optional vector embeddings paired with lexical glob matching for relevant context ranking.
|
|
95
|
+
- **Recursive decision ancestry**: Tracking parent-child relationships across decision versions using recursive Common Table Expressions.
|
|
96
|
+
- **Conflict resolution between related decisions**: Interactive terminal UI (`kl review`) supporting accept, reject, manual edit, and LLM-assisted decision merging.
|
|
97
|
+
- **Multiple model-provider integrations**: Bring-Your-Own-Key (BYOK) support for Anthropic, OpenAI, OpenRouter, Google Gemini, and Groq.
|
|
98
|
+
- **CLI-oriented workflow for coding-agent environments**: Direct compatibility flags for tools like `aider` and `opencode`.
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## Design choice: SQLite
|
|
103
|
+
|
|
104
|
+
SQLite keeps the decision history:
|
|
105
|
+
|
|
106
|
+
- **local** to the repository or workspace;
|
|
107
|
+
- **inspectable** with standard SQL tools or CLI commands;
|
|
108
|
+
- **easy to back up** by copying `.klyd/`;
|
|
109
|
+
- **usable** without requiring any cloud service, daemon, or database server;
|
|
110
|
+
- **available** to low-latency command-line workflows and shell scripts.
|
|
111
|
+
|
|
112
|
+
The trade-off is that Klyd prioritizes local developer infrastructure and explicit Git workflow integration over centralized multi-user cloud coordination.
|
|
113
|
+
|
|
114
|
+
---
|
|
115
|
+
|
|
116
|
+
## Engineering details
|
|
117
|
+
|
|
118
|
+
### In-database custom multi-glob matching
|
|
119
|
+
|
|
120
|
+
When staged files are evaluated (e.g. `auth/login.py`), Klyd must match them against comma-separated glob patterns (e.g. `auth/*, security/*`) stored in the `decisions` table. Standard SQL lacks native glob-list evaluation, and loading all rows into Python memory for full-table scanning creates unnecessary overhead.
|
|
121
|
+
|
|
122
|
+
Klyd solves this by registering a custom Python callback function (`match_files`) directly into the SQLite C-runtime using `sqlite3.Connection.create_function`:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
def _match_any_file(file_patterns: str, file_list_str: str) -> int:
|
|
126
|
+
patterns = [p.strip() for p in file_patterns.split(",")]
|
|
127
|
+
files = file_list_str.split("|")
|
|
128
|
+
for f in files:
|
|
129
|
+
for p in patterns:
|
|
130
|
+
if fnmatch.fnmatch(f, p):
|
|
131
|
+
return 1
|
|
132
|
+
return 0
|
|
133
|
+
|
|
134
|
+
conn.create_function("match_files", 2, _match_any_file)
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
This allows the SQLite query planner to filter rows atomically in a single pass at the database layer before sorting by relevance and recency.
|
|
138
|
+
|
|
139
|
+
### Decision lineage with recursive CTEs
|
|
140
|
+
|
|
141
|
+
When conflicting decisions are merged or updated during human review, older decisions are soft-archived rather than overwritten. Lineage is tracked through `parent_decision_id`, allowing complete evolutionary trees to be reconstructed using recursive Common Table Expressions:
|
|
142
|
+
|
|
143
|
+
```sql
|
|
144
|
+
WITH RECURSIVE ancestors(id, decision, parent_decision_id) AS (
|
|
145
|
+
SELECT id, decision, parent_decision_id FROM decisions WHERE id = ?
|
|
146
|
+
UNION ALL
|
|
147
|
+
SELECT d.id, d.decision, d.parent_decision_id
|
|
148
|
+
FROM decisions d JOIN ancestors a ON d.id = a.parent_decision_id
|
|
149
|
+
)
|
|
150
|
+
SELECT * FROM ancestors;
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## Quickstart
|
|
156
|
+
|
|
157
|
+
### 1. Install Klyd
|
|
158
|
+
|
|
159
|
+
> **0.2.4 is the current release.** The 0.2.2 wheel was missing its hook
|
|
160
|
+
> templates and SQL schema; 0.2.3 fixed packaging, and 0.2.4 fixes the CLI
|
|
161
|
+
> defects found by exercising every command against the published wheel.
|
|
162
|
+
> Install the current release:
|
|
163
|
+
>
|
|
164
|
+
> ```bash
|
|
165
|
+
> pip install klyd==0.2.4
|
|
166
|
+
> ```
|
|
167
|
+
|
|
168
|
+
### 2. Initialize a repository
|
|
169
|
+
|
|
170
|
+
Run inside the root of your Git repository:
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
kl init
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
This creates `.klyd/memory.db`, initializes the configuration file, and installs the Git hooks into `.git/hooks/`.
|
|
177
|
+
|
|
178
|
+
### 3. Configure a model provider
|
|
179
|
+
|
|
180
|
+
Set your preferred API key (BYOK):
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
kl config --api-key sk-ant-...
|
|
184
|
+
# or: kl config --openai-key sk-...
|
|
185
|
+
# or: kl config --gemini-key ...
|
|
186
|
+
# or: kl config --groq-key ...
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Inspect active configuration:
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
kl config --show
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### 4. Record decisions from commits
|
|
196
|
+
|
|
197
|
+
Decisions are automatically extracted by the `post-commit` hook whenever you make a Git commit:
|
|
198
|
+
|
|
199
|
+
```bash
|
|
200
|
+
git commit -m "refactor(db): use SQLite connection pooling instead of global instances"
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
You can also trigger extraction manually for the latest commit:
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
kl extract-commit
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### 5. Retrieve relevant decisions
|
|
210
|
+
|
|
211
|
+
View stored architectural decisions in a table:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
kl status
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
Filter decisions by search keyword:
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
kl status --search "database"
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
View decisions grouped by module hierarchy:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
kl status --tree
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### 6. Run an agent with decision memory
|
|
230
|
+
|
|
231
|
+
Launch your coding agent wrapped with Klyd context:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
kl run aider
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
For custom agent invocations, generate the injection context directly:
|
|
238
|
+
|
|
239
|
+
```bash
|
|
240
|
+
kl prepare-injection
|
|
241
|
+
# Context is written to .klyd/injection.txt
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Commands reference
|
|
247
|
+
|
|
248
|
+
| Command | Description |
|
|
249
|
+
|---|---|
|
|
250
|
+
| `kl init` | Initialise `.klyd/` storage and install Git hooks. |
|
|
251
|
+
| `kl config` | Configure model API keys, templates, and extraction thresholds. |
|
|
252
|
+
| `kl extract-commit` | Extract architectural decisions from the latest Git commit. |
|
|
253
|
+
| `kl prepare-injection` | Query matching decisions for staged files and generate `.klyd/injection.txt`. |
|
|
254
|
+
| `kl preview-injection` | Preview the injection prompt without writing it to disk. |
|
|
255
|
+
| `kl status` | Display active decisions, conflict summaries, and drift statistics. |
|
|
256
|
+
| `kl review` | Interactive CLI to resolve flagged architectural conflicts (`accept`, `merge`, `edit`, `reject`). |
|
|
257
|
+
| `kl pin <id>` | Pin a non-negotiable architectural constraint so it is always injected. |
|
|
258
|
+
| `kl unpin <id>` | Remove a pinned decision constraint. |
|
|
259
|
+
| `kl run <agent>` | Execute a coding agent with memory injected via command-line arguments. |
|
|
260
|
+
| `kl metrics` | Display aggregated decision counts, average confidence, and conflict rates. |
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Current status
|
|
265
|
+
|
|
266
|
+
Klyd is an actively developed developer-tooling project (v0.2.4 distributed on PyPI).
|
|
267
|
+
|
|
268
|
+
The current implementation is focused on local decision persistence, retrieval, Git lifecycle integration, and terminal coding-agent workflows.
|
|
269
|
+
|
|
270
|
+
- **Local scope**: Designed for single-developer repository workspaces. Remote peer sync and multi-user concurrent locking are not included.
|
|
271
|
+
- **LLM extraction dependency**: Quality of extracted decisions correlates with commit message clarity and the reasoning capabilities of the configured model.
|
|
272
|
+
- **Agent support**: Native argument injection is configured for `aider` and `opencode`; other agents receive the injection as a final positional argument. The same text is written to `.klyd/injection.txt` for agents that take a context-file flag.
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## License
|
|
277
|
+
|
|
278
|
+
MIT License — see [LICENSE](./LICENSE).
|
klyd-0.2.4/README.md
ADDED
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/kaadipranav/kaadipranav/refs/heads/main/assets/klydnewposter.png" />
|
|
3
|
+
</div>
|
|
4
|
+
|
|
5
|
+
# KLYD
|
|
6
|
+
|
|
7
|
+
### Decision memory for coding agents.
|
|
8
|
+
|
|
9
|
+
Coding agents can generate code quickly but often lose the architectural decisions that shaped a repository.
|
|
10
|
+
|
|
11
|
+
Klyd records, retrieves, and reintroduces those decisions so future agent sessions can work with the project's existing reasoning instead of repeatedly rediscovering it.
|
|
12
|
+
|
|
13
|
+
[PyPI: klyd](https://pypi.org/project/klyd/) · [GitHub](https://github.com/klyd-studio/klyd-harness) · [License: MIT](./LICENSE)
|
|
14
|
+
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
## The problem
|
|
18
|
+
|
|
19
|
+
A coding agent may know the current files but not the reasons behind them:
|
|
20
|
+
|
|
21
|
+
- why a database choice was made;
|
|
22
|
+
- why a workaround exists;
|
|
23
|
+
- why an API must remain stable;
|
|
24
|
+
- why a previous approach was rejected;
|
|
25
|
+
- which architectural constraints are non-negotiable.
|
|
26
|
+
|
|
27
|
+
Without that context, agents can produce locally plausible changes that violate the system's existing design. Over multiple sessions, a codebase accumulates conflicting architectural patterns, turning into a patchwork of fragmented decisions.
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## The workflow
|
|
32
|
+
|
|
33
|
+
Klyd operates invisibly through standard Git hooks without requiring a background daemon or wrapping agent subprocesses with intrusive proxies:
|
|
34
|
+
|
|
35
|
+
```mermaid
|
|
36
|
+
graph TD
|
|
37
|
+
A[Developer commits] --> B["post-commit hook
|
|
38
|
+
kl extract-commit"]
|
|
39
|
+
B --> C["LLM Extraction
|
|
40
|
+
classify: NEW / REINFORCE / CONTRADICT"]
|
|
41
|
+
C -->|NEW or REINFORCE| D[("SQLite Store
|
|
42
|
+
.klyd/memory.db")]
|
|
43
|
+
C -->|CONTRADICT| E["Flagged for Review
|
|
44
|
+
kl review"]
|
|
45
|
+
E -->|Resolve: Accept / Merge / Edit| D
|
|
46
|
+
|
|
47
|
+
F[Agent stages changes] --> G["pre-commit hook
|
|
48
|
+
kl prepare-injection"]
|
|
49
|
+
G --> H["Single-pass query:
|
|
50
|
+
glob match + cosine similarity"]
|
|
51
|
+
H --> D
|
|
52
|
+
H --> I[".klyd/injection.txt
|
|
53
|
+
formatted context"]
|
|
54
|
+
I --> J["kl run aider
|
|
55
|
+
context injected"]
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
All state remains strictly local to `.klyd/` inside the target git repository.
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Example
|
|
63
|
+
|
|
64
|
+
A repository previously decided:
|
|
65
|
+
|
|
66
|
+
> Authentication must remain inside the existing WebCrypto-based boundary. External token libraries must not be introduced.
|
|
67
|
+
|
|
68
|
+
Months later, an autonomous agent tasked with fixing an auth endpoint proposes adding a third-party token parser.
|
|
69
|
+
|
|
70
|
+
Before the change is committed, Klyd inspects the staged files, retrieves the earlier decision and its rationale from `.klyd/memory.db`, and injects the constraint directly into the agent's context window. The agent refactors the code within the established WebCrypto pattern instead of introducing an incompatible dependency.
|
|
71
|
+
|
|
72
|
+
*(Note: This is an illustrative example of an architectural boundary constraint captured from commit history and reintroduced to guide subsequent agent turns).*
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## Technical design
|
|
77
|
+
|
|
78
|
+
Klyd currently uses:
|
|
79
|
+
|
|
80
|
+
- **SQLite for persistent decision storage**: Embedded relational database maintaining schema versions, embeddings, and decision records.
|
|
81
|
+
- **Git hooks for repository lifecycle integration**: `post-commit` extracts decisions asynchronously from diffs; `pre-commit` prepares context from staged changes.
|
|
82
|
+
- **Semantic similarity for retrieval**: Optional vector embeddings paired with lexical glob matching for relevant context ranking.
|
|
83
|
+
- **Recursive decision ancestry**: Tracking parent-child relationships across decision versions using recursive Common Table Expressions.
|
|
84
|
+
- **Conflict resolution between related decisions**: Interactive terminal UI (`kl review`) supporting accept, reject, manual edit, and LLM-assisted decision merging.
|
|
85
|
+
- **Multiple model-provider integrations**: Bring-Your-Own-Key (BYOK) support for Anthropic, OpenAI, OpenRouter, Google Gemini, and Groq.
|
|
86
|
+
- **CLI-oriented workflow for coding-agent environments**: Direct compatibility flags for tools like `aider` and `opencode`.
|
|
87
|
+
|
|
88
|
+
---
|
|
89
|
+
|
|
90
|
+
## Design choice: SQLite
|
|
91
|
+
|
|
92
|
+
SQLite keeps the decision history:
|
|
93
|
+
|
|
94
|
+
- **local** to the repository or workspace;
|
|
95
|
+
- **inspectable** with standard SQL tools or CLI commands;
|
|
96
|
+
- **easy to back up** by copying `.klyd/`;
|
|
97
|
+
- **usable** without requiring any cloud service, daemon, or database server;
|
|
98
|
+
- **available** to low-latency command-line workflows and shell scripts.
|
|
99
|
+
|
|
100
|
+
The trade-off is that Klyd prioritizes local developer infrastructure and explicit Git workflow integration over centralized multi-user cloud coordination.
|
|
101
|
+
|
|
102
|
+
---
|
|
103
|
+
|
|
104
|
+
## Engineering details
|
|
105
|
+
|
|
106
|
+
### In-database custom multi-glob matching
|
|
107
|
+
|
|
108
|
+
When staged files are evaluated (e.g. `auth/login.py`), Klyd must match them against comma-separated glob patterns (e.g. `auth/*, security/*`) stored in the `decisions` table. Standard SQL lacks native glob-list evaluation, and loading all rows into Python memory for full-table scanning creates unnecessary overhead.
|
|
109
|
+
|
|
110
|
+
Klyd solves this by registering a custom Python callback function (`match_files`) directly into the SQLite C-runtime using `sqlite3.Connection.create_function`:
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
def _match_any_file(file_patterns: str, file_list_str: str) -> int:
|
|
114
|
+
patterns = [p.strip() for p in file_patterns.split(",")]
|
|
115
|
+
files = file_list_str.split("|")
|
|
116
|
+
for f in files:
|
|
117
|
+
for p in patterns:
|
|
118
|
+
if fnmatch.fnmatch(f, p):
|
|
119
|
+
return 1
|
|
120
|
+
return 0
|
|
121
|
+
|
|
122
|
+
conn.create_function("match_files", 2, _match_any_file)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
This allows the SQLite query planner to filter rows atomically in a single pass at the database layer before sorting by relevance and recency.
|
|
126
|
+
|
|
127
|
+
### Decision lineage with recursive CTEs
|
|
128
|
+
|
|
129
|
+
When conflicting decisions are merged or updated during human review, older decisions are soft-archived rather than overwritten. Lineage is tracked through `parent_decision_id`, allowing complete evolutionary trees to be reconstructed using recursive Common Table Expressions:
|
|
130
|
+
|
|
131
|
+
```sql
|
|
132
|
+
WITH RECURSIVE ancestors(id, decision, parent_decision_id) AS (
|
|
133
|
+
SELECT id, decision, parent_decision_id FROM decisions WHERE id = ?
|
|
134
|
+
UNION ALL
|
|
135
|
+
SELECT d.id, d.decision, d.parent_decision_id
|
|
136
|
+
FROM decisions d JOIN ancestors a ON d.id = a.parent_decision_id
|
|
137
|
+
)
|
|
138
|
+
SELECT * FROM ancestors;
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## Quickstart
|
|
144
|
+
|
|
145
|
+
### 1. Install Klyd
|
|
146
|
+
|
|
147
|
+
> **0.2.4 is the current release.** The 0.2.2 wheel was missing its hook
|
|
148
|
+
> templates and SQL schema; 0.2.3 fixed packaging, and 0.2.4 fixes the CLI
|
|
149
|
+
> defects found by exercising every command against the published wheel.
|
|
150
|
+
> Install the current release:
|
|
151
|
+
>
|
|
152
|
+
> ```bash
|
|
153
|
+
> pip install klyd==0.2.4
|
|
154
|
+
> ```
|
|
155
|
+
|
|
156
|
+
### 2. Initialize a repository
|
|
157
|
+
|
|
158
|
+
Run inside the root of your Git repository:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
kl init
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
This creates `.klyd/memory.db`, initializes the configuration file, and installs the Git hooks into `.git/hooks/`.
|
|
165
|
+
|
|
166
|
+
### 3. Configure a model provider
|
|
167
|
+
|
|
168
|
+
Set your preferred API key (BYOK):
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
kl config --api-key sk-ant-...
|
|
172
|
+
# or: kl config --openai-key sk-...
|
|
173
|
+
# or: kl config --gemini-key ...
|
|
174
|
+
# or: kl config --groq-key ...
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Inspect active configuration:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
kl config --show
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
### 4. Record decisions from commits
|
|
184
|
+
|
|
185
|
+
Decisions are automatically extracted by the `post-commit` hook whenever you make a Git commit:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
git commit -m "refactor(db): use SQLite connection pooling instead of global instances"
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
You can also trigger extraction manually for the latest commit:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
kl extract-commit
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### 5. Retrieve relevant decisions
|
|
198
|
+
|
|
199
|
+
View stored architectural decisions in a table:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
kl status
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Filter decisions by search keyword:
|
|
206
|
+
|
|
207
|
+
```bash
|
|
208
|
+
kl status --search "database"
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
View decisions grouped by module hierarchy:
|
|
212
|
+
|
|
213
|
+
```bash
|
|
214
|
+
kl status --tree
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
### 6. Run an agent with decision memory
|
|
218
|
+
|
|
219
|
+
Launch your coding agent wrapped with Klyd context:
|
|
220
|
+
|
|
221
|
+
```bash
|
|
222
|
+
kl run aider
|
|
223
|
+
```
|
|
224
|
+
|
|
225
|
+
For custom agent invocations, generate the injection context directly:
|
|
226
|
+
|
|
227
|
+
```bash
|
|
228
|
+
kl prepare-injection
|
|
229
|
+
# Context is written to .klyd/injection.txt
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Commands reference
|
|
235
|
+
|
|
236
|
+
| Command | Description |
|
|
237
|
+
|---|---|
|
|
238
|
+
| `kl init` | Initialise `.klyd/` storage and install Git hooks. |
|
|
239
|
+
| `kl config` | Configure model API keys, templates, and extraction thresholds. |
|
|
240
|
+
| `kl extract-commit` | Extract architectural decisions from the latest Git commit. |
|
|
241
|
+
| `kl prepare-injection` | Query matching decisions for staged files and generate `.klyd/injection.txt`. |
|
|
242
|
+
| `kl preview-injection` | Preview the injection prompt without writing it to disk. |
|
|
243
|
+
| `kl status` | Display active decisions, conflict summaries, and drift statistics. |
|
|
244
|
+
| `kl review` | Interactive CLI to resolve flagged architectural conflicts (`accept`, `merge`, `edit`, `reject`). |
|
|
245
|
+
| `kl pin <id>` | Pin a non-negotiable architectural constraint so it is always injected. |
|
|
246
|
+
| `kl unpin <id>` | Remove a pinned decision constraint. |
|
|
247
|
+
| `kl run <agent>` | Execute a coding agent with memory injected via command-line arguments. |
|
|
248
|
+
| `kl metrics` | Display aggregated decision counts, average confidence, and conflict rates. |
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
## Current status
|
|
253
|
+
|
|
254
|
+
Klyd is an actively developed developer-tooling project (v0.2.4 distributed on PyPI).
|
|
255
|
+
|
|
256
|
+
The current implementation is focused on local decision persistence, retrieval, Git lifecycle integration, and terminal coding-agent workflows.
|
|
257
|
+
|
|
258
|
+
- **Local scope**: Designed for single-developer repository workspaces. Remote peer sync and multi-user concurrent locking are not included.
|
|
259
|
+
- **LLM extraction dependency**: Quality of extracted decisions correlates with commit message clarity and the reasoning capabilities of the configured model.
|
|
260
|
+
- **Agent support**: Native argument injection is configured for `aider` and `opencode`; other agents receive the injection as a final positional argument. The same text is written to `.klyd/injection.txt` for agents that take a context-file flag.
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## License
|
|
265
|
+
|
|
266
|
+
MIT License — see [LICENSE](./LICENSE).
|