palabre 0.7.0 → 0.8.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.
- package/README.md +102 -68
- package/dist/adapters/cli-pty.js +1 -1
- package/dist/adapters/cli.js +33 -3
- package/dist/adapters/ollama.js +1 -1
- package/dist/agentRegistry.js +3 -3
- package/dist/args.js +21 -1
- package/dist/config.js +58 -24
- package/dist/configWizard.js +12 -2
- package/dist/context.js +5 -1
- package/dist/discovery.js +3 -3
- package/dist/doctor.js +4 -1
- package/dist/history.js +85 -0
- package/dist/index.js +742 -94
- package/dist/messages/agents.js +4 -2
- package/dist/messages/common.js +4 -0
- package/dist/messages/config.js +18 -8
- package/dist/messages/help.js +116 -10
- package/dist/messages/index.js +2 -0
- package/dist/messages/init.js +2 -2
- package/dist/messages/new.js +14 -0
- package/dist/messages/output.js +10 -0
- package/dist/messages/preview.js +4 -2
- package/dist/messages/prompt.js +46 -2
- package/dist/messages/renderers.js +2 -2
- package/dist/messages/tui.js +228 -0
- package/dist/messages/update.js +16 -2
- package/dist/new.js +158 -4
- package/dist/orchestrator.js +168 -9
- package/dist/output.js +31 -8
- package/dist/presets.js +39 -39
- package/dist/prompt.js +61 -10
- package/dist/renderers/console.js +39 -3
- package/dist/renderers/ndjson.js +30 -1
- package/dist/renderers/tui.js +1055 -0
- package/dist/tuiState.js +31 -0
- package/dist/update.js +2 -0
- package/package.json +2 -1
- package/palabre.config.example.json +0 -17
package/dist/configWizard.js
CHANGED
|
@@ -64,11 +64,17 @@ export async function runConfigWizard(configPath, config, messages) {
|
|
|
64
64
|
if (summaryAgent === undefined)
|
|
65
65
|
return;
|
|
66
66
|
config.defaults = {
|
|
67
|
+
...(config.defaults ?? {}),
|
|
67
68
|
agentA,
|
|
68
69
|
agentB,
|
|
69
|
-
...(summaryAgent ? { summaryAgent } : {}),
|
|
70
70
|
turns
|
|
71
71
|
};
|
|
72
|
+
if (summaryAgent) {
|
|
73
|
+
config.defaults.summaryAgent = summaryAgent;
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
delete config.defaults.summaryAgent;
|
|
77
|
+
}
|
|
72
78
|
await writeExampleConfig(configPath, config);
|
|
73
79
|
console.log(messages.config.wizardDefaultsSet(configPath, formatDefaults(config.defaults, messages)));
|
|
74
80
|
}
|
|
@@ -205,8 +211,12 @@ function formatDefaults(defaults, messages) {
|
|
|
205
211
|
return messages.config.wizardDefaults({
|
|
206
212
|
agentA: defaults.agentA,
|
|
207
213
|
agentB: defaults.agentB,
|
|
214
|
+
mode: defaults.mode,
|
|
215
|
+
interfaceName: defaults.interface,
|
|
216
|
+
askAgents: defaults.askAgents,
|
|
208
217
|
turns: turnsOrDefault(defaults.turns ?? DEFAULT_TURNS),
|
|
209
|
-
summaryAgent: defaults.summaryAgent
|
|
218
|
+
summaryAgent: defaults.summaryAgent,
|
|
219
|
+
askSummaryAgent: defaults.askSummaryAgent
|
|
210
220
|
});
|
|
211
221
|
}
|
|
212
222
|
function isQuit(value) {
|
package/dist/context.js
CHANGED
|
@@ -80,7 +80,11 @@ async function addContextPaths(paths, cwd, state) {
|
|
|
80
80
|
const uniquePaths = [...new Set(paths.map((item) => item.trim()).filter(Boolean))];
|
|
81
81
|
for (const inputPath of uniquePaths) {
|
|
82
82
|
const absolutePath = path.resolve(cwd, inputPath);
|
|
83
|
-
const fileStat = await stat(absolutePath);
|
|
83
|
+
const fileStat = await stat(absolutePath).catch(() => undefined);
|
|
84
|
+
if (!fileStat) {
|
|
85
|
+
state.warnings.push(state.messages.context.ignoredNotFileOrDirectory(inputPath));
|
|
86
|
+
continue;
|
|
87
|
+
}
|
|
84
88
|
if (fileStat.isFile()) {
|
|
85
89
|
await addContextFile(absolutePath, cwd, state);
|
|
86
90
|
continue;
|
package/dist/discovery.js
CHANGED
|
@@ -7,21 +7,21 @@ import { executableExtensions } from "./exec.js";
|
|
|
7
7
|
* Antigravity est exposé selon les installations sous `agy` ou `antigravity`.
|
|
8
8
|
*/
|
|
9
9
|
export async function discoverLocalTools() {
|
|
10
|
-
const [codex, claude,
|
|
10
|
+
const [codex, claude, antigravity, opencode, vibe, ollamaCommand] = await Promise.all([
|
|
11
11
|
detectCommand("codex"),
|
|
12
12
|
detectFirstCommand(process.platform === "win32" ? ["claude.exe", "claude"] : ["claude"]),
|
|
13
|
-
detectCommand("gemini"),
|
|
14
13
|
detectFirstCommand(["agy", "antigravity"]),
|
|
15
14
|
detectCommand("opencode"),
|
|
15
|
+
detectCommand("vibe"),
|
|
16
16
|
detectCommand("ollama")
|
|
17
17
|
]);
|
|
18
18
|
const ollamaServer = await detectOllamaServer();
|
|
19
19
|
return {
|
|
20
20
|
codex,
|
|
21
21
|
claude,
|
|
22
|
-
gemini,
|
|
23
22
|
antigravity,
|
|
24
23
|
opencode,
|
|
24
|
+
vibe,
|
|
25
25
|
ollama: {
|
|
26
26
|
...ollamaServer,
|
|
27
27
|
commandAvailable: ollamaCommand.available
|
package/dist/doctor.js
CHANGED
|
@@ -43,9 +43,9 @@ export async function runDoctor(explicitConfigPath, plain = false, explicitLangu
|
|
|
43
43
|
lines.push(info(t.doctor.localTools, "tools"));
|
|
44
44
|
lines.push(formatCommand("Codex CLI", discovery.codex.available, discovery.codex.command, discovery.codex.path, t));
|
|
45
45
|
lines.push(formatCommand("Claude CLI", discovery.claude.available, discovery.claude.command, discovery.claude.path, t));
|
|
46
|
-
lines.push(formatCommand("Gemini CLI", discovery.gemini.available, discovery.gemini.command, discovery.gemini.path, t));
|
|
47
46
|
lines.push(formatCommand("Antigravity CLI", discovery.antigravity.available, discovery.antigravity.command, discovery.antigravity.path, t));
|
|
48
47
|
lines.push(formatCommand("OpenCode CLI", discovery.opencode.available, discovery.opencode.command, discovery.opencode.path, t));
|
|
48
|
+
lines.push(formatCommand("Mistral Vibe CLI", discovery.vibe.available, discovery.vibe.command, discovery.vibe.path, t));
|
|
49
49
|
lines.push(discovery.ollama.available
|
|
50
50
|
? ok(t.doctor.ollamaReachable(discovery.ollama.baseUrl, discovery.ollama.models.length))
|
|
51
51
|
: warn(discovery.ollama.commandAvailable
|
|
@@ -105,6 +105,9 @@ async function inspectConfig(config, lines, t) {
|
|
|
105
105
|
else {
|
|
106
106
|
lines.push(warn(t.doctor.summaryAgentMissing));
|
|
107
107
|
}
|
|
108
|
+
if (config.defaults?.askSummaryAgent) {
|
|
109
|
+
inspectDefaultAgent("defaults.askSummaryAgent", config.defaults.askSummaryAgent, config, lines, t);
|
|
110
|
+
}
|
|
108
111
|
await inspectOutputDir(config.outputDir, lines, t);
|
|
109
112
|
}
|
|
110
113
|
function inspectDefaultAgent(label, agentName, config, lines, t) {
|
package/dist/history.js
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { readdir, readFile, stat } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
const maxHeaderBytes = 12_000;
|
|
4
|
+
export async function listHistoryEntries(outputDir, limit = 10) {
|
|
5
|
+
const resolved = path.resolve(outputDir);
|
|
6
|
+
let entries;
|
|
7
|
+
try {
|
|
8
|
+
entries = await readdir(resolved, { withFileTypes: true });
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return [];
|
|
12
|
+
}
|
|
13
|
+
const markdownFiles = entries
|
|
14
|
+
.filter((entry) => entry.isFile() && /\.(debate|ask)\.md$/i.test(entry.name))
|
|
15
|
+
.map((entry) => path.join(resolved, entry.name));
|
|
16
|
+
const history = await Promise.all(markdownFiles.map(readHistoryFile));
|
|
17
|
+
return history
|
|
18
|
+
.filter((entry) => Boolean(entry))
|
|
19
|
+
.sort((left, right) => right.mtimeMs - left.mtimeMs)
|
|
20
|
+
.slice(0, limit);
|
|
21
|
+
}
|
|
22
|
+
async function readHistoryFile(filePath) {
|
|
23
|
+
try {
|
|
24
|
+
const [metadata, raw] = await Promise.all([
|
|
25
|
+
stat(filePath),
|
|
26
|
+
readFile(filePath, "utf8")
|
|
27
|
+
]);
|
|
28
|
+
const header = raw.slice(0, maxHeaderBytes);
|
|
29
|
+
const table = parseMetadataTable(header);
|
|
30
|
+
const fileName = path.basename(filePath);
|
|
31
|
+
const mode = fileName.endsWith(".ask.md") ? "ask" : "debate";
|
|
32
|
+
return {
|
|
33
|
+
fileName,
|
|
34
|
+
path: filePath,
|
|
35
|
+
mode,
|
|
36
|
+
topic: table.Sujet ?? table.Subject ?? topicFromFileName(fileName),
|
|
37
|
+
agents: table.Agents ?? "",
|
|
38
|
+
date: table["Date locale"] ?? table["Local date"] ?? table["Session demarree a"] ?? table["Session started at"] ?? "",
|
|
39
|
+
count: countFromTable(mode, table),
|
|
40
|
+
mtimeMs: metadata.mtimeMs
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return undefined;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function countFromTable(mode, table) {
|
|
48
|
+
if (mode === "ask") {
|
|
49
|
+
const received = table["Reponses recues"] ?? table["Received responses"];
|
|
50
|
+
const requested = table["Reponses attendues"] ?? table["Expected responses"];
|
|
51
|
+
return received && requested ? `${received}/${requested}` : received ?? requested ?? "";
|
|
52
|
+
}
|
|
53
|
+
const played = table["Tours joues"] ?? table["Played turns"];
|
|
54
|
+
const requested = table["Tours demandes"] ?? table["Requested turns"];
|
|
55
|
+
return played && requested ? `${played}/${requested}` : played ?? requested ?? "";
|
|
56
|
+
}
|
|
57
|
+
function parseMetadataTable(markdown) {
|
|
58
|
+
const fields = {};
|
|
59
|
+
const lines = markdown.split(/\r?\n/);
|
|
60
|
+
for (const line of lines) {
|
|
61
|
+
const match = line.match(/^\|\s*([^|]+?)\s*\|\s*([^|]*?)\s*\|$/);
|
|
62
|
+
if (!match)
|
|
63
|
+
continue;
|
|
64
|
+
const key = stripMarkdown(match[1] ?? "");
|
|
65
|
+
const value = stripMarkdown(match[2] ?? "");
|
|
66
|
+
if (!key || key === "Champ" || key === "Field" || /^-+$/.test(key))
|
|
67
|
+
continue;
|
|
68
|
+
fields[key] = value;
|
|
69
|
+
}
|
|
70
|
+
return fields;
|
|
71
|
+
}
|
|
72
|
+
function stripMarkdown(value) {
|
|
73
|
+
return value
|
|
74
|
+
.replace(/\*\*/g, "")
|
|
75
|
+
.replace(/`/g, "")
|
|
76
|
+
.trim();
|
|
77
|
+
}
|
|
78
|
+
function topicFromFileName(fileName) {
|
|
79
|
+
return fileName
|
|
80
|
+
.replace(/^palabre-/, "")
|
|
81
|
+
.replace(/\.(debate|ask)\.md$/i, "")
|
|
82
|
+
.replace(/-\d{4}-\d{2}-\d{2}t.*$/i, "")
|
|
83
|
+
.replace(/-/g, " ")
|
|
84
|
+
.trim() || fileName;
|
|
85
|
+
}
|