infernoflow 0.32.8 → 0.32.9

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 (78) hide show
  1. package/dist/bin/infernoflow.mjs +84 -255
  2. package/dist/lib/adopters/angular.mjs +1 -128
  3. package/dist/lib/adopters/css.mjs +1 -111
  4. package/dist/lib/adopters/react.mjs +1 -104
  5. package/dist/lib/ai/ideDetection.mjs +1 -31
  6. package/dist/lib/ai/localProvider.mjs +1 -88
  7. package/dist/lib/ai/providerRouter.mjs +2 -295
  8. package/dist/lib/commands/adopt.mjs +20 -869
  9. package/dist/lib/commands/adoptWizard.mjs +9 -320
  10. package/dist/lib/commands/agent.mjs +5 -191
  11. package/dist/lib/commands/ai.mjs +2 -407
  12. package/dist/lib/commands/audit.mjs +13 -300
  13. package/dist/lib/commands/changelog.mjs +26 -594
  14. package/dist/lib/commands/check.mjs +3 -184
  15. package/dist/lib/commands/ci.mjs +3 -208
  16. package/dist/lib/commands/claudeMd.mjs +25 -130
  17. package/dist/lib/commands/cloud.mjs +5 -521
  18. package/dist/lib/commands/context.mjs +31 -287
  19. package/dist/lib/commands/coverage.mjs +2 -282
  20. package/dist/lib/commands/dashboard.mjs +123 -635
  21. package/dist/lib/commands/demo.mjs +8 -465
  22. package/dist/lib/commands/diff.mjs +5 -274
  23. package/dist/lib/commands/docGate.mjs +2 -81
  24. package/dist/lib/commands/doctor.mjs +3 -321
  25. package/dist/lib/commands/explain.mjs +8 -438
  26. package/dist/lib/commands/export.mjs +10 -239
  27. package/dist/lib/commands/generateSkills.mjs +38 -163
  28. package/dist/lib/commands/graph.mjs +203 -321
  29. package/dist/lib/commands/health.mjs +2 -309
  30. package/dist/lib/commands/impact.mjs +2 -325
  31. package/dist/lib/commands/implement.mjs +7 -103
  32. package/dist/lib/commands/init.mjs +23 -475
  33. package/dist/lib/commands/installCursorHooks.mjs +1 -36
  34. package/dist/lib/commands/installVsCodeCopilotHooks.mjs +1 -37
  35. package/dist/lib/commands/link.mjs +2 -342
  36. package/dist/lib/commands/monorepo.mjs +4 -428
  37. package/dist/lib/commands/notify.mjs +4 -258
  38. package/dist/lib/commands/onboard.mjs +4 -296
  39. package/dist/lib/commands/prComment.mjs +2 -361
  40. package/dist/lib/commands/prImpact.mjs +2 -157
  41. package/dist/lib/commands/publish.mjs +15 -316
  42. package/dist/lib/commands/report.mjs +28 -272
  43. package/dist/lib/commands/review.mjs +9 -223
  44. package/dist/lib/commands/run.mjs +8 -336
  45. package/dist/lib/commands/scaffold.mjs +54 -419
  46. package/dist/lib/commands/scan.mjs +5 -558
  47. package/dist/lib/commands/scout.mjs +2 -291
  48. package/dist/lib/commands/setup.mjs +5 -310
  49. package/dist/lib/commands/share.mjs +13 -196
  50. package/dist/lib/commands/snapshot.mjs +3 -383
  51. package/dist/lib/commands/stability.mjs +2 -293
  52. package/dist/lib/commands/status.mjs +4 -172
  53. package/dist/lib/commands/suggest.mjs +21 -563
  54. package/dist/lib/commands/syncAuto.mjs +1 -96
  55. package/dist/lib/commands/synthesize.mjs +10 -228
  56. package/dist/lib/commands/teamSync.mjs +2 -388
  57. package/dist/lib/commands/test.mjs +6 -363
  58. package/dist/lib/commands/version.mjs +2 -282
  59. package/dist/lib/commands/vibe.mjs +7 -357
  60. package/dist/lib/commands/watch.mjs +4 -203
  61. package/dist/lib/commands/why.mjs +4 -358
  62. package/dist/lib/cursorHooksInstall.mjs +1 -60
  63. package/dist/lib/draftToolingInstall.mjs +7 -68
  64. package/dist/lib/git/detect-drift.mjs +4 -208
  65. package/dist/lib/learning/adapt.mjs +6 -101
  66. package/dist/lib/learning/observe.mjs +1 -119
  67. package/dist/lib/learning/patternDetector.mjs +1 -298
  68. package/dist/lib/learning/profile.mjs +2 -279
  69. package/dist/lib/learning/skillSynthesizer.mjs +24 -145
  70. package/dist/lib/templates/index.mjs +1 -131
  71. package/dist/lib/ui/errors.mjs +1 -142
  72. package/dist/lib/ui/output.mjs +6 -72
  73. package/dist/lib/ui/prompts.mjs +6 -147
  74. package/dist/lib/vsCodeCopilotHooksInstall.mjs +1 -42
  75. package/dist/templates/cursor/inferno-mcp-server.mjs +29 -0
  76. package/dist/templates/github-app/GITHUB_APP.md +67 -0
  77. package/dist/templates/github-app/app-manifest.json +20 -0
  78. package/package.json +1 -1
@@ -1,156 +1,21 @@
1
1
  #!/usr/bin/env node
