infernoflow 0.4.2 → 0.5.0
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 +41 -25
- package/bin/infernoflow.mjs +58 -40
- package/lib/commands/context.mjs +170 -0
- package/package.json +1 -1
- package/lib/infernoflow.mjs +0 -94
package/README.md
CHANGED
|
@@ -25,16 +25,19 @@ npx infernoflow init
|
|
|
25
25
|
## Quick Start
|
|
26
26
|
|
|
27
27
|
```bash
|
|
28
|
-
#
|
|
28
|
+
# 1. Scaffold in your project root:
|
|
29
29
|
npx infernoflow init
|
|
30
30
|
|
|
31
|
-
# See your contract health:
|
|
31
|
+
# 2. See your contract health:
|
|
32
32
|
infernoflow status
|
|
33
33
|
|
|
34
|
-
#
|
|
34
|
+
# 3. When you add a feature, let AI update the docs:
|
|
35
|
+
infernoflow suggest "added email notifications and user profiles"
|
|
36
|
+
|
|
37
|
+
# 4. Validate everything:
|
|
35
38
|
infernoflow check
|
|
36
39
|
|
|
37
|
-
# In CI / pre-push hook:
|
|
40
|
+
# 5. In CI / pre-push hook:
|
|
38
41
|
infernoflow doc-gate
|
|
39
42
|
```
|
|
40
43
|
|
|
@@ -44,48 +47,61 @@ infernoflow doc-gate
|
|
|
44
47
|
|---|---|
|
|
45
48
|
| `infernoflow init` | Interactive scaffold — creates `inferno/` in your project |
|
|
46
49
|
| `infernoflow status` | At-a-glance health of your contract |
|
|
50
|
+
| `infernoflow suggest` | Generate an AI prompt, apply capability updates |
|
|
47
51
|
| `infernoflow check` | Full validation: contract, capabilities, scenarios, changelog |
|
|
48
52
|
| `infernoflow doc-gate` | Fails if code changed but docs weren't updated |
|
|
49
53
|
|
|
50
54
|
### Options
|
|
51
55
|
|
|
52
56
|
```bash
|
|
53
|
-
infernoflow init --force
|
|
54
|
-
infernoflow init --yes
|
|
55
|
-
infernoflow
|
|
57
|
+
infernoflow init --force # overwrite existing files
|
|
58
|
+
infernoflow init --yes # skip prompts, use defaults
|
|
59
|
+
infernoflow suggest "..." # describe what changed
|
|
60
|
+
infernoflow check --json # machine-readable output for CI
|
|
56
61
|
infernoflow check --skip-doc-gate
|
|
57
62
|
```
|
|
58
63
|
|
|
59
|
-
##
|
|
64
|
+
## `infernoflow suggest` — AI-powered updates
|
|
60
65
|
|
|
61
|
-
|
|
66
|
+
When you add a feature, just describe it in plain language. infernoflow generates a prompt you can paste into **any AI** (Claude, ChatGPT, Copilot, Cursor, etc.), then applies the suggested changes automatically.
|
|
62
67
|
|
|
68
|
+
```bash
|
|
69
|
+
infernoflow suggest "added payment processing and invoice generation"
|
|
63
70
|
```
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
│ └── happy_path.json ← covers all 5 capabilities
|
|
75
|
-
└── CHANGELOG.md
|
|
71
|
+
|
|
72
|
+
**What happens:**
|
|
73
|
+
1. infernoflow reads your current contract state
|
|
74
|
+
2. Generates a structured prompt with full context
|
|
75
|
+
3. You paste it into your AI of choice
|
|
76
|
+
4. Paste the JSON response back
|
|
77
|
+
5. infernoflow previews the changes and asks for confirmation
|
|
78
|
+
6. On approval — updates `contract.json`, `capabilities.json`, `scenarios/`, and `CHANGELOG.md`
|
|
79
|
+
|
|
80
|
+
**Example output:**
|
|
76
81
|
```
|
|
82
|
+
Proposed Changes
|
|
77
83
|
|
|
78
|
-
|
|
84
|
+
Summary: Added payment processing and invoice generation functionality.
|
|
79
85
|
|
|
80
|
-
|
|
81
|
-
|
|
86
|
+
+ New capabilities:
|
|
87
|
+
ProcessPayment — Process Payment
|
|
88
|
+
GenerateInvoice — Generate Invoice
|
|
89
|
+
|
|
90
|
+
~ Scenario updates:
|
|
91
|
+
[update] happy_path.json
|
|
92
|
+
|
|
93
|
+
📝 Changelog: - Add payment processing and invoice generation capabilities.
|
|
94
|
+
|
|
95
|
+
Apply these changes? (y/n)
|
|
82
96
|
```
|
|
83
97
|
|
|
98
|
+
Works with any AI — Claude, ChatGPT, GitHub Copilot, Cursor, or your own setup.
|
|
99
|
+
|
|
84
100
|
## Why infernoflow?
|
|
85
101
|
|
|
86
102
|
**The problem:** AI-assisted development moves fast. Code changes daily. But what does the system *actually do*? What changed? What's covered?
|
|
87
103
|
|
|
88
|
-
**The metaphor:** A forge (כיבשן). Metal becomes liquid — flexible, shapeable. The forge is the controlled environment where that change happens safely, with molds (contracts) and tempering (
|
|
104
|
+
**The metaphor:** A forge (כיבשן). Metal becomes liquid — flexible, shapeable. The forge is the controlled environment where that change happens safely, with molds (contracts) and tempering (validation).
|
|
89
105
|
|
|
90
106
|
**The principle:** Liquid where you want flexibility. Solid where you need safety.
|
|
91
107
|
|
package/bin/infernoflow.mjs
CHANGED
|
@@ -1,60 +1,50 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import { bold, gray, cyan, red } from "../lib/ui/output.mjs";
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
import { bold, gray, cyan, red, orange } from "../lib/ui/output.mjs";
|
|
5
|
-
|
|
6
|
-
const VERSION = "0.1.0";
|
|
4
|
+
const VERSION = "0.5.0";
|
|
7
5
|
|
|
8
6
|
const HELP = `
|
|
9
7
|
${bold("🔥 infernoflow")} ${gray("v" + VERSION)}
|
|
10
|
-
${gray("The forge for liquid code")}
|
|
8
|
+
${gray("The forge for liquid code — keep every AI session in sync")}
|
|
11
9
|
|
|
12
10
|
${bold("Usage:")}
|
|
13
11
|
infernoflow <command> [options]
|
|
14
12
|
|
|
15
13
|
${bold("Commands:")}
|
|
16
|
-
init Scaffold inferno/ in your project
|
|
14
|
+
init Scaffold inferno/ in your project
|
|
17
15
|
check Validate contract, capabilities, scenarios, changelog
|
|
18
16
|
status Show contract health at a glance
|
|
19
17
|
doc-gate Fail if code changed but docs were not updated
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
${bold("
|
|
31
|
-
${
|
|
32
|
-
${
|
|
33
|
-
${
|
|
34
|
-
${
|
|
35
|
-
${
|
|
36
|
-
|
|
37
|
-
${bold("CI example:")}
|
|
38
|
-
${gray("# In GitHub Actions:")}
|
|
39
|
-
${gray("- run: npx infernoflow check --json")}
|
|
40
|
-
${gray(" env:")}
|
|
41
|
-
${gray(" BASE_SHA: ${{ github.event.pull_request.base.sha }}")}
|
|
42
|
-
${gray(" HEAD_SHA: ${{ github.event.pull_request.head.sha }}")}
|
|
18
|
+
suggest Generate AI prompt + apply capability updates
|
|
19
|
+
context Generate AI-ready context for new sessions
|
|
20
|
+
|
|
21
|
+
${bold("context options:")}
|
|
22
|
+
--intent "..." What you plan to build next
|
|
23
|
+
--working "..." What you are building right now
|
|
24
|
+
--decision "..." Record a decision or note
|
|
25
|
+
--show Print context without writing file
|
|
26
|
+
--reset Clear all stored state
|
|
27
|
+
|
|
28
|
+
${bold("Typical workflow:")}
|
|
29
|
+
${gray('1. infernoflow context --intent "what I want to build"')}
|
|
30
|
+
${gray("2. [paste inferno/CONTEXT.md into Claude / Cursor / Copilot]")}
|
|
31
|
+
${gray("3. [build the feature]")}
|
|
32
|
+
${gray('4. infernoflow suggest "what I built"')}
|
|
33
|
+
${gray("5. infernoflow check")}
|
|
43
34
|
`;
|
|
44
35
|
|
|
45
|
-
const [
|
|
36
|
+
const [, , cmd, ...rest] = process.argv;
|
|
46
37
|
|
|
47
38
|
if (!cmd || cmd === "--help" || cmd === "-h") {
|
|
48
39
|
console.log(HELP);
|
|
49
40
|
process.exit(0);
|
|
50
41
|
}
|
|
51
|
-
|
|
52
42
|
if (cmd === "--version" || cmd === "-v") {
|
|
53
43
|
console.log(VERSION);
|
|
54
44
|
process.exit(0);
|
|
55
45
|
}
|
|
56
46
|
|
|
57
|
-
const commands = ["init", "check", "status", "doc-gate"];
|
|
47
|
+
const commands = ["init", "check", "status", "doc-gate", "suggest", "context"];
|
|
58
48
|
|
|
59
49
|
if (!commands.includes(cmd)) {
|
|
60
50
|
console.error(red(`\nUnknown command: ${cmd}`));
|
|
@@ -67,22 +57,50 @@ const args = [cmd, ...rest];
|
|
|
67
57
|
switch (cmd) {
|
|
68
58
|
case "init":
|
|
69
59
|
import("../lib/commands/init.mjs")
|
|
70
|
-
.then(m => m.initCommand(args))
|
|
71
|
-
.catch(err => {
|
|
60
|
+
.then((m) => m.initCommand(args))
|
|
61
|
+
.catch((err) => {
|
|
62
|
+
console.error(red("\nError: ") + err.message);
|
|
63
|
+
process.exit(1);
|
|
64
|
+
});
|
|
72
65
|
break;
|
|
73
66
|
case "check":
|
|
74
67
|
import("../lib/commands/check.mjs")
|
|
75
|
-
.then(m => m.checkCommand(args))
|
|
76
|
-
.catch(err => {
|
|
68
|
+
.then((m) => m.checkCommand(args))
|
|
69
|
+
.catch((err) => {
|
|
70
|
+
console.error(red("\nError: ") + err.message);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
});
|
|
77
73
|
break;
|
|
78
74
|
case "status":
|
|
79
75
|
import("../lib/commands/status.mjs")
|
|
80
|
-
.then(m => m.statusCommand(args))
|
|
81
|
-
.catch(err => {
|
|
76
|
+
.then((m) => m.statusCommand(args))
|
|
77
|
+
.catch((err) => {
|
|
78
|
+
console.error(red("\nError: ") + err.message);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
});
|
|
81
|
+
break;
|
|
82
|
+
case "suggest":
|
|
83
|
+
import("../lib/commands/suggest.mjs")
|
|
84
|
+
.then((m) => m.suggestCommand(args))
|
|
85
|
+
.catch((err) => {
|
|
86
|
+
console.error(red("\nError: ") + err.message);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
});
|
|
89
|
+
break;
|
|
90
|
+
case "context":
|
|
91
|
+
import("../lib/commands/context.mjs")
|
|
92
|
+
.then((m) => m.contextCommand(args))
|
|
93
|
+
.catch((err) => {
|
|
94
|
+
console.error(red("\nError: ") + err.message);
|
|
95
|
+
process.exit(1);
|
|
96
|
+
});
|
|
82
97
|
break;
|
|
83
98
|
case "doc-gate":
|
|
84
99
|
import("../lib/commands/docGate.mjs")
|
|
85
|
-
.then(m => m.docGateCommand())
|
|
86
|
-
.catch(err => {
|
|
100
|
+
.then((m) => m.docGateCommand())
|
|
101
|
+
.catch((err) => {
|
|
102
|
+
console.error(red("\nError: ") + err.message);
|
|
103
|
+
process.exit(1);
|
|
104
|
+
});
|
|
87
105
|
break;
|
|
88
106
|
}
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { bold, gray, cyan, red, green, yellow } from "../ui/output.mjs";
|
|
4
|
+
|
|
5
|
+
const INFERNO_DIR = "inferno";
|
|
6
|
+
const CONTEXT_FILE = path.join(INFERNO_DIR, "CONTEXT.md");
|
|
7
|
+
const STATE_FILE = path.join(INFERNO_DIR, "context-state.json");
|
|
8
|
+
|
|
9
|
+
function readJSON(filePath) {
|
|
10
|
+
try { return JSON.parse(fs.readFileSync(filePath, "utf8")); }
|
|
11
|
+
catch { return null; }
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
function readFile(filePath) {
|
|
15
|
+
try { return fs.readFileSync(filePath, "utf8"); }
|
|
16
|
+
catch { return null; }
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function parseRecentChangelog(changelogContent, maxEntries = 3) {
|
|
20
|
+
if (!changelogContent) return [];
|
|
21
|
+
const lines = changelogContent.split("\n");
|
|
22
|
+
const entries = [];
|
|
23
|
+
let current = null;
|
|
24
|
+
|
|
25
|
+
for (const line of lines) {
|
|
26
|
+
if (line.startsWith("## ")) {
|
|
27
|
+
if (current && entries.length < maxEntries) entries.push(current);
|
|
28
|
+
if (entries.length >= maxEntries) break;
|
|
29
|
+
current = { title: line.replace("## ", "").trim(), items: [] };
|
|
30
|
+
} else if (current && line.startsWith("- ")) {
|
|
31
|
+
current.items.push(line.replace("- ", "").trim());
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
if (current && entries.length < maxEntries) entries.push(current);
|
|
35
|
+
return entries.filter(e => e.items.length > 0);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function loadState() {
|
|
39
|
+
const raw = readFile(STATE_FILE);
|
|
40
|
+
if (!raw) return {};
|
|
41
|
+
try { return JSON.parse(raw); } catch { return {}; }
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function saveState(state) {
|
|
45
|
+
fs.writeFileSync(STATE_FILE, JSON.stringify(state, null, 2), "utf8");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function formatDate(iso) {
|
|
49
|
+
if (!iso) return "unknown";
|
|
50
|
+
return new Date(iso).toLocaleDateString("en-GB", {
|
|
51
|
+
day: "2-digit", month: "short", year: "numeric"
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export async function contextCommand(args) {
|
|
56
|
+
const getFlagValue = (f) => {
|
|
57
|
+
const i = args.indexOf(f);
|
|
58
|
+
return i !== -1 && args[i + 1] ? args[i + 1] : null;
|
|
59
|
+
};
|
|
60
|
+
const hasFlag = (f) => args.includes(f);
|
|
61
|
+
|
|
62
|
+
const intent = getFlagValue("--intent") || getFlagValue("-i");
|
|
63
|
+
const working = getFlagValue("--working") || getFlagValue("-w");
|
|
64
|
+
const decision = getFlagValue("--decision") || getFlagValue("-d");
|
|
65
|
+
const showOnly = hasFlag("--show") || hasFlag("-s");
|
|
66
|
+
const resetState = hasFlag("--reset");
|
|
67
|
+
|
|
68
|
+
console.log(`\n ${bold("🔥 infernoflow — context")}`);
|
|
69
|
+
console.log(` ${"─".repeat(50)}\n`);
|
|
70
|
+
|
|
71
|
+
if (!fs.existsSync(INFERNO_DIR)) {
|
|
72
|
+
console.error(red(" ✘ inferno/ not found"));
|
|
73
|
+
console.error(gray(" → Run: infernoflow init\n"));
|
|
74
|
+
process.exit(1);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const contract = readJSON(path.join(INFERNO_DIR, "contract.json"));
|
|
78
|
+
const capabilities = readJSON(path.join(INFERNO_DIR, "capabilities.json"));
|
|
79
|
+
const changelog = readFile(path.join(INFERNO_DIR, "CHANGELOG.md"));
|
|
80
|
+
|
|
81
|
+
if (!contract || !capabilities) {
|
|
82
|
+
console.error(red(" ✘ Missing contract.json or capabilities.json"));
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
let state = loadState();
|
|
87
|
+
if (resetState) { state = {}; console.log(yellow(" ⚠ State reset\n")); }
|
|
88
|
+
|
|
89
|
+
if (intent) { state.intent = intent; state.intentUpdated = new Date().toISOString(); console.log(green(` ✔ Intent saved: "${intent}"`)); }
|
|
90
|
+
if (working) { state.working = working; state.workingUpdated = new Date().toISOString(); console.log(green(` ✔ Working on: "${working}"`)); }
|
|
91
|
+
if (decision) {
|
|
92
|
+
if (!state.decisions) state.decisions = [];
|
|
93
|
+
state.decisions.push({ text: decision, date: new Date().toISOString() });
|
|
94
|
+
console.log(green(` ✔ Decision recorded: "${decision}"`));
|
|
95
|
+
}
|
|
96
|
+
if (intent || working || decision) saveState(state);
|
|
97
|
+
|
|
98
|
+
const capList = capabilities.capabilities || [];
|
|
99
|
+
const contractCaps = contract.capabilities || [];
|
|
100
|
+
const allInSync = capList.length === contractCaps.length;
|
|
101
|
+
const recentChanges = parseRecentChangelog(changelog, 3);
|
|
102
|
+
|
|
103
|
+
const now = new Date().toLocaleDateString("en-GB", {
|
|
104
|
+
day: "2-digit", month: "short", year: "numeric"
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const capLines = capList.map(c => `- **${c.id}** — ${c.title}`).join("\n");
|
|
108
|
+
|
|
109
|
+
const changelogLines = recentChanges.length > 0
|
|
110
|
+
? recentChanges.map(e => `### ${e.title}\n${e.items.map(i => ` - ${i}`).join("\n")}`).join("\n\n")
|
|
111
|
+
: "_No recent changes recorded_";
|
|
112
|
+
|
|
113
|
+
const intentLine = state.intent
|
|
114
|
+
? `${state.intent} _(updated: ${formatDate(state.intentUpdated)})_`
|
|
115
|
+
: "_Not set — run: `infernoflow context --intent \"what I want to do next\"`_";
|
|
116
|
+
|
|
117
|
+
const workingLine = state.working
|
|
118
|
+
? `${state.working} _(updated: ${formatDate(state.workingUpdated)})_`
|
|
119
|
+
: "_Not set — run: `infernoflow context --working \"what I am building now\"`_";
|
|
120
|
+
|
|
121
|
+
const decisionsLines = state.decisions?.length > 0
|
|
122
|
+
? state.decisions.slice(-5).map(d => `- ${d.text} _(${formatDate(d.date)})_`).join("\n")
|
|
123
|
+
: "_No decisions recorded — run: `infernoflow context --decision \"why I chose X\"`_";
|
|
124
|
+
|
|
125
|
+
const syncBadge = allInSync ? "✓ validated" : "⚠ out of sync — run infernoflow check";
|
|
126
|
+
const version = String(contract.policyVersion).replace(/^v/i, "");
|
|
127
|
+
|
|
128
|
+
const contextMd = `# Project Context — ${contract.policyId} v${version}
|
|
129
|
+
> Generated by infernoflow | ${now} | ${syncBadge}
|
|
130
|
+
|
|
131
|
+
---
|
|
132
|
+
|
|
133
|
+
## What this system does
|
|
134
|
+
|
|
135
|
+
${capLines}
|
|
136
|
+
|
|
137
|
+
---
|
|
138
|
+
|
|
139
|
+
## Recent changes
|
|
140
|
+
|
|
141
|
+
${changelogLines}
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Current state
|
|
146
|
+
|
|
147
|
+
- **Capabilities declared:** ${capList.length}
|
|
148
|
+
- **Contract version:** v${version}
|
|
149
|
+
- **Sync status:** ${syncBadge}
|
|
150
|
+
|
|
151
|
+
---
|
|
152
|
+
|
|
153
|
+
## What I am working on right now
|
|
154
|
+
|
|
155
|
+
${workingLine}
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Intent — what I want to build next
|
|
160
|
+
|
|
161
|
+
${intentLine}
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Decisions & notes
|
|
166
|
+
|
|
167
|
+
${decisionsLines}
|
|
168
|
+
|
|
169
|
+
---
|
|
170
|
+
_Paste this block at the start of any new AI session
|
package/package.json
CHANGED
package/lib/infernoflow.mjs
DELETED
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { parseArgs } from "node:util";
|
|
4
|
-
import { bold, gray, cyan, red, orange } from "../lib/ui/output.mjs";
|
|
5
|
-
|
|
6
|
-
const VERSION = "0.1.0";
|
|
7
|
-
|
|
8
|
-
const HELP = `
|
|
9
|
-
${bold("🔥 infernoflow")} ${gray("v" + VERSION)}
|
|
10
|
-
${gray("The forge for liquid code")}
|
|
11
|
-
|
|
12
|
-
${bold("Usage:")}
|
|
13
|
-
infernoflow <command> [options]
|
|
14
|
-
|
|
15
|
-
${bold("Commands:")}
|
|
16
|
-
init Scaffold inferno/ in your project (interactive)
|
|
17
|
-
check Validate contract, capabilities, scenarios, changelog
|
|
18
|
-
status Show contract health at a glance
|
|
19
|
-
doc-gate Fail if code changed but docs were not updated
|
|
20
|
-
suggest Generate AI prompt + apply capability updates
|
|
21
|
-
|
|
22
|
-
${bold("Options:")}
|
|
23
|
-
init:
|
|
24
|
-
--force, -f Overwrite existing files
|
|
25
|
-
--yes, -y Skip prompts, use defaults
|
|
26
|
-
|
|
27
|
-
check:
|
|
28
|
-
--skip-doc-gate Skip the git doc-gate check
|
|
29
|
-
--json Machine-readable JSON output (for CI)
|
|
30
|
-
|
|
31
|
-
${bold("Examples:")}
|
|
32
|
-
${cyan("npx infernoflow init")}
|
|
33
|
-
${cyan("infernoflow status")}
|
|
34
|
-
${cyan("infernoflow check")}
|
|
35
|
-
${cyan("infernoflow check --json")}
|
|
36
|
-
${cyan("infernoflow doc-gate")}
|
|
37
|
-
|
|
38
|
-
${bold("CI example:")}
|
|
39
|
-
${gray("# In GitHub Actions:")}
|
|
40
|
-
${gray("- run: npx infernoflow check --json")}
|
|
41
|
-
${gray(" env:")}
|
|
42
|
-
${gray(" BASE_SHA: ${{ github.event.pull_request.base.sha }}")}
|
|
43
|
-
${gray(" HEAD_SHA: ${{ github.event.pull_request.head.sha }}")}
|
|
44
|
-
`;
|
|
45
|
-
|
|
46
|
-
const [,, cmd, ...rest] = process.argv;
|
|
47
|
-
|
|
48
|
-
if (!cmd || cmd === "--help" || cmd === "-h") {
|
|
49
|
-
console.log(HELP);
|
|
50
|
-
process.exit(0);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (cmd === "--version" || cmd === "-v") {
|
|
54
|
-
console.log(VERSION);
|
|
55
|
-
process.exit(0);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const commands = ["init", "check", "status", "doc-gate", "suggest"];
|
|
59
|
-
|
|
60
|
-
if (!commands.includes(cmd)) {
|
|
61
|
-
console.error(red(`\nUnknown command: ${cmd}`));
|
|
62
|
-
console.error(gray("Run: infernoflow --help\n"));
|
|
63
|
-
process.exit(1);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
const args = [cmd, ...rest];
|
|
67
|
-
|
|
68
|
-
switch (cmd) {
|
|
69
|
-
case "init":
|
|
70
|
-
import("../lib/commands/init.mjs")
|
|
71
|
-
.then(m => m.initCommand(args))
|
|
72
|
-
.catch(err => { console.error(red("\nError: ") + err.message); process.exit(1); });
|
|
73
|
-
break;
|
|
74
|
-
case "check":
|
|
75
|
-
import("../lib/commands/check.mjs")
|
|
76
|
-
.then(m => m.checkCommand(args))
|
|
77
|
-
.catch(err => { console.error(red("\nError: ") + err.message); process.exit(1); });
|
|
78
|
-
break;
|
|
79
|
-
case "status":
|
|
80
|
-
import("../lib/commands/status.mjs")
|
|
81
|
-
.then(m => m.statusCommand(args))
|
|
82
|
-
.catch(err => { console.error(red("\nError: ") + err.message); process.exit(1); });
|
|
83
|
-
break;
|
|
84
|
-
case "suggest":
|
|
85
|
-
import("../lib/commands/suggest.mjs")
|
|
86
|
-
.then(m => m.suggestCommand(args))
|
|
87
|
-
.catch(err => { console.error(red("\nError: ") + err.message); process.exit(1); });
|
|
88
|
-
break;
|
|
89
|
-
case "doc-gate":
|
|
90
|
-
import("../lib/commands/docGate.mjs")
|
|
91
|
-
.then(m => m.docGateCommand())
|
|
92
|
-
.catch(err => { console.error(red("\nError: ") + err.message); process.exit(1); });
|
|
93
|
-
break;
|
|
94
|
-
}
|