@grainulation/wheat 1.0.3 → 1.0.5

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 (43) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +32 -31
  3. package/bin/wheat.js +63 -40
  4. package/compiler/detect-sprints.js +108 -66
  5. package/compiler/generate-manifest.js +116 -69
  6. package/compiler/wheat-compiler.js +763 -471
  7. package/lib/compiler.js +11 -6
  8. package/lib/connect.js +273 -134
  9. package/lib/defaults.js +32 -0
  10. package/lib/disconnect.js +61 -40
  11. package/lib/guard.js +20 -17
  12. package/lib/index.js +8 -8
  13. package/lib/init.js +260 -142
  14. package/lib/install-prompt.js +26 -26
  15. package/lib/load-claims.js +88 -0
  16. package/lib/quickstart.js +225 -111
  17. package/lib/serve-mcp.js +495 -180
  18. package/lib/server.js +198 -111
  19. package/lib/stats.js +65 -39
  20. package/lib/status.js +65 -34
  21. package/lib/update.js +13 -11
  22. package/package.json +8 -4
  23. package/templates/claude.md +31 -17
  24. package/templates/commands/blind-spot.md +9 -2
  25. package/templates/commands/brief.md +11 -1
  26. package/templates/commands/calibrate.md +3 -1
  27. package/templates/commands/challenge.md +4 -1
  28. package/templates/commands/connect.md +12 -1
  29. package/templates/commands/evaluate.md +4 -0
  30. package/templates/commands/feedback.md +3 -1
  31. package/templates/commands/handoff.md +11 -7
  32. package/templates/commands/init.md +4 -1
  33. package/templates/commands/merge.md +4 -1
  34. package/templates/commands/next.md +1 -0
  35. package/templates/commands/present.md +3 -0
  36. package/templates/commands/prototype.md +2 -0
  37. package/templates/commands/pull.md +103 -0
  38. package/templates/commands/replay.md +8 -0
  39. package/templates/commands/research.md +1 -0
  40. package/templates/commands/resolve.md +4 -1
  41. package/templates/commands/status.md +4 -0
  42. package/templates/commands/sync.md +94 -0
  43. package/templates/commands/witness.md +6 -2
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2026 Aid Idrizovic
3
+ Copyright (c) 2026 grainulation contributors
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -3,7 +3,8 @@
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/npm/l/@grainulation/wheat" 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" 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
+ <a href="https://deepwiki.com/grainulation/wheat"><img src="https://deepwiki.com/badge.svg" alt="Explore on DeepWiki"></a>
7
8
  </p>
8
9
 
9
10
  <p align="center"><strong>CI/CD for technical decisions.</strong></p>
@@ -76,26 +77,26 @@ The compiler catches conflicts, warns about weak evidence, and blocks the build
76
77
 
77
78
  ## Commands
78
79
 
79
- | Command | What it does |
80
- |---------|-------------|
81
- | `/init` | Bootstrap a new research sprint |
82
- | `/research <topic>` | Deep dive on a topic, creates claims |
83
- | `/prototype` | Build something testable |
84
- | `/challenge <id>` | Adversarial stress-test of a claim |
85
- | `/witness <id> <url>` | External corroboration |
86
- | `/blind-spot` | Find gaps in your investigation |
87
- | `/status` | Sprint dashboard |
88
- | `/brief` | Compile the decision document |
89
- | `/present` | Generate a stakeholder presentation |
90
- | `/feedback` | Incorporate stakeholder input |
91
- | `/resolve` | Adjudicate conflicts between claims |
92
- | `/replay` | Time-travel through sprint history |
93
- | `/calibrate` | Score predictions against actual outcomes |
94
- | `/handoff` | Package sprint for knowledge transfer |
95
- | `/merge <path>` | Combine findings across sprints |
96
- | `/connect <type>` | Link external tools (Jira, docs, etc.) |
97
- | `/evaluate` | Test claims against reality, resolve conflicts |
98
- | `/next` | Route next steps through Farmer (mobile feedback) |
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) |
99
100
 
100
101
  ## Guard rails
101
102
 
@@ -116,16 +117,16 @@ Node built-in modules only. No npm install waterfall. No supply chain anxiety.
116
117
 
117
118
  ## Part of the grainulation ecosystem
118
119
 
