@coreplane/switchboard 1.235.0 → 1.236.0

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 (132) hide show
  1. package/dist/assets/Dockerfile +11 -0
  2. package/dist/assets/config/config.example.yaml +9 -4
  3. package/dist/assets/deploy/cloudflare-memory/worker.ts +12 -0
  4. package/dist/assets/deploy/cloudflare-resident/Dockerfile +18 -0
  5. package/dist/assets/deploy/cloudflare-resident/worker.ts +115 -56
  6. package/dist/assets/deploy/cloudflare-sandbox/Dockerfile +11 -0
  7. package/dist/assets/deploy/cloudflare-sandbox/worker.ts +68 -7
  8. package/dist/assets/package-lock.json +212 -3
  9. package/dist/assets/package.json +4 -1
  10. package/dist/assets/source.json +3 -3
  11. package/dist/assets/src/core/coordinator/contract.ts +24 -4
  12. package/dist/assets/src/core/coordinator/driver.ts +31 -3
  13. package/dist/assets/src/core/runEvents.ts +36 -1
  14. package/dist/assets/src/core/runFriction.ts +1 -0
  15. package/dist/assets/src/core/ship/contract.ts +3 -1
  16. package/dist/assets/src/core/ship/coordinator.ts +213 -29
  17. package/dist/assets/src/core/trace/types.ts +5 -0
  18. package/dist/assets/src/execution/residentDisk.ts +21 -10
  19. package/dist/assets/src/execution/sandboxErrors.ts +72 -0
  20. package/dist/assets/src/execution/sandboxStart.ts +90 -0
  21. package/dist/assets/web/dist/.vite/manifest.json +437 -423
  22. package/dist/assets/web/dist/assets/{AppShell-lYVcj-k7.js → AppShell-DZdz_sl7.js} +1 -1
  23. package/dist/assets/web/dist/assets/{CostsPage-D-v8am88.js → CostsPage-BfJsol9y.js} +1 -1
  24. package/dist/assets/web/dist/assets/{DeliveryPage-CvlWP7Eq.js → DeliveryPage-CvInfu7y.js} +1 -1
  25. package/dist/assets/web/dist/assets/{NotFoundPage-BzWS4Ca1.js → NotFoundPage-d37EP8hS.js} +1 -1
  26. package/dist/assets/web/dist/assets/ResidentDetailPage-DQSD0SZD.js +1 -0
  27. package/dist/assets/web/dist/assets/ResidentsIndexPage-CZUGLen6.js +1 -0
  28. package/dist/assets/web/dist/assets/RunFoldRow-Bngn4GjF.js +9 -0
  29. package/dist/assets/web/dist/assets/{RunRoutePage-oN9GkVEA.js → RunRoutePage-a-tMrirB.js} +3 -3
  30. package/dist/assets/web/dist/assets/RunsIndexPage-s0VKmRda.js +1 -0
  31. package/dist/assets/web/dist/assets/{RunsTabs-DEICQ4FY.js → RunsTabs-CyCdOhJ2.js} +1 -1
  32. package/dist/assets/web/dist/assets/ScheduledPage-ByCmyrDs.js +1 -0
  33. package/dist/assets/web/dist/assets/SettingsPage-DhKEokGK.js +1 -0
  34. package/dist/assets/web/dist/assets/{StatusDot-D14iJMy7.js → StatusDot-D-BPSPpw.js} +1 -1
  35. package/dist/assets/web/dist/assets/{Tooltip-B0Ob5MQ4.js → Tooltip-DPDx5tXT.js} +1 -1
  36. package/dist/assets/web/dist/assets/UnitRoutePage-0eiekTHQ.js +1 -0
  37. package/dist/assets/web/dist/assets/{angular-html-Cw130Zyi.js → angular-html-Ni1Xil2G.js} +1 -1
  38. package/dist/assets/web/dist/assets/{angular-ts-DY1m4C2s.js → angular-ts-oCgo6p05.js} +1 -1
  39. package/dist/assets/web/dist/assets/{apl-W6Ty7v05.js → apl-CiWYl0gh.js} +1 -1
  40. package/dist/assets/web/dist/assets/{astro-DlLVHwVk.js → astro-B-VeKZ_J.js} +1 -1
  41. package/dist/assets/web/dist/assets/{blade-Bco3tDh4.js → blade-BIWEISKd.js} +1 -1
  42. package/dist/assets/web/dist/assets/{c-1LaFY_cj.js → c-DHxA5Byp.js} +1 -1
  43. package/dist/assets/web/dist/assets/{chapel-B-OvrOL5.js → chapel-D4qGLw-Q.js} +1 -1
  44. package/dist/assets/web/dist/assets/{cobol-Ch3EPlHu.js → cobol-BznX5Q-u.js} +1 -1
  45. package/dist/assets/web/dist/assets/{coffee-hZuITnto.js → coffee-CVr8Idlj.js} +1 -1
  46. package/dist/assets/web/dist/assets/{cpp-B8iRVo8m.js → cpp-wrk6NfW4.js} +1 -1
  47. package/dist/assets/web/dist/assets/{crystal-DKveI7lr.js → crystal-CGYWMeH1.js} +1 -1
  48. package/dist/assets/web/dist/assets/{css-_2_CD-rr.js → css-BgGytMsy.js} +1 -1
  49. package/dist/assets/web/dist/assets/{dist-pOdUzj6D.js → dist-DSkVB16z.js} +2 -2
  50. package/dist/assets/web/dist/assets/durationTone-DYogEPEk.js +1 -0
  51. package/dist/assets/web/dist/assets/{edge-BenMDPct.js → edge-CdR6AU9v.js} +1 -1
  52. package/dist/assets/web/dist/assets/{elixir-CBbdEqG6.js → elixir-CQRb3PZx.js} +1 -1
  53. package/dist/assets/web/dist/assets/{elm-DMub_2lY.js → elm-CpuA6W8B.js} +1 -1
  54. package/dist/assets/web/dist/assets/{erb-CI9He_Up.js → erb-CvlrblqH.js} +1 -1
  55. package/dist/assets/web/dist/assets/{favicon-BQsePYv5.js → favicon-CSt-qDvc.js} +1 -1
  56. package/dist/assets/web/dist/assets/{git-rebase-BBfhnyF8.js → git-rebase-COnovCVc.js} +1 -1
  57. package/dist/assets/web/dist/assets/{glimmer-js-CR9Fxrau.js → glimmer-js-C-DS4g_J.js} +1 -1
  58. package/dist/assets/web/dist/assets/{glimmer-ts-CwFwX_XS.js → glimmer-ts-DTkorWRI.js} +1 -1
  59. package/dist/assets/web/dist/assets/{glsl-Daiodp1r.js → glsl-CH51-JW7.js} +1 -1
  60. package/dist/assets/web/dist/assets/{graphql-DZvrsEkB.js → graphql-BO-XymNv.js} +1 -1
  61. package/dist/assets/web/dist/assets/{hack-BaXOzdg7.js → hack-C-N0oicf.js} +1 -1
  62. package/dist/assets/web/dist/assets/{haml-CMskq_VA.js → haml-BfmdtWoP.js} +1 -1
  63. package/dist/assets/web/dist/assets/{handlebars-Dhw_f7jD.js → handlebars-BqhO_te-.js} +1 -1
  64. package/dist/assets/web/dist/assets/{html-C9k99z0z.js → html-DUEZlTKV.js} +1 -1
  65. package/dist/assets/web/dist/assets/{html-derivative-VckPItXN.js → html-derivative-DOUJTS8A.js} +1 -1
  66. package/dist/assets/web/dist/assets/{http-DXU_3h9v.js → http-j7UH0Cqv.js} +1 -1
  67. package/dist/assets/web/dist/assets/{hurl-KU24JNdp.js → hurl-D6ZaBLJk.js} +1 -1
  68. package/dist/assets/web/dist/assets/indexRow-BjXBzI5Z.js +1 -0
  69. package/dist/assets/web/dist/assets/{java-BbZjTNgf.js → java-dugWx3wi.js} +1 -1
  70. package/dist/assets/web/dist/assets/{javascript-DXCdqcZZ.js → javascript-CK4GC4JO.js} +1 -1
  71. package/dist/assets/web/dist/assets/{jinja-pDlsjTVp.js → jinja-DrLKIyKG.js} +1 -1
  72. package/dist/assets/web/dist/assets/{jison-DsXDk66e.js → jison-CS1Th-TO.js} +1 -1
  73. package/dist/assets/web/dist/assets/{json-tCxXfRgG.js → json-CkBqdVys.js} +1 -1
  74. package/dist/assets/web/dist/assets/{jsx-B0ZYkCmi.js → jsx-CCxdg7n3.js} +1 -1
  75. package/dist/assets/web/dist/assets/{julia-BLzzeI6x.js → julia-BalKW2hA.js} +1 -1
  76. package/dist/assets/web/dist/assets/{just-DvD2_60c.js → just-BKw1G40D.js} +1 -1
  77. package/dist/assets/web/dist/assets/{latex-511zn3h7.js → latex-Dfad6ZN-.js} +1 -1
  78. package/dist/assets/web/dist/assets/{liquid-BD0BkMox.js → liquid-f_CMGBvd.js} +1 -1
  79. package/dist/assets/web/dist/assets/{indexFormat-B-pd4r7Y.js → localIso-CNA-bhS-.js} +1 -1
  80. package/dist/assets/web/dist/assets/{lua-NFicKm6N.js → lua-BcMK_uKM.js} +1 -1
  81. package/dist/assets/web/dist/assets/main-B77vAZVg.css +1 -0
  82. package/dist/assets/web/dist/assets/main-DR8iKpNt.js +28 -0
  83. package/dist/assets/web/dist/assets/{marko-1-G_nEXK.js → marko-B0oNLx2i.js} +1 -1
  84. package/dist/assets/web/dist/assets/{mdc-DUe3AQLp.js → mdc-Bc_MmIyq.js} +1 -1
  85. package/dist/assets/web/dist/assets/{nginx-Dg379_bA.js → nginx-Cmxv8RIt.js} +1 -1
  86. package/dist/assets/web/dist/assets/{nim-BnFq97ZO.js → nim-BtgRfaY0.js} +1 -1
  87. package/dist/assets/web/dist/assets/{org-F0uiwGvq.js → org-Dl9EzlHh.js} +1 -1
  88. package/dist/assets/web/dist/assets/{perl-B0euczkl.js → perl-BmF7x7BB.js} +1 -1
  89. package/dist/assets/web/dist/assets/{php-DkL3k_n7.js → php-rH6CVptQ.js} +1 -1
  90. package/dist/assets/web/dist/assets/{pug-L_OjjZP4.js → pug-CIN5Ccck.js} +1 -1
  91. package/dist/assets/web/dist/assets/{qml-BMjB00Zz.js → qml-BpLS3RFr.js} +1 -1
  92. package/dist/assets/web/dist/assets/{r-DoeLdnqR.js → r-BUMF3B-H.js} +1 -1
  93. package/dist/assets/web/dist/assets/{razor-BzYNkAWy.js → razor-B7sTBPdT.js} +1 -1
  94. package/dist/assets/web/dist/assets/{regexp-CPmElMk3.js → regexp-h2SvwrsJ.js} +1 -1
  95. package/dist/assets/web/dist/assets/residentsModel-VSJEepL1.js +1 -0
  96. package/dist/assets/web/dist/assets/{rst-DrsjgfI7.js → rst-DLOWEsD2.js} +1 -1
  97. package/dist/assets/web/dist/assets/{ruby-cB42ppvx.js → ruby-Cl_-I4k3.js} +1 -1
  98. package/dist/assets/web/dist/assets/{sas-R5Y3NM_I.js → sas-Cm4M-BvV.js} +1 -1
  99. package/dist/assets/web/dist/assets/{scss-C-zWxV9s.js → scss-CEFCEQUF.js} +1 -1
  100. package/dist/assets/web/dist/assets/{shellscript-oJF96aAU.js → shellscript-CE6zb5eS.js} +1 -1
  101. package/dist/assets/web/dist/assets/{shellsession-CznECKyi.js → shellsession-B4fDVzrM.js} +1 -1
  102. package/dist/assets/web/dist/assets/{soy-wjHLSRag.js → soy-DwXCMpjE.js} +1 -1
  103. package/dist/assets/web/dist/assets/{sql-C_BM8IOW.js → sql-DrnAKnyD.js} +1 -1
  104. package/dist/assets/web/dist/assets/{stata-D31HO8aQ.js → stata-BzlwPWD6.js} +1 -1
  105. package/dist/assets/web/dist/assets/{surrealql-CKCLyplA.js → surrealql-CeUieZXd.js} +1 -1
  106. package/dist/assets/web/dist/assets/{svelte-3geWk2iu.js → svelte-BERIpIKR.js} +1 -1
  107. package/dist/assets/web/dist/assets/{templ-DiJr_hTD.js → templ-6FSuUDwg.js} +1 -1
  108. package/dist/assets/web/dist/assets/{tex-BEJGWyeF.js → tex-SWCyMwNX.js} +1 -1
  109. package/dist/assets/web/dist/assets/{ts-tags-C8Mzdpxx.js → ts-tags-VWj7gWgY.js} +1 -1
  110. package/dist/assets/web/dist/assets/{tsx-UQiSm_p3.js → tsx-B6dzfL8L.js} +1 -1
  111. package/dist/assets/web/dist/assets/{twig-_Pvzkeo9.js → twig-BDXsr482.js} +1 -1
  112. package/dist/assets/web/dist/assets/{typescript-BWMkINKK.js → typescript-s100Dt8y.js} +1 -1
  113. package/dist/assets/web/dist/assets/{typst-Bdg9m-e7.js → typst-WfyEAUdt.js} +1 -1
  114. package/dist/assets/web/dist/assets/{vue-CDZrrAZ8.js → vue-CkXOOJ-6.js} +1 -1
  115. package/dist/assets/web/dist/assets/{vue-html-tAlpNhfN.js → vue-html-CEpzdcau.js} +1 -1
  116. package/dist/assets/web/dist/assets/{vue-vine-C27UF_rh.js → vue-vine-D9dsfiFA.js} +1 -1
  117. package/dist/assets/web/dist/assets/{xml-CxeDr9Zh.js → xml-iBDofbJq.js} +1 -1
  118. package/dist/assets/web/dist/assets/{xsl-Bpi0uUnM.js → xsl-CqbJF4hD.js} +1 -1
  119. package/dist/assets/web/dist/assets/{yaml-BtUgZ1GN.js → yaml-D9i6OxYe.js} +1 -1
  120. package/dist/cli.js +2255 -1170
  121. package/package.json +1 -1
  122. package/dist/assets/web/dist/assets/ResidentDetailPage-DSpsye5e.js +0 -1
  123. package/dist/assets/web/dist/assets/ResidentsIndexPage-CT8fI1M3.js +0 -1
  124. package/dist/assets/web/dist/assets/RunFoldRow-Cqh8pTXC.js +0 -9
  125. package/dist/assets/web/dist/assets/RunsIndexPage-sjXr8iCV.js +0 -1
  126. package/dist/assets/web/dist/assets/ScheduledPage-Tz__zLzi.js +0 -1
  127. package/dist/assets/web/dist/assets/UnitRoutePage-CbKCL58v.js +0 -1
  128. package/dist/assets/web/dist/assets/indexRow-Bnj883ii.js +0 -1
  129. package/dist/assets/web/dist/assets/localIso-L06jV29p.js +0 -1
  130. package/dist/assets/web/dist/assets/main-D3lG-yQ9.js +0 -28
  131. package/dist/assets/web/dist/assets/main-Dm11o0hc.css +0 -1
  132. package/dist/assets/web/dist/assets/residentDiskBudget-BMBKlYRH.js +0 -1
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "switchboard",
3
- "version": "1.235.0",
3
+ "version": "1.236.0",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "switchboard",
9
- "version": "1.235.0",
9
+ "version": "1.236.0",
10
10
  "license": "Apache-2.0",
