@desplega.ai/agent-swarm 1.172.0 → 1.173.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 (214) hide show
  1. package/dist/{acp-adapter-fpecx1g1.js → acp-adapter-ccm9xrep.js} +8 -8
  2. package/dist/{actions-pw87a1a8.js → actions-sgeyv08k.js} +44 -19
  3. package/dist/{amp-adapter-8jem2bc0.js → amp-adapter-gpxp3kc9.js} +1 -1
  4. package/dist/{anthropic-messages-8ee2f22q.js → anthropic-messages-r6czkjv1.js} +7 -7
  5. package/dist/{app-wmf0m843.js → app-km9qnv2f.js} +6 -4
  6. package/dist/{assistant-emp1e108.js → assistant-5r8tcvvd.js} +44 -22
  7. package/dist/{boot-reembed-4ymn9atn.js → boot-reembed-16rv9843.js} +4 -3
  8. package/dist/{boot-reembed-1de4f4aj.js → boot-reembed-swwzdgd7.js} +4 -3
  9. package/dist/{boot-scrub-sweep-adhk1s8c.js → boot-scrub-sweep-zkr6vkqb.js} +5 -4
  10. package/dist/{boot-seeds-8q637aew.js → boot-seeds-d8sp49t2.js} +7 -6
  11. package/dist/{claude-adapter-t26cv8a4.js → claude-adapter-yzzzh8jp.js} +9 -9
  12. package/dist/{claude-sdk-session-gsfsh662.js → claude-sdk-session-4whxere4.js} +9458 -9164
  13. package/dist/{cli-g4f5pj26.js → cli-0a7mm3zp.js} +92 -10
  14. package/dist/{cli-pj6x9qce.js → cli-0kxf81jj.js} +1 -1
  15. package/dist/{cli-kb4ehzx5.js → cli-1w0vj3gw.js} +4 -4
  16. package/dist/{cli-e0a9sk00.js → cli-3nxdmjrc.js} +1 -1
  17. package/dist/{cli-6jb2rf77.js → cli-42qhyvwx.js} +3 -3
  18. package/dist/{cli-esnpehf5.js → cli-5er5gjbm.js} +4 -4
  19. package/dist/{cli-04emfe2q.js → cli-5wpw4rab.js} +1 -1
  20. package/dist/{cli-aspcaef3.js → cli-6r2f7edk.js} +4 -4
  21. package/dist/{cli-xczpdp9e.js → cli-6thk4jz3.js} +1 -1
  22. package/dist/{cli-j6kpj9az.js → cli-7a93cv8c.js} +1458 -48
  23. package/dist/{cli-k46r9hmk.js → cli-94b48jhk.js} +2 -2
  24. package/dist/{cli-gp1rtyvk.js → cli-9xf7fdtp.js} +2 -2
  25. package/dist/{cli-qsztpfry.js → cli-anzdk0z4.js} +1 -1
  26. package/dist/{cli-cceskcvt.js → cli-b07hr3bt.js} +8 -8
  27. package/dist/{cli-c2pq2rjb.js → cli-bv2etw2y.js} +2 -2
  28. package/dist/{cli-hwwvy36w.js → cli-c3rk1v0x.js} +3 -3
  29. package/dist/{cli-tgpfnm6r.js → cli-fmhj1ehj.js} +53 -13
  30. package/dist/{cli-r8smj8b8.js → cli-jpc4r224.js} +1 -1
  31. package/dist/{cli-4nz8p1p5.js → cli-m89t9jdf.js} +5 -5
  32. package/dist/{cli-bf7485pm.js → cli-na2pxe4f.js} +1 -1
  33. package/dist/{cli-prrt9fa0.js → cli-ne7smj1b.js} +4 -4
  34. package/dist/{cli-cf69s3ew.js → cli-nwrdx840.js} +2 -2
  35. package/dist/cli-p0sg24zp.js +16 -0
  36. package/dist/{cli-gj81e47t.js → cli-phcqp1b9.js} +1 -1
  37. package/dist/{cli-5rv1j9ga.js → cli-qm1448f9.js} +51 -5
  38. package/dist/{cli-8hzfb6xz.js → cli-r0byd61h.js} +7 -7
  39. package/dist/{cli-nyhb1r6x.js → cli-r4fqfpwf.js} +3 -3
  40. package/dist/{cli-1hgat6pa.js → cli-rfs4vddv.js} +5 -5
  41. package/dist/{cli-ztrv9y21.js → cli-rfz2ve55.js} +861 -246
  42. package/dist/{cli-pstq9888.js → cli-s8z6x4b4.js} +22 -21
  43. package/dist/{cli-j1pmc07z.js → cli-saqyage0.js} +92 -16
  44. package/dist/{cli-zxm9p3x4.js → cli-srqq3gc5.js} +1 -1
  45. package/dist/{cli-9xsmdpdt.js → cli-tcc4wd5d.js} +136 -42
  46. package/dist/cli-v3zhnxsb.js +263 -0
  47. package/dist/{cli-388egyf6.js → cli-w1apjecb.js} +1 -1
  48. package/dist/{cli-g6t9texm.js → cli-wrh08zjd.js} +4 -4
  49. package/dist/{cli-8vs9trd4.js → cli-x119kdba.js} +1 -1
  50. package/dist/{cli-nv4zd0b9.js → cli-xc7p7s3g.js} +1 -1
  51. package/dist/cli.js +16 -16
  52. package/dist/{codex-adapter-m4tgdysy.js → codex-adapter-r3dn4fp5.js} +6 -6
  53. package/dist/{codex-session-runner-ymwzm6ea.js → codex-session-runner-fwt793h4.js} +6 -6
  54. package/dist/{commands-n0hshcvs.js → commands-z8fq9qna.js} +14 -4
  55. package/dist/{controllers-connect-y07cqcvy.js → controllers-connect-3mf2btyj.js} +21 -19
  56. package/dist/{db-4w7tmt1g.js → db-qfpq4bt7.js} +4 -3
  57. package/dist/{db-hkqvrdcb.js → db-yyhqqrbf.js} +5 -4
  58. package/dist/{dispatcher-5sd69y14.js → dispatcher-x0x7qfcq.js} +20 -18
  59. package/dist/{dsh-adapter-2h8m4cab.js → dsh-adapter-34etvb5m.js} +1 -1
  60. package/dist/external-channel-h1fjecwe.js +51 -0
  61. package/dist/{grok-adapter-8m9yqzbq.js → grok-adapter-e7mr287e.js} +9 -9
  62. package/dist/{handlers-s20xr10r.js → handlers-znb9n7d4.js} +23 -21
  63. package/dist/{heartbeat-3k31q4g2.js → heartbeat-bm4qkn8d.js} +22 -20
  64. package/dist/{hook-gdn6a2fn.js → hook-254r4mza.js} +7 -7
  65. package/dist/{hook-ygwerrdh.js → hook-xaa3q80s.js} +8 -8
  66. package/dist/{http-jdteeg81.js → http-3dgrgp8y.js} +135 -64
  67. package/dist/{index-6ksewd5y.js → index-2ybk7khy.js} +618 -120
  68. package/dist/{index-tsszt7g9.js → index-bdsqa799.js} +22 -20
  69. package/dist/{index-e0snym4t.js → index-fx3jqq1e.js} +20 -18
  70. package/dist/{index-vm3bm9t7.js → index-g2byveez.js} +20 -18
  71. package/dist/{index-ffqzqgwb.js → index-jd7sejm2.js} +4 -3
  72. package/dist/{keepalive-jekc896t.js → keepalive-6ywhpja1.js} +6 -5
  73. package/dist/{lead-4k9s9szx.js → lead-cw45n21s.js} +32 -30
  74. package/dist/{maintenance-shazch4n.js → maintenance-ss1a1ge9.js} +4 -3
  75. package/dist/node-c9we95xf.js +1 -1
  76. package/dist/{oauth-refresh-sweep-5gb36kn8.js → oauth-refresh-sweep-3c6f8vyy.js} +5 -4
  77. package/dist/{onboard-ydrbnvww.js → onboard-8hzdhc1k.js} +2 -2
  78. package/dist/{opencode-adapter-5zh0he20.js → opencode-adapter-qbchbcfz.js} +6 -6
  79. package/dist/{otel-impl-6pf5cv86.js → otel-impl-e6mnvc4v.js} +7 -2
  80. package/dist/{pi-mono-adapter-ef9wwx9m.js → pi-mono-adapter-3c9g9snh.js} +6 -6
  81. package/dist/{pricing-refresh-s52nsa5q.js → pricing-refresh-gedkjdw0.js} +6 -5
  82. package/dist/{rbac-roles-aq3msh4e.js → rbac-roles-dt4vh1yy.js} +4 -3
  83. package/dist/{rbac-roles-q5gb5e8v.js → rbac-roles-eszdg6pm.js} +5 -4
  84. package/dist/{render-v2-pd1rg54q.js → render-v2-907cy6sa.js} +6 -4
  85. package/dist/{resume-gw4a2c6v.js → resume-42stcaz0.js} +11 -9
  86. package/dist/{setup-jda1ksdh.js → setup-adbc1c10.js} +2 -2
  87. package/dist/{virtual-modules-b3ga2m65.js → virtual-modules-rtmt494q.js} +3 -3
  88. package/dist/{work-objects-tb7ycye8.js → work-objects-wpj8ck95.js} +28 -21
  89. package/dist/{worker-njjccz5d.js → worker-bzdra9rf.js} +32 -30
  90. package/openapi.json +423 -7
  91. package/package.json +4 -4
  92. package/src/apps/catalog.generated.json +1309 -53
  93. package/src/apps/page-validator.ts +93 -31
  94. package/src/azure-devops/api.ts +94 -18
  95. package/src/azure-devops/auth.ts +32 -0
  96. package/src/azure-devops/boards-sync.ts +708 -0
  97. package/src/azure-devops/handlers.ts +52 -8
  98. package/src/azure-devops/html.ts +26 -0
  99. package/src/azure-devops/index.ts +15 -0
  100. package/src/azure-devops/templates.ts +86 -0
  101. package/src/azure-devops/types.ts +65 -1
  102. package/src/be/db.ts +22 -6
  103. package/src/be/migrations/213_script_connections_sql.sql +79 -0
  104. package/src/be/script-connections.ts +47 -8
  105. package/src/be/seed-skills/bundled-files.generated.json +10 -0
  106. package/src/be/seed-skills/index.ts +3 -0
  107. package/src/be/sql-connections.ts +118 -0
  108. package/src/be/swarm-config-guard.ts +1 -0
  109. package/src/commands/profile-sync.ts +5 -3
  110. package/src/commands/runner.ts +6 -2
  111. package/src/http/mcp-oauth.ts +6 -13
  112. package/src/http/pages-public.ts +3 -2
  113. package/src/http/pages.ts +2 -1
  114. package/src/http/route-def.ts +7 -6
  115. package/src/http/script-connection-proxy.ts +51 -4
  116. package/src/http/script-connections.ts +5 -2
  117. package/src/http/session-cost-recompute.ts +12 -2
  118. package/src/http/session-data.ts +4 -0
  119. package/src/http/webhooks.ts +24 -1
  120. package/src/jira/adf.ts +3 -1
  121. package/src/kv-reserved-namespaces.ts +2 -0
  122. package/src/oauth/mcp-wrapper.ts +10 -6
  123. package/src/otel-impl.ts +2 -1
  124. package/src/prompts/base-prompt.ts +3 -3
  125. package/src/providers/acp-targets.ts +1 -1
  126. package/src/providers/amp-adapter.ts +1 -1
  127. package/src/providers/claude-adapter.ts +27 -2
  128. package/src/providers/claude-flag-settings.ts +121 -0
  129. package/src/providers/claude-sdk-session.ts +7 -0
  130. package/src/providers/dsh-adapter.ts +1 -1
  131. package/src/providers/opencode-adapter.ts +26 -12
  132. package/src/providers/opencode-billing.ts +86 -0
  133. package/src/providers/opencode-swarm-plugin.ts +20 -0
  134. package/src/providers/pricing-sources.md +4 -1
  135. package/src/providers/types.ts +5 -0
  136. package/src/scripts-runtime/api-client.ts +15 -1
  137. package/src/scripts-runtime/api-types.ts +9 -1
  138. package/src/scripts-runtime/ctx.ts +1 -1
  139. package/src/scripts-runtime/mcp-client.ts +30 -19
  140. package/src/slack/actions.ts +29 -1
  141. package/src/slack/app.ts +14 -2
  142. package/src/slack/assistant.ts +36 -2
  143. package/src/slack/channel-join.ts +3 -16
  144. package/src/slack/commands.ts +9 -1
  145. package/src/slack/external-channel-egress.ts +113 -0
  146. package/src/slack/external-channel.ts +309 -0
  147. package/src/slack/handlers.ts +61 -0
  148. package/src/slack/render-v2.ts +40 -47
  149. package/src/slack/work-objects.ts +5 -0
  150. package/src/tasks/context-key.ts +34 -1
  151. package/src/telemetry.ts +2 -1
  152. package/src/tests/apps-catalog-feedback.test.ts +310 -0
  153. package/src/tests/apps-catalog-inputs.test.ts +70 -0
  154. package/src/tests/apps-catalog-table.test.ts +113 -0
  155. package/src/tests/azure-devops-boards-sync.test.ts +584 -0
  156. package/src/tests/azure-devops-html.test.ts +13 -0
  157. package/src/tests/azure-devops-webhook-malformed.test.ts +4 -0
  158. package/src/tests/claude-adapter-binary.test.ts +139 -0
  159. package/src/tests/claude-flag-settings.test.ts +106 -0
  160. package/src/tests/claude-sdk-lifecycle.test.ts +142 -1
  161. package/src/tests/claude-sdk-process.fixture.ts +7 -0
  162. package/src/tests/context-key.test.ts +32 -0
  163. package/src/tests/deferred-task-wake.test.ts +52 -4
  164. package/src/tests/docs-index-footprint.test.js +3 -3
  165. package/src/tests/dsh-adapter.test.ts +1 -1
  166. package/src/tests/fixtures/azure-boards/workitem.commented.json +89 -0
  167. package/src/tests/fixtures/azure-boards/workitem.created.json +81 -0
  168. package/src/tests/fixtures/azure-boards/workitem.deleted.json +70 -0
  169. package/src/tests/fixtures/azure-boards/workitem.restored.json +82 -0
  170. package/src/tests/fixtures/azure-boards/workitem.updated.json +130 -0
  171. package/src/tests/fixtures/catalog-feedback-definition.json.txt +860 -0
  172. package/src/tests/fixtures/catalog-inputs-definition.json.txt +910 -0
  173. package/src/tests/fixtures/catalog-table-definition.json.txt +468 -0
  174. package/src/tests/fixtures/runner-identity-refresh.ts +3 -0
  175. package/src/tests/node-env-runtime.test.ts +98 -0
  176. package/src/tests/opencode-adapter.test.ts +132 -1
  177. package/src/tests/opencode-billing.test.ts +28 -0
  178. package/src/tests/runner-identity-refresh.test.ts +3 -0
  179. package/src/tests/script-connections-sql.test.ts +675 -0
  180. package/src/tests/script-connections.test.ts +5 -1
  181. package/src/tests/session-cost-recompute-unit.test.ts +48 -0
  182. package/src/tests/slack-channel-join.test.ts +4 -1
  183. package/src/tests/slack-external-channel-config.test.ts +65 -0
  184. package/src/tests/slack-external-channel-egress.test.ts +237 -0
  185. package/src/tests/slack-external-channel-guard.test.ts +280 -0
  186. package/src/tests/slack-external-channel-tools.test.ts +173 -0
  187. package/src/tests/slack-external-channel.test.ts +370 -0
  188. package/src/tests/slack-render-v2.test.ts +86 -10
  189. package/src/tests/spec-base-url.test.ts +16 -1
  190. package/src/tests/vendored-openapi.test.ts +16 -1
  191. package/src/tools/defer-task.ts +17 -0
  192. package/src/tools/slack-post.ts +6 -0
  193. package/src/tools/slack-read.ts +8 -0
  194. package/src/tools/slack-reply.ts +6 -0
  195. package/src/tools/slack-start-thread.ts +6 -0
  196. package/src/tools/slack-update.ts +6 -0
  197. package/src/tools/slack-upload-file.ts +6 -0
  198. package/src/utils/node-env.ts +24 -0
  199. package/templates/skills/apps/SKILL.md +742 -0
  200. package/templates/skills/apps/content.md +52 -21
  201. package/templates/skills/qa-loom/config.json +14 -0
  202. package/templates/skills/qa-loom/content.md +187 -0
  203. package/templates/skills/qa-loom/files/build-loom.mjs +221 -0
  204. package/templates/skills/qa-loom/files/run-qa.sh +57 -0
  205. package/templates/skills/slack-interaction/content.md +4 -0
  206. package/dist/{azure-openai-responses-ap1gwxgr.js → azure-openai-responses-ygfreq4t.js} +5 -5
  207. package/dist/{cli-4fnb6884.js → cli-h7k0xtry.js} +3 -3
  208. package/dist/{cli-5rqrj7q0.js → cli-pw7ebjdt.js} +0 -0
  209. package/dist/{google-generative-ai-7pavrbv7.js → google-generative-ai-szdxbpqg.js} +1 -1
  210. package/dist/{google-vertex-3f1jk41f.js → google-vertex-qzw3p36d.js} +1 -1
  211. package/dist/{openai-codex-responses-33qhkkdy.js → openai-codex-responses-3bk0grnr.js} +4 -4
  212. package/dist/{openai-completions-s88xm3ns.js → openai-completions-5d4jpakc.js} +9 -9
  213. package/dist/{openai-responses-7xd2f2e2.js → openai-responses-krb51f59.js} +5 -5
  214. package/dist/{pi-messages-xszk613n.js → pi-messages-x9gzynm1.js} +3 -3
