@wowok/agent-mcp 3.3.9 → 3.4.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 (480) hide show
  1. package/README.md +8 -0
  2. package/dist/chain-semantics/composition-truth.d.ts +102 -0
  3. package/dist/chain-semantics/composition-truth.js +1 -0
  4. package/dist/chain-semantics/eval-order.js +1 -1
  5. package/dist/chain-semantics/field-capability.js +1 -1
  6. package/dist/chain-semantics/freeze-map.js +1 -1
  7. package/dist/chain-semantics/fund-flow.js +1 -1
  8. package/dist/chain-semantics/guard-verbs.js +1 -1
  9. package/dist/chain-semantics/index.d.ts +1 -0
  10. package/dist/chain-semantics/index.js +1 -1
  11. package/dist/chain-semantics/object-graph.js +1 -1
  12. package/dist/composition/audit.js +1 -1
  13. package/dist/composition/blueprint-view.d.ts +3 -3
  14. package/dist/composition/blueprint-view.js +1 -1
  15. package/dist/composition/compile.d.ts +26 -4
  16. package/dist/composition/compile.js +1 -1
  17. package/dist/composition/emit-phases.d.ts +206 -0
  18. package/dist/composition/emit-phases.js +1 -0
  19. package/dist/composition/generate.d.ts +40 -0
  20. package/dist/composition/generate.js +1 -0
  21. package/dist/composition/guard-fill.d.ts +44 -0
  22. package/dist/composition/guard-fill.js +1 -0
  23. package/dist/composition/inflight.d.ts +26 -2
  24. package/dist/composition/inflight.js +1 -1
  25. package/dist/composition/input-normalize.d.ts +15 -0
  26. package/dist/composition/input-normalize.js +1 -0
  27. package/dist/composition/materialize.d.ts +22 -13
  28. package/dist/composition/materialize.js +1 -1
  29. package/dist/composition/mode-gates.d.ts +35 -0
  30. package/dist/composition/mode-gates.js +1 -0
  31. package/dist/composition/param-disclosure.d.ts +61 -0
  32. package/dist/composition/param-disclosure.js +1 -0
  33. package/dist/composition/plan-retry-ledger.d.ts +21 -0
  34. package/dist/composition/plan-retry-ledger.js +1 -0
  35. package/dist/composition/plan.d.ts +17 -2
  36. package/dist/composition/plan.js +1 -1
  37. package/dist/composition/product-card.d.ts +94 -0
  38. package/dist/composition/product-card.js +1 -0
  39. package/dist/composition/supply-chain-emit.d.ts +46 -0
  40. package/dist/composition/supply-chain-emit.js +1 -0
  41. package/dist/config/config-audit.spec.js +1 -1
  42. package/dist/config/config-warnings.d.ts +2 -0
  43. package/dist/config/config-warnings.js +1 -0
  44. package/dist/config/exposure.d.ts +2 -2
  45. package/dist/config/judgment.d.ts +31 -5
  46. package/dist/config/judgment.js +1 -1
  47. package/dist/config/judgment.spec.js +1 -1
  48. package/dist/config/match-policy-file.d.ts +34 -0
  49. package/dist/config/match-policy-file.js +1 -0
  50. package/dist/config/match-policy-file.spec.d.ts +1 -0
  51. package/dist/config/match-policy-file.spec.js +1 -0
  52. package/dist/config/rule-engine.d.ts +5 -5
  53. package/dist/config/rule-engine.js +1 -1
  54. package/dist/config/runtime.d.ts +0 -1
  55. package/dist/config/runtime.js +1 -1
  56. package/dist/config/severity.d.ts +0 -2
  57. package/dist/config/severity.js +1 -1
  58. package/dist/config/store-policy.spec.js +1 -1
  59. package/dist/config/template-params.d.ts +42 -0
  60. package/dist/config/template-params.js +1 -0
  61. package/dist/config/template-params.spec.d.ts +1 -0
  62. package/dist/config/template-params.spec.js +1 -0
  63. package/dist/customer/account-events.js +1 -1
  64. package/dist/data/api/api.spec.js +1 -1
  65. package/dist/data/api/cli.js +1 -1
  66. package/dist/data/api/server.d.ts +1 -0
  67. package/dist/data/api/server.js +1 -1
  68. package/dist/data/projection/store.d.ts +3 -1
  69. package/dist/data/projection/store.js +1 -1
  70. package/dist/data/projection/types.d.ts +32 -0
  71. package/dist/data/sync/cdc.d.ts +1 -2
  72. package/dist/data/sync/cdc.js +1 -1
  73. package/dist/data/sync/cdc.spec.js +1 -1
  74. package/dist/data/sync/store.d.ts +5 -0
  75. package/dist/data/sync/store.js +1 -1
  76. package/dist/data/sync/types.d.ts +2 -0
  77. package/dist/evaluation/acceptance.d.ts +8 -0
  78. package/dist/evaluation/acceptance.js +1 -1
  79. package/dist/evaluation/builtins/demand-match.js +1 -1
  80. package/dist/evaluation/builtins/graph-service.spec.js +1 -1
  81. package/dist/evaluation/capability.d.ts +2 -0
  82. package/dist/evaluation/category-match-rules.d.ts +0 -1
  83. package/dist/evaluation/category-match-rules.js +1 -1
  84. package/dist/evaluation/composer.d.ts +25 -0
  85. package/dist/evaluation/composer.js +1 -1
  86. package/dist/evaluation/engine.js +1 -1
  87. package/dist/evaluation/extract.d.ts +7 -0
  88. package/dist/evaluation/extract.js +1 -1
  89. package/dist/evaluation/game-strategy.d.ts +0 -3
  90. package/dist/evaluation/game-strategy.js +1 -1
  91. package/dist/evaluation/guard-scan.js +1 -1
  92. package/dist/evaluation/match-operation.d.ts +9 -0
  93. package/dist/evaluation/match-operation.js +1 -1
  94. package/dist/evaluation/match-policy-resolver.d.ts +9 -0
  95. package/dist/evaluation/match-policy-resolver.js +1 -0
  96. package/dist/evaluation/match-policy.d.ts +3 -1
  97. package/dist/evaluation/match-policy.js +1 -1
  98. package/dist/evaluation/region.d.ts +0 -6
  99. package/dist/evaluation/region.js +1 -1
  100. package/dist/evaluation/standards.d.ts +2 -1
  101. package/dist/evaluation/standards.js +1 -1
  102. package/dist/evaluation/structured-lines.d.ts +8 -0
  103. package/dist/evaluation/structured-lines.js +1 -0
  104. package/dist/evaluation/types.d.ts +6 -0
  105. package/dist/experience/realtime-feedback.js +1 -1
  106. package/dist/extensions/capability-manifest.d.ts +1 -0
  107. package/dist/extensions/capability-manifest.js +1 -1
  108. package/dist/extensions/capability.d.ts +91 -0
  109. package/dist/extensions/capability.js +1 -0
  110. package/dist/extensions/industry-audit.spec.js +1 -1
  111. package/dist/extensions/industry-pack.d.ts +13 -0
  112. package/dist/extensions/industry-pack.js +1 -1
  113. package/dist/extensions/modes.js +1 -1
  114. package/dist/extensions/registry.d.ts +0 -2
  115. package/dist/extensions/registry.js +1 -1
  116. package/dist/goal/GoalEngine.js +1 -1
  117. package/dist/graph/onchain/analyze.js +1 -1
  118. package/dist/graph/onchain/expand.js +1 -1
  119. package/dist/graph/onchain/exposure.js +1 -1
  120. package/dist/graph/onchain/facts.js +1 -1
  121. package/dist/graph/onchain/order-status.d.ts +0 -1
  122. package/dist/graph/onchain/order-status.js +1 -1
  123. package/dist/harness/recover.js +1 -1
  124. package/dist/harness/verify.d.ts +0 -3
  125. package/dist/harness/verify.js +1 -1
  126. package/dist/index.js +1 -1
  127. package/dist/intent/types.d.ts +0 -1
  128. package/dist/intent/types.js +1 -1
  129. package/dist/keeper/detectors.js +1 -1
  130. package/dist/keeper/types.d.ts +0 -1
  131. package/dist/keeper/types.js +1 -1
  132. package/dist/knowledge/allocation-risk.d.ts +1 -0
  133. package/dist/knowledge/allocation-risk.js +1 -1
  134. package/dist/knowledge/allocation-templates.js +1 -1
  135. package/dist/knowledge/allocator-rail-verifier.d.ts +6 -1
  136. package/dist/knowledge/allocator-rail-verifier.js +1 -1
  137. package/dist/knowledge/arb-fund-facts.d.ts +1 -0
  138. package/dist/knowledge/arb-fund-facts.js +1 -1
  139. package/dist/knowledge/arbitration-ledger.js +1 -1
  140. package/dist/knowledge/arbitration-puzzle.js +1 -1
  141. package/dist/knowledge/arbitration-risk.d.ts +1 -0
  142. package/dist/knowledge/arbitration-risk.js +1 -1
  143. package/dist/knowledge/audit-rules.d.ts +2 -2
  144. package/dist/knowledge/audit-rules.js +1 -1
  145. package/dist/knowledge/baselines/judgment-baselines.json +21 -2
  146. package/dist/knowledge/baselines/rules/allocation.json +6 -6
  147. package/dist/knowledge/baselines/rules/arb.json +2 -2
  148. package/dist/knowledge/baselines/rules/guard.json +11 -11
  149. package/dist/knowledge/baselines/rules/oracle.json +120 -0
  150. package/dist/knowledge/baselines/rules/order.json +1 -1
  151. package/dist/knowledge/baselines/rules/plan.json +385 -18
  152. package/dist/knowledge/baselines/rules/progress.json +20 -2
  153. package/dist/knowledge/baselines/semantic-facts.js +1 -1
  154. package/dist/knowledge/builtin-templates.d.ts +25 -1
  155. package/dist/knowledge/builtin-templates.js +1 -1
  156. package/dist/knowledge/catalog-facts.d.ts +4 -0
  157. package/dist/knowledge/catalog-facts.js +1 -0
  158. package/dist/knowledge/commission-landing.js +1 -1
  159. package/dist/knowledge/component-schema.d.ts +64 -0
  160. package/dist/knowledge/component-schema.js +1 -0
  161. package/dist/knowledge/contact-templates.d.ts +0 -1
  162. package/dist/knowledge/contact-templates.js +1 -1
  163. package/dist/knowledge/dynamic-pricing.js +1 -1
  164. package/dist/knowledge/entity-recipient-guard.js +1 -1
  165. package/dist/knowledge/event-semantics.js +1 -1
  166. package/dist/knowledge/fee-param-bindings.d.ts +26 -0
  167. package/dist/knowledge/fee-param-bindings.js +1 -0
  168. package/dist/knowledge/fund-layer.d.ts +1 -0
  169. package/dist/knowledge/fund-layer.js +1 -1
  170. package/dist/knowledge/game-scenarios.js +1 -1
  171. package/dist/knowledge/getting-started.d.ts +2 -2
  172. package/dist/knowledge/getting-started.js +1 -1
  173. package/dist/knowledge/guard-anchor-reach.js +1 -1
  174. package/dist/knowledge/guard-binding-table.d.ts +52 -0
  175. package/dist/knowledge/guard-binding-table.js +1 -0
  176. package/dist/knowledge/guard-binding-verifier.d.ts +30 -0
  177. package/dist/knowledge/guard-binding-verifier.js +1 -0
  178. package/dist/knowledge/guard-bindings.js +1 -1
  179. package/dist/knowledge/guard-blueprint.d.ts +68 -0
  180. package/dist/knowledge/guard-blueprint.js +1 -0
  181. package/dist/knowledge/guard-design-patterns.d.ts +1 -1
  182. package/dist/knowledge/guard-design-patterns.js +1 -1
  183. package/dist/knowledge/guard-field-cognition.js +1 -1
  184. package/dist/knowledge/guard-host-context.d.ts +24 -0
  185. package/dist/knowledge/guard-host-context.js +1 -0
  186. package/dist/knowledge/guard-ledger.js +1 -1
  187. package/dist/knowledge/guard-lint.d.ts +1 -0
  188. package/dist/knowledge/guard-lint.js +1 -1
  189. package/dist/knowledge/guard-node-gates.d.ts +3 -0
  190. package/dist/knowledge/guard-node-gates.js +1 -1
  191. package/dist/knowledge/guard-puzzle.js +1 -1
  192. package/dist/knowledge/guard-render.js +1 -1
  193. package/dist/knowledge/guard-risk.js +1 -1
  194. package/dist/knowledge/guard-submission-prompt.d.ts +11 -0
  195. package/dist/knowledge/guard-submission-prompt.js +1 -1
  196. package/dist/knowledge/guard-templates.d.ts +1 -1
  197. package/dist/knowledge/guard-templates.js +1 -1
  198. package/dist/knowledge/guard-translation.js +1 -1
  199. package/dist/knowledge/index.d.ts +1 -1
  200. package/dist/knowledge/index.js +1 -1
  201. package/dist/knowledge/industry-generalizer.d.ts +6 -1
  202. package/dist/knowledge/industry-generalizer.js +1 -1
  203. package/dist/knowledge/industry-registry.js +1 -1
  204. package/dist/knowledge/industry-strategy.js +1 -1
  205. package/dist/knowledge/jsonrpc-enum.d.ts +52 -3
  206. package/dist/knowledge/jsonrpc-enum.js +1 -1
  207. package/dist/knowledge/knob-docs.d.ts +5 -0
  208. package/dist/knowledge/knob-docs.js +1 -0
  209. package/dist/knowledge/machine-templates.js +1 -1
  210. package/dist/knowledge/machine-topology.js +1 -1
  211. package/dist/knowledge/machine-translation.js +1 -1
  212. package/dist/knowledge/object-dependency.d.ts +31 -0
  213. package/dist/knowledge/object-dependency.js +1 -0
  214. package/dist/knowledge/onchain-constants.d.ts +4 -0
  215. package/dist/knowledge/onchain-constants.js +1 -1
  216. package/dist/knowledge/order-ledger.js +1 -1
  217. package/dist/knowledge/param-schema.d.ts +93 -0
  218. package/dist/knowledge/param-schema.js +1 -0
  219. package/dist/knowledge/param-tiers.d.ts +25 -0
  220. package/dist/knowledge/param-tiers.js +1 -0
  221. package/dist/knowledge/passport-ledger.d.ts +1 -1
  222. package/dist/knowledge/passport-ledger.js +1 -1
  223. package/dist/knowledge/path-oracle/coverage.d.ts +16 -0
  224. package/dist/knowledge/path-oracle/coverage.js +1 -0
  225. package/dist/knowledge/path-oracle/index.d.ts +5 -0
  226. package/dist/knowledge/path-oracle/index.js +1 -0
  227. package/dist/knowledge/path-oracle/products/food-delivery.d.ts +2 -0
  228. package/dist/knowledge/path-oracle/products/food-delivery.js +1 -0
  229. package/dist/knowledge/path-oracle/schema.d.ts +188 -0
  230. package/dist/knowledge/path-oracle/schema.js +1 -0
  231. package/dist/knowledge/pattern-resolutions.d.ts +108 -0
  232. package/dist/knowledge/pattern-resolutions.js +1 -0
  233. package/dist/knowledge/progress-ledger.js +1 -1
  234. package/dist/knowledge/progress-risk.js +1 -1
  235. package/dist/knowledge/projection.spec.js +1 -1
  236. package/dist/knowledge/protocol-facts.js +1 -1
  237. package/dist/knowledge/requirement-families.d.ts +13 -0
  238. package/dist/knowledge/requirement-families.js +1 -0
  239. package/dist/knowledge/reward-ledger.js +1 -1
  240. package/dist/knowledge/safety-rules.js +1 -1
  241. package/dist/knowledge/scenario-modes.d.ts +2 -0
  242. package/dist/knowledge/scenario-modes.js +1 -1
  243. package/dist/knowledge/scenario-topology.js +1 -1
  244. package/dist/knowledge/semantic-ir.d.ts +4 -0
  245. package/dist/knowledge/semantic-ir.js +1 -1
  246. package/dist/knowledge/service-allocation-semantics.js +1 -1
  247. package/dist/knowledge/service-ledger.d.ts +1 -1
  248. package/dist/knowledge/service-ledger.js +1 -1
  249. package/dist/knowledge/service-templates.js +1 -1
  250. package/dist/knowledge/sku-name-gate.d.ts +17 -0
  251. package/dist/knowledge/sku-name-gate.js +1 -0
  252. package/dist/knowledge/strategy-manuals.d.ts +1 -1
  253. package/dist/knowledge/strategy-manuals.js +1 -1
  254. package/dist/knowledge/supply-chain.d.ts +9 -0
  255. package/dist/knowledge/supply-chain.js +1 -1
  256. package/dist/knowledge/template-loader.d.ts +114 -6
  257. package/dist/knowledge/template-loader.js +1 -1
  258. package/dist/knowledge/template-nav.d.ts +9 -0
  259. package/dist/knowledge/template-nav.js +1 -0
  260. package/dist/knowledge/template-prose.d.ts +1 -1
  261. package/dist/knowledge/template-registry.js +1 -1
  262. package/dist/knowledge/template-scanner.d.ts +95 -0
  263. package/dist/knowledge/template-scanner.js +1 -1
  264. package/dist/knowledge/template-test-profiles.d.ts +17 -0
  265. package/dist/knowledge/template-test-profiles.js +1 -0
  266. package/dist/knowledge/template-validation.d.ts +1 -0
  267. package/dist/knowledge/template-validation.js +1 -1
  268. package/dist/knowledge/tools-reference.js +1 -1
  269. package/dist/knowledge/treasury-templates.js +1 -1
  270. package/dist/knowledge/workflow-guidance.d.ts +5 -0
  271. package/dist/knowledge/workflow-guidance.js +1 -1
  272. package/dist/monitor/MonitorLoop.js +1 -1
  273. package/dist/participation/radar-core.js +1 -1
  274. package/dist/participation/time-window.d.ts +37 -0
  275. package/dist/participation/time-window.js +1 -0
  276. package/dist/persona/address-format.d.ts +0 -1
  277. package/dist/persona/address-format.js +1 -1
  278. package/dist/persona/bridge.js +1 -1
  279. package/dist/persona/index.d.ts +0 -2
  280. package/dist/persona/index.js +1 -1
  281. package/dist/persona/model.js +1 -1
  282. package/dist/persona/persona-audit.spec.js +1 -1
  283. package/dist/persona/types.d.ts +6 -0
  284. package/dist/playbooks/service-build/business-puzzle.js +1 -1
  285. package/dist/playbooks/service-build/game-theory.d.ts +2 -2
  286. package/dist/playbooks/service-build/intent-analyzer.js +1 -1
  287. package/dist/playbooks/service-build/machine-panorama.d.ts +1 -0
  288. package/dist/playbooks/service-build/machine-panorama.js +1 -1
  289. package/dist/playbooks/service-build/merchant-guide.d.ts +52 -22
  290. package/dist/playbooks/service-build/merchant-guide.js +1 -1
  291. package/dist/playbooks/service-build/migration-planner.d.ts +2 -0
  292. package/dist/playbooks/service-build/migration-planner.js +1 -1
  293. package/dist/playbooks/service-build/mode-actions.js +1 -1
  294. package/dist/playbooks/service-build/object-panorama.d.ts +8 -0
  295. package/dist/playbooks/service-build/object-panorama.js +1 -1
  296. package/dist/playbooks/service-build/participation-radar.d.ts +1 -0
  297. package/dist/playbooks/service-build/participation-radar.js +1 -1
  298. package/dist/playbooks/service-build/relationship-profile.js +1 -1
  299. package/dist/playbooks/service-build/reverse-mapping.d.ts +6 -0
  300. package/dist/playbooks/service-build/reverse-mapping.js +1 -1
  301. package/dist/playbooks/service-build/service-panorama.d.ts +2 -0
  302. package/dist/playbooks/service-build/service-panorama.js +1 -1
  303. package/dist/playbooks/service-build/service-quote.js +1 -1
  304. package/dist/playbooks/service-build/service-quote.spec.js +1 -1
  305. package/dist/playbooks/service-build/workflow-design-assessment.d.ts +10 -1
  306. package/dist/playbooks/service-build/workflow-design-assessment.js +1 -1
  307. package/dist/relationship/registry.js +1 -1
  308. package/dist/review/index.js +1 -1
  309. package/dist/review/repository.js +1 -1
  310. package/dist/runtime/instance-registry.d.ts +7 -1
  311. package/dist/runtime/instance-registry.js +1 -1
  312. package/dist/safety/confirm-gate.js +1 -1
  313. package/dist/schema/benchmark-migration/index.d.ts +106 -0
  314. package/dist/schema/benchmark-migration/index.js +1 -1
  315. package/dist/schema/call/allocation.d.ts +15 -6
  316. package/dist/schema/call/allocation.js +1 -1
  317. package/dist/schema/call/arbitration.js +1 -1
  318. package/dist/schema/call/base.d.ts +264 -0
  319. package/dist/schema/call/base.js +1 -1
  320. package/dist/schema/call/bridge.d.ts +34 -6
  321. package/dist/schema/call/demand.d.ts +15 -6
  322. package/dist/schema/call/demand.js +1 -1
  323. package/dist/schema/call/error-codes.d.ts +1 -1
  324. package/dist/schema/call/error-codes.js +1 -1
  325. package/dist/schema/call/guard.d.ts +8 -8
  326. package/dist/schema/call/guard.js +1 -1
  327. package/dist/schema/call/handler.d.ts +3 -0
  328. package/dist/schema/call/handler.js +1 -1
  329. package/dist/schema/call/machine.d.ts +32 -8
  330. package/dist/schema/call/machine.js +1 -1
  331. package/dist/schema/call/order.d.ts +26 -8
  332. package/dist/schema/call/order.js +1 -1
  333. package/dist/schema/call/payment.d.ts +20 -8
  334. package/dist/schema/call/payment.js +1 -1
  335. package/dist/schema/call/permission-handler.js +1 -1
  336. package/dist/schema/call/permission.d.ts +330 -114
  337. package/dist/schema/call/permission.js +1 -1
  338. package/dist/schema/call/personal.d.ts +10 -4
  339. package/dist/schema/call/personal.js +1 -1
  340. package/dist/schema/call/progress.d.ts +16 -4
  341. package/dist/schema/call/reward.d.ts +10 -4
  342. package/dist/schema/call/reward.js +1 -1
  343. package/dist/schema/call/semantic.d.ts +1 -0
  344. package/dist/schema/call/semantic.js +1 -1
  345. package/dist/schema/call/service.d.ts +131 -43
  346. package/dist/schema/call/service.js +1 -1
  347. package/dist/schema/call/treasury.d.ts +15 -6
  348. package/dist/schema/call/treasury.js +1 -1
  349. package/dist/schema/common/index.js +1 -1
  350. package/dist/schema/config/index.d.ts +61 -0
  351. package/dist/schema/config/index.js +1 -1
  352. package/dist/schema/envelope-unify.d.ts +4 -0
  353. package/dist/schema/envelope-unify.js +1 -0
  354. package/dist/schema/evaluation/index.d.ts +224 -19
  355. package/dist/schema/evaluation/index.js +1 -1
  356. package/dist/schema/goal/index.d.ts +47 -0
  357. package/dist/schema/goal/planning.d.ts +116 -1
  358. package/dist/schema/goal/planning.js +1 -1
  359. package/dist/schema/industry-pack/index.d.ts +166 -6
  360. package/dist/schema/industry-pack/index.js +1 -1
  361. package/dist/schema/industry-pack/modes.d.ts +6 -6
  362. package/dist/schema/keeper/index.d.ts +26 -0
  363. package/dist/schema/local/index.d.ts +157 -0
  364. package/dist/schema/local/index.js +1 -1
  365. package/dist/schema/local/wip.d.ts +6 -0
  366. package/dist/schema/local/wip.js +1 -1
  367. package/dist/schema/messenger/index.d.ts +28 -0
  368. package/dist/schema/messenger/index.js +1 -1
  369. package/dist/schema/operations.d.ts +343 -84
  370. package/dist/schema/operations.js +1 -1
  371. package/dist/schema/persona/index.d.ts +2907 -640
  372. package/dist/schema/persona/index.js +1 -1
  373. package/dist/schema/query/bi.d.ts +251 -4
  374. package/dist/schema/query/bi.js +1 -1
  375. package/dist/schema/query/index.d.ts +271 -78
  376. package/dist/schema/query/index.js +1 -1
  377. package/dist/schema/schema-query/index.d.ts +1 -1
  378. package/dist/schema/schema-query/index.js +1 -1
  379. package/dist/schema/schema-version.js +1 -1
  380. package/dist/schema/utils/permission-machine-check.d.ts +2 -0
  381. package/dist/schema/utils/permission-machine-check.js +1 -1
  382. package/dist/schema/watch/index.d.ts +16 -0
  383. package/dist/schema/watch/index.js +1 -1
  384. package/dist/schema/workflow/index.d.ts +2 -2
  385. package/dist/schema/workflow/index.js +1 -1
  386. package/dist/schema-query-impl/index.d.ts +1 -1
  387. package/dist/schema-query-impl/index.js +1 -1
  388. package/dist/schemas/account_operation.output.json +98 -2
  389. package/dist/schemas/benchmark_migration_operation.output.json +341 -12
  390. package/dist/schemas/benchmark_migration_operation.schema.json +42 -3
  391. package/dist/schemas/bridge_operation.output.json +98 -2
  392. package/dist/schemas/bridge_operation.schema.json +5 -5
  393. package/dist/schemas/config_operation.output.json +352 -0
  394. package/dist/schemas/config_operation.schema.json +20 -2
  395. package/dist/schemas/evaluation_operation.output.json +586 -4
  396. package/dist/schemas/evaluation_operation.schema.json +194 -3
  397. package/dist/schemas/goal_operation.schema.json +183 -0
  398. package/dist/schemas/guard2file.schema.json +1 -1
  399. package/dist/schemas/index.json +1 -1
  400. package/dist/schemas/industry_pack_operation.output.json +771 -1
  401. package/dist/schemas/industry_pack_operation.schema.json +28 -4
  402. package/dist/schemas/keeper_operation.output.json +96 -2
  403. package/dist/schemas/local_cache_operation.output.json +98 -2
  404. package/dist/schemas/local_history_operation.output.json +98 -2
  405. package/dist/schemas/local_info_operation.output.json +98 -2
  406. package/dist/schemas/local_mark_operation.output.json +98 -2
  407. package/dist/schemas/machineNode2file.schema.json +1 -1
  408. package/dist/schemas/messenger_operation.output.json +107 -2
  409. package/dist/schemas/messenger_operation.schema.json +41 -34
  410. package/dist/schemas/monitor_events.output.json +96 -2
  411. package/dist/schemas/monitor_subscription.output.json +96 -2
  412. package/dist/schemas/onchain_events.output.json +108 -14
  413. package/dist/schemas/onchain_operations.output.json +326 -11
  414. package/dist/schemas/onchain_operations.schema.json +1343 -734
  415. package/dist/schemas/onchain_operations_allocation.schema.json +35 -19
  416. package/dist/schemas/onchain_operations_arbitration.schema.json +16 -8
  417. package/dist/schemas/onchain_operations_contact.schema.json +12 -4
  418. package/dist/schemas/onchain_operations_demand.schema.json +33 -17
  419. package/dist/schemas/onchain_operations_gen_passport.schema.json +12 -4
  420. package/dist/schemas/onchain_operations_gen_proof.schema.json +1 -1
  421. package/dist/schemas/onchain_operations_guard.schema.json +297 -111
  422. package/dist/schemas/onchain_operations_machine.schema.json +56 -39
  423. package/dist/schemas/onchain_operations_order.schema.json +67 -42
  424. package/dist/schemas/onchain_operations_payment.schema.json +27 -12
  425. package/dist/schemas/onchain_operations_permission.schema.json +363 -232
  426. package/dist/schemas/onchain_operations_personal.schema.json +43 -28
  427. package/dist/schemas/onchain_operations_progress.schema.json +49 -32
  428. package/dist/schemas/onchain_operations_proof.schema.json +12 -4
  429. package/dist/schemas/onchain_operations_repository.schema.json +17 -8
  430. package/dist/schemas/onchain_operations_reward.schema.json +36 -20
  431. package/dist/schemas/onchain_operations_service.schema.json +230 -130
  432. package/dist/schemas/onchain_operations_treasury.schema.json +36 -20
  433. package/dist/schemas/onchain_table_data.output.json +276 -19
  434. package/dist/schemas/onchain_table_data.schema.json +104 -64
  435. package/dist/schemas/persona_operation.output.json +7752 -0
  436. package/dist/schemas/persona_operation.schema.json +1232 -4
  437. package/dist/schemas/query_toolkit.output.json +1054 -146
  438. package/dist/schemas/query_toolkit.schema.json +144 -13
  439. package/dist/schemas/schema_query.schema.json +1 -1
  440. package/dist/schemas/watch_operation.output.json +86 -3
  441. package/dist/schemas/wip_file.output.json +8 -0
  442. package/dist/schemas/workflow_operation.schema.json +5 -4
  443. package/dist/schemas/wowok_buildin_info.schema.json +1 -1
  444. package/dist/task/playbook.js +1 -1
  445. package/dist/tools/handlers/benchmark-migration.d.ts +12 -3
  446. package/dist/tools/handlers/benchmark-migration.js +1 -1
  447. package/dist/tools/handlers/config.js +1 -1
  448. package/dist/tools/handlers/evaluation.js +1 -1
  449. package/dist/tools/handlers/evaluation.spec.js +1 -1
  450. package/dist/tools/handlers/industry-pack.js +1 -1
  451. package/dist/tools/handlers/messenger.js +1 -1
  452. package/dist/tools/handlers/onchain.d.ts +24 -0
  453. package/dist/tools/handlers/onchain.js +1 -1
  454. package/dist/tools/handlers/persona.js +1 -1
  455. package/dist/tools/handlers/query.d.ts +8 -0
  456. package/dist/tools/handlers/query.js +1 -1
  457. package/dist/tools/handlers/winner-derivation.d.ts +20 -0
  458. package/dist/tools/handlers/winner-derivation.js +1 -0
  459. package/dist/tools/handlers/wip-upload.js +1 -1
  460. package/dist/tools/index.d.ts +1 -0
  461. package/dist/tools/index.js +1 -1
  462. package/dist/tools/registry/business.js +1 -1
  463. package/dist/tools/registry/config.js +1 -1
  464. package/dist/tools/registry/evaluation.js +1 -1
  465. package/dist/tools/registry/identity.js +1 -1
  466. package/dist/tools/registry/onchain.js +1 -1
  467. package/dist/tools/registry/query.js +1 -1
  468. package/dist/tools/sanitize-output.js +1 -1
  469. package/dist/tools/sanitize-output.spec.js +1 -1
  470. package/dist/tools/transport-integrity.d.ts +7 -0
  471. package/dist/tools/transport-integrity.js +1 -0
  472. package/dist/tools/types.d.ts +1 -0
  473. package/dist/tools/upgrade-check.d.ts +22 -0
  474. package/dist/tools/upgrade-check.js +1 -1
  475. package/dist/tools/wrap.d.ts +6 -1
  476. package/dist/tools/wrap.js +1 -1
  477. package/package.json +7 -6
  478. package/dist/extensions/business-modules.d.ts +0 -54
  479. package/dist/extensions/business-modules.js +0 -1
  480. package/dist/schemas/guard-templates.json +0 -379
