@wrongstack/cli 1.1.4 → 1.1.5

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 (100) hide show
  1. package/dist/{acp-MZ5MQBFN.js → acp-NKUEYJDZ.js} +6 -5
  2. package/dist/acp-leader/acp-leader-confirm.d.ts +2 -0
  3. package/dist/acp-leader/acp-leader-host-binding.d.ts +1 -0
  4. package/dist/acp-leader/acp-leader-host.d.ts +2 -0
  5. package/dist/acp-leader/acp-leader-picker.d.ts +6 -3
  6. package/dist/acp-leader/acp-leader-stream.d.ts +1 -0
  7. package/dist/{auth-IHQS6AFW.js → auth-2ZG5DBHS.js} +4 -4
  8. package/dist/boot/launch-menu-arrow.d.ts +20 -0
  9. package/dist/boot/launch-menu-types.d.ts +36 -0
  10. package/dist/boot/launch-menu.d.ts +1 -57
  11. package/dist/boot/tui-session-resume-rollback.d.ts +31 -0
  12. package/dist/{boot-auto-thin-7D4OVEWA.js → boot-auto-thin-N2CIGTXE.js} +3 -3
  13. package/dist/{chunk-TZPKOS5G.js → chunk-2XQ6SRKG.js} +2 -2
  14. package/dist/{chunk-JKTJSLUT.js → chunk-5SGMUDP5.js} +242 -18
  15. package/dist/{chunk-3EXRPTAU.js → chunk-5TQ65PXQ.js} +17 -17
  16. package/dist/{chunk-2LTHDKZX.js → chunk-7BM4LGKQ.js} +18 -18
  17. package/dist/{chunk-VAQXOZKP.js → chunk-AJM4EFCM.js} +139 -136
  18. package/dist/{chunk-C2BBH4S4.js → chunk-E3MJFAFR.js} +2 -2
  19. package/dist/{chunk-AWRZWPJ3.js → chunk-JFYQGMMM.js} +99 -75
  20. package/dist/{chunk-BIGSVBPI.js → chunk-KNYIEQAY.js} +64 -61
  21. package/dist/{chunk-GKGWPFW2.js → chunk-LUEO5HLZ.js} +1 -1
  22. package/dist/chunk-LYWOV4OX.js +252 -0
  23. package/dist/{chunk-COGI7EQU.js → chunk-M7FNHCE3.js} +621 -9
  24. package/dist/{chunk-75OLD563.js → chunk-M7PSENGF.js} +3 -1
  25. package/dist/{chunk-TAE3EGBM.js → chunk-MEBXWI7U.js} +5 -5
  26. package/dist/{chunk-I5LJLKA3.js → chunk-MKMM5RIW.js} +12 -5
  27. package/dist/{chunk-ZF4HRR5F.js → chunk-P7MEEUGT.js} +275 -250
  28. package/dist/chunk-QLYPIJ7X.js +258 -0
  29. package/dist/chunk-RN5CFAVQ.js +292 -0
  30. package/dist/{chunk-WDXNBYGD.js → chunk-TDP7CZGE.js} +6 -1
  31. package/dist/{chunk-6VPWQ4TG.js → chunk-UROB7MK5.js} +2 -1
  32. package/dist/chunk-VEESMPTX.js +254 -0
  33. package/dist/{chunk-IJLIAPCW.js → chunk-VPSAKGLK.js} +47 -47
  34. package/dist/{cli-context-E44HQ4ZO.js → cli-context-CQYGIWOU.js} +247 -236
  35. package/dist/{cli-main-OT63I2FX.js → cli-main-VRUJNUBX.js} +1743 -1491
  36. package/dist/cli-main-boot.d.ts +1 -1
  37. package/dist/config-doctor-known-keys.d.ts +33 -0
  38. package/dist/config-doctor.d.ts +2 -47
  39. package/dist/config-history-support.d.ts +36 -0
  40. package/dist/config-history.d.ts +1 -1
  41. package/dist/{config-transfer-Y7XJMJRN.js → config-transfer-B4GOZTFC.js} +2 -2
  42. package/dist/{execution-OK34CJKJ.js → execution-IV72RUSM.js} +5883 -5792
  43. package/dist/execution-tui.d.ts +30 -0
  44. package/dist/fleet/acp-wrongstack-bridge.d.ts +11 -3
  45. package/dist/fleet/host-acp.d.ts +3 -0
  46. package/dist/fleet/wrongforge-client.d.ts +116 -0
  47. package/dist/fleet/wrongforge-gateway.d.ts +20 -0
  48. package/dist/fleet/wrongforge-info.d.ts +32 -0
  49. package/dist/fleet/wrongforge-quota.d.ts +10 -0
  50. package/dist/fleet/wrongforge-runner.d.ts +37 -0
  51. package/dist/fleet/wrongforge-runtime.d.ts +10 -0
  52. package/dist/{hq-JD5AZVMG.js → hq-54PQYR5O.js} +311 -307
  53. package/dist/hq-server/sweeps.d.ts +28 -0
  54. package/dist/{hq-server-BI23EPM7.js → hq-server-YK7FBLL6.js} +3 -3
  55. package/dist/index.js +5 -5
  56. package/dist/mcp-22CFBX4H.js +236 -0
  57. package/dist/mcp-serve.d.ts +0 -63
  58. package/dist/{modeldiag-HDIKG37X.js → modeldiag-5PBB777J.js} +4 -4
  59. package/dist/{per-subcommand-help-4GYSCMLU.js → per-subcommand-help-MQGERD4E.js} +2 -2
  60. package/dist/plugin-llm-command.d.ts +9 -0
  61. package/dist/{plugin-usage-TYF5HY4K.js → plugin-usage-UWKYMNQU.js} +3 -3
  62. package/dist/{plugins-XGAXDLPT.js → plugins-VP7JQH47.js} +4 -4
  63. package/dist/{sdd-runtime-6MFUXWJK.js → sdd-runtime-HIJ4Z5TF.js} +2 -2
  64. package/dist/services/sdd/state.d.ts +2 -0
  65. package/dist/session-event-wiring-types.d.ts +62 -0
  66. package/dist/session-event-wiring.d.ts +2 -52
  67. package/dist/{sessions-config-SJVQXCIE.js → sessions-config-7MK742OW.js} +2 -2
  68. package/dist/short-circuit-flags-AGHURHMQ.js +11 -0
  69. package/dist/slash-commands/command-context-fleet.d.ts +187 -0
  70. package/dist/slash-commands/command-context-sdd-goal.d.ts +102 -0
  71. package/dist/slash-commands/command-context.d.ts +3 -282
  72. package/dist/slash-commands/project-switch-interactive.d.ts +11 -0
  73. package/dist/slash-commands/setmodel-helpers.d.ts +36 -0
  74. package/dist/subcommands/handlers/hq-token.d.ts +3 -0
  75. package/dist/subcommands/handlers/hq.d.ts +0 -21
  76. package/dist/subcommands/handlers/per-subcommand-help-operations.d.ts +8 -0
  77. package/dist/subcommands/handlers/tools-cli-args.d.ts +57 -0
  78. package/dist/subcommands/handlers/tools-cli.d.ts +5 -0
  79. package/dist/subcommands/handlers/tools-serve.d.ts +4 -0
  80. package/dist/{subcommands-YADUV7IJ.js → subcommands-OCJNO57E.js} +2 -2
  81. package/dist/tool-gateway-http.d.ts +30 -0
  82. package/dist/tool-gateway.d.ts +185 -0
  83. package/dist/tools-cli-44MLIUQO.js +509 -0
  84. package/dist/tools-serve-TRCET2M7.js +102 -0
  85. package/dist/{tools-skills-55QVTMSK.js → tools-skills-WDTMCE46.js} +7 -2
  86. package/dist/tuneup-runtime-checks.d.ts +7 -0
  87. package/dist/tuneup-types.d.ts +118 -0
  88. package/dist/tuneup.d.ts +3 -122
  89. package/dist/{typesafe-YBEADNAH.js → typesafe-QLSMFU7J.js} +1 -1
  90. package/dist/{version-help-RBZC5GZZ.js → version-help-X6CC4CFY.js} +2 -2
  91. package/dist/{webui-server-CB64CFDG.js → webui-server-V2R5WQUK.js} +44 -6
  92. package/dist/wiring/provider-runtime-setup.d.ts +3 -1
  93. package/dist/wiring/session-runtime.d.ts +1 -1
  94. package/dist/wrongforge-gateway-UOFBK56J.js +92 -0
  95. package/dist/wrongforge-leader/wrongforge-leader-gateway.d.ts +9 -0
  96. package/dist/wrongforge-leader/wrongforge-leader-picker.d.ts +12 -0
  97. package/dist/wrongforge-leader/wrongforge-leader-provider.d.ts +49 -0
  98. package/package.json +1 -1
  99. package/dist/mcp-W7A5HUXV.js +0 -560
  100. package/dist/short-circuit-flags-QEXUS3BY.js +0 -11
