@wrongstack/cli 1.0.19 → 1.0.26

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 (195) hide show
  1. package/data/providers.json +44 -0
  2. package/dist/{acp-INCNOH42.js → acp-LI665LO2.js} +18 -7
  3. package/dist/arg-parser.d.ts +1 -0
  4. package/dist/ascii-mode-SG4PRNLP.js +7 -0
  5. package/dist/{auth-YXK3EDUL.js → auth-TE55JF4Z.js} +68 -22
  6. package/dist/auth-menu/direct.d.ts +1 -0
  7. package/dist/auth-menu/local.d.ts +2 -0
  8. package/dist/auth-menu/oauth-menu.d.ts +3 -1
  9. package/dist/auth-menu/panel-service.d.ts +20 -0
  10. package/dist/{bench-YBU6BVQP.js → bench-GTLPM22B.js} +2 -2
  11. package/dist/boot/append-system-prompt.d.ts +10 -0
  12. package/dist/boot/ascii-mode.d.ts +12 -0
  13. package/dist/boot/config-backup-recovery.d.ts +2 -1
  14. package/dist/boot/container-wiring.d.ts +4 -2
  15. package/dist/boot/dispatch-singleshot.d.ts +4 -1
  16. package/dist/boot/dispatch-webui.d.ts +11 -0
  17. package/dist/boot/mcp-config-flag.d.ts +22 -0
  18. package/dist/boot/piped-stdin.d.ts +40 -0
  19. package/dist/boot/restricted-mode.d.ts +15 -0
  20. package/dist/boot/safe-mode.d.ts +30 -0
  21. package/dist/boot/short-circuit-desktop.d.ts +1 -0
  22. package/dist/boot/single-shot-budget.d.ts +30 -0
  23. package/dist/boot/stream-json.d.ts +36 -0
  24. package/dist/boot/structured-output.d.ts +16 -0
  25. package/dist/boot/system-prompt-builder.d.ts +2 -0
  26. package/dist/boot/tool-restriction-flags.d.ts +36 -0
  27. package/dist/boot/tui-project-picker-callback.d.ts +1 -1
  28. package/dist/boot/tui-settings-adapter.d.ts +15 -2
  29. package/dist/boot/worktree-sessions.d.ts +21 -0
  30. package/dist/{boot-auto-thin-MANHOYHE.js → boot-auto-thin-6Q56FY3F.js} +3 -2
  31. package/dist/boot-provider-selection.d.ts +67 -0
  32. package/dist/boot.d.ts +1 -38
  33. package/dist/{chunk-JY52HWL6.js → chunk-2EBVTYJR.js} +2 -2
  34. package/dist/{chunk-RDHFXOJM.js → chunk-2ERX3RPN.js} +112 -65
  35. package/dist/chunk-4TVYGG6G.js +62 -0
  36. package/dist/chunk-5JYDKG5B.js +154 -0
  37. package/dist/{chunk-KEPABQYT.js → chunk-5SEYGOCH.js} +8 -82
  38. package/dist/{chunk-3VXYY5JC.js → chunk-5UZBUV2H.js} +3 -19
  39. package/dist/chunk-BBHWW6LR.js +549 -0
  40. package/dist/chunk-BEHGRNOQ.js +58 -0
  41. package/dist/chunk-CZTXF6HY.js +140 -0
  42. package/dist/{chunk-JX6KL7OF.js → chunk-EPR42SWM.js} +39 -8
  43. package/dist/chunk-F5DCFAKI.js +36 -0
  44. package/dist/chunk-HLSHFXTO.js +97 -0
  45. package/dist/{chunk-CJTBLTS4.js → chunk-KJS5543T.js} +4 -3
  46. package/dist/{chunk-DE7BZDNK.js → chunk-KOEO4CJG.js} +27 -4
  47. package/dist/{chunk-SIS37L3W.js → chunk-L2RVEQWO.js} +211 -193
  48. package/dist/chunk-LBPLTTZ6.js +105 -0
  49. package/dist/chunk-LDCGZJTC.js +46 -0
  50. package/dist/chunk-LKPEBZBE.js +143 -0
  51. package/dist/chunk-LUMETJFO.js +171 -0
  52. package/dist/{chunk-KK2LB3ZS.js → chunk-OAVBM55Q.js} +9 -5
  53. package/dist/chunk-PZQBGUVZ.js +18 -0
  54. package/dist/{chunk-C3Z4N6A6.js → chunk-Q4INH2DG.js} +51 -3
  55. package/dist/chunk-R4QGL6GB.js +10 -0
  56. package/dist/{chunk-YLQEGYV4.js → chunk-RZ4ZDRYA.js} +14 -4
  57. package/dist/chunk-S4FFHDJG.js +93 -0
  58. package/dist/chunk-SFBFYIOW.js +271 -0
  59. package/dist/{chunk-RMQNCHGO.js → chunk-TI7KLHYX.js} +136 -11
  60. package/dist/{chunk-2ENZU66X.js → chunk-WQV2NP57.js} +5 -5
  61. package/dist/{chunk-B4JLSXZB.js → chunk-WSTVGC2C.js} +73 -45
  62. package/dist/chunk-X756ZS72.js +329 -0
  63. package/dist/{chunk-XJ7K67PP.js → chunk-YHYINL47.js} +63 -24
  64. package/dist/{chunk-2VMJ3E5Z.js → chunk-YTEOAWOJ.js} +6 -2
  65. package/dist/{chunk-GPPRNAKW.js → chunk-ZMX5HRLI.js} +2 -2
  66. package/dist/{cli-context-33F74CSZ.js → cli-context-UVGAN3NO.js} +496 -384
  67. package/dist/cli-entry-point.d.ts +2 -0
  68. package/dist/{cli-main-FNGMKPBA.js → cli-main-TN3KZ2P6.js} +3561 -2724
  69. package/dist/cli-update-notice.d.ts +2 -1
  70. package/dist/config-doctor.d.ts +10 -2
  71. package/dist/{config-transfer-2YF3CRTN.js → config-transfer-RUWLDCNK.js} +34 -13
  72. package/dist/{diag-doctor-ANPRUYFM.js → diag-doctor-BIZAFIAT.js} +2 -2
  73. package/dist/execute-deps.d.ts +2 -1
  74. package/dist/{execution-A6WJLSOC.js → execution-7QIP6GRY.js} +2384 -2055
  75. package/dist/fleet/host-types.d.ts +3 -1
  76. package/dist/goal-commands.d.ts +47 -0
  77. package/dist/goal-host.d.ts +1 -14
  78. package/dist/{hq-XQWQTRDA.js → hq-GLZ7QESM.js} +277 -261
  79. package/dist/hq-command-controller.d.ts +1 -1
  80. package/dist/{hq-server-IIBZQZU4.js → hq-server-YTKDVQPY.js} +2 -2
  81. package/dist/{hq-service-L5INQFM4.js → hq-service-BMMJAHRT.js} +11 -4
  82. package/dist/import-claude-code-32PCSIQI.js +236 -0
  83. package/dist/index.d.ts +1 -1
  84. package/dist/index.js +19 -10
  85. package/dist/kanban-supervisor-67ECABTD.js +7 -0
  86. package/dist/live-settings-input.d.ts +7 -0
  87. package/dist/{mailbox-serve-3GFOK2I7.js → mailbox-serve-NW5VZG7R.js} +3 -3
  88. package/dist/{mcp-DC5WSBOO.js → mcp-LBS45HWZ.js} +4 -4
  89. package/dist/modeldiag-36VODVIH.js +828 -0
  90. package/dist/{per-subcommand-help-DHTYU524.js → per-subcommand-help-QDAQASPZ.js} +3 -3
  91. package/dist/permission-prompt-mirror.d.ts +1 -1
  92. package/dist/permission-prompt.d.ts +16 -2
  93. package/dist/permission-rules-view.d.ts +18 -0
  94. package/dist/{permissions-CFDLXETM.js → permissions-PL27UHYD.js} +67 -45
  95. package/dist/plugin-config.d.ts +12 -0
  96. package/dist/plugin-management-types.d.ts +31 -0
  97. package/dist/plugin-management.d.ts +2 -30
  98. package/dist/plugin-package-install.d.ts +3 -0
  99. package/dist/{plugin-usage-M6KET4OZ.js → plugin-usage-CIGOOTX3.js} +6 -5
  100. package/dist/{plugins-WJLW6ULV.js → plugins-HQTXUD6A.js} +6 -3
  101. package/dist/preflight.d.ts +1 -1
  102. package/dist/{projects-LMNAGGEU.js → projects-T4CZCA25.js} +3 -6
  103. package/dist/provider-config-utils.d.ts +1 -6
  104. package/dist/provider-helpers.d.ts +7 -11
  105. package/dist/{providers-models-LFNZ5WI7.js → providers-models-5Z2PJTEW.js} +44 -34
  106. package/dist/release-asset-download.d.ts +13 -0
  107. package/dist/release-attestation.d.ts +28 -0
  108. package/dist/remote/remote-session.d.ts +64 -0
  109. package/dist/remote/remote-target.d.ts +69 -0
  110. package/dist/remote-O5WXHLWV.js +561 -0
  111. package/dist/{replay-Z3FTJEMM.js → replay-DEI566CW.js} +2 -2
  112. package/dist/services/commit-message.d.ts +2 -1
  113. package/dist/services/dispatch-classifier.d.ts +39 -5
  114. package/dist/session-move-P2EC2COA.js +44 -0
  115. package/dist/session-move.d.ts +20 -0
  116. package/dist/session-stats.d.ts +10 -0
  117. package/dist/{sessions-config-UL45XKX7.js → sessions-config-SXTTLNXA.js} +47 -9
  118. package/dist/settings-menu.d.ts +2 -0
  119. package/dist/short-circuit-flags-74Y5N6CF.js +10 -0
  120. package/dist/{simpleui-dist-CXSIDAXZ.js → simpleui-dist-7BQISSEP.js} +7 -3
  121. package/dist/skill-suggest-L2EVWB6R.js +290 -0
  122. package/dist/slash-commands/command-context.d.ts +15 -5
  123. package/dist/slash-commands/effort.d.ts +1 -1
  124. package/dist/slash-commands/fallback.d.ts +1 -1
  125. package/dist/slash-commands/gitid.d.ts +1 -1
  126. package/dist/slash-commands/goal-refiner.d.ts +4 -49
  127. package/dist/slash-commands/jev.d.ts +4 -0
  128. package/dist/slash-commands/mcp.d.ts +2 -1
  129. package/dist/slash-commands/openai-quota.d.ts +15 -0
  130. package/dist/slash-commands/permissions.d.ts +4 -0
  131. package/dist/slash-commands/sdd-task-mutations.d.ts +4 -0
  132. package/dist/slash-commands/settings-context-mutations.d.ts +5 -0
  133. package/dist/slash-commands/settings-keys.d.ts +2 -0
  134. package/dist/slash-commands/settings-limits-mutations.d.ts +12 -0
  135. package/dist/slash-commands/settings-reset.d.ts +6 -0
  136. package/dist/standalone-auto-update-TOTRGCSA.js +249 -0
  137. package/dist/standalone-auto-update.d.ts +65 -0
  138. package/dist/standalone-update-LZO3MNLH.js +24 -0
  139. package/dist/standalone-update.d.ts +55 -0
  140. package/dist/subcommands/handlers/hq-alerts.d.ts +3 -0
  141. package/dist/subcommands/handlers/hq-audit.d.ts +46 -0
  142. package/dist/subcommands/handlers/hq-data-dir.d.ts +13 -0
  143. package/dist/subcommands/handlers/import-claude-code.d.ts +42 -0
  144. package/dist/subcommands/handlers/permissions.d.ts +9 -3
  145. package/dist/subcommands/handlers/remote.d.ts +6 -0
  146. package/dist/subcommands/handlers/skill-suggest.d.ts +21 -0
  147. package/dist/subcommands/handlers/typesafe-brain-replay.d.ts +26 -0
  148. package/dist/subcommands/handlers/typesafe-judgment-check.d.ts +3 -0
  149. package/dist/subcommands/handlers/typesafe-topic-replay.d.ts +19 -0
  150. package/dist/subcommands/handlers/typesafe-triage-replay.d.ts +18 -0
  151. package/dist/subcommands/handlers/typesafe.d.ts +23 -0
  152. package/dist/subcommands/handlers/version-help.d.ts +5 -0
  153. package/dist/{subcommands-XSLXMIDP.js → subcommands-Q6ORSB2E.js} +2 -2
  154. package/dist/tui-resume-callback.d.ts +18 -0
  155. package/dist/typesafe-U7YB2RRV.js +316 -0
  156. package/dist/typesafe-brain-replay-C5276FVR.js +222 -0
  157. package/dist/typesafe-judgment-check-GGYYV5UF.js +29 -0
  158. package/dist/typesafe-topic-replay-ZILIU3WS.js +234 -0
  159. package/dist/typesafe-triage-replay-FGAW7QM7.js +215 -0
  160. package/dist/{update-5DPB4YD4.js → update-TDZX4IL2.js} +4 -3
  161. package/dist/{update-check-BS3DHTSI.js → update-check-J5ZVKS73.js} +3 -2
  162. package/dist/update-check.d.ts +1 -1
  163. package/dist/version-JB2UAV2A.js +11 -0
  164. package/dist/version-help-XJJQ7YSH.js +10 -0
  165. package/dist/version.d.ts +3 -2
  166. package/dist/webui-client-observability.d.ts +7 -0
  167. package/dist/webui-server/route-contexts.d.ts +1 -1
  168. package/dist/webui-server/session-start-payload.d.ts +5 -1
  169. package/dist/{webui-server-MRPGTTKL.js → webui-server-YTHLRFD2.js} +577 -370
  170. package/dist/webui-server-lifecycle.d.ts +57 -0
  171. package/dist/webui-server-options.d.ts +11 -0
  172. package/dist/webui-server.d.ts +1 -1
  173. package/dist/wiring/brain-and-orchestration.d.ts +3 -1
  174. package/dist/wiring/cli-prompt-and-tools-setup.d.ts +9 -0
  175. package/dist/wiring/cli-slash-commands-setup.d.ts +1 -0
  176. package/dist/wiring/domain-glossary.d.ts +5 -4
  177. package/dist/wiring/lifecycle-plugins.d.ts +4 -2
  178. package/dist/wiring/metrics.d.ts +9 -1
  179. package/dist/wiring/pipeline.d.ts +2 -7
  180. package/dist/wiring/plugins.d.ts +4 -1
  181. package/dist/wiring/provider-persisters.d.ts +24 -0
  182. package/dist/wiring/provider-runtime.d.ts +9 -1
  183. package/dist/wiring/provider-status.d.ts +1 -0
  184. package/dist/wiring/provider-utility-tools.d.ts +3 -1
  185. package/dist/wiring/runtime-dispatch-state.d.ts +3 -1
  186. package/package.json +28 -28
  187. package/dist/chunk-2CZEORLV.js +0 -54
  188. package/dist/chunk-672UXYL3.js +0 -65
  189. package/dist/chunk-6WRKAACA.js +0 -96
  190. package/dist/chunk-DR2OXU46.js +0 -174
  191. package/dist/chunk-JACOMTIH.js +0 -275
  192. package/dist/chunk-XJXDOF63.js +0 -28
  193. package/dist/modeldiag-CJSFHZ3J.js +0 -1356
  194. package/dist/short-circuit-flags-7GQIGMVD.js +0 -10
  195. package/dist/version-help-WXI42PZ3.js +0 -10
