pi-proactive 0.2.0-beta.2 → 0.2.0-beta.3

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 (243) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +32 -28
  3. package/build/cli.mjs +121 -0
  4. package/build/extensions/proactive.js +47 -6
  5. package/build/src/commands.js +78 -2
  6. package/build/src/config.js +511 -4
  7. package/build/src/daemon-config.js +221 -0
  8. package/build/src/daemon-contact.js +103 -0
  9. package/build/src/daemon-host.js +84 -0
  10. package/build/src/daemon.js +193 -3
  11. package/build/src/health.js +84 -0
  12. package/build/src/lineage.js +41 -2
  13. package/build/src/notify.js +183 -0
  14. package/build/src/progress-eta.js +134 -0
  15. package/build/src/trigger.js +43 -0
  16. package/build/src/trust-loop.js +321 -0
  17. package/build/src/trust-metrics.js +236 -0
  18. package/build/src/trust-notify.js +73 -0
  19. package/build/src/trust-policy.js +58 -0
  20. package/build/src/trust-registry.js +323 -0
  21. package/daemon/launchd.plist +48 -0
  22. package/daemon/pi-proactive-daemon.service +29 -0
  23. package/daemon/run-daemon.sh +84 -0
  24. package/node_modules/typebox/build/compile/code.mjs +2 -1
  25. package/node_modules/typebox/build/compile/validator.mjs +1 -5
  26. package/node_modules/typebox/build/format/date_time.d.mts +1 -2
  27. package/node_modules/typebox/build/format/date_time.mjs +3 -12
  28. package/node_modules/typebox/build/format/duration.d.mts +2 -2
  29. package/node_modules/typebox/build/format/duration.mjs +2 -2
  30. package/node_modules/typebox/build/format/idn_email.d.mts +0 -1
  31. package/node_modules/typebox/build/format/idn_email.mjs +0 -1
  32. package/node_modules/typebox/build/format/idn_hostname.d.mts +1 -1
  33. package/node_modules/typebox/build/format/idn_hostname.mjs +1 -1
  34. package/node_modules/typebox/build/format/ipv4.d.mts +2 -2
  35. package/node_modules/typebox/build/format/ipv4.mjs +2 -2
  36. package/node_modules/typebox/build/format/ipv6.d.mts +1 -1
  37. package/node_modules/typebox/build/format/ipv6.mjs +1 -1
  38. package/node_modules/typebox/build/format/iri.mjs +9 -16
  39. package/node_modules/typebox/build/format/relative_json_pointer.d.mts +2 -2
  40. package/node_modules/typebox/build/format/relative_json_pointer.mjs +2 -2
  41. package/node_modules/typebox/build/guard/emit.mjs +2 -2
  42. package/node_modules/typebox/build/guard/guard.d.mts +5 -7
  43. package/node_modules/typebox/build/guard/guard.mjs +9 -14
  44. package/node_modules/typebox/build/guard/index.mjs +0 -6
  45. package/node_modules/typebox/build/guard/{unicode/unicode_segment.mjs → string.mjs} +19 -16
  46. package/node_modules/typebox/build/schema/build.mjs +5 -5
  47. package/node_modules/typebox/build/schema/check.mjs +1 -1
  48. package/node_modules/typebox/build/schema/engine/_context.d.mts +1 -5
  49. package/node_modules/typebox/build/schema/engine/_context.mjs +3 -16
  50. package/node_modules/typebox/build/schema/engine/_functions.d.mts +2 -2
  51. package/node_modules/typebox/build/schema/engine/_functions.mjs +1 -1
  52. package/node_modules/typebox/build/schema/engine/_reducer.d.mts +3 -3
  53. package/node_modules/typebox/build/schema/engine/_refine.d.mts +5 -5
  54. package/node_modules/typebox/build/schema/engine/_refine.mjs +9 -14
  55. package/node_modules/typebox/build/schema/engine/_stack.d.mts +20 -34
  56. package/node_modules/typebox/build/schema/engine/_stack.mjs +202 -143
  57. package/node_modules/typebox/build/schema/engine/_unique.d.mts +2 -4
  58. package/node_modules/typebox/build/schema/engine/_unique.mjs +3 -7
  59. package/node_modules/typebox/build/schema/engine/additionalItems.d.mts +4 -4
  60. package/node_modules/typebox/build/schema/engine/additionalItems.mjs +3 -3
  61. package/node_modules/typebox/build/schema/engine/additionalProperties.d.mts +8 -5
  62. package/node_modules/typebox/build/schema/engine/additionalProperties.mjs +32 -27
  63. package/node_modules/typebox/build/schema/engine/allOf.d.mts +4 -4
  64. package/node_modules/typebox/build/schema/engine/allOf.mjs +1 -1
  65. package/node_modules/typebox/build/schema/engine/anyOf.d.mts +4 -4
  66. package/node_modules/typebox/build/schema/engine/anyOf.mjs +9 -4
  67. package/node_modules/typebox/build/schema/engine/boolean.d.mts +4 -4
  68. package/node_modules/typebox/build/schema/engine/boolean.mjs +6 -2
  69. package/node_modules/typebox/build/schema/engine/const.d.mts +4 -4
  70. package/node_modules/typebox/build/schema/engine/const.mjs +6 -2
  71. package/node_modules/typebox/build/schema/engine/contains.d.mts +4 -4
  72. package/node_modules/typebox/build/schema/engine/contains.mjs +9 -5
  73. package/node_modules/typebox/build/schema/engine/dependencies.d.mts +4 -4
  74. package/node_modules/typebox/build/schema/engine/dependencies.mjs +7 -5
  75. package/node_modules/typebox/build/schema/engine/dependentRequired.d.mts +4 -4
  76. package/node_modules/typebox/build/schema/engine/dependentRequired.mjs +6 -2
  77. package/node_modules/typebox/build/schema/engine/dependentSchemas.d.mts +4 -4
  78. package/node_modules/typebox/build/schema/engine/dependentSchemas.mjs +1 -2
  79. package/node_modules/typebox/build/schema/engine/dynamicRef.d.mts +4 -4
  80. package/node_modules/typebox/build/schema/engine/dynamicRef.mjs +8 -12
  81. package/node_modules/typebox/build/schema/engine/enum.d.mts +4 -4
  82. package/node_modules/typebox/build/schema/engine/enum.mjs +6 -2
  83. package/node_modules/typebox/build/schema/engine/exclusiveMaximum.d.mts +4 -4
  84. package/node_modules/typebox/build/schema/engine/exclusiveMaximum.mjs +6 -2
  85. package/node_modules/typebox/build/schema/engine/exclusiveMinimum.d.mts +4 -4
  86. package/node_modules/typebox/build/schema/engine/exclusiveMinimum.mjs +6 -2
  87. package/node_modules/typebox/build/schema/engine/format.d.mts +4 -4
  88. package/node_modules/typebox/build/schema/engine/format.mjs +8 -11
  89. package/node_modules/typebox/build/schema/engine/if.d.mts +4 -4
  90. package/node_modules/typebox/build/schema/engine/if.mjs +13 -5
  91. package/node_modules/typebox/build/schema/engine/index.d.mts +0 -1
  92. package/node_modules/typebox/build/schema/engine/index.mjs +0 -1
  93. package/node_modules/typebox/build/schema/engine/items.d.mts +4 -4
  94. package/node_modules/typebox/build/schema/engine/items.mjs +5 -8
  95. package/node_modules/typebox/build/schema/engine/maxContains.d.mts +4 -4
  96. package/node_modules/typebox/build/schema/engine/maxContains.mjs +8 -4
  97. package/node_modules/typebox/build/schema/engine/maxItems.d.mts +4 -4
  98. package/node_modules/typebox/build/schema/engine/maxItems.mjs +6 -2
  99. package/node_modules/typebox/build/schema/engine/maxLength.d.mts +4 -4
  100. package/node_modules/typebox/build/schema/engine/maxLength.mjs +6 -2
  101. package/node_modules/typebox/build/schema/engine/maxProperties.d.mts +4 -4
  102. package/node_modules/typebox/build/schema/engine/maxProperties.mjs +6 -2
  103. package/node_modules/typebox/build/schema/engine/maximum.d.mts +4 -4
  104. package/node_modules/typebox/build/schema/engine/maximum.mjs +6 -2
  105. package/node_modules/typebox/build/schema/engine/minContains.d.mts +4 -4
  106. package/node_modules/typebox/build/schema/engine/minContains.mjs +9 -5
  107. package/node_modules/typebox/build/schema/engine/minItems.d.mts +5 -5
  108. package/node_modules/typebox/build/schema/engine/minItems.mjs +6 -2
  109. package/node_modules/typebox/build/schema/engine/minLength.d.mts +4 -4
  110. package/node_modules/typebox/build/schema/engine/minLength.mjs +6 -2
  111. package/node_modules/typebox/build/schema/engine/minProperties.d.mts +4 -4
  112. package/node_modules/typebox/build/schema/engine/minProperties.mjs +6 -2
  113. package/node_modules/typebox/build/schema/engine/minimum.d.mts +4 -4
  114. package/node_modules/typebox/build/schema/engine/minimum.mjs +6 -2
  115. package/node_modules/typebox/build/schema/engine/multipleOf.d.mts +4 -4
  116. package/node_modules/typebox/build/schema/engine/multipleOf.mjs +6 -2
  117. package/node_modules/typebox/build/schema/engine/not.d.mts +4 -4
  118. package/node_modules/typebox/build/schema/engine/not.mjs +8 -4
  119. package/node_modules/typebox/build/schema/engine/oneOf.d.mts +4 -4
  120. package/node_modules/typebox/build/schema/engine/oneOf.mjs +11 -6
  121. package/node_modules/typebox/build/schema/engine/pattern.d.mts +4 -4
  122. package/node_modules/typebox/build/schema/engine/pattern.mjs +7 -3
  123. package/node_modules/typebox/build/schema/engine/patternProperties.d.mts +4 -4
  124. package/node_modules/typebox/build/schema/engine/patternProperties.mjs +5 -6
  125. package/node_modules/typebox/build/schema/engine/prefixItems.d.mts +4 -4
  126. package/node_modules/typebox/build/schema/engine/prefixItems.mjs +1 -1
  127. package/node_modules/typebox/build/schema/engine/properties.d.mts +4 -4
  128. package/node_modules/typebox/build/schema/engine/properties.mjs +3 -4
  129. package/node_modules/typebox/build/schema/engine/propertyNames.d.mts +4 -4
  130. package/node_modules/typebox/build/schema/engine/propertyNames.mjs +10 -7
  131. package/node_modules/typebox/build/schema/engine/recursiveRef.d.mts +4 -4
  132. package/node_modules/typebox/build/schema/engine/recursiveRef.mjs +8 -12
  133. package/node_modules/typebox/build/schema/engine/ref.d.mts +4 -4
  134. package/node_modules/typebox/build/schema/engine/ref.mjs +14 -18
  135. package/node_modules/typebox/build/schema/engine/required.d.mts +4 -4
  136. package/node_modules/typebox/build/schema/engine/required.mjs +6 -2
  137. package/node_modules/typebox/build/schema/engine/schema.d.mts +7 -7
  138. package/node_modules/typebox/build/schema/engine/schema.mjs +138 -136
  139. package/node_modules/typebox/build/schema/engine/type.d.mts +4 -4
  140. package/node_modules/typebox/build/schema/engine/type.mjs +6 -2
  141. package/node_modules/typebox/build/schema/engine/unevaluatedItems.d.mts +4 -4
  142. package/node_modules/typebox/build/schema/engine/unevaluatedItems.mjs +9 -5
  143. package/node_modules/typebox/build/schema/engine/unevaluatedProperties.d.mts +4 -4
  144. package/node_modules/typebox/build/schema/engine/unevaluatedProperties.mjs +9 -5
  145. package/node_modules/typebox/build/schema/engine/uniqueItems.d.mts +4 -4
  146. package/node_modules/typebox/build/schema/engine/uniqueItems.mjs +6 -2
  147. package/node_modules/typebox/build/schema/errors.mjs +1 -1
  148. package/node_modules/typebox/build/schema/intern/intern.d.mts +9 -6
  149. package/node_modules/typebox/build/schema/intern/intern.mjs +56 -90
  150. package/node_modules/typebox/build/schema/parse.mjs +0 -3
  151. package/node_modules/typebox/build/schema/pointer/pointer.d.mts +6 -1
  152. package/node_modules/typebox/build/schema/pointer/pointer.mjs +64 -47
  153. package/node_modules/typebox/build/schema/resolve/resolve.d.mts +32 -6
  154. package/node_modules/typebox/build/schema/resolve/resolve.mjs +227 -231
  155. package/node_modules/typebox/build/schema/schema.d.mts +0 -1
  156. package/node_modules/typebox/build/schema/schema.mjs +0 -1
  157. package/node_modules/typebox/build/system/hashing/hash.mjs +34 -63
  158. package/node_modules/typebox/build/system/locale/en_US.mjs +1 -2
  159. package/node_modules/typebox/build/system/memory/assign.d.mts +8 -2
  160. package/node_modules/typebox/build/system/memory/assign.mjs +6 -13
  161. package/node_modules/typebox/build/system/memory/clone.d.mts +5 -4
  162. package/node_modules/typebox/build/system/memory/clone.mjs +96 -8
  163. package/node_modules/typebox/build/system/memory/create.d.mts +5 -1
  164. package/node_modules/typebox/build/system/memory/create.mjs +13 -18
  165. package/node_modules/typebox/build/system/memory/discard.d.mts +1 -1
  166. package/node_modules/typebox/build/system/memory/discard.mjs +8 -9
  167. package/node_modules/typebox/build/system/memory/freeze.d.mts +4 -0
  168. package/node_modules/typebox/build/system/memory/freeze.mjs +6 -0
  169. package/node_modules/typebox/build/system/memory/update.d.mts +4 -1
  170. package/node_modules/typebox/build/system/memory/update.mjs +16 -43
  171. package/node_modules/typebox/build/system/settings/settings.d.mts +0 -11
  172. package/node_modules/typebox/build/system/settings/settings.mjs +0 -14
  173. package/node_modules/typebox/build/type/engine/evaluate/composite.d.mts +24 -2
  174. package/node_modules/typebox/build/type/engine/evaluate/composite.mjs +29 -2
  175. package/node_modules/typebox/build/type/engine/evaluate/index.d.mts +0 -1
  176. package/node_modules/typebox/build/type/engine/evaluate/index.mjs +0 -1
  177. package/node_modules/typebox/build/type/engine/evaluate/narrow.d.mts +1 -5
  178. package/node_modules/typebox/build/type/engine/evaluate/narrow.mjs +1 -6
  179. package/node_modules/typebox/build/type/engine/immutable/instantiate_add.d.mts +3 -1
  180. package/node_modules/typebox/build/type/engine/immutable/instantiate_add.mjs +4 -1
  181. package/node_modules/typebox/build/type/engine/object/from_intersect.d.mts +2 -2
  182. package/node_modules/typebox/build/type/engine/object/from_intersect.mjs +2 -2
  183. package/node_modules/typebox/build/type/engine/object/from_union.d.mts +2 -2
  184. package/node_modules/typebox/build/type/engine/object/from_union.mjs +2 -2
  185. package/node_modules/typebox/build/type/engine/optional/instantiate_add.d.mts +3 -1
  186. package/node_modules/typebox/build/type/engine/optional/instantiate_add.mjs +4 -1
  187. package/node_modules/typebox/build/type/engine/readonly/instantiate_add.d.mts +3 -1
  188. package/node_modules/typebox/build/type/engine/readonly/instantiate_add.mjs +4 -1
  189. package/node_modules/typebox/build/type/extends/inference.d.mts +1 -1
  190. package/node_modules/typebox/build/type/extends/inference.mjs +2 -15
  191. package/node_modules/typebox/build/type/extends/tuple.d.mts +1 -2
  192. package/node_modules/typebox/build/type/extends/tuple.mjs +1 -21
  193. package/node_modules/typebox/build/value/clean/from_object.mjs +1 -1
  194. package/node_modules/typebox/build/value/clone/clone.d.mts +3 -4
  195. package/node_modules/typebox/build/value/clone/clone.mjs +7 -5
  196. package/node_modules/typebox/build/value/parse/parse.mjs +4 -10
  197. package/node_modules/typebox/build/value/shared/union_priority_sort.mjs +14 -25
  198. package/node_modules/typebox/package.json +1 -1
  199. package/node_modules/typebox/readme.md +84 -52
  200. package/package.json +11 -3
  201. package/skills/pi-proactive/SKILL.md +27 -24
  202. package/tools/cli.mjs +121 -0
  203. package/tools/daemon-install.sh +397 -0
  204. package/tools/daemon-uninstall.sh +226 -0
  205. package/node_modules/typebox/build/guard/unicode/unicode.d.mts +0 -6
  206. package/node_modules/typebox/build/guard/unicode/unicode.mjs +0 -35
  207. package/node_modules/typebox/build/schema/engine/_pathing.d.mts +0 -1
  208. package/node_modules/typebox/build/schema/engine/_pathing.mjs +0 -11
  209. package/node_modules/typebox/build/schema/meta/draft_2019_09.d.mts +0 -2
  210. package/node_modules/typebox/build/schema/meta/draft_2019_09.mjs +0 -288
  211. package/node_modules/typebox/build/schema/meta/draft_2020_12.d.mts +0 -2
  212. package/node_modules/typebox/build/schema/meta/draft_2020_12.mjs +0 -300
  213. package/node_modules/typebox/build/schema/meta/draft_3.d.mts +0 -2
  214. package/node_modules/typebox/build/schema/meta/draft_3.mjs +0 -143
  215. package/node_modules/typebox/build/schema/meta/draft_4.d.mts +0 -2
  216. package/node_modules/typebox/build/schema/meta/draft_4.mjs +0 -149
  217. package/node_modules/typebox/build/schema/meta/draft_6.d.mts +0 -2
  218. package/node_modules/typebox/build/schema/meta/draft_6.mjs +0 -155
  219. package/node_modules/typebox/build/schema/meta/draft_7.d.mts +0 -2
  220. package/node_modules/typebox/build/schema/meta/draft_7.mjs +0 -172
  221. package/node_modules/typebox/build/schema/meta/index.d.mts +0 -2
  222. package/node_modules/typebox/build/schema/meta/index.mjs +0 -2
  223. package/node_modules/typebox/build/schema/meta/meta.d.mts +0 -9
  224. package/node_modules/typebox/build/schema/meta/meta.mjs +0 -15
  225. package/node_modules/typebox/build/schema/meta/schema.d.mts +0 -6
  226. package/node_modules/typebox/build/schema/meta/schema.mjs +0 -1
  227. package/node_modules/typebox/build/system/memory/deep.d.mts +0 -2
  228. package/node_modules/typebox/build/system/memory/deep.mjs +0 -108
  229. package/node_modules/typebox/build/system/memory/finalize.d.mts +0 -4
  230. package/node_modules/typebox/build/system/memory/finalize.mjs +0 -30
  231. package/node_modules/typebox/build/system/memory/keys.d.mts +0 -2
  232. package/node_modules/typebox/build/system/memory/keys.mjs +0 -8
  233. package/node_modules/typebox/build/system/settings/internal.d.mts +0 -2
  234. package/node_modules/typebox/build/system/settings/internal.mjs +0 -20
  235. package/node_modules/typebox/build/type/engine/call/index.d.mts +0 -1
  236. package/node_modules/typebox/build/type/engine/call/index.mjs +0 -1
  237. package/node_modules/typebox/build/type/engine/evaluate/property.d.mts +0 -30
  238. package/node_modules/typebox/build/type/engine/evaluate/property.mjs +0 -29
  239. package/node_modules/typebox/build/type/engine/this/index.d.mts +0 -1
  240. package/node_modules/typebox/build/type/engine/this/index.mjs +0 -1
  241. package/node_modules/typebox/build/value/repair/from_cyclic.d.mts +0 -2
  242. package/node_modules/typebox/build/value/repair/from_cyclic.mjs +0 -6
  243. /package/node_modules/typebox/build/guard/{unicode/unicode_segment.d.mts → string.d.mts} +0 -0