11
11
  "workspaces": [
12
12
  "web",
@@ -34,7 +34,10 @@
34
34
  "devDependencies": {
35
35
  "@earendil-works/pi-coding-agent": "0.85.1",
36
36
  "@eslint/js": "^10.0.1",
37
+ "@opencode/protocol": "2.0.3",
38
+ "@opencode/schema": "2.0.3",
37
39
  "@types/node": "^24.0.0",
40
+ "effect": "4.0.0-rc.112",
38
41
  "eslint": "^10.10.0",
39
42
  "eslint-config-prettier": "^10.1.8",
40
43
  "eslint-plugin-vue": "^10.11.0",
@@ -5863,6 +5866,90 @@
5863
5866
  "@chevrotain/types": "~11.1.2"
5864
5867
  }
5865
5868
  },
5869
+ "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": {
5870
+ "version": "3.0.4",
5871
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.4.tgz",
5872
+ "integrity": "sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ==",
5873
+ "cpu": [
5874
+ "arm64"
5875
+ ],
5876
+ "dev": true,
5877
+ "license": "MIT",
5878
+ "optional": true,
5879
+ "os": [
5880
+ "darwin"
5881
+ ]
5882
+ },
5883
+ "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": {
5884
+ "version": "3.0.4",
5885
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.4.tgz",
5886
+ "integrity": "sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w==",
5887
+ "cpu": [
5888
+ "x64"
5889
+ ],
5890
+ "dev": true,
5891
+ "license": "MIT",
5892
+ "optional": true,
5893
+ "os": [
5894
+ "darwin"
5895
+ ]
5896
+ },
5897
+ "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": {
5898
+ "version": "3.0.4",
5899
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.4.tgz",
5900
+ "integrity": "sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw==",
5901
+ "cpu": [
5902
+ "arm"
5903
+ ],
5904
+ "dev": true,
5905
+ "license": "MIT",
5906
+ "optional": true,
5907
+ "os": [
5908
+ "linux"
5909
+ ]
5910
+ },
5911
+ "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": {
5912
+ "version": "3.0.4",
5913
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.4.tgz",
5914
+ "integrity": "sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw==",
5915
+ "cpu": [
5916
+ "arm64"
5917
+ ],
5918
+ "dev": true,
5919
+ "license": "MIT",
5920
+ "optional": true,
5921
+ "os": [
5922
+ "linux"
5923
+ ]
5924
+ },
5925
+ "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": {
5926
+ "version": "3.0.4",
5927
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.4.tgz",
5928
+ "integrity": "sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ==",
5929
+ "cpu": [
5930
+ "x64"
5931
+ ],
5932
+ "dev": true,
5933
+ "license": "MIT",
5934
+ "optional": true,
5935
+ "os": [
5936
+ "linux"
5937
+ ]
5938
+ },
5939
+ "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": {
5940
+ "version": "3.0.4",
5941
+ "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.4.tgz",
5942
+ "integrity": "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ==",
5943
+ "cpu": [
5944
+ "x64"
5945
+ ],
5946
+ "dev": true,
5947
+ "license": "MIT",
5948
+ "optional": true,
5949
+ "os": [
5950
+ "win32"
5951
+ ]
5952
+ },
5866
5953
  "node_modules/@napi-rs/lzma-linux-x64-gnu": {
5867
5954
  "version": "1.5.1",
5868
5955
  "resolved": "https://registry.npmjs.org/@napi-rs/lzma-linux-x64-gnu/-/lzma-linux-x64-gnu-1.5.1.tgz",
@@ -6155,6 +6242,28 @@
6155
6242
  "dev": true,
6156
6243
  "license": "MIT"
6157
6244
  },
