@xrkseek/harness 0.6.21 → 0.7.0-rc.1

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 (677) hide show
  1. package/node_modules/@xrkseek/a2a/README.md +45 -45
  2. package/node_modules/@xrkseek/attachment/README.md +23 -23
  3. package/node_modules/@xrkseek/attachment-local/README.md +6 -6
  4. package/node_modules/@xrkseek/attachment-local/package.json +26 -26
  5. package/node_modules/@xrkseek/checkpoint/README.md +90 -90
  6. package/node_modules/@xrkseek/checkpoint/dist/store.d.ts +21 -0
  7. package/node_modules/@xrkseek/checkpoint/dist/store.d.ts.map +1 -1
  8. package/node_modules/@xrkseek/checkpoint/dist/store.js +33 -0
  9. package/node_modules/@xrkseek/checkpoint/dist/store.js.map +1 -1
  10. package/node_modules/@xrkseek/checkpoint/package.json +26 -26
  11. package/node_modules/@xrkseek/claude-code-mods/README.md +152 -0
  12. package/node_modules/@xrkseek/claude-code-mods/README.zh.md +172 -0
  13. package/node_modules/@xrkseek/claude-code-mods/dist/api.d.ts +36 -0
  14. package/node_modules/@xrkseek/claude-code-mods/dist/api.d.ts.map +1 -0
  15. package/node_modules/@xrkseek/claude-code-mods/dist/api.js +215 -0
  16. package/node_modules/@xrkseek/claude-code-mods/dist/api.js.map +1 -0
  17. package/node_modules/@xrkseek/claude-code-mods/dist/attach.d.ts +92 -0
  18. package/node_modules/@xrkseek/claude-code-mods/dist/attach.d.ts.map +1 -0
  19. package/node_modules/@xrkseek/claude-code-mods/dist/attach.js +106 -0
  20. package/node_modules/@xrkseek/claude-code-mods/dist/attach.js.map +1 -0
  21. package/node_modules/@xrkseek/claude-code-mods/dist/chain.d.ts +105 -0
  22. package/node_modules/@xrkseek/claude-code-mods/dist/chain.d.ts.map +1 -0
  23. package/node_modules/@xrkseek/claude-code-mods/dist/chain.js +324 -0
  24. package/node_modules/@xrkseek/claude-code-mods/dist/chain.js.map +1 -0
  25. package/node_modules/@xrkseek/claude-code-mods/dist/define-mod.d.ts +39 -0
  26. package/node_modules/@xrkseek/claude-code-mods/dist/define-mod.d.ts.map +1 -0
  27. package/node_modules/@xrkseek/claude-code-mods/dist/define-mod.js +39 -0
  28. package/node_modules/@xrkseek/claude-code-mods/dist/define-mod.js.map +1 -0
  29. package/node_modules/@xrkseek/claude-code-mods/dist/elements.d.ts +96 -0
  30. package/node_modules/@xrkseek/claude-code-mods/dist/elements.d.ts.map +1 -0
  31. package/node_modules/@xrkseek/claude-code-mods/dist/elements.js +171 -0
  32. package/node_modules/@xrkseek/claude-code-mods/dist/elements.js.map +1 -0
  33. package/node_modules/@xrkseek/claude-code-mods/dist/engine.d.ts +155 -0
  34. package/node_modules/@xrkseek/claude-code-mods/dist/engine.d.ts.map +1 -0
  35. package/node_modules/@xrkseek/claude-code-mods/dist/engine.js +356 -0
  36. package/node_modules/@xrkseek/claude-code-mods/dist/engine.js.map +1 -0
  37. package/node_modules/@xrkseek/claude-code-mods/dist/host-ops.d.ts +72 -0
  38. package/node_modules/@xrkseek/claude-code-mods/dist/host-ops.d.ts.map +1 -0
  39. package/node_modules/@xrkseek/claude-code-mods/dist/host-ops.js +603 -0
  40. package/node_modules/@xrkseek/claude-code-mods/dist/host-ops.js.map +1 -0
  41. package/node_modules/@xrkseek/claude-code-mods/dist/index.d.ts +112 -0
  42. package/node_modules/@xrkseek/claude-code-mods/dist/index.d.ts.map +1 -0
  43. package/node_modules/@xrkseek/claude-code-mods/dist/index.js +654 -0
  44. package/node_modules/@xrkseek/claude-code-mods/dist/index.js.map +1 -0
  45. package/node_modules/@xrkseek/claude-code-mods/dist/matcher.d.ts +45 -0
  46. package/node_modules/@xrkseek/claude-code-mods/dist/matcher.d.ts.map +1 -0
  47. package/node_modules/@xrkseek/claude-code-mods/dist/matcher.js +195 -0
  48. package/node_modules/@xrkseek/claude-code-mods/dist/matcher.js.map +1 -0
  49. package/node_modules/@xrkseek/claude-code-mods/dist/module.d.ts +74 -0
  50. package/node_modules/@xrkseek/claude-code-mods/dist/module.d.ts.map +1 -0
  51. package/node_modules/@xrkseek/claude-code-mods/dist/module.js +167 -0
  52. package/node_modules/@xrkseek/claude-code-mods/dist/module.js.map +1 -0
  53. package/node_modules/@xrkseek/claude-code-mods/dist/native-import.d.ts +31 -0
  54. package/node_modules/@xrkseek/claude-code-mods/dist/native-import.d.ts.map +1 -0
  55. package/node_modules/@xrkseek/claude-code-mods/dist/native-import.js +32 -0
  56. package/node_modules/@xrkseek/claude-code-mods/dist/native-import.js.map +1 -0
  57. package/node_modules/@xrkseek/claude-code-mods/dist/plugin-dir.d.ts +70 -0
  58. package/node_modules/@xrkseek/claude-code-mods/dist/plugin-dir.d.ts.map +1 -0
  59. package/node_modules/@xrkseek/claude-code-mods/dist/plugin-dir.js +167 -0
  60. package/node_modules/@xrkseek/claude-code-mods/dist/plugin-dir.js.map +1 -0
  61. package/node_modules/@xrkseek/claude-code-mods/dist/product-agent.d.ts +57 -0
  62. package/node_modules/@xrkseek/claude-code-mods/dist/product-agent.d.ts.map +1 -0
  63. package/node_modules/@xrkseek/claude-code-mods/dist/product-agent.js +85 -0
  64. package/node_modules/@xrkseek/claude-code-mods/dist/product-agent.js.map +1 -0
  65. package/node_modules/@xrkseek/claude-code-mods/dist/runtime.d.ts +117 -0
  66. package/node_modules/@xrkseek/claude-code-mods/dist/runtime.d.ts.map +1 -0
  67. package/node_modules/@xrkseek/claude-code-mods/dist/runtime.js +252 -0
  68. package/node_modules/@xrkseek/claude-code-mods/dist/runtime.js.map +1 -0
  69. package/node_modules/@xrkseek/claude-code-mods/dist/storage-domain.d.ts +68 -0
  70. package/node_modules/@xrkseek/claude-code-mods/dist/storage-domain.d.ts.map +1 -0
  71. package/node_modules/@xrkseek/claude-code-mods/dist/storage-domain.js +104 -0
  72. package/node_modules/@xrkseek/claude-code-mods/dist/storage-domain.js.map +1 -0
  73. package/node_modules/@xrkseek/claude-code-mods/dist/surfaces.d.ts +82 -0
  74. package/node_modules/@xrkseek/claude-code-mods/dist/surfaces.d.ts.map +1 -0
  75. package/node_modules/@xrkseek/claude-code-mods/dist/surfaces.js +243 -0
  76. package/node_modules/@xrkseek/claude-code-mods/dist/surfaces.js.map +1 -0
  77. package/node_modules/@xrkseek/claude-code-mods/dist/testing.d.ts +157 -0
  78. package/node_modules/@xrkseek/claude-code-mods/dist/testing.d.ts.map +1 -0
  79. package/node_modules/@xrkseek/claude-code-mods/dist/testing.js +266 -0
  80. package/node_modules/@xrkseek/claude-code-mods/dist/testing.js.map +1 -0
  81. package/node_modules/@xrkseek/claude-code-mods/dist/tool-names.d.ts +21 -0
  82. package/node_modules/@xrkseek/claude-code-mods/dist/tool-names.d.ts.map +1 -0
  83. package/node_modules/@xrkseek/claude-code-mods/dist/tool-names.js +37 -0
  84. package/node_modules/@xrkseek/claude-code-mods/dist/tool-names.js.map +1 -0
  85. package/node_modules/@xrkseek/claude-code-mods/dist/types.d.ts +592 -0
  86. package/node_modules/@xrkseek/claude-code-mods/dist/types.d.ts.map +1 -0
  87. package/node_modules/@xrkseek/claude-code-mods/dist/types.js +10 -0
  88. package/node_modules/@xrkseek/claude-code-mods/dist/types.js.map +1 -0
  89. package/node_modules/@xrkseek/claude-code-mods/dist/values.d.ts +58 -0
  90. package/node_modules/@xrkseek/claude-code-mods/dist/values.d.ts.map +1 -0
  91. package/node_modules/@xrkseek/claude-code-mods/dist/values.js +75 -0
  92. package/node_modules/@xrkseek/claude-code-mods/dist/values.js.map +1 -0
  93. package/node_modules/@xrkseek/claude-code-mods/dist/working-directory.d.ts +45 -0
  94. package/node_modules/@xrkseek/claude-code-mods/dist/working-directory.d.ts.map +1 -0
  95. package/node_modules/@xrkseek/claude-code-mods/dist/working-directory.js +29 -0
  96. package/node_modules/@xrkseek/claude-code-mods/dist/working-directory.js.map +1 -0
  97. package/node_modules/@xrkseek/claude-code-mods/package.json +47 -0
  98. package/node_modules/@xrkseek/code-runtime/README.md +20 -20
  99. package/node_modules/@xrkseek/core-agent/dist/index.d.ts +87 -0
  100. package/node_modules/@xrkseek/core-agent/dist/index.d.ts.map +1 -1
  101. package/node_modules/@xrkseek/core-agent/dist/index.js.map +1 -1
  102. package/node_modules/@xrkseek/core-agent-loop/dist/index.d.ts.map +1 -1
  103. package/node_modules/@xrkseek/core-agent-loop/dist/index.js +9 -1
  104. package/node_modules/@xrkseek/core-agent-loop/dist/index.js.map +1 -1
  105. package/node_modules/@xrkseek/core-agent-loop/package.json +42 -42
  106. package/node_modules/@xrkseek/core-session/README.md +35 -35
  107. package/node_modules/@xrkseek/core-session/dist/compaction.d.ts.map +1 -1
  108. package/node_modules/@xrkseek/core-session/dist/compaction.js +62 -37
  109. package/node_modules/@xrkseek/core-session/dist/compaction.js.map +1 -1
  110. package/node_modules/@xrkseek/core-session/dist/freeze.d.ts +6 -0
  111. package/node_modules/@xrkseek/core-session/dist/freeze.d.ts.map +1 -1
  112. package/node_modules/@xrkseek/core-session/dist/freeze.js +9 -0
  113. package/node_modules/@xrkseek/core-session/dist/freeze.js.map +1 -1
  114. package/node_modules/@xrkseek/core-session/dist/index.d.ts +18 -2
  115. package/node_modules/@xrkseek/core-session/dist/index.d.ts.map +1 -1
  116. package/node_modules/@xrkseek/core-session/dist/index.js +53 -12
  117. package/node_modules/@xrkseek/core-session/dist/index.js.map +1 -1
  118. package/node_modules/@xrkseek/core-session/dist/list-hints.d.ts.map +1 -1
  119. package/node_modules/@xrkseek/core-session/dist/list-hints.js +14 -4
  120. package/node_modules/@xrkseek/core-session/dist/list-hints.js.map +1 -1
  121. package/node_modules/@xrkseek/core-session/dist/repair-open-turn.d.ts +8 -1
  122. package/node_modules/@xrkseek/core-session/dist/repair-open-turn.d.ts.map +1 -1
  123. package/node_modules/@xrkseek/core-session/dist/repair-open-turn.js +14 -4
  124. package/node_modules/@xrkseek/core-session/dist/repair-open-turn.js.map +1 -1
  125. package/node_modules/@xrkseek/core-session/dist/sqlite-store.d.ts +55 -0
  126. package/node_modules/@xrkseek/core-session/dist/sqlite-store.d.ts.map +1 -1
  127. package/node_modules/@xrkseek/core-session/dist/sqlite-store.js +670 -92
  128. package/node_modules/@xrkseek/core-session/dist/sqlite-store.js.map +1 -1
  129. package/node_modules/@xrkseek/core-session/dist/store.d.ts +38 -0
  130. package/node_modules/@xrkseek/core-session/dist/store.d.ts.map +1 -1
  131. package/node_modules/@xrkseek/core-session/package.json +34 -34
  132. package/node_modules/@xrkseek/core-system-prompt/README.md +14 -14
  133. package/node_modules/@xrkseek/core-tools/dist/session-query-prompt.d.ts.map +1 -1
  134. package/node_modules/@xrkseek/core-tools/dist/session-query-prompt.js +3 -2
  135. package/node_modules/@xrkseek/core-tools/dist/session-query-prompt.js.map +1 -1
  136. package/node_modules/@xrkseek/core-tools/dist/std-tools.d.ts.map +1 -1
  137. package/node_modules/@xrkseek/core-tools/dist/std-tools.js +1 -13
  138. package/node_modules/@xrkseek/core-tools/dist/std-tools.js.map +1 -1
  139. package/node_modules/@xrkseek/exec-computer-use/README.md +14 -14
  140. package/node_modules/@xrkseek/exec-computer-use/dist/windows-uia.js +402 -402
  141. package/node_modules/@xrkseek/exec-computer-use/package.json +26 -26
  142. package/node_modules/@xrkseek/exec-fs/README.md +12 -12
  143. package/node_modules/@xrkseek/exec-fs/dist/read-image.js +4 -4
  144. package/node_modules/@xrkseek/exec-image-gen/README.md +13 -13
  145. package/node_modules/@xrkseek/exec-image-gen/package.json +28 -28
  146. package/node_modules/@xrkseek/exec-memory/README.md +14 -14
  147. package/node_modules/@xrkseek/exec-memory/dist/live-fragment.d.ts +11 -0
  148. package/node_modules/@xrkseek/exec-memory/dist/live-fragment.d.ts.map +1 -0
  149. package/node_modules/@xrkseek/exec-memory/dist/live-fragment.js +40 -0
  150. package/node_modules/@xrkseek/exec-memory/dist/live-fragment.js.map +1 -0
  151. package/node_modules/@xrkseek/exec-memory/package.json +28 -28
  152. package/node_modules/@xrkseek/exec-sandbox/README.md +15 -15
  153. package/node_modules/@xrkseek/exec-ssh/README.md +19 -19
  154. package/node_modules/@xrkseek/exec-subprocess/README.md +10 -10
  155. package/node_modules/@xrkseek/exec-video-analyze/README.md +11 -11
  156. package/node_modules/@xrkseek/exec-video-analyze/package.json +26 -26
  157. package/node_modules/@xrkseek/exec-video-gen/README.md +26 -26
  158. package/node_modules/@xrkseek/exec-voice/README.md +25 -25
  159. package/node_modules/@xrkseek/exec-web/README.md +11 -11
  160. package/node_modules/@xrkseek/llm-deepseek/README.md +22 -22
  161. package/node_modules/@xrkseek/llm-deepseek/package.json +30 -30
  162. package/node_modules/@xrkseek/llm-registry/dist/index.d.ts +2 -2
  163. package/node_modules/@xrkseek/llm-registry/dist/index.d.ts.map +1 -1
  164. package/node_modules/@xrkseek/llm-registry/dist/index.js +1 -1
  165. package/node_modules/@xrkseek/llm-registry/dist/index.js.map +1 -1
  166. package/node_modules/@xrkseek/llm-registry/dist/types.d.ts +29 -0
  167. package/node_modules/@xrkseek/llm-registry/dist/types.d.ts.map +1 -1
  168. package/node_modules/@xrkseek/llm-registry/dist/types.js +21 -0
  169. package/node_modules/@xrkseek/llm-registry/dist/types.js.map +1 -1
  170. package/node_modules/@xrkseek/mcp/README.md +78 -78
  171. package/node_modules/@xrkseek/policy/README.md +18 -18
  172. package/node_modules/@xrkseek/policy/package.json +31 -31
  173. package/node_modules/@xrkseek/preset-harness/README.md +7 -7
  174. package/node_modules/@xrkseek/preset-harness/dist/mods.d.ts +68 -0
  175. package/node_modules/@xrkseek/preset-harness/dist/mods.d.ts.map +1 -0
  176. package/node_modules/@xrkseek/preset-harness/dist/mods.js +510 -0
  177. package/node_modules/@xrkseek/preset-harness/dist/mods.js.map +1 -0
  178. package/node_modules/@xrkseek/preset-harness/dist/preset.d.ts +12 -1
  179. package/node_modules/@xrkseek/preset-harness/dist/preset.d.ts.map +1 -1
  180. package/node_modules/@xrkseek/preset-harness/dist/preset.js +73 -26
  181. package/node_modules/@xrkseek/preset-harness/dist/preset.js.map +1 -1
  182. package/node_modules/@xrkseek/preset-harness/dist/tsconfig.tsbuildinfo +1 -1
  183. package/node_modules/@xrkseek/preset-harness/package.json +9 -8
  184. package/node_modules/@xrkseek/preset-minimal/README.md +6 -6
  185. package/node_modules/@xrkseek/preset-minimal/dist/preset.d.ts.map +1 -1
  186. package/node_modules/@xrkseek/preset-minimal/dist/preset.js +9 -3
  187. package/node_modules/@xrkseek/preset-minimal/dist/preset.js.map +1 -1
  188. package/node_modules/@xrkseek/preset-minimal/dist/tsconfig.tsbuildinfo +1 -1
  189. package/node_modules/@xrkseek/preset-server/README.md +4 -4
  190. package/node_modules/@xrkseek/preset-server/dist/preset.d.ts.map +1 -1
  191. package/node_modules/@xrkseek/preset-server/dist/preset.js +2 -1
  192. package/node_modules/@xrkseek/preset-server/dist/preset.js.map +1 -1
  193. package/node_modules/@xrkseek/preset-server/dist/tsconfig.tsbuildinfo +1 -1
  194. package/node_modules/@xrkseek/protocol/README.md +34 -34
  195. package/node_modules/@xrkseek/protocol/dist/index.d.ts +3 -2
  196. package/node_modules/@xrkseek/protocol/dist/index.d.ts.map +1 -1
  197. package/node_modules/@xrkseek/protocol/dist/index.js +1 -0
  198. package/node_modules/@xrkseek/protocol/dist/index.js.map +1 -1
  199. package/node_modules/@xrkseek/protocol/dist/json-schema.d.ts +12 -0
  200. package/node_modules/@xrkseek/protocol/dist/json-schema.d.ts.map +1 -1
  201. package/node_modules/@xrkseek/protocol/dist/json-schema.js +9 -0
  202. package/node_modules/@xrkseek/protocol/dist/json-schema.js.map +1 -1
  203. package/node_modules/@xrkseek/protocol/dist/json-value.d.ts +25 -0
  204. package/node_modules/@xrkseek/protocol/dist/json-value.d.ts.map +1 -0
  205. package/node_modules/@xrkseek/protocol/dist/json-value.js +181 -0
  206. package/node_modules/@xrkseek/protocol/dist/json-value.js.map +1 -0
  207. package/node_modules/@xrkseek/protocol/dist/session-events.d.ts +21 -1
  208. package/node_modules/@xrkseek/protocol/dist/session-events.d.ts.map +1 -1
  209. package/node_modules/@xrkseek/protocol/dist/session-events.js +1 -0
  210. package/node_modules/@xrkseek/protocol/dist/session-events.js.map +1 -1
  211. package/node_modules/@xrkseek/protocol/dist/validate.d.ts +4 -1
  212. package/node_modules/@xrkseek/protocol/dist/validate.d.ts.map +1 -1
  213. package/node_modules/@xrkseek/protocol/dist/validate.js +28 -2
  214. package/node_modules/@xrkseek/protocol/dist/validate.js.map +1 -1
  215. package/node_modules/@xrkseek/schemastery/lib/index.cjs +597 -597
  216. package/node_modules/@xrkseek/schemastery/lib/index.mjs +597 -597
  217. package/node_modules/@xrkseek/schemastery/lib/types/index.d.ts +203 -203
  218. package/node_modules/@xrkseek/schemastery/src/index.d.ts +203 -203
  219. package/node_modules/@xrkseek/schemastery/src/index.ts +906 -906
  220. package/node_modules/@xrkseek/server-config/package.json +28 -28
  221. package/node_modules/@xrkseek/server-cron/README.md +12 -12
  222. package/node_modules/@xrkseek/server-cron/package.json +26 -26
  223. package/node_modules/@xrkseek/server-face/dist/adapt/history-paginate.d.ts +22 -0
  224. package/node_modules/@xrkseek/server-face/dist/adapt/history-paginate.d.ts.map +1 -1
  225. package/node_modules/@xrkseek/server-face/dist/adapt/history-paginate.js +40 -3
  226. package/node_modules/@xrkseek/server-face/dist/adapt/history-paginate.js.map +1 -1
  227. package/node_modules/@xrkseek/server-face/dist/adapt/subagent-notice.d.ts.map +1 -1
  228. package/node_modules/@xrkseek/server-face/dist/adapt/subagent-notice.js +2 -0
  229. package/node_modules/@xrkseek/server-face/dist/adapt/subagent-notice.js.map +1 -1
  230. package/node_modules/@xrkseek/server-face/dist/adapt/wire-event.d.ts +1 -0
  231. package/node_modules/@xrkseek/server-face/dist/adapt/wire-event.d.ts.map +1 -1
  232. package/node_modules/@xrkseek/server-face/dist/adapt/wire-event.js +2 -0
  233. package/node_modules/@xrkseek/server-face/dist/adapt/wire-event.js.map +1 -1
  234. package/node_modules/@xrkseek/server-face/dist/adapt/wire-ids.d.ts +5 -0
  235. package/node_modules/@xrkseek/server-face/dist/adapt/wire-ids.d.ts.map +1 -1
  236. package/node_modules/@xrkseek/server-face/dist/adapt/wire-ids.js +7 -0
  237. package/node_modules/@xrkseek/server-face/dist/adapt/wire-ids.js.map +1 -1
  238. package/node_modules/@xrkseek/server-face/dist/agent-home-boundary.d.ts +31 -0
  239. package/node_modules/@xrkseek/server-face/dist/agent-home-boundary.d.ts.map +1 -0
  240. package/node_modules/@xrkseek/server-face/dist/agent-home-boundary.js +71 -0
  241. package/node_modules/@xrkseek/server-face/dist/agent-home-boundary.js.map +1 -0
  242. package/node_modules/@xrkseek/server-face/dist/agent-home.d.ts +18 -0
  243. package/node_modules/@xrkseek/server-face/dist/agent-home.d.ts.map +1 -0
  244. package/node_modules/@xrkseek/server-face/dist/agent-home.js +64 -0
  245. package/node_modules/@xrkseek/server-face/dist/agent-home.js.map +1 -0
  246. package/node_modules/@xrkseek/server-face/dist/agent-roster-store.d.ts +41 -2
  247. package/node_modules/@xrkseek/server-face/dist/agent-roster-store.d.ts.map +1 -1
  248. package/node_modules/@xrkseek/server-face/dist/agent-roster-store.js +200 -28
  249. package/node_modules/@xrkseek/server-face/dist/agent-roster-store.js.map +1 -1
  250. package/node_modules/@xrkseek/server-face/dist/agent-team-roles.js +1 -1
  251. package/node_modules/@xrkseek/server-face/dist/agent-team-roles.js.map +1 -1
  252. package/node_modules/@xrkseek/server-face/dist/attach-http.d.ts.map +1 -1
  253. package/node_modules/@xrkseek/server-face/dist/attach-http.js +9 -0
  254. package/node_modules/@xrkseek/server-face/dist/attach-http.js.map +1 -1
  255. package/node_modules/@xrkseek/server-face/dist/boss-status-broadcast.d.ts +55 -0
  256. package/node_modules/@xrkseek/server-face/dist/boss-status-broadcast.d.ts.map +1 -0
  257. package/node_modules/@xrkseek/server-face/dist/boss-status-broadcast.js +167 -0
  258. package/node_modules/@xrkseek/server-face/dist/boss-status-broadcast.js.map +1 -0
  259. package/node_modules/@xrkseek/server-face/dist/collab-board.d.ts +12 -0
  260. package/node_modules/@xrkseek/server-face/dist/collab-board.d.ts.map +1 -1
  261. package/node_modules/@xrkseek/server-face/dist/collab-board.js +101 -19
  262. package/node_modules/@xrkseek/server-face/dist/collab-board.js.map +1 -1
  263. package/node_modules/@xrkseek/server-face/dist/context.d.ts +25 -2
  264. package/node_modules/@xrkseek/server-face/dist/context.d.ts.map +1 -1
  265. package/node_modules/@xrkseek/server-face/dist/dispatch.d.ts.map +1 -1
  266. package/node_modules/@xrkseek/server-face/dist/dispatch.js +6 -2
  267. package/node_modules/@xrkseek/server-face/dist/dispatch.js.map +1 -1
  268. package/node_modules/@xrkseek/server-face/dist/face-schema.d.ts.map +1 -1
  269. package/node_modules/@xrkseek/server-face/dist/face-schema.js +2 -1
  270. package/node_modules/@xrkseek/server-face/dist/face-schema.js.map +1 -1
  271. package/node_modules/@xrkseek/server-face/dist/fork-cut.d.ts.map +1 -1
  272. package/node_modules/@xrkseek/server-face/dist/fork-cut.js +15 -3
  273. package/node_modules/@xrkseek/server-face/dist/fork-cut.js.map +1 -1
  274. package/node_modules/@xrkseek/server-face/dist/fork-lineage.d.ts +7 -0
  275. package/node_modules/@xrkseek/server-face/dist/fork-lineage.d.ts.map +1 -1
  276. package/node_modules/@xrkseek/server-face/dist/fork-lineage.js +23 -8
  277. package/node_modules/@xrkseek/server-face/dist/fork-lineage.js.map +1 -1
  278. package/node_modules/@xrkseek/server-face/dist/handlers/band.d.ts +7 -0
  279. package/node_modules/@xrkseek/server-face/dist/handlers/band.d.ts.map +1 -0
  280. package/node_modules/@xrkseek/server-face/dist/handlers/band.js +40 -0
  281. package/node_modules/@xrkseek/server-face/dist/handlers/band.js.map +1 -0
  282. package/node_modules/@xrkseek/server-face/dist/handlers/checkpoint.d.ts.map +1 -1
  283. package/node_modules/@xrkseek/server-face/dist/handlers/checkpoint.js +81 -3
  284. package/node_modules/@xrkseek/server-face/dist/handlers/checkpoint.js.map +1 -1
  285. package/node_modules/@xrkseek/server-face/dist/handlers/remotes.d.ts.map +1 -1
  286. package/node_modules/@xrkseek/server-face/dist/handlers/remotes.js +4 -1
  287. package/node_modules/@xrkseek/server-face/dist/handlers/remotes.js.map +1 -1
  288. package/node_modules/@xrkseek/server-face/dist/handlers/session.d.ts +2 -0
  289. package/node_modules/@xrkseek/server-face/dist/handlers/session.d.ts.map +1 -1
  290. package/node_modules/@xrkseek/server-face/dist/handlers/session.js +236 -62
  291. package/node_modules/@xrkseek/server-face/dist/handlers/session.js.map +1 -1
  292. package/node_modules/@xrkseek/server-face/dist/handlers/team.d.ts.map +1 -1
  293. package/node_modules/@xrkseek/server-face/dist/handlers/team.js +100 -9
  294. package/node_modules/@xrkseek/server-face/dist/handlers/team.js.map +1 -1
  295. package/node_modules/@xrkseek/server-face/dist/handlers/worktree.d.ts +8 -1
  296. package/node_modules/@xrkseek/server-face/dist/handlers/worktree.d.ts.map +1 -1
  297. package/node_modules/@xrkseek/server-face/dist/handlers/worktree.js +15 -1
  298. package/node_modules/@xrkseek/server-face/dist/handlers/worktree.js.map +1 -1
  299. package/node_modules/@xrkseek/server-face/dist/index.d.ts +5 -1
  300. package/node_modules/@xrkseek/server-face/dist/index.d.ts.map +1 -1
  301. package/node_modules/@xrkseek/server-face/dist/index.js +5 -1
  302. package/node_modules/@xrkseek/server-face/dist/index.js.map +1 -1
  303. package/node_modules/@xrkseek/server-face/dist/instruction-authority-fragment.d.ts +19 -0
  304. package/node_modules/@xrkseek/server-face/dist/instruction-authority-fragment.d.ts.map +1 -0
  305. package/node_modules/@xrkseek/server-face/dist/instruction-authority-fragment.js +28 -0
  306. package/node_modules/@xrkseek/server-face/dist/instruction-authority-fragment.js.map +1 -0
  307. package/node_modules/@xrkseek/server-face/dist/log-cut-reset.d.ts +3 -0
  308. package/node_modules/@xrkseek/server-face/dist/log-cut-reset.d.ts.map +1 -0
  309. package/node_modules/@xrkseek/server-face/dist/log-cut-reset.js +22 -0
  310. package/node_modules/@xrkseek/server-face/dist/log-cut-reset.js.map +1 -0
  311. package/node_modules/@xrkseek/server-face/dist/managed-worktree.d.ts +66 -4
  312. package/node_modules/@xrkseek/server-face/dist/managed-worktree.d.ts.map +1 -1
  313. package/node_modules/@xrkseek/server-face/dist/managed-worktree.js +147 -5
  314. package/node_modules/@xrkseek/server-face/dist/managed-worktree.js.map +1 -1
  315. package/node_modules/@xrkseek/server-face/dist/model-catalog.d.ts.map +1 -1
  316. package/node_modules/@xrkseek/server-face/dist/model-catalog.js +60 -5
  317. package/node_modules/@xrkseek/server-face/dist/model-catalog.js.map +1 -1
  318. package/node_modules/@xrkseek/server-face/dist/projections/index.d.ts +2 -2
  319. package/node_modules/@xrkseek/server-face/dist/projections/index.d.ts.map +1 -1
  320. package/node_modules/@xrkseek/server-face/dist/projections/index.js +2 -2
  321. package/node_modules/@xrkseek/server-face/dist/projections/index.js.map +1 -1
  322. package/node_modules/@xrkseek/server-face/dist/projections/list-checkpoint-cache.d.ts +50 -4
  323. package/node_modules/@xrkseek/server-face/dist/projections/list-checkpoint-cache.d.ts.map +1 -1
  324. package/node_modules/@xrkseek/server-face/dist/projections/list-checkpoint-cache.js +167 -19
  325. package/node_modules/@xrkseek/server-face/dist/projections/list-checkpoint-cache.js.map +1 -1
  326. package/node_modules/@xrkseek/server-face/dist/projections/snapshot-keys.d.ts +21 -1
  327. package/node_modules/@xrkseek/server-face/dist/projections/snapshot-keys.d.ts.map +1 -1
  328. package/node_modules/@xrkseek/server-face/dist/projections/snapshot-keys.js +21 -1
  329. package/node_modules/@xrkseek/server-face/dist/projections/snapshot-keys.js.map +1 -1
  330. package/node_modules/@xrkseek/server-face/dist/projections/units/context-timeline.d.ts.map +1 -1
  331. package/node_modules/@xrkseek/server-face/dist/projections/units/context-timeline.js +58 -0
  332. package/node_modules/@xrkseek/server-face/dist/projections/units/context-timeline.js.map +1 -1
  333. package/node_modules/@xrkseek/server-face/dist/projections/units/cost-usage.d.ts.map +1 -1
  334. package/node_modules/@xrkseek/server-face/dist/projections/units/cost-usage.js +85 -0
  335. package/node_modules/@xrkseek/server-face/dist/projections/units/cost-usage.js.map +1 -1
  336. package/node_modules/@xrkseek/server-face/dist/projections/units/session-list-metadata.d.ts.map +1 -1
  337. package/node_modules/@xrkseek/server-face/dist/projections/units/session-list-metadata.js +14 -0
  338. package/node_modules/@xrkseek/server-face/dist/projections/units/session-list-metadata.js.map +1 -1
  339. package/node_modules/@xrkseek/server-face/dist/projections/units/title.d.ts.map +1 -1
  340. package/node_modules/@xrkseek/server-face/dist/projections/units/title.js +14 -0
  341. package/node_modules/@xrkseek/server-face/dist/projections/units/title.js.map +1 -1
  342. package/node_modules/@xrkseek/server-face/dist/projections/units/turn-outline.d.ts.map +1 -1
  343. package/node_modules/@xrkseek/server-face/dist/projections/units/turn-outline.js +24 -0
  344. package/node_modules/@xrkseek/server-face/dist/projections/units/turn-outline.js.map +1 -1
  345. package/node_modules/@xrkseek/server-face/dist/runtime.d.ts +4 -2
  346. package/node_modules/@xrkseek/server-face/dist/runtime.d.ts.map +1 -1
  347. package/node_modules/@xrkseek/server-face/dist/runtime.js +127 -17
  348. package/node_modules/@xrkseek/server-face/dist/runtime.js.map +1 -1
  349. package/node_modules/@xrkseek/server-face/dist/seat-identity.d.ts +26 -0
  350. package/node_modules/@xrkseek/server-face/dist/seat-identity.d.ts.map +1 -0
  351. package/node_modules/@xrkseek/server-face/dist/seat-identity.js +137 -0
  352. package/node_modules/@xrkseek/server-face/dist/seat-identity.js.map +1 -0
  353. package/node_modules/@xrkseek/server-face/dist/seat-titles.d.ts +29 -0
  354. package/node_modules/@xrkseek/server-face/dist/seat-titles.d.ts.map +1 -0
  355. package/node_modules/@xrkseek/server-face/dist/seat-titles.js +74 -0
  356. package/node_modules/@xrkseek/server-face/dist/seat-titles.js.map +1 -0
  357. package/node_modules/@xrkseek/server-face/dist/session-capability.d.ts.map +1 -1
  358. package/node_modules/@xrkseek/server-face/dist/session-capability.js +9 -6
  359. package/node_modules/@xrkseek/server-face/dist/session-capability.js.map +1 -1
  360. package/node_modules/@xrkseek/server-face/dist/session-cwd.d.ts.map +1 -1
  361. package/node_modules/@xrkseek/server-face/dist/session-cwd.js +3 -1
  362. package/node_modules/@xrkseek/server-face/dist/session-cwd.js.map +1 -1
  363. package/node_modules/@xrkseek/server-face/dist/session-event-window.d.ts +37 -0
  364. package/node_modules/@xrkseek/server-face/dist/session-event-window.d.ts.map +1 -0
  365. package/node_modules/@xrkseek/server-face/dist/session-event-window.js +88 -0
  366. package/node_modules/@xrkseek/server-face/dist/session-event-window.js.map +1 -0
  367. package/node_modules/@xrkseek/server-face/dist/session-identity-store.d.ts +20 -0
  368. package/node_modules/@xrkseek/server-face/dist/session-identity-store.d.ts.map +1 -0
  369. package/node_modules/@xrkseek/server-face/dist/session-identity-store.js +82 -0
  370. package/node_modules/@xrkseek/server-face/dist/session-identity-store.js.map +1 -0
  371. package/node_modules/@xrkseek/server-face/dist/session-posture.d.ts +1 -1
  372. package/node_modules/@xrkseek/server-face/dist/session-posture.d.ts.map +1 -1
  373. package/node_modules/@xrkseek/server-face/dist/session-posture.js +20 -5
  374. package/node_modules/@xrkseek/server-face/dist/session-posture.js.map +1 -1
  375. package/node_modules/@xrkseek/server-face/dist/session-query-tools.d.ts +1 -0
  376. package/node_modules/@xrkseek/server-face/dist/session-query-tools.d.ts.map +1 -1
  377. package/node_modules/@xrkseek/server-face/dist/session-query-tools.js +172 -25
  378. package/node_modules/@xrkseek/server-face/dist/session-query-tools.js.map +1 -1
  379. package/node_modules/@xrkseek/server-face/dist/session-search.d.ts +20 -2
  380. package/node_modules/@xrkseek/server-face/dist/session-search.d.ts.map +1 -1
  381. package/node_modules/@xrkseek/server-face/dist/session-search.js +125 -19
  382. package/node_modules/@xrkseek/server-face/dist/session-search.js.map +1 -1
  383. package/node_modules/@xrkseek/server-face/dist/session-status.d.ts +1 -1
  384. package/node_modules/@xrkseek/server-face/dist/session-status.d.ts.map +1 -1
  385. package/node_modules/@xrkseek/server-face/dist/session-status.js +143 -21
  386. package/node_modules/@xrkseek/server-face/dist/session-status.js.map +1 -1
  387. package/node_modules/@xrkseek/server-face/dist/session-thread-tools.d.ts.map +1 -1
  388. package/node_modules/@xrkseek/server-face/dist/session-thread-tools.js +5 -0
  389. package/node_modules/@xrkseek/server-face/dist/session-thread-tools.js.map +1 -1
  390. package/node_modules/@xrkseek/server-face/dist/session-tool-copy.d.ts.map +1 -1
  391. package/node_modules/@xrkseek/server-face/dist/session-tool-copy.js +2 -1
  392. package/node_modules/@xrkseek/server-face/dist/session-tool-copy.js.map +1 -1
  393. package/node_modules/@xrkseek/server-face/dist/settings-credentials.d.ts.map +1 -1
  394. package/node_modules/@xrkseek/server-face/dist/settings-credentials.js +10 -2
  395. package/node_modules/@xrkseek/server-face/dist/settings-credentials.js.map +1 -1
  396. package/node_modules/@xrkseek/server-face/dist/settings-schemas.d.ts.map +1 -1
  397. package/node_modules/@xrkseek/server-face/dist/settings-schemas.js +48 -10
  398. package/node_modules/@xrkseek/server-face/dist/settings-schemas.js.map +1 -1
  399. package/node_modules/@xrkseek/server-face/dist/skill-documents.d.ts.map +1 -1
  400. package/node_modules/@xrkseek/server-face/dist/skill-documents.js +14 -4
  401. package/node_modules/@xrkseek/server-face/dist/skill-documents.js.map +1 -1
  402. package/node_modules/@xrkseek/server-face/dist/skill-list.d.ts +4 -2
  403. package/node_modules/@xrkseek/server-face/dist/skill-list.d.ts.map +1 -1
  404. package/node_modules/@xrkseek/server-face/dist/skill-list.js +10 -4
  405. package/node_modules/@xrkseek/server-face/dist/skill-list.js.map +1 -1
  406. package/node_modules/@xrkseek/server-face/dist/skill-read.d.ts.map +1 -1
  407. package/node_modules/@xrkseek/server-face/dist/skill-read.js +9 -2
  408. package/node_modules/@xrkseek/server-face/dist/skill-read.js.map +1 -1
  409. package/node_modules/@xrkseek/server-face/dist/skill-source.d.ts +2 -1
  410. package/node_modules/@xrkseek/server-face/dist/skill-source.d.ts.map +1 -1
  411. package/node_modules/@xrkseek/server-face/dist/skill-source.js +12 -2
  412. package/node_modules/@xrkseek/server-face/dist/skill-source.js.map +1 -1
  413. package/node_modules/@xrkseek/server-face/dist/slash.d.ts +10 -1
  414. package/node_modules/@xrkseek/server-face/dist/slash.d.ts.map +1 -1
  415. package/node_modules/@xrkseek/server-face/dist/slash.js +97 -22
  416. package/node_modules/@xrkseek/server-face/dist/slash.js.map +1 -1
  417. package/node_modules/@xrkseek/server-face/dist/status-snapshot-cache.d.ts.map +1 -1
  418. package/node_modules/@xrkseek/server-face/dist/status-snapshot-cache.js +53 -0
  419. package/node_modules/@xrkseek/server-face/dist/status-snapshot-cache.js.map +1 -1
  420. package/node_modules/@xrkseek/server-face/dist/subagent-tools.d.ts.map +1 -1
  421. package/node_modules/@xrkseek/server-face/dist/subagent-tools.js +10 -5
  422. package/node_modules/@xrkseek/server-face/dist/subagent-tools.js.map +1 -1
  423. package/node_modules/@xrkseek/server-face/dist/types.d.ts +23 -0
  424. package/node_modules/@xrkseek/server-face/dist/types.d.ts.map +1 -1
  425. package/node_modules/@xrkseek/server-face/dist/workspace-checkpoint.d.ts +6 -1
  426. package/node_modules/@xrkseek/server-face/dist/workspace-checkpoint.d.ts.map +1 -1
  427. package/node_modules/@xrkseek/server-face/dist/workspace-checkpoint.js +17 -1
  428. package/node_modules/@xrkseek/server-face/dist/workspace-checkpoint.js.map +1 -1
  429. package/node_modules/@xrkseek/server-face/dist/workspace-face.d.ts.map +1 -1
  430. package/node_modules/@xrkseek/server-face/dist/workspace-face.js +19 -14
  431. package/node_modules/@xrkseek/server-face/dist/workspace-face.js.map +1 -1
  432. package/node_modules/@xrkseek/server-face/dist/workspace-member-look.d.ts +22 -0
  433. package/node_modules/@xrkseek/server-face/dist/workspace-member-look.d.ts.map +1 -0
  434. package/node_modules/@xrkseek/server-face/dist/workspace-member-look.js +35 -0
  435. package/node_modules/@xrkseek/server-face/dist/workspace-member-look.js.map +1 -0
  436. package/node_modules/@xrkseek/server-face/dist/workspace-orchestrate-tools.d.ts +3 -2
  437. package/node_modules/@xrkseek/server-face/dist/workspace-orchestrate-tools.d.ts.map +1 -1
  438. package/node_modules/@xrkseek/server-face/dist/workspace-orchestrate-tools.js +74 -57
  439. package/node_modules/@xrkseek/server-face/dist/workspace-orchestrate-tools.js.map +1 -1
  440. package/node_modules/@xrkseek/server-face/dist/workspace-registry.d.ts +31 -0
  441. package/node_modules/@xrkseek/server-face/dist/workspace-registry.d.ts.map +1 -1
  442. package/node_modules/@xrkseek/server-face/dist/workspace-registry.js +109 -0
  443. package/node_modules/@xrkseek/server-face/dist/workspace-registry.js.map +1 -1
  444. package/node_modules/@xrkseek/server-face/dist/workspace-store.d.ts +2 -0
  445. package/node_modules/@xrkseek/server-face/dist/workspace-store.d.ts.map +1 -1
  446. package/node_modules/@xrkseek/server-face/dist/workspace-store.js +7 -0
  447. package/node_modules/@xrkseek/server-face/dist/workspace-store.js.map +1 -1
  448. package/node_modules/@xrkseek/server-face/package.json +60 -60
  449. package/node_modules/@xrkseek/server-host/dist/agent-cache.d.ts +16 -2
  450. package/node_modules/@xrkseek/server-host/dist/agent-cache.d.ts.map +1 -1
  451. package/node_modules/@xrkseek/server-host/dist/agent-cache.js +84 -36
  452. package/node_modules/@xrkseek/server-host/dist/agent-cache.js.map +1 -1
  453. package/node_modules/@xrkseek/server-host/dist/index.d.ts +37 -6
  454. package/node_modules/@xrkseek/server-host/dist/index.d.ts.map +1 -1
  455. package/node_modules/@xrkseek/server-host/dist/index.js +124 -27
  456. package/node_modules/@xrkseek/server-host/dist/index.js.map +1 -1
  457. package/node_modules/@xrkseek/server-host/dist/log.d.ts +6 -0
  458. package/node_modules/@xrkseek/server-host/dist/log.d.ts.map +1 -1
  459. package/node_modules/@xrkseek/server-host/dist/sidebar-face-bridge.d.ts.map +1 -1
  460. package/node_modules/@xrkseek/server-host/dist/sidebar-face-bridge.js +17 -2
  461. package/node_modules/@xrkseek/server-host/dist/sidebar-face-bridge.js.map +1 -1
  462. package/node_modules/@xrkseek/server-host/dist/standing-tools.d.ts.map +1 -1
  463. package/node_modules/@xrkseek/server-host/dist/standing-tools.js +3 -3
  464. package/node_modules/@xrkseek/server-host/dist/standing-tools.js.map +1 -1
  465. package/node_modules/@xrkseek/server-host/package.json +75 -75
  466. package/node_modules/@xrkseek/server-http/dist/dsh-compat/adapter-types.d.ts +5 -0
  467. package/node_modules/@xrkseek/server-http/dist/dsh-compat/adapter-types.d.ts.map +1 -1
  468. package/node_modules/@xrkseek/server-http/dist/dsh-compat/auto-review-tool-pre.d.ts +1 -1
  469. package/node_modules/@xrkseek/server-http/dist/dsh-compat/auto-review-tool-pre.d.ts.map +1 -1
  470. package/node_modules/@xrkseek/server-http/dist/dsh-compat/generic-plugin-http.d.ts.map +1 -1
  471. package/node_modules/@xrkseek/server-http/dist/dsh-compat/generic-plugin-http.js +41 -6
  472. package/node_modules/@xrkseek/server-http/dist/dsh-compat/generic-plugin-http.js.map +1 -1
  473. package/node_modules/@xrkseek/server-http/dist/dsh-compat/genui-browser-runtime.js +188 -188
  474. package/node_modules/@xrkseek/server-http/dist/dsh-compat/index.d.ts +1 -1
  475. package/node_modules/@xrkseek/server-http/dist/dsh-compat/index.d.ts.map +1 -1
  476. package/node_modules/@xrkseek/server-http/dist/dsh-compat/index.js +1 -1
  477. package/node_modules/@xrkseek/server-http/dist/dsh-compat/index.js.map +1 -1
  478. package/node_modules/@xrkseek/server-http/dist/dsh-compat/mobile-access-auth.d.ts.map +1 -1
  479. package/node_modules/@xrkseek/server-http/dist/dsh-compat/mobile-access-auth.js +292 -24
  480. package/node_modules/@xrkseek/server-http/dist/dsh-compat/mobile-access-auth.js.map +1 -1
  481. package/node_modules/@xrkseek/server-http/dist/dsh-compat/mobile-access-gate.d.ts.map +1 -1
  482. package/node_modules/@xrkseek/server-http/dist/dsh-compat/mobile-access-gate.js +12 -1
  483. package/node_modules/@xrkseek/server-http/dist/dsh-compat/mobile-access-gate.js.map +1 -1
  484. package/node_modules/@xrkseek/server-http/dist/dsh-compat/mobile-access.d.ts +16 -1
  485. package/node_modules/@xrkseek/server-http/dist/dsh-compat/mobile-access.d.ts.map +1 -1
  486. package/node_modules/@xrkseek/server-http/dist/dsh-compat/mobile-access.js +47 -2
  487. package/node_modules/@xrkseek/server-http/dist/dsh-compat/mobile-access.js.map +1 -1
  488. package/node_modules/@xrkseek/server-http/dist/dsh-compat/skin-center.d.ts +1 -1
  489. package/node_modules/@xrkseek/server-http/dist/dsh-compat/token-usage-stats-dash.js +53 -53
  490. package/node_modules/@xrkseek/server-http/dist/dsh-compat/underlying/mobile-gate-kit.d.ts +9 -4
  491. package/node_modules/@xrkseek/server-http/dist/dsh-compat/underlying/mobile-gate-kit.d.ts.map +1 -1
  492. package/node_modules/@xrkseek/server-http/dist/dsh-compat/underlying/mobile-gate-kit.js +39 -20
  493. package/node_modules/@xrkseek/server-http/dist/dsh-compat/underlying/mobile-gate-kit.js.map +1 -1
  494. package/node_modules/@xrkseek/server-http/dist/index.d.ts +2 -1
  495. package/node_modules/@xrkseek/server-http/dist/index.d.ts.map +1 -1
  496. package/node_modules/@xrkseek/server-http/dist/index.js +2 -1
  497. package/node_modules/@xrkseek/server-http/dist/index.js.map +1 -1
  498. package/node_modules/@xrkseek/server-http/dist/sunflower-free/ensure.d.ts +11 -0
  499. package/node_modules/@xrkseek/server-http/dist/sunflower-free/ensure.d.ts.map +1 -0
  500. package/node_modules/@xrkseek/server-http/dist/sunflower-free/ensure.js +85 -0
  501. package/node_modules/@xrkseek/server-http/dist/sunflower-free/ensure.js.map +1 -0
  502. package/node_modules/@xrkseek/server-http/package.json +72 -72
  503. package/node_modules/@xrkseek/server-loader/dist/load.d.ts.map +1 -1
  504. package/node_modules/@xrkseek/server-loader/dist/load.js +132 -0
  505. package/node_modules/@xrkseek/server-loader/dist/load.js.map +1 -1
  506. package/node_modules/@xrkseek/session-projection/README.md +26 -26
  507. package/node_modules/@xrkseek/session-projection/dist/index.d.ts +31 -2
  508. package/node_modules/@xrkseek/session-projection/dist/index.d.ts.map +1 -1
  509. package/node_modules/@xrkseek/session-projection/dist/index.js +135 -19
  510. package/node_modules/@xrkseek/session-projection/dist/index.js.map +1 -1
  511. package/node_modules/@xrkseek/session-telemetry/README.md +11 -11
  512. package/node_modules/@xrkseek/session-telemetry/dist/index.d.ts +1 -0
  513. package/node_modules/@xrkseek/session-telemetry/dist/index.d.ts.map +1 -1
  514. package/node_modules/@xrkseek/session-telemetry/dist/index.js +1 -0
  515. package/node_modules/@xrkseek/session-telemetry/dist/index.js.map +1 -1
  516. package/node_modules/@xrkseek/session-telemetry/dist/redact.d.ts +14 -0
  517. package/node_modules/@xrkseek/session-telemetry/dist/redact.d.ts.map +1 -0
  518. package/node_modules/@xrkseek/session-telemetry/dist/redact.js +58 -0
  519. package/node_modules/@xrkseek/session-telemetry/dist/redact.js.map +1 -0
  520. package/node_modules/@xrkseek/session-telemetry/dist/wrap-store.d.ts +7 -0
  521. package/node_modules/@xrkseek/session-telemetry/dist/wrap-store.d.ts.map +1 -1
  522. package/node_modules/@xrkseek/session-telemetry/dist/wrap-store.js +43 -12
  523. package/node_modules/@xrkseek/session-telemetry/dist/wrap-store.js.map +1 -1
  524. package/node_modules/@xrkseek/session-telemetry/package.json +27 -27
  525. package/node_modules/@xrkseek/workspace/dist/durable-inject.d.ts +13 -0
  526. package/node_modules/@xrkseek/workspace/dist/durable-inject.d.ts.map +1 -1
  527. package/node_modules/@xrkseek/workspace/dist/durable-inject.js +40 -4
  528. package/node_modules/@xrkseek/workspace/dist/durable-inject.js.map +1 -1
  529. package/node_modules/@xrkseek/workspace/dist/ecosystem-instructions.d.ts +10 -9
  530. package/node_modules/@xrkseek/workspace/dist/ecosystem-instructions.d.ts.map +1 -1
  531. package/node_modules/@xrkseek/workspace/dist/ecosystem-instructions.js +67 -19
  532. package/node_modules/@xrkseek/workspace/dist/ecosystem-instructions.js.map +1 -1
  533. package/node_modules/@xrkseek/workspace/dist/index.d.ts +19 -20
  534. package/node_modules/@xrkseek/workspace/dist/index.d.ts.map +1 -1
  535. package/node_modules/@xrkseek/workspace/dist/index.js +43 -20
  536. package/node_modules/@xrkseek/workspace/dist/index.js.map +1 -1
  537. package/node_modules/@xrkseek/workspace/dist/inject-fingerprint.d.ts +2 -0
  538. package/node_modules/@xrkseek/workspace/dist/inject-fingerprint.d.ts.map +1 -1
  539. package/node_modules/@xrkseek/workspace/dist/inject-fingerprint.js +23 -12
  540. package/node_modules/@xrkseek/workspace/dist/inject-fingerprint.js.map +1 -1
  541. package/node_modules/@xrkseek/workspace/dist/inject-sources.d.ts +7 -4
  542. package/node_modules/@xrkseek/workspace/dist/inject-sources.d.ts.map +1 -1
  543. package/node_modules/@xrkseek/workspace/dist/inject-sources.js +10 -0
  544. package/node_modules/@xrkseek/workspace/dist/inject-sources.js.map +1 -1
  545. package/node_modules/@xrkseek/workspace/dist/instruction-authority.d.ts +27 -0
  546. package/node_modules/@xrkseek/workspace/dist/instruction-authority.d.ts.map +1 -0
  547. package/node_modules/@xrkseek/workspace/dist/instruction-authority.js +78 -0
  548. package/node_modules/@xrkseek/workspace/dist/instruction-authority.js.map +1 -0
  549. package/node_modules/@xrkseek/workspace/dist/skill-dirs.d.ts +7 -0
  550. package/node_modules/@xrkseek/workspace/dist/skill-dirs.d.ts.map +1 -1
  551. package/node_modules/@xrkseek/workspace/dist/skill-dirs.js +4 -2
  552. package/node_modules/@xrkseek/workspace/dist/skill-dirs.js.map +1 -1
  553. package/node_modules/@xrkseek/workspace/dist/skill-tools.js +1 -1
  554. package/node_modules/@xrkseek/workspace/dist/skill-tools.js.map +1 -1
  555. package/node_modules/@xrkseek/workspace/dist/skills.d.ts +13 -1
  556. package/node_modules/@xrkseek/workspace/dist/skills.d.ts.map +1 -1
  557. package/node_modules/@xrkseek/workspace/dist/skills.js +45 -5
  558. package/node_modules/@xrkseek/workspace/dist/skills.js.map +1 -1
  559. package/node_modules/@xrkseek/workspace/dist/standing-skill-dirs.d.ts +26 -0
  560. package/node_modules/@xrkseek/workspace/dist/standing-skill-dirs.d.ts.map +1 -0
  561. package/node_modules/@xrkseek/workspace/dist/standing-skill-dirs.js +80 -0
  562. package/node_modules/@xrkseek/workspace/dist/standing-skill-dirs.js.map +1 -0
  563. package/node_modules/@xrkseek/workspace/dist/workspace-anchor.d.ts +7 -1
  564. package/node_modules/@xrkseek/workspace/dist/workspace-anchor.d.ts.map +1 -1
  565. package/node_modules/@xrkseek/workspace/dist/workspace-anchor.js +21 -1
  566. package/node_modules/@xrkseek/workspace/dist/workspace-anchor.js.map +1 -1
  567. package/node_modules/@xrkseek/workspace/package.json +28 -28
  568. package/node_modules/@xrkseek/xrk-agent/lib/index.js +1 -793
  569. package/node_modules/@xrkseek/xrk-agent/lib/invariant.js +1 -23
  570. package/node_modules/@xrkseek/xrk-attachment/lib/index.js +1 -1
  571. package/node_modules/@xrkseek/xrk-attachment/lib/invariant.js +1 -0
  572. package/node_modules/@xrkseek/xrk-attachment/lib/types/brand.js +10 -0
  573. package/node_modules/@xrkseek/xrk-attachment/lib/types/error.js +48 -0
  574. package/node_modules/@xrkseek/xrk-attachment/lib/types/index.js +42 -0
  575. package/node_modules/@xrkseek/xrk-attachment/lib/types/invariant.js +16 -0
  576. package/node_modules/@xrkseek/xrk-attachment/lib/types/types.d.ts +6 -0
  577. package/node_modules/@xrkseek/xrk-attachment/lib/types/types.js +3 -0
  578. package/node_modules/@xrkseek/xrk-attachment/package.json +1 -0
  579. package/node_modules/@xrkseek/xrk-brand/lib/index.js +1 -1
  580. package/node_modules/@xrkseek/xrk-brand/lib/invariant.js +1 -0
  581. package/node_modules/@xrkseek/xrk-brand/lib/types/index.js +24 -0
  582. package/node_modules/@xrkseek/xrk-brand/lib/types/invariant.js +22 -0
  583. package/node_modules/@xrkseek/xrk-brand/package.json +1 -0
  584. package/node_modules/@xrkseek/xrk-commands/lib/index.js +1 -1
  585. package/node_modules/@xrkseek/xrk-commands/lib/invariant.js +1 -0
  586. package/node_modules/@xrkseek/xrk-file-reference-local/README.md +46 -46
  587. package/node_modules/@xrkseek/xrk-file-reference-local/README.zh.md +46 -46
  588. package/node_modules/@xrkseek/xrk-file-reference-local/package.json +30 -30
  589. package/node_modules/@xrkseek/xrk-invariants/lib/index.js +1 -1
  590. package/node_modules/@xrkseek/xrk-invariants/lib/invariant.js +1 -0
  591. package/node_modules/@xrkseek/xrk-invariants/lib/types/index.js +148 -0
  592. package/node_modules/@xrkseek/xrk-invariants/lib/types/invariant.js +22 -0
  593. package/node_modules/@xrkseek/xrk-invariants/package.json +1 -0
  594. package/node_modules/@xrkseek/xrk-llm/lib/index.js +1 -1
  595. package/node_modules/@xrkseek/xrk-llm/lib/invariant.js +1 -0
  596. package/node_modules/@xrkseek/xrk-llm/lib/types/index.js +4 -0
  597. package/node_modules/@xrkseek/xrk-llm/lib/types/types.d.ts +11 -0
  598. package/node_modules/@xrkseek/xrk-permission-presets/lib/index.js +1 -1
  599. package/node_modules/@xrkseek/xrk-permission-presets/lib/invariant.js +1 -0
  600. package/node_modules/@xrkseek/xrk-scope/lib/index.js +1 -0
  601. package/node_modules/@xrkseek/xrk-scope/lib/types/index.d.ts +129 -0
  602. package/node_modules/@xrkseek/xrk-scope/lib/types/index.js +243 -0
  603. package/node_modules/@xrkseek/xrk-scope/package.json +34 -0
  604. package/node_modules/@xrkseek/xrk-session/lib/index.js +1 -1
  605. package/node_modules/@xrkseek/xrk-session/lib/invariant.js +1 -0
  606. package/node_modules/@xrkseek/xrk-session-projection/lib/index.js +1 -1
  607. package/node_modules/@xrkseek/xrk-session-projection/lib/invariant.js +1 -0
  608. package/node_modules/@xrkseek/xrk-session-reference/README.md +50 -50
  609. package/node_modules/@xrkseek/xrk-session-reference/README.zh.md +50 -50
  610. package/node_modules/@xrkseek/xrk-session-reference/dist/prepare-face.js +13 -13
  611. package/node_modules/@xrkseek/xrk-session-reference/dist/spill.js +2 -2
  612. package/node_modules/@xrkseek/xrk-session-reference/package.json +56 -56
  613. package/node_modules/@xrkseek/xrk-settings/lib/index.js +1 -638
  614. package/node_modules/@xrkseek/xrk-settings/lib/invariant.js +1 -67
  615. package/node_modules/@xrkseek/xrk-system-prompt/package.json +15 -15
  616. package/node_modules/@xrkseek/xrk-system-prompt/src/index.ts +144 -144
  617. package/node_modules/@xrkseek/xrk-token-meter/README.i18n.yaml +6 -0
  618. package/node_modules/@xrkseek/xrk-token-meter/README.md +68 -0
  619. package/node_modules/@xrkseek/xrk-token-meter/README.zh.md +68 -0
  620. package/node_modules/@xrkseek/xrk-token-meter/lib/index.js +1 -0
  621. package/node_modules/@xrkseek/xrk-token-meter/lib/invariant.js +1 -0
  622. package/node_modules/@xrkseek/xrk-token-meter/lib/types/breakdown-projection.d.ts +29 -0
  623. package/node_modules/@xrkseek/xrk-token-meter/lib/types/breakdown-projection.js +56 -0
  624. package/node_modules/@xrkseek/xrk-token-meter/lib/types/client.d.ts +9 -0
  625. package/node_modules/@xrkseek/xrk-token-meter/lib/types/client.js +7 -0
  626. package/node_modules/@xrkseek/xrk-token-meter/lib/types/estimate.d.ts +42 -0
  627. package/node_modules/@xrkseek/xrk-token-meter/lib/types/estimate.js +79 -0
  628. package/node_modules/@xrkseek/xrk-token-meter/lib/types/index.d.ts +62 -0
  629. package/node_modules/@xrkseek/xrk-token-meter/lib/types/index.js +250 -0
  630. package/node_modules/@xrkseek/xrk-token-meter/lib/types/invariant.d.ts +16 -0
  631. package/node_modules/@xrkseek/xrk-token-meter/lib/types/invariant.js +30 -0
  632. package/node_modules/@xrkseek/xrk-token-meter/lib/types/projection.d.ts +74 -0
  633. package/node_modules/@xrkseek/xrk-token-meter/lib/types/projection.js +7 -0
  634. package/node_modules/@xrkseek/xrk-token-meter/lib/types/surface-fold.d.ts +38 -0
  635. package/node_modules/@xrkseek/xrk-token-meter/lib/types/surface-fold.js +47 -0
  636. package/node_modules/@xrkseek/xrk-token-meter/lib/types/surface-projection.d.ts +59 -0
  637. package/node_modules/@xrkseek/xrk-token-meter/lib/types/surface-projection.js +66 -0
  638. package/node_modules/@xrkseek/xrk-token-meter/lib/types/turn-usage.d.ts +33 -0
  639. package/node_modules/@xrkseek/xrk-token-meter/lib/types/turn-usage.js +247 -0
  640. package/node_modules/@xrkseek/xrk-token-meter/lib/types/types.d.ts +44 -0
  641. package/node_modules/@xrkseek/xrk-token-meter/lib/types/types.js +7 -0
  642. package/node_modules/@xrkseek/xrk-token-meter/lib/types/usage-projection.d.ts +64 -0
  643. package/node_modules/@xrkseek/xrk-token-meter/lib/types/usage-projection.js +161 -0
  644. package/node_modules/@xrkseek/xrk-token-meter/package.json +57 -0
  645. package/node_modules/@xrkseek/xrk-tools/lib/index.js +1 -1
  646. package/node_modules/@xrkseek/xrk-tools/lib/invariant.js +1 -1
  647. package/node_modules/@xrkseek/xrk-tools/src/presentation.ts +39 -39
  648. package/node_modules/@xrkseek/xrk-typert-protocol/lib/index.js +1 -1
  649. package/node_modules/@xrkseek/xrk-typert-protocol/lib/invariant.js +1 -0
  650. package/node_modules/@xrkseek/xrk-workflow/README.md +73 -73
  651. package/node_modules/@xrkseek/xrk-workflow/README.zh.md +72 -72
  652. package/node_modules/@xrkseek/xrk-workflow/lib/types/index.js +118 -118
  653. package/package.json +7 -1
  654. package/node_modules/@xrkseek/llm/dist/reasoning-effort.d.ts +0 -14
  655. package/node_modules/@xrkseek/llm/dist/reasoning-effort.d.ts.map +0 -1
  656. package/node_modules/@xrkseek/llm/dist/reasoning-effort.js +0 -21
  657. package/node_modules/@xrkseek/llm/dist/reasoning-effort.js.map +0 -1
  658. package/node_modules/@xrkseek/server-face/dist/index.d.mts +0 -3734
  659. package/node_modules/@xrkseek/server-face/dist/index.d.mts.map +0 -1
  660. package/node_modules/@xrkseek/server-face/dist/index.mjs +0 -22085
  661. package/node_modules/@xrkseek/server-face/dist/index.mjs.map +0 -1
  662. package/node_modules/@xrkseek/server-face/dist/model-reasoning.d.ts +0 -51
  663. package/node_modules/@xrkseek/server-face/dist/model-reasoning.d.ts.map +0 -1
  664. package/node_modules/@xrkseek/server-face/dist/model-reasoning.js +0 -104
  665. package/node_modules/@xrkseek/server-face/dist/model-reasoning.js.map +0 -1
  666. package/node_modules/@xrkseek/server-host/dist/sidebar-pty-agent.d.ts +0 -2
  667. package/node_modules/@xrkseek/server-host/dist/sidebar-pty-agent.d.ts.map +0 -1
  668. package/node_modules/@xrkseek/server-host/dist/sidebar-pty-agent.js +0 -98
  669. package/node_modules/@xrkseek/server-host/dist/sidebar-pty-agent.js.map +0 -1
  670. package/node_modules/@xrkseek/server-host/dist/sidebar-pty-worker.d.ts +0 -18
  671. package/node_modules/@xrkseek/server-host/dist/sidebar-pty-worker.d.ts.map +0 -1
  672. package/node_modules/@xrkseek/server-host/dist/sidebar-pty-worker.js +0 -141
  673. package/node_modules/@xrkseek/server-host/dist/sidebar-pty-worker.js.map +0 -1
  674. package/node_modules/@xrkseek/server-host/dist/win-fd-inherit.d.ts +0 -30
  675. package/node_modules/@xrkseek/server-host/dist/win-fd-inherit.d.ts.map +0 -1
  676. package/node_modules/@xrkseek/server-host/dist/win-fd-inherit.js +0 -96
  677. package/node_modules/@xrkseek/server-host/dist/win-fd-inherit.js.map +0 -1
