@grainulation/wheat 1.0.4 → 1.0.6

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/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  </p>
4
4
 
5
5
  <p align="center">
6
- <a href="https://www.npmjs.com/package/@grainulation/wheat"><img src="https://img.shields.io/npm/v/@grainulation/wheat" alt="npm version"></a> <a href="https://www.npmjs.com/package/@grainulation/wheat"><img src="https://img.shields.io/npm/dm/@grainulation/wheat" alt="npm downloads"></a> <a href="https://github.com/grainulation/wheat/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="license"></a> <a href="https://nodejs.org"><img src="https://img.shields.io/node/v/@grainulation/wheat" alt="node"></a> <a href="https://github.com/grainulation/wheat/actions"><img src="https://github.com/grainulation/wheat/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
6
+ <a href="https://www.npmjs.com/package/@grainulation/wheat"><img src="https://img.shields.io/npm/v/@grainulation/wheat?label=%40grainulation%2Fwheat" alt="npm version"></a> <a href="https://www.npmjs.com/package/@grainulation/wheat"><img src="https://img.shields.io/npm/dm/@grainulation/wheat" alt="npm downloads"></a> <a href="https://github.com/grainulation/wheat/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green" alt="license"></a> <a href="https://nodejs.org"><img src="https://img.shields.io/node/v/@grainulation/wheat" alt="node"></a> <a href="https://github.com/grainulation/wheat/actions"><img src="https://github.com/grainulation/wheat/actions/workflows/ci.yml/badge.svg" alt="CI"></a>
7
7
  <a href="https://deepwiki.com/grainulation/wheat"><img src="https://deepwiki.com/badge.svg" alt="Explore on DeepWiki"></a>
8
8
  </p>
9
9
 
@@ -15,118 +15,99 @@ The migration will take months. It will cost real money. And right now, the deci
15
15
 
16
16
  You'd never ship code without tests. Why ship a decision without validated evidence?
17
17
 
18
- Wheat is a continuous planning pipeline. Every finding is a typed assertion. A compiler validates them. You can't ship with contradictions, same as you can't merge with failing tests.
19
-
20
- ## Install
18
+ ## Quick start
21
19
 
22
20
  ```bash
23
- npx @grainulation/wheat init
21
+ npx @grainulation/wheat "Should we migrate to GraphQL?"
24
22
  ```
25
23
 
26
- No dependencies are added to your project. No `node_modules` pollution. Wheat is a tool you run, not a library you import.
24
+ One command. Zero prompts. Sprint ready in under 3 seconds.
27
25
 
28
- ## See it in 30 seconds
26
+ Then open your AI coding tool and start investigating:
29
27
 
30
- ```bash
31
- npx @grainulation/wheat quickstart
28
+ ```
29
+ /research "GraphQL performance vs REST"
30
+ /challenge r003
31
+ /blind-spot
32
+ /brief
32
33
  ```
33
34
 
34
- Creates a demo build with pre-seeded assertions, an intentional conflict, compiles everything, and opens a dashboard. You'll see the compiler flag the conflict and block output until it's resolved.
35
+ Works with [Claude Code](https://claude.com/claude-code), [Cursor](https://cursor.com), [GitHub Copilot](https://github.com/features/copilot), or standalone via CLI.
35
36
 
36
- ## Start a real investigation
37
+ ## Full MCP integration (optional)
38
+
39
+ For native tool access in Claude Code:
37
40
 
38
41
  ```bash
39
- npx @grainulation/wheat init
42
+ claude mcp add wheat -- npx -y @grainulation/wheat mcp
40
43
  ```
41
44
 
42
- Wheat asks a few questions -- what you're investigating, who needs the answer, what constraints exist. Then it scaffolds the investigation in your repo:
43
-
44
- ```
45
- claims.json # Typed assertions (the test suite for your decision)
46
- CLAUDE.md # AI assistant configuration
47
- .claude/commands/ # 18 slash commands
48
- output/ # Where compiled artifacts land
49
- ```
45
+ This gives Claude direct access to wheat's claims engine add-claim, compile, search, status without shelling out.
50
46
 
51
- Open Claude Code and start investigating:
47
+ ## See it in 30 seconds
52
48
 
53
- ```
54
- /research "Postgres migration risks"
55
- /prototype # build something testable
56
- /challenge r003 # stress-test a finding
57
- /blind-spot # what are we missing?
58
- /brief # compile the decision document
49
+ ```bash
50
+ npx @grainulation/wheat quickstart
59
51
  ```
