@wowok/agent-mcp 3.0.0 → 3.0.2

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 (245) hide show
  1. package/dist/communication/evidence.d.ts +6 -0
  2. package/dist/communication/evidence.js +1 -0
  3. package/dist/evaluation/acceptance.d.ts +24 -0
  4. package/dist/evaluation/acceptance.js +1 -0
  5. package/dist/evaluation/builtins/demand-match.d.ts +3 -2
  6. package/dist/evaluation/builtins/demand-match.js +1 -1
  7. package/dist/evaluation/builtins/service-risk.d.ts +2 -1
  8. package/dist/evaluation/builtins/service-risk.js +1 -1
  9. package/dist/evaluation/index.d.ts +1 -0
  10. package/dist/evaluation/index.js +1 -1
  11. package/dist/evaluation/match-operation.d.ts +14 -0
  12. package/dist/evaluation/match-operation.js +1 -0
  13. package/dist/experience/realtime-feedback.js +1 -1
  14. package/dist/extensions/modes.js +1 -1
  15. package/dist/goal/GoalClassifier.js +1 -1
  16. package/dist/goal/GoalEngine.d.ts +8 -0
  17. package/dist/goal/GoalEngine.js +1 -1
  18. package/dist/goal/types.d.ts +1 -1
  19. package/dist/harness/auto-escalation.d.ts +0 -12
  20. package/dist/harness/auto-escalation.js +1 -1
  21. package/dist/harness/index.d.ts +1 -14
  22. package/dist/harness/index.js +1 -1
  23. package/dist/harness/types.d.ts +0 -38
  24. package/dist/intent/types.d.ts +1 -1
  25. package/dist/intent/types.js +1 -1
  26. package/dist/keeper/KeeperScan.d.ts +39 -0
  27. package/dist/keeper/KeeperScan.js +1 -0
  28. package/dist/keeper/KeeperStore.d.ts +43 -0
  29. package/dist/keeper/KeeperStore.js +1 -0
  30. package/dist/keeper/detectors.d.ts +23 -0
  31. package/dist/keeper/detectors.js +1 -0
  32. package/dist/keeper/keeper.spec.d.ts +1 -0
  33. package/dist/keeper/keeper.spec.js +1 -0
  34. package/dist/keeper/types.d.ts +65 -0
  35. package/dist/keeper/types.js +1 -0
  36. package/dist/knowledge/demand-risk.js +1 -1
  37. package/dist/knowledge/event-semantics.d.ts +3 -0
  38. package/dist/knowledge/event-semantics.js +1 -1
  39. package/dist/knowledge/event-semantics.spec.d.ts +1 -0
  40. package/dist/knowledge/event-semantics.spec.js +1 -0
  41. package/dist/knowledge/evidence-review.d.ts +23 -0
  42. package/dist/knowledge/evidence-review.js +1 -1
  43. package/dist/knowledge/examples-scanner-cli.js +1 -1
  44. package/dist/knowledge/examples-scanner.js +1 -1
  45. package/dist/knowledge/guard-bytecode-spec.d.ts +82 -0
  46. package/dist/knowledge/guard-bytecode-spec.js +1 -0
  47. package/dist/knowledge/guard-design-patterns.d.ts +1 -1
  48. package/dist/knowledge/guard-design-patterns.js +1 -1
  49. package/dist/knowledge/index.d.ts +10 -6
  50. package/dist/knowledge/index.js +1 -1
  51. package/dist/knowledge/industry-registry.js +1 -1
  52. package/dist/knowledge/mcp-schema-audit-cli.js +1 -1
  53. package/dist/knowledge/mcp-schema-audit.js +1 -1
  54. package/dist/knowledge/migration-preflight.d.ts +27 -0
  55. package/dist/knowledge/migration-preflight.js +1 -0
  56. package/dist/knowledge/scenario-modes.d.ts +1 -1
  57. package/dist/knowledge/scenario-modes.js +1 -1
  58. package/dist/knowledge/template-registry.js +1 -1
  59. package/dist/knowledge/tools-reference.js +1 -1
  60. package/dist/knowledge/workflow-guidance.d.ts +20 -0
  61. package/dist/knowledge/workflow-guidance.js +1 -1
  62. package/dist/monitor/MonitorLoop.d.ts +1 -0
  63. package/dist/monitor/MonitorLoop.js +1 -1
  64. package/dist/monitor/ScopeResolver.js +1 -1
  65. package/dist/monitor/SuggestionBridge.d.ts +1 -1
  66. package/dist/monitor/SuggestionBridge.js +1 -1
  67. package/dist/monitor/SuggestionBridge.spec.d.ts +1 -0
  68. package/dist/monitor/SuggestionBridge.spec.js +1 -0
  69. package/dist/monitor/normalize.js +1 -1
  70. package/dist/monitor/types.d.ts +0 -1
  71. package/dist/monitor/types.js +1 -1
  72. package/dist/participation/employee-kpi.d.ts +12 -0
  73. package/dist/participation/employee-kpi.js +1 -1
  74. package/dist/participation/employee-kpi.spec.d.ts +1 -0
  75. package/dist/participation/employee-kpi.spec.js +1 -0
  76. package/dist/playbooks/service-build/business-puzzle.js +1 -1
  77. package/dist/playbooks/service-build/mode-actions.d.ts +19 -6
  78. package/dist/playbooks/service-build/mode-actions.js +1 -1
  79. package/dist/playbooks/service-build/relationship-profile.js +1 -1
  80. package/dist/relationship/derivation.d.ts +6 -0
  81. package/dist/relationship/derivation.js +1 -1
  82. package/dist/relationship/derivation.spec.d.ts +1 -0
  83. package/dist/relationship/derivation.spec.js +1 -0
  84. package/dist/role/index.d.ts +2 -2
  85. package/dist/role/index.js +1 -1
  86. package/dist/role/model.d.ts +2 -1
  87. package/dist/role/model.js +1 -1
  88. package/dist/role/types.d.ts +5 -0
  89. package/dist/rules.d.ts +1 -1
  90. package/dist/safety/confirm-gate.js +1 -1
  91. package/dist/schema/call/semantic.js +1 -1
  92. package/dist/schema/common/index.js +1 -1
  93. package/dist/schema/employee/index.d.ts +61 -1
  94. package/dist/schema/employee/index.js +1 -1
  95. package/dist/schema/evaluation/index.d.ts +70 -5
  96. package/dist/schema/evaluation/index.js +1 -1
  97. package/dist/schema/index.d.ts +1 -0
  98. package/dist/schema/index.js +1 -1
  99. package/dist/schema/industry-pack/index.d.ts +43 -7
  100. package/dist/schema/industry-pack/modes.d.ts +42 -6
  101. package/dist/schema/industry-pack/modes.js +1 -1
  102. package/dist/schema/intent-radar/index.d.ts +3 -0
  103. package/dist/schema/intent-radar/index.js +1 -1
  104. package/dist/schema/keeper/index.d.ts +475 -0
  105. package/dist/schema/keeper/index.js +1 -0
  106. package/dist/schema/local/index.js +1 -1
  107. package/dist/schema/messenger/index.d.ts +2 -0
  108. package/dist/schema/messenger/index.js +1 -1
  109. package/dist/schema/operations.d.ts +34 -0
  110. package/dist/schema/query/bi.d.ts +188 -0
  111. package/dist/schema/query/bi.js +1 -1
  112. package/dist/schema/query/index.d.ts +48 -48
  113. package/dist/schema/query/index.js +1 -1
  114. package/dist/schema/schema-query/index.d.ts +2 -11
  115. package/dist/schema/schema-query/index.js +1 -1
  116. package/dist/schema/schema-version.js +1 -1
  117. package/dist/schema/utils/skills-recommendation.js +1 -1
  118. package/dist/schema/watch/index.d.ts +4 -0
  119. package/dist/schema/watch/index.js +1 -1
  120. package/dist/schema-query-impl/index.d.ts +33 -14
  121. package/dist/schema-query-impl/index.js +1 -1
  122. package/dist/schemas/employee_operation.output.json +100 -0
  123. package/dist/schemas/employee_operation.schema.json +148 -5
  124. package/dist/schemas/evaluation_operation.output.json +135 -9
  125. package/dist/schemas/evaluation_operation.schema.json +176 -7
  126. package/dist/schemas/index.json +7 -1
  127. package/dist/schemas/industry_pack_operation.output.json +158 -32
  128. package/dist/schemas/intent_radar.output.json +2 -0
  129. package/dist/schemas/intent_radar.schema.json +1 -0
  130. package/dist/schemas/keeper_operation.output.json +1274 -0
  131. package/dist/schemas/keeper_operation.schema.json +359 -0
  132. package/dist/schemas/messenger_operation.schema.json +8 -0
  133. package/dist/schemas/onchain_events.output.json +55 -11
  134. package/dist/schemas/onchain_events.schema.json +4 -0
  135. package/dist/schemas/onchain_table_data.output.json +59 -0
  136. package/dist/schemas/query_toolkit.output.json +428 -0
  137. package/dist/schemas/query_toolkit.schema.json +59 -0
  138. package/dist/schemas/schema_query.output.json +1 -64
  139. package/dist/schemas/schema_query.schema.json +18 -3
  140. package/dist/schemas/watch_operation.output.json +21 -1
  141. package/dist/task/playbook.js +1 -1
  142. package/dist/task/types.d.ts +1 -1
  143. package/dist/tools/handlers/bridge.js +1 -1
  144. package/dist/tools/handlers/config.js +1 -1
  145. package/dist/tools/handlers/employee.d.ts +6 -0
  146. package/dist/tools/handlers/employee.js +1 -1
  147. package/dist/tools/handlers/employee.spec.d.ts +1 -0
  148. package/dist/tools/handlers/employee.spec.js +1 -0
  149. package/dist/tools/handlers/evaluation.js +1 -1
  150. package/dist/tools/handlers/evaluation.spec.d.ts +1 -0
  151. package/dist/tools/handlers/evaluation.spec.js +1 -0
  152. package/dist/tools/handlers/intent-radar.js +1 -1
  153. package/dist/tools/handlers/keeper.d.ts +12 -0
  154. package/dist/tools/handlers/keeper.js +1 -0
  155. package/dist/tools/handlers/messenger.js +1 -1
  156. package/dist/tools/handlers/onchain.js +1 -1
  157. package/dist/tools/handlers/query.js +1 -1
  158. package/dist/tools/handlers/schema-query.js +1 -1
  159. package/dist/tools/handlers/watch.js +1 -1
  160. package/dist/tools/handlers/workflow.js +1 -1
  161. package/dist/tools/index.js +1 -1
  162. package/dist/tools/registry/agent.d.ts +2 -0
  163. package/dist/tools/registry/agent.js +1 -0
  164. package/dist/tools/registry/bridge.d.ts +2 -0
  165. package/dist/tools/registry/bridge.js +1 -0
  166. package/dist/tools/registry/business.d.ts +2 -0
  167. package/dist/tools/registry/business.js +1 -0
  168. package/dist/tools/registry/config.d.ts +2 -0
  169. package/dist/tools/registry/config.js +1 -0
  170. package/dist/tools/registry/files.d.ts +2 -0
  171. package/dist/tools/registry/files.js +1 -0
  172. package/dist/tools/registry/identity.d.ts +2 -0
  173. package/dist/tools/registry/identity.js +1 -0
  174. package/dist/tools/registry/local.d.ts +2 -0
  175. package/dist/tools/registry/local.js +1 -0
  176. package/dist/tools/registry/messenger.d.ts +2 -0
  177. package/dist/tools/registry/messenger.js +1 -0
  178. package/dist/tools/registry/monitor.d.ts +2 -0
  179. package/dist/tools/registry/monitor.js +1 -0
  180. package/dist/tools/registry/onchain.d.ts +2 -0
  181. package/dist/tools/registry/onchain.js +1 -0
  182. package/dist/tools/registry/query.d.ts +2 -0
  183. package/dist/tools/registry/query.js +1 -0
  184. package/dist/tools/registry/trust.d.ts +2 -0
  185. package/dist/tools/registry/trust.js +1 -0
  186. package/dist/tools/shared.js +1 -1
  187. package/dist/tools/wrap.js +1 -1
  188. package/package.json +2 -2
  189. package/dist/examples/arbitration-dispute-create.json +0 -41
  190. package/dist/examples/arbitration-vote-weighted.json +0 -35
  191. package/dist/examples/arbitration-voting-guard-add.json +0 -38
  192. package/dist/examples/demand-present-service.json +0 -33
  193. package/dist/examples/education-contact-create.json +0 -40
  194. package/dist/examples/freelance-contact-create.json +0 -40
  195. package/dist/examples/gen-passport-verify-guard.json +0 -48
  196. package/dist/examples/guard-template-balance-check.json +0 -59
  197. package/dist/examples/guard-template-time-lock.json +0 -60
  198. package/dist/examples/insurance-guard-claim-timelock.json +0 -75
  199. package/dist/examples/insurance-guard-withdraw-allocation.json +0 -96
  200. package/dist/examples/insurance-machine-create.json +0 -75
  201. package/dist/examples/insurance-service-allocators.json +0 -55
  202. package/dist/examples/machine-multisig-threshold.json +0 -87
  203. package/dist/examples/machine-publish.json +0 -30
  204. package/dist/examples/machine-template-7node-rental.json +0 -119
  205. package/dist/examples/payment-scenario-bound.json +0 -45
  206. package/dist/examples/rental-ziroom-machine-create.json +0 -148
  207. package/dist/examples/rental-ziroom-permission-create.json +0 -41
  208. package/dist/examples/rental-ziroom-service-create.json +0 -36
  209. package/dist/examples/retail-adv-guard-customer-win-create.json +0 -80
  210. package/dist/examples/retail-adv-guard-messenger-proof-create.json +0 -65
  211. package/dist/examples/retail-adv-guard-reward-timeout-create.json +0 -92
  212. package/dist/examples/retail-adv-reward-guard-add.json +0 -51
  213. package/dist/examples/retail-myshop-allocation-activate.json +0 -55
  214. package/dist/examples/retail-myshop-arbitration-create.json +0 -40
  215. package/dist/examples/retail-myshop-contact-create.json +0 -43
  216. package/dist/examples/retail-myshop-order-create.json +0 -56
  217. package/dist/examples/retail-myshop-progress-operate.json +0 -38
  218. package/dist/examples/retail-myshop-reward-create.json +0 -35
  219. package/dist/examples/retail-myshop-service-create.json +0 -38
  220. package/dist/examples/retail-myshop-service-customer-required.json +0 -31
  221. package/dist/examples/service-discount-issue.json +0 -46
  222. package/dist/examples/subscription-contact-create.json +0 -40
  223. package/dist/examples/threebody-guard-create.json +0 -56
  224. package/dist/examples/threebody-machine-create.json +0 -71
  225. package/dist/examples/threebody-permission-create.json +0 -38
  226. package/dist/examples/threebody-service-allocators.json +0 -48
  227. package/dist/examples/travel-guard-time-lock.json +0 -69
  228. package/dist/examples/travel-guard-weather-oracle.json +0 -70
  229. package/dist/examples/travel-machine-create.json +0 -135
  230. package/dist/examples/travel-repository-create.json +0 -47
  231. package/dist/examples/travel-service-create.json +0 -34
  232. package/dist/examples/travel-treasury-create.json +0 -34
  233. package/dist/examples/treasury-deposit.json +0 -37
  234. package/dist/examples/treasury-withdraw.json +0 -38
  235. package/dist/harness/plan.d.ts +0 -33
  236. package/dist/harness/plan.js +0 -1
  237. package/dist/knowledge/demand-matching.d.ts +0 -29
  238. package/dist/knowledge/demand-matching.js +0 -1
  239. package/dist/knowledge/guard-context.d.ts +0 -56
  240. package/dist/knowledge/guard-context.js +0 -1
  241. package/dist/knowledge/guard-migration.d.ts +0 -48
  242. package/dist/knowledge/guard-migration.js +0 -1
  243. package/dist/schemas/guard-node-schema.json +0 -1000
  244. package/dist/task/stage-gate.d.ts +0 -22
  245. package/dist/task/stage-gate.js +0 -1
@@ -234,4 +234,24 @@ export declare function accountCanExecuteForward(f: ParsedForward, account: stri
234
234
  name: string;
235
235
  operators: string[];
236
236
  }[], orderCtx: OrderContext | undefined, permCtx: PermissionContext | undefined): boolean;
237
+ export type ForwardOperatorKind = "order_holder" | "named_operator" | "permission_index";
238
+ export declare function forwardOperatorKind(f: ParsedForward): ForwardOperatorKind;
239
+ export interface ActionableForwardOption {
240
+ next_node: string;
241
+ forward: string;
242
+ weight: number;
243
+ threshold: number;
244
+ guard?: string;
245
+ operator_kind: ForwardOperatorKind;
246
+ permission_index?: number;
247
+ named_operator?: string;
248
+ executable_accounts: string[];
249
+ }
250
+ export declare function enumerateActionableForwards(progress: {
251
+ current?: unknown;
252
+ session?: unknown;
253
+ }, nodes: ParsedMachineNode[], accounts: string[], progressNamedOperator: {
254
+ name: string;
255
+ operators: string[];
256
+ }[], orderCtx: OrderContext | undefined, permCtx: PermissionContext | undefined): ActionableForwardOption[];
237
257
  export {};
