@wenathlan/devthink 2.0.13 → 2.0.15

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 (444) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/accounts.ts +2087 -0
  3. package/agent.ts +2331 -0
  4. package/antigravity.ts +2139 -0
  5. package/apifreeze.ts +4146 -0
  6. package/auth.ts +642 -0
  7. package/background.ts +16837 -0
  8. package/bridge.ts +2080 -0
  9. package/build.ts +54 -0
  10. package/bun.ts +26 -0
  11. package/capture.ts +1614 -0
  12. package/checksecrets.ts +72 -0
  13. package/cjs.ts +9 -0
  14. package/cli.ts +3500 -0
  15. package/commands.ts +1101 -0
  16. package/companion.ts +450 -0
  17. package/compatibility.ts +37 -0
  18. package/config.ts +3137 -0
  19. package/constants.ts +943 -0
  20. package/core.ts +1473 -0
  21. package/crossbrowser.ts +1359 -0
  22. package/dashdone.ts +605 -0
  23. package/data.ts +943 -0
  24. package/database.ts +133 -0
  25. package/debug.ts +850 -0
  26. package/deno.ts +27 -0
  27. package/devthink.ts +707 -0
  28. package/dist/accounts.d.ts +409 -0
  29. package/dist/agent.d.ts +837 -0
  30. package/dist/antigravity.d.ts +380 -0
  31. package/dist/apifreeze.d.ts +113 -0
  32. package/dist/auth.d.ts +224 -0
  33. package/{bridge.d.ts → dist/bridge.d.ts} +1 -1
  34. package/dist/capture.d.ts +595 -0
  35. package/dist/cjs.d.ts +6 -0
  36. package/{cli.js → dist/cli.js} +2 -2
  37. package/dist/commands.d.ts +310 -0
  38. package/dist/compatibility.d.ts +17 -0
  39. package/dist/config.d.ts +1853 -0
  40. package/dist/constants.d.ts +637 -0
  41. package/dist/core.d.ts +361 -0
  42. package/dist/data.d.ts +330 -0
  43. package/dist/database.d.ts +24 -0
  44. package/dist/debug.d.ts +270 -0
  45. package/dist/engine.d.ts +74 -0
  46. package/dist/environments.d.ts +244 -0
  47. package/dist/evidence.d.ts +277 -0
  48. package/dist/export.d.ts +311 -0
  49. package/dist/fingerprint.d.ts +594 -0
  50. package/dist/flow.d.ts +300 -0
  51. package/dist/gates.d.ts +103 -0
  52. package/dist/identity.d.ts +51 -0
  53. package/dist/ids.d.ts +7 -0
  54. package/dist/llm.d.ts +652 -0
  55. package/dist/models.d.ts +1807 -0
  56. package/dist/net.d.ts +325 -0
  57. package/dist/neutral.d.ts +41 -0
  58. package/dist/oauth.d.ts +703 -0
  59. package/dist/page.d.ts +1166 -0
  60. package/dist/perf.d.ts +481 -0
  61. package/dist/plan.d.ts +134 -0
  62. package/dist/project.d.ts +395 -0
  63. package/dist/providers.d.ts +37 -0
  64. package/dist/quota.d.ts +453 -0
  65. package/dist/recovery.d.ts +621 -0
  66. package/dist/request.d.ts +1492 -0
  67. package/dist/run.d.ts +779 -0
  68. package/dist/runtime.d.ts +212 -0
  69. package/dist/search.d.ts +375 -0
  70. package/dist/security.d.ts +534 -0
  71. package/dist/serve.d.ts +136 -0
  72. package/dist/session.d.ts +296 -0
  73. package/dist/storage.d.ts +53 -0
  74. package/dist/streaming.d.ts +1119 -0
  75. package/dist/swarm.d.ts +328 -0
  76. package/dist/tools.d.ts +170 -0
  77. package/dist/types.d.ts +8357 -0
  78. package/dist/utils.d.ts +82 -0
  79. package/dist/version.d.ts +7 -0
  80. package/dist/versionregistry.d.ts +406 -0
  81. package/dist/views.d.ts +579 -0
  82. package/dist/workbenchsession.d.ts +69 -0
  83. package/dist/workflow.d.ts +649 -0
  84. package/docs/readme.md +92 -0
  85. package/docs/schemas/antigravity.json +192 -0
  86. package/engine.ts +1524 -0
  87. package/environments.ts +1005 -0
  88. package/evidence.ts +643 -0
  89. package/export.ts +889 -0
  90. package/fingerprint.ts +1458 -0
  91. package/flow.ts +1190 -0
  92. package/gates.ts +307 -0
  93. package/gateway.ts +34 -0
  94. package/hardening.ts +191 -0
  95. package/headless.ts +369 -0
  96. package/http.ts +2110 -0
  97. package/identity.ts +246 -0
  98. package/ids.ts +26 -0
  99. package/index.ts +369 -0
  100. package/llm.ts +2682 -0
  101. package/mcp.ts +1835 -0
  102. package/{memory.js → memory.ts} +3834 -2310
  103. package/models.ts +3805 -0
  104. package/modes.ts +43 -0
  105. package/net.ts +1214 -0
  106. package/neutral.ts +362 -0
  107. package/node.ts +26 -0
  108. package/oauth.ts +2216 -0
  109. package/offscreen.ts +170 -0
  110. package/pack.ts +956 -0
  111. package/package.json +175 -82
  112. package/page.ts +7824 -0
  113. package/pagebridge.ts +1116 -0
  114. package/perf.ts +957 -0
  115. package/plan.ts +672 -0
  116. package/plugin.ts +76 -0
  117. package/{policy.js → policy.ts} +5073 -4679
  118. package/prisma.config.ts +27 -0
  119. package/progress.ts +1308 -0
  120. package/project.ts +1291 -0
  121. package/protocol.ts +4187 -0
  122. package/providers.ts +246 -0
  123. package/quota.ts +1887 -0
  124. package/recovery.ts +2433 -0
  125. package/request.ts +4482 -0
  126. package/run.ts +2135 -0
  127. package/runtime.ts +526 -0
  128. package/search.ts +1760 -0
  129. package/security.ts +1673 -0
  130. package/serve.ts +419 -0
  131. package/server.ts +5538 -0
  132. package/session.ts +1162 -0
  133. package/storage.ts +182 -0
  134. package/streaming.ts +4101 -0
  135. package/swarm.ts +884 -0
  136. package/sync.ts +56 -0
  137. package/tests/agentcert.test.ts +128 -0
  138. package/tests/agentfleet.test.ts +214 -0
  139. package/tests/agentreview.test.ts +241 -0
  140. package/tests/agentstream.test.ts +335 -0
  141. package/tests/agentwork.test.ts +356 -0
  142. package/tests/apifreeze.test.ts +290 -0
  143. package/tests/apimap.test.ts +112 -0
  144. package/tests/approvalgate.test.ts +175 -0
  145. package/tests/artifactmanifest.test.ts +204 -0
  146. package/tests/attentionfeed.test.ts +163 -0
  147. package/tests/backgroundruns.test.ts +100 -0
  148. package/tests/batchscheduling.test.ts +131 -0
  149. package/tests/blackboard.test.ts +238 -0
  150. package/tests/bridge.test.ts +1088 -0
  151. package/tests/browsercoverage.test.ts +134 -0
  152. package/tests/browserpolyfills.test.ts +124 -0
  153. package/tests/build.mjs +1260 -0
  154. package/tests/clientauth.test.ts +223 -0
  155. package/tests/clitools.test.ts +578 -0
  156. package/tests/confirmgates.test.ts +190 -0
  157. package/tests/containerpack.test.ts +143 -0
  158. package/tests/controlflow.test.ts +2120 -0
  159. package/tests/coordination.test.ts +345 -0
  160. package/tests/copyscreen.test.ts +139 -0
  161. package/tests/core.test.ts +417 -0
  162. package/tests/costcert.test.ts +95 -0
  163. package/tests/crossbrowser.test.ts +115 -0
  164. package/tests/cspaudit.test.ts +79 -0
  165. package/tests/dashdone.test.ts +615 -0
  166. package/tests/datagrid.test.ts +137 -0
  167. package/tests/doccheck.test.ts +107 -0
  168. package/tests/dombatch.test.ts +109 -0
  169. package/tests/emulation.test.ts +282 -0
  170. package/tests/environments.test.ts +259 -0
  171. package/tests/evidenceviews.test.ts +88 -0
  172. package/tests/exporttools.test.ts +185 -0
  173. package/tests/firefoxprep.test.ts +134 -0
  174. package/tests/flowlibrary.test.ts +242 -0
  175. package/tests/flowrun.test.ts +303 -0
  176. package/tests/forensics.test.ts +439 -0
  177. package/tests/gateway.test.ts +939 -0
  178. package/tests/headlesslib.test.ts +171 -0
  179. package/tests/httpstream.test.ts +277 -0
  180. package/tests/immutablelog.test.ts +157 -0
  181. package/tests/inboundguard.test.ts +177 -0
  182. package/tests/lazyload.test.ts +72 -0
  183. package/tests/librarymodes.test.ts +623 -0
  184. package/tests/llm.test.ts +696 -0
  185. package/tests/manifest.test.ts +226 -0
  186. package/tests/maskinputs.test.ts +150 -0
  187. package/tests/matrixverify.test.ts +111 -0
  188. package/tests/mavenpack.test.ts +75 -0
  189. package/tests/mcpserver.test.ts +704 -0
  190. package/tests/memory.test.ts +4155 -0
  191. package/tests/memorycare.test.ts +230 -0
  192. package/tests/migrateplan.test.ts +349 -0
  193. package/tests/minimization.test.ts +414 -0
  194. package/tests/modelroute.test.ts +112 -0
  195. package/tests/multiagent.test.ts +440 -0
  196. package/tests/nativebridge.test.ts +807 -0
  197. package/tests/navigation.test.ts +284 -0
  198. package/tests/nugetpack.test.ts +83 -0
  199. package/tests/orchestration.test.ts +449 -0
  200. package/tests/originpolicy.test.ts +405 -0
  201. package/tests/outputcompare.test.ts +97 -0
  202. package/tests/package.test.ts +91 -0
  203. package/tests/pagebridge.test.ts +5909 -0
  204. package/tests/pentest.test.ts +75 -0
  205. package/tests/perfrecords.test.ts +257 -0
  206. package/tests/permdiff.test.ts +85 -0
  207. package/tests/phishguard.test.ts +128 -0
  208. package/tests/pickerviews.test.ts +155 -0
  209. package/tests/pipelines.test.ts +381 -0
  210. package/tests/planlint.test.ts +240 -0
  211. package/tests/planreview.test.ts +383 -0
  212. package/tests/platformtargets.test.ts +56 -0
  213. package/tests/policy.test.ts +8284 -0
  214. package/tests/portability.test.ts +96 -0
  215. package/tests/progress.test.ts +1036 -0
  216. package/tests/promptlibrary.test.ts +116 -0
  217. package/tests/protocol.test.ts +4793 -0
  218. package/tests/publishingpipeline.test.ts +314 -0
  219. package/tests/quickactions.test.ts +164 -0
  220. package/tests/readiness.test.ts +78 -0
  221. package/tests/recipes.test.ts +163 -0
  222. package/tests/redactshots.test.ts +216 -0
  223. package/tests/registernvidiakeys.ts +51 -0
  224. package/tests/relayserve.test.ts +304 -0
  225. package/tests/releasenotes.test.ts +276 -0
  226. package/tests/resilience.test.ts +467 -0
  227. package/tests/resourceaware.test.ts +187 -0
  228. package/tests/runbudget.test.ts +125 -0
  229. package/tests/runhistory.test.ts +299 -0
  230. package/tests/runreplay.test.ts +113 -0
  231. package/tests/runresume.test.ts +184 -0
  232. package/tests/runstate.test.ts +288 -0
  233. package/tests/runtimeadapters.test.ts +251 -0
  234. package/tests/safariskeleton.test.ts +115 -0
  235. package/tests/sandboxframe.test.ts +196 -0
  236. package/tests/sbom.test.ts +105 -0
  237. package/tests/secretvault.test.ts +188 -0
  238. package/tests/selcache.test.ts +111 -0
  239. package/tests/sessioninterface.test.ts +791 -0
  240. package/tests/sessions.test.ts +591 -0
  241. package/tests/siteprefs.test.ts +228 -0
  242. package/tests/snapshotdelta.test.ts +165 -0
  243. package/tests/statusviews.test.ts +237 -0
  244. package/tests/stepmeter.test.ts +200 -0
  245. package/tests/streamparse.test.ts +163 -0
  246. package/tests/stylepruning.test.ts +90 -0
  247. package/tests/surfaces.test.ts +282 -0
  248. package/tests/sweep.test.ts +78 -0
  249. package/tests/syncbridge.test.ts +164 -0
  250. package/tests/taskqueue.test.ts +206 -0
  251. package/tests/toolcalls.test.ts +336 -0
  252. package/tests/toolcatalog.test.ts +201 -0
  253. package/tests/torture-agent.test.ts +706 -0
  254. package/tests/torture-auth.test.ts +461 -0
  255. package/tests/torture-commands.test.ts +895 -0
  256. package/tests/torture-data.test.ts +923 -0
  257. package/tests/torture-environments.test.ts +285 -0
  258. package/tests/torture-export.test.ts +263 -0
  259. package/tests/torture-http.test.ts +1379 -0
  260. package/tests/torture-llm.test.ts +808 -0
  261. package/tests/torture-memory.test.ts +1084 -0
  262. package/tests/torture-plan.test.ts +829 -0
  263. package/tests/torture-run.test.ts +626 -0
  264. package/tests/torture-session.test.ts +928 -0
  265. package/tests/torture-swarm.test.ts +1245 -0
  266. package/tests/torture-tools.test.ts +964 -0
  267. package/tests/torture-workflow.test.ts +2354 -0
  268. package/tests/tourviews.test.ts +52 -0
  269. package/tests/transparency.test.ts +147 -0
  270. package/tests/trigger.test.ts +941 -0
  271. package/tests/v1sunset.test.ts +428 -0
  272. package/tests/virtlist.test.ts +94 -0
  273. package/tests/vision.test.ts +540 -0
  274. package/tests/vsixpack.test.ts +145 -0
  275. package/tests/webapi.test.ts +523 -0
  276. package/tests/workflow.test.ts +1785 -0
  277. package/tests/workfloweditor.test.ts +759 -0
  278. package/tests/xpipack.test.ts +128 -0
  279. package/tools.ts +734 -0
  280. package/types.ts +9908 -0
  281. package/umd.ts +9 -0
  282. package/utils.ts +249 -0
  283. package/version.ts +8 -0
  284. package/versionregistry.ts +1310 -0
  285. package/views.ts +2153 -0
  286. package/vitest.config.ts +12 -0
  287. package/web/App.tsx +78 -0
  288. package/web/README.md +47 -0
  289. package/web/capacitor.config.ts +46 -0
  290. package/web/const.ts +19 -0
  291. package/web/control.shell.tsx +66 -0
  292. package/web/dashboardpage.ts +554 -0
  293. package/web/db.ts +493 -0
  294. package/web/design.html +541 -0
  295. package/web/gatewayview/Gateway.tsx +345 -0
  296. package/web/gatewayview/config.ts +1042 -0
  297. package/web/gatewayview/definition.ts +174 -0
  298. package/web/icons.ts +15 -0
  299. package/{manifest.json → web/manifest.json} +1 -1
  300. package/web/optionspage.ts +691 -0
  301. package/web/popup.ts +1651 -0
  302. package/web/schema.prisma +176 -0
  303. package/web/sidepanel.ts +7941 -0
  304. package/web/sitemanifest.json +13 -0
  305. package/web/terminal-ui.tsx +622 -0
  306. package/web/transparencypage.ts +541 -0
  307. package/web/vite.config.ts +39 -0
  308. package/web/workspace.ts +23 -0
  309. package/workbenchmemory.ts +104 -0
  310. package/workbenchsession.ts +304 -0
  311. package/workflow.ts +4495 -0
  312. package/bridge.d.ts.map +0 -1
  313. package/bridge.js +0 -1877
  314. package/bun.d.ts.map +0 -1
  315. package/bun.js +0 -52329
  316. package/caps/background.json +0 -712
  317. package/caps/cli.json +0 -360
  318. package/caps/library.json +0 -3611
  319. package/caps/mcp.json +0 -126
  320. package/caps/pagebridge.json +0 -377
  321. package/caps/popup.json +0 -51
  322. package/caps/sidepanel.json +0 -522
  323. package/checksums.txt +0 -142
  324. package/cli.d.ts.map +0 -1
  325. package/companion.d.ts.map +0 -1
  326. package/companion.js +0 -389
  327. package/crossbrowser.d.ts.map +0 -1
  328. package/crossbrowser.js +0 -1191
  329. package/dashdone.d.ts.map +0 -1
  330. package/dashdone.js +0 -368
  331. package/deno.d.ts.map +0 -1
  332. package/deno.js +0 -52325
  333. package/devthink.umd.js +0 -52346
  334. package/fixtures/bun.ts +0 -7
  335. package/fixtures/cjs.js +0 -6
  336. package/fixtures/deno.ts +0 -6
  337. package/fixtures/example-org-pagestate.json +0 -22
  338. package/fixtures/importers/automa-workflow.json +0 -18
  339. package/fixtures/importers/selenium-side.json +0 -20
  340. package/fixtures/importers/tabular-plan.csv +0 -7
  341. package/fixtures/importers/uivision-macro.json +0 -10
  342. package/fixtures/importers/v1-plan.json +0 -13
  343. package/fixtures/mcp-client.mjs +0 -14
  344. package/fixtures/pages/checkout.html +0 -192
  345. package/fixtures/pages/dashboard.html +0 -110
  346. package/fixtures/pages/feed.html +0 -113
  347. package/fixtures/pages/product-grid.html +0 -150
  348. package/fixtures/plans/form-inventory-plan.json +0 -11
  349. package/fixtures/plans/release-notes-plan.json +0 -11
  350. package/fixtures/recipes/agentscompete.json +0 -11
  351. package/fixtures/recipes/agentsforms.json +0 -11
  352. package/fixtures/recipes/agentsmonitor.json +0 -11
  353. package/fixtures/recipes/agentsreview.json +0 -29
  354. package/fixtures/recipes/agentswarm.json +0 -11
  355. package/fixtures/recipes/fillcalendar.json +0 -12
  356. package/fixtures/recipes/fillcheckout.json +0 -13
  357. package/fixtures/recipes/filldependentdropdowns.json +0 -12
  358. package/fixtures/recipes/fillfromcsv.json +0 -13
  359. package/fixtures/recipes/fillloginform.json +0 -12
  360. package/fixtures/recipes/fillmultistepwizard.json +0 -13
  361. package/fixtures/recipes/fillregistration.json +0 -12
  362. package/fixtures/recipes/fillsearchfilters.json +0 -12
  363. package/fixtures/recipes/filltypeahead.json +0 -11
  364. package/fixtures/recipes/monitoralerts.json +0 -12
  365. package/fixtures/recipes/monitoravailability.json +0 -11
  366. package/fixtures/recipes/monitornetworkquiet.json +0 -12
  367. package/fixtures/recipes/monitorpagechanges.json +0 -11
  368. package/fixtures/recipes/monitorpricechange.json +0 -11
  369. package/fixtures/recipes/monitorschedule.json +0 -12
  370. package/fixtures/recipes/scrapedynamicprices.json +0 -13
  371. package/fixtures/recipes/scrapeimagegallery.json +0 -12
  372. package/fixtures/recipes/scrapeinfinitefeed.json +0 -13
  373. package/fixtures/recipes/scrapenestedlists.json +0 -12
  374. package/fixtures/recipes/scrapeproductgrid.json +0 -12
  375. package/fixtures/recipes/scrapereviews.json +0 -12
  376. package/fixtures/recipes/scrapesearchresults.json +0 -12
  377. package/fixtures/recipes/scrapetablepagination.json +0 -12
  378. package/fixtures/recipes/testaccessibility.json +0 -34
  379. package/fixtures/recipes/testconsoleerrors.json +0 -12
  380. package/fixtures/recipes/testdeeplinks.json +0 -12
  381. package/fixtures/recipes/testformvalidation.json +0 -13
  382. package/fixtures/recipes/testlayoutshift.json +0 -12
  383. package/fixtures/recipes/testlinkcheck.json +0 -12
  384. package/fixtures/recipes/testloadtiming.json +0 -12
  385. package/fixtures/recipes/testvisualdiff.json +0 -12
  386. package/fixtures/workflows/changelog-digest-workflow.json +0 -13
  387. package/fixtures/workflows/form-survey-workflow.json +0 -13
  388. package/gallery.json +0 -706
  389. package/hardening.d.ts.map +0 -1
  390. package/hardening.js +0 -188
  391. package/headless.d.ts.map +0 -1
  392. package/headless.js +0 -11522
  393. package/http.d.ts.map +0 -1
  394. package/http.js +0 -2165
  395. package/index.cjs +0 -54682
  396. package/index.d.ts.map +0 -1
  397. package/index.js +0 -52310
  398. package/index.neutral.js +0 -46343
  399. package/mcp.d.ts.map +0 -1
  400. package/mcp.js +0 -20515
  401. package/memory.d.ts.map +0 -1
  402. package/nativehost.template.json +0 -10
  403. package/node.cjs +0 -54686
  404. package/node.d.ts.map +0 -1
  405. package/pack.d.ts.map +0 -1
  406. package/pack.js +0 -805
  407. package/policy.d.ts.map +0 -1
  408. package/progress.d.ts.map +0 -1
  409. package/progress.js +0 -645
  410. package/protocol.d.ts.map +0 -1
  411. package/protocol.js +0 -8334
  412. package/schemas/audit.schema.json +0 -226
  413. package/schemas/capability.schema.json +0 -113
  414. package/schemas/envelope.schema.json +0 -162
  415. package/schemas/memory.schema.json +0 -51
  416. package/schemas/observation.schema.json +0 -113
  417. package/schemas/plan.schema.json +0 -208
  418. package/schemas/progress.schema.json +0 -126
  419. package/schemas/proposal.schema.json +0 -68
  420. package/schemas/session.schema.json +0 -82
  421. package/schemas/tool.schema.json +0 -94
  422. package/server.d.ts.map +0 -1
  423. package/server.js +0 -28877
  424. package/umd-example.html +0 -18
  425. package/umd.d.ts.map +0 -1
  426. /package/{bun.d.ts → dist/bun.d.ts} +0 -0
  427. /package/{cli.d.ts → dist/cli.d.ts} +0 -0
  428. /package/{companion.d.ts → dist/companion.d.ts} +0 -0
  429. /package/{crossbrowser.d.ts → dist/crossbrowser.d.ts} +0 -0
  430. /package/{dashdone.d.ts → dist/dashdone.d.ts} +0 -0
  431. /package/{deno.d.ts → dist/deno.d.ts} +0 -0
  432. /package/{hardening.d.ts → dist/hardening.d.ts} +0 -0
  433. /package/{headless.d.ts → dist/headless.d.ts} +0 -0
  434. /package/{http.d.ts → dist/http.d.ts} +0 -0
  435. /package/{index.d.ts → dist/index.d.ts} +0 -0
  436. /package/{mcp.d.ts → dist/mcp.d.ts} +0 -0
  437. /package/{memory.d.ts → dist/memory.d.ts} +0 -0
  438. /package/{node.d.ts → dist/node.d.ts} +0 -0
  439. /package/{pack.d.ts → dist/pack.d.ts} +0 -0
  440. /package/{policy.d.ts → dist/policy.d.ts} +0 -0
  441. /package/{progress.d.ts → dist/progress.d.ts} +0 -0
  442. /package/{protocol.d.ts → dist/protocol.d.ts} +0 -0
  443. /package/{server.d.ts → dist/server.d.ts} +0 -0
  444. /package/{umd.d.ts → dist/umd.d.ts} +0 -0
