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,324 @@
1
+ // src/cli/commands/setup.ts
2
+ import { existsSync, mkdirSync, writeFileSync } from "fs";
3
+ import { resolve, dirname } from "path";
4
+ import { createInterface } from "readline/promises";
5
+
6
+ // src/integrations/claude/generateSkills.ts
7
+ function generateClaudeSkills() {
8
+ return [
9
+ {
10
+ path: ".claude/skills/gauntlet-quick/SKILL.md",
11
+ description: "Claude Code skill for quick critique",
12
+ content: `---
13
+ name: gauntlet-quick
14
+ description: Run a quick adversarial critique of a product idea
15
+ ---
16
+
17
+ # Gauntlet Quick
18
+
19
+ Run a structured adversarial critique of a product idea.
20
+
21
+ ## Instructions
22
+ 1. Understand the product idea from the user's input.
23
+ 2. Analyze it using the skeptic and defender roles below.
24
+ 3. Present the report with: verdict, core insight, risks, assumptions, kill tests, next actions.
25
+
26
+ ## Prompt: Skeptic
27
+ You are the Skeptic in IdeaGauntlet. Find the strongest reasons this product idea may fail. Focus on hidden assumptions, user apathy, behavior-change cost, substitutes, distribution risk, retention risk, and monetization weakness. Return specific, testable objections.
28
+
29
+ ## Prompt: Defender
30
+ You are the Defender in IdeaGauntlet. Make the strongest honest case for the idea. Identify the most compelling wedge, the likely early adopters, and the narrow version of the idea most likely to work.
31
+ `
32
+ },
33
+ {
34
+ path: ".claude/skills/gauntlet-court/SKILL.md",
35
+ description: "Claude Code skill for court debate",
36
+ content: `---
37
+ name: gauntlet-court
38
+ description: Run a structured court-style debate on a product idea
39
+ ---
40
+
41
+ # Gauntlet Court
42
+
43
+ Run a multi-role structured debate.
44
+
45
+ ## Roles
46
+ 1. Prosecutor \u2014 attacks the idea
47
+ 2. Defender \u2014 argues why it could work
48
+ 3. User Advocate \u2014 argues from the user's perspective
49
+ 4. Investor \u2014 evaluates market, scale, defensibility
50
+ 5. Competitor \u2014 explains how the idea could be copied
51
+
52
+ ## Output
53
+ Judge verdict with unresolved questions.
54
+ `
55
+ },
56
+ {
57
+ path: ".claude/skills/gauntlet-users/SKILL.md",
58
+ description: "Claude Code skill for synthetic user generation",
59
+ content: `---
60
+ name: gauntlet-users
61
+ description: Generate synthetic user personas for hypothesis generation
62
+ ---
63
+
64
+ # Gauntlet Users
65
+
66
+ Generate fictional user archetypes to surface objections and prepare interview questions.
67
+
68
+ **IMPORTANT:** These are fictional archetypes for hypothesis generation, not real validation. Always label them as such.
69
+ `
70
+ },
71
+ {
72
+ path: ".claude/skills/gauntlet-mvp/SKILL.md",
73
+ description: "Claude Code skill for MVP validation planning",
74
+ content: `---
75
+ name: gauntlet-mvp
76
+ description: Generate an aggressive MVP validation plan
77
+ ---
78
+
79
+ # Gauntlet MVP
80
+
81
+ Turn critique into a concrete validation plan. Be aggressive about reducing scope. A 14-day plan should not include auth, payments, or onboarding flows.
82
+ `
83
+ }
84
+ ];
85
+ }
86
+
87
+ // src/integrations/claude/generateAgents.ts
88
+ function generateClaudeAgents() {
89
+ return [
90
+ {
91
+ path: ".claude/agents/skeptic.md",
92
+ description: "Claude Code subagent for Skeptic role",
93
+ content: `---
94
+ model:
95
+ name: claude-sonnet-5
96
+ instructions: |
97
+ You are the Skeptic in IdeaGauntlet.
98
+ Find the strongest reasons a product idea may fail.
99
+ Focus on hidden assumptions, user apathy, behavior-change cost, substitutes, distribution risk, retention risk, and monetization weakness.
100
+ Return specific, testable objections.
101
+ `
102
+ },
103
+ {
104
+ path: ".claude/agents/defender.md",
105
+ description: "Claude Code subagent for Defender role",
106
+ content: `---
107
+ model:
108
+ name: claude-sonnet-5
109
+ instructions: |
110
+ You are the Defender in IdeaGauntlet.
111
+ Make the strongest honest case for a product idea.
112
+ Do not exaggerate. Do not invent evidence.
113
+ Identify the most compelling wedge, the likely early adopters, and the narrow version of the idea most likely to work.
114
+ `
115
+ },
116
+ {
117
+ path: ".claude/agents/judge.md",
118
+ description: "Claude Code subagent for Judge role",
119
+ content: `---
120
+ model:
121
+ name: claude-sonnet-5
122
+ instructions: |
123
+ You are the Judge in IdeaGauntlet.
124
+ Synthesize arguments from all agents into a conservative verdict.
125
+ Separate what is known, what is assumed, and what must be tested.
126
+ Do not predict success. Recommend the next validation step.
127
+ `
128
+ }
129
+ ];
130
+ }
131
+
132
+ // src/integrations/claude/generateCommands.ts
133
+ function generateClaudeCommands() {
134
+ return [
135
+ {
136
+ path: ".claude/commands/gauntlet-quick.md",
137
+ description: "Claude Code slash command for quick critique",
138
+ content: `---
139
+ name: gauntlet-quick
140
+ description: Run an IdeaGauntlet quick critique on the current product idea
141
+ ---
142
+ Run a structured adversarial critique using the Skeptic and Defender roles. Output a verdict with core insight, risks, assumptions, kill tests, and next actions.
143
+ `
144
+ },
145
+ {
146
+ path: ".claude/commands/gauntlet-court.md",
147
+ description: "Claude Code slash command for court debate",
148
+ content: `---
149
+ name: gauntlet-court
150
+ description: Run an IdeaGauntlet court-style debate
151
+ ---
152
+ Run a structured debate with Prosecutor, Defender, User Advocate, Investor, and Competitor roles. End with a Judge verdict.
153
+ `
154
+ }
155
+ ];
156
+ }
157
+
158
+ // src/integrations/cursor/generateCursorRules.ts
159
+ function generateCursorRules() {
160
+ return [
161
+ {
162
+ path: ".cursor/rules/idea-gauntlet-quick.mdc",
163
+ description: "Cursor rule for quick critique",
164
+ content: `---
165
+ description: Run an IdeaGauntlet-style quick critique on product ideas
166
+ globs: *.md
167
+ ---
168
+ When asked to evaluate a product idea, use the IdeaGauntlet framework:
169
+ 1. Identify the core insight
170
+ 2. Find the weakest assumption
171
+ 3. List top failure modes
172
+ 4. Propose kill tests
173
+ 5. Suggest next actions
174
+ `
175
+ }
176
+ ];
177
+ }
178
+
179
+ // src/integrations/codex/generateAgentsMd.ts
180
+ function generateCodexConfig() {
181
+ return [
182
+ {
183
+ path: "AGENTS.md",
184
+ description: "Codex agent definitions",
185
+ content: `# Codex Agents \u2014 IdeaGauntlet
186
+
187
+ ## skeptic
188
+ An agent that attacks product ideas to find weaknesses.
189
+
190
+ ## defender
191
+ An agent that makes the strongest honest case for a product idea.
192
+
193
+ ## judge
194
+ An agent that synthesizes arguments into a conservative verdict.
195
+ `
196
+ },
197
+ {
198
+ path: ".codex/config.toml",
199
+ description: "Codex TOML configuration",
200
+ content: `[agents]
201
+ skeptic = { definition = "AGENTS.md#skeptic" }
202
+ defender = { definition = "AGENTS.md#defender" }
203
+ judge = { definition = "AGENTS.md#judge" }
204
+ `
205
+ }
206
+ ];
207
+ }
208
+
209
+ // src/integrations/github/generateActionYaml.ts
210
+ function generateGitHubAction() {
211
+ return [
212
+ {
213
+ path: ".github/workflows/idea-gauntlet.yml",
214
+ description: "GitHub Action for PR idea critique",
215
+ content: `name: IdeaGauntlet Critique
216
+ on:
217
+ issues:
218
+ types: [opened]
219
+ jobs:
220
+ critique:
221
+ runs-on: ubuntu-latest
222
+ steps:
223
+ - uses: actions/checkout@v4
224
+ - run: npx idea-gauntlet quick "\${{ github.event.issue.title }}" --mock
225
+ `
226
+ }
227
+ ];
228
+ }
229
+
230
+ // src/cli/commands/setup.ts
231
+ var ALL_GROUPS = [
232
+ { key: "claude-skills", label: "Claude Code skills", files: generateClaudeSkills() },
233
+ { key: "claude-agents", label: "Claude Code agents", files: generateClaudeAgents() },
234
+ { key: "claude-commands", label: "Claude Code commands", files: generateClaudeCommands() },
235
+ { key: "cursor", label: "Cursor rules", files: generateCursorRules() },
236
+ { key: "codex", label: "Codex AGENTS.md + config", files: generateCodexConfig() },
237
+ { key: "github-action", label: "GitHub Action workflow", files: generateGitHubAction() }
238
+ ];
239
+ async function setupCommand(options) {
240
+ const all = !!options.all;
241
+ const dryRun = !!(options["dry-run"] ?? options.dryRun);
242
+ const force = !!options.force;
243
+ const targets = options.targets ?? (all ? ALL_GROUPS.map((g) => g.key).join(",") : "");
244
+ const selected = ALL_GROUPS.filter((g) => targets.split(",").map((s) => s.trim()).includes(g.key));
245
+ if (selected.length === 0) {
246
+ console.log("No integration targets selected. Use --all or --targets.");
247
+ console.log("Available: " + ALL_GROUPS.map((g) => g.key).join(", "));
248
+ return;
249
+ }
250
+ const allFiles = selected.flatMap((g) => g.files);
251
+ if (dryRun) {
252
+ console.log("\n\u{1F4CB} Dry run \u2014 files that would be created:\n");
253
+ for (const g of selected) {
254
+ if (g.files.length === 0) continue;
255
+ console.log(` ${g.label}:`);
256
+ for (const f of g.files) {
257
+ const exists = existsSync(resolve(process.cwd(), f.path));
258
+ console.log(` ${exists ? "\u26A0" : " "} ${f.path} (${f.description})`);
259
+ }
260
+ console.log("");
261
+ }
262
+ const total = selected.reduce((s, g) => s + g.files.length, 0);
263
+ console.log(`${total} file(s) would be processed.`);
264
+ return;
265
+ }
266
+ let written = 0;
267
+ let skipped = 0;
268
+ for (const f of allFiles) {
269
+ const fullPath = resolve(process.cwd(), f.path);
270
+ const dir = dirname(fullPath);
271
+ if (existsSync(fullPath) && !force) {
272
+ const action = await resolveConflict(f.path);
273
+ if (action === "skip") {
274
+ skipped++;
275
+ continue;
276
+ }
277
+ if (action === "overwrite") {
278
+ }
279
+ if (action === "sidecar") {
280
+ const sidecarPath = fullPath + ".idea-gauntlet";
281
+ mkdirSync(dirname(sidecarPath), { recursive: true });
282
+ writeFileSync(sidecarPath, f.content, "utf-8");
283
+ written++;
284
+ continue;
285
+ }
286
+ if (action === "append") {
287
+ const existing = (await import("fs")).readFileSync(fullPath, "utf-8");
288
+ writeFileSync(fullPath, existing + "\n\n<!-- IdeaGauntlet -->\n" + f.content, "utf-8");
289
+ written++;
290
+ continue;
291
+ }
292
+ }
293
+ mkdirSync(dir, { recursive: true });
294
+ writeFileSync(fullPath, f.content, "utf-8");
295
+ written++;
296
+ }
297
+ console.log(`
298
+ \u2713 ${written} file(s) written, ${skipped} skipped.`);
299
+ }
300
+ async function resolveConflict(path) {
301
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
302
+ console.log(`
303
+ File already exists: ${path}`);
304
+ console.log(" [A] Append IdeaGauntlet section");
305
+ console.log(" [B] Create sidecar file");
306
+ console.log(" [C] Skip");
307
+ console.log(" [D] Overwrite");
308
+ const answer = (await rl.question("Choose (A/B/C/D): ")).trim().toLowerCase();
309
+ rl.close();
310
+ switch (answer) {
311
+ case "a":
312
+ return "append";
313
+ case "b":
314
+ return "sidecar";
315
+ case "d":
316
+ return "overwrite";
317
+ default:
318
+ return "skip";
319
+ }
320
+ }
321
+
322
+ export {
323
+ setupCommand
324
+ };