@wrongstack/cli 0.310.0 → 0.313.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.
Files changed (37) hide show
  1. package/dist/{acp-EA57GUFB.js → acp-LQMSMV32.js} +2 -2
  2. package/dist/chunk-4JRIWVJ4.js +13 -0
  3. package/dist/{chunk-63GFD62R.js → chunk-4S52MIIM.js} +2 -2
  4. package/dist/chunk-7CECQDNH.js +24 -0
  5. package/dist/chunk-AOAIPYFB.js +58 -0
  6. package/dist/{chunk-CHZZEEIP.js → chunk-CNQZ4HG4.js} +40 -9
  7. package/dist/{chunk-KQNYSZG2.js → chunk-E3X4KM7T.js} +6 -3
  8. package/dist/chunk-GWVLRUVH.js +120 -0
  9. package/dist/{cli-main-RFEZAJ4U.js → cli-main-BFUSCWXE.js} +228 -50
  10. package/dist/{diag-doctor-HJKFUY6B.js → diag-doctor-OPTB2NWY.js} +61 -3
  11. package/dist/{execution-WA2UCXNM.js → execution-TOBPK6MD.js} +109 -19
  12. package/dist/execution-chimera-cascade.d.ts +4 -1
  13. package/dist/execution-chimera-review.d.ts +4 -1
  14. package/dist/fleet/host-types.d.ts +9 -0
  15. package/dist/fleet/subagent-hook-runner.d.ts +22 -0
  16. package/dist/{hq-AG4VW4XO.js → hq-2XIXGAER.js} +2 -2
  17. package/dist/{hq-server-GZGM4BHA.js → hq-server-DBT3OOYD.js} +2 -2
  18. package/dist/index.js +16 -15
  19. package/dist/live-settings-input.d.ts +15 -1
  20. package/dist/proxy-wiring-G26YGP7S.js +15 -0
  21. package/dist/subcommands/contracts.d.ts +7 -0
  22. package/dist/subcommands/handlers/diag-doctor.d.ts +14 -0
  23. package/dist/{update-RATFF63M.js → update-ZXNC6I6G.js} +2 -2
  24. package/dist/webui-server/prefs-seeding.d.ts +4 -0
  25. package/dist/{webui-server-3DU6BVTB.js → webui-server-I53IYBW4.js} +8 -1
  26. package/dist/webui-server-options.d.ts +8 -0
  27. package/dist/wiring/provider-runtime.d.ts +25 -0
  28. package/dist/wiring/proxy-probe.d.ts +62 -0
  29. package/dist/wiring/proxy-wiring.d.ts +59 -0
  30. package/dist/wiring/wrongtrace-gate-counters.d.ts +18 -0
  31. package/dist/wiring/wrongtrace-gate.d.ts +13 -0
  32. package/dist/wiring/wrongtrace-hooks.d.ts +8 -0
  33. package/dist/wiring/wrongtrace-prompt-contributor.d.ts +23 -0
  34. package/dist/wiring/wrongtrace-telemetry.d.ts +53 -0
  35. package/dist/wrongtrace-gate-counters-P5BCBXQN.js +22 -0
  36. package/dist/wrongtrace-telemetry-6M2CCBX5.js +34 -0
  37. package/package.json +28 -27
@@ -9,9 +9,6 @@ import {
9
9
  setAutoSuggestions,
10
10
  setSuggestions
11
11
  } from "./chunk-X3N5TS2S.js";
12
- import {
13
- startCliHqConnection
14
- } from "./chunk-FKWHSFX4.js";
15
12
  import "./chunk-WHOIR577.js";
