@opscanvas/opscanvas 0.0.6

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.
@@ -0,0 +1,25 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 287.03 51.26">
3
+ <defs>
4
+ <style>
5
+ .cls-1 {
6
+ fill: #005ce0;
7
+ }
8
+
9
+ .cls-2 {
10
+ fill: #e2e8f0;
11
+ }
12
+ </style>
13
+ </defs>
14
+ <path class="cls-1" d="m63.25,28.26c-.69,1.25-1.6,2.21-2.73,2.88-1.13.68-2.35,1.01-3.66,1.01s-2.49-.33-3.61-.98c-1.13-.66-2.04-1.61-2.73-2.86-.69-1.25-1.04-2.71-1.04-4.4s.34-3.15,1.04-4.4c.69-1.25,1.6-2.2,2.73-2.86,1.13-.66,2.33-.99,3.61-.99s2.53.32,3.66.96c1.13.64,2.04,1.58,2.73,2.81.69,1.23,1.04,2.69,1.04,4.37s-.35,3.2-1.04,4.45m1.97-17.04c-1.94-1.18-4.1-1.77-6.5-1.77-2.06,0-3.88.43-5.48,1.29-1.6.86-2.86,1.93-3.77,3.21v-4.05h-7.08v41.35h7.08v-17.34c.98,1.28,2.25,2.34,3.82,3.19,1.57.84,3.38,1.26,5.43,1.26,2.39,0,4.56-.61,6.5-1.82,1.94-1.21,3.47-2.92,4.6-5.13,1.13-2.21,1.69-4.74,1.69-7.61s-.57-5.38-1.69-7.56c-1.13-2.17-2.66-3.85-4.6-5.03"/>
15
+ <path class="cls-1" d="m91.49,22.95c-1.32-.54-2.98-1.06-5.01-1.57-1.99-.51-3.45-1-4.4-1.49-.94-.49-1.42-1.21-1.42-2.15,0-.84.34-1.5,1.03-1.97.69-.47,1.68-.71,2.96-.71,1.38,0,2.49.33,3.31.99.83.66,1.29,1.54,1.39,2.65h6.77c-.2-2.83-1.3-5.08-3.29-6.75-1.99-1.67-4.65-2.5-7.99-2.5-2.26,0-4.22.37-5.89,1.11-1.67.74-2.95,1.75-3.84,3.03-.89,1.28-1.34,2.7-1.34,4.25,0,1.89.48,3.39,1.44,4.5.96,1.11,2.11,1.94,3.44,2.48,1.33.54,3.04,1.06,5.13,1.57,2.02.54,3.5,1.04,4.42,1.49.93.45,1.39,1.14,1.39,2.05,0,.84-.38,1.53-1.14,2.07-.76.54-1.81.81-3.16.81s-2.54-.35-3.46-1.06c-.93-.71-1.46-1.6-1.59-2.68h-7.13c.1,1.72.68,3.29,1.75,4.7,1.06,1.42,2.5,2.54,4.32,3.36,1.82.82,3.88,1.24,6.17,1.24s4.17-.36,5.84-1.09c1.67-.73,2.95-1.73,3.84-3.01.89-1.28,1.34-2.73,1.34-4.35-.03-1.85-.53-3.35-1.49-4.47-.96-1.13-2.1-1.96-3.41-2.5"/>
16
+ <path class="cls-2" d="m114.41,8.28c1.7-1.02,3.64-1.53,5.81-1.53,2.04,0,3.83.45,5.39,1.34,1.55.89,2.76,2.23,3.62,4.02h8.63c-1.25-3.79-3.45-6.75-6.59-8.9-3.15-2.14-6.81-3.21-10.99-3.21-3.57,0-6.79.81-9.67,2.44-2.88,1.63-5.14,3.9-6.8,6.81-1.66,2.91-2.49,6.21-2.49,9.89s.83,6.97,2.49,9.86c1.66,2.89,3.93,5.15,6.8,6.78,2.88,1.62,6.1,2.44,9.67,2.44,4.21,0,7.89-1.06,11.01-3.19,3.13-2.12,5.31-5.1,6.56-8.92h-8.63c-.86,1.79-2.06,3.13-3.62,4.05-1.55.91-3.35,1.37-5.39,1.37-2.18,0-4.12-.51-5.81-1.53-1.7-1.02-3.02-2.46-3.97-4.34-.95-1.88-1.42-4.05-1.42-6.51s.47-4.68,1.42-6.54c.95-1.86,2.27-3.29,3.97-4.31"/>
17
+ <path class="cls-2" d="m161.36,28.33c-.68,1.23-1.59,2.17-2.73,2.83-1.15.66-2.38.99-3.69.99s-2.49-.34-3.61-1.01c-1.13-.67-2.04-1.64-2.73-2.91s-1.04-2.74-1.04-4.42.35-3.14,1.04-4.37c.69-1.23,1.59-2.16,2.71-2.8,1.11-.64,2.33-.96,3.64-.96s2.54.33,3.69.99c1.14.66,2.06,1.6,2.73,2.83.67,1.23,1.01,2.7,1.01,4.42s-.34,3.19-1.01,4.42m1.01-14.43c-.95-1.28-2.2-2.34-3.77-3.18-1.57-.84-3.39-1.26-5.49-1.26-2.39,0-4.56.59-6.5,1.77-1.94,1.18-3.47,2.86-4.6,5.05-1.13,2.19-1.69,4.7-1.69,7.53s.56,5.4,1.69,7.61c1.13,2.21,2.66,3.92,4.6,5.13,1.94,1.21,4.09,1.82,6.44,1.82,2.09,0,3.93-.43,5.54-1.29,1.6-.86,2.86-1.95,3.77-3.26v4.09h7.13V9.91h-7.13v3.99Z"/>
18
+ <path class="cls-2" d="m189.92,9.5c-1.75,0-3.36.35-4.83,1.04-1.47.69-2.67,1.64-3.61,2.86v-3.49h-7.08v28.01h7.08v-15.47c0-2.23.56-3.94,1.69-5.13,1.13-1.19,2.67-1.79,4.63-1.79s3.44.6,4.55,1.79c1.11,1.2,1.67,2.91,1.67,5.13v15.47h7.08v-16.43c0-3.77-1.03-6.71-3.08-8.82-2.06-2.1-4.75-3.16-8.09-3.16"/>
19
+ <polygon class="cls-2" points="216.46 31.39 209.38 9.91 201.8 9.91 212.11 37.91 220.71 37.91 231.07 9.91 223.54 9.91 216.46 31.39"/>
20
+ <path class="cls-2" d="m252.25,28.33c-.68,1.23-1.59,2.17-2.73,2.83-1.15.66-2.38.99-3.69.99s-2.49-.34-3.62-1.01c-1.13-.67-2.04-1.64-2.73-2.91-.69-1.26-1.04-2.74-1.04-4.42s.35-3.14,1.04-4.37c.69-1.23,1.59-2.16,2.71-2.8s2.32-.96,3.64-.96,2.54.33,3.69.99c1.14.66,2.06,1.6,2.73,2.83.67,1.23,1.01,2.7,1.01,4.42s-.34,3.19-1.01,4.42m1.01-14.43c-.95-1.28-2.2-2.34-3.77-3.18-1.57-.84-3.4-1.26-5.49-1.26-2.39,0-4.56.59-6.5,1.77-1.94,1.18-3.47,2.86-4.6,5.05-1.13,2.19-1.69,4.7-1.69,7.53s.56,5.4,1.69,7.61c1.13,2.21,2.66,3.92,4.6,5.13,1.94,1.21,4.09,1.82,6.45,1.82,2.09,0,3.93-.43,5.54-1.29,1.6-.86,2.86-1.95,3.77-3.26v4.09h7.13V9.91h-7.13v3.99Z"/>
21
+ <path class="cls-2" d="m285.54,25.45c-.96-1.13-2.1-1.96-3.41-2.5-1.31-.54-2.98-1.06-5.01-1.57-1.99-.51-3.45-1-4.4-1.49s-1.42-1.2-1.42-2.15c0-.84.35-1.5,1.04-1.97.69-.47,1.68-.71,2.96-.71,1.38,0,2.48.33,3.31.99.83.66,1.29,1.54,1.39,2.65h6.77c-.2-2.83-1.3-5.08-3.29-6.75-1.99-1.67-4.65-2.5-7.99-2.5-2.26,0-4.22.37-5.89,1.11-1.67.74-2.95,1.75-3.84,3.03-.89,1.28-1.34,2.7-1.34,4.25,0,1.89.48,3.39,1.44,4.5.96,1.11,2.11,1.94,3.44,2.48,1.33.54,3.04,1.06,5.13,1.57,2.02.54,3.5,1.04,4.42,1.49.93.45,1.39,1.14,1.39,2.05,0,.84-.38,1.53-1.14,2.07-.76.54-1.81.81-3.16.81s-2.54-.35-3.46-1.06c-.93-.71-1.46-1.6-1.59-2.68h-7.13c.1,1.72.68,3.29,1.74,4.7,1.06,1.42,2.5,2.54,4.32,3.36,1.82.82,3.88,1.24,6.17,1.24s4.17-.36,5.84-1.09c1.67-.73,2.95-1.73,3.84-3.01.89-1.28,1.34-2.73,1.34-4.35-.03-1.85-.53-3.34-1.49-4.47"/>
22
+ <path class="cls-1" d="m30.44,26.08c-1.15,1.97-2.66,3.46-4.64,4.57-2.01,1.13-4.19,1.68-6.64,1.68s-4.62-.55-6.64-1.68c-1.98-1.11-3.51-2.61-4.68-4.59-1.16-1.97-1.72-4.18-1.72-6.77s.56-4.75,1.72-6.72c1.17-1.98,2.69-3.48,4.68-4.59,2.01-1.13,4.19-1.68,6.64-1.68s4.66.55,6.65,1.67c1.96,1.11,3.48,2.6,4.62,4.57,1.15,1.98,1.71,4.18,1.71,6.74s-.56,4.82-1.71,6.79m-1.62-23.44C25.91,1,22.69.18,19.16.18s-6.71.82-9.63,2.46c-2.92,1.64-5.24,3.92-6.96,6.82C.85,12.37,0,15.64,0,19.28s.85,6.97,2.57,9.87c1.71,2.91,4.03,5.18,6.96,6.82,2.93,1.64,6.14,2.46,9.63,2.46s6.71-.82,9.63-2.46c2.92-1.64,5.24-3.92,6.93-6.82,1.69-2.91,2.54-6.2,2.54-9.87s-.85-6.91-2.54-9.82c-1.7-2.91-4-5.18-6.9-6.82"/>
23
+ <path class="cls-1" d="m14.29,19.31c0-2.72,2.21-4.93,4.93-4.93v-4.93c-1.8,0-3.45.42-4.95,1.27-1.51.85-2.7,2.02-3.59,3.52-.88,1.5-1.32,3.19-1.32,5.06s.44,3.59,1.32,5.09c.88,1.5,2.08,2.67,3.59,3.52,1.5.84,3.15,1.27,4.95,1.27v-4.93c-2.72,0-4.93-2.21-4.93-4.93"/>
24
+ <path class="cls-1" d="m19.72,15.39v7.84c2.16,0,3.92-1.75,3.92-3.92s-1.76-3.92-3.92-3.92"/>
25
+ </svg>
@@ -0,0 +1,17 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <title>OpsCanvas Operator</title>
7
+ <!-- Relative so the bundler emits and fingerprints it. An absolute path
8
+ would need a `public/` directory, which this package deliberately does
9
+ not have. -->
10
+ <link rel="icon" href="/assets/favicon-Bm_xPDCY.png" />
11
+ <script type="module" crossorigin src="/assets/index-Bl0pj2gr.js"></script>
12
+ <link rel="stylesheet" crossorigin href="/assets/index--QBdFuC7.css">
13
+ </head>
14
+ <body>
15
+ <div id="root"></div>
16
+ </body>
17
+ </html>
@@ -0,0 +1,366 @@
1
+ // packages/launcher/src/index.ts
2
+ import { spawnSync } from "node:child_process";
3
+ import { existsSync as existsSync2, readFileSync } from "node:fs";
4
+ import { createRequire } from "node:module";
5
+ import { dirname as dirname2 } from "node:path";
6
+
7
+ // packages/launcher/src/fetch-binary.ts
8
+ import { createHash } from "node:crypto";
9
+ import { chmod, mkdir, readFile, rename, rm } from "node:fs/promises";
10
+ import { createWriteStream, existsSync } from "node:fs";
11
+ import http from "node:http";
12
+ import https from "node:https";
13
+ import net from "node:net";
14
+ import tls from "node:tls";
15
+ import { dirname } from "node:path";
16
+ import { pipeline } from "node:stream/promises";
17
+ var MAX_ATTEMPTS = 3;
18
+ var RETRY_BASE_MS = 500;
19
+ var MAX_REDIRECTS = 5;
20
+ var REQUEST_TIMEOUT_MS = 30000;
21
+ function resolveUrl(manifestUrl, env) {
22
+ const override = env["OPERATOR_BINARY_BASE_URL"];
23
+ if (override === undefined || override === "")
24
+ return manifestUrl;
25
+ const original = new URL(manifestUrl);
26
+ const base = new URL(override.endsWith("/") ? override : `${override}/`);
27
+ return new URL(`${original.pathname.replace(/^\//, "")}${original.search}`, base).toString();
28
+ }
29
+ async function sha256Of(path) {
30
+ const hash = createHash("sha256");
31
+ hash.update(await readFile(path));
32
+ return hash.digest("hex");
33
+ }
34
+ async function matchesChecksum(path, sha256) {
35
+ if (!existsSync(path))
36
+ return false;
37
+ try {
38
+ return await sha256Of(path) === sha256;
39
+ } catch {
40
+ return false;
41
+ }
42
+ }
43
+ function proxyFor(protocol, env) {
44
+ const raw = protocol === "https:" ? env["HTTPS_PROXY"] ?? env["https_proxy"] : env["HTTP_PROXY"] ?? env["http_proxy"];
45
+ if (raw === undefined || raw === "")
46
+ return null;
47
+ try {
48
+ return new URL(raw);
49
+ } catch {
50
+ return null;
51
+ }
52
+ }
53
+ function bypassesProxy(host, env) {
54
+ const noProxy = env["NO_PROXY"] ?? env["no_proxy"] ?? "";
55
+ return noProxy.split(",").map((entry) => entry.trim()).filter((entry) => entry.length > 0).some((entry) => entry === "*" || host === entry || host.endsWith(`.${entry.replace(/^\./, "")}`));
56
+ }
57
+ function tunnelingAgent(proxy, targetIsHttps) {
58
+
59
+ class TunnelAgent extends http.Agent {
60
+ createConnection(options, callback) {
61
+ const target = options.host ?? "";
62
+ const targetPort = typeof options.port === "number" ? options.port : targetIsHttps ? 443 : 80;
63
+ const proxyPort = proxy.port.length > 0 ? Number(proxy.port) : proxy.protocol === "https:" ? 443 : 80;
64
+ const proxySocket = net.connect({ host: proxy.hostname, port: proxyPort });
65
+ const done = callback ?? (() => {});
66
+ const fail = (err) => {
67
+ proxySocket.destroy();
68
+ const placeholder = new net.Socket;
69
+ placeholder.destroy();
70
+ done(err, placeholder);
71
+ };
72
+ proxySocket.once("error", fail);
73
+ proxySocket.once("connect", () => {
74
+ const auth = proxy.username.length > 0 ? `Proxy-Authorization: Basic ${Buffer.from(`${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`).toString("base64")}\r
75
+ ` : "";
76
+ proxySocket.write(`CONNECT ${target}:${String(targetPort)} HTTP/1.1\r
77
+ Host: ${target}:${String(targetPort)}\r
78
+ ${auth}Connection: keep-alive\r
79
+ \r
80
+ `);
81
+ });
82
+ let buffered = "";
83
+ const onData = (chunk) => {
84
+ buffered += chunk.toString("latin1");
85
+ const headerEnd = buffered.indexOf(`\r
86
+ \r
87
+ `);
88
+ if (headerEnd === -1)
89
+ return;
90
+ proxySocket.removeListener("data", onData);
91
+ proxySocket.removeListener("error", fail);
92
+ const statusLine = buffered.slice(0, buffered.indexOf(`\r
93
+ `));
94
+ if (!/ 200 /.test(statusLine)) {
95
+ fail(new Error(`proxy refused CONNECT ${target}:${String(targetPort)}: ${statusLine.trim()}`));
96
+ return;
97
+ }
98
+ if (!targetIsHttps) {
99
+ done(null, proxySocket);
100
+ return;
101
+ }
102
+ const requestedServername = options.servername;
103
+ const tlsSocket = tls.connect({
104
+ socket: proxySocket,
105
+ host: target,
106
+ servername: typeof requestedServername === "string" ? requestedServername : target
107
+ });
108
+ tlsSocket.once("error", (err) => {
109
+ done(err, tlsSocket);
110
+ });
111
+ tlsSocket.once("secureConnect", () => {
112
+ done(null, tlsSocket);
113
+ });
114
+ };
115
+ proxySocket.on("data", onData);
116
+ return;
117
+ }
118
+ }
119
+ return new TunnelAgent;
120
+ }
121
+ function open(url, env) {
122
+ return new Promise((resolvePromise, reject) => {
123
+ const parsed = new URL(url);
124
+ const client = parsed.protocol === "http:" ? http : https;
125
+ const proxy = bypassesProxy(parsed.hostname, env) ? null : proxyFor(parsed.protocol, env);
126
+ const agent = proxy === null ? undefined : tunnelingAgent(proxy, parsed.protocol === "https:");
127
+ const req = client.get(parsed, { agent, timeout: REQUEST_TIMEOUT_MS, headers: { "user-agent": "opscanvas-launcher" } }, (res) => {
128
+ resolvePromise(res);
129
+ });
130
+ req.once("timeout", () => {
131
+ req.destroy(new Error(`timed out after ${String(REQUEST_TIMEOUT_MS)}ms`));
132
+ });
133
+ req.once("error", reject);
134
+ });
135
+ }
136
+ async function fetchToFile(url, destination, env) {
137
+ let current = url;
138
+ for (let redirect = 0;redirect <= MAX_REDIRECTS; redirect += 1) {
139
+ let response;
140
+ try {
141
+ response = await open(current, env);
142
+ } catch (cause) {
143
+ return { ok: false, message: cause instanceof Error ? cause.message : String(cause) };
144
+ }
145
+ const status = response.statusCode ?? 0;
146
+ if (status >= 300 && status < 400) {
147
+ const location = response.headers.location;
148
+ response.resume();
149
+ if (location === undefined)
150
+ return { ok: false, message: `redirected with no Location header (status ${String(status)})` };
151
+ current = new URL(location, current).toString();
152
+ continue;
153
+ }
154
+ if (status !== 200) {
155
+ response.resume();
156
+ return { ok: false, message: `${current} answered ${String(status)}` };
157
+ }
158
+ try {
159
+ await pipeline(response, createWriteStream(destination));
160
+ } catch (cause) {
161
+ return { ok: false, message: cause instanceof Error ? cause.message : String(cause) };
162
+ }
163
+ return { ok: true };
164
+ }
165
+ return { ok: false, message: `too many redirects fetching ${url}` };
166
+ }
167
+ function delay(ms) {
168
+ return new Promise((resolvePromise) => {
169
+ setTimeout(resolvePromise, ms);
170
+ });
171
+ }
172
+ async function ensureBinary(request) {
173
+ if (await matchesChecksum(request.destination, request.sha256))
174
+ return { ok: true };
175
+ const url = resolveUrl(request.url, request.env);
176
+ await mkdir(dirname(request.destination), { recursive: true });
177
+ const temp = `${request.destination}.download`;
178
+ let lastError = "";
179
+ for (let attempt = 1;attempt <= MAX_ATTEMPTS; attempt += 1) {
180
+ const fetched = await fetchToFile(url, temp, request.env);
181
+ const verified = fetched.ok && await matchesChecksum(temp, request.sha256);
182
+ if (verified) {
183
+ await chmod(temp, 493);
184
+ await rename(temp, request.destination);
185
+ return { ok: true };
186
+ }
187
+ lastError = fetched.ok ? "downloaded file does not match the published checksum" : fetched.message;
188
+ await rm(temp, { force: true });
189
+ if (attempt < MAX_ATTEMPTS) {
190
+ request.report(`opscanvas: fetching the binary failed (${lastError}), retrying...
191
+ `);
192
+ await delay(RETRY_BASE_MS * 2 ** (attempt - 1));
193
+ }
194
+ }
195
+ return {
196
+ ok: false,
197
+ message: `could not fetch ${url} after ${String(MAX_ATTEMPTS)} attempts: ${lastError}`
198
+ };
199
+ }
200
+
201
+ // packages/launcher/src/resolve.ts
202
+ import { join } from "node:path";
203
+
204
+ // packages/launcher/src/platform-package.ts
205
+ var MAIN_PACKAGE = "@therealopscanvas/opscanvas";
206
+ function platformPackageName(platform, arch) {
207
+ return `${MAIN_PACKAGE}-${platform}-${arch}`;
208
+ }
209
+ function binaryName(platform) {
210
+ return platform === "win32" ? "opscanvas.exe" : "opscanvas";
211
+ }
212
+ function binaryKey(platform, arch) {
213
+ return `${platform}-${arch}`;
214
+ }
215
+
216
+ // packages/launcher/src/resolve.ts
217
+ function platformsIn(supported) {
218
+ return supported.map((name) => name.slice(`${MAIN_PACKAGE}-`.length)).join(", ");
219
+ }
220
+ function resolveBinary({
221
+ platform,
222
+ arch,
223
+ locate,
224
+ exists,
225
+ supported
226
+ }) {
227
+ const packageName = platformPackageName(platform, arch);
228
+ if (!supported.includes(packageName)) {
229
+ return {
230
+ ok: false,
231
+ message: `OpsCanvas does not ship a binary for ${platform}-${arch}. It ships for ${platformsIn(supported)}.`
232
+ };
233
+ }
234
+ const directory = locate(packageName);
235
+ if (directory === null) {
236
+ return {
237
+ ok: false,
238
+ message: `${packageName} is not installed, so there is no binary to run. It is an optional dependency, which npm skips silently when it cannot fetch one: check that @opscanvas resolves to https://npm.pkg.github.com in your .npmrc, then reinstall.`
239
+ };
240
+ }
241
+ const path = join(directory, "bin", binaryName(platform));
242
+ if (!exists(path)) {
243
+ return {
244
+ ok: false,
245
+ message: `${packageName} is installed but holds no binary at ${path}. Reinstalling is the fix; a package that resolves and carries nothing is a partial download rather than a supported state.`
246
+ };
247
+ }
248
+ return { ok: true, value: { packageName, path } };
249
+ }
250
+
251
+ // packages/launcher/src/resolve-public.ts
252
+ import { join as join2 } from "node:path";
253
+ function platformsIn2(manifest) {
254
+ return Object.keys(manifest).join(", ");
255
+ }
256
+ function resolvePublicBinary({
257
+ platform,
258
+ arch,
259
+ packageDirectory,
260
+ manifest
261
+ }) {
262
+ const key = binaryKey(platform, arch);
263
+ const entry = manifest[key];
264
+ if (entry === undefined) {
265
+ return {
266
+ ok: false,
267
+ message: `OpsCanvas does not ship a binary for ${platform}-${arch}. It ships for ${platformsIn2(manifest)}.`
268
+ };
269
+ }
270
+ return { ok: true, value: { destination: join2(packageDirectory, "bin", binaryName(platform)), entry } };
271
+ }
272
+
273
+ // packages/launcher/src/index.ts
274
+ function readManifest(manifestPath) {
275
+ try {
276
+ const parsed = JSON.parse(readFileSync(manifestPath, "utf8"));
277
+ return typeof parsed === "object" && parsed !== null ? parsed : {};
278
+ } catch {
279
+ return {};
280
+ }
281
+ }
282
+ function supportedPlatforms(manifest) {
283
+ return manifest.optionalDependencies === undefined ? [] : Object.keys(manifest.optionalDependencies);
284
+ }
285
+ function locate(moduleUrl) {
286
+ const require2 = createRequire(moduleUrl);
287
+ return (specifier) => {
288
+ try {
289
+ return dirname2(require2.resolve(`${specifier}/package.json`));
290
+ } catch {
291
+ return null;
292
+ }
293
+ };
294
+ }
295
+ async function findBinary(environment, report) {
296
+ const manifest = readManifest(environment.manifestPath);
297
+ if (manifest.opscanvasBinaries !== undefined) {
298
+ const resolved = resolvePublicBinary({
299
+ platform: environment.platform,
300
+ arch: environment.arch,
301
+ packageDirectory: dirname2(environment.manifestPath),
302
+ manifest: manifest.opscanvasBinaries
303
+ });
304
+ if (!resolved.ok)
305
+ return resolved;
306
+ const fetched = await ensureBinary({
307
+ url: resolved.value.entry.url,
308
+ sha256: resolved.value.entry.sha256,
309
+ destination: resolved.value.destination,
310
+ env: process.env,
311
+ report
312
+ });
313
+ if (!fetched.ok)
314
+ return { ok: false, message: fetched.message };
315
+ return {
316
+ ok: true,
317
+ value: { packageName: `opscanvas (${environment.platform}-${environment.arch})`, path: resolved.value.destination }
318
+ };
319
+ }
320
+ return resolveBinary({
321
+ platform: environment.platform,
322
+ arch: environment.arch,
323
+ locate: locate(environment.moduleUrl),
324
+ exists: existsSync2,
325
+ supported: supportedPlatforms(manifest)
326
+ });
327
+ }
328
+ async function execute(environment, args, report) {
329
+ const found = await findBinary(environment, report);
330
+ if (!found.ok) {
331
+ report(`opscanvas: ${found.message}
332
+ `);
333
+ return 1;
334
+ }
335
+ const finished = spawnSync(found.value.path, [...args], { stdio: "inherit" });
336
+ if (finished.error !== undefined) {
337
+ report(`opscanvas: could not run ${found.value.path}: ${finished.error.message}
338
+ `);
339
+ return 1;
340
+ }
341
+ return finished.status ?? 1;
342
+ }
343
+ var SERVICE_UNREGISTRABLE = 3;
344
+ async function cli(environment, argv, report) {
345
+ return execute(environment, argv, report);
346
+ }
347
+ async function postinstall(environment, report) {
348
+ const code = await execute(environment, ["setup"], report);
349
+ if (code === SERVICE_UNREGISTRABLE) {
350
+ report("opscanvas: installed, but nothing will start it at login on this machine. Run `opscanvas service restart` when you need it.\n");
351
+ } else if (code !== 0) {
352
+ report("opscanvas: setup did not finish. The package is installed; run `npx opscanvas setup` to try again.\n");
353
+ }
354
+ return 0;
355
+ }
356
+ export {
357
+ resolvePublicBinary,
358
+ resolveBinary,
359
+ postinstall,
360
+ platformPackageName,
361
+ findBinary,
362
+ execute,
363
+ cli,
364
+ binaryName,
365
+ MAIN_PACKAGE
366
+ };
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@opscanvas/opscanvas",
3
+ "version": "0.0.6",
4
+ "description": "Findings evaluation, planning, and verification engine for the practitioner's own agent harness.",
5
+ "license": "GPL-3.0-only",
6
+ "repository": "https://github.com/TheRealOpsCanvas/opscanvas-operator",
7
+ "type": "module",
8
+ "bin": {
9
+ "opscanvas": "bin/opscanvas.mjs"
10
+ },
11
+ "scripts": {
12
+ "postinstall": "node ./postinstall.mjs"
13
+ },
14
+ "files": [
15
+ "bin",
16
+ "lib",
17
+ "dist",
18
+ "postinstall.mjs",
19
+ "README.md"
20
+ ],
21
+ "opscanvasBinaries": {
22
+ "darwin-arm64": {
23
+ "url": "https://packages.opscanvas.io/opscanvas/0.0.6/darwin-arm64/opscanvas",
24
+ "sha256": "6afb3a096b69761af87f792d19a2469a1b5c688603b6434bb739c2363bebcbd9",
25
+ "size": 64655266
26
+ },
27
+ "darwin-x64": {
28
+ "url": "https://packages.opscanvas.io/opscanvas/0.0.6/darwin-x64/opscanvas",
29
+ "sha256": "069888fcfce1e935240cce81ac41a1e48b96178666fb308d60b188cccb5eb910",
30
+ "size": 69861888
31
+ },
32
+ "linux-arm64": {
33
+ "url": "https://packages.opscanvas.io/opscanvas/0.0.6/linux-arm64/opscanvas",
34
+ "sha256": "5a3a3852844f7566acbb6447698323e0fc61758dff8562289f3e7f30ca7f68ef",
35
+ "size": 102959424
36
+ },
37
+ "linux-x64": {
38
+ "url": "https://packages.opscanvas.io/opscanvas/0.0.6/linux-x64/opscanvas",
39
+ "sha256": "66f873e4d9938f6cdbe39853f8f67d572bfc73b903254dd4097a55e9fbd3b459",
40
+ "size": 103422272
41
+ },
42
+ "win32-x64": {
43
+ "url": "https://packages.opscanvas.io/opscanvas/0.0.6/win32-x64/opscanvas.exe",
44
+ "sha256": "4e9b02449eab04003446b41149e3a51e0f8368e6653b548b78f67247808b814f",
45
+ "size": 119251456
46
+ }
47
+ },
48
+ "publishConfig": {
49
+ "registry": "https://registry.npmjs.org"
50
+ }
51
+ }
@@ -0,0 +1,14 @@
1
+ import { fileURLToPath } from "node:url";
2
+ import { postinstall } from "./lib/launcher.js";
3
+
4
+ // Always zero. See `postinstall` in packages/launcher: a failed install script
5
+ // fails the whole install, and nothing this can discover is worth that.
6
+ process.exitCode = await postinstall(
7
+ {
8
+ moduleUrl: import.meta.url,
9
+ manifestPath: fileURLToPath(new URL("./package.json", import.meta.url)),
10
+ platform: process.platform,
11
+ arch: process.arch,
12
+ },
13
+ (text) => process.stderr.write(text),
14
+ );