60
52
 
53
+ Creates a demo sprint with pre-seeded claims, an intentional conflict, compiles everything, and opens a dashboard. The compiler flags the conflict and blocks output until it's resolved.
54
+
61
55
  ## How it works
62
56
 
63
- Wheat is a continuous planning pipeline. Findings are validated as they come in, not after the fact:
57
+ Wheat is a continuous planning pipeline. Findings are validated as they come in:
64
58
 
65
59
  ```
66
- You investigate --> Assertions accumulate --> Compiler validates --> Artifacts compile
67
- /research claims.json wheat compile /brief, /present
68
- /prototype (typed, evidence-graded) (7-pass pipeline) (backed by evidence)
69
- /challenge
60
+ You investigate Claims accumulate Compiler validates Brief compiles
61
+ /research typed, evidence-graded 7-pass pipeline backed by evidence
62
+ /prototype
63
+ /challenge
70
64
  ```
71
65
 
72
- **Assertion types:** constraint, factual, estimate, risk, recommendation, feedback
66
+ **Claim types:** constraint, factual, estimate, risk, recommendation, feedback
73
67
 
74
- **Evidence tiers** (like test coverage): stated (untested) > web > documented > tested > production (battle-hardened)
68
+ **Evidence tiers:** stated web documented tested production
75
69
 
76
- The compiler catches conflicts, warns about weak evidence, and blocks the build when issues exist. You cannot ship a brief built on unresolved contradictions — same as you can't merge with failing tests.
70
+ The compiler catches conflicts, flags weak evidence, and blocks the build when issues exist. You can't ship a brief built on contradictions — same as you can't merge with failing tests.
77
71
 
78
72
  ## Commands
79
73
 
80
- | Command | What it does |
81
- | --------------------- | ------------------------------------------------- |
82
- | `/init` | Bootstrap a new research sprint |
83
- | `/research <topic>` | Deep dive on a topic, creates claims |
84
- | `/prototype` | Build something testable |
85
- | `/challenge <id>` | Adversarial stress-test of a claim |
86
- | `/witness <id> <url>` | External corroboration |
87
- | `/blind-spot` | Find gaps in your investigation |
88
- | `/status` | Sprint dashboard |
89
- | `/brief` | Compile the decision document |
90
- | `/present` | Generate a stakeholder presentation |
91
- | `/feedback` | Incorporate stakeholder input |
92
- | `/resolve` | Adjudicate conflicts between claims |
93
- | `/replay` | Time-travel through sprint history |
94
- | `/calibrate` | Score predictions against actual outcomes |
95
- | `/handoff` | Package sprint for knowledge transfer |
96
- | `/merge <path>` | Combine findings across sprints |
97
- | `/connect <type>` | Link external tools (Jira, docs, etc.) |
98
- | `/evaluate` | Test claims against reality, resolve conflicts |
99
- | `/next` | Route next steps through Farmer (mobile feedback) |
74
+ | Command | What it does |
75
+ |---------|-------------|
76
+ | `/research <topic>` | Deep dive on a topic, creates claims |
77
+ | `/prototype` | Build something testable |
78
+ | `/challenge <id>` | Adversarial stress-test of a claim |
79
+ | `/witness <id> <url>` | External corroboration |
80
+ | `/blind-spot` | Find gaps in your investigation |
81
+ | `/brief` | Compile the decision document |
82
+ | `/status` | Sprint dashboard |
83
+ | `/present` | Generate a stakeholder presentation |
84
+ | `/resolve` | Adjudicate conflicts between claims |
100
85
 
101
86
  ## Guard rails
102
87
 
103
- Wheat installs two guard mechanisms:
104
-
105
- 1. **Git pre-commit hook** -- prevents committing broken `claims.json`
106
- 2. **Claude Code guard hook** -- prevents generating output artifacts from stale or blocked compilations
107
-
108
- Both are optional and can be removed.
109
-
110
- ## Works in any repo
88
+ Wheat installs two optional guard mechanisms:
111
89
 
112
- Wheat doesn't care what language you use. Your Scala project, your Python monorepo, your Flutter app -- wheat works the same everywhere. Node 18+ is the only requirement.
90
+ 1. **Git pre-commit hook** prevents committing broken claims
91
+ 2. **Claude Code guard hook** — prevents generating output from stale compilations
113
92
 
114
- ## Zero dependencies
93
+ ## Works everywhere
115
94
 
