infernoflow 0.31.0 → 0.32.1

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.
@@ -45,12 +45,17 @@ function checkNodeVersion() {
45
45
  }
46
46
 
47
47
  function checkCli() {
48
+ // Use shell: true so Windows .cmd wrappers resolve correctly.
49
+ // If the spawn fails entirely, we're still clearly running — downgrade to warn.
48
50
  try {
49
- const r = spawnSync("infernoflow", ["--version"], { encoding: "utf8", timeout: 5000 });
50
- if (r.status === 0) return pass(`infernoflow v${r.stdout.trim()} installed`);
51
- return fail("infernoflow CLI not found on PATH", "npm install -g infernoflow");
51
+ const r = spawnSync("infernoflow", ["--version"], { encoding: "utf8", timeout: 5000, shell: true });
52
+ if (r.status === 0 && r.stdout.trim()) {
53
+ return pass(`infernoflow v${r.stdout.trim()} on PATH`);
54
+ }
55
+ // Running but PATH lookup failed for subprocesses (common on Windows)
56
+ return warn("infernoflow not resolvable in subprocesses", "Ensure npm global bin folder is in your PATH");
52
57
  } catch {
53
- return fail("infernoflow CLI not found on PATH", "npm install -g infernoflow");
58
+ return warn("infernoflow not resolvable in subprocesses", "Ensure npm global bin folder is in your PATH");
54
59
  }
55
60
  }
56
61
 
@@ -224,8 +229,40 @@ function printReport(results, elapsed) {
224
229
  console.log(` ${overall} — ${green(String(counts.pass))} pass · ${yellow(String(counts.warn))} warn · ${red(String(counts.fail))} fail (${elapsed}ms)`);
225
230
  console.log();
226
231
 
227
- if (counts.warn > 0 || counts.fail > 0) {
228
- console.log(` Run ${cyan("infernoflow doctor --fix")} to auto-fix warnings`);
232
+ // Prioritized action list show concrete next steps, not just status flags
233
+ const actions = [];
234
+
235
+ // Failures first
236
+ const fails = results.filter(r => r.status === "fail");
237
+ for (const f of fails) {
238
+ if (f.fix) actions.push({ priority: "🔴", text: f.fix });
239
+ else actions.push({ priority: "🔴", text: `Fix: ${f.label} — ${f.message}` });
240
+ }
241
+
242
+ // AI provider — very common gap, elevate it
243
+ const aiCheck = results.find(r => r.label === "AI providers");
244
+ if (aiCheck && aiCheck.status !== "pass") {
245
+ actions.push({ priority: "💡", text: `Connect an AI provider: ${cyan("infernoflow ai setup")} (unlocks explain, why, review, changelog)` });
246
+ }
247
+
248
+ // Warnings
249
+ const warns = results.filter(r => r.status === "warn" && r.label !== "AI providers");
250
+ for (const w of warns) {
251
+ if (w.fix) actions.push({ priority: "⚠️ ", text: w.fix });
252
+ }
253
+
254
+ if (actions.length > 0) {
255
+ console.log(` ${bold("Next steps:")}`);
256
+ for (const a of actions) {
257
+ console.log(` ${a.priority} ${a.text}`);
258
+ }
259
+ console.log();
260
+ if (warns.length > 0) {
261
+ console.log(` ${gray("Auto-fix warnings:")} ${cyan("infernoflow doctor --fix")}`);
262
+ }
263
+ console.log();
264
+ } else {
265
+ console.log(` ${green("✓")} You're all set. Run ${cyan("infernoflow demo")} to see the full capability chain.`);
229
266
  console.log();
230
267
  }
231
268
  }
@@ -439,6 +439,17 @@ export async function initCommand(args) {
439
439
  if (!silent) {
440
440
  done("infernoflow initialized!");
441
441
 
442
+ // AI provider nudge — show once at init if nothing is configured
443
+ const intPath = path.join(infernoDir, "integrations.json");
444
+ const hasAiKey = process.env.ANTHROPIC_API_KEY || process.env.OPENAI_API_KEY ||
445
+ process.env.GOOGLE_AI_API_KEY || process.env.OPENROUTER_API_KEY ||
446
+ process.env.GEMINI_API_KEY;
447
+ if (!hasAiKey && !fs.existsSync(intPath)) {
448
+ console.log();
449
+ console.log(` ${yellow("💡")} ${bold("Tip:")} connect an AI provider for explain, why, review, and changelog AI.`);
450
+ console.log(` ${cyan("infernoflow ai setup")} — takes 60 seconds`);
451
+ }
452
+
442
453
  nextSteps([
443
454
  cyan("infernoflow status") + " — see your contract at a glance",
444
455
  cyan("infernoflow check") + " — validate everything",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "infernoflow",
3
- "version": "0.31.0",
3
+ "version": "0.32.1",
4
4
  "description": "The forge for liquid code - keep capabilities, contracts, and docs in sync.",
5
5
  "type": "module",
6
6
  "bin": {