@lunora/cli 1.0.0-alpha.74 → 1.0.0-alpha.76
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/dist/bin.mjs +1 -1
- package/dist/index.d.mts +6 -4
- package/dist/index.d.ts +6 -4
- package/dist/index.mjs +2 -2
- package/dist/packem_chunks/handler.mjs +2 -2
- package/dist/packem_chunks/handler17.mjs +1 -1
- package/dist/packem_chunks/runInitCommand.mjs +65 -17
- package/dist/packem_shared/{COMMANDS-0BD3K1pb.mjs → COMMANDS-DW8lQmuW.mjs} +7 -3
- package/dist/packem_shared/{commands-CF2YHeFa.mjs → commands-ClEvcz3V.mjs} +2 -2
- package/dist/packem_shared/{runAddCommand-BGvSitq5.mjs → runAddCommand-DGjFXGqa.mjs} +1 -1
- package/dist/packem_shared/{storage-HRI1N4Ao.mjs → storage-DEXpJkXh.mjs} +1 -1
- package/package.json +1 -1
package/dist/bin.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -736,7 +736,7 @@ interface AddCommandResult {
|
|
|
736
736
|
* sub-prompt or alias; every other value IS the registry item name applied
|
|
737
737
|
* directly (`storage` → the `storage` registry item, etc.).
|
|
738
738
|
*/
|
|
739
|
-
type StackFeature = "auth" | "backup" | "crons" | "email" | "presence" | "
|
|
739
|
+
type StackFeature = "ai" | "auth" | "backup" | "browser" | "cloudflare-access" | "crons" | "email" | "flags" | "hyperdrive" | "payment" | "presence" | "queue" | "storage" | "workflow";
|
|
740
740
|
/** Customize a resolved manifest before it is written (e.g. inject the chosen R2 bucket name). */
|
|
741
741
|
type OfferTransformManifest = (manifest: RegistryManifest) => RegistryManifest;
|
|
742
742
|
/**
|
|
@@ -792,7 +792,9 @@ interface OfferDeps {
|
|
|
792
792
|
}) => Promise<string>;
|
|
793
793
|
}
|
|
794
794
|
/**
|
|
795
|
-
* Offer the stack features (
|
|
795
|
+
* Offer the stack features (ai, auth, backup, browser, cloudflare-access,
|
|
796
|
+
* crons, email, flags, hyperdrive, payment, presence, queue, storage,
|
|
797
|
+
* workflow) in ONE multi-select after a successful scaffold. Auth,
|
|
796
798
|
* presence, backups) in ONE multi-select after a successful scaffold. Auth,
|
|
797
799
|
* email, and storage run a follow-up prompt (provider / destination / bucket
|
|
798
800
|
* name); every other feature value is applied as its registry item directly.
|
|
@@ -806,8 +808,8 @@ type Template = "analog" | "astro" | "next" | "nuxt" | "react-router" | "standal
|
|
|
806
808
|
interface InitCommandOptions {
|
|
807
809
|
/**
|
|
808
810
|
* Add features non-interactively after scaffolding (the `--add` flag): a
|
|
809
|
-
* comma-separated list of `auth |
|
|
810
|
-
*
|
|
811
|
+
* comma-separated list of `ai | auth | backup | browser | cloudflare-access | crons | email | flags | hyperdrive | payment | presence | queue | storage | workflow`.
|
|
812
|
+
* Bypasses the interactive multi-select and sub-prompts —
|
|
811
813
|
* each named feature is applied with its shipped defaults.
|
|
812
814
|
*/
|
|
813
815
|
add?: string;
|
package/dist/index.d.ts
CHANGED
|
@@ -736,7 +736,7 @@ interface AddCommandResult {
|
|
|
736
736
|
* sub-prompt or alias; every other value IS the registry item name applied
|
|
737
737
|
* directly (`storage` → the `storage` registry item, etc.).
|
|
738
738
|
*/
|
|
739
|
-
type StackFeature = "auth" | "backup" | "crons" | "email" | "presence" | "
|
|
739
|
+
type StackFeature = "ai" | "auth" | "backup" | "browser" | "cloudflare-access" | "crons" | "email" | "flags" | "hyperdrive" | "payment" | "presence" | "queue" | "storage" | "workflow";
|
|
740
740
|
/** Customize a resolved manifest before it is written (e.g. inject the chosen R2 bucket name). */
|
|
741
741
|
type OfferTransformManifest = (manifest: RegistryManifest) => RegistryManifest;
|
|
742
742
|
/**
|
|
@@ -792,7 +792,9 @@ interface OfferDeps {
|
|
|
792
792
|
}) => Promise<string>;
|
|
793
793
|
}
|
|
794
794
|
/**
|
|
795
|
-
* Offer the stack features (
|
|
795
|
+
* Offer the stack features (ai, auth, backup, browser, cloudflare-access,
|
|
796
|
+
* crons, email, flags, hyperdrive, payment, presence, queue, storage,
|
|
797
|
+
* workflow) in ONE multi-select after a successful scaffold. Auth,
|
|
796
798
|
* presence, backups) in ONE multi-select after a successful scaffold. Auth,
|
|
797
799
|
* email, and storage run a follow-up prompt (provider / destination / bucket
|
|
798
800
|
* name); every other feature value is applied as its registry item directly.
|
|
@@ -806,8 +808,8 @@ type Template = "analog" | "astro" | "next" | "nuxt" | "react-router" | "standal
|
|
|
806
808
|
interface InitCommandOptions {
|
|
807
809
|
/**
|
|
808
810
|
* Add features non-interactively after scaffolding (the `--add` flag): a
|
|
809
|
-
* comma-separated list of `auth |
|
|
810
|
-
*
|
|
811
|
+
* comma-separated list of `ai | auth | backup | browser | cloudflare-access | crons | email | flags | hyperdrive | payment | presence | queue | storage | workflow`.
|
|
812
|
+
* Bypasses the interactive multi-select and sub-prompts —
|
|
811
813
|
* each named feature is applied with its shipped defaults.
|
|
812
814
|
*/
|
|
813
815
|
add?: string;
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { COMMANDS, VERSION, runCli } from './packem_shared/COMMANDS-
|
|
1
|
+
export { COMMANDS, VERSION, runCli } from './packem_shared/COMMANDS-DW8lQmuW.mjs';
|
|
2
2
|
export { runCodegenCommand } from './packem_chunks/runCodegenCommand.mjs';
|
|
3
3
|
export { DEFAULT_IMPORT_BATCH_SIZE, runExportCommand, runImportCommand } from './packem_shared/DEFAULT_IMPORT_BATCH_SIZE-CRQmmBZM.mjs';
|
|
4
4
|
export { runDeployCommand } from './packem_chunks/runDeployCommand.mjs';
|
|
@@ -16,4 +16,4 @@ export { createRecordingSpawner, defaultSpawner } from './packem_shared/createRe
|
|
|
16
16
|
export { default as parseManifest } from './packem_shared/parseManifest-Dbp-Q2q3.mjs';
|
|
17
17
|
export { REQUIRED_COMPATIBILITY_DATE, REQUIRED_FLAG, validateWranglerProject as validateWrangler, validateWranglerConfig } from '@lunora/config';
|
|
18
18
|
export { buildRegistryIndex } from './packem_shared/buildRegistryIndex-BS5ig822.mjs';
|
|
19
|
-
export { r as runAddCommand, a as runBuildIndexCommand, b as runRegistryViewCommand } from './packem_shared/commands-
|
|
19
|
+
export { r as runAddCommand, a as runBuildIndexCommand, b as runRegistryViewCommand } from './packem_shared/commands-ClEvcz3V.mjs';
|
|
@@ -4,8 +4,8 @@ import { join, basename } from '@visulima/path';
|
|
|
4
4
|
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
5
5
|
import { v as validateOutputFormat, i as isJsonFormat, p as printJson, l as loggerForFormat } from '../packem_shared/output-format-B4642rjE.mjs';
|
|
6
6
|
import { t as tuiText, a as tuiSelect } from '../packem_shared/tui-prompts-BjEN8XgP.mjs';
|
|
7
|
-
import { n as normalizeFeature, E as EMAIL_ITEM, s as sanitizeBucketName, d as deriveBucketName, p as promptBucketName, r as resolveTypedDestination, M as MAIL_DESTINATION_PROMPT, a as sanitizeDatabaseName, b as deriveDatabaseName, c as promptDatabaseName, D as DEFAULT_AUTH_ITEM, e as promptAuthProvider, A as AUTH_PROVIDER_OPTIONS, w as withStorageBucketName, f as withMailDestination, g as withAuthDatabaseName } from '../packem_shared/storage-
|
|
8
|
-
import { r as runAddCommand } from '../packem_shared/commands-
|
|
7
|
+
import { n as normalizeFeature, E as EMAIL_ITEM, s as sanitizeBucketName, d as deriveBucketName, p as promptBucketName, r as resolveTypedDestination, M as MAIL_DESTINATION_PROMPT, a as sanitizeDatabaseName, b as deriveDatabaseName, c as promptDatabaseName, D as DEFAULT_AUTH_ITEM, e as promptAuthProvider, A as AUTH_PROVIDER_OPTIONS, w as withStorageBucketName, f as withMailDestination, g as withAuthDatabaseName } from '../packem_shared/storage-DEXpJkXh.mjs';
|
|
8
|
+
import { r as runAddCommand } from '../packem_shared/commands-ClEvcz3V.mjs';
|
|
9
9
|
|
|
10
10
|
const providerToItem = (provider) => {
|
|
11
11
|
const value = provider.trim().toLowerCase();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { d as defineHandler } from '../packem_shared/command-lYnl4QyF.mjs';
|
|
2
|
-
import { r as runAddCommand, b as runRegistryViewCommand, a as runBuildIndexCommand } from '../packem_shared/commands-
|
|
2
|
+
import { r as runAddCommand, b as runRegistryViewCommand, a as runBuildIndexCommand } from '../packem_shared/commands-ClEvcz3V.mjs';
|
|
3
3
|
|
|
4
4
|
const execute = defineHandler(({ argument, cwd, logger, options }) => {
|
|
5
5
|
const subcommand = argument[0];
|
|
@@ -11,11 +11,11 @@ import { d as detectPackageManager, a as detectInstalledManagers, i as installAr
|
|
|
11
11
|
import MagicString from 'magic-string';
|
|
12
12
|
import { Project, SyntaxKind } from 'ts-morph';
|
|
13
13
|
import { P as PromptCancelledError } from '../packem_shared/prompt-cancelled-APzX1Im-.mjs';
|
|
14
|
-
import { c as resolveTagVersions, d as resolveSourceRef, e as resolvePinnedSourceRef, f as resolveDistTag, r as runAddCommand } from '../packem_shared/commands-
|
|
14
|
+
import { c as resolveTagVersions, d as resolveSourceRef, e as resolvePinnedSourceRef, f as resolveDistTag, r as runAddCommand } from '../packem_shared/commands-ClEvcz3V.mjs';
|
|
15
15
|
import { defaultSpawner } from '../packem_shared/createRecordingSpawner-Cw5Iu73G.mjs';
|
|
16
16
|
import { d as tuiMascot, e as tuiStep, f as tuiMoonrise, t as tuiText, g as tuiHeadline, h as tuiInfo, a as tuiSelect, b as tuiConfirm, w as withTuiSpinner, i as tuiNextSteps, j as tuiTasks, k as tuiMultiSelect, l as withTuiBadgeProgress } from '../packem_shared/tui-prompts-BjEN8XgP.mjs';
|
|
17
17
|
import { logStep } from '../packem_shared/createLogger-CIWSHrTL.mjs';
|
|
18
|
-
import { E as EMAIL_ITEM, p as promptBucketName, w as withStorageBucketName, M as MAIL_DESTINATION_PROMPT, r as resolveTypedDestination, f as withMailDestination, e as promptAuthProvider, c as promptDatabaseName, g as withAuthDatabaseName } from '../packem_shared/storage-
|
|
18
|
+
import { E as EMAIL_ITEM, p as promptBucketName, w as withStorageBucketName, M as MAIL_DESTINATION_PROMPT, r as resolveTypedDestination, f as withMailDestination, e as promptAuthProvider, c as promptDatabaseName, g as withAuthDatabaseName } from '../packem_shared/storage-DEXpJkXh.mjs';
|
|
19
19
|
import dns from 'node:dns/promises';
|
|
20
20
|
|
|
21
21
|
const GITHUB_CONTENT = `name: Deploy
|
|
@@ -343,13 +343,20 @@ ${LUNA_NAME}: ${LUNA_SIGNOFF}`);
|
|
|
343
343
|
};
|
|
344
344
|
|
|
345
345
|
const STACK_FEATURE_OPTIONS = [
|
|
346
|
+
{ description: "LLMs via Workers AI (summarize, generate, stream)", label: "AI", value: "ai" },
|
|
346
347
|
{ description: "Sign-up / sign-in (asks which provider)", label: "Authentication", value: "auth" },
|
|
347
|
-
{ description: "
|
|
348
|
-
{ description: "
|
|
349
|
-
{ description: "
|
|
348
|
+
{ description: "Snapshot + restore your Durable Object data", label: "Backups", value: "backup" },
|
|
349
|
+
{ description: "Headless browser screenshots + PDFs", label: "Browser rendering", value: "browser" },
|
|
350
|
+
{ description: "Zero Trust identity via Cloudflare Access", label: "Cloudflare Access", value: "cloudflare-access" },
|
|
350
351
|
{ description: "Scheduled jobs via Cron Triggers (@lunora/scheduler)", label: "Cron jobs", value: "crons" },
|
|
352
|
+
{ description: "Cloudflare Email Workers + a dev mail catcher", label: "Transactional email", value: "email" },
|
|
353
|
+
{ description: "OpenFeature feature flags (ctx.flags)", label: "Feature flags", value: "flags" },
|
|
354
|
+
{ description: "External Postgres/MySQL via Hyperdrive", label: "Hyperdrive", value: "hyperdrive" },
|
|
355
|
+
{ description: "Stripe-first payments (checkout, subscription, webhooks)", label: "Payments", value: "payment" },
|
|
351
356
|
{ description: "Live presence / who's-online over hibernated WebSockets", label: "Presence", value: "presence" },
|
|
352
|
-
{ description: "
|
|
357
|
+
{ description: "Async message queues (push/pull consumers)", label: "Queues", value: "queue" },
|
|
358
|
+
{ description: "Typed R2 buckets + signed URLs (@lunora/storage)", label: "File storage", value: "storage" },
|
|
359
|
+
{ description: "Durable long-running workflows (step.do, sleep, branch)", label: "Workflows", value: "workflow" }
|
|
353
360
|
];
|
|
354
361
|
const STACK_FEATURE_VALUES = STACK_FEATURE_OPTIONS.map((option) => option.value);
|
|
355
362
|
const featureItem = (feature) => feature === "email" ? EMAIL_ITEM : feature;
|
|
@@ -401,7 +408,10 @@ const offerRegistryExtras = async (deps) => {
|
|
|
401
408
|
return;
|
|
402
409
|
}
|
|
403
410
|
if (!deps.interactive) {
|
|
404
|
-
deps.logger.info(
|
|
411
|
+
deps.logger.info(
|
|
412
|
+
// eslint-disable-next-line no-secrets/no-secrets -- the pipe-separated feature list in this tip is a UI prompt, not a credential
|
|
413
|
+
"tip: add features later with `lunora add <ai|auth|backup|browser|cloudflare-access|crons|email|flags|hyperdrive|payment|presence|queue|storage|workflow>`."
|
|
414
|
+
);
|
|
405
415
|
return;
|
|
406
416
|
}
|
|
407
417
|
const picked = await deps.multiSelect("Which features do you want to add?", STACK_FEATURE_OPTIONS, { defaults: [] });
|
|
@@ -1470,7 +1480,49 @@ const ADAPTERS = {
|
|
|
1470
1480
|
};
|
|
1471
1481
|
const isOverlayFramework = (value) => Object.hasOwn(ADAPTERS, value);
|
|
1472
1482
|
|
|
1473
|
-
const
|
|
1483
|
+
const RATELIMIT_SCHEMA = `import type { Middleware } from "lunorash/server";
|
|
1484
|
+
import { defineSchemaExtension, defineTable, definePlugin, v } from "lunorash/server";
|
|
1485
|
+
import { createDbStore, RateLimiter } from "lunorash/ratelimit";
|
|
1486
|
+
import type { RateLimitConfigMap } from "lunorash/ratelimit";
|
|
1487
|
+
|
|
1488
|
+
export const limits = {
|
|
1489
|
+
default: { kind: "token bucket", period: 60_000, rate: 10 },
|
|
1490
|
+
} as const satisfies RateLimitConfigMap;
|
|
1491
|
+
|
|
1492
|
+
export type LimitName = keyof typeof limits;
|
|
1493
|
+
|
|
1494
|
+
export const makeRateLimiter = (ctx: { db: unknown }): RateLimiter<LimitName> =>
|
|
1495
|
+
new RateLimiter<LimitName>({
|
|
1496
|
+
config: limits,
|
|
1497
|
+
store: createDbStore({ db: ctx.db as never, table: "ratelimit_buckets" }),
|
|
1498
|
+
});
|
|
1499
|
+
|
|
1500
|
+
const middleware: Middleware<{ api?: Record<string, unknown>; db: unknown }, { api: Record<string, unknown>; db: unknown }> = ({ ctx, next }) =>
|
|
1501
|
+
next({
|
|
1502
|
+
ctx: {
|
|
1503
|
+
...ctx,
|
|
1504
|
+
api: { ...ctx.api, ratelimit: makeRateLimiter(ctx) },
|
|
1505
|
+
},
|
|
1506
|
+
});
|
|
1507
|
+
|
|
1508
|
+
export const ratelimit = definePlugin("ratelimit", {
|
|
1509
|
+
extension: defineSchemaExtension("ratelimit", {
|
|
1510
|
+
tables: {
|
|
1511
|
+
buckets: defineTable({
|
|
1512
|
+
key: v.string(),
|
|
1513
|
+
value: v.number(),
|
|
1514
|
+
ts: v.number(),
|
|
1515
|
+
prev: v.optional(v.number()),
|
|
1516
|
+
})
|
|
1517
|
+
.index("by_key", ["key"])
|
|
1518
|
+
.externallyManaged(),
|
|
1519
|
+
},
|
|
1520
|
+
}),
|
|
1521
|
+
middleware,
|
|
1522
|
+
});
|
|
1523
|
+
`;
|
|
1524
|
+
const LUNORA_SCHEMA = `import { ratelimit } from "./ratelimit/schema.js";
|
|
1525
|
+
import { defineSchema, defineTable, v } from "lunorash/server";
|
|
1474
1526
|
|
|
1475
1527
|
export default defineSchema({
|
|
1476
1528
|
messages: defineTable({
|
|
@@ -1479,22 +1531,17 @@ export default defineSchema({
|
|
|
1479
1531
|
})
|
|
1480
1532
|
.shardBy("channelId")
|
|
1481
1533
|
.index("by_channel", ["channelId"]),
|
|
1482
|
-
});
|
|
1534
|
+
}).extend(ratelimit.extension);
|
|
1483
1535
|
`;
|
|
1484
|
-
const LUNORA_MESSAGES = `import { RateLimiter, rateLimit } from "
|
|
1536
|
+
const LUNORA_MESSAGES = `import { RateLimiter, rateLimit, createDbStore } from "lunorash/ratelimit";
|
|
1485
1537
|
|
|
1486
1538
|
import { mutation, query, v } from "#lunora/_generated/server.js";
|
|
1487
1539
|
|
|
1488
|
-
|
|
1489
|
-
* One in-memory limiter so the public \`send\` mutation isn't an open flood target
|
|
1490
|
-
* out of the box. The default store is in-memory (per-isolate, resets on
|
|
1491
|
-
* eviction) — fine for a starter; run \`lunora add ratelimit\` for the durable,
|
|
1492
|
-
* \`ctx.db\`-backed store when you ship to production.
|
|
1493
|
-
*/
|
|
1494
|
-
const limiter = new RateLimiter({
|
|
1540
|
+
const limiter = (ctx: { db: unknown }) => new RateLimiter({
|
|
1495
1541
|
config: {
|
|
1496
1542
|
send: { kind: "token bucket", period: 60_000, rate: 30 },
|
|
1497
1543
|
},
|
|
1544
|
+
store: createDbStore({ db: ctx.db as never, table: "ratelimit_buckets" }),
|
|
1498
1545
|
});
|
|
1499
1546
|
|
|
1500
1547
|
export const list = query.input({ channelId: v.string().meta({ schema: { maxLength: 256 } }), limit: v.optional(v.number()) }).query(async ({ args, ctx }) => {
|
|
@@ -1620,6 +1667,7 @@ const patchBaseViteConfig = (target, logger) => {
|
|
|
1620
1667
|
const applyLunoraOverlay = async (options) => {
|
|
1621
1668
|
const { adapter, distTag, logger, name, target } = options;
|
|
1622
1669
|
const written = [];
|
|
1670
|
+
writeFile(target, join$1("lunora", "ratelimit", "schema.ts"), RATELIMIT_SCHEMA, written);
|
|
1623
1671
|
writeFile(target, join$1("lunora", "schema.ts"), LUNORA_SCHEMA, written);
|
|
1624
1672
|
writeFile(target, join$1("lunora", "messages.ts"), LUNORA_MESSAGES, written);
|
|
1625
1673
|
writeFile(target, join$1("src", "server.ts"), SERVER_ENTRY, written);
|
|
@@ -10,8 +10,12 @@ import { tmpdir } from 'node:os';
|
|
|
10
10
|
import { join } from 'node:path';
|
|
11
11
|
|
|
12
12
|
const addCommand = {
|
|
13
|
-
argument: {
|
|
14
|
-
|
|
13
|
+
argument: {
|
|
14
|
+
description: "Feature or registry item: ai | auth | email | storage | crons | presence | queue | workflow | flags | backup | …",
|
|
15
|
+
name: "feature",
|
|
16
|
+
type: String
|
|
17
|
+
},
|
|
18
|
+
description: "Add a feature or registry item (ai, auth, email, storage, crons, …) to the current Lunora project",
|
|
15
19
|
examples: [
|
|
16
20
|
["lunora add auth", "Add authentication (asks which provider)"],
|
|
17
21
|
["lunora add auth --provider clerk", "Add Clerk auth without prompting"],
|
|
@@ -446,7 +450,7 @@ const initCommand = {
|
|
|
446
450
|
type: String
|
|
447
451
|
},
|
|
448
452
|
{
|
|
449
|
-
description: "Add features non-interactively after scaffolding (comma-separated): auth |
|
|
453
|
+
description: "Add features non-interactively after scaffolding (comma-separated): ai | auth | backup | browser | cloudflare-access | crons | email | flags | hyperdrive | payment | presence | queue | storage | workflow",
|
|
450
454
|
name: "add",
|
|
451
455
|
type: String
|
|
452
456
|
},
|
|
@@ -148,8 +148,8 @@ const resolveDepRange = (range) => {
|
|
|
148
148
|
}
|
|
149
149
|
return rest;
|
|
150
150
|
};
|
|
151
|
-
const UMBRELLA_REEXPORTED_DEPS = /* @__PURE__ */ new Set(["@lunora/client", "@lunora/do", "@lunora/runtime", "@lunora/server", "@lunora/values"]);
|
|
152
|
-
const UMBRELLA_IMPORT_RE = /(['"])@lunora\/(client|do|runtime|server|values)(\/[^'"]*)?\1/gu;
|
|
151
|
+
const UMBRELLA_REEXPORTED_DEPS = /* @__PURE__ */ new Set(["@lunora/client", "@lunora/do", "@lunora/ratelimit", "@lunora/runtime", "@lunora/server", "@lunora/values"]);
|
|
152
|
+
const UMBRELLA_IMPORT_RE = /(['"])@lunora\/(client|do|ratelimit|runtime|server|values)(\/[^'"]*)?\1/gu;
|
|
153
153
|
const projectUsesUmbrella = (projectRoot) => {
|
|
154
154
|
const packageJsonPath = join(projectRoot, "package.json");
|
|
155
155
|
if (!existsSync(packageJsonPath)) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import 'node:fs';
|
|
2
2
|
import '@visulima/path';
|
|
3
|
-
export { r as runAddCommand, a as runBuildIndexCommand, g as runListCommand, b as runRegistryViewCommand } from './commands-
|
|
3
|
+
export { r as runAddCommand, a as runBuildIndexCommand, g as runListCommand, b as runRegistryViewCommand } from './commands-ClEvcz3V.mjs';
|
|
4
4
|
import './buildRegistryIndex-BS5ig822.mjs';
|