@forumulate/cli 0.8.0 → 0.10.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 (286) hide show
  1. package/README.md +11 -3
  2. package/dist/api/args.d.ts.map +1 -1
  3. package/dist/api/args.js +1 -0
  4. package/dist/api/args.js.map +1 -1
  5. package/dist/api/command.d.ts +1 -1
  6. package/dist/api/command.d.ts.map +1 -1
  7. package/dist/api/command.js +86 -11
  8. package/dist/api/command.js.map +1 -1
  9. package/dist/api/http.d.ts +8 -0
  10. package/dist/api/http.d.ts.map +1 -1
  11. package/dist/api/http.js +3 -2
  12. package/dist/api/http.js.map +1 -1
  13. package/dist/api/live-spec.d.ts +48 -0
  14. package/dist/api/live-spec.d.ts.map +1 -0
  15. package/dist/api/live-spec.js +72 -0
  16. package/dist/api/live-spec.js.map +1 -0
  17. package/dist/api/operations.json +1 -1
  18. package/dist/api/request.d.ts.map +1 -1
  19. package/dist/api/request.js +25 -1
  20. package/dist/api/request.js.map +1 -1
  21. package/dist/api/send.d.ts +10 -1
  22. package/dist/api/send.d.ts.map +1 -1
  23. package/dist/api/send.js +14 -3
  24. package/dist/api/send.js.map +1 -1
  25. package/dist/api/slim.d.ts +14 -0
  26. package/dist/api/slim.d.ts.map +1 -0
  27. package/dist/api/slim.js +174 -0
  28. package/dist/api/slim.js.map +1 -0
  29. package/dist/cache-command.d.ts +12 -0
  30. package/dist/cache-command.d.ts.map +1 -0
  31. package/dist/cache-command.js +93 -0
  32. package/dist/cache-command.js.map +1 -0
  33. package/dist/check/command.d.ts +48 -0
  34. package/dist/check/command.d.ts.map +1 -0
  35. package/dist/check/command.js +256 -0
  36. package/dist/check/command.js.map +1 -0
  37. package/dist/check/external.d.ts +66 -0
  38. package/dist/check/external.d.ts.map +1 -0
  39. package/dist/check/external.js +177 -0
  40. package/dist/check/external.js.map +1 -0
  41. package/dist/check/markdown-links.d.ts +38 -0
  42. package/dist/check/markdown-links.d.ts.map +1 -0
  43. package/dist/check/markdown-links.js +166 -0
  44. package/dist/check/markdown-links.js.map +1 -0
  45. package/dist/cli.js +42 -7
  46. package/dist/cli.js.map +1 -1
  47. package/dist/commands/completion.d.ts.map +1 -1
  48. package/dist/commands/completion.js +17 -0
  49. package/dist/commands/completion.js.map +1 -1
  50. package/dist/commands/context.d.ts.map +1 -1
  51. package/dist/commands/context.js +6 -2
  52. package/dist/commands/context.js.map +1 -1
  53. package/dist/commands/groups-api.d.ts.map +1 -1
  54. package/dist/commands/groups-api.js +20 -2
  55. package/dist/commands/groups-api.js.map +1 -1
  56. package/dist/commands/groups-docs.d.ts.map +1 -1
  57. package/dist/commands/groups-docs.js +8 -2
  58. package/dist/commands/groups-docs.js.map +1 -1
  59. package/dist/commands/groups-jobs.d.ts +10 -0
  60. package/dist/commands/groups-jobs.d.ts.map +1 -0
  61. package/dist/commands/groups-jobs.js +89 -0
  62. package/dist/commands/groups-jobs.js.map +1 -0
  63. package/dist/commands/groups-org.d.ts.map +1 -1
  64. package/dist/commands/groups-org.js +59 -2
  65. package/dist/commands/groups-org.js.map +1 -1
  66. package/dist/commands/groups-site.d.ts.map +1 -1
  67. package/dist/commands/groups-site.js +47 -10
  68. package/dist/commands/groups-site.js.map +1 -1
  69. package/dist/commands/groups-spaces.d.ts.map +1 -1
  70. package/dist/commands/groups-spaces.js +11 -5
  71. package/dist/commands/groups-spaces.js.map +1 -1
  72. package/dist/commands/groups-types.d.ts.map +1 -1
  73. package/dist/commands/groups-types.js +74 -0
  74. package/dist/commands/groups-types.js.map +1 -1
  75. package/dist/commands/groups.d.ts.map +1 -1
  76. package/dist/commands/groups.js +2 -0
  77. package/dist/commands/groups.js.map +1 -1
  78. package/dist/commands/index.d.ts +9 -0
  79. package/dist/commands/index.d.ts.map +1 -1
  80. package/dist/commands/index.js +18 -3
  81. package/dist/commands/index.js.map +1 -1
  82. package/dist/commands/job-wait.d.ts +64 -0
  83. package/dist/commands/job-wait.d.ts.map +1 -0
  84. package/dist/commands/job-wait.js +91 -0
  85. package/dist/commands/job-wait.js.map +1 -0
  86. package/dist/commands/resource.d.ts +19 -0
  87. package/dist/commands/resource.d.ts.map +1 -1
  88. package/dist/commands/resource.js +65 -3
  89. package/dist/commands/resource.js.map +1 -1
  90. package/dist/content/library.d.ts +8 -0
  91. package/dist/content/library.d.ts.map +1 -1
  92. package/dist/content/library.js +10 -2
  93. package/dist/content/library.js.map +1 -1
  94. package/dist/credentials.d.ts +43 -4
  95. package/dist/credentials.d.ts.map +1 -1
  96. package/dist/credentials.js +67 -4
  97. package/dist/credentials.js.map +1 -1
  98. package/dist/dev/command.d.ts +41 -0
  99. package/dist/dev/command.d.ts.map +1 -0
  100. package/dist/dev/command.js +158 -0
  101. package/dist/dev/command.js.map +1 -0
  102. package/dist/doctor/address-checks.d.ts +56 -0
  103. package/dist/doctor/address-checks.d.ts.map +1 -0
  104. package/dist/doctor/address-checks.js +183 -0
  105. package/dist/doctor/address-checks.js.map +1 -0
  106. package/dist/doctor/boilerplate.d.ts +33 -0
  107. package/dist/doctor/boilerplate.d.ts.map +1 -0
  108. package/dist/doctor/boilerplate.js +78 -0
  109. package/dist/doctor/boilerplate.js.map +1 -0
  110. package/dist/doctor/command.d.ts +18 -0
  111. package/dist/doctor/command.d.ts.map +1 -0
  112. package/dist/doctor/command.js +234 -0
  113. package/dist/doctor/command.js.map +1 -0
  114. package/dist/doctor/crawl.d.ts +49 -0
  115. package/dist/doctor/crawl.d.ts.map +1 -0
  116. package/dist/doctor/crawl.js +210 -0
  117. package/dist/doctor/crawl.js.map +1 -0
  118. package/dist/doctor/extended.d.ts +52 -0
  119. package/dist/doctor/extended.d.ts.map +1 -0
  120. package/dist/doctor/extended.js +150 -0
  121. package/dist/doctor/extended.js.map +1 -0
  122. package/dist/doctor/page-checks.d.ts +42 -0
  123. package/dist/doctor/page-checks.d.ts.map +1 -0
  124. package/dist/doctor/page-checks.js +200 -0
  125. package/dist/doctor/page-checks.js.map +1 -0
  126. package/dist/doctor/probe.d.ts +63 -0
  127. package/dist/doctor/probe.d.ts.map +1 -0
  128. package/dist/doctor/probe.js +170 -0
  129. package/dist/doctor/probe.js.map +1 -0
  130. package/dist/doctor/reader-auth-atlas.d.ts +18 -0
  131. package/dist/doctor/reader-auth-atlas.d.ts.map +1 -0
  132. package/dist/doctor/reader-auth-atlas.js +50 -0
  133. package/dist/doctor/reader-auth-atlas.js.map +1 -0
  134. package/dist/doctor/robots-params.d.ts +36 -0
  135. package/dist/doctor/robots-params.d.ts.map +1 -0
  136. package/dist/doctor/robots-params.js +97 -0
  137. package/dist/doctor/robots-params.js.map +1 -0
  138. package/dist/doctor/site.d.ts +42 -0
  139. package/dist/doctor/site.d.ts.map +1 -0
  140. package/dist/doctor/site.js +82 -0
  141. package/dist/doctor/site.js.map +1 -0
  142. package/dist/doctor.d.ts +21 -0
  143. package/dist/doctor.d.ts.map +1 -1
  144. package/dist/doctor.js +94 -3
  145. package/dist/doctor.js.map +1 -1
  146. package/dist/exit-codes.d.ts +40 -0
  147. package/dist/exit-codes.d.ts.map +1 -0
  148. package/dist/exit-codes.js +66 -0
  149. package/dist/exit-codes.js.map +1 -0
  150. package/dist/help-commands.d.ts +13 -0
  151. package/dist/help-commands.d.ts.map +1 -0
  152. package/dist/help-commands.js +215 -0
  153. package/dist/help-commands.js.map +1 -0
  154. package/dist/help.d.ts +1 -1
  155. package/dist/help.d.ts.map +1 -1
  156. package/dist/help.js +74 -11
  157. package/dist/help.js.map +1 -1
  158. package/dist/io.d.ts +33 -0
  159. package/dist/io.d.ts.map +1 -0
  160. package/dist/io.js +81 -0
  161. package/dist/io.js.map +1 -0
  162. package/dist/preview-comment.d.ts +20 -0
  163. package/dist/preview-comment.d.ts.map +1 -0
  164. package/dist/preview-comment.js +88 -0
  165. package/dist/preview-comment.js.map +1 -0
  166. package/dist/publish/about.d.ts +23 -0
  167. package/dist/publish/about.d.ts.map +1 -0
  168. package/dist/publish/about.js +66 -0
  169. package/dist/publish/about.js.map +1 -0
  170. package/dist/publish/api.d.ts +30 -12
  171. package/dist/publish/api.d.ts.map +1 -1
  172. package/dist/publish/api.js +62 -10
  173. package/dist/publish/api.js.map +1 -1
  174. package/dist/publish/client.d.ts +19 -0
  175. package/dist/publish/client.d.ts.map +1 -0
  176. package/dist/publish/client.js +3 -0
  177. package/dist/publish/client.js.map +1 -0
  178. package/dist/publish/command.d.ts +51 -2
  179. package/dist/publish/command.d.ts.map +1 -1
  180. package/dist/publish/command.js +157 -17
  181. package/dist/publish/command.js.map +1 -1
  182. package/dist/publish/context.d.ts +12 -1
  183. package/dist/publish/context.d.ts.map +1 -1
  184. package/dist/publish/context.js.map +1 -1
  185. package/dist/publish/diff.d.ts +21 -0
  186. package/dist/publish/diff.d.ts.map +1 -0
  187. package/dist/publish/diff.js +96 -0
  188. package/dist/publish/diff.js.map +1 -0
  189. package/dist/publish/docs-apply.d.ts +8 -1
  190. package/dist/publish/docs-apply.d.ts.map +1 -1
  191. package/dist/publish/docs-apply.js +49 -10
  192. package/dist/publish/docs-apply.js.map +1 -1
  193. package/dist/publish/docs-plan.d.ts +16 -3
  194. package/dist/publish/docs-plan.d.ts.map +1 -1
  195. package/dist/publish/docs-plan.js +57 -6
  196. package/dist/publish/docs-plan.js.map +1 -1
  197. package/dist/publish/extras.d.ts +10 -0
  198. package/dist/publish/extras.d.ts.map +1 -1
  199. package/dist/publish/extras.js +54 -2
  200. package/dist/publish/extras.js.map +1 -1
  201. package/dist/publish/frontmatter.d.ts +1 -1
  202. package/dist/publish/frontmatter.d.ts.map +1 -1
  203. package/dist/publish/frontmatter.js +1 -0
  204. package/dist/publish/frontmatter.js.map +1 -1
  205. package/dist/publish/index.d.ts +12 -0
  206. package/dist/publish/index.d.ts.map +1 -0
  207. package/dist/publish/index.js +17 -0
  208. package/dist/publish/index.js.map +1 -0
  209. package/dist/publish/manifest.d.ts.map +1 -1
  210. package/dist/publish/manifest.js +48 -3
  211. package/dist/publish/manifest.js.map +1 -1
  212. package/dist/publish/names.d.ts +28 -0
  213. package/dist/publish/names.d.ts.map +1 -0
  214. package/dist/publish/names.js +80 -0
  215. package/dist/publish/names.js.map +1 -0
  216. package/dist/publish/posts.d.ts.map +1 -1
  217. package/dist/publish/posts.js +46 -13
  218. package/dist/publish/posts.js.map +1 -1
  219. package/dist/publish/preview.d.ts +56 -0
  220. package/dist/publish/preview.d.ts.map +1 -0
  221. package/dist/publish/preview.js +133 -0
  222. package/dist/publish/preview.js.map +1 -0
  223. package/dist/publish/redirects.d.ts +13 -0
  224. package/dist/publish/redirects.d.ts.map +1 -0
  225. package/dist/publish/redirects.js +154 -0
  226. package/dist/publish/redirects.js.map +1 -0
  227. package/dist/publish/reserved.d.ts +49 -0
  228. package/dist/publish/reserved.d.ts.map +1 -0
  229. package/dist/publish/reserved.js +118 -0
  230. package/dist/publish/reserved.js.map +1 -0
  231. package/dist/publish/rewrite.d.ts +12 -0
  232. package/dist/publish/rewrite.d.ts.map +1 -1
  233. package/dist/publish/rewrite.js +22 -0
  234. package/dist/publish/rewrite.js.map +1 -1
  235. package/dist/publish/scan-docs.d.ts +10 -0
  236. package/dist/publish/scan-docs.d.ts.map +1 -0
  237. package/dist/publish/scan-docs.js +160 -0
  238. package/dist/publish/scan-docs.js.map +1 -0
  239. package/dist/publish/scan.d.ts +21 -17
  240. package/dist/publish/scan.d.ts.map +1 -1
  241. package/dist/publish/scan.js +99 -232
  242. package/dist/publish/scan.js.map +1 -1
  243. package/dist/publish/slots.d.ts +39 -0
  244. package/dist/publish/slots.d.ts.map +1 -0
  245. package/dist/publish/slots.js +64 -0
  246. package/dist/publish/slots.js.map +1 -0
  247. package/dist/publish/studio-edits.d.ts +25 -0
  248. package/dist/publish/studio-edits.d.ts.map +1 -0
  249. package/dist/publish/studio-edits.js +53 -0
  250. package/dist/publish/studio-edits.js.map +1 -0
  251. package/dist/publish/tags.d.ts +9 -0
  252. package/dist/publish/tags.d.ts.map +1 -0
  253. package/dist/publish/tags.js +194 -0
  254. package/dist/publish/tags.js.map +1 -0
  255. package/dist/publish/types.d.ts +84 -1
  256. package/dist/publish/types.d.ts.map +1 -1
  257. package/dist/publish/types.js +0 -10
  258. package/dist/publish/types.js.map +1 -1
  259. package/dist/publish-command.d.ts +55 -0
  260. package/dist/publish-command.d.ts.map +1 -0
  261. package/dist/publish-command.js +197 -0
  262. package/dist/publish-command.js.map +1 -0
  263. package/dist/run.d.ts +3 -10
  264. package/dist/run.d.ts.map +1 -1
  265. package/dist/run.js +171 -112
  266. package/dist/run.js.map +1 -1
  267. package/dist/translations/target.d.ts.map +1 -1
  268. package/dist/translations/target.js +2 -2
  269. package/dist/translations/target.js.map +1 -1
  270. package/dist/validate.d.ts +39 -0
  271. package/dist/validate.d.ts.map +1 -0
  272. package/dist/validate.js +166 -0
  273. package/dist/validate.js.map +1 -0
  274. package/dist/version.d.ts +8 -0
  275. package/dist/version.d.ts.map +1 -0
  276. package/dist/version.js +11 -0
  277. package/dist/version.js.map +1 -0
  278. package/dist/whoami.d.ts +41 -0
  279. package/dist/whoami.d.ts.map +1 -0
  280. package/dist/whoami.js +161 -0
  281. package/dist/whoami.js.map +1 -0
  282. package/package.json +2 -2
  283. package/dist/publish-dir.d.ts +0 -54
  284. package/dist/publish-dir.d.ts.map +0 -1
  285. package/dist/publish-dir.js +0 -119
  286. package/dist/publish-dir.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address-checks.js","sourceRoot":"","sources":["../../src/doctor/address-checks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Descriptions that were written by a template, not by the site's owner.
