zelari-code 1.6.0 → 1.7.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/dist/cli/hooks/historyCompaction.js +6 -5
- package/dist/cli/hooks/historyCompaction.js.map +1 -1
- package/dist/cli/hooks/useChatTurn.js +28 -22
- package/dist/cli/hooks/useChatTurn.js.map +1 -1
- package/dist/cli/main.bundled.js +636 -81
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/runHeadless.js +79 -8
- package/dist/cli/runHeadless.js.map +1 -1
- package/dist/cli/utils/envNumber.js +62 -0
- package/dist/cli/utils/envNumber.js.map +1 -0
- package/dist/cli/utils/prereqChecks.js +96 -26
- package/dist/cli/utils/prereqChecks.js.map +1 -1
- package/package.json +2 -2
package/dist/cli/main.bundled.js
CHANGED
|
@@ -16576,6 +16576,28 @@ var init_filesystem = __esm({
|
|
|
16576
16576
|
// packages/core/dist/core/tools/builtin/shellResolver.js
|
|
16577
16577
|
import { existsSync as existsSync4 } from "node:fs";
|
|
16578
16578
|
import { spawnSync } from "node:child_process";
|
|
16579
|
+
function isWslBashPath(p3) {
|
|
16580
|
+
if (!p3 || typeof p3 !== "string")
|
|
16581
|
+
return false;
|
|
16582
|
+
const n = p3.replace(/\//g, "\\").toLowerCase();
|
|
16583
|
+
if (n.includes("\\windows\\system32\\bash.exe"))
|
|
16584
|
+
return true;
|
|
16585
|
+
if (n.includes("\\windows\\syswow64\\bash.exe"))
|
|
16586
|
+
return true;
|
|
16587
|
+
if (n.includes("\\windowsapps\\bash.exe"))
|
|
16588
|
+
return true;
|
|
16589
|
+
return false;
|
|
16590
|
+
}
|
|
16591
|
+
function acceptBashPath(p3) {
|
|
16592
|
+
if (!p3 || p3.trim().length === 0)
|
|
16593
|
+
return null;
|
|
16594
|
+
const trimmed = p3.trim();
|
|
16595
|
+
if (isWslBashPath(trimmed))
|
|
16596
|
+
return null;
|
|
16597
|
+
if (!existsSyncSafe(trimmed))
|
|
16598
|
+
return null;
|
|
16599
|
+
return trimmed;
|
|
16600
|
+
}
|
|
16579
16601
|
function resolveShell(forceReResolve = false) {
|
|
16580
16602
|
if (memoized && !forceReResolve)
|
|
16581
16603
|
return memoized;
|
|
@@ -16596,24 +16618,25 @@ function resolveShell(forceReResolve = false) {
|
|
|
16596
16618
|
return memoized;
|
|
16597
16619
|
}
|
|
16598
16620
|
function resolveBashWindows() {
|
|
16599
|
-
const
|
|
16600
|
-
if (
|
|
16601
|
-
return
|
|
16602
|
-
|
|
16603
|
-
|
|
16604
|
-
|
|
16605
|
-
return sessionShell;
|
|
16606
|
-
}
|
|
16621
|
+
const fromEnv = acceptBashPath(process.env.ZELARI_SHELL);
|
|
16622
|
+
if (fromEnv)
|
|
16623
|
+
return fromEnv;
|
|
16624
|
+
const fromSession = acceptBashPath(process.env.SHELL);
|
|
16625
|
+
if (fromSession)
|
|
16626
|
+
return fromSession;
|
|
16607
16627
|
for (const p3 of STANDARD_BASH_PATHS) {
|
|
16608
|
-
|
|
16609
|
-
|
|
16628
|
+
const accepted = acceptBashPath(p3);
|
|
16629
|
+
if (accepted)
|
|
16630
|
+
return accepted;
|
|
16610
16631
|
}
|
|
16611
16632
|
try {
|
|
16612
16633
|
const result = spawnSync("where", ["bash"], { encoding: "utf-8", windowsHide: true });
|
|
16613
16634
|
if (result.status === 0 && result.stdout) {
|
|
16614
|
-
const
|
|
16615
|
-
|
|
16616
|
-
|
|
16635
|
+
for (const line of result.stdout.split(/\r?\n/)) {
|
|
16636
|
+
const accepted = acceptBashPath(line);
|
|
16637
|
+
if (accepted)
|
|
16638
|
+
return accepted;
|
|
16639
|
+
}
|
|
16617
16640
|
}
|
|
16618
16641
|
} catch {
|
|
16619
16642
|
}
|
|
@@ -16643,6 +16666,24 @@ var init_shellResolver = __esm({
|
|
|
16643
16666
|
|
|
16644
16667
|
// packages/core/dist/core/tools/builtin/shell.js
|
|
16645
16668
|
import { spawn } from "node:child_process";
|
|
16669
|
+
import { dirname } from "node:path";
|
|
16670
|
+
function withNodeDirOnPath(base) {
|
|
16671
|
+
const env = { ...base };
|
|
16672
|
+
try {
|
|
16673
|
+
const nodeDir = dirname(process.execPath);
|
|
16674
|
+
if (!nodeDir)
|
|
16675
|
+
return env;
|
|
16676
|
+
const sep = process.platform === "win32" ? ";" : ":";
|
|
16677
|
+
const current = env.PATH ?? env.Path ?? "";
|
|
16678
|
+
const parts = current.split(sep).filter((p3) => p3.length > 0);
|
|
16679
|
+
const has = parts.some((p3) => p3.toLowerCase() === nodeDir.toLowerCase());
|
|
16680
|
+
if (!has) {
|
|
16681
|
+
env.PATH = `${nodeDir}${sep}${current}`;
|
|
16682
|
+
}
|
|
16683
|
+
} catch {
|
|
16684
|
+
}
|
|
16685
|
+
return env;
|
|
16686
|
+
}
|
|
16646
16687
|
var BashArgsSchema, INTERACTIVE_CANCEL_RE, INTERACTIVE_HINT, bashTool;
|
|
16647
16688
|
var init_shell = __esm({
|
|
16648
16689
|
"packages/core/dist/core/tools/builtin/shell.js"() {
|
|
@@ -16669,7 +16710,10 @@ var init_shell = __esm({
|
|
|
16669
16710
|
const cwd = args.cwd ?? ctx.cwd;
|
|
16670
16711
|
const resolved = resolveShell();
|
|
16671
16712
|
let child;
|
|
16672
|
-
const baseEnv = {
|
|
16713
|
+
const baseEnv = withNodeDirOnPath({
|
|
16714
|
+
...process.env,
|
|
16715
|
+
CI: process.env.CI ?? "1"
|
|
16716
|
+
});
|
|
16673
16717
|
const env = resolved.isBash ? { ...baseEnv, MSYSTEM: process.env.MSYSTEM ?? "MINGW64" } : baseEnv;
|
|
16674
16718
|
if (resolved.isBash) {
|
|
16675
16719
|
child = spawn(resolved.shell, ["-c", args.command], {
|
|
@@ -18401,6 +18445,366 @@ var init_systemPromptBuilder = __esm({
|
|
|
18401
18445
|
}
|
|
18402
18446
|
});
|
|
18403
18447
|
|
|
18448
|
+
// packages/core/dist/agents/languagePolicy.js
|
|
18449
|
+
function isLetter(cp) {
|
|
18450
|
+
return cp >= 65 && cp <= 90 || // A-Z
|
|
18451
|
+
cp >= 97 && cp <= 122 || // a-z
|
|
18452
|
+
cp >= 192 && cp <= 591 || // Latin-1 supplement + Extended A/B
|
|
18453
|
+
cp >= 7680 && cp <= 7935 || // Latin Extended Additional
|
|
18454
|
+
cp >= 880 && cp <= 1023 || // Greek
|
|
18455
|
+
cp >= 1024 && cp <= 1279 || // Cyrillic
|
|
18456
|
+
cp >= 1424 && cp <= 1535 || // Hebrew
|
|
18457
|
+
cp >= 1536 && cp <= 1791 || // Arabic
|
|
18458
|
+
cp >= 2304 && cp <= 2431 || // Devanagari
|
|
18459
|
+
cp >= 12352 && cp <= 12543 || // Hiragana + Katakana
|
|
18460
|
+
cp >= 19968 && cp <= 40959 || // CJK Unified
|
|
18461
|
+
cp >= 44032 && cp <= 55215;
|
|
18462
|
+
}
|
|
18463
|
+
function isLatinChar(cp) {
|
|
18464
|
+
return cp >= 65 && cp <= 90 || // A-Z
|
|
18465
|
+
cp >= 97 && cp <= 122 || // a-z
|
|
18466
|
+
cp >= 192 && cp <= 591 || // Latin-1 supplement + Extended A/B
|
|
18467
|
+
cp >= 7680 && cp <= 7935;
|
|
18468
|
+
}
|
|
18469
|
+
function detectResponseLanguage(text) {
|
|
18470
|
+
if (!text || text.trim().length === 0)
|
|
18471
|
+
return "it";
|
|
18472
|
+
const stripped = text.replace(/```[\s\S]*?```/g, " ").replace(/`[^`]*`/g, " ").toLowerCase();
|
|
18473
|
+
if (stripped.trim().length === 0)
|
|
18474
|
+
return "it";
|
|
18475
|
+
let totalLetters = 0;
|
|
18476
|
+
let nonLatinLetters = 0;
|
|
18477
|
+
for (let i = 0; i < stripped.length; i++) {
|
|
18478
|
+
const cp = stripped.codePointAt(i);
|
|
18479
|
+
if (cp === void 0)
|
|
18480
|
+
continue;
|
|
18481
|
+
if (!isLetter(cp))
|
|
18482
|
+
continue;
|
|
18483
|
+
totalLetters += 1;
|
|
18484
|
+
if (!isLatinChar(cp))
|
|
18485
|
+
nonLatinLetters += 1;
|
|
18486
|
+
}
|
|
18487
|
+
const nonLatinRatio = totalLetters > 0 ? nonLatinLetters / totalLetters : 0;
|
|
18488
|
+
const SCRIPT_DOMINANCE_THRESHOLD = 0.3;
|
|
18489
|
+
if (nonLatinRatio >= SCRIPT_DOMINANCE_THRESHOLD) {
|
|
18490
|
+
for (const { lang, ranges } of SCRIPT_RANGES) {
|
|
18491
|
+
for (const [lo, hi] of ranges) {
|
|
18492
|
+
for (let i = 0; i < stripped.length; i++) {
|
|
18493
|
+
const cp = stripped.codePointAt(i);
|
|
18494
|
+
if (cp !== void 0 && cp >= lo && cp <= hi)
|
|
18495
|
+
return lang;
|
|
18496
|
+
}
|
|
18497
|
+
}
|
|
18498
|
+
}
|
|
18499
|
+
}
|
|
18500
|
+
const ACCENT_VOTES = [
|
|
18501
|
+
// Italian-specific
|
|
18502
|
+
{ lang: "it", weight: 2, chars: "\xE0\xE8\xE9\xEC\xF2\xF3\xF9" },
|
|
18503
|
+
// French-only accents
|
|
18504
|
+
{ lang: "fr", weight: 2, chars: "\xE2\xE7\xEA\xEB\xEE\xEF\xF4\xFB\u0153\xE6" },
|
|
18505
|
+
// German-only
|
|
18506
|
+
{ lang: "de", weight: 3, chars: "\xE4\xF6\xFC\xDF" },
|
|
18507
|
+
// Spanish-only (ñ is the discriminator)
|
|
18508
|
+
{ lang: "es", weight: 3, chars: "\xF1\xE1\xED\xF3\xFA\xBF\xA1" },
|
|
18509
|
+
// Portuguese-only (ã/õ are the discriminator)
|
|
18510
|
+
{ lang: "pt", weight: 3, chars: "\xE3\xF5\xE1\xE9\xED\xF3\xFA\xE2\xEA\xF4" },
|
|
18511
|
+
// Dutch-only
|
|
18512
|
+
{ lang: "nl", weight: 2, chars: "\xE1\xE8\xE9\xEB\xED\xF3\xF6\xFA\xFC" }
|
|
18513
|
+
];
|
|
18514
|
+
const accentScores = {};
|
|
18515
|
+
for (const { lang, weight, chars } of ACCENT_VOTES) {
|
|
18516
|
+
let hits = 0;
|
|
18517
|
+
for (const c of chars)
|
|
18518
|
+
if (stripped.includes(c))
|
|
18519
|
+
hits += 1;
|
|
18520
|
+
if (hits > 0)
|
|
18521
|
+
accentScores[lang] = (accentScores[lang] ?? 0) + weight * hits;
|
|
18522
|
+
}
|
|
18523
|
+
const accentOrdered = Object.entries(accentScores).sort((a, b) => b[1] - a[1]).map(([l]) => l);
|
|
18524
|
+
if (accentOrdered.length > 0 && accentOrdered.length === 1) {
|
|
18525
|
+
return accentOrdered[0];
|
|
18526
|
+
}
|
|
18527
|
+
if (accentOrdered.length > 1) {
|
|
18528
|
+
return accentOrdered[0];
|
|
18529
|
+
}
|
|
18530
|
+
const tokens = stripped.split(/[\s,;.!?()\[\]{}<>:'"\\/]+/).filter((t) => t.length > 1);
|
|
18531
|
+
if (tokens.length === 0)
|
|
18532
|
+
return "it";
|
|
18533
|
+
const scores = {};
|
|
18534
|
+
for (const [lang, words] of Object.entries(FUNCTION_WORDS)) {
|
|
18535
|
+
let hits = 0;
|
|
18536
|
+
const tokenSet = new Set(tokens);
|
|
18537
|
+
for (const w of words) {
|
|
18538
|
+
if (tokenSet.has(w))
|
|
18539
|
+
hits += 1;
|
|
18540
|
+
}
|
|
18541
|
+
if (hits > 0)
|
|
18542
|
+
scores[lang] = hits;
|
|
18543
|
+
}
|
|
18544
|
+
const ordered = Object.entries(scores).sort((a, b) => b[1] - a[1] || (a[0] === "it" ? -1 : b[0] === "it" ? 1 : 0)).map(([l]) => l);
|
|
18545
|
+
if (ordered.length > 0)
|
|
18546
|
+
return ordered[0];
|
|
18547
|
+
return "it";
|
|
18548
|
+
}
|
|
18549
|
+
function resolveResponseLanguage(text, env = process.env) {
|
|
18550
|
+
const raw = env.ZELARI_RESPONSE_LANG?.trim().toLowerCase();
|
|
18551
|
+
if (raw && raw !== "auto") {
|
|
18552
|
+
if (raw in LANGUAGE_LABELS)
|
|
18553
|
+
return raw;
|
|
18554
|
+
const sink = globalThis.__zelariLangWarnSink ?? ((msg) => console.warn(`[zelari-code] ${msg}`));
|
|
18555
|
+
sink(`ZELARI_RESPONSE_LANG='${env.ZELARI_RESPONSE_LANG}' is not a supported language (known: ${Object.keys(LANGUAGE_LABELS).join(", ")}, or 'auto'). Falling back to detection.`);
|
|
18556
|
+
}
|
|
18557
|
+
return detectResponseLanguage(text);
|
|
18558
|
+
}
|
|
18559
|
+
function buildLanguageDirective(lang) {
|
|
18560
|
+
const label = LANGUAGE_LABELS[lang];
|
|
18561
|
+
return `# Response Language \u2014 ${label}
|
|
18562
|
+
|
|
18563
|
+
Reply in **${label}** for the entirety of your response, including any final synthesis, clarifying questions, and tool-call descriptions. This directive applies in all modes (single agent, council members, zelari slices):
|
|
18564
|
+
|
|
18565
|
+
- Read the user's last message in context and mirror its language. If the user's prompt is in ${label}, reply in ${label}. If it mixes languages, default to ${label}.
|
|
18566
|
+
- Do not switch to English (or any other language) for code, error messages, tool names, file paths, or technical terms \u2014 code is language-neutral and stays as-is.
|
|
18567
|
+
- If the user explicitly asks for a different language in the same turn (e.g. "reply in English"), honor that request for the rest of this turn only.
|
|
18568
|
+
- For clarifying questions (---QUESTION--- blocks), write the \`question\` and \`choices\` fields in ${label} so the picker UI matches the user's language.
|
|
18569
|
+
- For council synthesis (Lucifero) and any final-answer turn, the user-visible text is in ${label}; intermediate specialist notes that the user never sees directly can stay in their working language.`;
|
|
18570
|
+
}
|
|
18571
|
+
function buildLanguagePolicyModule(lang) {
|
|
18572
|
+
return {
|
|
18573
|
+
type: LANGUAGE_POLICY_MODULE_TYPE,
|
|
18574
|
+
title: `Response Language (${LANGUAGE_LABELS[lang]})`,
|
|
18575
|
+
priority: 5,
|
|
18576
|
+
content: buildLanguageDirective(lang)
|
|
18577
|
+
};
|
|
18578
|
+
}
|
|
18579
|
+
function buildLanguagePolicyModuleFor(userText, env = process.env) {
|
|
18580
|
+
return buildLanguagePolicyModule(resolveResponseLanguage(userText, env));
|
|
18581
|
+
}
|
|
18582
|
+
var LANGUAGE_LABELS, SCRIPT_RANGES, FUNCTION_WORDS, LANGUAGE_POLICY_MODULE_TYPE;
|
|
18583
|
+
var init_languagePolicy = __esm({
|
|
18584
|
+
"packages/core/dist/agents/languagePolicy.js"() {
|
|
18585
|
+
"use strict";
|
|
18586
|
+
LANGUAGE_LABELS = {
|
|
18587
|
+
it: "Italian",
|
|
18588
|
+
en: "English",
|
|
18589
|
+
fr: "French",
|
|
18590
|
+
es: "Spanish",
|
|
18591
|
+
de: "German",
|
|
18592
|
+
pt: "Portuguese",
|
|
18593
|
+
nl: "Dutch",
|
|
18594
|
+
zh: "Chinese (Simplified)",
|
|
18595
|
+
ja: "Japanese",
|
|
18596
|
+
ko: "Korean",
|
|
18597
|
+
ru: "Russian",
|
|
18598
|
+
ar: "Arabic"
|
|
18599
|
+
};
|
|
18600
|
+
SCRIPT_RANGES = [
|
|
18601
|
+
// v1.7.0 fix: ja/kr MUST come before zh — kanji (CJK Unified) and hangul
|
|
18602
|
+
// glyphs can fall in either's range when both languages are present, but
|
|
18603
|
+
// hiragana/katakana (ja) and hangul jamo (kr) are unique owners. A mixed
|
|
18604
|
+
// string like "こんにちは、関数の作り方を…" had kanji that triggered the
|
|
18605
|
+
// zh range first, returning 'zh' for a clearly-Japanese message.
|
|
18606
|
+
{ lang: "ja", ranges: [[12352, 12447], [12448, 12543]] },
|
|
18607
|
+
{ lang: "ko", ranges: [[44032, 55215], [4352, 4607]] },
|
|
18608
|
+
{ lang: "zh", ranges: [[19968, 40959]] },
|
|
18609
|
+
{ lang: "ar", ranges: [[1536, 1791]] },
|
|
18610
|
+
{ lang: "ru", ranges: [[1024, 1279]] }
|
|
18611
|
+
];
|
|
18612
|
+
FUNCTION_WORDS = {
|
|
18613
|
+
it: [
|
|
18614
|
+
"il",
|
|
18615
|
+
"lo",
|
|
18616
|
+
"la",
|
|
18617
|
+
"gli",
|
|
18618
|
+
"le",
|
|
18619
|
+
"un",
|
|
18620
|
+
"uno",
|
|
18621
|
+
"una",
|
|
18622
|
+
"di",
|
|
18623
|
+
"del",
|
|
18624
|
+
"della",
|
|
18625
|
+
"dei",
|
|
18626
|
+
"e",
|
|
18627
|
+
"che",
|
|
18628
|
+
"chi",
|
|
18629
|
+
"come",
|
|
18630
|
+
"con",
|
|
18631
|
+
"per",
|
|
18632
|
+
"non",
|
|
18633
|
+
"sono",
|
|
18634
|
+
"questo",
|
|
18635
|
+
"questa",
|
|
18636
|
+
"quello",
|
|
18637
|
+
"quella",
|
|
18638
|
+
"fare",
|
|
18639
|
+
"fai",
|
|
18640
|
+
"crea",
|
|
18641
|
+
"creare",
|
|
18642
|
+
"mostra",
|
|
18643
|
+
"ciao",
|
|
18644
|
+
"grazie",
|
|
18645
|
+
"bene",
|
|
18646
|
+
"male",
|
|
18647
|
+
"puoi",
|
|
18648
|
+
"come",
|
|
18649
|
+
"cosa",
|
|
18650
|
+
"questo"
|
|
18651
|
+
],
|
|
18652
|
+
en: [
|
|
18653
|
+
"the",
|
|
18654
|
+
"a",
|
|
18655
|
+
"an",
|
|
18656
|
+
"of",
|
|
18657
|
+
"and",
|
|
18658
|
+
"is",
|
|
18659
|
+
"are",
|
|
18660
|
+
"was",
|
|
18661
|
+
"were",
|
|
18662
|
+
"to",
|
|
18663
|
+
"for",
|
|
18664
|
+
"with",
|
|
18665
|
+
"that",
|
|
18666
|
+
"this",
|
|
18667
|
+
"these",
|
|
18668
|
+
"those",
|
|
18669
|
+
"do",
|
|
18670
|
+
"does",
|
|
18671
|
+
"make",
|
|
18672
|
+
"create",
|
|
18673
|
+
"show",
|
|
18674
|
+
"hello",
|
|
18675
|
+
"help",
|
|
18676
|
+
"please",
|
|
18677
|
+
"thanks",
|
|
18678
|
+
"how",
|
|
18679
|
+
"what",
|
|
18680
|
+
"where",
|
|
18681
|
+
"why"
|
|
18682
|
+
],
|
|
18683
|
+
fr: [
|
|
18684
|
+
"le",
|
|
18685
|
+
"la",
|
|
18686
|
+
"les",
|
|
18687
|
+
"un",
|
|
18688
|
+
"une",
|
|
18689
|
+
"des",
|
|
18690
|
+
"de",
|
|
18691
|
+
"du",
|
|
18692
|
+
"et",
|
|
18693
|
+
"est",
|
|
18694
|
+
"sont",
|
|
18695
|
+
"que",
|
|
18696
|
+
"qui",
|
|
18697
|
+
"avec",
|
|
18698
|
+
"pour",
|
|
18699
|
+
"dans",
|
|
18700
|
+
"pas",
|
|
18701
|
+
"oui",
|
|
18702
|
+
"non",
|
|
18703
|
+
"faire",
|
|
18704
|
+
"cr\xE9er",
|
|
18705
|
+
"bonjour",
|
|
18706
|
+
"merci",
|
|
18707
|
+
"bien"
|
|
18708
|
+
],
|
|
18709
|
+
es: [
|
|
18710
|
+
"el",
|
|
18711
|
+
"la",
|
|
18712
|
+
"los",
|
|
18713
|
+
"las",
|
|
18714
|
+
"un",
|
|
18715
|
+
"una",
|
|
18716
|
+
"de",
|
|
18717
|
+
"del",
|
|
18718
|
+
"y",
|
|
18719
|
+
"es",
|
|
18720
|
+
"son",
|
|
18721
|
+
"que",
|
|
18722
|
+
"con",
|
|
18723
|
+
"por",
|
|
18724
|
+
"para",
|
|
18725
|
+
"no",
|
|
18726
|
+
"s\xED",
|
|
18727
|
+
"hacer",
|
|
18728
|
+
"crear",
|
|
18729
|
+
"mostrar",
|
|
18730
|
+
"hola",
|
|
18731
|
+
"gracias",
|
|
18732
|
+
"bueno"
|
|
18733
|
+
],
|
|
18734
|
+
de: [
|
|
18735
|
+
"der",
|
|
18736
|
+
"die",
|
|
18737
|
+
"das",
|
|
18738
|
+
"den",
|
|
18739
|
+
"dem",
|
|
18740
|
+
"des",
|
|
18741
|
+
"und",
|
|
18742
|
+
"ist",
|
|
18743
|
+
"sind",
|
|
18744
|
+
"nicht",
|
|
18745
|
+
"mit",
|
|
18746
|
+
"f\xFCr",
|
|
18747
|
+
"auf",
|
|
18748
|
+
"zu",
|
|
18749
|
+
"ja",
|
|
18750
|
+
"nein",
|
|
18751
|
+
"machen",
|
|
18752
|
+
"erstellen",
|
|
18753
|
+
"zeigen",
|
|
18754
|
+
"hallo",
|
|
18755
|
+
"danke",
|
|
18756
|
+
"gut"
|
|
18757
|
+
],
|
|
18758
|
+
pt: [
|
|
18759
|
+
"o",
|
|
18760
|
+
"a",
|
|
18761
|
+
"os",
|
|
18762
|
+
"as",
|
|
18763
|
+
"um",
|
|
18764
|
+
"uma",
|
|
18765
|
+
"de",
|
|
18766
|
+
"do",
|
|
18767
|
+
"da",
|
|
18768
|
+
"e",
|
|
18769
|
+
"\xE9",
|
|
18770
|
+
"s\xE3o",
|
|
18771
|
+
"que",
|
|
18772
|
+
"com",
|
|
18773
|
+
"para",
|
|
18774
|
+
"n\xE3o",
|
|
18775
|
+
"sim",
|
|
18776
|
+
"fazer",
|
|
18777
|
+
"criar",
|
|
18778
|
+
"mostrar",
|
|
18779
|
+
"ol\xE1",
|
|
18780
|
+
"obrigado",
|
|
18781
|
+
"bom"
|
|
18782
|
+
],
|
|
18783
|
+
nl: [
|
|
18784
|
+
"de",
|
|
18785
|
+
"het",
|
|
18786
|
+
"een",
|
|
18787
|
+
"van",
|
|
18788
|
+
"en",
|
|
18789
|
+
"is",
|
|
18790
|
+
"zijn",
|
|
18791
|
+
"niet",
|
|
18792
|
+
"met",
|
|
18793
|
+
"voor",
|
|
18794
|
+
"ja",
|
|
18795
|
+
"nee",
|
|
18796
|
+
"doen",
|
|
18797
|
+
"maken",
|
|
18798
|
+
"tonen",
|
|
18799
|
+
"hallo",
|
|
18800
|
+
"dank",
|
|
18801
|
+
"goed"
|
|
18802
|
+
]
|
|
18803
|
+
};
|
|
18804
|
+
LANGUAGE_POLICY_MODULE_TYPE = "language-policy";
|
|
18805
|
+
}
|
|
18806
|
+
});
|
|
18807
|
+
|
|
18404
18808
|
// packages/core/dist/skills/index.js
|
|
18405
18809
|
var skills_exports = {};
|
|
18406
18810
|
__export(skills_exports, {
|
|
@@ -18408,14 +18812,19 @@ __export(skills_exports, {
|
|
|
18408
18812
|
ALL_TOOLS: () => ALL_TOOLS,
|
|
18409
18813
|
CODING_CATEGORY: () => CODING_CATEGORY,
|
|
18410
18814
|
CODING_SKILL_CATALOG: () => CODING_SKILL_CATALOG,
|
|
18815
|
+
LANGUAGE_POLICY_MODULE_TYPE: () => LANGUAGE_POLICY_MODULE_TYPE,
|
|
18411
18816
|
SINGLE_AGENT_IDENTITY_MODULE: () => SINGLE_AGENT_IDENTITY_MODULE,
|
|
18412
18817
|
SKILL_CATALOG: () => SKILL_CATALOG,
|
|
18413
18818
|
TOOL_DEFINITIONS: () => TOOL_DEFINITIONS,
|
|
18414
18819
|
VAULT_TOOL_DEFINITIONS: () => VAULT_TOOL_DEFINITIONS,
|
|
18415
18820
|
buildCustomParameters: () => buildCustomParameters,
|
|
18821
|
+
buildLanguageDirective: () => buildLanguageDirective,
|
|
18822
|
+
buildLanguagePolicyModule: () => buildLanguagePolicyModule,
|
|
18823
|
+
buildLanguagePolicyModuleFor: () => buildLanguagePolicyModuleFor,
|
|
18416
18824
|
buildSystemPrompt: () => buildSystemPrompt,
|
|
18417
18825
|
clearCustomTools: () => clearCustomTools,
|
|
18418
18826
|
cliToolToEnhanced: () => cliToolToEnhanced,
|
|
18827
|
+
detectResponseLanguage: () => detectResponseLanguage,
|
|
18419
18828
|
executeTool: () => executeTool,
|
|
18420
18829
|
findCodingSkillsByCategory: () => findCodingSkillsByCategory,
|
|
18421
18830
|
findCodingSkillsByTag: () => findCodingSkillsByTag,
|
|
@@ -18436,6 +18845,7 @@ __export(skills_exports, {
|
|
|
18436
18845
|
registerCustomTool: () => registerCustomTool,
|
|
18437
18846
|
registerSkill: () => registerSkill,
|
|
18438
18847
|
resolveAgentSkills: () => resolveAgentSkills,
|
|
18848
|
+
resolveResponseLanguage: () => resolveResponseLanguage,
|
|
18439
18849
|
resolveSkillDependencies: () => resolveSkillDependencies,
|
|
18440
18850
|
setWorkspaceStubs: () => setWorkspaceStubs,
|
|
18441
18851
|
unregisterCustomTool: () => unregisterCustomTool,
|
|
@@ -18453,6 +18863,7 @@ var init_skills2 = __esm({
|
|
|
18453
18863
|
init_harnessToolBridge();
|
|
18454
18864
|
init_promptModules();
|
|
18455
18865
|
init_systemPromptBuilder();
|
|
18866
|
+
init_languagePolicy();
|
|
18456
18867
|
}
|
|
18457
18868
|
});
|
|
18458
18869
|
|
|
@@ -23438,6 +23849,17 @@ async function* runCouncilPure(userMessage, config2, callbacks = {}) {
|
|
|
23438
23849
|
const sessionId = config2.sessionId ?? crypto.randomUUID();
|
|
23439
23850
|
const runMode = config2.runMode ?? "implementation";
|
|
23440
23851
|
const isDesignPhase = runMode === "design-phase";
|
|
23852
|
+
let councilLanguageModule;
|
|
23853
|
+
try {
|
|
23854
|
+
councilLanguageModule = buildLanguagePolicyModuleFor(userMessage);
|
|
23855
|
+
} catch {
|
|
23856
|
+
councilLanguageModule = {
|
|
23857
|
+
type: "language-policy",
|
|
23858
|
+
title: "Response Language",
|
|
23859
|
+
priority: 5,
|
|
23860
|
+
content: "# Response Language\nReply in the user's language when possible, otherwise Italian."
|
|
23861
|
+
};
|
|
23862
|
+
}
|
|
23441
23863
|
yield createBrainEvent("council_mode", sessionId, {
|
|
23442
23864
|
tier: councilTierFromSize(config2.councilSize),
|
|
23443
23865
|
councilSize: config2.councilSize,
|
|
@@ -23561,7 +23983,8 @@ async function* runCouncilPure(userMessage, config2, callbacks = {}) {
|
|
|
23561
23983
|
effectiveModel,
|
|
23562
23984
|
onToolCall: () => {
|
|
23563
23985
|
toolCalls += 1;
|
|
23564
|
-
}
|
|
23986
|
+
},
|
|
23987
|
+
languageModule: councilLanguageModule
|
|
23565
23988
|
});
|
|
23566
23989
|
} else if (isDesignPhase) {
|
|
23567
23990
|
enforceDesignPhaseToolEmissions(agent.id, emittedToolNames);
|
|
@@ -23699,7 +24122,8 @@ async function* runCouncilPure(userMessage, config2, callbacks = {}) {
|
|
|
23699
24122
|
effectiveModel,
|
|
23700
24123
|
onToolCall: () => {
|
|
23701
24124
|
toolCalls += 1;
|
|
23702
|
-
}
|
|
24125
|
+
},
|
|
24126
|
+
languageModule: councilLanguageModule
|
|
23703
24127
|
});
|
|
23704
24128
|
} else if (isDesignPhase) {
|
|
23705
24129
|
enforceDesignPhaseToolEmissions(oracle.id, emittedToolNames);
|
|
@@ -23867,7 +24291,8 @@ async function* runCouncilPure(userMessage, config2, callbacks = {}) {
|
|
|
23867
24291
|
effectiveModel,
|
|
23868
24292
|
onToolCall: () => {
|
|
23869
24293
|
toolCalls += 1;
|
|
23870
|
-
}
|
|
24294
|
+
},
|
|
24295
|
+
languageModule: councilLanguageModule
|
|
23871
24296
|
});
|
|
23872
24297
|
} else if (isDesignPhase) {
|
|
23873
24298
|
enforceDesignPhaseToolEmissions(chairman.id, emittedToolNames);
|
|
@@ -23927,7 +24352,8 @@ async function* runCouncilPure(userMessage, config2, callbacks = {}) {
|
|
|
23927
24352
|
onSuccessfulWrite: () => {
|
|
23928
24353
|
successfulWriteCount += 1;
|
|
23929
24354
|
},
|
|
23930
|
-
onCouncilStatus: callbacks.onCouncilStatus
|
|
24355
|
+
onCouncilStatus: callbacks.onCouncilStatus,
|
|
24356
|
+
languageModule: councilLanguageModule
|
|
23931
24357
|
});
|
|
23932
24358
|
}
|
|
23933
24359
|
}
|
|
@@ -23946,7 +24372,8 @@ async function* runCouncilPure(userMessage, config2, callbacks = {}) {
|
|
|
23946
24372
|
effectiveModel,
|
|
23947
24373
|
onToolCall: () => {
|
|
23948
24374
|
toolCalls += 1;
|
|
23949
|
-
}
|
|
24375
|
+
},
|
|
24376
|
+
languageModule: councilLanguageModule
|
|
23950
24377
|
});
|
|
23951
24378
|
}
|
|
23952
24379
|
if (chairmanProjectRoot) {
|
|
@@ -23964,7 +24391,8 @@ async function* runCouncilPure(userMessage, config2, callbacks = {}) {
|
|
|
23964
24391
|
onToolCall: () => {
|
|
23965
24392
|
toolCalls += 1;
|
|
23966
24393
|
},
|
|
23967
|
-
onCouncilStatus: callbacks.onCouncilStatus
|
|
24394
|
+
onCouncilStatus: callbacks.onCouncilStatus,
|
|
24395
|
+
languageModule: councilLanguageModule
|
|
23968
24396
|
});
|
|
23969
24397
|
}
|
|
23970
24398
|
}
|
|
@@ -24030,7 +24458,8 @@ async function* applyCompletionRetry(args) {
|
|
|
24030
24458
|
toolRegistry: args.config.tools,
|
|
24031
24459
|
providerStream: args.config.providerStream,
|
|
24032
24460
|
runMode: args.config.runMode,
|
|
24033
|
-
retryPrompt: buildImplementationVerifyRetryPrompt(retryTool)
|
|
24461
|
+
retryPrompt: buildImplementationVerifyRetryPrompt(retryTool),
|
|
24462
|
+
languageModule: args.languageModule
|
|
24034
24463
|
});
|
|
24035
24464
|
for await (const event of retryGenerator) {
|
|
24036
24465
|
if (event.type === "tool_execution_start") {
|
|
@@ -24088,7 +24517,8 @@ async function* applyImplementationWriteRetry(args) {
|
|
|
24088
24517
|
toolRegistry: args.config.tools,
|
|
24089
24518
|
providerStream: args.config.providerStream,
|
|
24090
24519
|
runMode: "implementation",
|
|
24091
|
-
retryPrompt: buildImplementationWriteRetryPrompt(args.userMessage)
|
|
24520
|
+
retryPrompt: buildImplementationWriteRetryPrompt(args.userMessage),
|
|
24521
|
+
languageModule: args.languageModule
|
|
24092
24522
|
});
|
|
24093
24523
|
for await (const event of retryGenerator) {
|
|
24094
24524
|
if (event.type === "tool_execution_start")
|
|
@@ -24157,7 +24587,8 @@ async function* runChairmanDeliveryLoop(args) {
|
|
|
24157
24587
|
toolRegistry: args.config.tools,
|
|
24158
24588
|
providerStream: args.config.providerStream,
|
|
24159
24589
|
runMode: "implementation",
|
|
24160
|
-
retryPrompt: buildDeliveryFixPrompt(blocking, args.userMessage)
|
|
24590
|
+
retryPrompt: buildDeliveryFixPrompt(blocking, args.userMessage),
|
|
24591
|
+
languageModule: args.languageModule
|
|
24161
24592
|
});
|
|
24162
24593
|
for await (const event of fixGenerator) {
|
|
24163
24594
|
if (event.type === "tool_execution_start")
|
|
@@ -24255,7 +24686,8 @@ async function* runChairmanFixLoop(args) {
|
|
|
24255
24686
|
toolRegistry: args.config.tools,
|
|
24256
24687
|
providerStream: args.config.providerStream,
|
|
24257
24688
|
runMode: "implementation",
|
|
24258
|
-
retryPrompt: buildMotionFixPrompt(current)
|
|
24689
|
+
retryPrompt: buildMotionFixPrompt(current),
|
|
24690
|
+
languageModule: args.languageModule
|
|
24259
24691
|
});
|
|
24260
24692
|
for await (const event of fixGenerator) {
|
|
24261
24693
|
if (event.type === "tool_execution_start")
|
|
@@ -24400,7 +24832,8 @@ async function* applyRetryIfMissing(args) {
|
|
|
24400
24832
|
eventBus: args.config.eventBus,
|
|
24401
24833
|
toolRegistry: args.config.tools,
|
|
24402
24834
|
providerStream: args.config.providerStream,
|
|
24403
|
-
runMode: args.config.runMode
|
|
24835
|
+
runMode: args.config.runMode,
|
|
24836
|
+
languageModule: args.languageModule
|
|
24404
24837
|
});
|
|
24405
24838
|
for await (const event of retryGenerator) {
|
|
24406
24839
|
if (event.type === "tool_execution_start") {
|
|
@@ -24422,6 +24855,7 @@ var init_councilApi = __esm({
|
|
|
24422
24855
|
init_toolSchemas();
|
|
24423
24856
|
init_systemPromptBuilder();
|
|
24424
24857
|
init_tools();
|
|
24858
|
+
init_languagePolicy();
|
|
24425
24859
|
init_events();
|
|
24426
24860
|
init_AgentHarness();
|
|
24427
24861
|
init_modeBanners();
|
|
@@ -25820,7 +26254,7 @@ import {
|
|
|
25820
26254
|
readdirSync as readdirSync2,
|
|
25821
26255
|
renameSync as renameSync2
|
|
25822
26256
|
} from "node:fs";
|
|
25823
|
-
import { dirname, join as join13 } from "node:path";
|
|
26257
|
+
import { dirname as dirname2, join as join13 } from "node:path";
|
|
25824
26258
|
function parseFrontmatter(md) {
|
|
25825
26259
|
const m = FRONTMATTER_RE.exec(md);
|
|
25826
26260
|
if (!m) return { meta: {}, body: md };
|
|
@@ -26091,7 +26525,7 @@ var init_storage = __esm({
|
|
|
26091
26525
|
* The meta object is serialized as YAML frontmatter; body as Markdown.
|
|
26092
26526
|
*/
|
|
26093
26527
|
write(path34, meta3, body) {
|
|
26094
|
-
mkdirSync7(
|
|
26528
|
+
mkdirSync7(dirname2(path34), { recursive: true });
|
|
26095
26529
|
const tmp = path34 + ".tmp-" + process.pid;
|
|
26096
26530
|
const md = serializeFrontmatter(meta3, body);
|
|
26097
26531
|
writeFileSync11(tmp, md, "utf8");
|
|
@@ -26146,7 +26580,7 @@ import {
|
|
|
26146
26580
|
mkdirSync as mkdirSync8,
|
|
26147
26581
|
renameSync as renameSync3
|
|
26148
26582
|
} from "node:fs";
|
|
26149
|
-
import { join as join14, basename as basename2, dirname as
|
|
26583
|
+
import { join as join14, basename as basename2, dirname as dirname3, relative as relative2 } from "node:path";
|
|
26150
26584
|
function createWorkspaceContext(projectRoot = process.cwd()) {
|
|
26151
26585
|
const rootDir = resolveWorkspaceRoot(projectRoot);
|
|
26152
26586
|
return {
|
|
@@ -26185,7 +26619,7 @@ function readPlan(ctx) {
|
|
|
26185
26619
|
}
|
|
26186
26620
|
function writePlan(ctx, summary) {
|
|
26187
26621
|
const jsonPath = planJsonPath(ctx);
|
|
26188
|
-
mkdirSync8(
|
|
26622
|
+
mkdirSync8(dirname3(jsonPath), { recursive: true });
|
|
26189
26623
|
const tmp = jsonPath + ".tmp-" + process.pid;
|
|
26190
26624
|
writeFileSync12(tmp, JSON.stringify(summary, null, 2), "utf8");
|
|
26191
26625
|
renameSync3(tmp, jsonPath);
|
|
@@ -28764,29 +29198,47 @@ __export(prereqChecks_exports, {
|
|
|
28764
29198
|
checkAgentGit: () => checkAgentGit,
|
|
28765
29199
|
checkAgentNode: () => checkAgentNode,
|
|
28766
29200
|
checkMainNode: () => checkMainNode,
|
|
29201
|
+
isWslBashPath: () => isWslBashPath2,
|
|
28767
29202
|
runPrereqChecks: () => runPrereqChecks
|
|
28768
29203
|
});
|
|
28769
29204
|
import { execSync, spawnSync as spawnSync2 } from "node:child_process";
|
|
28770
29205
|
import { existsSync as existsSync25 } from "node:fs";
|
|
29206
|
+
import { dirname as dirname4 } from "node:path";
|
|
29207
|
+
function isWslBashPath2(p3) {
|
|
29208
|
+
if (!p3 || typeof p3 !== "string") return false;
|
|
29209
|
+
const n = p3.replace(/\//g, "\\").toLowerCase();
|
|
29210
|
+
if (n.includes("\\windows\\system32\\bash.exe")) return true;
|
|
29211
|
+
if (n.includes("\\windows\\syswow64\\bash.exe")) return true;
|
|
29212
|
+
if (n.includes("\\windowsapps\\bash.exe")) return true;
|
|
29213
|
+
return false;
|
|
29214
|
+
}
|
|
29215
|
+
function acceptBashPath2(p3) {
|
|
29216
|
+
if (!p3 || p3.trim().length === 0) return null;
|
|
29217
|
+
const trimmed = p3.trim();
|
|
29218
|
+
if (isWslBashPath2(trimmed)) return null;
|
|
29219
|
+
if (!existsSyncSafe2(trimmed)) return null;
|
|
29220
|
+
return trimmed;
|
|
29221
|
+
}
|
|
28771
29222
|
function resolveAgentShellSync() {
|
|
28772
29223
|
if (process.platform !== "win32") {
|
|
28773
29224
|
return { bashPath: null, isBash: true, via: "/bin/sh" };
|
|
28774
29225
|
}
|
|
28775
|
-
const
|
|
28776
|
-
if (
|
|
28777
|
-
return { bashPath:
|
|
29226
|
+
const fromEnv = acceptBashPath2(process.env.ZELARI_SHELL);
|
|
29227
|
+
if (fromEnv) {
|
|
29228
|
+
return { bashPath: fromEnv, isBash: true, via: `bash (${fromEnv})` };
|
|
28778
29229
|
}
|
|
28779
|
-
const
|
|
28780
|
-
if (
|
|
29230
|
+
const fromSession = acceptBashPath2(process.env.SHELL);
|
|
29231
|
+
if (fromSession) {
|
|
28781
29232
|
return {
|
|
28782
|
-
bashPath:
|
|
29233
|
+
bashPath: fromSession,
|
|
28783
29234
|
isBash: true,
|
|
28784
|
-
via: `bash (${
|
|
29235
|
+
via: `bash (${fromSession})`
|
|
28785
29236
|
};
|
|
28786
29237
|
}
|
|
28787
29238
|
for (const p3 of STANDARD_BASH_PATHS2) {
|
|
28788
|
-
|
|
28789
|
-
|
|
29239
|
+
const accepted = acceptBashPath2(p3);
|
|
29240
|
+
if (accepted) {
|
|
29241
|
+
return { bashPath: accepted, isBash: true, via: `bash (${accepted})` };
|
|
28790
29242
|
}
|
|
28791
29243
|
}
|
|
28792
29244
|
try {
|
|
@@ -28795,16 +29247,39 @@ function resolveAgentShellSync() {
|
|
|
28795
29247
|
windowsHide: true
|
|
28796
29248
|
});
|
|
28797
29249
|
if (result.status === 0 && result.stdout) {
|
|
28798
|
-
const
|
|
28799
|
-
|
|
28800
|
-
|
|
28801
|
-
|
|
29250
|
+
for (const line of result.stdout.split(/\r?\n/)) {
|
|
29251
|
+
const accepted = acceptBashPath2(line);
|
|
29252
|
+
if (accepted) {
|
|
29253
|
+
return {
|
|
29254
|
+
bashPath: accepted,
|
|
29255
|
+
isBash: true,
|
|
29256
|
+
via: `bash (${accepted})`
|
|
29257
|
+
};
|
|
29258
|
+
}
|
|
28802
29259
|
}
|
|
28803
29260
|
}
|
|
28804
29261
|
} catch {
|
|
28805
29262
|
}
|
|
28806
29263
|
return { bashPath: null, isBash: false, via: "cmd.exe" };
|
|
28807
29264
|
}
|
|
29265
|
+
function agentProbeEnv() {
|
|
29266
|
+
const env = { ...process.env };
|
|
29267
|
+
try {
|
|
29268
|
+
const nodeDir = dirname4(process.execPath);
|
|
29269
|
+
if (!nodeDir) return env;
|
|
29270
|
+
const sep = process.platform === "win32" ? ";" : ":";
|
|
29271
|
+
const current = env.PATH ?? env.Path ?? "";
|
|
29272
|
+
const parts = current.split(sep).filter((p3) => p3.length > 0);
|
|
29273
|
+
const has = parts.some(
|
|
29274
|
+
(p3) => p3.toLowerCase() === nodeDir.toLowerCase()
|
|
29275
|
+
);
|
|
29276
|
+
if (!has) {
|
|
29277
|
+
env.PATH = `${nodeDir}${sep}${current}`;
|
|
29278
|
+
}
|
|
29279
|
+
} catch {
|
|
29280
|
+
}
|
|
29281
|
+
return env;
|
|
29282
|
+
}
|
|
28808
29283
|
function existsSyncSafe2(p3) {
|
|
28809
29284
|
try {
|
|
28810
29285
|
return existsSync25(p3);
|
|
@@ -28815,12 +29290,14 @@ function existsSyncSafe2(p3) {
|
|
|
28815
29290
|
function probeTool(tool) {
|
|
28816
29291
|
const shell = resolveAgentShellSync();
|
|
28817
29292
|
let stdout = "";
|
|
29293
|
+
const env = agentProbeEnv();
|
|
28818
29294
|
if (shell.bashPath) {
|
|
28819
29295
|
try {
|
|
28820
29296
|
const r = spawnSync2(shell.bashPath, ["-c", `${tool} --version`], {
|
|
28821
29297
|
encoding: "utf8",
|
|
28822
29298
|
stdio: ["ignore", "pipe", "ignore"],
|
|
28823
|
-
windowsHide: true
|
|
29299
|
+
windowsHide: true,
|
|
29300
|
+
env
|
|
28824
29301
|
});
|
|
28825
29302
|
if (r.status === 0) stdout = (r.stdout || "").trim();
|
|
28826
29303
|
} catch {
|
|
@@ -28829,7 +29306,8 @@ function probeTool(tool) {
|
|
|
28829
29306
|
try {
|
|
28830
29307
|
stdout = execSync(`${tool} --version`, {
|
|
28831
29308
|
encoding: "utf8",
|
|
28832
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
29309
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
29310
|
+
env
|
|
28833
29311
|
}).trim();
|
|
28834
29312
|
} catch {
|
|
28835
29313
|
}
|
|
@@ -28837,7 +29315,8 @@ function probeTool(tool) {
|
|
|
28837
29315
|
try {
|
|
28838
29316
|
stdout = execSync(`${tool} --version`, {
|
|
28839
29317
|
encoding: "utf8",
|
|
28840
|
-
stdio: ["ignore", "pipe", "ignore"]
|
|
29318
|
+
stdio: ["ignore", "pipe", "ignore"],
|
|
29319
|
+
env
|
|
28841
29320
|
}).trim();
|
|
28842
29321
|
} catch {
|
|
28843
29322
|
}
|
|
@@ -28852,14 +29331,21 @@ function probeTool(tool) {
|
|
|
28852
29331
|
function nodeMissingHint() {
|
|
28853
29332
|
const shell = resolveAgentShellSync();
|
|
28854
29333
|
if (process.platform === "win32") {
|
|
29334
|
+
if (!shell.isBash) {
|
|
29335
|
+
return `node is not reachable from the agent's shell (${shell.via}).
|
|
29336
|
+
Install Node >= ${MIN_NODE_MAJOR} (https://nodejs.org) and ensure it is
|
|
29337
|
+
on PATH, then open a NEW terminal. Optional: install Git for
|
|
29338
|
+
Windows so the agent can use real bash (https://git-scm.com/download/win).`;
|
|
29339
|
+
}
|
|
28855
29340
|
return `node is not reachable from the agent's shell (${shell.via}).
|
|
28856
29341
|
This usually means Node was installed for "current user" only,
|
|
28857
|
-
while Git Bash
|
|
29342
|
+
while Git Bash sees a different Path. Fix (pick one):
|
|
28858
29343
|
- Reinstall Node (https://nodejs.org) and choose
|
|
28859
29344
|
"Add to PATH for all users", OR
|
|
28860
|
-
- Add
|
|
28861
|
-
|
|
28862
|
-
|
|
29345
|
+
- Add your nodejs folder to the User or System Path, OR
|
|
29346
|
+
- Set ZELARI_SHELL to a bash that already sees node.
|
|
29347
|
+
Note: WSL's C:\\Windows\\System32\\bash.exe is NOT a valid agent
|
|
29348
|
+
shell \u2014 install Git for Windows instead.`;
|
|
28863
29349
|
}
|
|
28864
29350
|
return `node is not on the agent's shell PATH.
|
|
28865
29351
|
Install Node >= ${MIN_NODE_MAJOR} (https://nodejs.org) or, if you use
|
|
@@ -33163,12 +33649,32 @@ function finalizeStreamingAssistant(setMessages) {
|
|
|
33163
33649
|
});
|
|
33164
33650
|
}
|
|
33165
33651
|
|
|
33652
|
+
// src/cli/utils/envNumber.ts
|
|
33653
|
+
function envNumber(raw, opts) {
|
|
33654
|
+
const { default: def, min, max } = opts;
|
|
33655
|
+
if (raw === void 0 || raw === null) return def;
|
|
33656
|
+
const trimmed = raw.trim();
|
|
33657
|
+
if (trimmed.length === 0) return def;
|
|
33658
|
+
if (trimmed.toLowerCase() === "undefined" || trimmed.toLowerCase() === "null") return def;
|
|
33659
|
+
const parsed = Number.parseInt(trimmed, 10);
|
|
33660
|
+
if (!Number.isFinite(parsed)) return def;
|
|
33661
|
+
const absStr = `${Math.abs(parsed)}`;
|
|
33662
|
+
const body = trimmed.replace(/^[-+]/, "").replace(/^0+(?=\d)/, "");
|
|
33663
|
+
if (body !== absStr) return def;
|
|
33664
|
+
const firstChar = trimmed[0];
|
|
33665
|
+
const expectedSign = parsed < 0 ? "-" : /[0-9+]/.test(firstChar ?? "");
|
|
33666
|
+
const actualSign = parsed < 0 ? firstChar === "-" : firstChar !== "-";
|
|
33667
|
+
if (!expectedSign || !actualSign) return def;
|
|
33668
|
+
let clamped = parsed;
|
|
33669
|
+
if (min !== void 0 && clamped < min) clamped = min;
|
|
33670
|
+
if (max !== void 0 && clamped > max) clamped = max;
|
|
33671
|
+
return clamped;
|
|
33672
|
+
}
|
|
33673
|
+
|
|
33166
33674
|
// src/cli/hooks/historyCompaction.ts
|
|
33167
33675
|
var COMPACT_MARKER = "[history] Earlier turns were compacted to stay within the context budget.";
|
|
33168
33676
|
function resolveMaxMessages(opts) {
|
|
33169
|
-
const
|
|
33170
|
-
const parsed = raw ? Number.parseInt(raw, 10) : 6;
|
|
33171
|
-
const envTurns = Number.isFinite(parsed) && parsed >= 0 ? parsed : 6;
|
|
33677
|
+
const envTurns = envNumber(process.env.ZELARI_HISTORY_TURNS, { default: 6, min: 0 });
|
|
33172
33678
|
const turns = opts?.maxMessages ? Math.ceil(opts.maxMessages / 4) : envTurns;
|
|
33173
33679
|
if (turns <= 0) return 0;
|
|
33174
33680
|
return turns * 4;
|
|
@@ -33379,21 +33885,24 @@ function useChatTurn(params) {
|
|
|
33379
33885
|
const workspaceContext = [workspaceSummary, zelariReadHint].filter(Boolean).join("\n\n");
|
|
33380
33886
|
let systemPrompt;
|
|
33381
33887
|
try {
|
|
33888
|
+
const languageModule = buildLanguagePolicyModuleFor(userText);
|
|
33382
33889
|
systemPrompt = buildSystemPrompt(singleAgentRole, {
|
|
33383
33890
|
tools: getAllTools(),
|
|
33384
33891
|
toolNames: toolListNames,
|
|
33385
33892
|
aiConfig: {
|
|
33386
33893
|
enabledSkills: [],
|
|
33387
33894
|
enabledTools: toolListNames,
|
|
33388
|
-
customPromptModules: [SINGLE_AGENT_IDENTITY_MODULE],
|
|
33895
|
+
customPromptModules: [SINGLE_AGENT_IDENTITY_MODULE, languageModule],
|
|
33389
33896
|
agentSkillConfigs: []
|
|
33390
33897
|
},
|
|
33391
33898
|
workspaceContext: workspaceContext || void 0,
|
|
33392
33899
|
ragContext: planSummary || void 0
|
|
33393
33900
|
});
|
|
33394
33901
|
} catch {
|
|
33902
|
+
const languageModule = buildLanguagePolicyModuleFor(userText);
|
|
33395
33903
|
systemPrompt = [
|
|
33396
33904
|
SINGLE_AGENT_IDENTITY_MODULE.content,
|
|
33905
|
+
languageModule.content,
|
|
33397
33906
|
shellContextBlock,
|
|
33398
33907
|
"# Available Tools",
|
|
33399
33908
|
"You can call these tools. Use them to take action and gather information autonomously:",
|
|
@@ -33402,16 +33911,14 @@ function useChatTurn(params) {
|
|
|
33402
33911
|
...planSummary ? ["", planSummary] : []
|
|
33403
33912
|
].join("\n");
|
|
33404
33913
|
}
|
|
33405
|
-
const maxToolCallsPerTurn = (
|
|
33406
|
-
|
|
33407
|
-
|
|
33408
|
-
|
|
33409
|
-
|
|
33410
|
-
|
|
33411
|
-
|
|
33412
|
-
|
|
33413
|
-
return Number.isFinite(n) && n > 0 ? n : 90;
|
|
33414
|
-
})();
|
|
33914
|
+
const maxToolCallsPerTurn = envNumber(process.env.ZELARI_MAX_TOOL_CALLS, {
|
|
33915
|
+
default: 25,
|
|
33916
|
+
min: 1
|
|
33917
|
+
});
|
|
33918
|
+
const maxToolLoopIterations = envNumber(process.env.ZELARI_MAX_TOOL_LOOP_ITERATIONS, {
|
|
33919
|
+
default: 90,
|
|
33920
|
+
min: 1
|
|
33921
|
+
});
|
|
33415
33922
|
const harness2 = new AgentHarness({
|
|
33416
33923
|
model: envConfig.model,
|
|
33417
33924
|
provider: "openai-compatible",
|
|
@@ -33748,11 +34255,10 @@ async function dispatchCouncilPromptImpl(text, deps, overrides = {}) {
|
|
|
33748
34255
|
const councilFeedbackStore = new FeedbackStore2();
|
|
33749
34256
|
let streamContent = "";
|
|
33750
34257
|
let streamMemberId = null;
|
|
33751
|
-
const councilMaxToolCalls = (
|
|
33752
|
-
|
|
33753
|
-
|
|
33754
|
-
|
|
33755
|
-
})();
|
|
34258
|
+
const councilMaxToolCalls = envNumber(process.env.ZELARI_MAX_TOOL_CALLS, {
|
|
34259
|
+
default: 15,
|
|
34260
|
+
min: 1
|
|
34261
|
+
});
|
|
33756
34262
|
let membersCompleted = 0;
|
|
33757
34263
|
let chairmanProducedOutput = false;
|
|
33758
34264
|
let chairmanSynthesisText = "";
|
|
@@ -34129,11 +34635,10 @@ async function runZelariMissionInTui(userMessage, deps, emit) {
|
|
|
34129
34635
|
hasPlan: hasWorkspacePlan2(projectRoot)
|
|
34130
34636
|
});
|
|
34131
34637
|
const memory = await getMemoryBackend2(projectRoot);
|
|
34132
|
-
const chairmanBudget = (
|
|
34133
|
-
|
|
34134
|
-
|
|
34135
|
-
|
|
34136
|
-
})();
|
|
34638
|
+
const chairmanBudget = envNumber(process.env.ZELARI_MODE_MAX_TOOLS_LUCIFER, {
|
|
34639
|
+
default: 30,
|
|
34640
|
+
min: 1
|
|
34641
|
+
});
|
|
34137
34642
|
try {
|
|
34138
34643
|
await runZelariMission2(userMessage, brief, {
|
|
34139
34644
|
projectRoot,
|
|
@@ -37295,6 +37800,7 @@ function emitEvent(event) {
|
|
|
37295
37800
|
// src/cli/runHeadless.ts
|
|
37296
37801
|
init_harness();
|
|
37297
37802
|
init_toolRegistry();
|
|
37803
|
+
init_skills2();
|
|
37298
37804
|
async function runHeadless(opts) {
|
|
37299
37805
|
const { provider, model } = resolveHeadlessProvider(opts);
|
|
37300
37806
|
const key = await resolveHeadlessKey(provider);
|
|
@@ -37322,11 +37828,61 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
37322
37828
|
description: t.function.description,
|
|
37323
37829
|
parameters: t.function.parameters
|
|
37324
37830
|
}));
|
|
37325
|
-
const
|
|
37326
|
-
|
|
37327
|
-
|
|
37328
|
-
|
|
37329
|
-
|
|
37831
|
+
const toolNames = tools.map((t) => t.name);
|
|
37832
|
+
let systemPrompt;
|
|
37833
|
+
let languageDirectiveContent;
|
|
37834
|
+
try {
|
|
37835
|
+
languageDirectiveContent = buildLanguagePolicyModuleFor(opts.task).content;
|
|
37836
|
+
} catch {
|
|
37837
|
+
languageDirectiveContent = "# Response Language\nReply in the user's language when possible, otherwise Italian.";
|
|
37838
|
+
}
|
|
37839
|
+
try {
|
|
37840
|
+
const headlessRole = {
|
|
37841
|
+
id: "single",
|
|
37842
|
+
name: "Zelari Code",
|
|
37843
|
+
codename: "zelari",
|
|
37844
|
+
role: "headless coding agent",
|
|
37845
|
+
color: "#00d9a3",
|
|
37846
|
+
avatar: "\u25C6",
|
|
37847
|
+
tools: toolNames,
|
|
37848
|
+
// v1.7.0 fix (agy audit): include platform/shell context in the role
|
|
37849
|
+
// prompt so the agent knows its cwd and shell — previously this was
|
|
37850
|
+
// empty (systemPrompt: '') and the agent lacked the platform block
|
|
37851
|
+
// the TUI single-agent path gets.
|
|
37852
|
+
systemPrompt: [
|
|
37853
|
+
"# Platform",
|
|
37854
|
+
`platform: ${process.platform}`,
|
|
37855
|
+
`shell: ${process.platform === "win32" ? "cmd.exe / Git Bash (auto-detected)" : "/bin/sh"}`,
|
|
37856
|
+
"",
|
|
37857
|
+
"# Working Directory",
|
|
37858
|
+
`You are running in: ${process.cwd()}`,
|
|
37859
|
+
"All relative file paths are resolved against this directory.",
|
|
37860
|
+
"The shell is NON-INTERACTIVE (stdin closed): pass non-interactive flags (--yes, --force, --template)."
|
|
37861
|
+
].join("\n")
|
|
37862
|
+
};
|
|
37863
|
+
systemPrompt = buildSystemPrompt(headlessRole, {
|
|
37864
|
+
tools: getAllTools(),
|
|
37865
|
+
toolNames,
|
|
37866
|
+
aiConfig: {
|
|
37867
|
+
enabledSkills: [],
|
|
37868
|
+
enabledTools: toolNames,
|
|
37869
|
+
customPromptModules: [SINGLE_AGENT_IDENTITY_MODULE, {
|
|
37870
|
+
type: "language-policy",
|
|
37871
|
+
title: "Response Language",
|
|
37872
|
+
priority: 5,
|
|
37873
|
+
content: languageDirectiveContent
|
|
37874
|
+
}],
|
|
37875
|
+
agentSkillConfigs: []
|
|
37876
|
+
}
|
|
37877
|
+
});
|
|
37878
|
+
} catch {
|
|
37879
|
+
systemPrompt = [
|
|
37880
|
+
"You are zelari-code, a CLI coding agent. Be concise and direct.",
|
|
37881
|
+
"When the user asks you to write code, debug, or explore, be proactive: list files and read key files to understand the project.",
|
|
37882
|
+
"When you finish a task, briefly summarize what you did.",
|
|
37883
|
+
languageDirectiveContent
|
|
37884
|
+
].join("\n");
|
|
37885
|
+
}
|
|
37330
37886
|
const harness = new AgentHarness({
|
|
37331
37887
|
model,
|
|
37332
37888
|
provider,
|
|
@@ -37339,9 +37895,8 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
37339
37895
|
toolRegistry,
|
|
37340
37896
|
providerStream,
|
|
37341
37897
|
maxToolLoopIterations: (() => {
|
|
37342
|
-
const
|
|
37343
|
-
|
|
37344
|
-
return Number.isFinite(n) && n > 0 ? n : 30;
|
|
37898
|
+
const n = envNumber(process.env.ZELARI_MAX_TOOL_LOOP_ITERATIONS, { default: 30, min: 1 });
|
|
37899
|
+
return n;
|
|
37345
37900
|
})()
|
|
37346
37901
|
});
|
|
37347
37902
|
let finalReason = "completed";
|