@desplega.ai/agent-swarm 2.4.0 → 2.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (239) hide show
  1. package/README.md +1 -1
  2. package/dist/{acp-adapter-kedstxx6.js → acp-adapter-dv7hmx4r.js} +9 -9
  3. package/dist/{actions-vget6r1k.js → actions-51nc1gny.js} +21 -21
  4. package/dist/{amp-adapter-xeb5mktv.js → amp-adapter-abp5tdx8.js} +4 -4
  5. package/dist/{app-mqap8t8m.js → app-9h14qvr6.js} +3 -3
  6. package/dist/{assistant-h0gv97mv.js → assistant-wv1gz3mt.js} +22 -22
  7. package/dist/{boot-reembed-qr8a894z.js → boot-reembed-6yn53ms9.js} +1 -1
  8. package/dist/{boot-reembed-rj85jjhw.js → boot-reembed-7fcka4z5.js} +1 -1
  9. package/dist/{boot-scrub-sweep-eyfvn6v9.js → boot-scrub-sweep-pm1580ax.js} +4 -4
  10. package/dist/{boot-seeds-xs9a8dx1.js → boot-seeds-g5hfc1x8.js} +4 -4
  11. package/dist/{claude-adapter-bm23cye7.js → claude-adapter-gf3kxhf0.js} +9 -9
  12. package/dist/{claude-managed-adapter-1mwrsm9d.js → claude-managed-adapter-h2y889ge.js} +2 -2
  13. package/dist/{claude-managed-setup-gkfgks4j.js → claude-managed-setup-h00hsgtz.js} +2 -2
  14. package/dist/{claude-sdk-session-apb4ypz3.js → claude-sdk-session-s2k1qd8y.js} +13 -13
  15. package/dist/{cli-tj4j2ts4.js → cli-02qm7src.js} +8 -8
  16. package/dist/{cli-1cevz46c.js → cli-0qvtffe9.js} +6 -6
  17. package/dist/{cli-avmqhatn.js → cli-10hhg0km.js} +8 -8
  18. package/dist/{cli-7gh7020n.js → cli-1dmcq2eh.js} +1 -1
  19. package/dist/{cli-kz116kvw.js → cli-239yjk27.js} +7 -7
  20. package/dist/{cli-7ayprxp7.js → cli-2dfbv8qr.js} +8 -0
  21. package/dist/{cli-a49vpbf3.js → cli-5kqnemen.js} +1 -1
  22. package/dist/{cli-x719j3vs.js → cli-5rk36sjf.js} +442 -205
  23. package/dist/{cli-fb6t92v8.js → cli-6x9ma5w5.js} +1 -1
  24. package/dist/{cli-c8fwpgqb.js → cli-7225gwj7.js} +2 -2
  25. package/dist/{cli-5s5hx57y.js → cli-7awf1fp8.js} +1 -1
  26. package/dist/{cli-bn26xbcs.js → cli-8nyhf7za.js} +1 -1
  27. package/dist/{cli-ywyrffff.js → cli-8sxqsbbq.js} +1 -1
  28. package/dist/{cli-rsd7ga7v.js → cli-8zwe9mpk.js} +11 -11
  29. package/dist/{cli-y83zk5sb.js → cli-a0kcty51.js} +4 -4
  30. package/dist/{cli-8b9wvjps.js → cli-a4gvwttf.js} +4 -4
  31. package/dist/{cli-jhp7w1fy.js → cli-a5ebc95n.js} +2 -2
  32. package/dist/{cli-mvg2hf8p.js → cli-ahtpy9kf.js} +14 -7
  33. package/dist/{cli-x1p5dhq2.js → cli-bcj753sq.js} +3 -3
  34. package/dist/{cli-p22zdvnt.js → cli-bn0rewsy.js} +3 -3
  35. package/dist/{cli-p1m2b6gc.js → cli-d2mb5s8a.js} +7 -7
  36. package/dist/{cli-rg7ntypm.js → cli-d3qqdy4c.js} +456 -94
  37. package/dist/{cli-c5sbmw1v.js → cli-d82btycs.js} +94 -15
  38. package/dist/{cli-02vhhssk.js → cli-efaqv1c7.js} +5 -5
  39. package/dist/{cli-vjfpshn3.js → cli-ejs3m1sx.js} +1 -1
  40. package/dist/{cli-kk2r80n5.js → cli-faypxz7q.js} +4 -4
  41. package/dist/{cli-a1esmmee.js → cli-fpmsqq59.js} +7 -2
  42. package/dist/{cli-wrv09v7q.js → cli-ftyypbg5.js} +1 -1
  43. package/dist/{cli-zvze9rbm.js → cli-fyzjmseb.js} +3 -3
  44. package/dist/{cli-8rwvksbc.js → cli-g0hgtz4p.js} +5 -5
  45. package/dist/{cli-nrrg0fvy.js → cli-h38rjv87.js} +133 -12
  46. package/dist/{cli-tg9ksbn8.js → cli-h93c9vb3.js} +2 -2
  47. package/dist/{cli-eqgfs202.js → cli-hqhzg1qq.js} +2 -2
  48. package/dist/{cli-bhwa8rzc.js → cli-hyfw2j1e.js} +13 -12
  49. package/dist/{cli-3wjs22x3.js → cli-j4rqdf2n.js} +2 -2
  50. package/dist/{cli-6ftrrwm1.js → cli-n85dqg6d.js} +5 -5
  51. package/dist/{cli-8cxkw1f5.js → cli-nmqdc2t3.js} +2 -2
  52. package/dist/{cli-4fhyq711.js → cli-nn47d7e8.js} +13 -13
  53. package/dist/{cli-x3en6ct3.js → cli-nwyw3zhg.js} +1 -1
  54. package/dist/{cli-3avfh5az.js → cli-pemywhfq.js} +2 -2
  55. package/dist/{cli-xfe63zx3.js → cli-pkht5hap.js} +2 -2
  56. package/dist/{cli-sppc0cmw.js → cli-pnp2j5zg.js} +2 -2
  57. package/dist/{cli-wk8ccrz6.js → cli-pw7v69vp.js} +2 -2
  58. package/dist/{cli-tgvpmnwz.js → cli-r99kc9yq.js} +5 -5
  59. package/dist/{cli-bfc3k1x5.js → cli-rdyw3mct.js} +9 -9
  60. package/dist/{cli-b80a1100.js → cli-s6vr7r2d.js} +2 -2
  61. package/dist/{cli-zv4vy2b0.js → cli-s95dknxh.js} +1 -1
  62. package/dist/{cli-ttaz6c7m.js → cli-saw9a6f6.js} +6 -5
  63. package/dist/{cli-mz1ezzzh.js → cli-shvfedvm.js} +3 -3
  64. package/dist/{cli-rdr166ht.js → cli-smvcw9z5.js} +1 -1
  65. package/dist/{cli-2rwet3r7.js → cli-sv5gb0yb.js} +1 -1
  66. package/dist/{cli-5ff2sjyt.js → cli-t30yj95q.js} +2 -2
  67. package/dist/{cli-ptkpaqfy.js → cli-wt645v7q.js} +1 -1
  68. package/dist/{cli-f3nx1h8z.js → cli-wxbn3yfx.js} +2 -2
  69. package/dist/{cli-wyrr38xm.js → cli-x5mq1fyq.js} +1 -1
  70. package/dist/{cli-ccn0eybf.js → cli-xbzvet96.js} +6 -6
  71. package/dist/{cli-4mkvwgzr.js → cli-xf234ws8.js} +1 -1
  72. package/dist/{cli-nme7wery.js → cli-y2x52gs2.js} +46 -13
  73. package/dist/{cli-ffbrkh1r.js → cli-y8n5k515.js} +46 -38
  74. package/dist/{cli-ecshf504.js → cli-z4wd2ftv.js} +7 -7
  75. package/dist/{cli-dsgj3e7a.js → cli-zfg9enh9.js} +2 -2
  76. package/dist/{cli-yxqag76b.js → cli-zw88zjba.js} +1 -1
  77. package/dist/cli.js +20 -20
  78. package/dist/{codex-adapter-pp2gq8gr.js → codex-adapter-ttygw382.js} +6 -6
  79. package/dist/{codex-hook-qwzccd64.js → codex-hook-x7nejyrr.js} +7 -4
  80. package/dist/{codex-login-35p4sk85.js → codex-login-m819c41r.js} +1 -1
  81. package/dist/{codex-session-runner-0vzn09t8.js → codex-session-runner-60b58vv3.js} +7 -7
  82. package/dist/{commands-psqhkttb.js → commands-edmdwa4x.js} +2 -2
  83. package/dist/{controller-t20vz2k8.js → controller-m263fg43.js} +4 -4
  84. package/dist/{controllers-connect-gkxmqw9d.js → controllers-connect-5fym8sw1.js} +23 -23
  85. package/dist/{cursor-adapter-3v542qe5.js → cursor-adapter-cz6nm6mj.js} +3 -3
  86. package/dist/{db-nc1rd869.js → db-2y0mgstc.js} +3 -3
  87. package/dist/{db-2xbyenjr.js → db-nn0hcmx5.js} +6 -2
  88. package/dist/{devin-adapter-7egzmt0k.js → devin-adapter-zgqadvnm.js} +1 -1
  89. package/dist/{dispatcher-ewceb8ts.js → dispatcher-0a9wwjcx.js} +20 -20
  90. package/dist/{docker-njavd3fb.js → docker-fkgtr75t.js} +2 -2
  91. package/dist/{dsh-adapter-75xwh78t.js → dsh-adapter-3n3net33.js} +3 -3
  92. package/dist/{e2b-5r6a5jeb.js → e2b-7am6tmq6.js} +2 -2
  93. package/dist/{e2b-pw1nvtmh.js → e2b-thdcxtjd.js} +2 -2
  94. package/dist/{easter-egg-3d-xsc47jwf.js → easter-egg-3d-5cgynaja.js} +1 -1
  95. package/dist/{event-bus-101fenkh.js → event-bus-9vpk8gmq.js} +1 -1
  96. package/dist/{execute-gzmw1mnw.js → execute-t4e6m3rw.js} +1 -1
  97. package/dist/{external-channel-a5dsmxn4.js → external-channel-zhvt95n3.js} +2 -2
  98. package/dist/{grok-adapter-vj88xr23.js → grok-adapter-qnr1hp2y.js} +10 -10
  99. package/dist/handlers-dkcarkd0.js +39 -0
  100. package/dist/{heartbeat-t2m9r3wa.js → heartbeat-gz97r7ac.js} +23 -23
  101. package/dist/{hook-xa677f8r.js → hook-1mmdgjqs.js} +16 -9
  102. package/dist/{hook-8femx1bg.js → hook-x8rthca4.js} +6 -6
  103. package/dist/{http-xpmmq028.js → http-r8f85xr9.js} +274 -160
  104. package/dist/index-5jecgp3n.js +41 -0
  105. package/dist/index-aex0eba9.js +40 -0
  106. package/dist/{index-syztqdt6.js → index-g6tbb6ve.js} +1 -1
  107. package/dist/{index-cdzyfrsp.js → index-smxyk04s.js} +1 -1
  108. package/dist/{index-dg2tmj99.js → index-vzvfqzfj.js} +20 -20
  109. package/dist/{index-s7ckdajq.js → index-y7rbcrc1.js} +10 -10
  110. package/dist/{keepalive-3nr4st3r.js → keepalive-64c0f34c.js} +4 -4
  111. package/dist/lead-b1da0f97.js +78 -0
  112. package/dist/{maintenance-verwpe2c.js → maintenance-mnxpar12.js} +1 -1
  113. package/dist/{oauth-refresh-sweep-9q2t0y3q.js → oauth-refresh-sweep-36hs2v4h.js} +3 -3
  114. package/dist/{onboard-aytqedmq.js → onboard-xes8de61.js} +3 -3
  115. package/dist/{opencode-adapter-f4hryjny.js → opencode-adapter-3s7ax02e.js} +7 -7
  116. package/dist/{otel-impl-hckw4wt1.js → otel-impl-fzc57kcq.js} +2 -2
  117. package/dist/{pi-mono-adapter-hxby0ce1.js → pi-mono-adapter-ytp7gz8b.js} +22 -11
  118. package/dist/{pricing-refresh-5nvme3sm.js → pricing-refresh-1nek2w7b.js} +3 -3
  119. package/dist/{rbac-roles-vbpy21mg.js → rbac-roles-sqefb5hw.js} +2 -2
  120. package/dist/{rbac-roles-pd8c26m1.js → rbac-roles-ttyfaep2.js} +1 -1
  121. package/dist/{render-v2-7nqgvk2q.js → render-v2-vb527jwn.js} +3 -3
  122. package/dist/{resume-b6djcj3c.js → resume-jcdzg1bn.js} +10 -8
  123. package/dist/{runtime-txrxc9za.js → runtime-xe3aqy4x.js} +1 -1
  124. package/dist/{session-access-fc3f9y12.js → session-access-zsp4wsp0.js} +4 -4
  125. package/dist/{setup-n39szm6b.js → setup-1nb2zqd3.js} +1 -1
  126. package/dist/{virtual-modules-wyp2k6z3.js → virtual-modules-4r3zkc20.js} +2 -2
  127. package/dist/{work-objects-jem2fre0.js → work-objects-61w08fwr.js} +23 -23
  128. package/dist/worker-c1e68hpa.js +78 -0
  129. package/dist/{x-8ewt8gxn.js → x-y45mthwn.js} +2 -2
  130. package/openapi.json +491 -52
  131. package/package.json +3 -3
  132. package/src/apps/action-runner.ts +146 -0
  133. package/src/apps/catalog.generated.json +3 -2
  134. package/src/apps/definition.ts +152 -4
  135. package/src/apps/row-store.ts +23 -9
  136. package/src/apps/schema-migrate.ts +14 -6
  137. package/src/apps/script-types.ts +2 -1
  138. package/src/apps/sync.ts +20 -19
  139. package/src/be/db/tasks/read.ts +112 -0
  140. package/src/be/db.ts +16 -4
  141. package/src/be/fleet-benchmark-stats.ts +10 -5
  142. package/src/be/models-catalog.ts +4 -0
  143. package/src/be/onboarding.ts +6 -0
  144. package/src/be/scripts/typecheck.ts +13 -0
  145. package/src/be/swarm-config-guard.ts +25 -1
  146. package/src/be/telemetry-enable.ts +1 -1
  147. package/src/commands/provider-credentials.ts +12 -2
  148. package/src/commands/runner.ts +3 -0
  149. package/src/heartbeat/heartbeat.ts +2 -2
  150. package/src/hooks/codex-hook.ts +6 -2
  151. package/src/hooks/hook.ts +7 -0
  152. package/src/hooks/pr-body-guard.ts +38 -11
  153. package/src/hooks/pr-room-guard.ts +88 -0
  154. package/src/http/agents.ts +1 -0
  155. package/src/http/apps.ts +99 -183
  156. package/src/http/fleet-benchmark.ts +79 -30
  157. package/src/http/global-config.ts +7 -0
  158. package/src/http/ranking.ts +24 -40
  159. package/src/http/status.ts +49 -43
  160. package/src/http/tasks.ts +49 -1
  161. package/src/http/telemetry-ui.ts +1 -1
  162. package/src/http/used-by.ts +55 -19
  163. package/src/http/users.ts +2 -2
  164. package/src/providers/acp-targets.ts +1 -1
  165. package/src/providers/amp-adapter.ts +1 -1
  166. package/src/providers/pi-mono-adapter.ts +15 -0
  167. package/src/providers/reasoning-effort.ts +2 -1
  168. package/src/providers/types.ts +2 -0
  169. package/src/ranking/telemetry-ranking.ts +5 -33
  170. package/src/scripts-runtime/sdk-allowlist.ts +7 -0
  171. package/src/scripts-runtime/types/stdlib.d.ts +31 -0
  172. package/src/scripts-runtime/types/swarm-sdk.d.ts +31 -0
  173. package/src/server.ts +4 -0
  174. package/src/telemetry-context.ts +19 -1
  175. package/src/telemetry-contract/EVENTS.md +42 -8
  176. package/src/telemetry-contract/SOURCE.json +6 -5
  177. package/src/telemetry-contract/catalog.json +225 -5
  178. package/src/telemetry-contract/ranking/fixtures/valid/no-claim.json +10 -0
  179. package/src/telemetry-contract/ranking/listing.v1.schema.json +2 -2
  180. package/src/telemetry-contract/types.gen.ts +225 -27
  181. package/src/telemetry-identity.ts +47 -9
  182. package/src/telemetry-snapshot.ts +9 -1
  183. package/src/telemetry-ui-events.ts +9 -2
  184. package/src/telemetry.ts +29 -6
  185. package/src/tests/app-action-run-tool.test.ts +178 -0
  186. package/src/tests/app-row-tools.test.ts +385 -0
  187. package/src/tests/apps-json-column.test.ts +611 -0
  188. package/src/tests/apps-script-types.test.ts +2 -0
  189. package/src/tests/apps-sync-engine.test.ts +42 -0
  190. package/src/tests/check-pr-body.test.ts +0 -23
  191. package/src/tests/credential-check.test.ts +38 -0
  192. package/src/tests/db-task-read-contract.test.ts +4 -0
  193. package/src/tests/db-task-write-contract.test.ts +2 -0
  194. package/src/tests/docs-index-footprint.test.js +2 -2
  195. package/src/tests/fleet-benchmark.test.ts +122 -2
  196. package/src/tests/http-users.test.ts +62 -1
  197. package/src/tests/model-catalog-table.test.ts +63 -0
  198. package/src/tests/model-profiles-api.test.ts +19 -7
  199. package/src/tests/models-catalog.test.ts +50 -0
  200. package/src/tests/onboarding.test.ts +21 -0
  201. package/src/tests/org-website.test.ts +62 -0
  202. package/src/tests/pi-mono-adapter.test.ts +23 -0
  203. package/src/tests/pr-body-leaks.test.ts +4 -0
  204. package/src/tests/pr-room-guard.test.ts +242 -0
  205. package/src/tests/ranking-listing.test.ts +8 -23
  206. package/src/tests/ranking-route.test.ts +49 -47
  207. package/src/tests/reasoning-effort.test.ts +39 -3
  208. package/src/tests/runner-harness-telemetry-env.test.ts +62 -1
  209. package/src/tests/status.test.ts +158 -9
  210. package/src/tests/swarm-tool-result-gate.test.ts +2 -4
  211. package/src/tests/task-lineage.test.ts +180 -0
  212. package/src/tests/telemetry-context.test.ts +128 -2
  213. package/src/tests/telemetry-init.test.ts +62 -5
  214. package/src/tests/telemetry-ui-route.test.ts +123 -0
  215. package/src/tests/tool-annotations.test.ts +3 -2
  216. package/src/tests/used-by-route.test.ts +144 -10
  217. package/src/tests/user-token-rest-auth.test.ts +38 -0
  218. package/src/tests/workflow-agent-task-retry.test.ts +130 -4
  219. package/src/tests/workflow-wait-recovery.test.ts +116 -4
  220. package/src/tools/app-action-run.ts +63 -0
  221. package/src/tools/app-rows.ts +239 -0
  222. package/src/tools/model-catalog/index.ts +1 -1
  223. package/src/tools/tool-config.ts +8 -0
  224. package/src/tools/utils.ts +1 -1
  225. package/src/tools/workflows/retry-workflow-run.ts +1 -1
  226. package/src/types.ts +17 -0
  227. package/src/utils/company-profile.ts +24 -0
  228. package/src/utils/org-website.ts +58 -21
  229. package/src/workflows/recovery.ts +10 -22
  230. package/src/workflows/resume.ts +16 -0
  231. package/src/workflows/task-step-routing.ts +47 -7
  232. package/templates/skills/apps/SKILL.md +44 -4
  233. package/templates/skills/apps/content.md +44 -4
  234. package/dist/handlers-zbs90bny.js +0 -39
  235. package/dist/index-8pwc1jc8.js +0 -40
  236. package/dist/index-nxa6me0q.js +0 -41
  237. package/dist/lead-td8h2sfn.js +0 -78
  238. package/dist/worker-wr6xgfr2.js +0 -78
  239. package/src/tests/check-ranking-entry.test.ts +0 -146