@@ -1 +1 @@
1
- import{query_objects,query_table,query_account_list,LocalMark,GetLocalNamesByAddresses,bcs,deriveDynamicFieldID,queryOrdersByUser,objectTypeFromAddress,ObjectType}from'@wowok/wowok';import{REPOSITORY_PERMISSIONS,REWARD_PERMISSIONS,MACHINE_PERMISSIONS,PROGRESS_PERMISSIONS,TREASURY_PERMISSIONS,SERVICE_PERMISSIONS,ARBITRATION_PERMISSIONS,DEMAND_PERMISSIONS,CONTACT_PERMISSIONS}from'./permission-ledger.js';import{formatShortAddress}from'../persona/address-format.js';const BUILTIN_PERMISSION_MAP=new Map();for(const entry of[...REPOSITORY_PERMISSIONS,...REWARD_PERMISSIONS,...MACHINE_PERMISSIONS,...PROGRESS_PERMISSIONS,...TREASURY_PERMISSIONS,...SERVICE_PERMISSIONS,...ARBITRATION_PERMISSIONS,...DEMAND_PERMISSIONS,...CONTACT_PERMISSIONS]){BUILTIN_PERMISSION_MAP['set'](entry['index'],entry['name']);}export function resolvePermissionRole(a,b){if(a===undefined||a===null)return'unknown\x20role';if(b){const d=/([A-Za-z][A-Za-z0-9_]*)\s*=\s*(\d+)/g;let e;while((e=d['exec'](b))!==null){if(Number(e[0x2])===a)return e[0x1]+'\x20(permission\x20'+a+')';}}const c=BUILTIN_PERMISSION_MAP['get'](a);if(c)return c+'\x20(permission\x20'+a+')';return'permission\x20'+a;}export const QUERY_OBJECTS_BATCH=0x32;export async function fetchTableEntries(a,b){const c=[],d=b?.['maxItems'];let e=![],f=undefined;for(;;){const g=await query_table({'parent':a,'cursor':f??undefined,'limit':b?.['limit'],'no_cache':b?.['noCache'],'network':b?.['network']});for(const i of g?.['items']??[]){if(d!==undefined&&c['length']>=d)break;const j=String(i?.['object']??'');if(!j['startsWith']('0x'))continue;c['push']({'key':String(i?.['key']?.['value']??''),'objectId':j});}const h=g?.['hasNextPage']===!![]&&!!g?.['nextCursor'];if(d!==undefined&&c['length']>=d){e=h;break;}if(!h)break;f=String(g['nextCursor']);}return{'entries':c,'truncated':e};}export async function fetchAllFieldObjectIds(a,b,c){const {entries:d}=await fetchTableEntries(a,{'network':b,'noCache':c});return d['map'](f=>f['objectId']);}export async function batchQueryObjectsByIds(a,b,c){const d=[];for(let e=0x0;e<a['length'];e+=QUERY_OBJECTS_BATCH){const f=a['slice'](e,e+QUERY_OBJECTS_BATCH),g=await query_objects({'objects':f,'no_cache':c,'network':b});d['push'](...g?.['objects']??[]);}return d;}export async function batchQueryTableItems(a,b){const {entries:c,truncated:d}=await fetchTableEntries(a,b),e=c['length']>0x0?await batchQueryObjectsByIds(c['map'](h=>h['objectId']),b?.['network'],b?.['noCache']):[],f=new Map();for(const h of e){const i=String(h?.['object']??'')['toLowerCase']();if(i)f['set'](i,h);}const g=c['map'](j=>({...j,'object':f['get'](j['objectId']['toLowerCase']())}));return{'items':g,'truncated':d};}export async function fetchMachineNodes(a,b,c){const d=await query_objects({'objects':[a],'no_cache':c,'network':b}),e=d?.['objects']?.[0x0],f=e?.['object']??(typeof a==='string'&&a['startsWith']('0x')?a:undefined);if(!f)return[];const {items:g}=await batchQueryTableItems(f,{'network':b,'noCache':c});return g['map'](h=>h['object'])['filter'](h=>h?.['type']==='TableItem_MachineNode')['map'](h=>{const i=h?.['data']??h,j=typeof i?.['name']==='string'?i['name']:'',k=Array['isArray'](i?.['value'])?i['value']:Array['isArray'](i?.['pairs'])?i['pairs']:[];if(!j)return null;return{'name':j,'pairs':k['map'](l=>({'prev_node':String(l?.['prev_node']??''),'threshold':Number(l?.['threshold']??0x0),'forwards':Array['isArray'](l?.['forwards'])?l['forwards']['map'](m=>{const n=typeof m?.['guard']==='object'&&m?.['guard']!==null?m['guard']['guard']??undefined:typeof m?.['guard']==='string'?m['guard']:undefined;return{'name':String(m?.['name']??''),'weight':Number(m?.['weight']??0x0),'namedOperator':m?.['namedOperator']!==undefined&&m?.['namedOperator']!==null?String(m['namedOperator']):undefined,'permissionIndex':m?.['permissionIndex']!==undefined&&m?.['permissionIndex']!==null?Number(m['permissionIndex']):undefined,'guard':n};}):[]}))};})['filter'](h=>h!==null);}const COMPLETE_RE=/(^|_)(completed?|done|finished|received|delivered|accepted|confirmed|finalized|success|approved)(_|$)/i,REFUND_RE=/(^|_)(cancel(led)?|refund(ed)?|return(ed|_approved)?)(_|$)/i,EXCEPTION_RE=/(^|_)(interrupt(ed)?|exception|dispute(d)?|fail(ed)?|abort(ed)?|reject(ed)?)(_|$)/i;function classifyNode(a){if(COMPLETE_RE['test'](a))return'complete';if(REFUND_RE['test'](a))return'refund';if(EXCEPTION_RE['test'](a))return'exception';return'advance';}function businessMeaning(a,b){switch(b){case'complete':return'Service/deliverable\x20accepted\x20at\x20\x22'+a+'\x22\x20—\x20triggers\x20settlement\x20allocation\x20(funds\x20released\x20to\x20the\x20provider)';case'refund':return'Order\x20cancelled/returned\x20at\x20\x22'+a+'\x22\x20—\x20triggers\x20refund\x20allocation\x20(funds\x20back\x20to\x20the\x20customer)';case'exception':return'Exception\x20path\x20at\x20\x22'+a+'\x22\x20—\x20typically\x20routes\x20to\x20arbitration\x20or\x20partial-refund\x20handling';default:return'Progress\x20to\x20\x22'+a+'\x22';}}function shortAddr(a){if(!a)return undefined;return formatShortAddress(a);}function callerIsOrderHolder(a,b){if(!a||!b?.['length'])return![];const d=a['toLowerCase']();return b['some'](e=>e?.['toLowerCase']()===d);}function resolveOperator(a,b,c,d){if(a['namedOperator']===''){const e=b?.[0x0];return{'kind':'order_holder','role_name':'order\x20holder\x20(customer)','account_name':d?d(e):shortAddr(e)};}if(typeof a['namedOperator']==='string'&&a['namedOperator']['length']>0x0)return{'kind':'named_operator','named_operator':a['namedOperator'],'role_name':'named\x20operator\x20\x22'+a['namedOperator']+'\x22'};if(a['permissionIndex']!==undefined&&a['permissionIndex']!==null)return{'kind':'permission_index','permission_index':a['permissionIndex'],'role_name':resolvePermissionRole(a['permissionIndex'],c)};return{'kind':'order_holder','role_name':'unknown\x20operator'};}function gainsRisksFor(a,b,c){if(!c)return{'gains':[],'risks':[]};if(b)switch(a){case'complete':return{'gains':['Flow\x20advances','Settlement\x20triggered\x20(funds\x20released)'],'risks':['Funds\x20released\x20to\x20provider','Refund\x20leverage\x20lost\x20—\x20confirm\x20only\x20if\x20service\x20verified']};case'refund':return{'gains':['Funds\x20returned\x20to\x20you'],'risks':['If\x20service\x20was\x20already\x20rendered,\x20cancellation\x20may\x20be\x20disputed']};case'exception':return{'gains':['Avoids\x20stalemate'],'risks':['May\x20trigger\x20arbitration\x20/\x20reputation\x20impact']};default:return{'gains':['Flow\x20advances'],'risks':[]};}switch(a){case'complete':return{'gains':['Settlement\x20triggered\x20—\x20funds\x20released\x20to\x20provider'],'risks':[]};case'refund':return{'gains':['Clean\x20closure'],'risks':['Lost\x20revenue\x20for\x20this\x20order']};case'exception':return{'gains':['Avoids\x20stalemate'],'risks':['May\x20trigger\x20arbitration\x20/\x20compensation\x20fund']};default:return{'gains':['Flow\x20advances'],'risks':[]};}}function consistencyFor(a,b,c,d,e){let f;if(!e)f=a==='exception'?0x2d:0x32;else b?f=a==='refund'?0x46:a==='complete'?0x37:a==='exception'?0x23:0x32:f=a==='complete'?0x4b:a==='refund'?0x1e:a==='exception'?0x23:0x32;if(e&&c)f+=0x14;if(d)f-=0xa;return Math['max'](0x0,Math['min'](0x64,f));}export function buildWorkflowGuidance(a){const b=[];for(const i of a['nodes']){for(const j of i['pairs']){if(j['prev_node']!==a['current'])continue;for(const k of j['forwards']){if(!k['name'])continue;const l=resolveOperator(k,a['orderHolderAddresses'],a['permissionDescription'],a['nameResolver']),m=callerIsOrderHolder(a['callerAddress']??a['caller'],a['orderHolderAddresses']);let n=![];a['callerAddress']&&(n=accountCanExecuteForward(k,a['callerAddress'],a['progressNamedOperator']??[],a['orderContext'],a['permissionContext']));const p=classifyNode(i['name']),q=!!a['caller'],{gains:r,risks:s}=gainsRisksFor(p,m,q),t=consistencyFor(p,m,n,!!k['guard'],q);b['push']({'next_node':i['name'],'forward':k['name'],'weight':k['weight'],'operator':l,'guard':k['guard'],'business_meaning':businessMeaning(i['name'],p),'gains':r,'risks':s,'consistency':t,'recommended':![]});}}}if(b['length']===0x0)return{'current_node':a['current'],'caller':a['caller'],'options':[],'note':'Node\x20\x22'+a['current']+'\x22\x20has\x20no\x20outgoing\x20forwards\x20—\x20it\x20is\x20a\x20terminal\x20node\x20(or\x20the\x20workflow\x20is\x20stuck).\x20No\x20further\x20progress\x20operation\x20is\x20available\x20here.'};b['sort']((u,v)=>v['consistency']-u['consistency']);const c=b[0x0];b[0x0]={...c,'recommended':!![]};const d=[];for(const u of b){u!==c&&u['consistency']>0x0&&u['forward']!==c['forward']&&d['push']('Choosing\x20\x22'+u['forward']+'\x20→\x20'+u['next_node']+'\x22\x20forfeits\x20the\x20faster/more\x20aligned\x20path\x20\x22'+c['forward']+'\x20→\x20'+c['next_node']+'\x22');}const e=[],g=b['filter'](v=>v['operator']['kind']==='order_holder'&&v['forward']!==c['forward']&&c['forward']!==v['forward']),h=b['filter'](v=>v['operator']['account_name']&&v['operator']['account_name']!==a['caller']);return h['length']>0x0&&!b['some'](v=>v['recommended']&&v['operator']['account_name']===a['caller'])&&e['push']('The\x20recommended\x20action\x20is\x20executed\x20by\x20another\x20account\x20('+h[0x0]['operator']['account_name']+');\x20switch\x20the\x20signing\x20account\x20(env.account)\x20before\x20operating.'),{'current_node':a['current'],'caller':a['caller'],'options':b,'recommendation':{'best':c['forward']+'\x20→\x20'+c['next_node'],'rationale':'Highest\x20consistency\x20('+c['consistency']+'/100)\x20with\x20the\x20caller\x27s\x20interests.\x20Gains:\x20'+(c['gains']['join'](';\x20')||'none')+'.\x20Risks:\x20'+(c['risks']['join'](';\x20')||'none')+'.\x20Operator:\x20'+(c['operator']['role_name']??c['operator']['kind'])+(c['operator']['account_name']?'\x20('+c['operator']['account_name']+')':'')+'.'+(c['guard']?'\x20Guard\x20to\x20satisfy:\x20'+c['guard']+'.':''),'caveat':d['length']?d['join']('.\x20'):undefined},'note':e['length']?e['join']('\x20'):undefined};}export function buildWorkflowReceipt(a){const b=a['current']===a['targetNode'],c={'account':a['callerName'],'action':a['callerName']+'\x20executed\x20'+a['forward']+'\x20(→\x20'+a['targetNode']+')','forward':a['forward'],'target_node':a['targetNode'],'op':a['op'],'migrated':b,'current_node':a['current']};if(!b){const e=a['nodes']['filter'](j=>j['name']===a['targetNode'])['flatMap'](j=>j['pairs'])['find'](j=>j['prev_node']===a['current']),g=a['session']?.['slice'](-0x1)[0x0],h=g?.['threshold']??e?.['threshold']??0x0,i=g?.['weights']??0x0;if(h>0x0){c['threshold']=h,c['accumulated_weight']=i,c['remaining']=Math['max'](0x0,h-i);const j=new Set((g?.['forwards']??[])['filter'](l=>l?.['accomplished']!==![])['map'](l=>l?.['forward'])['filter'](l=>!!l)),k=[];for(const l of e?.['forwards']??[]){if(!l['name']||j['has'](l['name']))continue;k['push']({'forward':l['name'],'operator':resolveOperator(l,a['orderHolderAddresses'],a['permissionDescription'],a['nameResolver'])});}if(k['length'])c['waiting_on']=k;c['note']='Node\x20did\x20not\x20migrate:\x20threshold\x20'+h+',\x20accumulated\x20weight\x20'+i+',\x20remaining\x20'+Math['max'](0x0,h-i)+'.\x20'+(k['length']?'Waiting\x20for:\x20'+k['map'](m=>m['forward']+'\x20('+(m['operator']['role_name']??m['operator']['kind'])+')')['join'](';\x20'):'All\x20forwards\x20on\x20this\x20pair\x20are\x20accomplished\x20—\x20the\x20node\x20should\x20migrate\x20on\x20the\x20next\x20operation.');}else c['note']='Node\x20did\x20not\x20migrate\x20(threshold\x200)\x20—\x20no\x20further\x20weight\x20cooperation\x20required;\x20verify\x20the\x20operation\x20outcome.';}const d=buildWorkflowGuidance({'current':a['current'],'nodes':a['nodes'],'caller':a['caller'],'callerAddress':a['callerAddress'],'orderHolderAddresses':a['orderHolderAddresses'],'progressNamedOperator':a['progressNamedOperator'],'permissionContext':a['permissionContext'],'orderContext':a['orderContext'],'permissionDescription':a['permissionDescription'],'nameResolver':a['nameResolver']});if(d['options']['length']>0x0)c['next_guidance']=d;return c;}function operatorText(a){const b=[a['role_name']??a['kind']];if(a['account_name'])b['push'](a['account_name']);return b['join']('\x20/\x20');}export function renderGuidanceText(a){const b=['[WORKFLOW\x20GUIDANCE]\x20current\x20node:\x20\x22'+a['current_node']+'\x22'+(a['caller']?'\x20(caller:\x20'+a['caller']+')':'')];if(a['options']['length']===0x0)return b['push']('\x20\x20•\x20'+(a['note']??'No\x20reachable\x20next\x20nodes.')),b['join']('\x0a');for(const c of a['options']){const d=['\x22'+c['forward']+'\x22\x20→\x20\x22'+c['next_node']+'\x22','operator:\x20'+operatorText(c['operator']),'weight:\x20'+c['weight'],'consistency:\x20'+c['consistency']+'/100'+(c['recommended']?'\x20[RECOMMENDED]':'')];if(c['guard'])d['push']('guard:\x20'+c['guard']);d['push']('meaning:\x20'+c['business_meaning']);if(c['gains']['length'])d['push']('gains:\x20'+c['gains']['join'](';\x20'));if(c['risks']['length'])d['push']('risks:\x20'+c['risks']['join'](';\x20'));b['push']('\x20\x20•\x20'+d['join']('\x20|\x20'));}if(a['recommendation']?.['best']){b['push']('\x20\x20RECOMMENDED:\x20'+a['recommendation']['best']+'.\x20'+(a['recommendation']['rationale']??''));if(a['recommendation']['caveat'])b['push']('\x20\x20CAVEAT\x20(opportunity\x20cost):\x20'+a['recommendation']['caveat']);}if(a['note'])b['push']('\x20\x20NOTE:\x20'+a['note']);return b['push']('\x20\x20(AI\x20recommendation\x20only\x20—\x20the\x20account\x20decides;\x20switch\x20env.account\x20if\x20another\x20operator\x20must\x20act.)'),b['join']('\x0a');}export function renderReceiptText(a){const b=['[WORKFLOW\x20RECEIPT]\x20'+a['action']];b['push']('\x20\x20•\x20node\x20migrated:\x20'+(a['migrated']?'yes\x20→\x20current:\x20\x22'+a['current_node']+'\x22':'no\x20→\x20current:\x20\x22'+a['current_node']+'\x22'));if(!a['migrated']){a['threshold']!==undefined&&a['threshold']>0x0&&(b['push']('\x20\x20•\x20threshold:\x20'+a['threshold']+'\x20|\x20accumulated\x20weight:\x20'+(a['accumulated_weight']??0x0)+'\x20|\x20remaining:\x20'+(a['remaining']??0x0)),a['waiting_on']?.['length']&&b['push']('\x20\x20•\x20waiting\x20on:\x20'+a['waiting_on']['map'](c=>'\x22'+c['forward']+'\x22\x20('+operatorText(c['operator'])+')')['join'](';\x20')));if(a['note'])b['push']('\x20\x20•\x20note:\x20'+a['note']);}return a['next_guidance']&&a['next_guidance']['options']['length']>0x0&&b['push'](renderGuidanceText(a['next_guidance'])),b['join']('\x0a');}async function makeNameResolver(a){const b=[...new Set(a['filter'](d=>!!d))],c=new Map();if(b['length'])try{const d=await GetLocalNamesByAddresses(b);for(const e of d){const f=e?.['account']??e?.['local_mark'];if(f)c['set'](e['address']['toLowerCase'](),f);}}catch{}return g=>{if(!g)return undefined;const h=c['get'](g['toLowerCase']());return h??shortAddr(g);};}export async function enrichWorkflowGuidance(a){try{let b;if(a['progressRef']['startsWith']('0x'))b=a['progressRef'];else b=await LocalMark['Instance']()['get_address'](a['progressRef'])??undefined;if(!b)return undefined;const c=await query_objects({'objects':[b],'no_cache':a['noCache'],'network':a['network']}),d=c?.['objects']?.[0x0],e=d?.['data']??d;if((d?.['type']??e?.['type'])!=='Progress')return undefined;const f=e['current']??'',g=e['machine'],h=Array['isArray'](e['session'])?e['session']:[],i=(Array['isArray'](e['namedOperator'])?e['namedOperator']['find'](v=>v?.['name']==='')?.['operators']:undefined)??[];if(!g)return undefined;const j=await fetchMachineNodes(g,a['network'],![]);let k,l;try{const v=await query_objects({'objects':[g],'no_cache':a['noCache'],'network':a['network']}),w=v?.['objects']?.[0x0],x=w?.['data']??w,y=x?.['permission'];if(y){const z=await query_objects({'objects':[y],'no_cache':a['noCache'],'network':a['network']}),A=z?.['objects']?.[0x0];k=(A?.['data']??A)?.['description']??undefined,l=await fetchPermissionContext(y,a['network'],a['noCache']);}}catch{}const m=(Array['isArray'](e['namedOperator'])?e['namedOperator']:[])['map'](B=>({'name':String(B?.['name']??''),'operators':(B?.['operators']??[])['map'](C=>String(C))}));let n;e['task']&&(n=await fetchOrderContext(e['task'],a['network'],a['noCache']));const o=n?Array['from'](new Set([n['builder'],...n['agent']])['values']()):i;let p;try{p=await LocalMark['Instance']()['get_address'](a['accountName'])??undefined;}catch{p=undefined;}const q=await makeNameResolver([a['accountName'],...o]),r={'current':f,'nodes':j,'caller':a['accountName'],'callerAddress':p,'orderHolderAddresses':o,'progressNamedOperator':m,'permissionContext':l,'orderContext':n,'permissionDescription':k,'nameResolver':q},s=buildWorkflowGuidance(r);let t;a['operate']?.['forward']&&a['operate']?.['next_node_name']&&(t=buildWorkflowReceipt({...r,'callerName':a['accountName']??b,'forward':a['operate']['forward'],'targetNode':a['operate']['next_node_name'],'op':a['operate']['op'],'session':h}));const u=[t?renderReceiptText(t):undefined,s['options']['length']&&!t?.['next_guidance']?.['options']['length']?renderGuidanceText(s):undefined]['filter'](B=>!!B)['join']('\x0a\x0a');return{'guidance':s,'receipt':t,'text':u};}catch{return undefined;}}export function mergeGuidanceIntoOutput(a,b){if(!b)return a;try{const c=a?.['structuredContent'];if(c&&typeof c==='object'){const d=c['semantic'];if(d&&typeof d==='object'){if(b['guidance'])d['workflow_guidance']=b['guidance'];if(b['receipt'])d['workflow_receipt']=b['receipt'];}}b['text']&&Array['isArray'](a?.['content'])&&a['content'][0x0]?.['text']!==undefined&&(a['content'][0x0]['text']=b['text']+'\x0a\x0a'+a['content'][0x0]['text']);}catch{}return a;}export const ENTITY_REGISTRAR_OBJECT_ID='0x0000000000000000000000000000000000000000000000000000000000000aab';export const ENTITY_LINKER_OBJECT_ID='0x0000000000000000000000000000000000000000000000000000000000000aaa';async function batchReadDerivedFields(a,b,c,d){const e=new Map();if(b['length']===0x0)return e;const f=new Map();for(const h of b){const i=deriveDynamicFieldID(a,h['typeTag'],h['keyBytes'])['toLowerCase']();f['set'](i,h['joinKey']);}const g=await batchQueryObjectsByIds([...f['keys']()],c,d);for(const j of g){const l=String(j?.['object']??'')['toLowerCase'](),m=f['get'](l);if(!m)continue;e['set'](m,j?.['data']??j);}return e;}export async function batchReadAddressKeyedFields(a,b,c,d){const e=[...new Set((b??[])['map'](f=>String(f)['toLowerCase']())['filter'](f=>f['startsWith']('0x')))];return batchReadDerivedFields(a,e['map'](f=>({'typeTag':'address','keyBytes':bcs['Address']['serialize'](f)['toBytes'](),'joinKey':f})),c,d);}export async function batchReadU64KeyedFields(a,b,c,d){const e=[...new Set((b??[])['map'](f=>String(f))['filter'](f=>f!==''&&Number['isFinite'](Number(f))))];return batchReadDerivedFields(a,e['map'](f=>({'typeTag':'u64','keyBytes':bcs['u64']()['serialize'](Number(f))['toBytes'](),'joinKey':f})),c,d);}export async function batchFetchEntityRegistrar(a,b,c){try{return await batchReadAddressKeyedFields(ENTITY_REGISTRAR_OBJECT_ID,a,b,c);}catch{return new Map();}}export async function batchFetchEntityLinker(a,b,c){try{return await batchReadAddressKeyedFields(ENTITY_LINKER_OBJECT_ID,a,b,c);}catch{return new Map();}}export const ENTITY_PERMISSION_OBJECT_ID='0xaad';export const ENTITY_PERMISSION_ROLES={'OWNER':0x1,'ADMIN':0x2,'ENTITY':0x4};export async function fetchEntityPermission(a,b,c){try{const e=await batchReadAddressKeyedFields(ENTITY_PERMISSION_OBJECT_ID,[a],b,c),f=e['get'](String(a)['toLowerCase']()),g=[],h=new Map(),i=Array['isArray'](f?.['items'])?f['items']:[];for(const j of i){const k=Number(j?.['role']??0x0),l=String(j?.['permission']??'')['toLowerCase'](),m=Number(j?.['time']??0x0);l&&(g['push']({'role':k,'permission':l,'time':m}),h['set'](l,(h['get'](l)??0x0)|k));}return{'items':g,'byPermission':h};}catch{return undefined;}}export const ENTITY_CONTACT_OBJECT_ID='0xaa9';export async function fetchEntityContact(a,b,c){try{const e=await batchReadAddressKeyedFields(ENTITY_CONTACT_OBJECT_ID,[a],b,c),f=e['get'](String(a)['toLowerCase']()),g=[],h=new Map(),i=Array['isArray'](f?.['items'])?f['items']:[];for(const j of i){const k=String(j?.['contact']??'')['toLowerCase'](),l=Number(j?.['time']??0x0);k&&(g['push']({'contact':k,'time':l}),h['set'](k,(h['get'](k)??l)||l));}return{'items':g,'byContact':h};}catch{return undefined;}}export const ENTITY_ORDER_OBJECT_ID='0xaa8';export const ENTITY_ORDER_ROLES={'OWNER':0x1,'AGENT':0x2};export async function fetchOrdersOfUser(a,b,c){try{return await queryOrdersByUser({'address':a,'no_cache':c,'network':b});}catch{return undefined;}}export async function resolveLocalNamesFor(a){const b=new Map();try{const c=[...new Set((a??[])['filter'](e=>typeof e==='string'&&e['startsWith']('0x')))];if(c['length']===0x0)return{'byAddress':b};const d=await GetLocalNamesByAddresses(c);for(const e of d??[]){const f=e?.['account']||e?.['local_mark'];if(f)b['set'](String(e['address'])['toLowerCase'](),f);}}catch{}return{'byAddress':b};}export const OBJECT_LINKER_CORE_OBJECT_ID='0xaae';export const OBJECT_LINKER_TX_OBJECT_ID='0xaaf';async function fetchObjectLinker(a,b,c,e){try{const f=await batchReadAddressKeyedFields(a,[b],c,e),g=f['get'](String(b)['toLowerCase']()),h=[],i=new Map(),j=Array['isArray'](g?.['items'])?g['items']:[];for(const k of j){const l=String(k?.['who']??'')['toLowerCase'](),m=Number(k?.['time']??0x0);l&&(h['push']({'who':l,'time':m}),i['set'](l,m));}return{'items':h,'byWho':i};}catch{return undefined;}}export async function fetchObjectLinkerCore(a,b,c){return fetchObjectLinker(OBJECT_LINKER_CORE_OBJECT_ID,a,b,c);}export async function fetchObjectLinkerTx(a,b,c){return fetchObjectLinker(OBJECT_LINKER_TX_OBJECT_ID,a,b,c);}export async function fetchServiceOrders(a,b,c){const d=await fetchObjectLinkerTx(a,b,c);if(!d)return undefined;const e=d['items']['filter'](f=>objectTypeFromAddress(f['who'])===ObjectType['Order']);return{'items':e,'byWho':new Map(e['map'](f=>[f['who'],f['time']]))};}export async function fetchPermissionContext(a,b,c){try{const e=await query_objects({'objects':[a],'no_cache':c,'network':b}),f=e?.['objects']?.[0x0],g=f?.['data']??f,h=new Set((g?.['admin']??[])['map'](k=>String(k)['toLowerCase']())),i=new Map(),{items:j}=await batchQueryTableItems(a,{'network':b,'noCache':c});for(const k of j){const l=k['object'];if(!l)continue;const m=l?.['data']??l,n=m?.['address'],p=m?.['perm'];n!=null&&Array['isArray'](p)&&i['set'](String(n)['toLowerCase'](),new Set(p['map'](q=>Number(q))));}return{'admin':h,'table':i};}catch{return undefined;}}export async function fetchOrderContext(a,b,c){try{const e=await query_objects({'objects':[a],'no_cache':c,'network':b}),f=e?.['objects']?.[0x0];if((f?.['type']??f?.['data']?.['type'])!=='Order')return undefined;const g=f?.['data']??f;return{'builder':String(g?.['builder']??g?.['owner']??''),'agent':new Set((g?.['agent']??[])['map'](h=>String(h)['toLowerCase']()))};}catch{return undefined;}}export async function listLocalAccounts(){try{const a=await query_account_list({'suspended':![]});return(a??[])['filter'](b=>b?.['address'])['map'](b=>({'address':String(b['address']),'name':b['name']??undefined}));}catch{return[];}}export function accountCanExecuteForward(a,b,c,d,e){const g=b['toLowerCase']();if(a['namedOperator']!==undefined&&a['namedOperator']!==null){if(a['namedOperator']===''){if(d&&(g===d['builder']['toLowerCase']()||d['agent']['has'](g)))return!![];}else{if(a['namedOperator']['length']>0x0){const h=a['namedOperator'],i=c['find'](j=>String(j?.['name']??'')===h);if(i?.['operators']?.['some'](j=>String(j)['toLowerCase']()===g))return!![];}}}if(a['permissionIndex']!==undefined&&a['permissionIndex']!==null&&e){if(e['admin']['has'](g))return!![];const j=e['table']['get'](g);if(j?.['has'](a['permissionIndex']))return!![];}return![];}
1
+ import{query_objects,query_table,query_account_list,LocalMark,GetLocalNamesByAddresses,bcs,deriveDynamicFieldID,queryOrdersByUser,objectTypeFromAddress,ObjectType}from'@wowok/wowok';import{REPOSITORY_PERMISSIONS,REWARD_PERMISSIONS,MACHINE_PERMISSIONS,PROGRESS_PERMISSIONS,TREASURY_PERMISSIONS,SERVICE_PERMISSIONS,ARBITRATION_PERMISSIONS,DEMAND_PERMISSIONS,CONTACT_PERMISSIONS}from'./permission-ledger.js';import{formatShortAddress}from'../persona/address-format.js';const BUILTIN_PERMISSION_MAP=new Map();for(const entry of[...REPOSITORY_PERMISSIONS,...REWARD_PERMISSIONS,...MACHINE_PERMISSIONS,...PROGRESS_PERMISSIONS,...TREASURY_PERMISSIONS,...SERVICE_PERMISSIONS,...ARBITRATION_PERMISSIONS,...DEMAND_PERMISSIONS,...CONTACT_PERMISSIONS]){BUILTIN_PERMISSION_MAP['set'](entry['index'],entry['name']);}export function resolvePermissionRole(a,b){if(a===undefined||a===null)return'unknown\x20role';if(b){const d=/([A-Za-z][A-Za-z0-9_]*)\s*=\s*(\d+)/g;let e;while((e=d['exec'](b))!==null){if(Number(e[0x2])===a)return e[0x1]+'\x20(permission\x20'+a+')';}}const c=BUILTIN_PERMISSION_MAP['get'](a);if(c)return c+'\x20(permission\x20'+a+')';return'permission\x20'+a;}export const QUERY_OBJECTS_BATCH=0x32;export async function fetchTableEntries(a,b){const c=[],d=b?.['maxItems'];let e=![],f=undefined;for(;;){const g=await query_table({'parent':a,'cursor':f??undefined,'limit':b?.['limit'],'no_cache':b?.['noCache'],'network':b?.['network']});for(const i of g?.['items']??[]){if(d!==undefined&&c['length']>=d)break;const j=String(i?.['object']??'');if(!j['startsWith']('0x'))continue;c['push']({'key':String(i?.['key']?.['value']??''),'objectId':j});}const h=g?.['hasNextPage']===!![]&&!!g?.['nextCursor'];if(d!==undefined&&c['length']>=d){e=h;break;}if(!h)break;f=String(g['nextCursor']);}return{'entries':c,'truncated':e};}export async function fetchAllFieldObjectIds(a,b,c){const {entries:d}=await fetchTableEntries(a,{'network':b,'noCache':c});return d['map'](f=>f['objectId']);}export async function batchQueryObjectsByIds(a,b,c){const d=[];for(let e=0x0;e<a['length'];e+=QUERY_OBJECTS_BATCH){const f=a['slice'](e,e+QUERY_OBJECTS_BATCH),g=await query_objects({'objects':f,'no_cache':c,'network':b});d['push'](...g?.['objects']??[]);}return d;}export async function batchQueryTableItems(a,b){const {entries:c,truncated:d}=await fetchTableEntries(a,b),e=c['length']>0x0?await batchQueryObjectsByIds(c['map'](h=>h['objectId']),b?.['network'],b?.['noCache']):[],f=new Map();for(const h of e){const i=String(h?.['object']??'')['toLowerCase']();if(i)f['set'](i,h);}const g=c['map'](j=>({...j,'object':f['get'](j['objectId']['toLowerCase']())}));return{'items':g,'truncated':d};}export async function fetchMachineNodes(a,b,c){const d=await query_objects({'objects':[a],'no_cache':c,'network':b}),e=d?.['objects']?.[0x0],f=e?.['object']??(typeof a==='string'&&a['startsWith']('0x')?a:undefined);if(!f)return[];const {items:g}=await batchQueryTableItems(f,{'network':b,'noCache':c});return g['map'](h=>h['object'])['filter'](h=>h?.['type']==='TableItem_MachineNode')['map'](h=>{const i=h?.['data']??h,j=typeof i?.['name']==='string'?i['name']:'',k=Array['isArray'](i?.['value'])?i['value']:Array['isArray'](i?.['pairs'])?i['pairs']:[];if(!j)return null;return{'name':j,'pairs':k['map'](l=>({'prev_node':String(l?.['prev_node']??''),'threshold':Number(l?.['threshold']??0x0),'forwards':Array['isArray'](l?.['forwards'])?l['forwards']['map'](m=>{const n=typeof m?.['guard']==='object'&&m?.['guard']!==null?m['guard']['guard']??undefined:typeof m?.['guard']==='string'?m['guard']:undefined;return{'name':String(m?.['name']??''),'weight':Number(m?.['weight']??0x0),'namedOperator':m?.['namedOperator']!==undefined&&m?.['namedOperator']!==null?String(m['namedOperator']):undefined,'permissionIndex':m?.['permissionIndex']!==undefined&&m?.['permissionIndex']!==null?Number(m['permissionIndex']):undefined,'guard':n};}):[]}))};})['filter'](h=>h!==null);}const COMPLETE_RE=/(^|_)(completed?|done|finished|received|delivered|accepted|confirmed|finalized|success|approved)(_|$)/i,REFUND_RE=/(^|_)(cancel(led)?|refund(ed)?|return(ed|_approved)?)(_|$)/i,EXCEPTION_RE=/(^|_)(interrupt(ed)?|exception|dispute(d)?|fail(ed)?|abort(ed)?|reject(ed)?)(_|$)/i;function classifyNode(a){if(COMPLETE_RE['test'](a))return'complete';if(REFUND_RE['test'](a))return'refund';if(EXCEPTION_RE['test'](a))return'exception';return'advance';}function businessMeaning(a,b){switch(b){case'complete':return'Service/deliverable\x20accepted\x20at\x20\x22'+a+'\x22\x20—\x20triggers\x20settlement\x20allocation\x20(funds\x20released\x20to\x20the\x20provider)';case'refund':return'Order\x20cancelled/returned\x20at\x20\x22'+a+'\x22\x20—\x20triggers\x20refund\x20allocation\x20(funds\x20back\x20to\x20the\x20customer)';case'exception':return'Exception\x20path\x20at\x20\x22'+a+'\x22\x20—\x20typically\x20routes\x20to\x20arbitration\x20or\x20partial-refund\x20handling';default:return'Progress\x20to\x20\x22'+a+'\x22';}}function shortAddr(a){if(!a)return undefined;return formatShortAddress(a);}function callerIsOrderHolder(a,b){if(!a||!b?.['length'])return![];const d=a['toLowerCase']();return b['some'](e=>e?.['toLowerCase']()===d);}function resolveOperator(a,b,c,d){if(a['namedOperator']===''){const e=b?.[0x0];return{'kind':'order_holder','role_name':'order\x20holder\x20(customer)','account_name':d?d(e):shortAddr(e)};}if(typeof a['namedOperator']==='string'&&a['namedOperator']['length']>0x0)return{'kind':'named_operator','named_operator':a['namedOperator'],'role_name':'named\x20operator\x20\x22'+a['namedOperator']+'\x22'};if(a['permissionIndex']!==undefined&&a['permissionIndex']!==null)return{'kind':'permission_index','permission_index':a['permissionIndex'],'role_name':resolvePermissionRole(a['permissionIndex'],c)};return{'kind':'order_holder','role_name':'unknown\x20operator'};}function gainsRisksFor(a,b,c){if(!c)return{'gains':[],'risks':[]};if(b)switch(a){case'complete':return{'gains':['Flow\x20advances','Settlement\x20triggered\x20(funds\x20released)'],'risks':['Funds\x20released\x20to\x20provider','Refund\x20leverage\x20lost\x20—\x20confirm\x20only\x20if\x20service\x20verified']};case'refund':return{'gains':['Funds\x20returned\x20to\x20you'],'risks':['If\x20service\x20was\x20already\x20rendered,\x20cancellation\x20may\x20be\x20disputed']};case'exception':return{'gains':['Avoids\x20stalemate'],'risks':['May\x20trigger\x20arbitration\x20/\x20reputation\x20impact']};default:return{'gains':['Flow\x20advances'],'risks':[]};}switch(a){case'complete':return{'gains':['Settlement\x20triggered\x20—\x20funds\x20released\x20to\x20provider'],'risks':[]};case'refund':return{'gains':['Clean\x20closure'],'risks':['Lost\x20revenue\x20for\x20this\x20order']};case'exception':return{'gains':['Avoids\x20stalemate'],'risks':['May\x20trigger\x20arbitration\x20/\x20compensation\x20fund']};default:return{'gains':['Flow\x20advances'],'risks':[]};}}function consistencyFor(a,b,c,d,e){let f;if(!e)f=a==='exception'?0x2d:0x32;else b?f=a==='refund'?0x46:a==='complete'?0x37:a==='exception'?0x23:0x32:f=a==='complete'?0x4b:a==='refund'?0x1e:a==='exception'?0x23:0x32;if(e&&c)f+=0x14;if(d)f-=0xa;return Math['max'](0x0,Math['min'](0x64,f));}export function buildWorkflowGuidance(a){const b=[];for(const i of a['nodes']){for(const j of i['pairs']){if(j['prev_node']!==a['current'])continue;for(const k of j['forwards']){if(!k['name'])continue;const l=resolveOperator(k,a['orderHolderAddresses'],a['permissionDescription'],a['nameResolver']),m=callerIsOrderHolder(a['callerAddress']??a['caller'],a['orderHolderAddresses']);let n=![];a['callerAddress']&&(n=accountCanExecuteForward(k,a['callerAddress'],a['progressNamedOperator']??[],a['orderContext'],a['permissionContext']));const p=classifyNode(i['name']),q=!!a['caller'],{gains:r,risks:s}=gainsRisksFor(p,m,q),t=consistencyFor(p,m,n,!!k['guard'],q);b['push']({'next_node':i['name'],'forward':k['name'],'weight':k['weight'],'operator':l,'guard':k['guard'],'business_meaning':businessMeaning(i['name'],p),'gains':r,'risks':s,'consistency':t,'recommended':![]});}}}if(b['length']===0x0)return{'current_node':a['current'],'caller':a['caller'],'options':[],'note':'Node\x20\x22'+a['current']+'\x22\x20has\x20no\x20outgoing\x20forwards\x20—\x20it\x20is\x20a\x20terminal\x20node\x20(or\x20the\x20workflow\x20is\x20stuck).\x20No\x20further\x20progress\x20operation\x20is\x20available\x20here.'};b['sort']((u,v)=>v['consistency']-u['consistency']);const c=b[0x0];b[0x0]={...c,'recommended':!![]};const d=[];for(const u of b){u!==c&&u['consistency']>0x0&&u['forward']!==c['forward']&&d['push']('Choosing\x20\x22'+u['forward']+'\x20→\x20'+u['next_node']+'\x22\x20forfeits\x20the\x20faster/more\x20aligned\x20path\x20\x22'+c['forward']+'\x20→\x20'+c['next_node']+'\x22');}const e=[],g=b['filter'](v=>v['operator']['kind']==='order_holder'&&v['forward']!==c['forward']&&c['forward']!==v['forward']),h=b['filter'](v=>v['operator']['account_name']&&v['operator']['account_name']!==a['caller']);return h['length']>0x0&&!b['some'](v=>v['recommended']&&v['operator']['account_name']===a['caller'])&&e['push']('The\x20recommended\x20action\x20is\x20executed\x20by\x20another\x20account\x20('+h[0x0]['operator']['account_name']+');\x20switch\x20the\x20signing\x20account\x20(env.account)\x20before\x20operating.'),{'current_node':a['current'],'caller':a['caller'],'options':b,'recommendation':{'best':c['forward']+'\x20→\x20'+c['next_node'],'rationale':'Highest\x20consistency\x20('+c['consistency']+'/100)\x20with\x20the\x20caller\x27s\x20interests.\x20Gains:\x20'+(c['gains']['join'](';\x20')||'none')+'.\x20Risks:\x20'+(c['risks']['join'](';\x20')||'none')+'.\x20Operator:\x20'+(c['operator']['role_name']??c['operator']['kind'])+(c['operator']['account_name']?'\x20('+c['operator']['account_name']+')':'')+'.'+(c['guard']?'\x20Guard\x20to\x20satisfy:\x20'+c['guard']+'.':''),'caveat':d['length']?d['join']('.\x20'):undefined},'note':e['length']?e['join']('\x20'):undefined};}export function buildWorkflowReceipt(a){const b=a['current']===a['targetNode'],c={'account':a['callerName'],'action':a['callerName']+'\x20executed\x20'+a['forward']+'\x20(→\x20'+a['targetNode']+')','forward':a['forward'],'target_node':a['targetNode'],'op':a['op'],'migrated':b,'current_node':a['current']};if(!b){const e=a['nodes']['filter'](j=>j['name']===a['targetNode'])['flatMap'](j=>j['pairs'])['find'](j=>j['prev_node']===a['current']),g=a['session']?.['slice'](-0x1)[0x0],h=g?.['threshold']??e?.['threshold']??0x0,i=g?.['weights']??0x0;if(h>0x0){c['threshold']=h,c['accumulated_weight']=i,c['remaining']=Math['max'](0x0,h-i);const j=new Set((g?.['forwards']??[])['filter'](l=>l?.['accomplished']!==![])['map'](l=>l?.['forward'])['filter'](l=>!!l)),k=[];for(const l of e?.['forwards']??[]){if(!l['name']||j['has'](l['name']))continue;k['push']({'forward':l['name'],'operator':resolveOperator(l,a['orderHolderAddresses'],a['permissionDescription'],a['nameResolver'])});}if(k['length'])c['waiting_on']=k;c['note']='Node\x20did\x20not\x20migrate:\x20threshold\x20'+h+',\x20accumulated\x20weight\x20'+i+',\x20remaining\x20'+Math['max'](0x0,h-i)+'.\x20'+(k['length']?'Waiting\x20for:\x20'+k['map'](m=>m['forward']+'\x20('+(m['operator']['role_name']??m['operator']['kind'])+')')['join'](';\x20'):'All\x20forwards\x20on\x20this\x20pair\x20are\x20accomplished\x20—\x20the\x20node\x20should\x20migrate\x20on\x20the\x20next\x20operation.');}else c['note']='Node\x20did\x20not\x20migrate\x20(threshold\x200)\x20—\x20no\x20further\x20weight\x20cooperation\x20required;\x20verify\x20the\x20operation\x20outcome.';}const d=buildWorkflowGuidance({'current':a['current'],'nodes':a['nodes'],'caller':a['caller'],'callerAddress':a['callerAddress'],'orderHolderAddresses':a['orderHolderAddresses'],'progressNamedOperator':a['progressNamedOperator'],'permissionContext':a['permissionContext'],'orderContext':a['orderContext'],'permissionDescription':a['permissionDescription'],'nameResolver':a['nameResolver']});if(d['options']['length']>0x0)c['next_guidance']=d;return c;}function operatorText(a){const b=[a['role_name']??a['kind']];if(a['account_name'])b['push'](a['account_name']);return b['join']('\x20/\x20');}export function renderGuidanceText(a){const b=['[WORKFLOW\x20GUIDANCE]\x20current\x20node:\x20\x22'+a['current_node']+'\x22'+(a['caller']?'\x20(caller:\x20'+a['caller']+')':'')];if(a['options']['length']===0x0)return b['push']('\x20\x20•\x20'+(a['note']??'No\x20reachable\x20next\x20nodes.')),b['join']('\x0a');for(const c of a['options']){const d=['\x22'+c['forward']+'\x22\x20→\x20\x22'+c['next_node']+'\x22','operator:\x20'+operatorText(c['operator']),'weight:\x20'+c['weight'],'consistency:\x20'+c['consistency']+'/100'+(c['recommended']?'\x20[RECOMMENDED]':'')];if(c['guard'])d['push']('guard:\x20'+c['guard']);d['push']('meaning:\x20'+c['business_meaning']);if(c['gains']['length'])d['push']('gains:\x20'+c['gains']['join'](';\x20'));if(c['risks']['length'])d['push']('risks:\x20'+c['risks']['join'](';\x20'));b['push']('\x20\x20•\x20'+d['join']('\x20|\x20'));}if(a['recommendation']?.['best']){b['push']('\x20\x20RECOMMENDED:\x20'+a['recommendation']['best']+'.\x20'+(a['recommendation']['rationale']??''));if(a['recommendation']['caveat'])b['push']('\x20\x20CAVEAT\x20(opportunity\x20cost):\x20'+a['recommendation']['caveat']);}if(a['note'])b['push']('\x20\x20NOTE:\x20'+a['note']);return b['push']('\x20\x20(AI\x20recommendation\x20only\x20—\x20the\x20account\x20decides;\x20switch\x20env.account\x20if\x20another\x20operator\x20must\x20act.)'),b['join']('\x0a');}export function renderReceiptText(a){const b=['[WORKFLOW\x20RECEIPT]\x20'+a['action']];b['push']('\x20\x20•\x20node\x20migrated:\x20'+(a['migrated']?'yes\x20→\x20current:\x20\x22'+a['current_node']+'\x22':'no\x20→\x20current:\x20\x22'+a['current_node']+'\x22'));if(!a['migrated']){a['threshold']!==undefined&&a['threshold']>0x0&&(b['push']('\x20\x20•\x20threshold:\x20'+a['threshold']+'\x20|\x20accumulated\x20weight:\x20'+(a['accumulated_weight']??0x0)+'\x20|\x20remaining:\x20'+(a['remaining']??0x0)),a['waiting_on']?.['length']&&b['push']('\x20\x20•\x20waiting\x20on:\x20'+a['waiting_on']['map'](c=>'\x22'+c['forward']+'\x22\x20('+operatorText(c['operator'])+')')['join'](';\x20')));if(a['note'])b['push']('\x20\x20•\x20note:\x20'+a['note']);}return a['next_guidance']&&a['next_guidance']['options']['length']>0x0&&b['push'](renderGuidanceText(a['next_guidance'])),b['join']('\x0a');}async function makeNameResolver(a){const b=[...new Set(a['filter'](d=>!!d))],c=new Map();if(b['length'])try{const d=await GetLocalNamesByAddresses(b);for(const e of d){const f=e?.['account']??e?.['local_mark'];if(f)c['set'](e['address']['toLowerCase'](),f);}}catch{}return g=>{if(!g)return undefined;const h=c['get'](g['toLowerCase']());return h??shortAddr(g);};}export async function enrichWorkflowGuidance(a){try{let b;if(a['progressRef']['startsWith']('0x'))b=a['progressRef'];else b=await LocalMark['Instance']()['get_address'](a['progressRef'])??undefined;if(!b)return undefined;const c=await query_objects({'objects':[b],'no_cache':a['noCache'],'network':a['network']}),d=c?.['objects']?.[0x0],e=d?.['data']??d;if((d?.['type']??e?.['type'])!=='Progress')return undefined;const f=e['current']??'',g=e['machine'],h=Array['isArray'](e['session'])?e['session']:[],i=(Array['isArray'](e['namedOperator'])?e['namedOperator']['find'](v=>v?.['name']==='')?.['operators']:undefined)??[];if(!g)return undefined;const j=await fetchMachineNodes(g,a['network'],![]);let k,l;try{const v=await query_objects({'objects':[g],'no_cache':a['noCache'],'network':a['network']}),w=v?.['objects']?.[0x0],x=w?.['data']??w,y=x?.['permission'];if(y){const z=await query_objects({'objects':[y],'no_cache':a['noCache'],'network':a['network']}),A=z?.['objects']?.[0x0];k=(A?.['data']??A)?.['description']??undefined,l=await fetchPermissionContext(y,a['network'],a['noCache']);}}catch{}const m=(Array['isArray'](e['namedOperator'])?e['namedOperator']:[])['map'](B=>({'name':String(B?.['name']??''),'operators':(B?.['operators']??[])['map'](C=>String(C))}));let n;e['task']&&(n=await fetchOrderContext(e['task'],a['network'],a['noCache']));const o=n?Array['from'](new Set([n['builder'],...n['agent']])['values']()):i;let p;try{p=await LocalMark['Instance']()['get_address'](a['accountName'])??undefined;}catch{p=undefined;}const q=await makeNameResolver([a['accountName'],...o]),r={'current':f,'nodes':j,'caller':a['accountName'],'callerAddress':p,'orderHolderAddresses':o,'progressNamedOperator':m,'permissionContext':l,'orderContext':n,'permissionDescription':k,'nameResolver':q},s=buildWorkflowGuidance(r);let t;a['operate']?.['forward']&&a['operate']?.['next_node_name']&&(t=buildWorkflowReceipt({...r,'callerName':a['accountName']??b,'forward':a['operate']['forward'],'targetNode':a['operate']['next_node_name'],'op':a['operate']['op'],'session':h}));const u=[t?renderReceiptText(t):undefined,s['options']['length']&&!t?.['next_guidance']?.['options']['length']?renderGuidanceText(s):undefined]['filter'](B=>!!B)['join']('\x0a\x0a');return{'guidance':s,'receipt':t,'text':u};}catch{return undefined;}}export function mergeGuidanceIntoOutput(a,b){if(!b)return a;try{const c=a?.['structuredContent'];if(c&&typeof c==='object'){const d=c['semantic'];if(d&&typeof d==='object'){if(b['guidance'])d['workflow_guidance']=b['guidance'];if(b['receipt'])d['workflow_receipt']=b['receipt'];}}b['text']&&Array['isArray'](a?.['content'])&&a['content'][0x0]?.['text']!==undefined&&(a['content'][0x0]['text']=b['text']+'\x0a\x0a'+a['content'][0x0]['text']);}catch{}return a;}export const ENTITY_REGISTRAR_OBJECT_ID='0x0000000000000000000000000000000000000000000000000000000000000aab';export const ENTITY_LINKER_OBJECT_ID='0x0000000000000000000000000000000000000000000000000000000000000aaa';async function batchReadDerivedFields(a,b,c,d){const e=new Map();if(b['length']===0x0)return e;const f=new Map();for(const h of b){const i=deriveDynamicFieldID(a,h['typeTag'],h['keyBytes'])['toLowerCase']();f['set'](i,h['joinKey']);}const g=await batchQueryObjectsByIds([...f['keys']()],c,d);for(const j of g){const l=String(j?.['object']??'')['toLowerCase'](),m=f['get'](l);if(!m)continue;e['set'](m,j?.['data']??j);}return e;}export async function batchReadAddressKeyedFields(a,b,c,d){const e=[...new Set((b??[])['map'](f=>String(f)['toLowerCase']())['filter'](f=>f['startsWith']('0x')))];return batchReadDerivedFields(a,e['map'](f=>({'typeTag':'address','keyBytes':bcs['Address']['serialize'](f)['toBytes'](),'joinKey':f})),c,d);}export async function batchReadU64KeyedFields(a,b,c,d){const e=[...new Set((b??[])['map'](f=>String(f))['filter'](f=>f!==''&&Number['isFinite'](Number(f))))];return batchReadDerivedFields(a,e['map'](f=>({'typeTag':'u64','keyBytes':bcs['u64']()['serialize'](Number(f))['toBytes'](),'joinKey':f})),c,d);}export async function batchFetchEntityRegistrar(a,b,c){try{return await batchReadAddressKeyedFields(ENTITY_REGISTRAR_OBJECT_ID,a,b,c);}catch{return new Map();}}export async function batchFetchEntityLinker(a,b,c){try{return await batchReadAddressKeyedFields(ENTITY_LINKER_OBJECT_ID,a,b,c);}catch{return new Map();}}export const ENTITY_PERMISSION_OBJECT_ID='0xaad';export const ENTITY_PERMISSION_ROLES={'OWNER':0x1,'ADMIN':0x2,'ENTITY':0x4};export async function fetchEntityPermission(a,b,c){try{const e=await batchReadAddressKeyedFields(ENTITY_PERMISSION_OBJECT_ID,[a],b,c),f=e['get'](String(a)['toLowerCase']()),g=[],h=new Map(),i=Array['isArray'](f?.['items'])?f['items']:[];for(const j of i){const k=Number(j?.['role']??0x0),l=String(j?.['permission']??'')['toLowerCase'](),m=Number(j?.['time']??0x0);l&&(g['push']({'role':k,'permission':l,'time':m}),h['set'](l,(h['get'](l)??0x0)|k));}return{'items':g,'byPermission':h};}catch{return undefined;}}export const ENTITY_CONTACT_OBJECT_ID='0xaa9';export async function fetchEntityContact(a,b,c){try{const e=await batchReadAddressKeyedFields(ENTITY_CONTACT_OBJECT_ID,[a],b,c),f=e['get'](String(a)['toLowerCase']()),g=[],h=new Map(),i=Array['isArray'](f?.['items'])?f['items']:[];for(const j of i){const k=String(j?.['contact']??'')['toLowerCase'](),l=Number(j?.['time']??0x0);k&&(g['push']({'contact':k,'time':l}),h['set'](k,(h['get'](k)??l)||l));}return{'items':g,'byContact':h};}catch{return undefined;}}export const ENTITY_ORDER_OBJECT_ID='0xaa8';export const ENTITY_ORDER_ROLES={'OWNER':0x1,'AGENT':0x2};export async function fetchOrdersOfUser(a,b,c){try{return await queryOrdersByUser({'address':a,'no_cache':c,'network':b});}catch{return undefined;}}export async function resolveLocalNamesFor(a){const b=new Map();try{const c=[...new Set((a??[])['filter'](e=>typeof e==='string'&&e['startsWith']('0x')))];if(c['length']===0x0)return{'byAddress':b};const d=await GetLocalNamesByAddresses(c);for(const e of d??[]){const f=e?.['account']||e?.['local_mark'];if(f)b['set'](String(e['address'])['toLowerCase'](),f);}}catch{}return{'byAddress':b};}export const OBJECT_LINKER_CORE_OBJECT_ID='0xaae';export const OBJECT_LINKER_TX_OBJECT_ID='0xaaf';async function fetchObjectLinker(a,b,c,e){try{const f=await batchReadAddressKeyedFields(a,[b],c,e),g=f['get'](String(b)['toLowerCase']()),h=[],i=new Map(),j=Array['isArray'](g?.['items'])?g['items']:[];for(const k of j){const l=String(k?.['who']??'')['toLowerCase'](),m=Number(k?.['time']??0x0);l&&(h['push']({'who':l,'time':m}),i['set'](l,m));}return{'items':h,'byWho':i};}catch{return undefined;}}export async function fetchObjectLinkerCore(a,b,c){return fetchObjectLinker(OBJECT_LINKER_CORE_OBJECT_ID,a,b,c);}export async function fetchObjectLinkerTx(a,b,c){return fetchObjectLinker(OBJECT_LINKER_TX_OBJECT_ID,a,b,c);}export async function fetchServiceOrders(a,b,c){const d=await fetchObjectLinkerTx(a,b,c);if(!d)return undefined;const e=d['items']['filter'](f=>objectTypeFromAddress(f['who'])===ObjectType['Order']);return{'items':e,'byWho':new Map(e['map'](f=>[f['who'],f['time']]))};}export async function fetchPermissionContext(a,b,c){try{const e=await query_objects({'objects':[a],'no_cache':c,'network':b}),f=e?.['objects']?.[0x0],g=f?.['data']??f,h=new Set((g?.['admin']??[])['map'](k=>String(k)['toLowerCase']())),i=new Map(),{items:j}=await batchQueryTableItems(a,{'network':b,'noCache':c});for(const k of j){const l=k['object'];if(!l)continue;const m=l?.['data']??l,n=m?.['address'],p=m?.['perm'];n!=null&&Array['isArray'](p)&&i['set'](String(n)['toLowerCase'](),new Set(p['map'](q=>Number(q))));}return{'admin':h,'table':i};}catch{return undefined;}}export async function fetchOrderContext(a,b,c){try{const e=await query_objects({'objects':[a],'no_cache':c,'network':b}),f=e?.['objects']?.[0x0];if((f?.['type']??f?.['data']?.['type'])!=='Order')return undefined;const g=f?.['data']??f;return{'builder':String(g?.['builder']??g?.['owner']??''),'agent':new Set((g?.['agent']??[])['map'](h=>String(h)['toLowerCase']()))};}catch{return undefined;}}export async function listLocalAccounts(){try{const a=await query_account_list({'suspended':![]});return(a??[])['filter'](b=>b?.['address'])['map'](b=>({'address':String(b['address']),'name':b['name']??undefined}));}catch{return[];}}export function accountCanExecuteForward(a,b,c,d,e){const g=b['toLowerCase']();if(a['namedOperator']!==undefined&&a['namedOperator']!==null){if(a['namedOperator']===''){if(d&&(g===d['builder']['toLowerCase']()||d['agent']['has'](g)))return!![];}else{if(a['namedOperator']['length']>0x0){const h=a['namedOperator'],i=c['find'](j=>String(j?.['name']??'')===h);if(i?.['operators']?.['some'](j=>String(j)['toLowerCase']()===g))return!![];}}}if(a['permissionIndex']!==undefined&&a['permissionIndex']!==null&&e){if(e['admin']['has'](g))return!![];const j=e['table']['get'](g);if(j?.['has'](a['permissionIndex']))return!![];}return![];}export function forwardOperatorKind(a){if(a['namedOperator']==='')return'order_holder';if(typeof a['namedOperator']==='string'&&a['namedOperator']['length']>0x0)return'named_operator';return'permission_index';}export function enumerateActionableForwards(a,b,c,d,e,g){const h=typeof a?.['current']==='string'?a['current']:'',i=new Map();for(const k of Array['isArray'](a?.['session'])?a['session']:[]){const l=String(k?.['next_node']??'');for(const m of Array['isArray'](k?.['forwards'])?k['forwards']:[]){i['set'](l+'|'+String(m?.['forward']??''),{'who':m?.['who']?String(m['who'])['toLowerCase']():null,'accomplished':!!m?.['accomplished']});}}const j=[];for(const n of b){for(const o of n['pairs']){if(o['prev_node']!==h)continue;for(const p of o['forwards']){if(!p['name'])continue;const q=i['get'](n['name']+'|'+p['name']);if(q?.['accomplished'])continue;let r=c['filter'](t=>accountCanExecuteForward(p,t,d,e,g));q?.['who']&&(r=r['filter'](t=>t['toLowerCase']()===q['who'])),j['push']({'next_node':n['name'],'forward':p['name'],'weight':p['weight'],'threshold':o['threshold'],'guard':p['guard'],'operator_kind':forwardOperatorKind(p),'permission_index':p['permissionIndex']??undefined,'named_operator':typeof p['namedOperator']==='string'&&p['namedOperator']['length']>0x0?p['namedOperator']:undefined,'executable_accounts':r['map'](t=>t['toLowerCase']())});}}}return j;}
@@ -58,6 +58,7 @@ export interface MonitorLoopDeps {
58
58
  logger(message: string): void;
59
59
  openProblems?(input: ProblemBridgeInput): Promise<number>;
60
60
  openSuggestions?(input: SuggestionBridgeInput): Promise<number>;
61
+ runKeeperScan?(network: string, scope: ScopeSnapshot): Promise<unknown>;
61
62
  setTimer(cb: () => void, ms: number): unknown;
62
63
  clearTimer(handle: unknown): void;
63
64
  }
