@rness/cli 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -11
- package/dist/bin/rness.js +1 -1
- package/dist/{chunk-VYP4L7BQ.js → chunk-VQMX52HT.js} +391 -127
- package/dist/chunk-VQMX52HT.js.map +1 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-VYP4L7BQ.js.map +0 -1
|
@@ -797,7 +797,7 @@ function classifyProbe(url, exitCode, stderr) {
|
|
|
797
797
|
var STDERR_FLUSH_MS = 200;
|
|
798
798
|
async function probeRemote(url, timeoutMs = 6e4, credentials) {
|
|
799
799
|
positional(url, "repository url");
|
|
800
|
-
return new Promise((
|
|
800
|
+
return new Promise((resolve6) => {
|
|
801
801
|
const auth = withCredentials(credentials);
|
|
802
802
|
const child = spawn(
|
|
803
803
|
"git",
|
|
@@ -816,7 +816,7 @@ async function probeRemote(url, timeoutMs = 6e4, credentials) {
|
|
|
816
816
|
settled = true;
|
|
817
817
|
clearTimeout(timer);
|
|
818
818
|
child.stderr?.destroy();
|
|
819
|
-
|
|
819
|
+
resolve6(probe);
|
|
820
820
|
};
|
|
821
821
|
const timer = setTimeout(() => {
|
|
822
822
|
child.kill("SIGKILL");
|
|
@@ -827,14 +827,14 @@ async function probeRemote(url, timeoutMs = 6e4, credentials) {
|
|
|
827
827
|
}, timeoutMs);
|
|
828
828
|
child.on("error", (e) => settle(classifyProbe(url, 1, e.message)));
|
|
829
829
|
child.on("exit", (code) => {
|
|
830
|
-
const
|
|
830
|
+
const finish2 = () => settle(classifyProbe(url, code ?? 1, chunks.join("")));
|
|
831
831
|
const stderr = child.stderr;
|
|
832
832
|
if (stderr === null || stderr.readableEnded || stderr.destroyed)
|
|
833
|
-
return
|
|
834
|
-
const flush = setTimeout(
|
|
833
|
+
return finish2();
|
|
834
|
+
const flush = setTimeout(finish2, STDERR_FLUSH_MS);
|
|
835
835
|
const done = () => {
|
|
836
836
|
clearTimeout(flush);
|
|
837
|
-
|
|
837
|
+
finish2();
|
|
838
838
|
};
|
|
839
839
|
stderr.once("end", done);
|
|
840
840
|
stderr.once("error", done);
|
|
@@ -1248,7 +1248,7 @@ async function detectGithubSsh(opts) {
|
|
|
1248
1248
|
...opts.interactive ? [] : ["-o", "BatchMode=yes"],
|
|
1249
1249
|
"git@github.com"
|
|
1250
1250
|
];
|
|
1251
|
-
return new Promise((
|
|
1251
|
+
return new Promise((resolve6) => {
|
|
1252
1252
|
const child = spawn2(opts.command ?? "ssh", args, {
|
|
1253
1253
|
stdio: [opts.interactive ? "inherit" : "ignore", "ignore", "pipe"]
|
|
1254
1254
|
});
|
|
@@ -1261,7 +1261,7 @@ async function detectGithubSsh(opts) {
|
|
|
1261
1261
|
settled = true;
|
|
1262
1262
|
clearTimeout(timer);
|
|
1263
1263
|
child.stderr?.destroy();
|
|
1264
|
-
|
|
1264
|
+
resolve6(access2);
|
|
1265
1265
|
};
|
|
1266
1266
|
const timer = setTimeout(() => {
|
|
1267
1267
|
child.kill("SIGKILL");
|
|
@@ -1269,7 +1269,7 @@ async function detectGithubSsh(opts) {
|
|
|
1269
1269
|
}, timeoutMs);
|
|
1270
1270
|
child.on("error", (e) => settle({ ok: false, reason: e.message }));
|
|
1271
1271
|
child.on("exit", (code) => {
|
|
1272
|
-
const
|
|
1272
|
+
const finish2 = () => {
|
|
1273
1273
|
const stderr2 = chunks.join("");
|
|
1274
1274
|
const login = parseSshGreeting(stderr2);
|
|
1275
1275
|
settle(
|
|
@@ -1281,11 +1281,11 @@ async function detectGithubSsh(opts) {
|
|
|
1281
1281
|
};
|
|
1282
1282
|
const stderr = child.stderr;
|
|
1283
1283
|
if (stderr === null || stderr.readableEnded || stderr.destroyed)
|
|
1284
|
-
return
|
|
1285
|
-
const flush = setTimeout(
|
|
1284
|
+
return finish2();
|
|
1285
|
+
const flush = setTimeout(finish2, STDERR_FLUSH_MS2);
|
|
1286
1286
|
const done = () => {
|
|
1287
1287
|
clearTimeout(flush);
|
|
1288
|
-
|
|
1288
|
+
finish2();
|
|
1289
1289
|
};
|
|
1290
1290
|
stderr.once("end", done);
|
|
1291
1291
|
stderr.once("error", done);
|
|
@@ -1390,7 +1390,7 @@ function reportError(e) {
|
|
|
1390
1390
|
}
|
|
1391
1391
|
|
|
1392
1392
|
// src/version.ts
|
|
1393
|
-
var VERSION = "0.
|
|
1393
|
+
var VERSION = "0.8.0";
|
|
1394
1394
|
|
|
1395
1395
|
// src/core/block.ts
|
|
1396
1396
|
import { createHash } from "crypto";
|
|
@@ -2030,12 +2030,12 @@ function sessionUi(p) {
|
|
|
2030
2030
|
},
|
|
2031
2031
|
async step(options, work, done) {
|
|
2032
2032
|
const label = options.sentence ?? tidy(options.doing);
|
|
2033
|
-
const
|
|
2033
|
+
const finish2 = (result) => done?.(result) ?? null;
|
|
2034
2034
|
const label_ = (line) => `${line[1]} ${line[0]}`;
|
|
2035
2035
|
if (options.git === true && !this.gitIsSilent) {
|
|
2036
2036
|
p.log.message(paint("idle", `${label}\u2026`));
|
|
2037
2037
|
const result = await work();
|
|
2038
|
-
const line =
|
|
2038
|
+
const line = finish2(result);
|
|
2039
2039
|
if (line !== null) say(line[0], label_(line));
|
|
2040
2040
|
return result;
|
|
2041
2041
|
}
|
|
@@ -2043,7 +2043,7 @@ function sessionUi(p) {
|
|
|
2043
2043
|
spin.start(label);
|
|
2044
2044
|
try {
|
|
2045
2045
|
const result = await work();
|
|
2046
|
-
const line =
|
|
2046
|
+
const line = finish2(result);
|
|
2047
2047
|
spin.stop(line === null ? label : label_(line));
|
|
2048
2048
|
return result;
|
|
2049
2049
|
} catch (e) {
|
|
@@ -2710,21 +2710,29 @@ function scaffoldDir() {
|
|
|
2710
2710
|
import { chmod as chmod2, mkdir as mkdir3, readFile as readFile7, stat as stat2, writeFile as writeFile2 } from "fs/promises";
|
|
2711
2711
|
import { dirname as dirname6, join as join14 } from "path";
|
|
2712
2712
|
var TOKENISED = /* @__PURE__ */ new Set(["package.json"]);
|
|
2713
|
-
async function
|
|
2714
|
-
const
|
|
2713
|
+
async function renderScaffold(source, tokens) {
|
|
2714
|
+
const files = [];
|
|
2715
2715
|
for (const rel of SCAFFOLD_FILES) {
|
|
2716
2716
|
if (rel === "rness.json") continue;
|
|
2717
2717
|
const from = join14(source, ...rel.split("/"));
|
|
2718
|
-
const targetRel = rel === "_gitignore" ? ".gitignore" : rel;
|
|
2719
|
-
const to = join14(dest, ...targetRel.split("/"));
|
|
2720
|
-
await mkdir3(dirname6(to), { recursive: true });
|
|
2721
2718
|
let content = await readFile7(from, "utf8");
|
|
2722
2719
|
if (TOKENISED.has(rel)) {
|
|
2723
2720
|
content = content.replaceAll("__RNESS_VERSION__", tokens.version).replaceAll("__RNESS_PM__", tokens.packageManager);
|
|
2724
2721
|
}
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2722
|
+
files.push({
|
|
2723
|
+
path: rel === "_gitignore" ? ".gitignore" : rel,
|
|
2724
|
+
content,
|
|
2725
|
+
executable: ((await stat2(from)).mode & 73) !== 0
|
|
2726
|
+
});
|
|
2727
|
+
}
|
|
2728
|
+
return files;
|
|
2729
|
+
}
|
|
2730
|
+
async function copyScaffold(dest, tokens) {
|
|
2731
|
+
for (const file of await renderScaffold(scaffoldDir(), tokens)) {
|
|
2732
|
+
const to = join14(dest, ...file.path.split("/"));
|
|
2733
|
+
await mkdir3(dirname6(to), { recursive: true });
|
|
2734
|
+
await writeFile2(to, file.content, "utf8");
|
|
2735
|
+
if (file.executable) await chmod2(to, 493);
|
|
2728
2736
|
}
|
|
2729
2737
|
}
|
|
2730
2738
|
|
|
@@ -2878,13 +2886,13 @@ function revokeUrl() {
|
|
|
2878
2886
|
}
|
|
2879
2887
|
|
|
2880
2888
|
// src/commands/create.ts
|
|
2881
|
-
import { mkdir as mkdir6, mkdtemp, rename as rename2, rm as
|
|
2882
|
-
import { tmpdir } from "os";
|
|
2883
|
-
import { join as
|
|
2889
|
+
import { mkdir as mkdir6, mkdtemp as mkdtemp2, rename as rename2, rm as rm6 } from "fs/promises";
|
|
2890
|
+
import { tmpdir as tmpdir2 } from "os";
|
|
2891
|
+
import { join as join19, relative as relative4, resolve as resolve5 } from "path";
|
|
2884
2892
|
|
|
2885
2893
|
// src/core/new-workspace.ts
|
|
2886
|
-
import { mkdir as mkdir4, readdir as readdir2, rm as
|
|
2887
|
-
import { dirname as
|
|
2894
|
+
import { mkdir as mkdir4, readdir as readdir2, rm as rm5, stat as stat3 } from "fs/promises";
|
|
2895
|
+
import { dirname as dirname8, join as join17, relative as relative2 } from "path";
|
|
2888
2896
|
|
|
2889
2897
|
// src/core/pinned.ts
|
|
2890
2898
|
import { execFile as execFile4 } from "child_process";
|
|
@@ -3124,6 +3132,166 @@ async function syncPinned(root, shown, fallback) {
|
|
|
3124
3132
|
}
|
|
3125
3133
|
}
|
|
3126
3134
|
|
|
3135
|
+
// src/core/scaffold-git.ts
|
|
3136
|
+
import { execFile as execFile5 } from "child_process";
|
|
3137
|
+
import { mkdtemp, realpath as realpath2, rm as rm4, writeFile as writeFile3 } from "fs/promises";
|
|
3138
|
+
import { tmpdir } from "os";
|
|
3139
|
+
import { dirname as dirname7, join as join16, resolve as resolve3 } from "path";
|
|
3140
|
+
import { promisify as promisify5 } from "util";
|
|
3141
|
+
var execFileP5 = promisify5(execFile5);
|
|
3142
|
+
var CREATE_SUBJECT = "chore: rness workspace context";
|
|
3143
|
+
var SCAFFOLD_SUBJECT = /^chore: rness scaffold (\S+)$/;
|
|
3144
|
+
var SCAFFOLD_TRAILER = "Rness-Scaffold";
|
|
3145
|
+
async function run(dir, args, env = {}) {
|
|
3146
|
+
try {
|
|
3147
|
+
const { stdout, stderr } = await execFileP5("git", [...args], {
|
|
3148
|
+
cwd: dir,
|
|
3149
|
+
env: {
|
|
3150
|
+
...process.env,
|
|
3151
|
+
...env,
|
|
3152
|
+
GIT_TERMINAL_PROMPT: "0",
|
|
3153
|
+
GIT_CEILING_DIRECTORIES: dirname7(resolve3(dir))
|
|
3154
|
+
},
|
|
3155
|
+
maxBuffer: 16 * 1024 * 1024
|
|
3156
|
+
});
|
|
3157
|
+
return { code: 0, stdout, stderr };
|
|
3158
|
+
} catch (e) {
|
|
3159
|
+
const err = e;
|
|
3160
|
+
return {
|
|
3161
|
+
code: typeof err.code === "number" ? err.code : 1,
|
|
3162
|
+
stdout: err.stdout ?? "",
|
|
3163
|
+
stderr: err.stderr ?? String(e)
|
|
3164
|
+
};
|
|
3165
|
+
}
|
|
3166
|
+
}
|
|
3167
|
+
async function must(dir, args, env = {}) {
|
|
3168
|
+
const r = await run(dir, args, env);
|
|
3169
|
+
if (r.code !== 0) {
|
|
3170
|
+
const first = r.stderr.split("\n").find((l) => l.trim() !== "") ?? "unknown error";
|
|
3171
|
+
throw new Error(`git ${args[0] ?? ""} failed: ${first.trim()}`);
|
|
3172
|
+
}
|
|
3173
|
+
return r.stdout.trim();
|
|
3174
|
+
}
|
|
3175
|
+
function scaffoldMessage(subject, version) {
|
|
3176
|
+
return `${subject}
|
|
3177
|
+
|
|
3178
|
+
${SCAFFOLD_TRAILER}: ${version}`;
|
|
3179
|
+
}
|
|
3180
|
+
async function findScaffoldBase(rnessDir) {
|
|
3181
|
+
const log = await run(rnessDir, [
|
|
3182
|
+
"log",
|
|
3183
|
+
"--topo-order",
|
|
3184
|
+
`--format=%H%x1f%P%x1f%s%x1f%(trailers:key=${SCAFFOLD_TRAILER},valueonly,separator=%x2C)%x1e`,
|
|
3185
|
+
"HEAD"
|
|
3186
|
+
]);
|
|
3187
|
+
if (log.code !== 0) return null;
|
|
3188
|
+
const commits = log.stdout.split("").map((r) => r.trim()).filter((r) => r !== "").map((r) => {
|
|
3189
|
+
const [hash = "", parents = "", subject = "", trailer = ""] = r.split("");
|
|
3190
|
+
return { hash, parents: parents.trim(), subject, trailer: trailer.trim() };
|
|
3191
|
+
});
|
|
3192
|
+
for (const c of commits) {
|
|
3193
|
+
const m = SCAFFOLD_SUBJECT.exec(c.subject);
|
|
3194
|
+
if (m !== null) return { commit: c.hash, version: m[1] ?? null };
|
|
3195
|
+
}
|
|
3196
|
+
const root = commits.find(
|
|
3197
|
+
(c) => c.parents === "" && c.subject === CREATE_SUBJECT
|
|
3198
|
+
);
|
|
3199
|
+
if (root === void 0) return null;
|
|
3200
|
+
return {
|
|
3201
|
+
commit: root.hash,
|
|
3202
|
+
version: root.trailer === "" ? null : root.trailer
|
|
3203
|
+
};
|
|
3204
|
+
}
|
|
3205
|
+
async function buildScaffoldCommit(rnessDir, base, files, version) {
|
|
3206
|
+
const scratch = await mkdtemp(join16(tmpdir(), "rness-scaffold-"));
|
|
3207
|
+
const env = { GIT_INDEX_FILE: join16(scratch, "index") };
|
|
3208
|
+
try {
|
|
3209
|
+
await must(
|
|
3210
|
+
rnessDir,
|
|
3211
|
+
["read-tree", ...base === null ? ["--empty"] : [base]],
|
|
3212
|
+
env
|
|
3213
|
+
);
|
|
3214
|
+
for (const [i, file] of files.entries()) {
|
|
3215
|
+
const tmp = join16(scratch, `blob-${i}`);
|
|
3216
|
+
await writeFile3(tmp, file.content, "utf8");
|
|
3217
|
+
const blob = await must(rnessDir, [
|
|
3218
|
+
"hash-object",
|
|
3219
|
+
"-w",
|
|
3220
|
+
"--no-filters",
|
|
3221
|
+
"--",
|
|
3222
|
+
tmp
|
|
3223
|
+
]);
|
|
3224
|
+
await must(
|
|
3225
|
+
rnessDir,
|
|
3226
|
+
[
|
|
3227
|
+
"update-index",
|
|
3228
|
+
"--add",
|
|
3229
|
+
"--cacheinfo",
|
|
3230
|
+
`${file.executable ? "100755" : "100644"},${blob},${file.path}`
|
|
3231
|
+
],
|
|
3232
|
+
env
|
|
3233
|
+
);
|
|
3234
|
+
}
|
|
3235
|
+
const tree = await must(rnessDir, ["write-tree"], env);
|
|
3236
|
+
return await must(rnessDir, [
|
|
3237
|
+
"commit-tree",
|
|
3238
|
+
tree,
|
|
3239
|
+
...base === null ? [] : ["-p", base],
|
|
3240
|
+
"-m",
|
|
3241
|
+
scaffoldMessage(`chore: rness scaffold ${version}`, version)
|
|
3242
|
+
]);
|
|
3243
|
+
} finally {
|
|
3244
|
+
await rm4(scratch, { recursive: true, force: true });
|
|
3245
|
+
}
|
|
3246
|
+
}
|
|
3247
|
+
async function blobAt(rnessDir, rev, path) {
|
|
3248
|
+
const r = await run(rnessDir, [
|
|
3249
|
+
"rev-parse",
|
|
3250
|
+
"--verify",
|
|
3251
|
+
"--quiet",
|
|
3252
|
+
`${rev}:${path}`
|
|
3253
|
+
]);
|
|
3254
|
+
return r.code === 0 ? r.stdout.trim() : null;
|
|
3255
|
+
}
|
|
3256
|
+
async function mergeScaffold(rnessDir, commit, base) {
|
|
3257
|
+
await run(rnessDir, [
|
|
3258
|
+
"merge",
|
|
3259
|
+
"--no-commit",
|
|
3260
|
+
"--no-ff",
|
|
3261
|
+
...base === null ? ["--allow-unrelated-histories"] : [],
|
|
3262
|
+
commit
|
|
3263
|
+
]);
|
|
3264
|
+
const conflicts = (await must(rnessDir, ["diff", "--name-only", "--diff-filter=U"])).split("\n").filter((l) => l !== "");
|
|
3265
|
+
const changes = [];
|
|
3266
|
+
const status2 = await must(rnessDir, [
|
|
3267
|
+
"diff",
|
|
3268
|
+
"--cached",
|
|
3269
|
+
"--name-status",
|
|
3270
|
+
"HEAD"
|
|
3271
|
+
]);
|
|
3272
|
+
for (const line of status2.split("\n")) {
|
|
3273
|
+
const [letter = "", path = ""] = line.split(" ");
|
|
3274
|
+
if (path === "" || conflicts.includes(path)) continue;
|
|
3275
|
+
if (letter === "A") changes.push(["added", path]);
|
|
3276
|
+
else if (letter === "D") changes.push(["removed", path]);
|
|
3277
|
+
else if (letter === "M") {
|
|
3278
|
+
const untouched = base !== null && await blobAt(rnessDir, "HEAD", path) === await blobAt(rnessDir, base, path);
|
|
3279
|
+
changes.push([untouched ? "updated" : "merged", path]);
|
|
3280
|
+
}
|
|
3281
|
+
}
|
|
3282
|
+
return { conflicts, changes };
|
|
3283
|
+
}
|
|
3284
|
+
async function isShallow(rnessDir) {
|
|
3285
|
+
const r = await run(rnessDir, ["rev-parse", "--is-shallow-repository"]);
|
|
3286
|
+
return r.code === 0 && r.stdout.trim() === "true";
|
|
3287
|
+
}
|
|
3288
|
+
async function isRepository2(rnessDir) {
|
|
3289
|
+
const r = await run(rnessDir, ["rev-parse", "--show-toplevel"]);
|
|
3290
|
+
if (r.code !== 0) return false;
|
|
3291
|
+
const real = (p) => realpath2(p).catch(() => resolve3(p));
|
|
3292
|
+
return await real(r.stdout.trim()) === await real(rnessDir);
|
|
3293
|
+
}
|
|
3294
|
+
|
|
3127
3295
|
// src/core/new-workspace.ts
|
|
3128
3296
|
async function isEmptyDir(dir) {
|
|
3129
3297
|
return (await readdir2(dir)).length === 0;
|
|
@@ -3138,11 +3306,11 @@ async function insideWorkspace(dir) {
|
|
|
3138
3306
|
}
|
|
3139
3307
|
async function targetProblem(cwd, root, pm) {
|
|
3140
3308
|
const shown = relative2(cwd, root) || ".";
|
|
3141
|
-
if (await insideWorkspace(cwd) || await insideWorkspace(
|
|
3309
|
+
if (await insideWorkspace(cwd) || await insideWorkspace(dirname8(root)))
|
|
3142
3310
|
return "already inside an rness workspace; create runs from outside one";
|
|
3143
3311
|
if (!await exists(root)) return null;
|
|
3144
|
-
if (await exists(
|
|
3145
|
-
if (!await exists(
|
|
3312
|
+
if (await exists(join17(root, ".rness", "rness.json"))) {
|
|
3313
|
+
if (!await exists(join17(root, ".rness", "node_modules")))
|
|
3146
3314
|
return `${shown} holds an rness workspace whose dependencies are not installed; cd ${shown}/.rness && ${pm} install, then ${rnessCommand()} sync`;
|
|
3147
3315
|
return `${shown} already holds an rness workspace (.rness/); run ${rnessCommand()} add inside it to add repositories`;
|
|
3148
3316
|
}
|
|
@@ -3165,7 +3333,7 @@ async function installContext(input) {
|
|
|
3165
3333
|
}
|
|
3166
3334
|
async function buildContext(input) {
|
|
3167
3335
|
const { ui, root, shown, pm } = input;
|
|
3168
|
-
const rnessDir =
|
|
3336
|
+
const rnessDir = join17(root, ".rness");
|
|
3169
3337
|
const pmVersion = await packageManagerVersion(pm);
|
|
3170
3338
|
await mkdir4(root, { recursive: true });
|
|
3171
3339
|
try {
|
|
@@ -3179,9 +3347,9 @@ async function buildContext(input) {
|
|
|
3179
3347
|
return true;
|
|
3180
3348
|
} catch (e) {
|
|
3181
3349
|
reportError(e);
|
|
3182
|
-
await
|
|
3350
|
+
await rm5(rnessDir, { recursive: true, force: true }).catch(() => void 0);
|
|
3183
3351
|
if (await isEmptyDir(root).catch(() => false))
|
|
3184
|
-
await
|
|
3352
|
+
await rm5(root, { recursive: true, force: true }).catch(() => void 0);
|
|
3185
3353
|
process.stderr.write(
|
|
3186
3354
|
`removed ${shown}/.rness after the failure; fix it and retry
|
|
3187
3355
|
`
|
|
@@ -3193,7 +3361,7 @@ async function commitContext(input) {
|
|
|
3193
3361
|
const { ui, rnessDir, shown } = input;
|
|
3194
3362
|
await init(rnessDir);
|
|
3195
3363
|
try {
|
|
3196
|
-
await commitAll(rnessDir,
|
|
3364
|
+
await commitAll(rnessDir, scaffoldMessage(CREATE_SUBJECT, VERSION));
|
|
3197
3365
|
ui.line("committed", `${shown}/.rness`);
|
|
3198
3366
|
} catch (e) {
|
|
3199
3367
|
ui.warn(
|
|
@@ -3234,7 +3402,7 @@ async function syncBlocks(ui, root, shown, inPlace, sshWorks) {
|
|
|
3234
3402
|
|
|
3235
3403
|
// src/commands/create-blank.ts
|
|
3236
3404
|
import { mkdir as mkdir5 } from "fs/promises";
|
|
3237
|
-
import { join as
|
|
3405
|
+
import { join as join18, relative as relative3, resolve as resolve4 } from "path";
|
|
3238
3406
|
var WORKSPACE_NAME = /^(?!\.{1,2}$)[A-Za-z0-9._][A-Za-z0-9._-]*$/;
|
|
3239
3407
|
function workspaceNameError(name) {
|
|
3240
3408
|
return `workspace name "${name}" may only contain letters, digits, '.', '_' and '-', not starting with '-'`;
|
|
@@ -3266,7 +3434,7 @@ async function createBlank(input) {
|
|
|
3266
3434
|
name = answer.trim();
|
|
3267
3435
|
prompted = true;
|
|
3268
3436
|
}
|
|
3269
|
-
const root =
|
|
3437
|
+
const root = resolve4(cwd, name);
|
|
3270
3438
|
const shown = relative3(cwd, root) || ".";
|
|
3271
3439
|
const problem = await targetProblem(cwd, root, pm);
|
|
3272
3440
|
if (problem !== null) {
|
|
@@ -3308,8 +3476,8 @@ async function createBlank(input) {
|
|
|
3308
3476
|
kind: "blank workspace"
|
|
3309
3477
|
});
|
|
3310
3478
|
if (!built) return 1;
|
|
3311
|
-
await mkdir5(
|
|
3312
|
-
await commitContext({ ui, rnessDir:
|
|
3479
|
+
await mkdir5(join18(root, "org"), { recursive: true });
|
|
3480
|
+
await commitContext({ ui, rnessDir: join18(root, ".rness"), shown });
|
|
3313
3481
|
const code = await syncBlocks(
|
|
3314
3482
|
ui,
|
|
3315
3483
|
root,
|
|
@@ -3469,7 +3637,7 @@ async function cloneSelection(input) {
|
|
|
3469
3637
|
{ doing: `cloning org/${repo}`, git: true },
|
|
3470
3638
|
() => clone(
|
|
3471
3639
|
entry.url,
|
|
3472
|
-
|
|
3640
|
+
join19(input.root, "org", repo),
|
|
3473
3641
|
input.provider.credentialsFor(entry.url)
|
|
3474
3642
|
),
|
|
3475
3643
|
() => ["cloned", `org/${repo}`]
|
|
@@ -3738,7 +3906,7 @@ async function createCommand(opts, deps = {}) {
|
|
|
3738
3906
|
org = answer.trim();
|
|
3739
3907
|
prompted = true;
|
|
3740
3908
|
}
|
|
3741
|
-
const root =
|
|
3909
|
+
const root = resolve5(cwd, org);
|
|
3742
3910
|
const shown = relative4(cwd, root) || ".";
|
|
3743
3911
|
const problem = await targetProblem(cwd, root, pm);
|
|
3744
3912
|
if (problem !== null) {
|
|
@@ -3793,8 +3961,8 @@ async function createCommand(opts, deps = {}) {
|
|
|
3793
3961
|
scopes: {}
|
|
3794
3962
|
};
|
|
3795
3963
|
const staged = async () => {
|
|
3796
|
-
staging ??= await
|
|
3797
|
-
return
|
|
3964
|
+
staging ??= await mkdtemp2(join19(tmpdir2(), "rness-join-"));
|
|
3965
|
+
return join19(staging, ".rness");
|
|
3798
3966
|
};
|
|
3799
3967
|
if (joining) {
|
|
3800
3968
|
const stagedDir = await staged();
|
|
@@ -3852,7 +4020,7 @@ async function createCommand(opts, deps = {}) {
|
|
|
3852
4020
|
});
|
|
3853
4021
|
if (p.isCancel(ok) || ok !== true) return cancelled(ui);
|
|
3854
4022
|
}
|
|
3855
|
-
const rnessDir =
|
|
4023
|
+
const rnessDir = join19(root, ".rness");
|
|
3856
4024
|
const install = () => installContext({ ui, pm, rnessDir, skip: opts.skipInstall === true });
|
|
3857
4025
|
if (joining) {
|
|
3858
4026
|
await mkdir6(root, { recursive: true });
|
|
@@ -3865,7 +4033,7 @@ async function createCommand(opts, deps = {}) {
|
|
|
3865
4033
|
ui.line("cloned", `${shown}/.rness (joined ${org})`);
|
|
3866
4034
|
if (opts.pm === void 0) pm = await workspacePackageManager(rnessDir);
|
|
3867
4035
|
await install();
|
|
3868
|
-
await mkdir6(
|
|
4036
|
+
await mkdir6(join19(root, "org"), { recursive: true });
|
|
3869
4037
|
const failures2 = await cloneSelection({
|
|
3870
4038
|
root,
|
|
3871
4039
|
rnessDir,
|
|
@@ -3918,7 +4086,7 @@ ${next2.map((l) => ` ${l}`).join("\n")}
|
|
|
3918
4086
|
kind: "new workspace"
|
|
3919
4087
|
});
|
|
3920
4088
|
if (!built) return 1;
|
|
3921
|
-
await mkdir6(
|
|
4089
|
+
await mkdir6(join19(root, "org"), { recursive: true });
|
|
3922
4090
|
const failures = await cloneSelection({
|
|
3923
4091
|
root,
|
|
3924
4092
|
rnessDir,
|
|
@@ -3985,7 +4153,7 @@ ${next2.map((l) => ` ${l}`).join("\n")}
|
|
|
3985
4153
|
return reportError(e);
|
|
3986
4154
|
} finally {
|
|
3987
4155
|
if (staging !== void 0)
|
|
3988
|
-
await
|
|
4156
|
+
await rm6(staging, { recursive: true, force: true }).catch(() => void 0);
|
|
3989
4157
|
}
|
|
3990
4158
|
}
|
|
3991
4159
|
|
|
@@ -4018,17 +4186,16 @@ async function logoutCommand() {
|
|
|
4018
4186
|
}
|
|
4019
4187
|
|
|
4020
4188
|
// src/commands/upgrade.ts
|
|
4021
|
-
import { execFile as
|
|
4022
|
-
import {
|
|
4023
|
-
import {
|
|
4024
|
-
import {
|
|
4025
|
-
|
|
4189
|
+
import { execFile as execFile6 } from "child_process";
|
|
4190
|
+
import { mkdtemp as mkdtemp3, readFile as readFile9, rm as rm7 } from "fs/promises";
|
|
4191
|
+
import { tmpdir as tmpdir3 } from "os";
|
|
4192
|
+
import { basename as basename5, join as join20, relative as relative5 } from "path";
|
|
4193
|
+
import { promisify as promisify6 } from "util";
|
|
4194
|
+
var execFileP6 = promisify6(execFile6);
|
|
4026
4195
|
var NOTES = "https://github.com/rness-dev/rness/tree/main/packages/cli#readme";
|
|
4027
|
-
var OLD_WORKFLOW_RUN = /npx --yes @rness\/cli@(\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?) validate/;
|
|
4028
|
-
var WORKFLOW_RUN = `npx --yes "@rness/cli@$(node -p "require('./package.json').devDependencies['@rness/cli']")" validate`;
|
|
4029
4196
|
async function latestVersion() {
|
|
4030
4197
|
try {
|
|
4031
|
-
const { stdout } = await
|
|
4198
|
+
const { stdout } = await execFileP6(
|
|
4032
4199
|
"npm",
|
|
4033
4200
|
["view", "@rness/cli@latest", "version"],
|
|
4034
4201
|
{ timeout: 3e4 }
|
|
@@ -4039,7 +4206,70 @@ async function latestVersion() {
|
|
|
4039
4206
|
return null;
|
|
4040
4207
|
}
|
|
4041
4208
|
}
|
|
4042
|
-
async function
|
|
4209
|
+
async function scaffoldFor(version, rnessDir) {
|
|
4210
|
+
if (version === VERSION) return { dir: scaffoldDir() };
|
|
4211
|
+
const installed = await readPinnedCli(rnessDir);
|
|
4212
|
+
const inside = installed === null ? null : join20(installed.dir, "scaffold");
|
|
4213
|
+
if (installed?.version === version && inside !== null && await exists(join20(inside, "package.json")))
|
|
4214
|
+
return { dir: inside };
|
|
4215
|
+
const scratch = await mkdtemp3(join20(tmpdir3(), "rness-pack-"));
|
|
4216
|
+
const cleanup = () => rm7(scratch, { recursive: true, force: true });
|
|
4217
|
+
try {
|
|
4218
|
+
const { stdout } = await execFileP6(
|
|
4219
|
+
"npm",
|
|
4220
|
+
[
|
|
4221
|
+
"pack",
|
|
4222
|
+
`@rness/cli@${version}`,
|
|
4223
|
+
"--pack-destination",
|
|
4224
|
+
scratch,
|
|
4225
|
+
"--silent"
|
|
4226
|
+
],
|
|
4227
|
+
{ timeout: 6e4 }
|
|
4228
|
+
);
|
|
4229
|
+
const tarball = stdout.trim().split("\n").at(-1) ?? "";
|
|
4230
|
+
await execFileP6("tar", ["-xzf", join20(scratch, tarball), "-C", scratch]);
|
|
4231
|
+
return { dir: join20(scratch, "package", "scaffold"), cleanup };
|
|
4232
|
+
} catch (e) {
|
|
4233
|
+
await cleanup();
|
|
4234
|
+
throw new Error(
|
|
4235
|
+
`cannot get the @rness/cli ${version} scaffold (npm pack): ${e instanceof Error ? e.message.split("\n")[0] : String(e)}`,
|
|
4236
|
+
{ cause: e }
|
|
4237
|
+
);
|
|
4238
|
+
}
|
|
4239
|
+
}
|
|
4240
|
+
async function declaredManager(rnessDir, pm) {
|
|
4241
|
+
try {
|
|
4242
|
+
const pkg = JSON.parse(
|
|
4243
|
+
await readFile9(join20(rnessDir, "package.json"), "utf8")
|
|
4244
|
+
);
|
|
4245
|
+
if (typeof pkg.packageManager === "string") return pkg.packageManager;
|
|
4246
|
+
} catch {
|
|
4247
|
+
}
|
|
4248
|
+
return `${pm}@${await packageManagerVersion(pm)}`;
|
|
4249
|
+
}
|
|
4250
|
+
function finish(ui, cwd, rnessDir, label, target) {
|
|
4251
|
+
const rel = relative5(cwd, rnessDir) || ".";
|
|
4252
|
+
const next = [
|
|
4253
|
+
`git -C ${rel} add -A && git -C ${rel} commit -m "chore: rness ${target}"`,
|
|
4254
|
+
"# teammates: git pull \u2014 the next rness command installs it"
|
|
4255
|
+
];
|
|
4256
|
+
if (ui.session) {
|
|
4257
|
+
ui.note("Next steps", next);
|
|
4258
|
+
ui.outro(`${label} runs @rness/cli ${target}`);
|
|
4259
|
+
} else
|
|
4260
|
+
process.stdout.write(
|
|
4261
|
+
[
|
|
4262
|
+
"",
|
|
4263
|
+
status("upgraded", `${label} to @rness/cli ${target}`),
|
|
4264
|
+
"",
|
|
4265
|
+
"Next:",
|
|
4266
|
+
...next.map((line) => ` ${line}`),
|
|
4267
|
+
""
|
|
4268
|
+
].join("\n")
|
|
4269
|
+
);
|
|
4270
|
+
return 0;
|
|
4271
|
+
}
|
|
4272
|
+
async function upgradeCommand(version, opts, terminal = defaultTerminal, deps = {}) {
|
|
4043
4273
|
const cwd = opts.cwd ?? process.cwd();
|
|
4044
4274
|
if (version !== void 0 && !EXACT_VERSION.test(version)) {
|
|
4045
4275
|
process.stderr.write(
|
|
@@ -4081,7 +4311,21 @@ async function upgradeCommand(version, opts, terminal = defaultTerminal) {
|
|
|
4081
4311
|
return 1;
|
|
4082
4312
|
}
|
|
4083
4313
|
const installed = (await readPinnedCli(ws.rnessDir))?.version ?? null;
|
|
4084
|
-
if (
|
|
4314
|
+
if (!await isRepository2(ws.rnessDir)) {
|
|
4315
|
+
process.stderr.write(`${label} is not a git repository
|
|
4316
|
+
`);
|
|
4317
|
+
return 1;
|
|
4318
|
+
}
|
|
4319
|
+
if (!await isClean(ws.rnessDir)) {
|
|
4320
|
+
process.stderr.write(
|
|
4321
|
+
`${label} has uncommitted changes; commit or stash them, then ${rnessCommand()} upgrade
|
|
4322
|
+
`
|
|
4323
|
+
);
|
|
4324
|
+
return 1;
|
|
4325
|
+
}
|
|
4326
|
+
const base = await findScaffoldBase(ws.rnessDir);
|
|
4327
|
+
const scaffoldCurrent = base !== null && base.version === target;
|
|
4328
|
+
if (pin.spec === target && installed === target && scaffoldCurrent) {
|
|
4085
4329
|
if (ui.session) ui.outro(`Already at ${target}`);
|
|
4086
4330
|
else process.stdout.write(`already at ${target}
|
|
4087
4331
|
`);
|
|
@@ -4096,7 +4340,9 @@ async function upgradeCommand(version, opts, terminal = defaultTerminal) {
|
|
|
4096
4340
|
return 1;
|
|
4097
4341
|
}
|
|
4098
4342
|
const pm = await workspacePackageManager(ws.rnessDir);
|
|
4099
|
-
if (pin.spec === target)
|
|
4343
|
+
if (pin.spec === target && installed === target)
|
|
4344
|
+
ui.line("scaffold", `@rness/cli ${target} \u2014 merging it into ${label}`);
|
|
4345
|
+
else if (pin.spec === target)
|
|
4100
4346
|
ui.line(
|
|
4101
4347
|
"install",
|
|
4102
4348
|
`@rness/cli ${target} in ${label} (${pm}) \u2014 ${installed ?? "nothing"} is installed`
|
|
@@ -4118,46 +4364,58 @@ async function upgradeCommand(version, opts, terminal = defaultTerminal) {
|
|
|
4118
4364
|
return 1;
|
|
4119
4365
|
}
|
|
4120
4366
|
}
|
|
4121
|
-
|
|
4122
|
-
|
|
4123
|
-
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4367
|
+
let merged = false;
|
|
4368
|
+
if (!scaffoldCurrent) {
|
|
4369
|
+
const source = await (deps.scaffoldFor ?? scaffoldFor)(
|
|
4370
|
+
target,
|
|
4371
|
+
ws.rnessDir
|
|
4372
|
+
);
|
|
4373
|
+
try {
|
|
4374
|
+
const files = await renderScaffold(source.dir, {
|
|
4375
|
+
version: target,
|
|
4376
|
+
packageManager: await declaredManager(ws.rnessDir, pm)
|
|
4377
|
+
});
|
|
4378
|
+
if (base === null)
|
|
4379
|
+
ui.line(
|
|
4380
|
+
"adopting",
|
|
4381
|
+
`the @rness/cli ${target} scaffold (no scaffold commit in ${label} yet)`
|
|
4382
|
+
);
|
|
4383
|
+
else ui.line("merging", `the @rness/cli ${target} scaffold`);
|
|
4384
|
+
const commit = await buildScaffoldCommit(
|
|
4385
|
+
ws.rnessDir,
|
|
4386
|
+
base?.commit ?? null,
|
|
4387
|
+
files,
|
|
4388
|
+
target
|
|
4138
4389
|
);
|
|
4139
|
-
|
|
4140
|
-
|
|
4141
|
-
|
|
4390
|
+
const result = await mergeScaffold(
|
|
4391
|
+
ws.rnessDir,
|
|
4392
|
+
commit,
|
|
4393
|
+
base?.commit ?? null
|
|
4142
4394
|
);
|
|
4143
|
-
|
|
4144
|
-
|
|
4395
|
+
for (const [change, path] of result.changes) ui.line(change, path);
|
|
4396
|
+
if (result.conflicts.length > 0) {
|
|
4397
|
+
for (const path of result.conflicts) ui.error(`conflict ${path}`);
|
|
4398
|
+
const rel = relative5(cwd, ws.rnessDir) || ".";
|
|
4399
|
+
ui.hint(
|
|
4400
|
+
`resolve them in ${rel} (git checkout --ours <file> keeps yours, --theirs takes the scaffold's, or edit), git add, git commit, then ${rnessCommand()} upgrade again`,
|
|
4401
|
+
"stderr"
|
|
4402
|
+
);
|
|
4403
|
+
return 1;
|
|
4404
|
+
}
|
|
4405
|
+
merged = true;
|
|
4406
|
+
} finally {
|
|
4407
|
+
await source.cleanup?.();
|
|
4145
4408
|
}
|
|
4146
4409
|
}
|
|
4147
|
-
const
|
|
4148
|
-
|
|
4149
|
-
|
|
4150
|
-
|
|
4151
|
-
|
|
4152
|
-
|
|
4153
|
-
|
|
4154
|
-
|
|
4155
|
-
);
|
|
4156
|
-
ui.line(
|
|
4157
|
-
"wrote",
|
|
4158
|
-
".rness/.github/dependabot.yml (@rness/cli now moves by pull request)"
|
|
4159
|
-
);
|
|
4160
|
-
}
|
|
4410
|
+
const packageFile = join20(ws.rnessDir, "package.json");
|
|
4411
|
+
const restore = /* @__PURE__ */ new Map([
|
|
4412
|
+
[packageFile, await readFile9(packageFile, "utf8")]
|
|
4413
|
+
]);
|
|
4414
|
+
const moved = await readPin(ws.rnessDir);
|
|
4415
|
+
if (moved !== null && moved.spec !== target)
|
|
4416
|
+
await writePin(ws.rnessDir, moved.spec, target);
|
|
4417
|
+
if (pin.spec === target && installed === target)
|
|
4418
|
+
return finish(ui, cwd, ws.rnessDir, label, target);
|
|
4161
4419
|
try {
|
|
4162
4420
|
await ui.step(
|
|
4163
4421
|
{ doing: `installing dependencies with ${pm}` },
|
|
@@ -4165,10 +4423,20 @@ async function upgradeCommand(version, opts, terminal = defaultTerminal) {
|
|
|
4165
4423
|
() => ["installed", `dependencies with ${pm}`]
|
|
4166
4424
|
);
|
|
4167
4425
|
} catch (e) {
|
|
4168
|
-
for (const [file, text] of restore) await writeFileAtomic(file, text);
|
|
4169
4426
|
const message = e instanceof Error ? e.message : String(e);
|
|
4170
4427
|
ui.error(message);
|
|
4171
|
-
|
|
4428
|
+
if (!merged) {
|
|
4429
|
+
for (const [file, text] of restore) await writeFileAtomic(file, text);
|
|
4430
|
+
ui.hint(
|
|
4431
|
+
`restored ${relative5(cwd, packageFile) || packageFile}`,
|
|
4432
|
+
"stderr"
|
|
4433
|
+
);
|
|
4434
|
+
}
|
|
4435
|
+
if (merged)
|
|
4436
|
+
ui.hint(
|
|
4437
|
+
`the scaffold merge is still staged; undo it with: git -C ${relative5(cwd, ws.rnessDir) || "."} merge --abort`,
|
|
4438
|
+
"stderr"
|
|
4439
|
+
);
|
|
4172
4440
|
if (/minimum.?release.?age|NO_MATURE/i.test(message))
|
|
4173
4441
|
ui.hint(
|
|
4174
4442
|
"pnpm refuses versions published less than 24 h ago: add '@rness/cli' under minimumReleaseAgeExclude in .rness/pnpm-workspace.yaml",
|
|
@@ -4187,33 +4455,14 @@ async function upgradeCommand(version, opts, terminal = defaultTerminal) {
|
|
|
4187
4455
|
ui.gitIsSilent = true;
|
|
4188
4456
|
const code = await syncBlocks(ui, ws.root, basename5(ws.root));
|
|
4189
4457
|
if (code !== 0) return code;
|
|
4190
|
-
|
|
4191
|
-
const next = [
|
|
4192
|
-
`git -C ${rel} add -A && git -C ${rel} commit -m "chore: rness ${target}"`,
|
|
4193
|
-
"# teammates: git pull \u2014 the next rness command installs it"
|
|
4194
|
-
];
|
|
4195
|
-
if (ui.session) {
|
|
4196
|
-
ui.note("Next steps", next);
|
|
4197
|
-
ui.outro(`${label} runs @rness/cli ${target}`);
|
|
4198
|
-
} else
|
|
4199
|
-
process.stdout.write(
|
|
4200
|
-
[
|
|
4201
|
-
"",
|
|
4202
|
-
status("upgraded", `${label} to @rness/cli ${target}`),
|
|
4203
|
-
"",
|
|
4204
|
-
"Next:",
|
|
4205
|
-
...next.map((line) => ` ${line}`),
|
|
4206
|
-
""
|
|
4207
|
-
].join("\n")
|
|
4208
|
-
);
|
|
4209
|
-
return 0;
|
|
4458
|
+
return finish(ui, cwd, ws.rnessDir, label, target);
|
|
4210
4459
|
} catch (e) {
|
|
4211
4460
|
return reportError(e);
|
|
4212
4461
|
}
|
|
4213
4462
|
}
|
|
4214
4463
|
|
|
4215
4464
|
// src/core/blocks.ts
|
|
4216
|
-
import { join as
|
|
4465
|
+
import { join as join21 } from "path";
|
|
4217
4466
|
var PROBLEM = /* @__PURE__ */ new Set(["stale", "malformed"]);
|
|
4218
4467
|
async function checkBlocks({
|
|
4219
4468
|
root,
|
|
@@ -4230,7 +4479,7 @@ async function checkBlocks({
|
|
|
4230
4479
|
warnings: checks.filter((c) => !PROBLEM.has(c.status) && c.message !== null).map((c) => c.message),
|
|
4231
4480
|
checks
|
|
4232
4481
|
});
|
|
4233
|
-
if (!await exists(
|
|
4482
|
+
if (!await exists(join21(root, "org"))) return derive();
|
|
4234
4483
|
const targets = [
|
|
4235
4484
|
{ scope: null, dir: root, depth: 0, file: "AGENTS.md", label: "AGENTS.md" },
|
|
4236
4485
|
{ scope: null, dir: root, depth: 0, file: "CLAUDE.md", label: "CLAUDE.md" }
|
|
@@ -4239,7 +4488,7 @@ async function checkBlocks({
|
|
|
4239
4488
|
const segments = entry.path.split("/");
|
|
4240
4489
|
targets.push({
|
|
4241
4490
|
scope: name,
|
|
4242
|
-
dir:
|
|
4491
|
+
dir: join21(root, ...segments),
|
|
4243
4492
|
depth: segments.length,
|
|
4244
4493
|
file: "AGENTS.md",
|
|
4245
4494
|
label: `${entry.path}/AGENTS.md`
|
|
@@ -4254,7 +4503,7 @@ async function checkBlocks({
|
|
|
4254
4503
|
);
|
|
4255
4504
|
continue;
|
|
4256
4505
|
}
|
|
4257
|
-
const text = await readOrNull(
|
|
4506
|
+
const text = await readOrNull(join21(t.dir, t.file));
|
|
4258
4507
|
const lines = text === null ? [] : text.split(/\r?\n/);
|
|
4259
4508
|
const found = findBlock(lines);
|
|
4260
4509
|
if (found.kind === "none") {
|
|
@@ -4294,7 +4543,7 @@ async function checkBlocks({
|
|
|
4294
4543
|
}
|
|
4295
4544
|
|
|
4296
4545
|
// src/core/contract.ts
|
|
4297
|
-
import { join as
|
|
4546
|
+
import { join as join22 } from "path";
|
|
4298
4547
|
var STATUSES = {
|
|
4299
4548
|
adr: ["Proposed", "Accepted", "Rejected", "Superseded"],
|
|
4300
4549
|
specs: [
|
|
@@ -4313,7 +4562,7 @@ async function checkContract(rnessDir) {
|
|
|
4313
4562
|
const problems = [];
|
|
4314
4563
|
for (const name of COLLECTIONS) {
|
|
4315
4564
|
const allowed = STATUSES[name];
|
|
4316
|
-
const items = await collectMarkdown(
|
|
4565
|
+
const items = await collectMarkdown(join22(rnessDir, name));
|
|
4317
4566
|
for (const item of items) {
|
|
4318
4567
|
const where = `${name}/${item.rel}`;
|
|
4319
4568
|
if (SKIP.has(where)) continue;
|
|
@@ -4375,11 +4624,25 @@ async function validateCommand(opts, deps = {}) {
|
|
|
4375
4624
|
);
|
|
4376
4625
|
else if (o.status === "invalid")
|
|
4377
4626
|
problems.push(`${o.label}: ${o.detail ?? "unreadable"}`);
|
|
4627
|
+
const scaffoldWarnings = [];
|
|
4628
|
+
if (await isRepository2(ws.rnessDir) && !await isShallow(ws.rnessDir)) {
|
|
4629
|
+
const pin = await readPin(ws.rnessDir);
|
|
4630
|
+
const base = await findScaffoldBase(ws.rnessDir);
|
|
4631
|
+
if (base === null || base.version === null)
|
|
4632
|
+
scaffoldWarnings.push(
|
|
4633
|
+
`the scaffold is not tracked in .rness yet: run ${rnessCommand()} upgrade`
|
|
4634
|
+
);
|
|
4635
|
+
else if (pin !== null && EXACT_VERSION.test(pin.spec) && pin.spec !== base.version)
|
|
4636
|
+
scaffoldWarnings.push(
|
|
4637
|
+
`the @rness/cli ${pin.spec} scaffold is not merged here: run ${rnessCommand()} upgrade`
|
|
4638
|
+
);
|
|
4639
|
+
}
|
|
4378
4640
|
const ui = await makeUi(deps.terminal ?? defaultTerminal);
|
|
4379
4641
|
if (!ui.session) {
|
|
4380
4642
|
for (const p of problems) process.stderr.write(`${p}
|
|
4381
4643
|
`);
|
|
4382
|
-
for (const w of blocks.warnings
|
|
4644
|
+
for (const w of [...blocks.warnings, ...scaffoldWarnings])
|
|
4645
|
+
process.stderr.write(`${warn(w)}
|
|
4383
4646
|
`);
|
|
4384
4647
|
if (problems.length > 0) return 1;
|
|
4385
4648
|
process.stdout.write("context ok\n");
|
|
@@ -4400,6 +4663,7 @@ async function validateCommand(opts, deps = {}) {
|
|
|
4400
4663
|
for (const o of targets)
|
|
4401
4664
|
if (o.status === "unchanged") ui.line("current", o.label);
|
|
4402
4665
|
for (const p of problems) if (!blocks.problems.includes(p)) ui.error(p);
|
|
4666
|
+
for (const w of scaffoldWarnings) ui.warn(w);
|
|
4403
4667
|
ui.outro(
|
|
4404
4668
|
problems.length > 0 ? "Context mismatch" : "Context OK",
|
|
4405
4669
|
problems.length > 0 ? "error" : "done"
|
|
@@ -4551,7 +4815,7 @@ function buildProgram(state) {
|
|
|
4551
4815
|
});
|
|
4552
4816
|
return program;
|
|
4553
4817
|
}
|
|
4554
|
-
async function
|
|
4818
|
+
async function run2(argv) {
|
|
4555
4819
|
const state = { code: 0 };
|
|
4556
4820
|
const program = buildProgram(state);
|
|
4557
4821
|
if (argv.length === 0) {
|
|
@@ -4678,8 +4942,8 @@ export {
|
|
|
4678
4942
|
STATUSES,
|
|
4679
4943
|
checkContract,
|
|
4680
4944
|
validateCommand,
|
|
4681
|
-
run,
|
|
4945
|
+
run2 as run,
|
|
4682
4946
|
OWN_COMMANDS,
|
|
4683
4947
|
catchUp
|
|
4684
4948
|
};
|
|
4685
|
-
//# sourceMappingURL=chunk-
|
|
4949
|
+
//# sourceMappingURL=chunk-VQMX52HT.js.map
|