automata-cli 0.1.0-009-codex-flag-implement-next.75 → 0.1.0-010-sonarcloud-prompts-execute.79
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/dist/index.js +214 -25
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
|
-
import { Command as
|
|
4
|
+
import { Command as Command6 } from "commander";
|
|
5
5
|
|
|
6
6
|
// src/version.ts
|
|
7
7
|
import { readFileSync } from "fs";
|
|
@@ -23,6 +23,7 @@ import { Box, Text, useInput, useApp } from "ink";
|
|
|
23
23
|
// src/config/configStore.ts
|
|
24
24
|
import { readFileSync as readFileSync2, writeFileSync, mkdirSync } from "fs";
|
|
25
25
|
import { join } from "path";
|
|
26
|
+
var DEFAULT_SONAR_PROMPT = "You are an expert software engineer. You have been given the URL of a SonarCloud analysis for this pull request. Please visit the SonarCloud analysis URL provided and fix all new issues reported. Focus on code smells, bugs, and vulnerabilities flagged as new in this PR. Make targeted, minimal changes that resolve each issue without altering unrelated code.";
|
|
26
27
|
var CONFIG_DIR = ".automata";
|
|
27
28
|
var CONFIG_FILE = "config.json";
|
|
28
29
|
function configPath() {
|
|
@@ -53,22 +54,42 @@ var TECHNIQUE_OPTIONS = [
|
|
|
53
54
|
{ label: "By Assignee", value: "assignee" },
|
|
54
55
|
{ label: "By Title Contains", value: "title-contains" }
|
|
55
56
|
];
|
|
57
|
+
var MAIN_MENU_OPTIONS = ["Remote / Mode", "Implement-Next", "Prompts"];
|
|
56
58
|
function ConfigWizard() {
|
|
57
59
|
const existing = readConfig();
|
|
58
60
|
const initialRemoteIndex = REMOTE_OPTIONS.findIndex((o) => o.value === existing.remoteType);
|
|
59
61
|
const initialTechIndex = TECHNIQUE_OPTIONS.findIndex((o) => o.value === existing.issueDiscoveryTechnique);
|
|
60
|
-
const [screen, setScreen] = useState("
|
|
62
|
+
const [screen, setScreen] = useState("main");
|
|
63
|
+
const [mainMenuIndex, setMainMenuIndex] = useState(0);
|
|
61
64
|
const [selectedRemoteIndex, setSelectedRemoteIndex] = useState(initialRemoteIndex >= 0 ? initialRemoteIndex : 0);
|
|
62
65
|
const [selectedTechIndex, setSelectedTechIndex] = useState(initialTechIndex >= 0 ? initialTechIndex : 0);
|
|
63
66
|
const [discoveryValue, setDiscoveryValue] = useState(existing.issueDiscoveryValue ?? "");
|
|
64
67
|
const [systemPrompt, setSystemPrompt] = useState(existing.claudeSystemPrompt ?? "");
|
|
68
|
+
const [sonarPrompt, setSonarPrompt] = useState(existing.prompts?.sonar ?? DEFAULT_SONAR_PROMPT);
|
|
65
69
|
const [pendingRemote, setPendingRemote] = useState(existing.remoteType ?? "gh");
|
|
66
70
|
const [pendingTechnique, setPendingTechnique] = useState(
|
|
67
71
|
existing.issueDiscoveryTechnique ?? "label"
|
|
68
72
|
);
|
|
69
73
|
const { exit } = useApp();
|
|
70
74
|
useInput((input, key) => {
|
|
71
|
-
if (screen === "
|
|
75
|
+
if (screen === "main") {
|
|
76
|
+
if (key.upArrow) {
|
|
77
|
+
setMainMenuIndex((i) => i > 0 ? i - 1 : MAIN_MENU_OPTIONS.length - 1);
|
|
78
|
+
} else if (key.downArrow) {
|
|
79
|
+
setMainMenuIndex((i) => i < MAIN_MENU_OPTIONS.length - 1 ? i + 1 : 0);
|
|
80
|
+
} else if (key.return) {
|
|
81
|
+
const chosen = MAIN_MENU_OPTIONS[mainMenuIndex];
|
|
82
|
+
if (chosen === "Remote / Mode") {
|
|
83
|
+
setScreen("remote");
|
|
84
|
+
} else if (chosen === "Implement-Next") {
|
|
85
|
+
setScreen("technique");
|
|
86
|
+
} else {
|
|
87
|
+
setScreen("prompts-menu");
|
|
88
|
+
}
|
|
89
|
+
} else if (key.escape || key.ctrl && input === "c") {
|
|
90
|
+
exit();
|
|
91
|
+
}
|
|
92
|
+
} else if (screen === "remote") {
|
|
72
93
|
if (key.upArrow) {
|
|
73
94
|
setSelectedRemoteIndex((i) => i > 0 ? i - 1 : REMOTE_OPTIONS.length - 1);
|
|
74
95
|
} else if (key.downArrow) {
|
|
@@ -82,7 +103,9 @@ function ConfigWizard() {
|
|
|
82
103
|
writeConfig({ ...existing, remoteType: chosen.value });
|
|
83
104
|
exit();
|
|
84
105
|
}
|
|
85
|
-
} else if (key.escape
|
|
106
|
+
} else if (key.escape) {
|
|
107
|
+
setScreen("main");
|
|
108
|
+
} else if (key.ctrl && input === "c") {
|
|
86
109
|
exit();
|
|
87
110
|
}
|
|
88
111
|
} else if (screen === "technique") {
|
|
@@ -94,7 +117,9 @@ function ConfigWizard() {
|
|
|
94
117
|
const chosen = TECHNIQUE_OPTIONS[selectedTechIndex];
|
|
95
118
|
setPendingTechnique(chosen.value);
|
|
96
119
|
setScreen("value");
|
|
97
|
-
} else if (key.escape
|
|
120
|
+
} else if (key.escape) {
|
|
121
|
+
setScreen("main");
|
|
122
|
+
} else if (key.ctrl && input === "c") {
|
|
98
123
|
exit();
|
|
99
124
|
}
|
|
100
125
|
} else if (screen === "value") {
|
|
@@ -102,7 +127,9 @@ function ConfigWizard() {
|
|
|
102
127
|
setScreen("system-prompt");
|
|
103
128
|
} else if (key.backspace || key.delete) {
|
|
104
129
|
setDiscoveryValue((v) => v.slice(0, -1));
|
|
105
|
-
} else if (key.escape
|
|
130
|
+
} else if (key.escape) {
|
|
131
|
+
setScreen("main");
|
|
132
|
+
} else if (key.ctrl && input === "c") {
|
|
106
133
|
exit();
|
|
107
134
|
} else if (input && !key.ctrl && !key.meta) {
|
|
108
135
|
setDiscoveryValue((v) => v + input);
|
|
@@ -119,29 +146,67 @@ function ConfigWizard() {
|
|
|
119
146
|
exit();
|
|
120
147
|
} else if (key.backspace || key.delete) {
|
|
121
148
|
setSystemPrompt((v) => v.slice(0, -1));
|
|
122
|
-
} else if (key.escape
|
|
149
|
+
} else if (key.escape) {
|
|
150
|
+
setScreen("main");
|
|
151
|
+
} else if (key.ctrl && input === "c") {
|
|
123
152
|
exit();
|
|
124
153
|
} else if (input && !key.ctrl && !key.meta) {
|
|
125
154
|
setSystemPrompt((v) => v + input);
|
|
126
155
|
}
|
|
156
|
+
} else if (screen === "prompts-menu") {
|
|
157
|
+
if (key.return) {
|
|
158
|
+
setScreen("sonar-prompt");
|
|
159
|
+
} else if (key.escape) {
|
|
160
|
+
setScreen("main");
|
|
161
|
+
} else if (key.ctrl && input === "c") {
|
|
162
|
+
exit();
|
|
163
|
+
}
|
|
164
|
+
} else if (screen === "sonar-prompt") {
|
|
165
|
+
if (key.return) {
|
|
166
|
+
writeConfig({
|
|
167
|
+
...existing,
|
|
168
|
+
prompts: { ...existing.prompts, sonar: sonarPrompt || void 0 }
|
|
169
|
+
});
|
|
170
|
+
exit();
|
|
171
|
+
} else if (key.backspace || key.delete) {
|
|
172
|
+
setSonarPrompt((v) => v.slice(0, -1));
|
|
173
|
+
} else if (key.escape) {
|
|
174
|
+
setScreen("prompts-menu");
|
|
175
|
+
} else if (key.ctrl && input === "c") {
|
|
176
|
+
exit();
|
|
177
|
+
} else if (input && !key.ctrl && !key.meta) {
|
|
178
|
+
setSonarPrompt((v) => v + input);
|
|
179
|
+
}
|
|
127
180
|
}
|
|
128
181
|
});
|
|
129
|
-
if (screen === "
|
|
182
|
+
if (screen === "main") {
|
|
130
183
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginY: 1, children: [
|
|
131
184
|
/* @__PURE__ */ jsx(Text, { bold: true, children: "Configure Automata" }),
|
|
132
185
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
186
|
+
MAIN_MENU_OPTIONS.map((option, index) => /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { color: index === mainMenuIndex ? "cyan" : void 0, children: [
|
|
187
|
+
index === mainMenuIndex ? "\u276F " : " ",
|
|
188
|
+
option
|
|
189
|
+
] }) }, option)),
|
|
190
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
191
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 to move \xB7 Enter to select \xB7 Ctrl+C to cancel" })
|
|
192
|
+
] });
|
|
193
|
+
}
|
|
194
|
+
if (screen === "remote") {
|
|
195
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginY: 1, children: [
|
|
196
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Remote / Mode" }),
|
|
197
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
133
198
|
/* @__PURE__ */ jsx(Text, { children: "Remote environment type:" }),
|
|
134
199
|
REMOTE_OPTIONS.map((option, index) => /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { color: index === selectedRemoteIndex ? "cyan" : void 0, children: [
|
|
135
200
|
index === selectedRemoteIndex ? "\u276F " : " ",
|
|
136
201
|
option.label
|
|
137
202
|
] }) }, option.value)),
|
|
138
203
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
139
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 to move \xB7 Enter to confirm \xB7 Ctrl+C to cancel" })
|
|
204
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 to move \xB7 Enter to confirm \xB7 Esc to go back \xB7 Ctrl+C to cancel" })
|
|
140
205
|
] });
|
|
141
206
|
}
|
|
142
207
|
if (screen === "technique") {
|
|
143
208
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginY: 1, children: [
|
|
144
|
-
/* @__PURE__ */ jsx(Text, { bold: true, children: "
|
|
209
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Implement-Next \u2014 Issue Discovery Technique" }),
|
|
145
210
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
146
211
|
/* @__PURE__ */ jsx(Text, { children: "How to find the next issue to work on:" }),
|
|
147
212
|
TECHNIQUE_OPTIONS.map((option, index) => /* @__PURE__ */ jsx(Box, { children: /* @__PURE__ */ jsxs(Text, { color: index === selectedTechIndex ? "cyan" : void 0, children: [
|
|
@@ -149,13 +214,13 @@ function ConfigWizard() {
|
|
|
149
214
|
option.label
|
|
150
215
|
] }) }, option.value)),
|
|
151
216
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
152
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 to move \xB7 Enter to confirm \xB7 Ctrl+C to cancel" })
|
|
217
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "\u2191/\u2193 to move \xB7 Enter to confirm \xB7 Esc to go back \xB7 Ctrl+C to cancel" })
|
|
153
218
|
] });
|
|
154
219
|
}
|
|
155
220
|
if (screen === "value") {
|
|
156
221
|
const techLabel = TECHNIQUE_OPTIONS.find((t) => t.value === pendingTechnique)?.label ?? pendingTechnique;
|
|
157
222
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginY: 1, children: [
|
|
158
|
-
/* @__PURE__ */ jsx(Text, { bold: true, children: "
|
|
223
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Implement-Next \u2014 Issue Discovery Value" }),
|
|
159
224
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
160
225
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
161
226
|
techLabel,
|
|
@@ -167,22 +232,50 @@ function ConfigWizard() {
|
|
|
167
232
|
] })
|
|
168
233
|
] }),
|
|
169
234
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
170
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Type value \xB7 Enter to
|
|
235
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Type value \xB7 Enter to continue \xB7 Esc to go back \xB7 Ctrl+C to cancel" })
|
|
236
|
+
] });
|
|
237
|
+
}
|
|
238
|
+
if (screen === "system-prompt") {
|
|
239
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginY: 1, children: [
|
|
240
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Implement-Next \u2014 Claude System Prompt" }),
|
|
241
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
242
|
+
/* @__PURE__ */ jsxs(Text, { children: [
|
|
243
|
+
"System prompt (optional):",
|
|
244
|
+
" ",
|
|
245
|
+
/* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
246
|
+
systemPrompt,
|
|
247
|
+
/* @__PURE__ */ jsx(Text, { children: "_" })
|
|
248
|
+
] })
|
|
249
|
+
] }),
|
|
250
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
251
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Type prompt \xB7 Enter to save and exit \xB7 Esc to go back \xB7 Ctrl+C to cancel" })
|
|
252
|
+
] });
|
|
253
|
+
}
|
|
254
|
+
if (screen === "prompts-menu") {
|
|
255
|
+
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginY: 1, children: [
|
|
256
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Prompts" }),
|
|
257
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
258
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
259
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: "\u276F " }),
|
|
260
|
+
/* @__PURE__ */ jsx(Text, { color: "cyan", children: "Sonar" })
|
|
261
|
+
] }),
|
|
262
|
+
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
263
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Enter to edit Sonar prompt \xB7 Esc to go back \xB7 Ctrl+C to cancel" })
|
|
171
264
|
] });
|
|
172
265
|
}
|
|
173
266
|
return /* @__PURE__ */ jsxs(Box, { flexDirection: "column", marginY: 1, children: [
|
|
174
|
-
/* @__PURE__ */ jsx(Text, { bold: true, children: "
|
|
267
|
+
/* @__PURE__ */ jsx(Text, { bold: true, children: "Prompts \u2014 Sonar" }),
|
|
175
268
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
176
269
|
/* @__PURE__ */ jsxs(Text, { children: [
|
|
177
|
-
"
|
|
270
|
+
"Sonar prompt:",
|
|
178
271
|
" ",
|
|
179
272
|
/* @__PURE__ */ jsxs(Text, { color: "cyan", children: [
|
|
180
|
-
|
|
273
|
+
sonarPrompt,
|
|
181
274
|
/* @__PURE__ */ jsx(Text, { children: "_" })
|
|
182
275
|
] })
|
|
183
276
|
] }),
|
|
184
277
|
/* @__PURE__ */ jsx(Text, { children: " " }),
|
|
185
|
-
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Type prompt \xB7 Enter to save and exit \xB7 Ctrl+C to cancel" })
|
|
278
|
+
/* @__PURE__ */ jsx(Text, { dimColor: true, children: "Type prompt \xB7 Enter to save and exit \xB7 Esc to go back \xB7 Ctrl+C to cancel" })
|
|
186
279
|
] });
|
|
187
280
|
}
|
|
188
281
|
|
|
@@ -335,7 +428,27 @@ function fetchCheckRunOutputs(ownerRepo, sha) {
|
|
|
335
428
|
}
|
|
336
429
|
return map;
|
|
337
430
|
}
|
|
338
|
-
function
|
|
431
|
+
function extractSonarProjectKey(url) {
|
|
432
|
+
try {
|
|
433
|
+
const parsed = new URL(url);
|
|
434
|
+
const id = parsed.searchParams.get("id");
|
|
435
|
+
return id ?? null;
|
|
436
|
+
} catch {
|
|
437
|
+
return null;
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
async function fetchSonarNewIssues(projectKey, prNumber) {
|
|
441
|
+
const apiUrl = `https://sonarcloud.io/api/issues/search?componentKeys=${encodeURIComponent(projectKey)}&pullRequest=${String(prNumber)}&resolved=false&ps=1`;
|
|
442
|
+
try {
|
|
443
|
+
const response = await fetch(apiUrl);
|
|
444
|
+
if (!response.ok) return null;
|
|
445
|
+
const data = await response.json();
|
|
446
|
+
return data.paging?.total ?? null;
|
|
447
|
+
} catch {
|
|
448
|
+
return null;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
async function getPrInfoGh(branch) {
|
|
339
452
|
const { stdout, stderr, status } = run2("gh", [
|
|
340
453
|
"pr",
|
|
341
454
|
"view",
|
|
@@ -365,9 +478,28 @@ function getPrInfoGh(branch) {
|
|
|
365
478
|
detailsUrl: enriched?.detailsUrl || c.detailsUrl || ""
|
|
366
479
|
};
|
|
367
480
|
});
|
|
368
|
-
|
|
481
|
+
const sonarCheck = checks.find((c) => c.detailsUrl.includes("sonarcloud.io"));
|
|
482
|
+
let sonarcloudUrl;
|
|
483
|
+
let sonarNewIssues;
|
|
484
|
+
if (sonarCheck) {
|
|
485
|
+
sonarcloudUrl = sonarCheck.detailsUrl;
|
|
486
|
+
const projectKey = extractSonarProjectKey(sonarCheck.detailsUrl);
|
|
487
|
+
if (projectKey) {
|
|
488
|
+
sonarNewIssues = await fetchSonarNewIssues(projectKey, raw.number);
|
|
489
|
+
} else {
|
|
490
|
+
sonarNewIssues = null;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
return {
|
|
494
|
+
number: raw.number,
|
|
495
|
+
title: raw.title,
|
|
496
|
+
state: raw.state,
|
|
497
|
+
url: raw.url,
|
|
498
|
+
checks,
|
|
499
|
+
...sonarcloudUrl !== void 0 ? { sonarcloudUrl, sonarNewIssues } : {}
|
|
500
|
+
};
|
|
369
501
|
}
|
|
370
|
-
function getPrInfo2(branch) {
|
|
502
|
+
async function getPrInfo2(branch) {
|
|
371
503
|
const config = readConfig();
|
|
372
504
|
if (config.remoteType === "azdo") {
|
|
373
505
|
return getPrInfo();
|
|
@@ -603,7 +735,7 @@ See docs/git.md for full output reference.`
|
|
|
603
735
|
let pr2;
|
|
604
736
|
while (true) {
|
|
605
737
|
try {
|
|
606
|
-
pr2 = getPrInfo2(branch);
|
|
738
|
+
pr2 = await getPrInfo2(branch);
|
|
607
739
|
} catch (err) {
|
|
608
740
|
process.stderr.write(`Error: ${err.message}
|
|
609
741
|
`);
|
|
@@ -643,7 +775,7 @@ See docs/git.md for full output reference.`
|
|
|
643
775
|
}
|
|
644
776
|
let pr;
|
|
645
777
|
try {
|
|
646
|
-
pr = getPrInfo2(branch);
|
|
778
|
+
pr = await getPrInfo2(branch);
|
|
647
779
|
} catch (err) {
|
|
648
780
|
process.stderr.write(`Error: ${err.message}
|
|
649
781
|
`);
|
|
@@ -662,6 +794,13 @@ Title: ${pr.title}
|
|
|
662
794
|
State: ${pr.state}
|
|
663
795
|
URL: ${pr.url}
|
|
664
796
|
`);
|
|
797
|
+
if (pr.sonarcloudUrl !== void 0) {
|
|
798
|
+
process.stdout.write(`Sonar: ${pr.sonarcloudUrl}
|
|
799
|
+
`);
|
|
800
|
+
const issueStr = pr.sonarNewIssues === null || pr.sonarNewIssues === void 0 ? "unavailable" : String(pr.sonarNewIssues);
|
|
801
|
+
process.stdout.write(`Sonar New Issues: ${issueStr}
|
|
802
|
+
`);
|
|
803
|
+
}
|
|
665
804
|
process.stdout.write(formatCheckSummary(pr.checks));
|
|
666
805
|
process.stdout.write(formatChecks(pr.checks));
|
|
667
806
|
}
|
|
@@ -724,7 +863,7 @@ ${safeBody}`);
|
|
|
724
863
|
}
|
|
725
864
|
process.stdout.write(lines.join("\n\n") + "\n");
|
|
726
865
|
});
|
|
727
|
-
var finishFeatureCmd = new Command2("finish-feature").description("Clean up a merged feature branch: checkout develop, pull, and delete local branch").action(() => {
|
|
866
|
+
var finishFeatureCmd = new Command2("finish-feature").description("Clean up a merged feature branch: checkout develop, pull, and delete local branch").action(async () => {
|
|
728
867
|
let branch;
|
|
729
868
|
try {
|
|
730
869
|
branch = getCurrentBranch();
|
|
@@ -745,7 +884,7 @@ var finishFeatureCmd = new Command2("finish-feature").description("Clean up a me
|
|
|
745
884
|
}
|
|
746
885
|
let pr;
|
|
747
886
|
try {
|
|
748
|
-
pr = getPrInfo2(branch);
|
|
887
|
+
pr = await getPrInfo2(branch);
|
|
749
888
|
} catch (err) {
|
|
750
889
|
process.stderr.write(`Error: ${err.message}
|
|
751
890
|
`);
|
|
@@ -1194,13 +1333,63 @@ var testCodexCmd = new Command4("codex").description("Test Codex CLI invocation
|
|
|
1194
1333
|
});
|
|
1195
1334
|
var testCommand = new Command4("test").description("Test commands for verifying automata integrations").addCommand(testClaudeCmd).addCommand(testCodexCmd);
|
|
1196
1335
|
|
|
1336
|
+
// src/commands/executePrompt.ts
|
|
1337
|
+
import { Command as Command5 } from "commander";
|
|
1338
|
+
var executeSonarCmd = new Command5("sonar").description(
|
|
1339
|
+
"Check the current branch for a SonarCloud analysis and invoke the AI with the Sonar prompt and analysis URL"
|
|
1340
|
+
).option("--codex", "Use Codex CLI instead of Claude Code").option("--verbose", "Show step-by-step progress (Claude only; ignored for Codex)").option("--opus", "Use claude-opus-4-6 (Claude only)").option("--sonnet", "Use claude-sonnet-4-6 (Claude only)").option("--haiku", "Use claude-haiku-4-5-20251001 (Claude only)").action(
|
|
1341
|
+
async (options) => {
|
|
1342
|
+
let branch;
|
|
1343
|
+
try {
|
|
1344
|
+
branch = getCurrentBranch();
|
|
1345
|
+
} catch (err) {
|
|
1346
|
+
process.stderr.write(`Error: ${err.message}
|
|
1347
|
+
`);
|
|
1348
|
+
process.exit(1);
|
|
1349
|
+
}
|
|
1350
|
+
let pr;
|
|
1351
|
+
try {
|
|
1352
|
+
pr = await getPrInfo2(branch);
|
|
1353
|
+
} catch (err) {
|
|
1354
|
+
process.stderr.write(`Error: ${err.message}
|
|
1355
|
+
`);
|
|
1356
|
+
process.exit(1);
|
|
1357
|
+
}
|
|
1358
|
+
if (pr === null) {
|
|
1359
|
+
process.stderr.write(`Error: No pull request found for branch: ${branch}
|
|
1360
|
+
`);
|
|
1361
|
+
process.exit(1);
|
|
1362
|
+
}
|
|
1363
|
+
if (!pr.sonarcloudUrl) {
|
|
1364
|
+
process.stderr.write(
|
|
1365
|
+
`Error: No SonarCloud analysis found for PR #${pr.number}. Ensure a SonarCloud check is configured on this repository.
|
|
1366
|
+
`
|
|
1367
|
+
);
|
|
1368
|
+
process.exit(1);
|
|
1369
|
+
}
|
|
1370
|
+
const config = readConfig();
|
|
1371
|
+
const sonarPromptText = config.prompts?.sonar ?? DEFAULT_SONAR_PROMPT;
|
|
1372
|
+
const fullPrompt = `${sonarPromptText}
|
|
1373
|
+
|
|
1374
|
+
SonarCloud analysis URL: ${pr.sonarcloudUrl}`;
|
|
1375
|
+
if (options.codex) {
|
|
1376
|
+
invokeCodexCode(fullPrompt, { verbose: options.verbose });
|
|
1377
|
+
} else {
|
|
1378
|
+
const model = resolveModelOption(options);
|
|
1379
|
+
await invokeClaudeCode(fullPrompt, { verbose: options.verbose, model });
|
|
1380
|
+
}
|
|
1381
|
+
}
|
|
1382
|
+
);
|
|
1383
|
+
var executePromptCommand = new Command5("execute-prompt").description("Execute a configured custom prompt using an AI assistant").addCommand(executeSonarCmd);
|
|
1384
|
+
|
|
1197
1385
|
// src/index.ts
|
|
1198
|
-
var program = new
|
|
1386
|
+
var program = new Command6();
|
|
1199
1387
|
program.name("automata").description("Automata CLI tool").version(version, "-v, --version");
|
|
1200
1388
|
program.addCommand(configCommand);
|
|
1201
1389
|
program.addCommand(gitCommand);
|
|
1202
1390
|
program.addCommand(implementNextCommand);
|
|
1203
1391
|
program.addCommand(testCommand);
|
|
1392
|
+
program.addCommand(executePromptCommand);
|
|
1204
1393
|
program.showHelpAfterError();
|
|
1205
1394
|
program.parse();
|
|
1206
1395
|
if (process.argv.length <= 2) {
|