@@ -12,7 +12,7 @@ import {
12
12
  generateRandomCodeVerifier,
13
13
  generateRandomState,
14
14
  oauthAppRowToProviderConfig
15
- } from "./cli-388egyf6.js";
15
+ } from "./cli-w1apjecb.js";
16
16
  import {
17
17
  CredentialBroker,
18
18
  DEFAULT_CREDENTIAL_BINDINGS,
@@ -46,7 +46,7 @@ import {
46
46
  updateAuthorizationTokens,
47
47
  upsertAuthorization,
48
48
  upsertSwarmConfig
49
- } from "./cli-tgpfnm6r.js";
49
+ } from "./cli-fmhj1ehj.js";
50
50
  import {
51
51
  defaultAssetKey,
52
52
  init_key
@@ -69,6 +69,10 @@ import {
69
69
  union,
70
70
  unknown
71
71
  } from "./cli-w5e1d1vv.js";
72
+ import {
73
+ init_node_env,
74
+ isDevOrTestNodeEnv
75
+ } from "./cli-p0sg24zp.js";
72
76
  import {
73
77
  init_env_flag,
74
78
  isEnvFlagEnabled
@@ -175854,6 +175858,7 @@ init_oauth();
175854
175858
 
175855
175859
  // src/oauth/mcp-wrapper.ts
175856
175860
  init_env_flag();
175861
+ init_node_env();
175857
175862
  init_secret_scrubber();
175858
175863
  var PRIVATE_IPV4_BLOCKS = [
175859
175864
  { prefix: "10.", mask: 8 },
@@ -175932,22 +175937,21 @@ function assertUrlSafe(rawUrl, opts = {}) {
175932
175937
  return parsed;
175933
175938
  }
175934
175939
  function publicEndpointSsrfOptions() {
175935
- const env = "development";
175936
- const dev = env === "development" || env === "test" || process.env.ALLOW_PRIVATE_NETWORK_URLS === "true";
175940
+ const dev = isDevOrTestNodeEnv() || process.env.ALLOW_PRIVATE_NETWORK_URLS === "true";
175937
175941
  return {
175938
175942
  allowPrivateHosts: dev,
175939
175943
  allowInsecure: dev
175940
175944
  };
175941
175945
  }
175942
- function defaultSsrfOptions() {
175946
+ function mcpOAuthSsrfOptions() {
175943
175947
  return {
175944
175948
  allowPrivateHosts: isEnvFlagEnabled("MCP_OAUTH_ALLOW_PRIVATE_HOSTS", false),
175945
- allowInsecure: true
175949
+ allowInsecure: isDevOrTestNodeEnv()
175946
175950
  };
175947
175951
  }
175948
175952
  var DEFAULT_FETCH_TIMEOUT_MS = 15000;
175949
175953
  async function safeFetch(url, init, timeoutMs = DEFAULT_FETCH_TIMEOUT_MS) {
175950
- assertUrlSafe(url, defaultSsrfOptions());
175954
+ assertUrlSafe(url, mcpOAuthSsrfOptions());
175951
175955
  return fetch(url, { ...init, signal: init?.signal ?? AbortSignal.timeout(timeoutMs) });
175952
175956
  }
175953
175957
  async function discoverProtectedResourceMetadata(resourceUrl) {
@@ -176801,6 +176805,82 @@ async function callMcpServerTool(serverId, tool, args, context = {}) {
176801
176805
  return client.callToolRaw(tool, args);
176802
176806
  }
176803
176807
 
176808
+ // src/be/sql-connections.ts
176809
+ init_db2();
176810
+ init_secret_scrubber();
176811
+ var SQL_MAX_ROWS = 1000;
176812
+ var SQL_MAX_BYTES = 5 * 1024 * 1024;
176813
+ var SQL_FETCH_BATCH = 100;
176814
+ function assertPostgresDsn(dsn) {
176815
+ if (!URL.canParse(dsn) || !["postgres:", "postgresql:"].includes(new URL(dsn).protocol)) {
176816
+ throw new Error("SQL connection DSN must be a postgres:// or postgresql:// URL.");
176817
+ }
176818
+ }
176819
+ async function resolveSqlDsn(connection, agentId) {
176820
+ const key = connection.authConfigKey;
176821
+ if (!key)
176822
+ throw new Error("SQL connection has no DSN config key.");
176823
+ const repoId = connection.scope === "repo" ? connection.scopeId ?? undefined : undefined;
176824
+ const dsn = (await getResolvedConfig(agentId, repoId)).find((c) => c.key === key)?.value;
176825
+ if (!dsn)
176826
+ throw new Error(`SQL connection DSN '${key}' is not set.`);
176827
+ registerVolatileSecret(dsn, key);
176828
+ if (URL.canParse(dsn))
176829
+ registerVolatileSecret(decodeURIComponent(new URL(dsn).password), key);
176830
+ assertPostgresDsn(dsn);
176831
+ return dsn;
176832
+ }
176833
+ var asTemplate = (text) => Object.assign([text], { raw: [text] });
176834
+ var defaultExecutor = async (dsn, query, params, take) => {
176835
+ const sql = new Bun.SQL({
176836
+ adapter: "postgres",
176837
+ url: dsn,
176838
+ max: 1,
176839
+ connectionTimeout: 10,
176840
+ connection: { default_transaction_read_only: "on", statement_timeout: 30000 }
176841
+ });
176842
+ try {
176843
+ await sql.begin("read only", async (tx) => {
176844
+ const declare = `declare swarm_sql_cursor no scroll cursor for ${query}`;
176845
+ await (params.length > 0 ? tx.unsafe(declare, params) : tx(asTemplate(declare)));
176846
+ const fetchNext = asTemplate(`fetch ${SQL_FETCH_BATCH} from swarm_sql_cursor`);
176847
+ for (;; ) {
176848
+ const batch = [...await tx(fetchNext)];
176849
+ if (!take(batch) || batch.length < SQL_FETCH_BATCH)
176850
+ return;
176851
+ }
176852
+ });
176853
+ } finally {
176854
+ await sql.close();
176855
+ }
176856
+ };
176857
+ var sqlExecutorForTesting = null;
176858
+ async function runReadOnlyQuery(dsn, query, params = []) {
176859
+ const rows = [];
176860
+ let bytes = 0;
176861
+ let truncated = false;
176862
+ const take = (batch) => {
176863
+ for (const row of batch) {
176864
+ const size = Buffer.byteLength(JSON.stringify(row, (_, v) => typeof v === "bigint" ? v.toString() : v));
176865
+ if (rows.length >= SQL_MAX_ROWS || bytes + size > SQL_MAX_BYTES) {
176866
+ truncated = true;
176867
+ return false;
176868
+ }
176869
+ bytes += size;
176870
+ rows.push(row);
176871
+ }
176872
+ return true;
176873
+ };
176874
+ try {
176875
+ await (sqlExecutorForTesting ?? defaultExecutor)(dsn, query, params, take);
176876
+ return { rows, rowCount: rows.length, truncated };
176877
+ } catch (err) {
176878
+ const code = err.errno;
176879
+ const message = err instanceof Error ? err.message : String(err);
176880
+ throw new Error(scrubSecrets(typeof code === "string" ? `${message} (SQLSTATE ${code})` : message));
176881
+ }
176882
+ }
176883
+
176804
176884
  // src/be/vendored-openapi.ts
176805
176885
  import { readFileSync } from "node:fs";
176806
176886
  import path from "node:path";
@@ -176899,6 +176979,9 @@ var ConnectionAuthInputSchema = exports_external.discriminatedUnion("type", [
176899
176979
  hosts: authHostsSchema
176900
176980
  })
176901
176981
  ]);
176982
+ var SqlDsnInputSchema = exports_external.object({ secret: authSecretSchema, configKey: authConfigKeySchema }).refine((dsn) => dsn.secret === undefined !== (dsn.configKey === undefined), {
176983
+ message: "Provide exactly one of `secret` or `configKey` for the SQL DSN."
176984
+ });
176902
176985
  function parseJsonArray(value) {
176903
176986
  try {
176904
176987
  const parsed = JSON.parse(value);
@@ -177620,7 +177703,9 @@ function assertConfigKeyNotReserved(auth) {
177620
177703
  function derivedInlineSecretKey(connection) {
177621
177704
  if (!connection)
177622
177705
  return null;
177623
- if (connection.authType === "none" || connection.authType === "oauth")
177706
+ if (connection.authType === "oauth")
177707
+ return null;
177708
+ if (connection.authType === "none" && connection.kind !== "sql")
177624
177709
  return null;
177625
177710
  const key = connection.authConfigKey;
177626
177711
  return key && DERIVED_INLINE_SECRET_KEY.test(key) ? key : null;
@@ -177781,6 +177866,9 @@ async function upsertScriptConnection(data) {
177781
177866
  if (data.kind === "mcp" && data.auth && data.auth.type !== "none") {
177782
177867
  throw new Error("MCP connections resolve auth through their MCP server; `auth` is not supported.");
177783
177868
  }
177869
+ if (data.kind === "sql" && data.auth && data.auth.type !== "none") {
177870
+ throw new Error("SQL connections authenticate through their DSN; `auth` is not supported.");
177871
+ }
177784
177872
  assertConfigKeyNotReserved(data.auth);
177785
177873
  if (data.kind === "openapi" && existingConnection?.openapiSpecJson && data.openapiSpecJson == null && data.openapiSpecUrl == null && data.openapiSpecSource == null) {
177786
177874
  openapiSpecJson = existingConnection.openapiSpecJson;
@@ -177790,7 +177878,7 @@ async function upsertScriptConnection(data) {
177790
177878
  openapiSpecFetchedAt = existingConnection.openapiSpecFetchedAt;
177791
177879
  }
177792
177880
  const explicitLegacyBinding = data.auth === undefined && data.credentialBindingId !== undefined;
177793
- const authIntent = data.kind === "mcp" || explicitLegacyBinding ? { type: "none" } : data.auth ?? reconstructAuthFromConnection(existingConnection);
177881
+ const authIntent = data.kind === "mcp" || data.kind === "sql" || explicitLegacyBinding ? { type: "none" } : data.auth ?? reconstructAuthFromConnection(existingConnection);
177794
177882
  let derived = null;
177795
177883
  const explicitBinding = explicitLegacyBinding && data.credentialBindingId ? await getCredentialBindingById(data.credentialBindingId) : null;
177796
177884
  const explicitBindingCredential = explicitBinding ? {
@@ -177913,17 +178001,41 @@ async function upsertScriptConnection(data) {
177913
178001
  generatedRuntimeJson = artifacts.generatedRuntimeJson;
177914
178002
  generatedAt = now;
177915
178003
  }
178004
+ let sqlDsnKey = null;
178005
+ let sqlSecretWrite = null;
178006
+ if (data.kind === "sql") {
178007
+ if (data.sqlDsn?.secret !== undefined) {
178008
+ assertPostgresDsn(data.sqlDsn.secret);
178009
+ sqlDsnKey = `connection.${normalizedSlug}.secret`;
178010
+ sqlSecretWrite = { scope, scopeId, key: sqlDsnKey, value: data.sqlDsn.secret };
178011
+ } else if (data.sqlDsn?.configKey) {
178012
+ assertConfigKeyNotReserved({ type: "bearer", configKey: data.sqlDsn.configKey });
178013
+ sqlDsnKey = data.sqlDsn.configKey;
178014
+ } else {
178015
+ sqlDsnKey = existingConnection?.kind === "sql" ? existingConnection.authConfigKey : null;
178016
+ }
178017
+ if (!sqlDsnKey)
178018
+ throw new Error("SQL connections require `dsn.secret` or `dsn.configKey`.");
178019
+ generatedRuntimeJson = JSON.stringify({ slug: normalizedSlug, kind: "sql", connectionId });
178020
+ generatedTypes = `export interface ${pascal(normalizedSlug)}Api {
178021
+ /** One read-only statement; pass values via params ($1, $2, ...). */
178022
+ query<T = Record<string, JsonValue>>(sql: string, params?: JsonValue[]): Promise<{ rows: T[]; rowCount: number; truncated: boolean }>;
178023
+ }`;
178024
+ generatedAt = now;
178025
+ }
177916
178026
  if (data.kind !== "graphql") {
177917
178027
  allowedHosts = data.allowedHosts ?? (effectiveBaseUrl ? [new URL(effectiveBaseUrl).hostname] : []);
177918
178028
  }
177919
178029
  const oldDerivedSecretKey = derivedInlineSecretKey(existingConnection);
177920
- const newReferencedConfigKey = derived?.configKey ?? explicitBinding?.configKey ?? null;
178030
+ const newReferencedConfigKey = derived?.configKey ?? explicitBinding?.configKey ?? sqlDsnKey ?? null;
177921
178031
  let supersededSecretDeleted = false;
177922
178032
  const writeConnectionAndBinding = () => getDbClient().transaction(async (tx) => {
177923
178033
  await tx.run("PRAGMA defer_foreign_keys = ON");
177924
178034
  if (derived?.secretWrite) {
177925
178035
  await upsertSwarmConfig({ ...derived.secretWrite, isSecret: true });
177926
178036
  }
178037
+ if (sqlSecretWrite)
178038
+ await upsertSwarmConfig({ ...sqlSecretWrite, isSecret: true });
177927
178039
  if (oldDerivedSecretKey && oldDerivedSecretKey !== newReferencedConfigKey) {
177928
178040
  await deleteManagedConnectionSecret({
177929
178041
  scope: existingConnection?.scope ?? scope,
@@ -177964,6 +178076,8 @@ async function upsertScriptConnection(data) {
177964
178076
  credentialBindingId = existingConnection && existingManaged && existingConnection.credentialBindingId === existingManaged.id ? null : existingConnection?.credentialBindingId ?? null;
177965
178077
  authCols = NONE_AUTH_COLUMNS;
177966
178078
  }
178079
+ if (sqlDsnKey)
178080
+ authCols = { ...NONE_AUTH_COLUMNS, authConfigKey: sqlDsnKey };
177967
178081
  const params = [
177968
178082
  normalizedSlug,
177969
178083
  data.displayName ?? null,
@@ -178027,8 +178141,9 @@ async function upsertScriptConnection(data) {
178027
178141
  return row2;
178028
178142
  });
178029
178143
  const row = await writeConnectionAndBinding();
178030
- if (derived?.secretWrite || supersededSecretDeleted)
178144
+ if (derived?.secretWrite || sqlSecretWrite || supersededSecretDeleted) {
178031
178145
  refreshSecretScrubberCache();
178146
+ }
178032
178147
  return connectionFromRow(row);
178033
178148
  }
178034
178149
  async function refreshScriptConnection(id, userId, callerAgentId) {
@@ -178143,7 +178258,7 @@ async function deleteScriptConnection(id) {
178143
178258
  return deleted;
178144
178259
  }
178145
178260
  function getScriptApiConnectionDescriptors(context = {}) {
178146
- return listScriptConnections(context).filter((connection) => connection.kind === "openapi" || connection.kind === "graphql").map((connection) => {
178261
+ return listScriptConnections(context).filter((connection) => ["openapi", "graphql", "sql"].includes(connection.kind)).map((connection) => {
178147
178262
  if (!connection.generatedRuntimeJson)
178148
178263
  return null;
178149
178264
  try {
@@ -178165,7 +178280,7 @@ function getScriptMcpConnectionDescriptors(context = {}) {
178165
178280
  }).filter((descriptor) => Boolean(descriptor));
178166
178281
  }
178167
178282
  function getScriptApiTypes(context = {}) {
178168
- const connections = listScriptConnections(context).filter((connection) => connection.kind === "openapi" || connection.kind === "graphql");
178283
+ const connections = listScriptConnections(context).filter((connection) => ["openapi", "graphql", "sql"].includes(connection.kind));
178169
178284
  const blocks = connections.filter((connection) => connection.generatedTypes).map((connection) => connection.generatedTypes);
178170
178285
  if (blocks.length === 0)
178171
178286
  return `export interface ScriptApiRegistry {}
@@ -178436,6 +178551,16 @@ var catalog_generated_default = {
178436
178551
  "Metric",
178437
178552
  "Alert",
178438
178553
  "Badge",
178554
+ "Icon",
178555
+ "Progress",
178556
+ "EmptyState",
178557
+ "CopyButton",
178558
+ "Kbd",
178559
+ "Skeleton",
178560
+ "Spinner",
178561
+ "AvatarStack",
178562
+ "Section",
178563
+ "Chips",
178439
178564
  "Table",
178440
178565
  "Form",
178441
178566
  "Drawer",
@@ -178449,6 +178574,7 @@ var catalog_generated_default = {
178449
178574
  actionTypes: [
178450
178575
  "swarm.sdk",
178451
178576
  "swarm.call",
178577
+ "ui.toast",
178452
178578
  "app.mutate",
178453
178579
  "app.refresh",
178454
178580
  "app.action",
@@ -178456,7 +178582,7 @@ var catalog_generated_default = {
178456
178582
  ],
178457
178583
  components: {
178458
178584
  Stack: {
178459
- description: "THE primary layout primitive — a flex column (default) or row of its children. `gap`/`padding` use the shared spacing scale (none|xs|sm|md|lg|xl, default gap md); `align` is the cross axis, `justify` the main axis, `wrap` lets a row reflow. For rows, set `collapseBelow` (sm|md|lg) so the row stacks vertically on narrow viewports — filter bars should always set it. Use this as the page root and for every section; `Container` is the legacy 2-prop alias kept for older pages.",
178585
+ description: "THE primary layout primitive — a flex column (default) or row of its children. `gap`/`padding` use the shared spacing scale (none|xs|sm|md|lg|xl, default gap md); `align` is the cross axis, `justify` the main axis, `wrap` lets a row reflow. For rows, set `collapseBelow` (sm|md|lg) so the row stacks vertically on narrow viewports — filter bars should always set it. `motion` (rise|fade|none, default rise) is the entrance of the direct children on first paint: a 200ms fade plus a 4px rise, staggered 30ms; it never replays on data polls, nested Stacks inherit the parent's entrance, and reduced-motion viewers get a short fade. Use this as the page root and for every section; `Container` is the legacy 2-prop alias kept for older pages.",
178460
178586
  slots: ["default"],
178461
178587
  props: {
178462
178588
  $schema: "http://json-schema.org/draft-07/schema#",
@@ -178488,6 +178614,10 @@ var catalog_generated_default = {
178488
178614
  collapseBelow: {
178489
178615
  type: "string",
178490
178616
  enum: ["sm", "md", "lg"]
178617
+ },
178618
+ motion: {
178619
+ type: "string",
178620
+ enum: ["rise", "fade", "none"]
178491
178621
  }
178492
178622
  },
178493
178623
  additionalProperties: false
@@ -178591,7 +178721,7 @@ var catalog_generated_default = {
178591
178721
  }
178592
178722
  },
178593
178723
  Tabs: {
178594
- description: 'Tabbed sections. POSITIONAL children: children[i] is the body of tabs[i], so declare exactly as many children as tabs, in the same order. Only the active tab is visible but every child stays mounted, so polled Tables in background tabs keep their data warm. The active key is mirrored into state at `/ui/<id>/tab`, so other components can bind `{ "$state": "/ui/<id>/tab" }`. `defaultTab` picks the initial key (defaults to the first tab).',
178724
+ description: 'Tabbed sections. POSITIONAL children: children[i] is the body of tabs[i], so declare exactly as many children as tabs, in the same order. Only the active tab is visible but every child stays mounted, so polled Tables in background tabs keep their data warm. The active key is mirrored into state at `/ui/<id>/tab`, so other components can bind `{ "$state": "/ui/<id>/tab" }`. `defaultTab` picks the initial key (defaults to the first tab). Tab entries take an optional `icon` and `count` (a small count pill; a literal or a bound number). `variant: "segmented"` renders a compact segmented control instead of the tab strip (same state and warm panels).',
178595
178725
  slots: ["default"],
178596
178726
  props: {
178597
178727
  $schema: "http://json-schema.org/draft-07/schema#",
@@ -178611,6 +178741,54 @@ var catalog_generated_default = {
178611
178741
  },
178612
178742
  label: {
178613
178743
  type: "string"
178744
+ },
178745
+ icon: {
178746
+ type: "string",
178747
+ enum: [
178748
+ "plus",
178749
+ "refresh-cw",
178750
+ "search",
178751
+ "filter",
178752
+ "download",
178753
+ "upload",
178754
+ "external-link",
178755
+ "copy",
178756
+ "check",
178757
+ "x",
178758
+ "trash-2",
178759
+ "pencil",
178760
+ "eye",
178761
+ "calendar",
178762
+ "clock",
178763
+ "user",
178764
+ "users",
178765
+ "bot",
178766
+ "git-pull-request",
178767
+ "git-branch",
178768
+ "github",
178769
+ "slack",
178770
+ "mail",
178771
+ "link",
178772
+ "file-text",
178773
+ "folder",
178774
+ "database",
178775
+ "zap",
178776
+ "sparkles",
178777
+ "flag",
178778
+ "star",
178779
+ "tag",
178780
+ "alert-triangle",
178781
+ "info",
178782
+ "circle-check",
178783
+ "trending-up",
178784
+ "trending-down",
178785
+ "dollar-sign",
178786
+ "activity",
178787
+ "rocket"
178788
+ ]
178789
+ },
178790
+ count: {
178791
+ type: "number"
178614
178792
  }
178615
178793
  },
178616
178794
  required: ["key"],
@@ -178619,6 +178797,10 @@ var catalog_generated_default = {
178619
178797
  },
178620
178798
  defaultTab: {
178621
178799
  type: "string"
178800
+ },
178801
+ variant: {
178802
+ type: "string",
178803
+ enum: ["line", "segmented"]
178622
178804
  }
178623
178805
  },
178624
178806
  required: ["id", "tabs"],
@@ -178712,7 +178894,7 @@ var catalog_generated_default = {
178712
178894
  }
178713
178895
  },
178714
178896
  SearchInput: {
178715
- description: 'Free-text search box. Writes the debounced (~200ms) query into state at `/ui/<id>/value`; bind it into a Table with `"search": { "$state": "/ui/<id>/value" }`. Purely client-side — it filters rows the page already polled, it does not re-run the query.',
178897
+ description: 'Free-text search box. Writes the debounced (~200ms) query into state at `/ui/<id>/value`; bind it into a Table with `"search": { "$state": "/ui/<id>/value" }`. Purely client-side — it filters rows the page already polled, it does not re-run the query. `shortcut` (usually `"/"`) shows a keycap hint and focuses the field when pressed outside a text field.',
178716
178898
  props: {
178717
178899
  $schema: "http://json-schema.org/draft-07/schema#",
178718
178900
  type: "object",
@@ -178725,6 +178907,11 @@ var catalog_generated_default = {
178725
178907
  },
178726
178908
  label: {
178727
178909
  type: "string"
178910
+ },
178911
+ shortcut: {
178912
+ type: "string",
178913
+ minLength: 1,
178914
+ maxLength: 12
178728
178915
  }
178729
178916
  },
178730
178917
  required: ["id"],
@@ -178732,7 +178919,7 @@ var catalog_generated_default = {
178732
178919
  }
178733
178920
  },
178734
178921
  Select: {
178735
- description: 'Dropdown filter/picker. `options` are plain strings or `{ value, label }` objects. Writes the chosen value into state at `/ui/<id>/value` (clearing writes `null`); bind it into a Table with `"filters": { "<column>": { "$state": "/ui/<id>/value" } }`. `clearable` (default true) shows a clear button.',
178922
+ description: 'Dropdown filter/picker. `options` are plain strings or `{ value, label?, icon?, hint? }` objects. Writes the chosen value into state at `/ui/<id>/value` (clearing writes `null`); bind it into a Table with `"filters": { "<column>": { "$state": "/ui/<id>/value" } }`. `clearable` (default true) shows a clear button. `searchable` adds a type-to-filter field (on by default past 8 options; `searchPlaceholder` sets its hint). `multiple` picks several: the value is a string array (empty = nothing picked), which a Table filter reads as "cell is one of".',
178736
178923
  props: {
178737
178924
  $schema: "http://json-schema.org/draft-07/schema#",
178738
178925
  type: "object",
@@ -178756,6 +178943,54 @@ var catalog_generated_default = {
178756
178943
  },
178757
178944
  label: {
178758
178945
  type: "string"
178946
+ },
178947
+ icon: {
178948
+ type: "string",
178949
+ enum: [
178950
+ "plus",
178951
+ "refresh-cw",
178952
+ "search",
178953
+ "filter",
178954
+ "download",
178955
+ "upload",
178956
+ "external-link",
178957
+ "copy",
178958
+ "check",
178959
+ "x",
178960
+ "trash-2",
178961
+ "pencil",
178962
+ "eye",
178963
+ "calendar",
178964
+ "clock",
178965
+ "user",
178966
+ "users",
178967
+ "bot",
178968
+ "git-pull-request",
178969
+ "git-branch",
178970
+ "github",
178971
+ "slack",
178972
+ "mail",
178973
+ "link",
178974
+ "file-text",
178975
+ "folder",
178976
+ "database",
178977
+ "zap",
178978
+ "sparkles",
178979
+ "flag",
178980
+ "star",
178981
+ "tag",
178982
+ "alert-triangle",
178983
+ "info",
178984
+ "circle-check",
178985
+ "trending-up",
178986
+ "trending-down",
178987
+ "dollar-sign",
178988
+ "activity",
178989
+ "rocket"
178990
+ ]
178991
+ },
178992
+ hint: {
178993
+ type: "string"
178759
178994
  }
178760
178995
  },
178761
178996
  required: ["value"],
@@ -178772,6 +179007,15 @@ var catalog_generated_default = {
178772
179007
  },
178773
179008
  clearable: {
178774
179009
  type: "boolean"
179010
+ },
179011
+ searchable: {
179012
+ type: "boolean"
179013
+ },
179014
+ multiple: {
179015
+ type: "boolean"
179016
+ },
179017
+ searchPlaceholder: {
179018
+ type: "string"
178775
179019
  }
178776
179020
  },
178777
179021
  required: ["id", "options"],
@@ -178779,7 +179023,7 @@ var catalog_generated_default = {
178779
179023
  }
178780
179024
  },
178781
179025
  Button: {
178782
- description: 'Interactive button. Wire to actions via `on.press`. `variant: "destructive-outline"` is the canonical red-outlined destructive look (standalone deletes should use it, not solid red). `disabled` accepts a constant or a bound boolean; `busyWith: "<actionName>"` disables the button and shows a spinner while that custom action is running.',
179026
+ description: 'Interactive button. Wire to actions via `on.press`. `variant: "destructive-outline"` is the canonical red-outlined destructive look (standalone deletes should use it, not solid red). `disabled` accepts a constant or a bound boolean; `busyWith: "<actionName>"` swaps the label for a spinner (presses ignored) while that custom action is running, then shows a check plus `successLabel` for ~1.5s when it finishes ok. `icon` + `iconPosition` (start|end) add an icon from the curated set; `size` sm|default|lg. `shortcut` (one key, e.g. `"n"`) shows a keycap inside the button and presses it from anywhere on the page (not while typing in a field, not with Ctrl/Cmd/Alt). `hint` is a hover tooltip.',
178783
179027
  props: {
178784
179028
  $schema: "http://json-schema.org/draft-07/schema#",
178785
179029
  type: "object",
@@ -178803,6 +179047,70 @@ var catalog_generated_default = {
178803
179047
  },
178804
179048
  busyWith: {
178805
179049
  type: "string"
179050
+ },
179051
+ icon: {
179052
+ type: "string",
179053
+ enum: [
179054
+ "plus",
179055
+ "refresh-cw",
179056
+ "search",
179057
+ "filter",
179058
+ "download",
179059
+ "upload",
179060
+ "external-link",
179061
+ "copy",
179062
+ "check",
179063
+ "x",
179064
+ "trash-2",
179065
+ "pencil",
179066
+ "eye",
179067
+ "calendar",
179068
+ "clock",
179069
+ "user",
179070
+ "users",
179071
+ "bot",
179072
+ "git-pull-request",
179073
+ "git-branch",
179074
+ "github",
179075
+ "slack",
179076
+ "mail",
179077
+ "link",
179078
+ "file-text",
179079
+ "folder",
179080
+ "database",
179081
+ "zap",
179082
+ "sparkles",
179083
+ "flag",
179084
+ "star",
179085
+ "tag",
179086
+ "alert-triangle",
179087
+ "info",
179088
+ "circle-check",
179089
+ "trending-up",
179090
+ "trending-down",
179091
+ "dollar-sign",
179092
+ "activity",
179093
+ "rocket"
179094
+ ]
179095
+ },
179096
+ iconPosition: {
179097
+ type: "string",
179098
+ enum: ["start", "end"]
179099
+ },
179100
+ successLabel: {
179101
+ type: "string"
179102
+ },
179103
+ size: {
179104
+ type: "string",
179105
+ enum: ["sm", "default", "lg"]
179106
+ },
179107
+ shortcut: {
179108
+ type: "string",
179109
+ minLength: 1,
179110
+ maxLength: 12
179111
+ },
179112
+ hint: {
179113
+ type: "string"
178806
179114
  }
178807
179115
  },
178808
179116
  required: ["label"],
@@ -178810,7 +179118,7 @@ var catalog_generated_default = {
178810
179118
  }
178811
179119
  },
178812
179120
  Metric: {
178813
- description: 'Single label/value tile for status pages. Bind `loading` to the backing query (`{ "$state": "/queries/<name>/loading" }`) to show a skeleton instead of a blank value while it loads.',
179121
+ description: 'Stat tile (the dashboard `StatPanel`): label, value, optional `detail` line and `trend: { direction: "up"|"down"|"flat", label }` (arrow plus success/error/muted text). `icon` adds a tile tinted by `tone` (neutral|success|active|error|info|pending|warning|paused); `info` is a one-sentence explanation in a tooltip next to the label. Bind `loading` to the backing query (`{ "$state": "/queries/<name>/loading" }`) to show a skeleton instead of a blank value while it loads; an empty value renders an em dash.',
178814
179122
  props: {
178815
179123
  $schema: "http://json-schema.org/draft-07/schema#",
178816
179124
  type: "object",
@@ -178830,6 +179138,84 @@ var catalog_generated_default = {
178830
179138
  },
178831
179139
  loading: {
178832
179140
  type: "boolean"
179141
+ },
179142
+ icon: {
179143
+ type: "string",
179144
+ enum: [
179145
+ "plus",
179146
+ "refresh-cw",
179147
+ "search",
179148
+ "filter",
179149
+ "download",
179150
+ "upload",
179151
+ "external-link",
179152
+ "copy",
179153
+ "check",
179154
+ "x",
179155
+ "trash-2",
179156
+ "pencil",
179157
+ "eye",
179158
+ "calendar",
179159
+ "clock",
179160
+ "user",
179161
+ "users",
179162
+ "bot",
179163
+ "git-pull-request",
179164
+ "git-branch",
179165
+ "github",
179166
+ "slack",
179167
+ "mail",
179168
+ "link",
179169
+ "file-text",
179170
+ "folder",
179171
+ "database",
179172
+ "zap",
179173
+ "sparkles",
179174
+ "flag",
179175
+ "star",
179176
+ "tag",
179177
+ "alert-triangle",
179178
+ "info",
179179
+ "circle-check",
179180
+ "trending-up",
179181
+ "trending-down",
179182
+ "dollar-sign",
179183
+ "activity",
179184
+ "rocket"
179185
+ ]
179186
+ },
179187
+ tone: {
179188
+ type: "string",
179189
+ enum: [
179190
+ "neutral",
179191
+ "success",
179192
+ "active",
179193
+ "error",
179194
+ "info",
179195
+ "pending",
179196
+ "warning",
179197
+ "paused"
179198
+ ]
179199
+ },
179200
+ detail: {
179201
+ type: "string"
179202
+ },
179203
+ info: {
179204
+ type: "string"
179205
+ },
179206
+ trend: {
179207
+ type: "object",
179208
+ properties: {
179209
+ direction: {
179210
+ type: "string",
179211
+ enum: ["up", "down", "flat"]
179212
+ },
179213
+ label: {
179214
+ type: "string"
179215
+ }
179216
+ },
179217
+ required: ["direction", "label"],
179218
+ additionalProperties: false
178833
179219
  }
178834
179220
  },
178835
179221
  required: ["label", "value"],
@@ -178837,7 +179223,7 @@ var catalog_generated_default = {
178837
179223
  }
178838
179224
  },
178839
179225
  Alert: {
178840
- description: "Status-toned inline alert.",
179226
+ description: "Status-toned inline alert. `icon` overrides the tone's default icon. `actionLabel` adds a button inside the callout that emits the element's `press` event (wire it with `on.press`).",
178841
179227
  props: {
178842
179228
  $schema: "http://json-schema.org/draft-07/schema#",
178843
179229
  type: "object",
@@ -178851,6 +179237,54 @@ var catalog_generated_default = {
178851
179237
  },
178852
179238
  title: {
178853
179239
  type: "string"
179240
+ },
179241
+ icon: {
179242
+ type: "string",
179243
+ enum: [
179244
+ "plus",
179245
+ "refresh-cw",
179246
+ "search",
179247
+ "filter",
179248
+ "download",
179249
+ "upload",
179250
+ "external-link",
179251
+ "copy",
179252
+ "check",
179253
+ "x",
179254
+ "trash-2",
179255
+ "pencil",
179256
+ "eye",
179257
+ "calendar",
179258
+ "clock",
179259
+ "user",
179260
+ "users",
179261
+ "bot",
179262
+ "git-pull-request",
179263
+ "git-branch",
179264
+ "github",
179265
+ "slack",
179266
+ "mail",
179267
+ "link",
179268
+ "file-text",
179269
+ "folder",
179270
+ "database",
179271
+ "zap",
179272
+ "sparkles",
179273
+ "flag",
179274
+ "star",
179275
+ "tag",
179276
+ "alert-triangle",
179277
+ "info",
179278
+ "circle-check",
179279
+ "trending-up",
179280
+ "trending-down",
179281
+ "dollar-sign",
179282
+ "activity",
179283
+ "rocket"
179284
+ ]
179285
+ },
179286
+ actionLabel: {
179287
+ type: "string"
178854
179288
  }
178855
179289
  },
178856
179290
  required: ["message"],
@@ -178858,7 +179292,7 @@ var catalog_generated_default = {
178858
179292
  }
178859
179293
  },
178860
179294
  Badge: {
178861
- description: "Status pill (uppercase tag chip) with a semantic tone.",
179295
+ description: "Small chip. `variant`: `tag` (default, the uppercase status chip with a tone dot), `status` (11px sentence-case pill with a dot or icon), `count` (compact rounded numeric pill), `beta` (the BETA tag; `hint` is its tooltip). `tone` is neutral|success|active|error|info|pending|warning|paused; `icon` replaces the dot. `status` takes a lifecycle value (pending, in_progress, completed, failed, cancelled, paused, ...) and renders the dashboard status chip with its icon and label — any other value falls back to a toned pill showing `text`. `hint` adds a hover tooltip.",
178862
179296
  props: {
178863
179297
  $schema: "http://json-schema.org/draft-07/schema#",
178864
179298
  type: "object",
@@ -178885,14 +179319,465 @@ var catalog_generated_default = {
178885
179319
  "warning",
178886
179320
  "paused"
178887
179321
  ]
179322
+ },
179323
+ icon: {
179324
+ type: "string",
179325
+ enum: [
179326
+ "plus",
179327
+ "refresh-cw",
179328
+ "search",
179329
+ "filter",
179330
+ "download",
179331
+ "upload",
179332
+ "external-link",
179333
+ "copy",
179334
+ "check",
179335
+ "x",
179336
+ "trash-2",
179337
+ "pencil",
179338
+ "eye",
179339
+ "calendar",
179340
+ "clock",
179341
+ "user",
179342
+ "users",
179343
+ "bot",
179344
+ "git-pull-request",
179345
+ "git-branch",
179346
+ "github",
179347
+ "slack",
179348
+ "mail",
179349
+ "link",
179350
+ "file-text",
179351
+ "folder",
179352
+ "database",
179353
+ "zap",
179354
+ "sparkles",
179355
+ "flag",
179356
+ "star",
179357
+ "tag",
179358
+ "alert-triangle",
179359
+ "info",
179360
+ "circle-check",
179361
+ "trending-up",
179362
+ "trending-down",
179363
+ "dollar-sign",
179364
+ "activity",
179365
+ "rocket"
179366
+ ]
179367
+ },
179368
+ status: {
179369
+ type: "string"
179370
+ },
179371
+ variant: {
179372
+ type: "string",
179373
+ enum: ["tag", "status", "count", "beta"]
179374
+ },
179375
+ hint: {
179376
+ type: "string"
178888
179377
  }
178889
179378
  },
178890
179379
  required: ["text"],
178891
179380
  additionalProperties: false
178892
179381
  }
178893
179382
  },
179383
+ Icon: {
179384
+ description: "One icon from the curated lucide set (`plus`, `refresh-cw`, `search`, `filter`, `download`, `upload`, `external-link`, `copy`, `check`, `x`, `trash-2`, `pencil`, `eye`, `calendar`, `clock`, `user`, `users`, `bot`, `git-pull-request`, `git-branch`, `github`, `slack`, `mail`, `link`, `file-text`, `folder`, `database`, `zap`, `sparkles`, `flag`, `star`, `tag`, `alert-triangle`, `info`, `circle-check`, `trending-up`, `trending-down`, `dollar-sign`, `activity`, `rocket`). The same names work on every `icon` prop (Button, Badge, Metric, Alert, Tabs entries, Chips options, EmptyState, Table columns, row actions and Drawer actions). Decorative unless `label` is set. `size` sm|md|lg, `tone` default|muted|success|warning|error|info.",
179385
+ props: {
179386
+ $schema: "http://json-schema.org/draft-07/schema#",
179387
+ type: "object",
179388
+ properties: {
179389
+ name: {
179390
+ type: "string",
179391
+ enum: [
179392
+ "plus",
179393
+ "refresh-cw",
179394
+ "search",
179395
+ "filter",
179396
+ "download",
179397
+ "upload",
179398
+ "external-link",
179399
+ "copy",
179400
+ "check",
179401
+ "x",
179402
+ "trash-2",
179403
+ "pencil",
179404
+ "eye",
179405
+ "calendar",
179406
+ "clock",
179407
+ "user",
179408
+ "users",
179409
+ "bot",
179410
+ "git-pull-request",
179411
+ "git-branch",
179412
+ "github",
179413
+ "slack",
179414
+ "mail",
179415
+ "link",
179416
+ "file-text",
179417
+ "folder",
179418
+ "database",
179419
+ "zap",
179420
+ "sparkles",
179421
+ "flag",
179422
+ "star",
179423
+ "tag",
179424
+ "alert-triangle",
179425
+ "info",
179426
+ "circle-check",
179427
+ "trending-up",
179428
+ "trending-down",
179429
+ "dollar-sign",
179430
+ "activity",
179431
+ "rocket"
179432
+ ]
179433
+ },
179434
+ size: {
179435
+ type: "string",
179436
+ enum: ["sm", "md", "lg"]
179437
+ },
179438
+ tone: {
179439
+ type: "string",
179440
+ enum: ["default", "muted", "success", "warning", "error", "info"]
179441
+ },
179442
+ label: {
179443
+ type: "string"
179444
+ }
179445
+ },
179446
+ required: ["name"],
179447
+ additionalProperties: false
179448
+ }
179449
+ },
179450
+ Progress: {
179451
+ description: 'Progress readout. `value` against `max` (default 100), usually bound to state. `variant: "bar"` (default) is a toned bar (`tone` neutral|success|active|error|info|pending|warning|paused) with an optional `label` above it; `"ring"` is the dashboard progress ring (done arc). `showValue` (default true) prints the percent (bar) or `value / max` (ring).',
179452
+ props: {
179453
+ $schema: "http://json-schema.org/draft-07/schema#",
179454
+ type: "object",
179455
+ properties: {
179456
+ value: {
179457
+ type: "number"
179458
+ },
179459
+ max: {
179460
+ type: "number",
179461
+ exclusiveMinimum: 0
179462
+ },
179463
+ tone: {
179464
+ type: "string",
179465
+ enum: [
179466
+ "neutral",
179467
+ "success",
179468
+ "active",
179469
+ "error",
179470
+ "info",
179471
+ "pending",
179472
+ "warning",
179473
+ "paused"
179474
+ ]
179475
+ },
179476
+ label: {
179477
+ type: "string"
179478
+ },
179479
+ variant: {
179480
+ type: "string",
179481
+ enum: ["bar", "ring"]
179482
+ },
179483
+ showValue: {
179484
+ type: "boolean"
179485
+ }
179486
+ },
179487
+ required: ["value"],
179488
+ additionalProperties: false
179489
+ }
179490
+ },
179491
+ EmptyState: {
179492
+ description: "Centered empty state: `icon` (curated set, default inbox), `title`, optional `body`. `actionLabel` adds a button that emits the element's `press` event — wire it with `on.press` like a Button.",
179493
+ props: {
179494
+ $schema: "http://json-schema.org/draft-07/schema#",
179495
+ type: "object",
179496
+ properties: {
179497
+ icon: {
179498
+ type: "string",
179499
+ enum: [
179500
+ "plus",
179501
+ "refresh-cw",
179502
+ "search",
179503
+ "filter",
179504
+ "download",
179505
+ "upload",
179506
+ "external-link",
179507
+ "copy",
179508
+ "check",
179509
+ "x",
179510
+ "trash-2",
179511
+ "pencil",
179512
+ "eye",
179513
+ "calendar",
179514
+ "clock",
179515
+ "user",
179516
+ "users",
179517
+ "bot",
179518
+ "git-pull-request",
179519
+ "git-branch",
179520
+ "github",
179521
+ "slack",
179522
+ "mail",
179523
+ "link",
179524
+ "file-text",
179525
+ "folder",
179526
+ "database",
179527
+ "zap",
179528
+ "sparkles",
179529
+ "flag",
179530
+ "star",
179531
+ "tag",
179532
+ "alert-triangle",
179533
+ "info",
179534
+ "circle-check",
179535
+ "trending-up",
179536
+ "trending-down",
179537
+ "dollar-sign",
179538
+ "activity",
179539
+ "rocket"
179540
+ ]
179541
+ },
179542
+ title: {
179543
+ type: "string"
179544
+ },
179545
+ body: {
179546
+ type: "string"
179547
+ },
179548
+ actionLabel: {
179549
+ type: "string"
179550
+ }
179551
+ },
179552
+ required: ["title"],
179553
+ additionalProperties: false
179554
+ }
179555
+ },
179556
+ CopyButton: {
179557
+ description: "Copies `value` to the clipboard; the icon swaps to a check on copy. `label` is the visible text; without it the button is icon-only.",
179558
+ props: {
179559
+ $schema: "http://json-schema.org/draft-07/schema#",
179560
+ type: "object",
179561
+ properties: {
179562
+ value: {
179563
+ anyOf: [
179564
+ {
179565
+ type: "string"
179566
+ },
179567
+ {
179568
+ type: "number"
179569
+ }
179570
+ ]
179571
+ },
179572
+ label: {
179573
+ type: "string"
179574
+ }
179575
+ },
179576
+ required: ["value"],
179577
+ additionalProperties: false
179578
+ }
179579
+ },
179580
+ Kbd: {
179581
+ description: 'Keycaps for a keyboard shortcut, one per entry in `keys` (e.g. `["⌘", "K"]`). Display only.',
179582
+ props: {
179583
+ $schema: "http://json-schema.org/draft-07/schema#",
179584
+ type: "object",
179585
+ properties: {
179586
+ keys: {
179587
+ minItems: 1,
179588
+ type: "array",
179589
+ items: {
179590
+ type: "string"
179591
+ }
179592
+ }
179593
+ },
179594
+ required: ["keys"],
179595
+ additionalProperties: false
179596
+ }
179597
+ },
179598
+ Skeleton: {
179599
+ description: "Loading placeholder. `shape`: `line` (text lines), `block` (one box, `height` in px, default 128), `rows` (table-like rows), `metric` (stat tiles), `card` (a card sketch). `count` repeats lines, rows or tiles. Pair with `visible` on a query's `loading` state.",
179600
+ props: {
179601
+ $schema: "http://json-schema.org/draft-07/schema#",
179602
+ type: "object",
179603
+ properties: {
179604
+ shape: {
179605
+ type: "string",
179606
+ enum: ["line", "block", "rows", "metric", "card"]
179607
+ },
179608
+ count: {
179609
+ type: "integer",
179610
+ minimum: 1,
179611
+ maximum: 20
179612
+ },
179613
+ height: {
179614
+ type: "integer",
179615
+ minimum: 8,
179616
+ maximum: 800
179617
+ }
179618
+ },
179619
+ required: ["shape"],
179620
+ additionalProperties: false
179621
+ }
179622
+ },
179623
+ Spinner: {
179624
+ description: 'Inline busy indicator with `role=status`. `variant` ring|ellipsis|bars (default: the dashboard spinner), `size` sm|md, `label` shown next to it (and its accessible name; defaults to an sr-only "Loading").',
179625
+ props: {
179626
+ $schema: "http://json-schema.org/draft-07/schema#",
179627
+ type: "object",
179628
+ properties: {
179629
+ variant: {
179630
+ type: "string",
179631
+ enum: ["ring", "ellipsis", "bars"]
179632
+ },
179633
+ size: {
179634
+ type: "string",
179635
+ enum: ["sm", "md"]
179636
+ },
179637
+ label: {
179638
+ type: "string"
179639
+ }
179640
+ },
179641
+ additionalProperties: false
179642
+ }
179643
+ },
179644
+ AvatarStack: {
179645
+ description: "Overlapping initials avatars for `users` (display names), up to `max` (default 4) then a `+N` count; hover lists every name.",
179646
+ props: {
179647
+ $schema: "http://json-schema.org/draft-07/schema#",
179648
+ type: "object",
179649
+ properties: {
179650
+ users: {
179651
+ type: "array",
179652
+ items: {
179653
+ type: "string"
179654
+ }
179655
+ },
179656
+ max: {
179657
+ type: "integer",
179658
+ minimum: 1,
179659
+ maximum: 20
179660
+ }
179661
+ },
179662
+ required: ["users"],
179663
+ additionalProperties: false
179664
+ }
179665
+ },
179666
+ Section: {
179667
+ description: "Titled section around its children: `title`, optional `description`. `collapsible` folds the body under a toggle header (`defaultOpen`, default true).",
179668
+ slots: ["default"],
179669
+ props: {
179670
+ $schema: "http://json-schema.org/draft-07/schema#",
179671
+ type: "object",
179672
+ properties: {
179673
+ title: {
179674
+ type: "string"
179675
+ },
179676
+ description: {
179677
+ type: "string"
179678
+ },
179679
+ collapsible: {
179680
+ type: "boolean"
179681
+ },
179682
+ defaultOpen: {
179683
+ type: "boolean"
179684
+ }
179685
+ },
179686
+ required: ["title"],
179687
+ additionalProperties: false
179688
+ }
179689
+ },
179690
+ Chips: {
179691
+ description: 'Toggle chips for quick filters. `options` are strings or `{ value, label?, icon? }`. Writes the selection to `/ui/<id>/value`: one string or `null` (pressing the selected chip clears it), or with `multiple` a string array (empty = nothing picked). Bind it into a Table with `"filters": { "<column>": { "$state": "/ui/<id>/value" } }` — an array filter matches rows whose cell is one of the values. `label` names the group for screen readers.',
179692
+ props: {
179693
+ $schema: "http://json-schema.org/draft-07/schema#",
179694
+ type: "object",
179695
+ properties: {
179696
+ id: {
179697
+ type: "string"
179698
+ },
179699
+ options: {
179700
+ minItems: 1,
179701
+ type: "array",
179702
+ items: {
179703
+ anyOf: [
179704
+ {
179705
+ type: "string"
179706
+ },
179707
+ {
179708
+ type: "object",
179709
+ properties: {
179710
+ value: {
179711
+ type: "string"
179712
+ },
179713
+ label: {
179714
+ type: "string"
179715
+ },
179716
+ icon: {
179717
+ type: "string",
179718
+ enum: [
179719
+ "plus",
179720
+ "refresh-cw",
179721
+ "search",
179722
+ "filter",
179723
+ "download",
179724
+ "upload",
179725
+ "external-link",
179726
+ "copy",
179727
+ "check",
179728
+ "x",
179729
+ "trash-2",
179730
+ "pencil",
179731
+ "eye",
179732
+ "calendar",
179733
+ "clock",
179734
+ "user",
179735
+ "users",
179736
+ "bot",
179737
+ "git-pull-request",
179738
+ "git-branch",
179739
+ "github",
179740
+ "slack",
179741
+ "mail",
179742
+ "link",
179743
+ "file-text",
179744
+ "folder",
179745
+ "database",
179746
+ "zap",
179747
+ "sparkles",
179748
+ "flag",
179749
+ "star",
179750
+ "tag",
179751
+ "alert-triangle",
179752
+ "info",
179753
+ "circle-check",
179754
+ "trending-up",
179755
+ "trending-down",
179756
+ "dollar-sign",
179757
+ "activity",
179758
+ "rocket"
179759
+ ]
179760
+ }
179761
+ },
179762
+ required: ["value"],
179763
+ additionalProperties: false
179764
+ }
179765
+ ]
179766
+ }
179767
+ },
179768
+ multiple: {
179769
+ type: "boolean"
179770
+ },
179771
+ label: {
179772
+ type: "string"
179773
+ }
179774
+ },
179775
+ required: ["id", "options"],
179776
+ additionalProperties: false
179777
+ }
179778
+ },
178894
179779
  Table: {
178895
- description: 'Data table. Bind `data`/`loading`/`error` to a named query (`/queries/<name>/...`). `rowActions` chains receive `{ "$row": "<col>" }` (or `{ "$row": "" }` for the whole row) and `{ "$rowIndex": true }`. Destructive row actions always confirm via a dialog; override the copy with `confirm: { title, description, confirmLabel }`. `search` (case-insensitive substring across every listed column) and `filters` (per-column equality, `null`/`""` disables one) narrow the polled rows client-side — bind them to a `SearchInput` / `Select` via `/ui/<id>/value`, or pin a constant (e.g. `"filters": { "pinned": true }`). Columns take `pinned: "left"|"right"` to survive horizontal scroll; `pagination` pages large row sets (auto past 200 rows); `density: "compact"` tightens row height.',
179780
+ description: 'Data table. Bind `data`/`loading`/`error` to a named query (`/queries/<name>/...`). `rowActions` chains receive `{ "$row": "<col>" }` (or `{ "$row": "" }` for the whole row) and `{ "$rowIndex": true }`. Destructive row actions always confirm via a dialog; override the copy with `confirm: { title, description, confirmLabel }`. `search` (case-insensitive substring across every listed column) and `filters` (per-column equality, `null`/`""` disables one; an array means "one of", which is what a multiple `Chips` writes, and an empty array disables it) narrow the polled rows client-side — bind them to a `SearchInput` / `Select` via `/ui/<id>/value`, or pin a constant (e.g. `"filters": { "pinned": true }`). Columns take `pinned: "left"|"right"` to survive horizontal scroll; `pagination` pages large row sets (auto past 200 rows); `density: "compact"` tightens row height. Column kinds: `status` (lifecycle values like pending/in_progress/completed/failed get the dashboard status icon, anything else a `tones` pill), `user` / `agent` (avatar + name), `relative` (smart time with the exact time on hover), `duration` (ms → 1m 23s), `progress` (bar, `max` default 100), `copy` (value + copy button), `switch` (runs the column\'s `onChange` chain with `$row` set to the new value; read-only without it), `link` (http(s) URL, opens in a new tab). Columns also take `align`, `truncate: "middle"` (ids, paths), a header `icon` and `tooltip` (a row field shown on hover). `onRowClick` runs a chain with `$row` when a row is clicked — pair it with `app.navigate` + a Drawer and bind `selectedId` to the drawer param to highlight the open row. `rowId` names the id field (default `id`). Below 768px the table renders as a phone list (`mobile: "list"`, fields picked by `mobileFields: { title, subtitle?, meta?, status? }`); `mobile: "scroll"` keeps the grid. `emptyState: { icon?, title, body? }` replaces the empty message. Row actions take `icon` and `placement: "menu"` (collected into a More menu).',
178896
179781
  props: {
178897
179782
  $schema: "http://json-schema.org/draft-07/schema#",
178898
179783
  type: "object",
@@ -178920,7 +179805,24 @@ var catalog_generated_default = {
178920
179805
  },
178921
179806
  kind: {
178922
179807
  type: "string",
178923
- enum: ["text", "string", "number", "boolean", "date", "badge", "enum"]
179808
+ enum: [
179809
+ "text",
179810
+ "string",
179811
+ "number",
179812
+ "boolean",
179813
+ "date",
179814
+ "badge",
179815
+ "enum",
179816
+ "status",
179817
+ "user",
179818
+ "agent",
179819
+ "relative",
179820
+ "duration",
179821
+ "progress",
179822
+ "copy",
179823
+ "switch",
179824
+ "link"
179825
+ ]
178924
179826
  },
178925
179827
  tones: {
178926
179828
  type: "object",
@@ -178947,6 +179849,86 @@ var catalog_generated_default = {
178947
179849
  pinned: {
178948
179850
  type: "string",
178949
179851
  enum: ["left", "right"]
179852
+ },
179853
+ align: {
179854
+ type: "string",
179855
+ enum: ["start", "end"]
179856
+ },
179857
+ truncate: {
179858
+ type: "string",
179859
+ enum: ["end", "middle"]
179860
+ },
179861
+ icon: {
179862
+ type: "string",
179863
+ enum: [
179864
+ "plus",
179865
+ "refresh-cw",
179866
+ "search",
179867
+ "filter",
179868
+ "download",
179869
+ "upload",
179870
+ "external-link",
179871
+ "copy",
179872
+ "check",
179873
+ "x",
179874
+ "trash-2",
179875
+ "pencil",
179876
+ "eye",
179877
+ "calendar",
179878
+ "clock",
179879
+ "user",
179880
+ "users",
179881
+ "bot",
179882
+ "git-pull-request",
179883
+ "git-branch",
179884
+ "github",
179885
+ "slack",
179886
+ "mail",
179887
+ "link",
179888
+ "file-text",
179889
+ "folder",
179890
+ "database",
179891
+ "zap",
179892
+ "sparkles",
179893
+ "flag",
179894
+ "star",
179895
+ "tag",
179896
+ "alert-triangle",
179897
+ "info",
179898
+ "circle-check",
179899
+ "trending-up",
179900
+ "trending-down",
179901
+ "dollar-sign",
179902
+ "activity",
179903
+ "rocket"
179904
+ ]
179905
+ },
179906
+ tooltip: {
179907
+ type: "string"
179908
+ },
179909
+ max: {
179910
+ type: "number",
179911
+ exclusiveMinimum: 0
179912
+ },
179913
+ onChange: {
179914
+ type: "array",
179915
+ items: {
179916
+ type: "object",
179917
+ properties: {
179918
+ action: {
179919
+ type: "string"
179920
+ },
179921
+ params: {
179922
+ type: "object",
179923
+ propertyNames: {
179924
+ type: "string"
179925
+ },
179926
+ additionalProperties: {}
179927
+ }
179928
+ },
179929
+ required: ["action"],
179930
+ additionalProperties: false
179931
+ }
178950
179932
  }
178951
179933
  },
178952
179934
  required: ["key"],
@@ -179016,6 +179998,55 @@ var catalog_generated_default = {
179016
179998
  required: ["action"],
179017
179999
  additionalProperties: false
179018
180000
  }
180001
+ },
180002
+ icon: {
180003
+ type: "string",
180004
+ enum: [
180005
+ "plus",
180006
+ "refresh-cw",
180007
+ "search",
180008
+ "filter",
180009
+ "download",
180010
+ "upload",
180011
+ "external-link",
180012
+ "copy",
180013
+ "check",
180014
+ "x",
180015
+ "trash-2",
180016
+ "pencil",
180017
+ "eye",
180018
+ "calendar",
180019
+ "clock",
180020
+ "user",
180021
+ "users",
180022
+ "bot",
180023
+ "git-pull-request",
180024
+ "git-branch",
180025
+ "github",
180026
+ "slack",
180027
+ "mail",
180028
+ "link",
180029
+ "file-text",
180030
+ "folder",
180031
+ "database",
180032
+ "zap",
180033
+ "sparkles",
180034
+ "flag",
180035
+ "star",
180036
+ "tag",
180037
+ "alert-triangle",
180038
+ "info",
180039
+ "circle-check",
180040
+ "trending-up",
180041
+ "trending-down",
180042
+ "dollar-sign",
180043
+ "activity",
180044
+ "rocket"
180045
+ ]
180046
+ },
180047
+ placement: {
180048
+ type: "string",
180049
+ enum: ["inline", "menu"]
179019
180050
  }
179020
180051
  },
179021
180052
  required: ["label", "actions"],
@@ -179058,6 +180089,22 @@ var catalog_generated_default = {
179058
180089
  },
179059
180090
  {
179060
180091
  type: "boolean"
180092
+ },
180093
+ {
180094
+ type: "array",
180095
+ items: {
180096
+ anyOf: [
180097
+ {
180098
+ type: "string"
180099
+ },
180100
+ {
180101
+ type: "number"
180102
+ },
180103
+ {
180104
+ type: "boolean"
180105
+ }
180106
+ ]
180107
+ }
179061
180108
  }
179062
180109
  ]
179063
180110
  },
@@ -179073,6 +180120,137 @@ var catalog_generated_default = {
179073
180120
  density: {
179074
180121
  type: "string",
179075
180122
  enum: ["comfortable", "compact"]
180123
+ },
180124
+ rowId: {
180125
+ type: "string"
180126
+ },
180127
+ onRowClick: {
180128
+ type: "array",
180129
+ items: {
180130
+ type: "object",
180131
+ properties: {
180132
+ action: {
180133
+ type: "string"
180134
+ },
180135
+ params: {
180136
+ type: "object",
180137
+ propertyNames: {
180138
+ type: "string"
180139
+ },
180140
+ additionalProperties: {}
180141
+ }
180142
+ },
180143
+ required: ["action"],
180144
+ additionalProperties: false
180145
+ }
180146
+ },
180147
+ selectedId: {
180148
+ anyOf: [
180149
+ {
180150
+ anyOf: [
180151
+ {
180152
+ type: "string"
180153
+ },
180154
+ {
180155
+ type: "number"
180156
+ }
180157
+ ]
180158
+ },
180159
+ {
180160
+ type: "null"
180161
+ }
180162
+ ]
180163
+ },
180164
+ mobile: {
180165
+ type: "string",
180166
+ enum: ["list", "scroll"]
180167
+ },
180168
+ mobileFields: {
180169
+ type: "object",
180170
+ properties: {
180171
+ title: {
180172
+ type: "string"
180173
+ },
180174
+ subtitle: {
180175
+ type: "string"
180176
+ },
180177
+ meta: {
180178
+ anyOf: [
180179
+ {
180180
+ type: "string"
180181
+ },
180182
+ {
180183
+ type: "array",
180184
+ items: {
180185
+ type: "string"
180186
+ }
180187
+ }
180188
+ ]
180189
+ },
180190
+ status: {
180191
+ type: "string"
180192
+ }
180193
+ },
180194
+ required: ["title"],
180195
+ additionalProperties: false
180196
+ },
180197
+ emptyState: {
180198
+ type: "object",
180199
+ properties: {
180200
+ icon: {
180201
+ type: "string",
180202
+ enum: [
180203
+ "plus",
180204
+ "refresh-cw",
180205
+ "search",
180206
+ "filter",
180207
+ "download",
180208
+ "upload",
180209
+ "external-link",
180210
+ "copy",
180211
+ "check",
180212
+ "x",
180213
+ "trash-2",
180214
+ "pencil",
180215
+ "eye",
180216
+ "calendar",
180217
+ "clock",
180218
+ "user",
180219
+ "users",
180220
+ "bot",
180221
+ "git-pull-request",
180222
+ "git-branch",
180223
+ "github",
180224
+ "slack",
180225
+ "mail",
180226
+ "link",
180227
+ "file-text",
180228
+ "folder",
180229
+ "database",
180230
+ "zap",
180231
+ "sparkles",
180232
+ "flag",
180233
+ "star",
180234
+ "tag",
180235
+ "alert-triangle",
180236
+ "info",
180237
+ "circle-check",
180238
+ "trending-up",
180239
+ "trending-down",
180240
+ "dollar-sign",
180241
+ "activity",
180242
+ "rocket"
180243
+ ]
180244
+ },
180245
+ title: {
180246
+ type: "string"
180247
+ },
180248
+ body: {
180249
+ type: "string"
180250
+ }
180251
+ },
180252
+ required: ["title"],
180253
+ additionalProperties: false
179076
180254
  }
179077
180255
  },
179078
180256
  required: ["columns"],
@@ -179153,7 +180331,7 @@ var catalog_generated_default = {
179153
180331
  }
179154
180332
  },
179155
180333
  Drawer: {
179156
- description: 'Route-driven slide-in side panel (sheet). Open exactly when the route param named by `param` is set — open it with `app.navigate` (e.g. a rowAction setting `{ "panel": { "$row": "id" } }`), and the URL stays shareable: a deep link with the param renders the drawer open, and closing it clears the param. Children mount only while open (a Table inside does NOT stay warm when closed — unlike Tabs). `side` right (default) or left; `size` sm|md|lg|xl width.',
180334
+ description: 'Route-driven slide-in side panel (sheet). Open exactly when the route param named by `param` is set — open it with `app.navigate` (e.g. a rowAction setting `{ "panel": { "$row": "id" } }`), and the URL stays shareable: a deep link with the param renders the drawer open, and closing it clears the param. Children mount only while open (a Table inside does NOT stay warm when closed — unlike Tabs). `side` right (default) or left; `size` sm|md|lg|xl width. `actions: [{ label, icon?, variant?, confirm?, actions }]` render in a sticky footer with the Table rowActions confirm rules (destructive variants confirm, an `app.mutate` delete always confirms); chains have no `$row`, so read the open record id with `{ "$state": "/route/params/<param>" }`.',
179157
180335
  slots: ["default"],
179158
180336
  props: {
179159
180337
  $schema: "http://json-schema.org/draft-07/schema#",
@@ -179175,6 +180353,120 @@ var catalog_generated_default = {
179175
180353
  size: {
179176
180354
  type: "string",
179177
180355
  enum: ["sm", "md", "lg", "xl"]
180356
+ },
180357
+ actions: {
180358
+ type: "array",
180359
+ items: {
180360
+ type: "object",
180361
+ properties: {
180362
+ label: {
180363
+ type: "string"
180364
+ },
180365
+ variant: {
180366
+ type: "string",
180367
+ enum: [
180368
+ "default",
180369
+ "secondary",
180370
+ "outline",
180371
+ "ghost",
180372
+ "destructive",
180373
+ "destructive-outline"
180374
+ ]
180375
+ },
180376
+ confirm: {
180377
+ anyOf: [
180378
+ {
180379
+ type: "boolean"
180380
+ },
180381
+ {
180382
+ type: "object",
180383
+ properties: {
180384
+ title: {
180385
+ type: "string"
180386
+ },
180387
+ description: {
180388
+ type: "string"
180389
+ },
180390
+ confirmLabel: {
180391
+ type: "string"
180392
+ }
180393
+ },
180394
+ additionalProperties: false
180395
+ },
180396
+ {
180397
+ type: "string"
180398
+ }
180399
+ ]
180400
+ },
180401
+ actions: {
180402
+ type: "array",
180403
+ items: {
180404
+ type: "object",
180405
+ properties: {
180406
+ action: {
180407
+ type: "string"
180408
+ },
180409
+ params: {
180410
+ type: "object",
180411
+ propertyNames: {
180412
+ type: "string"
180413
+ },
180414
+ additionalProperties: {}
180415
+ }
180416
+ },
180417
+ required: ["action"],
180418
+ additionalProperties: false
180419
+ }
180420
+ },
180421
+ icon: {
180422
+ type: "string",
180423
+ enum: [
180424
+ "plus",
180425
+ "refresh-cw",
180426
+ "search",
180427
+ "filter",
180428
+ "download",
180429
+ "upload",
180430
+ "external-link",
180431
+ "copy",
180432
+ "check",
180433
+ "x",
180434
+ "trash-2",
180435
+ "pencil",
180436
+ "eye",
180437
+ "calendar",
180438
+ "clock",
180439
+ "user",
180440
+ "users",
180441
+ "bot",
180442
+ "git-pull-request",
180443
+ "git-branch",
180444
+ "github",
180445
+ "slack",
180446
+ "mail",
180447
+ "link",
180448
+ "file-text",
180449
+ "folder",
180450
+ "database",
180451
+ "zap",
180452
+ "sparkles",
180453
+ "flag",
180454
+ "star",
180455
+ "tag",
180456
+ "alert-triangle",
180457
+ "info",
180458
+ "circle-check",
180459
+ "trending-up",
180460
+ "trending-down",
180461
+ "dollar-sign",
180462
+ "activity",
180463
+ "rocket"
180464
+ ]
180465
+ }
180466
+ },
180467
+ required: ["label", "actions"],
180468
+ additionalProperties: false
180469
+ }
179178
180470
  }
179179
180471
  },
179180
180472
  required: ["param"],
@@ -179182,7 +180474,7 @@ var catalog_generated_default = {
179182
180474
  }
179183
180475
  },
179184
180476
  DetailList: {
179185
- description: 'Read-only label/value detail view for ONE record. Bind `data` to a single row — usually `{ "$state": "/queries/<name>/data/0" }` with a `$param`-filtered query. `fields` pick and format properties with the same kinds as Table columns (badge tones, relative dates) plus `code` for raw/JSON values. Bind `loading` to the query (`/queries/<name>/loading`) for skeleton fields while it loads; `emptyMessage` shows when the record is genuinely missing.',
180477
+ description: 'Read-only label/value detail view for ONE record. Bind `data` to a single row — usually `{ "$state": "/queries/<name>/data/0" }` with a `$param`-filtered query. `fields` pick and format properties with the same kinds as Table columns (badge tones, relative dates) plus `status` (lifecycle chip), `user` (avatar + name), `relative` (smart time, exact on hover), `copy` (value + copy button), `code` (monospace block) and `json` (collapsible JSON tree). Bind `loading` to the query (`/queries/<name>/loading`) for skeleton fields while it loads; `emptyMessage` shows when the record is genuinely missing.',
179186
180478
  props: {
179187
180479
  $schema: "http://json-schema.org/draft-07/schema#",
179188
180480
  type: "object",
@@ -179215,7 +180507,21 @@ var catalog_generated_default = {
179215
180507
  },
179216
180508
  kind: {
179217
180509
  type: "string",
179218
- enum: ["text", "string", "number", "boolean", "date", "badge", "enum", "code"]
180510
+ enum: [
180511
+ "text",
180512
+ "string",
180513
+ "number",
180514
+ "boolean",
180515
+ "date",
180516
+ "badge",
180517
+ "enum",
180518
+ "code",
180519
+ "status",
180520
+ "user",
180521
+ "relative",
180522
+ "copy",
180523
+ "json"
180524
+ ]
179219
180525
  },
179220
180526
  tones: {
179221
180527
  type: "object",
@@ -179265,7 +180571,7 @@ var catalog_generated_default = {
179265
180571
  }
179266
180572
  },
179267
180573
  Kanban: {
179268
- description: 'Kanban board: one card per row, grouped into `columns` by the row\'s `columnField`. Bind `data`/`loading` to a named query. `titleField` is the card title; `cardFields` add label/value lines with Table column kinds (badge tones, relative dates). Dragging a card to another column runs `onMove` with `$row` = the moved row, `columnField` already set to the new column — typically `[{ "action": "app.mutate", "params": { "model": "<m>", "op": "update", "rowId": { "$row": "id" }, "values": { "<columnField>": { "$row": "<columnField>" } } } }]`. Without `onMove` the board is read-only. `onCardClick` runs with `$row` (e.g. an `app.navigate` that opens a Drawer).',
180574
+ description: 'Kanban board: one card per row, grouped into `columns` by the row\'s `columnField`. Bind `data`/`loading` to a named query. `titleField` is the card title; `cardFields` add label/value lines with the DetailList field kinds (badge tones, status, user, relative, copy, ...). Dragging a card to another column runs `onMove` with `$row` = the moved row, `columnField` already set to the new column — typically `[{ "action": "app.mutate", "params": { "model": "<m>", "op": "update", "rowId": { "$row": "id" }, "values": { "<columnField>": { "$row": "<columnField>" } } } }]`. Without `onMove` the board is read-only. `onCardClick` runs with `$row` (e.g. an `app.navigate` that opens a Drawer).',
179269
180575
  props: {
179270
180576
  $schema: "http://json-schema.org/draft-07/schema#",
179271
180577
  type: "object",
@@ -179326,7 +180632,21 @@ var catalog_generated_default = {
179326
180632
  },
179327
180633
  kind: {
179328
180634
  type: "string",
179329
- enum: ["text", "string", "number", "boolean", "date", "badge", "enum", "code"]
180635
+ enum: [
180636
+ "text",
180637
+ "string",
180638
+ "number",
180639
+ "boolean",
180640
+ "date",
180641
+ "badge",
180642
+ "enum",
180643
+ "code",
180644
+ "status",
180645
+ "user",
180646
+ "relative",
180647
+ "copy",
180648
+ "json"
180649
+ ]
179330
180650
  },
179331
180651
  tones: {
179332
180652
  type: "object",
@@ -179610,6 +180930,57 @@ var catalog_generated_default = {
179610
180930
  additionalProperties: false
179611
180931
  }
179612
180932
  },
180933
+ "ui.toast": {
180934
+ description: 'Show a toast: `message`, optional `description`, `tone` success|error|info|warning (default info). `undo: { label?, actions }` adds an Undo button (label defaults to "Undo") that runs `actions` as a chain — e.g. an `app.mutate` that restores the row a delete just removed.',
180935
+ params: {
180936
+ $schema: "http://json-schema.org/draft-07/schema#",
180937
+ type: "object",
180938
+ properties: {
180939
+ message: {
180940
+ type: "string"
180941
+ },
180942
+ description: {
180943
+ type: "string"
180944
+ },
180945
+ tone: {
180946
+ type: "string",
180947
+ enum: ["success", "error", "info", "warning"]
180948
+ },
180949
+ undo: {
180950
+ type: "object",
180951
+ properties: {
180952
+ label: {
180953
+ type: "string"
180954
+ },
180955
+ actions: {
180956
+ type: "array",
180957
+ items: {
180958
+ type: "object",
180959
+ properties: {
180960
+ action: {
180961
+ type: "string"
180962
+ },
180963
+ params: {
180964
+ type: "object",
180965
+ propertyNames: {
180966
+ type: "string"
180967
+ },
180968
+ additionalProperties: {}
180969
+ }
180970
+ },
180971
+ required: ["action"],
180972
+ additionalProperties: false
180973
+ }
180974
+ }
180975
+ },
180976
+ required: ["actions"],
180977
+ additionalProperties: false
180978
+ }
180979
+ },
180980
+ required: ["message"],
180981
+ additionalProperties: false
180982
+ }
180983
+ },
179613
180984
  "app.mutate": {
179614
180985
  description: "Create / update / delete a swarm-app row, then refetch every named query on the same model.",
179615
180986
  params: {
@@ -179721,12 +181092,37 @@ var ELEMENT_KEYS = new Set([
179721
181092
  "repeat",
179722
181093
  "watch"
179723
181094
  ]);
179724
- var UI_STATE_COMPONENTS = new Set(["SearchInput", "Select", "Tabs"]);
181095
+ var UI_STATE_COMPONENTS = new Set(["SearchInput", "Select", "Tabs", "Chips"]);
179725
181096
  var PROP_ACTION_CHAINS = {
181097
+ Table: ["onRowClick"],
179726
181098
  Form: ["onSubmit"],
179727
181099
  Kanban: ["onMove", "onCardClick"],
179728
181100
  Calendar: ["onSelect"]
179729
181101
  };
181102
+ var ITEM_ACTION_CHAINS = {
181103
+ Table: [
181104
+ ["rowActions", "actions"],
181105
+ ["columns", "onChange"]
181106
+ ],
181107
+ Drawer: [["actions", "actions"]]
181108
+ };
181109
+ function itemActionChains(type, props, propsPath) {
181110
+ const chains = [];
181111
+ for (const [arrayProp, chainKey] of ITEM_ACTION_CHAINS[String(type)] ?? []) {
181112
+ const items = props[arrayProp];
181113
+ if (!Array.isArray(items))
181114
+ continue;
181115
+ for (const [index, item] of items.entries()) {
181116
+ if (!isPlainObject(item) || !Object.hasOwn(item, chainKey))
181117
+ continue;
181118
+ chains.push({
181119
+ path: `${propsPath}.${arrayProp}.${index}.${chainKey}`,
181120
+ chain: item[chainKey]
181121
+ });
181122
+ }
181123
+ }
181124
+ return chains;
181125
+ }
179730
181126
  var DATA_FIELD_PROPS = {
179731
181127
  Kanban: ["columnField", "titleField", "idField"],
179732
181128
  Calendar: ["startField", "endField", "titleField", "idField"],
@@ -179965,9 +181361,9 @@ function actionParams(step, path2, definition, catalog, validateNavigation = fal
179965
181361
  }
179966
181362
  if (op === "update" || op === "delete") {
179967
181363
  const rowId = params.rowId;
179968
- const validRowId = typeof rowId === "string" || isPlainObject(rowId) && typeof rowId.$row === "string" && Object.keys(rowId).length === 1;
181364
+ const validRowId = typeof rowId === "string" || isStateBinding(rowId) || isPlainObject(rowId) && typeof rowId.$row === "string" && Object.keys(rowId).length === 1;
179969
181365
  if (!validRowId) {
179970
- result.issues.push(issue(appendPath(paramsPath, "rowId"), "is required for update and delete and must be a string or $row binding"));
181366
+ result.issues.push(issue(appendPath(paramsPath, "rowId"), "is required for update and delete and must be a string, $row, or $state binding"));
179971
181367
  }
179972
181368
  }
179973
181369
  if (isPlainObject(params.values) && !isActionSentinel(params.values) && !isStateBinding(params.values)) {
@@ -179986,6 +181382,13 @@ function actionParams(step, path2, definition, catalog, validateNavigation = fal
179986
181382
  if (typeof params.name !== "string" || !Object.hasOwn(definition.actions ?? {}, params.name)) {
179987
181383
  result.issues.push(issue(appendPath(paramsPath, "name"), `unknown app action "${String(params.name)}"`));
179988
181384
  }
181385
+ } else if (step.action === "ui.toast") {
181386
+ const undo = toastUndoChain(step);
181387
+ if (Array.isArray(undo)) {
181388
+ const undoResult = validateActionChain(undo, appendPath(appendPath(paramsPath, "undo"), "actions"), definition, catalog);
181389
+ result.issues.push(...undoResult.issues);
181390
+ result.stateRefs.push(...undoResult.stateRefs);
181391
+ }
179989
181392
  }
179990
181393
  return result;
179991
181394
  }
@@ -180170,10 +181573,21 @@ function visitActionChain(chain, path2, visit, allowSingle) {
180170
181573
  if (!Array.isArray(normalized))
180171
181574
  return;
180172
181575
  for (const [index, step] of normalized.entries()) {
180173
- if (isPlainObject(step))
180174
- visit(step, appendPath(path2, index));
181576
+ if (!isPlainObject(step))
181577
+ continue;
181578
+ const stepPath = appendPath(path2, index);
181579
+ visit(step, stepPath);
181580
+ const undo = toastUndoChain(step);
181581
+ if (undo !== undefined)
181582
+ visitActionChain(undo, `${stepPath}.params.undo.actions`, visit, false);
180175
181583
  }
180176
181584
  }
181585
+ function toastUndoChain(step) {
181586
+ if (step.action !== "ui.toast" || !isPlainObject(step.params))
181587
+ return;
181588
+ const undo = step.params.undo;
181589
+ return isPlainObject(undo) && Object.hasOwn(undo, "actions") ? undo.actions : undefined;
181590
+ }
180177
181591
  function visitPageActionSteps(page, pagePath, visit) {
180178
181592
  if (!isPlainObject(page.elements))
180179
181593
  return;
@@ -180191,12 +181605,8 @@ function visitPageActionSteps(page, pagePath, visit) {
180191
181605
  }
180192
181606
  if (!isPlainObject(rawElement.props))
180193
181607
  continue;
180194
- if (rawElement.type === "Table" && Array.isArray(rawElement.props.rowActions)) {
180195
- for (const [index, rowAction] of rawElement.props.rowActions.entries()) {
180196
- if (!isPlainObject(rowAction))
180197
- continue;
180198
- visitActionChain(rowAction.actions, `${elementPath}.props.rowActions.${index}.actions`, visit, false);
180199
- }
181608
+ for (const { path: path2, chain } of itemActionChains(rawElement.type, rawElement.props, `${elementPath}.props`)) {
181609
+ visitActionChain(chain, path2, visit, false);
180200
181610
  }
180201
181611
  for (const prop of PROP_ACTION_CHAINS[String(rawElement.type)] ?? []) {
180202
181612
  visitActionChain(rawElement.props[prop], `${elementPath}.props.${prop}`, visit, false);
@@ -180526,7 +181936,8 @@ function validatePage(definition, catalog, target) {
180526
181936
  }
180527
181937
  if (component) {
180528
181938
  const propsPath = appendPath(elementPath, "props");
180529
- const actionChainPath = (path2) => (PROP_ACTION_CHAINS[String(type)] ?? []).some((prop) => path2 === `${propsPath}.${prop}`) || type === "Table" && /^.+\.rowActions\.\d+\.actions$/.test(path2);
181939
+ const itemChainPaths = new Set(isPlainObject(rawElement.props) ? itemActionChains(type, rawElement.props, propsPath).map(({ path: path2 }) => path2) : []);
181940
+ const actionChainPath = (path2) => (PROP_ACTION_CHAINS[String(type)] ?? []).some((prop) => path2 === `${propsPath}.${prop}`) || itemChainPaths.has(path2);
180530
181941
  const propsResult = validateSchema(Object.hasOwn(rawElement, "props") ? rawElement.props : {}, component.props, propsPath, false, actionChainPath);
180531
181942
  issues.push(...propsResult.issues);
180532
181943
  stateRefs.push(...propsResult.stateRefs);
@@ -180563,6 +181974,9 @@ function validatePage(definition, catalog, target) {
180563
181974
  }
180564
181975
  }
180565
181976
  collectRowFieldIssues(rawElement.props.rowActions, `${elementPath}.props.rowActions`, queryModel.modelName, queryModel.model, issues);
181977
+ for (const prop of ["onRowClick", "columns"]) {
181978
+ collectRowFieldIssues(rawElement.props[prop], `${elementPath}.props.${prop}`, queryModel.modelName, queryModel.model, issues);
181979
+ }
180566
181980
  }
180567
181981
  } else if (type === "DetailList") {
180568
181982
  const queryModel = queryModelFromDataBinding(definition, rawElement.props.data);
@@ -180659,16 +182073,12 @@ function validatePage(definition, catalog, target) {
180659
182073
  issues.push(...visibleConditionIssues(rawElement[key], bindingPath));
180660
182074
  }
180661
182075
  }
180662
- if (type === "Table" && isPlainObject(rawElement.props) && Array.isArray(rawElement.props.rowActions)) {
180663
- for (const [rowActionIndex, rowAction] of rawElement.props.rowActions.entries()) {
180664
- if (!isPlainObject(rowAction) || !Object.hasOwn(rowAction, "actions"))
180665
- continue;
180666
- const chainResult = validateActionChain(rowAction.actions, `${elementPath}.props.rowActions.${rowActionIndex}.actions`, definition, catalog);
182076
+ if (isPlainObject(rawElement.props)) {
182077
+ for (const { path: path2, chain } of itemActionChains(type, rawElement.props, `${elementPath}.props`)) {
182078
+ const chainResult = validateActionChain(chain, path2, definition, catalog);
180667
182079
  issues.push(...chainResult.issues);
180668
182080
  stateRefs.push(...chainResult.stateRefs);
180669
182081
  }
180670
- }
180671
- if (isPlainObject(rawElement.props)) {
180672
182082
  for (const prop of PROP_ACTION_CHAINS[String(type)] ?? []) {
180673
182083
  if (!Object.hasOwn(rawElement.props, prop))
180674
182084
  continue;
@@ -182939,4 +184349,4 @@ void _scriptMain;
182939
184349
  });
182940
184350
  }
182941
184351
 
182942
- export { require_dist, isInvalidClientError, assertUrlSafe, publicEndpointSsrfOptions, discoverProtectedResourceMetadata, discoverAuthorizationServerMetadata, normalizeTokenEndpointAuthMethod, resolveAdvertisedTokenEndpointAuthMethod, authMethodForStoredClient, selectDcrTokenEndpointAuthMethod, registerClient, buildAuthorizeUrl, exchangeCodeForTokens, refreshMcpToken, revokeMcpToken, computeExpiresAt, getMcpOAuthToken, findReusableMcpOAuthClient, invalidateMcpOAuthClient, upsertMcpOAuthToken, applyMcpOAuthRefresh, markMcpOAuthTokenStatus, deleteMcpOAuthToken, insertMcpOAuthPending, consumeMcpOAuthPending, gcMcpOAuthPending, setMcpServerAuthMethod, ensureMcpToken, callMcpServerTool, listVendoredOpenapiEntries, ConnectionAuthInputSchema, connectionAuthSummary, listRelationalCredentialBindings, getCredentialBindingById, findCredentialBindingByIdentity, upsertCredentialBinding, disableCredentialBinding, listScriptConnections, listScriptConnectionsAsync, getScriptConnectionById, ScriptConnectionConflictError, connectionAuthInputFromFlat, upsertScriptConnection, refreshScriptConnection, setScriptConnectionEnabled, deleteScriptConnection, getScriptApiConnectionDescriptors, getScriptMcpConnectionDescriptors, getScriptApiTypes, getScriptMcpTypes, oauthAppToProviderConfig, getOAuthProviderConfig, getOAuthBindingTokenStatus, buildScriptCredentialBindingsWithFailures, buildScriptCredentialBindings, buildSandboxedCommand, sandboxSpawnEnv, createCappedStreamState, snapshotCapped, readStreamCapped, writeBareImportShim, MIN_SCRIPT_WALL_CLOCK_MS, SCRIPT_LONG_TIMEOUT_HINT_MS, MAX_SCRIPT_WALL_CLOCK_MS, DEFAULT_SCRIPT_RESOURCES, require_typescript, checkImportAllowlist, validateScriptImports, runScript, extractScriptSignature, extractArgsJsonSchema, getSavedScriptOwnerAgentId, runSavedScriptAsAgent, resolveSyncRunAs, AppNameSchema, ColumnKindSchema, isIso8601Date, SYSTEM_COLUMN_KINDS, SORTABLE_SYSTEM_DATE_COLUMNS, AppElementsSchema, AppDefinitionSchema, collectScriptReferences, parseAppDefinition, applyAppDefinitionPatch, upgradeAppDefinition, decodeAppDefinition, appDefinitionNeedsRepair, createApp, getApp, listApps, listAppRecords, updateApp, deleteApp, getScriptAppTypes, SCRIPT_SDK_TYPES, scriptSdkTypesWithGeneratedApis, SCRIPT_STDLIB_MODULE_TYPES, scriptStdlibTypesWithGeneratedApis, typecheckWithAmbient, typecheckScript };
184352
+ export { require_dist, isInvalidClientError, assertUrlSafe, publicEndpointSsrfOptions, mcpOAuthSsrfOptions, discoverProtectedResourceMetadata, discoverAuthorizationServerMetadata, normalizeTokenEndpointAuthMethod, resolveAdvertisedTokenEndpointAuthMethod, authMethodForStoredClient, selectDcrTokenEndpointAuthMethod, registerClient, buildAuthorizeUrl, exchangeCodeForTokens, refreshMcpToken, revokeMcpToken, computeExpiresAt, getMcpOAuthToken, findReusableMcpOAuthClient, invalidateMcpOAuthClient, upsertMcpOAuthToken, applyMcpOAuthRefresh, markMcpOAuthTokenStatus, deleteMcpOAuthToken, insertMcpOAuthPending, consumeMcpOAuthPending, gcMcpOAuthPending, setMcpServerAuthMethod, ensureMcpToken, callMcpServerTool, resolveSqlDsn, runReadOnlyQuery, listVendoredOpenapiEntries, ConnectionAuthInputSchema, SqlDsnInputSchema, connectionAuthSummary, listRelationalCredentialBindings, getCredentialBindingById, findCredentialBindingByIdentity, upsertCredentialBinding, disableCredentialBinding, listScriptConnections, listScriptConnectionsAsync, getScriptConnectionById, ScriptConnectionConflictError, connectionAuthInputFromFlat, upsertScriptConnection, refreshScriptConnection, setScriptConnectionEnabled, deleteScriptConnection, getScriptApiConnectionDescriptors, getScriptMcpConnectionDescriptors, getScriptApiTypes, getScriptMcpTypes, oauthAppToProviderConfig, getOAuthProviderConfig, getOAuthBindingTokenStatus, buildScriptCredentialBindingsWithFailures, buildScriptCredentialBindings, buildSandboxedCommand, sandboxSpawnEnv, createCappedStreamState, snapshotCapped, readStreamCapped, writeBareImportShim, MIN_SCRIPT_WALL_CLOCK_MS, SCRIPT_LONG_TIMEOUT_HINT_MS, MAX_SCRIPT_WALL_CLOCK_MS, DEFAULT_SCRIPT_RESOURCES, require_typescript, checkImportAllowlist, validateScriptImports, runScript, extractScriptSignature, extractArgsJsonSchema, getSavedScriptOwnerAgentId, runSavedScriptAsAgent, resolveSyncRunAs, AppNameSchema, ColumnKindSchema, isIso8601Date, SYSTEM_COLUMN_KINDS, SORTABLE_SYSTEM_DATE_COLUMNS, AppElementsSchema, AppDefinitionSchema, collectScriptReferences, parseAppDefinition, applyAppDefinitionPatch, upgradeAppDefinition, decodeAppDefinition, appDefinitionNeedsRepair, createApp, getApp, listApps, listAppRecords, updateApp, deleteApp, getScriptAppTypes, SCRIPT_SDK_TYPES, scriptSdkTypesWithGeneratedApis, SCRIPT_STDLIB_MODULE_TYPES, scriptStdlibTypesWithGeneratedApis, typecheckWithAmbient, typecheckScript };