@remixhq/cli 0.1.11 → 0.1.13
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/cli.js +195 -16
- package/dist/cli.js.map +1 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -1923,6 +1923,9 @@ function buildKeyName(params) {
|
|
|
1923
1923
|
const ts = Math.floor(Date.now() / 1e3);
|
|
1924
1924
|
return `cli_${user}_${hostname}_${ts}`;
|
|
1925
1925
|
}
|
|
1926
|
+
function buildDashboardAppUrl(appId) {
|
|
1927
|
+
return `https://dashboard.remix.one/apps/${encodeURIComponent(appId)}`;
|
|
1928
|
+
}
|
|
1926
1929
|
async function initLocal(params) {
|
|
1927
1930
|
await ensureAuth({ yes: params.yes, json: params.json });
|
|
1928
1931
|
const cfg = await resolveConfig({ yes: params.yes });
|
|
@@ -1992,6 +1995,7 @@ async function initLocal(params) {
|
|
|
1992
1995
|
});
|
|
1993
1996
|
return {
|
|
1994
1997
|
appId: imported.appId,
|
|
1998
|
+
dashboardUrl: buildDashboardAppUrl(imported.appId),
|
|
1995
1999
|
uploadId: imported.uploadId,
|
|
1996
2000
|
projectId: imported.projectId,
|
|
1997
2001
|
threadId: imported.threadId,
|
|
@@ -2018,6 +2022,7 @@ function registerInitCommands(program) {
|
|
|
2018
2022
|
return;
|
|
2019
2023
|
}
|
|
2020
2024
|
console.log(pc9.green(`Completed. appId=${res.appId}`));
|
|
2025
|
+
console.log(pc9.dim(`Dashboard: ${res.dashboardUrl}`));
|
|
2021
2026
|
if (res.status) console.log(pc9.dim(`Status: ${res.status}`));
|
|
2022
2027
|
});
|
|
2023
2028
|
}
|
|
@@ -2027,10 +2032,14 @@ import fs15 from "fs/promises";
|
|
|
2027
2032
|
import path13 from "path";
|
|
2028
2033
|
import pc10 from "picocolors";
|
|
2029
2034
|
import {
|
|
2035
|
+
collabListMembers as collabListMembersCore,
|
|
2036
|
+
collabUpdateMemberRole as collabUpdateMemberRoleCore,
|
|
2037
|
+
getMemberRolesForScope,
|
|
2030
2038
|
collabAdd as collabAddCore,
|
|
2031
2039
|
collabRecordTurn as collabRecordTurnCore,
|
|
2032
2040
|
collabApprove as collabApproveCore,
|
|
2033
|
-
|
|
2041
|
+
collabCheckout as collabCheckoutCore,
|
|
2042
|
+
collabListMergeRequests as collabListMergeRequestsCore,
|
|
2034
2043
|
collabInit as collabInitCore,
|
|
2035
2044
|
collabInvite as collabInviteCore,
|
|
2036
2045
|
collabList as collabListCore,
|
|
@@ -2065,6 +2074,13 @@ function printResultWarnings(json, value) {
|
|
|
2065
2074
|
console.log(pc10.yellow(warning));
|
|
2066
2075
|
}
|
|
2067
2076
|
}
|
|
2077
|
+
function printMergeRequests(result, json) {
|
|
2078
|
+
if (json) return;
|
|
2079
|
+
const items = Array.isArray(result.mergeRequests) ? result.mergeRequests : [];
|
|
2080
|
+
for (const mr of items) {
|
|
2081
|
+
console.log(`${mr.id} ${mr.status} ${mr.title ?? "(untitled)"}`);
|
|
2082
|
+
}
|
|
2083
|
+
}
|
|
2068
2084
|
async function createCollabApi(params) {
|
|
2069
2085
|
await ensureAuth({ yes: params.yes, json: params.json });
|
|
2070
2086
|
const cfg = await resolveConfig({ yes: params.yes });
|
|
@@ -2132,6 +2148,7 @@ async function collabInit(params) {
|
|
|
2132
2148
|
} else {
|
|
2133
2149
|
console.log(pc10.green(`Initialized repository in Remix. appId=${result.appId}`));
|
|
2134
2150
|
}
|
|
2151
|
+
console.log(pc10.dim(`Dashboard: ${result.dashboardUrl}`));
|
|
2135
2152
|
printResultWarnings(params.json, result);
|
|
2136
2153
|
}
|
|
2137
2154
|
return result;
|
|
@@ -2242,7 +2259,24 @@ async function collabRemix(params) {
|
|
|
2242
2259
|
appId: params.appId,
|
|
2243
2260
|
name: params.name
|
|
2244
2261
|
});
|
|
2245
|
-
if (!params.json)
|
|
2262
|
+
if (!params.json) {
|
|
2263
|
+
console.log(pc10.green(`Created remix. appId=${result.appId} path=${result.repoRoot}`));
|
|
2264
|
+
console.log(pc10.dim(`Dashboard: ${result.dashboardUrl}`));
|
|
2265
|
+
}
|
|
2266
|
+
return result;
|
|
2267
|
+
}
|
|
2268
|
+
async function collabCheckout(params) {
|
|
2269
|
+
const api = await createCollabApi(params);
|
|
2270
|
+
const result = await collabCheckoutCore({
|
|
2271
|
+
api,
|
|
2272
|
+
cwd: params.cwd,
|
|
2273
|
+
outputDir: params.outputDir ?? null,
|
|
2274
|
+
appId: params.appId
|
|
2275
|
+
});
|
|
2276
|
+
if (!params.json) {
|
|
2277
|
+
console.log(pc10.green(`Checked out app. appId=${result.appId} path=${result.repoRoot}`));
|
|
2278
|
+
console.log(pc10.dim(`Dashboard: ${result.dashboardUrl}`));
|
|
2279
|
+
}
|
|
2246
2280
|
return result;
|
|
2247
2281
|
}
|
|
2248
2282
|
async function collabAdd(params) {
|
|
@@ -2425,15 +2459,39 @@ async function collabRequestMerge(params) {
|
|
|
2425
2459
|
if (!params.json) console.log(pc10.green(`Opened merge request. id=${result.id}`));
|
|
2426
2460
|
return result;
|
|
2427
2461
|
}
|
|
2428
|
-
async function
|
|
2462
|
+
async function collabReviewQueue(params) {
|
|
2429
2463
|
const api = await createCollabApi(params);
|
|
2430
|
-
const result = await
|
|
2431
|
-
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2464
|
+
const result = await collabListMergeRequestsCore({
|
|
2465
|
+
api,
|
|
2466
|
+
queue: "reviewable",
|
|
2467
|
+
status: params.status ?? "open",
|
|
2468
|
+
kind: params.kind ?? "merge"
|
|
2469
|
+
});
|
|
2470
|
+
printMergeRequests(result, params.json);
|
|
2471
|
+
return result;
|
|
2472
|
+
}
|
|
2473
|
+
async function collabMyMergeRequests(params) {
|
|
2474
|
+
const api = await createCollabApi(params);
|
|
2475
|
+
const result = await collabListMergeRequestsCore({
|
|
2476
|
+
api,
|
|
2477
|
+
queue: "created_by_me",
|
|
2478
|
+
status: params.status ?? "open",
|
|
2479
|
+
kind: params.kind ?? "merge"
|
|
2480
|
+
});
|
|
2481
|
+
printMergeRequests(result, params.json);
|
|
2482
|
+
return result;
|
|
2483
|
+
}
|
|
2484
|
+
async function collabListAppMergeRequests(params) {
|
|
2485
|
+
const api = await createCollabApi(params);
|
|
2486
|
+
const result = await collabListMergeRequestsCore({
|
|
2487
|
+
api,
|
|
2488
|
+
cwd: params.cwd,
|
|
2489
|
+
appId: params.appId ?? null,
|
|
2490
|
+
queue: params.queue,
|
|
2491
|
+
status: params.status ?? "open",
|
|
2492
|
+
kind: params.kind ?? "merge"
|
|
2493
|
+
});
|
|
2494
|
+
printMergeRequests(result, params.json);
|
|
2437
2495
|
return result;
|
|
2438
2496
|
}
|
|
2439
2497
|
async function collabView(params) {
|
|
@@ -2563,6 +2621,50 @@ async function collabInviteRevoke(params) {
|
|
|
2563
2621
|
if (!params.json) console.log(pc10.green(`Revoked ${params.scope} invite. id=${params.inviteId}`));
|
|
2564
2622
|
return result;
|
|
2565
2623
|
}
|
|
2624
|
+
async function collabMembersList(params) {
|
|
2625
|
+
const api = await createCollabApi(params);
|
|
2626
|
+
const result = await collabListMembersCore({
|
|
2627
|
+
api,
|
|
2628
|
+
cwd: params.cwd,
|
|
2629
|
+
scope: params.scope,
|
|
2630
|
+
targetId: params.targetId ?? null
|
|
2631
|
+
});
|
|
2632
|
+
if (!params.json) {
|
|
2633
|
+
for (const member of result.members) {
|
|
2634
|
+
console.log(
|
|
2635
|
+
`${String(member.userId ?? "")} role=${String(member.role ?? "")} invitedBy=${String(member.invitedBy ?? "")}`
|
|
2636
|
+
);
|
|
2637
|
+
}
|
|
2638
|
+
}
|
|
2639
|
+
return result;
|
|
2640
|
+
}
|
|
2641
|
+
async function collabMembersUpdate(params) {
|
|
2642
|
+
const normalizedRole = params.role.trim().toLowerCase();
|
|
2643
|
+
if (!getMemberRolesForScope(params.scope).includes(normalizedRole)) {
|
|
2644
|
+
throw new CliError(`Invalid ${params.scope} member role.`, {
|
|
2645
|
+
exitCode: 2,
|
|
2646
|
+
hint: `Allowed roles: ${getMemberRolesForScope(params.scope).join(", ")}`
|
|
2647
|
+
});
|
|
2648
|
+
}
|
|
2649
|
+
const api = await createCollabApi(params);
|
|
2650
|
+
const result = await collabUpdateMemberRoleCore({
|
|
2651
|
+
api,
|
|
2652
|
+
cwd: params.cwd,
|
|
2653
|
+
scope: params.scope,
|
|
2654
|
+
targetId: params.targetId ?? null,
|
|
2655
|
+
userId: params.userId,
|
|
2656
|
+
role: normalizedRole
|
|
2657
|
+
});
|
|
2658
|
+
if (!params.json) {
|
|
2659
|
+
const member = result.member;
|
|
2660
|
+
console.log(
|
|
2661
|
+
pc10.green(
|
|
2662
|
+
`Updated ${result.scopeType} member. userId=${String(member.userId ?? params.userId)} role=${String(member.role ?? normalizedRole)}`
|
|
2663
|
+
)
|
|
2664
|
+
);
|
|
2665
|
+
}
|
|
2666
|
+
return result;
|
|
2667
|
+
}
|
|
2566
2668
|
|
|
2567
2669
|
// src/services/memory.ts
|
|
2568
2670
|
import pc11 from "picocolors";
|
|
@@ -2785,6 +2887,20 @@ function parseInviteScope(value) {
|
|
|
2785
2887
|
if (normalized === "app") return "app";
|
|
2786
2888
|
throw new Error("scope must be one of: organization, project, app");
|
|
2787
2889
|
}
|
|
2890
|
+
function parseMergeRequestKind(value) {
|
|
2891
|
+
const normalized = String(value).trim().toLowerCase();
|
|
2892
|
+
if (normalized === "merge" || normalized === "sync" || normalized === "all") {
|
|
2893
|
+
return normalized;
|
|
2894
|
+
}
|
|
2895
|
+
throw new Error("kind must be one of: merge, sync, all");
|
|
2896
|
+
}
|
|
2897
|
+
function parseAppMergeRequestQueue(value) {
|
|
2898
|
+
const normalized = String(value).trim().toLowerCase();
|
|
2899
|
+
if (normalized === "app_reviewable" || normalized === "app_outgoing" || normalized === "app_related_visible") {
|
|
2900
|
+
return normalized;
|
|
2901
|
+
}
|
|
2902
|
+
throw new Error("queue must be one of: app_reviewable, app_outgoing, app_related_visible");
|
|
2903
|
+
}
|
|
2788
2904
|
function registerCollabCommands(program) {
|
|
2789
2905
|
const collab = program.command("collab").description("Generic collaboration workflow for any software repository");
|
|
2790
2906
|
const memory = collab.command("memory").description("Inspect collaboration memory for the current bound repository or an explicit app");
|
|
@@ -2858,6 +2974,16 @@ function registerCollabCommands(program) {
|
|
|
2858
2974
|
});
|
|
2859
2975
|
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
2860
2976
|
});
|
|
2977
|
+
collab.command("checkout <appId>").description("Check out an existing Remix app as-is into a new local checkout").option("--output-dir <path>", "Exact destination path for the checked out app").option("--cwd <path>", "Parent directory where the checked out app will be created when --output-dir is not provided").option("--yes", "Run non-interactively", false).option("--non-interactive", "Run non-interactively", false).option("--json", "Output JSON", false).action(async (appId, opts) => {
|
|
2978
|
+
const result = await collabCheckout({
|
|
2979
|
+
cwd: opts.cwd ? String(opts.cwd) : process.cwd(),
|
|
2980
|
+
outputDir: opts.outputDir ? String(opts.outputDir) : null,
|
|
2981
|
+
appId: appId ? String(appId) : null,
|
|
2982
|
+
json: Boolean(opts.json),
|
|
2983
|
+
yes: Boolean(opts.yes || opts.nonInteractive)
|
|
2984
|
+
});
|
|
2985
|
+
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
2986
|
+
});
|
|
2861
2987
|
collab.command("remix <appId>").description("Create a remix/fork and materialize a new local checkout").option("--name <name>", "Optional name for the remix").option("--output-dir <path>", "Exact destination path for the new remix checkout").option("--cwd <path>", "Parent directory where the new remix checkout will be created when --output-dir is not provided").option("--yes", "Run non-interactively", false).option("--non-interactive", "Run non-interactively", false).option("--json", "Output JSON", false).action(async (appId, opts) => {
|
|
2862
2988
|
const result = await collabRemix({
|
|
2863
2989
|
cwd: opts.cwd ? String(opts.cwd) : process.cwd(),
|
|
@@ -2922,7 +3048,7 @@ function registerCollabCommands(program) {
|
|
|
2922
3048
|
});
|
|
2923
3049
|
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
2924
3050
|
});
|
|
2925
|
-
collab.command("sync-upstream").description("
|
|
3051
|
+
collab.command("sync-upstream").description("Create an upstream catch-up sync for the current remix, then update the local checkout").option("--cwd <path>", "Working directory for repository detection").option("--yes", "Run non-interactively", false).option("--non-interactive", "Run non-interactively", false).option("--json", "Output JSON", false).action(async (opts) => {
|
|
2926
3052
|
const result = await collabSyncUpstream({
|
|
2927
3053
|
cwd: opts.cwd ? String(opts.cwd) : process.cwd(),
|
|
2928
3054
|
json: Boolean(opts.json),
|
|
@@ -2930,7 +3056,7 @@ function registerCollabCommands(program) {
|
|
|
2930
3056
|
});
|
|
2931
3057
|
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
2932
3058
|
});
|
|
2933
|
-
collab.command("request-merge").description("Open a merge request from the current remix to its upstream app").option("--yes", "Run non-interactively", false).option("--cwd <path>", "Working directory for repository detection").option("--non-interactive", "Run non-interactively", false).option("--json", "Output JSON", false).action(async (opts) => {
|
|
3059
|
+
collab.command("request-merge").description("Open a prompt-backed merge request from the current remix to its upstream app").option("--yes", "Run non-interactively", false).option("--cwd <path>", "Working directory for repository detection").option("--non-interactive", "Run non-interactively", false).option("--json", "Output JSON", false).action(async (opts) => {
|
|
2934
3060
|
const result = await collabRequestMerge({
|
|
2935
3061
|
cwd: opts.cwd ? String(opts.cwd) : process.cwd(),
|
|
2936
3062
|
json: Boolean(opts.json),
|
|
@@ -2938,11 +3064,41 @@ function registerCollabCommands(program) {
|
|
|
2938
3064
|
});
|
|
2939
3065
|
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
2940
3066
|
});
|
|
2941
|
-
collab.command("
|
|
2942
|
-
const result = await
|
|
3067
|
+
collab.command("review-queue").description("List reviewable merge requests available to the current user").option("--status <status>", "Filter merge requests by status").option("--kind <kind>", "Filter merge requests by kind (merge|sync|all)", parseMergeRequestKind).option("--yes", "Run non-interactively", false).option("--non-interactive", "Run non-interactively", false).option("--json", "Output JSON", false).action(async (opts) => {
|
|
3068
|
+
const result = await collabReviewQueue({
|
|
3069
|
+
status: opts.status ? String(opts.status) : void 0,
|
|
3070
|
+
kind: opts.kind,
|
|
3071
|
+
json: Boolean(opts.json),
|
|
3072
|
+
yes: Boolean(opts.yes || opts.nonInteractive)
|
|
3073
|
+
});
|
|
3074
|
+
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
3075
|
+
});
|
|
3076
|
+
collab.command("my-merge-requests").description("List merge requests created by the current user").option("--status <status>", "Filter merge requests by status").option("--kind <kind>", "Filter merge requests by kind (merge|sync|all)", parseMergeRequestKind).option("--yes", "Run non-interactively", false).option("--non-interactive", "Run non-interactively", false).option("--json", "Output JSON", false).action(async (opts) => {
|
|
3077
|
+
const result = await collabMyMergeRequests({
|
|
3078
|
+
status: opts.status ? String(opts.status) : void 0,
|
|
3079
|
+
kind: opts.kind,
|
|
3080
|
+
json: Boolean(opts.json),
|
|
3081
|
+
yes: Boolean(opts.yes || opts.nonInteractive)
|
|
3082
|
+
});
|
|
2943
3083
|
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
2944
3084
|
});
|
|
2945
|
-
collab.command("
|
|
3085
|
+
collab.command("list-app-merge-requests").description("List merge requests for the current bound app or an explicit app").requiredOption(
|
|
3086
|
+
"--queue <queue>",
|
|
3087
|
+
"App-scoped queue (app_reviewable|app_outgoing|app_related_visible)",
|
|
3088
|
+
parseAppMergeRequestQueue
|
|
3089
|
+
).option("--cwd <path>", "Working directory for repository detection").option("--app-id <id>", "Explicit app id instead of the current bound repository").option("--status <status>", "Filter merge requests by status").option("--kind <kind>", "Filter merge requests by kind (merge|sync|all)", parseMergeRequestKind).option("--yes", "Run non-interactively", false).option("--non-interactive", "Run non-interactively", false).option("--json", "Output JSON", false).action(async (opts) => {
|
|
3090
|
+
const result = await collabListAppMergeRequests({
|
|
3091
|
+
cwd: opts.cwd ? String(opts.cwd) : process.cwd(),
|
|
3092
|
+
appId: opts.appId ? String(opts.appId) : null,
|
|
3093
|
+
queue: opts.queue,
|
|
3094
|
+
status: opts.status ? String(opts.status) : void 0,
|
|
3095
|
+
kind: opts.kind,
|
|
3096
|
+
json: Boolean(opts.json),
|
|
3097
|
+
yes: Boolean(opts.yes || opts.nonInteractive)
|
|
3098
|
+
});
|
|
3099
|
+
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
3100
|
+
});
|
|
3101
|
+
collab.command("view <mrId>").description("View merge request review groups and diffs").option("--yes", "Run non-interactively", false).option("--non-interactive", "Run non-interactively", false).option("--json", "Output JSON", false).action(async (mrId, opts) => {
|
|
2946
3102
|
const result = await collabView({
|
|
2947
3103
|
mrId: String(mrId),
|
|
2948
3104
|
json: Boolean(opts.json),
|
|
@@ -2950,7 +3106,7 @@ function registerCollabCommands(program) {
|
|
|
2950
3106
|
});
|
|
2951
3107
|
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
2952
3108
|
});
|
|
2953
|
-
collab.command("approve <mrId>").description("Approve a merge request").option("--yes", "Run non-interactively", false).option("--non-interactive", "Run non-interactively", false).option("--remote-only", "Approve remotely and wait for merge completion without touching the local repo", false).option("--sync-target-repo", "Approve, wait for merge completion, and sync the current target repo checkout", false).option("--allow-branch-mismatch", "Allow syncing the target repo from a branch that does not match the checkout's preferred Remix branch", false).option("--json", "Output JSON", false).action(async (mrId, opts) => {
|
|
3109
|
+
collab.command("approve <mrId>").description("Approve a merge request or upstream sync request").option("--yes", "Run non-interactively", false).option("--non-interactive", "Run non-interactively", false).option("--remote-only", "Approve remotely and wait for merge completion without touching the local repo", false).option("--sync-target-repo", "Approve, wait for merge completion, and sync the current target repo checkout", false).option("--allow-branch-mismatch", "Allow syncing the target repo from a branch that does not match the checkout's preferred Remix branch", false).option("--json", "Output JSON", false).action(async (mrId, opts) => {
|
|
2954
3110
|
const result = await collabApprove({
|
|
2955
3111
|
mrId: String(mrId),
|
|
2956
3112
|
cwd: process.cwd(),
|
|
@@ -3017,6 +3173,29 @@ function registerCollabCommands(program) {
|
|
|
3017
3173
|
});
|
|
3018
3174
|
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
3019
3175
|
});
|
|
3176
|
+
const members = collab.command("members").description("List members and update membership roles");
|
|
3177
|
+
members.command("list").description("List members for an organization, project, or app").option("--scope <scope>", "Membership scope (organization|project|app)", parseInviteScope, "project").option("--target-id <id>", "Explicit organization/project/app id instead of using the current repository binding").option("--cwd <path>", "Working directory for repository detection").option("--yes", "Run non-interactively", false).option("--non-interactive", "Run non-interactively", false).option("--json", "Output JSON", false).action(async (opts) => {
|
|
3178
|
+
const result = await collabMembersList({
|
|
3179
|
+
cwd: opts.cwd ? String(opts.cwd) : process.cwd(),
|
|
3180
|
+
scope: parseInviteScope(String(opts.scope ?? "project")),
|
|
3181
|
+
targetId: opts.targetId ? String(opts.targetId) : null,
|
|
3182
|
+
json: Boolean(opts.json),
|
|
3183
|
+
yes: Boolean(opts.yes || opts.nonInteractive)
|
|
3184
|
+
});
|
|
3185
|
+
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
3186
|
+
});
|
|
3187
|
+
members.command("update <userId>").description("Update a member role for an organization, project, or app").requiredOption("--role <role>", "Role for the membership").option("--scope <scope>", "Membership scope (organization|project|app)", parseInviteScope, "project").option("--target-id <id>", "Explicit organization/project/app id instead of using the current repository binding").option("--cwd <path>", "Working directory for repository detection").option("--yes", "Run non-interactively", false).option("--non-interactive", "Run non-interactively", false).option("--json", "Output JSON", false).action(async (userId, opts) => {
|
|
3188
|
+
const result = await collabMembersUpdate({
|
|
3189
|
+
cwd: opts.cwd ? String(opts.cwd) : process.cwd(),
|
|
3190
|
+
scope: parseInviteScope(String(opts.scope ?? "project")),
|
|
3191
|
+
userId: String(userId),
|
|
3192
|
+
role: String(opts.role),
|
|
3193
|
+
targetId: opts.targetId ? String(opts.targetId) : null,
|
|
3194
|
+
json: Boolean(opts.json),
|
|
3195
|
+
yes: Boolean(opts.yes || opts.nonInteractive)
|
|
3196
|
+
});
|
|
3197
|
+
if (opts.json) console.log(JSON.stringify(result, null, 2));
|
|
3198
|
+
});
|
|
3020
3199
|
}
|
|
3021
3200
|
|
|
3022
3201
|
// src/cli.ts
|