palabre 0.9.1 → 0.10.1

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.
Files changed (52) hide show
  1. package/README.md +6 -0
  2. package/dist/adapters/cli-pty.js +30 -10
  3. package/dist/adapters/cli-shared.js +73 -0
  4. package/dist/adapters/cli.js +40 -77
  5. package/dist/adapters/index.js +1 -0
  6. package/dist/adapters/ollama.js +32 -32
  7. package/dist/adapters/terminal.js +1 -0
  8. package/dist/args.js +1 -0
  9. package/dist/commands/agents.js +7 -1
  10. package/dist/commands/context.js +7 -1
  11. package/dist/commands/history.js +6 -1
  12. package/dist/commands/init.js +8 -3
  13. package/dist/commands/presets.js +6 -1
  14. package/dist/commands/shared.js +5 -1
  15. package/dist/commands/update.js +6 -1
  16. package/dist/config.js +17 -1
  17. package/dist/configWizard.js +5 -4
  18. package/dist/context.js +1 -0
  19. package/dist/contextScan.js +4 -3
  20. package/dist/discovery.js +1 -0
  21. package/dist/doctor.js +1 -0
  22. package/dist/errors.js +4 -0
  23. package/dist/exec.js +1 -0
  24. package/dist/history.js +10 -0
  25. package/dist/i18n.js +2 -0
  26. package/dist/index.js +170 -112
  27. package/dist/limits.js +4 -0
  28. package/dist/messages/adapter-errors.js +26 -2
  29. package/dist/messages/config.js +6 -0
  30. package/dist/messages/index.js +1 -0
  31. package/dist/messages/renderers.js +10 -2
  32. package/dist/messages/tui.js +8 -2
  33. package/dist/new.js +65 -11
  34. package/dist/ollamaUrl.js +20 -0
  35. package/dist/orchestrator.js +103 -150
  36. package/dist/output.js +1 -0
  37. package/dist/presets.js +1 -0
  38. package/dist/prompt.js +1 -0
  39. package/dist/renderers/console.js +1 -1
  40. package/dist/renderers/tui-prompts.js +343 -0
  41. package/dist/renderers/tui-renderer.js +228 -0
  42. package/dist/renderers/tui-screens.js +352 -0
  43. package/dist/renderers/tui-theme.js +356 -0
  44. package/dist/renderers/tui.js +7 -1086
  45. package/dist/runOptions.js +33 -2
  46. package/dist/session.js +1 -0
  47. package/dist/tuiController.js +61 -16
  48. package/dist/tuiState.js +4 -0
  49. package/dist/types.js +1 -0
  50. package/dist/update.js +1 -0
  51. package/dist/version.js +1 -0
  52. package/package.json +1 -1
@@ -1,9 +1,14 @@
1
+ /** @file Commande de decouverte des presets et de leur disponibilite. */
1
2
  import { configExists, createConfigFromDiscovery, loadConfig, resolveDefaultConfigPath } from "../config.js";
2
3
  import { discoverLocalTools, discoverLocalToolsForConfig } from "../discovery.js";
3
4
  import { createTranslator, resolveLanguage } from "../i18n.js";
4
5
  import { listPresetsWithAvailability } from "../presets.js";
5
6
  import { optionalString } from "./shared.js";
