@wenathlan/devthink 2.0.15 → 2.0.20

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 +54 -0
  2. package/{dist/bridge.d.ts → bridge.d.ts} +1 -1
  3. package/bridge.d.ts.map +1 -0
  4. package/bridge.js +1877 -0
  5. package/bun.d.ts.map +1 -0
  6. package/bun.js +52329 -0
  7. package/caps/background.json +712 -0
  8. package/caps/cli.json +360 -0
  9. package/caps/library.json +3611 -0
  10. package/caps/mcp.json +126 -0
  11. package/caps/pagebridge.json +377 -0
  12. package/caps/popup.json +51 -0
  13. package/caps/sidepanel.json +522 -0
  14. package/checksums.txt +142 -0
  15. package/cli.d.ts.map +1 -0
  16. package/{dist/cli.js → cli.js} +2 -2
  17. package/companion.d.ts.map +1 -0
  18. package/companion.js +389 -0
  19. package/crossbrowser.d.ts.map +1 -0
  20. package/crossbrowser.js +1191 -0
  21. package/dashdone.d.ts.map +1 -0
  22. package/dashdone.js +368 -0
  23. package/deno.d.ts.map +1 -0
  24. package/deno.js +52325 -0
  25. package/devthink.umd.js +52346 -0
  26. package/fixtures/bun.ts +7 -0
  27. package/fixtures/cjs.js +6 -0
  28. package/fixtures/deno.ts +6 -0
  29. package/fixtures/example-org-pagestate.json +22 -0
  30. package/fixtures/importers/automa-workflow.json +18 -0
  31. package/fixtures/importers/selenium-side.json +20 -0
  32. package/fixtures/importers/tabular-plan.csv +7 -0
  33. package/fixtures/importers/uivision-macro.json +10 -0
  34. package/fixtures/importers/v1-plan.json +13 -0
  35. package/fixtures/mcp-client.mjs +14 -0
  36. package/fixtures/pages/checkout.html +192 -0
  37. package/fixtures/pages/dashboard.html +110 -0
  38. package/fixtures/pages/feed.html +113 -0
  39. package/fixtures/pages/product-grid.html +150 -0
  40. package/fixtures/plans/form-inventory-plan.json +11 -0
  41. package/fixtures/plans/release-notes-plan.json +11 -0
  42. package/fixtures/recipes/agentscompete.json +11 -0
  43. package/fixtures/recipes/agentsforms.json +11 -0
  44. package/fixtures/recipes/agentsmonitor.json +11 -0
  45. package/fixtures/recipes/agentsreview.json +29 -0
  46. package/fixtures/recipes/agentswarm.json +11 -0
  47. package/fixtures/recipes/fillcalendar.json +12 -0
  48. package/fixtures/recipes/fillcheckout.json +13 -0
  49. package/fixtures/recipes/filldependentdropdowns.json +12 -0
  50. package/fixtures/recipes/fillfromcsv.json +13 -0
  51. package/fixtures/recipes/fillloginform.json +12 -0
  52. package/fixtures/recipes/fillmultistepwizard.json +13 -0
  53. package/fixtures/recipes/fillregistration.json +12 -0
  54. package/fixtures/recipes/fillsearchfilters.json +12 -0
  55. package/fixtures/recipes/filltypeahead.json +11 -0
  56. package/fixtures/recipes/monitoralerts.json +12 -0
  57. package/fixtures/recipes/monitoravailability.json +11 -0
  58. package/fixtures/recipes/monitornetworkquiet.json +12 -0
  59. package/fixtures/recipes/monitorpagechanges.json +11 -0
  60. package/fixtures/recipes/monitorpricechange.json +11 -0
  61. package/fixtures/recipes/monitorschedule.json +12 -0
  62. package/fixtures/recipes/scrapedynamicprices.json +13 -0
  63. package/fixtures/recipes/scrapeimagegallery.json +12 -0
  64. package/fixtures/recipes/scrapeinfinitefeed.json +13 -0
  65. package/fixtures/recipes/scrapenestedlists.json +12 -0
  66. package/fixtures/recipes/scrapeproductgrid.json +12 -0
  67. package/fixtures/recipes/scrapereviews.json +12 -0
  68. package/fixtures/recipes/scrapesearchresults.json +12 -0
  69. package/fixtures/recipes/scrapetablepagination.json +12 -0
  70. package/fixtures/recipes/testaccessibility.json +34 -0
  71. package/fixtures/recipes/testconsoleerrors.json +12 -0
  72. package/fixtures/recipes/testdeeplinks.json +12 -0
  73. package/fixtures/recipes/testformvalidation.json +13 -0
  74. package/fixtures/recipes/testlayoutshift.json +12 -0
  75. package/fixtures/recipes/testlinkcheck.json +12 -0
  76. package/fixtures/recipes/testloadtiming.json +12 -0
  77. package/fixtures/recipes/testvisualdiff.json +12 -0
  78. package/fixtures/workflows/changelog-digest-workflow.json +13 -0
  79. package/fixtures/workflows/form-survey-workflow.json +13 -0
  80. package/gallery.json +706 -0
  81. package/hardening.d.ts.map +1 -0
  82. package/hardening.js +188 -0
  83. package/headless.d.ts.map +1 -0
  84. package/headless.js +11522 -0
  85. package/http.d.ts.map +1 -0
  86. package/http.js +2165 -0
  87. package/index.cjs +54682 -0
  88. package/index.d.ts.map +1 -0
  89. package/index.js +52310 -0
  90. package/index.neutral.js +46343 -0
  91. package/{web/manifest.json → manifest.json} +1 -1
  92. package/mcp.d.ts.map +1 -0
  93. package/mcp.js +20515 -0
  94. package/memory.d.ts.map +1 -0
  95. package/{memory.ts → memory.js} +2310 -3834
  96. package/nativehost.template.json +10 -0
  97. package/node.cjs +54686 -0
  98. package/node.d.ts.map +1 -0
  99. package/pack.d.ts.map +1 -0
  100. package/pack.js +805 -0
  101. package/package.json +83 -176
  102. package/policy.d.ts.map +1 -0
  103. package/{policy.ts → policy.js} +4679 -5073
  104. package/progress.d.ts.map +1 -0
  105. package/progress.js +645 -0
  106. package/protocol.d.ts.map +1 -0
  107. package/protocol.js +8334 -0
  108. package/schemas/audit.schema.json +226 -0
  109. package/schemas/capability.schema.json +113 -0
  110. package/schemas/envelope.schema.json +162 -0
  111. package/schemas/memory.schema.json +51 -0
  112. package/schemas/observation.schema.json +113 -0
  113. package/schemas/plan.schema.json +208 -0
  114. package/schemas/progress.schema.json +126 -0
  115. package/schemas/proposal.schema.json +68 -0
  116. package/schemas/session.schema.json +82 -0
  117. package/schemas/tool.schema.json +94 -0
  118. package/server.d.ts.map +1 -0
  119. package/server.js +28877 -0
  120. package/umd-example.html +18 -0
  121. package/umd.d.ts.map +1 -0
  122. package/accounts.ts +0 -2087
  123. package/agent.ts +0 -2331
  124. package/antigravity.ts +0 -2139
  125. package/apifreeze.ts +0 -4146
  126. package/auth.ts +0 -642
  127. package/background.ts +0 -16837
  128. package/bridge.ts +0 -2080
  129. package/build.ts +0 -54
  130. package/bun.ts +0 -26
  131. package/capture.ts +0 -1614
  132. package/checksecrets.ts +0 -72
  133. package/cjs.ts +0 -9
  134. package/cli.ts +0 -3500
  135. package/commands.ts +0 -1101
  136. package/companion.ts +0 -450
  137. package/compatibility.ts +0 -37
  138. package/config.ts +0 -3137
  139. package/constants.ts +0 -943
  140. package/core.ts +0 -1473
  141. package/crossbrowser.ts +0 -1359
  142. package/dashdone.ts +0 -605
  143. package/data.ts +0 -943
  144. package/database.ts +0 -133
  145. package/debug.ts +0 -850
  146. package/deno.ts +0 -27
  147. package/devthink.ts +0 -707
  148. package/dist/accounts.d.ts +0 -409
  149. package/dist/agent.d.ts +0 -837
  150. package/dist/antigravity.d.ts +0 -380
  151. package/dist/apifreeze.d.ts +0 -113
  152. package/dist/auth.d.ts +0 -224
  153. package/dist/capture.d.ts +0 -595
  154. package/dist/cjs.d.ts +0 -6
  155. package/dist/commands.d.ts +0 -310
  156. package/dist/compatibility.d.ts +0 -17
  157. package/dist/config.d.ts +0 -1853
  158. package/dist/constants.d.ts +0 -637
  159. package/dist/core.d.ts +0 -361
  160. package/dist/data.d.ts +0 -330
  161. package/dist/database.d.ts +0 -24
  162. package/dist/debug.d.ts +0 -270
  163. package/dist/engine.d.ts +0 -74
  164. package/dist/environments.d.ts +0 -244
  165. package/dist/evidence.d.ts +0 -277
  166. package/dist/export.d.ts +0 -311
  167. package/dist/fingerprint.d.ts +0 -594
  168. package/dist/flow.d.ts +0 -300
  169. package/dist/gates.d.ts +0 -103
  170. package/dist/identity.d.ts +0 -51
  171. package/dist/ids.d.ts +0 -7
  172. package/dist/llm.d.ts +0 -652
  173. package/dist/models.d.ts +0 -1807
  174. package/dist/net.d.ts +0 -325
  175. package/dist/neutral.d.ts +0 -41
  176. package/dist/oauth.d.ts +0 -703
  177. package/dist/page.d.ts +0 -1166
  178. package/dist/perf.d.ts +0 -481
  179. package/dist/plan.d.ts +0 -134
  180. package/dist/project.d.ts +0 -395
  181. package/dist/providers.d.ts +0 -37
  182. package/dist/quota.d.ts +0 -453
  183. package/dist/recovery.d.ts +0 -621
  184. package/dist/request.d.ts +0 -1492
  185. package/dist/run.d.ts +0 -779
  186. package/dist/runtime.d.ts +0 -212
  187. package/dist/search.d.ts +0 -375
  188. package/dist/security.d.ts +0 -534
  189. package/dist/serve.d.ts +0 -136
  190. package/dist/session.d.ts +0 -296
  191. package/dist/storage.d.ts +0 -53
  192. package/dist/streaming.d.ts +0 -1119
  193. package/dist/swarm.d.ts +0 -328
  194. package/dist/tools.d.ts +0 -170
  195. package/dist/types.d.ts +0 -8357
  196. package/dist/utils.d.ts +0 -82
  197. package/dist/version.d.ts +0 -7
  198. package/dist/versionregistry.d.ts +0 -406
  199. package/dist/views.d.ts +0 -579
  200. package/dist/workbenchsession.d.ts +0 -69
  201. package/dist/workflow.d.ts +0 -649
  202. package/docs/readme.md +0 -92
  203. package/docs/schemas/antigravity.json +0 -192
  204. package/engine.ts +0 -1524
  205. package/environments.ts +0 -1005
  206. package/evidence.ts +0 -643
  207. package/export.ts +0 -889
  208. package/fingerprint.ts +0 -1458
  209. package/flow.ts +0 -1190
  210. package/gates.ts +0 -307
  211. package/gateway.ts +0 -34
  212. package/hardening.ts +0 -191
  213. package/headless.ts +0 -369
  214. package/http.ts +0 -2110
  215. package/identity.ts +0 -246
  216. package/ids.ts +0 -26
  217. package/index.ts +0 -369
  218. package/llm.ts +0 -2682
  219. package/mcp.ts +0 -1835
  220. package/models.ts +0 -3805
  221. package/modes.ts +0 -43
  222. package/net.ts +0 -1214
  223. package/neutral.ts +0 -362
  224. package/node.ts +0 -26
  225. package/oauth.ts +0 -2216
  226. package/offscreen.ts +0 -170
  227. package/pack.ts +0 -956
  228. package/page.ts +0 -7824
  229. package/pagebridge.ts +0 -1116
  230. package/perf.ts +0 -957
  231. package/plan.ts +0 -672
  232. package/plugin.ts +0 -76
  233. package/prisma.config.ts +0 -27
  234. package/progress.ts +0 -1308
  235. package/project.ts +0 -1291
  236. package/protocol.ts +0 -4187
  237. package/providers.ts +0 -246
  238. package/quota.ts +0 -1887
  239. package/recovery.ts +0 -2433
  240. package/request.ts +0 -4482
  241. package/run.ts +0 -2135
  242. package/runtime.ts +0 -526
  243. package/search.ts +0 -1760
  244. package/security.ts +0 -1673
  245. package/serve.ts +0 -419
  246. package/server.ts +0 -5538
  247. package/session.ts +0 -1162
  248. package/storage.ts +0 -182
  249. package/streaming.ts +0 -4101
  250. package/swarm.ts +0 -884
  251. package/sync.ts +0 -56
  252. package/tests/agentcert.test.ts +0 -128
  253. package/tests/agentfleet.test.ts +0 -214
  254. package/tests/agentreview.test.ts +0 -241
  255. package/tests/agentstream.test.ts +0 -335
  256. package/tests/agentwork.test.ts +0 -356
  257. package/tests/apifreeze.test.ts +0 -290
  258. package/tests/apimap.test.ts +0 -112
  259. package/tests/approvalgate.test.ts +0 -175
  260. package/tests/artifactmanifest.test.ts +0 -204
  261. package/tests/attentionfeed.test.ts +0 -163
  262. package/tests/backgroundruns.test.ts +0 -100
  263. package/tests/batchscheduling.test.ts +0 -131
  264. package/tests/blackboard.test.ts +0 -238
  265. package/tests/bridge.test.ts +0 -1088
  266. package/tests/browsercoverage.test.ts +0 -134
  267. package/tests/browserpolyfills.test.ts +0 -124
  268. package/tests/build.mjs +0 -1260
  269. package/tests/clientauth.test.ts +0 -223
  270. package/tests/clitools.test.ts +0 -578
  271. package/tests/confirmgates.test.ts +0 -190
  272. package/tests/containerpack.test.ts +0 -143
  273. package/tests/controlflow.test.ts +0 -2120
  274. package/tests/coordination.test.ts +0 -345
  275. package/tests/copyscreen.test.ts +0 -139
  276. package/tests/core.test.ts +0 -417
  277. package/tests/costcert.test.ts +0 -95
  278. package/tests/crossbrowser.test.ts +0 -115
  279. package/tests/cspaudit.test.ts +0 -79
  280. package/tests/dashdone.test.ts +0 -615
  281. package/tests/datagrid.test.ts +0 -137
  282. package/tests/doccheck.test.ts +0 -107
  283. package/tests/dombatch.test.ts +0 -109
  284. package/tests/emulation.test.ts +0 -282
  285. package/tests/environments.test.ts +0 -259
  286. package/tests/evidenceviews.test.ts +0 -88
  287. package/tests/exporttools.test.ts +0 -185
  288. package/tests/firefoxprep.test.ts +0 -134
  289. package/tests/flowlibrary.test.ts +0 -242
  290. package/tests/flowrun.test.ts +0 -303
  291. package/tests/forensics.test.ts +0 -439
  292. package/tests/gateway.test.ts +0 -939
  293. package/tests/headlesslib.test.ts +0 -171
  294. package/tests/httpstream.test.ts +0 -277
  295. package/tests/immutablelog.test.ts +0 -157
  296. package/tests/inboundguard.test.ts +0 -177
  297. package/tests/lazyload.test.ts +0 -72
  298. package/tests/librarymodes.test.ts +0 -623
  299. package/tests/llm.test.ts +0 -696
  300. package/tests/manifest.test.ts +0 -226
  301. package/tests/maskinputs.test.ts +0 -150
  302. package/tests/matrixverify.test.ts +0 -111
  303. package/tests/mavenpack.test.ts +0 -75
  304. package/tests/mcpserver.test.ts +0 -704
  305. package/tests/memory.test.ts +0 -4155
  306. package/tests/memorycare.test.ts +0 -230
  307. package/tests/migrateplan.test.ts +0 -349
  308. package/tests/minimization.test.ts +0 -414
  309. package/tests/modelroute.test.ts +0 -112
  310. package/tests/multiagent.test.ts +0 -440
  311. package/tests/nativebridge.test.ts +0 -807
  312. package/tests/navigation.test.ts +0 -284
  313. package/tests/nugetpack.test.ts +0 -83
  314. package/tests/orchestration.test.ts +0 -449
  315. package/tests/originpolicy.test.ts +0 -405
  316. package/tests/outputcompare.test.ts +0 -97
  317. package/tests/package.test.ts +0 -91
  318. package/tests/pagebridge.test.ts +0 -5909
  319. package/tests/pentest.test.ts +0 -75
  320. package/tests/perfrecords.test.ts +0 -257
  321. package/tests/permdiff.test.ts +0 -85
  322. package/tests/phishguard.test.ts +0 -128
  323. package/tests/pickerviews.test.ts +0 -155
  324. package/tests/pipelines.test.ts +0 -381
  325. package/tests/planlint.test.ts +0 -240
  326. package/tests/planreview.test.ts +0 -383
  327. package/tests/platformtargets.test.ts +0 -56
  328. package/tests/policy.test.ts +0 -8284
  329. package/tests/portability.test.ts +0 -96
  330. package/tests/progress.test.ts +0 -1036
  331. package/tests/promptlibrary.test.ts +0 -116
  332. package/tests/protocol.test.ts +0 -4793
  333. package/tests/publishingpipeline.test.ts +0 -314
  334. package/tests/quickactions.test.ts +0 -164
  335. package/tests/readiness.test.ts +0 -78
  336. package/tests/recipes.test.ts +0 -163
  337. package/tests/redactshots.test.ts +0 -216
  338. package/tests/registernvidiakeys.ts +0 -51
  339. package/tests/relayserve.test.ts +0 -304
  340. package/tests/releasenotes.test.ts +0 -276
  341. package/tests/resilience.test.ts +0 -467
  342. package/tests/resourceaware.test.ts +0 -187
  343. package/tests/runbudget.test.ts +0 -125
  344. package/tests/runhistory.test.ts +0 -299
  345. package/tests/runreplay.test.ts +0 -113
  346. package/tests/runresume.test.ts +0 -184
  347. package/tests/runstate.test.ts +0 -288
  348. package/tests/runtimeadapters.test.ts +0 -251
  349. package/tests/safariskeleton.test.ts +0 -115
  350. package/tests/sandboxframe.test.ts +0 -196
  351. package/tests/sbom.test.ts +0 -105
  352. package/tests/secretvault.test.ts +0 -188
  353. package/tests/selcache.test.ts +0 -111
  354. package/tests/sessioninterface.test.ts +0 -791
  355. package/tests/sessions.test.ts +0 -591
  356. package/tests/siteprefs.test.ts +0 -228
  357. package/tests/snapshotdelta.test.ts +0 -165
  358. package/tests/statusviews.test.ts +0 -237
  359. package/tests/stepmeter.test.ts +0 -200
  360. package/tests/streamparse.test.ts +0 -163
  361. package/tests/stylepruning.test.ts +0 -90
  362. package/tests/surfaces.test.ts +0 -282
  363. package/tests/sweep.test.ts +0 -78
  364. package/tests/syncbridge.test.ts +0 -164
  365. package/tests/taskqueue.test.ts +0 -206
  366. package/tests/toolcalls.test.ts +0 -336
  367. package/tests/toolcatalog.test.ts +0 -201
  368. package/tests/torture-agent.test.ts +0 -706
  369. package/tests/torture-auth.test.ts +0 -461
  370. package/tests/torture-commands.test.ts +0 -895
  371. package/tests/torture-data.test.ts +0 -923
  372. package/tests/torture-environments.test.ts +0 -285
  373. package/tests/torture-export.test.ts +0 -263
  374. package/tests/torture-http.test.ts +0 -1379
  375. package/tests/torture-llm.test.ts +0 -808
  376. package/tests/torture-memory.test.ts +0 -1084
  377. package/tests/torture-plan.test.ts +0 -829
  378. package/tests/torture-run.test.ts +0 -626
  379. package/tests/torture-session.test.ts +0 -928
  380. package/tests/torture-swarm.test.ts +0 -1245
  381. package/tests/torture-tools.test.ts +0 -964
  382. package/tests/torture-workflow.test.ts +0 -2354
  383. package/tests/tourviews.test.ts +0 -52
  384. package/tests/transparency.test.ts +0 -147
  385. package/tests/trigger.test.ts +0 -941
  386. package/tests/v1sunset.test.ts +0 -428
  387. package/tests/virtlist.test.ts +0 -94
  388. package/tests/vision.test.ts +0 -540
  389. package/tests/vsixpack.test.ts +0 -145
  390. package/tests/webapi.test.ts +0 -523
  391. package/tests/workflow.test.ts +0 -1785
  392. package/tests/workfloweditor.test.ts +0 -759
  393. package/tests/xpipack.test.ts +0 -128
  394. package/tools.ts +0 -734
  395. package/types.ts +0 -9908
  396. package/umd.ts +0 -9
  397. package/utils.ts +0 -249
  398. package/version.ts +0 -8
  399. package/versionregistry.ts +0 -1310
  400. package/views.ts +0 -2153
  401. package/vitest.config.ts +0 -12
  402. package/web/App.tsx +0 -78
  403. package/web/README.md +0 -47
  404. package/web/capacitor.config.ts +0 -46
  405. package/web/const.ts +0 -19
  406. package/web/control.shell.tsx +0 -66
  407. package/web/dashboardpage.ts +0 -554
  408. package/web/db.ts +0 -493
  409. package/web/design.html +0 -541
  410. package/web/gatewayview/Gateway.tsx +0 -345
  411. package/web/gatewayview/config.ts +0 -1042
  412. package/web/gatewayview/definition.ts +0 -174
  413. package/web/icons.ts +0 -15
  414. package/web/optionspage.ts +0 -691
  415. package/web/popup.ts +0 -1651
  416. package/web/schema.prisma +0 -176
  417. package/web/sidepanel.ts +0 -7941
  418. package/web/sitemanifest.json +0 -13
  419. package/web/terminal-ui.tsx +0 -622
  420. package/web/transparencypage.ts +0 -541
  421. package/web/vite.config.ts +0 -39
  422. package/web/workspace.ts +0 -23
  423. package/workbenchmemory.ts +0 -104
  424. package/workbenchsession.ts +0 -304
  425. package/workflow.ts +0 -4495
  426. /package/{dist/bun.d.ts → bun.d.ts} +0 -0
  427. /package/{dist/cli.d.ts → cli.d.ts} +0 -0
  428. /package/{dist/companion.d.ts → companion.d.ts} +0 -0
  429. /package/{dist/crossbrowser.d.ts → crossbrowser.d.ts} +0 -0
  430. /package/{dist/dashdone.d.ts → dashdone.d.ts} +0 -0
  431. /package/{dist/deno.d.ts → deno.d.ts} +0 -0
  432. /package/{dist/hardening.d.ts → hardening.d.ts} +0 -0
  433. /package/{dist/headless.d.ts → headless.d.ts} +0 -0
  434. /package/{dist/http.d.ts → http.d.ts} +0 -0
  435. /package/{dist/index.d.ts → index.d.ts} +0 -0
  436. /package/{dist/mcp.d.ts → mcp.d.ts} +0 -0
  437. /package/{dist/memory.d.ts → memory.d.ts} +0 -0
  438. /package/{dist/node.d.ts → node.d.ts} +0 -0
  439. /package/{dist/pack.d.ts → pack.d.ts} +0 -0
  440. /package/{dist/policy.d.ts → policy.d.ts} +0 -0
  441. /package/{dist/progress.d.ts → progress.d.ts} +0 -0
  442. /package/{dist/protocol.d.ts → protocol.d.ts} +0 -0
  443. /package/{dist/server.d.ts → server.d.ts} +0 -0
  444. /package/{dist/umd.d.ts → umd.d.ts} +0 -0