@@ -1,3 +1,7 @@
1
+ import {
2
+ resolveWrongForgeEndpoint,
3
+ wrongForgeCall
4
+ } from "./chunk-VEESMPTX.js";
1
5
 
2
6
  // src/fleet/acp-wrongstack-bridge.ts
3
7
  import { statSync } from "node:fs";
@@ -17,6 +21,43 @@ function wstackLaunch(args, entry = process.argv[1]) {
17
21
  }
18
22
  return { command: "wstack", args };
19
23
  }
24
+ function wstackToolsCommand(entry = process.argv[1], platform = process.platform) {
25
+ const launch = wstackLaunch(["tools"], entry);
26
+ return [launch.command, ...launch.args].map((word) => shellWord(word, platform)).join(" ");
27
+ }
28
+ function shellWord(word, platform) {
29
+ const w = platform === "win32" ? word.replace(/\\/g, "/") : word;
30
+ return /^[A-Za-z0-9_./:@=+-]+$/.test(w) ? w : `"${w.replace(/(["\\$`])/g, "\\$1")}"`;
31
+ }
32
+ function cliIndexNote(cmd) {
33
+ return [
34
+ `- \`${cmd} run <tool> -- --<field> <value>\` (run through your shell): a prebuilt, ranked`,
35
+ " symbol index of this repository, caught up with the disk on every call. Prefer it over",
36
+ ' grep/glob and whole-file reads for code navigation: codebase-context --query "<task>"',
37
+ " (files relevant to a task), codebase-search --query <name> (where something is defined),",
38
+ " codebase-incoming-calls / codebase-outgoing-calls --symbol <name> (callers, callees),",
39
+ " codebase-read-symbol --file <path> --symbol <name> (one symbol's source),",
40
+ " codebase-skeleton --path <file-or-dir> (an outline), codebase-impact-analysis --symbol",
41
+ ` <name> (what a change affects). \`${cmd} describe <tool>\` lists a tool's fields;`,
42
+ ` \`${cmd} batch\` runs several JSONL calls ({"tool":\u2026,"input":\u2026}) in one process.`,
43
+ " Use grep for literal text such as strings, comments and config values."
44
+ ];
45
+ }
46
+ function serviceNotes(servers, delegated, indexCli) {
47
+ const viaCli = indexCli !== void 0 && servers.includes("codebase-index");
48
+ const mcp = viaCli ? servers.filter((s) => s !== "codebase-index") : servers;
49
+ return [
50
+ ...mcp.length > 0 ? [
51
+ "WrongStack's project services are available as MCP servers:",
52
+ ...mcp.map((s) => SERVER_NOTES[s](delegated))
53
+ ] : [],
54
+ ...viaCli ? [
55
+ ...mcp.length > 0 ? [""] : [],
56
+ "WrongStack's codebase index is available through its CLI:",
57
+ ...cliIndexNote(indexCli)
58
+ ] : []
59
+ ];
60
+ }
20
61
  var SERVER_NAMES = {
21
62
  sage: "wrongstack-sage",
22
63
  mailbox: "wrongstack-mailbox",
@@ -31,9 +72,15 @@ var SERVER_NOTES = {
31
72
  "codebase-index": () => "- wrongstack-index: a prebuilt, ranked symbol index of this repository, kept fresh by WrongStack. Prefer it over grep/glob and whole-file reads for code navigation: codebase_search (where something is defined), codebase_incoming_calls / codebase_outgoing_calls (callers, callees), codebase_read_symbol (one symbol's source), codebase_skeleton (a file or folder outline), codebase_impact_analysis (what a change affects), codebase_context (files relevant to a task), codebase_repo_map (overview). Use grep for literal text such as strings, comments and config values.",
32
73
  "requirement-intake": () => "- wrongstack-intake: the project's requirements intake. List open requests; file a new one when you are handed an unrecorded software request."
33
74
  };
34
- function serviceWorkflow(servers) {
75
+ function serviceWorkflow(servers, indexCli) {
35
76
  return [
36
- ...servers.includes("codebase-index") ? [
77
+ ...servers.includes("codebase-index") ? indexCli !== void 0 ? [
78
+ "Use the WrongStack index first for code navigation; use your file tools for edits,",
79
+ "exact literal searches, and verification. Start a code task with",
80
+ `${indexCli} run codebase-context -- --query "<the task in a few words>"; for a named`,
81
+ `symbol use ${indexCli} run codebase-search -- --query <name>. If the index lacks a`,
82
+ "result, fall back to your tools."
83
+ ] : [
37
84
  "Use wrongstack-index first for code navigation; use your file tools for edits, exact",
38
85
  "literal searches, and verification. Start a code task with",
39
86
  "mcp__wrongstack-index__codebase_context (task description); for a named symbol use",
@@ -57,10 +104,12 @@ function serviceWorkflow(servers) {
57
104
  "If a project service is unavailable, continue with available tools and report the gap."
58
105
  ];
59
106
  }
60
- function bridgeTaskKickoff(servers) {
107
+ function bridgeTaskKickoff(servers, indexCli) {
61
108
  return [
62
109
  "Project-service kickoff for this task:",
63
- ...servers.includes("codebase-index") ? ["First use mcp__wrongstack-index__codebase_context to locate relevant code."] : [],
110
+ ...servers.includes("codebase-index") ? [
111
+ indexCli !== void 0 ? `First run ${indexCli} run codebase-context -- --query "<the task>" to locate relevant code.` : "First use mcp__wrongstack-index__codebase_context to locate relevant code."
112
+ ] : [],
64
113
  ...servers.includes("sage") ? ["Use mcp__wrongstack-sage__memory_search for prior project guidance."] : [],
65
114
  ...servers.includes("mailbox") ? ['Check mcp__wrongstack-mailbox__mailbox_read with action "inbox".'] : [],
66
115
  ...servers.includes("kanban") ? ["If the task names a board card, inspect it with mcp__wrongstack-kanban__kanban_read."] : [],
@@ -93,7 +142,7 @@ function serverArgs(server, projectRoot, ctx) {
93
142
  return [...base, "--writable"];
94
143
  }
95
144
  }
96
- function bridgeNote(servers, delegated = true) {
145
+ function bridgeNote(servers, delegated = true, indexCli) {
97
146
  return [
98
147
  "You are working as a delegated worker inside a WrongStack project.",
99
148
  "WrongStack is the orchestrator the user runs: it sent you this task and receives your",
@@ -104,10 +153,9 @@ function bridgeNote(servers, delegated = true) {
104
153
  "from the user who delegated the task, and answer what it asks."
105
154
  ] : [],
106
155
  "",
107
- "WrongStack's project services are available as MCP servers:",
108
- ...servers.map((s) => SERVER_NOTES[s](delegated)),
156
+ ...serviceNotes(servers, delegated, indexCli),
109
157
  "",
110
- ...serviceWorkflow(servers),
158
+ ...serviceWorkflow(servers, indexCli),
111
159
  "",
112
160
  "WrongStack applies the user's rules to your edits and commands. A refused permission",
113
161
  "comes from them (a deny rule the user wrote, a history-rewriting git command, a",
@@ -115,15 +163,14 @@ function bridgeNote(servers, delegated = true) {
115
163
  "was refused in your final reply."
116
164
  ].join("\n");
117
165
  }
118
- function leaderBridgeNote(servers) {
166
+ function leaderBridgeNote(servers, indexCli) {
119
167
  return [
120
168
  "You are the leader of a WrongStack session. The user talks to you through WrongStack",
121
169
  "(its terminal UI or web UI), which shows your replies, your tool calls and their results.",
122
170
  "",
123
- "WrongStack's project services are available as MCP servers:",
124
- ...servers.map((s) => SERVER_NOTES[s](false)),
171
+ ...serviceNotes(servers, false, indexCli),
125
172
  "",
126
- ...serviceWorkflow(servers),
173
+ ...serviceWorkflow(servers, indexCli),
127
174
  "",
128
175
  "WrongStack applies the user's rules to your edits and commands and asks the user when one",
129
176
  "needs approval. A refused permission is the user's decision or rule: do not retry it or",
@@ -167,21 +214,24 @@ function installedBridgeAgents(acp, isOnPath = (c) => onPath(c)) {
167
214
  }
168
215
  function wrongstackBridgeSetup(agentId, projectRoot, config, role = "worker") {
169
216
  const agents = config?.agents ?? DEFAULT_BRIDGE_AGENTS;
170
- if (!agents.some((a) => a === agentId || REGISTRY_ID_ALIASES[a] === agentId)) return void 0;
217
+ const listed = (a) => a === agentId || REGISTRY_ID_ALIASES[a] === agentId || REGISTRY_ID_ALIASES[agentId] === a;
218
+ if (!agents.some(listed)) return void 0;
171
219
  const servers = [...new Set(config?.servers ?? DEFAULT_BRIDGE_SERVERS)].filter(
172
220
  (s) => Object.hasOwn(SERVER_NAMES, s)
173
221
  );
174
222
  if (servers.length === 0) return void 0;
223
+ const indexCli = config?.indexSurface === "cli" && servers.includes("codebase-index") ? wstackToolsCommand() : void 0;
224
+ const attached = indexCli ? servers.filter((s) => s !== "codebase-index") : servers;
175
225
  return (_task, ctx) => ({
176
- promptPrefix: bridgeTaskKickoff(servers),
177
- mcpServers: servers.map((server) => {
226
+ promptPrefix: bridgeTaskKickoff(servers, indexCli),
227
+ mcpServers: attached.map((server) => {
178
228
  const launch = wstackLaunch(serverArgs(server, projectRoot, ctx));
179
229
  return { name: SERVER_NAMES[server], ...launch, env: [] };
180
230
  }),
181
231
  meta: {
182
232
  systemPrompt: {
183
233
  // `@session` only reaches someone when a WrongStack session delegated the task.
184
- append: role === "leader" ? leaderBridgeNote(servers) : bridgeNote(servers, ctx.sessionId !== void 0)
234
+ append: role === "leader" ? leaderBridgeNote(servers, indexCli) : bridgeNote(servers, ctx.sessionId !== void 0, indexCli)
185
235
  }
186
236
  }
187
237
  });
@@ -517,12 +567,186 @@ ${command}
517
567
  }
518
568
  }
519
569
 
570
+ // src/fleet/wrongforge-info.ts
571
+ import { mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
572
+ import path from "node:path";
573
+ import { wstackGlobalRoot } from "@wrongstack/core/utils";
574
+ function wrongForgeInfoCacheFile() {
575
+ return path.join(wstackGlobalRoot(), "cache", "wrongforge-info.json");
576
+ }
577
+ function parseWrongForgeInfo(body) {
578
+ const o = body && typeof body === "object" ? body : {};
579
+ const strings = (v) => Array.isArray(v) ? v.filter((x) => typeof x === "string" && x.length > 0) : [];
580
+ const def = o["default_model"] ?? o["defaultModel"];
581
+ const details = o["model_details"] ?? o["modelDetails"];
582
+ const effort = o["effort"];
583
+ const levels = effort?.levels ?? o["effortLevels"];
584
+ return {
585
+ models: strings(o["models"]),
586
+ ...typeof def === "string" && def ? { defaultModel: def } : {},
587
+ features: strings(o["features"]),
588
+ ...Array.isArray(levels) ? { effortLevels: strings(levels) } : {},
589
+ ...Array.isArray(details) ? {
590
+ modelDetails: details.flatMap((value) => {
591
+ if (!value || typeof value !== "object") return [];
592
+ const d = value;
593
+ if (typeof d["id"] !== "string" || !d["id"]) return [];
594
+ return [
595
+ {
596
+ id: d["id"],
597
+ description: typeof d["description"] === "string" ? d["description"] : "",
598
+ effortLevels: strings(d["effort_levels"] ?? d["effortLevels"])
599
+ }
600
+ ];
601
+ })
602
+ } : {}
603
+ };
604
+ }
605
+ function readCachedWrongForgeInfo(file = wrongForgeInfoCacheFile()) {
606
+ try {
607
+ const info = parseWrongForgeInfo(JSON.parse(readFileSync(file, "utf8").replace(/^\uFEFF/, "")));
608
+ return info.models.length > 0 ? info : void 0;
609
+ } catch {
610
+ return void 0;
611
+ }
612
+ }
613
+ function writeWrongForgeInfoCache(info, file = wrongForgeInfoCacheFile()) {
614
+ if (info.models.length === 0) return;
615
+ try {
616
+ mkdirSync(path.dirname(file), { recursive: true });
617
+ const tmp = `${file}.${process.pid}.tmp`;
618
+ writeFileSync(tmp, `${JSON.stringify(info)}
619
+ `);
620
+ renameSync(tmp, file);
621
+ } catch {
622
+ }
623
+ }
624
+ async function fetchWrongForgeInfo(ep, opts = {}) {
625
+ const res = await (opts.fetchImpl ?? fetch)(`${ep.url}/v1/info`, {
626
+ headers: { authorization: `Bearer ${ep.apiKey}` },
627
+ ...opts.signal ? { signal: opts.signal } : {}
628
+ });
629
+ if (!res.ok) throw new Error(`WrongForge /v1/info answered ${res.status}`);
630
+ return parseWrongForgeInfo(await res.json());
631
+ }
632
+ function refreshWrongForgeInfoCache(ep) {
633
+ if (!ep) return;
634
+ void fetchWrongForgeInfo(ep, { signal: AbortSignal.timeout(3e3) }).then((info) => writeWrongForgeInfoCache(info)).catch(() => void 0);
635
+ }
636
+
637
+ // src/fleet/wrongforge-quota.ts
638
+ import {
639
+ DEFAULT_QUOTA_METER,
640
+ recordProviderQuota
641
+ } from "@wrongstack/core/quota";
642
+ var reads = /* @__PURE__ */ new Map();
643
+ var REFRESH_MS = 2e4;
644
+ function object(value) {
645
+ return value !== null && typeof value === "object" && !Array.isArray(value) ? value : {};
646
+ }
647
+ function percent(value) {
648
+ return typeof value === "number" && Number.isFinite(value) && value >= 0 && value <= 100;
649
+ }
650
+ async function reportWrongForgeQuota(opts = {}) {
651
+ const endpoint = opts.endpoint ?? resolveWrongForgeEndpoint();
652
+ if (!endpoint) return false;
653
+ const providerId = opts.providerId ?? "wrongforge";
654
+ const key = `${providerId}\0${endpoint.url}\0${endpoint.apiKey}`;
655
+ const prior = reads.get(key);
656
+ if (prior?.pending) {
657
+ if (opts.force && !prior.forced) {
658
+ await prior.pending;
659
+ return reportWrongForgeQuota(opts);
660
+ }
661
+ return prior.pending;
662
+ }
663
+ if (!opts.force && prior && Date.now() - prior.at < REFRESH_MS) return prior.ok;
664
+ const state = { at: Date.now(), ok: false, forced: opts.force === true };
665
+ reads.set(key, state);
666
+ if (reads.size > 128)
667
+ for (const [id, entry] of reads) {
668
+ if (!entry.pending && id !== key) {
669
+ reads.delete(id);
670
+ break;
671
+ }
672
+ }
673
+ state.pending = (async () => {
674
+ try {
675
+ const signal = AbortSignal.timeout(opts.timeoutMs ?? 1e4);
676
+ const body = object(
677
+ await wrongForgeCall(endpoint, opts.fetchImpl)(
678
+ "GET",
679
+ `/v1/usage${opts.force ? "?force=1" : ""}`,
680
+ void 0,
681
+ signal
682
+ )
683
+ );
684
+ if (signal.aborted) return false;
685
+ const windows = [];
686
+ for (const spec of [
687
+ { key: "five_hour", id: "primary", label: "5h", windowMinutes: 300 },
688
+ { key: "weekly", id: "secondary", label: "weekly", windowMinutes: 10080 }
689
+ ]) {
690
+ const raw = object(body[spec.key]);
691
+ if (!percent(raw.percent)) continue;
692
+ const reset = typeof raw.resetsAt === "string" ? Date.parse(raw.resetsAt) : Number.NaN;
693
+ windows.push({
694
+ id: spec.id,
695
+ label: spec.label,
696
+ windowMinutes: spec.windowMinutes,
697
+ usedPercent: raw.percent,
698
+ ...Number.isFinite(reset) ? { resetsAt: Math.floor(reset / 1e3) } : {}
699
+ });
700
+ }
701
+ if (windows.length === 0) return false;
702
+ const extra = object(body.extra_usage);
703
+ const snapshot = {
704
+ providerId,
705
+ meterId: DEFAULT_QUOTA_METER,
706
+ meterLabel: "WrongForge \xB7 Claude subscription",
707
+ windows,
708
+ capturedAt: Date.now()
709
+ };
710
+ if (extra.enabled === false) snapshot.credits = { hasCredits: false, unlimited: false };
711
+ if (extra.enabled === true) {
712
+ snapshot.note = percent(extra.utilization) ? `Extra usage enabled \xB7 ${extra.utilization}% used` : "Extra usage enabled";
713
+ if (typeof extra.usedCredits === "number" && Number.isFinite(extra.usedCredits) && extra.usedCredits >= 0 && typeof extra.monthlyLimit === "number" && Number.isFinite(extra.monthlyLimit) && extra.monthlyLimit >= 0) {
714
+ const remaining = Math.max(0, extra.monthlyLimit - extra.usedCredits);
715
+ snapshot.credits = {
716
+ hasCredits: remaining > 0,
717
+ unlimited: false,
718
+ balance: `${remaining} credits remaining (${extra.usedCredits}/${extra.monthlyLimit})`
719
+ };
720
+ }
721
+ } else if (extra.enabled === false) snapshot.note = "Extra usage disabled";
722
+ const exhausted = windows.filter(
723
+ (window) => window.usedPercent >= 100 && (window.resetsAt === void 0 || window.resetsAt * 1e3 > snapshot.capturedAt)
724
+ );
725
+ exhausted.sort((a, b) => (b.resetsAt ?? Infinity) - (a.resetsAt ?? Infinity));
726
+ if (exhausted[0]) snapshot.reachedWindowId = exhausted[0].id;
727
+ recordProviderQuota(providerId, [snapshot]);
728
+ state.ok = true;
729
+ return true;
730
+ } catch {
731
+ return false;
732
+ } finally {
733
+ delete state.pending;
734
+ }
735
+ })();
736
+ return state.pending;
737
+ }
738
+
520
739
  export {
521
740
  DEFAULT_BRIDGE_SERVERS,
522
741
  installedBridgeAgents,
523
742
  wrongstackBridgeSetup,
524
743
  createProjectKanbanTransitionHandler,
525
744
  createProjectKanbanAssignHandler,
526
- createHqCommandDispatcher
745
+ createHqCommandDispatcher,
746
+ parseWrongForgeInfo,
747
+ readCachedWrongForgeInfo,
748
+ writeWrongForgeInfoCache,
749
+ refreshWrongForgeInfoCache,
750
+ reportWrongForgeQuota
527
751
  };
528
- //# sourceMappingURL=chunk-JKTJSLUT.js.map
752
+ //# sourceMappingURL=chunk-5SGMUDP5.js.map
@@ -1,19 +1,7 @@
1
1
 
2
- // src/hq-server/audit-actor.ts
3
- import * as os from "node:os";
4
- function resolveAuditActor() {
5
- const user = (process.env.USERNAME ?? process.env.USER ?? "").toString();
6
- try {
7
- const host = os.hostname();
8
- return user ? `${user}@${host}` : `cli@${host}`;
9
- } catch {
10
- return user ? `${user}@unknown` : "cli";
11
- }
12
- }
13
-
14
2
  // src/hq-server/utils.ts
15
3
  import * as fs from "node:fs/promises";
16
- import * as os2 from "node:os";
4
+ import * as os from "node:os";
17
5
  import * as path from "node:path";
18
6
  import { resolveHqDataDir } from "@wrongstack/core/hq";
19
7
  import { isSafeSessionId as coreIsSafeSessionId } from "@wrongstack/core/utils";
@@ -166,7 +154,7 @@ function hqRuntimeMarkerPath(dataDir) {
166
154
  function lanIPv4Addresses() {
167
155
  const out = [];
168
156
  try {
169
- const ifaces = os2.networkInterfaces();
157
+ const ifaces = os.networkInterfaces();
170
158
  for (const name of Object.keys(ifaces)) {
171
159
  for (const ni of ifaces[name] ?? []) {
172
160
  if (ni.family === "IPv4" && !ni.internal) out.push(ni.address);
@@ -212,8 +200,19 @@ function recordTimeseriesSignal(persistence, event) {
212
200
  }
213
201
  }
214
202
 
203
+ // src/hq-server/audit-actor.ts
204
+ import * as os2 from "node:os";
205
+ function resolveAuditActor() {
206
+ const user = (process.env.USERNAME ?? process.env.USER ?? "").toString();
207
+ try {
208
+ const host = os2.hostname();
209
+ return user ? `${user}@${host}` : `cli@${host}`;
210
+ } catch {
211
+ return user ? `${user}@unknown` : "cli";
212
+ }
213
+ }
214
+
215
215
  export {
216
- resolveAuditActor,
217
216
  TRANSCRIPT_RING_MAX,
218
217
  MAX_TRANSCRIPT_SESSIONS,
219
218
  MAX_AGENT_RINGS,
@@ -234,6 +233,7 @@ export {
234
233
  truncateHqSummary,
235
234
  hqMachineKey,
236
235
  recordTimeseriesSignal,
237
- sanitizeApiError
236
+ sanitizeApiError,
237
+ resolveAuditActor
238
238
  };
239
- //# sourceMappingURL=chunk-3EXRPTAU.js.map
239
+ //# sourceMappingURL=chunk-5TQ65PXQ.js.map
@@ -3,40 +3,40 @@
3
3
  var loaders = {
4
4
  automation: async () => (await import("./automation-O7ZRZSFS.js")).automationCmd,
5
5
  sandbox: async () => (await import("./sandbox-EZQ76MNY.js")).sandboxCmd,
6
- acp: async () => (await import("./acp-MZ5MQBFN.js")).acpCmd,
6
+ acp: async () => (await import("./acp-NKUEYJDZ.js")).acpCmd,
7
7
  init: async () => (await import("./init-5PLABNLR.js")).initCmd,
8
- auth: async () => (await import("./auth-IHQS6AFW.js")).authCmd,
8
+ auth: async () => (await import("./auth-2ZG5DBHS.js")).authCmd,
9
9
  update: async () => (await import("./update-54W7GUS5.js")).updateCmd,
10
10
  remote: async () => (await import("./remote-AKKRJEHK.js")).remoteCmd,
11
- sessions: async () => (await import("./sessions-config-SJVQXCIE.js")).sessionsCmd,
12
- config: async () => (await import("./sessions-config-SJVQXCIE.js")).configCmd,
13
- "config-export": async () => (await import("./config-transfer-Y7XJMJRN.js")).configExportCmd,
14
- "config-import": async () => (await import("./config-transfer-Y7XJMJRN.js")).configImportCmd,
11
+ sessions: async () => (await import("./sessions-config-7MK742OW.js")).sessionsCmd,
12
+ config: async () => (await import("./sessions-config-7MK742OW.js")).configCmd,
13
+ "config-export": async () => (await import("./config-transfer-B4GOZTFC.js")).configExportCmd,
14
+ "config-import": async () => (await import("./config-transfer-B4GOZTFC.js")).configImportCmd,
15
15
  rewind: async () => (await import("./rewind-GAUXWSTU.js")).rewindCmd,
16
16
  replay: async () => (await import("./replay-URJFMQCU.js")).replayCmd,
17
17
  audit: async () => (await import("./audit-NH7NUKBV.js")).auditCmd,
18
- tools: async () => (await import("./tools-skills-55QVTMSK.js")).toolsCmd,
19
- skills: async () => (await import("./tools-skills-55QVTMSK.js")).skillsCmd,
18
+ tools: async () => (await import("./tools-skills-WDTMCE46.js")).toolsCmd,
19
+ skills: async () => (await import("./tools-skills-WDTMCE46.js")).skillsCmd,
20
20
  "skill-suggest": async () => (await import("./skill-suggest-LZV2TIPQ.js")).skillSuggestCmd,
21
- typesafe: async () => (await import("./typesafe-YBEADNAH.js")).typesafeCmd,
21
+ typesafe: async () => (await import("./typesafe-QLSMFU7J.js")).typesafeCmd,
22
22
  providers: async () => (await import("./providers-models-CDI5GVBX.js")).providersCmd,
23
23
  models: async () => (await import("./providers-models-CDI5GVBX.js")).modelsCmd,
24
- mcp: async () => (await import("./mcp-W7A5HUXV.js")).mcpCmd,
25
- plugin: async () => (await import("./plugin-usage-TYF5HY4K.js")).pluginCmd,
26
- plugins: async () => (await import("./plugin-usage-TYF5HY4K.js")).pluginCmd,
24
+ mcp: async () => (await import("./mcp-22CFBX4H.js")).mcpCmd,
25
+ plugin: async () => (await import("./plugin-usage-UWKYMNQU.js")).pluginCmd,
26
+ plugins: async () => (await import("./plugin-usage-UWKYMNQU.js")).pluginCmd,
27
27
  diag: async () => (await import("./diag-doctor-5SVYK2DR.js")).diagCmd,
28
28
  doctor: async () => (await import("./diag-doctor-5SVYK2DR.js")).doctorCmd,
29
29
  "proxy-status": async () => (await import("./diag-doctor-5SVYK2DR.js")).proxyCmd,
30
30
  export: async () => (await import("./export-W27PTU6Y.js")).exportCmd,
31
- usage: async () => (await import("./plugin-usage-TYF5HY4K.js")).usageCmd,
32
- version: async () => (await import("./version-help-RBZC5GZZ.js")).versionCmd,
33
- help: async () => (await import("./version-help-RBZC5GZZ.js")).helpCmd,
31
+ usage: async () => (await import("./plugin-usage-UWKYMNQU.js")).usageCmd,
32
+ version: async () => (await import("./version-help-X6CC4CFY.js")).versionCmd,
33
+ help: async () => (await import("./version-help-X6CC4CFY.js")).helpCmd,
34
34
  projects: async () => (await import("./projects-FWRJHW3S.js")).projectsCmd,
35
- modeldiag: async () => (await import("./modeldiag-HDIKG37X.js")).modeldiagCmd,
35
+ modeldiag: async () => (await import("./modeldiag-5PBB777J.js")).modeldiagCmd,
36
36
  quick: async () => (await import("./quick-NPC3N3ZX.js")).quickCmd,
37
37
  bench: async () => (await import("./bench-NDYES33Y.js")).benchCmd,
38
38
  chronicle: async () => (await import("./chronicle-WBK3TJRB.js")).chronicleCmd,
39
- hq: async () => (await import("./hq-JD5AZVMG.js")).hqCmd,
39
+ hq: async () => (await import("./hq-54PQYR5O.js")).hqCmd,
40
40
  mailbox: async () => (await import("./mailbox-serve-MMQCHOHI.js")).mailboxServeCmd,
41
41
  permissions: async () => (await import("./permissions-6YJ64W65.js")).permissionsCmd,
42
42
  project: async () => (await import("./project-V5KNTLV4.js")).projectCmd,
@@ -58,4 +58,4 @@ export {
58
58
  subcommands,
59
59
  subcommandNames
60
60
  };
61
- //# sourceMappingURL=chunk-2LTHDKZX.js.map
61
+ //# sourceMappingURL=chunk-7BM4LGKQ.js.map