@voltro/cli 0.12.0 → 0.13.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 (85) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/dist/{apiBuild-GefjNI5d.js → apiBuild-B6_ehbem.js} +3 -3
  3. package/dist/apiBuild-Bzpb383i.js +2 -0
  4. package/dist/bin.js +3 -3
  5. package/dist/{commands-BmNi1RgZ.js → commands-DYOuGlEC.js} +1668 -1371
  6. package/dist/dbCommand-ADD4mrTI.js +2 -0
  7. package/dist/{dbCommand-DNrkb58g.js → dbCommand-DIOJQwsq.js} +71 -57
  8. package/dist/{dev-d0LjACxE.js → dev-Fb9BmavX.js} +1483 -1414
  9. package/dist/dev-xdijqojc.js +3 -0
  10. package/dist/{seedRunner-DZmhoqNt.js → frameworkTableAssembly-CYlrafoK.js} +110 -331
  11. package/dist/frameworkTableAssembly-XvKO7wQt.js +2 -0
  12. package/dist/index.js +1 -1
  13. package/dist/{inspectMetrics-uEfIS1vp.js → inspectMetrics-DOiiII34.js} +302 -293
  14. package/dist/seedRunner-D6eu-u5U.js +229 -0
  15. package/dist/{serveCommand-B2-YV9TU.js → serveCommand-CqYxzBZR.js} +368 -367
  16. package/dist/serveEntry.js +3 -3
  17. package/dist/{start-DKcQd52a.js → start-CjG_0xhR.js} +1 -1
  18. package/dist/startEntry.js +2 -2
  19. package/package.json +17 -17
  20. package/templates/AGENTS.md +1 -1
  21. package/templates/agent-docs/_index.md +1 -1
  22. package/templates/agent-docs/authentication.md +36 -0
  23. package/templates/agent-docs/cli.md +78 -4
  24. package/templates/agent-docs/configuration.md +48 -0
  25. package/templates/agent-docs/database/migrations.md +32 -0
  26. package/templates/agent-docs/database/transactions.md +31 -0
  27. package/templates/agent-docs/testing.md +24 -0
  28. package/templates/agent-docs/whats-new.md +41 -137
  29. package/templates/apps/api-ai/package.json +7 -7
  30. package/templates/apps/api-auth/package.json +8 -8
  31. package/templates/apps/api-backend/package.json +7 -7
  32. package/templates/apps/api-backend-deactivation/package.json +7 -7
  33. package/templates/apps/api-backend-deactivation/tests/users.deactivate.test.ts +1 -1
  34. package/templates/apps/api-backend-mail/package.json +8 -8
  35. package/templates/apps/api-backend-mariadb/package.json +9 -9
  36. package/templates/apps/api-backend-storage/package.json +8 -8
  37. package/templates/apps/api-data-advanced/package.json +8 -8
  38. package/templates/apps/api-data-advanced/tests/queries.test.ts +6 -1
  39. package/templates/apps/api-durable/package.json +8 -8
  40. package/templates/apps/api-feature-flags/package.json +9 -9
  41. package/templates/apps/api-governance/app.config.ts +0 -1
  42. package/templates/apps/api-governance/package.json +8 -8
  43. package/templates/apps/api-kv/package.json +8 -8
  44. package/templates/apps/api-kv/tests/sync.test.ts +2 -2
  45. package/templates/apps/api-moderation/package.json +8 -8
  46. package/templates/apps/api-observability/package.json +8 -8
  47. package/templates/apps/api-ratelimit/package.json +8 -8
  48. package/templates/apps/api-rbac/README.md +53 -14
  49. package/templates/apps/api-rbac/app.config.ts +24 -26
  50. package/templates/apps/api-rbac/authz.ts +76 -0
  51. package/templates/apps/api-rbac/database/schema.ts +23 -6
  52. package/templates/apps/api-rbac/mutations/notes.create.mutation.server.ts +7 -5
  53. package/templates/apps/api-rbac/mutations/notes.create.mutation.ts +15 -8
  54. package/templates/apps/api-rbac/mutations/notes.delete.mutation.server.ts +54 -0
  55. package/templates/apps/api-rbac/mutations/notes.delete.mutation.ts +43 -0
  56. package/templates/apps/api-rbac/mutations/teams.rename.mutation.server.ts +19 -0
  57. package/templates/apps/api-rbac/mutations/teams.rename.mutation.ts +37 -0
  58. package/templates/apps/api-rbac/package.json +8 -8
  59. package/templates/apps/api-rbac/queries/notes.list.query.server.ts +12 -0
  60. package/templates/apps/api-rbac/queries/notes.list.query.ts +26 -0
  61. package/templates/apps/api-rbac/template.json +2 -2
  62. package/templates/apps/api-rbac/tests/authz.test.ts +233 -0
  63. package/templates/apps/api-rest/package.json +7 -7
  64. package/templates/apps/api-saas/package.json +11 -11
  65. package/templates/apps/api-search/package.json +8 -8
  66. package/templates/apps/api-versioning/package.json +8 -8
  67. package/templates/apps/api-webhooks/package.json +9 -8
  68. package/templates/apps/changelog/package.json +6 -6
  69. package/templates/apps/edge-functions/package.json +2 -2
  70. package/templates/apps/frontend-admin/package.json +8 -8
  71. package/templates/apps/frontend-app/package.json +8 -8
  72. package/templates/apps/frontend-blank/package.json +7 -7
  73. package/templates/apps/frontend-contact/package.json +7 -7
  74. package/templates/apps/frontend-dashboard/package.json +7 -7
  75. package/templates/apps/frontend-docs/package.json +7 -7
  76. package/templates/apps/frontend-i18n/package.json +6 -6
  77. package/templates/apps/frontend-landing/package.json +7 -7
  78. package/templates/apps/frontend-spa/package.json +7 -7
  79. package/templates/apps/frontend-ssr/package.json +7 -7
  80. package/templates/apps/frontend-ssr-api/package.json +8 -8
  81. package/templates/apps/frontend-static-blog/package.json +6 -6
  82. package/dist/apiBuild-s7swuEU5.js +0 -2
  83. package/dist/dbCommand-Bt6BCG7g.js +0 -2
  84. package/dist/dev-YHbHmeXt.js +0 -3
  85. package/templates/apps/api-rbac/tests/notes.create.test.ts +0 -80
