@wrongstack/cli 1.0.19 → 1.0.24

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 (124) hide show
  1. package/dist/{acp-INCNOH42.js → acp-AJWSKWE5.js} +18 -7
  2. package/dist/arg-parser.d.ts +1 -0
  3. package/dist/{auth-YXK3EDUL.js → auth-GRBZ7Y3D.js} +61 -15
  4. package/dist/auth-menu/direct.d.ts +1 -0
  5. package/dist/auth-menu/local.d.ts +2 -0
  6. package/dist/auth-menu/oauth-menu.d.ts +3 -1
  7. package/dist/auth-menu/panel-service.d.ts +20 -0
  8. package/dist/{bench-YBU6BVQP.js → bench-N5K7Z5O3.js} +2 -2
  9. package/dist/boot/config-backup-recovery.d.ts +2 -1
  10. package/dist/boot/dispatch-webui.d.ts +11 -0
  11. package/dist/boot/short-circuit-desktop.d.ts +1 -0
  12. package/dist/boot/tui-project-picker-callback.d.ts +1 -1
  13. package/dist/boot/tui-settings-adapter.d.ts +15 -2
  14. package/dist/{boot-auto-thin-MANHOYHE.js → boot-auto-thin-6Q56FY3F.js} +3 -2
  15. package/dist/{chunk-6WRKAACA.js → chunk-2BKFWIER.js} +4 -2
  16. package/dist/{chunk-JY52HWL6.js → chunk-2EBVTYJR.js} +2 -2
  17. package/dist/chunk-3OCUS3VN.js +46 -0
  18. package/dist/chunk-424ORSE7.js +56 -0
  19. package/dist/{chunk-KEPABQYT.js → chunk-5SEYGOCH.js} +8 -82
  20. package/dist/chunk-BBHWW6LR.js +549 -0
  21. package/dist/{chunk-CJTBLTS4.js → chunk-BLD5DSVA.js} +4 -3
  22. package/dist/{chunk-KK2LB3ZS.js → chunk-DRM7PSW7.js} +9 -5
  23. package/dist/{chunk-XJ7K67PP.js → chunk-JF2MULWF.js} +17 -10
  24. package/dist/{chunk-SIS37L3W.js → chunk-L2RVEQWO.js} +211 -193
  25. package/dist/{chunk-RDHFXOJM.js → chunk-LFMVHT3R.js} +106 -57
  26. package/dist/chunk-LUMETJFO.js +171 -0
  27. package/dist/{chunk-C3Z4N6A6.js → chunk-MHEBWVXL.js} +6 -2
  28. package/dist/{chunk-2ENZU66X.js → chunk-PGKJ2OQP.js} +5 -5
  29. package/dist/{chunk-672UXYL3.js → chunk-QBBF7GIK.js} +2 -2
  30. package/dist/{chunk-DE7BZDNK.js → chunk-QFPQXKCG.js} +11 -3
  31. package/dist/chunk-R4QGL6GB.js +10 -0
  32. package/dist/chunk-S4FFHDJG.js +93 -0
  33. package/dist/chunk-SFBFYIOW.js +271 -0
  34. package/dist/{chunk-JX6KL7OF.js → chunk-SKPDE62W.js} +4 -3
  35. package/dist/{chunk-RMQNCHGO.js → chunk-U46QR4WR.js} +5 -9
  36. package/dist/{chunk-B4JLSXZB.js → chunk-WSTVGC2C.js} +73 -45
  37. package/dist/chunk-YBUCXXYZ.js +36 -0
  38. package/dist/{chunk-2VMJ3E5Z.js → chunk-YTEOAWOJ.js} +6 -2
  39. package/dist/{chunk-GPPRNAKW.js → chunk-ZMX5HRLI.js} +2 -2
  40. package/dist/{chunk-YLQEGYV4.js → chunk-ZZRSG7VK.js} +14 -4
  41. package/dist/{cli-context-33F74CSZ.js → cli-context-34Q5IJRA.js} +121 -89
  42. package/dist/cli-entry-point.d.ts +2 -0
  43. package/dist/{cli-main-FNGMKPBA.js → cli-main-AELJDBGU.js} +1439 -1276
  44. package/dist/config-doctor.d.ts +10 -2
  45. package/dist/{config-transfer-2YF3CRTN.js → config-transfer-RUWLDCNK.js} +34 -13
  46. package/dist/{diag-doctor-ANPRUYFM.js → diag-doctor-WIFJH3XH.js} +2 -2
  47. package/dist/execute-deps.d.ts +2 -1
  48. package/dist/{execution-A6WJLSOC.js → execution-PYC5FCS4.js} +303 -256
  49. package/dist/{hq-XQWQTRDA.js → hq-JTUTFI4L.js} +274 -258
  50. package/dist/hq-command-controller.d.ts +1 -1
  51. package/dist/{hq-server-IIBZQZU4.js → hq-server-PC7GZMPT.js} +2 -2
  52. package/dist/{hq-service-L5INQFM4.js → hq-service-NW56MUP2.js} +11 -4
  53. package/dist/index.d.ts +1 -1
  54. package/dist/index.js +17 -12
  55. package/dist/kanban-supervisor-67ECABTD.js +7 -0
  56. package/dist/live-settings-input.d.ts +7 -0
  57. package/dist/{mailbox-serve-3GFOK2I7.js → mailbox-serve-WDOCH6KR.js} +3 -3
  58. package/dist/{mcp-DC5WSBOO.js → mcp-LBS45HWZ.js} +4 -4
  59. package/dist/modeldiag-36OGAL5C.js +828 -0
  60. package/dist/{per-subcommand-help-DHTYU524.js → per-subcommand-help-XE77MTGJ.js} +3 -3
  61. package/dist/permission-prompt-mirror.d.ts +1 -1
  62. package/dist/permission-prompt.d.ts +2 -2
  63. package/dist/plugin-config.d.ts +12 -0
  64. package/dist/plugin-management-types.d.ts +31 -0
  65. package/dist/plugin-management.d.ts +2 -30
  66. package/dist/plugin-package-install.d.ts +3 -0
  67. package/dist/{plugin-usage-M6KET4OZ.js → plugin-usage-S5LVGMBW.js} +6 -5
  68. package/dist/{plugins-WJLW6ULV.js → plugins-RHBIVLI7.js} +4 -3
  69. package/dist/provider-config-utils.d.ts +1 -6
  70. package/dist/{providers-models-LFNZ5WI7.js → providers-models-2CFG46RD.js} +41 -31
  71. package/dist/release-asset-download.d.ts +3 -0
  72. package/dist/services/dispatch-classifier.d.ts +39 -5
  73. package/dist/{sessions-config-UL45XKX7.js → sessions-config-IQUH2GXT.js} +13 -5
  74. package/dist/settings-menu.d.ts +2 -0
  75. package/dist/short-circuit-flags-SDT53OML.js +10 -0
  76. package/dist/{simpleui-dist-CXSIDAXZ.js → simpleui-dist-7BQISSEP.js} +7 -3
  77. package/dist/skill-suggest-L2EVWB6R.js +290 -0
  78. package/dist/slash-commands/effort.d.ts +1 -1
  79. package/dist/slash-commands/fallback.d.ts +1 -1
  80. package/dist/slash-commands/gitid.d.ts +1 -1
  81. package/dist/slash-commands/jev.d.ts +4 -0
  82. package/dist/slash-commands/openai-quota.d.ts +15 -0
  83. package/dist/slash-commands/sdd-task-mutations.d.ts +4 -0
  84. package/dist/slash-commands/settings-keys.d.ts +2 -0
  85. package/dist/slash-commands/settings-reset.d.ts +6 -0
  86. package/dist/standalone-update-MW47J3AK.js +164 -0
  87. package/dist/standalone-update.d.ts +19 -0
  88. package/dist/subcommands/handlers/hq-alerts.d.ts +3 -0
  89. package/dist/subcommands/handlers/hq-audit.d.ts +46 -0
  90. package/dist/subcommands/handlers/hq-data-dir.d.ts +13 -0
  91. package/dist/subcommands/handlers/skill-suggest.d.ts +21 -0
  92. package/dist/subcommands/handlers/typesafe-brain-replay.d.ts +26 -0
  93. package/dist/subcommands/handlers/typesafe-judgment-check.d.ts +3 -0
  94. package/dist/subcommands/handlers/typesafe-topic-replay.d.ts +19 -0
  95. package/dist/subcommands/handlers/typesafe-triage-replay.d.ts +18 -0
  96. package/dist/subcommands/handlers/typesafe.d.ts +23 -0
  97. package/dist/{subcommands-XSLXMIDP.js → subcommands-ZTSIN7LG.js} +2 -2
  98. package/dist/typesafe-HVEVPA6R.js +316 -0
  99. package/dist/typesafe-brain-replay-C5276FVR.js +222 -0
  100. package/dist/typesafe-judgment-check-GGYYV5UF.js +29 -0
  101. package/dist/typesafe-topic-replay-4W73BOLV.js +218 -0
  102. package/dist/typesafe-triage-replay-FGAW7QM7.js +215 -0
  103. package/dist/{update-5DPB4YD4.js → update-7XIOEXTD.js} +4 -3
  104. package/dist/{update-check-BS3DHTSI.js → update-check-2POMBHFB.js} +3 -2
  105. package/dist/update-check.d.ts +1 -1
  106. package/dist/version-help-WZ623NWM.js +10 -0
  107. package/dist/version.d.ts +3 -2
  108. package/dist/webui-client-observability.d.ts +7 -0
  109. package/dist/{webui-server-MRPGTTKL.js → webui-server-L2SICPTB.js} +158 -94
  110. package/dist/webui-server-options.d.ts +11 -0
  111. package/dist/webui-server.d.ts +15 -1
  112. package/dist/wiring/domain-glossary.d.ts +5 -4
  113. package/dist/wiring/plugins.d.ts +1 -1
  114. package/dist/wiring/provider-persisters.d.ts +24 -0
  115. package/dist/wiring/provider-runtime.d.ts +9 -1
  116. package/dist/wiring/runtime-dispatch-state.d.ts +3 -1
  117. package/package.json +28 -28
  118. package/dist/chunk-2CZEORLV.js +0 -54
  119. package/dist/chunk-DR2OXU46.js +0 -174
  120. package/dist/chunk-JACOMTIH.js +0 -275
  121. package/dist/chunk-XJXDOF63.js +0 -28
  122. package/dist/modeldiag-CJSFHZ3J.js +0 -1356
  123. package/dist/short-circuit-flags-7GQIGMVD.js +0 -10
  124. 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