spec-agent 0.1.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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vishesh Chaitanya
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.
@@ -0,0 +1,390 @@
1
+ Metadata-Version: 2.4
2
+ Name: spec-agent
3
+ Version: 0.1.0
4
+ Summary: Auto-generate an Obsidian knowledge wiki from every git push, powered by Claude
5
+ Author-email: Vishesh Chaitanya <visheshchaitanya@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/visheshchaitanya/spec-agent
8
+ Project-URL: Repository, https://github.com/visheshchaitanya/spec-agent
9
+ Project-URL: Issues, https://github.com/visheshchaitanya/spec-agent/issues
10
+ Keywords: obsidian,wiki,git,documentation,anthropic,claude,ai,developer-tools
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: Software Development :: Documentation
20
+ Classifier: Topic :: Software Development :: Version Control :: Git
21
+ Classifier: Topic :: Utilities
22
+ Requires-Python: >=3.11
23
+ Description-Content-Type: text/markdown
24
+ License-File: LICENSE
25
+ Requires-Dist: anthropic>=0.40.0
26
+ Requires-Dist: click>=8.1
27
+ Requires-Dist: pyyaml>=6.0
28
+ Requires-Dist: python-frontmatter>=1.1
29
+ Requires-Dist: rich>=13.0
30
+ Provides-Extra: dev
31
+ Requires-Dist: pytest>=8.0; extra == "dev"
32
+ Requires-Dist: pytest-cov>=5.0; extra == "dev"
33
+ Dynamic: license-file
34
+
35
+ # spec-agent
36
+
37
+ > Auto-generate an Obsidian knowledge wiki from every `git push` — powered by Claude.
38
+
39
+ Every time you push code, **spec-agent** reads the diff, classifies the change, and writes a structured spec document into your [Obsidian](https://obsidian.md) vault. Over time, your vault becomes a living, visually-navigable graph of everything you've ever built.
40
+
41
+ Inspired by [Andrej Karpathy's LLM Wiki pattern](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f): the LLM acts as a compiler (raw commits → structured wiki), not a retrieval engine. No RAG, no embeddings — just well-organized markdown with `[[wikilinks]]` that Obsidian renders as a knowledge graph.
42
+
43
+ ---
44
+
45
+ ## How It Works
46
+
47
+ ```
48
+ git push
49
+ └── ~/.git-hooks/post-push ← global hook, fires on every repo
50
+ └── spec-agent run ← Python CLI
51
+ └── Claude (tool-use) ← agentic loop
52
+ ├── classify_commit
53
+ ├── search_wiki ← finds related existing pages
54
+ ├── read_wiki_file ← reads context before updating
55
+ ├── write_wiki_file ← creates or updates spec
56
+ └── update_index ← appends row to index.md
57
+ ```
58
+
59
+ The agent:
60
+ 1. Classifies the commit type (`feature`, `bug`, `refactor`, `arch`, `chore`)
61
+ 2. Searches your vault for related pages to link to
62
+ 3. Writes an adaptive spec using the appropriate template
63
+ 4. Updates `index.md` — the master log that Claude reads at session start
64
+
65
+ **Chore commits are skipped.** Bot branches (`dependabot/*`, `renovate/*`) are skipped. Tiny commits (below a configurable character threshold) are skipped.
66
+
67
+ ---
68
+
69
+ ## Features
70
+
71
+ - **Zero friction** — fires automatically on every `git push`, no developer action needed
72
+ - **Adaptive templates** — selects the right format based on commit type
73
+ - `feature` → full spec (summary, problem, implementation, files, open questions)
74
+ - `bug` → short report (root cause, fix applied)
75
+ - `refactor` → brief note (what changed, why, before/after)
76
+ - `arch` → ADR format (context, decision, consequences, alternatives)
77
+ - **Accurate `[[wikilinks]]`** — searches vault for existing pages before writing, so links are real
78
+ - **Living index** — `index.md` is a table of every spec ever written; share it with Claude at session start to give it full project memory
79
+ - **Obsidian graph** — concepts referenced by many specs become visual hubs after 10+ specs
80
+ - **Works on every repo** — one global hook installation covers all your projects
81
+
82
+ ---
83
+
84
+ ## Prerequisites
85
+
86
+ - **Python 3.11+**
87
+ - **An Anthropic API key** — [get one here](https://console.anthropic.com)
88
+ - **Obsidian** — [download here](https://obsidian.md) (free)
89
+ - **Git 2.9+** (for `core.hooksPath` support)
90
+
91
+ ---
92
+
93
+ ## Installation
94
+
95
+ ### From PyPI (recommended)
96
+
97
+ ```bash
98
+ pip install spec-agent
99
+ ```
100
+
101
+ ### From source
102
+
103
+ ```bash
104
+ git clone https://github.com/visheshchaitanya/spec-agent.git ~/.spec-agent
105
+ pip install -e ~/.spec-agent
106
+ ```
107
+
108
+ ---
109
+
110
+ ## Setup
111
+
112
+ ### 1. Set your API key
113
+
114
+ ```bash
115
+ export ANTHROPIC_API_KEY="sk-ant-..."
116
+ ```
117
+
118
+ Add this to your shell profile (`~/.zshrc`, `~/.bashrc`, or `~/.zshenv`) to make it permanent:
119
+
120
+ ```bash
121
+ echo 'export ANTHROPIC_API_KEY="sk-ant-..."' >> ~/.zshrc
122
+ ```
123
+
124
+ ### 2. Initialize your vault
125
+
126
+ ```bash
127
+ spec-agent init --vault ~/Documents/dev-wiki
128
+ ```
129
+
130
+ This creates the vault directory structure and writes a default `~/.spec-agent/config.yaml`.
131
+
132
+ Then open `~/Documents/dev-wiki` as a vault in Obsidian (**File → Open vault as folder**).
133
+
134
+ ### 3. Install the global git hook
135
+
136
+ ```bash
137
+ spec-agent install-hook
138
+ ```
139
+
140
+ This creates `~/.git-hooks/post-push` and sets `git config --global core.hooksPath ~/.git-hooks`. The hook fires on every push in every repository on your machine.
141
+
142
+ ### 4. Push anything to test
143
+
144
+ ```bash
145
+ cd ~/any-repo
146
+ git push
147
+ # → spec-agent fires in the background
148
+ # → spec appears in ~/Documents/dev-wiki
149
+ ```
150
+
151
+ ---
152
+
153
+ ## Configuration
154
+
155
+ Config lives at `~/.spec-agent/config.yaml`:
156
+
157
+ ```yaml
158
+ vault_path: ~/Documents/dev-wiki
159
+ model: claude-sonnet-4-6
160
+ ignored_repos: [] # list of repo names to skip entirely
161
+ ignored_branches:
162
+ - dependabot/*
163
+ - renovate/*
164
+ min_commit_chars: 50 # skip pushes where total commit message length is below this
165
+ ```
166
+
167
+ | Key | Default | Description |
168
+ |-----|---------|-------------|
169
+ | `vault_path` | `~/Documents/dev-wiki` | Absolute path to your Obsidian vault |
170
+ | `model` | `claude-sonnet-4-6` | Anthropic model to use |
171
+ | `ignored_repos` | `[]` | Exact repo names to never process |
172
+ | `ignored_branches` | `[dependabot/*, renovate/*]` | Glob patterns — matching branches are skipped |
173
+ | `min_commit_chars` | `50` | Skip pushes where total commit message length is below this (filters "wip", "fix typo") |
174
+
175
+ ---
176
+
177
+ ## Vault Structure
178
+
179
+ ```
180
+ ~/Documents/dev-wiki/
181
+ ├── index.md ← master log — give this to Claude at session start
182
+ ├── features/
183
+ │ ├── alert-ingestion.md
184
+ │ └── auth-system.md
185
+ ├── bugs/
186
+ │ ├── fix-status-migration.md
187
+ │ └── fix-null-pointer.md
188
+ ├── refactors/
189
+ │ └── extract-auth-middleware.md
190
+ ├── concepts/ ← auto-created graph hubs when first referenced
191
+ │ ├── clickhouse.md
192
+ │ └── jwt.md
193
+ └── projects/
194
+ └── my-app.md
195
+ ```
196
+
197
+ ### index.md — your project memory
198
+
199
+ `index.md` is a markdown table of every spec ever written:
200
+
201
+ ```markdown
202
+ # Dev Wiki — Index
203
+
204
+ | Date | Type | Title | Project | Link |
205
+ |------|------|-------|---------|------|
206
+ | 2026-04-07 | bug | Fix status migration | my-app | [[bugs/fix-status-migration]] |
207
+ | 2026-04-05 | feature | Alert ingestion pipeline | my-app | [[features/alert-ingestion]] |
208
+ ```
209
+
210
+ Paste the contents of `index.md` at the start of any Claude session — Claude immediately knows everything you've built across all projects.
211
+
212
+ ### Spec frontmatter
213
+
214
+ Every generated spec has YAML frontmatter:
215
+
216
+ ```yaml
217
+ ---
218
+ type: feature
219
+ project: my-app
220
+ date: 2026-04-07
221
+ commit: a3f9c12
222
+ status: shipped
223
+ ---
224
+ ```
225
+
226
+ ---
227
+
228
+ ## Giving Claude context at session start
229
+
230
+ Paste this into your Claude session to give it full project memory:
231
+
232
+ ```
233
+ Here is my dev wiki index — everything I've built:
234
+
235
+ <paste contents of ~/Documents/dev-wiki/index.md>
236
+
237
+ I'm working on <task>. Based on the index, what related specs should I look at?
238
+ ```
239
+
240
+ Claude can then ask you to paste specific spec files for deeper context.
241
+
242
+ ---
243
+
244
+ ## CLI Reference
245
+
246
+ ```
247
+ spec-agent [COMMAND] [OPTIONS]
248
+
249
+ Commands:
250
+ run Run the agent (called automatically by git hook)
251
+ init Initialize vault directory and write config
252
+ install-hook Install global git post-push hook
253
+ config-get Read a config value (used internally by hook)
254
+ ```
255
+
256
+ ### `spec-agent run`
257
+
258
+ ```
259
+ Options:
260
+ --repo TEXT Repository name (required)
261
+ --branch TEXT Branch that was pushed (required)
262
+ --messages TEXT Newline-separated commit messages (required)
263
+ --diff-file TEXT Path to temp file containing the git diff (required)
264
+ --config TEXT Path to config.yaml [default: ~/.spec-agent/config.yaml]
265
+ ```
266
+
267
+ ### `spec-agent init`
268
+
269
+ ```
270
+ Options:
271
+ --vault TEXT Path to Obsidian vault directory (required)
272
+ ```
273
+
274
+ ### `spec-agent install-hook`
275
+
276
+ No options. Installs `~/.git-hooks/post-push` and sets the global git hooks path.
277
+
278
+ ---
279
+
280
+ ## Manual run (without pushing)
281
+
282
+ You can run the agent manually against any repo:
283
+
284
+ ```bash
285
+ DIFF_FILE=$(mktemp /tmp/spec-agent-diff.XXXXXX)
286
+ git diff HEAD~1..HEAD | head -c 50000 > "$DIFF_FILE"
287
+
288
+ spec-agent run \
289
+ --repo "$(basename $(pwd))" \
290
+ --branch "$(git rev-parse --abbrev-ref HEAD)" \
291
+ --messages "$(git log HEAD~1..HEAD --format='%s')" \
292
+ --diff-file "$DIFF_FILE"
293
+ ```
294
+
295
+ ---
296
+
297
+ ## Per-repo opt-out
298
+
299
+ To exclude a specific repo from spec generation, add its name to `ignored_repos` in `~/.spec-agent/config.yaml`:
300
+
301
+ ```yaml
302
+ ignored_repos:
303
+ - my-private-repo
304
+ - dotfiles
305
+ ```
306
+
307
+ ---
308
+
309
+ ## Development
310
+
311
+ ### Requirements
312
+
313
+ ```bash
314
+ git clone https://github.com/visheshchaitanya/spec-agent.git
315
+ cd spec-agent
316
+ pip install -e ".[dev]"
317
+ ```
318
+
319
+ ### Run tests
320
+
321
+ ```bash
322
+ pytest
323
+ ```
324
+
325
+ ### Run tests with coverage
326
+
327
+ ```bash
328
+ pytest --cov=spec_agent --cov-report=term-missing
329
+ ```
330
+
331
+ All tests use temporary directories — no vault or API key required.
332
+
333
+ ---
334
+
335
+ ## Architecture
336
+
337
+ ### Tool-using agent loop
338
+
339
+ The agent runs an Anthropic `messages.create` loop until `stop_reason == "end_turn"`:
340
+
341
+ ```
342
+ client.messages.create(tools=TOOL_DEFINITIONS, ...)
343
+ → stop_reason == "tool_use"
344
+ → dispatch tool, collect results
345
+ → append assistant + user messages
346
+ → loop
347
+ → stop_reason == "end_turn"
348
+ → done
349
+ ```
350
+
351
+ ### Tools
352
+
353
+ | Tool | Purpose |
354
+ |------|---------|
355
+ | `classify_commit` | Agent classifies diff type and extracts concepts (no-op server-side — agent reasons internally) |
356
+ | `search_wiki` | Full-text search across vault using `grep -r` — finds related pages for wikilinks |
357
+ | `read_wiki_file` | Reads existing spec file — enables update mode instead of duplicate creation |
358
+ | `write_wiki_file` | Writes markdown to vault; `mode=update` appends a dated changelog section |
359
+ | `update_index` | Appends row to `index.md` master log |
360
+
361
+ ### Diff safety
362
+
363
+ Git diffs larger than 50,000 characters are truncated before being passed to the agent. The diff is passed via a temp file (not shell arguments) to avoid escaping issues with special characters.
364
+
365
+ ---
366
+
367
+ ## Roadmap
368
+
369
+ - [ ] GitHub webhook / cloud daemon (replace local hook with HTTP POST)
370
+ - [ ] Multi-agent parallel processing (Classifier + Writer + Linker)
371
+ - [ ] Obsidian Dataview dashboards
372
+ - [ ] Per-project vault paths
373
+ - [ ] Slack/email notifications on spec creation
374
+
375
+ ---
376
+
377
+ ## Contributing
378
+
379
+ Pull requests welcome. Please:
380
+
381
+ 1. Fork the repo and create a branch from `main`
382
+ 2. Add tests for any new behavior
383
+ 3. Ensure `pytest` passes
384
+ 4. Open a pull request
385
+
386
+ ---
387
+
388
+ ## License
389
+
390
+ [MIT](LICENSE) — © 2026 Vishesh Chaitanya