6245
+ "node_modules/@opencode/protocol": {
6246
+ "version": "2.0.3",
6247
+ "resolved": "https://registry.npmjs.org/@opencode/protocol/-/protocol-2.0.3.tgz",
6248
+ "integrity": "sha512-DNHbkLDTuAyMsmVdnjuKulcfoDbllW2dxt4W19r2aJEYvswJpEO9168CSK6Sjbx1FOh/B9yL7SQgoDRMd4K5Vw==",
6249
+ "dev": true,
6250
+ "license": "MIT",
6251
+ "dependencies": {
6252
+ "@opencode/schema": "2.0.3",
6253
+ "effect": "4.0.0-rc.112"
6254
+ }
6255
+ },
6256
+ "node_modules/@opencode/schema": {
6257
+ "version": "2.0.3",
6258
+ "resolved": "https://registry.npmjs.org/@opencode/schema/-/schema-2.0.3.tgz",
6259
+ "integrity": "sha512-thPeBbqw4+SkZ/0LOuqfahSRGuWogRa/wwfIVyiQYsoE0vzLx8XUpHQ+FSUWkdz6llDtP0+ZsyBqXUMpXmPgbg==",
6260
+ "dev": true,
6261
+ "license": "MIT",
6262
+ "dependencies": {
6263
+ "@standard-schema/spec": "1.1.0",
6264
+ "effect": "4.0.0-rc.112"
6265
+ }
6266
+ },
6158
6267
  "node_modules/@oxc-project/types": {
6159
6268
  "version": "0.148.0",
6160
6269
  "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.148.0.tgz",
@@ -11840,6 +11949,17 @@
11840
11949
  "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
11841
11950
  "license": "MIT"
11842
11951
  },
