@wrongstack/cli 0.10.3 → 0.31.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import * as path24 from 'path';
3
3
  import * as fsp3 from 'fs/promises';
4
- import { color, DefaultPathResolver, TOKENS, DefaultSystemPromptBuilder, makeAutonomyPromptContributor, ToolRegistry, createContextManagerTool, EventBus, SlashCommandRegistry, createDelegateTool, FLEET_ROSTER, createMcpControlTool, EternalAutonomyEngine, DefaultLogger, DefaultModelsRegistry, runProviderWithRetry, ReplayLogStore, ReplayProviderRunner, ProviderRegistry, InMemoryMetricsSink, wireMetricsToEvents, DefaultHealthRegistry, startMetricsServer, RecoveryLock, DefaultAttachmentStore, QueueStore, Context, loadTodosCheckpoint, attachTodosCheckpoint, loadDirectorState, loadPlan, createDefaultPipelines, AutoCompactionMiddleware, estimateRequestTokens, Agent, loadPlugins, FleetManager, makeDirectorSessionFactory, Director, makeFleetEmitTool, makeFleetStatusTool, AutoApprovePermissionPolicy, PhaseStore, AutoPhasePlanner, PhaseGraphBuilder, WorktreeManager, PhaseOrchestrator, makeLLMClassifier, resolveWstackPaths, DefaultSecretVault, migratePlaintextSecrets, DefaultConfigLoader, DefaultSessionReader, ToolAuditLog, DefaultSessionRewinder, DefaultSessionStore, atomicWrite, DefaultPluginAPI, makeAgentSubagentRunner, NULL_FLEET_BUS, buildChildEnv, formatContextWindowModeList, repairToolUseAdjacency, getContextWindowMode, resolveContextWindowPolicy, AGENTS_BY_PHASE, dispatchAgent, formatTodosList, SpecStore, TaskGraphStore, analyzeCriticalPath, getTemplate, listTemplates, templateToMarkdown, SpecParser, renderSpecAnalysis, AISpecBuilder, DefaultTaskStore, TaskTracker, renderProgress, renderTaskGraph, SessionRecovery, loadGoal, goalFilePath, summarizeUsage, saveGoal, emptyGoal, buildGoalPreamble, formatGoal, pendingBtwCount, setBtwNote, decryptConfigSecrets, encryptConfigSecrets as encryptConfigSecrets$1, InputBuilder, FsError, ERROR_CODES, SpecVersioning, ParallelEternalEngine, allServers as allServers$1 } from '@wrongstack/core';
4
+ import { color, DefaultPathResolver, TOKENS, DefaultSystemPromptBuilder, makeAutonomyPromptContributor, ToolRegistry, createContextManagerTool, EventBus, SlashCommandRegistry, createDelegateTool, FLEET_ROSTER, createMcpControlTool, EternalAutonomyEngine, DefaultLogger, DefaultModelsRegistry, runProviderWithRetry, ReplayLogStore, ReplayProviderRunner, ProviderRegistry, InMemoryMetricsSink, wireMetricsToEvents, DefaultHealthRegistry, startMetricsServer, RecoveryLock, DefaultAttachmentStore, QueueStore, Context, loadTodosCheckpoint, attachTodosCheckpoint, loadDirectorState, loadPlan, createDefaultPipelines, AutoCompactionMiddleware, estimateRequestTokensCalibrated, Agent, loadPlugins, FleetManager, makeDirectorSessionFactory, Director, makeFleetEmitTool, makeFleetStatusTool, AutoApprovePermissionPolicy, PhaseStore, AutoPhasePlanner, PhaseGraphBuilder, WorktreeManager, PhaseOrchestrator, makeLLMClassifier, resolveWstackPaths, DefaultSecretVault, migratePlaintextSecrets, DefaultConfigLoader, DefaultSessionReader, ToolAuditLog, DefaultSessionRewinder, DefaultSessionStore, atomicWrite, DefaultPluginAPI, makeAgentSubagentRunner, NULL_FLEET_BUS, buildChildEnv, formatContextWindowModeList, repairToolUseAdjacency, getContextWindowMode, resolveContextWindowPolicy, AGENTS_BY_PHASE, dispatchAgent, formatTodosList, SpecStore, TaskGraphStore, analyzeCriticalPath, getTemplate, listTemplates, templateToMarkdown, SpecParser, renderSpecAnalysis, AISpecBuilder, DefaultTaskStore, TaskTracker, renderProgress, renderTaskGraph, SessionRecovery, loadGoal, goalFilePath, summarizeUsage, saveGoal, emptyGoal, buildGoalPreamble, formatGoal, pendingBtwCount, setBtwNote, decryptConfigSecrets, encryptConfigSecrets as encryptConfigSecrets$1, InputBuilder, FsError, ERROR_CODES, SpecVersioning, ParallelEternalEngine, allServers as allServers$1 } from '@wrongstack/core';
5
5
  import { createRequire } from 'module';
