fixtureforge 2.2.0__tar.gz → 2.3.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.
Files changed (58) hide show
  1. fixtureforge-2.3.0/PKG-INFO +455 -0
  2. fixtureforge-2.3.0/README.md +417 -0
  3. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/pyproject.toml +6 -3
  4. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/__init__.py +422 -424
  5. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/core/batch_engine.py +23 -3
  6. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/core/exporter.py +5 -5
  7. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/core/generator.py +111 -3
  8. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/core/router.py +3 -2
  9. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/core/swarm.py +144 -139
  10. fixtureforge-2.3.0/src/fixtureforge/enterprise/__init__.py +60 -0
  11. fixtureforge-2.3.0/src/fixtureforge/enterprise/airgap.py +196 -0
  12. fixtureforge-2.3.0/src/fixtureforge/enterprise/forge_enterprise.py +251 -0
  13. fixtureforge-2.3.0/src/fixtureforge/enterprise/provenance.py +182 -0
  14. fixtureforge-2.3.0/src/fixtureforge/enterprise/tenancy.py +148 -0
  15. fixtureforge-2.3.0/src/fixtureforge/mcp_server.py +310 -0
  16. fixtureforge-2.2.0/PKG-INFO +0 -433
  17. fixtureforge-2.2.0/README.md +0 -399
  18. fixtureforge-2.2.0/src/fixtureforge/pyproject.toml +0 -15
  19. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/LICENSE +0 -0
  20. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/ai/__init__.py +0 -0
  21. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/ai/_audit_log.py +0 -0
  22. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/ai/_groq_client.py +0 -0
  23. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/ai/cache.py +0 -0
  24. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/ai/engine.py +0 -0
  25. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/ai/failure_analyzer.py +0 -0
  26. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/ai/prompts.py +0 -0
  27. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/ai/semantic_assert.py +0 -0
  28. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/cli/__init__.py +0 -0
  29. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/cli/commands.py +0 -0
  30. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/config/__init__.py +0 -0
  31. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/config/flags.py +0 -0
  32. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/core/__init__.py +0 -0
  33. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/core/analyzer.py +0 -0
  34. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/core/compression.py +0 -0
  35. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/core/dataset.py +0 -0
  36. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/core/parser.py +0 -0
  37. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/core/recipe.py +0 -0
  38. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/core/streamer.py +0 -0
  39. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/integrations/__init__.py +0 -0
  40. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/integrations/github.py +0 -0
  41. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/integrations/jira.py +0 -0
  42. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/library/__init__.py +0 -0
  43. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/library/sharing.py +0 -0
  44. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/library/storage.py +0 -0
  45. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/memory/__init__.py +0 -0
  46. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/memory/dream.py +0 -0
  47. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/memory/store.py +0 -0
  48. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/providers/__init__.py +0 -0
  49. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/providers/anthropic.py +0 -0
  50. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/providers/base.py +0 -0
  51. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/providers/factory.py +0 -0
  52. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/providers/gemini.py +0 -0
  53. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/providers/groq.py +0 -0
  54. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/providers/ollama.py +0 -0
  55. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/providers/openai.py +0 -0
  56. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/pytest_plugin.py +0 -0
  57. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/security/__init__.py +0 -0
  58. {fixtureforge-2.2.0 → fixtureforge-2.3.0}/src/fixtureforge/security/permissions.py +0 -0
