@wrongstack/cli 1.0.24 → 1.0.27

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 (146) hide show
  1. package/data/providers.json +44 -0
  2. package/dist/{acp-AJWSKWE5.js → acp-M4565YUW.js} +33 -20
  3. package/dist/ascii-mode-SG4PRNLP.js +7 -0
  4. package/dist/{auth-GRBZ7Y3D.js → auth-TE55JF4Z.js} +14 -14
  5. package/dist/{bench-N5K7Z5O3.js → bench-GTLPM22B.js} +2 -2
  6. package/dist/boot/append-system-prompt.d.ts +10 -0
  7. package/dist/boot/ascii-mode.d.ts +12 -0
  8. package/dist/boot/container-wiring.d.ts +4 -2
  9. package/dist/boot/dispatch-singleshot.d.ts +12 -1
  10. package/dist/boot/dispatch-webui.d.ts +2 -0
  11. package/dist/boot/goal-tui-default.d.ts +10 -0
  12. package/dist/boot/mcp-config-flag.d.ts +22 -0
  13. package/dist/boot/piped-stdin.d.ts +40 -0
  14. package/dist/boot/restricted-mode.d.ts +15 -0
  15. package/dist/boot/safe-mode.d.ts +30 -0
  16. package/dist/boot/single-shot-budget.d.ts +30 -0
  17. package/dist/boot/stream-json.d.ts +36 -0
  18. package/dist/boot/structured-output.d.ts +16 -0
  19. package/dist/boot/system-prompt-builder.d.ts +2 -0
  20. package/dist/boot/tool-restriction-flags.d.ts +36 -0
  21. package/dist/boot/worktree-sessions.d.ts +21 -0
  22. package/dist/boot-provider-selection.d.ts +67 -0
  23. package/dist/boot.d.ts +1 -38
  24. package/dist/{chunk-LFMVHT3R.js → chunk-2ERX3RPN.js} +11 -13
  25. package/dist/chunk-4TVYGG6G.js +62 -0
  26. package/dist/chunk-5JYDKG5B.js +154 -0
  27. package/dist/{chunk-3VXYY5JC.js → chunk-5UZBUV2H.js} +3 -19
  28. package/dist/chunk-CZTXF6HY.js +140 -0
  29. package/dist/{chunk-DRM7PSW7.js → chunk-ENRYW73H.js} +527 -381
  30. package/dist/{chunk-SKPDE62W.js → chunk-EPR42SWM.js} +36 -6
  31. package/dist/{chunk-YBUCXXYZ.js → chunk-F5DCFAKI.js} +1 -1
  32. package/dist/chunk-HDMFKTT3.js +157 -0
  33. package/dist/{chunk-PGKJ2OQP.js → chunk-HFZH2XJN.js} +5 -5
  34. package/dist/chunk-HLSHFXTO.js +97 -0
  35. package/dist/{chunk-QFPQXKCG.js → chunk-KOEO4CJG.js} +21 -6
  36. package/dist/chunk-LBPLTTZ6.js +105 -0
  37. package/dist/{chunk-3OCUS3VN.js → chunk-LDCGZJTC.js} +4 -4
  38. package/dist/chunk-LKPEBZBE.js +143 -0
  39. package/dist/chunk-N57IU5FG.js +58 -0
  40. package/dist/{chunk-2EBVTYJR.js → chunk-NRXWOMK7.js} +17 -3
  41. package/dist/chunk-PZQBGUVZ.js +18 -0
  42. package/dist/{chunk-MHEBWVXL.js → chunk-Q4INH2DG.js} +46 -2
  43. package/dist/{chunk-5SEYGOCH.js → chunk-RDGGWMTI.js} +2 -2
  44. package/dist/{chunk-BLD5DSVA.js → chunk-RGFWGUAB.js} +27 -15
  45. package/dist/{chunk-ZZRSG7VK.js → chunk-RZ4ZDRYA.js} +3 -3
  46. package/dist/{chunk-S4FFHDJG.js → chunk-SDJCLEK6.js} +6 -2
  47. package/dist/{chunk-U46QR4WR.js → chunk-TI7KLHYX.js} +132 -3
  48. package/dist/chunk-X756ZS72.js +329 -0
  49. package/dist/{chunk-JF2MULWF.js → chunk-YHYINL47.js} +47 -15
  50. package/dist/{cli-context-34Q5IJRA.js → cli-context-C7RBSWHF.js} +434 -327
  51. package/dist/{cli-main-AELJDBGU.js → cli-main-TQTH73ZK.js} +2948 -2315
  52. package/dist/cli-update-notice.d.ts +2 -1
  53. package/dist/config-doctor.d.ts +1 -1
  54. package/dist/{diag-doctor-WIFJH3XH.js → diag-doctor-BIZAFIAT.js} +2 -2
  55. package/dist/{execution-PYC5FCS4.js → execution-3STBD2U7.js} +2167 -1831
  56. package/dist/execution-chimera-review.d.ts +18 -1
  57. package/dist/fleet/host-types.d.ts +3 -1
  58. package/dist/goal-commands.d.ts +47 -0
  59. package/dist/goal-host.d.ts +1 -14
  60. package/dist/{hq-JTUTFI4L.js → hq-44F4OQH2.js} +9 -8
  61. package/dist/hq-fleet-control.d.ts +36 -0
  62. package/dist/hq-live-status.d.ts +22 -0
  63. package/dist/hq-publisher.d.ts +18 -0
  64. package/dist/hq-server/routes/command-handlers.d.ts +12 -1
  65. package/dist/hq-server/routes/data-handlers.d.ts +1 -1
  66. package/dist/hq-server/socket-credentials.d.ts +63 -0
  67. package/dist/hq-server/upgrade-handler.d.ts +2 -0
  68. package/dist/hq-server/ws.d.ts +24 -0
  69. package/dist/{hq-server-PC7GZMPT.js → hq-server-UIB24LU6.js} +2 -2
  70. package/dist/{hq-service-NW56MUP2.js → hq-service-BMMJAHRT.js} +4 -4
  71. package/dist/import-claude-code-AYG24RG2.js +268 -0
  72. package/dist/index.js +12 -8
  73. package/dist/live-settings-input.d.ts +1 -0
  74. package/dist/{mailbox-serve-WDOCH6KR.js → mailbox-serve-GNGXEQ2R.js} +3 -3
  75. package/dist/{modeldiag-36OGAL5C.js → modeldiag-W7XAE625.js} +9 -9
  76. package/dist/{per-subcommand-help-XE77MTGJ.js → per-subcommand-help-QDAQASPZ.js} +2 -2
  77. package/dist/permission-prompt.d.ts +14 -0
  78. package/dist/permission-rules-view.d.ts +18 -0
  79. package/dist/{permissions-CFDLXETM.js → permissions-PL27UHYD.js} +67 -45
  80. package/dist/{plugin-usage-S5LVGMBW.js → plugin-usage-CIGOOTX3.js} +2 -2
  81. package/dist/{plugins-RHBIVLI7.js → plugins-HQTXUD6A.js} +4 -2
  82. package/dist/preflight.d.ts +1 -1
  83. package/dist/{projects-LMNAGGEU.js → projects-T4CZCA25.js} +3 -6
  84. package/dist/provider-helpers.d.ts +7 -11
  85. package/dist/{providers-models-2CFG46RD.js → providers-models-5Z2PJTEW.js} +5 -5
  86. package/dist/release-asset-download.d.ts +10 -0
  87. package/dist/release-attestation.d.ts +28 -0
  88. package/dist/remote/remote-session.d.ts +64 -0
  89. package/dist/remote/remote-target.d.ts +69 -0
  90. package/dist/remote-GB5VXCCT.js +576 -0
  91. package/dist/{replay-Z3FTJEMM.js → replay-DEI566CW.js} +2 -2
  92. package/dist/services/commit-message.d.ts +2 -1
  93. package/dist/session-move-P2EC2COA.js +44 -0
  94. package/dist/session-move.d.ts +20 -0
  95. package/dist/session-stats.d.ts +10 -0
  96. package/dist/{sessions-config-IQUH2GXT.js → sessions-config-XHLXJ5C3.js} +109 -10
  97. package/dist/short-circuit-flags-5TNTJPQR.js +10 -0
  98. package/dist/slash-commands/command-context.d.ts +15 -5
  99. package/dist/slash-commands/goal-refiner.d.ts +4 -49
  100. package/dist/slash-commands/mcp.d.ts +2 -1
  101. package/dist/slash-commands/permissions.d.ts +4 -0
  102. package/dist/slash-commands/settings-context-mutations.d.ts +5 -0
  103. package/dist/slash-commands/settings-limits-mutations.d.ts +12 -0
  104. package/dist/slash-commands/theme.d.ts +15 -1
  105. package/dist/standalone-auto-update-TOTRGCSA.js +249 -0
  106. package/dist/standalone-auto-update.d.ts +65 -0
  107. package/dist/standalone-update-LZO3MNLH.js +24 -0
  108. package/dist/standalone-update.d.ts +37 -1
  109. package/dist/subcommands/handlers/import-claude-code.d.ts +52 -0
  110. package/dist/subcommands/handlers/permissions.d.ts +9 -3
  111. package/dist/subcommands/handlers/remote.d.ts +6 -0
  112. package/dist/subcommands/handlers/sessions-fleet.d.ts +0 -12
  113. package/dist/subcommands/handlers/version-help.d.ts +5 -0
  114. package/dist/{subcommands-ZTSIN7LG.js → subcommands-BHQYLDSD.js} +2 -2
  115. package/dist/tui-resume-callback.d.ts +18 -0
  116. package/dist/{typesafe-HVEVPA6R.js → typesafe-U7YB2RRV.js} +5 -5
  117. package/dist/{typesafe-topic-replay-4W73BOLV.js → typesafe-topic-replay-ZILIU3WS.js} +18 -2
  118. package/dist/{update-7XIOEXTD.js → update-TDZX4IL2.js} +4 -4
  119. package/dist/{update-check-2POMBHFB.js → update-check-J5ZVKS73.js} +3 -3
  120. package/dist/version-JB2UAV2A.js +11 -0
  121. package/dist/version-help-XJJQ7YSH.js +10 -0
  122. package/dist/webui-server/route-contexts.d.ts +1 -1
  123. package/dist/webui-server/session-start-payload.d.ts +5 -1
  124. package/dist/{webui-server-L2SICPTB.js → webui-server-GCXIO3JY.js} +515 -365
  125. package/dist/webui-server-lifecycle.d.ts +57 -0
  126. package/dist/webui-server-options.d.ts +10 -0
  127. package/dist/webui-server.d.ts +0 -14
  128. package/dist/wiring/brain-and-orchestration.d.ts +3 -1
  129. package/dist/wiring/cli-prompt-and-tools-setup.d.ts +9 -0
  130. package/dist/wiring/cli-slash-commands-setup.d.ts +1 -0
  131. package/dist/wiring/command-host-state.d.ts +2 -0
  132. package/dist/wiring/hq-telemetry.d.ts +12 -0
  133. package/dist/wiring/lifecycle-plugins.d.ts +4 -2
  134. package/dist/wiring/metrics.d.ts +9 -1
  135. package/dist/wiring/pipeline.d.ts +2 -7
  136. package/dist/wiring/plugins.d.ts +3 -0
  137. package/dist/wiring/provider-status.d.ts +1 -0
  138. package/dist/wiring/provider-utility-tools.d.ts +3 -1
  139. package/package.json +29 -28
  140. package/dist/chunk-2BKFWIER.js +0 -98
  141. package/dist/chunk-424ORSE7.js +0 -56
  142. package/dist/chunk-OWNC7LMD.js +0 -78
  143. package/dist/chunk-QBBF7GIK.js +0 -65
  144. package/dist/short-circuit-flags-SDT53OML.js +0 -10
  145. package/dist/standalone-update-MW47J3AK.js +0 -164
  146. package/dist/version-help-WZ623NWM.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
