idea-gauntlet 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.
@@ -0,0 +1,210 @@
1
+ import { z } from 'zod';
2
+
3
+ type IdeaStage = "napkin" | "pre-mvp" | "mvp" | "growth";
4
+ type GauntletMode = "quick" | "court" | "users" | "mvp" | "compare";
5
+ type Verdict = "strong" | "promising_but_risky" | "unclear" | "weak" | "needs_real_evidence" | "pivot_recommended";
6
+ type Severity = "low" | "medium" | "high" | "critical";
7
+ type Confidence = "low" | "medium" | "high";
8
+ type WillingnessToPay = "none" | "low" | "medium" | "high";
9
+ type OnboardingChoice = "ollama" | "generate_prompt" | "mock" | "configure_key" | "setup_agent_native";
10
+ type IntegrationTarget = "claude-skills" | "claude-agents" | "claude-commands" | "codex" | "cursor" | "mcp" | "github-action";
11
+ declare const IdeaStageSchema: z.ZodEnum<["napkin", "pre-mvp", "mvp", "growth"]>;
12
+ declare const GauntletModeSchema: z.ZodEnum<["quick", "court", "users", "mvp", "compare"]>;
13
+ declare const SeveritySchema: z.ZodEnum<["low", "medium", "high", "critical"]>;
14
+ declare const ConfidenceSchema: z.ZodEnum<["low", "medium", "high"]>;
15
+ declare const WillingnessToPaySchema: z.ZodEnum<["none", "low", "medium", "high"]>;
16
+ declare const VerdictSchema: z.ZodEnum<["strong", "promising_but_risky", "unclear", "weak", "needs_real_evidence", "pivot_recommended"]>;
17
+ declare const IdeaInputSchema: z.ZodObject<{
18
+ title: z.ZodOptional<z.ZodString>;
19
+ idea: z.ZodString;
20
+ targetUsers: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
21
+ market: z.ZodOptional<z.ZodString>;
22
+ stage: z.ZodOptional<z.ZodEnum<["napkin", "pre-mvp", "mvp", "growth"]>>;
23
+ constraints: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
24
+ mode: z.ZodOptional<z.ZodEnum<["quick", "court", "users", "mvp", "compare"]>>;
25
+ }, "strip", z.ZodTypeAny, {
26
+ idea: string;
27
+ title?: string | undefined;
28
+ targetUsers?: string[] | undefined;
29
+ market?: string | undefined;
30
+ stage?: "napkin" | "pre-mvp" | "mvp" | "growth" | undefined;
31
+ constraints?: Record<string, unknown> | undefined;
32
+ mode?: "mvp" | "quick" | "court" | "users" | "compare" | undefined;
33
+ }, {
34
+ idea: string;
35
+ title?: string | undefined;
36
+ targetUsers?: string[] | undefined;
37
+ market?: string | undefined;
38
+ stage?: "napkin" | "pre-mvp" | "mvp" | "growth" | undefined;
39
+ constraints?: Record<string, unknown> | undefined;
40
+ mode?: "mvp" | "quick" | "court" | "users" | "compare" | undefined;
41
+ }>;
42
+ type IdeaInput = z.infer<typeof IdeaInputSchema>;
43
+ interface Scorecard {
44
+ clarity: number;
45
+ pain: number;
46
+ differentiation: number;
47
+ buildability: number;
48
+ distribution: number;
49
+ monetization: number;
50
+ evidence: number;
51
+ }
52
+ interface Risk {
53
+ title: string;
54
+ severity: Severity;
55
+ explanation: string;
56
+ mitigation?: string;
57
+ }
58
+ interface Assumption {
59
+ title: string;
60
+ whyItMatters: string;
61
+ howToTest: string;
62
+ confidence: Confidence;
63
+ }
64
+ interface KillTest {
65
+ title: string;
66
+ method: string;
67
+ timeframe: string;
68
+ successSignal: string;
69
+ killSignal: string;
70
+ }
71
+ interface SyntheticPersona {
72
+ name: string;
73
+ archetype: string;
74
+ goal: string;
75
+ currentWorkaround: string;
76
+ triggerToTry: string;
77
+ primaryObjection: string;
78
+ willingnessToPay: WillingnessToPay;
79
+ likelyChurnReason: string;
80
+ quote: string;
81
+ interviewQuestion: string;
82
+ }
83
+ interface CourtTurn {
84
+ role: string;
85
+ argument: string;
86
+ }
87
+ interface CourtSession {
88
+ transcript: CourtTurn[];
89
+ verdict: string;
90
+ unresolvedQuestions: string[];
91
+ }
92
+ interface MVPPlan {
93
+ goal: string;
94
+ scope: string[];
95
+ nonGoals: string[];
96
+ timeline: string;
97
+ metrics: string[];
98
+ }
99
+ interface ComparedIdea {
100
+ title: string;
101
+ verdict: Verdict;
102
+ score: number;
103
+ riskiestAssumption: string;
104
+ evidenceScore: number;
105
+ }
106
+ interface ComparisonResult {
107
+ ideas: ComparedIdea[];
108
+ ranking: string[];
109
+ fastestToValidate: string;
110
+ highestUpside: string;
111
+ recommendedPick: string;
112
+ }
113
+ interface GauntletReport {
114
+ id: string;
115
+ createdAt: string;
116
+ mode: GauntletMode;
117
+ input: IdeaInput;
118
+ verdict: Verdict;
119
+ scores?: Scorecard;
120
+ coreInsight?: string;
121
+ strongestCase?: string;
122
+ weakestAssumption?: string;
123
+ risks?: Risk[];
124
+ assumptions?: Assumption[];
125
+ killTests?: KillTest[];
126
+ syntheticUsers?: SyntheticPersona[];
127
+ court?: CourtSession;
128
+ comparison?: ComparisonResult;
129
+ mvpPlan?: MVPPlan;
130
+ nextActions?: string[];
131
+ markdown: string;
132
+ }
133
+ interface CompletionOptions {
134
+ system?: string;
135
+ temperature?: number;
136
+ maxTokens?: number;
137
+ }
138
+ interface LLMProvider {
139
+ kind: "mock" | "openai" | "ollama" | "custom";
140
+ complete(prompt: string, options?: CompletionOptions): Promise<string>;
141
+ }
142
+
143
+ declare function runImmuneEngine(idea: IdeaInput, provider: LLMProvider): Promise<GauntletReport>;
144
+
145
+ declare function runGauntlet(params: {
146
+ idea: string;
147
+ targetUsers?: string[];
148
+ market?: string;
149
+ stage?: string;
150
+ constraints?: Record<string, unknown>;
151
+ mode?: GauntletMode;
152
+ provider?: LLMProvider;
153
+ }): Promise<GauntletReport>;
154
+
155
+ declare function buildReport(report: GauntletReport): string;
156
+
157
+ declare function calculateScores(params: {
158
+ hasEvidence: boolean;
159
+ evidenceStrength?: "weak" | "medium" | "strong";
160
+ overrides?: Partial<Scorecard>;
161
+ }): Scorecard;
162
+ declare function medianScore(scores: Scorecard): number;
163
+
164
+ declare class MockProvider implements LLMProvider {
165
+ kind: "mock";
166
+ complete(prompt: string, options?: CompletionOptions): Promise<string>;
167
+ }
168
+
169
+ type OpenAICompatibleConfig = {
170
+ apiKey: string;
171
+ baseUrl?: string;
172
+ model?: string;
173
+ };
174
+ declare class OpenAICompatibleProvider implements LLMProvider {
175
+ kind: "openai";
176
+ private config;
177
+ constructor(config: OpenAICompatibleConfig);
178
+ complete(prompt: string, options?: CompletionOptions): Promise<string>;
179
+ }
180
+
181
+ declare class OllamaProvider implements LLMProvider {
182
+ kind: "ollama";
183
+ private baseUrl;
184
+ private model;
185
+ constructor(model?: string, baseUrl?: string);
186
+ complete(prompt: string, options?: CompletionOptions): Promise<string>;
187
+ }
188
+
189
+ type ProviderResolution = {
190
+ provider: LLMProvider;
191
+ source: "mock" | "flags" | "env" | "ollama" | null;
192
+ };
193
+ declare function resolveProvider(options?: {
194
+ mock?: boolean;
195
+ apiKey?: string;
196
+ baseUrl?: string;
197
+ model?: string;
198
+ ollama?: boolean;
199
+ }): ProviderResolution | null;
200
+ declare function getProvider(options?: {
201
+ mock?: boolean;
202
+ apiKey?: string;
203
+ baseUrl?: string;
204
+ model?: string;
205
+ }): LLMProvider;
206
+ declare class NoProviderError extends Error {
207
+ constructor();
208
+ }
209
+
210
+ export { type Assumption, type ComparedIdea, type ComparisonResult, type CompletionOptions, type Confidence, ConfidenceSchema, type CourtSession, type CourtTurn, type GauntletMode, GauntletModeSchema, type GauntletReport, type IdeaInput, IdeaInputSchema, type IdeaStage, IdeaStageSchema, type IntegrationTarget, type KillTest, type LLMProvider, type MVPPlan, MockProvider, NoProviderError, OllamaProvider, type OnboardingChoice, OpenAICompatibleProvider, type Risk, type Scorecard, type Severity, SeveritySchema, type SyntheticPersona, type Verdict, VerdictSchema, type WillingnessToPay, WillingnessToPaySchema, buildReport, calculateScores, getProvider, medianScore, resolveProvider, runGauntlet, runImmuneEngine };
package/dist/index.js ADDED
@@ -0,0 +1,139 @@
1
+ import {
2
+ MockProvider,
3
+ NoProviderError,
4
+ OpenAICompatibleProvider,
5
+ buildReport,
6
+ calculateScores,
7
+ getProvider,
8
+ medianScore,
9
+ resolveProvider,
10
+ runCompareEngine,
11
+ runCourtEngine,
12
+ runImmuneEngine,
13
+ runMvpPlanner,
14
+ runUserLab
15
+ } from "./chunk-P4FDULQC.js";
16
+ import "./chunk-VQHEJYTS.js";
17
+
18
+ // src/core/types.ts
19
+ import { z } from "zod";
20
+ var IdeaStageSchema = z.enum(["napkin", "pre-mvp", "mvp", "growth"]);
21
+ var GauntletModeSchema = z.enum([
22
+ "quick",
23
+ "court",
24
+ "users",
25
+ "mvp",
26
+ "compare"
27
+ ]);
28
+ var SeveritySchema = z.enum(["low", "medium", "high", "critical"]);
29
+ var ConfidenceSchema = z.enum(["low", "medium", "high"]);
30
+ var WillingnessToPaySchema = z.enum(["none", "low", "medium", "high"]);
31
+ var VerdictSchema = z.enum([
32
+ "strong",
33
+ "promising_but_risky",
34
+ "unclear",
35
+ "weak",
36
+ "needs_real_evidence",
37
+ "pivot_recommended"
38
+ ]);
39
+ var IdeaInputSchema = z.object({
40
+ title: z.string().optional(),
41
+ idea: z.string(),
42
+ targetUsers: z.array(z.string()).optional(),
43
+ market: z.string().optional(),
44
+ stage: IdeaStageSchema.optional(),
45
+ constraints: z.record(z.unknown()).optional(),
46
+ mode: GauntletModeSchema.optional()
47
+ });
48
+
49
+ // src/core/runGauntlet.ts
50
+ async function runGauntlet(params) {
51
+ if (!params.provider) {
52
+ throw new Error("LLM provider is required. Pass --mock or set IDEAGAUNTLET_API_KEY.");
53
+ }
54
+ const input = {
55
+ idea: params.idea,
56
+ targetUsers: params.targetUsers,
57
+ market: params.market,
58
+ stage: params.stage,
59
+ constraints: params.constraints,
60
+ mode: params.mode ?? "quick"
61
+ };
62
+ const mode = params.mode ?? "quick";
63
+ let report;
64
+ switch (mode) {
65
+ case "quick":
66
+ report = await runImmuneEngine(input, params.provider);
67
+ break;
68
+ case "court":
69
+ report = await runCourtEngine(input, params.provider);
70
+ break;
71
+ case "users":
72
+ report = await runUserLab(input, params.provider);
73
+ break;
74
+ case "mvp":
75
+ report = await runMvpPlanner(input, params.provider);
76
+ break;
77
+ case "compare":
78
+ report = await runCompareEngine([input], params.provider);
79
+ break;
80
+ default:
81
+ report = await runImmuneEngine(input, params.provider);
82
+ break;
83
+ }
84
+ report.markdown = buildReport(report);
85
+ return report;
86
+ }
87
+
88
+ // src/providers/ollamaProvider.ts
89
+ var OllamaProvider = class {
90
+ kind = "ollama";
91
+ baseUrl;
92
+ model;
93
+ constructor(model, baseUrl) {
94
+ this.baseUrl = baseUrl ?? "http://localhost:11434";
95
+ this.model = model ?? "llama3";
96
+ }
97
+ async complete(prompt, options) {
98
+ const url = `${this.baseUrl}/api/chat`;
99
+ const messages = [];
100
+ if (options?.system) messages.push({ role: "system", content: options.system });
101
+ messages.push({ role: "user", content: prompt });
102
+ const response = await fetch(url, {
103
+ method: "POST",
104
+ headers: { "Content-Type": "application/json" },
105
+ body: JSON.stringify({
106
+ model: this.model,
107
+ messages,
108
+ stream: false,
109
+ options: { temperature: options?.temperature ?? 0.4, num_predict: options?.maxTokens ?? 2048 }
110
+ })
111
+ });
112
+ if (!response.ok) {
113
+ const text = await response.text();
114
+ throw new Error(`Ollama returned ${response.status}: ${text}`);
115
+ }
116
+ const data = await response.json();
117
+ return data.message?.content ?? "";
118
+ }
119
+ };
120
+ export {
121
+ ConfidenceSchema,
122
+ GauntletModeSchema,
123
+ IdeaInputSchema,
124
+ IdeaStageSchema,
125
+ MockProvider,
126
+ NoProviderError,
127
+ OllamaProvider,
128
+ OpenAICompatibleProvider,
129
+ SeveritySchema,
130
+ VerdictSchema,
131
+ WillingnessToPaySchema,
132
+ buildReport,
133
+ calculateScores,
134
+ getProvider,
135
+ medianScore,
136
+ resolveProvider,
137
+ runGauntlet,
138
+ runImmuneEngine
139
+ };
@@ -0,0 +1,9 @@
1
+ import {
2
+ startMcpServer
3
+ } from "./chunk-A6GCV4RD.js";
4
+ import "./chunk-P4FDULQC.js";
5
+ import "./chunk-VQHEJYTS.js";
6
+ import "./chunk-FF7CULAJ.js";
7
+ export {
8
+ startMcpServer
9
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ setupCommand
3
+ } from "./chunk-HW6JACOL.js";
4
+ export {
5
+ setupCommand
6
+ };
@@ -0,0 +1,6 @@
1
+ import {
2
+ skeptic
3
+ } from "./chunk-VQHEJYTS.js";
4
+ export {
5
+ skeptic
6
+ };
package/package.json ADDED
@@ -0,0 +1,53 @@
1
+ {
2
+ "name": "idea-gauntlet",
3
+ "version": "0.1.0",
4
+ "description": "Stress-test product ideas with adversarial agents, synthetic users, and court-style critique.",
5
+ "type": "module",
6
+ "bin": {
7
+ "idea-gauntlet": "dist/cli/index.js"
8
+ },
9
+ "exports": {
10
+ ".": {
11
+ "import": "./dist/index.js",
12
+ "types": "./dist/index.d.ts"
13
+ },
14
+ "./cli": {
15
+ "import": "./dist/cli/index.js",
16
+ "types": "./dist/cli/index.d.ts"
17
+ }
18
+ },
19
+ "files": [
20
+ "dist"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsup src/index.ts src/cli/index.ts --format esm --dts --clean",
24
+ "dev": "tsx src/cli/index.ts",
25
+ "start": "node dist/cli/index.js",
26
+ "test": "vitest run",
27
+ "test:watch": "vitest",
28
+ "typecheck": "tsc --noEmit",
29
+ "prepublishOnly": "npm run build"
30
+ },
31
+ "keywords": [
32
+ "product-discovery",
33
+ "validation",
34
+ "adversarial",
35
+ "startup",
36
+ "idea"
37
+ ],
38
+ "license": "MIT",
39
+ "engines": {
40
+ "node": ">=18"
41
+ },
42
+ "dependencies": {
43
+ "cac": "^6.7.14",
44
+ "zod": "^3.23.0"
45
+ },
46
+ "devDependencies": {
47
+ "typescript": "^5.5.0",
48
+ "tsup": "^8.2.0",
49
+ "tsx": "^4.16.0",
50
+ "vitest": "^2.0.0",
51
+ "@types/node": "^20.0.0"
52
+ }
53
+ }