2
- import { readFileSync } from "node:fs";
3
- import { dirname, join } from "node:path";
4
- import { fileURLToPath } from "node:url";
5
- import { bold, gray, cyan, red } from "../lib/ui/output.mjs";
6
-
7
- const __dirname = dirname(fileURLToPath(import.meta.url));
8
- // When installed globally: __dirname = .../infernoflow/dist/bin
9
- // Root package.json lives two levels up at .../infernoflow/package.json
10
- // npm always includes the root package.json, so this path is always reliable.
11
- const pkg = JSON.parse(readFileSync(join(__dirname, "..", "..", "package.json"), "utf8"));
12
- const VERSION = pkg.version || "0.0.0";
13
- const COMMAND_DESCRIPTIONS = {
14
- publish: "Bump version, update changelog, build, npm publish, git commit + push in one shot",
15
- diff: "Show what capabilities changed since the last git tag (or any ref)",
16
- changelog: "Draft a changelog entry from commits since the last tag",
17
- setup: "One command to get fully operational — detects IDE, inits, installs hooks + MCP",
18
- init: "Scaffold inferno/ in your project (or adopt existing project)",
19
- "install-cursor-hooks": "Install Cursor hooks: draft agent replies to inferno/CONTEXT.draft.md",
20
- "install-vscode-copilot-hooks":
21
- "Install VS Code + Copilot agent hooks (Preview): draft to inferno/CONTEXT.draft.md",
22
- check: "Validate contract, capabilities, scenarios, changelog",
23
- status: "Show contract health at a glance",
24
- "pr-impact": "Summarize PR impact on capabilities and docs",
25
- sync: "Run deterministic inferno sync flow",
26
- run: "One-command detect/propose/apply/validate flow",
27
- "doc-gate": "Fail if code changed but docs were not updated",
28
- suggest: "Generate AI prompt + apply capability updates",
29
- implement: "Generate code-agent implementation prompt(s)",
30
- context: "Generate AI-ready context for new sessions",
31
- "generate-skills": "Generate personalised Cursor rules + skill files from your developer profile",
32
- synthesize: "Auto-detect workflow patterns and synthesize reusable skills + agents",
33
- agent: "Manage and run auto-synthesized agents (list | run | show | delete)",
34
- version: "Smart semver bump recommendation based on capability changes (--apply to write)",
35
- "pr-comment": "Post capability drift analysis as a GitHub PR comment (works in CI automatically)",
36
- dashboard: "Launch local web dashboard on localhost:7337 — live contract health, capabilities, agents",
37
- "team-sync": "Sync capability contract across a team via a shared git branch (push | pull | status | init)",
38
- onboard: "Interactive onboarding wizard for new developers — explains infernoflow in 5 minutes",
39
- cloud: "Sync capability contracts via infernoflow cloud (init | push | pull | status | dashboard)",
40
- share: "Generate a public read-only HTML snapshot of your capability contract",
41
- watch: "Watch source files and run suggest automatically on save",
42
- ci: "CI-native check: GitHub Actions annotations, GitLab code quality, exit codes",
43
- notify: "Post capability drift summary to Slack or Discord",
44
- report: "Generate a weekly/monthly HTML or Markdown report of capability activity",
45
- monorepo: "Manage infernoflow across monorepo packages (init | list | status | diff | sync)",
46
- link: "Link capabilities to Jira, Linear, or GitHub Issues tickets",
47
- audit: "Classify capabilities by sensitivity (auth, payment, PII, admin) and generate security surface map",
48
- scout: "Scan source files for undocumented capabilities not yet in the contract",
49
- export: "Export contract to OpenAPI, Backstage catalog-info.yaml, CSV, or Markdown",
50
- snapshot: "Save/diff/restore named snapshots of the capability contract",
51
- health: "Compute a 0–100 health score across coverage, docs, freshness, completeness, drift",
52
- vibe: "Vibe coding mode — watches files, auto-syncs contract, regenerates context on every save",
53
- adopt: "Interactive wizard to adopt infernoflow in an existing project (detect → review → wire up)",
54
- doctor: "Diagnose your infernoflow setup — checks Node, git, contract, AI providers, MCP, hooks",
55
- coverage: "Map test files to capabilities — show which caps have test coverage and which don't",
56
- review: "AI-powered capability impact review for staged or recent git changes",
57
- scan: "Deep AST scan — reads actual function bodies, extracts calls, DB ops, external services",
58
- graph: "Build capability dependency graph — shows which caps call which, detects breaking changes",
59
- stability: "Show solid/liquid stability level for every capability (frozen/stable/experimental)",
60
- freeze: "Mark a capability as frozen (solid) — AI will not modify it without explicit instruction",
61
- thaw: "Reset a capability to experimental (liquid) — free to evolve",
62
- why: "Given a file or function name — show which capability it serves, scenarios, stability, and git history",
63
- impact: "Blast radius analysis — see every cap, scenario, and risk level affected before you change anything",
64
- scaffold: "Generate a new capability — source skeleton, contract registration, and placeholder scenario in one command",
65
- explain: "AI narrative about a capability — what it does, why it exists, what's risky, and what to test",
66
- test: "Run registered scenarios for a capability — auto-generates a smoke harness if no test runner is configured",
67
- ai: "Manage AI providers — setup, status, test connection (subcommands: setup | status | test | clear)",
68
- demo: "Interactive walkthrough — scaffolds a sample project and runs the full capability chain end-to-end",
69
- };
70
-
71
- const COMMAND_HANDLERS = {
72
- publish: async (args) => (await import("../lib/commands/publish.mjs")).publishCommand(args),
73
- diff: async (args) => (await import("../lib/commands/diff.mjs")).diffCommand(args),
74
- changelog: async (args) => (await import("../lib/commands/changelog.mjs")).changelogCommand(args),
75
- setup: async (args) => (await import("../lib/commands/setup.mjs")).setupCommand(args),
76
- init: async (args) => (await import("../lib/commands/init.mjs")).initCommand(args),
77
- "install-cursor-hooks": async (args) =>
78
- (await import("../lib/commands/installCursorHooks.mjs")).installCursorHooksCommand(args),
79
- "install-vscode-copilot-hooks": async (args) =>
80
- (await import("../lib/commands/installVsCodeCopilotHooks.mjs")).installVsCodeCopilotHooksCommand(args),
81
- check: async (args) => (await import("../lib/commands/check.mjs")).checkCommand(args),
82
- status: async (args) => (await import("../lib/commands/status.mjs")).statusCommand(args),
83
- "pr-impact": async (args) => (await import("../lib/commands/prImpact.mjs")).prImpactCommand(args),
84
- sync: async (args) => (await import("../lib/commands/syncAuto.mjs")).syncCommand(args),
85
- run: async (args) => (await import("../lib/commands/run.mjs")).runCommand(args),
86
- suggest: async (args) => (await import("../lib/commands/suggest.mjs")).suggestCommand(args),
87
- implement: async (args) => (await import("../lib/commands/implement.mjs")).implementCommand(args),
88
- context: async (args) => (await import("../lib/commands/context.mjs")).contextCommand(args),
89
- "doc-gate": async (args) => (await import("../lib/commands/docGate.mjs")).docGateCommand(args),
90
- "generate-skills": async (args) => (await import("../lib/commands/generateSkills.mjs")).generateSkillsCommand(args),
91
- synthesize: async (args) => (await import("../lib/commands/synthesize.mjs")).synthesizeCommand(args),
92
- agent: async (args) => (await import("../lib/commands/agent.mjs")).agentCommand(args),
93
- version: async (args) => (await import("../lib/commands/version.mjs")).versionCommand(args),
94
- "pr-comment": async (args) => (await import("../lib/commands/prComment.mjs")).prCommentCommand(args),
95
- dashboard: async (args) => (await import("../lib/commands/dashboard.mjs")).dashboardCommand(args),
96
- "team-sync": async (args) => (await import("../lib/commands/teamSync.mjs")).teamSyncCommand(args),
97
- onboard: async (args) => (await import("../lib/commands/onboard.mjs")).onboardCommand(args),
98
- cloud: async (args) => (await import("../lib/commands/cloud.mjs")).cloudCommand(args),
99
- share: async (args) => (await import("../lib/commands/share.mjs")).shareCommand(args),
100
- watch: async (args) => (await import("../lib/commands/watch.mjs")).watchCommand(args),
101
- ci: async (args) => (await import("../lib/commands/ci.mjs")).ciCommand(args),
102
- notify: async (args) => (await import("../lib/commands/notify.mjs")).notifyCommand(args),
103
- report: async (args) => (await import("../lib/commands/report.mjs")).reportCommand(args),
104
- monorepo: async (args) => (await import("../lib/commands/monorepo.mjs")).monorepoCommand(args),
105
- link: async (args) => (await import("../lib/commands/link.mjs")).linkCommand(args),
106
- audit: async (args) => (await import("../lib/commands/audit.mjs")).auditCommand(args),
107
- scout: async (args) => (await import("../lib/commands/scout.mjs")).scoutCommand(args),
108
- export: async (args) => (await import("../lib/commands/export.mjs")).exportCommand(args),
109
- snapshot: async (args) => (await import("../lib/commands/snapshot.mjs")).snapshotCommand(args),
110
- health: async (args) => (await import("../lib/commands/health.mjs")).healthCommand(args),
111
- vibe: async (args) => (await import("../lib/commands/vibe.mjs")).vibeCommand(args),
112
- adopt: async (args) => (await import("../lib/commands/adoptWizard.mjs")).adoptWizardCommand(args),
113
- doctor: async (args) => (await import("../lib/commands/doctor.mjs")).doctorCommand(args),
114
- coverage: async (args) => (await import("../lib/commands/coverage.mjs")).coverageCommand(args),
115
- review: async (args) => (await import("../lib/commands/review.mjs")).reviewCommand(args),
116
- scan: async (args) => (await import("../lib/commands/scan.mjs")).scanCommand(args),
117
- graph: async (args) => (await import("../lib/commands/graph.mjs")).graphCommand(args),
118
- stability: async (args) => (await import("../lib/commands/stability.mjs")).stabilityCommand(args),
119
- freeze: async (args) => (await import("../lib/commands/stability.mjs")).freezeCommand(args),
120
- thaw: async (args) => (await import("../lib/commands/stability.mjs")).thawCommand(args),
121
- why: async (args) => (await import("../lib/commands/why.mjs")).whyCommand(args),
122
- impact: async (args) => (await import("../lib/commands/impact.mjs")).impactCommand(args),
123
- scaffold: async (args) => (await import("../lib/commands/scaffold.mjs")).scaffoldCommand(args),
124
- explain: async (args) => (await import("../lib/commands/explain.mjs")).explainCommand(args),
125
- test: async (args) => (await import("../lib/commands/test.mjs")).testCommand(args),
126
- ai: async (args) => (await import("../lib/commands/ai.mjs")).aiCommand(args),
127
- demo: async (args) => (await import("../lib/commands/demo.mjs")).demoCommand(args),
128
- };
129
-
130
- function formatCommandsHelp() {
131
- const names = Object.keys(COMMAND_DESCRIPTIONS);
132
- const w = Math.max(...names.map((n) => n.length), 8) + 1;
133
- return Object.entries(COMMAND_DESCRIPTIONS)
134
- .map(([name, desc]) => ` ${name.padEnd(w, " ")}${desc}`)
135
- .join("\n");
136
- }
137
-
138
- const HELP = `
139
- ${bold("🔥 infernoflow")} ${gray("v" + VERSION)}
140
- ${gray("The forge for liquid code — keep every AI session in sync")}
141
-
142
- ${bold("Usage:")}
2
+ import{readFileSync as d}from"node:fs";import{dirname as m,join as u}from"node:path";import{fileURLToPath as f}from"node:url";import{bold as t,gray as a,red as s}from"../lib/ui/output.mjs";const h=m(f(import.meta.url)),y=JSON.parse(d(u(h,"..","..","package.json"),"utf8")),r=y.version||"0.0.0",c={publish:"Bump version, update changelog, build, npm publish, git commit + push in one shot",diff:"Show what capabilities changed since the last git tag (or any ref)",changelog:"Draft a changelog entry from commits since the last tag",setup:"One command to get fully operational \u2014 detects IDE, inits, installs hooks + MCP",init:"Scaffold inferno/ in your project (or adopt existing project)","install-cursor-hooks":"Install Cursor hooks: draft agent replies to inferno/CONTEXT.draft.md","install-vscode-copilot-hooks":"Install VS Code + Copilot agent hooks (Preview): draft to inferno/CONTEXT.draft.md",check:"Validate contract, capabilities, scenarios, changelog",status:"Show contract health at a glance","pr-impact":"Summarize PR impact on capabilities and docs",sync:"Run deterministic inferno sync flow",run:"One-command detect/propose/apply/validate flow","doc-gate":"Fail if code changed but docs were not updated",suggest:"Generate AI prompt + apply capability updates",implement:"Generate code-agent implementation prompt(s)",context:"Generate AI-ready context for new sessions","generate-skills":"Generate personalised Cursor rules + skill files from your developer profile",synthesize:"Auto-detect workflow patterns and synthesize reusable skills + agents",agent:"Manage and run auto-synthesized agents (list | run | show | delete)",version:"Smart semver bump recommendation based on capability changes (--apply to write)","pr-comment":"Post capability drift analysis as a GitHub PR comment (works in CI automatically)",dashboard:"Launch local web dashboard on localhost:7337 \u2014 live contract health, capabilities, agents","team-sync":"Sync capability contract across a team via a shared git branch (push | pull | status | init)",onboard:"Interactive onboarding wizard for new developers \u2014 explains infernoflow in 5 minutes",cloud:"Sync capability contracts via infernoflow cloud (init | push | pull | status | dashboard)",share:"Generate a public read-only HTML snapshot of your capability contract",watch:"Watch source files and run suggest automatically on save",ci:"CI-native check: GitHub Actions annotations, GitLab code quality, exit codes",notify:"Post capability drift summary to Slack or Discord",report:"Generate a weekly/monthly HTML or Markdown report of capability activity",monorepo:"Manage infernoflow across monorepo packages (init | list | status | diff | sync)",link:"Link capabilities to Jira, Linear, or GitHub Issues tickets",audit:"Classify capabilities by sensitivity (auth, payment, PII, admin) and generate security surface map",scout:"Scan source files for undocumented capabilities not yet in the contract",export:"Export contract to OpenAPI, Backstage catalog-info.yaml, CSV, or Markdown",snapshot:"Save/diff/restore named snapshots of the capability contract",health:"Compute a 0\u2013100 health score across coverage, docs, freshness, completeness, drift",vibe:"Vibe coding mode \u2014 watches files, auto-syncs contract, regenerates context on every save",adopt:"Interactive wizard to adopt infernoflow in an existing project (detect \u2192 review \u2192 wire up)",doctor:"Diagnose your infernoflow setup \u2014 checks Node, git, contract, AI providers, MCP, hooks",coverage:"Map test files to capabilities \u2014 show which caps have test coverage and which don't",review:"AI-powered capability impact review for staged or recent git changes",scan:"Deep AST scan \u2014 reads actual function bodies, extracts calls, DB ops, external services",graph:"Build capability dependency graph \u2014 shows which caps call which, detects breaking changes",stability:"Show solid/liquid stability level for every capability (frozen/stable/experimental)",freeze:"Mark a capability as frozen (solid) \u2014 AI will not modify it without explicit instruction",thaw:"Reset a capability to experimental (liquid) \u2014 free to evolve",why:"Given a file or function name \u2014 show which capability it serves, scenarios, stability, and git history",impact:"Blast radius analysis \u2014 see every cap, scenario, and risk level affected before you change anything",scaffold:"Generate a new capability \u2014 source skeleton, contract registration, and placeholder scenario in one command",explain:"AI narrative about a capability \u2014 what it does, why it exists, what's risky, and what to test",test:"Run registered scenarios for a capability \u2014 auto-generates a smoke harness if no test runner is configured",ai:"Manage AI providers \u2014 setup, status, test connection (subcommands: setup | status | test | clear)",demo:"Interactive walkthrough \u2014 scaffolds a sample project and runs the full capability chain end-to-end"},l={publish:async e=>(await import("../lib/commands/publish.mjs")).publishCommand(e),diff:async e=>(await import("../lib/commands/diff.mjs")).diffCommand(e),changelog:async e=>(await import("../lib/commands/changelog.mjs")).changelogCommand(e),setup:async e=>(await import("../lib/commands/setup.mjs")).setupCommand(e),init:async e=>(await import("../lib/commands/init.mjs")).initCommand(e),"install-cursor-hooks":async e=>(await import("../lib/commands/installCursorHooks.mjs")).installCursorHooksCommand(e),"install-vscode-copilot-hooks":async e=>(await import("../lib/commands/installVsCodeCopilotHooks.mjs")).installVsCodeCopilotHooksCommand(e),check:async e=>(await import("../lib/commands/check.mjs")).checkCommand(e),status:async e=>(await import("../lib/commands/status.mjs")).statusCommand(e),"pr-impact":async e=>(await import("../lib/commands/prImpact.mjs")).prImpactCommand(e),sync:async e=>(await import("../lib/commands/syncAuto.mjs")).syncCommand(e),run:async e=>(await import("../lib/commands/run.mjs")).runCommand(e),suggest:async e=>(await import("../lib/commands/suggest.mjs")).suggestCommand(e),implement:async e=>(await import("../lib/commands/implement.mjs")).implementCommand(e),context:async e=>(await import("../lib/commands/context.mjs")).contextCommand(e),"doc-gate":async e=>(await import("../lib/commands/docGate.mjs")).docGateCommand(e),"generate-skills":async e=>(await import("../lib/commands/generateSkills.mjs")).generateSkillsCommand(e),synthesize:async e=>(await import("../lib/commands/synthesize.mjs")).synthesizeCommand(e),agent:async e=>(await import("../lib/commands/agent.mjs")).agentCommand(e),version:async e=>(await import("../lib/commands/version.mjs")).versionCommand(e),"pr-comment":async e=>(await import("../lib/commands/prComment.mjs")).prCommentCommand(e),dashboard:async e=>(await import("../lib/commands/dashboard.mjs")).dashboardCommand(e),"team-sync":async e=>(await import("../lib/commands/teamSync.mjs")).teamSyncCommand(e),onboard:async e=>(await import("../lib/commands/onboard.mjs")).onboardCommand(e),cloud:async e=>(await import("../lib/commands/cloud.mjs")).cloudCommand(e),share:async e=>(await import("../lib/commands/share.mjs")).shareCommand(e),watch:async e=>(await import("../lib/commands/watch.mjs")).watchCommand(e),ci:async e=>(await import("../lib/commands/ci.mjs")).ciCommand(e),notify:async e=>(await import("../lib/commands/notify.mjs")).notifyCommand(e),report:async e=>(await import("../lib/commands/report.mjs")).reportCommand(e),monorepo:async e=>(await import("../lib/commands/monorepo.mjs")).monorepoCommand(e),link:async e=>(await import("../lib/commands/link.mjs")).linkCommand(e),audit:async e=>(await import("../lib/commands/audit.mjs")).auditCommand(e),scout:async e=>(await import("../lib/commands/scout.mjs")).scoutCommand(e),export:async e=>(await import("../lib/commands/export.mjs")).exportCommand(e),snapshot:async e=>(await import("../lib/commands/snapshot.mjs")).snapshotCommand(e),health:async e=>(await import("../lib/commands/health.mjs")).healthCommand(e),vibe:async e=>(await import("../lib/commands/vibe.mjs")).vibeCommand(e),adopt:async e=>(await import("../lib/commands/adoptWizard.mjs")).adoptWizardCommand(e),doctor:async e=>(await import("../lib/commands/doctor.mjs")).doctorCommand(e),coverage:async e=>(await import("../lib/commands/coverage.mjs")).coverageCommand(e),review:async e=>(await import("../lib/commands/review.mjs")).reviewCommand(e),scan:async e=>(await import("../lib/commands/scan.mjs")).scanCommand(e),graph:async e=>(await import("../lib/commands/graph.mjs")).graphCommand(e),stability:async e=>(await import("../lib/commands/stability.mjs")).stabilityCommand(e),freeze:async e=>(await import("../lib/commands/stability.mjs")).freezeCommand(e),thaw:async e=>(await import("../lib/commands/stability.mjs")).thawCommand(e),why:async e=>(await import("../lib/commands/why.mjs")).whyCommand(e),impact:async e=>(await import("../lib/commands/impact.mjs")).impactCommand(e),scaffold:async e=>(await import("../lib/commands/scaffold.mjs")).scaffoldCommand(e),explain:async e=>(await import("../lib/commands/explain.mjs")).explainCommand(e),test:async e=>(await import("../lib/commands/test.mjs")).testCommand(e),ai:async e=>(await import("../lib/commands/ai.mjs")).aiCommand(e),demo:async e=>(await import("../lib/commands/demo.mjs")).demoCommand(e)};function w(){const e=Object.keys(c),n=Math.max(...e.map(i=>i.length),8)+1;return Object.entries(c).map(([i,p])=>` ${i.padEnd(n," ")}${p}`).join(`
3
+ `)}const g=`
4
+ ${t("\u{1F525} infernoflow")} ${a("v"+r)}
5
+ ${a("The forge for liquid code \u2014 keep every AI session in sync")}
6
+
7
+ ${t("Usage:")}
143
8
  infernoflow <command> [options]
