@stll/oxlint-config 1.9.0 → 2.1.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.
Files changed (74) hide show
  1. package/README.md +110 -63
  2. package/dist/cloud-setup-cli.cjs +1 -2
  3. package/dist/cloud-setup-cli.cjs.map +1 -1
  4. package/dist/cloud-setup-cli.mjs +1 -2
  5. package/dist/cloud-setup-cli.mjs.map +1 -1
  6. package/dist/consumer-node-support.cjs +2 -2
  7. package/dist/consumer-node-support.mjs +1 -1
  8. package/dist/dependabot.d.cts +8 -19
  9. package/dist/dependabot.d.mts +8 -19
  10. package/dist/publish-artifact-syntax.cjs +1 -1
  11. package/dist/publish-artifact-syntax.mjs +1 -1
  12. package/dist/publish-contract-cli.cjs +1 -1
  13. package/dist/publish-contract-cli.mjs +1 -1
  14. package/dist/quarantine-cli.cjs +2 -1
  15. package/dist/quarantine-cli.cjs.map +1 -1
  16. package/dist/quarantine-cli.mjs +3 -2
  17. package/dist/quarantine-cli.mjs.map +1 -1
  18. package/dist/quarantine-policy.d.cts +25 -2
  19. package/dist/quarantine-policy.d.mts +25 -2
  20. package/dist/quarantine-policy2.cjs +177 -5
  21. package/dist/quarantine-policy2.cjs.map +1 -1
  22. package/dist/quarantine-policy2.mjs +166 -6
  23. package/dist/quarantine-policy2.mjs.map +1 -1
  24. package/dist/rust-policy-cli.cjs +481 -0
  25. package/dist/rust-policy-cli.cjs.map +1 -0
  26. package/dist/rust-policy-cli.mjs +479 -0
  27. package/dist/rust-policy-cli.mjs.map +1 -0
  28. package/dist/toolchain-changed-cli.cjs +1477 -2
  29. package/dist/toolchain-changed-cli.cjs.map +1 -1
  30. package/dist/toolchain-changed-cli.mjs +1474 -1
  31. package/dist/toolchain-changed-cli.mjs.map +1 -1
  32. package/dist/toolchain-check-cli.cjs +2 -0
  33. package/dist/toolchain-check-cli.cjs.map +1 -1
  34. package/dist/toolchain-check-cli.mjs +2 -0
  35. package/dist/toolchain-check-cli.mjs.map +1 -1
  36. package/dist/toolchain-dependabot.cjs +1 -1
  37. package/dist/toolchain-dependabot.mjs +2 -2
  38. package/dist/toolchain-dependabot.mjs.map +1 -1
  39. package/dist/toolchain-guard.cjs +353 -244
  40. package/dist/toolchain-guard.cjs.map +1 -1
  41. package/dist/toolchain-guard.mjs +348 -245
  42. package/dist/toolchain-guard.mjs.map +1 -1
  43. package/dist/toolchain-inputs.cjs +108 -56
  44. package/dist/toolchain-inputs.cjs.map +1 -1
  45. package/dist/toolchain-inputs.mjs +102 -56
  46. package/dist/toolchain-inputs.mjs.map +1 -1
  47. package/dist/toolchain-schema.cjs +8 -46
  48. package/dist/toolchain-schema.cjs.map +1 -1
  49. package/dist/toolchain-schema.mjs +8 -46
  50. package/dist/toolchain-schema.mjs.map +1 -1
  51. package/dist/typecheck-probe-cli.cjs +40 -2
  52. package/dist/typecheck-probe-cli.cjs.map +1 -1
  53. package/dist/typecheck-probe-cli.mjs +39 -1
  54. package/dist/typecheck-probe-cli.mjs.map +1 -1
  55. package/package.json +4 -4
  56. package/toolchain.json +13 -27
  57. package/dist/toolchain-bun.cjs +0 -34
  58. package/dist/toolchain-bun.cjs.map +0 -1
  59. package/dist/toolchain-bun.mjs +0 -23
  60. package/dist/toolchain-bun.mjs.map +0 -1
  61. package/dist/toolchain-changed.cjs +0 -1484
  62. package/dist/toolchain-changed.cjs.map +0 -1
  63. package/dist/toolchain-changed.mjs +0 -1477
  64. package/dist/toolchain-changed.mjs.map +0 -1
  65. package/dist/typecheck-parity-cli.cjs +0 -71
  66. package/dist/typecheck-parity-cli.cjs.map +0 -1
  67. package/dist/typecheck-parity-cli.mjs +0 -71
  68. package/dist/typecheck-parity-cli.mjs.map +0 -1
  69. package/dist/typecheck-parity.cjs +0 -908
  70. package/dist/typecheck-parity.cjs.map +0 -1
  71. package/dist/typecheck-parity.mjs +0 -897
  72. package/dist/typecheck-parity.mjs.map +0 -1
  73. /package/dist/{typecheck-parity-cli.d.cts → rust-policy-cli.d.cts} +0 -0
  74. /package/dist/{typecheck-parity-cli.d.mts → rust-policy-cli.d.mts} +0 -0
package/README.md CHANGED
@@ -236,11 +236,41 @@ The CLI checks tracked files, prints `path:line: [rule] message` diagnostics,
236
236
  and exits with status 1 on a mismatch. Updating the package updates the
237
237
  policy; update consumer pins and run the checker together.
238
238
 
239
- `typescriptInstallLayouts` declares the compiler package, exact specifier,
240
- and typecheck command for each supported layout. Prefer the direct layout.
241
- Use the split compatibility layout for the compiler-API consumers and peer
242
- blockers listed in `typescript6Compatibility`; it retains the current
243
- compiler for typechecking while providing the compatibility package.
239
+ The `typescript-layout` rule keeps TypeScript out of manifests: type checking
240
+ runs `bun check`, programs and checkers use tsrs, and syntax reads use
241
+ oxc-parser. No manifest, catalog, override or resolution declares `typescript`,
242
+ `@typescript/native` or an `npm:typescript@…` alias unless the repository
243
+ allows it. A `typecheck` script that runs a compiler must run `bun check`.
244
+
245
+ Each repository lists the TypeScript installs its own tools need in
246
+ `typescriptAllowlist` in tracked root `stll-toolchain.json`; there is no shared
247
+ list. An entry names the workspace directory (`.` for the root), the declared
248
+ name, the exact spec the manifest resolves to, the dependency in that same
249
+ workspace that needs it, and a reason:
250
+
251
+ ```json
252
+ {
253
+ "typescriptAllowlist": [
254
+ {
255
+ "workspace": "apps/docs",
256
+ "name": "typescript",
257
+ "spec": "6.0.3",
258
+ "dependency": "@astrojs/check",
259
+ "reason": "astro check loads the TypeScript 6 language service."
260
+ }
261
+ ]
262
+ }
263
+ ```
264
+
265
+ The workspace's `dependencies`, `devDependencies` or `optionalDependencies`
266
+ may declare the entry directly or through a catalog (`catalog:`,
267
+ `catalog:ts6`); it must resolve to `spec`. A catalog holds a TypeScript entry
268
+ only at the spec of an allowed install that references it. An undeclared
269
+ install fails with the entry to add; an entry fails when its spec differs,
270
+ when the workspace no longer declares the name, or when it no longer depends on
271
+ `dependency`. Overrides and resolutions never declare TypeScript. To keep
272
+ Dependabot from moving an allowed alias, declare it in `dependabotIgnores`;
273
+ `typescript` and `@typescript/native` are already shared ignores.
244
274
 
245
275
  An exception requires a tracked root `stll-toolchain.json` with the named
246
276
  rule and a nonempty reason:
@@ -251,13 +281,8 @@ rule and a nonempty reason:
251
281
  }
252
282
  ```
253
283
 
254
- Workspace TypeScript toolchains combine the root and declared members' devDependencies.
255
- An included member may declare the exact TypeScript 6 compatibility API across
256
- dependencies, devDependencies, and peerDependencies when that shared install uses
257
- the complete split layout. Ambiguous or partial layouts do not grant this allowance.
258
- Peer ranges declare support: they must include the policy compiler release and the
259
- compatibility release when the selected layout uses it. Ranges do not contribute
260
- to the installed compiler inventory.
284
+ Peer ranges, exact versions included, declare support: a `typescript` range
285
+ must include the policy release. Ranges do not count as installs.
261
286
 
262
287
  JavaScript update roots include the repository root, declared workspace membership,
263
288
  and directories with their own `bun.lock`, `package-lock.json`, `yarn.lock`, or
@@ -276,23 +301,6 @@ rules, empty reasons, and malformed configuration fail validation. See the
276
301
  for the schema, rule list, runtime support ranges, and generated Dependabot
277
302
  template.
278
303
 
279
- ## Typecheck parity project selection
280
-
281
- Run `stll-typecheck-parity` from the repository root. Without flags, it checks
282
- the root `tsconfig.json` and recursively discovers project references in build
283
- mode. Repeat `--project` to check exactly the selected configs:
284
-
285
- ```sh
286
- stll-typecheck-parity --project packages/api/tsconfig.json --project packages/web/tsconfig.json
287
- ```
288
-
289
- Selected configs run independently using the repository-root compiler
290
- installation; child packages need no compiler declaration and a root tsconfig
291
- is unnecessary. Their original reference metadata is preserved without
292
- discovering or building referenced projects. Missing, unreadable, and zero-input
293
- selected configs fail the check. `--help` prints usage and exits successfully;
294
- unknown arguments fail.
295
-
296
304
  ## Generate dependency update configuration
297
305
 
298
306
  Run `bunx --no-install stll-dependabot` from the repository root. It reads tracked
@@ -396,6 +404,7 @@ Add an explicit declaration to tracked root `stll-toolchain.json`:
396
404
  "cloud": {
397
405
  "services": ["postgres", "valkey"],
398
406
  "install": "bun install --frozen-lockfile",
407
+ "submodules": true,
399
408
  "envFile": ".env.cloud",
400
409
  "rust": {
401
410
  "components": ["clippy", "rustfmt"],
@@ -417,7 +426,13 @@ only. No `cloud` declaration means no cloud setup script. `envFile` is required
417
426
  with services and rejected without services; runtime-only scripts emit no
418
427
  environment file code. With services, `envFile` must be a canonical
419
428
  repository-relative path; its existing parent must be safe at runtime. Track an exact stable Node patch in root
420
- `.node-version` within the shared Node series. Generate and commit the script:
429
+ `.node-version` within the shared Node series.
430
+
431
+ Set `cloud.submodules` to `true` when workspace inputs are held in Git
432
+ submodules. The networked install phase synchronizes and shallow-initializes
433
+ submodules recursively before dependency installation; startup remains offline.
434
+
435
+ Generate and commit the script:
421
436
 
422
437
  ```sh
423
438
  bunx --no-install stll-cloud-setup
@@ -477,6 +492,13 @@ it gets no network allowance. Generation fails when the script is not in the
477
492
  root `package.json`.
478
493
 
479
494
  Generation uses the installed policy's Bun, Node, PostgreSQL, and Valkey pins.
