preflight-dev 3.1.0 → 3.2.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.
Files changed (57) hide show
  1. package/README.md +77 -16
  2. package/dist/cli/init.js +0 -48
  3. package/dist/cli/init.js.map +1 -1
  4. package/dist/index.js +7 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/lib/contracts.d.ts +27 -0
  7. package/dist/lib/contracts.js +309 -0
  8. package/dist/lib/contracts.js.map +1 -0
  9. package/dist/lib/patterns.d.ts +38 -0
  10. package/dist/lib/patterns.js +176 -0
  11. package/dist/lib/patterns.js.map +1 -0
  12. package/dist/lib/triage.d.ts +2 -0
  13. package/dist/lib/triage.js.map +1 -1
  14. package/dist/profiles.js +4 -0
  15. package/dist/profiles.js.map +1 -1
  16. package/dist/tools/check-patterns.d.ts +2 -0
  17. package/dist/tools/check-patterns.js +33 -0
  18. package/dist/tools/check-patterns.js.map +1 -0
  19. package/dist/tools/clarify-intent.js +9 -1
  20. package/dist/tools/clarify-intent.js.map +1 -1
  21. package/dist/tools/enrich-agent-task.js +132 -3
  22. package/dist/tools/enrich-agent-task.js.map +1 -1
  23. package/dist/tools/estimate-cost.d.ts +2 -0
  24. package/dist/tools/estimate-cost.js +261 -0
  25. package/dist/tools/estimate-cost.js.map +1 -0
  26. package/dist/tools/generate-scorecard.js +466 -14
  27. package/dist/tools/generate-scorecard.js.map +1 -1
  28. package/dist/tools/log-correction.js +7 -1
  29. package/dist/tools/log-correction.js.map +1 -1
  30. package/dist/tools/onboard-project.js +10 -1
  31. package/dist/tools/onboard-project.js.map +1 -1
  32. package/dist/tools/preflight-check.js +16 -0
  33. package/dist/tools/preflight-check.js.map +1 -1
  34. package/dist/tools/scope-work.js +6 -0
  35. package/dist/tools/scope-work.js.map +1 -1
  36. package/dist/tools/search-contracts.d.ts +2 -0
  37. package/dist/tools/search-contracts.js +46 -0
  38. package/dist/tools/search-contracts.js.map +1 -0
  39. package/dist/tools/session-stats.js +2 -0
  40. package/dist/tools/session-stats.js.map +1 -1
  41. package/package.json +1 -1
  42. package/src/index.ts +7 -0
  43. package/src/lib/contracts.ts +354 -0
  44. package/src/lib/patterns.ts +210 -0
  45. package/src/lib/triage.ts +2 -0
  46. package/src/profiles.ts +4 -0
  47. package/src/tools/check-patterns.ts +43 -0
  48. package/src/tools/clarify-intent.ts +10 -1
  49. package/src/tools/enrich-agent-task.ts +150 -3
  50. package/src/tools/estimate-cost.ts +332 -0
  51. package/src/tools/generate-scorecard.ts +541 -14
  52. package/src/tools/log-correction.ts +8 -1
  53. package/src/tools/onboard-project.ts +10 -1
  54. package/src/tools/preflight-check.ts +19 -0
  55. package/src/tools/scope-work.ts +7 -0
  56. package/src/tools/search-contracts.ts +61 -0
  57. package/src/tools/session-stats.ts +2 -0