144
9
 
145
- ${bold("Commands:")}
146
- ${formatCommandsHelp()}
10
+ ${t("Commands:")}
11
+ ${w()}
147
12
 
148
- ${bold("diff options:")}
13
+ ${t("diff options:")}
149
14
  --ref <tag|commit> Compare against a specific ref (default: last git tag)
150
15
  --summary One-liner count only
151
16
  --json Machine-readable output
152
17
 
153
- ${bold("changelog options:")}
18
+ ${t("changelog options:")}
154
19
  update Draft ## Unreleased from commits (default sub-command)
155
20
  show Print the current ## Unreleased block
156
21
  list List commits since last tag
@@ -161,7 +26,7 @@ ${formatCommandsHelp()}
161
26
  --append Append to existing ## Unreleased instead of replacing
162
27
  --json Machine-readable output
163
28
 
164
- ${bold("publish options:")}
29
+ ${t("publish options:")}
165
30
  --bump patch|minor|major Version bump type (default: patch)
166
31
  --skip-build Skip the build step
167
32
  --skip-tests Skip smoke tests
@@ -170,13 +35,13 @@ ${formatCommandsHelp()}
170
35
  --dry-run Print all steps without executing
171
36
  --yes, -y Non-interactive (skip confirmation prompt)
172
37
 
