@rness/cli 0.5.3 → 0.6.1
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 +51 -5
- package/dist/bin/rness.js +1 -1
- package/dist/{chunk-CQ6YD63L.js → chunk-YAIZOFYV.js} +434 -222
- package/dist/chunk-YAIZOFYV.js.map +1 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-CQ6YD63L.js.map +0 -1
|
@@ -45,6 +45,75 @@ async function writeFileAtomic(p, text) {
|
|
|
45
45
|
}
|
|
46
46
|
}
|
|
47
47
|
|
|
48
|
+
// src/core/pm.ts
|
|
49
|
+
import { execFile } from "child_process";
|
|
50
|
+
import { promisify } from "util";
|
|
51
|
+
var execFileP = promisify(execFile);
|
|
52
|
+
var PACKAGE_MANAGERS = [
|
|
53
|
+
"npm",
|
|
54
|
+
"pnpm",
|
|
55
|
+
"yarn",
|
|
56
|
+
"bun"
|
|
57
|
+
];
|
|
58
|
+
function isPackageManager(value) {
|
|
59
|
+
return PACKAGE_MANAGERS.includes(value);
|
|
60
|
+
}
|
|
61
|
+
function detectPackageManager(userAgent = process.env["npm_config_user_agent"] ?? "") {
|
|
62
|
+
const name = userAgent.split("/")[0] ?? "";
|
|
63
|
+
return isPackageManager(name) ? name : "npm";
|
|
64
|
+
}
|
|
65
|
+
function firstLine(text) {
|
|
66
|
+
return text.split("\n").find((l) => l.trim() !== "")?.trim() ?? "unknown error";
|
|
67
|
+
}
|
|
68
|
+
async function packageManagerVersion(pm) {
|
|
69
|
+
try {
|
|
70
|
+
const { stdout } = await execFileP(pm, ["--version"]);
|
|
71
|
+
return stdout.trim();
|
|
72
|
+
} catch (e) {
|
|
73
|
+
throw new Error(`${pm} is not available on PATH`, { cause: e });
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function rnessRunner(pm, version) {
|
|
77
|
+
if (pm === "pnpm") return "pnpm dlx @rness/cli";
|
|
78
|
+
if (pm === "bun") return "bunx @rness/cli";
|
|
79
|
+
if (pm === "yarn" && Number(version?.split(".")[0]) >= 2)
|
|
80
|
+
return "yarn dlx @rness/cli";
|
|
81
|
+
return "npx @rness/cli";
|
|
82
|
+
}
|
|
83
|
+
function rnessCommand(env = process.env) {
|
|
84
|
+
const agent = env["npm_config_user_agent"] ?? "";
|
|
85
|
+
if (agent === "") return "rness";
|
|
86
|
+
const pm = detectPackageManager(agent);
|
|
87
|
+
const [name, version] = (agent.split(" ")[0] ?? "").split("/");
|
|
88
|
+
return rnessRunner(pm, name === pm ? version ?? null : null);
|
|
89
|
+
}
|
|
90
|
+
var BARE_NPM_CODE = /^npm (error|ERR!) code \S+$/;
|
|
91
|
+
function installErrorLine(stderr) {
|
|
92
|
+
const lines = stderr.split("\n").map((l) => l.trim()).filter((l) => l !== "");
|
|
93
|
+
return lines.find((l) => !BARE_NPM_CODE.test(l)) ?? firstLine(stderr);
|
|
94
|
+
}
|
|
95
|
+
var FROZEN = {
|
|
96
|
+
npm: ["ci"],
|
|
97
|
+
pnpm: ["install", "--frozen-lockfile"],
|
|
98
|
+
yarn: ["install", "--immutable"],
|
|
99
|
+
bun: ["install", "--frozen-lockfile"]
|
|
100
|
+
};
|
|
101
|
+
function frozenArgs(pm) {
|
|
102
|
+
return [...FROZEN[pm]];
|
|
103
|
+
}
|
|
104
|
+
async function installDependencies(pm, dir, opts = {}) {
|
|
105
|
+
const args = opts.frozen === true ? frozenArgs(pm) : ["install"];
|
|
106
|
+
try {
|
|
107
|
+
await execFileP(pm, args, { cwd: dir, maxBuffer: 16 * 1024 * 1024 });
|
|
108
|
+
} catch (e) {
|
|
109
|
+
const err = e;
|
|
110
|
+
throw new Error(
|
|
111
|
+
`${pm} ${args.join(" ")} failed in ${dir}: ${installErrorLine(err.stderr ?? err.message)}`,
|
|
112
|
+
{ cause: e }
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
48
117
|
// src/core/auth.ts
|
|
49
118
|
import { chmod, mkdir, open, readFile as readFile2, rm as rm2, stat } from "fs/promises";
|
|
50
119
|
import { homedir } from "os";
|
|
@@ -298,7 +367,7 @@ async function resolveToken(deps = {}) {
|
|
|
298
367
|
await clearAuth();
|
|
299
368
|
(deps.notify ?? ((l) => process.stderr.write(`${l}
|
|
300
369
|
`)))(
|
|
301
|
-
|
|
370
|
+
`your GitHub login expired; run ${rnessCommand()} login`
|
|
302
371
|
);
|
|
303
372
|
return null;
|
|
304
373
|
}
|
|
@@ -313,7 +382,7 @@ async function resolveToken(deps = {}) {
|
|
|
313
382
|
var DEFAULT_GITHUB_API = "https://api.github.com";
|
|
314
383
|
var MAX_PAGES = 50;
|
|
315
384
|
var PER_PAGE = 100;
|
|
316
|
-
var
|
|
385
|
+
var addLater = () => `; add repositories later with ${rnessCommand()} add <repo>`;
|
|
317
386
|
var NEXT = /<[^>]*>\s*;\s*rel="next"/;
|
|
318
387
|
function isRepository(value) {
|
|
319
388
|
if (value === null || typeof value !== "object") return false;
|
|
@@ -357,12 +426,12 @@ function httpError(page, path) {
|
|
|
357
426
|
return new Error("GitHub rejected the token (401)", { cause });
|
|
358
427
|
if (page.status === 429 || page.status === 403 && (page.headers.get("x-ratelimit-remaining") === "0" || page.headers.has("retry-after"))) {
|
|
359
428
|
return new Error(
|
|
360
|
-
|
|
429
|
+
`GitHub API rate limit reached; set GITHUB_TOKEN or add repositories later with ${rnessCommand()} add`,
|
|
361
430
|
{ cause }
|
|
362
431
|
);
|
|
363
432
|
}
|
|
364
433
|
return new Error(
|
|
365
|
-
`GitHub API answered ${page.status} for ${path}${
|
|
434
|
+
`GitHub API answered ${page.status} for ${path}${addLater()}`,
|
|
366
435
|
{ cause }
|
|
367
436
|
);
|
|
368
437
|
}
|
|
@@ -403,7 +472,7 @@ async function listRepositories(owner, options) {
|
|
|
403
472
|
page = await getPage(url(kind, n), headers, timeoutMs);
|
|
404
473
|
if (page.status === 404) {
|
|
405
474
|
throw new Error(
|
|
406
|
-
`GitHub has no organization or user named "${owner}" (or it is not visible to you)${
|
|
475
|
+
`GitHub has no organization or user named "${owner}" (or it is not visible to you)${addLater()}`,
|
|
407
476
|
{ cause: { status: 404, path: kind.path } }
|
|
408
477
|
);
|
|
409
478
|
}
|
|
@@ -599,10 +668,10 @@ async function githubProvider(apiBase) {
|
|
|
599
668
|
import { spawn } from "child_process";
|
|
600
669
|
|
|
601
670
|
// src/core/git.ts
|
|
602
|
-
import { execFile } from "child_process";
|
|
671
|
+
import { execFile as execFile2 } from "child_process";
|
|
603
672
|
import { dirname as dirname2, resolve } from "path";
|
|
604
|
-
import { promisify } from "util";
|
|
605
|
-
var
|
|
673
|
+
import { promisify as promisify2 } from "util";
|
|
674
|
+
var execFileP2 = promisify2(execFile2);
|
|
606
675
|
var ENV_HELPER = '!f() { test "$1" = get && printf "username=%s\\npassword=%s\\n" "$RNESS_GIT_USERNAME" "$RNESS_GIT_TOKEN"; }; f';
|
|
607
676
|
function withCredentials(credentials) {
|
|
608
677
|
if (credentials === null || credentials === void 0)
|
|
@@ -618,7 +687,7 @@ function withCredentials(credentials) {
|
|
|
618
687
|
async function git(args, cwd, credentials) {
|
|
619
688
|
const auth = withCredentials(credentials);
|
|
620
689
|
try {
|
|
621
|
-
const { stdout } = await
|
|
690
|
+
const { stdout } = await execFileP2("git", [...auth.args, ...args], {
|
|
622
691
|
...cwd === void 0 ? {} : { cwd },
|
|
623
692
|
env: {
|
|
624
693
|
...process.env,
|
|
@@ -709,7 +778,7 @@ var NOT_FOUND = [
|
|
|
709
778
|
/repository .*not found/i,
|
|
710
779
|
/does not appear to be a git repository/i
|
|
711
780
|
];
|
|
712
|
-
function
|
|
781
|
+
function firstLine2(text) {
|
|
713
782
|
return text.split("\n").find((l) => l.trim() !== "")?.trim() ?? "unknown error";
|
|
714
783
|
}
|
|
715
784
|
function classifyProbe(url, exitCode, stderr) {
|
|
@@ -717,15 +786,15 @@ function classifyProbe(url, exitCode, stderr) {
|
|
|
717
786
|
if (AUTH.some((r) => r.test(stderr)))
|
|
718
787
|
return {
|
|
719
788
|
kind: "error",
|
|
720
|
-
message: `cannot access ${url}: ${
|
|
789
|
+
message: `cannot access ${url}: ${firstLine2(stderr)}`
|
|
721
790
|
};
|
|
722
791
|
if (NOT_FOUND.some((r) => r.test(stderr))) return { kind: "not-found" };
|
|
723
|
-
return { kind: "error", message: `cannot reach ${url}: ${
|
|
792
|
+
return { kind: "error", message: `cannot reach ${url}: ${firstLine2(stderr)}` };
|
|
724
793
|
}
|
|
725
794
|
var STDERR_FLUSH_MS = 200;
|
|
726
795
|
async function probeRemote(url, timeoutMs = 6e4, credentials) {
|
|
727
796
|
positional(url, "repository url");
|
|
728
|
-
return new Promise((
|
|
797
|
+
return new Promise((resolve5) => {
|
|
729
798
|
const auth = withCredentials(credentials);
|
|
730
799
|
const child = spawn(
|
|
731
800
|
"git",
|
|
@@ -744,7 +813,7 @@ async function probeRemote(url, timeoutMs = 6e4, credentials) {
|
|
|
744
813
|
settled = true;
|
|
745
814
|
clearTimeout(timer);
|
|
746
815
|
child.stderr?.destroy();
|
|
747
|
-
|
|
816
|
+
resolve5(probe);
|
|
748
817
|
};
|
|
749
818
|
const timer = setTimeout(() => {
|
|
750
819
|
child.kill("SIGKILL");
|
|
@@ -814,13 +883,8 @@ function readOrg(value) {
|
|
|
814
883
|
}
|
|
815
884
|
return value;
|
|
816
885
|
}
|
|
817
|
-
function
|
|
818
|
-
|
|
819
|
-
const name = basename2(root);
|
|
820
|
-
return {
|
|
821
|
-
org: name,
|
|
822
|
-
warning: `rness.json: no "org"; using the directory name "${name}"`
|
|
823
|
-
};
|
|
886
|
+
function workspaceName(manifest, root) {
|
|
887
|
+
return manifest.org ?? basename2(root);
|
|
824
888
|
}
|
|
825
889
|
function readRepos(value) {
|
|
826
890
|
const raw = value ?? {};
|
|
@@ -915,8 +979,13 @@ function parseRepoSpec(spec, org, host) {
|
|
|
915
979
|
url = spec;
|
|
916
980
|
} else {
|
|
917
981
|
const parts = spec.split("/");
|
|
918
|
-
if (parts.length === 1)
|
|
919
|
-
|
|
982
|
+
if (parts.length === 1) {
|
|
983
|
+
if (org === null)
|
|
984
|
+
throw new Error(
|
|
985
|
+
"this workspace has no GitHub organization: give <owner>/<repo> or a git URL"
|
|
986
|
+
);
|
|
987
|
+
url = repoUrl(host, org, spec);
|
|
988
|
+
} else if (parts.length === 2 && parts[0] !== void 0 && parts[1] !== void 0)
|
|
920
989
|
url = repoUrl(host, parts[0], parts[1]);
|
|
921
990
|
else
|
|
922
991
|
throw new Error(
|
|
@@ -1149,7 +1218,7 @@ var GREETING = /^Hi ([^!\s]+)! You've successfully authenticated/m;
|
|
|
1149
1218
|
function parseSshGreeting(stderr) {
|
|
1150
1219
|
return GREETING.exec(stderr)?.[1] ?? null;
|
|
1151
1220
|
}
|
|
1152
|
-
function
|
|
1221
|
+
function firstLine3(text) {
|
|
1153
1222
|
return text.split("\n").find((l) => l.trim() !== "")?.trim() ?? null;
|
|
1154
1223
|
}
|
|
1155
1224
|
var STDERR_FLUSH_MS2 = 200;
|
|
@@ -1162,7 +1231,7 @@ async function detectGithubSsh(opts) {
|
|
|
1162
1231
|
...opts.interactive ? [] : ["-o", "BatchMode=yes"],
|
|
1163
1232
|
"git@github.com"
|
|
1164
1233
|
];
|
|
1165
|
-
return new Promise((
|
|
1234
|
+
return new Promise((resolve5) => {
|
|
1166
1235
|
const child = spawn2(opts.command ?? "ssh", args, {
|
|
1167
1236
|
stdio: [opts.interactive ? "inherit" : "ignore", "ignore", "pipe"]
|
|
1168
1237
|
});
|
|
@@ -1175,7 +1244,7 @@ async function detectGithubSsh(opts) {
|
|
|
1175
1244
|
settled = true;
|
|
1176
1245
|
clearTimeout(timer);
|
|
1177
1246
|
child.stderr?.destroy();
|
|
1178
|
-
|
|
1247
|
+
resolve5(access2);
|
|
1179
1248
|
};
|
|
1180
1249
|
const timer = setTimeout(() => {
|
|
1181
1250
|
child.kill("SIGKILL");
|
|
@@ -1189,7 +1258,7 @@ async function detectGithubSsh(opts) {
|
|
|
1189
1258
|
settle(
|
|
1190
1259
|
login !== null ? { ok: true, login } : {
|
|
1191
1260
|
ok: false,
|
|
1192
|
-
reason:
|
|
1261
|
+
reason: firstLine3(stderr2) ?? `ssh exited with code ${code ?? "?"}`
|
|
1193
1262
|
}
|
|
1194
1263
|
);
|
|
1195
1264
|
};
|
|
@@ -1254,7 +1323,7 @@ var INSTEAD_OF_LINES = [
|
|
|
1254
1323
|
' git config --global url."https://github.com/".insteadOf git@github.com:'
|
|
1255
1324
|
];
|
|
1256
1325
|
function httpsFlagLine(spec) {
|
|
1257
|
-
return `or clone this repository over HTTPS:
|
|
1326
|
+
return `or clone this repository over HTTPS: ${rnessCommand()} add ${spec} --https`;
|
|
1258
1327
|
}
|
|
1259
1328
|
|
|
1260
1329
|
// src/core/workspace.ts
|
|
@@ -1828,9 +1897,8 @@ async function syncCommand(opts, deps = {}) {
|
|
|
1828
1897
|
try {
|
|
1829
1898
|
const ws = await findWorkspace(cwd);
|
|
1830
1899
|
const manifest = await loadManifest(ws.rnessDir);
|
|
1831
|
-
const
|
|
1900
|
+
const org = workspaceName(manifest, ws.root);
|
|
1832
1901
|
if (ownUi) ui.intro(`Sync workspace ${org}`);
|
|
1833
|
-
if (warning !== null) ui.warn(warning);
|
|
1834
1902
|
if (opts.scope !== void 0 && !Object.hasOwn(manifest.scopes, opts.scope)) {
|
|
1835
1903
|
process.stderr.write(`unknown scope: ${opts.scope}
|
|
1836
1904
|
`);
|
|
@@ -1917,7 +1985,7 @@ async function syncCommand(opts, deps = {}) {
|
|
|
1917
1985
|
}
|
|
1918
1986
|
if (notCloned.size > 0)
|
|
1919
1987
|
lines.push(
|
|
1920
|
-
`not cloned: ${[...notCloned].join(", ")} (
|
|
1988
|
+
`not cloned: ${[...notCloned].join(", ")} (${rnessCommand()} add <name>, or ${rnessCommand()} sync --all)`
|
|
1921
1989
|
);
|
|
1922
1990
|
const scoped = new Set(
|
|
1923
1991
|
Object.values(manifest.scopes).map((s) => s.path.split("/")[1])
|
|
@@ -1927,7 +1995,7 @@ async function syncCommand(opts, deps = {}) {
|
|
|
1927
1995
|
);
|
|
1928
1996
|
if (undeclared.length > 0)
|
|
1929
1997
|
lines.push(
|
|
1930
|
-
`not in rness.json: ${undeclared.join(", ")} (
|
|
1998
|
+
`not in rness.json: ${undeclared.join(", ")} (${rnessCommand()} add <name> declares it)`
|
|
1931
1999
|
);
|
|
1932
2000
|
if (!await exists(join9(ws.root, "org"))) {
|
|
1933
2001
|
lines.push(["skipped", "blocks (no org/ directory here)"]);
|
|
@@ -1991,7 +2059,9 @@ async function syncCommand(opts, deps = {}) {
|
|
|
1991
2059
|
lines.push(["updated", `${t.label}`]);
|
|
1992
2060
|
}
|
|
1993
2061
|
if (check && differences > 0)
|
|
1994
|
-
problems.push(
|
|
2062
|
+
problems.push(
|
|
2063
|
+
`${differences} block(s) out of date \u2014 run ${rnessCommand()} sync`
|
|
2064
|
+
);
|
|
1995
2065
|
}
|
|
1996
2066
|
return problems.length > 0 ? 1 : 0;
|
|
1997
2067
|
} finally {
|
|
@@ -2035,9 +2105,7 @@ async function addCommand(spec, opts, deps = {}) {
|
|
|
2035
2105
|
try {
|
|
2036
2106
|
const ws = await findWorkspace(cwd);
|
|
2037
2107
|
const manifest = await loadManifest(ws.rnessDir);
|
|
2038
|
-
const
|
|
2039
|
-
if (warning !== null) process.stderr.write(`${warn(warning)}
|
|
2040
|
-
`);
|
|
2108
|
+
const org = manifest.org;
|
|
2041
2109
|
let parsed;
|
|
2042
2110
|
try {
|
|
2043
2111
|
parsed = parseRepoSpec(spec, org, transport.hosts.https);
|
|
@@ -2062,7 +2130,10 @@ async function addCommand(spec, opts, deps = {}) {
|
|
|
2062
2130
|
return 2;
|
|
2063
2131
|
}
|
|
2064
2132
|
const ui = deps.ui ?? (interactive ? await makeUi(terminal) : { ...plainUi });
|
|
2065
|
-
if (ownUi)
|
|
2133
|
+
if (ownUi)
|
|
2134
|
+
ui.intro(
|
|
2135
|
+
`Add ${parsed.name} to workspace ${workspaceName(manifest, ws.root)}`
|
|
2136
|
+
);
|
|
2066
2137
|
if (opts.host !== void 0 || opts.https === true) ui.gitIsSilent = true;
|
|
2067
2138
|
let host = opts.host;
|
|
2068
2139
|
if (host === void 0 && opts.ssh === true) host = transport.hosts.ssh;
|
|
@@ -2229,6 +2300,9 @@ async function contextCommand(opts) {
|
|
|
2229
2300
|
}
|
|
2230
2301
|
}
|
|
2231
2302
|
|
|
2303
|
+
// src/version.ts
|
|
2304
|
+
var VERSION = "0.6.1";
|
|
2305
|
+
|
|
2232
2306
|
// src/core/delegate.ts
|
|
2233
2307
|
import { readFile as readFile6 } from "fs/promises";
|
|
2234
2308
|
import { join as join11 } from "path";
|
|
@@ -2276,61 +2350,6 @@ async function findDelegate(cwd, ownVersion) {
|
|
|
2276
2350
|
return { entry: join11(pinned.dir, "dist", "index.js"), version, root };
|
|
2277
2351
|
}
|
|
2278
2352
|
|
|
2279
|
-
// src/core/pm.ts
|
|
2280
|
-
import { execFile as execFile2 } from "child_process";
|
|
2281
|
-
import { promisify as promisify2 } from "util";
|
|
2282
|
-
var execFileP2 = promisify2(execFile2);
|
|
2283
|
-
var PACKAGE_MANAGERS = [
|
|
2284
|
-
"npm",
|
|
2285
|
-
"pnpm",
|
|
2286
|
-
"yarn",
|
|
2287
|
-
"bun"
|
|
2288
|
-
];
|
|
2289
|
-
function isPackageManager(value) {
|
|
2290
|
-
return PACKAGE_MANAGERS.includes(value);
|
|
2291
|
-
}
|
|
2292
|
-
function detectPackageManager(userAgent = process.env["npm_config_user_agent"] ?? "") {
|
|
2293
|
-
const name = userAgent.split("/")[0] ?? "";
|
|
2294
|
-
return isPackageManager(name) ? name : "npm";
|
|
2295
|
-
}
|
|
2296
|
-
function firstLine3(text) {
|
|
2297
|
-
return text.split("\n").find((l) => l.trim() !== "")?.trim() ?? "unknown error";
|
|
2298
|
-
}
|
|
2299
|
-
async function packageManagerVersion(pm) {
|
|
2300
|
-
try {
|
|
2301
|
-
const { stdout } = await execFileP2(pm, ["--version"]);
|
|
2302
|
-
return stdout.trim();
|
|
2303
|
-
} catch (e) {
|
|
2304
|
-
throw new Error(`${pm} is not available on PATH`, { cause: e });
|
|
2305
|
-
}
|
|
2306
|
-
}
|
|
2307
|
-
var BARE_NPM_CODE = /^npm (error|ERR!) code \S+$/;
|
|
2308
|
-
function installErrorLine(stderr) {
|
|
2309
|
-
const lines = stderr.split("\n").map((l) => l.trim()).filter((l) => l !== "");
|
|
2310
|
-
return lines.find((l) => !BARE_NPM_CODE.test(l)) ?? firstLine3(stderr);
|
|
2311
|
-
}
|
|
2312
|
-
var FROZEN = {
|
|
2313
|
-
npm: ["ci"],
|
|
2314
|
-
pnpm: ["install", "--frozen-lockfile"],
|
|
2315
|
-
yarn: ["install", "--immutable"],
|
|
2316
|
-
bun: ["install", "--frozen-lockfile"]
|
|
2317
|
-
};
|
|
2318
|
-
function frozenArgs(pm) {
|
|
2319
|
-
return [...FROZEN[pm]];
|
|
2320
|
-
}
|
|
2321
|
-
async function installDependencies(pm, dir, opts = {}) {
|
|
2322
|
-
const args = opts.frozen === true ? frozenArgs(pm) : ["install"];
|
|
2323
|
-
try {
|
|
2324
|
-
await execFileP2(pm, args, { cwd: dir, maxBuffer: 16 * 1024 * 1024 });
|
|
2325
|
-
} catch (e) {
|
|
2326
|
-
const err = e;
|
|
2327
|
-
throw new Error(
|
|
2328
|
-
`${pm} ${args.join(" ")} failed in ${dir}: ${installErrorLine(err.stderr ?? err.message)}`,
|
|
2329
|
-
{ cause: e }
|
|
2330
|
-
);
|
|
2331
|
-
}
|
|
2332
|
-
}
|
|
2333
|
-
|
|
2334
2353
|
// src/core/scaffold.ts
|
|
2335
2354
|
import { statSync } from "fs";
|
|
2336
2355
|
import { dirname as dirname4, join as join12 } from "path";
|
|
@@ -2389,9 +2408,6 @@ async function copyScaffold(dest, tokens) {
|
|
|
2389
2408
|
}
|
|
2390
2409
|
}
|
|
2391
2410
|
|
|
2392
|
-
// src/version.ts
|
|
2393
|
-
var VERSION = "0.5.3";
|
|
2394
|
-
|
|
2395
2411
|
// src/commands/login.ts
|
|
2396
2412
|
import { spawn as spawn3 } from "child_process";
|
|
2397
2413
|
import { realpath } from "fs/promises";
|
|
@@ -2469,8 +2485,8 @@ async function offerSetupGit(opts, terminal, bin, ui) {
|
|
|
2469
2485
|
const changed = await setupGit(process.execPath, bin);
|
|
2470
2486
|
ui.line(
|
|
2471
2487
|
changed ? "updated" : "unchanged",
|
|
2472
|
-
|
|
2473
|
-
|
|
2488
|
+
`git: rness answers for https://github.com (${rnessCommand()} logout undoes it)`,
|
|
2489
|
+
`git now asks rness for your github.com login over HTTPS (${rnessCommand()} logout undoes it)`
|
|
2474
2490
|
);
|
|
2475
2491
|
}
|
|
2476
2492
|
async function loginCommand(opts, deps = {}) {
|
|
@@ -2487,7 +2503,7 @@ async function loginCommand(opts, deps = {}) {
|
|
|
2487
2503
|
if (stored !== null && await resolveToken() !== null) {
|
|
2488
2504
|
ui.line(
|
|
2489
2505
|
"logged in",
|
|
2490
|
-
`as ${stored.login} (github.com);
|
|
2506
|
+
`as ${stored.login} (github.com); ${rnessCommand()} logout to switch`
|
|
2491
2507
|
);
|
|
2492
2508
|
await offerSetupGit(opts, terminal, bin, ui);
|
|
2493
2509
|
if (own) ui.outro("Nothing to do", "idle");
|
|
@@ -2542,9 +2558,13 @@ function revokeUrl() {
|
|
|
2542
2558
|
}
|
|
2543
2559
|
|
|
2544
2560
|
// src/commands/create.ts
|
|
2545
|
-
import { mkdir as
|
|
2561
|
+
import { mkdir as mkdir5, mkdtemp, rename as rename2, rm as rm5 } from "fs/promises";
|
|
2546
2562
|
import { tmpdir } from "os";
|
|
2547
|
-
import {
|
|
2563
|
+
import { join as join17, relative as relative4, resolve as resolve4 } from "path";
|
|
2564
|
+
|
|
2565
|
+
// src/core/new-workspace.ts
|
|
2566
|
+
import { mkdir as mkdir3, readdir as readdir2, rm as rm4, stat as stat3 } from "fs/promises";
|
|
2567
|
+
import { dirname as dirname6, join as join15, relative as relative2 } from "path";
|
|
2548
2568
|
|
|
2549
2569
|
// src/core/pinned.ts
|
|
2550
2570
|
import { execFile as execFile4 } from "child_process";
|
|
@@ -2746,7 +2766,7 @@ async function syncPinned(root, shown, fallback) {
|
|
|
2746
2766
|
if (installed === null) {
|
|
2747
2767
|
if (fallback !== void 0) return fallback();
|
|
2748
2768
|
process.stderr.write(
|
|
2749
|
-
`@rness/cli is not installed in ${shown}/.rness; install in .rness/, then
|
|
2769
|
+
`@rness/cli is not installed in ${shown}/.rness; install in .rness/, then ${rnessCommand()} sync
|
|
2750
2770
|
`
|
|
2751
2771
|
);
|
|
2752
2772
|
return 1;
|
|
@@ -2784,8 +2804,88 @@ async function syncPinned(root, shown, fallback) {
|
|
|
2784
2804
|
}
|
|
2785
2805
|
}
|
|
2786
2806
|
|
|
2807
|
+
// src/core/new-workspace.ts
|
|
2808
|
+
async function isEmptyDir(dir) {
|
|
2809
|
+
return (await readdir2(dir)).length === 0;
|
|
2810
|
+
}
|
|
2811
|
+
async function insideWorkspace(dir) {
|
|
2812
|
+
try {
|
|
2813
|
+
await findWorkspace(dir);
|
|
2814
|
+
return true;
|
|
2815
|
+
} catch {
|
|
2816
|
+
return false;
|
|
2817
|
+
}
|
|
2818
|
+
}
|
|
2819
|
+
async function targetProblem(cwd, root, pm) {
|
|
2820
|
+
const shown = relative2(cwd, root) || ".";
|
|
2821
|
+
if (await insideWorkspace(cwd) || await insideWorkspace(dirname6(root)))
|
|
2822
|
+
return "already inside an rness workspace; create runs from outside one";
|
|
2823
|
+
if (!await exists(root)) return null;
|
|
2824
|
+
if (await exists(join15(root, ".rness", "rness.json"))) {
|
|
2825
|
+
if (!await exists(join15(root, ".rness", "node_modules")))
|
|
2826
|
+
return `${shown} holds an rness workspace whose dependencies are not installed; cd ${shown}/.rness && ${pm} install, then ${rnessCommand()} sync`;
|
|
2827
|
+
return `${shown} already holds an rness workspace (.rness/); run ${rnessCommand()} add inside it to add repositories`;
|
|
2828
|
+
}
|
|
2829
|
+
if (!(await stat3(root)).isDirectory()) return `${shown} is not a directory`;
|
|
2830
|
+
if (!await isEmptyDir(root)) return `${shown} is not empty`;
|
|
2831
|
+
return null;
|
|
2832
|
+
}
|
|
2833
|
+
async function installContext(input) {
|
|
2834
|
+
const { ui, pm, rnessDir } = input;
|
|
2835
|
+
if (input.skip) {
|
|
2836
|
+
ui.line("skipped", `install with ${pm} (--skip-install)`);
|
|
2837
|
+
return;
|
|
2838
|
+
}
|
|
2839
|
+
const frozen = await hasLockfile(rnessDir, pm);
|
|
2840
|
+
await ui.step(
|
|
2841
|
+
{ doing: `installing dependencies with ${pm}` },
|
|
2842
|
+
() => installDependencies(pm, rnessDir, { frozen }),
|
|
2843
|
+
() => ["installed", `dependencies with ${pm}`]
|
|
2844
|
+
);
|
|
2845
|
+
}
|
|
2846
|
+
async function buildContext(input) {
|
|
2847
|
+
const { ui, root, shown, pm } = input;
|
|
2848
|
+
const rnessDir = join15(root, ".rness");
|
|
2849
|
+
const pmVersion = await packageManagerVersion(pm);
|
|
2850
|
+
await mkdir3(root, { recursive: true });
|
|
2851
|
+
try {
|
|
2852
|
+
await copyScaffold(rnessDir, {
|
|
2853
|
+
version: VERSION,
|
|
2854
|
+
packageManager: `${pm}@${pmVersion}`
|
|
2855
|
+
});
|
|
2856
|
+
await writeManifest(rnessDir, input.manifest);
|
|
2857
|
+
ui.line("created", `${shown}/.rness (${input.kind})`);
|
|
2858
|
+
await installContext({ ui, pm, rnessDir, skip: input.skipInstall });
|
|
2859
|
+
return true;
|
|
2860
|
+
} catch (e) {
|
|
2861
|
+
reportError(e);
|
|
2862
|
+
await rm4(rnessDir, { recursive: true, force: true }).catch(() => void 0);
|
|
2863
|
+
if (await isEmptyDir(root).catch(() => false))
|
|
2864
|
+
await rm4(root, { recursive: true, force: true }).catch(() => void 0);
|
|
2865
|
+
process.stderr.write(
|
|
2866
|
+
`removed ${shown}/.rness after the failure; fix it and retry
|
|
2867
|
+
`
|
|
2868
|
+
);
|
|
2869
|
+
return false;
|
|
2870
|
+
}
|
|
2871
|
+
}
|
|
2872
|
+
async function commitContext(input) {
|
|
2873
|
+
const { ui, rnessDir, shown } = input;
|
|
2874
|
+
await init(rnessDir);
|
|
2875
|
+
try {
|
|
2876
|
+
await commitAll(rnessDir, "chore: rness workspace context");
|
|
2877
|
+
ui.line("committed", `${shown}/.rness`);
|
|
2878
|
+
} catch (e) {
|
|
2879
|
+
ui.warn(
|
|
2880
|
+
`${e instanceof Error ? e.message : String(e)} \u2014 commit ${shown}/.rness yourself`
|
|
2881
|
+
);
|
|
2882
|
+
}
|
|
2883
|
+
}
|
|
2884
|
+
|
|
2787
2885
|
// src/core/sync-blocks.ts
|
|
2788
2886
|
async function syncBlocks(ui, root, shown, inPlace, sshWorks) {
|
|
2887
|
+
if (process.env["RNESS_NO_DELEGATE"] === "1" && inPlace !== void 0)
|
|
2888
|
+
return inPlace();
|
|
2789
2889
|
if (!ui.session)
|
|
2790
2890
|
return ui.step(
|
|
2791
2891
|
{ doing: "syncing the blocks", git: true },
|
|
@@ -2802,7 +2902,7 @@ async function syncBlocks(ui, root, shown, inPlace, sshWorks) {
|
|
|
2802
2902
|
if (result === null) {
|
|
2803
2903
|
if (inPlace !== void 0) return inPlace();
|
|
2804
2904
|
ui.error(
|
|
2805
|
-
`@rness/cli is not installed in ${shown}/.rness; install in .rness/, then
|
|
2905
|
+
`@rness/cli is not installed in ${shown}/.rness; install in .rness/, then ${rnessCommand()} sync`
|
|
2806
2906
|
);
|
|
2807
2907
|
return 1;
|
|
2808
2908
|
}
|
|
@@ -2812,38 +2912,113 @@ async function syncBlocks(ui, root, shown, inPlace, sshWorks) {
|
|
|
2812
2912
|
return outcome.code;
|
|
2813
2913
|
}
|
|
2814
2914
|
|
|
2815
|
-
// src/commands/create.ts
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
}
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
}
|
|
2824
|
-
|
|
2915
|
+
// src/commands/create-blank.ts
|
|
2916
|
+
import { mkdir as mkdir4 } from "fs/promises";
|
|
2917
|
+
import { join as join16, relative as relative3, resolve as resolve3 } from "path";
|
|
2918
|
+
var WORKSPACE_NAME = /^(?!\.{1,2}$)[A-Za-z0-9._][A-Za-z0-9._-]*$/;
|
|
2919
|
+
function workspaceNameError(name) {
|
|
2920
|
+
return `workspace name "${name}" may only contain letters, digits, '.', '_' and '-', not starting with '-'`;
|
|
2921
|
+
}
|
|
2922
|
+
async function createBlank(input) {
|
|
2923
|
+
const { cwd, pm, ui } = input;
|
|
2924
|
+
let name = input.name;
|
|
2925
|
+
let prompted = false;
|
|
2926
|
+
if (name === void 0) {
|
|
2927
|
+
if (!input.interactive) {
|
|
2928
|
+
process.stderr.write(
|
|
2929
|
+
"rness create --blank needs a <name> without a prompt\n"
|
|
2930
|
+
);
|
|
2931
|
+
return 2;
|
|
2932
|
+
}
|
|
2933
|
+
const p = await input.prompts();
|
|
2934
|
+
const answer = await p.text({
|
|
2935
|
+
message: "What should the workspace be called?",
|
|
2936
|
+
placeholder: "my-workspace",
|
|
2937
|
+
validate: (value) => {
|
|
2938
|
+
const v = value?.trim() ?? "";
|
|
2939
|
+
return WORKSPACE_NAME.test(v) ? void 0 : workspaceNameError(v);
|
|
2940
|
+
}
|
|
2941
|
+
});
|
|
2942
|
+
if (p.isCancel(answer) || typeof answer !== "string") {
|
|
2943
|
+
ui.cancelled();
|
|
2944
|
+
return 0;
|
|
2945
|
+
}
|
|
2946
|
+
name = answer.trim();
|
|
2947
|
+
prompted = true;
|
|
2948
|
+
}
|
|
2949
|
+
const root = resolve3(cwd, name);
|
|
2950
|
+
const shown = relative3(cwd, root) || ".";
|
|
2951
|
+
const problem = await targetProblem(cwd, root, pm);
|
|
2952
|
+
if (problem !== null) {
|
|
2953
|
+
process.stderr.write(`${problem}
|
|
2954
|
+
`);
|
|
2955
|
+
return 1;
|
|
2956
|
+
}
|
|
2957
|
+
if (!input.mayWrite) {
|
|
2958
|
+
process.stderr.write(
|
|
2959
|
+
"rness create writes files; pass --yes to run without a prompt\n"
|
|
2960
|
+
);
|
|
2961
|
+
return 2;
|
|
2825
2962
|
}
|
|
2963
|
+
if (input.interactive && !prompted) {
|
|
2964
|
+
const p = await input.prompts();
|
|
2965
|
+
const ok = await p.confirm({
|
|
2966
|
+
message: `Create blank workspace ${name} in ./${shown}?`
|
|
2967
|
+
});
|
|
2968
|
+
if (p.isCancel(ok) || ok !== true) {
|
|
2969
|
+
ui.cancelled();
|
|
2970
|
+
return 0;
|
|
2971
|
+
}
|
|
2972
|
+
}
|
|
2973
|
+
const built = await buildContext({
|
|
2974
|
+
ui,
|
|
2975
|
+
root,
|
|
2976
|
+
shown,
|
|
2977
|
+
manifest: { contract: 1, org: null, repos: {}, scopes: {} },
|
|
2978
|
+
pm,
|
|
2979
|
+
skipInstall: input.skipInstall,
|
|
2980
|
+
kind: "blank workspace"
|
|
2981
|
+
});
|
|
2982
|
+
if (!built) return 1;
|
|
2983
|
+
await mkdir4(join16(root, "org"), { recursive: true });
|
|
2984
|
+
await commitContext({ ui, rnessDir: join16(root, ".rness"), shown });
|
|
2985
|
+
const code = await syncBlocks(
|
|
2986
|
+
ui,
|
|
2987
|
+
root,
|
|
2988
|
+
shown,
|
|
2989
|
+
() => syncCommand({ yes: true, cwd: root })
|
|
2990
|
+
);
|
|
2991
|
+
if (code !== 0) return code;
|
|
2992
|
+
const next = [
|
|
2993
|
+
`cd ${shown}`,
|
|
2994
|
+
"# bring a repository in: <owner>/<repo> on GitHub, or any git URL",
|
|
2995
|
+
`${rnessCommand()} add <owner>/<repo>`,
|
|
2996
|
+
'# to share it: set "org" in .rness/rness.json, then push .rness to github.com/<org>/.rness'
|
|
2997
|
+
];
|
|
2998
|
+
if (ui.session) {
|
|
2999
|
+
ui.note("Next steps", next);
|
|
3000
|
+
ui.outro(`Workspace ${name} is ready in ${shown}/`);
|
|
3001
|
+
} else
|
|
3002
|
+
process.stdout.write(
|
|
3003
|
+
[
|
|
3004
|
+
"",
|
|
3005
|
+
`Workspace \`${name}\` is ready in ${shown}/.`,
|
|
3006
|
+
"",
|
|
3007
|
+
"Next:",
|
|
3008
|
+
...next.map((line) => ` ${line}`),
|
|
3009
|
+
""
|
|
3010
|
+
].join("\n")
|
|
3011
|
+
);
|
|
3012
|
+
return 0;
|
|
2826
3013
|
}
|
|
3014
|
+
|
|
3015
|
+
// src/commands/create.ts
|
|
2827
3016
|
function firstLine4(text) {
|
|
2828
3017
|
return text.split("\n").find((l) => l.trim() !== "")?.trim() ?? "unknown error";
|
|
2829
3018
|
}
|
|
2830
3019
|
function splitSpecs(list) {
|
|
2831
3020
|
return list.split(",").map((s) => s.trim()).filter((s) => s !== "");
|
|
2832
3021
|
}
|
|
2833
|
-
async function targetProblem(cwd, root, pm) {
|
|
2834
|
-
const shown = relative2(cwd, root) || ".";
|
|
2835
|
-
if (await insideWorkspace(cwd) || await insideWorkspace(dirname6(root)))
|
|
2836
|
-
return "already inside an rness workspace; create runs from outside one";
|
|
2837
|
-
if (!await exists(root)) return null;
|
|
2838
|
-
if (await exists(join15(root, ".rness", "rness.json"))) {
|
|
2839
|
-
if (!await exists(join15(root, ".rness", "node_modules")))
|
|
2840
|
-
return `${shown} holds an rness workspace whose dependencies are not installed; cd ${shown}/.rness && ${pm} install, then rness sync`;
|
|
2841
|
-
return `${shown} already holds an rness workspace (.rness/); run rness add inside it to add repositories`;
|
|
2842
|
-
}
|
|
2843
|
-
if (!(await stat3(root)).isDirectory()) return `${shown} is not a directory`;
|
|
2844
|
-
if (!await isEmptyDir(root)) return `${shown} is not empty`;
|
|
2845
|
-
return null;
|
|
2846
|
-
}
|
|
2847
3022
|
function cancelled(ui) {
|
|
2848
3023
|
ui.cancelled();
|
|
2849
3024
|
return 0;
|
|
@@ -2887,11 +3062,11 @@ async function pickRepositories(input) {
|
|
|
2887
3062
|
listed = listing.repositories;
|
|
2888
3063
|
if (listing.owner === "user")
|
|
2889
3064
|
ui.hint(
|
|
2890
|
-
`only public repositories of ${org} are listed; add private ones later with
|
|
3065
|
+
`only public repositories of ${org} are listed; add private ones later with ${rnessCommand()} add <repo>`
|
|
2891
3066
|
);
|
|
2892
3067
|
else if (!provider.authenticated)
|
|
2893
3068
|
ui.hint(
|
|
2894
|
-
|
|
3069
|
+
`only public repositories are listed; ${rnessCommand()} login lists the private ones you can access`
|
|
2895
3070
|
);
|
|
2896
3071
|
if (listing.truncated)
|
|
2897
3072
|
ui.hint(`listed the first ${MAX_PAGES * PER_PAGE} repositories of ${org}`);
|
|
@@ -2966,7 +3141,7 @@ async function cloneSelection(input) {
|
|
|
2966
3141
|
{ doing: `cloning org/${repo}`, git: true },
|
|
2967
3142
|
() => clone(
|
|
2968
3143
|
entry.url,
|
|
2969
|
-
|
|
3144
|
+
join17(input.root, "org", repo),
|
|
2970
3145
|
input.provider.credentialsFor(entry.url)
|
|
2971
3146
|
),
|
|
2972
3147
|
() => ["cloned", `org/${repo}`]
|
|
@@ -3006,6 +3181,25 @@ async function placeContext(staged, rnessDir, url, credentials) {
|
|
|
3006
3181
|
await clone(url, rnessDir, credentials);
|
|
3007
3182
|
}
|
|
3008
3183
|
}
|
|
3184
|
+
function blankConflict(opts) {
|
|
3185
|
+
if (opts.org !== void 0) return "--org";
|
|
3186
|
+
if (opts.repos !== void 0) return "--repos";
|
|
3187
|
+
if (opts.ssh === true) return "--ssh";
|
|
3188
|
+
if (opts.https === true) return "--https";
|
|
3189
|
+
if (opts.host !== void 0) return "--host";
|
|
3190
|
+
return null;
|
|
3191
|
+
}
|
|
3192
|
+
async function chooseStart(prompts) {
|
|
3193
|
+
const answer = await prompts.select({
|
|
3194
|
+
message: "How do you want to start?",
|
|
3195
|
+
options: [
|
|
3196
|
+
{ value: "github", label: "From a GitHub organization" },
|
|
3197
|
+
{ value: "blank", label: "Blank local workspace" }
|
|
3198
|
+
]
|
|
3199
|
+
});
|
|
3200
|
+
if (prompts.isCancel(answer)) return null;
|
|
3201
|
+
return answer === "blank" ? "blank" : "github";
|
|
3202
|
+
}
|
|
3009
3203
|
var OTHER = /* @__PURE__ */ Symbol("another organization");
|
|
3010
3204
|
async function chooseOrganization(provider, prompts) {
|
|
3011
3205
|
if (!provider.authenticated) return OTHER;
|
|
@@ -3082,6 +3276,19 @@ async function createCommand(opts, deps = {}) {
|
|
|
3082
3276
|
process.stderr.write("--ssh and --https cannot be combined\n");
|
|
3083
3277
|
return 2;
|
|
3084
3278
|
}
|
|
3279
|
+
if (opts.blank === true) {
|
|
3280
|
+
const clash = blankConflict(opts);
|
|
3281
|
+
if (clash !== null) {
|
|
3282
|
+
process.stderr.write(`--blank cannot be combined with ${clash}
|
|
3283
|
+
`);
|
|
3284
|
+
return 2;
|
|
3285
|
+
}
|
|
3286
|
+
if (opts.name !== void 0 && !WORKSPACE_NAME.test(opts.name)) {
|
|
3287
|
+
process.stderr.write(`${workspaceNameError(opts.name)}
|
|
3288
|
+
`);
|
|
3289
|
+
return 2;
|
|
3290
|
+
}
|
|
3291
|
+
}
|
|
3085
3292
|
if (opts.org !== void 0 && !ORG_NAME.test(opts.org)) {
|
|
3086
3293
|
process.stderr.write(
|
|
3087
3294
|
`organization name "${opts.org}" is not a valid GitHub organization name
|
|
@@ -3129,6 +3336,23 @@ async function createCommand(opts, deps = {}) {
|
|
|
3129
3336
|
);
|
|
3130
3337
|
return 1;
|
|
3131
3338
|
}
|
|
3339
|
+
let blank = opts.blank === true;
|
|
3340
|
+
if (!blank && interactive && opts.org === void 0 && opts.repos === void 0) {
|
|
3341
|
+
const start = await chooseStart(await prompts());
|
|
3342
|
+
if (start === null) return cancelled(ui);
|
|
3343
|
+
blank = start === "blank";
|
|
3344
|
+
}
|
|
3345
|
+
if (blank)
|
|
3346
|
+
return await createBlank({
|
|
3347
|
+
name: opts.name,
|
|
3348
|
+
cwd,
|
|
3349
|
+
pm,
|
|
3350
|
+
interactive,
|
|
3351
|
+
mayWrite: opts.yes === true || terminal.isTty(),
|
|
3352
|
+
skipInstall: opts.skipInstall === true,
|
|
3353
|
+
ui,
|
|
3354
|
+
prompts
|
|
3355
|
+
});
|
|
3132
3356
|
let prompted = false;
|
|
3133
3357
|
let org = opts.org;
|
|
3134
3358
|
if (org === void 0 && !interactive) {
|
|
@@ -3176,8 +3400,8 @@ async function createCommand(opts, deps = {}) {
|
|
|
3176
3400
|
org = answer.trim();
|
|
3177
3401
|
prompted = true;
|
|
3178
3402
|
}
|
|
3179
|
-
const root =
|
|
3180
|
-
const shown =
|
|
3403
|
+
const root = resolve4(cwd, org);
|
|
3404
|
+
const shown = relative4(cwd, root) || ".";
|
|
3181
3405
|
const problem = await targetProblem(cwd, root, pm);
|
|
3182
3406
|
if (problem !== null) {
|
|
3183
3407
|
process.stderr.write(`${problem}
|
|
@@ -3218,8 +3442,8 @@ async function createCommand(opts, deps = {}) {
|
|
|
3218
3442
|
);
|
|
3219
3443
|
let catalogue = { contract: 1, org, repos: {}, scopes: {} };
|
|
3220
3444
|
const staged = async () => {
|
|
3221
|
-
staging ??= await mkdtemp(
|
|
3222
|
-
return
|
|
3445
|
+
staging ??= await mkdtemp(join17(tmpdir(), "rness-join-"));
|
|
3446
|
+
return join17(staging, ".rness");
|
|
3223
3447
|
};
|
|
3224
3448
|
if (joining) {
|
|
3225
3449
|
const stagedDir = await staged();
|
|
@@ -3269,21 +3493,10 @@ async function createCommand(opts, deps = {}) {
|
|
|
3269
3493
|
});
|
|
3270
3494
|
if (p.isCancel(ok) || ok !== true) return cancelled(ui);
|
|
3271
3495
|
}
|
|
3272
|
-
const rnessDir =
|
|
3273
|
-
const install =
|
|
3274
|
-
if (opts.skipInstall === true) {
|
|
3275
|
-
ui.line("skipped", `install with ${pm} (--skip-install)`);
|
|
3276
|
-
return;
|
|
3277
|
-
}
|
|
3278
|
-
const frozen = await hasLockfile(rnessDir, pm);
|
|
3279
|
-
await ui.step(
|
|
3280
|
-
{ doing: `installing dependencies with ${pm}` },
|
|
3281
|
-
() => installDependencies(pm, rnessDir, { frozen }),
|
|
3282
|
-
() => ["installed", `dependencies with ${pm}`]
|
|
3283
|
-
);
|
|
3284
|
-
};
|
|
3496
|
+
const rnessDir = join17(root, ".rness");
|
|
3497
|
+
const install = () => installContext({ ui, pm, rnessDir, skip: opts.skipInstall === true });
|
|
3285
3498
|
if (joining) {
|
|
3286
|
-
await
|
|
3499
|
+
await mkdir5(root, { recursive: true });
|
|
3287
3500
|
await placeContext(
|
|
3288
3501
|
await staged(),
|
|
3289
3502
|
rnessDir,
|
|
@@ -3293,7 +3506,7 @@ async function createCommand(opts, deps = {}) {
|
|
|
3293
3506
|
ui.line("cloned", `${shown}/.rness (joined ${org})`);
|
|
3294
3507
|
if (opts.pm === void 0) pm = await workspacePackageManager(rnessDir);
|
|
3295
3508
|
await install();
|
|
3296
|
-
await
|
|
3509
|
+
await mkdir5(join17(root, "org"), { recursive: true });
|
|
3297
3510
|
const failures2 = await cloneSelection({
|
|
3298
3511
|
root,
|
|
3299
3512
|
rnessDir,
|
|
@@ -3316,15 +3529,18 @@ async function createCommand(opts, deps = {}) {
|
|
|
3316
3529
|
const remaining = Object.keys(catalogue.repos).filter(
|
|
3317
3530
|
(name2) => !cloned.has(name2)
|
|
3318
3531
|
);
|
|
3532
|
+
const rness2 = rnessCommand();
|
|
3319
3533
|
const next2 = [
|
|
3320
3534
|
`cd ${shown}`,
|
|
3321
3535
|
// The comment above its command, as the new-workspace note does: a
|
|
3322
3536
|
// line that wraps in a narrow terminal is a line nobody reads.
|
|
3323
3537
|
...remaining.length > 0 ? [
|
|
3324
3538
|
`# clone the catalogue repositories you did not pick: ${remaining.join(", ")}`,
|
|
3325
|
-
|
|
3539
|
+
`${rness2} sync --all`
|
|
3326
3540
|
] : [],
|
|
3327
|
-
...failures2.map(
|
|
3541
|
+
...failures2.map(
|
|
3542
|
+
(f) => `${rness2} add ${f.spec} # failed: ${f.message}`
|
|
3543
|
+
)
|
|
3328
3544
|
];
|
|
3329
3545
|
if (ui.session) ui.note("Next steps", next2);
|
|
3330
3546
|
else process.stdout.write(`
|
|
@@ -3333,30 +3549,17 @@ ${next2.map((l) => ` ${l}`).join("\n")}
|
|
|
3333
3549
|
ui.outro(`You joined ${org} \u2014 your workspace is in ${shown}/`);
|
|
3334
3550
|
return failures2.length > 0 ? 1 : 0;
|
|
3335
3551
|
}
|
|
3336
|
-
const
|
|
3337
|
-
|
|
3338
|
-
|
|
3339
|
-
|
|
3340
|
-
|
|
3341
|
-
|
|
3342
|
-
|
|
3343
|
-
|
|
3344
|
-
|
|
3345
|
-
|
|
3346
|
-
|
|
3347
|
-
reportError(e);
|
|
3348
|
-
await rm4(rnessDir, { recursive: true, force: true }).catch(
|
|
3349
|
-
() => void 0
|
|
3350
|
-
);
|
|
3351
|
-
if (await isEmptyDir(root).catch(() => false))
|
|
3352
|
-
await rm4(root, { recursive: true, force: true }).catch(() => void 0);
|
|
3353
|
-
process.stderr.write(
|
|
3354
|
-
`removed ${shown}/.rness after the failure; fix it and retry
|
|
3355
|
-
`
|
|
3356
|
-
);
|
|
3357
|
-
return 1;
|
|
3358
|
-
}
|
|
3359
|
-
await mkdir3(join15(root, "org"), { recursive: true });
|
|
3552
|
+
const built = await buildContext({
|
|
3553
|
+
ui,
|
|
3554
|
+
root,
|
|
3555
|
+
shown,
|
|
3556
|
+
manifest: catalogue,
|
|
3557
|
+
pm,
|
|
3558
|
+
skipInstall: opts.skipInstall === true,
|
|
3559
|
+
kind: "new workspace"
|
|
3560
|
+
});
|
|
3561
|
+
if (!built) return 1;
|
|
3562
|
+
await mkdir5(join17(root, "org"), { recursive: true });
|
|
3360
3563
|
const failures = await cloneSelection({
|
|
3361
3564
|
root,
|
|
3362
3565
|
rnessDir,
|
|
@@ -3367,15 +3570,7 @@ ${next2.map((l) => ` ${l}`).join("\n")}
|
|
|
3367
3570
|
provider: gitProvider,
|
|
3368
3571
|
ui
|
|
3369
3572
|
});
|
|
3370
|
-
await
|
|
3371
|
-
try {
|
|
3372
|
-
await commitAll(rnessDir, "chore: rness workspace context");
|
|
3373
|
-
ui.line("committed", `${shown}/.rness`);
|
|
3374
|
-
} catch (e) {
|
|
3375
|
-
ui.warn(
|
|
3376
|
-
`${e instanceof Error ? e.message : String(e)} \u2014 commit ${shown}/.rness yourself`
|
|
3377
|
-
);
|
|
3378
|
-
}
|
|
3573
|
+
await commitContext({ ui, rnessDir, shown });
|
|
3379
3574
|
const code = await syncBlocks(
|
|
3380
3575
|
ui,
|
|
3381
3576
|
root,
|
|
@@ -3394,11 +3589,12 @@ ${next2.map((l) => ` ${l}`).join("\n")}
|
|
|
3394
3589
|
url: contextUrl
|
|
3395
3590
|
}) : false;
|
|
3396
3591
|
if (published === null) return cancelled(ui);
|
|
3592
|
+
const rness = rnessCommand();
|
|
3397
3593
|
const next = [
|
|
3398
3594
|
`cd ${shown}/.rness`,
|
|
3399
3595
|
// What was asked for and did not happen, as the command that retries
|
|
3400
3596
|
// it — the workspace is complete otherwise.
|
|
3401
|
-
...failures.map((f) =>
|
|
3597
|
+
...failures.map((f) => `${rness} add ${f.spec} # failed: ${f.message}`),
|
|
3402
3598
|
...published ? [] : [
|
|
3403
3599
|
`# create the empty private repository ${org}/.rness on github.com, then:`,
|
|
3404
3600
|
`git remote add origin ${contextUrl} && git push -u origin main`,
|
|
@@ -3407,7 +3603,9 @@ ${next2.map((l) => ` ${l}`).join("\n")}
|
|
|
3407
3603
|
"# or, with the GitHub CLI (gh) installed, in one step:",
|
|
3408
3604
|
`gh repo create ${org}/.rness --private --source . --push`
|
|
3409
3605
|
],
|
|
3410
|
-
|
|
3606
|
+
// How this command was launched (npm when rness was typed directly),
|
|
3607
|
+
// whatever --pm installed with.
|
|
3608
|
+
`# then, for every teammate: ${detectPackageManager()} create rness ${org}`
|
|
3411
3609
|
];
|
|
3412
3610
|
if (ui.session) {
|
|
3413
3611
|
ui.note("Next steps", next);
|
|
@@ -3428,7 +3626,7 @@ ${next2.map((l) => ` ${l}`).join("\n")}
|
|
|
3428
3626
|
return reportError(e);
|
|
3429
3627
|
} finally {
|
|
3430
3628
|
if (staging !== void 0)
|
|
3431
|
-
await
|
|
3629
|
+
await rm5(staging, { recursive: true, force: true }).catch(() => void 0);
|
|
3432
3630
|
}
|
|
3433
3631
|
}
|
|
3434
3632
|
|
|
@@ -3462,8 +3660,8 @@ async function logoutCommand() {
|
|
|
3462
3660
|
|
|
3463
3661
|
// src/commands/upgrade.ts
|
|
3464
3662
|
import { execFile as execFile5 } from "child_process";
|
|
3465
|
-
import { mkdir as
|
|
3466
|
-
import { basename as basename5, dirname as dirname7, join as
|
|
3663
|
+
import { mkdir as mkdir6, readFile as readFile9, readdir as readdir3 } from "fs/promises";
|
|
3664
|
+
import { basename as basename5, dirname as dirname7, join as join18, relative as relative5 } from "path";
|
|
3467
3665
|
import { promisify as promisify5 } from "util";
|
|
3468
3666
|
var execFileP5 = promisify5(execFile5);
|
|
3469
3667
|
var NOTES = "https://github.com/rness-dev/rness/tree/main/packages/cli#readme";
|
|
@@ -3497,7 +3695,7 @@ async function upgradeCommand(version, opts, terminal = defaultTerminal) {
|
|
|
3497
3695
|
const pin = await readPin(ws.rnessDir);
|
|
3498
3696
|
if (pin === null) {
|
|
3499
3697
|
process.stderr.write(
|
|
3500
|
-
`no @rness/cli entry in ${label}/package.json; add it to devDependencies, then run
|
|
3698
|
+
`no @rness/cli entry in ${label}/package.json; add it to devDependencies, then run ${rnessCommand()} upgrade
|
|
3501
3699
|
`
|
|
3502
3700
|
);
|
|
3503
3701
|
return 1;
|
|
@@ -3518,7 +3716,8 @@ async function upgradeCommand(version, opts, terminal = defaultTerminal) {
|
|
|
3518
3716
|
);
|
|
3519
3717
|
if (target === null) {
|
|
3520
3718
|
process.stderr.write(
|
|
3521
|
-
|
|
3719
|
+
`cannot reach the registry; name the version: ${rnessCommand()} upgrade <version>
|
|
3720
|
+
`
|
|
3522
3721
|
);
|
|
3523
3722
|
return 1;
|
|
3524
3723
|
}
|
|
@@ -3532,7 +3731,7 @@ async function upgradeCommand(version, opts, terminal = defaultTerminal) {
|
|
|
3532
3731
|
const downgrading = EXACT_VERSION.test(pin.spec) && compareVersions(target, pin.spec) < 0;
|
|
3533
3732
|
if (downgrading && version === void 0) {
|
|
3534
3733
|
process.stderr.write(
|
|
3535
|
-
`${label} pins @rness/cli ${pin.spec}, newer than the latest release ${target}; to downgrade:
|
|
3734
|
+
`${label} pins @rness/cli ${pin.spec}, newer than the latest release ${target}; to downgrade: ${rnessCommand()} upgrade ${target}
|
|
3536
3735
|
`
|
|
3537
3736
|
);
|
|
3538
3737
|
return 1;
|
|
@@ -3560,15 +3759,15 @@ async function upgradeCommand(version, opts, terminal = defaultTerminal) {
|
|
|
3560
3759
|
return 1;
|
|
3561
3760
|
}
|
|
3562
3761
|
}
|
|
3563
|
-
const packageFile =
|
|
3762
|
+
const packageFile = join18(ws.rnessDir, "package.json");
|
|
3564
3763
|
const restore = /* @__PURE__ */ new Map([
|
|
3565
3764
|
[packageFile, await readFile9(packageFile, "utf8")]
|
|
3566
3765
|
]);
|
|
3567
3766
|
if (pin.spec !== target) await writePin(ws.rnessDir, pin.spec, target);
|
|
3568
|
-
const workflows =
|
|
3767
|
+
const workflows = join18(ws.rnessDir, ".github", "workflows");
|
|
3569
3768
|
for (const name of await readdir3(workflows).catch(() => [])) {
|
|
3570
3769
|
if (!/\.ya?ml$/.test(name)) continue;
|
|
3571
|
-
const file =
|
|
3770
|
+
const file = join18(workflows, name);
|
|
3572
3771
|
const text = await readOrNull(file);
|
|
3573
3772
|
if (text === null) continue;
|
|
3574
3773
|
const shown = `.github/workflows/${name}`;
|
|
@@ -3586,14 +3785,14 @@ async function upgradeCommand(version, opts, terminal = defaultTerminal) {
|
|
|
3586
3785
|
ui.warn(`${shown} names @rness/cli@${pin.spec}; update it by hand`);
|
|
3587
3786
|
}
|
|
3588
3787
|
}
|
|
3589
|
-
const dependabot =
|
|
3788
|
+
const dependabot = join18(ws.rnessDir, ".github", "dependabot.yml");
|
|
3590
3789
|
if (await exists(dependabot)) {
|
|
3591
3790
|
ui.hint(".github/dependabot.yml is already there \u2014 left as it is");
|
|
3592
3791
|
} else {
|
|
3593
|
-
await
|
|
3792
|
+
await mkdir6(dirname7(dependabot), { recursive: true });
|
|
3594
3793
|
await writeFileAtomic(
|
|
3595
3794
|
dependabot,
|
|
3596
|
-
await readFile9(
|
|
3795
|
+
await readFile9(join18(scaffoldDir(), ".github", "dependabot.yml"), "utf8")
|
|
3597
3796
|
);
|
|
3598
3797
|
ui.line(
|
|
3599
3798
|
"wrote",
|
|
@@ -3610,7 +3809,7 @@ async function upgradeCommand(version, opts, terminal = defaultTerminal) {
|
|
|
3610
3809
|
for (const [file, text] of restore) await writeFileAtomic(file, text);
|
|
3611
3810
|
const message = e instanceof Error ? e.message : String(e);
|
|
3612
3811
|
ui.error(message);
|
|
3613
|
-
ui.hint(`restored ${
|
|
3812
|
+
ui.hint(`restored ${relative5(cwd, packageFile) || packageFile}`, "stderr");
|
|
3614
3813
|
if (/minimum.?release.?age|NO_MATURE/i.test(message))
|
|
3615
3814
|
ui.hint(
|
|
3616
3815
|
"pnpm refuses versions published less than 24 h ago: add '@rness/cli' under minimumReleaseAgeExclude in .rness/pnpm-workspace.yaml",
|
|
@@ -3629,7 +3828,7 @@ async function upgradeCommand(version, opts, terminal = defaultTerminal) {
|
|
|
3629
3828
|
ui.gitIsSilent = true;
|
|
3630
3829
|
const code = await syncBlocks(ui, ws.root, basename5(ws.root));
|
|
3631
3830
|
if (code !== 0) return code;
|
|
3632
|
-
const rel =
|
|
3831
|
+
const rel = relative5(cwd, ws.rnessDir) || ".";
|
|
3633
3832
|
const next = [
|
|
3634
3833
|
`git -C ${rel} add -A && git -C ${rel} commit -m "chore: rness ${target}"`,
|
|
3635
3834
|
"# teammates: git pull \u2014 the next rness command installs it"
|
|
@@ -3655,7 +3854,7 @@ async function upgradeCommand(version, opts, terminal = defaultTerminal) {
|
|
|
3655
3854
|
}
|
|
3656
3855
|
|
|
3657
3856
|
// src/core/blocks.ts
|
|
3658
|
-
import { join as
|
|
3857
|
+
import { join as join19 } from "path";
|
|
3659
3858
|
var PROBLEM = /* @__PURE__ */ new Set(["stale", "malformed"]);
|
|
3660
3859
|
async function checkBlocks({
|
|
3661
3860
|
root,
|
|
@@ -3672,13 +3871,13 @@ async function checkBlocks({
|
|
|
3672
3871
|
warnings: checks.filter((c) => !PROBLEM.has(c.status) && c.message !== null).map((c) => c.message),
|
|
3673
3872
|
checks
|
|
3674
3873
|
});
|
|
3675
|
-
if (!await exists(
|
|
3874
|
+
if (!await exists(join19(root, "org"))) return derive();
|
|
3676
3875
|
const targets = [{ scope: null, dir: root, depth: 0, label: "AGENTS.md" }];
|
|
3677
3876
|
for (const [name, entry] of Object.entries(manifest.scopes)) {
|
|
3678
3877
|
const segments = entry.path.split("/");
|
|
3679
3878
|
targets.push({
|
|
3680
3879
|
scope: name,
|
|
3681
|
-
dir:
|
|
3880
|
+
dir: join19(root, ...segments),
|
|
3682
3881
|
depth: segments.length,
|
|
3683
3882
|
label: `${entry.path}/AGENTS.md`
|
|
3684
3883
|
});
|
|
@@ -3692,14 +3891,14 @@ async function checkBlocks({
|
|
|
3692
3891
|
);
|
|
3693
3892
|
continue;
|
|
3694
3893
|
}
|
|
3695
|
-
const text = await readOrNull(
|
|
3894
|
+
const text = await readOrNull(join19(t.dir, "AGENTS.md"));
|
|
3696
3895
|
const lines = text === null ? [] : text.split(/\r?\n/);
|
|
3697
3896
|
const found = findBlock(lines);
|
|
3698
3897
|
if (found.kind === "none") {
|
|
3699
3898
|
note(
|
|
3700
3899
|
t.label,
|
|
3701
3900
|
"no-block",
|
|
3702
|
-
`${t.label}: no rness block yet (run
|
|
3901
|
+
`${t.label}: no rness block yet (run ${rnessCommand()} sync)`
|
|
3703
3902
|
);
|
|
3704
3903
|
continue;
|
|
3705
3904
|
}
|
|
@@ -3721,13 +3920,17 @@ async function checkBlocks({
|
|
|
3721
3920
|
if (isCurrentBlock(lines.slice(found.begin, found.end + 1), fresh2.hash))
|
|
3722
3921
|
note(t.label, "current");
|
|
3723
3922
|
else
|
|
3724
|
-
note(
|
|
3923
|
+
note(
|
|
3924
|
+
t.label,
|
|
3925
|
+
"stale",
|
|
3926
|
+
`${t.label}: stale rness block (run ${rnessCommand()} sync)`
|
|
3927
|
+
);
|
|
3725
3928
|
}
|
|
3726
3929
|
return derive();
|
|
3727
3930
|
}
|
|
3728
3931
|
|
|
3729
3932
|
// src/core/contract.ts
|
|
3730
|
-
import { join as
|
|
3933
|
+
import { join as join20 } from "path";
|
|
3731
3934
|
var STATUSES = {
|
|
3732
3935
|
adr: ["Proposed", "Accepted", "Rejected", "Superseded"],
|
|
3733
3936
|
specs: [
|
|
@@ -3746,7 +3949,7 @@ async function checkContract(rnessDir) {
|
|
|
3746
3949
|
const problems = [];
|
|
3747
3950
|
for (const name of COLLECTIONS) {
|
|
3748
3951
|
const allowed = STATUSES[name];
|
|
3749
|
-
const items = await collectMarkdown(
|
|
3952
|
+
const items = await collectMarkdown(join20(rnessDir, name));
|
|
3750
3953
|
for (const item of items) {
|
|
3751
3954
|
const where = `${name}/${item.rel}`;
|
|
3752
3955
|
if (SKIP.has(where)) continue;
|
|
@@ -3789,8 +3992,7 @@ async function validateCommand(opts, deps = {}) {
|
|
|
3789
3992
|
const ws = await findWorkspace(cwd);
|
|
3790
3993
|
const manifest = await loadManifest(ws.rnessDir);
|
|
3791
3994
|
for (const s of Object.keys(manifest.scopes)) scopeChain(manifest, s);
|
|
3792
|
-
const
|
|
3793
|
-
const warnings = warning === null ? [] : [warning];
|
|
3995
|
+
const org = workspaceName(manifest, ws.root);
|
|
3794
3996
|
const problems = await checkContract(ws.rnessDir);
|
|
3795
3997
|
const blocks = await checkBlocks({
|
|
3796
3998
|
root: ws.root,
|
|
@@ -3799,12 +4001,11 @@ async function validateCommand(opts, deps = {}) {
|
|
|
3799
4001
|
org
|
|
3800
4002
|
});
|
|
3801
4003
|
problems.push(...blocks.problems);
|
|
3802
|
-
warnings.push(...blocks.warnings);
|
|
3803
4004
|
const ui = await makeUi(deps.terminal ?? defaultTerminal);
|
|
3804
4005
|
if (!ui.session) {
|
|
3805
4006
|
for (const p of problems) process.stderr.write(`${p}
|
|
3806
4007
|
`);
|
|
3807
|
-
for (const w of warnings) process.stderr.write(`${warn(w)}
|
|
4008
|
+
for (const w of blocks.warnings) process.stderr.write(`${warn(w)}
|
|
3808
4009
|
`);
|
|
3809
4010
|
if (problems.length > 0) return 1;
|
|
3810
4011
|
process.stdout.write("context ok\n");
|
|
@@ -3817,7 +4018,6 @@ async function validateCommand(opts, deps = {}) {
|
|
|
3817
4018
|
ui.error(c.message);
|
|
3818
4019
|
else ui.warn(c.message);
|
|
3819
4020
|
for (const p of problems) if (!blocks.problems.includes(p)) ui.error(p);
|
|
3820
|
-
for (const w of warnings) if (!blocks.warnings.includes(w)) ui.warn(w);
|
|
3821
4021
|
ui.outro(
|
|
3822
4022
|
problems.length > 0 ? "Context mismatch" : "Context OK",
|
|
3823
4023
|
problems.length > 0 ? "error" : "done"
|
|
@@ -3920,8 +4120,11 @@ function buildProgram(state) {
|
|
|
3920
4120
|
state.code = await upgradeCommand(version, opts);
|
|
3921
4121
|
});
|
|
3922
4122
|
program.command("create").description(
|
|
3923
|
-
"Create
|
|
3924
|
-
).argument(
|
|
4123
|
+
"Create or join a GitHub organization's workspace, or a blank one with --blank"
|
|
4124
|
+
).argument(
|
|
4125
|
+
"[name]",
|
|
4126
|
+
"the GitHub organization, same as --org; with --blank, the workspace directory"
|
|
4127
|
+
).option(
|
|
3925
4128
|
"--org <name>",
|
|
3926
4129
|
"the GitHub organization, exact name (github.com/<name>)"
|
|
3927
4130
|
).option(
|
|
@@ -3933,7 +4136,16 @@ function buildProgram(state) {
|
|
|
3933
4136
|
).option(
|
|
3934
4137
|
"--ssh",
|
|
3935
4138
|
"force git@github.com: (default: SSH when it works, else HTTPS)"
|
|
3936
|
-
).option("--https", "force https://github.com/").option(
|
|
4139
|
+
).option("--https", "force https://github.com/").option(
|
|
4140
|
+
"--blank",
|
|
4141
|
+
"a local workspace with no GitHub organization: .rness/, an empty org/, the root files"
|
|
4142
|
+
).option("--skip-install", "do not install .rness/ dependencies").option("-y, --yes", "do not ask for confirmation").option("--template <name>", "reserved").addOption(new Option("--host <base>").hideHelp()).addOption(new Option("--github-api <base>").hideHelp()).addOption(new Option("--cwd <dir>").hideHelp()).action(async (orgArg, opts) => {
|
|
4143
|
+
if (opts.blank === true) {
|
|
4144
|
+
state.code = await createCommand(
|
|
4145
|
+
orgArg === void 0 ? opts : { ...opts, name: orgArg }
|
|
4146
|
+
);
|
|
4147
|
+
return;
|
|
4148
|
+
}
|
|
3937
4149
|
if (orgArg !== void 0 && opts.org !== void 0 && orgArg !== opts.org) {
|
|
3938
4150
|
process.stderr.write(
|
|
3939
4151
|
`organization given twice: "${orgArg}" and --org "${opts.org}"
|
|
@@ -4016,6 +4228,11 @@ export {
|
|
|
4016
4228
|
exists,
|
|
4017
4229
|
readOrNull,
|
|
4018
4230
|
writeFileAtomic,
|
|
4231
|
+
PACKAGE_MANAGERS,
|
|
4232
|
+
isPackageManager,
|
|
4233
|
+
detectPackageManager,
|
|
4234
|
+
packageManagerVersion,
|
|
4235
|
+
installDependencies,
|
|
4019
4236
|
GitHubOAuthProvider,
|
|
4020
4237
|
githubProvider,
|
|
4021
4238
|
DEFAULT_HOST,
|
|
@@ -4058,16 +4275,11 @@ export {
|
|
|
4058
4275
|
addCommand,
|
|
4059
4276
|
renderMarkdown,
|
|
4060
4277
|
contextCommand,
|
|
4278
|
+
VERSION,
|
|
4061
4279
|
findDelegate,
|
|
4062
|
-
PACKAGE_MANAGERS,
|
|
4063
|
-
isPackageManager,
|
|
4064
|
-
detectPackageManager,
|
|
4065
|
-
packageManagerVersion,
|
|
4066
|
-
installDependencies,
|
|
4067
4280
|
SCAFFOLD_FILES,
|
|
4068
4281
|
scaffoldDir,
|
|
4069
4282
|
copyScaffold,
|
|
4070
|
-
VERSION,
|
|
4071
4283
|
loginCommand,
|
|
4072
4284
|
createCommand,
|
|
4073
4285
|
logoutCommand,
|
|
@@ -4080,4 +4292,4 @@ export {
|
|
|
4080
4292
|
OWN_COMMANDS,
|
|
4081
4293
|
catchUp
|
|
4082
4294
|
};
|
|
4083
|
-
//# sourceMappingURL=chunk-
|
|
4295
|
+
//# sourceMappingURL=chunk-YAIZOFYV.js.map
|