6
6
  import * as os3 from 'os';
7
7
  import os3__default from 'os';
@@ -4127,6 +4127,55 @@ function buildBtwCommand(opts) {
4127
4127
  }
4128
4128
  };
4129
4129
  }
4130
+ function buildNextCommand(opts) {
4131
+ return {
4132
+ name: "next",
4133
+ description: "Toggle next-task prediction \u2014 show likely next steps after each turn.",
4134
+ argsHint: "[on|off|toggle]",
4135
+ help: [
4136
+ "Usage:",
4137
+ " /next Show whether next-task prediction is on or off",
4138
+ " /next on Enable \u2014 after each turn, show 1-3 predicted next steps",
4139
+ " /next off Disable (default)",
4140
+ " /next toggle Flip the current state",
4141
+ "",
4142
+ "Predictions are informational only. They come from a cheap single-shot",
4143
+ "model call (no tools, no context replay) and are never run automatically \u2014",
4144
+ "copy or retype one to act on it. The setting persists across sessions."
4145
+ ].join("\n"),
4146
+ async run(args) {
4147
+ if (!opts.onNextPredict) {
4148
+ const msg2 = "Next-task prediction is not available in this session.";
4149
+ opts.renderer.writeWarning(msg2);
4150
+ return { message: msg2 };
4151
+ }
4152
+ const arg = args.trim().toLowerCase();
4153
+ const current = opts.onNextPredict();
4154
+ const label = (on) => on ? `${color.cyan("ON")} ${color.dim("(predicted next steps shown after each turn)")}` : `${color.green("OFF")} ${color.dim("(no predictions)")}`;
4155
+ if (!arg || arg === "status") {
4156
+ const msg2 = `Next-task prediction: ${label(current)}`;
4157
+ opts.renderer.write(msg2);
4158
+ return { message: msg2 };
4159
+ }
4160
+ let target;
4161
+ if (arg === "on" || arg === "enable" || arg === "true") {
4162
+ target = true;
4163
+ } else if (arg === "off" || arg === "disable" || arg === "false") {
4164
+ target = false;
4165
+ } else if (arg === "toggle" || arg === "cycle") {
4166
+ target = !current;
4167
+ } else {
4168
+ const msg2 = `Unknown argument: ${arg}. Use /next on, off, or toggle.`;
4169
+ opts.renderer.writeWarning(msg2);
4170
+ return { message: msg2 };
4171
+ }
4172
+ const now = opts.onNextPredict(target);
4173
+ const msg = `Next-task prediction: ${label(now)}`;
4174
+ opts.renderer.write(msg);
4175
+ return { message: msg };
4176
+ }
4177
+ };
4178
+ }
4130
4179
  var KNOWN_VERBS = /* @__PURE__ */ new Set([
4131
4180
  "",
4132
4181
  "show",
@@ -5876,6 +5925,7 @@ function buildBuiltinSlashCommands(opts) {
5876
5925
  buildAutonomyCommand(opts),
5877
5926
  buildGoalCommand(opts),
5878
5927
  buildBtwCommand(opts),
5928
+ buildNextCommand(opts),
5879
5929
  buildModeCommand(opts),
5880
5930
  buildExitCommand(opts),
5881
5931
  buildFixCommand(opts),
@@ -9708,22 +9758,22 @@ function fmtDuration(ms) {
9708
9758
  const remMin = m - h * 60;
9709
9759
  return `${h}h${remMin}m`;
9710
9760
  }
9711
- function fmtTaskResultLine(r, color41) {
9761
+ function fmtTaskResultLine(r, color42) {
9712
9762
  const stats = `${r.iterations}it ${r.toolCalls}tc ${fmtDuration(r.durationMs)}`;
9713
9763
  const errMsg = typeof r.error === "string" ? r.error : r.error?.message;
9714
9764
  const errKind = typeof r.error === "object" ? r.error?.kind : void 0;
9715
9765
  const errTail = errMsg ? ` \u2014 ${errMsg.replace(/\s+/g, " ").slice(0, 80)}${errMsg.length > 80 ? "\u2026" : ""}` : "";
9716
- const errKindChip = errKind ? color41.dim(` [${errKind}]`) : "";
9717
- const errSnip = errMsg || errKind ? `${errKindChip}${color41.dim(errTail)}` : "";
9766
+ const errKindChip = errKind ? color42.dim(` [${errKind}]`) : "";
9767
+ const errSnip = errMsg || errKind ? `${errKindChip}${color42.dim(errTail)}` : "";
9718
9768
  switch (r.status) {
9719
9769
  case "success":
9720
- return { mark: color41.green("\u2713"), stats, tail: "" };
9770
+ return { mark: color42.green("\u2713"), stats, tail: "" };
9721
9771
  case "timeout":
9722
- return { mark: color41.yellow("\u23F1"), stats: `${color41.yellow("timeout")} ${stats}`, tail: errSnip };
9772
+ return { mark: color42.yellow("\u23F1"), stats: `${color42.yellow("timeout")} ${stats}`, tail: errSnip };
9723
9773
  case "stopped":
9724
- return { mark: color41.dim("\u2298"), stats: `${color41.dim("stopped")} ${stats}`, tail: errSnip };
9774
+ return { mark: color42.dim("\u2298"), stats: `${color42.dim("stopped")} ${stats}`, tail: errSnip };
9725
9775
  case "failed":
9726
- return { mark: color41.red("\u2717"), stats: `${color41.red("failed")} ${stats}`, tail: errSnip };
9776
+ return { mark: color42.red("\u2717"), stats: `${color42.red("failed")} ${stats}`, tail: errSnip };
9727
9777
  }
9728
9778
  }
9729
9779
 
@@ -10140,7 +10190,88 @@ var FleetStatusLine = class {
10140
10190
  }
10141
10191
  };
10142
10192
 
10143
- // src/repl.ts
10193
+ // src/next-task-predictor.ts
10194
+ var SYSTEM_PROMPT = `You predict the developer's most likely NEXT actions in a coding session. Given what they just asked and what the assistant just did, output the 1-3 most probable next steps. Each must be a concrete, actionable task phrased as an imperative the user could hand back to the assistant (e.g. "Add tests for the new parser", "Wire the command into the CLI"). Output ONLY a numbered list, one step per line, no preamble, no explanation. Prefer steps that follow naturally from unfinished todos or obvious gaps. If there is genuinely nothing meaningful left to do, output exactly: NONE`;
10195
+ var MAX_REQUEST_CHARS = 1200;
10196
+ var MAX_SUMMARY_CHARS = 1200;
10197
+ function clamp(text, n) {
10198
+ const t = text.trim();
10199
+ return t.length <= n ? t : `${t.slice(0, n)}\u2026`;
10200
+ }
10201
+ function buildPredictionPrompt(input) {
10202
+ const parts = [];
10203
+ parts.push(`The user asked:
10204
+ ${clamp(input.userRequest, MAX_REQUEST_CHARS) || "(no text)"}`);
10205
+ if (input.assistantSummary.trim()) {
10206
+ parts.push(
10207
+ `The assistant just finished and reported:
10208
+ ${clamp(input.assistantSummary, MAX_SUMMARY_CHARS)}`
10209
+ );
10210
+ }
10211
+ const pending = input.todos.filter((t) => t.status !== "completed");
10212
+ if (pending.length > 0) {
10213
+ const list = pending.slice(0, 8).map((t) => `- [${t.status}] ${t.content}`).join("\n");
10214
+ parts.push(`Open todo items:
10215
+ ${list}`);
10216
+ }
10217
+ parts.push("Predict the 1-3 most likely next steps.");
10218
+ return parts.join("\n\n");
10219
+ }
10220
+ function parsePredictions(raw, max = 3) {
10221
+ const text = raw.trim();
10222
+ if (!text) return [];
10223
+ if (/^none\b/i.test(text) || /no further steps/i.test(text)) return [];
10224
+ const out = [];
10225
+ for (const lineRaw of text.split("\n")) {
10226
+ const line = lineRaw.trim();
10227
+ if (!line) continue;
10228
+ const stripped = line.replace(/^\s*(?:\d+[.)]|[-*•])\s+/, "").trim();
10229
+ const candidate = stripped || line;
10230
+ if (/^none$/i.test(candidate)) continue;
10231
+ if (candidate) out.push(candidate);
10232
+ if (out.length >= max) break;
10233
+ }
10234
+ return out;
10235
+ }
10236
+ function extractText(content) {
10237
+ if (Array.isArray(content)) {
10238
+ return content[0]?.text ?? "";
10239
+ }
10240
+ if (content && typeof content === "object") {
10241
+ return content.text ?? "";
10242
+ }
10243
+ return typeof content === "string" ? content : "";
10244
+ }
10245
+ async function predictNextTasks(input, opts) {
10246
+ const max = opts.maxPredictions ?? 3;
10247
+ const internal = new AbortController();
10248
+ const timeout = setTimeout(() => internal.abort(), 12e3);
10249
+ const onParentAbort = () => internal.abort();
10250
+ if (opts.signal) {
10251
+ if (opts.signal.aborted) internal.abort();
10252
+ else opts.signal.addEventListener("abort", onParentAbort, { once: true });
10253
+ }
10254
+ try {
10255
+ const resp = await opts.provider.complete(
10256
+ {
10257
+ model: opts.model,
10258
+ system: [{ type: "text", text: SYSTEM_PROMPT }],
10259
+ messages: [
10260
+ { role: "user", content: [{ type: "text", text: buildPredictionPrompt(input) }] }
10261
+ ],
10262
+ maxTokens: 160,
10263
+ temperature: 0.3
10264
+ },
10265
+ { signal: internal.signal }
10266
+ );
10267
+ return parsePredictions(extractText(resp.content), max);
10268
+ } catch {
10269
+ return [];
10270
+ } finally {
10271
+ clearTimeout(timeout);
10272
+ if (opts.signal) opts.signal.removeEventListener("abort", onParentAbort);
10273
+ }
10274
+ }
10144
10275
  init_sdd();
10145
10276
  async function runRepl(opts) {
10146
10277
  if (opts.banner !== false) printBanner(opts.renderer, opts.projectName);
@@ -10289,6 +10420,13 @@ async function runRepl(opts) {
10289
10420
  activeCtrl = runCtrl2;
10290
10421
  try {
10291
10422
  const runResult = await opts.agent.run(runBlocks, { signal: runCtrl2.signal });
10423
+ opts.onAgentIterationComplete?.(
10424
+ estimateRequestTokensCalibrated(
10425
+ opts.agent.ctx.messages,
10426
+ opts.agent.ctx.systemPrompt,
10427
+ opts.agent.ctx.tools ?? []
10428
+ ).total
10429
+ );
10292
10430
  if (runResult.status === "done" && runResult.finalText) {
10293
10431
  const specSaved = await trySaveSpecFromAIOutput(runResult.finalText);
10294
10432
  if (specSaved) {
@@ -10418,6 +10556,13 @@ ${taskList}`;
10418
10556
  );
10419
10557
  }
10420
10558
  const result = await opts.agent.run(routed.blocks, { signal: runCtrl.signal });
10559
+ opts.onAgentIterationComplete?.(
10560
+ estimateRequestTokensCalibrated(
10561
+ opts.agent.ctx.messages,
10562
+ opts.agent.ctx.systemPrompt,
10563
+ opts.agent.ctx.tools ?? []
10564
+ ).total
10565
+ );
10421
10566
  if (result.status === "aborted") {
10422
10567
  opts.renderer.writeWarning("Aborted.");
10423
10568
  } else if (result.status === "failed") {
@@ -10516,6 +10661,13 @@ ${color.dim(
10516
10661
  activeCtrl = nextCtrl;
10517
10662
  try {
10518
10663
  const nextResult = await opts.agent.run(nextBlocks, { signal: nextCtrl.signal });
10664
+ opts.onAgentIterationComplete?.(
10665
+ estimateRequestTokensCalibrated(
10666
+ opts.agent.ctx.messages,
10667
+ opts.agent.ctx.systemPrompt,
10668
+ opts.agent.ctx.tools ?? []
10669
+ ).total
10670
+ );
10519
10671
  if (nextResult.status === "done" && nextResult.finalText?.trim() === "DONE") {
10520
10672
  opts.renderer.write(color.dim("\n \u21B3 [autonomy] agent reports task complete.\n"));
10521
10673
  }
@@ -10535,6 +10687,13 @@ ${color.dim(
10535
10687
  activeCtrl = suggestCtrl;
10536
10688
  try {
10537
10689
  const suggestResult = await opts.agent.run(suggestBlocks, { signal: suggestCtrl.signal });
10690
+ opts.onAgentIterationComplete?.(
10691
+ estimateRequestTokensCalibrated(
10692
+ opts.agent.ctx.messages,
10693
+ opts.agent.ctx.systemPrompt,
10694
+ opts.agent.ctx.tools ?? []
10695
+ ).total
10696
+ );
10538
10697
  if (suggestResult.status === "done" && suggestResult.finalText) {
10539
10698
  opts.renderer.write(
10540
10699
  `
@@ -10549,6 +10708,37 @@ ${suggestResult.finalText}
10549
10708
  }
10550
10709
  }
10551
10710
  }
10711
+ if (result.status === "done" && opts.getNextPredict?.()) {
10712
+ const autonomy = opts.getAutonomy?.() ?? "off";
10713
+ if (autonomy === "off") {
10714
+ const predictCtrl = new AbortController();
10715
+ activeCtrl = predictCtrl;
10716
+ try {
10717
+ const predictions = await predictNextTasks(
10718
+ {
10719
+ userRequest: trimmed,
10720
+ assistantSummary: result.finalText ?? "",
10721
+ todos: opts.agent.ctx.todos
10722
+ },
10723
+ {
10724
+ provider: opts.agent.ctx.provider,
10725
+ model: opts.agent.ctx.model,
10726
+ signal: predictCtrl.signal
10727
+ }
10728
+ );
10729
+ if (predictions.length > 0) {
10730
+ const lines = predictions.map((p, i) => ` ${i + 1}. ${p}`).join("\n");
10731
+ opts.renderer.write(`
10732
+ ${color.dim(" \u21B3 likely next:")}
10733
+ ${color.dim(lines)}
10734
+ `);
10735
+ }
10736
+ } catch {
10737
+ } finally {
10738
+ activeCtrl = void 0;
10739
+ }
10740
+ }
10741
+ }
10552
10742
  } catch (err) {
10553
10743
  opts.renderer.writeError(err instanceof Error ? err.message : String(err));
10554
10744
  } finally {
@@ -10731,6 +10921,7 @@ async function execute(deps) {
10731
10921
  getYolo,
10732
10922
  getAutonomy,
10733
10923
  onAutonomy,
10924
+ getNextPredict,
10734
10925
  getEternalEngine,
10735
10926
  getParallelEngine,
10736
10927
  subscribeEternalIteration,
@@ -10888,6 +11079,20 @@ async function execute(deps) {
10888
11079
  yolo: !!config.yolo,
10889
11080
  getYolo,
10890
11081
  getAutonomy,
11082
+ // Next-task prediction (/next). Host owns the gating: returns [] when
11083
+ // the toggle is off or autonomy is self-driving, so the TUI can call
11084
+ // this unconditionally after a done turn. Display-only.
11085
+ predictNext: async (input) => {
11086
+ if (!getNextPredict?.()) return [];
11087
+ if ((getAutonomy?.() ?? "off") !== "off") return [];
11088
+ return predictNextTasks(
11089
+ { ...input, todos: context.todos },
11090
+ {
11091
+ provider: context.provider,
11092
+ model: context.model
11093
+ }
11094
+ );
11095
+ },
10891
11096
  getEternalEngine,
10892
11097
  subscribeEternalIteration,
10893
11098
  subscribeEternalStage,
@@ -10932,13 +11137,11 @@ async function execute(deps) {
10932
11137
  // resize/overlay-leak artifacts can opt back into alt-screen with
10933
11138
  // `--alt-screen`. `--no-alt-screen` still wins when both are passed.
10934
11139
  altScreen: flags["alt-screen"] === true && flags["no-alt-screen"] !== true,
10935
- // Full mouse mode: clickable pickers + in-app wheel scroll. Opt-in
10936
- // via --mouse. The TUI combines altScreen || mouse to determine
10937
- // whether to use the managed viewport (ScrollableHistory + in-app
10938
- // scroll); --mouse alone enables that without requiring --alt-screen.
10939
- // Mouse mode takes ownership of the terminal's mouse, suspending
10940
- // native scroll/copy until `/mouse off`.
10941
- mouse: flags.mouse === true,
11140
+ // Mouse mode is DISABLED. It was unreliable on Windows consoles
11141
+ // (freezes / constant repaint in the managed viewport) and is not
11142
+ // wanted, so `--mouse` is intentionally ignored and never engages —
11143
+ // the TUI stays keyboard-only. Do not re-wire `flags.mouse` here.
11144
+ mouse: false,
10942
11145
  director,
10943
11146
  fleetRoster,
10944
11147
  onAfterExit: () => {
@@ -11016,11 +11219,15 @@ async function execute(deps) {
11016
11219
  projectRoot,
11017
11220
  getAutonomy,
11018
11221
  onAutonomy,
11222
+ getNextPredict,
11019
11223
  getEternalEngine,
11020
11224
  getParallelEngine,
11021
11225
  skillLoader,
11022
11226
  agentsMonitorController,
11023
- fleetStreamController
11227
+ fleetStreamController,
11228
+ // Report context pressure to the Director after each iteration so
11229
+ // the spawn pre-check (maxLeaderContextLoad) stays accurate.
11230
+ onAgentIterationComplete: director ? (tokens) => director.setLeaderContextPressure(tokens) : void 0
11024
11231
  });
11025
11232
  } finally {
11026
11233
  await webuiPromise.catch(() => void 0);
@@ -11039,11 +11246,13 @@ async function execute(deps) {
11039
11246
  projectName: path24.basename(projectRoot) || void 0,
11040
11247
  getAutonomy,
11041
11248
  onAutonomy,
11249
+ getNextPredict,
11042
11250
  getEternalEngine,
11043
11251
  getParallelEngine,
11044
11252
  skillLoader,
11045
11253
  agentsMonitorController,
11046
- fleetStreamController
11254
+ fleetStreamController,
11255
+ onAgentIterationComplete: director ? (tokens) => director.setLeaderContextPressure(tokens) : void 0
11047
11256
  });
11048
11257
  }
11049
11258
  } finally {
@@ -12221,9 +12430,9 @@ async function setupCompaction(params) {
12221
12430
  autoCompactor = new AutoCompactionMiddleware(
12222
12431
  compactor,
12223
12432
  effectiveMaxContext,
12224
- // Use the full API request estimator: messages + system prompt + tool definitions.
12225
- // This matches what the provider actually counts as input tokens.
12226
- (ctx) => estimateRequestTokens(ctx.messages, ctx.systemPrompt, ctx.tools ?? []).total,
12433
+ // Calibrated estimator: recordActualUsage() is called after each API
12434
+ // response so this converges on real token counts for compaction decisions.
12435
+ (ctx) => estimateRequestTokensCalibrated(ctx.messages, ctx.systemPrompt, ctx.tools ?? []).total,
12227
12436
  {
12228
12437
  warn: config.context.warnThreshold,
12229
12438
  soft: config.context.softThreshold,
@@ -13017,6 +13226,7 @@ async function main(argv) {
13017
13226
  return "off";
13018
13227
  })();
13019
13228
  autonomyModeRef.current = autonomyMode;
13229
+ let nextPredictEnabled = config.nextPrediction === true;
13020
13230
  let eternalEngine = null;
13021
13231
  let parallelEngine = null;
13022
13232
  const eternalListeners = /* @__PURE__ */ new Set();
@@ -13608,6 +13818,14 @@ Restart WrongStack to load or unload plugin code in this session.`;
13608
13818
  }
13609
13819
  return policy.getYolo();
13610
13820
  },
13821
+ onNextPredict: (setTo) => {
13822
+ if (setTo !== void 0) {
13823
+ nextPredictEnabled = setTo;
13824
+ config = patchConfig(config, { nextPrediction: setTo });
13825
+ return setTo;
13826
+ }
13827
+ return nextPredictEnabled;
13828
+ },
13611
13829
  onAutonomy: (setTo) => {
13612
13830
  if (setTo !== void 0) {
13613
13831
  autonomyMode = setTo;
@@ -13838,6 +14056,7 @@ Restart WrongStack to load or unload plugin code in this session.`;
13838
14056
  }
13839
14057
  return autonomyMode;
13840
14058
  },
14059
+ getNextPredict: () => nextPredictEnabled,
13841
14060
  getEternalEngine: () => eternalEngine,
13842
14061
  getParallelEngine: () => parallelEngine,
13843
14062
  subscribeEternalIteration: (fn) => {