173
- ${bold("setup options:")}
38
+ ${t("setup options:")}
174
39
  --yes, -y Skip prompts (non-interactive)
175
40
  --force, -f Overwrite existing hook files
176
41
 
177
- ${bold("init options:")}
178
- --cursor-hooks Also install Cursor hooks (draft inferno/CONTEXT.draft.md)
179
- --vscode-copilot-hooks Also install VS Code + Copilot hooks (.github/hooks Preview)
42
+ ${t("init options:")}
43
+ --cursor-hooks Also install Cursor hooks (draft \u2192 inferno/CONTEXT.draft.md)
44
+ --vscode-copilot-hooks Also install VS Code + Copilot hooks (.github/hooks \u2014 Preview)
180
45
  --adopt Infer capabilities from an existing codebase
181
46
  --lang <name> Override detected language (e.g. ts, js, py)
182
47
  --framework <name> Override detected framework (e.g. react, angular, express)
@@ -187,13 +52,13 @@ ${formatCommandsHelp()}
187
52
  --yes, -y Skip prompts and accept inferred/default values
188
53
  --force, -f Overwrite existing inferno/ files
189
54
 
190
- ${bold("install-cursor-hooks options:")}
55
+ ${t("install-cursor-hooks options:")}
191
56
  --force, -f Overwrite .cursor/hooks.json and hook scripts if they exist