@@ -9,7 +9,10 @@ import {
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";
@@ -109,6 +112,28 @@ var BUILTIN_PLUGIN_FACTORIES = [
109
112
  // ── Telegram plugin ─────────────────────────────────────────────────
110
113
  async () => (await import("@wrongstack/telegram")).default
111
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
+ }
112
137
  async function setupPlugins(params) {
113
138
  const {
114
139
  config,
@@ -133,24 +158,30 @@ async function setupPlugins(params) {
133
158
  vault,
134
159
  pipelines,
135
160
  paths,
136
- hookRegistry
161
+ hookRegistry,
162
+ safeMode
137
163
  } = params;
138
164
  const builtinPlugins = [];
139
165
  if (paths && config.features?.plugins !== false) {
140
- 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
+ }
141
181
  try {
142
182
  const plugin = await factory();
143
183
  if (!plugin) continue;
144
- const auditEntry = PLUGIN_AUDIT_ENTRIES.find((entry) => entry.name === plugin.name);
145
- const { enabled, source } = resolvePluginEnablement({
146
- name: plugin.name,
147
- aliases: plugin.configAliases,
148
- // Built-ins outside the audit catalog (prompts, sync, skills, …)
149
- // are infrastructure — they run unless explicitly turned off.
150
- defaultState: auditEntry?.defaultState ?? "active",
151
- config,
152
- matches: (spec) => (builtinPluginNameFromSpec(spec) ?? spec) === plugin.name
153
- });
184
+ const { enabled, source } = builtinEnablement(plugin.name, config, plugin.configAliases);
154
185
  if (!enabled) {
155
186
  if (source !== "default") {
156
187
  log.info(`[setupPlugins] built-in plugin "${plugin.name}" disabled by ${source}`);
@@ -164,7 +195,7 @@ async function setupPlugins(params) {
164
195
  }
165
196
  }
166
197
  }
167
- const userPlugins = config.features?.plugins === false ? [] : await loadExternalPlugins(
198
+ const userPlugins = config.features?.plugins === false || safeMode === true ? [] : await loadExternalPlugins(
168
199
  {
169
200
  config,
170
201
  log,
@@ -272,6 +303,7 @@ export {
272
303
  pluginNameFromSpec,
273
304
  builtinPluginNameFromSpec,
274
305
  BUILTIN_PLUGIN_FACTORIES,
306
+ BUILTIN_PLUGIN_NAME_HINTS,
275
307
  setupPlugins
276
308
  };
277
- //# sourceMappingURL=chunk-JF2MULWF.js.map
309
+ //# sourceMappingURL=chunk-YHYINL47.js.map