weifuwu 0.24.1 → 0.24.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +818 -712
  2. package/cli/template/app.ts +5 -1
  3. package/cli/template/index.ts +4 -1
  4. package/cli/template/locales/en.json +6 -1
  5. package/cli/template/locales/zh-CN.json +6 -1
  6. package/cli/template/locales/zh-TW.json +6 -1
  7. package/cli/template/locales/zh.json +6 -1
  8. package/cli/template/ui/app/globals.css +1 -1
  9. package/cli/template/ui/app/page.tsx +55 -16
  10. package/cli.ts +148 -104
  11. package/dist/agent/rest.d.ts +1 -1
  12. package/dist/agent/run.d.ts +2 -2
  13. package/dist/ai/workflow.d.ts +1 -1
  14. package/dist/ai-sdk.d.ts +1 -1
  15. package/dist/cli.js +135 -97
  16. package/dist/cookie.d.ts +24 -0
  17. package/dist/fts.d.ts +5 -5
  18. package/dist/iii/index.d.ts +1 -1
  19. package/dist/index.d.ts +5 -5
  20. package/dist/index.js +787 -346
  21. package/dist/live.d.ts +2 -3
  22. package/dist/logdb/rest.d.ts +1 -1
  23. package/dist/mailer.d.ts +1 -1
  24. package/dist/messager/agent.d.ts +2 -2
  25. package/dist/messager/rest.d.ts +3 -3
  26. package/dist/messager/ws.d.ts +3 -3
  27. package/dist/opencode/index.d.ts +1 -1
  28. package/dist/opencode/permissions.d.ts +1 -1
  29. package/dist/opencode/run.d.ts +1 -1
  30. package/dist/opencode/session.d.ts +9 -9
  31. package/dist/opencode/tools/web.d.ts +1 -1
  32. package/dist/opencode/ws.d.ts +1 -2
  33. package/dist/permissions.d.ts +2 -2
  34. package/dist/postgres/module.d.ts +3 -3
  35. package/dist/postgres/schema/index.d.ts +1 -1
  36. package/dist/postgres/schema/table.d.ts +22 -20
  37. package/dist/postgres/types.d.ts +4 -4
  38. package/dist/queue/types.d.ts +1 -1
  39. package/dist/react.d.ts +1 -1
  40. package/dist/react.js +135 -90
  41. package/dist/router.d.ts +10 -10
  42. package/dist/session.d.ts +1 -2
  43. package/dist/tenant/graphql.d.ts +2 -2
  44. package/dist/tenant/index.d.ts +1 -1
  45. package/dist/tenant/rest.d.ts +2 -2
  46. package/dist/test-utils.d.ts +3 -3
  47. package/dist/user/index.d.ts +1 -1
  48. package/dist/user/oauth-login.d.ts +2 -2
  49. package/dist/vendor.d.ts +4 -0
  50. package/opencode/ui/app/globals.css +1 -1
  51. package/opencode/ui/app/layout.tsx +2 -3
  52. package/opencode/ui/app/page.tsx +302 -73
  53. package/package.json +26 -3
  54. package/cli/template/.weifuwu/ssr/2e3a7e60.js +0 -112
package/dist/index.js CHANGED
@@ -262,9 +262,13 @@ function serve(handler, options) {
262
262
  }
263
263
  };
264
264
  }
265
- options.signal.addEventListener("abort", () => {
266
- server.close();
267
- }, { once: true });
265
+ options.signal.addEventListener(
266
+ "abort",
267
+ () => {
268
+ server.close();
269
+ },
270
+ { once: true }
271
+ );
268
272
  }
