cwm-assistant 0.2.1 → 0.3.0
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.
|
@@ -5,10 +5,10 @@ var __export = (target, all) => {
|
|
|
5
5
|
};
|
|
6
6
|
|
|
7
7
|
// src/cli.ts
|
|
8
|
-
import { spawn as
|
|
9
|
-
import
|
|
8
|
+
import { spawn as spawn8 } from "node:child_process";
|
|
9
|
+
import fs24 from "node:fs";
|
|
10
10
|
import os9 from "node:os";
|
|
11
|
-
import
|
|
11
|
+
import path27 from "node:path";
|
|
12
12
|
import { createInterface } from "node:readline/promises";
|
|
13
13
|
|
|
14
14
|
// ../../node_modules/@sinclair/typebox/build/esm/type/guard/value.mjs
|
|
@@ -2619,7 +2619,7 @@ var Type = type_exports2;
|
|
|
2619
2619
|
|
|
2620
2620
|
// ../../packages/contracts/src/assistant.ts
|
|
2621
2621
|
var ASSISTANT_PROTOCOL = 1;
|
|
2622
|
-
var ASSISTANT_VERSION = "0.
|
|
2622
|
+
var ASSISTANT_VERSION = "0.3.0";
|
|
2623
2623
|
var ASSISTANT_PORT = 46322;
|
|
2624
2624
|
|
|
2625
2625
|
// ../../packages/contracts/src/index.ts
|
|
@@ -5554,20 +5554,20 @@ function registerQueryRoutes(app, store) {
|
|
|
5554
5554
|
app.get("/v1/repositories", async (request) => {
|
|
5555
5555
|
const grant = requestGrant(request);
|
|
5556
5556
|
const prefix = scopeKey(grant.workbenchId, grant.userId, "");
|
|
5557
|
-
return Object.entries(store.state.repositories).filter(([key]) => key.startsWith(prefix)).map(([key,
|
|
5557
|
+
return Object.entries(store.state.repositories).filter(([key]) => key.startsWith(prefix)).map(([key, path28]) => ({ id: key.slice(prefix.length), path: path28 }));
|
|
5558
5558
|
});
|
|
5559
5559
|
app.post("/v1/repositories/inspect", async (request) => {
|
|
5560
5560
|
const body = request.body;
|
|
5561
|
-
const
|
|
5562
|
-
if (!
|
|
5561
|
+
const path28 = body.path;
|
|
5562
|
+
if (!path28 || !(await import("node:path")).default.isAbsolute(path28))
|
|
5563
5563
|
throw new Error("\u8BF7\u9009\u62E9\u7EDD\u5BF9\u8DEF\u5F84");
|
|
5564
5564
|
return git4(async () => ({
|
|
5565
|
-
root: await runGit(
|
|
5566
|
-
remoteUrl: (await runGit(
|
|
5565
|
+
root: await runGit(path28, ["rev-parse", "--show-toplevel"]),
|
|
5566
|
+
remoteUrl: (await runGit(path28, ["remote", "get-url", "origin"]).catch(() => "")).replace(
|
|
5567
5567
|
/(https?:\/\/)[^/@\s]+@/gi,
|
|
5568
5568
|
"$1"
|
|
5569
5569
|
),
|
|
5570
|
-
branches: (await runGit(
|
|
5570
|
+
branches: (await runGit(path28, [
|
|
5571
5571
|
"for-each-ref",
|
|
5572
5572
|
"--format=%(refname:short)",
|
|
5573
5573
|
"refs/heads",
|
|
@@ -5985,8 +5985,121 @@ function registerReviewRoute(app, store, jobs) {
|
|
|
5985
5985
|
});
|
|
5986
5986
|
}
|
|
5987
5987
|
|
|
5988
|
+
// src/upgrade.ts
|
|
5989
|
+
import { spawn as spawn7 } from "node:child_process";
|
|
5990
|
+
import fs23 from "node:fs";
|
|
5991
|
+
import path26 from "node:path";
|
|
5992
|
+
function packageRoot(entry) {
|
|
5993
|
+
let directory = path26.dirname(path26.resolve(entry));
|
|
5994
|
+
for (let depth = 0; depth < 4; depth++) {
|
|
5995
|
+
if (fs23.existsSync(path26.join(directory, "package.json"))) return directory;
|
|
5996
|
+
directory = path26.dirname(directory);
|
|
5997
|
+
}
|
|
5998
|
+
return path26.dirname(path26.dirname(path26.resolve(entry)));
|
|
5999
|
+
}
|
|
6000
|
+
function isGlobalInstall(root, prefix) {
|
|
6001
|
+
if (!prefix) return false;
|
|
6002
|
+
const relative = path26.relative(path26.resolve(prefix), path26.resolve(root));
|
|
6003
|
+
return Boolean(relative) && !relative.startsWith("..") && !path26.isAbsolute(relative);
|
|
6004
|
+
}
|
|
6005
|
+
function looksGlobal(root) {
|
|
6006
|
+
const modules = path26.dirname(path26.resolve(root));
|
|
6007
|
+
if (path26.basename(modules) !== "node_modules") return false;
|
|
6008
|
+
return !fs23.existsSync(path26.join(path26.dirname(modules), "package.json"));
|
|
6009
|
+
}
|
|
6010
|
+
function isNewer(candidate, current) {
|
|
6011
|
+
const parse = (value) => value.split("-")[0].split(".").map((part) => Number(part) || 0);
|
|
6012
|
+
const [a, b] = [parse(candidate), parse(current)];
|
|
6013
|
+
for (let index = 0; index < Math.max(a.length, b.length); index++) {
|
|
6014
|
+
const [left, right] = [a[index] ?? 0, b[index] ?? 0];
|
|
6015
|
+
if (left !== right) return left > right;
|
|
6016
|
+
}
|
|
6017
|
+
return !candidate.includes("-") && current.includes("-");
|
|
6018
|
+
}
|
|
6019
|
+
async function latestPublished() {
|
|
6020
|
+
const response = await fetch("https://registry.npmjs.org/cwm-assistant/latest", {
|
|
6021
|
+
signal: AbortSignal.timeout(5e3),
|
|
6022
|
+
headers: { Accept: "application/vnd.npm.install-v1+json" }
|
|
6023
|
+
});
|
|
6024
|
+
if (!response.ok) throw new Error("\u65E0\u6CD5\u67E5\u8BE2 npm \u4E0A\u7684\u6700\u65B0\u7248\u672C");
|
|
6025
|
+
const data = await response.json();
|
|
6026
|
+
if (!data.version) throw new Error("npm \u8FD4\u56DE\u7684\u7248\u672C\u4FE1\u606F\u65E0\u6548");
|
|
6027
|
+
return data.version;
|
|
6028
|
+
}
|
|
6029
|
+
var statusFile = (store) => path26.join(store.directory, "upgrade.json");
|
|
6030
|
+
function readStatus(store) {
|
|
6031
|
+
try {
|
|
6032
|
+
return JSON.parse(fs23.readFileSync(statusFile(store), "utf8"));
|
|
6033
|
+
} catch {
|
|
6034
|
+
return void 0;
|
|
6035
|
+
}
|
|
6036
|
+
}
|
|
6037
|
+
function registerUpgradeRoutes(app, store, entry, options = {}) {
|
|
6038
|
+
const latestVersion = options.latest || latestPublished;
|
|
6039
|
+
const root = packageRoot(entry);
|
|
6040
|
+
const prefix = () => store.state.installPrefix || process.env.npm_config_prefix;
|
|
6041
|
+
const global = isGlobalInstall(root, prefix()) || looksGlobal(root);
|
|
6042
|
+
app.get("/v1/upgrade", async () => {
|
|
6043
|
+
let latest = "";
|
|
6044
|
+
let error = "";
|
|
6045
|
+
try {
|
|
6046
|
+
latest = await latestVersion();
|
|
6047
|
+
} catch (cause) {
|
|
6048
|
+
error = cause.message;
|
|
6049
|
+
}
|
|
6050
|
+
const status = readStatus(store);
|
|
6051
|
+
const busy = Object.values(store.state.jobs).some((job) => job.state === "running");
|
|
6052
|
+
return {
|
|
6053
|
+
version: ASSISTANT_VERSION,
|
|
6054
|
+
latest,
|
|
6055
|
+
available: Boolean(latest) && isNewer(latest, ASSISTANT_VERSION),
|
|
6056
|
+
// A source run (or an install we cannot locate) is not replaced from the page.
|
|
6057
|
+
upgradeable: global,
|
|
6058
|
+
reason: global ? "" : "\u5F53\u524D\u4E0D\u662F\u5168\u5C40 npm \u5B89\u88C5\uFF0C\u8BF7\u5728\u7EC8\u7AEF\u5347\u7EA7",
|
|
6059
|
+
error,
|
|
6060
|
+
busy,
|
|
6061
|
+
// A previous attempt that never reached the new version left this behind.
|
|
6062
|
+
previous: status && status.target !== ASSISTANT_VERSION ? status : void 0
|
|
6063
|
+
};
|
|
6064
|
+
});
|
|
6065
|
+
app.post("/v1/upgrade", async (_request, reply) => {
|
|
6066
|
+
if (!global) return reply.code(409).send({ error: "\u5F53\u524D\u4E0D\u662F\u5168\u5C40 npm \u5B89\u88C5\uFF0C\u8BF7\u5728\u7EC8\u7AEF\u5347\u7EA7" });
|
|
6067
|
+
if (Object.values(store.state.jobs).some((job) => job.state === "running"))
|
|
6068
|
+
return reply.code(409).send({ error: "\u672C\u5730\u4EFB\u52A1\u8FD0\u884C\u4E2D\uFF0C\u8BF7\u7B49\u5F85\u5B8C\u6210\u540E\u518D\u5347\u7EA7" });
|
|
6069
|
+
let latest;
|
|
6070
|
+
try {
|
|
6071
|
+
latest = await latestVersion();
|
|
6072
|
+
} catch (cause) {
|
|
6073
|
+
return reply.code(502).send({ error: cause.message });
|
|
6074
|
+
}
|
|
6075
|
+
if (!isNewer(latest, ASSISTANT_VERSION)) return { latest, started: false };
|
|
6076
|
+
fs23.writeFileSync(
|
|
6077
|
+
statusFile(store),
|
|
6078
|
+
JSON.stringify({ target: latest, state: "running", startedAt: (/* @__PURE__ */ new Date()).toISOString() }),
|
|
6079
|
+
{ mode: 384 }
|
|
6080
|
+
);
|
|
6081
|
+
const child = spawn7(
|
|
6082
|
+
process.execPath,
|
|
6083
|
+
[
|
|
6084
|
+
path26.join(root, "scripts", "upgrade.mjs"),
|
|
6085
|
+
"--version",
|
|
6086
|
+
latest,
|
|
6087
|
+
"--state-dir",
|
|
6088
|
+
store.directory
|
|
6089
|
+
],
|
|
6090
|
+
{ detached: true, stdio: "ignore", windowsHide: true, cwd: root }
|
|
6091
|
+
);
|
|
6092
|
+
child.unref();
|
|
6093
|
+
if (store.state.autostart)
|
|
6094
|
+
await configureAutostart(false, store.directory, entry).catch(() => {
|
|
6095
|
+
});
|
|
6096
|
+
setTimeout(() => process.exit(0), 300);
|
|
6097
|
+
return { latest, started: true };
|
|
6098
|
+
});
|
|
6099
|
+
}
|
|
6100
|
+
|
|
5988
6101
|
// src/server.ts
|
|
5989
|
-
async function buildAssistant(store, options = {}) {
|
|
6102
|
+
async function buildAssistant(store, options = {}, entry, upgrade = {}) {
|
|
5990
6103
|
const app = Fastify({ logger: false, bodyLimit: 1024 * 1024 });
|
|
5991
6104
|
const jobs = new LocalJobs(store);
|
|
5992
6105
|
app.setErrorHandler(
|
|
@@ -6001,7 +6114,7 @@ async function buildAssistant(store, options = {}) {
|
|
|
6001
6114
|
return;
|
|
6002
6115
|
}
|
|
6003
6116
|
const origin = request.headers.origin || "";
|
|
6004
|
-
const
|
|
6117
|
+
const path28 = request.url.split("?")[0];
|
|
6005
6118
|
let workbench = store.state.workbenches[origin];
|
|
6006
6119
|
if (!workbench && trustedOrigin(origin)) {
|
|
6007
6120
|
try {
|
|
@@ -6024,7 +6137,7 @@ async function buildAssistant(store, options = {}) {
|
|
|
6024
6137
|
reply.header("Access-Control-Allow-Headers", "Authorization, Content-Type, X-CWM-Binding");
|
|
6025
6138
|
return reply.code(204).send();
|
|
6026
6139
|
}
|
|
6027
|
-
if (
|
|
6140
|
+
if (path28 === "/v1/health" || path28 === "/v1/pairings") return;
|
|
6028
6141
|
try {
|
|
6029
6142
|
const token = request.headers.authorization?.replace(/^Bearer /, "") || "";
|
|
6030
6143
|
const grant = verifyGrant(token, workbench.publicKey);
|
|
@@ -6143,6 +6256,8 @@ async function buildAssistant(store, options = {}) {
|
|
|
6143
6256
|
input: job.input,
|
|
6144
6257
|
state: job.state,
|
|
6145
6258
|
error: job.error,
|
|
6259
|
+
// The list is used to pick the newest job per workspace, so ordering needs a timestamp.
|
|
6260
|
+
updatedAt: "updatedAt" in job ? job.updatedAt : void 0,
|
|
6146
6261
|
deviceId: store.state.identity.id
|
|
6147
6262
|
}));
|
|
6148
6263
|
});
|
|
@@ -6172,6 +6287,7 @@ async function buildAssistant(store, options = {}) {
|
|
|
6172
6287
|
return { ok: true };
|
|
6173
6288
|
});
|
|
6174
6289
|
registerLocalRoutes(app, store, options);
|
|
6290
|
+
if (entry) registerUpgradeRoutes(app, store, entry, upgrade);
|
|
6175
6291
|
registerQueryRoutes(app, store);
|
|
6176
6292
|
registerAdoptRoutes(app, store, jobs);
|
|
6177
6293
|
registerDeleteRoute(app, store, jobs);
|
|
@@ -6195,7 +6311,7 @@ async function cli(args, entry) {
|
|
|
6195
6311
|
return;
|
|
6196
6312
|
}
|
|
6197
6313
|
const dirIndex = args.indexOf("--state-dir");
|
|
6198
|
-
const directory = dirIndex >= 0 ?
|
|
6314
|
+
const directory = dirIndex >= 0 ? path27.resolve(args[dirIndex + 1]) : defaultStateDirectory();
|
|
6199
6315
|
const command = args[0] || "status";
|
|
6200
6316
|
const store = new StateStore(directory);
|
|
6201
6317
|
const control = async (action) => {
|
|
@@ -6221,14 +6337,14 @@ async function cli(args, entry) {
|
|
|
6221
6337
|
}
|
|
6222
6338
|
if (store.state.autostart) await startAutostart();
|
|
6223
6339
|
else {
|
|
6224
|
-
const log =
|
|
6225
|
-
const child =
|
|
6340
|
+
const log = fs24.openSync(path27.join(directory, "assistant.log"), "a", 384);
|
|
6341
|
+
const child = spawn8(process.execPath, [entry, "serve", "--state-dir", directory], {
|
|
6226
6342
|
detached: true,
|
|
6227
6343
|
windowsHide: true,
|
|
6228
6344
|
stdio: ["ignore", log, log]
|
|
6229
6345
|
});
|
|
6230
6346
|
child.unref();
|
|
6231
|
-
|
|
6347
|
+
fs24.closeSync(log);
|
|
6232
6348
|
}
|
|
6233
6349
|
const deadline = Date.now() + 1e4;
|
|
6234
6350
|
while (Date.now() < deadline) {
|
|
@@ -6243,21 +6359,21 @@ async function cli(args, entry) {
|
|
|
6243
6359
|
throw new Error("\u542F\u52A8\u5931\u8D25\uFF0C\u8BF7\u8FD0\u884C cwm-assistant logs \u68C0\u67E5\u7AEF\u53E3\u548C\u8FD0\u884C\u73AF\u5883");
|
|
6244
6360
|
}
|
|
6245
6361
|
if (command === "serve") {
|
|
6246
|
-
const lock =
|
|
6247
|
-
if (
|
|
6248
|
-
const pid = Number(
|
|
6362
|
+
const lock = path27.join(directory, "process.lock");
|
|
6363
|
+
if (fs24.existsSync(lock)) {
|
|
6364
|
+
const pid = Number(fs24.readFileSync(lock, "utf8"));
|
|
6249
6365
|
try {
|
|
6250
6366
|
process.kill(pid, 0);
|
|
6251
6367
|
throw new Error("Workspace \u52A9\u624B\u5DF2\u8FD0\u884C");
|
|
6252
6368
|
} catch (error) {
|
|
6253
6369
|
if (error.code !== "ESRCH") throw error;
|
|
6254
|
-
|
|
6370
|
+
fs24.unlinkSync(lock);
|
|
6255
6371
|
}
|
|
6256
6372
|
}
|
|
6257
|
-
|
|
6373
|
+
fs24.writeFileSync(lock, String(process.pid), { flag: "wx", mode: 384 });
|
|
6258
6374
|
store.reload();
|
|
6259
6375
|
store.recover();
|
|
6260
|
-
const { app, jobs } = await buildAssistant(store);
|
|
6376
|
+
const { app, jobs } = await buildAssistant(store, {}, entry);
|
|
6261
6377
|
app.post("/control", async (request, reply) => {
|
|
6262
6378
|
const action = request.body.action;
|
|
6263
6379
|
if (action === "status")
|
|
@@ -6278,12 +6394,12 @@ async function cli(args, entry) {
|
|
|
6278
6394
|
return reply.code(400).send({ error: "\u63A7\u5236\u64CD\u4F5C\u65E0\u6548" });
|
|
6279
6395
|
});
|
|
6280
6396
|
app.addHook("onClose", async () => {
|
|
6281
|
-
|
|
6397
|
+
fs24.rmSync(lock, { force: true });
|
|
6282
6398
|
});
|
|
6283
6399
|
try {
|
|
6284
6400
|
await app.listen({ host: "127.0.0.1", port: ASSISTANT_PORT });
|
|
6285
6401
|
} catch (error) {
|
|
6286
|
-
|
|
6402
|
+
fs24.rmSync(lock, { force: true });
|
|
6287
6403
|
throw error;
|
|
6288
6404
|
}
|
|
6289
6405
|
for (const signal of ["SIGTERM", "SIGINT"])
|
|
@@ -6292,6 +6408,9 @@ async function cli(args, entry) {
|
|
|
6292
6408
|
}
|
|
6293
6409
|
if (command === "start") return start();
|
|
6294
6410
|
if (command === "install") {
|
|
6411
|
+
const prefixIndex = args.indexOf("--prefix");
|
|
6412
|
+
const installPrefix = prefixIndex >= 0 ? args[prefixIndex + 1] : store.state.installPrefix;
|
|
6413
|
+
if (installPrefix) store.state.installPrefix = installPrefix;
|
|
6295
6414
|
const running = await control("status").catch(() => void 0);
|
|
6296
6415
|
if (running?.busy) {
|
|
6297
6416
|
console.error(
|
|
@@ -6305,18 +6424,21 @@ async function cli(args, entry) {
|
|
|
6305
6424
|
await control("stop").catch(() => {
|
|
6306
6425
|
});
|
|
6307
6426
|
const deadline = Date.now() + 1e4;
|
|
6308
|
-
while (
|
|
6427
|
+
while (fs24.existsSync(path27.join(directory, "process.lock")) && Date.now() < deadline) {
|
|
6309
6428
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
6310
6429
|
}
|
|
6311
6430
|
}
|
|
6431
|
+
let autostart = false;
|
|
6312
6432
|
try {
|
|
6313
6433
|
await configureAutostart(true, directory, entry);
|
|
6314
|
-
|
|
6315
|
-
store.state.autostart = true;
|
|
6316
|
-
store.save();
|
|
6434
|
+
autostart = true;
|
|
6317
6435
|
} catch {
|
|
6318
6436
|
console.error("\u672A\u80FD\u6CE8\u518C\u767B\u5F55\u81EA\u542F\u52A8\uFF0C\u52A9\u624B\u5C06\u53EA\u4F5C\u4E3A\u540E\u53F0\u8FDB\u7A0B\u8FD0\u884C\u3002");
|
|
6319
6437
|
}
|
|
6438
|
+
store.reload();
|
|
6439
|
+
store.state.autostart = autostart;
|
|
6440
|
+
if (installPrefix) store.state.installPrefix = installPrefix;
|
|
6441
|
+
store.save();
|
|
6320
6442
|
await start();
|
|
6321
6443
|
return;
|
|
6322
6444
|
}
|
|
@@ -6334,9 +6456,9 @@ async function cli(args, entry) {
|
|
|
6334
6456
|
return;
|
|
6335
6457
|
}
|
|
6336
6458
|
if (command === "logs") {
|
|
6337
|
-
const file =
|
|
6459
|
+
const file = path27.join(directory, "assistant.log");
|
|
6338
6460
|
console.log(
|
|
6339
|
-
|
|
6461
|
+
fs24.existsSync(file) ? fs24.readFileSync(file, "utf8").split("\n").slice(-100).join("\n") : "\u6682\u65E0\u65E5\u5FD7"
|
|
6340
6462
|
);
|
|
6341
6463
|
return;
|
|
6342
6464
|
}
|
|
@@ -6351,10 +6473,10 @@ async function cli(args, entry) {
|
|
|
6351
6473
|
await control("stop").catch(() => {
|
|
6352
6474
|
});
|
|
6353
6475
|
const deadline = Date.now() + 1e4;
|
|
6354
|
-
while (
|
|
6476
|
+
while (fs24.existsSync(path27.join(directory, "process.lock")) && Date.now() < deadline) {
|
|
6355
6477
|
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
6356
6478
|
}
|
|
6357
|
-
if (
|
|
6479
|
+
if (fs24.existsSync(path27.join(directory, "process.lock")))
|
|
6358
6480
|
throw new Error("\u52A9\u624B\u5C1A\u672A\u505C\u6B62\uFF0C\u8BF7\u7A0D\u540E\u91CD\u8BD5\uFF1B\u672A\u4FEE\u6539\u672C\u5730\u72B6\u6001");
|
|
6359
6481
|
}
|
|
6360
6482
|
store.reload();
|
|
@@ -6389,11 +6511,11 @@ async function cli(args, entry) {
|
|
|
6389
6511
|
{
|
|
6390
6512
|
node: process.version,
|
|
6391
6513
|
nodePath: process.execPath,
|
|
6392
|
-
entryExists:
|
|
6514
|
+
entryExists: fs24.existsSync(entry),
|
|
6393
6515
|
git: store.state.git,
|
|
6394
6516
|
gitVersion,
|
|
6395
6517
|
platform: process.platform,
|
|
6396
|
-
rootExists: Boolean(store.state.root &&
|
|
6518
|
+
rootExists: Boolean(store.state.root && fs24.existsSync(store.state.root)),
|
|
6397
6519
|
configuredWorkbenches: Object.keys(store.state.workbenches),
|
|
6398
6520
|
autostart: store.state.autostart,
|
|
6399
6521
|
process: await control("status").catch(() => "\u672A\u8FD0\u884C")
|
|
@@ -6434,9 +6556,9 @@ async function cli(args, entry) {
|
|
|
6434
6556
|
}
|
|
6435
6557
|
}
|
|
6436
6558
|
if (rootArg) {
|
|
6437
|
-
if (!
|
|
6559
|
+
if (!path27.isAbsolute(rootArg) || !fs24.statSync(rootArg).isDirectory())
|
|
6438
6560
|
throw new Error("\u5DE5\u4F5C\u76EE\u5F55\u5FC5\u987B\u662F\u5DF2\u5B58\u5728\u7684\u7EDD\u5BF9\u8DEF\u5F84");
|
|
6439
|
-
store.state.root =
|
|
6561
|
+
store.state.root = fs24.realpathSync(rootArg);
|
|
6440
6562
|
}
|
|
6441
6563
|
const auto = wantAutostart || !assumeYes && await ask("\u767B\u5F55\u7535\u8111\u65F6\u81EA\u52A8\u542F\u52A8\uFF1F[Y/n] ") !== "n";
|
|
6442
6564
|
store.save();
|
|
@@ -6466,4 +6588,4 @@ async function cli(args, entry) {
|
|
|
6466
6588
|
export {
|
|
6467
6589
|
cli
|
|
6468
6590
|
};
|
|
6469
|
-
//# sourceMappingURL=cli-
|
|
6591
|
+
//# sourceMappingURL=cli-5CFP7QJS.js.map
|