devfix-cli 1.0.2 → 1.0.3
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 +9 -6
- package/package.json +1 -1
- package/src/utils/run.js +78 -70
package/README.md
CHANGED
|
@@ -83,26 +83,29 @@ devfix logout
|
|
|
83
83
|
```bash
|
|
84
84
|
devfix run <Command> --context
|
|
85
85
|
```
|
|
86
|
+
**for example : devfix run kubectl get pods --context**
|
|
86
87
|
---
|
|
87
|
-
|
|
88
|
+
|
|
88
89
|
---
|
|
89
90
|
|
|
90
91
|
2. Stack Command -> Force stack type
|
|
91
92
|
```bash
|
|
92
93
|
devfix run <Command> --stack <StackName>
|
|
93
94
|
```
|
|
94
|
-
|
|
95
|
-
for example : devfix run kubectl get pods --stack kubernetes
|
|
95
|
+
**for example : devfix run kubectl get pods --stack kubernetes**
|
|
96
96
|
---
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
3. Model Command -> OpenRouter model override
|
|
99
101
|
|
|
100
102
|
```bash
|
|
101
103
|
devfix run <Command> --model <ModelName>
|
|
102
104
|
```
|
|
105
|
+
**for example : devfix run kubectl get pods --model openai/gpt-4o-mini**
|
|
103
106
|
---
|
|
104
|
-
|
|
105
|
-
|
|
107
|
+
|
|
108
|
+
|
|
106
109
|
|
|
107
110
|
|
|
108
111
|
|
package/package.json
CHANGED
package/src/utils/run.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
|
|
1
2
|
import chalk from "chalk";
|
|
2
3
|
import boxen from "boxen";
|
|
3
4
|
import inquirer from "inquirer";
|
|
@@ -44,6 +45,9 @@ export async function runCommand(cmdArgs, options) {
|
|
|
44
45
|
const args = cmdArgs.slice(1);
|
|
45
46
|
const fullCmd = `${command} ${args.join(" ")}`.trim();
|
|
46
47
|
|
|
48
|
+
// ✅ Prevent duplicate prompts + duplicate AI calls
|
|
49
|
+
let handled = false;
|
|
50
|
+
|
|
47
51
|
console.log(
|
|
48
52
|
boxen(
|
|
49
53
|
`${chalk.bold.cyan("▶ DevFix Run")}\n\n${chalk.white("Command:")} ${chalk.yellow(fullCmd)}\n${
|
|
@@ -53,7 +57,7 @@ export async function runCommand(cmdArgs, options) {
|
|
|
53
57
|
)
|
|
54
58
|
);
|
|
55
59
|
|
|
56
|
-
// ✅ No shell=true (removes
|
|
60
|
+
// ✅ No shell=true (removes security warning)
|
|
57
61
|
const child = spawn(command, args, { stdio: ["inherit", "pipe", "pipe"] });
|
|
58
62
|
|
|
59
63
|
let stdout = "";
|
|
@@ -71,7 +75,80 @@ export async function runCommand(cmdArgs, options) {
|
|
|
71
75
|
process.stderr.write(text);
|
|
72
76
|
});
|
|
73
77
|
|
|
78
|
+
// ✅ Handle "command not found"
|
|
79
|
+
child.on("error", async (err) => {
|
|
80
|
+
if (handled) return;
|
|
81
|
+
handled = true;
|
|
82
|
+
|
|
83
|
+
if (err.code === "ENOENT") {
|
|
84
|
+
console.log(chalk.red(`\n❌ Command not found: ${command}\n`));
|
|
85
|
+
console.log(chalk.gray("Tip: Did you mean `kubectl`?\n"));
|
|
86
|
+
|
|
87
|
+
const { confirm } = await inquirer.prompt([
|
|
88
|
+
{
|
|
89
|
+
name: "confirm",
|
|
90
|
+
type: "confirm",
|
|
91
|
+
message: "Send this error to DevFix AI for a fix?",
|
|
92
|
+
default: true,
|
|
93
|
+
},
|
|
94
|
+
]);
|
|
95
|
+
|
|
96
|
+
if (!confirm) {
|
|
97
|
+
console.log(chalk.yellow("\n❌ Not sent to AI.\n"));
|
|
98
|
+
process.exit(1);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const errorText = `Command not found: ${command}\nTried to run: ${fullCmd}`;
|
|
102
|
+
const context = options.context ? collectContext() : {};
|
|
103
|
+
const stack = options.stack || detectStack(errorText);
|
|
104
|
+
const usedModel = options.model || "openai/gpt-4o-mini";
|
|
105
|
+
|
|
106
|
+
const spinner = ora("DevFix AI is analyzing...").start();
|
|
107
|
+
|
|
108
|
+
try {
|
|
109
|
+
const prompt = buildPrompt({
|
|
110
|
+
stack,
|
|
111
|
+
input: errorText,
|
|
112
|
+
context,
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
const answer = await askAI({
|
|
116
|
+
apiKey,
|
|
117
|
+
model: usedModel,
|
|
118
|
+
prompt,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
spinner.succeed("Analysis complete");
|
|
122
|
+
|
|
123
|
+
console.log(
|
|
124
|
+
boxen(chalk.bold.green("✅ DevFix Suggested Fix"), {
|
|
125
|
+
padding: 1,
|
|
126
|
+
borderStyle: "round",
|
|
127
|
+
})
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
console.log(marked(answer));
|
|
131
|
+
console.log();
|
|
132
|
+
} catch (e) {
|
|
133
|
+
spinner.fail("AI request failed");
|
|
134
|
+
console.log(chalk.red("\n❌ Error:\n"));
|
|
135
|
+
console.log(e?.response?.data || e.message);
|
|
136
|
+
console.log();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
process.exit(1);
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
console.log(chalk.red("\n❌ Failed to run command:\n"));
|
|
143
|
+
console.log(err.message);
|
|
144
|
+
process.exit(1);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// ✅ Handle normal command exit
|
|
74
148
|
child.on("close", async (code) => {
|
|
149
|
+
if (handled) return;
|
|
150
|
+
handled = true;
|
|
151
|
+
|
|
75
152
|
if (code === 0) {
|
|
76
153
|
console.log(chalk.green("\n✅ Command succeeded.\n"));
|
|
77
154
|
return;
|
|
@@ -114,7 +191,6 @@ export async function runCommand(cmdArgs, options) {
|
|
|
114
191
|
const stack = options.stack || detectStack(errorText);
|
|
115
192
|
const usedModel = options.model || "openai/gpt-4o-mini";
|
|
116
193
|
|
|
117
|
-
// 🔥 Send a better bundle (so AI never asks useless questions)
|
|
118
194
|
const errorBundle = `
|
|
119
195
|
Command:
|
|
120
196
|
${fullCmd}
|
|
@@ -159,7 +235,6 @@ ${errorText}
|
|
|
159
235
|
})
|
|
160
236
|
);
|
|
161
237
|
|
|
162
|
-
// ✅ Pretty output (markdown rendered)
|
|
163
238
|
console.log(marked(answer));
|
|
164
239
|
console.log();
|
|
165
240
|
} catch (err) {
|
|
@@ -170,71 +245,4 @@ ${errorText}
|
|
|
170
245
|
console.log();
|
|
171
246
|
}
|
|
172
247
|
});
|
|
173
|
-
child.on("error", async (err) => {
|
|
174
|
-
if (err.code === "ENOENT") {
|
|
175
|
-
console.log(chalk.red(`\n❌ Command not found: ${command}\n`));
|
|
176
|
-
console.log(chalk.gray("Tip: Did you mean `kubectl`?\n"));
|
|
177
|
-
|
|
178
|
-
const { confirm } = await inquirer.prompt([
|
|
179
|
-
{
|
|
180
|
-
name: "confirm",
|
|
181
|
-
type: "confirm",
|
|
182
|
-
message: "Send this error to DevFix AI for a fix?",
|
|
183
|
-
default: true,
|
|
184
|
-
},
|
|
185
|
-
]);
|
|
186
|
-
|
|
187
|
-
if (!confirm) {
|
|
188
|
-
console.log(chalk.yellow("\n❌ Not sent to AI.\n"));
|
|
189
|
-
process.exit(1);
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
const errorText = `Command not found: ${command}\nTried to run: ${fullCmd}`;
|
|
193
|
-
const context = options.context ? collectContext() : {};
|
|
194
|
-
const stack = options.stack || detectStack(errorText);
|
|
195
|
-
const usedModel = options.model || "openai/gpt-4o-mini";
|
|
196
|
-
|
|
197
|
-
const spinner = ora("DevFix AI is analyzing...").start();
|
|
198
|
-
|
|
199
|
-
try {
|
|
200
|
-
const prompt = buildPrompt({
|
|
201
|
-
stack,
|
|
202
|
-
input: errorText,
|
|
203
|
-
context,
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
const answer = await askAI({
|
|
207
|
-
apiKey,
|
|
208
|
-
model: usedModel,
|
|
209
|
-
prompt,
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
spinner.succeed("Analysis complete");
|
|
213
|
-
|
|
214
|
-
console.log(
|
|
215
|
-
boxen(chalk.bold.green("✅ DevFix Suggested Fix"), {
|
|
216
|
-
padding: 1,
|
|
217
|
-
borderStyle: "round",
|
|
218
|
-
})
|
|
219
|
-
);
|
|
220
|
-
|
|
221
|
-
console.log(marked(answer));
|
|
222
|
-
console.log();
|
|
223
|
-
} catch (e) {
|
|
224
|
-
spinner.fail("AI request failed");
|
|
225
|
-
console.log(chalk.red("\n❌ Error:\n"));
|
|
226
|
-
console.log(e?.response?.data || e.message);
|
|
227
|
-
console.log();
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
process.exit(1);
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
console.log(chalk.red("\n❌ Failed to run command:\n"));
|
|
234
|
-
console.log(err.message);
|
|
235
|
-
process.exit(1);
|
|
236
|
-
});
|
|
237
|
-
|
|
238
248
|
}
|
|
239
|
-
|
|
240
|
-
|