@clossys/launcher 0.3.1 → 0.4.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 (285) hide show
  1. package/README.md +1324 -60
  2. package/contracts/conversation-contract.md +2 -2
  3. package/contracts/product-ci-workflow.yml +74 -0
  4. package/contracts/repository-inventory.json +53 -0
  5. package/dist/admission-fixture.d.ts +168 -0
  6. package/dist/admission-fixture.d.ts.map +1 -0
  7. package/dist/admission-fixture.js +453 -0
  8. package/dist/admission-fixture.js.map +1 -0
  9. package/dist/admission.d.ts +124 -0
  10. package/dist/admission.d.ts.map +1 -0
  11. package/dist/admission.js +799 -0
  12. package/dist/admission.js.map +1 -0
  13. package/dist/agents-guide.d.ts +9 -0
  14. package/dist/agents-guide.d.ts.map +1 -0
  15. package/dist/agents-guide.js +26 -0
  16. package/dist/agents-guide.js.map +1 -0
  17. package/dist/apply-command-options.check.d.ts +12 -0
  18. package/dist/apply-command-options.check.d.ts.map +1 -0
  19. package/dist/apply-command-options.check.js +20 -0
  20. package/dist/apply-command-options.check.js.map +1 -0
  21. package/dist/apply-plan-cli.d.ts +39 -1
  22. package/dist/apply-plan-cli.d.ts.map +1 -1
  23. package/dist/apply-plan-cli.js +432 -15
  24. package/dist/apply-plan-cli.js.map +1 -1
  25. package/dist/apply-plan.d.ts +46 -59
  26. package/dist/apply-plan.d.ts.map +1 -1
  27. package/dist/apply-plan.js +112 -97
  28. package/dist/apply-plan.js.map +1 -1
  29. package/dist/apply-step-fixture.d.ts +87 -0
  30. package/dist/apply-step-fixture.d.ts.map +1 -0
  31. package/dist/apply-step-fixture.js +199 -0
  32. package/dist/apply-step-fixture.js.map +1 -0
  33. package/dist/apply-store.d.ts +93 -0
  34. package/dist/apply-store.d.ts.map +1 -0
  35. package/dist/apply-store.js +625 -0
  36. package/dist/apply-store.js.map +1 -0
  37. package/dist/approval-sheet.d.ts +21 -0
  38. package/dist/approval-sheet.d.ts.map +1 -0
  39. package/dist/approval-sheet.js +157 -0
  40. package/dist/approval-sheet.js.map +1 -0
  41. package/dist/body-command.d.ts +42 -0
  42. package/dist/body-command.d.ts.map +1 -0
  43. package/dist/body-command.js +143 -0
  44. package/dist/body-command.js.map +1 -0
  45. package/dist/change-set-contract.d.ts +381 -0
  46. package/dist/change-set-contract.d.ts.map +1 -0
  47. package/dist/change-set-contract.js +738 -0
  48. package/dist/change-set-contract.js.map +1 -0
  49. package/dist/change-set-digest.d.ts +28 -0
  50. package/dist/change-set-digest.d.ts.map +1 -0
  51. package/dist/change-set-digest.js +65 -0
  52. package/dist/change-set-digest.js.map +1 -0
  53. package/dist/check-cli.d.ts.map +1 -1
  54. package/dist/check-cli.js +14 -3
  55. package/dist/check-cli.js.map +1 -1
  56. package/dist/cli.d.ts +17 -6
  57. package/dist/cli.d.ts.map +1 -1
  58. package/dist/cli.js +84 -23
  59. package/dist/cli.js.map +1 -1
  60. package/dist/core.d.ts +79 -22
  61. package/dist/core.d.ts.map +1 -1
  62. package/dist/core.js +843 -268
  63. package/dist/core.js.map +1 -1
  64. package/dist/dry-materialize.d.ts +63 -0
  65. package/dist/dry-materialize.d.ts.map +1 -0
  66. package/dist/dry-materialize.js +330 -0
  67. package/dist/dry-materialize.js.map +1 -0
  68. package/dist/generated/contract-schema.generated.d.ts +97 -0
  69. package/dist/generated/contract-schema.generated.d.ts.map +1 -0
  70. package/dist/generated/contract-schema.generated.js +496 -0
  71. package/dist/generated/contract-schema.generated.js.map +1 -0
  72. package/dist/generated/package-scope.generated.d.ts +6 -0
  73. package/dist/generated/package-scope.generated.d.ts.map +1 -0
  74. package/dist/generated/package-scope.generated.js +10 -0
  75. package/dist/generated/package-scope.generated.js.map +1 -0
  76. package/dist/generated/plan-contracts.generated.d.ts +3 -0
  77. package/dist/generated/plan-contracts.generated.d.ts.map +1 -0
  78. package/dist/generated/plan-contracts.generated.js +2840 -0
  79. package/dist/generated/plan-contracts.generated.js.map +1 -0
  80. package/dist/host.d.ts.map +1 -1
  81. package/dist/host.js +11 -0
  82. package/dist/host.js.map +1 -1
  83. package/dist/identity.d.ts +15 -0
  84. package/dist/identity.d.ts.map +1 -0
  85. package/dist/identity.js +48 -0
  86. package/dist/identity.js.map +1 -0
  87. package/dist/index.d.ts +34 -5
  88. package/dist/index.d.ts.map +1 -1
  89. package/dist/index.js +19 -2
  90. package/dist/index.js.map +1 -1
  91. package/dist/inventory-adoption.d.ts +24 -5
  92. package/dist/inventory-adoption.d.ts.map +1 -1
  93. package/dist/inventory-adoption.js +70 -25
  94. package/dist/inventory-adoption.js.map +1 -1
  95. package/dist/inventory-choice.d.ts +40 -0
  96. package/dist/inventory-choice.d.ts.map +1 -0
  97. package/dist/inventory-choice.js +156 -0
  98. package/dist/inventory-choice.js.map +1 -0
  99. package/dist/inventory-contract.d.ts +89 -0
  100. package/dist/inventory-contract.d.ts.map +1 -0
  101. package/dist/inventory-contract.js +121 -0
  102. package/dist/inventory-contract.js.map +1 -0
  103. package/dist/key-editor.d.ts +30 -0
  104. package/dist/key-editor.d.ts.map +1 -0
  105. package/dist/key-editor.js +445 -0
  106. package/dist/key-editor.js.map +1 -0
  107. package/dist/ledger-contract.d.ts +187 -0
  108. package/dist/ledger-contract.d.ts.map +1 -0
  109. package/dist/ledger-contract.js +532 -0
  110. package/dist/ledger-contract.js.map +1 -0
  111. package/dist/ledger-trust.d.ts +90 -0
  112. package/dist/ledger-trust.d.ts.map +1 -0
  113. package/dist/ledger-trust.js +198 -0
  114. package/dist/ledger-trust.js.map +1 -0
  115. package/dist/lockfile-invariants.d.ts +48 -0
  116. package/dist/lockfile-invariants.d.ts.map +1 -0
  117. package/dist/lockfile-invariants.js +375 -0
  118. package/dist/lockfile-invariants.js.map +1 -0
  119. package/dist/lockfile-readers.d.ts +72 -0
  120. package/dist/lockfile-readers.d.ts.map +1 -0
  121. package/dist/lockfile-readers.js +713 -0
  122. package/dist/lockfile-readers.js.map +1 -0
  123. package/dist/lockfile-regen.d.ts +106 -0
  124. package/dist/lockfile-regen.d.ts.map +1 -0
  125. package/dist/lockfile-regen.js +760 -0
  126. package/dist/lockfile-regen.js.map +1 -0
  127. package/dist/lockfile-tool-env.d.ts +29 -0
  128. package/dist/lockfile-tool-env.d.ts.map +1 -0
  129. package/dist/lockfile-tool-env.js +111 -0
  130. package/dist/lockfile-tool-env.js.map +1 -0
  131. package/dist/materialize.d.ts +113 -0
  132. package/dist/materialize.d.ts.map +1 -0
  133. package/dist/materialize.js +840 -0
  134. package/dist/materialize.js.map +1 -0
  135. package/dist/observe-repository.d.ts +90 -0
  136. package/dist/observe-repository.d.ts.map +1 -0
  137. package/dist/observe-repository.js +1367 -0
  138. package/dist/observe-repository.js.map +1 -0
  139. package/dist/plan-bundle-setup-fixture.d.ts +68 -0
  140. package/dist/plan-bundle-setup-fixture.d.ts.map +1 -0
  141. package/dist/plan-bundle-setup-fixture.js +167 -0
  142. package/dist/plan-bundle-setup-fixture.js.map +1 -0
  143. package/dist/plan-bundle.d.ts +250 -0
  144. package/dist/plan-bundle.d.ts.map +1 -0
  145. package/dist/plan-bundle.js +827 -0
  146. package/dist/plan-bundle.js.map +1 -0
  147. package/dist/plan-command.d.ts +29 -0
  148. package/dist/plan-command.d.ts.map +1 -0
  149. package/dist/plan-command.js +493 -0
  150. package/dist/plan-command.js.map +1 -0
  151. package/dist/plan-contract.d.ts +153 -0
  152. package/dist/plan-contract.d.ts.map +1 -0
  153. package/dist/plan-contract.js +61 -0
  154. package/dist/plan-contract.js.map +1 -0
  155. package/dist/plan-digest.d.ts +25 -0
  156. package/dist/plan-digest.d.ts.map +1 -0
  157. package/dist/plan-digest.js +106 -0
  158. package/dist/plan-digest.js.map +1 -0
  159. package/dist/plan-rules.d.ts +23 -0
  160. package/dist/plan-rules.d.ts.map +1 -0
  161. package/dist/plan-rules.js +177 -0
  162. package/dist/plan-rules.js.map +1 -0
  163. package/dist/planned-bundle.d.ts +20 -0
  164. package/dist/planned-bundle.d.ts.map +1 -0
  165. package/dist/planned-bundle.js +191 -0
  166. package/dist/planned-bundle.js.map +1 -0
  167. package/dist/product-repository.d.ts +4 -0
  168. package/dist/product-repository.d.ts.map +1 -1
  169. package/dist/product-repository.js +9 -1
  170. package/dist/product-repository.js.map +1 -1
  171. package/dist/provenance-gate.d.ts +48 -0
  172. package/dist/provenance-gate.d.ts.map +1 -0
  173. package/dist/provenance-gate.js +324 -0
  174. package/dist/provenance-gate.js.map +1 -0
  175. package/dist/pull-request-body.d.ts +45 -0
  176. package/dist/pull-request-body.d.ts.map +1 -0
  177. package/dist/pull-request-body.js +232 -0
  178. package/dist/pull-request-body.js.map +1 -0
  179. package/dist/registry-snapshot.d.ts +141 -0
  180. package/dist/registry-snapshot.d.ts.map +1 -0
  181. package/dist/registry-snapshot.js +483 -0
  182. package/dist/registry-snapshot.js.map +1 -0
  183. package/dist/release-age-edit.d.ts +52 -0
  184. package/dist/release-age-edit.d.ts.map +1 -0
  185. package/dist/release-age-edit.js +413 -0
  186. package/dist/release-age-edit.js.map +1 -0
  187. package/dist/root-entries.d.ts +36 -0
  188. package/dist/root-entries.d.ts.map +1 -0
  189. package/dist/root-entries.js +80 -0
  190. package/dist/root-entries.js.map +1 -0
  191. package/dist/setup-template-scripts.d.ts +34 -0
  192. package/dist/setup-template-scripts.d.ts.map +1 -0
  193. package/dist/setup-template-scripts.js +557 -0
  194. package/dist/setup-template-scripts.js.map +1 -0
  195. package/dist/setup-templates.d.ts +54 -0
  196. package/dist/setup-templates.d.ts.map +1 -0
  197. package/dist/setup-templates.js +427 -0
  198. package/dist/setup-templates.js.map +1 -0
  199. package/dist/skills.d.ts +34 -1
  200. package/dist/skills.d.ts.map +1 -1
  201. package/dist/skills.js +129 -17
  202. package/dist/skills.js.map +1 -1
  203. package/dist/status.d.ts +63 -0
  204. package/dist/status.d.ts.map +1 -0
  205. package/dist/status.js +539 -0
  206. package/dist/status.js.map +1 -0
  207. package/dist/types.d.ts +151 -13
  208. package/dist/types.d.ts.map +1 -1
  209. package/package.json +4 -4
  210. package/skeleton/README.md +14 -9
  211. package/skeleton/package.json +2 -1
  212. package/skill/SKILL.md +23 -7
  213. package/skill-catalogue/advisor/SKILL.md +59 -6
  214. package/skill-catalogue/architect/SKILL.md +2 -2
  215. package/skill-catalogue/bouncer/SKILL.md +2 -2
  216. package/skill-catalogue/builder/SKILL.md +2 -2
  217. package/skill-catalogue/butler/SKILL.md +2 -2
  218. package/skill-catalogue/controller/SKILL.md +2 -2
  219. package/skill-catalogue/customer/SKILL.md +2 -2
  220. package/skill-catalogue/designer/SKILL.md +4 -2
  221. package/skill-catalogue/giver/SKILL.md +2 -2
  222. package/skill-catalogue/influencer/SKILL.md +2 -2
  223. package/skill-catalogue/inspector/SKILL.md +2 -2
  224. package/skill-catalogue/integrator/SKILL.md +2 -2
  225. package/skill-catalogue/keeper/SKILL.md +2 -2
  226. package/skill-catalogue/launcher/SKILL.md +23 -7
  227. package/skill-catalogue/locksmith/SKILL.md +2 -2
  228. package/skill-catalogue/messenger/SKILL.md +2 -2
  229. package/skill-catalogue/observer/SKILL.md +2 -2
  230. package/skill-catalogue/publisher/SKILL.md +2 -2
  231. package/skill-catalogue/starter/SKILL.md +3 -2
  232. package/skill-catalogue/strategist/SKILL.md +12 -4
  233. package/skill-catalogue/writer/SKILL.md +2 -2
  234. package/src/admission-fixture.ts +572 -0
  235. package/src/admission.ts +816 -0
  236. package/src/agents-guide.ts +29 -0
  237. package/src/apply-command-options.check.ts +27 -0
  238. package/src/apply-plan-cli.ts +454 -14
  239. package/src/apply-plan.ts +112 -124
  240. package/src/apply-step-fixture.ts +236 -0
  241. package/src/apply-store.ts +584 -0
  242. package/src/approval-sheet.ts +164 -0
  243. package/src/body-command.ts +162 -0
  244. package/src/change-set-contract.ts +937 -0
  245. package/src/change-set-digest.ts +70 -0
  246. package/src/check-cli.ts +14 -3
  247. package/src/cli.ts +90 -22
  248. package/src/core.ts +973 -275
  249. package/src/dry-materialize.ts +353 -0
  250. package/src/generated/contract-schema.generated.ts +520 -0
  251. package/src/generated/package-scope.generated.ts +10 -0
  252. package/src/generated/plan-contracts.generated.ts +2840 -0
  253. package/src/host.ts +10 -0
  254. package/src/identity.ts +51 -0
  255. package/src/index.ts +72 -3
  256. package/src/inventory-adoption.ts +107 -29
  257. package/src/inventory-choice.ts +172 -0
  258. package/src/inventory-contract.ts +166 -0
  259. package/src/key-editor.ts +446 -0
  260. package/src/ledger-contract.ts +637 -0
  261. package/src/ledger-trust.ts +267 -0
  262. package/src/lockfile-invariants.ts +421 -0
  263. package/src/lockfile-readers.ts +749 -0
  264. package/src/lockfile-regen.ts +851 -0
  265. package/src/lockfile-tool-env.ts +131 -0
  266. package/src/materialize.ts +886 -0
  267. package/src/observe-repository.ts +1365 -0
  268. package/src/plan-bundle-setup-fixture.ts +200 -0
  269. package/src/plan-bundle.ts +964 -0
  270. package/src/plan-command.ts +509 -0
  271. package/src/plan-contract.ts +179 -0
  272. package/src/plan-digest.ts +102 -0
  273. package/src/plan-rules.ts +188 -0
  274. package/src/planned-bundle.ts +211 -0
  275. package/src/product-repository.ts +10 -1
  276. package/src/provenance-gate.ts +352 -0
  277. package/src/pull-request-body.ts +261 -0
  278. package/src/registry-snapshot.ts +534 -0
  279. package/src/release-age-edit.ts +430 -0
  280. package/src/root-entries.ts +81 -0
  281. package/src/setup-template-scripts.ts +571 -0
  282. package/src/setup-templates.ts +471 -0
  283. package/src/skills.ts +161 -18
  284. package/src/status.ts +557 -0
  285. package/src/types.ts +148 -13