@@ -3,66 +3,28 @@ import { basename as t, join as n } from "node:path";
3
3
  import { pathToFileURL as r } from "node:url";
4
4
  import { Effect as i } from "effect";
5
5
  import { promises as a } from "node:fs";
6
- import { _voltroConnectionGrantsTable as o, _voltroConnectionsTable as s, _voltroScheduleClaimsTable as c, _voltroScheduleRunsTable as l, _voltroTracesTable as u, _voltroUndoLogTable as d, _voltroWakeupsTable as ee, _voltroWorkflowEventDeliveriesTable as te, _voltroWorkflowEventsTable as ne, outboxAttemptsTable as re, outboxTable as ie, undoCaptureEnabled as f } from "@voltro/runtime";
7
- import { createRequire as ae } from "node:module";
6
+ import { _voltroConnectionGrantsTable as o, _voltroConnectionsTable as s, _voltroScheduleClaimsTable as c, _voltroScheduleRunsTable as l, _voltroTracesTable as u, _voltroUndoLogTable as d, _voltroWakeupsTable as ee, _voltroWorkflowEventDeliveriesTable as f, _voltroWorkflowEventsTable as te, outboxAttemptsTable as ne, outboxTable as re, undoCaptureEnabled as ie } from "@voltro/runtime";
8
7
  import { SqlClient as p } from "@effect/sql";
