@nebulacomponents/citable 0.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 (586) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/LICENSE +201 -0
  3. package/README.md +150 -0
  4. package/cli/bin/citable.js +5 -0
  5. package/dist/universal/.agents/skills/citable/SKILL.md +137 -0
  6. package/dist/universal/.agents/skills/citable/VERSION +1 -0
  7. package/dist/universal/.agents/skills/citable/commands/README.md +36 -0
  8. package/dist/universal/.agents/skills/citable/commands/ingest.md +44 -0
  9. package/dist/universal/.agents/skills/citable/commands/measurement.md +49 -0
  10. package/dist/universal/.agents/skills/citable/commands/optimize-page.md +53 -0
  11. package/dist/universal/.agents/skills/citable/commands/page-work.md +48 -0
  12. package/dist/universal/.agents/skills/citable/commands/validate-render.md +24 -0
  13. package/dist/universal/.agents/skills/citable/manifest.json +54 -0
  14. package/dist/universal/.agents/skills/citable/policies/crawler-policy-template.md +47 -0
  15. package/dist/universal/.agents/skills/citable/references/anti-patterns.md +61 -0
  16. package/dist/universal/.agents/skills/citable/rubrics/README.md +30 -0
  17. package/dist/universal/.agents/skills/citable/rubrics/answer-extractability.md +44 -0
  18. package/dist/universal/.agents/skills/citable/rubrics/claim-boundedness.md +36 -0
  19. package/dist/universal/.agents/skills/citable/rubrics/comparison-fairness.md +30 -0
  20. package/dist/universal/.agents/skills/citable/rubrics/conversion-alignment.md +37 -0
  21. package/dist/universal/.agents/skills/citable/rubrics/entity-clarity.md +41 -0
  22. package/dist/universal/.agents/skills/citable/rubrics/evidence-strength.md +53 -0
  23. package/dist/universal/.agents/skills/citable/rubrics/information-gain.md +33 -0
  24. package/dist/universal/.agents/skills/citable/rubrics/intent-alignment.md +41 -0
  25. package/dist/universal/.agents/skills/citable/rubrics/narrative-accuracy.md +46 -0
  26. package/dist/universal/.agents/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  27. package/dist/universal/.agents/skills/citable/rubrics/semantic-clarity.md +42 -0
  28. package/dist/universal/.agents/skills/citable/rubrics/source-authority.md +37 -0
  29. package/dist/universal/.agents/skills/citable/schemas/claim.schema.json +53 -0
  30. package/dist/universal/.agents/skills/citable/schemas/common.defs.json +33 -0
  31. package/dist/universal/.agents/skills/citable/schemas/competitor.schema.json +28 -0
  32. package/dist/universal/.agents/skills/citable/schemas/config.schema.json +41 -0
  33. package/dist/universal/.agents/skills/citable/schemas/crawler.schema.json +33 -0
  34. package/dist/universal/.agents/skills/citable/schemas/detector-quality.schema.json +39 -0
  35. package/dist/universal/.agents/skills/citable/schemas/entity.schema.json +39 -0
  36. package/dist/universal/.agents/skills/citable/schemas/evidence.schema.json +41 -0
  37. package/dist/universal/.agents/skills/citable/schemas/experiment.schema.json +37 -0
  38. package/dist/universal/.agents/skills/citable/schemas/finding.schema.json +101 -0
  39. package/dist/universal/.agents/skills/citable/schemas/page.schema.json +40 -0
  40. package/dist/universal/.agents/skills/citable/schemas/project.schema.json +29 -0
  41. package/dist/universal/.agents/skills/citable/schemas/prompt-result.schema.json +37 -0
  42. package/dist/universal/.agents/skills/citable/schemas/prompt.schema.json +41 -0
  43. package/dist/universal/.agents/skills/citable/schemas/query.schema.json +43 -0
  44. package/dist/universal/.agents/skills/citable/schemas/run.schema.json +36 -0
  45. package/dist/universal/.agents/skills/citable/scripts/README.md +4 -0
  46. package/dist/universal/.agents/skills/citable/templates/finding-review.md +54 -0
  47. package/dist/universal/.claude/skills/citable/SKILL.md +137 -0
  48. package/dist/universal/.claude/skills/citable/VERSION +1 -0
  49. package/dist/universal/.claude/skills/citable/commands/README.md +36 -0
  50. package/dist/universal/.claude/skills/citable/commands/ingest.md +44 -0
  51. package/dist/universal/.claude/skills/citable/commands/measurement.md +49 -0
  52. package/dist/universal/.claude/skills/citable/commands/optimize-page.md +53 -0
  53. package/dist/universal/.claude/skills/citable/commands/page-work.md +48 -0
  54. package/dist/universal/.claude/skills/citable/commands/validate-render.md +24 -0
  55. package/dist/universal/.claude/skills/citable/manifest.json +54 -0
  56. package/dist/universal/.claude/skills/citable/policies/crawler-policy-template.md +47 -0
  57. package/dist/universal/.claude/skills/citable/references/anti-patterns.md +61 -0
  58. package/dist/universal/.claude/skills/citable/rubrics/README.md +30 -0
  59. package/dist/universal/.claude/skills/citable/rubrics/answer-extractability.md +44 -0
  60. package/dist/universal/.claude/skills/citable/rubrics/claim-boundedness.md +36 -0
  61. package/dist/universal/.claude/skills/citable/rubrics/comparison-fairness.md +30 -0
  62. package/dist/universal/.claude/skills/citable/rubrics/conversion-alignment.md +37 -0
  63. package/dist/universal/.claude/skills/citable/rubrics/entity-clarity.md +41 -0
  64. package/dist/universal/.claude/skills/citable/rubrics/evidence-strength.md +53 -0
  65. package/dist/universal/.claude/skills/citable/rubrics/information-gain.md +33 -0
  66. package/dist/universal/.claude/skills/citable/rubrics/intent-alignment.md +41 -0
  67. package/dist/universal/.claude/skills/citable/rubrics/narrative-accuracy.md +46 -0
  68. package/dist/universal/.claude/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  69. package/dist/universal/.claude/skills/citable/rubrics/semantic-clarity.md +42 -0
  70. package/dist/universal/.claude/skills/citable/rubrics/source-authority.md +37 -0
  71. package/dist/universal/.claude/skills/citable/schemas/claim.schema.json +53 -0
  72. package/dist/universal/.claude/skills/citable/schemas/common.defs.json +33 -0
  73. package/dist/universal/.claude/skills/citable/schemas/competitor.schema.json +28 -0
  74. package/dist/universal/.claude/skills/citable/schemas/config.schema.json +41 -0
  75. package/dist/universal/.claude/skills/citable/schemas/crawler.schema.json +33 -0
  76. package/dist/universal/.claude/skills/citable/schemas/detector-quality.schema.json +39 -0
  77. package/dist/universal/.claude/skills/citable/schemas/entity.schema.json +39 -0
  78. package/dist/universal/.claude/skills/citable/schemas/evidence.schema.json +41 -0
  79. package/dist/universal/.claude/skills/citable/schemas/experiment.schema.json +37 -0
  80. package/dist/universal/.claude/skills/citable/schemas/finding.schema.json +101 -0
  81. package/dist/universal/.claude/skills/citable/schemas/page.schema.json +40 -0
  82. package/dist/universal/.claude/skills/citable/schemas/project.schema.json +29 -0
  83. package/dist/universal/.claude/skills/citable/schemas/prompt-result.schema.json +37 -0
  84. package/dist/universal/.claude/skills/citable/schemas/prompt.schema.json +41 -0
  85. package/dist/universal/.claude/skills/citable/schemas/query.schema.json +43 -0
  86. package/dist/universal/.claude/skills/citable/schemas/run.schema.json +36 -0
  87. package/dist/universal/.claude/skills/citable/scripts/README.md +4 -0
  88. package/dist/universal/.claude/skills/citable/templates/finding-review.md +54 -0
  89. package/dist/universal/.cursor/skills/citable/SKILL.md +137 -0
  90. package/dist/universal/.cursor/skills/citable/VERSION +1 -0
  91. package/dist/universal/.cursor/skills/citable/commands/README.md +36 -0
  92. package/dist/universal/.cursor/skills/citable/commands/ingest.md +44 -0
  93. package/dist/universal/.cursor/skills/citable/commands/measurement.md +49 -0
  94. package/dist/universal/.cursor/skills/citable/commands/optimize-page.md +53 -0
  95. package/dist/universal/.cursor/skills/citable/commands/page-work.md +48 -0
  96. package/dist/universal/.cursor/skills/citable/commands/validate-render.md +24 -0
  97. package/dist/universal/.cursor/skills/citable/manifest.json +54 -0
  98. package/dist/universal/.cursor/skills/citable/policies/crawler-policy-template.md +47 -0
  99. package/dist/universal/.cursor/skills/citable/references/anti-patterns.md +61 -0
  100. package/dist/universal/.cursor/skills/citable/rubrics/README.md +30 -0
  101. package/dist/universal/.cursor/skills/citable/rubrics/answer-extractability.md +44 -0
  102. package/dist/universal/.cursor/skills/citable/rubrics/claim-boundedness.md +36 -0
  103. package/dist/universal/.cursor/skills/citable/rubrics/comparison-fairness.md +30 -0
  104. package/dist/universal/.cursor/skills/citable/rubrics/conversion-alignment.md +37 -0
  105. package/dist/universal/.cursor/skills/citable/rubrics/entity-clarity.md +41 -0
  106. package/dist/universal/.cursor/skills/citable/rubrics/evidence-strength.md +53 -0
  107. package/dist/universal/.cursor/skills/citable/rubrics/information-gain.md +33 -0
  108. package/dist/universal/.cursor/skills/citable/rubrics/intent-alignment.md +41 -0
  109. package/dist/universal/.cursor/skills/citable/rubrics/narrative-accuracy.md +46 -0
  110. package/dist/universal/.cursor/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  111. package/dist/universal/.cursor/skills/citable/rubrics/semantic-clarity.md +42 -0
  112. package/dist/universal/.cursor/skills/citable/rubrics/source-authority.md +37 -0
  113. package/dist/universal/.cursor/skills/citable/schemas/claim.schema.json +53 -0
  114. package/dist/universal/.cursor/skills/citable/schemas/common.defs.json +33 -0
  115. package/dist/universal/.cursor/skills/citable/schemas/competitor.schema.json +28 -0
  116. package/dist/universal/.cursor/skills/citable/schemas/config.schema.json +41 -0
  117. package/dist/universal/.cursor/skills/citable/schemas/crawler.schema.json +33 -0
  118. package/dist/universal/.cursor/skills/citable/schemas/detector-quality.schema.json +39 -0
  119. package/dist/universal/.cursor/skills/citable/schemas/entity.schema.json +39 -0
  120. package/dist/universal/.cursor/skills/citable/schemas/evidence.schema.json +41 -0
  121. package/dist/universal/.cursor/skills/citable/schemas/experiment.schema.json +37 -0
  122. package/dist/universal/.cursor/skills/citable/schemas/finding.schema.json +101 -0
  123. package/dist/universal/.cursor/skills/citable/schemas/page.schema.json +40 -0
  124. package/dist/universal/.cursor/skills/citable/schemas/project.schema.json +29 -0
  125. package/dist/universal/.cursor/skills/citable/schemas/prompt-result.schema.json +37 -0
  126. package/dist/universal/.cursor/skills/citable/schemas/prompt.schema.json +41 -0
  127. package/dist/universal/.cursor/skills/citable/schemas/query.schema.json +43 -0
  128. package/dist/universal/.cursor/skills/citable/schemas/run.schema.json +36 -0
  129. package/dist/universal/.cursor/skills/citable/scripts/README.md +4 -0
  130. package/dist/universal/.cursor/skills/citable/templates/finding-review.md +54 -0
  131. package/dist/universal/.gemini/skills/citable/SKILL.md +137 -0
  132. package/dist/universal/.gemini/skills/citable/VERSION +1 -0
  133. package/dist/universal/.gemini/skills/citable/commands/README.md +36 -0
  134. package/dist/universal/.gemini/skills/citable/commands/ingest.md +44 -0
  135. package/dist/universal/.gemini/skills/citable/commands/measurement.md +49 -0
  136. package/dist/universal/.gemini/skills/citable/commands/optimize-page.md +53 -0
  137. package/dist/universal/.gemini/skills/citable/commands/page-work.md +48 -0
  138. package/dist/universal/.gemini/skills/citable/commands/validate-render.md +24 -0
  139. package/dist/universal/.gemini/skills/citable/manifest.json +54 -0
  140. package/dist/universal/.gemini/skills/citable/policies/crawler-policy-template.md +47 -0
  141. package/dist/universal/.gemini/skills/citable/references/anti-patterns.md +61 -0
  142. package/dist/universal/.gemini/skills/citable/rubrics/README.md +30 -0
  143. package/dist/universal/.gemini/skills/citable/rubrics/answer-extractability.md +44 -0
  144. package/dist/universal/.gemini/skills/citable/rubrics/claim-boundedness.md +36 -0
  145. package/dist/universal/.gemini/skills/citable/rubrics/comparison-fairness.md +30 -0
  146. package/dist/universal/.gemini/skills/citable/rubrics/conversion-alignment.md +37 -0
  147. package/dist/universal/.gemini/skills/citable/rubrics/entity-clarity.md +41 -0
  148. package/dist/universal/.gemini/skills/citable/rubrics/evidence-strength.md +53 -0
  149. package/dist/universal/.gemini/skills/citable/rubrics/information-gain.md +33 -0
  150. package/dist/universal/.gemini/skills/citable/rubrics/intent-alignment.md +41 -0
  151. package/dist/universal/.gemini/skills/citable/rubrics/narrative-accuracy.md +46 -0
  152. package/dist/universal/.gemini/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  153. package/dist/universal/.gemini/skills/citable/rubrics/semantic-clarity.md +42 -0
  154. package/dist/universal/.gemini/skills/citable/rubrics/source-authority.md +37 -0
  155. package/dist/universal/.gemini/skills/citable/schemas/claim.schema.json +53 -0
  156. package/dist/universal/.gemini/skills/citable/schemas/common.defs.json +33 -0
  157. package/dist/universal/.gemini/skills/citable/schemas/competitor.schema.json +28 -0
  158. package/dist/universal/.gemini/skills/citable/schemas/config.schema.json +41 -0
  159. package/dist/universal/.gemini/skills/citable/schemas/crawler.schema.json +33 -0
  160. package/dist/universal/.gemini/skills/citable/schemas/detector-quality.schema.json +39 -0
  161. package/dist/universal/.gemini/skills/citable/schemas/entity.schema.json +39 -0
  162. package/dist/universal/.gemini/skills/citable/schemas/evidence.schema.json +41 -0
  163. package/dist/universal/.gemini/skills/citable/schemas/experiment.schema.json +37 -0
  164. package/dist/universal/.gemini/skills/citable/schemas/finding.schema.json +101 -0
  165. package/dist/universal/.gemini/skills/citable/schemas/page.schema.json +40 -0
  166. package/dist/universal/.gemini/skills/citable/schemas/project.schema.json +29 -0
  167. package/dist/universal/.gemini/skills/citable/schemas/prompt-result.schema.json +37 -0
  168. package/dist/universal/.gemini/skills/citable/schemas/prompt.schema.json +41 -0
  169. package/dist/universal/.gemini/skills/citable/schemas/query.schema.json +43 -0
  170. package/dist/universal/.gemini/skills/citable/schemas/run.schema.json +36 -0
  171. package/dist/universal/.gemini/skills/citable/scripts/README.md +4 -0
  172. package/dist/universal/.gemini/skills/citable/templates/finding-review.md +54 -0
  173. package/dist/universal/.github/skills/citable/SKILL.md +137 -0
  174. package/dist/universal/.github/skills/citable/VERSION +1 -0
  175. package/dist/universal/.github/skills/citable/commands/README.md +36 -0
  176. package/dist/universal/.github/skills/citable/commands/ingest.md +44 -0
  177. package/dist/universal/.github/skills/citable/commands/measurement.md +49 -0
  178. package/dist/universal/.github/skills/citable/commands/optimize-page.md +53 -0
  179. package/dist/universal/.github/skills/citable/commands/page-work.md +48 -0
  180. package/dist/universal/.github/skills/citable/commands/validate-render.md +24 -0
  181. package/dist/universal/.github/skills/citable/manifest.json +54 -0
  182. package/dist/universal/.github/skills/citable/policies/crawler-policy-template.md +47 -0
  183. package/dist/universal/.github/skills/citable/references/anti-patterns.md +61 -0
  184. package/dist/universal/.github/skills/citable/rubrics/README.md +30 -0
  185. package/dist/universal/.github/skills/citable/rubrics/answer-extractability.md +44 -0
  186. package/dist/universal/.github/skills/citable/rubrics/claim-boundedness.md +36 -0
  187. package/dist/universal/.github/skills/citable/rubrics/comparison-fairness.md +30 -0
  188. package/dist/universal/.github/skills/citable/rubrics/conversion-alignment.md +37 -0
  189. package/dist/universal/.github/skills/citable/rubrics/entity-clarity.md +41 -0
  190. package/dist/universal/.github/skills/citable/rubrics/evidence-strength.md +53 -0
  191. package/dist/universal/.github/skills/citable/rubrics/information-gain.md +33 -0
  192. package/dist/universal/.github/skills/citable/rubrics/intent-alignment.md +41 -0
  193. package/dist/universal/.github/skills/citable/rubrics/narrative-accuracy.md +46 -0
  194. package/dist/universal/.github/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  195. package/dist/universal/.github/skills/citable/rubrics/semantic-clarity.md +42 -0
  196. package/dist/universal/.github/skills/citable/rubrics/source-authority.md +37 -0
  197. package/dist/universal/.github/skills/citable/schemas/claim.schema.json +53 -0
  198. package/dist/universal/.github/skills/citable/schemas/common.defs.json +33 -0
  199. package/dist/universal/.github/skills/citable/schemas/competitor.schema.json +28 -0
  200. package/dist/universal/.github/skills/citable/schemas/config.schema.json +41 -0
  201. package/dist/universal/.github/skills/citable/schemas/crawler.schema.json +33 -0
  202. package/dist/universal/.github/skills/citable/schemas/detector-quality.schema.json +39 -0
  203. package/dist/universal/.github/skills/citable/schemas/entity.schema.json +39 -0
  204. package/dist/universal/.github/skills/citable/schemas/evidence.schema.json +41 -0
  205. package/dist/universal/.github/skills/citable/schemas/experiment.schema.json +37 -0
  206. package/dist/universal/.github/skills/citable/schemas/finding.schema.json +101 -0
  207. package/dist/universal/.github/skills/citable/schemas/page.schema.json +40 -0
  208. package/dist/universal/.github/skills/citable/schemas/project.schema.json +29 -0
  209. package/dist/universal/.github/skills/citable/schemas/prompt-result.schema.json +37 -0
  210. package/dist/universal/.github/skills/citable/schemas/prompt.schema.json +41 -0
  211. package/dist/universal/.github/skills/citable/schemas/query.schema.json +43 -0
  212. package/dist/universal/.github/skills/citable/schemas/run.schema.json +36 -0
  213. package/dist/universal/.github/skills/citable/scripts/README.md +4 -0
  214. package/dist/universal/.github/skills/citable/templates/finding-review.md +54 -0
  215. package/dist/universal/.kiro/skills/citable/SKILL.md +137 -0
  216. package/dist/universal/.kiro/skills/citable/VERSION +1 -0
  217. package/dist/universal/.kiro/skills/citable/commands/README.md +36 -0
  218. package/dist/universal/.kiro/skills/citable/commands/ingest.md +44 -0
  219. package/dist/universal/.kiro/skills/citable/commands/measurement.md +49 -0
  220. package/dist/universal/.kiro/skills/citable/commands/optimize-page.md +53 -0
  221. package/dist/universal/.kiro/skills/citable/commands/page-work.md +48 -0
  222. package/dist/universal/.kiro/skills/citable/commands/validate-render.md +24 -0
  223. package/dist/universal/.kiro/skills/citable/manifest.json +54 -0
  224. package/dist/universal/.kiro/skills/citable/policies/crawler-policy-template.md +47 -0
  225. package/dist/universal/.kiro/skills/citable/references/anti-patterns.md +61 -0
  226. package/dist/universal/.kiro/skills/citable/rubrics/README.md +30 -0
  227. package/dist/universal/.kiro/skills/citable/rubrics/answer-extractability.md +44 -0
  228. package/dist/universal/.kiro/skills/citable/rubrics/claim-boundedness.md +36 -0
  229. package/dist/universal/.kiro/skills/citable/rubrics/comparison-fairness.md +30 -0
  230. package/dist/universal/.kiro/skills/citable/rubrics/conversion-alignment.md +37 -0
  231. package/dist/universal/.kiro/skills/citable/rubrics/entity-clarity.md +41 -0
  232. package/dist/universal/.kiro/skills/citable/rubrics/evidence-strength.md +53 -0
  233. package/dist/universal/.kiro/skills/citable/rubrics/information-gain.md +33 -0
  234. package/dist/universal/.kiro/skills/citable/rubrics/intent-alignment.md +41 -0
  235. package/dist/universal/.kiro/skills/citable/rubrics/narrative-accuracy.md +46 -0
  236. package/dist/universal/.kiro/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  237. package/dist/universal/.kiro/skills/citable/rubrics/semantic-clarity.md +42 -0
  238. package/dist/universal/.kiro/skills/citable/rubrics/source-authority.md +37 -0
  239. package/dist/universal/.kiro/skills/citable/schemas/claim.schema.json +53 -0
  240. package/dist/universal/.kiro/skills/citable/schemas/common.defs.json +33 -0
  241. package/dist/universal/.kiro/skills/citable/schemas/competitor.schema.json +28 -0
  242. package/dist/universal/.kiro/skills/citable/schemas/config.schema.json +41 -0
  243. package/dist/universal/.kiro/skills/citable/schemas/crawler.schema.json +33 -0
  244. package/dist/universal/.kiro/skills/citable/schemas/detector-quality.schema.json +39 -0
  245. package/dist/universal/.kiro/skills/citable/schemas/entity.schema.json +39 -0
  246. package/dist/universal/.kiro/skills/citable/schemas/evidence.schema.json +41 -0
  247. package/dist/universal/.kiro/skills/citable/schemas/experiment.schema.json +37 -0
  248. package/dist/universal/.kiro/skills/citable/schemas/finding.schema.json +101 -0
  249. package/dist/universal/.kiro/skills/citable/schemas/page.schema.json +40 -0
  250. package/dist/universal/.kiro/skills/citable/schemas/project.schema.json +29 -0
  251. package/dist/universal/.kiro/skills/citable/schemas/prompt-result.schema.json +37 -0
  252. package/dist/universal/.kiro/skills/citable/schemas/prompt.schema.json +41 -0
  253. package/dist/universal/.kiro/skills/citable/schemas/query.schema.json +43 -0
  254. package/dist/universal/.kiro/skills/citable/schemas/run.schema.json +36 -0
  255. package/dist/universal/.kiro/skills/citable/scripts/README.md +4 -0
  256. package/dist/universal/.kiro/skills/citable/templates/finding-review.md +54 -0
  257. package/dist/universal/.opencode/skills/citable/SKILL.md +137 -0
  258. package/dist/universal/.opencode/skills/citable/VERSION +1 -0
  259. package/dist/universal/.opencode/skills/citable/commands/README.md +36 -0
  260. package/dist/universal/.opencode/skills/citable/commands/ingest.md +44 -0
  261. package/dist/universal/.opencode/skills/citable/commands/measurement.md +49 -0
  262. package/dist/universal/.opencode/skills/citable/commands/optimize-page.md +53 -0
  263. package/dist/universal/.opencode/skills/citable/commands/page-work.md +48 -0
  264. package/dist/universal/.opencode/skills/citable/commands/validate-render.md +24 -0
  265. package/dist/universal/.opencode/skills/citable/manifest.json +54 -0
  266. package/dist/universal/.opencode/skills/citable/policies/crawler-policy-template.md +47 -0
  267. package/dist/universal/.opencode/skills/citable/references/anti-patterns.md +61 -0
  268. package/dist/universal/.opencode/skills/citable/rubrics/README.md +30 -0
  269. package/dist/universal/.opencode/skills/citable/rubrics/answer-extractability.md +44 -0
  270. package/dist/universal/.opencode/skills/citable/rubrics/claim-boundedness.md +36 -0
  271. package/dist/universal/.opencode/skills/citable/rubrics/comparison-fairness.md +30 -0
  272. package/dist/universal/.opencode/skills/citable/rubrics/conversion-alignment.md +37 -0
  273. package/dist/universal/.opencode/skills/citable/rubrics/entity-clarity.md +41 -0
  274. package/dist/universal/.opencode/skills/citable/rubrics/evidence-strength.md +53 -0
  275. package/dist/universal/.opencode/skills/citable/rubrics/information-gain.md +33 -0
  276. package/dist/universal/.opencode/skills/citable/rubrics/intent-alignment.md +41 -0
  277. package/dist/universal/.opencode/skills/citable/rubrics/narrative-accuracy.md +46 -0
  278. package/dist/universal/.opencode/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  279. package/dist/universal/.opencode/skills/citable/rubrics/semantic-clarity.md +42 -0
  280. package/dist/universal/.opencode/skills/citable/rubrics/source-authority.md +37 -0
  281. package/dist/universal/.opencode/skills/citable/schemas/claim.schema.json +53 -0
  282. package/dist/universal/.opencode/skills/citable/schemas/common.defs.json +33 -0
  283. package/dist/universal/.opencode/skills/citable/schemas/competitor.schema.json +28 -0
  284. package/dist/universal/.opencode/skills/citable/schemas/config.schema.json +41 -0
  285. package/dist/universal/.opencode/skills/citable/schemas/crawler.schema.json +33 -0
  286. package/dist/universal/.opencode/skills/citable/schemas/detector-quality.schema.json +39 -0
  287. package/dist/universal/.opencode/skills/citable/schemas/entity.schema.json +39 -0
  288. package/dist/universal/.opencode/skills/citable/schemas/evidence.schema.json +41 -0
  289. package/dist/universal/.opencode/skills/citable/schemas/experiment.schema.json +37 -0
  290. package/dist/universal/.opencode/skills/citable/schemas/finding.schema.json +101 -0
  291. package/dist/universal/.opencode/skills/citable/schemas/page.schema.json +40 -0
  292. package/dist/universal/.opencode/skills/citable/schemas/project.schema.json +29 -0
  293. package/dist/universal/.opencode/skills/citable/schemas/prompt-result.schema.json +37 -0
  294. package/dist/universal/.opencode/skills/citable/schemas/prompt.schema.json +41 -0
  295. package/dist/universal/.opencode/skills/citable/schemas/query.schema.json +43 -0
  296. package/dist/universal/.opencode/skills/citable/schemas/run.schema.json +36 -0
  297. package/dist/universal/.opencode/skills/citable/scripts/README.md +4 -0
  298. package/dist/universal/.opencode/skills/citable/templates/finding-review.md +54 -0
  299. package/dist/universal/.pi/agent/skills/citable/SKILL.md +137 -0
  300. package/dist/universal/.pi/agent/skills/citable/VERSION +1 -0
  301. package/dist/universal/.pi/agent/skills/citable/commands/README.md +36 -0
  302. package/dist/universal/.pi/agent/skills/citable/commands/ingest.md +44 -0
  303. package/dist/universal/.pi/agent/skills/citable/commands/measurement.md +49 -0
  304. package/dist/universal/.pi/agent/skills/citable/commands/optimize-page.md +53 -0
  305. package/dist/universal/.pi/agent/skills/citable/commands/page-work.md +48 -0
  306. package/dist/universal/.pi/agent/skills/citable/commands/validate-render.md +24 -0
  307. package/dist/universal/.pi/agent/skills/citable/manifest.json +54 -0
  308. package/dist/universal/.pi/agent/skills/citable/policies/crawler-policy-template.md +47 -0
  309. package/dist/universal/.pi/agent/skills/citable/references/anti-patterns.md +61 -0
  310. package/dist/universal/.pi/agent/skills/citable/rubrics/README.md +30 -0
  311. package/dist/universal/.pi/agent/skills/citable/rubrics/answer-extractability.md +44 -0
  312. package/dist/universal/.pi/agent/skills/citable/rubrics/claim-boundedness.md +36 -0
  313. package/dist/universal/.pi/agent/skills/citable/rubrics/comparison-fairness.md +30 -0
  314. package/dist/universal/.pi/agent/skills/citable/rubrics/conversion-alignment.md +37 -0
  315. package/dist/universal/.pi/agent/skills/citable/rubrics/entity-clarity.md +41 -0
  316. package/dist/universal/.pi/agent/skills/citable/rubrics/evidence-strength.md +53 -0
  317. package/dist/universal/.pi/agent/skills/citable/rubrics/information-gain.md +33 -0
  318. package/dist/universal/.pi/agent/skills/citable/rubrics/intent-alignment.md +41 -0
  319. package/dist/universal/.pi/agent/skills/citable/rubrics/narrative-accuracy.md +46 -0
  320. package/dist/universal/.pi/agent/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  321. package/dist/universal/.pi/agent/skills/citable/rubrics/semantic-clarity.md +42 -0
  322. package/dist/universal/.pi/agent/skills/citable/rubrics/source-authority.md +37 -0
  323. package/dist/universal/.pi/agent/skills/citable/schemas/claim.schema.json +53 -0
  324. package/dist/universal/.pi/agent/skills/citable/schemas/common.defs.json +33 -0
  325. package/dist/universal/.pi/agent/skills/citable/schemas/competitor.schema.json +28 -0
  326. package/dist/universal/.pi/agent/skills/citable/schemas/config.schema.json +41 -0
  327. package/dist/universal/.pi/agent/skills/citable/schemas/crawler.schema.json +33 -0
  328. package/dist/universal/.pi/agent/skills/citable/schemas/detector-quality.schema.json +39 -0
  329. package/dist/universal/.pi/agent/skills/citable/schemas/entity.schema.json +39 -0
  330. package/dist/universal/.pi/agent/skills/citable/schemas/evidence.schema.json +41 -0
  331. package/dist/universal/.pi/agent/skills/citable/schemas/experiment.schema.json +37 -0
  332. package/dist/universal/.pi/agent/skills/citable/schemas/finding.schema.json +101 -0
  333. package/dist/universal/.pi/agent/skills/citable/schemas/page.schema.json +40 -0
  334. package/dist/universal/.pi/agent/skills/citable/schemas/project.schema.json +29 -0
  335. package/dist/universal/.pi/agent/skills/citable/schemas/prompt-result.schema.json +37 -0
  336. package/dist/universal/.pi/agent/skills/citable/schemas/prompt.schema.json +41 -0
  337. package/dist/universal/.pi/agent/skills/citable/schemas/query.schema.json +43 -0
  338. package/dist/universal/.pi/agent/skills/citable/schemas/run.schema.json +36 -0
  339. package/dist/universal/.pi/agent/skills/citable/scripts/README.md +4 -0
  340. package/dist/universal/.pi/agent/skills/citable/templates/finding-review.md +54 -0
  341. package/dist/universal/.qoder/skills/citable/SKILL.md +137 -0
  342. package/dist/universal/.qoder/skills/citable/VERSION +1 -0
  343. package/dist/universal/.qoder/skills/citable/commands/README.md +36 -0
  344. package/dist/universal/.qoder/skills/citable/commands/ingest.md +44 -0
  345. package/dist/universal/.qoder/skills/citable/commands/measurement.md +49 -0
  346. package/dist/universal/.qoder/skills/citable/commands/optimize-page.md +53 -0
  347. package/dist/universal/.qoder/skills/citable/commands/page-work.md +48 -0
  348. package/dist/universal/.qoder/skills/citable/commands/validate-render.md +24 -0
  349. package/dist/universal/.qoder/skills/citable/manifest.json +54 -0
  350. package/dist/universal/.qoder/skills/citable/policies/crawler-policy-template.md +47 -0
  351. package/dist/universal/.qoder/skills/citable/references/anti-patterns.md +61 -0
  352. package/dist/universal/.qoder/skills/citable/rubrics/README.md +30 -0
  353. package/dist/universal/.qoder/skills/citable/rubrics/answer-extractability.md +44 -0
  354. package/dist/universal/.qoder/skills/citable/rubrics/claim-boundedness.md +36 -0
  355. package/dist/universal/.qoder/skills/citable/rubrics/comparison-fairness.md +30 -0
  356. package/dist/universal/.qoder/skills/citable/rubrics/conversion-alignment.md +37 -0
  357. package/dist/universal/.qoder/skills/citable/rubrics/entity-clarity.md +41 -0
  358. package/dist/universal/.qoder/skills/citable/rubrics/evidence-strength.md +53 -0
  359. package/dist/universal/.qoder/skills/citable/rubrics/information-gain.md +33 -0
  360. package/dist/universal/.qoder/skills/citable/rubrics/intent-alignment.md +41 -0
  361. package/dist/universal/.qoder/skills/citable/rubrics/narrative-accuracy.md +46 -0
  362. package/dist/universal/.qoder/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  363. package/dist/universal/.qoder/skills/citable/rubrics/semantic-clarity.md +42 -0
  364. package/dist/universal/.qoder/skills/citable/rubrics/source-authority.md +37 -0
  365. package/dist/universal/.qoder/skills/citable/schemas/claim.schema.json +53 -0
  366. package/dist/universal/.qoder/skills/citable/schemas/common.defs.json +33 -0
  367. package/dist/universal/.qoder/skills/citable/schemas/competitor.schema.json +28 -0
  368. package/dist/universal/.qoder/skills/citable/schemas/config.schema.json +41 -0
  369. package/dist/universal/.qoder/skills/citable/schemas/crawler.schema.json +33 -0
  370. package/dist/universal/.qoder/skills/citable/schemas/detector-quality.schema.json +39 -0
  371. package/dist/universal/.qoder/skills/citable/schemas/entity.schema.json +39 -0
  372. package/dist/universal/.qoder/skills/citable/schemas/evidence.schema.json +41 -0
  373. package/dist/universal/.qoder/skills/citable/schemas/experiment.schema.json +37 -0
  374. package/dist/universal/.qoder/skills/citable/schemas/finding.schema.json +101 -0
  375. package/dist/universal/.qoder/skills/citable/schemas/page.schema.json +40 -0
  376. package/dist/universal/.qoder/skills/citable/schemas/project.schema.json +29 -0
  377. package/dist/universal/.qoder/skills/citable/schemas/prompt-result.schema.json +37 -0
  378. package/dist/universal/.qoder/skills/citable/schemas/prompt.schema.json +41 -0
  379. package/dist/universal/.qoder/skills/citable/schemas/query.schema.json +43 -0
  380. package/dist/universal/.qoder/skills/citable/schemas/run.schema.json +36 -0
  381. package/dist/universal/.qoder/skills/citable/scripts/README.md +4 -0
  382. package/dist/universal/.qoder/skills/citable/templates/finding-review.md +54 -0
  383. package/dist/universal/.rovodev/skills/citable/SKILL.md +137 -0
  384. package/dist/universal/.rovodev/skills/citable/VERSION +1 -0
  385. package/dist/universal/.rovodev/skills/citable/commands/README.md +36 -0
  386. package/dist/universal/.rovodev/skills/citable/commands/ingest.md +44 -0
  387. package/dist/universal/.rovodev/skills/citable/commands/measurement.md +49 -0
  388. package/dist/universal/.rovodev/skills/citable/commands/optimize-page.md +53 -0
  389. package/dist/universal/.rovodev/skills/citable/commands/page-work.md +48 -0
  390. package/dist/universal/.rovodev/skills/citable/commands/validate-render.md +24 -0
  391. package/dist/universal/.rovodev/skills/citable/manifest.json +54 -0
  392. package/dist/universal/.rovodev/skills/citable/policies/crawler-policy-template.md +47 -0
  393. package/dist/universal/.rovodev/skills/citable/references/anti-patterns.md +61 -0
  394. package/dist/universal/.rovodev/skills/citable/rubrics/README.md +30 -0
  395. package/dist/universal/.rovodev/skills/citable/rubrics/answer-extractability.md +44 -0
  396. package/dist/universal/.rovodev/skills/citable/rubrics/claim-boundedness.md +36 -0
  397. package/dist/universal/.rovodev/skills/citable/rubrics/comparison-fairness.md +30 -0
  398. package/dist/universal/.rovodev/skills/citable/rubrics/conversion-alignment.md +37 -0
  399. package/dist/universal/.rovodev/skills/citable/rubrics/entity-clarity.md +41 -0
  400. package/dist/universal/.rovodev/skills/citable/rubrics/evidence-strength.md +53 -0
  401. package/dist/universal/.rovodev/skills/citable/rubrics/information-gain.md +33 -0
  402. package/dist/universal/.rovodev/skills/citable/rubrics/intent-alignment.md +41 -0
  403. package/dist/universal/.rovodev/skills/citable/rubrics/narrative-accuracy.md +46 -0
  404. package/dist/universal/.rovodev/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  405. package/dist/universal/.rovodev/skills/citable/rubrics/semantic-clarity.md +42 -0
  406. package/dist/universal/.rovodev/skills/citable/rubrics/source-authority.md +37 -0
  407. package/dist/universal/.rovodev/skills/citable/schemas/claim.schema.json +53 -0
  408. package/dist/universal/.rovodev/skills/citable/schemas/common.defs.json +33 -0
  409. package/dist/universal/.rovodev/skills/citable/schemas/competitor.schema.json +28 -0
  410. package/dist/universal/.rovodev/skills/citable/schemas/config.schema.json +41 -0
  411. package/dist/universal/.rovodev/skills/citable/schemas/crawler.schema.json +33 -0
  412. package/dist/universal/.rovodev/skills/citable/schemas/detector-quality.schema.json +39 -0
  413. package/dist/universal/.rovodev/skills/citable/schemas/entity.schema.json +39 -0
  414. package/dist/universal/.rovodev/skills/citable/schemas/evidence.schema.json +41 -0
  415. package/dist/universal/.rovodev/skills/citable/schemas/experiment.schema.json +37 -0
  416. package/dist/universal/.rovodev/skills/citable/schemas/finding.schema.json +101 -0
  417. package/dist/universal/.rovodev/skills/citable/schemas/page.schema.json +40 -0
  418. package/dist/universal/.rovodev/skills/citable/schemas/project.schema.json +29 -0
  419. package/dist/universal/.rovodev/skills/citable/schemas/prompt-result.schema.json +37 -0
  420. package/dist/universal/.rovodev/skills/citable/schemas/prompt.schema.json +41 -0
  421. package/dist/universal/.rovodev/skills/citable/schemas/query.schema.json +43 -0
  422. package/dist/universal/.rovodev/skills/citable/schemas/run.schema.json +36 -0
  423. package/dist/universal/.rovodev/skills/citable/scripts/README.md +4 -0
  424. package/dist/universal/.rovodev/skills/citable/templates/finding-review.md +54 -0
  425. package/dist/universal/.trae/skills/citable/SKILL.md +137 -0
  426. package/dist/universal/.trae/skills/citable/VERSION +1 -0
  427. package/dist/universal/.trae/skills/citable/commands/README.md +36 -0
  428. package/dist/universal/.trae/skills/citable/commands/ingest.md +44 -0
  429. package/dist/universal/.trae/skills/citable/commands/measurement.md +49 -0
  430. package/dist/universal/.trae/skills/citable/commands/optimize-page.md +53 -0
  431. package/dist/universal/.trae/skills/citable/commands/page-work.md +48 -0
  432. package/dist/universal/.trae/skills/citable/commands/validate-render.md +24 -0
  433. package/dist/universal/.trae/skills/citable/manifest.json +54 -0
  434. package/dist/universal/.trae/skills/citable/policies/crawler-policy-template.md +47 -0
  435. package/dist/universal/.trae/skills/citable/references/anti-patterns.md +61 -0
  436. package/dist/universal/.trae/skills/citable/rubrics/README.md +30 -0
  437. package/dist/universal/.trae/skills/citable/rubrics/answer-extractability.md +44 -0
  438. package/dist/universal/.trae/skills/citable/rubrics/claim-boundedness.md +36 -0
  439. package/dist/universal/.trae/skills/citable/rubrics/comparison-fairness.md +30 -0
  440. package/dist/universal/.trae/skills/citable/rubrics/conversion-alignment.md +37 -0
  441. package/dist/universal/.trae/skills/citable/rubrics/entity-clarity.md +41 -0
  442. package/dist/universal/.trae/skills/citable/rubrics/evidence-strength.md +53 -0
  443. package/dist/universal/.trae/skills/citable/rubrics/information-gain.md +33 -0
  444. package/dist/universal/.trae/skills/citable/rubrics/intent-alignment.md +41 -0
  445. package/dist/universal/.trae/skills/citable/rubrics/narrative-accuracy.md +46 -0
  446. package/dist/universal/.trae/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  447. package/dist/universal/.trae/skills/citable/rubrics/semantic-clarity.md +42 -0
  448. package/dist/universal/.trae/skills/citable/rubrics/source-authority.md +37 -0
  449. package/dist/universal/.trae/skills/citable/schemas/claim.schema.json +53 -0
  450. package/dist/universal/.trae/skills/citable/schemas/common.defs.json +33 -0
  451. package/dist/universal/.trae/skills/citable/schemas/competitor.schema.json +28 -0
  452. package/dist/universal/.trae/skills/citable/schemas/config.schema.json +41 -0
  453. package/dist/universal/.trae/skills/citable/schemas/crawler.schema.json +33 -0
  454. package/dist/universal/.trae/skills/citable/schemas/detector-quality.schema.json +39 -0
  455. package/dist/universal/.trae/skills/citable/schemas/entity.schema.json +39 -0
  456. package/dist/universal/.trae/skills/citable/schemas/evidence.schema.json +41 -0
  457. package/dist/universal/.trae/skills/citable/schemas/experiment.schema.json +37 -0
  458. package/dist/universal/.trae/skills/citable/schemas/finding.schema.json +101 -0
  459. package/dist/universal/.trae/skills/citable/schemas/page.schema.json +40 -0
  460. package/dist/universal/.trae/skills/citable/schemas/project.schema.json +29 -0
  461. package/dist/universal/.trae/skills/citable/schemas/prompt-result.schema.json +37 -0
  462. package/dist/universal/.trae/skills/citable/schemas/prompt.schema.json +41 -0
  463. package/dist/universal/.trae/skills/citable/schemas/query.schema.json +43 -0
  464. package/dist/universal/.trae/skills/citable/schemas/run.schema.json +36 -0
  465. package/dist/universal/.trae/skills/citable/scripts/README.md +4 -0
  466. package/dist/universal/.trae/skills/citable/templates/finding-review.md +54 -0
  467. package/dist/universal/.trae-cn/skills/citable/SKILL.md +137 -0
  468. package/dist/universal/.trae-cn/skills/citable/VERSION +1 -0
  469. package/dist/universal/.trae-cn/skills/citable/commands/README.md +36 -0
  470. package/dist/universal/.trae-cn/skills/citable/commands/ingest.md +44 -0
  471. package/dist/universal/.trae-cn/skills/citable/commands/measurement.md +49 -0
  472. package/dist/universal/.trae-cn/skills/citable/commands/optimize-page.md +53 -0
  473. package/dist/universal/.trae-cn/skills/citable/commands/page-work.md +48 -0
  474. package/dist/universal/.trae-cn/skills/citable/commands/validate-render.md +24 -0
  475. package/dist/universal/.trae-cn/skills/citable/manifest.json +54 -0
  476. package/dist/universal/.trae-cn/skills/citable/policies/crawler-policy-template.md +47 -0
  477. package/dist/universal/.trae-cn/skills/citable/references/anti-patterns.md +61 -0
  478. package/dist/universal/.trae-cn/skills/citable/rubrics/README.md +30 -0
  479. package/dist/universal/.trae-cn/skills/citable/rubrics/answer-extractability.md +44 -0
  480. package/dist/universal/.trae-cn/skills/citable/rubrics/claim-boundedness.md +36 -0
  481. package/dist/universal/.trae-cn/skills/citable/rubrics/comparison-fairness.md +30 -0
  482. package/dist/universal/.trae-cn/skills/citable/rubrics/conversion-alignment.md +37 -0
  483. package/dist/universal/.trae-cn/skills/citable/rubrics/entity-clarity.md +41 -0
  484. package/dist/universal/.trae-cn/skills/citable/rubrics/evidence-strength.md +53 -0
  485. package/dist/universal/.trae-cn/skills/citable/rubrics/information-gain.md +33 -0
  486. package/dist/universal/.trae-cn/skills/citable/rubrics/intent-alignment.md +41 -0
  487. package/dist/universal/.trae-cn/skills/citable/rubrics/narrative-accuracy.md +46 -0
  488. package/dist/universal/.trae-cn/skills/citable/rubrics/recommendation-eligibility.md +36 -0
  489. package/dist/universal/.trae-cn/skills/citable/rubrics/semantic-clarity.md +42 -0
  490. package/dist/universal/.trae-cn/skills/citable/rubrics/source-authority.md +37 -0
  491. package/dist/universal/.trae-cn/skills/citable/schemas/claim.schema.json +53 -0
  492. package/dist/universal/.trae-cn/skills/citable/schemas/common.defs.json +33 -0
  493. package/dist/universal/.trae-cn/skills/citable/schemas/competitor.schema.json +28 -0
  494. package/dist/universal/.trae-cn/skills/citable/schemas/config.schema.json +41 -0
  495. package/dist/universal/.trae-cn/skills/citable/schemas/crawler.schema.json +33 -0
  496. package/dist/universal/.trae-cn/skills/citable/schemas/detector-quality.schema.json +39 -0
  497. package/dist/universal/.trae-cn/skills/citable/schemas/entity.schema.json +39 -0
  498. package/dist/universal/.trae-cn/skills/citable/schemas/evidence.schema.json +41 -0
  499. package/dist/universal/.trae-cn/skills/citable/schemas/experiment.schema.json +37 -0
  500. package/dist/universal/.trae-cn/skills/citable/schemas/finding.schema.json +101 -0
  501. package/dist/universal/.trae-cn/skills/citable/schemas/page.schema.json +40 -0
  502. package/dist/universal/.trae-cn/skills/citable/schemas/project.schema.json +29 -0
  503. package/dist/universal/.trae-cn/skills/citable/schemas/prompt-result.schema.json +37 -0
  504. package/dist/universal/.trae-cn/skills/citable/schemas/prompt.schema.json +41 -0
  505. package/dist/universal/.trae-cn/skills/citable/schemas/query.schema.json +43 -0
  506. package/dist/universal/.trae-cn/skills/citable/schemas/run.schema.json +36 -0
  507. package/dist/universal/.trae-cn/skills/citable/scripts/README.md +4 -0
  508. package/dist/universal/.trae-cn/skills/citable/templates/finding-review.md +54 -0
  509. package/dist/universal/manifest.json +598 -0
  510. package/package.json +89 -0
  511. package/schemas/claim.schema.json +53 -0
  512. package/schemas/common.defs.json +33 -0
  513. package/schemas/competitor.schema.json +28 -0
  514. package/schemas/config.schema.json +41 -0
  515. package/schemas/crawler.schema.json +33 -0
  516. package/schemas/detector-quality.schema.json +39 -0
  517. package/schemas/entity.schema.json +39 -0
  518. package/schemas/evidence.schema.json +41 -0
  519. package/schemas/experiment.schema.json +37 -0
  520. package/schemas/finding.schema.json +101 -0
  521. package/schemas/page.schema.json +40 -0
  522. package/schemas/project.schema.json +29 -0
  523. package/schemas/prompt-result.schema.json +37 -0
  524. package/schemas/prompt.schema.json +41 -0
  525. package/schemas/query.schema.json +43 -0
  526. package/schemas/run.schema.json +36 -0
  527. package/scripts/build-dist.js +143 -0
  528. package/skill/SKILL.md +137 -0
  529. package/skill/commands/README.md +36 -0
  530. package/skill/commands/ingest.md +44 -0
  531. package/skill/commands/measurement.md +49 -0
  532. package/skill/commands/optimize-page.md +53 -0
  533. package/skill/commands/page-work.md +48 -0
  534. package/skill/commands/validate-render.md +24 -0
  535. package/skill/policies/crawler-policy-template.md +47 -0
  536. package/skill/references/anti-patterns.md +61 -0
  537. package/skill/rubrics/README.md +30 -0
  538. package/skill/rubrics/answer-extractability.md +44 -0
  539. package/skill/rubrics/claim-boundedness.md +36 -0
  540. package/skill/rubrics/comparison-fairness.md +30 -0
  541. package/skill/rubrics/conversion-alignment.md +37 -0
  542. package/skill/rubrics/entity-clarity.md +41 -0
  543. package/skill/rubrics/evidence-strength.md +53 -0
  544. package/skill/rubrics/information-gain.md +33 -0
  545. package/skill/rubrics/intent-alignment.md +41 -0
  546. package/skill/rubrics/narrative-accuracy.md +46 -0
  547. package/skill/rubrics/recommendation-eligibility.md +36 -0
  548. package/skill/rubrics/semantic-clarity.md +42 -0
  549. package/skill/rubrics/source-authority.md +37 -0
  550. package/skill/templates/finding-review.md +54 -0
  551. package/src/cli/index.js +135 -0
  552. package/src/commands/audit.js +111 -0
  553. package/src/commands/compareSnapshots.js +48 -0
  554. package/src/commands/context.js +62 -0
  555. package/src/commands/init.js +111 -0
  556. package/src/commands/inspect.js +61 -0
  557. package/src/commands/mapClaims.js +89 -0
  558. package/src/commands/schemaCmd.js +71 -0
  559. package/src/commands/substantiate.js +121 -0
  560. package/src/commands/validate.js +27 -0
  561. package/src/crawler/fetch.js +31 -0
  562. package/src/crawler/robots.js +67 -0
  563. package/src/crawler/sitemap.js +25 -0
  564. package/src/detectors/ans.js +219 -0
  565. package/src/detectors/arch.js +154 -0
  566. package/src/detectors/claim.js +230 -0
  567. package/src/detectors/crawl.js +143 -0
  568. package/src/detectors/entity.js +202 -0
  569. package/src/detectors/evd.js +164 -0
  570. package/src/detectors/framework.js +137 -0
  571. package/src/detectors/geoReco.js +218 -0
  572. package/src/detectors/index.js +50 -0
  573. package/src/detectors/lifeMeas.js +212 -0
  574. package/src/detectors/link.js +121 -0
  575. package/src/detectors/page.js +202 -0
  576. package/src/detectors/schemaData.js +249 -0
  577. package/src/detectors/tech.js +397 -0
  578. package/src/evidence/run.js +88 -0
  579. package/src/extractor/page.js +125 -0
  580. package/src/extractor/site.js +175 -0
  581. package/src/installer/index.js +1117 -0
  582. package/src/installer/providers.js +164 -0
  583. package/src/registries/index.js +127 -0
  584. package/src/reporting/report.js +82 -0
  585. package/src/shared/io.js +56 -0
  586. package/src/shared/schemaValidator.js +29 -0