@@ -332,19 +332,19 @@ import {
332
332
  recordInlineScriptRun2,
333
333
  exports_db,
334
334
  init_db3
335
- } from "./cli-rg7ntypm.js";
335
+ } from "./cli-d3qqdy4c.js";
336
336
  import {
337
337
  getUserGrant2,
338
338
  init_rbac_roles
339
- } from "./cli-5s5hx57y.js";
339
+ } from "./cli-7awf1fp8.js";
340
340
  import {
341
341
  ensurePricingSeeded2,
342
342
  ensureRbacSeeded2,
343
343
  ensureModelProfilesSeeded2
344
- } from "./cli-kk2r80n5.js";
344
+ } from "./cli-faypxz7q.js";
345
345
  import {
346
346
  loadModelsDevCache
347
- } from "./cli-tg9ksbn8.js";
347
+ } from "./cli-h93c9vb3.js";
348
348
  import {
349
349
  buildCatalogEntries,
350
350
  listModelCatalog,
@@ -354,12 +354,12 @@ import {
354
354
  loadModelsCatalog,
355
355
  requestModelCatalogRefresh2,
356
356
  startPricingRefreshLoop2
357
- } from "./cli-ttaz6c7m.js";
357
+ } from "./cli-saw9a6f6.js";
358
358
  import {
359
359
  ampPinProviderError,
360
360
  ampPinCatalogError,
361
361
  ampModelError
362
- } from "./cli-2rwet3r7.js";
362
+ } from "./cli-sv5gb0yb.js";
363
363
  import {
364
364
  notifyAutomationPreflightFailure,
365
365
  isNeedsSetupFailure,
@@ -397,6 +397,7 @@ import {
397
397
  cancelWorkflowRunRows2,
398
398
  cancelWorkflowRun2,
399
399
  resumeWaitState2,
400
+ recoverResolvedWaitState2,
400
401
  resumeFromChildRun2,
401
402
  initWaitBusSubscriptions2,
402
403
  TriggerSchemaError,
@@ -410,7 +411,7 @@ import {
410
411
  buildNodeInterpolationCtx,
411
412
  interpolateNodeConfig,
412
413
  scriptBodyInterpolationError
413
- } from "./cli-nme7wery.js";
414
+ } from "./cli-y2x52gs2.js";
414
415
  import {
415
416
  require_dist2,
416
417
  publicEndpointSsrfOptions,
@@ -448,8 +449,11 @@ import {
448
449
  runSavedScriptAsAgent,
449
450
  resolveSyncRunAs,
450
451
  AppNameSchema,
451
- ColumnKindSchema,
452
+ ScalarColumnKindSchema,
452
453
  isIso8601Date,
454
+ jsonColumnSizeLabel,
455
+ jsonColumnValueIssue,
456
+ isValidColumnValue,
453
457
  SYSTEM_COLUMN_KINDS,
454
458
  SORTABLE_SYSTEM_DATE_COLUMNS,
455
459
  AppElementsSchema,
@@ -467,14 +471,14 @@ import {
467
471
  deleteApp,
468
472
  typecheckScript,
469
473
  parseSkillContent
470
- } from "./cli-nrrg0fvy.js";
474
+ } from "./cli-h38rjv87.js";
471
475
  import {
472
476
  buildAuthorizationUrl,
473
477
  onAuthorizationRefreshed,
474
478
  ensureAuthorizationTokenOrThrow,
475
479
  ensureToken,
476
480
  ensureTokenOrThrow
477
- } from "./cli-b80a1100.js";
481
+ } from "./cli-s6vr7r2d.js";
478
482
  import {
479
483
  detachedProcessGroup,
480
484
  registerProcessGroup,
@@ -504,14 +508,14 @@ import {
504
508
  getSlackApp2,
505
509
  startSlackApp2,
506
510
  stopSlackApp2
507
- } from "./cli-4fhyq711.js";
511
+ } from "./cli-nn47d7e8.js";
508
512
  import {
509
513
  slackCode,
510
514
  slackMissingScopeMessage,
511
515
  withAutoJoin,
512
516
  externalChannelToolError2,
513
517
  getChannelBlockReason2
514
- } from "./cli-xfe63zx3.js";
518
+ } from "./cli-pkht5hap.js";
515
519
  import {
516
520
  BaseExecutor,
517
521
  postApprovalCancellationUpdates,
@@ -528,11 +532,11 @@ import {
528
532
  definitionNodeIds,
529
533
  validateDefinition,
530
534
  applyDefinitionPatch
531
- } from "./cli-tj4j2ts4.js";
535
+ } from "./cli-02qm7src.js";
532
536
  import {
533
537
  workflowEventBus2,
534
538
  init_event_bus
535
- } from "./cli-ptkpaqfy.js";
539
+ } from "./cli-wt645v7q.js";
536
540
  import {
537
541
  duplicateGuardedQueryKey,
538
542
  parseQueryParams,
@@ -557,7 +561,7 @@ import {
557
561
  isPublicRoute,
558
562
  findRoute,
559
563
  route
560
- } from "./cli-02vhhssk.js";
564
+ } from "./cli-efaqv1c7.js";
561
565
  import {
562
566
  isMultiRuntimeEnabled
563
567
  } from "./cli-7a91w22y.js";