6
- /** Exécute `palabre presets` en sortie humaine ou JSON versionné. */
7
+ /**
8
+ * Liste les presets enrichis avec la disponibilité issue de la config et de la discovery.
9
+ * @param flags - Flags de config, langue, URL Ollama et format JSON.
10
+ * @returns Une promesse résolue après écriture de la liste.
11
+ */
7
12
  export async function runPresetsCommand(flags) {
8
13
  const configPath = optionalString(flags.config) ?? await resolveDefaultConfigPath();
9
14
  const ollamaUrl = optionalString(flags["ollama-url"]);
@@ -1,4 +1,8 @@
1
- /** Extrait une chaîne non vide depuis une valeur de flag. */
1
+ /**
2
+ * Extrait une chaîne non vide depuis une valeur de flag.
3
+ * @param value - Valeur brute produite par le parseur CLI.
4
+ * @returns La chaîne non vide, sinon `undefined`.
5
+ */
2
6
  export function optionalString(value) {
3
7
  return typeof value === "string" && value.trim() ? value : undefined;
4
8
  }
@@ -1,9 +1,14 @@
1
+ /** @file Commande de diagnostic et application des mises a jour Palabre. */
1
2
  import { configExists, loadConfig, resolveDefaultConfigPath } from "../config.js";
2
3
  import { createTranslator, resolveLanguage } from "../i18n.js";
3
4
  import { applySourceUpdate, formatUpdateInstructions, getUpdateInfo } from "../update.js";
4
5
  import { getPackageVersion } from "../version.js";
5
6
  import { optionalString } from "./shared.js";
6
- /** Exécute `palabre update`, avec application explicite pour un checkout source. */
7
+ /**
8
+ * Affiche les instructions de mise à jour ou applique le workflow d'un checkout source.
9
+ * @param flags - Flags de config, langue et application explicite.
10
+ * @returns Une promesse résolue après affichage ou mise à jour.
11
+ */
7
12
  export async function runUpdateCommand(flags) {
8
13
  const info = await getUpdateInfo(await getPackageVersion());
9
14
  const configPath = optionalString(flags.config) ?? await resolveDefaultConfigPath();
package/dist/config.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** @file Chargement, génération et validation de la config Palabre, ainsi que la synchronisation des agents/modèles Ollama détectés. */
1
2
  import { access, mkdir, readFile, writeFile } from "node:fs/promises";
2
3
  import os from "node:os";
3
4
  import path from "node:path";
@@ -234,6 +235,10 @@ function migrateVibePlanAgent(config) {
234
235
  function isLegacyVibePlanArgs(args) {
235
236
  return JSON.stringify(args) === JSON.stringify(["--output", "text", "--agent", "plan", "--trust", "--prompt"]);
236
237
  }
238
+ /**
239
+ * Variante de `syncDetectedAgents` qui indique aussi si la config a changé,
240
+ * même quand aucun agent n'a été ajouté (ex. migration d'arguments legacy).
241
+ */
237
242
  export function syncDetectedAgentsDetailed(config, discovery) {
238
243
  const before = JSON.stringify(config.agents);
239
244
  const addedAgents = syncDetectedAgents(config, discovery);
@@ -243,6 +248,12 @@ export function syncDetectedAgentsDetailed(config, discovery) {
243
248
  changed
244
249
  };
245
250
  }
251
+ /**
252
+ * Bascule le modèle de l'agent `ollama-local` vers un modèle installé si celui configuré
253
+ * ne l'est pas. Mute `config` directement.
254
+ * @returns `undefined` si l'agent n'est pas de type `ollama`, si aucun modèle n'est installé,
255
+ * ou si le modèle configuré est déjà installé.
256
+ */
246
257
  export function syncOllamaModel(config, discovery) {
247
258
  const agent = config.agents["ollama-local"];
248
259
  if (agent?.type !== "ollama" || discovery.ollama.models.length === 0) {
@@ -258,6 +269,11 @@ export function syncOllamaModel(config, discovery) {
258
269
  nextModel: agent.model
259
270
  };
260
271
  }
272
+ /**
273
+ * Force le modèle de l'agent `ollama-local` à `model`, sans vérifier qu'il est installé.
274
+ * Mute `config` directement.
275
+ * @returns `undefined` si l'agent n'est pas de type `ollama`.
276
+ */
261
277
  export function setOllamaModel(config, model) {
262
278
  const agent = config.agents["ollama-local"];
263
279
  if (agent?.type !== "ollama") {
@@ -279,7 +295,7 @@ export function setOllamaBaseUrl(config, baseUrl) {
279
295
  return agents.length;
280
296
  }
281
297
  /** Écrit `config` sérialisé en JSON dans `configPath`. Crée le répertoire parent si nécessaire. */
282
- export async function writeExampleConfig(configPath = DEFAULT_CONFIG_PATH, config = exampleConfig) {
298
+ export async function writeConfig(configPath = DEFAULT_CONFIG_PATH, config = exampleConfig) {
283
299
  const resolved = path.resolve(configPath);
284
300
  await mkdir(path.dirname(resolved), { recursive: true });
285
301
  await writeFile(resolved, `${JSON.stringify(config, null, 2)}\n`, "utf8");
@@ -1,6 +1,7 @@
1
+ /** @file Wizard interactif `palabre config` (sans sous-commande) pour éditer les defaults au clavier. */
1
2
  import { createInterface } from "node:readline/promises";
2
3
  import { stdin as input, stdout as output } from "node:process";
3
- import { syncDetectedAgents, writeExampleConfig } from "./config.js";
4
+ import { syncDetectedAgents, writeConfig } from "./config.js";
4
5
  import { discoverLocalTools } from "./discovery.js";
5
6
  import { DEFAULT_TURNS, MAX_TURNS, turnsOrDefault, validateTurns } from "./limits.js";
6
7
  /**
@@ -36,7 +37,7 @@ export async function runConfigWizard(configPath, config, messages) {
36
37
  }
37
38
  if (action === "2") {
38
39
  delete config.defaults;
39
- await writeExampleConfig(configPath, config);
40
+ await writeConfig(configPath, config);
40
41
  console.log(messages.config.wizardCleared(configPath));
41
42
  return;
42
43
  }
@@ -47,7 +48,7 @@ export async function runConfigWizard(configPath, config, messages) {
47
48
  console.log(messages.config.syncNoMissing(configPath));
48
49
  return;
49
50
  }
50
- await writeExampleConfig(configPath, config);
51
+ await writeConfig(configPath, config);
51
52
  console.log(messages.config.syncAdded(configPath, addedAgents.join(", ")));
52
53
  return;
53
54
  }
@@ -75,7 +76,7 @@ export async function runConfigWizard(configPath, config, messages) {
75
76
  else {
76
77
  delete config.defaults.summaryAgent;
77
78
  }
78
- await writeExampleConfig(configPath, config);
79
+ await writeConfig(configPath, config);
79
80
  console.log(messages.config.wizardDefaultsSet(configPath, formatDefaults(config.defaults, messages)));
80
81
  }
81
82
  finally {
package/dist/context.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** @file Chargement du contexte projet : `--files` strict et `--context` tolérant avec règles `.gitignore` simplifiées. */
1
2
  import { readdir, readFile, stat } from "node:fs/promises";
2
3
  import path from "node:path";
3
4
  import { createTranslator } from "./i18n.js";
@@ -1,11 +1,12 @@
1
+ /** @file Contrat JSON v1 de `palabre context scan --json`, consommé par les intégrations. */
1
2
  import path from "node:path";
2
3
  import { loadProjectInputs } from "./context.js";
3
4
  import { createTranslator } from "./i18n.js";
4
5
  /**
5
- * Builds the machine-readable context preview used by integrations.
6
+ * Construit l'aperçu de contexte lisible par une machine, utilisé par les intégrations.
6
7
  *
7
- * The scan intentionally reuses the same tolerant loader as `--context`, so
8
- * the returned files are the files Palabre would actually inject into a debate.
8
+ * Le scan réutilise volontairement le même chargeur tolérant que `--context`, afin que
9
+ * les fichiers renvoyés soient exactement ceux que Palabre injecterait dans un débat.
9
10
  */
10
11
  export async function buildContextScan(scanPaths, cwd = process.cwd(), messages = createTranslator("fr")) {
11
12
  const effectiveScanPaths = scanPaths.length > 0 ? scanPaths : ["."];
package/dist/discovery.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** @file Détection locale des CLIs agents et d'Ollama, utilisée par `init`, `doctor`, `presets` et l'accueil TUI. */
1
2
  import { access } from "node:fs/promises";
2
3
  import path from "node:path";
3
4
  import { executableExtensions } from "./exec.js";
package/dist/doctor.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** @file Diagnostic `palabre doctor` : vérifie config, agents détectés et connectivité Ollama. */
1
2
  import path from "node:path";
2
3
  import { stat } from "node:fs/promises";
3
4
  import { configExists, loadConfig, resolveDefaultConfigPath, resolveOutputDir } from "./config.js";
package/dist/errors.js CHANGED
@@ -20,3 +20,7 @@ export function formatAdapterError(error, messages = createTranslator("fr")) {
20
20
  const hint = messages.adapterErrors.hint(error.kind);
21
21
  return hint ? `${error.message}\n${messages.adapterErrors.suggestionPrefix}: ${hint}` : error.message;
22
22
  }
23
+ /** Construit l'`AdapterError` standard d'annulation utilisateur, partagée par tous les adapters. */
24
+ export function cancelledError(adapterName) {
25
+ return new AdapterError("cancelled", adapterName, `${adapterName} cancelled by user.`);
26
+ }
package/dist/exec.js CHANGED
@@ -1,3 +1,4 @@
1
+ /** @file Résolution d'extensions exécutables partagée entre discovery et l'adapter PTY. */
1
2
  import path from "node:path";
2
3
  /**
3
4
  * Extensions exécutables candidates pour résoudre une commande dans le PATH.
package/dist/history.js CHANGED
@@ -1,6 +1,12 @@
1
+ /** @file Liste les exports Markdown récents en reparsant leur table de métadonnées, pour `palabre history` et la TUI. */
1
2
  import { readdir, readFile, stat } from "node:fs/promises";
2
3
  import path from "node:path";
4
+ /** Limite de lecture par fichier : la table de métadonnées est toujours en tête de l'export. */
3
5
  const maxHeaderBytes = 12_000;
6
+ /**
7
+ * Liste les exports les plus récents d'un dossier de sortie, triés par date de modification.
8
+ * Silencieux si `outputDir` est absent ou inaccessible : retourne `[]` sans lever.
9
+ */
4
10
  export async function listHistoryEntries(outputDir, limit = 10) {
5
11
  const resolved = path.resolve(outputDir);
6
12
  let entries;
@@ -19,6 +25,7 @@ export async function listHistoryEntries(outputDir, limit = 10) {
19
25
  .sort((left, right) => right.mtimeMs - left.mtimeMs)
20
26
  .slice(0, limit);
21
27
  }
28
+ /** Lit et parse un fichier d'export. Retourne `undefined` sur toute erreur filesystem/parsing plutôt que de lever. */
22
29
  async function readHistoryFile(filePath) {
23
30
  try {
24
31
  const [metadata, raw] = await Promise.all([
@@ -44,6 +51,7 @@ async function readHistoryFile(filePath) {
44
51
  return undefined;
45
52
  }
46
53
  }
54
+ /** Formate le compteur `x/y` adapté au mode, en tolérant les clés FR/EN de la table de métadonnées. */
47
55
  function countFromTable(mode, table) {
48
56
  if (mode === "ask") {
49
57
  const received = table["Reponses recues"] ?? table["Received responses"];
@@ -54,6 +62,7 @@ function countFromTable(mode, table) {
54
62
  const requested = table["Tours demandes"] ?? table["Requested turns"];
55
63
  return played && requested ? `${played}/${requested}` : played ?? requested ?? "";
56
64
  }
65
+ /** Extrait les paires clé/valeur de la table Markdown `| Champ | Valeur |` générée par l'export. */
57
66
  function parseMetadataTable(markdown) {
58
67
  const fields = {};
59
68
  const lines = markdown.split(/\r?\n/);
@@ -75,6 +84,7 @@ function stripMarkdown(value) {
75
84
  .replace(/`/g, "")
76
85
  .trim();
77
86
  }
87
+ /** Reconstruit un sujet lisible depuis le nom de fichier quand la table de métadonnées ne l'indique pas. */
78
88
  function topicFromFileName(fileName) {
79
89
  return fileName
80
90
  .replace(/^palabre-/, "")
package/dist/i18n.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import { createTranslator } from "./messages/index.js";
2
+ /** Langue utilisée quand aucune source explicite (flag, env, config) n'en fournit une valide. */
2
3
  export const DEFAULT_LANGUAGE = "fr";
4
+ /** Langues acceptées par `parseLanguage`/`resolveLanguage`. */
3
5
  export const SUPPORTED_LANGUAGES = ["fr", "en"];
4
6
  /**
5
7
  * Valide une langue Palabre.