@wrongstack/cli 0.282.1 → 0.283.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/index.js +363 -28
- package/dist/index.js.map +1 -1
- package/package.json +15 -15
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { CODEX_MODELS, color, ToolCapabilities, PHASE_EVENT_NAMES, readBundledInstructionText, writeErr, loadPlugins, renderProgress, SpecStore, TaskGraphStore, analyzeCriticalPath, getTemplate, listTemplates, templateToMarkdown, SpecParser, renderSpecAnalysis, AISpecBuilder, expectDefined, DefaultTaskStore, TaskTracker, renderTaskGraph, withFileLock, ConfigError, resolveHqDataDir, ensureHqFirstRunAuthFile, DEFAULT_HQ_REDACTION_POLICY, createHqPersistence, HqCommandAuditLog, HqAlertEngine, toAlertMessage, validateHqCommand, watchHqAuthFile, parseHqFrame, HQ_PROTOCOL_VERSION, parseHqEventPayload, scrubAndTruncateHqPreview, FetchError, removeColumn, addColumn, getTask, removeTask, getBoard, assignTask, updateTaskAssignment, listBoards, updateGoalMetricOnTask, addGoalMetricToTask, releaseTaskClaim, claimReadyTask, getTaskChain, setTaskChain, copyTaskToBoard, transferTaskToBoard, moveTask, updateTask, mergeTasks, splitTask, addTask, syncBoardFromTaskGraph, deserializeTaskGraph, exportBoardToTaskGraph, serializeTaskGraph, getKanbanOrchestrationSnapshot, listReadyTasks, generateBoardFromDescription, createBoard, parseLinesIntoTasks, removeBoard, duplicateBoard, updateBoard, wstackGlobalRoot, DefaultSecretScrubber, resolveWstackPaths, watchProviderConfig,
|
|
2
|
+
import { CODEX_MODELS, color, ToolCapabilities, PHASE_EVENT_NAMES, readBundledInstructionText, writeErr, loadPlugins, renderProgress, SpecStore, TaskGraphStore, analyzeCriticalPath, getTemplate, listTemplates, templateToMarkdown, SpecParser, renderSpecAnalysis, AISpecBuilder, expectDefined, DefaultTaskStore, TaskTracker, renderTaskGraph, withFileLock, ConfigError, resolveHqDataDir, ensureHqFirstRunAuthFile, DEFAULT_HQ_REDACTION_POLICY, createHqPersistence, HqCommandAuditLog, HqAlertEngine, toAlertMessage, validateHqCommand, watchHqAuthFile, parseHqFrame, HQ_PROTOCOL_VERSION, parseHqEventPayload, scrubAndTruncateHqPreview, FetchError, removeColumn, addColumn, getTask, removeTask, getBoard, assignTask, updateTaskAssignment, listBoards, updateGoalMetricOnTask, addGoalMetricToTask, releaseTaskClaim, claimReadyTask, getTaskChain, setTaskChain, copyTaskToBoard, transferTaskToBoard, moveTask, updateTask, mergeTasks, splitTask, addTask, syncBoardFromTaskGraph, deserializeTaskGraph, exportBoardToTaskGraph, serializeTaskGraph, getKanbanOrchestrationSnapshot, listReadyTasks, generateBoardFromDescription, createBoard, parseLinesIntoTasks, removeBoard, duplicateBoard, updateBoard, wstackGlobalRoot, DefaultSecretScrubber, resolveWstackPaths, watchProviderConfig, TOKENS, PromptUsageStore, ToolRegistry, GlobalMailbox, resolveSessionLoggingConfig, createSessionEventBridge, HookRegistry, HookRunner, shellHooksEqual, countShellHooks, normalizeTokenSavingTier, allServers as allServers$1, SlashCommandRegistry, attachDepWatcherBridge, createFallbackModelExtension, SessionMemoryConsolidator, BrainDecisionQueue, ObservableBrainArbiter, HumanEscalatingBrainArbiter, createTieredBrainArbiter, DefaultBrainArbiter, BrainMonitor, mailboxSessionTag, createDelegateTool, FLEET_ROSTER, createMcpControlTool, startTechStackConsumer, startPackageOutdatedWatcher, SddRunRegistry, recordFileAction, createAutonomyBrain, DefaultPluginAPI, SpecVersioning, buildTranscriptFromEvents, DefaultLogger, DefaultModelsRegistry, isStdinTTY, FsError, atomicWrite, EventBus, runProviderWithRetry, ReplayLogStore, ReplayProviderRunner, mergeCustomModelDefs, DefaultSystemPromptBuilder, makeAutonomyPromptContributor, sessionScopedPath as sessionScopedPath$1, createContextManagerTool, makeMailboxTool, makeMailSendTool, makeMailInboxTool, makeFleetStatusTool, applyToolDescriptionModes, applyToolResultRenderModes, InMemoryMetricsSink, wireMetricsToEvents, DefaultHealthRegistry, startMetricsServer, createHqPublisherFromEnv, DEFAULT_SESSION_PRUNE_DAYS, RecoveryLock, DefaultAttachmentStore, Context, QueueStore, loadTodosCheckpoint, attachTodosCheckpoint, loadDirectorState, loadPlan, createDefaultPipelines, applyModelRuntime, installDesignStudioMiddleware, resolveContextWindowPolicy, resolveAuditLevel, AutoCompactionMiddleware, estimateRequestTokensCalibrated, Agent, FleetManager, makeDirectorSessionFactory, WorktreeManager, Director, makeFleetEmitTool, AdaptiveConcurrencyController, resolveSubagentModelTarget, DEFAULT_SUBAGENT_BASELINE, AutoApprovePermissionPolicy, mergeModelRuntime, ToolValidationError, WIDE_SUBAGENT_CAPABILITIES, resolveProjectDir, FleetSupervisor, AgentError, PhaseStore, PhaseOrchestrator, assignNickname, AutoPhasePlanner, PhaseGraphBuilder, makeLLMClassifier, writeOut, ParallelEternalEngine, EternalAutonomyEngine, CHIMERA_REVIEW_PROMPT, setQueuedMessagesSnapshot, bootConfig as bootConfig$1, setOutputLineGuard, setRawMode, DefaultSessionReader, ToolAuditLog, DefaultSessionRewinder, DefaultSessionStore, ProviderRegistry, makePreferSideConflictResolver, makeAgentSubagentRunner, NULL_FLEET_BUS, ERROR_CODES, buildChildEnv, exportBoardAsMarkdown, formatContextWindowModeList, repairToolUseAdjacency, getContextWindowMode, AGENT_CATALOG, dispatchAgent, normalizeToolDescriptionMode, getToolDescriptionMode, noOpVault, formatTodosList, loadTasks, formatTaskList, formatTaskProgress, mutateTasks, emptyPlan, addPlanItem, savePlan, formatPlan, recordCompletedWorkEvidence, saveCompletedWorkCheckpoint, SessionRecovery, loadGoal, goalFilePath, summarizeUsage, saveGoal, formatGoal, emptyGoal, buildGoalPreamble, pendingBtwCount, setBtwNote, getDesignKitLoader, getDesignState, clearActiveKit, clearPersistedActiveKit, recordOverrides, setDesignOverrides, loadActiveKit, isDesignStack, applyTokenOverrides, materializeTokens, setActiveKit, readHqRuntimeFileSync, resolveHqConfig, MATRIX_PHASE_KEYS, matrixKeyKind, phaseForRole, resolveModelMatrix, resolveModelTargetFromEntry, fallbackProfileChain, parseModelRef, normalizeModelRef, onResize, hasOpenTodos, InputBuilder, detectContinueIntent, resolveContinuation, DefaultSecretVault as DefaultSecretVault$1, decryptConfigSecrets as decryptConfigSecrets$1, encryptConfigSecrets as encryptConfigSecrets$1, DEFAULT_CONTEXT_WINDOW_MODE_ID, HQ_AUTH_FILE_VERSION, truncate, createBoardFromTaskGraph, addDependency, addNoteToTask, addCheckToTask, estimateMessageTokens, AGENTS_BY_PHASE, validateAgainstSchema, normalizeToolResultRenderMode, getToolResultRenderMode, setToolResultRenderMode, resolveMailboxIdentity, smartDefaultFallbackChain, AutonomousCoordinator, mutateHqAuthFile, mintHqToken, readHqAuthFile, areDependenciesMet, findBlockedTasks, renderInstructionTemplate, recentTextTurns, gatedEnhancerReasoning, enhanceUserPrompt, mutatePlan, setPlanItemStatus, getPlanTemplate, resolveProviderModelList, ParseError, startSessionTelemetryBridge, startFleetTelemetryBridge, startBrainTelemetryBridge, startWorktreeTelemetryBridge, startToolTelemetryBridge, startCostTelemetryBridge } from '@wrongstack/core';
|
|
3
3
|
import * as fs2 from 'fs/promises';
|
|
4
4
|
import { access, readFile } from 'fs/promises';
|
|
5
5
|
import { DefaultSecretVault, decryptConfigSecrets, encryptConfigSecrets, isSecretField } from '@wrongstack/core/security';
|
|
@@ -34,7 +34,7 @@ import { parseNextSteps } from '@wrongstack/tui';
|
|
|
34
34
|
import { WrongStackACPServer, makeACPServerAgentTurn, ACPSessionStore, WsBridgeTransport, ACPProtocolHandler } from '@wrongstack/acp/agent';
|
|
35
35
|
import { allServers, DefaultPathResolver, DefaultTokenCounter } from '@wrongstack/core/infrastructure';
|
|
36
36
|
import { ToolExecutor } from '@wrongstack/core/execution';
|
|
37
|
-
import { loadBenchConfig, reportHeaderLine, readSummary, renderMarkdownReport, createPolyglotSuite, createSwebenchSuite, runBenchmark, writeJsonArtifacts, collectCellPredictions, writePredictionsJsonl, gradePolyglot, gradeSwebench } from '@wrongstack/bench';
|
|
37
|
+
import { loadBenchConfig, reportHeaderLine, computeToolManifestHash, readSummary, renderMarkdownReport, createPolyglotSuite, createSwebenchSuite, createLocalManifestSuite, runBenchmark, writeJsonArtifacts, collectCellPredictions, writePredictionsJsonl, gradePolyglot, gradeSwebench, gradeLocalManifest } from '@wrongstack/bench';
|
|
38
38
|
import { createAgentMonitorService, acquireOrJoin, release, finalize, readLiveLock } from '@wrongstack/core/coordination';
|
|
39
39
|
import * as net from 'net';
|
|
40
40
|
import { createToolVisionAdapters } from '@wrongstack/runtime/vision';
|
|
@@ -7388,6 +7388,29 @@ var init_cost_helpers = __esm({
|
|
|
7388
7388
|
function currentSessionId2(ctx) {
|
|
7389
7389
|
return ctx.agent.ctx.session?.id ?? ctx.sessionId;
|
|
7390
7390
|
}
|
|
7391
|
+
function toolEntries(ctx) {
|
|
7392
|
+
const registry = ctx.agent.tools;
|
|
7393
|
+
if (typeof registry.listWithOwner === "function") {
|
|
7394
|
+
return [
|
|
7395
|
+
...registry.listWithOwner(),
|
|
7396
|
+
...typeof registry.listDisabled === "function" ? registry.listDisabled() : []
|
|
7397
|
+
];
|
|
7398
|
+
}
|
|
7399
|
+
return (registry.list?.() ?? []).map((tool) => ({ tool, owner: "core" }));
|
|
7400
|
+
}
|
|
7401
|
+
function persistDisabledTool(ctx, name, disabled) {
|
|
7402
|
+
const configStore = ctx.configStore;
|
|
7403
|
+
if (!configStore) return;
|
|
7404
|
+
const currentTools = configStore.get().tools ?? {};
|
|
7405
|
+
const disabledTools = new Set(currentTools.disabledTools ?? []);
|
|
7406
|
+
if (disabled) disabledTools.add(name);
|
|
7407
|
+
else disabledTools.delete(name);
|
|
7408
|
+
configStore.update({ tools: { ...currentTools, disabledTools: Array.from(disabledTools) } });
|
|
7409
|
+
}
|
|
7410
|
+
function toolNameFromPayload(payload) {
|
|
7411
|
+
const name = payload?.name;
|
|
7412
|
+
return typeof name === "string" && name.trim().length > 0 ? name.trim() : void 0;
|
|
7413
|
+
}
|
|
7391
7414
|
async function handleSkillsList(ctx, ws) {
|
|
7392
7415
|
if (!ctx.skillLoader) {
|
|
7393
7416
|
ctx.send(ws, { type: "skills.list", payload: { skills: [], enabled: false } });
|
|
@@ -7424,17 +7447,42 @@ async function handleSkillsList(ctx, ws) {
|
|
|
7424
7447
|
}
|
|
7425
7448
|
}
|
|
7426
7449
|
function handleToolsList(ctx, ws) {
|
|
7427
|
-
const
|
|
7428
|
-
|
|
7450
|
+
const registry = ctx.agent.tools;
|
|
7451
|
+
const list = toolEntries(ctx).map(({ tool, owner }) => {
|
|
7452
|
+
const schema = tool.inputSchema ?? {};
|
|
7429
7453
|
const params = schema.properties ? Object.keys(schema.properties) : [];
|
|
7430
7454
|
return {
|
|
7431
|
-
name:
|
|
7432
|
-
|
|
7433
|
-
|
|
7455
|
+
name: tool.name,
|
|
7456
|
+
owner,
|
|
7457
|
+
description: tool.description ?? "",
|
|
7458
|
+
params,
|
|
7459
|
+
disabled: registry.isDisabled?.(tool.name) ?? false,
|
|
7460
|
+
mutating: !!tool.mutating,
|
|
7461
|
+
permission: tool.permission ?? "auto"
|
|
7434
7462
|
};
|
|
7435
7463
|
});
|
|
7436
7464
|
ctx.send(ws, { type: "tools.list", payload: { tools: list } });
|
|
7437
7465
|
}
|
|
7466
|
+
function handleToolDisable(ctx, ws, payload) {
|
|
7467
|
+
const name = toolNameFromPayload(payload);
|
|
7468
|
+
if (!name) {
|
|
7469
|
+
ctx.send(ws, { type: "error", payload: { message: "tool.disable requires a name" } });
|
|
7470
|
+
return;
|
|
7471
|
+
}
|
|
7472
|
+
const ok2 = ctx.agent.tools.disable(name);
|
|
7473
|
+
if (ok2) persistDisabledTool(ctx, name, true);
|
|
7474
|
+
ctx.send(ws, { type: "tool.disabled", payload: { name, ok: ok2 } });
|
|
7475
|
+
}
|
|
7476
|
+
function handleToolEnable(ctx, ws, payload) {
|
|
7477
|
+
const name = toolNameFromPayload(payload);
|
|
7478
|
+
if (!name) {
|
|
7479
|
+
ctx.send(ws, { type: "error", payload: { message: "tool.enable requires a name" } });
|
|
7480
|
+
return;
|
|
7481
|
+
}
|
|
7482
|
+
const ok2 = ctx.agent.tools.enable(name);
|
|
7483
|
+
if (ok2) persistDisabledTool(ctx, name, false);
|
|
7484
|
+
ctx.send(ws, { type: "tool.enabled", payload: { name, ok: ok2 } });
|
|
7485
|
+
}
|
|
7438
7486
|
function handleDiagGet(ctx, ws) {
|
|
7439
7487
|
const actx = ctx.agent.ctx;
|
|
7440
7488
|
const tools = ctx.agent.tools.list();
|
|
@@ -9901,6 +9949,8 @@ function createMessageRouter(deps) {
|
|
|
9901
9949
|
});
|
|
9902
9950
|
},
|
|
9903
9951
|
"tools.list": (_msg, ws) => handleToolsList(introspectionCtx, ws),
|
|
9952
|
+
"tool.disable": (msg, ws) => handleToolDisable(introspectionCtx, ws, msg.payload),
|
|
9953
|
+
"tool.enable": (msg, ws) => handleToolEnable(introspectionCtx, ws, msg.payload),
|
|
9904
9954
|
// ── Autonomy ──
|
|
9905
9955
|
"autonomy.switch": (msg, ws) => handleAutonomySwitch(prefsCtx, ws, msg.payload.mode),
|
|
9906
9956
|
// ── Brain ──
|
|
@@ -11554,6 +11604,7 @@ async function runWebUI(opts) {
|
|
|
11554
11604
|
projectRoot: opts.projectRoot,
|
|
11555
11605
|
sessionId: opts.session.id,
|
|
11556
11606
|
sessionStartedAt,
|
|
11607
|
+
configStore: opts.agent.container?.safeResolve?.(TOKENS.ConfigStore),
|
|
11557
11608
|
send: send2,
|
|
11558
11609
|
broadcast,
|
|
11559
11610
|
log: (m) => console.log(m)
|
|
@@ -17143,6 +17194,10 @@ function buildBrainCommand(opts) {
|
|
|
17143
17194
|
const trimmed = args.trim();
|
|
17144
17195
|
const [sub, ...rest] = trimmed.split(/\s+/);
|
|
17145
17196
|
const subcommand = (sub ?? "").toLowerCase();
|
|
17197
|
+
if ((subcommand === "" || subcommand === "status") && opts.onPanelOpen?.current) {
|
|
17198
|
+
const opened = opts.onPanelOpen.current("brainOpen");
|
|
17199
|
+
if (opened) return { message: "" };
|
|
17200
|
+
}
|
|
17146
17201
|
if (subcommand === "risk") {
|
|
17147
17202
|
if (!opts.brainSettings) {
|
|
17148
17203
|
const msg3 = "Brain settings are not available in this session.";
|
|
@@ -17949,6 +18004,10 @@ ${description}`
|
|
|
17949
18004
|
return { message: `Task ${taskId.slice(0, 8)} marked failed: ${reason}` };
|
|
17950
18005
|
}
|
|
17951
18006
|
if (verb === "status") {
|
|
18007
|
+
if (opts.onPanelOpen?.current) {
|
|
18008
|
+
const opened = opts.onPanelOpen.current("toggleCoordinatorMonitor");
|
|
18009
|
+
if (opened) return { message: "" };
|
|
18010
|
+
}
|
|
17952
18011
|
const statusFn = getStatus();
|
|
17953
18012
|
if (statusFn) {
|
|
17954
18013
|
const stats = await statusFn();
|
|
@@ -21128,6 +21187,10 @@ function buildGoalCommand(opts) {
|
|
|
21128
21187
|
"every iteration to decide what to do next."
|
|
21129
21188
|
].join("\n"),
|
|
21130
21189
|
async run(args) {
|
|
21190
|
+
if (!args.trim() && opts.onPanelOpen?.current) {
|
|
21191
|
+
const opened = opts.onPanelOpen.current("toggleGoalPanel");
|
|
21192
|
+
if (opened) return { message: "" };
|
|
21193
|
+
}
|
|
21131
21194
|
const trimmed = args.trim();
|
|
21132
21195
|
const [verbRaw, ...rest] = trimmed.split(/\s+/);
|
|
21133
21196
|
const verb = (verbRaw ?? "").toLowerCase();
|
|
@@ -21346,6 +21409,10 @@ function buildHelpCommand(opts) {
|
|
|
21346
21409
|
].join("\n"),
|
|
21347
21410
|
async run(args) {
|
|
21348
21411
|
const query = args.trim();
|
|
21412
|
+
if (!query && opts.onPanelOpen?.current) {
|
|
21413
|
+
opts.onPanelOpen.current("helpOpen");
|
|
21414
|
+
return { message: "" };
|
|
21415
|
+
}
|
|
21349
21416
|
if (query) {
|
|
21350
21417
|
const needle = query.startsWith("/") ? query.slice(1) : query;
|
|
21351
21418
|
let match;
|
|
@@ -23343,7 +23410,7 @@ function buildMcpSlashCommand(opts) {
|
|
|
23343
23410
|
argsHint: "[list|add <name>|remove <name>|enable <name>|disable <name>|restart <name>]",
|
|
23344
23411
|
help: [
|
|
23345
23412
|
"Usage:",
|
|
23346
|
-
" /mcp
|
|
23413
|
+
" /mcp Open interactive server picker (TUI) or list servers.",
|
|
23347
23414
|
" /mcp list Same.",
|
|
23348
23415
|
" /mcp add <name> Add server preset to config (disabled).",
|
|
23349
23416
|
" /mcp add <name> --enable Add and immediately enable.",
|
|
@@ -23359,10 +23426,15 @@ function buildMcpSlashCommand(opts) {
|
|
|
23359
23426
|
" /mcp restart brave-search"
|
|
23360
23427
|
].join("\n"),
|
|
23361
23428
|
async run(args) {
|
|
23429
|
+
const trimmed = args.trim();
|
|
23430
|
+
if ((trimmed === "" || trimmed === "list") && opts.onPanelOpen?.current) {
|
|
23431
|
+
const opened = opts.onPanelOpen.current("mcpPickerOpen");
|
|
23432
|
+
if (opened) return { message: "" };
|
|
23433
|
+
}
|
|
23362
23434
|
if (!opts.onMcp) {
|
|
23363
23435
|
return { message: "MCP management is not available in this session." };
|
|
23364
23436
|
}
|
|
23365
|
-
const result = await opts.onMcp(
|
|
23437
|
+
const result = await opts.onMcp(trimmed);
|
|
23366
23438
|
return { message: result };
|
|
23367
23439
|
}
|
|
23368
23440
|
};
|
|
@@ -23844,15 +23916,15 @@ function buildModeCommand(opts) {
|
|
|
23844
23916
|
" /mode Show current mode and available modes",
|
|
23845
23917
|
" /mode <id> Switch to a different mode",
|
|
23846
23918
|
"",
|
|
23847
|
-
"Available
|
|
23848
|
-
"
|
|
23849
|
-
"
|
|
23850
|
-
" teach Mentor mode \u2014 explains why, not just what",
|
|
23851
|
-
" code-reviewer, code-auditor, architect, debugger, tester, devops, refactorer",
|
|
23919
|
+
"Available mode families:",
|
|
23920
|
+
" Token-saving: brief, review-lite, audit-lite, plan-lite, debug-lite, test-lite, refactor-lite, research-lite",
|
|
23921
|
+
" Deep/full: code-reviewer, code-auditor, architect, debugger, tester, devops, refactorer, ui-design, teach, research-web",
|
|
23852
23922
|
"",
|
|
23853
|
-
"
|
|
23854
|
-
" /mode brief
|
|
23855
|
-
" /mode
|
|
23923
|
+
"Examples:",
|
|
23924
|
+
" /mode brief Ultra-compact responses",
|
|
23925
|
+
" /mode review-lite Narrow changed-file review",
|
|
23926
|
+
" /mode code-reviewer Full correctness/security review",
|
|
23927
|
+
" /mode teach Mentor-style explanations"
|
|
23856
23928
|
].join("\n"),
|
|
23857
23929
|
async run(args, ctx) {
|
|
23858
23930
|
const modeStore = opts.modeStore;
|
|
@@ -25775,6 +25847,64 @@ function formatSuggestions(suggestions) {
|
|
|
25775
25847
|
return lines.join("\n");
|
|
25776
25848
|
}
|
|
25777
25849
|
|
|
25850
|
+
// src/slash-commands/surfaces.ts
|
|
25851
|
+
var DESKTOP_MESSAGE = [
|
|
25852
|
+
"WrongStack Desktop",
|
|
25853
|
+
"\u2500".repeat("WrongStack Desktop".length),
|
|
25854
|
+
"The desktop app is the local graphical shell for WrongStack sessions, project state, and agent coordination.",
|
|
25855
|
+
"",
|
|
25856
|
+
"Recommended path:",
|
|
25857
|
+
" Start it from your desktop launcher or from the platform-specific package you installed.",
|
|
25858
|
+
"",
|
|
25859
|
+
"Why this command only explains:",
|
|
25860
|
+
" A slash command runs inside the current CLI/TUI process, so silently launching a GUI is platform- and install-dependent. Keeping this informational avoids surprising side effects."
|
|
25861
|
+
].join("\n");
|
|
25862
|
+
var WEBUI_MESSAGE = [
|
|
25863
|
+
"WrongStack Web UI",
|
|
25864
|
+
"\u2500".repeat("WrongStack Web UI".length),
|
|
25865
|
+
"The Web UI is the browser-based view for sessions, agents, mailbox coordination, and project activity.",
|
|
25866
|
+
"",
|
|
25867
|
+
"Recommended path:",
|
|
25868
|
+
" Start the Web UI/HQ server with the project command you normally use, then open the printed local URL in your browser.",
|
|
25869
|
+
"",
|
|
25870
|
+
"Why this command only explains:",
|
|
25871
|
+
" The active slash-command surface may not know which port, host, or Web UI package is running. Showing guidance is more reliable than guessing and opening the wrong target."
|
|
25872
|
+
].join("\n");
|
|
25873
|
+
function buildDesktopCommand() {
|
|
25874
|
+
return {
|
|
25875
|
+
name: "desktop",
|
|
25876
|
+
category: "App",
|
|
25877
|
+
description: "Explain how to access the WrongStack Desktop app.",
|
|
25878
|
+
help: [
|
|
25879
|
+
"Usage:",
|
|
25880
|
+
" /desktop",
|
|
25881
|
+
"",
|
|
25882
|
+
"Shows where the Desktop app fits and why the CLI/TUI does not automatically launch it."
|
|
25883
|
+
].join("\n"),
|
|
25884
|
+
async run() {
|
|
25885
|
+
return { message: DESKTOP_MESSAGE };
|
|
25886
|
+
}
|
|
25887
|
+
};
|
|
25888
|
+
}
|
|
25889
|
+
function buildWebuiCommand() {
|
|
25890
|
+
return {
|
|
25891
|
+
name: "webui",
|
|
25892
|
+
aliases: ["web"],
|
|
25893
|
+
category: "App",
|
|
25894
|
+
description: "Explain how to access the WrongStack browser UI.",
|
|
25895
|
+
help: [
|
|
25896
|
+
"Usage:",
|
|
25897
|
+
" /webui",
|
|
25898
|
+
" /web",
|
|
25899
|
+
"",
|
|
25900
|
+
"Shows Web UI access guidance without guessing whether a local server is already running."
|
|
25901
|
+
].join("\n"),
|
|
25902
|
+
async run() {
|
|
25903
|
+
return { message: WEBUI_MESSAGE };
|
|
25904
|
+
}
|
|
25905
|
+
};
|
|
25906
|
+
}
|
|
25907
|
+
|
|
25778
25908
|
// src/slash-commands/agents.ts
|
|
25779
25909
|
init_helpers();
|
|
25780
25910
|
function formatAgentLine(a) {
|
|
@@ -25797,6 +25927,10 @@ function buildAgentsCommand(opts) {
|
|
|
25797
25927
|
category: "Agent",
|
|
25798
25928
|
description: "Monitor subagent activity: /agents [stream on|off|status|list|show <id>]",
|
|
25799
25929
|
async run(args) {
|
|
25930
|
+
if ((!args.trim() || args.trim() === "list") && opts.onPanelOpen?.current) {
|
|
25931
|
+
const opened = opts.onPanelOpen.current("toggleAgentsMonitor");
|
|
25932
|
+
if (opened) return { message: "" };
|
|
25933
|
+
}
|
|
25800
25934
|
const monitor = opts.agentMonitor;
|
|
25801
25935
|
const { cmd, rest } = parseSubcommand(args);
|
|
25802
25936
|
const restJoined = rest.join(" ").trim();
|
|
@@ -27482,6 +27616,13 @@ function buildShadowCommand(opts) {
|
|
|
27482
27616
|
async run(args, _ctx) {
|
|
27483
27617
|
const [action, ...rest] = args.trim().split(/\s+/);
|
|
27484
27618
|
switch (action) {
|
|
27619
|
+
case void 0:
|
|
27620
|
+
case "":
|
|
27621
|
+
if (opts.onPanelOpen?.current) {
|
|
27622
|
+
const opened = opts.onPanelOpen.current("shadowOpen");
|
|
27623
|
+
if (opened) return { message: "" };
|
|
27624
|
+
}
|
|
27625
|
+
return { message: this.help ?? "/shadow \u2014 use /shadow help for usage" };
|
|
27485
27626
|
case "start": {
|
|
27486
27627
|
if (!opts.onSpawn) {
|
|
27487
27628
|
return { message: "/shadow requires a running director with subagent support." };
|
|
@@ -29002,7 +29143,7 @@ ${color.dim("No default chat set. You can add it later: /telegram-setup <token>
|
|
|
29002
29143
|
`${color.amber("\u26A0")} Restart WrongStack for the plugin to pick up the new config.`,
|
|
29003
29144
|
"",
|
|
29004
29145
|
"After restart, try:",
|
|
29005
|
-
` ${color.cyan("/telegram
|
|
29146
|
+
` ${color.cyan("/telegram")} \u2014 check bot connection`,
|
|
29006
29147
|
` ${color.cyan("/telegram:send")} \u2014 send a test message`
|
|
29007
29148
|
].join("\n")
|
|
29008
29149
|
};
|
|
@@ -29138,6 +29279,7 @@ function buildToolCommand(opts) {
|
|
|
29138
29279
|
" /tool <name> result simple|extend Set ONLY the on-screen result mode",
|
|
29139
29280
|
" /tool disable <name> Hide a tool from the registry and system prompt",
|
|
29140
29281
|
" /tool enable <name> Restore a disabled tool",
|
|
29282
|
+
" /tool <name> disable|enable Same as above, noun-first alias",
|
|
29141
29283
|
" /tool enable-all Restore all disabled tools",
|
|
29142
29284
|
"",
|
|
29143
29285
|
"Modes:",
|
|
@@ -29376,6 +29518,19 @@ function buildToolCommand(opts) {
|
|
|
29376
29518
|
return { message: `${color.red("Error")}: ${toErrorMessage$1(err)}` };
|
|
29377
29519
|
}
|
|
29378
29520
|
}
|
|
29521
|
+
const action = parts[1]?.toLowerCase();
|
|
29522
|
+
if (action === "disable" || action === "enable") {
|
|
29523
|
+
if (parts.length > 2) {
|
|
29524
|
+
return {
|
|
29525
|
+
message: `${color.amber("Usage:")} /tool ${name} ${action}`
|
|
29526
|
+
};
|
|
29527
|
+
}
|
|
29528
|
+
try {
|
|
29529
|
+
return { message: action === "disable" ? await cmdDisable(name) : await cmdEnable(name) };
|
|
29530
|
+
} catch (err) {
|
|
29531
|
+
return { message: `${color.red("Error")}: ${toErrorMessage$1(err)}` };
|
|
29532
|
+
}
|
|
29533
|
+
}
|
|
29379
29534
|
if (!opts.toolRegistry.get(name) && !opts.toolRegistry.isDisabled(name)) {
|
|
29380
29535
|
return {
|
|
29381
29536
|
message: `${color.red("Unknown tool")}: ${name}. Use ${color.dim("/tools")} to list registered tools.`
|
|
@@ -29456,11 +29611,15 @@ function buildToolsCommand(opts) {
|
|
|
29456
29611
|
async run(args) {
|
|
29457
29612
|
const reg = opts.toolRegistry;
|
|
29458
29613
|
const filter = args.trim().toLowerCase();
|
|
29459
|
-
const allTools = reg.listWithOwner();
|
|
29614
|
+
const allTools = [...reg.listWithOwner(), ...reg.listDisabled()];
|
|
29460
29615
|
const all = filter ? allTools.filter(
|
|
29461
29616
|
({ tool, owner }) => tool.name.toLowerCase().includes(filter) || owner.toLowerCase().includes(filter)
|
|
29462
29617
|
) : allTools;
|
|
29463
29618
|
const disabled = reg.listDisabled();
|
|
29619
|
+
if (opts.onPanelOpen?.current) {
|
|
29620
|
+
const opened = opts.onPanelOpen.current("toolsPickerOpen");
|
|
29621
|
+
if (opened) return { message: "" };
|
|
29622
|
+
}
|
|
29464
29623
|
if (filter && all.length === 0) {
|
|
29465
29624
|
const msg2 = `${color.bold("Tools")} \u2014 no tool name or owner matched "${filter}".`;
|
|
29466
29625
|
opts.renderer.write(msg2);
|
|
@@ -29682,6 +29841,8 @@ function buildYoloCommand(opts) {
|
|
|
29682
29841
|
function buildBuiltinSlashCommands(opts) {
|
|
29683
29842
|
return [
|
|
29684
29843
|
buildHelpCommand(opts),
|
|
29844
|
+
buildDesktopCommand(),
|
|
29845
|
+
buildWebuiCommand(),
|
|
29685
29846
|
buildInitCommand(opts),
|
|
29686
29847
|
buildClearCommand(opts),
|
|
29687
29848
|
buildInterruptCommand(opts),
|
|
@@ -32074,6 +32235,9 @@ function printUsage(deps) {
|
|
|
32074
32235
|
color.dim(
|
|
32075
32236
|
" wstack bench run --suite polyglot --polyglot-dir ./polyglot --models bench.config.json --limit 5"
|
|
32076
32237
|
),
|
|
32238
|
+
color.dim(
|
|
32239
|
+
" wstack bench run --suite local --suite-dir ./evals --models bench.config.json"
|
|
32240
|
+
),
|
|
32077
32241
|
color.dim(" wstack bench report ./bench-results/2026-06-14T10-00-00"),
|
|
32078
32242
|
""
|
|
32079
32243
|
].join("\n") + "\n"
|
|
@@ -32141,11 +32305,26 @@ async function benchRun(_args, deps) {
|
|
|
32141
32305
|
docker
|
|
32142
32306
|
});
|
|
32143
32307
|
grade = (a) => gradeSwebench({ ...a, predictionsDir });
|
|
32308
|
+
} else if (suiteId === "local" || suiteId === "manifest") {
|
|
32309
|
+
const suiteDirRaw = flagStr(deps, "suite-dir");
|
|
32310
|
+
const manifestRaw = flagStr(deps, "manifest");
|
|
32311
|
+
if (!suiteDirRaw && !manifestRaw) {
|
|
32312
|
+
deps.renderer.writeError(
|
|
32313
|
+
"--suite-dir <path> or --manifest <file> is required for the local suite."
|
|
32314
|
+
);
|
|
32315
|
+
return 1;
|
|
32316
|
+
}
|
|
32317
|
+
const manifestFile = manifestRaw ? path5.resolve(deps.cwd, manifestRaw) : void 0;
|
|
32318
|
+
const suiteDir = suiteDirRaw ? path5.resolve(deps.cwd, suiteDirRaw) : path5.dirname(manifestFile);
|
|
32319
|
+
suite = createLocalManifestSuite({ suiteDir, manifestFile });
|
|
32320
|
+
grade = (a) => gradeLocalManifest(a);
|
|
32144
32321
|
} else {
|
|
32145
|
-
deps.renderer.writeError(`unknown suite "${suiteId}" (expected: polyglot | swebench)`);
|
|
32322
|
+
deps.renderer.writeError(`unknown suite "${suiteId}" (expected: polyglot | swebench | local)`);
|
|
32146
32323
|
return 1;
|
|
32147
32324
|
}
|
|
32148
|
-
const
|
|
32325
|
+
const tools = deps.toolRegistry?.list() ?? [];
|
|
32326
|
+
const toolNames = tools.map((t) => t.name);
|
|
32327
|
+
const toolManifestHash = computeToolManifestHash(tools);
|
|
32149
32328
|
const wstackEntry = await resolveWstackEntry();
|
|
32150
32329
|
deps.renderer.writeInfo(`Running ${suiteId} across ${config.cells.length} model(s)\u2026`);
|
|
32151
32330
|
let report;
|
|
@@ -32156,6 +32335,7 @@ async function benchRun(_args, deps) {
|
|
|
32156
32335
|
config,
|
|
32157
32336
|
cliVersion: CLI_VERSION,
|
|
32158
32337
|
toolNames,
|
|
32338
|
+
toolManifestHash,
|
|
32159
32339
|
nodeBin: process.execPath,
|
|
32160
32340
|
wstackEntry,
|
|
32161
32341
|
limit,
|
|
@@ -32212,6 +32392,9 @@ async function benchList(_args, deps) {
|
|
|
32212
32392
|
deps.renderer.write(
|
|
32213
32393
|
" swebench " + color.dim("SWE-bench Verified (end-to-end) \u2014 Phase 2, Docker-gated\n")
|
|
32214
32394
|
);
|
|
32395
|
+
deps.renderer.write(
|
|
32396
|
+
" local " + color.dim("Project-defined manifest tasks with command/file graders\n")
|
|
32397
|
+
);
|
|
32215
32398
|
const modelsPath = flagStr(deps, "models");
|
|
32216
32399
|
if (modelsPath) {
|
|
32217
32400
|
try {
|
|
@@ -32223,12 +32406,14 @@ async function benchList(_args, deps) {
|
|
|
32223
32406
|
`
|
|
32224
32407
|
);
|
|
32225
32408
|
}
|
|
32409
|
+
const tools = deps.toolRegistry?.list() ?? [];
|
|
32226
32410
|
const fp = reportHeaderLine({
|
|
32227
32411
|
cliVersion: CLI_VERSION,
|
|
32228
|
-
toolNames:
|
|
32412
|
+
toolNames: tools.map((t) => t.name),
|
|
32229
32413
|
maxIterations: config.maxIterations,
|
|
32230
32414
|
yolo: true,
|
|
32231
32415
|
subsetId: "(computed at run time)",
|
|
32416
|
+
toolManifestHash: computeToolManifestHash(tools),
|
|
32232
32417
|
hash: "(computed at run time)"
|
|
32233
32418
|
});
|
|
32234
32419
|
deps.renderer.write("\n" + color.dim(`Harness: ${fp}`) + "\n");
|
|
@@ -37900,6 +38085,7 @@ function createSettingsAdapter(ctx) {
|
|
|
37900
38085
|
restrictFsToRoot: resolvedRestrict,
|
|
37901
38086
|
autoProceedMaxIterations: cfg.autonomy?.autoProceedMaxIterations ?? 50,
|
|
37902
38087
|
debugStream: cfg.debugStream ?? false,
|
|
38088
|
+
shellBangWarningDontShowAgain: autonomy?.shellBangWarningDontShowAgain === true,
|
|
37903
38089
|
statuslineMode: autonomy?.statuslineMode === "minimum" ? "minimum" : "detailed",
|
|
37904
38090
|
thinkingWord: normalizeTuiThinkingWord(autonomy?.thinkingWord),
|
|
37905
38091
|
animationStyle: normalizeAnimationStyle(autonomy?.animationStyle),
|
|
@@ -37920,7 +38106,7 @@ function createSettingsAdapter(ctx) {
|
|
|
37920
38106
|
}
|
|
37921
38107
|
async function saveSettings(s) {
|
|
37922
38108
|
try {
|
|
37923
|
-
if (s.mode !== void 0 || s.delayMs !== void 0 || s.titleAnimation !== void 0 || s.yolo !== void 0 || s.streamFleet !== void 0 || s.chime !== void 0 || s.confirmExit !== void 0 || s.mouseMode !== void 0 || s.featureMcp !== void 0 || s.featurePlugins !== void 0 || s.featureMemory !== void 0 || s.featureSkills !== void 0 || s.featureModelsRegistry !== void 0 || s.featureTokenSaving !== void 0 || s.allowOutsideProjectRoot !== void 0 || s.contextAutoCompact !== void 0 || s.contextStrategy !== void 0 || s.contextMode !== void 0 || s.maxConcurrent !== void 0 || s.logLevel !== void 0 || s.auditLevel !== void 0 || s.indexOnStart !== void 0 || s.maxIterations !== void 0 || s.restrictFsToRoot !== void 0 || s.nextPrediction !== void 0 || s.debugStream !== void 0 || s.configScope !== void 0 || s.enhanceDelayMs !== void 0 || s.enhanceEnabled !== void 0 || s.enhanceLanguage !== void 0 || s.midRunSendPicker !== void 0 || s.statuslineMode !== void 0 || s.thinkingWord !== void 0 || s.animationStyle !== void 0 || s.autonomyNextPrompt !== void 0 || s.autoProceedMaxIterations !== void 0 || s.reasoningMode !== void 0 || s.reasoningEffort !== void 0 || s.reasoningPreserve !== void 0 || s.cacheTtl !== void 0) {
|
|
38109
|
+
if (s.mode !== void 0 || s.delayMs !== void 0 || s.titleAnimation !== void 0 || s.yolo !== void 0 || s.streamFleet !== void 0 || s.chime !== void 0 || s.confirmExit !== void 0 || s.mouseMode !== void 0 || s.featureMcp !== void 0 || s.featurePlugins !== void 0 || s.featureMemory !== void 0 || s.featureSkills !== void 0 || s.featureModelsRegistry !== void 0 || s.featureTokenSaving !== void 0 || s.allowOutsideProjectRoot !== void 0 || s.contextAutoCompact !== void 0 || s.contextStrategy !== void 0 || s.contextMode !== void 0 || s.maxConcurrent !== void 0 || s.logLevel !== void 0 || s.auditLevel !== void 0 || s.indexOnStart !== void 0 || s.maxIterations !== void 0 || s.restrictFsToRoot !== void 0 || s.nextPrediction !== void 0 || s.debugStream !== void 0 || s.shellBangWarningDontShowAgain !== void 0 || s.configScope !== void 0 || s.enhanceDelayMs !== void 0 || s.enhanceEnabled !== void 0 || s.enhanceLanguage !== void 0 || s.midRunSendPicker !== void 0 || s.statuslineMode !== void 0 || s.thinkingWord !== void 0 || s.animationStyle !== void 0 || s.autonomyNextPrompt !== void 0 || s.autoProceedMaxIterations !== void 0 || s.reasoningMode !== void 0 || s.reasoningEffort !== void 0 || s.reasoningPreserve !== void 0 || s.cacheTtl !== void 0) {
|
|
37924
38110
|
const configScope = s.configScope ?? configStore.get().configScope ?? "global";
|
|
37925
38111
|
const targetPath = configScope === "project" && wpaths.inProjectConfig ? wpaths.inProjectConfig : wpaths.globalConfig;
|
|
37926
38112
|
let raw;
|
|
@@ -37950,6 +38136,8 @@ function createSettingsAdapter(ctx) {
|
|
|
37950
38136
|
if (s.enhanceEnabled !== void 0) autonomy.enhance = s.enhanceEnabled;
|
|
37951
38137
|
if (s.enhanceLanguage !== void 0) autonomy.enhanceLanguage = s.enhanceLanguage;
|
|
37952
38138
|
if (s.midRunSendPicker !== void 0) autonomy.midRunSendPicker = s.midRunSendPicker;
|
|
38139
|
+
if (s.shellBangWarningDontShowAgain !== void 0)
|
|
38140
|
+
autonomy.shellBangWarningDontShowAgain = s.shellBangWarningDontShowAgain;
|
|
37953
38141
|
if (s.statuslineMode !== void 0) autonomy.statuslineMode = s.statuslineMode;
|
|
37954
38142
|
if (s.thinkingWord !== void 0)
|
|
37955
38143
|
autonomy.thinkingWord = normalizeTuiThinkingWord(s.thinkingWord);
|
|
@@ -38787,11 +38975,37 @@ ${color.dim(taskList2)}
|
|
|
38787
38975
|
}
|
|
38788
38976
|
continue;
|
|
38789
38977
|
}
|
|
38790
|
-
|
|
38791
|
-
|
|
38792
|
-
|
|
38793
|
-
|
|
38978
|
+
if (detectContinueIntent(trimmed)) {
|
|
38979
|
+
const resolved = resolveContinuation({
|
|
38980
|
+
todos: opts.agent.ctx.todos,
|
|
38981
|
+
suggestions: getSuggestions()
|
|
38982
|
+
});
|
|
38983
|
+
if (resolved.source === "open") {
|
|
38984
|
+
opts.renderer.write(
|
|
38985
|
+
` ${color.amber("\u26A0")} ${color.bold("'continue' has no anchor")} ${color.dim("\u2014 no pending todo or suggestion.")}
|
|
38986
|
+
` + color.dim(" If you proceed, I'll choose the next step from context; that can drift.\n")
|
|
38987
|
+
);
|
|
38988
|
+
const ans = (await opts.reader.readLine(color.dim(" Proceed anyway? [Y/n \xB7 e = type your own] "))).trim().toLowerCase();
|
|
38989
|
+
if (ans === "n" || ans === "no") {
|
|
38990
|
+
opts.renderer.write(color.dim(" Cancelled \u2014 nothing sent.\n"));
|
|
38991
|
+
continue;
|
|
38992
|
+
}
|
|
38993
|
+
if (ans === "e" || ans === "edit") {
|
|
38994
|
+
opts.renderer.write(color.dim(" Okay \u2014 type what to continue with.\n"));
|
|
38995
|
+
continue;
|
|
38996
|
+
}
|
|
38997
|
+
} else {
|
|
38998
|
+
opts.renderer.write(color.dim(` ${resolved.label}
|
|
38999
|
+
`));
|
|
39000
|
+
}
|
|
39001
|
+
builder.appendText(resolved.text);
|
|
39002
|
+
} else {
|
|
39003
|
+
const ph = await builder.appendPaste(raw);
|
|
39004
|
+
if (ph) {
|
|
39005
|
+
const lineCount = raw.split("\n").length;
|
|
39006
|
+
opts.renderer.write(color.dim(` \u21B3 ${ph} (${lineCount} lines)
|
|
38794
39007
|
`));
|
|
39008
|
+
}
|
|
38795
39009
|
}
|
|
38796
39010
|
const blocks = await builder.submit();
|
|
38797
39011
|
const sddContext = getActiveSDDContext();
|
|
@@ -39347,6 +39561,16 @@ async function execute(deps) {
|
|
|
39347
39561
|
saveStatuslineHiddenItems,
|
|
39348
39562
|
getPluginItems,
|
|
39349
39563
|
onPluginToggle,
|
|
39564
|
+
getMcpServers,
|
|
39565
|
+
onMcpToggle,
|
|
39566
|
+
onMcpRestart,
|
|
39567
|
+
getToolsItems,
|
|
39568
|
+
onToolToggle,
|
|
39569
|
+
getBrainData,
|
|
39570
|
+
onBrainRiskLevel,
|
|
39571
|
+
getShadowData,
|
|
39572
|
+
onShadowStart,
|
|
39573
|
+
onShadowStop,
|
|
39350
39574
|
authHost,
|
|
39351
39575
|
agentsMonitorController,
|
|
39352
39576
|
onPanelOpen,
|
|
@@ -39833,6 +40057,16 @@ async function execute(deps) {
|
|
|
39833
40057
|
saveStatuslineHiddenItems,
|
|
39834
40058
|
getPluginItems,
|
|
39835
40059
|
onPluginToggle,
|
|
40060
|
+
getMcpServers,
|
|
40061
|
+
onMcpToggle,
|
|
40062
|
+
onMcpRestart,
|
|
40063
|
+
getToolsItems,
|
|
40064
|
+
onToolToggle,
|
|
40065
|
+
getBrainData,
|
|
40066
|
+
onBrainRiskLevel,
|
|
40067
|
+
getShadowData,
|
|
40068
|
+
onShadowStart,
|
|
40069
|
+
onShadowStop,
|
|
39836
40070
|
authHost,
|
|
39837
40071
|
agentsMonitorController,
|
|
39838
40072
|
getLiveSessions: () => getLiveSessions({ state }),
|
|
@@ -42841,9 +43075,11 @@ function wireEventWiring(deps) {
|
|
|
42841
43075
|
evOn("provider.fallback", (p) => {
|
|
42842
43076
|
if (!isCurrentSession(p.sessionId)) return;
|
|
42843
43077
|
stopSpinnerAndStreaming();
|
|
43078
|
+
const contextWarning = p.contextWindowWarning ? ` \u26A0 smaller context window: ${p.contextWindowWarning.fromMaxContext.toLocaleString("en-US")} \u2192 ${p.contextWindowWarning.toMaxContext.toLocaleString("en-US")} tokens${p.contextWindowWarning.currentTokens ? `; current request \u2248 ${p.contextWindowWarning.currentTokens.toLocaleString("en-US")} tokens (${Math.round(p.contextWindowWarning.currentTokens / p.contextWindowWarning.toMaxContext * 100)}% of new window)` : ""}
|
|
43079
|
+
` : "";
|
|
42844
43080
|
writeErr(
|
|
42845
43081
|
color.yellow(` \u21BB rate-limited (${p.status}) \u2014 switched to ${p.to.providerId}/${p.to.model}
|
|
42846
|
-
`)
|
|
43082
|
+
${contextWarning}`)
|
|
42847
43083
|
);
|
|
42848
43084
|
spinner.start(color.dim(`${p.to.providerId}/${p.to.model} thinking\u2026`));
|
|
42849
43085
|
});
|
|
@@ -44982,6 +45218,22 @@ Restart WrongStack to load or unload plugin code in this session.`;
|
|
|
44982
45218
|
error: result.code === 0 ? void 0 : result.message
|
|
44983
45219
|
};
|
|
44984
45220
|
};
|
|
45221
|
+
const getToolPickerItems = () => {
|
|
45222
|
+
const rows = [...toolRegistry.listWithOwner(), ...toolRegistry.listDisabled()];
|
|
45223
|
+
return rows.map(({ tool, owner }) => {
|
|
45224
|
+
const descMode = getToolDescriptionMode(toolRegistry, tool.name);
|
|
45225
|
+
return {
|
|
45226
|
+
name: tool.name,
|
|
45227
|
+
owner,
|
|
45228
|
+
category: tool.category ?? "Other",
|
|
45229
|
+
enabled: !toolRegistry.isDisabled(tool.name),
|
|
45230
|
+
mutating: tool.mutating,
|
|
45231
|
+
permission: tool.permission,
|
|
45232
|
+
descMode,
|
|
45233
|
+
description: tool.description
|
|
45234
|
+
};
|
|
45235
|
+
});
|
|
45236
|
+
};
|
|
44985
45237
|
const savedProviderCfg = config.providers?.[config.provider];
|
|
44986
45238
|
return execute({
|
|
44987
45239
|
agent,
|
|
@@ -45045,6 +45297,89 @@ Restart WrongStack to load or unload plugin code in this session.`;
|
|
|
45045
45297
|
saveStatuslineHiddenItems,
|
|
45046
45298
|
getPluginItems: getPluginPickerItems,
|
|
45047
45299
|
onPluginToggle: togglePluginFromPicker,
|
|
45300
|
+
getMcpServers: () => {
|
|
45301
|
+
const servers = config.mcpServers ?? {};
|
|
45302
|
+
const liveStatus = mcpRegistry.list();
|
|
45303
|
+
const liveMap = new Map(liveStatus.map((s) => [s.name, s]));
|
|
45304
|
+
return Object.entries(servers).map(([name, cfg]) => {
|
|
45305
|
+
const live = liveMap.get(name);
|
|
45306
|
+
return {
|
|
45307
|
+
name,
|
|
45308
|
+
enabled: cfg.enabled !== false,
|
|
45309
|
+
status: live ? live.state : "stopped",
|
|
45310
|
+
transport: cfg.transport ?? "stdio",
|
|
45311
|
+
description: cfg.description,
|
|
45312
|
+
toolCount: live?.toolCount ?? 0,
|
|
45313
|
+
lazy: cfg.lazy
|
|
45314
|
+
};
|
|
45315
|
+
});
|
|
45316
|
+
},
|
|
45317
|
+
onMcpToggle: async (name) => {
|
|
45318
|
+
const { enableMcp, disableMcp, listMcp } = await import('@wrongstack/mcp');
|
|
45319
|
+
const deps = { configPath: wpaths.globalConfig, registry: mcpRegistry, presets: allServers$1() };
|
|
45320
|
+
const live = mcpRegistry.list().find((s) => s.name === name);
|
|
45321
|
+
const isCurrentlyEnabled = live !== void 0 && live.state !== "idle";
|
|
45322
|
+
const result = isCurrentlyEnabled ? await disableMcp(name, deps) : await enableMcp(name, deps);
|
|
45323
|
+
const items = await listMcp(deps);
|
|
45324
|
+
return {
|
|
45325
|
+
items: items.map((s) => ({ name: s.name, enabled: s.enabled, status: s.status, transport: s.transport, description: s.description, toolCount: s.tools.length, lazy: s.lazy })),
|
|
45326
|
+
message: result.ok ? result.server ? `${result.server.status === "connected" ? "\u25CF" : "\u25CB"} ${name}` : result.message : void 0,
|
|
45327
|
+
error: result.ok ? void 0 : result.message
|
|
45328
|
+
};
|
|
45329
|
+
},
|
|
45330
|
+
onMcpRestart: async (name) => {
|
|
45331
|
+
const { listMcp } = await import('@wrongstack/mcp');
|
|
45332
|
+
const deps = { configPath: wpaths.globalConfig, registry: mcpRegistry, presets: allServers$1() };
|
|
45333
|
+
try {
|
|
45334
|
+
await mcpRegistry.restart(name);
|
|
45335
|
+
} catch (err) {
|
|
45336
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
45337
|
+
const items2 = await listMcp(deps);
|
|
45338
|
+
return { items: items2.map((s) => ({ name: s.name, enabled: s.enabled, status: s.status, transport: s.transport, description: s.description, toolCount: s.tools.length, lazy: s.lazy })), message: void 0, error: message };
|
|
45339
|
+
}
|
|
45340
|
+
const items = await listMcp(deps);
|
|
45341
|
+
return { items: items.map((s) => ({ name: s.name, enabled: s.enabled, status: s.status, transport: s.transport, description: s.description, toolCount: s.tools.length, lazy: s.lazy })), message: `Restarted "${name}".`, error: void 0 };
|
|
45342
|
+
},
|
|
45343
|
+
getToolsItems: getToolPickerItems,
|
|
45344
|
+
onToolToggle: async (name) => {
|
|
45345
|
+
const disabled = new Set(config.tools?.disabledTools ?? []);
|
|
45346
|
+
const isCurrentlyDisabled = toolRegistry.isDisabled(name);
|
|
45347
|
+
if (isCurrentlyDisabled) {
|
|
45348
|
+
toolRegistry.enable(name);
|
|
45349
|
+
disabled.delete(name);
|
|
45350
|
+
} else {
|
|
45351
|
+
toolRegistry.disable(name);
|
|
45352
|
+
disabled.add(name);
|
|
45353
|
+
}
|
|
45354
|
+
const nextTools = { ...config.tools ?? {}, disabledTools: Array.from(disabled) };
|
|
45355
|
+
config = patchConfig(config, { tools: nextTools });
|
|
45356
|
+
configStore.update({ tools: nextTools });
|
|
45357
|
+
return {
|
|
45358
|
+
items: getToolPickerItems(),
|
|
45359
|
+
message: isCurrentlyDisabled ? `Enabled "${name}".` : `Disabled "${name}".`,
|
|
45360
|
+
error: void 0
|
|
45361
|
+
};
|
|
45362
|
+
},
|
|
45363
|
+
getBrainData: () => {
|
|
45364
|
+
const ceiling = brainSettings?.maxAutoRisk ?? "medium";
|
|
45365
|
+
const log = brainLog.slice(-20).map((entry) => ({
|
|
45366
|
+
kind: entry.kind,
|
|
45367
|
+
question: entry.question,
|
|
45368
|
+
outcome: entry.outcome,
|
|
45369
|
+
age: typeof entry.at === "number" ? (() => {
|
|
45370
|
+
const s = Math.max(0, Math.round((Date.now() - entry.at) / 1e3));
|
|
45371
|
+
if (s < 60) return `${s}s`;
|
|
45372
|
+
if (s < 3600) return `${Math.round(s / 60)}m`;
|
|
45373
|
+
return `${Math.round(s / 3600)}h`;
|
|
45374
|
+
})() : ""
|
|
45375
|
+
}));
|
|
45376
|
+
return { riskLevel: ceiling, log };
|
|
45377
|
+
},
|
|
45378
|
+
onBrainRiskLevel: (level) => {
|
|
45379
|
+
if (!brainSettings) return "Brain settings not available.";
|
|
45380
|
+
brainSettings.maxAutoRisk = level;
|
|
45381
|
+
return void 0;
|
|
45382
|
+
},
|
|
45048
45383
|
// Interactive /auth panel host — provider/key CRUD, catalog/local adds
|
|
45049
45384
|
// and OAuth sign-in, all executed CLI-side against the encrypted config
|
|
45050
45385
|
// (secrets never enter the TUI; key values arrive pre-masked).
|