119
- | Tool | Role |
120
- |------|------|
121
- | **wheat** | Research engine -- grow structured evidence |
122
- | [farmer](https://github.com/grainulation/farmer) | Permission dashboard -- approve AI actions in real time (admin + viewer roles) |
123
- | [barn](https://github.com/grainulation/barn) | Shared tools -- templates, validators, sprint detection |
124
- | [mill](https://github.com/grainulation/mill) | Format conversion -- export to PDF, CSV, slides, 24 formats |
125
- | [silo](https://github.com/grainulation/silo) | Knowledge storage -- reusable claim libraries and packs |
126
- | [harvest](https://github.com/grainulation/harvest) | Analytics -- cross-sprint patterns and prediction scoring |
127
- | [orchard](https://github.com/grainulation/orchard) | Orchestration -- multi-sprint coordination and dependencies |
128
- | [grainulation](https://github.com/grainulation/grainulation) | Unified CLI -- single entry point to the ecosystem |
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 |
129
130
 
130
131
  ## License
131
132
 
package/bin/wheat.js CHANGED
@@ -19,34 +19,40 @@
19
19
  * Zero npm dependencies.
20
20
  */
21
21
 
22
- import path from 'path';
23
- import { readFileSync } from 'fs';
24
- import { fileURLToPath } from 'url';
25
- import { track as trackInstall, maybePrompt as installPrompt } from '../lib/install-prompt.js';
22
+ import path from "path";
23
+ import { readFileSync } from "fs";
24
+ import { fileURLToPath } from "url";
25
+ import {
26
+ track as trackInstall,
27
+ maybePrompt as installPrompt,
28
+ } from "../lib/install-prompt.js";
26
29
 
27
30
  const __filename = fileURLToPath(import.meta.url);
28
31
  const __dirname = path.dirname(__filename);
29
32
 
30
- const VERSION = JSON.parse(readFileSync(path.join(__dirname, '..', 'package.json'), 'utf8')).version;
33
+ const VERSION = JSON.parse(
34
+ readFileSync(path.join(__dirname, "..", "package.json"), "utf8")
35
+ ).version;
31
36
 
32
37
  // ─── Parse arguments ─────────────────────────────────────────────────────────
33
38
 
34
- const verbose = process.argv.includes('--verbose');
39
+ const verbose = process.argv.includes("--verbose");
35
40
  function vlog(...a) {
36
41
  if (!verbose) return;
37
42
  const ts = new Date().toISOString();
38
- process.stderr.write(`[${ts}] wheat: ${a.join(' ')}\n`);
43
+ process.stderr.write(`[${ts}] wheat: ${a.join(" ")}\n`);
39
44
  }
40
45
  export { vlog, verbose };
41
46
 
42
47
  const args = process.argv.slice(2);
43
48
  const subcommand = args[0];
44
49
 
45
- vlog('startup', `subcommand=${subcommand || '(none)'}`, `cwd=${process.cwd()}`);
50
+ vlog("startup", `subcommand=${subcommand || "(none)"}`, `cwd=${process.cwd()}`);
46
51
 
47
52
  // Extract --dir or --root flag (applies to all subcommands)
48
53
  let targetDir = process.cwd();
49
- const dirIdx = args.indexOf('--dir') !== -1 ? args.indexOf('--dir') : args.indexOf('--root');
54
+ const dirIdx =
55
+ args.indexOf("--dir") !== -1 ? args.indexOf("--dir") : args.indexOf("--root");
50
56
  if (dirIdx !== -1 && args[dirIdx + 1]) {
51
57
  targetDir = path.resolve(args[dirIdx + 1]);
52
58
  args.splice(dirIdx, 2);
@@ -57,11 +63,12 @@ const subArgs = args.slice(1);
57
63
 
58
64
  // ─── Help / Version ──────────────────────────────────────────────────────────
59
65
 
60
- if (!subcommand || subcommand === '--help' || subcommand === '-h') {
66
+ if (!subcommand || subcommand === "--help" || subcommand === "-h") {
61
67
  console.log(`wheat v${VERSION} — Research-driven development framework
62
68
 
63
69
  Usage:
64
- wheat <command> [options]
70
+ wheat "your question" Start a sprint instantly (recommended)
71
+ wheat <command> [options] Run a specific command
65
72
 
66
73
  Commands:
67
74
  init Bootstrap a new research sprint in this repo
@@ -84,17 +91,15 @@ Global options:
84
91
  --help Show this help
85
92
 
86
93
  Examples:
87
- npx @grainulation/wheat quickstart
94
+ npx @grainulation/wheat "Should we migrate to Postgres?"
88
95
  npx @grainulation/wheat init
89
96
  npx @grainulation/wheat compile --summary
90
- npx @grainulation/wheat init --question "Should we migrate to Postgres?"
91
- npx @grainulation/wheat init --non-interactive --question "..." --audience "..." --done "..."
92
97
 
93
98
  Documentation: https://github.com/grainulation/wheat`);
94
99
  process.exit(0);
95
100
  }
96
101
 
97
- if (subcommand === '--version' || subcommand === '-v') {
102
+ if (subcommand === "--version" || subcommand === "-v") {
98
103
  console.log(`wheat v${VERSION}`);
99
104
  process.exit(0);
100
105
  }
@@ -109,28 +114,27 @@ installPrompt(subcommand);
109
114
  // ─── Dispatch ────────────────────────────────────────────────────────────────
110
115
 
111
116
  const commands = {
112
- init: '../lib/init.js',
113
- quickstart: '../lib/quickstart.js',
114
- compile: '../lib/compiler.js',
115
- guard: '../lib/guard.js',
116
- status: '../lib/status.js',
117
- stats: '../lib/stats.js',
118
- update: '../lib/update.js',
119
- serve: '../lib/server.js',
120
- mcp: '../lib/serve-mcp.js',
117
+ init: "../lib/init.js",
118
+ quickstart: "../lib/quickstart.js",
119
+ compile: "../lib/compiler.js",
120
+ guard: "../lib/guard.js",
121
+ status: "../lib/status.js",
122
+ stats: "../lib/stats.js",
123
+ update: "../lib/update.js",
124
+ serve: "../lib/server.js",
125
+ mcp: "../lib/serve-mcp.js",
121
126
  };
122
127
 
123
128
  // ─── wheat migrate (not yet implemented) ────────────────────────────────────
124
- if (subcommand === 'migrate') {
125
- console.error('wheat migrate is not yet available');
129
+ if (subcommand === "migrate") {
130
+ console.error("wheat migrate is not yet available");
126
131
  process.exit(1);
127
132
  }
128
133
 
129
-
130
134
  // Handle "wheat connect <target>" as a compound subcommand
131
- if (subcommand === 'connect') {
135
+ if (subcommand === "connect") {
132
136
  const target = subArgs[0];
133
- if (!target || target === '--help' || target === '-h') {
137
+ if (!target || target === "--help" || target === "-h") {
134
138
  console.log(`wheat connect — Link external tools
135
139
 
136
140
  Usage:
@@ -139,9 +143,11 @@ Usage:
139
143
  Run "wheat connect farmer --help" for options.`);
140
144
  process.exit(0);
141
145
  }
142
- if (target === 'farmer') {
143
- const connectModule = await import(new URL('../lib/connect.js', import.meta.url).href);
144
- await connectModule.run(targetDir, subArgs.slice(1)).catch(err => {
146
+ if (target === "farmer") {
147
+ const connectModule = await import(
148
+ new URL("../lib/connect.js", import.meta.url).href
149
+ );
150
+ await connectModule.run(targetDir, subArgs.slice(1)).catch((err) => {
145
151
  console.error(`\nwheat connect farmer failed:`, err.message);
146
152
  if (process.env.WHEAT_DEBUG) console.error(err.stack);
147
153
  process.exit(1);
@@ -153,9 +159,9 @@ Run "wheat connect farmer --help" for options.`);
153
159
  }
154
160
 
155
161
  // Handle "wheat disconnect <target>" as a compound subcommand
156
- if (subcommand === 'disconnect') {
162
+ if (subcommand === "disconnect") {
157
163
  const target = subArgs[0];
158
- if (!target || target === '--help' || target === '-h') {
164
+ if (!target || target === "--help" || target === "-h") {
159
165
  console.log(`wheat disconnect — Remove external tool hooks
160
166
 
161
167
  Usage:
@@ -164,30 +170,47 @@ Usage:
164
170
  Run "wheat disconnect farmer --help" for options.`);
165
171
  process.exit(0);
166
172
  }
167
- if (target === 'farmer') {
168
- const disconnectModule = await import(new URL('../lib/disconnect.js', import.meta.url).href);
169
- await disconnectModule.run(targetDir, subArgs.slice(1)).catch(err => {
173
+ if (target === "farmer") {
174
+ const disconnectModule = await import(
175
+ new URL("../lib/disconnect.js", import.meta.url).href
176
+ );
177
+ await disconnectModule.run(targetDir, subArgs.slice(1)).catch((err) => {
170
178
  console.error(`\nwheat disconnect farmer failed:`, err.message);
171
179
  if (process.env.WHEAT_DEBUG) console.error(err.stack);
172
180
  process.exit(1);
173
181
  });
174
182
  process.exit(0);
175
183
  }
176
- console.error(`wheat: unknown disconnect target: ${target}\nAvailable: farmer`);
184
+ console.error(
185
+ `wheat: unknown disconnect target: ${target}\nAvailable: farmer`
186
+ );
177
187
  process.exit(1);
178
188
  }
179
189
 
180
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
+ }
181
204
  console.error(`wheat: unknown command: ${subcommand}\n`);
182
205
  console.error('Run "wheat --help" for available commands.');
183
206
  process.exit(1);
184
207
  }
185
208
 
186
209
  // Load and run the subcommand module
187
- vlog('dispatch', `loading module for "${subcommand}"`);
210
+ vlog("dispatch", `loading module for "${subcommand}"`);
188
211
  const modulePath = new URL(commands[subcommand], import.meta.url).href;
189
212
  const handler = await import(modulePath);
190
- handler.run(targetDir, subArgs).catch(err => {
213
+ handler.run(targetDir, subArgs).catch((err) => {
191
214
  console.error(`\nwheat ${subcommand} failed:`, err.message);
192
215
  if (process.env.WHEAT_DEBUG) console.error(err.stack);
193
216
  process.exit(1);