@@ -1,3 +1,6 @@
1
+ import {
2
+ backupCurrent
3
+ } from "./chunk-WSTVGC2C.js";
1
4
 
2
5
  // src/wiring/external-plugins.ts
3
6
  import { isAbsolute, join, resolve } from "node:path";
@@ -329,10 +332,8 @@ async function hashPluginClosure(entryPath) {
329
332
  }
330
333
 
331
334
  // src/plugin-management.ts
332
- import { execFile } from "node:child_process";
333
- import * as fs from "node:fs/promises";
334
- import { homedir } from "node:os";
335
- import { join as join2 } from "node:path";
335
+ import { homedir as homedir2 } from "node:os";
336
+ import { join as join4 } from "node:path";
336
337
  import {
337
338
  defaultPluginTrustPath as defaultPluginTrustPath2,
338
339
  discoverExternalPlugins as discoverExternalPlugins2,
@@ -344,11 +345,213 @@ import {
344
345
  resolvePluginTarget as resolvePluginTarget2,
345
346
  unpinPluginTrust
346
347
  } from "@wrongstack/core/plugin";
347
- import { atomicWrite, buildChildEnv } from "@wrongstack/core/utils";
348
+ import { atomicWrite } from "@wrongstack/core/utils";
348
349
  import {
349
350
  PLUGIN_AUDIT_ENTRIES
350
351
  } from "@wrongstack/plugins/plugin-audit-catalog";
352
+
353
+ // src/plugin-config.ts
354
+ import * as fs from "node:fs/promises";
355
+ import { homedir } from "node:os";
356
+ import { join as join2 } from "node:path";
357
+ import { updateJsonObjectFile } from "@wrongstack/core/utils";
358
+ async function readConfig(file) {
359
+ try {
360
+ return JSON.parse(await fs.readFile(file, "utf8"));
361
+ } catch {
362
+ return {};
363
+ }
364
+ }
365
+ function pluginName(p) {
366
+ return typeof p === "string" ? p : p.name;
367
+ }
368
+ function pluginEntry(spec, enabled, path) {
369
+ if (path !== void 0) return { name: spec, path, enabled };
370
+ return enabled ? spec : { name: spec, enabled: false };
371
+ }
372
+ async function upsertPlugin(spec, opts, deps, verb) {
373
+ let plugins = [];
374
+ let features = {};
375
+ await updateJsonObjectFile(deps.configPath, async (existing) => {
376
+ await backupCurrent(void 0, deps.configPath);
377
+ plugins = Array.isArray(existing.plugins) ? existing.plugins : [];
378
+ const idx = plugins.findIndex((p) => pluginName(p) === spec);
379
+ const nextEntry = pluginEntry(spec, opts.enabled, opts.path);
380
+ if (idx >= 0) plugins[idx] = nextEntry;
381
+ else plugins.push(nextEntry);
382
+ features = {
383
+ ...isRecord(deps.config.features) ? deps.config.features : {},
384
+ ...isRecord(existing.features) ? existing.features : {},
385
+ plugins: true
386
+ };
387
+ existing.plugins = plugins;
388
+ existing.features = features;
389
+ });
390
+ const restartRequired = spec === "branch-guard" && !opts.enabled ? void 0 : true;
391
+ return {
392
+ code: 0,
393
+ level: "info",
394
+ message: `${verb} "${spec}" (${opts.enabled ? "enabled" : "disabled"}). Config written to ${deps.configPath}.` + (spec === "branch-guard" && !opts.enabled ? " The running branch-guard hook will disable itself on config update." : ""),
395
+ patch: { plugins, features },
396
+ restartRequired
397
+ };
398
+ }
399
+ function errorResult(message) {
400
+ return { code: 1, level: "error", message };
401
+ }
402
+ function globalPluginsRoot(deps) {
403
+ return join2(deps.globalRoot ?? join2(homedir(), ".wrongstack"), "plugins");
404
+ }
405
+ function isRecord(value) {
406
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
407
+ }
408
+
409
+ // src/plugin-package-install.ts
410
+ import { execFile } from "node:child_process";
411
+ import * as fs2 from "node:fs/promises";
412
+ import { join as join3 } from "node:path";
413
+ import { buildChildEnv } from "@wrongstack/core/utils";
351
414
  import { resolveExecInvocation } from "@wrongstack/plugins/runtime";
415
+ function detectPackageManager(args) {
416
+ const override = args.find((a) => a.startsWith("--pm="));
417
+ if (override) {
418
+ const pm = override.slice(5);
419
+ if (pm === "npm" || pm === "pnpm" || pm === "yarn" || pm === "bun") return pm;
420
+ }
421
+ const idx = args.indexOf("--pm");
422
+ if (idx >= 0 && args[idx + 1]) {
423
+ const pm = args[idx + 1];
424
+ if (pm === "npm" || pm === "pnpm" || pm === "yarn" || pm === "bun") return pm;
425
+ }
426
+ const ua = process.env.npm_config_user_agent ?? "";
427
+ if (ua.startsWith("pnpm")) return "pnpm";
428
+ if (ua.startsWith("yarn")) return "yarn";
429
+ if (ua.startsWith("bun")) return "bun";
430
+ return "npm";
431
+ }
432
+ function packageNameFromSpec(spec) {
433
+ const stripped = spec.trim();
434
+ if (stripped.startsWith("@")) {
435
+ const scopedEnd = stripped.indexOf("/", 1);
436
+ if (scopedEnd === -1) return stripped.split("@")[0] ?? stripped;
437
+ const rest = stripped.slice(scopedEnd + 1);
438
+ const at2 = rest.lastIndexOf("@");
439
+ return at2 === -1 ? stripped : stripped.slice(0, scopedEnd + 1 + at2);
440
+ }
441
+ const at = stripped.indexOf("@");
442
+ return at === -1 ? stripped : stripped.slice(0, at);
443
+ }
444
+ function buildInstallArgs(pm, targetDir, runScripts, spec) {
445
+ const ignoreScripts = runScripts ? [] : ["--ignore-scripts"];
446
+ switch (pm) {
447
+ case "pnpm":
448
+ return ["add", "--dir", targetDir, ...ignoreScripts, spec];
449
+ case "yarn":
450
+ return ["add", "--cwd", targetDir, ...ignoreScripts, spec];
451
+ case "bun":
452
+ return ["add", "--cwd", targetDir, ...ignoreScripts, spec];
453
+ default:
454
+ return ["install", "--prefix", targetDir, "--no-audit", "--no-fund", ...ignoreScripts, spec];
455
+ }
456
+ }
457
+ function runPackageManagerInstall(pm, args, cwd) {
458
+ return new Promise((resolvePromise) => {
459
+ let invocation;
460
+ try {
461
+ invocation = resolveExecInvocation(pm, args);
462
+ } catch (err) {
463
+ resolvePromise({
464
+ code: 127,
465
+ stdout: "",
466
+ stderr: err instanceof Error ? err.message : String(err)
467
+ });
468
+ return;
469
+ }
470
+ execFile(
471
+ invocation.cmd,
472
+ invocation.args,
473
+ {
474
+ cwd,
475
+ // H-8 (security report VF-09): this runs npm/pnpm install — including
476
+ // untrusted package lifecycle scripts — with the full inherited
477
+ // environment. Strip credentials via the shared child env.
478
+ env: buildChildEnv(),
479
+ timeout: 3e5,
480
+ maxBuffer: 16 * 1024 * 1024,
481
+ windowsHide: true,
482
+ ...invocation.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}
483
+ },
484
+ (err, stdout, stderr) => {
485
+ const code = err ? err.code ?? 1 : 0;
486
+ resolvePromise({
487
+ code: typeof code === "number" ? code : 1,
488
+ stdout: typeof stdout === "string" ? stdout : "",
489
+ stderr: typeof stderr === "string" ? stderr : ""
490
+ });
491
+ }
492
+ );
493
+ });
494
+ }
495
+ async function installPluginPackage(spec, args, deps) {
496
+ const pm = detectPackageManager(args);
497
+ const runScripts = args.includes("--run-scripts");
498
+ const targetDir = globalPluginsRoot(deps);
499
+ try {
500
+ await fs2.mkdir(targetDir, { recursive: true });
501
+ const pkgJsonPath = join3(targetDir, "package.json");
502
+ try {
503
+ await fs2.access(pkgJsonPath);
504
+ } catch {
505
+ await fs2.writeFile(
506
+ pkgJsonPath,
507
+ `${JSON.stringify({ name: "wrongstack-user-plugins", private: true, version: "0.0.0" }, null, 2)}
508
+ `,
509
+ "utf8"
510
+ );
511
+ }
512
+ } catch (err) {
513
+ return errorResult(
514
+ `Could not prepare plugin directory ${targetDir}: ${err instanceof Error ? err.message : String(err)}`
515
+ );
516
+ }
517
+ const run = deps.runPackageManager ?? runPackageManagerInstall;
518
+ const pmArgs = buildInstallArgs(pm, targetDir, runScripts, spec);
519
+ let result;
520
+ try {
521
+ result = await run(pm, pmArgs, targetDir);
522
+ } catch (err) {
523
+ return errorResult(
524
+ `${pm} failed to start: ${err instanceof Error ? err.message : String(err)}`
525
+ );
526
+ }
527
+ if (result.code !== 0) {
528
+ const tail = (result.stderr || result.stdout).trim().split("\n").slice(-8).join("\n");
529
+ return errorResult(`${pm} ${pmArgs.join(" ")} failed (exit ${result.code}):
530
+ ${tail}`);
531
+ }
532
+ const pkgName = packageNameFromSpec(spec);
533
+ const installPath = join3(targetDir, "node_modules", ...pkgName.split("/"));
534
+ try {
535
+ await fs2.access(installPath);
536
+ } catch {
537
+ return errorResult(
538
+ `${pm} reported success but "${installPath}" does not exist \u2014 check the package name "${pkgName}".`
539
+ );
540
+ }
541
+ const upsert = await upsertPlugin(
542
+ pkgName,
543
+ { enabled: !args.includes("--disabled"), path: installPath },
544
+ deps,
545
+ "Installed"
546
+ );
547
+ if (upsert.code !== 0) return upsert;
548
+ return {
549
+ ...upsert,
550
+ message: `${upsert.message} Loaded from ${installPath}. It will be trusted (pinned) on first load.` + (runScripts ? "" : " Install scripts were skipped (default --ignore-scripts; pass --run-scripts if the package needs build steps).")
551
+ };
552
+ }
553
+
554
+ // src/plugin-management.ts
352
555
  var OFFICIAL_PLUGINS = [
353
556
  {
354
557
  alias: "telegram",
@@ -696,20 +899,6 @@ function renderPluginAuditReport(config) {
696
899
  );
697
900
  return lines.join("\n");
698
901
  }
699
- async function readConfig(file) {
700
- try {
701
- return JSON.parse(await fs.readFile(file, "utf8"));
702
- } catch {
703
- return {};
704
- }
705
- }
706
- function pluginName(p) {
707
- return typeof p === "string" ? p : p.name;
708
- }
709
- function pluginEntry(spec, enabled, path) {
710
- if (path !== void 0) return { name: spec, path, enabled };
711
- return enabled ? spec : { name: spec, enabled: false };
712
- }
713
902
  function pluginMatchesToggleSpec(p, spec) {
714
903
  const name = pluginName(p);
715
904
  if (spec === "telegram") return name === "telegram" || name === "@wrongstack/telegram";
@@ -808,30 +997,6 @@ async function togglePlugin(spec, deps) {
808
997
  restartRequired
809
998
  };
810
999
  }
811
- async function upsertPlugin(spec, opts, deps, verb) {
812
- const existing = await readConfig(deps.configPath);
813
- const plugins = Array.isArray(existing.plugins) ? existing.plugins : [];
814
- const idx = plugins.findIndex((p) => pluginName(p) === spec);
815
- const nextEntry = pluginEntry(spec, opts.enabled, opts.path);
816
- if (idx >= 0) plugins[idx] = nextEntry;
817
- else plugins.push(nextEntry);
818
- const features = {
819
- ...isRecord(deps.config.features) ? deps.config.features : {},
820
- ...isRecord(existing.features) ? existing.features : {},
821
- plugins: true
822
- };
823
- existing.plugins = plugins;
824
- existing.features = features;
825
- await atomicWrite(deps.configPath, JSON.stringify(existing, null, 2), { mode: 384 });
826
- const restartRequired = spec === "branch-guard" && !opts.enabled ? void 0 : true;
827
- return {
828
- code: 0,
829
- level: "info",
830
- message: `${verb} "${spec}" (${opts.enabled ? "enabled" : "disabled"}). Config written to ${deps.configPath}.` + (spec === "branch-guard" && !opts.enabled ? " The running branch-guard hook will disable itself on config update." : ""),
831
- patch: { plugins, features },
832
- restartRequired
833
- };
834
- }
835
1000
  async function removePlugin(spec, deps) {
836
1001
  const existing = await readConfig(deps.configPath);
837
1002
  const plugins = Array.isArray(existing.plugins) ? existing.plugins : [];
@@ -849,12 +1014,6 @@ async function removePlugin(spec, deps) {
849
1014
  restartRequired: true
850
1015
  };
851
1016
  }
852
- function errorResult(message) {
853
- return { code: 1, level: "error", message };
854
- }
855
- function globalPluginsRoot(deps) {
856
- return join2(deps.globalRoot ?? join2(homedir(), ".wrongstack"), "plugins");
857
- }
858
1017
  async function resolveExternalPluginEntry(name, deps) {
859
1018
  const projectRoot = process.cwd();
860
1019
  for (const p of deps.config.plugins ?? []) {
@@ -866,7 +1025,7 @@ async function resolveExternalPluginEntry(name, deps) {
866
1025
  }
867
1026
  const { candidates } = await discoverExternalPlugins2([
868
1027
  globalPluginsRoot(deps),
869
- join2(projectRoot, ".wrongstack", "plugins")
1028
+ join4(projectRoot, ".wrongstack", "plugins")
870
1029
  ]);
871
1030
  const discovered = candidates.find((c) => c.name === name);
872
1031
  if (discovered) return discovered.entryPath;
@@ -886,7 +1045,7 @@ var PLUGIN_TRUST_USAGE = [
886
1045
  " wstack plugin trust <name> --remove Drop the pin (plugin re-trusts on next load)."
887
1046
  ].join("\n");
888
1047
  async function runPluginTrustCommand(args, deps) {
889
- const storePath = defaultPluginTrustPath2(join2(deps.globalRoot ?? join2(homedir(), ".wrongstack")));
1048
+ const storePath = defaultPluginTrustPath2(join4(deps.globalRoot ?? join4(homedir2(), ".wrongstack")));
890
1049
  const positional = args.filter((a) => !a.startsWith("--"));
891
1050
  const name = positional[0];
892
1051
  const remove = args.includes("--remove") || args.includes("--unpin");
@@ -944,151 +1103,10 @@ async function runPluginTrustCommand(args, deps) {
944
1103
  message: `Re-pinned "${name}" \u2192 ${integrity.slice(0, 19)}\u2026 (${canonical}).`
945
1104
  };
946
1105
  }
947
- function detectPackageManager(args) {
948
- const override = args.find((a) => a.startsWith("--pm="));
949
- if (override) {
950
- const pm = override.slice(5);
951
- if (pm === "npm" || pm === "pnpm" || pm === "yarn" || pm === "bun") return pm;
952
- }
953
- const idx = args.indexOf("--pm");
954
- if (idx >= 0 && args[idx + 1]) {
955
- const pm = args[idx + 1];
956
- if (pm === "npm" || pm === "pnpm" || pm === "yarn" || pm === "bun") return pm;
957
- }
958
- const ua = process.env.npm_config_user_agent ?? "";
959
- if (ua.startsWith("pnpm")) return "pnpm";
960
- if (ua.startsWith("yarn")) return "yarn";
961
- if (ua.startsWith("bun")) return "bun";
962
- return "npm";
963
- }
964
- function packageNameFromSpec(spec) {
965
- const stripped = spec.trim();
966
- if (stripped.startsWith("@")) {
967
- const scopedEnd = stripped.indexOf("/", 1);
968
- if (scopedEnd === -1) return stripped.split("@")[0] ?? stripped;
969
- const rest = stripped.slice(scopedEnd + 1);
970
- const at2 = rest.lastIndexOf("@");
971
- return at2 === -1 ? stripped : stripped.slice(0, scopedEnd + 1 + at2);
972
- }
973
- const at = stripped.indexOf("@");
974
- return at === -1 ? stripped : stripped.slice(0, at);
975
- }
976
- function buildInstallArgs(pm, targetDir, runScripts, spec) {
977
- const ignoreScripts = runScripts ? [] : ["--ignore-scripts"];
978
- switch (pm) {
979
- case "pnpm":
980
- return ["add", "--dir", targetDir, ...ignoreScripts, spec];
981
- case "yarn":
982
- return ["add", "--cwd", targetDir, ...ignoreScripts, spec];
983
- case "bun":
984
- return ["add", "--cwd", targetDir, ...ignoreScripts, spec];
985
- default:
986
- return ["install", "--prefix", targetDir, "--no-audit", "--no-fund", ...ignoreScripts, spec];
987
- }
988
- }
989
- function runPackageManagerInstall(pm, args, cwd) {
990
- return new Promise((resolvePromise) => {
991
- let invocation;
992
- try {
993
- invocation = resolveExecInvocation(pm, args);
994
- } catch (err) {
995
- resolvePromise({
996
- code: 127,
997
- stdout: "",
998
- stderr: err instanceof Error ? err.message : String(err)
999
- });
1000
- return;
1001
- }
1002
- execFile(
1003
- invocation.cmd,
1004
- invocation.args,
1005
- {
1006
- cwd,
1007
- // H-8 (security report VF-09): this runs npm/pnpm install — including
1008
- // untrusted package lifecycle scripts — with the full inherited
1009
- // environment. Strip credentials via the shared child env.
1010
- env: buildChildEnv(),
1011
- timeout: 3e5,
1012
- maxBuffer: 16 * 1024 * 1024,
1013
- windowsHide: true,
1014
- ...invocation.windowsVerbatimArguments ? { windowsVerbatimArguments: true } : {}
1015
- },
1016
- (err, stdout, stderr) => {
1017
- const code = err ? err.code ?? 1 : 0;
1018
- resolvePromise({
1019
- code: typeof code === "number" ? code : 1,
1020
- stdout: typeof stdout === "string" ? stdout : "",
1021
- stderr: typeof stderr === "string" ? stderr : ""
1022
- });
1023
- }
1024
- );
1025
- });
1026
- }
1027
- async function installPluginPackage(spec, args, deps) {
1028
- const pm = detectPackageManager(args);
1029
- const runScripts = args.includes("--run-scripts");
1030
- const targetDir = globalPluginsRoot(deps);
1031
- try {
1032
- await fs.mkdir(targetDir, { recursive: true });
1033
- const pkgJsonPath = join2(targetDir, "package.json");
1034
- try {
1035
- await fs.access(pkgJsonPath);
1036
- } catch {
1037
- await fs.writeFile(
1038
- pkgJsonPath,
1039
- `${JSON.stringify({ name: "wrongstack-user-plugins", private: true, version: "0.0.0" }, null, 2)}
1040
- `,
1041
- "utf8"
1042
- );
1043
- }
1044
- } catch (err) {
1045
- return errorResult(
1046
- `Could not prepare plugin directory ${targetDir}: ${err instanceof Error ? err.message : String(err)}`
1047
- );
1048
- }
1049
- const run = deps.runPackageManager ?? runPackageManagerInstall;
1050
- const pmArgs = buildInstallArgs(pm, targetDir, runScripts, spec);
1051
- let result;
1052
- try {
1053
- result = await run(pm, pmArgs, targetDir);
1054
- } catch (err) {
1055
- return errorResult(
1056
- `${pm} failed to start: ${err instanceof Error ? err.message : String(err)}`
1057
- );
1058
- }
1059
- if (result.code !== 0) {
1060
- const tail = (result.stderr || result.stdout).trim().split("\n").slice(-8).join("\n");
1061
- return errorResult(`${pm} ${pmArgs.join(" ")} failed (exit ${result.code}):
1062
- ${tail}`);
1063
- }
1064
- const pkgName = packageNameFromSpec(spec);
1065
- const installPath = join2(targetDir, "node_modules", ...pkgName.split("/"));
1066
- try {
1067
- await fs.access(installPath);
1068
- } catch {
1069
- return errorResult(
1070
- `${pm} reported success but "${installPath}" does not exist \u2014 check the package name "${pkgName}".`
1071
- );
1072
- }
1073
- const upsert = await upsertPlugin(
1074
- pkgName,
1075
- { enabled: !args.includes("--disabled"), path: installPath },
1076
- deps,
1077
- "Installed"
1078
- );
1079
- if (upsert.code !== 0) return upsert;
1080
- return {
1081
- ...upsert,
1082
- message: `${upsert.message} Loaded from ${installPath}. It will be trusted (pinned) on first load.` + (runScripts ? "" : " Install scripts were skipped (default --ignore-scripts; pass --run-scripts if the package needs build steps).")
1083
- };
1084
- }
1085
- function isRecord(value) {
1086
- return Boolean(value) && typeof value === "object" && !Array.isArray(value);
1087
- }
1088
1106
 
1089
1107
  export {
1090
1108
  loadExternalPlugins,
1091
1109
  PLUGIN_AUDIT_ENTRIES,
1092
1110
  runPluginManagementCommand
1093
1111
  };
1094
- //# sourceMappingURL=chunk-SIS37L3W.js.map
1112
+ //# sourceMappingURL=chunk-L2RVEQWO.js.map
@@ -0,0 +1,105 @@
1
+
2
+ // src/preflight.ts
3
+ import { ensureSessionShell } from "@wrongstack/tools/session-shell";
4
+
5
+ // src/cli-update-notice.ts
6
+ import { realpathSync } from "node:fs";
7
+ import { isStandaloneBinary, writeErr } from "@wrongstack/core/utils";
8
+ var NOTICE_FMT = `
9
+ \x1B[33m\u2191 Update available: v%s \u2192 v%s\x1B[0m Run \`wrongstack update\` to upgrade.
10
+
11
+ `;
12
+ var READY_FMT = `
13
+ \x1B[33m\u2191 v%s is downloaded\x1B[0m It replaces this executable when this session exits.
14
+
15
+ `;
16
+ var READY_MANUAL_FMT = `
17
+ \x1B[33m\u2191 v%s is downloaded\x1B[0m Run \`wrongstack update\` to install it.
18
+
19
+ `;
20
+ var APPLIED_FMT = `
21
+ \x1B[32m\u2713 Updated wrongstack v%s \u2192 v%s\x1B[0m
22
+
23
+ `;
24
+ async function printStandaloneUpdateNotice(info, config) {
25
+ const [{ autoUpdateEnabled, standaloneUpdater, takeAppliedUpdate }, { isNewer }, version] = await Promise.all([
26
+ import("./standalone-auto-update-TOTRGCSA.js"),
27
+ import("./update-check-J5ZVKS73.js"),
28
+ import("./version-JB2UAV2A.js")
29
+ ]);
30
+ const applied = takeAppliedUpdate();
31
+ if (applied) writeErr(APPLIED_FMT.replace("%s", applied.from).replace("%s", applied.to));
32
+ const pending = standaloneUpdater({
33
+ executable: realpathSync(process.execPath),
34
+ target: version.STANDALONE_TARGET ?? "",
35
+ current: version.CLI_VERSION
36
+ }).pending();
37
+ if (pending && info && isNewer(pending.version, info.current) && pending.version === info.latest) {
38
+ const fmt = autoUpdateEnabled(config) ? READY_FMT : READY_MANUAL_FMT;
39
+ writeErr(fmt.replace("%s", pending.version));
40
+ return true;
41
+ }
42
+ return false;
43
+ }
44
+ async function printUpdateNotice(initialUpdateInfo, config) {
45
+ let info = initialUpdateInfo;
46
+ if (!info?.outdated) {
47
+ const ac = new AbortController();
48
+ const timer = setTimeout(() => ac.abort(), 2e3);
49
+ try {
50
+ const { checkForUpdate } = await import("./update-check-J5ZVKS73.js");
51
+ info = await checkForUpdate(ac.signal);
52
+ } catch {
53
+ } finally {
54
+ clearTimeout(timer);
55
+ }
56
+ }
57
+ let reported = false;
58
+ if (isStandaloneBinary()) {
59
+ try {
60
+ reported = await printStandaloneUpdateNotice(info, config);
61
+ } catch {
62
+ }
63
+ }
64
+ if (info?.outdated && !reported) {
65
+ writeErr(NOTICE_FMT.replace("%s", info.current).replace("%s", info.latest));
66
+ }
67
+ return info;
68
+ }
69
+
70
+ // src/preflight.ts
71
+ function applyNodeEnvDefault() {
72
+ if (process.env["NODE_ENV"] === void 0) {
73
+ process.env["NODE_ENV"] = "production";
74
+ process.env["WRONGSTACK_NODE_ENV_DEFAULTED"] = "1";
75
+ }
76
+ }
77
+ function applySessionShellDefault() {
78
+ ensureSessionShell();
79
+ }
80
+ async function applyPrintUpdateNotice(initialUpdateInfo, config) {
81
+ return await printUpdateNotice(initialUpdateInfo, config);
82
+ }
83
+ async function applyDebugStreamSeed(config) {
84
+ const { setDebugStreamEnabled } = await import("@wrongstack/providers");
85
+ if (config.debugStream) {
86
+ setDebugStreamEnabled(true);
87
+ }
88
+ }
89
+ async function runPreflight(config, initialUpdateInfo) {
90
+ applyNodeEnvDefault();
91
+ applySessionShellDefault();
92
+ const updateInfo = await applyPrintUpdateNotice(initialUpdateInfo, config);
93
+ await applyDebugStreamSeed(config);
94
+ return {
95
+ updateInfo,
96
+ debugStreamEnabled: Boolean(config.debugStream)
97
+ };
98
+ }
99
+
100
+ export {
101
+ applyNodeEnvDefault,
102
+ applySessionShellDefault,
103
+ runPreflight
104
+ };
105
+ //# sourceMappingURL=chunk-LBPLTTZ6.js.map
@@ -0,0 +1,46 @@
1
+ import {
2
+ mutateConfigProviders
3
+ } from "./chunk-LUMETJFO.js";
4
+ import {
5
+ activeProfileConfigPath
6
+ } from "./chunk-YMXXOOFN.js";
7
+
8
+ // src/wiring/provider-persisters.ts
9
+ import {
10
+ applyProviderOAuthRefresh,
11
+ matchesActiveProviderCredential,
12
+ setOAuthTokenPersister,
13
+ setProviderModelPersister
14
+ } from "@wrongstack/providers";
15
+ import { applyProviderOAuthRefresh as applyProviderOAuthRefresh2 } from "@wrongstack/providers";
16
+ function installProviderPersisters(args) {
17
+ const profileConfigPath = activeProfileConfigPath(args.paths, args.config);
18
+ setOAuthTokenPersister((providerId, creds, source) => {
19
+ void mutateConfigProviders(profileConfigPath, args.vault, (all) => {
20
+ const p = all[providerId];
21
+ if (!p) return;
22
+ applyProviderOAuthRefresh(p, creds, source);
23
+ }).catch(
24
+ () => args.logger?.warn(
25
+ `OAuth token refresh for "${providerId}" could not be saved. Sign-in may be required next session.`
26
+ )
27
+ );
28
+ });
29
+ setProviderModelPersister((providerId, models, source) => {
30
+ if (models.length === 0) return;
31
+ void mutateConfigProviders(profileConfigPath, args.vault, (all) => {
32
+ const p = all[providerId];
33
+ if (!p) return;
34
+ if (source && !matchesActiveProviderCredential(p, source)) return;
35
+ const live = models.map((m) => m.id);
36
+ if (p.models?.length === live.length && p.models.every((id, i) => id === live[i])) return;
37
+ p.models = live;
38
+ }).catch(() => args.logger?.warn(`Model discovery for "${providerId}" could not be saved.`));
39
+ });
40
+ }
41
+
42
+ export {
43
+ installProviderPersisters,
44
+ applyProviderOAuthRefresh2 as applyProviderOAuthRefresh
45
+ };
46
+ //# sourceMappingURL=chunk-LDCGZJTC.js.map