@norskvideo/ctl-dev-kit 0.2.67 → 0.2.69

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.
@@ -9,6 +9,24 @@
9
9
  # need GitHub auth in every shell and CI runner.
10
10
  { pkgs, biome }:
11
11
  let
12
+ # Bun from its own nixpkgs pin, so ctl and every product run one Bun, and
13
+ # bumping it is one edit here (the dev-kit sync carries it to the products)
14
+ # rather than moving the main nixpkgs pin, and with it Chromium and every
15
+ # other tool. Fetched by hash, so each repo shares one store path.
16
+ #
17
+ # 1.4.2: 1.3.13's node:http2 client segfaulted in its HPACK encoder
18
+ # (lshpack.HPACK.encode from H2FrameParser.request) — norsk-mgr's gRPC client
19
+ # to the Manager, killed mid-drain and mid-migration in the nightly e2e.
20
+ # Keep each repo's package.json "packageManager" (its image's Bun) on the
21
+ # same version. That nixpkgs no longer builds x86_64-darwin, which keeps the
22
+ # main pin's.
23
+ bun =
24
+ if pkgs.stdenv.hostPlatform.system == "x86_64-darwin" then pkgs.bun
25
+ else (import (builtins.fetchTarball {
26
+ url = "https://github.com/NixOS/nixpkgs/archive/e7439b6b14ad3cc35d05608ebca9bce01a25f5f8.tar.gz"; # bun 1.4.2
27
+ sha256 = "19y4py973w62z4qb7gzn0chjs67ihxy8rbjb7g71iyk8yz7z5k8z";
28
+ }) { inherit (pkgs.stdenv.hostPlatform) system; }).bun;
29
+
12
30
  # Playwright doc-guide browser. nix-pinned headless Chromium needs a real X
13
31
  # display on a truly headless box (page.fill silently no-ops on plain HTML
14
32
  # inputs; some pages crash the renderer). Ubuntu's apt Xvfb is too old for
@@ -42,7 +60,7 @@ let
42
60
 
43
61
  buildTools = [
44
62
  biome
45
- pkgs.bun
63
+ bun
46
64
  pkgs.nodejs # @biomejs/biome's bin is a JS wrapper, not the binary — it is
47
65
  # what reads BIOME_BINARY and execs the nix build. Something has
48
66
  # to *parse* that wrapper first, so a modern node has to be on
@@ -91,7 +109,7 @@ let
91
109
  };
92
110
  in