@@ -0,0 +1,261 @@
1
+ // =============================================================================
2
+ // estimate_cost — Estimate token usage and cost for a Claude Code session
3
+ // =============================================================================
4
+ import { z } from "zod";
5
+ import { readFileSync, statSync } from "node:fs";
6
+ import { basename } from "node:path";
7
+ import { findSessionDirs, findSessionFiles } from "../lib/session-parser.js";
8
+ // ── Pricing (per 1M tokens) ────────────────────────────────────────────────
9
+ const PRICING = {
10
+ "claude-sonnet-4": { input: 3.0, output: 15.0 },
11
+ "claude-opus-4": { input: 15.0, output: 75.0 },
12
+ "claude-haiku-3.5": { input: 0.8, output: 4.0 },
13
+ };
14
+ const DEFAULT_MODEL = "claude-sonnet-4";
15
+ const CORRECTION_SIGNALS = /\b(no[,.\s]|wrong|not that|i meant|actually|try again|revert|undo|that's not|not what i)\b/i;
16
+ const PREFLIGHT_TOOLS = new Set([
17
+ "preflight_check",
18
+ "clarify_intent",
19
+ "scope_work",
20
+ "sharpen_followup",
21
+ "token_audit",
22
+ "prompt_score",
23
+ ]);
24
+ // ── Helpers ─────────────────────────────────────────────────────────────────
25
+ function estimateTokens(text) {
26
+ return Math.ceil(text.length / 4);
27
+ }
28
+ function extractText(content) {
29
+ if (typeof content === "string")
30
+ return content;
31
+ if (Array.isArray(content)) {
32
+ return content
33
+ .filter((b) => typeof b.text === "string")
34
+ .map((b) => b.text)
35
+ .join("\n");
36
+ }
37
+ return "";
38
+ }
39
+ function extractToolNames(content) {
40
+ if (!Array.isArray(content))
41
+ return [];
42
+ return content
43
+ .filter((b) => b.type === "tool_use" && b.name)
44
+ .map((b) => b.name);
45
+ }
46
+ function formatTokens(n) {
47
+ if (n >= 1_000_000)
48
+ return `${(n / 1_000_000).toFixed(1)}M`;
49
+ if (n >= 1_000)
50
+ return `${(n / 1_000).toFixed(1)}k`;
51
+ return String(n);
52
+ }
53
+ function formatCost(dollars) {
54
+ if (dollars < 0.01)
55
+ return `<$0.01`;
56
+ return `$${dollars.toFixed(2)}`;
57
+ }
58
+ function formatDuration(ms) {
59
+ const mins = Math.floor(ms / 60_000);
60
+ if (mins < 60)
61
+ return `${mins}m`;
62
+ const hours = Math.floor(mins / 60);
63
+ const rem = mins % 60;
64
+ return `${hours}h ${rem}m`;
65
+ }
66
+ function analyzeSessionFile(filePath) {
67
+ const content = readFileSync(filePath, "utf-8");
68
+ const lines = content.trim().split("\n").filter(Boolean);
69
+ const result = {
70
+ inputTokens: 0,
71
+ outputTokens: 0,
72
+ promptCount: 0,
73
+ toolCallCount: 0,
74
+ corrections: 0,
75
+ wastedOutputTokens: 0,
76
+ preflightCalls: 0,
77
+ preflightTokens: 0,
78
+ firstTimestamp: null,
79
+ lastTimestamp: null,
80
+ };
81
+ let lastType = "";
82
+ let lastAssistantTokens = 0;
83
+ for (const line of lines) {
84
+ let obj;
85
+ try {
86
+ obj = JSON.parse(line);
87
+ }
88
+ catch {
89
+ continue;
90
+ }
91
+ // Track timestamps
92
+ const ts = obj.timestamp;
93
+ if (ts) {
94
+ const tsStr = typeof ts === "string" ? ts : new Date(ts < 1e12 ? ts * 1000 : ts).toISOString();
95
+ if (!result.firstTimestamp)
96
+ result.firstTimestamp = tsStr;
97
+ result.lastTimestamp = tsStr;
98
+ }
99
+ if (obj.type === "user") {
100
+ const text = extractText(obj.message?.content);
101
+ const tokens = estimateTokens(text);
102
+ result.inputTokens += tokens;
103
+ result.promptCount++;
104
+ // Correction detection
105
+ if (lastType === "assistant" && CORRECTION_SIGNALS.test(text)) {
106
+ result.corrections++;
107
+ result.wastedOutputTokens += lastAssistantTokens;
108
+ }
109
+ lastType = "user";
110
+ }
111
+ else if (obj.type === "assistant") {
112
+ const msgContent = obj.message?.content;
113
+ const text = extractText(msgContent);
114
+ const tokens = estimateTokens(text);
115
+ result.outputTokens += tokens;
116
+ lastAssistantTokens = tokens;
117
+ // Tool calls
118
+ const toolNames = extractToolNames(msgContent);
119
+ result.toolCallCount += toolNames.length;
120
+ for (const name of toolNames) {
121
+ if (PREFLIGHT_TOOLS.has(name)) {
122
+ result.preflightCalls++;
123
+ // Estimate tool call tokens (name + args)
124
+ const toolBlocks = msgContent.filter((b) => b.type === "tool_use" && b.name === name);
125
+ for (const tb of toolBlocks) {
126
+ result.preflightTokens += estimateTokens(JSON.stringify(tb.input ?? {}));
127
+ }
128
+ }
129
+ }
130
+ lastType = "assistant";
131
+ }
132
+ else if (obj.type === "tool_result") {
133
+ const text = extractText(obj.content);
134
+ const tokens = estimateTokens(text);
135
+ result.inputTokens += tokens;
136
+ // Check if this is a preflight tool result
137
+ if (obj.tool_use_id) {
138
+ // We can't perfectly match tool_use_id to name, so count tokens as preflight
139
+ // if they're small (typical preflight responses)
140
+ }
141
+ }
142
+ }
143
+ return result;
144
+ }
145
+ // ── Registration ────────────────────────────────────────────────────────────
146
+ export function registerEstimateCost(server) {
147
+ server.tool("estimate_cost", "Estimate token usage and cost for the current session. Shows waste from vague prompts and savings from preflight checks.", {
148
+ session_dir: z
149
+ .string()
150
+ .optional()
151
+ .describe("Path to session JSONL file (optional, uses latest if omitted)"),
152
+ model: z
153
+ .string()
154
+ .optional()
155
+ .describe("Pricing model to use (claude-sonnet-4, claude-opus-4, claude-haiku-3.5). Default: claude-sonnet-4"),
156
+ }, async ({ session_dir, model }) => {
157
+ const pricingModel = model && PRICING[model] ? model : DEFAULT_MODEL;
158
+ const pricing = PRICING[pricingModel];
159
+ // Find session file
160
+ let filePath;
161
+ if (session_dir) {
162
+ filePath = session_dir;
163
+ }
164
+ else {
165
+ // Find latest session file
166
+ const dirs = findSessionDirs();
167
+ let latest = null;
168
+ for (const dir of dirs) {
169
+ const files = findSessionFiles(dir.sessionDir);
170
+ for (const f of files) {
171
+ if (!latest || f.mtime > latest.mtime) {
172
+ latest = f;
173
+ }
174
+ }
175
+ }
176
+ if (!latest) {
177
+ return {
178
+ content: [
179
+ {
180
+ type: "text",
181
+ text: "No session files found in ~/.claude/projects/",
182
+ },
183
+ ],
184
+ };
185
+ }
186
+ filePath = latest.path;
187
+ }
188
+ // Verify file exists
189
+ try {
190
+ statSync(filePath);
191
+ }
192
+ catch {
193
+ return {
194
+ content: [
195
+ {
196
+ type: "text",
197
+ text: `Session file not found: ${filePath}`,
198
+ },
199
+ ],
200
+ };
201
+ }
202
+ const analysis = analyzeSessionFile(filePath);
203
+ const totalTokens = analysis.inputTokens + analysis.outputTokens;
204
+ const inputCost = (analysis.inputTokens / 1_000_000) * pricing.input;
205
+ const outputCost = (analysis.outputTokens / 1_000_000) * pricing.output;
206
+ const totalCost = inputCost + outputCost;
207
+ const wasteCost = (analysis.wastedOutputTokens / 1_000_000) * pricing.output;
208
+ const wastePercent = totalCost > 0 ? ((wasteCost / totalCost) * 100).toFixed(1) : "0";
209
+ // Duration
210
+ let durationStr = "unknown";
211
+ if (analysis.firstTimestamp && analysis.lastTimestamp) {
212
+ const ms = new Date(analysis.lastTimestamp).getTime() -
213
+ new Date(analysis.firstTimestamp).getTime();
214
+ if (ms > 0)
215
+ durationStr = formatDuration(ms);
216
+ }
217
+ // Preflight impact
218
+ const preflightCost = (analysis.preflightTokens / 1_000_000) * pricing.input;
219
+ // Estimate: each preflight check prevents ~0.5 corrections on average
220
+ const estimatedPrevented = Math.round(analysis.preflightCalls * 0.5);
221
+ // Average wasted tokens per correction
222
+ const avgWastePerCorrection = analysis.corrections > 0
223
+ ? analysis.wastedOutputTokens / analysis.corrections
224
+ : 500;
225
+ const estimatedSavingsTokens = estimatedPrevented * avgWastePerCorrection;
226
+ const estimatedSavingsCost = (estimatedSavingsTokens / 1_000_000) * pricing.output;
227
+ // Build report
228
+ const lines = [
229
+ `📊 Session Cost Estimate`,
230
+ `━━━━━━━━━━━━━━━━━━━━━━`,
231
+ `Duration: ${durationStr} | ${analysis.promptCount} prompts | ${analysis.toolCallCount} tool calls`,
232
+ `File: ${basename(filePath)}`,
233
+ ``,
234
+ `Token Usage (estimated):`,
235
+ ` Input: ~${formatTokens(analysis.inputTokens)} tokens`,
236
+ ` Output: ~${formatTokens(analysis.outputTokens)} tokens`,
237
+ ` Total: ~${formatTokens(totalTokens)} tokens`,
238
+ ``,
239
+ `Estimated Cost: ~${formatCost(totalCost)} (${pricingModel.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase())})`,
240
+ ];
241
+ if (analysis.corrections > 0) {
242
+ lines.push(``, `Waste Analysis:`, ` Corrections detected: ${analysis.corrections}`, ` Wasted output tokens: ~${formatTokens(analysis.wastedOutputTokens)}`, ` Estimated waste: ~${formatCost(wasteCost)} (${wastePercent}% of total)`);
243
+ }
244
+ else {
245
+ lines.push(``, `Waste Analysis:`, ` No corrections detected 🎯`);
246
+ }
247
+ if (analysis.preflightCalls > 0) {
248
+ lines.push(``, `Preflight Impact:`, ` Preflight checks: ${analysis.preflightCalls} calls (~${formatTokens(analysis.preflightTokens)} tokens)`, ` Preflight cost: ~${formatCost(preflightCost)}`);
249
+ if (estimatedPrevented > 0) {
250
+ lines.push(` Estimated corrections prevented: ${estimatedPrevented}`, ` Estimated savings: ~${formatCost(estimatedSavingsCost)}`, ``, `💡 Net benefit: preflight saved ~${formatCost(estimatedSavingsCost - preflightCost)} this session`);
251
+ }
252
+ }
253
+ else {
254
+ lines.push(``, `Preflight Impact:`, ` No preflight checks used this session`, ` 💡 Tip: Use preflight_check to catch issues before they cost tokens`);
255
+ }
256
+ return {
257
+ content: [{ type: "text", text: lines.join("\n") }],
258
+ };
259
+ });
260
+ }
261
+ //# sourceMappingURL=estimate-cost.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"estimate-cost.js","sourceRoot":"","sources":["../../src/tools/estimate-cost.ts"],"names":[],"mappings":"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"}