@basemachina/agentic-browser-cli 0.3.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/dist/ai-model-NZ7QJNJW.js +32 -0
- package/dist/ai-model-NZ7QJNJW.js.map +1 -0
- package/dist/chunk-KDEQ2AAE.js +93 -0
- package/dist/chunk-KDEQ2AAE.js.map +1 -0
- package/dist/chunk-U6GPCKY3.js +3186 -0
- package/dist/chunk-U6GPCKY3.js.map +1 -0
- package/dist/chunk-VNQYQSMI.js +922 -0
- package/dist/chunk-VNQYQSMI.js.map +1 -0
- package/dist/chunk-XAEHXRUC.js +607 -0
- package/dist/chunk-XAEHXRUC.js.map +1 -0
- package/dist/cli.js +55 -0
- package/dist/cli.js.map +1 -0
- package/dist/compose-EHDWVF7N.js +543 -0
- package/dist/compose-EHDWVF7N.js.map +1 -0
- package/dist/fix-instruction-JLCLTXAN.js +406 -0
- package/dist/fix-instruction-JLCLTXAN.js.map +1 -0
- package/dist/instruction-executor-M5Q6HYSM.js +5202 -0
- package/dist/instruction-executor-M5Q6HYSM.js.map +1 -0
- package/dist/instruction-generator-5RPRYTVR.js +2470 -0
- package/dist/instruction-generator-5RPRYTVR.js.map +1 -0
- package/package.json +29 -0
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
parseModelConfig
|
|
4
|
+
} from "./chunk-KDEQ2AAE.js";
|
|
5
|
+
import {
|
|
6
|
+
getModel,
|
|
7
|
+
initModel,
|
|
8
|
+
trackedGenerateText
|
|
9
|
+
} from "./chunk-XAEHXRUC.js";
|
|
10
|
+
import {
|
|
11
|
+
ParsedInstructionSchema,
|
|
12
|
+
cancel,
|
|
13
|
+
initLocale,
|
|
14
|
+
intro,
|
|
15
|
+
log,
|
|
16
|
+
outro,
|
|
17
|
+
promptConfirm,
|
|
18
|
+
promptSelect,
|
|
19
|
+
spinner,
|
|
20
|
+
t,
|
|
21
|
+
tf
|
|
22
|
+
} from "./chunk-VNQYQSMI.js";
|
|
23
|
+
|
|
24
|
+
// src/fix-instruction/index.ts
|
|
25
|
+
import { readFile, writeFile } from "fs/promises";
|
|
26
|
+
|
|
27
|
+
// src/fix-instruction/config.ts
|
|
28
|
+
import { parseArgs as nodeParseArgs } from "util";
|
|
29
|
+
import { existsSync } from "fs";
|
|
30
|
+
async function parseArgs() {
|
|
31
|
+
const { values } = nodeParseArgs({
|
|
32
|
+
options: {
|
|
33
|
+
instruction: { type: "string" },
|
|
34
|
+
report: { type: "string" },
|
|
35
|
+
model: { type: "string" },
|
|
36
|
+
"model-provider": { type: "string" },
|
|
37
|
+
"model-base-url": { type: "string" },
|
|
38
|
+
"model-review": { type: "string" },
|
|
39
|
+
locale: { type: "string" }
|
|
40
|
+
},
|
|
41
|
+
strict: true
|
|
42
|
+
});
|
|
43
|
+
initLocale(values.locale);
|
|
44
|
+
if (!values.instruction) {
|
|
45
|
+
throw new Error(t("cli.instructionRequired"));
|
|
46
|
+
}
|
|
47
|
+
if (!values.report) {
|
|
48
|
+
throw new Error(t("cli.reportRequired"));
|
|
49
|
+
}
|
|
50
|
+
if (!existsSync(values.instruction)) {
|
|
51
|
+
throw new Error(`Instruction file not found: ${values.instruction}`);
|
|
52
|
+
}
|
|
53
|
+
if (!existsSync(values.report)) {
|
|
54
|
+
throw new Error(`Report file not found: ${values.report}`);
|
|
55
|
+
}
|
|
56
|
+
const aiModelConfig = parseModelConfig(values);
|
|
57
|
+
return {
|
|
58
|
+
instructionPath: values.instruction,
|
|
59
|
+
reportPath: values.report,
|
|
60
|
+
aiModelConfig
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// src/fix-instruction/report-parser.ts
|
|
65
|
+
function extractSuggestions(reportContent) {
|
|
66
|
+
const suggestions = extractFromAiAgentSummary(reportContent);
|
|
67
|
+
if (suggestions.length > 0) return suggestions;
|
|
68
|
+
return extractFromDiagnostics(reportContent);
|
|
69
|
+
}
|
|
70
|
+
function extractFromAiAgentSummary(content) {
|
|
71
|
+
const summaryStart = content.indexOf("## AI Agent Summary");
|
|
72
|
+
if (summaryStart === -1) return [];
|
|
73
|
+
const afterSummary = content.slice(summaryStart + "## AI Agent Summary".length);
|
|
74
|
+
const nextSection = afterSummary.search(/\n## [^#]/);
|
|
75
|
+
const summaryContent = nextSection === -1 ? afterSummary : afterSummary.slice(0, nextSection);
|
|
76
|
+
const suggestions = [];
|
|
77
|
+
const stepPattern = /#### Step #(\d+): (.+)/g;
|
|
78
|
+
let match;
|
|
79
|
+
const stepPositions = [];
|
|
80
|
+
while ((match = stepPattern.exec(summaryContent)) !== null) {
|
|
81
|
+
stepPositions.push({
|
|
82
|
+
ordinal: parseInt(match[1], 10),
|
|
83
|
+
description: match[2].trim(),
|
|
84
|
+
start: match.index + match[0].length
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
for (let i = 0; i < stepPositions.length; i++) {
|
|
88
|
+
const pos = stepPositions[i];
|
|
89
|
+
const end = i + 1 < stepPositions.length ? stepPositions[i + 1].start : summaryContent.length;
|
|
90
|
+
const stepContent = summaryContent.slice(pos.start, end);
|
|
91
|
+
const suggestion = {
|
|
92
|
+
stepOrdinal: pos.ordinal,
|
|
93
|
+
description: pos.description,
|
|
94
|
+
error: extractField(stepContent, "\u30A8\u30E9\u30FC") ?? "Unknown",
|
|
95
|
+
category: extractField(stepContent, "\u5206\u985E")?.replace(/`/g, ""),
|
|
96
|
+
recoveryHint: extractField(stepContent, "\u63A8\u5968\u5BFE\u5FDC"),
|
|
97
|
+
yamlFix: extractField(stepContent, "YAML \u4FEE\u6B63\u63D0\u6848"),
|
|
98
|
+
contextFix: extractField(stepContent, "Context \u4FEE\u6B63\u63D0\u6848"),
|
|
99
|
+
suggestedStrategy: extractField(stepContent, "\u63A8\u5968\u6226\u7565"),
|
|
100
|
+
currentSelector: extractCodeBlock(stepContent, "\u73FE\u5728\u306E\u30BB\u30EC\u30AF\u30BF"),
|
|
101
|
+
lastSnapshotPreview: extractCodeBlock(stepContent, "\u6700\u7D42\u30B9\u30CA\u30C3\u30D7\u30B7\u30E7\u30C3\u30C8")
|
|
102
|
+
};
|
|
103
|
+
suggestions.push(suggestion);
|
|
104
|
+
}
|
|
105
|
+
return suggestions;
|
|
106
|
+
}
|
|
107
|
+
function extractFromDiagnostics(content) {
|
|
108
|
+
const diagStart = content.indexOf("## Failed Step Diagnostics");
|
|
109
|
+
if (diagStart === -1) return [];
|
|
110
|
+
const afterDiag = content.slice(diagStart);
|
|
111
|
+
const nextSection = afterDiag.search(/\n## [^#]/);
|
|
112
|
+
const diagContent = nextSection === -1 ? afterDiag : afterDiag.slice(0, nextSection);
|
|
113
|
+
const stepPattern = /### Step #(\d+) — (?:Diagnostics|Error Info|Retry Details)/g;
|
|
114
|
+
let match;
|
|
115
|
+
const ordinalContents = /* @__PURE__ */ new Map();
|
|
116
|
+
while ((match = stepPattern.exec(diagContent)) !== null) {
|
|
117
|
+
const ordinal = parseInt(match[1], 10);
|
|
118
|
+
const sectionStart = match.index + match[0].length;
|
|
119
|
+
const rest = diagContent.slice(sectionStart);
|
|
120
|
+
const nextStep = rest.search(/\n### Step #/);
|
|
121
|
+
const sectionContent = nextStep === -1 ? rest : rest.slice(0, nextStep);
|
|
122
|
+
const existing = ordinalContents.get(ordinal) ?? "";
|
|
123
|
+
ordinalContents.set(ordinal, existing + "\n" + sectionContent);
|
|
124
|
+
}
|
|
125
|
+
const suggestions = [];
|
|
126
|
+
for (const [ordinal, stepContent] of ordinalContents) {
|
|
127
|
+
const recoveryHint = extractField(stepContent, "Recovery Hint");
|
|
128
|
+
const error = extractField(stepContent, "Error") ?? "Unknown";
|
|
129
|
+
const stepResultPattern = new RegExp(`${ordinal}\\. \\[FAILED\\] (.+?) \\(`);
|
|
130
|
+
const descMatch = content.match(stepResultPattern);
|
|
131
|
+
suggestions.push({
|
|
132
|
+
stepOrdinal: ordinal,
|
|
133
|
+
description: descMatch?.[1] ?? `Step #${ordinal}`,
|
|
134
|
+
error,
|
|
135
|
+
recoveryHint,
|
|
136
|
+
currentSelector: extractCodeBlock(stepContent, "Step Action")
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return suggestions;
|
|
140
|
+
}
|
|
141
|
+
function extractField(content, label) {
|
|
142
|
+
const listPattern = new RegExp(`- \\*\\*${escapeRegex(label)}\\*\\*: (.+?)(?:
|
|
143
|
+
|$)`);
|
|
144
|
+
const listMatch = content.match(listPattern);
|
|
145
|
+
if (listMatch) return listMatch[1].trim();
|
|
146
|
+
const boldPattern = new RegExp(`\\*\\*${escapeRegex(label)}\\*\\*: (.+?)(?:
|
|
147
|
+
|$)`);
|
|
148
|
+
const boldMatch = content.match(boldPattern);
|
|
149
|
+
return boldMatch?.[1]?.trim();
|
|
150
|
+
}
|
|
151
|
+
function extractCodeBlock(content, label) {
|
|
152
|
+
const labelIdx = content.indexOf(`**${label}**`);
|
|
153
|
+
if (labelIdx === -1) return void 0;
|
|
154
|
+
const afterLabel = content.slice(labelIdx);
|
|
155
|
+
const codeStart = afterLabel.indexOf("```");
|
|
156
|
+
if (codeStart === -1) return void 0;
|
|
157
|
+
const codeContentStart = afterLabel.indexOf("\n", codeStart) + 1;
|
|
158
|
+
const codeEnd = afterLabel.indexOf("```", codeContentStart);
|
|
159
|
+
if (codeEnd === -1) return void 0;
|
|
160
|
+
return afterLabel.slice(codeContentStart, codeEnd).trim();
|
|
161
|
+
}
|
|
162
|
+
function escapeRegex(str) {
|
|
163
|
+
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// src/fix-instruction/yaml-patcher.ts
|
|
167
|
+
import { parse } from "yaml";
|
|
168
|
+
async function generatePatch(originalYaml, suggestion) {
|
|
169
|
+
const s = spinner();
|
|
170
|
+
s.start(`Step #${suggestion.stepOrdinal} \u306E\u30D1\u30C3\u30C1\u3092\u751F\u6210\u4E2D...`);
|
|
171
|
+
try {
|
|
172
|
+
const { system, userPrompt } = buildPatchMessages(originalYaml, suggestion);
|
|
173
|
+
const { text } = await trackedGenerateText("review", {
|
|
174
|
+
model: getModel("review"),
|
|
175
|
+
messages: [
|
|
176
|
+
{
|
|
177
|
+
role: "system",
|
|
178
|
+
content: system,
|
|
179
|
+
providerOptions: {
|
|
180
|
+
anthropic: { cacheControl: { type: "ephemeral" } }
|
|
181
|
+
}
|
|
182
|
+
},
|
|
183
|
+
{ role: "user", content: userPrompt }
|
|
184
|
+
],
|
|
185
|
+
temperature: 0
|
|
186
|
+
});
|
|
187
|
+
const patchedYaml = extractYamlFromResponse(text);
|
|
188
|
+
if (!patchedYaml) {
|
|
189
|
+
s.stop("\u30D1\u30C3\u30C1\u751F\u6210\u5931\u6557");
|
|
190
|
+
return {
|
|
191
|
+
success: false,
|
|
192
|
+
patchedYaml: originalYaml,
|
|
193
|
+
error: "AI \u30EC\u30B9\u30DD\u30F3\u30B9\u304B\u3089 YAML \u3092\u62BD\u51FA\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F"
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
const validationError = validateYaml(patchedYaml);
|
|
197
|
+
if (validationError) {
|
|
198
|
+
s.stop("\u30D0\u30EA\u30C7\u30FC\u30B7\u30E7\u30F3\u5931\u6557");
|
|
199
|
+
return {
|
|
200
|
+
success: false,
|
|
201
|
+
patchedYaml: originalYaml,
|
|
202
|
+
error: `\u30D0\u30EA\u30C7\u30FC\u30B7\u30E7\u30F3\u30A8\u30E9\u30FC: ${validationError}`
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
s.stop("\u30D1\u30C3\u30C1\u751F\u6210\u5B8C\u4E86");
|
|
206
|
+
return { success: true, patchedYaml };
|
|
207
|
+
} catch (error) {
|
|
208
|
+
s.stop("\u30D1\u30C3\u30C1\u751F\u6210\u5931\u6557");
|
|
209
|
+
return {
|
|
210
|
+
success: false,
|
|
211
|
+
patchedYaml: originalYaml,
|
|
212
|
+
error: error instanceof Error ? error.message : String(error)
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
var PATCH_SYSTEM_PROMPT = [
|
|
217
|
+
"\u3042\u306A\u305F\u306F instruction YAML \u306E\u30D1\u30C3\u30C1\u751F\u6210\u30C4\u30FC\u30EB\u3067\u3059\u3002",
|
|
218
|
+
"\u4EE5\u4E0B\u306E\u4FEE\u6B63\u63D0\u6848\u306B\u57FA\u3065\u3044\u3066\u3001YAML \u3092\u4FEE\u6B63\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
|
|
219
|
+
"",
|
|
220
|
+
"## \u30EB\u30FC\u30EB",
|
|
221
|
+
"- \u4FEE\u6B63\u5BFE\u8C61\u30B9\u30C6\u30C3\u30D7\u4EE5\u5916\u306F\u4E00\u5207\u5909\u66F4\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044",
|
|
222
|
+
"- YAML \u306E\u30D5\u30A9\u30FC\u30DE\u30C3\u30C8\uFF08\u30A4\u30F3\u30C7\u30F3\u30C8\u3001\u5F15\u7528\u7B26\u30B9\u30BF\u30A4\u30EB\u3001\u30B3\u30E1\u30F3\u30C8\u4F4D\u7F6E\uFF09\u3092\u3067\u304D\u308B\u9650\u308A\u7DAD\u6301\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
223
|
+
"- \u4FEE\u6B63\u306F\u6700\u5C0F\u9650\u306B\u3057\u3066\u304F\u3060\u3055\u3044",
|
|
224
|
+
"- \u51FA\u529B\u306F YAML \u306E\u307F\uFF08```yaml ... ``` \u3067\u56F2\u3093\u3067\u304F\u3060\u3055\u3044\uFF09",
|
|
225
|
+
"- \u8AAC\u660E\u3084\u30B3\u30E1\u30F3\u30C8\u306F\u4E0D\u8981\u3067\u3059"
|
|
226
|
+
].join("\n");
|
|
227
|
+
function buildPatchMessages(originalYaml, suggestion) {
|
|
228
|
+
const parts = [
|
|
229
|
+
"## \u4FEE\u6B63\u5BFE\u8C61",
|
|
230
|
+
`- \u30B9\u30C6\u30C3\u30D7\u756A\u53F7: ${suggestion.stepOrdinal}`,
|
|
231
|
+
`- \u8AAC\u660E: ${suggestion.description}`,
|
|
232
|
+
`- \u30A8\u30E9\u30FC: ${suggestion.error}`
|
|
233
|
+
];
|
|
234
|
+
if (suggestion.category) {
|
|
235
|
+
parts.push(`- \u30A8\u30E9\u30FC\u5206\u985E: ${suggestion.category}`);
|
|
236
|
+
}
|
|
237
|
+
if (suggestion.recoveryHint) {
|
|
238
|
+
parts.push(`- \u63A8\u5968\u5BFE\u5FDC: ${suggestion.recoveryHint}`);
|
|
239
|
+
}
|
|
240
|
+
if (suggestion.yamlFix) {
|
|
241
|
+
parts.push(`- \u4FEE\u6B63\u63D0\u6848: ${suggestion.yamlFix}`);
|
|
242
|
+
}
|
|
243
|
+
if (suggestion.currentSelector) {
|
|
244
|
+
parts.push(`- \u73FE\u5728\u306E\u30BB\u30EC\u30AF\u30BF: ${suggestion.currentSelector}`);
|
|
245
|
+
}
|
|
246
|
+
if (suggestion.lastSnapshotPreview) {
|
|
247
|
+
parts.push("");
|
|
248
|
+
parts.push("## \u6700\u7D42\u30B9\u30CA\u30C3\u30D7\u30B7\u30E7\u30C3\u30C8\uFF08\u30DA\u30FC\u30B8\u306E\u73FE\u5728\u306E\u72B6\u614B\uFF09");
|
|
249
|
+
parts.push("```");
|
|
250
|
+
parts.push(suggestion.lastSnapshotPreview);
|
|
251
|
+
parts.push("```");
|
|
252
|
+
}
|
|
253
|
+
parts.push("");
|
|
254
|
+
parts.push("## \u73FE\u5728\u306E YAML");
|
|
255
|
+
parts.push("```yaml");
|
|
256
|
+
parts.push(originalYaml);
|
|
257
|
+
parts.push("```");
|
|
258
|
+
return { system: PATCH_SYSTEM_PROMPT, userPrompt: parts.join("\n") };
|
|
259
|
+
}
|
|
260
|
+
function extractYamlFromResponse(response) {
|
|
261
|
+
const yamlMatch = response.match(/```ya?ml\n([\s\S]*?)```/);
|
|
262
|
+
if (yamlMatch) return yamlMatch[1].trim();
|
|
263
|
+
const codeMatch = response.match(/```\n([\s\S]*?)```/);
|
|
264
|
+
if (codeMatch) return codeMatch[1].trim();
|
|
265
|
+
try {
|
|
266
|
+
parse(response);
|
|
267
|
+
return response.trim();
|
|
268
|
+
} catch {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
function validateYaml(yamlContent) {
|
|
273
|
+
try {
|
|
274
|
+
const doc = parse(yamlContent);
|
|
275
|
+
ParsedInstructionSchema.parse(doc);
|
|
276
|
+
return null;
|
|
277
|
+
} catch (error) {
|
|
278
|
+
if (error instanceof Error) {
|
|
279
|
+
return error.message.slice(0, 200);
|
|
280
|
+
}
|
|
281
|
+
return String(error);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
// src/fix-instruction/index.ts
|
|
286
|
+
async function main() {
|
|
287
|
+
const config = await parseArgs();
|
|
288
|
+
await initModel(config.aiModelConfig);
|
|
289
|
+
intro("fix-instruction");
|
|
290
|
+
log.info(`Instruction: ${config.instructionPath}`);
|
|
291
|
+
log.info(`Report: ${config.reportPath}`);
|
|
292
|
+
const reportContent = await readFile(config.reportPath, "utf-8");
|
|
293
|
+
const suggestions = extractSuggestions(reportContent);
|
|
294
|
+
if (suggestions.length === 0) {
|
|
295
|
+
log.warn(t("fix.noSuggestions"));
|
|
296
|
+
log.info(t("fix.noSuggestionsHint"));
|
|
297
|
+
outro(t("fix.complete"));
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
log.info(tf("fix.suggestionCount", { count: suggestions.length }));
|
|
301
|
+
const originalYaml = await readFile(config.instructionPath, "utf-8");
|
|
302
|
+
const appliedSuggestions = [];
|
|
303
|
+
let currentYaml = originalYaml;
|
|
304
|
+
for (const suggestion of suggestions) {
|
|
305
|
+
log.step(`Step #${suggestion.stepOrdinal}: ${suggestion.description}`);
|
|
306
|
+
log.info(tf("fix.errorLabel", { error: suggestion.error }));
|
|
307
|
+
if (suggestion.category) {
|
|
308
|
+
log.info(tf("fix.categoryLabel", { category: suggestion.category }));
|
|
309
|
+
}
|
|
310
|
+
if (suggestion.yamlFix) {
|
|
311
|
+
log.info(tf("fix.yamlFixLabel", { fix: suggestion.yamlFix }));
|
|
312
|
+
}
|
|
313
|
+
if (suggestion.contextFix) {
|
|
314
|
+
log.info(tf("fix.contextFixLabel", { fix: suggestion.contextFix }));
|
|
315
|
+
}
|
|
316
|
+
if (suggestion.recoveryHint) {
|
|
317
|
+
log.info(tf("fix.recoveryHintLabel", { hint: suggestion.recoveryHint }));
|
|
318
|
+
}
|
|
319
|
+
if (!suggestion.yamlFix) {
|
|
320
|
+
log.warn(t("fix.noYamlFix"));
|
|
321
|
+
continue;
|
|
322
|
+
}
|
|
323
|
+
const action = await promptSelect(t("fix.applyPrompt"), [
|
|
324
|
+
{ value: "apply", label: t("fix.applyLabel"), hint: t("fix.applyHint") },
|
|
325
|
+
{ value: "skip", label: t("fix.skipLabel"), hint: t("fix.skipHint") },
|
|
326
|
+
{ value: "abort", label: t("fix.abortLabel"), hint: t("fix.abortHint") }
|
|
327
|
+
]);
|
|
328
|
+
if (action === "abort") {
|
|
329
|
+
break;
|
|
330
|
+
}
|
|
331
|
+
if (action === "apply") {
|
|
332
|
+
const patchResult = await generatePatch(currentYaml, suggestion);
|
|
333
|
+
if (patchResult.success) {
|
|
334
|
+
log.success(t("fix.patchGenerated"));
|
|
335
|
+
showDiff(currentYaml, patchResult.patchedYaml);
|
|
336
|
+
const confirmed = await promptConfirm(t("fix.confirmApply"));
|
|
337
|
+
if (confirmed) {
|
|
338
|
+
currentYaml = patchResult.patchedYaml;
|
|
339
|
+
appliedSuggestions.push(suggestion);
|
|
340
|
+
log.success(tf("fix.applied", { ordinal: suggestion.stepOrdinal }));
|
|
341
|
+
} else {
|
|
342
|
+
log.info(t("fix.skippedMsg"));
|
|
343
|
+
}
|
|
344
|
+
} else {
|
|
345
|
+
log.error(tf("fix.patchFailed", { error: patchResult.error ?? "unknown" }));
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
if (appliedSuggestions.length > 0) {
|
|
350
|
+
const shouldWrite = await promptConfirm(
|
|
351
|
+
tf("fix.writePrompt", { count: appliedSuggestions.length, path: config.instructionPath })
|
|
352
|
+
);
|
|
353
|
+
if (shouldWrite) {
|
|
354
|
+
await writeFile(config.instructionPath, currentYaml, "utf-8");
|
|
355
|
+
log.success(tf("fix.writeSuccess", { path: config.instructionPath }));
|
|
356
|
+
log.info(`
|
|
357
|
+
${t("fix.verifyCommand")}`);
|
|
358
|
+
log.info(` pnpm execute -- --instruction ${config.instructionPath} --maintenance`);
|
|
359
|
+
} else {
|
|
360
|
+
log.info(t("fix.writeCancelled"));
|
|
361
|
+
}
|
|
362
|
+
} else {
|
|
363
|
+
log.info(t("fix.noChanges"));
|
|
364
|
+
}
|
|
365
|
+
outro(t("fix.complete"));
|
|
366
|
+
}
|
|
367
|
+
function showDiff(original, patched) {
|
|
368
|
+
const origLines = original.split("\n");
|
|
369
|
+
const patchLines = patched.split("\n");
|
|
370
|
+
const maxLines = Math.max(origLines.length, patchLines.length);
|
|
371
|
+
const diffLines = [];
|
|
372
|
+
let contextBefore = 0;
|
|
373
|
+
for (let i = 0; i < maxLines; i++) {
|
|
374
|
+
const orig = origLines[i];
|
|
375
|
+
const patch = patchLines[i];
|
|
376
|
+
if (orig !== patch) {
|
|
377
|
+
if (contextBefore === 0) {
|
|
378
|
+
for (let j = Math.max(0, i - 2); j < i; j++) {
|
|
379
|
+
if (origLines[j] !== void 0) {
|
|
380
|
+
diffLines.push(` ${origLines[j]}`);
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
if (orig !== void 0) {
|
|
385
|
+
diffLines.push(`- ${orig}`);
|
|
386
|
+
}
|
|
387
|
+
if (patch !== void 0) {
|
|
388
|
+
diffLines.push(`+ ${patch}`);
|
|
389
|
+
}
|
|
390
|
+
contextBefore = 3;
|
|
391
|
+
} else if (contextBefore > 0) {
|
|
392
|
+
diffLines.push(` ${orig}`);
|
|
393
|
+
contextBefore--;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
if (diffLines.length > 0) {
|
|
397
|
+
log.info(diffLines.join("\n"));
|
|
398
|
+
} else {
|
|
399
|
+
log.info(t("fix.noDiff"));
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
main().catch((error) => {
|
|
403
|
+
cancel(`Fatal error: ${error instanceof Error ? error.message : String(error)}`);
|
|
404
|
+
process.exit(1);
|
|
405
|
+
});
|
|
406
|
+
//# sourceMappingURL=fix-instruction-JLCLTXAN.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/fix-instruction/index.ts","../../../src/fix-instruction/config.ts","../../../src/fix-instruction/report-parser.ts","../../../src/fix-instruction/yaml-patcher.ts"],"sourcesContent":["/**\n * fix-instruction CLI — レポートから修正提案を抽出し、instruction YAML に適用する\n *\n * Usage:\n * pnpm fix-instruction -- \\\n * --instruction ./instructions/login-flow.yaml \\\n * --report ./instructions/login-flow-report.md\n */\n\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { parseArgs } from \"./config\";\nimport { initModel } from \"../harness/ai-model\";\nimport { extractSuggestions, type ExtractedSuggestion } from \"./report-parser\";\nimport { generatePatch } from \"./yaml-patcher\";\nimport { intro, outro, log, cancel, promptSelect, promptConfirm } from \"../cli/prompts\";\nimport { t, tf } from \"../i18n\";\n\nasync function main() {\n const config = await parseArgs();\n await initModel(config.aiModelConfig);\n\n intro(\"fix-instruction\");\n log.info(`Instruction: ${config.instructionPath}`);\n log.info(`Report: ${config.reportPath}`);\n\n // レポートからAI Agent Summaryを読み取り、修正提案を抽出\n const reportContent = await readFile(config.reportPath, \"utf-8\");\n const suggestions = extractSuggestions(reportContent);\n\n if (suggestions.length === 0) {\n log.warn(t(\"fix.noSuggestions\"));\n log.info(t(\"fix.noSuggestionsHint\"));\n outro(t(\"fix.complete\"));\n return;\n }\n\n log.info(tf(\"fix.suggestionCount\", { count: suggestions.length }));\n\n // instruction YAML を読み込み\n const originalYaml = await readFile(config.instructionPath, \"utf-8\");\n\n // 各提案を対話的に処理\n const appliedSuggestions: ExtractedSuggestion[] = [];\n let currentYaml = originalYaml;\n\n for (const suggestion of suggestions) {\n log.step(`Step #${suggestion.stepOrdinal}: ${suggestion.description}`);\n log.info(tf(\"fix.errorLabel\", { error: suggestion.error }));\n if (suggestion.category) {\n log.info(tf(\"fix.categoryLabel\", { category: suggestion.category }));\n }\n if (suggestion.yamlFix) {\n log.info(tf(\"fix.yamlFixLabel\", { fix: suggestion.yamlFix }));\n }\n if (suggestion.contextFix) {\n log.info(tf(\"fix.contextFixLabel\", { fix: suggestion.contextFix }));\n }\n if (suggestion.recoveryHint) {\n log.info(tf(\"fix.recoveryHintLabel\", { hint: suggestion.recoveryHint }));\n }\n\n if (!suggestion.yamlFix) {\n log.warn(t(\"fix.noYamlFix\"));\n continue;\n }\n\n const action = await promptSelect(t(\"fix.applyPrompt\"), [\n { value: \"apply\", label: t(\"fix.applyLabel\"), hint: t(\"fix.applyHint\") },\n { value: \"skip\", label: t(\"fix.skipLabel\"), hint: t(\"fix.skipHint\") },\n { value: \"abort\", label: t(\"fix.abortLabel\"), hint: t(\"fix.abortHint\") },\n ]);\n\n if (action === \"abort\") {\n break;\n }\n\n if (action === \"apply\") {\n const patchResult = await generatePatch(currentYaml, suggestion);\n if (patchResult.success) {\n log.success(t(\"fix.patchGenerated\"));\n showDiff(currentYaml, patchResult.patchedYaml);\n\n const confirmed = await promptConfirm(t(\"fix.confirmApply\"));\n if (confirmed) {\n currentYaml = patchResult.patchedYaml;\n appliedSuggestions.push(suggestion);\n log.success(tf(\"fix.applied\", { ordinal: suggestion.stepOrdinal }));\n } else {\n log.info(t(\"fix.skippedMsg\"));\n }\n } else {\n log.error(tf(\"fix.patchFailed\", { error: patchResult.error ?? \"unknown\" }));\n }\n }\n }\n\n // 変更があればファイルに書き込み\n if (appliedSuggestions.length > 0) {\n const shouldWrite = await promptConfirm(\n tf(\"fix.writePrompt\", { count: appliedSuggestions.length, path: config.instructionPath }),\n );\n\n if (shouldWrite) {\n await writeFile(config.instructionPath, currentYaml, \"utf-8\");\n log.success(tf(\"fix.writeSuccess\", { path: config.instructionPath }));\n\n log.info(`\\n${t(\"fix.verifyCommand\")}`);\n log.info(` pnpm execute -- --instruction ${config.instructionPath} --maintenance`);\n } else {\n log.info(t(\"fix.writeCancelled\"));\n }\n } else {\n log.info(t(\"fix.noChanges\"));\n }\n\n outro(t(\"fix.complete\"));\n}\n\nfunction showDiff(original: string, patched: string): void {\n const origLines = original.split(\"\\n\");\n const patchLines = patched.split(\"\\n\");\n\n // 簡易差分表示: 変更のあった行を +- で表示\n const maxLines = Math.max(origLines.length, patchLines.length);\n const diffLines: string[] = [];\n let contextBefore = 0;\n\n for (let i = 0; i < maxLines; i++) {\n const orig = origLines[i];\n const patch = patchLines[i];\n\n if (orig !== patch) {\n // 変更前のコンテキスト行(最大2行)\n if (contextBefore === 0) {\n for (let j = Math.max(0, i - 2); j < i; j++) {\n if (origLines[j] !== undefined) {\n diffLines.push(` ${origLines[j]}`);\n }\n }\n }\n if (orig !== undefined) {\n diffLines.push(`- ${orig}`);\n }\n if (patch !== undefined) {\n diffLines.push(`+ ${patch}`);\n }\n contextBefore = 3;\n } else if (contextBefore > 0) {\n diffLines.push(` ${orig}`);\n contextBefore--;\n }\n }\n\n if (diffLines.length > 0) {\n log.info(diffLines.join(\"\\n\"));\n } else {\n log.info(t(\"fix.noDiff\"));\n }\n}\n\nmain().catch((error) => {\n cancel(`Fatal error: ${error instanceof Error ? error.message : String(error)}`);\n process.exit(1);\n});\n","/**\n * apply-fix CLI 引数パース\n */\n\nimport { parseArgs as nodeParseArgs } from \"node:util\";\nimport { existsSync } from \"node:fs\";\nimport { t, initLocale } from \"../i18n\";\nimport type { AIModelConfig } from \"../harness/ai-model\";\nimport { parseModelConfig } from \"../cli/config-helpers\";\n\nexport interface ApplyFixConfig {\n instructionPath: string;\n reportPath: string;\n /** AIモデル設定 */\n aiModelConfig?: AIModelConfig;\n}\n\nexport async function parseArgs(): Promise<ApplyFixConfig> {\n const { values } = nodeParseArgs({\n options: {\n instruction: { type: \"string\" },\n report: { type: \"string\" },\n model: { type: \"string\" },\n \"model-provider\": { type: \"string\" },\n \"model-base-url\": { type: \"string\" },\n \"model-review\": { type: \"string\" },\n locale: { type: \"string\" },\n },\n strict: true,\n });\n\n initLocale(values.locale);\n\n if (!values.instruction) {\n throw new Error(t(\"cli.instructionRequired\"));\n }\n if (!values.report) {\n throw new Error(t(\"cli.reportRequired\"));\n }\n\n if (!existsSync(values.instruction)) {\n throw new Error(`Instruction file not found: ${values.instruction}`);\n }\n if (!existsSync(values.report)) {\n throw new Error(`Report file not found: ${values.report}`);\n }\n\n const aiModelConfig = parseModelConfig(values);\n\n return {\n instructionPath: values.instruction,\n reportPath: values.report,\n aiModelConfig,\n };\n}\n","/**\n * report-parser — レポート Markdown から修正提案を抽出する\n *\n * AI Agent Summary セクションをパースし、各失敗ステップの修正情報を抽出。\n * フォールバックとして Failed Step Diagnostics セクションからも情報を取得。\n */\n\nexport interface ExtractedSuggestion {\n stepOrdinal: number;\n description: string;\n error: string;\n category?: string;\n recoveryHint?: string;\n currentSelector?: string;\n yamlFix?: string;\n contextFix?: string;\n suggestedStrategy?: string;\n lastSnapshotPreview?: string;\n}\n\n/**\n * レポート Markdown から修正提案を抽出する。\n * AI Agent Summary セクションを優先的にパースし、存在しない場合は\n * Failed Step Diagnostics から情報を抽出する。\n */\nexport function extractSuggestions(reportContent: string): ExtractedSuggestion[] {\n const suggestions = extractFromAiAgentSummary(reportContent);\n if (suggestions.length > 0) return suggestions;\n\n // フォールバック: Failed Step Diagnostics から抽出\n return extractFromDiagnostics(reportContent);\n}\n\n/**\n * AI Agent Summary セクションから修正提案を抽出する。\n */\nfunction extractFromAiAgentSummary(content: string): ExtractedSuggestion[] {\n const summaryStart = content.indexOf(\"## AI Agent Summary\");\n if (summaryStart === -1) return [];\n\n // セクション終端を探す(次の ## まで)\n const afterSummary = content.slice(summaryStart + \"## AI Agent Summary\".length);\n const nextSection = afterSummary.search(/\\n## [^#]/);\n const summaryContent = nextSection === -1 ? afterSummary : afterSummary.slice(0, nextSection);\n\n const suggestions: ExtractedSuggestion[] = [];\n\n // #### Step #N: description パターンで各ステップを分割\n const stepPattern = /#### Step #(\\d+): (.+)/g;\n let match: RegExpExecArray | null;\n const stepPositions: { ordinal: number; description: string; start: number }[] = [];\n\n while ((match = stepPattern.exec(summaryContent)) !== null) {\n stepPositions.push({\n ordinal: parseInt(match[1], 10),\n description: match[2].trim(),\n start: match.index + match[0].length,\n });\n }\n\n for (let i = 0; i < stepPositions.length; i++) {\n const pos = stepPositions[i];\n const end = i + 1 < stepPositions.length ? stepPositions[i + 1].start : summaryContent.length;\n const stepContent = summaryContent.slice(pos.start, end);\n\n const suggestion: ExtractedSuggestion = {\n stepOrdinal: pos.ordinal,\n description: pos.description,\n error: extractField(stepContent, \"エラー\") ?? \"Unknown\",\n category: extractField(stepContent, \"分類\")?.replace(/`/g, \"\"),\n recoveryHint: extractField(stepContent, \"推奨対応\"),\n yamlFix: extractField(stepContent, \"YAML 修正提案\"),\n contextFix: extractField(stepContent, \"Context 修正提案\"),\n suggestedStrategy: extractField(stepContent, \"推奨戦略\"),\n currentSelector: extractCodeBlock(stepContent, \"現在のセレクタ\"),\n lastSnapshotPreview: extractCodeBlock(stepContent, \"最終スナップショット\"),\n };\n\n suggestions.push(suggestion);\n }\n\n return suggestions;\n}\n\n/**\n * Failed Step Diagnostics セクションから基本情報を抽出する(フォールバック)。\n */\nfunction extractFromDiagnostics(content: string): ExtractedSuggestion[] {\n const diagStart = content.indexOf(\"## Failed Step Diagnostics\");\n if (diagStart === -1) return [];\n\n const afterDiag = content.slice(diagStart);\n const nextSection = afterDiag.search(/\\n## [^#]/);\n const diagContent = nextSection === -1 ? afterDiag : afterDiag.slice(0, nextSection);\n\n // 同一 ordinal の複数セクション(Retry Details + Diagnostics + Error Info)を統合\n const stepPattern = /### Step #(\\d+) — (?:Diagnostics|Error Info|Retry Details)/g;\n let match: RegExpExecArray | null;\n const ordinalContents = new Map<number, string>();\n\n while ((match = stepPattern.exec(diagContent)) !== null) {\n const ordinal = parseInt(match[1], 10);\n const sectionStart = match.index + match[0].length;\n const rest = diagContent.slice(sectionStart);\n const nextStep = rest.search(/\\n### Step #/);\n const sectionContent = nextStep === -1 ? rest : rest.slice(0, nextStep);\n\n const existing = ordinalContents.get(ordinal) ?? \"\";\n ordinalContents.set(ordinal, existing + \"\\n\" + sectionContent);\n }\n\n const suggestions: ExtractedSuggestion[] = [];\n\n for (const [ordinal, stepContent] of ordinalContents) {\n const recoveryHint = extractField(stepContent, \"Recovery Hint\");\n const error = extractField(stepContent, \"Error\") ?? \"Unknown\";\n\n // Step Results セクションから description を取得\n const stepResultPattern = new RegExp(`${ordinal}\\\\. \\\\[FAILED\\\\] (.+?) \\\\(`);\n const descMatch = content.match(stepResultPattern);\n\n suggestions.push({\n stepOrdinal: ordinal,\n description: descMatch?.[1] ?? `Step #${ordinal}`,\n error,\n recoveryHint,\n currentSelector: extractCodeBlock(stepContent, \"Step Action\"),\n });\n }\n\n return suggestions;\n}\n\n/**\n * `- **label**: value` または `**label**: value` パターンからフィールド値を抽出する。\n */\nfunction extractField(content: string, label: string): string | undefined {\n // `- **label**: value` パターン(AI Agent Summary 形式)\n const listPattern = new RegExp(`- \\\\*\\\\*${escapeRegex(label)}\\\\*\\\\*: (.+?)(?:\\n|$)`);\n const listMatch = content.match(listPattern);\n if (listMatch) return listMatch[1].trim();\n\n // `**label**: value` パターン(Diagnostics 形式)\n const boldPattern = new RegExp(`\\\\*\\\\*${escapeRegex(label)}\\\\*\\\\*: (.+?)(?:\\n|$)`);\n const boldMatch = content.match(boldPattern);\n return boldMatch?.[1]?.trim();\n}\n\n/**\n * ラベルの後に続くコードブロック(```...```)を抽出する。\n */\nfunction extractCodeBlock(content: string, label: string): string | undefined {\n const labelIdx = content.indexOf(`**${label}**`);\n if (labelIdx === -1) return undefined;\n\n const afterLabel = content.slice(labelIdx);\n const codeStart = afterLabel.indexOf(\"```\");\n if (codeStart === -1) return undefined;\n\n const codeContentStart = afterLabel.indexOf(\"\\n\", codeStart) + 1;\n const codeEnd = afterLabel.indexOf(\"```\", codeContentStart);\n if (codeEnd === -1) return undefined;\n\n return afterLabel.slice(codeContentStart, codeEnd).trim();\n}\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n","/**\n * yaml-patcher — AI を使って instruction YAML を修正する\n *\n * 修正提案と現在の YAML を AI に渡し、パッチ済み YAML を生成する。\n * yaml パッケージの Document API でパースしバリデーションを行う。\n */\n\nimport { parse, stringify } from \"yaml\";\nimport { getModel, trackedGenerateText } from \"../harness/ai-model\";\nimport { ParsedInstructionSchema } from \"../schemas/instruction-schema\";\nimport { spinner } from \"../cli/prompts\";\nimport type { ExtractedSuggestion } from \"./report-parser\";\n\nexport interface PatchResult {\n success: boolean;\n patchedYaml: string;\n error?: string;\n}\n\n/**\n * AI を使って YAML を修正する。\n * 修正後の YAML が ParsedInstructionSchema でバリデーションを通ることを確認。\n */\nexport async function generatePatch(\n originalYaml: string,\n suggestion: ExtractedSuggestion,\n): Promise<PatchResult> {\n const s = spinner();\n s.start(`Step #${suggestion.stepOrdinal} のパッチを生成中...`);\n\n try {\n const { system, userPrompt } = buildPatchMessages(originalYaml, suggestion);\n\n const { text } = await trackedGenerateText(\"review\", {\n model: getModel(\"review\"),\n messages: [\n {\n role: \"system\",\n content: system,\n providerOptions: {\n anthropic: { cacheControl: { type: \"ephemeral\" } },\n },\n },\n { role: \"user\", content: userPrompt },\n ],\n temperature: 0,\n });\n\n // AI のレスポンスから YAML 部分を抽出\n const patchedYaml = extractYamlFromResponse(text);\n if (!patchedYaml) {\n s.stop(\"パッチ生成失敗\");\n return {\n success: false,\n patchedYaml: originalYaml,\n error: \"AI レスポンスから YAML を抽出できませんでした\",\n };\n }\n\n // バリデーション\n const validationError = validateYaml(patchedYaml);\n if (validationError) {\n s.stop(\"バリデーション失敗\");\n return {\n success: false,\n patchedYaml: originalYaml,\n error: `バリデーションエラー: ${validationError}`,\n };\n }\n\n s.stop(\"パッチ生成完了\");\n return { success: true, patchedYaml };\n } catch (error) {\n s.stop(\"パッチ生成失敗\");\n return {\n success: false,\n patchedYaml: originalYaml,\n error: error instanceof Error ? error.message : String(error),\n };\n }\n}\n\n/** 静的な YAML パッチ用システムプロンプト(キャッシュ対象) */\nconst PATCH_SYSTEM_PROMPT = [\n \"あなたは instruction YAML のパッチ生成ツールです。\",\n \"以下の修正提案に基づいて、YAML を修正してください。\",\n \"\",\n \"## ルール\",\n \"- 修正対象ステップ以外は一切変更しないでください\",\n \"- YAML のフォーマット(インデント、引用符スタイル、コメント位置)をできる限り維持してください\",\n \"- 修正は最小限にしてください\",\n \"- 出力は YAML のみ(```yaml ... ``` で囲んでください)\",\n \"- 説明やコメントは不要です\",\n].join(\"\\n\");\n\nfunction buildPatchMessages(originalYaml: string, suggestion: ExtractedSuggestion): { system: string; userPrompt: string } {\n const parts: string[] = [\n \"## 修正対象\",\n `- ステップ番号: ${suggestion.stepOrdinal}`,\n `- 説明: ${suggestion.description}`,\n `- エラー: ${suggestion.error}`,\n ];\n\n if (suggestion.category) {\n parts.push(`- エラー分類: ${suggestion.category}`);\n }\n if (suggestion.recoveryHint) {\n parts.push(`- 推奨対応: ${suggestion.recoveryHint}`);\n }\n if (suggestion.yamlFix) {\n parts.push(`- 修正提案: ${suggestion.yamlFix}`);\n }\n if (suggestion.currentSelector) {\n parts.push(`- 現在のセレクタ: ${suggestion.currentSelector}`);\n }\n if (suggestion.lastSnapshotPreview) {\n parts.push(\"\");\n parts.push(\"## 最終スナップショット(ページの現在の状態)\");\n parts.push(\"```\");\n parts.push(suggestion.lastSnapshotPreview);\n parts.push(\"```\");\n }\n\n parts.push(\"\");\n parts.push(\"## 現在の YAML\");\n parts.push(\"```yaml\");\n parts.push(originalYaml);\n parts.push(\"```\");\n\n return { system: PATCH_SYSTEM_PROMPT, userPrompt: parts.join(\"\\n\") };\n}\n\n/**\n * AI レスポンスから YAML コードブロックを抽出する。\n */\nfunction extractYamlFromResponse(response: string): string | null {\n // ```yaml ... ``` パターン\n const yamlMatch = response.match(/```ya?ml\\n([\\s\\S]*?)```/);\n if (yamlMatch) return yamlMatch[1].trim();\n\n // ``` ... ``` パターン(言語指定なし)\n const codeMatch = response.match(/```\\n([\\s\\S]*?)```/);\n if (codeMatch) return codeMatch[1].trim();\n\n // コードブロックなし — レスポンス全体が YAML の可能性\n try {\n parse(response);\n return response.trim();\n } catch {\n return null;\n }\n}\n\n/**\n * パッチ済み YAML が有効な instruction かバリデーションする。\n */\nfunction validateYaml(yamlContent: string): string | null {\n try {\n const doc = parse(yamlContent);\n ParsedInstructionSchema.parse(doc);\n return null;\n } catch (error) {\n if (error instanceof Error) {\n return error.message.slice(0, 200);\n }\n return String(error);\n }\n}\n"],"mappings":"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","names":[]}
|