@@ -1,7 +1,5 @@
1
1
  export declare const SEVERITY_ORDER: readonly ["critical", "high", "medium", "low", "info"];
2
2
  export type Severity = (typeof SEVERITY_ORDER)[number];
3
- export declare function compareSeverity(a: Severity, b: Severity): number;
4
3
  export declare function severityRank(s: Severity): number;
5
4
  export declare function maxSeverity(list: ReadonlyArray<Severity>): Severity;
6
5
  export declare function normalizeSeverity(raw: string): Severity;
7
- export declare function isSeverity(raw: string): raw is Severity;
@@ -1 +1 @@
1
- export const SEVERITY_ORDER=['critical','high','medium','low','info'];const RANK={'critical':0x4,'high':0x3,'medium':0x2,'low':0x1,'info':0x0},LEGACY_ALIASES={'warning':'high','warn':'high'};export function compareSeverity(c,d){return RANK[c]-RANK[d];}export function severityRank(a){return RANK[a];}export function maxSeverity(a){let b='info';for(const c of a){if(RANK[c]>RANK[b])b=c;}return b;}export function normalizeSeverity(a){const b=a?.['toLowerCase']();if(SEVERITY_ORDER['includes'](b))return b;return LEGACY_ALIASES[b]??'info';}export function isSeverity(a){return SEVERITY_ORDER['includes'](a?.['toLowerCase']());}
1
+ export const SEVERITY_ORDER=['critical','high','medium','low','info'];const RANK={'critical':0x4,'high':0x3,'medium':0x2,'low':0x1,'info':0x0},LEGACY_ALIASES={'warning':'high','warn':'high'};export function severityRank(a){return RANK[a];}export function maxSeverity(a){let b='info';for(const c of a){if(RANK[c]>RANK[b])b=c;}return b;}export function normalizeSeverity(a){const b=a?.['toLowerCase']();if(SEVERITY_ORDER['includes'](b))return b;return LEGACY_ALIASES[b]??'info';}
@@ -1 +1 @@
1
- import{mkdtempSync,writeFileSync}from'fs';import{tmpdir}from'os';import{join}from'path';import{describe,expect,it,beforeEach}from'vitest';import{getStoreDualPayoutPolicy,setStoreDualPayoutPreauthorization,clearStoreDualPayoutPreauthorization,isDualPayoutPreauthorized}from'./store-policy.js';const ACC='0xABCdef1234567890abcdef1234567890abcdef12',ACC_LOWER=ACC['toLowerCase']();describe('store-policy\x20D-1\x20ledger',()=>{let a;beforeEach(()=>{a=mkdtempSync(join(tmpdir(),'wowok-store-policy-')),process['env']['WOWOK_CONFIG_DIR']=a;}),it('set\x20WITHOUT\x20confirm\x20throws\x20and\x20records\x20nothing',()=>{expect(()=>setStoreDualPayoutPreauthorization(ACC,{'confirm':![]}))['toThrow'](/confirm=true/),expect(()=>setStoreDualPayoutPreauthorization(ACC,{}))['toThrow'](/confirm=true/),expect(getStoreDualPayoutPolicy(ACC))['toBeUndefined']();}),it('set\x20with\x20confirm:true\x20persists\x20and\x20get\x20roundtrips\x20(case-insensitive\x20key)',()=>{const b=setStoreDualPayoutPreauthorization(ACC,{'confirm':!![],'note':'merchant\x20standing\x20netting','network':'mainnet'});expect(b['preauthorized'])['toBe'](!![]),expect(b['authorized_at'])['toBeTruthy'](),expect(b['note'])['toBe']('merchant\x20standing\x20netting'),expect(getStoreDualPayoutPolicy(ACC['toLowerCase']())?.['preauthorized'])['toBe'](!![]),expect(getStoreDualPayoutPolicy(ACC['toUpperCase']())?.['preauthorized'])['toBe'](!![]),expect(isDualPayoutPreauthorized(ACC))['toBe'](!![]);}),it('unconfigured\x20account\x20→\x20not\x20preauthorized\x20(safe\x20hard-block\x20default)',()=>{expect(getStoreDualPayoutPolicy(ACC))['toBeUndefined'](),expect(isDualPayoutPreauthorized(ACC))['toBe'](![]),expect(isDualPayoutPreauthorized(undefined))['toBe'](![]),expect(isDualPayoutPreauthorized(''))['toBe'](![]);}),it('clear\x20removes\x20an\x20existing\x20record\x20(true)\x20and\x20reports\x20false\x20when\x20absent',()=>{setStoreDualPayoutPreauthorization(ACC,{'confirm':!![]}),expect(clearStoreDualPayoutPreauthorization(ACC['toUpperCase']()))['toBe'](!![]),expect(getStoreDualPayoutPolicy(ACC))['toBeUndefined'](),expect(isDualPayoutPreauthorized(ACC))['toBe'](![]),expect(clearStoreDualPayoutPreauthorization(ACC))['toBe'](![]);}),it('corrupt\x20policy\x20file\x20→\x20fail-soft\x20to\x20not-preauthorized\x20(never\x20crashes\x20the\x20gate\x20read)',()=>{writeFileSync(join(a,'store-policies.json'),'{not\x20json\x20at\x20all','utf-8'),expect(getStoreDualPayoutPolicy(ACC))['toBeUndefined'](),expect(isDualPayoutPreauthorized(ACC))['toBe'](![]),setStoreDualPayoutPreauthorization(ACC,{'confirm':!![]}),expect(isDualPayoutPreauthorized(ACC))['toBe'](!![]);});});
1
+ import{mkdtempSync,writeFileSync}from'fs';import{tmpdir}from'os';import{join}from'path';import{describe,expect,it,beforeEach}from'vitest';import{getStoreDualPayoutPolicy,setStoreDualPayoutPreauthorization,clearStoreDualPayoutPreauthorization,isDualPayoutPreauthorized}from'./store-policy.js';const ACC='0xABCdef1234567890abcdef1234567890abcdef12';describe('store-policy\x20D-1\x20ledger',()=>{let a;beforeEach(()=>{a=mkdtempSync(join(tmpdir(),'wowok-store-policy-')),process['env']['WOWOK_CONFIG_DIR']=a;}),it('set\x20WITHOUT\x20confirm\x20throws\x20and\x20records\x20nothing',()=>{expect(()=>setStoreDualPayoutPreauthorization(ACC,{'confirm':![]}))['toThrow'](/confirm=true/),expect(()=>setStoreDualPayoutPreauthorization(ACC,{}))['toThrow'](/confirm=true/),expect(getStoreDualPayoutPolicy(ACC))['toBeUndefined']();}),it('set\x20with\x20confirm:true\x20persists\x20and\x20get\x20roundtrips\x20(case-insensitive\x20key)',()=>{const b=setStoreDualPayoutPreauthorization(ACC,{'confirm':!![],'note':'merchant\x20standing\x20netting','network':'mainnet'});expect(b['preauthorized'])['toBe'](!![]),expect(b['authorized_at'])['toBeTruthy'](),expect(b['note'])['toBe']('merchant\x20standing\x20netting'),expect(getStoreDualPayoutPolicy(ACC['toLowerCase']())?.['preauthorized'])['toBe'](!![]),expect(getStoreDualPayoutPolicy(ACC['toUpperCase']())?.['preauthorized'])['toBe'](!![]),expect(isDualPayoutPreauthorized(ACC))['toBe'](!![]);}),it('unconfigured\x20account\x20→\x20not\x20preauthorized\x20(safe\x20hard-block\x20default)',()=>{expect(getStoreDualPayoutPolicy(ACC))['toBeUndefined'](),expect(isDualPayoutPreauthorized(ACC))['toBe'](![]),expect(isDualPayoutPreauthorized(undefined))['toBe'](![]),expect(isDualPayoutPreauthorized(''))['toBe'](![]);}),it('clear\x20removes\x20an\x20existing\x20record\x20(true)\x20and\x20reports\x20false\x20when\x20absent',()=>{setStoreDualPayoutPreauthorization(ACC,{'confirm':!![]}),expect(clearStoreDualPayoutPreauthorization(ACC['toUpperCase']()))['toBe'](!![]),expect(getStoreDualPayoutPolicy(ACC))['toBeUndefined'](),expect(isDualPayoutPreauthorized(ACC))['toBe'](![]),expect(clearStoreDualPayoutPreauthorization(ACC))['toBe'](![]);}),it('corrupt\x20policy\x20file\x20→\x20fail-soft\x20to\x20not-preauthorized\x20(never\x20crashes\x20the\x20gate\x20read)',()=>{writeFileSync(join(a,'store-policies.json'),'{not\x20json\x20at\x20all','utf-8'),expect(getStoreDualPayoutPolicy(ACC))['toBeUndefined'](),expect(isDualPayoutPreauthorized(ACC))['toBe'](![]),setStoreDualPayoutPreauthorization(ACC,{'confirm':!![]}),expect(isDualPayoutPreauthorized(ACC))['toBe'](!![]);});});
@@ -0,0 +1,42 @@
1
+ import { z } from "zod";
2
+ declare const TemplateParamsFileSchema: z.ZodObject<{
3
+ version: z.ZodOptional<z.ZodNumber>;
4
+ comment: z.ZodOptional<z.ZodString>;
5
+ defaults: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>>;
6
+ templates: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>>>>;
7
+ }, z.core.$strict>;
8
+ export type TemplateParamsFileState = z.infer<typeof TemplateParamsFileSchema>;
9
+ export interface TemplateParamFileRead {
10
+ path: string;
11
+ exists: boolean;
12
+ error: string | null;
13
+ comment?: string;
14
+ defaults?: Record<string, number | string>;
15
+ templates?: Record<string, Record<string, number | string>>;
16
+ }
17
+ export declare function templateParamsFilePath(): string;
18
+ export declare function getTemplateParamFileState(): TemplateParamFileRead;
19
+ export declare function getTemplateParamFileLayer(templateId: string): Record<string, number | string>;
20
+ export declare function resetTemplateParamFileCache(): void;
21
+ export interface TemplateParamPatchChange {
22
+ path: string;
23
+ old: unknown;
24
+ new: unknown;
25
+ }
26
+ export interface TemplateParamPatchResult {
27
+ applied: true;
28
+ path: string;
29
+ backup_path: string | null;
30
+ changed: TemplateParamPatchChange[];
31
+ error: string | null;
32
+ }
33
+ export declare function patchTemplateParamFile(patch: unknown): TemplateParamPatchResult;
34
+ export interface TemplateParamClearResult {
35
+ cleared: boolean;
36
+ path: string;
37
+ scope: "file" | "defaults" | "template";
38
+ template_id?: string;
39
+ backup_path: string | null;
40
+ }
41
+ export declare function clearTemplateParamFile(template?: string): TemplateParamClearResult;
42
+ export {};
@@ -0,0 +1 @@
1
+ import*as a42a from'node:fs';import*as a42b from'node:path';import{z}from'zod';import{getWowMcpDir}from'@wowok/wowok';const FILE_NAME='template-params.json',ParamValueSchema=z['union']([z['number']()['finite']()['nonnegative'](),z['string']()['min'](0x1)]),TemplateParamsFileSchema=z['object']({'version':z['number']()['int']()['nonnegative']()['optional'](),'comment':z['string']()['optional'](),'defaults':z['record'](z['string'](),ParamValueSchema)['optional'](),'templates':z['record'](z['string'](),z['record'](z['string'](),ParamValueSchema))['optional']()})['strict']();export function templateParamsFilePath(){const a=process['env']['WOWOK_CONFIG_DIR']||getWowMcpDir();return a42b['join'](a,FILE_NAME);}let cache=null;function zodMessage(a){return a instanceof z['ZodError']?a['issues']['map'](b=>b['path']['join']('.')+':\x20'+b['message'])['join'](';\x20'):a instanceof Error?a['message']:String(a);}function readAndParse(a){let b;try{b=a42a['readFileSync'](a,'utf-8');}catch(c){return{'path':a,'exists':!![],'error':'unreadable:\x20'+(c instanceof Error?c['message']:String(c))};}try{const d=TemplateParamsFileSchema['parse'](JSON['parse'](b));return{'path':a,'exists':!![],'error':null,...d['comment']!==undefined?{'comment':d['comment']}:{},...d['defaults']!==undefined?{'defaults':d['defaults']}:{},...d['templates']!==undefined?{'templates':d['templates']}:{}};}catch(f){return{'path':a,'exists':!![],'error':zodMessage(f)};}}export function getTemplateParamFileState(){const a=templateParamsFilePath();try{const b=a42a['statSync'](a);if(cache&&cache['mtimeMs']===b['mtimeMs'])return cache['state'];const c=readAndParse(a);if(c['error']===null)cache={'mtimeMs':b['mtimeMs'],'state':c};return c;}catch{return{'path':a,'exists':![],'error':null};}}export function getTemplateParamFileLayer(a){const b=getTemplateParamFileState();if(b['error']!==null)return{};const c=b['templates']?.[a];return{...b['defaults']??{},...c??{}};}export function resetTemplateParamFileCache(){cache=null;}function isPlainObject(a){return typeof a==='object'&&a!==null&&!Array['isArray'](a);}function deepMergeValues(a,b){if(isPlainObject(a)&&isPlainObject(b)){const c={...a};for(const [d,e]of Object['entries'](b)){c[d]=d in a?deepMergeValues(a[d],e):e;}return c;}return b;}function collectLeafChanges(a,c,d,e){if(isPlainObject(c)){const f=isPlainObject(a)?a:{};for(const [g,h]of Object['entries'](c)){collectLeafChanges(f[g],h,d?d+'.'+g:g,e);}return;}JSON['stringify'](a)!==JSON['stringify'](c)&&e['push']({'path':d||'(root)','old':a===undefined?null:a,'new':c});}export function patchTemplateParamFile(a){const b=templateParamsFilePath(),c=a42b['join'](a42b['dirname'](b),'template-params.backup.json');if(!isPlainObject(a))throw new Error('\x27patch\x27\x20must\x20be\x20an\x20object\x20like\x20{\x22defaults\x22:\x20{…},\x20\x22templates\x22:\x20{\x22<tpl-id>\x22:\x20{…}}}');const d=Object['keys'](a)['filter'](m=>m!=='defaults'&&m!=='templates'&&m!=='comment');if(d['length']>0x0)throw new Error('patch\x20rejected:\x20unknown\x20key(s)\x20'+d['map'](m=>'\x27'+m+'\x27')['join'](',\x20')+'\x20—\x20allowed:\x20defaults,\x20templates,\x20comment');let f={},g=![];try{const m=a42a['readFileSync'](b,'utf-8');g=!![],f=TemplateParamsFileSchema['parse'](JSON['parse'](m));}catch(n){if(g)throw new Error('the\x20current\x20template-params.json\x20is\x20not\x20a\x20valid\x20template-params\x20document\x20('+zodMessage(n)+')\x20—\x20fix\x20or\x20remove\x20'+b+'\x20by\x20hand\x20first');f={};}const h={...f},i=[];for(const o of['defaults','templates']){const p=a[o];if(p===undefined)continue;if(!isPlainObject(p))throw new Error('patch.'+o+'\x20must\x20be\x20an\x20object\x20(param\x20→\x20value'+(o==='templates'?',\x20keyed\x20by\x20template\x20id':'')+')');const q=deepMergeValues(f[o]??{},p);try{h[o]=TemplateParamsFileSchema['shape'][o]['parse'](q);}catch(r){throw new Error('patch.'+o+'\x20rejected:\x20'+zodMessage(r));}collectLeafChanges(f[o]??{},p,o,i);}if(a['comment']!==undefined){if(typeof a['comment']!=='string')throw new Error('patch.comment\x20must\x20be\x20a\x20string');h['comment']=a['comment'];}if(i['length']===0x0)return{'applied':!![],'path':b,'backup_path':null,'changed':i,'error':null};const j={'version':0x1,...h};TemplateParamsFileSchema['parse'](j);const k=JSON['stringify'](j,null,0x2)+'\x0a';a42a['mkdirSync'](a42b['dirname'](b),{'recursive':!![]});if(g)a42a['copyFileSync'](b,c);const l=b+'.tmp';return a42a['writeFileSync'](l,k,'utf-8'),a42a['renameSync'](l,b),cache={'mtimeMs':a42a['statSync'](b)['mtimeMs'],'state':readAndParse(b)},{'applied':!![],'path':b,'backup_path':g?c:null,'changed':i,'error':cache['state']['error']};}export function clearTemplateParamFile(a){const b=templateParamsFilePath(),c=a42b['join'](a42b['dirname'](b),'template-params.backup.json');try{a42a['statSync'](b);}catch{return{'cleared':![],'path':b,'scope':'file','backup_path':null};}a42a['copyFileSync'](b,c);if(!a)return a42a['rmSync'](b),cache=null,{'cleared':!![],'path':b,'scope':'file','backup_path':c};let d;try{d=JSON['parse'](a42a['readFileSync'](b,'utf-8'));}catch(g){throw new Error('template-params.json\x20is\x20unreadable\x20('+zodMessage(g)+')\x20—\x20clear\x20the\x20WHOLE\x20file\x20(omit\x20\x27template\x27)\x20or\x20remove\x20'+b+'\x20by\x20hand');}if(a==='defaults')delete d['defaults'];else{const h=isPlainObject(d['templates'])?{...d['templates']}:{};if(!(a in h))return{'cleared':![],'path':b,'scope':'template','template_id':a,'backup_path':null};delete h[a],d['templates']=h;}const f=isPlainObject(d['defaults'])&&Object['keys'](d['defaults'])['length']>0x0||isPlainObject(d['templates'])&&Object['keys'](d['templates'])['length']>0x0;if(f){const i=JSON['stringify'](d,null,0x2)+'\x0a',j=b+'.tmp';a42a['writeFileSync'](j,i,'utf-8'),a42a['renameSync'](j,b);}else a42a['rmSync'](b);return cache=null,{'cleared':!![],'path':b,'scope':a==='defaults'?'defaults':'template','template_id':a==='defaults'?undefined:a,'backup_path':c};}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ import{mkdtempSync,rmSync,writeFileSync,existsSync}from'node:fs';import{tmpdir}from'node:os';import{join}from'node:path';import{afterEach,beforeEach,describe,expect,it}from'vitest';import{getTemplateParamFileLayer,getTemplateParamFileState,patchTemplateParamFile,clearTemplateParamFile,resetTemplateParamFileCache,templateParamsFilePath}from'./template-params.js';let dir;beforeEach(()=>{dir=mkdtempSync(join(tmpdir(),'tpl-params-')),process['env']['WOWOK_CONFIG_DIR']=dir,resetTemplateParamFileCache();}),afterEach(()=>{delete process['env']['WOWOK_CONFIG_DIR'],resetTemplateParamFileCache(),rmSync(dir,{'recursive':!![],'force':!![]});}),describe('template-params\x20config\x20layer',()=>{it('is\x20inert\x20when\x20no\x20file\x20exists\x20({}\x20layer,\x20shipped\x20defaults\x20in\x20force)',()=>{const a=getTemplateParamFileState();expect(a['exists'])['toBe'](![]),expect(a['error'])['toBeNull'](),expect(getTemplateParamFileLayer('travel/global-ota'))['toEqual']({});}),it('patches\x20defaults\x20+\x20per-template\x20sections;\x20the\x20template\x20section\x20wins\x20over\x20defaults',()=>{const a=patchTemplateParamFile({'defaults':{'review_window_days':0x7,'platform_commission_bps':0x0},'templates':{'travel/global-ota':{'review_window_days':0x3}}});expect(a['applied'])['toBe'](!![]),expect(a['error'])['toBeNull'](),expect(existsSync(templateParamsFilePath()))['toBe'](!![]),expect(getTemplateParamFileLayer('freelance/agent-task'))['toEqual']({'review_window_days':0x7,'platform_commission_bps':0x0}),expect(getTemplateParamFileLayer('travel/global-ota'))['toEqual']({'review_window_days':0x3,'platform_commission_bps':0x0});}),it('deep-merges\x20a\x20second\x20patch\x20into\x20the\x20current\x20file\x20and\x20records\x20leaf\x20changes',()=>{patchTemplateParamFile({'defaults':{'review_window_days':0x7}});const a=patchTemplateParamFile({'defaults':{'escrow_release_days':0x2}});expect(a['changed']['map'](b=>b['path']))['toContain']('defaults.escrow_release_days'),expect(getTemplateParamFileLayer('retail/vertical-handmade'))['toEqual']({'review_window_days':0x7,'escrow_release_days':0x2});}),it('rejects\x20an\x20illegal\x20value\x20BEFORE\x20any\x20disk\x20write\x20(string\x20or\x20finite\x20non-negative\x20number\x20only)',()=>{expect(()=>patchTemplateParamFile({'defaults':{'review_window_days':-0x1}}))['toThrow'](),expect(()=>patchTemplateParamFile({'defaults':{'review_window_days':!![]}}))['toThrow'](),expect(existsSync(templateParamsFilePath()))['toBe'](![]);}),it('never\x20patches\x20over\x20an\x20existing\x20invalid\x20file\x20—\x20the\x20human\x20fixes\x20it\x20by\x20hand',()=>{writeFileSync(templateParamsFilePath(),'{\x20not\x20json','utf-8'),expect(()=>patchTemplateParamFile({'defaults':{'review_window_days':0x7}}))['toThrow'](/not a valid template-params document/);}),it('clears\x20one\x20template\x20section,\x20keeps\x20the\x20rest;\x20clears\x20the\x20whole\x20file\x20without\x20an\x20id',()=>{patchTemplateParamFile({'defaults':{'review_window_days':0x7},'templates':{'travel/global-ota':{'escrow_release_days':0x3},'retail/vertical-handmade':{}}});const a=clearTemplateParamFile('travel/global-ota');expect(a['cleared'])['toBe'](!![]),expect(a['scope'])['toBe']('template'),expect(getTemplateParamFileLayer('travel/global-ota'))['toEqual']({'review_window_days':0x7});const b=clearTemplateParamFile();expect(b['cleared'])['toBe'](!![]),expect(b['scope'])['toBe']('file'),expect(existsSync(templateParamsFilePath()))['toBe'](![]),expect(getTemplateParamFileLayer('retail/vertical-handmade'))['toEqual']({});});});
@@ -1 +1 @@
1
- import{watch_conversations,query_events,query_objects}from'@wowok/wowok';import{computeReviewStats,detectReviewManipulation,filterVerifiedReviews}from'../knowledge/reputation-rules.js';import{pendingWrappersAt,trackAccountPayments}from'../knowledge/payment-tracker.js';const watchers=new Map();export function registerAccountEventWatcher(a){if(!a['id']||watchers['has'](a['id']))return![];return watchers['set'](a['id'],a),!![];}export function unregisterAccountEventWatcher(a){return watchers['delete'](a);}export function listAccountEventWatchers(){return Array['from'](watchers['values']());}const PRIORITY_RANK={'required':0x4,'recommended':0x3,'info':0x2,'reminder':0x1};export async function runAccountEventWatchers(a,b){const c=[],d=b&&b['length']>0x0?new Set(b):undefined;for(const g of watchers['values']()){if(d&&!d['has'](g['id']))continue;if(g['applies']&&!await g['applies'](a))continue;try{c['push'](...await g['watch'](a));}catch{}}const f=new Map();for(const h of c)f['set'](h['id'],h);return Array['from'](f['values']())['sort']((i,j)=>PRIORITY_RANK[j['priority']]-PRIORITY_RANK[i['priority']]||j['timestamp']-i['timestamp']);}registerAccountEventWatcher({'id':'messenger_unread','description':'Unread\x20encrypted\x20messages\x20needing\x20attention','watch':async({account:a})=>{const b=await watch_conversations({'account':a,'unreadOnly':!![],'previewMessageCount':0x1,'skipAutoMarkViewed':!![]});return b['map'](d=>({'id':'messenger_unread:'+d['peerAddress'],'category':'messenger_unread','priority':'reminder','title':'Unread\x20messages\x20from\x20'+d['peerAddress'],'message':d['unreadCount']+'\x20unread\x20message(s)'+(d['lastMessagePreview']?'\x20—\x20\x22'+d['lastMessagePreview']+'\x22':''),'action':'View\x20and\x20reply\x20via\x20messenger_operation','object_ref':d['peerAddress'],'timestamp':Date['now']()}));}});function toCollectionEvent(a){const b=a['plan']['holder_kind']==='business_object';return{'id':'order_collection:'+a['wrapper_id'],'category':'order_collection','priority':'recommended','title':b?'Payment\x20awaiting\x20extraction\x20at\x20object\x20'+a['holder']:'Payment\x20awaiting\x20unwrap\x20in\x20your\x20account','message':'CoinWrapper\x20'+a['wrapper_id']+'\x20(payment\x20'+a['payment']+',\x20amount\x20'+a['amount']+')\x20is\x20held\x20by\x20'+a['holder']+'.\x20'+('Drive\x20'+a['plan']['operation']+(a['plan']['anyone_can_submit']?'\x20—\x20anyone\x20may\x20submit\x20the\x20transaction':'')+';\x20')+('the\x20bare\x20Coin\x20settles\x20to\x20'+a['plan']['settles_to']+'.\x20'+a['plan']['steps']['join']('\x20')),'action':'Extract\x20via\x20'+a['plan']['operation'],'object_ref':a['wrapper_id'],'timestamp':Date['now']()};}registerAccountEventWatcher({'id':'order_collection','description':'CoinWrappers\x20awaiting\x20extraction\x20at\x20the\x20account\x20or\x20at\x20objects\x20the\x20account\x20beneficially\x20owns','watch':async({account:a,network:b})=>{if(!a)return[];const c=new Map();try{for(const d of await pendingWrappersAt(a,{'network':b})){c['set'](d['wrapper_id'],toCollectionEvent(d));}}catch{}try{const e=await trackAccountPayments({'account':a,'network':b,'max_events':0x64});for(const f of e){for(const g of f['pending']){if(!c['has'](g['wrapper_id']))c['set'](g['wrapper_id'],toCollectionEvent(g));}}}catch{}return Array['from'](c['values']());}}),registerAccountEventWatcher({'id':'demand_presented','description':'A\x20service\x20presented\x20against\x20one\x20of\x20my\x20demands','watch':async({account:a,network:b})=>{if(!a)return[];const c=await query_events({'type':'DemandPresentEvent','order':'descending','limit':0x14,'network':b,'no_cache':!![]}),d=[];for(const e of c?.['data']??[]){const f=e['demand'];if(!f)continue;try{const g=await query_objects({'objects':[f],'network':b,'no_cache':!![]}),h=g['objects']?.[0x0],i=typeof h?.['owner']==='string'?h['owner']:h?.['owner']?.['AddressOwner'];i&&i['toLowerCase']()===a['toLowerCase']()&&d['push']({'id':'demand_presented:'+f+':'+(e['service']??'?'),'category':'demand_presented','priority':'info','title':'New\x20service\x20presented\x20on\x20your\x20demand','message':'A\x20service\x20('+(e['service']??'unknown')+')\x20presented\x20against\x20demand\x20'+f+(e['recommend']?'\x20—\x20\x22'+e['recommend']+'\x22':''),'action':'Review\x20the\x20presenter\x20via\x20onchain_table_data\x20(demand\x20presenter\x20item)','object_ref':f,'timestamp':Number(e['time']??Date['now']())});}catch{}}return d;}}),registerAccountEventWatcher({'id':'reputation_integrity','description':'Review-reputation\x20analysis\x20for\x20supplied\x20review\x20rows:\x20verification,\x20stats,\x20and\x20manipulation\x20detection\x20(knowledge/reputation-rules)','applies':({reviews:a})=>Array['isArray'](a)&&a['length']>0x0,'watch':async({reviews:a,order_history:b})=>{const c=a??[],d=b&&b['length']>0x0?filterVerifiedReviews(c,b):c,e=computeReviewStats(d),f=detectReviewManipulation(d),g=[];return f['suspicious']&&g['push']({'id':'reputation_integrity:manipulation','category':'reputation_integrity','priority':'required','title':'Suspicious\x20review\x20activity\x20detected','message':'Manipulation\x20signals:\x20'+f['reasons']['join'](';\x20')+'.\x20Stats:\x20'+e['likes']+'\x20likes\x20/\x20'+e['dislikes']+'\x20dislikes\x20across\x20'+e['total']+'\x20reviews\x20('+e['verifiedCount']+'\x20verified).','action':'Cross-check\x20reviewer\x20addresses\x20against\x20completed\x20orders\x20before\x20trusting\x20the\x20review\x20aggregate','timestamp':Date['now']()}),e['total']>=0x5&&e['verifiedCount']/e['total']<0.3&&g['push']({'id':'reputation_integrity:unverified','category':'reputation_integrity','priority':'recommended','title':'Reviews\x20are\x20dominated\x20by\x20unverified\x20submissions','message':'Only\x20'+e['verifiedCount']+'/'+e['total']+'\x20reviews\x20carry\x20a\x20completed-order\x20credential\x20—\x20the\x20aggregate\x20may\x20reflect\x20spam\x20rather\x20than\x20real\x20buyers.','action':'Declare\x20the\x20review\x20rail\x20in\x20the\x20service\x20build\x20(review_mode\x20\x27review\x27\x20or\x20\x27review_reward\x27)\x20so\x20the\x20build\x20plan\x20emits\x20the\x20review\x20Repository\x20with\x20the\x20verified-buyer\x20write\x20credential\x20(AR-1)\x20—\x20manual\x20Guard/Repository\x20assembly\x20is\x20deprecated','timestamp':Date['now']()}),e['recentTrend']==='declining'&&g['push']({'id':'reputation_integrity:declining','category':'reputation_integrity','priority':'info','title':'Review\x20trend\x20is\x20declining','message':'Recent\x20like-rate\x20is\x20materially\x20below\x20the\x20earlier\x20period\x20('+Math['round'](e['likeRate']*0x64)+'%\x20overall,\x20top\x20tags:\x20'+(e['topTags']['map'](h=>h['tag'])['join'](',\x20')||'none')+').','action':'Inspect\x20recent\x20dislike\x20tags\x20for\x20recurring\x20complaint\x20themes','timestamp':Date['now']()}),g;}});
1
+ import{watch_conversations,query_events,query_objects}from'@wowok/wowok';import{computeReviewStats,detectReviewManipulation,filterVerifiedReviews}from'../knowledge/reputation-rules.js';import{pendingWrappersAt,trackAccountPayments}from'../knowledge/payment-tracker.js';const watchers=new Map();export function registerAccountEventWatcher(a){if(!a['id']||watchers['has'](a['id']))return![];return watchers['set'](a['id'],a),!![];}export function unregisterAccountEventWatcher(a){return watchers['delete'](a);}export function listAccountEventWatchers(){return Array['from'](watchers['values']());}const PRIORITY_RANK={'required':0x4,'recommended':0x3,'info':0x2,'reminder':0x1};export async function runAccountEventWatchers(a,b){const c=[],d=b&&b['length']>0x0?new Set(b):undefined;for(const g of watchers['values']()){if(d&&!d['has'](g['id']))continue;if(g['applies']&&!await g['applies'](a))continue;try{c['push'](...await g['watch'](a));}catch{}}const f=new Map();for(const h of c)f['set'](h['id'],h);return Array['from'](f['values']())['sort']((i,j)=>PRIORITY_RANK[j['priority']]-PRIORITY_RANK[i['priority']]||j['timestamp']-i['timestamp']);}registerAccountEventWatcher({'id':'messenger_unread','description':'Unread\x20encrypted\x20messages\x20needing\x20attention','watch':async({account:a})=>{const b=await watch_conversations({'account':a,'unreadOnly':!![],'previewMessageCount':0x1,'skipAutoMarkViewed':!![]});return b['map'](d=>({'id':'messenger_unread:'+d['peerAddress'],'category':'messenger_unread','priority':'reminder','title':'Unread\x20messages\x20from\x20'+d['peerAddress'],'message':d['unreadCount']+'\x20unread\x20message(s)'+(d['lastMessagePreview']?'\x20—\x20\x22'+d['lastMessagePreview']+'\x22':''),'action':'View\x20and\x20reply\x20via\x20messenger_operation','object_ref':d['peerAddress'],'timestamp':Date['now']()}));}});function toCollectionEvent(a){const b=a['plan']['holder_kind']==='business_object';return{'id':'order_collection:'+a['wrapper_id'],'category':'order_collection','priority':'recommended','title':b?'Payment\x20awaiting\x20extraction\x20at\x20object\x20'+a['holder']:'Payment\x20awaiting\x20unwrap\x20in\x20your\x20account','message':'CoinWrapper\x20'+a['wrapper_id']+'\x20(payment\x20'+a['payment']+',\x20amount\x20'+a['amount']+')\x20is\x20held\x20by\x20'+a['holder']+'.\x20'+('Drive\x20'+a['plan']['operation']+(a['plan']['anyone_can_submit']?'\x20—\x20anyone\x20may\x20submit\x20the\x20transaction':'')+';\x20')+('the\x20bare\x20Coin\x20settles\x20to\x20'+a['plan']['settles_to']+'.\x20'+a['plan']['steps']['join']('\x20')),'action':'Extract\x20via\x20'+a['plan']['operation'],'object_ref':a['wrapper_id'],'timestamp':Date['now']()};}registerAccountEventWatcher({'id':'order_collection','description':'CoinWrappers\x20awaiting\x20extraction\x20at\x20the\x20account\x20or\x20at\x20objects\x20the\x20account\x20beneficially\x20owns','watch':async({account:a,network:b})=>{if(!a)return[];const c=new Map();try{for(const d of await pendingWrappersAt(a,{'network':b})){c['set'](d['wrapper_id'],toCollectionEvent(d));}}catch{}try{const e=await trackAccountPayments({'account':a,'network':b,'max_events':0x64});for(const f of e){for(const g of f['pending']){if(!c['has'](g['wrapper_id']))c['set'](g['wrapper_id'],toCollectionEvent(g));}}}catch{}return Array['from'](c['values']());}}),registerAccountEventWatcher({'id':'demand_presented','description':'A\x20service\x20presented\x20against\x20one\x20of\x20my\x20demands','watch':async({account:a,network:b})=>{if(!a)return[];const c=await query_events({'type':'DemandPresentEvent','order':'descending','limit':0x14,'network':b,'no_cache':!![]}),d=[];for(const e of c?.['data']??[]){const f=e['demand'];if(!f)continue;try{const g=await query_objects({'objects':[f],'network':b,'no_cache':!![]}),h=g['objects']?.[0x0],i=typeof h?.['owner']==='string'?h['owner']:h?.['owner']?.['AddressOwner'];i&&i['toLowerCase']()===a['toLowerCase']()&&d['push']({'id':'demand_presented:'+f+':'+(e['service']??'?'),'category':'demand_presented','priority':'info','title':'New\x20service\x20presented\x20on\x20your\x20demand','message':'A\x20service\x20('+(e['service']??'unknown')+')\x20presented\x20against\x20demand\x20'+f+(e['recommend']?'\x20—\x20\x22'+e['recommend']+'\x22':''),'action':'Review\x20the\x20presenter\x20via\x20onchain_table_data\x20(demand\x20presenter\x20item)','object_ref':f,'timestamp':Number(e['time']??Date['now']())});}catch{}}return d;}}),registerAccountEventWatcher({'id':'reputation_integrity','description':'Review-reputation\x20analysis\x20for\x20supplied\x20review\x20rows:\x20verification,\x20stats,\x20and\x20manipulation\x20detection\x20(the\x20review-reputation\x20rules)','applies':({reviews:a})=>Array['isArray'](a)&&a['length']>0x0,'watch':async({reviews:a,order_history:b})=>{const c=a??[],d=b&&b['length']>0x0?filterVerifiedReviews(c,b):c,e=computeReviewStats(d),f=detectReviewManipulation(d),g=[];return f['suspicious']&&g['push']({'id':'reputation_integrity:manipulation','category':'reputation_integrity','priority':'required','title':'Suspicious\x20review\x20activity\x20detected','message':'Manipulation\x20signals:\x20'+f['reasons']['join'](';\x20')+'.\x20Stats:\x20'+e['likes']+'\x20likes\x20/\x20'+e['dislikes']+'\x20dislikes\x20across\x20'+e['total']+'\x20reviews\x20('+e['verifiedCount']+'\x20verified).','action':'Cross-check\x20reviewer\x20addresses\x20against\x20completed\x20orders\x20before\x20trusting\x20the\x20review\x20aggregate','timestamp':Date['now']()}),e['total']>=0x5&&e['verifiedCount']/e['total']<0.3&&g['push']({'id':'reputation_integrity:unverified','category':'reputation_integrity','priority':'recommended','title':'Reviews\x20are\x20dominated\x20by\x20unverified\x20submissions','message':'Only\x20'+e['verifiedCount']+'/'+e['total']+'\x20reviews\x20carry\x20a\x20completed-order\x20credential\x20—\x20the\x20aggregate\x20may\x20reflect\x20spam\x20rather\x20than\x20real\x20buyers.','action':'Declare\x20the\x20review\x20rail\x20in\x20the\x20service\x20build\x20(review_mode\x20\x27review\x27\x20or\x20\x27review_reward\x27)\x20so\x20the\x20build\x20plan\x20emits\x20the\x20review\x20Repository\x20with\x20the\x20verified-buyer\x20write\x20credential\x20(AR-1)\x20—\x20manual\x20Guard/Repository\x20assembly\x20is\x20deprecated','timestamp':Date['now']()}),e['recentTrend']==='declining'&&g['push']({'id':'reputation_integrity:declining','category':'reputation_integrity','priority':'info','title':'Review\x20trend\x20is\x20declining','message':'Recent\x20like-rate\x20is\x20materially\x20below\x20the\x20earlier\x20period\x20('+Math['round'](e['likeRate']*0x64)+'%\x20overall,\x20top\x20tags:\x20'+(e['topTags']['map'](h=>h['tag'])['join'](',\x20')||'none')+').','action':'Inspect\x20recent\x20dislike\x20tags\x20for\x20recurring\x20complaint\x20themes','timestamp':Date['now']()}),g;}});
@@ -1 +1 @@
1
- import{toBase58}from'@wowok/wowok';import{DataType,newDb}from'pg-mem';import{afterEach,beforeEach,describe,expect,it}from'vitest';import{PostgresProjectionStore}from'../projection/store.js';import{PostgresSyncStore}from'../sync/store.js';import{createProjectionApi}from'./server.js';const digest=toBase58(new Uint8Array(0x20)['fill'](0x7)),objectId='0x14'+'01'['repeat'](0x1f);describe('projection\x20read-only\x20API',()=>{let a,b,c,d;beforeEach(async()=>{const e=newDb();e['public']['registerFunction']({'name':'pg_advisory_xact_lock','args':[DataType['integer'],DataType['integer']],'returns':DataType['integer'],'implementation':()=>0x0});const {Pool:f}=e['adapters']['createPg']();a=new PostgresProjectionStore(new f(),0x10),b=new PostgresSyncStore(new f()),await a['migrate'](),await b['migrate'](),await a['apply']({'chain_id':'chain_a','object_id':objectId,'object_version':'1','move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/service-1','payload_hash':'0x'+'41'['repeat'](0x20),'payload_format':'json+bcs-v1','payload_json':{'name':'Indexed\x20service','stock':0x3},'checkpoint':'100','tx_digest':digest,'state':'active','observed_at':'2026-10-24T00:00:00.000Z'});const g=await b['start']({'chainId':'chain_a','stream':'graphql-shared:Service','scope':{'kind':'Service'},'checkpoint':'100'});await b['savePage']({'chainId':g['chainId'],'stream':g['stream'],'runId':g['runId'],'cursor':null,'checkpoint':'100','objects':[{'objectId':objectId,'objectVersion':0x1n}]}),await b['complete']({'chainId':g['chainId'],'stream':g['stream'],'runId':g['runId']}),c=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b}),await new Promise(i=>c['listen'](0x0,'127.0.0.1',i));const h=c['address']();d='http://127.0.0.1:'+h['port'];}),afterEach(async()=>{await new Promise((e,f)=>{c['close'](g=>g?f(g):e());}),await a['close'](),await b['close']();}),it('returns\x20projection\x20and\x20persisted\x20sync\x20status',async()=>{const e=await fetch(d+'/v1/status'),f=await e['json']();expect(e['status'])['toBe'](0xc8),expect(f)['toMatchObject']({'chain_id':'chain_a','read_only':!![],'projection':{'active_objects':0x1,'coverage':{'complete':![]}},'sync':[{'state':'complete','pages':0x1,'objects':0x1}],'head':null,'freshness':null}),expect(f['watermarks'])['toEqual']([{'verified_kind':'Service','max_checkpoint':'100','active_objects':0x1}]);}),it('reports\x20chain-head\x20lag\x20and\x20staleness\x20when\x20a\x20probe\x20is\x20configured',async()=>{const e=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'staleLag':0x3,'head':{'read':async()=>({'checkpoint':'105','observed_at':'2026-10-24T12:00:00.000Z','source':'probe'})}});await new Promise(g=>e['listen'](0x0,'127.0.0.1',g));const f=e['address']();try{const g=await fetch('http://127.0.0.1:'+f['port']+'/v1/status'),h=await g['json']();expect(h['head'])['toMatchObject']({'checkpoint':'105','source':'probe'}),expect(h['freshness'])['toEqual']({'head_checkpoint':'105','projection_checkpoint':'100','head_lag':'5','stale':!![]});}finally{await new Promise((i,j)=>{e['close'](k=>k?j(k):i());});}}),it('lists\x20current\x20objects\x20with\x20coverage\x20and\x20version\x20metadata',async()=>{const e=await fetch(d+'/v1/objects?kind=Service&limit=1'),f=await e['json']();expect(e['status'])['toBe'](0xc8),expect(f['objects'])['toHaveLength'](0x1),expect(f['objects'][0x0])['toMatchObject']({'objectId':objectId,'objectVersion':'1','verifiedKind':'Service','payloadJson':{'name':'Indexed\x20service','stock':0x3}}),expect(f['coverage'])['toMatchObject']({'mode':'known_objects','complete':![]}),expect(e['headers']['get']('cache-control'))['toBe']('no-store');}),it('rejects\x20invalid\x20selectors\x20without\x20exposing\x20internal\x20errors',async()=>{const e=await fetch(d+'/v1/objects?kind=Unknown'),f=await fetch(d+'/v1/objects?cursor=invalid'),g=await fetch(d+'/v1/objects?shard_count=16');expect(e['status'])['toBe'](0x190),expect(f['status'])['toBe'](0x190),expect(g['status'])['toBe'](0x190),expect(await e['json']())['toEqual']({'error':{'code':'BAD_REQUEST','message':'Unknown\x20object\x20kind:\x20Unknown'}});}),it('exposes\x20graph\x20edges\x20with\x20orphan\x20annotation',async()=>{const e='0x15'+'02'['repeat'](0x1f);await a['apply']({'chain_id':'chain_a','object_id':objectId,'object_version':'2','move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/service-2','payload_hash':'0x'+'43'['repeat'](0x20),'payload_format':'rpc-content-v1','payload_json':{'machine':e,'name':'Indexed\x20service'},'checkpoint':'101','tx_digest':digest,'state':'active','observed_at':'2026-10-24T01:00:00.000Z'});const f=await fetch(d+'/v1/edges?src='+objectId),g=await f['json']();expect(f['status'])['toBe'](0xc8),expect(g)['toMatchObject']({'direction':'out','object_id':objectId,'orphan_count':0x1}),expect(g['edges'])['toEqual']([{'src':objectId,'srcKind':'Service','edge':'machine','dst':e,'dstKind':'Machine','objectVersion':'2','dstProjected':![]}]);const h=await fetch(d+'/v1/edges?dst='+e),i=await h['json']();expect(h['status'])['toBe'](0xc8),expect(i['direction'])['toBe']('in'),expect(i['edges'][0x0])['toMatchObject']({'src':objectId,'edge':'machine'});const j=await fetch(d+'/v1/edges'),k=await fetch(d+'/v1/edges?src=invalid');expect(j['status'])['toBe'](0x190),expect(k['status'])['toBe'](0x190);}),it('has\x20no\x20write\x20or\x20catch-all\x20endpoints',async()=>{const e=await fetch(d+'/v1/objects',{'method':'POST','body':'{}'}),f=await fetch(d+'/v1/unknown');expect(e['status'])['toBe'](0x195),expect(e['headers']['get']('allow'))['toBe']('GET'),expect(f['status'])['toBe'](0x194);});}),describe('match\x20API',()=>{let a,b,c,d;const e=j=>'0x14'+j['repeat'](0x1f),f=e('01'),g=e('02'),h=e('03');function i(j,k,l){return{'chain_id':'chain_a','object_id':j,'object_version':k,'move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/'+j+'-'+k,'payload_hash':'0x'+'41'['repeat'](0x20),'payload_format':'rpc-content-v1','payload_json':l,'checkpoint':'100','tx_digest':toBase58(new Uint8Array(0x20)['fill'](0x7)),'state':'active','observed_at':'2026-10-24T00:00:00.000Z'};}beforeEach(async()=>{const j=newDb();j['public']['registerFunction']({'name':'pg_advisory_xact_lock','args':[DataType['integer'],DataType['integer']],'returns':DataType['integer'],'implementation':()=>0x0});const {Pool:k}=j['adapters']['createPg']();a=new PostgresProjectionStore(new k(),0x10),b=new PostgresSyncStore(new k()),await a['migrate'](),await b['migrate'](),await a['apply'](i(f,'1',{'description':'Exclusive\x20beat\x20license\x20for\x20hip\x20hop\x20producers','location':'remote','sales':[{'fields':{'name':'Beat\x20License','price':'6000000000','wip_hash':'0xabc'}}],'arbitrations':['0x12'+'04'['repeat'](0x1f)],'compensation_fund':'1000000000','machine':'0x15'+'05'['repeat'](0x1f),'um':'0x24'+'06'['repeat'](0x1f),'bPublished':!![],'bPaused':![]})),await a['apply'](i(g,'1',{'description':'Coffee\x20shop\x20interior\x20mural\x20painting','location':'Shanghai','sales':[{'fields':{'name':'Mural','price':'15000000000'}}],'arbitrations':[],'compensation_fund':'0','bPublished':!![],'bPaused':![]})),await a['apply'](i(h,'1',{'description':'Beat\x20store\x20on\x20holiday','sales':[{'fields':{'name':'Beat\x20Pack','price':'1000000000'}}],'bPublished':!![],'bPaused':!![]})),c=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b}),await new Promise(l=>c['listen'](0x0,'127.0.0.1',l)),d='http://127.0.0.1:'+c['address']()['port'];}),afterEach(async()=>{await new Promise((j,k)=>{c['close'](l=>l?k(l):j());}),await a['close'](),await b['close']();}),it('matches\x20materialized\x20facets\x20end-to-end\x20with\x20honest\x20coverage',async()=>{const j=new URLSearchParams({'kind':'Service','q':'beat\x20license','capabilities':'has_arbitration','budget':'10','limit':'10'}),k=await fetch(d+'/v1/match?'+j),l=await k['json']();expect(k['status'])['toBe'](0xc8),expect(l['chain_id'])['toBe']('chain_a'),expect(l['policy_version'])['toBe']('public-baseline-1'),expect(l['coverage'])['toMatchObject']({'mode':'known_objects','complete':![]}),expect(l['recall'])['toMatchObject']({'live_set':0x3,'gated':0x2,'merged':0x2,'channels_active':['structured','bm25']}),expect(l['candidates']['map'](o=>o['object_id']))['toEqual']([f,g]);const m=l['candidates'][0x0];expect(m['server_evaluation']['policy_version'])['toBe']('public-baseline-1'),expect(m['server_evaluation']['total'])['toBe'](0x64),expect(m['server_evaluation']['unknown_rules']['some'](o=>o['startsWith']('trust:')))['toBe'](!![]),expect(m['public_features']['capabilities'])['toContain']('has_refund_path');const n=l['candidates'][0x1];expect(n['server_evaluation']['red_flags'])['toEqual'](['price_over_budget','missing_capability:has_arbitration']);}),it('rejects\x20invalid\x20match\x20parameters',async()=>{const j=['/v1/match','/v1/match?kind=Arb','/v1/match?kind=Service&capabilities=has_wings','/v1/match?kind=Service&budget=abc','/v1/match?kind=Service&budget=1.2345678901','/v1/match?kind=Service&budget=-5','/v1/match?kind=Service&limit=0','/v1/match?kind=Service&limit=101','/v1/match?kind=Service&recall_limit=1001'];for(const k of j){const l=await fetch(''+d+k);expect(l['status'],k)['toBe'](0x190),expect((await l['json']())['error']['code'])['toBe']('BAD_REQUEST');}});});
1
+ import{toBase58}from'@wowok/wowok';import{DataType,newDb}from'pg-mem';import{afterEach,beforeEach,describe,expect,it}from'vitest';import{PostgresProjectionStore}from'../projection/store.js';import{PostgresSyncStore}from'../sync/store.js';import{createProjectionApi}from'./server.js';const digest=toBase58(new Uint8Array(0x20)['fill'](0x7)),objectId='0x14'+'01'['repeat'](0x1f);describe('projection\x20read-only\x20API',()=>{let a,b,c,d;beforeEach(async()=>{const e=newDb();e['public']['registerFunction']({'name':'pg_advisory_xact_lock','args':[DataType['integer'],DataType['integer']],'returns':DataType['integer'],'implementation':()=>0x0});const {Pool:f}=e['adapters']['createPg']();a=new PostgresProjectionStore(new f(),0x10),b=new PostgresSyncStore(new f()),await a['migrate'](),await b['migrate'](),await a['apply']({'chain_id':'chain_a','object_id':objectId,'object_version':'1','move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/service-1','payload_hash':'0x'+'41'['repeat'](0x20),'payload_format':'json+bcs-v1','payload_json':{'name':'Indexed\x20service','stock':0x3},'checkpoint':'100','tx_digest':digest,'state':'active','observed_at':'2026-10-24T00:00:00.000Z'});const g=await b['start']({'chainId':'chain_a','stream':'graphql-shared:Service','scope':{'kind':'Service'},'checkpoint':'100'});await b['savePage']({'chainId':g['chainId'],'stream':g['stream'],'runId':g['runId'],'cursor':null,'checkpoint':'100','objects':[{'objectId':objectId,'objectVersion':0x1n}]}),await b['complete']({'chainId':g['chainId'],'stream':g['stream'],'runId':g['runId']}),c=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b}),await new Promise(i=>c['listen'](0x0,'127.0.0.1',i));const h=c['address']();d='http://127.0.0.1:'+h['port'];}),afterEach(async()=>{await new Promise((e,f)=>{c['close'](g=>g?f(g):e());}),await a['close'](),await b['close']();}),it('returns\x20projection\x20and\x20persisted\x20sync\x20status',async()=>{const e=await fetch(d+'/v1/status'),f=await e['json']();expect(e['status'])['toBe'](0xc8),expect(f)['toMatchObject']({'chain_id':'chain_a','read_only':!![],'projection':{'active_objects':0x1,'coverage':{'complete':![]}},'sync':[{'state':'complete','pages':0x1,'objects':0x1}],'head':null,'freshness':null,'cdc':[]}),expect(f['watermarks'])['toEqual']([{'verified_kind':'Service','max_checkpoint':'100','active_objects':0x1}]);}),it('publishes\x20every\x20CDC\x20cursor\x20with\x20its\x20distance\x20from\x20head',async()=>{await b['setCdcCheckpoint']('chain_a','Service','100'),await b['setCdcCheckpoint']('chain_a','Demand','90');const e=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'head':{'read':async()=>({'checkpoint':'200','observed_at':'2026-10-24T12:00:00.000Z','source':'probe'})}});await new Promise(g=>e['listen'](0x0,'127.0.0.1',g));const f=e['address']();try{const g=await(await fetch('http://127.0.0.1:'+f['port']+'/v1/status'))['json']();expect(g['cdc'])['toEqual']([{'kind':'Demand','checkpoint':'90','updated_at':expect['any'](String),'behind_head':'110'},{'kind':'Service','checkpoint':'100','updated_at':expect['any'](String),'behind_head':'100'}]);}finally{await new Promise((h,i)=>{e['close'](j=>j?i(j):h());});}}),it('reports\x20chain-head\x20lag\x20and\x20staleness\x20when\x20a\x20probe\x20is\x20configured',async()=>{const e=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'staleLag':0x3,'head':{'read':async()=>({'checkpoint':'105','observed_at':'2026-10-24T12:00:00.000Z','source':'probe'})}});await new Promise(g=>e['listen'](0x0,'127.0.0.1',g));const f=e['address']();try{const g=await fetch('http://127.0.0.1:'+f['port']+'/v1/status'),h=await g['json']();expect(h['head'])['toMatchObject']({'checkpoint':'105','source':'probe'}),expect(h['freshness'])['toMatchObject']({'head_checkpoint':'105','projection_checkpoint':'100','head_lag':'5','stale':!![]}),expect(h['freshness']['projection_age_seconds'])['toBe'](0x0),expect(h['freshness']['version_observed_at'])['toBe']('2026-10-24T00:00:00.000Z');}finally{await new Promise((i,j)=>{e['close'](k=>k?j(k):i());});}}),it('scores\x20freshness\x20off\x20the\x20last\x20confirmed\x20round,\x20not\x20off\x20the\x20last\x20version\x20change',async()=>{const e=await b['start']({'chainId':'chain_a','stream':'graphql-shared:Service','scope':{'kind':'Service'},'checkpoint':'200'});await b['savePage']({'chainId':e['chainId'],'stream':e['stream'],'runId':e['runId'],'cursor':null,'checkpoint':'200','objects':[{'objectId':objectId,'objectVersion':0x1n}]}),await b['complete']({'chainId':e['chainId'],'stream':e['stream'],'runId':e['runId']});const f=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'staleAgeSec':0x1,'head':{'read':async()=>({'checkpoint':'210','observed_at':new Date()['toISOString'](),'source':'probe'})}});await new Promise(h=>f['listen'](0x0,'127.0.0.1',h));const g=f['address']();try{const h=await(await fetch('http://127.0.0.1:'+g['port']+'/v1/status'))['json']();expect(h['freshness'])['toMatchObject']({'projection_checkpoint':'200','head_lag':'10','version_checkpoint':'100','version_observed_at':'2026-10-24T00:00:00.000Z','stale':![]}),expect(h['freshness']['projection_age_seconds'])['toBeLessThan'](0x3c);}finally{await new Promise((i,j)=>{f['close'](k=>k?j(k):i());});}}),it('splits\x20quarantined\x20facts\x20into\x20blocking\x20and\x20superseded',async()=>{const e=await a['apply']({'chain_id':'chain_a','object_id':objectId,'object_version':'1','move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/service-other','payload_hash':'0x'+'42'['repeat'](0x20),'payload_format':'json+bcs-v1','checkpoint':'150','tx_digest':digest,'state':'active','observed_at':'2026-10-24T01:00:00.000Z'});expect(e['status'])['toBe']('conflict');const f=await a['apply']({'chain_id':'chain_a','object_id':'0x14'+'02'['repeat'](0x1f),'object_version':'7','move_type':'0x9::unknown::Unknown','owner_kind':'Shared','payload_uri':'test://raw/unknown-1','payload_hash':'0x'+'43'['repeat'](0x20),'payload_format':'json+bcs-v1','checkpoint':'160','tx_digest':digest,'state':'active','observed_at':'2026-10-24T02:00:00.000Z'});expect(f['status'])['toBe']('quarantined');const g=await(await fetch(d+'/v1/status'))['json']();expect(g['quarantine']['blocking'])['toBe'](0x1),expect(g['quarantine']['entries']['map'](h=>[h['reason_code'],h['blocking']]))['toEqual']([['UNSUPPORTED_OR_INVALID_MOVE_TYPE',!![]],['CONFLICTING_OBJECT_VERSION',![]]]),expect(g['quarantine']['entries'][0x1]['object_id'])['toBe'](objectId);}),it('calls\x20a\x20projection\x20stale\x20by\x20age\x20even\x20when\x20it\x20sits\x20on\x20the\x20chain\x20head',async()=>{for(const g of await b['status']('chain_a')){await b['fail'](g['chainId'],g['stream'],g['runId'],'simulated\x20timer\x20outage');}const e=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b,'staleAgeSec':0x1,'head':{'read':async()=>({'checkpoint':'100','observed_at':'2026-10-24T12:00:00.000Z','source':'probe'})}});await new Promise(h=>e['listen'](0x0,'127.0.0.1',h));const f=e['address']();try{const h=await(await fetch('http://127.0.0.1:'+f['port']+'/v1/status'))['json']();expect(h['freshness'])['toMatchObject']({'head_lag':'0','stale':!![]}),expect(h['projection']['observed_at'])['toBe']('2026-10-24T00:00:00.000Z');}finally{await new Promise((i,j)=>{e['close'](k=>k?j(k):i());});}}),it('lists\x20current\x20objects\x20with\x20coverage\x20and\x20version\x20metadata',async()=>{const e=await fetch(d+'/v1/objects?kind=Service&limit=1'),f=await e['json']();expect(e['status'])['toBe'](0xc8),expect(f['objects'])['toHaveLength'](0x1),expect(f['objects'][0x0])['toMatchObject']({'objectId':objectId,'objectVersion':'1','verifiedKind':'Service','payloadJson':{'name':'Indexed\x20service','stock':0x3}}),expect(f['coverage'])['toMatchObject']({'mode':'known_objects','complete':![]}),expect(e['headers']['get']('cache-control'))['toBe']('no-store');}),it('rejects\x20invalid\x20selectors\x20without\x20exposing\x20internal\x20errors',async()=>{const e=await fetch(d+'/v1/objects?kind=Unknown'),f=await fetch(d+'/v1/objects?cursor=invalid'),g=await fetch(d+'/v1/objects?shard_count=16');expect(e['status'])['toBe'](0x190),expect(f['status'])['toBe'](0x190),expect(g['status'])['toBe'](0x190),expect(await e['json']())['toEqual']({'error':{'code':'BAD_REQUEST','message':'Unknown\x20object\x20kind:\x20Unknown'}});}),it('exposes\x20graph\x20edges\x20with\x20orphan\x20annotation',async()=>{const e='0x15'+'02'['repeat'](0x1f);await a['apply']({'chain_id':'chain_a','object_id':objectId,'object_version':'2','move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/service-2','payload_hash':'0x'+'43'['repeat'](0x20),'payload_format':'rpc-content-v1','payload_json':{'machine':e,'name':'Indexed\x20service'},'checkpoint':'101','tx_digest':digest,'state':'active','observed_at':'2026-10-24T01:00:00.000Z'});const f=await fetch(d+'/v1/edges?src='+objectId),g=await f['json']();expect(f['status'])['toBe'](0xc8),expect(g)['toMatchObject']({'direction':'out','object_id':objectId,'orphan_count':0x1}),expect(g['edges'])['toEqual']([{'src':objectId,'srcKind':'Service','edge':'machine','dst':e,'dstKind':'Machine','objectVersion':'2','dstProjected':![]}]);const h=await fetch(d+'/v1/edges?dst='+e),i=await h['json']();expect(h['status'])['toBe'](0xc8),expect(i['direction'])['toBe']('in'),expect(i['edges'][0x0])['toMatchObject']({'src':objectId,'edge':'machine'});const j=await fetch(d+'/v1/edges'),k=await fetch(d+'/v1/edges?src=invalid');expect(j['status'])['toBe'](0x190),expect(k['status'])['toBe'](0x190);}),it('has\x20no\x20write\x20or\x20catch-all\x20endpoints',async()=>{const e=await fetch(d+'/v1/objects',{'method':'POST','body':'{}'}),f=await fetch(d+'/v1/unknown');expect(e['status'])['toBe'](0x195),expect(e['headers']['get']('allow'))['toBe']('GET'),expect(f['status'])['toBe'](0x194);});}),describe('match\x20API',()=>{let a,b,c,d;const e=j=>'0x14'+j['repeat'](0x1f),f=e('01'),g=e('02'),h=e('03');function i(j,k,l){return{'chain_id':'chain_a','object_id':j,'object_version':k,'move_type':'0x2::service::Service<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/'+j+'-'+k,'payload_hash':'0x'+'41'['repeat'](0x20),'payload_format':'rpc-content-v1','payload_json':l,'checkpoint':'100','tx_digest':toBase58(new Uint8Array(0x20)['fill'](0x7)),'state':'active','observed_at':'2026-10-24T00:00:00.000Z'};}beforeEach(async()=>{const j=newDb();j['public']['registerFunction']({'name':'pg_advisory_xact_lock','args':[DataType['integer'],DataType['integer']],'returns':DataType['integer'],'implementation':()=>0x0});const {Pool:k}=j['adapters']['createPg']();a=new PostgresProjectionStore(new k(),0x10),b=new PostgresSyncStore(new k()),await a['migrate'](),await b['migrate'](),await a['apply'](i(f,'1',{'description':'Exclusive\x20beat\x20license\x20for\x20hip\x20hop\x20producers','location':'remote','sales':[{'fields':{'name':'Beat\x20License','price':'6000000000','wip_hash':'0xabc'}}],'arbitrations':['0x12'+'04'['repeat'](0x1f)],'compensation_fund':'1000000000','machine':'0x15'+'05'['repeat'](0x1f),'um':'0x24'+'06'['repeat'](0x1f),'bPublished':!![],'bPaused':![]})),await a['apply'](i(g,'1',{'description':'Coffee\x20shop\x20interior\x20mural\x20painting','location':'Shanghai','sales':[{'fields':{'name':'Mural','price':'15000000000'}}],'arbitrations':[],'compensation_fund':'0','bPublished':!![],'bPaused':![]})),await a['apply'](i(h,'1',{'description':'Beat\x20store\x20on\x20holiday','sales':[{'fields':{'name':'Beat\x20Pack','price':'1000000000'}}],'bPublished':!![],'bPaused':!![]})),c=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b}),await new Promise(l=>c['listen'](0x0,'127.0.0.1',l)),d='http://127.0.0.1:'+c['address']()['port'];}),afterEach(async()=>{await new Promise((j,k)=>{c['close'](l=>l?k(l):j());}),await a['close'](),await b['close']();}),it('matches\x20materialized\x20facets\x20end-to-end\x20with\x20honest\x20coverage',async()=>{const j=new URLSearchParams({'kind':'Service','q':'beat\x20license','capabilities':'has_arbitration','budget':'10','limit':'10'}),k=await fetch(d+'/v1/match?'+j),l=await k['json']();expect(k['status'])['toBe'](0xc8),expect(l['chain_id'])['toBe']('chain_a'),expect(l['policy_version'])['toBe']('public-baseline-1'),expect(l['coverage'])['toMatchObject']({'mode':'known_objects','complete':![]}),expect(l['recall'])['toMatchObject']({'live_set':0x3,'gated':0x2,'merged':0x2,'channels_active':['structured','bm25']}),expect(l['candidates']['map'](o=>o['object_id']))['toEqual']([f,g]);const m=l['candidates'][0x0];expect(m['server_evaluation']['policy_version'])['toBe']('public-baseline-1'),expect(m['server_evaluation']['total'])['toBe'](0x64),expect(m['server_evaluation']['unknown_rules']['some'](o=>o['startsWith']('trust:')))['toBe'](!![]),expect(m['public_features']['capabilities'])['toContain']('has_refund_path');const n=l['candidates'][0x1];expect(n['server_evaluation']['red_flags'])['toEqual'](['price_over_budget','missing_capability:has_arbitration']);}),it('rejects\x20invalid\x20match\x20parameters',async()=>{const j=['/v1/match','/v1/match?kind=Arb','/v1/match?kind=Service&capabilities=has_wings','/v1/match?kind=Service&budget=abc','/v1/match?kind=Service&budget=1.2345678901','/v1/match?kind=Service&budget=-5','/v1/match?kind=Service&limit=0','/v1/match?kind=Service&limit=101','/v1/match?kind=Service&recall_limit=1001'];for(const k of j){const l=await fetch(''+d+k);expect(l['status'],k)['toBe'](0x190),expect((await l['json']())['error']['code'])['toBe']('BAD_REQUEST');}});}),describe('projection\x20aggregate\x20API\x20(S17-C\x20F-RQD2-06\x20cross-order\x20view)',()=>{let a,b,c,d;const e='0x14'+'aa'['repeat'](0x1f),f='0x14'+'bb'['repeat'](0x1f),g='0x15'+'cc'['repeat'](0x1f),h='0x12'+'dd'['repeat'](0x1f),i='0x00'+'11'['repeat'](0x1f),j='0x00'+'22'['repeat'](0x1f),k=o=>'0x16'+String(o)['padStart'](0x2,'0')['repeat'](0x1f),l=toBase58(new Uint8Array(0x20)['fill'](0x9));async function m(n,o){await a['apply']({'chain_id':'chain_a','object_id':n,'object_version':'1','move_type':'0x2::order::Order<0x2::wow::WOW>','owner_kind':'Shared','payload_uri':'test://raw/'+n,'payload_hash':'0x'+'42'['repeat'](0x20),'payload_format':'rpc-content-v1','payload_json':{'service':o['service'],...o['machine']?{'machine':o['machine']}:{},'amount':o['amount'],'owner':o['owner'],'claimed_by':o['claimed_by']??null,'time':0x1a18a4d1565},'checkpoint':'200','tx_digest':l,'state':'active','observed_at':'2026-10-31T00:00:00.000Z'});}beforeEach(async()=>{const n=newDb();n['public']['registerFunction']({'name':'pg_advisory_xact_lock','args':[DataType['integer'],DataType['integer']],'returns':DataType['integer'],'implementation':()=>0x0});const {Pool:o}=n['adapters']['createPg']();a=new PostgresProjectionStore(new o(),0x10),b=new PostgresSyncStore(new o()),await a['migrate'](),await b['migrate'](),await m(k(0x1),{'service':e,'amount':'6000000000','owner':i}),await m(k(0x2),{'service':e,'amount':'6000000000','owner':j}),await m(k(0x3),{'service':e,'amount':'6000000000','owner':i,'claimed_by':h}),await m(k(0x4),{'service':f,'machine':g,'amount':'1000000000','owner':j}),c=createProjectionApi({'chainId':'chain_a','projection':a,'sync':b}),await new Promise(p=>c['listen'](0x0,'127.0.0.1',p)),d='http://127.0.0.1:'+c['address']()['port'];}),afterEach(async()=>{await new Promise((n,o)=>{c['close'](p=>p?o(p):n());}),await a['close'](),await b['close']();}),it('aggregates\x20orders\x20per\x20service\x20with\x20totals\x20and\x20the\x20coverage\x20watermark',async()=>{const n=await fetch(d+'/v1/aggregate?kind=Order'),o=await n['json']();expect(n['status'])['toBe'](0xc8),expect(o)['toMatchObject']({'chain_id':'chain_a','kind':'Order','group':'service','group_id':null,'metric':'amount','exclude_claimed':![],'rows':[{'group_id':e,'count':0x3,'metric_sum':'18000000000','max_checkpoint':'200'},{'group_id':f,'count':0x1,'metric_sum':'1000000000','max_checkpoint':'200'}],'totals':{'count':0x4,'metric_sum':'19000000000'},'truncated':![]}),expect(o['coverage'])['toMatchObject']({'mode':'known_objects','chain_id':'chain_a'});}),it('answers\x20the\x20target\x20check:\x20single\x20group\x20with\x20claimed\x20orders\x20excluded',async()=>{const n=new URLSearchParams({'kind':'Order','group_id':e,'exclude_claimed':'1'}),o=await(await fetch(d+'/v1/aggregate?'+n))['json']();expect(o['rows'])['toEqual']([{'group_id':e,'count':0x2,'metric_sum':'12000000000','max_checkpoint':'200'}]),expect(o['totals'])['toEqual']({'count':0x2,'metric_sum':'12000000000'});}),it('aggregates\x20by\x20the\x20owner\x20dimension',async()=>{const n=await(await fetch(d+'/v1/aggregate?kind=Order&group=owner'))['json']();expect(n['rows'])['toEqual']([{'group_id':i,'count':0x2,'metric_sum':'12000000000','max_checkpoint':'200'},{'group_id':j,'count':0x2,'metric_sum':'7000000000','max_checkpoint':'200'}]);}),it('returns\x20an\x20empty\x20honest\x20aggregate\x20when\x20nothing\x20is\x20projected',async()=>{const n=newDb();n['public']['registerFunction']({'name':'pg_advisory_xact_lock','args':[DataType['integer'],DataType['integer']],'returns':DataType['integer'],'implementation':()=>0x0});const {Pool:o}=n['adapters']['createPg'](),p=new PostgresProjectionStore(new o(),0x10);await p['migrate']();try{const q=createProjectionApi({'chainId':'chain_a','projection':p,'sync':b});await new Promise(s=>q['listen'](0x0,'127.0.0.1',s));const r=q['address']()['port'];try{const s=await(await fetch('http://127.0.0.1:'+r+'/v1/aggregate?kind=Order'))['json']();expect(s['rows'])['toEqual']([]),expect(s['totals'])['toEqual']({'count':0x0,'metric_sum':'0'}),expect(s['coverage'])['toMatchObject']({'chain_id':'chain_a'});}finally{await new Promise((t,u)=>{q['close'](v=>v?u(v):t());});}}finally{await p['close']();}}),it('rejects\x20invalid\x20aggregate\x20parameters',async()=>{const n=['/v1/aggregate','/v1/aggregate?kind=Arb','/v1/aggregate?kind=Order&group=progress','/v1/aggregate?kind=Order&metric=allocation','/v1/aggregate?kind=Order&group_id=not-an-address','/v1/aggregate?kind=Order&exclude_claimed=maybe','/v1/aggregate?kind=Order&limit=0','/v1/aggregate?kind=Order&limit=1001'];for(const o of n){const p=await fetch(''+d+o);expect(p['status'],o)['toBe'](0x190),expect((await p['json']())['error']['code'])['toBe']('BAD_REQUEST');}});});
@@ -1 +1 @@
1
- import{PostgresProjectionStore}from'../projection/store.js';import{PostgresSyncStore}from'../sync/store.js';import{createChainHeadProbe}from'./head.js';import{createProjectionApi}from'./server.js';async function main(){const a=process['argv']['slice'](0x2);if(a[0x0]==='--help'||a[0x0]==='help'){console['log']('Usage:\x20index-api\x20<chain-id>\x0aEnvironment:\x20DATABASE_URL,\x20WOWOK_INDEX_HOST=127.0.0.1,\x20WOWOK_INDEX_PORT=8787,\x20WOWOK_HEAD_RPC_URL\x20(optional),\x20WOWOK_INDEX_STALE_LAG=0\x20(optional)');return;}if(a['length']!==0x1||!a[0x0]){console['error']('Usage:\x20index-api\x20<chain-id>'),process['exitCode']=0x2;return;}const b=process['env']['DATABASE_URL'];if(!b)throw new Error('DATABASE_URL\x20is\x20required');const c=process['env']['WOWOK_INDEX_HOST']??'127.0.0.1',d=Number(process['env']['WOWOK_INDEX_PORT']??0x2253);if(!Number['isInteger'](d)||d<0x0||d>0xffff)throw new Error('Invalid\x20API\x20port');const e=Number(process['env']['WOWOK_INDEX_SHARD_COUNT']??0x100),f=Number(process['env']['WOWOK_INDEX_STALE_LAG']??0x0),g=process['env']['WOWOK_HEAD_RPC_URL'],h=PostgresProjectionStore['fromDatabaseUrl'](b,e),i=PostgresSyncStore['fromDatabaseUrl'](b),j=createProjectionApi({'chainId':a[0x0],'projection':h,'sync':i,'staleLag':f,'head':g?createChainHeadProbe(g):undefined});try{await new Promise((k,l)=>{j['once']('error',l),j['listen'](d,c,()=>{const n=j['address']();console['log'](JSON['stringify']({'status':'listening','host':n['address'],'port':n['port'],'read_only':!![]}));});const m=()=>{j['close'](n=>n?l(n):k());};process['once']('SIGINT',m),process['once']('SIGTERM',m);});}finally{await h['close'](),await i['close']();}}await main();
1
+ import{PostgresProjectionStore}from'../projection/store.js';import{PostgresSyncStore}from'../sync/store.js';import{createChainHeadProbe}from'./head.js';import{createProjectionApi}from'./server.js';async function main(){const a=process['argv']['slice'](0x2);if(a[0x0]==='--help'||a[0x0]==='help'){console['log']('Usage:\x20index-api\x20<chain-id>\x0aEnvironment:\x20DATABASE_URL,\x20WOWOK_INDEX_HOST=127.0.0.1,\x20WOWOK_INDEX_PORT=8787,\x20WOWOK_HEAD_RPC_URL\x20(optional),\x20WOWOK_INDEX_STALE_LAG=0\x20(optional),\x20WOWOK_INDEX_STALE_AGE_SEC=0\x20(optional)');return;}if(a['length']!==0x1||!a[0x0]){console['error']('Usage:\x20index-api\x20<chain-id>'),process['exitCode']=0x2;return;}const b=process['env']['DATABASE_URL'];if(!b)throw new Error('DATABASE_URL\x20is\x20required');const c=process['env']['WOWOK_INDEX_HOST']??'127.0.0.1',d=Number(process['env']['WOWOK_INDEX_PORT']??0x2253);if(!Number['isInteger'](d)||d<0x0||d>0xffff)throw new Error('Invalid\x20API\x20port');const e=Number(process['env']['WOWOK_INDEX_SHARD_COUNT']??0x100),f=Number(process['env']['WOWOK_INDEX_STALE_LAG']??0x0),g=Number(process['env']['WOWOK_INDEX_STALE_AGE_SEC']??0x0),h=process['env']['WOWOK_HEAD_RPC_URL'],i=PostgresProjectionStore['fromDatabaseUrl'](b,e),j=PostgresSyncStore['fromDatabaseUrl'](b),k=createProjectionApi({'chainId':a[0x0],'projection':i,'sync':j,'staleLag':f,'staleAgeSec':g,'head':h?createChainHeadProbe(h):undefined});try{await new Promise((l,m)=>{k['once']('error',m),k['listen'](d,c,()=>{const o=k['address']();console['log'](JSON['stringify']({'status':'listening','host':o['address'],'port':o['port'],'read_only':!![]}));});const n=()=>{k['close'](o=>o?m(o):l());};process['once']('SIGINT',n),process['once']('SIGTERM',n);});}finally{await i['close'](),await j['close']();}}await main();
@@ -8,5 +8,6 @@ export interface ProjectionApiOptions {
8
8
  sync: PostgresSyncStore;
9
9
  head?: ChainHeadProbe;
10
10
  staleLag?: number;
11
+ staleAgeSec?: number;
11
12
  }