@@ -0,0 +1,397 @@
1
+ import { defineDetector, indexTargets, registryPageFor, pageSubject, safePath } from './framework.js';
2
+ import { isAllowed } from '../crawler/robots.js';
3
+
4
+ const D = [];
5
+
6
+ D.push(defineDetector({
7
+ id: 'TECH-001', name: 'Non-200 index-target URL', namespace: 'TECH',
8
+ description: 'A page intended for indexing does not return HTTP 200.',
9
+ discipline: ['seo', 'aeo', 'geo'], severity: 'critical', deterministic: true, requires: ['site'],
10
+ impact: { retrieval: 'high', ranking: 'high', citation: 'high' },
11
+ applicable_requirement: 'SEO §2 required URL-level conditions; AEO §2 required indexing controls; GEO §2 required technical conditions',
12
+ remediation: 'Restore a 200 response for the canonical URL, or update the page registry if the URL is intentionally retired (with a redirect to its successor).',
13
+ verification: 'Fetch the URL and confirm HTTP 200.',
14
+ check(ctx) {
15
+ return indexTargets(ctx).filter((p) => p.status !== 200).map((p) => ({
16
+ subject: pageSubject(p),
17
+ summary: `Index-target URL returns HTTP ${p.status}`,
18
+ evidence: [`HTTP status ${p.status} observed for ${p.url}`],
19
+ captured: p.status, expected: 200,
20
+ }));
21
+ },
22
+ }));
23
+
24
+ D.push(defineDetector({
25
+ id: 'TECH-002', name: 'Accidental noindex on index-target page', namespace: 'TECH',
26
+ description: 'A page whose registry intent is "index" carries a noindex directive (meta robots or X-Robots-Tag).',
27
+ discipline: ['seo', 'aeo', 'geo'], severity: 'critical', deterministic: true, requires: ['site'],
28
+ impact: { retrieval: 'high', ranking: 'high', citation: 'high' },
29
+ applicable_requirement: 'SEO §2 crawl controls; AEO §2 no accidental noindex',
30
+ remediation: 'Remove the noindex directive, or set indexing_intent: noindex in the page registry if exclusion is intended.',
31
+ verification: 'Re-extract robots directives from the rendered page and response headers.',
32
+ check(ctx) {
33
+ return indexTargets(ctx).filter((p) => p.noindex).map((p) => ({
34
+ subject: pageSubject(p),
35
+ summary: 'Index-target page carries a noindex directive',
36
+ evidence: [`robots directives: ${p.robotsDirectives.join(', ')}`],
37
+ captured: p.robotsDirectives, expected: 'indexable directives',
38
+ }));
39
+ },
40
+ }));
41
+
42
+ D.push(defineDetector({
43
+ id: 'TECH-003', name: 'robots.txt blocks index-target page', namespace: 'TECH',
44
+ description: 'robots.txt disallows a search crawler from fetching a page that is intended to be indexed and cited.',
45
+ discipline: ['seo', 'aeo', 'geo'], severity: 'critical', deterministic: true, requires: ['site'],
46
+ impact: { retrieval: 'high', ranking: 'high', citation: 'high' },
47
+ applicable_requirement: 'SEO §2 critical distinction (robots.txt vs noindex); AEO §2 required crawler access',
48
+ remediation: 'Remove or narrow the disallow rule for the affected path; use noindex (not robots.txt) when removal from search is the objective.',
49
+ verification: 'Evaluate the robots.txt group matching the crawler against the URL path.',
50
+ check(ctx) {
51
+ if (!ctx.site.robots) return [];
52
+ const hits = [];
53
+ for (const p of indexTargets(ctx)) {
54
+ const verdict = isAllowed(ctx.site.robots, 'Googlebot', safePath(p.url));
55
+ if (!verdict.allowed) {
56
+ hits.push({
57
+ subject: pageSubject(p),
58
+ summary: `robots.txt blocks Googlebot from index-target path (${verdict.rule})`,
59
+ evidence: [`matched rule: ${verdict.rule}`],
60
+ captured: verdict.rule, expected: 'allow',
61
+ });
62
+ }
63
+ }
64
+ return hits;
65
+ },
66
+ }));
67
+
68
+ D.push(defineDetector({
69
+ id: 'TECH-004', name: 'Multiple conflicting canonical declarations', namespace: 'TECH',
70
+ description: 'A document declares more than one rel=canonical with differing targets.',
71
+ discipline: ['seo', 'aeo'], severity: 'high', deterministic: true, requires: ['site'],
72
+ impact: { retrieval: 'medium', ranking: 'high' },
73
+ applicable_requirement: 'SEO §2 canonicalization: common canonical failures',
74
+ remediation: 'Emit exactly one canonical link element per document, generated from the authoritative URL field.',
75
+ verification: 'Count canonical link elements in rendered HTML.',
76
+ check(ctx) {
77
+ return ctx.site.pages.filter((p) => new Set(p.canonicals).size > 1).map((p) => ({
78
+ subject: pageSubject(p),
79
+ summary: `Document declares ${p.canonicals.length} canonical URLs`,
80
+ evidence: p.canonicals.map((c) => `rel=canonical → ${c}`),
81
+ captured: p.canonicals, expected: 'one canonical',
82
+ }));
83
+ },
84
+ }));
85
+
86
+ D.push(defineDetector({
87
+ id: 'TECH-005', name: 'Canonical points to redirect', namespace: 'TECH',
88
+ description: 'rel=canonical targets a URL that itself redirects.',
89
+ discipline: ['seo', 'aeo'], severity: 'high', deterministic: true, requires: ['site'],
90
+ impact: { retrieval: 'medium', ranking: 'high' },
91
+ applicable_requirement: 'SEO §2 canonical failures: canonical points to a redirect',
92
+ remediation: 'Point the canonical at the final 200 destination.',
93
+ verification: 'Resolve the canonical target and confirm a direct 200.',
94
+ check(ctx) {
95
+ return canonicalTargetProblem(ctx, (t) => t.status >= 300 && t.status < 400, 'redirect');
96
+ },
97
+ }));
98
+
99
+ D.push(defineDetector({
100
+ id: 'TECH-006', name: 'Canonical points to error page', namespace: 'TECH',
101
+ description: 'rel=canonical targets a URL returning 4xx/5xx.',
102
+ discipline: ['seo', 'aeo'], severity: 'high', deterministic: true, requires: ['site'],
103
+ impact: { retrieval: 'high', ranking: 'high' },
104
+ applicable_requirement: 'SEO §2 canonical failures: canonical target returns an error',
105
+ remediation: 'Point the canonical at a live 200 URL.',
106
+ verification: 'Resolve the canonical target and confirm HTTP 200.',
107
+ check(ctx) {
108
+ return canonicalTargetProblem(ctx, (t) => t.status >= 400, 'error status');
109
+ },
110
+ }));
111
+
112
+ D.push(defineDetector({
113
+ id: 'TECH-007', name: 'Canonical points to noindex page', namespace: 'TECH',
114
+ description: 'rel=canonical consolidates signals into a URL that is itself noindexed.',
115
+ discipline: ['seo', 'aeo'], severity: 'high', deterministic: true, requires: ['site'],
116
+ impact: { retrieval: 'high', ranking: 'high' },
117
+ applicable_requirement: 'SEO §2 canonical failures: canonical target is noindex',
118
+ remediation: 'Either make the canonical target indexable or choose an indexable canonical.',
119
+ verification: 'Check robots directives on the canonical target.',
120
+ check(ctx) {
121
+ return canonicalTargetProblem(ctx, (t) => t.noindex, 'noindex target');
122
+ },
123
+ }));
124
+
125
+ D.push(defineDetector({
126
+ id: 'TECH-008', name: 'Sitemap contains redirecting URL', namespace: 'TECH',
127
+ description: 'An XML sitemap lists a URL that does not resolve directly with HTTP 200 (redirects).',
128
+ discipline: ['seo', 'aeo'], severity: 'medium', deterministic: true, requires: ['site'],
129
+ impact: { retrieval: 'medium', ranking: 'low' },
130
+ applicable_requirement: 'SEO §2: sitemap contains redirect',
131
+ remediation: 'Regenerate sitemaps from the canonical URL set only.',
132
+ verification: 'Fetch each sitemap URL and confirm direct 200 responses.',
133
+ check(ctx) {
134
+ return sitemapEntryProblem(ctx, (p) => p.status >= 300 && p.status < 400, 'redirects');
135
+ },
136
+ }));
137
+
138
+ D.push(defineDetector({
139
+ id: 'TECH-009', name: 'Sitemap contains non-canonical URL', namespace: 'TECH',
140
+ description: 'A sitemap lists a URL whose page declares a different canonical.',
141
+ discipline: ['seo', 'aeo'], severity: 'medium', deterministic: true, requires: ['site'],
142
+ impact: { ranking: 'medium' },
143
+ applicable_requirement: 'SEO §2 canonical signals should agree across sitemap entries',
144
+ remediation: 'List only canonical URLs in sitemaps.',
145
+ verification: 'Compare each sitemap URL with the canonical declared on the page it resolves to.',
146
+ check(ctx) {
147
+ const hits = [];
148
+ for (const sm of ctx.site.sitemaps) {
149
+ for (const u of sm.parsed.urls) {
150
+ const page = ctx.site.byUrl.get(ctx.site.normalize(u.loc));
151
+ if (!page || page.canonicals.length === 0) continue;
152
+ const canon = page.canonicals[0];
153
+ if (safePath(canon, ctx.site.baseUrl) !== safePath(u.loc, ctx.site.baseUrl)) {
154
+ hits.push({
155
+ subject: { type: 'url', identifier: u.loc, url: u.loc, source_location: sm.source },
156
+ summary: `Sitemap lists non-canonical URL (page canonical: ${canon})`,
157
+ evidence: [`sitemap ${sm.source} lists ${u.loc}`, `page declares canonical ${canon}`],
158
+ captured: u.loc, expected: canon,
159
+ });
160
+ }
161
+ }
162
+ }
163
+ return hits;
164
+ },
165
+ }));
166
+
167
+ D.push(defineDetector({
168
+ id: 'TECH-010', name: 'Sitemap URL unresolvable or errors', namespace: 'TECH',
169
+ description: 'A sitemap lists a URL that is missing from the built output or returns an error.',
170
+ discipline: ['seo', 'aeo'], severity: 'medium', deterministic: true, requires: ['site'],
171
+ impact: { retrieval: 'medium' },
172
+ applicable_requirement: 'SEO §2 sitemap processing; clean sitemap coverage (§15)',
173
+ remediation: 'Regenerate sitemaps from live canonical URLs; remove retired URLs.',
174
+ verification: 'Resolve every sitemap URL against the built output or deployed site.',
175
+ check(ctx) {
176
+ const hits = [];
177
+ for (const sm of ctx.site.sitemaps) {
178
+ for (const u of sm.parsed.urls) {
179
+ const page = ctx.site.byUrl.get(ctx.site.normalize(u.loc));
180
+ if (!page) {
181
+ hits.push({
182
+ subject: { type: 'url', identifier: u.loc, url: u.loc, source_location: sm.source },
183
+ summary: 'Sitemap URL not present in audited output',
184
+ evidence: [`sitemap ${sm.source} lists ${u.loc}; no matching page found`],
185
+ });
186
+ } else if (page.status >= 400) {
187
+ hits.push({
188
+ subject: { type: 'url', identifier: u.loc, url: u.loc, source_location: sm.source },
189
+ summary: `Sitemap URL returns HTTP ${page.status}`,
190
+ evidence: [`sitemap ${sm.source} lists ${u.loc}; observed status ${page.status}`],
191
+ });
192
+ }
193
+ }
194
+ }
195
+ return hits;
196
+ },
197
+ }));
198
+
199
+ D.push(defineDetector({
200
+ id: 'TECH-011', name: 'Render-dependent primary content', namespace: 'TECH',
201
+ description: 'Initial HTML contains almost no primary text relative to script payload; principal content likely requires client-side rendering.',
202
+ discipline: ['seo', 'aeo', 'geo'], severity: 'high', deterministic: false, requires: ['site'],
203
+ impact: { retrieval: 'high', citation: 'high' },
204
+ applicable_requirement: 'SEO §2 rendering; AEO §2 rendering requirements; GEO §2 server-rendered principal content',
205
+ false_positive_conditions: ['intentionally minimal pages (e.g., app shells excluded from indexing)'],
206
+ remediation: 'Server-render or statically generate the principal content so it exists in initial HTML.',
207
+ verification: 'Compare extracted text of raw HTML against rendered output.',
208
+ check(ctx) {
209
+ return indexTargets(ctx)
210
+ .filter((p) => p.status === 200 && p.wordCount < 40 && p.scriptBytes > 2000)
211
+ .map((p) => ({
212
+ subject: pageSubject(p),
213
+ summary: `Initial HTML has ~${p.wordCount} words but ${p.scriptBytes} bytes of script; primary content appears render-dependent`,
214
+ evidence: [`extracted word count: ${p.wordCount}`, `inline/external script text bytes: ${p.scriptBytes}`],
215
+ confidence: 'medium',
216
+ }));
217
+ },
218
+ }));
219
+
220
+ D.push(defineDetector({
221
+ id: 'TECH-012', name: 'Invalid MIME type for HTML page', namespace: 'TECH',
222
+ description: 'An index-target page is served with a non-HTML content type.',
223
+ discipline: ['seo'], severity: 'high', deterministic: true, requires: ['site'],
224
+ impact: { retrieval: 'high' },
225
+ applicable_requirement: 'SEO §2 correct MIME type',
226
+ remediation: 'Serve HTML documents with Content-Type: text/html.',
227
+ verification: 'Inspect the Content-Type response header.',
228
+ check(ctx) {
229
+ return indexTargets(ctx)
230
+ .filter((p) => p.status === 200 && p.contentType && !p.contentType.includes('text/html'))
231
+ .map((p) => ({
232
+ subject: pageSubject(p),
233
+ summary: `HTML page served with Content-Type "${p.contentType}"`,
234
+ evidence: [`content-type: ${p.contentType}`],
235
+ captured: p.contentType, expected: 'text/html',
236
+ }));
237
+ },
238
+ }));
239
+
240
+ D.push(defineDetector({
241
+ id: 'TECH-013', name: 'Redirect chain', namespace: 'TECH',
242
+ description: 'Reaching the final URL required more than one redirect hop.',
243
+ discipline: ['seo'], severity: 'medium', deterministic: true, requires: ['site'],
244
+ impact: { retrieval: 'medium', ranking: 'low' },
245
+ applicable_requirement: 'SEO §2 no redirect chain',
246
+ remediation: 'Collapse redirect chains so every legacy URL redirects directly to the final destination.',
247
+ verification: 'Follow redirects and count hops.',
248
+ check(ctx) {
249
+ return ctx.site.pages.filter((p) => (p.redirectChain?.length || 0) > 1).map((p) => ({
250
+ subject: pageSubject(p),
251
+ summary: `Redirect chain of ${p.redirectChain.length} hops`,
252
+ evidence: p.redirectChain.map((r) => `${r.status} ${r.url} → ${r.location}`),
253
+ }));
254
+ },
255
+ }));
256
+
257
+ D.push(defineDetector({
258
+ id: 'TECH-014', name: 'Soft-404 behaviour', namespace: 'TECH',
259
+ description: 'A page returns 200 but its content indicates the resource does not exist.',
260
+ discipline: ['seo'], severity: 'medium', deterministic: false, requires: ['site'],
261
+ impact: { retrieval: 'medium', ranking: 'medium' },
262
+ applicable_requirement: 'SEO §2 no soft-404 behaviour',
263
+ false_positive_conditions: ['pages legitimately discussing 404 handling or error pages'],
264
+ remediation: 'Return a real 404/410 status for missing resources.',
265
+ verification: 'Check the HTTP status of the affected URL.',
266
+ check(ctx) {
267
+ const rx = /\b(page not found|404 not found|this page (does not|doesn't) exist|nothing (was )?found here)\b/i;
268
+ return ctx.site.pages
269
+ .filter((p) => p.status === 200 && p.wordCount < 120 && (rx.test(p.title || '') || rx.test(p.text)))
270
+ .map((p) => ({
271
+ subject: pageSubject(p),
272
+ summary: 'Page returns 200 but content indicates "not found" (soft 404)',
273
+ evidence: [`title: ${p.title}`, `matched not-found phrasing in a ${p.wordCount}-word page`],
274
+ confidence: 'medium',
275
+ }));
276
+ },
277
+ }));
278
+
279
+ D.push(defineDetector({
280
+ id: 'TECH-015', name: 'Staging or preview host exposed as indexable', namespace: 'TECH',
281
+ description: 'The audited base URL looks like a staging/preview environment yet pages are indexable.',
282
+ discipline: ['seo'], severity: 'critical', deterministic: false, requires: ['site'],
283
+ impact: { retrieval: 'high', ranking: 'high', reputational: 'medium' },
284
+ applicable_requirement: 'SEO §2 staging environments; §12 staging environment protection',
285
+ false_positive_conditions: ['production hosts that legitimately contain words like "preview" in the brand'],
286
+ remediation: 'Add noindex + authentication to non-production environments.',
287
+ verification: 'Check robots directives and access controls on the staging host.',
288
+ check(ctx) {
289
+ let host;
290
+ try { host = new URL(ctx.site.baseUrl).hostname; } catch { return []; }
291
+ const labels = host.split('.').slice(0, -1); // TLDs like .test/.dev are not staging signals
292
+ if (!labels.some((l) => /(^|-)(staging|stage|preview|dev|test|uat)(-|$)/i.test(l))) return [];
293
+ const indexable = ctx.site.pages.filter((p) => !p.noindex && p.status === 200);
294
+ if (indexable.length === 0) return [];
295
+ return [{
296
+ subject: { type: 'site', identifier: ctx.site.baseUrl, url: ctx.site.baseUrl },
297
+ summary: `Host "${host}" resembles a non-production environment and serves ${indexable.length} indexable page(s)`,
298
+ evidence: [`hostname: ${host}`, `indexable pages: ${indexable.slice(0, 5).map((p) => p.url).join(', ')}`],
299
+ confidence: 'medium',
300
+ }];
301
+ },
302
+ }));
303
+
304
+ D.push(defineDetector({
305
+ id: 'TECH-016', name: 'Missing sitemap', namespace: 'TECH',
306
+ description: 'No XML sitemap was found for the audited output.',
307
+ discipline: ['seo', 'aeo'], severity: 'medium', deterministic: true, requires: ['site'],
308
+ impact: { retrieval: 'medium' },
309
+ applicable_requirement: 'SEO §2 inclusion in the appropriate XML sitemap; AEO §2 sitemap architecture',
310
+ remediation: 'Generate an XML sitemap covering all canonical index-target URLs and reference it from robots.txt.',
311
+ verification: 'Confirm sitemap presence and robots.txt Sitemap directive.',
312
+ check(ctx) {
313
+ if (ctx.site.sitemaps.length > 0) return [];
314
+ return [{
315
+ subject: { type: 'site', identifier: ctx.site.baseUrl, url: ctx.site.baseUrl },
316
+ summary: 'No XML sitemap found',
317
+ evidence: ['no sitemap*.xml present in audited output and none referenced from robots.txt'],
318
+ }];
319
+ },
320
+ }));
321
+
322
+ D.push(defineDetector({
323
+ id: 'TECH-017', name: 'Snippet suppression on citation-target page', namespace: 'TECH',
324
+ description: 'A page targeted for answer citation carries nosnippet or max-snippet:0, which removes snippet eligibility that generative search features depend on.',
325
+ discipline: ['aeo', 'geo'], severity: 'high', deterministic: true, requires: ['site'],
326
+ impact: { citation: 'high', representation: 'medium' },
327
+ applicable_requirement: 'AEO §2 no restrictive nosnippet; GEO §2 snippet eligibility',
328
+ remediation: 'Remove nosnippet/max-snippet:0 from citation-target pages, or record an explicit decision that snippet suppression is intended.',
329
+ verification: 'Re-extract robots directives.',
330
+ check(ctx) {
331
+ return indexTargets(ctx).filter((p) => p.nosnippet).map((p) => ({
332
+ subject: pageSubject(p),
333
+ summary: 'Citation-target page suppresses snippets',
334
+ evidence: [`robots directives: ${p.robotsDirectives.join(', ')}`],
335
+ }));
336
+ },
337
+ }));
338
+
339
+ D.push(defineDetector({
340
+ id: 'TECH-018', name: 'Missing viewport (mobile readiness)', namespace: 'TECH',
341
+ description: 'Page lacks a viewport meta tag, a minimum condition for mobile parity.',
342
+ discipline: ['seo'], severity: 'low', deterministic: true, requires: ['site'],
343
+ impact: { ranking: 'low' },
344
+ applicable_requirement: 'SEO §2 mobile-first requirements (proxy check; full parity requires dual rendering)',
345
+ false_negative_conditions: ['viewport present but mobile content still diverges — requires rendered comparison, not covered here'],
346
+ remediation: 'Add a responsive viewport meta tag; verify mobile content parity separately.',
347
+ verification: 'Check for meta[name=viewport] in rendered HTML.',
348
+ check(ctx) {
349
+ return indexTargets(ctx)
350
+ .filter((p) => p.status === 200 && !p.viewportMeta)
351
+ .map((p) => ({
352
+ subject: pageSubject(p),
353
+ summary: 'No viewport meta tag; mobile rendering readiness not established',
354
+ evidence: ['meta[name=viewport] absent from document head'],
355
+ }));
356
+ },
357
+ }));
358
+
359
+ export function canonicalTargetProblem(ctx, predicate, label) {
360
+ const hits = [];
361
+ for (const p of ctx.site.pages) {
362
+ for (const c of p.canonicals) {
363
+ let target;
364
+ try {
365
+ target = ctx.site.byUrl.get(ctx.site.normalize(new URL(c, p.url).href));
366
+ } catch { continue; }
367
+ if (target && target !== p && predicate(target)) {
368
+ hits.push({
369
+ subject: pageSubject(p),
370
+ summary: `Canonical points to ${label} (${c})`,
371
+ evidence: [`rel=canonical → ${c}`, `target status: ${target.status}${target.noindex ? ', noindex' : ''}`],
372
+ captured: c,
373
+ });
374
+ }
375
+ }
376
+ }
377
+ return hits;
378
+ }
379
+
380
+ function sitemapEntryProblem(ctx, predicate, label) {
381
+ const hits = [];
382
+ for (const sm of ctx.site.sitemaps) {
383
+ for (const u of sm.parsed.urls) {
384
+ const page = ctx.site.byUrl.get(ctx.site.normalize(u.loc));
385
+ if (page && predicate(page)) {
386
+ hits.push({
387
+ subject: { type: 'url', identifier: u.loc, url: u.loc, source_location: sm.source },
388
+ summary: `Sitemap URL ${label} (status ${page.status})`,
389
+ evidence: [`sitemap ${sm.source} lists ${u.loc}; observed status ${page.status}`],
390
+ });
391
+ }
392
+ }
393
+ }
394
+ return hits;
395
+ }
396
+
397
+ export default D;
@@ -0,0 +1,88 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import { execSync } from 'node:child_process';
4
+ import { writeJson, sha256, sha256File, nowIso } from '../shared/io.js';
5
+ import { validateAgainst } from '../shared/schemaValidator.js';
6
+ import { readJson } from '../shared/io.js';
7
+ import { fileURLToPath } from 'node:url';
8
+
9
+ const PKG = readJson(path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../../package.json'));
10
+
11
+ export function newRunId(command) {
12
+ const t = new Date().toISOString().replace(/[-:]/g, '').replace(/\..*/, '');
13
+ return `${t}-${command.replace(/\s+/g, '-')}-${Math.random().toString(36).slice(2, 6)}`;
14
+ }
15
+
16
+ function gitInfo(root) {
17
+ try {
18
+ const commit = execSync('git rev-parse HEAD', { cwd: root, stdio: ['pipe', 'pipe', 'ignore'] }).toString().trim();
19
+ const dirty = execSync('git status --porcelain', { cwd: root, stdio: ['pipe', 'pipe', 'ignore'] }).toString().trim().length > 0;
20
+ return { commit, state: dirty ? 'dirty' : 'clean' };
21
+ } catch {
22
+ return { commit: null, state: null };
23
+ }
24
+ }
25
+
26
+ /** Create a run evidence package under <root>/.citable/runs/<run-id>/. */
27
+ export function createRun(root, { command, argv = [], target, locale = process.env.LANG || 'en', jurisdiction = null, configHash = null }) {
28
+ const runId = newRunId(command);
29
+ const dir = path.join(root, '.citable', 'runs', runId);
30
+ fs.mkdirSync(dir, { recursive: true });
31
+ const git = gitInfo(root);
32
+ const manifest = {
33
+ run_id: runId,
34
+ command,
35
+ argv,
36
+ tool_version: PKG.version,
37
+ skill_version: PKG.version,
38
+ repository_commit: git.commit,
39
+ working_tree_state: git.state,
40
+ target,
41
+ timestamp: nowIso(),
42
+ locale,
43
+ jurisdiction,
44
+ configuration_hash: configHash,
45
+ input_hashes: {},
46
+ output_hashes: {},
47
+ detectors_run: [],
48
+ detectors_skipped: [],
49
+ incomplete_checks: [],
50
+ errors: [],
51
+ warnings: [],
52
+ status: 'incomplete',
53
+ };
54
+ return {
55
+ runId,
56
+ dir,
57
+ manifest,
58
+ addInput(name, content) {
59
+ manifest.input_hashes[name] = sha256(typeof content === 'string' ? content : JSON.stringify(content));
60
+ },
61
+ writeArtifact(relPath, data) {
62
+ const file = path.join(dir, relPath);
63
+ fs.mkdirSync(path.dirname(file), { recursive: true });
64
+ if (typeof data === 'string') fs.writeFileSync(file, data);
65
+ else writeJson(file, data);
66
+ manifest.output_hashes[relPath] = sha256File(file);
67
+ return file;
68
+ },
69
+ finalize(status) {
70
+ manifest.status = status;
71
+ const { valid, errors } = validateAgainst('run.schema.json', manifest);
72
+ if (!valid) throw new Error(`run manifest invalid: ${errors.join('; ')}`);
73
+ writeJson(path.join(dir, 'manifest.json'), manifest);
74
+ // checksums over every artifact in the package
75
+ const checksums = {};
76
+ const walk = (d) => {
77
+ for (const name of fs.readdirSync(d)) {
78
+ const p = path.join(d, name);
79
+ if (fs.statSync(p).isDirectory()) walk(p);
80
+ else if (name !== 'checksums.json') checksums[path.relative(dir, p)] = sha256File(p);
81
+ }
82
+ };
83
+ walk(dir);
84
+ writeJson(path.join(dir, 'checksums.json'), checksums);
85
+ return dir;
86
+ },
87
+ };
88
+ }
@@ -0,0 +1,125 @@
1
+ import { parse } from 'node-html-parser';
2
+
3
+ /**
4
+ * Extract a PageModel from raw HTML plus transport metadata.
5
+ * Everything downstream (detectors, inspect, schema) consumes this model.
6
+ */
7
+ export function extractPage({ url, html, status = 200, headers = {}, sourceFile = null, redirectChain = [] }) {
8
+ const root = parse(html, { comment: true });
9
+ const head = root.querySelector('head');
10
+
11
+ const metas = {};
12
+ for (const m of root.querySelectorAll('meta')) {
13
+ const name = (m.getAttribute('name') || m.getAttribute('property') || '').toLowerCase();
14
+ if (name) (metas[name] ||= []).push(m.getAttribute('content') ?? '');
15
+ }
16
+
17
+ const canonicals = root
18
+ .querySelectorAll('link[rel=canonical]')
19
+ .map((l) => l.getAttribute('href'))
20
+ .filter(Boolean);
21
+
22
+ const robotsMetaRaw = [...(metas['robots'] || []), ...(metas['googlebot'] || [])].join(',').toLowerCase();
23
+ const xRobots = String(headers['x-robots-tag'] || '').toLowerCase();
24
+ const robotsDirectives = new Set(
25
+ (robotsMetaRaw + ',' + xRobots)
26
+ .split(',')
27
+ .map((s) => s.trim())
28
+ .filter(Boolean)
29
+ );
30
+
31
+ const headings = [];
32
+ for (const h of root.querySelectorAll('h1,h2,h3,h4,h5,h6')) {
33
+ headings.push({ level: Number(h.tagName[1]), text: h.text.trim() });
34
+ }
35
+
36
+ const links = root.querySelectorAll('a').map((a) => ({
37
+ href: a.getAttribute('href') || '',
38
+ text: a.text.trim(),
39
+ rel: (a.getAttribute('rel') || '').toLowerCase(),
40
+ }));
41
+
42
+ const images = root.querySelectorAll('img').map((i) => ({
43
+ src: i.getAttribute('src') || '',
44
+ alt: i.getAttribute('alt'),
45
+ }));
46
+
47
+ const jsonLd = [];
48
+ for (const s of root.querySelectorAll('script[type="application/ld+json"]')) {
49
+ const raw = s.text;
50
+ try {
51
+ const parsed = JSON.parse(raw);
52
+ const blocks = Array.isArray(parsed) ? parsed : parsed['@graph'] ? parsed['@graph'] : [parsed];
53
+ jsonLd.push({ raw, parsed, blocks, parseError: null });
54
+ } catch (err) {
55
+ jsonLd.push({ raw, parsed: null, blocks: [], parseError: err.message });
56
+ }
57
+ }
58
+
59
+ const body = root.querySelector('body');
60
+ // Strip script/style/nav/footer noise for main-text estimation
61
+ const bodyClone = body ? parse(body.outerHTML) : null;
62
+ if (bodyClone) for (const s of bodyClone.querySelectorAll('script,style,noscript,nav,footer,header[role=banner]')) s.remove();
63
+ const text = bodyClone ? bodyClone.text.replace(/\s+/g, ' ').trim() : '';
64
+ const paragraphs = bodyClone
65
+ ? bodyClone.querySelectorAll('p').map((p) => p.text.replace(/\s+/g, ' ').trim()).filter((t) => t.length > 0)
66
+ : [];
67
+
68
+ const scriptBytes = root.querySelectorAll('script').reduce((n, s) => n + (s.text?.length || 0), 0);
69
+
70
+ // Ordered/unordered lists and tables (answer-structure signals)
71
+ const orderedLists = root.querySelectorAll('ol').length;
72
+ const tables = root.querySelectorAll('table').length;
73
+
74
+ // Hidden-text capture for prompt-injection detection
75
+ const hiddenTexts = [];
76
+ for (const el of root.querySelectorAll('[hidden],[aria-hidden=true],[style]')) {
77
+ const style = (el.getAttribute('style') || '').toLowerCase().replace(/\s/g, '');
78
+ const isHidden =
79
+ el.hasAttribute('hidden') ||
80
+ el.getAttribute('aria-hidden') === 'true' ||
81
+ style.includes('display:none') ||
82
+ style.includes('visibility:hidden') ||
83
+ /font-size:0(px|;|$)/.test(style) ||
84
+ style.includes('opacity:0;') || style.endsWith('opacity:0');
85
+ if (isHidden) {
86
+ const t = el.text.replace(/\s+/g, ' ').trim();
87
+ if (t) hiddenTexts.push(t);
88
+ }
89
+ }
90
+ for (const c of root.querySelectorAll('*')) {
91
+ // comments handled below via rawHtml scan in detectors
92
+ }
93
+
94
+ return {
95
+ url,
96
+ sourceFile,
97
+ status,
98
+ headers,
99
+ redirectChain,
100
+ contentType: String(headers['content-type'] || ''),
101
+ rawHtml: html,
102
+ title: head?.querySelector('title')?.text.trim() ?? root.querySelector('title')?.text.trim() ?? null,
103
+ metaDescription: metas['description']?.[0] ?? null,
104
+ metas,
105
+ canonicals,
106
+ robotsDirectives: [...robotsDirectives],
107
+ noindex: robotsDirectives.has('noindex') || robotsDirectives.has('none'),
108
+ nosnippet: robotsDirectives.has('nosnippet') || [...robotsDirectives].some((d) => /^max-snippet:\s*0$/.test(d)),
109
+ lang: root.querySelector('html')?.getAttribute('lang') ?? null,
110
+ viewportMeta: metas['viewport']?.[0] ?? null,
111
+ ogUrl: metas['og:url']?.[0] ?? null,
112
+ headings,
113
+ h1s: headings.filter((h) => h.level === 1),
114
+ links,
115
+ images,
116
+ jsonLd,
117
+ text,
118
+ paragraphs,
119
+ wordCount: text ? text.split(/\s+/).length : 0,
120
+ scriptBytes,
121
+ orderedLists,
122
+ tables,
123
+ hiddenTexts,
124
+ };
125
+ }