@grainulation/wheat 1.0.4 → 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.
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);
@@ -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/init.js CHANGED
@@ -20,6 +20,7 @@ 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";
23
24
 
24
25
  const __filename = fileURLToPath(import.meta.url);
25
26
  const __dirname = path.dirname(__filename);
@@ -357,7 +358,26 @@ export async function run(dir, args) {
357
358
 
358
359
  let meta;
359
360
 
360
- if (flags.headless || flags["non-interactive"]) {
361
+ if (flags.auto) {
362
+ // ── Auto mode — question only, smart defaults for everything else ──
363
+ if (!flags.question) {
364
+ console.error(" wheat: no question provided");
365
+ process.exit(1);
366
+ }
367
+ meta = {
368
+ question: flags.question,
369
+ audience: flags.audience
370
+ ? flags.audience.split(",").map((s) => s.trim())
371
+ : DEFAULTS.audience,
372
+ constraints: flags.constraints
373
+ ? flags.constraints
374
+ .split(";")
375
+ .map((s) => s.trim())
376
+ .filter(Boolean)
377
+ : DEFAULTS.constraints,
378
+ doneCriteria: flags.done || DEFAULTS.doneCriteria,
379
+ };
380
+ } else if (flags.headless || flags["non-interactive"]) {
361
381
  // ── Headless mode — all flags required ──
362
382
  const missing = [];
363
383
  if (!flags.question) missing.push("--question");
@@ -518,6 +538,29 @@ export async function run(dir, args) {
518
538
  }
519
539
 
520
540
  console.log();
541
+ // Auto mode: compact output, no tutorial
542
+ if (flags.auto) {
543
+ const mode = outputMode();
544
+ if (mode === "quiet") {
545
+ return;
546
+ } else if (mode === "json") {
547
+ console.log(JSON.stringify({
548
+ question: meta.question,
549
+ audience: meta.audience,
550
+ claims: claims.claims.length,
551
+ dir,
552
+ }));
553
+ return;
554
+ } else {
555
+ console.log();
556
+ console.log(` \x1b[1m\x1b[33mwheat\x1b[0m — sprint created`);
557
+ console.log(` ${meta.question}`);
558
+ console.log(` ${claims.claims.length} constraint(s) seeded`);
559
+ console.log();
560
+ return;
561
+ }
562
+ }
563
+
521
564
  console.log(" ─────────────────────────────────────────");
522
565
  console.log(` \x1b[1m\x1b[33mSprint ready.\x1b[0m`);
523
566
  console.log();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@grainulation/wheat",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "description": "Research-driven development framework — structured claims, compiled evidence, deterministic output",
5
5
  "license": "MIT",
6
6
  "author": "grainulation contributors",