116
- Node built-in modules only. No npm install waterfall. No supply chain anxiety.
95
+ Wheat doesn't care what language you use or what AI tool you run. Your Scala project, your Python monorepo, your Flutter app — wheat works the same everywhere. Node 20+ is the only requirement. Zero npm dependencies.
117
96
 
118
97
  ## Part of the grainulation ecosystem
119
98
 
120
- | Tool | Role |
121
- | ------------------------------------------------------------ | ------------------------------------------------------------------------------ |
122
- | **wheat** | Research engine -- grow structured evidence |
123
- | [farmer](https://github.com/grainulation/farmer) | Permission dashboard -- approve AI actions in real time (admin + viewer roles) |
124
- | [barn](https://github.com/grainulation/barn) | Shared tools -- templates, validators, sprint detection |
125
- | [mill](https://github.com/grainulation/mill) | Format conversion -- export to PDF, CSV, slides, 24 formats |
126
- | [silo](https://github.com/grainulation/silo) | Knowledge storage -- reusable claim libraries and packs |
127
- | [harvest](https://github.com/grainulation/harvest) | Analytics -- cross-sprint patterns and prediction scoring |
128
- | [orchard](https://github.com/grainulation/orchard) | Orchestration -- multi-sprint coordination and dependencies |
129
- | [grainulation](https://github.com/grainulation/grainulation) | Unified CLI -- single entry point to the ecosystem |
99
+ | Tool | Role |
100
+ |------|------|
101
+ | **wheat** | Research engine grow structured evidence |
102
+ | [farmer](https://github.com/grainulation/farmer) | Permission dashboard approve AI actions in real time |
103
+ | [barn](https://github.com/grainulation/barn) | Shared tools templates, validators, sprint detection |
104
+ | [mill](https://github.com/grainulation/mill) | Format conversion export to PDF, CSV, slides |
105
+ | [silo](https://github.com/grainulation/silo) | Knowledge storage reusable claim libraries |
106
+ | [harvest](https://github.com/grainulation/harvest) | Analytics cross-sprint patterns and prediction scoring |
107
+ | [orchard](https://github.com/grainulation/orchard) | Orchestration multi-sprint coordination |
108
+ | [grainulation](https://github.com/grainulation/grainulation) | Unified CLI single entry point to the ecosystem |
109
+
110
+ **You don't need all eight.** Start with wheat. That's it.
130
111
 
131
112
  ## License
132
113
 
package/bin/wheat.js CHANGED
@@ -67,7 +67,8 @@ if (!subcommand || subcommand === "--help" || subcommand === "-h") {
67
67
  console.log(`wheat v${VERSION} — Research-driven development framework
68
68
 
69
69
  Usage:
70
- wheat <command> [options]
70
+ wheat "your question" Start a sprint instantly (recommended)
71
+ wheat <command> [options] Run a specific command
71
72
 
72
73
  Commands:
73
74
  init Bootstrap a new research sprint in this repo
@@ -90,11 +91,9 @@ Global options:
90
91
  --help Show this help
91
92
 
92
93
  Examples:
93
- npx @grainulation/wheat quickstart
94
+ npx @grainulation/wheat "Should we migrate to Postgres?"
94
95
  npx @grainulation/wheat init
95
96
  npx @grainulation/wheat compile --summary
96
- npx @grainulation/wheat init --question "Should we migrate to Postgres?"
97
- npx @grainulation/wheat init --non-interactive --question "..." --audience "..." --done "..."
98
97
 
99
98
  Documentation: https://github.com/grainulation/wheat`);
100
99
  process.exit(0);
@@ -189,6 +188,19 @@ Run "wheat disconnect farmer --help" for options.`);
189
188
  }
190
189
 
191
190
  if (!commands[subcommand]) {
191
+ // Verb-less mode: wheat "my question" → dispatch to init with auto defaults
192
+ const compoundCmds = ["connect", "disconnect", "migrate"];
193
+ if (subcommand && !subcommand.startsWith("-") && !compoundCmds.includes(subcommand)) {
194
+ vlog("dispatch", `verb-less mode: treating "${subcommand}" as question`);
195
+ const initPath = new URL(commands.init, import.meta.url).href;
196
+ const initHandler = await import(initPath);
197
+ await initHandler.run(targetDir, ["--question", subcommand, "--auto"]).catch((err) => {
198
+ console.error(`\nwheat failed:`, err.message);
199
+ if (process.env.WHEAT_DEBUG) console.error(err.stack);
200
+ process.exit(1);
201
+ });
202
+ process.exit(0);
203
+ }
192
204
  console.error(`wheat: unknown command: ${subcommand}\n`);
193
205
  console.error('Run "wheat --help" for available commands.');
194
206
  process.exit(1);
@@ -19,6 +19,7 @@ import crypto from "crypto";
19
19
  import path from "path";
20
20
 
21
21
  import { fileURLToPath } from "url";
22
+ import { maybeHint } from "../lib/hints.js";
22
23
 
23
24
  // Sprint detection — git-based, no config pointer needed (p013/f001)
24
25
  import { detectSprints } from "./detect-sprints.js";
@@ -1195,6 +1196,17 @@ Options:
1195
1196
  `Certificate: ${c.compilation_certificate.input_hash.slice(0, 20)}...`
1196
1197
  );
1197
1198
 
1199
+ if (!jsonFlag) {
1200
+ try {
1201
+ const hint = maybeHint(compilation, { context: "compile" });
1202
+ if (hint) {
1203
+ process.stderr.write("\n" + hint + "\n");
1204
+ }
1205
+ } catch {
1206
+ // hints are non-critical — fail silently
1207
+ }
1208
+ }
1209
+
1198
1210
  if (jsonFlag) {
1199
1211
  console.log(JSON.stringify(c, null, 2));
1200
1212
  }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Smart defaults and environment detection for wheat CLI.
3
+ * Zero dependencies — Node built-ins only.
4
+ */
5
+
6
+ export const DEFAULTS = {
7
+ audience: ["engineers"],
8
+ constraints: [],
9
+ doneCriteria: "Decision-ready brief with evidence",
10
+ };
11
+
12
+ export function isTTY() {
13
+ return Boolean(process.stdout.isTTY) && !isCI();
14
+ }
15
+
16
+ export function isCI() {
17
+ return Boolean(
18
+ process.env.CI ||
19
+ process.env.GITHUB_ACTIONS ||
20
+ process.env.GITLAB_CI ||
21
+ process.env.CIRCLECI ||
22
+ process.env.JENKINS_URL ||
23
+ process.env.BUILDKITE,
24
+ );
25
+ }
26
+
27
+ export function outputMode() {
28
+ if (process.argv.includes("--quiet")) return "quiet";
29
+ if (process.argv.includes("--json")) return "json";
30
+ if (!isTTY()) return "json";
31
+ return "tty";
32
+ }
package/lib/hints.js ADDED
@@ -0,0 +1,214 @@
1
+ /**
2
+ * hints.js — Ecosystem cross-promotion hints
3
+ *
4
+ * Contextual, one-line, non-blocking hints that surface Grainulation
5
+ * ecosystem tools at the moment the user's workflow makes them relevant.
6
+ *
7
+ * Shows max 1 hint per invocation on stderr.
8
+ * Tracks shown hints in ~/.grainulation/hints.json
9
+ * Fails silently on any I/O error — never blocks the CLI.
10
+ *
11
+ * Zero dependencies.
12
+ */
13
+
14
+ import { readFileSync, writeFileSync, mkdirSync } from "fs";
15
+ import path from "path";
16
+ import { homedir } from "os";
17
+
18
+ const HINTS_DIR = path.join(homedir(), ".grainulation");
19
+ const HINTS_FILE = path.join(HINTS_DIR, "hints.json");
20
+ const MAX_SHOWS = 3;
21
+ const COOLDOWN_MS = 24 * 60 * 60 * 1000; // 24h
22
+
23
+ // ─── State I/O (sync, fail-silent) ──────────────────────────────────────────
24
+
25
+ function readHints() {
26
+ try {
27
+ return JSON.parse(readFileSync(HINTS_FILE, "utf8"));
28
+ } catch {
29
+ return { shown: {}, dismissed: [], installed: [] };
30
+ }
31
+ }
32
+
33
+ function writeHints(data) {
34
+ try {
35
+ mkdirSync(HINTS_DIR, { recursive: true });
36
+ writeFileSync(HINTS_FILE, JSON.stringify(data, null, 2) + "\n");
37
+ } catch {
38
+ // fail silently
39
+ }
40
+ }
41
+
42
+ function shouldSuppress(product, state) {
43
+ if ((state.dismissed || []).includes(product)) return true;
44
+ if ((state.installed || []).includes(product)) return true;
45
+ const record = (state.shown || {})[product];
46
+ if (!record) return false;
47
+ if (record.count >= MAX_SHOWS) return true;
48
+ if (record.last && Date.now() - new Date(record.last).getTime() < COOLDOWN_MS) return true;
49
+ return false;
50
+ }
51
+
52
+ // ─── Triggers (ordered by priority, first match wins) ────────────────────────
53
+
54
+ const TRIGGERS = [
55
+ // 1. >20 claims → harvest
56
+ function detectHarvestFromClaims(compilation) {
57
+ const count = compilation?.claims?.length || 0;
58
+ if (count > 20) {
59
+ return {
60
+ product: "harvest",
61
+ message: "btw: harvest can visualize claim growth across sprints (npx @grainulation/harvest)",
62
+ };
63
+ }
64
+ return null;
65
+ },
66
+
67
+ // 2. >3 topics → orchard
68
+ function detectOrchardFromTopics(compilation) {
69
+ const claims = compilation?.claims || [];
70
+ const topics = new Set(claims.map((c) => c.topic).filter(Boolean));
71
+ if (topics.size > 3) {
72
+ return {
73
+ product: "orchard",
74
+ message: "btw: orchard can run multiple research sprints in parallel (npx @grainulation/orchard)",
75
+ };
76
+ }
77
+ return null;
78
+ },
79
+
80
+ // 3. brief/present context → mill
81
+ function detectMillFromBrief(compilation, context) {
82
+ if (context === "brief" || context === "present") {
83
+ return {
84
+ product: "mill",
85
+ message: "btw: mill can export this as PDF, slides, or Confluence (npx @grainulation/mill)",
86
+ };
87
+ }
88
+ return null;
89
+ },
90
+
91
+ // 4. first ever compile → farmer
92
+ function detectFarmerFirstCompile(compilation, context) {
93
+ if (context !== "compile") return null;
94
+ // Check if this looks like a first compile (no prior hint state)
95
+ try {
96
+ const state = readHints();
97
+ const totalShows = Object.values(state.shown || {}).reduce(
98
+ (sum, r) => sum + (r.count || 0),
99
+ 0
100
+ );
101
+ if (totalShows === 0) {
102
+ return {
103
+ product: "farmer",
104
+ message: "btw: farmer gives you a mobile dashboard for AI permissions (npx @grainulation/farmer)",
105
+ };
106
+ }
107
+ } catch {
108
+ // fail silently
109
+ }
110
+ return null;
111
+ },
112
+
113
+ // 5. >5 sprints → silo
114
+ function detectSiloFromSprints(compilation) {
115
+ const sprintCount = compilation?.sprints?.length || 0;
116
+ if (sprintCount > 5) {
117
+ return {
118
+ product: "silo",
119
+ message: "btw: silo stores reusable claim libraries across projects (npx @grainulation/silo)",
120
+ };
121
+ }
122
+ return null;
123
+ },
124
+ ];
125
+
126
+ // ─── Format ──────────────────────────────────────────────────────────────────
127
+
128
+ function formatHint(message) {
129
+ return ` \x1b[2m${message}\x1b[0m`;
130
+ }
131
+
132
+ // ─── Public API ──────────────────────────────────────────────────────────────
133
+
134
+ /**
135
+ * Evaluate trigger conditions and return a formatted hint string,
136
+ * or null if no hint should be shown.
137
+ *
138
+ * @param {object} compilation - The compilation.json data
139
+ * @param {object} opts
140
+ * @param {string} opts.context - "compile" | "init" | "brief" | "present"
141
+ * @returns {string|null} Formatted hint for stderr, or null
142
+ */
143
+ export function maybeHint(compilation, opts = {}) {
144
+ try {
145
+ // Global suppression
146
+ if (process.env.WHEAT_BTW === "off") return null;
147
+ if (process.env.WHEAT_NO_HINTS === "1") return null;
148
+ if (process.env.CI) return null;
149
+ if (process.argv.includes("--quiet")) return null;
150
+ if (process.argv.includes("--json")) return null;
151
+ if (!process.stderr.isTTY) return null;
152
+
153
+ const state = readHints();
154
+
155
+ for (const trigger of TRIGGERS) {
156
+ const result = trigger(compilation, opts.context);
157
+ if (!result) continue;
158
+ if (shouldSuppress(result.product, state)) continue;
159
+
160
+ // Record the show
161
+ if (!state.shown) state.shown = {};
162
+ if (!state.shown[result.product]) state.shown[result.product] = { count: 0 };
163
+ state.shown[result.product].count++;
164
+ state.shown[result.product].last = new Date().toISOString();
165
+ writeHints(state);
166
+
167
+ return formatHint(result.message);
168
+ }
169
+ } catch {
170
+ // fail silently — never block the main output
171
+ }
172
+ return null;
173
+ }
174
+
175
+ /**
176
+ * Record that a product has been installed/connected.
177
+ * @param {string} product
178
+ */
179
+ export function markInstalled(product) {
180
+ try {
181
+ const state = readHints();
182
+ if (!state.installed) state.installed = [];
183
+ if (!state.installed.includes(product)) {
184
+ state.installed.push(product);
185
+ writeHints(state);
186
+ }
187
+ } catch {
188
+ // fail silently
189
+ }
190
+ }
191
+
192
+ /**
193
+ * Record that the user dismissed hints for a product.
194
+ * @param {string} product
195
+ */
196
+ export function dismiss(product) {
197
+ try {
198
+ const state = readHints();
199
+ if (!state.dismissed) state.dismissed = [];
200
+ if (!state.dismissed.includes(product)) {
201
+ state.dismissed.push(product);
202
+ writeHints(state);
203
+ }
204
+ } catch {
205
+ // fail silently
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Reset all hint state (for testing).
211
+ */
212
+ export function reset() {
213
+ writeHints({ shown: {}, dismissed: [], installed: [] });
214
+ }
package/lib/init.js CHANGED
@@ -9,7 +9,7 @@
9
9
  * Creates in the TARGET repo:
10
10
  * - claims.json (seeded with constraint claims)
11
11
  * - CLAUDE.md (sprint configuration for Claude Code)
12
- * - .claude/commands/*.md (slash commands)
12
+ * - .claude/commands/wheat/*.md (slash commands)
13
13
  * - wheat.config.json (local config pointing back to package)
14
14
  *
15
15
  * Zero npm dependencies.
@@ -20,6 +20,8 @@ import path from "path";
20
20
  import readline from "readline";
21
21
  import { execFileSync } from "child_process";
22
22
  import { fileURLToPath } from "url";
23
+ import { DEFAULTS, outputMode } from "./defaults.js";
24
+ import { maybeHint } from "./hints.js";
23
25
 
24
26
  const __filename = fileURLToPath(import.meta.url);
25
27
  const __dirname = path.dirname(__filename);
@@ -232,9 +234,9 @@ function buildClaudeMd(meta) {
232
234
 
233
235
  function copyCommands(dir) {
234
236
  const srcDir = path.join(packageRoot(), "templates", "commands");
235
- const destDir = target(dir, ".claude", "commands");
237
+ const destDir = target(dir, ".claude", "commands", "wheat");
236
238
 
237
- // Create .claude/commands/ if it doesn't exist
239
+ // Create .claude/commands/wheat/ if it doesn't exist
238
240
  fs.mkdirSync(destDir, { recursive: true });
239
241
 
240
242
  let copied = 0;
@@ -247,7 +249,7 @@ function copyCommands(dir) {
247
249
 
248
250
  // Don't overwrite existing commands (user may have customized)
249
251
  if (fs.existsSync(dest)) {
250
- console.log(` Skipped .claude/commands/${file} (already exists)`);
252
+ console.log(` Skipped .claude/commands/wheat/${file} (already exists)`);
251
253
  continue;
252
254
  }
253
255
 
@@ -336,6 +338,86 @@ fi
336
338
  }
337
339
  }
338
340
 
341
+ // ─── .mcp.json & AGENTS.md ──────────────────────────────────────────────────
342
+
343
+ function writeMcpJson(dir) {
344
+ const mcpPath = target(dir, ".mcp.json");
345
+ const wheatEntry = {
346
+ command: "npx",
347
+ args: ["-y", "@grainulation/wheat", "mcp"],
348
+ };
349
+
350
+ let config = { mcpServers: {} };
351
+ if (fs.existsSync(mcpPath)) {
352
+ try {
353
+ config = JSON.parse(fs.readFileSync(mcpPath, "utf8"));
354
+ if (!config.mcpServers) config.mcpServers = {};
355
+ } catch {
356
+ // Corrupted file — overwrite with fresh config
357
+ config = { mcpServers: {} };
358
+ }
359
+ }
360
+
361
+ config.mcpServers.wheat = wheatEntry;
362
+ fs.writeFileSync(mcpPath, JSON.stringify(config, null, 2) + "\n");
363
+ console.log(
364
+ " \x1b[32m+\x1b[0m .mcp.json (Claude Code MCP auto-discovery)"
365
+ );
366
+ }
367
+
368
+ function writeAgentsMd(dir, meta) {
369
+ const agentsPath = target(dir, "AGENTS.md");
370
+ const constraintList =
371
+ meta.constraints.length > 0
372
+ ? meta.constraints.map((c) => `- ${c}`).join("\n")
373
+ : "- (none specified)";
374
+
375
+ const section = `# Wheat Research Sprint
376
+
377
+ **Question:** ${meta.question}
378
+
379
+ **Audience:** ${meta.audience.join(", ")}
380
+
381
+ **Constraints:**
382
+ ${constraintList}
383
+
384
+ **Done looks like:** ${meta.doneCriteria || "A recommendation with evidence"}
385
+
386
+ ## Claims System
387
+
388
+ All findings are tracked as typed claims in \`claims.json\`. Claim types: constraint, factual, estimate, risk, recommendation, feedback. Evidence tiers (low to high): stated, web, documented, tested, production.
389
+
390
+ ## Key Commands
391
+
392
+ - \`wheat init\` — bootstrap a research sprint
393
+ - \`wheat compile\` — validate and compile claims
394
+ - \`wheat status\` — sprint health dashboard
395
+ - \`wheat search <query>\` — search claims
396
+ - \`wheat add-claim\` — add a new claim
397
+ - \`wheat resolve <id>\` — resolve a conflicting claim
398
+ `;
399
+
400
+ if (fs.existsSync(agentsPath)) {
401
+ const existing = fs.readFileSync(agentsPath, "utf8");
402
+ if (existing.includes("# Wheat Research Sprint")) {
403
+ console.log(
404
+ " \x1b[34m-\x1b[0m AGENTS.md (wheat section already present)"
405
+ );
406
+ return;
407
+ }
408
+ // Append wheat section
409
+ fs.appendFileSync(agentsPath, "\n" + section);
410
+ console.log(
411
+ " \x1b[32m+\x1b[0m AGENTS.md (appended wheat section)"
412
+ );
413
+ } else {
414
+ fs.writeFileSync(agentsPath, section);
415
+ console.log(
416
+ " \x1b[32m+\x1b[0m AGENTS.md (universal AI instructions)"
417
+ );
418
+ }
419
+ }
420
+
339
421
  // ─── Main ────────────────────────────────────────────────────────────────────
340
422
 
341
423
  export async function run(dir, args) {
@@ -357,7 +439,26 @@ export async function run(dir, args) {
357
439
 
358
440
  let meta;
359
441
 
360
- if (flags.headless || flags["non-interactive"]) {
442
+ if (flags.auto) {
443
+ // ── Auto mode — question only, smart defaults for everything else ──
444
+ if (!flags.question) {
445
+ console.error(" wheat: no question provided");
446
+ process.exit(1);
447
+ }
448
+ meta = {
449
+ question: flags.question,
450
+ audience: flags.audience
451
+ ? flags.audience.split(",").map((s) => s.trim())
452
+ : DEFAULTS.audience,
453
+ constraints: flags.constraints
454
+ ? flags.constraints
455
+ .split(";")
456
+ .map((s) => s.trim())
457
+ .filter(Boolean)
458
+ : DEFAULTS.constraints,
459
+ doneCriteria: flags.done || DEFAULTS.doneCriteria,
460
+ };
461
+ } else if (flags.headless || flags["non-interactive"]) {
361
462
  // ── Headless mode — all flags required ──
362
463
  const missing = [];
363
464
  if (!flags.question) missing.push("--question");
@@ -481,12 +582,18 @@ export async function run(dir, args) {
481
582
  fs.writeFileSync(claudePath, claudeMd);
482
583
  console.log(" \x1b[32m+\x1b[0m CLAUDE.md");
483
584
 
484
- // .claude/commands/
585
+ // .claude/commands/wheat/
485
586
  const copied = copyCommands(dir);
486
587
  console.log(
487
- ` \x1b[32m+\x1b[0m .claude/commands/ (${copied} commands installed)`
588
+ ` \x1b[32m+\x1b[0m .claude/commands/wheat/ (${copied} commands installed)`
488
589
  );
489
590
 
591
+ // .mcp.json (Claude Code MCP auto-discovery)
592
+ writeMcpJson(dir);
593
+
594
+ // AGENTS.md (universal AI instructions)
595
+ writeAgentsMd(dir, meta);
596
+
490
597
  // Create output directories
491
598
  const dirs = ["output", "research", "prototypes", "evidence"];
492
599
  for (const d of dirs) {
@@ -510,7 +617,7 @@ export async function run(dir, args) {
510
617
  constraints: meta.constraints.length,
511
618
  done_criteria: meta.doneCriteria || null,
512
619
  claims_seeded: claims.claims.length,
513
- files_created: ["claims.json", "CLAUDE.md", ".claude/commands/"],
620
+ files_created: ["claims.json", "CLAUDE.md", ".claude/commands/wheat/", ".mcp.json", "AGENTS.md"],
514
621
  dir,
515
622
  })
516
623
  );
@@ -518,6 +625,33 @@ export async function run(dir, args) {
518
625
  }
519
626
 
520
627
  console.log();
628
+ // Auto mode: compact output, no tutorial
629
+ if (flags.auto) {
630
+ const mode = outputMode();
631
+ if (mode === "quiet") {
632
+ return;
633
+ } else if (mode === "json") {
634
+ console.log(JSON.stringify({
635
+ question: meta.question,
636
+ audience: meta.audience,
637
+ claims: claims.claims.length,
638
+ dir,
639
+ }));
640
+ return;
641
+ } else {
642
+ console.log();
643
+ console.log(` \x1b[1m\x1b[33mwheat\x1b[0m — sprint created`);
644
+ console.log(` ${meta.question}`);
645
+ console.log(` ${claims.claims.length} constraint(s) seeded`);
646
+ try {
647
+ const hint = maybeHint({ claims: claims.claims }, { context: "init" });
648
+ if (hint) process.stderr.write(hint + "\n");
649
+ } catch { /* non-critical */ }
650
+ console.log();
651
+ return;
652
+ }
653
+ }
654
+
521
655
  console.log(" ─────────────────────────────────────────");
522
656
  console.log(` \x1b[1m\x1b[33mSprint ready.\x1b[0m`);
523
657
  console.log();
@@ -528,7 +662,9 @@ export async function run(dir, args) {
528
662
  console.log(" Created:");
529
663
  console.log(" claims.json Your evidence database");
530
664
  console.log(" CLAUDE.md AI assistant configuration");
531
- console.log(" .claude/commands/ 18 slash commands for Claude Code");
665
+ console.log(" .claude/commands/wheat/ slash commands for Claude Code");
666
+ console.log(" .mcp.json Claude Code MCP auto-discovery");
667
+ console.log(" AGENTS.md Universal AI instructions");
532
668
  console.log(" output/ Where compiled artifacts land");
533
669
  console.log();
534
670
  console.log(" Next steps:");
@@ -539,5 +675,9 @@ export async function run(dir, args) {
539
675
  );
540
676
  console.log();
541
677
  console.log(" Trust the process. The evidence will compound.");
678
+ try {
679
+ const hint = maybeHint({ claims: claims.claims }, { context: "init" });
680
+ if (hint) process.stderr.write(hint + "\n");
681
+ } catch { /* non-critical */ }
542
682
  console.log();
543
683
  }
package/lib/update.js CHANGED
@@ -1,8 +1,8 @@
1
1
  /**
2
- * wheat update — Copy/update slash commands to .claude/commands/
2
+ * wheat update — Copy/update slash commands to .claude/commands/wheat/
3
3
  *
4
4
  * Copies command templates from the installed package into the user's
5
- * .claude/commands/ directory. Existing files can be overwritten with --force.
5
+ * .claude/commands/wheat/ directory. Existing files can be overwritten with --force.
6
6
  *
7
7
  * Zero npm dependencies.
8
8
  */
@@ -21,7 +21,7 @@ function packageRoot() {
21
21
  export async function run(dir, args) {
22
22
  const force = args.includes("--force");
23
23
  const srcDir = path.join(packageRoot(), "templates", "commands");
24
- const destDir = path.join(dir, ".claude", "commands");
24
+ const destDir = path.join(dir, ".claude", "commands", "wheat");
25
25
 
26
26
  fs.mkdirSync(destDir, { recursive: true });
27
27
 
@@ -34,7 +34,7 @@ export async function run(dir, args) {
34
34
  }
35
35
 
36
36
  console.log();
37
- console.log(` Updating .claude/commands/ (${files.length} commands)`);
37
+ console.log(` Updating .claude/commands/wheat/ (${files.length} commands)`);
38
38
  console.log();
39
39
 
40
40
  let updated = 0;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grainulation/wheat",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "description": "Research-driven development framework — structured claims, compiled evidence, deterministic output",
5
5
  "license": "MIT",
6
6
  "author": "grainulation contributors",