@@ -0,0 +1,449 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import {
3
+ ackreview,
4
+ applyreview,
5
+ arbitrate,
6
+ assignwork,
7
+ boardstate,
8
+ checkclaim,
9
+ collectresults,
10
+ consensusstate,
11
+ castvote,
12
+ electleader,
13
+ escalate,
14
+ openconsensus,
15
+ plannersplit,
16
+ reportstep,
17
+ requestreview,
18
+ resolveescalation,
19
+ scaleworkers,
20
+ sweepreviews,
21
+ } from "../swarm.js";
22
+ import type { agentidentity, arbitrationrule, handoffrecord, leaderworker, reviewrequest } from "../types.js";
23
+ import { emptyqueue, enqueue } from "../swarm.js";
24
+
25
+ const now = 1_800_000_000_000;
26
+
27
+ /** Builds one agent identity fixture with every value user chosen. */
28
+ function agent(over: Partial<agentidentity> = {}): agentidentity {
29
+ return {
30
+ id: "a1",
31
+ name: "Scout",
32
+ role: "worker",
33
+ depth: 0,
34
+ state: "active",
35
+ registeredat: now,
36
+ heartbeatat: now,
37
+ ...over,
38
+ };
39
+ }
40
+
41
+ /** Builds one review request fixture routed between two agents. */
42
+ function request(over: Partial<reviewrequest> = {}): reviewrequest {
43
+ return {
44
+ id: "r1",
45
+ fromagentid: "a1",
46
+ toagentid: "a2",
47
+ subject: "The extraction output",
48
+ payload: "The table rows",
49
+ state: "open",
50
+ requestedat: now,
51
+ ...over,
52
+ };
53
+ }
54
+
55
+ describe("orchestration leader election and work assignment", () => {
56
+ /** The stored agent list stays newest first, so the first registered agent sits at its end exactly like the registeragent order keeps it. */
57
+ const swarm = [
58
+ agent({ id: "a4", name: "Guide", role: "planner" }),
59
+ agent({ id: "a3", name: "Probe", role: "verifier" }),
60
+ agent({ id: "a2", name: "Scribe", role: "critic" }),
61
+ agent({ id: "a1", name: "Scout", role: "worker", tabid: 1 }),
62
+ ];
63
+
64
+ it("elects the first registered agent under the first rule and separates the worker, critic and verifier lanes", () => {
65
+ const topology = electleader({ agents: swarm, id: "top1", rule: { kind: "first" }, now });
66
+ expect(topology.leaderid).toBe("a1");
67
+ expect(topology.workerids).toEqual([]);
68
+ expect(topology.criticids).toEqual(["a2"]);
69
+ expect(topology.verifierids).toEqual(["a3"]);
70
+ expect(topology.rule).toEqual({ kind: "first" });
71
+ });
72
+
73
+ it("elects the user named agent under the named rule and refuses an unknown name", () => {
74
+ const topology = electleader({ agents: swarm, id: "top2", rule: { kind: "named", agentid: "a4" }, now });
75
+ expect(topology.leaderid).toBe("a4");
76
+ expect(topology.workerids).toEqual(["a1"]);
77
+ expect(() => electleader({ agents: swarm, id: "top3", rule: { kind: "named", agentid: "missing" }, now })).toThrow(
78
+ /not a live agent/i,
79
+ );
80
+ expect(() => electleader({ agents: swarm, id: "top4", rule: { kind: "named" }, now })).toThrow(
81
+ /agent id the user named/i,
82
+ );
83
+ });
84
+
85
+ it("slices the tasks across the workers in turns and records the worker assignments", () => {
86
+ const workers = [agent({ id: "a1" }), agent({ id: "a2" }), agent({ id: "a3" })];
87
+ const topology = electleader({
88
+ agents: [agent({ id: "a9", name: "Guide", role: "planner" }), ...workers],
89
+ id: "top5",
90
+ rule: { kind: "named", agentid: "a9" },
91
+ now,
92
+ });
93
+ const queue = enqueue({
94
+ queue: enqueue({
95
+ queue: emptyqueue({ lanes: ["extraction"] }),
96
+ id: "t1",
97
+ lane: "extraction",
98
+ priority: 1,
99
+ payload: "Read the table",
100
+ now,
101
+ }),
102
+ id: "t2",
103
+ lane: "extraction",
104
+ priority: 1,
105
+ payload: "Read the footer",
106
+ now,
107
+ });
108
+ const assigned = assignwork({ topology, tasks: queue.items, now: now + 1 });
109
+ expect(assigned.assignments.map((assignment) => assignment.workerid)).toEqual(["a1", "a2"]);
110
+ expect(assigned.assignments[0]).toMatchObject({ taskid: "t1", slice: expect.stringContaining("Read the table") });
111
+ expect(assignwork({ topology, tasks: [], now }).assignments).toHaveLength(0);
112
+ expect(() => assignwork({ topology: { ...topology, workerids: [] }, tasks: queue.items, now })).toThrow(
113
+ /no worker/i,
114
+ );
115
+ });
116
+
117
+ it("gathers the worker outputs with status and names the missing slices", () => {
118
+ const topology: leaderworker = {
119
+ id: "top",
120
+ leaderid: "a9",
121
+ workerids: ["a1", "a2"],
122
+ criticids: [],
123
+ verifierids: [],
124
+ assignments: [
125
+ { workerid: "a1", taskid: "t1", slice: "One", assignedat: now },
126
+ { workerid: "a2", taskid: "t2", slice: "Two", assignedat: now },
127
+ ],
128
+ rule: { kind: "first" },
129
+ electedat: now,
130
+ };
131
+ const gathered = collectresults({
132
+ topology,
133
+ outputs: [{ workerid: "a1", taskid: "t1", state: "done", summary: "Rows read." }],
134
+ });
135
+ expect(gathered.gathered[0]).toMatchObject({ state: "done", summary: "Rows read." });
136
+ expect(gathered.gathered[1]).toMatchObject({ state: "pending" });
137
+ expect(gathered.missing).toEqual(["a2:t2"]);
138
+ });
139
+
140
+ it("scales the worker lane by load under the user configured bound with no engine cap", () => {
141
+ const live = [
142
+ agent({ id: "a1" }),
143
+ agent({ id: "a2" }),
144
+ agent({ id: "a3" }),
145
+ agent({ id: "a9", name: "Guide", role: "planner" }),
146
+ ];
147
+ const topology: leaderworker = {
148
+ id: "top",
149
+ leaderid: "a9",
150
+ workerids: ["a1"],
151
+ criticids: [],
152
+ verifierids: [],
153
+ assignments: [],
154
+ rule: { kind: "first" },
155
+ electedat: now,
156
+ };
157
+ const grown = scaleworkers({ topology, agents: live, pending: 3, now });
158
+ expect(grown.added).toEqual(["a2", "a3"]);
159
+ expect(grown.topology.workerids).toEqual(["a1", "a2", "a3"]);
160
+ const bounded = scaleworkers({ topology: grown.topology, agents: live, pending: 6, bound: 3, now });
161
+ expect(bounded.added).toEqual([]);
162
+ expect(bounded.reason).toMatch(/bound of 3 workers holds/i);
163
+ const unbounded = scaleworkers({ topology: grown.topology, agents: live, pending: 9, now });
164
+ expect(unbounded.reason).toMatch(/no further live worker role agent to add/i);
165
+ const spare = scaleworkers({ topology: { ...topology, workerids: ["a1"] }, agents: live, pending: 2, now });
166
+ expect(spare.added).toEqual(["a2"]);
167
+ expect(spare.reason).toMatch(/added the workers a2/i);
168
+ const retired = scaleworkers({ topology: grown.topology, agents: live, pending: 1, now });
169
+ expect(retired.retired).toEqual(["a2", "a3"]);
170
+ expect(retired.topology.workerids).toEqual(["a1"]);
171
+ });
172
+ });
173
+
174
+ describe("orchestration planner executor split", () => {
175
+ it("keeps plan drafting and execution in different agents and collects the executor step reports", () => {
176
+ const split = plannersplit({ id: "s1", planownerid: "a1", runownerid: "a2", taskid: "t1", now });
177
+ expect(split).toMatchObject({ planownerid: "a1", runownerid: "a2", taskid: "t1" });
178
+ expect(split.stepreports).toHaveLength(0);
179
+ const reported = reportstep({
180
+ split,
181
+ stepid: "step1",
182
+ outcome: "done",
183
+ detail: "The row count is 42.",
184
+ now: now + 1,
185
+ });
186
+ const twice = reportstep({
187
+ split: reported,
188
+ stepid: "step1",
189
+ outcome: "failed",
190
+ detail: "The re-read found 41.",
191
+ now: now + 2,
192
+ });
193
+ expect(twice.stepreports).toHaveLength(1);
194
+ expect(twice.stepreports[0]).toMatchObject({ outcome: "failed" });
195
+ expect(() => plannersplit({ id: "s2", planownerid: "a1", runownerid: "a1", now })).toThrow(/different agents/i);
196
+ expect(() => reportstep({ split, stepid: " ", outcome: "done", detail: "d", now })).toThrow(/step id/i);
197
+ });
198
+ });
199
+
200
+ describe("orchestration critic review verdict flows", () => {
201
+ it("routes a review request between agents with ack, answer and timeout", () => {
202
+ const requests = requestreview({
203
+ requests: [],
204
+ id: "r1",
205
+ fromagentid: "a1",
206
+ toagentid: "a2",
207
+ subject: "The output",
208
+ payload: "The rows",
209
+ timeoutms: 1000,
210
+ now,
211
+ });
212
+ expect(requests[0]).toMatchObject({ state: "open", timeoutat: now + 1000 });
213
+ const acked = ackreview({ requests, id: "r1", now: now + 1 });
214
+ expect(acked[0]).toMatchObject({ state: "acked", ackedat: now + 1 });
215
+ expect(() => ackreview({ requests: acked, id: "r1", now: now + 2 })).toThrow(/only an open request/i);
216
+ const swept = sweepreviews({ requests: acked, now: now + 2000 });
217
+ expect(swept.requests[0]?.state).toBe("timeout");
218
+ expect(swept.timedout).toEqual(["r1"]);
219
+ const never = sweepreviews({
220
+ requests: requestreview({
221
+ requests: [],
222
+ id: "r2",
223
+ fromagentid: "a1",
224
+ toagentid: "a2",
225
+ subject: "s",
226
+ payload: "p",
227
+ now,
228
+ }),
229
+ now: now + 999_999,
230
+ });
231
+ expect(never.timedout).toEqual([]);
232
+ });
233
+
234
+ it("applies the critic verdict with issues and required changes and refuses the wrong reviewer", () => {
235
+ const requests = requestreview({
236
+ requests: [],
237
+ id: "r1",
238
+ fromagentid: "a1",
239
+ toagentid: "a2",
240
+ subject: "The output",
241
+ payload: "The rows",
242
+ now,
243
+ });
244
+ const outcome = applyreview({
245
+ requests,
246
+ id: "r1",
247
+ reviewerid: "a2",
248
+ verdict: "changes",
249
+ issues: ["One row is stale."],
250
+ requiredchanges: ["Re-read the footer."],
251
+ taskid: "t1",
252
+ now: now + 1,
253
+ });
254
+ expect(outcome.review).toMatchObject({
255
+ verdict: "changes",
256
+ subjectagentid: "a1",
257
+ issues: ["One row is stale."],
258
+ requiredchanges: ["Re-read the footer."],
259
+ });
260
+ expect(outcome.requests[0]).toMatchObject({ state: "answered", answeredat: now + 1 });
261
+ expect(() =>
262
+ applyreview({
263
+ requests: outcome.requests,
264
+ id: "r1",
265
+ reviewerid: "a2",
266
+ verdict: "approve",
267
+ issues: [],
268
+ requiredchanges: [],
269
+ now,
270
+ }),
271
+ ).toThrow(/never reviews again/i);
272
+ expect(() =>
273
+ applyreview({ requests, id: "r1", reviewerid: "a3", verdict: "approve", issues: [], requiredchanges: [], now }),
274
+ ).toThrow(/routes to the agent/i);
275
+ expect(() =>
276
+ applyreview({ requests, id: "r1", reviewerid: "a2", verdict: "changes", issues: [], requiredchanges: [], now }),
277
+ ).toThrow(/required changes/i);
278
+ });
279
+
280
+ it("routes review requests only to another reviewing agent", () => {
281
+ expect(() =>
282
+ requestreview({ requests: [], id: "r1", fromagentid: "a1", toagentid: "a1", subject: "s", payload: "p", now }),
283
+ ).toThrow(/never its own requester/i);
284
+ expect(() =>
285
+ requestreview({ requests: [], id: "r1", fromagentid: "a1", toagentid: "a2", subject: " ", payload: "p", now }),
286
+ ).toThrow(/subject/i);
287
+ });
288
+ });
289
+
290
+ describe("orchestration verifier pass and fail checks", () => {
291
+ it("marks one claim pass with the method used and its evidence", () => {
292
+ const pass = checkclaim({
293
+ id: "v1",
294
+ verifierid: "a3",
295
+ claimagentid: "a1",
296
+ claim: "The table holds 42 rows.",
297
+ method: "re-read",
298
+ outcome: "pass",
299
+ evidence: "The re-read counted 42 rows.",
300
+ taskid: "t1",
301
+ now,
302
+ });
303
+ expect(pass).toMatchObject({ outcome: "pass", method: "re-read", evidence: "The re-read counted 42 rows." });
304
+ });
305
+
306
+ it("marks one claim fail and refuses a claim or method without words", () => {
307
+ const fail = checkclaim({
308
+ id: "v2",
309
+ verifierid: "a3",
310
+ claimagentid: "a1",
311
+ claim: "The footer shows the price.",
312
+ method: "compare",
313
+ outcome: "fail",
314
+ now,
315
+ });
316
+ expect(fail.outcome).toBe("fail");
317
+ expect(fail.evidence).toBeUndefined();
318
+ expect(fail.taskid).toBeUndefined();
319
+ expect(() =>
320
+ checkclaim({
321
+ id: "v3",
322
+ verifierid: "a3",
323
+ claimagentid: "a1",
324
+ claim: " ",
325
+ method: "re-read",
326
+ outcome: "pass",
327
+ now,
328
+ }),
329
+ ).toThrow(/claim/i);
330
+ expect(() =>
331
+ checkclaim({ id: "v4", verifierid: "a3", claimagentid: "a1", claim: "c", method: " ", outcome: "pass", now }),
332
+ ).toThrow(/method/i);
333
+ });
334
+ });
335
+
336
+ describe("orchestration boardstate, escalation, arbitration and consensus", () => {
337
+ it("aggregates the agents, queue and topology into progressboard lanes", () => {
338
+ const agents = [agent({ id: "a1", name: "Scout" }), agent({ id: "a2", name: "Watcher", role: "observer" })];
339
+ const enqueued = enqueue({
340
+ queue: emptyqueue({ lanes: ["extraction"] }),
341
+ id: "t1",
342
+ lane: "extraction",
343
+ priority: 1,
344
+ payload: "Read the table",
345
+ now,
346
+ });
347
+ const queue = {
348
+ ...enqueued,
349
+ items: enqueued.items.map((item) => ({ ...item, state: "claimed" as const })),
350
+ claims: [{ agentid: "a1", taskid: "t1", claimedat: now, heartbeatat: now }],
351
+ };
352
+ const topology: leaderworker = {
353
+ id: "top",
354
+ leaderid: "a9",
355
+ workerids: ["a1"],
356
+ criticids: [],
357
+ verifierids: [],
358
+ assignments: [{ workerid: "a1", taskid: "t1", slice: "Read the table", assignedat: now }],
359
+ rule: { kind: "first" },
360
+ electedat: now,
361
+ };
362
+ const board = boardstate({
363
+ agents,
364
+ queue,
365
+ topology,
366
+ milestones: { a1: [{ label: "Rows read", done: true, at: now }] },
367
+ now,
368
+ });
369
+ expect(board.lanes).toHaveLength(2);
370
+ expect(board.lanes[0]).toMatchObject({
371
+ agentid: "a1",
372
+ role: "worker",
373
+ lane: "extraction",
374
+ currenttask: "Read the table",
375
+ });
376
+ expect(board.lanes[0]?.milestones[0]).toMatchObject({ label: "Rows read", done: true });
377
+ expect(board.lanes[1]).toMatchObject({ agentid: "a2", role: "observer", lane: "idle" });
378
+ });
379
+
380
+ it("lifts a stalled decision to the user and only the user decides it", () => {
381
+ const raised = escalate({
382
+ id: "e1",
383
+ agentid: "a1",
384
+ subject: "Which origin to open next",
385
+ context: "Both origins hold half of the table.",
386
+ now,
387
+ });
388
+ expect(raised).toMatchObject({ state: "open" });
389
+ expect(raised.decision).toBeUndefined();
390
+ const decided = resolveescalation({ escalation: raised, decision: "Open the second origin.", now: now + 1 });
391
+ expect(decided).toMatchObject({ state: "decided", decision: "Open the second origin.", decidedat: now + 1 });
392
+ expect(() => resolveescalation({ escalation: decided, decision: "Again.", now: now + 2 })).toThrow(
393
+ /already carries/i,
394
+ );
395
+ expect(() => escalate({ id: "e2", agentid: "a1", subject: "s", context: " ", now })).toThrow(/full context/i);
396
+ });
397
+
398
+ it("orders competing resource claims by the user rule and priority", () => {
399
+ const claims = [
400
+ { agentid: "a2", claimedat: now + 5 },
401
+ { agentid: "a1", claimedat: now },
402
+ { agentid: "a3", claimedat: now + 2 },
403
+ ];
404
+ const priority: arbitrationrule = {
405
+ id: "rule1",
406
+ strategy: "priority",
407
+ priorityorder: ["a3", "a2"],
408
+ configuredat: now,
409
+ };
410
+ expect(arbitrate({ rule: priority, claims })).toEqual(["a3", "a2", "a1"]);
411
+ expect(arbitrate({ rule: { ...priority, strategy: "age" }, claims })).toEqual(["a1", "a3", "a2"]);
412
+ expect(arbitrate({ rule: { ...priority, strategy: "leader" }, leaderid: "a2", claims })).toEqual([
413
+ "a2",
414
+ "a1",
415
+ "a3",
416
+ ]);
417
+ expect(() => arbitrate({ rule: { ...priority, strategy: "leader" }, claims })).toThrow(/elected leader/i);
418
+ expect(arbitrate({ rule: priority, claims: [] })).toEqual([]);
419
+ });
420
+
421
+ it("collects verdicts to the user configured quorum and closes the round", () => {
422
+ const round = openconsensus({ id: "c1", subject: "Which lane runs first", quorum: 2, now });
423
+ expect(round).toMatchObject({ state: "open", quorum: 2 });
424
+ const first = castvote({ round, agentid: "a1", vote: "yes", now: now + 1 });
425
+ expect(consensusstate(first)).toMatchObject({ yes: 1, no: 0, abstain: 0, quorum: 2, state: "open" });
426
+ const carried = castvote({ round: first, agentid: "a2", vote: "yes", now: now + 2 });
427
+ expect(carried.state).toBe("carried");
428
+ expect(() => castvote({ round: carried, agentid: "a3", vote: "yes", now: now + 3 })).toThrow(/closed round/i);
429
+ expect(() => castvote({ round: first, agentid: "a1", vote: "yes", now: now + 3 })).toThrow(/already voted/i);
430
+ const failing = openconsensus({ id: "c2", subject: "Abort the run", quorum: 2, now });
431
+ const votedno = castvote({ round: failing, agentid: "a1", vote: "no", now: now + 1 });
432
+ expect(castvote({ round: votedno, agentid: "a2", vote: "no", now: now + 2 }).state).toBe("failed");
433
+ expect(consensusstate(votedno).abstain).toBe(0);
434
+ expect(() => openconsensus({ id: "c3", subject: "s", quorum: 0, now })).toThrow(/quorum/i);
435
+ });
436
+
437
+ it("builds handoff shaped records from the swarm shapes without losing the packaged state", () => {
438
+ const record: handoffrecord = {
439
+ id: "h1",
440
+ fromagentid: "a1",
441
+ toagentid: "a2",
442
+ tabid: 7,
443
+ taskstate: "Halfway through the footer.",
444
+ state: "prepared",
445
+ createdat: now,
446
+ };
447
+ expect(record).toMatchObject({ state: "prepared", tabid: 7 });
448
+ });
449
+ });