package/progress.ts DELETED
@@ -1,1308 +0,0 @@
1
- import type {
2
- agentplan,
3
- clockadapter,
4
- environmentkind,
5
- gatewaitevidence,
6
- perfrecord,
7
- planprogress,
8
- shotpair,
9
- shotrecord,
10
- snapshotchange,
11
- stepoutcome,
12
- wizardstate,
13
- } from "./types.js";
14
- import { packageversion, protocolmajor } from "./version.js";
15
-
16
- /**
17
- * Execution-progress logics for reviewed plans.
18
- * Every correlated rule for step completion, outcome history, deduplication and plan closure lives in this file. The 1.1.81 library modes keep the module clock free: the progress model takes the clock adapter the runtime injects, so the timestamps answer the adapter seam instead of a clock the module creates.
19
- */
20
-
21
- /** One release candidate provenance stamp of the rc audit trail: the package release and the protocol major of the build that produced the stamped entry, so the audit trail answers which release wrote every progress record and every step stamp. */
22
- export interface provenancestamp {
23
- /** The package release of the build that produced the stamped entry, read from the version.ts packageversion const. */
24
- release: string;
25
- /** The frozen protocol major of the build that produced the stamped entry, read from the version.ts protocolmajor const. */
26
- protocolmajor: number;
27
- }
28
-
29
- /** Stamps the release candidate provenance of this build: every progress record the stamp functions create and every outcome they record carries the stamp, so the audit trail names the release that produced each entry. */
30
- export function provenancestampof(): provenancestamp {
31
- return { release: packageversion, protocolmajor };
32
- }
33
-
34
- /** Reads the current timestamp through the clock adapter the runtime injected: the progress module owns no clock, so the running bundle decides what now means. Example: `progressnow(clock)` answers the adapter timestamp. */
35
- export function progressnow(clock: clockadapter): number {
36
- return clock.now();
37
- }
38
-
39
- /** Records one step outcome through the clock adapter: the completion stamp and the outcome append in one pass, so a caller drives the progress model with the injected clock alone. Example: `recordoutcomewithclock(progress, planid, outcome, clock)` stamps the adapter timestamp. */
40
- export function recordoutcomewithclock(
41
- progress: planprogress | undefined,
42
- planid: string,
43
- outcome: stepoutcome,
44
- clock: clockadapter,
45
- ): planprogress {
46
- return recordoutcome(progress, planid, outcome, clock.now());
47
- }
48
-
49
- /** Returns a fresh progress record for a plan that has not executed any step yet; the record carries the release candidate provenance stamp of the build that created it. */
50
- export function emptyprogress(planid: string, now: number): planprogress {
51
- return { planid, completedsteps: [], provenance: provenancestampof(), updatedat: now };
52
- }
53
-
54
- /** Records one successfully executed step; repeated executions of the same step stay deduplicated, and a fresh record carries the release candidate provenance stamp of the build that wrote it. */
55
- export function recordstep(
56
- progress: planprogress | undefined,
57
- planid: string,
58
- stepid: string,
59
- now: number,
60
- ): planprogress {
61
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
62
- if (base.completedsteps.includes(stepid)) return { ...base, updatedat: now };
63
- return { planid, completedsteps: [...base.completedsteps, stepid], provenance: provenancestampof(), updatedat: now };
64
- }
65
-
66
- /** Records one structured step outcome beside the completion log; outcomes are never truncated and every outcome gains the release candidate provenance stamp of the build that recorded it. */
67
- export function recordoutcome(
68
- progress: planprogress | undefined,
69
- planid: string,
70
- outcome: stepoutcome,
71
- now: number,
72
- ): planprogress {
73
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
74
- return {
75
- ...base,
76
- outcomes: [...(base.outcomes ?? []), { ...outcome, provenance: provenancestampof() }],
77
- updatedat: now,
78
- };
79
- }
80
-
81
- /** Records the execution environment of one completed step so the evidence trail reads where every step ran; repeated records of one step keep the latest environment. */
82
- export function recordenvironment(
83
- progress: planprogress | undefined,
84
- planid: string,
85
- stepid: string,
86
- environment: environmentkind,
87
- now: number,
88
- ): planprogress {
89
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
90
- return { ...base, environments: { ...(base.environments ?? {}), [stepid]: environment }, updatedat: now };
91
- }
92
-
93
- /** Reads the recorded execution environment of one step of the tracked plan. */
94
- export function environmentof(
95
- progress: planprogress | undefined,
96
- planid: string,
97
- stepid: string,
98
- ): environmentkind | undefined {
99
- if (!progress || progress.planid !== planid) return undefined;
100
- return (progress.environments ?? {})[stepid];
101
- }
102
-
103
- /** Records the worker turnaround of one offloaded step in milliseconds for later profiling; repeated records of one step keep the latest turnaround. */
104
- export function recordturnaround(
105
- progress: planprogress | undefined,
106
- planid: string,
107
- stepid: string,
108
- milliseconds: number,
109
- now: number,
110
- ): planprogress {
111
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
112
- return { ...base, turnarounds: { ...(base.turnarounds ?? {}), [stepid]: milliseconds }, updatedat: now };
113
- }
114
-
115
- /** Reads the recorded worker turnaround of one step of the tracked plan, in milliseconds. */
116
- export function turnaroundof(progress: planprogress | undefined, planid: string, stepid: string): number | undefined {
117
- if (!progress || progress.planid !== planid) return undefined;
118
- return (progress.turnarounds ?? {})[stepid];
119
- }
120
-
121
- /** Records the gate wait of one gated step beside its step durations: the confirm gate the step waited at with its waited milliseconds; repeated records of one step keep the latest wait. */
122
- export function recordgatewait(
123
- progress: planprogress | undefined,
124
- planid: string,
125
- stepid: string,
126
- entry: gatewaitevidence,
127
- now: number,
128
- ): planprogress {
129
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
130
- return { ...base, gatewaits: { ...(base.gatewaits ?? {}), [stepid]: entry }, updatedat: now };
131
- }
132
-
133
- /** Reads the recorded gate wait of one step of the tracked plan. */
134
- export function gatewaitof(
135
- progress: planprogress | undefined,
136
- planid: string,
137
- stepid: string,
138
- ): gatewaitevidence | undefined {
139
- if (!progress || progress.planid !== planid) return undefined;
140
- return (progress.gatewaits ?? {})[stepid];
141
- }
142
-
143
- /** Records the perf data of one executed step beside its outcome: the duration, the query count, the cache hits and the delta flag the step cost; repeated records of one step keep the latest measurement. */
144
- export function recordperf(
145
- progress: planprogress | undefined,
146
- planid: string,
147
- stepid: string,
148
- record: perfrecord,
149
- now: number,
150
- ): planprogress {
151
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
152
- return { ...base, perf: { ...(base.perf ?? {}), [stepid]: record }, updatedat: now };
153
- }
154
-
155
- /** Reads the recorded perf record of one step of the tracked plan: the duration, the query count and the cache hits beside the delta flag. */
156
- export function perfof(progress: planprogress | undefined, planid: string, stepid: string): perfrecord | undefined {
157
- if (!progress || progress.planid !== planid) return undefined;
158
- return (progress.perf ?? {})[stepid];
159
- }
160
-
161
- /** Records the snapshot change set of one executed step in the incrsnapshot change format, so progress deltas reuse the exact change format the snapshot builder emits; repeated records of one step keep the latest change set. */
162
- export function recorddeltas(
163
- progress: planprogress | undefined,
164
- planid: string,
165
- stepid: string,
166
- changes: snapshotchange[],
167
- now: number,
168
- ): planprogress {
169
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
170
- return { ...base, deltas: { ...(base.deltas ?? {}), [stepid]: changes }, updatedat: now };
171
- }
172
-
173
- /** Reads the recorded snapshot change set of one step of the tracked plan, in the incrsnapshot change format. */
174
- export function deltasof(progress: planprogress | undefined, planid: string, stepid: string): snapshotchange[] {
175
- if (!progress || progress.planid !== planid) return [];
176
- return (progress.deltas ?? {})[stepid] ?? [];
177
- }
178
-
179
- /** True only when every step of the plan has a recorded, successful execution. */
180
- export function iscomplete(progress: planprogress | undefined, plan: agentplan): boolean {
181
- if (!progress || progress.planid !== plan.id) return false;
182
- const required = plan.steps.map((step) => step.id);
183
- return required.length > 0 && required.every((id) => progress.completedsteps.includes(id));
184
- }
185
-
186
- /** Clears progress whenever a different plan replaces the tracked one while preserving prior history snapshots; the fresh record carries the release candidate provenance stamp of the build that reset it. */
187
- export function resetforplan(progress: planprogress | undefined, plan: agentplan, now: number): planprogress {
188
- if (progress && progress.planid === plan.id) return progress;
189
- if (!progress) return emptyprogress(plan.id, now);
190
- const snapshot: planprogress = {
191
- planid: progress.planid,
192
- completedsteps: progress.completedsteps,
193
- ...(progress.outcomes ? { outcomes: progress.outcomes } : {}),
194
- updatedat: progress.updatedat,
195
- };
196
- return {
197
- planid: plan.id,
198
- completedsteps: [],
199
- outcomes: [],
200
- prior: [...(progress.prior ?? []), snapshot],
201
- provenance: provenancestampof(),
202
- updatedat: now,
203
- };
204
- }
205
-
206
- /** True when a reviewed watch lifetime window has closed at the given time. */
207
- export function watchclosed(startedat: number, lifetime: number, now: number): boolean {
208
- return now >= startedat + lifetime;
209
- }
210
-
211
- /** Records one watch step as completed only once its reviewed lifetime window has closed. */
212
- export function recordwatchcompletion(
213
- progress: planprogress | undefined,
214
- planid: string,
215
- stepid: string,
216
- startedat: number,
217
- lifetime: number,
218
- now: number,
219
- ): planprogress {
220
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
221
- if (!watchclosed(startedat, lifetime, now)) return base;
222
- return recordstep(base, planid, stepid, now);
223
- }
224
-
225
- /** One navlist entry completion record with its index, url and outcome. */
226
- export interface naventry {
227
- index: number;
228
- url: string;
229
- ok: boolean;
230
- }
231
-
232
- /** Records one navlist entry as it completes, beside the step outcome log, so the trail shows current url and remaining count. */
233
- export function recordnaventry(
234
- progress: planprogress | undefined,
235
- planid: string,
236
- stepid: string,
237
- entry: naventry,
238
- now: number,
239
- ): planprogress {
240
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
241
- const outcome: stepoutcome = {
242
- stepid,
243
- ok: entry.ok,
244
- summary: `Navigation list entry ${entry.index + 1} of ${entry.url} ${entry.ok ? "completed" : "failed"}.`,
245
- details: { naventry: entry },
246
- at: now,
247
- };
248
- return recordoutcome(base, planid, outcome, now);
249
- }
250
-
251
- /** Returns every recorded navlist entry completion of one step, oldest first. */
252
- export function naventries(progress: planprogress | undefined, planid: string, stepid: string): naventry[] {
253
- if (!progress || progress.planid !== planid) return [];
254
- return (progress.outcomes ?? [])
255
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.naventry !== undefined)
256
- .map((outcome) => outcome.details?.naventry as naventry);
257
- }
258
-
259
- /** Assigns one tab to the running task so progress tracks work across its tabs. */
260
- export function assigntasktab(
261
- progress: planprogress | undefined,
262
- planid: string,
263
- tabid: number,
264
- now: number,
265
- ): planprogress {
266
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
267
- if ((base.tasktabs ?? []).includes(tabid)) return { ...base, updatedat: now };
268
- return { ...base, tasktabs: [...(base.tasktabs ?? []), tabid], updatedat: now };
269
- }
270
-
271
- /** Releases one task tab when its work inside the running task ends. */
272
- export function releasetasktab(
273
- progress: planprogress | undefined,
274
- planid: string,
275
- tabid: number,
276
- now: number,
277
- ): planprogress {
278
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
279
- const remaining = (base.tasktabs ?? []).filter((id) => id !== tabid);
280
- const { tasktabs: released, ...rest } = base;
281
- void released;
282
- return { ...rest, ...(remaining.length > 0 ? { tasktabs: remaining } : {}), updatedat: now };
283
- }
284
-
285
- /** Returns the tabs assigned to the running task, in assignment order. */
286
- export function tasktabs(progress: planprogress | undefined, planid: string): number[] {
287
- if (!progress || progress.planid !== planid) return [];
288
- return progress.tasktabs ?? [];
289
- }
290
-
291
- /** Returns the wizard completion share as executed steps over the total steps. */
292
- export function wizardcompletion(state: wizardstate): number {
293
- if (state.steps <= 0) return 0;
294
- return Math.min(1, state.completed.filter(Boolean).length / state.steps);
295
- }
296
-
297
- /** Returns the extraction progress share as rows collected over the user estimated total; an absent estimate stays at zero. */
298
- export function extractionshare(rowscollected: number, estimatedtotal: number): number {
299
- if (!Number.isFinite(estimatedtotal) || estimatedtotal <= 0) return 0;
300
- return Math.min(1, Math.max(0, rowscollected) / estimatedtotal);
301
- }
302
-
303
- /** One extraction page completion record with its page number, row count and cursor. */
304
- export interface extractionentry {
305
- page: number;
306
- rows: number;
307
- cursor: number;
308
- }
309
-
310
- /** Records one extracted page in the plan progress outcome log with its page count, row count and resume cursor. */
311
- export function recordextraction(
312
- progress: planprogress | undefined,
313
- planid: string,
314
- stepid: string,
315
- entry: extractionentry,
316
- now: number,
317
- ): planprogress {
318
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
319
- const outcome: stepoutcome = {
320
- stepid,
321
- ok: true,
322
- summary: `Extraction page ${entry.page} collected ${entry.rows} row${entry.rows === 1 ? "" : "s"} at cursor ${entry.cursor}.`,
323
- details: { extraction: entry },
324
- at: now,
325
- };
326
- return recordoutcome(base, planid, outcome, now);
327
- }
328
-
329
- /** Returns every recorded extraction page completion of one step, oldest first. */
330
- export function extractionentries(
331
- progress: planprogress | undefined,
332
- planid: string,
333
- stepid: string,
334
- ): extractionentry[] {
335
- if (!progress || progress.planid !== planid) return [];
336
- return (progress.outcomes ?? [])
337
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.extraction !== undefined)
338
- .map((outcome) => outcome.details?.extraction as extractionentry);
339
- }
340
-
341
- /** Records one wizard step completion into the plan progress outcome log, beside the step log, with the step index and total steps. */
342
- export function recordwizardstep(
343
- progress: planprogress | undefined,
344
- planid: string,
345
- stepid: string,
346
- state: wizardstate,
347
- now: number,
348
- ): planprogress {
349
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
350
- const executed = Math.min(state.index, state.steps);
351
- const done = executed >= state.steps;
352
- const outcome: stepoutcome = {
353
- stepid,
354
- ok: done,
355
- summary: `Wizard step ${executed} of ${state.steps} ${done ? "completed the wizard" : "executed"}.`,
356
- details: { wizard: { index: state.index, steps: state.steps, completed: [...state.completed] } },
357
- at: now,
358
- };
359
- return recordoutcome(base, planid, outcome, now);
360
- }
361
-
362
- /** Returns the batch download progress share as files completed over the total files of the batch. */
363
- export function downloadshare(completed: number, total: number): number {
364
- if (!Number.isFinite(total) || total <= 0) return 0;
365
- return Math.min(1, Math.max(0, completed) / total);
366
- }
367
-
368
- /** One batch download file completion record with its index, url and resulting state. */
369
- export interface downloadentry {
370
- index: number;
371
- url: string;
372
- state: string;
373
- }
374
-
375
- /** Records one batch download file completion in the plan progress outcome log so the queue shows live per file states. */
376
- export function recorddownload(
377
- progress: planprogress | undefined,
378
- planid: string,
379
- stepid: string,
380
- entry: downloadentry,
381
- now: number,
382
- ): planprogress {
383
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
384
- const outcome: stepoutcome = {
385
- stepid,
386
- ok: entry.state === "complete",
387
- summary: `Download ${entry.index + 1} of ${entry.url} ended in the ${entry.state} state.`,
388
- details: { download: entry },
389
- at: now,
390
- };
391
- return recordoutcome(base, planid, outcome, now);
392
- }
393
-
394
- /** Returns every recorded batch download file completion of one step, oldest first. */
395
- export function downloadentries(progress: planprogress | undefined, planid: string, stepid: string): downloadentry[] {
396
- if (!progress || progress.planid !== planid) return [];
397
- return (progress.outcomes ?? [])
398
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.download !== undefined)
399
- .map((outcome) => outcome.details?.download as downloadentry);
400
- }
401
-
402
- /** Records one capture completion in the plan progress outcome log with the record id, format and byte size as reviewable evidence. */
403
- export function recordcapture(
404
- progress: planprogress | undefined,
405
- planid: string,
406
- stepid: string,
407
- capture: shotrecord,
408
- now: number,
409
- ): planprogress {
410
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
411
- const bytes = capture.bytes?.length ?? 0;
412
- const outcome: stepoutcome = {
413
- stepid,
414
- ok: true,
415
- summary: `Captured a ${capture.format} ${capture.kind} shot of ${capture.width} by ${capture.height} pixels with ${bytes} character${bytes === 1 ? "" : "s"} of image data.`,
416
- details: {
417
- capture: {
418
- id: capture.id,
419
- kind: capture.kind,
420
- format: capture.format,
421
- width: capture.width,
422
- height: capture.height,
423
- bytes,
424
- },
425
- },
426
- at: now,
427
- };
428
- return recordoutcome(base, planid, outcome, now);
429
- }
430
-
431
- /** Records one before and after shotpair of a wrapped action in the plan progress outcome log with both shot ids and the dom snapshot id. */
432
- export function recordpair(
433
- progress: planprogress | undefined,
434
- planid: string,
435
- stepid: string,
436
- pair: shotpair,
437
- now: number,
438
- ): planprogress {
439
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
440
- const outcome: stepoutcome = {
441
- stepid,
442
- ok: true,
443
- summary: `Paired the before shot ${pair.beforeid} with the after shot ${pair.afterid} around the ${pair.actionkind} action.`,
444
- details: {
445
- shotpair: {
446
- id: pair.id,
447
- beforeid: pair.beforeid,
448
- afterid: pair.afterid,
449
- actionkind: pair.actionkind,
450
- ...(pair.target !== undefined ? { target: pair.target } : {}),
451
- ...(pair.domsnapshotid !== undefined ? { domsnapshotid: pair.domsnapshotid } : {}),
452
- },
453
- },
454
- at: now,
455
- };
456
- return recordoutcome(base, planid, outcome, now);
457
- }
458
-
459
- /** Returns every recorded capture completion of one step, oldest first. */
460
- export function captureentries(
461
- progress: planprogress | undefined,
462
- planid: string,
463
- stepid: string,
464
- ): Array<{ id: string; kind: string; format: string; width: number; height: number; bytes: number }> {
465
- if (!progress || progress.planid !== planid) return [];
466
- return (progress.outcomes ?? [])
467
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.capture !== undefined)
468
- .map(
469
- (outcome) =>
470
- outcome.details?.capture as {
471
- id: string;
472
- kind: string;
473
- format: string;
474
- width: number;
475
- height: number;
476
- bytes: number;
477
- },
478
- );
479
- }
480
-
481
- /** Returns every recorded shotpair of one step, oldest first. */
482
- export function pairentries(
483
- progress: planprogress | undefined,
484
- planid: string,
485
- stepid: string,
486
- ): Array<{ id: string; beforeid: string; afterid: string; actionkind: string }> {
487
- if (!progress || progress.planid !== planid) return [];
488
- return (progress.outcomes ?? [])
489
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.shotpair !== undefined)
490
- .map(
491
- (outcome) => outcome.details?.shotpair as { id: string; beforeid: string; afterid: string; actionkind: string },
492
- );
493
- }
494
-
495
- /** Records one media capture completion in the plan progress outcome log with the record id, kind, scope and byte size as reviewable evidence. */
496
- export function recordmedia(
497
- progress: planprogress | undefined,
498
- planid: string,
499
- stepid: string,
500
- media: { id: string; kind: string; scope: string; bytes: number },
501
- now: number,
502
- ): planprogress {
503
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
504
- const outcome: stepoutcome = {
505
- stepid,
506
- ok: true,
507
- summary: `Captured a ${media.kind} media record of ${media.scope} scope with ${media.bytes} character${media.bytes === 1 ? "" : "s"} of media data.`,
508
- details: { media },
509
- at: now,
510
- };
511
- return recordoutcome(base, planid, outcome, now);
512
- }
513
-
514
- /** Returns every recorded media capture completion of one step, oldest first. */
515
- export function mediaentries(
516
- progress: planprogress | undefined,
517
- planid: string,
518
- stepid: string,
519
- ): Array<{ id: string; kind: string; scope: string; bytes: number }> {
520
- if (!progress || progress.planid !== planid) return [];
521
- return (progress.outcomes ?? [])
522
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.media !== undefined)
523
- .map((outcome) => outcome.details?.media as { id: string; kind: string; scope: string; bytes: number });
524
- }
525
-
526
- /** One outbound call completion record with its transport facts, retries and byte counts as reviewable evidence. */
527
- export interface callentry {
528
- id: string;
529
- kind: string;
530
- origin: string;
531
- method: string;
532
- status: number;
533
- statusclass: string;
534
- duration: number;
535
- retries: number;
536
- bytes: number;
537
- }
538
-
539
- /** Records one outbound call completion in the plan progress outcome log with method, origin, status class, retries and byte counts. */
540
- export function recordcall(
541
- progress: planprogress | undefined,
542
- planid: string,
543
- stepid: string,
544
- entry: callentry,
545
- now: number,
546
- ): planprogress {
547
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
548
- const outcome: stepoutcome = {
549
- stepid,
550
- ok: entry.statusclass === "success",
551
- summary: `Outbound ${entry.method} ${entry.kind} call to ${entry.origin} ended in the ${entry.status} ${entry.statusclass} class after ${entry.retries} retr${entry.retries === 1 ? "y" : "ies"} and ${entry.bytes} byte${entry.bytes === 1 ? "" : "s"}.`,
552
- details: { call: entry },
553
- at: now,
554
- };
555
- return recordoutcome(base, planid, outcome, now);
556
- }
557
-
558
- /** Returns every recorded outbound call completion of one step, oldest first. */
559
- export function callentries(progress: planprogress | undefined, planid: string, stepid: string): callentry[] {
560
- if (!progress || progress.planid !== planid) return [];
561
- return (progress.outcomes ?? [])
562
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.call !== undefined)
563
- .map((outcome) => outcome.details?.call as callentry);
564
- }
565
-
566
- /** One fetch retry progress record with its attempt number, url and backoff wait. */
567
- export interface fetchretryentry {
568
- attempt: number;
569
- url: string;
570
- wait: number;
571
- reason: string;
572
- }
573
-
574
- /** Records one fetch retry in the plan progress outcome log so the sidepanel reports fetch progress on each retry. */
575
- export function recordfetchretry(
576
- progress: planprogress | undefined,
577
- planid: string,
578
- stepid: string,
579
- retry: fetchretryentry,
580
- now: number,
581
- ): planprogress {
582
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
583
- const outcome: stepoutcome = {
584
- stepid,
585
- ok: false,
586
- summary: `Fetch attempt ${retry.attempt} of ${retry.url} failed (${retry.reason}); retrying after a ${retry.wait} millisecond backoff.`,
587
- details: { fetchretry: retry },
588
- at: now,
589
- };
590
- return recordoutcome(base, planid, outcome, now);
591
- }
592
-
593
- /** Returns every recorded fetch retry of one step, oldest first. */
594
- export function fetchretryentries(
595
- progress: planprogress | undefined,
596
- planid: string,
597
- stepid: string,
598
- ): fetchretryentry[] {
599
- if (!progress || progress.planid !== planid) return [];
600
- return (progress.outcomes ?? [])
601
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.fetchretry !== undefined)
602
- .map((outcome) => outcome.details?.fetchretry as fetchretryentry);
603
- }
604
-
605
- /** One channel lifecycle evidence record with its id, kind, state and message counters. */
606
- export interface channelentry {
607
- id: string;
608
- kind: string;
609
- state: string;
610
- url: string;
611
- sent: number;
612
- received: number;
613
- }
614
-
615
- /** Records one channel lifecycle transition in the plan progress outcome log with its message counters. */
616
- export function recordchannel(
617
- progress: planprogress | undefined,
618
- planid: string,
619
- stepid: string,
620
- entry: channelentry,
621
- now: number,
622
- ): planprogress {
623
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
624
- const outcome: stepoutcome = {
625
- stepid,
626
- ok: entry.state !== "failed",
627
- summary: `The ${entry.kind} channel of ${entry.url} is ${entry.state} after ${entry.sent} sent and ${entry.received} received message${entry.received === 1 ? "" : "s"}.`,
628
- details: { channel: entry },
629
- at: now,
630
- };
631
- return recordoutcome(base, planid, outcome, now);
632
- }
633
-
634
- /** Returns every recorded channel lifecycle transition of one step, oldest first. */
635
- export function channelentries(progress: planprogress | undefined, planid: string, stepid: string): channelentry[] {
636
- if (!progress || progress.planid !== planid) return [];
637
- return (progress.outcomes ?? [])
638
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.channel !== undefined)
639
- .map((outcome) => outcome.details?.channel as channelentry);
640
- }
641
-
642
- /** One observed exchange evidence record with its correlation id, transport facts and error class. */
643
- export interface exchangeevidence {
644
- id: string;
645
- correlationid: string;
646
- method: string;
647
- origin: string;
648
- url: string;
649
- status: number;
650
- statusclass: string;
651
- duration: number;
652
- bytes: number;
653
- errorclass?: string;
654
- }
655
-
656
- /** Records one observed request exchange in the plan progress outcome log with its correlation id, status class, duration and byte size. */
657
- export function recordexchange(
658
- progress: planprogress | undefined,
659
- planid: string,
660
- stepid: string,
661
- entry: exchangeevidence,
662
- now: number,
663
- ): planprogress {
664
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
665
- const outcome: stepoutcome = {
666
- stepid,
667
- ok: entry.errorclass === undefined && entry.statusclass === "success",
668
- summary: `Observed the ${entry.method} request of ${entry.url} as exchange ${entry.correlationid} in the ${entry.status} ${entry.statusclass} class over ${entry.duration} millisecond${entry.duration === 1 ? "" : "s"}${entry.errorclass !== undefined ? ` failing with the ${entry.errorclass} class` : ""}.`,
669
- details: { exchange: entry },
670
- at: now,
671
- };
672
- return recordoutcome(base, planid, outcome, now);
673
- }
674
-
675
- /** Returns every recorded exchange evidence of one step, oldest first. */
676
- export function exchangeentries(
677
- progress: planprogress | undefined,
678
- planid: string,
679
- stepid: string,
680
- ): exchangeevidence[] {
681
- if (!progress || progress.planid !== planid) return [];
682
- return (progress.outcomes ?? [])
683
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.exchange !== undefined)
684
- .map((outcome) => outcome.details?.exchange as exchangeevidence);
685
- }
686
-
687
- /** One event stream evidence record with its url, event name, observed count and last event id. */
688
- export interface evententry {
689
- url: string;
690
- name: string;
691
- events: number;
692
- lasteventid?: string;
693
- }
694
-
695
- /** Records one server sent events observation in the plan progress outcome log with the event name, the observed count and the resume point. */
696
- export function recordevent(
697
- progress: planprogress | undefined,
698
- planid: string,
699
- stepid: string,
700
- entry: evententry,
701
- now: number,
702
- ): planprogress {
703
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
704
- const outcome: stepoutcome = {
705
- stepid,
706
- ok: true,
707
- summary: `The event stream of ${entry.url} observed ${entry.events} ${entry.name || "message"} event${entry.events === 1 ? "" : "s"}${entry.lasteventid !== undefined ? ` resuming from ${entry.lasteventid}` : ""}.`,
708
- details: { event: entry },
709
- at: now,
710
- };
711
- return recordoutcome(base, planid, outcome, now);
712
- }
713
-
714
- /** Returns every recorded event stream observation of one step, oldest first. */
715
- export function evententries(progress: planprogress | undefined, planid: string, stepid: string): evententry[] {
716
- if (!progress || progress.planid !== planid) return [];
717
- return (progress.outcomes ?? [])
718
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.event !== undefined)
719
- .map((outcome) => outcome.details?.event as evententry);
720
- }
721
-
722
- /** One long poll iteration evidence record with its poll number, cursor value and stop state. */
723
- export interface pollentry {
724
- poll: number;
725
- cursor?: string;
726
- status: number;
727
- stopped: boolean;
728
- reason: string;
729
- }
730
-
731
- /** Records one long poll iteration in the plan progress outcome log with its cursor value, status and stop reason. */
732
- export function recordpoll(
733
- progress: planprogress | undefined,
734
- planid: string,
735
- stepid: string,
736
- entry: pollentry,
737
- now: number,
738
- ): planprogress {
739
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
740
- const outcome: stepoutcome = {
741
- stepid,
742
- ok: true,
743
- summary: `Long poll ${entry.poll} returned the ${entry.status} status${entry.cursor !== undefined ? ` at cursor ${entry.cursor}` : ""} and ${entry.stopped ? `stopped: ${entry.reason}` : "continues"}.`,
744
- details: { poll: entry },
745
- at: now,
746
- };
747
- return recordoutcome(base, planid, outcome, now);
748
- }
749
-
750
- /** Returns every recorded long poll iteration of one step, oldest first. */
751
- export function pollentries(progress: planprogress | undefined, planid: string, stepid: string): pollentry[] {
752
- if (!progress || progress.planid !== planid) return [];
753
- return (progress.outcomes ?? [])
754
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.poll !== undefined)
755
- .map((outcome) => outcome.details?.poll as pollentry);
756
- }
757
-
758
- /** One traffic control evidence record of the run: the rule counts applied, blocked and mocked with the hits of the active rules. */
759
- export interface controlevidence {
760
- applied: number;
761
- blocked: number;
762
- mocked: number;
763
- reverts: number;
764
- reason: string;
765
- }
766
-
767
- /** Records one traffic control state change in the plan progress outcome log with the applied, blocked and mocked rule counts. */
768
- export function recordcontrol(
769
- progress: planprogress | undefined,
770
- planid: string,
771
- stepid: string,
772
- entry: controlevidence,
773
- now: number,
774
- ): planprogress {
775
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
776
- const outcome: stepoutcome = {
777
- stepid,
778
- ok: true,
779
- summary: `${entry.reason}: ${entry.applied} applied rule${entry.applied === 1 ? "" : "s"}, ${entry.blocked} blocked request${entry.blocked === 1 ? "" : "s"}, ${entry.mocked} mocked response${entry.mocked === 1 ? "" : "s"} and ${entry.reverts} reverted rule${entry.reverts === 1 ? "" : "s"}.`,
780
- details: { control: entry },
781
- at: now,
782
- };
783
- return recordoutcome(base, planid, outcome, now);
784
- }
785
-
786
- /** Returns every recorded traffic control evidence of one step, oldest first. */
787
- export function controlentries(progress: planprogress | undefined, planid: string, stepid: string): controlevidence[] {
788
- if (!progress || progress.planid !== planid) return [];
789
- return (progress.outcomes ?? [])
790
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.control !== undefined)
791
- .map((outcome) => outcome.details?.control as controlevidence);
792
- }
793
-
794
- /** One multipart upload progress record with its chunk count, uploaded bytes and total byte size. */
795
- export interface uploadentry {
796
- chunk: number;
797
- chunks: number;
798
- uploaded: number;
799
- bytes: number;
800
- }
801
-
802
- /** Records one multipart upload progress note in the plan progress outcome log with the uploaded chunk and byte counts. */
803
- export function recordupload(
804
- progress: planprogress | undefined,
805
- planid: string,
806
- stepid: string,
807
- entry: uploadentry,
808
- now: number,
809
- ): planprogress {
810
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
811
- const outcome: stepoutcome = {
812
- stepid,
813
- ok: true,
814
- summary: `The multipart upload moved chunk ${entry.chunk} of ${entry.chunks} with ${entry.uploaded} of ${entry.bytes} bytes sent.`,
815
- details: { upload: entry },
816
- at: now,
817
- };
818
- return recordoutcome(base, planid, outcome, now);
819
- }
820
-
821
- /** Returns every recorded multipart upload progress note of one step, oldest first. */
822
- export function uploadentries(progress: planprogress | undefined, planid: string, stepid: string): uploadentry[] {
823
- if (!progress || progress.planid !== planid) return [];
824
- return (progress.outcomes ?? [])
825
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.upload !== undefined)
826
- .map((outcome) => outcome.details?.upload as uploadentry);
827
- }
828
-
829
- /** One run timeline evidence record of a debugging step: the entry, error, rejection and long task counts with the spam collapse count. */
830
- export interface timelineevidence {
831
- entries: number;
832
- collapsed: number;
833
- errors: number;
834
- rejections: number;
835
- longtasks: number;
836
- }
837
-
838
- /** Records one run timeline capture in the plan progress outcome log with the entry, error, rejection and long task counts of the watched window. */
839
- export function recordtimeline(
840
- progress: planprogress | undefined,
841
- planid: string,
842
- stepid: string,
843
- entry: timelineevidence,
844
- now: number,
845
- ): planprogress {
846
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
847
- const outcome: stepoutcome = {
848
- stepid,
849
- ok: true,
850
- summary: `Captured ${entry.entries} timeline entr${entry.entries === 1 ? "y" : "ies"} with ${entry.collapsed} collapsed repeat${entry.collapsed === 1 ? "" : "s"}, ${entry.errors} error${entry.errors === 1 ? "" : "s"}, ${entry.rejections} rejection${entry.rejections === 1 ? "" : "s"} and ${entry.longtasks} long task${entry.longtasks === 1 ? "" : "s"}.`,
851
- details: { timeline: entry },
852
- at: now,
853
- };
854
- return recordoutcome(base, planid, outcome, now);
855
- }
856
-
857
- /** Returns every recorded run timeline capture of one step, oldest first. */
858
- export function timelineevidences(
859
- progress: planprogress | undefined,
860
- planid: string,
861
- stepid: string,
862
- ): timelineevidence[] {
863
- if (!progress || progress.planid !== planid) return [];
864
- return (progress.outcomes ?? [])
865
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.timeline !== undefined)
866
- .map((outcome) => outcome.details?.timeline as timelineevidence);
867
- }
868
-
869
- /** One devtools protocol evidence record of a debugging part two step: the family, the method or domain, the duration, the error class, the matched event or hit counts and the captured frame count. */
870
- export interface cdpevidence {
871
- family: "attach" | "detach" | "command" | "watch" | "breakpoint" | "step" | "pause" | "override";
872
- method?: string;
873
- domain?: string;
874
- duration?: number;
875
- errorclass?: string;
876
- events?: number;
877
- hits?: number;
878
- frames?: number;
879
- domains?: number;
880
- }
881
-
882
- /** Records one devtools protocol evidence in the plan progress outcome log with the family, the method or domain, the duration and the error class of the step. */
883
- export function recordcdp(
884
- progress: planprogress | undefined,
885
- planid: string,
886
- stepid: string,
887
- entry: cdpevidence,
888
- now: number,
889
- ): planprogress {
890
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
891
- const summary =
892
- entry.family === "command"
893
- ? `The reviewed ${entry.method ?? "raw"} command of the ${entry.domain ?? "unknown"} domain returned in ${entry.duration ?? 0} millisecond${(entry.duration ?? 0) === 1 ? "" : "s"}${entry.errorclass !== undefined ? ` with the ${entry.errorclass} error class` : ""}.`
894
- : `The devtools ${entry.family} step ran${entry.domain !== undefined ? ` on the ${entry.domain} domain` : ""}${entry.events !== undefined ? ` and matched ${entry.events} event${entry.events === 1 ? "" : "s"}` : ""}${entry.hits !== undefined ? ` with ${entry.hits} hit${entry.hits === 1 ? "" : "s"}` : ""}${entry.frames !== undefined ? ` capturing ${entry.frames} call frame${entry.frames === 1 ? "" : "s"}` : ""}.`;
895
- const outcome: stepoutcome = {
896
- stepid,
897
- ok: entry.errorclass === undefined,
898
- summary,
899
- details: { cdp: entry },
900
- at: now,
901
- };
902
- return recordoutcome(base, planid, outcome, now);
903
- }
904
-
905
- /** Returns every recorded devtools protocol evidence of one step, oldest first. */
906
- export function cdpevidences(progress: planprogress | undefined, planid: string, stepid: string): cdpevidence[] {
907
- if (!progress || progress.planid !== planid) return [];
908
- return (progress.outcomes ?? [])
909
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.cdp !== undefined)
910
- .map((outcome) => outcome.details?.cdp as cdpevidence);
911
- }
912
-
913
- /** One profiling evidence record of a debugging part three step: the instrument family, the metric, sample, node and event counts, the byte size, the flagged step count and the record ids of the heavy artifacts. */
914
- export interface profileevidence {
915
- family: "flow" | "heap" | "memory" | "cpu" | "shift" | "trace" | "annotate" | "replay" | "sourcemap";
916
- metrics?: number;
917
- samples?: number;
918
- nodes?: number;
919
- events?: number;
920
- bytes?: number;
921
- flagged?: number;
922
- recordids?: string[];
923
- }
924
-
925
- /** Records one profiling evidence in the plan progress outcome log with the instrument family, the counts of the capture and the record ids of the heavy artifacts. */
926
- export function recordprofile(
927
- progress: planprogress | undefined,
928
- planid: string,
929
- stepid: string,
930
- entry: profileevidence,
931
- now: number,
932
- ): planprogress {
933
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
934
- const counts =
935
- `${entry.metrics !== undefined ? `${entry.metrics} metric${entry.metrics === 1 ? "" : "s"}, ` : ""}${entry.samples !== undefined ? `${entry.samples} sample${entry.samples === 1 ? "" : "s"}, ` : ""}${entry.nodes !== undefined ? `${entry.nodes} node${entry.nodes === 1 ? "" : "s"}, ` : ""}${entry.events !== undefined ? `${entry.events} event${entry.events === 1 ? "" : "s"}, ` : ""}${entry.bytes !== undefined ? `${entry.bytes} byte${entry.bytes === 1 ? "" : "s"}, ` : ""}${entry.flagged !== undefined ? `${entry.flagged} flagged step${entry.flagged === 1 ? "" : "s"}, ` : ""}`.replace(
936
- /, $/,
937
- "",
938
- );
939
- const outcome: stepoutcome = {
940
- stepid,
941
- ok: true,
942
- summary: `The profiling ${entry.family} capture ran${counts.length > 0 ? ` with ${counts}` : ""}.`,
943
- details: { profile: entry },
944
- at: now,
945
- };
946
- return recordoutcome(base, planid, outcome, now);
947
- }
948
-
949
- /** Returns every recorded profiling evidence of one step, oldest first. */
950
- export function profileevidences(
951
- progress: planprogress | undefined,
952
- planid: string,
953
- stepid: string,
954
- ): profileevidence[] {
955
- if (!progress || progress.planid !== planid) return [];
956
- return (progress.outcomes ?? [])
957
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.profile !== undefined)
958
- .map((outcome) => outcome.details?.profile as profileevidence);
959
- }
960
-
961
- /** One emulation evidence record of a run: the applied and reverted layer names of the step with the reason the state changed. */
962
- export interface emulationevidence {
963
- applied: string[];
964
- reverted: string[];
965
- reason: string;
966
- }
967
-
968
- /** Records one emulation state change in the plan progress outcome log with the applied and reverted layer names of the step. */
969
- export function recordemulation(
970
- progress: planprogress | undefined,
971
- planid: string,
972
- stepid: string,
973
- entry: emulationevidence,
974
- now: number,
975
- ): planprogress {
976
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
977
- const outcome: stepoutcome = {
978
- stepid,
979
- ok: true,
980
- summary: `${entry.reason}: ${entry.applied.length} applied layer${entry.applied.length === 1 ? "" : "s"}${entry.applied.length > 0 ? ` (${entry.applied.join(", ")})` : ""} and ${entry.reverted.length} reverted layer${entry.reverted.length === 1 ? "" : "s"}${entry.reverted.length > 0 ? ` (${entry.reverted.join(", ")})` : ""}.`,
981
- details: { emulation: entry },
982
- at: now,
983
- };
984
- return recordoutcome(base, planid, outcome, now);
985
- }
986
-
987
- /** Returns every recorded emulation evidence of one step, oldest first. */
988
- export function emulationevidences(
989
- progress: planprogress | undefined,
990
- planid: string,
991
- stepid: string,
992
- ): emulationevidence[] {
993
- if (!progress || progress.planid !== planid) return [];
994
- return (progress.outcomes ?? [])
995
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.emulation !== undefined)
996
- .map((outcome) => outcome.details?.emulation as emulationevidence);
997
- }
998
-
999
- /** One session memory evidence record of a run: the family, the reviewed detail and the counts of the checkpoint, capture, restore, filing, diff, search, export or import. */
1000
- export interface sessionevidence {
1001
- family: "persist" | "capture" | "restore" | "name" | "diff" | "search" | "export" | "import" | "crash" | "auto";
1002
- detail: string;
1003
- recordid?: string;
1004
- sections?: number;
1005
- matches?: number;
1006
- restored?: number;
1007
- skipped?: number;
1008
- cursor?: number;
1009
- bytes?: number;
1010
- }
1011
-
1012
- /** Records one session memory evidence in the plan progress outcome log with the family, the reviewed detail and the counts of the step. */
1013
- export function recordsession(
1014
- progress: planprogress | undefined,
1015
- planid: string,
1016
- stepid: string,
1017
- entry: sessionevidence,
1018
- now: number,
1019
- ): planprogress {
1020
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
1021
- const counts =
1022
- `${entry.sections !== undefined ? `${entry.sections} section${entry.sections === 1 ? "" : "s"}, ` : ""}${entry.matches !== undefined ? `${entry.matches} match${entry.matches === 1 ? "" : "es"}, ` : ""}${entry.restored !== undefined ? `${entry.restored} restored tab${entry.restored === 1 ? "" : "s"}, ` : ""}${entry.skipped !== undefined ? `${entry.skipped} skipped origin${entry.skipped === 1 ? "" : "s"}, ` : ""}${entry.cursor !== undefined ? `cursor ${entry.cursor}, ` : ""}${entry.bytes !== undefined ? `${entry.bytes} byte${entry.bytes === 1 ? "" : "s"}, ` : ""}`.replace(
1023
- /, $/,
1024
- "",
1025
- );
1026
- const outcome: stepoutcome = {
1027
- stepid,
1028
- ok: true,
1029
- summary: `${entry.detail}${counts.length > 0 ? ` with ${counts}` : ""}.`,
1030
- details: { session: entry },
1031
- at: now,
1032
- };
1033
- return recordoutcome(base, planid, outcome, now);
1034
- }
1035
-
1036
- /** Returns every recorded session memory evidence of one step, oldest first. */
1037
- export function sessionevidences(
1038
- progress: planprogress | undefined,
1039
- planid: string,
1040
- stepid: string,
1041
- ): sessionevidence[] {
1042
- if (!progress || progress.planid !== planid) return [];
1043
- return (progress.outcomes ?? [])
1044
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.session !== undefined)
1045
- .map((outcome) => outcome.details?.session as sessionevidence);
1046
- }
1047
-
1048
- /** One workflow evidence entry of the plan progress outcome log: the family, the reviewed detail, the run id, the executed and refused step counts over the total, and the loop iterations over the user defined denominator of control flow steps. */
1049
- export interface workflowevidence {
1050
- family:
1051
- | "compose"
1052
- | "template"
1053
- | "run"
1054
- | "dryrun"
1055
- | "delay"
1056
- | "wait"
1057
- | "compute"
1058
- | "extract"
1059
- | "pause"
1060
- | "resume"
1061
- | "cancel"
1062
- | "checkpoint"
1063
- | "control";
1064
- detail: string;
1065
- runid?: string;
1066
- executed?: number;
1067
- total?: number;
1068
- refused?: number;
1069
- iterations?: number;
1070
- denominator?: number;
1071
- }
1072
-
1073
- /** Records one workflow evidence in the plan progress outcome log with the family, the reviewed detail, the executed, refused and total step counts and the loop iterations over the user defined denominator. */
1074
- export function recordworkflow(
1075
- progress: planprogress | undefined,
1076
- planid: string,
1077
- stepid: string,
1078
- entry: workflowevidence,
1079
- now: number,
1080
- ): planprogress {
1081
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
1082
- const counts =
1083
- `${entry.executed !== undefined ? `${entry.executed} executed step${entry.executed === 1 ? "" : "s"}, ` : ""}${entry.refused !== undefined ? `${entry.refused} refused step${entry.refused === 1 ? "" : "s"}, ` : ""}${entry.total !== undefined ? `${entry.total} total step${entry.total === 1 ? "" : "s"}, ` : ""}${entry.iterations !== undefined ? `${entry.iterations} iteration${entry.iterations === 1 ? "" : "s"}, ` : ""}${entry.denominator !== undefined ? `denominator ${entry.denominator}, ` : ""}`.replace(
1084
- /, $/,
1085
- "",
1086
- );
1087
- const outcome: stepoutcome = {
1088
- stepid,
1089
- ok: true,
1090
- summary: `${entry.detail}${counts.length > 0 ? ` with ${counts}` : ""}.`,
1091
- details: { workflow: entry },
1092
- at: now,
1093
- };
1094
- return recordoutcome(base, planid, outcome, now);
1095
- }
1096
-
1097
- /** Returns every recorded workflow evidence of one step, oldest first. */
1098
- export function workflowevidences(
1099
- progress: planprogress | undefined,
1100
- planid: string,
1101
- stepid: string,
1102
- ): workflowevidence[] {
1103
- if (!progress || progress.planid !== planid) return [];
1104
- return (progress.outcomes ?? [])
1105
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.workflow !== undefined)
1106
- .map((outcome) => outcome.details?.workflow as workflowevidence);
1107
- }
1108
-
1109
- /** Tracks workflow completion as executed steps over total steps; an empty workflow completes nothing. */
1110
- export function workflowshare(executed: number, total: number): number {
1111
- if (total <= 0) return 0;
1112
- return Math.min(1, Math.max(0, executed / total));
1113
- }
1114
-
1115
- /** Tracks loop completion as executed iterations over the user defined denominator; a zero denominator completes nothing and no code ceiling applies to the denominator. */
1116
- export function loopshare(iterations: number, denominator: number): number {
1117
- if (denominator <= 0) return 0;
1118
- return Math.min(1, Math.max(0, iterations / denominator));
1119
- }
1120
-
1121
- /** One trigger evidence entry of the plan progress outcome log: the family, the reviewed detail, the rule id, the fire, launch and suppression counts, the queued fire count and the next scheduled fire time. */
1122
- export interface triggerevidence {
1123
- family: "arm" | "fire" | "suppress" | "queue" | "drain" | "toggle" | "manual";
1124
- detail: string;
1125
- ruleid?: string;
1126
- fires?: number;
1127
- launches?: number;
1128
- suppressions?: number;
1129
- queued?: number;
1130
- nextfireat?: number;
1131
- }
1132
-
1133
- /** Records one trigger evidence in the plan progress outcome log with the family, the reviewed detail, the rule counters, the queued fire count and the next scheduled fire time. */
1134
- export function recordtrigger(
1135
- progress: planprogress | undefined,
1136
- planid: string,
1137
- stepid: string,
1138
- entry: triggerevidence,
1139
- now: number,
1140
- ): planprogress {
1141
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
1142
- const counts =
1143
- `${entry.fires !== undefined ? `${entry.fires} fire${entry.fires === 1 ? "" : "s"}, ` : ""}${entry.launches !== undefined ? `${entry.launches} launch${entry.launches === 1 ? "" : "es"}, ` : ""}${entry.suppressions !== undefined ? `${entry.suppressions} suppression${entry.suppressions === 1 ? "" : "s"}, ` : ""}${entry.queued !== undefined ? `${entry.queued} queued fire${entry.queued === 1 ? "" : "s"}, ` : ""}`.replace(
1144
- /, $/,
1145
- "",
1146
- );
1147
- const outcome: stepoutcome = {
1148
- stepid,
1149
- ok: true,
1150
- summary: `${entry.detail}${counts.length > 0 ? ` with ${counts}` : ""}.`,
1151
- details: { trigger: entry },
1152
- at: now,
1153
- };
1154
- return recordoutcome(base, planid, outcome, now);
1155
- }
1156
-
1157
- /** Returns every recorded trigger evidence of one step, oldest first. */
1158
- export function triggerevidences(
1159
- progress: planprogress | undefined,
1160
- planid: string,
1161
- stepid: string,
1162
- ): triggerevidence[] {
1163
- if (!progress || progress.planid !== planid) return [];
1164
- return (progress.outcomes ?? [])
1165
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.trigger !== undefined)
1166
- .map((outcome) => outcome.details?.trigger as triggerevidence);
1167
- }
1168
-
1169
- /** One agent protocol tool call evidence entry of the plan progress outcome log: the client that called, the namespaced tool, the outcome flag and the refusal code when the consent gates refused. */
1170
- export interface toolevidence {
1171
- clientid: string;
1172
- tool: string;
1173
- ok: boolean;
1174
- code?: string;
1175
- }
1176
-
1177
- /** Records one agent protocol tool call evidence in the plan progress outcome log with the calling client, the namespaced tool and the outcome. */
1178
- export function recordtoolcall(
1179
- progress: planprogress | undefined,
1180
- planid: string,
1181
- stepid: string,
1182
- entry: toolevidence,
1183
- now: number,
1184
- ): planprogress {
1185
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
1186
- const outcome: stepoutcome = {
1187
- stepid,
1188
- ok: entry.ok,
1189
- summary: `The ${entry.tool} tool call of the client ${entry.clientid} ${entry.ok ? "ran behind the consent gates" : `was refused${entry.code !== undefined ? ` with the ${entry.code} error` : ""}`}.`,
1190
- details: { tool: entry },
1191
- at: now,
1192
- };
1193
- return recordoutcome(base, planid, outcome, now);
1194
- }
1195
-
1196
- /** Returns every recorded agent protocol tool call evidence of one step, oldest first. */
1197
- export function toolcallevidences(progress: planprogress | undefined, planid: string, stepid: string): toolevidence[] {
1198
- if (!progress || progress.planid !== planid) return [];
1199
- return (progress.outcomes ?? [])
1200
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.tool !== undefined)
1201
- .map((outcome) => outcome.details?.tool as toolevidence);
1202
- }
1203
-
1204
- /** One denied step evidence of the plan progress outcome log: the origin, the action kind and the deny reason in plain language, recorded without navigation. */
1205
- export interface deniedstepevidence {
1206
- origin: string;
1207
- kind: string;
1208
- reason: string;
1209
- }
1210
-
1211
- /** Records one denied step in the plan progress outcome log: the origin, the kind and the deny reason stay as evidence while no navigation or dispatch happened. */
1212
- export function recorddenied(
1213
- progress: planprogress | undefined,
1214
- planid: string,
1215
- stepid: string,
1216
- entry: deniedstepevidence,
1217
- now: number,
1218
- ): planprogress {
1219
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
1220
- const outcome: stepoutcome = {
1221
- stepid,
1222
- ok: false,
1223
- summary: `The ${entry.kind} step on ${entry.origin} was denied: ${entry.reason}`,
1224
- details: { denied: entry },
1225
- at: now,
1226
- };
1227
- return recordoutcome(base, planid, outcome, now);
1228
- }
1229
-
1230
- /** Returns every recorded denied step evidence of one step, oldest first. */
1231
- export function deniedevidences(
1232
- progress: planprogress | undefined,
1233
- planid: string,
1234
- stepid: string,
1235
- ): deniedstepevidence[] {
1236
- if (!progress || progress.planid !== planid) return [];
1237
- return (progress.outcomes ?? [])
1238
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.denied !== undefined)
1239
- .map((outcome) => outcome.details?.denied as deniedstepevidence);
1240
- }
1241
-
1242
- /** One revocation evidence of the plan progress outcome log: the halted steps, the revoked step the run stopped at and the reason. */
1243
- export interface revokedrunevidence {
1244
- haltedstepids: string[];
1245
- revokedstepid?: string;
1246
- reason: string;
1247
- }
1248
-
1249
- /** Records one revoked run in the plan progress outcome log: the run halts at the revoked step with the halted queue named as evidence. */
1250
- export function recordrevocation(
1251
- progress: planprogress | undefined,
1252
- planid: string,
1253
- stepid: string,
1254
- entry: revokedrunevidence,
1255
- now: number,
1256
- ): planprogress {
1257
- const base = progress && progress.planid === planid ? progress : emptyprogress(planid, now);
1258
- const outcome: stepoutcome = {
1259
- stepid,
1260
- ok: false,
1261
- summary: `The run halted at the step ${stepid}${entry.haltedstepids.length > 1 ? ` with ${entry.haltedstepids.length - 1} queued step${entry.haltedstepids.length === 2 ? "" : "s"} rolled back` : ""}: ${entry.reason}`,
1262
- details: { revoked: entry },
1263
- at: now,
1264
- };
1265
- return recordoutcome(base, planid, outcome, now);
1266
- }
1267
-
1268
- /** Returns every recorded revocation evidence of one step, oldest first. */
1269
- export function revocationevidences(
1270
- progress: planprogress | undefined,
1271
- planid: string,
1272
- stepid: string,
1273
- ): revokedrunevidence[] {
1274
- if (!progress || progress.planid !== planid) return [];
1275
- return (progress.outcomes ?? [])
1276
- .filter((outcome) => outcome.stepid === stepid && outcome.details?.revoked !== undefined)
1277
- .map((outcome) => outcome.details?.revoked as revokedrunevidence);
1278
- }
1279
-
1280
- /* ── The progress replay path of the 2.0.0 release candidate provenance family: the runreplay walks sealed verified chains while the progress replay derives the ordered step stamps of a recorded run, and every replay record carries the release candidate provenance stamp so the audit trail answers which release produced each entry. ── */
1281
-
1282
- /** One progress replay entry: the ordered step stamp the replay walks with its outcome flag, its summary, its time and its release candidate provenance stamp. */
1283
- export interface progressreplayentry {
1284
- index: number;
1285
- stepid: string;
1286
- ok: boolean;
1287
- summary: string;
1288
- at: number;
1289
- /** The release candidate provenance stamp of the outcome this entry replays, so a replayed view answers which release produced the entry. */
1290
- provenance?: { release: string; protocolmajor: number };
1291
- }
1292
-
1293
- /** Replays the progress record of one plan for the runreplay family: one ordered replay entry per recorded outcome, read only — a progress replay never re-executes anything, it walks the recorded step stamps with their provenance beside the record level stamp of the run. */
1294
- export function replayprogress(
1295
- progress: planprogress | undefined,
1296
- planid: string,
1297
- ): { planid: string; entries: progressreplayentry[]; provenance?: { release: string; protocolmajor: number } } {
1298
- if (!progress || progress.planid !== planid) return { planid, entries: [] };
1299
- const entries = (progress.outcomes ?? []).map((outcome, index) => ({
1300
- index,
1301
- stepid: outcome.stepid,
1302
- ok: outcome.ok,
1303
- summary: outcome.summary,
1304
- at: outcome.at,
1305
- ...(outcome.provenance !== undefined ? { provenance: outcome.provenance } : {}),
1306
- }));
1307
- return { planid, entries, ...(progress.provenance !== undefined ? { provenance: progress.provenance } : {}) };
1308
- }