@@ -0,0 +1,483 @@
1
+ // The registry snapshot step (issue #1178): the one step of applying a plan
2
+ // that reads the package registry. It fetches each requested package's registry
3
+ // document anonymously, projects it into the shared registry snapshot
4
+ // contract (docs/contracts/registry-snapshot.json, in the public repository,
5
+ // not shipped in this package; its content is packed into src/generated/ at
6
+ // build time), validates the whole snapshot against that contract, and only
7
+ // then writes it, atomically.
8
+ //
9
+ // Credentials: every read goes through an injected `Transport` whose default
10
+ // is Node's own `fetch`. Nothing here runs the npm CLI, reads an `.npmrc`,
11
+ // reads an environment variable, or sets an `Authorization` header; the only
12
+ // headers this step sets are `accept` and `accept-encoding: identity`, and
13
+ // Node's fetch adds its own default, non-credential headers. Identity asks
14
+ // for the body uncompressed, so when the server honours it the hash and the
15
+ // size cap apply to the bytes received. Redirects are refused (`redirect: "error"`, and a
16
+ // 3xx answer from any transport is refused too), each response is read as a
17
+ // stream and abandoned the moment it passes MAX_RESPONSE_BYTES (counted after
18
+ // any decoding, so a server that compresses anyway is still bounded), and each
19
+ // request, body included, is abandoned after a timeout.
20
+ import { createHash, randomBytes } from "node:crypto";
21
+ import { closeSync, fsyncSync, mkdirSync, openSync, readFileSync, renameSync, rmSync, writeSync } from "node:fs";
22
+ import { basename, dirname, join } from "node:path";
23
+ import { ContractDocumentError, readContractDocument, validateAgainstContract } from "./generated/contract-schema.generated.js";
24
+ import { PACKAGE_SCOPE } from "./generated/package-scope.generated.js";
25
+ import { PLAN_CONTRACTS } from "./generated/plan-contracts.generated.js";
26
+ /** Where the snapshot is written by default, relative to the hub root. */
27
+ export const REGISTRY_SNAPSHOT_REL = "clossys/.state/apply/registry-snapshot.json";
28
+ /** The most bytes read from any one registry response (10 MiB). */
29
+ export const MAX_RESPONSE_BYTES = 10 * 1024 * 1024;
30
+ /** How long one request, its body included, may take. */
31
+ export const DEFAULT_TIMEOUT_MS = 30_000;
32
+ /** Node's own `fetch`. It reads no npm configuration and adds no registry credential (a proxy URL's own username and password, if any, go only to that proxy). */
33
+ export const nodeFetchTransport = (input, init) => fetch(input, init);
34
+ /**
35
+ * Why the snapshot step stopped. The message names a package only by its
36
+ * position in the request (`names[<n>]`), never by its name: a name is
37
+ * request text, and a request is a file anyone could have written. It
38
+ * never carries registry content either.
39
+ */
40
+ export class RegistrySnapshotError extends Error {
41
+ }
42
+ function loadContract(name) {
43
+ const contract = Object.hasOwn(PLAN_CONTRACTS, name) ? PLAN_CONTRACTS[name] : undefined;
44
+ if (contract === undefined)
45
+ throw new Error(`no packed contract named ${JSON.stringify(name)}`);
46
+ return contract;
47
+ }
48
+ function eachRepeat(items, key, onRepeat) {
49
+ const first = new Map();
50
+ items.forEach((item, index) => {
51
+ const value = key(item);
52
+ const earlier = first.get(value);
53
+ if (earlier === undefined)
54
+ first.set(value, index);
55
+ else
56
+ onRepeat(index, earlier);
57
+ });
58
+ }
59
+ /**
60
+ * Every violation of the registry snapshot contract: its schema, then, only
61
+ * for a snapshot whose shape is known good, its code rules N1-N3 (no package
62
+ * named twice, no version recorded twice for one package, no `latest` or
63
+ * versions for a package that was not found). Implemented separately from
64
+ * @clossys/advisor's reader; both are tested against the one corpus,
65
+ * docs/contracts/registry-snapshot.fixture.json (in the public repository,
66
+ * not shipped in this package). Never throws.
67
+ */
68
+ export function registrySnapshotViolations(value) {
69
+ const schema = validateAgainstContract(loadContract("registry-snapshot.json"), value, loadContract);
70
+ // The shared checker's path and message never carry document text: an undeclared field is placed at its object, by position.
71
+ if (schema.length > 0)
72
+ return schema.map((violation) => ({ rule: "schema", path: violation.path, message: violation.message }));
73
+ const snapshot = value;
74
+ const violations = [];
75
+ eachRepeat(snapshot.packages, (entry) => entry.name, (index, first) => violations.push({ rule: "N1", path: `packages[${index}].name`, message: `repeats packages[${first}].name` }));
76
+ snapshot.packages.forEach((entry, index) => {
77
+ eachRepeat(entry.versions, (version) => version.version, (position, first) => violations.push({ rule: "N2", path: `packages[${index}].versions[${position}].version`, message: `repeats packages[${index}].versions[${first}].version` }));
78
+ if (entry.status === "not-found") {
79
+ if (entry.latest !== null)
80
+ violations.push({ rule: "N3", path: `packages[${index}].latest`, message: "must be null when the package was not found" });
81
+ if (entry.versions.length > 0)
82
+ violations.push({ rule: "N3", path: `packages[${index}].versions`, message: "must be empty when the package was not found" });
83
+ }
84
+ });
85
+ return violations;
86
+ }
87
+ /** Compares strings as sequences of UTF-16 code units, the order the snapshot contract sorts by. */
88
+ function byCodeUnits(left, right) {
89
+ return left < right ? -1 : left > right ? 1 : 0;
90
+ }
91
+ /** The snapshot in the contract's canonical order: packages sorted by name, each package's versions sorted by version. */
92
+ export function canonicalRegistrySnapshot(snapshot) {
93
+ return {
94
+ ...snapshot,
95
+ packages: [...snapshot.packages]
96
+ .sort((left, right) => byCodeUnits(left.name, right.name))
97
+ .map((entry) => ({ ...entry, versions: [...entry.versions].sort((left, right) => byCodeUnits(left.version, right.version)) })),
98
+ };
99
+ }
100
+ /**
101
+ * A package name's registry path segment. Copied, unchanged, from
102
+ * `registryEncodedName` in @clossys/integrator's provenance-check.ts, which
103
+ * this package must not depend on at runtime; a test compares the two
104
+ * function bodies so they cannot drift apart. The leading `@` stays literal
105
+ * and only the slash is percent-encoded (`@scope%2Fname`), the convention
106
+ * npm-compatible registries share; `encodeURIComponent` on the whole name
107
+ * would also encode the `@`, which none of them expect.
108
+ */
109
+ export function registryEncodedName(name) {
110
+ const slash = name.indexOf("/");
111
+ if (slash === -1)
112
+ return encodeURIComponent(name);
113
+ return `@${encodeURIComponent(name.slice(1, slash))}%2F${encodeURIComponent(name.slice(slash + 1))}`;
114
+ }
115
+ /** The full registry document's URL for `name`: `{registry}/{encoded name}`. */
116
+ export function packumentUrl(registry, name) {
117
+ return new URL(registryEncodedName(name), registry.endsWith("/") ? registry : `${registry}/`);
118
+ }
119
+ const PACKAGE_NAME = new RegExp(loadContract("registry-snapshot.json").definitions.packageName.pattern);
120
+ /**
121
+ * The package names in a snapshot request: the report `advisor-package-request`
122
+ * prints, `{ state: "satisfied", names, findings: [] }`, or just `{ names }`.
123
+ * Every name must be a scoped package name in the packed publishing scope,
124
+ * named once. A refusal names positions only, never the request's text.
125
+ */
126
+ export function requestedPackageNames(request, scope = PACKAGE_SCOPE.scope) {
127
+ if (typeof request !== "object" || request === null || Array.isArray(request))
128
+ throw new RegistrySnapshotError("the request must be a JSON object with a names array");
129
+ const record = request;
130
+ if (Object.keys(record).some((key) => key !== "state" && key !== "names" && key !== "findings")) {
131
+ throw new RegistrySnapshotError("the request has a field other than state, names and findings");
132
+ }
133
+ if (Object.hasOwn(record, "state") && record.state !== "satisfied") {
134
+ throw new RegistrySnapshotError("the request's state is not satisfied: fix the plan and run advisor-package-request again");
135
+ }
136
+ if (Object.hasOwn(record, "findings") && !(Array.isArray(record.findings) && record.findings.length === 0)) {
137
+ throw new RegistrySnapshotError("the request's findings must be an empty array");
138
+ }
139
+ const names = Object.hasOwn(record, "names") ? record.names : undefined;
140
+ if (!Array.isArray(names) || names.length === 0)
141
+ throw new RegistrySnapshotError("the request's names must be a non-empty array");
142
+ const seen = new Map();
143
+ for (let index = 0; index < names.length; index += 1) {
144
+ if (!Object.hasOwn(names, index))
145
+ throw new RegistrySnapshotError(`names[${index}] is missing`);
146
+ const name = names[index];
147
+ if (typeof name !== "string" || !PACKAGE_NAME.test(name) || !name.startsWith(`${scope}/`)) {
148
+ throw new RegistrySnapshotError(`names[${index}] is not a package name in the ${scope} scope`);
149
+ }
150
+ const earlier = seen.get(name);
151
+ if (earlier !== undefined)
152
+ throw new RegistrySnapshotError(`names[${index}] repeats names[${earlier}]`);
153
+ seen.set(name, index);
154
+ }
155
+ return names;
156
+ }
157
+ /** A registry document that cannot be projected. `what` is fixed text, never the document's. */
158
+ class PackumentShapeError extends Error {
159
+ }
160
+ function isPlainObject(value) {
161
+ return typeof value === "object" && value !== null && !Array.isArray(value);
162
+ }
163
+ /** An own member only: a registry document's inherited members are never read. */
164
+ function own(record, key) {
165
+ return Object.hasOwn(record, key) ? record[key] : undefined;
166
+ }
167
+ /** An own member that must be a plain object when present; absent or null reads as undefined. */
168
+ function optionalObject(record, key, what) {
169
+ const value = own(record, key);
170
+ if (value === undefined || value === null)
171
+ return undefined;
172
+ if (!isPlainObject(value))
173
+ throw new PackumentShapeError(what);
174
+ return value;
175
+ }
176
+ function optionalString(record, key, what) {
177
+ const value = own(record, key);
178
+ if (value === undefined || value === null)
179
+ return null;
180
+ if (typeof value !== "string")
181
+ throw new PackumentShapeError(what);
182
+ return value;
183
+ }
184
+ /**
185
+ * Projects a registry document into one snapshot entry's `latest` and
186
+ * `versions`, reading only what the contract records: the version the
187
+ * `latest` dist-tag names, and that one version's integrity, tarball,
188
+ * deprecation, publish time and attestation presence. Every other version,
189
+ * dist-tag and field is ignored. When `latest` names a version the document
190
+ * does not list, `versions` is empty, so a resolver refuses it by name.
191
+ */
192
+ export function projectPackument(name, document) {
193
+ if (!isPlainObject(document))
194
+ throw new PackumentShapeError("is not a JSON object");
195
+ if (own(document, "name") !== name)
196
+ throw new PackumentShapeError("does not name the package that was requested");
197
+ const distTags = optionalObject(document, "dist-tags", "has dist-tags that are not an object");
198
+ const latest = distTags === undefined ? null : optionalString(distTags, "latest", "has a latest dist-tag that is not a string");
199
+ if (latest === null)
200
+ return { latest: null, versions: [] };
201
+ const versions = optionalObject(document, "versions", "has versions that are not an object");
202
+ const entry = versions === undefined ? undefined : own(versions, latest);
203
+ if (entry === undefined)
204
+ return { latest, versions: [] };
205
+ if (!isPlainObject(entry))
206
+ throw new PackumentShapeError("lists the latest version as something that is not an object");
207
+ if (own(entry, "version") !== latest)
208
+ throw new PackumentShapeError("lists the latest version under a different version number");
209
+ const dist = optionalObject(entry, "dist", "has a latest version whose dist is not an object") ?? {};
210
+ const tarball = own(dist, "tarball");
211
+ if (typeof tarball !== "string")
212
+ throw new PackumentShapeError("has a latest version with no tarball URL");
213
+ const deprecation = own(entry, "deprecated");
214
+ let deprecated;
215
+ if (deprecation === undefined || deprecation === null)
216
+ deprecated = false;
217
+ else if (typeof deprecation === "boolean")
218
+ deprecated = deprecation;
219
+ // npm treats an empty deprecation message as no deprecation, and any other message as one.
220
+ else if (typeof deprecation === "string")
221
+ deprecated = deprecation !== "";
222
+ else
223
+ throw new PackumentShapeError("marks the latest version deprecated with something that is neither text nor a boolean");
224
+ const attestations = own(dist, "attestations");
225
+ if (attestations !== undefined && attestations !== null && !isPlainObject(attestations)) {
226
+ throw new PackumentShapeError("has latest-version attestations that are not an object");
227
+ }
228
+ const time = optionalObject(document, "time", "has a time field that is not an object");
229
+ return {
230
+ latest,
231
+ versions: [
232
+ {
233
+ version: latest,
234
+ integrity: optionalString(dist, "integrity", "has a latest-version integrity that is not a string"),
235
+ tarball,
236
+ deprecated,
237
+ publishedAt: time === undefined ? null : optionalString(time, latest, "has a latest-version publish time that is not a string"),
238
+ // Listed only when the registry names where the attestations are: an empty object lists none.
239
+ hasAttestations: isPlainObject(attestations) && typeof own(attestations, "url") === "string" && /\S/.test(own(attestations, "url")),
240
+ },
241
+ ],
242
+ };
243
+ }
244
+ const TIMED_OUT = Symbol("timed out");
245
+ /** Settles with `promise`, or rejects with TIMED_OUT as soon as `signal` aborts, whether or not the transport honours the signal. */
246
+ function untilAborted(promise, signal) {
247
+ if (signal.aborted)
248
+ return Promise.reject(TIMED_OUT);
249
+ return new Promise((resolve, reject) => {
250
+ const onAbort = () => reject(TIMED_OUT);
251
+ signal.addEventListener("abort", onAbort, { once: true });
252
+ promise.then((value) => {
253
+ signal.removeEventListener("abort", onAbort);
254
+ resolve(value);
255
+ }, (error) => {
256
+ signal.removeEventListener("abort", onAbort);
257
+ reject(error);
258
+ });
259
+ });
260
+ }
261
+ /**
262
+ * The body's bytes, read chunk by chunk. The read stops, and the stream is
263
+ * cancelled, the moment the running total passes `cap`, so an oversize body
264
+ * is never buffered past it.
265
+ */
266
+ async function readCapped(body, cap, signal) {
267
+ if (body === null)
268
+ return new Uint8Array(0);
269
+ const reader = body.getReader();
270
+ const chunks = [];
271
+ let total = 0;
272
+ try {
273
+ for (;;) {
274
+ const { done, value } = await untilAborted(reader.read(), signal);
275
+ if (done)
276
+ break;
277
+ if (!(value instanceof Uint8Array))
278
+ throw new TypeError("a response chunk is not bytes");
279
+ total += value.byteLength;
280
+ if (total > cap)
281
+ return "too-large";
282
+ chunks.push(value);
283
+ }
284
+ }
285
+ finally {
286
+ reader.cancel().catch(() => undefined);
287
+ }
288
+ const bytes = new Uint8Array(total);
289
+ let offset = 0;
290
+ for (const chunk of chunks) {
291
+ bytes.set(chunk, offset);
292
+ offset += chunk.byteLength;
293
+ }
294
+ return bytes;
295
+ }
296
+ /**
297
+ * The request options this step sets on every registry read: `accept`, and
298
+ * `accept-encoding: identity` so that a server that honours it sends the body
299
+ * uncompressed and `responseSha256` and the size cap apply to the exact bytes
300
+ * received; no credential, no redirect. Node's fetch adds its own default,
301
+ * non-credential headers.
302
+ */
303
+ function requestInit(signal) {
304
+ return { method: "GET", headers: { accept: "application/json", "accept-encoding": "identity" }, redirect: "error", credentials: "omit", signal };
305
+ }
306
+ async function fetchOne(transport, url, where, timeoutMs) {
307
+ const controller = new AbortController();
308
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
309
+ const seconds = `${timeoutMs / 1000} s`;
310
+ try {
311
+ let response;
312
+ try {
313
+ response = await untilAborted(transport(url, requestInit(controller.signal)), controller.signal);
314
+ }
315
+ catch {
316
+ if (controller.signal.aborted)
317
+ throw new RegistrySnapshotError(`${where}: the registry did not answer within ${seconds}`);
318
+ throw new RegistrySnapshotError(`${where}: the registry could not be reached, or answered with a redirect, which is refused`);
319
+ }
320
+ const { status } = response;
321
+ const discard = () => {
322
+ response.body?.cancel().catch(() => undefined);
323
+ };
324
+ if (response.redirected || (status >= 300 && status < 400)) {
325
+ discard();
326
+ throw new RegistrySnapshotError(`${where}: the registry answered with a redirect${response.redirected ? "" : ` (HTTP ${status})`}, which is refused and never followed`);
327
+ }
328
+ if (status !== 200 && status !== 404) {
329
+ discard();
330
+ throw new RegistrySnapshotError(`${where}: the registry answered HTTP ${status}; only 200 and 404 are recorded`);
331
+ }
332
+ const tooLarge = `${where}: the registry's response is larger than ${MAX_RESPONSE_BYTES / (1024 * 1024)} MiB and was not read past that`;
333
+ const declared = response.headers.get("content-length");
334
+ if (declared !== null && /^\d+$/.test(declared.trim()) && Number(declared.trim()) > MAX_RESPONSE_BYTES) {
335
+ discard();
336
+ throw new RegistrySnapshotError(tooLarge);
337
+ }
338
+ let bytes;
339
+ try {
340
+ bytes = await readCapped(response.body, MAX_RESPONSE_BYTES, controller.signal);
341
+ }
342
+ catch {
343
+ if (controller.signal.aborted)
344
+ throw new RegistrySnapshotError(`${where}: the registry did not finish its response within ${seconds}`);
345
+ throw new RegistrySnapshotError(`${where}: the registry's response could not be read`);
346
+ }
347
+ if (bytes === "too-large")
348
+ throw new RegistrySnapshotError(tooLarge);
349
+ return { status, bytes };
350
+ }
351
+ finally {
352
+ clearTimeout(timer);
353
+ }
354
+ }
355
+ function strictJsonReason(cause) {
356
+ if (!(cause instanceof ContractDocumentError))
357
+ return "is not strict JSON";
358
+ const where = cause.position === undefined ? "" : ` at position ${cause.position}`;
359
+ const why = cause.reason === "encoding" ? "is not valid UTF-8" : cause.reason === "repeated-key" ? "repeats a key in one object" : "is not valid JSON";
360
+ return `${why}${where}`;
361
+ }
362
+ let ownIdentity;
363
+ /** This package's own name and version, from the package.json it ships with. */
364
+ function launcherIdentity() {
365
+ if (ownIdentity === undefined) {
366
+ const manifest = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
367
+ if (typeof manifest.name !== "string" || typeof manifest.version !== "string")
368
+ throw new RegistrySnapshotError("this package's own package.json has no name and version");
369
+ ownIdentity = { name: manifest.name, version: manifest.version };
370
+ }
371
+ return ownIdentity;
372
+ }
373
+ /**
374
+ * Fetches every named package's full registry document, one at a time, and
375
+ * returns the snapshot in canonical order, validated against the contract.
376
+ * Throws RegistrySnapshotError, having fetched no further, on the first
377
+ * package whose read fails: a transport error, a timeout, a redirect, an
378
+ * answer other than 200 or 404, a body over MAX_RESPONSE_BYTES, a 200 body
379
+ * that is not strict JSON or not a registry document for that package, or a
380
+ * projection the contract refuses. A 404 records `status: "not-found"`.
381
+ * `names` must already have passed `requestedPackageNames()`.
382
+ */
383
+ export async function takeRegistrySnapshot(names, options = {}) {
384
+ const transport = options.transport ?? nodeFetchTransport;
385
+ const { registry } = PACKAGE_SCOPE;
386
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
387
+ const fetchedBy = options.fetchedBy ?? launcherIdentity();
388
+ const ordered = names.map((name, index) => ({ name, index })).sort((left, right) => byCodeUnits(left.name, right.name));
389
+ const packages = [];
390
+ for (const { name, index } of ordered) {
391
+ // The position only: the name itself is request text.
392
+ const where = `names[${index}]`;
393
+ const { status, bytes } = await fetchOne(transport, packumentUrl(registry, name), where, timeoutMs);
394
+ const responseSha256 = `sha256:${createHash("sha256").update(bytes).digest("hex")}`;
395
+ if (status === 404) {
396
+ packages.push({ name, status: "not-found", latest: null, versions: [], responseSha256 });
397
+ continue;
398
+ }
399
+ let document;
400
+ try {
401
+ document = readContractDocument(bytes);
402
+ }
403
+ catch (cause) {
404
+ throw new RegistrySnapshotError(`${where}: the registry's response ${strictJsonReason(cause)}`);
405
+ }
406
+ try {
407
+ packages.push({ name, status: "found", ...projectPackument(name, document), responseSha256 });
408
+ }
409
+ catch (cause) {
410
+ if (cause instanceof PackumentShapeError)
411
+ throw new RegistrySnapshotError(`${where}: the registry's document ${cause.message}`);
412
+ throw cause;
413
+ }
414
+ }
415
+ const snapshot = canonicalRegistrySnapshot({
416
+ schemaVersion: 1,
417
+ kind: "clossys.registry-snapshot",
418
+ registry,
419
+ fetchedAt: (options.now ?? (() => new Date().toISOString()))(),
420
+ fetchedBy: { name: fetchedBy.name, version: fetchedBy.version },
421
+ packages,
422
+ });
423
+ assertValidSnapshot(snapshot);
424
+ return snapshot;
425
+ }
426
+ function assertValidSnapshot(value) {
427
+ const violations = registrySnapshotViolations(value);
428
+ if (violations.length > 0) {
429
+ const listed = violations.map((violation) => `snapshot${violation.path === "" ? "" : violation.path.startsWith("[") ? violation.path : `.${violation.path}`} ${violation.message} (rule ${violation.rule})`);
430
+ throw new RegistrySnapshotError(`the snapshot does not validate against the registry snapshot contract, so none is written: ${listed.join("; ")}`);
431
+ }
432
+ }
433
+ /** The snapshot's file text: two-space JSON with a final newline, in the order given. */
434
+ export function serializeRegistrySnapshot(snapshot) {
435
+ return `${JSON.stringify(snapshot, null, 2)}\n`;
436
+ }
437
+ /**
438
+ * Writes `text` to `path` so that a reader sees the old file or the whole
439
+ * new one, never part of it: the bytes go to a new temporary file in the same
440
+ * directory, are flushed to disk, and the temporary file is then renamed over
441
+ * `path`. On any failure the temporary file is removed and `path` is left as
442
+ * it was.
443
+ */
444
+ export function writeFileAtomically(path, text) {
445
+ const directory = dirname(path);
446
+ mkdirSync(directory, { recursive: true });
447
+ const temporary = join(directory, `.${basename(path)}.${randomBytes(8).toString("hex")}.tmp`);
448
+ const bytes = Buffer.from(text, "utf8");
449
+ let descriptor;
450
+ try {
451
+ descriptor = openSync(temporary, "wx", 0o644);
452
+ let written = 0;
453
+ while (written < bytes.length)
454
+ written += writeSync(descriptor, bytes, written, bytes.length - written);
455
+ fsyncSync(descriptor);
456
+ closeSync(descriptor);
457
+ descriptor = undefined;
458
+ renameSync(temporary, path);
459
+ }
460
+ catch (cause) {
461
+ if (descriptor !== undefined) {
462
+ try {
463
+ closeSync(descriptor);
464
+ }
465
+ catch {
466
+ // Already failing; the original error is the one reported.
467
+ }
468
+ }
469
+ rmSync(temporary, { force: true });
470
+ throw cause;
471
+ }
472
+ }
473
+ /**
474
+ * Serializes a snapshot, re-reads that exact text strictly and validates it
475
+ * against the contract, and only then writes it atomically to `path`. The
476
+ * bytes on disk are therefore exactly the bytes that validated.
477
+ */
478
+ export function writeRegistrySnapshot(path, snapshot) {
479
+ const text = serializeRegistrySnapshot(snapshot);
480
+ assertValidSnapshot(readContractDocument(Buffer.from(text, "utf8")));
481
+ writeFileAtomically(path, text);
482
+ }
483
+ //# sourceMappingURL=registry-snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry-snapshot.js","sourceRoot":"","sources":["../src/registry-snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ import { type ExemptionSurfaceKind } from "./change-set-contract.js";
2
+ export type ReleaseAgeEditRefusalReason = "release-age-surface-unparseable" | "release-age-surface-conflict";
3
+ /** The outcome of editing: the new text, nothing to do, or a refusal that leaves the file alone. */
4
+ export type ReleaseAgeEdit = {
5
+ readonly kind: "edited";
6
+ readonly text: string;
7
+ } | {
8
+ readonly kind: "unchanged";
9
+ } | {
10
+ readonly kind: "refused";
11
+ readonly reason: ReleaseAgeEditRefusalReason;
12
+ };
13
+ export interface ReleaseAgeEditInput {
14
+ readonly surface: ExemptionSurfaceKind;
15
+ /** The surface file's text, or null when the file does not exist. */
16
+ readonly text: string | null;
17
+ /** The repository's .npmrc text (null or absent: none); read for the pnpm surface only. */
18
+ readonly npmrc?: string | null;
19
+ }
20
+ export interface ReleaseAgeVerifyInput {
21
+ readonly surface: ExemptionSurfaceKind;
22
+ readonly before: string | null;
23
+ readonly after: string;
24
+ readonly npmrc?: string | null;
25
+ }
26
+ /** Verified only when `after` is `before` plus exactly the one scope entry; `value` is the ledger entries row value. */
27
+ export type ReleaseAgeVerdict = {
28
+ readonly verified: true;
29
+ readonly value: string;
30
+ } | {
31
+ readonly verified: false;
32
+ };
33
+ /**
34
+ * Adds the scope entry to the surface's exemption list. A missing file or key
35
+ * is created or appended with a two-space list; an existing block sequence
36
+ * gains one line after its last item, in its own indent, and nothing else
37
+ * changes. An already-present entry is unchanged. Refuses a pnpm `.npmrc`
38
+ * that sets the same list (conflict) or has any line outside the fixed safe
39
+ * grammar (unparseable), and any file the restricted reader does not fully
40
+ * recognise (flow lists, comments inside the list, anchors, aliases, tags,
41
+ * block scalars, multiple documents, tabs, CRLF, repeated keys, and more).
42
+ */
43
+ export declare function editReleaseAgeExemption(input: ReleaseAgeEditInput): ReleaseAgeEdit;
44
+ /**
45
+ * Whether `after` is `before` plus exactly the one scope entry, judged by its
46
+ * own structural comparison of the two texts (and, as a second check, by the
47
+ * edit function reproducing `after`). The entry must sit after the last
48
+ * existing item, in the list's indent and the surface's quoting, with every
49
+ * other byte, including the final newline, unchanged.
50
+ */
51
+ export declare function verifyReleaseAgeExemption(input: ReleaseAgeVerifyInput): ReleaseAgeVerdict;
52
+ //# sourceMappingURL=release-age-edit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"release-age-edit.d.ts","sourceRoot":"","sources":["../src/release-age-edit.ts"],"names":[],"mappings":"AAUA,OAAO,EAAsB,KAAK,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAGzF,MAAM,MAAM,2BAA2B,GAAG,iCAAiC,GAAG,8BAA8B,CAAC;AAE7G,oGAAoG;AACpG,MAAM,MAAM,cAAc,GACtB;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClD;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAA;CAAE,GAC9B;IAAE,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,2BAA2B,CAAA;CAAE,CAAC;AAE/E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;IACvC,qEAAqE;IACrE,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,2FAA2F;IAC3F,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,OAAO,EAAE,oBAAoB,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,wHAAwH;AACxH,MAAM,MAAM,iBAAiB,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,QAAQ,CAAC,QAAQ,EAAE,KAAK,CAAA;CAAE,CAAC;AAmUnH;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,mBAAmB,GAAG,cAAc,CAkBlF;AAED;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,qBAAqB,GAAG,iBAAiB,CAgCzF"}