9
- import { _voltroWorkflowRunEventsTable as oe, _voltroWorkflowRunStepsTable as se, _voltroWorkflowRunsTable as ce, _voltroWorkflowStartContextsTable as le } from "@voltro/workflow";
10
- import { agentMessagesTable as ue, agentThreadsTable as de, aiBudgetTable as fe, aiUsageTable as pe, isAgentDescriptor as me, isAgentExecutor as he, resolveToolModuleHandlers as ge } from "@voltro/ai";
11
- import { _voltroApiKeysTable as _e, _voltroCdcOffsetsTable as ve, _voltroIdempotencyTable as ye, _voltroKvTable as be, _voltroMigrationPlansTable as xe, _voltroMigrationsTable as Se, _voltroMssqlCdcOffsetsTable as Ce, _voltroSeedsTable as m, and as we, eq as h, generateId as g, isSeedDefinition as _, lt as Te } from "@voltro/database";
12
- import { _voltroWebhookDeliveriesTable as Ee, _voltroWebhookTargetsTable as De } from "@voltro/plugin-webhooks/mixin";
13
- import { _voltroStorageBlobsTable as v, _voltroStorageGrantsTable as y, _voltroStorageRefsTable as b, _voltroStorageUsageTable as x } from "@voltro/plugin-storage";
14
- import { defineAction as S, defineMutation as C, defineQuery as w } from "@voltro/protocol";
15
- import { createHash as T } from "node:crypto";
16
- //#region src/dialectDriver.ts
17
- var E = {
18
- postgres: "@voltro/sql-postgres",
19
- sqlite: "@voltro/sql-sqlite",
20
- mysql: "@voltro/sql-mysql",
21
- mariadb: "@voltro/sql-mysql",
22
- mssql: "@voltro/sql-mssql",
23
- turso: "@voltro/sql-turso"
24
- }, Oe = [...new Set(Object.values(E))], ke = {
25
- postgres: "postgresDialect",
26
- sqlite: "sqliteDialect",
27
- mysql: "mysqlDialect",
28
- mariadb: "mariadbDialect",
29
- mssql: "mssqlDialect",
30
- turso: "tursoDialect"
31
- }, D = /* @__PURE__ */ new Map(), Ae = (e, t) => {
32
- D.set(e, t);
33
- }, O = async (e) => {
34
- let t = D.get(e);
35
- if (t) return t;
36
- try {
37
- return await import(r(ae(n(process.cwd(), "package.json")).resolve(e)).href);
38
- } catch {
39
- try {
40
- return await import(e);
41
- } catch {
42
- throw Error(`The '${e}' database driver is not installed.\n\nEvery Voltro app declares the driver for its DB dialect as a dependency (a memory store needs none). Install it in the app:\n\n pnpm add ${e}\n`);
43
- }
44
- }
45
- }, je = async (e) => {
46
- let t = E[e];
47
- if (!t) throw Error(`Unsupported DB_DIALECT='${e}'. Supported: memory, postgres, sqlite, mysql, mariadb, mssql, turso.`);
48
- return (await O(t))[ke[e]];
49
- }, Me = [
8
+ import { _voltroWorkflowRunEventsTable as ae, _voltroWorkflowRunStepsTable as oe, _voltroWorkflowRunsTable as se, _voltroWorkflowStartContextsTable as m } from "@voltro/workflow";
9
+ import { agentMessagesTable as ce, agentThreadsTable as le, aiBudgetTable as ue, aiUsageTable as de, isAgentDescriptor as fe, isAgentExecutor as pe, resolveToolModuleHandlers as me } from "@voltro/ai";
10
+ import { _voltroApiKeysTable as he, _voltroCdcOffsetsTable as ge, _voltroIdempotencyTable as _e, _voltroKvTable as ve, _voltroMigrationPlansTable as ye, _voltroMigrationsTable as be, _voltroMssqlCdcOffsetsTable as h, _voltroSeedsTable as g, lt as _ } from "@voltro/database";
11
+ import { _voltroWebhookDeliveriesTable as v, _voltroWebhookTargetsTable as y } from "@voltro/plugin-webhooks/mixin";
12
+ import { _voltroStorageBlobsTable as b, _voltroStorageGrantsTable as x, _voltroStorageRefsTable as S, _voltroStorageUsageTable as C } from "@voltro/plugin-storage";
13
+ import { defineAction as w, defineMutation as T, defineQuery as E } from "@voltro/protocol";
14
+ //#region src/frameworkTables.ts
15
+ var D = [
50
16
  {
51
- table: Se,
17
+ table: be,
52
18
  when: "always"
53
19
  },
54
20
  {
55
- table: m,
21
+ table: g,
56
22
  when: "always"
57
23
  },
58
24
  {
59
- table: xe,
25
+ table: ye,
60
26
  when: "always"
61
27
  },
62
- {
63
- table: ce,
64
- when: "workflows"
65
- },
66
28
  {
67
29
  table: se,
68
30
  when: "workflows"
@@ -72,17 +34,21 @@ var E = {
72
34
  when: "workflows"
73
35
  },
74
36
  {
75
- table: le,
37
+ table: ae,
76
38
  when: "workflows"
77
39
  },
78
40
  {
79
- table: ne,
41
+ table: m,
80
42
  when: "workflows"
81
43
  },
82
44
  {
83
45
  table: te,
84
46
  when: "workflows"
85
47
  },
48
+ {
49
+ table: f,
50
+ when: "workflows"
51
+ },
86
52
  {
87
53
  table: l,
88
54
  when: "schedules"
@@ -92,11 +58,11 @@ var E = {
92
58
  when: "schedules"
93
59
  },
94
60
  {
95
- table: De,
61
+ table: y,
96
62
  when: "webhooks"
97
63
  },
98
64
  {
99
- table: Ee,
65
+ table: v,
100
66
  when: "webhooks"
101
67
  },
102
68
  {
@@ -108,11 +74,11 @@ var E = {
108
74
  when: "undo"
109
75
  },
110
76
  {
111
- table: ie,
77
+ table: re,
112
78
  when: "outbox"
113
79
  },
114
80
  {
115
- table: re,
81
+ table: ne,
116
82
  when: "outbox"
117
83
  },
118
84
  {
@@ -128,81 +94,81 @@ var E = {
128
94
  when: "always"
129
95
  },
130
96
  {
131
- table: b,
97
+ table: S,
132
98
  when: "always"
133
99
  },
134
100
  {
135
- table: y,
101
+ table: x,
136
102
  when: "always"
137
103
  },
138
104
  {
139
- table: v,
105
+ table: b,
140
106
  when: "always"
141
107
  },
142
108
  {
143
- table: x,
109
+ table: C,
144
110
  when: "always"
145
111
  },
146
112
  {
147
- table: ye,
113
+ table: _e,
148
114
  when: "always"
149
115
  },
150
116
  {
151
- table: _e,
117
+ table: he,
152
118
  when: "always"
153
119
  },
154
120
  {
155
- table: be,
121
+ table: ve,
156
122
  when: "always"
157
123
  }
158
- ], k = (e) => {
159
- let t = Me.filter((t) => t.when === "always" || t.when === "workflows" && e.workflows || t.when === "schedules" && e.schedules || t.when === "webhooks" && e.webhooks || t.when === "traces" && e.traces || t.when === "undo" && e.undo === !0 || t.when === "outbox" && e.outbox === !0 || t.when === "connections" && e.connections === !0).map((e) => e.table);
160
- return e.cdc === !0 && t.push(e.cdcDialect === "mssql" ? Ce : ve), t;
161
- }, A = (e) => {
124
+ ], O = (e) => {
125
+ let t = D.filter((t) => t.when === "always" || t.when === "workflows" && e.workflows || t.when === "schedules" && e.schedules || t.when === "webhooks" && e.webhooks || t.when === "traces" && e.traces || t.when === "undo" && e.undo === !0 || t.when === "outbox" && e.outbox === !0 || t.when === "connections" && e.connections === !0).map((e) => e.table);
126
+ return e.cdc === !0 && t.push(e.cdcDialect === "mssql" ? h : ge), t;
127
+ }, k = (e) => {
162
128
  let t = e.startsWith("@") ? e.replace(/^@[^/]+\//, "") : e;
163
129
  return (t.startsWith("plugin-") ? t.slice(7) : t).replace(/-([a-zA-Z0-9])/g, (e, t) => t.toUpperCase());
164
- }, Ne = (e) => {
130
+ }, A = (e) => {
165
131
  let t = e.startsWith("@") ? e.replace(/^@[^/]+\//, "") : e;
166
132
  return (t.startsWith("plugin-") ? t.slice(7) : t).replace(/#/g, "--").replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
167
- }, Pe = (e, t) => t.name.includes(".") ? t.name : `${A(e.name)}.${t.name}`, Fe = (e, t, n) => {
133
+ }, j = (e, t) => t.name.includes(".") ? t.name : `${k(e.name)}.${t.name}`, M = (e, t, n) => {
168
134
  switch (e) {
169
- case "query": return w({
135
+ case "query": return E({
170
136
  name: t,
171
137
  input: n.input,
172
138
  output: n.output,
173
139
  ...n.error === void 0 ? {} : { error: n.error },
174
140
  ...n.source === void 0 ? {} : { source: n.source }
175
141
  });
176
- case "mutation": return C({
142
+ case "mutation": return T({
177
143
  name: t,
178
144
  input: n.input,
179
145
  output: n.output,
180
146
  ...n.error === void 0 ? {} : { error: n.error }
181
147
  });
182
- case "action": return S({
148
+ case "action": return w({
183
149
  name: t,
184
150
  input: n.input,
185
151
  output: n.output,
186
152
  ...n.error === void 0 ? {} : { error: n.error }
187
153
  });
188
154
  }
189
- }, Ie = (e) => (t, n) => i.suspend(() => {
155
+ }, N = (e) => (t, n) => i.suspend(() => {
190
156
  let r = { request: {
191
157
  subject: n.request.subject,
192
158
  traceId: n.request.traceId
193
159
  } };
194
160
  return e.execute(t, r);
195
- }), Le = (e) => {
161
+ }), xe = (e) => {
196
162
  let t = [];
197
163
  for (let n of e) {
198
164
  let e = n.routes ?? [];
199
165
  for (let r of e) {
200
- let e = Pe(n, r), i = Fe(r.kind, e, r);
166
+ let e = j(n, r), i = M(r.kind, e, r);
201
167
  t.push({
202
168
  kind: r.kind,
203
169
  file: `plugin:${n.name}`,
204
170
  descriptor: i,
205
- executor: Ie(r),
171
+ executor: N(r),
206
172
  plugin: {
207
173
  name: n.name,
208
174
  version: n.version
@@ -211,7 +177,7 @@ var E = {
211
177
  }
212
178
  }
213
179
  return t;
214
- }, Re = (e, t) => {
180
+ }, Se = (e, t) => {
215
181
  let n = /* @__PURE__ */ new Map();
216
182
  for (let e of t) n.set(e, "user-route");
217
183
  for (let t of e) {
@@ -219,9 +185,9 @@ var E = {
219
185
  if (r !== void 0) throw Error(`plugin route tag collision: "${e}" declared by plugin "${t.plugin.name}" but already claimed by ${r === "user-route" ? "a user-authored route" : `plugin "${r}"`}`);
220
186
  n.set(e, t.plugin.name);
221
187
  }
222
- }, j = "_voltro_plugin_migrations", ze = () => i.gen(function* () {
188
+ }, P = "_voltro_plugin_migrations", Ce = () => i.gen(function* () {
223
189
  yield* (yield* p.SqlClient).unsafe(`
224
- CREATE TABLE IF NOT EXISTS ${j} (
190
+ CREATE TABLE IF NOT EXISTS ${P} (
225
191
  id TEXT PRIMARY KEY,
226
192
  plugin_name TEXT NOT NULL,
227
193
  migration_id TEXT NOT NULL,
@@ -229,25 +195,25 @@ var E = {
229
195
  applied_at TEXT NOT NULL
230
196
  );
231
197
  `).pipe(i.orDie);
232
- }), Be = (e, t) => `${A(e)}__${t}`, Ve = () => i.gen(function* () {
233
- let e = yield* p.SqlClient, t = yield* e`SELECT id FROM ${e(j)}`.pipe(i.orDie);
198
+ }), we = (e, t) => `${k(e)}__${t}`, Te = () => i.gen(function* () {
199
+ let e = yield* p.SqlClient, t = yield* e`SELECT id FROM ${e(P)}`.pipe(i.orDie);
234
200
  return new Set(t.map((e) => e.id));
235
- }), He = (e) => i.gen(function* () {
201
+ }), Ee = (e) => i.gen(function* () {
236
202
  let t = yield* p.SqlClient, n = (/* @__PURE__ */ new Date()).toISOString();
237
203
  yield* t`
238
- INSERT INTO ${t(j)} (id, plugin_name, migration_id, description, applied_at)
204
+ INSERT INTO ${t(P)} (id, plugin_name, migration_id, description, applied_at)
239
205
  VALUES (${e.key}, ${e.pluginName}, ${e.migration.id}, ${e.migration.description ?? null}, ${n})
240
206
  `.pipe(i.orDie);
241
- }), Ue = (e) => i.gen(function* () {
207
+ }), De = (e) => i.gen(function* () {
242
208
  let t = e.flatMap((e) => (e.extendSchema?.migrations ?? []).map((t) => ({
243
209
  plugin: e,
244
210
  migration: t
245
211
  })));
246
212
  if (t.length === 0) return [];
247
- yield* ze();
248
- let n = yield* Ve(), r = [];
213
+ yield* Ce();
214
+ let n = yield* Te(), r = [];
249
215
  for (let { plugin: e, migration: a } of t) {
250
- let t = Be(e.name, a.id), o = Date.now();
216
+ let t = we(e.name, a.id), o = Date.now();
251
217
  if (n.has(t)) {
252
218
  r.push({
253
219
  pluginName: e.name,
@@ -259,7 +225,7 @@ var E = {
259
225
  }
260
226
  let s = yield* p.SqlClient;
261
227
  try {
262
- yield* a.up(s).pipe(i.mapError((e) => e)), yield* He({
228
+ yield* a.up(s).pipe(i.mapError((e) => e)), yield* Ee({
263
229
  key: t,
264
230
  pluginName: e.name,
265
231
  migration: a
@@ -280,24 +246,24 @@ var E = {
280
246
  }
281
247
  }
282
248
  return r;
283
- }), We = (e) => e.filter((e) => e.extendSchema && (e.extendSchema.tables?.length ?? 0) + (e.extendSchema.migrations?.length ?? 0) > 0).map((e) => ({
249
+ }), Oe = (e) => e.filter((e) => e.extendSchema && (e.extendSchema.tables?.length ?? 0) + (e.extendSchema.migrations?.length ?? 0) > 0).map((e) => ({
284
250
  pluginName: e.name,
285
- pluginAlias: A(e.name),
251
+ pluginAlias: k(e.name),
286
252
  tables: e.extendSchema.tables?.length ?? 0,
287
253
  migrations: e.extendSchema.migrations?.length ?? 0
288
- })), Ge = (e) => e.flatMap((e) => e.extendSchema?.tables ?? []), M = /(?<!\.server)\.agent\.tsx?$/, Ke = /\.agent\.server\.tsx?$/, N = /\.tool\.tsx?$/, qe = async (t, n) => {
254
+ })), ke = (e) => e.flatMap((e) => e.extendSchema?.tables ?? []), F = /(?<!\.server)\.agent\.tsx?$/, Ae = /\.agent\.server\.tsx?$/, I = /\.tool\.tsx?$/, L = async (t, n) => {
289
255
  let r = 0;
290
- for (let i of t) if (N.test(i)) try {
256
+ for (let i of t) if (I.test(i)) try {
291
257
  let t = await e(i);
292
- r += ge(t);
258
+ r += me(t);
293
259
  } catch (e) {
294
260
  n.warn("tool: failed to import — handler not wired", { file: i }, e);
295
261
  }
296
262
  return r;
297
- }, Je = (e) => e.replace(/\.agent\.(tsx?)$/, ".agent.server.$1"), Ye = async (t, n) => {
263
+ }, je = (e) => e.replace(/\.agent\.(tsx?)$/, ".agent.server.$1"), Me = async (t, n) => {
298
264
  let r = [], i = /* @__PURE__ */ new Set();
299
265
  for (let a of t) {
300
- if (!M.test(a)) continue;
266
+ if (!F.test(a)) continue;
301
267
  let t;
302
268
  try {
303
269
  t = await e(a);
@@ -305,7 +271,7 @@ var E = {
305
271
  n.warn("agent: failed to import descriptor", { file: a }, e);
306
272
  continue;
307
273
  }
308
- let o = Object.values(t).find(me);
274
+ let o = Object.values(t).find(fe);
309
275
  if (o === void 0) {
310
276
  n.warn("agent: no defineAgent() descriptor export found", { file: a });
311
277
  continue;
@@ -317,7 +283,7 @@ var E = {
317
283
  });
318
284
  continue;
319
285
  }
320
- let s = Je(a), c;
286
+ let s = je(a), c;
321
287
  try {
322
288
  c = await e(s);
323
289
  } catch (e) {
@@ -329,7 +295,7 @@ var E = {
329
295
  continue;
330
296
  }
331
297
  let l = c.default;
332
- if (!he(l)) {
298
+ if (!pe(l)) {
333
299
  n.warn("agent: executor file must default-export defineAgentExecutor(descriptor, {...})", {
334
300
  file: s,
335
301
  name: o.name
@@ -344,7 +310,7 @@ var E = {
344
310
  });
345
311
  }
346
312
  return { agents: r };
347
- }, P = /\.connection\.tsx?$/, Xe = (e) => e.replace(P, ""), Ze = async (n, r) => {
313
+ }, R = /\.connection\.tsx?$/, Ne = (e) => e.replace(R, ""), Pe = async (n, r) => {
348
314
  let i = [], a = /* @__PURE__ */ new Map();
349
315
  for (let t of n) {
350
316
  let n;
@@ -387,26 +353,26 @@ var E = {
387
353
  }
388
354
  return i.length > 0 && r.info("discovered connections", {
389
355
  connections: i.map((e) => `${e.definition.id} (${e.definition.kind})`),
390
- files: i.map((e) => Xe(t(e.file)))
356
+ files: i.map((e) => Ne(t(e.file)))
391
357
  }), i;
392
- }, F = (e) => typeof e.attributes["framework.kind"] == "string" && e.attributes["framework.kind"].startsWith("subscription."), I = (e) => {
358
+ }, z = (e) => typeof e.attributes["framework.kind"] == "string" && e.attributes["framework.kind"].startsWith("subscription."), B = (e) => {
393
359
  if (e.name.includes("_voltro_traces")) return !0;
394
360
  for (let t in e.attributes) {
395
361
  let n = e.attributes[t];
396
362
  if (typeof n == "string" && n.includes("_voltro_traces")) return !0;
397
363
  }
398
364
  return !1;
399
- }, Qe = (e) => typeof e.attributes["framework.kind"] == "string" && e.attributes["framework.kind"].startsWith("subscription"), $e = 1e3, et = 500, tt = 50, L = class {
365
+ }, Fe = (e) => typeof e.attributes["framework.kind"] == "string" && e.attributes["framework.kind"].startsWith("subscription"), Ie = 1e3, Le = 500, Re = 50, V = class {
400
366
  capacity;
401
367
  buffer = [];
402
- constructor(e = $e) {
368
+ constructor(e = Ie) {
403
369
  this.capacity = e;
404
370
  }
405
371
  append(e) {
406
372
  this.buffer.push(e), this.buffer.length > this.capacity && this.buffer.shift();
407
373
  }
408
374
  query(e = {}) {
409
- let t = e.since ?? 0, n = e.until ?? Date.now(), r = Math.min(e.max ?? et, this.capacity), i = e.traceId, a = e.minDurationMs, o = e.status, s = e.name?.toLowerCase(), c = [];
375
+ let t = e.since ?? 0, n = e.until ?? Date.now(), r = Math.min(e.max ?? Le, this.capacity), i = e.traceId, a = e.minDurationMs, o = e.status, s = e.name?.toLowerCase(), c = [];
410
376
  for (let e = this.buffer.length - 1; e >= 0 && c.length < r; e--) {
411
377
  let r = this.buffer[e];
412
378
  r.startMs < t || r.startMs > n || i !== void 0 && r.traceId !== i || a !== void 0 && r.durationMs < a || o !== void 0 && r.status !== o || s !== void 0 && !r.name.toLowerCase().includes(s) || c.push(r);
@@ -414,7 +380,7 @@ var E = {
414
380
  return c.reverse();
415
381
  }
416
382
  queryGrouped(e = {}) {
417
- let t = e.since ?? 0, n = e.maxTraces ?? tt, r = e.onlyErrors ?? !1, i = /* @__PURE__ */ new Map();
383
+ let t = e.since ?? 0, n = e.maxTraces ?? Re, r = e.onlyErrors ?? !1, i = /* @__PURE__ */ new Map();
418
384
  for (let e of this.buffer) {
419
385
  if (e.startMs < t) continue;
420
386
  let n = i.get(e.traceId);
@@ -425,7 +391,7 @@ var E = {
425
391
  t.sort((e, t) => e.startMs - t.startMs);
426
392
  let n = t.some((e) => e.status === "error");
427
393
  if (r && !n) continue;
428
- let i = t[0].startMs, o = t.reduce((e, t) => t.endMs > e ? t.endMs : e, i), s = t.filter(F), c = s.length > 0 || t.some(Qe), l = s.reduce((e, t) => e === void 0 || t.startMs > e.startMs ? t : e, void 0);
394
+ let i = t[0].startMs, o = t.reduce((e, t) => t.endMs > e ? t.endMs : e, i), s = t.filter(z), c = s.length > 0 || t.some(Fe), l = s.reduce((e, t) => e === void 0 || t.startMs > e.startMs ? t : e, void 0);
429
395
  a.push({
430
396
  traceId: e,
431
397
  rootName: t[0].name,
@@ -450,69 +416,69 @@ var E = {
450
416
  clear() {
451
417
  this.buffer = [];
452
418
  }
453
- }, R = null, nt = () => (R === null && (R = new L()), R), rt = /* @__PURE__ */ new Set([
419
+ }, H = null, ze = () => (H === null && (H = new V()), H), Be = /* @__PURE__ */ new Set([
454
420
  "off",
455
421
  "errors",
456
422
  "interesting",
457
423
  "all"
458
- ]), z = (e, t, n, r) => {
424
+ ]), U = (e, t, n, r) => {
459
425
  let i = Number(e);
460
426
  return Number.isFinite(i) ? Math.min(r, Math.max(n, i)) : t;
461
- }, it = (e) => e !== void 0 && [
427
+ }, Ve = (e) => e !== void 0 && [
462
428
  "1",
463
429
  "true",
464
430
  "yes",
465
431
  "on"
466
- ].includes(e.toLowerCase()), at = (e) => {
432
+ ].includes(e.toLowerCase()), He = (e) => {
467
433
  let t = Number(e);
468
434
  return Number.isFinite(t) && t > 0 ? t : 24;
469
- }, B = (e = process.env) => {
470
- let t = (e.VOLTRO_TRACING_BUFFER ?? "").toLowerCase() === "off", n = z(e.VOLTRO_TRACING_SAMPLE, 1, 0, 1), r = (e.VOLTRO_TRACING_PERSIST ?? "").toLowerCase(), i = e.NODE_ENV === "production" ? "off" : "interesting";
435
+ }, W = (e = process.env) => {
436
+ let t = (e.VOLTRO_TRACING_BUFFER ?? "").toLowerCase() === "off", n = U(e.VOLTRO_TRACING_SAMPLE, 1, 0, 1), r = (e.VOLTRO_TRACING_PERSIST ?? "").toLowerCase(), i = e.NODE_ENV === "production" ? "off" : "interesting";
471
437
  return {
472
- mode: rt.has(r) ? r : n <= 0 ? "off" : i,
438
+ mode: Be.has(r) ? r : n <= 0 ? "off" : i,
473
439
  sampleRate: n,
474
- slowMs: z(e.VOLTRO_TRACING_SLOW_MS, 500, 0, 2 ** 53 - 1),
475
- ttlHours: at(e.VOLTRO_TRACING_TTL_HOURS),
476
- persistDelivery: it(e.VOLTRO_TRACING_PERSIST_DELIVERY),
440
+ slowMs: U(e.VOLTRO_TRACING_SLOW_MS, 500, 0, 2 ** 53 - 1),
441
+ ttlHours: He(e.VOLTRO_TRACING_TTL_HOURS),
442
+ persistDelivery: Ve(e.VOLTRO_TRACING_PERSIST_DELIVERY),
477
443
  bufferDisabled: t
478
444
  };
479
- }, V = (e = process.env) => {
480
- let t = B(e);
445
+ }, G = (e = process.env) => {
446
+ let t = W(e);
481
447
  return !t.bufferDisabled && t.mode !== "off";
482
- }, ot = (e, t) => {
448
+ }, Ue = (e, t) => {
483
449
  if (t >= 1) return !0;
484
450
  if (t <= 0) return !1;
485
451
  let n = 2166136261;
486
452
  for (let t = 0; t < e.length; t++) n ^= e.charCodeAt(t), n = Math.imul(n, 16777619);
487
453
  return (n >>> 0) % 1e3 < t * 1e3;
488
- }, st = (e, t) => {
489
- if (t.mode === "off" || I(e) || F(e) && !t.persistDelivery) return !1;
454
+ }, We = (e, t) => {
455
+ if (t.mode === "off" || B(e) || z(e) && !t.persistDelivery) return !1;
490
456
  let n = e.status === "error";
491
457
  if (t.mode === "errors") return n;
492
458
  if (n) return !0;
493
- if (!ot(e.traceId, t.sampleRate)) return !1;
459
+ if (!Ue(e.traceId, t.sampleRate)) return !1;
494
460
  if (t.mode === "all") return !0;
495
461
  let r = e.parentSpanId === null || e.parentSpanId === void 0 || e.parentSpanId === "", i = typeof e.durationMs == "number" && e.durationMs >= t.slowMs;
496
462
  return r || i;
497
- }, ct = (e) => {
463
+ }, Ge = (e) => {
498
464
  if (e.bufferDisabled) return "durable traces: OFF (VOLTRO_TRACING_BUFFER=off)";
499
465
  if (e.mode === "off") return "durable traces: OFF — _voltro_traces not created (prod default; set VOLTRO_TRACING_PERSIST=interesting to enable, or use OTLP)";
500
466
  let t = e.mode === "interesting" ? ` (errors + slow≥${e.slowMs}ms + roots)` : e.mode === "errors" ? " (errors only)" : "";
501
467
  return `durable traces: mode=${e.mode}${t}` + (e.sampleRate < 1 ? ` · sample=${e.sampleRate}` : "") + (e.persistDelivery ? " · +delivery" : "") + ` · ttl=${e.ttlHours}h`;
502
- }, lt = (e = 30 * 6e4) => {
468
+ }, Ke = (e = 30 * 6e4) => {
503
469
  let t = /* @__PURE__ */ new Map();
504
470
  return (n, r) => {
505
471
  let i = t.get(n);
506
472
  return i !== void 0 && r - i < e ? !1 : (t.set(n, r), !0);
507
473
  };
508
- }, ut = (e) => {
509
- let { store: t, log: n } = e, r = e.policy ?? B();
510
- n.info(ct(r));
511
- let i = lt(), a = [], o = () => {};
474
+ }, qe = (e) => {
475
+ let { store: t, log: n } = e, r = e.policy ?? W();
476
+ n.info(Ge(r));
477
+ let i = Ke(), a = [], o = () => {};
512
478
  if (r.mode !== "off") {
513
479
  let e = [], s = 0;
514
480
  o = (t) => {
515
- st(t, r) && (e.length >= 5e3 && (e.shift(), s += 1, i("flush-drop", Date.now()) && (n.warn(`trace flush queue saturated — dropping durable spans (${s}+ since last warning). Durable inflow exceeds write throughput; reduce it with VOLTRO_TRACING_PERSIST=errors|interesting or VOLTRO_TRACING_SAMPLE<1.`), s = 0)), e.push(t));
481
+ We(t, r) && (e.length >= 5e3 && (e.shift(), s += 1, i("flush-drop", Date.now()) && (n.warn(`trace flush queue saturated — dropping durable spans (${s}+ since last warning). Durable inflow exceeds write throughput; reduce it with VOLTRO_TRACING_PERSIST=errors|interesting or VOLTRO_TRACING_SAMPLE<1.`), s = 0)), e.push(t));
516
482
  };
517
483
  let c = async () => {
518
484
  if (e.length === 0) return;
@@ -554,7 +520,7 @@ var E = {
554
520
  let n = await t.query({
555
521
  table: "_voltro_traces",
556
522
  order: [],
557
- predicate: Te("startedAt", e),
523
+ predicate: _("startedAt", e),
558
524
  projection: ["id"],
559
525
  skip: void 0,
560
526
  take: c
@@ -578,7 +544,7 @@ var E = {
578
544
  for (let e of a) clearInterval(e);
579
545
  }
580
546
  };
581
- }, dt = /\.(query|mutation|action|stream)\.ts$/, ft = /\.(query|mutation|action|stream)\.server\.ts$/, H = /\.workflow\.tsx$/, U = /\.workflow\.server\.tsx$/, W = /\.workflow\.tsx?$/, G = /\.trigger\.tsx?$/, K = /\.cron\.tsx?$/, q = /\.webhook\.tsx?$/, J = /\.outbox\.tsx?$/, pt = /\.subscribe\.tsx?$/, mt = /\.reaction\.tsx?$/, ht = /\.aggregate\.tsx?$/, gt = /\.startup\.tsx?$/, _t = /\.seed\.ts$/, vt = /\.relations\.ts$/, yt = /\.entity\.ts$|\.schema\.ts$|^schema\.ts$/, bt = (e) => W.test(e) && !H.test(e) && !U.test(e), xt = async (e) => {
547
+ }, Je = /\.(query|mutation|action|stream)\.ts$/, Ye = /\.(query|mutation|action|stream)\.server\.ts$/, K = /\.workflow\.tsx$/, q = /\.workflow\.server\.tsx$/, J = /\.workflow\.tsx?$/, Y = /\.trigger\.tsx?$/, X = /\.cron\.tsx?$/, Z = /\.webhook\.tsx?$/, Q = /\.outbox\.tsx?$/, Xe = /\.subscribe\.tsx?$/, Ze = /\.reaction\.tsx?$/, Qe = /\.aggregate\.tsx?$/, $e = /\.startup\.tsx?$/, et = /\.seed\.ts$/, tt = /\.relations\.ts$/, nt = /\.entity\.ts$|\.schema\.ts$|^schema\.ts$/, rt = (e) => J.test(e) && !K.test(e) && !q.test(e), it = async (e) => {
582
548
  let t = !1, r = !1, i = !1, o = !1, s = !1, c = !1, l = async (e) => {
583
549
  let u = await a.readdir(e, { withFileTypes: !0 }).catch(() => []);
584
550
  for (let a of u) if (a.isDirectory()) {
@@ -586,7 +552,7 @@ var E = {
586
552
  await l(n(e, a.name));
587
553
  } else {
588
554
  let e = a.name;
589
- (W.test(e) || G.test(e)) && (t = !0), K.test(e) && (r = !0), q.test(e) && (i = !0), M.test(e) && (o = !0), J.test(e) && (s = !0), P.test(e) && (c = !0);
555
+ (J.test(e) || Y.test(e)) && (t = !0), X.test(e) && (r = !0), Z.test(e) && (i = !0), F.test(e) && (o = !0), Q.test(e) && (s = !0), R.test(e) && (c = !0);
590
556
  }
591
557
  };
592
558
  return await l(e), {
@@ -597,225 +563,38 @@ var E = {
597
563
  outbox: s,
598
564
  connections: c
599
565
  };
600
- }, St = async (e) => {
566
+ }, at = async (e) => {
601
567
  try {
602
568
  return (await import(r(n(e, "app.config.ts")).href)).default?.plugins ?? [];
603
569
  } catch {
604
570
  return [];
605
571
  }
606
- }, Y = (e) => {
572
+ }, $ = (e) => {
607
573
  let t = /* @__PURE__ */ new Map(), n = (e) => {
608
574
  e?.tableName && !t.has(e.tableName) && t.set(e.tableName, e);
609
575
  };
610
- for (let t of k({
576
+ for (let t of O({
611
577
  workflows: e.mix.workflows,
612
578
  schedules: e.mix.schedules,
613
579
  webhooks: e.mix.webhooks,
614
- traces: V(),
580
+ traces: G(),
615
581
  cdc: e.cdc,
616
582
  ...e.cdcDialect ? { cdcDialect: e.cdcDialect } : {},
617
- undo: f(),
583
+ undo: ie(),
618
584
  outbox: e.mix.outbox,
619
585
  connections: e.mix.connections
620
586
  })) n(t);
621
- e.mix.agents && (n(de), n(ue), n(pe), n(fe));
622
- for (let t of Ge(e.plugins)) n(t);
587
+ e.mix.agents && (n(le), n(ce), n(de), n(ue));
588
+ for (let t of ke(e.plugins)) n(t);
623
589
  return [...t.values()];
624
- }, X = async (e) => {
625
- let t = await xt(e.root), n = await St(e.root), r = (process.env.DB_DIALECT ?? "postgres").toLowerCase(), i = r === "mariadb" ? "mariadb" : r === "mssql" ? "mssql" : void 0;
626
- return Y({
590
+ }, ot = async (e) => {
591
+ let t = await it(e.root), n = await at(e.root), r = (process.env.DB_DIALECT ?? "postgres").toLowerCase(), i = r === "mariadb" ? "mariadb" : r === "mssql" ? "mssql" : void 0;
592
+ return $({
627
593
  mix: t,
628
594
  plugins: n,
629
595
  cdc: e.cdc ?? (i !== void 0 && (process.env.CDC ?? "1") !== "0"),
630
596
  ...i ? { cdcDialect: i } : {}
631
597
  });
632
- }, Ct = async (e, t) => {
633
- let n = [];
634
- for (let i of e) {
635
- let e;
636
- try {
637
- e = await import(r(i).href);
638
- } catch (e) {
639
- t.warn("seed: failed to import", { file: i }, e);
640
- continue;
641
- }
642
- let o = (e.default && _(e.default) ? e.default : void 0) ?? Object.values(e).find(_);
643
- if (!o) {
644
- t.warn("seed: no defineSeed export", { file: i });
645
- continue;
646
- }
647
- let s = await a.readFile(i, "utf8").catch(() => ""), c = o.fingerprint ? o.fingerprint({ src: s }) : T("sha256").update(s).digest("hex").slice(0, 16);
648
- n.push({
649
- file: i,
650
- definition: o,
651
- fingerprint: c
652
- });
653
- }
654
- return n;
655
- }, wt = (e) => ({
656
- query: (t) => e.query({
657
- table: t.table,
658
- order: t.order ?? [],
659
- ...t.predicate ? { predicate: t.predicate } : {},
660
- ...t.take === void 0 ? {} : { take: t.take },
661
- ...t.skip === void 0 ? {} : { skip: t.skip },
662
- ...t.projection ? { projection: t.projection } : {}
663
- }),
664
- insert: (t, n) => e.insert(t, n),
665
- insertIgnore: (t, n, r) => e.insertIgnore(t, n, r),
666
- update: (t, n, r) => e.update(t, n, r),
667
- delete: (t, n) => e.delete(t, n)
668
- }), Tt = (e) => async (t, n, r) => {
669
- let i = Object.keys(n);
670
- if (i.length === 0) throw Error("upsertByUnique: matchFields must have at least one key");
671
- let a;
672
- if (i.length === 1) {
673
- let e = i[0];
674
- a = h(e, n[e]);
675
- } else a = we(...i.map((e) => h(e, n[e])));
676
- let o = (await e.query({
677
- table: t,
678
- order: [],
679
- predicate: a
680
- }))[0];
681
- if (o) {
682
- let n = o.id;
683
- return {
684
- row: await e.update(t, n, r) ?? o,
685
- created: !1
686
- };
687
- }
688
- return {
689
- row: await e.insert(t, r),
690
- created: !0
691
- };
692
- }, Et = (e, t) => {
693
- let n = Tt(e);
694
- return {
695
- store: wt(e),
696
- upsertByUnique: n,
697
- progress: (e, n) => t.debug("seed progress", {
698
- done: e,
699
- total: n
700
- })
701
- };
702
- }, Z = "_voltro_seeds", Dt = () => {
703
- let e = m.fields.id?.idScheme;
704
- return (e ? g(e, Z) : null) ?? g({
705
- kind: "typeid",
706
- prefix: "seed"
707
- }, Z);
708
- }, Ot = {
709
- isUnchanged: () => !1,
710
- record: async () => {}
711
- }, Q = async (e, t) => {
712
- let n;
713
- try {
714
- n = await e.query({
715
- table: Z,
716
- order: [],
717
- predicate: void 0,
718
- projection: void 0,
719
- skip: void 0,
720
- take: void 0
721
- });
722
- } catch (e) {
723
- return t.warn("seeds: ledger unreadable — every boot seed will run", {
724
- table: Z,
725
- error: String(e)
726
- }), Ot;
727
- }
728
- let r = new Map(n.map((e) => [e.name, e]));
729
- return {
730
- isUnchanged: (e) => {
731
- let t = r.get(e.definition.id);
732
- return t?.lastRunStatus === "succeeded" && t.fingerprint === e.fingerprint;
733
- },
734
- record: async (n, i) => {
735
- let a = {
736
- name: n.definition.id,
737
- lifecycle: n.definition.lifecycle,
738
- fingerprint: n.fingerprint,
739
- lastRunStatus: i.status,
740
- lastRunAt: /* @__PURE__ */ new Date(),
741
- lastRunDurationMs: i.durationMs,
742
- lastRunRowsTouched: i.rowsTouched,
743
- lastError: i.error?.message ?? null
744
- };
745
- try {
746
- let t = r.get(n.definition.id);
747
- t ? await e.update(Z, t.id, a) : await e.insert(Z, {
748
- id: Dt(),
749
- ...a
750
- });
751
- } catch (e) {
752
- t.warn("seeds: could not record the ledger row — this seed will re-run on every boot", {
753
- seedId: n.definition.id,
754
- table: Z,
755
- error: String(e)
756
- });
757
- }
758
- }
759
- };
760
- }, $ = async (e, t, n) => {
761
- let r = Date.now(), i = Et(t, n), a = 0;
762
- for (let t of e.definition.steps) try {
763
- let e = await t.body(i);
764
- e && typeof e.rowsTouched == "number" && (a += e.rowsTouched);
765
- } catch (i) {
766
- let o = i;
767
- return n.error(`seed "${e.definition.id}" failed at step "${t.name}"`, {
768
- seedId: e.definition.id,
769
- step: t.name
770
- }, o), {
771
- seedId: e.definition.id,
772
- status: "failed",
773
- durationMs: Date.now() - r,
774
- rowsTouched: a,
775
- error: {
776
- message: o.message,
777
- ...o.stack ? { stack: o.stack } : {},
778
- stepName: t.name
779
- }
780
- };
781
- }
782
- return {
783
- seedId: e.definition.id,
784
- status: "succeeded",
785
- durationMs: Date.now() - r,
786
- rowsTouched: a
787
- };
788
- }, kt = async (e, t, n, r = {}) => {
789
- let i = e.filter((e) => e.definition.lifecycle === "boot");
790
- if (i.length === 0) return [];
791
- let a = await Q(t, n), o = [], s = 0;
792
- for (let e of i) {
793
- if (!r.force && a.isUnchanged(e)) {
794
- s++, n.debug(`seed "${e.definition.id}" unchanged — skipped`, { fingerprint: e.fingerprint }), o.push({
795
- seedId: e.definition.id,
796
- status: "skipped",
797
- durationMs: 0,
798
- rowsTouched: 0
799
- });
800
- continue;
801
- }
802
- let i = await $(e, t, n);
803
- i.status === "succeeded" && n.info(`seed "${i.seedId}" applied`, {
804
- durationMs: i.durationMs,
805
- rowsTouched: i.rowsTouched,
806
- fingerprint: e.fingerprint
807
- }), await a.record(e, i), o.push(i);
808
- }
809
- return n.info("seeds: boot-lifecycle pass complete", {
810
- ran: o.length - s,
811
- skipped: s,
812
- ...r.force ? { forced: !0 } : {}
813
- }), o;
814
- }, At = async (e, t, n, r) => {
815
- let i = e.find((e) => e.definition.id === t);
816
- if (!i) throw Error(`seed not found: ${t}`);
817
- let a = await $(i, n, r);
818
- return await (await Q(n, r)).record(i, a), a;
819
- }, jt = /\.seed\.ts$/;
598
+ };
820
599
  //#endregion
821
- export { Ze as A, A as B, bt as C, nt as D, L as E, qe as F, je as G, k as H, Ue as I, Ae as K, We as L, Ke as M, N, I as O, Ye as P, Re as R, U as S, V as T, Oe as U, Ne as V, O as W, pt as _, X as a, H as b, K as c, ft as d, mt as f, gt as g, _t as h, At as i, M as j, P as k, J as l, yt as m, Ct as n, Y as o, vt as p, kt as r, ht as s, jt as t, dt as u, G as v, ut as w, W as x, q as y, Le as z };
600
+ export { Me as A, ze as C, F as D, Pe as E, xe as F, k as I, A as L, De as M, Oe as N, Ae as O, Se as P, O as R, V as S, R as T, J as _, Q as a, qe as b, Ze as c, et as d, $e as f, K as g, Z as h, X as i, L as j, I as k, tt as l, Y as m, $ as n, Je as o, Xe as p, Qe as r, Ye as s, ot as t, nt as u, q as v, B as w, G as x, rt as y };