@@ -1 +1 @@
1
- import{randomUUID}from'node:crypto';import{Config,SQLiteStorage}from'@wowok/wowok/w/local';import{query_events}from'@wowok/wowok';import{monitorEventStore}from'./EventStore.js';import{subscriptionStore}from'./SubscriptionStore.js';import{loadScopeSnapshot,resolveScope}from'./ScopeResolver.js';import{annotateBatch,backfillAnnotations}from'./EventRouter.js';import{bridgeMonitorProblems}from'./ProblemBridge.js';import{bridgeMonitorSuggestions}from'./SuggestionBridge.js';import{EVENT_MODULE_OF,MONITOR_CAPTURE_TYPES,PAYMENT_EVENT_TYPE,normalizeMonitorEvent}from'./normalize.js';import{LOOP_DEFAULTS}from'./types.js';import{goalStore}from'../goal/GoalStore.js';import{addProblem,addSuggestion,listProblems,listSuggestions}from'../task/ProcessStore.js';const LEASE_PREFIX='mon_lease:v4:',SEED_PAGE=0x64,SEED_MAX=0x7d0,POLL_BATCH=0x32,MAX_BACKOFF_MS=0x493e0;function netKey(a){return(a||'default')['replace'](/[^a-zA-Z0-9_-]/g,'_');}function leaseKey(a){return''+LEASE_PREFIX+netKey(a);}function realDeps(){return{'store':monitorEventStore,'configStore':subscriptionStore,'storage':new SQLiteStorage(),'resolveScope':(a,b)=>resolveScope(a,b),'loadScope':a=>loadScopeSnapshot(a),'router':{'annotateBatch':annotateBatch,'backfillAnnotations':backfillAnnotations},'queryEvents':a=>query_events({'type':a['type'],'cursor':a['cursor'],'limit':a['limit'],'order':a['order'],'network':a['network']}),'defaultNetwork':()=>Config['Instance']()['network_get'](),'now':()=>Date['now'](),'pid':process['pid'],'bootId':randomUUID(),'logger':a=>console['error']('[monitor]\x20'+a),'openProblems':a=>bridgeMonitorProblems(a,{'getGoal':(b,c)=>goalStore['get'](b,c),'addProblem':addProblem,'listProblems':listProblems,'logger':b=>console['error']('[monitor]\x20'+b)}),'openSuggestions':a=>bridgeMonitorSuggestions(a,{'getGoal':(b,c)=>goalStore['get'](b,c),'addSuggestion':addSuggestion,'listSuggestions':listSuggestions,'logger':b=>console['error']('[monitor]\x20'+b)}),'setTimer':(a,b)=>setTimeout(a,b),'clearTimer':a=>clearTimeout(a)};}function newRuntime(a){return{'network':a,'started':![],'holdsLease':![],'leaseHolder':null,'timer':undefined,'ticking':![],'scope':undefined,'lastScopeRefreshAt':0x0,'pollIntervalMs':LOOP_DEFAULTS['poll_interval_ms'],'lastTickAt':0x0,'lastNewCount':0x0,'lastSummary':undefined,'consecutiveErrors':0x0,'backoffMs':0x0};}export class MonitorLoop{['deps'];['runtimes']=new Map();constructor(a){this['deps']={...realDeps(),...a??{}};}async['start'](a){let b=a&&a['length']>0x0?a:undefined;if(!b)b=[await this['deps']['defaultNetwork']()];for(const c of b){const d=netKey(c);if(this['runtimes']['has'](d)){const f=this['runtimes']['get'](d);if(f['started'])continue;f['started']=!![],this['schedule'](f,0x0);continue;}const e=newRuntime(c);e['started']=!![],this['runtimes']['set'](d,e);try{const g=await this['deps']['loadScope'](c);g&&(e['scope']=g,e['lastScopeRefreshAt']=Number(g['resolved_at'])||0x0);}catch{}this['schedule'](e,0x0);}return b;}async['stop'](a){const b=a?[netKey(a)]:[...this['runtimes']['keys']()];for(const c of b){const d=this['runtimes']['get'](c);if(!d)continue;d['started']=![];d['timer']!==undefined&&(this['deps']['clearTimer'](d['timer']),d['timer']=undefined);if(d['holdsLease']){d['holdsLease']=![];try{await this['deps']['storage']['del'](leaseKey(d['network']));}catch{}}this['runtimes']['delete'](c);}}['status'](a){const b=a?this['runtimes']['get'](netKey(a)):[...this['runtimes']['values']()][0x0];if(!b)return{'running':![],'lease_holder':null,'last_tick_at':0x0,'last_new_count':0x0,'scope_version':0x0,'backoff_ms':0x0};return{'running':b['started']&&b['holdsLease'],'lease_holder':b['leaseHolder']?b['leaseHolder']['pid']+':'+b['leaseHolder']['boot_id']:null,'last_tick_at':b['lastTickAt'],'last_new_count':b['lastNewCount'],'scope_version':b['scope']?.['version']??0x0,'backoff_ms':b['backoffMs'],...b['lastSummary']?{'last_tick':b['lastSummary']}:{}};}['kick'](a){const b=this['runtimes']['get'](netKey(a));if(!b||!b['started']||!b['holdsLease']||b['ticking'])return;if(this['deps']['now']()-b['lastTickAt']<b['pollIntervalMs'])return;void this['tick'](b['network']);}['invalidateScope'](a){const b=this['runtimes']['get'](netKey(a));if(!b)return;b['scope']=undefined,b['lastScopeRefreshAt']=0x0;}async['tick'](a){const b=netKey(a);let c=this['runtimes']['get'](b);!c&&(c=newRuntime(a),this['runtimes']['set'](b,c));if(c['ticking'])return undefined;c['ticking']=!![];const d=this['deps']['now']();try{const f=await this['deps']['configStore']['getConfig'](a),g=Number(f['loop']?.['poll_interval_ms'])||LOOP_DEFAULTS['poll_interval_ms'];c['pollIntervalMs']=g;const h=await this['acquireLease'](c,g);if(!h)return undefined;const {newCount:i,events:j}=await this['capture'](c,f),k=await this['getScope'](c,f);let l=0x0,m=[];if(i>0x0&&j['length']>0x0){const p=this['deps']['router']['annotateBatch'](j,k,f)['filter'](q=>q['rules']['length']>0x0||q['focus_hit']||q['matched_filters']['length']>0x0);p['length']>0x0&&(await this['deps']['store']['saveAnnotations'](a,p),l=p['length'],m=p);}if(m['length']>0x0&&this['deps']['openProblems'])try{await this['deps']['openProblems']({'network':a,'events':j,'annotations':m,'scope':k});}catch(q){this['deps']['logger']('monitor\x20loop:\x20problem\x20bridge\x20error\x20on\x20'+a+':\x20'+String(q?.['message']??q));}if(m['length']>0x0&&this['deps']['openSuggestions'])try{await this['deps']['openSuggestions']({'network':a,'events':j,'annotations':m,'scope':k});}catch(s){this['deps']['logger']('monitor\x20loop:\x20suggestion\x20bridge\x20error\x20on\x20'+a+':\x20'+String(s?.['message']??s));}const n=Number(f['loop']?.['scope_refresh_ms'])||LOOP_DEFAULTS['scope_refresh_ms'];if(this['deps']['now']()-c['lastScopeRefreshAt']>=n){c['lastScopeRefreshAt']=this['deps']['now']();const {snapshot:t,changed:u}=await this['deps']['resolveScope'](a,f);c['scope']=t;if(u){const v=Number(f['loop']?.['backfill_days']??LOOP_DEFAULTS['backfill_days']),w=await this['deps']['router']['backfillAnnotations'](a,this['deps']['store'],t,v,f);this['deps']['logger']('monitor\x20loop:\x20scope\x20v'+t['version']+'\x20on\x20'+a+'\x20changed\x20—\x20backfill\x20rescanned\x20'+w['rescanned']+',\x20updated\x20'+w['updated']);}}c['lastTickAt']=this['deps']['now'](),c['lastNewCount']=i,c['consecutiveErrors']=0x0,c['backoffMs']=0x0;const o={'captured':j['length'],'annotated':l,'duration_ms':this['deps']['now']()-d};return c['lastSummary']=o,o;}catch(x){const y=String(x?.['message']??x);return this['deps']['logger']('monitor\x20loop:\x20tick\x20error\x20on\x20'+a+':\x20'+y),c['consecutiveErrors']+=0x1,c['backoffMs']=Math['min'](c['pollIntervalMs']*0x2**c['consecutiveErrors'],MAX_BACKOFF_MS),undefined;}finally{c['ticking']=![],c['started']&&this['schedule'](c,c['backoffMs']>0x0?c['backoffMs']:c['pollIntervalMs']);}}['schedule'](a,b){if(a['timer']!==undefined)this['deps']['clearTimer'](a['timer']);const c=this['deps']['setTimer'](()=>{a['timer']=undefined,void this['tick'](a['network']);},Math['max'](0x0,b));c?.['unref']?.(),a['timer']=c;}async['acquireLease'](a,b){const c=leaseKey(a['network']),d=this['deps']['now']();let e;try{const i=await this['deps']['storage']['get'](c);e=i?JSON['parse'](i):undefined;}catch{e=undefined;}const f={'pid':this['deps']['pid'],'boot_id':this['deps']['bootId']},g=!!e&&e['boot_id']===f['boot_id']&&e['pid']===f['pid'],h=!e||d-Number(e['heartbeat_at']??0x0)>0x2*b;if(g||h)return await this['deps']['storage']['put'](c,JSON['stringify']({...f,'heartbeat_at':d})),a['holdsLease']=!![],a['leaseHolder']=f,!![];return a['holdsLease']=![],a['leaseHolder']={'pid':e['pid'],'boot_id':e['boot_id']},![];}async['getScope'](a,b){if(!a['scope'])try{const c=await this['deps']['loadScope'](a['network']);c&&(a['scope']=c,a['lastScopeRefreshAt']=Number(c['resolved_at'])||0x0);}catch{}if(!a['scope']){a['lastScopeRefreshAt']=this['deps']['now']();const {snapshot:d,changed:e}=await this['deps']['resolveScope'](a['network'],b);a['scope']=d;if(e){const f=Number(b['loop']?.['backfill_days']??LOOP_DEFAULTS['backfill_days']);await this['deps']['router']['backfillAnnotations'](a['network'],this['deps']['store'],d,f,b);}}return a['scope'];}async['capture'](a,b){const c=a['network'],d=await this['deps']['store']['getCursors'](c);let f=0x0;const g=[],h=[...MONITOR_CAPTURE_TYPES];if(b['events']?.[PAYMENT_EVENT_TYPE]===!![])h['push'](PAYMENT_EVENT_TYPE);for(const i of h){const j=EVENT_MODULE_OF[i];if(!j)continue;try{const k=d['cursors'][i];let l=null;if(!k){let m=null,n=0x0;while(n<SEED_MAX){const o=await this['deps']['queryEvents']({'type':i,'cursor':m,'limit':Math['min'](SEED_PAGE,SEED_MAX-n),'order':'descending','network':c}),p=(o?.['data']??[])['map'](q=>normalizeMonitorEvent(q));if(p['length']===0x0)break;if(l===null)l=p[0x0];n+=p['length'],f+=await this['deps']['store']['insert'](c,j,p),g['push'](...p);if(!o?.['hasNextPage']||!o?.['nextCursor'])break;m=o['nextCursor'];}}else{const q=await this['deps']['queryEvents']({'type':i,'cursor':k,'limit':POLL_BATCH,'order':'ascending','network':c}),r=(q?.['data']??[])['map'](s=>normalizeMonitorEvent(s));f+=await this['deps']['store']['insert'](c,j,r),g['push'](...r);if(r['length']>0x0)l=r[r['length']-0x1];}if(l?.['id']){const s=d['cursors'][i];(!s||BigInt(l['id']['eventSeq'])>BigInt(s['eventSeq']||'0'))&&(d['cursors'][i]={'eventSeq':String(l['id']['eventSeq']),'txDigest':String(l['id']['txDigest'])});}}catch(t){const u=String(t?.['message']??t);this['deps']['logger']('monitor\x20loop:\x20type\x20'+i+'\x20poll\x20error:\x20'+u),/referenced transaction/i['test'](u)&&(delete d['cursors'][i],this['deps']['logger']('monitor\x20loop:\x20type\x20'+i+'\x20cursor\x20invalid\x20—\x20dropped,\x20will\x20re-seed\x20next\x20cycle'));}}return await this['deps']['store']['saveCursors'](c,d['cursors'],this['deps']['now']()),{'newCount':f,'events':g};}}export const monitorLoop=new MonitorLoop();
1
+ import{randomUUID}from'node:crypto';import{Config,SQLiteStorage}from'@wowok/wowok/w/local';import{query_events}from'@wowok/wowok';import{monitorEventStore}from'./EventStore.js';import{subscriptionStore}from'./SubscriptionStore.js';import{loadScopeSnapshot,resolveScope}from'./ScopeResolver.js';import{annotateBatch,backfillAnnotations}from'./EventRouter.js';import{bridgeMonitorProblems}from'./ProblemBridge.js';import{bridgeMonitorSuggestions}from'./SuggestionBridge.js';import{EVENT_MODULE_OF,MONITOR_CAPTURE_TYPES,PAYMENT_EVENT_TYPE,normalizeMonitorEvent}from'./normalize.js';import{LOOP_DEFAULTS}from'./types.js';import{goalStore}from'../goal/GoalStore.js';import{runKeeperScan as a260a,realKeeperScanDeps}from'../keeper/KeeperScan.js';import{addProblem,addSuggestion,listProblems,listSuggestions}from'../task/ProcessStore.js';const LEASE_PREFIX='mon_lease:v4:',SEED_PAGE=0x64,SEED_MAX=0x7d0,POLL_BATCH=0x32,MAX_BACKOFF_MS=0x493e0;function netKey(a){return(a||'default')['replace'](/[^a-zA-Z0-9_-]/g,'_');}function leaseKey(a){return''+LEASE_PREFIX+netKey(a);}function realDeps(){return{'store':monitorEventStore,'configStore':subscriptionStore,'storage':new SQLiteStorage(),'resolveScope':(a,b)=>resolveScope(a,b),'loadScope':a=>loadScopeSnapshot(a),'router':{'annotateBatch':annotateBatch,'backfillAnnotations':backfillAnnotations},'queryEvents':a=>query_events({'type':a['type'],'cursor':a['cursor'],'limit':a['limit'],'order':a['order'],'network':a['network']}),'defaultNetwork':()=>Config['Instance']()['network_get'](),'now':()=>Date['now'](),'pid':process['pid'],'bootId':randomUUID(),'logger':a=>console['error']('[monitor]\x20'+a),'openProblems':a=>bridgeMonitorProblems(a,{'getGoal':(b,c)=>goalStore['get'](b,c),'addProblem':addProblem,'listProblems':listProblems,'logger':b=>console['error']('[monitor]\x20'+b)}),'openSuggestions':a=>bridgeMonitorSuggestions(a,{'getGoal':(b,c)=>goalStore['get'](b,c),'addSuggestion':addSuggestion,'listSuggestions':listSuggestions,'logger':b=>console['error']('[monitor]\x20'+b)}),'runKeeperScan':(a,b)=>a260a(a,b,realKeeperScanDeps()),'setTimer':(a,b)=>setTimeout(a,b),'clearTimer':a=>clearTimeout(a)};}function newRuntime(a){return{'network':a,'started':![],'holdsLease':![],'leaseHolder':null,'timer':undefined,'ticking':![],'scope':undefined,'lastScopeRefreshAt':0x0,'pollIntervalMs':LOOP_DEFAULTS['poll_interval_ms'],'lastTickAt':0x0,'lastNewCount':0x0,'lastSummary':undefined,'consecutiveErrors':0x0,'backoffMs':0x0};}export class MonitorLoop{['deps'];['runtimes']=new Map();constructor(a){this['deps']={...realDeps(),...a??{}};}async['start'](a){let b=a&&a['length']>0x0?a:undefined;if(!b)b=[await this['deps']['defaultNetwork']()];for(const c of b){const d=netKey(c);if(this['runtimes']['has'](d)){const f=this['runtimes']['get'](d);if(f['started'])continue;f['started']=!![],this['schedule'](f,0x0);continue;}const e=newRuntime(c);e['started']=!![],this['runtimes']['set'](d,e);try{const g=await this['deps']['loadScope'](c);g&&(e['scope']=g,e['lastScopeRefreshAt']=Number(g['resolved_at'])||0x0);}catch{}this['schedule'](e,0x0);}return b;}async['stop'](a){const b=a?[netKey(a)]:[...this['runtimes']['keys']()];for(const c of b){const d=this['runtimes']['get'](c);if(!d)continue;d['started']=![];d['timer']!==undefined&&(this['deps']['clearTimer'](d['timer']),d['timer']=undefined);if(d['holdsLease']){d['holdsLease']=![];try{await this['deps']['storage']['del'](leaseKey(d['network']));}catch{}}this['runtimes']['delete'](c);}}['status'](a){const b=a?this['runtimes']['get'](netKey(a)):[...this['runtimes']['values']()][0x0];if(!b)return{'running':![],'lease_holder':null,'last_tick_at':0x0,'last_new_count':0x0,'scope_version':0x0,'backoff_ms':0x0};return{'running':b['started']&&b['holdsLease'],'lease_holder':b['leaseHolder']?b['leaseHolder']['pid']+':'+b['leaseHolder']['boot_id']:null,'last_tick_at':b['lastTickAt'],'last_new_count':b['lastNewCount'],'scope_version':b['scope']?.['version']??0x0,'backoff_ms':b['backoffMs'],...b['lastSummary']?{'last_tick':b['lastSummary']}:{}};}['kick'](a){const b=this['runtimes']['get'](netKey(a));if(!b||!b['started']||!b['holdsLease']||b['ticking'])return;if(this['deps']['now']()-b['lastTickAt']<b['pollIntervalMs'])return;void this['tick'](b['network']);}['invalidateScope'](a){const b=this['runtimes']['get'](netKey(a));if(!b)return;b['scope']=undefined,b['lastScopeRefreshAt']=0x0;}async['tick'](a){const b=netKey(a);let c=this['runtimes']['get'](b);!c&&(c=newRuntime(a),this['runtimes']['set'](b,c));if(c['ticking'])return undefined;c['ticking']=!![];const d=this['deps']['now']();try{const f=await this['deps']['configStore']['getConfig'](a),g=Number(f['loop']?.['poll_interval_ms'])||LOOP_DEFAULTS['poll_interval_ms'];c['pollIntervalMs']=g;const h=await this['acquireLease'](c,g);if(!h)return undefined;const {newCount:i,events:j}=await this['capture'](c,f),k=await this['getScope'](c,f);let l=0x0,m=[];if(i>0x0&&j['length']>0x0){const p=this['deps']['router']['annotateBatch'](j,k,f)['filter'](q=>q['rules']['length']>0x0||q['focus_hit']||q['matched_filters']['length']>0x0);p['length']>0x0&&(await this['deps']['store']['saveAnnotations'](a,p),l=p['length'],m=p);}if(m['length']>0x0&&this['deps']['openProblems'])try{await this['deps']['openProblems']({'network':a,'events':j,'annotations':m,'scope':k});}catch(q){this['deps']['logger']('monitor\x20loop:\x20problem\x20bridge\x20error\x20on\x20'+a+':\x20'+String(q?.['message']??q));}if(m['length']>0x0&&this['deps']['openSuggestions'])try{await this['deps']['openSuggestions']({'network':a,'events':j,'annotations':m,'scope':k});}catch(s){this['deps']['logger']('monitor\x20loop:\x20suggestion\x20bridge\x20error\x20on\x20'+a+':\x20'+String(s?.['message']??s));}if(this['deps']['runKeeperScan'])try{await this['deps']['runKeeperScan'](a,k);}catch(t){this['deps']['logger']('monitor\x20loop:\x20keeper\x20scan\x20error\x20on\x20'+a+':\x20'+String(t?.['message']??t));}const n=Number(f['loop']?.['scope_refresh_ms'])||LOOP_DEFAULTS['scope_refresh_ms'];if(this['deps']['now']()-c['lastScopeRefreshAt']>=n){c['lastScopeRefreshAt']=this['deps']['now']();const {snapshot:u,changed:v}=await this['deps']['resolveScope'](a,f);c['scope']=u;if(v){const w=Number(f['loop']?.['backfill_days']??LOOP_DEFAULTS['backfill_days']),x=await this['deps']['router']['backfillAnnotations'](a,this['deps']['store'],u,w,f);this['deps']['logger']('monitor\x20loop:\x20scope\x20v'+u['version']+'\x20on\x20'+a+'\x20changed\x20—\x20backfill\x20rescanned\x20'+x['rescanned']+',\x20updated\x20'+x['updated']);}}c['lastTickAt']=this['deps']['now'](),c['lastNewCount']=i,c['consecutiveErrors']=0x0,c['backoffMs']=0x0;const o={'captured':j['length'],'annotated':l,'duration_ms':this['deps']['now']()-d};return c['lastSummary']=o,o;}catch(y){const z=String(y?.['message']??y);return this['deps']['logger']('monitor\x20loop:\x20tick\x20error\x20on\x20'+a+':\x20'+z),c['consecutiveErrors']+=0x1,c['backoffMs']=Math['min'](c['pollIntervalMs']*0x2**c['consecutiveErrors'],MAX_BACKOFF_MS),undefined;}finally{c['ticking']=![],c['started']&&this['schedule'](c,c['backoffMs']>0x0?c['backoffMs']:c['pollIntervalMs']);}}['schedule'](a,b){if(a['timer']!==undefined)this['deps']['clearTimer'](a['timer']);const c=this['deps']['setTimer'](()=>{a['timer']=undefined,void this['tick'](a['network']);},Math['max'](0x0,b));c?.['unref']?.(),a['timer']=c;}async['acquireLease'](a,b){const c=leaseKey(a['network']),d=this['deps']['now']();let e;try{const i=await this['deps']['storage']['get'](c);e=i?JSON['parse'](i):undefined;}catch{e=undefined;}const f={'pid':this['deps']['pid'],'boot_id':this['deps']['bootId']},g=!!e&&e['boot_id']===f['boot_id']&&e['pid']===f['pid'],h=!e||d-Number(e['heartbeat_at']??0x0)>0x2*b;if(g||h)return await this['deps']['storage']['put'](c,JSON['stringify']({...f,'heartbeat_at':d})),a['holdsLease']=!![],a['leaseHolder']=f,!![];return a['holdsLease']=![],a['leaseHolder']={'pid':e['pid'],'boot_id':e['boot_id']},![];}async['getScope'](a,b){if(!a['scope'])try{const c=await this['deps']['loadScope'](a['network']);c&&(a['scope']=c,a['lastScopeRefreshAt']=Number(c['resolved_at'])||0x0);}catch{}if(!a['scope']){a['lastScopeRefreshAt']=this['deps']['now']();const {snapshot:d,changed:e}=await this['deps']['resolveScope'](a['network'],b);a['scope']=d;if(e){const f=Number(b['loop']?.['backfill_days']??LOOP_DEFAULTS['backfill_days']);await this['deps']['router']['backfillAnnotations'](a['network'],this['deps']['store'],d,f,b);}}return a['scope'];}async['capture'](a,b){const c=a['network'],d=await this['deps']['store']['getCursors'](c);let f=0x0;const g=[],h=[...MONITOR_CAPTURE_TYPES];if(b['events']?.[PAYMENT_EVENT_TYPE]===!![])h['push'](PAYMENT_EVENT_TYPE);for(const i of h){const j=EVENT_MODULE_OF[i];if(!j)continue;try{const k=d['cursors'][i];let l=null;if(!k){let m=null,n=0x0;while(n<SEED_MAX){const o=await this['deps']['queryEvents']({'type':i,'cursor':m,'limit':Math['min'](SEED_PAGE,SEED_MAX-n),'order':'descending','network':c}),p=(o?.['data']??[])['map'](q=>normalizeMonitorEvent(q));if(p['length']===0x0)break;if(l===null)l=p[0x0];n+=p['length'],f+=await this['deps']['store']['insert'](c,j,p),g['push'](...p);if(!o?.['hasNextPage']||!o?.['nextCursor'])break;m=o['nextCursor'];}}else{const q=await this['deps']['queryEvents']({'type':i,'cursor':k,'limit':POLL_BATCH,'order':'ascending','network':c}),r=(q?.['data']??[])['map'](s=>normalizeMonitorEvent(s));f+=await this['deps']['store']['insert'](c,j,r),g['push'](...r);if(r['length']>0x0)l=r[r['length']-0x1];}if(l?.['id']){const s=d['cursors'][i];(!s||BigInt(l['id']['eventSeq'])>BigInt(s['eventSeq']||'0'))&&(d['cursors'][i]={'eventSeq':String(l['id']['eventSeq']),'txDigest':String(l['id']['txDigest'])});}}catch(t){const u=String(t?.['message']??t);this['deps']['logger']('monitor\x20loop:\x20type\x20'+i+'\x20poll\x20error:\x20'+u),/referenced transaction/i['test'](u)&&(delete d['cursors'][i],this['deps']['logger']('monitor\x20loop:\x20type\x20'+i+'\x20cursor\x20invalid\x20—\x20dropped,\x20will\x20re-seed\x20next\x20cycle'));}}return await this['deps']['store']['saveCursors'](c,d['cursors'],this['deps']['now']()),{'newCount':f,'events':g};}}export const monitorLoop=new MonitorLoop();
@@ -1 +1 @@
1
- import{SQLiteStorage}from'@wowok/wowok/w/local';import{query_objects,queryOrdersByUser,objectTypeFromAddress}from'@wowok/wowok';import{fetchEntityPermission,fetchObjectLinkerCore,fetchObjectLinkerTx,fetchServiceOrders,listLocalAccounts}from'../knowledge/workflow-guidance.js';import{monitorEventStore}from'./EventStore.js';import{LOOP_DEFAULTS,normalizeAddr,shortId}from'./types.js';const SCOPE_PREFIX='mon_scope:v4:',SCOPE_HIST_PREFIX='mon_scope_hist:v4:',SCOPE_HISTORY_KEEP=0x5,FAVOR_SCAN_MAX=0x1388;function netKey(a){return(a||'default')['replace'](/[^a-zA-Z0-9_-]/g,'_');}function realDeps(){return{'listLocalAccounts':()=>listLocalAccounts(),'fetchEntityPermission':(a,b)=>fetchEntityPermission(a,b),'fetchObjectLinkerCore':(a,b)=>fetchObjectLinkerCore(a,b),'fetchObjectLinkerTx':(a,b)=>fetchObjectLinkerTx(a,b),'queryServiceOrders':a=>fetchServiceOrders(a['address'],a['network']),'queryOrdersByUser':a=>queryOrdersByUser({'address':a['address'],'network':a['network']}),'queryObjects':a=>query_objects({'objects':a['objects'],'network':a['network']}),'objectTypeFromAddress':a=>objectTypeFromAddress(a),'store':monitorEventStore,'storage':new SQLiteStorage(),'now':()=>Date['now']()};}function canonicalize(a){if(Array['isArray'](a))return a['map'](canonicalize)['sort']((c,d)=>{const e=JSON['stringify'](c),f=JSON['stringify'](d);return e<f?-0x1:e>f?0x1:0x0;});if(a&&typeof a==='object'){const b={};for(const c of Object['keys'](a)['sort']()){b[c]=canonicalize(a[c]);}return b;}return a;}function semanticHashOf(a){return JSON['stringify'](canonicalize({'accounts':a['accounts'],'permissions':a['permissions'],'managed_objects':a['managed_objects'],'services':a['services'],'orders':a['orders'],'order_children':a['order_children'],'focus':a['focus']}));}function lowerTypeOf(a,b){try{return a['objectTypeFromAddress'](b)?.['toLowerCase']()??null;}catch{return null;}}function objectFields(a){return a?.['data']??a??{};}function childrenOfOrder(a){const b=[],c=Array['isArray'](a?.['dispute'])?a['dispute']:[];for(const e of c){if(typeof e==='string'&&e)b['push']({'type':'arb','object':e});}return typeof a?.['progress']==='string'&&a['progress']&&b['push']({'type':'progress','object':a['progress']}),typeof a?.['allocation']==='string'&&a['allocation']&&b['push']({'type':'allocation','object':a['allocation']}),b;}export async function loadScopeSnapshot(a,b){try{const c=await(b??new SQLiteStorage())['get'](''+SCOPE_PREFIX+netKey(a));if(!c)return undefined;const d=JSON['parse'](c);return d&&typeof d['version']==='number'?d:undefined;}catch{return undefined;}}export async function resolveScope(a,b,e){const g={...realDeps(),...e??{}},h=g['now'](),j=[],k=async(N,O)=>{try{return await O();}catch{return j['push'](N),undefined;}},l=''+SCOPE_PREFIX+netKey(a),n=''+SCOPE_HIST_PREFIX+netKey(a);let p;try{const N=await g['storage']['get'](l);p=N?JSON['parse'](N):undefined;}catch{p=undefined;}let q;if(b['scope']['accounts']==='local-all'){const O=await k('accounts',()=>g['listLocalAccounts']());q=(O??[])['map'](P=>P['address'])['filter'](P=>typeof P==='string'&&P);}else q=[...b['scope']['accounts']];q=[...new Set(q)];const s=b['scope']['rules'],t=[],u=[],w=new Map();if(s['managed_objects']||s['merchant_orders']){for(const R of q){const S=await k('entity_permission:'+shortId(R),()=>g['fetchEntityPermission'](R,a));for(const T of S?.['items']??[]){if(T?.['permission'])t['push'](T['permission']);}}const P=[...new Set(t)];t['length']=0x0,t['push'](...P);const Q=new Set();for(const U of P){const V=await k('object_linker_core:'+shortId(U),()=>g['fetchObjectLinkerCore'](U,a)),W=await k('object_linker_tx:'+shortId(U),()=>g['fetchObjectLinkerTx'](U,a)),X=[...(V?.['items']??[])['map'](Y=>Y?.['who']),...(W?.['items']??[])['map'](Y=>Y?.['who'])];for(const Y of X){if(typeof Y!=='string'||!Y)continue;const Z=lowerTypeOf(g,Y);if(!Z)continue;const a0=normalizeAddr(Y);if(Q['has'](a0))continue;Q['add'](a0),u['push']({'type':Z,'object':Y}),w['set'](a0,U);}}}const x=u['filter'](a1=>a1['type']==='service')['map'](a1=>a1['object']),y=new Map(),z=(a1,a2)=>{const a3=normalizeAddr(a1);if(!a3)return;const a4=y['get'](a3)??{'order':a1,'merchant':![],'buyer':![]};a4[a2]=!![],y['set'](a3,a4);};if(s['merchant_orders'])for(const a1 of x){const a2=await k('service_orders:'+shortId(a1),()=>g['queryServiceOrders']({'address':a1,'network':a}));for(const a3 of a2?.['items']??[]){if(typeof a3?.['who']==='string'&&a3['who'])z(a3['who'],'merchant');}}if(s['my_orders'])for(const a4 of q){const a5=await k('user_orders:'+shortId(a4),()=>g['queryOrdersByUser']({'address':a4,'network':a}));for(const a6 of a5??[]){if(!a6?.['is_owner']&&!a6?.['is_agent'])continue;const a7=a6?.['order']?.['object']??a6?.['order']?.['id'];if(typeof a7==='string'&&a7)z(a7,'buyer');}}const A=[...y['values']()]['map'](a8=>({'order':a8['order'],'role':a8['merchant']&&a8['buyer']?'both':a8['merchant']?'merchant':'buyer'})),B=[],C=new Map();if(s['order_children']&&y['size']>0x0){const a8=[...y['values']()]['map'](a9=>a9['order']);for(let a9=0x0;a9<a8['length'];a9+=0x32){const aa=a8['slice'](a9,a9+0x32),ab=await k('order_objects:'+shortId(aa[0x0]),()=>g['queryObjects']({'objects':aa,'network':a}));for(const ac of ab?.['objects']??[]){const ad=objectFields(ac),ae=ac?.['object']??ad?.['object']??ad?.['id'];if(typeof ae!=='string'||!ae)continue;for(const af of childrenOfOrder(ad)){const ag=normalizeAddr(af['object']);if(C['has'](ag))continue;C['set'](ag,ae),B['push'](af);}}}}const D=(b['scope']['focus_objects']??[])['map'](ah=>({...ah})),E=new Set(D['map'](ah=>normalizeAddr(ah['object']))),F=new Map();for(const ah of p?.['focus']??[]){if(ah?.['reason']==='favor'&&ah['object'])F['set'](normalizeAddr(ah['object']),ah['added_at']);}if(s['favor_objects']&&q['length']>0x0){const ai=Number(b['loop']?.['backfill_days']??LOOP_DEFAULTS['backfill_days']),aj=h-Math['max'](0x0,ai)*0x5265c00,ak=new Set(q['map'](al=>normalizeAddr(al)));try{let al=0x0;for(;;){const am=await g['store']['list'](a,{'module':'arb','eventType':'FeedbackEvent','since':aj,'offset':al,'limit':0xc8});if(am['events']['length']===0x0)break;for(const an of am['events']){const ao=an['event'],ap=normalizeAddr(ao?.['sender']);if(!ap||!ak['has'](ap))continue;const aq=ao?.['object'],ar=normalizeAddr(typeof aq==='string'?aq:'');if(!ar||E['has'](ar))continue;E['add'](ar),D['push']({'object':aq,'added_at':F['get'](ar)??h,'reason':'favor','closure':!![]});}al+=am['events']['length'];if(al>=am['total']||al>=FAVOR_SCAN_MAX)break;}}catch{j['push']('favor_scan');}}const G={},H=(as,at)=>{const au=normalizeAddr(as);if(!au)return;const av=G[au]??=[],aw=av['some'](ax=>ax['rule']===at['rule']&&normalizeAddr(ax['object'])===normalizeAddr(at['object']));if(!aw)av['push'](at);};if(s['managed_objects'])for(const as of u){const at=w['get'](normalizeAddr(as['object']));H(as['object'],{'rule':'managed_objects','object':as['object'],'detail':at?as['type']+'\x20'+shortId(as['object'])+'\x20of\x20permission\x20'+shortId(at):as['type']+'\x20'+shortId(as['object'])+'\x20(managed)'});}for(const au of A){(au['role']==='merchant'||au['role']==='both')&&H(au['order'],{'rule':'merchant_orders','object':au['order'],'detail':'order\x20'+shortId(au['order'])+'\x20(merchant)'}),(au['role']==='buyer'||au['role']==='both')&&H(au['order'],{'rule':'my_orders','object':au['order'],'detail':'order\x20'+shortId(au['order'])+'\x20(buyer)'});}if(s['order_children'])for(const av of B){const aw=C['get'](normalizeAddr(av['object']));H(av['object'],{'rule':'order_children','object':av['object'],'detail':aw?av['type']+'\x20'+shortId(av['object'])+'\x20of\x20order\x20'+shortId(aw):av['type']+'\x20'+shortId(av['object'])+'\x20(order\x20child)'});}for(const ax of D){const ay=lowerTypeOf(g,ax['object']);H(ax['object'],{'rule':'focus','object':ax['object'],'detail':'focused\x20'+(ay??'object')+'\x20'+shortId(ax['object'])});if(!ax['closure'])continue;if(ay==='service'){const az=await k('focus_service_orders:'+shortId(ax['object']),()=>g['queryServiceOrders']({'address':ax['object'],'network':a}));for(const aA of az?.['items']??[]){if(typeof aA?.['who']!=='string'||!aA['who'])continue;H(aA['who'],{'rule':'focus','object':aA['who'],'detail':'order\x20'+shortId(aA['who'])+'\x20of\x20focused\x20service\x20'+shortId(ax['object'])});}}else{if(ay==='order'){const aB=await k('focus_order:'+shortId(ax['object']),()=>g['queryObjects']({'objects':[ax['object']],'network':a})),aC=objectFields(aB?.['objects']?.[0x0]);for(const aD of childrenOfOrder(aC)){H(aD['object'],{'rule':'focus','object':aD['object'],'detail':aD['type']+'\x20'+shortId(aD['object'])+'\x20of\x20focused\x20order\x20'+shortId(ax['object'])});}}}}const I={'accounts':q,'permissions':t,'managed_objects':u,'services':x,'orders':A,'order_children':B,'focus':D},J=semanticHashOf(I),K=!p||semanticHashOf(p)!==J,L=p?K?p['version']+0x1:p['version']:0x1,M={'version':L,'resolved_at':h,...I,'index':G,...j['length']>0x0?{'data_gaps':j}:{}};try{await g['storage']['put'](l,JSON['stringify'](M));if(K){let aE=[];try{const aF=await g['storage']['get'](n),aG=aF?JSON['parse'](aF):undefined;aE=Array['isArray'](aG?.['snapshots'])?aG['snapshots']:[];}catch{aE=[];}aE['unshift'](M),await g['storage']['put'](n,JSON['stringify']({'snapshots':aE['slice'](0x0,SCOPE_HISTORY_KEEP)}));}}catch{j['push']('snapshot_persist');}return{'snapshot':M,'changed':K};}
1
+ import{SQLiteStorage}from'@wowok/wowok/w/local';import{query_objects,queryOrdersByUser,objectTypeFromAddress}from'@wowok/wowok';import{fetchEntityPermission,fetchObjectLinkerCore,fetchObjectLinkerTx,fetchServiceOrders,listLocalAccounts}from'../knowledge/workflow-guidance.js';import{monitorEventStore}from'./EventStore.js';import{formatShortAddress}from'../persona/address-format.js';import{LOOP_DEFAULTS,normalizeAddr}from'./types.js';const SCOPE_PREFIX='mon_scope:v4:',SCOPE_HIST_PREFIX='mon_scope_hist:v4:',SCOPE_HISTORY_KEEP=0x5,FAVOR_SCAN_MAX=0x1388;function netKey(a){return(a||'default')['replace'](/[^a-zA-Z0-9_-]/g,'_');}function realDeps(){return{'listLocalAccounts':()=>listLocalAccounts(),'fetchEntityPermission':(a,b)=>fetchEntityPermission(a,b),'fetchObjectLinkerCore':(a,b)=>fetchObjectLinkerCore(a,b),'fetchObjectLinkerTx':(a,b)=>fetchObjectLinkerTx(a,b),'queryServiceOrders':a=>fetchServiceOrders(a['address'],a['network']),'queryOrdersByUser':a=>queryOrdersByUser({'address':a['address'],'network':a['network']}),'queryObjects':a=>query_objects({'objects':a['objects'],'network':a['network']}),'objectTypeFromAddress':a=>objectTypeFromAddress(a),'store':monitorEventStore,'storage':new SQLiteStorage(),'now':()=>Date['now']()};}function canonicalize(a){if(Array['isArray'](a))return a['map'](canonicalize)['sort']((c,d)=>{const e=JSON['stringify'](c),f=JSON['stringify'](d);return e<f?-0x1:e>f?0x1:0x0;});if(a&&typeof a==='object'){const b={};for(const c of Object['keys'](a)['sort']()){b[c]=canonicalize(a[c]);}return b;}return a;}function semanticHashOf(a){return JSON['stringify'](canonicalize({'accounts':a['accounts'],'permissions':a['permissions'],'managed_objects':a['managed_objects'],'services':a['services'],'orders':a['orders'],'order_children':a['order_children'],'focus':a['focus']}));}function lowerTypeOf(a,b){try{return a['objectTypeFromAddress'](b)?.['toLowerCase']()??null;}catch{return null;}}function objectFields(a){return a?.['data']??a??{};}function childrenOfOrder(a){const b=[],c=Array['isArray'](a?.['dispute'])?a['dispute']:[];for(const e of c){if(typeof e==='string'&&e)b['push']({'type':'arb','object':e});}return typeof a?.['progress']==='string'&&a['progress']&&b['push']({'type':'progress','object':a['progress']}),typeof a?.['allocation']==='string'&&a['allocation']&&b['push']({'type':'allocation','object':a['allocation']}),b;}export async function loadScopeSnapshot(a,b){try{const c=await(b??new SQLiteStorage())['get'](''+SCOPE_PREFIX+netKey(a));if(!c)return undefined;const d=JSON['parse'](c);return d&&typeof d['version']==='number'?d:undefined;}catch{return undefined;}}export async function resolveScope(a,b,e){const g={...realDeps(),...e??{}},h=g['now'](),j=[],k=async(N,O)=>{try{return await O();}catch{return j['push'](N),undefined;}},l=''+SCOPE_PREFIX+netKey(a),n=''+SCOPE_HIST_PREFIX+netKey(a);let p;try{const N=await g['storage']['get'](l);p=N?JSON['parse'](N):undefined;}catch{p=undefined;}let q;if(b['scope']['accounts']==='local-all'){const O=await k('accounts',()=>g['listLocalAccounts']());q=(O??[])['map'](P=>P['address'])['filter'](P=>typeof P==='string'&&P);}else q=[...b['scope']['accounts']];q=[...new Set(q)];const s=b['scope']['rules'],t=[],u=[],w=new Map();if(s['managed_objects']||s['merchant_orders']){for(const R of q){const S=await k('entity_permission:'+formatShortAddress(R),()=>g['fetchEntityPermission'](R,a));for(const T of S?.['items']??[]){if(T?.['permission'])t['push'](T['permission']);}}const P=[...new Set(t)];t['length']=0x0,t['push'](...P);const Q=new Set();for(const U of P){const V=await k('object_linker_core:'+formatShortAddress(U),()=>g['fetchObjectLinkerCore'](U,a)),W=await k('object_linker_tx:'+formatShortAddress(U),()=>g['fetchObjectLinkerTx'](U,a)),X=[...(V?.['items']??[])['map'](Y=>Y?.['who']),...(W?.['items']??[])['map'](Y=>Y?.['who'])];for(const Y of X){if(typeof Y!=='string'||!Y)continue;const Z=lowerTypeOf(g,Y);if(!Z)continue;const a0=normalizeAddr(Y);if(Q['has'](a0))continue;Q['add'](a0),u['push']({'type':Z,'object':Y}),w['set'](a0,U);}}}const x=u['filter'](a1=>a1['type']==='service')['map'](a1=>a1['object']),y=new Map(),z=(a1,a2)=>{const a3=normalizeAddr(a1);if(!a3)return;const a4=y['get'](a3)??{'order':a1,'merchant':![],'buyer':![]};a4[a2]=!![],y['set'](a3,a4);};if(s['merchant_orders'])for(const a1 of x){const a2=await k('service_orders:'+formatShortAddress(a1),()=>g['queryServiceOrders']({'address':a1,'network':a}));for(const a3 of a2?.['items']??[]){if(typeof a3?.['who']==='string'&&a3['who'])z(a3['who'],'merchant');}}if(s['my_orders'])for(const a4 of q){const a5=await k('user_orders:'+formatShortAddress(a4),()=>g['queryOrdersByUser']({'address':a4,'network':a}));for(const a6 of a5??[]){if(!a6?.['is_owner']&&!a6?.['is_agent'])continue;const a7=a6?.['order']?.['object']??a6?.['order']?.['id'];if(typeof a7==='string'&&a7)z(a7,'buyer');}}const A=[...y['values']()]['map'](a8=>({'order':a8['order'],'role':a8['merchant']&&a8['buyer']?'both':a8['merchant']?'merchant':'buyer'})),B=[],C=new Map();if(s['order_children']&&y['size']>0x0){const a8=[...y['values']()]['map'](a9=>a9['order']);for(let a9=0x0;a9<a8['length'];a9+=0x32){const aa=a8['slice'](a9,a9+0x32),ab=await k('order_objects:'+formatShortAddress(aa[0x0]),()=>g['queryObjects']({'objects':aa,'network':a}));for(const ac of ab?.['objects']??[]){const ad=objectFields(ac),ae=ac?.['object']??ad?.['object']??ad?.['id'];if(typeof ae!=='string'||!ae)continue;for(const af of childrenOfOrder(ad)){const ag=normalizeAddr(af['object']);if(C['has'](ag))continue;C['set'](ag,ae),B['push'](af);}}}}const D=(b['scope']['focus_objects']??[])['map'](ah=>({...ah})),E=new Set(D['map'](ah=>normalizeAddr(ah['object']))),F=new Map();for(const ah of p?.['focus']??[]){if(ah?.['reason']==='favor'&&ah['object'])F['set'](normalizeAddr(ah['object']),ah['added_at']);}if(s['favor_objects']&&q['length']>0x0){const ai=Number(b['loop']?.['backfill_days']??LOOP_DEFAULTS['backfill_days']),aj=h-Math['max'](0x0,ai)*0x5265c00,ak=new Set(q['map'](al=>normalizeAddr(al)));try{let al=0x0;for(;;){const am=await g['store']['list'](a,{'module':'arb','eventType':'FeedbackEvent','since':aj,'offset':al,'limit':0xc8});if(am['events']['length']===0x0)break;for(const an of am['events']){const ao=an['event'],ap=normalizeAddr(ao?.['sender']);if(!ap||!ak['has'](ap))continue;const aq=ao?.['object'],ar=normalizeAddr(typeof aq==='string'?aq:'');if(!ar||E['has'](ar))continue;E['add'](ar),D['push']({'object':aq,'added_at':F['get'](ar)??h,'reason':'favor','closure':!![]});}al+=am['events']['length'];if(al>=am['total']||al>=FAVOR_SCAN_MAX)break;}}catch{j['push']('favor_scan');}}const G={},H=(as,at)=>{const au=normalizeAddr(as);if(!au)return;const av=G[au]??=[],aw=av['some'](ax=>ax['rule']===at['rule']&&normalizeAddr(ax['object'])===normalizeAddr(at['object']));if(!aw)av['push'](at);};if(s['managed_objects'])for(const as of u){const at=w['get'](normalizeAddr(as['object']));H(as['object'],{'rule':'managed_objects','object':as['object'],'detail':at?as['type']+'\x20'+formatShortAddress(as['object'])+'\x20of\x20permission\x20'+formatShortAddress(at):as['type']+'\x20'+formatShortAddress(as['object'])+'\x20(managed)'});}for(const au of A){(au['role']==='merchant'||au['role']==='both')&&H(au['order'],{'rule':'merchant_orders','object':au['order'],'detail':'order\x20'+formatShortAddress(au['order'])+'\x20(merchant)'}),(au['role']==='buyer'||au['role']==='both')&&H(au['order'],{'rule':'my_orders','object':au['order'],'detail':'order\x20'+formatShortAddress(au['order'])+'\x20(buyer)'});}if(s['order_children'])for(const av of B){const aw=C['get'](normalizeAddr(av['object']));H(av['object'],{'rule':'order_children','object':av['object'],'detail':aw?av['type']+'\x20'+formatShortAddress(av['object'])+'\x20of\x20order\x20'+formatShortAddress(aw):av['type']+'\x20'+formatShortAddress(av['object'])+'\x20(order\x20child)'});}for(const ax of D){const ay=lowerTypeOf(g,ax['object']);H(ax['object'],{'rule':'focus','object':ax['object'],'detail':'focused\x20'+(ay??'object')+'\x20'+formatShortAddress(ax['object'])});if(!ax['closure'])continue;if(ay==='service'){const az=await k('focus_service_orders:'+formatShortAddress(ax['object']),()=>g['queryServiceOrders']({'address':ax['object'],'network':a}));for(const aA of az?.['items']??[]){if(typeof aA?.['who']!=='string'||!aA['who'])continue;H(aA['who'],{'rule':'focus','object':aA['who'],'detail':'order\x20'+formatShortAddress(aA['who'])+'\x20of\x20focused\x20service\x20'+formatShortAddress(ax['object'])});}}else{if(ay==='order'){const aB=await k('focus_order:'+formatShortAddress(ax['object']),()=>g['queryObjects']({'objects':[ax['object']],'network':a})),aC=objectFields(aB?.['objects']?.[0x0]);for(const aD of childrenOfOrder(aC)){H(aD['object'],{'rule':'focus','object':aD['object'],'detail':aD['type']+'\x20'+formatShortAddress(aD['object'])+'\x20of\x20focused\x20order\x20'+formatShortAddress(ax['object'])});}}}}const I={'accounts':q,'permissions':t,'managed_objects':u,'services':x,'orders':A,'order_children':B,'focus':D},J=semanticHashOf(I),K=!p||semanticHashOf(p)!==J,L=p?K?p['version']+0x1:p['version']:0x1,M={'version':L,'resolved_at':h,...I,'index':G,...j['length']>0x0?{'data_gaps':j}:{}};try{await g['storage']['put'](l,JSON['stringify'](M));if(K){let aE=[];try{const aF=await g['storage']['get'](n),aG=aF?JSON['parse'](aF):undefined;aE=Array['isArray'](aG?.['snapshots'])?aG['snapshots']:[];}catch{aE=[];}aE['unshift'](M),await g['storage']['put'](n,JSON['stringify']({'snapshots':aE['slice'](0x0,SCOPE_HISTORY_KEEP)}));}}catch{j['push']('snapshot_persist');}return{'snapshot':M,'changed':K};}
@@ -2,7 +2,7 @@ import type { GoalRecord, GoalStage } from "../goal/types.js";
2
2
  import type { SuggestionRecord } from "../task/types.js";