11952
+ "node_modules/effect": {
11953
+ "version": "4.0.0-rc.112",
11954
+ "resolved": "https://registry.npmjs.org/effect/-/effect-4.0.0-rc.112.tgz",
11955
+ "integrity": "sha512-wXxwuh1Ywnv4cPRM3Wfa0vDwuOHnZ1TsTgHJkG9XgzND6inhBH9n1vBxhg3iIXOia/OrpmvVmd3lrD4vq6bF3A==",
11956
+ "dev": true,
11957
+ "license": "MIT",
11958
+ "dependencies": {
11959
+ "fast-check": "^4.9.0",
11960
+ "msgpackr": "^2.0.5"
11961
+ }
11962
+ },
11843
11963
  "node_modules/embla-carousel": {
11844
11964
  "version": "8.6.0",
11845
11965
  "resolved": "https://registry.npmjs.org/embla-carousel/-/embla-carousel-8.6.0.tgz",
@@ -12447,6 +12567,29 @@
12447
12567
  "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
12448
12568
  "license": "MIT"
12449
12569
  },
12570
+ "node_modules/fast-check": {
12571
+ "version": "4.10.1",
12572
+ "resolved": "https://registry.npmjs.org/fast-check/-/fast-check-4.10.1.tgz",
12573
+ "integrity": "sha512-sB5Vghiu8MyCyToHoBVGsT0baZg3sZWNIY+a6Ct2EDrQJlT4YdH6MC1BSLNe3kX1k5i5g0q1O52XFgcKK/rGHg==",
12574
+ "dev": true,
12575
+ "funding": [
12576
+ {
12577
+ "type": "individual",
12578
+ "url": "https://github.com/sponsors/dubzzz"
12579
+ },
12580
+ {
12581
+ "type": "opencollective",
12582
+ "url": "https://opencollective.com/fast-check"
12583
+ }
12584
+ ],
12585
+ "license": "MIT",
12586
+ "dependencies": {
12587
+ "pure-rand": "^8.0.0"
12588
+ },
12589
+ "engines": {
12590
+ "node": ">=12.17.0"
12591
+ }
12592
+ },
12450
12593
  "node_modules/fast-deep-equal": {
12451
12594
  "version": "3.1.3",
12452
12595
  "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -15349,6 +15492,39 @@
15349
15492
  "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
15350
15493
  "license": "MIT"
15351
15494
  },