93
111
  {
94
- inherit browserInputs browserHook buildTools mkCtl shell;
112
+ inherit browserInputs browserHook buildTools bun mkCtl shell;
95
113
 
96
114
  # The Studio-product shells:
97
115
  # default / dev -> build tools + the pinned norsk-ctl daemon on PATH
package/build/flake.nix CHANGED
@@ -19,7 +19,7 @@
19
19
  description = "norsk-ctl product build + dev shell";
20
20
 
21
21
  inputs = {
22
- nixpkgs.url = "github:NixOS/nixpkgs/d233902339c02a9c334e7e593de68855ad26c4cb"; # nixpkgs-unstable 2026-05-15, bun 1.3.13, chromium 148.0.7778.167
22
+ nixpkgs.url = "github:NixOS/nixpkgs/d233902339c02a9c334e7e593de68855ad26c4cb"; # nixpkgs-unstable 2026-05-15, chromium 148.0.7778.167 (bun comes from its own pin in nix/ctl-shell.nix)
23
23
  # Biome must match the version pinned in package.json (@biomejs/biome 2.5.5)
24
24
  # exactly: 2.4.x can't parse this repo's biome.json (`rules.preset` is a
25
25
  # 2.5 key) and any other 2.5.x emits a version-mismatch info that breaks the
@@ -13,12 +13,12 @@
13
13
  # result belongs to a commit, and moved nightly by bump.yml. Decision: bun for tooling (install / build /
14
14
  # test), Node for the shipped runtime (the SDK's blessed runtime).
15
15
  #
16
- # nixpkgs is pinned to the same rev the Studio flake uses, so bun matches the
17
- # fleet's 1.3.13.
16
+ # nixpkgs is pinned to the same rev the Studio flake uses, so the store is
17
+ # shared; bun is the fleet's, from its own pin in nix/ctl-shell.nix.
18
18
  description = "norsk-ctl sdk-app product dev shell (bun tooling + node runtime)";
19
19
 
20
20
  inputs = {
21
- nixpkgs.url = "github:NixOS/nixpkgs/d233902339c02a9c334e7e593de68855ad26c4cb"; # nixpkgs-unstable 2026-05-15, bun 1.3.13
21
+ nixpkgs.url = "github:NixOS/nixpkgs/d233902339c02a9c334e7e593de68855ad26c4cb"; # nixpkgs-unstable 2026-05-15 (bun comes from its own pin in nix/ctl-shell.nix)
22
22
  # Biome must match the version pinned in package.json (@biomejs/biome 2.5.5)
23
23
  # exactly; the node_modules biome binary is glibc-linked and can't run on
24
24
  # NixOS, so `bun run lint` execs this nix build via BIOME_BINARY. Keep this
@@ -45,7 +45,7 @@
45
45
  ffmpegFull = pkgs.ffmpeg-full;
46
46
  tools = [
47
47
  biome # `bun run lint` execs this via BIOME_BINARY
48
- pkgs.bun # tooling: install / build / test (fleet parity, dev-kit)
48
+ ctlShell.bun # tooling: install / build / test; its own pin, shared with ctl and every product
49
49
  pkgs.nodejs # the shipped runtime (bin/run -> node lib/index.js); also
50
50
  # parses @biomejs/biome's JS wrapper that reads BIOME_BINARY
51
51
  pkgs.git
@@ -412,6 +412,38 @@ export function productLogsProblems(repoRoot: string): string[] {
412
412
  ];
413
413
  }
414
414
 
415
+ /** The Bun the dev-kit's build/ctl-shell.nix pins: the version its pin's URL
416
+ * line names (`… .tar.gz"; # bun 1.4.2`). The shell runs it; the product's
417
+ * image runs package.json's "packageManager", which must name the same. */
418
+ export function pinnedBunVersion(ctlShell: string): string | undefined {
419
+ return /archive\/[0-9a-f]{40}\.tar\.gz"; # bun (\d+\.\d+\.\d+)/.exec(ctlShell)?.[1];
420
+ }
421
+
422
+ /** package.json's "packageManager" against the shell's Bun. They drifted once
423
+ * already: the fleet's shells and images ran 1.3.13 by agreement alone, and a
424
+ * move to 1.4.2 (1.3.13's HTTP/2 client segfaulted) had to touch every repo. */
425
+ export function bunVersionProblems(repoRoot: string, ctlShellCanonical: string): string[] {
426
+ const want = pinnedBunVersion(ctlShellCanonical);
427
+ if (want === undefined) {
428
+ return ["@norskvideo/ctl-dev-kit build/ctl-shell.nix names no Bun version on its pin (`# bun X.Y.Z`)."];
429
+ }
430
+ const pkgPath = join(repoRoot, "package.json");
431
+ if (!existsSync(pkgPath)) return [];
432
+ let have: unknown;
433
+ try {
434
+ have = (JSON.parse(readFileSync(pkgPath, "utf8")) as { packageManager?: unknown }).packageManager;
435
+ } catch (e) {
436
+ return [`package.json is not parseable JSON (${e instanceof Error ? e.message : String(e)}).`];
437
+ }
438
+ return have === `bun@${want}`
439
+ ? []
440
+ : [
441
+ `package.json "packageManager" is ${JSON.stringify(have ?? null)}, not "bun@${want}": it is the Bun the ` +
442
+ "product's image runs, and must be the one the shell runs (@norskvideo/ctl-dev-kit build/ctl-shell.nix). " +
443
+ "Re-sync to set it.",
444
+ ];
445
+ }
446
+
415
447
  // A file that must be a verbatim, byte-for-byte copy of its dev-kit canonical.
416
448
  function verbatimProblem(
417
449
  repoRoot: string,
@@ -862,6 +894,7 @@ export function checkDrift(repoRoot: string, canonical: CanonicalBytes, opts: Ch
862
894
 
863
895
  for (const p of demoProblems(repoRoot, canonical.demoShim)) push(p);
864
896
  for (const p of productLogsProblems(repoRoot)) push(p);
897
+ for (const p of bunVersionProblems(repoRoot, canonical.ctlShell)) push(p);
865
898
  for (const p of ctlPinProblems(repoRoot)) push(p);
866
899
 
867
900
  return { ok: problems.length === 0, problems };
@@ -48,6 +48,7 @@ import {
48
48
  PRODUCT_SENTINEL,
49
49
  type ProductShape,
50
50
  PUBLISH_IMAGE_LINE,
51
+ pinnedBunVersion,
51
52
  RETIRED_BUMP_WORKFLOWS,
52
53
  RUNNER_LINE,
53
54
  resolveRepoName,
@@ -401,6 +402,29 @@ function syncDocsTheme(repoRoot: string, r: SyncReport): void {
401
402
  for (const rel of adrift) r.written.push(`${DOCS_SITE_DIR}/${rel}`);
402
403
  }
403
404
 
405
+ // package.json "packageManager": the Bun the product's image runs, set to the
406
+ // one the shell pins (build/ctl-shell.nix), so a Bun move reaches every
407
+ // product through its sync. Only that field's value is rewritten, so the
408
+ // file's own formatting stays. A package.json with no field is left for the
409
+ // gate to flag.
410
+ function syncPackageManager(repoRoot: string, ctlShell: string, r: SyncReport): void {
411
+ const want = pinnedBunVersion(ctlShell);
412
+ const path = join(repoRoot, "package.json");
413
+ if (want === undefined || !existsSync(path)) return;
414
+ const current = readFileSync(path, "utf8");
415
+ const field = /("packageManager"\s*:\s*")[^"]*(")/;
416
+ if (!field.test(current)) {
417
+ r.skipped.push("package.json (no packageManager to set)");
418
+ return;
419
+ }
420
+ writeIfChanged(
421
+ path,
422
+ current.replace(field, (_m, a: string, b: string) => `${a}bun@${want}${b}`),
423
+ "package.json",
424
+ r.written,
425
+ );
426
+ }
427
+
404
428
  export function syncDrift(
405
429
  repoRoot: string,
406
430
  canonical: CanonicalBytes,
@@ -448,6 +472,7 @@ export function syncDrift(
448
472
 
449
473
  mkdirSync(dirname(join(repoRoot, CTL_SHELL_PATH)), { recursive: true });
450
474
  writeIfChanged(join(repoRoot, CTL_SHELL_PATH), canonical.ctlShell, CTL_SHELL_PATH, r.written);
475
+ syncPackageManager(repoRoot, canonical.ctlShell, r);
451
476
  syncFlake(repoRoot, flakeCanon, r);
452
477
  syncClaude(repoRoot, canonical.core, r);
453
478
  syncGitignore(repoRoot, canonical.gitignoreCore, r);
@@ -13,6 +13,8 @@
13
13
  // from the schema package, addComponent/stubbedLibrary with a THROWING
14
14
  // validate(), INVARIANTS + parity + byte-snapshot + studio-load wired into
15
15
  // test:unit, and an image smoke tier.
16
+
17
+ import { pinnedBunVersion } from "../conventions/check-drift.ts";
16
18
  import {
17
19
  type GeneratedFile,
18
20
  PRODUCT_ZOD,
@@ -362,7 +364,8 @@ function rootPackageJson(ctx: ShapeContext): string {
362
364
  "@types/node": "^22.10.0",
363
365
  typescript: "^5.7.2",
364
366
  },
365
- packageManager: "bun@1.3.13",
367
+ // The shell's Bun (build/ctl-shell.nix): the drift gate holds the two together.
368
+ packageManager: `bun@${pinnedBunVersion(ctx.canon.ctlShell)}`,
366
369
  overrides: {
367
370
  ws: "^8.20.1",
368
371
  "shell-quote": "^1.9.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@norskvideo/ctl-dev-kit",
3
- "version": "0.2.67",
3
+ "version": "0.2.69",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./create-product": "./create-product/create-product.ts",
@@ -38,7 +38,7 @@
38
38
  },
39
39
  "devDependencies": {
40
40
  "@norskvideo/ctl-oas-to-ts": "^0.1.0",
41
- "@norskvideo/norsk-sdk": "1.3.1-2026-10-09-a8949250",
41
+ "@norskvideo/norsk-sdk": "1.3.1-2026-10-10-c587f1cc",
42
42
  "@norskvideo/norsk-studio": "1.30.0-2026-10-10-c2e37ae9",
43
43
  "@norskvideo/norsk-studio-builder": "1.30.0-2026-10-10-c2e37ae9",
44
44
  "@norskvideo/norsk-studio-built-ins": "1.30.0-2026-10-10-c2e37ae9",