495
+ Node and Bun archives are verified against SHA256 values recorded at generation
496
+ time, in addition to the upstream checksum manifests. The shared policy records
497
+ them for its own Node patch and Bun release. A repository that tracks another
498
+ accepted Node patch or a newer Bun records that one release's amd64 and arm64
499
+ values from the official `SHASUMS256.txt` in `cloud.runtimeArchiveSha256`, for
500
+ example `{ "node": { "26.11.0": { "amd64": "…", "arm64": "…" } } }`; a release
501
+ the shared policy pins must not be repeated there.
480
502
  PostgreSQL uses the PGDG major-version packages; minor updates within the pinned
481
503
  major are accepted for the disposable database. Before adding PGDG, provisioning
482
504
  reuses an existing source only after verifying its signing-key fingerprint;
@@ -954,25 +976,25 @@ aliases), oxlint, oxlint-tsgolint, and shared tooling pins. Lockfile
954
976
  resolutions determine installed package versions; manifest ranges alone do not.
955
977
  Resolution locations and importer bindings are retained: swapping compiler
956
978
  versions between workspaces cannot look unchanged. Compiler specifier changes
957
- run parity even when the resolved release version is unchanged. Unknown lock
958
- shapes and ambiguous resolutions report an unreadable snapshot. Supported text
959
- locks include Bun JSONC (schema 0/1), pnpm YAML (5.4/6/9), npm package-lock/
979
+ report `typescript` even when the resolved release version is unchanged. Unknown
980
+ lock shapes and ambiguous resolutions report an unreadable snapshot. Supported
981
+ text locks include Bun JSONC (schema 0/1), pnpm YAML (5.4/6/9), npm package-lock/
960
982
  shrinkwrap (1/2/3), and bounded Yarn Classic/Berry shapes; a binary-only Bun lock
961
983
  cannot be compared without executing Bun.
962
984
  Workflow/action and Docker definition edits conservatively force full CI.
963
- Unrelated application dependency changes do not force compiler parity.
985
+ Unrelated application dependency changes do not report a compiler change.
964
986
  Setup-action runtime selectors and their tracked version-file contents must
965
987
  identify an exact stable release. Floating selectors,
966
988
  ranges, expressions, empty
967
- values, or omitted runtime versions report an unreadable snapshot and run parity
968
- even when their committed text is unchanged.
989
+ values, or omitted runtime versions report an unreadable snapshot even when
990
+ their committed text is unchanged.
969
991
 
970
- On pull requests, run the repository's ordinary Bun typecheck and the probe,
971
- then select parity using the same detector:
992
+ On pull requests, run the repository's ordinary Bun typecheck and the probe. The
993
+ shared `rust-napi-ci.yml` workflow runs both when called with `typecheck: true`;
994
+ elsewhere, run:
972
995
 
973
996
  ```sh
974
997
  stll-typecheck-probe --project packages/api/tsconfig.json --seed-dir packages/api/src -- bun run typecheck
975
- stll-typecheck-parity --changed-since origin/main --project packages/api/tsconfig.json
976
998
  ```
977
999
 
978
1000
  The probe writes an exclusive temporary TypeScript file in the declared
@@ -983,35 +1005,31 @@ excluded seeds fail instead of producing a vacuous pass. Commands are argv,
983
1005
  not shell expressions. Cleanup also runs on failure and handled termination.
984
1006
  Repeat the probe for independently checked projects as needed.
985
1007
 
986
- Conditional parity runs when Bun, TypeScript, or shared declarations change;
987
- otherwise it prints `parity skipped: toolchain unchanged since ...`. An unreadable
988
- reference runs full parity. Nightly jobs omit `--changed-since` to run full parity.
989
- Node and lint-tool changes still force full CI through the shared detector.
990
-
991
1008
  Workflow, composite-action, Docker, mise, and tool-version declarations are
992
- conservatively fingerprinted for compiler parity, including referenced tracked
1009
+ conservatively fingerprinted as `shared` changes, including referenced tracked
993
1010
  setup-action version files (Node, Bun, Python, Go, Java and other runtimes).
994
1011
  Rust toolchain-file selectors and conventional runtime files are included;
995
1012
  cache-dependency-path is not a runtime selector. Compose and Kubernetes image
996
- definitions are conservatively fingerprinted alongside Dockerfiles. Catalog and unresolved declaration changes also force parity;
997
- an unclassifiable reference runs full parity. This may run parity for unrelated
998
- edits to these declaration files. Active installed compiler comparisons still
999
- use the owning lockfile resolutions.
1013
+ definitions are conservatively fingerprinted alongside Dockerfiles. Catalog and
1014
+ unresolved declaration changes also report a change; an unclassifiable reference
1015
+ reports an unreadable snapshot. This may report a change for unrelated edits to
1016
+ these declaration files. Installed compiler comparisons use the owning lockfile
1017
+ resolutions.
1000
1018
 
1001
1019
  Compiler patch declarations, lockfile patch hashes, and their tracked patch files
1002
1020
  are included even when the compiler version is unchanged. Compiler patch-package
1003
1021
  files are included too. Missing referenced compiler patches fail closed; unrelated
1004
- package patches do not trigger compiler parity.
1022
+ package patches do not report a compiler change.
1005
1023
 
1006
1024
  Compiler manifest specifiers and complete compiler lock entries form part of the
1007
1025
  change identity, including resolved URLs, integrity, commits, checksums and patch
1008
- hashes. Changing a source at the same release version runs parity. Local compiler
1009
- sources without an immutable byte identity fail closed; a version alone does not
1010
- identify a local directory. Git compiler sources require a full commit identity.
1011
- Supported text locks include Bun, npm, pnpm and bounded
1012
- Yarn Classic/Berry shapes; unrecognized lock shapes run parity. Yarn compiler
1013
- `patch:` protocols are unsupported and run parity because their patch bytes are
1014
- not represented by the lock checksum alone.
1026
+ hashes. Changing a source at the same release version reports `typescript`. Local
1027
+ compiler sources without an immutable byte identity fail closed; a version alone
1028
+ does not identify a local directory. Git compiler sources require a full commit
1029
+ identity. Supported text locks include Bun, npm, pnpm and bounded
1030
+ Yarn Classic/Berry shapes; unrecognized lock shapes report an unreadable snapshot.
1031
+ Yarn compiler `patch:` protocols are unsupported and report an unreadable
1032
+ snapshot because their patch bytes are not represented by the lock checksum alone.
1015
1033
 
1016
1034
  ## Rust selectors
1017
1035
 
@@ -1023,8 +1041,10 @@ Cargo manifest `rust-version` remains an MSRV floor at or below the shared pin.
1023
1041
 
1024
1042
  Only `rustExceptions` in the consumer's root `stll-toolchain.json` can authorize
1025
1043
  another exact stable release. Each record contains exactly `pin`, `reason`,
