promptpilot 0.1.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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
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 ADDED
@@ -0,0 +1,283 @@
1
+ # promptpilot
2
+
3
+ `promptpilot` is a lightweight TypeScript npm package that sits between your app or CLI workflow and a target LLM. It rewrites prompts locally through Ollama when available, stores reusable session context, compresses older turns, and emits a Claude-friendly final prompt for shell pipelines or application code.
4
+
5
+ It is designed for local-first workflows on machines like an 18 GB MacBook. By default, `promptpilot` inspects your local Ollama installation and auto-selects a small optimization model, preferring `qwen2.5:3b`, `phi3:mini`, and `llama3.2:3b` in that order. The package still lets you override the model manually when needed.
6
+
7
+ ## Why local Ollama
8
+
9
+ - It keeps prompt optimization close to your workflow.
10
+ - It reduces external API calls for prompt rewriting.
11
+ - It lets you use a small, fast model for compression before sending the final prompt to a stronger remote model like Claude.
12
+ - It automatically picks an installed local model that fits a low-memory workflow.
13
+
14
+ ## What it does
15
+
16
+ - Accepts a raw prompt plus optional metadata.
17
+ - Persists session context across turns.
18
+ - Retrieves relevant prior context for the next prompt.
19
+ - Summarizes older context when budgets get tight.
20
+ - Preserves critical instructions and constraints.
21
+ - Estimates token usage before and after optimization.
22
+ - Outputs plain prompt text or structured JSON.
23
+ - Works cleanly with Claude CLI shell pipelines.
24
+
25
+ ## Quick start
26
+
27
+ ```bash
28
+ npm install
29
+ npm run build
30
+ npm test
31
+ ollama pull qwen2.5:3b
32
+ promptpilot optimize "explain binary search simply" --plain
33
+ promptpilot optimize "continue my study guide" --session dsa --save-context --plain | claude
34
+ ```
35
+
36
+ After publishing, install from npm with:
37
+
38
+ ```bash
39
+ npm install -g promptpilot
40
+ ```
41
+
42
+ ## Install and build
43
+
44
+ ```bash
45
+ npm install
46
+ npm run build
47
+ ```
48
+
49
+ Install directly from a local tarball:
50
+
51
+ ```bash
52
+ npm pack
53
+ npm install -g ./promptpilot-0.1.0.tgz
54
+ ```
55
+
56
+ ## Library usage
57
+
58
+ ```ts
59
+ import { createOptimizer, optimizePrompt } from "promptpilot";
60
+
61
+ const optimizer = createOptimizer({
62
+ provider: "ollama",
63
+ host: "http://localhost:11434",
64
+ contextStore: "local"
65
+ });
66
+
67
+ const result = await optimizer.optimize({
68
+ prompt: "help me write a better follow up email for a startup internship",
69
+ task: "email",
70
+ tone: "professional but human",
71
+ targetModel: "claude",
72
+ sessionId: "internship-search"
73
+ });
74
+
75
+ console.log(result.optimizedPrompt);
76
+
77
+ const oneOff = await optimizePrompt({
78
+ prompt: "continue working on my essay intro",
79
+ task: "essay",
80
+ sessionId: "essay1"
81
+ });
82
+
83
+ console.log(oneOff.finalPrompt);
84
+ ```
85
+
86
+ ## Claude CLI usage
87
+
88
+ Plain shell output:
89
+
90
+ ```bash
91
+ promptpilot optimize "help me explain binary search simply" --session study --plain
92
+ ```
93
+
94
+ Piping into Claude CLI:
95
+
96
+ ```bash
97
+ promptpilot optimize "help me explain binary search simply" --session study --plain | claude
98
+ ```
99
+
100
+ Using stdin in a shell pipeline:
101
+
102
+ ```bash
103
+ cat notes.txt | promptpilot optimize --task summarization --plain | claude
104
+ ```
105
+
106
+ Saving context between calls:
107
+
108
+ ```bash
109
+ promptpilot optimize "continue working on my essay intro" --session essay1 --task essay --save-context --plain
110
+ ```
111
+
112
+ Debugging token usage:
113
+
114
+ ```bash
115
+ promptpilot optimize "summarize these lecture notes" --session notes1 --json --debug
116
+ ```
117
+
118
+ Clearing a session:
119
+
120
+ ```bash
121
+ promptpilot optimize --session essay1 --clear-session
122
+ ```
123
+
124
+ Node `child_process` example:
125
+
126
+ ```ts
127
+ import { spawn } from "node:child_process";
128
+
129
+ const prompt = spawn("promptpilot", [
130
+ "optimize",
131
+ "continue my study guide",
132
+ "--session",
133
+ "dsa",
134
+ "--plain"
135
+ ]);
136
+
137
+ const claude = spawn("claude", [], { stdio: ["pipe", "inherit", "inherit"] });
138
+ prompt.stdout.pipe(claude.stdin);
139
+ ```
140
+
141
+ ## Session context
142
+
143
+ By default, if you pass a `sessionId`, `promptpilot` stores optimized turns in a local session store. The default store is JSON files under `~/.promptpilot/sessions`. A SQLite store is also available when `node:sqlite` or `better-sqlite3` is present.
144
+
145
+ If you do not pass `ollamaModel` or `--model`, `promptpilot` asks Ollama which models are installed and picks the best small model for the job. For most workflows it prefers `qwen2.5:3b`, then `phi3:mini`, then `llama3.2:3b`. For code-heavy prompts it will prefer `qwen2.5-coder:3b` when that model is installed. If only oversized local models are available, it warns and falls back to deterministic heuristic optimization instead of silently using a heavy model.
146
+
147
+ Each session stores:
148
+
149
+ - User prompts
150
+ - Optimized prompts
151
+ - Final prompts
152
+ - Extracted constraints
153
+ - Context summaries
154
+ - Timestamps
155
+ - Optional tags
156
+
157
+ Context retrieval prefers:
158
+
159
+ - Pinned constraints
160
+ - Task-aligned prior turns
161
+ - Recent prompts
162
+ - Named entities and recurring references
163
+ - Stored summaries when budgets are tight
164
+
165
+ ## Token reduction
166
+
167
+ `promptpilot` estimates token usage heuristically for:
168
+
169
+ - The new prompt
170
+ - Retrieved session context
171
+ - The final composed prompt
172
+
173
+ You can control the budgets with:
174
+
175
+ - `maxInputTokens`
176
+ - `maxContextTokens`
177
+ - `maxTotalTokens`
178
+
179
+ When context is too large, it ranks prior turns, preserves high-value constraints, summarizes older context, and drops lower-signal items.
180
+
181
+ ## CLI
182
+
183
+ ```bash
184
+ promptpilot optimize "write me a better prompt for asking claude to summarize lecture notes"
185
+ ```
186
+
187
+ Supported flags:
188
+
189
+ - `--session <id>`
190
+ - `--model <name>` to override auto-selection
191
+ - `--mode <mode>`
192
+ - `--task <task>`
193
+ - `--tone <tone>`
194
+ - `--preset <preset>`
195
+ - `--target-model <name>`
196
+ - `--output-format <text>`
197
+ - `--max-length <n>`
198
+ - `--tag <value>` repeatable
199
+ - `--pin-constraint <text>` repeatable
200
+ - `--store <local|sqlite>`
201
+ - `--storage-dir <path>`
202
+ - `--sqlite-path <path>`
203
+ - `--plain`
204
+ - `--json`
205
+ - `--debug`
206
+ - `--save-context`
207
+ - `--no-context`
208
+ - `--max-total-tokens <n>`
209
+ - `--max-context-tokens <n>`
210
+ - `--max-input-tokens <n>`
211
+ - `--clear-session`
212
+ - `--bypass-optimization`
213
+
214
+ If no prompt argument is provided, `promptpilot optimize` will read the raw prompt from stdin.
215
+
216
+ ## Public API
217
+
218
+ Main exports:
219
+
220
+ - `createOptimizer`
221
+ - `optimizePrompt`
222
+ - `PromptOptimizer`
223
+ - `OllamaClient`
224
+ - `FileSessionStore`
225
+ - `SQLiteSessionStore`
226
+
227
+ Supported modes:
228
+
229
+ - `clarity`
230
+ - `concise`
231
+ - `detailed`
232
+ - `structured`
233
+ - `persuasive`
234
+ - `compress`
235
+ - `claude_cli`
236
+
237
+ Supported presets:
238
+
239
+ - `code`
240
+ - `email`
241
+ - `essay`
242
+ - `support`
243
+ - `summarization`
244
+ - `chat`
245
+
246
+ ## File structure
247
+
248
+ ```text
249
+ src/
250
+ index.ts
251
+ types.ts
252
+ errors.ts
253
+ cli.ts
254
+ core/
255
+ optimizer.ts
256
+ ollamaClient.ts
257
+ systemPrompt.ts
258
+ contextManager.ts
259
+ tokenEstimator.ts
260
+ contextCompressor.ts
261
+ storage/
262
+ fileSessionStore.ts
263
+ sqliteSessionStore.ts
264
+ utils/
265
+ validation.ts
266
+ logger.ts
267
+ json.ts
268
+ test/
269
+ ```
270
+
271
+ ## Safety and fallback behavior
272
+
273
+ If Ollama is unavailable, `promptpilot` falls back to a deterministic local formatter that still preserves constraints and emits a Claude-compatible final prompt. Empty prompts are rejected, timeouts are supported, and hard token budget failures throw explicit errors.
274
+
275
+ ## Future improvements
276
+
277
+ - Semantic retrieval for context
278
+ - Better token counting by model
279
+ - Prompt scoring
280
+ - Local embeddings for relevance search
281
+ - Response-aware context updates
282
+ - Cache layer
283
+ - Benchmark suite
package/dist/cli.d.ts ADDED
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env node
2
+ import { createOptimizer } from './index.js';
3
+
4
+ type CliWriter = {
5
+ write(message: string): void;
6
+ };
7
+ interface CliIO {
8
+ stdout: CliWriter;
9
+ stderr: CliWriter;
10
+ stdin?: NodeJS.ReadStream;
11
+ }
12
+ interface CliDependencies {
13
+ createOptimizer: typeof createOptimizer;
14
+ readStdin: (stdin?: NodeJS.ReadStream) => Promise<string>;
15
+ }
16
+ declare function runCli(argv: string[], io?: CliIO, dependencies?: CliDependencies): Promise<number>;
17
+
18
+ export { runCli };