@tiangong-lca/pcr 0.0.0-stage → 0.2.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 (581) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +5 -0
  3. package/README.md +107 -2
  4. package/node_modules/ajv/.runkit_example.js +23 -0
  5. package/node_modules/ajv/LICENSE +22 -0
  6. package/node_modules/ajv/README.md +207 -0
  7. package/node_modules/ajv/dist/2019.d.ts +19 -0
  8. package/node_modules/ajv/dist/2019.js +61 -0
  9. package/node_modules/ajv/dist/2019.js.map +1 -0
  10. package/node_modules/ajv/dist/2020.d.ts +19 -0
  11. package/node_modules/ajv/dist/2020.js +55 -0
  12. package/node_modules/ajv/dist/2020.js.map +1 -0
  13. package/node_modules/ajv/dist/ajv.d.ts +18 -0
  14. package/node_modules/ajv/dist/ajv.js +50 -0
  15. package/node_modules/ajv/dist/ajv.js.map +1 -0
  16. package/node_modules/ajv/dist/compile/codegen/code.d.ts +40 -0
  17. package/node_modules/ajv/dist/compile/codegen/code.js +156 -0
  18. package/node_modules/ajv/dist/compile/codegen/code.js.map +1 -0
  19. package/node_modules/ajv/dist/compile/codegen/index.d.ts +79 -0
  20. package/node_modules/ajv/dist/compile/codegen/index.js +697 -0
  21. package/node_modules/ajv/dist/compile/codegen/index.js.map +1 -0
  22. package/node_modules/ajv/dist/compile/codegen/scope.d.ts +79 -0
  23. package/node_modules/ajv/dist/compile/codegen/scope.js +143 -0
  24. package/node_modules/ajv/dist/compile/codegen/scope.js.map +1 -0
  25. package/node_modules/ajv/dist/compile/errors.d.ts +13 -0
  26. package/node_modules/ajv/dist/compile/errors.js +123 -0
  27. package/node_modules/ajv/dist/compile/errors.js.map +1 -0
  28. package/node_modules/ajv/dist/compile/index.d.ts +80 -0
  29. package/node_modules/ajv/dist/compile/index.js +242 -0
  30. package/node_modules/ajv/dist/compile/index.js.map +1 -0
  31. package/node_modules/ajv/dist/compile/jtd/parse.d.ts +4 -0
  32. package/node_modules/ajv/dist/compile/jtd/parse.js +350 -0
  33. package/node_modules/ajv/dist/compile/jtd/parse.js.map +1 -0
  34. package/node_modules/ajv/dist/compile/jtd/serialize.d.ts +4 -0
  35. package/node_modules/ajv/dist/compile/jtd/serialize.js +236 -0
  36. package/node_modules/ajv/dist/compile/jtd/serialize.js.map +1 -0
  37. package/node_modules/ajv/dist/compile/jtd/types.d.ts +6 -0
  38. package/node_modules/ajv/dist/compile/jtd/types.js +14 -0
  39. package/node_modules/ajv/dist/compile/jtd/types.js.map +1 -0
  40. package/node_modules/ajv/dist/compile/names.d.ts +20 -0
  41. package/node_modules/ajv/dist/compile/names.js +28 -0
  42. package/node_modules/ajv/dist/compile/names.js.map +1 -0
  43. package/node_modules/ajv/dist/compile/ref_error.d.ts +6 -0
  44. package/node_modules/ajv/dist/compile/ref_error.js +12 -0
  45. package/node_modules/ajv/dist/compile/ref_error.js.map +1 -0
  46. package/node_modules/ajv/dist/compile/resolve.d.ts +12 -0
  47. package/node_modules/ajv/dist/compile/resolve.js +155 -0
  48. package/node_modules/ajv/dist/compile/resolve.js.map +1 -0
  49. package/node_modules/ajv/dist/compile/rules.d.ts +28 -0
  50. package/node_modules/ajv/dist/compile/rules.js +26 -0
  51. package/node_modules/ajv/dist/compile/rules.js.map +1 -0
  52. package/node_modules/ajv/dist/compile/util.d.ts +40 -0
  53. package/node_modules/ajv/dist/compile/util.js +178 -0
  54. package/node_modules/ajv/dist/compile/util.js.map +1 -0
  55. package/node_modules/ajv/dist/compile/validate/applicability.d.ts +6 -0
  56. package/node_modules/ajv/dist/compile/validate/applicability.js +19 -0
  57. package/node_modules/ajv/dist/compile/validate/applicability.js.map +1 -0
  58. package/node_modules/ajv/dist/compile/validate/boolSchema.d.ts +4 -0
  59. package/node_modules/ajv/dist/compile/validate/boolSchema.js +50 -0
  60. package/node_modules/ajv/dist/compile/validate/boolSchema.js.map +1 -0
  61. package/node_modules/ajv/dist/compile/validate/dataType.d.ts +17 -0
  62. package/node_modules/ajv/dist/compile/validate/dataType.js +203 -0
  63. package/node_modules/ajv/dist/compile/validate/dataType.js.map +1 -0
  64. package/node_modules/ajv/dist/compile/validate/defaults.d.ts +2 -0
  65. package/node_modules/ajv/dist/compile/validate/defaults.js +35 -0
  66. package/node_modules/ajv/dist/compile/validate/defaults.js.map +1 -0
  67. package/node_modules/ajv/dist/compile/validate/index.d.ts +42 -0
  68. package/node_modules/ajv/dist/compile/validate/index.js +520 -0
  69. package/node_modules/ajv/dist/compile/validate/index.js.map +1 -0
  70. package/node_modules/ajv/dist/compile/validate/keyword.d.ts +8 -0
  71. package/node_modules/ajv/dist/compile/validate/keyword.js +124 -0
  72. package/node_modules/ajv/dist/compile/validate/keyword.js.map +1 -0
  73. package/node_modules/ajv/dist/compile/validate/subschema.d.ts +47 -0
  74. package/node_modules/ajv/dist/compile/validate/subschema.js +81 -0
  75. package/node_modules/ajv/dist/compile/validate/subschema.js.map +1 -0
  76. package/node_modules/ajv/dist/core.d.ts +174 -0
  77. package/node_modules/ajv/dist/core.js +618 -0
  78. package/node_modules/ajv/dist/core.js.map +1 -0
  79. package/node_modules/ajv/dist/jtd.d.ts +47 -0
  80. package/node_modules/ajv/dist/jtd.js +72 -0
  81. package/node_modules/ajv/dist/jtd.js.map +1 -0
  82. package/node_modules/ajv/dist/refs/data.json +13 -0
  83. package/node_modules/ajv/dist/refs/json-schema-2019-09/index.d.ts +2 -0
  84. package/node_modules/ajv/dist/refs/json-schema-2019-09/index.js +28 -0
  85. package/node_modules/ajv/dist/refs/json-schema-2019-09/index.js.map +1 -0
  86. package/node_modules/ajv/dist/refs/json-schema-2019-09/meta/applicator.json +53 -0
  87. package/node_modules/ajv/dist/refs/json-schema-2019-09/meta/content.json +17 -0
  88. package/node_modules/ajv/dist/refs/json-schema-2019-09/meta/core.json +57 -0
  89. package/node_modules/ajv/dist/refs/json-schema-2019-09/meta/format.json +14 -0
  90. package/node_modules/ajv/dist/refs/json-schema-2019-09/meta/meta-data.json +37 -0
  91. package/node_modules/ajv/dist/refs/json-schema-2019-09/meta/validation.json +90 -0
  92. package/node_modules/ajv/dist/refs/json-schema-2019-09/schema.json +39 -0
  93. package/node_modules/ajv/dist/refs/json-schema-2020-12/index.d.ts +2 -0
  94. package/node_modules/ajv/dist/refs/json-schema-2020-12/index.js +30 -0
  95. package/node_modules/ajv/dist/refs/json-schema-2020-12/index.js.map +1 -0
  96. package/node_modules/ajv/dist/refs/json-schema-2020-12/meta/applicator.json +48 -0
  97. package/node_modules/ajv/dist/refs/json-schema-2020-12/meta/content.json +17 -0
  98. package/node_modules/ajv/dist/refs/json-schema-2020-12/meta/core.json +51 -0
  99. package/node_modules/ajv/dist/refs/json-schema-2020-12/meta/format-annotation.json +14 -0
  100. package/node_modules/ajv/dist/refs/json-schema-2020-12/meta/meta-data.json +37 -0
  101. package/node_modules/ajv/dist/refs/json-schema-2020-12/meta/unevaluated.json +15 -0
  102. package/node_modules/ajv/dist/refs/json-schema-2020-12/meta/validation.json +90 -0
  103. package/node_modules/ajv/dist/refs/json-schema-2020-12/schema.json +55 -0
  104. package/node_modules/ajv/dist/refs/json-schema-draft-06.json +137 -0
  105. package/node_modules/ajv/dist/refs/json-schema-draft-07.json +151 -0
  106. package/node_modules/ajv/dist/refs/json-schema-secure.json +88 -0
  107. package/node_modules/ajv/dist/refs/jtd-schema.d.ts +3 -0
  108. package/node_modules/ajv/dist/refs/jtd-schema.js +118 -0
  109. package/node_modules/ajv/dist/refs/jtd-schema.js.map +1 -0
  110. package/node_modules/ajv/dist/runtime/equal.d.ts +6 -0
  111. package/node_modules/ajv/dist/runtime/equal.js +7 -0
  112. package/node_modules/ajv/dist/runtime/equal.js.map +1 -0
  113. package/node_modules/ajv/dist/runtime/parseJson.d.ts +18 -0
  114. package/node_modules/ajv/dist/runtime/parseJson.js +185 -0
  115. package/node_modules/ajv/dist/runtime/parseJson.js.map +1 -0
  116. package/node_modules/ajv/dist/runtime/quote.d.ts +5 -0
  117. package/node_modules/ajv/dist/runtime/quote.js +30 -0
  118. package/node_modules/ajv/dist/runtime/quote.js.map +1 -0
  119. package/node_modules/ajv/dist/runtime/re2.d.ts +6 -0
  120. package/node_modules/ajv/dist/runtime/re2.js +6 -0
  121. package/node_modules/ajv/dist/runtime/re2.js.map +1 -0
  122. package/node_modules/ajv/dist/runtime/timestamp.d.ts +5 -0
  123. package/node_modules/ajv/dist/runtime/timestamp.js +42 -0
  124. package/node_modules/ajv/dist/runtime/timestamp.js.map +1 -0
  125. package/node_modules/ajv/dist/runtime/ucs2length.d.ts +5 -0
  126. package/node_modules/ajv/dist/runtime/ucs2length.js +24 -0
  127. package/node_modules/ajv/dist/runtime/ucs2length.js.map +1 -0
  128. package/node_modules/ajv/dist/runtime/uri.d.ts +6 -0
  129. package/node_modules/ajv/dist/runtime/uri.js +6 -0
  130. package/node_modules/ajv/dist/runtime/uri.js.map +1 -0
  131. package/node_modules/ajv/dist/runtime/validation_error.d.ts +7 -0
  132. package/node_modules/ajv/dist/runtime/validation_error.js +11 -0
  133. package/node_modules/ajv/dist/runtime/validation_error.js.map +1 -0
  134. package/node_modules/ajv/dist/standalone/index.d.ts +6 -0
  135. package/node_modules/ajv/dist/standalone/index.js +90 -0
  136. package/node_modules/ajv/dist/standalone/index.js.map +1 -0
  137. package/node_modules/ajv/dist/standalone/instance.d.ts +12 -0
  138. package/node_modules/ajv/dist/standalone/instance.js +35 -0
  139. package/node_modules/ajv/dist/standalone/instance.js.map +1 -0
  140. package/node_modules/ajv/dist/types/index.d.ts +183 -0
  141. package/node_modules/ajv/dist/types/index.js +3 -0
  142. package/node_modules/ajv/dist/types/index.js.map +1 -0
  143. package/node_modules/ajv/dist/types/json-schema.d.ts +125 -0
  144. package/node_modules/ajv/dist/types/json-schema.js +3 -0
  145. package/node_modules/ajv/dist/types/json-schema.js.map +1 -0
  146. package/node_modules/ajv/dist/types/jtd-schema.d.ts +174 -0
  147. package/node_modules/ajv/dist/types/jtd-schema.js +3 -0
  148. package/node_modules/ajv/dist/types/jtd-schema.js.map +1 -0
  149. package/node_modules/ajv/dist/vocabularies/applicator/additionalItems.d.ts +8 -0
  150. package/node_modules/ajv/dist/vocabularies/applicator/additionalItems.js +49 -0
  151. package/node_modules/ajv/dist/vocabularies/applicator/additionalItems.js.map +1 -0
  152. package/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.d.ts +6 -0
  153. package/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js +106 -0
  154. package/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js.map +1 -0
  155. package/node_modules/ajv/dist/vocabularies/applicator/allOf.d.ts +3 -0
  156. package/node_modules/ajv/dist/vocabularies/applicator/allOf.js +23 -0
  157. package/node_modules/ajv/dist/vocabularies/applicator/allOf.js.map +1 -0
  158. package/node_modules/ajv/dist/vocabularies/applicator/anyOf.d.ts +4 -0
  159. package/node_modules/ajv/dist/vocabularies/applicator/anyOf.js +12 -0
  160. package/node_modules/ajv/dist/vocabularies/applicator/anyOf.js.map +1 -0
  161. package/node_modules/ajv/dist/vocabularies/applicator/contains.d.ts +7 -0
  162. package/node_modules/ajv/dist/vocabularies/applicator/contains.js +95 -0
  163. package/node_modules/ajv/dist/vocabularies/applicator/contains.js.map +1 -0
  164. package/node_modules/ajv/dist/vocabularies/applicator/dependencies.d.ts +21 -0
  165. package/node_modules/ajv/dist/vocabularies/applicator/dependencies.js +85 -0
  166. package/node_modules/ajv/dist/vocabularies/applicator/dependencies.js.map +1 -0
  167. package/node_modules/ajv/dist/vocabularies/applicator/dependentSchemas.d.ts +3 -0
  168. package/node_modules/ajv/dist/vocabularies/applicator/dependentSchemas.js +11 -0
  169. package/node_modules/ajv/dist/vocabularies/applicator/dependentSchemas.js.map +1 -0
  170. package/node_modules/ajv/dist/vocabularies/applicator/if.d.ts +6 -0
  171. package/node_modules/ajv/dist/vocabularies/applicator/if.js +66 -0
  172. package/node_modules/ajv/dist/vocabularies/applicator/if.js.map +1 -0
  173. package/node_modules/ajv/dist/vocabularies/applicator/index.d.ts +13 -0
  174. package/node_modules/ajv/dist/vocabularies/applicator/index.js +44 -0
  175. package/node_modules/ajv/dist/vocabularies/applicator/index.js.map +1 -0
  176. package/node_modules/ajv/dist/vocabularies/applicator/items.d.ts +5 -0
  177. package/node_modules/ajv/dist/vocabularies/applicator/items.js +52 -0
  178. package/node_modules/ajv/dist/vocabularies/applicator/items.js.map +1 -0
  179. package/node_modules/ajv/dist/vocabularies/applicator/items2020.d.ts +6 -0
  180. package/node_modules/ajv/dist/vocabularies/applicator/items2020.js +30 -0
  181. package/node_modules/ajv/dist/vocabularies/applicator/items2020.js.map +1 -0
  182. package/node_modules/ajv/dist/vocabularies/applicator/not.d.ts +4 -0
  183. package/node_modules/ajv/dist/vocabularies/applicator/not.js +26 -0
  184. package/node_modules/ajv/dist/vocabularies/applicator/not.js.map +1 -0
  185. package/node_modules/ajv/dist/vocabularies/applicator/oneOf.d.ts +6 -0
  186. package/node_modules/ajv/dist/vocabularies/applicator/oneOf.js +60 -0
  187. package/node_modules/ajv/dist/vocabularies/applicator/oneOf.js.map +1 -0
  188. package/node_modules/ajv/dist/vocabularies/applicator/patternProperties.d.ts +3 -0
  189. package/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js +75 -0
  190. package/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js.map +1 -0
  191. package/node_modules/ajv/dist/vocabularies/applicator/prefixItems.d.ts +3 -0
  192. package/node_modules/ajv/dist/vocabularies/applicator/prefixItems.js +12 -0
  193. package/node_modules/ajv/dist/vocabularies/applicator/prefixItems.js.map +1 -0
  194. package/node_modules/ajv/dist/vocabularies/applicator/properties.d.ts +3 -0
  195. package/node_modules/ajv/dist/vocabularies/applicator/properties.js +54 -0
  196. package/node_modules/ajv/dist/vocabularies/applicator/properties.js.map +1 -0
  197. package/node_modules/ajv/dist/vocabularies/applicator/propertyNames.d.ts +6 -0
  198. package/node_modules/ajv/dist/vocabularies/applicator/propertyNames.js +38 -0
  199. package/node_modules/ajv/dist/vocabularies/applicator/propertyNames.js.map +1 -0
  200. package/node_modules/ajv/dist/vocabularies/applicator/thenElse.d.ts +3 -0
  201. package/node_modules/ajv/dist/vocabularies/applicator/thenElse.js +13 -0
  202. package/node_modules/ajv/dist/vocabularies/applicator/thenElse.js.map +1 -0
  203. package/node_modules/ajv/dist/vocabularies/code.d.ts +17 -0
  204. package/node_modules/ajv/dist/vocabularies/code.js +131 -0
  205. package/node_modules/ajv/dist/vocabularies/code.js.map +1 -0
  206. package/node_modules/ajv/dist/vocabularies/core/id.d.ts +3 -0
  207. package/node_modules/ajv/dist/vocabularies/core/id.js +10 -0
  208. package/node_modules/ajv/dist/vocabularies/core/id.js.map +1 -0
  209. package/node_modules/ajv/dist/vocabularies/core/index.d.ts +3 -0
  210. package/node_modules/ajv/dist/vocabularies/core/index.js +16 -0
  211. package/node_modules/ajv/dist/vocabularies/core/index.js.map +1 -0
  212. package/node_modules/ajv/dist/vocabularies/core/ref.d.ts +8 -0
  213. package/node_modules/ajv/dist/vocabularies/core/ref.js +122 -0
  214. package/node_modules/ajv/dist/vocabularies/core/ref.js.map +1 -0
  215. package/node_modules/ajv/dist/vocabularies/discriminator/index.d.ts +5 -0
  216. package/node_modules/ajv/dist/vocabularies/discriminator/index.js +104 -0
  217. package/node_modules/ajv/dist/vocabularies/discriminator/index.js.map +1 -0
  218. package/node_modules/ajv/dist/vocabularies/discriminator/types.d.ts +10 -0
  219. package/node_modules/ajv/dist/vocabularies/discriminator/types.js +9 -0
  220. package/node_modules/ajv/dist/vocabularies/discriminator/types.js.map +1 -0
  221. package/node_modules/ajv/dist/vocabularies/draft2020.d.ts +3 -0
  222. package/node_modules/ajv/dist/vocabularies/draft2020.js +23 -0
  223. package/node_modules/ajv/dist/vocabularies/draft2020.js.map +1 -0
  224. package/node_modules/ajv/dist/vocabularies/draft7.d.ts +3 -0
  225. package/node_modules/ajv/dist/vocabularies/draft7.js +17 -0
  226. package/node_modules/ajv/dist/vocabularies/draft7.js.map +1 -0
  227. package/node_modules/ajv/dist/vocabularies/dynamic/dynamicAnchor.d.ts +5 -0
  228. package/node_modules/ajv/dist/vocabularies/dynamic/dynamicAnchor.js +30 -0
  229. package/node_modules/ajv/dist/vocabularies/dynamic/dynamicAnchor.js.map +1 -0
  230. package/node_modules/ajv/dist/vocabularies/dynamic/dynamicRef.d.ts +5 -0
  231. package/node_modules/ajv/dist/vocabularies/dynamic/dynamicRef.js +51 -0
  232. package/node_modules/ajv/dist/vocabularies/dynamic/dynamicRef.js.map +1 -0
  233. package/node_modules/ajv/dist/vocabularies/dynamic/index.d.ts +3 -0
  234. package/node_modules/ajv/dist/vocabularies/dynamic/index.js +9 -0
  235. package/node_modules/ajv/dist/vocabularies/dynamic/index.js.map +1 -0
  236. package/node_modules/ajv/dist/vocabularies/dynamic/recursiveAnchor.d.ts +3 -0
  237. package/node_modules/ajv/dist/vocabularies/dynamic/recursiveAnchor.js +16 -0
  238. package/node_modules/ajv/dist/vocabularies/dynamic/recursiveAnchor.js.map +1 -0
  239. package/node_modules/ajv/dist/vocabularies/dynamic/recursiveRef.d.ts +3 -0
  240. package/node_modules/ajv/dist/vocabularies/dynamic/recursiveRef.js +10 -0
  241. package/node_modules/ajv/dist/vocabularies/dynamic/recursiveRef.js.map +1 -0
  242. package/node_modules/ajv/dist/vocabularies/errors.d.ts +9 -0
  243. package/node_modules/ajv/dist/vocabularies/errors.js +3 -0
  244. package/node_modules/ajv/dist/vocabularies/errors.js.map +1 -0
  245. package/node_modules/ajv/dist/vocabularies/format/format.d.ts +8 -0
  246. package/node_modules/ajv/dist/vocabularies/format/format.js +92 -0
  247. package/node_modules/ajv/dist/vocabularies/format/format.js.map +1 -0
  248. package/node_modules/ajv/dist/vocabularies/format/index.d.ts +3 -0
  249. package/node_modules/ajv/dist/vocabularies/format/index.js +6 -0
  250. package/node_modules/ajv/dist/vocabularies/format/index.js.map +1 -0
  251. package/node_modules/ajv/dist/vocabularies/jtd/discriminator.d.ts +6 -0
  252. package/node_modules/ajv/dist/vocabularies/jtd/discriminator.js +71 -0
  253. package/node_modules/ajv/dist/vocabularies/jtd/discriminator.js.map +1 -0
  254. package/node_modules/ajv/dist/vocabularies/jtd/elements.d.ts +5 -0
  255. package/node_modules/ajv/dist/vocabularies/jtd/elements.js +24 -0
  256. package/node_modules/ajv/dist/vocabularies/jtd/elements.js.map +1 -0
  257. package/node_modules/ajv/dist/vocabularies/jtd/enum.d.ts +6 -0
  258. package/node_modules/ajv/dist/vocabularies/jtd/enum.js +43 -0
  259. package/node_modules/ajv/dist/vocabularies/jtd/enum.js.map +1 -0
  260. package/node_modules/ajv/dist/vocabularies/jtd/error.d.ts +9 -0
  261. package/node_modules/ajv/dist/vocabularies/jtd/error.js +20 -0
  262. package/node_modules/ajv/dist/vocabularies/jtd/error.js.map +1 -0
  263. package/node_modules/ajv/dist/vocabularies/jtd/index.d.ts +10 -0
  264. package/node_modules/ajv/dist/vocabularies/jtd/index.js +29 -0
  265. package/node_modules/ajv/dist/vocabularies/jtd/index.js.map +1 -0
  266. package/node_modules/ajv/dist/vocabularies/jtd/metadata.d.ts +5 -0
  267. package/node_modules/ajv/dist/vocabularies/jtd/metadata.js +25 -0
  268. package/node_modules/ajv/dist/vocabularies/jtd/metadata.js.map +1 -0
  269. package/node_modules/ajv/dist/vocabularies/jtd/nullable.d.ts +4 -0
  270. package/node_modules/ajv/dist/vocabularies/jtd/nullable.js +22 -0
  271. package/node_modules/ajv/dist/vocabularies/jtd/nullable.js.map +1 -0
  272. package/node_modules/ajv/dist/vocabularies/jtd/optionalProperties.d.ts +3 -0
  273. package/node_modules/ajv/dist/vocabularies/jtd/optionalProperties.js +15 -0
  274. package/node_modules/ajv/dist/vocabularies/jtd/optionalProperties.js.map +1 -0
  275. package/node_modules/ajv/dist/vocabularies/jtd/properties.d.ts +22 -0
  276. package/node_modules/ajv/dist/vocabularies/jtd/properties.js +149 -0
  277. package/node_modules/ajv/dist/vocabularies/jtd/properties.js.map +1 -0
  278. package/node_modules/ajv/dist/vocabularies/jtd/ref.d.ts +4 -0
  279. package/node_modules/ajv/dist/vocabularies/jtd/ref.js +67 -0
  280. package/node_modules/ajv/dist/vocabularies/jtd/ref.js.map +1 -0
  281. package/node_modules/ajv/dist/vocabularies/jtd/type.d.ts +10 -0
  282. package/node_modules/ajv/dist/vocabularies/jtd/type.js +69 -0
  283. package/node_modules/ajv/dist/vocabularies/jtd/type.js.map +1 -0
  284. package/node_modules/ajv/dist/vocabularies/jtd/union.d.ts +3 -0
  285. package/node_modules/ajv/dist/vocabularies/jtd/union.js +12 -0
  286. package/node_modules/ajv/dist/vocabularies/jtd/union.js.map +1 -0
  287. package/node_modules/ajv/dist/vocabularies/jtd/values.d.ts +5 -0
  288. package/node_modules/ajv/dist/vocabularies/jtd/values.js +51 -0
  289. package/node_modules/ajv/dist/vocabularies/jtd/values.js.map +1 -0
  290. package/node_modules/ajv/dist/vocabularies/metadata.d.ts +3 -0
  291. package/node_modules/ajv/dist/vocabularies/metadata.js +18 -0
  292. package/node_modules/ajv/dist/vocabularies/metadata.js.map +1 -0
  293. package/node_modules/ajv/dist/vocabularies/next.d.ts +3 -0
  294. package/node_modules/ajv/dist/vocabularies/next.js +8 -0
  295. package/node_modules/ajv/dist/vocabularies/next.js.map +1 -0
  296. package/node_modules/ajv/dist/vocabularies/unevaluated/index.d.ts +3 -0
  297. package/node_modules/ajv/dist/vocabularies/unevaluated/index.js +7 -0
  298. package/node_modules/ajv/dist/vocabularies/unevaluated/index.js.map +1 -0
  299. package/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedItems.d.ts +6 -0
  300. package/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedItems.js +40 -0
  301. package/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedItems.js.map +1 -0
  302. package/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedProperties.d.ts +6 -0
  303. package/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedProperties.js +65 -0
  304. package/node_modules/ajv/dist/vocabularies/unevaluated/unevaluatedProperties.js.map +1 -0
  305. package/node_modules/ajv/dist/vocabularies/validation/const.d.ts +6 -0
  306. package/node_modules/ajv/dist/vocabularies/validation/const.js +25 -0
  307. package/node_modules/ajv/dist/vocabularies/validation/const.js.map +1 -0
  308. package/node_modules/ajv/dist/vocabularies/validation/dependentRequired.d.ts +5 -0
  309. package/node_modules/ajv/dist/vocabularies/validation/dependentRequired.js +12 -0
  310. package/node_modules/ajv/dist/vocabularies/validation/dependentRequired.js.map +1 -0
  311. package/node_modules/ajv/dist/vocabularies/validation/enum.d.ts +8 -0
  312. package/node_modules/ajv/dist/vocabularies/validation/enum.js +48 -0
  313. package/node_modules/ajv/dist/vocabularies/validation/enum.js.map +1 -0
  314. package/node_modules/ajv/dist/vocabularies/validation/index.d.ts +16 -0
  315. package/node_modules/ajv/dist/vocabularies/validation/index.js +33 -0
  316. package/node_modules/ajv/dist/vocabularies/validation/index.js.map +1 -0
  317. package/node_modules/ajv/dist/vocabularies/validation/limitContains.d.ts +3 -0
  318. package/node_modules/ajv/dist/vocabularies/validation/limitContains.js +15 -0
  319. package/node_modules/ajv/dist/vocabularies/validation/limitContains.js.map +1 -0
  320. package/node_modules/ajv/dist/vocabularies/validation/limitItems.d.ts +3 -0
  321. package/node_modules/ajv/dist/vocabularies/validation/limitItems.js +24 -0
  322. package/node_modules/ajv/dist/vocabularies/validation/limitItems.js.map +1 -0
  323. package/node_modules/ajv/dist/vocabularies/validation/limitLength.d.ts +3 -0
  324. package/node_modules/ajv/dist/vocabularies/validation/limitLength.js +27 -0
  325. package/node_modules/ajv/dist/vocabularies/validation/limitLength.js.map +1 -0
  326. package/node_modules/ajv/dist/vocabularies/validation/limitNumber.d.ts +11 -0
  327. package/node_modules/ajv/dist/vocabularies/validation/limitNumber.js +27 -0
  328. package/node_modules/ajv/dist/vocabularies/validation/limitNumber.js.map +1 -0
  329. package/node_modules/ajv/dist/vocabularies/validation/limitProperties.d.ts +3 -0
  330. package/node_modules/ajv/dist/vocabularies/validation/limitProperties.js +24 -0
  331. package/node_modules/ajv/dist/vocabularies/validation/limitProperties.js.map +1 -0
  332. package/node_modules/ajv/dist/vocabularies/validation/multipleOf.d.ts +8 -0
  333. package/node_modules/ajv/dist/vocabularies/validation/multipleOf.js +26 -0
  334. package/node_modules/ajv/dist/vocabularies/validation/multipleOf.js.map +1 -0
  335. package/node_modules/ajv/dist/vocabularies/validation/pattern.d.ts +8 -0
  336. package/node_modules/ajv/dist/vocabularies/validation/pattern.js +33 -0
  337. package/node_modules/ajv/dist/vocabularies/validation/pattern.js.map +1 -0
  338. package/node_modules/ajv/dist/vocabularies/validation/required.d.ts +8 -0
  339. package/node_modules/ajv/dist/vocabularies/validation/required.js +79 -0
  340. package/node_modules/ajv/dist/vocabularies/validation/required.js.map +1 -0
  341. package/node_modules/ajv/dist/vocabularies/validation/uniqueItems.d.ts +9 -0
  342. package/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js +64 -0
  343. package/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js.map +1 -0
  344. package/node_modules/ajv/lib/2019.ts +81 -0
  345. package/node_modules/ajv/lib/2020.ts +75 -0
  346. package/node_modules/ajv/lib/ajv.ts +70 -0
  347. package/node_modules/ajv/lib/compile/codegen/code.ts +169 -0
  348. package/node_modules/ajv/lib/compile/codegen/index.ts +852 -0
  349. package/node_modules/ajv/lib/compile/codegen/scope.ts +215 -0
  350. package/node_modules/ajv/lib/compile/errors.ts +184 -0
  351. package/node_modules/ajv/lib/compile/index.ts +324 -0
  352. package/node_modules/ajv/lib/compile/jtd/parse.ts +411 -0
  353. package/node_modules/ajv/lib/compile/jtd/serialize.ts +277 -0
  354. package/node_modules/ajv/lib/compile/jtd/types.ts +16 -0
  355. package/node_modules/ajv/lib/compile/names.ts +27 -0
  356. package/node_modules/ajv/lib/compile/ref_error.ts +13 -0
  357. package/node_modules/ajv/lib/compile/resolve.ts +149 -0
  358. package/node_modules/ajv/lib/compile/rules.ts +50 -0
  359. package/node_modules/ajv/lib/compile/util.ts +213 -0
  360. package/node_modules/ajv/lib/compile/validate/applicability.ts +22 -0
  361. package/node_modules/ajv/lib/compile/validate/boolSchema.ts +47 -0
  362. package/node_modules/ajv/lib/compile/validate/dataType.ts +230 -0
  363. package/node_modules/ajv/lib/compile/validate/defaults.ts +32 -0
  364. package/node_modules/ajv/lib/compile/validate/index.ts +582 -0
  365. package/node_modules/ajv/lib/compile/validate/keyword.ts +171 -0
  366. package/node_modules/ajv/lib/compile/validate/subschema.ts +135 -0
  367. package/node_modules/ajv/lib/core.ts +892 -0
  368. package/node_modules/ajv/lib/jtd.ts +132 -0
  369. package/node_modules/ajv/lib/refs/data.json +13 -0
  370. package/node_modules/ajv/lib/refs/json-schema-2019-09/index.ts +28 -0
  371. package/node_modules/ajv/lib/refs/json-schema-2019-09/meta/applicator.json +53 -0
  372. package/node_modules/ajv/lib/refs/json-schema-2019-09/meta/content.json +17 -0
  373. package/node_modules/ajv/lib/refs/json-schema-2019-09/meta/core.json +57 -0
  374. package/node_modules/ajv/lib/refs/json-schema-2019-09/meta/format.json +14 -0
  375. package/node_modules/ajv/lib/refs/json-schema-2019-09/meta/meta-data.json +37 -0
  376. package/node_modules/ajv/lib/refs/json-schema-2019-09/meta/validation.json +90 -0
  377. package/node_modules/ajv/lib/refs/json-schema-2019-09/schema.json +39 -0
  378. package/node_modules/ajv/lib/refs/json-schema-2020-12/index.ts +30 -0
  379. package/node_modules/ajv/lib/refs/json-schema-2020-12/meta/applicator.json +48 -0
  380. package/node_modules/ajv/lib/refs/json-schema-2020-12/meta/content.json +17 -0
  381. package/node_modules/ajv/lib/refs/json-schema-2020-12/meta/core.json +51 -0
  382. package/node_modules/ajv/lib/refs/json-schema-2020-12/meta/format-annotation.json +14 -0
  383. package/node_modules/ajv/lib/refs/json-schema-2020-12/meta/meta-data.json +37 -0
  384. package/node_modules/ajv/lib/refs/json-schema-2020-12/meta/unevaluated.json +15 -0
  385. package/node_modules/ajv/lib/refs/json-schema-2020-12/meta/validation.json +90 -0
  386. package/node_modules/ajv/lib/refs/json-schema-2020-12/schema.json +55 -0
  387. package/node_modules/ajv/lib/refs/json-schema-draft-06.json +137 -0
  388. package/node_modules/ajv/lib/refs/json-schema-draft-07.json +151 -0
  389. package/node_modules/ajv/lib/refs/json-schema-secure.json +88 -0
  390. package/node_modules/ajv/lib/refs/jtd-schema.ts +130 -0
  391. package/node_modules/ajv/lib/runtime/equal.ts +7 -0
  392. package/node_modules/ajv/lib/runtime/parseJson.ts +177 -0
  393. package/node_modules/ajv/lib/runtime/quote.ts +31 -0
  394. package/node_modules/ajv/lib/runtime/re2.ts +6 -0
  395. package/node_modules/ajv/lib/runtime/timestamp.ts +46 -0
  396. package/node_modules/ajv/lib/runtime/ucs2length.ts +20 -0
  397. package/node_modules/ajv/lib/runtime/uri.ts +6 -0
  398. package/node_modules/ajv/lib/runtime/validation_error.ts +13 -0
  399. package/node_modules/ajv/lib/standalone/index.ts +100 -0
  400. package/node_modules/ajv/lib/standalone/instance.ts +36 -0
  401. package/node_modules/ajv/lib/types/index.ts +244 -0
  402. package/node_modules/ajv/lib/types/json-schema.ts +187 -0
  403. package/node_modules/ajv/lib/types/jtd-schema.ts +273 -0
  404. package/node_modules/ajv/lib/vocabularies/applicator/additionalItems.ts +56 -0
  405. package/node_modules/ajv/lib/vocabularies/applicator/additionalProperties.ts +118 -0
  406. package/node_modules/ajv/lib/vocabularies/applicator/allOf.ts +22 -0
  407. package/node_modules/ajv/lib/vocabularies/applicator/anyOf.ts +14 -0
  408. package/node_modules/ajv/lib/vocabularies/applicator/contains.ts +109 -0
  409. package/node_modules/ajv/lib/vocabularies/applicator/dependencies.ts +112 -0
  410. package/node_modules/ajv/lib/vocabularies/applicator/dependentSchemas.ts +11 -0
  411. package/node_modules/ajv/lib/vocabularies/applicator/if.ts +80 -0
  412. package/node_modules/ajv/lib/vocabularies/applicator/index.ts +53 -0
  413. package/node_modules/ajv/lib/vocabularies/applicator/items.ts +59 -0
  414. package/node_modules/ajv/lib/vocabularies/applicator/items2020.ts +36 -0
  415. package/node_modules/ajv/lib/vocabularies/applicator/not.ts +38 -0
  416. package/node_modules/ajv/lib/vocabularies/applicator/oneOf.ts +82 -0
  417. package/node_modules/ajv/lib/vocabularies/applicator/patternProperties.ts +91 -0
  418. package/node_modules/ajv/lib/vocabularies/applicator/prefixItems.ts +12 -0
  419. package/node_modules/ajv/lib/vocabularies/applicator/properties.ts +57 -0
  420. package/node_modules/ajv/lib/vocabularies/applicator/propertyNames.ts +50 -0
  421. package/node_modules/ajv/lib/vocabularies/applicator/thenElse.ts +13 -0
  422. package/node_modules/ajv/lib/vocabularies/code.ts +168 -0
  423. package/node_modules/ajv/lib/vocabularies/core/id.ts +10 -0
  424. package/node_modules/ajv/lib/vocabularies/core/index.ts +16 -0
  425. package/node_modules/ajv/lib/vocabularies/core/ref.ts +129 -0
  426. package/node_modules/ajv/lib/vocabularies/discriminator/index.ts +113 -0
  427. package/node_modules/ajv/lib/vocabularies/discriminator/types.ts +12 -0
  428. package/node_modules/ajv/lib/vocabularies/draft2020.ts +23 -0
  429. package/node_modules/ajv/lib/vocabularies/draft7.ts +17 -0
  430. package/node_modules/ajv/lib/vocabularies/dynamic/dynamicAnchor.ts +31 -0
  431. package/node_modules/ajv/lib/vocabularies/dynamic/dynamicRef.ts +51 -0
  432. package/node_modules/ajv/lib/vocabularies/dynamic/index.ts +9 -0
  433. package/node_modules/ajv/lib/vocabularies/dynamic/recursiveAnchor.ts +14 -0
  434. package/node_modules/ajv/lib/vocabularies/dynamic/recursiveRef.ts +10 -0
  435. package/node_modules/ajv/lib/vocabularies/errors.ts +18 -0
  436. package/node_modules/ajv/lib/vocabularies/format/format.ts +120 -0
  437. package/node_modules/ajv/lib/vocabularies/format/index.ts +6 -0
  438. package/node_modules/ajv/lib/vocabularies/jtd/discriminator.ts +89 -0
  439. package/node_modules/ajv/lib/vocabularies/jtd/elements.ts +32 -0
  440. package/node_modules/ajv/lib/vocabularies/jtd/enum.ts +45 -0
  441. package/node_modules/ajv/lib/vocabularies/jtd/error.ts +23 -0
  442. package/node_modules/ajv/lib/vocabularies/jtd/index.ts +37 -0
  443. package/node_modules/ajv/lib/vocabularies/jtd/metadata.ts +24 -0
  444. package/node_modules/ajv/lib/vocabularies/jtd/nullable.ts +21 -0
  445. package/node_modules/ajv/lib/vocabularies/jtd/optionalProperties.ts +15 -0
  446. package/node_modules/ajv/lib/vocabularies/jtd/properties.ts +184 -0
  447. package/node_modules/ajv/lib/vocabularies/jtd/ref.ts +76 -0
  448. package/node_modules/ajv/lib/vocabularies/jtd/type.ts +75 -0
  449. package/node_modules/ajv/lib/vocabularies/jtd/union.ts +12 -0
  450. package/node_modules/ajv/lib/vocabularies/jtd/values.ts +58 -0
  451. package/node_modules/ajv/lib/vocabularies/metadata.ts +17 -0
  452. package/node_modules/ajv/lib/vocabularies/next.ts +8 -0
  453. package/node_modules/ajv/lib/vocabularies/unevaluated/index.ts +7 -0
  454. package/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedItems.ts +47 -0
  455. package/node_modules/ajv/lib/vocabularies/unevaluated/unevaluatedProperties.ts +85 -0
  456. package/node_modules/ajv/lib/vocabularies/validation/const.ts +28 -0
  457. package/node_modules/ajv/lib/vocabularies/validation/dependentRequired.ts +23 -0
  458. package/node_modules/ajv/lib/vocabularies/validation/enum.ts +54 -0
  459. package/node_modules/ajv/lib/vocabularies/validation/index.ts +49 -0
  460. package/node_modules/ajv/lib/vocabularies/validation/limitContains.ts +16 -0
  461. package/node_modules/ajv/lib/vocabularies/validation/limitItems.ts +26 -0
  462. package/node_modules/ajv/lib/vocabularies/validation/limitLength.ts +30 -0
  463. package/node_modules/ajv/lib/vocabularies/validation/limitNumber.ts +42 -0
  464. package/node_modules/ajv/lib/vocabularies/validation/limitProperties.ts +26 -0
  465. package/node_modules/ajv/lib/vocabularies/validation/multipleOf.ts +34 -0
  466. package/node_modules/ajv/lib/vocabularies/validation/pattern.ts +39 -0
  467. package/node_modules/ajv/lib/vocabularies/validation/required.ts +98 -0
  468. package/node_modules/ajv/lib/vocabularies/validation/uniqueItems.ts +79 -0
  469. package/node_modules/ajv/package.json +126 -0
  470. package/node_modules/fast-deep-equal/LICENSE +21 -0
  471. package/node_modules/fast-deep-equal/README.md +96 -0
  472. package/node_modules/fast-deep-equal/es6/index.d.ts +2 -0
  473. package/node_modules/fast-deep-equal/es6/index.js +72 -0
  474. package/node_modules/fast-deep-equal/es6/react.d.ts +2 -0
  475. package/node_modules/fast-deep-equal/es6/react.js +79 -0
  476. package/node_modules/fast-deep-equal/index.d.ts +4 -0
  477. package/node_modules/fast-deep-equal/index.js +46 -0
  478. package/node_modules/fast-deep-equal/package.json +61 -0
  479. package/node_modules/fast-deep-equal/react.d.ts +2 -0
  480. package/node_modules/fast-deep-equal/react.js +53 -0
  481. package/node_modules/fast-uri/.gitattributes +2 -0
  482. package/node_modules/fast-uri/.github/dependabot.yml +13 -0
  483. package/node_modules/fast-uri/.github/workflows/ci.yml +106 -0
  484. package/node_modules/fast-uri/.github/workflows/lock-threads.yml +19 -0
  485. package/node_modules/fast-uri/.github/workflows/package-manager-ci.yml +24 -0
  486. package/node_modules/fast-uri/LICENSE +30 -0
  487. package/node_modules/fast-uri/README.md +152 -0
  488. package/node_modules/fast-uri/benchmark/benchmark.mjs +159 -0
  489. package/node_modules/fast-uri/benchmark/equal.mjs +51 -0
  490. package/node_modules/fast-uri/benchmark/non-simple-domain.mjs +22 -0
  491. package/node_modules/fast-uri/benchmark/package.json +17 -0
  492. package/node_modules/fast-uri/benchmark/string-array-to-hex-stripped.mjs +24 -0
  493. package/node_modules/fast-uri/benchmark/ws-is-secure.mjs +65 -0
  494. package/node_modules/fast-uri/eslint.config.js +6 -0
  495. package/node_modules/fast-uri/index.js +627 -0
  496. package/node_modules/fast-uri/lib/schemes.js +272 -0
  497. package/node_modules/fast-uri/lib/utils.js +747 -0
  498. package/node_modules/fast-uri/package.json +68 -0
  499. package/node_modules/fast-uri/test/ajv.test.js +43 -0
  500. package/node_modules/fast-uri/test/component-safe-serialization.test.js +163 -0
  501. package/node_modules/fast-uri/test/equal.test.js +145 -0
  502. package/node_modules/fast-uri/test/fixtures/uri-js-parse.json +503 -0
  503. package/node_modules/fast-uri/test/fixtures/uri-js-serialize.json +120 -0
  504. package/node_modules/fast-uri/test/ipv6-canonical.test.js +34 -0
  505. package/node_modules/fast-uri/test/ipv6-validation.test.js +124 -0
  506. package/node_modules/fast-uri/test/malformed-percent.test.js +77 -0
  507. package/node_modules/fast-uri/test/malformed-urn.test.js +61 -0
  508. package/node_modules/fast-uri/test/parse.test.js +327 -0
  509. package/node_modules/fast-uri/test/query-fragment-normalization.test.js +33 -0
  510. package/node_modules/fast-uri/test/reserved-path-normalization.test.js +109 -0
  511. package/node_modules/fast-uri/test/resolve.test.js +87 -0
  512. package/node_modules/fast-uri/test/rfc-3986.test.js +90 -0
  513. package/node_modules/fast-uri/test/scheme-validation.test.js +124 -0
  514. package/node_modules/fast-uri/test/security-normalization.test.js +140 -0
  515. package/node_modules/fast-uri/test/security.test.js +431 -0
  516. package/node_modules/fast-uri/test/serialize.test.js +151 -0
  517. package/node_modules/fast-uri/test/uri-js-compatibility.test.js +33 -0
  518. package/node_modules/fast-uri/test/uri-js.test.js +912 -0
  519. package/node_modules/fast-uri/test/urn-full-input.test.js +29 -0
  520. package/node_modules/fast-uri/test/util.test.js +38 -0
  521. package/node_modules/fast-uri/test/websocket-query-preservation.test.js +24 -0
  522. package/node_modules/fast-uri/tsconfig.json +9 -0
  523. package/node_modules/fast-uri/types/index.d.ts +60 -0
  524. package/node_modules/fast-uri/types/index.test-d.ts +17 -0
  525. package/node_modules/json-schema-traverse/.eslintrc.yml +27 -0
  526. package/node_modules/json-schema-traverse/.github/FUNDING.yml +2 -0
  527. package/node_modules/json-schema-traverse/.github/workflows/build.yml +28 -0
  528. package/node_modules/json-schema-traverse/.github/workflows/publish.yml +27 -0
  529. package/node_modules/json-schema-traverse/LICENSE +21 -0
  530. package/node_modules/json-schema-traverse/README.md +95 -0
  531. package/node_modules/json-schema-traverse/index.d.ts +40 -0
  532. package/node_modules/json-schema-traverse/index.js +93 -0
  533. package/node_modules/json-schema-traverse/package.json +43 -0
  534. package/node_modules/json-schema-traverse/spec/.eslintrc.yml +6 -0
  535. package/node_modules/json-schema-traverse/spec/fixtures/schema.js +125 -0
  536. package/node_modules/json-schema-traverse/spec/index.spec.js +171 -0
  537. package/node_modules/require-from-string/index.js +34 -0
  538. package/node_modules/require-from-string/license +21 -0
  539. package/node_modules/require-from-string/package.json +28 -0
  540. package/node_modules/require-from-string/readme.md +56 -0
  541. package/package.json +33 -4
  542. package/packages/pcr-core/schemas/agent-review.schema.json +69 -0
  543. package/packages/pcr-core/schemas/classification-coverage.schema.json +187 -0
  544. package/packages/pcr-core/schemas/controlled-vocabulary.schema.json +189 -0
  545. package/packages/pcr-core/schemas/dataset-validation-input.schema.json +7 -0
  546. package/packages/pcr-core/schemas/feedback-draft-output.schema.json +12 -0
  547. package/packages/pcr-core/schemas/feedback.schema.json +27 -0
  548. package/packages/pcr-core/schemas/guidance-output.schema.json +97 -0
  549. package/packages/pcr-core/schemas/model-validation-input.schema.json +10 -0
  550. package/packages/pcr-core/schemas/pcr-id-aliases.schema.json +120 -0
  551. package/packages/pcr-core/schemas/readiness.schema.json +100 -0
  552. package/packages/pcr-core/schemas/structured-projection.schema.json +269 -0
  553. package/packages/pcr-core/schemas/validation-output.schema.json +117 -0
  554. package/packages/pcr-core/src/classification-coverage.mjs +732 -0
  555. package/packages/pcr-core/src/consumption-calculation.mjs +53 -0
  556. package/packages/pcr-core/src/consumption-data.mjs +88 -0
  557. package/packages/pcr-core/src/consumption-guidance.mjs +62 -0
  558. package/packages/pcr-core/src/consumption-review.mjs +83 -0
  559. package/packages/pcr-core/src/contracts.mjs +195 -0
  560. package/packages/pcr-core/src/generated/controlled-vocabulary.mjs +41 -0
  561. package/packages/pcr-core/src/index.mjs +2101 -0
  562. package/packages/pcr-core/src/languages.mjs +86 -0
  563. package/packages/pcr-core/src/offline-library.mjs +121 -0
  564. package/packages/pcr-core/src/output-semantics.mjs +228 -0
  565. package/packages/pcr-core/src/pcr-id-aliases.mjs +949 -0
  566. package/packages/pcr-core/src/projection-completeness.mjs +284 -0
  567. package/packages/pcr-core/src/projection-integrity.mjs +208 -0
  568. package/packages/pcr-core/src/read-context.mjs +505 -0
  569. package/packages/pcr-core/src/schema-validation.mjs +142 -0
  570. package/packages/pcr-core/src/source-context.mjs +13 -0
  571. package/packages/pcr-core/src/tidas-inspection.mjs +177 -0
  572. package/packages/pcr-core/src/yaml-lite.mjs +261 -0
  573. package/packages/tiangong-pcr-cli/bin/tiangong-pcr.mjs +12 -0
  574. package/packages/tiangong-pcr-cli/src/commands.mjs +1691 -0
  575. package/skills/tiangong-pcr/SKILL.md +90 -0
  576. package/skills/tiangong-pcr/references/cli-usage.md +66 -0
  577. package/skills/tiangong-pcr/references/feedback-loop.md +16 -0
  578. package/skills/tiangong-pcr/references/lca-authoring.md +30 -0
  579. package/skills/tiangong-pcr/references/model-authoring-loop.md +6 -0
  580. package/skills/tiangong-pcr/references/reviewing-tidas.md +71 -0
  581. package/skills/tiangong-pcr/references/tidas-authoring.md +45 -0