@@ -0,0 +1,48 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3
+ <!--
4
+ pi-proactive 常驻值班进程(macOS launchd LaunchAgent)。
5
+
6
+ **模板文件**:双下划线包裹的大写占位符由 `pi-proactive/tools/daemon-install.sh` 渲染
7
+ (节点路径 / 值班脚本路径 / agentDir / 稳定身份 / 日志目录)。
8
+
9
+ 为什么用 launchd 而不是 cron(任务卡 §2①):
10
+ - cron 的最小粒度是 1 分钟,且**没有崩溃自愈**;launchd 有 `KeepAlive`(进程退出即拉起)→ 崩溃重启是内建的;
11
+ - cron 不带环境变量语义(要绕 shell 脚本传身份);launchd 的 `EnvironmentVariables` 是结构化的;
12
+ - 日志由 `StandardOutPath` / `StandardErrorPath` 落盘 → 可被巡检读。
13
+
14
+ 成本硬约束:这里的 `PI_PROACTIVE_DAEMON_DRY_RUN=1` 与配置里的 `enabled=false`(默认)
15
+ 一起保证**装上不等于花钱**。
16
+ -->
17
+ <plist version="1.0">
18
+ <dict>
19
+ <key>Label</key>
20
+ <string>__LABEL__</string>
21
+ <key>ProgramArguments</key>
22
+ <array>
23
+ <string>/bin/bash</string>
24
+ <string>__RUNNER__</string>
25
+ </array>
26
+ <key>RunAtLoad</key>
27
+ <true/>
28
+ <key>KeepAlive</key>
29
+ <true/>
30
+ <key>ThrottleInterval</key>
31
+ <integer>10</integer>
32
+ <key>ProcessType</key>
33
+ <string>Background</string>
34
+ <key>WorkingDirectory</key>
35
+ <string>__PKG_ROOT__</string>
36
+ <key>EnvironmentVariables</key>
37
+ <dict>
38
+ <key>PI_PROACTIVE_AGENT_ID</key>
39
+ <string>__AGENT_ID__</string>
40
+ <key>PI_PROACTIVE_DAEMON_DRY_RUN</key>
41
+ <string>1</string>
42
+ </dict>
43
+ <key>StandardOutPath</key>
44
+ <string>__LOG_DIR__/daemon.out.log</string>
45
+ <key>StandardErrorPath</key>
46
+ <string>__LOG_DIR__/daemon.err.log</string>
47
+ </dict>
48
+ </plist>
@@ -0,0 +1,29 @@
1
+ # pi-proactive 常驻值班进程(Linux systemd --user 单元)
2
+ #
3
+ # **模板文件**:双下划线包裹的大写占位符由 `pi-proactive/tools/daemon-install.sh` 渲染
4
+ # (节点路径 / 值班脚本路径 / agentDir / 稳定身份)。
5
+ #
6
+ # 为什么用 systemd --user 而不是 cron(任务卡 §2①):
7
+ # - `Restart=always` → 崩溃自启是内建的(cron 没有);
8
+ # - `Environment=` → 稳定身份(`PI_PROACTIVE_AGENT_ID`)跨重启连续;
9
+ # - `KillSignal=SIGTERM` + `TimeoutStopSec` → 停止时给值班进程时间写交班摘要再退出。
10
+ #
11
+ # 成本硬约束:`PI_PROACTIVE_DAEMON_DRY_RUN=1` + 配置里的 `enabled=false`(默认)
12
+ # 一起保证**装上不等于花钱**。
13
+ [Unit]
14
+ Description=pi-proactive 常驻值班进程(7x24 数字员工)
15
+ After=default.target
16
+
17
+ [Service]
18
+ Type=simple
19
+ ExecStart=/bin/bash __RUNNER__
20
+ WorkingDirectory=__PKG_ROOT__
21
+ Environment=PI_PROACTIVE_AGENT_ID=__AGENT_ID__
22
+ Environment=PI_PROACTIVE_DAEMON_DRY_RUN=1
23
+ Restart=always
24
+ RestartSec=5
25
+ KillSignal=SIGTERM
26
+ TimeoutStopSec=20
27
+
28
+ [Install]
29
+ WantedBy=default.target
@@ -0,0 +1,84 @@
1
+ #!/usr/bin/env bash
2
+
3
+
4
+ # pi-proactive 常驻助理的**保活监督器**(supervisor)。
5
+ #
6
+ # 角色:**同时**充当两个宿主里的「保活容器」——
7
+ # ① herdr 宿主:助理跑在 herdr pane 里(纯 headless:无 TUI、不抢 stdin);
8
+ # ② 系统宿主:launchd / systemd --user 单元跑的就是这个脚本。
9
+ # 两者**跑的是同一个脚本** → 谁先拿到「值班锁」谁当值班进程,另一个转为待命。
10
+ #
11
+ # 为什么必须这样(形态选型 §2.5):
12
+ # - 「用 herdr 工具」≠「有常驻」:herdr server 挂了 / pane 被回收 → 助理就没了;
13
+ # - 所以:**任何一边的宿主没了,另一边立刻接管**(助理不会随宿主一起消失);
14
+ # - 这就是 §2.5 要求的「server 挂 → 助理可判定的降级」——降级目标 = 自带 daemon。
15
+ #
16
+ # 判定(**可判定**,不猜):
17
+ # - 心跳新鲜(< STALE_MS)→ 已有实例在值班 → **不重复拉起**(避免双开 → 避免重复打扰);
18
+ # - 心跳陈旧/缺失 → 抢 `daemon.lock`(mkdir 原子锁)→ 拿到锁的成为值班进程。
19
+ #
20
+ # 模板文件:双下划线包裹的大写占位符由 `pi-proactive/tools/daemon-install.sh` 渲染。
21
+ set -uo pipefail
22
+
23
+ NODE_BIN="__NODE__"
24
+ DAEMON_TS="__DAEMON_TS__"
25
+ AGENT_DIR="__AGENT_DIR__"
26
+ AGENT_ID="__AGENT_ID__"
27
+ LOG_DIR="__LOG_DIR__"
28
+
29
+ export PI_PROACTIVE_AGENT_ID="${AGENT_ID}"
30
+
31
+ DAEMON_DIR="${AGENT_DIR}/proactive/daemon"
32
+ HEARTBEAT_FILE="${DAEMON_DIR}/heartbeat.json"
33
+ LOCK_DIR="${DAEMON_DIR}/daemon.lock"
34
+ # 心跳周期 5s(src/daemon.ts 的 HEARTBEAT_INTERVAL_MS)→ 20s 还没更新即判定「没在跑」。
35
+ STALE_MS=20000
36
+
37
+ mkdir -p "${LOG_DIR}" 2>/dev/null || true
38
+
39
+ # 心跳是否新鲜(= 已经有实例在值班)。
40
+ heartbeat_fresh() {
41
+ [ -f "${HEARTBEAT_FILE}" ] || return 1
42
+ local ts now
43
+ ts="$("${NODE_BIN}" -e '
44
+ const fs=require("fs");
45
+ try{const j=JSON.parse(fs.readFileSync(process.argv[1],"utf8"));console.log(String(j.ts??""))}catch{console.log("")}' "${HEARTBEAT_FILE}" 2>/dev/null)"
46
+ [ -n "${ts}" ] || return 1
47
+ now="$(date +%s000)"
48
+ [ $(( now - ts )) -lt ${STALE_MS} ]
49
+ }
50
+
51
+ # 抢值班锁(mkdir 是原子的 → 两个监督器同时启动也只有一个能当值班进程)。
52
+ acquire_lock() {
53
+ if mkdir "${LOCK_DIR}" 2>/dev/null; then
54
+ printf '%s' "$$" >"${LOCK_DIR}/pid" 2>/dev/null || true
55
+ return 0
56
+ fi
57
+ # 锁可能是上次崩溃留下的 → 锁里的 pid 不在了就清掉重抢。
58
+ local owner=""
59
+ owner="$(cat "${LOCK_DIR}/pid" 2>/dev/null || true)"
60
+ if [ -n "${owner}" ] && kill -0 "${owner}" 2>/dev/null; then
61
+ return 1
62
+ fi
63
+ rm -rf "${LOCK_DIR}" 2>/dev/null || true
64
+ if mkdir "${LOCK_DIR}" 2>/dev/null; then
65
+ printf '%s' "$$" >"${LOCK_DIR}/pid" 2>/dev/null || true
66
+ return 0
67
+ fi
68
+ return 1
69
+ }
70
+
71
+ while true; do
72
+ if heartbeat_fresh; then
73
+ # 已有实例在值班(多半是另一个宿主里的那个)→ 待命,不重复拉起。
74
+ sleep 3
75
+ continue
76
+ fi
77
+ if acquire_lock; then
78
+ "${NODE_BIN}" --experimental-strip-types "${DAEMON_TS}" --agent-dir "${AGENT_DIR}" \
79
+ >>"${LOG_DIR}/daemon.out.log" 2>>"${LOG_DIR}/daemon.err.log"
80
+ # 值班进程退出 → 释放锁,稍后重试(崩溃自愈)。
81
+ rm -rf "${LOCK_DIR}" 2>/dev/null || true
82
+ fi
83
+ sleep 3
84
+ done
@@ -16,8 +16,9 @@ function Separator() {
16
16
  function ImportSection(build) {
17
17
  const context = build.UseUnevaluated() ? [`import { CheckContext } from "typebox/schema"`] : [];
18
18
  const hashing = `import { Hashing } from "typebox/system"`;
19
+ const format = `import { Format } from "typebox/format"`;
19
20
  const guard = `import { Guard } from "typebox/guard"`;
20
- return [...context, hashing, guard];
21
+ return [...context, hashing, format, guard];
21
22
  }
22
23
  // ------------------------------------------------------------------
23
24
  // ExternalSection
@@ -1,5 +1,4 @@
1
1
  // deno-fmt-ignore-file
2
- import { EnableParseErrors, DisableParseErrors } from '../system/settings/internal.mjs';
3
2
  import { Settings } from '../system/settings/index.mjs';
4
3
  import { Errors, Clean, Convert, Create, Default, Decode, Encode, HasCodec, Parser, ParseError } from '../value/index.mjs';
5
4
  import { Build } from '../schema/index.mjs';
@@ -52,10 +51,7 @@ export class Validator {
52
51
  return value;
53
52
  if (Settings.Get().correctiveParse)
54
53
  return Parser(this.Context(), this.Type(), value);
55
- EnableParseErrors();
56
- const errors = this.Errors(value);
57
- DisableParseErrors();
58
- throw new ParseError(value, errors);
54
+ throw new ParseError(value, this.Errors(value));
59
55
  }
60
56
  /** Returns an array of validation errors for the given value. */
61
57
  Errors(value) {
@@ -1,7 +1,6 @@
1
1
  /**
2
- * Returns true if the string is an [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339) date-time with optional [RFC 9557](https://datatracker.ietf.org/doc/html/rfc9557) suffix.
2
+ * Returns true if the value is a ISO8601 DateTime string
3
3
  * @specification https://datatracker.ietf.org/doc/html/rfc3339
4
- * @specification https://datatracker.ietf.org/doc/html/rfc9557
5
4
  * @example `2020-12-12T20:20:40+00:00`
6
5
  */
7
6
  export declare function IsDateTime(value: string): boolean;
@@ -1,20 +1,11 @@
1
1
  import { IsDate } from './date.mjs';
2
2
  import { IsTime } from './time.mjs';
3
- // ------------------------------------------------------------------
4
- // RFC 9557 DATE_TIME_SUFFIX
5
- // ------------------------------------------------------------------
6
- const DATE_TIME_SUFFIX = /^(?:\[!?(?:(?!\.{1,2}[/\]])[A-Za-z._][A-Za-z._0-9+-]{0,13}(?:\/(?!\.{1,2}[/\]])[A-Za-z._][A-Za-z._0-9+-]{0,13})*|[+-](?:[01][0-9]|2[0-3]):[0-5][0-9])\](?:\[!?[a-z_][a-z_0-9-]*=[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*\])*|(?:\[!?[a-z_][a-z_0-9-]*=[A-Za-z0-9]+(?:-[A-Za-z0-9]+)*\])*)$/;
7
3
  /**
8
- * Returns true if the string is an [RFC 3339](https://datatracker.ietf.org/doc/html/rfc3339) date-time with optional [RFC 9557](https://datatracker.ietf.org/doc/html/rfc9557) suffix.
4
+ * Returns true if the value is a ISO8601 DateTime string
9
5
  * @specification https://datatracker.ietf.org/doc/html/rfc3339
10
- * @specification https://datatracker.ietf.org/doc/html/rfc9557
11
6
  * @example `2020-12-12T20:20:40+00:00`
12
7
  */
13
8
  export function IsDateTime(value) {
14
- const index = value.indexOf('[');
15
- const datetime = index === -1 ? value : value.slice(0, index);
16
- if (index !== -1 && !DATE_TIME_SUFFIX.test(value.slice(index)))
17
- return false;
18
- const split = datetime.split(/T/i);
19
- return split.length === 2 && IsDate(split[0]) && IsTime(split[1]);
9
+ const dateTime = value.split(/T/i);
10
+ return dateTime.length === 2 && IsDate(dateTime[0]) && IsTime(dateTime[1]);
20
11
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Returns true if the value is a valid duration.
3
- * @specification https://www.rfc-editor.org/rfc/rfc3339.html#appendix-A
2
+ * Returns true if the value is a valid ISO-8601 duration.
3
+ * @specification https://tools.ietf.org/html/rfc3339
4
4
  */
5
5
  export declare function IsDuration(value: string): boolean;
@@ -1,7 +1,7 @@
1
1
  const Duration = /^P((\d+Y(\d+M(\d+D)?)?|\d+M(\d+D)?|\d+D)(T(\d+H(\d+M(\d+S)?)?|\d+M(\d+S)?|\d+S))?|T(\d+H(\d+M(\d+S)?)?|\d+M(\d+S)?|\d+S)|\d+W)$/;
2
2
  /**
3
- * Returns true if the value is a valid duration.
4
- * @specification https://www.rfc-editor.org/rfc/rfc3339.html#appendix-A
3
+ * Returns true if the value is a valid ISO-8601 duration.
4
+ * @specification https://tools.ietf.org/html/rfc3339
5
5
  */
6
6
  export function IsDuration(value) {
7
7
  return Duration.test(value);
@@ -1,6 +1,5 @@
1
1
  /**
2
2
  * Returns true if the value is an IdnEmail
3
3
  * @specification https://datatracker.ietf.org/doc/html/rfc4952
4
- * @specification https://datatracker.ietf.org/doc/html/rfc6531
5
4
  */
6
5
  export declare function IsIdnEmail(value: string): boolean;
@@ -2,7 +2,6 @@ const IdnEmail = /^(?:[A-Za-z0-9!#$%&'*+\/=?^_`{|}~\u{0080}-\u{10FFFF}-]+(?:\.[A
2
2
  /**
3
3
  * Returns true if the value is an IdnEmail
4
4
  * @specification https://datatracker.ietf.org/doc/html/rfc4952
5
- * @specification https://datatracker.ietf.org/doc/html/rfc6531
6
5
  */
7
6
  export function IsIdnEmail(value) {
8
7
  return IdnEmail.test(value.normalize('NFC'));
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Returns true if the value is a valid internationalized (IDN) hostname.
3
- * @specification https://datatracker.ietf.org/doc/html/rfc5890
3
+ * @specification https://tools.ietf.org/html/rfc3490
4
4
  * @specification https://tools.ietf.org/html/rfc5891
5
5
  * @specification https://tools.ietf.org/html/rfc5892
6
6
  * @specification https://tools.ietf.org/html/rfc5893
@@ -1,7 +1,7 @@
1
1
  import * as Idna from './idna/index.mjs';
2
2
  /**
3
3
  * Returns true if the value is a valid internationalized (IDN) hostname.
4
- * @specification https://datatracker.ietf.org/doc/html/rfc5890
4
+ * @specification https://tools.ietf.org/html/rfc3490
5
5
  * @specification https://tools.ietf.org/html/rfc5891
6
6
  * @specification https://tools.ietf.org/html/rfc5892
7
7
  * @specification https://tools.ietf.org/html/rfc5893
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Returns true if the value is an IPv4 address
3
- * @specification https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2
2
+ * Returns true if the value is a IPV4 address
3
+ * @specification http://tools.ietf.org/html/rfc2673#section-3.2
4
4
  */
5
5
  export declare function IsIPv4(value: string): boolean;
@@ -1,7 +1,7 @@
1
1
  const IPv4 = /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/;
2
2
  /**
3
- * Returns true if the value is an IPv4 address
4
- * @specification https://datatracker.ietf.org/doc/html/rfc3986#section-3.2.2
3
+ * Returns true if the value is a IPV4 address
4
+ * @specification http://tools.ietf.org/html/rfc2673#section-3.2
5
5
  */
6
6
  export function IsIPv4(value) {
7
7
  return IPv4.test(value);
@@ -1,5 +1,5 @@
1
1
  /**
2
2
  * Returns true if the value is an IPv6 address
3
- * @specification https://datatracker.ietf.org/doc/html/rfc4291#section-2.2
3
+ * @specification http://tools.ietf.org/html/rfc2373#section-2.2
4
4
  */
5
5
  export declare function IsIPv6(value: string): boolean;
@@ -1,7 +1,7 @@
1
1
  const IPv6 = /^(?:(?:(?:[0-9a-f]{1,4}:){6}|::(?:[0-9a-f]{1,4}:){5}|(?:[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){4}|(?:(?:[0-9a-f]{1,4}:)?[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){3}|(?:(?:[0-9a-f]{1,4}:){0,2}[0-9a-f]{1,4})?::(?:[0-9a-f]{1,4}:){2}|(?:(?:[0-9a-f]{1,4}:){0,3}[0-9a-f]{1,4})?::[0-9a-f]{1,4}:|(?:(?:[0-9a-f]{1,4}:){0,4}[0-9a-f]{1,4})?::)(?:[0-9a-f]{1,4}:[0-9a-f]{1,4}|(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d))|(?:(?:[0-9a-f]{1,4}:){0,5}[0-9a-f]{1,4})?::[0-9a-f]{1,4}|(?:(?:[0-9a-f]{1,4}:){0,6}[0-9a-f]{1,4})?::)$/i;
2
2
  /**
3
3
  * Returns true if the value is an IPv6 address
4
- * @specification https://datatracker.ietf.org/doc/html/rfc4291#section-2.2
4
+ * @specification http://tools.ietf.org/html/rfc2373#section-2.2
5
5
  */
6
6
  export function IsIPv6(value) {
7
7
  return IPv6.test(value);
@@ -1,10 +1,9 @@
1
1
  // deno-lint-ignore-file no-control-regex
2
+ const IpvFutureMatchMaxLength = 2048;
3
+ const IpvFutureMatch = /\[[vV][0-9a-fA-F]+\.[^\]]+\]/; // Guarded By IpvFutureMatchMaxLength
4
+ const InvalidIriChars = /[\x00-\x20<>\^`{|}\\]/;
5
+ const InvalidPercentEncoding = /%(?![0-9a-fA-F]{2})/;
2
6
  // ------------------------------------------------------------------
3
- //
4
- // Removed by the following PR
5
- //
6
- // https://github.com/json-schema-org/JSON-Schema-Test-Suite/pull/1176
7
- //
8
7
  // NarrowIpvFuture
9
8
  //
10
9
  // Substitutes an IPvFuture address with a standard IPv6 loopback
@@ -14,18 +13,12 @@
14
13
  // be expensive on large strings, this operation is strictly
15
14
  // limited to inputs under a defined length threshold.
16
15
  //
17
- // ------------------------------------------------------------------
18
- //
19
- // const IpvFutureMatchMaxLength = 2048
20
- // const IpvFutureMatch = /\[[vV][0-9a-fA-F]+\.[^\]]+\]/ // Guarded By IpvFutureMatchMaxLength
21
- //
22
- // function NarrowIpvFuture(value: string): string {
23
- // return value.length < IpvFutureMatchMaxLength ? value.replace(IpvFutureMatch, '[::1]') : value
24
- // }
16
+ // (review-optimization)
25
17
  //
26
18
  // ------------------------------------------------------------------
27
- const InvalidIriChars = /[\x00-\x20<>\^`{|}\\]/;
28
- const InvalidPercentEncoding = /%(?![0-9a-fA-F]{2})/;
19
+ function NarrowIpvFuture(value) {
20
+ return value.length < IpvFutureMatchMaxLength ? value.replace(IpvFutureMatch, '[::1]') : value;
21
+ }
29
22
  /**
30
23
  * Returns true if the value is a valid Internationalized Resource Identifier.
31
24
  * @specification https://datatracker.ietf.org/doc/html/rfc3987
@@ -38,5 +31,5 @@ export function IsIri(value) {
38
31
  if (InvalidPercentEncoding.test(value))
39
32
  return false;
40
33
  // 3. Delegate to the native URL parser, patching the IPvFuture edge case beforehand.
41
- return URL.canParse(value);
34
+ return URL.canParse(NarrowIpvFuture(value));
42
35
  }
@@ -1,6 +1,6 @@
1
1
  /**
2
- * Returns true if the value is a relative JSON Pointer
3
- * @specification https://datatracker.ietf.org/doc/html/draft-handrews-relative-json-pointer/
2
+ * Returns true if the value is a relative json pointer
3
+ * @specification https://datatracker.ietf.org/doc/html/rfc6901
4
4
  * @source https://github.com/ajv-validator/ajv-formats
5
5
  */
6
6
  export declare function IsRelativeJsonPointer(value: string): boolean;
@@ -1,7 +1,7 @@
1
1
  const RelativeJsonPointer = /^(?:0|[1-9][0-9]*)(?:#|(?:\/(?:[^~/]|~0|~1)*)*)$/;
2
2
  /**
3
- * Returns true if the value is a relative JSON Pointer
4
- * @specification https://datatracker.ietf.org/doc/html/draft-handrews-relative-json-pointer/
3
+ * Returns true if the value is a relative json pointer
4
+ * @specification https://datatracker.ietf.org/doc/html/rfc6901
5
5
  * @source https://github.com/ajv-validator/ajv-formats
6
6
  */
7
7
  export function IsRelativeJsonPointer(value) {
@@ -97,10 +97,10 @@ export function IsGreaterEqualThan(left, right) {
97
97
  // String
98
98
  // --------------------------------------------------------------------------
99
99
  export function IsMinLength(value, length) {
100
- return `(${value}.length >= ${(+length) << 1} || (${value}.length >= ${length} && Guard.CodePointCount(${value}) >= ${length}))`;
100
+ return `Guard.IsMinLength(${value}, ${length})`;
101
101
  }
102
102
  export function IsMaxLength(value, length) {
103
- return `(${value}.length <= ${length} || (${value}.length <= ${(+length) << 1} && Guard.CodePointCount(${value}) <= ${length}))`;
103
+ return `Guard.IsMaxLength(${value}, ${length})`;
104
104
  }
105
105
  // --------------------------------------------------------------------------
106
106
  // Array
@@ -33,14 +33,12 @@ export declare function IsMultipleOf(dividend: bigint | number, divisor: bigint
33
33
  /** Returns true if the value appears to be an instance of a class. */
34
34
  export declare function IsClassInstance(value: unknown): boolean;
35
35
  export declare function IsValueLike(value: unknown): value is bigint | boolean | null | number | string | undefined;
36
- /** Returns the total number of visual grapheme clusters in the string. */
36
+ /** Returns the number of grapheme clusters in the string */
37
37
  export declare function GraphemeCount(value: string): number;
38
- /** Returns the total number of Unicode code points in the string. */
39
- export declare function CodePointCount(value: string): number;
40
- /** Returns true if the string length in Unicode code points does not exceed maxLength */
41
- export declare function IsMaxLength(value: string, maxLength: number): boolean;
42
- /** Returns true if the string length in Unicode code points is at least minLength */
43
- export declare function IsMinLength(value: string, minLength: number): boolean;
38
+ /** Returns true if the string has at most the given number of graphemes */
39
+ export declare function IsMaxLength(value: string, length: number): boolean;
40
+ /** Returns true if the string has at least the given number of graphemes */
41
+ export declare function IsMinLength(value: string, length: number): boolean;
44
42
  /** Returns true if every element from offset satisfies the callback, short-circuiting on the first failure */
45
43
  export declare function Every<T>(value: T[], offset: number, callback: (value: T, index: number) => boolean): boolean;
46
44
  /** Returns true if every element from offset satisfies the callback, using exhaustive enumeration */
@@ -1,6 +1,5 @@
1
1
  // deno-fmt-ignore-file
2
- import * as UnicodeSegmentGuard from './unicode/unicode_segment.mjs';
3
- import * as UnicodeGuard from './unicode/unicode.mjs';
2
+ import * as String from './string.mjs';
4
3
  // --------------------------------------------------------------------------
5
4
  // Guards
6
5
  // --------------------------------------------------------------------------
@@ -124,21 +123,17 @@ export function IsValueLike(value) {
124
123
  // --------------------------------------------------------------------------
125
124
  // String
126
125
  // --------------------------------------------------------------------------
127
- /** Returns the total number of visual grapheme clusters in the string. */
126
+ /** Returns the number of grapheme clusters in the string */
128
127
  export function GraphemeCount(value) {
129
- return UnicodeSegmentGuard.GraphemeCount(value);
128
+ return String.GraphemeCount(value);
130
129
  }
131
- /** Returns the total number of Unicode code points in the string. */
132
- export function CodePointCount(value) {
133
- return UnicodeGuard.CodePointCount(value);
130
+ /** Returns true if the string has at most the given number of graphemes */
131
+ export function IsMaxLength(value, length) {
132
+ return String.IsMaxLength(value, length);
134
133
  }
135
- /** Returns true if the string length in Unicode code points does not exceed maxLength */
136
- export function IsMaxLength(value, maxLength) {
137
- return UnicodeGuard.IsMaxLength(value, maxLength);
138
- }
139
- /** Returns true if the string length in Unicode code points is at least minLength */
140
- export function IsMinLength(value, minLength) {
141
- return UnicodeGuard.IsMinLength(value, minLength);
134
+ /** Returns true if the string has at least the given number of graphemes */
135
+ export function IsMinLength(value, length) {
136
+ return String.IsMinLength(value, length);
142
137
  }
143
138
  // --------------------------------------------------------------------------
144
139
  // Array
@@ -1,12 +1,6 @@
1
- // ------------------------------------------------------------------
2
- // Guards
3
- // ------------------------------------------------------------------
4
1
  export * as EmitGuard from './emit.mjs';
5
2
  export * as GlobalsGuard from './globals.mjs';
6
3
  export * as NativeGuard from './native.mjs';
7
- // ------------------------------------------------------------------
8
- // Default
9
- // ------------------------------------------------------------------
10
4
  import * as Guard from './guard.mjs';
11
5
  export * as Guard from './guard.mjs';
12
6
  export default Guard;
@@ -91,12 +91,26 @@ function IsGraphemeCodePoint(value) {
91
91
  IsZeroWidthJoiner(value)));
92
92
  }
93
93
  // --------------------------------------------------------------------------
94
+ // GraphemeCount
95
+ // --------------------------------------------------------------------------
96
+ /** Returns the number of grapheme clusters in a string */
97
+ export function GraphemeCount(value) {
98
+ let count = 0;
99
+ let index = 0;
100
+ while (index < value.length) {
101
+ index = NextGraphemeClusterIndex(value, index);
102
+ count++;
103
+ }
104
+ return count;
105
+ }
106
+ // --------------------------------------------------------------------------
94
107
  // IsMinLengthSegmented
95
108
  // --------------------------------------------------------------------------
96
109
  /** Checks if a string has at least a minimum number of grapheme clusters */
97
110
  function IsMinLengthSegmented(value, minLength) {
98
111
  // if (minLength === 0) return true // 0-length (unreachable)
99
- let count = 0, index = 0;
112
+ let count = 0;
113
+ let index = 0;
100
114
  while (index < value.length) {
101
115
  index = NextGraphemeClusterIndex(value, index);
102
116
  if ((++count) >= minLength)
@@ -109,7 +123,8 @@ function IsMinLengthSegmented(value, minLength) {
109
123
  // --------------------------------------------------------------------------
110
124
  /** Checks if a string has at most a maximum number of grapheme clusters */
111
125
  function IsMaxLengthSegmented(value, maxLength) {
112
- let count = 0, index = 0;
126
+ let count = 0;
127
+ let index = 0;
113
128
  while (index < value.length) {
114
129
  index = NextGraphemeClusterIndex(value, index);
115
130
  if ((++count) > maxLength)
@@ -118,19 +133,7 @@ function IsMaxLengthSegmented(value, maxLength) {
118
133
  return true;
119
134
  }
120
135
  // --------------------------------------------------------------------------
121
- // GraphemeCount
122
- // --------------------------------------------------------------------------
123
- /** Returns the number of grapheme clusters in a string */
124
- export function GraphemeCount(value) {
125
- let count = 0, index = 0;
126
- while (index < value.length) {
127
- index = NextGraphemeClusterIndex(value, index);
128
- count++;
129
- }
130
- return count;
131
- }
132
- // --------------------------------------------------------------------------
133
- // IsMinLength
136
+ // IsMinLengthFast
134
137
  // --------------------------------------------------------------------------
135
138
  /** Fast check for minimum grapheme length, falls back to full check if needed */
136
139
  export function IsMinLength(value, minLength) {
@@ -148,7 +151,7 @@ export function IsMinLength(value, minLength) {
148
151
  }
149
152
  }
150
153
  // --------------------------------------------------------------------------
151
- // IsMaxLength
154
+ // IsMaxLengthFast
152
155
  // --------------------------------------------------------------------------
153
156
  /** Fast check for maximum grapheme length, falls back to full check if needed */
154
157
  export function IsMaxLength(value, maxLength) {
@@ -4,6 +4,7 @@ import { Arguments } from '../system/arguments/index.mjs';
4
4
  import { Environment } from '../system/environment/index.mjs';
5
5
  import { Hashing } from '../system/hashing/index.mjs';
6
6
  import { Guard } from '../guard/index.mjs';
7
+ import { Format } from '../format/index.mjs';
7
8
  import * as Engine from './engine/index.mjs';
8
9
  // ------------------------------------------------------------------
9
10
  // CreateCode
@@ -19,14 +20,14 @@ function CreateCode(build) {
19
20
  // CreateEvaluatedCheck
20
21
  // ------------------------------------------------------------------
21
22
  function CreateEvaluatedCheck(build, code) {
22
- const factory = Environment.Evaluate('CheckContext', 'Guard', 'Hashing', build.External().identifier, code);
23
- return factory(Engine.CheckContext, Guard, Hashing, build.External().variables);
23
+ const factory = Environment.Evaluate('CheckContext', 'Guard', 'Format', 'Hashing', build.External().identifier, code);
24
+ return factory(Engine.CheckContext, Guard, Format, Hashing, build.External().variables);
24
25
  }
25
26
  // ------------------------------------------------------------------
26
27
  // CreateDynamicCheck
27
28
  // ------------------------------------------------------------------
28
29
  function CreateDynamicCheck(build) {
29
- const stack = Engine.Stack(build.Context(), build.Schema());
30
+ const stack = new Engine.Stack(build.Context(), build.Schema());
30
31
  const context = new Engine.CheckContext();
31
32
  return (value) => Engine.CheckSchema(stack, context, build.Schema(), value);
32
33
  }
@@ -106,10 +107,9 @@ export function Build(...args) {
106
107
  2: (context, schema) => [context, schema],
107
108
  1: (schema) => [{}, schema]
108
109
  });
109
- Engine.ResetUnique();
110
110
  Engine.ResetExternal();
111
111
  Engine.ResetFunctions();
112
- const stack = Engine.Stack(context, schema);
112
+ const stack = new Engine.Stack(context, schema);
113
113
  const build = new Engine.BuildContext(Engine.HasUnevaluated(context, schema));
114
114
  const call = Engine.CreateFunction(stack, build, schema, 'value');
115
115
  const functions = Engine.GetFunctions();
@@ -8,7 +8,7 @@ export function Check(...args) {
8
8
  3: (context, schema, value) => [context, schema, value],
9
9
  2: (schema, value) => [{}, schema, value]
10
10
  });
11
- const stack = Engine.Stack(context, schema);
11
+ const stack = new Engine.Stack(context, schema);
12
12
  const checkContext = new Engine.CheckContext();
13
13
  return Engine.CheckSchema(stack, checkContext, schema, value);
14
14
  }
@@ -25,10 +25,6 @@ export declare class ErrorContext extends CheckContext {
25
25
  private readonly errors;
26
26
  constructor();
27
27
  AtCapacity(): boolean;
28
- AddError<Keyword extends TValidationError['keyword']>(keyword: Keyword, schemaPath: string, instancePath: string, params: Extract<TValidationError, {
29
- keyword: Keyword;
30
- }>['params']): false;
31
- AddErrors(error: TValidationError[]): false;
28
+ AddError(error: TValidationError): false;
32
29
  GetErrors(): TValidationError[];
33
- private AddErrorObject;
34
30
  }