3
+ *
4
+ * A space with no description of its own fell back to the preset's blurb —
5
+ * "Guides and reference, in a nested tree.", "Community discussions in
6
+ * Community." — and that sentence became the meta description, the og:description
7
+ * a link preview shows, and the summary line of llms.txt (FMU-B08). Nothing was
8
+ * broken in the HTTP sense, so no check noticed; a reader sharing a link noticed.
9
+ *
10
+ * One list, in one place, so `meta-description` and `llms-txt` judge the same
11
+ * strings. Patterns rather than exact strings: the template interpolates the
12
+ * space or site name, and the point is to recognise the template whatever was
13
+ * poured into it. They are generic generator phrasings — any docs platform
14
+ * that fills an empty description from a type preset produces sentences of this
15
+ * shape — not a list of one vendor's copy.
16
+ */
17
+ export declare const PRESET_DESCRIPTION_PATTERNS: readonly RegExp[];
18
+ export declare function isPresetDescription(text: string): boolean;
19
+ /**
20
+ * True when a description is headings run together rather than prose.
21
+ *
22
+ * A generated reference landing described itself as its tag names joined with
23
+ * spaces — "Referalli API Analytics and operations Billing Authentication
24
+ * Programs and partners Partner portal Payouts…" (FMU-B09). It has words, so
25
+ * "missing" never fires; it has no sentence in it, which is what this tests:
26
+ * eight words or more, no sentence punctuation at all, and most of the
27
+ * non-trivial words capitalised. A run of CamelCase joins (`PayoutsPartners`)
28
+ * counts too — that is the same list with the spaces lost.
29
+ */
30
+ export declare function isHeadingSoup(text: string): boolean;
31
+ /** Why a description is not one, or undefined when it reads like one somebody wrote. */
32
+ export declare function descriptionProblem(text: string | undefined): string | undefined;
33
+ //# sourceMappingURL=boilerplate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boilerplate.d.ts","sourceRoot":"","sources":["../../src/doctor/boilerplate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,2BAA2B,EAAE,SAAS,MAAM,EAUxD,CAAC;AAEF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGzD;AAKD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAUnD;AAED,wFAAwF;AACxF,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAM/E"}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.PRESET_DESCRIPTION_PATTERNS = void 0;
4
+ exports.isPresetDescription = isPresetDescription;
5
+ exports.isHeadingSoup = isHeadingSoup;
6
+ exports.descriptionProblem = descriptionProblem;
7
+ /**
8
+ * Descriptions that were written by a template, not by the site's owner.
9
+ *
10
+ * A space with no description of its own fell back to the preset's blurb —
11
+ * "Guides and reference, in a nested tree.", "Community discussions in
12
+ * Community." — and that sentence became the meta description, the og:description
13
+ * a link preview shows, and the summary line of llms.txt (FMU-B08). Nothing was
14
+ * broken in the HTTP sense, so no check noticed; a reader sharing a link noticed.
15
+ *
16
+ * One list, in one place, so `meta-description` and `llms-txt` judge the same
17
+ * strings. Patterns rather than exact strings: the template interpolates the
18
+ * space or site name, and the point is to recognise the template whatever was
19
+ * poured into it. They are generic generator phrasings — any docs platform
20
+ * that fills an empty description from a type preset produces sentences of this
21
+ * shape — not a list of one vendor's copy.
22
+ */
23
+ exports.PRESET_DESCRIPTION_PATTERNS = [
24
+ /^guides and reference, in a nested tree\.?$/i,
25
+ /^community discussions in .+\.?$/i,
26
+ /^the latest posts from .+\.?$/i,
27
+ /^published documentation for .+\.?$/i,
28
+ /^documentation for .+\.?$/i,
29
+ /^welcome to .+ (?:docs|documentation)\.?$/i,
30
+ // A not-found page's title used as a description: the address in the
31
+ // sitemap or llms.txt is dead, and the preview says so to everybody.
32
+ /this page isn[’']t here/i,
33
+ ];
34
+ function isPresetDescription(text) {
35
+ const t = text.trim();
36
+ return exports.PRESET_DESCRIPTION_PATTERNS.some((re) => re.test(t));
37
+ }
38
+ /** Small words a real sentence has and a list of headings also has. */
39
+ const STOP = new Set(['and', 'or', 'the', 'of', 'a', 'an', 'to', 'in', 'for', 'with', 'on', '&']);
40
+ /**
41
+ * True when a description is headings run together rather than prose.
42
+ *
43
+ * A generated reference landing described itself as its tag names joined with
44
+ * spaces — "Referalli API Analytics and operations Billing Authentication
45
+ * Programs and partners Partner portal Payouts…" (FMU-B09). It has words, so
46
+ * "missing" never fires; it has no sentence in it, which is what this tests:
47
+ * eight words or more, no sentence punctuation at all, and most of the
48
+ * non-trivial words capitalised. A run of CamelCase joins (`PayoutsPartners`)
49
+ * counts too — that is the same list with the spaces lost.
50
+ */
51
+ function isHeadingSoup(text) {
52
+ const t = text.replace(/(?:…|\.\.\.)\s*$/, '').trim();
53
+ if ((t.match(/[a-z][A-Z][a-z]/g) ?? []).length >= 2 && !/[.,;:!?]/.test(t))
54
+ return true;
55
+ if (/[.,;:!?—–()]/.test(t))
56
+ return false;
57
+ const words = t.split(/\s+/).filter(Boolean);
58
+ if (words.length < 8)
59
+ return false;
60
+ const content = words.filter((w) => !STOP.has(w.toLowerCase()));
61
+ if (content.length === 0)
62
+ return false;
63
+ const capped = content.filter((w) => /^[A-Z0-9]/.test(w)).length;
64
+ return capped / content.length >= 0.5;
65
+ }
66
+ /** Why a description is not one, or undefined when it reads like one somebody wrote. */
67
+ function descriptionProblem(text) {
68
+ if (text === undefined)
69
+ return 'missing';
70
+ if (!text.trim())
71
+ return 'empty';
72
+ if (isPresetDescription(text))
73
+ return `preset text "${text.trim()}"`;
74
+ if (isHeadingSoup(text))
75
+ return `headings run together "${text.trim().slice(0, 80)}…"`;
76
+ return undefined;
77
+ }
78
+ //# sourceMappingURL=boilerplate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boilerplate.js","sourceRoot":"","sources":["../../src/doctor/boilerplate.ts"],"names":[],"mappings":";;;AA4BA,kDAGC;AAgBD,sCAUC;AAGD,gDAMC;AAlED;;;;;;;;;;;;;;;GAeG;AACU,QAAA,2BAA2B,GAAsB;IAC5D,8CAA8C;IAC9C,mCAAmC;IACnC,gCAAgC;IAChC,sCAAsC;IACtC,4BAA4B;IAC5B,4CAA4C;IAC5C,qEAAqE;IACrE,qEAAqE;IACrE,0BAA0B;CAC3B,CAAC;AAEF,SAAgB,mBAAmB,CAAC,IAAY;IAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IACtB,OAAO,mCAA2B,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,uEAAuE;AACvE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;AAElG;;;;;;;;;;GAUG;AACH,SAAgB,aAAa,CAAC,IAAY;IACxC,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACtD,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,IAAI,CAAC;IACxF,IAAI,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;QAAE,OAAO,KAAK,CAAC;IACzC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7C,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IACnC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC;IAChE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IACvC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;IACjE,OAAO,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC;AACxC,CAAC;AAED,wFAAwF;AACxF,SAAgB,kBAAkB,CAAC,IAAwB;IACzD,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACzC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QAAE,OAAO,OAAO,CAAC;IACjC,IAAI,mBAAmB,CAAC,IAAI,CAAC;QAAE,OAAO,gBAAgB,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC;IACrE,IAAI,aAAa,CAAC,IAAI,CAAC;QAAE,OAAO,0BAA0B,IAAI,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC;IACvF,OAAO,SAAS,CAAC;AACnB,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { Http } from '../api/http';
2
+ import { type DoctorReport } from '../doctor';
3
+ export declare const DOCTOR_CHECK_IDS: readonly string[];
4
+ export declare const DOCTOR_HELP = "forumulate doctor \u2014 check a live site from the outside\n\nUsage:\n forumulate doctor <readerUrl> [flags]\n forumulate doctor --site <slug|id> [--org <slug|id>] [flags]\n\nPlain HTTP, no token needed for a URL: the same report against our platform, a\nstaging mount or any other docs host. --site asks the API for every address of\nevery space on a site (needs a token), and checks each copy.\n\nFlags:\n --site <slug|id> every member space, at its custom domain AND its\n platform copy (token: FORUMULATE_TOKEN or `login`)\n --org <slug|id> the org --site is in (default: FORUMULATE_ORG / config)\n --also <url> another address of the same page, e.g. the platform copy\n of a custom-domain page (repeatable)\n --only a,b run just these checks (ids below)\n --json the full report as JSON on stdout (nothing else there)\n --api-base <origin> where /api/health lives, when not on the page's host\n --platform-host <h> the hosting platform's hostname, for white-label and\n canonical checks (default: FORUMULATE_URL's host, else\n forumulate.com)\n --limit <n> sitemap URLs to sample (default 60)\n --timeout <ms> per-request timeout (default 15000)\n\nChecks (id \u2014 what fails it):\n health /api/health not 2xx JSON (also tried under the mount)\n public-read a logged-out reader is sent to sign-in\n canonical the page's canonical names another host\n html-untouched a proxy rewrites the markup (email obfuscation)\n cache-headers no Cache-Control, or no-store, on the page\n robots / sitemap robots.txt missing, disallows the path, no Sitemap:\n crawler-access a crawler gets a different status than a reader\n feeds an advertised feed does not answer 200\n images a picture on the page does not load\n canonical-both-addresses a page's copies (custom domain, platform) name\n different canonicals, or not the primary address\n sitemap-crawl a sitemap URL redirects, 404s, is on another host or\n names another canonical\n cache-consistency pages of one space cached differently (public vs\n private/no-store) with no x-forumulate-cache-reason\n root-redirect a space root answers 302/307, or a redirect with a\n body over 1 KB, or lands on a page canonical elsewhere\n meta-description missing description/og:description, template text\n (\"Guides and reference, in a nested tree.\"), or\n headings run together\n llms-txt /llms.txt missing, no H1, preset summary, links on\n another host, slugs in titles, no sections/descriptions\n favicon /favicon.ico or <link rel=icon> not an image; an\n asset path answering a large HTML page\n consent-tag a consent manager (any CMP: Cookie Munch, Cookiebot,\n OneTrust, Osano, Termly, Usercentrics, Didomi,\n iubenda, Complianz, TCF) not told the page language\n white-label-leaks a custom-domain page or its .md twin links to the\n platform host\n robots-params (advice) prints the Disallow lines that keep crawlers\n off each mount's ?sort= / ?period= / ?range= copies\n reader-auth-atlas (advice, needs --org and a token) the organization\n uses Atlas but signs readers in another way (an\n external_jwt route): prints the relink and the switch\n to the Atlas reader provider (readerAuth: atlas)\n\nExamples:\n forumulate doctor https://docs.acme.com/docs\n forumulate doctor https://acme.com/legal/privacy --also https://forumulate.com/p/acme/legal/privacy\n forumulate doctor --site main --org acme --json > doctor.json\n forumulate doctor https://acme.com/docs --only sitemap-crawl,root-redirect\n\nIn CI: packages/cli/examples/github-action-doctor.yml runs this on a schedule and\non every push, uploads the JSON report and fails the job on any FAIL.\n\nExit status:\n 0 ok 1 failed (verification mismatch, doctor FAIL)\n 2 usage 3 auth (no token, 401, token not allowed)\n 4 not found 5 conflict (409/412, edited in the studio since your last publish)\n 124 --wait timed out (the job keeps running; with --wait, a failed job is 1)\n doctor: 1 when any check FAILs; a SKIP is not a failure.";
5
+ export interface DoctorCommandDeps {
6
+ out: (line: string) => void;
7
+ err: (line: string) => void;
8
+ env?: NodeJS.ProcessEnv;
9
+ fetchImpl?: typeof fetch;
10
+ http?: Http;
11
+ userAgent?: string;
12
+ /** The global `--token` (FMU-DOC01); beats FORUMULATE_TOKEN and the stored token. */
13
+ flagToken?: string;
14
+ }
15
+ /** `forumulate doctor …` → an exit code. */
16
+ export declare function runDoctorCommand(argv: string[], deps: DoctorCommandDeps): Promise<number>;
17
+ export declare function printReport(report: DoctorReport, out: (l: string) => void): void;
18
+ //# sourceMappingURL=command.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.d.ts","sourceRoot":"","sources":["../../src/doctor/command.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAC;AAKnC,OAAO,EAA6B,KAAK,YAAY,EAAE,MAAM,WAAW,CAAC;AAOzE,eAAO,MAAM,gBAAgB,EAAE,SAAS,MAAM,EAI7C,CAAC;AAEF,eAAO,MAAM,WAAW,gtJAwEmC,CAAC;AAE5D,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID,4CAA4C;AAC5C,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,CA4H/F;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,YAAY,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAUhF"}
@@ -0,0 +1,234 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DOCTOR_HELP = exports.DOCTOR_CHECK_IDS = void 0;
4
+ exports.runDoctorCommand = runDoctorCommand;
5
+ exports.printReport = printReport;
6
+ const args_1 = require("../api/args");
7
+ const http_1 = require("../api/http");
8
+ const api_base_1 = require("../api-base");
9
+ const config_1 = require("../commands/config");
10
+ const credentials_1 = require("../credentials");
11
+ const exit_codes_1 = require("../exit-codes");
12
+ const doctor_1 = require("../doctor");
13
+ const extended_1 = require("./extended");
14
+ const site_1 = require("./site");
15
+ const probe_1 = require("./probe");
16
+ const reader_auth_atlas_1 = require("./reader-auth-atlas");
17
+ exports.DOCTOR_CHECK_IDS = [
18
+ ...doctor_1.BASE_CHECK_IDS,
19
+ ...extended_1.EXTENDED_CHECK_IDS,
20
+ reader_auth_atlas_1.READER_AUTH_ATLAS_CHECK,
21
+ ];
22
+ exports.DOCTOR_HELP = `forumulate doctor — check a live site from the outside
23
+
24
+ Usage:
25
+ forumulate doctor <readerUrl> [flags]
26
+ forumulate doctor --site <slug|id> [--org <slug|id>] [flags]
27
+
28
+ Plain HTTP, no token needed for a URL: the same report against our platform, a
29
+ staging mount or any other docs host. --site asks the API for every address of
30
+ every space on a site (needs a token), and checks each copy.
31
+
32
+ Flags:
33
+ --site <slug|id> every member space, at its custom domain AND its
34
+ platform copy (token: FORUMULATE_TOKEN or \`login\`)
35
+ --org <slug|id> the org --site is in (default: FORUMULATE_ORG / config)
36
+ --also <url> another address of the same page, e.g. the platform copy
37
+ of a custom-domain page (repeatable)
38
+ --only a,b run just these checks (ids below)
39
+ --json the full report as JSON on stdout (nothing else there)
40
+ --api-base <origin> where /api/health lives, when not on the page's host
41
+ --platform-host <h> the hosting platform's hostname, for white-label and
42
+ canonical checks (default: FORUMULATE_URL's host, else
43
+ ${extended_1.DEFAULT_PLATFORM_HOST})
44
+ --limit <n> sitemap URLs to sample (default ${extended_1.DEFAULT_SAMPLE_LIMIT})
45
+ --timeout <ms> per-request timeout (default 15000)
46
+
47
+ Checks (id — what fails it):
48
+ health /api/health not 2xx JSON (also tried under the mount)
49
+ public-read a logged-out reader is sent to sign-in
50
+ canonical the page's canonical names another host
51
+ html-untouched a proxy rewrites the markup (email obfuscation)
52
+ cache-headers no Cache-Control, or no-store, on the page
53
+ robots / sitemap robots.txt missing, disallows the path, no Sitemap:
54
+ crawler-access a crawler gets a different status than a reader
55
+ feeds an advertised feed does not answer 200
56
+ images a picture on the page does not load
57
+ canonical-both-addresses a page's copies (custom domain, platform) name
58
+ different canonicals, or not the primary address
59
+ sitemap-crawl a sitemap URL redirects, 404s, is on another host or
60
+ names another canonical
61
+ cache-consistency pages of one space cached differently (public vs
62
+ private/no-store) with no x-forumulate-cache-reason
63
+ root-redirect a space root answers 302/307, or a redirect with a
64
+ body over 1 KB, or lands on a page canonical elsewhere
65
+ meta-description missing description/og:description, template text
66
+ ("Guides and reference, in a nested tree."), or
67
+ headings run together
68
+ llms-txt /llms.txt missing, no H1, preset summary, links on
69
+ another host, slugs in titles, no sections/descriptions
70
+ favicon /favicon.ico or <link rel=icon> not an image; an
71
+ asset path answering a large HTML page
72
+ consent-tag a consent manager (any CMP: Cookie Munch, Cookiebot,
73
+ OneTrust, Osano, Termly, Usercentrics, Didomi,
74
+ iubenda, Complianz, TCF) not told the page language
75
+ white-label-leaks a custom-domain page or its .md twin links to the
76
+ platform host
77
+ robots-params (advice) prints the Disallow lines that keep crawlers
78
+ off each mount's ?sort= / ?period= / ?range= copies
79
+ reader-auth-atlas (advice, needs --org and a token) the organization
80
+ uses Atlas but signs readers in another way (an
81
+ external_jwt route): prints the relink and the switch
82
+ to the Atlas reader provider (readerAuth: atlas)
83
+
84
+ Examples:
85
+ forumulate doctor https://docs.acme.com/docs
86
+ forumulate doctor https://acme.com/legal/privacy --also https://forumulate.com/p/acme/legal/privacy
87
+ forumulate doctor --site main --org acme --json > doctor.json
88
+ forumulate doctor https://acme.com/docs --only sitemap-crawl,root-redirect
89
+
90
+ In CI: packages/cli/examples/github-action-doctor.yml runs this on a schedule and
91
+ on every push, uploads the JSON report and fails the job on any FAIL.
92
+
93
+ ${exit_codes_1.EXIT_CODES_HELP}
94
+ doctor: 1 when any check FAILs; a SKIP is not a failure.`;
95
+ const SWITCHES = new Set(['json', 'help', 'h']);
96
+ /** `forumulate doctor …` → an exit code. */
97
+ async function runDoctorCommand(argv, deps) {
98
+ const p = (0, args_1.parseArgs)(argv, SWITCHES);
99
+ if ((0, args_1.has)(p, 'help') || (0, args_1.has)(p, 'h')) {
100
+ deps.out(exports.DOCTOR_HELP);
101
+ return exit_codes_1.EXIT.OK;
102
+ }
103
+ const env = deps.env ?? process.env;
104
+ const json = (0, args_1.has)(p, 'json');
105
+ const usage = (why) => {
106
+ deps.err(why);
107
+ deps.err('Usage: forumulate doctor <readerUrl> | --site <slug|id> [--org …] (doctor --help)');
108
+ return exit_codes_1.EXIT.USAGE;
109
+ };
110
+ const only = (0, args_1.all)(p, 'only')
111
+ .flatMap((v) => v.split(','))
112
+ .map((v) => v.trim())
113
+ .filter(Boolean);
114
+ const unknown = only.filter((id) => !exports.DOCTOR_CHECK_IDS.includes(id));
115
+ if (unknown.length)
116
+ return usage(`Unknown check id(s): ${unknown.join(', ')}. Known: ${exports.DOCTOR_CHECK_IDS.join(', ')}.`);
117
+ const limit = (0, args_1.flag)(p, 'limit') === undefined ? undefined : Number((0, args_1.flag)(p, 'limit'));
118
+ if (limit !== undefined && !(Number.isInteger(limit) && limit > 0))
119
+ return usage('--limit takes a positive whole number.');
120
+ const timeout = (0, args_1.flag)(p, 'timeout') === undefined ? undefined : Number((0, args_1.flag)(p, 'timeout'));
121
+ if (timeout !== undefined && !(Number.isInteger(timeout) && timeout > 0))
122
+ return usage('--timeout takes a positive number of milliseconds.');
123
+ let url = p.positionals[0];
124
+ if (p.positionals.length > 1)
125
+ return usage(`One URL at a time; got ${p.positionals.join(' ')}.`);
126
+ if (url !== undefined) {
127
+ try {
128
+ const parsed = new URL(url);
129
+ if (!/^https?:$/.test(parsed.protocol))
130
+ throw new Error('not http');
131
+ }
132
+ catch {
133
+ return usage(`"${url}" is not an http(s) URL.`);
134
+ }
135
+ }
136
+ const siteUrl = (0, api_base_1.siteFromEnv)(env);
137
+ const platformHost = ((0, args_1.flag)(p, 'platform-host') ??
138
+ (siteUrl ? new URL(siteUrl).host : undefined) ??
139
+ extended_1.DEFAULT_PLATFORM_HOST).toLowerCase();
140
+ const fetchImpl = deps.fetchImpl ?? fetch;
141
+ const addressSets = [];
142
+ let roots;
143
+ const site = (0, args_1.flag)(p, 'site');
144
+ // The organization's own checks (reader-auth-atlas) need an org and a token;
145
+ // `--site` needs both anyway.
146
+ const orgFlag = (0, args_1.flag)(p, 'org');
147
+ const orgRef = site || orgFlag ? (0, config_1.setting)('org', orgFlag, env, (0, config_1.readConfig)(env)) : undefined;
148
+ const apiHttp = () => {
149
+ const baseUrl = (0, api_base_1.apiBaseFromEnv)(env);
150
+ return (deps.http ??
151
+ new http_1.Http({
152
+ baseUrl,
153
+ token: (0, credentials_1.resolveToken)(baseUrl, env, deps.flagToken),
154
+ userAgent: deps.userAgent ?? '@forumulate/cli',
155
+ fetch: fetchImpl,
156
+ }));
157
+ };
158
+ if (site) {
159
+ const org = orgRef;
160
+ if (!org)
161
+ return usage('--site needs --org <slug|id> (or FORUMULATE_ORG, or `config set org`).');
162
+ const http = apiHttp();
163
+ try {
164
+ const resolved = await (0, site_1.resolveSite)(http, org, site);
165
+ for (const problem of resolved.problems)
166
+ deps.err(`note: ${problem}`);
167
+ if (!url)
168
+ url = resolved.url;
169
+ if (!url) {
170
+ deps.err(`Site ${site} has no space with a public address to check.`);
171
+ return exit_codes_1.EXIT.NOT_FOUND;
172
+ }
173
+ roots = resolved.spaces.flatMap((s) => s.endpoints.map((e) => e.url.replace(/\/+$/, '')));
174
+ const get = (0, probe_1.makeGet)({ fetchImpl, timeoutMs: timeout });
175
+ addressSets.push(...(await (0, site_1.addressSetsFor)(get, resolved)));
176
+ }
177
+ catch (e) {
178
+ const err = e;
179
+ deps.err(`Could not read site ${site}: ${err.message ?? String(e)}`);
180
+ return (0, exit_codes_1.exitCodeForError)(e);
181
+ }
182
+ }
183
+ if (!url)
184
+ return usage('Give a reader URL, or --site <slug|id>.');
185
+ const also = (0, args_1.all)(p, 'also');
186
+ if (also.length)
187
+ addressSets.push({ urls: [url, ...also] });
188
+ const report = await (0, doctor_1.runDoctor)({
189
+ url,
190
+ apiBase: (0, args_1.flag)(p, 'api-base') ?? siteUrl,
191
+ fetchImpl,
192
+ only: only.length ? only : undefined,
193
+ platformHost,
194
+ // The platform the copies are compared against: the configured API when
195
+ // one is, else the API of whichever host --platform-host named.
196
+ platformApi: env.FORUMULATE_API_URL?.trim() || env.FORUMULATE_URL?.trim()
197
+ ? (0, api_base_1.apiBaseFromEnv)(env)
198
+ : `https://${platformHost}/api`,
199
+ addressSets: addressSets.length ? addressSets : undefined,
200
+ roots,
201
+ limit,
202
+ timeoutMs: timeout,
203
+ });
204
+ // FMU-X01: the organization's reader sign-in, from the API's own recommendation.
205
+ if (orgRef && (!only.length || only.includes(reader_auth_atlas_1.READER_AUTH_ATLAS_CHECK))) {
206
+ const c = await (0, reader_auth_atlas_1.readerAuthAtlasCheck)(apiHttp(), orgRef);
207
+ report.checks.push(c);
208
+ if (c.state === 'pass')
209
+ report.passed += 1;
210
+ else if (c.state === 'fail')
211
+ report.failed += 1;
212
+ else
213
+ report.warnings += 1;
214
+ }
215
+ if (json)
216
+ deps.out(JSON.stringify(report, null, 2));
217
+ else
218
+ printReport(report, deps.out);
219
+ return report.failed > 0 ? exit_codes_1.EXIT.FAILED : exit_codes_1.EXIT.OK;
220
+ }
221
+ function printReport(report, out) {
222
+ out(`Checking ${report.url}`);
223
+ for (const c of report.checks) {
224
+ const mark = c.state === 'pass' ? 'PASS' : c.state === 'fail' ? 'FAIL' : 'SKIP';
225
+ out(` ${mark} ${c.id} ${c.title}`);
226
+ // A detail may be several lines (robots-params prints a robots.txt block).
227
+ for (const line of c.detail.split('\n'))
228
+ out(` ${line}`);
229
+ if (c.state === 'fail' && c.matters)
230
+ out(` why it matters: ${c.matters}`);
231
+ }
232
+ out(`${report.passed} passed, ${report.failed} failed, ${report.warnings} skipped`);
233
+ }
234
+ //# sourceMappingURL=command.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"command.js","sourceRoot":"","sources":["../../src/doctor/command.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import type { Check } from '../conformance';
2
+ import { type Get, type Probe } from './probe';
3
+ export interface CrawlResult {
4
+ check: Check;
5
+ /** Every listed URL that was fetched, with its answer. */
6
+ pages: Probe[];
7
+ }
8
+ /** `Sitemap:` lines of robots.txt, else the conventional address. */
9
+ export declare function sitemapsFromRobots(robots: string, origin: string): string[];
10
+ /**
11
+ * Read sitemaps (following a sitemap index), returning the URL lists per
12
+ * document, so the sample can draw from every space rather than exhaust the
13
+ * first one: a site with a 900-page reference and a 4-page legal space would
14
+ * otherwise never have its legal pages looked at.
15
+ */
16
+ export declare function readSitemaps(get: Get, start: string[]): Promise<{
17
+ lists: {
18
+ sitemap: string;
19
+ urls: string[];
20
+ }[];
21
+ problems: string[];
22
+ }>;
23
+ /** Up to `limit` URLs, round-robin across the sitemaps so every space is represented. */
24
+ export declare function sample(lists: {
25
+ urls: string[];
26
+ }[], limit: number): string[];
27
+ export declare function sitemapCrawl(get: Get, origin: string, robots: string | undefined, limit: number): Promise<CrawlResult>;
28
+ /**
29
+ * The space a URL belongs to, for grouping: its first path segment, which is
30
+ * where a path-mounted space lives (`/docs`, `/legal`). Pages at the root of a
31
+ * site domain group together under `/`. Coarse, and that is fine — a
32
+ * difference between two spaces is a choice; a difference inside one is what
33
+ * this is looking for.
34
+ */
35
+ export declare function groupOf(url: string): string;
36
+ /** `public` (a shared cache may keep it) or `private` (it may not), by the directives that decide it. */
37
+ export declare function cacheClass(cc: string | null): 'public' | 'private' | 'none';
38
+ /**
39
+ * `cache-consistency`: the pages of one space are cached the same way.
40
+ *
41
+ * Every legal document answered `private, no-cache, no-store` to a reader with
42
+ * no cookie at all, while the legal index beside it was `public, s-maxage=10`
43
+ * (FMU-B05). Neither header is wrong on its own; the difference is the defect —
44
+ * either something is gated and should say so, or a code path forgot the
45
+ * public header and every reader pays a full origin render. A page that sends
46
+ * a reason header is taken at its word.
47
+ */
48
+ export declare function cacheConsistency(pages: Probe[]): Check;
49
+ //# sourceMappingURL=crawl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crawl.d.ts","sourceRoot":"","sources":["../../src/doctor/crawl.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAQL,KAAK,GAAG,EACR,KAAK,KAAK,EACX,MAAM,SAAS,CAAC;AAmBjB,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,KAAK,CAAC;IACb,0DAA0D;IAC1D,KAAK,EAAE,KAAK,EAAE,CAAC;CAChB;AAED,qEAAqE;AACrE,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAG3E;AAQD;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,MAAM,EAAE,GACd,OAAO,CAAC;IAAE,KAAK,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,EAAE,CAAA;KAAE,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAAC,CAkB/E;AAED,yFAAyF;AACzF,wBAAgB,MAAM,CAAC,KAAK,EAAE;IAAE,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,EAAE,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAkB3E;AAED,wBAAsB,YAAY,CAChC,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,KAAK,EAAE,MAAM,GACZ,OAAO,CAAC,WAAW,CAAC,CAuDtB;AAED;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAY3C;AAED,yGAAyG;AACzG,wBAAgB,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,GAAG,QAAQ,GAAG,SAAS,GAAG,MAAM,CAK3E;AAKD;;;;;;;;;GASG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,KAAK,CA0CtD"}