192
57
 
193
- ${bold("install-vscode-copilot-hooks options:")}
58
+ ${t("install-vscode-copilot-hooks options:")}
194
59
  --force, -f Overwrite .github/hooks/infernoflow-drafts.json and scripts if they exist
195
60
 
196
- ${bold("context options:")}
61
+ ${t("context options:")}
197
62
  --intent "..." What you plan to build next
198
63
  --working "..." What you are building right now
199
64
  --decision "..." Record a decision or note
@@ -205,39 +70,39 @@ ${formatCommandsHelp()}
205
70
  --auto-commit Watch mode: commit CONTEXT.md to git on every change
206
71
  --auto-push Watch mode: commit + push CONTEXT.md on every change
207
72
 
208
- ${bold("generate-skills options:")}
73
+ ${t("generate-skills options:")}
209
74
  --cursor Also install rules to .cursor/rules/infernoflow.md
210
75
  --force, -f Overwrite existing generated skill files
211
76
 
212
- ${bold("implement options:")}
77
+ ${t("implement options:")}
213
78
  --mode <type> cursor | generic | both (default: both)
214
79
  --copy, -c Copy generated prompt(s) to clipboard
215
80
 
216
- ${bold("run options:")}
81
+ ${t("run options:")}
217
82
  --dry-run Execute full flow without writing files
