@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,543 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
ParsedInstructionSchema,
|
|
4
|
+
initLocale,
|
|
5
|
+
intro,
|
|
6
|
+
log,
|
|
7
|
+
note,
|
|
8
|
+
outro,
|
|
9
|
+
promptConfirm,
|
|
10
|
+
promptSelect,
|
|
11
|
+
promptText,
|
|
12
|
+
t,
|
|
13
|
+
tf
|
|
14
|
+
} from "./chunk-VNQYQSMI.js";
|
|
15
|
+
|
|
16
|
+
// src/compose/config.ts
|
|
17
|
+
import { parseArgs } from "util";
|
|
18
|
+
function parseComposeArgs() {
|
|
19
|
+
const { values } = parseArgs({
|
|
20
|
+
options: {
|
|
21
|
+
"branch-on": { type: "string" },
|
|
22
|
+
case: { type: "string", multiple: true },
|
|
23
|
+
goal: { type: "string" },
|
|
24
|
+
output: { type: "string" },
|
|
25
|
+
locale: { type: "string" }
|
|
26
|
+
},
|
|
27
|
+
strict: false
|
|
28
|
+
});
|
|
29
|
+
const output = values["output"];
|
|
30
|
+
if (!output) {
|
|
31
|
+
console.error("--output is required");
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
const caseArgs = values["case"] ?? [];
|
|
35
|
+
const cases = caseArgs.map((c) => {
|
|
36
|
+
const colonIdx = c.indexOf(":");
|
|
37
|
+
if (colonIdx === -1) {
|
|
38
|
+
console.error(`Invalid --case format: "${c}" (expected match:yamlPath)`);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
match: c.slice(0, colonIdx),
|
|
43
|
+
yamlPath: c.slice(colonIdx + 1)
|
|
44
|
+
};
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
branchOn: values["branch-on"],
|
|
48
|
+
cases,
|
|
49
|
+
goal: values["goal"],
|
|
50
|
+
output,
|
|
51
|
+
locale: values["locale"]
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// src/compose/composer.ts
|
|
56
|
+
import { readFile, writeFile } from "fs/promises";
|
|
57
|
+
import { parse, stringify } from "yaml";
|
|
58
|
+
async function loadCase(match, yamlPath) {
|
|
59
|
+
const raw = await readFile(yamlPath, "utf-8");
|
|
60
|
+
const doc = parse(raw);
|
|
61
|
+
const instruction = ParsedInstructionSchema.parse(doc);
|
|
62
|
+
return { match, yamlPath, instruction };
|
|
63
|
+
}
|
|
64
|
+
function normalizeVarDef(def) {
|
|
65
|
+
return {
|
|
66
|
+
source: def.source,
|
|
67
|
+
required: def.required ?? true,
|
|
68
|
+
sensitive: def.sensitive ?? false,
|
|
69
|
+
...def.description !== void 0 ? { description: def.description } : {},
|
|
70
|
+
...def.value !== void 0 ? { value: def.value } : {},
|
|
71
|
+
...def.expression !== void 0 ? { expression: def.expression } : {},
|
|
72
|
+
...def.envKey !== void 0 ? { envKey: def.envKey } : {}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
function varDefsEqual(a, b) {
|
|
76
|
+
const na = normalizeVarDef(a);
|
|
77
|
+
const nb = normalizeVarDef(b);
|
|
78
|
+
return na.source === nb.source && na.required === nb.required && na.sensitive === nb.sensitive && na.description === nb.description && na.value === nb.value && na.expression === nb.expression && na.envKey === nb.envKey;
|
|
79
|
+
}
|
|
80
|
+
function analyzeVariables(cases) {
|
|
81
|
+
const varMap = /* @__PURE__ */ new Map();
|
|
82
|
+
for (const lc of cases) {
|
|
83
|
+
if (!lc.instruction.variables) continue;
|
|
84
|
+
for (const [name, def] of Object.entries(lc.instruction.variables)) {
|
|
85
|
+
const existing = varMap.get(name) ?? [];
|
|
86
|
+
existing.push({ caseName: lc.match, def });
|
|
87
|
+
varMap.set(name, existing);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
const shared = {};
|
|
91
|
+
const conflicts = [];
|
|
92
|
+
const caseSpecific = [];
|
|
93
|
+
for (const [name, entries] of varMap) {
|
|
94
|
+
if (entries.length === 1) {
|
|
95
|
+
caseSpecific.push({ caseName: entries[0].caseName, name, def: entries[0].def });
|
|
96
|
+
} else if (entries.length === cases.length) {
|
|
97
|
+
const allEqual = entries.every((e) => varDefsEqual(e.def, entries[0].def));
|
|
98
|
+
if (allEqual) {
|
|
99
|
+
shared[name] = entries[0].def;
|
|
100
|
+
} else {
|
|
101
|
+
conflicts.push({ name, definitions: entries });
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
conflicts.push({ name, definitions: entries });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return { shared, conflicts, caseSpecific };
|
|
108
|
+
}
|
|
109
|
+
function mergeVariables(analysis, resolutions, branchOn, caseMatches) {
|
|
110
|
+
const merged = {};
|
|
111
|
+
for (const [name, def] of Object.entries(analysis.shared)) {
|
|
112
|
+
merged[name] = def;
|
|
113
|
+
}
|
|
114
|
+
for (const conflict of analysis.conflicts) {
|
|
115
|
+
const resolved = resolutions.get(conflict.name);
|
|
116
|
+
if (resolved) {
|
|
117
|
+
merged[conflict.name] = resolved;
|
|
118
|
+
} else {
|
|
119
|
+
merged[conflict.name] = conflict.definitions[0].def;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
for (const cs of analysis.caseSpecific) {
|
|
123
|
+
merged[cs.name] = cs.def;
|
|
124
|
+
}
|
|
125
|
+
if (!(branchOn in merged)) {
|
|
126
|
+
merged[branchOn] = {
|
|
127
|
+
source: "prompt",
|
|
128
|
+
description: `\u5206\u5C90\u6761\u4EF6 (${caseMatches.join(", ")})`,
|
|
129
|
+
required: true,
|
|
130
|
+
sensitive: false
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return merged;
|
|
134
|
+
}
|
|
135
|
+
function diffSettings(cases) {
|
|
136
|
+
if (cases.length <= 1) return [];
|
|
137
|
+
const diffs = [];
|
|
138
|
+
const keys = ["baseUrl", "defaultTimeout", "pauseBetweenSteps", "stopOnError"];
|
|
139
|
+
for (const key of keys) {
|
|
140
|
+
const values = cases.map((lc) => ({
|
|
141
|
+
caseName: lc.match,
|
|
142
|
+
value: lc.instruction.settings[key]
|
|
143
|
+
}));
|
|
144
|
+
const allSame = values.every((v) => v.value === values[0].value);
|
|
145
|
+
if (!allSame) {
|
|
146
|
+
diffs.push({ key, values });
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return diffs;
|
|
150
|
+
}
|
|
151
|
+
function buildComposedInstruction(state) {
|
|
152
|
+
const base = state.cases[0].instruction;
|
|
153
|
+
const branchStep = {
|
|
154
|
+
ordinal: 0,
|
|
155
|
+
description: state.goal ?? `${state.branchOn} \u306B\u5FDC\u3058\u305F\u5206\u5C90`,
|
|
156
|
+
action: { type: "memory" },
|
|
157
|
+
url: state.metadata.startUrl,
|
|
158
|
+
riskLevel: "low",
|
|
159
|
+
requiresConfirmation: false,
|
|
160
|
+
branches: {
|
|
161
|
+
value: `{{${state.branchOn}}}`,
|
|
162
|
+
cases: state.cases.map((lc) => ({
|
|
163
|
+
match: lc.match,
|
|
164
|
+
steps: lc.instruction.steps.map((s, i) => ({
|
|
165
|
+
...s,
|
|
166
|
+
ordinal: i
|
|
167
|
+
}))
|
|
168
|
+
}))
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
return {
|
|
172
|
+
title: state.title,
|
|
173
|
+
...base.naturalLanguageSummary ? { naturalLanguageSummary: base.naturalLanguageSummary } : {},
|
|
174
|
+
settings: state.settings,
|
|
175
|
+
metadata: {
|
|
176
|
+
...state.metadata,
|
|
177
|
+
totalSteps: 1,
|
|
178
|
+
generatedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
179
|
+
},
|
|
180
|
+
steps: [branchStep],
|
|
181
|
+
variables: state.mergedVariables
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
async function validateAndWriteYaml(composed, outputPath) {
|
|
185
|
+
ParsedInstructionSchema.parse(composed);
|
|
186
|
+
const yamlContent = stringify(composed, { lineWidth: 120 });
|
|
187
|
+
await writeFile(outputPath, yamlContent, "utf-8");
|
|
188
|
+
return outputPath;
|
|
189
|
+
}
|
|
190
|
+
function formatVariableDef(def) {
|
|
191
|
+
const parts = [`source: ${def.source}`];
|
|
192
|
+
if (def.value !== void 0) parts.push(`value: "${def.value}"`);
|
|
193
|
+
if (def.envKey !== void 0) parts.push(`envKey: ${def.envKey}`);
|
|
194
|
+
if (def.expression !== void 0) parts.push(`expression: ${def.expression}`);
|
|
195
|
+
return parts.join(", ");
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// src/compose/interactive.ts
|
|
199
|
+
async function gatherBranchVariable() {
|
|
200
|
+
return promptText(t("compose.branchVarPrompt"), {
|
|
201
|
+
validate: (v) => !v?.trim() ? t("compose.branchVarPrompt") : void 0
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
async function gatherCasesInteractively() {
|
|
205
|
+
const cases = [];
|
|
206
|
+
while (cases.length < 2 || await promptConfirm(t("compose.addAnotherCase"), false)) {
|
|
207
|
+
const yamlPath = await promptText(t("compose.yamlPathPrompt"), {
|
|
208
|
+
validate: (v) => !v?.trim() ? t("compose.yamlPathPrompt") : void 0
|
|
209
|
+
});
|
|
210
|
+
const match = await promptText(t("compose.matchValuePrompt"), {
|
|
211
|
+
validate: (v) => !v?.trim() ? t("compose.matchValuePrompt") : void 0
|
|
212
|
+
});
|
|
213
|
+
const loaded = await loadCase(match, yamlPath);
|
|
214
|
+
const varCount = loaded.instruction.variables ? Object.keys(loaded.instruction.variables).length : 0;
|
|
215
|
+
log.success(
|
|
216
|
+
tf("compose.caseLoaded", {
|
|
217
|
+
title: loaded.instruction.title,
|
|
218
|
+
steps: loaded.instruction.steps.length,
|
|
219
|
+
vars: varCount
|
|
220
|
+
})
|
|
221
|
+
);
|
|
222
|
+
cases.push(loaded);
|
|
223
|
+
}
|
|
224
|
+
return cases;
|
|
225
|
+
}
|
|
226
|
+
async function loadProvidedCases(caseDefs) {
|
|
227
|
+
const cases = [];
|
|
228
|
+
for (const c of caseDefs) {
|
|
229
|
+
const loaded = await loadCase(c.match, c.yamlPath);
|
|
230
|
+
const varCount = loaded.instruction.variables ? Object.keys(loaded.instruction.variables).length : 0;
|
|
231
|
+
log.success(
|
|
232
|
+
tf("compose.caseLoaded", {
|
|
233
|
+
title: loaded.instruction.title,
|
|
234
|
+
steps: loaded.instruction.steps.length,
|
|
235
|
+
vars: varCount
|
|
236
|
+
})
|
|
237
|
+
);
|
|
238
|
+
cases.push(loaded);
|
|
239
|
+
}
|
|
240
|
+
return cases;
|
|
241
|
+
}
|
|
242
|
+
async function gatherGoal(defaultGoal) {
|
|
243
|
+
const goal = await promptText(t("compose.goalPrompt"), {
|
|
244
|
+
initialValue: defaultGoal,
|
|
245
|
+
placeholder: defaultGoal
|
|
246
|
+
});
|
|
247
|
+
return goal.trim() || void 0;
|
|
248
|
+
}
|
|
249
|
+
function displayVariableMergePreview(analysis, branchOn) {
|
|
250
|
+
const lines = [];
|
|
251
|
+
const sharedEntries = Object.entries(analysis.shared);
|
|
252
|
+
if (sharedEntries.length > 0) {
|
|
253
|
+
lines.push(t("compose.sharedVariables"));
|
|
254
|
+
for (const [name, def] of sharedEntries) {
|
|
255
|
+
lines.push(` ${name} \u2192 ${formatVariableDef(def)}`);
|
|
256
|
+
}
|
|
257
|
+
lines.push("");
|
|
258
|
+
}
|
|
259
|
+
if (analysis.conflicts.length > 0) {
|
|
260
|
+
lines.push(t("compose.conflictingVariables"));
|
|
261
|
+
for (const conflict of analysis.conflicts) {
|
|
262
|
+
lines.push(` ${conflict.name}`);
|
|
263
|
+
for (const d of conflict.definitions) {
|
|
264
|
+
lines.push(` [${d.caseName}] ${formatVariableDef(d.def)}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
lines.push("");
|
|
268
|
+
}
|
|
269
|
+
if (analysis.caseSpecific.length > 0) {
|
|
270
|
+
lines.push(t("compose.caseSpecificVariables"));
|
|
271
|
+
for (const cs of analysis.caseSpecific) {
|
|
272
|
+
lines.push(` [${cs.caseName}] ${cs.name} \u2192 ${formatVariableDef(cs.def)}`);
|
|
273
|
+
}
|
|
274
|
+
lines.push("");
|
|
275
|
+
}
|
|
276
|
+
lines.push(t("compose.branchVariable"));
|
|
277
|
+
lines.push(` ${branchOn} \u2192 source: prompt`);
|
|
278
|
+
note(lines.join("\n"), t("compose.variableMergePreview"));
|
|
279
|
+
}
|
|
280
|
+
async function resolveVariableConflicts(analysis) {
|
|
281
|
+
const resolutions = /* @__PURE__ */ new Map();
|
|
282
|
+
for (const conflict of analysis.conflicts) {
|
|
283
|
+
const options = conflict.definitions.map((d) => ({
|
|
284
|
+
value: d.caseName,
|
|
285
|
+
label: tf("compose.useFromCase", { case: d.caseName }),
|
|
286
|
+
hint: formatVariableDef(d.def)
|
|
287
|
+
}));
|
|
288
|
+
const chosen = await promptSelect(
|
|
289
|
+
tf("compose.conflictPrompt", { name: conflict.name }),
|
|
290
|
+
options
|
|
291
|
+
);
|
|
292
|
+
const selected = conflict.definitions.find((d) => d.caseName === chosen);
|
|
293
|
+
if (selected) {
|
|
294
|
+
resolutions.set(conflict.name, selected.def);
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return resolutions;
|
|
298
|
+
}
|
|
299
|
+
async function resolveSettings(diffs, cases, baseSettings) {
|
|
300
|
+
const settings = { ...baseSettings };
|
|
301
|
+
for (const diff of diffs) {
|
|
302
|
+
const options = diff.values.map((v) => ({
|
|
303
|
+
value: v.caseName,
|
|
304
|
+
label: tf("compose.useFromCase", { case: v.caseName }),
|
|
305
|
+
hint: `${diff.key} = ${JSON.stringify(v.value)}`
|
|
306
|
+
}));
|
|
307
|
+
const chosen = await promptSelect(
|
|
308
|
+
tf("compose.settingsDiffPrompt", { key: diff.key }),
|
|
309
|
+
options
|
|
310
|
+
);
|
|
311
|
+
const selectedCase = cases.find((c) => c.match === chosen);
|
|
312
|
+
if (selectedCase) {
|
|
313
|
+
settings[diff.key] = selectedCase.instruction.settings[diff.key];
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return settings;
|
|
317
|
+
}
|
|
318
|
+
function displayPreview(state) {
|
|
319
|
+
const lines = [];
|
|
320
|
+
lines.push(`Title: ${state.title}`);
|
|
321
|
+
lines.push(`Branch: {{${state.branchOn}}}`);
|
|
322
|
+
lines.push(
|
|
323
|
+
`Cases: ${state.cases.map((c) => `${c.match} (${c.instruction.steps.length} steps)`).join(", ")}`
|
|
324
|
+
);
|
|
325
|
+
lines.push("");
|
|
326
|
+
const varEntries = Object.entries(state.mergedVariables);
|
|
327
|
+
lines.push(`Variables (${varEntries.length}):`);
|
|
328
|
+
for (const [name, def] of varEntries) {
|
|
329
|
+
const isBranch = name === state.branchOn ? " (branch)" : "";
|
|
330
|
+
lines.push(` ${name} \u2192 ${formatVariableDef(def)}${isBranch}`);
|
|
331
|
+
}
|
|
332
|
+
lines.push("");
|
|
333
|
+
lines.push("Settings:");
|
|
334
|
+
lines.push(` baseUrl: ${state.settings.baseUrl}`);
|
|
335
|
+
lines.push(` defaultTimeout: ${state.settings.defaultTimeout}`);
|
|
336
|
+
note(lines.join("\n"), t("compose.composedPreview"));
|
|
337
|
+
}
|
|
338
|
+
async function editLoop(state) {
|
|
339
|
+
while (true) {
|
|
340
|
+
displayPreview(state);
|
|
341
|
+
const action = await promptSelect(t("compose.selectAction"), [
|
|
342
|
+
{ value: "confirm", label: t("compose.confirm"), hint: t("compose.confirmHint") },
|
|
343
|
+
{ value: "editBranch", label: t("compose.editBranch") },
|
|
344
|
+
{ value: "editMatches", label: t("compose.editMatches") },
|
|
345
|
+
{ value: "editVariables", label: t("compose.editVariables") },
|
|
346
|
+
{ value: "editTitle", label: t("compose.editTitle") }
|
|
347
|
+
]);
|
|
348
|
+
if (action === "confirm") break;
|
|
349
|
+
switch (action) {
|
|
350
|
+
case "editBranch":
|
|
351
|
+
await handleEditBranch(state);
|
|
352
|
+
break;
|
|
353
|
+
case "editMatches":
|
|
354
|
+
await handleEditMatches(state);
|
|
355
|
+
break;
|
|
356
|
+
case "editVariables":
|
|
357
|
+
await handleEditVariables(state);
|
|
358
|
+
break;
|
|
359
|
+
case "editTitle":
|
|
360
|
+
await handleEditTitle(state);
|
|
361
|
+
break;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
async function handleEditBranch(state) {
|
|
366
|
+
const oldBranch = state.branchOn;
|
|
367
|
+
const newBranch = await promptText(t("compose.newBranchVar"), {
|
|
368
|
+
initialValue: oldBranch,
|
|
369
|
+
validate: (v) => !v?.trim() ? t("compose.branchVarPrompt") : void 0
|
|
370
|
+
});
|
|
371
|
+
if (newBranch !== oldBranch) {
|
|
372
|
+
const branchDef = state.mergedVariables[oldBranch];
|
|
373
|
+
if (branchDef) {
|
|
374
|
+
delete state.mergedVariables[oldBranch];
|
|
375
|
+
state.mergedVariables[newBranch] = branchDef;
|
|
376
|
+
}
|
|
377
|
+
state.branchOn = newBranch;
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
async function handleEditMatches(state) {
|
|
381
|
+
const options = state.cases.map((c) => ({
|
|
382
|
+
value: c.match,
|
|
383
|
+
label: c.match,
|
|
384
|
+
hint: c.instruction.title
|
|
385
|
+
}));
|
|
386
|
+
const selected = await promptSelect(t("compose.selectCase"), options);
|
|
387
|
+
const caseObj = state.cases.find((c) => c.match === selected);
|
|
388
|
+
if (!caseObj) return;
|
|
389
|
+
const newMatch = await promptText(t("compose.newMatchValue"), {
|
|
390
|
+
initialValue: caseObj.match,
|
|
391
|
+
validate: (v) => !v?.trim() ? t("compose.matchValuePrompt") : void 0
|
|
392
|
+
});
|
|
393
|
+
caseObj.match = newMatch;
|
|
394
|
+
const branchDef = state.mergedVariables[state.branchOn];
|
|
395
|
+
if (branchDef) {
|
|
396
|
+
branchDef.description = `\u5206\u5C90\u6761\u4EF6 (${state.cases.map((c) => c.match).join(", ")})`;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
async function handleEditVariables(state) {
|
|
400
|
+
const action = await promptSelect(t("compose.editVarAction"), [
|
|
401
|
+
{ value: "delete", label: t("compose.deleteVar") },
|
|
402
|
+
{ value: "add", label: t("compose.addVar") },
|
|
403
|
+
{ value: "edit", label: t("compose.editVarDef") }
|
|
404
|
+
]);
|
|
405
|
+
const varNames = Object.keys(state.mergedVariables).filter((n) => n !== state.branchOn);
|
|
406
|
+
switch (action) {
|
|
407
|
+
case "delete": {
|
|
408
|
+
if (varNames.length === 0) return;
|
|
409
|
+
const toDelete = await promptSelect(
|
|
410
|
+
t("compose.selectVar"),
|
|
411
|
+
varNames.map((n) => ({
|
|
412
|
+
value: n,
|
|
413
|
+
label: n,
|
|
414
|
+
hint: formatVariableDef(state.mergedVariables[n])
|
|
415
|
+
}))
|
|
416
|
+
);
|
|
417
|
+
delete state.mergedVariables[toDelete];
|
|
418
|
+
log.success(tf("compose.varDeleted", { name: toDelete }));
|
|
419
|
+
break;
|
|
420
|
+
}
|
|
421
|
+
case "add": {
|
|
422
|
+
const name = await promptText(t("compose.newVarName"), {
|
|
423
|
+
validate: (v) => {
|
|
424
|
+
if (!v?.trim()) return t("compose.newVarName");
|
|
425
|
+
if (v.trim() === state.branchOn)
|
|
426
|
+
return tf("compose.branchVarConflict", { name: v.trim() });
|
|
427
|
+
return void 0;
|
|
428
|
+
}
|
|
429
|
+
});
|
|
430
|
+
const source = await promptSelect(t("compose.newVarSource"), [
|
|
431
|
+
{ value: "prompt", label: "prompt" },
|
|
432
|
+
{ value: "fixed", label: "fixed" },
|
|
433
|
+
{ value: "env", label: "env" },
|
|
434
|
+
{ value: "context", label: "context" },
|
|
435
|
+
{ value: "expression", label: "expression" },
|
|
436
|
+
{ value: "data", label: "data" }
|
|
437
|
+
]);
|
|
438
|
+
const value = await promptText(t("compose.newVarValue"));
|
|
439
|
+
const description = await promptText(t("compose.newVarDescription"));
|
|
440
|
+
state.mergedVariables[name] = {
|
|
441
|
+
source,
|
|
442
|
+
required: true,
|
|
443
|
+
sensitive: false,
|
|
444
|
+
...value.trim() ? { value: value.trim() } : {},
|
|
445
|
+
...description.trim() ? { description: description.trim() } : {}
|
|
446
|
+
};
|
|
447
|
+
log.success(tf("compose.varAdded", { name }));
|
|
448
|
+
break;
|
|
449
|
+
}
|
|
450
|
+
case "edit": {
|
|
451
|
+
if (varNames.length === 0) return;
|
|
452
|
+
const toEdit = await promptSelect(
|
|
453
|
+
t("compose.selectVar"),
|
|
454
|
+
varNames.map((n) => ({
|
|
455
|
+
value: n,
|
|
456
|
+
label: n,
|
|
457
|
+
hint: formatVariableDef(state.mergedVariables[n])
|
|
458
|
+
}))
|
|
459
|
+
);
|
|
460
|
+
const currentDef = state.mergedVariables[toEdit];
|
|
461
|
+
const newSource = await promptSelect(t("compose.newVarSource"), [
|
|
462
|
+
{ value: "prompt", label: "prompt" },
|
|
463
|
+
{ value: "fixed", label: "fixed" },
|
|
464
|
+
{ value: "env", label: "env" },
|
|
465
|
+
{ value: "context", label: "context" },
|
|
466
|
+
{ value: "expression", label: "expression" },
|
|
467
|
+
{ value: "data", label: "data" }
|
|
468
|
+
]);
|
|
469
|
+
const newValue = await promptText(t("compose.newVarValue"), {
|
|
470
|
+
initialValue: currentDef.value ?? ""
|
|
471
|
+
});
|
|
472
|
+
const newDesc = await promptText(t("compose.newVarDescription"), {
|
|
473
|
+
initialValue: currentDef.description ?? ""
|
|
474
|
+
});
|
|
475
|
+
state.mergedVariables[toEdit] = {
|
|
476
|
+
source: newSource,
|
|
477
|
+
required: currentDef.required,
|
|
478
|
+
sensitive: currentDef.sensitive,
|
|
479
|
+
...newValue.trim() ? { value: newValue.trim() } : {},
|
|
480
|
+
...newDesc.trim() ? { description: newDesc.trim() } : {}
|
|
481
|
+
};
|
|
482
|
+
log.success(tf("compose.varUpdated", { name: toEdit }));
|
|
483
|
+
break;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
async function handleEditTitle(state) {
|
|
488
|
+
const newTitle = await promptText(t("compose.newTitle"), {
|
|
489
|
+
initialValue: state.title,
|
|
490
|
+
validate: (v) => !v?.trim() ? t("compose.newTitle") : void 0
|
|
491
|
+
});
|
|
492
|
+
state.title = newTitle;
|
|
493
|
+
state.goal = newTitle;
|
|
494
|
+
state.metadata = { ...state.metadata, goal: newTitle };
|
|
495
|
+
}
|
|
496
|
+
async function buildState(opts) {
|
|
497
|
+
const { branchOn, cases, goal, output } = opts;
|
|
498
|
+
const varAnalysis = analyzeVariables(cases);
|
|
499
|
+
displayVariableMergePreview(varAnalysis, branchOn);
|
|
500
|
+
const resolutions = await resolveVariableConflicts(varAnalysis);
|
|
501
|
+
const settingsDiffs = diffSettings(cases);
|
|
502
|
+
const settings = await resolveSettings(settingsDiffs, cases, cases[0].instruction.settings);
|
|
503
|
+
const mergedVars = mergeVariables(
|
|
504
|
+
varAnalysis,
|
|
505
|
+
resolutions,
|
|
506
|
+
branchOn,
|
|
507
|
+
cases.map((c) => c.match)
|
|
508
|
+
);
|
|
509
|
+
const title = goal ?? cases[0].instruction.title;
|
|
510
|
+
return {
|
|
511
|
+
branchOn,
|
|
512
|
+
cases,
|
|
513
|
+
goal,
|
|
514
|
+
output,
|
|
515
|
+
mergedVariables: mergedVars,
|
|
516
|
+
settings,
|
|
517
|
+
metadata: {
|
|
518
|
+
...cases[0].instruction.metadata,
|
|
519
|
+
goal: goal ?? cases[0].instruction.metadata.goal
|
|
520
|
+
},
|
|
521
|
+
title
|
|
522
|
+
};
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
// src/compose/index.ts
|
|
526
|
+
var config = parseComposeArgs();
|
|
527
|
+
initLocale(config.locale);
|
|
528
|
+
intro(t("compose.title"));
|
|
529
|
+
try {
|
|
530
|
+
const branchOn = config.branchOn ?? await gatherBranchVariable();
|
|
531
|
+
const cases = config.cases.length > 0 ? await loadProvidedCases(config.cases) : await gatherCasesInteractively();
|
|
532
|
+
const goal = config.goal ?? await gatherGoal(cases[0]?.instruction.title);
|
|
533
|
+
const state = await buildState({ branchOn, cases, goal, output: config.output });
|
|
534
|
+
await editLoop(state);
|
|
535
|
+
const composed = buildComposedInstruction(state);
|
|
536
|
+
const outputPath = await validateAndWriteYaml(composed, config.output);
|
|
537
|
+
outro(tf("compose.complete", { path: outputPath }));
|
|
538
|
+
} catch (error) {
|
|
539
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
540
|
+
console.error(`\u5408\u6210\u5931\u6557: ${msg}`);
|
|
541
|
+
process.exit(1);
|
|
542
|
+
}
|
|
543
|
+
//# sourceMappingURL=compose-EHDWVF7N.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/compose/config.ts","../../../src/compose/composer.ts","../../../src/compose/interactive.ts","../../../src/compose/index.ts"],"sourcesContent":["/**\n * compose CLI 引数パース\n *\n * 対話式フローでは全引数を optional に。--output のみ必須。\n * CLI 引数はプリフィルとして使用し、未指定分はプロンプトで収集。\n */\n\nimport { parseArgs } from \"node:util\";\n\nexport interface ComposeConfig {\n /** 分岐条件の変数名(未指定時はプロンプトで収集) */\n branchOn?: string;\n /** \"match:yamlPath\" のペア(未指定時はプロンプトで収集) */\n cases: { match: string; yamlPath: string }[];\n /** 合成後のゴール */\n goal?: string;\n /** 出力先 YAML パス */\n output: string;\n /** ロケール */\n locale?: string;\n}\n\nexport function parseComposeArgs(): ComposeConfig {\n const { values } = parseArgs({\n options: {\n \"branch-on\": { type: \"string\" },\n case: { type: \"string\", multiple: true },\n goal: { type: \"string\" },\n output: { type: \"string\" },\n locale: { type: \"string\" },\n },\n strict: false,\n });\n\n const output = values[\"output\"] as string | undefined;\n if (!output) {\n console.error(\"--output is required\");\n process.exit(1);\n }\n\n const caseArgs = (values[\"case\"] as string[] | undefined) ?? [];\n const cases = caseArgs.map((c) => {\n const colonIdx = c.indexOf(\":\");\n if (colonIdx === -1) {\n console.error(`Invalid --case format: \"${c}\" (expected match:yamlPath)`);\n process.exit(1);\n }\n return {\n match: c.slice(0, colonIdx),\n yamlPath: c.slice(colonIdx + 1),\n };\n });\n\n return {\n branchOn: values[\"branch-on\"] as string | undefined,\n cases,\n goal: values[\"goal\"] as string | undefined,\n output,\n locale: values[\"locale\"] as string | undefined,\n };\n}\n","/**\n * composer — 複数の指示書 YAML を1つの分岐付き指示書に合成する純粋関数群\n */\n\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { parse, stringify } from \"yaml\";\nimport { ParsedInstructionSchema, VariableDefinitionSchema } from \"../schemas/instruction-schema\";\nimport type { z } from \"zod\";\n\n// ── 型定義 ──\n\nexport type ParsedInstruction = z.infer<typeof ParsedInstructionSchema>;\nexport type VariableDefinition = z.infer<typeof VariableDefinitionSchema>;\n\nexport interface LoadedCase {\n match: string;\n yamlPath: string;\n instruction: ParsedInstruction;\n}\n\nexport interface VariableConflict {\n name: string;\n definitions: { caseName: string; def: VariableDefinition }[];\n}\n\nexport interface VariableMergeResult {\n /** 全ケースで定義一致の変数 */\n shared: Record<string, VariableDefinition>;\n /** ケース間で定義が異なる変数 */\n conflicts: VariableConflict[];\n /** 特定ケースにのみ存在する変数 */\n caseSpecific: { caseName: string; name: string; def: VariableDefinition }[];\n}\n\nexport interface SettingsDiff {\n key: string;\n values: { caseName: string; value: unknown }[];\n}\n\nexport interface CompositionState {\n branchOn: string;\n cases: LoadedCase[];\n goal?: string;\n output: string;\n mergedVariables: Record<string, VariableDefinition>;\n settings: ParsedInstruction[\"settings\"];\n metadata: ParsedInstruction[\"metadata\"];\n title: string;\n}\n\n// ── 純粋関数 ──\n\n/**\n * 単一ケースの読み込み・バリデーション\n */\nexport async function loadCase(match: string, yamlPath: string): Promise<LoadedCase> {\n const raw = await readFile(yamlPath, \"utf-8\");\n const doc = parse(raw);\n const instruction = ParsedInstructionSchema.parse(doc);\n return { match, yamlPath, instruction };\n}\n\n/**\n * VariableDefinition を正規化して比較用にする。\n * Zod のデフォルト値(required: true, sensitive: false)を埋めた上でフィールド単位比較。\n */\nfunction normalizeVarDef(def: VariableDefinition): VariableDefinition {\n return {\n source: def.source,\n required: def.required ?? true,\n sensitive: def.sensitive ?? false,\n ...(def.description !== undefined ? { description: def.description } : {}),\n ...(def.value !== undefined ? { value: def.value } : {}),\n ...(def.expression !== undefined ? { expression: def.expression } : {}),\n ...(def.envKey !== undefined ? { envKey: def.envKey } : {}),\n };\n}\n\nfunction varDefsEqual(a: VariableDefinition, b: VariableDefinition): boolean {\n const na = normalizeVarDef(a);\n const nb = normalizeVarDef(b);\n return (\n na.source === nb.source &&\n na.required === nb.required &&\n na.sensitive === nb.sensitive &&\n na.description === nb.description &&\n na.value === nb.value &&\n na.expression === nb.expression &&\n na.envKey === nb.envKey\n );\n}\n\n/**\n * 変数を分析(共通/競合/ケース固有に分類)\n */\nexport function analyzeVariables(cases: LoadedCase[]): VariableMergeResult {\n // 各変数名がどのケースに定義されているか収集\n const varMap = new Map<string, { caseName: string; def: VariableDefinition }[]>();\n for (const lc of cases) {\n if (!lc.instruction.variables) continue;\n for (const [name, def] of Object.entries(lc.instruction.variables)) {\n const existing = varMap.get(name) ?? [];\n existing.push({ caseName: lc.match, def });\n varMap.set(name, existing);\n }\n }\n\n const shared: Record<string, VariableDefinition> = {};\n const conflicts: VariableConflict[] = [];\n const caseSpecific: { caseName: string; name: string; def: VariableDefinition }[] = [];\n\n for (const [name, entries] of varMap) {\n if (entries.length === 1) {\n // 1つのケースにのみ存在\n caseSpecific.push({ caseName: entries[0].caseName, name, def: entries[0].def });\n } else if (entries.length === cases.length) {\n // 全ケースに存在 → 定義が一致するか確認\n const allEqual = entries.every((e) => varDefsEqual(e.def, entries[0].def));\n if (allEqual) {\n shared[name] = entries[0].def;\n } else {\n conflicts.push({ name, definitions: entries });\n }\n } else {\n // 一部のケースにのみ存在(2ケース以上だが全ケースではない)\n // これも競合として扱う\n conflicts.push({ name, definitions: entries });\n }\n }\n\n return { shared, conflicts, caseSpecific };\n}\n\n/**\n * 競合解決マップ付きで変数をマージ。\n * resolutions: 競合変数名 → 採用する定義のマップ\n */\nexport function mergeVariables(\n analysis: VariableMergeResult,\n resolutions: Map<string, VariableDefinition>,\n branchOn: string,\n caseMatches: string[],\n): Record<string, VariableDefinition> {\n const merged: Record<string, VariableDefinition> = {};\n\n // 共通変数\n for (const [name, def] of Object.entries(analysis.shared)) {\n merged[name] = def;\n }\n\n // 競合変数(解決マップから採用)\n for (const conflict of analysis.conflicts) {\n const resolved = resolutions.get(conflict.name);\n if (resolved) {\n merged[conflict.name] = resolved;\n } else {\n // 解決がない場合は最初のケースの定義を使用\n merged[conflict.name] = conflict.definitions[0].def;\n }\n }\n\n // ケース固有変数\n for (const cs of analysis.caseSpecific) {\n merged[cs.name] = cs.def;\n }\n\n // 分岐変数を追加(まだ含まれていなければ)\n if (!(branchOn in merged)) {\n merged[branchOn] = {\n source: \"prompt\",\n description: `分岐条件 (${caseMatches.join(\", \")})`,\n required: true,\n sensitive: false,\n };\n }\n\n return merged;\n}\n\n/**\n * Settings の差分検出。全ケースで同じ値なら空配列。\n */\nexport function diffSettings(cases: LoadedCase[]): SettingsDiff[] {\n if (cases.length <= 1) return [];\n\n const diffs: SettingsDiff[] = [];\n const keys = [\"baseUrl\", \"defaultTimeout\", \"pauseBetweenSteps\", \"stopOnError\"] as const;\n\n for (const key of keys) {\n const values = cases.map((lc) => ({\n caseName: lc.match,\n value: lc.instruction.settings[key],\n }));\n\n const allSame = values.every((v) => v.value === values[0].value);\n if (!allSame) {\n diffs.push({ key, values });\n }\n }\n\n return diffs;\n}\n\n/**\n * 合成済み instruction オブジェクト構築(I/O なし)\n */\nexport function buildComposedInstruction(state: CompositionState): Record<string, unknown> {\n const base = state.cases[0].instruction;\n\n const branchStep = {\n ordinal: 0,\n description: state.goal ?? `${state.branchOn} に応じた分岐`,\n action: { type: \"memory\" },\n url: state.metadata.startUrl,\n riskLevel: \"low\",\n requiresConfirmation: false,\n branches: {\n value: `{{${state.branchOn}}}`,\n cases: state.cases.map((lc) => ({\n match: lc.match,\n steps: lc.instruction.steps.map((s, i) => ({\n ...s,\n ordinal: i,\n })),\n })),\n },\n };\n\n return {\n title: state.title,\n ...(base.naturalLanguageSummary ? { naturalLanguageSummary: base.naturalLanguageSummary } : {}),\n settings: state.settings,\n metadata: {\n ...state.metadata,\n totalSteps: 1,\n generatedAt: new Date().toISOString(),\n },\n steps: [branchStep],\n variables: state.mergedVariables,\n };\n}\n\n/**\n * Zod バリデーション + YAML 書き出し\n */\nexport async function validateAndWriteYaml(\n composed: Record<string, unknown>,\n outputPath: string,\n): Promise<string> {\n ParsedInstructionSchema.parse(composed);\n const yamlContent = stringify(composed, { lineWidth: 120 });\n await writeFile(outputPath, yamlContent, \"utf-8\");\n return outputPath;\n}\n\n/**\n * 変数定義の表示文字列を生成\n */\nexport function formatVariableDef(def: VariableDefinition): string {\n const parts = [`source: ${def.source}`];\n if (def.value !== undefined) parts.push(`value: \"${def.value}\"`);\n if (def.envKey !== undefined) parts.push(`envKey: ${def.envKey}`);\n if (def.expression !== undefined) parts.push(`expression: ${def.expression}`);\n return parts.join(\", \");\n}\n","/**\n * compose/interactive — 対話ロジック(収集・競合解決・プレビュー・編集ループ)\n *\n * composer.ts の純粋関数を呼び出しつつ、@clack/prompts でユーザーと対話する。\n */\n\nimport { t, tf } from \"../i18n\";\nimport { log, note, promptConfirm, promptSelect, promptText } from \"../cli/prompts\";\nimport type {\n CompositionState,\n LoadedCase,\n VariableConflict,\n VariableDefinition,\n VariableMergeResult,\n SettingsDiff,\n ParsedInstruction,\n} from \"./composer\";\nimport { loadCase, formatVariableDef, analyzeVariables, mergeVariables, diffSettings } from \"./composer\";\n\n// ── Phase 1: 入力収集 ──\n\n/**\n * 分岐変数名をプロンプトで取得\n */\nexport async function gatherBranchVariable(): Promise<string> {\n return promptText(t(\"compose.branchVarPrompt\"), {\n validate: (v) => (!v?.trim() ? t(\"compose.branchVarPrompt\") : undefined),\n });\n}\n\n/**\n * 対話的にケースを1つずつ追加\n */\nexport async function gatherCasesInteractively(): Promise<LoadedCase[]> {\n const cases: LoadedCase[] = [];\n\n // 最低2ケース必要\n while (cases.length < 2 || (await promptConfirm(t(\"compose.addAnotherCase\"), false))) {\n const yamlPath = await promptText(t(\"compose.yamlPathPrompt\"), {\n validate: (v) => (!v?.trim() ? t(\"compose.yamlPathPrompt\") : undefined),\n });\n const match = await promptText(t(\"compose.matchValuePrompt\"), {\n validate: (v) => (!v?.trim() ? t(\"compose.matchValuePrompt\") : undefined),\n });\n\n const loaded = await loadCase(match, yamlPath);\n const varCount = loaded.instruction.variables\n ? Object.keys(loaded.instruction.variables).length\n : 0;\n log.success(\n tf(\"compose.caseLoaded\", {\n title: loaded.instruction.title,\n steps: loaded.instruction.steps.length,\n vars: varCount,\n }),\n );\n cases.push(loaded);\n }\n\n return cases;\n}\n\n/**\n * CLI 引数で指定されたケースを一括ロード\n */\nexport async function loadProvidedCases(\n caseDefs: { match: string; yamlPath: string }[],\n): Promise<LoadedCase[]> {\n const cases: LoadedCase[] = [];\n for (const c of caseDefs) {\n const loaded = await loadCase(c.match, c.yamlPath);\n const varCount = loaded.instruction.variables\n ? Object.keys(loaded.instruction.variables).length\n : 0;\n log.success(\n tf(\"compose.caseLoaded\", {\n title: loaded.instruction.title,\n steps: loaded.instruction.steps.length,\n vars: varCount,\n }),\n );\n cases.push(loaded);\n }\n return cases;\n}\n\n/**\n * ゴールをプロンプトで取得\n */\nexport async function gatherGoal(defaultGoal?: string): Promise<string | undefined> {\n const goal = await promptText(t(\"compose.goalPrompt\"), {\n initialValue: defaultGoal,\n placeholder: defaultGoal,\n });\n return goal.trim() || undefined;\n}\n\n// ── Phase 2: 変数競合解決 ──\n\n/**\n * 変数マージプレビューを表示\n */\nexport function displayVariableMergePreview(\n analysis: VariableMergeResult,\n branchOn: string,\n): void {\n const lines: string[] = [];\n\n // 共通変数\n const sharedEntries = Object.entries(analysis.shared);\n if (sharedEntries.length > 0) {\n lines.push(t(\"compose.sharedVariables\"));\n for (const [name, def] of sharedEntries) {\n lines.push(` ${name} → ${formatVariableDef(def)}`);\n }\n lines.push(\"\");\n }\n\n // 競合変数\n if (analysis.conflicts.length > 0) {\n lines.push(t(\"compose.conflictingVariables\"));\n for (const conflict of analysis.conflicts) {\n lines.push(` ${conflict.name}`);\n for (const d of conflict.definitions) {\n lines.push(` [${d.caseName}] ${formatVariableDef(d.def)}`);\n }\n }\n lines.push(\"\");\n }\n\n // ケース固有変数\n if (analysis.caseSpecific.length > 0) {\n lines.push(t(\"compose.caseSpecificVariables\"));\n for (const cs of analysis.caseSpecific) {\n lines.push(` [${cs.caseName}] ${cs.name} → ${formatVariableDef(cs.def)}`);\n }\n lines.push(\"\");\n }\n\n // 分岐変数\n lines.push(t(\"compose.branchVariable\"));\n lines.push(` ${branchOn} → source: prompt`);\n\n note(lines.join(\"\\n\"), t(\"compose.variableMergePreview\"));\n}\n\n/**\n * 競合変数の解決をユーザーに問う\n */\nexport async function resolveVariableConflicts(\n analysis: VariableMergeResult,\n): Promise<Map<string, VariableDefinition>> {\n const resolutions = new Map<string, VariableDefinition>();\n\n for (const conflict of analysis.conflicts) {\n const options = conflict.definitions.map((d) => ({\n value: d.caseName,\n label: tf(\"compose.useFromCase\", { case: d.caseName }),\n hint: formatVariableDef(d.def),\n }));\n\n const chosen = await promptSelect(\n tf(\"compose.conflictPrompt\", { name: conflict.name }),\n options,\n );\n\n const selected = conflict.definitions.find((d) => d.caseName === chosen);\n if (selected) {\n resolutions.set(conflict.name, selected.def);\n }\n }\n\n return resolutions;\n}\n\n// ── Phase 3: Settings 解決 ──\n\n/**\n * Settings の差分をユーザーに問う\n */\nexport async function resolveSettings(\n diffs: SettingsDiff[],\n cases: LoadedCase[],\n baseSettings: ParsedInstruction[\"settings\"],\n): Promise<ParsedInstruction[\"settings\"]> {\n const settings = { ...baseSettings };\n\n for (const diff of diffs) {\n const options = diff.values.map((v) => ({\n value: v.caseName,\n label: tf(\"compose.useFromCase\", { case: v.caseName }),\n hint: `${diff.key} = ${JSON.stringify(v.value)}`,\n }));\n\n const chosen = await promptSelect(\n tf(\"compose.settingsDiffPrompt\", { key: diff.key }),\n options,\n );\n\n const selectedCase = cases.find((c) => c.match === chosen);\n if (selectedCase) {\n (settings as Record<string, unknown>)[diff.key] =\n selectedCase.instruction.settings[diff.key as keyof typeof settings];\n }\n }\n\n return settings;\n}\n\n// ── Phase 4: プレビュー + 編集ループ ──\n\n/**\n * 合成結果のプレビューを表示\n */\nfunction displayPreview(state: CompositionState): void {\n const lines: string[] = [];\n lines.push(`Title: ${state.title}`);\n lines.push(`Branch: {{${state.branchOn}}}`);\n lines.push(\n `Cases: ${state.cases.map((c) => `${c.match} (${c.instruction.steps.length} steps)`).join(\", \")}`,\n );\n lines.push(\"\");\n\n const varEntries = Object.entries(state.mergedVariables);\n lines.push(`Variables (${varEntries.length}):`);\n for (const [name, def] of varEntries) {\n const isBranch = name === state.branchOn ? \" (branch)\" : \"\";\n lines.push(` ${name} → ${formatVariableDef(def)}${isBranch}`);\n }\n lines.push(\"\");\n\n lines.push(\"Settings:\");\n lines.push(` baseUrl: ${state.settings.baseUrl}`);\n lines.push(` defaultTimeout: ${state.settings.defaultTimeout}`);\n\n note(lines.join(\"\\n\"), t(\"compose.composedPreview\"));\n}\n\ntype EditAction = \"confirm\" | \"editBranch\" | \"editMatches\" | \"editVariables\" | \"editTitle\";\n\n/**\n * 編集ループ — ユーザーが「確定」を選ぶまで繰り返す\n */\nexport async function editLoop(state: CompositionState): Promise<void> {\n while (true) {\n displayPreview(state);\n\n const action = await promptSelect<EditAction>(t(\"compose.selectAction\"), [\n { value: \"confirm\", label: t(\"compose.confirm\"), hint: t(\"compose.confirmHint\") },\n { value: \"editBranch\", label: t(\"compose.editBranch\") },\n { value: \"editMatches\", label: t(\"compose.editMatches\") },\n { value: \"editVariables\", label: t(\"compose.editVariables\") },\n { value: \"editTitle\", label: t(\"compose.editTitle\") },\n ]);\n\n if (action === \"confirm\") break;\n\n switch (action) {\n case \"editBranch\":\n await handleEditBranch(state);\n break;\n case \"editMatches\":\n await handleEditMatches(state);\n break;\n case \"editVariables\":\n await handleEditVariables(state);\n break;\n case \"editTitle\":\n await handleEditTitle(state);\n break;\n }\n }\n}\n\nasync function handleEditBranch(state: CompositionState): Promise<void> {\n const oldBranch = state.branchOn;\n const newBranch = await promptText(t(\"compose.newBranchVar\"), {\n initialValue: oldBranch,\n validate: (v) => (!v?.trim() ? t(\"compose.branchVarPrompt\") : undefined),\n });\n\n if (newBranch !== oldBranch) {\n // mergedVariables のキーを付け替え\n const branchDef = state.mergedVariables[oldBranch];\n if (branchDef) {\n delete state.mergedVariables[oldBranch];\n state.mergedVariables[newBranch] = branchDef;\n }\n state.branchOn = newBranch;\n }\n}\n\nasync function handleEditMatches(state: CompositionState): Promise<void> {\n const options = state.cases.map((c) => ({\n value: c.match,\n label: c.match,\n hint: c.instruction.title,\n }));\n\n const selected = await promptSelect(t(\"compose.selectCase\"), options);\n const caseObj = state.cases.find((c) => c.match === selected);\n if (!caseObj) return;\n\n const newMatch = await promptText(t(\"compose.newMatchValue\"), {\n initialValue: caseObj.match,\n validate: (v) => (!v?.trim() ? t(\"compose.matchValuePrompt\") : undefined),\n });\n caseObj.match = newMatch;\n\n // 分岐変数の description を更新\n const branchDef = state.mergedVariables[state.branchOn];\n if (branchDef) {\n branchDef.description = `分岐条件 (${state.cases.map((c) => c.match).join(\", \")})`;\n }\n}\n\ntype VarAction = \"delete\" | \"add\" | \"edit\";\n\nasync function handleEditVariables(state: CompositionState): Promise<void> {\n const action = await promptSelect<VarAction>(t(\"compose.editVarAction\"), [\n { value: \"delete\", label: t(\"compose.deleteVar\") },\n { value: \"add\", label: t(\"compose.addVar\") },\n { value: \"edit\", label: t(\"compose.editVarDef\") },\n ]);\n\n const varNames = Object.keys(state.mergedVariables).filter((n) => n !== state.branchOn);\n\n switch (action) {\n case \"delete\": {\n if (varNames.length === 0) return;\n const toDelete = await promptSelect(\n t(\"compose.selectVar\"),\n varNames.map((n) => ({\n value: n,\n label: n,\n hint: formatVariableDef(state.mergedVariables[n]),\n })),\n );\n delete state.mergedVariables[toDelete];\n log.success(tf(\"compose.varDeleted\", { name: toDelete }));\n break;\n }\n case \"add\": {\n const name = await promptText(t(\"compose.newVarName\"), {\n validate: (v) => {\n if (!v?.trim()) return t(\"compose.newVarName\");\n if (v.trim() === state.branchOn)\n return tf(\"compose.branchVarConflict\", { name: v.trim() });\n return undefined;\n },\n });\n const source = await promptSelect(t(\"compose.newVarSource\"), [\n { value: \"prompt\", label: \"prompt\" },\n { value: \"fixed\", label: \"fixed\" },\n { value: \"env\", label: \"env\" },\n { value: \"context\", label: \"context\" },\n { value: \"expression\", label: \"expression\" },\n { value: \"data\", label: \"data\" },\n ]);\n const value = await promptText(t(\"compose.newVarValue\"));\n const description = await promptText(t(\"compose.newVarDescription\"));\n state.mergedVariables[name] = {\n source: source as VariableDefinition[\"source\"],\n required: true,\n sensitive: false,\n ...(value.trim() ? { value: value.trim() } : {}),\n ...(description.trim() ? { description: description.trim() } : {}),\n };\n log.success(tf(\"compose.varAdded\", { name }));\n break;\n }\n case \"edit\": {\n if (varNames.length === 0) return;\n const toEdit = await promptSelect(\n t(\"compose.selectVar\"),\n varNames.map((n) => ({\n value: n,\n label: n,\n hint: formatVariableDef(state.mergedVariables[n]),\n })),\n );\n const currentDef = state.mergedVariables[toEdit];\n const newSource = await promptSelect(t(\"compose.newVarSource\"), [\n { value: \"prompt\", label: \"prompt\" },\n { value: \"fixed\", label: \"fixed\" },\n { value: \"env\", label: \"env\" },\n { value: \"context\", label: \"context\" },\n { value: \"expression\", label: \"expression\" },\n { value: \"data\", label: \"data\" },\n ]);\n const newValue = await promptText(t(\"compose.newVarValue\"), {\n initialValue: currentDef.value ?? \"\",\n });\n const newDesc = await promptText(t(\"compose.newVarDescription\"), {\n initialValue: currentDef.description ?? \"\",\n });\n state.mergedVariables[toEdit] = {\n source: newSource as VariableDefinition[\"source\"],\n required: currentDef.required,\n sensitive: currentDef.sensitive,\n ...(newValue.trim() ? { value: newValue.trim() } : {}),\n ...(newDesc.trim() ? { description: newDesc.trim() } : {}),\n };\n log.success(tf(\"compose.varUpdated\", { name: toEdit }));\n break;\n }\n }\n}\n\nasync function handleEditTitle(state: CompositionState): Promise<void> {\n const newTitle = await promptText(t(\"compose.newTitle\"), {\n initialValue: state.title,\n validate: (v) => (!v?.trim() ? t(\"compose.newTitle\") : undefined),\n });\n state.title = newTitle;\n state.goal = newTitle;\n state.metadata = { ...state.metadata, goal: newTitle };\n}\n\n// ── ヘルパー: 状態構築の再利用 ──\n\n/**\n * 変数分析・競合解決・Settings 解決を経て CompositionState を構築する\n */\nexport async function buildState(opts: {\n branchOn: string;\n cases: LoadedCase[];\n goal?: string;\n output: string;\n}): Promise<CompositionState> {\n const { branchOn, cases, goal, output } = opts;\n\n // 変数分析\n const varAnalysis = analyzeVariables(cases);\n displayVariableMergePreview(varAnalysis, branchOn);\n const resolutions = await resolveVariableConflicts(varAnalysis);\n\n // Settings 解決\n const settingsDiffs = diffSettings(cases);\n const settings = await resolveSettings(settingsDiffs, cases, cases[0].instruction.settings);\n\n const mergedVars = mergeVariables(\n varAnalysis,\n resolutions,\n branchOn,\n cases.map((c) => c.match),\n );\n\n const title = goal ?? cases[0].instruction.title;\n\n return {\n branchOn,\n cases,\n goal,\n output,\n mergedVariables: mergedVars,\n settings,\n metadata: {\n ...cases[0].instruction.metadata,\n goal: goal ?? cases[0].instruction.metadata.goal,\n },\n title,\n };\n}\n","/**\n * compose CLI エントリポイント\n *\n * 複数の生成済み指示書を1つの分岐付き指示書に対話的に合成する。\n * CLI 引数はプリフィルとして使用し、未指定分はプロンプトで収集。\n */\n\nimport { initLocale, t, tf } from \"../i18n\";\nimport { intro, outro } from \"../cli/prompts\";\nimport { parseComposeArgs } from \"./config\";\nimport { buildComposedInstruction, validateAndWriteYaml } from \"./composer\";\nimport {\n gatherBranchVariable,\n gatherCasesInteractively,\n loadProvidedCases,\n gatherGoal,\n buildState,\n editLoop,\n} from \"./interactive\";\n\nconst config = parseComposeArgs();\ninitLocale(config.locale);\nintro(t(\"compose.title\"));\n\ntry {\n // Phase 1: 入力収集(CLI 引数はプリフィル)\n const branchOn = config.branchOn ?? (await gatherBranchVariable());\n const cases =\n config.cases.length > 0\n ? await loadProvidedCases(config.cases)\n : await gatherCasesInteractively();\n const goal = config.goal ?? (await gatherGoal(cases[0]?.instruction.title));\n\n // Phase 2 & 3: 変数競合解決 + Settings 解決\n const state = await buildState({ branchOn, cases, goal, output: config.output });\n\n // Phase 4: プレビュー + 編集ループ\n await editLoop(state);\n\n // Phase 5: 書き出し\n const composed = buildComposedInstruction(state);\n const outputPath = await validateAndWriteYaml(composed, config.output);\n outro(tf(\"compose.complete\", { path: outputPath }));\n} catch (error) {\n const msg = error instanceof Error ? error.message : String(error);\n console.error(`合成失敗: ${msg}`);\n process.exit(1);\n}\n"],"mappings":"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","names":[]}
|