@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.
- package/data/providers.json +44 -0
- package/dist/{acp-INCNOH42.js → acp-LI665LO2.js} +18 -7
- package/dist/arg-parser.d.ts +1 -0
- package/dist/ascii-mode-SG4PRNLP.js +7 -0
- package/dist/{auth-YXK3EDUL.js → auth-TE55JF4Z.js} +68 -22
- package/dist/auth-menu/direct.d.ts +1 -0
- package/dist/auth-menu/local.d.ts +2 -0
- package/dist/auth-menu/oauth-menu.d.ts +3 -1
- package/dist/auth-menu/panel-service.d.ts +20 -0
- package/dist/{bench-YBU6BVQP.js → bench-GTLPM22B.js} +2 -2
- package/dist/boot/append-system-prompt.d.ts +10 -0
- package/dist/boot/ascii-mode.d.ts +12 -0
- package/dist/boot/config-backup-recovery.d.ts +2 -1
- package/dist/boot/container-wiring.d.ts +4 -2
- package/dist/boot/dispatch-singleshot.d.ts +4 -1
- package/dist/boot/dispatch-webui.d.ts +11 -0
- package/dist/boot/mcp-config-flag.d.ts +22 -0
- package/dist/boot/piped-stdin.d.ts +40 -0
- package/dist/boot/restricted-mode.d.ts +15 -0
- package/dist/boot/safe-mode.d.ts +30 -0
- package/dist/boot/short-circuit-desktop.d.ts +1 -0
- package/dist/boot/single-shot-budget.d.ts +30 -0
- package/dist/boot/stream-json.d.ts +36 -0
- package/dist/boot/structured-output.d.ts +16 -0
- package/dist/boot/system-prompt-builder.d.ts +2 -0
- package/dist/boot/tool-restriction-flags.d.ts +36 -0
- package/dist/boot/tui-project-picker-callback.d.ts +1 -1
- package/dist/boot/tui-settings-adapter.d.ts +15 -2
- package/dist/boot/worktree-sessions.d.ts +21 -0
- package/dist/{boot-auto-thin-MANHOYHE.js → boot-auto-thin-6Q56FY3F.js} +3 -2
- package/dist/boot-provider-selection.d.ts +67 -0
- package/dist/boot.d.ts +1 -38
- package/dist/{chunk-JY52HWL6.js → chunk-2EBVTYJR.js} +2 -2
- package/dist/{chunk-RDHFXOJM.js → chunk-2ERX3RPN.js} +112 -65
- package/dist/chunk-4TVYGG6G.js +62 -0
- package/dist/chunk-5JYDKG5B.js +154 -0
- package/dist/{chunk-KEPABQYT.js → chunk-5SEYGOCH.js} +8 -82
- package/dist/{chunk-3VXYY5JC.js → chunk-5UZBUV2H.js} +3 -19
- package/dist/chunk-BBHWW6LR.js +549 -0
- package/dist/chunk-BEHGRNOQ.js +58 -0
- package/dist/chunk-CZTXF6HY.js +140 -0
- package/dist/{chunk-JX6KL7OF.js → chunk-EPR42SWM.js} +39 -8
- package/dist/chunk-F5DCFAKI.js +36 -0
- package/dist/chunk-HLSHFXTO.js +97 -0
- package/dist/{chunk-CJTBLTS4.js → chunk-KJS5543T.js} +4 -3
- package/dist/{chunk-DE7BZDNK.js → chunk-KOEO4CJG.js} +27 -4
- package/dist/{chunk-SIS37L3W.js → chunk-L2RVEQWO.js} +211 -193
- package/dist/chunk-LBPLTTZ6.js +105 -0
- package/dist/chunk-LDCGZJTC.js +46 -0
- package/dist/chunk-LKPEBZBE.js +143 -0
- package/dist/chunk-LUMETJFO.js +171 -0
- package/dist/{chunk-KK2LB3ZS.js → chunk-OAVBM55Q.js} +9 -5
- package/dist/chunk-PZQBGUVZ.js +18 -0
- package/dist/{chunk-C3Z4N6A6.js → chunk-Q4INH2DG.js} +51 -3
- package/dist/chunk-R4QGL6GB.js +10 -0
- package/dist/{chunk-YLQEGYV4.js → chunk-RZ4ZDRYA.js} +14 -4
- package/dist/chunk-S4FFHDJG.js +93 -0
- package/dist/chunk-SFBFYIOW.js +271 -0
- package/dist/{chunk-RMQNCHGO.js → chunk-TI7KLHYX.js} +136 -11
- package/dist/{chunk-2ENZU66X.js → chunk-WQV2NP57.js} +5 -5
- package/dist/{chunk-B4JLSXZB.js → chunk-WSTVGC2C.js} +73 -45
- package/dist/chunk-X756ZS72.js +329 -0
- package/dist/{chunk-XJ7K67PP.js → chunk-YHYINL47.js} +63 -24
- package/dist/{chunk-2VMJ3E5Z.js → chunk-YTEOAWOJ.js} +6 -2
- package/dist/{chunk-GPPRNAKW.js → chunk-ZMX5HRLI.js} +2 -2
- package/dist/{cli-context-33F74CSZ.js → cli-context-UVGAN3NO.js} +496 -384
- package/dist/cli-entry-point.d.ts +2 -0
- package/dist/{cli-main-FNGMKPBA.js → cli-main-TN3KZ2P6.js} +3561 -2724
- package/dist/cli-update-notice.d.ts +2 -1
- package/dist/config-doctor.d.ts +10 -2
- package/dist/{config-transfer-2YF3CRTN.js → config-transfer-RUWLDCNK.js} +34 -13
- package/dist/{diag-doctor-ANPRUYFM.js → diag-doctor-BIZAFIAT.js} +2 -2
- package/dist/execute-deps.d.ts +2 -1
- package/dist/{execution-A6WJLSOC.js → execution-7QIP6GRY.js} +2384 -2055
- package/dist/fleet/host-types.d.ts +3 -1
- package/dist/goal-commands.d.ts +47 -0
- package/dist/goal-host.d.ts +1 -14
- package/dist/{hq-XQWQTRDA.js → hq-GLZ7QESM.js} +277 -261
- package/dist/hq-command-controller.d.ts +1 -1
- package/dist/{hq-server-IIBZQZU4.js → hq-server-YTKDVQPY.js} +2 -2
- package/dist/{hq-service-L5INQFM4.js → hq-service-BMMJAHRT.js} +11 -4
- package/dist/import-claude-code-32PCSIQI.js +236 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.js +19 -10
- package/dist/kanban-supervisor-67ECABTD.js +7 -0
- package/dist/live-settings-input.d.ts +7 -0
- package/dist/{mailbox-serve-3GFOK2I7.js → mailbox-serve-NW5VZG7R.js} +3 -3
- package/dist/{mcp-DC5WSBOO.js → mcp-LBS45HWZ.js} +4 -4
- package/dist/modeldiag-36VODVIH.js +828 -0
- package/dist/{per-subcommand-help-DHTYU524.js → per-subcommand-help-QDAQASPZ.js} +3 -3
- package/dist/permission-prompt-mirror.d.ts +1 -1
- package/dist/permission-prompt.d.ts +16 -2
- package/dist/permission-rules-view.d.ts +18 -0
- package/dist/{permissions-CFDLXETM.js → permissions-PL27UHYD.js} +67 -45
- package/dist/plugin-config.d.ts +12 -0
- package/dist/plugin-management-types.d.ts +31 -0
- package/dist/plugin-management.d.ts +2 -30
- package/dist/plugin-package-install.d.ts +3 -0
- package/dist/{plugin-usage-M6KET4OZ.js → plugin-usage-CIGOOTX3.js} +6 -5
- package/dist/{plugins-WJLW6ULV.js → plugins-HQTXUD6A.js} +6 -3
- package/dist/preflight.d.ts +1 -1
- package/dist/{projects-LMNAGGEU.js → projects-T4CZCA25.js} +3 -6
- package/dist/provider-config-utils.d.ts +1 -6
- package/dist/provider-helpers.d.ts +7 -11
- package/dist/{providers-models-LFNZ5WI7.js → providers-models-5Z2PJTEW.js} +44 -34
- package/dist/release-asset-download.d.ts +13 -0
- package/dist/release-attestation.d.ts +28 -0
- package/dist/remote/remote-session.d.ts +64 -0
- package/dist/remote/remote-target.d.ts +69 -0
- package/dist/remote-O5WXHLWV.js +561 -0
- package/dist/{replay-Z3FTJEMM.js → replay-DEI566CW.js} +2 -2
- package/dist/services/commit-message.d.ts +2 -1
- package/dist/services/dispatch-classifier.d.ts +39 -5
- package/dist/session-move-P2EC2COA.js +44 -0
- package/dist/session-move.d.ts +20 -0
- package/dist/session-stats.d.ts +10 -0
- package/dist/{sessions-config-UL45XKX7.js → sessions-config-SXTTLNXA.js} +47 -9
- package/dist/settings-menu.d.ts +2 -0
- package/dist/short-circuit-flags-74Y5N6CF.js +10 -0
- package/dist/{simpleui-dist-CXSIDAXZ.js → simpleui-dist-7BQISSEP.js} +7 -3
- package/dist/skill-suggest-L2EVWB6R.js +290 -0
- package/dist/slash-commands/command-context.d.ts +15 -5
- package/dist/slash-commands/effort.d.ts +1 -1
- package/dist/slash-commands/fallback.d.ts +1 -1
- package/dist/slash-commands/gitid.d.ts +1 -1
- package/dist/slash-commands/goal-refiner.d.ts +4 -49
- package/dist/slash-commands/jev.d.ts +4 -0
- package/dist/slash-commands/mcp.d.ts +2 -1
- package/dist/slash-commands/openai-quota.d.ts +15 -0
- package/dist/slash-commands/permissions.d.ts +4 -0
- package/dist/slash-commands/sdd-task-mutations.d.ts +4 -0
- package/dist/slash-commands/settings-context-mutations.d.ts +5 -0
- package/dist/slash-commands/settings-keys.d.ts +2 -0
- package/dist/slash-commands/settings-limits-mutations.d.ts +12 -0
- package/dist/slash-commands/settings-reset.d.ts +6 -0
- package/dist/standalone-auto-update-TOTRGCSA.js +249 -0
- package/dist/standalone-auto-update.d.ts +65 -0
- package/dist/standalone-update-LZO3MNLH.js +24 -0
- package/dist/standalone-update.d.ts +55 -0
- package/dist/subcommands/handlers/hq-alerts.d.ts +3 -0
- package/dist/subcommands/handlers/hq-audit.d.ts +46 -0
- package/dist/subcommands/handlers/hq-data-dir.d.ts +13 -0
- package/dist/subcommands/handlers/import-claude-code.d.ts +42 -0
- package/dist/subcommands/handlers/permissions.d.ts +9 -3
- package/dist/subcommands/handlers/remote.d.ts +6 -0
- package/dist/subcommands/handlers/skill-suggest.d.ts +21 -0
- package/dist/subcommands/handlers/typesafe-brain-replay.d.ts +26 -0
- package/dist/subcommands/handlers/typesafe-judgment-check.d.ts +3 -0
- package/dist/subcommands/handlers/typesafe-topic-replay.d.ts +19 -0
- package/dist/subcommands/handlers/typesafe-triage-replay.d.ts +18 -0
- package/dist/subcommands/handlers/typesafe.d.ts +23 -0
- package/dist/subcommands/handlers/version-help.d.ts +5 -0
- package/dist/{subcommands-XSLXMIDP.js → subcommands-Q6ORSB2E.js} +2 -2
- package/dist/tui-resume-callback.d.ts +18 -0
- package/dist/typesafe-U7YB2RRV.js +316 -0
- package/dist/typesafe-brain-replay-C5276FVR.js +222 -0
- package/dist/typesafe-judgment-check-GGYYV5UF.js +29 -0
- package/dist/typesafe-topic-replay-ZILIU3WS.js +234 -0
- package/dist/typesafe-triage-replay-FGAW7QM7.js +215 -0
- package/dist/{update-5DPB4YD4.js → update-TDZX4IL2.js} +4 -3
- package/dist/{update-check-BS3DHTSI.js → update-check-J5ZVKS73.js} +3 -2
- package/dist/update-check.d.ts +1 -1
- package/dist/version-JB2UAV2A.js +11 -0
- package/dist/version-help-XJJQ7YSH.js +10 -0
- package/dist/version.d.ts +3 -2
- package/dist/webui-client-observability.d.ts +7 -0
- package/dist/webui-server/route-contexts.d.ts +1 -1
- package/dist/webui-server/session-start-payload.d.ts +5 -1
- package/dist/{webui-server-MRPGTTKL.js → webui-server-YTHLRFD2.js} +577 -370
- package/dist/webui-server-lifecycle.d.ts +57 -0
- package/dist/webui-server-options.d.ts +11 -0
- package/dist/webui-server.d.ts +1 -1
- package/dist/wiring/brain-and-orchestration.d.ts +3 -1
- package/dist/wiring/cli-prompt-and-tools-setup.d.ts +9 -0
- package/dist/wiring/cli-slash-commands-setup.d.ts +1 -0
- package/dist/wiring/domain-glossary.d.ts +5 -4
- package/dist/wiring/lifecycle-plugins.d.ts +4 -2
- package/dist/wiring/metrics.d.ts +9 -1
- package/dist/wiring/pipeline.d.ts +2 -7
- package/dist/wiring/plugins.d.ts +4 -1
- package/dist/wiring/provider-persisters.d.ts +24 -0
- package/dist/wiring/provider-runtime.d.ts +9 -1
- package/dist/wiring/provider-status.d.ts +1 -0
- package/dist/wiring/provider-utility-tools.d.ts +3 -1
- package/dist/wiring/runtime-dispatch-state.d.ts +3 -1
- package/package.json +28 -28
- package/dist/chunk-2CZEORLV.js +0 -54
- package/dist/chunk-672UXYL3.js +0 -65
- package/dist/chunk-6WRKAACA.js +0 -96
- package/dist/chunk-DR2OXU46.js +0 -174
- package/dist/chunk-JACOMTIH.js +0 -275
- package/dist/chunk-XJXDOF63.js +0 -28
- package/dist/modeldiag-CJSFHZ3J.js +0 -1356
- package/dist/short-circuit-flags-7GQIGMVD.js +0 -10
- 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-
|
|
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 {
|
|
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
|
|
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-
|
|
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-
|
|
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(
|
|
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-
|
|
128
|
+
//# sourceMappingURL=chunk-ZMX5HRLI.js.map
|