@wrongstack/cli 0.319.0 → 1.0.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 (113) hide show
  1. package/data/providers.json +22 -15
  2. package/dist/{acp-5ANIAOZC.js → acp-3LARESEO.js} +113 -10
  3. package/dist/acp-hq-telemetry.d.ts +44 -0
  4. package/dist/{audit-ZPCLCC3C.js → audit-46YK5DSC.js} +1 -2
  5. package/dist/{auth-KF5TAD7V.js → auth-KIBJZZIE.js} +5 -6
  6. package/dist/auth-menu/add-provider.d.ts +7 -0
  7. package/dist/auth-menu/panel-service.d.ts +2 -20
  8. package/dist/{auto-discover-providers-MHFLDSD3.js → auto-discover-providers-VQU3IZMR.js} +1 -2
  9. package/dist/{bench-XYG56AMO.js → bench-YBU6BVQP.js} +175 -35
  10. package/dist/boot/brain-decision-log.d.ts +22 -2
  11. package/dist/{boot-auto-thin-BZ675EVT.js → boot-auto-thin-MANHOYHE.js} +1 -2
  12. package/dist/{chronicle-6EPPMUC5.js → chronicle-UTFETHP6.js} +1 -2
  13. package/dist/{chunk-VWCZL4OH.js → chunk-4HV5RKZH.js} +5 -5
  14. package/dist/{chunk-42JD25KU.js → chunk-5IA5337I.js} +3 -3
  15. package/dist/{chunk-7JBKXVMK.js → chunk-C2E24IXZ.js} +44 -32
  16. package/dist/{chunk-7CECQDNH.js → chunk-D3K4NYQL.js} +1 -1
  17. package/dist/{chunk-XPX432BZ.js → chunk-DR2OXU46.js} +50 -39
  18. package/dist/{chunk-4JRIWVJ4.js → chunk-ERX4BLKP.js} +1 -1
  19. package/dist/chunk-ETYHZPXP.js +52 -0
  20. package/dist/{chunk-TYO2OVAD.js → chunk-EWKESL4L.js} +8 -4
  21. package/dist/{chunk-QAC263FZ.js → chunk-FPIWTJ2G.js} +2 -3
  22. package/dist/{chunk-7YLN7YUA.js → chunk-IMWXXF4J.js} +61 -9
  23. package/dist/{chunk-G7337TTK.js → chunk-IS2PPBQV.js} +1 -1
  24. package/dist/{chunk-G3IMKQRH.js → chunk-JHPXJRRI.js} +1 -1
  25. package/dist/{chunk-XHIEA6LG.js → chunk-MNQQ4ZNF.js} +26 -22
  26. package/dist/{chunk-P2OKBDCH.js → chunk-MXEJEYT7.js} +53 -14
  27. package/dist/{chunk-PCBJSXYV.js → chunk-O4A3HHKD.js} +2 -2
  28. package/dist/{chunk-XYKYXFEE.js → chunk-TE3Q32JP.js} +10 -4
  29. package/dist/{chunk-H7GABTGS.js → chunk-TEBMCYZN.js} +69 -30
  30. package/dist/{chunk-E4I2TF5S.js → chunk-TNK6237M.js} +2 -2
  31. package/dist/{chunk-SYIBTG3X.js → chunk-VOTTENR5.js} +3 -5
  32. package/dist/chunk-WHOIR577.js +1 -0
  33. package/dist/{chunk-2ZNBRZ4W.js → chunk-WQZW3RDP.js} +2 -2
  34. package/dist/{chunk-GGGUZSAU.js → chunk-Z7A5MXKJ.js} +18 -12
  35. package/dist/{chunk-F5GA2QW2.js → chunk-ZSZ3EYWH.js} +2 -2
  36. package/dist/{cli-context-LH4QP4W2.js → cli-context-CYMKNOK3.js} +58 -307
  37. package/dist/{cli-main-72XUFUCL.js → cli-main-TTIVR4DI.js} +925 -329
  38. package/dist/{diag-doctor-LFCCBPMD.js → diag-doctor-7LYUYU35.js} +4 -6
  39. package/dist/execute-deps.d.ts +5 -1
  40. package/dist/{execution-DKJDNPYF.js → execution-3Y55IWBK.js} +512 -469
  41. package/dist/{export-ROG3DKTZ.js → export-VVRIOWFV.js} +1 -2
  42. package/dist/{governance-JSGHHA2R.js → governance-RYSHV675.js} +1 -2
  43. package/dist/{hq-3GWBFLON.js → hq-IG3YRGCO.js} +2 -3
  44. package/dist/hq-command-controller.d.ts +37 -7
  45. package/dist/hq-server/routes.d.ts +1 -1
  46. package/dist/hq-server/ws.d.ts +1 -1
  47. package/dist/{hq-server-OARPUSQJ.js → hq-server-OILU3NPI.js} +2 -3
  48. package/dist/{hq-ttl-KUO3AU7X.js → hq-ttl-VJR65OBJ.js} +1 -2
  49. package/dist/{hq-tunnel-LO55RCZE.js → hq-tunnel-NIJ5EP2Y.js} +1 -2
  50. package/dist/index.js +5 -6
  51. package/dist/{init-4JQSG66Q.js → init-DRMMFG2G.js} +1 -2
  52. package/dist/{kanban-run-mirror-EKVNGXWW.js → kanban-run-mirror-22HQ5FNG.js} +1 -2
  53. package/dist/live-settings-input.d.ts +2 -0
  54. package/dist/{mailbox-serve-VKQIRCCB.js → mailbox-serve-VUCWZ2SJ.js} +2 -3
  55. package/dist/{mcp-AQKSASHD.js → mcp-HOMLC4WE.js} +1 -2
  56. package/dist/{modeldiag-5FRMT6FQ.js → modeldiag-FMJT37SN.js} +2 -3
  57. package/dist/{per-subcommand-help-6VCIKDUW.js → per-subcommand-help-BWBHYVJO.js} +2 -3
  58. package/dist/{permissions-2PWBL4YU.js → permissions-CFDLXETM.js} +1 -2
  59. package/dist/{plugin-usage-CYUORYM6.js → plugin-usage-HFBI3TFT.js} +2 -3
  60. package/dist/{plugins-RV3OBBND.js → plugins-PZ2VZL7V.js} +4 -5
  61. package/dist/{project-BLQ3ALVL.js → project-AOQI5XTK.js} +1 -2
  62. package/dist/{project-manifest-YFTJ3D5N.js → project-manifest-7NSFVBM3.js} +2 -3
  63. package/dist/{project-picker-R5TYAE3Q.js → project-picker-SVBXMPKX.js} +3 -4
  64. package/dist/{projects-5J727S4L.js → projects-L6C6XLDY.js} +1 -2
  65. package/dist/provider-config-utils.d.ts +1 -1
  66. package/dist/{providers-models-OKKQZIWU.js → providers-models-YVMVYWRS.js} +3 -4
  67. package/dist/{proxy-wiring-EQB5X5YH.js → proxy-wiring-MGRSKZZB.js} +3 -4
  68. package/dist/{quick-XLYLZX4B.js → quick-CNB4Z3HS.js} +1 -2
  69. package/dist/{replay-RZXZKP2U.js → replay-JJ2NOWD6.js} +1 -2
  70. package/dist/{replay-FJ2JBXUA.js → replay-Z3FTJEMM.js} +1 -2
  71. package/dist/{rewind-2FFNOOKS.js → rewind-JA3ZLCNM.js} +1 -2
  72. package/dist/{sdd-runtime-FLKCSTYV.js → sdd-runtime-PTOSPYI4.js} +2 -3
  73. package/dist/services/sdd-runtime.d.ts +1 -1
  74. package/dist/services/statusline-config.d.ts +43 -13
  75. package/dist/{sessions-config-KAMEBVOX.js → sessions-config-UL45XKX7.js} +2 -3
  76. package/dist/{sessions-doctor-EXHAZSSE.js → sessions-doctor-QUL37U32.js} +1 -2
  77. package/dist/short-circuit-flags-6PSP56L7.js +10 -0
  78. package/dist/{simpleui-dist-JKNRCRRK.js → simpleui-dist-CXSIDAXZ.js} +1 -2
  79. package/dist/slash-commands/command-context.d.ts +10 -0
  80. package/dist/slash-commands/sdd.d.ts +1 -1
  81. package/dist/slash-commands/statusline.d.ts +1 -1
  82. package/dist/subcommands/handlers/bench-run-config.d.ts +18 -0
  83. package/dist/subcommands/handlers/bench.d.ts +8 -7
  84. package/dist/subcommands-HZQKA4G2.js +9 -0
  85. package/dist/{tools-skills-Q4P27URS.js → tools-skills-GH24UCBY.js} +1 -2
  86. package/dist/{update-K45CS6SS.js → update-5DPB4YD4.js} +1 -2
  87. package/dist/{update-check-PKSMSMD6.js → update-check-BS3DHTSI.js} +1 -2
  88. package/dist/version-help-MYKF724O.js +10 -0
  89. package/dist/webui-server/client-registration.d.ts +9 -1
  90. package/dist/{webui-server-SY4EQCKD.js → webui-server-T6AMOXJJ.js} +54 -13
  91. package/dist/wiring/brain-and-orchestration.d.ts +2 -0
  92. package/dist/wiring/cli-execute-builder.d.ts +4 -0
  93. package/dist/wiring/cli-slash-commands-setup.d.ts +1 -0
  94. package/dist/wiring/command-host-state.d.ts +50 -5
  95. package/dist/wiring/external-plugins.d.ts +9 -0
  96. package/dist/wiring/provider-runtime-setup.d.ts +2 -0
  97. package/dist/wiring/runtime-controller-deps.d.ts +3 -0
  98. package/dist/wiring/vector-memory-setup.d.ts +12 -0
  99. package/dist/wiring/wrongtrace-gate.d.ts +2 -2
  100. package/dist/wiring/wrongtrace-hooks.d.ts +1 -1
  101. package/dist/wiring/wrongtrace-prompt-contributor.d.ts +5 -2
  102. package/dist/{wrongtrace-gate-counters-P5BCBXQN.js → wrongtrace-gate-counters-7C2EAAZL.js} +2 -3
  103. package/dist/{wrongtrace-telemetry-FNLANZ5I.js → wrongtrace-telemetry-3ASFKOZO.js} +2 -3
  104. package/package.json +28 -28
  105. package/dist/chunk-7OCVIDC7.js +0 -11
  106. package/dist/chunk-ALE5KHCA.js +0 -1
  107. package/dist/chunk-OZDE3OWD.js +0 -52
  108. package/dist/launch-hints.d.ts +0 -49
  109. package/dist/short-circuit-flags-U6CJAF6J.js +0 -11
  110. package/dist/subcommands-J4JMWC5W.js +0 -10
  111. package/dist/version-help-WMPSEL4U.js +0 -11
  112. package/dist/webui-server/privileged-actions.d.ts +0 -14
  113. package/dist/wiring/cli-heap-watchdog.d.ts +0 -34