@@ -0,0 +1,455 @@
1
+ Metadata-Version: 2.4
2
+ Name: fixtureforge
3
+ Version: 2.3.0
4
+ Summary: Agentic Test Data Harness: memory, multi-agent swarms, permission gates, coverage analysis. Provider-agnostic (Gemini, OpenAI, Anthropic, Ollama).
5
+ License: MIT
6
+ License-File: LICENSE
7
+ Keywords: pytest,fixtures,test-data,pydantic,faker,factory,ai,testing,mock-data,qa,automation,synthetic-data,llm,test-fixtures,fixture-generator
8
+ Author: Yaniv Metuku
9
+ Requires-Python: >=3.11,<4.0
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Classifier: Programming Language :: Python :: 3.13
15
+ Classifier: Programming Language :: Python :: 3.14
16
+ Classifier: Programming Language :: Python :: 3.15
17
+ Provides-Extra: all
18
+ Provides-Extra: anthropic
19
+ Provides-Extra: gemini
20
+ Provides-Extra: mcp
21
+ Provides-Extra: openai
22
+ Provides-Extra: sql
23
+ Requires-Dist: anthropic (>=0.18.0,<0.19.0) ; extra == "anthropic" or extra == "all"
24
+ Requires-Dist: click (>=8.1.0,<9.0.0)
25
+ Requires-Dist: faker (>=22.0.0,<23.0.0)
26
+ Requires-Dist: google-genai (>=1.0.0,<2.0.0) ; extra == "gemini" or extra == "all"
27
+ Requires-Dist: mcp (>=2.0.0,<3.0.0) ; extra == "mcp" or extra == "all"
28
+ Requires-Dist: openai (>=1.0.0,<2.0.0) ; extra == "openai" or extra == "all"
29
+ Requires-Dist: pydantic (>=2.5.0,<3.0.0)
30
+ Requires-Dist: pyyaml (>=6.0,<7.0)
31
+ Requires-Dist: requests (>=2.31.0,<3.0.0)
32
+ Requires-Dist: rich (>=13.7.0,<14.0.0)
33
+ Requires-Dist: sqlalchemy (>=2.0.0,<3.0.0) ; extra == "sql" or extra == "all"
34
+ Project-URL: Homepage, https://fixtureforge.dev
35
+ Project-URL: Repository, https://github.com/Yaniv2809/fixtureforge
36
+ Description-Content-Type: text/markdown
37
+
38
+ <p align="center">
39
+ <img src="fixtureforge-logo.png" alt="FixtureForge" width="360"/>
40
+ </p>
41
+
42
+ <h1 align="center">FixtureForge</h1>
43
+ <p align="center"><b>Agentic test data harness for Python — deterministic in CI, AI-powered in dev.</b></p>
44
+
45
+ <p align="center">
46
+ <a href="https://pypi.org/project/fixtureforge/"><img src="https://img.shields.io/pypi/v/fixtureforge.svg" alt="PyPI version"/></a>
47
+ <a href="https://pypi.org/project/fixtureforge/"><img src="https://img.shields.io/pypi/dm/fixtureforge.svg" alt="Downloads"/></a>
48
+ <a href="https://www.python.org/"><img src="https://img.shields.io/badge/python-3.11%2B-blue.svg" alt="Python 3.11+"/></a>
49
+ <a href="https://pypi.org/project/fixtureforge/"><img src="https://img.shields.io/badge/pytest-plugin-orange.svg" alt="pytest plugin"/></a>
50
+ <a href="LICENSE"><img src="https://img.shields.io/badge/License-MIT-green.svg" alt="MIT License"/></a>
51
+ </p>
52
+
53
+ ---
54
+
55
+ ## The problem with test data today
56
+
57
+ ```python
58
+ # ❌ Everyone does this. It's brittle and misses real-world edge cases.
59
+ user = User(name="Test User", email="test@test.com", bio="Lorem ipsum...")
60
+
61
+ # ❌ factory_boy is great — but it's static. No surprises, no edge cases.
62
+ UserFactory.create(role="admin")
63
+
64
+ # ❌ Writing 500 of them by hand? Not happening.
65
+ ```
66
+
67
+ Hardcoded fixtures rot. AI-generated fixtures are unpredictable in CI.
68
+ **FixtureForge solves both** — same codebase, two behaviors:
69
+
70
+ ```
71
+ Dev mode → AI generates rich, realistic, edge-case-aware fixtures
72
+ CI mode → same fixtures, frozen with seed=42, 100% reproducible
73
+ ```
74
+
75
+ ---
76
+
77
+ ## Quickstart
78
+
79
+ ```bash
80
+ pip install fixtureforge
81
+ ```
82
+
83
+ ```python
84
+ from fixtureforge import Forge
85
+ from pydantic import BaseModel
86
+
87
+ class User(BaseModel):
88
+ id: int
89
+ name: str
90
+ email: str
91
+ bio: str
92
+
93
+ forge = Forge() # auto-detects AI provider from env vars
94
+ users = forge.create_batch(User, count=50, context="SaaS platform users")
95
+ ```
96
+
97
+ FixtureForge routes each field to the cheapest generator automatically:
98
+
99
+ - **`id`** → sequential counter *(free)*
100
+ - **`name`, `email`** → Faker *(free)*
101
+ - **`bio`** → single batched AI call for all 50 records *(1 API call, not 50)*
102
+
103
+ **No AI key? No problem.** Pure Faker mode works out of the box:
104
+
105
+ ```python
106
+ forge = Forge(use_ai=False, seed=42) # deterministic, zero network, CI-safe
107
+ users = forge.create_batch(User, count=500)
108
+ ```
109
+
110
+ ---
111
+
112
+ ## Intelligent Field Routing
113
+
114
+ Every field is classified into a tier. Only semantic fields hit the AI:
115
+
116
+ | Tier | Fields | Generator | Cost |
117
+ |------|--------|-----------|------|
118
+ | **Structural** | `id`, `user_id`, `order_id` | Counters + FK registry | Free |
119
+ | **Standard** | `name`, `email`, `phone`, `address` | Faker | Free |
120
+ | **Computed** | `@computed_field` | Pydantic | Free |
121
+ | **Semantic** | `bio`, `description`, `review`, `message` | LLM (batched) | API tokens |
122
+
123
+ 100 users with 2 semantic fields = **2 API calls**, not 200.
124
+
125
+ ---
126
+
127
+ ## CI/CD — zero config changes between environments
128
+
129
+ ```yaml
130
+ # .github/workflows/test.yml
131
+ - name: Run tests
132
+ env:
133
+ FORGE_SEED: 42 # identical output every run
134
+ # No AI key needed — FixtureForge auto-detects and falls back to Faker
135
+ run: pytest
136
+ ```
137
+
138
+ In dev, export any provider key and AI kicks in automatically:
139
+
140
+ ```bash
141
+ export ANTHROPIC_API_KEY=sk-ant-... # → Claude
142
+ export OPENAI_API_KEY=sk-... # → GPT
143
+ export GOOGLE_API_KEY=... # → Gemini
144
+ export GROQ_API_KEY=... # → Groq (fast + cheap)
145
+ ```
146
+
147
+ ---
148
+
149
+ ## Foreign Key Relationships — automatic
150
+
151
+ ```python
152
+ # Step 1: generate customers
153
+ customers = forge.create_batch(Customer, count=10)
154
+
155
+ # Step 2: Order.customer_id auto-resolves to a real customer.id
156
+ orders = forge.create_batch(Order, count=100)
157
+ # → every order.customer_id is valid. No manual wiring.
158
+ ```
159
+
160
+ ---
161
+
162
+ ## DataSwarms — bulk generation, shared cache
163
+
164
+ Generate multiple models in parallel. The first model warms the AI cache;
165
+ every subsequent model inherits it — **~90% cheaper per additional model**.
166
+
167
+ ```python
168
+ results = forge.swarm(
169
+ models=[User, Order, Product, Payment],
170
+ counts=[10, 50, 100, 30],
171
+ contexts=["SaaS users", "E-commerce orders", None, None],
172
+ )
173
+ # {
174
+ # "User": [...10 users...],
175
+ # "Order": [...50 orders...],
176
+ # "Product": [...100 products...],
177
+ # "Payment": [...30 payments...],
178
+ # }
179
+ ```
180
+
181
+ 5 models ≈ cost of 1.5 models.
182
+
183
+ ---
184
+
185
+ ## ForgeMemory — fixtures that remember your domain
186
+
187
+ ```python
188
+ forge.memory.add_rule("financial", "Users under 18 get restricted account type")
189
+ forge.memory.add_rule("user", "Israeli phone numbers use format 05x-xxx-xxxx")
190
+ forge.memory.add_rule("orders", "Max 3 active loans per customer at any time")
191
+
192
+ # Rules inject into AI prompts automatically on every generation call
193
+ users = forge.create_batch(User, count=50, context="Israeli SaaS platform")
194
+ ```
195
+
196
+ Rules survive across sessions. Update a rule — next call respects it immediately.
197
+ **Skeptical Memory** validates stored rules against the live schema before every call.
198
+
199
+ ---
200
+
201
+ ## pytest plugin — one line per fixture
202
+
203
+ ```python
204
+ # conftest.py
205
+ from fixtureforge.pytest_plugin import forge_fixture, forge_swarm_fixture
206
+ from pydantic import BaseModel
207
+
208
+ class User(BaseModel):
209
+ id: int; name: str; email: str
210
+
211
+ forge_fixture(User, count=10, seed=42) # → fixture: "users"
212
+ forge_swarm_fixture([User, Order], counts=[5, 20], seed=42) # → "swarm_data"
213
+ ```
214
+
215
+ ```python
216
+ # test_users.py
217
+ def test_signup(users):
218
+ for user in users:
219
+ assert "@" in user.email
220
+
221
+ def test_full_flow(swarm_data):
222
+ users = swarm_data["User"]
223
+ orders = swarm_data["Order"]
224
+ ```
225
+
226
+ The `forge` fixture is auto-available in every test with zero config.
227
+
228
+ ---
229
+
230
+ ## Multi-provider support
231
+
232
+ ```python
233
+ # Be explicit
234
+ forge = Forge(provider_name="anthropic", model="claude-haiku-4-5-20251001")
235
+ forge = Forge(provider_name="openai", model="gpt-4o-mini")
236
+ forge = Forge(provider_name="gemini", model="gemini-2.0-flash")
237
+ forge = Forge(provider_name="groq", model="llama-3.3-70b-versatile")
238
+ forge = Forge(provider_name="ollama", model="llama3.2") # local, zero cost
239
+ forge = Forge(use_ai=False) # pure Faker
240
+ ```
241
+
242
+ ---
243
+
244
+ ## Large datasets — constant AI cost regardless of count
245
+
246
+ ```python
247
+ # Seed + Interpolation: generates ~1 000 unique AI values, tiles to 100 000
248
+ dataset = forge.create_large(Order, count=100_000, seed_ratio=0.01)
249
+
250
+ # Streaming — one record at a time, never loads all into memory
251
+ for user in forge.create_stream(User, count=1_000_000, filename="users.json"):
252
+ process(user)
253
+ ```
254
+
255
+ ---
256
+
257
+ ## Export
258
+
259
+ ```python
260
+ from fixtureforge.core.exporter import DataExporter
261
+
262
+ users = forge.create_batch(User, count=100)
263
+ DataExporter.export(users, "users.json") # format inferred from extension
264
+ DataExporter.export(users, "users.csv")
265
+ DataExporter.export(users, "users.sql")
266
+ ```
267
+
268
+ ---
269
+
270
+ ## FixtureForge vs alternatives
271
+
272
+ | | FixtureForge | factory\_boy | Faker | hypothesis |
273
+ |--|:--:|:--:|:--:|:--:|
274
+ | AI-powered context | ✅ | ❌ | ❌ | ❌ |
275
+ | Deterministic (seed=) | ✅ | ✅ | ✅ | ✅ |
276
+ | FK relationships | **Auto** | Manual | ❌ | ❌ |
277
+ | Batched AI calls | ✅ | ❌ | ❌ | ❌ |
278
+ | Coverage gap analysis | ✅ | ❌ | ❌ | Partial |
279
+ | Large datasets (100k+) | ✅ | Manual | Manual | ❌ |
280
+ | pytest plugin | ✅ | ❌ | ❌ | ❌ |
281
+ | Multi-LLM support | ✅ | ❌ | ❌ | ❌ |
282
+ | Permission gates | ✅ | ❌ | ❌ | ❌ |
283
+ | CI-safe (zero network) | ✅ | ✅ | ✅ | ✅ |
284
+
285
+ FixtureForge is not a replacement for Faker — it uses Faker internally for standard fields.
286
+ It adds the layer between *"I need realistic data"* and *"I need it to feel like production."*
287
+
288
+ ---
289
+
290
+ ## Installation
291
+
292
+ ```bash
293
+ # Core (deterministic mode, no AI)
294
+ pip install fixtureforge
295
+
296
+ # With your preferred provider
297
+ pip install "fixtureforge[anthropic]" # Claude
298
+ pip install "fixtureforge[openai]" # GPT
299
+ pip install "fixtureforge[gemini]" # Gemini
300
+ pip install "fixtureforge[all]" # All providers
301
+ ```
302
+
303
+ **Requirements:** Python 3.11+ · pydantic ≥ 2.5 · faker ≥ 22.0
304
+
305
+ ---
306
+
307
+ ## Enterprise Edition
308
+
309
+ For teams with compliance requirements — GDPR, SOC2, HIPAA, multi-tenant SaaS:
310
+
311
+ | | Community | Enterprise |
312
+ |--|:--:|:--:|
313
+ | AI generation + Faker | ✅ | ✅ |
314
+ | pytest plugin | ✅ | ✅ |
315
+ | Deterministic seeding | ✅ | ✅ |
316
+ | **Cryptographic Provenance Envelope** | ❌ | ✅ |
317
+ | **PII Airgap — fail-closed scanner** | ❌ | ✅ |
318
+ | **Contextual Tenant Enclaves** | ❌ | ✅ |
319
+ | **Cross-tenant FK violation detection** | ❌ | ✅ |
320
+ | **Presidio / custom scanner support** | ❌ | ✅ |
321
+
322
+ ```python
323
+ from fixtureforge.enterprise import ForgeEnterprise
324
+
325
+ forge = ForgeEnterprise(use_ai=False)
326
+ users = forge.create_batch(User, count=10)
327
+
328
+ users[0].model_dump()
329
+ # { "id": 1, "name": "...", "bio": "...",
330
+ # "forge_metadata": {
331
+ # "forge_id": "abc-123",
332
+ # "provenance_hash": "sha256:029773ed...", ← immutable audit stamp
333
+ # "tenant_id": "tenant-acme",
334
+ # "source": "faker",
335
+ # ...
336
+ # }
337
+ # }
338
+
339
+ with forge.isolate_tenant("tenant-acme"):
340
+ acme_users = forge.create_batch(User, count=5)
341
+ # FK references from tenant-acme can NEVER resolve to tenant-xyz records
342
+ ```
343
+
344
+ **Access:** [yaniv2809@gmail.com](mailto:yaniv2809@gmail.com)
345
+
346
+ ---
347
+
348
+ ## Project status
349
+
350
+ | Component | Status |
351
+ |-----------|--------|
352
+ | Core (`Forge`, `create_batch`) | ✅ Stable |
353
+ | DataSwarms | ✅ Stable |
354
+ | ForgeMemory | ✅ Stable |
355
+ | pytest plugin | ✅ v2.2.0 |
356
+ | Anthropic / OpenAI / Gemini / Groq / Ollama | ✅ |
357
+ | Literal / Enum / date / datetime / UUID / Decimal | ✅ v2.2.0 |
358
+ | MCP Server (`fixtureforge-mcp`) | ✅ v2.3.0 |
359
+ | `assert_semantic_match` | ✅ v2.2.0 |
360
+ | `SmartFailureAnalyzer` | ✅ v2.2.0 |
361
+ | Enterprise Edition | ✅ (access by request) |
362
+ | ForgeDream (coverage analysis) | 🔜 Feature-flagged |
363
+ | Async support | 🔜 Planned |
364
+
365
+ ---
366
+
367
+ ## Links
368
+
369
+ - **Docs**: https://yaniv2809.github.io/fixtureforge/
370
+ - **PyPI**: https://pypi.org/project/fixtureforge/
371
+ - **Repository**: https://github.com/Yaniv2809/fixtureforge
372
+ - **Issues**: https://github.com/Yaniv2809/fixtureforge/issues
373
+ - **Discussion**: https://github.com/Yaniv2809/fixtureforge/discussions/1
374
+
375
+ ---
376
+
377
+ ## MCP Server — use FixtureForge inside Claude Desktop / any MCP client
378
+
379
+ FixtureForge ships a built-in MCP server so Claude Desktop and other MCP-capable
380
+ AI tools can generate test data directly in a conversation.
381
+
382
+ ### Install
383
+
384
+ ```bash
385
+ pip install "fixtureforge[mcp]"
386
+ ```
387
+
388
+ ### Add to Claude Desktop (`claude_desktop_config.json`)
389
+
390
+ ```json
391
+ {
392
+ "mcpServers": {
393
+ "fixtureforge": {
394
+ "command": "fixtureforge-mcp"
395
+ }
396
+ }
397
+ }
398
+ ```
399
+
400
+ Restart Claude Desktop — FixtureForge appears in the tool list automatically.
401
+
402
+ ### Available tools
403
+
404
+ | Tool | What it does |
405
+ |------|-------------|
406
+ | `generate` | Generate N records for a model described by `{field: type}` |
407
+ | `swarm` | Generate multiple models in parallel with shared AI cache |
408
+ | `add_rule` | Persist a domain rule injected into every AI prompt |
409
+ | `export` | Generate records and save to `.json`, `.csv`, or `.sql` |
410
+
411
+ ### Example prompt to Claude
412
+
413
+ > "Use fixtureforge to generate 20 User records with id, name, email and bio fields,
414
+ > then export them to users.json"
415
+
416
+ ---
417
+
418
+ ## Use with AI coding agents
419
+
420
+ FixtureForge ships an official agent skill so AI coding assistants (Claude Code,
421
+ Cursor, GitHub Copilot, Devin, etc.) know exactly how to use the library.
422
+
423
+ The skill lives at [`skills/fixtureforge/SKILL.md`](skills/fixtureforge/SKILL.md)
424
+ and covers: when to use FixtureForge, install & setup, core API, CI determinism,
425
+ FK wiring, pytest plugin, common mistakes, and provider names.
426
+
427
+ Agents working in a repo that uses FixtureForge will automatically pick up the
428
+ skill and avoid the most common mistakes (hardcoded generators, manual FK wiring,
429
+ `use_ai=True` in CI).
430
+
431
+ ---
432
+
433
+ ## Contributing
434
+
435
+ Issues and PRs welcome.
436
+
437
+ ```bash
438
+ git clone https://github.com/Yaniv2809/fixtureforge
439
+ cd fixtureforge
440
+ pip install -e ".[dev]"
441
+ PYTHONPATH=src python -m pytest tests/
442
+ ```
443
+
444
+ ---
445
+
446
+ ## License
447
+
448
+ MIT © [Yaniv2809](https://github.com/Yaniv2809)
449
+
450
+ ---
451
+
452
+ <p align="center">
453
+ <b>If FixtureForge saved you time, give it a ⭐ — it helps others find it.</b>
454
+ </p>
455
+