12
13
  export declare function createProjectionApi(options: ProjectionApiOptions): Server;
@@ -1 +1 @@
1
- import{createServer}from'node:http';import{WOW_OBJECT_TYPE_TAGS,wowAddressToBytes}from'@wowok/wowok';import{KNOWN_CAPABILITIES,runMatch}from'./match.js';function json(a,b,c){a['writeHead'](b,{'Content-Type':'application/json;\x20charset=utf-8','Cache-Control':'no-store','X-Content-Type-Options':'nosniff'}),a['end'](JSON['stringify'](c));}function badRequest(a,b){json(a,0x190,{'error':{'code':'BAD_REQUEST','message':b}});}const WOW_DECIMALS=0x9;function parseWowToWei(a){const b=/^(\d+)(?:\.(\d{1,9}))?$/['exec'](a['trim']());if(!b)return null;const c=(b[0x2]??'')['padEnd'](WOW_DECIMALS,'0');return(BigInt(b[0x1])*BigInt(0xa**WOW_DECIMALS)+BigInt(c))['toString']();}function parsePositiveInt(a){return/^\d+$/['test'](a['trim']())?Number(a['trim']()):null;}export function createProjectionApi(a){if(!a['chainId'])throw new Error('chainId\x20is\x20required');const b=a['staleLag']??0x0;if(!Number['isInteger'](b)||b<0x0)throw new Error('Invalid\x20staleLag');return createServer(async(c,d)=>{try{if(c['method']!=='GET'){d['setHeader']('Allow','GET'),json(d,0x195,{'error':{'code':'METHOD_NOT_ALLOWED','message':'GET\x20required'}});return;}const e=new URL(c['url']??'/','http://localhost');if(e['pathname']==='/v1/status'){const [f,g,h,i]=await Promise['all']([a['projection']['status'](a['chainId']),a['sync']['status'](a['chainId']),a['projection']['watermarks'](a['chainId']),a['head']?a['head']['read']():Promise['resolve'](null)]);let j=null;if(i?.['checkpoint']!==null&&i?.['checkpoint']!==undefined&&f['max_checkpoint']!==null){const k=BigInt(i['checkpoint'])-BigInt(f['max_checkpoint']);j={'head_checkpoint':i['checkpoint'],'projection_checkpoint':f['max_checkpoint'],'head_lag':(k>0x0n?k:0x0n)['toString'](),'stale':b>0x0&&k>BigInt(b)};}json(d,0xc8,{'chain_id':a['chainId'],'read_only':!![],'generated_at':new Date()['toISOString'](),'projection':f,'sync':g,'watermarks':h,'head':i,'freshness':j});return;}if(e['pathname']==='/v1/objects'){const l=e['searchParams']['get']('kind')??undefined;if(l&&!(l in WOW_OBJECT_TYPE_TAGS)){badRequest(d,'Unknown\x20object\x20kind:\x20'+l);return;}const m=e['searchParams']['get']('cursor')??undefined;if(m)try{wowAddressToBytes(m);}catch{badRequest(d,'Invalid\x20object\x20cursor');return;}const n=e['searchParams']['get']('limit'),o=n===null?undefined:Number(n);if(o!==undefined&&(!Number['isInteger'](o)||o<0x1||o>0x3e8)){badRequest(d,'limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x201000');return;}const p=e['searchParams']['get']('shard_count'),r=e['searchParams']['get']('shard_index');if(p===null!==(r===null)){badRequest(d,'shard_count\x20and\x20shard_index\x20must\x20be\x20provided\x20together');return;}const s=p===null||r===null?undefined:{'count':Number(p),'index':Number(r)};if(s&&(!Number['isInteger'](s['count'])||s['count']<0x1||!Number['isInteger'](s['index'])||s['index']<0x0||s['index']>=s['count'])){badRequest(d,'Invalid\x20shard\x20selector');return;}const t=await a['projection']['listCurrent']({'chainId':a['chainId'],'kind':l,'cursor':m,'limit':o,'shard':s});json(d,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),...t});return;}if(e['pathname']==='/v1/edges'){const u=e['searchParams']['get']('src'),v=e['searchParams']['get']('dst');if(u===null===(v===null)){badRequest(d,'Provide\x20exactly\x20one\x20of\x20src\x20or\x20dst');return;}const w=u??v;try{wowAddressToBytes(w);}catch{badRequest(d,'Invalid\x20object\x20address');return;}const x=u!==null?await a['projection']['edgesFrom'](a['chainId'],w):await a['projection']['edgesTo'](a['chainId'],w);json(d,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),'direction':u!==null?'out':'in','object_id':w['toLowerCase'](),'edges':x,'orphan_count':x['filter'](y=>!y['dstProjected'])['length']});return;}if(e['pathname']==='/v1/match'){const y=e['searchParams']['get']('kind');if(y!=='Service'&&y!=='Demand'){badRequest(d,'kind\x20must\x20be\x20\x27Service\x27\x20or\x20\x27Demand\x27');return;}const z=e['searchParams']['get']('q')??undefined,A=e['searchParams']['get']('location')??undefined,B=e['searchParams']['get']('industry')??undefined;let C;const D=e['searchParams']['get']('budget');if(D!==null){C=parseWowToWei(D)??undefined;if(C===undefined){badRequest(d,'budget\x20must\x20be\x20a\x20non-negative\x20decimal\x20WOW\x20amount\x20(max\x209\x20fractional\x20digits)');return;}}let E;const F=e['searchParams']['get']('capabilities');if(F!==null){E=F['split'](',')['map'](S=>S['trim']())['filter'](S=>S['length']>0x0);const R=E['filter'](S=>!KNOWN_CAPABILITIES['includes'](S));if(R['length']>0x0){badRequest(d,'Unknown\x20capability:\x20'+R['join'](',\x20')+'\x20(known:\x20'+KNOWN_CAPABILITIES['join'](',\x20')+')');return;}}let G=0x14;const H=e['searchParams']['get']('limit');if(H!==null){G=parsePositiveInt(H)??-0x1;if(!Number['isInteger'](G)||G<0x1||G>0x64){badRequest(d,'limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x20100');return;}}let I=0xc8;const J=e['searchParams']['get']('recall_limit');if(J!==null){I=parsePositiveInt(J)??-0x1;if(!Number['isInteger'](I)||I<0x1||I>0x3e8){badRequest(d,'recall_limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x201000');return;}}const K=e['searchParams']['get']('include_payload');let L=![];if(K!==null){if(K==='1'||K==='true')L=!![];else{if(K!=='0'&&K!=='false'){badRequest(d,'include_payload\x20must\x20be\x20one\x20of\x201,\x20true,\x200,\x20false');return;}}}const M={'kind':y,'q':z,'location':A,'industry':B,'budgetWei':C,'capabilities':E,'limit':G,'recallLimit':I},[N,O]=await Promise['all']([a['projection']['activeFacets'](a['chainId'],y),a['projection']['status'](a['chainId'])]),P=runMatch(N,M);let Q=P['candidates'];if(L&&Q['length']>0x0){const S=await a['projection']['currentPayloads'](a['chainId'],Q['map'](T=>T['object_id']));Q=Q['map'](T=>({...T,'payload_json':S['get'](T['object_id'])??null}));}json(d,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),'coverage':O['coverage'],...P,'candidates':Q});return;}json(d,0x194,{'error':{'code':'NOT_FOUND','message':'Unknown\x20endpoint'}});}catch{json(d,0x1f4,{'error':{'code':'INTERNAL_ERROR','message':'Index\x20query\x20failed'}});}});}
1
+ import{createServer}from'node:http';import{WOW_OBJECT_TYPE_TAGS,wowAddressToBytes}from'@wowok/wowok';import{KNOWN_CAPABILITIES,runMatch}from'./match.js';function json(a,b,c){a['writeHead'](b,{'Content-Type':'application/json;\x20charset=utf-8','Cache-Control':'no-store','X-Content-Type-Options':'nosniff'}),a['end'](JSON['stringify'](c));}function badRequest(a,b){json(a,0x190,{'error':{'code':'BAD_REQUEST','message':b}});}const WOW_DECIMALS=0x9;function parseWowToWei(a){const b=/^(\d+)(?:\.(\d{1,9}))?$/['exec'](a['trim']());if(!b)return null;const c=(b[0x2]??'')['padEnd'](WOW_DECIMALS,'0');return(BigInt(b[0x1])*BigInt(0xa**WOW_DECIMALS)+BigInt(c))['toString']();}function parsePositiveInt(a){return/^\d+$/['test'](a['trim']())?Number(a['trim']()):null;}const AGGREGATE_SHAPES={'Order':{'defaultGroup':'service','groups':['service','machine','owner'],'defaultMetric':'amount','metrics':['amount']}};export function createProjectionApi(a){if(!a['chainId'])throw new Error('chainId\x20is\x20required');const b=a['staleLag']??0x0;if(!Number['isInteger'](b)||b<0x0)throw new Error('Invalid\x20staleLag');const c=a['staleAgeSec']??0x0;if(!Number['isInteger'](c)||c<0x0)throw new Error('Invalid\x20staleAgeSec');return createServer(async(d,e)=>{try{if(d['method']!=='GET'){e['setHeader']('Allow','GET'),json(e,0x195,{'error':{'code':'METHOD_NOT_ALLOWED','message':'GET\x20required'}});return;}const f=new URL(d['url']??'/','http://localhost');if(f['pathname']==='/v1/status'){const [g,h,i,j,k,l]=await Promise['all']([a['projection']['status'](a['chainId']),a['sync']['status'](a['chainId']),a['projection']['watermarks'](a['chainId']),a['head']?a['head']['read']():Promise['resolve'](null),a['sync']['cdcCursors'](a['chainId']),a['projection']['quarantineQueue'](a['chainId'])]);let m=g['max_checkpoint'],n=g['observed_at'];for(const p of h){if(p['state']!=='complete'||!p['checkpoint'])continue;(m===null||BigInt(p['checkpoint'])>BigInt(m))&&(m=p['checkpoint']);const r=p['updatedAt'];r&&(n===null||Date['parse'](r)>Date['parse'](n))&&(n=r);}let o=null;if(j?.['checkpoint']!==null&&j?.['checkpoint']!==undefined&&m!==null){const s=BigInt(j['checkpoint'])-BigInt(m),t=n===null?null:Math['max'](0x0,Math['floor']((Date['now']()-Date['parse'](n))/0x3e8));o={'head_checkpoint':j['checkpoint'],'projection_checkpoint':m,'head_lag':(s>0x0n?s:0x0n)['toString'](),'projection_age_seconds':t,'version_checkpoint':g['max_checkpoint'],'version_observed_at':g['observed_at'],'stale':b>0x0&&s>BigInt(b)||c>0x0&&t!==null&&t>c};}json(e,0xc8,{'chain_id':a['chainId'],'read_only':!![],'generated_at':new Date()['toISOString'](),'projection':g,'sync':h,'watermarks':i,'head':j,'freshness':o,'cdc':k['map'](u=>({...u,'behind_head':j?.['checkpoint']===null||j?.['checkpoint']===undefined?null:((()=>{const v=BigInt(j['checkpoint'])-BigInt(u['checkpoint']);return(v>0x0n?v:0x0n)['toString']();})())})),'quarantine':{'blocking':l['filter'](u=>u['blocking'])['length'],'entries':l}});return;}if(f['pathname']==='/v1/objects'){const u=f['searchParams']['get']('kind')??undefined;if(u&&!(u in WOW_OBJECT_TYPE_TAGS)){badRequest(e,'Unknown\x20object\x20kind:\x20'+u);return;}const v=f['searchParams']['get']('cursor')??undefined;if(v)try{wowAddressToBytes(v);}catch{badRequest(e,'Invalid\x20object\x20cursor');return;}const w=f['searchParams']['get']('limit'),x=w===null?undefined:Number(w);if(x!==undefined&&(!Number['isInteger'](x)||x<0x1||x>0x3e8)){badRequest(e,'limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x201000');return;}const y=f['searchParams']['get']('shard_count'),z=f['searchParams']['get']('shard_index');if(y===null!==(z===null)){badRequest(e,'shard_count\x20and\x20shard_index\x20must\x20be\x20provided\x20together');return;}const A=y===null||z===null?undefined:{'count':Number(y),'index':Number(z)};if(A&&(!Number['isInteger'](A['count'])||A['count']<0x1||!Number['isInteger'](A['index'])||A['index']<0x0||A['index']>=A['count'])){badRequest(e,'Invalid\x20shard\x20selector');return;}const B=await a['projection']['listCurrent']({'chainId':a['chainId'],'kind':u,'cursor':v,'limit':x,'shard':A});json(e,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),...B});return;}if(f['pathname']==='/v1/edges'){const C=f['searchParams']['get']('src'),D=f['searchParams']['get']('dst');if(C===null===(D===null)){badRequest(e,'Provide\x20exactly\x20one\x20of\x20src\x20or\x20dst');return;}const E=C??D;try{wowAddressToBytes(E);}catch{badRequest(e,'Invalid\x20object\x20address');return;}const F=C!==null?await a['projection']['edgesFrom'](a['chainId'],E):await a['projection']['edgesTo'](a['chainId'],E);json(e,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),'direction':C!==null?'out':'in','object_id':E['toLowerCase'](),'edges':F,'orphan_count':F['filter'](G=>!G['dstProjected'])['length']});return;}if(f['pathname']==='/v1/match'){const G=f['searchParams']['get']('kind');if(G!=='Service'&&G!=='Demand'){badRequest(e,'kind\x20must\x20be\x20\x27Service\x27\x20or\x20\x27Demand\x27');return;}const H=f['searchParams']['get']('q')??undefined,I=f['searchParams']['get']('location')??undefined,J=f['searchParams']['get']('industry')??undefined;let K;const L=f['searchParams']['get']('budget');if(L!==null){K=parseWowToWei(L)??undefined;if(K===undefined){badRequest(e,'budget\x20must\x20be\x20a\x20non-negative\x20decimal\x20WOW\x20amount\x20(max\x209\x20fractional\x20digits)');return;}}let M;const N=f['searchParams']['get']('capabilities');if(N!==null){M=N['split'](',')['map'](a0=>a0['trim']())['filter'](a0=>a0['length']>0x0);const Z=M['filter'](a0=>!KNOWN_CAPABILITIES['includes'](a0));if(Z['length']>0x0){badRequest(e,'Unknown\x20capability:\x20'+Z['join'](',\x20')+'\x20(known:\x20'+KNOWN_CAPABILITIES['join'](',\x20')+')');return;}}let O=0x14;const P=f['searchParams']['get']('limit');if(P!==null){O=parsePositiveInt(P)??-0x1;if(!Number['isInteger'](O)||O<0x1||O>0x64){badRequest(e,'limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x20100');return;}}let Q=0xc8;const R=f['searchParams']['get']('recall_limit');if(R!==null){Q=parsePositiveInt(R)??-0x1;if(!Number['isInteger'](Q)||Q<0x1||Q>0x3e8){badRequest(e,'recall_limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x201000');return;}}const S=f['searchParams']['get']('include_payload');let T=![];if(S!==null){if(S==='1'||S==='true')T=!![];else{if(S!=='0'&&S!=='false'){badRequest(e,'include_payload\x20must\x20be\x20one\x20of\x201,\x20true,\x200,\x20false');return;}}}const U={'kind':G,'q':H,'location':I,'industry':J,'budgetWei':K,'capabilities':M,'limit':O,'recallLimit':Q},[V,W]=await Promise['all']([a['projection']['activeFacets'](a['chainId'],G),a['projection']['status'](a['chainId'])]),X=runMatch(V,U);let Y=X['candidates'];if(T&&Y['length']>0x0){const a0=await a['projection']['currentPayloads'](a['chainId'],Y['map'](a1=>a1['object_id']));Y=Y['map'](a1=>({...a1,'payload_json':a0['get'](a1['object_id'])??null}));}json(e,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),'coverage':W['coverage'],...X,'candidates':Y});return;}if(f['pathname']==='/v1/aggregate'){const a1=f['searchParams']['get']('kind')??'',a2=AGGREGATE_SHAPES[a1];if(!a2){badRequest(e,'Unknown\x20aggregate\x20kind:\x20'+(a1||'(missing)')+'\x20(known:\x20'+Object['keys'](AGGREGATE_SHAPES)['join'](',\x20')+')');return;}const a3=f['searchParams']['get']('group')??a2['defaultGroup'];if(!a2['groups']['includes'](a3)){badRequest(e,'Unknown\x20group\x20field:\x20'+a3+'\x20(known\x20for\x20'+a1+':\x20'+a2['groups']['join'](',\x20')+')');return;}const a4=f['searchParams']['get']('metric')??a2['defaultMetric'];if(!a2['metrics']['includes'](a4)){badRequest(e,'Unknown\x20metric\x20field:\x20'+a4+'\x20(known\x20for\x20'+a1+':\x20'+a2['metrics']['join'](',\x20')+')');return;}let a5;const a6=f['searchParams']['get']('group_id');if(a6!==null){try{wowAddressToBytes(a6);}catch{badRequest(e,'Invalid\x20group_id\x20address');return;}a5=a6;}const a7=f['searchParams']['get']('exclude_claimed');let a8=![];if(a7!==null){if(a7==='1'||a7==='true')a8=!![];else{if(a7!=='0'&&a7!=='false'){badRequest(e,'exclude_claimed\x20must\x20be\x20one\x20of\x201,\x20true,\x200,\x20false');return;}}}let a9=0x32;const aa=f['searchParams']['get']('limit');if(aa!==null){a9=parsePositiveInt(aa)??-0x1;if(!Number['isInteger'](a9)||a9<0x1||a9>0x3e8){badRequest(e,'limit\x20must\x20be\x20an\x20integer\x20between\x201\x20and\x201000');return;}}const [ab,ac]=await Promise['all']([a['projection']['aggregate'](a['chainId'],{'chainId':a['chainId'],'group':a3,'groupId':a5,'metric':a4,'excludeClaimed':a8,'limit':a9}),a['projection']['status'](a['chainId'])]);json(e,0xc8,{'chain_id':a['chainId'],'generated_at':new Date()['toISOString'](),'kind':a1,'group':a3,'group_id':a5??null,'metric':a4,'exclude_claimed':a8,...ab,'coverage':ac['coverage']});return;}json(e,0x194,{'error':{'code':'NOT_FOUND','message':'Unknown\x20endpoint'}});}catch{json(e,0x1f4,{'error':{'code':'INTERNAL_ERROR','message':'Index\x20query\x20failed'}});}});}
@@ -1,6 +1,6 @@
1
1
  import { type WowTypedObjectKind } from "@wowok/wowok";
