@inixiative/config 0.5.183 → 0.5.185
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/LICENSE +21 -0
- package/README.md +42 -34
- package/dist/cli.js +310 -63
- package/package.json +4 -2
- package/theme/domains.css +137 -0
- package/theme/marketing.css +513 -0
- package/theme/public.css +3 -1
- package/theme/{agentic.css → status.css} +1 -1
- package/versions.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
// src/cli.ts
|
|
4
|
-
import { spawnSync as
|
|
4
|
+
import { spawnSync as spawnSync3 } from "child_process";
|
|
5
5
|
import {
|
|
6
|
-
existsSync as
|
|
7
|
-
mkdirSync as
|
|
6
|
+
existsSync as existsSync3,
|
|
7
|
+
mkdirSync as mkdirSync3,
|
|
8
8
|
mkdtempSync,
|
|
9
|
-
readdirSync as
|
|
10
|
-
readFileSync as
|
|
11
|
-
rmSync as
|
|
12
|
-
writeFileSync as
|
|
9
|
+
readdirSync as readdirSync3,
|
|
10
|
+
readFileSync as readFileSync3,
|
|
11
|
+
rmSync as rmSync3,
|
|
12
|
+
writeFileSync as writeFileSync3
|
|
13
13
|
} from "fs";
|
|
14
14
|
import { hostname as hostname2, tmpdir } from "os";
|
|
15
|
-
import { basename, dirname as
|
|
15
|
+
import { basename, dirname as dirname3, join as join3, resolve as resolve2 } from "path";
|
|
16
16
|
|
|
17
17
|
// src/args.ts
|
|
18
18
|
import { parseArgs } from "util";
|
|
@@ -999,7 +999,7 @@ var isConfigCheckout = (dir2) => {
|
|
|
999
999
|
};
|
|
1000
1000
|
|
|
1001
1001
|
// src/args.ts
|
|
1002
|
-
var COMMANDS = ["check", "sync", "scan", "train", "ports"];
|
|
1002
|
+
var COMMANDS = ["check", "sync", "scan", "train", "ports", "terms"];
|
|
1003
1003
|
var PRESETS = ["base", "node", "react"];
|
|
1004
1004
|
var preset = { type: "string" };
|
|
1005
1005
|
var lane = { type: "string" };
|
|
@@ -1009,7 +1009,8 @@ var OPTIONS = {
|
|
|
1009
1009
|
sync: { preset, force: flag, "no-install": flag },
|
|
1010
1010
|
scan: { lane },
|
|
1011
1011
|
train: { lane, push: flag, "dry-run": flag },
|
|
1012
|
-
ports: {}
|
|
1012
|
+
ports: {},
|
|
1013
|
+
terms: { "write-baseline": flag }
|
|
1013
1014
|
};
|
|
1014
1015
|
var UsageError = class extends Error {
|
|
1015
1016
|
};
|
|
@@ -1057,7 +1058,8 @@ var parseCommandLine = (argv) => {
|
|
|
1057
1058
|
force: values.force === true,
|
|
1058
1059
|
noInstall: values["no-install"] === true,
|
|
1059
1060
|
push: values.push === true,
|
|
1060
|
-
dryRun: values["dry-run"] === true
|
|
1061
|
+
dryRun: values["dry-run"] === true,
|
|
1062
|
+
writeBaseline: values["write-baseline"] === true
|
|
1061
1063
|
};
|
|
1062
1064
|
};
|
|
1063
1065
|
|
|
@@ -1103,6 +1105,238 @@ function portsFor(project) {
|
|
|
1103
1105
|
);
|
|
1104
1106
|
}
|
|
1105
1107
|
|
|
1108
|
+
// src/retiredTerms.ts
|
|
1109
|
+
import { spawnSync as spawnSync2 } from "child_process";
|
|
1110
|
+
import {
|
|
1111
|
+
existsSync as existsSync2,
|
|
1112
|
+
lstatSync,
|
|
1113
|
+
mkdirSync as mkdirSync2,
|
|
1114
|
+
readdirSync as readdirSync2,
|
|
1115
|
+
readFileSync as readFileSync2,
|
|
1116
|
+
rmSync as rmSync2,
|
|
1117
|
+
writeFileSync as writeFileSync2
|
|
1118
|
+
} from "fs";
|
|
1119
|
+
import { dirname as dirname2, join as join2 } from "path";
|
|
1120
|
+
var RETIRED_TERMS = [
|
|
1121
|
+
{
|
|
1122
|
+
id: "kastle",
|
|
1123
|
+
pattern: /\bkastles?\b/gi,
|
|
1124
|
+
scope: "docs",
|
|
1125
|
+
instead: "Kingdom, owner, integration or Signet"
|
|
1126
|
+
},
|
|
1127
|
+
{
|
|
1128
|
+
id: "castle",
|
|
1129
|
+
pattern: /\bCastles?\b/g,
|
|
1130
|
+
scope: "docs",
|
|
1131
|
+
instead: "Kingdom, owner, integration or Signet"
|
|
1132
|
+
},
|
|
1133
|
+
{
|
|
1134
|
+
id: "runtime-keys",
|
|
1135
|
+
pattern: /\bRuntimeInstallations?\b|\bkingdom_runtime_/g,
|
|
1136
|
+
scope: "docs",
|
|
1137
|
+
instead: "a Signet enrollment on the Foundry integration"
|
|
1138
|
+
},
|
|
1139
|
+
{
|
|
1140
|
+
id: "medical-demo",
|
|
1141
|
+
pattern: /\bsignetDemo\b|\bmedicalQuestionStep\b/g,
|
|
1142
|
+
scope: "docs",
|
|
1143
|
+
instead: "nothing: the demo is gone (demos live in template-workbench)"
|
|
1144
|
+
},
|
|
1145
|
+
{
|
|
1146
|
+
id: "retired-workspaces",
|
|
1147
|
+
pattern: /\bkingdom-workspace\b|\bfoundry-lab\b|\bnative-candidate\b/g,
|
|
1148
|
+
scope: "docs",
|
|
1149
|
+
instead: "the canonical repos (kingdom, foundry)"
|
|
1150
|
+
},
|
|
1151
|
+
{
|
|
1152
|
+
id: "foundry-oracle",
|
|
1153
|
+
pattern: /\bfoundry-oracle\b/gi,
|
|
1154
|
+
scope: "docs",
|
|
1155
|
+
instead: "Foundry and Oracle, two products"
|
|
1156
|
+
},
|
|
1157
|
+
{
|
|
1158
|
+
id: "own-llm-keys",
|
|
1159
|
+
pattern: /\byour own (?:LLM|model|API) keys?\b/gi,
|
|
1160
|
+
scope: "docs",
|
|
1161
|
+
instead: "your own subscriptions (Foundry runs on subscription logins)"
|
|
1162
|
+
},
|
|
1163
|
+
{
|
|
1164
|
+
id: "foundry-roles",
|
|
1165
|
+
pattern: /\b(?:Cartographer|Librarian|Artificer|Steward)s?\b/g,
|
|
1166
|
+
scope: "public",
|
|
1167
|
+
instead: "say what it does: Wardens point at what exists; your agent decides"
|
|
1168
|
+
}
|
|
1169
|
+
];
|
|
1170
|
+
var RETIRED_TERMS_DIR = "scripts/ci/retired-terms";
|
|
1171
|
+
var ALLOW_FILE = `${RETIRED_TERMS_DIR}/allow.txt`;
|
|
1172
|
+
var BASELINE_FILE = `${RETIRED_TERMS_DIR}/baseline.txt`;
|
|
1173
|
+
var TEXT_FILE = /\.(md|mdx|html|astro)$/i;
|
|
1174
|
+
var PUBLIC_FILE = /(^|\/)README[^/]*\.md$|\.(html|astro|mdx)$/i;
|
|
1175
|
+
var SKIPPED = /(^|\/)(node_modules|\.git|\.worktrees|fixtures|rule-violations)\/|^(dist|build|coverage|tmp)\/|^\.foundry\/regions\/|(^|\/)CHANGELOG[^/]*\.md$/i;
|
|
1176
|
+
var walk = (root, dir2 = "", out = []) => {
|
|
1177
|
+
for (const entry of readdirSync2(join2(root, dir2), { withFileTypes: true })) {
|
|
1178
|
+
const rel = dir2 ? `${dir2}/${entry.name}` : entry.name;
|
|
1179
|
+
if (entry.isDirectory() && !SKIPPED.test(`${rel}/`)) walk(root, rel, out);
|
|
1180
|
+
else if (entry.isFile()) out.push(rel);
|
|
1181
|
+
}
|
|
1182
|
+
return out;
|
|
1183
|
+
};
|
|
1184
|
+
var readText = (abs) => {
|
|
1185
|
+
try {
|
|
1186
|
+
return lstatSync(abs).isFile() ? readFileSync2(abs, "utf8") : null;
|
|
1187
|
+
} catch {
|
|
1188
|
+
return null;
|
|
1189
|
+
}
|
|
1190
|
+
};
|
|
1191
|
+
var listFiles = (root) => {
|
|
1192
|
+
if (existsSync2(join2(root, ".git"))) {
|
|
1193
|
+
const listed = spawnSync2(
|
|
1194
|
+
"git",
|
|
1195
|
+
["ls-files", "-z", "--cached", "--others", "--exclude-standard"],
|
|
1196
|
+
{
|
|
1197
|
+
cwd: root,
|
|
1198
|
+
encoding: "utf8"
|
|
1199
|
+
}
|
|
1200
|
+
);
|
|
1201
|
+
if (listed.status === 0) return listed.stdout.split("\0").filter(Boolean);
|
|
1202
|
+
}
|
|
1203
|
+
return walk(root);
|
|
1204
|
+
};
|
|
1205
|
+
var lineOf = (text, index) => text.slice(0, index).split("\n").length;
|
|
1206
|
+
var scanRetiredTerms = (root) => {
|
|
1207
|
+
const hits = [];
|
|
1208
|
+
for (const path of listFiles(root).sort()) {
|
|
1209
|
+
if (SKIPPED.test(path) || path.startsWith(`${RETIRED_TERMS_DIR}/`)) continue;
|
|
1210
|
+
const isManifest = /(^|\/)package\.json$/.test(path);
|
|
1211
|
+
if (!isManifest && !TEXT_FILE.test(path)) continue;
|
|
1212
|
+
const raw = readText(join2(root, path));
|
|
1213
|
+
if (raw === null) continue;
|
|
1214
|
+
let text = raw;
|
|
1215
|
+
if (isManifest) {
|
|
1216
|
+
try {
|
|
1217
|
+
const description = JSON.parse(raw).description;
|
|
1218
|
+
if (typeof description !== "string") continue;
|
|
1219
|
+
text = description;
|
|
1220
|
+
} catch {
|
|
1221
|
+
continue;
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
const isPublic = isManifest || PUBLIC_FILE.test(path);
|
|
1225
|
+
for (const term of RETIRED_TERMS) {
|
|
1226
|
+
if (term.scope === "public" && !isPublic) continue;
|
|
1227
|
+
for (const match of text.matchAll(term.pattern)) {
|
|
1228
|
+
hits.push({
|
|
1229
|
+
path,
|
|
1230
|
+
line: isManifest ? lineOf(raw, raw.indexOf('"description"')) : lineOf(text, match.index),
|
|
1231
|
+
term,
|
|
1232
|
+
text: match[0]
|
|
1233
|
+
});
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
}
|
|
1237
|
+
return hits;
|
|
1238
|
+
};
|
|
1239
|
+
var readList = (root, file) => {
|
|
1240
|
+
const abs = join2(root, file);
|
|
1241
|
+
if (!existsSync2(abs)) return [];
|
|
1242
|
+
return readFileSync2(abs, "utf8").split("\n").map((line) => line.trimEnd()).filter((line) => line.trim() !== "" && !line.trimStart().startsWith("#"));
|
|
1243
|
+
};
|
|
1244
|
+
var allowedBy = (lines) => {
|
|
1245
|
+
const rules = lines.map((line) => {
|
|
1246
|
+
const [first2, second] = line.split(" ");
|
|
1247
|
+
return second === void 0 ? { path: "", term: first2.trim() } : { path: first2, term: second.trim() };
|
|
1248
|
+
});
|
|
1249
|
+
return (hit) => rules.some(
|
|
1250
|
+
(rule) => rule.term === hit.term.id && (rule.path === "" || rule.path === hit.path || rule.path.endsWith("/") && hit.path.startsWith(rule.path))
|
|
1251
|
+
);
|
|
1252
|
+
};
|
|
1253
|
+
var countByKey = (hits) => {
|
|
1254
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1255
|
+
for (const hit of hits) {
|
|
1256
|
+
const key = `${hit.path} ${hit.term.id}`;
|
|
1257
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
1258
|
+
}
|
|
1259
|
+
return counts;
|
|
1260
|
+
};
|
|
1261
|
+
var BASELINE_LINE = /^([^\t]+)\t([^\t]+)\t(\d+)$/;
|
|
1262
|
+
var readBaseline = (root) => {
|
|
1263
|
+
const counts = /* @__PURE__ */ new Map();
|
|
1264
|
+
const malformed = [];
|
|
1265
|
+
for (const line of readList(root, BASELINE_FILE)) {
|
|
1266
|
+
const match = BASELINE_LINE.exec(line);
|
|
1267
|
+
if (match) counts.set(`${match[1]} ${match[2]}`, Number(match[3]));
|
|
1268
|
+
else malformed.push(line);
|
|
1269
|
+
}
|
|
1270
|
+
return { counts, malformed };
|
|
1271
|
+
};
|
|
1272
|
+
var checkRetiredTerms = (root) => {
|
|
1273
|
+
const allowed = allowedBy(readList(root, ALLOW_FILE));
|
|
1274
|
+
const hits = scanRetiredTerms(root).filter((hit) => !allowed(hit));
|
|
1275
|
+
const counts = countByKey(hits);
|
|
1276
|
+
const { counts: baseline, malformed } = readBaseline(root);
|
|
1277
|
+
const findings = malformed.map((line) => ({
|
|
1278
|
+
level: "error",
|
|
1279
|
+
message: `${BASELINE_FILE}: "${line}" is not <path>\\t<term>\\t<count> \u2192 rewrite it with terms --write-baseline`
|
|
1280
|
+
}));
|
|
1281
|
+
for (const [key, count] of counts) {
|
|
1282
|
+
const known = baseline.get(key) ?? 0;
|
|
1283
|
+
if (count <= known) continue;
|
|
1284
|
+
const fresh = hits.filter((hit) => `${hit.path} ${hit.term.id}` === key).slice(known);
|
|
1285
|
+
for (const hit of fresh) {
|
|
1286
|
+
findings.push({
|
|
1287
|
+
level: "error",
|
|
1288
|
+
message: `retired term in ${hit.path}:${hit.line}: "${hit.text}" (${hit.term.id}) \u2192 ${hit.term.instead}`
|
|
1289
|
+
});
|
|
1290
|
+
}
|
|
1291
|
+
}
|
|
1292
|
+
for (const [key, known] of baseline) {
|
|
1293
|
+
const count = counts.get(key) ?? 0;
|
|
1294
|
+
if (count >= known) continue;
|
|
1295
|
+
const [path, term] = key.split(" ");
|
|
1296
|
+
findings.push({
|
|
1297
|
+
level: "error",
|
|
1298
|
+
message: count === 0 ? `${BASELINE_FILE}: ${path} no longer uses ${term} \u2192 delete its line` : `${BASELINE_FILE}: ${path} uses ${term} ${count}\xD7 now, not ${known} \u2192 lower its count`
|
|
1299
|
+
});
|
|
1300
|
+
}
|
|
1301
|
+
const baselined = [...counts].reduce(
|
|
1302
|
+
(sum, [key, count]) => sum + Math.min(count, baseline.get(key) ?? 0),
|
|
1303
|
+
0
|
|
1304
|
+
);
|
|
1305
|
+
if (baselined > 0) {
|
|
1306
|
+
findings.push({
|
|
1307
|
+
level: "warn",
|
|
1308
|
+
message: `${baselined} retired-term use${baselined === 1 ? "" : "s"} in ${BASELINE_FILE} (not blocking; fix the copy and shrink the baseline)`
|
|
1309
|
+
});
|
|
1310
|
+
}
|
|
1311
|
+
return { findings, hits };
|
|
1312
|
+
};
|
|
1313
|
+
var writeRetiredTermsBaseline = (root) => {
|
|
1314
|
+
const allowed = allowedBy(readList(root, ALLOW_FILE));
|
|
1315
|
+
const counts = countByKey(scanRetiredTerms(root).filter((hit) => !allowed(hit)));
|
|
1316
|
+
const path = join2(root, BASELINE_FILE);
|
|
1317
|
+
if (existsSync2(path)) {
|
|
1318
|
+
const { counts: baseline } = readBaseline(root);
|
|
1319
|
+
const refused = [...counts].filter(([key, count]) => count > (baseline.get(key) ?? 0)).map(
|
|
1320
|
+
([key, count]) => `${key.replace(" ", " ")} ${count}\xD7 (baseline ${baseline.get(key) ?? 0})`
|
|
1321
|
+
);
|
|
1322
|
+
if (refused.length > 0) return { written: 0, refused };
|
|
1323
|
+
}
|
|
1324
|
+
const header = [
|
|
1325
|
+
"# Retired-term uses that predate the rule: reported, not failed (@inixiative/config check).",
|
|
1326
|
+
"# One per line: <path>\\t<term>\\t<count>. Fix the copy and lower or delete its line.",
|
|
1327
|
+
"# Rewrite after fixing: inixiative-config terms --write-baseline (it refuses to grow)."
|
|
1328
|
+
];
|
|
1329
|
+
const lines = [...counts].sort(([a], [b]) => a.localeCompare(b)).map(([key, n]) => `${key} ${n}`);
|
|
1330
|
+
if (lines.length === 0) {
|
|
1331
|
+
rmSync2(path, { force: true });
|
|
1332
|
+
return { written: 0, refused: [] };
|
|
1333
|
+
}
|
|
1334
|
+
mkdirSync2(dirname2(path), { recursive: true });
|
|
1335
|
+
writeFileSync2(path, `${[...header, ...lines].join("\n")}
|
|
1336
|
+
`);
|
|
1337
|
+
return { written: lines.length, refused: [] };
|
|
1338
|
+
};
|
|
1339
|
+
|
|
1106
1340
|
// src/cli.ts
|
|
1107
1341
|
var commandLine;
|
|
1108
1342
|
try {
|
|
@@ -1111,7 +1345,7 @@ try {
|
|
|
1111
1345
|
if (!(error instanceof UsageError)) throw error;
|
|
1112
1346
|
console.error(`\u2717 ${error.message}`);
|
|
1113
1347
|
console.error(
|
|
1114
|
-
"Usage: inixiative-config check [dir] [--preset=base|node|react]\n inixiative-config sync [dir] [--preset=base|node|react] [--force] [--no-install]\n inixiative-config scan [root] [--lane=primitives|agentic]\n inixiative-config train [root] [--lane=primitives|agentic] [--push] [--dry-run]\n inixiative-config ports [project]"
|
|
1348
|
+
"Usage: inixiative-config check [dir] [--preset=base|node|react]\n inixiative-config sync [dir] [--preset=base|node|react] [--force] [--no-install]\n inixiative-config scan [root] [--lane=primitives|agentic]\n inixiative-config train [root] [--lane=primitives|agentic] [--push] [--dry-run]\n inixiative-config ports [project]\n inixiative-config terms [dir] [--write-baseline]"
|
|
1115
1349
|
);
|
|
1116
1350
|
process.exit(2);
|
|
1117
1351
|
}
|
|
@@ -1145,7 +1379,7 @@ var report = (findings) => {
|
|
|
1145
1379
|
if (process.versions.bun && process.versions.bun !== manifest.bun) {
|
|
1146
1380
|
console.log(`\u26A0 running bun ${process.versions.bun}, blessed is ${manifest.bun} (bun upgrade)`);
|
|
1147
1381
|
}
|
|
1148
|
-
var git = (cwd, ...gitArgs) =>
|
|
1382
|
+
var git = (cwd, ...gitArgs) => spawnSync3("git", gitArgs, { cwd, encoding: "utf8" });
|
|
1149
1383
|
var behindOrigin = (cwd) => {
|
|
1150
1384
|
const behind = git(cwd, "rev-list", "--count", "HEAD..@{upstream}");
|
|
1151
1385
|
return behind.status === 0 ? Number(behind.stdout.trim()) : 0;
|
|
@@ -1183,7 +1417,20 @@ var offDefaultBranch = (cwd) => {
|
|
|
1183
1417
|
};
|
|
1184
1418
|
if (command === "check") {
|
|
1185
1419
|
const { findings } = inspect(dir, manifest, presetFlag);
|
|
1186
|
-
process.exit(report(findings) > 0 ? 1 : 0);
|
|
1420
|
+
process.exit(report([...findings, ...checkRetiredTerms(dir).findings]) > 0 ? 1 : 0);
|
|
1421
|
+
}
|
|
1422
|
+
if (command === "terms") {
|
|
1423
|
+
if (commandLine.writeBaseline) {
|
|
1424
|
+
const { written, refused } = writeRetiredTermsBaseline(dir);
|
|
1425
|
+
if (refused.length > 0) {
|
|
1426
|
+
console.error("\u2717 the baseline only shrinks; fix these uses (or allow a legitimate one):");
|
|
1427
|
+
for (const entry of refused) console.error(` ${entry}`);
|
|
1428
|
+
process.exit(1);
|
|
1429
|
+
}
|
|
1430
|
+
console.log(`wrote ${written} baseline entr${written === 1 ? "y" : "ies"}`);
|
|
1431
|
+
process.exit(0);
|
|
1432
|
+
}
|
|
1433
|
+
process.exit(report(checkRetiredTerms(dir).findings) > 0 ? 1 : 0);
|
|
1187
1434
|
}
|
|
1188
1435
|
var laneLabel = (checkout) => checkout.consumer ? `consumer of ${checkout.consumer.lanes.join(" + ")}` : `${checkout.lane} lane`;
|
|
1189
1436
|
if (command === "scan") {
|
|
@@ -1306,7 +1553,7 @@ if (command === "train") {
|
|
|
1306
1553
|
const worktrees = [];
|
|
1307
1554
|
const removeWorktree = ({ repo, path, tooling }) => {
|
|
1308
1555
|
if (tooling) {
|
|
1309
|
-
|
|
1556
|
+
spawnSync3("bun", ["run", "worktree:destroy", basename(path), "--force"], {
|
|
1310
1557
|
cwd: repo,
|
|
1311
1558
|
stdio: "inherit"
|
|
1312
1559
|
});
|
|
@@ -1355,7 +1602,7 @@ if (command === "train") {
|
|
|
1355
1602
|
}
|
|
1356
1603
|
if (!dryRun) {
|
|
1357
1604
|
console.log(`\u2193 fast-forwarded to origin (+${behind})`);
|
|
1358
|
-
checkout.pkg = JSON.parse(
|
|
1605
|
+
checkout.pkg = JSON.parse(readFileSync3(join3(checkout.dir, "package.json"), "utf8"));
|
|
1359
1606
|
}
|
|
1360
1607
|
}
|
|
1361
1608
|
return true;
|
|
@@ -1381,7 +1628,7 @@ if (command === "train") {
|
|
|
1381
1628
|
};
|
|
1382
1629
|
};
|
|
1383
1630
|
const relockAndCheck = (checkout, check = true) => effect(`re-lock ${checkout.name}${check ? " and run its check" : ""}`, void 0, () => {
|
|
1384
|
-
const install = (...flags) =>
|
|
1631
|
+
const install = (...flags) => spawnSync3("bun", ["install", ...flags], { cwd: checkout.dir, stdio: "inherit" }).status === 0;
|
|
1385
1632
|
if (!install() && !install("--no-cache")) {
|
|
1386
1633
|
throw new Abort(`bun install failed in ${checkout.name}`);
|
|
1387
1634
|
}
|
|
@@ -1389,9 +1636,9 @@ if (command === "train") {
|
|
|
1389
1636
|
checkout.dir,
|
|
1390
1637
|
inspect(checkout.dir, target()).findings
|
|
1391
1638
|
)) {
|
|
1392
|
-
|
|
1639
|
+
spawnSync3("bun", ["update", ...names], { cwd, stdio: "inherit" });
|
|
1393
1640
|
}
|
|
1394
|
-
if (check &&
|
|
1641
|
+
if (check && spawnSync3("bun", ["run", "check"], { cwd: checkout.dir, stdio: "inherit" }).status !== 0) {
|
|
1395
1642
|
throw new CheckFailed(`check failed in ${checkout.name}`);
|
|
1396
1643
|
}
|
|
1397
1644
|
});
|
|
@@ -1400,7 +1647,7 @@ if (command === "train") {
|
|
|
1400
1647
|
if (git(checkout.dir, "status", "--porcelain").stdout.trim() === "") return;
|
|
1401
1648
|
git(checkout.dir, "reset", "--quiet", "--hard", "HEAD");
|
|
1402
1649
|
git(checkout.dir, "clean", "--quiet", "-fd");
|
|
1403
|
-
|
|
1650
|
+
spawnSync3("bun", ["install", "--frozen-lockfile"], { cwd: checkout.dir, stdio: "inherit" });
|
|
1404
1651
|
});
|
|
1405
1652
|
const movesOf = (checkout) => {
|
|
1406
1653
|
const candidates2 = activeCandidates(manifest);
|
|
@@ -1430,11 +1677,11 @@ if (command === "train") {
|
|
|
1430
1677
|
};
|
|
1431
1678
|
const worktree = (checkout, branch) => {
|
|
1432
1679
|
const tooling = !!checkout.pkg.scripts?.["worktree:create"];
|
|
1433
|
-
const path = tooling ?
|
|
1434
|
-
const created = tooling ?
|
|
1680
|
+
const path = tooling ? join3(checkout.dir, ".worktrees", branch.replaceAll("/", "-")) : join3(mkdtempSync(join3(tmpdir(), "inixiative-train-")), basename(checkout.dir));
|
|
1681
|
+
const created = tooling ? spawnSync3("bun", ["run", "worktree:create", defaultBranch(checkout.dir), branch], {
|
|
1435
1682
|
cwd: checkout.dir,
|
|
1436
1683
|
stdio: "inherit"
|
|
1437
|
-
}).status === 0 &&
|
|
1684
|
+
}).status === 0 && existsSync3(path) : git(checkout.dir, "worktree", "add", "--quiet", "-b", branch, path, "HEAD").status === 0;
|
|
1438
1685
|
if (!created) throw new Abort(`could not create ${branch} in ${checkout.name}`);
|
|
1439
1686
|
worktrees.push({ repo: checkout.dir, path, tooling });
|
|
1440
1687
|
const envFiles = git(
|
|
@@ -1449,9 +1696,9 @@ if (command === "train") {
|
|
|
1449
1696
|
(file) => /(^|\/)\.env[^/]*$/.test(file) && !/(^|\/)(node_modules|\.worktrees)\//.test(file)
|
|
1450
1697
|
);
|
|
1451
1698
|
for (const file of envFiles) {
|
|
1452
|
-
if (
|
|
1453
|
-
|
|
1454
|
-
|
|
1699
|
+
if (existsSync3(join3(path, file))) continue;
|
|
1700
|
+
mkdirSync3(dirname3(join3(path, file)), { recursive: true });
|
|
1701
|
+
writeFileSync3(join3(path, file), readFileSync3(join3(checkout.dir, file)));
|
|
1455
1702
|
}
|
|
1456
1703
|
return { ...checkout, dir: path };
|
|
1457
1704
|
};
|
|
@@ -1475,8 +1722,8 @@ if (command === "train") {
|
|
|
1475
1722
|
() => {
|
|
1476
1723
|
const branchCheckout = worktree(checkout, branch);
|
|
1477
1724
|
for (const path of [...packagePaths, "bun.lock"]) {
|
|
1478
|
-
if (
|
|
1479
|
-
|
|
1725
|
+
if (existsSync3(join3(checkout.dir, path))) {
|
|
1726
|
+
writeFileSync3(join3(branchCheckout.dir, path), readFileSync3(join3(checkout.dir, path)));
|
|
1480
1727
|
}
|
|
1481
1728
|
}
|
|
1482
1729
|
restore(checkout);
|
|
@@ -1517,7 +1764,7 @@ if (command === "train") {
|
|
|
1517
1764
|
try {
|
|
1518
1765
|
bumpRanges(branchCheckout);
|
|
1519
1766
|
relockAndCheck(branchCheckout, false);
|
|
1520
|
-
if (script &&
|
|
1767
|
+
if (script && spawnSync3("bun", ["run", "train:adopt"], {
|
|
1521
1768
|
cwd: branchCheckout.dir,
|
|
1522
1769
|
stdio: "inherit"
|
|
1523
1770
|
}).status !== 0) {
|
|
@@ -1526,7 +1773,7 @@ if (command === "train") {
|
|
|
1526
1773
|
);
|
|
1527
1774
|
}
|
|
1528
1775
|
git(branchCheckout.dir, "add", "-A");
|
|
1529
|
-
const commit =
|
|
1776
|
+
const commit = spawnSync3("git", ["commit", "-m", `chore: adopt ${label}`], {
|
|
1530
1777
|
cwd: branchCheckout.dir,
|
|
1531
1778
|
stdio: "inherit"
|
|
1532
1779
|
});
|
|
@@ -1555,14 +1802,14 @@ if (command === "train") {
|
|
|
1555
1802
|
if (dryRun && !changes) return false;
|
|
1556
1803
|
return effect(`commit its package.json files + bun.lock in ${checkout.name}`, true, () => {
|
|
1557
1804
|
const tracked = [...packagePaths, "bun.lock"].filter(
|
|
1558
|
-
(path) =>
|
|
1805
|
+
(path) => existsSync3(join3(checkout.dir, path))
|
|
1559
1806
|
);
|
|
1560
1807
|
const mutated = git(checkout.dir, "status", "--porcelain", "--", ...tracked);
|
|
1561
1808
|
if (mutated.status !== 0 || mutated.stdout.trim().length === 0) return false;
|
|
1562
1809
|
if (git(checkout.dir, "add", "--", ...tracked).status !== 0) {
|
|
1563
1810
|
throw new Abort(`git add failed in ${checkout.name} \u2014 is bun.lock ignored?`);
|
|
1564
1811
|
}
|
|
1565
|
-
const commit =
|
|
1812
|
+
const commit = spawnSync3("git", ["commit", "-m", message], {
|
|
1566
1813
|
cwd: checkout.dir,
|
|
1567
1814
|
stdio: "inherit"
|
|
1568
1815
|
});
|
|
@@ -1580,24 +1827,24 @@ if (command === "train") {
|
|
|
1580
1827
|
});
|
|
1581
1828
|
const publishToNpm = (checkout, entry) => {
|
|
1582
1829
|
if (entry.path === "package.json") {
|
|
1583
|
-
return
|
|
1830
|
+
return spawnSync3("npm", ["publish"], { cwd: checkout.dir, stdio: "inherit" }).status === 0;
|
|
1584
1831
|
}
|
|
1585
|
-
const memberDir =
|
|
1586
|
-
const out = mkdtempSync(
|
|
1832
|
+
const memberDir = join3(checkout.dir, dirname3(entry.path));
|
|
1833
|
+
const out = mkdtempSync(join3(tmpdir(), "inixiative-train-"));
|
|
1587
1834
|
try {
|
|
1588
|
-
const pack =
|
|
1835
|
+
const pack = spawnSync3("bun", ["pm", "pack", "--destination", out], {
|
|
1589
1836
|
cwd: memberDir,
|
|
1590
1837
|
stdio: "inherit"
|
|
1591
1838
|
});
|
|
1592
|
-
const tarball =
|
|
1839
|
+
const tarball = readdirSync3(out).find((name) => name.endsWith(".tgz"));
|
|
1593
1840
|
if (pack.status !== 0 || !tarball) return false;
|
|
1594
|
-
return
|
|
1841
|
+
return spawnSync3("npm", ["publish", join3(out, tarball)], { cwd: memberDir, stdio: "inherit" }).status === 0;
|
|
1595
1842
|
} finally {
|
|
1596
|
-
|
|
1843
|
+
rmSync3(out, { recursive: true, force: true });
|
|
1597
1844
|
}
|
|
1598
1845
|
};
|
|
1599
1846
|
const npmLatest = (name) => {
|
|
1600
|
-
const remote =
|
|
1847
|
+
const remote = spawnSync3("npm", ["view", `${name}@latest`, "version"], { encoding: "utf8" });
|
|
1601
1848
|
return remote.status === 0 ? remote.stdout.trim() : null;
|
|
1602
1849
|
};
|
|
1603
1850
|
for (const { lane: lane2, checkouts, missing, ambiguous } of plan.lanes) {
|
|
@@ -1626,7 +1873,7 @@ if (command === "train") {
|
|
|
1626
1873
|
continue;
|
|
1627
1874
|
}
|
|
1628
1875
|
const releases = checkout.packages.map((entry) => {
|
|
1629
|
-
const local = JSON.parse(
|
|
1876
|
+
const local = JSON.parse(readFileSync3(join3(checkout.dir, entry.path), "utf8")).version ?? "0.0.0";
|
|
1630
1877
|
const remote = npmLatest(entry.name);
|
|
1631
1878
|
return { entry, local, remote, ahead: remote === null || compare(local, remote) > 0 };
|
|
1632
1879
|
});
|
|
@@ -1816,10 +2063,10 @@ blessed: ${promoted.length === 0 ? "nothing" : promoted.join(", ")}`);
|
|
|
1816
2063
|
version = bumpPatch(remoteVersion);
|
|
1817
2064
|
const bumped = version;
|
|
1818
2065
|
effect(`bump @inixiative/config to ${bumped} in package.json`, void 0, () => {
|
|
1819
|
-
const pkgPath =
|
|
1820
|
-
const pkg = JSON.parse(
|
|
2066
|
+
const pkgPath = join3(packageRoot, "package.json");
|
|
2067
|
+
const pkg = JSON.parse(readFileSync3(pkgPath, "utf8"));
|
|
1821
2068
|
pkg.version = bumped;
|
|
1822
|
-
|
|
2069
|
+
writeFileSync3(pkgPath, `${JSON.stringify(pkg, null, 2)}
|
|
1823
2070
|
`);
|
|
1824
2071
|
});
|
|
1825
2072
|
}
|
|
@@ -1838,7 +2085,7 @@ blessed: ${promoted.length === 0 ? "nothing" : promoted.join(", ")}`);
|
|
|
1838
2085
|
}
|
|
1839
2086
|
);
|
|
1840
2087
|
effect("run bun run check in @inixiative/config", void 0, () => {
|
|
1841
|
-
const check =
|
|
2088
|
+
const check = spawnSync3("bun", ["run", "check"], { cwd: packageRoot, stdio: "inherit" });
|
|
1842
2089
|
if (check.status !== 0) {
|
|
1843
2090
|
console.error("\u2717 check failed in @inixiative/config \u2014 aborting before publish");
|
|
1844
2091
|
process.exit(1);
|
|
@@ -1849,12 +2096,12 @@ blessed: ${promoted.length === 0 ? "nothing" : promoted.join(", ")}`);
|
|
|
1849
2096
|
recorded.length > 0 ? `candidate ${recorded.join(", ")}` : ""
|
|
1850
2097
|
].filter(Boolean).join("; ") || "release"} \u2014 ${version}`;
|
|
1851
2098
|
effect(`commit "${message}" in @inixiative/config`, void 0, () => {
|
|
1852
|
-
|
|
2099
|
+
spawnSync3("git", ["add", "--", "package.json", "versions.json", "test/fixtures"], {
|
|
1853
2100
|
cwd: packageRoot
|
|
1854
2101
|
});
|
|
1855
|
-
if (
|
|
2102
|
+
if (spawnSync3("git", ["diff", "--cached", "--quiet"], { cwd: packageRoot }).status === 0)
|
|
1856
2103
|
return;
|
|
1857
|
-
const commit =
|
|
2104
|
+
const commit = spawnSync3("git", ["commit", "-m", message], {
|
|
1858
2105
|
cwd: packageRoot,
|
|
1859
2106
|
stdio: "inherit"
|
|
1860
2107
|
});
|
|
@@ -1864,7 +2111,7 @@ blessed: ${promoted.length === 0 ? "nothing" : promoted.join(", ")}`);
|
|
|
1864
2111
|
}
|
|
1865
2112
|
});
|
|
1866
2113
|
effect(`publish @inixiative/config@${version} to npm`, void 0, () => {
|
|
1867
|
-
const publish2 =
|
|
2114
|
+
const publish2 = spawnSync3("npm", ["publish"], { cwd: packageRoot, stdio: "inherit" });
|
|
1868
2115
|
if (publish2.status !== 0 || !servedByRegistry("@inixiative/config", version)) {
|
|
1869
2116
|
console.error("\u2717 publish failed for @inixiative/config");
|
|
1870
2117
|
process.exit(1);
|
|
@@ -1898,17 +2145,17 @@ dry run complete \u2014 a real train would commit in ${committed.size} repo(s) a
|
|
|
1898
2145
|
for (const { dir: repoDir, branch } of reviewBranches) console.log(` ${repoDir} (${branch})`);
|
|
1899
2146
|
} else if (commandLine.push) {
|
|
1900
2147
|
for (const repoDir of committed) {
|
|
1901
|
-
if (
|
|
2148
|
+
if (spawnSync3("git", ["push"], { cwd: repoDir, stdio: "inherit" }).status !== 0) {
|
|
1902
2149
|
console.error(`\u2717 push failed in ${repoDir}`);
|
|
1903
2150
|
process.exit(1);
|
|
1904
2151
|
}
|
|
1905
2152
|
}
|
|
1906
2153
|
for (const { dir: repoDir, branch, base } of reviewBranches) {
|
|
1907
|
-
const push =
|
|
2154
|
+
const push = spawnSync3("git", ["push", "-u", "origin", branch], {
|
|
1908
2155
|
cwd: repoDir,
|
|
1909
2156
|
stdio: "inherit"
|
|
1910
2157
|
});
|
|
1911
|
-
const pr = push.status === 0 &&
|
|
2158
|
+
const pr = push.status === 0 && spawnSync3("gh", ["pr", "create", "--fill", "--base", base, "--head", branch], {
|
|
1912
2159
|
cwd: repoDir,
|
|
1913
2160
|
stdio: "inherit"
|
|
1914
2161
|
}).status === 0;
|
|
@@ -1927,7 +2174,7 @@ dry run complete \u2014 a real train would commit in ${committed.size} repo(s) a
|
|
|
1927
2174
|
process.exit(failed.length > 0 ? 1 : 0);
|
|
1928
2175
|
}
|
|
1929
2176
|
function prUrl(cwd, branch) {
|
|
1930
|
-
const view =
|
|
2177
|
+
const view = spawnSync3("gh", ["pr", "view", branch, "--json", "url", "--jq", ".url"], {
|
|
1931
2178
|
cwd,
|
|
1932
2179
|
encoding: "utf8"
|
|
1933
2180
|
});
|
|
@@ -1945,7 +2192,7 @@ function freeBranch(cwd, name) {
|
|
|
1945
2192
|
function servedByRegistry(name, version) {
|
|
1946
2193
|
const deadline = Date.now() + 15 * 6e4;
|
|
1947
2194
|
while (true) {
|
|
1948
|
-
const view =
|
|
2195
|
+
const view = spawnSync3("npm", ["view", `${name}@${version}`, "version", "--prefer-online"], {
|
|
1949
2196
|
encoding: "utf8"
|
|
1950
2197
|
});
|
|
1951
2198
|
if (view.status === 0 && view.stdout.trim() === version) return true;
|
|
@@ -1958,12 +2205,12 @@ function bumpPatch(version) {
|
|
|
1958
2205
|
return `${major}.${minor}.${(patch ?? 0) + 1}`;
|
|
1959
2206
|
}
|
|
1960
2207
|
function fixtureDirs() {
|
|
1961
|
-
const root =
|
|
1962
|
-
if (!
|
|
1963
|
-
return
|
|
2208
|
+
const root = join3(packageRoot, "test", "fixtures");
|
|
2209
|
+
if (!existsSync3(root)) return [];
|
|
2210
|
+
return readdirSync3(root).map((name) => join3(root, name)).filter((dir2) => existsSync3(join3(dir2, "package.json")));
|
|
1964
2211
|
}
|
|
1965
|
-
if (
|
|
1966
|
-
const status =
|
|
2212
|
+
if (existsSync3(join3(dir, ".git")) && !commandLine.force) {
|
|
2213
|
+
const status = spawnSync3("git", ["status", "--porcelain"], { cwd: dir, encoding: "utf8" });
|
|
1967
2214
|
if (status.status === 0 && status.stdout.trim().length > 0) {
|
|
1968
2215
|
console.error("\u2717 working tree dirty \u2014 commit first or pass --force");
|
|
1969
2216
|
process.exit(1);
|
|
@@ -1977,14 +2224,14 @@ if (fixed > 0) console.log(`applied ${fixed} fix${fixed === 1 ? "" : "es"}`);
|
|
|
1977
2224
|
if (!commandLine.noInstall) {
|
|
1978
2225
|
const relinked = new Set(
|
|
1979
2226
|
first.findings.flatMap(
|
|
1980
|
-
(finding) => finding.kind === "member-toolchain" && finding.path ? [
|
|
2227
|
+
(finding) => finding.kind === "member-toolchain" && finding.path ? [dirname3(finding.path)] : []
|
|
1981
2228
|
)
|
|
1982
2229
|
);
|
|
1983
2230
|
for (const member of relinked) {
|
|
1984
|
-
|
|
2231
|
+
rmSync3(join3(dir, member, "node_modules"), { recursive: true, force: true });
|
|
1985
2232
|
}
|
|
1986
2233
|
const install = (...extra) => {
|
|
1987
|
-
if (
|
|
2234
|
+
if (spawnSync3("bun", ["install", ...extra], { cwd: dir, stdio: "inherit" }).status !== 0) {
|
|
1988
2235
|
console.error("\u2717 bun install failed");
|
|
1989
2236
|
process.exit(1);
|
|
1990
2237
|
}
|
|
@@ -1996,7 +2243,7 @@ if (!commandLine.noInstall) {
|
|
|
1996
2243
|
installed = inspect(dir, manifest, presetFlag);
|
|
1997
2244
|
}
|
|
1998
2245
|
for (const { cwd, names } of staleUpdates(dir, installed.findings)) {
|
|
1999
|
-
if (
|
|
2246
|
+
if (spawnSync3("bun", ["update", ...names], { cwd, stdio: "inherit" }).status !== 0) {
|
|
2000
2247
|
console.error(`\u2717 bun update failed in ${cwd}`);
|
|
2001
2248
|
process.exit(1);
|
|
2002
2249
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inixiative/config",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.185",
|
|
4
4
|
"description": "Shared toolchain for the inixiative ecosystem: tsconfig/biome/tsup presets, a version manifest (BOM), and a sync/check CLI",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -39,7 +39,9 @@
|
|
|
39
39
|
},
|
|
40
40
|
"./ports.json": "./ports.json",
|
|
41
41
|
"./theme/public.css": "./theme/public.css",
|
|
42
|
-
"./theme/
|
|
42
|
+
"./theme/status.css": "./theme/status.css",
|
|
43
|
+
"./theme/domains.css": "./theme/domains.css",
|
|
44
|
+
"./theme/marketing.css": "./theme/marketing.css",
|
|
43
45
|
"./theme/fonts/*": "./theme/fonts/*"
|
|
44
46
|
},
|
|
45
47
|
"scripts": {
|