@@ -1,906 +1,906 @@
1
- import { Binary, clone, deepEqual, filterKeys, isNullable, isPlainObject, pick, valueMap, type Dict } from '@xrkseek/cosmokit'
2
- import type { StandardSchemaV1 } from '@standard-schema/spec'
3
-
4
- const kSchema = Symbol.for('schemastery')
5
- const kValidationError = Symbol.for('ValidationError')
6
-
7
- declare global {
8
- namespace Schemastery {
9
- /** Convert primitive constructors, constants, and existing schemas into a schema type. */
10
- export type From<X> =
11
- | X extends string | number | boolean ? Schema<X>
12
- : X extends Schema ? X
13
- : X extends typeof String ? Schema<string>
14
- : X extends typeof Number ? Schema<number>
15
- : X extends typeof Boolean ? Schema<boolean>
16
- : X extends typeof Function ? Schema<Function, (...args: any[]) => any>
17
- : X extends Constructor<infer S> ? Schema<S>
18
- : never
19
-
20
- type TypeS1<X> = X extends Schema<infer S, unknown> ? S : never
21
- type Inverse<X> = X extends Schema<any, infer Y> ? (arg: Y) => void : never
22
-
23
- /** Input type accepted by a schema-like value. */
24
- export type TypeS<X> = TypeS1<From<X>>
25
- /** Output type returned by a schema-like value after validation. */
26
- export type TypeT<X> = ReturnType<From<X>>
27
- /** Resolver callback used by custom schema types registered with `Schema.extend()`. */
28
- export type Resolve = (data: any, schema: Schema, options: Options, strict?: boolean) => [any, any?]
29
-
30
- /** Input type accepted by one schema in an intersection. */
31
- export type IntersectS<X> = From<X> extends Schema<infer S, unknown> ? S : never
32
- /** Output type returned by one schema in an intersection. */
33
- export type IntersectT<X> = Inverse<From<X>> extends ((arg: infer T) => void) ? T : never
34
-
35
- type TupleS<X extends readonly any[]> = X extends readonly [infer L, ...infer R] ? [TypeS<L>?, ...TupleS<R>] : any[]
36
- type TupleT<X extends readonly any[]> = X extends readonly [infer L, ...infer R] ? [TypeT<L>?, ...TupleT<R>] : any[]
37
- type ObjectS<X extends Dict> = { [K in keyof X]?: TypeS<X[K]> | null } & Dict
38
- type ObjectT<X extends Dict> = { [K in keyof X]: TypeT<X[K]> } & Dict
39
- type Constructor<T = any> = new (...args: any[]) => T
40
-
41
- /** Static constructor and factory methods exposed by the default `Schema` export. */
42
- export interface Static {
43
- <T = any>(options: Partial<Schema<T>>): Schema<T>
44
- new <T = any>(options: Partial<Schema<T>>): Schema<T>
45
- prototype: Schema
46
- /** Validate a value against a schema node and return `[output, adaptedInput?]`. */
47
- resolve: Resolve
48
- /** Infer a schema from a primitive value, constructor, or existing schema. */
49
- from<X = any>(source?: X): From<X>
50
- /** Register a resolver for a custom schema `type`. */
51
- extend(type: string, resolve: Resolve): void
52
- /** Accept any value without validation. */
53
- any<T = any>(): Schema<T>
54
- /** Accept only nullable input. */
55
- never(): Schema<never>
56
- /** Accept exactly one constant value. */
57
- const<const T>(value: T): Schema<T>
58
- /** Accept strings, with optional metadata constraints added by instance methods. */
59
- string(): Schema<string>
60
- /** Accept numbers, with optional range and step constraints. */
61
- number(): Schema<number>
62
- /** Accept non-negative integer numbers. */
63
- natural(): Schema<number>
64
- /** Accept a number between 0 and 1 and mark it as a slider. */
65
- percent(): Schema<number>
66
- /** Accept booleans. */
67
- boolean(): Schema<boolean>
68
- /** Accept `Date` instances or parse datetime strings into `Date` objects. */
69
- date(): Schema<string | Date, Date>
70
- /** Accept `RegExp` instances or parse strings into regular expressions. */
71
- regExp(flag?: string): Schema<string | RegExp, RegExp>
72
- /** Accept binary sources and normalize them to `ArrayBufferLike`. */
73
- arrayBuffer(): Schema<Binary.Source, ArrayBufferLike>
74
- arrayBuffer(encoding: 'hex' | 'base64'): Schema<Binary.Source | string, ArrayBufferLike>
75
- /** Accept a numeric bitset or string keys and normalize to a number. */
76
- bitset<K extends string>(bits: Partial<Record<K, number>>): Schema<number | readonly K[], number>
77
- /** Accept functions. */
78
- function(): Schema<Function, (...args: any[]) => any>
79
- /** Accept instances of a constructor or objects whose constructor name matches. */
80
- is(constructor: string): Schema
81
- is<T>(constructor: Constructor<T>): Schema<T>
82
- /** Accept arrays whose elements match `inner`. */
83
- array<X>(inner: X): Schema<TypeS<X>[], TypeT<X>[]>
84
- /** Accept plain objects with values matching `inner` and optional key schema. */
85
- dict<X, Y extends Schema<any, string> = Schema<string>>(inner: X, sKey?: Y): Schema<Dict<TypeS<X>, TypeS<Y>>, Dict<TypeT<X>, TypeT<Y>>>
86
- /** Accept tuple arrays where each index matches the corresponding schema. */
87
- tuple<const X extends readonly any[]>(list: X): Schema<TupleS<X>, TupleT<X>>
88
- /** Accept plain objects whose declared properties match the schema dictionary. */
89
- object<X extends Dict>(dict: X): Schema<ObjectS<X>, ObjectT<X>>
90
- /** Accept values matching at least one schema in `list`. */
91
- union<const X>(list: readonly X[]): Schema<TypeS<X>, TypeT<X>>
92
- /** Accept values matching every schema in `list`, merging object outputs. */
93
- intersect<const X>(list: readonly X[]): Schema<IntersectS<X>, IntersectT<X>>
94
- /** Validate with `inner`, then convert the result with `callback`. */
95
- transform<X, T>(inner: X, callback: (value: TypeS<X>, options: Schemastery.Options) => T, preserve?: boolean): Schema<TypeS<X>, T>
96
- /** Defer construction of a recursive schema until validation or serialization. */
97
- lazy<X extends Schema>(callback: () => X): X
98
- ValidationError: typeof ValidationError
99
- }
100
-
101
- /** Runtime validation options shared by all schema calls. */
102
- interface Options {
103
- /** Remove invalid object properties instead of throwing when possible. */
104
- autofix?: boolean
105
- /** Skip validation for selected values and schema nodes. */
106
- ignore?(data: any, schema: Schema): boolean
107
- /** Path used to format nested validation errors. */
108
- path?: (keyof any)[]
109
- }
110
-
111
- /** UI and validation metadata attached by schema builder methods. */
112
- export interface Meta<T = any> {
113
- default?: T extends {} ? Partial<T> : T
114
- required?: boolean
115
- disabled?: boolean
116
- collapse?: boolean
117
- badges?: { text: string; type: string }[]
118
- hidden?: boolean
119
- loose?: boolean
120
- /** Runtime-only; skip persist (DSH community packs e.g. OFM channel-pack). */
121
- volatile?: boolean
122
- role?: string
123
- extra?: any
124
- link?: string
125
- description?: string | Dict<string>
126
- comment?: string
127
- pattern?: { source: string; flags?: string }
128
- max?: number
129
- min?: number
130
- step?: number
131
- }
132
- }
133
-
134
- /** Callable schema instance that validates input and returns normalized output. */
135
- interface Schemastery<S = any, T = S> {
136
- (data?: S | null, options?: Schemastery.Options): T
137
- new (data?: S | null, options?: Schemastery.Options): T
138
- [kSchema]: true
139
- uid: number
140
- meta: Schemastery.Meta<T>
141
- type: string
142
- sKey?: Schema
143
- inner?: Schema
144
- list?: Schema[]
145
- dict?: Dict<Schema>
146
- bits?: Dict<number>
147
- callback?: Function
148
- constructor?: string | Function
149
- builder?: Function
150
- value?: T
151
- refs?: Dict<Schema>
152
- preserve?: boolean
153
- '~standard': StandardSchemaV1.Props // <S, T>
154
- /** Format this schema as a compact TypeScript-like type string. */
155
- toString(inline?: boolean): string
156
- /** Serialize this schema, preserving shared and recursive references. */
157
- toJSON(): Schema<S, T>
158
- /** Mark nullable input as invalid unless a default supplies a fallback. */
159
- required(value?: boolean): Schema<S, T>
160
- /** Hide this schema node from UI renderers. */
161
- hidden(value?: boolean): Schema<S, T>
162
- /** Mark this node as runtime-only (not persisted). */
163
- volatile(value?: boolean): Schema<S, T>
164
- /** Return the default value instead of throwing when validation fails. */
165
- loose(value?: boolean): Schema<S, T>
166
- /** Attach a renderer role and optional role-specific metadata. */
167
- role(text: string, extra?: any): Schema<S, T>
168
- /** Attach an external documentation link. */
169
- link(link: string): Schema<S, T>
170
- /** Set the fallback value used for nullable input. */
171
- default(value: T): Schema<S, T>
172
- /** Attach an auxiliary comment for documentation or form UIs. */
173
- comment(text: string): Schema<S, T>
174
- /** Attach a localized or plain description for documentation or form UIs. */
175
- description(text: string): Schema<S, T>
176
- /** Mark this schema node as disabled for form UIs. */
177
- disabled(value?: boolean): Schema<S, T>
178
- /** Request collapsed rendering for nested form UIs. */
179
- collapse(value?: boolean): Schema<S, T>
180
- /** Add a deprecated badge to this schema node. */
181
- deprecated(): Schema<S, T>
182
- /** Add an experimental badge to this schema node. */
183
- experimental(): Schema<S, T>
184
- /** Require strings to match a regular expression. */
185
- pattern(regexp: RegExp): Schema<S, T>
186
- /** Set an inclusive maximum for numbers or collection lengths. */
187
- max(value: number): Schema<S, T>
188
- /** Set an inclusive minimum for numbers or collection lengths. */
189
- min(value: number): Schema<S, T>
190
- /** Set the numeric increment constraint. */
191
- step(value: number): Schema<S, T>
192
- /** Add or replace an object property schema. */
193
- set(key: string, value: Schema): Schema<S, T>
194
- /** Append a tuple, union, or intersection member schema. */
195
- push(value: Schema): Schema<S, T>
196
- /** Remove values equal to schema defaults from normalized output. */
197
- simplify(value?: any): any
198
- /** Return a schema clone with descriptions merged from locale messages. */
199
- i18n(messages: Dict): Schema<S, T>
200
- /** Attach arbitrary metadata consumed by form renderers and downstream tools. */
201
- extra<K extends keyof Schemastery.Meta>(key: K, value: Schemastery.Meta[K]): Schema<S, T>
202
- }
203
- }
204
-
205
- declare namespace globalThis {
206
- // eslint-disable-next-line @typescript-eslint/naming-convention
207
- export let __schemastery_index__: number
208
- export let __schemastery_refs__: Record<number, Schema> | undefined
209
- }
210
-
211
- globalThis.__schemastery_index__ ??= 0
212
- globalThis.__schemastery_refs__ = undefined
213
-
214
- class ValidationError extends TypeError {
215
- name = 'ValidationError'
216
-
217
- constructor(message: string, public options: Schemastery.Options) {
218
- let prefix = '$'
219
- for (const segment of options.path || []) {
220
- if (typeof segment === 'string') {
221
- prefix += '.' + segment
222
- } else if (typeof segment === 'number') {
223
- prefix += '[' + segment + ']'
224
- } else if (typeof segment === 'symbol') {
225
- prefix += `[Symbol(${segment.toString()})]`
226
- }
227
- }
228
- if (prefix.startsWith('.')) prefix = prefix.slice(1)
229
- super((prefix === '$' ? '' : `${prefix} `) + message)
230
- }
231
-
232
- static is(error: any): error is ValidationError {
233
- return !!error?.[kValidationError]
234
- }
235
- }
236
-
237
- Object.defineProperty(ValidationError.prototype, kValidationError, {
238
- value: true,
239
- })
240
-
241
- type Schema<S = any, T = S> = Schemastery<S, T>
242
-
243
- const Schema = function (options: Schema) {
244
- const schema = function (data: any, options: Schemastery.Options = {}) {
245
- return Schema.resolve(data, schema, options)[0]
246
- } as Schema
247
-
248
- if (options.refs) {
249
- const refs = valueMap(options.refs, options => new Schema(options))
250
- const getRef = (uid: any) => refs[uid]!
251
- for (const key in refs) {
252
- const options = refs[key]!
253
- options.sKey = getRef(options.sKey)
254
- options.inner = getRef(options.inner)
255
- options.list = options.list && options.list.map(getRef)
256
- options.dict = options.dict && valueMap(options.dict, getRef)
257
- }
258
- return refs[options.uid!]
259
- }
260
-
261
- Object.assign(schema, options)
262
- if (typeof schema.callback === 'string') {
263
- try {
264
- // eslint-disable-next-line no-new-func
265
- schema.callback = new Function('return ' + schema.callback)()
266
- } catch {}
267
- }
268
- Object.defineProperty(schema, 'uid', { value: globalThis.__schemastery_index__++ })
269
- Object.setPrototypeOf(schema, Schema.prototype)
270
- schema.meta ||= {}
271
- schema.toString = schema.toString.bind(schema)
272
- return schema
273
- } as Schemastery.Static
274
-
275
- Schema.prototype = Object.create(Function.prototype)
276
-
277
- Schema.prototype[kSchema] = true
278
-
279
- Object.defineProperty(Schema.prototype, '~standard', {
280
- get(this: Schema) {
281
- return {
282
- version: 1,
283
- vendor: 'schemastery',
284
- validate: (value: unknown) => {
285
- try {
286
- return { value: Schema.resolve(value, this, {})[0] }
287
- } catch (error) {
288
- if (ValidationError.is(error)) {
289
- return { issues: [{ message: error.message, path: error.options.path }] }
290
- }
291
- throw error
292
- }
293
- },
294
- }
295
- },
296
- })
297
-
298
- Schema.ValidationError = ValidationError
299
-
300
- Schema.prototype.toJSON = function toJSON() {
301
- if (globalThis.__schemastery_refs__) {
302
- globalThis.__schemastery_refs__[this.uid] ??= JSON.parse(JSON.stringify({ ...this }))
303
- return this.uid as any
304
- }
305
-
306
- globalThis.__schemastery_refs__ = { [this.uid]: { ...this } as Schema }
307
- globalThis.__schemastery_refs__[this.uid] = JSON.parse(JSON.stringify({ ...this }))
308
- const result = { uid: this.uid, refs: globalThis.__schemastery_refs__ }
309
- globalThis.__schemastery_refs__ = undefined
310
- return result
311
- }
312
-
313
- Schema.prototype.set = function set(key, value) {
314
- this.dict![key] = value
315
- return this
316
- }
317
-
318
- Schema.prototype.push = function push(value) {
319
- this.list!.push(value)
320
- return this
321
- }
322
-
323
- function mergeDesc(original: undefined | string | Dict<string>, messages: Dict) {
324
- const result: Dict<string> = typeof original === 'string' ? { '': original } : { ...original }
325
- for (const locale in messages) {
326
- const value = messages[locale]
327
- if (value?.$description || value?.$desc) {
328
- result[locale] = value.$description || value.$desc
329
- } else if (typeof value === 'string') {
330
- result[locale] = value
331
- }
332
- }
333
- return result
334
- }
335
-
336
- function getInner(value: any) {
337
- return value?.$value ?? value?.$inner
338
- }
339
-
340
- function extractKeys(data: any) {
341
- return filterKeys(data ?? {}, key => !key.startsWith('$'))
342
- }
343
-
344
- Schema.prototype.i18n = function i18n(messages) {
345
- const schema = Schema(this)
346
- const desc = mergeDesc(schema.meta.description, messages)
347
- if (Object.keys(desc).length) schema.meta.description = desc
348
- if (schema.dict) {
349
- schema.dict = valueMap(schema.dict, (inner, key) => {
350
- return inner.i18n(valueMap(messages, (data) => getInner(data)?.[key] ?? data?.[key]))
351
- })
352
- }
353
- if (schema.list) {
354
- schema.list = schema.list!.map((inner, index) => {
355
- return inner.i18n(valueMap(messages, (data = {}) => {
356
- if (Array.isArray(getInner(data))) return getInner(data)[index]
357
- if (Array.isArray(data)) return data[index]
358
- return extractKeys(data)
359
- }))
360
- })
361
- }
362
- if (schema.inner) {
363
- schema.inner = schema.inner.i18n(valueMap(messages, (data) => {
364
- if (getInner(data)) return getInner(data)
365
- return extractKeys(data)
366
- }))
367
- }
368
- if (schema.sKey) {
369
- schema.sKey = schema.sKey.i18n(valueMap(messages, (data) => data?.$key))
370
- }
371
- return schema
372
- }
373
-
374
- Schema.prototype.extra = function extra(key, value) {
375
- const schema = Schema(this)
376
- schema.meta = { ...schema.meta, [key]: value }
377
- return schema
378
- }
379
-
380
- for (const key of ['required', 'disabled', 'collapse', 'hidden', 'loose', 'volatile']) {
381
- Object.assign(Schema.prototype, {
382
- [key](this: Schema, value = true) {
383
- const schema = Schema(this)
384
- schema.meta = { ...schema.meta, [key]: value }
385
- return schema
386
- },
387
- })
388
- }
389
-
390
- Schema.prototype.deprecated = function deprecated() {
391
- const schema = Schema(this)
392
- schema.meta.badges ||= []
393
- schema.meta.badges.push({ text: 'deprecated', type: 'danger' })
394
- return schema
395
- }
396
-
397
- Schema.prototype.experimental = function experimental() {
398
- const schema = Schema(this)
399
- schema.meta.badges ||= []
400
- schema.meta.badges.push({ text: 'experimental', type: 'warning' })
401
- return schema
402
- }
403
-
404
- Schema.prototype.pattern = function pattern(regexp) {
405
- const schema = Schema(this)
406
- const pattern = pick(regexp, ['source', 'flags'])
407
- schema.meta = { ...schema.meta, pattern }
408
- return schema
409
- }
410
-
411
- Schema.prototype.simplify = function simplify(this: Schema, value) {
412
- if (deepEqual(value, this.meta.default, this.type === 'dict')) return null
413
- if (isNullable(value)) return value
414
- if (this.type === 'object' || this.type === 'dict') {
415
- const result: Dict = {}
416
- for (const key in value) {
417
- const schema = this.type === 'object' ? this.dict![key] : this.inner
418
- const item = schema?.simplify(value[key])
419
- if (this.type === 'dict' || !isNullable(item)) result[key] = item
420
- }
421
- if (deepEqual(result, this.meta.default, this.type === 'dict')) return null
422
- return result
423
- } else if (this.type === 'array' || this.type === 'tuple') {
424
- const result: any[] = []
425
- ;(value as any[]).forEach((value, index) => {
426
- const schema = this.type === 'array' ? this.inner : this.list![index]
427
- const item = schema ? schema.simplify(value) : value
428
- result.push(item)
429
- })
430
- return result
431
- } else if (this.type === 'intersect') {
432
- const result: Dict = {}
433
- for (const item of this.list!) {
434
- Object.assign(result, item.simplify(value))
435
- }
436
- return result
437
- } else if (this.type === 'union') {
438
- for (const schema of this.list!) {
439
- try {
440
- Schema.resolve(value, schema, {})
441
- return schema.simplify(value)
442
- } catch {}
443
- }
444
- }
445
- return value
446
- }
447
-
448
- Schema.prototype.toString = function toString(inline?: boolean) {
449
- return formatters[this.type]?.(this, inline) ?? `Schema<${this.type}>`
450
- }
451
-
452
- Schema.prototype.role = function role(role, extra) {
453
- const schema = Schema(this)
454
- schema.meta = { ...schema.meta, role, extra }
455
- return schema
456
- }
457
-
458
- for (const key of ['default', 'link', 'comment', 'description', 'max', 'min', 'step']) {
459
- Object.assign(Schema.prototype, {
460
- [key](this: Schema, value: any) {
461
- const schema = Schema(this)
462
- schema.meta = { ...schema.meta, [key]: value }
463
- return schema
464
- },
465
- })
466
- }
467
-
468
- const resolvers: Dict<Schemastery.Resolve> = {}
469
-
470
- Schema.extend = function extend(type, resolve) {
471
- resolvers[type] = resolve
472
- }
473
-
474
- Schema.resolve = function resolve(data, schema, options = {}, strict = false) {
475
- if (!schema) return [data]
476
- if (options.ignore?.(data, schema)) return [data]
477
-
478
- if (isNullable(data) && schema.type !== 'lazy') {
479
- if (schema.meta.required) throw new ValidationError(`missing required value`, options)
480
- let current = schema
481
- let fallback = schema.meta.default
482
- while (current?.type === 'intersect' && isNullable(fallback)) {
483
- current = current.list![0]
484
- fallback = current?.meta.default
485
- }
486
- if (isNullable(fallback)) return [data]
487
- data = clone(fallback)
488
- }
489
-
490
- const callback = resolvers[schema.type]
491
- if (!callback) throw new ValidationError(`unsupported type "${schema.type}"`, options)
492
-
493
- try {
494
- return callback(data, schema, options, strict)
495
- } catch (error) {
496
- if (!schema.meta.loose) throw error
497
- return [schema.meta.default]
498
- }
499
- }
500
-
501
- Schema.from = function from(source: any) {
502
- if (isNullable(source)) {
503
- return Schema.any()
504
- } else if (['string', 'number', 'boolean'].includes(typeof source)) {
505
- return Schema.const(source).required()
506
- } else if (source[kSchema]) {
507
- return source
508
- } else if (typeof source === 'function') {
509
- switch (source) {
510
- case String: return Schema.string().required()
511
- case Number: return Schema.number().required()
512
- case Boolean: return Schema.boolean().required()
513
- case Function: return Schema.function().required()
514
- default: return Schema.is(source).required()
515
- }
516
- } else {
517
- throw new TypeError(`cannot infer schema from ${source}`)
518
- }
519
- }
520
-
521
- Schema.lazy = function lazy(builder) {
522
- const toJSON = () => {
523
- if (!schema.inner![kSchema]) {
524
- schema.inner = schema.builder!()
525
- schema.inner!.meta = { ...schema.meta, ...schema.inner!.meta }
526
- }
527
- return schema.inner!.toJSON()
528
- }
529
- const schema = new Schema({ type: 'lazy', builder, inner: { toJSON } as any })
530
- return schema as any
531
- }
532
-
533
- Schema.natural = function natural() {
534
- return Schema.number().step(1).min(0)
535
- }
536
-
537
- Schema.percent = function percent() {
538
- return Schema.number().step(0.01).min(0).max(1).role('slider')
539
- }
540
-
541
- Schema.date = function date() {
542
- return Schema.union([
543
- Schema.is(Date),
544
- Schema.transform(Schema.string().role('datetime'), (value, options) => {
545
- const date = new Date(value)
546
- if (isNaN(+date)) throw new ValidationError(`invalid date "${value}"`, options)
547
- return date
548
- }, true),
549
- ])
550
- }
551
-
552
- Schema.regExp = function regExp(flag = '') {
553
- return Schema.union([
554
- Schema.is(RegExp),
555
- Schema.transform(Schema.string().role('regexp', { flag }), (value, options) => {
556
- try {
557
- return new RegExp(value, flag)
558
- } catch (e: any) {
559
- throw new ValidationError(e.message, options)
560
- }
561
- }, true),
562
- ])
563
- }
564
-
565
- Schema.arrayBuffer = function arrayBuffer(encoding?: 'hex' | 'base64'): any {
566
- return Schema.union([
567
- Schema.is(ArrayBuffer),
568
- Schema.is(SharedArrayBuffer),
569
- Schema.transform(Schema.any<ArrayBufferView>(), (value, options) => {
570
- if (Binary.isSource(value)) return Binary.fromSource(value)
571
- throw new ValidationError(`expected ArrayBufferSource but got ${value}`, options)
572
- }, true),
573
- ...encoding ? [Schema.transform(Schema.string(), (value, options) => {
574
- try {
575
- return encoding === 'base64'
576
- ? Binary.fromBase64(value)
577
- : Binary.fromHex(value)
578
- } catch (e: any) {
579
- throw new ValidationError(e.message, options)
580
- }
581
- }, true)] as const : [],
582
- ])
583
- }
584
-
585
- Schema.extend('lazy', (data, schema, options, strict) => {
586
- if (!schema.inner![kSchema]) {
587
- schema.inner = schema.builder!()
588
- schema.inner!.meta = { ...schema.meta, ...schema.inner!.meta }
589
- }
590
- return Schema.resolve(data, schema.inner!, options, strict)
591
- })
592
-
593
- Schema.extend('any', (data) => {
594
- return [data]
595
- })
596
-
597
- Schema.extend('never', (data, _, options) => {
598
- throw new ValidationError(`expected nullable but got ${data}`, options)
599
- })
600
-
601
- Schema.extend('const', (data, { value }, options) => {
602
- if (deepEqual(data, value)) return [value]
603
- throw new ValidationError(`expected ${value} but got ${data}`, options)
604
- })
605
-
606
- function checkWithinRange(data: number, meta: Schemastery.Meta<any>, description: string, options: Schemastery.Options, skipMin = false) {
607
- const { max = Infinity, min = -Infinity } = meta
608
- if (data > max) throw new ValidationError(`expected ${description} <= ${max} but got ${data}`, options)
609
- if (data < min && !skipMin) throw new ValidationError(`expected ${description} >= ${min} but got ${data}`, options)
610
- }
611
-
612
- Schema.extend('string', (data, { meta }, options) => {
613
- if (typeof data !== 'string') throw new ValidationError(`expected string but got ${data}`, options)
614
- if (meta.pattern) {
615
- const regexp = new RegExp(meta.pattern.source, meta.pattern.flags)
616
- if (!regexp.test(data)) throw new ValidationError(`expect string to match regexp ${regexp}`, options)
617
- }
618
- checkWithinRange(data.length, meta, 'string length', options)
619
- return [data]
620
- })
621
-
622
- function decimalShift(data: number, digits: number) {
623
- const str = data.toString()
624
- if (str.includes('e')) return data * Math.pow(10, digits)
625
- const index = str.indexOf('.')
626
- if (index === -1) return data * Math.pow(10, digits)
627
- const frac = str.slice(index + 1)
628
- const integer = str.slice(0, index)
629
- if (frac.length <= digits) return +(integer + frac.padEnd(digits, '0'))
630
- return +(integer + frac.slice(0, digits) + '.' + frac.slice(digits))
631
- }
632
-
633
- function isMultipleOf(data: number, min: number, step: number) {
634
- step = Math.abs(step)
635
- if (!/^\d+\.\d+$/.test(step.toString())) {
636
- return (data - min) % step === 0
637
- }
638
- const index = step.toString().indexOf('.')
639
- const digits = step.toString().slice(index + 1).length
640
- return Math.abs(decimalShift(data, digits) - decimalShift(min, digits)) % decimalShift(step, digits) === 0
641
- }
642
-
643
- Schema.extend('number', (data, { meta }, options) => {
644
- if (typeof data !== 'number') throw new ValidationError(`expected number but got ${data}`, options)
645
- checkWithinRange(data, meta, 'number', options)
646
- const { step } = meta
647
- if (step && !isMultipleOf(data, meta.min ?? 0, step)) {
648
- throw new ValidationError(`expected number multiple of ${step} but got ${data}`, options)
649
- }
650
- return [data]
651
- })
652
-
653
- Schema.extend('boolean', (data, _, options) => {
654
- if (typeof data === 'boolean') return [data]
655
- throw new ValidationError(`expected boolean but got ${data}`, options)
656
- })
657
-
658
- Schema.extend('bitset', (data, { bits, meta }, options) => {
659
- let value = 0, keys: string[] = []
660
- if (typeof data === 'number') {
661
- value = data
662
- for (const key in bits!) {
663
- if (data & bits![key]!) {
664
- keys.push(key)
665
- }
666
- }
667
- } else if (Array.isArray(data)) {
668
- keys = data
669
- for (const key of keys) {
670
- if (typeof key !== 'string') throw new ValidationError(`expected string but got ${key}`, options)
671
- if (key in bits!) value |= bits![key]!
672
- }
673
- } else {
674
- throw new ValidationError(`expected number or array but got ${data}`, options)
675
- }
676
- if (value === meta.default) return [value]
677
- return [value, keys]
678
- })
679
-
680
- Schema.extend('function', (data, _, options) => {
681
- if (typeof data === 'function') return [data]
682
- throw new ValidationError(`expected function but got ${data}`, options)
683
- })
684
-
685
- Schema.extend('is', (data, { constructor }, options) => {
686
- if (typeof constructor === 'function') {
687
- if (data instanceof constructor) return [data]
688
- throw new ValidationError(`expected ${constructor.name} but got ${data}`, options)
689
- } else {
690
- if (isNullable(data)) {
691
- throw new ValidationError(`expected ${constructor} but got ${data}`, options)
692
- }
693
- let prototype = Object.getPrototypeOf(data)
694
- while (prototype) {
695
- if (prototype.constructor?.name === constructor) return [data]
696
- prototype = Object.getPrototypeOf(prototype)
697
- }
698
- throw new ValidationError(`expected ${constructor} but got ${data}`, options)
699
- }
700
- })
701
-
702
- function property(data: any, key: keyof any, schema: Schema, options: Schemastery.Options) {
703
- try {
704
- const [value, adapted] = Schema.resolve(data[key], schema, {
705
- ...options,
706
- path: [...options.path || [], key],
707
- })
708
- if (adapted !== undefined) data[key] = adapted
709
- return value
710
- } catch (e) {
711
- if (!options?.autofix) throw e
712
- delete data[key]
713
- return schema.meta.default
714
- }
715
- }
716
-
717
- Schema.extend('array', (data, { inner, meta }, options) => {
718
- if (!Array.isArray(data)) throw new ValidationError(`expected array but got ${data}`, options)
719
- checkWithinRange(data.length, meta, 'array length', options, !isNullable(inner!.meta.default))
720
- return [data.map((_, index) => property(data, index, inner!, options))]
721
- })
722
-
723
- Schema.extend('dict', (data, { inner, sKey }, options, strict) => {
724
- if (!isPlainObject(data)) throw new ValidationError(`expected object but got ${data}`, options)
725
- const result: any = {}
726
- for (const key in data) {
727
- let rKey: string
728
- try {
729
- rKey = Schema.resolve(key, sKey!, options)[0]
730
- } catch (error) {
731
- if (strict) continue
732
- throw error
733
- }
734
- result[rKey] = property(data, key, inner!, options)
735
- data[rKey] = data[key]
736
- if (key !== rKey) delete data[key]
737
- }
738
- return [result]
739
- })
740
-
741
- Schema.extend('tuple', (data, { list }, options, strict) => {
742
- if (!Array.isArray(data)) throw new ValidationError(`expected array but got ${data}`, options)
743
- const result = list!.map((inner, index) => property(data, index, inner, options))
744
- if (strict) return [result]
745
- result.push(...data.slice(list!.length))
746
- return [result]
747
- })
748
-
749
- function merge(result: any, data: any) {
750
- for (const key in data) {
751
- if (key in result) continue
752
- result[key] = data[key]
753
- }
754
- }
755
-
756
- Schema.extend('object', (data, { dict }, options, strict) => {
757
- if (!isPlainObject(data)) throw new ValidationError(`expected object but got ${data}`, options)
758
- const result: any = {}
759
- for (const key in dict) {
760
- const value = property(data, key, dict![key]!, options)
761
- if (!isNullable(value) || key in data) {
762
- result[key] = value
763
- }
764
- }
765
- if (!strict) merge(result, data)
766
- return [result]
767
- })
768
-
769
- Schema.extend('union', (data, { list, toString }, options, strict) => {
770
- const messages: any[] = []
771
- for (const inner of list!) {
772
- try {
773
- return Schema.resolve(data, inner, options, strict)
774
- } catch (error) {
775
- messages.push(error)
776
- }
777
- }
778
- throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options)
779
- })
780
-
781
- Schema.extend('intersect', (data, { list, toString }, options, strict) => {
782
- if (!list!.length) return [data]
783
- let result
784
- for (const inner of list!) {
785
- const value: any = Schema.resolve(data, inner, options, true)[0]
786
- if (isNullable(value)) continue
787
- if (isNullable(result)) {
788
- result = value
789
- } else if (typeof result !== typeof value) {
790
- throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options)
791
- } else if (typeof value === 'object') {
792
- merge(result ??= {}, value)
793
- } else if (result !== value) {
794
- throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options)
795
- }
796
- }
797
- if (!strict && isPlainObject(data)) merge(result, data)
798
- return [result]
799
- })
800
-
801
- Schema.extend('transform', (data, { inner, callback, preserve }, options) => {
802
- const [result, adapted = data] = Schema.resolve(data, inner!, options, true)
803
- if (preserve) {
804
- return [callback!(result)]
805
- // } else if (isPlainObject(data)) {
806
- // const temp: any = {}
807
- // for (const key in result) {
808
- // if (!(key in data)) continue
809
- // temp[key] = data[key]
810
- // delete data[key]
811
- // }
812
- // Object.assign(data, callback!(temp))
813
- // return [callback!(result)]
814
- } else {
815
- return [callback!(result), callback!(adapted)]
816
- }
817
- })
818
-
819
- type Formatter = (schema: Schema, inline?: boolean) => string
820
- const formatters: Dict<Formatter> = {}
821
-
822
- function defineMethod(name: string, keys: (keyof Schema)[], format: Formatter) {
823
- formatters[name] = format
824
- Object.assign(Schema, {
825
- [name](...args: any[]) {
826
- const schema = new Schema({ type: name } as Schema)
827
- keys.forEach((key, index) => {
828
- switch (key) {
829
- case 'sKey': schema.sKey = args[index] ?? Schema.string(); break
830
- case 'inner': schema.inner = Schema.from(args[index]); break
831
- case 'list': schema.list = args[index].map(Schema.from); break
832
- case 'dict': schema.dict = valueMap(args[index], Schema.from); break
833
- case 'bits': {
834
- schema.bits = {}
835
- for (const key in args[index]) {
836
- if (typeof args[index][key] !== 'number') continue
837
- schema.bits[key] = args[index][key]
838
- }
839
- break
840
- }
841
- case 'callback': {
842
- const callback = schema.callback = args[index]
843
- ;callback['toJSON'] ||= () => callback.toString()
844
- break
845
- }
846
- case 'constructor': {
847
- const constructor = schema.constructor = args[index]
848
- if (typeof constructor === 'function') {
849
- ;constructor['toJSON'] ||= () => constructor['name']
850
- }
851
- break
852
- }
853
- default: schema[key] = args[index] as never
854
- }
855
- })
856
- if (name === 'object' || name === 'dict') {
857
- schema.meta.default = {}
858
- } else if (name === 'array' || name === 'tuple') {
859
- schema.meta.default = []
860
- } else if (name === 'bitset') {
861
- schema.meta.default = 0
862
- }
863
- return schema
864
- },
865
- })
866
- }
867
-
868
- defineMethod('is', ['constructor'], ({ constructor }) => {
869
- if (typeof constructor === 'function') {
870
- return constructor.name
871
- } else {
872
- return constructor!
873
- }
874
- })
875
-
876
- defineMethod('any', [], () => 'any')
877
- defineMethod('never', [], () => 'never')
878
- defineMethod('const', ['value'], ({ value }) => typeof value === 'string' ? JSON.stringify(value) : value)
879
- defineMethod('string', [], () => 'string')
880
- defineMethod('number', [], () => 'number')
881
- defineMethod('boolean', [], () => 'boolean')
882
- defineMethod('bitset', ['bits'], () => 'bitset')
883
- defineMethod('function', [], () => 'function')
884
- defineMethod('array', ['inner'], ({ inner }) => `${inner!.toString(true)}[]`)
885
- defineMethod('dict', ['inner', 'sKey'], ({ inner, sKey }) => `{ [key: ${sKey!.toString()}]: ${inner!.toString()} }`)
886
- defineMethod('tuple', ['list'], ({ list }) => `[${list!.map((inner) => inner.toString()).join(', ')}]`)
887
-
888
- defineMethod('object', ['dict'], ({ dict }) => {
889
- if (Object.keys(dict!).length === 0) return '{}'
890
- return `{ ${Object.entries(dict!).map(([key, inner]) => {
891
- return `${key}${inner!.meta.required ? '' : '?'}: ${inner!.toString()}`
892
- }).join(', ')} }`
893
- })
894
-
895
- defineMethod('union', ['list'], ({ list }, inline) => {
896
- const result = list!.map(({ toString: format }) => format()).join(' | ')
897
- return inline ? `(${result})` : result
898
- })
899
-
900
- defineMethod('intersect', ['list'], ({ list }) => {
901
- return `${list!.map((inner) => inner.toString(true)).join(' & ')}`
902
- })
903
-
904
- defineMethod('transform', ['inner', 'callback', 'preserve'], ({ inner }, isInner) => inner!.toString(isInner))
905
-
906
- export default Schema
1
+ import { Binary, clone, deepEqual, filterKeys, isNullable, isPlainObject, pick, valueMap, type Dict } from '@xrkseek/cosmokit'
2
+ import type { StandardSchemaV1 } from '@standard-schema/spec'
3
+
4
+ const kSchema = Symbol.for('schemastery')
5
+ const kValidationError = Symbol.for('ValidationError')
6
+
7
+ declare global {
8
+ namespace Schemastery {
9
+ /** Convert primitive constructors, constants, and existing schemas into a schema type. */
10
+ export type From<X> =
11
+ | X extends string | number | boolean ? Schema<X>
12
+ : X extends Schema ? X
13
+ : X extends typeof String ? Schema<string>
14
+ : X extends typeof Number ? Schema<number>
15
+ : X extends typeof Boolean ? Schema<boolean>
16
+ : X extends typeof Function ? Schema<Function, (...args: any[]) => any>
17
+ : X extends Constructor<infer S> ? Schema<S>
18
+ : never
19
+
20
+ type TypeS1<X> = X extends Schema<infer S, unknown> ? S : never
21
+ type Inverse<X> = X extends Schema<any, infer Y> ? (arg: Y) => void : never
22
+
23
+ /** Input type accepted by a schema-like value. */
24
+ export type TypeS<X> = TypeS1<From<X>>
25
+ /** Output type returned by a schema-like value after validation. */
26
+ export type TypeT<X> = ReturnType<From<X>>
27
+ /** Resolver callback used by custom schema types registered with `Schema.extend()`. */
28
+ export type Resolve = (data: any, schema: Schema, options: Options, strict?: boolean) => [any, any?]
29
+
30
+ /** Input type accepted by one schema in an intersection. */
31
+ export type IntersectS<X> = From<X> extends Schema<infer S, unknown> ? S : never
32
+ /** Output type returned by one schema in an intersection. */
33
+ export type IntersectT<X> = Inverse<From<X>> extends ((arg: infer T) => void) ? T : never
34
+
35
+ type TupleS<X extends readonly any[]> = X extends readonly [infer L, ...infer R] ? [TypeS<L>?, ...TupleS<R>] : any[]
36
+ type TupleT<X extends readonly any[]> = X extends readonly [infer L, ...infer R] ? [TypeT<L>?, ...TupleT<R>] : any[]
37
+ type ObjectS<X extends Dict> = { [K in keyof X]?: TypeS<X[K]> | null } & Dict
38
+ type ObjectT<X extends Dict> = { [K in keyof X]: TypeT<X[K]> } & Dict
39
+ type Constructor<T = any> = new (...args: any[]) => T
40
+
41
+ /** Static constructor and factory methods exposed by the default `Schema` export. */
42
+ export interface Static {
43
+ <T = any>(options: Partial<Schema<T>>): Schema<T>
44
+ new <T = any>(options: Partial<Schema<T>>): Schema<T>
45
+ prototype: Schema
46
+ /** Validate a value against a schema node and return `[output, adaptedInput?]`. */
47
+ resolve: Resolve
48
+ /** Infer a schema from a primitive value, constructor, or existing schema. */
49
+ from<X = any>(source?: X): From<X>
50
+ /** Register a resolver for a custom schema `type`. */
51
+ extend(type: string, resolve: Resolve): void
52
+ /** Accept any value without validation. */
53
+ any<T = any>(): Schema<T>
54
+ /** Accept only nullable input. */
55
+ never(): Schema<never>
56
+ /** Accept exactly one constant value. */
57
+ const<const T>(value: T): Schema<T>
58
+ /** Accept strings, with optional metadata constraints added by instance methods. */
59
+ string(): Schema<string>
60
+ /** Accept numbers, with optional range and step constraints. */
61
+ number(): Schema<number>
62
+ /** Accept non-negative integer numbers. */
63
+ natural(): Schema<number>
64
+ /** Accept a number between 0 and 1 and mark it as a slider. */
65
+ percent(): Schema<number>
66
+ /** Accept booleans. */
67
+ boolean(): Schema<boolean>
68
+ /** Accept `Date` instances or parse datetime strings into `Date` objects. */
69
+ date(): Schema<string | Date, Date>
70
+ /** Accept `RegExp` instances or parse strings into regular expressions. */
71
+ regExp(flag?: string): Schema<string | RegExp, RegExp>
72
+ /** Accept binary sources and normalize them to `ArrayBufferLike`. */
73
+ arrayBuffer(): Schema<Binary.Source, ArrayBufferLike>
74
+ arrayBuffer(encoding: 'hex' | 'base64'): Schema<Binary.Source | string, ArrayBufferLike>
75
+ /** Accept a numeric bitset or string keys and normalize to a number. */
76
+ bitset<K extends string>(bits: Partial<Record<K, number>>): Schema<number | readonly K[], number>
77
+ /** Accept functions. */
78
+ function(): Schema<Function, (...args: any[]) => any>
79
+ /** Accept instances of a constructor or objects whose constructor name matches. */
80
+ is(constructor: string): Schema
81
+ is<T>(constructor: Constructor<T>): Schema<T>
82
+ /** Accept arrays whose elements match `inner`. */
83
+ array<X>(inner: X): Schema<TypeS<X>[], TypeT<X>[]>
84
+ /** Accept plain objects with values matching `inner` and optional key schema. */
85
+ dict<X, Y extends Schema<any, string> = Schema<string>>(inner: X, sKey?: Y): Schema<Dict<TypeS<X>, TypeS<Y>>, Dict<TypeT<X>, TypeT<Y>>>
86
+ /** Accept tuple arrays where each index matches the corresponding schema. */
87
+ tuple<const X extends readonly any[]>(list: X): Schema<TupleS<X>, TupleT<X>>
88
+ /** Accept plain objects whose declared properties match the schema dictionary. */
89
+ object<X extends Dict>(dict: X): Schema<ObjectS<X>, ObjectT<X>>
90
+ /** Accept values matching at least one schema in `list`. */
91
+ union<const X>(list: readonly X[]): Schema<TypeS<X>, TypeT<X>>
92
+ /** Accept values matching every schema in `list`, merging object outputs. */
93
+ intersect<const X>(list: readonly X[]): Schema<IntersectS<X>, IntersectT<X>>
94
+ /** Validate with `inner`, then convert the result with `callback`. */
95
+ transform<X, T>(inner: X, callback: (value: TypeS<X>, options: Schemastery.Options) => T, preserve?: boolean): Schema<TypeS<X>, T>
96
+ /** Defer construction of a recursive schema until validation or serialization. */
97
+ lazy<X extends Schema>(callback: () => X): X
98
+ ValidationError: typeof ValidationError
99
+ }
100
+
101
+ /** Runtime validation options shared by all schema calls. */
102
+ interface Options {
103
+ /** Remove invalid object properties instead of throwing when possible. */
104
+ autofix?: boolean
105
+ /** Skip validation for selected values and schema nodes. */
106
+ ignore?(data: any, schema: Schema): boolean
107
+ /** Path used to format nested validation errors. */
108
+ path?: (keyof any)[]
109
+ }
110
+
111
+ /** UI and validation metadata attached by schema builder methods. */
112
+ export interface Meta<T = any> {
113
+ default?: T extends {} ? Partial<T> : T
114
+ required?: boolean
115
+ disabled?: boolean
116
+ collapse?: boolean
117
+ badges?: { text: string; type: string }[]
118
+ hidden?: boolean
119
+ loose?: boolean
120
+ /** Runtime-only; skip persist (DSH community packs e.g. OFM channel-pack). */
121
+ volatile?: boolean
122
+ role?: string
123
+ extra?: any
124
+ link?: string
125
+ description?: string | Dict<string>
126
+ comment?: string
127
+ pattern?: { source: string; flags?: string }
128
+ max?: number
129
+ min?: number
130
+ step?: number
131
+ }
132
+ }
133
+
134
+ /** Callable schema instance that validates input and returns normalized output. */
135
+ interface Schemastery<S = any, T = S> {
136
+ (data?: S | null, options?: Schemastery.Options): T
137
+ new (data?: S | null, options?: Schemastery.Options): T
138
+ [kSchema]: true
139
+ uid: number
140
+ meta: Schemastery.Meta<T>
141
+ type: string
142
+ sKey?: Schema
143
+ inner?: Schema
144
+ list?: Schema[]
145
+ dict?: Dict<Schema>
146
+ bits?: Dict<number>
147
+ callback?: Function
148
+ constructor?: string | Function
149
+ builder?: Function
150
+ value?: T
151
+ refs?: Dict<Schema>
152
+ preserve?: boolean
153
+ '~standard': StandardSchemaV1.Props // <S, T>
154
+ /** Format this schema as a compact TypeScript-like type string. */
155
+ toString(inline?: boolean): string
156
+ /** Serialize this schema, preserving shared and recursive references. */
157
+ toJSON(): Schema<S, T>
158
+ /** Mark nullable input as invalid unless a default supplies a fallback. */
159
+ required(value?: boolean): Schema<S, T>
160
+ /** Hide this schema node from UI renderers. */
161
+ hidden(value?: boolean): Schema<S, T>
162
+ /** Mark this node as runtime-only (not persisted). */
163
+ volatile(value?: boolean): Schema<S, T>
164
+ /** Return the default value instead of throwing when validation fails. */
165
+ loose(value?: boolean): Schema<S, T>
166
+ /** Attach a renderer role and optional role-specific metadata. */
167
+ role(text: string, extra?: any): Schema<S, T>
168
+ /** Attach an external documentation link. */
169
+ link(link: string): Schema<S, T>
170
+ /** Set the fallback value used for nullable input. */
171
+ default(value: T): Schema<S, T>
172
+ /** Attach an auxiliary comment for documentation or form UIs. */
173
+ comment(text: string): Schema<S, T>
174
+ /** Attach a localized or plain description for documentation or form UIs. */
175
+ description(text: string): Schema<S, T>
176
+ /** Mark this schema node as disabled for form UIs. */
177
+ disabled(value?: boolean): Schema<S, T>
178
+ /** Request collapsed rendering for nested form UIs. */
179
+ collapse(value?: boolean): Schema<S, T>
180
+ /** Add a deprecated badge to this schema node. */
181
+ deprecated(): Schema<S, T>
182
+ /** Add an experimental badge to this schema node. */
183
+ experimental(): Schema<S, T>
184
+ /** Require strings to match a regular expression. */
185
+ pattern(regexp: RegExp): Schema<S, T>
186
+ /** Set an inclusive maximum for numbers or collection lengths. */
187
+ max(value: number): Schema<S, T>
188
+ /** Set an inclusive minimum for numbers or collection lengths. */
189
+ min(value: number): Schema<S, T>
190
+ /** Set the numeric increment constraint. */
191
+ step(value: number): Schema<S, T>
192
+ /** Add or replace an object property schema. */
193
+ set(key: string, value: Schema): Schema<S, T>
194
+ /** Append a tuple, union, or intersection member schema. */
195
+ push(value: Schema): Schema<S, T>
196
+ /** Remove values equal to schema defaults from normalized output. */
197
+ simplify(value?: any): any
198
+ /** Return a schema clone with descriptions merged from locale messages. */
199
+ i18n(messages: Dict): Schema<S, T>
200
+ /** Attach arbitrary metadata consumed by form renderers and downstream tools. */
201
+ extra<K extends keyof Schemastery.Meta>(key: K, value: Schemastery.Meta[K]): Schema<S, T>
202
+ }
203
+ }
204
+
205
+ declare namespace globalThis {
206
+ // eslint-disable-next-line @typescript-eslint/naming-convention
207
+ export let __schemastery_index__: number
208
+ export let __schemastery_refs__: Record<number, Schema> | undefined
209
+ }
210
+
211
+ globalThis.__schemastery_index__ ??= 0
212
+ globalThis.__schemastery_refs__ = undefined
213
+
214
+ class ValidationError extends TypeError {
215
+ name = 'ValidationError'
216
+
217
+ constructor(message: string, public options: Schemastery.Options) {
218
+ let prefix = '$'
219
+ for (const segment of options.path || []) {
220
+ if (typeof segment === 'string') {
221
+ prefix += '.' + segment
222
+ } else if (typeof segment === 'number') {
223
+ prefix += '[' + segment + ']'
224
+ } else if (typeof segment === 'symbol') {
225
+ prefix += `[Symbol(${segment.toString()})]`
226
+ }
227
+ }
228
+ if (prefix.startsWith('.')) prefix = prefix.slice(1)
229
+ super((prefix === '$' ? '' : `${prefix} `) + message)
230
+ }
231
+
232
+ static is(error: any): error is ValidationError {
233
+ return !!error?.[kValidationError]
234
+ }
235
+ }
236
+
237
+ Object.defineProperty(ValidationError.prototype, kValidationError, {
238
+ value: true,
239
+ })
240
+
241
+ type Schema<S = any, T = S> = Schemastery<S, T>
242
+
243
+ const Schema = function (options: Schema) {
244
+ const schema = function (data: any, options: Schemastery.Options = {}) {
245
+ return Schema.resolve(data, schema, options)[0]
246
+ } as Schema
247
+
248
+ if (options.refs) {
249
+ const refs = valueMap(options.refs, options => new Schema(options))
250
+ const getRef = (uid: any) => refs[uid]!
251
+ for (const key in refs) {
252
+ const options = refs[key]!
253
+ options.sKey = getRef(options.sKey)
254
+ options.inner = getRef(options.inner)
255
+ options.list = options.list && options.list.map(getRef)
256
+ options.dict = options.dict && valueMap(options.dict, getRef)
257
+ }
258
+ return refs[options.uid!]
259
+ }
260
+
261
+ Object.assign(schema, options)
262
+ if (typeof schema.callback === 'string') {
263
+ try {
264
+ // eslint-disable-next-line no-new-func
265
+ schema.callback = new Function('return ' + schema.callback)()
266
+ } catch {}
267
+ }
268
+ Object.defineProperty(schema, 'uid', { value: globalThis.__schemastery_index__++ })
269
+ Object.setPrototypeOf(schema, Schema.prototype)
270
+ schema.meta ||= {}
271
+ schema.toString = schema.toString.bind(schema)
272
+ return schema
273
+ } as Schemastery.Static
274
+
275
+ Schema.prototype = Object.create(Function.prototype)
276
+
277
+ Schema.prototype[kSchema] = true
278
+
279
+ Object.defineProperty(Schema.prototype, '~standard', {
280
+ get(this: Schema) {
281
+ return {
282
+ version: 1,
283
+ vendor: 'schemastery',
284
+ validate: (value: unknown) => {
285
+ try {
286
+ return { value: Schema.resolve(value, this, {})[0] }
287
+ } catch (error) {
288
+ if (ValidationError.is(error)) {
289
+ return { issues: [{ message: error.message, path: error.options.path }] }
290
+ }
291
+ throw error
292
+ }
293
+ },
294
+ }
295
+ },
296
+ })
297
+
298
+ Schema.ValidationError = ValidationError
299
+
300
+ Schema.prototype.toJSON = function toJSON() {
301
+ if (globalThis.__schemastery_refs__) {
302
+ globalThis.__schemastery_refs__[this.uid] ??= JSON.parse(JSON.stringify({ ...this }))
303
+ return this.uid as any
304
+ }
305
+
306
+ globalThis.__schemastery_refs__ = { [this.uid]: { ...this } as Schema }
307
+ globalThis.__schemastery_refs__[this.uid] = JSON.parse(JSON.stringify({ ...this }))
308
+ const result = { uid: this.uid, refs: globalThis.__schemastery_refs__ }
309
+ globalThis.__schemastery_refs__ = undefined
310
+ return result
311
+ }
312
+
313
+ Schema.prototype.set = function set(key, value) {
314
+ this.dict![key] = value
315
+ return this
316
+ }
317
+
318
+ Schema.prototype.push = function push(value) {
319
+ this.list!.push(value)
320
+ return this
321
+ }
322
+
323
+ function mergeDesc(original: undefined | string | Dict<string>, messages: Dict) {
324
+ const result: Dict<string> = typeof original === 'string' ? { '': original } : { ...original }
325
+ for (const locale in messages) {
326
+ const value = messages[locale]
327
+ if (value?.$description || value?.$desc) {
328
+ result[locale] = value.$description || value.$desc
329
+ } else if (typeof value === 'string') {
330
+ result[locale] = value
331
+ }
332
+ }
333
+ return result
334
+ }
335
+
336
+ function getInner(value: any) {
337
+ return value?.$value ?? value?.$inner
338
+ }
339
+
340
+ function extractKeys(data: any) {
341
+ return filterKeys(data ?? {}, key => !key.startsWith('$'))
342
+ }
343
+
344
+ Schema.prototype.i18n = function i18n(messages) {
345
+ const schema = Schema(this)
346
+ const desc = mergeDesc(schema.meta.description, messages)
347
+ if (Object.keys(desc).length) schema.meta.description = desc
348
+ if (schema.dict) {
349
+ schema.dict = valueMap(schema.dict, (inner, key) => {
350
+ return inner.i18n(valueMap(messages, (data) => getInner(data)?.[key] ?? data?.[key]))
351
+ })
352
+ }
353
+ if (schema.list) {
354
+ schema.list = schema.list!.map((inner, index) => {
355
+ return inner.i18n(valueMap(messages, (data = {}) => {
356
+ if (Array.isArray(getInner(data))) return getInner(data)[index]
357
+ if (Array.isArray(data)) return data[index]
358
+ return extractKeys(data)
359
+ }))
360
+ })
361
+ }
362
+ if (schema.inner) {
363
+ schema.inner = schema.inner.i18n(valueMap(messages, (data) => {
364
+ if (getInner(data)) return getInner(data)
365
+ return extractKeys(data)
366
+ }))
367
+ }
368
+ if (schema.sKey) {
369
+ schema.sKey = schema.sKey.i18n(valueMap(messages, (data) => data?.$key))
370
+ }
371
+ return schema
372
+ }
373
+
374
+ Schema.prototype.extra = function extra(key, value) {
375
+ const schema = Schema(this)
376
+ schema.meta = { ...schema.meta, [key]: value }
377
+ return schema
378
+ }
379
+
380
+ for (const key of ['required', 'disabled', 'collapse', 'hidden', 'loose', 'volatile']) {
381
+ Object.assign(Schema.prototype, {
382
+ [key](this: Schema, value = true) {
383
+ const schema = Schema(this)
384
+ schema.meta = { ...schema.meta, [key]: value }
385
+ return schema
386
+ },
387
+ })
388
+ }
389
+
390
+ Schema.prototype.deprecated = function deprecated() {
391
+ const schema = Schema(this)
392
+ schema.meta.badges ||= []
393
+ schema.meta.badges.push({ text: 'deprecated', type: 'danger' })
394
+ return schema
395
+ }
396
+
397
+ Schema.prototype.experimental = function experimental() {
398
+ const schema = Schema(this)
399
+ schema.meta.badges ||= []
400
+ schema.meta.badges.push({ text: 'experimental', type: 'warning' })
401
+ return schema
402
+ }
403
+
404
+ Schema.prototype.pattern = function pattern(regexp) {
405
+ const schema = Schema(this)
406
+ const pattern = pick(regexp, ['source', 'flags'])
407
+ schema.meta = { ...schema.meta, pattern }
408
+ return schema
409
+ }
410
+
411
+ Schema.prototype.simplify = function simplify(this: Schema, value) {
412
+ if (deepEqual(value, this.meta.default, this.type === 'dict')) return null
413
+ if (isNullable(value)) return value
414
+ if (this.type === 'object' || this.type === 'dict') {
415
+ const result: Dict = {}
416
+ for (const key in value) {
417
+ const schema = this.type === 'object' ? this.dict![key] : this.inner
418
+ const item = schema?.simplify(value[key])
419
+ if (this.type === 'dict' || !isNullable(item)) result[key] = item
420
+ }
421
+ if (deepEqual(result, this.meta.default, this.type === 'dict')) return null
422
+ return result
423
+ } else if (this.type === 'array' || this.type === 'tuple') {
424
+ const result: any[] = []
425
+ ;(value as any[]).forEach((value, index) => {
426
+ const schema = this.type === 'array' ? this.inner : this.list![index]
427
+ const item = schema ? schema.simplify(value) : value
428
+ result.push(item)
429
+ })
430
+ return result
431
+ } else if (this.type === 'intersect') {
432
+ const result: Dict = {}
433
+ for (const item of this.list!) {
434
+ Object.assign(result, item.simplify(value))
435
+ }
436
+ return result
437
+ } else if (this.type === 'union') {
438
+ for (const schema of this.list!) {
439
+ try {
440
+ Schema.resolve(value, schema, {})
441
+ return schema.simplify(value)
442
+ } catch {}
443
+ }
444
+ }
445
+ return value
446
+ }
447
+
448
+ Schema.prototype.toString = function toString(inline?: boolean) {
449
+ return formatters[this.type]?.(this, inline) ?? `Schema<${this.type}>`
450
+ }
451
+
452
+ Schema.prototype.role = function role(role, extra) {
453
+ const schema = Schema(this)
454
+ schema.meta = { ...schema.meta, role, extra }
455
+ return schema
456
+ }
457
+
458
+ for (const key of ['default', 'link', 'comment', 'description', 'max', 'min', 'step']) {
459
+ Object.assign(Schema.prototype, {
460
+ [key](this: Schema, value: any) {
461
+ const schema = Schema(this)
462
+ schema.meta = { ...schema.meta, [key]: value }
463
+ return schema
464
+ },
465
+ })
466
+ }
467
+
468
+ const resolvers: Dict<Schemastery.Resolve> = {}
469
+
470
+ Schema.extend = function extend(type, resolve) {
471
+ resolvers[type] = resolve
472
+ }
473
+
474
+ Schema.resolve = function resolve(data, schema, options = {}, strict = false) {
475
+ if (!schema) return [data]
476
+ if (options.ignore?.(data, schema)) return [data]
477
+
478
+ if (isNullable(data) && schema.type !== 'lazy') {
479
+ if (schema.meta.required) throw new ValidationError(`missing required value`, options)
480
+ let current = schema
481
+ let fallback = schema.meta.default
482
+ while (current?.type === 'intersect' && isNullable(fallback)) {
483
+ current = current.list![0]
484
+ fallback = current?.meta.default
485
+ }
486
+ if (isNullable(fallback)) return [data]
487
+ data = clone(fallback)
488
+ }
489
+
490
+ const callback = resolvers[schema.type]
491
+ if (!callback) throw new ValidationError(`unsupported type "${schema.type}"`, options)
492
+
493
+ try {
494
+ return callback(data, schema, options, strict)
495
+ } catch (error) {
496
+ if (!schema.meta.loose) throw error
497
+ return [schema.meta.default]
498
+ }
499
+ }
500
+
501
+ Schema.from = function from(source: any) {
502
+ if (isNullable(source)) {
503
+ return Schema.any()
504
+ } else if (['string', 'number', 'boolean'].includes(typeof source)) {
505
+ return Schema.const(source).required()
506
+ } else if (source[kSchema]) {
507
+ return source
508
+ } else if (typeof source === 'function') {
509
+ switch (source) {
510
+ case String: return Schema.string().required()
511
+ case Number: return Schema.number().required()
512
+ case Boolean: return Schema.boolean().required()
513
+ case Function: return Schema.function().required()
514
+ default: return Schema.is(source).required()
515
+ }
516
+ } else {
517
+ throw new TypeError(`cannot infer schema from ${source}`)
518
+ }
519
+ }
520
+
521
+ Schema.lazy = function lazy(builder) {
522
+ const toJSON = () => {
523
+ if (!schema.inner![kSchema]) {
524
+ schema.inner = schema.builder!()
525
+ schema.inner!.meta = { ...schema.meta, ...schema.inner!.meta }
526
+ }
527
+ return schema.inner!.toJSON()
528
+ }
529
+ const schema = new Schema({ type: 'lazy', builder, inner: { toJSON } as any })
530
+ return schema as any
531
+ }
532
+
533
+ Schema.natural = function natural() {
534
+ return Schema.number().step(1).min(0)
535
+ }
536
+
537
+ Schema.percent = function percent() {
538
+ return Schema.number().step(0.01).min(0).max(1).role('slider')
539
+ }
540
+
541
+ Schema.date = function date() {
542
+ return Schema.union([
543
+ Schema.is(Date),
544
+ Schema.transform(Schema.string().role('datetime'), (value, options) => {
545
+ const date = new Date(value)
546
+ if (isNaN(+date)) throw new ValidationError(`invalid date "${value}"`, options)
547
+ return date
548
+ }, true),
549
+ ])
550
+ }
551
+
552
+ Schema.regExp = function regExp(flag = '') {
553
+ return Schema.union([
554
+ Schema.is(RegExp),
555
+ Schema.transform(Schema.string().role('regexp', { flag }), (value, options) => {
556
+ try {
557
+ return new RegExp(value, flag)
558
+ } catch (e: any) {
559
+ throw new ValidationError(e.message, options)
560
+ }
561
+ }, true),
562
+ ])
563
+ }
564
+
565
+ Schema.arrayBuffer = function arrayBuffer(encoding?: 'hex' | 'base64'): any {
566
+ return Schema.union([
567
+ Schema.is(ArrayBuffer),
568
+ Schema.is(SharedArrayBuffer),
569
+ Schema.transform(Schema.any<ArrayBufferView>(), (value, options) => {
570
+ if (Binary.isSource(value)) return Binary.fromSource(value)
571
+ throw new ValidationError(`expected ArrayBufferSource but got ${value}`, options)
572
+ }, true),
573
+ ...encoding ? [Schema.transform(Schema.string(), (value, options) => {
574
+ try {
575
+ return encoding === 'base64'
576
+ ? Binary.fromBase64(value)
577
+ : Binary.fromHex(value)
578
+ } catch (e: any) {
579
+ throw new ValidationError(e.message, options)
580
+ }
581
+ }, true)] as const : [],
582
+ ])
583
+ }
584
+
585
+ Schema.extend('lazy', (data, schema, options, strict) => {
586
+ if (!schema.inner![kSchema]) {
587
+ schema.inner = schema.builder!()
588
+ schema.inner!.meta = { ...schema.meta, ...schema.inner!.meta }
589
+ }
590
+ return Schema.resolve(data, schema.inner!, options, strict)
591
+ })
592
+
593
+ Schema.extend('any', (data) => {
594
+ return [data]
595
+ })
596
+
597
+ Schema.extend('never', (data, _, options) => {
598
+ throw new ValidationError(`expected nullable but got ${data}`, options)
599
+ })
600
+
601
+ Schema.extend('const', (data, { value }, options) => {
602
+ if (deepEqual(data, value)) return [value]
603
+ throw new ValidationError(`expected ${value} but got ${data}`, options)
604
+ })
605
+
606
+ function checkWithinRange(data: number, meta: Schemastery.Meta<any>, description: string, options: Schemastery.Options, skipMin = false) {
607
+ const { max = Infinity, min = -Infinity } = meta
608
+ if (data > max) throw new ValidationError(`expected ${description} <= ${max} but got ${data}`, options)
609
+ if (data < min && !skipMin) throw new ValidationError(`expected ${description} >= ${min} but got ${data}`, options)
610
+ }
611
+
612
+ Schema.extend('string', (data, { meta }, options) => {
613
+ if (typeof data !== 'string') throw new ValidationError(`expected string but got ${data}`, options)
614
+ if (meta.pattern) {
615
+ const regexp = new RegExp(meta.pattern.source, meta.pattern.flags)
616
+ if (!regexp.test(data)) throw new ValidationError(`expect string to match regexp ${regexp}`, options)
617
+ }
618
+ checkWithinRange(data.length, meta, 'string length', options)
619
+ return [data]
620
+ })
621
+
622
+ function decimalShift(data: number, digits: number) {
623
+ const str = data.toString()
624
+ if (str.includes('e')) return data * Math.pow(10, digits)
625
+ const index = str.indexOf('.')
626
+ if (index === -1) return data * Math.pow(10, digits)
627
+ const frac = str.slice(index + 1)
628
+ const integer = str.slice(0, index)
629
+ if (frac.length <= digits) return +(integer + frac.padEnd(digits, '0'))
630
+ return +(integer + frac.slice(0, digits) + '.' + frac.slice(digits))
631
+ }
632
+
633
+ function isMultipleOf(data: number, min: number, step: number) {
634
+ step = Math.abs(step)
635
+ if (!/^\d+\.\d+$/.test(step.toString())) {
636
+ return (data - min) % step === 0
637
+ }
638
+ const index = step.toString().indexOf('.')
639
+ const digits = step.toString().slice(index + 1).length
640
+ return Math.abs(decimalShift(data, digits) - decimalShift(min, digits)) % decimalShift(step, digits) === 0
641
+ }
642
+
643
+ Schema.extend('number', (data, { meta }, options) => {
644
+ if (typeof data !== 'number') throw new ValidationError(`expected number but got ${data}`, options)
645
+ checkWithinRange(data, meta, 'number', options)
646
+ const { step } = meta
647
+ if (step && !isMultipleOf(data, meta.min ?? 0, step)) {
648
+ throw new ValidationError(`expected number multiple of ${step} but got ${data}`, options)
649
+ }
650
+ return [data]
651
+ })
652
+
653
+ Schema.extend('boolean', (data, _, options) => {
654
+ if (typeof data === 'boolean') return [data]
655
+ throw new ValidationError(`expected boolean but got ${data}`, options)
656
+ })
657
+
658
+ Schema.extend('bitset', (data, { bits, meta }, options) => {
659
+ let value = 0, keys: string[] = []
660
+ if (typeof data === 'number') {
661
+ value = data
662
+ for (const key in bits!) {
663
+ if (data & bits![key]!) {
664
+ keys.push(key)
665
+ }
666
+ }
667
+ } else if (Array.isArray(data)) {
668
+ keys = data
669
+ for (const key of keys) {
670
+ if (typeof key !== 'string') throw new ValidationError(`expected string but got ${key}`, options)
671
+ if (key in bits!) value |= bits![key]!
672
+ }
673
+ } else {
674
+ throw new ValidationError(`expected number or array but got ${data}`, options)
675
+ }
676
+ if (value === meta.default) return [value]
677
+ return [value, keys]
678
+ })
679
+
680
+ Schema.extend('function', (data, _, options) => {
681
+ if (typeof data === 'function') return [data]
682
+ throw new ValidationError(`expected function but got ${data}`, options)
683
+ })
684
+
685
+ Schema.extend('is', (data, { constructor }, options) => {
686
+ if (typeof constructor === 'function') {
687
+ if (data instanceof constructor) return [data]
688
+ throw new ValidationError(`expected ${constructor.name} but got ${data}`, options)
689
+ } else {
690
+ if (isNullable(data)) {
691
+ throw new ValidationError(`expected ${constructor} but got ${data}`, options)
692
+ }
693
+ let prototype = Object.getPrototypeOf(data)
694
+ while (prototype) {
695
+ if (prototype.constructor?.name === constructor) return [data]
696
+ prototype = Object.getPrototypeOf(prototype)
697
+ }
698
+ throw new ValidationError(`expected ${constructor} but got ${data}`, options)
699
+ }
700
+ })
701
+
702
+ function property(data: any, key: keyof any, schema: Schema, options: Schemastery.Options) {
703
+ try {
704
+ const [value, adapted] = Schema.resolve(data[key], schema, {
705
+ ...options,
706
+ path: [...options.path || [], key],
707
+ })
708
+ if (adapted !== undefined) data[key] = adapted
709
+ return value
710
+ } catch (e) {
711
+ if (!options?.autofix) throw e
712
+ delete data[key]
713
+ return schema.meta.default
714
+ }
715
+ }
716
+
717
+ Schema.extend('array', (data, { inner, meta }, options) => {
718
+ if (!Array.isArray(data)) throw new ValidationError(`expected array but got ${data}`, options)
719
+ checkWithinRange(data.length, meta, 'array length', options, !isNullable(inner!.meta.default))
720
+ return [data.map((_, index) => property(data, index, inner!, options))]
721
+ })
722
+
723
+ Schema.extend('dict', (data, { inner, sKey }, options, strict) => {
724
+ if (!isPlainObject(data)) throw new ValidationError(`expected object but got ${data}`, options)
725
+ const result: any = {}
726
+ for (const key in data) {
727
+ let rKey: string
728
+ try {
729
+ rKey = Schema.resolve(key, sKey!, options)[0]
730
+ } catch (error) {
731
+ if (strict) continue
732
+ throw error
733
+ }
734
+ result[rKey] = property(data, key, inner!, options)
735
+ data[rKey] = data[key]
736
+ if (key !== rKey) delete data[key]
737
+ }
738
+ return [result]
739
+ })
740
+
741
+ Schema.extend('tuple', (data, { list }, options, strict) => {
742
+ if (!Array.isArray(data)) throw new ValidationError(`expected array but got ${data}`, options)
743
+ const result = list!.map((inner, index) => property(data, index, inner, options))
744
+ if (strict) return [result]
745
+ result.push(...data.slice(list!.length))
746
+ return [result]
747
+ })
748
+
749
+ function merge(result: any, data: any) {
750
+ for (const key in data) {
751
+ if (key in result) continue
752
+ result[key] = data[key]
753
+ }
754
+ }
755
+
756
+ Schema.extend('object', (data, { dict }, options, strict) => {
757
+ if (!isPlainObject(data)) throw new ValidationError(`expected object but got ${data}`, options)
758
+ const result: any = {}
759
+ for (const key in dict) {
760
+ const value = property(data, key, dict![key]!, options)
761
+ if (!isNullable(value) || key in data) {
762
+ result[key] = value
763
+ }
764
+ }
765
+ if (!strict) merge(result, data)
766
+ return [result]
767
+ })
768
+
769
+ Schema.extend('union', (data, { list, toString }, options, strict) => {
770
+ const messages: any[] = []
771
+ for (const inner of list!) {
772
+ try {
773
+ return Schema.resolve(data, inner, options, strict)
774
+ } catch (error) {
775
+ messages.push(error)
776
+ }
777
+ }
778
+ throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options)
779
+ })
780
+
781
+ Schema.extend('intersect', (data, { list, toString }, options, strict) => {
782
+ if (!list!.length) return [data]
783
+ let result
784
+ for (const inner of list!) {
785
+ const value: any = Schema.resolve(data, inner, options, true)[0]
786
+ if (isNullable(value)) continue
787
+ if (isNullable(result)) {
788
+ result = value
789
+ } else if (typeof result !== typeof value) {
790
+ throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options)
791
+ } else if (typeof value === 'object') {
792
+ merge(result ??= {}, value)
793
+ } else if (result !== value) {
794
+ throw new ValidationError(`expected ${toString()} but got ${JSON.stringify(data)}`, options)
795
+ }
796
+ }
797
+ if (!strict && isPlainObject(data)) merge(result, data)
798
+ return [result]
799
+ })
800
+
801
+ Schema.extend('transform', (data, { inner, callback, preserve }, options) => {
802
+ const [result, adapted = data] = Schema.resolve(data, inner!, options, true)
803
+ if (preserve) {
804
+ return [callback!(result)]
805
+ // } else if (isPlainObject(data)) {
806
+ // const temp: any = {}
807
+ // for (const key in result) {
808
+ // if (!(key in data)) continue
809
+ // temp[key] = data[key]
810
+ // delete data[key]
811
+ // }
812
+ // Object.assign(data, callback!(temp))
813
+ // return [callback!(result)]
814
+ } else {
815
+ return [callback!(result), callback!(adapted)]
816
+ }
817
+ })
818
+
819
+ type Formatter = (schema: Schema, inline?: boolean) => string
820
+ const formatters: Dict<Formatter> = {}
821
+
822
+ function defineMethod(name: string, keys: (keyof Schema)[], format: Formatter) {
823
+ formatters[name] = format
824
+ Object.assign(Schema, {
825
+ [name](...args: any[]) {
826
+ const schema = new Schema({ type: name } as Schema)
827
+ keys.forEach((key, index) => {
828
+ switch (key) {
829
+ case 'sKey': schema.sKey = args[index] ?? Schema.string(); break
830
+ case 'inner': schema.inner = Schema.from(args[index]); break
831
+ case 'list': schema.list = args[index].map(Schema.from); break
832
+ case 'dict': schema.dict = valueMap(args[index], Schema.from); break
833
+ case 'bits': {
834
+ schema.bits = {}
835
+ for (const key in args[index]) {
836
+ if (typeof args[index][key] !== 'number') continue
837
+ schema.bits[key] = args[index][key]
838
+ }
839
+ break
840
+ }
841
+ case 'callback': {
842
+ const callback = schema.callback = args[index]
843
+ ;callback['toJSON'] ||= () => callback.toString()
844
+ break
845
+ }
846
+ case 'constructor': {
847
+ const constructor = schema.constructor = args[index]
848
+ if (typeof constructor === 'function') {
849
+ ;constructor['toJSON'] ||= () => constructor['name']
850
+ }
851
+ break
852
+ }
853
+ default: schema[key] = args[index] as never
854
+ }
855
+ })
856
+ if (name === 'object' || name === 'dict') {
857
+ schema.meta.default = {}
858
+ } else if (name === 'array' || name === 'tuple') {
859
+ schema.meta.default = []
860
+ } else if (name === 'bitset') {
861
+ schema.meta.default = 0
862
+ }
863
+ return schema
864
+ },
865
+ })
866
+ }
867
+
868
+ defineMethod('is', ['constructor'], ({ constructor }) => {
869
+ if (typeof constructor === 'function') {
870
+ return constructor.name
871
+ } else {
872
+ return constructor!
873
+ }
874
+ })
875
+
876
+ defineMethod('any', [], () => 'any')
877
+ defineMethod('never', [], () => 'never')
878
+ defineMethod('const', ['value'], ({ value }) => typeof value === 'string' ? JSON.stringify(value) : value)
879
+ defineMethod('string', [], () => 'string')
880
+ defineMethod('number', [], () => 'number')
881
+ defineMethod('boolean', [], () => 'boolean')
882
+ defineMethod('bitset', ['bits'], () => 'bitset')
883
+ defineMethod('function', [], () => 'function')
884
+ defineMethod('array', ['inner'], ({ inner }) => `${inner!.toString(true)}[]`)
885
+ defineMethod('dict', ['inner', 'sKey'], ({ inner, sKey }) => `{ [key: ${sKey!.toString()}]: ${inner!.toString()} }`)
886
+ defineMethod('tuple', ['list'], ({ list }) => `[${list!.map((inner) => inner.toString()).join(', ')}]`)
887
+
888
+ defineMethod('object', ['dict'], ({ dict }) => {
889
+ if (Object.keys(dict!).length === 0) return '{}'
890
+ return `{ ${Object.entries(dict!).map(([key, inner]) => {
891
+ return `${key}${inner!.meta.required ? '' : '?'}: ${inner!.toString()}`
892
+ }).join(', ')} }`
893
+ })
894
+
895
+ defineMethod('union', ['list'], ({ list }, inline) => {
896
+ const result = list!.map(({ toString: format }) => format()).join(' | ')
897
+ return inline ? `(${result})` : result
898
+ })
899
+
900
+ defineMethod('intersect', ['list'], ({ list }) => {
901
+ return `${list!.map((inner) => inner.toString(true)).join(' & ')}`
902
+ })
903
+
904
+ defineMethod('transform', ['inner', 'callback', 'preserve'], ({ inner }, isInner) => inner!.toString(isInner))
905
+
906
+ export default Schema