@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
@@ -0,0 +1,329 @@
1
+ import {
2
+ STANDALONE_TARGET
3
+ } from "./chunk-F5DCFAKI.js";
4
+
5
+ // src/standalone-update.ts
6
+ import { createHash as createHash2, randomBytes } from "node:crypto";
7
+ import * as fs from "node:fs";
8
+ import * as path from "node:path";
9
+ import { FetchError } from "@wrongstack/core/types";
10
+
11
+ // src/release-asset-download.ts
12
+ import { createHash } from "node:crypto";
13
+ import * as fsp from "node:fs/promises";
14
+ async function downloadReleaseAsset(url, timeoutMs, maxBytes) {
15
+ const res = await fetch(url, {
16
+ signal: AbortSignal.timeout(timeoutMs),
17
+ headers: { "User-Agent": "wrongstack-cli" },
18
+ redirect: "follow"
19
+ });
20
+ if (!res.ok) throw new Error(`download ${url} responded ${res.status}`);
21
+ const declared = Number(res.headers.get("content-length") ?? "0");
22
+ if (declared > maxBytes) throw new Error(`download ${url} is too large`);
23
+ if (!res.body) return Buffer.alloc(0);
24
+ const chunks = [];
25
+ let received = 0;
26
+ const reader = res.body.getReader();
27
+ try {
28
+ while (true) {
29
+ const { done, value } = await reader.read();
30
+ if (done) break;
31
+ received += value.byteLength;
32
+ if (received > maxBytes) {
33
+ await reader.cancel();
34
+ throw new Error(`download ${url} is too large`);
35
+ }
36
+ chunks.push(Buffer.from(value.buffer, value.byteOffset, value.byteLength));
37
+ }
38
+ } finally {
39
+ reader.releaseLock();
40
+ }
41
+ return Buffer.concat(chunks, received);
42
+ }
43
+ async function downloadReleaseAssetToFile(url, file, options) {
44
+ const timeout = AbortSignal.timeout(options.timeoutMs);
45
+ const res = await fetch(url, {
46
+ signal: options.signal ? AbortSignal.any([options.signal, timeout]) : timeout,
47
+ headers: { "User-Agent": "wrongstack-cli" },
48
+ redirect: "follow"
49
+ });
50
+ if (!res.ok) throw new Error(`download ${url} responded ${res.status}`);
51
+ const declared = Number(res.headers.get("content-length") ?? "0");
52
+ if (declared > options.maxBytes) throw new Error(`download ${url} is too large`);
53
+ const hash = createHash("sha256");
54
+ const out = await fsp.open(file, "wx", 384);
55
+ let received = 0;
56
+ try {
57
+ if (res.body) {
58
+ const reader = res.body.getReader();
59
+ try {
60
+ while (true) {
61
+ const { done, value } = await reader.read();
62
+ if (done) break;
63
+ received += value.byteLength;
64
+ if (received > options.maxBytes) {
65
+ await reader.cancel();
66
+ throw new Error(`download ${url} is too large`);
67
+ }
68
+ hash.update(value);
69
+ await out.write(value);
70
+ }
71
+ } finally {
72
+ reader.releaseLock();
73
+ }
74
+ }
75
+ await out.sync();
76
+ } catch (err) {
77
+ await out.close().catch(() => void 0);
78
+ await fsp.rm(file, { force: true });
79
+ throw err;
80
+ }
81
+ await out.close();
82
+ return hash.digest("hex");
83
+ }
84
+
85
+ // src/release-attestation.ts
86
+ var RELEASES_REPO = "WrongStack/WrongStack";
87
+ var RELEASES_REPO_ID = 1237163046;
88
+ var REPO_URL = `https://github.com/${RELEASES_REPO}`;
89
+ var IN_TOTO_PAYLOAD = "application/vnd.in-toto+json";
90
+ var IN_TOTO_STATEMENT = "https://in-toto.io/Statement/v1";
91
+ var SLSA_PROVENANCE = "https://slsa.dev/provenance/v1";
92
+ var obj = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
93
+ function statementOf(attestation) {
94
+ const envelope = obj(obj(attestation["bundle"])?.["dsseEnvelope"]);
95
+ if (envelope?.["payloadType"] !== IN_TOTO_PAYLOAD) return void 0;
96
+ const payload = envelope["payload"];
97
+ if (typeof payload !== "string") return void 0;
98
+ try {
99
+ return obj(JSON.parse(Buffer.from(payload, "base64").toString("utf8")));
100
+ } catch {
101
+ return void 0;
102
+ }
103
+ }
104
+ function vouches(attestation, subject) {
105
+ if (attestation["repository_id"] !== RELEASES_REPO_ID) return false;
106
+ const statement = statementOf(attestation);
107
+ if (statement?.["_type"] !== IN_TOTO_STATEMENT) return false;
108
+ if (statement["predicateType"] !== SLSA_PROVENANCE) return false;
109
+ const subjects = Array.isArray(statement["subject"]) ? statement["subject"] : [];
110
+ const named = subjects.some((entry) => {
111
+ const s = obj(entry);
112
+ return s?.["name"] === subject.assetName && obj(s["digest"])?.["sha256"] === subject.sha256;
113
+ });
114
+ if (!named) return false;
115
+ const tag = `refs/tags/v${subject.version}`;
116
+ const predicate = obj(statement["predicate"]);
117
+ const build = obj(predicate?.["buildDefinition"]);
118
+ const workflow = obj(obj(build?.["externalParameters"])?.["workflow"]);
119
+ const github = obj(obj(build?.["internalParameters"])?.["github"]);
120
+ const builder = obj(obj(predicate?.["runDetails"])?.["builder"]);
121
+ return workflow?.["repository"] === REPO_URL && workflow["path"] === ".github/workflows/release.yml" && workflow["ref"] === tag && builder?.["id"] === `${REPO_URL}/.github/workflows/binaries.yml@${tag}` && github?.["event_name"] === "push" && github["runner_environment"] === "github-hosted";
122
+ }
123
+ function attestationsVouchFor(response, subject) {
124
+ const list = obj(response)?.["attestations"];
125
+ if (!Array.isArray(list)) return false;
126
+ return list.some((entry) => {
127
+ const attestation = obj(entry);
128
+ return attestation !== void 0 && vouches(attestation, subject);
129
+ });
130
+ }
131
+ async function verifyReleaseAttestation(subject, signal) {
132
+ const url = `https://api.github.com/repos/${RELEASES_REPO}/attestations/sha256:${subject.sha256}`;
133
+ const timeout = AbortSignal.timeout(3e4);
134
+ const res = await fetch(url, {
135
+ signal: signal ? AbortSignal.any([signal, timeout]) : timeout,
136
+ headers: { Accept: "application/vnd.github+json", "User-Agent": "wrongstack-cli" }
137
+ });
138
+ if (res.status === 404) {
139
+ throw new Error(`no build attestation exists for ${subject.assetName}`);
140
+ }
141
+ if (!res.ok) {
142
+ const limited = res.status === 403 || res.status === 429;
143
+ throw new Error(
144
+ limited ? "GitHub API rate limit reached while checking the build attestation; try again later" : `GitHub attestations API responded ${res.status}`
145
+ );
146
+ }
147
+ if (!attestationsVouchFor(await res.json(), subject)) {
148
+ throw new Error(
149
+ `${subject.assetName} has no attestation from the v${subject.version} release workflow`
150
+ );
151
+ }
152
+ }
153
+
154
+ // src/standalone-update.ts
155
+ var API_LATEST = `https://api.github.com/repos/${RELEASES_REPO}/releases/latest`;
156
+ var MAX_BINARY_BYTES = 512 * 1024 * 1024;
157
+ var MAX_CHECKSUM_BYTES = 1024 * 1024;
158
+ function standaloneAssetName(target) {
159
+ const name = `wstack-${target.replace(/^bun-/, "")}`;
160
+ return target.startsWith("bun-windows") ? `${name}.exe` : name;
161
+ }
162
+ async function fetchLatestRelease(timeoutMs, signal) {
163
+ const timeoutSignal = AbortSignal.timeout(timeoutMs);
164
+ const res = await fetch(API_LATEST, {
165
+ signal: signal ? AbortSignal.any([signal, timeoutSignal]) : timeoutSignal,
166
+ headers: { Accept: "application/vnd.github+json", "User-Agent": "wrongstack-cli" }
167
+ });
168
+ if (!res.ok) {
169
+ throw new FetchError({
170
+ message: `GitHub releases responded ${res.status}`,
171
+ status: res.status,
172
+ context: { op: "checkForUpdate", registry: "github-releases", url: API_LATEST }
173
+ });
174
+ }
175
+ const data = await res.json();
176
+ if (typeof data.tag_name !== "string") throw new Error("Latest release has no tag");
177
+ const assets = Array.isArray(data.assets) ? data.assets.filter(
178
+ (a) => typeof a?.name === "string" && typeof a?.browser_download_url === "string" && (a.digest === void 0 || a.digest === null || typeof a.digest === "string")
179
+ ) : [];
180
+ return { version: data.tag_name.replace(/^v/, ""), assets };
181
+ }
182
+ async function findStandaloneRelease(target, signal) {
183
+ const release = await fetchLatestRelease(15e3, signal);
184
+ const assetName = standaloneAssetName(target);
185
+ const asset = release.assets.find((a) => a.name === assetName);
186
+ const sums = release.assets.find((a) => a.name === "SHA256SUMS");
187
+ if (!asset || !sums) throw new Error(`release v${release.version} has no ${assetName} build`);
188
+ return { version: release.version, assetName, asset, sums };
189
+ }
190
+ async function verifyStandaloneDigest(release, sha256, signal) {
191
+ const sumsText = (await downloadReleaseAsset(release.sums.browser_download_url, 3e4, MAX_CHECKSUM_BYTES)).toString("utf8");
192
+ if (parseSha256Sums(sumsText).get(release.assetName) !== sha256) {
193
+ throw new Error("checksum does not match the release SHA256SUMS");
194
+ }
195
+ const digest = release.asset.digest;
196
+ if (typeof digest === "string" && digest !== `sha256:${sha256}`) {
197
+ throw new Error("checksum does not match the digest GitHub recorded for the asset");
198
+ }
199
+ await verifyReleaseAttestation(
200
+ { assetName: release.assetName, sha256, version: release.version },
201
+ signal
202
+ );
203
+ }
204
+ async function fetchLatestStandaloneVersion(timeoutMs = 3e3, signal) {
205
+ return (await fetchLatestRelease(timeoutMs, signal)).version;
206
+ }
207
+ function parseSha256Sums(text) {
208
+ const sums = /* @__PURE__ */ new Map();
209
+ for (const line of text.split(/\r?\n/)) {
210
+ const match = line.trim().match(/^([0-9a-f]{64})\s+\*?(.+)$/i);
211
+ if (match?.[1] && match[2]) {
212
+ const name = match[2].trim();
213
+ if (sums.has(name)) throw new Error(`Duplicate SHA256SUMS entry: ${name}`);
214
+ sums.set(name, match[1].toLowerCase());
215
+ }
216
+ }
217
+ return sums;
218
+ }
219
+ function replaceExecutable(target, bytes, platform = process.platform) {
220
+ const staged = stagingPath(target);
221
+ fs.writeFileSync(staged, bytes, { mode: 493, flag: "wx" });
222
+ swapIntoPlace(target, staged, platform);
223
+ }
224
+ function installExecutableFrom(target, source, sha256, platform = process.platform) {
225
+ const staged = stagingPath(target);
226
+ fs.copyFileSync(source, staged, fs.constants.COPYFILE_EXCL);
227
+ try {
228
+ if (sha256File(staged) !== sha256) throw new Error("staged update does not match its digest");
229
+ fs.chmodSync(staged, 493);
230
+ } catch (error) {
231
+ fs.rmSync(staged, { force: true });
232
+ throw error;
233
+ }
234
+ swapIntoPlace(target, staged, platform);
235
+ }
236
+ function stagingPath(target) {
237
+ return `${target}.new-${randomBytes(9).toString("hex")}`;
238
+ }
239
+ function sha256File(file) {
240
+ const hash = createHash2("sha256");
241
+ const fd = fs.openSync(file, "r");
242
+ try {
243
+ const chunk = Buffer.allocUnsafe(1024 * 1024);
244
+ let read = fs.readSync(fd, chunk);
245
+ while (read > 0) {
246
+ hash.update(chunk.subarray(0, read));
247
+ read = fs.readSync(fd, chunk);
248
+ }
249
+ } finally {
250
+ fs.closeSync(fd);
251
+ }
252
+ return hash.digest("hex");
253
+ }
254
+ function swapIntoPlace(target, staged, platform) {
255
+ try {
256
+ if (platform === "win32") {
257
+ const aside = `${target}.old`;
258
+ fs.rmSync(aside, { force: true });
259
+ fs.renameSync(target, aside);
260
+ try {
261
+ fs.renameSync(staged, target);
262
+ } catch (error) {
263
+ fs.renameSync(aside, target);
264
+ throw error;
265
+ }
266
+ } else {
267
+ fs.renameSync(staged, target);
268
+ }
269
+ } finally {
270
+ fs.rmSync(staged, { force: true });
271
+ }
272
+ }
273
+ async function updateStandaloneBinary(options) {
274
+ const { renderer } = options;
275
+ if (!STANDALONE_TARGET) {
276
+ renderer.write("Update failed: this executable does not record its build target.\n");
277
+ return 1;
278
+ }
279
+ try {
280
+ const release = await findStandaloneRelease(STANDALONE_TARGET);
281
+ renderer.write(`Updating wrongstack from v${options.current} to v${release.version}...
282
+ `);
283
+ const executable = fs.realpathSync(process.execPath);
284
+ const staged = options.staged;
285
+ if (staged && staged.version === release.version) {
286
+ renderer.write(`Installing the v${staged.version} build already downloaded
287
+ `);
288
+ installExecutableFrom(executable, staged.file, staged.sha256);
289
+ } else {
290
+ renderer.write(`Downloading ${release.assetName}
291
+ `);
292
+ const bytes = await downloadReleaseAsset(
293
+ release.asset.browser_download_url,
294
+ 6e5,
295
+ MAX_BINARY_BYTES
296
+ );
297
+ renderer.write("Verifying the checksum and the build attestation\n");
298
+ await verifyStandaloneDigest(release, createHash2("sha256").update(bytes).digest("hex"));
299
+ replaceExecutable(executable, bytes);
300
+ }
301
+ renderer.write(
302
+ `
303
+ Updated ${path.basename(executable)} to v${release.version}. Restart wrongstack to use it.
304
+ `
305
+ );
306
+ return 0;
307
+ } catch (err) {
308
+ const msg = err instanceof Error ? err.message : String(err);
309
+ const permission = /EACCES|EPERM/.test(msg) ? "\nThe executable is not writable by this user; rerun with the permissions it was installed with." : "";
310
+ renderer.write(`
311
+ Update failed: ${msg}${permission}
312
+ `);
313
+ return 1;
314
+ }
315
+ }
316
+
317
+ export {
318
+ downloadReleaseAssetToFile,
319
+ MAX_BINARY_BYTES,
320
+ standaloneAssetName,
321
+ findStandaloneRelease,
322
+ verifyStandaloneDigest,
323
+ fetchLatestStandaloneVersion,
324
+ parseSha256Sums,
325
+ replaceExecutable,
326
+ installExecutableFrom,
327
+ updateStandaloneBinary
328
+ };
329
+ //# sourceMappingURL=chunk-X756ZS72.js.map
@@ -4,12 +4,15 @@ import {
4
4
  import {
5
5
  PLUGIN_AUDIT_ENTRIES,
6
6
  loadExternalPlugins
7
- } from "./chunk-SIS37L3W.js";
7
+ } from "./chunk-L2RVEQWO.js";
8
8
 