2
2
  import { Pool } from "pg";
3
- import type { ApplyProjectionResult, CurrentObjectPage, GraphEdgeView, ObjectFacetRow, ObjectVersionFact, ProjectionStatus, ProjectionWatermark, RecordReconciliationOptions, RecordReconciliationResult, ReconciliationGeneration } from "./types.js";
3
+ import type { AggregateAnswer, AggregateOptions, ApplyProjectionResult, CurrentObjectPage, GraphEdgeView, ObjectFacetRow, ObjectVersionFact, ProjectionStatus, ProjectionWatermark, QuarantineEntry, RecordReconciliationOptions, RecordReconciliationResult, ReconciliationGeneration } from "./types.js";
4
4
  export interface ListCurrentObjectsOptions {
5
5
  chainId: string;
6
6
  kind?: WowTypedObjectKind;
@@ -40,10 +40,12 @@ export declare class PostgresProjectionStore {
40
40
  }>;
41
41
  activeFacets(chainId: string, kind?: string): Promise<ObjectFacetRow[]>;
42
42
  currentPayloads(chainId: string, objectIds: string[]): Promise<Map<string, Record<string, unknown> | null>>;
43
+ aggregate(chainId: string, options: AggregateOptions): Promise<AggregateAnswer>;
43
44
  recordReconciliation(options: RecordReconciliationOptions): Promise<RecordReconciliationResult>;
44
45
  reconciliationSummary(chainId: string): Promise<ReconciliationGeneration[]>;
45
46
  private reconciledThrough;
46
47
  status(chainId: string): Promise<ProjectionStatus>;
47
48
  watermarks(chainId: string): Promise<ProjectionWatermark[]>;
49
+ quarantineQueue(chainId: string, limit?: number): Promise<QuarantineEntry[]>;
48
50
  listCurrent(options: ListCurrentObjectsOptions): Promise<CurrentObjectPage>;
49
51
  }