1026
- `tracking` (a GitHub issue URL) and `expires` (a future `YYYY-MM-DD` date).
1027
- Channels, expired records and `rust-version` rule opt-outs fail validation.
1044
+ `tracking` (a GitHub issue URL) and `expires` (a `YYYY-MM-DD` date).
1045
+ Channels and `rust-version` rule opt-outs fail validation. A record expires on
1046
+ its date and then follows the same expiry scope as quarantine excludes (see
1047
+ [Quarantine preset and expiry checks](#quarantine-preset-and-expiry-checks)).
1028
1048
  See the [root policy guide](../../README.md) for a complete declaration.
1029
1049
 
1030
1050
  `stll-toolchain-check` requires tracked JavaScript and TypeScript files selected by type-aware lint to belong to declared TypeScript projects. See the [Node scripts project recipe](https://github.com/stella/tooling/blob/main/README.md) for scripts outside the library project. The check inventories Oxlint-selected files and expands compiler configurations; it does not run lint or type checking.
@@ -1048,16 +1068,33 @@ creation timestamps remain stable across runs; they are not expiries.
1048
1068
 
1049
1069
  Third-party entries require `# quarantine-expires: YYYY-MM-DDTHH:mm:ss.sssZ`.
1050
1070
  `stll-toolchain-check` warns 48 hours before expiry; warnings continue through
1051
- the existing 24-hour removal grace, after which expired entries fail. The
1052
- quarantine rule cannot be opted out. `stll-quarantine --check` is read-only;
1071
+ the existing 24-hour removal grace, after which expired entries fail where the
1072
+ run can act on them. The same scope applies to expired `rustExceptions`. The
1073
+ clock alone never fails a change that leaves an entry untouched:
1074
+
1075
+ - `push`, `schedule`, `workflow_dispatch` and other GitHub Actions events, and
1076
+ non-GitHub CI (`CI` set), fail every overdue entry, which prompts the removal
1077
+ PR.
1078
+ - `pull_request`, `pull_request_target` and `merge_group` fail an overdue entry
1079
+ only when the change adds it or edits its expiry, compared with the event's
1080
+ base commit; inherited overdue entries warn. A shallow checkout that lacks the
1081
+ base fetches exactly that commit from its remote
1082
+ (`git fetch --no-tags --depth=1 origin <base>`, using the checkout's
1083
+ credentials). Only if that also fails does an overdue entry fail, with the
1084
+ reason. Entries that have not expired never need the base.
1085
+ - Local runs outside CI warn.
1086
+
1087
+ The quarantine rule cannot be opted out. `stll-quarantine --check` is read-only;
1053
1088
  `--prune` removes expired third-party entries without removing first-party ones.
1054
1089
  `--help` lists modes. Linked output files are rejected.
1055
1090
 
1056
1091
  `@stll/oxlint-config/quarantine` exports the Node-compatible repository helpers
1057
1092
  `checkRepositoryQuarantine`, `synchronizeRepositoryQuarantine`, and
1058
1093
  `pruneRepositoryQuarantine`, accepting a tracked `files` snapshot and optional
1059
- `now`. The toolchain API reports advisory expiry messages through `onWarning`;
1060
- its returned diagnostics remain failures. Snapshot readers keep lockfiles
1094
+ `now`, plus an optional `expiry` scope (`{ kind: "enforce" }` by default). The
1095
+ toolchain API takes the same scope as `expiryScope`, reports advisory
1096
+ expiry messages through `onWarning`, and its returned diagnostics remain
1097
+ failures. Snapshot readers keep lockfiles
1061
1098
  opaque by default; `{ bunLock: "content" }` explicitly requests the root graph
1062
1099
  when quarantine identity checks need it.
1063
1100
 
@@ -1099,3 +1136,13 @@ closed and writes nothing unless both inputs normalize successfully.
1099
1136
  Use `stll-normalize-wasi-loaders --check <loader-1> <loader-2>` in CI. Check mode
1100
1137
  does not write files and exits non-zero if either loader differs from the normalized
1101
1138
  output.
1139
+
1140
+ ## Rust policy generation
1141
+
1142
+ Run `bunx --no-install stll-rust-policy` at the repository root with
1143
+ `stll-rust-policy.json` containing `{ "kind": "single-crate" }`. Use
1144
+ `--check` in CI to report drift without writes and `--config <path>` to select
1145
+ another input. The published CLI embeds the canonical `rust/` templates and
1146
+ merges policy into Cargo, Cargo aliases, rustfmt, and Clippy configuration.
1147
+ Unrelated TOML values survive; comments and layout are canonicalized.
1148
+ See [Rust adoption](../../rust/README.md) for workspace members and exceptions.
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
3
  const require_generated_file = require("./generated-file.cjs");
4
4
  const require_toolchain_inputs = require("./toolchain-inputs.cjs");
5
- const require_toolchain_bun = require("./toolchain-bun.cjs");
6
5
  const require_toolchain_guard = require("./toolchain-guard.cjs");
7
6
  const require_toolchain_schema = require("./toolchain-schema.cjs");
8
7
  let node_fs_promises = require("node:fs/promises");
@@ -60,7 +59,7 @@ const main = async () => {
60
59
  const sharedPolicy = require_toolchain_schema.parseToolchainPolicy(JSON.parse(await (0, node_fs_promises.readFile)(new URL("../toolchain.json", require("url").pathToFileURL(__filename).href), "utf8")));
61
60
  const policy = {
62
61
  ...sharedPolicy,
63
- bun: require_toolchain_bun.repositoryBun(sharedPolicy.bun, files["package.json"])
62
+ bun: require_toolchain_guard.repositoryBun(sharedPolicy.bun, files["package.json"])
64
63
  };
65
64
  const script = require_toolchain_inputs.generateCloudSetup({
66
65
  policy,
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-setup-cli.cjs","names":["checkGeneratedOutput","open","constants","cloudClaudeSettingsPath","cloudSessionStartFix","realpath","readToolchainInputs","join","cloudSetupPath","generationDiagnostics","parseToolchainConfiguration","parseToolchainPolicy","readFile","repositoryBun","generateCloudSetup","mergeCloudClaudeSettings","writeGeneratedFile"],"sources":["../src/cloud-setup-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { constants } from \"node:fs\";\nimport { open, readFile, realpath } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { cloudSetupPath, generateCloudSetup } from \"./cloud-setup\";\nimport {\n cloudClaudeSettingsPath,\n cloudSessionStartFix,\n mergeCloudClaudeSettings,\n} from \"./cloud-setup-claude\";\nimport {\n checkGeneratedOutput,\n generationDiagnostics,\n writeGeneratedFile,\n} from \"./generated-file\";\nimport { repositoryBun } from \"./toolchain-bun\";\nimport {\n parseToolchainConfiguration,\n readToolchainInputs,\n} from \"./toolchain-guard\";\nimport { parseToolchainPolicy } from \"./toolchain-schema\";\n\nconst usage =\n \"Usage: stll-cloud-setup (run from repository root)\\n stll-cloud-setup --help\";\nconst readClaudeSettings = async (destination: string) => {\n try {\n if ((await checkGeneratedOutput(destination)) === undefined)\n return undefined;\n const input = await open(\n destination,\n constants.O_RDONLY | constants.O_NOFOLLOW,\n );\n try {\n const opened = await input.stat();\n if (!opened.isFile() || opened.nlink !== 1)\n throw new Error(\n \"settings must be a single-link regular repository file\",\n );\n return { text: await input.readFile(\"utf8\"), mode: opened.mode & 0o777 };\n } finally {\n await input.close();\n }\n } catch (error) {\n throw new Error(\n `cannot safely merge ${cloudClaudeSettingsPath}: ${error instanceof Error ? error.message : String(error)}; ${cloudSessionStartFix}`,\n );\n }\n};\n\nconst main = async () => {\n const args = process.argv.slice(2);\n if (args.length === 1 && args.at(0) === \"--help\") {\n process.stdout.write(`${usage}\\n`);\n return;\n }\n if (args.length !== 0) throw new Error(usage);\n const root = await realpath(process.cwd());\n const { files, diagnostics } = readToolchainInputs(root);\n const destination = join(root, cloudSetupPath);\n const settingsDestination = join(root, cloudClaudeSettingsPath);\n // Validate settings separately to retain actionable merge diagnostics.\n const settings = await readClaudeSettings(settingsDestination);\n const remainingDiagnostics = await generationDiagnostics({\n diagnostics,\n outputs: [\n { relative: cloudSetupPath, destination },\n { relative: cloudClaudeSettingsPath, destination: settingsDestination },\n ],\n });\n if (remainingDiagnostics.length > 0)\n throw new Error(\n remainingDiagnostics\n .map(\n ({ path, message }) =>\n `${path}: ${message}${path === cloudClaudeSettingsPath ? `; ${cloudSessionStartFix}` : \"\"}`,\n )\n .join(\"\\n\"),\n );\n const text = files[\"stll-toolchain.json\"];\n if (text === undefined)\n throw new Error(\"requires tracked stll-toolchain.json\");\n const { cloud, rustExceptions } = parseToolchainConfiguration(\n JSON.parse(text),\n );\n if (cloud === undefined)\n throw new Error(\"requires an explicit cloud declaration\");\n const nodeVersion = files[\".node-version\"];\n if (nodeVersion === undefined)\n throw new Error(\"requires tracked root .node-version\");\n const sharedPolicy = parseToolchainPolicy(\n JSON.parse(\n await readFile(new URL(\"../toolchain.json\", import.meta.url), \"utf8\"),\n ),\n );\n const policy = {\n ...sharedPolicy,\n bun: repositoryBun(sharedPolicy.bun, files[\"package.json\"]),\n };\n const script = generateCloudSetup({\n policy,\n cloud,\n nodeVersion: nodeVersion.trim(),\n files,\n rustExceptions,\n });\n const mergedSettings = mergeCloudClaudeSettings(settings?.text);\n await writeGeneratedFile({ destination, text: script, mode: 0o755 });\n if (mergedSettings !== settings?.text)\n await writeGeneratedFile({\n destination: settingsDestination,\n text: mergedSettings,\n mode: settings?.mode ?? 0o644,\n });\n process.stdout.write(\n `Generated ${cloudSetupPath} and ${cloudClaudeSettingsPath}\\n`,\n );\n};\n\nmain().catch((error: unknown) => {\n process.stderr.write(\n `cloud-setup: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"cloud-setup-cli.cjs","names":["checkGeneratedOutput","open","constants","cloudClaudeSettingsPath","cloudSessionStartFix","realpath","readToolchainInputs","join","cloudSetupPath","generationDiagnostics","parseToolchainConfiguration","parseToolchainPolicy","readFile","repositoryBun","generateCloudSetup","mergeCloudClaudeSettings","writeGeneratedFile"],"sources":["../src/cloud-setup-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { constants } from \"node:fs\";\nimport { open, readFile, realpath } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { cloudSetupPath, generateCloudSetup } from \"./cloud-setup\";\nimport {\n cloudClaudeSettingsPath,\n cloudSessionStartFix,\n mergeCloudClaudeSettings,\n} from \"./cloud-setup-claude\";\nimport {\n checkGeneratedOutput,\n generationDiagnostics,\n writeGeneratedFile,\n} from \"./generated-file\";\nimport { repositoryBun } from \"./toolchain-bun\";\nimport {\n parseToolchainConfiguration,\n readToolchainInputs,\n} from \"./toolchain-guard\";\nimport { parseToolchainPolicy } from \"./toolchain-schema\";\n\nconst usage =\n \"Usage: stll-cloud-setup (run from repository root)\\n stll-cloud-setup --help\";\nconst readClaudeSettings = async (destination: string) => {\n try {\n if ((await checkGeneratedOutput(destination)) === undefined)\n return undefined;\n const input = await open(\n destination,\n constants.O_RDONLY | constants.O_NOFOLLOW,\n );\n try {\n const opened = await input.stat();\n if (!opened.isFile() || opened.nlink !== 1)\n throw new Error(\n \"settings must be a single-link regular repository file\",\n );\n return { text: await input.readFile(\"utf8\"), mode: opened.mode & 0o777 };\n } finally {\n await input.close();\n }\n } catch (error) {\n throw new Error(\n `cannot safely merge ${cloudClaudeSettingsPath}: ${error instanceof Error ? error.message : String(error)}; ${cloudSessionStartFix}`,\n );\n }\n};\n\nconst main = async () => {\n const args = process.argv.slice(2);\n if (args.length === 1 && args.at(0) === \"--help\") {\n process.stdout.write(`${usage}\\n`);\n return;\n }\n if (args.length !== 0) throw new Error(usage);\n const root = await realpath(process.cwd());\n const { files, diagnostics } = readToolchainInputs(root);\n const destination = join(root, cloudSetupPath);\n const settingsDestination = join(root, cloudClaudeSettingsPath);\n // Validate settings separately to retain actionable merge diagnostics.\n const settings = await readClaudeSettings(settingsDestination);\n const remainingDiagnostics = await generationDiagnostics({\n diagnostics,\n outputs: [\n { relative: cloudSetupPath, destination },\n { relative: cloudClaudeSettingsPath, destination: settingsDestination },\n ],\n });\n if (remainingDiagnostics.length > 0)\n throw new Error(\n remainingDiagnostics\n .map(\n ({ path, message }) =>\n `${path}: ${message}${path === cloudClaudeSettingsPath ? `; ${cloudSessionStartFix}` : \"\"}`,\n )\n .join(\"\\n\"),\n );\n const text = files[\"stll-toolchain.json\"];\n if (text === undefined)\n throw new Error(\"requires tracked stll-toolchain.json\");\n const { cloud, rustExceptions } = parseToolchainConfiguration(\n JSON.parse(text),\n );\n if (cloud === undefined)\n throw new Error(\"requires an explicit cloud declaration\");\n const nodeVersion = files[\".node-version\"];\n if (nodeVersion === undefined)\n throw new Error(\"requires tracked root .node-version\");\n const sharedPolicy = parseToolchainPolicy(\n JSON.parse(\n await readFile(new URL(\"../toolchain.json\", import.meta.url), \"utf8\"),\n ),\n );\n const policy = {\n ...sharedPolicy,\n bun: repositoryBun(sharedPolicy.bun, files[\"package.json\"]),\n };\n const script = generateCloudSetup({\n policy,\n cloud,\n nodeVersion: nodeVersion.trim(),\n files,\n rustExceptions,\n });\n const mergedSettings = mergeCloudClaudeSettings(settings?.text);\n await writeGeneratedFile({ destination, text: script, mode: 0o755 });\n if (mergedSettings !== settings?.text)\n await writeGeneratedFile({\n destination: settingsDestination,\n text: mergedSettings,\n mode: settings?.mode ?? 0o644,\n });\n process.stdout.write(\n `Generated ${cloudSetupPath} and ${cloudClaudeSettingsPath}\\n`,\n );\n};\n\nmain().catch((error: unknown) => {\n process.stderr.write(\n `cloud-setup: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n});\n"],"mappings":"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"}
@@ -1,8 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { n as generationDiagnostics, r as writeGeneratedFile, t as checkGeneratedOutput } from "./generated-file.mjs";
3
3
  import { C as cloudSetupPath, S as mergeCloudClaudeSettings, v as cloudClaudeSettingsPath, w as generateCloudSetup, y as cloudSessionStartFix } from "./toolchain-inputs.mjs";
4
- import { t as repositoryBun } from "./toolchain-bun.mjs";
5
- import { n as parseToolchainConfiguration, r as readToolchainInputs } from "./toolchain-guard.mjs";
4
+ import { i as repositoryBun, n as parseToolchainConfiguration, r as readToolchainInputs } from "./toolchain-guard.mjs";
6
5
  import { t as parseToolchainPolicy } from "./toolchain-schema.mjs";
7
6
  import { open, readFile, realpath } from "node:fs/promises";
8
7
  import { join } from "node:path";
@@ -1 +1 @@
1
- {"version":3,"file":"cloud-setup-cli.mjs","names":[],"sources":["../src/cloud-setup-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { constants } from \"node:fs\";\nimport { open, readFile, realpath } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { cloudSetupPath, generateCloudSetup } from \"./cloud-setup\";\nimport {\n cloudClaudeSettingsPath,\n cloudSessionStartFix,\n mergeCloudClaudeSettings,\n} from \"./cloud-setup-claude\";\nimport {\n checkGeneratedOutput,\n generationDiagnostics,\n writeGeneratedFile,\n} from \"./generated-file\";\nimport { repositoryBun } from \"./toolchain-bun\";\nimport {\n parseToolchainConfiguration,\n readToolchainInputs,\n} from \"./toolchain-guard\";\nimport { parseToolchainPolicy } from \"./toolchain-schema\";\n\nconst usage =\n \"Usage: stll-cloud-setup (run from repository root)\\n stll-cloud-setup --help\";\nconst readClaudeSettings = async (destination: string) => {\n try {\n if ((await checkGeneratedOutput(destination)) === undefined)\n return undefined;\n const input = await open(\n destination,\n constants.O_RDONLY | constants.O_NOFOLLOW,\n );\n try {\n const opened = await input.stat();\n if (!opened.isFile() || opened.nlink !== 1)\n throw new Error(\n \"settings must be a single-link regular repository file\",\n );\n return { text: await input.readFile(\"utf8\"), mode: opened.mode & 0o777 };\n } finally {\n await input.close();\n }\n } catch (error) {\n throw new Error(\n `cannot safely merge ${cloudClaudeSettingsPath}: ${error instanceof Error ? error.message : String(error)}; ${cloudSessionStartFix}`,\n );\n }\n};\n\nconst main = async () => {\n const args = process.argv.slice(2);\n if (args.length === 1 && args.at(0) === \"--help\") {\n process.stdout.write(`${usage}\\n`);\n return;\n }\n if (args.length !== 0) throw new Error(usage);\n const root = await realpath(process.cwd());\n const { files, diagnostics } = readToolchainInputs(root);\n const destination = join(root, cloudSetupPath);\n const settingsDestination = join(root, cloudClaudeSettingsPath);\n // Validate settings separately to retain actionable merge diagnostics.\n const settings = await readClaudeSettings(settingsDestination);\n const remainingDiagnostics = await generationDiagnostics({\n diagnostics,\n outputs: [\n { relative: cloudSetupPath, destination },\n { relative: cloudClaudeSettingsPath, destination: settingsDestination },\n ],\n });\n if (remainingDiagnostics.length > 0)\n throw new Error(\n remainingDiagnostics\n .map(\n ({ path, message }) =>\n `${path}: ${message}${path === cloudClaudeSettingsPath ? `; ${cloudSessionStartFix}` : \"\"}`,\n )\n .join(\"\\n\"),\n );\n const text = files[\"stll-toolchain.json\"];\n if (text === undefined)\n throw new Error(\"requires tracked stll-toolchain.json\");\n const { cloud, rustExceptions } = parseToolchainConfiguration(\n JSON.parse(text),\n );\n if (cloud === undefined)\n throw new Error(\"requires an explicit cloud declaration\");\n const nodeVersion = files[\".node-version\"];\n if (nodeVersion === undefined)\n throw new Error(\"requires tracked root .node-version\");\n const sharedPolicy = parseToolchainPolicy(\n JSON.parse(\n await readFile(new URL(\"../toolchain.json\", import.meta.url), \"utf8\"),\n ),\n );\n const policy = {\n ...sharedPolicy,\n bun: repositoryBun(sharedPolicy.bun, files[\"package.json\"]),\n };\n const script = generateCloudSetup({\n policy,\n cloud,\n nodeVersion: nodeVersion.trim(),\n files,\n rustExceptions,\n });\n const mergedSettings = mergeCloudClaudeSettings(settings?.text);\n await writeGeneratedFile({ destination, text: script, mode: 0o755 });\n if (mergedSettings !== settings?.text)\n await writeGeneratedFile({\n destination: settingsDestination,\n text: mergedSettings,\n mode: settings?.mode ?? 0o644,\n });\n process.stdout.write(\n `Generated ${cloudSetupPath} and ${cloudClaudeSettingsPath}\\n`,\n );\n};\n\nmain().catch((error: unknown) => {\n process.stderr.write(\n `cloud-setup: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n});\n"],"mappings":";;;;;;;;;;AAuBA,MAAM,QACJ;AACF,MAAM,qBAAqB,OAAO,gBAAwB;CACxD,IAAI;EACF,IAAK,MAAM,qBAAqB,WAAW,MAAO,KAAA,GAChD,OAAO,KAAA;EACT,MAAM,QAAQ,MAAM,KAClB,aACA,UAAU,WAAW,UAAU,UACjC;EACA,IAAI;GACF,MAAM,SAAS,MAAM,MAAM,KAAK;GAChC,IAAI,CAAC,OAAO,OAAO,KAAK,OAAO,UAAU,GACvC,MAAM,IAAI,MACR,wDACF;GACF,OAAO;IAAE,MAAM,MAAM,MAAM,SAAS,MAAM;IAAG,MAAM,OAAO,OAAO;GAAM;EACzE,UAAU;GACR,MAAM,MAAM,MAAM;EACpB;CACF,SAAS,OAAO;EACd,MAAM,IAAI,MACR,uBAAuB,wBAAwB,IAAI,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,IAAI,sBAChH;CACF;AACF;AAEA,MAAM,OAAO,YAAY;CACvB,MAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;CACjC,IAAI,KAAK,WAAW,KAAK,KAAK,GAAG,CAAC,MAAM,UAAU;EAChD,QAAQ,OAAO,MAAM,GAAG,MAAM,GAAG;EACjC;CACF;CACA,IAAI,KAAK,WAAW,GAAG,MAAM,IAAI,MAAM,KAAK;CAC5C,MAAM,OAAO,MAAM,SAAS,QAAQ,IAAI,CAAC;CACzC,MAAM,EAAE,OAAO,gBAAgB,oBAAoB,IAAI;CACvD,MAAM,cAAc,KAAK,MAAM,cAAc;CAC7C,MAAM,sBAAsB,KAAK,MAAM,uBAAuB;CAE9D,MAAM,WAAW,MAAM,mBAAmB,mBAAmB;CAC7D,MAAM,uBAAuB,MAAM,sBAAsB;EACvD;EACA,SAAS,CACP;GAAE,UAAU;GAAgB;EAAY,GACxC;GAAE,UAAU;GAAyB,aAAa;EAAoB,CACxE;CACF,CAAC;CACD,IAAI,qBAAqB,SAAS,GAChC,MAAM,IAAI,MACR,qBACG,KACE,EAAE,MAAM,cACP,GAAG,KAAK,IAAI,UAAU,SAAA,0BAAmC,KAAK,yBAAyB,IAC3F,CAAC,CACA,KAAK,IAAI,CACd;CACF,MAAM,OAAO,MAAM;CACnB,IAAI,SAAS,KAAA,GACX,MAAM,IAAI,MAAM,sCAAsC;CACxD,MAAM,EAAE,OAAO,mBAAmB,4BAChC,KAAK,MAAM,IAAI,CACjB;CACA,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,MAAM,wCAAwC;CAC1D,MAAM,cAAc,MAAM;CAC1B,IAAI,gBAAgB,KAAA,GAClB,MAAM,IAAI,MAAM,qCAAqC;CACvD,MAAM,eAAe,qBACnB,KAAK,MACH,MAAM,SAAS,IAAI,IAAI,qBAAqB,YAAY,GAAG,GAAG,MAAM,CACtE,CACF;CACA,MAAM,SAAS;EACb,GAAG;EACH,KAAK,cAAc,aAAa,KAAK,MAAM,eAAe;CAC5D;CACA,MAAM,SAAS,mBAAmB;EAChC;EACA;EACA,aAAa,YAAY,KAAK;EAC9B;EACA;CACF,CAAC;CACD,MAAM,iBAAiB,yBAAyB,UAAU,IAAI;CAC9D,MAAM,mBAAmB;EAAE;EAAa,MAAM;EAAQ,MAAM;CAAM,CAAC;CACnE,IAAI,mBAAmB,UAAU,MAC/B,MAAM,mBAAmB;EACvB,aAAa;EACb,MAAM;EACN,MAAM,UAAU,QAAQ;CAC1B,CAAC;CACH,QAAQ,OAAO,MACb,aAAa,eAAe,OAAO,wBAAwB,GAC7D;AACF;AAEA,KAAK,CAAC,CAAC,OAAO,UAAmB;CAC/B,QAAQ,OAAO,MACb,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GACzE;CACA,QAAQ,WAAW;AACrB,CAAC"}
1
+ {"version":3,"file":"cloud-setup-cli.mjs","names":[],"sources":["../src/cloud-setup-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { constants } from \"node:fs\";\nimport { open, readFile, realpath } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { cloudSetupPath, generateCloudSetup } from \"./cloud-setup\";\nimport {\n cloudClaudeSettingsPath,\n cloudSessionStartFix,\n mergeCloudClaudeSettings,\n} from \"./cloud-setup-claude\";\nimport {\n checkGeneratedOutput,\n generationDiagnostics,\n writeGeneratedFile,\n} from \"./generated-file\";\nimport { repositoryBun } from \"./toolchain-bun\";\nimport {\n parseToolchainConfiguration,\n readToolchainInputs,\n} from \"./toolchain-guard\";\nimport { parseToolchainPolicy } from \"./toolchain-schema\";\n\nconst usage =\n \"Usage: stll-cloud-setup (run from repository root)\\n stll-cloud-setup --help\";\nconst readClaudeSettings = async (destination: string) => {\n try {\n if ((await checkGeneratedOutput(destination)) === undefined)\n return undefined;\n const input = await open(\n destination,\n constants.O_RDONLY | constants.O_NOFOLLOW,\n );\n try {\n const opened = await input.stat();\n if (!opened.isFile() || opened.nlink !== 1)\n throw new Error(\n \"settings must be a single-link regular repository file\",\n );\n return { text: await input.readFile(\"utf8\"), mode: opened.mode & 0o777 };\n } finally {\n await input.close();\n }\n } catch (error) {\n throw new Error(\n `cannot safely merge ${cloudClaudeSettingsPath}: ${error instanceof Error ? error.message : String(error)}; ${cloudSessionStartFix}`,\n );\n }\n};\n\nconst main = async () => {\n const args = process.argv.slice(2);\n if (args.length === 1 && args.at(0) === \"--help\") {\n process.stdout.write(`${usage}\\n`);\n return;\n }\n if (args.length !== 0) throw new Error(usage);\n const root = await realpath(process.cwd());\n const { files, diagnostics } = readToolchainInputs(root);\n const destination = join(root, cloudSetupPath);\n const settingsDestination = join(root, cloudClaudeSettingsPath);\n // Validate settings separately to retain actionable merge diagnostics.\n const settings = await readClaudeSettings(settingsDestination);\n const remainingDiagnostics = await generationDiagnostics({\n diagnostics,\n outputs: [\n { relative: cloudSetupPath, destination },\n { relative: cloudClaudeSettingsPath, destination: settingsDestination },\n ],\n });\n if (remainingDiagnostics.length > 0)\n throw new Error(\n remainingDiagnostics\n .map(\n ({ path, message }) =>\n `${path}: ${message}${path === cloudClaudeSettingsPath ? `; ${cloudSessionStartFix}` : \"\"}`,\n )\n .join(\"\\n\"),\n );\n const text = files[\"stll-toolchain.json\"];\n if (text === undefined)\n throw new Error(\"requires tracked stll-toolchain.json\");\n const { cloud, rustExceptions } = parseToolchainConfiguration(\n JSON.parse(text),\n );\n if (cloud === undefined)\n throw new Error(\"requires an explicit cloud declaration\");\n const nodeVersion = files[\".node-version\"];\n if (nodeVersion === undefined)\n throw new Error(\"requires tracked root .node-version\");\n const sharedPolicy = parseToolchainPolicy(\n JSON.parse(\n await readFile(new URL(\"../toolchain.json\", import.meta.url), \"utf8\"),\n ),\n );\n const policy = {\n ...sharedPolicy,\n bun: repositoryBun(sharedPolicy.bun, files[\"package.json\"]),\n };\n const script = generateCloudSetup({\n policy,\n cloud,\n nodeVersion: nodeVersion.trim(),\n files,\n rustExceptions,\n });\n const mergedSettings = mergeCloudClaudeSettings(settings?.text);\n await writeGeneratedFile({ destination, text: script, mode: 0o755 });\n if (mergedSettings !== settings?.text)\n await writeGeneratedFile({\n destination: settingsDestination,\n text: mergedSettings,\n mode: settings?.mode ?? 0o644,\n });\n process.stdout.write(\n `Generated ${cloudSetupPath} and ${cloudClaudeSettingsPath}\\n`,\n );\n};\n\nmain().catch((error: unknown) => {\n process.stderr.write(\n `cloud-setup: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n});\n"],"mappings":";;;;;;;;;AAuBA,MAAM,QACJ;AACF,MAAM,qBAAqB,OAAO,gBAAwB;CACxD,IAAI;EACF,IAAK,MAAM,qBAAqB,WAAW,MAAO,KAAA,GAChD,OAAO,KAAA;EACT,MAAM,QAAQ,MAAM,KAClB,aACA,UAAU,WAAW,UAAU,UACjC;EACA,IAAI;GACF,MAAM,SAAS,MAAM,MAAM,KAAK;GAChC,IAAI,CAAC,OAAO,OAAO,KAAK,OAAO,UAAU,GACvC,MAAM,IAAI,MACR,wDACF;GACF,OAAO;IAAE,MAAM,MAAM,MAAM,SAAS,MAAM;IAAG,MAAM,OAAO,OAAO;GAAM;EACzE,UAAU;GACR,MAAM,MAAM,MAAM;EACpB;CACF,SAAS,OAAO;EACd,MAAM,IAAI,MACR,uBAAuB,wBAAwB,IAAI,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,IAAI,sBAChH;CACF;AACF;AAEA,MAAM,OAAO,YAAY;CACvB,MAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;CACjC,IAAI,KAAK,WAAW,KAAK,KAAK,GAAG,CAAC,MAAM,UAAU;EAChD,QAAQ,OAAO,MAAM,GAAG,MAAM,GAAG;EACjC;CACF;CACA,IAAI,KAAK,WAAW,GAAG,MAAM,IAAI,MAAM,KAAK;CAC5C,MAAM,OAAO,MAAM,SAAS,QAAQ,IAAI,CAAC;CACzC,MAAM,EAAE,OAAO,gBAAgB,oBAAoB,IAAI;CACvD,MAAM,cAAc,KAAK,MAAM,cAAc;CAC7C,MAAM,sBAAsB,KAAK,MAAM,uBAAuB;CAE9D,MAAM,WAAW,MAAM,mBAAmB,mBAAmB;CAC7D,MAAM,uBAAuB,MAAM,sBAAsB;EACvD;EACA,SAAS,CACP;GAAE,UAAU;GAAgB;EAAY,GACxC;GAAE,UAAU;GAAyB,aAAa;EAAoB,CACxE;CACF,CAAC;CACD,IAAI,qBAAqB,SAAS,GAChC,MAAM,IAAI,MACR,qBACG,KACE,EAAE,MAAM,cACP,GAAG,KAAK,IAAI,UAAU,SAAA,0BAAmC,KAAK,yBAAyB,IAC3F,CAAC,CACA,KAAK,IAAI,CACd;CACF,MAAM,OAAO,MAAM;CACnB,IAAI,SAAS,KAAA,GACX,MAAM,IAAI,MAAM,sCAAsC;CACxD,MAAM,EAAE,OAAO,mBAAmB,4BAChC,KAAK,MAAM,IAAI,CACjB;CACA,IAAI,UAAU,KAAA,GACZ,MAAM,IAAI,MAAM,wCAAwC;CAC1D,MAAM,cAAc,MAAM;CAC1B,IAAI,gBAAgB,KAAA,GAClB,MAAM,IAAI,MAAM,qCAAqC;CACvD,MAAM,eAAe,qBACnB,KAAK,MACH,MAAM,SAAS,IAAI,IAAI,qBAAqB,YAAY,GAAG,GAAG,MAAM,CACtE,CACF;CACA,MAAM,SAAS;EACb,GAAG;EACH,KAAK,cAAc,aAAa,KAAK,MAAM,eAAe;CAC5D;CACA,MAAM,SAAS,mBAAmB;EAChC;EACA;EACA,aAAa,YAAY,KAAK;EAC9B;EACA;CACF,CAAC;CACD,MAAM,iBAAiB,yBAAyB,UAAU,IAAI;CAC9D,MAAM,mBAAmB;EAAE;EAAa,MAAM;EAAQ,MAAM;CAAM,CAAC;CACnE,IAAI,mBAAmB,UAAU,MAC/B,MAAM,mBAAmB;EACvB,aAAa;EACb,MAAM;EACN,MAAM,UAAU,QAAQ;CAC1B,CAAC;CACH,QAAQ,OAAO,MACb,aAAa,eAAe,OAAO,wBAAwB,GAC7D;AACF;AAEA,KAAK,CAAC,CAAC,OAAO,UAAmB;CAC/B,QAAQ,OAAO,MACb,gBAAgB,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GACzE;CACA,QAAQ,WAAW;AACrB,CAAC"}
@@ -2,11 +2,11 @@ const require_rolldown_runtime = require("./rolldown-runtime.cjs");
2
2
  const require_toolchain_inputs = require("./toolchain-inputs.cjs");
3
3
  let node_path = require("node:path");
4
4
  node_path = require_rolldown_runtime.__toESM(node_path, 1);
5
+ let picomatch = require("picomatch");
6
+ picomatch = require_rolldown_runtime.__toESM(picomatch, 1);
5
7
  let semver = require("semver");
6
8
  let node_util = require("node:util");
7
9
  let yaml = require("yaml");
8
- let picomatch = require("picomatch");
9
- picomatch = require_rolldown_runtime.__toESM(picomatch, 1);
10
10
  //#region src/consumer-catalogs.ts
11
11
  const record = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
12
12
  const catalogMapping = (value, field) => {
@@ -1,9 +1,9 @@
1
1
  import { g as workspaceContains } from "./toolchain-inputs.mjs";
2
2
  import path from "node:path";
3
+ import picomatch from "picomatch";
3
4
  import { satisfies, valid, validRange } from "semver";
4
5
  import { isDeepStrictEqual } from "node:util";
5
6
  import { parseDocument } from "yaml";
6
- import picomatch from "picomatch";
7
7
  //#region src/consumer-catalogs.ts
8
8
  const record = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
9
9
  const catalogMapping = (value, field) => {
@@ -65,9 +65,17 @@ type FormatterPolicy = {
65
65
  /** Reject unsupported or incomplete installed policies before inspecting a consumer. */
66
66
  export declare const parseToolchainPolicy: (input: unknown) => {
67
67
  bun: string;
68
+ bunArchiveSha256: Readonly<Record<string, {
69
+ readonly amd64: string;
70
+ readonly arm64: string;
71
+ }>>;
68
72
  formatter: FormatterPolicy;
69
73
  typescript: string;
70
74
  node: string;
75
+ nodeArchiveSha256: Readonly<Record<string, {
76
+ readonly amd64: string;
77
+ readonly arm64: string;
78
+ }>>;
71
79
  postgres: string;
72
80
  valkey: string;
73
81
  valkeyArtifacts: {
@@ -103,25 +111,6 @@ export declare const parseToolchainPolicy: (input: unknown) => {
103
111
  sha: string;
104
112
  version: string;
105
113
  }>;
106
- typescriptInstallLayouts: ({
107
- readonly type: "direct";
108
- readonly compilerPackage: "typescript";
109
- readonly compilerSpecifier: string;
110
- readonly typecheckCommand: string;
111
- readonly compatibilityPackage?: never;
112
- readonly compatibilitySpecifier?: never;
113
- } | {
114
- readonly type: "split-compatibility";
115
- readonly compilerPackage: string;
116
- readonly compilerSpecifier: string;
117
- readonly compatibilityPackage: string;
118
- readonly compatibilitySpecifier: string;
119
- readonly typecheckCommand: string;
120
- })[];
121
- typescript6Compatibility: {
122
- version: string;
123
- packageAlias: string;
124
- };
125
114
  dependabot: {
126
115
  schedule: {
127
116
  interval: string;
@@ -65,9 +65,17 @@ type FormatterPolicy = {
65
65
  /** Reject unsupported or incomplete installed policies before inspecting a consumer. */
66
66
  export declare const parseToolchainPolicy: (input: unknown) => {
67
67
  bun: string;
68
+ bunArchiveSha256: Readonly<Record<string, {
69
+ readonly amd64: string;
70
+ readonly arm64: string;
71
+ }>>;
68
72
  formatter: FormatterPolicy;
69
73
  typescript: string;
70
74
  node: string;
75
+ nodeArchiveSha256: Readonly<Record<string, {
76
+ readonly amd64: string;
77
+ readonly arm64: string;
78
+ }>>;
71
79
  postgres: string;
72
80
  valkey: string;
73
81
  valkeyArtifacts: {
@@ -103,25 +111,6 @@ export declare const parseToolchainPolicy: (input: unknown) => {
103
111
  sha: string;
104
112
  version: string;
105
113
  }>;
106
- typescriptInstallLayouts: ({
107
- readonly type: "direct";
108
- readonly compilerPackage: "typescript";
109
- readonly compilerSpecifier: string;
110
- readonly typecheckCommand: string;
111
- readonly compatibilityPackage?: never;
112
- readonly compatibilitySpecifier?: never;
113
- } | {
114
- readonly type: "split-compatibility";
115
- readonly compilerPackage: string;
116
- readonly compilerSpecifier: string;
117
- readonly compatibilityPackage: string;
118
- readonly compatibilitySpecifier: string;
119
- readonly typecheckCommand: string;
120
- })[];
121
- typescript6Compatibility: {
122
- version: string;
123
- packageAlias: string;
124
- };
125
114
  dependabot: {
126
115
  schedule: {
127
116
  interval: string;
@@ -11,8 +11,8 @@ let yaml = require("yaml");
11
11
  let node_os = require("node:os");
12
12
  let node_module = require("node:module");
13
13
  node_module = require_rolldown_runtime.__toESM(node_module, 1);
14
- let acorn = require("acorn");
15
14
  let node_url = require("node:url");
15
+ let acorn = require("acorn");
16
16
  let node_events = require("node:events");
17
17
  let node_readline = require("node:readline");
18
18
  //#region src/consumer-release-pack.ts
@@ -8,8 +8,8 @@ import { lte, parse, satisfies } from "semver";
8
8
  import { isDeepStrictEqual, promisify } from "node:util";
9
9
  import { parseDocument } from "yaml";
10
10
  import { tmpdir } from "node:os";
11
- import { parse as parse$2 } from "acorn";
12
11
  import { fileURLToPath } from "node:url";
12
+ import { parse as parse$2 } from "acorn";
13
13
  import { once } from "node:events";
14
14
  import { createInterface } from "node:readline";
15
15
  //#region src/consumer-release-pack.ts
@@ -13,8 +13,8 @@ let node_fs = require("node:fs");
13
13
  let node_child_process = require("node:child_process");
14
14
  let node_os = require("node:os");
15
15
  let node_module = require("node:module");
16
- let acorn = require("acorn");
17
16
  let node_url = require("node:url");
17
+ let acorn = require("acorn");
18
18
  let esbuild = require("esbuild");
19
19
  //#region src/publish-build-target-nuxt.ts
20
20
  const supportedVersions = {
@@ -10,8 +10,8 @@ import path from "node:path";
10
10
  import { existsSync, mkdtempSync, readFileSync, realpathSync, rmSync, writeFileSync } from "node:fs";
11
11
  import { execFileSync, spawnSync } from "node:child_process";
12
12
  import { tmpdir } from "node:os";
13
- import { parse } from "acorn";
14
13
  import { pathToFileURL } from "node:url";
14
+ import { parse } from "acorn";
15
15
  import { transformSync } from "esbuild";
16
16
  //#region src/publish-build-target-nuxt.ts
17
17
  const supportedVersions = {
@@ -41,7 +41,8 @@ const main = async () => {
41
41
  });
42
42
  const result = require_quarantine_policy.checkRepositoryQuarantine({
43
43
  files,
44
- npmrcPresent: npmrc !== void 0 || trackedFiles.has(".npmrc")
44
+ npmrcPresent: npmrc !== void 0 || trackedFiles.has(".npmrc"),
45
+ expiry: require_quarantine_policy.resolveExpiryScope(root)
45
46
  });
46
47
  for (const warning of result.warnings) process.stderr.write(`warning: ${warning}\n`);
47
48
  if (result.errors.length > 0) throw new Error(result.errors.join("\n"));
@@ -1 +1 @@
1
- {"version":3,"file":"quarantine-cli.cjs","names":["realpath","readToolchainInputs","join","checkGeneratedOutput","readFile","generationDiagnostics","lstat","checkRepositoryQuarantine","synchronizeRepositoryQuarantine","pruneRepositoryQuarantine","writeGeneratedFile"],"sources":["../src/quarantine-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { lstat, readFile, realpath } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport {\n checkGeneratedOutput,\n generationDiagnostics,\n writeGeneratedFile,\n} from \"./generated-file\";\nimport {\n checkRepositoryQuarantine,\n pruneRepositoryQuarantine,\n synchronizeRepositoryQuarantine,\n} from \"./quarantine-policy\";\nimport { readToolchainInputs } from \"./toolchain-guard\";\n\nconst usage =\n \"Usage: stll-quarantine [--check | --sync | --prune]\\nRun from the repository root; --check is the default.\";\nconst main = async () => {\n const args = process.argv.slice(2);\n if (args.length === 1 && args.at(0) === \"--help\") {\n process.stdout.write(`${usage}\\n`);\n return;\n }\n const mode = args.at(0) ?? \"--check\";\n if (args.length > 1 || ![\"--check\", \"--sync\", \"--prune\"].includes(mode))\n throw new Error(usage);\n const root = await realpath(process.cwd());\n const { files, trackedFiles, diagnostics } = readToolchainInputs(root, {\n bunLock: \"content\",\n });\n const destination = join(root, \"bunfig.toml\");\n // These root inputs may be new outputs not yet staged in Git.\n for (const file of [\"bunfig.toml\", \"bun.lock\"]) {\n const source = join(root, file);\n if ((await checkGeneratedOutput(source)) !== undefined)\n files[file] = await readFile(source, \"utf8\");\n }\n const remaining = await generationDiagnostics({\n diagnostics,\n outputs: [{ relative: \"bunfig.toml\", destination }],\n });\n if (remaining.length > 0)\n throw new Error(\n remaining.map(({ path, message }) => `${path}: ${message}`).join(\"\\n\"),\n );\n if (mode === \"--check\") {\n const npmrc = await lstat(join(root, \".npmrc\")).catch((error: unknown) => {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\")\n return undefined;\n throw error;\n });\n const result = checkRepositoryQuarantine({\n files,\n npmrcPresent: npmrc !== undefined || trackedFiles.has(\".npmrc\"),\n });\n for (const warning of result.warnings)\n process.stderr.write(`warning: ${warning}\\n`);\n if (result.errors.length > 0) throw new Error(result.errors.join(\"\\n\"));\n process.stdout.write(\"Verified bunfig.toml quarantine policy\\n\");\n return;\n }\n const text =\n mode === \"--sync\"\n ? synchronizeRepositoryQuarantine({ files })\n : pruneRepositoryQuarantine({ files }).bunfig;\n const stat = await checkGeneratedOutput(destination);\n if (text !== files[\"bunfig.toml\"])\n await writeGeneratedFile({\n destination,\n text,\n mode: stat === undefined ? 0o644 : stat.mode & 0o777,\n });\n process.stdout.write(\n `${mode === \"--sync\" ? \"Synchronized\" : \"Pruned\"} bunfig.toml quarantine policy\\n`,\n );\n};\nmain().catch((error: unknown) => {\n process.stderr.write(\n `quarantine: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n});\n"],"mappings":";;;;;;;;AAgBA,MAAM,QACJ;AACF,MAAM,OAAO,YAAY;CACvB,MAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;CACjC,IAAI,KAAK,WAAW,KAAK,KAAK,GAAG,CAAC,MAAM,UAAU;EAChD,QAAQ,OAAO,MAAM,GAAG,MAAM,GAAG;EACjC;CACF;CACA,MAAM,OAAO,KAAK,GAAG,CAAC,KAAK;CAC3B,IAAI,KAAK,SAAS,KAAK,CAAC;EAAC;EAAW;EAAU;CAAS,CAAC,CAAC,SAAS,IAAI,GACpE,MAAM,IAAI,MAAM,KAAK;CACvB,MAAM,OAAO,OAAA,GAAMA,iBAAAA,SAAAA,CAAS,QAAQ,IAAI,CAAC;CACzC,MAAM,EAAE,OAAO,cAAc,gBAAgBC,wBAAAA,oBAAoB,MAAM,EACrE,SAAS,UACX,CAAC;CACD,MAAM,eAAA,GAAcC,UAAAA,KAAAA,CAAK,MAAM,aAAa;CAE5C,KAAK,MAAM,QAAQ,CAAC,eAAe,UAAU,GAAG;EAC9C,MAAM,UAAA,GAASA,UAAAA,KAAAA,CAAK,MAAM,IAAI;EAC9B,IAAK,MAAMC,uBAAAA,qBAAqB,MAAM,MAAO,KAAA,GAC3C,MAAM,QAAQ,OAAA,GAAMC,iBAAAA,SAAAA,CAAS,QAAQ,MAAM;CAC/C;CACA,MAAM,YAAY,MAAMC,uBAAAA,sBAAsB;EAC5C;EACA,SAAS,CAAC;GAAE,UAAU;GAAe;EAAY,CAAC;CACpD,CAAC;CACD,IAAI,UAAU,SAAS,GACrB,MAAM,IAAI,MACR,UAAU,KAAK,EAAE,MAAM,cAAc,GAAG,KAAK,IAAI,SAAS,CAAC,CAAC,KAAK,IAAI,CACvE;CACF,IAAI,SAAS,WAAW;EACtB,MAAM,QAAQ,OAAA,GAAMC,iBAAAA,MAAAA,EAAAA,GAAMJ,UAAAA,KAAAA,CAAK,MAAM,QAAQ,CAAC,CAAC,CAAC,OAAO,UAAmB;GACxE,IAAI,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS,UAC9D,OAAO,KAAA;GACT,MAAM;EACR,CAAC;EACD,MAAM,SAASK,0BAAAA,0BAA0B;GACvC;GACA,cAAc,UAAU,KAAA,KAAa,aAAa,IAAI,QAAQ;EAChE,CAAC;EACD,KAAK,MAAM,WAAW,OAAO,UAC3B,QAAQ,OAAO,MAAM,YAAY,QAAQ,GAAG;EAC9C,IAAI,OAAO,OAAO,SAAS,GAAG,MAAM,IAAI,MAAM,OAAO,OAAO,KAAK,IAAI,CAAC;EACtE,QAAQ,OAAO,MAAM,0CAA0C;EAC/D;CACF;CACA,MAAM,OACJ,SAAS,WACLC,0BAAAA,gCAAgC,EAAE,MAAM,CAAC,IACzCC,0BAAAA,0BAA0B,EAAE,MAAM,CAAC,CAAC,CAAC;CAC3C,MAAM,OAAO,MAAMN,uBAAAA,qBAAqB,WAAW;CACnD,IAAI,SAAS,MAAM,gBACjB,MAAMO,uBAAAA,mBAAmB;EACvB;EACA;EACA,MAAM,SAAS,KAAA,IAAY,MAAQ,KAAK,OAAO;CACjD,CAAC;CACH,QAAQ,OAAO,MACb,GAAG,SAAS,WAAW,iBAAiB,SAAS,iCACnD;AACF;AACA,KAAK,CAAC,CAAC,OAAO,UAAmB;CAC/B,QAAQ,OAAO,MACb,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GACxE;CACA,QAAQ,WAAW;AACrB,CAAC"}
1
+ {"version":3,"file":"quarantine-cli.cjs","names":["realpath","readToolchainInputs","join","checkGeneratedOutput","readFile","generationDiagnostics","lstat","checkRepositoryQuarantine","resolveExpiryScope","synchronizeRepositoryQuarantine","pruneRepositoryQuarantine","writeGeneratedFile"],"sources":["../src/quarantine-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { lstat, readFile, realpath } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { resolveExpiryScope } from \"./dated-entry-scope\";\nimport {\n checkGeneratedOutput,\n generationDiagnostics,\n writeGeneratedFile,\n} from \"./generated-file\";\nimport {\n checkRepositoryQuarantine,\n pruneRepositoryQuarantine,\n synchronizeRepositoryQuarantine,\n} from \"./quarantine-policy\";\nimport { readToolchainInputs } from \"./toolchain-guard\";\n\nconst usage =\n \"Usage: stll-quarantine [--check | --sync | --prune]\\nRun from the repository root; --check is the default.\";\nconst main = async () => {\n const args = process.argv.slice(2);\n if (args.length === 1 && args.at(0) === \"--help\") {\n process.stdout.write(`${usage}\\n`);\n return;\n }\n const mode = args.at(0) ?? \"--check\";\n if (args.length > 1 || ![\"--check\", \"--sync\", \"--prune\"].includes(mode))\n throw new Error(usage);\n const root = await realpath(process.cwd());\n const { files, trackedFiles, diagnostics } = readToolchainInputs(root, {\n bunLock: \"content\",\n });\n const destination = join(root, \"bunfig.toml\");\n // These root inputs may be new outputs not yet staged in Git.\n for (const file of [\"bunfig.toml\", \"bun.lock\"]) {\n const source = join(root, file);\n if ((await checkGeneratedOutput(source)) !== undefined)\n files[file] = await readFile(source, \"utf8\");\n }\n const remaining = await generationDiagnostics({\n diagnostics,\n outputs: [{ relative: \"bunfig.toml\", destination }],\n });\n if (remaining.length > 0)\n throw new Error(\n remaining.map(({ path, message }) => `${path}: ${message}`).join(\"\\n\"),\n );\n if (mode === \"--check\") {\n const npmrc = await lstat(join(root, \".npmrc\")).catch((error: unknown) => {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\")\n return undefined;\n throw error;\n });\n const result = checkRepositoryQuarantine({\n files,\n npmrcPresent: npmrc !== undefined || trackedFiles.has(\".npmrc\"),\n expiry: resolveExpiryScope(root),\n });\n for (const warning of result.warnings)\n process.stderr.write(`warning: ${warning}\\n`);\n if (result.errors.length > 0) throw new Error(result.errors.join(\"\\n\"));\n process.stdout.write(\"Verified bunfig.toml quarantine policy\\n\");\n return;\n }\n const text =\n mode === \"--sync\"\n ? synchronizeRepositoryQuarantine({ files })\n : pruneRepositoryQuarantine({ files }).bunfig;\n const stat = await checkGeneratedOutput(destination);\n if (text !== files[\"bunfig.toml\"])\n await writeGeneratedFile({\n destination,\n text,\n mode: stat === undefined ? 0o644 : stat.mode & 0o777,\n });\n process.stdout.write(\n `${mode === \"--sync\" ? \"Synchronized\" : \"Pruned\"} bunfig.toml quarantine policy\\n`,\n );\n};\nmain().catch((error: unknown) => {\n process.stderr.write(\n `quarantine: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n});\n"],"mappings":";;;;;;;;AAiBA,MAAM,QACJ;AACF,MAAM,OAAO,YAAY;CACvB,MAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;CACjC,IAAI,KAAK,WAAW,KAAK,KAAK,GAAG,CAAC,MAAM,UAAU;EAChD,QAAQ,OAAO,MAAM,GAAG,MAAM,GAAG;EACjC;CACF;CACA,MAAM,OAAO,KAAK,GAAG,CAAC,KAAK;CAC3B,IAAI,KAAK,SAAS,KAAK,CAAC;EAAC;EAAW;EAAU;CAAS,CAAC,CAAC,SAAS,IAAI,GACpE,MAAM,IAAI,MAAM,KAAK;CACvB,MAAM,OAAO,OAAA,GAAMA,iBAAAA,SAAAA,CAAS,QAAQ,IAAI,CAAC;CACzC,MAAM,EAAE,OAAO,cAAc,gBAAgBC,wBAAAA,oBAAoB,MAAM,EACrE,SAAS,UACX,CAAC;CACD,MAAM,eAAA,GAAcC,UAAAA,KAAAA,CAAK,MAAM,aAAa;CAE5C,KAAK,MAAM,QAAQ,CAAC,eAAe,UAAU,GAAG;EAC9C,MAAM,UAAA,GAASA,UAAAA,KAAAA,CAAK,MAAM,IAAI;EAC9B,IAAK,MAAMC,uBAAAA,qBAAqB,MAAM,MAAO,KAAA,GAC3C,MAAM,QAAQ,OAAA,GAAMC,iBAAAA,SAAAA,CAAS,QAAQ,MAAM;CAC/C;CACA,MAAM,YAAY,MAAMC,uBAAAA,sBAAsB;EAC5C;EACA,SAAS,CAAC;GAAE,UAAU;GAAe;EAAY,CAAC;CACpD,CAAC;CACD,IAAI,UAAU,SAAS,GACrB,MAAM,IAAI,MACR,UAAU,KAAK,EAAE,MAAM,cAAc,GAAG,KAAK,IAAI,SAAS,CAAC,CAAC,KAAK,IAAI,CACvE;CACF,IAAI,SAAS,WAAW;EACtB,MAAM,QAAQ,OAAA,GAAMC,iBAAAA,MAAAA,EAAAA,GAAMJ,UAAAA,KAAAA,CAAK,MAAM,QAAQ,CAAC,CAAC,CAAC,OAAO,UAAmB;GACxE,IAAI,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS,UAC9D,OAAO,KAAA;GACT,MAAM;EACR,CAAC;EACD,MAAM,SAASK,0BAAAA,0BAA0B;GACvC;GACA,cAAc,UAAU,KAAA,KAAa,aAAa,IAAI,QAAQ;GAC9D,QAAQC,0BAAAA,mBAAmB,IAAI;EACjC,CAAC;EACD,KAAK,MAAM,WAAW,OAAO,UAC3B,QAAQ,OAAO,MAAM,YAAY,QAAQ,GAAG;EAC9C,IAAI,OAAO,OAAO,SAAS,GAAG,MAAM,IAAI,MAAM,OAAO,OAAO,KAAK,IAAI,CAAC;EACtE,QAAQ,OAAO,MAAM,0CAA0C;EAC/D;CACF;CACA,MAAM,OACJ,SAAS,WACLC,0BAAAA,gCAAgC,EAAE,MAAM,CAAC,IACzCC,0BAAAA,0BAA0B,EAAE,MAAM,CAAC,CAAC,CAAC;CAC3C,MAAM,OAAO,MAAMP,uBAAAA,qBAAqB,WAAW;CACnD,IAAI,SAAS,MAAM,gBACjB,MAAMQ,uBAAAA,mBAAmB;EACvB;EACA;EACA,MAAM,SAAS,KAAA,IAAY,MAAQ,KAAK,OAAO;CACjD,CAAC;CACH,QAAQ,OAAO,MACb,GAAG,SAAS,WAAW,iBAAiB,SAAS,iCACnD;AACF;AACA,KAAK,CAAC,CAAC,OAAO,UAAmB;CAC/B,QAAQ,OAAO,MACb,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GACxE;CACA,QAAQ,WAAW;AACrB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { n as generationDiagnostics, r as writeGeneratedFile, t as checkGeneratedOutput } from "./generated-file.mjs";
3
- import { i as synchronizeRepositoryQuarantine, r as pruneRepositoryQuarantine, t as checkRepositoryQuarantine } from "./quarantine-policy2.mjs";
3
+ import { i as synchronizeRepositoryQuarantine, r as pruneRepositoryQuarantine, t as checkRepositoryQuarantine, u as resolveExpiryScope } from "./quarantine-policy2.mjs";
4
4
  import { r as readToolchainInputs } from "./toolchain-guard.mjs";
5
5
  import { lstat, readFile, realpath } from "node:fs/promises";
6
6
  import { join } from "node:path";
@@ -40,7 +40,8 @@ const main = async () => {
40
40
  });
41
41
  const result = checkRepositoryQuarantine({
42
42
  files,
43
- npmrcPresent: npmrc !== void 0 || trackedFiles.has(".npmrc")
43
+ npmrcPresent: npmrc !== void 0 || trackedFiles.has(".npmrc"),
44
+ expiry: resolveExpiryScope(root)
44
45
  });
45
46
  for (const warning of result.warnings) process.stderr.write(`warning: ${warning}\n`);
46
47
  if (result.errors.length > 0) throw new Error(result.errors.join("\n"));
@@ -1 +1 @@
1
- {"version":3,"file":"quarantine-cli.mjs","names":[],"sources":["../src/quarantine-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { lstat, readFile, realpath } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport {\n checkGeneratedOutput,\n generationDiagnostics,\n writeGeneratedFile,\n} from \"./generated-file\";\nimport {\n checkRepositoryQuarantine,\n pruneRepositoryQuarantine,\n synchronizeRepositoryQuarantine,\n} from \"./quarantine-policy\";\nimport { readToolchainInputs } from \"./toolchain-guard\";\n\nconst usage =\n \"Usage: stll-quarantine [--check | --sync | --prune]\\nRun from the repository root; --check is the default.\";\nconst main = async () => {\n const args = process.argv.slice(2);\n if (args.length === 1 && args.at(0) === \"--help\") {\n process.stdout.write(`${usage}\\n`);\n return;\n }\n const mode = args.at(0) ?? \"--check\";\n if (args.length > 1 || ![\"--check\", \"--sync\", \"--prune\"].includes(mode))\n throw new Error(usage);\n const root = await realpath(process.cwd());\n const { files, trackedFiles, diagnostics } = readToolchainInputs(root, {\n bunLock: \"content\",\n });\n const destination = join(root, \"bunfig.toml\");\n // These root inputs may be new outputs not yet staged in Git.\n for (const file of [\"bunfig.toml\", \"bun.lock\"]) {\n const source = join(root, file);\n if ((await checkGeneratedOutput(source)) !== undefined)\n files[file] = await readFile(source, \"utf8\");\n }\n const remaining = await generationDiagnostics({\n diagnostics,\n outputs: [{ relative: \"bunfig.toml\", destination }],\n });\n if (remaining.length > 0)\n throw new Error(\n remaining.map(({ path, message }) => `${path}: ${message}`).join(\"\\n\"),\n );\n if (mode === \"--check\") {\n const npmrc = await lstat(join(root, \".npmrc\")).catch((error: unknown) => {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\")\n return undefined;\n throw error;\n });\n const result = checkRepositoryQuarantine({\n files,\n npmrcPresent: npmrc !== undefined || trackedFiles.has(\".npmrc\"),\n });\n for (const warning of result.warnings)\n process.stderr.write(`warning: ${warning}\\n`);\n if (result.errors.length > 0) throw new Error(result.errors.join(\"\\n\"));\n process.stdout.write(\"Verified bunfig.toml quarantine policy\\n\");\n return;\n }\n const text =\n mode === \"--sync\"\n ? synchronizeRepositoryQuarantine({ files })\n : pruneRepositoryQuarantine({ files }).bunfig;\n const stat = await checkGeneratedOutput(destination);\n if (text !== files[\"bunfig.toml\"])\n await writeGeneratedFile({\n destination,\n text,\n mode: stat === undefined ? 0o644 : stat.mode & 0o777,\n });\n process.stdout.write(\n `${mode === \"--sync\" ? \"Synchronized\" : \"Pruned\"} bunfig.toml quarantine policy\\n`,\n );\n};\nmain().catch((error: unknown) => {\n process.stderr.write(\n `quarantine: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n});\n"],"mappings":";;;;;;;AAgBA,MAAM,QACJ;AACF,MAAM,OAAO,YAAY;CACvB,MAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;CACjC,IAAI,KAAK,WAAW,KAAK,KAAK,GAAG,CAAC,MAAM,UAAU;EAChD,QAAQ,OAAO,MAAM,GAAG,MAAM,GAAG;EACjC;CACF;CACA,MAAM,OAAO,KAAK,GAAG,CAAC,KAAK;CAC3B,IAAI,KAAK,SAAS,KAAK,CAAC;EAAC;EAAW;EAAU;CAAS,CAAC,CAAC,SAAS,IAAI,GACpE,MAAM,IAAI,MAAM,KAAK;CACvB,MAAM,OAAO,MAAM,SAAS,QAAQ,IAAI,CAAC;CACzC,MAAM,EAAE,OAAO,cAAc,gBAAgB,oBAAoB,MAAM,EACrE,SAAS,UACX,CAAC;CACD,MAAM,cAAc,KAAK,MAAM,aAAa;CAE5C,KAAK,MAAM,QAAQ,CAAC,eAAe,UAAU,GAAG;EAC9C,MAAM,SAAS,KAAK,MAAM,IAAI;EAC9B,IAAK,MAAM,qBAAqB,MAAM,MAAO,KAAA,GAC3C,MAAM,QAAQ,MAAM,SAAS,QAAQ,MAAM;CAC/C;CACA,MAAM,YAAY,MAAM,sBAAsB;EAC5C;EACA,SAAS,CAAC;GAAE,UAAU;GAAe;EAAY,CAAC;CACpD,CAAC;CACD,IAAI,UAAU,SAAS,GACrB,MAAM,IAAI,MACR,UAAU,KAAK,EAAE,MAAM,cAAc,GAAG,KAAK,IAAI,SAAS,CAAC,CAAC,KAAK,IAAI,CACvE;CACF,IAAI,SAAS,WAAW;EACtB,MAAM,QAAQ,MAAM,MAAM,KAAK,MAAM,QAAQ,CAAC,CAAC,CAAC,OAAO,UAAmB;GACxE,IAAI,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS,UAC9D,OAAO,KAAA;GACT,MAAM;EACR,CAAC;EACD,MAAM,SAAS,0BAA0B;GACvC;GACA,cAAc,UAAU,KAAA,KAAa,aAAa,IAAI,QAAQ;EAChE,CAAC;EACD,KAAK,MAAM,WAAW,OAAO,UAC3B,QAAQ,OAAO,MAAM,YAAY,QAAQ,GAAG;EAC9C,IAAI,OAAO,OAAO,SAAS,GAAG,MAAM,IAAI,MAAM,OAAO,OAAO,KAAK,IAAI,CAAC;EACtE,QAAQ,OAAO,MAAM,0CAA0C;EAC/D;CACF;CACA,MAAM,OACJ,SAAS,WACL,gCAAgC,EAAE,MAAM,CAAC,IACzC,0BAA0B,EAAE,MAAM,CAAC,CAAC,CAAC;CAC3C,MAAM,OAAO,MAAM,qBAAqB,WAAW;CACnD,IAAI,SAAS,MAAM,gBACjB,MAAM,mBAAmB;EACvB;EACA;EACA,MAAM,SAAS,KAAA,IAAY,MAAQ,KAAK,OAAO;CACjD,CAAC;CACH,QAAQ,OAAO,MACb,GAAG,SAAS,WAAW,iBAAiB,SAAS,iCACnD;AACF;AACA,KAAK,CAAC,CAAC,OAAO,UAAmB;CAC/B,QAAQ,OAAO,MACb,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GACxE;CACA,QAAQ,WAAW;AACrB,CAAC"}
1
+ {"version":3,"file":"quarantine-cli.mjs","names":[],"sources":["../src/quarantine-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { lstat, readFile, realpath } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport { resolveExpiryScope } from \"./dated-entry-scope\";\nimport {\n checkGeneratedOutput,\n generationDiagnostics,\n writeGeneratedFile,\n} from \"./generated-file\";\nimport {\n checkRepositoryQuarantine,\n pruneRepositoryQuarantine,\n synchronizeRepositoryQuarantine,\n} from \"./quarantine-policy\";\nimport { readToolchainInputs } from \"./toolchain-guard\";\n\nconst usage =\n \"Usage: stll-quarantine [--check | --sync | --prune]\\nRun from the repository root; --check is the default.\";\nconst main = async () => {\n const args = process.argv.slice(2);\n if (args.length === 1 && args.at(0) === \"--help\") {\n process.stdout.write(`${usage}\\n`);\n return;\n }\n const mode = args.at(0) ?? \"--check\";\n if (args.length > 1 || ![\"--check\", \"--sync\", \"--prune\"].includes(mode))\n throw new Error(usage);\n const root = await realpath(process.cwd());\n const { files, trackedFiles, diagnostics } = readToolchainInputs(root, {\n bunLock: \"content\",\n });\n const destination = join(root, \"bunfig.toml\");\n // These root inputs may be new outputs not yet staged in Git.\n for (const file of [\"bunfig.toml\", \"bun.lock\"]) {\n const source = join(root, file);\n if ((await checkGeneratedOutput(source)) !== undefined)\n files[file] = await readFile(source, \"utf8\");\n }\n const remaining = await generationDiagnostics({\n diagnostics,\n outputs: [{ relative: \"bunfig.toml\", destination }],\n });\n if (remaining.length > 0)\n throw new Error(\n remaining.map(({ path, message }) => `${path}: ${message}`).join(\"\\n\"),\n );\n if (mode === \"--check\") {\n const npmrc = await lstat(join(root, \".npmrc\")).catch((error: unknown) => {\n if (error instanceof Error && \"code\" in error && error.code === \"ENOENT\")\n return undefined;\n throw error;\n });\n const result = checkRepositoryQuarantine({\n files,\n npmrcPresent: npmrc !== undefined || trackedFiles.has(\".npmrc\"),\n expiry: resolveExpiryScope(root),\n });\n for (const warning of result.warnings)\n process.stderr.write(`warning: ${warning}\\n`);\n if (result.errors.length > 0) throw new Error(result.errors.join(\"\\n\"));\n process.stdout.write(\"Verified bunfig.toml quarantine policy\\n\");\n return;\n }\n const text =\n mode === \"--sync\"\n ? synchronizeRepositoryQuarantine({ files })\n : pruneRepositoryQuarantine({ files }).bunfig;\n const stat = await checkGeneratedOutput(destination);\n if (text !== files[\"bunfig.toml\"])\n await writeGeneratedFile({\n destination,\n text,\n mode: stat === undefined ? 0o644 : stat.mode & 0o777,\n });\n process.stdout.write(\n `${mode === \"--sync\" ? \"Synchronized\" : \"Pruned\"} bunfig.toml quarantine policy\\n`,\n );\n};\nmain().catch((error: unknown) => {\n process.stderr.write(\n `quarantine: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n});\n"],"mappings":";;;;;;;AAiBA,MAAM,QACJ;AACF,MAAM,OAAO,YAAY;CACvB,MAAM,OAAO,QAAQ,KAAK,MAAM,CAAC;CACjC,IAAI,KAAK,WAAW,KAAK,KAAK,GAAG,CAAC,MAAM,UAAU;EAChD,QAAQ,OAAO,MAAM,GAAG,MAAM,GAAG;EACjC;CACF;CACA,MAAM,OAAO,KAAK,GAAG,CAAC,KAAK;CAC3B,IAAI,KAAK,SAAS,KAAK,CAAC;EAAC;EAAW;EAAU;CAAS,CAAC,CAAC,SAAS,IAAI,GACpE,MAAM,IAAI,MAAM,KAAK;CACvB,MAAM,OAAO,MAAM,SAAS,QAAQ,IAAI,CAAC;CACzC,MAAM,EAAE,OAAO,cAAc,gBAAgB,oBAAoB,MAAM,EACrE,SAAS,UACX,CAAC;CACD,MAAM,cAAc,KAAK,MAAM,aAAa;CAE5C,KAAK,MAAM,QAAQ,CAAC,eAAe,UAAU,GAAG;EAC9C,MAAM,SAAS,KAAK,MAAM,IAAI;EAC9B,IAAK,MAAM,qBAAqB,MAAM,MAAO,KAAA,GAC3C,MAAM,QAAQ,MAAM,SAAS,QAAQ,MAAM;CAC/C;CACA,MAAM,YAAY,MAAM,sBAAsB;EAC5C;EACA,SAAS,CAAC;GAAE,UAAU;GAAe;EAAY,CAAC;CACpD,CAAC;CACD,IAAI,UAAU,SAAS,GACrB,MAAM,IAAI,MACR,UAAU,KAAK,EAAE,MAAM,cAAc,GAAG,KAAK,IAAI,SAAS,CAAC,CAAC,KAAK,IAAI,CACvE;CACF,IAAI,SAAS,WAAW;EACtB,MAAM,QAAQ,MAAM,MAAM,KAAK,MAAM,QAAQ,CAAC,CAAC,CAAC,OAAO,UAAmB;GACxE,IAAI,iBAAiB,SAAS,UAAU,SAAS,MAAM,SAAS,UAC9D,OAAO,KAAA;GACT,MAAM;EACR,CAAC;EACD,MAAM,SAAS,0BAA0B;GACvC;GACA,cAAc,UAAU,KAAA,KAAa,aAAa,IAAI,QAAQ;GAC9D,QAAQ,mBAAmB,IAAI;EACjC,CAAC;EACD,KAAK,MAAM,WAAW,OAAO,UAC3B,QAAQ,OAAO,MAAM,YAAY,QAAQ,GAAG;EAC9C,IAAI,OAAO,OAAO,SAAS,GAAG,MAAM,IAAI,MAAM,OAAO,OAAO,KAAK,IAAI,CAAC;EACtE,QAAQ,OAAO,MAAM,0CAA0C;EAC/D;CACF;CACA,MAAM,OACJ,SAAS,WACL,gCAAgC,EAAE,MAAM,CAAC,IACzC,0BAA0B,EAAE,MAAM,CAAC,CAAC,CAAC;CAC3C,MAAM,OAAO,MAAM,qBAAqB,WAAW;CACnD,IAAI,SAAS,MAAM,gBACjB,MAAM,mBAAmB;EACvB;EACA;EACA,MAAM,SAAS,KAAA,IAAY,MAAQ,KAAK,OAAO;CACjD,CAAC;CACH,QAAQ,OAAO,MACb,GAAG,SAAS,WAAW,iBAAiB,SAAS,iCACnD;AACF;AACA,KAAK,CAAC,CAAC,OAAO,UAAmB;CAC/B,QAAQ,OAAO,MACb,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,EAAE,GACxE;CACA,QAAQ,WAAW;AACrB,CAAC"}