palabre 0.2.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 +290 -245
- 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;
|
|
@@ -43,40 +47,69 @@ async function main() {
|
|
|
43
47
|
await runAgentsCommand(parsed.flags);
|
|
44
48
|
return;
|
|
45
49
|
}
|
|
50
|
+
if (parsed.command === "presets" || parsed.command === "preset") {
|
|
51
|
+
await runPresetsCommand(parsed.flags);
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
46
54
|
if (parsed.command === "update") {
|
|
47
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);
|
|
48
65
|
if (parsed.flags.apply) {
|
|
49
|
-
await applySourceUpdate(info);
|
|
50
|
-
console.log(
|
|
66
|
+
await applySourceUpdate(info, updateMessages);
|
|
67
|
+
console.log(updateMessages.update.upToDate);
|
|
51
68
|
return;
|
|
52
69
|
}
|
|
53
|
-
console.log(formatUpdateInstructions(info));
|
|
70
|
+
console.log(formatUpdateInstructions(info, updateMessages));
|
|
54
71
|
return;
|
|
55
72
|
}
|
|
56
73
|
if (parsed.command === "init" || parsed.command === "setup") {
|
|
57
74
|
const initConfigPath = optionalString(parsed.flags.config) ?? (parsed.flags.local ? DEFAULT_CONFIG_PATH : GLOBAL_CONFIG_PATH);
|
|
58
75
|
if (await configExists(initConfigPath)) {
|
|
59
|
-
console.log(
|
|
76
|
+
console.log(startupMessages.init.configExists(initConfigPath));
|
|
60
77
|
return;
|
|
61
78
|
}
|
|
62
79
|
const discovery = await discoverLocalTools();
|
|
63
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);
|
|
64
86
|
await writeExampleConfig(initConfigPath, config);
|
|
65
|
-
console.log(
|
|
66
|
-
printInitDiscovery(discovery, config);
|
|
87
|
+
console.log(initMessages.init.configCreated(initConfigPath));
|
|
88
|
+
printInitDiscovery(discovery, config, initMessages);
|
|
67
89
|
return;
|
|
68
90
|
}
|
|
69
91
|
const configPath = optionalString(parsed.flags.config) ?? await resolveDefaultConfigPath();
|
|
70
92
|
if (!(await configExists(configPath))) {
|
|
71
|
-
await
|
|
72
|
-
|
|
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));
|
|
73
101
|
return;
|
|
74
102
|
}
|
|
75
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);
|
|
76
109
|
if (parsed.command === "new") {
|
|
77
|
-
const selection = await runNewWizard(config);
|
|
110
|
+
const selection = await runNewWizard(config, messages);
|
|
78
111
|
if (!selection) {
|
|
79
|
-
console.log(
|
|
112
|
+
console.log(messages.new.cancelled);
|
|
80
113
|
return;
|
|
81
114
|
}
|
|
82
115
|
parsed.flags["agent-a"] = selection.agentA;
|
|
@@ -104,17 +137,18 @@ async function main() {
|
|
|
104
137
|
parsed.flags.context = selection.context;
|
|
105
138
|
}
|
|
106
139
|
const topic = optionalString(parsed.flags.topic) ?? "";
|
|
107
|
-
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);
|
|
108
141
|
const presetName = optionalString(parsed.flags.preset);
|
|
109
|
-
const preset = presetName ? resolvePreset(presetName) : undefined;
|
|
142
|
+
const preset = presetName ? resolvePreset(presetName, messages) : undefined;
|
|
110
143
|
if (!topic) {
|
|
111
|
-
throw new Error(
|
|
144
|
+
throw new Error(messages.common.topicRequired);
|
|
112
145
|
}
|
|
113
146
|
const options = {
|
|
147
|
+
language,
|
|
114
148
|
topic,
|
|
115
|
-
agentA: resolveAgentName("agent A", parsed.flags["agent-a"], preset?.agentA, config.defaults?.agentA),
|
|
116
|
-
agentB: resolveAgentName("agent B", parsed.flags["agent-b"], preset?.agentB, config.defaults?.agentB),
|
|
117
|
-
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),
|
|
118
152
|
session: createSessionContext(),
|
|
119
153
|
files: context.files,
|
|
120
154
|
modelA: optionalString(parsed.flags["model-a"]),
|
|
@@ -127,14 +161,14 @@ async function main() {
|
|
|
127
161
|
plainOutput: Boolean(parsed.flags.plain)
|
|
128
162
|
};
|
|
129
163
|
if (parsed.flags["show-prompt"]) {
|
|
130
|
-
printContextWarnings(context.warnings);
|
|
131
|
-
printPromptPreview(config, options);
|
|
164
|
+
printContextWarnings(context.warnings, messages);
|
|
165
|
+
printPromptPreview(config, options, language, messages);
|
|
132
166
|
return;
|
|
133
167
|
}
|
|
134
|
-
const renderer = createRendererFromFlags(parsed.flags, options.plainOutput);
|
|
168
|
+
const renderer = createRendererFromFlags(parsed.flags, options.plainOutput, messages);
|
|
135
169
|
context.warnings.forEach((warning) => renderer.warning(warning));
|
|
136
|
-
const result = await runDebate(config, options, renderer);
|
|
137
|
-
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);
|
|
138
172
|
renderer.done(outputPath);
|
|
139
173
|
}
|
|
140
174
|
/**
|
|
@@ -144,11 +178,17 @@ async function main() {
|
|
|
144
178
|
async function runAgentsCommand(flags) {
|
|
145
179
|
const configPath = optionalString(flags.config) ?? await resolveDefaultConfigPath();
|
|
146
180
|
if (!(await configExists(configPath))) {
|
|
147
|
-
|
|
181
|
+
const messages = createTranslator(resolveLanguage({ explicitLanguage: optionalString(flags.language) }));
|
|
182
|
+
throw new Error(messages.agents.noConfig);
|
|
148
183
|
}
|
|
149
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);
|
|
150
190
|
const discovery = await discoverLocalTools();
|
|
151
|
-
printAgents(configPath, config, discovery);
|
|
191
|
+
printAgents(configPath, config, discovery, messages);
|
|
152
192
|
}
|
|
153
193
|
/**
|
|
154
194
|
* Exécute la commande `config` : wizard interactif ou mise à jour directe des paramètres par défaut.
|
|
@@ -156,62 +196,76 @@ async function runAgentsCommand(flags) {
|
|
|
156
196
|
*/
|
|
157
197
|
async function runConfigCommand(flags) {
|
|
158
198
|
const configPath = optionalString(flags.config) ?? await resolveDefaultConfigPath();
|
|
199
|
+
const explicitLanguage = optionalString(flags.language);
|
|
159
200
|
if (!(await configExists(configPath))) {
|
|
201
|
+
const messages = createTranslator(resolveLanguage({ explicitLanguage }));
|
|
160
202
|
await writeExampleConfig(configPath);
|
|
161
|
-
console.log(
|
|
203
|
+
console.log(messages.config.createdForConfig(configPath));
|
|
162
204
|
return;
|
|
163
205
|
}
|
|
164
206
|
const config = await loadConfig(configPath);
|
|
207
|
+
const language = resolveLanguage({
|
|
208
|
+
explicitLanguage,
|
|
209
|
+
configLanguage: config.language
|
|
210
|
+
});
|
|
211
|
+
const messages = createTranslator(language);
|
|
165
212
|
if (flags["sync-agents"]) {
|
|
166
213
|
const discovery = await discoverLocalTools();
|
|
167
214
|
const addedAgents = syncDetectedAgents(config, discovery);
|
|
168
215
|
if (addedAgents.length === 0) {
|
|
169
|
-
console.log(
|
|
216
|
+
console.log(messages.config.syncNoMissing(configPath));
|
|
170
217
|
return;
|
|
171
218
|
}
|
|
172
219
|
await writeExampleConfig(configPath, config);
|
|
173
|
-
console.log(
|
|
220
|
+
console.log(messages.config.syncAdded(configPath, addedAgents.join(", ")));
|
|
174
221
|
return;
|
|
175
222
|
}
|
|
176
223
|
const defaultAgents = getStringListFlag(flags["set-defaults"]);
|
|
177
224
|
const hasTurnsFlag = flags.turns !== undefined;
|
|
178
225
|
const summaryAgentValue = optionalString(flags["summary-agent"]);
|
|
179
|
-
|
|
226
|
+
const languageValue = explicitLanguage;
|
|
227
|
+
const changesDefaults = defaultAgents.length > 0 || hasTurnsFlag || summaryAgentValue !== undefined;
|
|
228
|
+
if (changesDefaults || languageValue !== undefined) {
|
|
180
229
|
const nextDefaults = { ...(config.defaults ?? {}) };
|
|
181
230
|
if (defaultAgents.length > 0) {
|
|
182
231
|
const [agentA, agentB] = defaultAgents;
|
|
183
232
|
if (!agentA || !agentB) {
|
|
184
|
-
throw new Error(
|
|
233
|
+
throw new Error(messages.common.setDefaultsRequiresTwo);
|
|
185
234
|
}
|
|
186
|
-
assertKnownAgent(config, agentA, "defaults.agentA");
|
|
187
|
-
assertKnownAgent(config, agentB, "defaults.agentB");
|
|
235
|
+
assertKnownAgent(config, agentA, "defaults.agentA", messages);
|
|
236
|
+
assertKnownAgent(config, agentB, "defaults.agentB", messages);
|
|
188
237
|
nextDefaults.agentA = agentA;
|
|
189
238
|
nextDefaults.agentB = agentB;
|
|
190
239
|
}
|
|
191
240
|
if (hasTurnsFlag) {
|
|
192
|
-
nextDefaults.turns = parseTurnsFlag(flags.turns, nextDefaults.turns ?? DEFAULT_TURNS, "--turns");
|
|
241
|
+
nextDefaults.turns = parseTurnsFlag(flags.turns, nextDefaults.turns ?? DEFAULT_TURNS, "--turns", messages);
|
|
193
242
|
}
|
|
194
243
|
if (summaryAgentValue !== undefined) {
|
|
195
244
|
if (isNoneValue(summaryAgentValue)) {
|
|
196
245
|
delete nextDefaults.summaryAgent;
|
|
197
246
|
}
|
|
198
247
|
else {
|
|
199
|
-
assertKnownAgent(config, summaryAgentValue, "defaults.summaryAgent");
|
|
248
|
+
assertKnownAgent(config, summaryAgentValue, "defaults.summaryAgent", messages);
|
|
200
249
|
nextDefaults.summaryAgent = summaryAgentValue;
|
|
201
250
|
}
|
|
202
251
|
}
|
|
203
|
-
|
|
252
|
+
if (languageValue !== undefined) {
|
|
253
|
+
config.language = parseLanguage(languageValue, "--language");
|
|
254
|
+
}
|
|
255
|
+
if (changesDefaults) {
|
|
256
|
+
config.defaults = nextDefaults;
|
|
257
|
+
}
|
|
204
258
|
await writeExampleConfig(configPath, config);
|
|
205
|
-
console.log(
|
|
259
|
+
console.log(messages.config.updated(configPath, formatDefaultsForMessage(config.defaults ?? {}, messages), config.language ?? DEFAULT_LANGUAGE));
|
|
206
260
|
return;
|
|
207
261
|
}
|
|
208
262
|
if (flags["clear-defaults"]) {
|
|
209
263
|
delete config.defaults;
|
|
210
264
|
await writeExampleConfig(configPath, config);
|
|
211
|
-
console.log(
|
|
265
|
+
console.log(messages.config.cleared(configPath));
|
|
212
266
|
return;
|
|
213
267
|
}
|
|
214
|
-
await runConfigWizard(configPath, config);
|
|
268
|
+
await runConfigWizard(configPath, config, messages);
|
|
215
269
|
}
|
|
216
270
|
/**
|
|
217
271
|
* Renvoie `true` si la valeur représente une désactivation explicite (ex. "none", "0", "disabled").
|
|
@@ -225,12 +279,8 @@ function isNoneValue(value) {
|
|
|
225
279
|
* @param defaults - Objet `defaults` de la config Palabre.
|
|
226
280
|
* @returns Chaîne résumant la paire d'agents, le nombre de réponses et l'agent de synthèse.
|
|
227
281
|
*/
|
|
228
|
-
function formatDefaultsForMessage(defaults) {
|
|
229
|
-
|
|
230
|
-
? `agents: ${defaults.agentA} <-> ${defaults.agentB}`
|
|
231
|
-
: "agents: non définis";
|
|
232
|
-
const summary = defaults.summaryAgent ? `synthèse: ${defaults.summaryAgent}` : "synthèse: agent B";
|
|
233
|
-
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);
|
|
234
284
|
}
|
|
235
285
|
/**
|
|
236
286
|
* Lève une erreur si `agentName` n'est pas déclaré dans la config.
|
|
@@ -238,9 +288,9 @@ function formatDefaultsForMessage(defaults) {
|
|
|
238
288
|
* @param agentName - Nom de l'agent à vérifier.
|
|
239
289
|
* @param fieldName - Nom du champ (utilisé dans le message d'erreur).
|
|
240
290
|
*/
|
|
241
|
-
function assertKnownAgent(config, agentName, fieldName) {
|
|
291
|
+
function assertKnownAgent(config, agentName, fieldName, messages) {
|
|
242
292
|
if (!config.agents[agentName]) {
|
|
243
|
-
throw new Error(
|
|
293
|
+
throw new Error(messages.common.unknownAgentForField(fieldName, agentName, Object.keys(config.agents).join(", ")));
|
|
244
294
|
}
|
|
245
295
|
}
|
|
246
296
|
/**
|
|
@@ -252,10 +302,10 @@ function assertKnownAgent(config, agentName, fieldName) {
|
|
|
252
302
|
* @param defaultValue - Valeur issue des défauts de la config.
|
|
253
303
|
* @returns Nom de l'agent résolu.
|
|
254
304
|
*/
|
|
255
|
-
function resolveAgentName(label, explicitValue, presetValue, defaultValue) {
|
|
305
|
+
function resolveAgentName(label, explicitValue, presetValue, defaultValue, messages) {
|
|
256
306
|
const resolved = optionalString(explicitValue) ?? presetValue ?? defaultValue;
|
|
257
307
|
if (!resolved) {
|
|
258
|
-
throw new Error(
|
|
308
|
+
throw new Error(messages.common.noAgentDefined(label));
|
|
259
309
|
}
|
|
260
310
|
return resolved;
|
|
261
311
|
}
|
|
@@ -264,30 +314,33 @@ function resolveAgentName(label, explicitValue, presetValue, defaultValue) {
|
|
|
264
314
|
* @param config - Config chargée.
|
|
265
315
|
* @param options - Options du débat résolues.
|
|
266
316
|
*/
|
|
267
|
-
function printPromptPreview(config, options) {
|
|
317
|
+
function printPromptPreview(config, options, language, messages) {
|
|
268
318
|
const agentConfig = config.agents[options.agentA];
|
|
269
319
|
if (!agentConfig) {
|
|
270
|
-
throw new Error(
|
|
320
|
+
throw new Error(messages.common.unknownAgent(options.agentA));
|
|
271
321
|
}
|
|
272
322
|
const prompt = formatAgentPrompt({
|
|
273
323
|
topic: options.topic,
|
|
274
324
|
turn: 1,
|
|
325
|
+
totalTurns: options.turns,
|
|
275
326
|
selfName: options.agentA,
|
|
276
327
|
peerName: options.agentB,
|
|
277
328
|
selfRole: agentConfig.role,
|
|
329
|
+
language: options.language,
|
|
278
330
|
session: options.session,
|
|
279
331
|
files: options.files,
|
|
280
332
|
transcript: []
|
|
281
333
|
});
|
|
282
|
-
console.log(
|
|
283
|
-
console.log(
|
|
284
|
-
console.log(
|
|
285
|
-
console.log(
|
|
286
|
-
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));
|
|
287
340
|
console.log("");
|
|
288
341
|
console.log(prompt);
|
|
289
342
|
console.log("");
|
|
290
|
-
console.log(
|
|
343
|
+
console.log(messages.preview.note);
|
|
291
344
|
}
|
|
292
345
|
/**
|
|
293
346
|
* Extrait une chaîne non vide depuis une valeur de flag, ou renvoie `undefined`.
|
|
@@ -296,6 +349,20 @@ function printPromptPreview(config, options) {
|
|
|
296
349
|
function optionalString(value) {
|
|
297
350
|
return typeof value === "string" && value.trim() ? value : undefined;
|
|
298
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
|
+
}
|
|
299
366
|
/** Liste des kinds de renderer acceptés par `--renderer`. */
|
|
300
367
|
const SUPPORTED_RENDERERS = ["auto", "pretty", "plain", "ndjson"];
|
|
301
368
|
/**
|
|
@@ -309,28 +376,65 @@ const SUPPORTED_RENDERERS = ["auto", "pretty", "plain", "ndjson"];
|
|
|
309
376
|
*
|
|
310
377
|
* Lève si la valeur de `--renderer` n'est pas dans `SUPPORTED_RENDERERS`.
|
|
311
378
|
*/
|
|
312
|
-
function createRendererFromFlags(flags, plainOutputFallback) {
|
|
379
|
+
function createRendererFromFlags(flags, plainOutputFallback, messages) {
|
|
313
380
|
const explicit = optionalString(flags.renderer);
|
|
314
381
|
if (explicit) {
|
|
315
382
|
if (!SUPPORTED_RENDERERS.includes(explicit)) {
|
|
316
|
-
throw new Error(
|
|
383
|
+
throw new Error(messages.common.unknownRenderer(explicit, SUPPORTED_RENDERERS.join(", ")));
|
|
317
384
|
}
|
|
318
385
|
const kind = explicit;
|
|
319
386
|
switch (kind) {
|
|
320
387
|
case "ndjson":
|
|
321
388
|
return createNdjsonRenderer();
|
|
322
389
|
case "plain":
|
|
323
|
-
return createConsoleRenderer(true);
|
|
390
|
+
return createConsoleRenderer(true, messages);
|
|
324
391
|
case "pretty":
|
|
325
|
-
return createConsoleRenderer(false);
|
|
392
|
+
return createConsoleRenderer(false, messages);
|
|
326
393
|
case "auto":
|
|
327
|
-
return createConsoleRenderer(plainOutputFallback);
|
|
394
|
+
return createConsoleRenderer(plainOutputFallback, messages);
|
|
328
395
|
}
|
|
329
396
|
}
|
|
330
397
|
if (flags.json) {
|
|
331
398
|
return createNdjsonRenderer();
|
|
332
399
|
}
|
|
333
|
-
return createConsoleRenderer(plainOutputFallback);
|
|
400
|
+
return createConsoleRenderer(plainOutputFallback, messages);
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* Exécute la commande `palabre presets`.
|
|
404
|
+
*
|
|
405
|
+
* Sortie humaine par défaut (liste alignée), ou JSON avec `--json` pour les
|
|
406
|
+
* intégrations (extension VS Code, scripts shell). Le schéma JSON est versionné
|
|
407
|
+
* via le champ `v` au cas où on enrichirait plus tard (ex : description par
|
|
408
|
+
* preset, tags premium/local).
|
|
409
|
+
*
|
|
410
|
+
* @param flags - Flags parsés depuis la ligne de commande.
|
|
411
|
+
*/
|
|
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
|
|
421
|
+
});
|
|
422
|
+
const messages = createTranslator(language);
|
|
423
|
+
const presets = listPresetsWithAvailability(config, discovery, messages);
|
|
424
|
+
if (flags.json) {
|
|
425
|
+
process.stdout.write(JSON.stringify({ v: 1, presets }) + "\n");
|
|
426
|
+
return;
|
|
427
|
+
}
|
|
428
|
+
console.log(messages.presets.title);
|
|
429
|
+
console.log("");
|
|
430
|
+
for (const preset of presets) {
|
|
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}`);
|
|
435
|
+
}
|
|
436
|
+
console.log("");
|
|
437
|
+
console.log(messages.presets.total(presets.length));
|
|
334
438
|
}
|
|
335
439
|
/**
|
|
336
440
|
* Parse `process.argv` en une structure typée `ParsedArgs`.
|
|
@@ -339,22 +443,27 @@ function createRendererFromFlags(flags, plainOutputFallback) {
|
|
|
339
443
|
* @param args - Tableau d'arguments (généralement `process.argv.slice(2)`).
|
|
340
444
|
* @returns Commande détectée, indicateur d'explicitation et map de flags.
|
|
341
445
|
*/
|
|
342
|
-
function parseArgs(args) {
|
|
446
|
+
function parseArgs(args, messages) {
|
|
343
447
|
const flags = {};
|
|
344
448
|
let command = "run";
|
|
345
449
|
let commandExplicit = false;
|
|
346
450
|
const positionals = [];
|
|
347
|
-
const commands = new Set(["run", "new", "init", "setup", "help", "version", "update", "doctor", "config", "agent", "agents"]);
|
|
451
|
+
const commands = new Set(["run", "new", "init", "setup", "help", "version", "update", "doctor", "config", "agent", "agents", "preset", "presets"]);
|
|
348
452
|
const presets = new Set(listPresetNames());
|
|
349
453
|
for (let index = 0; index < args.length; index += 1) {
|
|
350
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
|
+
}
|
|
351
460
|
if (!value.startsWith("-") && index === 0) {
|
|
352
461
|
if (commands.has(value)) {
|
|
353
462
|
command = value;
|
|
354
463
|
commandExplicit = true;
|
|
355
464
|
}
|
|
356
465
|
else if (isLikelyCommandTypo(value, commands)) {
|
|
357
|
-
throw new Error(
|
|
466
|
+
throw new Error(messages.common.unknownCommand(value, Array.from(commands).join(", ")));
|
|
358
467
|
}
|
|
359
468
|
else {
|
|
360
469
|
positionals.push(value);
|
|
@@ -381,7 +490,7 @@ function parseArgs(args) {
|
|
|
381
490
|
if (value === "-s") {
|
|
382
491
|
const next = args[index + 1];
|
|
383
492
|
if (!next || next.startsWith("-")) {
|
|
384
|
-
throw new Error("
|
|
493
|
+
throw new Error(messages.common.optionRequiresValue("-s"));
|
|
385
494
|
}
|
|
386
495
|
flags.topic = next;
|
|
387
496
|
index += 1;
|
|
@@ -390,7 +499,7 @@ function parseArgs(args) {
|
|
|
390
499
|
if (value === "-t") {
|
|
391
500
|
const next = args[index + 1];
|
|
392
501
|
if (!next || next.startsWith("-")) {
|
|
393
|
-
throw new Error("
|
|
502
|
+
throw new Error(messages.common.optionRequiresValue("-t"));
|
|
394
503
|
}
|
|
395
504
|
flags.turns = next;
|
|
396
505
|
index += 1;
|
|
@@ -406,7 +515,7 @@ function parseArgs(args) {
|
|
|
406
515
|
index += 1;
|
|
407
516
|
}
|
|
408
517
|
if (values.length !== 2) {
|
|
409
|
-
throw new Error(
|
|
518
|
+
throw new Error(messages.common.setDefaultsRequiresTwo);
|
|
410
519
|
}
|
|
411
520
|
flags[key] = values;
|
|
412
521
|
continue;
|
|
@@ -423,7 +532,7 @@ function parseArgs(args) {
|
|
|
423
532
|
const next = args[index + 1];
|
|
424
533
|
if (!next || next.startsWith("-")) {
|
|
425
534
|
if (requiresFlagValue(key)) {
|
|
426
|
-
throw new Error(
|
|
535
|
+
throw new Error(messages.common.optionRequiresValue(`--${rawKey}`));
|
|
427
536
|
}
|
|
428
537
|
flags[key] = true;
|
|
429
538
|
}
|
|
@@ -434,7 +543,7 @@ function parseArgs(args) {
|
|
|
434
543
|
}
|
|
435
544
|
}
|
|
436
545
|
if (command === "run") {
|
|
437
|
-
applyRunPositionals(positionals, flags, presets, commandExplicit);
|
|
546
|
+
applyRunPositionals(positionals, flags, presets, commandExplicit, commands, messages);
|
|
438
547
|
}
|
|
439
548
|
return { command, commandExplicit, flags };
|
|
440
549
|
}
|
|
@@ -482,7 +591,7 @@ function levenshteinDistance(left, right) {
|
|
|
482
591
|
* @param presets - Ensemble des noms de presets valides.
|
|
483
592
|
* @param commandExplicit - `true` si l'utilisateur a tapé `palabre run` explicitement.
|
|
484
593
|
*/
|
|
485
|
-
function applyRunPositionals(positionals, flags, presets, commandExplicit) {
|
|
594
|
+
function applyRunPositionals(positionals, flags, presets, commandExplicit, commands, messages) {
|
|
486
595
|
if (positionals.length === 0) {
|
|
487
596
|
return;
|
|
488
597
|
}
|
|
@@ -495,7 +604,10 @@ function applyRunPositionals(positionals, flags, presets, commandExplicit) {
|
|
|
495
604
|
return;
|
|
496
605
|
}
|
|
497
606
|
if (!commandExplicit && positionals.length === 1 && !positionals[0]?.includes(" ")) {
|
|
498
|
-
|
|
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]));
|
|
499
611
|
}
|
|
500
612
|
flags.topic ??= positionals.join(" ");
|
|
501
613
|
}
|
|
@@ -505,6 +617,7 @@ function applyRunPositionals(positionals, flags, presets, commandExplicit) {
|
|
|
505
617
|
*/
|
|
506
618
|
function normalizeFlagName(value) {
|
|
507
619
|
const aliases = {
|
|
620
|
+
lang: "language",
|
|
508
621
|
s: "topic",
|
|
509
622
|
subject: "topic",
|
|
510
623
|
t: "turns"
|
|
@@ -520,6 +633,7 @@ function requiresFlagValue(value) {
|
|
|
520
633
|
"agent-a",
|
|
521
634
|
"agent-b",
|
|
522
635
|
"config",
|
|
636
|
+
"language",
|
|
523
637
|
"model-a",
|
|
524
638
|
"model-b",
|
|
525
639
|
"preset",
|
|
@@ -555,9 +669,9 @@ function getStringListFlag(value) {
|
|
|
555
669
|
* Écrit les avertissements de contexte sur `stderr`.
|
|
556
670
|
* @param warnings - Messages d'avertissement issus du chargement des fichiers de contexte.
|
|
557
671
|
*/
|
|
558
|
-
function printContextWarnings(warnings) {
|
|
672
|
+
function printContextWarnings(warnings, messages) {
|
|
559
673
|
for (const warning of warnings) {
|
|
560
|
-
process.stderr.write(
|
|
674
|
+
process.stderr.write(`${messages.renderers.warningPrefix} ${warning}\n`);
|
|
561
675
|
}
|
|
562
676
|
}
|
|
563
677
|
/**
|
|
@@ -596,15 +710,15 @@ function findDetectedMissingAgents(config, discovery) {
|
|
|
596
710
|
* @param config - Config Palabre chargée.
|
|
597
711
|
* @param discovery - Résultat de la découverte locale des outils.
|
|
598
712
|
*/
|
|
599
|
-
function printAgents(configPath, config, discovery) {
|
|
713
|
+
function printAgents(configPath, config, discovery, messages) {
|
|
600
714
|
const entries = Object.entries(config.agents).sort(([left], [right]) => left.localeCompare(right));
|
|
601
|
-
console.log(
|
|
715
|
+
console.log(messages.agents.config(configPath));
|
|
602
716
|
console.log("");
|
|
603
|
-
console.log(
|
|
717
|
+
console.log(messages.agents.title);
|
|
604
718
|
for (const [name, agentConfig] of entries) {
|
|
605
|
-
const status = formatAgentDetection(name, agentConfig, discovery);
|
|
606
|
-
const defaults = formatAgentDefaults(name, config);
|
|
607
|
-
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);
|
|
608
722
|
const suffix = defaults ? ` | ${defaults}` : "";
|
|
609
723
|
console.log(`- ${name.padEnd(13)} ${`${agentConfig.type}/${agentConfig.role}`.padEnd(18)} ${status}${suffix}`);
|
|
610
724
|
if (details) {
|
|
@@ -612,32 +726,32 @@ function printAgents(configPath, config, discovery) {
|
|
|
612
726
|
}
|
|
613
727
|
}
|
|
614
728
|
console.log("");
|
|
615
|
-
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));
|
|
616
730
|
}
|
|
617
731
|
/**
|
|
618
732
|
* Renvoie un libellé indiquant si l'agent est agent A, agent B ou agent de synthèse par défaut.
|
|
619
733
|
* @param name - Nom de l'agent.
|
|
620
734
|
* @param config - Config Palabre contenant les défauts.
|
|
621
735
|
*/
|
|
622
|
-
function formatAgentDefaults(name, config) {
|
|
736
|
+
function formatAgentDefaults(name, config, messages) {
|
|
623
737
|
const labels = [];
|
|
624
738
|
if (config.defaults?.agentA === name)
|
|
625
|
-
labels.push(
|
|
739
|
+
labels.push(messages.agents.defaultAgentA);
|
|
626
740
|
if (config.defaults?.agentB === name)
|
|
627
|
-
labels.push(
|
|
741
|
+
labels.push(messages.agents.defaultAgentB);
|
|
628
742
|
if (config.defaults?.summaryAgent === name)
|
|
629
|
-
labels.push(
|
|
743
|
+
labels.push(messages.agents.defaultSummary);
|
|
630
744
|
return labels.join(", ");
|
|
631
745
|
}
|
|
632
746
|
/**
|
|
633
747
|
* Renvoie une ligne de détails pour un agent : commande CLI ou modèle Ollama.
|
|
634
748
|
* @param agentConfig - Configuration de l'agent.
|
|
635
749
|
*/
|
|
636
|
-
function formatAgentDetails(agentConfig) {
|
|
750
|
+
function formatAgentDetails(agentConfig, messages) {
|
|
637
751
|
if (agentConfig.type === "ollama") {
|
|
638
|
-
return
|
|
752
|
+
return messages.agents.model(agentConfig.model);
|
|
639
753
|
}
|
|
640
|
-
return
|
|
754
|
+
return messages.agents.command(agentConfig.command, agentConfig.model);
|
|
641
755
|
}
|
|
642
756
|
/**
|
|
643
757
|
* Renvoie le statut de détection d'un agent sous forme de chaîne lisible.
|
|
@@ -646,17 +760,17 @@ function formatAgentDetails(agentConfig) {
|
|
|
646
760
|
* @param agentConfig - Configuration de l'agent.
|
|
647
761
|
* @param discovery - Résultat de la découverte locale des outils.
|
|
648
762
|
*/
|
|
649
|
-
function formatAgentDetection(name, agentConfig, discovery) {
|
|
763
|
+
function formatAgentDetection(name, agentConfig, discovery, messages) {
|
|
650
764
|
if (agentConfig.type === "ollama") {
|
|
651
765
|
if (!discovery.ollama.available) {
|
|
652
|
-
return discovery.ollama.commandAvailable ?
|
|
766
|
+
return discovery.ollama.commandAvailable ? messages.agents.ollamaUnreachable : messages.agents.ollamaNotDetected;
|
|
653
767
|
}
|
|
654
768
|
return discovery.ollama.models.includes(agentConfig.model)
|
|
655
|
-
?
|
|
656
|
-
:
|
|
769
|
+
? messages.agents.detected()
|
|
770
|
+
: messages.agents.missingModel(agentConfig.model);
|
|
657
771
|
}
|
|
658
772
|
const detection = cliDetectionForAgent(name, agentConfig, discovery);
|
|
659
|
-
return detection.available ?
|
|
773
|
+
return detection.available ? messages.agents.detected(detection.command) : messages.agents.notDetected;
|
|
660
774
|
}
|
|
661
775
|
/**
|
|
662
776
|
* Résout l'entrée de détection correspondant à un agent CLI dans le résultat de découverte.
|
|
@@ -689,177 +803,108 @@ function normalizeCommandName(command) {
|
|
|
689
803
|
* @param discovery - Résultat de la découverte locale des outils.
|
|
690
804
|
* @param config - Config générée à partir de la découverte.
|
|
691
805
|
*/
|
|
692
|
-
function printInitDiscovery(discovery, config) {
|
|
806
|
+
function printInitDiscovery(discovery, config, messages) {
|
|
693
807
|
console.log("");
|
|
694
|
-
console.log(
|
|
695
|
-
console.log(`- Codex CLI: ${formatCommandDetection(discovery.codex)}`);
|
|
696
|
-
console.log(`- Claude CLI: ${formatCommandDetection(discovery.claude)}`);
|
|
697
|
-
console.log(`- Gemini CLI: ${formatCommandDetection(discovery.gemini)}`);
|
|
698
|
-
console.log(`- OpenCode CLI: ${formatCommandDetection(discovery.opencode)}`);
|
|
699
|
-
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)}`);
|
|
700
814
|
console.log("");
|
|
701
|
-
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(", ")}`;
|
|
702
839
|
}
|
|
703
840
|
/**
|
|
704
841
|
* Formate le statut de détection d'un outil CLI (disponible ou non).
|
|
705
842
|
* @param detection - Résultat de détection d'un outil CLI.
|
|
706
843
|
*/
|
|
707
|
-
function formatCommandDetection(detection) {
|
|
844
|
+
function formatCommandDetection(detection, messages) {
|
|
708
845
|
return detection.available
|
|
709
|
-
?
|
|
710
|
-
:
|
|
846
|
+
? messages.init.commandDetected(detection.command)
|
|
847
|
+
: messages.init.commandMissing;
|
|
711
848
|
}
|
|
712
849
|
/**
|
|
713
850
|
* Formate le statut de détection d'Ollama : commande absente, serveur injoignable ou modèles disponibles.
|
|
714
851
|
* @param detection - Résultat de détection d'Ollama.
|
|
715
852
|
*/
|
|
716
|
-
function formatOllamaDetection(detection) {
|
|
853
|
+
function formatOllamaDetection(detection, messages) {
|
|
717
854
|
if (!detection.available) {
|
|
718
855
|
return detection.commandAvailable
|
|
719
|
-
?
|
|
720
|
-
:
|
|
856
|
+
? messages.init.ollamaServerUnreachable(detection.baseUrl)
|
|
857
|
+
: messages.init.ollamaMissing;
|
|
721
858
|
}
|
|
722
859
|
const modelCount = detection.models.length;
|
|
723
|
-
return
|
|
860
|
+
return messages.init.ollamaDetected(modelCount);
|
|
724
861
|
}
|
|
725
862
|
/** Affiche le texte d'aide complet sur `stdout`. */
|
|
726
|
-
function printHelp() {
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
palabre init [--local]
|
|
757
|
-
Crée une config locale et détecte Codex, Claude, Gemini, OpenCode et Ollama.
|
|
758
|
-
|
|
759
|
-
palabre agents [--config <path>]
|
|
760
|
-
Liste les agents déclarés dans la config et leur détection locale.
|
|
761
|
-
|
|
762
|
-
palabre config
|
|
763
|
-
Assistant pour définir ou supprimer les paramètres par défaut.
|
|
764
|
-
|
|
765
|
-
palabre config --set-defaults <agentA> <agentB> [-t <n>] [--summary-agent <name>]
|
|
766
|
-
Définit les agents par défaut, et optionnellement les réponses et la synthèse.
|
|
767
|
-
|
|
768
|
-
palabre config -t <n>
|
|
769
|
-
Définit seulement le nombre de réponses par défaut.
|
|
770
|
-
|
|
771
|
-
palabre config --summary-agent <name|none>
|
|
772
|
-
Définit ou retire seulement l'agent de synthèse par défaut.
|
|
773
|
-
|
|
774
|
-
palabre config --clear-defaults
|
|
775
|
-
Supprime les paramètres par défaut.
|
|
776
|
-
|
|
777
|
-
palabre doctor [--config <path>]
|
|
778
|
-
Vérifie la config et les outils locaux.
|
|
779
|
-
|
|
780
|
-
palabre update [--apply]
|
|
781
|
-
Affiche ou exécute les étapes de mise à jour d'un checkout git.
|
|
782
|
-
|
|
783
|
-
palabre help
|
|
784
|
-
Affiche cette aide. Identique à -h ou --help.
|
|
785
|
-
|
|
786
|
-
palabre version
|
|
787
|
-
Affiche la version. Identique à -v ou --version.
|
|
788
|
-
|
|
789
|
-
_____________________________________________
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
Notation:
|
|
793
|
-
|
|
794
|
-
[option] signifie facultatif. Ne tape pas les crochets.
|
|
795
|
-
<valeur> signifie qu'il faut remplacer ce texte par ta valeur.
|
|
796
|
-
|
|
797
|
-
Options générales:
|
|
798
|
-
|
|
799
|
-
-h, --help Affiche cette aide
|
|
800
|
-
-v, --version Affiche la version
|
|
801
|
-
-a, --agents Liste les agents. Identique à palabre agents
|
|
802
|
-
--config <path> Chemin vers un fichier de config explicite
|
|
803
|
-
--plain Utilise le rendu console simple sans habillage TUI
|
|
804
|
-
--json Émet un événement NDJSON par ligne sur stdout (alias de --renderer ndjson)
|
|
805
|
-
--renderer <kind> Force le renderer : auto | pretty | plain | ndjson
|
|
806
|
-
|
|
807
|
-
Sujet et lancement:
|
|
808
|
-
|
|
809
|
-
-s, --subject <text> Sujet du débat, option recommandée
|
|
810
|
-
--topic <text> Alias compatible de --subject
|
|
811
|
-
--agent-a <name> Premier agent
|
|
812
|
-
--agent-b <name> Second agent
|
|
813
|
-
--preset <name> Preset de paire d'agents. Exemples: codex-claude, claude-gemini
|
|
814
|
-
-t, --turns <number> Nombre total de réponses (1 à 20)
|
|
815
|
-
--no-early-stop Désactive l'arrêt anticipé si les agents sont clairement d'accord
|
|
816
|
-
|
|
817
|
-
Modèles:
|
|
818
|
-
|
|
819
|
-
--model-a <model> Modèle brut transmis à l'agent A
|
|
820
|
-
--model-b <model> Modèle brut transmis à l'agent B
|
|
821
|
-
--pull-models Autorise Ollama à télécharger un modèle manquant
|
|
822
|
-
|
|
823
|
-
Synthèse:
|
|
824
|
-
|
|
825
|
-
--summary-agent <name> Agent utilisé pour produire la synthèse finale
|
|
826
|
-
--summary-model <model> Modèle brut transmis à l'agent de synthèse
|
|
827
|
-
--no-summary Désactive la synthèse finale
|
|
828
|
-
|
|
829
|
-
Contexte:
|
|
830
|
-
|
|
831
|
-
--files <paths...> Fichiers texte à injecter explicitement dans le contexte
|
|
832
|
-
--context <paths...> Scanne fichiers/dossiers texte en respectant les limites de contexte
|
|
833
|
-
--show-prompt Affiche le prompt du premier tour sans appeler d'agent
|
|
834
|
-
|
|
835
|
-
Configuration:
|
|
836
|
-
|
|
837
|
-
--local Avec init/setup, crée ./palabre.config.json
|
|
838
|
-
--set-defaults <a b> Avec config, définit les agents par défaut
|
|
839
|
-
--summary-agent <name> Avec config, définit l'agent de synthèse par défaut
|
|
840
|
-
--summary-agent none Avec config, retire l'agent de synthèse par défaut
|
|
841
|
-
--clear-defaults Avec config, supprime les paramètres par défaut
|
|
842
|
-
--sync-agents Avec config, ajoute les agents détectés manquants
|
|
843
|
-
|
|
844
|
-
Mise à jour:
|
|
845
|
-
|
|
846
|
-
--apply Avec update, exécute les étapes de mise à jour
|
|
847
|
-
|
|
848
|
-
_____________________________________________
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
Presets disponibles:
|
|
852
|
-
|
|
853
|
-
${listPresetNames().join(", ")}
|
|
854
|
-
|
|
855
|
-
_____________________________________________
|
|
856
|
-
|
|
857
|
-
`);
|
|
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 }));
|
|
858
893
|
}
|
|
859
894
|
main().catch((error) => {
|
|
895
|
+
const language = safeStartupLanguage(process.argv.slice(2));
|
|
896
|
+
const messages = createTranslator(language);
|
|
860
897
|
const message = error instanceof AdapterError
|
|
861
|
-
? formatAdapterError(error)
|
|
898
|
+
? formatAdapterError(error, messages)
|
|
862
899
|
: error instanceof Error ? error.message : String(error);
|
|
863
|
-
console.error(
|
|
900
|
+
console.error(`${messages.common.errorPrefix}: ${message}`);
|
|
864
901
|
process.exitCode = 1;
|
|
865
902
|
});
|
|
903
|
+
function safeStartupLanguage(args) {
|
|
904
|
+
try {
|
|
905
|
+
return resolveLanguage({ explicitLanguage: findRawLanguageFlag(args) });
|
|
906
|
+
}
|
|
907
|
+
catch {
|
|
908
|
+
return DEFAULT_LANGUAGE;
|
|
909
|
+
}
|
|
910
|
+
}
|