ai-wingman 0.0.4 → 1.0.0
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.
- package/LICENSE +21 -0
- package/README.md +232 -163
- package/dist/index.d.ts +117 -0
- package/dist/index.js +4052 -0
- package/dist/templates/README.md +8 -0
- package/dist/templates/agent-page.tsx +111 -0
- package/dist/templates/agent-route.ts +49 -0
- package/dist/templates/api-route-interrupt.ts +35 -0
- package/dist/templates/api-route-storage.ts +41 -0
- package/dist/templates/api-route.ts +24 -0
- package/dist/templates/audio-page-both.tsx +119 -0
- package/dist/templates/audio-page-speech-only.tsx +60 -0
- package/dist/templates/audio-page-transcribe-only.tsx +78 -0
- package/dist/templates/audio-speech-route.ts +32 -0
- package/dist/templates/audio-transcribe-route.ts +34 -0
- package/dist/templates/background-agent-enqueue-route.ts +28 -0
- package/dist/templates/background-agent-job-store.ts +55 -0
- package/dist/templates/background-agent-status-route.ts +24 -0
- package/dist/templates/background-agent-worker.ts +25 -0
- package/dist/templates/content-moderation-policy.ts +31 -0
- package/dist/templates/content-moderation-route.ts +44 -0
- package/dist/templates/conversation-by-id-route.ts +15 -0
- package/dist/templates/conversations-route.ts +16 -0
- package/dist/templates/document-processing-hook.ts +29 -0
- package/dist/templates/document-processing-route.ts +49 -0
- package/dist/templates/document-processing-schema.ts +17 -0
- package/dist/templates/eval-dataset-jsonl.ts +5 -0
- package/dist/templates/eval-dataset-runner.ts +99 -0
- package/dist/templates/eval-dataset-workflow.yml +30 -0
- package/dist/templates/eval-script.ts +112 -0
- package/dist/templates/generative-ui-page.tsx +98 -0
- package/dist/templates/generative-ui-route.ts +45 -0
- package/dist/templates/hybrid-search-bm25.ts +70 -0
- package/dist/templates/hybrid-search-reranker.ts +39 -0
- package/dist/templates/hybrid-search-route.ts +67 -0
- package/dist/templates/hybrid-search-store.ts +53 -0
- package/dist/templates/image-gen-page.tsx +82 -0
- package/dist/templates/image-gen-route.ts +25 -0
- package/dist/templates/interrupt-approval-widget.tsx +45 -0
- package/dist/templates/interrupt-page.tsx +73 -0
- package/dist/templates/interrupt-route.ts +32 -0
- package/dist/templates/interrupt-tools.ts +22 -0
- package/dist/templates/memory-inject.ts +35 -0
- package/dist/templates/memory-retrieve-route.ts +26 -0
- package/dist/templates/memory-save-route.ts +32 -0
- package/dist/templates/memory-store.ts +58 -0
- package/dist/templates/multi-agent-handoff-tools.ts +34 -0
- package/dist/templates/multi-agent-orchestrator-route.ts +35 -0
- package/dist/templates/multi-agent-specialists.ts +32 -0
- package/dist/templates/multi-agent-types.ts +11 -0
- package/dist/templates/multimodal-page.tsx +151 -0
- package/dist/templates/multimodal-route.ts +25 -0
- package/dist/templates/page-component-storage.tsx +356 -0
- package/dist/templates/page-component.tsx +273 -0
- package/dist/templates/rag-chunker.ts +64 -0
- package/dist/templates/rag-embed-route-chunked.ts +30 -0
- package/dist/templates/rag-embed-route.ts +27 -0
- package/dist/templates/rag-hook-streaming.ts +48 -0
- package/dist/templates/rag-hook.ts +31 -0
- package/dist/templates/rag-memory-store.ts +25 -0
- package/dist/templates/rag-pgvector-store.ts +30 -0
- package/dist/templates/rag-query-route-streaming.ts +34 -0
- package/dist/templates/rag-query-route.ts +34 -0
- package/dist/templates/rag-schema-sql.sql +14 -0
- package/dist/templates/rag-sqlite-store.ts +61 -0
- package/dist/templates/rag-store-pgvector.ts +28 -0
- package/dist/templates/rag-store-sqlite.ts +28 -0
- package/dist/templates/rag-store.ts +22 -0
- package/dist/templates/storage.ts +30 -0
- package/dist/templates/stream-object-hook.ts +24 -0
- package/dist/templates/stream-object-route.ts +20 -0
- package/dist/templates/structured-output-hook.ts +30 -0
- package/dist/templates/structured-output-route.ts +20 -0
- package/dist/templates/structured-output-schema.ts +12 -0
- package/dist/templates/tools-route.ts +30 -0
- package/dist/templates/tools-stub.ts +18 -0
- package/dist/wingman.js +2684 -5516
- package/package.json +12 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Yonatan Katz
|
|
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.
|
package/README.md
CHANGED
|
@@ -1,228 +1,297 @@
|
|
|
1
|
-
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src=".github/logo.svg" alt="ai-wingman logo" width="128" />
|
|
3
|
+
</p>
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
<h1 align="center">ai-wingman</h1>
|
|
4
6
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
7
|
+
<p align="center">
|
|
8
|
+
<strong>The right way to wire AI into your Next.js app.</strong>
|
|
9
|
+
</p>
|
|
10
|
+
|
|
11
|
+
<p align="center">
|
|
12
|
+
<a href="https://www.npmjs.com/package/ai-wingman"><img src="https://img.shields.io/npm/v/ai-wingman.svg" alt="npm version" /></a>
|
|
13
|
+
<a href="https://www.npmjs.com/package/ai-wingman"><img src="https://img.shields.io/npm/dm/ai-wingman.svg" alt="npm downloads" /></a>
|
|
14
|
+
<a href="https://github.com/yontn-oss/ai-wingman/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/ai-wingman.svg" alt="license" /></a>
|
|
15
|
+
<a href="https://github.com/yontn-oss/ai-wingman/blob/main/CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs welcome" /></a>
|
|
16
|
+
</p>
|
|
17
|
+
|
|
18
|
+
<p align="center">
|
|
19
|
+
<a href="https://ai-wingman-psi.vercel.app/">Website</a>
|
|
20
|
+
</p>
|
|
8
21
|
|
|
9
|
-
|
|
22
|
+
<p align="center">
|
|
23
|
+
<code>npx ai-wingman add chat</code>
|
|
24
|
+
</p>
|
|
25
|
+
|
|
26
|
+
<p align="center">
|
|
27
|
+
ai-wingman writes the API route, UI component, and all the wiring into your existing project — then exits.<br />
|
|
28
|
+
No runtime dependency. No lock-in. Just clean, typed TypeScript you own.
|
|
29
|
+
</p>
|
|
10
30
|
|
|
11
31
|
---
|
|
12
32
|
|
|
13
|
-
##
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
| `wingman add multimodal` | `convertToModelMessages` | Vision-aware chat route and page with image upload |
|
|
25
|
-
| `wingman add audio` | `experimental_transcribe` / `experimental_generateSpeech` | Transcription route, TTS route, recording page |
|
|
26
|
-
| `wingman add eval` | `generateText` (LLM judge) | Runnable eval script with string-match and judge scoring |
|
|
27
|
-
| `wingman add image-gen` | `generateImage` | Prompt-to-image route (DALL·E), display page with download |
|
|
28
|
-
| `wingman add generative-ui` | `streamUI` (ai/rsc) | Server action that streams React component trees to the client |
|
|
29
|
-
| `wingman add document-processing` | `generateText + Output.object` | File upload route, schema, and hook for PDF / document extraction |
|
|
33
|
+
## Table of contents
|
|
34
|
+
|
|
35
|
+
- [The problem it solves](#the-problem-it-solves)
|
|
36
|
+
- [How it works](#how-it-works)
|
|
37
|
+
- [18 patterns across 4 categories](#18-patterns-across-4-categories)
|
|
38
|
+
- [New to AI development?](#new-to-ai-development)
|
|
39
|
+
- [Quick start](#quick-start)
|
|
40
|
+
- [Prerequisites](#prerequisites)
|
|
41
|
+
- [Under the hood](#under-the-hood)
|
|
42
|
+
- [Contributing](#contributing)
|
|
43
|
+
- [License](#license)
|
|
30
44
|
|
|
31
45
|
---
|
|
32
46
|
|
|
33
|
-
##
|
|
47
|
+
## The problem it solves
|
|
34
48
|
|
|
35
|
-
|
|
49
|
+
Calling an AI API is three lines of code. Shipping a production AI feature is not.
|
|
36
50
|
|
|
37
|
-
|
|
38
|
-
|
|
51
|
+
You need to handle streaming tokens to the UI, structure outputs as typed JSON, store conversation history, let the model call your own functions, guard against bad content, measure quality over time, and do it all without turning your codebase into a mess of `fetch` calls and `any` types.
|
|
52
|
+
|
|
53
|
+
Every team figures this out from scratch. ai-wingman packages 18 of those patterns — each one the right way to wire that use-case — and scaffolds them with a single command.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## How it works
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
$ npx ai-wingman add rag
|
|
39
61
|
```
|
|
40
62
|
|
|
41
|
-
|
|
63
|
+
```
|
|
64
|
+
┌ ai-wingman
|
|
65
|
+
│
|
|
66
|
+
◆ Next.js 16.2.1 found
|
|
67
|
+
│
|
|
68
|
+
◇ AI provider?
|
|
69
|
+
│ Anthropic
|
|
70
|
+
│
|
|
71
|
+
◇ RAG storage backend?
|
|
72
|
+
│ SQLite + sqlite-vec
|
|
73
|
+
│
|
|
74
|
+
◇ Embedding model ID?
|
|
75
|
+
│ voyage-3
|
|
76
|
+
│
|
|
77
|
+
◇ Stream the query response?
|
|
78
|
+
│ Yes
|
|
79
|
+
│
|
|
80
|
+
◇ Plan ─────────────────────────╮
|
|
81
|
+
│ │
|
|
82
|
+
│ Install packages: │
|
|
83
|
+
│ @ai-sdk/anthropic │
|
|
84
|
+
│ ai │
|
|
85
|
+
│ better-sqlite3 │
|
|
86
|
+
│ sqlite-vec │
|
|
87
|
+
│ │
|
|
88
|
+
│ Create files: │
|
|
89
|
+
│ app/api/rag/embed/route.ts │
|
|
90
|
+
│ app/api/rag/query/route.ts │
|
|
91
|
+
│ lib/rag/store.ts │
|
|
92
|
+
│ lib/rag/sqlite-store.ts │
|
|
93
|
+
│ lib/rag/chunker.ts │
|
|
94
|
+
│ hooks/use-rag-query.ts │
|
|
95
|
+
│ │
|
|
96
|
+
├────────────────────────────────╯
|
|
97
|
+
│
|
|
98
|
+
◇ Proceed?
|
|
99
|
+
│ Yes
|
|
100
|
+
│
|
|
101
|
+
◆ Installed @ai-sdk/anthropic, ai, better-sqlite3, sqlite-vec
|
|
102
|
+
│
|
|
103
|
+
◆ Created app/api/rag/embed/route.ts
|
|
104
|
+
◆ Created app/api/rag/query/route.ts
|
|
105
|
+
◆ Created lib/rag/store.ts
|
|
106
|
+
◆ Created lib/rag/sqlite-store.ts
|
|
107
|
+
◆ Created lib/rag/chunker.ts
|
|
108
|
+
◆ Created hooks/use-rag-query.ts
|
|
109
|
+
│
|
|
110
|
+
◇ Add to .env.local ───────────╮
|
|
111
|
+
│ │
|
|
112
|
+
│ ANTHROPIC_API_KEY= │
|
|
113
|
+
│ SQLITE_RAG_PATH= │
|
|
114
|
+
│ │
|
|
115
|
+
├───────────────────────────────╯
|
|
116
|
+
│
|
|
117
|
+
└ Done! Start your dev server: npm run dev
|
|
118
|
+
```
|
|
42
119
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
120
|
+
The CLI detects your project, asks targeted questions, shows the full plan before touching anything, installs packages, writes files, and exits. No runtime dependency on ai-wingman after that point.
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
your project
|
|
124
|
+
│
|
|
125
|
+
▼
|
|
126
|
+
◆ detect ──── Next.js · TypeScript · shadcn/ui
|
|
127
|
+
│
|
|
128
|
+
▼
|
|
129
|
+
◇ prompt ──── provider · storage · model · options
|
|
130
|
+
│
|
|
131
|
+
▼
|
|
132
|
+
◇ plan ──── packages to install · files to create
|
|
133
|
+
│
|
|
134
|
+
▼
|
|
135
|
+
◇ confirm ──── review before anything is written
|
|
136
|
+
│
|
|
137
|
+
▼
|
|
138
|
+
◆ execute ──── install · write · done
|
|
139
|
+
│
|
|
140
|
+
▼
|
|
141
|
+
your project + production-ready AI feature
|
|
142
|
+
```
|
|
50
143
|
|
|
51
144
|
---
|
|
52
145
|
|
|
53
|
-
##
|
|
146
|
+
## 18 patterns across 4 categories
|
|
54
147
|
|
|
55
|
-
|
|
56
|
-
wingman add <pattern> # scaffold a pattern interactively
|
|
57
|
-
wingman list # list all available patterns
|
|
58
|
-
wingman add <pattern> --overwrite # re-scaffold, overwriting existing files
|
|
59
|
-
```
|
|
148
|
+
### Generate
|
|
60
149
|
|
|
61
|
-
|
|
150
|
+
Text, images, audio, structured data, and UI — anything the model produces directly.
|
|
62
151
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
152
|
+
| Command | What it builds | What that means |
|
|
153
|
+
|---------|---------------|-----------------|
|
|
154
|
+
| `ai-wingman add chat` | Streaming chat with conversation history | A ChatGPT-style interface backed by your own API route. Responses appear word-by-word instead of all at once. |
|
|
155
|
+
| `ai-wingman add structured-output` | AI that returns typed JSON, not prose | Ask the model a question; get back a strongly-typed object with named fields. Ready to store, display, or pass to the next function. |
|
|
156
|
+
| `ai-wingman add tools` | AI route that can call your functions | You expose functions like `searchDatabase()` or `sendEmail()`. The model decides when to call them and with what arguments. Your code executes them. |
|
|
157
|
+
| `ai-wingman add stream-object` | Progressively streamed typed JSON | The same typed object, but fields fill in one by one as the model generates them — good for long extractions where you want the UI to feel alive. |
|
|
158
|
+
| `ai-wingman add multimodal` | Vision-aware chat with image upload | The same chat interface, but users can attach images. The model can see, describe, and reason about them. |
|
|
159
|
+
| `ai-wingman add audio` | Speech-to-text input + text-to-speech replies | Users speak; the model transcribes, responds, and reads the answer back aloud. |
|
|
160
|
+
| `ai-wingman add image-gen` | Prompt-to-image route with display page | Generate images from a text prompt (DALL·E 3 by default). Includes a download button and swappable model flag. |
|
|
161
|
+
| `ai-wingman add generative-ui` | AI that streams back live React components | Instead of returning text, the model returns actual UI — charts, cards, forms — rendered in real time as they arrive. |
|
|
162
|
+
| `ai-wingman add document-processing` | Upload a file, extract structured data | Drop in a PDF; get back a typed object. Useful for invoice parsing, resume extraction, contract review. |
|
|
66
163
|
|
|
67
|
-
|
|
68
|
-
npx ai-wingman add chat --provider anthropic --api-route app/api/assistant/route.ts --yes
|
|
164
|
+
### Retrieval
|
|
69
165
|
|
|
70
|
-
|
|
71
|
-
npx ai-wingman add rag --provider openai --storage pgvector --yes
|
|
166
|
+
Patterns for grounding the model in your own data.
|
|
72
167
|
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
168
|
+
| Command | What it builds | What that means |
|
|
169
|
+
|---------|---------------|-----------------|
|
|
170
|
+
| `ai-wingman add rag` | Embed → store → retrieve → answer pipeline | Let the AI answer questions about *your* documents. It converts text to vectors, finds the most relevant chunks at query time, and uses them as context. This is how "chat with your PDF" products work. |
|
|
171
|
+
| `ai-wingman add hybrid-search` | Keyword + semantic search, merged | Runs a BM25 keyword search and a vector similarity search in parallel, then blends the rankings. More accurate than either approach alone — a drop-in upgrade to `rag`. |
|
|
172
|
+
| `ai-wingman add memory` | Per-user long-term memory across sessions | Saves facts about each user as embeddings, retrieves the most relevant ones at the start of each conversation, and injects them into the system prompt automatically. |
|
|
76
173
|
|
|
77
|
-
|
|
174
|
+
### Agents
|
|
78
175
|
|
|
79
|
-
|
|
176
|
+
Patterns where the model takes multiple steps or hands off to humans or other models.
|
|
80
177
|
|
|
81
|
-
|
|
|
82
|
-
|
|
83
|
-
| `
|
|
84
|
-
| `
|
|
85
|
-
| `
|
|
178
|
+
| Command | What it builds | What that means |
|
|
179
|
+
|---------|---------------|-----------------|
|
|
180
|
+
| `ai-wingman add agent` | Autonomous multi-step agent loop | The model thinks, calls a tool, sees the result, thinks again — repeating until the task is done. You set the step limit and define the tools. |
|
|
181
|
+
| `ai-wingman add interrupt` | Agent with human-in-the-loop approval gates | Like the agent pattern, but the model pauses and asks a human to confirm before taking any action that can't be undone. |
|
|
182
|
+
| `ai-wingman add multi-agent` | Orchestrator that delegates to specialist sub-agents | A coordinator model breaks work into sub-tasks and hands each off to a focused specialist. Results are synthesized into a single response. |
|
|
183
|
+
| `ai-wingman add background-agent` | Agent that runs outside the HTTP request cycle | Enqueue a task, get a job ID back immediately, then poll for status and result. For work that takes too long to complete in a single HTTP request. |
|
|
86
184
|
|
|
87
|
-
|
|
185
|
+
### Quality & Safety
|
|
88
186
|
|
|
89
|
-
|
|
187
|
+
Patterns that judge, classify, or score AI inputs and outputs.
|
|
90
188
|
|
|
91
|
-
|
|
|
92
|
-
|
|
93
|
-
|
|
|
94
|
-
|
|
|
95
|
-
| `--no-page` | patterns with pages | Omit the generated page component |
|
|
96
|
-
| `--storage <id>` | `rag` | `memory` / `sqlite` / `pgvector` |
|
|
97
|
-
| `--storage memory` | `chat` | Include conversation storage (default: off) |
|
|
98
|
-
| `--interrupt` | `chat` | Embed a human-in-the-loop approval gate in the chat route |
|
|
99
|
-
| `--stream` | `rag` | Use `streamText` instead of `generateText` in query route |
|
|
100
|
-
| `--schema-name <name>` | `structured-output`, `stream-object` | Name for the schema, hook, and type |
|
|
101
|
-
| `--no-hook` | `structured-output`, `stream-object` | Omit the generated client hook |
|
|
102
|
-
| `--tool-name <name>` | `tools` | Name for the generated tool stub file |
|
|
103
|
-
| `--image-model <model>` | `image-gen` | `dall-e-3` (default) or `dall-e-2` |
|
|
104
|
-
| `--overwrite` | all | Overwrite existing files without prompting |
|
|
105
|
-
| `-y, --yes` | all | Accept all defaults |
|
|
189
|
+
| Command | What it builds | What that means |
|
|
190
|
+
|---------|---------------|-----------------|
|
|
191
|
+
| `ai-wingman add eval` | LLM-as-judge evaluation harness | A test suite for AI outputs. You write test cases; a judge model scores each answer. Catch regressions when you change prompts or swap models — the same way unit tests catch bugs in regular code. |
|
|
192
|
+
| `ai-wingman add content-moderation` | LLM-based content classifier | Classifies any input or output against a policy you define. Returns `{ allowed, category, reason }` — drop it in front of any route. |
|
|
106
193
|
|
|
107
194
|
---
|
|
108
195
|
|
|
109
|
-
##
|
|
196
|
+
## New to AI development?
|
|
110
197
|
|
|
111
|
-
|
|
198
|
+
These terms come up constantly. Here's what they actually mean:
|
|
112
199
|
|
|
113
|
-
|
|
114
|
-
- You can overwrite, enter a different path, or skip the component
|
|
115
|
-
- `--overwrite` bypasses this prompt silently
|
|
116
|
-
- The CLI never silently overwrites without permission
|
|
200
|
+
**Streaming** — the model generates one token (roughly one word) at a time. Streaming means sending each token to the browser as it arrives, so the UI updates live. Without streaming, you wait for the full response before showing anything.
|
|
117
201
|
|
|
118
|
-
|
|
202
|
+
**Structured output** — by default, models return plain text. Structured output forces the model to return a JSON object that matches a schema you define — so you get typed fields instead of a paragraph you'd have to parse.
|
|
119
203
|
|
|
120
|
-
|
|
204
|
+
**Tool calling** — you define functions in your code and tell the model they exist. The model decides when to call them and what arguments to pass. Your code runs the function and returns the result. The model incorporates that result and keeps going. This is the foundation of all agent behavior.
|
|
121
205
|
|
|
122
|
-
|
|
123
|
-
|-------------|-------|-------------|
|
|
124
|
-
| React in `package.json` | Required — exits if missing | No |
|
|
125
|
-
| `tsconfig.json` | Required — exits if missing | No |
|
|
126
|
-
| shadcn/ui (`components.json`) | Required for page components | Prompted |
|
|
206
|
+
**RAG** — Retrieval-Augmented Generation. Your documents are converted to vectors (lists of numbers that capture meaning), stored in a vector database, and searched at query time. The most relevant chunks are included in the prompt alongside the user's question. The model answers using your data, not just what it learned during training.
|
|
127
207
|
|
|
128
|
-
|
|
208
|
+
**Eval** — AI outputs are non-deterministic. An eval harness measures quality by running your prompts against test cases and scoring the outputs — usually with a second model acting as a judge. It's how you tell whether a prompt change made things better or worse.
|
|
129
209
|
|
|
130
|
-
|
|
210
|
+
---
|
|
131
211
|
|
|
132
|
-
|
|
212
|
+
## Quick start
|
|
133
213
|
|
|
134
214
|
```bash
|
|
135
|
-
|
|
136
|
-
|
|
215
|
+
npx ai-wingman add chat
|
|
216
|
+
```
|
|
137
217
|
|
|
138
|
-
|
|
139
|
-
pnpm --filter ai-wingman watch
|
|
218
|
+
Add `--yes` to accept all defaults non-interactively:
|
|
140
219
|
|
|
141
|
-
|
|
142
|
-
bash scripts/new-fixture.sh
|
|
143
|
-
cd /tmp/wingman-fixture
|
|
220
|
+
### AI coding assistant integration
|
|
144
221
|
|
|
145
|
-
|
|
146
|
-
|
|
222
|
+
If you use Claude Code, Cursor, or another AI coding assistant, run:
|
|
223
|
+
|
|
224
|
+
```bash
|
|
225
|
+
npx ai-wingman skill
|
|
147
226
|
```
|
|
148
227
|
|
|
149
|
-
|
|
228
|
+
This downloads a `SKILL.md` into your project that tells your assistant about ai-wingman — what patterns are available, when to use them, and how to invoke them. Once it's there, your assistant will automatically reach for `ai-wingman add` instead of writing AI boilerplate by hand.
|
|
150
229
|
|
|
151
230
|
```bash
|
|
152
|
-
|
|
231
|
+
npx ai-wingman skill # saves to ./SKILL.md (default)
|
|
232
|
+
npx ai-wingman skill --output .cursorrules # custom output path
|
|
153
233
|
```
|
|
154
234
|
|
|
155
|
-
### Tests
|
|
156
|
-
|
|
157
235
|
```bash
|
|
158
|
-
|
|
236
|
+
npx ai-wingman add chat --provider anthropic --yes
|
|
237
|
+
npx ai-wingman add rag --provider openai --storage pgvector --yes
|
|
238
|
+
npx ai-wingman add chat --provider anthropic --overwrite --yes # re-scaffold
|
|
159
239
|
```
|
|
160
240
|
|
|
161
|
-
|
|
241
|
+
### Providers
|
|
162
242
|
|
|
163
|
-
|
|
243
|
+
| Value | Package installed | Env var required |
|
|
244
|
+
|-------|------------------|-----------------|
|
|
245
|
+
| `anthropic` | `@ai-sdk/anthropic` | `ANTHROPIC_API_KEY` |
|
|
246
|
+
| `openai` | `@ai-sdk/openai` | `OPENAI_API_KEY` |
|
|
247
|
+
| `google` | `@ai-sdk/google` | `GOOGLE_GENERATIVE_AI_API_KEY` |
|
|
164
248
|
|
|
165
|
-
|
|
166
|
-
packages/ai-wingman/
|
|
167
|
-
├── bin/
|
|
168
|
-
│ └── wingman.ts # CLI entry point (commander)
|
|
169
|
-
├── src/
|
|
170
|
-
│ ├── types.ts # Config types for all patterns
|
|
171
|
-
│ ├── registry/
|
|
172
|
-
│ │ ├── providers.ts # Anthropic, OpenAI, Google
|
|
173
|
-
│ │ ├── storage-adapters.ts
|
|
174
|
-
│ │ ├── patterns.ts # Pattern registry + resolvers
|
|
175
|
-
│ │ └── index.ts
|
|
176
|
-
│ ├── generators/ # Pure (config) => string functions
|
|
177
|
-
│ ├── patterns/ # One dir per pattern
|
|
178
|
-
│ │ ├── chat/
|
|
179
|
-
│ │ ├── structured-output/
|
|
180
|
-
│ │ ├── tools/
|
|
181
|
-
│ │ ├── stream-object/
|
|
182
|
-
│ │ ├── rag/
|
|
183
|
-
│ │ ├── interrupt/
|
|
184
|
-
│ │ ├── agent/
|
|
185
|
-
│ │ ├── multimodal/
|
|
186
|
-
│ │ ├── audio/
|
|
187
|
-
│ │ ├── eval/
|
|
188
|
-
│ │ ├── image-gen/
|
|
189
|
-
│ │ ├── generative-ui/
|
|
190
|
-
│ │ └── document-processing/
|
|
191
|
-
│ ├── commands/
|
|
192
|
-
│ │ ├── add/ # Main orchestrator
|
|
193
|
-
│ │ └── list/
|
|
194
|
-
│ ├── planner/ # Builds ExecutionPlan before writing
|
|
195
|
-
│ ├── steps/ # Shared interactive steps
|
|
196
|
-
│ └── utils/
|
|
197
|
-
└── tests/
|
|
198
|
-
└── unit/generators/ # Snapshot tests per generator
|
|
199
|
-
```
|
|
249
|
+
### All flags
|
|
200
250
|
|
|
201
|
-
|
|
251
|
+
| Flag | Applies to | What it does |
|
|
252
|
+
|------|-----------|-------------|
|
|
253
|
+
| `--provider <id>` | all | `anthropic` / `openai` / `google` |
|
|
254
|
+
| `--auth` | all | Add a NextAuth v5 session check to the route |
|
|
255
|
+
| `--no-page` | patterns with pages | Skip generating the page component |
|
|
256
|
+
| `--storage <id>` | `rag` | `memory` / `sqlite` / `pgvector` |
|
|
257
|
+
| `--storage memory` | `chat` | Add in-memory conversation storage |
|
|
258
|
+
| `--interrupt` | `chat` | Add a human approval gate to the chat route |
|
|
259
|
+
| `--stream` | `rag` | Stream the answer instead of waiting for the full response |
|
|
260
|
+
| `--schema-name <name>` | `structured-output`, `stream-object` | Name for the generated schema, type, and hook |
|
|
261
|
+
| `--no-hook` | `structured-output`, `stream-object` | Skip the generated React hook |
|
|
262
|
+
| `--tool-name <name>` | `tools` | Name for the generated tool stub |
|
|
263
|
+
| `--image-model <model>` | `image-gen` | `dall-e-3` (default) or `dall-e-2` |
|
|
264
|
+
| `--api-route <path>` | all | Custom output path for the API route |
|
|
265
|
+
| `--overwrite` | all | Overwrite existing files without prompting |
|
|
266
|
+
| `-y, --yes` | all | Accept all defaults |
|
|
202
267
|
|
|
203
|
-
|
|
268
|
+
The CLI never silently overwrites a file — it prompts for each conflict unless `--overwrite` is set.
|
|
204
269
|
|
|
205
|
-
|
|
206
|
-
{
|
|
207
|
-
id: 'mistral',
|
|
208
|
-
label: 'Mistral',
|
|
209
|
-
package: '@ai-sdk/mistral',
|
|
210
|
-
importName: 'mistral',
|
|
211
|
-
envVar: 'MISTRAL_API_KEY',
|
|
212
|
-
defaultModel: 'mistral-large-latest',
|
|
213
|
-
modelFactory: 'mistral("mistral-large-latest")',
|
|
214
|
-
}
|
|
215
|
-
```
|
|
270
|
+
---
|
|
216
271
|
|
|
217
|
-
|
|
272
|
+
## Prerequisites
|
|
273
|
+
|
|
274
|
+
| Requirement | Notes |
|
|
275
|
+
|-------------|-------|
|
|
276
|
+
| Next.js + TypeScript | Required. The CLI exits if either is missing. |
|
|
277
|
+
| shadcn/ui | Required for page components. The CLI offers to set it up if it's not found. |
|
|
278
|
+
|
|
279
|
+
---
|
|
280
|
+
|
|
281
|
+
## Under the hood
|
|
282
|
+
|
|
283
|
+
- **Generators are pure functions** — `(config) => string`. No side effects, no network calls, no filesystem reads. Fast to test, easy to snapshot.
|
|
284
|
+
- **The planner runs before any files are written** — every `ai-wingman add` builds a complete `ExecutionPlan` first, shows it to you for confirmation, then executes. Nothing is written speculatively.
|
|
285
|
+
- **525 snapshot tests** across all 18 generators. Changing a generator output requires updating the snapshot deliberately — not by accident.
|
|
286
|
+
- **Providers and patterns are registry entries** — adding a new provider is one object in `providers.ts`. All generators pick it up automatically.
|
|
287
|
+
|
|
288
|
+
For project structure, local dev setup, and contribution guidelines see [CONTRIBUTING.md](./CONTRIBUTING.md).
|
|
289
|
+
|
|
290
|
+
---
|
|
218
291
|
|
|
219
|
-
|
|
292
|
+
## Contributing
|
|
220
293
|
|
|
221
|
-
|
|
222
|
-
2. Add `prompt-config.ts` and `execute.ts` alongside it
|
|
223
|
-
3. Add generators to `src/generators/` as needed
|
|
224
|
-
4. Register the pattern in `src/registry/patterns.ts`
|
|
225
|
-
5. Add snapshot tests in `tests/unit/generators/<name>.test.ts`
|
|
294
|
+
Contributions are welcome! See [CONTRIBUTING.md](./CONTRIBUTING.md) for how to get started.
|
|
226
295
|
|
|
227
296
|
---
|
|
228
297
|
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
type PackageManager = 'npm' | 'pnpm' | 'yarn' | 'bun';
|
|
2
|
+
|
|
3
|
+
/** Config collected once before any pattern-specific prompts. */
|
|
4
|
+
interface SharedConfig {
|
|
5
|
+
provider: ProviderEntry;
|
|
6
|
+
pathAlias: string;
|
|
7
|
+
hasSrcDir: boolean;
|
|
8
|
+
packageManager: PackageManager;
|
|
9
|
+
targetDir: string;
|
|
10
|
+
prereqs: {
|
|
11
|
+
hasShadcn: boolean;
|
|
12
|
+
hasNext: boolean;
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
/** A single entry in the execution plan (display + execution metadata). */
|
|
16
|
+
type PlanEntry = {
|
|
17
|
+
kind: 'run';
|
|
18
|
+
command: string;
|
|
19
|
+
args: string[];
|
|
20
|
+
} | {
|
|
21
|
+
kind: 'create';
|
|
22
|
+
path: string;
|
|
23
|
+
overwrite?: boolean;
|
|
24
|
+
};
|
|
25
|
+
/** Unified plan produced by the planner across all requested patterns. */
|
|
26
|
+
interface ExecutionPlan {
|
|
27
|
+
/** Deduplicated package names to install before execution. */
|
|
28
|
+
packages: string[];
|
|
29
|
+
/** Ordered entries: CLI runs first, then file creates. */
|
|
30
|
+
entries: PlanEntry[];
|
|
31
|
+
/** Per-pattern groups used for display — same entries as above, grouped by pattern id. */
|
|
32
|
+
groups: Array<{
|
|
33
|
+
patternId: string;
|
|
34
|
+
entries: PlanEntry[];
|
|
35
|
+
}>;
|
|
36
|
+
}
|
|
37
|
+
/** Every pattern implements this interface. */
|
|
38
|
+
interface Pattern {
|
|
39
|
+
id: string;
|
|
40
|
+
description: string;
|
|
41
|
+
/** Non-universal CLI flags this pattern accepts (beyond provider, auth, overwrite, yes). */
|
|
42
|
+
cliFlags: (keyof AddChatOptions)[];
|
|
43
|
+
promptConfig(shared: SharedConfig, opts: unknown): Promise<unknown>;
|
|
44
|
+
getPackages(config: unknown): string[];
|
|
45
|
+
getPlanEntries(config: unknown): PlanEntry[];
|
|
46
|
+
getEnvVars(config: unknown): string[];
|
|
47
|
+
execute(config: unknown, shared: SharedConfig): Promise<void>;
|
|
48
|
+
}
|
|
49
|
+
interface ProviderEntry {
|
|
50
|
+
id: 'anthropic' | 'openai' | 'google';
|
|
51
|
+
label: string;
|
|
52
|
+
package: string;
|
|
53
|
+
importName: string;
|
|
54
|
+
envVar: string;
|
|
55
|
+
defaultModel: string;
|
|
56
|
+
modelFactory: string;
|
|
57
|
+
/** Method name on the provider for embedding models (e.g. 'embedding' for openai, 'textEmbeddingModel' for google). Absent if the provider has no native embedding support. */
|
|
58
|
+
embeddingMethod?: string;
|
|
59
|
+
/** Method name on the provider for speech generation (e.g. 'speech' for openai). Absent if unsupported. */
|
|
60
|
+
speechMethod?: string;
|
|
61
|
+
/** Method name on the provider for speech transcription (e.g. 'transcription' for openai). Absent if unsupported. */
|
|
62
|
+
transcriptionMethod?: string;
|
|
63
|
+
}
|
|
64
|
+
interface StorageEntry {
|
|
65
|
+
id: 'memory' | 'postgres';
|
|
66
|
+
label: string;
|
|
67
|
+
package?: string;
|
|
68
|
+
envVar?: string;
|
|
69
|
+
}
|
|
70
|
+
interface StackRegistry {
|
|
71
|
+
providers: ProviderEntry[];
|
|
72
|
+
storage: StorageEntry[];
|
|
73
|
+
}
|
|
74
|
+
/** Values parsed from CLI flags — undefined means "not supplied, prompt the user" */
|
|
75
|
+
interface AddChatOptions {
|
|
76
|
+
/** anthropic | openai | google */
|
|
77
|
+
provider?: string;
|
|
78
|
+
/** memory | postgres — presence implies storage component included (default: off) */
|
|
79
|
+
storage?: string;
|
|
80
|
+
/** true = --auth (default: off) */
|
|
81
|
+
auth?: boolean;
|
|
82
|
+
/** false = --no-page */
|
|
83
|
+
page?: boolean;
|
|
84
|
+
/** false = --no-chat-ui */
|
|
85
|
+
chatUi?: boolean;
|
|
86
|
+
/** override API route output path */
|
|
87
|
+
apiRoute?: string;
|
|
88
|
+
/** override storage output path */
|
|
89
|
+
storagePath?: string;
|
|
90
|
+
/** override page component output path */
|
|
91
|
+
pagePath?: string;
|
|
92
|
+
/** overwrite existing files without prompting */
|
|
93
|
+
overwrite?: boolean;
|
|
94
|
+
/** accept all defaults, skip optional prompts */
|
|
95
|
+
yes?: boolean;
|
|
96
|
+
/** schema/hook/type name (default: output) */
|
|
97
|
+
schemaName?: string;
|
|
98
|
+
/** override schema output path */
|
|
99
|
+
schemaPath?: string;
|
|
100
|
+
/** override hook output path */
|
|
101
|
+
hookPath?: string;
|
|
102
|
+
/** false = --no-hook */
|
|
103
|
+
hook?: boolean;
|
|
104
|
+
/** true = --interrupt */
|
|
105
|
+
interrupt?: boolean;
|
|
106
|
+
/** embedding model ID */
|
|
107
|
+
embeddingModel?: string;
|
|
108
|
+
/** image model: dall-e-3 | dall-e-2 (default: dall-e-3) */
|
|
109
|
+
imageModel?: string;
|
|
110
|
+
/** override API route output path (generative-ui) */
|
|
111
|
+
routePath?: string;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
declare function resolvePatterns(ids: string[]): Pattern[];
|
|
115
|
+
declare function resolveAllPatterns(): Pattern[];
|
|
116
|
+
|
|
117
|
+
export { type ExecutionPlan, type PackageManager, type Pattern, type PlanEntry, type ProviderEntry, type SharedConfig, type StackRegistry, type StorageEntry, resolveAllPatterns, resolvePatterns };
|