9
9
  // src/wiring/plugins.ts
10
10
  import { join } from "node:path";
11
11
  import { loadPlugins, resolvePluginConfig, resolvePluginEnablement } from "@wrongstack/core/plugin";
12
- import { OFFICIAL_PLUGIN_FACTORIES } from "@wrongstack/plugins/factories";
12
+ import {
13
+ OFFICIAL_PLUGIN_FACTORIES,
14
+ OFFICIAL_PLUGIN_SPECIFIERS
15
+ } from "@wrongstack/plugins/factories";
13
16
 
14
17
  // src/plugin-api-factory.ts
15
18
  import { DefaultPluginAPI } from "@wrongstack/core/plugin";
@@ -20,7 +23,21 @@ function createApi(ownerName, base) {
20
23
  // src/wiring/plugins.ts
21
24
  var DEPRECATED_PLUGIN_NAMES = {
22
25
  "web-search": "use the built-in `search` and `fetch` tools",
23
- "json-path": "use the built-in `json` tool with action: query | validate | transform | merge"
26
+ "json-path": "use the built-in `json` tool with action: query | validate | transform | merge",
27
+ // Deleted in the 2026-09-17 catalog review. The first four produced
28
+ // findings that were noise by construction (each was run against this
29
+ // repo and mis-reported); the rest duplicated infrastructure the host
30
+ // already ships. Kept here so an existing config that still lists one
31
+ // warns and skips instead of failing to resolve the import.
32
+ "interface-contract-guard": "removed \u2014 it reported plain data interfaces as unimplemented",
33
+ "refactor-suggester": "removed \u2014 use `lint-gate` plus the built-in `grep` and `read` tools",
34
+ "feature-flag-tracker": "removed \u2014 use the built-in `grep` tool with your own flag pattern",
35
+ "dead-code-detector": "removed \u2014 use your linter / `tsc` and `duplicate-code-detector`",
36
+ "semantic-search-indexer": "use the built-in `grep` tool or the codebase-index MCP server",
37
+ "knowledge-graph": "use the built-in `remember` / `search_memory` / `find_related_memories`",
38
+ "todo-tracker": "use the built-in `todo` tool and the Kanban board",
39
+ "smart-rename": "use the built-in `replace` tool",
40
+ "code-metrics": "removed \u2014 it reported numbers nothing acted on"
24
41
  };
25
42
  var deprecatedWarningsEmitted = /* @__PURE__ */ new Set();
26
43
  var BUILTIN_PLUGIN_CONFIG_ALIASES = {
@@ -95,6 +112,28 @@ var BUILTIN_PLUGIN_FACTORIES = [
95
112
  // ── Telegram plugin ─────────────────────────────────────────────────
96
113
  async () => (await import("@wrongstack/telegram")).default
97
114
  ];
115
+ var BUILTIN_PLUGIN_NAME_HINTS = [
116
+ "wstack-prompts",
117
+ "wstack-sync",
118
+ "wstack-cloud-config-sync",
119
+ "wstack-chimera",
120
+ "wstack-auto-review",
121
+ "wstack-specialist-triggers",
122
+ "wstack-skills",
123
+ ...OFFICIAL_PLUGIN_SPECIFIERS.map((specifier) => specifier.slice("@wrongstack/plugins/".length)),
124
+ "@wrongstack/plug-lsp",
125
+ "telegram"
126
+ ];
127
+ function builtinEnablement(name, config, aliases) {
128
+ const auditEntry = PLUGIN_AUDIT_ENTRIES.find((entry) => entry.name === name);
129
+ return resolvePluginEnablement({
130
+ name,
131
+ aliases,
132
+ defaultState: auditEntry?.defaultState ?? "active",
133
+ config,
134
+ matches: (spec) => (builtinPluginNameFromSpec(spec) ?? spec) === name
135
+ });
136
+ }
98
137
  async function setupPlugins(params) {
99
138
  const {
100
139
  config,
@@ -119,24 +158,30 @@ async function setupPlugins(params) {
119
158
  vault,
120
159
  pipelines,
121
160
  paths,
122
- hookRegistry
161
+ hookRegistry,
162
+ safeMode
123
163
  } = params;
124
164
  const builtinPlugins = [];
125
165
  if (paths && config.features?.plugins !== false) {
126
- for (const factory of BUILTIN_PLUGIN_FACTORIES) {
166
+ for (const [index, factory] of BUILTIN_PLUGIN_FACTORIES.entries()) {
167
+ const nameHint = BUILTIN_PLUGIN_NAME_HINTS[index];
168
+ if (nameHint && BUILTIN_PLUGIN_NAME_HINTS.length === BUILTIN_PLUGIN_FACTORIES.length) {
169
+ const { enabled, source } = builtinEnablement(
170
+ nameHint,
171
+ config,
172
+ nameHint === "telegram" ? ["@wrongstack/telegram"] : void 0
173
+ );
174
+ if (!enabled) {
175
+ if (source !== "default") {
176
+ log.info(`[setupPlugins] built-in plugin "${nameHint}" disabled by ${source}`);
177
+ }
178
+ continue;
179
+ }
180
+ }
127
181
  try {
128
182
  const plugin = await factory();
129
183
  if (!plugin) continue;
130
- const auditEntry = PLUGIN_AUDIT_ENTRIES.find((entry) => entry.name === plugin.name);
131
- const { enabled, source } = resolvePluginEnablement({
132
- name: plugin.name,
133
- aliases: plugin.configAliases,
134
- // Built-ins outside the audit catalog (prompts, sync, skills, …)
135
- // are infrastructure — they run unless explicitly turned off.
136
- defaultState: auditEntry?.defaultState ?? "active",
137
- config,
138
- matches: (spec) => (builtinPluginNameFromSpec(spec) ?? spec) === plugin.name
139
- });
184
+ const { enabled, source } = builtinEnablement(plugin.name, config, plugin.configAliases);
140
185
  if (!enabled) {
141
186
  if (source !== "default") {
142
187
  log.info(`[setupPlugins] built-in plugin "${plugin.name}" disabled by ${source}`);
@@ -150,7 +195,7 @@ async function setupPlugins(params) {
150
195
  }
151
196
  }
152
197
  }
153
- const userPlugins = config.features?.plugins === false ? [] : await loadExternalPlugins(
198
+ const userPlugins = config.features?.plugins === false || safeMode === true ? [] : await loadExternalPlugins(
154
199
  {
155
200
  config,
156
201
  log,
@@ -171,13 +216,6 @@ async function setupPlugins(params) {
171
216
  if (allPlugins.length === 0) return;
172
217
  const pluginOptions = buildPluginOptions(config, allPlugins);
173
218
  if (paths?.projectDir) {
174
- if (pluginOptions["todo-tracker"] === void 0) {
175
- pluginOptions["todo-tracker"] = {};
176
- }
177
- const todoTrackerOpts = pluginOptions["todo-tracker"];
178
- if (typeof todoTrackerOpts["filePath"] !== "string" || todoTrackerOpts["filePath"] === "") {
179
- todoTrackerOpts["filePath"] = join(paths.projectDir, "todo-tracker.json");
180
- }
181
219
  const contextPinsOpts = pluginOptions["context-pins"] ?? {};
182
220
  pluginOptions["context-pins"] = contextPinsOpts;
183
221
  if (typeof contextPinsOpts["filePath"] !== "string" || contextPinsOpts["filePath"] === "") {
@@ -265,6 +303,7 @@ export {
265
303
  pluginNameFromSpec,
266
304
  builtinPluginNameFromSpec,
267
305
  BUILTIN_PLUGIN_FACTORIES,
306
+ BUILTIN_PLUGIN_NAME_HINTS,
268
307
  setupPlugins
269
308
  };
270
- //# sourceMappingURL=chunk-XJ7K67PP.js.map
309
+ //# sourceMappingURL=chunk-YHYINL47.js.map
@@ -2,6 +2,10 @@
2
2
  // src/subcommands/handlers/auth-local-help.ts
3
3
  import { color } from "@wrongstack/core/utils";
4
4
  var LOCAL_AUTH_FLAGS = [
5
+ {
6
+ flag: "--alias <account>",
7
+ description: "Create a separate auth profile for this preset; the alias selects the endpoint, credential, and models in fallback references."
8
+ },
5
9
  {
6
10
  flag: "--name <ollama|vllm|lmstudio>",
7
11
  description: "Pick a preset (skip the interactive picker). Defaults to the first run; set this for scripting."
@@ -32,7 +36,7 @@ var LOCAL_AUTH_FLAGS = [
32
36
  }
33
37
  ];
34
38
  var LOCAL_FLAG_COLUMN_WIDTH = 38;
35
- var LOCAL_AUTH_HELP_USAGE = "wstack auth local [--name <id>] [--base-url <url>] [--no-key] [--no-probe|--probe-only] [--model <spec>] [--audit [target]]";
39
+ var LOCAL_AUTH_HELP_USAGE = "wstack auth local [--name <id>] [--alias <account>] [--base-url <url>] [--no-key] [--no-probe|--probe-only] [--model <spec>] [--audit [target]]";
36
40
  function wantsLocalHelp(args) {
37
41
  return args.includes("--help") || args.includes("-h");
38
42
  }
@@ -68,4 +72,4 @@ export {
68
72
  wantsLocalHelp,
69
73
  renderAuthLocalHelpToString
70
74
  };
71
- //# sourceMappingURL=chunk-2VMJ3E5Z.js.map
75
+ //# sourceMappingURL=chunk-YTEOAWOJ.js.map
@@ -60,7 +60,7 @@ function parseWebuiSessionChildOptions(flags) {
60
60
  const projectRoot = requireAbsolutePath(flagValue(flags, ["project-root"]), "--project-root");
61
61
  const workingDir = requireAbsolutePath(flagValue(flags, ["working-dir"]), "--working-dir");
62
62
  const relativeWorkingDir = path.relative(projectRoot, workingDir);
63
- if (relativeWorkingDir.startsWith("..") || path.isAbsolute(relativeWorkingDir)) {
63
+ if (relativeWorkingDir === ".." || relativeWorkingDir.startsWith(`..${path.sep}`) || path.isAbsolute(relativeWorkingDir)) {
64
64
  throw new Error("--working-dir must be inside --project-root");
65
65
  }
66
66
  const sessionId = flagValue(flags, ["session-id"]);
@@ -125,4 +125,4 @@ export {
125
125
  writeWebuiSessionChildReady,
126
126
  writeWebuiSessionChildError
127
127
  };
128
- //# sourceMappingURL=chunk-GPPRNAKW.js.map
128
+ //# sourceMappingURL=chunk-ZMX5HRLI.js.map