269
273
  server.on("error", (err) => {
270
274
  console.error("Failed to start server:", err.message);
@@ -488,7 +492,8 @@ var Router = class _Router {
488
492
  }
489
493
  } else if (typeof arg1 === "function") {
490
494
  this.globalMws.push(arg1);
491
- } else if (typeof arg1 === "object" && arg1 !== null && "middleware" in arg1 && typeof arg1.middleware === "function" && arg1 instanceof _Router) {
495
+ } else if (typeof arg1 === "object" && arg1 !== null && "middleware" in arg1 && // eslint-disable-next-line @typescript-eslint/no-explicit-any
496
+ typeof arg1.middleware === "function" && arg1 instanceof _Router) {
492
497
  const mod = arg1;
493
498
  this.globalMws.push(mod.middleware());
494
499
  this._mountRouter("/", mod);
@@ -529,6 +534,7 @@ var Router = class _Router {
529
534
  return this._routeImpl(method, path2, args);
530
535
  }
531
536
  /** Internal route registration — no type constraints (used by _mountRouter). */
537
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
532
538
  _routeImpl(method, path2, args) {
533
539
  const last = args[args.length - 1];
534
540
  if (last instanceof _Router) {
@@ -554,9 +560,7 @@ var Router = class _Router {
554
560
  node = getOrCreateChild(node, segment, createTrieNode, false);
555
561
  }
556
562
  if (!isProd() && node.handlers.has(method)) {
557
- console.warn(
558
- `[router] route conflict: ${method} ${path2} overwrites existing handler`
559
- );
563
+ console.warn(`[router] route conflict: ${method} ${path2} overwrites existing handler`);
560
564
  }
561
565
  node.handlers.set(method, handler);
562
566
  if (middlewares.length > 0) node.middlewares.set(method, middlewares);
@@ -591,7 +595,7 @@ var Router = class _Router {
591
595
  return result;
592
596
  }
593
597
  _collectRoutes(node, prefix, result) {
594
- for (const [method, handler] of node.handlers) {
598
+ for (const [method] of node.handlers) {
595
599
  const m = method === "*" ? "ANY" : method;
596
600
  const path2 = (prefix || "/") + (node.wildcard ? "/*" : "");
597
601
  const middlewares = node.middlewares.get(method);
@@ -669,7 +673,12 @@ var Router = class _Router {
669
673
  const wsRoutes = [];
670
674
  this._collectWs(sub.wsRoot, "", wsRoutes);
671
675
  for (const { path: path2, handler, middlewares } of wsRoutes) {
672
- this.ws(base + path2, ...allExtra, ...middlewares, handler);
676
+ this.ws(
677
+ base + path2,
678
+ ...allExtra,
679
+ ...middlewares,
680
+ handler
681
+ );
673
682
  }
674
683
  }
675
684
  mergeMws(base, extra) {
@@ -682,7 +691,12 @@ var Router = class _Router {
682
691
  for (const [method, handler] of node.handlers) {
683
692
  const rmws = node.middlewares.get(method) || [];
684
693
  const suffix = node.wildcard ? "/*" : "";
685
- result.push({ method, path: (prefix || "/") + suffix, handler, middlewares: this.mergeMws(mws, rmws) });
694
+ result.push({
695
+ method,
696
+ path: (prefix || "/") + suffix,
697
+ handler,
698
+ middlewares: this.mergeMws(mws, rmws)
699
+ });
686
700
  }
687
701
  for (const [seg, child] of node.children) {
688
702
  const next = seg === ":" ? `/:${child.param}` : `/${seg}`;
@@ -744,7 +758,12 @@ var Router = class _Router {
744
758
  return { handler: wildcardHandler, middlewares: wildcardMws, pathMws, params };
745
759
  }
746
760
  if (node.handlers.size > 0) {
747
- return { middlewares: [], pathMws, params, allowedMethods: [...node.handlers.keys()].filter((k) => k !== "*") };
761
+ return {
762
+ middlewares: [],
763
+ pathMws,
764
+ params,
765
+ allowedMethods: [...node.handlers.keys()].filter((k) => k !== "*")
766
+ };
748
767
  }
749
768
  return null;
750
769
  }
@@ -779,38 +798,54 @@ var Router = class _Router {
779
798
  if (match.allowedMethods && match.allowedMethods.length > 0) {
780
799
  if (this.globalMws.length > 0) {
781
800
  try {
782
- return await this.runChain(this.globalMws, () => new Response("Method Not Allowed", {
783
- status: 405,
784
- headers: { "Allow": match.allowedMethods.join(", ") }
785
- }), req, ctx);
801
+ return await this.runChain(
802
+ this.globalMws,
803
+ () => new Response("Method Not Allowed", {
804
+ status: 405,
805
+ headers: { Allow: match.allowedMethods.join(", ") }
806
+ }),
807
+ req,
808
+ ctx
809
+ );
786
810
  } catch (e) {
787
811
  return this.handleError(e, req, ctx);
788
812
  }
789
813
  }
790
814
  return new Response("Method Not Allowed", {
791
815
  status: 405,
792
- headers: { "Allow": match.allowedMethods.join(", ") }
816
+ headers: { Allow: match.allowedMethods.join(", ") }
793
817
  });
794
818
  }
795
819
  }
796
820
  if (this.globalMws.length > 0) {
797
821
  try {
798
- return await this.runChain(this.globalMws, () => {
799
- if (!isProd()) {
800
- return Response.json({ error: "Not Found", path: "/" + segments.join("/"), method: req.method }, { status: 404 });
801
- }
802
- return new Response("Not Found", { status: 404 });
803
- }, req, ctx);
822
+ return await this.runChain(
823
+ this.globalMws,
824
+ () => {
825
+ if (!isProd()) {
826
+ return Response.json(
827
+ { error: "Not Found", path: "/" + segments.join("/"), method: req.method },
828
+ { status: 404 }
829
+ );
830
+ }
831
+ return new Response("Not Found", { status: 404 });
832
+ },
833
+ req,
834
+ ctx
835
+ );
804
836
  } catch (e) {
805
837
  return this.handleError(e, req, ctx);
806
838
  }
807
839
  }
808
840
  if (!isProd()) {
809
- return Response.json({
810
- error: "Not Found",
811
- path: "/" + segments.join("/"),
812
- method: req.method
813
- }, { status: 404 });
841
+ return Response.json(
842
+ {
843
+ error: "Not Found",
844
+ path: "/" + segments.join("/"),
845
+ method: req.method
846
+ },
847
+ { status: 404 }
848
+ );
814
849
  }
815
850
  return new Response("Not Found", { status: 404 });
816
851
  }
@@ -825,7 +860,9 @@ function runChainLoop(middlewares, index, finalHandler, req, ctx) {
825
860
  let called = false;
826
861
  const dispatch = (r, c) => {
827
862
  if (called) {
828
- console.warn("[router] next() called more than once in middleware \u2014 ignoring duplicate call");
863
+ console.warn(
864
+ "[router] next() called more than once in middleware \u2014 ignoring duplicate call"
865
+ );
829
866
  return Promise.resolve(new Response("Internal Server Error", { status: 500 }));
830
867
  }
831
868
  called = true;
@@ -849,7 +886,7 @@ function upgradeSocket(wss, req, socket, head, handler, ctx, hub) {
849
886
  join(room) {
850
887
  hub.join(room, ws);
851
888
  },
852
- leave(room) {
889
+ leave(_room) {
853
890
  hub.leave(ws);
854
891
  },
855
892
  sendRoom(room, data) {
@@ -899,7 +936,15 @@ function sendHttpResponseOnSocket(socket, response) {
899
936
 
900
937
  // tsx-context.ts
901
938
  import { useSyncExternalStore, createContext } from "react";
902
- var DEFAULT_CTX = { params: {}, query: {}, parsed: {}, loaderData: {}, env: {}, user: {}, flash: {} };
939
+ var DEFAULT_CTX = {
940
+ params: {},
941
+ query: {},
942
+ parsed: {},
943
+ loaderData: {},
944
+ env: {},
945
+ user: {},
946
+ flash: {}
947
+ };
903
948
  var KEY = "__WEIFUWU_CTX_STORE";
904
949
  function getStore() {
905
950
  if (typeof globalThis !== "undefined" && globalThis[KEY]) {
@@ -907,12 +952,22 @@ function getStore() {
907
952
  }
908
953
  const s = {
909
954
  _ctx: DEFAULT_CTX,
910
- _snapshot: { params: DEFAULT_CTX.params, query: DEFAULT_CTX.query, user: DEFAULT_CTX.user, parsed: DEFAULT_CTX.parsed, theme: DEFAULT_CTX.theme, i18n: DEFAULT_CTX.i18n, loaderData: DEFAULT_CTX.loaderData, env: DEFAULT_CTX.env },
955
+ _snapshot: {
956
+ params: DEFAULT_CTX.params,
957
+ query: DEFAULT_CTX.query,
958
+ user: DEFAULT_CTX.user,
959
+ parsed: DEFAULT_CTX.parsed,
960
+ theme: DEFAULT_CTX.theme,
961
+ i18n: DEFAULT_CTX.i18n,
962
+ loaderData: DEFAULT_CTX.loaderData,
963
+ env: DEFAULT_CTX.env
964
+ },
911
965
  _listeners: /* @__PURE__ */ new Set(),
912
966
  _rebuilders: [],
913
967
  _alsGetStore: null
914
968
  };
915
969
  if (typeof globalThis !== "undefined") {
970
+ ;
916
971
  globalThis[KEY] = s;
917
972
  }
918
973
  return s;
@@ -929,7 +984,16 @@ function setCtx(value) {
929
984
  }
930
985
  }
931
986
  store._ctx = { ...store._ctx, ...value };
932
- store._snapshot = { params: store._ctx.params, query: store._ctx.query, user: store._ctx.user, parsed: store._ctx.parsed, theme: store._ctx.theme, i18n: store._ctx.i18n, loaderData: store._ctx.loaderData, env: store._ctx.env };
987
+ store._snapshot = {
988
+ params: store._ctx.params,
989
+ query: store._ctx.query,
990
+ user: store._ctx.user,
991
+ parsed: store._ctx.parsed,
992
+ theme: store._ctx.theme,
993
+ i18n: store._ctx.i18n,
994
+ loaderData: store._ctx.loaderData,
995
+ env: store._ctx.env
996
+ };
933
997
  if (typeof window !== "undefined") {
934
998
  ;
935
999
  window.__WEIFUWU_CTX = { ...window.__WEIFUWU_CTX, ...value };
@@ -1014,7 +1078,8 @@ function cors(options) {
1014
1078
  const headers = new Headers(res.headers);
1015
1079
  headers.set("Access-Control-Allow-Origin", acao);
1016
1080
  if (opts.credentials) headers.set("Access-Control-Allow-Credentials", "true");
1017
- if (opts.exposedHeaders?.length) headers.set("Access-Control-Expose-Headers", opts.exposedHeaders.join(", "));
1081
+ if (opts.exposedHeaders?.length)
1082
+ headers.set("Access-Control-Expose-Headers", opts.exposedHeaders.join(", "));
1018
1083
  if (acao !== "*") headers.set("Vary", "Origin");
1019
1084
  return new Response(res.body, { status: res.status, statusText: res.statusText, headers });
1020
1085
  }
@@ -1091,7 +1156,7 @@ function serveStatic(root, options) {
1091
1156
  const headers = {
1092
1157
  "Content-Type": mimeType,
1093
1158
  "Content-Length": String(stat3.size),
1094
- "ETag": etag,
1159
+ ETag: etag,
1095
1160
  "Last-Modified": stat3.mtime.toUTCString(),
1096
1161
  "Cache-Control": opts.immutable ? `public, max-age=${opts.maxAge ?? 31536e3}, immutable` : `public, max-age=${opts.maxAge ?? 0}`
1097
1162
  };
@@ -1181,10 +1246,12 @@ function validate(schemas) {
1181
1246
  if (result.success) {
1182
1247
  parsed.params = result.data;
1183
1248
  } else {
1184
- issues.push(...result.error.issues.map((i) => ({
1185
- path: ["params", ...i.path.map(String)],
1186
- message: i.message
1187
- })));
1249
+ issues.push(
1250
+ ...result.error.issues.map((i) => ({
1251
+ path: ["params", ...i.path.map(String)],
1252
+ message: i.message
1253
+ }))
1254
+ );
1188
1255
  }
1189
1256
  }
1190
1257
  if (schemas?.query) {
@@ -1192,10 +1259,12 @@ function validate(schemas) {
1192
1259
  if (result.success) {
1193
1260
  parsed.query = result.data;
1194
1261
  } else {
1195
- issues.push(...result.error.issues.map((i) => ({
1196
- path: ["query", ...i.path.map(String)],
1197
- message: i.message
1198
- })));
1262
+ issues.push(
1263
+ ...result.error.issues.map((i) => ({
1264
+ path: ["query", ...i.path.map(String)],
1265
+ message: i.message
1266
+ }))
1267
+ );
1199
1268
  }
1200
1269
  }
1201
1270
  if (schemas?.headers) {
@@ -1207,10 +1276,12 @@ function validate(schemas) {
1207
1276
  if (result.success) {
1208
1277
  parsed.headers = result.data;
1209
1278
  } else {
1210
- issues.push(...result.error.issues.map((i) => ({
1211
- path: ["headers", ...i.path.map(String)],
1212
- message: i.message
1213
- })));
1279
+ issues.push(
1280
+ ...result.error.issues.map((i) => ({
1281
+ path: ["headers", ...i.path.map(String)],
1282
+ message: i.message
1283
+ }))
1284
+ );
1214
1285
  }
1215
1286
  }
1216
1287
  if (req.method !== "GET" && req.method !== "HEAD") {
@@ -1234,10 +1305,12 @@ function validate(schemas) {
1234
1305
  if (result.success) {
1235
1306
  parsed.body = result.data;
1236
1307
  } else {
1237
- issues.push(...result.error.issues.map((i) => ({
1238
- path: ["body", ...i.path.map(String)],
1239
- message: i.message
1240
- })));
1308
+ issues.push(
1309
+ ...result.error.issues.map((i) => ({
1310
+ path: ["body", ...i.path.map(String)],
1311
+ message: i.message
1312
+ }))
1313
+ );
1241
1314
  }
1242
1315
  } else {
1243
1316
  parsed.body = bodyValue;
@@ -1305,11 +1378,14 @@ function setCookie(res, name, value, options) {
1305
1378
  }
1306
1379
  function deleteCookie(res, name, options) {
1307
1380
  const headers = new Headers(res.headers);
1308
- headers.append("Set-Cookie", serializeCookie(name, "", {
1309
- ...options,
1310
- maxAge: 0,
1311
- expires: /* @__PURE__ */ new Date(0)
1312
- }));
1381
+ headers.append(
1382
+ "Set-Cookie",
1383
+ serializeCookie(name, "", {
1384
+ ...options,
1385
+ maxAge: 0,
1386
+ expires: /* @__PURE__ */ new Date(0)
1387
+ })
1388
+ );
1313
1389
  return new Response(res.body, {
1314
1390
  status: res.status,
1315
1391
  statusText: res.statusText,
@@ -1433,21 +1509,24 @@ function rateLimit(options) {
1433
1509
  const keyPrefix = options?.prefix ?? "ratelimit:";
1434
1510
  const MAX_ENTRIES2 = 1e4;
1435
1511
  const hits = /* @__PURE__ */ new Map();
1436
- const interval = storeType === "memory" ? setInterval(() => {
1437
- const now = Date.now();
1438
- for (const [key, entry] of hits) {
1439
- if (entry.reset < now) hits.delete(key);
1440
- }
1441
- if (hits.size > MAX_ENTRIES2) {
1442
- const toDelete = hits.size - MAX_ENTRIES2;
1443
- let deleted = 0;
1444
- for (const key of hits.keys()) {
1445
- if (deleted >= toDelete) break;
1446
- hits.delete(key);
1447
- deleted++;
1512
+ const interval = storeType === "memory" ? setInterval(
1513
+ () => {
1514
+ const now = Date.now();
1515
+ for (const [key, entry] of hits) {
1516
+ if (entry.reset < now) hits.delete(key);
1517
+ }
1518
+ if (hits.size > MAX_ENTRIES2) {
1519
+ const toDelete = hits.size - MAX_ENTRIES2;
1520
+ let deleted = 0;
1521
+ for (const key of hits.keys()) {
1522
+ if (deleted >= toDelete) break;
1523
+ hits.delete(key);
1524
+ deleted++;
1525
+ }
1448
1526
  }
1449
- }
1450
- }, Math.min(window2, 3e4)) : null;
1527
+ },
1528
+ Math.min(window2, 3e4)
1529
+ ) : null;
1451
1530
  if (interval?.unref) interval.unref();
1452
1531
  async function checkAndIncrement(key) {
1453
1532
  const now = Date.now();
@@ -1461,7 +1540,7 @@ function rateLimit(options) {
1461
1540
  const reset = pttl > 0 ? now + pttl : now + window2;
1462
1541
  return { count, reset };
1463
1542
  }
1464
- let entry = hits.get(key);
1543
+ const entry = hits.get(key);
1465
1544
  if (!entry || entry.reset < now) {
1466
1545
  hits.set(key, { count: 1, reset: now + window2 });
1467
1546
  return { count: 1, reset: now + window2 };
@@ -1492,7 +1571,6 @@ function rateLimit(options) {
1492
1571
  if (interval) clearInterval(interval);
1493
1572
  hits.clear();
1494
1573
  };
1495
- mw.stop = mw.close;
1496
1574
  mw.stats = () => ({
1497
1575
  store: storeType,
1498
1576
  entries: storeType === "memory" ? hits.size : void 0,
@@ -1536,7 +1614,9 @@ function compress(options) {
1536
1614
  let compressed;
1537
1615
  try {
1538
1616
  if (encoding === "br") {
1539
- compressed = await brotliCompressAsync(body, { params: { [constants.BROTLI_PARAM_QUALITY]: Math.min(level, 11) } });
1617
+ compressed = await brotliCompressAsync(body, {
1618
+ params: { [constants.BROTLI_PARAM_QUALITY]: Math.min(level, 11) }
1619
+ });
1540
1620
  } else if (encoding === "gzip") {
1541
1621
  compressed = await gzipAsync(body, { level: Math.min(level, 9) });
1542
1622
  } else {
@@ -1650,9 +1730,7 @@ function createSSEStream(iterable, opts) {
1650
1730
  }
1651
1731
  } catch (e) {
1652
1732
  if (e.name !== "AbortError") {
1653
- controller.enqueue(
1654
- encoder.encode(formatSSE("error", { error: e.message }))
1655
- );
1733
+ controller.enqueue(encoder.encode(formatSSE("error", { error: e.message })));
1656
1734
  }
1657
1735
  } finally {
1658
1736
  controller.close();
@@ -1777,26 +1855,31 @@ var TestApp = class {
1777
1855
  }
1778
1856
  /** Register a GET route — supports route-level middleware via spread args. */
1779
1857
  get(path2, ...args) {
1858
+ ;
1780
1859
  this.router.get(path2, ...args);
1781
1860
  return this;
1782
1861
  }
1783
1862
  /** Register a POST route. */
1784
1863
  post(path2, ...args) {
1864
+ ;
1785
1865
  this.router.post(path2, ...args);
1786
1866
  return this;
1787
1867
  }
1788
1868
  /** Register a PUT route. */
1789
1869
  put(path2, ...args) {
1870
+ ;
1790
1871
  this.router.put(path2, ...args);
1791
1872
  return this;
1792
1873
  }
1793
1874
  /** Register a PATCH route. */
1794
1875
  patch(path2, ...args) {
1876
+ ;
1795
1877
  this.router.patch(path2, ...args);
1796
1878
  return this;
1797
1879
  }
1798
1880
  /** Register a DELETE route. */
1799
1881
  delete(path2, ...args) {
1882
+ ;
1800
1883
  this.router.delete(path2, ...args);
1801
1884
  return this;
1802
1885
  }
@@ -1879,7 +1962,12 @@ async function withTestDb(optionsOrFn, fn) {
1879
1962
  }
1880
1963
 
1881
1964
  // graphql.ts
1882
- import { buildSchema, graphql as executeGraphQL, validate as validateQuery, parse } from "graphql";
1965
+ import {
1966
+ buildSchema,
1967
+ graphql as executeGraphQL,
1968
+ validate as validateQuery,
1969
+ parse
1970
+ } from "graphql";
1883
1971
  import { makeExecutableSchema } from "@graphql-tools/schema";
1884
1972
  function parseParamsFromGet(url) {
1885
1973
  const query = url.searchParams.get("query");
@@ -1940,11 +2028,17 @@ async function executeQuery(schema, params, options, req, ctx) {
1940
2028
  const doc = parse(params.query);
1941
2029
  const depth = queryDepth(doc);
1942
2030
  if (depth > maxDepth) {
1943
- return Response.json({ errors: [{ message: `Query depth ${depth} exceeds limit ${maxDepth}` }] }, { status: 400 });
2031
+ return Response.json(
2032
+ { errors: [{ message: `Query depth ${depth} exceeds limit ${maxDepth}` }] },
2033
+ { status: 400 }
2034
+ );
1944
2035
  }
1945
2036
  const validationErrors = validateQuery(schema, doc);
1946
2037
  if (validationErrors.length > 0) {
1947
- return Response.json({ errors: validationErrors.map((e) => ({ message: e.message })) }, { status: 400 });
2038
+ return Response.json(
2039
+ { errors: validationErrors.map((e) => ({ message: e.message })) },
2040
+ { status: 400 }
2041
+ );
1948
2042
  }
1949
2043
  } catch (err) {
1950
2044
  const msg = err instanceof Error ? err.message : String(err);
@@ -2125,7 +2219,10 @@ function resolveRef(path2, ctx) {
2125
2219
  const propPath = after.slice(dot + 1);
2126
2220
  const output = ctx.nodeOutputs.get(id2);
2127
2221
  if (output === void 0) throw new Error(`Node "${id2}" has no output yet`);
2128
- return getByPath(output, propPath.startsWith("output") ? propPath.slice(7).split(".").filter(Boolean) : propPath.split("."));
2222
+ return getByPath(
2223
+ output,
2224
+ propPath.startsWith("output") ? propPath.slice(7).split(".").filter(Boolean) : propPath.split(".")
2225
+ );
2129
2226
  }
2130
2227
  if (path2.startsWith("$var.")) {
2131
2228
  const name = path2.slice(5);
@@ -2145,7 +2242,8 @@ function resolveValue(v, ctx) {
2145
2242
  if (Array.isArray(v)) return v.map((item) => resolveValue(item, ctx));
2146
2243
  if (typeof v === "object" && v !== null) {
2147
2244
  const result = {};
2148
- for (const [k, val] of Object.entries(v)) result[k] = resolveValue(val, ctx);
2245
+ for (const [k, val] of Object.entries(v))
2246
+ result[k] = resolveValue(val, ctx);
2149
2247
  return result;
2150
2248
  }
2151
2249
  return v;
@@ -2241,7 +2339,7 @@ async function executeNode(node, ctx) {
2241
2339
  iters++;
2242
2340
  ctx.stepCount++;
2243
2341
  if (ctx.stepCount > ctx.maxSteps) throw new Error(`Step limit exceeded`);
2244
- if (!Boolean(evaluateExpression(conditionExpr, ctx))) break;
2342
+ if (!evaluateExpression(conditionExpr, ctx)) break;
2245
2343
  for (const n of body ?? []) {
2246
2344
  last = await executeNode(n, ctx);
2247
2345
  ctx.nodeOutputs.set(n.id, last);
@@ -2273,7 +2371,10 @@ async function executeNode(node, ctx) {
2273
2371
  signal: controller.signal
2274
2372
  });
2275
2373
  const ct = res.headers.get("content-type") ?? "";
2276
- return { status: res.status, body: ct.includes("json") ? await res.json() : await res.text() };
2374
+ return {
2375
+ status: res.status,
2376
+ body: ct.includes("json") ? await res.json() : await res.text()
2377
+ };
2277
2378
  } finally {
2278
2379
  clearTimeout(timer);
2279
2380
  }
@@ -2293,20 +2394,25 @@ function runWorkflow(opts = {}) {
2293
2394
  description: "Execute a multi-step workflow. Supports eval, set, get, if, while, call, http nodes. Use $var.x for variables, $nodes.id.output for previous node results, $input.x for input parameters. Call nodes invoke registered tools.",
2294
2395
  inputSchema: z.object({
2295
2396
  goal: z.string().describe("What the workflow should accomplish"),
2296
- nodes: z.array(z.object({
2297
- id: z.string(),
2298
- tool: z.string(),
2299
- input: z.record(z.string(), z.unknown()).optional(),
2300
- conditions: z.array(z.object({ test: z.any(), body: z.any() })).optional(),
2301
- body: z.array(z.any()).optional()
2302
- })).optional().describe("Workflow nodes. Skip this and provide model for LLM to generate from goal.")
2397
+ nodes: z.array(
2398
+ z.object({
2399
+ id: z.string(),
2400
+ tool: z.string(),
2401
+ input: z.record(z.string(), z.unknown()).optional(),
2402
+ conditions: z.array(z.object({ test: z.any(), body: z.any() })).optional(),
2403
+ body: z.array(z.any()).optional()
2404
+ })
2405
+ ).optional().describe("Workflow nodes. Skip this and provide model for LLM to generate from goal.")
2303
2406
  }),
2304
2407
  execute: async (input) => {
2305
2408
  let nodes;
2306
2409
  if (input.nodes && input.nodes.length > 0) {
2307
2410
  nodes = input.nodes;
2308
2411
  } else {
2309
- if (!opts.provider && !opts.model) throw new Error('Provide either "nodes", a "model", or a "provider" with a model to generate the workflow from "goal"');
2412
+ if (!opts.provider && !opts.model)
2413
+ throw new Error(
2414
+ 'Provide either "nodes", a "model", or a "provider" with a model to generate the workflow from "goal"'
2415
+ );
2310
2416
  const toolsDesc = Object.entries(opts.tools ?? {}).map(([k, t]) => `- ${k}: ${t.description}`).join("\n");
2311
2417
  const system = [
2312
2418
  "You are a workflow generator. Given a user goal and available tools, output a workflow JSON.",
@@ -2318,7 +2424,10 @@ function runWorkflow(opts = {}) {
2318
2424
  "Reference syntax: $var.name, $nodes.id.output, $nodes.id.output.field, $input.field",
2319
2425
  "Output ONLY valid JSON. No explanation, no markdown."
2320
2426
  ].filter(Boolean).join("\n");
2321
- const genParams = { system, messages: [{ role: "user", content: input.goal }] };
2427
+ const genParams = {
2428
+ system,
2429
+ messages: [{ role: "user", content: input.goal }]
2430
+ };
2322
2431
  const result = opts.provider ? await opts.provider.generateText(genParams) : await generateText({ ...genParams, model: opts.model });
2323
2432
  const text2 = result.text.trim();
2324
2433
  const jsonStart = text2.indexOf("{");
@@ -2411,10 +2520,7 @@ import {
2411
2520
  embedMany,
2412
2521
  smoothStream
2413
2522
  } from "ai";
2414
- import {
2415
- openai,
2416
- createOpenAI as createOpenAI2
2417
- } from "@ai-sdk/openai";
2523
+ import { openai, createOpenAI as createOpenAI2 } from "@ai-sdk/openai";
2418
2524
 
2419
2525
  // postgres/client.ts
2420
2526
  import postgresFactory from "postgres";
@@ -2657,7 +2763,10 @@ var Table = class {
2657
2763
  const using = opts?.type ? `USING ${opts.type.toUpperCase()}` : "";
2658
2764
  const colList = cols.map((c) => opts?.desc ? `"${c}" DESC` : `"${c}"`).join(", ");
2659
2765
  const operator = opts?.operator ? ` ${opts.operator}` : "";
2660
- const ddl = `CREATE ${unique} INDEX IF NOT EXISTS ${name} ON "${this.tableName}" ${using} (${colList}${operator})`.replace(/\s+/g, " ");
2766
+ const ddl = `CREATE ${unique} INDEX IF NOT EXISTS ${name} ON "${this.tableName}" ${using} (${colList}${operator})`.replace(
2767
+ /\s+/g,
2768
+ " "
2769
+ );
2661
2770
  await sql2.unsafe(ddl);
2662
2771
  }
2663
2772
  async createUniqueIndex(sql2, columns) {
@@ -2761,7 +2870,10 @@ var Table = class {
2761
2870
  const softDel = this._softDeleteFilter(where, opts);
2762
2871
  if (softDel) conditions.push(softDel);
2763
2872
  const whereClause = conditions.length > 0 ? ` WHERE ${conditions.join(" AND ")}` : "";
2764
- const [countRow] = await sql2.unsafe(`SELECT COUNT(*) AS _total FROM "${this.tableName}"${whereClause}`, values);
2873
+ const [countRow] = await sql2.unsafe(
2874
+ `SELECT COUNT(*) AS _total FROM "${this.tableName}"${whereClause}`,
2875
+ values
2876
+ );
2765
2877
  const count = Number(countRow._total);
2766
2878
  if (conditions.length === 0 && !opts?.orderBy && !opts?.limit && !opts?.offset && !opts?.select) {
2767
2879
  const rows2 = await sql2`SELECT * FROM ${sql2(this.tableName)}`;
@@ -2794,7 +2906,10 @@ var Table = class {
2794
2906
  async updateMany(sql2, where, data) {
2795
2907
  const { sets, values: setValues } = this._buildSET(data);
2796
2908
  if (sets.length === 0) return 0;
2797
- const { conditions: wConditions, values: wValues } = this._buildConditions(where, setValues.length);
2909
+ const { conditions: wConditions, values: wValues } = this._buildConditions(
2910
+ where,
2911
+ setValues.length
2912
+ );
2798
2913
  if (wConditions.length === 0) return 0;
2799
2914
  const rows = await sql2.unsafe(
2800
2915
  `UPDATE "${this.tableName}" SET ${sets.join(", ")} WHERE ${wConditions.join(" AND ")} RETURNING 1`,
@@ -2883,13 +2998,20 @@ var Table = class {
2883
2998
  const softDel = this._softDeleteFilter(where);
2884
2999
  if (softDel) conditions.push(softDel);
2885
3000
  const whereClause = conditions.length > 0 ? ` WHERE ${conditions.join(" AND ")}` : "";
2886
- const [row] = await sql2.unsafe(`SELECT COUNT(*) AS _total FROM "${this.tableName}"${whereClause}`, values);
3001
+ const [row] = await sql2.unsafe(
3002
+ `SELECT COUNT(*) AS _total FROM "${this.tableName}"${whereClause}`,
3003
+ values
3004
+ );
2887
3005
  return Number(row._total);
2888
3006
  }
2889
3007
  };
2890
3008
  var BoundTable = class _BoundTable {
2891
3009
  inner;
2892
3010
  sql;
3011
+ /** The underlying table name. */
3012
+ get tableName() {
3013
+ return this.inner.tableName;
3014
+ }
2893
3015
  constructor(sql2, tableName, builders) {
2894
3016
  this.inner = new Table(tableName, builders);
2895
3017
  this.sql = sql2;
@@ -2977,13 +3099,17 @@ function postgres(opts) {
2977
3099
  connect_timeout: options.connect_timeout
2978
3100
  });
2979
3101
  if (options.signal) {
2980
- options.signal.addEventListener("abort", () => {
2981
- sql2.end();
2982
- }, { once: true });
3102
+ options.signal.addEventListener(
3103
+ "abort",
3104
+ () => {
3105
+ sql2.end();
3106
+ },
3107
+ { once: true }
3108
+ );
2983
3109
  }
2984
3110
  const closeTimeout = options.closeTimeout ?? 5;
2985
- let _active = 0;
2986
- let _waiting = 0;
3111
+ const _active = 0;
3112
+ const _waiting = 0;
2987
3113
  const poolMax = options.max ?? 10;
2988
3114
  const mw = ((req, ctx, next) => {
2989
3115
  ctx.sql = sql2;
@@ -3011,10 +3137,9 @@ function postgres(opts) {
3011
3137
  );
3012
3138
  };
3013
3139
  mw.isMigrated = async (moduleName) => {
3014
- const [row] = await sql2.unsafe(
3015
- `SELECT 1 FROM "${MIGRATIONS_TABLE}" WHERE name = $1`,
3016
- [moduleName]
3017
- );
3140
+ const [row] = await sql2.unsafe(`SELECT 1 FROM "${MIGRATIONS_TABLE}" WHERE name = $1`, [
3141
+ moduleName
3142
+ ]);
3018
3143
  return !!row;
3019
3144
  };
3020
3145
  mw.transaction = (async (fn, retryOpts) => {
@@ -3146,10 +3271,9 @@ function createOAuth2Server(deps) {
3146
3271
  return null;
3147
3272
  }
3148
3273
  function consentPage(client, params) {
3149
- const fields = Object.entries(params).map(
3150
- ([k, v]) => `<input type="hidden" name="${k}" value="${v.replace(/"/g, "&quot;")}">`
3151
- ).join("\n ");
3152
- return new Response(`<!DOCTYPE html>
3274
+ const fields = Object.entries(params).map(([k, v]) => `<input type="hidden" name="${k}" value="${v.replace(/"/g, "&quot;")}">`).join("\n ");
3275
+ return new Response(
3276
+ `<!DOCTYPE html>
3153
3277
  <html lang="en">
3154
3278
  <head><meta charset="utf-8"><title>Authorize</title>
3155
3279
  <style>
@@ -3176,17 +3300,22 @@ function createOAuth2Server(deps) {
3176
3300
  </form>
3177
3301
  </div>
3178
3302
  </body>
3179
- </html>`, { headers: { "Content-Type": "text/html; charset=utf-8" } });
3303
+ </html>`,
3304
+ { headers: { "Content-Type": "text/html; charset=utf-8" } }
3305
+ );
3180
3306
  }
3181
3307
  function errorPage2(error, description) {
3182
- return new Response(`<!DOCTYPE html>
3308
+ return new Response(
3309
+ `<!DOCTYPE html>
3183
3310
  <html lang="en">
3184
3311
  <head><meta charset="utf-8"><title>Error</title>
3185
3312
  <style>body{font-family:sans-serif;max-width:480px;margin:80px auto;padding:0 20px}
3186
3313
  h2{color:#dc2626}.desc{color:#555}</style>
3187
3314
  </head>
3188
3315
  <body><h2>${error}</h2>${description ? `<p class="desc">${description}</p>` : ""}</body>
3189
- </html>`, { status: 400, headers: { "Content-Type": "text/html; charset=utf-8" } });
3316
+ </html>`,
3317
+ { status: 400, headers: { "Content-Type": "text/html; charset=utf-8" } }
3318
+ );
3190
3319
  }
3191
3320
  async function authorizeHandler(req, _ctx) {
3192
3321
  const url = new URL(req.url);
@@ -3205,7 +3334,10 @@ h2{color:#dc2626}.desc{color:#555}</style>
3205
3334
  return errorPage2("Invalid client_id", "No client found with the given client_id.");
3206
3335
  }
3207
3336
  if (!client.redirectUris.includes(redirectUri)) {
3208
- return errorPage2("Invalid redirect_uri", "The redirect_uri is not registered for this client.");
3337
+ return errorPage2(
3338
+ "Invalid redirect_uri",
3339
+ "The redirect_uri is not registered for this client."
3340
+ );
3209
3341
  }
3210
3342
  const user2 = extractUser(req);
3211
3343
  if (!user2) {
@@ -3291,14 +3423,23 @@ h2{color:#dc2626}.desc{color:#555}</style>
3291
3423
  return Response.json({ error: "invalid_grant" }, { status: 400 });
3292
3424
  }
3293
3425
  if (new Date(stored.expires_at) < /* @__PURE__ */ new Date()) {
3294
- return Response.json({ error: "invalid_grant", error_description: "Code expired" }, { status: 400 });
3426
+ return Response.json(
3427
+ { error: "invalid_grant", error_description: "Code expired" },
3428
+ { status: 400 }
3429
+ );
3295
3430
  }
3296
3431
  if (stored.redirect_uri !== redirectUri) {
3297
- return Response.json({ error: "invalid_grant", error_description: "redirect_uri mismatch" }, { status: 400 });
3432
+ return Response.json(
3433
+ { error: "invalid_grant", error_description: "redirect_uri mismatch" },
3434
+ { status: 400 }
3435
+ );
3298
3436
  }
3299
3437
  if (stored.code_challenge) {
3300
3438
  if (!codeVerifier) {
3301
- return Response.json({ error: "invalid_grant", error_description: "code_verifier required" }, { status: 400 });
3439
+ return Response.json(
3440
+ { error: "invalid_grant", error_description: "code_verifier required" },
3441
+ { status: 400 }
3442
+ );
3302
3443
  }
3303
3444
  let expected;
3304
3445
  if (stored.code_challenge_method === "plain") {
@@ -3307,7 +3448,10 @@ h2{color:#dc2626}.desc{color:#555}</style>
3307
3448
  expected = crypto4.createHash("sha256").update(codeVerifier).digest().toString("base64url");
3308
3449
  }
3309
3450
  if (expected !== stored.code_challenge) {
3310
- return Response.json({ error: "invalid_grant", error_description: "code_verifier mismatch" }, { status: 400 });
3451
+ return Response.json(
3452
+ { error: "invalid_grant", error_description: "code_verifier mismatch" },
3453
+ { status: 400 }
3454
+ );
3311
3455
  }
3312
3456
  }
3313
3457
  await pg.sql`UPDATE "_oauth2_codes" SET "used" = TRUE WHERE "id" = ${stored.id}`;
@@ -3512,7 +3656,7 @@ function registerOAuthLoginRoutes(router, deps, providers) {
3512
3656
  try {
3513
3657
  tokenRes = await fetch(meta.tokenUrl, {
3514
3658
  method: "POST",
3515
- headers: { "Content-Type": "application/json", "Accept": "application/json" },
3659
+ headers: { "Content-Type": "application/json", Accept: "application/json" },
3516
3660
  body: JSON.stringify({
3517
3661
  code,
3518
3662
  client_id: config.clientId,
@@ -3522,7 +3666,10 @@ function registerOAuthLoginRoutes(router, deps, providers) {
3522
3666
  })
3523
3667
  });
3524
3668
  } catch (err) {
3525
- console.error(`[oauth] token exchange network error for ${providerName}:`, err.message);
3669
+ console.error(
3670
+ `[oauth] token exchange network error for ${providerName}:`,
3671
+ err.message
3672
+ );
3526
3673
  return Response.json({ error: "Failed to connect to OAuth provider" }, { status: 502 });
3527
3674
  }
3528
3675
  if (!tokenRes.ok) {
@@ -3539,7 +3686,10 @@ function registerOAuthLoginRoutes(router, deps, providers) {
3539
3686
  try {
3540
3687
  userRes = await fetch(meta.userUrl, { headers: { Authorization: "Bearer " + accessToken } });
3541
3688
  } catch (err) {
3542
- console.error("[oauth] user info network error for " + providerName + ":", err.message);
3689
+ console.error(
3690
+ "[oauth] user info network error for " + providerName + ":",
3691
+ err.message
3692
+ );
3543
3693
  return Response.json({ error: "Failed to connect to OAuth provider" }, { status: 502 });
3544
3694
  }
3545
3695
  if (!userRes.ok) {
@@ -3707,11 +3857,9 @@ function user(options) {
3707
3857
  await tokens.create();
3708
3858
  }
3709
3859
  function signToken(user2) {
3710
- return jwt2.sign(
3711
- { sub: user2.id, email: user2.email, role: user2.role },
3712
- secret,
3713
- { expiresIn }
3714
- );
3860
+ return jwt2.sign({ sub: user2.id, email: user2.email, role: user2.role }, secret, {
3861
+ expiresIn
3862
+ });
3715
3863
  }
3716
3864
  function stripPassword(row) {
3717
3865
  const { password: _, ...user2 } = row;
@@ -3879,6 +4027,7 @@ function user(options) {
3879
4027
  return async (req, ctx, next) => {
3880
4028
  const userData = await resolveUser(req, ctx);
3881
4029
  if (userData) {
4030
+ ;
3882
4031
  ctx.user = userData;
3883
4032
  }
3884
4033
  return next(req, ctx);
@@ -3940,18 +4089,22 @@ function user(options) {
3940
4089
  r.post("/oauth/token", (req) => oauth2.tokenHandler(req));
3941
4090
  }
3942
4091
  if (hasDb && options.oauthLogin) {
3943
- registerOAuthLoginRoutes(r, {
3944
- sql: _pg.sql,
3945
- jwtSecret: secret,
3946
- expiresIn,
3947
- usersTable: table,
3948
- providerTable: "_auth_providers",
3949
- redirectUrl: options.oauthLogin.redirectUrl || "/",
3950
- signToken,
3951
- createPlaceholderUser,
3952
- findUserById: findById,
3953
- findUserByEmail: findByEmail
3954
- }, options.oauthLogin.providers);
4092
+ registerOAuthLoginRoutes(
4093
+ r,
4094
+ {
4095
+ sql: _pg.sql,
4096
+ jwtSecret: secret,
4097
+ expiresIn,
4098
+ usersTable: table,
4099
+ providerTable: "_auth_providers",
4100
+ redirectUrl: options.oauthLogin.redirectUrl || "/",
4101
+ signToken,
4102
+ createPlaceholderUser,
4103
+ findUserById: findById,
4104
+ findUserByEmail: findByEmail
4105
+ },
4106
+ options.oauthLogin.providers
4107
+ );
3955
4108
  }
3956
4109
  const mod = r;
3957
4110
  mod.middleware = middleware;
@@ -4048,9 +4201,7 @@ var FIELD_RANGES = [
4048
4201
  function parsePattern(pattern) {
4049
4202
  const fields = pattern.trim().split(/\s+/);
4050
4203
  if (fields.length !== 5) {
4051
- throw new Error(
4052
- `Invalid cron pattern "${pattern}": expected 5 fields, got ${fields.length}`
4053
- );
4204
+ throw new Error(`Invalid cron pattern "${pattern}": expected 5 fields, got ${fields.length}`);
4054
4205
  }
4055
4206
  return fields.map((f, i) => parseField(f, FIELD_RANGES[i][0], FIELD_RANGES[i][1]));
4056
4207
  }
@@ -4059,7 +4210,7 @@ function matches(fields, date) {
4059
4210
  }
4060
4211
  function cronNext(expr, from = /* @__PURE__ */ new Date()) {
4061
4212
  const fields = parsePattern(expr);
4062
- let candidate = new Date(from.getTime() + 6e4);
4213
+ const candidate = new Date(from.getTime() + 6e4);
4063
4214
  candidate.setSeconds(0, 0);
4064
4215
  for (let i = 0; i < 525600; i++) {
4065
4216
  if (fields[4].has(candidate.getDay()) && fields[3].has(candidate.getMonth() + 1) && fields[2].has(candidate.getDate()) && fields[1].has(candidate.getHours()) && fields[0].has(candidate.getMinutes())) {
@@ -4122,7 +4273,12 @@ function createMemoryQueue(opts) {
4122
4273
  }
4123
4274
  if (job.schedule) {
4124
4275
  try {
4125
- insertJob({ ...job, id: crypto6.randomUUID(), runAt: cronNext(job.schedule), createdAt: Date.now() });
4276
+ insertJob({
4277
+ ...job,
4278
+ id: crypto6.randomUUID(),
4279
+ runAt: cronNext(job.schedule),
4280
+ createdAt: Date.now()
4281
+ });
4126
4282
  } catch (e) {
4127
4283
  console.error("[queue] cron re-queue failed:", e.message);
4128
4284
  }
@@ -4210,7 +4366,14 @@ function createMemoryQueue(opts) {
4210
4366
  mw.dashboard = function dashboard() {
4211
4367
  return buildDashboard(q);
4212
4368
  };
4213
- mw.stats = () => ({ running, inflight, processed: _processed, failed: _failed, handlers: handlers.size, maxConcurrent: MAX_CONCURRENT });
4369
+ mw.stats = () => ({
4370
+ running,
4371
+ inflight,
4372
+ processed: _processed,
4373
+ failed: _failed,
4374
+ handlers: handlers.size,
4375
+ maxConcurrent: MAX_CONCURRENT
4376
+ });
4214
4377
  attachCron(q, handlers);
4215
4378
  return q;
4216
4379
  }
@@ -4225,8 +4388,12 @@ function createPgQueue(opts) {
4225
4388
  const MAX_FAILED = 1e3;
4226
4389
  async function ensureTable() {
4227
4390
  if (ready) return;
4228
- await sql2.unsafe(`CREATE TABLE IF NOT EXISTS ${escapeIdent3(table)} (id UUID PRIMARY KEY, type TEXT NOT NULL, payload JSONB NOT NULL DEFAULT '{}', run_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), schedule TEXT, status TEXT NOT NULL DEFAULT 'pending', error TEXT, failed_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW())`);
4229
- await sql2.unsafe(`CREATE INDEX IF NOT EXISTS ${escapeIdent3(table + "_run_at_idx")} ON ${escapeIdent3(table)} (run_at, status)`);
4391
+ await sql2.unsafe(
4392
+ `CREATE TABLE IF NOT EXISTS ${escapeIdent3(table)} (id UUID PRIMARY KEY, type TEXT NOT NULL, payload JSONB NOT NULL DEFAULT '{}', run_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), schedule TEXT, status TEXT NOT NULL DEFAULT 'pending', error TEXT, failed_at TIMESTAMPTZ, created_at TIMESTAMPTZ NOT NULL DEFAULT NOW())`
4393
+ );
4394
+ await sql2.unsafe(
4395
+ `CREATE INDEX IF NOT EXISTS ${escapeIdent3(table + "_run_at_idx")} ON ${escapeIdent3(table)} (run_at, status)`
4396
+ );
4230
4397
  ready = true;
4231
4398
  }
4232
4399
  async function processJob(job, handler) {
@@ -4239,14 +4406,26 @@ function createPgQueue(opts) {
4239
4406
  _failed++;
4240
4407
  const msg = e.message;
4241
4408
  console.error("[queue] handler error:", msg);
4242
- await sql2.unsafe(`UPDATE ${escapeIdent3(table)} SET status = 'failed', error = $2, failed_at = NOW() WHERE id = $1`, [job.id, msg]);
4409
+ await sql2.unsafe(
4410
+ `UPDATE ${escapeIdent3(table)} SET status = 'failed', error = $2, failed_at = NOW() WHERE id = $1`,
4411
+ [job.id, msg]
4412
+ );
4243
4413
  } finally {
4244
4414
  inflight--;
4245
4415
  }
4246
4416
  if (job.schedule) {
4247
4417
  try {
4248
4418
  const nextRun = cronNext(job.schedule);
4249
- await sql2.unsafe(`INSERT INTO ${escapeIdent3(table)} (id, type, payload, run_at, schedule) VALUES ($1, $2, $3::jsonb, $4, $5)`, [crypto6.randomUUID(), job.type, JSON.stringify(job.payload), new Date(nextRun).toISOString(), job.schedule]);
4419
+ await sql2.unsafe(
4420
+ `INSERT INTO ${escapeIdent3(table)} (id, type, payload, run_at, schedule) VALUES ($1, $2, $3::jsonb, $4, $5)`,
4421
+ [
4422
+ crypto6.randomUUID(),
4423
+ job.type,
4424
+ JSON.stringify(job.payload),
4425
+ new Date(nextRun).toISOString(),
4426
+ job.schedule
4427
+ ]
4428
+ );
4250
4429
  } catch (e) {
4251
4430
  console.error("[queue] cron re-queue failed:", e.message);
4252
4431
  }
@@ -4256,10 +4435,20 @@ function createPgQueue(opts) {
4256
4435
  if (!running) return;
4257
4436
  try {
4258
4437
  while (running && inflight < MAX_CONCURRENT) {
4259
- const rows = await sql2.unsafe(`UPDATE ${escapeIdent3(table)} SET status = 'running' WHERE id = (SELECT id FROM ${escapeIdent3(table)} WHERE run_at <= NOW() AND status = 'pending' ORDER BY run_at LIMIT 1 FOR UPDATE SKIP LOCKED) RETURNING *`);
4438
+ const rows = await sql2.unsafe(
4439
+ `UPDATE ${escapeIdent3(table)} SET status = 'running' WHERE id = (SELECT id FROM ${escapeIdent3(table)} WHERE run_at <= NOW() AND status = 'pending' ORDER BY run_at LIMIT 1 FOR UPDATE SKIP LOCKED) RETURNING *`
4440
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4441
+ );
4260
4442
  if (rows.length === 0) break;
4261
4443
  const row = rows[0];
4262
- const job = { id: row.id, type: row.type, payload: typeof row.payload === "string" ? JSON.parse(row.payload) : row.payload, createdAt: new Date(row.created_at).getTime(), runAt: new Date(row.run_at).getTime(), schedule: row.schedule || void 0 };
4444
+ const job = {
4445
+ id: row.id,
4446
+ type: row.type,
4447
+ payload: typeof row.payload === "string" ? JSON.parse(row.payload) : row.payload,
4448
+ createdAt: new Date(row.created_at).getTime(),
4449
+ runAt: new Date(row.run_at).getTime(),
4450
+ schedule: row.schedule || void 0
4451
+ };
4263
4452
  const handler = handlers.get(job.type);
4264
4453
  if (handler) processJob(job, handler);
4265
4454
  }
@@ -4294,7 +4483,10 @@ function createPgQueue(opts) {
4294
4483
  } else {
4295
4484
  runAt = /* @__PURE__ */ new Date();
4296
4485
  }
4297
- await sql2.unsafe(`INSERT INTO ${escapeIdent3(table)} (id, type, payload, run_at, schedule) VALUES ($1, $2, $3::jsonb, $4, $5)`, [id2, type, JSON.stringify(payload), runAt.toISOString(), opts2?.schedule || null]);
4486
+ await sql2.unsafe(
4487
+ `INSERT INTO ${escapeIdent3(table)} (id, type, payload, run_at, schedule) VALUES ($1, $2, $3::jsonb, $4, $5)`,
4488
+ [id2, type, JSON.stringify(payload), runAt.toISOString(), opts2?.schedule || null]
4489
+ );
4298
4490
  return id2;
4299
4491
  })();
4300
4492
  };
@@ -4320,25 +4512,64 @@ function createPgQueue(opts) {
4320
4512
  while (inflight > 0) await new Promise((r) => setTimeout(r, 50));
4321
4513
  };
4322
4514
  mw.jobs = async function jobs(limit) {
4323
- const rows = await sql2.unsafe(`SELECT * FROM ${escapeIdent3(table)} WHERE status = 'pending' ORDER BY run_at LIMIT $1`, [limit ?? 50]);
4324
- return rows.map((r) => ({ id: r.id, type: r.type, payload: typeof r.payload === "string" ? JSON.parse(r.payload) : r.payload, createdAt: new Date(r.created_at).getTime(), runAt: new Date(r.run_at).getTime(), schedule: r.schedule || void 0 }));
4515
+ const rows = await sql2.unsafe(
4516
+ `SELECT * FROM ${escapeIdent3(table)} WHERE status = 'pending' ORDER BY run_at LIMIT $1`,
4517
+ [limit ?? 50]
4518
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4519
+ );
4520
+ return rows.map((r) => ({
4521
+ id: r.id,
4522
+ type: r.type,
4523
+ payload: typeof r.payload === "string" ? JSON.parse(r.payload) : r.payload,
4524
+ createdAt: new Date(r.created_at).getTime(),
4525
+ runAt: new Date(r.run_at).getTime(),
4526
+ schedule: r.schedule || void 0
4527
+ }));
4325
4528
  };
4326
4529
  mw.failedJobs = async function failedJobs(limit) {
4327
- const rows = await sql2.unsafe(`SELECT * FROM ${escapeIdent3(table)} WHERE status = 'failed' ORDER BY failed_at DESC LIMIT $1`, [limit ?? 50]);
4328
- return rows.map((r) => ({ id: r.id, type: r.type, payload: typeof r.payload === "string" ? JSON.parse(r.payload) : r.payload, createdAt: new Date(r.created_at).getTime(), runAt: new Date(r.run_at).getTime(), schedule: r.schedule || void 0, error: r.error || "", failedAt: new Date(r.failed_at).getTime() }));
4530
+ const rows = await sql2.unsafe(
4531
+ `SELECT * FROM ${escapeIdent3(table)} WHERE status = 'failed' ORDER BY failed_at DESC LIMIT $1`,
4532
+ [limit ?? 50]
4533
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4534
+ );
4535
+ return rows.map((r) => ({
4536
+ id: r.id,
4537
+ type: r.type,
4538
+ payload: typeof r.payload === "string" ? JSON.parse(r.payload) : r.payload,
4539
+ createdAt: new Date(r.created_at).getTime(),
4540
+ runAt: new Date(r.run_at).getTime(),
4541
+ schedule: r.schedule || void 0,
4542
+ error: r.error || "",
4543
+ failedAt: new Date(r.failed_at).getTime()
4544
+ }));
4329
4545
  };
4330
4546
  mw.retryFailed = async function retryFailed(jobId) {
4331
- const result = await sql2.unsafe(`UPDATE ${escapeIdent3(table)} SET status = 'pending', error = NULL, failed_at = NULL, run_at = NOW() WHERE id = $1 AND status = 'failed' RETURNING id`, [jobId]);
4547
+ const result = await sql2.unsafe(
4548
+ `UPDATE ${escapeIdent3(table)} SET status = 'pending', error = NULL, failed_at = NULL, run_at = NOW() WHERE id = $1 AND status = 'failed' RETURNING id`,
4549
+ [jobId]
4550
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4551
+ );
4332
4552
  return result.length > 0;
4333
4553
  };
4334
4554
  mw.retryAllFailed = async function retryAllFailed(type) {
4335
- const result = await sql2.unsafe(type ? `UPDATE ${escapeIdent3(table)} SET status = 'pending', error = NULL, failed_at = NULL, run_at = NOW() WHERE status = 'failed' AND type = $1 RETURNING id` : `UPDATE ${escapeIdent3(table)} SET status = 'pending', error = NULL, failed_at = NULL, run_at = NOW() WHERE status = 'failed' RETURNING id`, type ? [type] : []);
4555
+ const result = await sql2.unsafe(
4556
+ type ? `UPDATE ${escapeIdent3(table)} SET status = 'pending', error = NULL, failed_at = NULL, run_at = NOW() WHERE status = 'failed' AND type = $1 RETURNING id` : `UPDATE ${escapeIdent3(table)} SET status = 'pending', error = NULL, failed_at = NULL, run_at = NOW() WHERE status = 'failed' RETURNING id`,
4557
+ type ? [type] : []
4558
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4559
+ );
4336
4560
  return result.length;
4337
4561
  };
4338
4562
  mw.dashboard = function dashboard() {
4339
4563
  return buildDashboard(q);
4340
4564
  };
4341
- mw.stats = () => ({ running, inflight, processed: _processed, failed: _failed, handlers: handlers.size, maxConcurrent: MAX_CONCURRENT });
4565
+ mw.stats = () => ({
4566
+ running,
4567
+ inflight,
4568
+ processed: _processed,
4569
+ failed: _failed,
4570
+ handlers: handlers.size,
4571
+ maxConcurrent: MAX_CONCURRENT
4572
+ });
4342
4573
  attachCron(q, handlers);
4343
4574
  return q;
4344
4575
  }
@@ -4367,7 +4598,16 @@ function createRedisQueue(opts) {
4367
4598
  if (job.schedule) {
4368
4599
  try {
4369
4600
  const nextRun = cronNext(job.schedule);
4370
- await redis2.zadd(jobKey, nextRun, JSON.stringify({ ...job, id: crypto6.randomUUID(), runAt: nextRun, createdAt: Date.now() }));
4601
+ await redis2.zadd(
4602
+ jobKey,
4603
+ nextRun,
4604
+ JSON.stringify({
4605
+ ...job,
4606
+ id: crypto6.randomUUID(),
4607
+ runAt: nextRun,
4608
+ createdAt: Date.now()
4609
+ })
4610
+ );
4371
4611
  } catch (e) {
4372
4612
  console.error("[queue] cron re-queue failed:", e.message);
4373
4613
  }
@@ -4501,7 +4741,14 @@ function createRedisQueue(opts) {
4501
4741
  mw.dashboard = function dashboard() {
4502
4742
  return buildDashboard(q);
4503
4743
  };
4504
- mw.stats = () => ({ running, inflight, processed: _processed, failed: _failed, handlers: handlers.size, maxConcurrent: MAX_CONCURRENT });
4744
+ mw.stats = () => ({
4745
+ running,
4746
+ inflight,
4747
+ processed: _processed,
4748
+ failed: _failed,
4749
+ handlers: handlers.size,
4750
+ maxConcurrent: MAX_CONCURRENT
4751
+ });
4505
4752
  attachCron(q, handlers);
4506
4753
  return q;
4507
4754
  }
@@ -4649,10 +4896,14 @@ function createIndexesSQL(tenantId, slug, fields) {
4649
4896
  const name = internalTableName(tenantId, slug);
4650
4897
  const statements = [];
4651
4898
  statements.push(`CREATE INDEX IF NOT EXISTS "${name}_tenant_idx" ON "${name}" ("tenant_id")`);
4652
- statements.push(`CREATE INDEX IF NOT EXISTS "${name}_tenant_id_idx" ON "${name}" ("tenant_id", "id")`);
4899
+ statements.push(
4900
+ `CREATE INDEX IF NOT EXISTS "${name}_tenant_id_idx" ON "${name}" ("tenant_id", "id")`
4901
+ );
4653
4902
  for (const f of fields) {
4654
4903
  if (f.unique) {
4655
- statements.push(`CREATE UNIQUE INDEX IF NOT EXISTS "${name}_${f.name}_uidx" ON "${name}" ("${f.name}")`);
4904
+ statements.push(
4905
+ `CREATE UNIQUE INDEX IF NOT EXISTS "${name}_${f.name}_uidx" ON "${name}" ("${f.name}")`
4906
+ );
4656
4907
  } else if (f.index === "hnsw") {
4657
4908
  statements.push(
4658
4909
  `CREATE INDEX IF NOT EXISTS "${name}_${f.name}_hnsw_idx" ON "${name}" USING hnsw ("${f.name}" vector_cosine_ops)`
@@ -4914,10 +5165,9 @@ function buildRouter(sql2, usersTable) {
4914
5165
  `SELECT *, "${searchField}" ${operator} $1::vector AS "_distance" FROM "${name2}" WHERE tenant_id = $2 ORDER BY "_distance" LIMIT $3 OFFSET $4`,
4915
5166
  [parsed, ctx.tenant.id, limit, offset]
4916
5167
  ),
4917
- sql2.unsafe(
4918
- `SELECT count(*) as count FROM "${name2}" WHERE tenant_id = $1`,
4919
- [ctx.tenant.id]
4920
- )
5168
+ sql2.unsafe(`SELECT count(*) as count FROM "${name2}" WHERE tenant_id = $1`, [
5169
+ ctx.tenant.id
5170
+ ])
4921
5171
  ]);
4922
5172
  return Response.json({ rows: rows2, count: extractCount(countResult2) });
4923
5173
  } catch {
@@ -4930,10 +5180,7 @@ function buildRouter(sql2, usersTable) {
4930
5180
  `SELECT * FROM "${name}" WHERE tenant_id = $1 ORDER BY "${orderCol}" ${orderDir} LIMIT $2 OFFSET $3`,
4931
5181
  [ctx.tenant.id, limit, offset]
4932
5182
  ),
4933
- sql2.unsafe(
4934
- `SELECT count(*) as count FROM "${name}" WHERE tenant_id = $1`,
4935
- [ctx.tenant.id]
4936
- )
5183
+ sql2.unsafe(`SELECT count(*) as count FROM "${name}" WHERE tenant_id = $1`, [ctx.tenant.id])
4937
5184
  ]);
4938
5185
  return Response.json({ rows, count: extractCount(countResult) });
4939
5186
  });
@@ -5015,7 +5262,10 @@ function buildRouter(sql2, usersTable) {
5015
5262
  if (!childTable) return Response.json({ error: "Nested table not found" }, { status: 404 });
5016
5263
  const relField = findRelation(childTable.fields, ctx.params["_slug"]);
5017
5264
  if (!relField) {
5018
- return Response.json({ error: `No relation from "${nestedSlug}" to "${ctx.params["_slug"]}"` }, { status: 400 });
5265
+ return Response.json(
5266
+ { error: `No relation from "${nestedSlug}" to "${ctx.params["_slug"]}"` },
5267
+ { status: 400 }
5268
+ );
5019
5269
  }
5020
5270
  const relFields = getRelationFields(childTable.fields);
5021
5271
  if (relFields.length === 2) {
@@ -5086,11 +5336,11 @@ import {
5086
5336
  GraphQLID,
5087
5337
  GraphQLList,
5088
5338
  GraphQLNonNull,
5089
- GraphQLEnumType
5339
+ GraphQLEnumType,
5340
+ graphql as executeGraphQL2
5090
5341
  } from "graphql";
5091
- import { graphql as executeGraphQL2 } from "graphql";
5092
5342
  function graphqlType(field, required) {
5093
- let t;
5343
+ let t = GraphQLString;
5094
5344
  switch (field.type) {
5095
5345
  case "integer":
5096
5346
  t = GraphQLInt;
@@ -5107,15 +5357,11 @@ function graphqlType(field, required) {
5107
5357
  name: `Enum_${field.name}`,
5108
5358
  values: Object.fromEntries(field.options.map((o) => [o, { value: o }]))
5109
5359
  });
5110
- } else {
5111
- t = GraphQLString;
5112
5360
  }
5113
5361
  break;
5114
5362
  case "vector":
5115
5363
  t = GraphQLString;
5116
5364
  break;
5117
- default:
5118
- t = GraphQLString;
5119
5365
  }
5120
5366
  return required ? new GraphQLNonNull(t) : t;
5121
5367
  }
@@ -5142,6 +5388,7 @@ function buildObjectType(table, ctx) {
5142
5388
  limit: { type: GraphQLInt, defaultValue: 20 },
5143
5389
  offset: { type: GraphQLInt, defaultValue: 0 }
5144
5390
  },
5391
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5145
5392
  resolve: async (parent) => {
5146
5393
  const childName = internalTableName(ctx.tenantId, other.slug);
5147
5394
  const rows = await ctx.sql.unsafe(
@@ -5164,6 +5411,7 @@ function buildObjectType(table, ctx) {
5164
5411
  limit: { type: GraphQLInt, defaultValue: 20 },
5165
5412
  offset: { type: GraphQLInt, defaultValue: 0 }
5166
5413
  },
5414
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5167
5415
  resolve: async (parent) => {
5168
5416
  const childName = internalTableName(ctx.tenantId, other.slug);
5169
5417
  const targetName = internalTableName(ctx.tenantId, targetSlug);
@@ -5185,6 +5433,7 @@ function buildObjectType(table, ctx) {
5185
5433
  if (!targetTable) continue;
5186
5434
  fields[targetSlug] = {
5187
5435
  type: buildObjectType(targetTable, ctx),
5436
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5188
5437
  resolve: async (parent) => {
5189
5438
  const name = internalTableName(ctx.tenantId, targetSlug);
5190
5439
  const [row] = await ctx.sql.unsafe(
@@ -5205,9 +5454,7 @@ function buildInputType(table, prefix) {
5205
5454
  const typeName = pascalCase(`${prefix}_${table.slug}`) + "Input";
5206
5455
  return new GraphQLInputObjectType({
5207
5456
  name: typeName,
5208
- fields: Object.fromEntries(
5209
- table.fields.map((f) => [f.name, { type: inputGraphqlType(f) }])
5210
- )
5457
+ fields: Object.fromEntries(table.fields.map((f) => [f.name, { type: inputGraphqlType(f) }]))
5211
5458
  });
5212
5459
  }
5213
5460
  function buildQueryFields(tables, ctx) {
@@ -5222,6 +5469,7 @@ function buildQueryFields(tables, ctx) {
5222
5469
  limit: { type: GraphQLInt, defaultValue: 20 },
5223
5470
  offset: { type: GraphQLInt, defaultValue: 0 }
5224
5471
  },
5472
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5225
5473
  resolve: async (_, args) => {
5226
5474
  const name = internalTableName(ctx.tenantId, slug);
5227
5475
  const rows = await ctx.sql.unsafe(
@@ -5234,6 +5482,7 @@ function buildQueryFields(tables, ctx) {
5234
5482
  fields[`get${pascal}`] = {
5235
5483
  type: objType,
5236
5484
  args: { id: { type: new GraphQLNonNull(GraphQLID) } },
5485
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5237
5486
  resolve: async (_, args) => {
5238
5487
  const name = internalTableName(ctx.tenantId, slug);
5239
5488
  const [row] = await ctx.sql.unsafe(
@@ -5256,6 +5505,7 @@ function buildMutationFields(tables, ctx) {
5256
5505
  fields[`create${pascal}`] = {
5257
5506
  type: objType,
5258
5507
  args: { data: { type: new GraphQLNonNull(inputType) } },
5508
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5259
5509
  resolve: async (_, args) => {
5260
5510
  const name = internalTableName(ctx.tenantId, table.slug);
5261
5511
  const data = { ...args.data, tenant_id: ctx.tenantId };
@@ -5272,6 +5522,7 @@ function buildMutationFields(tables, ctx) {
5272
5522
  id: { type: new GraphQLNonNull(GraphQLID) },
5273
5523
  data: { type: new GraphQLNonNull(patchType) }
5274
5524
  },
5525
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5275
5526
  resolve: async (_, args) => {
5276
5527
  const name = internalTableName(ctx.tenantId, table.slug);
5277
5528
  const setClauses = table.fields.filter((f) => args.data[f.name] !== void 0).map((f, i) => `"${f.name}" = $${i + 1}`);
@@ -5294,6 +5545,7 @@ function buildMutationFields(tables, ctx) {
5294
5545
  fields[`delete${pascal}`] = {
5295
5546
  type: GraphQLBoolean,
5296
5547
  args: { id: { type: new GraphQLNonNull(GraphQLID) } },
5548
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
5297
5549
  resolve: async (_, args) => {
5298
5550
  const name = internalTableName(ctx.tenantId, table.slug);
5299
5551
  const result = await ctx.sql.unsafe(
@@ -5404,7 +5656,9 @@ function tenant(options) {
5404
5656
  });
5405
5657
  await members.create();
5406
5658
  await members.createIndex("user_id");
5407
- await sql2.unsafe(`CREATE UNIQUE INDEX IF NOT EXISTS "_tenant_members_unique_idx" ON "_tenant_members" ("tenant_id", "user_id")`);
5659
+ await sql2.unsafe(
5660
+ `CREATE UNIQUE INDEX IF NOT EXISTS "_tenant_members_unique_idx" ON "_tenant_members" ("tenant_id", "user_id")`
5661
+ );
5408
5662
  const tables = pg.table("_user_tables", {
5409
5663
  id: serial("id").primaryKey(),
5410
5664
  tenant_id: text("tenant_id").notNull().references("_tenants", "id", "cascade"),
@@ -5415,7 +5669,9 @@ function tenant(options) {
5415
5669
  });
5416
5670
  await tables.create();
5417
5671
  await tables.createIndex("tenant_id");
5418
- await sql2.unsafe(`CREATE UNIQUE INDEX IF NOT EXISTS "_user_tables_unique_idx" ON "_user_tables" ("tenant_id", "slug")`);
5672
+ await sql2.unsafe(
5673
+ `CREATE UNIQUE INDEX IF NOT EXISTS "_user_tables_unique_idx" ON "_user_tables" ("tenant_id", "slug")`
5674
+ );
5419
5675
  }
5420
5676
  function middleware() {
5421
5677
  return async (req, ctx, next) => {
@@ -5439,10 +5695,13 @@ function tenant(options) {
5439
5695
  }
5440
5696
  const headerId = req.headers.get("X-Tenant-ID");
5441
5697
  if (!headerId) {
5442
- return Response.json({
5443
- error: "Multiple tenants. Set X-Tenant-ID header.",
5444
- tenants: members.map((m) => ({ id: m.id, name: m.name, role: m.role }))
5445
- }, { status: 300 });
5698
+ return Response.json(
5699
+ {
5700
+ error: "Multiple tenants. Set X-Tenant-ID header.",
5701
+ tenants: members.map((m) => ({ id: m.id, name: m.name, role: m.role }))
5702
+ },
5703
+ { status: 300 }
5704
+ );
5446
5705
  }
5447
5706
  const member = members.find((m) => m.id === headerId);
5448
5707
  if (!member) {
@@ -5483,7 +5742,9 @@ function buildRouter2(deps) {
5483
5742
  return Response.json(row, { status: 201 });
5484
5743
  });
5485
5744
  r.get("/agents", async () => {
5486
- const { data: rows } = await agentsTable.readMany(void 0, { orderBy: { created_at: "desc" } });
5745
+ const { data: rows } = await agentsTable.readMany(void 0, {
5746
+ orderBy: { created_at: "desc" }
5747
+ });
5487
5748
  return Response.json(rows);
5488
5749
  });
5489
5750
  r.get("/agents/:id", async (_req, ctx) => {
@@ -5497,7 +5758,14 @@ function buildRouter2(deps) {
5497
5758
  if (!agent2) return Response.json({ error: "Agent not found" }, { status: 404 });
5498
5759
  const body = await req.json();
5499
5760
  const updateData = {};
5500
- for (const key of ["name", "description", "type", "model", "system_prompt", "active"]) {
5761
+ for (const key of [
5762
+ "name",
5763
+ "description",
5764
+ "type",
5765
+ "model",
5766
+ "system_prompt",
5767
+ "active"
5768
+ ]) {
5501
5769
  if (body[key] !== void 0) {
5502
5770
  updateData[key] = body[key];
5503
5771
  }
@@ -5634,7 +5902,9 @@ function chunkContent(content, chunkSize, overlap) {
5634
5902
 
5635
5903
  // agent/run.ts
5636
5904
  function hasKnowledgeDocs(sql2, agentId) {
5637
- return sql2`SELECT 1 FROM "_knowledge_documents" WHERE agent_id = ${agentId} LIMIT 1`.then((r) => r.length > 0);
5905
+ return sql2`SELECT 1 FROM "_knowledge_documents" WHERE agent_id = ${agentId} LIMIT 1`.then(
5906
+ (r) => r.length > 0
5907
+ );
5638
5908
  }
5639
5909
  async function searchKnowledge(sql2, provider, agentId, query, limit = 5) {
5640
5910
  const embedding = await provider.embed(query);
@@ -5808,7 +6078,14 @@ function agent(options) {
5808
6078
  trace_id: text("trace_id"),
5809
6079
  created_at: timestamptz("created_at").notNull().default(sql`NOW()`)
5810
6080
  });
5811
- const runner = createRunner({ sql: sql2, agents: agentsTable, runs: runsTable, knowledge: knowledgeTable, provider: resolvedProvider, userTools: options.tools });
6081
+ const runner = createRunner({
6082
+ sql: sql2,
6083
+ agents: agentsTable,
6084
+ runs: runsTable,
6085
+ knowledge: knowledgeTable,
6086
+ provider: resolvedProvider,
6087
+ userTools: options.tools
6088
+ });
5812
6089
  const base = new PgModule(pg);
5813
6090
  const r = buildRouter2({ agents: agentsTable, runs: runsTable, knowledge: knowledgeTable, runner });
5814
6091
  const mod = r;
@@ -6577,12 +6854,24 @@ async function deploy(config) {
6577
6854
  if (ac.ports && old?.process) {
6578
6855
  targetPort = old.currentPort === ac.ports[0] ? ac.ports[1] : ac.ports[0];
6579
6856
  }
6580
- const mp = await forkAndCheck(name, appDir, ac.entry, targetPort, ac.env, log, ac.healthEndpoint);
6857
+ const mp = await forkAndCheck(
6858
+ name,
6859
+ appDir,
6860
+ ac.entry,
6861
+ targetPort,
6862
+ ac.env,
6863
+ log,
6864
+ ac.healthEndpoint
6865
+ );
6581
6866
  if (!mp) {
6582
6867
  log("[deploy] new process failed to start, keeping old running");
6583
6868
  if (old?.process) apps.set(name, old);
6584
6869
  else {
6585
- setAppRuntime(name, ac, logs, { status: "error", port: targetPort, error: "failed to start" });
6870
+ setAppRuntime(name, ac, logs, {
6871
+ status: "error",
6872
+ port: targetPort,
6873
+ error: "failed to start"
6874
+ });
6586
6875
  }
6587
6876
  return;
6588
6877
  }
@@ -6625,7 +6914,7 @@ async function deploy(config) {
6625
6914
  function setAppRuntime(name, ac, logs, overrides) {
6626
6915
  apps.set(name, {
6627
6916
  config: ac,
6628
- status: { name, ...overrides },
6917
+ status: { name, status: "starting", port: 0, ...overrides },
6629
6918
  logs,
6630
6919
  process: null,
6631
6920
  currentPort: overrides.port ?? ac.port ?? 0,
@@ -6826,7 +7115,7 @@ async function compileVendorBundle() {
6826
7115
  if (vendorBundle) return vendorBundle;
6827
7116
  if (!_userRequire) _userRequire = createRequire(join2(process.cwd(), "package.json"));
6828
7117
  const modules = {
6829
- "react": [],
7118
+ react: [],
6830
7119
  "react-dom": ["react"],
6831
7120
  "react-dom/client": ["react"],
6832
7121
  "react/jsx-runtime": ["react"]
@@ -6863,10 +7152,12 @@ async function compileVendorBundle() {
6863
7152
  const stmts = [""];
6864
7153
  for (const [request, keys] of Object.entries(modules)) {
6865
7154
  const unique = keys.filter((k) => !used.has(k) && used.add(k));
6866
- if (unique.length > 0) stmts.push(`export { ${unique.join(", ")} } from ${JSON.stringify(request)};`);
7155
+ if (unique.length > 0)
7156
+ stmts.push(`export { ${unique.join(", ")} } from ${JSON.stringify(request)};`);
6867
7157
  }
6868
7158
  const uidWfw = wfwKeys.filter((k) => !used.has(k) && used.add(k));
6869
- if (uidWfw.length > 0) stmts.push(`export { ${uidWfw.join(", ")} } from ${JSON.stringify(reactAbsPath)};`);
7159
+ if (uidWfw.length > 0)
7160
+ stmts.push(`export { ${uidWfw.join(", ")} } from ${JSON.stringify(reactAbsPath)};`);
6870
7161
  const result = await esbuild.build({
6871
7162
  stdin: { contents: stmts.join("\n"), resolveDir: process.cwd() },
6872
7163
  format: "esm",
@@ -6909,7 +7200,14 @@ async function compileBrowser(path2, outDir) {
6909
7200
  jsx: "automatic",
6910
7201
  jsxImportSource: "react",
6911
7202
  bundle: true,
6912
- external: ["react", "react-dom", "react-dom/client", "react/jsx-runtime", "weifuwu", "weifuwu/react"],
7203
+ external: [
7204
+ "react",
7205
+ "react-dom",
7206
+ "react-dom/client",
7207
+ "react/jsx-runtime",
7208
+ "weifuwu",
7209
+ "weifuwu/react"
7210
+ ],
6913
7211
  plugins: [plugin],
6914
7212
  write: true,
6915
7213
  allowOverwrite: true
@@ -6943,7 +7241,14 @@ async function compileHotComponent(path2) {
6943
7241
  jsx: "automatic",
6944
7242
  jsxImportSource: "react",
6945
7243
  bundle: true,
6946
- external: ["react", "react-dom", "react-dom/client", "react/jsx-runtime", "weifuwu", "weifuwu/react"],
7244
+ external: [
7245
+ "react",
7246
+ "react-dom",
7247
+ "react-dom/client",
7248
+ "react/jsx-runtime",
7249
+ "weifuwu",
7250
+ "weifuwu/react"
7251
+ ],
6947
7252
  plugins: [plugin],
6948
7253
  write: false
6949
7254
  });
@@ -7147,7 +7452,7 @@ function tailwindRouter(dir) {
7147
7452
  const cssDir = resolve4(dir);
7148
7453
  const cssPath = join3(cssDir, "app", "globals.css");
7149
7454
  const r = new Router();
7150
- r.get("/__wfw/style/:hash.css", async (req, ctx) => {
7455
+ r.get("/__wfw/style/:hash.css", async (_req, _ctx) => {
7151
7456
  if (!cssCache.has(cssPath)) {
7152
7457
  await compileTailwindCss(cssPath, cssDir);
7153
7458
  }
@@ -7231,7 +7536,7 @@ function liveWs() {
7231
7536
  }
7232
7537
  };
7233
7538
  }
7234
- function liveRouter(dir) {
7539
+ function liveRouter(_dir) {
7235
7540
  const r = new Router();
7236
7541
  compileVendorBundle().catch(() => {
7237
7542
  });
@@ -7503,7 +7808,13 @@ async function resolveRoute(ssrDir, segments, routeCache) {
7503
7808
  if (d === appDir) break;
7504
7809
  d = dirname3(d);
7505
7810
  }
7506
- const result = { routePath: "/" + routeParams.join("/"), pageFile, layoutFiles, errorFiles, notFoundFile };
7811
+ const result = {
7812
+ routePath: "/" + routeParams.join("/"),
7813
+ pageFile,
7814
+ layoutFiles,
7815
+ errorFiles,
7816
+ notFoundFile
7817
+ };
7507
7818
  routeCache.set(cacheKey, result);
7508
7819
  return result;
7509
7820
  }
@@ -7560,7 +7871,6 @@ function renderPage(pageFile, outDir) {
7560
7871
  const absPath = resolve6(pageFile);
7561
7872
  const entryId = hashId(absPath);
7562
7873
  ssrEntries.set(entryId, { path: absPath });
7563
- const bundleKey = `/__ssr/${entryId}.js`;
7564
7874
  return async (req, ctx) => {
7565
7875
  let pageMod;
7566
7876
  try {
@@ -7574,7 +7884,6 @@ function renderPage(pageFile, outDir) {
7574
7884
  if (!Component) return errorPage("Missing default export", pageFile);
7575
7885
  const layouts = ctx.layoutStack || [];
7576
7886
  const layoutComponents = layouts.map((l) => l.component);
7577
- const layoutPaths = layouts.map((l) => l.path);
7578
7887
  const base = (ctx.mountPath || "").replace(/\/$/, "");
7579
7888
  const loaderData = serializeLoaderData(ctx);
7580
7889
  const ctxValue = {
@@ -7594,22 +7903,22 @@ function renderPage(pageFile, outDir) {
7594
7903
  let element = createElement3(
7595
7904
  "div",
7596
7905
  { id: "__weifuwu_root" },
7597
- createElement3(
7598
- TsxContext.Provider,
7599
- { value: ctxValue },
7600
- createElement3(Component, null)
7601
- )
7906
+ createElement3(TsxContext.Provider, { value: ctxValue }, createElement3(Component, null))
7602
7907
  );
7603
7908
  element = buildHtmlShell("weifuwu", element, layoutComponents);
7604
7909
  const { renderToReadableStream } = await import("react-dom/server");
7605
7910
  const stream = await renderToReadableStream(element);
7606
- return streamResponse(stream, {
7607
- ctx,
7608
- base,
7609
- isDev: isDev2,
7610
- loaderData,
7611
- tailwind: ctx.tailwind
7612
- }, buildHydrationScript(entryId, JSON.stringify(ctxValue), base));
7911
+ return streamResponse(
7912
+ stream,
7913
+ {
7914
+ ctx,
7915
+ base,
7916
+ isDev: isDev2,
7917
+ loaderData,
7918
+ tailwind: ctx.tailwind
7919
+ },
7920
+ buildHydrationScript(entryId, JSON.stringify(ctxValue), base)
7921
+ );
7613
7922
  });
7614
7923
  };
7615
7924
  }
@@ -7693,13 +8002,16 @@ function ssr(opts) {
7693
8002
  if (!resolved) {
7694
8003
  if (isDev2) {
7695
8004
  const pages = discoverRoutes(dir).map((p) => p.path).sort();
7696
- return Response.json({
7697
- error: "Not Found",
7698
- path: "/" + segments.join("/"),
7699
- method: req.method,
7700
- hint: "Available SSR pages",
7701
- pages
7702
- }, { status: 404 });
8005
+ return Response.json(
8006
+ {
8007
+ error: "Not Found",
8008
+ path: "/" + segments.join("/"),
8009
+ method: req.method,
8010
+ hint: "Available SSR pages",
8011
+ pages
8012
+ },
8013
+ { status: 404 }
8014
+ );
7703
8015
  }
7704
8016
  return new Response("Not Found", { status: 404 });
7705
8017
  }
@@ -7765,7 +8077,11 @@ async function getSession(sql2, id2) {
7765
8077
  async function listSessions(sql2, userId2) {
7766
8078
  const opts = { orderBy: { updated_at: "desc" } };
7767
8079
  if (userId2 !== void 0) {
7768
- const { data: rows2 } = await sessions.readMany(sql2, { user_id: userId2, active: true }, opts);
8080
+ const { data: rows2 } = await sessions.readMany(
8081
+ sql2,
8082
+ { user_id: userId2, active: true },
8083
+ opts
8084
+ );
7769
8085
  return rows2;
7770
8086
  }
7771
8087
  const { data: rows } = await sessions.readMany(sql2, { active: true }, opts);
@@ -7844,7 +8160,14 @@ async function* executeGenerator(opts) {
7844
8160
  totalTokens: result2.usage?.totalTokens ?? 0
7845
8161
  };
7846
8162
  try {
7847
- await addTextMessage(sql2, sessionId, "assistant", currentAssistantText, currentUsage.promptTokens, currentUsage.completionTokens);
8163
+ await addTextMessage(
8164
+ sql2,
8165
+ sessionId,
8166
+ "assistant",
8167
+ currentAssistantText,
8168
+ currentUsage.promptTokens,
8169
+ currentUsage.completionTokens
8170
+ );
7848
8171
  } catch (e) {
7849
8172
  console.error("[opencode] save message failed:", e);
7850
8173
  }
@@ -7887,11 +8210,7 @@ var DENIED_COMMANDS = [
7887
8210
  /^:\(\)\{.*\}:;$/,
7888
8211
  /^fork\s+bomb/i
7889
8212
  ];
7890
- var DENIED_PATHS = [
7891
- /\/\.env$/,
7892
- /\/\.env\.\w+$/,
7893
- /\/node_modules\//
7894
- ];
8213
+ var DENIED_PATHS = [/\/\.env$/, /\/\.env\.\w+$/, /\/node_modules\//];
7895
8214
  function isCommandAllowed(command) {
7896
8215
  const trimmed = command.trim();
7897
8216
  for (const re of DENIED_COMMANDS) {
@@ -7899,7 +8218,7 @@ function isCommandAllowed(command) {
7899
8218
  }
7900
8219
  return true;
7901
8220
  }
7902
- function isPathAllowed(resolvedPath, workspace, perms) {
8221
+ function isPathAllowed(resolvedPath, workspace, _perms) {
7903
8222
  if (!resolvedPath.startsWith(workspace)) return false;
7904
8223
  for (const re of DENIED_PATHS) {
7905
8224
  if (re.test(resolvedPath)) return false;
@@ -7954,16 +8273,20 @@ function createBashTool(ctx) {
7954
8273
  }
7955
8274
  const cwd = workdir ? `${ctx.workspace}/${workdir}` : ctx.workspace;
7956
8275
  return new Promise((resolve14) => {
7957
- const child = exec(command, { cwd, timeout: timeout * 1e3, maxBuffer: 1024 * 1024 }, (error, stdout, stderr) => {
7958
- const truncated = stdout.length > 1e6 || stderr.length > 1e6;
7959
- resolve14({
7960
- stdout: stdout.slice(0, 1e6),
7961
- stderr: stderr.slice(0, 1e6),
7962
- exitCode: error?.code ?? 0,
7963
- signal: error?.signal ?? null,
7964
- truncated
7965
- });
7966
- });
8276
+ const child = exec(
8277
+ command,
8278
+ { cwd, timeout: timeout * 1e3, maxBuffer: 1024 * 1024 },
8279
+ (error, stdout, stderr) => {
8280
+ const truncated = stdout.length > 1e6 || stderr.length > 1e6;
8281
+ resolve14({
8282
+ stdout: stdout.slice(0, 1e6),
8283
+ stderr: stderr.slice(0, 1e6),
8284
+ exitCode: error?.code ?? 0,
8285
+ signal: error?.signal ?? null,
8286
+ truncated
8287
+ });
8288
+ }
8289
+ );
7967
8290
  });
7968
8291
  }
7969
8292
  });
@@ -8070,7 +8393,10 @@ function createEditTool(ctx) {
8070
8393
  }
8071
8394
  const secondIdx = content.indexOf(oldString, firstIdx + 1);
8072
8395
  if (secondIdx !== -1) {
8073
- return { error: "Found multiple matches. Provide more surrounding context in oldString.", replaced: 0 };
8396
+ return {
8397
+ error: "Found multiple matches. Provide more surrounding context in oldString.",
8398
+ replaced: 0
8399
+ };
8074
8400
  }
8075
8401
  const result = content.replace(oldString, newString);
8076
8402
  writeFileSync3(resolved, result, "utf-8");
@@ -8112,7 +8438,11 @@ function createGrepTool(ctx) {
8112
8438
  stdout = execFileSync("grep", args, { timeout: 15e3, maxBuffer: 1024 * 1024 }).toString();
8113
8439
  }
8114
8440
  const lines = stdout.split("\n").filter(Boolean);
8115
- return { matches: lines.length, results: lines.slice(0, 200), truncated: lines.length > 200 };
8441
+ return {
8442
+ matches: lines.length,
8443
+ results: lines.slice(0, 200),
8444
+ truncated: lines.length > 200
8445
+ };
8116
8446
  } catch (e) {
8117
8447
  if (e.status === 1) {
8118
8448
  return { matches: 0, results: [], truncated: false };
@@ -8138,19 +8468,20 @@ function createGlobTool(ctx) {
8138
8468
  execute: async ({ pattern, path: path2 }) => {
8139
8469
  const searchDir = path2 ? resolve11(ctx.workspace, path2) : ctx.workspace;
8140
8470
  try {
8141
- const stdout = execFileSync2("find", [
8142
- searchDir,
8143
- "-name",
8144
- pattern,
8145
- "-not",
8146
- "-path",
8147
- "*/node_modules/*"
8148
- ], {
8149
- timeout: 1e4,
8150
- maxBuffer: 1024 * 1024
8151
- }).toString();
8471
+ const stdout = execFileSync2(
8472
+ "find",
8473
+ [searchDir, "-name", pattern, "-not", "-path", "*/node_modules/*"],
8474
+ {
8475
+ timeout: 1e4,
8476
+ maxBuffer: 1024 * 1024
8477
+ }
8478
+ ).toString();
8152
8479
  const lines = stdout.split("\n").filter(Boolean).slice(0, 200);
8153
- return { files: lines, total: lines.length, truncated: stdout.split("\n").filter(Boolean).length > 200 };
8480
+ return {
8481
+ files: lines,
8482
+ total: lines.length,
8483
+ truncated: stdout.split("\n").filter(Boolean).length > 200
8484
+ };
8154
8485
  } catch {
8155
8486
  return { files: [], total: 0, truncated: false };
8156
8487
  }
@@ -8161,7 +8492,7 @@ function createGlobTool(ctx) {
8161
8492
  // opencode/tools/web.ts
8162
8493
  import { tool as tool9 } from "ai";
8163
8494
  import { z as z11 } from "zod";
8164
- function createWebTool(ctx) {
8495
+ function createWebTool(_ctx) {
8165
8496
  return tool9({
8166
8497
  description: "Fetch a URL and return the content as text.",
8167
8498
  inputSchema: z11.object({
@@ -8290,15 +8621,29 @@ function createTools(ctx) {
8290
8621
 
8291
8622
  // opencode/rest.ts
8292
8623
  async function buildRouter4(deps) {
8293
- const { sql: sql2, model, workspace, systemPrompt, skills, skillsRegistry, permissions: permissions2, pendingQuestions } = deps;
8624
+ const {
8625
+ sql: sql2,
8626
+ model,
8627
+ workspace,
8628
+ systemPrompt,
8629
+ skills,
8630
+ skillsRegistry,
8631
+ permissions: permissions2,
8632
+ pendingQuestions
8633
+ } = deps;
8294
8634
  const router = new Router();
8295
8635
  router.post("/sessions", async (req, ctx) => {
8296
8636
  const body = await req.json().catch(() => ({}));
8297
- const session2 = await createSession(sql2, {
8298
- title: body.title,
8299
- model: body.model,
8300
- systemPrompt: body.systemPrompt || systemPrompt
8301
- }, workspace, ctx.mountPath || "");
8637
+ const session2 = await createSession(
8638
+ sql2,
8639
+ {
8640
+ title: body.title,
8641
+ model: body.model,
8642
+ systemPrompt: body.systemPrompt || systemPrompt
8643
+ },
8644
+ workspace,
8645
+ ctx.mountPath || ""
8646
+ );
8302
8647
  return Response.json(session2, { status: 201 });
8303
8648
  });
8304
8649
  router.get("/sessions", async () => {
@@ -8362,7 +8707,11 @@ async function buildRouter4(deps) {
8362
8707
  FROM "_opencode_messages"
8363
8708
  WHERE session_id = ${sessionId}
8364
8709
  `;
8365
- const stats = rows[0] || { message_count: 0, total_tokens_in: 0, total_tokens_out: 0 };
8710
+ const stats = rows[0] || {
8711
+ message_count: 0,
8712
+ total_tokens_in: 0,
8713
+ total_tokens_out: 0
8714
+ };
8366
8715
  return Response.json({
8367
8716
  session_id: sessionId,
8368
8717
  message_count: stats.message_count,
@@ -8383,7 +8732,16 @@ async function buildRouter4(deps) {
8383
8732
  // opencode/ws.ts
8384
8733
  var clients2 = /* @__PURE__ */ new WeakMap();
8385
8734
  function createWSHandler2(deps) {
8386
- const { sql: sql2, model, workspace, systemPrompt, skills, skillsRegistry, permissions: permissions2, pendingQuestions } = deps;
8735
+ const {
8736
+ sql: sql2,
8737
+ model,
8738
+ workspace,
8739
+ systemPrompt,
8740
+ skills,
8741
+ skillsRegistry,
8742
+ permissions: permissions2,
8743
+ pendingQuestions
8744
+ } = deps;
8387
8745
  return {
8388
8746
  open(ws, ctx) {
8389
8747
  const userId2 = ctx.user?.id ?? 0;
@@ -8403,12 +8761,17 @@ function createWSHandler2(deps) {
8403
8761
  switch (msg.type) {
8404
8762
  case "create": {
8405
8763
  try {
8406
- const session2 = await createSession(sql2, {
8407
- userId: client.userId,
8408
- title: msg.title,
8409
- model: msg.model,
8410
- systemPrompt: msg.systemPrompt || systemPrompt
8411
- }, workspace, client.mountPath);
8764
+ const session2 = await createSession(
8765
+ sql2,
8766
+ {
8767
+ userId: client.userId,
8768
+ title: msg.title,
8769
+ model: msg.model,
8770
+ systemPrompt: msg.systemPrompt || systemPrompt
8771
+ },
8772
+ workspace,
8773
+ client.mountPath
8774
+ );
8412
8775
  ws.send(JSON.stringify({ type: "session_created", session: session2 }));
8413
8776
  } catch (e) {
8414
8777
  ws.send(JSON.stringify({ type: "error", error: e.message }));
@@ -8505,8 +8868,7 @@ function createWSHandler2(deps) {
8505
8868
  }
8506
8869
 
8507
8870
  // opencode/skills.ts
8508
- import { readFile } from "node:fs/promises";
8509
- import { glob } from "node:fs/promises";
8871
+ import { readFile, glob } from "node:fs/promises";
8510
8872
  import { homedir } from "node:os";
8511
8873
  import { resolve as resolve12 } from "node:path";
8512
8874
  import { parse as parseYaml } from "yaml";
@@ -8603,7 +8965,16 @@ async function opencode(options) {
8603
8965
  const model = provider.chat(modelName);
8604
8966
  const pendingQuestions = /* @__PURE__ */ new Map();
8605
8967
  const base = new PgModule(pg);
8606
- const r = await buildRouter4({ sql: sql2, model, workspace, systemPrompt, skills: manualSkills, skillsRegistry, permissions: permissions2, pendingQuestions });
8968
+ const r = await buildRouter4({
8969
+ sql: sql2,
8970
+ model,
8971
+ workspace,
8972
+ systemPrompt,
8973
+ skills: manualSkills,
8974
+ skillsRegistry,
8975
+ permissions: permissions2,
8976
+ pendingQuestions
8977
+ });
8607
8978
  const mod = r;
8608
8979
  mod.migrate = async () => {
8609
8980
  const sessions2 = pg.table("_opencode_sessions", {
@@ -8636,7 +9007,16 @@ async function opencode(options) {
8636
9007
  await messages2.create();
8637
9008
  await messages2.createIndex(["session_id", "created_at"]);
8638
9009
  };
8639
- mod.wsHandler = () => createWSHandler2({ sql: sql2, model, workspace, systemPrompt, skills: manualSkills, skillsRegistry, permissions: permissions2, pendingQuestions });
9010
+ mod.wsHandler = () => createWSHandler2({
9011
+ sql: sql2,
9012
+ model,
9013
+ workspace,
9014
+ systemPrompt,
9015
+ skills: manualSkills,
9016
+ skillsRegistry,
9017
+ permissions: permissions2,
9018
+ pendingQuestions
9019
+ });
8640
9020
  mod.close = () => base.close();
8641
9021
  return mod;
8642
9022
  }
@@ -8745,7 +9125,10 @@ var MemStore = class {
8745
9125
  daily,
8746
9126
  top_pages: topPages,
8747
9127
  referrers: [...refMap.entries()].sort((a, b) => b[1] - a[1]).slice(0, 10).map(([domain, count]) => ({ domain, count })),
8748
- devices: { mobile: Math.round(totalMobile / total * 1e3) / 10, desktop: Math.round(totalDesktop / total * 1e3) / 10 }
9128
+ devices: {
9129
+ mobile: Math.round(totalMobile / total * 1e3) / 10,
9130
+ desktop: Math.round(totalDesktop / total * 1e3) / 10
9131
+ }
8749
9132
  };
8750
9133
  }
8751
9134
  };
@@ -8798,7 +9181,10 @@ async function queryPg(sql2, days) {
8798
9181
  daily: daily.map((d) => ({ date: d.date, pv: d.pv, uv: d.uv })),
8799
9182
  top_pages: pageRows.map((p) => ({ path: p.path, pv: p.pv })),
8800
9183
  referrers: [],
8801
- devices: { mobile: Math.round(t.total_mobile / denom * 1e3) / 10, desktop: Math.round(t.total_desktop / denom * 1e3) / 10 }
9184
+ devices: {
9185
+ mobile: Math.round(t.total_mobile / denom * 1e3) / 10,
9186
+ desktop: Math.round(t.total_desktop / denom * 1e3) / 10
9187
+ }
8802
9188
  };
8803
9189
  }
8804
9190
  function escapeHtml2(s) {
@@ -8813,9 +9199,7 @@ function renderDashboard(days, data) {
8813
9199
  const rows = top_pages.map(
8814
9200
  (p, i) => `<tr><td class="num">${i + 1}</td><td class="path">${escapeHtml2(p.path)}</td><td class="num">${p.pv}</td></tr>`
8815
9201
  ).join("");
8816
- const refRows = referrers.map(
8817
- (r) => `<tr><td>${escapeHtml2(r.domain)}</td><td class="num">${r.count}</td></tr>`
8818
- ).join("");
9202
+ const refRows = referrers.map((r) => `<tr><td>${escapeHtml2(r.domain)}</td><td class="num">${r.count}</td></tr>`).join("");
8819
9203
  return `<!DOCTYPE html><html lang="en">
8820
9204
  <head><meta charset="utf-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><title>Analytics - weifuwu</title>
8821
9205
  <style>*,:before,:after{box-sizing:border-box;margin:0;padding:0}
@@ -9022,7 +9406,10 @@ function i18n(options) {
9022
9406
  set: (value, loc) => {
9023
9407
  const cookie = `${opts.cookie}=${encodeURIComponent(value)}; Path=/; SameSite=Lax`;
9024
9408
  const location = loc ?? (req.headers.get("referer") || "/");
9025
- return new Response(null, { status: 302, headers: { Location: location, "Set-Cookie": cookie } });
9409
+ return new Response(null, {
9410
+ status: 302,
9411
+ headers: { Location: location, "Set-Cookie": cookie }
9412
+ });
9026
9413
  }
9027
9414
  };
9028
9415
  return next(req, ctx);
@@ -9041,7 +9428,11 @@ function i18n(options) {
9041
9428
  const accept = req.headers.get("accept") ?? "";
9042
9429
  if (accept.includes("application/json")) {
9043
9430
  return Response.json(
9044
- { ok: true, locale: value, messages: Object.keys(messages2).length > 0 ? messages2 : void 0 },
9431
+ {
9432
+ ok: true,
9433
+ locale: value,
9434
+ messages: Object.keys(messages2).length > 0 ? messages2 : void 0
9435
+ },
9045
9436
  { headers: { "Set-Cookie": cookie } }
9046
9437
  );
9047
9438
  }
@@ -9359,10 +9750,11 @@ function listHandler(entries) {
9359
9750
  if (before) conditions.push(lt("created_at", before));
9360
9751
  const limit = parseInt(url.searchParams.get("limit") ?? "50", 10);
9361
9752
  const offset = parseInt(url.searchParams.get("offset") ?? "0", 10);
9362
- const { count, data } = await entries.readMany(
9363
- conditions.length > 0 ? conditions : void 0,
9364
- { orderBy: { created_at: "desc" }, limit, offset }
9365
- );
9753
+ const { count, data } = await entries.readMany(conditions.length > 0 ? conditions : void 0, {
9754
+ orderBy: { created_at: "desc" },
9755
+ limit,
9756
+ offset
9757
+ });
9366
9758
  return Response.json({ entries: data.map(parseMetadata), total: count });
9367
9759
  };
9368
9760
  }
@@ -9473,12 +9865,15 @@ import crypto8 from "node:crypto";
9473
9865
 
9474
9866
  // iii/stream.ts
9475
9867
  function notify(channels, stream, group, item, event, data) {
9476
- const keys = [
9477
- `${stream}`,
9478
- `${stream}:${group}`,
9479
- `${stream}:${group}:${item}`
9480
- ];
9481
- const msg = JSON.stringify({ type: "stream", stream_name: stream, group_id: group, item_id: item, event, data });
9868
+ const keys = [`${stream}`, `${stream}:${group}`, `${stream}:${group}:${item}`];
9869
+ const msg = JSON.stringify({
9870
+ type: "stream",
9871
+ stream_name: stream,
9872
+ group_id: group,
9873
+ item_id: item,
9874
+ event,
9875
+ data
9876
+ });
9482
9877
  for (const key of keys) {
9483
9878
  const subs = channels.get(key);
9484
9879
  if (!subs) continue;
@@ -9697,10 +10092,13 @@ function createRedisStore(channels, redis2, ttl) {
9697
10092
  async set(stream, group, item, data) {
9698
10093
  const hk = hashKey(stream, group);
9699
10094
  const oldRaw = await redis2.hget(hk, item);
9700
- let old = oldRaw ? JSON.parse(oldRaw) : null;
10095
+ const old = oldRaw ? JSON.parse(oldRaw) : null;
9701
10096
  await redis2.hset(hk, item, JSON.stringify(data));
9702
10097
  setTTL(hk);
9703
- await redis2.publish(`iii:stream:${stream}`, JSON.stringify({ event: "set", group, item, data }));
10098
+ await redis2.publish(
10099
+ `iii:stream:${stream}`,
10100
+ JSON.stringify({ event: "set", group, item, data })
10101
+ );
9704
10102
  notify(channels, stream, group, item, "set", data);
9705
10103
  return { old_value: old, new_value: deepClone(data) };
9706
10104
  },
@@ -9776,7 +10174,10 @@ function createRedisStore(channels, redis2, ttl) {
9776
10174
  const newVal = applyOps(old, ops);
9777
10175
  await redis2.hset(hk, item, JSON.stringify(newVal));
9778
10176
  setTTL(hk);
9779
- await redis2.publish(`iii:stream:${stream}`, JSON.stringify({ event: "update", group, item, data: newVal }));
10177
+ await redis2.publish(
10178
+ `iii:stream:${stream}`,
10179
+ JSON.stringify({ event: "update", group, item, data: newVal })
10180
+ );
9780
10181
  notify(channels, stream, group, item, "update", newVal);
9781
10182
  return { old_value: old, new_value: deepClone(newVal) };
9782
10183
  }
@@ -9856,10 +10257,7 @@ function createWsHandler(deps) {
9856
10257
  }
9857
10258
  switch (msg.type) {
9858
10259
  case "register_worker": {
9859
- const workerId = deps.registerRemoteWorker(
9860
- ws,
9861
- msg.worker_name || `remote-${Date.now()}`
9862
- );
10260
+ const workerId = deps.registerRemoteWorker(ws, msg.worker_name || `remote-${Date.now()}`);
9863
10261
  wsToWorkerId.set(ws, workerId);
9864
10262
  ws.send(JSON.stringify({ type: "registered", worker_id: workerId }));
9865
10263
  break;
@@ -9963,10 +10361,7 @@ function buildRouter5(engine, wsHandler) {
9963
10361
  }
9964
10362
  return Response.json(result);
9965
10363
  } catch (err) {
9966
- return Response.json(
9967
- { error: err.message || "Internal error" },
9968
- { status: 500 }
9969
- );
10364
+ return Response.json({ error: err.message || "Internal error" }, { status: 500 });
9970
10365
  }
9971
10366
  });
9972
10367
  r.ws("/worker", wsHandler);
@@ -9989,14 +10384,23 @@ function iii(opts = {}) {
9989
10384
  triggers: []
9990
10385
  });
9991
10386
  }
9992
- registerBuiltin("stream::set", (p) => stream.set(p.stream_name, p.group_id, p.item_id, p.data));
10387
+ registerBuiltin(
10388
+ "stream::set",
10389
+ (p) => stream.set(p.stream_name, p.group_id, p.item_id, p.data)
10390
+ );
9993
10391
  registerBuiltin("stream::get", (p) => stream.get(p.stream_name, p.group_id, p.item_id));
9994
10392
  registerBuiltin("stream::delete", (p) => stream.delete(p.stream_name, p.group_id, p.item_id));
9995
10393
  registerBuiltin("stream::list", (p) => stream.list(p.stream_name, p.group_id));
9996
10394
  registerBuiltin("stream::list_groups", (p) => stream.list_groups(p.stream_name));
9997
10395
  registerBuiltin("stream::list_all", () => stream.list_all());
9998
- registerBuiltin("stream::send", (p) => stream.send(p.stream_name, p.group_id, p.type, p.data, p.id));
9999
- registerBuiltin("stream::update", (p) => stream.update(p.stream_name, p.group_id, p.item_id, p.ops));
10396
+ registerBuiltin(
10397
+ "stream::send",
10398
+ (p) => stream.send(p.stream_name, p.group_id, p.type, p.data, p.id)
10399
+ );
10400
+ registerBuiltin(
10401
+ "stream::update",
10402
+ (p) => stream.update(p.stream_name, p.group_id, p.item_id, p.ops)
10403
+ );
10000
10404
  function addLocalWorker(worker) {
10001
10405
  const workerId = crypto8.randomUUID();
10002
10406
  const reg = {
@@ -10049,12 +10453,14 @@ function iii(opts = {}) {
10049
10453
  reject(new Error(`Invocation timed out for "${id2}"`));
10050
10454
  }, 3e4);
10051
10455
  pending.set(invocationId, { resolve: resolve14, reject, timer });
10052
- worker.ws.send(JSON.stringify({
10053
- type: "invoke",
10054
- invocation_id: invocationId,
10055
- function_id: id2,
10056
- payload
10057
- }));
10456
+ worker.ws.send(
10457
+ JSON.stringify({
10458
+ type: "invoke",
10459
+ invocation_id: invocationId,
10460
+ function_id: id2,
10461
+ payload
10462
+ })
10463
+ );
10058
10464
  });
10059
10465
  };
10060
10466
  const fnReg = {
@@ -10138,18 +10544,26 @@ function iii(opts = {}) {
10138
10544
  handleInvoke(ws, invocationId, functionId, payload) {
10139
10545
  const fn = functions.get(functionId);
10140
10546
  if (!fn) {
10141
- ws.send(JSON.stringify({
10142
- type: "invoke_error",
10143
- invocation_id: invocationId,
10144
- error: `Function "${functionId}" not found`
10145
- }));
10547
+ ws.send(
10548
+ JSON.stringify({
10549
+ type: "invoke_error",
10550
+ invocation_id: invocationId,
10551
+ error: `Function "${functionId}" not found`
10552
+ })
10553
+ );
10146
10554
  return;
10147
10555
  }
10148
10556
  const ctx = { engine: engineRef, functionId, workerName: fn.workerName };
10149
10557
  Promise.resolve(fn.handler(payload, ctx)).then((result) => {
10150
10558
  ws.send(JSON.stringify({ type: "invoke_result", invocation_id: invocationId, result }));
10151
10559
  }).catch((err) => {
10152
- ws.send(JSON.stringify({ type: "invoke_error", invocation_id: invocationId, error: err.message }));
10560
+ ws.send(
10561
+ JSON.stringify({
10562
+ type: "invoke_error",
10563
+ invocation_id: invocationId,
10564
+ error: err.message
10565
+ })
10566
+ );
10153
10567
  });
10154
10568
  }
10155
10569
  });
@@ -10313,25 +10727,31 @@ function registerWorker(url) {
10313
10727
  case "invoke": {
10314
10728
  const handler = handlers.get(msg.function_id);
10315
10729
  if (!handler) {
10316
- ws?.send(JSON.stringify({
10317
- type: "invoke_error",
10318
- invocation_id: msg.invocation_id,
10319
- error: `Function "${msg.function_id}" not found`
10320
- }));
10730
+ ws?.send(
10731
+ JSON.stringify({
10732
+ type: "invoke_error",
10733
+ invocation_id: msg.invocation_id,
10734
+ error: `Function "${msg.function_id}" not found`
10735
+ })
10736
+ );
10321
10737
  return;
10322
10738
  }
10323
10739
  Promise.resolve(handler(msg.payload, {})).then((result) => {
10324
- ws?.send(JSON.stringify({
10325
- type: "invoke_result",
10326
- invocation_id: msg.invocation_id,
10327
- result
10328
- }));
10740
+ ws?.send(
10741
+ JSON.stringify({
10742
+ type: "invoke_result",
10743
+ invocation_id: msg.invocation_id,
10744
+ result
10745
+ })
10746
+ );
10329
10747
  }).catch((err) => {
10330
- ws?.send(JSON.stringify({
10331
- type: "invoke_error",
10332
- invocation_id: msg.invocation_id,
10333
- error: err.message
10334
- }));
10748
+ ws?.send(
10749
+ JSON.stringify({
10750
+ type: "invoke_error",
10751
+ invocation_id: msg.invocation_id,
10752
+ error: err.message
10753
+ })
10754
+ );
10335
10755
  });
10336
10756
  break;
10337
10757
  }
@@ -10385,7 +10805,12 @@ function registerWorker(url) {
10385
10805
  },
10386
10806
  registerTrigger(input) {
10387
10807
  registeredTriggers.add(JSON.stringify(input));
10388
- send({ type: "register_trigger", function_id: input.function_id, trigger_type: input.type, config: input.config });
10808
+ send({
10809
+ type: "register_trigger",
10810
+ function_id: input.function_id,
10811
+ trigger_type: input.type,
10812
+ config: input.config
10813
+ });
10389
10814
  },
10390
10815
  unregisterTrigger(functionId) {
10391
10816
  for (const key of registeredTriggers) {
@@ -10560,8 +10985,18 @@ function createSessionObject(data, sid, store2, ttl, createdAt) {
10560
10985
  enumerable: false,
10561
10986
  configurable: false
10562
10987
  });
10563
- Object.defineProperty(obj, "save", { enumerable: false, configurable: true, writable: true, value: obj.save });
10564
- Object.defineProperty(obj, "destroy", { enumerable: false, configurable: true, writable: true, value: obj.destroy });
10988
+ Object.defineProperty(obj, "save", {
10989
+ enumerable: false,
10990
+ configurable: true,
10991
+ writable: true,
10992
+ value: obj.save
10993
+ });
10994
+ Object.defineProperty(obj, "destroy", {
10995
+ enumerable: false,
10996
+ configurable: true,
10997
+ writable: true,
10998
+ value: obj.destroy
10999
+ });
10565
11000
  return obj;
10566
11001
  }
10567
11002
  function isSessionActive(session2) {
@@ -10931,7 +11366,8 @@ function createStripeVerifier(config) {
10931
11366
  }, {});
10932
11367
  const timestamp = parts["t"];
10933
11368
  const signature = parts["v1"];
10934
- if (!timestamp || !signature) return { valid: false, provider: "stripe", event: "", id: void 0 };
11369
+ if (!timestamp || !signature)
11370
+ return { valid: false, provider: "stripe", event: "", id: void 0 };
10935
11371
  const signed = `${timestamp}.${body}`;
10936
11372
  const expected = crypto11.createHmac("sha256", config.secret).update(signed).digest("hex");
10937
11373
  const valid = timingSafeEqual2(signature, expected);
@@ -10952,7 +11388,7 @@ function createGitHubVerifier(config) {
10952
11388
  if (!sig) return { valid: false, provider: "github", event: "", id: void 0 };
10953
11389
  const expected = `sha256=${crypto11.createHmac("sha256", config.secret).update(body).digest("hex")}`;
10954
11390
  const valid = timingSafeEqual2(sig, expected);
10955
- let event = headers["x-github-event"] ?? "";
11391
+ const event = headers["x-github-event"] ?? "";
10956
11392
  let id2;
10957
11393
  try {
10958
11394
  const parsed = JSON.parse(body);
@@ -10966,7 +11402,8 @@ function createSlackVerifier(config) {
10966
11402
  return (body, headers) => {
10967
11403
  const signature = headers["x-slack-signature"];
10968
11404
  const timestamp = headers["x-slack-request-timestamp"];
10969
- if (!signature || !timestamp) return { valid: false, provider: "slack", event: "", id: void 0 };
11405
+ if (!signature || !timestamp)
11406
+ return { valid: false, provider: "slack", event: "", id: void 0 };
10970
11407
  const now = Math.floor(Date.now() / 1e3);
10971
11408
  const ts = parseInt(timestamp, 10);
10972
11409
  if (isNaN(ts) || Math.abs(now - ts) > 300) {
@@ -11128,11 +11565,7 @@ __export(fts_exports, {
11128
11565
  suggest: () => suggest
11129
11566
  });
11130
11567
  function resolveTableName(table) {
11131
- const name = table.inner?.tableName ?? table.tableName;
11132
- if (!name || typeof name !== "string") {
11133
- throw new Error("fts: could not determine table name. Ensure you pass a pg.table() result.");
11134
- }
11135
- return name;
11568
+ return table.tableName;
11136
11569
  }
11137
11570
  function escapeIdent4(s) {
11138
11571
  return `"${s.replace(/"/g, '""')}"`;
@@ -11344,7 +11777,15 @@ function escapeIdent5(s) {
11344
11777
  return `"${s.replace(/"/g, '""')}"`;
11345
11778
  }
11346
11779
  function knowledgeBase(options) {
11347
- const { pg, provider, table = "_kb_docs", chunkSize = 512, chunkOverlap = 64, searchLimit = 5, searchThreshold = 0 } = options;
11780
+ const {
11781
+ pg,
11782
+ provider,
11783
+ table = "_kb_docs",
11784
+ chunkSize = 512,
11785
+ chunkOverlap = 64,
11786
+ searchLimit = 5,
11787
+ searchThreshold = 0
11788
+ } = options;
11348
11789
  const sql2 = pg.sql;
11349
11790
  const dimension = provider.dimension;
11350
11791
  const docsTable = pg.table(table, {