218
83
  --json Emit machine-readable events and result payload
219
84
  --no-rollback Keep changes even if validation fails
220
85
  --provider <type> auto | agent | local | prompt (default: auto)
221
86
  --ide <name> auto | cursor | vscode | windsurf (default: auto)
222
87
 
223
- ${bold("Typical workflow:")}
224
- ${gray('1. infernoflow context --intent "what I want to build"')}
225
- ${gray("2. [paste inferno/CONTEXT.md into Claude / Cursor / Copilot]")}
226
- ${gray("3. [build the feature]")}
227
- ${gray('4. infernoflow suggest "what I built"')}
228
- ${gray("5. infernoflow check")}
88
+ ${t("Typical workflow:")}
89
+ ${a('1. infernoflow context --intent "what I want to build"')}
90
+ ${a("2. [paste inferno/CONTEXT.md into Claude / Cursor / Copilot]")}
91
+ ${a("3. [build the feature]")}
92
+ ${a('4. infernoflow suggest "what I built"')}
93
+ ${a("5. infernoflow check")}
229
94
 
230
- ${bold("suggest options:")}
95
+ ${t("suggest options:")}
231
96
  --json Non-interactive: emit prompt as JSON, no readline prompts
232
97
  --response <json|@file> Provide AI response directly (use with --json)
233
98
  --apply Apply the response changes when using --json --response
234
99
 
235
- ${bold("version options:")}
100
+ ${t("version options:")}
236
101
  --ref <tag|commit> Compare against a specific ref (default: last git tag)
237
102
  --apply Write recommended version bump to package.json
238
103
  --json Machine-readable output
239
104
 
240
- ${bold("pr-comment options:")}
105
+ ${t("pr-comment options:")}
241
106
  --pr <number> PR number to comment on (auto-detected in GitHub Actions)
242
107
  --repo <owner/repo> GitHub repository (auto-detected in GitHub Actions)
243
108
  --token <ghp_...> GitHub token (auto-detected from GITHUB_TOKEN env var)
@@ -245,83 +110,83 @@ ${formatCommandsHelp()}
245
110
  --dry-run Print the comment without posting it
246
111
  --json Machine-readable output
247
112
 
248
- ${bold("cloud sub-commands:")}
113
+ ${t("cloud sub-commands:")}
249
114
  init Generate a project token and configure cloud sync
250
115
  push Upload local capability contract to cloud
251
116
  pull Download latest contract from cloud (conflict detection)
252
117
  status Compare local vs cloud (hashes, capability counts)
253
118
  dashboard Print hosted dashboard URL and open in browser
254
119
 
255
- ${bold("cloud options:")}
120
+ ${t("cloud options:")}
256
121
  --token <tok> Override token (or set INFERNOFLOW_TOKEN env var)