15495
+ "node_modules/msgpackr": {
15496
+ "version": "2.1.0",
15497
+ "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-2.1.0.tgz",
15498
+ "integrity": "sha512-p/pBCVO63CsvvpkomUnNNag6+n38rULuDA6HHe70o2gtC8ODI52foF/4ko2qQcp6OiErJXTmrZeXmsGGHsIQNQ==",
15499
+ "dev": true,
15500
+ "license": "MIT",
15501
+ "optionalDependencies": {
15502
+ "msgpackr-extract": "^3.0.4"
15503
+ }
15504
+ },
15505
+ "node_modules/msgpackr-extract": {
15506
+ "version": "3.0.4",
15507
+ "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.4.tgz",
15508
+ "integrity": "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw==",
15509
+ "dev": true,
15510
+ "hasInstallScript": true,
15511
+ "license": "MIT",
15512
+ "optional": true,
15513
+ "dependencies": {
15514
+ "node-gyp-build-optional-packages": "5.2.2"
15515
+ },
15516
+ "bin": {
15517
+ "download-msgpackr-prebuilds": "bin/download-prebuilds.js"
15518
+ },
15519
+ "optionalDependencies": {
15520
+ "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4",
15521
+ "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4",
15522
+ "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4",
15523
+ "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4",
15524
+ "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4",
15525
+ "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4"
15526
+ }
15527
+ },
15352
15528
  "node_modules/muggle-string": {
15353
15529
  "version": "0.4.1",
15354
15530
  "resolved": "https://registry.npmjs.org/muggle-string/-/muggle-string-0.4.1.tgz",
@@ -15453,6 +15629,22 @@
15453
15629
  "integrity": "sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==",
15454
15630
  "license": "MIT"
15455
15631
  },
15632
+ "node_modules/node-gyp-build-optional-packages": {
15633
+ "version": "5.2.2",
15634
+ "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz",
15635
+ "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==",
15636
+ "dev": true,
15637
+ "license": "MIT",
15638
+ "optional": true,
15639
+ "dependencies": {
15640
+ "detect-libc": "^2.0.1"
15641
+ },
15642
+ "bin": {
15643
+ "node-gyp-build-optional-packages": "bin.js",
15644
+ "node-gyp-build-optional-packages-optional": "optional.js",
15645
+ "node-gyp-build-optional-packages-test": "build-test.js"
15646
+ }
15647
+ },
15456
15648
  "node_modules/node-mock-http": {
15457
15649
  "version": "1.0.5",
15458
15650
  "resolved": "https://registry.npmjs.org/node-mock-http/-/node-mock-http-1.0.5.tgz",
@@ -16269,6 +16461,23 @@
16269
16461
  "node": ">=6"
16270
16462
  }