@@ -569,7 +573,7 @@ import {
569
573
  import {
570
574
  getRuntimePool2,
571
575
  init_db
572
- } from "./cli-6ftrrwm1.js";
576
+ } from "./cli-n85dqg6d.js";
573
577
  import {
574
578
  getMemoryRaterNames,
575
579
  REFERENCES_SOURCE_MAX_LENGTH,
@@ -580,7 +584,7 @@ import {
580
584
  COMPOSIO_HTTP_METHODS,
581
585
  executeComposioRequest,
582
586
  composioArgsFromParts
583
- } from "./cli-rdr166ht.js";
587
+ } from "./cli-smvcw9z5.js";
584
588
  import {
585
589
  require_fast_deep_equal
586
590
  } from "./cli-bhp11egn.js";
@@ -594,7 +598,7 @@ import {
594
598
  import {
595
599
  canProvisionKind,
596
600
  init_runtime_providers
597
- } from "./cli-wk8ccrz6.js";
601
+ } from "./cli-pw7v69vp.js";
598
602
  import {
599
603
  findUserById,
600
604
  findUserByExternalId,
@@ -610,7 +614,7 @@ import {
610
614
  resolveSessionToken,
611
615
  fingerprintApiKey,
612
616
  init_users
613
- } from "./cli-8cxkw1f5.js";
617
+ } from "./cli-nmqdc2t3.js";
614
618
  import {
615
619
  isRbacEnabled,
616
620
  decideAdmission,
@@ -679,7 +683,7 @@ import {
679
683
  KvNamespaceSchema,
680
684
  KvKeySchema,
681
685
  init_types
682
- } from "./cli-a1esmmee.js";
686
+ } from "./cli-fpmsqq59.js";
683
687
  import {
684
688
  generateDefaultClaudeMd2,
685
689
  generateDefaultSoulMd2,
@@ -688,7 +692,7 @@ import {
688
692
  taskAttachmentFetchCommand,
689
693
  taskAttachmentDisplayUrl,
690
694
  init_task_attachment_links
691
- } from "./cli-wyrr38xm.js";
695
+ } from "./cli-x5mq1fyq.js";
692
696
  import {
693
697
  getSlackConfiguration,
694
698
  init_config
@@ -750,7 +754,7 @@ import {
750
754
  import {
751
755
  init_package,
752
756
  package_default
753
- } from "./cli-mz1ezzzh.js";
757
+ } from "./cli-shvfedvm.js";
754
758
  import {
755
759
  realtimeBus,
756
760
  init_bus
@@ -783,7 +787,7 @@ import {
783
787
  registerVolatileSecret,
784
788
  registerSensitiveKeyName,
785
789
  init_secret_scrubber
786
- } from "./cli-4mkvwgzr.js";
790
+ } from "./cli-xf234ws8.js";
787
791
  import {
788
792
  isAlias,
789
793
  parseAlias,
@@ -797,7 +801,7 @@ import {
797
801
  openAICompatibleProviderIds,
798
802
  claudeCatalogModelId,
799
803
  init_src2
800
- } from "./cli-x3en6ct3.js";
804
+ } from "./cli-nwyw3zhg.js";
801
805
  import {
802
806
  __toESM,
803
807
  __commonJS,
@@ -20252,17 +20256,12 @@ async function recoverWaitStates(registry) {
20252
20256
  let recovered = 0;
20253
20257
  for (const stuck of stuckRuns) {
20254
20258
  try {
20255
- let resumeStatus;
20256
- let payload;
20257
- if (stuck.waitStatus === "fired") {
20258
- resumeStatus = "fired";
20259
- payload = stuck.firedPayload != null ? safeJsonParse(stuck.firedPayload) : undefined;
20260
- } else if (stuck.waitStatus === "timeout") {
20261
- resumeStatus = "timeout";
20259
+ if (stuck.waitStatus === "pending") {
20260
+ const status = stuck.waitMode === "time" ? "fired" : "timeout";
20261
+ await resumeWaitState2(stuck.waitId, status, undefined, registry);
20262
20262
  } else {
20263
- resumeStatus = stuck.waitMode === "time" ? "fired" : "timeout";
20263
+ await recoverResolvedWaitState2(stuck.waitId, registry);
20264
20264
  }
20265
- await resumeWaitState2(stuck.waitId, resumeStatus, payload, registry);
20266
20265
  recovered++;
20267
20266
  } catch (err) {
20268
20267
  if (await failRunOnUnreadableReplay(stuck.runId, err))
@@ -20272,13 +20271,6 @@ async function recoverWaitStates(registry) {
20272
20271
  }
20273
20272
  return recovered;
20274
20273
  }
20275
- function safeJsonParse(s) {
20276
- try {
20277
- return JSON.parse(s);
20278
- } catch {
20279
- return s;
20280
- }
20281
- }
20282
20274
  async function getRunIdsByStatus(status) {
20283
20275
  const rows = await getDbClient2().query("SELECT id FROM workflow_runs WHERE status = ?", [status]);
20284
20276
  return rows.map((r) => r.id);
@@ -21154,7 +21146,7 @@ class NotifyExecutor extends BaseExecutor {
21154
21146
  }
21155
21147
  }
21156
21148
  case "slack": {
21157
- const { getSlackApp } = await import("./app-mqap8t8m.js");
21149
+ const { getSlackApp } = await import("./app-9h14qvr6.js");
21158
21150
  const app = getSlackApp();
21159
21151
  if (!app) {
21160
21152
  return {
@@ -23705,6 +23697,13 @@ var SDK_TOOL_NAME_MAP = {
23705
23697
  app_list: "app-list",
23706
23698
  app_patch: "app-patch",
23707
23699
  app_query: "app-query",
23700
+ app_rows_list: "app-rows-list",
23701
+ app_row_get: "app-row-get",
23702
+ app_row_create: "app-row-create",
23703
+ app_rows_create: "app-rows-create",
23704
+ app_row_patch: "app-row-patch",
23705
+ app_row_delete: "app-row-delete",
23706
+ app_rows_delete: "app-rows-delete",
23708
23707
  app_rollback: "app-rollback",
23709
23708
  app_sync: "app-sync",
23710
23709
  app_upsert: "app-upsert",
@@ -24161,7 +24160,7 @@ var NUDGES = {
24161
24160
  const definition = r.data?.app?.definition;
24162
24161
  const hasQueries = Object.keys(definition?.queries ?? {}).length > 0;
24163
24162
  const hasActions = Object.keys(definition?.actions ?? {}).length > 0;
24164
- return hasQueries || hasActions ? "This app's callable surface is `definition.queries` (run with `app-query`, passing any `$param` values) and `definition.actions` (invoke with `POST /api/apps/<id>/actions/<name>`; `sync` actions refresh sources)." : undefined;
24163
+ return hasQueries || hasActions ? "Run `definition.queries` with `app-query` and supply each `$param` value. Invoke `definition.actions` with `app-action-run` through MCP or `POST /api/apps/<id>/actions/<name>` through REST. Sync actions refresh sources." : undefined;
24165
24164
  },
24166
24165
  "kv-get": (r) => {
24167
24166
  if (!r.ok)
@@ -24509,7 +24508,7 @@ function setPreloadedTools(server, names) {
24509
24508
  async function applyPreToolCall(name, args, requestInfo, inputSchema) {
24510
24509
  if (requestInfo.callOrigin !== "mcp")
24511
24510
  return { args };
24512
- const dispatcher = await import("./dispatcher-ewceb8ts.js");
24511
+ const dispatcher = await import("./dispatcher-0a9wwjcx.js");
24513
24512
  const result = await dispatcher.dispatchPre("pre.tool.call", { tool: name, args, requestInfo }, inputSchema ? {
24514
24513
  validateModify: async (data) => {
24515
24514
  const schema = normalizeObjectSchema(inputSchema) ?? inputSchema;
@@ -33822,7 +33821,7 @@ async function notifySlack(text) {
33822
33821
  return;
33823
33822
  }
33824
33823
  try {
33825
- const { getSlackApp } = await import("./app-mqap8t8m.js");
33824
+ const { getSlackApp } = await import("./app-9h14qvr6.js");
33826
33825
  const app = getSlackApp();
33827
33826
  if (!app) {
33828
33827
  console.warn("[Jira webhook keepalive] Slack not available, cannot send notification");
@@ -33893,7 +33892,7 @@ async function deleteJiraWebhook(webhookId) {
33893
33892
  console.log(`[Jira webhook keepalive] Deleted webhook id=${webhookId}`);
33894
33893
  }
33895
33894
  async function overwriteWebhookIds(next) {
33896
- const { getDbClient } = await import("./db-2xbyenjr.js");
33895
+ const { getDbClient } = await import("./db-nn0hcmx5.js");
33897
33896
  await getDbClient().transaction(async (tx) => {
33898
33897
  const row = await tx.get("SELECT metadata FROM oauth_apps WHERE provider = 'jira'");
33899
33898
  if (!row) {
@@ -107243,7 +107242,7 @@ async function reloadGlobalConfigsAndIntegrations() {
107243
107242
  return runWithoutRequestAuth(() => reloadGlobalConfigsAndIntegrationsInner());
107244
107243
  }
107245
107244
  async function reloadGlobalConfigsAndIntegrationsInner() {
107246
- const { getEmbeddingProvider, resetEmbeddingProvider } = await import("./index-cdzyfrsp.js");
107245
+ const { getEmbeddingProvider, resetEmbeddingProvider } = await import("./index-smxyk04s.js");
107247
107246
  const wasEmbeddingsConfigured = getEmbeddingProvider().isConfigured();
107248
107247
  const updated = await loadGlobalConfigsIntoEnv(true);
107249
107248
  await syncTelemetryEnabled("settings").catch((err) => {
@@ -107259,10 +107258,10 @@ async function reloadGlobalConfigsAndIntegrationsInner() {
107259
107258
  integrations.push("embeddings");
107260
107259
  }
107261
107260
  if (!wasEmbeddingsConfigured && isEmbeddingsConfigured) {
107262
- import("./boot-reembed-qr8a894z.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
107261
+ import("./boot-reembed-6yn53ms9.js").then(({ runBootReembed }) => runBootReembed()).catch((err) => {
107263
107262
  console.error("[config-reload] memory backfill failed (non-fatal):", err);
107264
107263
  });
107265
- import("./boot-reembed-rj85jjhw.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
107264
+ import("./boot-reembed-7fcka4z5.js").then(({ runBootReembedScripts }) => runBootReembedScripts()).catch((err) => {
107266
107265
  console.error("[config-reload] script backfill failed (non-fatal):", err);
107267
107266
  });
107268
107267
  }
@@ -107797,15 +107796,21 @@ var registerAcceptSteerTool = (server) => {
107797
107796
  }, async (args, info, _meta) => acceptSteerHandler(ownerCtx(info), args));
107798
107797
  };
107799
107798
 
107800
- // src/tools/app-diff.ts
107799
+ // src/tools/app-action-run.ts
107801
107800
  init_zod();
107802
107801
 
107803
- // src/apps/version.ts
107802
+ // src/apps/action-runner.ts
107803
+ init_key();
107804
107804
  init_db3();
107805
+ init_db2();
107806
+ init_resolver();
107807
+ init_secret_scrubber();
107805
107808
 
107806
- // src/apps/schema-migrate.ts
107809
+ // src/apps/sync.ts
107807
107810
  init_zod();
107808
107811
  init_db3();
107812
+ init_db2();
107813
+ init_types();
107809
107814
  init_secret_scrubber();
107810
107815
 
107811
107816
  // src/apps/row-store.ts
@@ -107850,6 +107855,8 @@ function appIndexKey(model, column, value, rowId) {
107850
107855
  function isIndexed(column) {
107851
107856
  if (column.hidden === true)
107852
107857
  return false;
107858
+ if (column.kind === "json")
107859
+ return false;
107853
107860
  if (column.kind === "enum")
107854
107861
  return true;
107855
107862
  return column.index === true && (column.kind === "string" || column.kind === "boolean");
@@ -107867,15 +107874,7 @@ function indexKeys(model, definition, row) {
107867
107874
  function validValue(column, value) {
107868
107875
  if (value === null)
107869
107876
  return column.required !== true;
107870
- if (column.kind === "string")
107871
- return typeof value === "string";
107872
- if (column.kind === "number")
107873
- return typeof value === "number" && Number.isFinite(value);
107874
- if (column.kind === "boolean")
107875
- return typeof value === "boolean";
107876
- if (column.kind === "date")
107877
- return typeof value === "string" && isIso8601Date(value);
107878
- return typeof value === "string" && Boolean(column.enum?.includes(value));
107877
+ return isValidColumnValue(column, value);
107879
107878
  }
107880
107879
  function joinKeyColumnNames(definition) {
107881
107880
  const names = new Set;
@@ -107931,7 +107930,19 @@ function prepareValues(definition, values, mode, options = {}) {
107931
107930
  if (!Object.hasOwn(definition.columns, name))
107932
107931
  continue;
107933
107932
  const column = definition.columns[name];
107934
- if (!validValue(column, value)) {
107933
+ if (column.kind === "json" && value !== null) {
107934
+ const issue = jsonColumnValueIssue(value);
107935
+ if (issue === "unserializable") {
107936
+ issues.push({ path: `values.${name}`, message: "must be a valid json value" });
107937
+ } else if (issue === "non-finite") {
107938
+ issues.push({ path: `values.${name}`, message: "json value contains a non-finite number" });
107939
+ } else if (issue === "oversized") {
107940
+ issues.push({
107941
+ path: `values.${name}`,
107942
+ message: `json value exceeds the ${jsonColumnSizeLabel()} size limit`
107943
+ });
107944
+ }
107945
+ } else if (!validValue(column, value)) {
107935
107946
  issues.push({ path: `values.${name}`, message: `must be a valid ${column.kind} value` });
107936
107947
  }
107937
107948
  }
@@ -108145,14 +108156,14 @@ async function rebuildAppColumnIndexUnlocked(appId, model, columnName, column, r
108145
108156
  });
108146
108157
  }
108147
108158
  }
108148
- function deleteAppRow(appId, model, _definition, rowId) {
108159
+ function deleteAppRow(appId, model, _definition, rowId, matches) {
108149
108160
  return withMutationLock(appId, model, async () => {
108150
108161
  const currentDefinition = await currentModelDefinition(appId, model);
108151
108162
  if (!currentDefinition)
108152
108163
  return false;
108153
108164
  const namespace = appsNamespace(appId);
108154
108165
  const row = await getAppRow(appId, model, rowId);
108155
- if (!row)
108166
+ if (!row || matches && !matches(row))
108156
108167
  return false;
108157
108168
  for (const key of indexKeys(model, currentDefinition, row))
108158
108169
  await deleteKv2(namespace, key);
@@ -108187,11 +108198,6 @@ function purgeAppRows(appId, models, afterPurge) {
108187
108198
  }
108188
108199
 
108189
108200
  // src/apps/sync.ts
108190
- init_zod();
108191
- init_db3();
108192
- init_db2();
108193
- init_types();
108194
- init_secret_scrubber();
108195
108201
  var MAX_PULL_RECORDS = 500;
108196
108202
  var MAX_PASS_WARNINGS = 20;
108197
108203
  var MAX_TASK_LIMIT = 200;
@@ -108463,17 +108469,6 @@ function applyTransform(value, transform) {
108463
108469
  }
108464
108470
  }
108465
108471
  }
108466
- function validForKind(column, value) {
108467
- if (column.kind === "string")
108468
- return typeof value === "string";
108469
- if (column.kind === "number")
108470
- return typeof value === "number" && Number.isFinite(value);
108471
- if (column.kind === "boolean")
108472
- return typeof value === "boolean";
108473
- if (column.kind === "date")
108474
- return typeof value === "string" && isIso8601Date(value);
108475
- return typeof value === "string" && Boolean(column.enum?.includes(value));
108476
- }
108477
108472
  function projectRecord(args) {
108478
108473
  const values = { [args.joinKey]: args.record.key };
108479
108474
  for (const [name, column] of args.bindings) {
@@ -108488,7 +108483,7 @@ function projectRecord(args) {
108488
108483
  warn(args.warnings, `column "${name}": transform "${binding.transform}" failed — ${error instanceof Error ? error.message : String(error)}`);
108489
108484
  value = null;
108490
108485
  }
108491
- if (value !== null && !validForKind(column, value)) {
108486
+ if (value !== null && !isValidColumnValue(column, value)) {
108492
108487
  warn(args.warnings, `column "${name}": field "${binding.field}" produced a value that is not a valid ${column.kind}`);
108493
108488
  value = null;
108494
108489
  }
@@ -108496,8 +108491,12 @@ function projectRecord(args) {
108496
108491
  }
108497
108492
  return values;
108498
108493
  }
108499
- function sameValue(existing, projected) {
108500
- return Object.is(existing ?? null, projected ?? null);
108494
+ function sameValue(column, existing, projected) {
108495
+ const before = existing ?? null;
108496
+ const after = projected ?? null;
108497
+ if (column?.kind === "json")
108498
+ return Bun.deepEquals(before, after);
108499
+ return Object.is(before, after);
108501
108500
  }
108502
108501
  async function resolvePair(appId, model, source) {
108503
108502
  const app = await getApp(appId);
@@ -108587,7 +108586,7 @@ function reconcile(args) {
108587
108586
  tally.created += 1;
108588
108587
  return;
108589
108588
  }
108590
- const differs = Object.entries(values).some(([name, value]) => !sameValue(existing[name], value));
108589
+ const differs = Object.entries(values).some(([name, value]) => !sameValue(modelDef.columns[name], existing[name], value));
108591
108590
  const updated = await patchAppRowUnlocked(appId, model, modelDef, existing.id, values, {
108592
108591
  allowSourceManaged: true,
108593
108592
  envelope,
@@ -108777,8 +108776,183 @@ async function runAppSync(input) {
108777
108776
  return { ok: passes.every((pass) => pass.error === undefined), passes };
108778
108777
  }
108779
108778
 
108779
+ // src/apps/action-runner.ts
108780
+ function syncPassError(sync) {
108781
+ const failed = sync.passes.filter((pass) => pass.error !== undefined);
108782
+ if (failed.length === 0)
108783
+ return;
108784
+ return failed.map((pass) => `${pass.model}.${pass.source}: ${pass.error}`).join("; ");
108785
+ }
108786
+ async function runAppAction({
108787
+ app,
108788
+ name,
108789
+ input = {},
108790
+ caller,
108791
+ actor
108792
+ }) {
108793
+ const actions = app.definition.actions;
108794
+ if (!actions || !Object.hasOwn(actions, name)) {
108795
+ return { status: 404, body: { error: "app action not found" } };
108796
+ }
108797
+ const action = actions[name];
108798
+ if (action.kind === "script") {
108799
+ const script = await getScriptById(action.scriptId);
108800
+ if (!script) {
108801
+ return {
108802
+ status: 400,
108803
+ body: {
108804
+ error: "invalid app action",
108805
+ issues: [
108806
+ {
108807
+ path: `actions.${name}.scriptId`,
108808
+ message: `script "${action.scriptId}" no longer exists`
108809
+ }
108810
+ ]
108811
+ }
108812
+ };
108813
+ }
108814
+ const runAsAgentId = getSavedScriptOwnerAgentId(script);
108815
+ if (!runAsAgentId) {
108816
+ return {
108817
+ status: 400,
108818
+ body: { error: "agentId is required: this script has no owning agent to run as" }
108819
+ };
108820
+ }
108821
+ const output = await runSavedScriptAsAgent({
108822
+ script,
108823
+ input: { ...action.args, ...input, app: { id: app.id }, caller },
108824
+ agentId: runAsAgentId
108825
+ });
108826
+ const ok = output.exitCode === 0 && !output.error && !output.runtimeError;
108827
+ const error = ok ? undefined : output.runtimeError ? `${output.runtimeError.name}: ${output.runtimeError.message}` : output.error ?? `Script exited with code ${output.exitCode}`;
108828
+ return {
108829
+ status: 200,
108830
+ body: scrubObject({
108831
+ ok,
108832
+ result: output.result,
108833
+ stdout: output.stdout,
108834
+ ...error === undefined ? {} : { error },
108835
+ durationMs: output.durationMs
108836
+ })
108837
+ };
108838
+ }
108839
+ if (action.kind === "sync") {
108840
+ const startedAt = Date.now();
108841
+ const sync = await runAppSync({
108842
+ appId: app.id,
108843
+ ...action.model === undefined ? {} : { model: action.model },
108844
+ ...action.source === undefined ? {} : { source: action.source },
108845
+ invokedBy: actor
108846
+ });
108847
+ const durationMs = Date.now() - startedAt;
108848
+ if (sync.issues && sync.issues.length > 0) {
108849
+ return { status: 400, body: { error: "invalid sync action", issues: sync.issues } };
108850
+ }
108851
+ const error = syncPassError(sync);
108852
+ return {
108853
+ status: 200,
108854
+ body: scrubObject({
108855
+ ok: sync.ok,
108856
+ result: { passes: sync.passes },
108857
+ ...error === undefined ? {} : { error },
108858
+ durationMs
108859
+ })
108860
+ };
108861
+ }
108862
+ const lead = action.agentId ? null : await getLeadAgent2();
108863
+ const taskPrompt = resolveTemplate("task.app.action", {
108864
+ prompt: action.prompt,
108865
+ app_id: app.id,
108866
+ action_name: name,
108867
+ input_json: JSON.stringify(input),
108868
+ caller_json: JSON.stringify(caller)
108869
+ });
108870
+ const task = await createTaskWithSiblingAwareness(taskPrompt.text, {
108871
+ source: "api",
108872
+ agentId: action.agentId ?? lead?.id,
108873
+ routingReason: action.agentId ? "human_pinned" : lead ? "skill" : undefined,
108874
+ routingSource: action.agentId || lead ? "engine_default" : undefined,
108875
+ key: normalizeAssetKey(`shared/app:${app.id}/action:${name}/`),
108876
+ ...actor.startsWith("user:") ? { requestedByUserId: actor.slice("user:".length) } : {}
108877
+ }, { origin: "app" });
108878
+ return {
108879
+ status: 200,
108880
+ body: { ok: true, taskId: task.id, status: task.status }
108881
+ };
108882
+ }
108883
+
108884
+ // src/tools/app-action-run.ts
108885
+ init_db3();
108886
+ init_rbac();
108887
+ function registerAppActionRunTool(server) {
108888
+ createToolRegistrar(server)("app-action-run", {
108889
+ title: "Run an app action",
108890
+ description: "Run a declared app action as an agent. Scripts and extensions cannot invoke this tool.",
108891
+ annotations: { readOnlyHint: false, destructiveHint: true, openWorldHint: true },
108892
+ rbac: { permission: "app.use" },
108893
+ inputSchema: object2({
108894
+ appId: string2().min(1),
108895
+ action: AppNameSchema,
108896
+ input: record2(string2(), unknown()).optional()
108897
+ }),
108898
+ outputSchema: swarmToolOutputSchema({
108899
+ ok: boolean().optional(),
108900
+ result: unknown().optional(),
108901
+ stdout: string2().optional(),
108902
+ error: string2().optional(),
108903
+ durationMs: number2().optional(),
108904
+ taskId: string2().optional(),
108905
+ status: string2().optional()
108906
+ })
108907
+ }, async ({ appId, action, input }, info) => {
108908
+ if (info.callOrigin === "script-sdk" || info.callOrigin === "extension")
108909
+ return toolErr("Scripts and extensions cannot run app actions.");
108910
+ if (!info.agentId)
108911
+ return toolErr('Agent ID not found. Set the "X-Agent-ID" header.');
108912
+ const agent = await getAgentById2(info.agentId);
108913
+ const decision = can({
108914
+ principal: { kind: "agent", agentId: info.agentId, isLead: agent?.isLead ?? false },
108915
+ verb: "app.use",
108916
+ resource: { kind: "app", appId },
108917
+ source: "mcp"
108918
+ });
108919
+ if (!decision.allow)
108920
+ return toolErr(decision.reason);
108921
+ const app = await getApp(appId);
108922
+ if (!app)
108923
+ return toolErr("App not found.");
108924
+ if (appDefinitionNeedsRepair(app))
108925
+ return toolErr("App definition needs repair.", { data: { issues: app.definitionError } });
108926
+ const output = await runAppAction({
108927
+ app,
108928
+ name: action,
108929
+ input,
108930
+ actor: `agent:${info.agentId}`,
108931
+ caller: { kind: "agent", id: info.agentId, ...agent?.name ? { name: agent.name } : {} }
108932
+ });
108933
+ if (output.status !== 200)
108934
+ return toolErr(output.body.error ?? "Action failed.", { data: output.body });
108935
+ return toolOk("Action invoked.", { data: output.body });
108936
+ });
108937
+ }
108938
+
108939
+ // src/tools/app-diff.ts
108940
+ init_zod();
108941
+
108942
+ // src/apps/version.ts
108943
+ init_db3();
108944
+
108780
108945
  // src/apps/schema-migrate.ts
108781
- var MigrationValueSchema = union2([string2(), number2(), boolean()]);
108946
+ init_zod();
108947
+ init_db3();
108948
+ init_secret_scrubber();
108949
+ var MigrationValueSchema = union2([
108950
+ string2(),
108951
+ number2(),
108952
+ boolean(),
108953
+ record2(string2(), unknown()),
108954
+ array2(unknown())
108955
+ ]);
108782
108956
  var AppMigrationDirectiveSchema = union2([
108783
108957
  object2({ set: MigrationValueSchema }).strict(),
108784
108958
  object2({
@@ -109008,15 +109182,7 @@ function isPurgeDirective(directive) {
109008
109182
  function columnAccepts(column, value) {
109009
109183
  if (value === null)
109010
109184
  return column.hidden === true || column.required !== true;
109011
- if (column.kind === "string")
109012
- return typeof value === "string";
109013
- if (column.kind === "number")
109014
- return typeof value === "number" && Number.isFinite(value);
109015
- if (column.kind === "boolean")
109016
- return typeof value === "boolean";
109017
- if (column.kind === "date")
109018
- return typeof value === "string" && isIso8601Date(value);
109019
- return typeof value === "string" && Boolean(column.enum?.includes(value));
109185
+ return isValidColumnValue(column, value);
109020
109186
  }
109021
109187
  function coerceValue(value, oldColumn, nextColumn) {
109022
109188
  if (columnAccepts(nextColumn, value))
@@ -109873,10 +110039,7 @@ async function upsertAppUserConfigValues(appId, scope, values) {
109873
110039
  }
109874
110040
 
109875
110041
  // src/http/apps.ts
109876
- init_key();
109877
110042
  init_db3();
109878
- init_db2();
109879
- init_resolver();
109880
110043
  init_rbac();
109881
110044
  init_types();
109882
110045
  init_request_auth_context();
@@ -109969,7 +110132,7 @@ var AppSyncStatusSchema = object2({
109969
110132
  });
109970
110133
  var UserConfigValuesSchema = record2(string2(), union2([string2(), number2(), boolean(), _null()]));
109971
110134
  var AppUserConfigFieldSchema = object2({
109972
- kind: ColumnKindSchema,
110135
+ kind: ScalarColumnKindSchema,
109973
110136
  default: union2([string2(), number2(), boolean()]).optional(),
109974
110137
  enum: array2(string2()).optional(),
109975
110138
  label: string2().optional()
@@ -110419,12 +110582,6 @@ function definitionNeedsRepair(res, app) {
110419
110582
  json(res, { error: "definition needs repair", issues: app.definitionError }, 409);
110420
110583
  return true;
110421
110584
  }
110422
- function syncPassError(sync) {
110423
- const failed = sync.passes.filter((pass) => pass.error !== undefined);
110424
- if (failed.length === 0)
110425
- return;
110426
- return failed.map((pass) => `${pass.model}.${pass.source}: ${pass.error}`).join("; ");
110427
- }
110428
110585
  function snapshotFailure(res) {
110429
110586
  jsonError(res, "failed to snapshot app", 500);
110430
110587
  }
@@ -110452,6 +110609,8 @@ async function resolveModel(appId, modelName, res) {
110452
110609
  return { app, model: app.definition.models[modelName] };
110453
110610
  }
110454
110611
  function parseFilterValue(raw, column) {
110612
+ if (column.kind === "json")
110613
+ throw new Error("json columns cannot be filtered");
110455
110614
  if (column.kind === "number") {
110456
110615
  if (!DECIMAL_NUMBER_PATTERN.test(raw))
110457
110616
  throw new Error("must be a decimal number");
@@ -110595,6 +110754,9 @@ function compareValues(left, right, direction, dateValues = false) {
110595
110754
  function rowValue(row, column) {
110596
110755
  return Object.hasOwn(row, column) ? row[column] : undefined;
110597
110756
  }
110757
+ function rowMatchesFilters(row, filters) {
110758
+ return filters.every((filter) => rowValue(row, filter.column) === filter.value);
110759
+ }
110598
110760
  function applyQuery(rows, query, model, params = {}, queryName = "<unnamed>") {
110599
110761
  const filters = resolveQueryFilters(query, model, params, queryName);
110600
110762
  let selected = rows.filter((row) => filters.every(([column, value]) => rowValue(row, column) === value));
@@ -110607,6 +110769,29 @@ function applyQuery(rows, query, model, params = {}, queryName = "<unnamed>") {
110607
110769
  }
110608
110770
  return selected.slice(0, query.limit ?? 200);
110609
110771
  }
110772
+ async function selectAppRows(appId, modelName, model, filters, sortRaw, limit = 200, systemColumns = false) {
110773
+ const jsonFilterIssues = filters.flatMap((filter) => Object.hasOwn(model.columns, filter.column) && model.columns[filter.column].kind === "json" ? [{ path: `filter.${filter.column}`, message: "json columns cannot be filtered" }] : []);
110774
+ if (jsonFilterIssues.length > 0)
110775
+ throw new AppRowValidationError(jsonFilterIssues);
110776
+ const rows = (await listAppRows(appId, modelName, filters.flatMap((filter) => typeof filter.value === "string" || typeof filter.value === "number" || typeof filter.value === "boolean" ? [{ column: filter.column, value: filter.value }] : []))).filter((row) => rowMatchesFilters(row, filters));
110777
+ if (sortRaw) {
110778
+ const [column, dir, extra] = sortRaw.split(":");
110779
+ if (extra !== undefined || !column || dir !== "asc" && dir !== "desc" || !SORTABLE_SYSTEM_DATE_COLUMNS.has(column) && !(systemColumns && Object.hasOwn(SYSTEM_COLUMN_KINDS, column)) && (!Object.hasOwn(model.columns, column) || model.columns[column].hidden === true)) {
110780
+ throw new AppRowValidationError([
110781
+ { path: "sort", message: "must be <column>:<asc|desc> for a known column" }
110782
+ ]);
110783
+ }
110784
+ if (model.columns[column]?.kind === "json") {
110785
+ throw new AppRowValidationError([{ path: "sort", message: "json columns cannot be sorted" }]);
110786
+ }
110787
+ rows.sort((a, b) => {
110788
+ const result = compareValues(rowValue(a, column), rowValue(b, column), dir, SORTABLE_SYSTEM_DATE_COLUMNS.has(column) || Object.hasOwn(model.columns, column) && model.columns[column].kind === "date");
110789
+ return result;
110790
+ });
110791
+ }
110792
+ const total = rows.length;
110793
+ return { rows: rows.slice(0, limit), total };
110794
+ }
110610
110795
  async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
110611
110796
  if (createAppRoute.match(req.method, pathSegments)) {
110612
110797
  if (enforceContentLengthCap(req, res, MAX_APP_BODY_BYTES) === BODY_TOO_LARGE)
@@ -110769,24 +110954,13 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
110769
110954
  json(res, { error: "invalid row query", issues }, 400);
110770
110955
  return true;
110771
110956
  }
110772
- const rows = (await listAppRows(parsed.params.id, parsed.params.model, filters.flatMap((filter) => typeof filter.value === "string" || typeof filter.value === "number" || typeof filter.value === "boolean" ? [{ column: filter.column, value: filter.value }] : []))).filter((row) => filters.every((filter) => rowValue(row, filter.column) === filter.value));
110773
- const sortRaw = parsed.query.sort;
110774
- if (sortRaw) {
110775
- const [column, dir, extra] = sortRaw.split(":");
110776
- if (extra !== undefined || !column || dir !== "asc" && dir !== "desc" || !SORTABLE_SYSTEM_DATE_COLUMNS.has(column) && (!Object.hasOwn(resolved.model.columns, column) || resolved.model.columns[column].hidden === true)) {
110777
- json(res, {
110778
- error: "invalid sort",
110779
- issues: [{ path: "sort", message: "must be <column>:<asc|desc> for a known column" }]
110780
- }, 400);
110781
- return true;
110782
- }
110783
- rows.sort((a, b) => {
110784
- const result = compareValues(rowValue(a, column), rowValue(b, column), dir, SORTABLE_SYSTEM_DATE_COLUMNS.has(column) || Object.hasOwn(resolved.model.columns, column) && resolved.model.columns[column].kind === "date");
110785
- return result;
110786
- });
110957
+ try {
110958
+ listRowsRoute.respond(res, 200, await selectAppRows(parsed.params.id, parsed.params.model, resolved.model, filters, parsed.query.sort, parsed.query.limit));
110959
+ } catch (error) {
110960
+ if (!(error instanceof AppRowValidationError))
110961
+ throw error;
110962
+ json(res, { error: "invalid sort", issues: error.issues }, 400);
110787
110963
  }
110788
- const total = rows.length;
110789
- listRowsRoute.respond(res, 200, { rows: rows.slice(0, parsed.query.limit ?? 200), total });
110790
110964
  return true;
110791
110965
  }
110792
110966
  if (getRowRoute.match(req.method, pathSegments)) {
@@ -110897,87 +111071,17 @@ async function handleApps(req, res, pathSegments, queryParams, myAgentId) {
110897
111071
  }
110898
111072
  if (definitionNeedsRepair(res, app))
110899
111073
  return true;
110900
- const actions = app.definition.actions;
110901
- if (!actions || !Object.hasOwn(actions, parsed.params.name)) {
110902
- jsonError(res, "app action not found", 404);
110903
- return true;
110904
- }
110905
- const action = actions[parsed.params.name];
110906
- const input = parsed.body.input ?? {};
110907
- if (action.kind === "script") {
110908
- const script = await getScriptById(action.scriptId);
110909
- if (!script) {
110910
- json(res, {
110911
- error: "invalid app action",
110912
- issues: [
110913
- {
110914
- path: `actions.${parsed.params.name}.scriptId`,
110915
- message: `script "${action.scriptId}" no longer exists`
110916
- }
110917
- ]
110918
- }, 400);
110919
- return true;
110920
- }
110921
- const runAsAgentId = getSavedScriptOwnerAgentId(script);
110922
- if (!runAsAgentId) {
110923
- jsonError(res, "agentId is required: this script has no owning agent to run as", 400);
110924
- return true;
110925
- }
110926
- const output = await runSavedScriptAsAgent({
110927
- script,
110928
- input: { ...action.args, ...input, app: { id: app.id }, caller },
110929
- agentId: runAsAgentId
110930
- });
110931
- const ok = output.exitCode === 0 && !output.error && !output.runtimeError;
110932
- const error = ok ? undefined : output.runtimeError ? `${output.runtimeError.name}: ${output.runtimeError.message}` : output.error ?? `Script exited with code ${output.exitCode}`;
110933
- runActionRoute.respond(res, 200, scrubObject({
110934
- ok,
110935
- result: output.result,
110936
- stdout: output.stdout,
110937
- ...error === undefined ? {} : { error },
110938
- durationMs: output.durationMs
110939
- }));
110940
- return true;
110941
- }
110942
- if (action.kind === "sync") {
110943
- const startedAt = Date.now();
110944
- const sync = await runAppSync({
110945
- appId: app.id,
110946
- ...action.model === undefined ? {} : { model: action.model },
110947
- ...action.source === undefined ? {} : { source: action.source },
110948
- invokedBy: actor
110949
- });
110950
- const durationMs = Date.now() - startedAt;
110951
- if (sync.issues && sync.issues.length > 0) {
110952
- json(res, { error: "invalid sync action", issues: sync.issues }, 400);
110953
- return true;
110954
- }
110955
- const error = syncPassError(sync);
110956
- runActionRoute.respond(res, 200, scrubObject({
110957
- ok: sync.ok,
110958
- result: { passes: sync.passes },
110959
- ...error === undefined ? {} : { error },
110960
- durationMs
110961
- }));
110962
- return true;
110963
- }
110964
- const lead = action.agentId ? null : await getLeadAgent2();
110965
- const taskPrompt = resolveTemplate("task.app.action", {
110966
- prompt: action.prompt,
110967
- app_id: app.id,
110968
- action_name: parsed.params.name,
110969
- input_json: JSON.stringify(input),
110970
- caller_json: JSON.stringify(caller)
111074
+ const output = await runAppAction({
111075
+ app,
111076
+ name: parsed.params.name,
111077
+ input: parsed.body.input,
111078
+ caller,
111079
+ actor
110971
111080
  });
110972
- const task = await createTaskWithSiblingAwareness(taskPrompt.text, {
110973
- source: "api",
110974
- agentId: action.agentId ?? lead?.id,
110975
- routingReason: action.agentId ? "human_pinned" : lead ? "skill" : undefined,
110976
- routingSource: action.agentId || lead ? "engine_default" : undefined,
110977
- key: normalizeAssetKey(`shared/app:${app.id}/action:${parsed.params.name}/`),
110978
- ...actor.startsWith("user:") ? { requestedByUserId: actor.slice("user:".length) } : {}
110979
- }, { origin: "app" });
110980
- runActionRoute.respond(res, 200, { ok: true, taskId: task.id, status: task.status });
111081
+ if (output.status === 200)
111082
+ runActionRoute.respond(res, 200, output.body);
111083
+ else
111084
+ json(res, output.body, output.status);
110981
111085
  return true;
110982
111086
  }
110983
111087
  if (syncAppRoute.match(req.method, pathSegments)) {
@@ -111720,6 +111824,137 @@ var registerAppRollbackTool = (server) => {
111720
111824
  });
111721
111825
  };
111722
111826
 
111827
+ // src/tools/app-rows.ts
111828
+ init_zod();
111829
+ init_db3();
111830
+ init_rbac();
111831
+ var base = { appId: string2().min(1), model: AppNameSchema };
111832
+ var rowId = string2().min(1);
111833
+ var values = record2(string2(), unknown());
111834
+ var equals = record2(string2(), union2([string2(), number2(), boolean()]));
111835
+ var limit = number2().int().min(1).max(1000);
111836
+ var rowOutput = { row: looseObject({}).optional() };
111837
+ var rowsOutput = { rows: array2(looseObject({})).optional() };
111838
+ function checkSize(value, max) {
111839
+ if (Buffer.byteLength(JSON.stringify(value), "utf8") > max) {
111840
+ throw new AppRowValidationError([
111841
+ { path: "values", message: `Row input exceeds ${max} bytes.` }
111842
+ ]);
111843
+ }
111844
+ }
111845
+ function rowFilters(model, equals = {}) {
111846
+ return Object.entries(equals).map(([column, value]) => {
111847
+ const declared = Object.hasOwn(model.columns, column) ? model.columns[column] : undefined;
111848
+ if (!declared && !Object.hasOwn(SYSTEM_COLUMN_KINDS, column) || declared?.hidden) {
111849
+ throw new AppRowValidationError([
111850
+ { path: `equals.${column}`, message: "Unknown or hidden column." }
111851
+ ]);
111852
+ }
111853
+ if (declared?.kind === "json") {
111854
+ throw new AppRowValidationError([
111855
+ { path: `equals.${column}`, message: "json columns cannot be filtered" }
111856
+ ]);
111857
+ }
111858
+ if (!validValue(declared ?? { kind: SYSTEM_COLUMN_KINDS[column] }, value)) {
111859
+ throw new AppRowValidationError([
111860
+ { path: `equals.${column}`, message: "Filter value must match the column kind." }
111861
+ ]);
111862
+ }
111863
+ return { column, value };
111864
+ });
111865
+ }
111866
+ function registerAppRowTools(server) {
111867
+ function register(name, description, shape, output, operation, readOnly = false) {
111868
+ createToolRegistrar(server)(name, {
111869
+ title: description,
111870
+ description,
111871
+ annotations: { readOnlyHint: readOnly },
111872
+ rbac: { permission: "app.use" },
111873
+ inputSchema: object2({ ...base, ...shape }),
111874
+ outputSchema: swarmToolOutputSchema(output)
111875
+ }, async (args, info) => {
111876
+ if (!info.agentId)
111877
+ return toolErr('Agent ID not found. Set the "X-Agent-ID" header.');
111878
+ const { appId, model: modelName } = object2(base).parse(args);
111879
+ const agent = await getAgentById2(info.agentId);
111880
+ const decision = can({
111881
+ principal: { kind: "agent", agentId: info.agentId, isLead: agent?.isLead ?? false },
111882
+ verb: "app.use",
111883
+ resource: { kind: "app", appId },
111884
+ source: "mcp"
111885
+ });
111886
+ if (!decision.allow)
111887
+ return toolErr(decision.reason);
111888
+ const app = await getApp(appId);
111889
+ if (!app)
111890
+ return toolErr("App not found.");
111891
+ if (appDefinitionNeedsRepair(app))
111892
+ return toolErr("App definition needs repair.", { data: { issues: app.definitionError } });
111893
+ if (!Object.hasOwn(app.definition.models, modelName))
111894
+ return toolErr("Model not found.");
111895
+ try {
111896
+ return await operation(args, app.definition.models[modelName], `agent:${info.agentId}`);
111897
+ } catch (error) {
111898
+ if (error instanceof AppRowValidationError)
111899
+ return toolErr(error.message, { data: { issues: error.issues } });
111900
+ if (error instanceof AppRowAppNotFoundError)
111901
+ return toolErr(error.message);
111902
+ throw error;
111903
+ }
111904
+ });
111905
+ }
111906
+ register("app-rows-list", "List app rows with equality filters, sorting, and a limit.", {
111907
+ equals: equals.optional(),
111908
+ sort: string2().optional(),
111909
+ limit: limit.optional()
111910
+ }, { ...rowsOutput, total: number2().optional() }, async (args, model) => {
111911
+ const data = await selectAppRows(args.appId, args.model, model, rowFilters(model, args.equals), args.sort, args.limit, true);
111912
+ return toolOk(`Found ${data.total} row(s).`, { data });
111913
+ }, true);
111914
+ register("app-row-get", "Get an app row.", { rowId }, rowOutput, async (args) => {
111915
+ const row = await getAppRow(args.appId, args.model, args.rowId);
111916
+ return row ? toolOk("Row retrieved.", { data: { row } }) : toolErr("Row not found.");
111917
+ }, true);
111918
+ register("app-row-create", "Create an app row.", { values }, rowOutput, async (args, model, actor) => {
111919
+ checkSize({ values: args.values }, MAX_APP_ROW_BODY_BYTES);
111920
+ const row = await createAppRow(args.appId, args.model, model, args.values, { actor });
111921
+ return toolOk("Row created.", { data: { row } });
111922
+ });
111923
+ register("app-rows-create", "Create up to 500 app rows within 10 MiB.", {
111924
+ rows: array2(values).min(1).max(500)
111925
+ }, rowsOutput, async (args, model, actor) => {
111926
+ checkSize({ rows: args.rows }, MAX_APP_BULK_ROWS_BODY_BYTES);
111927
+ for (const values of args.rows)
111928
+ checkSize({ values }, MAX_APP_ROW_BODY_BYTES);
111929
+ const rows = await createAppRows(args.appId, args.model, model, args.rows, { actor });
111930
+ return toolOk(`Created ${rows.length} row(s).`, { data: { rows } });
111931
+ });
111932
+ register("app-row-patch", "Patch an app row.", { rowId, values }, rowOutput, async (args, model, actor) => {
111933
+ checkSize({ values: args.values }, MAX_APP_ROW_BODY_BYTES);
111934
+ const row = await patchAppRow(args.appId, args.model, model, args.rowId, args.values, {
111935
+ actor
111936
+ });
111937
+ return row ? toolOk("Row updated.", { data: { row } }) : toolErr("Row not found.");
111938
+ });
111939
+ register("app-row-delete", "Delete an app row.", { rowId }, { ok: boolean().optional() }, async (args, model) => {
111940
+ const deleted = await deleteAppRow(args.appId, args.model, model, args.rowId);
111941
+ return deleted ? toolOk("Row deleted.", { data: { ok: true } }) : toolErr("Row not found.");
111942
+ });
111943
+ register("app-rows-delete", "Delete matching app rows. Supply at least one equality filter.", {
111944
+ equals: equals.refine((value) => Object.keys(value).length > 0, "Supply at least one equality filter."),
111945
+ limit: limit.optional()
111946
+ }, { deleted: number2().optional() }, async (args, model) => {
111947
+ const filters = rowFilters(model, args.equals);
111948
+ const { rows } = await selectAppRows(args.appId, args.model, model, filters, undefined, args.limit ?? 1000, true);
111949
+ const matches = (row) => rowMatchesFilters(row, filters);
111950
+ let deleted = 0;
111951
+ for (const row of rows)
111952
+ if (await deleteAppRow(args.appId, args.model, model, row.id, matches))
111953
+ deleted++;
111954
+ return toolOk(`Deleted ${deleted} row(s).`, { data: { deleted } });
111955
+ });
111956
+ }
111957
+
111723
111958
  // src/tools/app-sync.ts
111724
111959
  init_zod();
111725
111960
  init_db3();
@@ -118952,7 +119187,7 @@ var registerModelCatalogOverlayUpsertTool = (server) => {
118952
119187
  description: "Add or update hand-verified facts for one model (e.g. a launch models.dev has not listed yet). Overlay fields win over models.dev; overlay prices fill pricing-table gaps so cost recompute prices the model. The row auto-expires once models.dev matches every fact you set.",
118953
119188
  annotations: { idempotentHint: true },
118954
119189
  inputSchema: object2({
118955
- provider: string2().min(1).describe(`models.dev provider id: anthropic, openai, openrouter, amazon-bedrock, opencode, ${openAICompatibleProviderIds().join(", ")}.`),
119190
+ provider: string2().min(1).describe(`models.dev provider id: anthropic, openai, openrouter, amazon-bedrock, opencode, opencode-go, ${openAICompatibleProviderIds().join(", ")}.`),
118956
119191
  modelId: string2().min(1).describe("Model id as models.dev keys it (e.g. claude-opus-5-5)."),
118957
119192
  name: string2().optional().describe("Display name."),
118958
119193
  releaseDate: string2().optional().describe("Release date, YYYY-MM-DD."),
@@ -121700,7 +121935,7 @@ var varStorage = _localStorage;
121700
121935
 
121701
121936
  // node_modules/lib0/trait/equality.js
121702
121937
  var EqualityTraitSymbol = Symbol("Equality");
121703
- var equals = (a, b) => a === b || !!a?.[EqualityTraitSymbol]?.(b) || false;
121938
+ var equals2 = (a, b) => a === b || !!a?.[EqualityTraitSymbol]?.(b) || false;
121704
121939
 
121705
121940
  // node_modules/lib0/object.js
121706
121941
  var assign = Object.assign;
@@ -121726,7 +121961,7 @@ var every = (obj, f) => {
121726
121961
  return true;
121727
121962
  };
121728
121963
  var hasProperty = (obj, key) => Object.prototype.hasOwnProperty.call(obj, key);
121729
- var equalFlat = (a, b) => a === b || size(a) === size(b) && every(a, (val, key) => (val !== undefined || hasProperty(b, key)) && equals(b[key], val));
121964
+ var equalFlat = (a, b) => a === b || size(a) === size(b) && every(a, (val, key) => (val !== undefined || hasProperty(b, key)) && equals2(b[key], val));
121730
121965
  var freeze = Object.freeze;
121731
121966
  var deepFreeze = (o) => {
121732
121967
  for (const key in o) {
@@ -133789,7 +134024,7 @@ async function emitBudgetRefusalSideEffects(ctx, inserted) {
133789
134024
  console.warn(`[budget-refusal-notify] Failed to create follow-up task for budget refusal (task=${ctx.task.id.slice(0, 8)}): ${err}`);
133790
134025
  }
133791
134026
  }
133792
- import("./event-bus-101fenkh.js").then(({ workflowEventBus }) => {
134027
+ import("./event-bus-9vpk8gmq.js").then(({ workflowEventBus }) => {
133793
134028
  workflowEventBus.emit("task.budget_refused", {
133794
134029
  taskId: ctx.task.id,
133795
134030
  agentId: ctx.agentId,
@@ -135339,7 +135574,7 @@ var registerRetryWorkflowRunTool = (server) => {
135339
135574
  createToolRegistrar(server)("retry-workflow-run", {
135340
135575
  title: "Retry Workflow Run",
135341
135576
  annotations: { destructiveHint: false },
135342
- description: "Retry a failed workflow run from the beginning. The run must be in 'failed' status.",
135577
+ description: "Resume the same failed workflow run from its failed step(s); completed steps are not re-run. Retrying re-creates the failed node's side effects (e.g. an agent task), so check the target state first if that work was already done manually.",
135343
135578
  inputSchema: object2({
135344
135579
  runId: string2().uuid().describe("Workflow run ID to retry")
135345
135580
  }),
@@ -135803,6 +136038,8 @@ async function createServer(opts = {}) {
135803
136038
  }
135804
136039
  if (hasCapability("pages")) {
135805
136040
  registerAppGetTool(server);
136041
+ registerAppRowTools(server);
136042
+ registerAppActionRunTool(server);
135806
136043
  registerAppHistoryTool(server);
135807
136044
  registerAppDiffTool(server);
135808
136045
  registerAppListTool(server);