@inixiative/config 0.5.45 → 0.5.47
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 +3 -3
- package/dist/cli.js +28 -8
- package/package.json +1 -1
- package/versions.json +6 -6
package/README.md
CHANGED
|
@@ -71,11 +71,11 @@ bunx @inixiative/config ports [project]
|
|
|
71
71
|
|
|
72
72
|
`ports` prints each project's local ports from `ports.json` (also exported as `@inixiative/config/ports.json`). A project's port for a service is the service's usual default plus 100 times the project's block, so no two projects collide and none sits on a default: Archive (block 7) serves HTTP on 4700 with Postgres on 6132; Kingdom (block 2) has web 3200, API 8200, Postgres 5632, Redis 6579. Reserved ports (macOS AirPlay on 5000 and 7000) are never assigned. Give a new project the next free block, and a new kind of service its usual default; the tests fail on any collision.
|
|
73
73
|
|
|
74
|
-
`check` is read-only and exits non-zero on drift — run it in CI after a frozen-lockfile install. It verifies toolchain pins — declared once, at the root, pinned exactly: a workspace member declaring one is an error, and `bun.lock` must resolve each only to its pin (no second copy) — toolchain peer ranges (they must admit the pin and no older major; `sync` writes `>=<pin major>.<pin minor>.0`), `"latest"` ranges, `packageManager`/`.bun-version`, legacy `bun.lockb`, a committed (tracked, un-ignored) `bun.lock`, required scripts (`check`/`typecheck`/`lint`/`test`), lefthook (dep + `lefthook.yml` extending the shared hooks + `prepare` script; git repos only), stub `extends`, presence of this package, and for every ecosystem dependency — in the root or any workspace member, of either lane — that the declared range admits the blessed version and the lockfile actually resolves to it (the stale-lockfile class). An npm alias (`"@inixiative/session-archive": "npm:@inixiative/archive@^0.2.1"`) is held to its target's blessed version and rewritten as an alias; `workspace:`, `file:` and `link:` ranges are a repo linking itself and are left alone.
|
|
74
|
+
`check` is read-only and exits non-zero on drift — run it in CI after a frozen-lockfile install. It verifies toolchain pins — declared once, at the root, pinned exactly: a workspace member declaring one is an error, and `bun.lock` must resolve each only to its pin (no second copy) — toolchain peer ranges (they must admit the pin and no older major; `sync` writes `>=<pin major>.<pin minor>.0`), `"latest"` ranges, `packageManager`/`.bun-version`, legacy `bun.lockb`, a committed (tracked, un-ignored) `bun.lock`, required scripts (`check`/`typecheck`/`lint`/`test`), lefthook (dep + `lefthook.yml` extending the shared hooks + `prepare` script; git repos only), stub `extends`, presence of this package, and for every ecosystem dependency — in the root or any workspace member, of either lane — that the declared range admits the blessed version and the lockfile actually resolves to it (the stale-lockfile class). A range that does not admit the blessed version is rewritten to `^<blessed>`, except an exact pin, which stays exact and moves to the blessed version. An npm alias (`"@inixiative/session-archive": "npm:@inixiative/archive@^0.2.1"`) is held to its target's blessed version and rewritten as an alias; `workspace:`, `file:` and `link:` ranges are a repo linking itself and are left alone.
|
|
75
75
|
|
|
76
76
|
`sync` applies every fix (deleting member toolchain entries and their stale member links), re-locks via `bun install` (`--force` when a second toolchain copy survives), and runs `bun update` on stale ecosystem entries in the directory that declares them. It refuses to run on a dirty working tree without `--force`. The react preset is inferred from a `react` dependency; override with `--preset`. Missing scripts are filled with defaults; existing script bodies are never touched.
|
|
77
77
|
|
|
78
|
-
`scan` runs `check` across every ecosystem checkout under a root directory, for every lane or just the one `--lane` names. Targets are derived from the BOM: lane packages match by package name — the root package or any workspace member, so a monorepo such as foundry is found by the packages it publishes — and consumers match by their `origin` GitHub repo. Directory names and local layout never need declaring: scan looks at each child of the root and one level into a child without a `package.json` (a workspace folder such as `kingdom-workspace/`). Linked git worktrees are other sessions' branches and never targets; when several clones claim one package or repo, only those with an `origin` remote count, and if that still leaves more than one the target is reported ambiguous rather than guessed. Origin is the truth, not the checkout: scan fetches per repo and fails on checkouts behind origin (their findings describe a stale tree), fails when a BOM entry has no checkout at all, warns when a checkout sits on a non-default branch (its findings describe the branch, not what ships), and surfaces unmerged `claude/*` session branches.
|
|
78
|
+
`scan` runs `check` across every ecosystem checkout under a root directory, for every lane or just the one `--lane` names. Targets are derived from the BOM: lane packages match by package name — the root package or any workspace member, so a monorepo such as foundry is found by the packages it publishes — and consumers match by their `origin` GitHub repo. Directory names and local layout never need declaring: scan looks at each child of the root and one level into a child without a `package.json` (a workspace folder such as `kingdom-workspace/`). Linked git worktrees are other sessions' branches and never targets; when several clones claim one package or repo, only those with an `origin` remote count, a clone directly under the root wins over one nested in a workspace folder, and if that still leaves more than one the target is reported ambiguous rather than guessed. Origin is the truth, not the checkout: scan fetches per repo and fails on checkouts behind origin (their findings describe a stale tree), fails when a BOM entry has no checkout at all, warns when a checkout sits on a non-default branch (its findings describe the branch, not what ships), and surfaces unmerged `claude/*` session branches.
|
|
79
79
|
|
|
80
80
|
`train` is the release cascade, run from this repo's checkout. It walks every lane in order (primitives, then agentic), or only the lane `--lane` names. Origin is the truth: it refuses to run from a config checkout behind origin, and it fast-forwards clean checkouts to origin before working (dirty or diverged repos still skip). It only ships the default branch: a checkout on a feature branch is skipped whole — never re-locked, committed to, or published from.
|
|
81
81
|
|
|
@@ -83,7 +83,7 @@ Lanes stand alone. A lane with a package missing a checkout, or claimed by ambig
|
|
|
83
83
|
|
|
84
84
|
Consumers run once, after every selected lane, upstreams first, against the full blessed set: a consumer of both lanes ends coherent with both whichever lane ran. They get the same bump → re-lock → `check`, never a publish, and their changes go through review: the train commits them on a `train/ecosystem-sync-<date>` branch and leaves the checkout there until it is merged.
|
|
85
85
|
|
|
86
|
-
When anything was blessed it then ships this package last, so the BOM names the new state: bumps its own patch version if npm already has the current one, blesses that version in the BOM, brings the `test/fixtures` consumers onto the blessed set, runs `check`, commits, publishes. It never pushes unless asked: pass `--push` to push every repo it committed to and open a PR for each consumer branch; otherwise it prints the commands.
|
|
86
|
+
When anything was blessed it then ships this package last, so the BOM names the new state: bumps its own patch version if npm already has the current one, blesses that version in the BOM, brings the `test/fixtures` consumers onto the blessed set, runs `check`, commits, publishes. Then every checkout the train re-locked (lane packages on their default branch, consumers on their review branch) is re-locked onto that new `@inixiative/config` and committed, so none is left pinning the previous release. It never pushes unless asked: pass `--push` to push every repo it committed to and open a PR for each consumer branch; otherwise it prints the commands.
|
|
87
87
|
|
|
88
88
|
Division of labor: this CLI owns the toolchain set, ecosystem coherence, stubs, and lockfile format. Renovate owns everything else plus bumping `@inixiative/config` itself, and must be fenced off the toolchain packages.
|
|
89
89
|
|
package/dist/cli.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
import { spawnSync as spawnSync2 } from "child_process";
|
|
5
5
|
import { existsSync as existsSync2, mkdtempSync, readdirSync as readdirSync2, readFileSync as readFileSync2, rmSync as rmSync2, writeFileSync as writeFileSync2 } from "fs";
|
|
6
6
|
import { tmpdir } from "os";
|
|
7
|
-
import { dirname as dirname2, join as join2, resolve } from "path";
|
|
7
|
+
import { dirname as dirname2, join as join2, resolve as resolve2 } from "path";
|
|
8
8
|
|
|
9
9
|
// src/lib.ts
|
|
10
10
|
import { spawnSync } from "child_process";
|
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
statSync,
|
|
18
18
|
writeFileSync
|
|
19
19
|
} from "fs";
|
|
20
|
-
import { dirname, join, sep } from "path";
|
|
20
|
+
import { dirname, join, resolve, sep } from "path";
|
|
21
21
|
import { fileURLToPath } from "url";
|
|
22
22
|
var packageRoot = join(dirname(fileURLToPath(import.meta.url)), "..");
|
|
23
23
|
var LANES = ["primitives", "agentic"];
|
|
@@ -250,7 +250,9 @@ var discover = (root, manifest2, lanes2 = LANES) => {
|
|
|
250
250
|
const chosen = /* @__PURE__ */ new Map();
|
|
251
251
|
const ambiguous = [];
|
|
252
252
|
for (const [key, candidates] of claims) {
|
|
253
|
-
|
|
253
|
+
let pool = candidates.length > 1 ? candidates.filter((candidate) => originRepo(candidate.dir)) : candidates;
|
|
254
|
+
const direct = pool.filter((candidate) => dirname(candidate.dir) === resolve(root));
|
|
255
|
+
if (pool.length > 1 && direct.length === 1) pool = direct;
|
|
254
256
|
if (pool.length === 1) chosen.set(pool[0].dir, pool[0]);
|
|
255
257
|
else ambiguous.push({ key, dirs: candidates.map((candidate) => candidate.dir).sort() });
|
|
256
258
|
}
|
|
@@ -673,13 +675,14 @@ function inspect(dir2, manifest2, presetOverride) {
|
|
|
673
675
|
const rewrite = (next) => name === key ? next : `npm:${name}@${next}`;
|
|
674
676
|
const ok = admits(range, blessed);
|
|
675
677
|
if (ok === false) {
|
|
678
|
+
const next = /^\d+\.\d+\.\d+(?:-[\w.-]+)?$/.test(range) ? blessed : `^${blessed}`;
|
|
676
679
|
findings.push({
|
|
677
680
|
level: "error",
|
|
678
681
|
kind: "ecosystem-range",
|
|
679
682
|
name,
|
|
680
|
-
message: `${target.label}${key} ${field} range ${spec} does not admit blessed ${blessed} \u2192 ${rewrite(
|
|
683
|
+
message: `${target.label}${key} ${field} range ${spec} does not admit blessed ${blessed} \u2192 ${rewrite(next)}`,
|
|
681
684
|
fix: () => {
|
|
682
|
-
deps[key] = rewrite(
|
|
685
|
+
deps[key] = rewrite(next);
|
|
683
686
|
target.mark();
|
|
684
687
|
}
|
|
685
688
|
});
|
|
@@ -838,7 +841,7 @@ var flags = new Set(args.filter((arg) => arg.startsWith("--")).map((arg) => arg.
|
|
|
838
841
|
var presetFlag = args.find((arg) => arg.startsWith("--preset="))?.split("=")[1];
|
|
839
842
|
var laneFlag = args.find((arg) => arg.startsWith("--lane="))?.split("=")[1];
|
|
840
843
|
var positional = args.slice(1).filter((arg) => !arg.startsWith("--"));
|
|
841
|
-
var dir =
|
|
844
|
+
var dir = resolve2(positional[0] ?? ".");
|
|
842
845
|
var usage = () => {
|
|
843
846
|
console.log(
|
|
844
847
|
"Usage: inixiative-config <check|sync|scan|train> [dir] [--preset=base|node|react] [--lane=primitives|agentic] [--force] [--no-install] [--push]\n inixiative-config ports [project]"
|
|
@@ -1025,7 +1028,7 @@ if (command === "train") {
|
|
|
1025
1028
|
staleLock: inspection.findings.some((finding) => finding.kind === "stale-lock")
|
|
1026
1029
|
};
|
|
1027
1030
|
};
|
|
1028
|
-
const relockAndCheck = (checkout) => {
|
|
1031
|
+
const relockAndCheck = (checkout, check = true) => {
|
|
1029
1032
|
if (spawnSync2("bun", ["install"], { cwd: checkout.dir, stdio: "inherit" }).status !== 0) {
|
|
1030
1033
|
throw new Abort(`bun install failed in ${checkout.name}`);
|
|
1031
1034
|
}
|
|
@@ -1035,10 +1038,11 @@ if (command === "train") {
|
|
|
1035
1038
|
)) {
|
|
1036
1039
|
spawnSync2("bun", ["update", ...names], { cwd, stdio: "inherit" });
|
|
1037
1040
|
}
|
|
1038
|
-
if (spawnSync2("bun", ["run", "check"], { cwd: checkout.dir, stdio: "inherit" }).status !== 0) {
|
|
1041
|
+
if (check && spawnSync2("bun", ["run", "check"], { cwd: checkout.dir, stdio: "inherit" }).status !== 0) {
|
|
1039
1042
|
throw new Abort(`check failed in ${checkout.name}`);
|
|
1040
1043
|
}
|
|
1041
1044
|
};
|
|
1045
|
+
const followers = [];
|
|
1042
1046
|
const commitOwned = (checkout, packagePaths) => {
|
|
1043
1047
|
const tracked = [...packagePaths, "bun.lock"];
|
|
1044
1048
|
const mutated = git(checkout.dir, "status", "--porcelain", "--", ...tracked);
|
|
@@ -1120,6 +1124,7 @@ if (command === "train") {
|
|
|
1120
1124
|
if (bumped || staleLock || releases.some((release) => release.ahead))
|
|
1121
1125
|
relockAndCheck(checkout);
|
|
1122
1126
|
if (commitOwned(checkout, inspection.packagePaths)) committed.add(checkout.dir);
|
|
1127
|
+
followers.push(checkout);
|
|
1123
1128
|
for (const { entry, local, remote, ahead } of releases) {
|
|
1124
1129
|
if (ahead) {
|
|
1125
1130
|
console.log(`publishing ${entry.name}@${local} (npm has ${remote ?? "none"})`);
|
|
@@ -1196,6 +1201,7 @@ if (command === "train") {
|
|
|
1196
1201
|
if (git(checkout.dir, "switch", "-c", branch).status !== 0) {
|
|
1197
1202
|
throw new Abort(`could not create ${branch} in ${checkout.name}`);
|
|
1198
1203
|
}
|
|
1204
|
+
followers.push(checkout);
|
|
1199
1205
|
if (commitOwned(checkout, inspection.packagePaths)) {
|
|
1200
1206
|
reviewBranches.push({ dir: checkout.dir, branch, base });
|
|
1201
1207
|
console.log(`committed on ${branch} for review; the checkout stays on it until merged`);
|
|
@@ -1253,6 +1259,20 @@ blessed: ${blessed.length === 0 ? "nothing" : blessed.join(", ")}`);
|
|
|
1253
1259
|
}
|
|
1254
1260
|
committed.add(packageRoot);
|
|
1255
1261
|
console.log(`published: @inixiative/config@${version} \u2014 the BOM names the new state`);
|
|
1262
|
+
for (const checkout of followers) {
|
|
1263
|
+
try {
|
|
1264
|
+
const { inspection, bumped, staleLock } = bumpRanges(checkout);
|
|
1265
|
+
if (!bumped && !staleLock) continue;
|
|
1266
|
+
relockAndCheck(checkout, false);
|
|
1267
|
+
if (commitOwned(checkout, inspection.packagePaths) && !checkout.consumer)
|
|
1268
|
+
committed.add(checkout.dir);
|
|
1269
|
+
console.log(`\u2713 ${checkout.name} locked to @inixiative/config@${version}`);
|
|
1270
|
+
} catch (error) {
|
|
1271
|
+
if (!(error instanceof Abort)) throw error;
|
|
1272
|
+
failed.push(checkout.name);
|
|
1273
|
+
console.error(`\u2717 ${error.message} \u2014 re-lock onto @inixiative/config@${version} by hand`);
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1256
1276
|
}
|
|
1257
1277
|
if (flags.has("--push")) {
|
|
1258
1278
|
for (const repoDir of committed) {
|
package/package.json
CHANGED
package/versions.json
CHANGED
|
@@ -13,20 +13,20 @@
|
|
|
13
13
|
"@types/bun"
|
|
14
14
|
],
|
|
15
15
|
"ecosystem": {
|
|
16
|
-
"@inixiative/config": "0.5.
|
|
16
|
+
"@inixiative/config": "0.5.47",
|
|
17
17
|
"@inixiative/json-rules": "2.26.0",
|
|
18
|
-
"@inixiative/permissions": "0.3.
|
|
19
|
-
"@inixiative/transitions": "0.1.
|
|
18
|
+
"@inixiative/permissions": "0.3.4",
|
|
19
|
+
"@inixiative/transitions": "0.1.1",
|
|
20
20
|
"@inixiative/rules-builder": "0.28.0",
|
|
21
21
|
"@inixiative/prisma-map": "0.2.0",
|
|
22
22
|
"@inixiative/atlas": "0.1.1",
|
|
23
|
-
"@inixiative/gloss": "0.0.
|
|
23
|
+
"@inixiative/gloss": "0.0.5"
|
|
24
24
|
},
|
|
25
25
|
"agentic": {
|
|
26
26
|
"@inixiative/archive": "0.7.0",
|
|
27
27
|
"@inixiative/agent-session": "0.3.1",
|
|
28
|
-
"@inixiative/foundry-core": "0.
|
|
29
|
-
"@inixiative/foundry": "0.
|
|
28
|
+
"@inixiative/foundry-core": "0.3.0",
|
|
29
|
+
"@inixiative/foundry": "0.3.0"
|
|
30
30
|
},
|
|
31
31
|
"consumers": {
|
|
32
32
|
"inixiative/template": {
|