16271
16463
  },
16464
+ "node_modules/pure-rand": {
16465
+ "version": "8.4.2",
16466
+ "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-8.4.2.tgz",
16467
+ "integrity": "sha512-vvuOGgcuPJAirlHvuQw1TrOiw7ptaIXXmIbNuiNOY6lNGJJH49PQ1Kj4nd783nPdQhQdicgOjVI2yI/9BD6/Ng==",
16468
+ "dev": true,
16469
+ "funding": [
16470
+ {
16471
+ "type": "individual",
16472
+ "url": "https://github.com/sponsors/dubzzz"
16473
+ },
16474
+ {
16475
+ "type": "opencollective",
16476
+ "url": "https://opencollective.com/fast-check"
16477
+ }
16478
+ ],
16479
+ "license": "MIT"
16480
+ },
16272
16481
  "node_modules/qified": {
16273
16482
  "version": "0.10.1",
16274
16483
  "resolved": "https://registry.npmjs.org/qified/-/qified-0.10.1.tgz",
@@ -20032,7 +20241,7 @@
20032
20241
  },
20033
20242
  "packages/switchboard": {
20034
20243
  "name": "@coreplane/switchboard",
20035
- "version": "1.235.0",
20244
+ "version": "1.236.0",
20036
20245
  "license": "Apache-2.0",
20037
20246
  "dependencies": {
20038
20247
  "@earendil-works/pi-ai": "0.85.1",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "switchboard",
3
- "version": "1.235.0",
3
+ "version": "1.236.0",
4
4
  "private": true,
5
5
  "description": "Mention it in Slack and an agent reviews the PR, ships the fix, or answers the question — on the model you choose, with its tools running where you decide.",
6
6
  "license": "Apache-2.0",
@@ -91,7 +91,10 @@
91
91
  "devDependencies": {
92
92
  "@earendil-works/pi-coding-agent": "0.85.1",
93
93
  "@eslint/js": "^10.0.1",
94
+ "@opencode/protocol": "2.0.3",
95
+ "@opencode/schema": "2.0.3",
94
96
  "@types/node": "^24.0.0",
97
+ "effect": "4.0.0-rc.112",
95
98
  "eslint": "^10.10.0",
96
99
  "eslint-config-prettier": "^10.1.8",
97
100
  "eslint-plugin-vue": "^10.11.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.235.0",
3
- "commit": "091ab2f1f6d89290bde9c84e933d23525f9c8873",
4
- "builtAt": "2026-09-16T17:37:07.278Z"
2
+ "version": "1.236.0",
3
+ "commit": "cf9308dd5f28ac788804260c2978403ce5b59c81",
4
+ "builtAt": "2026-09-16T20:27:06.883Z"
5
5
  }
@@ -55,6 +55,18 @@ export function parseUnitKey(key: string): { instanceId: string; unit: string }
55
55
  return { instanceId: key.slice(0, at), unit: key.slice(at + 1) };
56
56
  }
57
57
 
58
+ /** The unit an idempotency key names — the head of its step
59
+ * (`<instance>:<unit>/<round>/<kind>` for the plan runner), or undefined for
60
+ * a key whose step carries no unit prefix the unit pattern accepts. What the
61
+ * `coordinator_tag` run event stamps as `unit`, so a run's stream names the
62
+ * unit it ran for without parsing the key back. */
63
+ export function unitOfIdempotencyKey(key: string): string | undefined {
64
+ if (!IDEMPOTENCY_KEY_PATTERN.test(key)) return undefined;
65
+ const step = key.slice(key.indexOf(":") + 1);
66
+ const head = step.split("/")[0];
67
+ return UNIT_PATTERN.test(head) ? head : undefined;
68
+ }
69
+
58
70
  /** The event a child's terminal record sends its parent: the type carries the
59
71
  * run id, so each `waitForEvent` matches its own child and a duplicate is
60
72
  * buffered harmlessly. An event type is the platform's alphabet — letters,
@@ -85,10 +97,12 @@ export interface CoordinatorTag {
85
97
  * (`CoordinatorInstance.base`), set by the spawn when the instance knows it.
86
98
  * A coordinator's child is dispatched AT its unit branch so the resident
87
99
  * attaches there, which makes the binding ref the branch itself — no base
88
- * the post-step could resolve from the thread — so the spawn says it. An
89
- * instruction to the run like `DispatchOptions.contract`, not a fact about
90
- * it: the fact the record keeps is the `pr_opened` it leads to, and
91
- * `coordinatorFields` leaves it off the rows. */
100
+ * the post-step could resolve from the thread — so the spawn says it.
101
+ * Published as the run's own `coordinator_tag` event at dispatch
102
+ * (run-history item 48a), so a run re-attached after a bot roll — whose
103
+ * dispatch options are gone with the process that spawned it — reads it
104
+ * back off its ledger events; `coordinatorFields` still leaves it off the
105
+ * rows, so rows and records keep the shape written before it existed. */
92
106
  base?: string;
93
107
  }
