superlore-cli 0.1.2 → 0.2.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.
- package/README.md +7 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +242 -20
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -40,11 +40,17 @@ curl -fsSL https://superlore.vercel.app/install.sh | sh # or: npm i -g superl
|
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
```bash
|
|
43
|
-
superlore init my-kb # scaffold — 2 questions → superlore.json + starter pages
|
|
43
|
+
superlore init my-kb # scaffold — 2 questions → superlore.json + starter pages, then sets up your editor
|
|
44
|
+
superlore connect # detect VS Code / Cursor / Windsurf and install the live-preview extension
|
|
44
45
|
superlore dev # live preview at localhost:3000
|
|
45
46
|
superlore build # production build, deploy anywhere
|
|
46
47
|
```
|
|
47
48
|
|
|
49
|
+
`init` ends by offering to run `connect` for you, so one command takes you from nothing to a
|
|
50
|
+
scaffolded KB with the editor extension installed — then it points you at wiring the MCP to your
|
|
51
|
+
agent. `connect` detects each editor via its CLI or standard install path (macOS / Linux / Windows)
|
|
52
|
+
and is safe to re-run.
|
|
53
|
+
|
|
48
54
|
`superlore deploy` is reserved for managed **superlore Cloud**
|
|
49
55
|
([waitlisted](https://superlore.vercel.app/cloud)) — self-host free with `superlore build`.
|
|
50
56
|
|
package/dist/index.d.ts
CHANGED
|
@@ -83,7 +83,7 @@ declare function serializeSuperloreJson(config: SuperloreJson): string;
|
|
|
83
83
|
declare function resolveMcpPath(config: SuperloreJson): string | undefined;
|
|
84
84
|
|
|
85
85
|
/** The CLI version, kept in sync with package.json at build time. */
|
|
86
|
-
declare const VERSION = "0.
|
|
86
|
+
declare const VERSION = "0.2.0";
|
|
87
87
|
/** Build the argument parser. Exported for tests; `run()` wires it to argv. */
|
|
88
88
|
declare function buildCli(argv?: readonly string[]): cac.CAC;
|
|
89
89
|
/** Parse argv and dispatch. Reports unknown commands and unexpected errors cleanly. */
|
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
// src/index.ts
|
|
4
4
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
5
|
-
import
|
|
5
|
+
import process3 from "process";
|
|
6
6
|
import { cac } from "cac";
|
|
7
7
|
|
|
8
8
|
// src/lib/log.ts
|
|
@@ -253,6 +253,194 @@ async function buildCommand() {
|
|
|
253
253
|
process.exit(code);
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
+
// src/lib/editors.ts
|
|
257
|
+
import { execFileSync } from "child_process";
|
|
258
|
+
import { existsSync as existsSync2, writeFileSync } from "fs";
|
|
259
|
+
import { homedir, tmpdir } from "os";
|
|
260
|
+
import { join as join2 } from "path";
|
|
261
|
+
import process2 from "process";
|
|
262
|
+
var EXTENSION_ID = "superlore.superlore-preview";
|
|
263
|
+
var DEFAULT_VSIX_URL = "https://superlore.vercel.app/superlore-preview.vsix";
|
|
264
|
+
async function downloadVsix(url = DEFAULT_VSIX_URL) {
|
|
265
|
+
const res = await fetch(url, { redirect: "follow" });
|
|
266
|
+
if (!res.ok) throw new Error(`couldn't fetch the extension (${res.status} ${res.statusText})`);
|
|
267
|
+
const bytes = Buffer.from(await res.arrayBuffer());
|
|
268
|
+
const path = join2(tmpdir(), "superlore-preview.vsix");
|
|
269
|
+
writeFileSync(path, bytes);
|
|
270
|
+
return path;
|
|
271
|
+
}
|
|
272
|
+
var EDITORS = [
|
|
273
|
+
{ id: "vscode", label: "VS Code", bin: "code" },
|
|
274
|
+
{ id: "cursor", label: "Cursor", bin: "cursor" },
|
|
275
|
+
{ id: "windsurf", label: "Windsurf", bin: "windsurf" }
|
|
276
|
+
];
|
|
277
|
+
function onPath(bin) {
|
|
278
|
+
const probe = process2.platform === "win32" ? "where" : "which";
|
|
279
|
+
try {
|
|
280
|
+
execFileSync(probe, [bin], { stdio: "ignore", shell: process2.platform === "win32" });
|
|
281
|
+
return true;
|
|
282
|
+
} catch {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
function fallbackPaths(editor) {
|
|
287
|
+
const home = homedir();
|
|
288
|
+
if (process2.platform === "darwin") {
|
|
289
|
+
const app = {
|
|
290
|
+
vscode: "Visual Studio Code.app",
|
|
291
|
+
cursor: "Cursor.app",
|
|
292
|
+
windsurf: "Windsurf.app"
|
|
293
|
+
};
|
|
294
|
+
const rel = `Contents/Resources/app/bin/${editor.bin}`;
|
|
295
|
+
return [
|
|
296
|
+
join2("/Applications", app[editor.id], rel),
|
|
297
|
+
join2(home, "Applications", app[editor.id], rel)
|
|
298
|
+
];
|
|
299
|
+
}
|
|
300
|
+
if (process2.platform === "win32") {
|
|
301
|
+
const local = process2.env.LOCALAPPDATA ?? join2(home, "AppData", "Local");
|
|
302
|
+
const programs = join2(local, "Programs");
|
|
303
|
+
const dir = {
|
|
304
|
+
vscode: "Microsoft VS Code",
|
|
305
|
+
cursor: "cursor",
|
|
306
|
+
windsurf: "Windsurf"
|
|
307
|
+
};
|
|
308
|
+
const exe = `bin\\${editor.bin}.cmd`;
|
|
309
|
+
return [
|
|
310
|
+
join2(programs, dir[editor.id], exe),
|
|
311
|
+
join2(process2.env.ProgramFiles ?? "C:\\Program Files", dir[editor.id], exe)
|
|
312
|
+
];
|
|
313
|
+
}
|
|
314
|
+
return [
|
|
315
|
+
join2("/usr/share", editor.bin, "bin", editor.bin),
|
|
316
|
+
join2("/usr/bin", editor.bin),
|
|
317
|
+
join2("/snap/bin", editor.bin),
|
|
318
|
+
join2(home, ".local", "bin", editor.bin)
|
|
319
|
+
];
|
|
320
|
+
}
|
|
321
|
+
function resolveEditorCommand(editor) {
|
|
322
|
+
if (onPath(editor.bin)) return editor.bin;
|
|
323
|
+
for (const candidate of fallbackPaths(editor)) {
|
|
324
|
+
if (existsSync2(candidate)) return candidate;
|
|
325
|
+
}
|
|
326
|
+
return void 0;
|
|
327
|
+
}
|
|
328
|
+
function detectEditors() {
|
|
329
|
+
const found = [];
|
|
330
|
+
for (const editor of EDITORS) {
|
|
331
|
+
const command = resolveEditorCommand(editor);
|
|
332
|
+
if (command) found.push({ ...editor, command });
|
|
333
|
+
}
|
|
334
|
+
return found;
|
|
335
|
+
}
|
|
336
|
+
var execRunner = (command, args) => execFileSync(command, [...args], {
|
|
337
|
+
encoding: "utf8",
|
|
338
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
339
|
+
// Editor CLIs on Windows are .cmd shims; a shell is needed to invoke them.
|
|
340
|
+
shell: process2.platform === "win32",
|
|
341
|
+
timeout: 6e4
|
|
342
|
+
}).trim();
|
|
343
|
+
function classifyInstallOutput(editor, output) {
|
|
344
|
+
return /already installed/i.test(output) ? { editor, status: "already-installed" } : { editor, status: "installed" };
|
|
345
|
+
}
|
|
346
|
+
function installInto(editor, options = {}) {
|
|
347
|
+
const run2 = options.run ?? execRunner;
|
|
348
|
+
const target = options.vsix ?? EXTENSION_ID;
|
|
349
|
+
try {
|
|
350
|
+
const output = run2(editor.command, ["--install-extension", target, "--force"]);
|
|
351
|
+
return classifyInstallOutput(editor, output);
|
|
352
|
+
} catch (error) {
|
|
353
|
+
return { editor, status: "failed", error: failureReason(error) };
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
function failureReason(error) {
|
|
357
|
+
if (error instanceof Error) {
|
|
358
|
+
const stderr = error.stderr;
|
|
359
|
+
const text2 = typeof stderr === "string" ? stderr : Buffer.isBuffer(stderr) ? stderr.toString() : "";
|
|
360
|
+
const lines = text2.split("\n").map((l) => l.trim()).filter((l) => l.length > 0 && !/^\(node:/.test(l) && !/^\(Use /.test(l));
|
|
361
|
+
const meaningful = lines.find((l) => /(not found|error|fail|denied)/i.test(l)) ?? lines[0];
|
|
362
|
+
if (meaningful) return meaningful;
|
|
363
|
+
return error.message.replace(/^Command failed:.*/s, "the editor CLI returned an error").trim();
|
|
364
|
+
}
|
|
365
|
+
return String(error);
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// src/commands/connect.ts
|
|
369
|
+
async function connectCommand(flags = {}) {
|
|
370
|
+
log.blank();
|
|
371
|
+
log.info(`${accent("superlore connect")} ${dim("\u2014 set up your editor")}`);
|
|
372
|
+
log.blank();
|
|
373
|
+
const detected = detectEditors();
|
|
374
|
+
if (detected.length === 0) {
|
|
375
|
+
log.warn("No supported editor detected (looked for VS Code, Cursor, and Windsurf).");
|
|
376
|
+
log.blank();
|
|
377
|
+
log.info(`${dim("Install one, then re-run")} ${cyan("superlore connect")}${dim(".")}`);
|
|
378
|
+
log.info(
|
|
379
|
+
`${dim("If an editor is installed but its CLI isn't on PATH, open it and run")} ${cyan(`"Shell Command: Install '<editor>' command in PATH"`)}${dim(".")}`
|
|
380
|
+
);
|
|
381
|
+
printMcpNextStep();
|
|
382
|
+
process.exit(0);
|
|
383
|
+
}
|
|
384
|
+
const labels = detected.map((e) => bold(e.label)).join(", ");
|
|
385
|
+
log.step(`Found ${labels}. Installing the superlore Preview extension\u2026`);
|
|
386
|
+
log.blank();
|
|
387
|
+
let vsix;
|
|
388
|
+
try {
|
|
389
|
+
vsix = flags.vsix ?? await downloadVsix();
|
|
390
|
+
} catch (error) {
|
|
391
|
+
log.error(
|
|
392
|
+
`Couldn't fetch the extension: ${error instanceof Error ? error.message : String(error)}`
|
|
393
|
+
);
|
|
394
|
+
printManualInstall();
|
|
395
|
+
process.exit(flags.optional ? 0 : 1);
|
|
396
|
+
}
|
|
397
|
+
const results = detected.map((editor) => report(installInto(editor, { vsix })));
|
|
398
|
+
log.blank();
|
|
399
|
+
const failed = results.filter((r) => r.status === "failed");
|
|
400
|
+
if (failed.length > 0 && failed.length === results.length) {
|
|
401
|
+
log.error("Couldn't install the extension into any editor. See the errors above.");
|
|
402
|
+
printManualInstall();
|
|
403
|
+
process.exit(flags.optional ? 0 : 1);
|
|
404
|
+
}
|
|
405
|
+
log.success(
|
|
406
|
+
`superlore Preview is ready. Open a ${cyan(".mdx")} file and run ${cyan("superlore: Open Preview")} ${dim("(Cmd/Ctrl+K V)")}.`
|
|
407
|
+
);
|
|
408
|
+
printMcpNextStep();
|
|
409
|
+
}
|
|
410
|
+
function report(result) {
|
|
411
|
+
switch (result.status) {
|
|
412
|
+
case "installed":
|
|
413
|
+
log.success(`${bold(result.editor.label)} ${dim("\u2014 extension installed.")}`);
|
|
414
|
+
break;
|
|
415
|
+
case "already-installed":
|
|
416
|
+
log.info(`${accent("\u203A")} ${bold(result.editor.label)} ${dim("\u2014 already installed, up to date.")}`);
|
|
417
|
+
break;
|
|
418
|
+
case "failed":
|
|
419
|
+
log.error(`${bold(result.editor.label)} ${dim("\u2014 install failed:")} ${result.error}`);
|
|
420
|
+
break;
|
|
421
|
+
}
|
|
422
|
+
return result;
|
|
423
|
+
}
|
|
424
|
+
function printManualInstall() {
|
|
425
|
+
log.blank();
|
|
426
|
+
log.info(
|
|
427
|
+
`${dim("Install it by hand: download")} ${cyan("superlore.vercel.app/superlore-preview.vsix")}${dim(",")}`
|
|
428
|
+
);
|
|
429
|
+
log.info(
|
|
430
|
+
`${dim("then run")} ${cyan('"Extensions: Install from VSIX\u2026"')} ${dim("in your editor (or")} ${cyan("code --install-extension <file>.vsix")}${dim(").")}`
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
function printMcpNextStep() {
|
|
434
|
+
log.blank();
|
|
435
|
+
log.info(bold("Next: connect the MCP"));
|
|
436
|
+
log.info(
|
|
437
|
+
` ${dim("Let your agent read the same corpus. Ask Claude")} ${cyan('"connect my superlore MCP"')}${dim(",")}`
|
|
438
|
+
);
|
|
439
|
+
log.info(
|
|
440
|
+
` ${dim("or register it yourself:")} ${cyan("claude mcp add --transport http -s user superlore <url>/api/mcp")}`
|
|
441
|
+
);
|
|
442
|
+
}
|
|
443
|
+
|
|
256
444
|
// src/commands/deploy.ts
|
|
257
445
|
import { spawn as spawn2 } from "child_process";
|
|
258
446
|
|
|
@@ -332,34 +520,34 @@ async function devCommand(flags) {
|
|
|
332
520
|
}
|
|
333
521
|
|
|
334
522
|
// src/commands/init.ts
|
|
335
|
-
import { existsSync as
|
|
523
|
+
import { existsSync as existsSync4 } from "fs";
|
|
336
524
|
import { basename, resolve as resolve3 } from "path";
|
|
337
525
|
import { cancel, confirm, intro, isCancel, outro, select, text } from "@clack/prompts";
|
|
338
526
|
|
|
339
527
|
// src/lib/scaffold.ts
|
|
340
|
-
import { cpSync, existsSync as
|
|
528
|
+
import { cpSync, existsSync as existsSync3, mkdirSync, readdirSync, writeFileSync as writeFileSync2 } from "fs";
|
|
341
529
|
import { fileURLToPath } from "url";
|
|
342
|
-
import { dirname as dirname2, join as
|
|
530
|
+
import { dirname as dirname2, join as join3, resolve as resolve2 } from "path";
|
|
343
531
|
var here = dirname2(fileURLToPath(import.meta.url));
|
|
344
532
|
function findStarterTemplate() {
|
|
345
533
|
let dir = here;
|
|
346
534
|
for (; ; ) {
|
|
347
|
-
const candidate =
|
|
348
|
-
if (
|
|
349
|
-
const bundled =
|
|
350
|
-
if (
|
|
535
|
+
const candidate = join3(dir, "templates", "starter");
|
|
536
|
+
if (existsSync3(candidate)) return candidate;
|
|
537
|
+
const bundled = join3(dir, "template");
|
|
538
|
+
if (existsSync3(bundled)) return bundled;
|
|
351
539
|
const parent = dirname2(dir);
|
|
352
540
|
if (parent === dir) return void 0;
|
|
353
541
|
dir = parent;
|
|
354
542
|
}
|
|
355
543
|
}
|
|
356
544
|
function isUsableTemplate(dir) {
|
|
357
|
-
if (!
|
|
545
|
+
if (!existsSync3(dir)) return false;
|
|
358
546
|
const entries = readdirSync(dir).filter((name) => name !== "README.md" && !name.startsWith("."));
|
|
359
547
|
return entries.length > 0;
|
|
360
548
|
}
|
|
361
549
|
function isEmptyDir(dir) {
|
|
362
|
-
if (!
|
|
550
|
+
if (!existsSync3(dir)) return true;
|
|
363
551
|
return readdirSync(dir).filter((n) => !n.startsWith(".")).length === 0;
|
|
364
552
|
}
|
|
365
553
|
function scaffold(options) {
|
|
@@ -374,7 +562,7 @@ function scaffold(options) {
|
|
|
374
562
|
writeSkeleton(root, options.config);
|
|
375
563
|
source = "skeleton";
|
|
376
564
|
}
|
|
377
|
-
|
|
565
|
+
writeFileSync2(join3(root, "superlore.json"), serializeSuperloreJson(options.config), "utf8");
|
|
378
566
|
return { root, source };
|
|
379
567
|
}
|
|
380
568
|
function writeSkeleton(root, config) {
|
|
@@ -382,9 +570,9 @@ function writeSkeleton(root, config) {
|
|
|
382
570
|
const mcpEnabled = config.mcp?.enabled ?? true;
|
|
383
571
|
const slug = config.name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "superlore-kb";
|
|
384
572
|
const write = (rel, body) => {
|
|
385
|
-
const file =
|
|
573
|
+
const file = join3(root, rel);
|
|
386
574
|
mkdirSync(dirname2(file), { recursive: true });
|
|
387
|
-
|
|
575
|
+
writeFileSync2(file, body, "utf8");
|
|
388
576
|
};
|
|
389
577
|
write(
|
|
390
578
|
"package.json",
|
|
@@ -792,7 +980,7 @@ ${result.issues.map((i) => ` - ${i.path} ${i.message}`).join("\n")}`
|
|
|
792
980
|
const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
|
|
793
981
|
const targetName = dir ?? (slug || "superlore-kb");
|
|
794
982
|
const targetDir = resolve3(process.cwd(), targetName);
|
|
795
|
-
if (
|
|
983
|
+
if (existsSync4(targetDir) && !isEmptyDir(targetDir)) {
|
|
796
984
|
if (interactive) {
|
|
797
985
|
const proceed = await confirm({
|
|
798
986
|
message: `${cyan(targetDir)} is not empty. Scaffold into it anyway?`,
|
|
@@ -812,6 +1000,33 @@ ${result.issues.map((i) => ` - ${i.path} ${i.message}`).join("\n")}`
|
|
|
812
1000
|
);
|
|
813
1001
|
}
|
|
814
1002
|
printNextSteps(root, config);
|
|
1003
|
+
await maybeConnectEditor(flags, interactive);
|
|
1004
|
+
}
|
|
1005
|
+
async function maybeConnectEditor(flags, interactive) {
|
|
1006
|
+
if (flags.connect === false) return;
|
|
1007
|
+
const editors = detectEditors();
|
|
1008
|
+
if (editors.length === 0) {
|
|
1009
|
+
log.blank();
|
|
1010
|
+
log.info(`${dim("Editor preview:")} install VS Code, Cursor, or Windsurf, then ${cyan("superlore connect")}.`);
|
|
1011
|
+
return;
|
|
1012
|
+
}
|
|
1013
|
+
const names = editors.map((e) => e.label).join(", ");
|
|
1014
|
+
if (flags.connect !== true && !interactive) {
|
|
1015
|
+
log.blank();
|
|
1016
|
+
log.info(`${dim(`Detected ${names}.`)} Run ${cyan("superlore connect")} to install the live-preview extension.`);
|
|
1017
|
+
return;
|
|
1018
|
+
}
|
|
1019
|
+
if (flags.connect !== true) {
|
|
1020
|
+
const proceed = await confirm({
|
|
1021
|
+
message: `Install the superlore Preview extension into ${names}?`,
|
|
1022
|
+
initialValue: true
|
|
1023
|
+
});
|
|
1024
|
+
if (isCancel(proceed) || !proceed) {
|
|
1025
|
+
log.info(`${dim("Skipped \u2014 run")} ${cyan("superlore connect")} ${dim("any time.")}`);
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
1028
|
+
}
|
|
1029
|
+
await connectCommand({ optional: true });
|
|
815
1030
|
}
|
|
816
1031
|
function printNextSteps(root, config) {
|
|
817
1032
|
const rel = basename(root);
|
|
@@ -829,14 +1044,17 @@ function printNextSteps(root, config) {
|
|
|
829
1044
|
}
|
|
830
1045
|
|
|
831
1046
|
// src/index.ts
|
|
832
|
-
var VERSION = "0.
|
|
833
|
-
function buildCli(argv =
|
|
1047
|
+
var VERSION = "0.2.0";
|
|
1048
|
+
function buildCli(argv = process3.argv) {
|
|
834
1049
|
const cli = cac("superlore");
|
|
835
|
-
cli.command("init [dir]", "Scaffold a new superlore knowledge base").option("--name <name>", "KB name").option("--type <type>", "KB type: company-kb | product-docs").option("--auth", "Enable the Google SSO auth gate").option("--no-auth", "Disable the auth gate").option("--allowed-domain <domain>", "Restrict SSO to one email domain (implies --auth)").option("--accent <color>", "Brand accent colour (any CSS colour)").option("--no-mcp", "Disable the MCP endpoint (on by default)").option("-y, --yes", "Skip prompts; use flags + defaults").example("superlore init my-kb --type product-docs").example("superlore init acme --type company-kb --auth --allowed-domain acme.com").action(
|
|
1050
|
+
cli.command("init [dir]", "Scaffold a new superlore knowledge base").option("--name <name>", "KB name").option("--type <type>", "KB type: company-kb | product-docs").option("--auth", "Enable the Google SSO auth gate").option("--no-auth", "Disable the auth gate").option("--allowed-domain <domain>", "Restrict SSO to one email domain (implies --auth)").option("--accent <color>", "Brand accent colour (any CSS colour)").option("--no-mcp", "Disable the MCP endpoint (on by default)").option("--connect", "Install the editor extension after scaffolding (skip the prompt)").option("--no-connect", "Don't set up the editor extension").option("-y, --yes", "Skip prompts; use flags + defaults").example("superlore init my-kb --type product-docs").example("superlore init acme --type company-kb --auth --allowed-domain acme.com").action(
|
|
836
1051
|
async (dir, flags) => {
|
|
837
1052
|
const authExplicit = argv.includes("--auth");
|
|
838
1053
|
const noAuthExplicit = argv.includes("--no-auth");
|
|
839
1054
|
const auth = authExplicit ? true : noAuthExplicit ? false : void 0;
|
|
1055
|
+
const connectExplicit = argv.includes("--connect");
|
|
1056
|
+
const noConnectExplicit = argv.includes("--no-connect");
|
|
1057
|
+
const connect = connectExplicit ? true : noConnectExplicit ? false : void 0;
|
|
840
1058
|
await initCommand(dir, {
|
|
841
1059
|
name: flags.name,
|
|
842
1060
|
type: flags.type,
|
|
@@ -845,6 +1063,7 @@ function buildCli(argv = process2.argv) {
|
|
|
845
1063
|
accent: flags.accent,
|
|
846
1064
|
// `--no-mcp` flips this to false; default true is the intended behaviour.
|
|
847
1065
|
mcp: flags.mcp,
|
|
1066
|
+
connect,
|
|
848
1067
|
yes: flags.yes
|
|
849
1068
|
});
|
|
850
1069
|
}
|
|
@@ -855,6 +1074,9 @@ function buildCli(argv = process2.argv) {
|
|
|
855
1074
|
cli.command("build", "Production build of the KB").action(async () => {
|
|
856
1075
|
await buildCommand();
|
|
857
1076
|
});
|
|
1077
|
+
cli.command("connect", "Install the superlore editor extension (VS Code \xB7 Cursor \xB7 Windsurf)").option("--vsix <path>", "Install from a local .vsix instead of the Marketplace").example("superlore connect").action(async (flags) => {
|
|
1078
|
+
await connectCommand({ vsix: flags.vsix });
|
|
1079
|
+
});
|
|
858
1080
|
cli.command("deploy", "Managed deploy (superlore Cloud) \u2014 private beta, joins the waitlist").option("--open", "Open the waitlist URL in your browser").action(async (flags) => {
|
|
859
1081
|
await deployCommand({ open: flags.open });
|
|
860
1082
|
});
|
|
@@ -862,7 +1084,7 @@ function buildCli(argv = process2.argv) {
|
|
|
862
1084
|
cli.version(VERSION);
|
|
863
1085
|
return cli;
|
|
864
1086
|
}
|
|
865
|
-
async function run(argv =
|
|
1087
|
+
async function run(argv = process3.argv) {
|
|
866
1088
|
const cli = buildCli(argv);
|
|
867
1089
|
const tokens = argv.slice(2);
|
|
868
1090
|
const hasCommand = tokens.some((t) => !t.startsWith("-"));
|
|
@@ -878,10 +1100,10 @@ async function run(argv = process2.argv) {
|
|
|
878
1100
|
} catch (error) {
|
|
879
1101
|
const message = error instanceof Error ? error.message : String(error);
|
|
880
1102
|
log.error(message);
|
|
881
|
-
|
|
1103
|
+
process3.exit(1);
|
|
882
1104
|
}
|
|
883
1105
|
}
|
|
884
|
-
var isEntrypoint = Boolean(
|
|
1106
|
+
var isEntrypoint = Boolean(process3.argv[1]) && fileURLToPath2(import.meta.url) === process3.argv[1];
|
|
885
1107
|
if (isEntrypoint) {
|
|
886
1108
|
void run();
|
|
887
1109
|
}
|
package/package.json
CHANGED