16
13
  import {
17
14
  advanceToNextTask,
@@ -26,17 +23,20 @@ import {
26
23
  trySaveSpecFromAIOutput,
27
24
  trySaveTasksFromAIOutput
28
25
  } from "./chunk-DGXNL7OT.js";
26
+ import {
27
+ startCliHqConnection
28
+ } from "./chunk-FKWHSFX4.js";
29
29
  import {
30
30
  theme
31
31
  } from "./chunk-QD544J2B.js";
32
+ import {
33
+ fmtTok
34
+ } from "./chunk-TYO2OVAD.js";
32
35
  import {
33
36
  WEBUI_SESSION_CHILD_CAPABILITIES,
34
37
  writeWebuiSessionChildError,
35
38
  writeWebuiSessionChildReady
36
39
  } from "./chunk-3JPTNADJ.js";
37
- import {
38
- fmtTok
39
- } from "./chunk-TYO2OVAD.js";
40
40
  import {
41
41
  terminalLink,
42
42
  terminalText
@@ -207,7 +207,7 @@ async function runWebUIDispatch(ctx) {
207
207
  const isSimpleUi = !isSessionChild && flags["simpleui"] === true;
208
208
  agent.disableInteractiveConfirmation();
209
209
  renderer.setSilent(true);
210
- const { runWebUI } = await import("./webui-server-3DU6BVTB.js");
210
+ const { runWebUI } = await import("./webui-server-I53IYBW4.js");
211
211
  const flagValue = (names) => {
212
212
  for (const name of names) {
213
213
  if (!Object.hasOwn(flags, name)) continue;
@@ -404,6 +404,11 @@ async function runWebUIDispatch(ctx) {
404
404
  },
405
405
  onYoloSwitch: (enabled) => {
406
406
  applyLiveSettings?.({ yolo: enabled });
407
+ },
408
+ onWrongProxyPrefsChange: (payload) => {
409
+ void import("./proxy-wiring-G26YGP7S.js").then(
410
+ ({ applyWrongProxyPrefs }) => applyWrongProxyPrefs(payload)
411
+ );
407
412
  }
408
413
  });
409
414
  const webuiExit = new Promise((resolve4) => {
@@ -1633,7 +1638,7 @@ function coerceAgentSwarmMode(v) {
1633
1638
  if (typeof v === "string" && (v === "bottom" || v === "sidebar" || v === "off")) return v;
1634
1639
  return "bottom";
1635
1640
  }
1636
- var ANIMATION_STYLES = ["rainbow", "wave", "pulse", "dots", "breathe", "cycle"];
1641
+ var ANIMATION_STYLES = ["rainbow", "wave", "pulse", "dots", "breathe", "static", "cycle"];
1637
1642
  function normalizeAnimationStyle(raw) {
1638
1643
  return typeof raw === "string" && ANIMATION_STYLES.includes(raw) ? raw : "rainbow";
1639
1644
  }
@@ -1716,12 +1721,23 @@ function createSettingsAdapter(ctx) {
1716
1721
  }),
1717
1722
  showSageMemoryInject: autonomy?.showSageMemoryInject ?? false,
1718
1723
  readSymbols: autonomy?.readAdvancedMode ?? false,
1719
- sageMemoryInjectThreshold: cfg.Sage?.inject ? cfg.Sage.inject?.relationFloor : void 0
1724
+ sageMemoryInjectThreshold: cfg.Sage?.inject ? cfg.Sage.inject?.relationFloor : void 0,
1725
+ // WrongProxy / WrongTrace: read from `tools.wrongProxy.{enabled,url}`
1726
+ // so the persistence shape mirrors the WebUI `LocalPrefs` shape
1727
+ // (single object with two fields, not two top-level keys). The
1728
+ // canonical type is `ToolsConfig.wrongProxy?: WrongProxyToolConfig`
1729
+ // — no index-signature widening cast needed.
1730
+ wrongProxyEnabled: cfg.tools?.wrongProxy?.enabled === true,
1731
+ wrongProxyUrl: cfg.tools?.wrongProxy?.url
1720
1732
  };
1721
1733
  }
1722
1734
  async function saveSettings(s) {
1723
1735
  try {
1724
- if (s.mode !== void 0 || s.delayMs !== void 0 || s.titleAnimation !== void 0 || s.yolo !== void 0 || s.fleetChatVerbosity !== 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.nextStepsTool !== 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 || s.breakerEnabled !== void 0 || s.breakerAutoKillResetMs !== void 0 || s.showModelReasoning !== void 0 || s.showAgentSwarmPanel !== void 0 || s.panelPositions !== void 0 || s.showSageMemoryInject !== void 0 || s.sageMemoryInjectThreshold !== void 0 || s.readSymbols !== void 0) {
1736
+ if (s.mode !== void 0 || s.delayMs !== void 0 || s.titleAnimation !== void 0 || s.yolo !== void 0 || s.fleetChatVerbosity !== 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.nextStepsTool !== 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 || s.breakerEnabled !== void 0 || s.breakerAutoKillResetMs !== void 0 || s.showModelReasoning !== void 0 || s.showAgentSwarmPanel !== void 0 || s.panelPositions !== void 0 || s.showSageMemoryInject !== void 0 || s.sageMemoryInjectThreshold !== void 0 || s.readSymbols !== void 0 || // WrongProxy / WrongTrace: gate the persisted-section write on
1737
+ // either key being present in the live patch. Without this, a
1738
+ // picker toggle round-trip would silently no-op the persistence
1739
+ // layer (the runtime probe would never read the change).
1740
+ s.wrongProxyEnabled !== void 0 || s.wrongProxyUrl !== void 0) {
1725
1741
  const cfg = configStore.get();
1726
1742
  const persistDeps = {
1727
1743
  configStore,
@@ -1819,11 +1835,21 @@ function createSettingsAdapter(ctx) {
1819
1835
  idx.onSessionStart = s.indexOnStart;
1820
1836
  decrypted.indexing = idx;
1821
1837
  }
1822
- if (s.maxIterations !== void 0 || s.nextStepsTool !== void 0 || fsAccess !== void 0) {
1838
+ if (s.maxIterations !== void 0 || s.nextStepsTool !== void 0 || fsAccess !== void 0 || // WrongProxy / WrongTrace: include either key in the tools-section
1839
+ // write guard so a picker toggle round-trip actually persists to
1840
+ // `tools.wrongProxy.{enabled,url}`. Without this, the gate at
1841
+ // line 279 would short-circuit and skip the whole section write.
1842
+ s.wrongProxyEnabled !== void 0 || s.wrongProxyUrl !== void 0) {
1823
1843
  const tools = decrypted.tools ?? {};
1824
1844
  if (s.maxIterations !== void 0) tools.maxIterations = s.maxIterations;
1825
1845
  if (s.nextStepsTool !== void 0) tools.nextsteps = { enabled: s.nextStepsTool };
1826
1846
  if (fsAccess !== void 0) tools.restrictToProjectRoot = fsAccess.restrictToProjectRoot;
1847
+ if (s.wrongProxyEnabled !== void 0 || s.wrongProxyUrl !== void 0) {
1848
+ const wp = tools.wrongProxy ?? {};
1849
+ if (s.wrongProxyEnabled !== void 0) wp.enabled = s.wrongProxyEnabled;
1850
+ if (s.wrongProxyUrl !== void 0) wp.url = s.wrongProxyUrl;
1851
+ tools.wrongProxy = wp;
1852
+ }
1827
1853
  decrypted.tools = tools;
1828
1854
  }
1829
1855
  if (s.debugStream !== void 0) {
@@ -1934,7 +1960,11 @@ function createSettingsAdapter(ctx) {
1934
1960
  ...decrypted.indexing ?? {}
1935
1961
  }
1936
1962
  } : {},
1937
- ...s.maxIterations !== void 0 || s.nextStepsTool !== void 0 || fsAccess !== void 0 ? {
1963
+ ...s.maxIterations !== void 0 || s.nextStepsTool !== void 0 || fsAccess !== void 0 || // WrongProxy / WrongTrace: must be in the tools guard or the
1964
+ // in-memory ConfigStore never sees the freshly-saved values,
1965
+ // and the next picker open in the same process would overwrite
1966
+ // the on-disk selection with stale state. See Chimera review.
1967
+ s.wrongProxyEnabled !== void 0 || s.wrongProxyUrl !== void 0 ? {
1938
1968
  tools: {
1939
1969
  ...currentConfig.tools,
1940
1970
  ...decrypted.tools ?? {}
@@ -2407,6 +2437,53 @@ async function finalizeExecutionCleanup(input) {
2407
2437
  sessionEndProducers.add(tracked);
2408
2438
  }
2409
2439
  });
2440
+ try {
2441
+ const model = agent.ctx.model;
2442
+ if (!model) {
2443
+ console.warn(
2444
+ JSON.stringify({
2445
+ level: "warn",
2446
+ event: "shutdown.wrongtrace_telemetry_skipped",
2447
+ message: "Skipping WrongTrace telemetry: agent model unknown at session end",
2448
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
2449
+ })
2450
+ );
2451
+ } else {
2452
+ const { reportWrongTraceSessionTelemetry } = await import("./wrongtrace-telemetry-6M2CCBX5.js");
2453
+ const usage = tokenCounter.total();
2454
+ const report = reportWrongTraceSessionTelemetry({
2455
+ sessionId: activeSession.id,
2456
+ agentName: "wrongstack-cli",
2457
+ model,
2458
+ provider: agent.ctx.provider?.id ?? "",
2459
+ usage: {
2460
+ input: usage.input,
2461
+ output: usage.output,
2462
+ cacheRead: usage.cacheRead,
2463
+ cacheWrite: usage.cacheWrite
2464
+ },
2465
+ costUsd: tokenCounter.estimateCost().total
2466
+ });
2467
+ const deadline = new Promise((resolve4) => {
2468
+ const t = setTimeout(resolve4, 5e3);
2469
+ t.unref?.();
2470
+ });
2471
+ const tracked = Promise.race([report, deadline]).finally(
2472
+ () => sessionEndProducers.delete(tracked)
2473
+ );
2474
+ void tracked.catch(() => void 0);
2475
+ sessionEndProducers.add(tracked);
2476
+ }
2477
+ } catch {
2478
+ }
2479
+ try {
2480
+ const { snapshotGateDecisions, persistWrongTraceGateCounters } = await import("./wrongtrace-gate-counters-P5BCBXQN.js");
2481
+ const projectRoot = agent.ctx.projectRoot;
2482
+ if (projectRoot) {
2483
+ await persistWrongTraceGateCounters(projectRoot, snapshotGateDecisions());
2484
+ }
2485
+ } catch {
2486
+ }
2410
2487
  if (director) {
2411
2488
  try {
2412
2489
  director.requestFinish("leader session ended \u2014 finish your review now");
@@ -3334,9 +3411,10 @@ function installChimeraCascadeHandler({
3334
3411
  trackWork,
3335
3412
  buildLadder,
3336
3413
  verifyEvidence = verifyCascadeEvidence,
3337
- persistEvidence
3414
+ persistEvidence,
3415
+ teardownHandlers
3338
3416
  }) {
3339
- events.onPattern("chimera.cascade_needed", (_event, payload) => {
3417
+ const off = events.onPattern("chimera.cascade_needed", (_event, payload) => {
3340
3418
  const p = payload;
3341
3419
  const dir = director;
3342
3420
  if (!dir) return;
@@ -3451,7 +3529,8 @@ function installChimeraCascadeHandler({
3451
3529
  });
3452
3530
  })();
3453
3531
  trackWork(pendingWork);
3454
- });
3532
+ }, "chimera-cascade");
3533
+ if (off) teardownHandlers?.push(off);
3455
3534
  }
3456
3535
  async function maybeReReviewCascade({
3457
3536
  events,
@@ -3626,9 +3705,10 @@ function installChimeraReviewHandler({
3626
3705
  projectDir,
3627
3706
  statusTracker,
3628
3707
  persistReview = persistChimeraReview,
3629
- trackWork
3708
+ trackWork,
3709
+ teardownHandlers
3630
3710
  }) {
3631
- events.onPattern("chimera.review_needed", (_event, payload) => {
3711
+ const off = events.onPattern("chimera.review_needed", (_event, payload) => {
3632
3712
  const p = payload;
3633
3713
  const reviewSessionId = agent.ctx.activeRunSessionId ?? agent.ctx.session?.id ?? session.id;
3634
3714
  const dir = director;
@@ -3989,7 +4069,8 @@ ${reviewBody}`;
3989
4069
  }
3990
4070
  })()
3991
4071
  );
3992
- });
4072
+ }, "chimera-review");
4073
+ if (off) teardownHandlers?.push(off);
3993
4074
  }
3994
4075
  async function persistChimeraReview(payload, projectDir) {
3995
4076
  const reportId = payload.reportId;
@@ -5732,6 +5813,7 @@ async function execute(deps) {
5732
5813
  const bootUpdateInfo = initialUpdateInfo;
5733
5814
  const offStorageObservability = installStorageObservability(events, context.traceId);
5734
5815
  const chimeraWork = createChimeraWorkRegistry();
5816
+ const chimeraTeardowns = [];
5735
5817
  installChimeraReviewHandler({
5736
5818
  events,
5737
5819
  director,
@@ -5740,6 +5822,7 @@ async function execute(deps) {
5740
5822
  agent,
5741
5823
  config,
5742
5824
  projectDir: wpaths.projectDir,
5825
+ teardownHandlers: chimeraTeardowns,
5743
5826
  // Thread the shared tracker so the round-robin Chimera reviewer picks
5744
5827
  // skip (provider, model) pairs currently in the waiting room. Without
5745
5828
  // this, a 429-stricken model is re-spawned on every concurrent reviewer
@@ -5753,6 +5836,7 @@ async function execute(deps) {
5753
5836
  events,
5754
5837
  director,
5755
5838
  session,
5839
+ teardownHandlers: chimeraTeardowns,
5756
5840
  buildLadder: () => buildMutatingAgentLadder({
5757
5841
  profileChain: effectiveFallbackChain2(config),
5758
5842
  session: { provider: config.provider, model: config.model }
@@ -6185,6 +6269,12 @@ async function execute(deps) {
6185
6269
  }
6186
6270
  }
6187
6271
  } finally {
6272
+ for (const off of chimeraTeardowns.splice(0)) {
6273
+ try {
6274
+ off();
6275
+ } catch {
6276
+ }
6277
+ }
6188
6278
  await finalizeExecutionCleanup({
6189
6279
  offStorageObservability,
6190
6280
  fleetStatusLine,
@@ -6213,4 +6303,4 @@ export {
6213
6303
  execute,
6214
6304
  resolveReviewerFallbackModels
6215
6305
  };
6216
- //# sourceMappingURL=execution-WA2UCXNM.js.map
6306
+ //# sourceMappingURL=execution-TOBPK6MD.js.map
@@ -18,9 +18,12 @@ export type InstallChimeraCascadeHandlerOptions = {
18
18
  buildLadder?: (() => ReviewerAttempt[]) | undefined;
19
19
  /** Test seam; production defaults to the real safe command verifier. */
20
20
  verifyEvidence?: typeof verifyCascadeEvidence | undefined;
21
+ /** Optional session-teardown chain — the wildcard listener disposer is
22
+ * pushed here so the registration is released when the session ends. */
23
+ teardownHandlers?: Array<() => void> | undefined;
21
24
  /** Persist every evidence verdict on the source report, even when re-review stops. */
22
25
  persistEvidence?: ((reportId: string, status: CascadeEvidenceStatus, checks: CascadeEvidenceCheckResult[]) => Promise<void>) | undefined;
23
26
  };
24
- export declare function installChimeraCascadeHandler({ events, director, session, getPendingWork, trackWork, buildLadder, verifyEvidence, persistEvidence, }: InstallChimeraCascadeHandlerOptions): void;
27
+ export declare function installChimeraCascadeHandler({ events, director, session, getPendingWork, trackWork, buildLadder, verifyEvidence, persistEvidence, teardownHandlers, }: InstallChimeraCascadeHandlerOptions): void;
25
28
  export {};
26
29
  //# sourceMappingURL=execution-chimera-cascade.d.ts.map
@@ -38,7 +38,10 @@ export type InstallChimeraReviewHandlerOptions = {
38
38
  statusTracker?: ProviderModelStatusTracker | undefined;
39
39
  persistReview?: ((payload: ChimeraReviewCompletePayload, projectDir: string) => Promise<void>) | undefined;
40
40
  trackWork: (work: Promise<void>) => void;
41
+ /** Optional session-teardown chain — the wildcard listener disposer is
42
+ * pushed here so the registration is released when the session ends. */
43
+ teardownHandlers?: Array<() => void> | undefined;
41
44
  };
42
- export declare function installChimeraReviewHandler({ events, director, session, mailbox, agent, config, projectDir, statusTracker, persistReview, trackWork, }: InstallChimeraReviewHandlerOptions): void;
45
+ export declare function installChimeraReviewHandler({ events, director, session, mailbox, agent, config, projectDir, statusTracker, persistReview, trackWork, teardownHandlers, }: InstallChimeraReviewHandlerOptions): void;
43
46
  export {};
44
47
  //# sourceMappingURL=execution-chimera-review.d.ts.map
@@ -1,5 +1,6 @@
1
1
  import type { AgentPipelines, FallbackProfileManager } from '@wrongstack/core/agent';
2
2
  import type { BrainArbiter, ProviderModelStatusTracker } from '@wrongstack/core/coordination';
3
+ import type { HookRunner } from '@wrongstack/core/hooks';
3
4
  import type { Container, EventBus } from '@wrongstack/core/kernel';
4
5
  import type { ProviderRegistry, ToolRegistry } from '@wrongstack/core/registry';
5
6
  import type { ConfigStore, ModelsRegistry, Renderer, SecretScrubber, SessionWriter, SkillLoader, SystemPromptBuilder, TokenCounter } from '@wrongstack/core/types';
@@ -32,6 +33,14 @@ export interface MultiAgentDeps {
32
33
  * subagent pipeline. This is host wiring, never a model-visible capability.
33
34
  */
34
35
  installToolBoundary?: ((pipelines: AgentPipelines) => void) | undefined;
36
+ /**
37
+ * Optional hook runner applied to every spawned subagent's ToolExecutor.
38
+ * The CLI wires a dedicated WrongTrace-only runner here so worker edits
39
+ * pass the same lock gate as the leader. Deliberately NOT the leader's
40
+ * own HookRegistry: shell hooks from `config.hooks` are a leader-session
41
+ * automation surface and must not silently replay on workers.
42
+ */
43
+ hookRunner?: HookRunner | undefined;
35
44
  }
36
45
  /**
37
46
  * Per-session options for the multi-agent host. Director Mode is always
@@ -0,0 +1,22 @@
1
+ import { HookRunner } from '@wrongstack/core/hooks';
2
+ /**
3
+ * Dedicated WrongTrace-only HookRunner for fleet subagents.
4
+ *
5
+ * Why not hand subagents the leader's own HookRunner: the leader's
6
+ * HookRegistry also carries shell hooks loaded from `config.hooks`, and
7
+ * those are a leader-session automation surface — replaying them on every
8
+ * worker tool call would be a silent behavior change beyond WrongTrace.
9
+ * This runner registers ONLY the fail-open lock-gate hooks, so a worker's
10
+ * `edit`/`write`/`replace`/`patch`/`codebase-ast-replace` call honors
11
+ * peer locks exactly like the leader does while nothing else changes.
12
+ *
13
+ * Lock claims are stamped `wrongstack:<leaderSessionId>` — one process,
14
+ * one lock-owner identity; per-worker ids would fragment the TTL picture
15
+ * without adding safety (the daemon lock is advisory coordination).
16
+ *
17
+ * Mirrors the registration contract in lifecycle-plugins.ts (same events,
18
+ * same matcher, same owner id). If production drifts, update both.
19
+ * `emit` (optional) forwards typed gate-decision events to the host bus.
20
+ */
21
+ export declare function createSubagentWrongTraceHookRunner(sessionId: () => string, emit?: (event: import('@wrongstack/wrongtrace').WrongTraceGateDecisionEvent) => void): HookRunner;
22
+ //# sourceMappingURL=subagent-hook-runner.d.ts.map
@@ -51,7 +51,7 @@ var hqCmd = async (args, deps) => {
51
51
  return 1;
52
52
  };
53
53
  async function startServer(deps) {
54
- const { startHqServer } = await import("./hq-server-GZGM4BHA.js");
54
+ const { startHqServer } = await import("./hq-server-DBT3OOYD.js");
55
55
  const dataDir = resolveDataDir(deps);
56
56
  const flags = deps.flags ?? {};
57
57
  const host = typeof flags["host"] === "string" ? flags["host"] : HQ_CLI_DEFAULT_HOST;
@@ -709,4 +709,4 @@ export {
709
709
  hqCmd,
710
710
  resolveAuditActor
711
711
  };
712
- //# sourceMappingURL=hq-AG4VW4XO.js.map
712
+ //# sourceMappingURL=hq-2XIXGAER.js.map
@@ -15,7 +15,7 @@ import {
15
15
  readLocalSubagentTranscript,
16
16
  sanitizeApiError,
17
17
  startHqServer
18
- } from "./chunk-KQNYSZG2.js";
18
+ } from "./chunk-E3X4KM7T.js";
19
19
  import "./chunk-KE7E7DPX.js";
20
20
  import "./chunk-Q5GTM25S.js";
21
21
  import "./chunk-7OCVIDC7.js";
@@ -37,4 +37,4 @@ export {
37
37
  sanitizeApiError,
38
38
  startHqServer
39
39
  };
40
- //# sourceMappingURL=hq-server-GZGM4BHA.js.map
40
+ //# sourceMappingURL=hq-server-DBT3OOYD.js.map
package/dist/index.js CHANGED
@@ -10,25 +10,25 @@ import {
10
10
  import {
11
11
  theme
12
12
  } from "./chunk-QD544J2B.js";
13
- import {
14
- parseWebuiSessionChildOptions,
15
- writeWebuiSessionChildError
16
- } from "./chunk-3JPTNADJ.js";
17
13
  import {
18
14
  fmtTok,
19
15
  patchConfig
20
16
  } from "./chunk-TYO2OVAD.js";
17
+ import {
18
+ parseWebuiSessionChildOptions,
19
+ writeWebuiSessionChildError
20
+ } from "./chunk-3JPTNADJ.js";
21
21
  import {
22
22
  discoverAndMergeProviders
23
23
  } from "./chunk-52C7PD2H.js";
24
24
  import {
25
25
  runUpdateCommand
26
- } from "./chunk-63GFD62R.js";
26
+ } from "./chunk-4S52MIIM.js";
27
27
  import "./chunk-U3SS4NRH.js";
28
28
  import "./chunk-NUIHRGPY.js";
29
29
  import {
30
30
  DEFAULT_PORT
31
- } from "./chunk-KQNYSZG2.js";
31
+ } from "./chunk-E3X4KM7T.js";
32
32
  import "./chunk-KE7E7DPX.js";
33
33
  import "./chunk-Q5GTM25S.js";
34
34
  import {
@@ -1645,8 +1645,8 @@ var helpTable = {
1645
1645
  update: {
1646
1646
  name: "update",
1647
1647
  title: "wstack update \u2014 self-update the CLI",
1648
- description: "Check the latest npm version and update the globally-installed `wrongstack` package. Use `--check-only` to just print the current/latest without installing. The update is global; run from any project root.",
1649
- usage: "wstack update [--check-only]",
1648
+ description: "Check the latest npm version and update the globally-installed `wrongstack` package. Use `--check-only` to just print the current/latest without installing. Pass `--pm <manager>` (or its shorthand `--npm`, `--pnpm`, `--yarn`, `--bun`) to force a specific package manager; pass `--allow-scripts` (alias `--lifecycle-scripts`) to opt into package lifecycle scripts during the update (off by default). The update is global; run from any project root.",
1649
+ usage: "wstack update [--check-only] [--pm <manager>] [--allow-scripts (alias: --lifecycle-scripts)]",
1650
1650
  seeAlso: "wstack version (read-only version info)"
1651
1651
  },
1652
1652
  // -- ACP (Agent Client Protocol) --------------------------------------
@@ -1861,10 +1861,10 @@ var subcommandsWithFocusedHelp = Object.keys(helpTable);
1861
1861
 
1862
1862
  // src/subcommands/index.ts
1863
1863
  var loaders = {
1864
- acp: async () => (await import("./acp-EA57GUFB.js")).acpCmd,
1864
+ acp: async () => (await import("./acp-LQMSMV32.js")).acpCmd,
1865
1865
  init: async () => (await import("./init-4JQSG66Q.js")).initCmd,
1866
1866
  auth: async () => (await import("./auth-VQMSZGKE.js")).authCmd,
1867
- update: async () => (await import("./update-RATFF63M.js")).updateCmd,
1867
+ update: async () => (await import("./update-ZXNC6I6G.js")).updateCmd,
1868
1868
  sessions: async () => (await import("./sessions-config-7Q7QJBKJ.js")).sessionsCmd,
1869
1869
  config: async () => (await import("./sessions-config-7Q7QJBKJ.js")).configCmd,
1870
1870
  rewind: async () => (await import("./rewind-2FFNOOKS.js")).rewindCmd,
@@ -1877,8 +1877,9 @@ var loaders = {
1877
1877
  mcp: async () => (await import("./mcp-RRPKNRSN.js")).mcpCmd,
1878
1878
  plugin: async () => (await import("./plugin-usage-GCTYOZPH.js")).pluginCmd,
1879
1879
  plugins: async () => (await import("./plugin-usage-GCTYOZPH.js")).pluginCmd,
1880
- diag: async () => (await import("./diag-doctor-HJKFUY6B.js")).diagCmd,
1881
- doctor: async () => (await import("./diag-doctor-HJKFUY6B.js")).doctorCmd,
1880
+ diag: async () => (await import("./diag-doctor-OPTB2NWY.js")).diagCmd,
1881
+ doctor: async () => (await import("./diag-doctor-OPTB2NWY.js")).doctorCmd,
1882
+ "proxy-status": async () => (await import("./diag-doctor-OPTB2NWY.js")).proxyCmd,
1882
1883
  export: async () => (await import("./export-ROG3DKTZ.js")).exportCmd,
1883
1884
  usage: async () => (await import("./plugin-usage-GCTYOZPH.js")).usageCmd,
1884
1885
  version: async () => (await import("./version-help-WMPSEL4U.js")).versionCmd,
@@ -1888,7 +1889,7 @@ var loaders = {
1888
1889
  quick: async () => (await import("./quick-XLYLZX4B.js")).quickCmd,
1889
1890
  bench: async () => (await import("./bench-XYG56AMO.js")).benchCmd,
1890
1891
  chronicle: async () => (await import("./chronicle-6EPPMUC5.js")).chronicleCmd,
1891
- hq: async () => (await import("./hq-AG4VW4XO.js")).hqCmd,
1892
+ hq: async () => (await import("./hq-2XIXGAER.js")).hqCmd,
1892
1893
  mailbox: async () => (await import("./mailbox-serve-5S3PHG5D.js")).mailboxServeCmd,
1893
1894
  permissions: async () => (await import("./permissions-2PWBL4YU.js")).permissionsCmd,
1894
1895
  project: async () => (await import("./project-BLQ3ALVL.js")).projectCmd,
@@ -1967,7 +1968,7 @@ async function isPortInUse(host, port) {
1967
1968
  }
1968
1969
  async function handleHqShortCircuit(flags) {
1969
1970
  if (flags["hq"] !== true) return null;
1970
- const { startHqServer } = await import("./hq-server-GZGM4BHA.js");
1971
+ const { startHqServer } = await import("./hq-server-DBT3OOYD.js");
1971
1972
  const tunnelRequested = flags["tunnel"] === true;
1972
1973
  const host = typeof flags["host"] === "string" ? flags["host"] : tunnelRequested ? "127.0.0.1" : HQ_CLI_DEFAULT_HOST2;
1973
1974
  if (tunnelRequested && !isLoopbackHost(host)) {
@@ -4480,7 +4481,7 @@ async function initializeCli(argv) {
4480
4481
  async function main(argv) {
4481
4482
  const cliCtx = await initializeCli(argv);
4482
4483
  if (typeof cliCtx === "number") return cliCtx;
4483
- const { runInteractive } = await import("./cli-main-RFEZAJ4U.js");
4484
+ const { runInteractive } = await import("./cli-main-BFUSCWXE.js");
4484
4485
  return runInteractive(cliCtx);
4485
4486
  }
4486
4487
 
@@ -52,7 +52,7 @@ export interface LiveSettingsInput {
52
52
  /** Single word shown in the TUI rainbow working-state chip. */
53
53
  thinkingWord?: string | undefined;
54
54
  /** Animation style for the TUI working-state chip. */
55
- animationStyle?: 'rainbow' | 'wave' | 'pulse' | 'dots' | 'breathe' | 'cycle' | undefined;
55
+ animationStyle?: 'rainbow' | 'wave' | 'pulse' | 'dots' | 'breathe' | 'static' | 'cycle' | undefined;
56
56
  /** Provider-runtime reasoning mode. */
57
57
  reasoningMode?: 'auto' | 'on' | 'off' | undefined;
58
58
  /** Provider-runtime reasoning effort. */
@@ -88,5 +88,19 @@ export interface LiveSettingsInput {
88
88
  nextStepsTool?: boolean | undefined;
89
89
  /** Minimum relation strength for SAGE memory injection. Default: 0.85. */
90
90
  sageMemoryInjectThreshold?: number | undefined;
91
+ /**
92
+ * WrongProxy / WrongTrace: master switch. When true AND the daemon at
93
+ * `wrongProxyUrl` is reachable, every provider's base URL is rewritten
94
+ * through `${wrongProxyUrl}/proxy/<host><path>`. openai-codex is
95
+ * excluded by spec. Persisted to `tools.wrongProxy.enabled` (read at
96
+ * boot, applied mid-session by `applyLiveSettings`).
97
+ */
98
+ wrongProxyEnabled?: boolean | undefined;
99
+ /**
100
+ * WrongProxy / WrongTrace URL. Default `http://localhost:3444`. The
101
+ * CLI's periodic probe targets `<wrongProxyUrl>/api/health`; a 2xx
102
+ * response flips the runtime's `active` flag.
103
+ */
104
+ wrongProxyUrl?: string | undefined;
91
105
  }
92
106
  //# sourceMappingURL=live-settings-input.d.ts.map
@@ -0,0 +1,15 @@
1
+ import {
2
+ applyWrongProxyPrefs,
3
+ awaitFirstWrongProxyProbe,
4
+ bootstrapWrongProxy,
5
+ shutdownWrongProxy
6
+ } from "./chunk-AOAIPYFB.js";
7
+ import "./chunk-GWVLRUVH.js";
8
+ import "./chunk-7OCVIDC7.js";
9
+ export {
10
+ applyWrongProxyPrefs,
11
+ awaitFirstWrongProxyProbe,
12
+ bootstrapWrongProxy,
13
+ shutdownWrongProxy
14
+ };
15
+ //# sourceMappingURL=proxy-wiring-G26YGP7S.js.map
@@ -19,5 +19,12 @@ export interface SubcommandDeps {
19
19
  userHome: string;
20
20
  /** Parsed top-level flags after they have been removed from positional args. */
21
21
  flags?: Record<string, string | boolean>;
22
+ /**
23
+ * Live EventBus when a subcommand is invoked from a host that holds one
24
+ * (e.g. an in-process diagnostics surface). Standalone `wstack doctor`
25
+ * runs in a fresh process and has none — the handler then omits the
26
+ * listener-pressure line instead of fabricating counts.
27
+ */
28
+ events?: import('@wrongstack/core/kernel').EventBus | undefined;
22
29
  }
23
30
  //# sourceMappingURL=contracts.d.ts.map
@@ -1,4 +1,18 @@
1
1
  import type { SubcommandHandler } from '../contracts.js';
2
2
  export declare const diagCmd: SubcommandHandler;
3
+ /**
4
+ * `wstack proxy-status` — print the live in-process `ProxyConfig` singleton.
5
+ *
6
+ * A fresh `wstack` invocation has never booted the WS prefs pipeline that
7
+ * the long-running session uses to populate the singleton, so reading
8
+ * `getProxyConfig()` raw here would always return the module default
9
+ * (`enabled=false, url='', active=false`) regardless of what's on disk
10
+ * or whether the daemon is reachable. To answer "did the probe flip
11
+ * active=true?" we seed the singleton from persisted prefs (`config.tools
12
+ * .wrongProxy`), start a one-shot probe, await its first poke, and only
13
+ * then read state. `startProxyProbe()` is idempotent so this is safe to
14
+ * call from a subcommand that has no other runtime side-effects.
15
+ */
16
+ export declare const proxyCmd: SubcommandHandler;
3
17
  export declare const doctorCmd: SubcommandHandler;
4
18
  //# sourceMappingURL=diag-doctor.d.ts.map
@@ -3,7 +3,7 @@ import {
3
3
  detectUpdatePackageName,
4
4
  runUpdateCommand,
5
5
  updateCmd
6
- } from "./chunk-63GFD62R.js";
6
+ } from "./chunk-4S52MIIM.js";
7
7
  import "./chunk-U3SS4NRH.js";
8
8
  import "./chunk-NUIHRGPY.js";
9
9
  import "./chunk-7OCVIDC7.js";
@@ -13,4 +13,4 @@ export {
13
13
  runUpdateCommand,
14
14
  updateCmd
15
15
  };
16
- //# sourceMappingURL=update-RATFF63M.js.map
16
+ //# sourceMappingURL=update-ZXNC6I6G.js.map
@@ -18,6 +18,10 @@ interface CliWebUIOptions {
18
18
  fallbackAuto?: boolean | undefined;
19
19
  modelMatrix?: Config['modelMatrix'] | undefined;
20
20
  uiLocale?: string | undefined;
21
+ /** WrongProxy / WrongTrace toggle. */
22
+ wrongProxyEnabled?: boolean | undefined;
23
+ /** WrongProxy / WrongTrace URL. Default: 'http://localhost:3444'. */
24
+ wrongProxyUrl?: string | undefined;
21
25
  } | undefined;
22
26
  }
23
27
  type PrefSnapshot = Record<string, unknown>;
@@ -746,6 +746,12 @@ function createPrefsSeeding(opts) {
746
746
  if (typeof payload["uiLocale"] === "string") {
747
747
  patchLiveAppConfig({ uiLocale: payload["uiLocale"] });
748
748
  }
749
+ if (typeof payload["wrongProxyEnabled"] === "boolean") {
750
+ patchLiveAppConfig({ wrongProxyEnabled: payload["wrongProxyEnabled"] });
751
+ }
752
+ if (typeof payload["wrongProxyUrl"] === "string") {
753
+ patchLiveAppConfig({ wrongProxyUrl: payload["wrongProxyUrl"] });
754
+ }
749
755
  if (payload["modelMatrix"] && typeof payload["modelMatrix"] === "object" && !Array.isArray(payload["modelMatrix"])) {
750
756
  patchLiveAppConfig({ modelMatrix: payload["modelMatrix"] });
751
757
  }
@@ -881,6 +887,7 @@ function createWebuiRouteContexts({
881
887
  persist: persistPrefs,
882
888
  setYolo: opts.onYoloSwitch,
883
889
  setAutonomy: opts.onAutonomySwitch,
890
+ applyWrongProxyPrefs: opts.onWrongProxyPrefsChange,
884
891
  pendingConfirms,
885
892
  configStore: opts.agent.container?.safeResolve?.(TOKENS2.ConfigStore),
886
893
  send,
@@ -1686,4 +1693,4 @@ async function runWebUI(opts) {
1686
1693
  export {
1687
1694
  runWebUI
1688
1695
  };
1689
- //# sourceMappingURL=webui-server-3DU6BVTB.js.map
1696
+ //# sourceMappingURL=webui-server-I53IYBW4.js.map
@@ -205,6 +205,14 @@ export interface CliWebUIOptions {
205
205
  onAutonomySwitch?: ((mode: string) => void) | undefined;
206
206
  /** Forward browser YOLO changes to the host's live permission policy. */
207
207
  onYoloSwitch?: ((enabled: boolean) => void) | undefined;
208
+ /**
209
+ * Forward `wrongProxyEnabled` / `wrongProxyUrl` changes from the
210
+ * browser to the runtime probe (`@wrongstack/cli/wiring/proxy-wiring`).
211
+ * Mirrors the `onAutonomySwitch` / `onYoloSwitch` pattern: the WS
212
+ * server stays package-agnostic and the boot site provides the
213
+ * host-side effect.
214
+ */
215
+ onWrongProxyPrefsChange?: ((payload: Record<string, unknown>) => void) | undefined;
208
216
  /**
209
217
  * Pre-computed update info from the CLI's preflight version check.
210
218
  * When present, the session.start payload includes appVersion,
@@ -42,6 +42,31 @@ export interface ResolvedProviderCfg {
42
42
  factoryType: string;
43
43
  }
44
44
  export declare function resolveProviderCfg(config: Pick<Config, 'providers' | 'apiKey' | 'baseUrl'>, providerId: string): ResolvedProviderCfg;
45
+ /**
46
+ * Shared proxy-aware provider-config resolver.
47
+ *
48
+ * Three sites in this monorepo merge a saved provider config with the
49
+ * top-level Config and hand the result to a provider factory:
50
+ *
51
+ * 1. `packages/cli/src/wiring/provider-runtime.ts` `resolveProviderCfg()`
52
+ * — used by `/model`, the fallback extension, and any other runtime
53
+ * path that rebuilds a Provider from a saved-config alias.
54
+ * 2. `packages/cli/src/wiring/provider.ts` `setupProvider()` — the
55
+ * boot-time setup path for the active session provider.
56
+ * 3. `packages/runtime/src/fleet/light-subagent-factory.ts` `buildProvider()`
57
+ * — subagent provider construction for SDD runs.
58
+ *
59
+ * Each of those had to apply the same proxy rewrite. The duplication
60
+ * drifted: `provider.ts:154` was force-setting `type: config.provider`
61
+ * before the `factoryType` read at line 158, silently destroying any
62
+ * saved-alias `type` field (e.g. `minimax-coding-plan` mapped to
63
+ * `type: 'anthropic'`). The drift was caught by Chimera review; this
64
+ * helper is the single source of truth that prevents it from recurring.
65
+ *
66
+ * Inputs are intentionally `Pick<Config, ...>` (not the full Config) so
67
+ * this helper stays free of disk I/O and can be called from any layer.
68
+ */
69
+ export declare function resolveProviderCfgWithProxy(config: Pick<Config, 'providers' | 'apiKey' | 'baseUrl'>, providerId: string): ResolvedProviderCfg;
45
70
  /**
46
71
  * Construct a credential-resolved Provider for a provider id, WITHOUT
47
72
  * persisting anything. Shared by the `/model` switch and the fallback