94
108
 
@@ -182,6 +196,11 @@ export interface CoordinatorUnit {
182
196
  * — no pre-check, no branch, no round 0. A task string's row only; written by
183
197
  * the hand-off, read by the driver into the machine's input. */
184
198
  resume?: { pr: number; headSha?: string; url?: string };
199
+ /** The head the unit's own coding child last pushed, recorded when the unit
200
+ * ended `review_pending` (the wall clock capped after the pull request was
201
+ * opened or updated): the next attempt's pre-check starts at the review
202
+ * round when the open pull request still heads exactly here. */
203
+ lastPush?: string;
185
204
  /** The round boundaries the coordinator reported, oldest first (the `ship_round` vocabulary). */
186
205
  rounds: Array<{ index: number; agent: string; outcome: string; at: number }>;
187
206
  /** How the unit ended: the ending's kind and the thread's report, when it has. */
@@ -244,6 +263,7 @@ export function isCoordinatorUnit(v: unknown): v is CoordinatorUnit {
244
263
  if (r.issue !== undefined && !isFinite(r.issue)) return false;
245
264
  if (r.pr !== undefined && !isPr(r.pr)) return false;
246
265
  if (r.resume !== undefined && !isResume(r.resume)) return false;
266
+ if (r.lastPush !== undefined && !isText(r.lastPush)) return false;
247
267
  if (
248
268
  !Array.isArray(r.rounds) ||
249
269
  r.rounds.length > MAX_ROUNDS ||
@@ -274,7 +274,18 @@ function readRecordReturn(step: string, a: BotAnswer): StepReturn {
274
274
 
275
275
  function prCheckReturn(step: string, a: BotAnswer): StepReturn {
276
276
  const { ok, state, prNumber, url, headSha, sha, mergedAt, at } = a.body;
277
- if (ok === true && state === "none") return { type: "pr-check", step, pr: { state: "none" }, at };
277
+ if (ok === true && state === "none") {
278
+ const { unrecovered } = a.body;
279
+ return {
280
+ type: "pr-check",
281
+ step,
282
+ pr: {
283
+ state: "none",
284
+ ...(unrecovered === "no_commits" || unrecovered === "no_base" ? { unrecovered } : {}),
285
+ },
286
+ at,
287
+ };
288
+ }
278
289
  if (ok === true && state === "open" && typeof prNumber === "number" && typeof url === "string")
279
290
  return {
280
291
  type: "pr-check",
@@ -389,9 +400,16 @@ async function perform(
389
400
  ),
390
401
  );
391
402
  case "pr-check":
403
+ // `recover` rides only after a dead coding child: the bot opens the pull
404
+ // request from the pushed branch itself instead of answering `none`.
392
405
  return prCheckReturn(
393
406
  action.step,
394
- answerOf("pr-check", await step.do(action.step, STEP_CONFIG, () => call(bot, "pr-check", tag))),
407
+ answerOf(
408
+ "pr-check",
409
+ await step.do(action.step, STEP_CONFIG, () =>
410
+ call(bot, "pr-check", { ...tag, ...(action.recover !== undefined ? { recover: action.recover } : {}) }),
411
+ ),
412
+ ),
395
413
  );
396
414
  case "sleep":
397
415
  await step.sleep(action.step, action.ms);
@@ -426,7 +444,11 @@ async function runUnit(
426
444
  // A resume at review (agent-ship item 10) rides the unit's row: the pull
427
445
  // request of ship's own the requester named opens the pipeline at its first
428
446
  // review round, with no pre-check, no branch and no round 0.
429
- const resume = plan.units.find((u) => u.unit === unit)?.resume;
447
+ const row = plan.units.find((u) => u.unit === unit);
448
+ const resume = row?.resume;
449
+ // A previous attempt's `review_pending` head: the machine's pre-check starts
450
+ // at the review round when the open pull request still heads exactly there.
451
+ const lastPush = row?.lastPush;
430
452
  let state: UnitPipelineState = openUnitPipeline(
431
453
  {
432
454
  unit: { id: unit, branch: node.branch },
@@ -441,6 +463,7 @@ async function runUnit(
441
463
  merge: plan.merge,
442
464
  generated: plan.generated,
443
465
  ...(resume !== undefined ? { resume } : {}),
466
+ ...(lastPush !== undefined ? { lastPush } : {}),
444
467
  },
445
468
  start.at,
446
469
  );
@@ -486,6 +509,11 @@ async function runUnit(
486
509
  ...tag,
487
510
  ending: { kind: note.ending.kind, report: renderUnitReport(state, endFacts) },
488
511
  ...(state.pr !== undefined ? { pr: state.pr } : {}),
512
+ // A review_pending ending names the child's own last push so the next
513
+ // attempt's pre-check can start at the review round (the row's lastPush).
514
+ ...(note.ending.kind === "review_pending" && note.ending.headSha !== undefined
515
+ ? { headSha: note.ending.headSha }
516
+ : {}),
489
517
  ...(state.lastCodingRunId !== undefined ? { codingRunId: state.lastCodingRunId } : {}),
490
518
  };
491
519
  await step.do(`${unit}/end`, STEP_CONFIG, () => call(bot, "unit-end", body));
@@ -356,6 +356,21 @@ export interface SpanEndEvent {
356
356
  at?: number;
357
357
  }
358
358
 
359
+ /** A value a `route` event may carry in a bound command input: JSON, nested
360
+ * at most three objects deep under `options`, and nothing else. The record
361
+ * crosses the run store's RPC boundary, whose typing walks every field: a
362
+ * field of `unknown` types the whole record `never`, and a recursive alias is
363
+ * "excessively deep" to it, so the nesting is spelled out level by level. The
364
+ * model's tool call is JSON to begin with; the registry's option schemas nest
365
+ * one object deep (`models.coding`); a deeper value is stored as its JSON
366
+ * text, still redacted and capped. */
367
+ export type RouteInputLeaf = string | number | boolean | null;
368
+ export type RouteInputLeafOrList = RouteInputLeaf | ReadonlyArray<RouteInputLeaf>;
369
+ export type RouteInputObject1 = { readonly [key: string]: RouteInputLeafOrList };
370
+ export type RouteInputObject2 = { readonly [key: string]: RouteInputLeafOrList | RouteInputObject1 };
371
+ export type RouteInputObject3 = { readonly [key: string]: RouteInputLeafOrList | RouteInputObject2 };
372
+ export type RouteInputValue = RouteInputLeafOrList | RouteInputObject3;
373
+
359
374
  export type RunEvent =
360
375
  /** `callId` is the provider's tool_use id — the explicit pair key between a
361
376
  * call and its result (live-view item 13); the runner stamps it on both. */
@@ -635,6 +650,16 @@ export type RunEvent =
635
650
  seq?: number;
636
651
  at?: number;
637
652
  }
653
+ /** The coordinator tag as a fact of the run (docs/reference/specs/run-history.md
654
+ * item 48a): the instance the run is a child of, the unit its idempotency
655
+ * key named, and the base branch its pull request targets — published by
656
+ * the dispatcher once at dispatch, from `DispatchOptions.coordinator`, so
657
+ * a run re-attached or restarted after a bot roll (whose spawn options are
658
+ * gone with the process) reads the plan's base back off its own events
659
+ * instead of letting the binding ref — the unit branch itself — stand in.
660
+ * `base` is absent when the spawn knew none; the post-step then falls to
661
+ * the coordinator store's `instance.base`. Additive: unknown → ignored. */
662
+ | { type: "coordinator_tag"; parentInstanceId: string; unit?: string; base?: string; seq?: number; at?: number }
638
663
  /** The review post-step's outcome when the verdict landed
639
664
  * (docs/reference/specs/agent-review.md item 18): the pull request it was
640
665
  * posted to, the head it was pinned to (the carried head after a rebase,
@@ -679,7 +704,14 @@ export type RunEvent =
679
704
  * `run_meta.agentSource` stays `default`). Published by the dispatcher
680
705
  * straight to the registry right after `run_meta`, once per run the router
681
706
  * answered; absent on every run a directive, a sticky preset or a scope
682
- * chose. Head material, like `run_meta`. Additive: unknown → ignored. */
707
+ * chose. Head material, like `run_meta`. Additive: unknown → ignored.
708
+ * A command the router bound from prose (record 0036: the door offers every
709
+ * chat command as a tool beside `route`) rides the command run's record
710
+ * instead, right after its `run_meta`: `preset` is the command run's agent
711
+ * (`command`), `command` the id the model called, `input` the bound input
712
+ * (redacted, each value capped) and `receipt` the chat form the reply led
713
+ * with (`routed: <chat form>`, redacted and capped at `ROUTE_RECEIPT_CAP`);
714
+ * how the invoke ended is the run's own status and `answer`. */
683
715
  | {
684
716
  type: "route";
685
717
  preset: string;
@@ -687,6 +719,9 @@ export type RunEvent =
687
719
  model: string;
688
720
  parts?: ReadonlyArray<{ preset: string; text: string }>;
689
721
  collapsed?: { presets: ReadonlyArray<string> };
722
+ command?: string;
723
+ input?: { readonly [key: string]: RouteInputValue };
724
+ receipt?: string;
690
725
  seq?: number;
691
726
  at?: number;
692
727
  }
@@ -421,6 +421,7 @@ export function analyzeRunFriction(events: readonly RunEvent[], opts: FrictionOp
421
421
  ev.type === "review_artifact" ||
422
422
  ev.type === "pr_description" ||
423
423
  ev.type === "pr_opened" ||
424
+ ev.type === "coordinator_tag" ||
424
425
  ev.type === "review_posted" ||
425
426
  ev.type === "ship_round" ||
426
427
  ev.type === "route" ||
@@ -427,7 +427,9 @@ function renderFirstInstruction(rebase: ChildContract["rebase"]): string {
427
427
  const onto = rebase.onto ? `\`${rebase.onto}\`` : "the merged parent";
428
428
  return (
429
429
  `Rebase ${branch} onto ${onto} before any other work — the parent unit has merged and the base has moved; ` +
430
- `the only writes are your own on that branch. A conflict ends the unit: report it as the handoff and stop.`
430
+ `the only writes are your own on that branch. A conflict ends the unit: report it as the handoff and stop. ` +
431
+ `Right before the push, fetch ${onto} again and rebase once more if it moved during verify, ` +
432
+ `so the pull request is not born conflicting.`
431
433
  );
432
434
  }
433
435