@@ -0,0 +1,1691 @@
1
+ import { createRequire } from "node:module";
2
+ import { OfflineLibrary } from "../../pcr-core/src/offline-library.mjs";
3
+ import { withPcrSource } from "../../pcr-core/src/source-context.mjs";
4
+ import { existsSync, readFileSync, writeFileSync } from "node:fs";
5
+ import path from "node:path";
6
+ import { fileURLToPath } from "node:url";
7
+ import { GUIDANCE_TOPICS, selectGuidance } from "../../pcr-core/src/consumption-guidance.mjs";
8
+ import { inspectTidas, INSPECTION_SECTIONS } from "../../pcr-core/src/tidas-inspection.mjs";
9
+ import { prepareReview, checkReview } from "../../pcr-core/src/consumption-review.mjs";
10
+ import { calculate } from "../../pcr-core/src/consumption-calculation.mjs";
11
+ import { readJsonDocument, sha256 } from "../../pcr-core/src/consumption-data.mjs";
12
+
13
+ import {
14
+ CLASSIFICATION_COVERAGE_STATUSES,
15
+ FEEDBACK_TYPES,
16
+ PCR_CATALOG_SCOPES,
17
+ buildGuidance,
18
+ buildPcrTree,
19
+ createFeedbackDraft,
20
+ getClassificationCoverageSummary,
21
+ listClassificationCoverage,
22
+ listPcrs,
23
+ readPcrMarkdown,
24
+ resolveClassification,
25
+ resolvePcrIdentity,
26
+ validateDatasetAgainstGuidance,
27
+ validateModelAgainstGuidance,
28
+ } from "../../pcr-core/src/index.mjs";
29
+ import {
30
+ CONTENT_MATURITY_VALUES,
31
+ PCR_STATUS_VALUES,
32
+ } from "../../pcr-core/src/generated/controlled-vocabulary.mjs";
33
+
34
+ const defaultRoot = path.resolve(fileURLToPath(new URL("../../..", import.meta.url)));
35
+ const VALID_FAIL_ON = new Set(["never", "error", "warning"]);
36
+ const VALID_LANGUAGES = new Set(["en-US", "zh-CN"]);
37
+ const VALID_PCR_STATUSES = new Set(PCR_STATUS_VALUES);
38
+ const VALID_CONTENT_MATURITIES = new Set(CONTENT_MATURITY_VALUES);
39
+ const VALID_CATALOG_SCOPES = new Set(PCR_CATALOG_SCOPES);
40
+ const VALID_COVERAGE_STATUSES = new Set(CLASSIFICATION_COVERAGE_STATUSES);
41
+ const GLOBAL_OPTIONS = new Set(["root", "library", "library-sha256", "format", "help"]);
42
+ const GLOBAL_HELP_OPTIONS = new Set(["root", "library", "library-sha256", "help"]);
43
+ const COMMAND_OPTIONS = {
44
+ library: new Set(),
45
+ "library:info": new Set(),
46
+ "library:verify": new Set(),
47
+ list: new Set(["status", "content-maturity", "path-prefix", "scope", "page", "page-size"]),
48
+ tree: new Set(["depth", "scope"]),
49
+ coverage: new Set(),
50
+ "coverage:summary": new Set(["classification"]),
51
+ "coverage:list": new Set(["classification", "status", "page", "page-size"]),
52
+ resolve: new Set(["classification", "pcr"]),
53
+ show: new Set(["pcr", "lang"]),
54
+ guidance: new Set(["pcr", "topic", "pointer", "page", "page-size", "output"]),
55
+ inspect: new Set(["input", "related", "section", "pointer", "page", "page-size", "output"]),
56
+ calculate: new Set(["input", "output"]),
57
+ review: new Set(),
58
+ "review:prepare": new Set(["pcr", "input", "related", "output"]),
59
+ "review:check": new Set(["pcr", "input", "related", "report", "output"]),
60
+ "validate-model": new Set(["pcr", "input", "fail-on"]),
61
+ "validate-dataset": new Set(["pcr", "input", "fail-on"]),
62
+ "feedback:draft": new Set([
63
+ "pcr",
64
+ "type",
65
+ "affected-section",
66
+ "process-id",
67
+ "flow-role",
68
+ "summary",
69
+ "evidence",
70
+ "proposed-change",
71
+ ]),
72
+ };
73
+ const COMMAND_DEFINITIONS = [
74
+ { key: "library", command: "library", formats: ["json"], defaultFormat: "json" },
75
+ { key: "library:info", command: "library", positional: ["info"], formats: ["json"], defaultFormat: "json" },
76
+ { key: "library:verify", command: "library", positional: ["verify"], formats: ["json"], defaultFormat: "json" },
77
+ { key: "list", command: "list", formats: ["json", "markdown", "table"], defaultFormat: "table" },
78
+ { key: "tree", command: "tree", formats: ["json", "markdown"], defaultFormat: "markdown" },
79
+ { key: "coverage", command: "coverage", formats: ["json", "table"], defaultFormat: "table" },
80
+ {
81
+ key: "coverage:summary",
82
+ command: "coverage",
83
+ positional: ["summary"],
84
+ formats: ["json", "table"],
85
+ defaultFormat: "table",
86
+ },
87
+ {
88
+ key: "coverage:list",
89
+ command: "coverage",
90
+ positional: ["list"],
91
+ formats: ["json", "table"],
92
+ defaultFormat: "table",
93
+ },
94
+ { key: "resolve", command: "resolve", formats: ["json"], defaultFormat: "json" },
95
+ { key: "show", command: "show", formats: ["markdown"], defaultFormat: "markdown" },
96
+ { key: "guidance", command: "guidance", formats: ["json"], defaultFormat: "json" },
97
+ { key: "inspect", command: "inspect", formats: ["json"], defaultFormat: "json" },
98
+ { key: "calculate", command: "calculate", formats: ["json"], defaultFormat: "json" },
99
+ { key: "review", command: "review", formats: ["json"], defaultFormat: "json" },
100
+ { key: "review:prepare", command: "review", positional: ["prepare"], formats: ["json"], defaultFormat: "json" },
101
+ { key: "review:check", command: "review", positional: ["check"], formats: ["json"], defaultFormat: "json" },
102
+ { key: "validate-model", command: "validate-model", formats: ["json"], defaultFormat: "json" },
103
+ { key: "validate-dataset", command: "validate-dataset", formats: ["json"], defaultFormat: "json" },
104
+ {
105
+ key: "feedback:draft",
106
+ command: "feedback",
107
+ positional: ["draft"],
108
+ formats: ["json", "markdown"],
109
+ defaultFormat: "markdown",
110
+ },
111
+ ];
112
+
113
+ export class CliError extends Error {
114
+ constructor(code, message, details = undefined) {
115
+ super(message);
116
+ this.name = "CliError";
117
+ this.code = code;
118
+ this.details = details === undefined ? undefined : structuredClone(details);
119
+ }
120
+ }
121
+
122
+ function installedLibrary() {
123
+ for (const filename of [path.join(process.cwd(), "package.json"), import.meta.url]) {
124
+ try { return path.join(path.dirname(createRequire(filename).resolve("@tiangong-lca/pcr-library/package.json")), "library.sqlite"); } catch {}
125
+ }
126
+ return null;
127
+ }
128
+
129
+ function toolVersion() {
130
+ const developmentManifest = fileURLToPath(new URL("../package.json", import.meta.url));
131
+ const filename = existsSync(developmentManifest) ? developmentManifest : path.join(defaultRoot, "package.json");
132
+ return JSON.parse(readFileSync(filename, "utf8")).version;
133
+ }
134
+
135
+ export function runTiangongPcr(argv) {
136
+ let library;
137
+ try {
138
+ if (argv.length === 1 && argv[0] === "--version") return ok(`${toolVersion()}\n`);
139
+ const { command, positional, options } = parseArgs(argv);
140
+ if (!command || command === "help" || options.help) return runCommand(argv);
141
+ if (command === "library" && positional.length === 0) throw new CliError("PCR_CLI_MISSING_SUBCOMMAND", "Use library info or library verify with --library <file>.");
142
+ if (options.root && options.library) throw new CliError("PCR_CLI_SOURCE_CONFLICT", "Choose either --root or --library.");
143
+ if (["inspect", "calculate"].includes(command)) {
144
+ if (options.library || options["library-sha256"]) throw new CliError("PCR_CLI_SOURCE_UNUSED", `${command} uses local input only; omit --library and --library-sha256.`);
145
+ return runCommand(argv);
146
+ }
147
+ const filename = options.library ?? (options.root ? null : process.env.PCR_LIBRARY ?? (existsSync(path.join(defaultRoot, "library/catalog.yaml")) ? null : installedLibrary()));
148
+ if (!filename) {
149
+ if (options["library-sha256"] || command === "library") throw new CliError("PCR_LIBRARY_REQUIRED", "Select a local snapshot with --library <library.sqlite>.");
150
+ if (!options.root && !existsSync(path.join(defaultRoot, "library/catalog.yaml"))) throw new CliError("PCR_LIBRARY_REQUIRED", "No offline library found. Install @tiangong-lca/pcr-library or pass --library <library.sqlite>.");
151
+ return runCommand(argv);
152
+ }
153
+ // Validate the command before opening a potentially large data file.
154
+ const definition = requireCommandDefinition(command, positional);
155
+ validateCommandOptions(definition, options);
156
+ validateCommandFormat(definition, options.format);
157
+ library = new OfflineLibrary(String(filename), { expectedSha256: options["library-sha256"] ?? null, verify: command === "library" && positional[0] === "verify" });
158
+ if (command === "library") return ok(`${JSON.stringify({ tool_version: toolVersion(), ...library.manifest, verified: positional[0] === "verify" || Boolean(options["library-sha256"]) }, null, 2)}\n`);
159
+ return withPcrSource(library.root, library, () => runCommand(argv, { root: library.root, library: path.resolve(filename), "library-sha256": options["library-sha256"] }));
160
+ } catch (error) {
161
+ return fail(error, requestedFormatFromArgv(argv), requestedRootFromArgv(argv));
162
+ } finally { library?.close(); }
163
+ }
164
+
165
+ function runCommand(argv, selected = null) {
166
+ const requestedFormat = requestedFormatFromArgv(argv);
167
+ const requestedRoot = requestedRootFromArgv(argv);
168
+ try {
169
+ const { command, positional, options } = parseArgs(argv);
170
+
171
+ if (command === "help" || !command) {
172
+ validateHelpInvocation({ command, positional, options });
173
+ return ok(helpText(command, positional));
174
+ }
175
+ const definition = requireCommandDefinition(command, positional);
176
+ validateCommandOptions(definition, options);
177
+ if (options.help) {
178
+ return ok(helpText(command, positional));
179
+ }
180
+
181
+ if (selected) options.library = selected.library;
182
+ const root = selected?.root ?? path.resolve(String(options.root ?? defaultRoot));
183
+ const format = validateCommandFormat(definition, options.format);
184
+
185
+ if (command === "list") {
186
+ validateListOptions(options);
187
+ const scope = effectiveCatalogScope(options);
188
+ const page = paginateList(
189
+ filterPcrs(listPcrs({ root, scope: scope.effective }), options),
190
+ options,
191
+ scope,
192
+ );
193
+ return ok(writeOutput(page, format, formatListTable));
194
+ }
195
+ if (command === "tree") {
196
+ const depth = positiveIntegerOption(options.depth, "depth", 2);
197
+ const scope = effectiveCatalogScope(options);
198
+ const tree = buildPcrTree({ root, depth, scope: scope.effective });
199
+ if (format === "json") {
200
+ return ok(`${JSON.stringify(treeOutput(tree, depth, scope), null, 2)}\n`);
201
+ }
202
+ return ok(`${formatTreeMarkdown(tree, depth, scope)}\n`);
203
+ }
204
+ if (command === "coverage" && positional.length === 0) {
205
+ throw new CliError(
206
+ "PCR_CLI_MISSING_SUBCOMMAND",
207
+ "Missing coverage subcommand. Use `coverage summary --classification <system>:<version>` or `coverage list --classification <system>:<version>`.",
208
+ { command: "coverage", valid_subcommands: ["summary", "list"] },
209
+ );
210
+ }
211
+ if (command === "coverage" && positional[0] === "summary") {
212
+ const classification = parseClassificationSelector(options.classification, {
213
+ includeCode: false,
214
+ });
215
+ const summary = coverageSummaryOutput(
216
+ getClassificationCoverageSummary({ root, ...classification }),
217
+ options,
218
+ );
219
+ return ok(writeOutput(summary, format, formatCoverageSummary));
220
+ }
221
+ if (command === "coverage" && positional[0] === "list") {
222
+ const classification = parseClassificationSelector(options.classification, {
223
+ includeCode: false,
224
+ });
225
+ validateCoverageListOptions(options);
226
+ const result = listClassificationCoverage({
227
+ root,
228
+ ...classification,
229
+ status: options.status === undefined ? null : String(options.status),
230
+ });
231
+ const page = paginateCoverage(result, classification, options);
232
+ return ok(writeOutput(page, format, formatCoverageList));
233
+ }
234
+ if (command === "resolve") {
235
+ validateResolveSelector(options);
236
+ if (options.pcr !== undefined) {
237
+ const resolution = resolvePcrIdentity({ root, pcrId: String(options.pcr) });
238
+ return ok(`${JSON.stringify(resolvePcrIdentityOutput(resolution, options), null, 2)}\n`);
239
+ }
240
+ const classification = parseClassificationSelector(options.classification, {
241
+ includeCode: true,
242
+ });
243
+ const resolution = resolveClassification({ root, ...classification });
244
+ return ok(`${JSON.stringify(resolveOutput(resolution, options), null, 2)}\n`);
245
+ }
246
+ if (command === "show") {
247
+ requireOption(options, "pcr");
248
+ const language = String(options.lang ?? "en-US");
249
+ if (!VALID_LANGUAGES.has(language)) {
250
+ throw invalidChoiceError("lang", language, [...VALID_LANGUAGES]);
251
+ }
252
+ return ok(readPcrMarkdown({ root, pcrId: String(options.pcr), language }));
253
+ }
254
+ if (command === "guidance") {
255
+ requireOption(options, "pcr");
256
+ if (["topic", "pointer", "page", "page-size"].some((key) => options[key] !== undefined)) {
257
+ validatePointerOptions(options, "topic");
258
+ const report = selectGuidance({ root, pcrId: String(options.pcr), topic: options.topic, pointer: options.pointer, ...consumptionPage(options) });
259
+ return consumptionOutput(withConsumptionContinuation(report, "guidance", options), options);
260
+ }
261
+ if (options.output) return consumptionOutput(buildGuidance({ root, pcrId: String(options.pcr) }), options);
262
+ return ok(writeOutput(buildGuidance({ root, pcrId: String(options.pcr) }), format, JSON.stringify));
263
+ }
264
+ if (command === "inspect") {
265
+ requireOption(options, "input");
266
+ validatePointerOptions(options, "section");
267
+ if (options.pointer === undefined && (!options.section || options.section === "summary") && (options.page || options["page-size"])) {
268
+ throw new CliError("PCR_CLI_OPTION_CONFLICT", "Summary is not paginated. Choose --section references|exchanges|instances|documents for paging.");
269
+ }
270
+ const report = inspectTidas({ input: options.input, related: options.related, section: options.section, pointer: options.pointer, ...consumptionPage(options) });
271
+ return consumptionOutput(withConsumptionContinuation(report, "inspect", options), options);
272
+ }
273
+ if (command === "calculate") {
274
+ requireOption(options, "input");
275
+ const source = readJsonDocument(options.input);
276
+ return consumptionOutput({ ...calculate(source.value), request_source: { file: source.file, sha256: source.sha256 } }, options);
277
+ }
278
+ if (command === "review") {
279
+ if (!positional.length) throw new CliError("PCR_CLI_MISSING_SUBCOMMAND", "Use review prepare to create an Agent draft or review check to verify its envelope. Run review --help.");
280
+ requireOption(options, "input");
281
+ requireOption(options, "pcr");
282
+ const args = { root, pcrId: String(options.pcr), input: options.input, related: options.related };
283
+ if (positional[0] === "prepare") return consumptionOutput(prepareReview(args), options);
284
+ requireOption(options, "report");
285
+ const source = readJsonDocument(options.report);
286
+ const report = checkReview({ ...args, report: source.value });
287
+ return consumptionOutput({ ...report, report_source: { file: source.file, sha256: source.sha256 } }, options, report.envelope_valid ? 0 : 2);
288
+ }
289
+ if (command === "validate-model") {
290
+ requireOption(options, "pcr");
291
+ requireOption(options, "input");
292
+ const failOn = validateFailOn(options["fail-on"]);
293
+ const modelText = readInputFile(options.input);
294
+ const report = validateModelAgainstGuidance({ root, pcrId: String(options.pcr), model: modelText });
295
+ return ok(writeOutput(
296
+ report,
297
+ format,
298
+ JSON.stringify,
299
+ ), validationExitCode(report, failOn));
300
+ }
301
+ if (command === "validate-dataset") {
302
+ requireOption(options, "pcr");
303
+ requireOption(options, "input");
304
+ const failOn = validateFailOn(options["fail-on"]);
305
+ const datasetText = readInputFile(options.input);
306
+ const dataset = parseDatasetInput(datasetText);
307
+ const report = validateDatasetAgainstGuidance({ root, pcrId: String(options.pcr), dataset });
308
+ return ok(writeOutput(
309
+ report,
310
+ format,
311
+ JSON.stringify,
312
+ ), validationExitCode(report, failOn));
313
+ }
314
+ if (command === "feedback" && positional[0] === "draft") {
315
+ requireOption(options, "type");
316
+ const feedbackType = String(options.type);
317
+ if (!FEEDBACK_TYPES.includes(feedbackType)) {
318
+ throw invalidChoiceError("type", feedbackType, FEEDBACK_TYPES);
319
+ }
320
+ const draft = createFeedbackDraft({
321
+ root,
322
+ pcrId: options.pcr ? String(options.pcr) : "",
323
+ type: feedbackType,
324
+ affectedSection: String(options["affected-section"] ?? ""),
325
+ processId: String(options["process-id"] ?? ""),
326
+ flowRole: String(options["flow-role"] ?? ""),
327
+ summary: String(options.summary ?? ""),
328
+ evidence: String(options.evidence ?? ""),
329
+ proposedChange: String(options["proposed-change"] ?? ""),
330
+ });
331
+ if (format === "json") {
332
+ return ok(`${JSON.stringify(draft, null, 2)}\n`);
333
+ }
334
+ return ok(`# ${draft.title}\n\n${draft.body}`);
335
+ }
336
+
337
+ throw new CliError(
338
+ "PCR_CLI_UNKNOWN_COMMAND",
339
+ `Unknown command: ${[command, ...positional].filter(Boolean).join(" ")}`,
340
+ );
341
+ } catch (error) {
342
+ return fail(error, requestedFormat, requestedRoot, selected);
343
+ }
344
+ }
345
+
346
+ function ok(stdout, exitCode = 0) {
347
+ return { stdout, stderr: "", exitCode };
348
+ }
349
+
350
+ function consumptionPage(options) {
351
+ return {
352
+ page: positiveIntegerOption(options.page, "page", 1),
353
+ pageSize: positiveIntegerOption(options["page-size"], "page-size", 10, 100),
354
+ };
355
+ }
356
+
357
+ function validatePointerOptions(options, selector) {
358
+ if (options.pointer !== undefined && [selector, "page", "page-size"].some((key) => options[key] !== undefined)) {
359
+ throw new CliError("PCR_CLI_OPTION_CONFLICT", `Use --pointer alone, or --${selector} with optional pagination.`);
360
+ }
361
+ }
362
+
363
+ function withConsumptionContinuation(report, command, options) {
364
+ const parts = command === "guidance" ? commandPrefix(options) : ["tiangong-pcr"];
365
+ parts.push(command);
366
+ if (command === "guidance") parts.push(...sourceArguments(options));
367
+ for (const key of command === "guidance" ? ["pcr", "topic"] : ["input", "related", "section"]) {
368
+ if (options[key] !== undefined) parts.push(`--${key}`, shellToken(["input", "related"].includes(key) ? path.resolve(options[key]) : options[key]));
369
+ }
370
+ const pagination = report.pagination;
371
+ return {
372
+ ...report,
373
+ next_command: pagination?.has_more ? `${parts.join(" ")} --page ${pagination.page + 1} --page-size ${pagination.page_size} --format json` : null,
374
+ next_step: command === "guidance"
375
+ ? "Read relevant topics; use --pointer with an item's source.pointer for complete text. Judge applicability and cite the returned source."
376
+ : "Inspect paged exchanges/instances and references; use --pointer with source.pointer for full fields. Resolve evidence gaps before methodological conclusions.",
377
+ };
378
+ }
379
+
380
+ function consumptionOutput(report, options, exitCode = 0) {
381
+ const output = `${JSON.stringify(report, null, 2)}\n`;
382
+ if (options.output) {
383
+ const filename = path.resolve(String(options.output));
384
+ try { writeFileSync(filename, output, { encoding: "utf8", flag: "wx" }); }
385
+ catch (error) { throw new CliError("PCR_CLI_OUTPUT_WRITE", `Cannot create new output file ${filename}: ${error.message}. Choose an unused path in an existing directory.`); }
386
+ return ok(`${JSON.stringify({ artifact: filename, sha256: sha256(output), bytes: Buffer.byteLength(output), kind: report.report_kind ?? report.check_kind ?? report.guidance_kind ?? report.inspection_kind ?? report.calculation_kind, ...(report.envelope_valid === undefined ? {} : { envelope_valid: report.envelope_valid, methodology_approval: false }), next_step: "Read the saved artifact. Source inputs were not modified." }, null, 2)}\n`, exitCode);
387
+ }
388
+ if (output.length > 32768) throw new CliError("PCR_CLI_OUTPUT_LARGE", "Result exceeds 32768 characters. Use --output <new-file> for the complete artifact or request a smaller page/pointer.");
389
+ return ok(output, exitCode);
390
+ }
391
+
392
+ function fail(error, requestedFormat, requestedRoot, selected = null) {
393
+ const normalized = normalizeError(error);
394
+ if (
395
+ normalized.code === "PCR_LEGACY_ID_REDIRECT"
396
+ && normalized.details?.target
397
+ ) {
398
+ const originalNextCommand = normalized.details.next_command;
399
+ const nextCommand = legacyRedirectCommand(
400
+ normalized.details.target,
401
+ { root: requestedRoot, library: selected?.library, "library-sha256": selected?.["library-sha256"] },
402
+ );
403
+ normalized.details.next_command = nextCommand;
404
+ normalized.message = typeof originalNextCommand === "string"
405
+ && normalized.message.includes(originalNextCommand)
406
+ ? normalized.message.replace(originalNextCommand, nextCommand)
407
+ : `${normalized.message} Next: ${nextCommand}`;
408
+ }
409
+ if (requestedFormat === "json") {
410
+ return {
411
+ stdout: "",
412
+ stderr: `${JSON.stringify({ error: { ...normalized, exit_code: 1 } }, null, 2)}\n`,
413
+ exitCode: 1,
414
+ };
415
+ }
416
+ return {
417
+ stdout: "",
418
+ stderr: `[${normalized.code}] ${normalized.message}\n`,
419
+ exitCode: 1,
420
+ };
421
+ }
422
+
423
+ function requestedFormatFromArgv(argv) {
424
+ for (let index = argv.length - 2; index >= 0; index -= 1) {
425
+ if (argv[index] === "--format" && argv[index + 1] === "json") {
426
+ return "json";
427
+ }
428
+ }
429
+ const index = argv.lastIndexOf("--format");
430
+ return index >= 0 && typeof argv[index + 1] === "string" ? argv[index + 1] : null;
431
+ }
432
+
433
+ function requestedRootFromArgv(argv) {
434
+ const index = argv.lastIndexOf("--root");
435
+ const value = index >= 0 ? argv[index + 1] : undefined;
436
+ return typeof value === "string" && !value.startsWith("--") ? value : undefined;
437
+ }
438
+
439
+ function normalizeError(error) {
440
+ const message = error instanceof Error ? error.message : String(error);
441
+ const code = error instanceof CliError || /^PCR_/u.test(String(error?.code ?? ""))
442
+ ? String(error.code)
443
+ : "PCR_CLI_RUNTIME_ERROR";
444
+ const details = coreOrCliErrorDetails(error);
445
+ return details === undefined ? { code, message } : { code, message, details };
446
+ }
447
+
448
+ function coreOrCliErrorDetails(error) {
449
+ if (error instanceof CliError) {
450
+ return error.details;
451
+ }
452
+ if (error?.details !== undefined) {
453
+ return structuredClone(error.details);
454
+ }
455
+ if (error?.readiness !== undefined) {
456
+ return { readiness: structuredClone(error.readiness) };
457
+ }
458
+ if (typeof error?.toJSON === "function") {
459
+ const serialized = error.toJSON();
460
+ if (serialized && typeof serialized === "object") {
461
+ const { code: _code, ...details } = serialized;
462
+ return details;
463
+ }
464
+ }
465
+ if (error?.details && typeof error.details === "object") {
466
+ return structuredClone(error.details);
467
+ }
468
+ return undefined;
469
+ }
470
+
471
+ function commandDefinitionFor(command, positional = []) {
472
+ return COMMAND_DEFINITIONS.find((definition) => {
473
+ if (definition.command !== command) {
474
+ return false;
475
+ }
476
+ const expectedPositionals = definition.positional ?? [];
477
+ return expectedPositionals.length === positional.length
478
+ && expectedPositionals.every((value, index) => positional[index] === value);
479
+ });
480
+ }
481
+
482
+ function requireCommandDefinition(command, positional) {
483
+ const definition = commandDefinitionFor(command, positional);
484
+ if (definition) {
485
+ return definition;
486
+ }
487
+
488
+ if (command === "coverage") {
489
+ const subcommand = positional[0] ?? "";
490
+ if (!["summary", "list"].includes(subcommand)) {
491
+ throw new CliError(
492
+ "PCR_CLI_UNKNOWN_SUBCOMMAND",
493
+ `Unknown coverage subcommand${subcommand ? `: ${subcommand}` : ""}. Use \`coverage summary --classification <system>:<version>\` or \`coverage list --classification <system>:<version>\`.`,
494
+ { command: "coverage", subcommand: subcommand || null, valid_subcommands: ["summary", "list"] },
495
+ );
496
+ }
497
+ throw new CliError(
498
+ "PCR_CLI_UNEXPECTED_POSITIONAL",
499
+ `Unexpected positional argument(s) for coverage ${subcommand}: ${positional.slice(1).join(" ")}`,
500
+ );
501
+ }
502
+
503
+ const commandDefinitions = COMMAND_DEFINITIONS.filter((candidate) => candidate.command === command);
504
+ if (commandDefinitions.length > 0) {
505
+ const expected = commandDefinitions[0].positional ?? [];
506
+ const isExpectedPrefix = expected.every((value, index) => positional[index] === value);
507
+ if (isExpectedPrefix && positional.length > expected.length) {
508
+ throw new CliError(
509
+ "PCR_CLI_UNEXPECTED_POSITIONAL",
510
+ `Unexpected positional argument(s) for ${[command, ...expected].join(" ")}: ${positional.slice(expected.length).join(" ")}`,
511
+ );
512
+ }
513
+ }
514
+ throw new CliError(
515
+ "PCR_CLI_UNKNOWN_COMMAND",
516
+ `Unknown command: ${[command, ...positional].filter(Boolean).join(" ")}`,
517
+ );
518
+ }
519
+
520
+ function validateHelpInvocation({ command, positional, options }) {
521
+ if (command === "help" && positional.length > 0) {
522
+ throw new CliError(
523
+ "PCR_CLI_UNEXPECTED_POSITIONAL",
524
+ `Unexpected positional argument(s) for help: ${positional.join(" ")}`,
525
+ );
526
+ }
527
+ validateOptionsAgainst(options, GLOBAL_HELP_OPTIONS);
528
+ if (!command && options.help !== true && Object.keys(options).length > 0) {
529
+ throw new CliError(
530
+ "PCR_CLI_MISSING_COMMAND",
531
+ "Missing command. Run tiangong-pcr --help to inspect available commands.",
532
+ );
533
+ }
534
+ }
535
+
536
+ function validateCommandOptions(definition, options) {
537
+ const allowed = new Set([...GLOBAL_OPTIONS, ...(COMMAND_OPTIONS[definition.key] ?? [])]);
538
+ validateOptionsAgainst(options, allowed);
539
+ }
540
+
541
+ function validateOptionsAgainst(options, allowed) {
542
+ for (const [key, value] of Object.entries(options)) {
543
+ if (!allowed.has(key)) {
544
+ throw new CliError("PCR_CLI_UNKNOWN_OPTION", `Unknown option --${key}`, { option: key });
545
+ }
546
+ if (key === "help") {
547
+ if (value !== true) {
548
+ throw new CliError(
549
+ "PCR_CLI_INVALID_OPTION",
550
+ "Option --help does not accept a value.",
551
+ { option: key, value },
552
+ );
553
+ }
554
+ continue;
555
+ }
556
+ if (value === true) {
557
+ throw new CliError(
558
+ "PCR_CLI_MISSING_OPTION_VALUE",
559
+ `Option --${key} requires a value.`,
560
+ { option: key },
561
+ );
562
+ }
563
+ }
564
+ }
565
+
566
+ function validateCommandFormat(definition, formatValue) {
567
+ const format = String(formatValue ?? definition.defaultFormat);
568
+ if (!definition.formats.includes(format)) {
569
+ throw invalidChoiceError("format", format, definition.formats, {
570
+ command: [definition.command, ...(definition.positional ?? [])].join(" "),
571
+ });
572
+ }
573
+ return format;
574
+ }
575
+
576
+ function parseArgs(argv) {
577
+ const options = {};
578
+ const positional = [];
579
+ let command = "";
580
+
581
+ for (let index = 0; index < argv.length; index += 1) {
582
+ const token = argv[index];
583
+ if (token.startsWith("--")) {
584
+ const key = token.slice(2);
585
+ if (!key) {
586
+ throw new CliError("PCR_CLI_INVALID_ARGUMENT", "Unexpected bare -- argument.");
587
+ }
588
+ if (Object.hasOwn(options, key)) {
589
+ throw new CliError("PCR_CLI_DUPLICATE_OPTION", `Duplicate option --${key}`, { option: key });
590
+ }
591
+ const next = argv[index + 1];
592
+ if (next === undefined || next.startsWith("--")) {
593
+ options[key] = true;
594
+ continue;
595
+ }
596
+ options[key] = next;
597
+ index += 1;
598
+ continue;
599
+ }
600
+ if (!command) {
601
+ command = token;
602
+ continue;
603
+ }
604
+ positional.push(token);
605
+ }
606
+
607
+ return { command, positional, options };
608
+ }
609
+
610
+ function writeOutput(value, format, tableFormatter) {
611
+ if (format === "json") {
612
+ return `${JSON.stringify(value, null, 2)}\n`;
613
+ }
614
+ if (format === "markdown") {
615
+ return `${tableFormatter(value)}\n`;
616
+ }
617
+ return `${tableFormatter(value)}\n`;
618
+ }
619
+
620
+ function parseDatasetInput(text) {
621
+ try {
622
+ return JSON.parse(text);
623
+ } catch (error) {
624
+ throw new CliError(
625
+ "PCR_CLI_INVALID_DATASET_JSON",
626
+ `Malformed dataset JSON: ${error.message}`,
627
+ );
628
+ }
629
+ }
630
+
631
+ function readInputFile(value) {
632
+ const inputPath = path.resolve(String(value));
633
+ try {
634
+ return readFileSync(inputPath, "utf8");
635
+ } catch (error) {
636
+ throw new CliError(
637
+ "PCR_CLI_INPUT_READ_FAILED",
638
+ `Unable to read --input file ${inputPath}: ${error.message}`,
639
+ { input: inputPath },
640
+ );
641
+ }
642
+ }
643
+
644
+ function parseClassificationSelector(value, { includeCode }) {
645
+ const classification = String(value ?? "");
646
+ const parts = classification.split(":");
647
+ const expectedParts = includeCode ? 3 : 2;
648
+ if (parts.length !== expectedParts || parts.some((part) => part.length === 0)) {
649
+ const expected = includeCode
650
+ ? "<system>:<version>:<code>, for example cpc:3.0:01111"
651
+ : "<system>:<version>, for example cpc:3.0";
652
+ throw new CliError(
653
+ "PCR_CLI_INVALID_CLASSIFICATION",
654
+ `Use --classification ${expected}`,
655
+ { value: classification, expected_segments: expectedParts },
656
+ );
657
+ }
658
+ const [system, version, code] = parts;
659
+ if (
660
+ !/^[A-Za-z0-9][A-Za-z0-9_-]*$/u.test(system)
661
+ || !/^[A-Za-z0-9][A-Za-z0-9._-]*$/u.test(version)
662
+ || (includeCode && !/^[A-Za-z0-9][A-Za-z0-9._-]*$/u.test(code))
663
+ ) {
664
+ throw new CliError(
665
+ "PCR_CLI_INVALID_CLASSIFICATION",
666
+ `Invalid --classification "${classification}". Use identifier tokens without spaces or path separators.`,
667
+ { value: classification },
668
+ );
669
+ }
670
+ if (includeCode) {
671
+ return { system, version, code };
672
+ }
673
+ return { system, version };
674
+ }
675
+
676
+ function validateResolveSelector(options) {
677
+ const supplied = ["classification", "pcr"].filter(
678
+ (key) => options[key] !== undefined,
679
+ );
680
+ if (supplied.length !== 1) {
681
+ throw new CliError(
682
+ "PCR_CLI_EXACTLY_ONE_SELECTOR_REQUIRED",
683
+ "Resolve requires exactly one selector: --classification <system>:<version>:<code> or --pcr <pcr-id>.",
684
+ {
685
+ required_exactly_one_of: ["classification", "pcr"],
686
+ supplied,
687
+ },
688
+ );
689
+ }
690
+ }
691
+
692
+ function validateListOptions(options) {
693
+ if (options.status !== undefined && !VALID_PCR_STATUSES.has(String(options.status))) {
694
+ throw invalidChoiceError("status", String(options.status), PCR_STATUS_VALUES);
695
+ }
696
+ if (
697
+ options["content-maturity"] !== undefined
698
+ && !VALID_CONTENT_MATURITIES.has(String(options["content-maturity"]))
699
+ ) {
700
+ throw invalidChoiceError(
701
+ "content-maturity",
702
+ String(options["content-maturity"]),
703
+ CONTENT_MATURITY_VALUES,
704
+ );
705
+ }
706
+ if (options["path-prefix"] !== undefined) {
707
+ normalizePathPrefix(options["path-prefix"]);
708
+ }
709
+ validateCatalogScope(options.scope);
710
+ positiveIntegerOption(options.page, "page", 1);
711
+ positiveIntegerOption(options["page-size"], "page-size", 10, 100);
712
+ }
713
+
714
+ function validateCoverageListOptions(options) {
715
+ if (options.status !== undefined && !VALID_COVERAGE_STATUSES.has(String(options.status))) {
716
+ throw invalidChoiceError("status", String(options.status), CLASSIFICATION_COVERAGE_STATUSES, {
717
+ command: "coverage list",
718
+ });
719
+ }
720
+ positiveIntegerOption(options.page, "page", 1);
721
+ positiveIntegerOption(options["page-size"], "page-size", 10, 100);
722
+ }
723
+
724
+ function validateCatalogScope(value) {
725
+ if (value !== undefined && !VALID_CATALOG_SCOPES.has(String(value))) {
726
+ throw invalidChoiceError("scope", String(value), PCR_CATALOG_SCOPES);
727
+ }
728
+ }
729
+
730
+ function effectiveCatalogScope(options) {
731
+ validateCatalogScope(options.scope);
732
+ if (options.scope !== undefined) {
733
+ return {
734
+ requested: String(options.scope),
735
+ effective: String(options.scope),
736
+ source: "explicit",
737
+ };
738
+ }
739
+ if (String(options.status ?? "") === "scaffold") {
740
+ return { requested: null, effective: "legacy", source: "derived_from_status" };
741
+ }
742
+ if (String(options["content-maturity"] ?? "") === "empty_scaffold") {
743
+ return { requested: null, effective: "legacy", source: "derived_from_content_maturity" };
744
+ }
745
+ return { requested: null, effective: "material", source: "default" };
746
+ }
747
+
748
+ function filterPcrs(pcrs, options) {
749
+ let result = pcrs;
750
+ if (options.status) {
751
+ result = result.filter((entry) => entry.status === String(options.status));
752
+ }
753
+ if (options["content-maturity"]) {
754
+ result = result.filter((entry) => entry.content_maturity === String(options["content-maturity"]));
755
+ }
756
+ if (options["path-prefix"]) {
757
+ const prefix = normalizePathPrefix(options["path-prefix"]);
758
+ result = result.filter((entry) => {
759
+ const relativePath = String(entry.path).replace(/^library\/pcrs\/?/u, "");
760
+ return relativePath === prefix || relativePath.startsWith(`${prefix}/`);
761
+ });
762
+ }
763
+ return result;
764
+ }
765
+
766
+ function paginateList(pcrs, options, scope) {
767
+ const pageSize = positiveIntegerOption(options["page-size"], "page-size", 10, 100);
768
+ const page = positiveIntegerOption(options.page, "page", 1);
769
+ const totalCount = pcrs.length;
770
+ const totalPages = Math.max(1, Math.ceil(totalCount / pageSize));
771
+ if (page > totalPages) {
772
+ throw new CliError(
773
+ "PCR_CLI_PAGE_OUT_OF_RANGE",
774
+ `--page ${page} is out of range. Available pages: 1-${totalPages}.`,
775
+ { page, total_pages: totalPages },
776
+ );
777
+ }
778
+ const startIndex = (page - 1) * pageSize;
779
+ const items = pcrs.slice(startIndex, startIndex + pageSize);
780
+ const nextPage = page < totalPages ? page + 1 : null;
781
+ const previousPage = page > 1 ? page - 1 : null;
782
+
783
+ return {
784
+ filters: {
785
+ scope: scope.effective,
786
+ status: options.status ? String(options.status) : null,
787
+ content_maturity: options["content-maturity"]
788
+ ? String(options["content-maturity"])
789
+ : null,
790
+ path_prefix: options["path-prefix"]
791
+ ? normalizePathPrefix(options["path-prefix"])
792
+ : null,
793
+ },
794
+ requested_scope: scope.requested,
795
+ effective_scope: scope.effective,
796
+ scope_source: scope.source,
797
+ page,
798
+ page_size: pageSize,
799
+ total_count: totalCount,
800
+ total_pages: totalPages,
801
+ has_more: nextPage !== null,
802
+ items,
803
+ previous_command: previousPage ? buildListCommand({ ...options, page: previousPage }) : null,
804
+ next_command: nextPage ? buildListCommand({ ...options, page: nextPage }) : null,
805
+ next_steps: [
806
+ "If you have a classification code, prefer npm --silent run tiangong-pcr -- resolve --classification <system>:<version>:<code>.",
807
+ "If the correct PCR is unclear, inspect npm --silent run tiangong-pcr -- tree --depth 3 and then open candidate guidance.",
808
+ "Check items[].readiness and run npm --silent run tiangong-pcr -- guidance --pcr <pcr-id> --format json only when usable_for_guidance is true.",
809
+ ],
810
+ };
811
+ }
812
+
813
+ function coverageSummaryOutput(summary, options) {
814
+ const classification = `${String(summary.classification_system).toLowerCase()}:${summary.classification_version}`;
815
+ return {
816
+ ...summary,
817
+ completeness: {
818
+ status: "complete",
819
+ bounded: true,
820
+ entry_details_included: false,
821
+ },
822
+ next_command: buildCoverageListCommand({
823
+ ...options,
824
+ classification: options.classification ?? classification,
825
+ page: 1,
826
+ }),
827
+ next_steps: [
828
+ "Use coverage list with --status to inspect a bounded, paginated subset.",
829
+ "Use resolve --classification <system>:<version>:<code> for deterministic resolution; candidate suggestions are never selected automatically.",
830
+ ],
831
+ };
832
+ }
833
+
834
+ function paginateCoverage(result, classification, options) {
835
+ const pageSize = positiveIntegerOption(options["page-size"], "page-size", 10, 100);
836
+ const page = positiveIntegerOption(options.page, "page", 1);
837
+ const totalCount = result.entries.length;
838
+ const totalPages = Math.max(1, Math.ceil(totalCount / pageSize));
839
+ if (page > totalPages) {
840
+ throw new CliError(
841
+ "PCR_CLI_PAGE_OUT_OF_RANGE",
842
+ `--page ${page} is out of range. Available pages: 1-${totalPages}.`,
843
+ { page, total_pages: totalPages },
844
+ );
845
+ }
846
+ const startIndex = (page - 1) * pageSize;
847
+ const items = result.entries.slice(startIndex, startIndex + pageSize);
848
+ const previousPage = page > 1 ? page - 1 : null;
849
+ const nextPage = page < totalPages ? page + 1 : null;
850
+ const commandOptions = {
851
+ ...options,
852
+ classification: options.classification ?? `${classification.system}:${classification.version}`,
853
+ };
854
+ return {
855
+ classification: {
856
+ system: result.classification_system,
857
+ version: result.classification_version,
858
+ },
859
+ filters: {
860
+ status: options.status === undefined ? null : String(options.status),
861
+ },
862
+ available_statuses: result.available_statuses,
863
+ completeness: {
864
+ status: nextPage === null && previousPage === null ? "complete" : "paginated",
865
+ page,
866
+ page_size: pageSize,
867
+ returned_count: items.length,
868
+ total_count: totalCount,
869
+ total_pages: totalPages,
870
+ has_more: nextPage !== null,
871
+ },
872
+ items,
873
+ previous_command: previousPage
874
+ ? buildCoverageListCommand({ ...commandOptions, page: previousPage })
875
+ : null,
876
+ next_command: nextPage
877
+ ? buildCoverageListCommand({ ...commandOptions, page: nextPage })
878
+ : null,
879
+ next_steps: [
880
+ "Continue with previous_command or next_command when present; pagination is explicit and deterministic.",
881
+ "Run resolve --classification <system>:<version>:<code> for an exact code. This command does not fuzzy-match or auto-select candidate suggestions.",
882
+ ],
883
+ };
884
+ }
885
+
886
+ function buildCoverageListCommand(options) {
887
+ const parts = [...commandPrefix(options), "coverage", "list"];
888
+ parts.push("--classification", shellToken(String(options.classification)));
889
+ if (options.status) {
890
+ parts.push("--status", shellToken(String(options.status)));
891
+ }
892
+ if (options["page-size"]) {
893
+ parts.push("--page-size", shellToken(String(options["page-size"])));
894
+ }
895
+ if (options.page) {
896
+ parts.push("--page", shellToken(String(options.page)));
897
+ }
898
+ parts.push(...sourceArguments(options));
899
+ if (options.format) {
900
+ parts.push("--format", shellToken(String(options.format)));
901
+ }
902
+ return parts.join(" ");
903
+ }
904
+
905
+ function treeOutput(tree, depth, scope) {
906
+ return {
907
+ scope: "library/pcrs",
908
+ requested_scope: scope.requested,
909
+ effective_scope: scope.effective,
910
+ scope_source: scope.source,
911
+ depth,
912
+ completeness: depth >= 3 ? "complete" : "partial",
913
+ tree,
914
+ next_steps: depth >= 3
915
+ ? [
916
+ "Inspect PCR leaf readiness and run npm --silent run tiangong-pcr -- guidance --pcr <pcr-id> --format json only when usable_for_guidance is true.",
917
+ ]
918
+ : [
919
+ "Choose a visible path and run npm --silent run tiangong-pcr -- list --path-prefix <path> --format json.",
920
+ "Use --depth 3 only when a complete hierarchy is required; the full tree is large.",
921
+ ],
922
+ };
923
+ }
924
+
925
+ function resolveOutput(resolution, options) {
926
+ const usable = resolution.pcr?.readiness?.usable_for_guidance === true;
927
+ const pcrId = resolution.mapping?.pcr_id;
928
+ const guidanceCommand = usable && resolution.resolution_status === "mapped" && pcrId
929
+ ? [
930
+ `${commandPrefix(options).join(" ")} guidance`,
931
+ `--pcr ${shellToken(String(pcrId))}`,
932
+ sourceArguments(options).join(" "),
933
+ "--format json",
934
+ ].filter(Boolean).join(" ")
935
+ : null;
936
+ if (resolution.resolution_status === "unmapped") {
937
+ const [system, version] = String(options.classification).split(":");
938
+ const coverageCommand = buildCoverageListCommand({
939
+ classification: `${system}:${version}`,
940
+ status: resolution.coverage_status,
941
+ root: options.root,
942
+ library: options.library,
943
+ "library-sha256": options["library-sha256"],
944
+ format: "json",
945
+ page: 1,
946
+ });
947
+ return {
948
+ ...resolution,
949
+ next_command: coverageCommand,
950
+ next_steps: [
951
+ "No accepted PCR mapping was selected. Candidate suggestions and manual-review targets remain evidence only.",
952
+ "Use next_command to inspect the same coverage status, or draft missing_pcr feedback with supporting evidence.",
953
+ ],
954
+ };
955
+ }
956
+ if (resolution.resolution_status === "legacy_scaffold_compatibility") {
957
+ return {
958
+ ...resolution,
959
+ next_command: null,
960
+ next_steps: [
961
+ "This is a legacy scaffold compatibility reference, not usable PCR methodology.",
962
+ "Do not run guidance. Draft missing_pcr feedback if material methodology is required.",
963
+ ],
964
+ };
965
+ }
966
+ return {
967
+ ...resolution,
968
+ next_command: guidanceCommand,
969
+ next_steps: usable
970
+ ? ["Run next_command to obtain foreground data-production guidance."]
971
+ : [
972
+ "The mapping identifies a PCR, but its readiness blocks guidance; inspect pcr.readiness.blockers.",
973
+ "Draft feedback when the mapping or missing methodology prevents the requested work.",
974
+ ],
975
+ };
976
+ }
977
+
978
+ function resolvePcrIdentityOutput(resolution, options) {
979
+ if (resolution.resolution_status === "legacy_id_redirect") {
980
+ const nextCommand = legacyRedirectCommand(resolution.redirect.target, options);
981
+ return {
982
+ ...resolution,
983
+ redirect: {
984
+ ...resolution.redirect,
985
+ next_command: nextCommand,
986
+ },
987
+ next_command: nextCommand,
988
+ next_steps: [
989
+ "This PCR id is retired. The target is a locator, not automatically selected methodology.",
990
+ "Run next_command explicitly to inspect the classification coverage or canonical PCR target.",
991
+ ],
992
+ };
993
+ }
994
+
995
+ const usable = resolution.pcr?.readiness?.usable_for_guidance === true;
996
+ const nextCommand = usable
997
+ ? [
998
+ `${commandPrefix(options).join(" ")} guidance`,
999
+ `--pcr ${shellToken(String(resolution.pcr.id))}`,
1000
+ sourceArguments(options).join(" "),
1001
+ "--format json",
1002
+ ].filter(Boolean).join(" ")
1003
+ : null;
1004
+ return {
1005
+ ...resolution,
1006
+ next_command: nextCommand,
1007
+ next_steps: usable
1008
+ ? ["The PCR id is canonical. Run next_command to obtain foreground data-production guidance."]
1009
+ : [
1010
+ "The PCR id is canonical, but readiness blocks guidance; inspect pcr.readiness.blockers.",
1011
+ ],
1012
+ };
1013
+ }
1014
+
1015
+ function legacyRedirectCommand(target, options) {
1016
+ const selector = target.kind === "classification_coverage"
1017
+ ? [
1018
+ "--classification",
1019
+ shellToken(
1020
+ `${target.classification_system}:${target.classification_version}:${target.code}`,
1021
+ ),
1022
+ ]
1023
+ : ["--pcr", shellToken(String(target.pcr_id))];
1024
+ return [
1025
+ `${commandPrefix(options).join(" ")} resolve`,
1026
+ ...selector,
1027
+ sourceArguments(options).join(" "),
1028
+ "--format json",
1029
+ ].filter(Boolean).join(" ");
1030
+ }
1031
+
1032
+ function validationExitCode(report, failOnValue) {
1033
+ const failOn = validateFailOn(failOnValue);
1034
+ if (failOn === "never") {
1035
+ return 0;
1036
+ }
1037
+ if (report.validation_status === "inconclusive") {
1038
+ return 2;
1039
+ }
1040
+ const errorCount = report.finding_summary?.error ?? 0;
1041
+ const warningCount = report.finding_summary?.warning ?? 0;
1042
+ if (failOn === "error" && errorCount > 0) {
1043
+ return 2;
1044
+ }
1045
+ if (failOn === "warning" && errorCount + warningCount > 0) {
1046
+ return 2;
1047
+ }
1048
+ return 0;
1049
+ }
1050
+
1051
+ function formatListTable(page) {
1052
+ const lines = [
1053
+ "PCR id | Status | Readiness | Title | Record kind",
1054
+ "--- | --- | --- | --- | ---",
1055
+ ];
1056
+ for (const pcr of page.items) {
1057
+ lines.push(`${pcr.id} | ${pcr.status} | ${pcr.readiness?.status ?? "unknown"} | ${pcr.title["en-US"] ?? ""} | ${pcr.record_kind}`);
1058
+ }
1059
+ const start = page.total_count === 0 ? 0 : (page.page - 1) * page.page_size + 1;
1060
+ const end = Math.min(page.page * page.page_size, page.total_count);
1061
+ lines.push("");
1062
+ lines.push(`Effective scope: ${page.effective_scope} (${page.scope_source}).`);
1063
+ lines.push(`Showing ${start}-${end} of ${page.total_count} PCR records. Page ${page.page} of ${page.total_pages}.`);
1064
+ if (page.previous_command) {
1065
+ lines.push(`Previous page: ${page.previous_command}`);
1066
+ }
1067
+ if (page.next_command) {
1068
+ lines.push(`Next page: ${page.next_command}`);
1069
+ }
1070
+ lines.push("Next step: inspect readiness and run `npm --silent run tiangong-pcr -- guidance --pcr <pcr-id> --format json` only when `usable_for_guidance` is true; use `npm --silent run tiangong-pcr -- resolve` when you have a classification code.");
1071
+ return lines.join("\n");
1072
+ }
1073
+
1074
+ function formatCoverageSummary(result) {
1075
+ const lines = [
1076
+ `Classification coverage: ${result.classification_system} ${result.classification_version}`,
1077
+ "",
1078
+ "Status | Count",
1079
+ "--- | ---:",
1080
+ ];
1081
+ for (const status of CLASSIFICATION_COVERAGE_STATUSES) {
1082
+ lines.push(`${status} | ${result.summary[status]}`);
1083
+ }
1084
+ lines.push(`total | ${result.summary.total}`);
1085
+ lines.push("");
1086
+ lines.push("Summary is complete and bounded; individual entries are not included.");
1087
+ lines.push(`Next: ${result.next_command}`);
1088
+ return lines.join("\n");
1089
+ }
1090
+
1091
+ function formatCoverageList(result) {
1092
+ const lines = [
1093
+ `Classification coverage: ${result.classification.system} ${result.classification.version}`,
1094
+ "",
1095
+ "Code | Coverage status | Label | Resolution evidence",
1096
+ "--- | --- | --- | ---",
1097
+ ];
1098
+ for (const entry of result.items) {
1099
+ const evidence = entry.mapping?.pcr_id ?? entry.legacy_reference?.pcr_id ?? "none";
1100
+ lines.push(`${entry.code} | ${entry.coverage_status} | ${entry.label} | ${evidence}`);
1101
+ }
1102
+ const completeness = result.completeness;
1103
+ lines.push("");
1104
+ lines.push(
1105
+ `Filter status: ${result.filters.status ?? "all"}. Showing ${completeness.returned_count} of ${completeness.total_count} entries on page ${completeness.page} of ${completeness.total_pages}.`,
1106
+ );
1107
+ if (result.previous_command) {
1108
+ lines.push(`Previous page: ${result.previous_command}`);
1109
+ }
1110
+ if (result.next_command) {
1111
+ lines.push(`Next page: ${result.next_command}`);
1112
+ }
1113
+ lines.push("Next: run `npm --silent run tiangong-pcr -- resolve --classification <system>:<version>:<code> --format json` for an exact code; no fuzzy or candidate auto-selection is performed.");
1114
+ return lines.join("\n");
1115
+ }
1116
+
1117
+ function positiveIntegerOption(value, optionName, fallback, maximum = Infinity) {
1118
+ if (value === undefined) {
1119
+ return fallback;
1120
+ }
1121
+ const token = String(value);
1122
+ const parsed = Number(token);
1123
+ if (!/^[1-9][0-9]*$/u.test(token) || !Number.isSafeInteger(parsed) || parsed > maximum) {
1124
+ const expectation = Number.isFinite(maximum)
1125
+ ? `a positive safe integer no greater than ${maximum}`
1126
+ : "a positive safe integer";
1127
+ throw new CliError(
1128
+ "PCR_CLI_INVALID_INTEGER_OPTION",
1129
+ `Invalid --${optionName} "${value}". Expected ${expectation}.`,
1130
+ { option: optionName, value: String(value), maximum: Number.isFinite(maximum) ? maximum : null },
1131
+ );
1132
+ }
1133
+ return parsed;
1134
+ }
1135
+
1136
+ function validateFailOn(value) {
1137
+ const failOn = String(value ?? "error");
1138
+ if (!VALID_FAIL_ON.has(failOn)) {
1139
+ throw invalidChoiceError("fail-on", failOn, [...VALID_FAIL_ON]);
1140
+ }
1141
+ return failOn;
1142
+ }
1143
+
1144
+ function invalidChoiceError(option, value, choices, details = {}) {
1145
+ return new CliError(
1146
+ "PCR_CLI_INVALID_CHOICE",
1147
+ `Invalid --${option} "${value}". Expected one of: ${choices.join(", ")}.`,
1148
+ { option, value, choices: [...choices], ...details },
1149
+ );
1150
+ }
1151
+
1152
+ function normalizePathPrefix(value) {
1153
+ const original = String(value);
1154
+ const prefix = original.replace(/^library\/pcrs\/?/u, "").replace(/^\/+|\/+$/gu, "");
1155
+ const segments = prefix.split("/");
1156
+ if (
1157
+ prefix.length === 0
1158
+ || original.includes("\\")
1159
+ || segments.some((segment) => segment.length === 0 || segment === "." || segment === "..")
1160
+ ) {
1161
+ throw new CliError(
1162
+ "PCR_CLI_INVALID_PATH_PREFIX",
1163
+ `Invalid --path-prefix "${original}". Use a slash-delimited path below library/pcrs without . or .. segments.`,
1164
+ { option: "path-prefix", value: original },
1165
+ );
1166
+ }
1167
+ return prefix;
1168
+ }
1169
+
1170
+ function buildListCommand(options) {
1171
+ const parts = [...commandPrefix(options), "list"];
1172
+ if (options.scope) {
1173
+ parts.push("--scope", shellToken(String(options.scope)));
1174
+ }
1175
+ if (options.status) {
1176
+ parts.push("--status", shellToken(String(options.status)));
1177
+ }
1178
+ if (options["content-maturity"]) {
1179
+ parts.push("--content-maturity", shellToken(String(options["content-maturity"])));
1180
+ }
1181
+ if (options["path-prefix"]) {
1182
+ parts.push("--path-prefix", shellToken(String(options["path-prefix"])));
1183
+ }
1184
+ if (options["page-size"]) {
1185
+ parts.push("--page-size", shellToken(String(options["page-size"])));
1186
+ }
1187
+ if (options.page) {
1188
+ parts.push("--page", shellToken(String(options.page)));
1189
+ }
1190
+ parts.push(...sourceArguments(options));
1191
+ if (options.format) {
1192
+ parts.push("--format", shellToken(String(options.format)));
1193
+ }
1194
+ return parts.join(" ");
1195
+ }
1196
+
1197
+ function commandPrefix(options) {
1198
+ return options.library ? ["tiangong-pcr"] : ["npm", "--silent", "run", "tiangong-pcr", "--"];
1199
+ }
1200
+ function sourceArguments(options) {
1201
+ const parts = options.library ? ["--library", shellToken(String(options.library))] : options.root ? ["--root", shellToken(String(options.root))] : [];
1202
+ if (options["library-sha256"]) parts.push("--library-sha256", shellToken(String(options["library-sha256"])));
1203
+ return parts;
1204
+ }
1205
+
1206
+ function shellToken(value) {
1207
+ return /^[A-Za-z0-9_./:-]+$/u.test(value)
1208
+ ? value
1209
+ : `'${String(value).replaceAll("'", `'"'"'`)}'`;
1210
+ }
1211
+
1212
+ function formatTreeMarkdown(tree, depth, scope) {
1213
+ const lines = [];
1214
+ lines.push(`Effective scope: ${scope.effective} (${scope.source}).`);
1215
+ lines.push("");
1216
+ renderTreeNode(tree, lines, 0);
1217
+ lines.push("");
1218
+ if (depth < 3) {
1219
+ lines.push(`This hierarchy is partial at depth ${depth}.`);
1220
+ lines.push("Next: run `npm --silent run tiangong-pcr -- list --path-prefix <visible-path>` to inspect paginated PCR records and readiness.");
1221
+ } else {
1222
+ lines.push("Next: inspect leaf readiness and run `npm --silent run tiangong-pcr -- guidance --pcr <pcr-id> --format json` only when `usable_for_guidance` is true.");
1223
+ }
1224
+ return lines.join("\n");
1225
+ }
1226
+
1227
+ function renderTreeNode(node, lines, depth) {
1228
+ for (const [segment, value] of Object.entries(node).sort(([left], [right]) => left.localeCompare(right))) {
1229
+ lines.push(`${" ".repeat(depth)}- ${segment}`);
1230
+ for (const pcr of value.pcrs ?? []) {
1231
+ const readiness = pcr.readiness ?? {};
1232
+ lines.push(
1233
+ `${" ".repeat(depth + 1)}- ${pcr.id} (readiness: ${readiness.status ?? "unknown"}; usable_for_guidance: ${readiness.usable_for_guidance === true})`,
1234
+ );
1235
+ }
1236
+ renderTreeNode(value.children ?? {}, lines, depth + 1);
1237
+ }
1238
+ }
1239
+
1240
+ function requireOption(options, key) {
1241
+ if (!options[key]) {
1242
+ throw new CliError(
1243
+ "PCR_CLI_MISSING_REQUIRED_OPTION",
1244
+ `Missing required option --${key}`,
1245
+ { option: key },
1246
+ );
1247
+ }
1248
+ }
1249
+
1250
+ function helpText(command = "", positional = []) {
1251
+ const definition = commandDefinitionFor(command, positional);
1252
+ if (command === "library") return `Usage: tiangong-pcr library info|verify --library <library.sqlite> [--library-sha256 sha256:<hex>] [--format json]\n\nRead snapshot identity, or verify the entire database checksum and SQLite integrity. No writes or network requests. Keep the manifest and pin with your task.\n`;
1253
+ if (!definition) {
1254
+ return globalHelpText();
1255
+ }
1256
+ if (definition.key === "list") {
1257
+ return `Usage: tiangong-pcr list [options]
1258
+
1259
+ Browse PCR records explicitly. This is catalog browsing, not fuzzy search.
1260
+
1261
+ Options:
1262
+ --scope all|material|legacy Record scope. Defaults to material. A scaffold/empty-scaffold filter derives legacy when scope is omitted.
1263
+ --status <status> Filter by manifest status, for example candidate or scaffold.
1264
+ --content-maturity <state> Filter by content maturity.
1265
+ --path-prefix <path> Filter below library/pcrs by a slash-delimited path prefix.
1266
+ --page <n> Page number. Defaults to 1.
1267
+ --page-size <n> Records per page, from 1 to 100. Defaults to 10 records per page.
1268
+ --format json|markdown|table Output format. Defaults to table.
1269
+ --root <path> PCR repository root.
1270
+ --library <file> Local library.sqlite (or PCR_LIBRARY). Mutually exclusive with --root.
1271
+ --library-sha256 <sha256:hex> Verify and pin the complete snapshot before reading.
1272
+ --help Show this command help.
1273
+
1274
+ JSON output:
1275
+ {
1276
+ "filters": { "scope": "material", "status": null, "content_maturity": null, "path_prefix": null },
1277
+ "effective_scope": "material",
1278
+ "scope_source": "default",
1279
+ "page": 1,
1280
+ "page_size": 10,
1281
+ "total_count": 3,
1282
+ "total_pages": 1,
1283
+ "has_more": false,
1284
+ "items": [{ "id": "<pcr-id>", "readiness": { "usable_for_guidance": true } }],
1285
+ "previous_command": null,
1286
+ "next_command": null,
1287
+ "next_steps": []
1288
+ }
1289
+
1290
+ Agent next step:
1291
+ Follow next_command when present. Use --scope all or --scope legacy only when those records are required.
1292
+ Inspect each record's readiness, and only when
1293
+ usable_for_guidance is true run:
1294
+ npm --silent run tiangong-pcr -- guidance --pcr <pcr-id> --format json
1295
+ `;
1296
+ }
1297
+ if (definition.key === "tree") {
1298
+ return `Usage: tiangong-pcr tree [options]
1299
+
1300
+ Show the PCR directory hierarchy so an Agent can inspect available categories before selecting a PCR.
1301
+
1302
+ Options:
1303
+ --depth <n> Limit hierarchy depth. Defaults to 2.
1304
+ --scope all|material|legacy Record scope. Defaults to material.
1305
+ --format json|markdown Output format. Defaults to markdown.
1306
+ --root <path> PCR repository root.
1307
+ --library <file> Local library.sqlite (or PCR_LIBRARY). Mutually exclusive with --root.
1308
+ --library-sha256 <sha256:hex> Verify and pin the complete snapshot before reading.
1309
+ --help Show this command help.
1310
+
1311
+ JSON output includes scope, requested depth, completeness, tree, and next_steps.
1312
+
1313
+ Agent next step:
1314
+ Use tree to narrow the category area, then run:
1315
+ npm --silent run tiangong-pcr -- list --path-prefix <path>
1316
+ Markdown PCR leaves include readiness and usable_for_guidance when --depth reaches them.
1317
+ `;
1318
+ }
1319
+ if (definition.key === "coverage") {
1320
+ return `Usage: tiangong-pcr coverage <summary|list> [options]
1321
+
1322
+ Inspect deterministic PCR coverage for one explicit classification system and version.
1323
+ This command family does not perform fuzzy search or automatically select candidate suggestions.
1324
+
1325
+ Subcommands:
1326
+ coverage summary --classification <system>:<version> [--format json|table]
1327
+ Return bounded aggregate counts without leaf entries.
1328
+ coverage list --classification <system>:<version> [--status <coverage-status>] [--page <n>] [--page-size <n>] [--format json|table]
1329
+ Return an explicitly filtered, paginated leaf list with completeness and continuation commands.
1330
+
1331
+ Selector:
1332
+ --classification <system>:<version> Example: cpc:3.0. A leaf code belongs only on resolve.
1333
+
1334
+ Output:
1335
+ summary and list support json|table. JSON stdout is stable and remains clean on success.
1336
+
1337
+ Agent next step:
1338
+ Start with:
1339
+ npm --silent run tiangong-pcr -- coverage summary --classification cpc:3.0 --format json
1340
+ Then follow next_command or run coverage list with an explicit status filter.
1341
+ `;
1342
+ }
1343
+ if (definition.key === "coverage:summary") {
1344
+ return `Usage: tiangong-pcr coverage summary --classification <system>:<version> [options]
1345
+
1346
+ Show bounded aggregate coverage for one explicit classification system and version.
1347
+ This command does not list leaves and does not perform fuzzy search.
1348
+
1349
+ Options:
1350
+ --classification <value> Example: cpc:3.0.
1351
+ --format json|table Output format. Defaults to table.
1352
+ --root <path> PCR repository root.
1353
+ --library <file> Local library.sqlite (or PCR_LIBRARY). Mutually exclusive with --root.
1354
+ --library-sha256 <sha256:hex> Verify and pin the complete snapshot before reading.
1355
+ --help Show this command help.
1356
+
1357
+ JSON output includes source, complete status counts, a bounded completeness marker, and next_command.
1358
+
1359
+ Agent next step:
1360
+ Run next_command or use coverage list --classification cpc:3.0 --status <status>
1361
+ to inspect a paginated subset.
1362
+ `;
1363
+ }
1364
+ if (definition.key === "coverage:list") {
1365
+ return `Usage: tiangong-pcr coverage list --classification <system>:<version> [options]
1366
+
1367
+ List explicit classification leaves and their PCR coverage status. This is deterministic coverage browsing, not fuzzy search.
1368
+
1369
+ Options:
1370
+ --classification <value> Example: cpc:3.0.
1371
+ --status <status> Filter by mapped, unmapped, candidate_suggestion, manual_review, or unknown.
1372
+ --page <n> Page number. Defaults to 1.
1373
+ --page-size <n> Entries per page, from 1 to 100. Defaults to 10.
1374
+ --format json|table Output format. Defaults to table.
1375
+ --root <path> PCR repository root.
1376
+ --library <file> Local library.sqlite (or PCR_LIBRARY). Mutually exclusive with --root.
1377
+ --library-sha256 <sha256:hex> Verify and pin the complete snapshot before reading.
1378
+ --help Show this command help.
1379
+
1380
+ JSON output keeps filters, completeness, items, previous_command, and next_command stable.
1381
+ Candidate suggestions and manual-review targets are evidence only and are never selected as accepted PCR mappings.
1382
+
1383
+ Agent next step:
1384
+ Follow the pagination commands, then run resolve --classification <system>:<version>:<code> for an exact leaf.
1385
+ `;
1386
+ }
1387
+ if (definition.key === "resolve") {
1388
+ return `Usage: tiangong-pcr resolve (--classification <system>:<version>:<code> | --pcr <pcr-id>) [options]
1389
+
1390
+ Resolve exactly one external classification code or PCR identity through deterministic contracts.
1391
+ This command does not perform fuzzy search and never silently follows a retired PCR id.
1392
+ Only coverage_status=mapped selects a material PCR. Known unmapped codes return success with mapping and pcr set to null.
1393
+ Retired PCR ids return a redirect locator and copyable next command without automatically following the target.
1394
+ Candidate suggestions and manual-review targets are never auto-selected.
1395
+ Even a mapped result does not prove that the methodology is usable; inspect PCR readiness.
1396
+
1397
+ Options:
1398
+ --classification <value> Example: cpc:3.0:01111.
1399
+ --pcr <pcr-id> Exact current or retired PCR id. Mutually exclusive with --classification.
1400
+ --format json Output format. JSON is recommended for Agents.
1401
+ --root <path> PCR repository root.
1402
+ --library <file> Local library.sqlite (or PCR_LIBRARY). Mutually exclusive with --root.
1403
+ --library-sha256 <sha256:hex> Verify and pin the complete snapshot before reading.
1404
+ --help Show this command help.
1405
+
1406
+ Examples:
1407
+ npm --silent run tiangong-pcr -- resolve --classification cpc:3.0:01111 --format json
1408
+ npm --silent run tiangong-pcr -- resolve --pcr <pcr-id> --format json
1409
+
1410
+ Agent next step:
1411
+ Inspect resolution_status. For legacy_id_redirect, run next_command explicitly; the target was not auto-selected.
1412
+ Only when the selected canonical or mapped PCR has readiness.usable_for_guidance=true, run:
1413
+ npm --silent run tiangong-pcr -- guidance --pcr <mapping.pcr_id> --format json
1414
+ `;
1415
+ }
1416
+ if (definition.key === "show") {
1417
+ return `Usage: tiangong-pcr show --pcr <pcr-id> [options]
1418
+
1419
+ Offline snapshots contain English only; use --lang en-US. Other languages require repository mode.
1420
+
1421
+ Print the human-readable PCR Markdown.
1422
+
1423
+ Options:
1424
+ --pcr <pcr-id> PCR id to display.
1425
+ --lang en-US|zh-CN Markdown language. Defaults to en-US.
1426
+ --format markdown Output format. Defaults to markdown.
1427
+ --root <path> PCR repository root.
1428
+ --library <file> Local library.sqlite (or PCR_LIBRARY). Mutually exclusive with --root.
1429
+ --library-sha256 <sha256:hex> Verify and pin the complete snapshot before reading.
1430
+ --help Show this command help.
1431
+
1432
+ Agent next step:
1433
+ Use show for human review. Use guidance for machine-readable foreground data-production rules.
1434
+ `;
1435
+ }
1436
+ if (definition.key === "guidance") {
1437
+ return `Usage: tiangong-pcr guidance --pcr <pcr-id> [options]
1438
+
1439
+ Print Agent-facing structured PCR guidance from generated structured.yaml.
1440
+ This command rejects scaffold, incomplete, deprecated, or otherwise unusable PCR methodology.
1441
+
1442
+ Options:
1443
+ --pcr <pcr-id> PCR id.
1444
+ --topic <topic> Bounded, cited selection (default overview when paging).
1445
+ --pointer <JSON Pointer> Read a complete value from the verified structured projection.
1446
+ --page <n> --page-size <n> Topic pagination; default 10, maximum 100 items.
1447
+ --output <new-file> Save complete JSON without overwriting an existing file.
1448
+ --format json Output format. JSON is recommended for Agents.
1449
+ --root <path> PCR repository root.
1450
+ --library <file> Local library.sqlite (or PCR_LIBRARY). Mutually exclusive with --root.
1451
+ --library-sha256 <sha256:hex> Verify and pin the complete snapshot before reading.
1452
+ --help Show this command help.
1453
+
1454
+ JSON output includes:
1455
+ pcr, readiness, system_boundary, reference_flow, measurement_rules, process_map,
1456
+ process_inventory, allocation_rules, validation_rules, data_sources, and validation_notes.
1457
+ Without selection flags, the legacy full guidance shape is preserved.
1458
+ Selected guidance includes source pointers, content hashes, readiness and pagination.
1459
+
1460
+ Topics:
1461
+ ${GUIDANCE_TOPICS.join(", ")}
1462
+
1463
+ Example:
1464
+ tiangong-pcr guidance --pcr <pcr-id> --topic boundary --format json
1465
+ tiangong-pcr guidance --pcr <pcr-id> --pointer /system_boundary/rules/0 --format json
1466
+
1467
+ Agent next step:
1468
+ Choose general LCA authoring, optional TIDAS authoring or existing-data review.
1469
+ Judge applicability and declared scope. Cite returned source references; expand truncated items with --pointer.
1470
+ `;
1471
+ }
1472
+ if (definition.key === "inspect") {
1473
+ return `Usage: tiangong-pcr inspect --input <native-tidas.json> [options]
1474
+
1475
+ Read local TIDAS process/model/support datasets without changing them or fetching references.
1476
+ This is fact inspection, not TIDAS schema validation or PCR compliance. No PCR library is needed.
1477
+
1478
+ Options:
1479
+ --input <file> One native TIDAS JSON dataset; wrapped rows are unsupported.
1480
+ --related <directory> Explicit local package: at most 200 JSON files / 64 MiB total.
1481
+ --section <section> ${INSPECTION_SECTIONS.join("|")}; default summary.
1482
+ --pointer <JSON Pointer> Read a full original value; mutually exclusive with section/paging.
1483
+ --page <n> --page-size <n> Paged sections: default 10, maximum 100 items.
1484
+ --output <new-file> Save complete JSON; existing files are never overwritten.
1485
+ --format json --help JSON output or this help.
1486
+
1487
+ Output:
1488
+ Original file/hash/pointer evidence, explicitly partial scope, local reference statuses and next_command.
1489
+ Previews may be truncated; --pointer retrieves the complete value, --output saves large results.
1490
+ References match kind, UUID and requested version; duplicate matches are ambiguous.
1491
+ Missing/unsupported identities remain unresolved. Unspecified versions are disclosed.
1492
+ Related JSON without a dataset root is ignored explicitly; malformed JSON and symlinks fail.
1493
+
1494
+ Examples:
1495
+ tiangong-pcr inspect --input wheat.process.json --related ./datasets --section exchanges --format json
1496
+ tiangong-pcr inspect --input wheat.model.json --related ./datasets --section references --format json
1497
+
1498
+ Next:
1499
+ Inspect scope and reference basis, resolve missing evidence, select PCR guidance and use review prepare.
1500
+ Unit interpretation needs local flow, flow-property and unit-group evidence. Use the TIDAS toolkit for schema validation.
1501
+ `;
1502
+ }
1503
+ if (definition.key === "calculate") {
1504
+ return `Usage: tiangong-pcr calculate --input <calculation.json> [--output <new-file>] [--format json]
1505
+
1506
+ Perform reproducible arithmetic using explicit values, units, basis and evidence. No library is needed.
1507
+ All requests require operation, basis and evidence. Numeric values may be finite numbers or decimal strings.
1508
+
1509
+ Normalization example:
1510
+ {"operation":"normalize","amount":50,"unit":"kg N","source_reference":1000,
1511
+ "target_reference":1,"reference_unit":"kg grain","basis":"same moisture and gate",
1512
+ "evidence":"production record A; explicit source and target reference amounts"}
1513
+
1514
+ Conversion fields:
1515
+ operation: convert; amount, from_unit, to_unit, factor, basis, evidence.
1516
+ factor is supplied in to_unit / from_unit; no unit equivalence or factor is inferred.
1517
+
1518
+ Balance fields:
1519
+ operation: balance; inputs and outputs: [{"amount":1,"label":"record A"}],
1520
+ accumulation (explicit, even if zero), unit, basis, evidence.
1521
+ All terms must use the same physical basis and unit. Residual = inputs - outputs - accumulation.
1522
+
1523
+ Output:
1524
+ Request hash, supplied request, formula, result and interpretation limits; floating-point arithmetic.
1525
+ No threshold, physical validity or anomaly verdict is inferred. Missing values are not zero.
1526
+ Next: retain the calculation artifact and assess its applicability and tolerance in the Agent review.
1527
+ `;
1528
+ }
1529
+ if (definition.command === "review") {
1530
+ return `Usage:
1531
+ tiangong-pcr review prepare --pcr <pcr-id> --input <native-tidas.json> [--related <directory>] --output <new-draft.json>
1532
+ tiangong-pcr review check --pcr <pcr-id> --input <native-tidas.json> [--related <directory>] --report <review.json>
1533
+
1534
+ prepare creates an unreviewed Agent artifact with exact input/PCR bindings, scope and uncovered topics.
1535
+ The Agent investigates and edits that artifact. check verifies its envelope and evidence locations.
1536
+ Neither command runs an LLM, validates TIDAS schemas or approves methodology.
1537
+
1538
+ Options:
1539
+ --pcr <pcr-id> --input <file> Explicit PCR and native TIDAS input, unchanged throughout review.
1540
+ --related <directory> Same explicitly supplied local package used during inspection.
1541
+ --report <file> Agent review JSON, required only by check.
1542
+ --output <new-file> Save complete output without replacing an existing file.
1543
+ --root <path> Repository source, mutually exclusive with --library.
1544
+ --library <file> Local snapshot or PCR_LIBRARY / installed library.
1545
+ --library-sha256 <sha256:hex> Verify and pin that snapshot.
1546
+ --format json --help JSON output or this help.
1547
+
1548
+ Agent report:
1549
+ status: draft|reviewed; scope: description, applicability, limitations.
1550
+ coverage: [{topic, status: reviewed|not_applicable|not_reviewed, rationale}].
1551
+ findings: [{id, kind: confirmed_issue|suspected_anomaly|evidence_gap, severity: error|warning|info,
1552
+ observation, rationale, input_refs, pcr_refs, suggested_action, questions, alternative_explanations?}].
1553
+ Copy input_refs from inspect source objects and pcr_refs from selected guidance source objects.
1554
+ Cite the nearest existing parent for a missing field. pcr_refs may be empty for purely structural observations.
1555
+ Preserve free reasoning and unresolved questions; do not infer missing lifecycle stages from a partial process.
1556
+
1557
+ Exit codes:
1558
+ 0 preparation completed or report envelope valid (drafts may be valid);
1559
+ 1 usage/input/runtime error; 2 report shape, binding or evidence-location problem.
1560
+ envelope_valid and methodology_approval=false are separate from Agent findings and severity.
1561
+
1562
+ Next: use the Skill review reference, investigate applicable topics and share findings with their scope limits.
1563
+ `;
1564
+ }
1565
+ if (definition.key === "validate-model") {
1566
+ return `Usage: tiangong-pcr validate-model --pcr <pcr-id> --input <file> [options]
1567
+
1568
+ Legacy diagnostic: check whether PCR reference qualifiers occur in the input text.
1569
+ JSON is treated as text; this does not parse TIDAS fields or perform semantic review.
1570
+
1571
+ Options:
1572
+ --pcr <pcr-id> PCR id.
1573
+ --input <file> Model draft file.
1574
+ --format json Output format. JSON is recommended for Agents.
1575
+ --fail-on never|error|warning Exit 2 at the selected finding threshold. Defaults to error.
1576
+ --root <path> PCR repository root.
1577
+ --library <file> Local library.sqlite (or PCR_LIBRARY). Mutually exclusive with --root.
1578
+ --library-sha256 <sha256:hex> Verify and pin the complete snapshot before reading.
1579
+ --help Show this command help.
1580
+
1581
+ JSON output includes:
1582
+ validation_status, completeness, input, check_coverage, finding_summary, and findings.
1583
+
1584
+ Exit codes:
1585
+ 0 command completed and the configured finding threshold was not reached;
1586
+ 1 usage, input, or runtime error; 2 validation is inconclusive or the --fail-on threshold was reached.
1587
+
1588
+ Agent next step:
1589
+ Treat matches as text-presence evidence only. Use inspect and review prepare/check for Agent-led TIDAS review.
1590
+ `;
1591
+ }
1592
+ if (definition.key === "validate-dataset") {
1593
+ return `Usage: tiangong-pcr validate-dataset --pcr <pcr-id> --input <file> [options]
1594
+
1595
+ Check a foreground data package JSON object against the implemented subset of selected PCR guidance.
1596
+ Currently checks collection protocol ID presence, not values, units, evidence quality or TIDAS validity.
1597
+ This optional legacy package format is not required for general LCA authoring or native TIDAS review.
1598
+
1599
+ Options:
1600
+ --pcr <pcr-id> PCR id.
1601
+ --input <file> Foreground data package JSON file. The JSON root must be an object.
1602
+ --format json Output format. JSON is recommended for Agents.
1603
+ --fail-on never|error|warning Exit 2 at the selected finding threshold. Defaults to error.
1604
+ --root <path> PCR repository root.
1605
+ --library <file> Local library.sqlite (or PCR_LIBRARY). Mutually exclusive with --root.
1606
+ --library-sha256 <sha256:hex> Verify and pin the complete snapshot before reading.
1607
+ --help Show this command help.
1608
+
1609
+ JSON output includes:
1610
+ validation_status, completeness, input, check_coverage, finding_summary, and findings.
1611
+ A passed status applies only to checks_performed; inspect checks_skipped when completeness is partial.
1612
+
1613
+ Exit codes:
1614
+ 0 command completed and the configured finding threshold was not reached;
1615
+ 1 malformed JSON, usage, or runtime error; 2 validation is inconclusive or the --fail-on threshold was reached.
1616
+
1617
+ Agent next step:
1618
+ Address error findings and inspect skipped coverage. Draft feedback when required PCR rules cannot be evaluated.
1619
+ `;
1620
+ }
1621
+ if (definition.key === "feedback:draft") {
1622
+ return `Usage: tiangong-pcr feedback draft --type <feedback-type> [options]
1623
+
1624
+ Create issue-ready Markdown for PCR maintainer feedback. Feedback is candidate evidence, not accepted PCR truth.
1625
+
1626
+ Options:
1627
+ --pcr <pcr-id> Affected PCR id when available.
1628
+ --type <feedback-type> Feedback type.
1629
+ --affected-section <section> Affected PCR section.
1630
+ --process-id <process_id> Affected process_id.
1631
+ --flow-role <role> Affected flow role.
1632
+ --summary <text> Short finding summary.
1633
+ --evidence <text> Evidence URLs, files, or notes.
1634
+ --proposed-change <text> Suggested change.
1635
+ --format json|markdown Output format. Defaults to markdown.
1636
+ --root <path> PCR repository root.
1637
+ --library <file> Local library.sqlite (or PCR_LIBRARY). Mutually exclusive with --root.
1638
+ --library-sha256 <sha256:hex> Verify and pin the complete snapshot before reading.
1639
+ --help Show this command help.
1640
+
1641
+ Feedback types:
1642
+ ${FEEDBACK_TYPES.map((type) => ` ${type}`).join("\n")}
1643
+
1644
+ Agent next step:
1645
+ Open a GitHub issue with the generated body, or hand it to a maintainer for intake.
1646
+ `;
1647
+ }
1648
+
1649
+ return globalHelpText();
1650
+ }
1651
+
1652
+ function globalHelpText() {
1653
+ return `Version: tiangong-pcr --version
1654
+ Offline: --library <library.sqlite> (or PCR_LIBRARY); --library-sha256 sha256:<hex> pins the file.
1655
+ library info|verify --library <file> --format json
1656
+ Requires Node 24.19+ for SQLite. No automatic downloads.
1657
+
1658
+ tiangong-pcr
1659
+
1660
+ Usage:
1661
+ tiangong-pcr <command> [options]
1662
+ tiangong-pcr <command> --help
1663
+
1664
+ Commands:
1665
+ list [--scope all|material|legacy] [--status <status>] [--content-maturity <state>] [--path-prefix <path>] [--page <n>] [--page-size <n>] [--format json|markdown|table]
1666
+ tree [--scope all|material|legacy] [--depth <n>] [--format json|markdown]
1667
+ coverage summary --classification <system>:<version> [--format json|table]
1668
+ coverage list --classification <system>:<version> [--status <coverage-status>] [--page <n>] [--page-size <n>] [--format json|table]
1669
+ resolve (--classification <system>:<version>:<code> | --pcr <pcr-id>) [--format json]
1670
+ show --pcr <pcr-id> [--lang en-US|zh-CN]
1671
+ guidance --pcr <pcr-id> [--topic <topic> | --pointer <pointer>] [--output <new-file>] [--format json]
1672
+ inspect --input <native-tidas.json> [--related <directory>] [--section <section> | --pointer <pointer>]
1673
+ calculate --input <calculation.json> [--output <new-file>]
1674
+ review prepare --pcr <pcr-id> --input <native-tidas.json> [--related <directory>] --output <new-draft.json>
1675
+ review check --pcr <pcr-id> --input <native-tidas.json> [--related <directory>] --report <review.json>
1676
+ validate-model --pcr <pcr-id> --input <file> [--format json] [--fail-on never|error|warning]
1677
+ validate-dataset --pcr <pcr-id> --input <file> [--format json] [--fail-on never|error|warning]
1678
+ feedback draft --type <type> [--pcr <pcr-id>] [--summary <text>]
1679
+
1680
+ Agent workflow:
1681
+ 1. Inspect coverage summary/list when classification completeness matters; no fuzzy matching is performed.
1682
+ 2. If a classification code is available, run resolve --classification <system>:<version>:<code> --format json.
1683
+ If a PCR id is available, run resolve --pcr <pcr-id> --format json. Supply exactly one selector.
1684
+ 3. If no code is available, use tree/list to browse explicit material PCR hierarchy. list defaults to 10 records per page.
1685
+ 4. Check resolution_status and readiness. Run guidance only for mapped material PCRs when usable_for_guidance is true.
1686
+ 5. Guide general LCA data authoring, optionally map a draft into TIDAS, or inspect existing TIDAS inputs.
1687
+ 6. For review, investigate applicable guidance and evidence, fill review prepare's draft, then use review check.
1688
+ CLI checks do not approve methodology. Existing validate-* commands are limited legacy diagnostics.
1689
+ 7. If PCR guidance is missing or ambiguous, run feedback draft with the observed gap.
1690
+ `;
1691
+ }