3
3
  import type { RelevanceAnnotation, ScopeSnapshot } from "./types.js";
4
4
  export interface ProgressionClassification {
5
- kind: "advance_stage" | "complete_goal";
5
+ kind: "advance_stage" | "complete_goal" | "note";
6
6
  stage?: GoalStage;
7
7
  goal_type?: string;
8
8
  title: string;
@@ -1 +1 @@
1
- import{monitorEventId}from'./EventStore.js';const ARB_STATUS_FINISHED=0x5,STAGE_GATE={'advance_stage':'acting','complete_goal':'monitoring'};export function classifyProgression(a){if(!a||typeof a!=='object')return null;if(a['type']==='NewOrderEvent'){const b=typeof a['order']==='string'?a['order']:null,c=typeof a['service']==='string'?a['service']:null,d=b??c;if(!d)return null;return{'kind':'advance_stage','stage':'monitoring','title':'First\x20order\x20received\x20—\x20enter\x20monitoring','detail':'NewOrderEvent\x20on\x20'+d+(c?'\x20for\x20service\x20'+c:'')+'.\x20The\x20goal\x27s\x20live\x20object\x20now\x20transacts\x20on\x20its\x20own;\x20confirm\x20to\x20enter\x20the\x20monitoring\x20station\x20(auto-binds\x20focus\x20for\x20the\x20order\x20lifecycle).','object':d};}if(a['type']==='ArbEvent'){const e=Number(a['status']);if(e!==ARB_STATUS_FINISHED)return null;const f=typeof a['order']==='string'?a['order']:null,g=typeof a['arb']==='string'?a['arb']:null,h=f??g;if(!h)return null;return{'kind':'complete_goal','title':'Arbitration\x20finished\x20—\x20verify\x20completion','detail':'The\x20dispute\x20covering\x20'+h+'\x20finished\x20(ArbEvent\x20Finished)'+(a['arbitration']?'\x20—\x20arbitration\x20'+a['arbitration']:'')+'.\x20Confirm\x20to\x20run\x20the\x20COMPLETE\x20station:\x20chain\x20conditions\x20are\x20re-verified\x20before\x20the\x20goal\x20closes.','object':h};}if(a['type']==='ServiceEvent'){const i=typeof a['object']==='string'?a['object']:null;if(!i)return null;return{'kind':'complete_goal','goal_type':'publish_service','title':'Service\x20live\x20—\x20verify\x20completion','detail':'ServiceEvent\x20on\x20'+i+(a['description']?'\x20('+a['description']+')':'')+'.\x20Confirm\x20to\x20run\x20the\x20COMPLETE\x20station:\x20the\x20service\x20conjunction\x20(healthy,\x20sales,\x20machine,\x20permission)\x20is\x20re-verified\x20on\x20chain.','object':i};}return null;}const EVENT_OBJECT_FIELDS=['order','service','arb','arbitration','object','progress'];export async function bridgeMonitorSuggestions(b,c){const {network:d,events:g,annotations:h,scope:i}=b;try{const j=new Set(h['map'](n=>n['event_id'])),k=new Map();for(const n of h){k['set'](n['event_id'],n['rules']['map'](o=>o['object']));}const l=new Map();for(const o of i['focus']??[]){if(o['goal_id']&&o['object'])l['set'](o['object'],o['goal_id']);}if(l['size']===0x0)return 0x0;const m=[];for(const p of g){const q=monitorEventId(p?.['id']);if(!q||!j['has'](q))continue;const r=classifyProgression(p);if(!r)continue;const s=[...k['get'](q)??[],...EVENT_OBJECT_FIELDS['map'](y=>p[y])['filter'](y=>typeof y==='string'&&y['length']>0x0)];let t;for(const y of s){const z=l['get'](y);if(z){t=z;break;}}if(!t)continue;const u=await c['getGoal'](d,t),v=u?.['process']?.['dir'];if(!u||!v)continue;const w=STAGE_GATE[r['kind']];if(w&&u['stage']!==w)continue;if(r['goal_type']&&u['goal_type']!==r['goal_type'])continue;const x=c['listSuggestions'](v)['some'](A=>A['origin']?.['source']==='monitor'&&A['origin']?.['event_id']===q);if(x)continue;c['addSuggestion'](v,{'object':r['object'],'kind':r['kind'],...r['stage']?{'stage':r['stage']}:{},'title':r['title'],'detail':r['detail'],'origin':{'source':'monitor','network':d,'event_id':q,'event_type':String(p['type']??'unknown')}}),m['push'](q);}return m['length']>0x0&&c['logger']('suggestion\x20bridge:\x20opened\x20'+m['length']+'\x20suggestion(s)\x20on\x20'+d+'\x20from\x20monitor\x20progressions'),m['length'];}catch(A){return c['logger']('suggestion\x20bridge:\x20skipped\x20('+String(A?.['message']??A)+')'),0x0;}}
1
+ import{monitorEventId}from'./EventStore.js';const ARB_STATUS_VOTING=0x2,ARB_STATUS_ARBITRATED=0x3,ARB_STATUS_FINISHED=0x5,STAGE_GATE={'advance_stage':'acting','complete_goal':'monitoring'};export function classifyProgression(a){if(!a||typeof a!=='object')return null;if(a['type']==='NewOrderEvent'){const b=typeof a['order']==='string'?a['order']:null,c=typeof a['service']==='string'?a['service']:null,d=b??c;if(!d)return null;return{'kind':'advance_stage','stage':'monitoring','title':'First\x20order\x20received\x20—\x20enter\x20monitoring','detail':'NewOrderEvent\x20on\x20'+d+(c?'\x20for\x20service\x20'+c:'')+'.\x20The\x20goal\x27s\x20live\x20object\x20now\x20transacts\x20on\x20its\x20own;\x20confirm\x20to\x20enter\x20the\x20monitoring\x20station\x20(auto-binds\x20focus\x20for\x20the\x20order\x20lifecycle).','object':d};}if(a['type']==='ArbEvent'){const e=Number(a['status']),f=typeof a['order']==='string'?a['order']:null,g=typeof a['arb']==='string'?a['arb']:null,h=f??g;if(!h)return null;if(e===ARB_STATUS_FINISHED)return{'kind':'complete_goal','title':'Arbitration\x20finished\x20—\x20verify\x20completion','detail':'The\x20dispute\x20covering\x20'+h+'\x20finished\x20(ArbEvent\x20Finished)'+(a['arbitration']?'\x20—\x20arbitration\x20'+a['arbitration']:'')+'.\x20Confirm\x20to\x20run\x20the\x20COMPLETE\x20station:\x20chain\x20conditions\x20are\x20re-verified\x20before\x20the\x20goal\x20closes.','object':h};if(e===ARB_STATUS_VOTING)return{'kind':'note','title':'Arbitration\x20voting\x20started\x20—\x20cast\x20your\x20vote','detail':'The\x20dispute\x20covering\x20'+h+'\x20entered\x20Voting\x20(ArbEvent\x20status\x202)'+(g?'\x20—\x20Arb\x20'+g:'')+'.\x20If\x20you\x20are\x20a\x20voting\x20guard\x20member:\x20read\x20the\x20Arb\x20object\x27s\x20voting_deadline\x20and\x20cast\x20your\x20vote\x20via\x20the\x20arbitration\x20workflow\x20(wowok-arbitrator\x20skill)\x20before\x20it\x20passes\x20—\x20the\x20deadline\x20itself\x20never\x20fires\x20an\x20event.\x20Parties:\x20voting\x20is\x20underway;\x20the\x20verdict\x20arrives\x20as\x20Arbitrated\x20(objection\x20window),\x20then\x20Finished.','object':h};if(e===ARB_STATUS_ARBITRATED)return{'kind':'note','title':'Verdict\x20reached\x20—\x20objection\x20window\x20open','detail':'The\x20dispute\x20covering\x20'+h+'\x20was\x20Arbitrated\x20(ArbEvent\x20status\x203):\x20voting\x20closed\x20and\x20the\x20verdict\x20is\x20on-chain'+(g?'\x20(Arb\x20'+g+')':'')+'.\x20The\x20objection\x20window\x20is\x20now\x20open\x20—\x20contest\x20the\x20verdict\x20BEFORE\x20it\x20finalizes\x20(Finished),\x20or\x20no\x20action\x20is\x20needed.','object':h};return null;}if(a['type']==='FeedbackEvent'){const i=typeof a['object']==='string'?a['object']:null;if(!i)return null;const j=typeof a['feedback']==='string'&&a['feedback']?a['feedback']['slice'](0x0,0x8c):null;return{'kind':'note','title':'Feedback\x20recorded\x20on\x20an\x20arbitration\x20case','detail':'FeedbackEvent\x20on\x20Arb\x20'+i+(j?':\x20\x22'+j+'\x22':'')+'.\x20The\x20feedback\x20joins\x20the\x20case\x27s\x20permanent\x20on-chain\x20record\x20and\x20feeds\x20the\x20voters\x27\x20reputation\x20—\x20review\x20it\x20in\x20the\x20arbitration\x20workflow.','object':i};}if(a['type']==='DemandFeedbackEvent'){const k=typeof a['demand']==='string'?a['demand']:null;if(!k)return null;const l=typeof a['service']==='string'?a['service']:null,m=a['acceptance_score']!==null&&a['acceptance_score']!==undefined?String(a['acceptance_score']):null,n=typeof a['feedback']==='string'&&a['feedback']?a['feedback']['slice'](0x0,0x8c):null;return{'kind':'note','title':'Presentation\x20feedback\x20recorded','detail':'DemandEvent\x20on\x20demand\x20'+k+(l?'\x20—\x20presented\x20service\x20'+l:'')+(m?'\x20—\x20acceptance_score\x20'+m:'')+(n?'\x20—\x20\x22'+n+'\x22':'')+'.\x20The\x20score\x20becomes\x20the\x20presenter\x27s\x20permanent\x20on-chain\x20reputation\x20signal;\x20the\x20presenter\x20should\x20review\x20the\x20feedback\x20and\x20improve.','object':k};}if(a['type']==='ServiceEvent'){const o=typeof a['object']==='string'?a['object']:null;if(!o)return null;return{'kind':'complete_goal','goal_type':'publish_service','title':'Service\x20live\x20—\x20verify\x20completion','detail':'ServiceEvent\x20on\x20'+o+(a['description']?'\x20('+a['description']+')':'')+'.\x20Confirm\x20to\x20run\x20the\x20COMPLETE\x20station:\x20the\x20service\x20conjunction\x20(healthy,\x20sales,\x20machine,\x20permission)\x20is\x20re-verified\x20on\x20chain.','object':o};}if(a['type']==='AllocationEvent'){const p=typeof a['object']==='string'?a['object']:null;if(!p)return null;const q=typeof a['payment']==='string'?a['payment']:null,r=a['amount']!==null&&a['amount']!==undefined?String(a['amount']):null;return{'kind':'note','title':'Settlement\x20executed\x20—\x20payment\x20split\x20created','detail':'AllocationEvent\x20on\x20'+p+(r?'\x20—\x20amount\x20'+r+'\x20(smallest\x20unit)':'')+(q?'\x20→\x20Payment\x20'+q:'')+'.\x20The\x20order\x27s\x20allocation\x20split\x20funds\x20on-chain;\x20recipients\x20receive\x20CoinWrapper(s)\x20they\x20claim\x20via\x20payment\x20{receive:true}\x20(the\x20keeper\x20surfaces\x20unclaimed\x20funds\x20separately).','object':p};}if(a['type']==='TreasuryEvent'){const s=typeof a['object']==='string'?a['object']:null;if(!s)return null;const t=Number(a['op']),u=t===0x0?'withdraw':t===0x1?'deposit':t===0x2?'receive':null,v=a['amount']!==null&&a['amount']!==undefined?String(a['amount']):null;return{'kind':'note','title':u?'Treasury\x20'+u+'\x20recorded':'Treasury\x20operation\x20recorded','detail':'TreasuryEvent\x20on\x20'+s+(u?'\x20—\x20'+u:'')+(v?'\x20of\x20'+v+'\x20(smallest\x20unit)':'')+(typeof a['payment']==='string'&&a['payment']?'\x20(Payment\x20'+a['payment']+')':'')+'.\x20The\x20treasury\x27s\x20on-chain\x20history\x20keeps\x20the\x20immutable\x20audit\x20trail\x20of\x20this\x20fund\x20movement.','object':s};}if(a['type']==='RewardClaimEvent'){const w=typeof a['object']==='string'?a['object']:null;if(!w)return null;const x=a['amount']!==null&&a['amount']!==undefined?String(a['amount']):null;return{'kind':'note','title':'Reward\x20claimed','detail':'RewardClaimEvent\x20on\x20'+w+(x?'\x20—\x20'+x+'\x20(smallest\x20unit)':'')+(typeof a['recipient']==='string'&&a['recipient']?'\x20to\x20'+a['recipient']:'')+(a['balance_left']!==null&&a['balance_left']!==undefined?'\x20—\x20pool\x20balance\x20left\x20'+String(a['balance_left'])+'\x20(smallest\x20unit)':'')+'.\x20The\x20claim\x20passed\x20its\x20guard\x20conditions\x20on-chain;\x20the\x20reward\x27s\x20record\x20table\x20keeps\x20the\x20receipt.','object':w};}if(a['type']==='RewardFundEvent'){const y=typeof a['object']==='string'?a['object']:null;if(!y)return null;const z=a['amount']!==null&&a['amount']!==undefined?String(a['amount']):null;return{'kind':'note','title':'Reward\x20pool\x20funded','detail':'RewardFundEvent\x20on\x20'+y+(z?'\x20—\x20+'+z+'\x20(smallest\x20unit)':'')+(a['balance']!==null&&a['balance']!==undefined?'\x20→\x20pool\x20balance\x20'+String(a['balance'])+'\x20(smallest\x20unit)':'')+'.\x20New\x20funding\x20is\x20claimable\x20under\x20the\x20pool\x27s\x20existing\x20reward\x20guards.','object':y};}if(a['type']==='ProgressEvent'){const A=typeof a['progress']==='string'?a['progress']:null;if(!A)return null;const B=typeof a['node']==='string'?a['node']:null,C=a['hold']===!![]||a['hold']==='true';return{'kind':'note','goal_type':'purchase_service','title':B?'Delivery\x20advanced\x20to\x20\x27'+B+'\x27':'Delivery\x20progressed','detail':'ProgressEvent\x20on\x20'+A+(B?'\x20—\x20workflow\x20advanced\x20to\x20node\x20\x27'+B+'\x27':'')+(typeof a['forward']==='string'&&a['forward']?'\x20via\x20forward\x20\x27'+a['forward']+'\x27':'')+(C?'\x20—\x20the\x20progress\x20is\x20HELD\x20(paused)':'')+'.\x20Review\x20the\x20delivery\x20evidence\x20for\x20this\x20node;\x20if\x20the\x20advance\x20looks\x20wrong\x20you\x20can\x20raise\x20a\x20dispute\x20(the\x20node\x27s\x20guard\x20verdict\x20and\x20WIP\x20hashes\x20are\x20on-chain).','object':A};}if(a['type']==='DemandPresentEvent'){const D=typeof a['demand']==='string'?a['demand']:null;if(!D)return null;const E=typeof a['service']==='string'?a['service']:null,F=typeof a['recommend']==='string'&&a['recommend']['length']>0x0?a['recommend']['slice'](0x0,0x8c):null;return{'kind':'note','goal_type':'publish_demand','title':'A\x20candidate\x20presented\x20to\x20your\x20demand\x20—\x20evaluate\x20&\x20select','detail':'DemandPresentEvent\x20on\x20'+D+(E?'\x20—\x20presented\x20service\x20'+E:'\x20(no\x20service\x20attached)')+(F?'\x20—\x20pitch:\x20\x22'+F+'\x22':'')+'.\x20Compare\x20the\x20candidate\x20via\x20the\x20service\x27s\x20trust\x20data\x20(registrar\x20votes,\x20past\x20orders,\x20arbitration\x20bindings)\x20before\x20selecting;\x20your\x20on-chain\x20feedback\x20(acceptance_score)\x20becomes\x20the\x20presenter\x27s\x20permanent\x20reputation.','object':D};}return null;}const EVENT_OBJECT_FIELDS=['order','service','arb','arbitration','object','progress','demand'];export async function bridgeMonitorSuggestions(b,c){const {network:d,events:g,annotations:h,scope:i}=b;try{const j=new Set(h['map'](n=>n['event_id'])),k=new Map();for(const n of h){k['set'](n['event_id'],n['rules']['map'](o=>o['object']));}const l=new Map();for(const o of i['focus']??[]){if(o['goal_id']&&o['object'])l['set'](o['object'],o['goal_id']);}if(l['size']===0x0)return 0x0;const m=[];for(const p of g){const q=monitorEventId(p?.['id']);if(!q||!j['has'](q))continue;const r=classifyProgression(p);if(!r)continue;const s=[...k['get'](q)??[],...EVENT_OBJECT_FIELDS['map'](y=>p[y])['filter'](y=>typeof y==='string'&&y['length']>0x0)];let t;for(const y of s){const z=l['get'](y);if(z){t=z;break;}}if(!t)continue;const u=await c['getGoal'](d,t),v=u?.['process']?.['dir'];if(!u||!v)continue;const w=STAGE_GATE[r['kind']];if(w&&u['stage']!==w)continue;if(r['goal_type']&&u['goal_type']!==r['goal_type'])continue;const x=c['listSuggestions'](v)['some'](A=>A['origin']?.['source']==='monitor'&&A['origin']?.['event_id']===q);if(x)continue;c['addSuggestion'](v,{'object':r['object'],'kind':r['kind'],...r['stage']?{'stage':r['stage']}:{},'title':r['title'],'detail':r['detail'],'origin':{'source':'monitor','network':d,'event_id':q,'event_type':String(p['type']??'unknown')}}),m['push'](q);}return m['length']>0x0&&c['logger']('suggestion\x20bridge:\x20opened\x20'+m['length']+'\x20suggestion(s)\x20on\x20'+d+'\x20from\x20monitor\x20progressions'),m['length'];}catch(A){return c['logger']('suggestion\x20bridge:\x20skipped\x20('+String(A?.['message']??A)+')'),0x0;}}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ import{describe,expect,it}from'vitest';import{bridgeMonitorSuggestions,classifyProgression}from'./SuggestionBridge.js';const NET='testnet',PROGRESS='0xprogress1',DEMAND='0xdemand1',SERVICE='0xservice1',ARB='0xarb1',ORDER='0xorder1',GOAL_ID='goal-1';function ev(a,b,c='1'){return{'id':{'eventSeq':c,'txDigest':'0xtx'},'type':a,...b};}function annotation(a,b){return{'event_id':a+':0xtx','event_type':'ProgressEvent','rules':[{'kind':'focus','object':b}],'focus_hit':!![],'matched_filters':[],'scope_version':0x1,'annotated_at':0x0};}function scopeWithFocus(a){return{'focus':[{'object':a,'added_at':0x0,'reason':'goal','closure':!![],'goal_id':GOAL_ID}]};}function goalOf(a,b){return{'id':GOAL_ID,'stage':a,'goal_type':b,'process':{'dir':'proc-dir'}};}function depsOf(a){const b=[],c={'getGoal':async()=>a,'addSuggestion':(d,e)=>{return b['push'](e),{'id':'sug-'+b['length'],'status':'pending',...e};},'listSuggestions':()=>b['map']((d,e)=>({'id':'sug-'+(e+0x1),'status':'pending',...d})),'logger':()=>{}};return{'deps':c,'added':b};}describe('classifyProgression',()=>{it('ProgressEvent\x20→\x20note\x20for\x20purchase_service\x20goals,\x20carries\x20node/forward/hold',()=>{const a=classifyProgression(ev('ProgressEvent',{'progress':PROGRESS,'node':'deliver','forward':'ship','hold':![]}));expect(a?.['kind'])['toBe']('note'),expect(a?.['goal_type'])['toBe']('purchase_service'),expect(a?.['object'])['toBe'](PROGRESS),expect(a?.['title'])['toContain']('deliver');}),it('ProgressEvent\x20without\x20progress\x20address\x20→\x20null',()=>{expect(classifyProgression(ev('ProgressEvent',{'node':'x'})))['toBeNull']();}),it('DemandPresentEvent\x20→\x20note\x20for\x20publish_demand\x20goals\x20with\x20pitch\x20preview',()=>{const a=classifyProgression(ev('DemandPresentEvent',{'demand':DEMAND,'service':SERVICE,'recommend':'I\x20can\x20do\x20it'}));expect(a?.['kind'])['toBe']('note'),expect(a?.['goal_type'])['toBe']('publish_demand'),expect(a?.['object'])['toBe'](DEMAND),expect(a?.['detail'])['toContain']('I\x20can\x20do\x20it');}),it('ArbEvent\x20Voting\x20(status\x202)\x20→\x20voting-started\x20note\x20pointing\x20at\x20the\x20deadline',()=>{const a=classifyProgression(ev('ArbEvent',{'arb':ARB,'order':ORDER,'status':0x2}));expect(a?.['kind'])['toBe']('note'),expect(a?.['object'])['toBe'](ORDER),expect(a?.['title'])['toContain']('voting\x20started'),expect(a?.['detail'])['toContain']('voting_deadline');}),it('ArbEvent\x20Arbitrated\x20(status\x203)\x20→\x20objection-window\x20note',()=>{const a=classifyProgression(ev('ArbEvent',{'arb':ARB,'order':ORDER,'status':0x3}));expect(a?.['kind'])['toBe']('note'),expect(a?.['title'])['toContain']('objection\x20window');}),it('ArbEvent\x20Finished\x20(status\x205)\x20→\x20complete_goal\x20(pre-existing\x20behavior\x20preserved)',()=>{const a=classifyProgression(ev('ArbEvent',{'arb':ARB,'order':ORDER,'status':0x5}));expect(a?.['kind'])['toBe']('complete_goal'),expect(a?.['object'])['toBe'](ORDER);}),it('ArbEvent\x20other\x20statuses\x20→\x20null',()=>{expect(classifyProgression(ev('ArbEvent',{'arb':ARB,'order':ORDER,'status':0x0})))['toBeNull'](),expect(classifyProgression(ev('ArbEvent',{'arb':ARB,'order':ORDER,'status':0x4})))['toBeNull'](),expect(classifyProgression(ev('ArbEvent',{'arb':ARB,'order':ORDER,'status':0x6})))['toBeNull']();}),it('FeedbackEvent\x20→\x20reputation\x20note\x20with\x20feedback\x20preview',()=>{const a=classifyProgression(ev('FeedbackEvent',{'object':ARB,'feedback':'fair\x20and\x20fast'}));expect(a?.['kind'])['toBe']('note'),expect(a?.['object'])['toBe'](ARB),expect(a?.['detail'])['toContain']('fair\x20and\x20fast'),expect(a?.['detail'])['toContain']('reputation');}),it('DemandFeedbackEvent\x20→\x20presenter-reputation\x20note\x20carrying\x20acceptance_score',()=>{const a=classifyProgression(ev('DemandFeedbackEvent',{'demand':DEMAND,'service':SERVICE,'acceptance_score':0x55,'feedback':'solid\x20work'}));expect(a?.['kind'])['toBe']('note'),expect(a?.['object'])['toBe'](DEMAND),expect(a?.['detail'])['toContain']('85'),expect(a?.['detail'])['toContain']('solid\x20work');}),it('AllocationEvent\x20→\x20settlement\x20note\x20carrying\x20amount\x20+\x20payment',()=>{const a=classifyProgression(ev('AllocationEvent',{'object':'0xalloc1','payment':'0xpay1','amount':'5000'}));expect(a?.['kind'])['toBe']('note'),expect(a?.['object'])['toBe']('0xalloc1'),expect(a?.['title'])['toContain']('Settlement\x20executed'),expect(a?.['detail'])['toContain']('5000'),expect(a?.['detail'])['toContain']('0xpay1'),expect(a?.['detail'])['toContain']('keeper');}),it('TreasuryEvent\x20→\x20op-labelled\x20note\x20(withdraw/deposit/receive)',()=>{const a=classifyProgression(ev('TreasuryEvent',{'object':'0xtre1','op':0x0,'amount':'7'}));expect(a?.['title'])['toContain']('withdraw'),expect(a?.['object'])['toBe']('0xtre1');const b=classifyProgression(ev('TreasuryEvent',{'object':'0xtre1','op':0x1}));expect(b?.['title'])['toContain']('deposit');const c=classifyProgression(ev('TreasuryEvent',{'object':'0xtre1','op':0x2}));expect(c?.['title'])['toContain']('receive');const e=classifyProgression(ev('TreasuryEvent',{'object':'0xtre1','op':0x9}));expect(e?.['title'])['toBe']('Treasury\x20operation\x20recorded');}),it('RewardClaimEvent\x20/\x20RewardFundEvent\x20→\x20reward\x20notes',()=>{const a=classifyProgression(ev('RewardClaimEvent',{'object':'0xrew1','recipient':'0xuser1','amount':'100','balance_left':'900'}));expect(a?.['kind'])['toBe']('note'),expect(a?.['title'])['toBe']('Reward\x20claimed'),expect(a?.['detail'])['toContain']('0xuser1'),expect(a?.['detail'])['toContain']('900');const b=classifyProgression(ev('RewardFundEvent',{'object':'0xrew1','amount':'1000','balance':'1000'}));expect(b?.['kind'])['toBe']('note'),expect(b?.['title'])['toBe']('Reward\x20pool\x20funded');}),it('NewPaymentEvent\x20is\x20deliberately\x20NOT\x20bridged\x20(keeper\x20owns\x20the\x20claim\x20reminder)',()=>{expect(classifyProgression(ev('NewPaymentEvent',{'object':'0xpay1','amount':'100'})))['toBeNull']();});}),describe('bridgeMonitorSuggestions',()=>{it('bridges\x20an\x20annotated\x20ProgressEvent\x20into\x20a\x20purchase_service\x20goal\x27s\x20suggestions',async()=>{const {deps:a,added:b}=depsOf(goalOf('monitoring','purchase_service')),c=await bridgeMonitorSuggestions({'network':NET,'events':[ev('ProgressEvent',{'progress':PROGRESS,'node':'deliver'})],'annotations':[annotation('1',PROGRESS)],'scope':scopeWithFocus(PROGRESS)},a);expect(c)['toBe'](0x1),expect(b[0x0]?.['kind'])['toBe']('note'),expect(b[0x0]?.['origin']?.['event_type'])['toBe']('ProgressEvent');}),it('drops\x20ProgressEvent\x20when\x20the\x20owning\x20goal\x20is\x20not\x20purchase_service',async()=>{const {deps:a,added:b}=depsOf(goalOf('monitoring','fulfill_order')),c=await bridgeMonitorSuggestions({'network':NET,'events':[ev('ProgressEvent',{'progress':PROGRESS})],'annotations':[annotation('1',PROGRESS)],'scope':scopeWithFocus(PROGRESS)},a);expect(c)['toBe'](0x0),expect(b)['toHaveLength'](0x0);}),it('bridges\x20DemandPresentEvent\x20via\x20the\x20demand\x20focus\x20field',async()=>{const {deps:a,added:b}=depsOf(goalOf('acting','publish_demand')),c=await bridgeMonitorSuggestions({'network':NET,'events':[ev('DemandPresentEvent',{'demand':DEMAND,'service':SERVICE})],'annotations':[annotation('1',DEMAND)],'scope':scopeWithFocus(DEMAND)},a);expect(c)['toBe'](0x1),expect(b[0x0]?.['object'])['toBe'](DEMAND);}),it('idempotency:\x20the\x20same\x20event\x20never\x20bridges\x20twice',async()=>{const {deps:a}=depsOf(goalOf('monitoring','purchase_service')),b={'network':NET,'events':[ev('ProgressEvent',{'progress':PROGRESS})],'annotations':[annotation('1',PROGRESS)],'scope':scopeWithFocus(PROGRESS)};expect(await bridgeMonitorSuggestions(b,a))['toBe'](0x1),expect(await bridgeMonitorSuggestions(b,a))['toBe'](0x0);}),it('relevance\x20gate:\x20un-annotated\x20events\x20never\x20bridge',async()=>{const {deps:a}=depsOf(goalOf('monitoring','purchase_service')),b=await bridgeMonitorSuggestions({'network':NET,'events':[ev('ProgressEvent',{'progress':PROGRESS})],'annotations':[],'scope':scopeWithFocus(PROGRESS)},a);expect(b)['toBe'](0x0);});});
@@ -1 +1 @@
1
- export const MONITOR_CAPTURE_TYPES=['NewOrderEvent','ArbEvent','VoteEvent','FeedbackEvent','DemandPresentEvent','DemandFeedbackEvent','DemandChangedEvent','ProgressEvent','AllocationEvent','TreasuryEvent','RewardClaimEvent','RewardFundEvent','ServiceEvent','NewEntityEvent'];export const PAYMENT_EVENT_TYPE='NewPaymentEvent';export const MONITOR_KNOWN_TYPES=[...MONITOR_CAPTURE_TYPES,PAYMENT_EVENT_TYPE];export const EVENT_MODULE_OF={'NewOrderEvent':'order','ArbEvent':'arb','VoteEvent':'arb','FeedbackEvent':'arb','DemandPresentEvent':'demand','DemandFeedbackEvent':'demand','DemandChangedEvent':'demand','ProgressEvent':'progress','AllocationEvent':'treasury','TreasuryEvent':'treasury','RewardClaimEvent':'reward','RewardFundEvent':'reward','ServiceEvent':'service','NewEntityEvent':'entity','NewPaymentEvent':'payment'};export function monitorEventShortType(a){if(!a||typeof a!=='string')return null;if(a['includes']('::order::NewOrderEvent'))return'NewOrderEvent';if(a['includes']('::demand::PresentEvent'))return'DemandPresentEvent';if(a['includes']('::demand::DemandChangedEvent'))return'DemandChangedEvent';if(a['includes']('::demand::DemandEvent'))return'DemandFeedbackEvent';if(a['includes']('::progress::ProgressEvent'))return'ProgressEvent';if(a['includes']('::arb::VoteEvent'))return'VoteEvent';if(a['includes']('::arb::FeedbackEvent'))return'FeedbackEvent';if(a['includes']('::arb::ArbEvent'))return'ArbEvent';if(a['includes']('::registrar::NewEntityEvent'))return'NewEntityEvent';if(a['includes']('::service::ServiceEvent'))return'ServiceEvent';if(a['includes']('::allocation::AllocationEvent'))return'AllocationEvent';if(a['includes']('::treasury::TreasuryEvent'))return'TreasuryEvent';if(a['includes']('::reward::RewardClaimEvent'))return'RewardClaimEvent';if(a['includes']('::reward::RewardFundEvent'))return'RewardFundEvent';if(a['includes']('::payment::NewPaymentEvent'))return'NewPaymentEvent';return null;}export function normalizeMonitorEvent(a){if(!a||typeof a!=='object')return a;if(MONITOR_KNOWN_TYPES['includes'](a['type'])&&!a['parsedJson_raw'])return a;const b=MONITOR_KNOWN_TYPES['includes'](a['type'])?a['type']:monitorEventShortType(a['type_raw']??a['type']);if(!b)return a;const c=a['parsedJson_raw']??{},d=f=>f&&typeof f==='object'&&!Array['isArray'](f)&&'some'in f?f['some']:f,e={...a,'type':b};switch(b){case'NewOrderEvent':return{...e,'order':d(c['object']),'service':d(c['service'])??null,'progress':d(c['progress'])??null,'discount':d(c['discount'])??null,'allocation':d(c['allocation'])??null,'amount':d(c['amount'])??null};case'DemandPresentEvent':return{...e,'demand':d(c['object']),'service':d(c['service'])??null,'recommend':d(c['recommend'])??null};case'DemandFeedbackEvent':return{...e,'demand':d(c['object']),'service':d(c['service'])??null,'feedback':d(c['feedback'])??null,'acceptance_score':d(c['acceptance_score'])??null};case'ProgressEvent':return{...e,'progress':d(c['object']),'machine':d(c['machine'])??null,'task':d(c['task'])??null,'node':d(c['node'])??null,'forward':d(c['forward'])??null,'hold':d(c['hold'])??null};case'ArbEvent':return{...e,'arb':d(c['object']),'arbitration':d(c['arbitration'])??null,'order':d(c['order'])??null,'status':d(c['status'])??null};case'NewEntityEvent':return{...e,'resource':d(c['resource'])??null,'address':a['sender'],'referrer':d(c['referrer'])??null};case'ServiceEvent':return{...e,'object':d(c['object']),'location':d(c['location'])??null,'description':d(c['description'])??null};case'DemandChangedEvent':return{...e,'object':d(c['object']),'location':d(c['location'])??null,'description':d(c['description'])??null,'rewards':d(c['rewards'])??[]};case'VoteEvent':return{...e,'object':d(c['object']),'voter':d(c['voter'])??null,'agrees':d(c['agrees'])??[],'weight':d(c['weight'])??null};case'FeedbackEvent':return{...e,'object':d(c['object']),'feedback':d(c['feedback'])??null};case'AllocationEvent':return{...e,'object':d(c['object']),'payment':d(c['payment'])??null,'guard':d(c['guard'])??null,'amount':d(c['amount'])??null};case'TreasuryEvent':return{...e,'object':d(c['object']),'op':d(c['op'])??null,'payment':d(c['payment'])??null,'amount':d(c['amount'])??null,'external_guard':d(c['external_guard'])??null,'store_from_id':d(c['store_from_id'])??null};case'RewardClaimEvent':return{...e,'object':d(c['object']),'guard':d(c['guard'])??null,'recipient':d(c['recipient'])??null,'amount':d(c['amount'])??null,'total':d(c['total'])??null,'balance_left':d(c['balance_left'])??null,'store_from_id':d(c['store_from_id'])??null};case'RewardFundEvent':return{...e,'object':d(c['object']),'amount':d(c['amount'])??null,'balance':d(c['balance'])??null,'from_payment':d(c['from_payment'])??null};case'NewPaymentEvent':return{...e,'object':d(c['object']),'info':c['info']?{...c['info'],'for_object':d(c['info']?.['for_object'])??null,'for_guard':d(c['info']?.['for_guard'])??null}:null,'record':Array['isArray'](c['record'])?c['record']:[],'amount':d(c['amount'])??null,'from_object':d(c['from_object'])??null};default:return e;}}export const EVENT_ADDRESS_FIELDS=['object','order','service','demand','progress','arb','arbitration','allocation','discount','machine','task','address','resource','payment','from_payment','from_object'];
1
+ export const MONITOR_CAPTURE_TYPES=['NewOrderEvent','ArbEvent','VoteEvent','FeedbackEvent','DemandPresentEvent','DemandFeedbackEvent','DemandChangedEvent','ProgressEvent','AllocationEvent','TreasuryEvent','RewardClaimEvent','RewardFundEvent','ServiceEvent','NewEntityEvent'];export const PAYMENT_EVENT_TYPE='NewPaymentEvent';export const MONITOR_KNOWN_TYPES=[...MONITOR_CAPTURE_TYPES,PAYMENT_EVENT_TYPE];export const EVENT_MODULE_OF={'NewOrderEvent':'order','ArbEvent':'arb','VoteEvent':'arb','FeedbackEvent':'arb','DemandPresentEvent':'demand','DemandFeedbackEvent':'demand','DemandChangedEvent':'demand','ProgressEvent':'progress','AllocationEvent':'treasury','TreasuryEvent':'treasury','RewardClaimEvent':'reward','RewardFundEvent':'reward','ServiceEvent':'service','NewEntityEvent':'entity','NewPaymentEvent':'payment'};export function monitorEventShortType(a){if(!a||typeof a!=='string')return null;if(a['includes']('::order::NewOrderEvent'))return'NewOrderEvent';if(a['includes']('::demand::PresentEvent'))return'DemandPresentEvent';if(a['includes']('::demand::DemandChangedEvent'))return'DemandChangedEvent';if(a['includes']('::demand::DemandEvent'))return'DemandFeedbackEvent';if(a['includes']('::progress::ProgressEvent'))return'ProgressEvent';if(a['includes']('::arb::VoteEvent'))return'VoteEvent';if(a['includes']('::arb::FeedbackEvent'))return'FeedbackEvent';if(a['includes']('::arb::ArbEvent'))return'ArbEvent';if(a['includes']('::registrar::NewEntityEvent'))return'NewEntityEvent';if(a['includes']('::service::ServiceEvent'))return'ServiceEvent';if(a['includes']('::arbitration::ArbitrationEvent'))return'ArbitrationEvent';if(a['includes']('::allocation::AllocationEvent'))return'AllocationEvent';if(a['includes']('::treasury::TreasuryEvent'))return'TreasuryEvent';if(a['includes']('::reward::RewardClaimEvent'))return'RewardClaimEvent';if(a['includes']('::reward::RewardFundEvent'))return'RewardFundEvent';if(a['includes']('::payment::NewPaymentEvent'))return'NewPaymentEvent';return null;}export function normalizeMonitorEvent(a){if(!a||typeof a!=='object')return a;if(MONITOR_KNOWN_TYPES['includes'](a['type'])&&!a['parsedJson_raw'])return a;const b=MONITOR_KNOWN_TYPES['includes'](a['type'])?a['type']:monitorEventShortType(a['type_raw']??a['type']);if(!b)return a;const c=a['parsedJson_raw']??{},d=f=>f&&typeof f==='object'&&!Array['isArray'](f)&&'some'in f?f['some']:f,e={...a,'type':b};switch(b){case'NewOrderEvent':return{...e,'order':d(c['object']),'service':d(c['service'])??null,'progress':d(c['progress'])??null,'discount':d(c['discount'])??null,'allocation':d(c['allocation'])??null,'amount':d(c['amount'])??null};case'DemandPresentEvent':return{...e,'demand':d(c['object']),'service':d(c['service'])??null,'recommend':d(c['recommend'])??null};case'DemandFeedbackEvent':return{...e,'demand':d(c['object']),'service':d(c['service'])??null,'feedback':d(c['feedback'])??null,'acceptance_score':d(c['acceptance_score'])??null};case'ProgressEvent':return{...e,'progress':d(c['object']),'machine':d(c['machine'])??null,'task':d(c['task'])??null,'node':d(c['node'])??null,'forward':d(c['forward'])??null,'hold':d(c['hold'])??null};case'ArbEvent':return{...e,'arb':d(c['object']),'arbitration':d(c['arbitration'])??null,'order':d(c['order'])??null,'status':d(c['status'])??null};case'NewEntityEvent':return{...e,'resource':d(c['resource'])??null,'address':a['sender'],'referrer':d(c['referrer'])??null};case'ServiceEvent':return{...e,'object':d(c['object']),'location':d(c['location'])??null,'description':d(c['description'])??null};case'ArbitrationEvent':return{...e,'object':d(c['object']),'location':d(c['location'])??null,'description':d(c['description'])??null,'fee':d(c['fee'])??null,'voting_guard_count':d(c['voting_guard_count'])??null};case'DemandChangedEvent':return{...e,'object':d(c['object']),'location':d(c['location'])??null,'description':d(c['description'])??null,'rewards':d(c['rewards'])??[]};case'VoteEvent':return{...e,'object':d(c['object']),'voter':d(c['voter'])??null,'agrees':d(c['agrees'])??[],'weight':d(c['weight'])??null};case'FeedbackEvent':return{...e,'object':d(c['object']),'feedback':d(c['feedback'])??null};case'AllocationEvent':return{...e,'object':d(c['object']),'payment':d(c['payment'])??null,'guard':d(c['guard'])??null,'amount':d(c['amount'])??null};case'TreasuryEvent':return{...e,'object':d(c['object']),'op':d(c['op'])??null,'payment':d(c['payment'])??null,'amount':d(c['amount'])??null,'external_guard':d(c['external_guard'])??null,'store_from_id':d(c['store_from_id'])??null};case'RewardClaimEvent':return{...e,'object':d(c['object']),'guard':d(c['guard'])??null,'recipient':d(c['recipient'])??null,'amount':d(c['amount'])??null,'total':d(c['total'])??null,'balance_left':d(c['balance_left'])??null,'store_from_id':d(c['store_from_id'])??null};case'RewardFundEvent':return{...e,'object':d(c['object']),'amount':d(c['amount'])??null,'balance':d(c['balance'])??null,'from_payment':d(c['from_payment'])??null};case'NewPaymentEvent':return{...e,'object':d(c['object']),'info':c['info']?{...c['info'],'for_object':d(c['info']?.['for_object'])??null,'for_guard':d(c['info']?.['for_guard'])??null}:null,'record':Array['isArray'](c['record'])?c['record']:[],'amount':d(c['amount'])??null,'from_object':d(c['from_object'])??null};default:return e;}}export const EVENT_ADDRESS_FIELDS=['object','order','service','demand','progress','arb','arbitration','allocation','discount','machine','task','address','resource','payment','from_payment','from_object'];
@@ -86,4 +86,3 @@ export declare const LOOP_MIN: {
86
86
  export declare const DEFAULT_EVENT_SWITCHES: Record<string, boolean>;
87
87
  export declare function defaultSubscriptionConfig(): SubscriptionConfig;
88
88
  export declare function normalizeAddr(addr?: string | null): string;
89
- export declare function shortId(addr?: string | null): string;
@@ -1 +1 @@
1
- export const MONITOR_EVENT_MODULES=['order','arb','demand','progress','treasury','reward','service','entity','payment'];export const LOOP_DEFAULTS={'poll_interval_ms':0x3a98,'scope_refresh_ms':0x493e0,'backfill_days':0x7};export const LOOP_MIN={'poll_interval_ms':0x1388,'scope_refresh_ms':0xea60,'backfill_days':0x0};export const DEFAULT_EVENT_SWITCHES={'NewOrderEvent':!![],'ProgressEvent':!![],'ArbEvent':!![],'VoteEvent':!![],'TreasuryEvent':!![],'RewardFundEvent':!![],'RewardClaimEvent':!![],'AllocationEvent':!![],'FeedbackEvent':![],'NewPaymentEvent':![],'DemandChangedEvent':![],'DemandPresentEvent':![],'DemandFeedbackEvent':![],'ServiceEvent':![],'NewEntityEvent':![]};export function defaultSubscriptionConfig(){return{'version':0x2,'enabled':!![],'scope':{'accounts':'local-all','rules':{'managed_objects':!![],'merchant_orders':!![],'my_orders':!![],'order_children':!![],'favor_objects':!![]},'focus_objects':[]},'events':{...DEFAULT_EVENT_SWITCHES},'filters':[],'loop':{...LOOP_DEFAULTS}};}export function normalizeAddr(a){if(!a)return'';const b=a['startsWith']('0x')?a['slice'](0x2):a;return b['toLowerCase']();}export function shortId(a){const b=normalizeAddr(a);if(!b)return'';if(b['length']<=0x7)return b['toUpperCase']();return b['slice'](0x0,0x4)['toUpperCase']()+'-'+b['slice'](-0x3)['toUpperCase']();}
1
+ export const MONITOR_EVENT_MODULES=['order','arb','demand','progress','treasury','reward','service','entity','payment'];export const LOOP_DEFAULTS={'poll_interval_ms':0x3a98,'scope_refresh_ms':0x493e0,'backfill_days':0x7};export const LOOP_MIN={'poll_interval_ms':0x1388,'scope_refresh_ms':0xea60,'backfill_days':0x0};export const DEFAULT_EVENT_SWITCHES={'NewOrderEvent':!![],'ProgressEvent':!![],'ArbEvent':!![],'VoteEvent':!![],'TreasuryEvent':!![],'RewardFundEvent':!![],'RewardClaimEvent':!![],'AllocationEvent':!![],'FeedbackEvent':![],'NewPaymentEvent':![],'DemandChangedEvent':![],'DemandPresentEvent':![],'DemandFeedbackEvent':![],'ServiceEvent':![],'NewEntityEvent':![]};export function defaultSubscriptionConfig(){return{'version':0x2,'enabled':!![],'scope':{'accounts':'local-all','rules':{'managed_objects':!![],'merchant_orders':!![],'my_orders':!![],'order_children':!![],'favor_objects':!![]},'focus_objects':[]},'events':{...DEFAULT_EVENT_SWITCHES},'filters':[],'loop':{...LOOP_DEFAULTS}};}export function normalizeAddr(a){if(!a)return'';const b=a['startsWith']('0x')?a['slice'](0x2):a;return b['toLowerCase']();}
@@ -18,6 +18,18 @@ export interface LiabilityResolution {
18
18
  }
19
19
  export declare function assessReactionKpi(node: string, assigned_at: number, advanced_at: number | undefined, budget_ms?: number): ReactionKpi;
20
20
  export declare function resolveLiability(liability: EmployeeLiability, loss_amount: number, hybrid_threshold?: number): LiabilityResolution;
21
+ export interface NodeTiming {
22
+ node: string;
23
+ assigned_at?: number;
24
+ advanced_at?: number;
25
+ source: "monitor_events" | "none";
26
+ gap?: string;
27
+ }
28
+ export declare function deriveNodeTiming(timeline: Array<{
29
+ node?: string;
30
+ time: number;
31
+ hold?: boolean | null;
32
+ }>, node: string): NodeTiming;
21
33
  export interface EmployeeProfileValidation {
22
34
  valid: boolean;
23
35
  issues: string[];
@@ -1 +1 @@
1
- const DEFAULT_RESPONSE_BUDGET_MS=0x30*0x3c*0x3c*0x3e8;export function assessReactionKpi(a,b,c,d=DEFAULT_RESPONSE_BUDGET_MS){if(c===undefined)return{'node':a,'reaction_ms':-0x1,'within_budget':![],'status':'warn'};const e=c-b,f=e<=d;return{'node':a,'reaction_ms':e,'within_budget':f,'status':f?'pass':'fail'};}export function resolveLiability(a,b,c=0x0){let d;switch(a){case'merchant_bears':d='merchant';break;case'self_bears':d='employee';break;case'hybrid':default:d=b>c?'employee':'merchant';break;}return{'bears':d,'must_compensate_before_resume':b>0x0,'note':d==='merchant'?'Merchant\x20bears\x20the\x20'+b+'\x20loss;\x20employee\x20error\x20is\x20attributed\x20to\x20the\x20merchant\x27s\x20problem\x20list\x20in\x20arbitration.':'Employee\x20bears\x20the\x20'+b+'\x20loss\x20(serious\x20negligence);\x20the\x20order\x20user\x20is\x20compensated\x20first,\x20then\x20the\x20workflow\x20resumes.'};}export function validateEmployeeProfile(a){const b=[];if(!a['department'])b['push']('department\x20is\x20required');if(!a['liability'])b['push']('liability\x20is\x20required');return a['response_time_budget_ms']!==undefined&&a['response_time_budget_ms']<=0x0&&b['push']('response_time_budget_ms\x20must\x20be\x20a\x20positive\x20number'),{'valid':b['length']===0x0,'issues':b};}
1
+ const DEFAULT_RESPONSE_BUDGET_MS=0x30*0x3c*0x3c*0x3e8;export function assessReactionKpi(a,b,c,d=DEFAULT_RESPONSE_BUDGET_MS){if(c===undefined)return{'node':a,'reaction_ms':-0x1,'within_budget':![],'status':'warn'};const e=c-b,f=e<=d;return{'node':a,'reaction_ms':e,'within_budget':f,'status':f?'pass':'fail'};}export function resolveLiability(a,b,c=0x0){let d;switch(a){case'merchant_bears':d='merchant';break;case'self_bears':d='employee';break;case'hybrid':default:d=b>c?'employee':'merchant';break;}return{'bears':d,'must_compensate_before_resume':b>0x0,'note':d==='merchant'?'Merchant\x20bears\x20the\x20'+b+'\x20loss;\x20employee\x20error\x20is\x20attributed\x20to\x20the\x20merchant\x27s\x20problem\x20list\x20in\x20arbitration.':'Employee\x20bears\x20the\x20'+b+'\x20loss\x20(serious\x20negligence);\x20the\x20order\x20user\x20is\x20compensated\x20first,\x20then\x20the\x20workflow\x20resumes.'};}export function deriveNodeTiming(a,b){const c=a['filter'](g=>g['hold']===undefined||g['hold']===null),d=c['findIndex'](g=>g['node']===b);if(d<0x0)return{'node':b,'source':'none','gap':'no\x20ProgressEvent\x20entering\x20node\x20\x27'+b+'\x27\x20in\x20the\x20monitored\x20timeline\x20—\x20the\x20node\x20may\x20not\x20be\x20reached\x20yet,\x20or\x20its\x20entry\x20predates\x20the\x20monitored\x20window;\x20supply\x20assigned_at/advanced_at\x20manually'};const e=c[d]['time'],f=d+0x1<c['length']?c[d+0x1]:undefined;return{'node':b,'assigned_at':e,'advanced_at':f?.['time'],'source':'monitor_events'};}export function validateEmployeeProfile(a){const b=[];if(!a['department'])b['push']('department\x20is\x20required');if(!a['liability'])b['push']('liability\x20is\x20required');return a['response_time_budget_ms']!==undefined&&a['response_time_budget_ms']<=0x0&&b['push']('response_time_budget_ms\x20must\x20be\x20a\x20positive\x20number'),{'valid':b['length']===0x0,'issues':b};}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ import{describe,expect,it}from'vitest';import{deriveNodeTiming}from'./employee-kpi.js';describe('deriveNodeTiming',()=>{it('middle\x20node:\x20assigned_at\x20=\x20entry,\x20advanced_at\x20=\x20exit\x20(next\x20entry)',()=>{const a=deriveNodeTiming([{'node':'received','time':0x3e8},{'node':'preparing','time':0x7d0},{'node':'shipped','time':0x2328}],'preparing');expect(a)['toEqual']({'node':'preparing','assigned_at':0x7d0,'advanced_at':0x2328,'source':'monitor_events'});}),it('first\x20node:\x20assigned_at\x20=\x20its\x20own\x20entry\x20(not\x20a\x20pre-monitor\x20gap)',()=>{const a=deriveNodeTiming([{'node':'received','time':0x3e8},{'node':'preparing','time':0x7d0}],'received');expect(a['assigned_at'])['toBe'](0x3e8),expect(a['advanced_at'])['toBe'](0x7d0),expect(a['source'])['toBe']('monitor_events'),expect(a['gap'])['toBeUndefined']();}),it('last\x20observed\x20node\x20is\x20still\x20current:\x20advanced_at\x20undefined\x20(still\x20waiting),\x20no\x20gap',()=>{const a=deriveNodeTiming([{'node':'received','time':0x3e8},{'node':'preparing','time':0x7d0}],'preparing');expect(a['assigned_at'])['toBe'](0x7d0),expect(a['advanced_at'])['toBeUndefined'](),expect(a['source'])['toBe']('monitor_events'),expect(a['gap'])['toBeUndefined']();}),it('node\x20not\x20found:\x20source\x20none\x20+\x20actionable\x20gap',()=>{const a=deriveNodeTiming([{'node':'received','time':0x3e8}],'preparing');expect(a['source'])['toBe']('none'),expect(a['assigned_at'])['toBeUndefined'](),expect(a['advanced_at'])['toBeUndefined'](),expect(a['gap'])['toMatch'](/no ProgressEvent entering node 'preparing'/),expect(a['gap'])['toMatch'](/manually/);}),it('empty\x20timeline:\x20source\x20none',()=>{const a=deriveNodeTiming([],'received');expect(a['source'])['toBe']('none');}),it('hold\x20signals\x20are\x20not\x20entries:\x20a\x20hold\x20TOWARD\x20the\x20target\x20is\x20not\x20its\x20entry',()=>{const a=deriveNodeTiming([{'node':'received','time':0x3e8},{'node':'preparing','time':0x5dc,'hold':!![]},{'node':'preparing','time':0x7d0},{'node':'shipped','time':0x2328}],'preparing');expect(a['assigned_at'])['toBe'](0x7d0),expect(a['advanced_at'])['toBe'](0x2328);}),it('hold\x20signals\x20are\x20not\x20exits:\x20a\x20hold\x20after\x20entry\x20leaves\x20the\x20node\x20still\x20current',()=>{const a=deriveNodeTiming([{'node':'received','time':0x3e8},{'node':'preparing','time':0x7d0},{'node':'shipped','time':0x9c4,'hold':![]}],'preparing');expect(a['assigned_at'])['toBe'](0x7d0),expect(a['advanced_at'])['toBeUndefined']();}),it('repeated\x20passages:\x20measures\x20the\x20FIRST\x20passage\x20through\x20the\x20node',()=>{const a=deriveNodeTiming([{'node':'review','time':0x3e8},{'node':'rework','time':0x7d0},{'node':'review','time':0xbb8},{'node':'done','time':0xfa0}],'review');expect(a['assigned_at'])['toBe'](0x3e8),expect(a['advanced_at'])['toBe'](0x7d0);}),it('self-loop:\x20an\x20advance\x20into\x20the\x20same\x20node\x20counts\x20as\x20exit\x20of\x20the\x20first\x20passage',()=>{const a=deriveNodeTiming([{'node':'poll','time':0x3e8},{'node':'poll','time':0x7d0}],'poll');expect(a['assigned_at'])['toBe'](0x3e8),expect(a['advanced_at'])['toBe'](0x7d0);});});