palabre 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/config.js +33 -7
- package/dist/configWizard.js +45 -40
- package/dist/context.js +16 -14
- package/dist/doctor.js +139 -135
- package/dist/errors.js +4 -31
- package/dist/i18n.js +30 -0
- package/dist/index.js +266 -256
- package/dist/limits.js +11 -10
- package/dist/messages/adapter-errors.js +36 -0
- package/dist/messages/agents.js +38 -0
- package/dist/messages/common.js +28 -0
- package/dist/messages/config.js +88 -0
- package/dist/messages/context.js +24 -0
- package/dist/messages/doctor.js +126 -0
- package/dist/messages/help.js +280 -0
- package/dist/messages/index.js +38 -0
- package/dist/messages/init.js +30 -0
- package/dist/messages/limits.js +12 -0
- package/dist/messages/new.js +66 -0
- package/dist/messages/orchestrator.js +14 -0
- package/dist/messages/output.js +64 -0
- package/dist/messages/presets.js +26 -0
- package/dist/messages/preview.js +22 -0
- package/dist/messages/prompt.js +102 -0
- package/dist/messages/renderers.js +38 -0
- package/dist/messages/update.js +40 -0
- package/dist/new.js +42 -42
- package/dist/orchestrator.js +23 -18
- package/dist/output.js +34 -33
- package/dist/presets.js +78 -2
- package/dist/prompt.js +43 -58
- package/dist/renderers/console.js +32 -26
- package/dist/update.js +10 -21
- package/package.json +1 -1
- package/palabre.config.example.json +1 -0
package/dist/index.js
CHANGED
|
@@ -2,16 +2,17 @@
|
|
|
2
2
|
import { readFile } from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
|
-
import { configExists, createConfigFromDiscovery, DEFAULT_CONFIG_PATH, GLOBAL_CONFIG_PATH, loadConfig, resolveDefaultConfigPath, writeExampleConfig } from "./config.js";
|
|
5
|
+
import { configExists, createConfigFromDiscovery, DEFAULT_CONFIG_PATH, GLOBAL_CONFIG_PATH, loadConfig, resolveDefaultConfigPath, resolveOutputDir, writeExampleConfig } from "./config.js";
|
|
6
6
|
import { loadProjectInputs } from "./context.js";
|
|
7
7
|
import { discoverLocalTools } from "./discovery.js";
|
|
8
8
|
import { runDoctor } from "./doctor.js";
|
|
9
9
|
import { AdapterError, formatAdapterError } from "./errors.js";
|
|
10
10
|
import { runConfigWizard } from "./configWizard.js";
|
|
11
|
+
import { createTranslator, DEFAULT_LANGUAGE, parseLanguage, resolveLanguage } from "./i18n.js";
|
|
11
12
|
import { DEFAULT_TURNS, parseTurnsFlag, turnsOrDefault } from "./limits.js";
|
|
12
13
|
import { formatAgentPrompt } from "./prompt.js";
|
|
13
14
|
import { runNewWizard } from "./new.js";
|
|
14
|
-
import { listPresetNames, resolvePreset } from "./presets.js";
|
|
15
|
+
import { listPresetNames, listPresetsWithAvailability, resolvePreset } from "./presets.js";
|
|
15
16
|
import { createConsoleRenderer } from "./renderers/console.js";
|
|
16
17
|
import { createNdjsonRenderer } from "./renderers/ndjson.js";
|
|
17
18
|
import { runDebate } from "./orchestrator.js";
|
|
@@ -20,17 +21,20 @@ import { applySourceUpdate, formatUpdateInstructions, getUpdateInfo } from "./up
|
|
|
20
21
|
import { createSessionContext } from "./session.js";
|
|
21
22
|
/** Point d'entrée principal du CLI Palabre. Dispatche vers la commande appropriée selon les arguments. */
|
|
22
23
|
async function main() {
|
|
23
|
-
const
|
|
24
|
+
const rawArgs = process.argv.slice(2);
|
|
25
|
+
const startupLanguage = resolveLanguage({ explicitLanguage: findRawLanguageFlag(rawArgs) });
|
|
26
|
+
const startupMessages = createTranslator(startupLanguage);
|
|
27
|
+
const parsed = parseArgs(rawArgs, startupMessages);
|
|
24
28
|
if (parsed.command === "version" || parsed.flags.version) {
|
|
25
29
|
console.log(await getPackageVersion());
|
|
26
30
|
return;
|
|
27
31
|
}
|
|
28
32
|
if (parsed.command === "help" || parsed.flags.help) {
|
|
29
|
-
printHelp();
|
|
33
|
+
printHelp(await resolveCommandMessages(parsed.flags), commandHelpTarget(parsed));
|
|
30
34
|
return;
|
|
31
35
|
}
|
|
32
36
|
if (parsed.command === "doctor") {
|
|
33
|
-
const result = await runDoctor(optionalString(parsed.flags.config), Boolean(parsed.flags.plain));
|
|
37
|
+
const result = await runDoctor(optionalString(parsed.flags.config), Boolean(parsed.flags.plain), optionalString(parsed.flags.language));
|
|
34
38
|
console.log(result.output);
|
|
35
39
|
process.exitCode = result.ok ? 0 : 1;
|
|
36
40
|
return;
|
|
@@ -44,43 +48,68 @@ async function main() {
|
|
|
44
48
|
return;
|
|
45
49
|
}
|
|
46
50
|
if (parsed.command === "presets" || parsed.command === "preset") {
|
|
47
|
-
runPresetsCommand(parsed.flags);
|
|
51
|
+
await runPresetsCommand(parsed.flags);
|
|
48
52
|
return;
|
|
49
53
|
}
|
|
50
54
|
if (parsed.command === "update") {
|
|
51
55
|
const info = await getUpdateInfo(await getPackageVersion());
|
|
56
|
+
const updateConfigPath = optionalString(parsed.flags.config) ?? await resolveDefaultConfigPath();
|
|
57
|
+
const updateConfig = await configExists(updateConfigPath)
|
|
58
|
+
? await loadConfig(updateConfigPath)
|
|
59
|
+
: undefined;
|
|
60
|
+
const updateLanguage = resolveLanguage({
|
|
61
|
+
explicitLanguage: optionalString(parsed.flags.language),
|
|
62
|
+
configLanguage: updateConfig?.language
|
|
63
|
+
});
|
|
64
|
+
const updateMessages = createTranslator(updateLanguage);
|
|
52
65
|
if (parsed.flags.apply) {
|
|
53
|
-
await applySourceUpdate(info);
|
|
54
|
-
console.log(
|
|
66
|
+
await applySourceUpdate(info, updateMessages);
|
|
67
|
+
console.log(updateMessages.update.upToDate);
|
|
55
68
|
return;
|
|
56
69
|
}
|
|
57
|
-
console.log(formatUpdateInstructions(info));
|
|
70
|
+
console.log(formatUpdateInstructions(info, updateMessages));
|
|
58
71
|
return;
|
|
59
72
|
}
|
|
60
73
|
if (parsed.command === "init" || parsed.command === "setup") {
|
|
61
74
|
const initConfigPath = optionalString(parsed.flags.config) ?? (parsed.flags.local ? DEFAULT_CONFIG_PATH : GLOBAL_CONFIG_PATH);
|
|
62
75
|
if (await configExists(initConfigPath)) {
|
|
63
|
-
console.log(
|
|
76
|
+
console.log(startupMessages.init.configExists(initConfigPath));
|
|
64
77
|
return;
|
|
65
78
|
}
|
|
66
79
|
const discovery = await discoverLocalTools();
|
|
67
80
|
const config = createConfigFromDiscovery(discovery);
|
|
81
|
+
config.language = resolveLanguage({
|
|
82
|
+
explicitLanguage: optionalString(parsed.flags.language),
|
|
83
|
+
configLanguage: config.language
|
|
84
|
+
});
|
|
85
|
+
const initMessages = createTranslator(config.language);
|
|
68
86
|
await writeExampleConfig(initConfigPath, config);
|
|
69
|
-
console.log(
|
|
70
|
-
printInitDiscovery(discovery, config);
|
|
87
|
+
console.log(initMessages.init.configCreated(initConfigPath));
|
|
88
|
+
printInitDiscovery(discovery, config, initMessages);
|
|
71
89
|
return;
|
|
72
90
|
}
|
|
73
91
|
const configPath = optionalString(parsed.flags.config) ?? await resolveDefaultConfigPath();
|
|
74
92
|
if (!(await configExists(configPath))) {
|
|
75
|
-
await
|
|
76
|
-
|
|
93
|
+
const config = createConfigFromDiscovery(await discoverLocalTools());
|
|
94
|
+
config.language = resolveLanguage({
|
|
95
|
+
explicitLanguage: optionalString(parsed.flags.language),
|
|
96
|
+
configLanguage: config.language
|
|
97
|
+
});
|
|
98
|
+
const messages = createTranslator(config.language);
|
|
99
|
+
await writeExampleConfig(configPath, config);
|
|
100
|
+
console.log(messages.init.editConfigThenRerun(configPath));
|
|
77
101
|
return;
|
|
78
102
|
}
|
|
79
103
|
const config = await loadConfig(configPath);
|
|
104
|
+
const language = resolveLanguage({
|
|
105
|
+
explicitLanguage: optionalString(parsed.flags.language),
|
|
106
|
+
configLanguage: config.language
|
|
107
|
+
});
|
|
108
|
+
const messages = createTranslator(language);
|
|
80
109
|
if (parsed.command === "new") {
|
|
81
|
-
const selection = await runNewWizard(config);
|
|
110
|
+
const selection = await runNewWizard(config, messages);
|
|
82
111
|
if (!selection) {
|
|
83
|
-
console.log(
|
|
112
|
+
console.log(messages.new.cancelled);
|
|
84
113
|
return;
|
|
85
114
|
}
|
|
86
115
|
parsed.flags["agent-a"] = selection.agentA;
|
|
@@ -108,17 +137,18 @@ async function main() {
|
|
|
108
137
|
parsed.flags.context = selection.context;
|
|
109
138
|
}
|
|
110
139
|
const topic = optionalString(parsed.flags.topic) ?? "";
|
|
111
|
-
const context = await loadProjectInputs(getStringListFlag(parsed.flags.files), getStringListFlag(parsed.flags.context));
|
|
140
|
+
const context = await loadProjectInputs(getStringListFlag(parsed.flags.files), getStringListFlag(parsed.flags.context), process.cwd(), messages);
|
|
112
141
|
const presetName = optionalString(parsed.flags.preset);
|
|
113
|
-
const preset = presetName ? resolvePreset(presetName) : undefined;
|
|
142
|
+
const preset = presetName ? resolvePreset(presetName, messages) : undefined;
|
|
114
143
|
if (!topic) {
|
|
115
|
-
throw new Error(
|
|
144
|
+
throw new Error(messages.common.topicRequired);
|
|
116
145
|
}
|
|
117
146
|
const options = {
|
|
147
|
+
language,
|
|
118
148
|
topic,
|
|
119
|
-
agentA: resolveAgentName("agent A", parsed.flags["agent-a"], preset?.agentA, config.defaults?.agentA),
|
|
120
|
-
agentB: resolveAgentName("agent B", parsed.flags["agent-b"], preset?.agentB, config.defaults?.agentB),
|
|
121
|
-
turns: parseTurnsFlag(parsed.flags.turns, config.defaults?.turns ?? DEFAULT_TURNS, "--turns"),
|
|
149
|
+
agentA: resolveAgentName("agent A", parsed.flags["agent-a"], preset?.agentA, config.defaults?.agentA, messages),
|
|
150
|
+
agentB: resolveAgentName("agent B", parsed.flags["agent-b"], preset?.agentB, config.defaults?.agentB, messages),
|
|
151
|
+
turns: parseTurnsFlag(parsed.flags.turns, config.defaults?.turns ?? DEFAULT_TURNS, "--turns", messages),
|
|
122
152
|
session: createSessionContext(),
|
|
123
153
|
files: context.files,
|
|
124
154
|
modelA: optionalString(parsed.flags["model-a"]),
|
|
@@ -131,14 +161,14 @@ async function main() {
|
|
|
131
161
|
plainOutput: Boolean(parsed.flags.plain)
|
|
132
162
|
};
|
|
133
163
|
if (parsed.flags["show-prompt"]) {
|
|
134
|
-
printContextWarnings(context.warnings);
|
|
135
|
-
printPromptPreview(config, options);
|
|
164
|
+
printContextWarnings(context.warnings, messages);
|
|
165
|
+
printPromptPreview(config, options, language, messages);
|
|
136
166
|
return;
|
|
137
167
|
}
|
|
138
|
-
const renderer = createRendererFromFlags(parsed.flags, options.plainOutput);
|
|
168
|
+
const renderer = createRendererFromFlags(parsed.flags, options.plainOutput, messages);
|
|
139
169
|
context.warnings.forEach((warning) => renderer.warning(warning));
|
|
140
|
-
const result = await runDebate(config, options, renderer);
|
|
141
|
-
const outputPath = await writeDebateMarkdown(config.outputDir
|
|
170
|
+
const result = await runDebate(config, options, renderer, messages);
|
|
171
|
+
const outputPath = await writeDebateMarkdown(resolveOutputDir(config.outputDir), result.options, result.messages, result.summary, result.stopReason, messages);
|
|
142
172
|
renderer.done(outputPath);
|
|
143
173
|
}
|
|
144
174
|
/**
|
|
@@ -148,11 +178,17 @@ async function main() {
|
|
|
148
178
|
async function runAgentsCommand(flags) {
|
|
149
179
|
const configPath = optionalString(flags.config) ?? await resolveDefaultConfigPath();
|
|
150
180
|
if (!(await configExists(configPath))) {
|
|
151
|
-
|
|
181
|
+
const messages = createTranslator(resolveLanguage({ explicitLanguage: optionalString(flags.language) }));
|
|
182
|
+
throw new Error(messages.agents.noConfig);
|
|
152
183
|
}
|
|
153
184
|
const config = await loadConfig(configPath);
|
|
185
|
+
const language = resolveLanguage({
|
|
186
|
+
explicitLanguage: optionalString(flags.language),
|
|
187
|
+
configLanguage: config.language
|
|
188
|
+
});
|
|
189
|
+
const messages = createTranslator(language);
|
|
154
190
|
const discovery = await discoverLocalTools();
|
|
155
|
-
printAgents(configPath, config, discovery);
|
|
191
|
+
printAgents(configPath, config, discovery, messages);
|
|
156
192
|
}
|
|
157
193
|
/**
|
|
158
194
|
* Exécute la commande `config` : wizard interactif ou mise à jour directe des paramètres par défaut.
|
|
@@ -160,62 +196,76 @@ async function runAgentsCommand(flags) {
|
|
|
160
196
|
*/
|
|
161
197
|
async function runConfigCommand(flags) {
|
|
162
198
|
const configPath = optionalString(flags.config) ?? await resolveDefaultConfigPath();
|
|
199
|
+
const explicitLanguage = optionalString(flags.language);
|
|
163
200
|
if (!(await configExists(configPath))) {
|
|
201
|
+
const messages = createTranslator(resolveLanguage({ explicitLanguage }));
|
|
164
202
|
await writeExampleConfig(configPath);
|
|
165
|
-
console.log(
|
|
203
|
+
console.log(messages.config.createdForConfig(configPath));
|
|
166
204
|
return;
|
|
167
205
|
}
|
|
168
206
|
const config = await loadConfig(configPath);
|
|
207
|
+
const language = resolveLanguage({
|
|
208
|
+
explicitLanguage,
|
|
209
|
+
configLanguage: config.language
|
|
210
|
+
});
|
|
211
|
+
const messages = createTranslator(language);
|
|
169
212
|
if (flags["sync-agents"]) {
|
|
170
213
|
const discovery = await discoverLocalTools();
|
|
171
214
|
const addedAgents = syncDetectedAgents(config, discovery);
|
|
172
215
|
if (addedAgents.length === 0) {
|
|
173
|
-
console.log(
|
|
216
|
+
console.log(messages.config.syncNoMissing(configPath));
|
|
174
217
|
return;
|
|
175
218
|
}
|
|
176
219
|
await writeExampleConfig(configPath, config);
|
|
177
|
-
console.log(
|
|
220
|
+
console.log(messages.config.syncAdded(configPath, addedAgents.join(", ")));
|
|
178
221
|
return;
|
|
179
222
|
}
|
|
180
223
|
const defaultAgents = getStringListFlag(flags["set-defaults"]);
|
|
181
224
|
const hasTurnsFlag = flags.turns !== undefined;
|
|
182
225
|
const summaryAgentValue = optionalString(flags["summary-agent"]);
|
|
183
|
-
|
|
226
|
+
const languageValue = explicitLanguage;
|
|
227
|
+
const changesDefaults = defaultAgents.length > 0 || hasTurnsFlag || summaryAgentValue !== undefined;
|
|
228
|
+
if (changesDefaults || languageValue !== undefined) {
|
|
184
229
|
const nextDefaults = { ...(config.defaults ?? {}) };
|
|
185
230
|
if (defaultAgents.length > 0) {
|
|
186
231
|
const [agentA, agentB] = defaultAgents;
|
|
187
232
|
if (!agentA || !agentB) {
|
|
188
|
-
throw new Error(
|
|
233
|
+
throw new Error(messages.common.setDefaultsRequiresTwo);
|
|
189
234
|
}
|
|
190
|
-
assertKnownAgent(config, agentA, "defaults.agentA");
|
|
191
|
-
assertKnownAgent(config, agentB, "defaults.agentB");
|
|
235
|
+
assertKnownAgent(config, agentA, "defaults.agentA", messages);
|
|
236
|
+
assertKnownAgent(config, agentB, "defaults.agentB", messages);
|
|
192
237
|
nextDefaults.agentA = agentA;
|
|
193
238
|
nextDefaults.agentB = agentB;
|
|
194
239
|
}
|
|
195
240
|
if (hasTurnsFlag) {
|
|
196
|
-
nextDefaults.turns = parseTurnsFlag(flags.turns, nextDefaults.turns ?? DEFAULT_TURNS, "--turns");
|
|
241
|
+
nextDefaults.turns = parseTurnsFlag(flags.turns, nextDefaults.turns ?? DEFAULT_TURNS, "--turns", messages);
|
|
197
242
|
}
|
|
198
243
|
if (summaryAgentValue !== undefined) {
|
|
199
244
|
if (isNoneValue(summaryAgentValue)) {
|
|
200
245
|
delete nextDefaults.summaryAgent;
|
|
201
246
|
}
|
|
202
247
|
else {
|
|
203
|
-
assertKnownAgent(config, summaryAgentValue, "defaults.summaryAgent");
|
|
248
|
+
assertKnownAgent(config, summaryAgentValue, "defaults.summaryAgent", messages);
|
|
204
249
|
nextDefaults.summaryAgent = summaryAgentValue;
|
|
205
250
|
}
|
|
206
251
|
}
|
|
207
|
-
|
|
252
|
+
if (languageValue !== undefined) {
|
|
253
|
+
config.language = parseLanguage(languageValue, "--language");
|
|
254
|
+
}
|
|
255
|
+
if (changesDefaults) {
|
|
256
|
+
config.defaults = nextDefaults;
|
|
257
|
+
}
|
|
208
258
|
await writeExampleConfig(configPath, config);
|
|
209
|
-
console.log(
|
|
259
|
+
console.log(messages.config.updated(configPath, formatDefaultsForMessage(config.defaults ?? {}, messages), config.language ?? DEFAULT_LANGUAGE));
|
|
210
260
|
return;
|
|
211
261
|
}
|
|
212
262
|
if (flags["clear-defaults"]) {
|
|
213
263
|
delete config.defaults;
|
|
214
264
|
await writeExampleConfig(configPath, config);
|
|
215
|
-
console.log(
|
|
265
|
+
console.log(messages.config.cleared(configPath));
|
|
216
266
|
return;
|
|
217
267
|
}
|
|
218
|
-
await runConfigWizard(configPath, config);
|
|
268
|
+
await runConfigWizard(configPath, config, messages);
|
|
219
269
|
}
|
|
220
270
|
/**
|
|
221
271
|
* Renvoie `true` si la valeur représente une désactivation explicite (ex. "none", "0", "disabled").
|
|
@@ -229,12 +279,8 @@ function isNoneValue(value) {
|
|
|
229
279
|
* @param defaults - Objet `defaults` de la config Palabre.
|
|
230
280
|
* @returns Chaîne résumant la paire d'agents, le nombre de réponses et l'agent de synthèse.
|
|
231
281
|
*/
|
|
232
|
-
function formatDefaultsForMessage(defaults) {
|
|
233
|
-
|
|
234
|
-
? `agents: ${defaults.agentA} <-> ${defaults.agentB}`
|
|
235
|
-
: "agents: non définis";
|
|
236
|
-
const summary = defaults.summaryAgent ? `synthèse: ${defaults.summaryAgent}` : "synthèse: agent B";
|
|
237
|
-
return `${pair}, réponses: ${turnsOrDefault(defaults.turns)}, ${summary}`;
|
|
282
|
+
function formatDefaultsForMessage(defaults, messages) {
|
|
283
|
+
return messages.config.defaultsSummary(defaults.agentA, defaults.agentB, turnsOrDefault(defaults.turns), defaults.summaryAgent);
|
|
238
284
|
}
|
|
239
285
|
/**
|
|
240
286
|
* Lève une erreur si `agentName` n'est pas déclaré dans la config.
|
|
@@ -242,9 +288,9 @@ function formatDefaultsForMessage(defaults) {
|
|
|
242
288
|
* @param agentName - Nom de l'agent à vérifier.
|
|
243
289
|
* @param fieldName - Nom du champ (utilisé dans le message d'erreur).
|
|
244
290
|
*/
|
|
245
|
-
function assertKnownAgent(config, agentName, fieldName) {
|
|
291
|
+
function assertKnownAgent(config, agentName, fieldName, messages) {
|
|
246
292
|
if (!config.agents[agentName]) {
|
|
247
|
-
throw new Error(
|
|
293
|
+
throw new Error(messages.common.unknownAgentForField(fieldName, agentName, Object.keys(config.agents).join(", ")));
|
|
248
294
|
}
|
|
249
295
|
}
|
|
250
296
|
/**
|
|
@@ -256,10 +302,10 @@ function assertKnownAgent(config, agentName, fieldName) {
|
|
|
256
302
|
* @param defaultValue - Valeur issue des défauts de la config.
|
|
257
303
|
* @returns Nom de l'agent résolu.
|
|
258
304
|
*/
|
|
259
|
-
function resolveAgentName(label, explicitValue, presetValue, defaultValue) {
|
|
305
|
+
function resolveAgentName(label, explicitValue, presetValue, defaultValue, messages) {
|
|
260
306
|
const resolved = optionalString(explicitValue) ?? presetValue ?? defaultValue;
|
|
261
307
|
if (!resolved) {
|
|
262
|
-
throw new Error(
|
|
308
|
+
throw new Error(messages.common.noAgentDefined(label));
|
|
263
309
|
}
|
|
264
310
|
return resolved;
|
|
265
311
|
}
|
|
@@ -268,30 +314,33 @@ function resolveAgentName(label, explicitValue, presetValue, defaultValue) {
|
|
|
268
314
|
* @param config - Config chargée.
|
|
269
315
|
* @param options - Options du débat résolues.
|
|
270
316
|
*/
|
|
271
|
-
function printPromptPreview(config, options) {
|
|
317
|
+
function printPromptPreview(config, options, language, messages) {
|
|
272
318
|
const agentConfig = config.agents[options.agentA];
|
|
273
319
|
if (!agentConfig) {
|
|
274
|
-
throw new Error(
|
|
320
|
+
throw new Error(messages.common.unknownAgent(options.agentA));
|
|
275
321
|
}
|
|
276
322
|
const prompt = formatAgentPrompt({
|
|
277
323
|
topic: options.topic,
|
|
278
324
|
turn: 1,
|
|
325
|
+
totalTurns: options.turns,
|
|
279
326
|
selfName: options.agentA,
|
|
280
327
|
peerName: options.agentB,
|
|
281
328
|
selfRole: agentConfig.role,
|
|
329
|
+
language: options.language,
|
|
282
330
|
session: options.session,
|
|
283
331
|
files: options.files,
|
|
284
332
|
transcript: []
|
|
285
333
|
});
|
|
286
|
-
console.log(
|
|
287
|
-
console.log(
|
|
288
|
-
console.log(
|
|
289
|
-
console.log(
|
|
290
|
-
console.log(
|
|
334
|
+
console.log(messages.preview.title);
|
|
335
|
+
console.log(messages.preview.agent(options.agentA, agentConfig.role));
|
|
336
|
+
console.log(messages.preview.peer(options.agentB));
|
|
337
|
+
console.log(messages.preview.pullModels(options.pullModels));
|
|
338
|
+
console.log(messages.preview.summary(options.summaryEnabled ? options.summaryAgent ?? options.agentB : messages.preview.disabled));
|
|
339
|
+
console.log(messages.preview.interfaceLanguage(language));
|
|
291
340
|
console.log("");
|
|
292
341
|
console.log(prompt);
|
|
293
342
|
console.log("");
|
|
294
|
-
console.log(
|
|
343
|
+
console.log(messages.preview.note);
|
|
295
344
|
}
|
|
296
345
|
/**
|
|
297
346
|
* Extrait une chaîne non vide depuis une valeur de flag, ou renvoie `undefined`.
|
|
@@ -300,6 +349,20 @@ function printPromptPreview(config, options) {
|
|
|
300
349
|
function optionalString(value) {
|
|
301
350
|
return typeof value === "string" && value.trim() ? value : undefined;
|
|
302
351
|
}
|
|
352
|
+
/**
|
|
353
|
+
* Pré-lit seulement `--language`/`--lang` dans les arguments bruts pour localiser
|
|
354
|
+
* les erreurs qui peuvent survenir avant le parsing complet ou le chargement de config.
|
|
355
|
+
*/
|
|
356
|
+
function findRawLanguageFlag(args) {
|
|
357
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
358
|
+
const value = args[index];
|
|
359
|
+
if (value === "--language" || value === "--lang") {
|
|
360
|
+
const next = args[index + 1];
|
|
361
|
+
return next && !next.startsWith("-") ? next : undefined;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
return undefined;
|
|
365
|
+
}
|
|
303
366
|
/** Liste des kinds de renderer acceptés par `--renderer`. */
|
|
304
367
|
const SUPPORTED_RENDERERS = ["auto", "pretty", "plain", "ndjson"];
|
|
305
368
|
/**
|
|
@@ -313,28 +376,28 @@ const SUPPORTED_RENDERERS = ["auto", "pretty", "plain", "ndjson"];
|
|
|
313
376
|
*
|
|
314
377
|
* Lève si la valeur de `--renderer` n'est pas dans `SUPPORTED_RENDERERS`.
|
|
315
378
|
*/
|
|
316
|
-
function createRendererFromFlags(flags, plainOutputFallback) {
|
|
379
|
+
function createRendererFromFlags(flags, plainOutputFallback, messages) {
|
|
317
380
|
const explicit = optionalString(flags.renderer);
|
|
318
381
|
if (explicit) {
|
|
319
382
|
if (!SUPPORTED_RENDERERS.includes(explicit)) {
|
|
320
|
-
throw new Error(
|
|
383
|
+
throw new Error(messages.common.unknownRenderer(explicit, SUPPORTED_RENDERERS.join(", ")));
|
|
321
384
|
}
|
|
322
385
|
const kind = explicit;
|
|
323
386
|
switch (kind) {
|
|
324
387
|
case "ndjson":
|
|
325
388
|
return createNdjsonRenderer();
|
|
326
389
|
case "plain":
|
|
327
|
-
return createConsoleRenderer(true);
|
|
390
|
+
return createConsoleRenderer(true, messages);
|
|
328
391
|
case "pretty":
|
|
329
|
-
return createConsoleRenderer(false);
|
|
392
|
+
return createConsoleRenderer(false, messages);
|
|
330
393
|
case "auto":
|
|
331
|
-
return createConsoleRenderer(plainOutputFallback);
|
|
394
|
+
return createConsoleRenderer(plainOutputFallback, messages);
|
|
332
395
|
}
|
|
333
396
|
}
|
|
334
397
|
if (flags.json) {
|
|
335
398
|
return createNdjsonRenderer();
|
|
336
399
|
}
|
|
337
|
-
return createConsoleRenderer(plainOutputFallback);
|
|
400
|
+
return createConsoleRenderer(plainOutputFallback, messages);
|
|
338
401
|
}
|
|
339
402
|
/**
|
|
340
403
|
* Exécute la commande `palabre presets`.
|
|
@@ -346,22 +409,32 @@ function createRendererFromFlags(flags, plainOutputFallback) {
|
|
|
346
409
|
*
|
|
347
410
|
* @param flags - Flags parsés depuis la ligne de commande.
|
|
348
411
|
*/
|
|
349
|
-
function runPresetsCommand(flags) {
|
|
350
|
-
const
|
|
351
|
-
|
|
352
|
-
|
|
412
|
+
async function runPresetsCommand(flags) {
|
|
413
|
+
const discovery = await discoverLocalTools();
|
|
414
|
+
const configPath = optionalString(flags.config) ?? await resolveDefaultConfigPath();
|
|
415
|
+
const config = await configExists(configPath)
|
|
416
|
+
? await loadConfig(configPath)
|
|
417
|
+
: createConfigFromDiscovery(discovery);
|
|
418
|
+
const language = resolveLanguage({
|
|
419
|
+
explicitLanguage: optionalString(flags.language),
|
|
420
|
+
configLanguage: config.language
|
|
353
421
|
});
|
|
422
|
+
const messages = createTranslator(language);
|
|
423
|
+
const presets = listPresetsWithAvailability(config, discovery, messages);
|
|
354
424
|
if (flags.json) {
|
|
355
425
|
process.stdout.write(JSON.stringify({ v: 1, presets }) + "\n");
|
|
356
426
|
return;
|
|
357
427
|
}
|
|
358
|
-
console.log(
|
|
428
|
+
console.log(messages.presets.title);
|
|
359
429
|
console.log("");
|
|
360
430
|
for (const preset of presets) {
|
|
361
|
-
|
|
431
|
+
const status = preset.available
|
|
432
|
+
? messages.presets.available
|
|
433
|
+
: messages.presets.unavailable(preset.unavailableReasons.join("; "));
|
|
434
|
+
console.log(` ${preset.name.padEnd(20)} ${preset.agentA} <-> ${preset.agentB} ${status}`);
|
|
362
435
|
}
|
|
363
436
|
console.log("");
|
|
364
|
-
console.log(
|
|
437
|
+
console.log(messages.presets.total(presets.length));
|
|
365
438
|
}
|
|
366
439
|
/**
|
|
367
440
|
* Parse `process.argv` en une structure typée `ParsedArgs`.
|
|
@@ -370,7 +443,7 @@ function runPresetsCommand(flags) {
|
|
|
370
443
|
* @param args - Tableau d'arguments (généralement `process.argv.slice(2)`).
|
|
371
444
|
* @returns Commande détectée, indicateur d'explicitation et map de flags.
|
|
372
445
|
*/
|
|
373
|
-
function parseArgs(args) {
|
|
446
|
+
function parseArgs(args, messages) {
|
|
374
447
|
const flags = {};
|
|
375
448
|
let command = "run";
|
|
376
449
|
let commandExplicit = false;
|
|
@@ -379,13 +452,18 @@ function parseArgs(args) {
|
|
|
379
452
|
const presets = new Set(listPresetNames());
|
|
380
453
|
for (let index = 0; index < args.length; index += 1) {
|
|
381
454
|
const value = args[index];
|
|
455
|
+
if (!value.startsWith("-") && !commandExplicit && positionals.length === 0 && commands.has(value)) {
|
|
456
|
+
command = value;
|
|
457
|
+
commandExplicit = true;
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
382
460
|
if (!value.startsWith("-") && index === 0) {
|
|
383
461
|
if (commands.has(value)) {
|
|
384
462
|
command = value;
|
|
385
463
|
commandExplicit = true;
|
|
386
464
|
}
|
|
387
465
|
else if (isLikelyCommandTypo(value, commands)) {
|
|
388
|
-
throw new Error(
|
|
466
|
+
throw new Error(messages.common.unknownCommand(value, Array.from(commands).join(", ")));
|
|
389
467
|
}
|
|
390
468
|
else {
|
|
391
469
|
positionals.push(value);
|
|
@@ -412,7 +490,7 @@ function parseArgs(args) {
|
|
|
412
490
|
if (value === "-s") {
|
|
413
491
|
const next = args[index + 1];
|
|
414
492
|
if (!next || next.startsWith("-")) {
|
|
415
|
-
throw new Error("
|
|
493
|
+
throw new Error(messages.common.optionRequiresValue("-s"));
|
|
416
494
|
}
|
|
417
495
|
flags.topic = next;
|
|
418
496
|
index += 1;
|
|
@@ -421,7 +499,7 @@ function parseArgs(args) {
|
|
|
421
499
|
if (value === "-t") {
|
|
422
500
|
const next = args[index + 1];
|
|
423
501
|
if (!next || next.startsWith("-")) {
|
|
424
|
-
throw new Error("
|
|
502
|
+
throw new Error(messages.common.optionRequiresValue("-t"));
|
|
425
503
|
}
|
|
426
504
|
flags.turns = next;
|
|
427
505
|
index += 1;
|
|
@@ -437,7 +515,7 @@ function parseArgs(args) {
|
|
|
437
515
|
index += 1;
|
|
438
516
|
}
|
|
439
517
|
if (values.length !== 2) {
|
|
440
|
-
throw new Error(
|
|
518
|
+
throw new Error(messages.common.setDefaultsRequiresTwo);
|
|
441
519
|
}
|
|
442
520
|
flags[key] = values;
|
|
443
521
|
continue;
|
|
@@ -454,7 +532,7 @@ function parseArgs(args) {
|
|
|
454
532
|
const next = args[index + 1];
|
|
455
533
|
if (!next || next.startsWith("-")) {
|
|
456
534
|
if (requiresFlagValue(key)) {
|
|
457
|
-
throw new Error(
|
|
535
|
+
throw new Error(messages.common.optionRequiresValue(`--${rawKey}`));
|
|
458
536
|
}
|
|
459
537
|
flags[key] = true;
|
|
460
538
|
}
|
|
@@ -465,7 +543,7 @@ function parseArgs(args) {
|
|
|
465
543
|
}
|
|
466
544
|
}
|
|
467
545
|
if (command === "run") {
|
|
468
|
-
applyRunPositionals(positionals, flags, presets, commandExplicit);
|
|
546
|
+
applyRunPositionals(positionals, flags, presets, commandExplicit, commands, messages);
|
|
469
547
|
}
|
|
470
548
|
return { command, commandExplicit, flags };
|
|
471
549
|
}
|
|
@@ -513,7 +591,7 @@ function levenshteinDistance(left, right) {
|
|
|
513
591
|
* @param presets - Ensemble des noms de presets valides.
|
|
514
592
|
* @param commandExplicit - `true` si l'utilisateur a tapé `palabre run` explicitement.
|
|
515
593
|
*/
|
|
516
|
-
function applyRunPositionals(positionals, flags, presets, commandExplicit) {
|
|
594
|
+
function applyRunPositionals(positionals, flags, presets, commandExplicit, commands, messages) {
|
|
517
595
|
if (positionals.length === 0) {
|
|
518
596
|
return;
|
|
519
597
|
}
|
|
@@ -526,7 +604,10 @@ function applyRunPositionals(positionals, flags, presets, commandExplicit) {
|
|
|
526
604
|
return;
|
|
527
605
|
}
|
|
528
606
|
if (!commandExplicit && positionals.length === 1 && !positionals[0]?.includes(" ")) {
|
|
529
|
-
|
|
607
|
+
if (isLikelyCommandTypo(positionals[0], commands)) {
|
|
608
|
+
throw new Error(messages.common.unknownCommand(positionals[0], Array.from(commands).join(", ")));
|
|
609
|
+
}
|
|
610
|
+
throw new Error(messages.common.ambiguousSubject(positionals[0]));
|
|
530
611
|
}
|
|
531
612
|
flags.topic ??= positionals.join(" ");
|
|
532
613
|
}
|
|
@@ -536,6 +617,7 @@ function applyRunPositionals(positionals, flags, presets, commandExplicit) {
|
|
|
536
617
|
*/
|
|
537
618
|
function normalizeFlagName(value) {
|
|
538
619
|
const aliases = {
|
|
620
|
+
lang: "language",
|
|
539
621
|
s: "topic",
|
|
540
622
|
subject: "topic",
|
|
541
623
|
t: "turns"
|
|
@@ -551,6 +633,7 @@ function requiresFlagValue(value) {
|
|
|
551
633
|
"agent-a",
|
|
552
634
|
"agent-b",
|
|
553
635
|
"config",
|
|
636
|
+
"language",
|
|
554
637
|
"model-a",
|
|
555
638
|
"model-b",
|
|
556
639
|
"preset",
|
|
@@ -586,9 +669,9 @@ function getStringListFlag(value) {
|
|
|
586
669
|
* Écrit les avertissements de contexte sur `stderr`.
|
|
587
670
|
* @param warnings - Messages d'avertissement issus du chargement des fichiers de contexte.
|
|
588
671
|
*/
|
|
589
|
-
function printContextWarnings(warnings) {
|
|
672
|
+
function printContextWarnings(warnings, messages) {
|
|
590
673
|
for (const warning of warnings) {
|
|
591
|
-
process.stderr.write(
|
|
674
|
+
process.stderr.write(`${messages.renderers.warningPrefix} ${warning}\n`);
|
|
592
675
|
}
|
|
593
676
|
}
|
|
594
677
|
/**
|
|
@@ -627,15 +710,15 @@ function findDetectedMissingAgents(config, discovery) {
|
|
|
627
710
|
* @param config - Config Palabre chargée.
|
|
628
711
|
* @param discovery - Résultat de la découverte locale des outils.
|
|
629
712
|
*/
|
|
630
|
-
function printAgents(configPath, config, discovery) {
|
|
713
|
+
function printAgents(configPath, config, discovery, messages) {
|
|
631
714
|
const entries = Object.entries(config.agents).sort(([left], [right]) => left.localeCompare(right));
|
|
632
|
-
console.log(
|
|
715
|
+
console.log(messages.agents.config(configPath));
|
|
633
716
|
console.log("");
|
|
634
|
-
console.log(
|
|
717
|
+
console.log(messages.agents.title);
|
|
635
718
|
for (const [name, agentConfig] of entries) {
|
|
636
|
-
const status = formatAgentDetection(name, agentConfig, discovery);
|
|
637
|
-
const defaults = formatAgentDefaults(name, config);
|
|
638
|
-
const details = formatAgentDetails(agentConfig);
|
|
719
|
+
const status = formatAgentDetection(name, agentConfig, discovery, messages);
|
|
720
|
+
const defaults = formatAgentDefaults(name, config, messages);
|
|
721
|
+
const details = formatAgentDetails(agentConfig, messages);
|
|
639
722
|
const suffix = defaults ? ` | ${defaults}` : "";
|
|
640
723
|
console.log(`- ${name.padEnd(13)} ${`${agentConfig.type}/${agentConfig.role}`.padEnd(18)} ${status}${suffix}`);
|
|
641
724
|
if (details) {
|
|
@@ -643,32 +726,32 @@ function printAgents(configPath, config, discovery) {
|
|
|
643
726
|
}
|
|
644
727
|
}
|
|
645
728
|
console.log("");
|
|
646
|
-
console.log(
|
|
729
|
+
console.log(messages.agents.defaults(config.defaults?.agentA ?? messages.agents.none, config.defaults?.agentB ?? messages.agents.none, turnsOrDefault(config.defaults?.turns), config.defaults?.summaryAgent ?? messages.agents.summaryAgentB));
|
|
647
730
|
}
|
|
648
731
|
/**
|
|
649
732
|
* Renvoie un libellé indiquant si l'agent est agent A, agent B ou agent de synthèse par défaut.
|
|
650
733
|
* @param name - Nom de l'agent.
|
|
651
734
|
* @param config - Config Palabre contenant les défauts.
|
|
652
735
|
*/
|
|
653
|
-
function formatAgentDefaults(name, config) {
|
|
736
|
+
function formatAgentDefaults(name, config, messages) {
|
|
654
737
|
const labels = [];
|
|
655
738
|
if (config.defaults?.agentA === name)
|
|
656
|
-
labels.push(
|
|
739
|
+
labels.push(messages.agents.defaultAgentA);
|
|
657
740
|
if (config.defaults?.agentB === name)
|
|
658
|
-
labels.push(
|
|
741
|
+
labels.push(messages.agents.defaultAgentB);
|
|
659
742
|
if (config.defaults?.summaryAgent === name)
|
|
660
|
-
labels.push(
|
|
743
|
+
labels.push(messages.agents.defaultSummary);
|
|
661
744
|
return labels.join(", ");
|
|
662
745
|
}
|
|
663
746
|
/**
|
|
664
747
|
* Renvoie une ligne de détails pour un agent : commande CLI ou modèle Ollama.
|
|
665
748
|
* @param agentConfig - Configuration de l'agent.
|
|
666
749
|
*/
|
|
667
|
-
function formatAgentDetails(agentConfig) {
|
|
750
|
+
function formatAgentDetails(agentConfig, messages) {
|
|
668
751
|
if (agentConfig.type === "ollama") {
|
|
669
|
-
return
|
|
752
|
+
return messages.agents.model(agentConfig.model);
|
|
670
753
|
}
|
|
671
|
-
return
|
|
754
|
+
return messages.agents.command(agentConfig.command, agentConfig.model);
|
|
672
755
|
}
|
|
673
756
|
/**
|
|
674
757
|
* Renvoie le statut de détection d'un agent sous forme de chaîne lisible.
|
|
@@ -677,17 +760,17 @@ function formatAgentDetails(agentConfig) {
|
|
|
677
760
|
* @param agentConfig - Configuration de l'agent.
|
|
678
761
|
* @param discovery - Résultat de la découverte locale des outils.
|
|
679
762
|
*/
|
|
680
|
-
function formatAgentDetection(name, agentConfig, discovery) {
|
|
763
|
+
function formatAgentDetection(name, agentConfig, discovery, messages) {
|
|
681
764
|
if (agentConfig.type === "ollama") {
|
|
682
765
|
if (!discovery.ollama.available) {
|
|
683
|
-
return discovery.ollama.commandAvailable ?
|
|
766
|
+
return discovery.ollama.commandAvailable ? messages.agents.ollamaUnreachable : messages.agents.ollamaNotDetected;
|
|
684
767
|
}
|
|
685
768
|
return discovery.ollama.models.includes(agentConfig.model)
|
|
686
|
-
?
|
|
687
|
-
:
|
|
769
|
+
? messages.agents.detected()
|
|
770
|
+
: messages.agents.missingModel(agentConfig.model);
|
|
688
771
|
}
|
|
689
772
|
const detection = cliDetectionForAgent(name, agentConfig, discovery);
|
|
690
|
-
return detection.available ?
|
|
773
|
+
return detection.available ? messages.agents.detected(detection.command) : messages.agents.notDetected;
|
|
691
774
|
}
|
|
692
775
|
/**
|
|
693
776
|
* Résout l'entrée de détection correspondant à un agent CLI dans le résultat de découverte.
|
|
@@ -720,181 +803,108 @@ function normalizeCommandName(command) {
|
|
|
720
803
|
* @param discovery - Résultat de la découverte locale des outils.
|
|
721
804
|
* @param config - Config générée à partir de la découverte.
|
|
722
805
|
*/
|
|
723
|
-
function printInitDiscovery(discovery, config) {
|
|
806
|
+
function printInitDiscovery(discovery, config, messages) {
|
|
724
807
|
console.log("");
|
|
725
|
-
console.log(
|
|
726
|
-
console.log(`- Codex CLI: ${formatCommandDetection(discovery.codex)}`);
|
|
727
|
-
console.log(`- Claude CLI: ${formatCommandDetection(discovery.claude)}`);
|
|
728
|
-
console.log(`- Gemini CLI: ${formatCommandDetection(discovery.gemini)}`);
|
|
729
|
-
console.log(`- OpenCode CLI: ${formatCommandDetection(discovery.opencode)}`);
|
|
730
|
-
console.log(`- Ollama API: ${formatOllamaDetection(discovery.ollama)}`);
|
|
808
|
+
console.log(messages.init.localDetectionTitle);
|
|
809
|
+
console.log(`- Codex CLI: ${formatCommandDetection(discovery.codex, messages)}`);
|
|
810
|
+
console.log(`- Claude CLI: ${formatCommandDetection(discovery.claude, messages)}`);
|
|
811
|
+
console.log(`- Gemini CLI: ${formatCommandDetection(discovery.gemini, messages)}`);
|
|
812
|
+
console.log(`- OpenCode CLI: ${formatCommandDetection(discovery.opencode, messages)}`);
|
|
813
|
+
console.log(`- Ollama API: ${formatOllamaDetection(discovery.ollama, messages)}`);
|
|
731
814
|
console.log("");
|
|
732
|
-
console.log(
|
|
815
|
+
console.log(config.defaults?.agentA && config.defaults.agentB
|
|
816
|
+
? messages.init.defaults(config.defaults.agentA, config.defaults.agentB)
|
|
817
|
+
: messages.init.noDefaultPair(formatDetectedAgentSummary(discovery, config.language ?? DEFAULT_LANGUAGE)));
|
|
818
|
+
console.log(messages.init.languageHint(config.language ?? DEFAULT_LANGUAGE));
|
|
819
|
+
}
|
|
820
|
+
function formatDetectedAgentSummary(discovery, language) {
|
|
821
|
+
const names = [
|
|
822
|
+
discovery.codex.available ? "codex" : undefined,
|
|
823
|
+
discovery.claude.available ? "claude" : undefined,
|
|
824
|
+
discovery.gemini.available ? "gemini" : undefined,
|
|
825
|
+
discovery.opencode.available ? "opencode" : undefined,
|
|
826
|
+
discovery.ollama.available ? "ollama-local" : undefined
|
|
827
|
+
].filter((name) => Boolean(name));
|
|
828
|
+
if (names.length === 0) {
|
|
829
|
+
return language === "en" ? "no agent detected" : "aucun agent détecté";
|
|
830
|
+
}
|
|
831
|
+
if (names.length === 1) {
|
|
832
|
+
return language === "en"
|
|
833
|
+
? `only one agent detected (${names[0]})`
|
|
834
|
+
: `un seul agent détecté (${names[0]})`;
|
|
835
|
+
}
|
|
836
|
+
return language === "en"
|
|
837
|
+
? `no usable pair detected among ${names.join(", ")}`
|
|
838
|
+
: `aucune paire utilisable détectée parmi ${names.join(", ")}`;
|
|
733
839
|
}
|
|
734
840
|
/**
|
|
735
841
|
* Formate le statut de détection d'un outil CLI (disponible ou non).
|
|
736
842
|
* @param detection - Résultat de détection d'un outil CLI.
|
|
737
843
|
*/
|
|
738
|
-
function formatCommandDetection(detection) {
|
|
844
|
+
function formatCommandDetection(detection, messages) {
|
|
739
845
|
return detection.available
|
|
740
|
-
?
|
|
741
|
-
:
|
|
846
|
+
? messages.init.commandDetected(detection.command)
|
|
847
|
+
: messages.init.commandMissing;
|
|
742
848
|
}
|
|
743
849
|
/**
|
|
744
850
|
* Formate le statut de détection d'Ollama : commande absente, serveur injoignable ou modèles disponibles.
|
|
745
851
|
* @param detection - Résultat de détection d'Ollama.
|
|
746
852
|
*/
|
|
747
|
-
function formatOllamaDetection(detection) {
|
|
853
|
+
function formatOllamaDetection(detection, messages) {
|
|
748
854
|
if (!detection.available) {
|
|
749
855
|
return detection.commandAvailable
|
|
750
|
-
?
|
|
751
|
-
:
|
|
856
|
+
? messages.init.ollamaServerUnreachable(detection.baseUrl)
|
|
857
|
+
: messages.init.ollamaMissing;
|
|
752
858
|
}
|
|
753
859
|
const modelCount = detection.models.length;
|
|
754
|
-
return
|
|
860
|
+
return messages.init.ollamaDetected(modelCount);
|
|
755
861
|
}
|
|
756
862
|
/** Affiche le texte d'aide complet sur `stdout`. */
|
|
757
|
-
function printHelp() {
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
palabre init [--local]
|
|
788
|
-
Crée une config locale et détecte Codex, Claude, Gemini, OpenCode et Ollama.
|
|
789
|
-
|
|
790
|
-
palabre agents [--config <path>]
|
|
791
|
-
Liste les agents déclarés dans la config et leur détection locale.
|
|
792
|
-
|
|
793
|
-
palabre presets [--json]
|
|
794
|
-
Liste les presets de paires d'agents. \`--json\` émet la liste structurée
|
|
795
|
-
pour les intégrations (extension VS Code, scripts).
|
|
796
|
-
|
|
797
|
-
palabre config
|
|
798
|
-
Assistant pour définir ou supprimer les paramètres par défaut.
|
|
799
|
-
|
|
800
|
-
palabre config --set-defaults <agentA> <agentB> [-t <n>] [--summary-agent <name>]
|
|
801
|
-
Définit les agents par défaut, et optionnellement les réponses et la synthèse.
|
|
802
|
-
|
|
803
|
-
palabre config -t <n>
|
|
804
|
-
Définit seulement le nombre de réponses par défaut.
|
|
805
|
-
|
|
806
|
-
palabre config --summary-agent <name|none>
|
|
807
|
-
Définit ou retire seulement l'agent de synthèse par défaut.
|
|
808
|
-
|
|
809
|
-
palabre config --clear-defaults
|
|
810
|
-
Supprime les paramètres par défaut.
|
|
811
|
-
|
|
812
|
-
palabre doctor [--config <path>]
|
|
813
|
-
Vérifie la config et les outils locaux.
|
|
814
|
-
|
|
815
|
-
palabre update [--apply]
|
|
816
|
-
Affiche ou exécute les étapes de mise à jour d'un checkout git.
|
|
817
|
-
|
|
818
|
-
palabre help
|
|
819
|
-
Affiche cette aide. Identique à -h ou --help.
|
|
820
|
-
|
|
821
|
-
palabre version
|
|
822
|
-
Affiche la version. Identique à -v ou --version.
|
|
823
|
-
|
|
824
|
-
_____________________________________________
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
Notation:
|
|
828
|
-
|
|
829
|
-
[option] signifie facultatif. Ne tape pas les crochets.
|
|
830
|
-
<valeur> signifie qu'il faut remplacer ce texte par ta valeur.
|
|
831
|
-
|
|
832
|
-
Options générales:
|
|
833
|
-
|
|
834
|
-
-h, --help Affiche cette aide
|
|
835
|
-
-v, --version Affiche la version
|
|
836
|
-
-a, --agents Liste les agents. Identique à palabre agents
|
|
837
|
-
--config <path> Chemin vers un fichier de config explicite
|
|
838
|
-
--plain Utilise le rendu console simple sans habillage TUI
|
|
839
|
-
--json Émet un événement NDJSON par ligne sur stdout (alias de --renderer ndjson)
|
|
840
|
-
--renderer <kind> Force le renderer : auto | pretty | plain | ndjson
|
|
841
|
-
|
|
842
|
-
Sujet et lancement:
|
|
843
|
-
|
|
844
|
-
-s, --subject <text> Sujet du débat, option recommandée
|
|
845
|
-
--topic <text> Alias compatible de --subject
|
|
846
|
-
--agent-a <name> Premier agent
|
|
847
|
-
--agent-b <name> Second agent
|
|
848
|
-
--preset <name> Preset de paire d'agents. Exemples: codex-claude, claude-gemini
|
|
849
|
-
-t, --turns <number> Nombre total de réponses (1 à 20)
|
|
850
|
-
--no-early-stop Désactive l'arrêt anticipé si les agents sont clairement d'accord
|
|
851
|
-
|
|
852
|
-
Modèles:
|
|
853
|
-
|
|
854
|
-
--model-a <model> Modèle brut transmis à l'agent A
|
|
855
|
-
--model-b <model> Modèle brut transmis à l'agent B
|
|
856
|
-
--pull-models Autorise Ollama à télécharger un modèle manquant
|
|
857
|
-
|
|
858
|
-
Synthèse:
|
|
859
|
-
|
|
860
|
-
--summary-agent <name> Agent utilisé pour produire la synthèse finale
|
|
861
|
-
--summary-model <model> Modèle brut transmis à l'agent de synthèse
|
|
862
|
-
--no-summary Désactive la synthèse finale
|
|
863
|
-
|
|
864
|
-
Contexte:
|
|
865
|
-
|
|
866
|
-
--files <paths...> Fichiers texte à injecter explicitement dans le contexte
|
|
867
|
-
--context <paths...> Scanne fichiers/dossiers texte en respectant les limites de contexte
|
|
868
|
-
--show-prompt Affiche le prompt du premier tour sans appeler d'agent
|
|
869
|
-
|
|
870
|
-
Configuration:
|
|
871
|
-
|
|
872
|
-
--local Avec init/setup, crée ./palabre.config.json
|
|
873
|
-
--set-defaults <a b> Avec config, définit les agents par défaut
|
|
874
|
-
--summary-agent <name> Avec config, définit l'agent de synthèse par défaut
|
|
875
|
-
--summary-agent none Avec config, retire l'agent de synthèse par défaut
|
|
876
|
-
--clear-defaults Avec config, supprime les paramètres par défaut
|
|
877
|
-
--sync-agents Avec config, ajoute les agents détectés manquants
|
|
878
|
-
|
|
879
|
-
Mise à jour:
|
|
880
|
-
|
|
881
|
-
--apply Avec update, exécute les étapes de mise à jour
|
|
882
|
-
|
|
883
|
-
_____________________________________________
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
Presets disponibles:
|
|
887
|
-
|
|
888
|
-
${listPresetNames().join(", ")}
|
|
889
|
-
|
|
890
|
-
_____________________________________________
|
|
891
|
-
|
|
892
|
-
`);
|
|
863
|
+
function printHelp(messages, command) {
|
|
864
|
+
const commandHelp = command ? messages.help.renderCommand(command) : undefined;
|
|
865
|
+
console.log(commandHelp ?? messages.help.render(listPresetNames().join(", ")));
|
|
866
|
+
}
|
|
867
|
+
function commandHelpTarget(parsed) {
|
|
868
|
+
if (parsed.command === "help" || parsed.command === "run") {
|
|
869
|
+
return undefined;
|
|
870
|
+
}
|
|
871
|
+
if (parsed.command === "agent")
|
|
872
|
+
return "agents";
|
|
873
|
+
if (parsed.command === "preset")
|
|
874
|
+
return "presets";
|
|
875
|
+
if (parsed.command === "setup")
|
|
876
|
+
return "init";
|
|
877
|
+
return parsed.command;
|
|
878
|
+
}
|
|
879
|
+
/** Résout les messages d'une commande qui peut être affichée avant le flux principal. */
|
|
880
|
+
async function resolveCommandMessages(flags) {
|
|
881
|
+
const explicitLanguage = optionalString(flags.language);
|
|
882
|
+
const configPath = optionalString(flags.config) ?? await resolveDefaultConfigPath();
|
|
883
|
+
let configLanguage;
|
|
884
|
+
try {
|
|
885
|
+
configLanguage = await configExists(configPath)
|
|
886
|
+
? (await loadConfig(configPath)).language
|
|
887
|
+
: undefined;
|
|
888
|
+
}
|
|
889
|
+
catch {
|
|
890
|
+
configLanguage = undefined;
|
|
891
|
+
}
|
|
892
|
+
return createTranslator(resolveLanguage({ explicitLanguage, configLanguage }));
|
|
893
893
|
}
|
|
894
894
|
main().catch((error) => {
|
|
895
|
+
const language = safeStartupLanguage(process.argv.slice(2));
|
|
896
|
+
const messages = createTranslator(language);
|
|
895
897
|
const message = error instanceof AdapterError
|
|
896
|
-
? formatAdapterError(error)
|
|
898
|
+
? formatAdapterError(error, messages)
|
|
897
899
|
: error instanceof Error ? error.message : String(error);
|
|
898
|
-
console.error(
|
|
900
|
+
console.error(`${messages.common.errorPrefix}: ${message}`);
|
|
899
901
|
process.exitCode = 1;
|
|
900
902
|
});
|
|
903
|
+
function safeStartupLanguage(args) {
|
|
904
|
+
try {
|
|
905
|
+
return resolveLanguage({ explicitLanguage: findRawLanguageFlag(args) });
|
|
906
|
+
}
|
|
907
|
+
catch {
|
|
908
|
+
return DEFAULT_LANGUAGE;
|
|
909
|
+
}
|
|
910
|
+
}
|