@wrongstack/cli 0.308.7 → 0.309.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/{cli-main-L3T4KJKU.js → cli-main-RG2PTQ6S.js} +739 -543
- package/dist/{execution-6HIKTAUB.js → execution-TYUXABWI.js} +51 -2
- package/dist/index.js +3 -3
- package/dist/{providers-models-4FAKM2WO.js → providers-models-D23WUD74.js} +2 -2
- package/dist/slash-commands/effort.d.ts +33 -0
- package/package.json +25 -25
|
@@ -5644,7 +5644,7 @@ async function runCliExecution(params) {
|
|
|
5644
5644
|
governanceHandle,
|
|
5645
5645
|
setConfig
|
|
5646
5646
|
} = params;
|
|
5647
|
-
const { execute } = await import("./execution-
|
|
5647
|
+
const { execute } = await import("./execution-TYUXABWI.js");
|
|
5648
5648
|
return execute(
|
|
5649
5649
|
toExecuteDeps({
|
|
5650
5650
|
core: {
|
|
@@ -22966,7 +22966,9 @@ import {
|
|
|
22966
22966
|
} from "@wrongstack/core/coordination";
|
|
22967
22967
|
import { decryptConfigSecrets as decryptConfigSecrets4, encryptConfigSecrets as encryptConfigSecrets4, noOpVault as noOpVault6 } from "@wrongstack/core/security";
|
|
22968
22968
|
import {
|
|
22969
|
-
ConfigError as ConfigError5
|
|
22969
|
+
ConfigError as ConfigError5,
|
|
22970
|
+
REASONING_EFFORT_LEVELS,
|
|
22971
|
+
isReasoningEffort
|
|
22970
22972
|
} from "@wrongstack/core/types";
|
|
22971
22973
|
import { atomicWrite as atomicWrite8, color as color48, expectDefined as expectDefined6, toErrorMessage as toErrorMessage21 } from "@wrongstack/core/utils";
|
|
22972
22974
|
import { catalogProviderIdFor } from "@wrongstack/providers";
|
|
@@ -23021,18 +23023,6 @@ function parseTarget(tokens, profiles = {}) {
|
|
|
23021
23023
|
}
|
|
23022
23024
|
return { model: only };
|
|
23023
23025
|
}
|
|
23024
|
-
var REASONING_EFFORTS = [
|
|
23025
|
-
"none",
|
|
23026
|
-
"minimal",
|
|
23027
|
-
"low",
|
|
23028
|
-
"medium",
|
|
23029
|
-
"high",
|
|
23030
|
-
"xhigh",
|
|
23031
|
-
"max"
|
|
23032
|
-
];
|
|
23033
|
-
function isReasoningEffort(value) {
|
|
23034
|
-
return !!value && REASONING_EFFORTS.includes(value);
|
|
23035
|
-
}
|
|
23036
23026
|
function isReasoningMode(value) {
|
|
23037
23027
|
return value === "auto" || value === "on" || value === "off";
|
|
23038
23028
|
}
|
|
@@ -23410,7 +23400,7 @@ function buildSetModelCommand(opts) {
|
|
|
23410
23400
|
const key = parts[1];
|
|
23411
23401
|
if (!key) {
|
|
23412
23402
|
return {
|
|
23413
|
-
message: `${color48.amber("Usage:")} /setmodel ${sub} <role|phase|*> ${sub === "reasoning" ? "auto|on|off [effort]" : sub === "reasoning-effort" ?
|
|
23403
|
+
message: `${color48.amber("Usage:")} /setmodel ${sub} <role|phase|*> ${sub === "reasoning" ? "auto|on|off [effort]" : sub === "reasoning-effort" ? REASONING_EFFORT_LEVELS.join("|") : "on|off"}`
|
|
23414
23404
|
};
|
|
23415
23405
|
}
|
|
23416
23406
|
if (matrixKeyKind(key) === "unknown") {
|
|
@@ -23431,7 +23421,7 @@ function buildSetModelCommand(opts) {
|
|
|
23431
23421
|
if (parts[3] !== void 0) {
|
|
23432
23422
|
if (!isReasoningEffort(parts[3])) {
|
|
23433
23423
|
return {
|
|
23434
|
-
message: `${color48.red("Invalid effort")}: "${parts[3]}". Expected ${
|
|
23424
|
+
message: `${color48.red("Invalid effort")}: "${parts[3]}". Expected ${REASONING_EFFORT_LEVELS.join(", ")}.`
|
|
23435
23425
|
};
|
|
23436
23426
|
}
|
|
23437
23427
|
nextEffort = parts[3];
|
|
@@ -23439,7 +23429,7 @@ function buildSetModelCommand(opts) {
|
|
|
23439
23429
|
} else if (sub === "reasoning-effort") {
|
|
23440
23430
|
if (!isReasoningEffort(parts[2])) {
|
|
23441
23431
|
return {
|
|
23442
|
-
message: `${color48.amber("Usage:")} /setmodel reasoning-effort ${key} ${
|
|
23432
|
+
message: `${color48.amber("Usage:")} /setmodel reasoning-effort ${key} ${REASONING_EFFORT_LEVELS.join("|")}`
|
|
23443
23433
|
};
|
|
23444
23434
|
}
|
|
23445
23435
|
nextEffort = parts[2];
|
|
@@ -23549,11 +23539,213 @@ function buildSetModelCommand(opts) {
|
|
|
23549
23539
|
};
|
|
23550
23540
|
}
|
|
23551
23541
|
|
|
23542
|
+
// src/slash-commands/effort.ts
|
|
23543
|
+
import { decryptConfigSecrets as decryptConfigSecrets5, encryptConfigSecrets as encryptConfigSecrets5, noOpVault as noOpVault7 } from "@wrongstack/core/security";
|
|
23544
|
+
import {
|
|
23545
|
+
isReasoningEffort as isReasoningEffort2,
|
|
23546
|
+
REASONING_EFFORT_LEVELS as REASONING_EFFORT_LEVELS2
|
|
23547
|
+
} from "@wrongstack/core/types";
|
|
23548
|
+
import { atomicWrite as atomicWrite9, color as color49 } from "@wrongstack/core/utils";
|
|
23549
|
+
import { catalogProviderIdFor as catalogProviderIdFor2 } from "@wrongstack/providers";
|
|
23550
|
+
import * as fs14 from "node:fs/promises";
|
|
23551
|
+
function buildEffortCommand(opts) {
|
|
23552
|
+
const levelsHint = REASONING_EFFORT_LEVELS2.join("|");
|
|
23553
|
+
const help = [
|
|
23554
|
+
"Usage:",
|
|
23555
|
+
" /effort Show current session effort + supported levels",
|
|
23556
|
+
` /effort <level> Set session effort (${levelsHint})`,
|
|
23557
|
+
" /effort clear Remove the setting \u2014 provider default applies",
|
|
23558
|
+
" /effort matrix Show per-role/phase effort overrides (/setmodel)",
|
|
23559
|
+
"",
|
|
23560
|
+
"Applies to the active model on the next request. Unsupported values for the",
|
|
23561
|
+
"current model are rejected up front when its capabilities are known.",
|
|
23562
|
+
"Per-subagent overrides: /setmodel reasoning-effort <role|phase|*> <level>."
|
|
23563
|
+
].join("\n");
|
|
23564
|
+
async function loadModelLevels() {
|
|
23565
|
+
const registry = opts.modelsRegistry;
|
|
23566
|
+
if (!registry) return { levels: void 0, supported: void 0 };
|
|
23567
|
+
const config = opts.configStore.get();
|
|
23568
|
+
try {
|
|
23569
|
+
const catalogId = catalogProviderIdFor2(
|
|
23570
|
+
config.provider,
|
|
23571
|
+
config.providers?.[config.provider]?.type
|
|
23572
|
+
);
|
|
23573
|
+
const resolved = await registry.getModel(catalogId, config.model);
|
|
23574
|
+
const rc = resolved?.capabilities.reasoningConfig;
|
|
23575
|
+
if (!rc) {
|
|
23576
|
+
const provider = await registry.getProvider(catalogId).catch(() => void 0);
|
|
23577
|
+
const raw = provider?.models.find((m) => m.id === config.model);
|
|
23578
|
+
return { levels: void 0, supported: raw?.reasoning === false ? false : void 0 };
|
|
23579
|
+
}
|
|
23580
|
+
return {
|
|
23581
|
+
levels: rc.effortLevels?.length ? rc.effortLevels : void 0,
|
|
23582
|
+
// rc present ⇒ the model is known to reason. Only a DOCUMENTED
|
|
23583
|
+
// absence (`effortSupported === false`) marks it unsupported; an
|
|
23584
|
+
// undocumented vocabulary (`undefined`) is "supported, not
|
|
23585
|
+
// enumerated" — accept any canonical level and let the wire adapter
|
|
23586
|
+
// gate. `undefined` here is reserved for capabilities-unknown above.
|
|
23587
|
+
supported: rc.effortSupported !== false
|
|
23588
|
+
};
|
|
23589
|
+
} catch {
|
|
23590
|
+
return { levels: void 0, supported: void 0 };
|
|
23591
|
+
}
|
|
23592
|
+
}
|
|
23593
|
+
return {
|
|
23594
|
+
name: "effort",
|
|
23595
|
+
category: "Config",
|
|
23596
|
+
description: "View or set the session-wide reasoning effort for the active model.",
|
|
23597
|
+
argsHint: `[${levelsHint}|clear|matrix]`,
|
|
23598
|
+
help,
|
|
23599
|
+
async run(args) {
|
|
23600
|
+
const parts = args.trim().split(/\s+/).filter(Boolean);
|
|
23601
|
+
const sub = (parts[0] ?? "").toLowerCase();
|
|
23602
|
+
if (sub === "help" || sub === "--help") return { message: help };
|
|
23603
|
+
if (!opts.configStore || !opts.paths) {
|
|
23604
|
+
return { message: `${color49.red("Error")} config store not available.` };
|
|
23605
|
+
}
|
|
23606
|
+
const config = opts.configStore.get();
|
|
23607
|
+
if (sub === "matrix") {
|
|
23608
|
+
const matrix = config.modelMatrix ?? {};
|
|
23609
|
+
const entries = Object.entries(matrix).filter(([, e]) => e?.modelRuntime?.reasoning);
|
|
23610
|
+
if (entries.length === 0) {
|
|
23611
|
+
return {
|
|
23612
|
+
message: [
|
|
23613
|
+
`${color49.bold("Effort overrides")} ${color49.dim("(model matrix)")}`,
|
|
23614
|
+
` ${color49.dim("(none \u2014 set one with /setmodel reasoning-effort <role|phase|*> <level>)")}`
|
|
23615
|
+
].join("\n")
|
|
23616
|
+
};
|
|
23617
|
+
}
|
|
23618
|
+
const lines = [`${color49.bold("Effort overrides")} ${color49.dim("(model matrix)")}`];
|
|
23619
|
+
for (const [key, entry] of entries.sort(([a], [b]) => a.localeCompare(b))) {
|
|
23620
|
+
const reasoning = entry.modelRuntime.reasoning;
|
|
23621
|
+
const bits = [
|
|
23622
|
+
reasoning.effort ? `effort:${reasoning.effort}` : "",
|
|
23623
|
+
reasoning.mode ? `mode:${reasoning.mode}` : "",
|
|
23624
|
+
reasoning.preserve !== void 0 ? `preserve:${reasoning.preserve ? "on" : "off"}` : ""
|
|
23625
|
+
].filter(Boolean);
|
|
23626
|
+
lines.push(` ${color49.amber(key.padEnd(22))} \u2192 ${bits.join(" ")}`);
|
|
23627
|
+
}
|
|
23628
|
+
return { message: lines.join("\n") };
|
|
23629
|
+
}
|
|
23630
|
+
const { levels, supported } = await loadModelLevels();
|
|
23631
|
+
const current = config.modelRuntime?.reasoning?.effort;
|
|
23632
|
+
if (!sub) {
|
|
23633
|
+
const lines = [
|
|
23634
|
+
`${color49.bold("WrongStack")} ${color49.dim("\u2014 Session effort")}`,
|
|
23635
|
+
"",
|
|
23636
|
+
` ${color49.bold("model")} ${color49.cyan(`${config.provider}/${config.model}`)}`
|
|
23637
|
+
];
|
|
23638
|
+
if (current) {
|
|
23639
|
+
const ok = !levels || levels.includes(current);
|
|
23640
|
+
lines.push(
|
|
23641
|
+
` ${color49.bold("effort")} ${color49.bold(current)}${ok ? "" : ` ${color49.amber(`(not advertised by this model \u2014 supported: ${levels.join(", ")})`)}`}`
|
|
23642
|
+
);
|
|
23643
|
+
} else {
|
|
23644
|
+
lines.push(` ${color49.bold("effort")} ${color49.dim("(not set \u2014 provider default)")}`);
|
|
23645
|
+
}
|
|
23646
|
+
if (levels) {
|
|
23647
|
+
const rendered = REASONING_EFFORT_LEVELS2.filter((l) => levels.includes(l)).map(
|
|
23648
|
+
(l) => l === current ? color49.bold(l) : l
|
|
23649
|
+
);
|
|
23650
|
+
lines.push(` ${color49.bold("levels")} ${rendered.join(" \xB7 ")}`);
|
|
23651
|
+
} else if (supported === true) {
|
|
23652
|
+
lines.push(
|
|
23653
|
+
` ${color49.bold("levels")} ${color49.dim("(not enumerated \u2014 any level is accepted; the transport applies its own gating)")}`
|
|
23654
|
+
);
|
|
23655
|
+
} else if (supported === false) {
|
|
23656
|
+
lines.push(
|
|
23657
|
+
` ${color49.bold("levels")} ${color49.red("no effort control")}${color49.dim(" \u2014 documented as unsupported for this model")}`
|
|
23658
|
+
);
|
|
23659
|
+
} else {
|
|
23660
|
+
lines.push(
|
|
23661
|
+
` ${color49.bold("levels")} ${color49.dim("(unknown \u2014 the resolver drops unsupported values with a warning)")}`
|
|
23662
|
+
);
|
|
23663
|
+
}
|
|
23664
|
+
lines.push(
|
|
23665
|
+
"",
|
|
23666
|
+
` ${color49.dim("/effort <level> \xB7 clear \xB7 matrix \xB7 help")}`
|
|
23667
|
+
);
|
|
23668
|
+
return { message: lines.join("\n") };
|
|
23669
|
+
}
|
|
23670
|
+
if (sub === "clear" || sub === "off-default") {
|
|
23671
|
+
if (current === void 0) {
|
|
23672
|
+
return { message: `${color49.dim("No session effort set \u2014 provider default already applies.")}` };
|
|
23673
|
+
}
|
|
23674
|
+
await patchSessionEffort(void 0, opts.paths, config.activeProfile ?? "default");
|
|
23675
|
+
opts.configStore.update({
|
|
23676
|
+
modelRuntime: {
|
|
23677
|
+
...config.modelRuntime,
|
|
23678
|
+
reasoning: { ...config.modelRuntime?.reasoning, effort: void 0 }
|
|
23679
|
+
}
|
|
23680
|
+
});
|
|
23681
|
+
return {
|
|
23682
|
+
message: `${color49.green("\u2713")} session effort cleared ${color49.dim("\u2014 provider default applies")}`
|
|
23683
|
+
};
|
|
23684
|
+
}
|
|
23685
|
+
if (!isReasoningEffort2(sub)) {
|
|
23686
|
+
return {
|
|
23687
|
+
message: `${color49.amber("Usage:")} /effort ${REASONING_EFFORT_LEVELS2.join("|")} | clear | matrix`
|
|
23688
|
+
};
|
|
23689
|
+
}
|
|
23690
|
+
if (supported === false) {
|
|
23691
|
+
return {
|
|
23692
|
+
message: [
|
|
23693
|
+
`${color49.red("No effort control")} for ${config.provider}/${config.model}: the catalog documents this model's reasoning options without effort levels.`,
|
|
23694
|
+
` ${color49.dim("/effort clear removes the setting")}`
|
|
23695
|
+
].join("\n")
|
|
23696
|
+
};
|
|
23697
|
+
}
|
|
23698
|
+
if (levels && !levels.includes(sub)) {
|
|
23699
|
+
return {
|
|
23700
|
+
message: [
|
|
23701
|
+
`${color49.red("Unsupported effort")} for ${config.provider}/${config.model}: "${sub}".`,
|
|
23702
|
+
` ${color49.dim(`advertised: ${levels.join(", ")}`)}`,
|
|
23703
|
+
` ${color49.dim("the resolver would drop this value with a warning \u2014 pick an advertised level, or /effort clear")}`
|
|
23704
|
+
].join("\n")
|
|
23705
|
+
};
|
|
23706
|
+
}
|
|
23707
|
+
await patchSessionEffort(sub, opts.paths, config.activeProfile ?? "default");
|
|
23708
|
+
opts.configStore.update({
|
|
23709
|
+
modelRuntime: {
|
|
23710
|
+
...config.modelRuntime,
|
|
23711
|
+
reasoning: { ...config.modelRuntime?.reasoning, effort: sub }
|
|
23712
|
+
}
|
|
23713
|
+
});
|
|
23714
|
+
return {
|
|
23715
|
+
message: `${color49.green("\u2713")} session effort \u2192 ${color49.bold(sub)} ${color49.dim(`(${config.provider}/${config.model}, next request)`)}`
|
|
23716
|
+
};
|
|
23717
|
+
}
|
|
23718
|
+
};
|
|
23719
|
+
}
|
|
23720
|
+
async function patchSessionEffort(effort, paths, activeProfile) {
|
|
23721
|
+
const targetPath = paths.profileConfig(activeProfile);
|
|
23722
|
+
let raw = "{}";
|
|
23723
|
+
try {
|
|
23724
|
+
raw = await fs14.readFile(targetPath, "utf8");
|
|
23725
|
+
} catch {
|
|
23726
|
+
}
|
|
23727
|
+
let parsed;
|
|
23728
|
+
try {
|
|
23729
|
+
parsed = JSON.parse(raw);
|
|
23730
|
+
} catch {
|
|
23731
|
+
parsed = {};
|
|
23732
|
+
}
|
|
23733
|
+
const decrypted = decryptConfigSecrets5(parsed, noOpVault7);
|
|
23734
|
+
const mr = decrypted.modelRuntime ?? {};
|
|
23735
|
+
const reasoning = { ...mr.reasoning ?? {} };
|
|
23736
|
+
if (effort === void 0) delete reasoning.effort;
|
|
23737
|
+
else reasoning.effort = effort;
|
|
23738
|
+
mr.reasoning = reasoning;
|
|
23739
|
+
decrypted.modelRuntime = mr;
|
|
23740
|
+
const encrypted = encryptConfigSecrets5(decrypted, noOpVault7);
|
|
23741
|
+
await atomicWrite9(targetPath, JSON.stringify(encrypted, null, 2), { mode: 384 });
|
|
23742
|
+
}
|
|
23743
|
+
|
|
23552
23744
|
// src/slash-commands/suggest.ts
|
|
23553
23745
|
import { execFile as execFile2 } from "node:child_process";
|
|
23554
23746
|
import { access as access3 } from "node:fs/promises";
|
|
23555
23747
|
import * as path16 from "node:path";
|
|
23556
|
-
import { color as
|
|
23748
|
+
import { color as color50, toErrorMessage as toErrorMessage22 } from "@wrongstack/core/utils";
|
|
23557
23749
|
import { parseNextSteps } from "@wrongstack/tools/next-steps";
|
|
23558
23750
|
function readGitStatus(projectRoot, includeBranch) {
|
|
23559
23751
|
const args = ["status", "--short"];
|
|
@@ -23645,7 +23837,7 @@ function buildSuggestCommand(opts) {
|
|
|
23645
23837
|
const suggestions = await generateHeuristicSuggestions(opts);
|
|
23646
23838
|
setSuggestions(suggestions);
|
|
23647
23839
|
opts.onSuggestions?.(suggestions);
|
|
23648
|
-
const display = formatSuggestions(suggestions) + "\n" +
|
|
23840
|
+
const display = formatSuggestions(suggestions) + "\n" + color50.dim("(Heuristic fallback \u2014 multi-agent not enabled)");
|
|
23649
23841
|
return { message: display };
|
|
23650
23842
|
}
|
|
23651
23843
|
if (!fresh && suggestCache && Date.now() - suggestCache.at < SUGGEST_CACHE_TTL_MS) {
|
|
@@ -23653,7 +23845,7 @@ function buildSuggestCommand(opts) {
|
|
|
23653
23845
|
opts.onSuggestions?.(suggestCache.suggestions);
|
|
23654
23846
|
const ageSec = Math.round((Date.now() - suggestCache.at) / 1e3);
|
|
23655
23847
|
return {
|
|
23656
|
-
message: formatSuggestions(suggestCache.suggestions) + "\n" +
|
|
23848
|
+
message: formatSuggestions(suggestCache.suggestions) + "\n" + color50.dim(`(cached ${ageSec}s ago \u2014 /suggest --fresh to regenerate)`)
|
|
23657
23849
|
};
|
|
23658
23850
|
}
|
|
23659
23851
|
const contextText = await collectContext({
|
|
@@ -23661,7 +23853,7 @@ function buildSuggestCommand(opts) {
|
|
|
23661
23853
|
projectRoot: opts.projectRoot
|
|
23662
23854
|
});
|
|
23663
23855
|
const task = buildSuggestPrompt(contextText);
|
|
23664
|
-
opts.renderer.write(
|
|
23856
|
+
opts.renderer.write(color50.dim("Generating suggestions..."));
|
|
23665
23857
|
try {
|
|
23666
23858
|
const raw = await opts.onSpawnAndWait(task, {
|
|
23667
23859
|
name: "suggest"
|
|
@@ -23756,14 +23948,14 @@ async function generateHeuristicSuggestions(opts) {
|
|
|
23756
23948
|
}
|
|
23757
23949
|
function formatSuggestions(suggestions) {
|
|
23758
23950
|
if (suggestions.length === 0) {
|
|
23759
|
-
return
|
|
23951
|
+
return color50.dim("No suggestions available.");
|
|
23760
23952
|
}
|
|
23761
23953
|
const lines = [
|
|
23762
|
-
` ${
|
|
23954
|
+
` ${color50.cyan("\u{1F4A1} Next steps")} ${color50.dim("(use /next 1, /next 2, or /next 1 2 3)")}`,
|
|
23763
23955
|
""
|
|
23764
23956
|
];
|
|
23765
23957
|
for (let i = 0; i < suggestions.length; i++) {
|
|
23766
|
-
const num =
|
|
23958
|
+
const num = color50.bold(`${i + 1}.`);
|
|
23767
23959
|
const text = suggestions[i] ?? "";
|
|
23768
23960
|
lines.push(` ${num} ${text}`);
|
|
23769
23961
|
}
|
|
@@ -23830,7 +24022,7 @@ function buildWebuiCommand() {
|
|
|
23830
24022
|
|
|
23831
24023
|
// src/slash-commands/theme.ts
|
|
23832
24024
|
import { THEME_PRESET_IDS } from "@wrongstack/core/types";
|
|
23833
|
-
import { color as
|
|
24025
|
+
import { color as color51, writeOut as writeOut3 } from "@wrongstack/core/utils";
|
|
23834
24026
|
var THEME_META = {
|
|
23835
24027
|
catppuccin: { name: "Catppuccin Mocha", desc: "Soft pastel dark theme (Default)" },
|
|
23836
24028
|
"tokyo-night": { name: "Tokyo Night", desc: "Deep violet, neon orange & cyan" },
|
|
@@ -23941,19 +24133,19 @@ async function runThemePicker(reader, activeId) {
|
|
|
23941
24133
|
);
|
|
23942
24134
|
const lines = [];
|
|
23943
24135
|
lines.push("");
|
|
23944
|
-
lines.push(`${
|
|
23945
|
-
lines.push(
|
|
24136
|
+
lines.push(`${color51.bold(color51.amber("WrongStack") + color51.dim(" \u2014 TUI Theme Selection"))}`);
|
|
24137
|
+
lines.push(color51.dim(" \u2191\u2193 navigate Enter select q quit"));
|
|
23946
24138
|
lines.push("");
|
|
23947
|
-
if (hasAbove) lines.push(
|
|
24139
|
+
if (hasAbove) lines.push(color51.dim(` \u2026 ${start} more above`));
|
|
23948
24140
|
for (let i = start; i < end; i++) {
|
|
23949
24141
|
const p = THEME_OPTIONS[i];
|
|
23950
|
-
const mark = p.id === activeId ?
|
|
23951
|
-
const prefix = i === currentCursor ?
|
|
23952
|
-
const name = i === currentCursor ?
|
|
24142
|
+
const mark = p.id === activeId ? color51.green(" [active]") : "";
|
|
24143
|
+
const prefix = i === currentCursor ? color51.bold("\u276F ") : " ";
|
|
24144
|
+
const name = i === currentCursor ? color51.bold(p.name) : p.name;
|
|
23953
24145
|
const desc = truncateDesc(p.desc, columns, p.id === activeId);
|
|
23954
|
-
lines.push(` ${prefix}${name.padEnd(21)} ${
|
|
24146
|
+
lines.push(` ${prefix}${name.padEnd(21)} ${color51.dim(desc)}${mark}`);
|
|
23955
24147
|
}
|
|
23956
|
-
if (hasBelow) lines.push(
|
|
24148
|
+
if (hasBelow) lines.push(color51.dim(` \u2026 ${THEME_OPTIONS.length - end} more below`));
|
|
23957
24149
|
lines.push("");
|
|
23958
24150
|
return lines.join("\n");
|
|
23959
24151
|
};
|
|
@@ -24008,21 +24200,21 @@ function buildThemeCommand(opts) {
|
|
|
24008
24200
|
}
|
|
24009
24201
|
}
|
|
24010
24202
|
return {
|
|
24011
|
-
message:
|
|
24203
|
+
message: color51.green(`Switched TUI theme preset to "${selected}" (saved to config).`),
|
|
24012
24204
|
metadata: { themePreset: selected }
|
|
24013
24205
|
};
|
|
24014
24206
|
}
|
|
24015
24207
|
const lines = [
|
|
24016
|
-
|
|
24208
|
+
color51.bold(`Current TUI theme: ${activePreset}`),
|
|
24017
24209
|
"",
|
|
24018
|
-
|
|
24210
|
+
color51.bold("Available Theme Presets:")
|
|
24019
24211
|
];
|
|
24020
24212
|
for (const t of THEME_OPTIONS) {
|
|
24021
|
-
const mark = t.id === activePreset ?
|
|
24022
|
-
lines.push(` \u2022 ${
|
|
24213
|
+
const mark = t.id === activePreset ? color51.green(" [active]") : "";
|
|
24214
|
+
lines.push(` \u2022 ${color51.bold(t.id.padEnd(21))} ${t.desc}${mark}`);
|
|
24023
24215
|
}
|
|
24024
24216
|
lines.push("");
|
|
24025
|
-
lines.push(
|
|
24217
|
+
lines.push(color51.dim("Usage: /theme <preset>"));
|
|
24026
24218
|
return { message: lines.join("\n") };
|
|
24027
24219
|
}
|
|
24028
24220
|
const preset = args.trim().toLowerCase();
|
|
@@ -24038,7 +24230,7 @@ function buildThemeCommand(opts) {
|
|
|
24038
24230
|
}
|
|
24039
24231
|
}
|
|
24040
24232
|
return {
|
|
24041
|
-
message:
|
|
24233
|
+
message: color51.green(`Switched TUI theme preset to "${preset}" (saved to config).`),
|
|
24042
24234
|
metadata: { themePreset: preset }
|
|
24043
24235
|
};
|
|
24044
24236
|
}
|
|
@@ -24046,7 +24238,7 @@ function buildThemeCommand(opts) {
|
|
|
24046
24238
|
}
|
|
24047
24239
|
|
|
24048
24240
|
// src/slash-commands/agents.ts
|
|
24049
|
-
import { noOpVault as
|
|
24241
|
+
import { noOpVault as noOpVault8 } from "@wrongstack/core/security";
|
|
24050
24242
|
function formatAgentLine(a) {
|
|
24051
24243
|
const statusIcon3 = {
|
|
24052
24244
|
spawned: "\u{1F7E2}",
|
|
@@ -24127,7 +24319,7 @@ function buildAgentsCommand(opts) {
|
|
|
24127
24319
|
configStore: opts.configStore,
|
|
24128
24320
|
profileConfigPath: opts.paths.profileConfig(activeProfile),
|
|
24129
24321
|
inProjectConfigPath: opts.paths.inProjectConfig,
|
|
24130
|
-
vault:
|
|
24322
|
+
vault: noOpVault8
|
|
24131
24323
|
},
|
|
24132
24324
|
(autonomy) => {
|
|
24133
24325
|
autonomy.fleetChatVerbosity = mode;
|
|
@@ -24285,8 +24477,8 @@ ${lines.join("\n")}` };
|
|
|
24285
24477
|
|
|
24286
24478
|
// src/slash-commands/hq.ts
|
|
24287
24479
|
import { readHqRuntimeFileSync, resolveHqConfig, resolveHqDataDir } from "@wrongstack/core/hq";
|
|
24288
|
-
import { noOpVault as
|
|
24289
|
-
import { color as
|
|
24480
|
+
import { noOpVault as noOpVault9 } from "@wrongstack/core/security";
|
|
24481
|
+
import { color as color52 } from "@wrongstack/core/utils";
|
|
24290
24482
|
function maskToken(t) {
|
|
24291
24483
|
if (t.length <= 10) return `${t.slice(0, 2)}\u2026(${t.length})`;
|
|
24292
24484
|
return `${t.slice(0, 6)}\u2026${t.slice(-4)} (${t.length} chars)`;
|
|
@@ -24297,12 +24489,12 @@ async function probeHq(url) {
|
|
|
24297
24489
|
const timer = setTimeout(() => ctrl.abort(), 2500);
|
|
24298
24490
|
const res = await fetch(url, { signal: ctrl.signal, redirect: "manual" }).catch(() => null);
|
|
24299
24491
|
clearTimeout(timer);
|
|
24300
|
-
if (!res) return
|
|
24301
|
-
if (res.ok) return
|
|
24302
|
-
if (res.status === 401) return
|
|
24303
|
-
return
|
|
24492
|
+
if (!res) return color52.red("unreachable");
|
|
24493
|
+
if (res.ok) return color52.green("reachable");
|
|
24494
|
+
if (res.status === 401) return color52.green("reachable") + color52.dim(" (token required)");
|
|
24495
|
+
return color52.amber(`reachable (HTTP ${res.status})`);
|
|
24304
24496
|
} catch {
|
|
24305
|
-
return
|
|
24497
|
+
return color52.red("unreachable");
|
|
24306
24498
|
}
|
|
24307
24499
|
}
|
|
24308
24500
|
function buildHqCommand(opts) {
|
|
@@ -24336,13 +24528,13 @@ function buildHqCommand(opts) {
|
|
|
24336
24528
|
const { cmd, rest } = parseSubcommand(args);
|
|
24337
24529
|
const sub = cmd;
|
|
24338
24530
|
if (!opts.configStore || !opts.paths) {
|
|
24339
|
-
return { message: `${
|
|
24531
|
+
return { message: `${color52.red("\u2717")} HQ config is unavailable in this surface.` };
|
|
24340
24532
|
}
|
|
24341
24533
|
const persistDeps = {
|
|
24342
24534
|
configStore: opts.configStore,
|
|
24343
24535
|
profileConfigPath: activeProfileConfigPath(opts.paths, opts.configStore.get()),
|
|
24344
24536
|
inProjectConfigPath: opts.paths.inProjectConfig,
|
|
24345
|
-
vault:
|
|
24537
|
+
vault: noOpVault9,
|
|
24346
24538
|
forceGlobal: true
|
|
24347
24539
|
};
|
|
24348
24540
|
const currentHq = opts.configStore.get().hq;
|
|
@@ -24350,14 +24542,14 @@ function buildHqCommand(opts) {
|
|
|
24350
24542
|
const url = (rest[0] ?? "").trim();
|
|
24351
24543
|
const token = rest.slice(1).join(" ").trim();
|
|
24352
24544
|
if (!url) {
|
|
24353
|
-
return { message: `${
|
|
24545
|
+
return { message: `${color52.amber("Usage:")} /hq set <http://host:3499> [client-token]` };
|
|
24354
24546
|
}
|
|
24355
24547
|
try {
|
|
24356
24548
|
const parsed = new URL(url);
|
|
24357
24549
|
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") throw new Error("proto");
|
|
24358
24550
|
} catch {
|
|
24359
24551
|
return {
|
|
24360
|
-
message: `${
|
|
24552
|
+
message: `${color52.red("Invalid URL:")} ${url} ${color52.dim("(expected http://host:3499)")}`
|
|
24361
24553
|
};
|
|
24362
24554
|
}
|
|
24363
24555
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -24369,16 +24561,16 @@ function buildHqCommand(opts) {
|
|
|
24369
24561
|
});
|
|
24370
24562
|
const reach = await probeHq(url);
|
|
24371
24563
|
const tokLine = token ? `
|
|
24372
|
-
token: ${
|
|
24564
|
+
token: ${color52.dim(maskToken(token))}` : "";
|
|
24373
24565
|
return {
|
|
24374
|
-
message: `${
|
|
24566
|
+
message: `${color52.green("\u2713")} HQ set \u2192 ${color52.cyan(url)}${tokLine}
|
|
24375
24567
|
status: ${reach}
|
|
24376
|
-
${
|
|
24568
|
+
${color52.dim("Connects on the next session start.")}`
|
|
24377
24569
|
};
|
|
24378
24570
|
}
|
|
24379
24571
|
if (sub === "token") {
|
|
24380
24572
|
const token = rest.join(" ").trim();
|
|
24381
|
-
if (!token) return { message: `${
|
|
24573
|
+
if (!token) return { message: `${color52.amber("Usage:")} /hq token <client-token>` };
|
|
24382
24574
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
24383
24575
|
const hq = cfg.hq ?? {};
|
|
24384
24576
|
hq.token = token;
|
|
@@ -24386,14 +24578,14 @@ function buildHqCommand(opts) {
|
|
|
24386
24578
|
cfg.hq = hq;
|
|
24387
24579
|
});
|
|
24388
24580
|
return {
|
|
24389
|
-
message: `${
|
|
24581
|
+
message: `${color52.green("\u2713")} HQ client token saved ${color52.dim(maskToken(token))}`
|
|
24390
24582
|
};
|
|
24391
24583
|
}
|
|
24392
24584
|
if (sub === "raw") {
|
|
24393
24585
|
const mode = (rest[0] ?? "").trim().toLowerCase();
|
|
24394
24586
|
if (mode !== "on" && mode !== "off") {
|
|
24395
24587
|
return {
|
|
24396
|
-
message: `${
|
|
24588
|
+
message: `${color52.amber("Usage:")} /hq raw on|off ${color52.dim("(publish raw chat/tool content to HQ)")}`
|
|
24397
24589
|
};
|
|
24398
24590
|
}
|
|
24399
24591
|
const on = mode === "on";
|
|
@@ -24403,8 +24595,8 @@ function buildHqCommand(opts) {
|
|
|
24403
24595
|
cfg.hq = hq;
|
|
24404
24596
|
});
|
|
24405
24597
|
return {
|
|
24406
|
-
message: `${
|
|
24407
|
-
${
|
|
24598
|
+
message: `${color52.green("\u2713")} HQ raw content \u2192 ${on ? color52.amber("on (unredacted)") : color52.dim("off (redacted)")}
|
|
24599
|
+
${color52.dim("Applies to sessions started after this change. Only enable for HQ servers you trust.")}`
|
|
24408
24600
|
};
|
|
24409
24601
|
}
|
|
24410
24602
|
if (sub === "on" || sub === "off") {
|
|
@@ -24415,29 +24607,29 @@ function buildHqCommand(opts) {
|
|
|
24415
24607
|
cfg.hq = hq;
|
|
24416
24608
|
});
|
|
24417
24609
|
return {
|
|
24418
|
-
message: `${
|
|
24610
|
+
message: `${color52.green("\u2713")} HQ publishing \u2192 ${on ? color52.cyan("on") : color52.dim("off")}`
|
|
24419
24611
|
};
|
|
24420
24612
|
}
|
|
24421
24613
|
if (sub === "clear") {
|
|
24422
24614
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
24423
24615
|
delete cfg.hq;
|
|
24424
24616
|
});
|
|
24425
|
-
return { message: `${
|
|
24617
|
+
return { message: `${color52.green("\u2713")} HQ configuration cleared.` };
|
|
24426
24618
|
}
|
|
24427
24619
|
if (sub === "" || sub === "status") {
|
|
24428
24620
|
const dataDir = resolveHqDataDir(currentHq?.dataDir);
|
|
24429
24621
|
const runtime = readHqRuntimeFileSync(dataDir);
|
|
24430
24622
|
const resolved = resolveHqConfig({ config: currentHq });
|
|
24431
|
-
const lines = [`${
|
|
24623
|
+
const lines = [`${color52.bold("\u{1F4CB} WrongStack HQ \u2014 connection")}`, ""];
|
|
24432
24624
|
if (!resolved) {
|
|
24433
24625
|
lines.push(
|
|
24434
|
-
` ${
|
|
24626
|
+
` ${color52.dim("Not configured.")} Use ${color52.cyan("/hq set <url> [token]")} to connect,`
|
|
24435
24627
|
);
|
|
24436
|
-
lines.push(` or run ${
|
|
24628
|
+
lines.push(` or run ${color52.cyan("wstack --hq")} locally (auto-discovered).`);
|
|
24437
24629
|
if (runtime) {
|
|
24438
24630
|
lines.push("");
|
|
24439
24631
|
lines.push(
|
|
24440
|
-
` ${
|
|
24632
|
+
` ${color52.green("A local HQ is running")} at ${color52.cyan(runtime.url)} ${color52.dim("(start a new session to attach)")}`
|
|
24441
24633
|
);
|
|
24442
24634
|
}
|
|
24443
24635
|
const message = lines.join("\n");
|
|
@@ -24445,35 +24637,35 @@ function buildHqCommand(opts) {
|
|
|
24445
24637
|
}
|
|
24446
24638
|
if (resolved.discover && !runtime) {
|
|
24447
24639
|
lines.push(
|
|
24448
|
-
` mode: ${
|
|
24640
|
+
` mode: ${color52.cyan("auto-discovery")} ${color52.dim("(no local HQ running yet)")}`
|
|
24449
24641
|
);
|
|
24450
24642
|
lines.push(
|
|
24451
|
-
` ${
|
|
24643
|
+
` ${color52.dim("This session will attach automatically when `wstack --hq` starts")}`
|
|
24452
24644
|
);
|
|
24453
|
-
lines.push(` ${
|
|
24454
|
-
lines.push(` ${
|
|
24645
|
+
lines.push(` ${color52.dim(`on this machine (watching ${dataDir}).`)}`);
|
|
24646
|
+
lines.push(` ${color52.dim("Disable with WRONGSTACK_HQ_ENABLED=0 or /hq off.")}`);
|
|
24455
24647
|
return { message: lines.join("\n") };
|
|
24456
24648
|
}
|
|
24457
24649
|
const source = process.env["WRONGSTACK_HQ_URL"] ? "WRONGSTACK_HQ_URL env" : currentHq?.url ? "config.json" : runtime ? `local HQ marker (pid ${runtime.pid ?? "?"})` : "default";
|
|
24458
|
-
lines.push(` url: ${
|
|
24650
|
+
lines.push(` url: ${color52.cyan(resolved.url)}`);
|
|
24459
24651
|
lines.push(
|
|
24460
|
-
` enabled: ${resolved.enabled === false ?
|
|
24652
|
+
` enabled: ${resolved.enabled === false ? color52.dim("false") : color52.green("true")}`
|
|
24461
24653
|
);
|
|
24462
|
-
if (resolved.discover) lines.push(` mode: ${
|
|
24463
|
-
lines.push(` source: ${
|
|
24654
|
+
if (resolved.discover) lines.push(` mode: ${color52.cyan("auto-discovery")}`);
|
|
24655
|
+
lines.push(` source: ${color52.dim(source)}`);
|
|
24464
24656
|
lines.push(
|
|
24465
|
-
` token: ${resolved.token ?
|
|
24657
|
+
` token: ${resolved.token ? color52.dim(maskToken(resolved.token)) : color52.dim("none (open mode)")}`
|
|
24466
24658
|
);
|
|
24467
24659
|
lines.push(
|
|
24468
|
-
` content: ${resolved.rawContent === true ?
|
|
24660
|
+
` content: ${resolved.rawContent === true ? color52.amber("raw (unredacted)") : color52.dim("redacted \u2014 explicitly disabled; enable with /hq raw on")}`
|
|
24469
24661
|
);
|
|
24470
|
-
if (resolved.projectAlias) lines.push(` alias: ${
|
|
24662
|
+
if (resolved.projectAlias) lines.push(` alias: ${color52.cyan(resolved.projectAlias)}`);
|
|
24471
24663
|
lines.push(` status: ${await probeHq(resolved.url)}`);
|
|
24472
24664
|
return { message: lines.join("\n") };
|
|
24473
24665
|
}
|
|
24474
24666
|
return {
|
|
24475
|
-
message: `${
|
|
24476
|
-
${
|
|
24667
|
+
message: `${color52.red("Unknown subcommand:")} ${sub}
|
|
24668
|
+
${color52.dim("Try /hq, /hq set <url> [token], /hq raw on|off, /hq on|off, /hq clear, or /help hq")}`
|
|
24477
24669
|
};
|
|
24478
24670
|
}
|
|
24479
24671
|
};
|
|
@@ -24524,11 +24716,11 @@ function buildMouseCommand(_opts) {
|
|
|
24524
24716
|
|
|
24525
24717
|
// src/slash-commands/project.ts
|
|
24526
24718
|
import { spawn as spawn5 } from "node:child_process";
|
|
24527
|
-
import * as
|
|
24719
|
+
import * as fs15 from "node:fs/promises";
|
|
24528
24720
|
import { createRequire } from "node:module";
|
|
24529
24721
|
import * as path17 from "node:path";
|
|
24530
24722
|
import {
|
|
24531
|
-
color as
|
|
24723
|
+
color as color53,
|
|
24532
24724
|
ensureProjectGitignore,
|
|
24533
24725
|
ensureProjectIdentity as ensureProjectIdentity2,
|
|
24534
24726
|
projectIdentityPath,
|
|
@@ -24661,17 +24853,17 @@ async function projectIdentityCommand(opts, ctx, action, confirmed) {
|
|
|
24661
24853
|
if (action === "show") {
|
|
24662
24854
|
const identity = await readProjectIdentity(root);
|
|
24663
24855
|
return identity ? {
|
|
24664
|
-
message: `${
|
|
24665
|
-
${
|
|
24666
|
-
} : { message: `No committed project identity. Run ${
|
|
24856
|
+
message: `${color53.bold("Project ID:")} ${color53.cyan(identity.projectId)}
|
|
24857
|
+
${color53.dim(filePath)}`
|
|
24858
|
+
} : { message: `No committed project identity. Run ${color53.cyan("/project init")}.` };
|
|
24667
24859
|
}
|
|
24668
24860
|
if (action === "init") {
|
|
24669
24861
|
const result2 = await ensureProjectIdentity2(root);
|
|
24670
24862
|
await ensureProjectGitignore(root);
|
|
24671
24863
|
return {
|
|
24672
|
-
message: result2.created ? `${
|
|
24673
|
-
${
|
|
24674
|
-
${
|
|
24864
|
+
message: result2.created ? `${color53.green("Created")} ${filePath}
|
|
24865
|
+
${color53.cyan(result2.identity.projectId)}
|
|
24866
|
+
${color53.dim("Commit this file so every clone and machine shares the same HQ project.")}` : `${color53.dim("Project identity already exists:")} ${color53.cyan(result2.identity.projectId)}`
|
|
24675
24867
|
};
|
|
24676
24868
|
}
|
|
24677
24869
|
if (!confirmed && opts.confirm) {
|
|
@@ -24686,17 +24878,17 @@ ${color52.dim("Commit this file so every clone and machine shares the same HQ pr
|
|
|
24686
24878
|
}
|
|
24687
24879
|
if (!confirmed) {
|
|
24688
24880
|
return {
|
|
24689
|
-
message: `Rekey requires confirmation. Pass ${
|
|
24881
|
+
message: `Rekey requires confirmation. Pass ${color53.cyan("--yes")} or ${color53.cyan("-y")}.`
|
|
24690
24882
|
};
|
|
24691
24883
|
}
|
|
24692
24884
|
const result = await rekeyProjectIdentity(root);
|
|
24693
24885
|
await ensureProjectGitignore(root);
|
|
24694
24886
|
return {
|
|
24695
24887
|
message: [
|
|
24696
|
-
result.previous ?
|
|
24697
|
-
`${
|
|
24698
|
-
|
|
24699
|
-
|
|
24888
|
+
result.previous ? color53.dim(`Previous: ${result.previous.projectId}`) : color53.dim("Previous: none"),
|
|
24889
|
+
`${color53.green("New project ID:")} ${color53.cyan(result.identity.projectId)}`,
|
|
24890
|
+
color53.dim(`Commit ${filePath} to make this fork independent on every machine.`),
|
|
24891
|
+
color53.dim("Restart WrongStack before publishing HQ or Kanban updates under the new ID.")
|
|
24700
24892
|
].join("\n")
|
|
24701
24893
|
};
|
|
24702
24894
|
}
|
|
@@ -24705,7 +24897,7 @@ async function listProjectsCommand(opts, ctx) {
|
|
|
24705
24897
|
const currentRoot = ctx?.projectRoot;
|
|
24706
24898
|
if (manifest.projects.length === 0) {
|
|
24707
24899
|
return {
|
|
24708
|
-
message:
|
|
24900
|
+
message: color53.dim("No projects registered. Add one: /project add <path> [name]")
|
|
24709
24901
|
};
|
|
24710
24902
|
}
|
|
24711
24903
|
const sorted = [...manifest.projects].sort((a, b) => {
|
|
@@ -24717,19 +24909,19 @@ async function listProjectsCommand(opts, ctx) {
|
|
|
24717
24909
|
const lines = [`Projects (${sorted.length}) registered in projects.json:`, ""];
|
|
24718
24910
|
for (const p of sorted) {
|
|
24719
24911
|
const isCurrent = p.root === currentRoot;
|
|
24720
|
-
const marker = isCurrent ?
|
|
24721
|
-
const name = isCurrent ?
|
|
24722
|
-
const slug =
|
|
24723
|
-
const last =
|
|
24912
|
+
const marker = isCurrent ? color53.green("\u25CF") : color53.dim("\u25CB");
|
|
24913
|
+
const name = isCurrent ? color53.bold(p.name) : p.name;
|
|
24914
|
+
const slug = color53.dim(`[${p.slug}]`);
|
|
24915
|
+
const last = color53.dim(fmtLastSeen(p.lastSeen));
|
|
24724
24916
|
lines.push(` ${marker} ${name} ${slug} ${last}`);
|
|
24725
24917
|
lines.push(` ${p.root}`);
|
|
24726
24918
|
if (isCurrent) {
|
|
24727
|
-
lines.push(` ${
|
|
24919
|
+
lines.push(` ${color53.green("\u2190 active session")}`);
|
|
24728
24920
|
}
|
|
24729
24921
|
lines.push("");
|
|
24730
24922
|
}
|
|
24731
24923
|
lines.push(
|
|
24732
|
-
|
|
24924
|
+
color53.dim(
|
|
24733
24925
|
"Commands: add <path> [name] | rename <slug> <name> | remove <slug> | switch [dir] (no args = picker)"
|
|
24734
24926
|
)
|
|
24735
24927
|
);
|
|
@@ -24738,19 +24930,19 @@ async function listProjectsCommand(opts, ctx) {
|
|
|
24738
24930
|
async function addProjectCommand(opts, ctx, targetPath, displayName) {
|
|
24739
24931
|
const resolved = path17.resolve(ctx?.projectRoot ?? ctx?.cwd ?? process.cwd(), targetPath);
|
|
24740
24932
|
try {
|
|
24741
|
-
await
|
|
24933
|
+
await fs15.access(resolved);
|
|
24742
24934
|
} catch {
|
|
24743
|
-
return { message:
|
|
24935
|
+
return { message: color53.red(`Directory not found: ${resolved}`) };
|
|
24744
24936
|
}
|
|
24745
|
-
const stat5 = await
|
|
24937
|
+
const stat5 = await fs15.stat(resolved);
|
|
24746
24938
|
if (!stat5.isDirectory()) {
|
|
24747
|
-
return { message:
|
|
24939
|
+
return { message: color53.red(`Not a directory: ${resolved}`) };
|
|
24748
24940
|
}
|
|
24749
24941
|
const manifest = await loadManifest(opts.paths?.globalConfig);
|
|
24750
24942
|
const existing = manifest.projects.find((p) => p.root === resolved);
|
|
24751
24943
|
if (existing) {
|
|
24752
24944
|
return {
|
|
24753
|
-
message:
|
|
24945
|
+
message: color53.yellow(`Project already registered: "${existing.name}" (${existing.slug})`)
|
|
24754
24946
|
};
|
|
24755
24947
|
}
|
|
24756
24948
|
const name = displayName?.trim() || path17.basename(resolved);
|
|
@@ -24762,9 +24954,9 @@ async function addProjectCommand(opts, ctx, targetPath, displayName) {
|
|
|
24762
24954
|
return {
|
|
24763
24955
|
message: [
|
|
24764
24956
|
"",
|
|
24765
|
-
|
|
24766
|
-
|
|
24767
|
-
|
|
24957
|
+
color53.green(` Added project: ${name}`),
|
|
24958
|
+
color53.dim(` Root: ${resolved}`),
|
|
24959
|
+
color53.dim(` Slug: ${slug}`),
|
|
24768
24960
|
""
|
|
24769
24961
|
].join("\n")
|
|
24770
24962
|
};
|
|
@@ -24774,7 +24966,7 @@ async function renameProjectCommand(opts, _ctx, slugOrName, newName) {
|
|
|
24774
24966
|
const project = findProject(manifest, slugOrName);
|
|
24775
24967
|
if (!project) {
|
|
24776
24968
|
return {
|
|
24777
|
-
message:
|
|
24969
|
+
message: color53.red(
|
|
24778
24970
|
`Project not found: "${slugOrName}". Use /project list to see available projects.`
|
|
24779
24971
|
)
|
|
24780
24972
|
};
|
|
@@ -24782,7 +24974,7 @@ async function renameProjectCommand(opts, _ctx, slugOrName, newName) {
|
|
|
24782
24974
|
const oldName = project.name;
|
|
24783
24975
|
project.name = newName;
|
|
24784
24976
|
await saveManifest(manifest, opts.paths?.globalConfig);
|
|
24785
|
-
return { message:
|
|
24977
|
+
return { message: color53.green(`Renamed: "${oldName}" \u2192 "${newName}" (${project.slug})`) };
|
|
24786
24978
|
}
|
|
24787
24979
|
async function removeProjectCommand(opts, _ctx, slugOrName) {
|
|
24788
24980
|
const manifest = await loadManifest(opts.paths?.globalConfig);
|
|
@@ -24791,7 +24983,7 @@ async function removeProjectCommand(opts, _ctx, slugOrName) {
|
|
|
24791
24983
|
);
|
|
24792
24984
|
if (idx === -1) {
|
|
24793
24985
|
return {
|
|
24794
|
-
message:
|
|
24986
|
+
message: color53.red(
|
|
24795
24987
|
`Project not found: "${slugOrName}". Use /project list to see available projects.`
|
|
24796
24988
|
)
|
|
24797
24989
|
};
|
|
@@ -24800,7 +24992,7 @@ async function removeProjectCommand(opts, _ctx, slugOrName) {
|
|
|
24800
24992
|
manifest.projects.splice(idx, 1);
|
|
24801
24993
|
await saveManifest(manifest, opts.paths?.globalConfig);
|
|
24802
24994
|
return {
|
|
24803
|
-
message:
|
|
24995
|
+
message: color53.dim(
|
|
24804
24996
|
`Removed: "${removed.name}" (${removed.root}) \u2014 data directory kept at ~/.wrongstack/projects/${removed.slug}/`
|
|
24805
24997
|
)
|
|
24806
24998
|
};
|
|
@@ -24808,13 +25000,13 @@ async function removeProjectCommand(opts, _ctx, slugOrName) {
|
|
|
24808
25000
|
async function switchProjectCommand(opts, ctx, target, displayName) {
|
|
24809
25001
|
const resolved = path17.resolve(ctx?.projectRoot ?? ctx?.cwd ?? process.cwd(), target);
|
|
24810
25002
|
try {
|
|
24811
|
-
await
|
|
25003
|
+
await fs15.access(resolved);
|
|
24812
25004
|
} catch {
|
|
24813
|
-
return { message:
|
|
25005
|
+
return { message: color53.red(`Directory not found: ${resolved}`) };
|
|
24814
25006
|
}
|
|
24815
|
-
const stat5 = await
|
|
25007
|
+
const stat5 = await fs15.stat(resolved);
|
|
24816
25008
|
if (!stat5.isDirectory()) {
|
|
24817
|
-
return { message:
|
|
25009
|
+
return { message: color53.red(`Not a directory: ${resolved}`) };
|
|
24818
25010
|
}
|
|
24819
25011
|
let cliPath;
|
|
24820
25012
|
try {
|
|
@@ -24822,12 +25014,12 @@ async function switchProjectCommand(opts, ctx, target, displayName) {
|
|
|
24822
25014
|
const pkgPath = req.resolve("@wrongstack/cli/package.json");
|
|
24823
25015
|
const pkgDir = path17.dirname(pkgPath);
|
|
24824
25016
|
cliPath = path17.join(pkgDir, "dist", "index.js");
|
|
24825
|
-
await
|
|
25017
|
+
await fs15.access(cliPath);
|
|
24826
25018
|
} catch {
|
|
24827
25019
|
cliPath = process.argv[1] ?? "";
|
|
24828
25020
|
if (!cliPath) {
|
|
24829
25021
|
return {
|
|
24830
|
-
message:
|
|
25022
|
+
message: color53.red(
|
|
24831
25023
|
"Could not locate the CLI entry point. Run `wstack` manually in the target directory."
|
|
24832
25024
|
)
|
|
24833
25025
|
};
|
|
@@ -24860,14 +25052,14 @@ async function switchProjectCommand(opts, ctx, target, displayName) {
|
|
|
24860
25052
|
// and boot/tui-project-spawn.ts documents this exact bug being removed.
|
|
24861
25053
|
});
|
|
24862
25054
|
child.on("error", (err) => {
|
|
24863
|
-
console.error(
|
|
25055
|
+
console.error(color53.red(`Failed to spawn wstack: ${err.message}`));
|
|
24864
25056
|
});
|
|
24865
25057
|
child.unref();
|
|
24866
25058
|
return {
|
|
24867
25059
|
message: [
|
|
24868
25060
|
"",
|
|
24869
|
-
|
|
24870
|
-
|
|
25061
|
+
color53.green(` Spawning wstack in ${resolved} ...`),
|
|
25062
|
+
color53.dim(" (current session stays open \u2014 Ctrl+C to return)"),
|
|
24871
25063
|
""
|
|
24872
25064
|
].join("\n")
|
|
24873
25065
|
};
|
|
@@ -24881,45 +25073,45 @@ async function confirmProjectSwitch(opts, targetName) {
|
|
|
24881
25073
|
const parallelActive = parallelEngine?.currentState === "running";
|
|
24882
25074
|
const hasActiveAgents = fleetRunning > 0 || eternalActive || parallelActive;
|
|
24883
25075
|
if (!hasActiveAgents) return true;
|
|
24884
|
-
const parts = [
|
|
25076
|
+
const parts = [color53.yellow(`\u26A0 Switching projects will stop all running agents.`), ""];
|
|
24885
25077
|
if (fleetRunning > 0) {
|
|
24886
|
-
parts.push(
|
|
25078
|
+
parts.push(color53.dim(` \u2022 ${fleetRunning} subagent(s) currently running`));
|
|
24887
25079
|
}
|
|
24888
25080
|
if (eternalActive) {
|
|
24889
|
-
parts.push(
|
|
25081
|
+
parts.push(color53.dim(" \u2022 Eternal engine is active"));
|
|
24890
25082
|
}
|
|
24891
25083
|
if (parallelActive) {
|
|
24892
|
-
parts.push(
|
|
25084
|
+
parts.push(color53.dim(" \u2022 Parallel engine is active"));
|
|
24893
25085
|
}
|
|
24894
25086
|
parts.push("");
|
|
24895
|
-
parts.push(
|
|
25087
|
+
parts.push(color53.dim(` Target: ${targetName}`));
|
|
24896
25088
|
opts.renderer.write(`
|
|
24897
25089
|
${parts.join("\n")}
|
|
24898
25090
|
`);
|
|
24899
25091
|
if (!opts.confirm) return true;
|
|
24900
25092
|
const confirmed = await opts.confirm(
|
|
24901
|
-
|
|
25093
|
+
color53.yellow(`Stop all agents and switch to "${targetName}"?`),
|
|
24902
25094
|
false
|
|
24903
25095
|
// default to No for safety
|
|
24904
25096
|
);
|
|
24905
25097
|
if (!confirmed) {
|
|
24906
|
-
opts.renderer.write(
|
|
25098
|
+
opts.renderer.write(color53.dim(" Switch cancelled.\n"));
|
|
24907
25099
|
return false;
|
|
24908
25100
|
}
|
|
24909
25101
|
if (fleetRunning > 0) {
|
|
24910
25102
|
const killed = opts.onFleetKill ? await opts.onFleetKill() : 0;
|
|
24911
25103
|
if (killed > 0) {
|
|
24912
|
-
opts.renderer.write(
|
|
25104
|
+
opts.renderer.write(color53.dim(` Stopped ${killed} subagent(s).
|
|
24913
25105
|
`));
|
|
24914
25106
|
}
|
|
24915
25107
|
}
|
|
24916
25108
|
if (eternalActive) {
|
|
24917
25109
|
eternalEngine?.stop();
|
|
24918
|
-
opts.renderer.write(
|
|
25110
|
+
opts.renderer.write(color53.dim(" Stopped eternal engine.\n"));
|
|
24919
25111
|
}
|
|
24920
25112
|
if (parallelActive) {
|
|
24921
25113
|
parallelEngine?.stop();
|
|
24922
|
-
opts.renderer.write(
|
|
25114
|
+
opts.renderer.write(color53.dim(" Stopped parallel engine.\n"));
|
|
24923
25115
|
}
|
|
24924
25116
|
return true;
|
|
24925
25117
|
}
|
|
@@ -24931,16 +25123,16 @@ async function switchInteractiveCommand(opts, ctx) {
|
|
|
24931
25123
|
currentProjectRoot: currentRoot
|
|
24932
25124
|
});
|
|
24933
25125
|
if (!result) {
|
|
24934
|
-
return { message:
|
|
25126
|
+
return { message: color53.dim("Cancelled.") };
|
|
24935
25127
|
}
|
|
24936
25128
|
switch (result.kind) {
|
|
24937
25129
|
case "project": {
|
|
24938
25130
|
const project = manifest.projects.find((p) => p.slug === result.key);
|
|
24939
25131
|
if (!project) {
|
|
24940
|
-
return { message:
|
|
25132
|
+
return { message: color53.red(`Project not found: ${result.key}`) };
|
|
24941
25133
|
}
|
|
24942
25134
|
if (project.root === currentRoot) {
|
|
24943
|
-
return { message:
|
|
25135
|
+
return { message: color53.dim(`Already in ${project.name} (${project.root})`) };
|
|
24944
25136
|
}
|
|
24945
25137
|
const canSwitch = await confirmProjectSwitch(opts, project.name);
|
|
24946
25138
|
if (!canSwitch) return { message: "" };
|
|
@@ -24953,11 +25145,11 @@ async function switchInteractiveCommand(opts, ctx) {
|
|
|
24953
25145
|
case "prev-sessions":
|
|
24954
25146
|
return handlePrevSessions(opts, ctx);
|
|
24955
25147
|
default:
|
|
24956
|
-
return { message:
|
|
25148
|
+
return { message: color53.dim("Cancelled.") };
|
|
24957
25149
|
}
|
|
24958
25150
|
}
|
|
24959
25151
|
default:
|
|
24960
|
-
return { message:
|
|
25152
|
+
return { message: color53.dim("Cancelled.") };
|
|
24961
25153
|
}
|
|
24962
25154
|
}
|
|
24963
25155
|
async function spawnInProject(opts, _ctx, root, projectName) {
|
|
@@ -24967,12 +25159,12 @@ async function spawnInProject(opts, _ctx, root, projectName) {
|
|
|
24967
25159
|
const pkgPath = req.resolve("@wrongstack/cli/package.json");
|
|
24968
25160
|
const pkgDir = path17.dirname(pkgPath);
|
|
24969
25161
|
cliPath = path17.join(pkgDir, "dist", "index.js");
|
|
24970
|
-
await
|
|
25162
|
+
await fs15.access(cliPath);
|
|
24971
25163
|
} catch {
|
|
24972
25164
|
cliPath = process.argv[1] ?? "";
|
|
24973
25165
|
if (!cliPath) {
|
|
24974
25166
|
return {
|
|
24975
|
-
message:
|
|
25167
|
+
message: color53.red(
|
|
24976
25168
|
"Could not locate the CLI entry point. Run `wstack` manually in the target directory."
|
|
24977
25169
|
)
|
|
24978
25170
|
};
|
|
@@ -25002,15 +25194,15 @@ async function spawnInProject(opts, _ctx, root, projectName) {
|
|
|
25002
25194
|
// and boot/tui-project-spawn.ts documents this exact bug being removed.
|
|
25003
25195
|
});
|
|
25004
25196
|
child.on("error", (err) => {
|
|
25005
|
-
console.error(
|
|
25197
|
+
console.error(color53.red(`Failed to spawn wstack: ${err.message}`));
|
|
25006
25198
|
});
|
|
25007
25199
|
child.unref();
|
|
25008
25200
|
return {
|
|
25009
25201
|
message: [
|
|
25010
25202
|
"",
|
|
25011
|
-
|
|
25012
|
-
|
|
25013
|
-
|
|
25203
|
+
color53.green(` Switched to ${projectName}`),
|
|
25204
|
+
color53.dim(` Root: ${root}`),
|
|
25205
|
+
color53.dim(" (current session stays open \u2014 Ctrl+C to return)"),
|
|
25014
25206
|
""
|
|
25015
25207
|
].join("\n")
|
|
25016
25208
|
};
|
|
@@ -25022,12 +25214,12 @@ async function handleNewSession(_opts, _ctx) {
|
|
|
25022
25214
|
const pkgPath = req.resolve("@wrongstack/cli/package.json");
|
|
25023
25215
|
const pkgDir = path17.dirname(pkgPath);
|
|
25024
25216
|
cliPath = path17.join(pkgDir, "dist", "index.js");
|
|
25025
|
-
await
|
|
25217
|
+
await fs15.access(cliPath);
|
|
25026
25218
|
} catch {
|
|
25027
25219
|
cliPath = process.argv[1] ?? "";
|
|
25028
25220
|
if (!cliPath) {
|
|
25029
25221
|
return {
|
|
25030
|
-
message:
|
|
25222
|
+
message: color53.red("Could not locate the CLI entry point. Run `wstack` manually.")
|
|
25031
25223
|
};
|
|
25032
25224
|
}
|
|
25033
25225
|
}
|
|
@@ -25044,14 +25236,14 @@ async function handleNewSession(_opts, _ctx) {
|
|
|
25044
25236
|
// and boot/tui-project-spawn.ts documents this exact bug being removed.
|
|
25045
25237
|
});
|
|
25046
25238
|
child.on("error", (err) => {
|
|
25047
|
-
console.error(
|
|
25239
|
+
console.error(color53.red(`Failed to spawn wstack: ${err.message}`));
|
|
25048
25240
|
});
|
|
25049
25241
|
child.unref();
|
|
25050
25242
|
return {
|
|
25051
25243
|
message: [
|
|
25052
25244
|
"",
|
|
25053
|
-
|
|
25054
|
-
|
|
25245
|
+
color53.green(" Starting new session ..."),
|
|
25246
|
+
color53.dim(" (current session stays open \u2014 Ctrl+C to return)"),
|
|
25055
25247
|
""
|
|
25056
25248
|
].join("\n")
|
|
25057
25249
|
};
|
|
@@ -25062,25 +25254,25 @@ async function handlePrevSessions(opts, _ctx) {
|
|
|
25062
25254
|
}
|
|
25063
25255
|
const list = await opts.sessionStore.list(15);
|
|
25064
25256
|
if (list.length === 0) {
|
|
25065
|
-
return { message:
|
|
25257
|
+
return { message: color53.dim("No saved sessions.") };
|
|
25066
25258
|
}
|
|
25067
25259
|
const currentId = opts.context?.session?.id;
|
|
25068
|
-
const lines = [
|
|
25260
|
+
const lines = [color53.bold(`Recent sessions (${list.length}):`), ""];
|
|
25069
25261
|
for (const s of list) {
|
|
25070
25262
|
const isCurrent = s.id === currentId;
|
|
25071
|
-
const marker = isCurrent ?
|
|
25072
|
-
const date =
|
|
25263
|
+
const marker = isCurrent ? color53.cyan("\u25CF") : " ";
|
|
25264
|
+
const date = color53.dim(s.startedAt.slice(0, 16).replace("T", " "));
|
|
25073
25265
|
const stats = [
|
|
25074
|
-
|
|
25075
|
-
s.toolCallCount ?
|
|
25076
|
-
s.iterationCount ?
|
|
25266
|
+
color53.dim(`${s.tokenTotal.toLocaleString()} tok`),
|
|
25267
|
+
s.toolCallCount ? color53.cyan(`${s.toolCallCount} calls`) : "",
|
|
25268
|
+
s.iterationCount ? color53.dim(`${s.iterationCount} iter`) : ""
|
|
25077
25269
|
].filter(Boolean).join(" ");
|
|
25078
|
-
const outcome = s.outcome === "completed" ?
|
|
25079
|
-
lines.push(` ${marker} ${
|
|
25080
|
-
lines.push(` ${stats} ${outcome} ${
|
|
25270
|
+
const outcome = s.outcome === "completed" ? color53.green("\u2713") : s.outcome === "aborted" ? color53.yellow("\u26A0") : s.outcome === "error" ? color53.red("\u2717") : color53.dim("?");
|
|
25271
|
+
lines.push(` ${marker} ${color53.bold(s.id)} ${date}`);
|
|
25272
|
+
lines.push(` ${stats} ${outcome} ${color53.dim(s.title)}`);
|
|
25081
25273
|
lines.push("");
|
|
25082
25274
|
}
|
|
25083
|
-
lines.push(
|
|
25275
|
+
lines.push(color53.dim("Resume: /sessions or wstack resume <id>"));
|
|
25084
25276
|
return { message: lines.join("\n") };
|
|
25085
25277
|
}
|
|
25086
25278
|
|
|
@@ -25288,11 +25480,15 @@ function buildSecurityCommand(opts) {
|
|
|
25288
25480
|
}
|
|
25289
25481
|
|
|
25290
25482
|
// src/slash-commands/settings.ts
|
|
25291
|
-
import { color as
|
|
25483
|
+
import { color as color56 } from "@wrongstack/core/utils";
|
|
25292
25484
|
|
|
25293
25485
|
// src/slash-commands/settings-mutations.ts
|
|
25294
|
-
import { noOpVault as
|
|
25295
|
-
import {
|
|
25486
|
+
import { noOpVault as noOpVault10 } from "@wrongstack/core/security";
|
|
25487
|
+
import {
|
|
25488
|
+
isReasoningEffort as isReasoningEffort3,
|
|
25489
|
+
REASONING_EFFORT_LEVELS as REASONING_EFFORT_LEVELS3
|
|
25490
|
+
} from "@wrongstack/core/types";
|
|
25491
|
+
import { color as color54, toErrorMessage as toErrorMessage23 } from "@wrongstack/core/utils";
|
|
25296
25492
|
import { getProcessRegistry } from "@wrongstack/tools";
|
|
25297
25493
|
|
|
25298
25494
|
// src/utils/delay-format.ts
|
|
@@ -25355,13 +25551,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25355
25551
|
configStore: opts.configStore,
|
|
25356
25552
|
profileConfigPath: opts.paths.profileConfig(activeProfile),
|
|
25357
25553
|
inProjectConfigPath: opts.paths.inProjectConfig,
|
|
25358
|
-
vault:
|
|
25554
|
+
vault: noOpVault10
|
|
25359
25555
|
};
|
|
25360
25556
|
try {
|
|
25361
25557
|
if (sub === "hq") {
|
|
25362
25558
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25363
25559
|
if (!["on", "off"].includes(raw)) {
|
|
25364
|
-
return { message: `${
|
|
25560
|
+
return { message: `${color54.amber("Usage:")} /settings hq on|off` };
|
|
25365
25561
|
}
|
|
25366
25562
|
const on = raw === "on";
|
|
25367
25563
|
await persistConfigSetting({ ...persistDeps, forceGlobal: true }, (cfg) => {
|
|
@@ -25370,19 +25566,19 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25370
25566
|
cfg.hq = hq;
|
|
25371
25567
|
});
|
|
25372
25568
|
return {
|
|
25373
|
-
message: `${
|
|
25569
|
+
message: `${color54.green("\u2713")} HQ publishing \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
|
|
25374
25570
|
};
|
|
25375
25571
|
}
|
|
25376
25572
|
if (sub === "hq-url") {
|
|
25377
25573
|
const raw = rest.join(" ").trim();
|
|
25378
25574
|
if (!raw)
|
|
25379
|
-
return { message: `${
|
|
25575
|
+
return { message: `${color54.amber("Usage:")} /settings hq-url <http://host:3499>` };
|
|
25380
25576
|
try {
|
|
25381
25577
|
const url = new URL(raw);
|
|
25382
25578
|
if (url.protocol !== "http:" && url.protocol !== "https:")
|
|
25383
25579
|
throw new Error("bad protocol");
|
|
25384
25580
|
} catch {
|
|
25385
|
-
return { message: `${
|
|
25581
|
+
return { message: `${color54.red("Invalid URL")}: ${raw}` };
|
|
25386
25582
|
}
|
|
25387
25583
|
await persistConfigSetting({ ...persistDeps, forceGlobal: true }, (cfg) => {
|
|
25388
25584
|
const hq = cfg.hq ?? {};
|
|
@@ -25390,12 +25586,12 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25390
25586
|
hq.enabled = true;
|
|
25391
25587
|
cfg.hq = hq;
|
|
25392
25588
|
});
|
|
25393
|
-
return { message: `${
|
|
25589
|
+
return { message: `${color54.green("\u2713")} HQ URL \u2192 ${color54.cyan(raw)}` };
|
|
25394
25590
|
}
|
|
25395
25591
|
if (sub === "hq-token") {
|
|
25396
25592
|
const token = rest.join(" ").trim();
|
|
25397
25593
|
if (!token)
|
|
25398
|
-
return { message: `${
|
|
25594
|
+
return { message: `${color54.amber("Usage:")} /settings hq-token <client-token>` };
|
|
25399
25595
|
await persistConfigSetting({ ...persistDeps, forceGlobal: true }, (cfg) => {
|
|
25400
25596
|
const hq = cfg.hq ?? {};
|
|
25401
25597
|
hq.token = token;
|
|
@@ -25403,13 +25599,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25403
25599
|
cfg.hq = hq;
|
|
25404
25600
|
});
|
|
25405
25601
|
return {
|
|
25406
|
-
message: `${
|
|
25602
|
+
message: `${color54.green("\u2713")} HQ token saved ${color54.dim("(active profile config)")}`
|
|
25407
25603
|
};
|
|
25408
25604
|
}
|
|
25409
25605
|
if (sub === "hq-raw") {
|
|
25410
25606
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25411
25607
|
if (!["on", "off"].includes(raw)) {
|
|
25412
|
-
return { message: `${
|
|
25608
|
+
return { message: `${color54.amber("Usage:")} /settings hq-raw on|off` };
|
|
25413
25609
|
}
|
|
25414
25610
|
const on = raw === "on";
|
|
25415
25611
|
await persistConfigSetting({ ...persistDeps, forceGlobal: true }, (cfg) => {
|
|
@@ -25418,56 +25614,56 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25418
25614
|
cfg.hq = hq;
|
|
25419
25615
|
});
|
|
25420
25616
|
return {
|
|
25421
|
-
message: `${
|
|
25617
|
+
message: `${color54.green("\u2713")} HQ raw content \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
|
|
25422
25618
|
};
|
|
25423
25619
|
}
|
|
25424
25620
|
if (sub === "delay") {
|
|
25425
25621
|
const raw = rest[0];
|
|
25426
25622
|
if (raw === void 0) {
|
|
25427
25623
|
return {
|
|
25428
|
-
message: `${
|
|
25624
|
+
message: `${color54.amber("Usage:")} /settings delay <seconds> ${color54.dim("(0 disables)")}`
|
|
25429
25625
|
};
|
|
25430
25626
|
}
|
|
25431
25627
|
const seconds = Number.parseFloat(raw);
|
|
25432
25628
|
if (Number.isNaN(seconds) || seconds < 0) {
|
|
25433
25629
|
return {
|
|
25434
|
-
message: `${
|
|
25630
|
+
message: `${color54.red("Invalid number")}: "${raw}". Enter seconds, e.g. /settings delay 30`
|
|
25435
25631
|
};
|
|
25436
25632
|
}
|
|
25437
25633
|
const ms = Math.round(seconds * 1e3);
|
|
25438
25634
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25439
25635
|
autonomy.autoProceedDelayMs = ms;
|
|
25440
25636
|
});
|
|
25441
|
-
return { message: `${
|
|
25637
|
+
return { message: `${color54.green("\u2713")} auto-proceed delay \u2192 ${formatDelay(ms)}` };
|
|
25442
25638
|
}
|
|
25443
25639
|
if (sub === "mode") {
|
|
25444
25640
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25445
25641
|
const modes = ["off", "suggest", "auto"];
|
|
25446
25642
|
if (!modes.includes(raw)) {
|
|
25447
|
-
return { message: `${
|
|
25643
|
+
return { message: `${color54.amber("Usage:")} /settings mode off|suggest|auto` };
|
|
25448
25644
|
}
|
|
25449
25645
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25450
25646
|
autonomy.defaultMode = raw;
|
|
25451
25647
|
});
|
|
25452
|
-
return { message: `${
|
|
25648
|
+
return { message: `${color54.green("\u2713")} default autonomy \u2192 ${color54.bold(raw)}` };
|
|
25453
25649
|
}
|
|
25454
25650
|
if (sub === "hints") {
|
|
25455
25651
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25456
25652
|
if (!["on", "off"].includes(raw)) {
|
|
25457
|
-
return { message: `${
|
|
25653
|
+
return { message: `${color54.amber("Usage:")} /settings hints on|off` };
|
|
25458
25654
|
}
|
|
25459
25655
|
const on = raw === "on";
|
|
25460
25656
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25461
25657
|
cfg.hints = on;
|
|
25462
25658
|
});
|
|
25463
25659
|
return {
|
|
25464
|
-
message: `${
|
|
25660
|
+
message: `${color54.green("\u2713")} launch hints \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
|
|
25465
25661
|
};
|
|
25466
25662
|
}
|
|
25467
25663
|
if (sub === "debug-stream") {
|
|
25468
25664
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25469
25665
|
if (!["on", "off"].includes(raw)) {
|
|
25470
|
-
return { message: `${
|
|
25666
|
+
return { message: `${color54.amber("Usage:")} /settings debug-stream on|off` };
|
|
25471
25667
|
}
|
|
25472
25668
|
const on = raw === "on";
|
|
25473
25669
|
const { setDebugStreamEnabled } = await import("@wrongstack/providers");
|
|
@@ -25476,24 +25672,24 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25476
25672
|
cfg.debugStream = on;
|
|
25477
25673
|
});
|
|
25478
25674
|
return {
|
|
25479
|
-
message: `${
|
|
25675
|
+
message: `${color54.green("\u2713")} debug stream \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("raw SSE hex-dump to stderr")}`
|
|
25480
25676
|
};
|
|
25481
25677
|
}
|
|
25482
25678
|
if (sub === "config-scope") {
|
|
25483
25679
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25484
25680
|
if (!["global", "project"].includes(raw)) {
|
|
25485
|
-
return { message: `${
|
|
25681
|
+
return { message: `${color54.amber("Usage:")} /settings config-scope global|project` };
|
|
25486
25682
|
}
|
|
25487
25683
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25488
25684
|
cfg.configScope = raw;
|
|
25489
25685
|
});
|
|
25490
|
-
const label = raw === "project" ? `${
|
|
25491
|
-
return { message: `${
|
|
25686
|
+
const label = raw === "project" ? `${color54.cyan("project")} \u2014 settings saved to <project>/.wrongstack/config.json` : `${color54.cyan("global")} \u2014 settings saved to ~/.wrongstack/profiles/${activeProfile}/config.json`;
|
|
25687
|
+
return { message: `${color54.green("\u2713")} config scope \u2192 ${label}` };
|
|
25492
25688
|
}
|
|
25493
25689
|
if (sub === "fs-access") {
|
|
25494
25690
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25495
25691
|
if (!["unrestricted", "project"].includes(raw)) {
|
|
25496
|
-
return { message: `${
|
|
25692
|
+
return { message: `${color54.amber("Usage:")} /settings fs-access unrestricted|project` };
|
|
25497
25693
|
}
|
|
25498
25694
|
const restrict = raw === "project";
|
|
25499
25695
|
const fsAccess = deriveFsAccessPair({ restrictFsToRoot: restrict });
|
|
@@ -25505,15 +25701,15 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25505
25701
|
features.allowOutsideProjectRoot = fsAccess.allowOutsideProjectRoot;
|
|
25506
25702
|
cfg.features = features;
|
|
25507
25703
|
});
|
|
25508
|
-
const label = restrict ? `${
|
|
25704
|
+
const label = restrict ? `${color54.cyan("project")} \u2014 file tools confined to the project root` : `${color54.cyan("unrestricted")} \u2014 file tools may access paths outside the project root`;
|
|
25509
25705
|
return {
|
|
25510
|
-
message: `${
|
|
25706
|
+
message: `${color54.green("\u2713")} filesystem access \u2192 ${label} ${color54.dim("(restart or re-open the session to apply)")}`
|
|
25511
25707
|
};
|
|
25512
25708
|
}
|
|
25513
25709
|
if (sub === "refine") {
|
|
25514
25710
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25515
25711
|
if (!["on", "off"].includes(raw)) {
|
|
25516
|
-
return { message: `${
|
|
25712
|
+
return { message: `${color54.amber("Usage:")} /settings refine on|off` };
|
|
25517
25713
|
}
|
|
25518
25714
|
const on = raw === "on";
|
|
25519
25715
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
@@ -25523,52 +25719,52 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25523
25719
|
opts.enhanceController.setEnabled(on);
|
|
25524
25720
|
}
|
|
25525
25721
|
return {
|
|
25526
|
-
message: `${
|
|
25722
|
+
message: `${color54.green("\u2713")} refine \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim(on ? "prompts will be refined before sending" : "prompts sent verbatim")}`
|
|
25527
25723
|
};
|
|
25528
25724
|
}
|
|
25529
25725
|
if (sub === "refine-delay") {
|
|
25530
25726
|
const raw = rest[0];
|
|
25531
25727
|
if (raw === void 0) {
|
|
25532
|
-
return { message: `${
|
|
25728
|
+
return { message: `${color54.amber("Usage:")} /settings refine-delay <seconds>` };
|
|
25533
25729
|
}
|
|
25534
25730
|
const seconds = Number.parseFloat(raw);
|
|
25535
25731
|
if (Number.isNaN(seconds) || seconds < 0) {
|
|
25536
25732
|
return {
|
|
25537
|
-
message: `${
|
|
25733
|
+
message: `${color54.red("Invalid number")}: "${raw}". Enter seconds, e.g. /settings refine-delay 30`
|
|
25538
25734
|
};
|
|
25539
25735
|
}
|
|
25540
25736
|
const ms = Math.round(seconds * 1e3);
|
|
25541
25737
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25542
25738
|
autonomy.enhanceDelayMs = ms;
|
|
25543
25739
|
});
|
|
25544
|
-
return { message: `${
|
|
25740
|
+
return { message: `${color54.green("\u2713")} refine-delay \u2192 ${formatDelay(ms)}` };
|
|
25545
25741
|
}
|
|
25546
25742
|
if (sub === "refine-language") {
|
|
25547
25743
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25548
25744
|
if (!["original", "english"].includes(raw)) {
|
|
25549
25745
|
return {
|
|
25550
|
-
message: `${
|
|
25746
|
+
message: `${color54.amber("Usage:")} /settings refine-language original|english`
|
|
25551
25747
|
};
|
|
25552
25748
|
}
|
|
25553
25749
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25554
25750
|
autonomy.enhanceLanguage = raw;
|
|
25555
25751
|
});
|
|
25556
|
-
const label = raw === "original" ? `${
|
|
25557
|
-
return { message: `${
|
|
25752
|
+
const label = raw === "original" ? `${color54.cyan("original")} \u2014 use the language you wrote in` : `${color54.cyan("english")} \u2014 translate to English`;
|
|
25753
|
+
return { message: `${color54.green("\u2713")} refine-language \u2192 ${label}` };
|
|
25558
25754
|
}
|
|
25559
25755
|
if (sub === "refiner-provider") {
|
|
25560
25756
|
const raw = rest.join(" ").trim();
|
|
25561
25757
|
const currentProvider = opts.configStore.get().autonomy?.refinerProvider;
|
|
25562
25758
|
if (!raw) {
|
|
25563
25759
|
return {
|
|
25564
|
-
message: `${
|
|
25760
|
+
message: `${color54.amber("Usage:")} /settings refiner-provider <providerId> ${color54.dim('(e.g. "openai", "anthropic")' + (currentProvider ? ` Current: ${currentProvider}` : ""))}`
|
|
25565
25761
|
};
|
|
25566
25762
|
}
|
|
25567
25763
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25568
25764
|
autonomy.refinerProvider = raw;
|
|
25569
25765
|
});
|
|
25570
25766
|
return {
|
|
25571
|
-
message: `${
|
|
25767
|
+
message: `${color54.green("\u2713")} refiner-provider \u2192 ${color54.cyan(raw)} ${color54.dim("goal refinement will use this provider when refiner-model is also set")}`
|
|
25572
25768
|
};
|
|
25573
25769
|
}
|
|
25574
25770
|
if (sub === "refiner-model") {
|
|
@@ -25576,14 +25772,14 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25576
25772
|
const currentModel = opts.configStore.get().autonomy?.refinerModel;
|
|
25577
25773
|
if (!raw) {
|
|
25578
25774
|
return {
|
|
25579
|
-
message: `${
|
|
25775
|
+
message: `${color54.amber("Usage:")} /settings refiner-model <modelId> ${color54.dim('(must be a favorite or the active model; e.g. "gpt-4o-mini")' + (currentModel ? ` Current: ${currentModel}` : ""))}`
|
|
25580
25776
|
};
|
|
25581
25777
|
}
|
|
25582
25778
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25583
25779
|
autonomy.refinerModel = raw;
|
|
25584
25780
|
});
|
|
25585
25781
|
return {
|
|
25586
|
-
message: `${
|
|
25782
|
+
message: `${color54.green("\u2713")} refiner-model \u2192 ${color54.cyan(raw)} ${color54.dim("goal refinement will use this model when it passes favorites/active validation")}`
|
|
25587
25783
|
};
|
|
25588
25784
|
}
|
|
25589
25785
|
if (sub === "refiner-fallback-profile") {
|
|
@@ -25591,14 +25787,14 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25591
25787
|
const currentProfile = opts.configStore.get().autonomy?.refinerFallbackProfile;
|
|
25592
25788
|
if (!raw) {
|
|
25593
25789
|
return {
|
|
25594
|
-
message: `${
|
|
25790
|
+
message: `${color54.amber("Usage:")} /settings refiner-fallback-profile <name> ${color54.dim('(e.g. "default")' + (currentProfile ? ` Current: ${currentProfile}` : ""))}`
|
|
25595
25791
|
};
|
|
25596
25792
|
}
|
|
25597
25793
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25598
25794
|
autonomy.refinerFallbackProfile = raw;
|
|
25599
25795
|
});
|
|
25600
25796
|
return {
|
|
25601
|
-
message: `${
|
|
25797
|
+
message: `${color54.green("\u2713")} refiner-fallback-profile \u2192 ${color54.cyan(raw)} ${color54.dim("goal refinement will use the first valid entry from this profile chain")}`
|
|
25602
25798
|
};
|
|
25603
25799
|
}
|
|
25604
25800
|
if (sub === "refiner-clear") {
|
|
@@ -25608,7 +25804,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25608
25804
|
autonomy.refinerFallbackProfile = void 0;
|
|
25609
25805
|
});
|
|
25610
25806
|
return {
|
|
25611
|
-
message: `${
|
|
25807
|
+
message: `${color54.green("\u2713")} Refiner config cleared ${color54.dim("goal refinement will use the session provider+model")}`
|
|
25612
25808
|
};
|
|
25613
25809
|
}
|
|
25614
25810
|
if (sub === "semver-part") {
|
|
@@ -25616,7 +25812,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25616
25812
|
const parts = ["patch", "minor", "major", "auto"];
|
|
25617
25813
|
if (!parts.includes(raw)) {
|
|
25618
25814
|
return {
|
|
25619
|
-
message: `${
|
|
25815
|
+
message: `${color54.amber("Usage:")} /settings semver-part patch|minor|major|auto`
|
|
25620
25816
|
};
|
|
25621
25817
|
}
|
|
25622
25818
|
await persistConfigSetting({ ...persistDeps, inProjectConfigPath: void 0 }, (cfg) => {
|
|
@@ -25625,13 +25821,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25625
25821
|
cfg.extensions = ext;
|
|
25626
25822
|
});
|
|
25627
25823
|
return {
|
|
25628
|
-
message: `${
|
|
25824
|
+
message: `${color54.green("\u2713")} semver default part \u2192 ${color54.bold(raw)} ${color54.dim("saved to active profile config; used when /semver or semver_bump gets no explicit part")}`
|
|
25629
25825
|
};
|
|
25630
25826
|
}
|
|
25631
25827
|
if (sub === "breaker") {
|
|
25632
25828
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25633
25829
|
if (!["on", "off"].includes(raw)) {
|
|
25634
|
-
return { message: `${
|
|
25830
|
+
return { message: `${color54.amber("Usage:")} /settings breaker on|off` };
|
|
25635
25831
|
}
|
|
25636
25832
|
const on = raw === "on";
|
|
25637
25833
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -25640,20 +25836,20 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25640
25836
|
});
|
|
25641
25837
|
getProcessRegistry().setBreakerConfig({ enabled: on });
|
|
25642
25838
|
return {
|
|
25643
|
-
message: `${
|
|
25839
|
+
message: `${color54.green("\u2713")} circuit breaker \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim(on ? "bash/exec gated on repeated failures; trips arm the kill/reset countdown" : "bash/exec always proceed")}`
|
|
25644
25840
|
};
|
|
25645
25841
|
}
|
|
25646
25842
|
if (sub === "breaker-timeout") {
|
|
25647
25843
|
const raw = rest[0];
|
|
25648
25844
|
if (raw === void 0) {
|
|
25649
25845
|
return {
|
|
25650
|
-
message: `${
|
|
25846
|
+
message: `${color54.amber("Usage:")} /settings breaker-timeout <seconds> ${color54.dim("(0 = manual recovery only)")}`
|
|
25651
25847
|
};
|
|
25652
25848
|
}
|
|
25653
25849
|
const seconds = Number.parseFloat(raw);
|
|
25654
25850
|
if (Number.isNaN(seconds) || seconds < 0) {
|
|
25655
25851
|
return {
|
|
25656
|
-
message: `${
|
|
25852
|
+
message: `${color54.red("Invalid number")}: "${raw}". Enter seconds, e.g. /settings breaker-timeout 60`
|
|
25657
25853
|
};
|
|
25658
25854
|
}
|
|
25659
25855
|
const ms = Math.round(seconds * 1e3);
|
|
@@ -25666,7 +25862,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25666
25862
|
});
|
|
25667
25863
|
getProcessRegistry().setBreakerConfig({ autoKillResetMs: ms });
|
|
25668
25864
|
return {
|
|
25669
|
-
message: `${
|
|
25865
|
+
message: `${color54.green("\u2713")} breaker kill/reset timeout \u2192 ${ms > 0 ? formatDelay(ms) : color54.dim("manual")} ${color54.dim(ms > 0 ? "statusline shows a countdown when the breaker trips" : "breaker trips require /kill reset")}`
|
|
25670
25866
|
};
|
|
25671
25867
|
}
|
|
25672
25868
|
if (sub === "context-mode") {
|
|
@@ -25674,7 +25870,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25674
25870
|
const modes = ["balanced", "frugal", "deep"];
|
|
25675
25871
|
if (!modes.includes(raw)) {
|
|
25676
25872
|
return {
|
|
25677
|
-
message: `${
|
|
25873
|
+
message: `${color54.amber("Usage:")} /settings context-mode balanced|frugal|deep`
|
|
25678
25874
|
};
|
|
25679
25875
|
}
|
|
25680
25876
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -25683,7 +25879,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25683
25879
|
cfg.context = ctx;
|
|
25684
25880
|
});
|
|
25685
25881
|
return {
|
|
25686
|
-
message: `${
|
|
25882
|
+
message: `${color54.green("\u2713")} context mode \u2192 ${color54.cyan(raw)} ${color54.dim("context window policy")}`
|
|
25687
25883
|
};
|
|
25688
25884
|
}
|
|
25689
25885
|
if (sub === "context-strategy") {
|
|
@@ -25691,7 +25887,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25691
25887
|
const strategies = ["hybrid", "intelligent", "selective"];
|
|
25692
25888
|
if (!strategies.includes(raw)) {
|
|
25693
25889
|
return {
|
|
25694
|
-
message: `${
|
|
25890
|
+
message: `${color54.amber("Usage:")} /settings context-strategy hybrid|intelligent|selective`
|
|
25695
25891
|
};
|
|
25696
25892
|
}
|
|
25697
25893
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -25700,13 +25896,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25700
25896
|
cfg.context = ctx;
|
|
25701
25897
|
});
|
|
25702
25898
|
return {
|
|
25703
|
-
message: `${
|
|
25899
|
+
message: `${color54.green("\u2713")} context strategy \u2192 ${color54.cyan(raw)} ${color54.dim("compactor strategy")}`
|
|
25704
25900
|
};
|
|
25705
25901
|
}
|
|
25706
25902
|
if (sub === "context-auto-compact") {
|
|
25707
25903
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25708
25904
|
if (!["on", "off"].includes(raw)) {
|
|
25709
|
-
return { message: `${
|
|
25905
|
+
return { message: `${color54.amber("Usage:")} /settings context-auto-compact on|off` };
|
|
25710
25906
|
}
|
|
25711
25907
|
const on = raw === "on";
|
|
25712
25908
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -25715,13 +25911,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25715
25911
|
cfg.context = ctx;
|
|
25716
25912
|
});
|
|
25717
25913
|
return {
|
|
25718
|
-
message: `${
|
|
25914
|
+
message: `${color54.green("\u2713")} context auto-compact \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("auto-compact context when thresholds crossed")}`
|
|
25719
25915
|
};
|
|
25720
25916
|
}
|
|
25721
25917
|
if (sub === "nextsteps-tool") {
|
|
25722
25918
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25723
25919
|
if (!["on", "off"].includes(raw)) {
|
|
25724
|
-
return { message: `${
|
|
25920
|
+
return { message: `${color54.amber("Usage:")} /settings nextsteps-tool on|off` };
|
|
25725
25921
|
}
|
|
25726
25922
|
const on = raw === "on";
|
|
25727
25923
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -25730,7 +25926,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25730
25926
|
cfg.tools = tools;
|
|
25731
25927
|
});
|
|
25732
25928
|
return {
|
|
25733
|
-
message: `${
|
|
25929
|
+
message: `${color54.green("\u2713")} nextsteps tool \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("takes effect in the next session")}`
|
|
25734
25930
|
};
|
|
25735
25931
|
}
|
|
25736
25932
|
if (sub === "token-saving") {
|
|
@@ -25738,7 +25934,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25738
25934
|
const tiers = ["off", "minimal", "light", "medium", "aggressive"];
|
|
25739
25935
|
if (!tiers.includes(raw)) {
|
|
25740
25936
|
return {
|
|
25741
|
-
message: `${
|
|
25937
|
+
message: `${color54.amber("Usage:")} /settings token-saving off|minimal|light|medium|aggressive`
|
|
25742
25938
|
};
|
|
25743
25939
|
}
|
|
25744
25940
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -25747,47 +25943,47 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25747
25943
|
cfg.features = feat;
|
|
25748
25944
|
});
|
|
25749
25945
|
return {
|
|
25750
|
-
message: `${
|
|
25946
|
+
message: `${color54.green("\u2713")} token-saving \u2192 ${color54.cyan(raw)} ${color54.dim("token-saving mode")}`
|
|
25751
25947
|
};
|
|
25752
25948
|
}
|
|
25753
25949
|
if (sub === "max-concurrent") {
|
|
25754
25950
|
const raw = rest[0];
|
|
25755
25951
|
if (raw === void 0) {
|
|
25756
25952
|
return {
|
|
25757
|
-
message: `${
|
|
25953
|
+
message: `${color54.amber("Usage:")} /settings max-concurrent <n> ${color54.dim("(0 = default)")}`
|
|
25758
25954
|
};
|
|
25759
25955
|
}
|
|
25760
25956
|
const n = Number.parseInt(raw, 10);
|
|
25761
25957
|
if (Number.isNaN(n) || n < 0) {
|
|
25762
25958
|
return {
|
|
25763
|
-
message: `${
|
|
25959
|
+
message: `${color54.red("Invalid number")}: "${raw}". Enter a non-negative integer (0 = default)`
|
|
25764
25960
|
};
|
|
25765
25961
|
}
|
|
25766
25962
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25767
25963
|
cfg.maxConcurrent = n;
|
|
25768
25964
|
});
|
|
25769
25965
|
return {
|
|
25770
|
-
message: `${
|
|
25966
|
+
message: `${color54.green("\u2713")} max-concurrent \u2192 ${color54.cyan(n === 0 ? "default" : String(n))} ${color54.dim("max concurrent subagents")}`
|
|
25771
25967
|
};
|
|
25772
25968
|
}
|
|
25773
25969
|
if (sub === "title-animation") {
|
|
25774
25970
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25775
25971
|
if (!["on", "off"].includes(raw)) {
|
|
25776
|
-
return { message: `${
|
|
25972
|
+
return { message: `${color54.amber("Usage:")} /settings title-animation on|off` };
|
|
25777
25973
|
}
|
|
25778
25974
|
const on = raw === "on";
|
|
25779
25975
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25780
25976
|
autonomy.terminalTitleAnimation = on;
|
|
25781
25977
|
});
|
|
25782
25978
|
return {
|
|
25783
|
-
message: `${
|
|
25979
|
+
message: `${color54.green("\u2713")} title animation \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("terminal title animation")}`
|
|
25784
25980
|
};
|
|
25785
25981
|
}
|
|
25786
25982
|
if (sub === "reasoning") {
|
|
25787
25983
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25788
25984
|
const modes = ["auto", "on", "off"];
|
|
25789
25985
|
if (!modes.includes(raw)) {
|
|
25790
|
-
return { message: `${
|
|
25986
|
+
return { message: `${color54.amber("Usage:")} /settings reasoning auto|on|off` };
|
|
25791
25987
|
}
|
|
25792
25988
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25793
25989
|
const mr = cfg.modelRuntime;
|
|
@@ -25795,14 +25991,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25795
25991
|
reasoning.mode = raw;
|
|
25796
25992
|
cfg.modelRuntime = { ...mr, reasoning };
|
|
25797
25993
|
});
|
|
25798
|
-
return { message: `${
|
|
25994
|
+
return { message: `${color54.green("\u2713")} reasoning mode \u2192 ${color54.bold(raw)}` };
|
|
25799
25995
|
}
|
|
25800
25996
|
if (sub === "reasoning-effort") {
|
|
25801
25997
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25802
|
-
|
|
25803
|
-
if (!efforts.includes(raw)) {
|
|
25998
|
+
if (!isReasoningEffort3(raw)) {
|
|
25804
25999
|
return {
|
|
25805
|
-
message: `${
|
|
26000
|
+
message: `${color54.amber("Usage:")} /settings reasoning-effort ${REASONING_EFFORT_LEVELS3.join("|")}`
|
|
25806
26001
|
};
|
|
25807
26002
|
}
|
|
25808
26003
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -25811,12 +26006,12 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25811
26006
|
reasoning.effort = raw;
|
|
25812
26007
|
cfg.modelRuntime = { ...mr, reasoning };
|
|
25813
26008
|
});
|
|
25814
|
-
return { message: `${
|
|
26009
|
+
return { message: `${color54.green("\u2713")} reasoning effort \u2192 ${color54.bold(raw)}` };
|
|
25815
26010
|
}
|
|
25816
26011
|
if (sub === "reasoning-preserve") {
|
|
25817
26012
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25818
26013
|
if (!["on", "off"].includes(raw)) {
|
|
25819
|
-
return { message: `${
|
|
26014
|
+
return { message: `${color54.amber("Usage:")} /settings reasoning-preserve on|off` };
|
|
25820
26015
|
}
|
|
25821
26016
|
const on = raw === "on";
|
|
25822
26017
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
@@ -25826,24 +26021,24 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25826
26021
|
cfg.modelRuntime = { ...mr, reasoning };
|
|
25827
26022
|
});
|
|
25828
26023
|
return {
|
|
25829
|
-
message: `${
|
|
26024
|
+
message: `${color54.green("\u2713")} reasoning preserve \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
|
|
25830
26025
|
};
|
|
25831
26026
|
}
|
|
25832
26027
|
if (sub === "cache-ttl") {
|
|
25833
26028
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25834
26029
|
if (!["5m", "1h"].includes(raw)) {
|
|
25835
|
-
return { message: `${
|
|
26030
|
+
return { message: `${color54.amber("Usage:")} /settings cache-ttl 5m|1h` };
|
|
25836
26031
|
}
|
|
25837
26032
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25838
26033
|
const mr = cfg.modelRuntime;
|
|
25839
26034
|
cfg.modelRuntime = { ...mr, cache: { ttl: raw } };
|
|
25840
26035
|
});
|
|
25841
|
-
return { message: `${
|
|
26036
|
+
return { message: `${color54.green("\u2713")} cache TTL \u2192 ${color54.bold(raw)}` };
|
|
25842
26037
|
}
|
|
25843
26038
|
if (sub === "mcp") {
|
|
25844
26039
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25845
26040
|
if (!["on", "off"].includes(raw))
|
|
25846
|
-
return { message: `${
|
|
26041
|
+
return { message: `${color54.amber("Usage:")} /settings mcp on|off` };
|
|
25847
26042
|
const on = raw === "on";
|
|
25848
26043
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25849
26044
|
const feats = cfg.features ?? {};
|
|
@@ -25851,13 +26046,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25851
26046
|
cfg.features = feats;
|
|
25852
26047
|
});
|
|
25853
26048
|
return {
|
|
25854
|
-
message: `${
|
|
26049
|
+
message: `${color54.green("\u2713")} MCP features \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("restart to apply")}`
|
|
25855
26050
|
};
|
|
25856
26051
|
}
|
|
25857
26052
|
if (sub === "plugins") {
|
|
25858
26053
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25859
26054
|
if (!["on", "off"].includes(raw))
|
|
25860
|
-
return { message: `${
|
|
26055
|
+
return { message: `${color54.amber("Usage:")} /settings plugins on|off` };
|
|
25861
26056
|
const on = raw === "on";
|
|
25862
26057
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25863
26058
|
const feats = cfg.features ?? {};
|
|
@@ -25865,13 +26060,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25865
26060
|
cfg.features = feats;
|
|
25866
26061
|
});
|
|
25867
26062
|
return {
|
|
25868
|
-
message: `${
|
|
26063
|
+
message: `${color54.green("\u2713")} Plugin features \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("restart to apply")}`
|
|
25869
26064
|
};
|
|
25870
26065
|
}
|
|
25871
26066
|
if (sub === "memory") {
|
|
25872
26067
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25873
26068
|
if (!["on", "off"].includes(raw))
|
|
25874
|
-
return { message: `${
|
|
26069
|
+
return { message: `${color54.amber("Usage:")} /settings memory on|off` };
|
|
25875
26070
|
const on = raw === "on";
|
|
25876
26071
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25877
26072
|
const feats = cfg.features ?? {};
|
|
@@ -25879,13 +26074,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25879
26074
|
cfg.features = feats;
|
|
25880
26075
|
});
|
|
25881
26076
|
return {
|
|
25882
|
-
message: `${
|
|
26077
|
+
message: `${color54.green("\u2713")} Memory features \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("restart to apply")}`
|
|
25883
26078
|
};
|
|
25884
26079
|
}
|
|
25885
26080
|
if (sub === "skills") {
|
|
25886
26081
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25887
26082
|
if (!["on", "off"].includes(raw))
|
|
25888
|
-
return { message: `${
|
|
26083
|
+
return { message: `${color54.amber("Usage:")} /settings skills on|off` };
|
|
25889
26084
|
const on = raw === "on";
|
|
25890
26085
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25891
26086
|
const feats = cfg.features ?? {};
|
|
@@ -25893,13 +26088,13 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25893
26088
|
cfg.features = feats;
|
|
25894
26089
|
});
|
|
25895
26090
|
return {
|
|
25896
|
-
message: `${
|
|
26091
|
+
message: `${color54.green("\u2713")} Skills features \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("restart to apply")}`
|
|
25897
26092
|
};
|
|
25898
26093
|
}
|
|
25899
26094
|
if (sub === "models-registry") {
|
|
25900
26095
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25901
26096
|
if (!["on", "off"].includes(raw))
|
|
25902
|
-
return { message: `${
|
|
26097
|
+
return { message: `${color54.amber("Usage:")} /settings models-registry on|off` };
|
|
25903
26098
|
const on = raw === "on";
|
|
25904
26099
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25905
26100
|
const feats = cfg.features ?? {};
|
|
@@ -25907,7 +26102,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25907
26102
|
cfg.features = feats;
|
|
25908
26103
|
});
|
|
25909
26104
|
return {
|
|
25910
|
-
message: `${
|
|
26105
|
+
message: `${color54.green("\u2713")} Models registry \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("restart to apply")}`
|
|
25911
26106
|
};
|
|
25912
26107
|
}
|
|
25913
26108
|
if (sub === "stream-fleet") {
|
|
@@ -25915,7 +26110,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25915
26110
|
const mode = raw === "on" ? "full" : raw === "off" || raw === "full" ? raw : void 0;
|
|
25916
26111
|
if (!mode)
|
|
25917
26112
|
return {
|
|
25918
|
-
message: `${
|
|
26113
|
+
message: `${color54.amber("Usage:")} /settings stream-fleet off|full (on = full)`
|
|
25919
26114
|
};
|
|
25920
26115
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25921
26116
|
autonomy.fleetChatVerbosity = mode;
|
|
@@ -25923,43 +26118,43 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25923
26118
|
opts.fleetStreamController?.setMode(mode);
|
|
25924
26119
|
const desc = mode === "full" ? "every subagent tool call and message in chat" : "subagent chat lines hidden (F2/F3 stay live)";
|
|
25925
26120
|
return {
|
|
25926
|
-
message: `${
|
|
26121
|
+
message: `${color54.green("\u2713")} fleet chat \u2192 ${color54.cyan(mode)} ${color54.dim(desc)}`
|
|
25927
26122
|
};
|
|
25928
26123
|
}
|
|
25929
26124
|
if (sub === "chime") {
|
|
25930
26125
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25931
26126
|
if (!["on", "off"].includes(raw))
|
|
25932
|
-
return { message: `${
|
|
26127
|
+
return { message: `${color54.amber("Usage:")} /settings chime on|off` };
|
|
25933
26128
|
const on = raw === "on";
|
|
25934
26129
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25935
26130
|
autonomy.chime = on;
|
|
25936
26131
|
});
|
|
25937
26132
|
return {
|
|
25938
|
-
message: `${
|
|
26133
|
+
message: `${color54.green("\u2713")} completion chime \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
|
|
25939
26134
|
};
|
|
25940
26135
|
}
|
|
25941
26136
|
if (sub === "confirm-exit") {
|
|
25942
26137
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25943
26138
|
if (!["on", "off"].includes(raw))
|
|
25944
|
-
return { message: `${
|
|
26139
|
+
return { message: `${color54.amber("Usage:")} /settings confirm-exit on|off` };
|
|
25945
26140
|
const on = raw === "on";
|
|
25946
26141
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25947
26142
|
autonomy.confirmExit = on;
|
|
25948
26143
|
});
|
|
25949
26144
|
return {
|
|
25950
|
-
message: `${
|
|
26145
|
+
message: `${color54.green("\u2713")} confirm before exit \u2192 ${on ? color54.cyan("on") : color54.dim("off")}`
|
|
25951
26146
|
};
|
|
25952
26147
|
}
|
|
25953
26148
|
if (sub === "max-iterations") {
|
|
25954
26149
|
const raw = rest[0];
|
|
25955
26150
|
if (raw === void 0)
|
|
25956
26151
|
return {
|
|
25957
|
-
message: `${
|
|
26152
|
+
message: `${color54.amber("Usage:")} /settings max-iterations <n> ${color54.dim("(0 = default)")}`
|
|
25958
26153
|
};
|
|
25959
26154
|
const n = Number.parseInt(raw, 10);
|
|
25960
26155
|
if (Number.isNaN(n) || n < 0)
|
|
25961
26156
|
return {
|
|
25962
|
-
message: `${
|
|
26157
|
+
message: `${color54.red("Invalid number")}: "${raw}". Enter a non-negative integer.`
|
|
25963
26158
|
};
|
|
25964
26159
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25965
26160
|
const tools = cfg.tools ?? {};
|
|
@@ -25967,31 +26162,31 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25967
26162
|
cfg.tools = tools;
|
|
25968
26163
|
});
|
|
25969
26164
|
return {
|
|
25970
|
-
message: `${
|
|
26165
|
+
message: `${color54.green("\u2713")} max iterations \u2192 ${color54.cyan(n === 0 ? "default" : String(n))} ${color54.dim("agent pauses after this many iterations")}`
|
|
25971
26166
|
};
|
|
25972
26167
|
}
|
|
25973
26168
|
if (sub === "auto-proceed-max-iterations") {
|
|
25974
26169
|
const raw = rest[0];
|
|
25975
26170
|
if (raw === void 0)
|
|
25976
26171
|
return {
|
|
25977
|
-
message: `${
|
|
26172
|
+
message: `${color54.amber("Usage:")} /settings auto-proceed-max-iterations <n> ${color54.dim("(0 = unlimited)")}`
|
|
25978
26173
|
};
|
|
25979
26174
|
const n = Number.parseInt(raw, 10);
|
|
25980
26175
|
if (Number.isNaN(n) || n < 0)
|
|
25981
26176
|
return {
|
|
25982
|
-
message: `${
|
|
26177
|
+
message: `${color54.red("Invalid number")}: "${raw}". Enter a non-negative integer.`
|
|
25983
26178
|
};
|
|
25984
26179
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
25985
26180
|
autonomy.autoProceedMaxIterations = n;
|
|
25986
26181
|
});
|
|
25987
26182
|
return {
|
|
25988
|
-
message: `${
|
|
26183
|
+
message: `${color54.green("\u2713")} auto-proceed max iterations \u2192 ${color54.cyan(n === 0 ? "unlimited" : String(n))}`
|
|
25989
26184
|
};
|
|
25990
26185
|
}
|
|
25991
26186
|
if (sub === "index-on-start") {
|
|
25992
26187
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
25993
26188
|
if (!["on", "off"].includes(raw))
|
|
25994
|
-
return { message: `${
|
|
26189
|
+
return { message: `${color54.amber("Usage:")} /settings index-on-start on|off` };
|
|
25995
26190
|
const on = raw === "on";
|
|
25996
26191
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
25997
26192
|
const idx = cfg.indexing ?? {};
|
|
@@ -25999,7 +26194,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
25999
26194
|
cfg.indexing = idx;
|
|
26000
26195
|
});
|
|
26001
26196
|
return {
|
|
26002
|
-
message: `${
|
|
26197
|
+
message: `${color54.green("\u2713")} index on session start \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim("effective next session")}`
|
|
26003
26198
|
};
|
|
26004
26199
|
}
|
|
26005
26200
|
if (sub === "log-level") {
|
|
@@ -26007,21 +26202,21 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
26007
26202
|
const levels = ["error", "warn", "info", "debug", "trace"];
|
|
26008
26203
|
if (!levels.includes(raw))
|
|
26009
26204
|
return {
|
|
26010
|
-
message: `${
|
|
26205
|
+
message: `${color54.amber("Usage:")} /settings log-level error|warn|info|debug|trace`
|
|
26011
26206
|
};
|
|
26012
26207
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
26013
26208
|
const log = cfg.log ?? {};
|
|
26014
26209
|
log.level = raw;
|
|
26015
26210
|
cfg.log = log;
|
|
26016
26211
|
});
|
|
26017
|
-
return { message: `${
|
|
26212
|
+
return { message: `${color54.green("\u2713")} log level \u2192 ${color54.cyan(raw)}` };
|
|
26018
26213
|
}
|
|
26019
26214
|
if (sub === "audit-level") {
|
|
26020
26215
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
26021
26216
|
const levels = ["minimal", "standard", "full"];
|
|
26022
26217
|
if (!levels.includes(raw))
|
|
26023
26218
|
return {
|
|
26024
|
-
message: `${
|
|
26219
|
+
message: `${color54.amber("Usage:")} /settings audit-level minimal|standard|full`
|
|
26025
26220
|
};
|
|
26026
26221
|
await persistConfigSetting(persistDeps, (cfg) => {
|
|
26027
26222
|
const sess = cfg.session ?? {};
|
|
@@ -26029,38 +26224,38 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
26029
26224
|
cfg.session = sess;
|
|
26030
26225
|
});
|
|
26031
26226
|
return {
|
|
26032
|
-
message: `${
|
|
26227
|
+
message: `${color54.green("\u2713")} audit level \u2192 ${color54.cyan(raw)} ${color54.dim("restart to apply")}`
|
|
26033
26228
|
};
|
|
26034
26229
|
}
|
|
26035
26230
|
if (sub === "thinking-word") {
|
|
26036
26231
|
const raw = rest.join(" ").trim();
|
|
26037
26232
|
if (!raw)
|
|
26038
26233
|
return {
|
|
26039
|
-
message: `${
|
|
26234
|
+
message: `${color54.amber("Usage:")} /settings thinking-word <word> ${color54.dim('single short word, e.g. "thinking", "vibing", "cooking"')}`
|
|
26040
26235
|
};
|
|
26041
26236
|
if (raw.length > 16)
|
|
26042
|
-
return { message: `${
|
|
26237
|
+
return { message: `${color54.red("Word too long")}: max 16 characters.` };
|
|
26043
26238
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
26044
26239
|
autonomy.thinkingWord = raw;
|
|
26045
26240
|
});
|
|
26046
|
-
return { message: `${
|
|
26241
|
+
return { message: `${color54.green("\u2713")} thinking word \u2192 ${color54.cyan(raw)}` };
|
|
26047
26242
|
}
|
|
26048
26243
|
if (sub === "statusline") {
|
|
26049
26244
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
26050
26245
|
const modes = ["minimum", "detailed", "no-color"];
|
|
26051
26246
|
if (!modes.includes(raw))
|
|
26052
26247
|
return {
|
|
26053
|
-
message: `${
|
|
26248
|
+
message: `${color54.amber("Usage:")} /settings statusline minimum|detailed|no-color`
|
|
26054
26249
|
};
|
|
26055
26250
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
26056
26251
|
autonomy.statuslineMode = raw;
|
|
26057
26252
|
});
|
|
26058
|
-
return { message: `${
|
|
26253
|
+
return { message: `${color54.green("\u2713")} statusline mode \u2192 ${color54.cyan(raw)}` };
|
|
26059
26254
|
}
|
|
26060
26255
|
if (sub === "read-symbols") {
|
|
26061
26256
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
26062
26257
|
if (!["on", "off"].includes(raw)) {
|
|
26063
|
-
return { message: `${
|
|
26258
|
+
return { message: `${color54.amber("Usage:")} /settings read-symbols on|off` };
|
|
26064
26259
|
}
|
|
26065
26260
|
const on = raw === "on";
|
|
26066
26261
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
@@ -26070,7 +26265,7 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
26070
26265
|
opts.context.meta["tools.read.advancedMode"] = on;
|
|
26071
26266
|
}
|
|
26072
26267
|
return {
|
|
26073
|
-
message: `${
|
|
26268
|
+
message: `${color54.green("\u2713")} read symbols \u2192 ${on ? color54.cyan("on") : color54.dim("off")} ${color54.dim(on ? "codebase-index symbols will be included in read tool results" : "read tool returns file content only")}`
|
|
26074
26269
|
};
|
|
26075
26270
|
}
|
|
26076
26271
|
if (sub === "animation") {
|
|
@@ -26078,26 +26273,26 @@ async function executeSettingsSubcommand(sub, rest, opts) {
|
|
|
26078
26273
|
const styles = ["rainbow", "wave", "pulse", "dots", "breathe", "cycle"];
|
|
26079
26274
|
if (!styles.includes(raw))
|
|
26080
26275
|
return {
|
|
26081
|
-
message: `${
|
|
26276
|
+
message: `${color54.amber("Usage:")} /settings animation rainbow|wave|pulse|dots|breathe|cycle`
|
|
26082
26277
|
};
|
|
26083
26278
|
await persistAutonomySetting(persistDeps, (autonomy) => {
|
|
26084
26279
|
autonomy.animationStyle = raw;
|
|
26085
26280
|
});
|
|
26086
|
-
return { message: `${
|
|
26281
|
+
return { message: `${color54.green("\u2713")} animation style \u2192 ${color54.cyan(raw)}` };
|
|
26087
26282
|
}
|
|
26088
26283
|
return {
|
|
26089
|
-
message: `${
|
|
26284
|
+
message: `${color54.red("Unknown setting")} "${sub}". ${unknownSubcommand(sub, ALL_SETTINGS_KEYS, "settings")}`
|
|
26090
26285
|
};
|
|
26091
26286
|
} catch (err) {
|
|
26092
26287
|
return {
|
|
26093
|
-
message: `${
|
|
26288
|
+
message: `${color54.red("Settings error")}: ${toErrorMessage23(err)}`
|
|
26094
26289
|
};
|
|
26095
26290
|
}
|
|
26096
26291
|
}
|
|
26097
26292
|
|
|
26098
26293
|
// src/slash-commands/settings-view.ts
|
|
26099
26294
|
import { resolveFleetChatVerbosity } from "@wrongstack/core/types";
|
|
26100
|
-
import { color as
|
|
26295
|
+
import { color as color55 } from "@wrongstack/core/utils";
|
|
26101
26296
|
var SETTINGS_HELP = [
|
|
26102
26297
|
"Usage:",
|
|
26103
26298
|
" /settings Show current settings",
|
|
@@ -26155,16 +26350,16 @@ var SETTINGS_HELP = [
|
|
|
26155
26350
|
].join("\n");
|
|
26156
26351
|
function formatSettingsDefaults() {
|
|
26157
26352
|
return [
|
|
26158
|
-
`${
|
|
26353
|
+
`${color55.bold("Default Values")}`,
|
|
26159
26354
|
"",
|
|
26160
|
-
` auto-proceed delay: ${
|
|
26161
|
-
` default autonomy mode: ${
|
|
26162
|
-
` launch hints: ${
|
|
26163
|
-
` iteration timeout: ${
|
|
26164
|
-
` session timeout: ${
|
|
26165
|
-
` max iterations: ${
|
|
26166
|
-
` max concurrent: ${
|
|
26167
|
-
` semver default part: ${
|
|
26355
|
+
` auto-proceed delay: ${color55.cyan("45s")} ${color55.dim("(WRONGSTACK_AUTO_PROCEED_DELAY_MS env)")}`,
|
|
26356
|
+
` default autonomy mode: ${color55.cyan("off")}`,
|
|
26357
|
+
` launch hints: ${color55.cyan("on")}`,
|
|
26358
|
+
` iteration timeout: ${color55.cyan("5 min")}`,
|
|
26359
|
+
` session timeout: ${color55.cyan("30 min")}`,
|
|
26360
|
+
` max iterations: ${color55.cyan("100")}`,
|
|
26361
|
+
` max concurrent: ${color55.cyan("4")}`,
|
|
26362
|
+
` semver default part: ${color55.cyan("patch")}`
|
|
26168
26363
|
].join("\n");
|
|
26169
26364
|
}
|
|
26170
26365
|
function formatCurrentSettingsView(opts) {
|
|
@@ -26208,56 +26403,56 @@ function formatCurrentSettingsView(opts) {
|
|
|
26208
26403
|
const idx = opts.configStore.get().indexing;
|
|
26209
26404
|
const sess = opts.configStore.get().session;
|
|
26210
26405
|
return [
|
|
26211
|
-
`${
|
|
26406
|
+
`${color55.bold("WrongStack")} ${color55.dim("\u2014 Settings")}`,
|
|
26212
26407
|
"",
|
|
26213
|
-
` auto-proceed delay: ${
|
|
26214
|
-
` default autonomy mode: ${
|
|
26215
|
-
` fleet chat: ${
|
|
26216
|
-
` completion chime: ${au?.chime === true ?
|
|
26217
|
-
` confirm before exit: ${au?.confirmExit !== false ?
|
|
26218
|
-
` launch hints: ${hints ?
|
|
26219
|
-
` debug stream: ${debugStream ?
|
|
26220
|
-
` config scope: ${
|
|
26221
|
-
` filesystem access: ${
|
|
26222
|
-
` refine: ${enhanceEnabled ?
|
|
26223
|
-
` refine-delay: ${
|
|
26224
|
-
` refine-language: ${
|
|
26225
|
-
` refiner-provider: ${
|
|
26226
|
-
` refiner-model: ${
|
|
26227
|
-
` refiner-fallback-profile: ${
|
|
26228
|
-
` semver default part: ${
|
|
26229
|
-
` circuit breaker: ${breakerEnabled ?
|
|
26230
|
-
` context mode: ${
|
|
26231
|
-
` context strategy: ${
|
|
26232
|
-
` context auto-compact: ${contextAutoCompact ?
|
|
26233
|
-
` token-saving: ${
|
|
26234
|
-
` nextsteps tool: ${nextStepsToolEnabled ?
|
|
26235
|
-
` MCP features: ${feats?.mcp !== false ?
|
|
26236
|
-
` plugin features: ${feats?.plugins !== false ?
|
|
26237
|
-
` memory features: ${feats?.memory !== false ?
|
|
26238
|
-
` skills features: ${feats?.skills !== false ?
|
|
26239
|
-
` models registry: ${feats?.modelsRegistry !== false ?
|
|
26240
|
-
` max concurrent: ${
|
|
26241
|
-
` max iterations: ${
|
|
26242
|
-
` auto-proceed max iters: ${
|
|
26243
|
-
` title animation: ${titleAnimation ?
|
|
26244
|
-
` thinking word: ${
|
|
26245
|
-
` statusline mode: ${
|
|
26246
|
-
` animation style: ${
|
|
26247
|
-
` read symbols: ${au?.readAdvancedMode === true ?
|
|
26248
|
-
` reasoning mode: ${
|
|
26249
|
-
` reasoning effort: ${
|
|
26250
|
-
` reasoning preserve: ${reasoningPreserve ?
|
|
26251
|
-
` cache TTL: ${
|
|
26252
|
-
` index on start: ${idx?.onSessionStart !== false ?
|
|
26253
|
-
` log level: ${
|
|
26254
|
-
` audit level: ${
|
|
26255
|
-
` HQ publishing: ${hqEnabled ?
|
|
26256
|
-
` HQ URL: ${
|
|
26257
|
-
` HQ token: ${
|
|
26258
|
-
` HQ raw content: ${hq?.rawContent === true ?
|
|
26408
|
+
` auto-proceed delay: ${color55.cyan(formatDelay(delay))} ${color55.dim("change: /settings delay <seconds>")}`,
|
|
26409
|
+
` default autonomy mode: ${color55.cyan(mode)} ${color55.dim("change: /settings mode off|suggest|auto")}`,
|
|
26410
|
+
` fleet chat: ${color55.cyan(resolveFleetChatVerbosity(au))} ${color55.dim("change: /settings stream-fleet off|full")}`,
|
|
26411
|
+
` completion chime: ${au?.chime === true ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings chime on|off")}`,
|
|
26412
|
+
` confirm before exit: ${au?.confirmExit !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings confirm-exit on|off")}`,
|
|
26413
|
+
` launch hints: ${hints ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings hints on|off")}`,
|
|
26414
|
+
` debug stream: ${debugStream ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings debug-stream on|off")}`,
|
|
26415
|
+
` config scope: ${color55.cyan(configScope)} ${color55.dim("change: /settings config-scope global|project")}`,
|
|
26416
|
+
` filesystem access: ${color55.cyan(fsAccess)} ${color55.dim("change: /settings fs-access unrestricted|project")}`,
|
|
26417
|
+
` refine: ${enhanceEnabled ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings refine on|off")}`,
|
|
26418
|
+
` refine-delay: ${color55.cyan(formatDelay(enhanceDelay))} ${color55.dim("change: /settings refine-delay <seconds>")}`,
|
|
26419
|
+
` refine-language: ${color55.cyan(enhanceLanguage)} ${color55.dim("change: /settings refine-language original|english")}`,
|
|
26420
|
+
` refiner-provider: ${color55.cyan(au?.refinerProvider ?? color55.dim("(unset)"))} ${color55.dim("change: /settings refiner-provider <id>")}`,
|
|
26421
|
+
` refiner-model: ${color55.cyan(au?.refinerModel ?? color55.dim("(unset)"))} ${color55.dim("change: /settings refiner-model <model>")}`,
|
|
26422
|
+
` refiner-fallback-profile: ${color55.cyan(au?.refinerFallbackProfile ?? color55.dim("(unset)"))} ${color55.dim("change: /settings refiner-fallback-profile <name>")}`,
|
|
26423
|
+
` semver default part: ${color55.cyan(semverPart)} ${color55.dim("change: /settings semver-part patch|minor|major|auto")}`,
|
|
26424
|
+
` circuit breaker: ${breakerEnabled ? color55.cyan("on") : color55.dim("off")} (${breakerTimeout > 0 ? formatDelay(breakerTimeout) : color55.dim("manual")}) ${color55.dim("change: /settings breaker on|off")}`,
|
|
26425
|
+
` context mode: ${color55.cyan(contextMode)} ${color55.dim("change: /settings context-mode balanced|frugal|deep")}`,
|
|
26426
|
+
` context strategy: ${color55.cyan(contextStrategy)} ${color55.dim("change: /settings context-strategy hybrid|intelligent|selective")}`,
|
|
26427
|
+
` context auto-compact: ${contextAutoCompact ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings context-auto-compact on|off")}`,
|
|
26428
|
+
` token-saving: ${color55.cyan(tokenSavingTier)} ${color55.dim("change: /settings token-saving off|minimal|light|medium|aggressive")}`,
|
|
26429
|
+
` nextsteps tool: ${nextStepsToolEnabled ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings nextsteps-tool on|off")}`,
|
|
26430
|
+
` MCP features: ${feats?.mcp !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings mcp on|off")}`,
|
|
26431
|
+
` plugin features: ${feats?.plugins !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings plugins on|off")}`,
|
|
26432
|
+
` memory features: ${feats?.memory !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings memory on|off")}`,
|
|
26433
|
+
` skills features: ${feats?.skills !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings skills on|off")}`,
|
|
26434
|
+
` models registry: ${feats?.modelsRegistry !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings models-registry on|off")}`,
|
|
26435
|
+
` max concurrent: ${color55.cyan(maxConcurrent === 0 ? "default" : String(maxConcurrent))} ${color55.dim("change: /settings max-concurrent <n>")}`,
|
|
26436
|
+
` max iterations: ${color55.cyan(String(tools?.maxIterations ?? "default"))} ${color55.dim("change: /settings max-iterations <n>")}`,
|
|
26437
|
+
` auto-proceed max iters: ${color55.cyan(String(au?.autoProceedMaxIterations ?? "unlimited"))} ${color55.dim("change: /settings auto-proceed-max-iterations <n>")}`,
|
|
26438
|
+
` title animation: ${titleAnimation ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings title-animation on|off")}`,
|
|
26439
|
+
` thinking word: ${color55.cyan(au?.thinkingWord ?? "thinking")} ${color55.dim("change: /settings thinking-word <word>")}`,
|
|
26440
|
+
` statusline mode: ${color55.cyan(au?.statuslineMode ?? "minimum")} ${color55.dim("change: /settings statusline minimum|detailed|no-color")}`,
|
|
26441
|
+
` animation style: ${color55.cyan(au?.animationStyle ?? "rainbow")} ${color55.dim("change: /settings animation rainbow|wave|pulse|dots|breathe|cycle")}`,
|
|
26442
|
+
` read symbols: ${au?.readAdvancedMode === true ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings read-symbols on|off")}`,
|
|
26443
|
+
` reasoning mode: ${color55.cyan(reasoningMode)} ${color55.dim("change: /settings reasoning auto|on|off")}`,
|
|
26444
|
+
` reasoning effort: ${color55.cyan(reasoningEffort)} ${color55.dim("change: /settings reasoning-effort <level>")}`,
|
|
26445
|
+
` reasoning preserve: ${reasoningPreserve ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings reasoning-preserve on|off")}`,
|
|
26446
|
+
` cache TTL: ${color55.cyan(cacheTtl)} ${color55.dim("change: /settings cache-ttl 5m|1h")}`,
|
|
26447
|
+
` index on start: ${idx?.onSessionStart !== false ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings index-on-start on|off")}`,
|
|
26448
|
+
` log level: ${color55.cyan(log?.level ?? "info")} ${color55.dim("change: /settings log-level error|warn|info|debug|trace")}`,
|
|
26449
|
+
` audit level: ${color55.cyan(sess?.auditLevel ?? "standard")} ${color55.dim("change: /settings audit-level minimal|standard|full")}`,
|
|
26450
|
+
` HQ publishing: ${hqEnabled ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings hq on|off")}`,
|
|
26451
|
+
` HQ URL: ${color55.cyan(hqUrl)} ${color55.dim("change: /settings hq-url <url>")}`,
|
|
26452
|
+
` HQ token: ${color55.cyan(hqToken)} ${color55.dim("change: /settings hq-token <token>")}`,
|
|
26453
|
+
` HQ raw content: ${hq?.rawContent === true ? color55.cyan("on") : color55.dim("off")} ${color55.dim("change: /settings hq-raw on|off")}`,
|
|
26259
26454
|
"",
|
|
26260
|
-
|
|
26455
|
+
color55.dim(` Persisted to ${persistedTo} \xB7 /settings help for more`)
|
|
26261
26456
|
].join("\n");
|
|
26262
26457
|
}
|
|
26263
26458
|
|
|
@@ -26275,7 +26470,7 @@ function buildSettingsCommand(opts) {
|
|
|
26275
26470
|
return { message: this.help ?? "" };
|
|
26276
26471
|
}
|
|
26277
26472
|
if (!opts.configStore || !opts.paths) {
|
|
26278
|
-
return { message: `${
|
|
26473
|
+
return { message: `${color56.red("Error")} config store not available.` };
|
|
26279
26474
|
}
|
|
26280
26475
|
if (!sub) {
|
|
26281
26476
|
return { message: formatCurrentSettingsView(opts) };
|
|
@@ -26292,7 +26487,7 @@ function buildSettingsCommand(opts) {
|
|
|
26292
26487
|
|
|
26293
26488
|
// src/slash-commands/shadow.ts
|
|
26294
26489
|
import { ToolValidationError as ToolValidationError5 } from "@wrongstack/core/types";
|
|
26295
|
-
import { color as
|
|
26490
|
+
import { color as color57 } from "@wrongstack/core/utils";
|
|
26296
26491
|
var DEFAULT_SHADOW_INTERVAL_MS = 3e4;
|
|
26297
26492
|
var MIN_SHADOW_INTERVAL_MS = 5e3;
|
|
26298
26493
|
function buildShadowCommand(opts) {
|
|
@@ -26362,7 +26557,7 @@ function buildShadowCommand(opts) {
|
|
|
26362
26557
|
if (opts.shadowController?.activeId != null) {
|
|
26363
26558
|
return {
|
|
26364
26559
|
message: [
|
|
26365
|
-
`${
|
|
26560
|
+
`${color57.yellow("\u26A0")} A Shadow Agent is already running (${opts.shadowController.activeId.slice(0, 8)}).`,
|
|
26366
26561
|
"",
|
|
26367
26562
|
"Only one Shadow Agent instance is allowed per session.",
|
|
26368
26563
|
"Use /shadow status to view the current instance."
|
|
@@ -26401,16 +26596,16 @@ function buildShadowCommand(opts) {
|
|
|
26401
26596
|
shadowIntervalMs: intervalMs
|
|
26402
26597
|
});
|
|
26403
26598
|
return {
|
|
26404
|
-
message: `${
|
|
26405
|
-
${
|
|
26406
|
-
${
|
|
26599
|
+
message: `${color57.green("\u2713")} Shadow Agent queued: ${spawnId}
|
|
26600
|
+
${color57.dim("Mode:")} one-shot quiet check
|
|
26601
|
+
${color57.dim("Model:")} ${modelRef.label}`
|
|
26407
26602
|
};
|
|
26408
26603
|
}
|
|
26409
26604
|
case "stop": {
|
|
26410
26605
|
const activeId = opts.shadowController?.activeId;
|
|
26411
26606
|
if (!activeId) {
|
|
26412
26607
|
return {
|
|
26413
|
-
message: `${
|
|
26608
|
+
message: `${color57.yellow("\u26A0")} No active Shadow Agent is registered for this session.`
|
|
26414
26609
|
};
|
|
26415
26610
|
}
|
|
26416
26611
|
if (!opts.onFleetTerminate) {
|
|
@@ -26419,12 +26614,12 @@ ${color56.dim("Model:")} ${modelRef.label}`
|
|
|
26419
26614
|
const ok = await opts.onFleetTerminate(activeId);
|
|
26420
26615
|
if (ok) {
|
|
26421
26616
|
opts.shadowController?.clear();
|
|
26422
|
-
return { message: `${
|
|
26617
|
+
return { message: `${color57.green("\u2713")} Shadow Agent stopped: ${activeId}` };
|
|
26423
26618
|
}
|
|
26424
26619
|
return {
|
|
26425
26620
|
message: [
|
|
26426
|
-
`${
|
|
26427
|
-
`It may already be stopped. Use ${
|
|
26621
|
+
`${color57.red("\u2717")} Failed to stop Shadow Agent ${color57.bold(activeId)}.`,
|
|
26622
|
+
`It may already be stopped. Use ${color57.bold("/shadow status")} to inspect active agents.`
|
|
26428
26623
|
].join("\n")
|
|
26429
26624
|
};
|
|
26430
26625
|
}
|
|
@@ -26452,10 +26647,10 @@ ${color56.dim("Model:")} ${modelRef.label}`
|
|
|
26452
26647
|
opts.shadowController?.clear();
|
|
26453
26648
|
return {
|
|
26454
26649
|
message: [
|
|
26455
|
-
`${
|
|
26650
|
+
`${color57.red("\u26A0")} HOOP: Stopped ${killed} running agent(s)`,
|
|
26456
26651
|
"",
|
|
26457
|
-
`Target: ${
|
|
26458
|
-
`Reason: ${
|
|
26652
|
+
`Target: ${color57.bold("all")}`,
|
|
26653
|
+
`Reason: ${color57.yellow(reason)}`
|
|
26459
26654
|
].join("\n")
|
|
26460
26655
|
};
|
|
26461
26656
|
}
|
|
@@ -26469,10 +26664,10 @@ ${color56.dim("Model:")} ${modelRef.label}`
|
|
|
26469
26664
|
}
|
|
26470
26665
|
return {
|
|
26471
26666
|
message: [
|
|
26472
|
-
ok ? `${
|
|
26667
|
+
ok ? `${color57.red("\u26A0")} HOOP: Stopped agent` : `${color57.red("\u2717")} HOOP: Failed to stop agent`,
|
|
26473
26668
|
"",
|
|
26474
|
-
`Target: ${
|
|
26475
|
-
`Reason: ${
|
|
26669
|
+
`Target: ${color57.bold(targetId)}`,
|
|
26670
|
+
`Reason: ${color57.yellow(reason)}`,
|
|
26476
26671
|
agentInfo ? `
|
|
26477
26672
|
Agent info:
|
|
26478
26673
|
${agentInfo}` : ""
|
|
@@ -26497,7 +26692,7 @@ Current default: ${defaultModelRef.label}`
|
|
|
26497
26692
|
opts.shadowController?.setDefaults?.({ provider: parsed.provider, model: parsed.model });
|
|
26498
26693
|
return {
|
|
26499
26694
|
message: `/shadow model ${parsed.label}
|
|
26500
|
-
${
|
|
26695
|
+
${color57.dim("Model will be applied on next /shadow start")}`
|
|
26501
26696
|
};
|
|
26502
26697
|
}
|
|
26503
26698
|
case "interval": {
|
|
@@ -26517,7 +26712,7 @@ Current default: ${DEFAULT_SHADOW_INTERVAL_MS}ms (30 seconds)`
|
|
|
26517
26712
|
opts.shadowController?.setDefaults?.({ intervalMs: ms });
|
|
26518
26713
|
return {
|
|
26519
26714
|
message: `/shadow interval ${ms}ms
|
|
26520
|
-
${
|
|
26715
|
+
${color57.dim("Interval will be applied on next /shadow start")}`
|
|
26521
26716
|
};
|
|
26522
26717
|
}
|
|
26523
26718
|
default: {
|
|
@@ -26790,7 +26985,7 @@ function buildStatuslineCommand(deps) {
|
|
|
26790
26985
|
}
|
|
26791
26986
|
|
|
26792
26987
|
// src/slash-commands/supervisor.ts
|
|
26793
|
-
import { color as
|
|
26988
|
+
import { color as color58 } from "@wrongstack/core/utils";
|
|
26794
26989
|
function fmtAge4(at) {
|
|
26795
26990
|
const s = Math.max(0, Math.round((Date.now() - at) / 1e3));
|
|
26796
26991
|
if (s < 60) return `${s}s ago`;
|
|
@@ -26826,13 +27021,13 @@ function buildSupervisorCommand(opts) {
|
|
|
26826
27021
|
}
|
|
26827
27022
|
if (sub === "on") {
|
|
26828
27023
|
supervisor.start();
|
|
26829
|
-
const msg2 = `Fleet supervisor ${
|
|
27024
|
+
const msg2 = `Fleet supervisor ${color58.green("armed")} \u2014 evaluating every ${Math.round(supervisor.configSnapshot().intervalMs / 1e3)}s.`;
|
|
26830
27025
|
opts.renderer.write(msg2);
|
|
26831
27026
|
return { message: msg2 };
|
|
26832
27027
|
}
|
|
26833
27028
|
if (sub === "off") {
|
|
26834
27029
|
supervisor.stop();
|
|
26835
|
-
const msg2 = `Fleet supervisor ${
|
|
27030
|
+
const msg2 = `Fleet supervisor ${color58.yellow("disarmed")} \u2014 no further automatic interventions this session.`;
|
|
26836
27031
|
opts.renderer.write(msg2);
|
|
26837
27032
|
return { message: msg2 };
|
|
26838
27033
|
}
|
|
@@ -26845,10 +27040,10 @@ function buildSupervisorCommand(opts) {
|
|
|
26845
27040
|
return { message: msg3 };
|
|
26846
27041
|
}
|
|
26847
27042
|
const lines2 = entries.map((e) => {
|
|
26848
|
-
const who = e.subagentId ? ` ${
|
|
27043
|
+
const who = e.subagentId ? ` ${color58.cyan(e.subagentId)}` : "";
|
|
26849
27044
|
const task = e.taskId ? ` task=${e.taskId.slice(0, 8)}` : "";
|
|
26850
|
-
const outcome = e.outcome === "approved" ?
|
|
26851
|
-
return `${
|
|
27045
|
+
const outcome = e.outcome === "approved" ? color58.green(e.outcome) : e.outcome === "denied" || e.outcome === "error" ? color58.red(e.outcome) : color58.yellow(e.outcome);
|
|
27046
|
+
return `${color58.dim(fmtAge4(e.at))} ${e.kind}${who}${task} \u2192 ${e.proposedAction} [${outcome}] ${color58.dim(e.detail)}`;
|
|
26852
27047
|
});
|
|
26853
27048
|
const msg2 = lines2.join("\n");
|
|
26854
27049
|
opts.renderer.write(msg2);
|
|
@@ -26858,12 +27053,12 @@ function buildSupervisorCommand(opts) {
|
|
|
26858
27053
|
const history = supervisor.history();
|
|
26859
27054
|
const last = history[history.length - 1];
|
|
26860
27055
|
const lines = [
|
|
26861
|
-
`Fleet supervisor: ${supervisor.isRunning() ?
|
|
27056
|
+
`Fleet supervisor: ${supervisor.isRunning() ? color58.green("armed") : color58.yellow("disarmed")}`,
|
|
26862
27057
|
` interval ${Math.round(cfg.intervalMs / 1e3)}s \xB7 cooldown ${Math.round(cfg.cooldownMs / 1e3)}s \xB7 max ${cfg.maxInterventionsPerSubagent} interventions/agent`,
|
|
26863
27058
|
` signals: starvation>${Math.round(cfg.pinnedWaitMs / 1e3)}s \xB7 overload\u2265${cfg.overloadPinnedThreshold} pinned \xB7 backlog>${cfg.backlogFactor}\xD7workers \xB7 stuck>${Math.round(cfg.stuckMs / 1e3)}s \xB7 failstreak\u2265${cfg.failureStreak}`,
|
|
26864
27059
|
` actions: retarget \u2713 \xB7 spawn ${cfg.allowSpawn ? "\u2713" : "\u2717"} \xB7 steer \u2713 \xB7 terminate ${cfg.allowTerminate ? "\u2713" : "\u2717 (config fleet.supervisor.allowTerminate)"}`,
|
|
26865
27060
|
` activity: ${history.length} engagement(s)${last ? ` \u2014 last: ${last.kind} \u2192 ${last.proposedAction} [${last.outcome}] ${fmtAge4(last.at)}` : ""}`,
|
|
26866
|
-
|
|
27061
|
+
color58.dim(" decisions are gated by the Brain \u2014 see /brain (risk ceiling applies)")
|
|
26867
27062
|
];
|
|
26868
27063
|
const msg = lines.join("\n");
|
|
26869
27064
|
opts.renderer.write(msg);
|
|
@@ -27290,21 +27485,21 @@ ${formatTaskProgress(file.tasks)}`;
|
|
|
27290
27485
|
}
|
|
27291
27486
|
|
|
27292
27487
|
// src/slash-commands/techstack.ts
|
|
27293
|
-
import * as
|
|
27488
|
+
import * as fs16 from "node:fs/promises";
|
|
27294
27489
|
import * as path19 from "node:path";
|
|
27295
|
-
import { color as
|
|
27490
|
+
import { color as color59, toErrorMessage as toErrorMessage25 } from "@wrongstack/core/utils";
|
|
27296
27491
|
async function discoverPackageFiles(projectRoot) {
|
|
27297
27492
|
const files = [];
|
|
27298
27493
|
const rootPkg = path19.join(projectRoot, "package.json");
|
|
27299
27494
|
try {
|
|
27300
|
-
await
|
|
27495
|
+
await fs16.access(rootPkg);
|
|
27301
27496
|
files.push(rootPkg);
|
|
27302
27497
|
} catch {
|
|
27303
27498
|
}
|
|
27304
27499
|
const workspaceFile = path19.join(projectRoot, "pnpm-workspace.yaml");
|
|
27305
27500
|
try {
|
|
27306
|
-
await
|
|
27307
|
-
const content = await
|
|
27501
|
+
await fs16.access(workspaceFile);
|
|
27502
|
+
const content = await fs16.readFile(workspaceFile, "utf8");
|
|
27308
27503
|
const globMatch = /packages?:\s*\[([^\]]+)\]/s.exec(content);
|
|
27309
27504
|
const rawGlobs = globMatch?.[1];
|
|
27310
27505
|
if (!rawGlobs) return files;
|
|
@@ -27313,12 +27508,12 @@ async function discoverPackageFiles(projectRoot) {
|
|
|
27313
27508
|
const dirPrefix = g.replace(/\/?\*$/, "").replace(/\/\*$/, "");
|
|
27314
27509
|
const dir = path19.join(projectRoot, dirPrefix);
|
|
27315
27510
|
try {
|
|
27316
|
-
const entries = await
|
|
27511
|
+
const entries = await fs16.readdir(dir, { withFileTypes: true });
|
|
27317
27512
|
for (const e of entries) {
|
|
27318
27513
|
if (!e.isDirectory()) continue;
|
|
27319
27514
|
const subPkg = path19.join(dir, e.name, "package.json");
|
|
27320
27515
|
try {
|
|
27321
|
-
await
|
|
27516
|
+
await fs16.access(subPkg);
|
|
27322
27517
|
files.push(subPkg);
|
|
27323
27518
|
} catch {
|
|
27324
27519
|
}
|
|
@@ -27442,10 +27637,10 @@ function buildTechStackCommand(opts) {
|
|
|
27442
27637
|
" 1. Reads every package.json in the project",
|
|
27443
27638
|
" 2. Looks up latest versions on the npm registry",
|
|
27444
27639
|
" 3. Flags outdated, dead, or obsolete packages",
|
|
27445
|
-
` 4. Writes a ${
|
|
27640
|
+
` 4. Writes a ${color59.cyan("techstack.md")} (or .json) report to the project root`,
|
|
27446
27641
|
"",
|
|
27447
27642
|
"Uses the `tech-stack` skill for version verification rules.",
|
|
27448
|
-
`Hooked into ${
|
|
27643
|
+
`Hooked into ${color59.cyan("/init")} \u2014 runs automatically on first project setup.`
|
|
27449
27644
|
].join("\n"),
|
|
27450
27645
|
async run(args, _ctx) {
|
|
27451
27646
|
const trimmed = args.trim().toLowerCase();
|
|
@@ -27529,12 +27724,12 @@ function buildTechStackCommand(opts) {
|
|
|
27529
27724
|
try {
|
|
27530
27725
|
packageFiles = await discoverPackageFiles(opts.projectRoot);
|
|
27531
27726
|
if (packageFiles.length === 0) {
|
|
27532
|
-
discoveryNote =
|
|
27727
|
+
discoveryNote = color59.amber(
|
|
27533
27728
|
"\u26A0 No package.json files found. This does not look like a Node.js project."
|
|
27534
27729
|
);
|
|
27535
27730
|
}
|
|
27536
27731
|
} catch (err) {
|
|
27537
|
-
discoveryNote =
|
|
27732
|
+
discoveryNote = color59.red(`Could not scan for package files: ${toErrorMessage25(err)}`);
|
|
27538
27733
|
}
|
|
27539
27734
|
const task = buildTechStackTask({
|
|
27540
27735
|
projectRoot: opts.projectRoot,
|
|
@@ -27557,11 +27752,11 @@ function buildTechStackCommand(opts) {
|
|
|
27557
27752
|
};
|
|
27558
27753
|
}
|
|
27559
27754
|
const header = isInit ? "Tech Stack Init Audit" : "Tech Stack Audit";
|
|
27560
|
-
const label = `${
|
|
27755
|
+
const label = `${color59.cyan("\u{1F50D}")} ${color59.bold(header)} ${color59.dim(`(${packageFiles.length} package files)`)}`;
|
|
27561
27756
|
opts.renderer.write(label);
|
|
27562
27757
|
if (discoveryNote) opts.renderer.write(discoveryNote);
|
|
27563
27758
|
opts.renderer.write(
|
|
27564
|
-
|
|
27759
|
+
color59.dim(
|
|
27565
27760
|
`Spawning tech-stack subagent \u2192 writes ${outputFormat === "json" ? "techstack.json" : "techstack.md"} when done.`
|
|
27566
27761
|
)
|
|
27567
27762
|
);
|
|
@@ -27583,10 +27778,10 @@ function buildTechStackCommand(opts) {
|
|
|
27583
27778
|
}
|
|
27584
27779
|
|
|
27585
27780
|
// src/slash-commands/telegram-settings.ts
|
|
27586
|
-
import { color as
|
|
27781
|
+
import { color as color61, toErrorMessage as toErrorMessage26 } from "@wrongstack/core/utils";
|
|
27587
27782
|
|
|
27588
27783
|
// src/slash-commands/telegram-setup.ts
|
|
27589
|
-
import { color as
|
|
27784
|
+
import { color as color60 } from "@wrongstack/core/utils";
|
|
27590
27785
|
|
|
27591
27786
|
// src/slash-commands/telegram-pairing.ts
|
|
27592
27787
|
var DISCOVERY_LIMIT = 25;
|
|
@@ -27702,31 +27897,31 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27702
27897
|
if (BOT_TOKEN_RE.test(first)) {
|
|
27703
27898
|
return {
|
|
27704
27899
|
message: [
|
|
27705
|
-
`${
|
|
27706
|
-
`Run ${
|
|
27900
|
+
`${color60.red("\u2717")} Bot tokens are no longer accepted as slash-command arguments.`,
|
|
27901
|
+
`Run ${color60.cyan("/telegram-setup [chatId]")} and enter it at the masked prompt.`
|
|
27707
27902
|
].join("\n")
|
|
27708
27903
|
};
|
|
27709
27904
|
}
|
|
27710
27905
|
if (parts.length > 1) {
|
|
27711
|
-
return { message: `${
|
|
27906
|
+
return { message: `${color60.amber("Usage:")} /telegram-setup [chatId]` };
|
|
27712
27907
|
}
|
|
27713
27908
|
if (!opts.readSecret || !opts.vault || !opts.paths?.globalConfig) {
|
|
27714
27909
|
return {
|
|
27715
|
-
message: `${
|
|
27910
|
+
message: `${color60.red("\u2717")} Secure Telegram setup is unavailable in this session.`
|
|
27716
27911
|
};
|
|
27717
27912
|
}
|
|
27718
27913
|
let botToken;
|
|
27719
27914
|
try {
|
|
27720
|
-
botToken = (await opts.readSecret(`Telegram bot token ${
|
|
27915
|
+
botToken = (await opts.readSecret(`Telegram bot token ${color60.dim("(hidden, paste OK)")}: `)).trim();
|
|
27721
27916
|
} catch {
|
|
27722
|
-
return { message:
|
|
27917
|
+
return { message: color60.dim("Telegram setup cancelled.") };
|
|
27723
27918
|
}
|
|
27724
|
-
if (!botToken) return { message:
|
|
27919
|
+
if (!botToken) return { message: color60.dim("Telegram setup cancelled.") };
|
|
27725
27920
|
if (!BOT_TOKEN_RE.test(botToken)) {
|
|
27726
27921
|
return {
|
|
27727
27922
|
message: [
|
|
27728
|
-
`${
|
|
27729
|
-
`Expected: ${
|
|
27923
|
+
`${color60.red("\u2717")} Invalid token format.`,
|
|
27924
|
+
`Expected: ${color60.dim("123456789:ABCdefGHIjkl...")}`,
|
|
27730
27925
|
"",
|
|
27731
27926
|
"Get a valid token from @BotFather on Telegram."
|
|
27732
27927
|
].join("\n")
|
|
@@ -27741,7 +27936,7 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27741
27936
|
} catch {
|
|
27742
27937
|
return {
|
|
27743
27938
|
message: [
|
|
27744
|
-
`${
|
|
27939
|
+
`${color60.red("\u2717")} Could not reach Telegram API.`,
|
|
27745
27940
|
"",
|
|
27746
27941
|
"Check your network connection and try again."
|
|
27747
27942
|
].join("\n")
|
|
@@ -27750,7 +27945,7 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27750
27945
|
if (!botInfo.ok || !botInfo.result) {
|
|
27751
27946
|
return {
|
|
27752
27947
|
message: [
|
|
27753
|
-
`${
|
|
27948
|
+
`${color60.red("\u2717")} Invalid bot token.`,
|
|
27754
27949
|
"",
|
|
27755
27950
|
"Get a valid token from @BotFather on Telegram."
|
|
27756
27951
|
].join("\n")
|
|
@@ -27760,13 +27955,13 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27760
27955
|
const classifiedChatId = chatId ? classifyTelegramChatId(chatId) : void 0;
|
|
27761
27956
|
if (classifiedChatId?.kind === "invalid") {
|
|
27762
27957
|
return {
|
|
27763
|
-
message: `${
|
|
27958
|
+
message: `${color60.red("\u2717")} Invalid Telegram chat ID. Expected a positive private chat ID.`
|
|
27764
27959
|
};
|
|
27765
27960
|
}
|
|
27766
27961
|
if (classifiedChatId?.kind === "group") {
|
|
27767
27962
|
return {
|
|
27768
27963
|
message: [
|
|
27769
|
-
`${
|
|
27964
|
+
`${color60.amber("\u26A0")} Shared group, supergroup, and channel IDs cannot be paired by manual ID.`,
|
|
27770
27965
|
"Run /telegram-setup without a chat ID and select a discovered private identity.",
|
|
27771
27966
|
"No configuration was changed."
|
|
27772
27967
|
].join("\n")
|
|
@@ -27780,7 +27975,7 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27780
27975
|
} catch {
|
|
27781
27976
|
return {
|
|
27782
27977
|
message: [
|
|
27783
|
-
`${
|
|
27978
|
+
`${color60.red("\u2717")} Could not discover recent Telegram chats.`,
|
|
27784
27979
|
"Message the bot once, then run /telegram-setup again.",
|
|
27785
27980
|
"No configuration was changed."
|
|
27786
27981
|
].join("\n")
|
|
@@ -27789,7 +27984,7 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27789
27984
|
if (candidates.length === 0) {
|
|
27790
27985
|
return {
|
|
27791
27986
|
message: [
|
|
27792
|
-
`${
|
|
27987
|
+
`${color60.amber("No recent chats found.")}`,
|
|
27793
27988
|
"Message the bot from the private account you want to pair, then run setup again.",
|
|
27794
27989
|
"No configuration was changed."
|
|
27795
27990
|
].join("\n")
|
|
@@ -27797,31 +27992,31 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27797
27992
|
}
|
|
27798
27993
|
opts.renderer.write(
|
|
27799
27994
|
[
|
|
27800
|
-
|
|
27995
|
+
color60.bold("Recent Telegram identities"),
|
|
27801
27996
|
formatTelegramPairingCandidates(candidates),
|
|
27802
27997
|
"",
|
|
27803
|
-
|
|
27998
|
+
color60.dim("Choose a private candidate number, or press Enter to cancel.")
|
|
27804
27999
|
].join("\n")
|
|
27805
28000
|
);
|
|
27806
28001
|
let choiceInput;
|
|
27807
28002
|
try {
|
|
27808
28003
|
choiceInput = opts.readText ? await opts.readText("Pair candidate \u203A ") : await opts.reader.readLine("Pair candidate \u203A ");
|
|
27809
28004
|
} catch {
|
|
27810
|
-
return { message:
|
|
28005
|
+
return { message: color60.dim("Telegram setup cancelled. No configuration was changed.") };
|
|
27811
28006
|
}
|
|
27812
28007
|
const choice = parseTelegramPairingChoice(choiceInput, candidates);
|
|
27813
28008
|
if (choice.kind === "cancel") {
|
|
27814
|
-
return { message:
|
|
28009
|
+
return { message: color60.dim("Telegram setup cancelled. No configuration was changed.") };
|
|
27815
28010
|
}
|
|
27816
28011
|
if (choice.kind === "invalid") {
|
|
27817
28012
|
return {
|
|
27818
|
-
message: `${
|
|
28013
|
+
message: `${color60.red("\u2717")} Invalid pairing choice. No configuration was changed.`
|
|
27819
28014
|
};
|
|
27820
28015
|
}
|
|
27821
28016
|
if (!choice.candidate.eligible) {
|
|
27822
28017
|
return {
|
|
27823
28018
|
message: [
|
|
27824
|
-
`${
|
|
28019
|
+
`${color60.amber("\u26A0")} Shared, group, or ambiguous identities are not paired automatically.`,
|
|
27825
28020
|
"Use a private chat where chat_id and user_id identify the same account.",
|
|
27826
28021
|
"No configuration was changed."
|
|
27827
28022
|
].join("\n")
|
|
@@ -27863,7 +28058,7 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27863
28058
|
} catch {
|
|
27864
28059
|
return {
|
|
27865
28060
|
message: [
|
|
27866
|
-
`${
|
|
28061
|
+
`${color60.red("\u2717")} Failed to save Telegram configuration.`,
|
|
27867
28062
|
"The token was not printed. Check the config path and vault, then try again."
|
|
27868
28063
|
].join("\n")
|
|
27869
28064
|
};
|
|
@@ -27871,15 +28066,15 @@ function buildTelegramSetupCommand(opts) {
|
|
|
27871
28066
|
const bot = botInfo.result;
|
|
27872
28067
|
return {
|
|
27873
28068
|
message: [
|
|
27874
|
-
`${
|
|
28069
|
+
`${color60.green("\u2713")} Telegram configured successfully.`,
|
|
27875
28070
|
"",
|
|
27876
|
-
`Bot: ${
|
|
28071
|
+
`Bot: ${color60.bold(`@${bot.username ?? bot.first_name}`)}`,
|
|
27877
28072
|
...pairedCandidate ? [
|
|
27878
|
-
`Paired private chat: ${
|
|
27879
|
-
`Paired user: ${
|
|
27880
|
-
] : chatId ? [`Default chat: ${
|
|
28073
|
+
`Paired private chat: ${color60.green(String(pairedCandidate.chatId))}`,
|
|
28074
|
+
`Paired user: ${color60.green(String(pairedCandidate.userId))}`
|
|
28075
|
+
] : chatId ? [`Default chat: ${color60.green(chatId)}`] : [],
|
|
27881
28076
|
"",
|
|
27882
|
-
`${
|
|
28077
|
+
`${color60.amber("\u26A0")} Restart WrongStack for the plugin to load the new token.`
|
|
27883
28078
|
].join("\n")
|
|
27884
28079
|
};
|
|
27885
28080
|
}
|
|
@@ -27913,15 +28108,15 @@ function buildTelegramSettingsCommand(opts) {
|
|
|
27913
28108
|
const chat = tg.notifyChatId !== void 0 && tg.notifyChatId !== null ? String(tg.notifyChatId) : "not set";
|
|
27914
28109
|
const hasToken = typeof tg.botToken === "string" && tg.botToken.length > 0;
|
|
27915
28110
|
return [
|
|
27916
|
-
`${
|
|
28111
|
+
`${color61.bold("Telegram")} ${color61.dim("\u2014 Notification Settings")}`,
|
|
27917
28112
|
"",
|
|
27918
|
-
` session end: ${sessionEnd ?
|
|
27919
|
-
` delegate done: ${delegate ?
|
|
27920
|
-
` long tool: ${
|
|
27921
|
-
` poll interval: ${
|
|
27922
|
-
` notify chat: ${
|
|
28113
|
+
` session end: ${sessionEnd ? color61.cyan("on") : color61.dim("off")} ${color61.dim("change: /telegram-settings session-end on|off")}`,
|
|
28114
|
+
` delegate done: ${delegate ? color61.cyan("on") : color61.dim("off")} ${color61.dim("change: /telegram-settings delegate on|off")}`,
|
|
28115
|
+
` long tool: ${color61.cyan(longTool)} ${color61.dim("change: /telegram-settings long-tool <ms|off>")}`,
|
|
28116
|
+
` poll interval: ${color61.cyan(poll)} ${color61.dim("change: /telegram-settings poll <seconds>")}`,
|
|
28117
|
+
` notify chat: ${color61.cyan(chat)} ${color61.dim("change: /telegram-settings chat <chatId>")}`,
|
|
27923
28118
|
"",
|
|
27924
|
-
hasToken ?
|
|
28119
|
+
hasToken ? color61.dim(" Bot token configured. Changes apply immediately.") : `${color61.amber("\u26A0")} No bot token configured. Run: /telegram-setup <botToken> [chatId]`
|
|
27925
28120
|
].join("\n");
|
|
27926
28121
|
}
|
|
27927
28122
|
return {
|
|
@@ -27937,7 +28132,7 @@ function buildTelegramSettingsCommand(opts) {
|
|
|
27937
28132
|
return { message: HELP2 };
|
|
27938
28133
|
}
|
|
27939
28134
|
if (!opts.configStore || !opts.paths?.globalConfig || !opts.vault) {
|
|
27940
|
-
return { message: `${
|
|
28135
|
+
return { message: `${color61.red("Error")} secure config persistence not available.` };
|
|
27941
28136
|
}
|
|
27942
28137
|
if (!sub) {
|
|
27943
28138
|
return { message: currentView() };
|
|
@@ -27951,7 +28146,7 @@ function buildTelegramSettingsCommand(opts) {
|
|
|
27951
28146
|
if (sub === "all") {
|
|
27952
28147
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
27953
28148
|
if (!["on", "off"].includes(raw)) {
|
|
27954
|
-
return { message: `${
|
|
28149
|
+
return { message: `${color61.amber("Usage:")} /telegram-settings all on|off` };
|
|
27955
28150
|
}
|
|
27956
28151
|
const on = raw === "on";
|
|
27957
28152
|
await persistTelegramConfig(persistDeps, (tg) => {
|
|
@@ -27959,40 +28154,40 @@ function buildTelegramSettingsCommand(opts) {
|
|
|
27959
28154
|
tg.notifyOnDelegate = on;
|
|
27960
28155
|
});
|
|
27961
28156
|
return {
|
|
27962
|
-
message: `${
|
|
28157
|
+
message: `${color61.green("\u2713")} all event notifications \u2192 ${on ? color61.cyan("on") : color61.dim("off")} ${color61.dim("(session-end, delegate)")}`
|
|
27963
28158
|
};
|
|
27964
28159
|
}
|
|
27965
28160
|
if (sub === "session-end") {
|
|
27966
28161
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
27967
28162
|
if (!["on", "off"].includes(raw)) {
|
|
27968
|
-
return { message: `${
|
|
28163
|
+
return { message: `${color61.amber("Usage:")} /telegram-settings session-end on|off` };
|
|
27969
28164
|
}
|
|
27970
28165
|
const on = raw === "on";
|
|
27971
28166
|
await persistTelegramConfig(persistDeps, (tg) => {
|
|
27972
28167
|
tg.notifyOnSessionEnd = on;
|
|
27973
28168
|
});
|
|
27974
28169
|
return {
|
|
27975
|
-
message: `${
|
|
28170
|
+
message: `${color61.green("\u2713")} session-end \u2192 ${on ? color61.cyan("on") : color61.dim("off")}`
|
|
27976
28171
|
};
|
|
27977
28172
|
}
|
|
27978
28173
|
if (sub === "delegate") {
|
|
27979
28174
|
const raw = (rest[0] ?? "").toLowerCase();
|
|
27980
28175
|
if (!["on", "off"].includes(raw)) {
|
|
27981
|
-
return { message: `${
|
|
28176
|
+
return { message: `${color61.amber("Usage:")} /telegram-settings delegate on|off` };
|
|
27982
28177
|
}
|
|
27983
28178
|
const on = raw === "on";
|
|
27984
28179
|
await persistTelegramConfig(persistDeps, (tg) => {
|
|
27985
28180
|
tg.notifyOnDelegate = on;
|
|
27986
28181
|
});
|
|
27987
28182
|
return {
|
|
27988
|
-
message: `${
|
|
28183
|
+
message: `${color61.green("\u2713")} delegate \u2192 ${on ? color61.cyan("on") : color61.dim("off")}`
|
|
27989
28184
|
};
|
|
27990
28185
|
}
|
|
27991
28186
|
if (sub === "long-tool") {
|
|
27992
28187
|
const raw = rest[0];
|
|
27993
28188
|
if (raw === void 0) {
|
|
27994
28189
|
return {
|
|
27995
|
-
message: `${
|
|
28190
|
+
message: `${color61.amber("Usage:")} /telegram-settings long-tool <ms|off> ${color61.dim("(0 or off disables)")}`
|
|
27996
28191
|
};
|
|
27997
28192
|
}
|
|
27998
28193
|
if (raw === "off") {
|
|
@@ -28000,57 +28195,57 @@ function buildTelegramSettingsCommand(opts) {
|
|
|
28000
28195
|
tg.longToolThresholdMs = 0;
|
|
28001
28196
|
});
|
|
28002
28197
|
return {
|
|
28003
|
-
message: `${
|
|
28198
|
+
message: `${color61.green("\u2713")} long-tool \u2192 ${color61.dim("off")}`
|
|
28004
28199
|
};
|
|
28005
28200
|
}
|
|
28006
28201
|
const ms = Number.parseInt(raw, 10);
|
|
28007
28202
|
if (Number.isNaN(ms) || ms < 0) {
|
|
28008
28203
|
return {
|
|
28009
|
-
message: `${
|
|
28204
|
+
message: `${color61.red("Invalid number")}: "${raw}". Enter milliseconds, e.g. /telegram-settings long-tool 15000`
|
|
28010
28205
|
};
|
|
28011
28206
|
}
|
|
28012
28207
|
await persistTelegramConfig(persistDeps, (tg) => {
|
|
28013
28208
|
tg.longToolThresholdMs = ms;
|
|
28014
28209
|
});
|
|
28015
28210
|
return {
|
|
28016
|
-
message: `${
|
|
28211
|
+
message: `${color61.green("\u2713")} long-tool \u2192 ${color61.cyan(`${ms}ms`)}`
|
|
28017
28212
|
};
|
|
28018
28213
|
}
|
|
28019
28214
|
if (sub === "poll") {
|
|
28020
28215
|
const raw = rest[0];
|
|
28021
28216
|
if (raw === void 0) {
|
|
28022
28217
|
return {
|
|
28023
|
-
message: `${
|
|
28218
|
+
message: `${color61.amber("Usage:")} /telegram-settings poll <seconds> ${color61.dim("(1\u201360)")}`
|
|
28024
28219
|
};
|
|
28025
28220
|
}
|
|
28026
28221
|
const sec = Number.parseInt(raw, 10);
|
|
28027
28222
|
if (Number.isNaN(sec) || sec < 1 || sec > 60) {
|
|
28028
28223
|
return {
|
|
28029
|
-
message: `${
|
|
28224
|
+
message: `${color61.red("Invalid value")}: "${raw}". Enter seconds between 1 and 60.`
|
|
28030
28225
|
};
|
|
28031
28226
|
}
|
|
28032
28227
|
await persistTelegramConfig(persistDeps, (tg) => {
|
|
28033
28228
|
tg.pollIntervalSec = sec;
|
|
28034
28229
|
});
|
|
28035
28230
|
return {
|
|
28036
|
-
message: `${
|
|
28231
|
+
message: `${color61.green("\u2713")} poll \u2192 ${color61.cyan(`${sec}s`)}`
|
|
28037
28232
|
};
|
|
28038
28233
|
}
|
|
28039
28234
|
if (sub === "chat") {
|
|
28040
28235
|
const raw = rest[0];
|
|
28041
28236
|
if (!raw) {
|
|
28042
|
-
return { message: `${
|
|
28237
|
+
return { message: `${color61.amber("Usage:")} /telegram-settings chat <chatId>` };
|
|
28043
28238
|
}
|
|
28044
28239
|
const classification = classifyTelegramChatId(raw);
|
|
28045
28240
|
if (classification.kind === "invalid") {
|
|
28046
|
-
return { message: `${
|
|
28241
|
+
return { message: `${color61.red("Invalid chat ID")}: expected a non-zero integer.` };
|
|
28047
28242
|
}
|
|
28048
28243
|
const current = opts.configStore.get();
|
|
28049
28244
|
const allowGroupChats = current.extensions?.telegram?.allowGroupChats === true;
|
|
28050
28245
|
if (classification.kind === "group" && !allowGroupChats) {
|
|
28051
28246
|
return {
|
|
28052
28247
|
message: [
|
|
28053
|
-
`${
|
|
28248
|
+
`${color61.amber("\u26A0")} Group, supergroup, and channel targets require explicit allowGroupChats=true.`,
|
|
28054
28249
|
"No configuration was changed."
|
|
28055
28250
|
].join("\n")
|
|
28056
28251
|
};
|
|
@@ -28073,15 +28268,15 @@ function buildTelegramSettingsCommand(opts) {
|
|
|
28073
28268
|
}
|
|
28074
28269
|
});
|
|
28075
28270
|
return {
|
|
28076
|
-
message: `${
|
|
28271
|
+
message: `${color61.green("\u2713")} notify chat \u2192 ${color61.cyan(raw)}`
|
|
28077
28272
|
};
|
|
28078
28273
|
}
|
|
28079
28274
|
return {
|
|
28080
|
-
message: `${
|
|
28275
|
+
message: `${color61.red("Unknown setting")} "${sub}". ${unknownSubcommand(sub, ["session-end", "delegate", "long-tool", "poll", "chat", "all"], "telegram-settings")}`
|
|
28081
28276
|
};
|
|
28082
28277
|
} catch (err) {
|
|
28083
28278
|
return {
|
|
28084
|
-
message: `${
|
|
28279
|
+
message: `${color61.red("Settings error")}: ${toErrorMessage26(err)}`
|
|
28085
28280
|
};
|
|
28086
28281
|
}
|
|
28087
28282
|
}
|
|
@@ -28227,9 +28422,9 @@ function buildTodosCommand(opts) {
|
|
|
28227
28422
|
}
|
|
28228
28423
|
|
|
28229
28424
|
// src/slash-commands/tool.ts
|
|
28230
|
-
import { noOpVault as
|
|
28425
|
+
import { noOpVault as noOpVault11 } from "@wrongstack/core/security";
|
|
28231
28426
|
import {
|
|
28232
|
-
color as
|
|
28427
|
+
color as color62,
|
|
28233
28428
|
getToolDescriptionMode,
|
|
28234
28429
|
getToolResultRenderMode,
|
|
28235
28430
|
normalizeToolDescriptionMode,
|
|
@@ -28243,11 +28438,11 @@ function fit(text, width) {
|
|
|
28243
28438
|
}
|
|
28244
28439
|
function formatDescriptionMode(mode) {
|
|
28245
28440
|
const raw = `desc:${mode}`;
|
|
28246
|
-
return mode === "simple" ?
|
|
28441
|
+
return mode === "simple" ? color62.amber(raw) : color62.cyan(raw);
|
|
28247
28442
|
}
|
|
28248
28443
|
function formatResultRenderMode(mode) {
|
|
28249
28444
|
const raw = `result:${mode}`;
|
|
28250
|
-
return mode === "simple" ?
|
|
28445
|
+
return mode === "simple" ? color62.amber(raw) : color62.cyan(raw);
|
|
28251
28446
|
}
|
|
28252
28447
|
function buildToolCommand(opts) {
|
|
28253
28448
|
const help = [
|
|
@@ -28311,7 +28506,7 @@ function buildToolCommand(opts) {
|
|
|
28311
28506
|
configStore: opts.configStore,
|
|
28312
28507
|
profileConfigPath: activeProfileConfigPath(opts.paths, opts.configStore.get()),
|
|
28313
28508
|
inProjectConfigPath: opts.paths.inProjectConfig,
|
|
28314
|
-
vault:
|
|
28509
|
+
vault: noOpVault11
|
|
28315
28510
|
},
|
|
28316
28511
|
(cfg) => {
|
|
28317
28512
|
cfg.tools = next;
|
|
@@ -28340,7 +28535,7 @@ function buildToolCommand(opts) {
|
|
|
28340
28535
|
configStore: opts.configStore,
|
|
28341
28536
|
profileConfigPath: activeProfileConfigPath(opts.paths, opts.configStore.get()),
|
|
28342
28537
|
inProjectConfigPath: opts.paths.inProjectConfig,
|
|
28343
|
-
vault:
|
|
28538
|
+
vault: noOpVault11
|
|
28344
28539
|
},
|
|
28345
28540
|
(cfg) => {
|
|
28346
28541
|
cfg.tools = nextTools;
|
|
@@ -28353,38 +28548,38 @@ function buildToolCommand(opts) {
|
|
|
28353
28548
|
const resultSimple = Object.entries(configured.resultRenderMode ?? {}).filter(([, mode]) => normalizeToolResultRenderMode(mode) === "simple").map(([name]) => name).sort();
|
|
28354
28549
|
const disabled = opts.toolRegistry.listDisabled();
|
|
28355
28550
|
const lines = [
|
|
28356
|
-
`${
|
|
28551
|
+
`${color62.bold("Tool modes")} ${color62.dim("(default: extend on both axes)")}`,
|
|
28357
28552
|
"",
|
|
28358
|
-
`${formatDescriptionMode("simple")}: ${descSimple.length > 0 ? descSimple.map((n) =>
|
|
28359
|
-
`${formatResultRenderMode("simple")}: ${resultSimple.length > 0 ? resultSimple.map((n) =>
|
|
28553
|
+
`${formatDescriptionMode("simple")}: ${descSimple.length > 0 ? descSimple.map((n) => color62.cyan(n)).join(", ") : color62.dim("none")}`,
|
|
28554
|
+
`${formatResultRenderMode("simple")}: ${resultSimple.length > 0 ? resultSimple.map((n) => color62.cyan(n)).join(", ") : color62.dim("none")}`,
|
|
28360
28555
|
""
|
|
28361
28556
|
];
|
|
28362
28557
|
if (disabled.length > 0) {
|
|
28363
28558
|
lines.push(
|
|
28364
|
-
`${
|
|
28559
|
+
`${color62.bold("Disabled tools")}`,
|
|
28365
28560
|
"",
|
|
28366
|
-
` ${
|
|
28561
|
+
` ${color62.red("disabled")}: ${disabled.map(({ tool }) => color62.dim(tool.name)).join(", ")}`,
|
|
28367
28562
|
""
|
|
28368
28563
|
);
|
|
28369
28564
|
}
|
|
28370
28565
|
lines.push(
|
|
28371
|
-
|
|
28566
|
+
color62.dim(
|
|
28372
28567
|
" /tool <name> desc simple \xB7 /tool <name> result simple \xB7 /tool list \xB7 /tool disable|enable <name>"
|
|
28373
28568
|
)
|
|
28374
28569
|
);
|
|
28375
28570
|
return lines.join("\n");
|
|
28376
28571
|
}
|
|
28377
28572
|
function formatList() {
|
|
28378
|
-
const header = ` ${
|
|
28573
|
+
const header = ` ${color62.dim(fit("tool", 28))} ${color62.dim(fit("owner", 28))} ${color62.dim(fit("status", 10))} ${color62.dim(fit("desc", 14))} ` + color62.dim("result");
|
|
28379
28574
|
const rows = opts.toolRegistry.listWithOwner().map(({ tool }) => {
|
|
28380
28575
|
const descMode = getToolDescriptionMode(opts.toolRegistry, tool.name);
|
|
28381
28576
|
const resultMode = getToolResultRenderMode(opts.toolRegistry, tool.name);
|
|
28382
28577
|
const owner = opts.toolRegistry.ownerOf(tool.name) ?? "core";
|
|
28383
|
-
const status = opts.toolRegistry.isDisabled(tool.name) ?
|
|
28384
|
-
return ` ${fit(tool.name, 28)} ${
|
|
28578
|
+
const status = opts.toolRegistry.isDisabled(tool.name) ? color62.red("disabled") : color62.green("active");
|
|
28579
|
+
return ` ${fit(tool.name, 28)} ${color62.dim(fit(`[${owner}]`, 28))} ${fit(status, 10)} ${fit(formatDescriptionMode(descMode), 14)} ` + formatResultRenderMode(resultMode);
|
|
28385
28580
|
});
|
|
28386
28581
|
return [
|
|
28387
|
-
`${
|
|
28582
|
+
`${color62.bold("Tool modes")} ${color62.dim("(default: extend on both axes)")}`,
|
|
28388
28583
|
"",
|
|
28389
28584
|
header,
|
|
28390
28585
|
...rows
|
|
@@ -28395,55 +28590,55 @@ function buildToolCommand(opts) {
|
|
|
28395
28590
|
const tool = reg.get(name);
|
|
28396
28591
|
if (!tool) {
|
|
28397
28592
|
if (reg.isDisabled(name)) {
|
|
28398
|
-
return `${
|
|
28593
|
+
return `${color62.amber(name)} is disabled. Use ${color62.dim(`/tool enable ${name}`)} to restore.`;
|
|
28399
28594
|
}
|
|
28400
|
-
return `${
|
|
28595
|
+
return `${color62.red("Unknown tool")}: ${name}. Use ${color62.dim("/tools")} to list registered tools.`;
|
|
28401
28596
|
}
|
|
28402
28597
|
const descMode = getToolDescriptionMode(reg, name);
|
|
28403
28598
|
const resultMode = getToolResultRenderMode(reg, name);
|
|
28404
|
-
const status = reg.isDisabled(name) ?
|
|
28599
|
+
const status = reg.isDisabled(name) ? color62.red("disabled") : color62.green("active");
|
|
28405
28600
|
return [
|
|
28406
|
-
`${
|
|
28601
|
+
`${color62.bold(name)} ${status}`,
|
|
28407
28602
|
`description mode: ${formatDescriptionMode(descMode)}`,
|
|
28408
28603
|
`result mode: ${formatResultRenderMode(resultMode)}`,
|
|
28409
28604
|
"",
|
|
28410
|
-
|
|
28605
|
+
color62.dim(tool.description)
|
|
28411
28606
|
].join("\n");
|
|
28412
28607
|
}
|
|
28413
28608
|
async function cmdEnable(name) {
|
|
28414
28609
|
const reg = opts.toolRegistry;
|
|
28415
28610
|
if (!reg.isDisabled(name)) {
|
|
28416
|
-
return `${
|
|
28611
|
+
return `${color62.amber(name)} is not disabled.`;
|
|
28417
28612
|
}
|
|
28418
28613
|
const ok = reg.enable(name);
|
|
28419
|
-
if (!ok) return `${
|
|
28614
|
+
if (!ok) return `${color62.red("Could not enable")}: ${name}.`;
|
|
28420
28615
|
const disabled = currentDisabledSet();
|
|
28421
28616
|
disabled.delete(name);
|
|
28422
28617
|
await persistDisabled(Array.from(disabled));
|
|
28423
|
-
return `${
|
|
28618
|
+
return `${color62.green("\u2713")} ${color62.cyan(name)} re-enabled \u2014 will appear in next provider request.`;
|
|
28424
28619
|
}
|
|
28425
28620
|
async function cmdEnableAll() {
|
|
28426
28621
|
const reg = opts.toolRegistry;
|
|
28427
28622
|
const count = reg.enableAll();
|
|
28428
|
-
if (count === 0) return `${
|
|
28623
|
+
if (count === 0) return `${color62.amber("No disabled tools to re-enable.")}`;
|
|
28429
28624
|
await persistDisabled([]);
|
|
28430
|
-
return `${
|
|
28625
|
+
return `${color62.green("\u2713")} All ${count} disabled tool(s) re-enabled.`;
|
|
28431
28626
|
}
|
|
28432
28627
|
async function cmdDisable(name) {
|
|
28433
28628
|
const reg = opts.toolRegistry;
|
|
28434
28629
|
const tool = reg.get(name);
|
|
28435
28630
|
if (!tool) {
|
|
28436
28631
|
if (reg.isDisabled(name)) {
|
|
28437
|
-
return `${
|
|
28632
|
+
return `${color62.amber(name)} is already disabled.`;
|
|
28438
28633
|
}
|
|
28439
|
-
return `${
|
|
28634
|
+
return `${color62.red("Unknown tool")}: ${name}. Use ${color62.dim("/tools")} to list registered tools.`;
|
|
28440
28635
|
}
|
|
28441
28636
|
const ok = reg.disable(name);
|
|
28442
|
-
if (!ok) return `${
|
|
28637
|
+
if (!ok) return `${color62.red("Could not disable")}: ${name}.`;
|
|
28443
28638
|
const disabled = currentDisabledSet();
|
|
28444
28639
|
disabled.add(name);
|
|
28445
28640
|
await persistDisabled(Array.from(disabled));
|
|
28446
|
-
return `${
|
|
28641
|
+
return `${color62.green("\u2713")} ${color62.cyan(name)} disabled \u2014 removed from system prompt and tool registry.`;
|
|
28447
28642
|
}
|
|
28448
28643
|
function applyDescMode(name, mode) {
|
|
28449
28644
|
opts.toolRegistry.setDescriptionMode?.(name, mode);
|
|
@@ -28459,7 +28654,7 @@ function buildToolCommand(opts) {
|
|
|
28459
28654
|
help,
|
|
28460
28655
|
async run(args) {
|
|
28461
28656
|
if (!opts.configStore) {
|
|
28462
|
-
return { message: `${
|
|
28657
|
+
return { message: `${color62.red("Error")} config store not available.` };
|
|
28463
28658
|
}
|
|
28464
28659
|
const parts = args.trim().split(/\s+/).filter(Boolean);
|
|
28465
28660
|
const sub = (parts[0] ?? "").toLowerCase();
|
|
@@ -28470,7 +28665,7 @@ function buildToolCommand(opts) {
|
|
|
28470
28665
|
try {
|
|
28471
28666
|
return { message: await cmdEnableAll() };
|
|
28472
28667
|
} catch (err) {
|
|
28473
|
-
return { message: `${
|
|
28668
|
+
return { message: `${color62.red("Error")}: ${toErrorMessage27(err)}` };
|
|
28474
28669
|
}
|
|
28475
28670
|
}
|
|
28476
28671
|
const name = parts[0] ?? "";
|
|
@@ -28478,43 +28673,43 @@ function buildToolCommand(opts) {
|
|
|
28478
28673
|
if (sub === "disable") {
|
|
28479
28674
|
const targets = parts.slice(1);
|
|
28480
28675
|
if (targets.length === 0)
|
|
28481
|
-
return { message: `${
|
|
28676
|
+
return { message: `${color62.amber("Usage:")} /tool disable <name> [name...]` };
|
|
28482
28677
|
try {
|
|
28483
28678
|
const results = [];
|
|
28484
28679
|
for (const t of targets) results.push(await cmdDisable(t));
|
|
28485
28680
|
return { message: results.join("\n") };
|
|
28486
28681
|
} catch (err) {
|
|
28487
|
-
return { message: `${
|
|
28682
|
+
return { message: `${color62.red("Error")}: ${toErrorMessage27(err)}` };
|
|
28488
28683
|
}
|
|
28489
28684
|
}
|
|
28490
28685
|
if (sub === "enable") {
|
|
28491
28686
|
const targets = parts.slice(1);
|
|
28492
28687
|
if (targets.length === 0)
|
|
28493
|
-
return { message: `${
|
|
28688
|
+
return { message: `${color62.amber("Usage:")} /tool enable <name> [name...]` };
|
|
28494
28689
|
try {
|
|
28495
28690
|
const results = [];
|
|
28496
28691
|
for (const t of targets) results.push(await cmdEnable(t));
|
|
28497
28692
|
return { message: results.join("\n") };
|
|
28498
28693
|
} catch (err) {
|
|
28499
|
-
return { message: `${
|
|
28694
|
+
return { message: `${color62.red("Error")}: ${toErrorMessage27(err)}` };
|
|
28500
28695
|
}
|
|
28501
28696
|
}
|
|
28502
28697
|
const action = parts[1]?.toLowerCase();
|
|
28503
28698
|
if (action === "disable" || action === "enable") {
|
|
28504
28699
|
if (parts.length > 2) {
|
|
28505
28700
|
return {
|
|
28506
|
-
message: `${
|
|
28701
|
+
message: `${color62.amber("Usage:")} /tool ${name} ${action}`
|
|
28507
28702
|
};
|
|
28508
28703
|
}
|
|
28509
28704
|
try {
|
|
28510
28705
|
return { message: action === "disable" ? await cmdDisable(name) : await cmdEnable(name) };
|
|
28511
28706
|
} catch (err) {
|
|
28512
|
-
return { message: `${
|
|
28707
|
+
return { message: `${color62.red("Error")}: ${toErrorMessage27(err)}` };
|
|
28513
28708
|
}
|
|
28514
28709
|
}
|
|
28515
28710
|
if (!opts.toolRegistry.get(name) && !opts.toolRegistry.isDisabled(name)) {
|
|
28516
28711
|
return {
|
|
28517
|
-
message: `${
|
|
28712
|
+
message: `${color62.red("Unknown tool")}: ${name}. Use ${color62.dim("/tools")} to list registered tools.`
|
|
28518
28713
|
};
|
|
28519
28714
|
}
|
|
28520
28715
|
if (parts.length === 1) return { message: formatOne(name) };
|
|
@@ -28523,53 +28718,53 @@ function buildToolCommand(opts) {
|
|
|
28523
28718
|
const rawMode = parts[2];
|
|
28524
28719
|
if (!rawMode) {
|
|
28525
28720
|
return {
|
|
28526
|
-
message: `${
|
|
28721
|
+
message: `${color62.amber("Usage:")} /tool ${name} ${axis} simple|extend`
|
|
28527
28722
|
};
|
|
28528
28723
|
}
|
|
28529
28724
|
const mode2 = normalizeToolDescriptionMode(rawMode);
|
|
28530
28725
|
if (!mode2) {
|
|
28531
28726
|
return {
|
|
28532
|
-
message: `${
|
|
28727
|
+
message: `${color62.amber("Usage:")} /tool ${name} ${axis} simple|extend`
|
|
28533
28728
|
};
|
|
28534
28729
|
}
|
|
28535
28730
|
try {
|
|
28536
28731
|
if (axis === "desc") {
|
|
28537
28732
|
const persisted2 = await persistModeForAxis(name, "desc", mode2);
|
|
28538
28733
|
applyDescMode(name, mode2);
|
|
28539
|
-
const persistence2 = persisted2 ?
|
|
28734
|
+
const persistence2 = persisted2 ? color62.dim("saved") : color62.dim("runtime only; config paths unavailable");
|
|
28540
28735
|
return {
|
|
28541
|
-
message: `${
|
|
28736
|
+
message: `${color62.green("\u2713")} ${color62.cyan(name)} ${formatDescriptionMode(mode2)} ${persistence2}`
|
|
28542
28737
|
};
|
|
28543
28738
|
}
|
|
28544
28739
|
const persisted = await persistModeForAxis(name, "result", mode2);
|
|
28545
28740
|
applyResultMode(name, mode2);
|
|
28546
|
-
const persistence = persisted ?
|
|
28741
|
+
const persistence = persisted ? color62.dim("saved") : color62.dim("runtime only; config paths unavailable");
|
|
28547
28742
|
return {
|
|
28548
|
-
message: `${
|
|
28743
|
+
message: `${color62.green("\u2713")} ${color62.cyan(name)} ${formatResultRenderMode(mode2)} ${persistence}`
|
|
28549
28744
|
};
|
|
28550
28745
|
} catch (err) {
|
|
28551
28746
|
return {
|
|
28552
|
-
message: `${
|
|
28747
|
+
message: `${color62.red("Could not save tool setting")}: ${toErrorMessage27(err)}`
|
|
28553
28748
|
};
|
|
28554
28749
|
}
|
|
28555
28750
|
}
|
|
28556
28751
|
const mode = normalizeToolDescriptionMode(axis);
|
|
28557
28752
|
if (!mode) {
|
|
28558
28753
|
return {
|
|
28559
|
-
message: `${
|
|
28754
|
+
message: `${color62.amber("Usage:")} /tool ${name} [desc|result] simple|extend`
|
|
28560
28755
|
};
|
|
28561
28756
|
}
|
|
28562
28757
|
try {
|
|
28563
28758
|
const persisted = await persistModeBoth(name, mode);
|
|
28564
28759
|
applyDescMode(name, mode);
|
|
28565
28760
|
applyResultMode(name, mode);
|
|
28566
|
-
const persistence = persisted ?
|
|
28761
|
+
const persistence = persisted ? color62.dim("saved (both axes)") : color62.dim("runtime only; config paths unavailable");
|
|
28567
28762
|
return {
|
|
28568
|
-
message: `${
|
|
28763
|
+
message: `${color62.green("\u2713")} ${color62.cyan(name)} ${formatDescriptionMode(mode)} + ${formatResultRenderMode(mode)} ${persistence}`
|
|
28569
28764
|
};
|
|
28570
28765
|
} catch (err) {
|
|
28571
28766
|
return {
|
|
28572
|
-
message: `${
|
|
28767
|
+
message: `${color62.red("Could not save tool setting")}: ${toErrorMessage27(err)}`
|
|
28573
28768
|
};
|
|
28574
28769
|
}
|
|
28575
28770
|
}
|
|
@@ -28577,14 +28772,14 @@ function buildToolCommand(opts) {
|
|
|
28577
28772
|
}
|
|
28578
28773
|
|
|
28579
28774
|
// src/slash-commands/tools.ts
|
|
28580
|
-
import { color as
|
|
28775
|
+
import { color as color63, getToolDescriptionMode as getToolDescriptionMode2 } from "@wrongstack/core/utils";
|
|
28581
28776
|
function fit2(text, width) {
|
|
28582
28777
|
if (text.length <= width) return text.padEnd(width);
|
|
28583
28778
|
return `${text.slice(0, Math.max(0, width - 3))}...`;
|
|
28584
28779
|
}
|
|
28585
28780
|
function formatDescriptionMode2(mode) {
|
|
28586
28781
|
const raw = `desc:${mode}`;
|
|
28587
|
-
return mode === "simple" ?
|
|
28782
|
+
return mode === "simple" ? color63.amber(raw) : color63.dim(raw);
|
|
28588
28783
|
}
|
|
28589
28784
|
function buildToolsCommand(opts) {
|
|
28590
28785
|
return {
|
|
@@ -28605,21 +28800,21 @@ function buildToolsCommand(opts) {
|
|
|
28605
28800
|
if (opened) return { message: "" };
|
|
28606
28801
|
}
|
|
28607
28802
|
if (filter && all.length === 0) {
|
|
28608
|
-
const msg2 = `${
|
|
28803
|
+
const msg2 = `${color63.bold("Tools")} \u2014 no tool name or owner matched "${filter}".`;
|
|
28609
28804
|
opts.renderer.write(msg2);
|
|
28610
28805
|
return { message: msg2 };
|
|
28611
28806
|
}
|
|
28612
|
-
const header = ` ${
|
|
28807
|
+
const header = ` ${color63.dim(fit2("tool", 28))} ${color63.dim(fit2("owner", 28))} ${color63.dim(fit2("rw", 4))} ${color63.dim(fit2("perm", 8))} ${color63.dim(fit2("status", 10))} ` + color63.dim("description");
|
|
28613
28808
|
const lines = all.map(({ tool, owner }) => {
|
|
28614
28809
|
const mode = getToolDescriptionMode2(reg, tool.name);
|
|
28615
|
-
const rw = tool.mutating ?
|
|
28616
|
-
const status = reg.isDisabled(tool.name) ?
|
|
28617
|
-
return ` ${fit2(tool.name, 28)} ${
|
|
28810
|
+
const rw = tool.mutating ? color63.yellow(fit2("mut", 4)) : color63.cyan(fit2("ro", 4));
|
|
28811
|
+
const status = reg.isDisabled(tool.name) ? color63.red("disabled") : color63.green("active");
|
|
28812
|
+
return ` ${fit2(tool.name, 28)} ${color63.dim(fit2(`[${owner}]`, 28))} ${rw} ${color63.dim(fit2(tool.permission, 8))} ${fit2(status, 10)} ` + formatDescriptionMode2(mode);
|
|
28618
28813
|
});
|
|
28619
28814
|
const extra = disabled.length > 0 ? `
|
|
28620
|
-
${
|
|
28621
|
-
const filterNote = filter ?
|
|
28622
|
-
const msg = `${
|
|
28815
|
+
${color63.dim(`${disabled.length} tool(s) disabled. Use /tool enable <name> or /tool enable-all to restore.`)}` : "";
|
|
28816
|
+
const filterNote = filter ? color63.dim(` matching "${filter}" (${all.length} of ${allTools.length})`) : "";
|
|
28817
|
+
const msg = `${color63.bold("Tools")}${filterNote} (${all.length} shown, ${disabled.length} disabled) ${color63.dim("description detail via /tool <name> simple|extend")}:
|
|
28623
28818
|
${header}
|
|
28624
28819
|
${lines.join("\n")}${extra}
|
|
28625
28820
|
`;
|
|
@@ -28630,10 +28825,10 @@ ${lines.join("\n")}${extra}
|
|
|
28630
28825
|
}
|
|
28631
28826
|
|
|
28632
28827
|
// src/slash-commands/tuneup.ts
|
|
28633
|
-
import * as
|
|
28828
|
+
import * as fs17 from "node:fs/promises";
|
|
28634
28829
|
import * as os3 from "node:os";
|
|
28635
28830
|
import * as path20 from "node:path";
|
|
28636
|
-
import { atomicWrite as
|
|
28831
|
+
import { atomicWrite as atomicWrite10, color as color64 } from "@wrongstack/core/utils";
|
|
28637
28832
|
|
|
28638
28833
|
// src/tuneup.ts
|
|
28639
28834
|
var DEFAULT_EAGER_MAX_CHARS = 24e3;
|
|
@@ -29111,17 +29306,17 @@ function buildTuneupCommand(opts) {
|
|
|
29111
29306
|
const parsed = parseArgs(args);
|
|
29112
29307
|
if (parsed.mode === "help") return { message: help };
|
|
29113
29308
|
if (parsed.mode === "usage") {
|
|
29114
|
-
return { message: `${
|
|
29309
|
+
return { message: `${color64.amber("Usage:")} /tuneup [fix [--power] [--pick] | deep]` };
|
|
29115
29310
|
}
|
|
29116
29311
|
if (!opts.paths) {
|
|
29117
|
-
return { message: `${
|
|
29312
|
+
return { message: `${color64.red("Error")} config paths not available.` };
|
|
29118
29313
|
}
|
|
29119
29314
|
const input = await gatherInput(opts, parsed.power);
|
|
29120
29315
|
const report = runTuneup(input);
|
|
29121
|
-
const lines = [`${
|
|
29316
|
+
const lines = [`${color64.bold("WrongStack")} ${color64.dim("\u2014 Tune-up")}`];
|
|
29122
29317
|
renderFindings(lines, report.findings);
|
|
29123
29318
|
if (parsed.mode === "deep") {
|
|
29124
|
-
lines.push("",
|
|
29319
|
+
lines.push("", color64.dim(" \u2192 asking the agent for a project-specific optimization plan\u2026"));
|
|
29125
29320
|
return { message: lines.join("\n"), runText: buildDeepPrompt(report) };
|
|
29126
29321
|
}
|
|
29127
29322
|
if (parsed.mode === "report") {
|
|
@@ -29143,18 +29338,18 @@ function buildTuneupCommand(opts) {
|
|
|
29143
29338
|
const applied = await applyActions(actions, opts);
|
|
29144
29339
|
lines.push("");
|
|
29145
29340
|
if (applied.messages.length === 0) {
|
|
29146
|
-
lines.push(
|
|
29341
|
+
lines.push(color64.dim(" no deterministic fixes to apply"));
|
|
29147
29342
|
} else {
|
|
29148
|
-
for (const m of applied.messages) lines.push(` ${
|
|
29343
|
+
for (const m of applied.messages) lines.push(` ${color64.green("\u2713")} ${m}`);
|
|
29149
29344
|
if (applied.changed) {
|
|
29150
29345
|
lines.push(
|
|
29151
|
-
` ${
|
|
29346
|
+
` ${color64.green("\u2713")} written ${color64.dim("(backup: config.json.last + timestamped .bak)")}`
|
|
29152
29347
|
);
|
|
29153
29348
|
}
|
|
29154
29349
|
}
|
|
29155
29350
|
const runText = report.agentHandoff || void 0;
|
|
29156
29351
|
if (runText) {
|
|
29157
|
-
lines.push("",
|
|
29352
|
+
lines.push("", color64.dim(" \u2192 handing instruction-file cleanups to the agent\u2026"));
|
|
29158
29353
|
}
|
|
29159
29354
|
return { message: lines.join("\n"), ...runText ? { runText } : {} };
|
|
29160
29355
|
}
|
|
@@ -29240,7 +29435,7 @@ async function gatherMemoryFiles(opts) {
|
|
|
29240
29435
|
const out = [];
|
|
29241
29436
|
for (const c of candidates) {
|
|
29242
29437
|
try {
|
|
29243
|
-
const content = await
|
|
29438
|
+
const content = await fs17.readFile(c.file, "utf8");
|
|
29244
29439
|
out.push({ label: c.label, path: c.file, content, committed: c.committed });
|
|
29245
29440
|
} catch {
|
|
29246
29441
|
}
|
|
@@ -29258,7 +29453,7 @@ async function gatherTrust(opts) {
|
|
|
29258
29453
|
const file = opts.paths?.projectTrust;
|
|
29259
29454
|
if (!file) return void 0;
|
|
29260
29455
|
try {
|
|
29261
|
-
const raw = await
|
|
29456
|
+
const raw = await fs17.readFile(file, "utf8");
|
|
29262
29457
|
const parsed = JSON.parse(raw);
|
|
29263
29458
|
if (parsed && typeof parsed === "object") return parsed;
|
|
29264
29459
|
} catch {
|
|
@@ -29269,7 +29464,7 @@ async function gatherConfigIssues(opts) {
|
|
|
29269
29464
|
if (!opts.paths) return 0;
|
|
29270
29465
|
const file = activeProfileConfigPath(opts.paths, opts.configStore.get());
|
|
29271
29466
|
try {
|
|
29272
|
-
const raw = await
|
|
29467
|
+
const raw = await fs17.readFile(file, "utf8");
|
|
29273
29468
|
const parsed = JSON.parse(raw);
|
|
29274
29469
|
return diagnoseConfig(parsed).findings.length;
|
|
29275
29470
|
} catch {
|
|
@@ -29287,14 +29482,14 @@ async function gatherSessionBytes(opts) {
|
|
|
29287
29482
|
}
|
|
29288
29483
|
async function dirSize(dir) {
|
|
29289
29484
|
let total = 0;
|
|
29290
|
-
const entries = await
|
|
29485
|
+
const entries = await fs17.readdir(dir, { withFileTypes: true });
|
|
29291
29486
|
for (const e of entries) {
|
|
29292
29487
|
const full = path20.join(dir, e.name);
|
|
29293
29488
|
if (e.isDirectory()) {
|
|
29294
29489
|
total += await dirSize(full);
|
|
29295
29490
|
} else if (e.isFile()) {
|
|
29296
29491
|
try {
|
|
29297
|
-
total += (await
|
|
29492
|
+
total += (await fs17.stat(full)).size;
|
|
29298
29493
|
} catch {
|
|
29299
29494
|
}
|
|
29300
29495
|
}
|
|
@@ -29307,7 +29502,7 @@ async function applyActions(actions, opts) {
|
|
|
29307
29502
|
const file = activeProfileConfigPath(opts.paths, opts.configStore.get());
|
|
29308
29503
|
let raw = "{}";
|
|
29309
29504
|
try {
|
|
29310
|
-
raw = await
|
|
29505
|
+
raw = await fs17.readFile(file, "utf8");
|
|
29311
29506
|
} catch {
|
|
29312
29507
|
}
|
|
29313
29508
|
let parsed;
|
|
@@ -29315,7 +29510,7 @@ async function applyActions(actions, opts) {
|
|
|
29315
29510
|
parsed = JSON.parse(raw);
|
|
29316
29511
|
} catch {
|
|
29317
29512
|
return {
|
|
29318
|
-
messages: [`${
|
|
29513
|
+
messages: [`${color64.red("\u2717")} global config is not valid JSON \u2014 run /doctor fix first`],
|
|
29319
29514
|
changed: false
|
|
29320
29515
|
};
|
|
29321
29516
|
}
|
|
@@ -29353,11 +29548,11 @@ async function applyActions(actions, opts) {
|
|
|
29353
29548
|
const changed = JSON.stringify(parsed) !== before;
|
|
29354
29549
|
if (!changed) return { messages, changed: false };
|
|
29355
29550
|
try {
|
|
29356
|
-
await
|
|
29357
|
-
await
|
|
29551
|
+
await atomicWrite10(`${file}.last`, raw);
|
|
29552
|
+
await atomicWrite10(`${file}.${Date.now()}.bak`, raw);
|
|
29358
29553
|
} catch {
|
|
29359
29554
|
}
|
|
29360
|
-
await
|
|
29555
|
+
await atomicWrite10(file, JSON.stringify(parsed, null, 2));
|
|
29361
29556
|
try {
|
|
29362
29557
|
const homeFn = () => path20.dirname(path20.dirname(file));
|
|
29363
29558
|
await appendHistory(JSON.parse(raw), parsed, "tuneup auto-fix", homeFn, file);
|
|
@@ -29424,26 +29619,26 @@ var CATEGORY_ORDER = [
|
|
|
29424
29619
|
function severityIcon(severity) {
|
|
29425
29620
|
switch (severity) {
|
|
29426
29621
|
case "error":
|
|
29427
|
-
return
|
|
29622
|
+
return color64.red("\u2717");
|
|
29428
29623
|
case "warning":
|
|
29429
|
-
return
|
|
29624
|
+
return color64.amber("!");
|
|
29430
29625
|
case "ok":
|
|
29431
|
-
return
|
|
29626
|
+
return color64.green("\u2713");
|
|
29432
29627
|
default:
|
|
29433
|
-
return
|
|
29628
|
+
return color64.cyan("\xB7");
|
|
29434
29629
|
}
|
|
29435
29630
|
}
|
|
29436
29631
|
function renderFindings(lines, findings) {
|
|
29437
29632
|
for (const category of CATEGORY_ORDER) {
|
|
29438
29633
|
const group = findings.filter((f) => f.category === category);
|
|
29439
29634
|
if (group.length === 0) continue;
|
|
29440
|
-
lines.push("",
|
|
29635
|
+
lines.push("", color64.bold(CATEGORY_LABELS[category]));
|
|
29441
29636
|
for (const f of group) {
|
|
29442
29637
|
lines.push(` ${severityIcon(f.severity)} ${f.problem}`);
|
|
29443
29638
|
if (f.suggestion) {
|
|
29444
|
-
for (const s of f.suggestion.split("\n")) lines.push(
|
|
29639
|
+
for (const s of f.suggestion.split("\n")) lines.push(color64.dim(` ${s}`));
|
|
29445
29640
|
}
|
|
29446
|
-
if (f.fix) lines.push(
|
|
29641
|
+
if (f.fix) lines.push(color64.dim(` \u2192 fixable: ${f.fix}`));
|
|
29447
29642
|
}
|
|
29448
29643
|
}
|
|
29449
29644
|
}
|
|
@@ -29452,20 +29647,20 @@ function summaryLine(findings, fixable, handoffs, power) {
|
|
|
29452
29647
|
(f) => f.severity === "warning" || f.severity === "error"
|
|
29453
29648
|
).length;
|
|
29454
29649
|
if (warnings === 0 && fixable === 0 && handoffs === 0) {
|
|
29455
|
-
return `${
|
|
29650
|
+
return `${color64.green("\u2713")} everything looks healthy`;
|
|
29456
29651
|
}
|
|
29457
29652
|
const parts = [];
|
|
29458
29653
|
if (warnings > 0) parts.push(`${warnings} warning(s)`);
|
|
29459
29654
|
if (fixable > 0) parts.push(`${fixable} auto-fixable`);
|
|
29460
29655
|
if (handoffs > 0) parts.push(`${handoffs} for the agent`);
|
|
29461
29656
|
const cmd = power ? "/tuneup fix --power" : "/tuneup fix";
|
|
29462
|
-
return `${parts.join(", ")} ${
|
|
29657
|
+
return `${parts.join(", ")} ${color64.dim(`\u2014 run ${cmd}`)}`;
|
|
29463
29658
|
}
|
|
29464
29659
|
|
|
29465
29660
|
// src/slash-commands/working-dir.ts
|
|
29466
|
-
import * as
|
|
29661
|
+
import * as fs18 from "node:fs/promises";
|
|
29467
29662
|
import * as path21 from "node:path";
|
|
29468
|
-
import { color as
|
|
29663
|
+
import { color as color65, toErrorMessage as toErrorMessage28 } from "@wrongstack/core/utils";
|
|
29469
29664
|
function buildWorkingDirCommand(_opts) {
|
|
29470
29665
|
return {
|
|
29471
29666
|
name: "working_dir",
|
|
@@ -29484,16 +29679,16 @@ function buildWorkingDirCommand(_opts) {
|
|
|
29484
29679
|
].join("\n"),
|
|
29485
29680
|
async run(args, ctx) {
|
|
29486
29681
|
if (!ctx) {
|
|
29487
|
-
return { message:
|
|
29682
|
+
return { message: color65.yellow("No active context. Start a session first.") };
|
|
29488
29683
|
}
|
|
29489
29684
|
const trimmed = args.trim();
|
|
29490
29685
|
if (!trimmed) {
|
|
29491
29686
|
const rel2 = path21.relative(ctx.projectRoot, ctx.workingDir) || ".";
|
|
29492
29687
|
return {
|
|
29493
29688
|
message: [
|
|
29494
|
-
`Working directory: ${
|
|
29495
|
-
|
|
29496
|
-
|
|
29689
|
+
`Working directory: ${color65.bold(ctx.workingDir)}`,
|
|
29690
|
+
color65.dim(` (relative to root: ${rel2})`),
|
|
29691
|
+
color65.dim(` Project root: ${ctx.projectRoot}`)
|
|
29497
29692
|
].join("\n")
|
|
29498
29693
|
};
|
|
29499
29694
|
}
|
|
@@ -29502,7 +29697,7 @@ function buildWorkingDirCommand(_opts) {
|
|
|
29502
29697
|
const rel = path21.relative(root, resolved);
|
|
29503
29698
|
if (rel.startsWith("..") || path21.isAbsolute(rel)) {
|
|
29504
29699
|
return {
|
|
29505
|
-
message:
|
|
29700
|
+
message: color65.red(
|
|
29506
29701
|
`Directory "${trimmed}" is outside the project root.
|
|
29507
29702
|
Resolved: ${resolved}
|
|
29508
29703
|
Root: ${root}`
|
|
@@ -29510,27 +29705,27 @@ function buildWorkingDirCommand(_opts) {
|
|
|
29510
29705
|
};
|
|
29511
29706
|
}
|
|
29512
29707
|
try {
|
|
29513
|
-
const stat5 = await
|
|
29708
|
+
const stat5 = await fs18.stat(resolved);
|
|
29514
29709
|
if (!stat5.isDirectory()) {
|
|
29515
|
-
return { message:
|
|
29710
|
+
return { message: color65.red(`Not a directory: ${resolved}`) };
|
|
29516
29711
|
}
|
|
29517
29712
|
} catch {
|
|
29518
|
-
return { message:
|
|
29713
|
+
return { message: color65.red(`Directory does not exist: ${resolved}`) };
|
|
29519
29714
|
}
|
|
29520
29715
|
const previous = ctx.workingDir;
|
|
29521
29716
|
try {
|
|
29522
29717
|
ctx.setWorkingDir(resolved);
|
|
29523
29718
|
} catch (err) {
|
|
29524
29719
|
return {
|
|
29525
|
-
message:
|
|
29720
|
+
message: color65.red(toErrorMessage28(err))
|
|
29526
29721
|
};
|
|
29527
29722
|
}
|
|
29528
29723
|
const prevRel = path21.relative(ctx.projectRoot, previous) || ".";
|
|
29529
29724
|
const newRel = path21.relative(ctx.projectRoot, resolved) || ".";
|
|
29530
29725
|
return {
|
|
29531
29726
|
message: [
|
|
29532
|
-
|
|
29533
|
-
|
|
29727
|
+
color65.green(` \u2713 ${prevRel} \u2192 ${color65.bold(newRel)}`),
|
|
29728
|
+
color65.dim(` ${resolved}`)
|
|
29534
29729
|
].join("\n")
|
|
29535
29730
|
};
|
|
29536
29731
|
}
|
|
@@ -29599,7 +29794,7 @@ function buildWorktreeCommand(opts) {
|
|
|
29599
29794
|
}
|
|
29600
29795
|
|
|
29601
29796
|
// src/slash-commands/yolo.ts
|
|
29602
|
-
import { color as
|
|
29797
|
+
import { color as color66 } from "@wrongstack/core/utils";
|
|
29603
29798
|
function buildYoloCommand(opts) {
|
|
29604
29799
|
return {
|
|
29605
29800
|
name: "yolo",
|
|
@@ -29623,7 +29818,7 @@ function buildYoloCommand(opts) {
|
|
|
29623
29818
|
}
|
|
29624
29819
|
if (!arg) {
|
|
29625
29820
|
const current = opts.onYolo();
|
|
29626
|
-
const status = current ? `${
|
|
29821
|
+
const status = current ? `${color66.yellow("ON")} ${color66.dim("(auto-approving tool calls)")}` : `${color66.green("OFF")} ${color66.dim("(permission prompts active)")}`;
|
|
29627
29822
|
const msg2 = `YOLO mode: ${status}`;
|
|
29628
29823
|
opts.renderer.write(msg2);
|
|
29629
29824
|
return { message: msg2 };
|
|
@@ -29638,11 +29833,11 @@ function buildYoloCommand(opts) {
|
|
|
29638
29833
|
} else if (arg === "destructive") {
|
|
29639
29834
|
const currentMode = opts.onYolo();
|
|
29640
29835
|
if (!currentMode) {
|
|
29641
|
-
const msg3 = `${
|
|
29836
|
+
const msg3 = `${color66.amber("YOLO is OFF.")} Destructive-gate flags are deprecated; prompts are active because YOLO is off.`;
|
|
29642
29837
|
opts.renderer.writeWarning(msg3);
|
|
29643
29838
|
return { message: msg3 };
|
|
29644
29839
|
}
|
|
29645
|
-
const msg2 = `${
|
|
29840
|
+
const msg2 = `${color66.amber("Destructive gate:")} ${color66.dim("deprecated \u2014 YOLO auto-approves all non-denied tool calls.")}`;
|
|
29646
29841
|
opts.renderer.writeWarning(msg2);
|
|
29647
29842
|
return { message: msg2 };
|
|
29648
29843
|
} else {
|
|
@@ -29651,7 +29846,7 @@ function buildYoloCommand(opts) {
|
|
|
29651
29846
|
return { message: msg2 };
|
|
29652
29847
|
}
|
|
29653
29848
|
opts.onYolo(newState);
|
|
29654
|
-
const label = newState ? `${
|
|
29849
|
+
const label = newState ? `${color66.yellow("ENABLED")} \u2014 tool calls will be auto-approved unless explicitly denied` : `${color66.green("DISABLED")} \u2014 permission prompts are active`;
|
|
29655
29850
|
const msg = `YOLO mode: ${label}`;
|
|
29656
29851
|
opts.renderer.write(msg);
|
|
29657
29852
|
return { message: msg };
|
|
@@ -29729,6 +29924,7 @@ function buildBuiltinSlashCommands(opts) {
|
|
|
29729
29924
|
buildTelegramSetupCommand(opts),
|
|
29730
29925
|
buildTelegramSettingsCommand(opts),
|
|
29731
29926
|
buildSetModelCommand(opts),
|
|
29927
|
+
buildEffortCommand(opts),
|
|
29732
29928
|
buildRefinerCommand(opts),
|
|
29733
29929
|
buildFallbackCommand(opts),
|
|
29734
29930
|
...opts.statusTracker ? [buildProviderStatusCommand(opts.statusTracker)] : [],
|
|
@@ -30857,7 +31053,7 @@ function installDesignStudio(deps) {
|
|
|
30857
31053
|
|
|
30858
31054
|
// src/wiring/metrics.ts
|
|
30859
31055
|
import { constants as fsConstants, writeFileSync } from "node:fs";
|
|
30860
|
-
import * as
|
|
31056
|
+
import * as fs19 from "node:fs/promises";
|
|
30861
31057
|
import * as path26 from "node:path";
|
|
30862
31058
|
import {
|
|
30863
31059
|
DefaultHealthRegistry,
|
|
@@ -31004,7 +31200,7 @@ function setupMetrics(params) {
|
|
|
31004
31200
|
name: "session-store",
|
|
31005
31201
|
check: async () => {
|
|
31006
31202
|
try {
|
|
31007
|
-
await
|
|
31203
|
+
await fs19.access(wpaths.projectSessions, fsConstants.R_OK | fsConstants.W_OK);
|
|
31008
31204
|
return { status: "healthy" };
|
|
31009
31205
|
} catch {
|
|
31010
31206
|
return { status: "unhealthy", detail: "session storage is not readable and writable" };
|
|
@@ -31015,7 +31211,7 @@ function setupMetrics(params) {
|
|
|
31015
31211
|
name: "project-storage",
|
|
31016
31212
|
check: async () => {
|
|
31017
31213
|
try {
|
|
31018
|
-
await
|
|
31214
|
+
await fs19.access(wpaths.projectDir, fsConstants.R_OK | fsConstants.W_OK);
|
|
31019
31215
|
return { status: "healthy" };
|
|
31020
31216
|
} catch {
|
|
31021
31217
|
return { status: "unhealthy", detail: "project storage is not readable and writable" };
|
|
@@ -32349,14 +32545,14 @@ function setupProviderRuntime(deps) {
|
|
|
32349
32545
|
}
|
|
32350
32546
|
|
|
32351
32547
|
// src/wiring/provider-status.ts
|
|
32352
|
-
import * as
|
|
32548
|
+
import * as fs20 from "node:fs/promises";
|
|
32353
32549
|
import { ProviderModelStatusTracker } from "@wrongstack/core/coordination";
|
|
32354
|
-
import { atomicWrite as
|
|
32550
|
+
import { atomicWrite as atomicWrite11, withFileLock } from "@wrongstack/core/utils";
|
|
32355
32551
|
async function setupProviderStatus(input) {
|
|
32356
32552
|
const tracker = new ProviderModelStatusTracker({ events: input.events });
|
|
32357
32553
|
const statusFile = input.paths.profileProviderStatus(input.paths.profileName);
|
|
32358
32554
|
try {
|
|
32359
|
-
const saved = JSON.parse(await
|
|
32555
|
+
const saved = JSON.parse(await fs20.readFile(statusFile, "utf8"));
|
|
32360
32556
|
const restored = tracker.restoreSnapshot(saved);
|
|
32361
32557
|
if (restored > 0) input.logger.info(`Restored ${restored} provider waiting-room entries`);
|
|
32362
32558
|
} catch (error) {
|
|
@@ -32368,7 +32564,7 @@ async function setupProviderStatus(input) {
|
|
|
32368
32564
|
tracker.sweepExpired();
|
|
32369
32565
|
if (syncRunning) return;
|
|
32370
32566
|
syncRunning = true;
|
|
32371
|
-
void
|
|
32567
|
+
void fs20.readFile(statusFile, "utf8").then((raw) => tracker.restoreSnapshot(JSON.parse(raw))).catch((error) => warnUnlessMissing(input.logger, "sync", error)).finally(() => {
|
|
32372
32568
|
syncRunning = false;
|
|
32373
32569
|
});
|
|
32374
32570
|
}, 3e4);
|
|
@@ -32383,7 +32579,7 @@ async function setupProviderStatus(input) {
|
|
|
32383
32579
|
await withFileLock(statusFile, async () => {
|
|
32384
32580
|
let statuses = [];
|
|
32385
32581
|
try {
|
|
32386
|
-
const current = JSON.parse(await
|
|
32582
|
+
const current = JSON.parse(await fs20.readFile(statusFile, "utf8"));
|
|
32387
32583
|
if (Array.isArray(current.statuses)) statuses = current.statuses;
|
|
32388
32584
|
} catch (error) {
|
|
32389
32585
|
if (error.code !== "ENOENT") throw error;
|
|
@@ -32399,7 +32595,7 @@ async function setupProviderStatus(input) {
|
|
|
32399
32595
|
if (current && current.state !== "healthy") statuses.push(current);
|
|
32400
32596
|
}
|
|
32401
32597
|
}
|
|
32402
|
-
await
|
|
32598
|
+
await atomicWrite11(
|
|
32403
32599
|
statusFile,
|
|
32404
32600
|
JSON.stringify({ version: 1, updatedAt: Date.now(), statuses }, null, 2),
|
|
32405
32601
|
{ mode: 384 }
|
|
@@ -33820,4 +34016,4 @@ export {
|
|
|
33820
34016
|
CLI_VERSION,
|
|
33821
34017
|
runInteractive
|
|
33822
34018
|
};
|
|
33823
|
-
//# sourceMappingURL=cli-main-
|
|
34019
|
+
//# sourceMappingURL=cli-main-RG2PTQ6S.js.map
|