@@ -12,18 +12,17 @@ var BENCH_RUN_FLAGS = [
12
12
  {
13
13
  name: "suite",
14
14
  flag: "--suite <id>",
15
- description: "Benchmark suite id (`polyglot` or `swebench`).",
15
+ description: "Benchmark suite id (`core`, `smoke`, `local`, `polyglot`, or `swebench`).",
16
16
  group: "suite",
17
17
  kind: "value",
18
- defaultValue: "polyglot"
18
+ defaultValue: "core"
19
19
  },
20
20
  {
21
21
  name: "polyglot-dir",
22
22
  flag: "--polyglot-dir <path>",
23
23
  description: "Path to the Aider polyglot dataset (required when --suite polyglot).",
24
24
  group: "suite",
25
- kind: "value",
26
- required: true
25
+ kind: "value"
27
26
  },
28
27
  {
29
28
  name: "languages",
@@ -46,15 +45,36 @@ var BENCH_RUN_FLAGS = [
46
45
  group: "suite",
47
46
  kind: "boolean"
48
47
  },
48
+ {
49
+ name: "suite-dir",
50
+ flag: "--suite-dir <path>",
51
+ description: "Directory containing bench.local.json (required when --suite local).",
52
+ group: "suite",
53
+ kind: "value"
54
+ },
55
+ {
56
+ name: "manifest",
57
+ flag: "--manifest <file>",
58
+ description: "Explicit local-manifest path (alternative to --suite-dir).",
59
+ group: "suite",
60
+ kind: "value"
61
+ },
49
62
  // -- Model matrix ---------------------------------------------------
50
63
  {
51
64
  name: "models",
52
65
  flag: "--models <config>",
53
- description: "Path to the model-cells config (JSON).",
66
+ description: "Path to the model-cells config (JSON). Optional when --cell or a saved model is set.",
54
67
  group: "models",
55
68
  kind: "value",
56
69
  defaultValue: "bench.config.json"
57
70
  },
71
+ {
72
+ name: "cell",
73
+ flag: "--cell <spec>",
74
+ description: "Comma-separated model cells (`provider/model` or `label=provider/model`). Skips the config file.",
75
+ group: "models",
76
+ kind: "value"
77
+ },
58
78
  // -- Run control ----------------------------------------------------
59
79
  {
60
80
  name: "limit",
@@ -77,6 +97,21 @@ var BENCH_RUN_FLAGS = [
77
97
  description: "Override the per-cell concurrency from the model config.",
78
98
  group: "control",
79
99
  kind: "value"
100
+ },
101
+ {
102
+ name: "repeats",
103
+ flag: "--repeats <N>",
104
+ description: "Attempts per (task x model). >1 adds pass@k and a flakiness count so run-to-run noise is visible.",
105
+ group: "control",
106
+ kind: "value",
107
+ defaultValue: "1"
108
+ },
109
+ {
110
+ name: "keep-sandbox",
111
+ flag: "--keep-sandbox",
112
+ description: "Keep the temporary sandbox (workdirs + isolated home) on disk for debugging.",
113
+ group: "control",
114
+ kind: "boolean"
80
115
  }
81
116
  ];
82
117
  var BENCH_RUN_BOOLEAN_FLAG_NAMES = BENCH_RUN_FLAGS.filter(
@@ -89,10 +124,10 @@ var BENCH_RUN_FLAG_COLUMN_WIDTH = 28;
89
124
  function renderBenchRunHelpToString() {
90
125
  const lines = [
91
126
  color.bold("wstack bench run \u2014 execute a benchmark suite across a model matrix"),
92
- color.dim(" Runs a benchmark suite (polyglot or swebench) across every model cell"),
93
- color.dim(" in the config. Output is a per-run directory with `report.md`, JSON"),
94
- color.dim(" artifacts, and (for swebench) per-cell predictions for the official"),
95
- color.dim(" harness."),
127
+ color.dim(" Default suite is bundled core (6 agent-edit tasks with tests). Pass --cell"),
128
+ color.dim(" provider/model to start immediately. Output is a per-run directory"),
129
+ color.dim(" with `report.md` (leaderboard + per-task matrix), JSON artifacts,"),
130
+ color.dim(" and (for swebench) per-cell predictions for the official harness."),
96
131
  "",
97
132
  color.bold("Usage"),
98
133
  ` ${buildUsageLine()}`,
@@ -101,7 +136,7 @@ function renderBenchRunHelpToString() {
101
136
  ...buildFlagBlock(),
102
137
  "",
103
138
  color.dim(
104
- "See also: wstack bench list (show available suites + cells); wstack bench report <dir>"
139
+ "See also: wstack bench list; wstack bench report <dir>; wstack bench compare <a> <b>"
105
140
  )
106
141
  ];
107
142
  return lines.join("\n") + "\n";
@@ -969,10 +1004,14 @@ var helpTable = {
969
1004
  bench: {
970
1005
  name: "bench",
971
1006
  title: "wstack bench \u2014 run model-independent agentic benchmarks",
972
- description: "Run WrongStack against the Aider polyglot or SWE-bench Verified suites with deterministic graders. Used internally to compare model quality across releases; also useful for evaluating a new model before adopting it.",
973
- usage: "wstack bench [run|report|list] [...]",
1007
+ description: "Run WrongStack against the bundled smoke suite, a local manifest, Aider polyglot, or SWE-bench Verified with deterministic graders. Default `bench run` is the bundled core edit-eval; pass --cell provider/model (or a saved model).",
1008
+ usage: "wstack bench [run|compare|report|list] [...]",
974
1009
  subcommands: [
975
- { name: "run", description: "Run a benchmark suite (--suite <id> --models <config>)." },
1010
+ { name: "run", description: "Run a suite. Default: bundled smoke + --cell or saved model." },
1011
+ {
1012
+ name: "compare <a> <b>",
1013
+ description: "Diff two finished run directories (fingerprint-aware)."
1014
+ },
976
1015
  { name: "report <dir>", description: "Render the Markdown report for a prior run." },
977
1016
  { name: "list", description: "List available suites and the model configs in the catalog." }
978
1017
  ],
@@ -1163,4 +1202,4 @@ export {
1163
1202
  subcommandsWithFocusedHelp,
1164
1203
  renderGenericHelp
1165
1204
  };
1166
- //# sourceMappingURL=chunk-P2OKBDCH.js.map
1205
+ //# sourceMappingURL=chunk-MXEJEYT7.js.map
@@ -14,7 +14,7 @@ async function printUpdateNotice(initialUpdateInfo) {
14
14
  const ac = new AbortController();
15
15
  const timer = setTimeout(() => ac.abort(), 2e3);
16
16
  try {
17
- const { checkForUpdate } = await import("./update-check-PKSMSMD6.js");
17
+ const { checkForUpdate } = await import("./update-check-BS3DHTSI.js");
18
18
  info = await checkForUpdate(ac.signal);
19
19
  } catch {
20
20
  } finally {
@@ -62,4 +62,4 @@ export {
62
62
  applySessionShellDefault,
63
63
  runPreflight
64
64
  };
65
- //# sourceMappingURL=chunk-PCBJSXYV.js.map
65
+ //# sourceMappingURL=chunk-O4A3HHKD.js.map
@@ -423,6 +423,7 @@ async function writeState(projectRoot, state) {
423
423
  }
424
424
 
425
425
  // src/hq-publisher.ts
426
+ var HQ_DISCOVERY_CONNECTION_KEY = "<discover>";
426
427
  function nodeWsSocketFactory(url) {
427
428
  return new WebSocket(url);
428
429
  }
@@ -440,11 +441,13 @@ function hqExplicitlyDisabled(options) {
440
441
  }
441
442
  function resolvedHqConnectionKey(options) {
442
443
  if (options.config !== void 0) {
443
- return options.config.enabled === false ? void 0 : `${options.config.url}
444
+ if (options.config.enabled === false) return void 0;
445
+ return options.config.discover === true ? HQ_DISCOVERY_CONNECTION_KEY : `${options.config.url}
444
446
  ${options.config.token ?? ""}`;
445
447
  }
446
448
  const config = resolveHqConfig({ config: options.appConfig?.hq });
447
- return config === void 0 ? void 0 : `${config.url}
449
+ if (config === void 0) return void 0;
450
+ return config.discover === true ? HQ_DISCOVERY_CONNECTION_KEY : `${config.url}
448
451
  ${config.token ?? ""}`;
449
452
  }
450
453
  function startCliHqConnection(options) {
@@ -460,7 +463,10 @@ function startCliHqConnection(options) {
460
463
  const tryConnect = () => {
461
464
  const nextKey = resolvedHqConnectionKey(options);
462
465
  if (nextKey === void 0) return;
463
- if (publisher !== void 0 && publisherKey === nextKey) return;
466
+ if (publisher !== void 0 && publisherKey === nextKey) {
467
+ if (nextKey === HQ_DISCOVERY_CONNECTION_KEY) publisher.refreshEndpoint();
468
+ return;
469
+ }
464
470
  publisher?.close();
465
471
  publisher = void 0;
466
472
  publisherKey = void 0;
@@ -507,4 +513,4 @@ function startCliHqConnection(options) {
507
513
  export {
508
514
  startCliHqConnection
509
515
  };
510
- //# sourceMappingURL=chunk-XYKYXFEE.js.map
516
+ //# sourceMappingURL=chunk-TE3Q32JP.js.map
@@ -1,7 +1,7 @@
1
1
 
2
2
  // src/wiring/external-plugins.ts
3
- import { fileURLToPath, pathToFileURL } from "node:url";
4
3
  import { isAbsolute, join, resolve } from "node:path";
4
+ import { fileURLToPath, pathToFileURL } from "node:url";
5
5
  import {
6
6
  defaultPluginTrustPath,
7
7
  discoverExternalPlugins,
@@ -13,6 +13,12 @@ import {
13
13
  resolvePluginTarget,
14
14
  verifyPluginTrust
15
15
  } from "@wrongstack/core/plugin";
16
+ function resolveExternalPluginTrustMode(raw) {
17
+ if (raw === false) return "off";
18
+ if (raw === "required") return "required";
19
+ if (raw === "advisory") return "advisory";
20
+ return "tofu";
21
+ }
16
22
  function normalizeConfigPath(raw, projectRoot) {
17
23
  if (raw.startsWith("file:")) return fileURLToPath(raw);
18
24
  return isAbsolute(raw) ? raw : resolve(projectRoot, raw);
@@ -50,15 +56,36 @@ async function loadExternalPlugins(ctx, hooks) {
50
56
  const { config, log } = ctx;
51
57
  if (config.features?.plugins === false) return [];
52
58
  const importModule = ctx.importModule ?? ((url) => import(url));
53
- const trustEnabled = config.features?.pluginsTrust !== false && (ctx.globalRoot !== void 0 || ctx.trustStorePath !== void 0);
59
+ const trustMode = resolveExternalPluginTrustMode(config.features?.pluginsTrust);
60
+ if (trustMode === "required" && ctx.globalRoot === void 0 && ctx.trustStorePath === void 0) {
61
+ log.error(
62
+ '[plugins] features.pluginsTrust is "required" but no trust store location is available (no globalRoot) \u2014 refusing all external plugins. Configure a global root, or set features.pluginsTrust to "tofu"/"advisory".'
63
+ );
64
+ return [];
65
+ }
66
+ const trustEnabled = trustMode !== "off";
54
67
  const trustStorePath = ctx.trustStorePath ?? (ctx.globalRoot !== void 0 ? defaultPluginTrustPath(ctx.globalRoot) : void 0);
55
68
  let trustStore;
56
- if (trustEnabled && trustStorePath !== void 0) {
69
+ let trustUsable = trustEnabled && trustStorePath !== void 0;
70
+ if (trustEnabled && !trustUsable) {
71
+ log.warn(
72
+ "[plugins] features.pluginsTrust is enabled but no trust store location is available (no globalRoot) \u2014 external plugins load WITHOUT integrity checks. Configure a global root to enable trust-on-first-use."
73
+ );
74
+ }
75
+ if (trustUsable && trustStorePath !== void 0) {
57
76
  try {
58
77
  trustStore = await readPluginTrustStore(trustStorePath);
59
78
  } catch (err) {
60
- log.error(`[plugins] ${err instanceof Error ? err.message : String(err)}`);
61
- return [];
79
+ const message = err instanceof Error ? err.message : String(err);
80
+ if (trustMode === "advisory") {
81
+ log.warn(
82
+ `[plugins] trust store unreadable (${message}) \u2014 features.pluginsTrust is 'advisory', loading external plugins WITHOUT integrity checks`
83
+ );
84
+ trustUsable = false;
85
+ } else {
86
+ log.error(`[plugins] ${message}`);
87
+ return [];
88
+ }
62
89
  }
63
90
  }
64
91
  const sources = [];
@@ -120,9 +147,7 @@ async function loadExternalPlugins(ctx, hooks) {
120
147
  });
121
148
  if (!enabled) {
122
149
  if (enablementSource !== "default") {
123
- log.info(
124
- `[plugins] discovered plugin "${candidate.name}" disabled by ${enablementSource}`
125
- );
150
+ log.info(`[plugins] discovered plugin "${candidate.name}" disabled by ${enablementSource}`);
126
151
  }
127
152
  continue;
128
153
  }
@@ -143,18 +168,25 @@ async function loadExternalPlugins(ctx, hooks) {
143
168
  const seenNames = /* @__PURE__ */ new Set();
144
169
  for (const source of sources) {
145
170
  const entryPath = source.kind === "spec" ? resolveSpecifierEntry(source.spec) : source.entryPath;
146
- if (trustEnabled && trustStorePath !== void 0 && entryPath !== void 0) {
171
+ if (trustUsable && trustStorePath !== void 0 && entryPath !== void 0) {
147
172
  const gate = await gateExternalPluginTrust({
148
173
  entryPath,
149
174
  spec: source.spec,
150
175
  label: source.label,
151
176
  store: trustStore,
152
177
  storePath: trustStorePath,
178
+ mode: trustMode,
153
179
  log
154
180
  });
155
181
  if (!gate.ok) continue;
156
182
  if (gate.pinned) trustStore = gate.store;
157
- } else if (trustEnabled && trustStorePath !== void 0 && entryPath === void 0) {
183
+ } else if (trustUsable && entryPath === void 0) {
184
+ if (trustMode === "required") {
185
+ log.error(
186
+ `[plugins] REFUSING external plugin "${source.label}" \u2014 features.pluginsTrust is 'required' and its entry file could not be resolved pre-import (spec "${source.spec}"). Install it so its entry file resolves, or load it by explicit path.`
187
+ );
188
+ continue;
189
+ }
158
190
  log.warn(
159
191
  `[plugins] trust check skipped for "${source.label}" \u2014 entry file could not be resolved pre-import`
160
192
  );
@@ -191,16 +223,21 @@ async function loadExternalPlugins(ctx, hooks) {
191
223
  return loaded;
192
224
  }
193
225
  async function gateExternalPluginTrust(args) {
194
- const { spec, label, store, storePath, log } = args;
226
+ const { spec, label, store, storePath, mode, log } = args;
195
227
  const entryPath = normalizeTrustKey(args.entryPath);
196
228
  if (!store) return { ok: true, pinned: false };
197
229
  let integrity;
198
230
  try {
199
231
  integrity = await hashFileContents(entryPath);
200
232
  } catch (err) {
201
- log.warn(
202
- `[plugins] trust check skipped for "${label}" \u2014 entry could not be read (${err instanceof Error ? err.message : String(err)})`
203
- );
233
+ const message = err instanceof Error ? err.message : String(err);
234
+ if (mode === "required") {
235
+ log.error(
236
+ `[plugins] REFUSING external plugin "${label}" \u2014 features.pluginsTrust is 'required' and its entry file could not be read (${message})`
237
+ );
238
+ return { ok: false, pinned: false };
239
+ }
240
+ log.warn(`[plugins] trust check skipped for "${label}" \u2014 entry could not be read (${message})`);
204
241
  return { ok: true, pinned: false };
205
242
  }
206
243
  const verification = verifyPluginTrust(entryPath, integrity, store);
@@ -213,15 +250,25 @@ async function gateExternalPluginTrust(args) {
213
250
  );
214
251
  return { ok: true, pinned: true, store: next };
215
252
  } catch (err) {
216
- log.warn(
217
- `[plugins] could not persist trust pin for "${label}" (${err instanceof Error ? err.message : String(err)})`
218
- );
253
+ const message = err instanceof Error ? err.message : String(err);
254
+ if (mode === "required") {
255
+ log.error(
256
+ `[plugins] REFUSING external plugin "${label}" \u2014 features.pluginsTrust is 'required' and its first-use pin could not be persisted (${message})`
257
+ );
258
+ return { ok: false, pinned: false };
259
+ }
260
+ log.warn(`[plugins] could not persist trust pin for "${label}" (${message})`);
219
261
  return { ok: true, pinned: false };
220
262
  }
221
263
  }
222
- log.error(
223
- `[plugins] REFUSING external plugin "${label}" \u2014 its entry file changed since it was first trusted (pinned ${verification.pinnedAt}). If you expected this update, re-pin it: wstack plugin trust ${label}`
224
- );
264
+ const changedMessage = `its entry file changed since it was first trusted (pinned ${verification.pinnedAt}). If you expected this update, re-pin it: wstack plugin trust ${label}`;
265
+ if (mode === "advisory") {
266
+ log.warn(
267
+ `[plugins] external plugin "${label}" \u2014 ${changedMessage} features.pluginsTrust is 'advisory', loading anyway WITHOUT integrity enforcement`
268
+ );
269
+ return { ok: true, pinned: false };
270
+ }
271
+ log.error(`[plugins] REFUSING external plugin "${label}" \u2014 ${changedMessage}`);
225
272
  return { ok: false, pinned: false };
226
273
  }
227
274
 
@@ -880,15 +927,7 @@ function buildInstallArgs(pm, targetDir, runScripts, spec) {
880
927
  case "bun":
881
928
  return ["add", "--cwd", targetDir, ...ignoreScripts, spec];
882
929
  default:
883
- return [
884
- "install",
885
- "--prefix",
886
- targetDir,
887
- "--no-audit",
888
- "--no-fund",
889
- ...ignoreScripts,
890
- spec
891
- ];
930
+ return ["install", "--prefix", targetDir, "--no-audit", "--no-fund", ...ignoreScripts, spec];
892
931
  }
893
932
  }
894
933
  function runPackageManagerInstall(pm, args, cwd) {
@@ -996,4 +1035,4 @@ export {
996
1035
  PLUGIN_AUDIT_ENTRIES,
997
1036
  runPluginManagementCommand
998
1037
  };
999
- //# sourceMappingURL=chunk-H7GABTGS.js.map
1038
+ //# sourceMappingURL=chunk-TEBMCYZN.js.map
@@ -3,7 +3,7 @@ import {
3
3
  normalizeKeys,
4
4
  nowIso,
5
5
  writeKeysBack
6
- } from "./chunk-XPX432BZ.js";
6
+ } from "./chunk-DR2OXU46.js";
7
7
 
8
8
  // src/auth-menu/openai-codex-oauth.ts
9
9
  import { color } from "@wrongstack/core/utils";
@@ -259,4 +259,4 @@ export {
259
259
  filterCurrentCodexModelIds,
260
260
  isCodexCatalogModel
261
261
  };
262
- //# sourceMappingURL=chunk-E4I2TF5S.js.map
262
+ //# sourceMappingURL=chunk-TNK6237M.js.map
@@ -1,11 +1,9 @@
1
1
  import {
2
2
  startProxyProbe
3
- } from "./chunk-G3IMKQRH.js";
3
+ } from "./chunk-JHPXJRRI.js";
4
4
 
5
5
  // src/wiring/proxy-wiring.ts
6
- import {
7
- applyProxyConfig
8
- } from "@wrongstack/core/wiring/proxy-rewrite";
6
+ import { applyProxyConfig } from "@wrongstack/core/wiring/proxy-rewrite";
9
7
  var probeRunner;
10
8
  function applyWrongProxyPrefs(payload) {
11
9
  const patch = {};
@@ -55,4 +53,4 @@ export {
55
53
  bootstrapWrongProxy,
56
54
  shutdownWrongProxy
57
55
  };
58
- //# sourceMappingURL=chunk-SYIBTG3X.js.map
56
+ //# sourceMappingURL=chunk-VOTTENR5.js.map
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=chunk-WHOIR577.js.map
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  loadManifest
3
- } from "./chunk-G7337TTK.js";
3
+ } from "./chunk-IS2PPBQV.js";
4
4
 
5
5
  // src/project-picker.ts
6
6
  import { color } from "@wrongstack/core/utils";
@@ -415,4 +415,4 @@ export {
415
415
  skipDivider,
416
416
  runProjectPicker
417
417
  };
418
- //# sourceMappingURL=chunk-2ZNBRZ4W.js.map
418
+ //# sourceMappingURL=chunk-WQZW3RDP.js.map
@@ -36,8 +36,6 @@ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
36
36
  "no-models-refresh",
37
37
  // (removed: 'director' and 'no-director' — Director Mode is always on)
38
38
  "no-autonomy",
39
- "no-hints",
40
- "hints",
41
39
  "no-menu",
42
40
  "no-hooks",
43
41
  "skip",
@@ -174,20 +172,28 @@ function parseAuthFlags(args) {
174
172
  const out = { positional: [] };
175
173
  for (let i = 0; i < args.length; i++) {
176
174
  const a = args[i];
177
- if (a === "--label") {
178
- const v = args[++i];
175
+ if (!a) continue;
176
+ let key = a;
177
+ let inlineVal;
178
+ const eq = a.indexOf("=");
179
+ if (a.startsWith("--") && eq !== -1) {
180
+ key = a.slice(0, eq);
181
+ inlineVal = a.slice(eq + 1);
182
+ }
183
+ if (key === "--label") {
184
+ const v = inlineVal !== void 0 ? inlineVal : args[++i];
179
185
  if (v) out.label = v;
180
- } else if (a === "--family") {
181
- const v = args[++i];
186
+ } else if (key === "--family") {
187
+ const v = inlineVal !== void 0 ? inlineVal : args[++i];
182
188
  if (v) out.family = v;
183
- } else if (a === "--base-url") {
184
- const v = args[++i];
189
+ } else if (key === "--base-url") {
190
+ const v = inlineVal !== void 0 ? inlineVal : args[++i];
185
191
  if (v) out.baseUrl = v;
186
- } else if (a === "--env") {
187
- const v = args[++i];
192
+ } else if (key === "--env") {
193
+ const v = inlineVal !== void 0 ? inlineVal : args[++i];
188
194
  if (v)
189
195
  out.envVars = v.split(",").map((s) => s.trim()).filter(Boolean);
190
- } else if (a && !a.startsWith("--")) {
196
+ } else if (!a.startsWith("--")) {
191
197
  out.positional.push(a);
192
198
  }
193
199
  }
@@ -232,4 +238,4 @@ export {
232
238
  parseAuthFlags,
233
239
  parseSpawnFlags
234
240
  };
235
- //# sourceMappingURL=chunk-GGGUZSAU.js.map
241
+ //# sourceMappingURL=chunk-Z7A5MXKJ.js.map
@@ -2,7 +2,7 @@ import {
2
2
  fallbackCodexProviderModels,
3
3
  filterCurrentCodexModelIds,
4
4
  isCodexCatalogModel
5
- } from "./chunk-E4I2TF5S.js";
5
+ } from "./chunk-TNK6237M.js";
6
6
 
7
7
  // src/acp-registry-cache.ts
8
8
  import * as fs from "node:fs/promises";
@@ -307,4 +307,4 @@ export {
307
307
  setupProvider,
308
308
  createGracefulShutdown
309
309
  };
310
- //# sourceMappingURL=chunk-F5GA2QW2.js.map
310
+ //# sourceMappingURL=chunk-ZSZ3EYWH.js.map