257
122
  --endpoint <url> Override default endpoint (https://cloud.infernoflow.dev)
258
123
  --force, -f Overwrite on init; overwrite local on conflicted pull
259
124
  --dry-run Print what would happen without sending
260
125
  --json Machine-readable output
261
126
 
262
- ${bold("share options:")}
127
+ ${t("share options:")}
263
128
  --upload Upload to dpaste.com and print a public URL
264
129
  --open Open the snapshot in your browser immediately
265
130
  --copy Copy HTML to clipboard
266
131
  --out <path> Custom output path (default: inferno/share.html)
267
132
  --json Machine-readable: { ok, file, url }
268
133
 
269
- ${bold("watch options:")}
134
+ ${t("watch options:")}
270
135
  [dirs...] Directories to watch (default: src/, lib/, app/)
271
136
  --interval <secs> Debounce interval in seconds (default: 3)
272
137
  --dry-run Print what would run without executing
273
138
  --silent No output (for git hook use)
274
139
 
275
- ${bold("notify options:")}
140
+ ${t("notify options:")}
276
141
  --slack <url> Slack incoming webhook URL
277
142
  --discord <url> Discord webhook URL
278
143
  --on-change Only notify if capabilities actually changed
279
144
  --dry-run Print message without sending
280
145
  --json Machine-readable result
281
146
 
282
- ${bold("report options:")}
147
+ ${t("report options:")}
283
148
  --format html|md Output format (default: html)
284
149
  --since <period> 7d, 30d, 90d, or YYYY-MM-DD (default: 30d)
285
150
  --out <path> Output file path (default: inferno/report.html)
286
151
  --open Open HTML report in browser after generating
287
152
  --json Machine-readable summary
288
153
 
289
- ${bold("ci options:")}
154
+ ${t("ci options:")}
290
155
  --platform <name> github | gitlab | bitbucket | generic (auto-detected)
291
156
  --fail-on <level> error | warning (default: error)
292
157
  --json Machine-readable result + exit code
293
158
 
294
- ${bold("monorepo sub-commands:")}
159
+ ${t("monorepo sub-commands:")}
295
160
  init Run infernoflow init --adopt in every package
296
161
  list List detected packages with their capability counts
297
162
  status Show contract health across all packages
298
163
  diff Show capability changes across packages (--package to filter)
299
164
  sync Aggregate all contracts into inferno-monorepo.json
300
165
 
301
- ${bold("monorepo options:")}
166
+ ${t("monorepo options:")}
302
167
  --package <name> Filter to a specific package
303
168
  --json Machine-readable output
304
169
 
305
- ${bold("link sub-commands:")}
170
+ ${t("link sub-commands:")}
306
171
  (default) Link a capability to a ticket
307
- list Show all capability→ticket links
172
+ list Show all capability\u2192ticket links
308
173
  status Show linked and unlinked capabilities
309
174
  remove Remove a link by capability ID
310
175
 
311
- ${bold("link options:")}
176
+ ${t("link options:")}
312
177
  --capability <id> Capability to link
313
178
  --jira <TICKET> Jira ticket ID (e.g. PROJ-123)
314
179
  --linear <ID> Linear issue ID
315
180
  --github <NUM> GitHub issue number
316
181
  --json Machine-readable output
317
182
 
318
- ${bold("audit options:")}
183
+ ${t("audit options:")}
319
184
  --format text|json|html Output format (default: text)
320
185
  --out <path> Save to file (default: prints to stdout)
321
186
  --fail-on high|medium Exit 1 if unreviewed caps at given severity exist
322
187
  --json Machine-readable output
323
188
 
324
- ${bold("vibe options:")}
189
+ ${t("vibe options:")}
325
190
  --dir <dirs> Comma-separated directories to watch (default: auto-detected)
326
191
  --no-suggest Disable automatic contract sync on file save
327
192
  --no-context Disable CONTEXT.md regeneration
@@ -329,30 +194,30 @@ ${formatCommandsHelp()}
329
194
  --port <n> Also run a mini status dashboard on localhost:<n>
330
195
  --silent Suppress all terminal output (pure background mode)
331
196
 
332
- ${bold("adopt options:")}
197
+ ${t("adopt options:")}
333
198
  --dir <dirs> Source directories to scan (default: src,lib,app,api,routes,controllers)
334
199
  --yes, -y Auto-approve all candidates (non-interactive)
335
200
  --json Machine-readable output, implies --yes
336
201
 
337
- ${bold("init --template options:")}
202
+ ${t("init --template options:")}
338
203
  --template rest-api REST API (Express/Fastify/Hono) starter
339
204
  --template nextjs Next.js fullstack app starter
340
205
  --template cli CLI tool (Node.js/Python) starter
341
206
  --template graphql GraphQL API (Apollo/Pothos) starter
342
207
  --template monorepo Monorepo workspace starter
343
208
 
344
- ${bold("scout options:")}
209
+ ${t("scout options:")}
345
210
  --dir <dirs> Comma-separated directories to scan (default: src,lib,app,api,routes)
346
211
  --apply Write discovered capabilities to the contract file
347
212
  --min-confidence <0-1> Minimum confidence threshold (default: 0.6)
348
213
  --json Machine-readable output
349
214
 
350
- ${bold("export options:")}
215
+ ${t("export options:")}
351
216
  --format openapi|backstage|csv|markdown|json Output format (required)
352
217
  --out <path> Output file path (default: project root, auto-named)
353
218
  --json Machine-readable summary
354
219
 
355
- ${bold("snapshot sub-commands:")}
220
+ ${t("snapshot sub-commands:")}
356
221
  save <name> Save current contract as a named snapshot
357
222
  list List all snapshots
358
223
  show <name> Print a snapshot's capabilities
@@ -360,62 +225,62 @@ ${formatCommandsHelp()}
360
225
  restore <name> Overwrite contract with snapshot contents
361
226
  delete <name> Delete a snapshot
362
227
 
363
- ${bold("snapshot options:")}
228
+ ${t("snapshot options:")}
364
229
  --json Machine-readable output
365
230
 
366
- ${bold("health options:")}
231
+ ${t("health options:")}
367
232
  --fail-below <score> Exit 1 if health score is below this threshold (CI gate)
368
233
  --watch Re-run every 30s (live terminal view)
369
234
  --interval <secs> Watch interval in seconds (default: 30)
370
235
  --json Machine-readable score + breakdown
371
236
 
372
- ${bold("doctor options:")}
237
+ ${t("doctor options:")}
373
238
  --fix Auto-fix common issues (installs hooks, runs init, etc.)
374
239
  --json Machine-readable list of pass/warn/fail results
375
240
 
376
- ${bold("coverage options:")}
241
+ ${t("coverage options:")}
377
242
  --dir <path> Extra directory to scan for test files (repeatable)
378
243
  --threshold <0-1> Minimum fuzzy-match score to count a test (default: 0.25)
379
244
  --fail-below <pct> Exit 1 if coverage percentage is below this value (CI gate)
380
245
  --json Machine-readable coverage breakdown
381
246
 
382
- ${bold("scan options:")}
247
+ ${t("scan options:")}
383
248
  --dir <path> Extra directory to scan (repeatable)
384
249
  --capability <id> Scan and enrich a single capability only
385
250
  --dry-run Print results without writing files
386
251
  --json Machine-readable scan output
387
252
 
388
- ${bold("graph options:")}
253
+ ${t("graph options:")}
389
254
  --cap <id> Show dependency view for a single capability
390
255
  --check Exit 1 if breaking dependency changes detected (CI gate)
391
256
  --json Machine-readable graph output
392
257
 
393
- ${bold("stability / freeze / thaw options:")}
258
+ ${t("stability / freeze / thaw options:")}
394
259
  infernoflow stability List all capabilities with their stability level
395
260
  infernoflow freeze <id> Mark capability as frozen (AI won't touch it)
396
261
  infernoflow freeze <id> --stable Mark as stable (careful, not forbidden)
397
- infernoflow thaw <id> Reset to experimental (liquid free to change)
262
+ infernoflow thaw <id> Reset to experimental (liquid \u2014 free to change)
398
263
  --json Machine-readable stability list
399
264
 
400
- ${bold("review options:")}
265
+ ${t("review options:")}
401
266
  --unstaged Review all working-tree changes (not just staged)
402
267
  --last Review last commit (git diff HEAD~1)
403
- --dry-run Print the AI prompt only no API call made
268
+ --dry-run Print the AI prompt only \u2014 no API call made
404
269
  --json Machine-readable output (affectedCaps, summary, provider)
405
270
 
406
- ${bold("why options:")}
271
+ ${t("why options:")}
407
272
  infernoflow why <file> Show capability for a source file
408
273
  infernoflow why <functionName> Show capability for a function name
409
274
  --function <name> Filter to a specific function when multiple caps match
410
275
  --json Machine-readable output
411
276
 
412
- ${bold("impact options:")}
277
+ ${t("impact options:")}
413
278
  infernoflow impact <cap-id> Show blast radius for a capability
414
279
  --depth <n> Max transitive depth to traverse (default: 10)
415
280
  --check Exit 1 if risk level is HIGH or CRITICAL (CI gate)
416
281
  --json Machine-readable output
417
282
 
418
- ${bold("scaffold options:")}
283
+ ${t("scaffold options:")}
419
284
  infernoflow scaffold <cap-id> Generate a new capability skeleton
420
285
  --dir <path> Output directory for the source file (default: auto-detected)
421
286
  --lang ts|js|py|go Language override (default: auto-detected from project)
@@ -423,12 +288,12 @@ ${formatCommandsHelp()}
423
288
  --dry-run Preview what would be generated without writing files
424
289
  --json Machine-readable output including generated code
425
290
 
426
- ${bold("explain options:")}
291
+ ${t("explain options:")}
427
292
  infernoflow explain <cap-id> AI narrative: what it does, risk, what to test
428
- --dry-run Print the AI prompt only no API call made
293
+ --dry-run Print the AI prompt only \u2014 no API call made
429
294
  --json Machine-readable output (narrative, stability, scenarios)
430
295
 
431
- ${bold("test options:")}
296
+ ${t("test options:")}
432
297
  infernoflow test Run all caps that have registered scenarios
433
298
  infernoflow test <cap-id> Run scenarios for a specific capability
434
299
  infernoflow test --all Run every capability (including those without scenarios)
@@ -437,66 +302,30 @@ ${formatCommandsHelp()}
437
302
  --verbose, -v Show runner output for each scenario
438
303
  --json Machine-readable output (passed/failed/skipped counts)
439
304
 
440
- ${bold("ai options:")}
441
- infernoflow ai setup Interactive wizard pick provider, enter API key, verify
305
+ ${t("ai options:")}
306
+ infernoflow ai setup Interactive wizard \u2014 pick provider, enter API key, verify
442
307
  infernoflow ai status Show all providers and which are configured
443
308
  infernoflow ai test [provider] Send a test prompt and verify the connection
444
309
  infernoflow ai clear <provider> Remove a provider's config from integrations.json
445
310
  Supported providers: anthropic openai gemini openrouter ollama
446
311
 
447
- ${bold("demo options:")}
312
+ ${t("demo options:")}
448
313
  infernoflow demo Full interactive walkthrough (sample e-commerce project)
449
- infernoflow demo --fast Skip pauses good for CI or screen recording
314
+ infernoflow demo --fast Skip pauses \u2014 good for CI or screen recording
450
315
  infernoflow demo --no-cleanup Keep the temp demo project after the run
451
316
 
452
- ${bold("Machine output:")}
453
- ${gray("status --json")}
454
- ${gray("check --json")}
455
- ${gray("doc-gate --json")}
456
- ${gray("pr-impact --json")}
457
- ${gray("sync --auto --json")}
458
- ${gray('run "task" --json')}
459
- ${gray('suggest "what changed" --json')}
460
- ${gray('suggest "what changed" --json --response \'{"newCapabilities":[...]}\' --apply')}
461
- ${gray("version --json")}
462
- ${gray("version --apply")}
463
- `;
464
-
465
- // ── Silent behavior observation ───────────────────────────────────────────
466
- import * as fs from "node:fs";
467
- import * as path from "node:path";
468
- try {
469
- const infernoDir = path.join(process.cwd(), "inferno");
470
- if (fs.existsSync(infernoDir)) {
471
- const { observeCommandStart } = await import("../lib/learning/observe.mjs");
472
- const cmdForObserve = process.argv[2];
473
- if (cmdForObserve && !cmdForObserve.startsWith("-")) {
474
- observeCommandStart(infernoDir, cmdForObserve);
475
- }
476
- }
477
- } catch {}
478
-
479
- const [, , cmd, ...rest] = process.argv;
480
-
481
- if (!cmd || cmd === "--help" || cmd === "-h") {
482
- console.log(HELP);
483
- process.exit(0);
484
- }
485
- if (cmd === "--version" || cmd === "-v") {
486
- console.log(VERSION);
487
- process.exit(0);
488
- }
489
-
490
- const commands = Object.keys(COMMAND_HANDLERS);
491
-
492
- if (!commands.includes(cmd)) {
493
- console.error(red(`\nUnknown command: ${cmd}`));
494
- console.error(gray("Run: infernoflow --help\n"));
495
- process.exit(1);
496
- }
497
-
498
- const args = [cmd, ...rest];
499
- COMMAND_HANDLERS[cmd](args).catch((err) => {
500
- console.error(red("\nError: ") + err.message);
501
- process.exit(1);
502
- });
317
+ ${t("Machine output:")}
318
+ ${a("status --json")}
319
+ ${a("check --json")}
320
+ ${a("doc-gate --json")}
321
+ ${a("pr-impact --json")}
322
+ ${a("sync --auto --json")}
323
+ ${a('run "task" --json')}
324
+ ${a('suggest "what changed" --json')}
325
+ ${a(`suggest "what changed" --json --response '{"newCapabilities":[...]}' --apply`)}
326
+ ${a("version --json")}
327
+ ${a("version --apply")}
328
+ `;import*as b from"node:fs";import*as v from"node:path";try{const e=v.join(process.cwd(),"inferno");if(b.existsSync(e)){const{observeCommandStart:n}=await import("../lib/learning/observe.mjs"),i=process.argv[2];i&&!i.startsWith("-")&&n(e,i)}}catch{}const[,,o,...k]=process.argv;(!o||o==="--help"||o==="-h")&&(console.log(g),process.exit(0)),(o==="--version"||o==="-v")&&(console.log(r),process.exit(0));const C=Object.keys(l);C.includes(o)||(console.error(s(`
329
+ Unknown command: ${o}`)),console.error(a(`Run: infernoflow --help
330
+ `)),process.exit(1));const j=[o,...k];l[o](j).catch(e=>{console.error(s(`
331
+ Error: `)+e.message),process.exit(1)});